UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 13.6 kB
{"version":3,"file":"select-dropdown.mjs","names":["computed","defineComponent","inject","ref","toRaw","unref","watch","createVNode","_createVNode","mergeProps","_mergeProps","get","getEventCode","isIOS","isObject","isUndefined","DynamicSizeList","FixedSizeList","useNamespace","EVENT_CODE","GroupItem","OptionItem","useProps","selectV2InjectionKey","props","loading","Boolean","data","type","Array","required","hoveringIndex","Number","width","id","String","ariaLabel","name","setup","slots","expose","select","ns","getLabel","getValue","getDisabled","cachedHeights","listRef","size","length","value","tooltipRef","updatePopper","isSized","estimatedOptionHeight","listProps","itemSize","itemHeight","estimatedSize","idx","contains","arr","target","valueKey","includes","some","item","isEqual","selected","isItemSelected","modelValue","multiple","isItemDisabled","disabled","multipleLimit","isItemHovering","scrollToItem","index","list","resetScrollTop","exposed","Item","itemProps","style","sized","onSelect","onHover","isSelected","isDisabled","isHovering","created","default","onKeyboardNavigate","onKeyboardSelect","onForward","onBackward","onEscOrTab","onKeydown","e","code","tab","esc","down","up","enter","numpadEnter","preventDefault","stopPropagation","height","scrollbarAlwaysOn","isScrollbarAlwaysOn","List","b","is","header","empty","be","role","footer"],"sources":["../../../../../../packages/components/select-v2/src/select-dropdown.tsx"],"sourcesContent":["import {\n computed,\n defineComponent,\n inject,\n ref,\n toRaw,\n unref,\n watch,\n} from 'vue'\nimport { get } from 'lodash-unified'\nimport { getEventCode, isIOS, isObject, isUndefined } from '@element-plus/utils'\nimport {\n DynamicSizeList,\n FixedSizeList,\n} from '@element-plus/components/virtual-list'\nimport { useNamespace } from '@element-plus/hooks'\nimport { EVENT_CODE } from '@element-plus/constants'\nimport GroupItem from './group-item.vue'\nimport OptionItem from './option-item.vue'\nimport { useProps } from './useProps'\nimport { selectV2InjectionKey } from './token'\n\nimport type {\n DynamicSizeListInstance,\n FixedSizeListInstance,\n ItemProps,\n} from '@element-plus/components/virtual-list'\nimport type { Option, OptionItemProps } from './select.types'\nimport type {\n ComponentPublicInstance,\n ComputedRef,\n ExtractPropTypes,\n Ref,\n} from 'vue'\n\nconst props = {\n loading: Boolean,\n data: {\n type: Array,\n required: true as const,\n },\n hoveringIndex: Number,\n width: Number,\n id: String,\n ariaLabel: String,\n}\ninterface SelectDropdownExposed {\n listRef: Ref<FixedSizeListInstance | DynamicSizeListInstance | undefined>\n isSized: ComputedRef<boolean>\n isItemDisabled: (modelValue: any[] | any, selected: boolean) => boolean\n isItemHovering: (target: number) => boolean\n isItemSelected: (modelValue: any[] | any, target: Option) => boolean\n scrollToItem: (index: number) => void\n resetScrollTop: () => void\n}\nexport type SelectDropdownInstance = ComponentPublicInstance<\n ExtractPropTypes<typeof props>,\n SelectDropdownExposed\n>\nexport default defineComponent({\n name: 'ElSelectDropdown',\n props,\n setup(props, { slots, expose }) {\n const select = inject(selectV2InjectionKey)!\n const ns = useNamespace('select')\n const { getLabel, getValue, getDisabled } = useProps(select.props)\n\n const cachedHeights = ref<Array<number>>([])\n\n const listRef = ref<FixedSizeListInstance | DynamicSizeListInstance>()\n\n const size = computed(() => props.data.length)\n watch(\n () => size.value,\n () => {\n select.tooltipRef.value?.updatePopper?.()\n }\n )\n\n const isSized = computed(() =>\n isUndefined(select.props.estimatedOptionHeight)\n )\n const listProps = computed(() => {\n if (isSized.value) {\n return {\n itemSize: select.props.itemHeight,\n }\n }\n\n return {\n estimatedSize: select.props.estimatedOptionHeight,\n itemSize: (idx: number) => cachedHeights.value[idx],\n }\n })\n\n const contains = (arr: Array<any> = [], target: any) => {\n const {\n props: { valueKey },\n } = select\n\n if (!isObject(target)) {\n return arr.includes(target)\n }\n\n return (\n arr &&\n arr.some((item) => {\n return toRaw(get(item, valueKey)) === get(target, valueKey)\n })\n )\n }\n const isEqual = (selected: unknown, target: unknown) => {\n if (!isObject(target)) {\n return selected === target\n } else {\n const { valueKey } = select.props\n return get(selected, valueKey) === get(target, valueKey)\n }\n }\n\n const isItemSelected: SelectDropdownExposed['isItemSelected'] = (\n modelValue,\n target\n ) => {\n if (select.props.multiple) {\n return contains(modelValue, getValue(target))\n }\n return isEqual(modelValue, getValue(target))\n }\n\n const isItemDisabled: SelectDropdownExposed['isItemDisabled'] = (\n modelValue,\n selected\n ) => {\n const { disabled, multiple, multipleLimit } = select.props\n return (\n disabled ||\n (!selected &&\n (multiple\n ? multipleLimit > 0 && modelValue.length >= multipleLimit\n : false))\n )\n }\n\n const isItemHovering: SelectDropdownExposed['isItemHovering'] = (target) =>\n props.hoveringIndex === target\n\n const scrollToItem: SelectDropdownExposed['scrollToItem'] = (index) => {\n const list = listRef.value\n if (list) {\n list.scrollToItem(index)\n }\n }\n\n const resetScrollTop: SelectDropdownExposed['resetScrollTop'] = () => {\n const list = listRef.value\n if (list) {\n list.resetScrollTop()\n }\n }\n const exposed: SelectDropdownExposed = {\n listRef,\n isSized,\n\n isItemDisabled,\n isItemHovering,\n isItemSelected,\n scrollToItem,\n resetScrollTop,\n }\n expose(exposed)\n\n const Item = (itemProps: ItemProps<any>) => {\n const { index, data, style } = itemProps\n const sized = unref(isSized)\n const { itemSize, estimatedSize } = unref(listProps)\n const { modelValue } = select.props\n const { onSelect, onHover } = select\n const item = data[index]\n if (item.type === 'Group') {\n return (\n <GroupItem\n item={item}\n style={style}\n height={sized ? (itemSize as number) : estimatedSize}\n />\n )\n }\n\n const isSelected = isItemSelected(modelValue, item)\n const isDisabled = isItemDisabled(modelValue, isSelected)\n const isHovering = isItemHovering(index)\n return (\n <OptionItem\n {...itemProps}\n selected={isSelected}\n disabled={getDisabled(item) || isDisabled}\n created={!!item.created}\n hovering={isHovering}\n item={item}\n onSelect={onSelect}\n onHover={onHover}\n >\n {{\n default: (props: OptionItemProps) =>\n slots.default?.(props) || <span>{getLabel(item)}</span>,\n }}\n </OptionItem>\n )\n }\n\n // computed\n const { onKeyboardNavigate, onKeyboardSelect } = select\n\n const onForward = () => {\n onKeyboardNavigate('forward')\n }\n\n const onBackward = () => {\n onKeyboardNavigate('backward')\n }\n\n const onEscOrTab = () => {\n // The following line actually doesn't work. Fixing it may introduce a small breaking change for some users, so just comment it out for now.\n // select.expanded = false\n }\n\n const onKeydown = (e: KeyboardEvent) => {\n const code = getEventCode(e)\n const { tab, esc, down, up, enter, numpadEnter } = EVENT_CODE\n if ([esc, down, up, enter, numpadEnter].includes(code)) {\n e.preventDefault()\n e.stopPropagation()\n }\n\n switch (code) {\n case tab:\n case esc:\n onEscOrTab()\n break\n case down:\n onForward()\n break\n case up:\n onBackward()\n break\n case enter:\n case numpadEnter:\n onKeyboardSelect()\n break\n }\n }\n\n return () => {\n const { data, width } = props\n const { height, multiple, scrollbarAlwaysOn } = select.props\n const isScrollbarAlwaysOn = computed(() => {\n // fix https://github.com/element-plus/element-plus/issues/19127\n return isIOS ? true : scrollbarAlwaysOn\n })\n\n const List = unref(isSized) ? FixedSizeList : DynamicSizeList\n\n return (\n <div\n class={[ns.b('dropdown'), ns.is('multiple', multiple)]}\n style={{\n width: `${width}px`,\n }}\n >\n {slots.header?.()}\n {slots.loading?.() || slots.empty?.() || (\n <List\n ref={listRef}\n {...unref(listProps)}\n className={ns.be('dropdown', 'list')}\n scrollbarAlwaysOn={isScrollbarAlwaysOn.value}\n data={data}\n height={height}\n width={width}\n total={data.length}\n innerElement=\"ul\"\n innerProps={{\n id: props.id,\n role: 'listbox',\n 'aria-label': props.ariaLabel,\n 'aria-orientation': 'vertical',\n }}\n // @ts-ignore - dts problem\n onKeydown={onKeydown}\n >\n {{\n default: (props: ItemProps<any>) => <Item {...props} />,\n }}\n </List>\n )}\n {slots.footer?.()}\n </div>\n )\n }\n },\n})\n"],"mappings":"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"}