UNPKG

web-ui-pack

Version:
164 lines (163 loc) 7.14 kB
import WUPPopupElement from "../popup/popupElement"; import { MenuOpenCases } from "./baseCombo"; import { SetValueReasons } from "./baseControl"; import WUPSelectControl from "./select"; declare const tagName = "wup-selectmany"; declare global { namespace WUP.SelectMany { interface EventMap extends WUP.BaseCombo.EventMap { } interface ValidityMap extends WUP.BaseCombo.ValidityMap { } interface NewOptions { /** Hide items in menu that selected * @defaultValue false */ hideSelected: boolean; /** Allow user to change ordering of items; Use drag&drop or keyboard Shift/Ctrl/Meta + arrows to change item position * @defaultValue false */ sortable: boolean; } interface Options<T = any, VM = ValidityMap> extends WUP.Select.Options<T, VM>, NewOptions { /** @readonly Constant value that impossible to change */ multiple: true; /** @deprecated Not supported in SelectManyControl */ prefix?: string | null | undefined; /** @deprecated Not supported in SelectManControl */ postfix?: string | null | undefined; } interface JSXProps<C = WUPSelectManyControl> extends WUP.Select.JSXProps<C>, WUP.Base.OnlyNames<NewOptions> { "w-hideSelected"?: boolean | ""; "w-sortable"?: boolean | ""; /** @deprecated Not supported in SelectManyControl */ "w-prefix"?: any; /** @deprecated Not supported in SelectManyControl */ "w-postfix"?: any; } } interface HTMLElementTagNameMap { [tagName]: WUPSelectManyControl; } } declare module "react" { namespace JSX { interface IntrinsicElements { /** Form-control with dropdown/combobox behavior * @see {@link WUPSelectManyControl} */ [tagName]: WUP.Base.ReactHTML<WUPSelectManyControl> & WUP.SelectMany.JSXProps; } } } declare module "preact/jsx-runtime" { namespace JSX { interface HTMLAttributes<RefType> { } interface IntrinsicElements { /** Form-control with dropdown/combobox behavior * @see {@link WUPSelectManyControl} */ [tagName]: HTMLAttributes<WUPSelectManyControl> & WUP.SelectMany.JSXProps; } } } /** Form-control with dropdown/combobox behavior * @see demo {@link https://yegorich555.github.io/web-ui-pack/control/selectMany} * @example const el = document.createElement("wup-selectmany"); el.$options.name = "gender"; el.$options.items = [ { value: 1, text: "Male" }, { value: 2, text: "Female" }, { value: 3, text: "Other/Skip" }, ]; el.$initValue = [3]; el.$options.validations = { required: true }; const form = document.body.appendChild(document.createElement("wup-form")); form.appendChild(el); // or HTML <wup-form> <wup-selectmany w-name="gender" w-initvalue="window.myInitValue" w-validations="myValidations" w-items="window.myDropdownItems" /> </wup-form>; @tutorial Troubleshooting * * Accessibility. Screen readers announce 'blank' when focus on not-empty control. Solution not found (using contenteditable fixes this but provides more other bugs) * @tutorial innerHTML @example * <label> * <span> // extra span requires to use with icons via label:before, label:after without adjustments * <span [item]>Item 1</span> * <span [item]>Item 2</span> * // etc/ * <input/> * <strong>{$options.label}</strong> * </span> * <button clear/> * <wup-popup menu> * <ul> * <li>Item 1</li> * <li>Item 2</li> * // etc/ * </ul> * </wup-popup> * </label> */ export default class WUPSelectManyControl<ValueType = any, TOptions extends WUP.SelectMany.Options = WUP.SelectMany.Options, EventMap extends WUP.SelectMany.EventMap = WUP.SelectMany.EventMap> extends WUPSelectControl<ValueType[], ValueType, TOptions, EventMap> { #private; static get $styleRoot(): string; static get $style(): string; static $isEmpty(v: unknown[] | undefined): boolean; static $filterMenuItem(this: WUPSelectManyControl, menuItemText: string, menuItemValue: any, inputValue: string, inputRawValue: string): boolean; static $defaults: WUP.SelectMany.Options; /** Items selected & rendered on control */ $refItems?: Array<HTMLElement & { _wupValue: ValueType; }>; protected renderControl(): void; protected canHandleUndo(): boolean; canParseInput(_text: string): boolean; parseInput(text: string): ValueType[] | undefined; protected gotChanges(propsChanged: Array<keyof WUP.Select.Options> | null): void; /** It prevents menu opening if user tries sorting and focus got after mouseUp */ _wasSortAfterClick?: boolean; /** Call it to remove dragdrop logic */ _disposeDragdrop?: () => void; /** Called to apply dragdrop logic */ protected applyDragdrop(): void; canOpenMenu(openCase: MenuOpenCases, e?: MouseEvent | FocusEvent | KeyboardEvent | null): boolean; protected renderMenu(popup: WUPPopupElement, menuId: string): HTMLElement; /** Called to update/remove selected items on control */ protected renderItems(v: ValueType[], all: WUP.Select.MenuItem<any>[]): void; /** Announce items as single value on change if element is focused */ protected ariaSpeakValue(): void; protected resetInputValue(): void; protected valueToInput(v: ValueType[] | undefined, isReset?: boolean): string; protected selectValue(v: ValueType, canCloseMenu?: boolean): void; /** Index of focused value-item */ _focusIndex?: number; /** Focus value-item by index (related to this.$refItems) */ protected focusItemByIndex(i: number | null): void; protected focusMenuItem(next: HTMLElement | null): void; protected selectMenuItemByValue(v: ValueType[] | undefined): void; protected selectMenuItem(next: HTMLElement | null): void; protected clearFilterMenuItems(): void; /** Called to remove item with animation */ protected removeValue(index: number): void; protected setValue(v: ValueType[] | undefined, reason: SetValueReasons, skipInput?: boolean): boolean | null; protected gotFocus(ev: FocusEvent): Array<() => void>; protected gotFocusLost(): void; protected gotKeyDown(e: KeyboardEvent): void; } export {}; /** * known issues when 'contenteditable': * * <span contenteditalbe='true'> * <span></span> * <span contenteditalbe='false'>Item 1</span> * <span></span> * <span contenteditalbe='false'>Item 2</span> * <span>Input text here</span> * </span> * 01. NVDA. Reads only first line (the same issue for textarea) * 02. NVDA. Reads only first item in Firefox (when :after exists) * 1. Firefox. Caret position is wrong/missed between Items is use try to use ArrowKeys * 2. Firefox. Caret position is missed if no empty spans between items * 3. Without contenteditalbe='false' browser moves cursor into item, but it should be outside */