@rotki/ui-library 3.0.0-beta.1 → 3.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js +3 -3
  2. package/dist/components/accordions/accordion/RuiAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -1
  3. package/dist/components/accordions/accordions/RuiAccordions.vue_vue_type_script_setup_true_lang.js +1 -1
  4. package/dist/components/avatars/RuiAvatar.vue_vue_type_script_setup_true_lang.js +1 -1
  5. package/dist/components/avatars/RuiAvatarGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  6. package/dist/components/buttons/button/RuiButton.js.map +1 -1
  7. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js +10 -10
  8. package/dist/components/buttons/button/RuiButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/buttons/button/button-styles.js +10 -2
  10. package/dist/components/buttons/button/button-styles.js.map +1 -1
  11. package/dist/components/buttons/button-group/RuiButtonGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  12. package/dist/components/calendar/RuiCalendar.vue_vue_type_script_setup_true_lang.js +1 -1
  13. package/dist/components/calendar/RuiCalendarGrid.vue_vue_type_script_setup_true_lang.js +1 -1
  14. package/dist/components/calendar/RuiCalendarHeader.vue_vue_type_script_setup_true_lang.js +1 -1
  15. package/dist/components/calendar/RuiCalendarMenu.vue_vue_type_script_setup_true_lang.js +1 -1
  16. package/dist/components/chips/RuiChip.vue_vue_type_script_setup_true_lang.js +1 -1
  17. package/dist/components/color-picker/RuiColorBoard.vue_vue_type_script_setup_true_lang.js +1 -1
  18. package/dist/components/color-picker/RuiColorDisplay.vue_vue_type_script_setup_true_lang.js +1 -1
  19. package/dist/components/color-picker/RuiColorHue.vue_vue_type_script_setup_true_lang.js +1 -1
  20. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js +9 -10
  21. package/dist/components/color-picker/RuiColorInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  22. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js +3 -4
  23. package/dist/components/color-picker/RuiColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js +33 -33
  25. package/dist/components/date-time-picker/RuiDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/date-time-picker/use-date-bounds.js +1 -1
  27. package/dist/components/date-time-picker/use-date-time-selection.js +65 -66
  28. package/dist/components/date-time-picker/use-date-time-selection.js.map +1 -1
  29. package/dist/components/date-time-picker/use-input-handler.js +1 -1
  30. package/dist/components/date-time-picker/use-keyboard-handler.js +29 -30
  31. package/dist/components/date-time-picker/use-keyboard-handler.js.map +1 -1
  32. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js +24 -24
  33. package/dist/components/forms/auto-complete/RuiAutoComplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js +49 -49
  35. package/dist/components/forms/category-picker/RuiCategoryPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/components/forms/checkbox/RuiCheckbox.vue_vue_type_script_setup_true_lang.js +1 -1
  37. package/dist/components/forms/checkbox/checkbox-group/RuiCheckboxGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  38. package/dist/components/forms/file-upload/RuiFileUpload.js.map +1 -1
  39. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js +19 -17
  40. package/dist/components/forms/file-upload/RuiFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/components/forms/radio-button/radio/RuiRadio.vue_vue_type_script_setup_true_lang.js +1 -1
  42. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js +11 -11
  43. package/dist/components/forms/select/RuiMenuSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  44. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js +17 -17
  45. package/dist/components/forms/slider/RuiSlider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/components/forms/switch/RuiSwitch.vue_vue_type_script_setup_true_lang.js +1 -1
  47. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js +21 -21
  48. package/dist/components/forms/text-area/RuiTextArea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  49. package/dist/components/forms/text-field/RuiTextField.js.map +1 -1
  50. package/dist/components/forms/text-field/RuiTextField.vue.d.ts +2 -0
  51. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js +24 -20
  52. package/dist/components/forms/text-field/RuiTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  53. package/dist/components/helpers/RuiFormTextDetail.js.map +1 -1
  54. package/dist/components/helpers/RuiFormTextDetail.vue.d.ts +11 -1
  55. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js +3 -3
  56. package/dist/components/helpers/RuiFormTextDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  57. package/dist/components/icons/RuiIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  58. package/dist/components/logos/RuiLogo.vue_vue_type_script_setup_true_lang.js +1 -1
  59. package/dist/components/overlays/badge/RuiBadge.vue_vue_type_script_setup_true_lang.js +1 -1
  60. package/dist/components/overlays/dialog/RuiDialog.vue_vue_type_script_setup_true_lang.js +1 -1
  61. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js +17 -17
  62. package/dist/components/overlays/menu/RuiMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.js.map +1 -1
  64. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js +9 -9
  65. package/dist/components/overlays/navigation-drawer/RuiNavigationDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js +3 -4
  67. package/dist/components/overlays/notification/RuiNotification.vue_vue_type_script_setup_true_lang.js.map +1 -1
  68. package/dist/components/overlays/tooltip/RuiTooltip.vue_vue_type_script_setup_true_lang.js +1 -1
  69. package/dist/components/progress/RuiProgress.vue_vue_type_script_setup_true_lang.js +1 -1
  70. package/dist/components/steppers/RuiFooterStepper.vue_vue_type_script_setup_true_lang.js +1 -1
  71. package/dist/components/steppers/RuiStepper.js.map +1 -1
  72. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js +13 -8
  73. package/dist/components/steppers/RuiStepper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  74. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js +27 -27
  75. package/dist/components/tables/RuiDataTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  76. package/dist/components/tables/RuiTableHead.vue_vue_type_script_setup_true_lang.js +1 -1
  77. package/dist/components/tables/RuiTablePagination.vue_vue_type_script_setup_true_lang.js +1 -1
  78. package/dist/components/tables/data-table/RuiDataTableCell.vue_vue_type_script_setup_true_lang.js +1 -1
  79. package/dist/components/tables/data-table/RuiDataTableGroupRow.vue_vue_type_script_setup_true_lang.js +1 -1
  80. package/dist/components/tables/data-table/RuiDataTableMobileSort.vue_vue_type_script_setup_true_lang.js +1 -1
  81. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js +23 -23
  82. package/dist/components/tables/data-table/RuiDataTableRow.vue_vue_type_script_setup_true_lang.js.map +1 -1
  83. package/dist/components/tables/use-pagination-navigation.js +1 -1
  84. package/dist/components/tabs/tab/RuiTab.vue_vue_type_script_setup_true_lang.js +1 -1
  85. package/dist/components/tabs/tab/use-tab-link.js +1 -1
  86. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js +6 -6
  87. package/dist/components/tabs/tab-items/RuiTabItems.vue_vue_type_script_setup_true_lang.js.map +1 -1
  88. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js +11 -12
  89. package/dist/components/tabs/tabs/RuiTabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  90. package/dist/components/tabs/tabs/use-tab-indicator.js +7 -7
  91. package/dist/components/tabs/tabs/use-tab-indicator.js.map +1 -1
  92. package/dist/components/tabs/tabs/use-tab-keyboard.js +1 -1
  93. package/dist/components/tabs/tabs/use-tab-scroll.js +15 -15
  94. package/dist/components/tabs/tabs/use-tab-scroll.js.map +1 -1
  95. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js +60 -61
  96. package/dist/components/time-picker/RuiTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  97. package/dist/composables/breakpoint.js +3 -3
  98. package/dist/composables/breakpoint.js.map +1 -1
  99. package/dist/composables/dropdown-menu.d.ts +9 -9
  100. package/dist/composables/dropdown-menu.js +32 -32
  101. package/dist/composables/dropdown-menu.js.map +1 -1
  102. package/dist/composables/floating.d.ts +1 -1
  103. package/dist/composables/floating.js +11 -11
  104. package/dist/composables/floating.js.map +1 -1
  105. package/dist/composables/forms/auto-complete/focus.js +16 -17
  106. package/dist/composables/forms/auto-complete/focus.js.map +1 -1
  107. package/dist/composables/forms/auto-complete/keyboard-navigation.js +1 -1
  108. package/dist/composables/forms/auto-complete/search.js +6 -7
  109. package/dist/composables/forms/auto-complete/search.js.map +1 -1
  110. package/dist/composables/forms/auto-complete/selection.js +1 -1
  111. package/dist/composables/forms/auto-complete/value.js +1 -1
  112. package/dist/composables/forms/category-picker/use-category-picker.js +1 -1
  113. package/dist/composables/forms/use-prepend-append-width.js +6 -6
  114. package/dist/composables/forms/use-prepend-append-width.js.map +1 -1
  115. package/dist/composables/keyboard-scroll.js +5 -5
  116. package/dist/composables/keyboard-scroll.js.map +1 -1
  117. package/dist/composables/overlay-stack.js +1 -1
  118. package/dist/composables/sticky-header.js +8 -8
  119. package/dist/composables/sticky-header.js.map +1 -1
  120. package/dist/composables/tables/data-table/columns.js +1 -1
  121. package/dist/composables/tables/data-table/expansion.js +1 -1
  122. package/dist/composables/tables/data-table/grouping.js +27 -28
  123. package/dist/composables/tables/data-table/grouping.js.map +1 -1
  124. package/dist/composables/tables/data-table/page-scroll.d.ts +7 -5
  125. package/dist/composables/tables/data-table/page-scroll.js +48 -17
  126. package/dist/composables/tables/data-table/page-scroll.js.map +1 -1
  127. package/dist/composables/tables/data-table/pagination.js +1 -1
  128. package/dist/composables/tables/data-table/selection.js +37 -38
  129. package/dist/composables/tables/data-table/selection.js.map +1 -1
  130. package/dist/composables/tables/data-table/sort.js +1 -1
  131. package/dist/composables/theme.js +12 -12
  132. package/dist/composables/theme.js.map +1 -1
  133. package/dist/composables/timeout-manager.js +1 -1
  134. package/dist/index.d.ts +2 -2
  135. package/dist/index.js +2 -2
  136. package/dist/index.js.map +1 -1
  137. package/dist/style.css +2 -18
  138. package/dist/types/dom.d.ts +9 -0
  139. package/dist/types/theme.d.ts +2 -3
  140. package/dist/types/theme.js.map +1 -1
  141. package/dist/utils/form-text-detail.js +1 -1
  142. package/dist/utils/helpers.js +1 -1
  143. package/dist/vendor/@vueuse/core/dist/index.js +1577 -0
  144. package/dist/vendor/@vueuse/core/dist/index.js.map +1 -0
  145. package/dist/vendor/@vueuse/shared/dist/index.js +563 -0
  146. package/dist/vendor/@vueuse/shared/dist/index.js.map +1 -0
  147. package/dist/vite-plugin/index.js +5 -6
  148. package/dist/vite-plugin/index.js.map +1 -1
  149. package/dist/web-types.json +9 -2
  150. package/package.json +5 -4
@@ -1 +1 @@
1
- {"version":3,"file":"dropdown-menu.js","names":[],"sources":["../../src/composables/dropdown-menu.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport type KeyOfType<T, V> = T extends string | number | boolean | symbol | null | undefined\n ? never\n : V extends object\n ? keyof T\n : keyof {\n [P in keyof T as T[P] extends V ? P : V extends T[P] ? P : never]: any;\n };\n\nexport interface DropdownItemAttr<TValue, TItem> {\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n}\n\n/**\n * An item key or a resolver. `& string` lets Vue's compiler infer a String runtime type for the key\n * form; a bare generic `keyof` compiles to Function only, and a consumer's runtime warns.\n */\nexport type GroupBy<TItem> = (keyof TItem & string) | ((item: TItem) => string);\n\nexport type ItemDisabled<TItem> = (keyof TItem & string) | ((item: TItem) => boolean);\n\n/**\n * The rendered height of a default option row, a `list` button at its default or `sm` size.\n * The virtual list reserves this much per row, so a mismatch leaves a gap under the last option.\n *\n * @param dense - whether the options render at the dense size\n * @returns the row height in pixels\n */\nexport function getOptionHeight(dense: boolean | undefined): number {\n return dense ? 32 : 40;\n}\n\nexport interface DropdownOptionGroup<TItem> {\n group: string;\n items: TItem[];\n}\n\nexport interface DropdownOptions<TValue, TItem> {\n options: MaybeRefOrGetter<TItem[]>;\n dense?: MaybeRefOrGetter<boolean>;\n disabled?: MaybeRefOrGetter<boolean>;\n value: Ref<TItem | TItem[] | undefined>;\n menuRef: Ref<HTMLElement> | TemplateRef<HTMLElement>;\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n appendWidth?: number;\n prependWidth?: number;\n itemHeight?: number;\n overscan?: number;\n autoSelectFirst?: boolean;\n setValue?: (val: TItem) => void;\n hideSelected?: boolean;\n isOpen?: Ref<boolean>;\n getText?: (item: TItem) => string | undefined;\n getIdentifier?: (item: TItem) => any;\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n itemDisabled?: MaybeRefOrGetter<ItemDisabled<TItem> | undefined>;\n}\n\nexport function useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n}: DropdownItemAttr<TValue, TItem>) {\n function getText(item: TItem): string | undefined {\n if (textAttr) {\n if (typeof textAttr === 'function')\n return textAttr(item);\n else return item[textAttr]?.toString();\n }\n\n return item?.toString();\n }\n\n function getIdentifier(\n item: TItem,\n ): TItem | TItem[KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>] {\n if (keyAttr)\n return item[keyAttr];\n\n return item;\n }\n\n return {\n getIdentifier,\n getText,\n };\n}\n\nfunction toSelectedArray<TItem>(val: TItem | TItem[] | undefined): TItem[] {\n if (Array.isArray(val))\n return val;\n if (val !== null && val !== undefined)\n return [val];\n return [];\n}\n\nexport function useDropdownMenu<TValue, TItem>({\n appendWidth,\n autoSelectFirst,\n dense,\n disabled = false,\n getIdentifier: externalGetIdentifier,\n getText: externalGetText,\n hideSelected,\n isOpen: externalIsOpen,\n itemHeight = getOptionHeight(false),\n keyAttr,\n menuRef: _menuRef,\n options: allOptions,\n overscan = 5,\n prependWidth,\n setValue,\n textAttr,\n value,\n groupBy,\n itemDisabled,\n}: DropdownOptions<TValue, TItem>) {\n const { getIdentifier: defaultGetIdentifier, getText: defaultGetText } = useDropdownOptionProperty({\n keyAttr,\n textAttr,\n });\n\n const getIdentifier = externalGetIdentifier ?? defaultGetIdentifier;\n const getText = externalGetText ?? defaultGetText;\n\n const activeIdentifiers = computed<Set<any>>(() => {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n const identifiers = new Set<any>();\n for (const item of selected) {\n identifiers.add(getIdentifier(item));\n }\n return identifiers;\n });\n\n function isActiveItem(item: TItem): boolean {\n return get(activeIdentifiers).has(getIdentifier(item));\n }\n\n const options = computed<TItem[]>(() => {\n const options = toValue(allOptions);\n if (!hideSelected)\n return options;\n\n return options.filter(item => !isActiveItem(item));\n });\n\n function getGroupKey(item: TItem): string {\n const group = toValue(groupBy);\n if (!group)\n return '';\n\n if (typeof group === 'function')\n return group(item);\n\n return String(item[group] ?? '');\n }\n\n function isItemDisabled(item: TItem): boolean {\n const itemDisabledValue = toValue(itemDisabled);\n if (!itemDisabledValue)\n return false;\n\n if (typeof itemDisabledValue === 'function')\n return itemDisabledValue(item);\n\n return Boolean(item[itemDisabledValue]);\n }\n\n const isGrouped = computed<boolean>(() => toValue(groupBy) !== undefined);\n\n const groupedOptions = computed<DropdownOptionGroup<TItem>[]>(() => {\n if (!get(isGrouped))\n return [];\n\n const buckets = new Map<string, TItem[]>();\n for (const item of get(options)) {\n const key = getGroupKey(item);\n const list = buckets.get(key);\n if (list)\n list.push(item);\n else\n buckets.set(key, [item]);\n }\n\n return Array.from(buckets.entries()).map(([group, items]) => ({ group, items }));\n });\n\n const { containerProps, list, scrollTo, wrapperProps } = useVirtualList<TItem>(options, {\n itemHeight,\n overscan,\n });\n\n const renderedData = useArrayMap(list, ({ data, index: _index }) => ({ _index, item: data }));\n\n const isOpen = externalIsOpen ?? shallowRef<boolean>(false);\n\n const valueKey = computed(() => {\n const selected = get(value);\n if (!keyAttr || !selected)\n return selected;\n return Array.isArray(selected) ? selected.map(item => item[keyAttr]) : selected[keyAttr];\n });\n\n const modelHighlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const modelUserNavigated = shallowRef<boolean>(false);\n\n const optionWidthBounds = computed<{ min: number; max: number }>(() => {\n let min = 0;\n let max = 0;\n for (const option of get(options)) {\n const length = getText(option)?.toString()?.length ?? 0;\n if (min === 0 && max === 0) {\n min = length;\n max = length;\n }\n else if (length < min) {\n min = length;\n }\n else if (length > max) {\n max = length;\n }\n }\n return { min, max };\n });\n\n const menuWidth = computed<string>(() => {\n const { min, max } = get(optionWidthBounds);\n const maxWidth = 30;\n const paddingX = 1.5;\n const fontMultiplier = toValue(dense) ? 12 : 13;\n const difference = max - min;\n\n function computeValue(width: number): string {\n const additionalWidths =\n (prependWidth ? prependWidth + 0.5 : 0) + (appendWidth ? appendWidth + 0.5 : 0);\n return `${Math.min((width * fontMultiplier) / 16 + paddingX + additionalWidths, maxWidth)}rem`;\n }\n\n if (difference <= 5)\n return computeValue(max);\n\n return computeValue(min + difference / 2);\n });\n\n function toggle(state: boolean = false): void {\n set(isOpen, state);\n }\n\n function itemIndexInValue(item: TItem): number {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n\n if (selected.length === 0)\n return -1;\n\n const itemId = getIdentifier(item);\n return selected.findIndex(selectedItem => getIdentifier(selectedItem) === itemId);\n }\n\n function scrollHighlightedIntoView(): void {\n get(_menuRef)\n ?.querySelector<HTMLElement>('[data-highlighted=\"true\"]')\n ?.scrollIntoView({ block: 'nearest' });\n }\n\n async function adjustScrollByHighlightedIndex(): Promise<void> {\n const index = get(modelHighlightedIndex);\n if (index === -1)\n return;\n\n await nextTick();\n if (get(_menuRef)?.querySelector('[data-highlighted=\"true\"]')) {\n scrollHighlightedIntoView();\n return;\n }\n\n // Outside the virtual list's rendered window, so render it first, then nudge it fully into view\n scrollTo(index);\n await nextTick();\n scrollHighlightedIntoView();\n }\n\n async function updateOpen(open: boolean): Promise<void> {\n if (!open)\n return;\n\n const val = get(value);\n\n // Set highlighted index to active item\n if ((Array.isArray(val) && val.length > 0) || (val !== null && val !== undefined)) {\n const index = get(options).findIndex(isActiveItem);\n if (index > -1)\n set(modelHighlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(modelHighlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(modelUserNavigated, false);\n if (get(modelHighlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(modelHighlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(modelHighlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(modelUserNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(modelUserNavigated, true);\n\n const items = get(options);\n const total = items.length;\n if (total === 0)\n return;\n\n const move = up ? -1 : 1;\n let position = get(modelHighlightedIndex);\n\n for (let step = 0; step < total; step++) {\n position += move;\n if (position >= total)\n position = 0;\n else if (position < 0)\n position = total - 1;\n\n const candidate = items[position];\n if (candidate !== undefined && !isItemDisabled(candidate)) {\n set(modelHighlightedIndex, position);\n return;\n }\n }\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(modelHighlightedIndex);\n if (highlightedIndexVal === -1)\n return;\n\n const entry = get(options)[highlightedIndexVal];\n if (entry !== undefined && !isItemDisabled(entry))\n setValue(entry);\n };\n\n return {\n applyHighlighted,\n containerProps,\n getIdentifier,\n getText,\n groupedOptions,\n modelHighlightedIndex,\n isActiveItem,\n isGrouped,\n isItemDisabled,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n modelUserNavigated,\n valueKey,\n wrapperProps,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dropdown-menu.js","names":[],"sources":["../../src/composables/dropdown-menu.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport type KeyOfType<T, V> = T extends string | number | boolean | symbol | null | undefined\n ? never\n : V extends object\n ? keyof T\n : keyof {\n [P in keyof T as T[P] extends V ? P : V extends T[P] ? P : never]: any;\n };\n\nexport interface DropdownItemAttr<TValue, TItem> {\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n}\n\n/**\n * An item key or a resolver. `& string` lets Vue's compiler infer a String runtime type for the key\n * form; a bare generic `keyof` compiles to Function only, and a consumer's runtime warns.\n */\nexport type GroupBy<TItem> = (keyof TItem & string) | ((item: TItem) => string);\n\nexport type ItemDisabled<TItem> = (keyof TItem & string) | ((item: TItem) => boolean);\n\n/**\n * The rendered height of a default option row, a `list` button at its default or `sm` size.\n * The virtual list reserves this much per row, so a mismatch leaves a gap under the last option.\n *\n * @param dense - whether the options render at the dense size\n * @returns the row height in pixels\n */\nexport function getOptionHeight(dense: boolean | undefined): number {\n return dense ? 32 : 40;\n}\n\nexport interface DropdownOptionGroup<TItem> {\n group: string;\n items: TItem[];\n}\n\nexport interface DropdownOptions<TValue, TItem> {\n options: MaybeRefOrGetter<TItem[]>;\n dense?: MaybeRefOrGetter<boolean>;\n disabled?: MaybeRefOrGetter<boolean>;\n value: Ref<TItem | TItem[] | undefined>;\n menuRef: Ref<HTMLElement> | TemplateRef<HTMLElement>;\n keyAttr?: KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>;\n textAttr?: keyof TItem | ((item: TItem) => string);\n appendWidth?: number;\n prependWidth?: number;\n itemHeight?: number;\n overscan?: number;\n autoSelectFirst?: boolean;\n setValue?: (val: TItem) => void;\n hideSelected?: boolean;\n isOpen?: Ref<boolean>;\n getText?: (item: TItem) => string | undefined;\n getIdentifier?: (item: TItem) => any;\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n itemDisabled?: MaybeRefOrGetter<ItemDisabled<TItem> | undefined>;\n}\n\nexport function useDropdownOptionProperty<TValue, TItem>({\n keyAttr,\n textAttr,\n}: DropdownItemAttr<TValue, TItem>) {\n function getText(item: TItem): string | undefined {\n if (textAttr) {\n if (typeof textAttr === 'function')\n return textAttr(item);\n else return item[textAttr]?.toString();\n }\n\n return item?.toString();\n }\n\n function getIdentifier(\n item: TItem,\n ): TItem | TItem[KeyOfType<TItem, TValue extends Array<infer U> ? U : TValue>] {\n if (keyAttr)\n return item[keyAttr];\n\n return item;\n }\n\n return {\n getIdentifier,\n getText,\n };\n}\n\nfunction toSelectedArray<TItem>(val: TItem | TItem[] | undefined): TItem[] {\n if (Array.isArray(val))\n return val;\n if (val !== null && val !== undefined)\n return [val];\n return [];\n}\n\nexport function useDropdownMenu<TValue, TItem>({\n appendWidth,\n autoSelectFirst,\n dense,\n disabled = false,\n getIdentifier: externalGetIdentifier,\n getText: externalGetText,\n hideSelected,\n isOpen: externalIsOpen,\n itemHeight = getOptionHeight(false),\n keyAttr,\n menuRef: _menuRef,\n options: allOptions,\n overscan = 5,\n prependWidth,\n setValue,\n textAttr,\n value,\n groupBy,\n itemDisabled,\n}: DropdownOptions<TValue, TItem>) {\n const { getIdentifier: defaultGetIdentifier, getText: defaultGetText } = useDropdownOptionProperty({\n keyAttr,\n textAttr,\n });\n\n const getIdentifier = externalGetIdentifier ?? defaultGetIdentifier;\n const getText = externalGetText ?? defaultGetText;\n\n const activeIdentifiers = computed<Set<any>>(() => {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n const identifiers = new Set<any>();\n for (const item of selected) {\n identifiers.add(getIdentifier(item));\n }\n return identifiers;\n });\n\n function isActiveItem(item: TItem): boolean {\n return get(activeIdentifiers).has(getIdentifier(item));\n }\n\n const options = computed<TItem[]>(() => {\n const options = toValue(allOptions);\n if (!hideSelected)\n return options;\n\n return options.filter(item => !isActiveItem(item));\n });\n\n function getGroupKey(item: TItem): string {\n const group = toValue(groupBy);\n if (!group)\n return '';\n\n if (typeof group === 'function')\n return group(item);\n\n return String(item[group] ?? '');\n }\n\n function isItemDisabled(item: TItem): boolean {\n const itemDisabledValue = toValue(itemDisabled);\n if (!itemDisabledValue)\n return false;\n\n if (typeof itemDisabledValue === 'function')\n return itemDisabledValue(item);\n\n return Boolean(item[itemDisabledValue]);\n }\n\n const isGrouped = computed<boolean>(() => toValue(groupBy) !== undefined);\n\n const groupedOptions = computed<DropdownOptionGroup<TItem>[]>(() => {\n if (!get(isGrouped))\n return [];\n\n const buckets = new Map<string, TItem[]>();\n for (const item of get(options)) {\n const key = getGroupKey(item);\n const list = buckets.get(key);\n if (list)\n list.push(item);\n else\n buckets.set(key, [item]);\n }\n\n return Array.from(buckets.entries()).map(([group, items]) => ({ group, items }));\n });\n\n const { containerProps, list, scrollTo, wrapperProps } = useVirtualList<TItem>(options, {\n itemHeight,\n overscan,\n });\n\n // typed as a plain ComputedRef so the published return type names nothing from VueUse\n const renderedData: ComputedRef<{ _index: number; item: TItem }[]> = useArrayMap(list, ({ data, index: _index }) => ({ _index, item: data }));\n\n const isOpen = externalIsOpen ?? shallowRef<boolean>(false);\n\n const valueKey = computed(() => {\n const selected = get(value);\n if (!keyAttr || !selected)\n return selected;\n return Array.isArray(selected) ? selected.map(item => item[keyAttr]) : selected[keyAttr];\n });\n\n const modelHighlightedIndex: Ref<number> = ref(get(autoSelectFirst) ? 0 : -1);\n const modelUserNavigated = shallowRef<boolean>(false);\n\n const optionWidthBounds = computed<{ min: number; max: number }>(() => {\n let min = 0;\n let max = 0;\n for (const option of get(options)) {\n const length = getText(option)?.toString()?.length ?? 0;\n if (min === 0 && max === 0) {\n min = length;\n max = length;\n }\n else if (length < min) {\n min = length;\n }\n else if (length > max) {\n max = length;\n }\n }\n return { min, max };\n });\n\n const menuWidth = computed<string>(() => {\n const { min, max } = get(optionWidthBounds);\n const maxWidth = 30;\n const paddingX = 1.5;\n const fontMultiplier = toValue(dense) ? 12 : 13;\n const difference = max - min;\n\n function computeValue(width: number): string {\n const additionalWidths =\n (prependWidth ? prependWidth + 0.5 : 0) + (appendWidth ? appendWidth + 0.5 : 0);\n return `${Math.min((width * fontMultiplier) / 16 + paddingX + additionalWidths, maxWidth)}rem`;\n }\n\n if (difference <= 5)\n return computeValue(max);\n\n return computeValue(min + difference / 2);\n });\n\n function toggle(state: boolean = false): void {\n set(isOpen, state);\n }\n\n function itemIndexInValue(item: TItem): number {\n const val = get(value);\n const selected: TItem[] = toSelectedArray(val);\n\n if (selected.length === 0)\n return -1;\n\n const itemId = getIdentifier(item);\n return selected.findIndex(selectedItem => getIdentifier(selectedItem) === itemId);\n }\n\n function scrollHighlightedIntoView(): void {\n get(_menuRef)\n ?.querySelector<HTMLElement>('[data-highlighted=\"true\"]')\n ?.scrollIntoView({ block: 'nearest' });\n }\n\n async function adjustScrollByHighlightedIndex(): Promise<void> {\n const index = get(modelHighlightedIndex);\n if (index === -1)\n return;\n\n await nextTick();\n if (get(_menuRef)?.querySelector('[data-highlighted=\"true\"]')) {\n scrollHighlightedIntoView();\n return;\n }\n\n // Outside the virtual list's rendered window, so render it first, then nudge it fully into view\n scrollTo(index);\n await nextTick();\n scrollHighlightedIntoView();\n }\n\n async function updateOpen(open: boolean): Promise<void> {\n if (!open)\n return;\n\n const val = get(value);\n\n // Set highlighted index to active item\n if ((Array.isArray(val) && val.length > 0) || (val !== null && val !== undefined)) {\n const index = get(options).findIndex(isActiveItem);\n if (index > -1)\n set(modelHighlightedIndex, index);\n }\n\n await adjustScrollByHighlightedIndex();\n }\n\n watch([isOpen, () => toValue(disabled)], async ([open, _]) => {\n await updateOpen(open);\n });\n\n watch(modelHighlightedIndex, async () => {\n await adjustScrollByHighlightedIndex();\n });\n\n watch(options, async () => {\n set(modelUserNavigated, false);\n if (get(modelHighlightedIndex) !== -1) {\n if (get(autoSelectFirst)) {\n set(modelHighlightedIndex, 0);\n await adjustScrollByHighlightedIndex();\n }\n else {\n set(modelHighlightedIndex, -1);\n scrollTo(0);\n }\n }\n else {\n scrollTo(0);\n }\n });\n\n watch(isOpen, (open) => {\n if (!open)\n set(modelUserNavigated, false);\n });\n\n const moveHighlight = (up: boolean): void => {\n if (!get(isOpen)) {\n toggle(true);\n return;\n }\n\n set(modelUserNavigated, true);\n\n const items = get(options);\n const total = items.length;\n if (total === 0)\n return;\n\n const move = up ? -1 : 1;\n let position = get(modelHighlightedIndex);\n\n for (let step = 0; step < total; step++) {\n position += move;\n if (position >= total)\n position = 0;\n else if (position < 0)\n position = total - 1;\n\n const candidate = items[position];\n if (candidate !== undefined && !isItemDisabled(candidate)) {\n set(modelHighlightedIndex, position);\n return;\n }\n }\n };\n\n const applyHighlighted = (): void => {\n if (!setValue || !get(isOpen))\n return;\n\n const highlightedIndexVal = get(modelHighlightedIndex);\n if (highlightedIndexVal === -1)\n return;\n\n const entry = get(options)[highlightedIndexVal];\n if (entry !== undefined && !isItemDisabled(entry))\n setValue(entry);\n };\n\n return {\n applyHighlighted,\n containerProps,\n getIdentifier,\n getText,\n groupedOptions,\n modelHighlightedIndex,\n isActiveItem,\n isGrouped,\n isItemDisabled,\n isOpen,\n itemIndexInValue,\n menuWidth,\n moveHighlight,\n optionsWithSelectedHidden: options,\n renderedData,\n toggle,\n modelUserNavigated,\n valueKey,\n wrapperProps,\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
+ import type { MaybeElement } from '../types/dom';
1
2
  import { type VirtualElement as FloatingVirtualElement } from '@floating-ui/dom';
2
- import { type MaybeElement } from '@vueuse/core';
3
3
  import { type MaybeRefOrGetter, type Ref } from 'vue';
4
4
  type VirtualElement = FloatingVirtualElement;
5
5
  export declare const Placement: {
@@ -1,7 +1,7 @@
1
+ import { get, set } from "../vendor/@vueuse/shared/dist/index.js";
2
+ import { unrefElement } from "../vendor/@vueuse/core/dist/index.js";
1
3
  import { useTimeoutManager } from "./timeout-manager.js";
2
4
  import { onMounted, readonly, ref, shallowRef, toValue, watchEffect } from "vue";
3
- import { unrefElement } from "@vueuse/core";
4
- import { get as get$1, set as set$1 } from "@vueuse/shared";
5
5
  import { arrow, autoUpdate, computePosition, flip, offset, shift, size } from "@floating-ui/dom";
6
6
  //#region src/composables/floating.ts
7
7
  var Placement = {
@@ -94,16 +94,16 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
94
94
  const openTimeoutManager = useTimeoutManager();
95
95
  const closeTimeoutManager = useTimeoutManager();
96
96
  function onLeaveComplete() {
97
- set$1(visible, false);
97
+ set(visible, false);
98
98
  }
99
99
  function onOpen(immediate = false) {
100
100
  if (toValue(disabled)) return;
101
101
  closeTimeoutManager.clear();
102
- set$1(leavePending, false);
102
+ set(leavePending, false);
103
103
  if (!openTimeoutManager.isActive()) {
104
- set$1(visible, true);
104
+ set(visible, true);
105
105
  openTimeoutManager.create(() => {
106
- set$1(open, true);
106
+ set(open, true);
107
107
  }, immediate ? 0 : toValue(openDelay));
108
108
  }
109
109
  }
@@ -111,15 +111,15 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
111
111
  if (toValue(disabled)) return;
112
112
  openTimeoutManager.clear();
113
113
  if (!closeTimeoutManager.isActive()) closeTimeoutManager.create(() => {
114
- if (!get$1(open)) onLeaveComplete();
115
- set$1(open, false);
114
+ if (!get(open)) onLeaveComplete();
115
+ set(open, false);
116
116
  }, immediate ? 0 : toValue(closeDelay));
117
117
  }
118
118
  function onLeavePending() {
119
- set$1(leavePending, true);
119
+ set(leavePending, true);
120
120
  }
121
121
  function getValidElements() {
122
- if (!get$1(popover) || !get$1(reference) && !toValue(virtualReference)) return null;
122
+ if (!get(popover) || !get(reference) && !toValue(virtualReference)) return null;
123
123
  const popoverEl = unrefElement(popover);
124
124
  const referenceEl = toValue(virtualReference) || unrefElement(reference);
125
125
  if (!(popoverEl instanceof HTMLElement) || !referenceEl) return null;
@@ -145,7 +145,7 @@ function useFloating(options, disabled = false, openDelay = 0, closeDelay = 0, v
145
145
  position: strategy,
146
146
  top: `${result.y}px`
147
147
  });
148
- set$1(currentPlacement, result.placement);
148
+ set(currentPlacement, result.placement);
149
149
  applyArrowStyles(arrowEl, result);
150
150
  }
151
151
  function startAutoUpdate() {
@@ -1 +1 @@
1
- {"version":3,"file":"floating.js","names":[],"sources":["../../src/composables/floating.ts"],"sourcesContent":["import {\n arrow,\n autoUpdate,\n computePosition,\n type ComputePositionReturn,\n flip,\n type VirtualElement as FloatingVirtualElement,\n type Middleware,\n offset,\n shift,\n size,\n} from '@floating-ui/dom';\nimport { type MaybeElement, unrefElement } from '@vueuse/core';\nimport { type MaybeRefOrGetter, onMounted, type Ref, ref, watchEffect } from 'vue';\nimport { useTimeoutManager } from './timeout-manager';\n\ntype VirtualElement = FloatingVirtualElement;\n\nexport const Placement = {\n bottom: 'bottom',\n bottomEnd: 'bottom-end',\n bottomStart: 'bottom-start',\n left: 'left',\n leftEnd: 'left-end',\n leftStart: 'left-start',\n right: 'right',\n rightEnd: 'right-end',\n rightStart: 'right-start',\n top: 'top',\n topEnd: 'top-end',\n topStart: 'top-start',\n} as const;\n\nexport type Placement = (typeof Placement)[keyof typeof Placement];\n\nexport const Strategy = {\n absolute: 'absolute',\n fixed: 'fixed',\n} as const;\n\nexport type Strategy = (typeof Strategy)[keyof typeof Strategy];\n\nexport interface FloatingOptions {\n /** Preferred placement relative to the reference element; defaults to `Placement.bottom`. */\n placement?: Placement;\n /** CSS positioning strategy; defaults to `Strategy.absolute`. */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element; defaults to 2. */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing; defaults to true. */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware; defaults to 8. */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize; defaults to true. */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n /**\n * Cap the floating element to the space available toward the viewport edge so\n * it never overflows the window. Exposes the measured space as the\n * `--rui-floating-max-height` custom property on the floating element; the\n * content is responsible for consuming it by capping its own max-height to\n * that variable and scrolling internally. Defaults to false.\n */\n size?: boolean;\n}\n\n/** Custom property carrying the space-aware max height set by the size middleware. */\nconst FLOATING_MAX_HEIGHT_VAR = '--rui-floating-max-height';\n\nexport const DEFAULT_FLOATING_OPTIONS: Required<FloatingOptions> = {\n autoUpdate: true,\n flip: true,\n offset: 2,\n placement: Placement.bottom,\n shiftPadding: 8,\n size: false,\n strategy: Strategy.absolute,\n};\n\nexport interface UseFloatingReturn {\n currentPlacement: Readonly<Ref<Placement>>;\n leavePending: Ref<boolean>;\n onClose: (immediate?: boolean) => void;\n onLeaveComplete: () => void;\n onLeavePending: () => void;\n onOpen: (immediate?: boolean) => void;\n open: Ref<boolean>;\n popover: Ref<MaybeElement>;\n reference: Ref<HTMLElement | undefined>;\n updatePosition: () => Promise<void>;\n visible: Ref<boolean>;\n}\n\n/**\n * Cap the floating element to the space available toward the viewport edge and\n * expose it as {@link FLOATING_MAX_HEIGHT_VAR}. The content decides how to use\n * it (cap its own height and scroll internally); writing a custom property\n * instead of a hard max-height keeps this non-invasive for elements that opt in\n * but size themselves differently.\n */\nfunction buildSizeMiddleware(padding: number): Middleware {\n return size({\n padding,\n apply({ availableHeight, elements }) {\n elements.floating.style.setProperty(FLOATING_MAX_HEIGHT_VAR, `${Math.max(0, Math.floor(availableHeight))}px`);\n },\n });\n}\n\n/**\n * The offset middleware, from either the shorthand distance or the per-axis\n * form, falling back to the default distance on the main axis.\n */\nfunction buildOffsetMiddleware(opts: FloatingOptions): Middleware {\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n\n if (typeof off === 'number')\n return offset(off);\n\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n return offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 });\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [buildOffsetMiddleware(opts)];\n\n if (opts.flip !== false)\n mw.push(flip());\n\n // `crossAxis`: when neither side fits, overlap the activator rather than open past the viewport edge\n mw.push(shift({ padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding, crossAxis: true }));\n\n if (arrowEl)\n mw.push(arrow({ element: arrowEl, padding: 4 }));\n\n if (opts.size === true)\n mw.push(buildSizeMiddleware(opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding));\n\n return mw;\n}\n\nfunction applyArrowStyles(arrowEl: HTMLElement | null, result: ComputePositionReturn): void {\n const arrowData = result.middlewareData.arrow;\n if (!arrowEl || !arrowData)\n return;\n\n Object.assign(arrowEl.style, {\n left: arrowData.x != null ? `${arrowData.x}px` : '',\n top: arrowData.y != null ? `${arrowData.y}px` : '',\n });\n}\n\nexport function useFloating(\n options: MaybeRefOrGetter<FloatingOptions>,\n disabled: MaybeRefOrGetter<boolean> = false,\n openDelay: MaybeRefOrGetter<number> = 0,\n closeDelay: MaybeRefOrGetter<number> = 0,\n virtualReference?: MaybeRefOrGetter<Element | VirtualElement | undefined>,\n): UseFloatingReturn {\n const reference = ref<HTMLElement>();\n const popover = ref<MaybeElement>();\n const open = shallowRef<boolean>(false);\n const visible = shallowRef<boolean>(false);\n const leavePending = shallowRef<boolean>(false);\n const currentPlacement = shallowRef<Placement>(toValue(options).placement ?? DEFAULT_FLOATING_OPTIONS.placement);\n\n let cleanupAutoUpdate: (() => void) | null = null;\n\n const openTimeoutManager = useTimeoutManager();\n const closeTimeoutManager = useTimeoutManager();\n\n function onLeaveComplete(): void {\n set(visible, false);\n }\n\n function onOpen(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n closeTimeoutManager.clear();\n\n set(leavePending, false);\n if (!openTimeoutManager.isActive()) {\n set(visible, true);\n\n openTimeoutManager.create(\n () => {\n set(open, true);\n },\n immediate ? 0 : toValue(openDelay),\n );\n }\n }\n\n function onClose(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n openTimeoutManager.clear();\n\n if (!closeTimeoutManager.isActive()) {\n closeTimeoutManager.create(\n () => {\n if (!get(open))\n onLeaveComplete();\n\n set(open, false);\n },\n immediate ? 0 : toValue(closeDelay),\n );\n }\n }\n\n function onLeavePending(): void {\n set(leavePending, true);\n }\n\n function getValidElements(): { popoverEl: HTMLElement; referenceEl: Element | VirtualElement } | null {\n if (!get(popover) || (!get(reference) && !toValue(virtualReference)))\n return null;\n\n const popoverEl = unrefElement(popover);\n const referenceEl = toValue(virtualReference) || unrefElement(reference);\n\n if (!(popoverEl instanceof HTMLElement) || !referenceEl)\n return null;\n\n return { popoverEl, referenceEl };\n }\n\n async function updatePosition(): Promise<void> {\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const arrowEl = popoverEl.querySelector<HTMLElement>('[data-id=\"arrow\"]');\n const strategy = opts.strategy ?? DEFAULT_FLOATING_OPTIONS.strategy;\n\n const result = await computePosition(referenceEl, popoverEl, {\n middleware: buildMiddleware(opts, arrowEl),\n placement: opts.placement ?? DEFAULT_FLOATING_OPTIONS.placement,\n strategy,\n });\n\n Object.assign(popoverEl.style, {\n left: `${result.x}px`,\n position: strategy,\n top: `${result.y}px`,\n });\n\n set(currentPlacement, result.placement);\n applyArrowStyles(arrowEl, result);\n }\n\n function startAutoUpdate(): void {\n stopAutoUpdate();\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const autoUpdateOpt = opts.autoUpdate ?? DEFAULT_FLOATING_OPTIONS.autoUpdate;\n\n if (autoUpdateOpt === false)\n return;\n\n const autoUpdateOptions = typeof autoUpdateOpt === 'object'\n ? {\n ancestorResize: autoUpdateOpt.resize ?? true,\n ancestorScroll: autoUpdateOpt.scroll ?? true,\n elementResize: true,\n }\n : undefined;\n\n cleanupAutoUpdate = autoUpdate(\n referenceEl,\n popoverEl,\n () => { updatePosition().catch(() => {}); },\n autoUpdateOptions,\n );\n }\n\n function stopAutoUpdate(): void {\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n }\n\n onMounted(() => {\n watchEffect((onCleanup) => {\n startAutoUpdate();\n onCleanup(stopAutoUpdate);\n });\n });\n\n return {\n currentPlacement: readonly(currentPlacement),\n leavePending, // eslint-disable-line @rotki/composable-return-readonly -- written by consumer transition hooks\n onClose,\n onLeaveComplete,\n onLeavePending,\n onOpen,\n open, // eslint-disable-line @rotki/composable-return-readonly -- v-model bound by consumers\n popover, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n reference, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n updatePosition,\n visible, // eslint-disable-line @rotki/composable-return-readonly -- used as v-if condition by consumers\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"floating.js","names":[],"sources":["../../src/composables/floating.ts"],"sourcesContent":["import type { MaybeElement } from '@/types/dom';\nimport {\n arrow,\n autoUpdate,\n computePosition,\n type ComputePositionReturn,\n flip,\n type VirtualElement as FloatingVirtualElement,\n type Middleware,\n offset,\n shift,\n size,\n} from '@floating-ui/dom';\nimport { unrefElement } from '@vueuse/core';\nimport { type MaybeRefOrGetter, onMounted, type Ref, ref, watchEffect } from 'vue';\nimport { useTimeoutManager } from './timeout-manager';\n\ntype VirtualElement = FloatingVirtualElement;\n\nexport const Placement = {\n bottom: 'bottom',\n bottomEnd: 'bottom-end',\n bottomStart: 'bottom-start',\n left: 'left',\n leftEnd: 'left-end',\n leftStart: 'left-start',\n right: 'right',\n rightEnd: 'right-end',\n rightStart: 'right-start',\n top: 'top',\n topEnd: 'top-end',\n topStart: 'top-start',\n} as const;\n\nexport type Placement = (typeof Placement)[keyof typeof Placement];\n\nexport const Strategy = {\n absolute: 'absolute',\n fixed: 'fixed',\n} as const;\n\nexport type Strategy = (typeof Strategy)[keyof typeof Strategy];\n\nexport interface FloatingOptions {\n /** Preferred placement relative to the reference element; defaults to `Placement.bottom`. */\n placement?: Placement;\n /** CSS positioning strategy; defaults to `Strategy.absolute`. */\n strategy?: Strategy;\n /** Main-axis and/or cross-axis offset from the reference element; defaults to 2. */\n offset?: number | { mainAxis?: number; crossAxis?: number };\n /** Whether to flip to the opposite side when overflowing; defaults to true. */\n flip?: boolean;\n /** Padding from viewport edges for shift middleware; defaults to 8. */\n shiftPadding?: number;\n /** Whether to auto-update position on scroll/resize; defaults to true. */\n autoUpdate?: boolean | { scroll?: boolean; resize?: boolean };\n /**\n * Cap the floating element to the space available toward the viewport edge so\n * it never overflows the window. Exposes the measured space as the\n * `--rui-floating-max-height` custom property on the floating element; the\n * content is responsible for consuming it by capping its own max-height to\n * that variable and scrolling internally. Defaults to false.\n */\n size?: boolean;\n}\n\n/** Custom property carrying the space-aware max height set by the size middleware. */\nconst FLOATING_MAX_HEIGHT_VAR = '--rui-floating-max-height';\n\nexport const DEFAULT_FLOATING_OPTIONS: Required<FloatingOptions> = {\n autoUpdate: true,\n flip: true,\n offset: 2,\n placement: Placement.bottom,\n shiftPadding: 8,\n size: false,\n strategy: Strategy.absolute,\n};\n\nexport interface UseFloatingReturn {\n currentPlacement: Readonly<Ref<Placement>>;\n leavePending: Ref<boolean>;\n onClose: (immediate?: boolean) => void;\n onLeaveComplete: () => void;\n onLeavePending: () => void;\n onOpen: (immediate?: boolean) => void;\n open: Ref<boolean>;\n popover: Ref<MaybeElement>;\n reference: Ref<HTMLElement | undefined>;\n updatePosition: () => Promise<void>;\n visible: Ref<boolean>;\n}\n\n/**\n * Cap the floating element to the space available toward the viewport edge and\n * expose it as {@link FLOATING_MAX_HEIGHT_VAR}. The content decides how to use\n * it (cap its own height and scroll internally); writing a custom property\n * instead of a hard max-height keeps this non-invasive for elements that opt in\n * but size themselves differently.\n */\nfunction buildSizeMiddleware(padding: number): Middleware {\n return size({\n padding,\n apply({ availableHeight, elements }) {\n elements.floating.style.setProperty(FLOATING_MAX_HEIGHT_VAR, `${Math.max(0, Math.floor(availableHeight))}px`);\n },\n });\n}\n\n/**\n * The offset middleware, from either the shorthand distance or the per-axis\n * form, falling back to the default distance on the main axis.\n */\nfunction buildOffsetMiddleware(opts: FloatingOptions): Middleware {\n const off = opts.offset ?? DEFAULT_FLOATING_OPTIONS.offset;\n\n if (typeof off === 'number')\n return offset(off);\n\n const defaultOffset = typeof DEFAULT_FLOATING_OPTIONS.offset === 'number' ? DEFAULT_FLOATING_OPTIONS.offset : 0;\n return offset({ mainAxis: off.mainAxis ?? defaultOffset, crossAxis: off.crossAxis ?? 0 });\n}\n\nfunction buildMiddleware(opts: FloatingOptions, arrowEl: HTMLElement | null): Middleware[] {\n const mw: Middleware[] = [buildOffsetMiddleware(opts)];\n\n if (opts.flip !== false)\n mw.push(flip());\n\n // `crossAxis`: when neither side fits, overlap the activator rather than open past the viewport edge\n mw.push(shift({ padding: opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding, crossAxis: true }));\n\n if (arrowEl)\n mw.push(arrow({ element: arrowEl, padding: 4 }));\n\n if (opts.size === true)\n mw.push(buildSizeMiddleware(opts.shiftPadding ?? DEFAULT_FLOATING_OPTIONS.shiftPadding));\n\n return mw;\n}\n\nfunction applyArrowStyles(arrowEl: HTMLElement | null, result: ComputePositionReturn): void {\n const arrowData = result.middlewareData.arrow;\n if (!arrowEl || !arrowData)\n return;\n\n Object.assign(arrowEl.style, {\n left: arrowData.x != null ? `${arrowData.x}px` : '',\n top: arrowData.y != null ? `${arrowData.y}px` : '',\n });\n}\n\nexport function useFloating(\n options: MaybeRefOrGetter<FloatingOptions>,\n disabled: MaybeRefOrGetter<boolean> = false,\n openDelay: MaybeRefOrGetter<number> = 0,\n closeDelay: MaybeRefOrGetter<number> = 0,\n virtualReference?: MaybeRefOrGetter<Element | VirtualElement | undefined>,\n): UseFloatingReturn {\n const reference = ref<HTMLElement>();\n const popover = ref<MaybeElement>();\n const open = shallowRef<boolean>(false);\n const visible = shallowRef<boolean>(false);\n const leavePending = shallowRef<boolean>(false);\n const currentPlacement = shallowRef<Placement>(toValue(options).placement ?? DEFAULT_FLOATING_OPTIONS.placement);\n\n let cleanupAutoUpdate: (() => void) | null = null;\n\n const openTimeoutManager = useTimeoutManager();\n const closeTimeoutManager = useTimeoutManager();\n\n function onLeaveComplete(): void {\n set(visible, false);\n }\n\n function onOpen(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n closeTimeoutManager.clear();\n\n set(leavePending, false);\n if (!openTimeoutManager.isActive()) {\n set(visible, true);\n\n openTimeoutManager.create(\n () => {\n set(open, true);\n },\n immediate ? 0 : toValue(openDelay),\n );\n }\n }\n\n function onClose(immediate: boolean = false): void {\n if (toValue(disabled))\n return;\n\n openTimeoutManager.clear();\n\n if (!closeTimeoutManager.isActive()) {\n closeTimeoutManager.create(\n () => {\n if (!get(open))\n onLeaveComplete();\n\n set(open, false);\n },\n immediate ? 0 : toValue(closeDelay),\n );\n }\n }\n\n function onLeavePending(): void {\n set(leavePending, true);\n }\n\n function getValidElements(): { popoverEl: HTMLElement; referenceEl: Element | VirtualElement } | null {\n if (!get(popover) || (!get(reference) && !toValue(virtualReference)))\n return null;\n\n const popoverEl = unrefElement(popover);\n const referenceEl = toValue(virtualReference) || unrefElement(reference);\n\n if (!(popoverEl instanceof HTMLElement) || !referenceEl)\n return null;\n\n return { popoverEl, referenceEl };\n }\n\n async function updatePosition(): Promise<void> {\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const arrowEl = popoverEl.querySelector<HTMLElement>('[data-id=\"arrow\"]');\n const strategy = opts.strategy ?? DEFAULT_FLOATING_OPTIONS.strategy;\n\n const result = await computePosition(referenceEl, popoverEl, {\n middleware: buildMiddleware(opts, arrowEl),\n placement: opts.placement ?? DEFAULT_FLOATING_OPTIONS.placement,\n strategy,\n });\n\n Object.assign(popoverEl.style, {\n left: `${result.x}px`,\n position: strategy,\n top: `${result.y}px`,\n });\n\n set(currentPlacement, result.placement);\n applyArrowStyles(arrowEl, result);\n }\n\n function startAutoUpdate(): void {\n stopAutoUpdate();\n const elements = getValidElements();\n if (!elements)\n return;\n\n const { popoverEl, referenceEl } = elements;\n const opts = toValue(options);\n const autoUpdateOpt = opts.autoUpdate ?? DEFAULT_FLOATING_OPTIONS.autoUpdate;\n\n if (autoUpdateOpt === false)\n return;\n\n const autoUpdateOptions = typeof autoUpdateOpt === 'object'\n ? {\n ancestorResize: autoUpdateOpt.resize ?? true,\n ancestorScroll: autoUpdateOpt.scroll ?? true,\n elementResize: true,\n }\n : undefined;\n\n cleanupAutoUpdate = autoUpdate(\n referenceEl,\n popoverEl,\n () => { updatePosition().catch(() => {}); },\n autoUpdateOptions,\n );\n }\n\n function stopAutoUpdate(): void {\n cleanupAutoUpdate?.();\n cleanupAutoUpdate = null;\n }\n\n onMounted(() => {\n watchEffect((onCleanup) => {\n startAutoUpdate();\n onCleanup(stopAutoUpdate);\n });\n });\n\n return {\n currentPlacement: readonly(currentPlacement),\n leavePending, // eslint-disable-line @rotki/composable-return-readonly -- written by consumer transition hooks\n onClose,\n onLeaveComplete,\n onLeavePending,\n onOpen,\n open, // eslint-disable-line @rotki/composable-return-readonly -- v-model bound by consumers\n popover, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n reference, // eslint-disable-line @rotki/composable-return-readonly -- template ref bound by consumers\n updatePosition,\n visible, // eslint-disable-line @rotki/composable-return-readonly -- used as v-if condition by consumers\n };\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
+ import { get, set, watchDebounced } from "../../../vendor/@vueuse/shared/dist/index.js";
1
2
  import { computed, nextTick, shallowRef, toValue, watch } from "vue";
2
- import { watchDebounced } from "@vueuse/core";
3
- import { get as get$1, set as set$1 } from "@vueuse/shared";
4
3
  //#region src/composables/forms/auto-complete/focus.ts
5
4
  function useAutoCompleteFocus(options, deps) {
6
5
  /**
@@ -8,24 +7,24 @@ function useAutoCompleteFocus(options, deps) {
8
7
  * empty search until the user types, clicks or opens the list again.
9
8
  */
10
9
  const settled = shallowRef(false);
11
- const anyFocused = computed(() => get$1(deps.activatorFocusedWithin) || get$1(deps.menuWrapperFocusedWithin));
12
- const editing = computed(() => get$1(deps.searchInputFocused) && !get$1(settled));
10
+ const anyFocused = computed(() => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin));
11
+ const editing = computed(() => get(deps.searchInputFocused) && !get(settled));
13
12
  const inputClass = computed(() => {
14
- const isFocused = get$1(anyFocused);
13
+ const isFocused = get(anyFocused);
15
14
  const isDisabled = toValue(options.disabled);
16
15
  const shouldApply = toValue(options.shouldApplyValueAsSearch);
17
- const hasSearch = get$1(deps.internalSearch);
16
+ const hasSearch = get(deps.internalSearch);
18
17
  if ((!isFocused || isDisabled) && !shouldApply) return "w-0 h-0";
19
18
  if (hasSearch) return "flex-1 min-w-[4rem]";
20
19
  return "flex-1 min-w-0";
21
20
  });
22
21
  function unsettle() {
23
- set$1(settled, false);
22
+ set(settled, false);
24
23
  }
25
24
  /** Puts focus on the input, as the combobox, while it keeps showing the value just picked. */
26
25
  function settleOnInput() {
27
- set$1(settled, true);
28
- set$1(deps.searchInputFocused, true);
26
+ set(settled, true);
27
+ set(deps.searchInputFocused, true);
29
28
  }
30
29
  /**
31
30
  * The first character typed after a pick replaces the shown value, as it would after tabbing in,
@@ -34,20 +33,20 @@ function useAutoCompleteFocus(options, deps) {
34
33
  * @param event - the key press on the input
35
34
  */
36
35
  function onSettledKeydown(event) {
37
- if (!get$1(settled) || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return;
38
- get$1(deps.textInput)?.select();
36
+ if (!get(settled) || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey) return;
37
+ get(deps.textInput)?.select();
39
38
  unsettle();
40
39
  }
41
40
  async function setInputFocus() {
42
41
  unsettle();
43
42
  await nextTick(() => {
44
- set$1(deps.searchInputFocused, true);
43
+ set(deps.searchInputFocused, true);
45
44
  });
46
45
  }
47
46
  function onInputFocused() {
48
- set$1(deps.focusedValueIndex, -1);
49
- if (toValue(options.shouldApplyValueAsSearch) && !get$1(settled)) get$1(deps.textInput)?.select();
50
- if (!get$1(deps.isOpen)) set$1(deps.justOpened, true);
47
+ set(deps.focusedValueIndex, -1);
48
+ if (toValue(options.shouldApplyValueAsSearch) && !get(settled)) get(deps.textInput)?.select();
49
+ if (!get(deps.isOpen)) set(deps.justOpened, true);
51
50
  }
52
51
  /**
53
52
  * The search text as it stood when focus was lost, kept for the custom-value
@@ -58,11 +57,11 @@ function useAutoCompleteFocus(options, deps) {
58
57
  watch(anyFocused, (focused) => {
59
58
  if (focused) return;
60
59
  unsettle();
61
- if (toValue(options.customValue)) pendingCustomSearch = get$1(deps.internalSearch);
60
+ if (toValue(options.customValue)) pendingCustomSearch = get(deps.internalSearch);
62
61
  });
63
62
  watchDebounced(anyFocused, (focused) => {
64
63
  if (!focused) {
65
- set$1(deps.isOpen, false);
64
+ set(deps.isOpen, false);
66
65
  const customValue = toValue(options.customValue);
67
66
  const searchToUse = pendingCustomSearch;
68
67
  pendingCustomSearch = "";
@@ -1 +1 @@
1
- {"version":3,"file":"focus.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/focus.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport interface UseAutoCompleteFocusOptions {\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether to apply the current value as the search text when focused. */\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n /** Whether the autocomplete is disabled. */\n disabled: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteFocusDeps {\n activatorFocusedWithin: Ref<boolean>;\n focusedValueIndex: Ref<number>;\n internalSearch: Ref<string>;\n isOpen: Ref<boolean>;\n justOpened: Ref<boolean>;\n menuWrapperFocusedWithin: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n textInput: Ref<HTMLInputElement | undefined> | TemplateRef<HTMLInputElement>;\n setSearchAsValue: () => void;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport interface UseAutoCompleteFocusReturn {\n anyFocused: ComputedRef<boolean>;\n /** Whether the user is searching: the input has focus and is not just showing a picked value. */\n editing: ComputedRef<boolean>;\n inputClass: ComputedRef<string>;\n onInputFocused: () => void;\n onSettledKeydown: (event: KeyboardEvent) => void;\n setInputFocus: () => Promise<void>;\n settleOnInput: () => void;\n unsettle: () => void;\n}\n\nexport function useAutoCompleteFocus(\n options: UseAutoCompleteFocusOptions,\n deps: UseAutoCompleteFocusDeps,\n): UseAutoCompleteFocusReturn {\n /**\n * The input holds focus after a pick, as the combobox, but shows the picked value rather than an\n * empty search until the user types, clicks or opens the list again.\n */\n const settled = shallowRef<boolean>(false);\n\n const anyFocused = computed<boolean>(\n () => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin),\n );\n\n const editing = computed<boolean>(() => get(deps.searchInputFocused) && !get(settled));\n\n const inputClass = computed<string>(() => {\n const isFocused = get(anyFocused);\n const isDisabled = toValue(options.disabled);\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n const hasSearch = get(deps.internalSearch);\n\n if ((!isFocused || isDisabled) && !shouldApply)\n return 'w-0 h-0';\n if (hasSearch)\n return 'flex-1 min-w-[4rem]';\n return 'flex-1 min-w-0';\n });\n\n function unsettle(): void {\n set(settled, false);\n }\n\n /** Puts focus on the input, as the combobox, while it keeps showing the value just picked. */\n function settleOnInput(): void {\n set(settled, true);\n set(deps.searchInputFocused, true);\n }\n\n /**\n * The first character typed after a pick replaces the shown value, as it would after tabbing in,\n * rather than adding to it.\n *\n * @param event - the key press on the input\n */\n function onSettledKeydown(event: KeyboardEvent): void {\n if (!get(settled) || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey)\n return;\n get(deps.textInput)?.select();\n unsettle();\n }\n\n async function setInputFocus(): Promise<void> {\n unsettle();\n await nextTick(() => {\n set(deps.searchInputFocused, true);\n });\n }\n\n function onInputFocused(): void {\n set(deps.focusedValueIndex, -1);\n\n // focus coming back after a pick keeps the value as it is, unselected\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (shouldApply && !get(settled)) {\n const textInput = get(deps.textInput);\n textInput?.select();\n }\n\n if (!get(deps.isOpen)) {\n set(deps.justOpened, true);\n }\n }\n\n /**\n * The search text as it stood when focus was lost, kept for the custom-value\n * blur flow: it is captured before the debounced handler runs, because the\n * watchers in value.ts clear the search when the menu closes.\n */\n let pendingCustomSearch = '';\n\n watch(anyFocused, (focused) => {\n if (focused)\n return;\n unsettle();\n if (toValue(options.customValue))\n pendingCustomSearch = get(deps.internalSearch);\n });\n\n // Debounced, so the menu does not close for a moment while focus moves between its own elements\n watchDebounced(\n anyFocused,\n (focused) => {\n if (!focused) {\n set(deps.isOpen, false);\n\n const customValue = toValue(options.customValue);\n const searchToUse = pendingCustomSearch;\n pendingCustomSearch = '';\n\n if (customValue && searchToUse) {\n deps.updateInternalSearch(searchToUse);\n deps.setSearchAsValue();\n }\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (!shouldApply) {\n deps.updateInternalSearch();\n }\n }\n },\n {\n debounce: 100,\n maxWait: 200,\n },\n );\n\n return {\n anyFocused,\n editing,\n inputClass,\n onInputFocused,\n onSettledKeydown,\n setInputFocus,\n settleOnInput,\n unsettle,\n };\n}\n"],"mappings":";;;;AAoCA,SAAgB,qBACd,SACA,MAC4B;;;;;CAK5B,MAAM,UAAU,WAAoB,KAAK;CAEzC,MAAM,aAAa,eACX,MAAI,KAAK,sBAAsB,KAAK,MAAI,KAAK,wBAAwB,CAC7E;CAEA,MAAM,UAAU,eAAwB,MAAI,KAAK,kBAAkB,KAAK,CAAC,MAAI,OAAO,CAAC;CAErF,MAAM,aAAa,eAAuB;EACxC,MAAM,YAAY,MAAI,UAAU;EAChC,MAAM,aAAa,QAAQ,QAAQ,QAAQ;EAC3C,MAAM,cAAc,QAAQ,QAAQ,wBAAwB;EAC5D,MAAM,YAAY,MAAI,KAAK,cAAc;EAEzC,KAAK,CAAC,aAAa,eAAe,CAAC,aACjC,OAAO;EACT,IAAI,WACF,OAAO;EACT,OAAO;CACT,CAAC;CAED,SAAS,WAAiB;EACxB,MAAI,SAAS,KAAK;CACpB;;CAGA,SAAS,gBAAsB;EAC7B,MAAI,SAAS,IAAI;EACjB,MAAI,KAAK,oBAAoB,IAAI;CACnC;;;;;;;CAQA,SAAS,iBAAiB,OAA4B;EACpD,IAAI,CAAC,MAAI,OAAO,KAAK,MAAM,IAAI,WAAW,KAAK,MAAM,WAAW,MAAM,WAAW,MAAM,QACrF;EACF,MAAI,KAAK,SAAS,CAAC,EAAE,OAAO;EAC5B,SAAS;CACX;CAEA,eAAe,gBAA+B;EAC5C,SAAS;EACT,MAAM,eAAe;GACnB,MAAI,KAAK,oBAAoB,IAAI;EACnC,CAAC;CACH;CAEA,SAAS,iBAAuB;EAC9B,MAAI,KAAK,mBAAmB,EAAE;EAI9B,IADoB,QAAQ,QAAQ,wBAChC,KAAe,CAAC,MAAI,OAAO,GAE7B,MADsB,KAAK,SAC3B,CAAA,EAAW,OAAO;EAGpB,IAAI,CAAC,MAAI,KAAK,MAAM,GAClB,MAAI,KAAK,YAAY,IAAI;CAE7B;;;;;;CAOA,IAAI,sBAAsB;CAE1B,MAAM,aAAa,YAAY;EAC7B,IAAI,SACF;EACF,SAAS;EACT,IAAI,QAAQ,QAAQ,WAAW,GAC7B,sBAAsB,MAAI,KAAK,cAAc;CACjD,CAAC;CAGD,eACE,aACC,YAAY;EACX,IAAI,CAAC,SAAS;GACZ,MAAI,KAAK,QAAQ,KAAK;GAEtB,MAAM,cAAc,QAAQ,QAAQ,WAAW;GAC/C,MAAM,cAAc;GACpB,sBAAsB;GAEtB,IAAI,eAAe,aAAa;IAC9B,KAAK,qBAAqB,WAAW;IACrC,KAAK,iBAAiB;GACxB;GAGA,IAAI,CADgB,QAAQ,QAAQ,wBAC/B,GACH,KAAK,qBAAqB;EAE9B;CACF,GACA;EACE,UAAU;EACV,SAAS;CACX,CACF;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
1
+ {"version":3,"file":"focus.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/focus.ts"],"sourcesContent":["import type { ComputedRef, MaybeRefOrGetter, Ref, TemplateRef } from 'vue';\n\nexport interface UseAutoCompleteFocusOptions {\n /** Whether custom (free-text) values are allowed. */\n customValue: MaybeRefOrGetter<boolean>;\n /** Whether to apply the current value as the search text when focused. */\n shouldApplyValueAsSearch: MaybeRefOrGetter<boolean>;\n /** Whether the autocomplete is disabled. */\n disabled: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteFocusDeps {\n activatorFocusedWithin: Ref<boolean>;\n focusedValueIndex: Ref<number>;\n internalSearch: Ref<string>;\n isOpen: Ref<boolean>;\n justOpened: Ref<boolean>;\n menuWrapperFocusedWithin: Ref<boolean>;\n searchInputFocused: Ref<boolean>;\n textInput: Ref<HTMLInputElement | undefined> | TemplateRef<HTMLInputElement>;\n setSearchAsValue: () => void;\n updateInternalSearch: (value?: string) => void;\n}\n\nexport interface UseAutoCompleteFocusReturn {\n anyFocused: ComputedRef<boolean>;\n /** Whether the user is searching: the input has focus and is not just showing a picked value. */\n editing: ComputedRef<boolean>;\n inputClass: ComputedRef<string>;\n onInputFocused: () => void;\n onSettledKeydown: (event: KeyboardEvent) => void;\n setInputFocus: () => Promise<void>;\n settleOnInput: () => void;\n unsettle: () => void;\n}\n\nexport function useAutoCompleteFocus(\n options: UseAutoCompleteFocusOptions,\n deps: UseAutoCompleteFocusDeps,\n): UseAutoCompleteFocusReturn {\n /**\n * The input holds focus after a pick, as the combobox, but shows the picked value rather than an\n * empty search until the user types, clicks or opens the list again.\n */\n const settled = shallowRef<boolean>(false);\n\n const anyFocused = computed<boolean>(\n () => get(deps.activatorFocusedWithin) || get(deps.menuWrapperFocusedWithin),\n );\n\n const editing = computed<boolean>(() => get(deps.searchInputFocused) && !get(settled));\n\n const inputClass = computed<string>(() => {\n const isFocused = get(anyFocused);\n const isDisabled = toValue(options.disabled);\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n const hasSearch = get(deps.internalSearch);\n\n if ((!isFocused || isDisabled) && !shouldApply)\n return 'w-0 h-0';\n if (hasSearch)\n return 'flex-1 min-w-[4rem]';\n return 'flex-1 min-w-0';\n });\n\n function unsettle(): void {\n set(settled, false);\n }\n\n /** Puts focus on the input, as the combobox, while it keeps showing the value just picked. */\n function settleOnInput(): void {\n set(settled, true);\n set(deps.searchInputFocused, true);\n }\n\n /**\n * The first character typed after a pick replaces the shown value, as it would after tabbing in,\n * rather than adding to it.\n *\n * @param event - the key press on the input\n */\n function onSettledKeydown(event: KeyboardEvent): void {\n if (!get(settled) || event.key.length !== 1 || event.ctrlKey || event.metaKey || event.altKey)\n return;\n get(deps.textInput)?.select();\n unsettle();\n }\n\n async function setInputFocus(): Promise<void> {\n unsettle();\n await nextTick(() => {\n set(deps.searchInputFocused, true);\n });\n }\n\n function onInputFocused(): void {\n set(deps.focusedValueIndex, -1);\n\n // focus coming back after a pick keeps the value as it is, unselected\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (shouldApply && !get(settled)) {\n const textInput = get(deps.textInput);\n textInput?.select();\n }\n\n if (!get(deps.isOpen)) {\n set(deps.justOpened, true);\n }\n }\n\n /**\n * The search text as it stood when focus was lost, kept for the custom-value\n * blur flow: it is captured before the debounced handler runs, because the\n * watchers in value.ts clear the search when the menu closes.\n */\n let pendingCustomSearch = '';\n\n watch(anyFocused, (focused) => {\n if (focused)\n return;\n unsettle();\n if (toValue(options.customValue))\n pendingCustomSearch = get(deps.internalSearch);\n });\n\n // Debounced, so the menu does not close for a moment while focus moves between its own elements\n watchDebounced(\n anyFocused,\n (focused) => {\n if (!focused) {\n set(deps.isOpen, false);\n\n const customValue = toValue(options.customValue);\n const searchToUse = pendingCustomSearch;\n pendingCustomSearch = '';\n\n if (customValue && searchToUse) {\n deps.updateInternalSearch(searchToUse);\n deps.setSearchAsValue();\n }\n\n const shouldApply = toValue(options.shouldApplyValueAsSearch);\n if (!shouldApply) {\n deps.updateInternalSearch();\n }\n }\n },\n {\n debounce: 100,\n maxWait: 200,\n },\n );\n\n return {\n anyFocused,\n editing,\n inputClass,\n onInputFocused,\n onSettledKeydown,\n setInputFocus,\n settleOnInput,\n unsettle,\n };\n}\n"],"mappings":";;;AAoCA,SAAgB,qBACd,SACA,MAC4B;;;;;CAK5B,MAAM,UAAU,WAAoB,KAAK;CAEzC,MAAM,aAAa,eACX,IAAI,KAAK,sBAAsB,KAAK,IAAI,KAAK,wBAAwB,CAC7E;CAEA,MAAM,UAAU,eAAwB,IAAI,KAAK,kBAAkB,KAAK,CAAC,IAAI,OAAO,CAAC;CAErF,MAAM,aAAa,eAAuB;EACxC,MAAM,YAAY,IAAI,UAAU;EAChC,MAAM,aAAa,QAAQ,QAAQ,QAAQ;EAC3C,MAAM,cAAc,QAAQ,QAAQ,wBAAwB;EAC5D,MAAM,YAAY,IAAI,KAAK,cAAc;EAEzC,KAAK,CAAC,aAAa,eAAe,CAAC,aACjC,OAAO;EACT,IAAI,WACF,OAAO;EACT,OAAO;CACT,CAAC;CAED,SAAS,WAAiB;EACxB,IAAI,SAAS,KAAK;CACpB;;CAGA,SAAS,gBAAsB;EAC7B,IAAI,SAAS,IAAI;EACjB,IAAI,KAAK,oBAAoB,IAAI;CACnC;;;;;;;CAQA,SAAS,iBAAiB,OAA4B;EACpD,IAAI,CAAC,IAAI,OAAO,KAAK,MAAM,IAAI,WAAW,KAAK,MAAM,WAAW,MAAM,WAAW,MAAM,QACrF;EACF,IAAI,KAAK,SAAS,CAAC,EAAE,OAAO;EAC5B,SAAS;CACX;CAEA,eAAe,gBAA+B;EAC5C,SAAS;EACT,MAAM,eAAe;GACnB,IAAI,KAAK,oBAAoB,IAAI;EACnC,CAAC;CACH;CAEA,SAAS,iBAAuB;EAC9B,IAAI,KAAK,mBAAmB,EAAE;EAI9B,IADoB,QAAQ,QAAQ,wBAChC,KAAe,CAAC,IAAI,OAAO,GAE7B,IADsB,KAAK,SAC3B,CAAA,EAAW,OAAO;EAGpB,IAAI,CAAC,IAAI,KAAK,MAAM,GAClB,IAAI,KAAK,YAAY,IAAI;CAE7B;;;;;;CAOA,IAAI,sBAAsB;CAE1B,MAAM,aAAa,YAAY;EAC7B,IAAI,SACF;EACF,SAAS;EACT,IAAI,QAAQ,QAAQ,WAAW,GAC7B,sBAAsB,IAAI,KAAK,cAAc;CACjD,CAAC;CAGD,eACE,aACC,YAAY;EACX,IAAI,CAAC,SAAS;GACZ,IAAI,KAAK,QAAQ,KAAK;GAEtB,MAAM,cAAc,QAAQ,QAAQ,WAAW;GAC/C,MAAM,cAAc;GACpB,sBAAsB;GAEtB,IAAI,eAAe,aAAa;IAC9B,KAAK,qBAAqB,WAAW;IACrC,KAAK,iBAAiB;GACxB;GAGA,IAAI,CADgB,QAAQ,QAAQ,wBAC/B,GACH,KAAK,qBAAqB;EAE9B;CACF,GACA;EACE,UAAU;EACV,SAAS;CACX,CACF;CAEA,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;AACF"}
@@ -1,5 +1,5 @@
1
+ import { get, set } from "../../../vendor/@vueuse/shared/dist/index.js";
1
2
  import { ref, toValue, watch } from "vue";
2
- import { get, set } from "@vueuse/shared";
3
3
  //#region src/composables/forms/auto-complete/keyboard-navigation.ts
4
4
  function useAutoCompleteKeyboardNavigation(options, deps) {
5
5
  const focusedValueIndex = ref(-1);
@@ -1,7 +1,6 @@
1
+ import { get, refDebounced, set } from "../../../vendor/@vueuse/shared/dist/index.js";
1
2
  import { getTextToken } from "../../../utils/helpers.js";
2
3
  import { computed, onUnmounted, readonly, shallowRef, toValue, watch } from "vue";
3
- import { refDebounced } from "@vueuse/core";
4
- import { get as get$1, set as set$1 } from "@vueuse/shared";
5
4
  //#region src/composables/forms/auto-complete/search.ts
6
5
  function useAutoCompleteSearch(options, searchModel, opts) {
7
6
  const internalSearch = shallowRef("");
@@ -31,9 +30,9 @@ function useAutoCompleteSearch(options, searchModel, opts) {
31
30
  return String(item?.[groupBy] ?? "");
32
31
  };
33
32
  const filteredOptions = computed(() => {
34
- const search = get$1(debouncedInternalSearch);
33
+ const search = get(debouncedInternalSearch);
35
34
  const optionsValue = toValue(options);
36
- if (toValue(opts.noFilter) || !search || get$1(justOpened)) return optionsValue;
35
+ if (toValue(opts.noFilter) || !search || get(justOpened)) return optionsValue;
37
36
  const keyAttr = toValue(opts.keyAttr);
38
37
  const textAttr = toValue(opts.textAttr);
39
38
  const filter = toValue(opts.filter);
@@ -72,11 +71,11 @@ function useAutoCompleteSearch(options, searchModel, opts) {
72
71
  };
73
72
  }
74
73
  function updateInternalSearch(value = "") {
75
- set$1(searchModel, value);
76
- set$1(internalSearch, value);
74
+ set(searchModel, value);
75
+ set(internalSearch, value);
77
76
  }
78
77
  watch(searchModel, (search) => {
79
- set$1(internalSearch, search);
78
+ set(internalSearch, search);
80
79
  }, { immediate: true });
81
80
  onUnmounted(() => {
82
81
  tokenCache.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/search.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref } from 'vue';\nimport type { GroupBy } from '@/composables/dropdown-menu';\nimport { get, set } from '@vueuse/shared';\nimport { getTextToken } from '@/utils/helpers';\n\nexport interface UseAutoCompleteSearchOptions<TItem> {\n /** The property used as the unique identifier for each item. */\n keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** The property used to display text for each item. */\n textAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** Whether to disable client-side filtering of options. */\n noFilter?: MaybeRefOrGetter<boolean>;\n /** Custom filter function to match items against the search query. */\n filter?: MaybeRefOrGetter<((item: TItem, queryText: string, group?: string) => boolean) | undefined>;\n /** Whether custom (free-text) values are allowed. */\n customValue?: MaybeRefOrGetter<boolean>;\n /** Whether to hide the custom value option from the dropdown. */\n hideCustomValue?: MaybeRefOrGetter<boolean>;\n /** Whether to return the full item object instead of just the key. */\n returnObject?: MaybeRefOrGetter<boolean>;\n /** How items are grouped, used to resolve group labels for filtering. */\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n /** When true and `groupBy` is set, the default filter also matches the resolved group label. */\n searchIncludesGroupLabel?: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteSearchReturn<TItem> {\n internalSearch: Readonly<Ref<string>>;\n debouncedInternalSearch: Readonly<Ref<string>>;\n filteredOptions: Readonly<Ref<TItem[]>>;\n justOpened: Ref<boolean>;\n updateInternalSearch: (value?: string) => void;\n textValueToProperValue: (val: any, returnObject?: boolean) => TItem;\n}\n\nexport function useAutoCompleteSearch<TItem>(\n options: MaybeRefOrGetter<TItem[]>,\n searchModel: Ref<string>,\n opts: UseAutoCompleteSearchOptions<TItem>,\n): UseAutoCompleteSearchReturn<TItem> {\n const internalSearch = shallowRef<string>('');\n const debouncedInternalSearch = refDebounced(internalSearch, 50);\n const justOpened = shallowRef<boolean>(false);\n\n // Map iteration order is insertion order, so deleting the first key evicts the oldest token\n const MAX_CACHE_SIZE = 100;\n const tokenCache = new Map<string, string>();\n const getCachedTextToken = (text: string): string => {\n const cached = tokenCache.get(text);\n if (cached !== undefined)\n return cached;\n\n if (tokenCache.size >= MAX_CACHE_SIZE) {\n const oldest = tokenCache.keys().next().value;\n if (oldest !== undefined)\n tokenCache.delete(oldest);\n }\n\n const token = getTextToken(text);\n tokenCache.set(text, token);\n return token;\n };\n\n /**\n * The group label an item sits under. Mirrors `getGroupKey` in\n * dropdown-menu.ts, so the filter matches the labels the rendered group\n * headers show.\n */\n const resolveGroup = (item: TItem, groupBy: GroupBy<TItem> | undefined): string | undefined => {\n if (!groupBy)\n return undefined;\n\n if (typeof groupBy === 'function')\n return groupBy(item);\n\n return String((item as any)?.[groupBy] ?? '');\n };\n\n const filteredOptions = computed<TItem[]>(() => {\n const search = get(debouncedInternalSearch);\n const optionsValue = toValue(options);\n\n const noFilter = toValue(opts.noFilter);\n if (noFilter || !search || get(justOpened))\n return optionsValue;\n\n const keyAttr = toValue(opts.keyAttr);\n const textAttr = toValue(opts.textAttr);\n const filter = toValue(opts.filter);\n const groupBy = toValue(opts.groupBy);\n const searchIncludesGroupLabel = toValue(opts.searchIncludesGroupLabel);\n\n // Cache the search token once\n const searchToken = getCachedTextToken(search);\n\n const filtered = filter\n ? optionsValue.filter(item => filter(item, search, resolveGroup(item, groupBy)))\n : optionsValue.filter((item) => {\n if (!item)\n return false;\n\n const keywords: string[] = [getCachedTextToken(keyAttr ? String((item as any)[keyAttr]) : item.toString())];\n\n if (textAttr && typeof item === 'object')\n keywords.push(getCachedTextToken(String((item as any)[textAttr])));\n\n // Matching the group label too surfaces every item under a \"Trade\" section for \"trade\"\n if (searchIncludesGroupLabel && groupBy) {\n const group = resolveGroup(item, groupBy);\n if (group)\n keywords.push(getCachedTextToken(group));\n }\n\n return keywords.some(keyword => keyword.includes(searchToken));\n });\n\n const customValue = toValue(opts.customValue);\n const hideCustomValue = toValue(opts.hideCustomValue);\n if (!customValue || hideCustomValue || !search) {\n return filtered;\n }\n\n // Use a more efficient check for custom value inclusion\n const isCustomValueIncluded = filtered.some((item) => {\n if (!item) {\n return false;\n }\n\n const val = textAttr ? (item as any)[textAttr] : item.toString();\n return val === search;\n });\n\n if (isCustomValueIncluded) {\n return filtered;\n }\n\n return [textValueToProperValue(search, {\n keyAttr,\n returnObject: toValue(opts.returnObject),\n textAttr,\n }), ...filtered];\n });\n\n function textValueToProperValue(val: any, options: { keyAttr?: keyof TItem; textAttr?: keyof TItem; returnObject?: boolean }): TItem {\n const { keyAttr, returnObject, textAttr } = options;\n if (!keyAttr || returnObject)\n return val;\n\n return {\n [keyAttr]: val,\n ...(\n textAttr\n ? { [textAttr]: val }\n : {}\n ),\n } as TItem;\n }\n\n function updateInternalSearch(value: string = ''): void {\n set(searchModel, value);\n set(internalSearch, value);\n }\n\n watch(searchModel, (search) => {\n set(internalSearch, search);\n }, { immediate: true });\n\n // Clear token cache when component unmounts to prevent memory leaks\n onUnmounted(() => {\n tokenCache.clear();\n });\n\n return {\n debouncedInternalSearch,\n filteredOptions,\n internalSearch: readonly(internalSearch),\n justOpened, // eslint-disable-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused and component setValue\n textValueToProperValue: (val: any, returnObjectOverride: boolean = false) => textValueToProperValue(val, {\n keyAttr: toValue(opts.keyAttr),\n returnObject: returnObjectOverride || toValue(opts.returnObject),\n textAttr: toValue(opts.textAttr),\n }),\n updateInternalSearch,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"search.js","names":[],"sources":["../../../../src/composables/forms/auto-complete/search.ts"],"sourcesContent":["import type { MaybeRefOrGetter, Ref } from 'vue';\nimport type { GroupBy } from '@/composables/dropdown-menu';\nimport { get, set } from '@vueuse/shared';\nimport { getTextToken } from '@/utils/helpers';\n\nexport interface UseAutoCompleteSearchOptions<TItem> {\n /** The property used as the unique identifier for each item. */\n keyAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** The property used to display text for each item. */\n textAttr?: MaybeRefOrGetter<keyof TItem | undefined>;\n /** Whether to disable client-side filtering of options. */\n noFilter?: MaybeRefOrGetter<boolean>;\n /** Custom filter function to match items against the search query. */\n filter?: MaybeRefOrGetter<((item: TItem, queryText: string, group?: string) => boolean) | undefined>;\n /** Whether custom (free-text) values are allowed. */\n customValue?: MaybeRefOrGetter<boolean>;\n /** Whether to hide the custom value option from the dropdown. */\n hideCustomValue?: MaybeRefOrGetter<boolean>;\n /** Whether to return the full item object instead of just the key. */\n returnObject?: MaybeRefOrGetter<boolean>;\n /** How items are grouped, used to resolve group labels for filtering. */\n groupBy?: MaybeRefOrGetter<GroupBy<TItem> | undefined>;\n /** When true and `groupBy` is set, the default filter also matches the resolved group label. */\n searchIncludesGroupLabel?: MaybeRefOrGetter<boolean>;\n}\n\nexport interface UseAutoCompleteSearchReturn<TItem> {\n internalSearch: Readonly<Ref<string>>;\n debouncedInternalSearch: Readonly<Ref<string>>;\n filteredOptions: Readonly<Ref<TItem[]>>;\n justOpened: Ref<boolean>;\n updateInternalSearch: (value?: string) => void;\n textValueToProperValue: (val: any, returnObject?: boolean) => TItem;\n}\n\nexport function useAutoCompleteSearch<TItem>(\n options: MaybeRefOrGetter<TItem[]>,\n searchModel: Ref<string>,\n opts: UseAutoCompleteSearchOptions<TItem>,\n): UseAutoCompleteSearchReturn<TItem> {\n const internalSearch = shallowRef<string>('');\n const debouncedInternalSearch = refDebounced(internalSearch, 50);\n const justOpened = shallowRef<boolean>(false);\n\n // Map iteration order is insertion order, so deleting the first key evicts the oldest token\n const MAX_CACHE_SIZE = 100;\n const tokenCache = new Map<string, string>();\n const getCachedTextToken = (text: string): string => {\n const cached = tokenCache.get(text);\n if (cached !== undefined)\n return cached;\n\n if (tokenCache.size >= MAX_CACHE_SIZE) {\n const oldest = tokenCache.keys().next().value;\n if (oldest !== undefined)\n tokenCache.delete(oldest);\n }\n\n const token = getTextToken(text);\n tokenCache.set(text, token);\n return token;\n };\n\n /**\n * The group label an item sits under. Mirrors `getGroupKey` in\n * dropdown-menu.ts, so the filter matches the labels the rendered group\n * headers show.\n */\n const resolveGroup = (item: TItem, groupBy: GroupBy<TItem> | undefined): string | undefined => {\n if (!groupBy)\n return undefined;\n\n if (typeof groupBy === 'function')\n return groupBy(item);\n\n return String((item as any)?.[groupBy] ?? '');\n };\n\n const filteredOptions = computed<TItem[]>(() => {\n const search = get(debouncedInternalSearch);\n const optionsValue = toValue(options);\n\n const noFilter = toValue(opts.noFilter);\n if (noFilter || !search || get(justOpened))\n return optionsValue;\n\n const keyAttr = toValue(opts.keyAttr);\n const textAttr = toValue(opts.textAttr);\n const filter = toValue(opts.filter);\n const groupBy = toValue(opts.groupBy);\n const searchIncludesGroupLabel = toValue(opts.searchIncludesGroupLabel);\n\n // Cache the search token once\n const searchToken = getCachedTextToken(search);\n\n const filtered = filter\n ? optionsValue.filter(item => filter(item, search, resolveGroup(item, groupBy)))\n : optionsValue.filter((item) => {\n if (!item)\n return false;\n\n const keywords: string[] = [getCachedTextToken(keyAttr ? String((item as any)[keyAttr]) : item.toString())];\n\n if (textAttr && typeof item === 'object')\n keywords.push(getCachedTextToken(String((item as any)[textAttr])));\n\n // Matching the group label too surfaces every item under a \"Trade\" section for \"trade\"\n if (searchIncludesGroupLabel && groupBy) {\n const group = resolveGroup(item, groupBy);\n if (group)\n keywords.push(getCachedTextToken(group));\n }\n\n return keywords.some(keyword => keyword.includes(searchToken));\n });\n\n const customValue = toValue(opts.customValue);\n const hideCustomValue = toValue(opts.hideCustomValue);\n if (!customValue || hideCustomValue || !search) {\n return filtered;\n }\n\n // Use a more efficient check for custom value inclusion\n const isCustomValueIncluded = filtered.some((item) => {\n if (!item) {\n return false;\n }\n\n const val = textAttr ? (item as any)[textAttr] : item.toString();\n return val === search;\n });\n\n if (isCustomValueIncluded) {\n return filtered;\n }\n\n return [textValueToProperValue(search, {\n keyAttr,\n returnObject: toValue(opts.returnObject),\n textAttr,\n }), ...filtered];\n });\n\n function textValueToProperValue(val: any, options: { keyAttr?: keyof TItem; textAttr?: keyof TItem; returnObject?: boolean }): TItem {\n const { keyAttr, returnObject, textAttr } = options;\n if (!keyAttr || returnObject)\n return val;\n\n return {\n [keyAttr]: val,\n ...(\n textAttr\n ? { [textAttr]: val }\n : {}\n ),\n } as TItem;\n }\n\n function updateInternalSearch(value: string = ''): void {\n set(searchModel, value);\n set(internalSearch, value);\n }\n\n watch(searchModel, (search) => {\n set(internalSearch, search);\n }, { immediate: true });\n\n // Clear token cache when component unmounts to prevent memory leaks\n onUnmounted(() => {\n tokenCache.clear();\n });\n\n return {\n debouncedInternalSearch,\n filteredOptions,\n internalSearch: readonly(internalSearch),\n justOpened, // eslint-disable-line @rotki/composable-return-readonly -- written by focus.ts onInputFocused and component setValue\n textValueToProperValue: (val: any, returnObjectOverride: boolean = false) => textValueToProperValue(val, {\n keyAttr: toValue(opts.keyAttr),\n returnObject: returnObjectOverride || toValue(opts.returnObject),\n textAttr: toValue(opts.textAttr),\n }),\n updateInternalSearch,\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
+ import { get, set } from "../../../vendor/@vueuse/shared/dist/index.js";
1
2
  import { nextTick } from "vue";
2
- import { get, set } from "@vueuse/shared";
3
3
  //#region src/composables/forms/auto-complete/selection.ts
4
4
  /**
5
5
  * The changes to the auto-complete's selection: picking or dropping an item, taking the typed text
@@ -1,7 +1,7 @@
1
1
  import { assert } from "../../../utils/assert.js";
2
+ import { get, set } from "../../../vendor/@vueuse/shared/dist/index.js";
2
3
  import { isEqual } from "../../../utils/is-equal.js";
3
4
  import { computed, toValue, watch } from "vue";
4
- import { get, set } from "@vueuse/shared";
5
5
  //#region src/composables/forms/auto-complete/value.ts
6
6
  function useAutoCompleteValue(modelValue, options, opts, deps) {
7
7
  function buildOptionsMap(optionsData) {
@@ -1,6 +1,6 @@
1
+ import { get, set } from "../../../vendor/@vueuse/shared/dist/index.js";
1
2
  import { useDropdownOptionProperty } from "../../dropdown-menu.js";
2
3
  import { computed, readonly, shallowRef, toValue, watch } from "vue";
3
- import { get, set } from "@vueuse/shared";
4
4
  //#region src/composables/forms/category-picker/use-category-picker.ts
5
5
  /**
6
6
  * Owns the grouping, filtering and selection state for `RuiCategoryPicker`.
@@ -1,7 +1,7 @@
1
1
  import { assert } from "../../utils/assert.js";
2
+ import { get, set } from "../../vendor/@vueuse/shared/dist/index.js";
3
+ import { useResizeObserver } from "../../vendor/@vueuse/core/dist/index.js";
2
4
  import { readonly, shallowRef } from "vue";
3
- import { useResizeObserver } from "@vueuse/core";
4
- import { get as get$1, set as set$1 } from "@vueuse/shared";
5
5
  //#region src/composables/forms/use-prepend-append-width.ts
6
6
  /**
7
7
  * Tracks how much room a field's prepend and append regions take.
@@ -22,14 +22,14 @@ function usePrependAppendWidth(prepend, append, offset = 0) {
22
22
  const prependWidth = shallowRef("0px");
23
23
  const appendWidth = shallowRef("0px");
24
24
  useResizeObserver(prepend, () => {
25
- const target = get$1(prepend);
25
+ const target = get(prepend);
26
26
  assert(target);
27
- set$1(prependWidth, `${target.offsetWidth + offset}px`);
27
+ set(prependWidth, `${target.offsetWidth + offset}px`);
28
28
  });
29
29
  useResizeObserver(append, () => {
30
- const target = get$1(append);
30
+ const target = get(append);
31
31
  assert(target);
32
- set$1(appendWidth, `${target.offsetWidth + offset}px`);
32
+ set(appendWidth, `${target.offsetWidth + offset}px`);
33
33
  });
34
34
  return {
35
35
  appendWidth: readonly(appendWidth),
@@ -1 +1 @@
1
- {"version":3,"file":"use-prepend-append-width.js","names":[],"sources":["../../../src/composables/forms/use-prepend-append-width.ts"],"sourcesContent":["import type { ShallowRef } from 'vue';\nimport { assert } from '@/utils/assert';\n\nexport interface PrependAppendWidth {\n prependWidth: Readonly<ShallowRef<string>>;\n appendWidth: Readonly<ShallowRef<string>>;\n}\n\n/**\n * Tracks how much room a field's prepend and append regions take.\n *\n * Each is measured by its outer border-box width, so a caller gets the whole\n * space the region occupies, both paddings included. The earlier\n * `contentRect.width + contentRect.left` form added padding-left but dropped\n * padding-right, so a prepend slot styled with `pr-3` alone reported 12px\n * short and the floated label landed under the icon's trailing padding\n * instead of aligned with the input text.\n *\n * @param prepend - the prepend region's element\n * @param append - the append region's element\n * @param offset - extra width to add to the prepend measurement\n * @returns both widths, in px, as CSS lengths\n */\nexport function usePrependAppendWidth(\n prepend: Readonly<ShallowRef<HTMLDivElement | null>>,\n append: Readonly<ShallowRef<HTMLDivElement | null>>,\n offset: number = 0,\n): PrependAppendWidth {\n const prependWidth = shallowRef<string>('0px');\n const appendWidth = shallowRef<string>('0px');\n\n useResizeObserver(prepend, () => {\n const target = get(prepend);\n assert(target);\n set(prependWidth, `${target.offsetWidth + offset}px`);\n });\n\n useResizeObserver(append, () => {\n const target = get(append);\n assert(target);\n set(appendWidth, `${target.offsetWidth + offset}px`);\n });\n\n return {\n appendWidth: readonly(appendWidth),\n prependWidth: readonly(prependWidth),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,sBACd,SACA,QACA,SAAiB,GACG;CACpB,MAAM,eAAe,WAAmB,KAAK;CAC7C,MAAM,cAAc,WAAmB,KAAK;CAE5C,kBAAkB,eAAe;EAC/B,MAAM,SAAS,MAAI,OAAO;EAC1B,OAAO,MAAM;EACb,MAAI,cAAc,GAAG,OAAO,cAAc,OAAO,GAAG;CACtD,CAAC;CAED,kBAAkB,cAAc;EAC9B,MAAM,SAAS,MAAI,MAAM;EACzB,OAAO,MAAM;EACb,MAAI,aAAa,GAAG,OAAO,cAAc,OAAO,GAAG;CACrD,CAAC;CAED,OAAO;EACL,aAAa,SAAS,WAAW;EACjC,cAAc,SAAS,YAAY;CACrC;AACF"}
1
+ {"version":3,"file":"use-prepend-append-width.js","names":[],"sources":["../../../src/composables/forms/use-prepend-append-width.ts"],"sourcesContent":["import type { ShallowRef } from 'vue';\nimport { assert } from '@/utils/assert';\n\nexport interface PrependAppendWidth {\n prependWidth: Readonly<ShallowRef<string>>;\n appendWidth: Readonly<ShallowRef<string>>;\n}\n\n/**\n * Tracks how much room a field's prepend and append regions take.\n *\n * Each is measured by its outer border-box width, so a caller gets the whole\n * space the region occupies, both paddings included. The earlier\n * `contentRect.width + contentRect.left` form added padding-left but dropped\n * padding-right, so a prepend slot styled with `pr-3` alone reported 12px\n * short and the floated label landed under the icon's trailing padding\n * instead of aligned with the input text.\n *\n * @param prepend - the prepend region's element\n * @param append - the append region's element\n * @param offset - extra width to add to the prepend measurement\n * @returns both widths, in px, as CSS lengths\n */\nexport function usePrependAppendWidth(\n prepend: Readonly<ShallowRef<HTMLDivElement | null>>,\n append: Readonly<ShallowRef<HTMLDivElement | null>>,\n offset: number = 0,\n): PrependAppendWidth {\n const prependWidth = shallowRef<string>('0px');\n const appendWidth = shallowRef<string>('0px');\n\n useResizeObserver(prepend, () => {\n const target = get(prepend);\n assert(target);\n set(prependWidth, `${target.offsetWidth + offset}px`);\n });\n\n useResizeObserver(append, () => {\n const target = get(append);\n assert(target);\n set(appendWidth, `${target.offsetWidth + offset}px`);\n });\n\n return {\n appendWidth: readonly(appendWidth),\n prependWidth: readonly(prependWidth),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,sBACd,SACA,QACA,SAAiB,GACG;CACpB,MAAM,eAAe,WAAmB,KAAK;CAC7C,MAAM,cAAc,WAAmB,KAAK;CAE5C,kBAAkB,eAAe;EAC/B,MAAM,SAAS,IAAI,OAAO;EAC1B,OAAO,MAAM;EACb,IAAI,cAAc,GAAG,OAAO,cAAc,OAAO,GAAG;CACtD,CAAC;CAED,kBAAkB,cAAc;EAC9B,MAAM,SAAS,IAAI,MAAM;EACzB,OAAO,MAAM;EACb,IAAI,aAAa,GAAG,OAAO,cAAc,OAAO,GAAG;CACrD,CAAC;CAED,OAAO;EACL,aAAa,SAAS,WAAW;EACjC,cAAc,SAAS,YAAY;CACrC;AACF"}
@@ -1,6 +1,6 @@
1
+ import { get, set } from "../vendor/@vueuse/shared/dist/index.js";
2
+ import { useMutationObserver, useResizeObserver } from "../vendor/@vueuse/core/dist/index.js";
1
3
  import { computed, onMounted, shallowRef } from "vue";
2
- import { useMutationObserver, useResizeObserver } from "@vueuse/core";
3
- import { get as get$1, set as set$1 } from "@vueuse/shared";
4
4
  //#region src/composables/keyboard-scroll.ts
5
5
  /** What a keyboard user can tab to inside a scrolling box, and so scroll it by. */
6
6
  var FOCUSABLE = [
@@ -33,8 +33,8 @@ function useKeyboardScroll(target) {
33
33
  let scheduled = false;
34
34
  function update() {
35
35
  scheduled = false;
36
- const element = get$1(target);
37
- set$1(focusable, element ? needsOwnFocus(element) : false);
36
+ const element = get(target);
37
+ set(focusable, element ? needsOwnFocus(element) : false);
38
38
  }
39
39
  /** Reading the scroll sizes forces layout, so a burst of resizes and mutations is checked once a frame. */
40
40
  function schedule() {
@@ -50,7 +50,7 @@ function useKeyboardScroll(target) {
50
50
  attributes: true,
51
51
  attributeFilter: ["disabled", "tabindex"]
52
52
  });
53
- return computed(() => get$1(focusable) ? 0 : void 0);
53
+ return computed(() => get(focusable) ? 0 : void 0);
54
54
  }
55
55
  //#endregion
56
56
  export { needsOwnFocus, useKeyboardScroll };
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-scroll.js","names":[],"sources":["../../src/composables/keyboard-scroll.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\nimport { useMutationObserver, useResizeObserver } from '@vueuse/core';\n\n/** What a keyboard user can tab to inside a scrolling box, and so scroll it by. */\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=hidden])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\n/**\n * Whether a box scrolls while holding nothing a keyboard user can reach, the case WCAG 2.1.1 and\n * axe's scrollable-region-focusable rule cover: the arrow keys only scroll what has focus.\n *\n * @param element - the scrolling box\n * @returns true when the box overflows and has no focusable content\n */\nexport function needsOwnFocus(element: HTMLElement): boolean {\n const overflows = element.scrollWidth > element.clientWidth + 1 || element.scrollHeight > element.clientHeight + 1;\n return overflows && element.querySelector(FOCUSABLE) === null;\n}\n\n/**\n * Makes a scrolling box a tab stop while, and only while, it overflows with nothing focusable\n * inside, so keyboard users can scroll it without a stray tab stop on every box that fits.\n *\n * @param target - the scrolling box\n * @returns the `tabindex` to bind on the box: 0 when it needs focus, otherwise undefined\n */\nexport function useKeyboardScroll(target: Readonly<Ref<HTMLElement | null | undefined>>): ComputedRef<0 | undefined> {\n const focusable = shallowRef<boolean>(false);\n let scheduled = false;\n\n function update(): void {\n scheduled = false;\n const element = get(target);\n set(focusable, element ? needsOwnFocus(element) : false);\n }\n\n /** Reading the scroll sizes forces layout, so a burst of resizes and mutations is checked once a frame. */\n function schedule(): void {\n if (scheduled)\n return;\n scheduled = true;\n requestAnimationFrame(update);\n }\n\n // the first check runs at mount, so the box is reachable from its first render, not a frame later\n onMounted(update);\n useResizeObserver(target, schedule);\n // the box keeps its size while its content grows or swaps, which changes whether it overflows\n useMutationObserver(target, schedule, { childList: true, subtree: true, attributes: true, attributeFilter: ['disabled', 'tabindex'] });\n\n return computed<0 | undefined>(() => (get(focusable) ? 0 : undefined));\n}\n"],"mappings":";;;;;AAIA,IAAM,YAAY;CAChB;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;;;;;;;;AASV,SAAgB,cAAc,SAA+B;CAE3D,QADkB,QAAQ,cAAc,QAAQ,cAAc,KAAK,QAAQ,eAAe,QAAQ,eAAe,MAC7F,QAAQ,cAAc,SAAS,MAAM;AAC3D;;;;;;;;AASA,SAAgB,kBAAkB,QAAmF;CACnH,MAAM,YAAY,WAAoB,KAAK;CAC3C,IAAI,YAAY;CAEhB,SAAS,SAAe;EACtB,YAAY;EACZ,MAAM,UAAU,MAAI,MAAM;EAC1B,MAAI,WAAW,UAAU,cAAc,OAAO,IAAI,KAAK;CACzD;;CAGA,SAAS,WAAiB;EACxB,IAAI,WACF;EACF,YAAY;EACZ,sBAAsB,MAAM;CAC9B;CAGA,UAAU,MAAM;CAChB,kBAAkB,QAAQ,QAAQ;CAElC,oBAAoB,QAAQ,UAAU;EAAE,WAAW;EAAM,SAAS;EAAM,YAAY;EAAM,iBAAiB,CAAC,YAAY,UAAU;CAAE,CAAC;CAErI,OAAO,eAA+B,MAAI,SAAS,IAAI,IAAI,KAAA,CAAU;AACvE"}
1
+ {"version":3,"file":"keyboard-scroll.js","names":[],"sources":["../../src/composables/keyboard-scroll.ts"],"sourcesContent":["import type { ComputedRef, Ref } from 'vue';\nimport { useMutationObserver, useResizeObserver } from '@vueuse/core';\n\n/** What a keyboard user can tab to inside a scrolling box, and so scroll it by. */\nconst FOCUSABLE = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=hidden])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\n/**\n * Whether a box scrolls while holding nothing a keyboard user can reach, the case WCAG 2.1.1 and\n * axe's scrollable-region-focusable rule cover: the arrow keys only scroll what has focus.\n *\n * @param element - the scrolling box\n * @returns true when the box overflows and has no focusable content\n */\nexport function needsOwnFocus(element: HTMLElement): boolean {\n const overflows = element.scrollWidth > element.clientWidth + 1 || element.scrollHeight > element.clientHeight + 1;\n return overflows && element.querySelector(FOCUSABLE) === null;\n}\n\n/**\n * Makes a scrolling box a tab stop while, and only while, it overflows with nothing focusable\n * inside, so keyboard users can scroll it without a stray tab stop on every box that fits.\n *\n * @param target - the scrolling box\n * @returns the `tabindex` to bind on the box: 0 when it needs focus, otherwise undefined\n */\nexport function useKeyboardScroll(target: Readonly<Ref<HTMLElement | null | undefined>>): ComputedRef<0 | undefined> {\n const focusable = shallowRef<boolean>(false);\n let scheduled = false;\n\n function update(): void {\n scheduled = false;\n const element = get(target);\n set(focusable, element ? needsOwnFocus(element) : false);\n }\n\n /** Reading the scroll sizes forces layout, so a burst of resizes and mutations is checked once a frame. */\n function schedule(): void {\n if (scheduled)\n return;\n scheduled = true;\n requestAnimationFrame(update);\n }\n\n // the first check runs at mount, so the box is reachable from its first render, not a frame later\n onMounted(update);\n useResizeObserver(target, schedule);\n // the box keeps its size while its content grows or swaps, which changes whether it overflows\n useMutationObserver(target, schedule, { childList: true, subtree: true, attributes: true, attributeFilter: ['disabled', 'tabindex'] });\n\n return computed<0 | undefined>(() => (get(focusable) ? 0 : undefined));\n}\n"],"mappings":";;;;;AAIA,IAAM,YAAY;CAChB;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;;;;;;;;AASV,SAAgB,cAAc,SAA+B;CAE3D,QADkB,QAAQ,cAAc,QAAQ,cAAc,KAAK,QAAQ,eAAe,QAAQ,eAAe,MAC7F,QAAQ,cAAc,SAAS,MAAM;AAC3D;;;;;;;;AASA,SAAgB,kBAAkB,QAAmF;CACnH,MAAM,YAAY,WAAoB,KAAK;CAC3C,IAAI,YAAY;CAEhB,SAAS,SAAe;EACtB,YAAY;EACZ,MAAM,UAAU,IAAI,MAAM;EAC1B,IAAI,WAAW,UAAU,cAAc,OAAO,IAAI,KAAK;CACzD;;CAGA,SAAS,WAAiB;EACxB,IAAI,WACF;EACF,YAAY;EACZ,sBAAsB,MAAM;CAC9B;CAGA,UAAU,MAAM;CAChB,kBAAkB,QAAQ,QAAQ;CAElC,oBAAoB,QAAQ,UAAU;EAAE,WAAW;EAAM,SAAS;EAAM,YAAY;EAAM,iBAAiB,CAAC,YAAY,UAAU;CAAE,CAAC;CAErI,OAAO,eAA+B,IAAI,SAAS,IAAI,IAAI,KAAA,CAAU;AACvE"}
@@ -1,5 +1,5 @@
1
+ import { get, set } from "../vendor/@vueuse/shared/dist/index.js";
1
2
  import { computed, onScopeDispose, ref, toValue, watch } from "vue";
2
- import { get, set } from "@vueuse/shared";
3
3
  //#region src/composables/overlay-stack.ts
4
4
  /**
5
5
  * Module scoped rather than per call. Layers stack in the window, not in a
@@ -1,6 +1,6 @@
1
+ import { get, set } from "../vendor/@vueuse/shared/dist/index.js";
2
+ import { useEventListener, useMutationObserver, useResizeObserver } from "../vendor/@vueuse/core/dist/index.js";
1
3
  import { onMounted, readonly, shallowRef, toValue } from "vue";
2
- import { useEventListener, useMutationObserver, useResizeObserver } from "@vueuse/core";
3
- import { get as get$1, set as set$1 } from "@vueuse/shared";
4
4
  //#region src/composables/sticky-header.ts
5
5
  var SELECTORS = {
6
6
  head: ":scope > thead[data-id=head-main]",
@@ -124,7 +124,7 @@ function useStickyTableHeader(sticky = shallowRef(false), offsetTop, tableRefs)
124
124
  }
125
125
  }
126
126
  function watchCellWidth() {
127
- const root = get$1(table);
127
+ const root = get(table);
128
128
  if (!toValue(sticky) || !root) return;
129
129
  const cloneRow = queryHeadRow(root, SELECTORS.headClone);
130
130
  const mainRow = queryHeadRow(root, SELECTORS.head);
@@ -140,7 +140,7 @@ function useStickyTableHeader(sticky = shallowRef(false), offsetTop, tableRefs)
140
140
  observeColumnResizes(cloneColumns, mainColumns);
141
141
  }
142
142
  function queryStickyElements() {
143
- const root = get$1(table);
143
+ const root = get(table);
144
144
  if (!toValue(sticky) || !root) return void 0;
145
145
  const theadClone = root.querySelector(SELECTORS.headClone);
146
146
  const head = root.querySelector(SELECTORS.head);
@@ -163,12 +163,12 @@ function useStickyTableHeader(sticky = shallowRef(false), offsetTop, tableRefs)
163
163
  head.style.width = `${clonedRect.width}px`;
164
164
  const lastRowHeight = getLastRowHeight(root);
165
165
  if (lastRowHeight === void 0) {
166
- set$1(stick, false);
166
+ set(stick, false);
167
167
  positionHeadAtRest(head);
168
168
  return;
169
169
  }
170
170
  if (isInStickyRange(tableRect, top)) {
171
- set$1(stick, true);
171
+ set(stick, true);
172
172
  positionHeadStuck(head, {
173
173
  clonedRect,
174
174
  lastRowHeight,
@@ -177,7 +177,7 @@ function useStickyTableHeader(sticky = shallowRef(false), offsetTop, tableRefs)
177
177
  top
178
178
  });
179
179
  } else {
180
- set$1(stick, false);
180
+ set(stick, false);
181
181
  positionHeadAtRest(head);
182
182
  }
183
183
  }
@@ -189,7 +189,7 @@ function useStickyTableHeader(sticky = shallowRef(false), offsetTop, tableRefs)
189
189
  });
190
190
  }
191
191
  function onScroll(event) {
192
- const root = get$1(table);
192
+ const root = get(table);
193
193
  const target = event.target;
194
194
  if (!root || !(target instanceof Node) || !target.contains(root)) return;
195
195
  throttledToggleStickyClass();