From da3934cc7bf70afaff2aea35a1a006792135e9a4 Mon Sep 17 00:00:00 2001 From: Darren Labithiotis Date: Tue, 6 Aug 2024 11:10:27 +0200 Subject: [PATCH] Push from menu-display-hidden (#14) --- .../textbox-autocomplete.tsx | 431 +++++++++--------- packages/ui/src/css/menu.module.css | 4 + 2 files changed, 220 insertions(+), 215 deletions(-) diff --git a/packages/ui/src/components/textbox/textbox-autocomplete/textbox-autocomplete.tsx b/packages/ui/src/components/textbox/textbox-autocomplete/textbox-autocomplete.tsx index f3c1f7a9..f620bc27 100644 --- a/packages/ui/src/components/textbox/textbox-autocomplete/textbox-autocomplete.tsx +++ b/packages/ui/src/components/textbox/textbox-autocomplete/textbox-autocomplete.tsx @@ -1,63 +1,64 @@ -import { ComponentChildren, h, JSX, RefObject } from 'preact' -import { useCallback, useRef, useState } from 'preact/hooks' - -import menuStyles from '../../../css/menu.module.css' -import { useMouseDownOutside } from '../../../hooks/use-mouse-down-outside' -import { IconMenuCheckmarkChecked16 } from '../../../icons/icon-16/icon-menu-checkmark-checked-16' -import { OnValueChange, Props } from '../../../types/types' -import { createClassName } from '../../../utilities/create-class-name' -import { getCurrentFromRef } from '../../../utilities/get-current-from-ref' -import { computeNextValue } from '../private/compute-next-value' -import { isKeyCodeCharacterGenerating } from '../private/is-keycode-character-generating' -import textboxStyles from '../textbox/textbox.module.css' -import textboxAutocompleteStyles from './textbox-autocomplete.module.css' - -const EMPTY_STRING = '' -const INVALID_ID = null -const ITEM_ID_DATA_ATTRIBUTE_NAME = 'data-textbox-autocomplete-item-id' -const MENU_VERTICAL_MARGIN = 16 +/** @jsx h */ +import { ComponentChildren, h, JSX, RefObject } from 'preact'; +import { useCallback, useRef, useState } from 'preact/hooks'; + +import menuStyles from '../../../css/menu.module.css'; +import { useMouseDownOutside } from '../../../hooks/use-mouse-down-outside'; +import { IconMenuCheckmarkChecked16 } from '../../../icons/icon-16/icon-menu-checkmark-checked-16'; +import { OnValueChange, Props } from '../../../types/types'; +import { createClassName } from '../../../utilities/create-class-name'; +import { getCurrentFromRef } from '../../../utilities/get-current-from-ref'; +import { computeNextValue } from '../private/compute-next-value'; +import { isKeyCodeCharacterGenerating } from '../private/is-keycode-character-generating'; +import textboxStyles from '../textbox/textbox.module.css'; +import textboxAutocompleteStyles from './textbox-autocomplete.module.css'; + +const EMPTY_STRING = ''; +const INVALID_ID = null; +const ITEM_ID_DATA_ATTRIBUTE_NAME = 'data-textbox-autocomplete-item-id'; +const MENU_VERTICAL_MARGIN = 16; export type TextboxAutocompleteProps = { - disabled?: boolean - filter?: boolean - icon?: ComponentChildren - name?: Name - onInput?: OmitThisParameter> - onValueInput?: OnValueChange - options: Array - placeholder?: string - propagateEscapeKeyDown?: boolean - revertOnEscapeKeyDown?: boolean - spellCheck?: boolean - strict?: boolean - top?: boolean - value: string - variant?: TextboxAutocompleteVariant -} + disabled?: boolean; + filter?: boolean; + icon?: ComponentChildren; + name?: Name; + onInput?: OmitThisParameter>; + onValueInput?: OnValueChange; + options: Array; + placeholder?: string; + propagateEscapeKeyDown?: boolean; + revertOnEscapeKeyDown?: boolean; + spellCheck?: boolean; + strict?: boolean; + top?: boolean; + value: string; + variant?: TextboxAutocompleteVariant; +}; export type TextboxAutocompleteOption = | TextboxAutocompleteOptionHeader | TextboxAutocompleteOptionValue - | TextboxAutocompleteOptionSeparator + | TextboxAutocompleteOptionSeparator; export type TextboxAutocompleteOptionHeader = { - header: string -} + header: string; +}; export type TextboxAutocompleteOptionValue = { - value: string - disabled?: boolean -} + value: string; + disabled?: boolean; +}; export type TextboxAutocompleteOptionSeparator = { - separator: true -} -export type TextboxAutocompleteVariant = 'border' | 'underline' + separator: true; +}; +export type TextboxAutocompleteVariant = 'border' | 'underline'; type Option = | TextboxAutocompleteOptionHeader | OptionValueWithId - | TextboxAutocompleteOptionSeparator + | TextboxAutocompleteOptionSeparator; type OptionValueWithId = TextboxAutocompleteOptionValue & { - id: string -} -type Id = typeof INVALID_ID | string + id: string; +}; +type Id = typeof INVALID_ID | string; export function TextboxAutocomplete({ disabled = false, @@ -77,166 +78,166 @@ export function TextboxAutocomplete({ ...rest }: Props>): JSX.Element { if (typeof icon === 'string' && icon.length !== 1) { - throw new Error(`String \`icon\` must be a single character: ${icon}`) + throw new Error(`String \`icon\` must be a single character: ${icon}`); } - const rootElementRef: RefObject = useRef(null) - const inputElementRef: RefObject = useRef(null) - const menuElementRef: RefObject = useRef(null) + const rootElementRef: RefObject = useRef(null); + const inputElementRef: RefObject = useRef(null); + const menuElementRef: RefObject = useRef(null); - const [isMenuVisible, setIsMenuVisible] = useState(false) - const [selectedId, setSelectedId] = useState(INVALID_ID) - const [originalValue, setOriginalValue] = useState(EMPTY_STRING) // Value of the textbox when it was initially focused - const [editedValue, setEditedValue] = useState(value) // Value being edited that does not match any of the options + const [isMenuVisible, setIsMenuVisible] = useState(false); + const [selectedId, setSelectedId] = useState(INVALID_ID); + const [originalValue, setOriginalValue] = useState(EMPTY_STRING); // Value of the textbox when it was initially focused + const [editedValue, setEditedValue] = useState(value); // Value being edited that does not match any of the options - let options: Array