UNPKG

selectic

Version:
358 lines (357 loc) 14.3 kB
import { ComputedRef } from 'vue'; type MandateProps<T extends {}> = { [TK in keyof T]-?: T[TK]; }; export type StrictOptionId = string | number; export type OptionId = StrictOptionId | null; export type SelectedValue = OptionId | StrictOptionId[]; export interface OptionValue { id: OptionId; text: string; title?: string; disabled?: boolean; group?: StrictOptionId; className?: string; style?: string; icon?: string; options?: OptionValue[]; exclusive?: boolean; data?: any; } type OptionBehaviorOperation = 'sort' | 'force'; type OptionBehaviorOrder = 'O' | 'D' | 'E'; export interface OptionItem extends OptionValue { selected: boolean; disabled: boolean; isGroup: boolean; } export type OptionProp = OptionValue | string; export interface GroupValue { id: StrictOptionId; text: string; } export type RequestResult = { /** The total number of expecting options. * Needed to know if there are more items to fetch, and to size the scrollbar. */ total: number; /** The list of the options. */ result: OptionValue[]; }; export type FetchCallback = (_search: string, _offsetItem: number, _pageSize: number) => Promise<RequestResult>; export type GetCallback = (_ids: OptionId[]) => Promise<OptionValue[]>; export type FormatCallback = (_option: OptionItem) => OptionItem; export type SelectionOverflow = /** Items are reduced in width and an ellipsis is displayed in their name. */ 'collapsed' | 'multiline'; export type ListPosition = /** Display the list at bottom */ 'bottom' /** Display the list at bottom */ | 'top' /** Display the list at bottom but if there is not enough space, display it at top */ | 'auto'; export type HideFilter = /** Display or hide the filter panel */ boolean /** The handler to open the filter panel is hidden only if there is less * than 10 options */ | 'auto' /** The panel filter is always open */ | 'open'; export type SelectAllOption = /** Display the "select all" only when data are all fetched or allowRevert */ 'auto' /** Always display the "select all" in mulitple mode. */ | 'visible'; export interface SelecticStoreStateParams { /** Equivalent of <select>'s "multiple" attribute */ multiple?: boolean; /** Equivalent of <input>'s "placeholder" attribute */ placeholder?: string; /** Hide filter component when enabled */ hideFilter?: HideFilter; /** Allow to reverse selection. * If true, parent should support the selectionIsExcluded property. * If false, the action is never available. * If undefined, the action is available only when it is not needed to * change selectionIsExcluded property. */ allowRevert?: boolean; /** Force the availability of the "select all" even if all data is not fetched yet. */ forceSelectAll?: SelectAllOption; /** Allow user to clear current selection */ allowClearSelection?: boolean; /** Number of items to retrieve in fetch request (it is possible * to fetch more items at once if several pages are requested) */ pageSize?: number; /** Select the first available option */ autoSelect?: boolean; /** Disable the select if only one option is given and must be selected. */ autoDisabled?: boolean; /** Accept only values which are in options */ strictValue?: boolean; /** Define how the component should behave when selected items are too * large for the container. * collapsed (default): Items are reduced in width and an ellipsis * is displayed in their name. * multiline: The container extends in height in order to display all * items. */ selectionOverflow?: SelectionOverflow; /** Called when item is displayed in the list. */ formatOption?: FormatCallback; /** Called when item is displayed in the selection area. */ formatSelection?: FormatCallback; /** Described behavior when options from several sources are set (static, dynamic, slots) * It describe what to do (sort or force) * and the order (O → static options, D → dynamic options, E → slot elements) * Example: "sort-ODE" */ optionBehavior?: string; /** Indicate where the list should be deployed */ listPosition?: ListPosition; /** If true, the component is open at start */ isOpen?: boolean; /** Avoid selecting all items when clicking on group's header */ disableGroupSelection?: boolean; } export interface Props { /** Selected value */ value?: SelectedValue | null; /** If true, the value represents the ones we don't want to select */ selectionIsExcluded?: boolean; /** Equivalent of "disabled" Select's attribute */ disabled?: boolean; /** List of options to display */ options?: OptionProp[] | null; /** List of options to display from child elements */ childOptions?: OptionValue[]; /** Define groups which will be used by items */ groups?: GroupValue[]; /** Overwrite default texts */ texts?: PartialMessages | null; /** Overwrite default icons */ icons?: PartialIcons | null; /** Overwrite default icon family */ iconFamily?: IconFamily | null; /** Keep this component open if another Selectic component opens. * * - `true` → Keep open for **any** Selectic component. * - `string` → Keep open only when the other Selectic matches the given CSS selector. * - `false` (default) → Always close when another Selectic opens. * * An empty string is treated the same as `false`. */ keepOpenWithOtherSelectic?: boolean | string; /** Selectic configuration */ params?: SelecticStoreStateParams; /** Method to call to fetch extra data */ fetchCallback?: FetchCallback | null; /** Method to call to get specific item */ getItemsCallback?: GetCallback | null; } type InternalProps = MandateProps<Props>; export interface Data { /** Number of items displayed in a page (before scrolling) */ itemsPerPage: number; labels: Messages; icons: PartialIcons; iconFamily: IconFamily; /** used to avoid checking and updating table while doing batch stuff */ doNotUpdate: boolean; cacheItem: Map<OptionId, OptionValue>; activeOrder: OptionBehaviorOrder; dynOffset: number; } export interface SelecticStoreState { /** The current selected values */ internalValue: SelectedValue; /** If true, user wants to choose the opposite selection */ selectionIsExcluded: boolean; /** If true, several value can be selected */ multiple: boolean; /** If true, no change can be done by user */ disabled: boolean; /** Define the default text to display when there is no selection */ placeholder: string; /** If true, filters and controls are hidden */ hideFilter: boolean; /** If true, the filter panel is always open */ keepFilterOpen: boolean; /** Allow to reverse selection. * If true, parent should support the selectionIsExcluded property. * If false, the action is never available. * If undefined, the action is available only when it is not needed to * change selectionIsExcluded property. */ allowRevert?: boolean; /** If true, user can clear current selection * (if false, it is still possible to clear it programmatically) */ allowClearSelection: boolean; /** If false, do not select the first available option even if value is mandatory */ autoSelect: boolean; /** If true, Selectic is disabled if there is only one mandatory option. */ autoDisabled: boolean; /** If true, only values which are in options are accepted. */ strictValue: boolean; /** Define how to behave when selected items are too large for container. */ selectionOverflow: SelectionOverflow; /** If true, the list is displayed */ isOpen: boolean; /** Text entered by user to look for options */ searchText: string; /** Contains all known options */ allOptions: OptionValue[]; /** Contains all fetched dynamic options */ dynOptions: OptionValue[]; /** Contains options which should be displayed */ filteredOptions: OptionItem[]; /** Contains options which are selected */ selectedOptions: OptionItem | OptionItem[] | null; /** The total number of all options (static + dynamic + elements) without any filter */ totalAllOptions: number; /** The total number of options which can be fetched (without any filter) */ totalDynOptions: number; /** The total number of options which should be displayed (filter is applied) */ totalFilteredOptions: number; /** Description of groups (optGroup) */ groups: Map<OptionId, string>; /** Starting index of options which are displayed */ offsetItem: number; /** Index of active item */ activeItemIdx: number; /** Number of items to fetch per page */ pageSize: number; /** Called when item is displayed in the list. */ formatOption?: FormatCallback; /** Called when item is displayed in the selection area. */ formatSelection?: FormatCallback; /** Operation to apply when there are several sources */ optionBehaviorOperation: OptionBehaviorOperation; /** Order of sources options */ optionBehaviorOrder: OptionBehaviorOrder[]; /** Indicate where the list should be deployed */ listPosition: ListPosition; /** If true, the "select All" is still available even if all data are not fetched yet. */ forceSelectAll: SelectAllOption; /** Avoid selecting all items when clicking on group's header */ disableGroupSelection: boolean; /** Inner status which should be modified only by store */ status: { /** If true, a search is currently done */ searching: boolean; /** If not empty, an error happens */ errorMessage: string; /** If true it means that all options are selected */ areAllSelected: boolean; /** If true, a change has been done by user */ hasChanged: boolean; /** If true, it means the current change has been done automatically by Selectic */ automaticChange: boolean; /** If true, it means the current close has been done automatically by Selectic */ automaticClose: boolean; }; } export type IconFamily = '' | 'selectic' | 'font-awesome-4' | 'font-awesome-5' | 'font-awesome-6' | 'raw' | `prefix:${string}`; export type IconKey = 'caret-down' | 'caret-up' | 'check' | 'dot' | 'search' | 'spinner' | 'strikethrough' | 'times' | 'question' | 'spin'; export type IconValue = `selectic:${IconKey}${'' | ':spin'}` | `raw:${string}` | `current:${IconKey}${'' | ':spin'}` | string; export type Icons = Record<IconKey, IconValue>; export type PartialIcons = { [K in IconKey]?: Icons[K]; }; interface Messages { noFetchMethod: string; searchPlaceholder: string; searching: string; cannotSelectAllSearchedItems: string; cannotSelectAllRevertItems: string; selectAll: string; excludeResult: string; reverseSelection: string; noData: string; noResult: string; clearSelection: string; clearSelections: string; wrongFormattedData: string; moreSelectedItem: string; moreSelectedItems: string; unknownPropertyValue: string; wrongQueryResult: string; } export type PartialMessages = { [K in keyof Messages]?: Messages[K]; }; export declare function changeTexts(texts: PartialMessages): void; export declare function changeIcons(newIcons: PartialIcons, newFamilyIcon?: IconFamily): void; export default class SelecticStore { props: InternalProps; state: SelecticStoreState; data: Data; private requestId; private requestSearchId; private isRequesting; private cacheRequest; private closeSelectic; /** Number of item to pre-display */ marginSize: ComputedRef<number>; /** If true, it is possible to click on group to select all items inside */ allowGroupSelection: ComputedRef<boolean>; isPartial: ComputedRef<boolean>; hasAllItems: ComputedRef<boolean>; hasFetchedAllItems: ComputedRef<boolean>; private listOptions; private elementOptions; _uid: number; constructor(props?: Props); commit<N extends keyof SelecticStoreState, V extends SelecticStoreState[N]>(name: N, value: V): void; setAutomaticChange(): void; setAutomaticClose(): void; getItem(id: OptionId): OptionValue; getItems(ids: OptionId[]): Promise<OptionItem[]>; selectGroup(id: OptionId, itemsSelected: boolean): void; selectItem(id: OptionId, selected?: boolean, keepOpen?: boolean): boolean; toggleSelectAll(): void; resetChange(): void; resetErrorMessage(): void; clearCache(forceReset?: boolean): void; changeGroups(groups: GroupValue[]): void; changeTexts(texts: PartialMessages): void; changeIcons(icons: PartialIcons | null, family?: IconFamily | null): void; private hasValue; private getValue; private convertTypeValue; private assertValueType; private assertCorrectValue; /** Reset the display cache in order to rebuild it */ private clearDisplay; /** rebuild the state filteredOptions to normalize their values */ private updateFilteredOptions; private addGroups; /** This method is for the computed property listOptions */ private getListOptions; /** This method is for the computed property elementOptions */ private getElementOptions; /** Generate the list of all options by combining the 3 option lists */ private buildAllOptions; private buildFilteredOptions; private buildSelectedOptions; private fetchRequest; private fetchData; private filterOptions; private addStaticFilteredOptions; private buildSelectedItems; private hasItemInStore; private buildItems; private buildGroupItems; private buildOptionBehavior; private nbGroups; private checkAutoSelect; private checkAutoDisabled; private checkHideFilter; /** update group item, to mark them as selected if needed */ private updateGroupSelection; /** assign new value to the filteredOptions and apply change depending on it */ private setFilteredOptions; } export {};