@leaflink/stash 53.4.1 → 53.4.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 (178) hide show
  1. package/dist/Accordion.js +1 -1
  2. package/dist/Accordion.js.map +1 -1
  3. package/dist/ActionsDropdown.js +2 -2
  4. package/dist/ActionsDropdown.js.map +1 -1
  5. package/dist/AddressSelect.js.map +1 -1
  6. package/dist/AddressSelect.vue.d.ts +1 -1
  7. package/dist/Alert.js.map +1 -1
  8. package/dist/AppNavigationItem.js +1 -1
  9. package/dist/AppNavigationItem.js.map +1 -1
  10. package/dist/AppSidebar.js.map +1 -1
  11. package/dist/AppTopbar.js +1 -1
  12. package/dist/AppTopbar.js.map +1 -1
  13. package/dist/Avatar.js.map +1 -1
  14. package/dist/Badge.js.map +1 -1
  15. package/dist/Box.vue_vue_type_script_setup_true_lang-dFFZN40_.js.map +1 -1
  16. package/dist/Button.js.map +1 -1
  17. package/dist/ButtonGroup.js.map +1 -1
  18. package/dist/Card.js.map +1 -1
  19. package/dist/CardHeader.js.map +1 -1
  20. package/dist/CardMedia.js.map +1 -1
  21. package/dist/Carousel.js +169 -169
  22. package/dist/Carousel.js.map +1 -1
  23. package/dist/Checkbox.js +31 -31
  24. package/dist/Checkbox.js.map +1 -1
  25. package/dist/ChevronToggle.vue_vue_type_script_setup_true_lang-Ce_qOXfR.js.map +1 -1
  26. package/dist/Chip.js +21 -21
  27. package/dist/Chip.js.map +1 -1
  28. package/dist/Chip.vue.d.ts +1 -1
  29. package/dist/ConfirmationCodeInput.js +1 -1
  30. package/dist/ConfirmationCodeInput.js.map +1 -1
  31. package/dist/ContextSwitcher.js +28 -28
  32. package/dist/ContextSwitcher.js.map +1 -1
  33. package/dist/Copy.js +1 -1
  34. package/dist/Copy.js.map +1 -1
  35. package/dist/CurrencyInput.js +1 -1
  36. package/dist/CurrencyInput.js.map +1 -1
  37. package/dist/DataView.js +51 -51
  38. package/dist/DataView.js.map +1 -1
  39. package/dist/DataViewFilters.js.map +1 -1
  40. package/dist/DataViewSortButton.js +2 -2
  41. package/dist/DataViewSortButton.js.map +1 -1
  42. package/dist/DataViewToolbar.js +5 -5
  43. package/dist/DataViewToolbar.js.map +1 -1
  44. package/dist/DatePicker.js +237 -237
  45. package/dist/DatePicker.js.map +1 -1
  46. package/dist/DatePicker.vue.d.ts +1 -1
  47. package/dist/DescriptionList.js.map +1 -1
  48. package/dist/DescriptionListDetail.js.map +1 -1
  49. package/dist/DescriptionListGroup.js.map +1 -1
  50. package/dist/DescriptionListTerm.js.map +1 -1
  51. package/dist/Dialog.js.map +1 -1
  52. package/dist/Divider.js.map +1 -1
  53. package/dist/Dropdown.js +45 -45
  54. package/dist/Dropdown.js.map +1 -1
  55. package/dist/EmptyState.js.map +1 -1
  56. package/dist/Expand.js +1 -1
  57. package/dist/Expand.vue_vue_type_script_setup_true_lang-BmNJA0Xy.js +74 -0
  58. package/dist/{Expand.vue_vue_type_script_setup_true_lang-CiONJfAp.js.map → Expand.vue_vue_type_script_setup_true_lang-BmNJA0Xy.js.map} +1 -1
  59. package/dist/Field.js +1 -1
  60. package/dist/{Field.vue_vue_type_script_setup_true_lang-dAGKfjf5.js → Field.vue_vue_type_script_setup_true_lang-D2I8xDEW.js} +29 -29
  61. package/dist/{Field.vue_vue_type_script_setup_true_lang-dAGKfjf5.js.map → Field.vue_vue_type_script_setup_true_lang-D2I8xDEW.js.map} +1 -1
  62. package/dist/FileUpload.js +54 -54
  63. package/dist/FileUpload.js.map +1 -1
  64. package/dist/FilterChip.js.map +1 -1
  65. package/dist/FilterChip.vue.d.ts +1 -1
  66. package/dist/FilterDrawerItem.js.map +1 -1
  67. package/dist/FilterDropdown.js.map +1 -1
  68. package/dist/FilterSelect.js +1 -1
  69. package/dist/FilterSelect.js.map +1 -1
  70. package/dist/Filters.js +4 -6
  71. package/dist/Filters.js.map +1 -1
  72. package/dist/Filters.vue.d.ts +57 -57
  73. package/dist/HttpError.js +6 -6
  74. package/dist/HttpError.js.map +1 -1
  75. package/dist/Icon.js.map +1 -1
  76. package/dist/IconLabel.js +13 -13
  77. package/dist/IconLabel.js.map +1 -1
  78. package/dist/Illustration.vue_vue_type_script_setup_true_lang-C1bPkWZZ.js.map +1 -1
  79. package/dist/Image.vue_vue_type_script_setup_true_lang-CAj0FH9h.js.map +1 -1
  80. package/dist/InlineEdit.js.map +1 -1
  81. package/dist/InlineEdit.vue.d.ts +1 -1
  82. package/dist/Input.js +35 -35
  83. package/dist/Input.js.map +1 -1
  84. package/dist/InputOptions.js +35 -35
  85. package/dist/InputOptions.js.map +1 -1
  86. package/dist/InputOptions.vue.d.ts +1 -1
  87. package/dist/IntegrationIcon.js.map +1 -1
  88. package/dist/Label.vue_vue_type_script_setup_true_lang-xwY3X-iV.js.map +1 -1
  89. package/dist/LicenseChip.js +9 -9
  90. package/dist/LicenseChip.js.map +1 -1
  91. package/dist/ListItem.js.map +1 -1
  92. package/dist/ListItemCell.js.map +1 -1
  93. package/dist/ListView.js +1 -1
  94. package/dist/ListView.js.map +1 -1
  95. package/dist/ListView.vue.d.ts +69 -69
  96. package/dist/Loading.js +2 -2
  97. package/dist/Loading.js.map +1 -1
  98. package/dist/Logo.js +1 -1
  99. package/dist/{Logo.vue_vue_type_script_setup_true_lang-DghNC_k6.js → Logo.vue_vue_type_script_setup_true_lang-qiNaaWWV.js} +17 -17
  100. package/dist/Logo.vue_vue_type_script_setup_true_lang-qiNaaWWV.js.map +1 -0
  101. package/dist/MenuItem.js.map +1 -1
  102. package/dist/Metric.js +12 -12
  103. package/dist/Metric.js.map +1 -1
  104. package/dist/Modal.js.map +1 -1
  105. package/dist/Modals.js.map +1 -1
  106. package/dist/Module.js.map +1 -1
  107. package/dist/ModuleContent.js.map +1 -1
  108. package/dist/ModuleFooter.js.map +1 -1
  109. package/dist/ModuleHeader.js.map +1 -1
  110. package/dist/MoreActions.js +2 -2
  111. package/dist/MoreActions.js.map +1 -1
  112. package/dist/ObfuscateText.js.map +1 -1
  113. package/dist/PageContent.js.map +1 -1
  114. package/dist/PageHeader.js.map +1 -1
  115. package/dist/PageNavigation.js +1 -1
  116. package/dist/PageNavigation.js.map +1 -1
  117. package/dist/Paginate.js.map +1 -1
  118. package/dist/PlaidLink.js.map +1 -1
  119. package/dist/QuickAction.js.map +1 -1
  120. package/dist/Radio.js.map +1 -1
  121. package/dist/RadioGroup.js +1 -1
  122. package/dist/RadioGroup.js.map +1 -1
  123. package/dist/RadioNew.js.map +1 -1
  124. package/dist/RangeInput.js.map +1 -1
  125. package/dist/SearchBar.js.map +1 -1
  126. package/dist/SearchBar.vue.d.ts +1 -1
  127. package/dist/SectionHeader.js.map +1 -1
  128. package/dist/Select.js +2 -2
  129. package/dist/Select.js.map +1 -1
  130. package/dist/Select.vue.d.ts +1 -1
  131. package/dist/SelectStatus.js.map +1 -1
  132. package/dist/SelectStatus.vue.d.ts +1 -1
  133. package/dist/Skeleton.js.map +1 -1
  134. package/dist/Step.js +8 -8
  135. package/dist/Step.js.map +1 -1
  136. package/dist/Stepper.js.map +1 -1
  137. package/dist/Switch.js +15 -15
  138. package/dist/Switch.js.map +1 -1
  139. package/dist/Tab.js +1 -1
  140. package/dist/Tab.js.map +1 -1
  141. package/dist/TabPanel.js.map +1 -1
  142. package/dist/Table.js.map +1 -1
  143. package/dist/TableCell.js.map +1 -1
  144. package/dist/TableHeaderCell.js.map +1 -1
  145. package/dist/TableHeaderRow.js.map +1 -1
  146. package/dist/TableRow.js +18 -18
  147. package/dist/TableRow.js.map +1 -1
  148. package/dist/Tabs.js +2 -2
  149. package/dist/{Tabs.vue_vue_type_script_setup_true_lang-BFURXY_-.js → Tabs.vue_vue_type_script_setup_true_lang-B3FBaVP5.js} +48 -48
  150. package/dist/{Tabs.vue_vue_type_script_setup_true_lang-BFURXY_-.js.map → Tabs.vue_vue_type_script_setup_true_lang-B3FBaVP5.js.map} +1 -1
  151. package/dist/TextEditor.js +1 -1
  152. package/dist/TextEditor.js.map +1 -1
  153. package/dist/TextEditor.vue.d.ts +1 -1
  154. package/dist/Textarea.js +1 -1
  155. package/dist/Textarea.js.map +1 -1
  156. package/dist/Thumbnail.js +33 -33
  157. package/dist/Thumbnail.js.map +1 -1
  158. package/dist/Thumbnail.vue.d.ts +3 -3
  159. package/dist/ThumbnailEmpty.js.map +1 -1
  160. package/dist/ThumbnailGroup.js.map +1 -1
  161. package/dist/Timeline.js.map +1 -1
  162. package/dist/TimelineItem.js.map +1 -1
  163. package/dist/Toast.js +27 -27
  164. package/dist/Toast.js.map +1 -1
  165. package/dist/Toasts.js.map +1 -1
  166. package/dist/Tooltip.js +1 -1
  167. package/dist/{Tooltip.vue_vue_type_script_setup_true_lang-CF6sw2VC.js → Tooltip.vue_vue_type_script_setup_true_lang-WMPMxzO-.js} +13 -16
  168. package/dist/Tooltip.vue_vue_type_script_setup_true_lang-WMPMxzO-.js.map +1 -0
  169. package/dist/components.css +1 -1
  170. package/dist/directives/tooltip.js.map +1 -1
  171. package/dist/floating-ui.vue-CuGrC-z8.js.map +1 -1
  172. package/dist/index-B1Gkwuxd.js.map +1 -1
  173. package/dist/index-D6bxWkZ1.js.map +1 -1
  174. package/dist/index.js.map +1 -1
  175. package/package.json +2 -2
  176. package/dist/Expand.vue_vue_type_script_setup_true_lang-CiONJfAp.js +0 -74
  177. package/dist/Logo.vue_vue_type_script_setup_true_lang-DghNC_k6.js.map +0 -1
  178. package/dist/Tooltip.vue_vue_type_script_setup_true_lang-CF6sw2VC.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"MoreActions.js","sources":["../src/composables/useToggleAnimation/useToggleAnimation.ts","../src/components/MoreActions/constants.ts","../src/components/MoreActions/utils.ts","../src/components/MoreActions/useOverflowCalculator.ts","../src/components/MoreActions/createIntersectionObserver.ts","../src/components/MoreActions/useMoreButtonWidth.ts","../src/components/MoreActions/useVisibleElementsWidth.ts","../src/components/MoreActions/MoreActions.vue"],"sourcesContent":["import { useToggle } from '@vueuse/core';\nimport { onUnmounted, type Ref, ref } from 'vue';\n\nexport interface UseToggleAnimationOptions {\n /**\n * Duration of the animation in milliseconds\n * @default 300\n */\n duration?: number;\n /**\n * Whether to start with the element visible\n * @default false\n */\n initialVisible?: boolean;\n}\n\nexport interface UseToggleAnimationReturn {\n /**\n * Whether the element should be visible in the DOM\n */\n isVisible: Ref<boolean>;\n /**\n * Whether the element should show the \"show\" animation (fade-in)\n */\n shouldShow: Ref<boolean>;\n /**\n * Whether the element should show the \"hide\" animation (fade-out)\n */\n shouldHide: Ref<boolean>;\n /**\n * Function to toggle the visibility with animation\n */\n toggle: (visible: boolean) => void;\n /**\n * Function to show the element with animation\n */\n show: () => void;\n /**\n * Function to hide the element with animation\n */\n hide: () => void;\n /**\n * Function to immediately set visibility without animation\n */\n setVisible: (visible: boolean) => void;\n /**\n * Cleanup function to clear any pending timeouts\n */\n cleanup: () => void;\n}\n\n/**\n * Composable for managing toggle animations with proper timeout cleanup\n *\n * @param options Configuration options for the animation\n * @returns Object with visibility state and control functions\n *\n */\nexport function useToggleAnimation(options: UseToggleAnimationOptions = {}): UseToggleAnimationReturn {\n const { duration = 300, initialVisible = false } = options;\n\n const [isVisible, toggleIsVisible] = useToggle(initialVisible);\n const [shouldShow, toggleShouldShow] = useToggle(initialVisible);\n const [shouldHide, toggleShouldHide] = useToggle(false);\n const timeoutId = ref<ReturnType<typeof setTimeout> | null>(null);\n\n /**\n * Clear any existing timeout to prevent race conditions\n */\n function clearExistingTimeout(): void {\n if (timeoutId.value !== null) {\n clearTimeout(timeoutId.value);\n timeoutId.value = null;\n }\n }\n\n /**\n * Set visibility immediately without animation\n */\n function setVisible(visible: boolean): void {\n clearExistingTimeout();\n if (isVisible.value !== visible) {\n toggleIsVisible();\n }\n if (shouldShow.value !== visible) {\n toggleShouldShow();\n }\n if (shouldHide.value) {\n toggleShouldHide();\n }\n }\n\n /**\n * Toggle visibility with animation\n */\n function toggle(visible: boolean): void {\n clearExistingTimeout();\n\n if (visible) {\n // Show with fade-in\n if (!isVisible.value) {\n toggleIsVisible();\n }\n if (!shouldShow.value) {\n toggleShouldShow();\n }\n if (shouldHide.value) {\n toggleShouldHide();\n }\n } else {\n // Hide with fade-out, then remove from DOM after animation\n if (shouldShow.value) {\n toggleShouldShow();\n }\n if (!shouldHide.value) {\n toggleShouldHide();\n }\n\n timeoutId.value = setTimeout(() => {\n if (isVisible.value) {\n toggleIsVisible();\n }\n if (shouldHide.value) {\n toggleShouldHide();\n }\n timeoutId.value = null;\n }, duration);\n }\n }\n\n /**\n * Show the element with animation\n */\n function show(): void {\n toggle(true);\n }\n\n /**\n * Hide the element with animation\n */\n function hide(): void {\n toggle(false);\n }\n\n /**\n * Cleanup function to clear any pending timeouts\n */\n function cleanup(): void {\n clearExistingTimeout();\n }\n\n // Cleanup timeout on component unmount to prevent memory leaks\n onUnmounted(() => {\n cleanup();\n });\n\n return {\n isVisible,\n shouldShow,\n shouldHide,\n toggle,\n show,\n hide,\n setVisible,\n cleanup,\n };\n}\n","export const Z_INDEX = {\n TRACKER: -1,\n DROPDOWN: 1000,\n} as const;\n\nexport const ID_PREFIXES = {\n AUTO_ACTION: 'auto-action-',\n INDEX_BASED: 'index-',\n MORE_MENU: 'more-actions-menu-',\n} as const;\n\nexport const DATA_ATTRIBUTES = {\n ACTION_ID: 'data-action-id',\n PROCESSED: 'data-more-actions-processed',\n} as const;\n\nexport const FADE_ANIMATION_DURATION = 300;\n","import { DEBOUNCE } from '../../constants';\nimport { DATA_ATTRIBUTES, ID_PREFIXES } from './constants';\n\n// Map to track pending timeouts for elements to prevent memory leaks\nconst elementTimeouts = new WeakMap<HTMLElement, ReturnType<typeof setTimeout>>();\n\n/**\n * Adds data-action-id attributes to first-level children of the actions container\n * Ensures unique IDs by checking existing ones\n */\nexport function addActionIdsToFirstLevelChildren(actionsContainerEl: HTMLElement | null): void {\n if (!actionsContainerEl) {\n return;\n }\n\n // Get all direct children of the actions container\n const directChildren = Array.from(actionsContainerEl.children) as HTMLElement[];\n\n // Collect existing action IDs to avoid duplicates\n const existingIds = new Set<string>();\n directChildren.forEach((child) => {\n const existingId = child.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n if (existingId) {\n existingIds.add(existingId);\n }\n });\n\n // Find the next available index for auto-generated IDs\n let nextIndex = 0;\n while (existingIds.has(`auto-action-${nextIndex}`)) {\n nextIndex++;\n }\n\n directChildren.forEach((child) => {\n // Only add data-action-id if it doesn't already exist\n if (!child.hasAttribute(DATA_ATTRIBUTES.ACTION_ID)) {\n child.setAttribute(DATA_ATTRIBUTES.ACTION_ID, `${ID_PREFIXES.AUTO_ACTION}${nextIndex}`);\n nextIndex++;\n }\n });\n}\n\n/**\n * Creates a map of elements to their IDs\n */\nexport function createElementIdMap(directChildren: HTMLElement[]): Map<HTMLElement, string> {\n const elementIdMap = new Map<HTMLElement, string>();\n\n directChildren.forEach((child, index) => {\n const actionId = child.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n if (actionId) {\n elementIdMap.set(child, actionId);\n } else {\n // Use index as ID for elements without data-action-id\n elementIdMap.set(child, `${ID_PREFIXES.INDEX_BASED}${index}`);\n }\n });\n\n return elementIdMap;\n}\n\n/**\n * Cleans up overflow IDs for elements that no longer exist\n */\nexport function cleanupOverflowIds(overflowIds: Set<string>, currentElementIds: Set<string>): void {\n const idsToRemove: string[] = [];\n\n overflowIds.forEach((id) => {\n if (!currentElementIds.has(id)) {\n idsToRemove.push(id);\n }\n });\n\n idsToRemove.forEach((id) => {\n overflowIds.delete(id);\n });\n}\n\n/**\n * Applies visibility classes to elements based on overflow state\n */\nexport function applyElementVisibility(element: HTMLElement, elementId: string, overflowIds: Set<string>): void {\n // Clear any pending timeout for this element\n const existingTimeout = elementTimeouts.get(element);\n if (existingTimeout) {\n clearTimeout(existingTimeout);\n elementTimeouts.delete(element);\n }\n\n if (overflowIds.has(elementId)) {\n element.removeAttribute(DATA_ATTRIBUTES.PROCESSED);\n element.classList.add('invisible');\n } else {\n const timeout = setTimeout(() => {\n if (element.isConnected) {\n element.setAttribute(DATA_ATTRIBUTES.PROCESSED, 'true');\n }\n elementTimeouts.delete(element);\n }, DEBOUNCE.FAST);\n elementTimeouts.set(element, timeout);\n element.classList.remove('invisible');\n }\n}\n\n/**\n * Syncs more-actions content visibility based on overflow state\n * Shows more-actions items whose data-action-id is in overflowIds\n * Supports nested elements with data-action-id (e.g., Menu > MenuItem)\n */\nexport function syncMoreActionsVisibility(moreDropdownMenuEl: HTMLElement | null, overflowIds: Set<string>): void {\n if (!moreDropdownMenuEl) {\n return;\n }\n\n // Find all elements with data-action-id at any nesting level (for nested wrappers like Menu > MenuItem)\n const nestedItemsWithActionId = Array.from(\n moreDropdownMenuEl.querySelectorAll(`[${DATA_ATTRIBUTES.ACTION_ID}]`),\n ) as HTMLElement[];\n\n // Filter to only \"leaf\" elements - those that don't contain other elements with data-action-id\n // This prevents hiding wrapper elements that contain the actual actionable items\n const leafItems = nestedItemsWithActionId.filter((element) => {\n const nestedActionsInside = element.querySelectorAll(`[${DATA_ATTRIBUTES.ACTION_ID}]`);\n // If element has nested elements with data-action-id inside, it's a wrapper, not a leaf\n return nestedActionsInside.length === 0;\n });\n\n // Apply styles and visibility to leaf items only\n leafItems.forEach((element) => {\n const actionId = element.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n\n // Show more-actions item only if its action-id is in overflowIds (item is hidden in toolbar)\n const shouldShow = actionId && overflowIds.has(actionId);\n if (shouldShow) {\n element.classList.remove('hidden');\n } else {\n element.classList.add('hidden');\n }\n });\n}\n","import { useElementBounding } from '@vueuse/core';\nimport debounce from 'lodash-es/debounce';\nimport { nextTick, type Ref, ref, type ShallowRef } from 'vue';\n\nimport { DEBOUNCE } from '../../constants';\nimport { DATA_ATTRIBUTES } from './constants';\nimport { applyElementVisibility, createElementIdMap, syncMoreActionsVisibility } from './utils';\n\ninterface UseOverflowCalculatorOptions {\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n overflowIds: Ref<Set<string>>;\n moreDropdownMenuRef: ShallowRef<HTMLElement | null>;\n trackerElementRef: ShallowRef<HTMLElement | null>;\n onOverflowChange?: () => void;\n}\n\nexport function useOverflowCalculator({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n onOverflowChange,\n}: UseOverflowCalculatorOptions) {\n const isProcessing = ref(false);\n const lastOverflowState = ref<string>(''); // Track last overflow state to prevent unnecessary updates\n const trackerBounding = useElementBounding(trackerElementRef);\n\n /**\n * Updates overflow state and applies visibility classes to elements\n */\n function updateOverflowState(\n newOverflowIds: Set<string>,\n directChildren: HTMLElement[],\n elementIdMap: Map<HTMLElement, string>,\n ): void {\n overflowIds.value.clear();\n newOverflowIds.forEach((id) => overflowIds.value.add(id));\n\n // Apply visibility classes\n directChildren.forEach((element) => {\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || undefined;\n\n if (elementId) {\n applyElementVisibility(element, elementId, overflowIds.value);\n }\n });\n }\n\n function calculateOverflowInternal() {\n if (!actionsContainerRef.value || !trackerElementRef.value) {\n isProcessing.value = false;\n return;\n }\n\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n const elementIdMap = createElementIdMap(directChildren);\n\n // Create a new overflow set to compare with current state\n const newOverflowIds = new Set<string>();\n\n // Get current gap width from CSS computed styles of the actions container\n const computedStyle = window.getComputedStyle(actionsContainerRef.value);\n const gapValue = computedStyle.columnGap || computedStyle.gap;\n const gapWidth = gapValue ? parseFloat(gapValue) : 0;\n\n // Calculate which elements should be hidden based on their position relative to tracker\n directChildren.forEach((element, index) => {\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || undefined;\n\n const elementRect = element.getBoundingClientRect();\n\n // Calculate the effective right edge including gap\n // If this is not the last element, add gap to the right edge\n const effectiveRightEdge = index < directChildren.length - 1 ? elementRect.right + gapWidth : elementRect.right;\n\n // If element's effective right edge extends beyond tracker's left edge, hide it\n if (effectiveRightEdge > trackerBounding.left.value) {\n if (elementId) {\n newOverflowIds.add(elementId);\n }\n }\n });\n\n // Check if overflow state has actually changed\n const currentOverflowState = Array.from(overflowIds.value).sort().join(',');\n const newOverflowState = Array.from(newOverflowIds).sort().join(',');\n\n if (currentOverflowState !== newOverflowState) {\n // Update overflow state and apply visibility\n updateOverflowState(newOverflowIds, directChildren, elementIdMap);\n\n // Sync more-actions content visibility\n syncMoreActionsVisibility(moreDropdownMenuRef.value, overflowIds.value);\n\n // Call callback if provided and state actually changed\n // Use nextTick to ensure CSS changes are applied before calculating visible elements width\n if (onOverflowChange && lastOverflowState.value !== newOverflowState) {\n lastOverflowState.value = newOverflowState;\n nextTick(() => {\n onOverflowChange();\n });\n }\n }\n\n isProcessing.value = false;\n }\n\n const debouncedCalculateOverflow = debounce(calculateOverflowInternal, DEBOUNCE.FAST);\n\n function calculateOverflow() {\n if (isProcessing.value || !actionsContainerRef.value || !trackerElementRef.value) {\n return;\n }\n\n isProcessing.value = true;\n debouncedCalculateOverflow();\n }\n\n function updateTrackerBounding() {\n trackerBounding.update();\n }\n\n function cleanup() {\n debouncedCalculateOverflow.cancel();\n isProcessing.value = false;\n }\n\n return {\n calculateOverflow,\n applyElementVisibility,\n updateOverflowState,\n updateTrackerBounding,\n cleanup,\n isProcessing,\n };\n}\n","import { useIntersectionObserver, useResizeObserver } from '@vueuse/core';\nimport debounce from 'lodash-es/debounce';\nimport { nextTick, onBeforeUnmount, onDeactivated, onMounted, onUpdated, type Ref, ref, type ShallowRef } from 'vue';\n\nimport { DEBOUNCE } from '../../constants';\nimport { DATA_ATTRIBUTES } from './constants';\nimport { useOverflowCalculator } from './useOverflowCalculator';\nimport {\n addActionIdsToFirstLevelChildren as addActionIds,\n cleanupOverflowIds,\n createElementIdMap,\n syncMoreActionsVisibility,\n} from './utils';\n\ninterface CreateIntersectionObserverOptions {\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n overflowIds: Ref<Set<string>>;\n moreDropdownMenuRef: ShallowRef<HTMLElement | null>;\n trackerElementRef: ShallowRef<HTMLElement | null>;\n moreDropdownWidth: Ref<number>;\n calculateMoreButtonWidth: () => number;\n hasMoreActionsSlot: Ref<boolean>;\n onOverflowChange?: () => void;\n}\n\nexport function createIntersectionObserver({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n moreDropdownWidth,\n calculateMoreButtonWidth,\n hasMoreActionsSlot,\n onOverflowChange,\n}: CreateIntersectionObserverOptions) {\n const isInitializing = ref(false);\n\n const {\n calculateOverflow,\n applyElementVisibility,\n updateOverflowState,\n updateTrackerBounding,\n cleanup: cleanupCalculator,\n isProcessing,\n } = useOverflowCalculator({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n onOverflowChange,\n });\n\n let mutationObserver: MutationObserver | null = null;\n let stopResizeObserver: (() => void) | null = null;\n let stopIntersectionObserver: (() => void) | null = null;\n\n function clearOverflowState() {\n overflowIds.value.clear();\n moreDropdownWidth.value = 0;\n }\n\n /**\n * Cleanup all observers (ResizeObserver and IntersectionObserver)\n * to prevent memory leaks when re-creating them\n */\n function cleanupObservers() {\n if (stopResizeObserver) {\n stopResizeObserver();\n stopResizeObserver = null;\n }\n if (stopIntersectionObserver) {\n stopIntersectionObserver();\n stopIntersectionObserver = null;\n }\n }\n\n // Track DOM mutations - created once, outside of createObserver to prevent duplicates\n const handleMutation = debounce(\n () => {\n if (!actionsContainerRef.value || !hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n\n // Cleanup old observers before re-initializing\n cleanupObservers();\n cleanupCalculator();\n debouncedInitObserve();\n },\n DEBOUNCE.FAST,\n { leading: false, trailing: true },\n );\n\n function createObserver() {\n if (!actionsContainerRef.value) {\n return;\n }\n\n // If there's no more-actions slot, don't set up overflow detection\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Get all direct children of the actions container\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n\n // Create a map of elements to their IDs (either data-action-id or index-based)\n const elementIdMap = createElementIdMap(directChildren);\n\n // Clean up overflowIds for elements that no longer exist\n const currentElementIds = new Set(elementIdMap.values());\n cleanupOverflowIds(overflowIds.value, currentElementIds);\n\n // to track container size changes\n const { stop: stopResize } = useResizeObserver(actionsContainerRef, () => {\n updateTrackerBounding();\n calculateOverflow();\n });\n stopResizeObserver = stopResize;\n\n const { stop: stopIntersection } = useIntersectionObserver(\n directChildren,\n (entries) => {\n if (isProcessing.value) {\n return;\n }\n\n let hasChanges = false;\n const newOverflowIds = new Set(overflowIds.value);\n\n entries.forEach((entry) => {\n const element = entry.target as HTMLElement;\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || undefined;\n\n // Check if element is fully visible\n if (entry.intersectionRatio === 1) {\n // show action, hide in dropdown\n if (elementId && newOverflowIds.has(elementId)) {\n newOverflowIds.delete(elementId);\n hasChanges = true;\n }\n } else {\n // hide action, show in dropdown (intersectionRatio < 1 means partially or not visible)\n if (elementId && !newOverflowIds.has(elementId)) {\n newOverflowIds.add(elementId);\n hasChanges = true;\n }\n }\n });\n\n // Only update if there are actual changes\n if (hasChanges) {\n const currentOverflowState = Array.from(overflowIds.value).sort().join(',');\n const newOverflowState = Array.from(newOverflowIds).sort().join(',');\n\n if (currentOverflowState !== newOverflowState) {\n // Update overflow state and apply visibility\n updateOverflowState(newOverflowIds, directChildren, elementIdMap);\n\n // Sync more-actions content visibility\n syncMoreActionsVisibility(moreDropdownMenuRef.value, overflowIds.value);\n\n // Call callback if provided and state actually changed\n // Use nextTick to ensure CSS changes are applied before calculating visible elements width\n if (onOverflowChange) {\n nextTick(() => {\n onOverflowChange();\n });\n }\n }\n }\n },\n {\n root: actionsContainerRef.value,\n },\n );\n stopIntersectionObserver = stopIntersection;\n\n // Apply initial visibility to all elements\n directChildren.forEach((element) => {\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || '';\n applyElementVisibility(element, elementId, overflowIds.value);\n });\n\n // Initial calculation\n calculateOverflow();\n\n syncMoreActionsVisibility(moreDropdownMenuRef.value, overflowIds.value);\n }\n\n function initObserve() {\n if (!actionsContainerRef.value) {\n return;\n }\n\n // If there's no more-actions slot, don't initialize\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n\n createObserver();\n\n // Set initial dropdown width - only if not already set\n if (moreDropdownWidth.value === 0) {\n moreDropdownWidth.value = calculateMoreButtonWidth();\n }\n\n // Setup MutationObserver once to watch for DOM changes\n // Only create if it doesn't exist to prevent duplicates\n if (!mutationObserver && actionsContainerRef.value) {\n mutationObserver = new MutationObserver(handleMutation);\n mutationObserver.observe(actionsContainerRef.value, {\n childList: true, // Watch for added/removed children\n subtree: false, // Only watch direct children\n });\n }\n }\n\n const debouncedInitObserve = debounce(\n () => {\n if (!isInitializing.value) {\n isInitializing.value = true;\n initObserve();\n isInitializing.value = false;\n }\n },\n DEBOUNCE.FAST,\n { leading: true },\n );\n\n onMounted(() => {\n // If there's no more-actions slot, skip initialization\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n initObserve();\n });\n\n onUpdated(() => {\n // If there's no more-actions slot, skip initialization\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n // Clear overflowIds if no actions are present\n if (actionsContainerRef.value) {\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n if (directChildren.length === 0) {\n clearOverflowState();\n }\n }\n cleanupObservers();\n cleanupCalculator();\n debouncedInitObserve();\n });\n\n onDeactivated(() => {\n cleanupObservers();\n cleanupCalculator();\n handleMutation.cancel();\n debouncedInitObserve.cancel();\n if (mutationObserver) {\n mutationObserver.disconnect();\n mutationObserver = null;\n }\n });\n\n onBeforeUnmount(() => {\n cleanupObservers();\n cleanupCalculator();\n handleMutation.cancel();\n debouncedInitObserve.cancel();\n if (mutationObserver) {\n mutationObserver.disconnect();\n mutationObserver = null;\n }\n });\n}\n","import { type ComputedRef, nextTick, ref, type ShallowRef, watch } from 'vue';\n\nimport Dropdown from '../Dropdown/Dropdown.vue';\n\n// Updated interface with Ref suffix naming convention\ninterface UseMoreDropdownWidthOptions {\n moreDropdownRef: ShallowRef<InstanceType<typeof Dropdown> | null>;\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n moreButtonAlign: 'separate' | 'together';\n hasOverflowActions: ComputedRef<boolean>;\n}\n\nexport function useMoreButtonWidth({\n moreDropdownRef,\n actionsContainerRef,\n moreButtonAlign,\n hasOverflowActions,\n}: UseMoreDropdownWidthOptions) {\n /**\n * Calculates the width of the More dropdown with gap consideration\n * When moreButtonAlign is 'separate', adds the gap between actions container and dropdown\n * When moreButtonAlign is 'together', returns only the dropdown width\n */\n const calculateMoreButtonWidth = (): number => {\n if (!moreDropdownRef.value?.$el) {\n return 0;\n }\n\n const dropdownWidth = moreDropdownRef.value.$el.getBoundingClientRect().width;\n\n // If moreButtonAlign is separate, add gap between actions container and dropdown\n if (moreButtonAlign === 'separate' && actionsContainerRef.value) {\n const computedStyle = window.getComputedStyle(actionsContainerRef.value);\n const gapWidth = parseFloat(computedStyle.gap) || 0;\n return dropdownWidth + gapWidth;\n }\n\n return dropdownWidth;\n };\n\n const moreButtonWidth = ref(0);\n\n watch(hasOverflowActions, (newValue) => {\n if (newValue && moreDropdownRef.value) {\n nextTick(() => {\n const calculatedWidth = calculateMoreButtonWidth();\n if (calculatedWidth > 0) {\n moreButtonWidth.value = calculatedWidth;\n }\n });\n }\n });\n\n return {\n calculateMoreButtonWidth,\n moreButtonWidth,\n };\n}\n","import { nextTick, type Ref, ref, type ShallowRef, watch } from 'vue';\n\nimport { DATA_ATTRIBUTES, FADE_ANIMATION_DURATION } from './constants';\n\ninterface UseVisibleElementsWidthOptions {\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n overflowIds: Ref<Set<string>>;\n}\n\nexport function useVisibleElementsWidth({ actionsContainerRef, overflowIds }: UseVisibleElementsWidthOptions) {\n const visibleElementsWidth = ref(0);\n const isRecalculatingWidth = ref(false);\n const isRecalculatingWithDelay = ref(false);\n let widthCalculationTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Calculates the total width of currently visible elements\n * This is used for positioning the More button\n */\n const calculateVisibleElementsWidth = () => {\n if (!actionsContainerRef.value) {\n visibleElementsWidth.value = 0;\n return;\n }\n\n let totalWidth = 0;\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n\n directChildren.forEach((element, index) => {\n const elementId = element.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n\n // Check if element should be visible based on overflow state\n // Elements without data-action-id are always considered visible (never hidden by overflow logic)\n const shouldBeVisible = !elementId || !overflowIds.value.has(elementId);\n\n // Double-check with CSS classes as a fallback\n const isHiddenByCSS = element.classList.contains('invisible');\n\n // Element is considered visible if:\n // 1. It's not in overflowIds (should be visible) OR it has no data-action-id (always visible)\n // 2. AND it's not hidden by CSS classes\n if (shouldBeVisible && !isHiddenByCSS) {\n const rect = element.getBoundingClientRect();\n totalWidth += rect.width;\n\n // Add gap between elements\n if (index < directChildren.length - 1 && actionsContainerRef.value) {\n // Always get the most current gap width from CSS computed styles of the actions container\n const computedStyle = window.getComputedStyle(actionsContainerRef.value);\n const gapValue = computedStyle.columnGap || computedStyle.gap;\n const gapWidth = gapValue ? parseFloat(gapValue) : 0;\n totalWidth += gapWidth;\n }\n }\n });\n\n visibleElementsWidth.value = totalWidth;\n };\n\n /**\n * Calculates visible elements width with a delay to allow animations to complete\n * This ensures that width calculation happens after elements are actually hidden/shown\n */\n const calculateVisibleElementsWidthDelayed = () => {\n // Set recalculating state immediately to hide More button\n isRecalculatingWithDelay.value = true;\n\n // Clear any existing timeout\n if (widthCalculationTimeout) {\n clearTimeout(widthCalculationTimeout);\n }\n\n // Set a new timeout to calculate width after animation completes\n widthCalculationTimeout = setTimeout(() => {\n if (!isRecalculatingWidth.value) {\n isRecalculatingWidth.value = true;\n\n // Use double nextTick to ensure all DOM updates and CSS changes are applied\n nextTick(() => {\n nextTick(() => {\n calculateVisibleElementsWidth();\n isRecalculatingWidth.value = false;\n isRecalculatingWithDelay.value = false; // Show More button after calculation is complete\n });\n });\n }\n }, FADE_ANIMATION_DURATION + 100); // Add small buffer to ensure animation is complete\n };\n\n // Watch for changes in overflowIds to recalculate visible elements width with delay\n watch(overflowIds, () => {\n calculateVisibleElementsWidthDelayed();\n });\n\n /**\n * Cleanup function to clear any pending timeouts\n */\n const cleanup = () => {\n if (widthCalculationTimeout) {\n clearTimeout(widthCalculationTimeout);\n widthCalculationTimeout = null;\n }\n isRecalculatingWithDelay.value = false;\n };\n\n return {\n visibleElementsWidth,\n isRecalculatingWidth,\n isRecalculatingWithDelay,\n calculateVisibleElementsWidth,\n calculateVisibleElementsWidthDelayed,\n cleanup,\n };\n}\n","<script lang=\"ts\" setup>\n /**\n * MoreActions Component\n *\n * This component provides a responsive toolbar that automatically moves overflow items\n * into a \"More\" dropdown menu when space is limited.\n *\n * @example\n * <MoreActions>\n * <Button data-action-id=\"edit\">Edit</Button>\n * <Button data-action-id=\"delete\">Delete</Button>\n * <Button data-action-id=\"share\">Share</Button>\n *\n * <template #more-actions>\n * <DropdownItem data-action-id=\"edit\">Edit Item</DropdownItem>\n * <DropdownItem data-action-id=\"delete\">Delete Item</DropdownItem>\n * <DropdownItem data-action-id=\"share\">Share Item</DropdownItem>\n * </template>\n * </MoreActions>\n *\n * IMPORTANT:\n * - The #more-actions slot is REQUIRED. If not provided, the More dropdown will not be rendered.\n * - Each item in the default slot must have a corresponding item in the 'more-actions'\n * slot with the same data-action-id attribute.\n * - The component automatically shows/hides matching items based on available space:\n * - Items visible in toolbar → hidden in more-actions\n * - Items hidden in toolbar (overflow) → visible in more-actions\n */\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, onBeforeUnmount, ref, useSlots, useTemplateRef, watch } from 'vue';\n\n import { useToggleAnimation } from '../../composables/useToggleAnimation/useToggleAnimation';\n import { DEBOUNCE } from '../../constants';\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import Icon from '../Icon/Icon.vue';\n import { FADE_ANIMATION_DURATION, ID_PREFIXES, Z_INDEX } from './constants';\n import { createIntersectionObserver } from './createIntersectionObserver';\n import { useMoreButtonWidth } from './useMoreButtonWidth';\n import { useVisibleElementsWidth } from './useVisibleElementsWidth';\n\n export interface MoreActionsProps {\n /**\n * CSS class or classes to be applied to the actions container\n */\n actionsContainerClass?: string | Record<string, boolean> | undefined;\n /**\n * HTML element tag to use for the actions container\n * Useful when you need to maintain valid HTML semantics\n * (e.g., use 'ul' when children are <li> elements)\n * @default 'div'\n */\n actionsContainerTag?: string;\n /**\n * Text to display on the more actions button\n */\n moreButtonText?: string;\n /**\n * Optional width for the more-actions container\n * Applies style=\"width: {width}\" to the stash-more-actions element\n */\n width?: string | number;\n /**\n * Rendering mode for dropdown items\n * - 'default': Button-style rendering (current behavior)\n * - 'custom': Custom rendering through slots\n */\n dropdownMode?: 'default' | 'custom';\n /**\n * Alignment of the More button\n * - 'separate': Button is aligned to the right edge of the actions container (default)\n * - 'together': Button is aligned immediately after the last visible action\n */\n moreButtonAlign?: 'separate' | 'together';\n }\n\n const props = withDefaults(defineProps<MoreActionsProps>(), {\n actionsContainerClass: undefined,\n actionsContainerTag: 'div',\n moreButtonText: () => t('ll.more'),\n dropdownMode: 'default',\n moreButtonAlign: 'separate',\n width: undefined,\n });\n\n // Check if more-actions slot is provided (REQUIRED for dropdown to render)\n const slots = useSlots();\n const hasMoreActionsSlot = computed(() => !!slots['more-actions']);\n\n // Refs for DOM elements\n const actionsContainerRef = useTemplateRef<HTMLElement>('actionsContainerRef');\n const moreDropdownRef = useTemplateRef('moreDropdownRef');\n const moreDropdownMenuRef = useTemplateRef('moreDropdownMenuRef');\n const trackerElementRef = useTemplateRef('trackerElementRef');\n\n // State management\n const overflowIds = ref<Set<string>>(new Set());\n const isMoreMenuOpen = ref(false);\n const moreMenuId = uniqueId(ID_PREFIXES.MORE_MENU);\n const showButtonDelayTimeout = ref<ReturnType<typeof setTimeout> | null>(null);\n const isDelayedShowReady = ref(false);\n\n const {\n isVisible: isMoreButtonVisible,\n shouldShow: shouldMoreButtonShow,\n toggle: toggleMoreButtonAnimation,\n } = useToggleAnimation({\n duration: FADE_ANIMATION_DURATION,\n initialVisible: false,\n });\n\n const hasOverflowActions = computed(() => overflowIds.value.size > 0);\n\n // Updated to use new Ref suffix naming convention\n const { calculateMoreButtonWidth, moreButtonWidth } = useMoreButtonWidth({\n moreDropdownRef,\n actionsContainerRef,\n moreButtonAlign: props.moreButtonAlign,\n hasOverflowActions,\n });\n\n // Updated to use new Ref suffix naming convention\n const {\n visibleElementsWidth,\n isRecalculatingWithDelay,\n calculateVisibleElementsWidthDelayed,\n cleanup: cleanupVisibleElementsWidth,\n } = useVisibleElementsWidth({\n actionsContainerRef,\n overflowIds,\n });\n\n const shouldShowMoreButton = computed(() => {\n return (\n hasMoreActionsSlot.value &&\n hasOverflowActions.value &&\n !isRecalculatingWithDelay.value &&\n isDelayedShowReady.value\n );\n });\n\n const isMoreMenuOpenString = computed(() => isMoreMenuOpen.value.toString());\n\n const actionsContainerWidth = computed(() => {\n if (!shouldShowMoreButton.value) {\n return '100%';\n }\n\n return `calc(100% - ${moreButtonWidth.value}px)`;\n });\n\n const moreButtonPosition = computed(() => {\n if (props.moreButtonAlign === 'together') {\n return { left: `${visibleElementsWidth.value}px`, right: 'auto' };\n } else {\n // Default separate alignment\n return { right: '0', left: 'auto' };\n }\n });\n\n createIntersectionObserver({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n moreDropdownWidth: moreButtonWidth,\n calculateMoreButtonWidth,\n hasMoreActionsSlot,\n onOverflowChange: calculateVisibleElementsWidthDelayed,\n });\n\n // Watch for when recalculation completes and overflow actions exist\n watch(\n () => hasMoreActionsSlot.value && hasOverflowActions.value && !isRecalculatingWithDelay.value,\n (isReady) => {\n // Clear any existing timeout\n if (showButtonDelayTimeout.value) {\n clearTimeout(showButtonDelayTimeout.value);\n showButtonDelayTimeout.value = null;\n }\n\n if (isReady) {\n // Add delay before showing the button\n showButtonDelayTimeout.value = setTimeout(() => {\n isDelayedShowReady.value = true;\n }, DEBOUNCE.FAST);\n } else {\n // Hide immediately when overflow actions are removed or slot is not available\n isDelayedShowReady.value = false;\n }\n },\n );\n\n // Watch for changes in shouldShowMoreButton to handle fade animations\n watch(shouldShowMoreButton, (newValue) => {\n toggleMoreButtonAnimation(newValue);\n });\n\n function handleDropdownToggle(event: boolean) {\n isMoreMenuOpen.value = event;\n }\n\n onBeforeUnmount(() => {\n cleanupVisibleElementsWidth();\n if (showButtonDelayTimeout.value) {\n clearTimeout(showButtonDelayTimeout.value);\n }\n });\n</script>\n\n<template>\n <div\n class=\"stash-more-actions relative overflow-x-hidden\"\n data-test=\"stash-more-actions\"\n :style=\"{ width: props.width }\"\n >\n <component\n :is=\"props.actionsContainerTag\"\n ref=\"actionsContainerRef\"\n data-test=\"stash-more-actions__container\"\n :style=\"{\n width: actionsContainerWidth,\n minWidth: moreButtonWidth ? `${moreButtonWidth}px` : undefined,\n }\"\n :class=\"['stash-more-actions__container flex items-center gap-2 overflow-x-hidden', props.actionsContainerClass]\"\n >\n <!-- Default slot for elements that can be hidden -->\n <slot></slot>\n </component>\n\n <!-- Tracker Element - to detect when action elements overlap with it, triggering overflow behavior -->\n <div\n ref=\"trackerElementRef\"\n class=\"stash-more-actions__tracker\"\n :style=\"{\n position: 'absolute',\n right: '0px',\n top: '0',\n visibility: 'hidden',\n width: moreButtonWidth + 'px',\n height: '100%',\n pointerEvents: 'none',\n zIndex: Z_INDEX.TRACKER,\n }\"\n ></div>\n\n <!-- Only render dropdown if more-actions slot is provided -->\n <Dropdown\n v-if=\"hasMoreActionsSlot\"\n ref=\"moreDropdownRef\"\n :class=\"[\n '!absolute top-0',\n shouldMoreButtonShow ? 'animate-fade-in' : 'animate-fade-out',\n { invisible: !isMoreButtonVisible },\n ]\"\n :style=\"moreButtonPosition\"\n @toggle=\"handleDropdownToggle\"\n >\n <template #toggle=\"{ toggle }\">\n <slot name=\"toggle\" :toggle=\"toggle\" :is-open=\"isMoreMenuOpen\">\n <Button\n class=\"button -border-gray-500 text-gray-500 flex w-full items-center justify-between -border\"\n secondary\n :aria-expanded=\"isMoreMenuOpenString\"\n @click=\"toggle\"\n >\n {{ props.moreButtonText }} <Icon class=\"-ml-1.5\" name=\"action-dots\" />\n </Button>\n </slot>\n </template>\n\n <template #default>\n <div\n :id=\"moreMenuId\"\n ref=\"moreDropdownMenuRef\"\n data-test=\"stash-more-actions__dropdown\"\n class=\"flex flex-col gap-1.5 p-1.5\"\n >\n <!-- More actions slot content (only overflow items will be shown) -->\n <slot name=\"more-actions\"></slot>\n </div>\n </template>\n </Dropdown>\n </div>\n</template>\n\n<style module>\n @layer utilities {\n :global([data-action-id]) {\n flex-shrink: 0;\n }\n }\n\n :global(.stash-more-actions__container [data-action-id]:not([data-more-actions-processed])) {\n visibility: hidden;\n }\n</style>\n"],"names":["useToggleAnimation","options","duration","initialVisible","isVisible","toggleIsVisible","useToggle","shouldShow","toggleShouldShow","shouldHide","toggleShouldHide","timeoutId","ref","clearExistingTimeout","setVisible","visible","toggle","show","hide","cleanup","onUnmounted","Z_INDEX","ID_PREFIXES","DATA_ATTRIBUTES","FADE_ANIMATION_DURATION","elementTimeouts","addActionIdsToFirstLevelChildren","actionsContainerEl","directChildren","existingIds","child","existingId","nextIndex","createElementIdMap","elementIdMap","index","actionId","cleanupOverflowIds","overflowIds","currentElementIds","idsToRemove","id","applyElementVisibility","element","elementId","existingTimeout","timeout","DEBOUNCE","syncMoreActionsVisibility","moreDropdownMenuEl","useOverflowCalculator","actionsContainerRef","moreDropdownMenuRef","trackerElementRef","onOverflowChange","isProcessing","lastOverflowState","trackerBounding","useElementBounding","updateOverflowState","newOverflowIds","calculateOverflowInternal","computedStyle","gapValue","gapWidth","elementRect","currentOverflowState","newOverflowState","nextTick","debouncedCalculateOverflow","debounce","calculateOverflow","updateTrackerBounding","createIntersectionObserver","moreDropdownWidth","calculateMoreButtonWidth","hasMoreActionsSlot","isInitializing","cleanupCalculator","mutationObserver","stopResizeObserver","stopIntersectionObserver","clearOverflowState","cleanupObservers","handleMutation","addActionIds","debouncedInitObserve","createObserver","stopResize","useResizeObserver","stopIntersection","useIntersectionObserver","entries","hasChanges","entry","initObserve","onMounted","onUpdated","onDeactivated","onBeforeUnmount","useMoreButtonWidth","moreDropdownRef","moreButtonAlign","hasOverflowActions","_a","dropdownWidth","moreButtonWidth","watch","newValue","calculatedWidth","useVisibleElementsWidth","visibleElementsWidth","isRecalculatingWidth","isRecalculatingWithDelay","widthCalculationTimeout","calculateVisibleElementsWidth","totalWidth","shouldBeVisible","isHiddenByCSS","rect","calculateVisibleElementsWidthDelayed","props","__props","slots","useSlots","computed","useTemplateRef","isMoreMenuOpen","moreMenuId","uniqueId","showButtonDelayTimeout","isDelayedShowReady","isMoreButtonVisible","shouldMoreButtonShow","toggleMoreButtonAnimation","cleanupVisibleElementsWidth","shouldShowMoreButton","isMoreMenuOpenString","actionsContainerWidth","moreButtonPosition","isReady","handleDropdownToggle","event"],"mappings":"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"}
1
+ {"version":3,"file":"MoreActions.js","sources":["../src/composables/useToggleAnimation/useToggleAnimation.ts","../src/components/MoreActions/constants.ts","../src/components/MoreActions/utils.ts","../src/components/MoreActions/useOverflowCalculator.ts","../src/components/MoreActions/createIntersectionObserver.ts","../src/components/MoreActions/useMoreButtonWidth.ts","../src/components/MoreActions/useVisibleElementsWidth.ts","../src/components/MoreActions/MoreActions.vue"],"sourcesContent":["import { useToggle } from '@vueuse/core';\nimport { onUnmounted, type Ref, ref } from 'vue';\n\nexport interface UseToggleAnimationOptions {\n /**\n * Duration of the animation in milliseconds\n * @default 300\n */\n duration?: number;\n /**\n * Whether to start with the element visible\n * @default false\n */\n initialVisible?: boolean;\n}\n\nexport interface UseToggleAnimationReturn {\n /**\n * Whether the element should be visible in the DOM\n */\n isVisible: Ref<boolean>;\n /**\n * Whether the element should show the \"show\" animation (fade-in)\n */\n shouldShow: Ref<boolean>;\n /**\n * Whether the element should show the \"hide\" animation (fade-out)\n */\n shouldHide: Ref<boolean>;\n /**\n * Function to toggle the visibility with animation\n */\n toggle: (visible: boolean) => void;\n /**\n * Function to show the element with animation\n */\n show: () => void;\n /**\n * Function to hide the element with animation\n */\n hide: () => void;\n /**\n * Function to immediately set visibility without animation\n */\n setVisible: (visible: boolean) => void;\n /**\n * Cleanup function to clear any pending timeouts\n */\n cleanup: () => void;\n}\n\n/**\n * Composable for managing toggle animations with proper timeout cleanup\n *\n * @param options Configuration options for the animation\n * @returns Object with visibility state and control functions\n *\n */\nexport function useToggleAnimation(options: UseToggleAnimationOptions = {}): UseToggleAnimationReturn {\n const { duration = 300, initialVisible = false } = options;\n\n const [isVisible, toggleIsVisible] = useToggle(initialVisible);\n const [shouldShow, toggleShouldShow] = useToggle(initialVisible);\n const [shouldHide, toggleShouldHide] = useToggle(false);\n const timeoutId = ref<ReturnType<typeof setTimeout> | null>(null);\n\n /**\n * Clear any existing timeout to prevent race conditions\n */\n function clearExistingTimeout(): void {\n if (timeoutId.value !== null) {\n clearTimeout(timeoutId.value);\n timeoutId.value = null;\n }\n }\n\n /**\n * Set visibility immediately without animation\n */\n function setVisible(visible: boolean): void {\n clearExistingTimeout();\n if (isVisible.value !== visible) {\n toggleIsVisible();\n }\n if (shouldShow.value !== visible) {\n toggleShouldShow();\n }\n if (shouldHide.value) {\n toggleShouldHide();\n }\n }\n\n /**\n * Toggle visibility with animation\n */\n function toggle(visible: boolean): void {\n clearExistingTimeout();\n\n if (visible) {\n // Show with fade-in\n if (!isVisible.value) {\n toggleIsVisible();\n }\n if (!shouldShow.value) {\n toggleShouldShow();\n }\n if (shouldHide.value) {\n toggleShouldHide();\n }\n } else {\n // Hide with fade-out, then remove from DOM after animation\n if (shouldShow.value) {\n toggleShouldShow();\n }\n if (!shouldHide.value) {\n toggleShouldHide();\n }\n\n timeoutId.value = setTimeout(() => {\n if (isVisible.value) {\n toggleIsVisible();\n }\n if (shouldHide.value) {\n toggleShouldHide();\n }\n timeoutId.value = null;\n }, duration);\n }\n }\n\n /**\n * Show the element with animation\n */\n function show(): void {\n toggle(true);\n }\n\n /**\n * Hide the element with animation\n */\n function hide(): void {\n toggle(false);\n }\n\n /**\n * Cleanup function to clear any pending timeouts\n */\n function cleanup(): void {\n clearExistingTimeout();\n }\n\n // Cleanup timeout on component unmount to prevent memory leaks\n onUnmounted(() => {\n cleanup();\n });\n\n return {\n isVisible,\n shouldShow,\n shouldHide,\n toggle,\n show,\n hide,\n setVisible,\n cleanup,\n };\n}\n","export const Z_INDEX = {\n TRACKER: -1,\n DROPDOWN: 1000,\n} as const;\n\nexport const ID_PREFIXES = {\n AUTO_ACTION: 'auto-action-',\n INDEX_BASED: 'index-',\n MORE_MENU: 'more-actions-menu-',\n} as const;\n\nexport const DATA_ATTRIBUTES = {\n ACTION_ID: 'data-action-id',\n PROCESSED: 'data-more-actions-processed',\n} as const;\n\nexport const FADE_ANIMATION_DURATION = 300;\n","import { DEBOUNCE } from '../../constants';\nimport { DATA_ATTRIBUTES, ID_PREFIXES } from './constants';\n\n// Map to track pending timeouts for elements to prevent memory leaks\nconst elementTimeouts = new WeakMap<HTMLElement, ReturnType<typeof setTimeout>>();\n\n/**\n * Adds data-action-id attributes to first-level children of the actions container\n * Ensures unique IDs by checking existing ones\n */\nexport function addActionIdsToFirstLevelChildren(actionsContainerEl: HTMLElement | null): void {\n if (!actionsContainerEl) {\n return;\n }\n\n // Get all direct children of the actions container\n const directChildren = Array.from(actionsContainerEl.children) as HTMLElement[];\n\n // Collect existing action IDs to avoid duplicates\n const existingIds = new Set<string>();\n directChildren.forEach((child) => {\n const existingId = child.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n if (existingId) {\n existingIds.add(existingId);\n }\n });\n\n // Find the next available index for auto-generated IDs\n let nextIndex = 0;\n while (existingIds.has(`auto-action-${nextIndex}`)) {\n nextIndex++;\n }\n\n directChildren.forEach((child) => {\n // Only add data-action-id if it doesn't already exist\n if (!child.hasAttribute(DATA_ATTRIBUTES.ACTION_ID)) {\n child.setAttribute(DATA_ATTRIBUTES.ACTION_ID, `${ID_PREFIXES.AUTO_ACTION}${nextIndex}`);\n nextIndex++;\n }\n });\n}\n\n/**\n * Creates a map of elements to their IDs\n */\nexport function createElementIdMap(directChildren: HTMLElement[]): Map<HTMLElement, string> {\n const elementIdMap = new Map<HTMLElement, string>();\n\n directChildren.forEach((child, index) => {\n const actionId = child.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n if (actionId) {\n elementIdMap.set(child, actionId);\n } else {\n // Use index as ID for elements without data-action-id\n elementIdMap.set(child, `${ID_PREFIXES.INDEX_BASED}${index}`);\n }\n });\n\n return elementIdMap;\n}\n\n/**\n * Cleans up overflow IDs for elements that no longer exist\n */\nexport function cleanupOverflowIds(overflowIds: Set<string>, currentElementIds: Set<string>): void {\n const idsToRemove: string[] = [];\n\n overflowIds.forEach((id) => {\n if (!currentElementIds.has(id)) {\n idsToRemove.push(id);\n }\n });\n\n idsToRemove.forEach((id) => {\n overflowIds.delete(id);\n });\n}\n\n/**\n * Applies visibility classes to elements based on overflow state\n */\nexport function applyElementVisibility(element: HTMLElement, elementId: string, overflowIds: Set<string>): void {\n // Clear any pending timeout for this element\n const existingTimeout = elementTimeouts.get(element);\n if (existingTimeout) {\n clearTimeout(existingTimeout);\n elementTimeouts.delete(element);\n }\n\n if (overflowIds.has(elementId)) {\n element.removeAttribute(DATA_ATTRIBUTES.PROCESSED);\n element.classList.add('invisible');\n } else {\n const timeout = setTimeout(() => {\n if (element.isConnected) {\n element.setAttribute(DATA_ATTRIBUTES.PROCESSED, 'true');\n }\n elementTimeouts.delete(element);\n }, DEBOUNCE.FAST);\n elementTimeouts.set(element, timeout);\n element.classList.remove('invisible');\n }\n}\n\n/**\n * Syncs more-actions content visibility based on overflow state\n * Shows more-actions items whose data-action-id is in overflowIds\n * Supports nested elements with data-action-id (e.g., Menu > MenuItem)\n */\nexport function syncMoreActionsVisibility(moreDropdownMenuEl: HTMLElement | null, overflowIds: Set<string>): void {\n if (!moreDropdownMenuEl) {\n return;\n }\n\n // Find all elements with data-action-id at any nesting level (for nested wrappers like Menu > MenuItem)\n const nestedItemsWithActionId = Array.from(\n moreDropdownMenuEl.querySelectorAll(`[${DATA_ATTRIBUTES.ACTION_ID}]`),\n ) as HTMLElement[];\n\n // Filter to only \"leaf\" elements - those that don't contain other elements with data-action-id\n // This prevents hiding wrapper elements that contain the actual actionable items\n const leafItems = nestedItemsWithActionId.filter((element) => {\n const nestedActionsInside = element.querySelectorAll(`[${DATA_ATTRIBUTES.ACTION_ID}]`);\n // If element has nested elements with data-action-id inside, it's a wrapper, not a leaf\n return nestedActionsInside.length === 0;\n });\n\n // Apply styles and visibility to leaf items only\n leafItems.forEach((element) => {\n const actionId = element.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n\n // Show more-actions item only if its action-id is in overflowIds (item is hidden in toolbar)\n const shouldShow = actionId && overflowIds.has(actionId);\n if (shouldShow) {\n element.classList.remove('hidden');\n } else {\n element.classList.add('hidden');\n }\n });\n}\n","import { useElementBounding } from '@vueuse/core';\nimport debounce from 'lodash-es/debounce';\nimport { nextTick, type Ref, ref, type ShallowRef } from 'vue';\n\nimport { DEBOUNCE } from '../../constants';\nimport { DATA_ATTRIBUTES } from './constants';\nimport { applyElementVisibility, createElementIdMap, syncMoreActionsVisibility } from './utils';\n\ninterface UseOverflowCalculatorOptions {\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n overflowIds: Ref<Set<string>>;\n moreDropdownMenuRef: ShallowRef<HTMLElement | null>;\n trackerElementRef: ShallowRef<HTMLElement | null>;\n onOverflowChange?: () => void;\n}\n\nexport function useOverflowCalculator({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n onOverflowChange,\n}: UseOverflowCalculatorOptions) {\n const isProcessing = ref(false);\n const lastOverflowState = ref<string>(''); // Track last overflow state to prevent unnecessary updates\n const trackerBounding = useElementBounding(trackerElementRef);\n\n /**\n * Updates overflow state and applies visibility classes to elements\n */\n function updateOverflowState(\n newOverflowIds: Set<string>,\n directChildren: HTMLElement[],\n elementIdMap: Map<HTMLElement, string>,\n ): void {\n overflowIds.value.clear();\n newOverflowIds.forEach((id) => overflowIds.value.add(id));\n\n // Apply visibility classes\n directChildren.forEach((element) => {\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || undefined;\n\n if (elementId) {\n applyElementVisibility(element, elementId, overflowIds.value);\n }\n });\n }\n\n function calculateOverflowInternal() {\n if (!actionsContainerRef.value || !trackerElementRef.value) {\n isProcessing.value = false;\n return;\n }\n\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n const elementIdMap = createElementIdMap(directChildren);\n\n // Create a new overflow set to compare with current state\n const newOverflowIds = new Set<string>();\n\n // Get current gap width from CSS computed styles of the actions container\n const computedStyle = window.getComputedStyle(actionsContainerRef.value);\n const gapValue = computedStyle.columnGap || computedStyle.gap;\n const gapWidth = gapValue ? parseFloat(gapValue) : 0;\n\n // Calculate which elements should be hidden based on their position relative to tracker\n directChildren.forEach((element, index) => {\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || undefined;\n\n const elementRect = element.getBoundingClientRect();\n\n // Calculate the effective right edge including gap\n // If this is not the last element, add gap to the right edge\n const effectiveRightEdge = index < directChildren.length - 1 ? elementRect.right + gapWidth : elementRect.right;\n\n // If element's effective right edge extends beyond tracker's left edge, hide it\n if (effectiveRightEdge > trackerBounding.left.value) {\n if (elementId) {\n newOverflowIds.add(elementId);\n }\n }\n });\n\n // Check if overflow state has actually changed\n const currentOverflowState = Array.from(overflowIds.value).sort().join(',');\n const newOverflowState = Array.from(newOverflowIds).sort().join(',');\n\n if (currentOverflowState !== newOverflowState) {\n // Update overflow state and apply visibility\n updateOverflowState(newOverflowIds, directChildren, elementIdMap);\n\n // Sync more-actions content visibility\n syncMoreActionsVisibility(moreDropdownMenuRef.value, overflowIds.value);\n\n // Call callback if provided and state actually changed\n // Use nextTick to ensure CSS changes are applied before calculating visible elements width\n if (onOverflowChange && lastOverflowState.value !== newOverflowState) {\n lastOverflowState.value = newOverflowState;\n nextTick(() => {\n onOverflowChange();\n });\n }\n }\n\n isProcessing.value = false;\n }\n\n const debouncedCalculateOverflow = debounce(calculateOverflowInternal, DEBOUNCE.FAST);\n\n function calculateOverflow() {\n if (isProcessing.value || !actionsContainerRef.value || !trackerElementRef.value) {\n return;\n }\n\n isProcessing.value = true;\n debouncedCalculateOverflow();\n }\n\n function updateTrackerBounding() {\n trackerBounding.update();\n }\n\n function cleanup() {\n debouncedCalculateOverflow.cancel();\n isProcessing.value = false;\n }\n\n return {\n calculateOverflow,\n applyElementVisibility,\n updateOverflowState,\n updateTrackerBounding,\n cleanup,\n isProcessing,\n };\n}\n","import { useIntersectionObserver, useResizeObserver } from '@vueuse/core';\nimport debounce from 'lodash-es/debounce';\nimport { nextTick, onBeforeUnmount, onDeactivated, onMounted, onUpdated, type Ref, ref, type ShallowRef } from 'vue';\n\nimport { DEBOUNCE } from '../../constants';\nimport { DATA_ATTRIBUTES } from './constants';\nimport { useOverflowCalculator } from './useOverflowCalculator';\nimport {\n addActionIdsToFirstLevelChildren as addActionIds,\n cleanupOverflowIds,\n createElementIdMap,\n syncMoreActionsVisibility,\n} from './utils';\n\ninterface CreateIntersectionObserverOptions {\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n overflowIds: Ref<Set<string>>;\n moreDropdownMenuRef: ShallowRef<HTMLElement | null>;\n trackerElementRef: ShallowRef<HTMLElement | null>;\n moreDropdownWidth: Ref<number>;\n calculateMoreButtonWidth: () => number;\n hasMoreActionsSlot: Ref<boolean>;\n onOverflowChange?: () => void;\n}\n\nexport function createIntersectionObserver({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n moreDropdownWidth,\n calculateMoreButtonWidth,\n hasMoreActionsSlot,\n onOverflowChange,\n}: CreateIntersectionObserverOptions) {\n const isInitializing = ref(false);\n\n const {\n calculateOverflow,\n applyElementVisibility,\n updateOverflowState,\n updateTrackerBounding,\n cleanup: cleanupCalculator,\n isProcessing,\n } = useOverflowCalculator({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n onOverflowChange,\n });\n\n let mutationObserver: MutationObserver | null = null;\n let stopResizeObserver: (() => void) | null = null;\n let stopIntersectionObserver: (() => void) | null = null;\n\n function clearOverflowState() {\n overflowIds.value.clear();\n moreDropdownWidth.value = 0;\n }\n\n /**\n * Cleanup all observers (ResizeObserver and IntersectionObserver)\n * to prevent memory leaks when re-creating them\n */\n function cleanupObservers() {\n if (stopResizeObserver) {\n stopResizeObserver();\n stopResizeObserver = null;\n }\n if (stopIntersectionObserver) {\n stopIntersectionObserver();\n stopIntersectionObserver = null;\n }\n }\n\n // Track DOM mutations - created once, outside of createObserver to prevent duplicates\n const handleMutation = debounce(\n () => {\n if (!actionsContainerRef.value || !hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n\n // Cleanup old observers before re-initializing\n cleanupObservers();\n cleanupCalculator();\n debouncedInitObserve();\n },\n DEBOUNCE.FAST,\n { leading: false, trailing: true },\n );\n\n function createObserver() {\n if (!actionsContainerRef.value) {\n return;\n }\n\n // If there's no more-actions slot, don't set up overflow detection\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Get all direct children of the actions container\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n\n // Create a map of elements to their IDs (either data-action-id or index-based)\n const elementIdMap = createElementIdMap(directChildren);\n\n // Clean up overflowIds for elements that no longer exist\n const currentElementIds = new Set(elementIdMap.values());\n cleanupOverflowIds(overflowIds.value, currentElementIds);\n\n // to track container size changes\n const { stop: stopResize } = useResizeObserver(actionsContainerRef, () => {\n updateTrackerBounding();\n calculateOverflow();\n });\n stopResizeObserver = stopResize;\n\n const { stop: stopIntersection } = useIntersectionObserver(\n directChildren,\n (entries) => {\n if (isProcessing.value) {\n return;\n }\n\n let hasChanges = false;\n const newOverflowIds = new Set(overflowIds.value);\n\n entries.forEach((entry) => {\n const element = entry.target as HTMLElement;\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || undefined;\n\n // Check if element is fully visible\n if (entry.intersectionRatio === 1) {\n // show action, hide in dropdown\n if (elementId && newOverflowIds.has(elementId)) {\n newOverflowIds.delete(elementId);\n hasChanges = true;\n }\n } else {\n // hide action, show in dropdown (intersectionRatio < 1 means partially or not visible)\n if (elementId && !newOverflowIds.has(elementId)) {\n newOverflowIds.add(elementId);\n hasChanges = true;\n }\n }\n });\n\n // Only update if there are actual changes\n if (hasChanges) {\n const currentOverflowState = Array.from(overflowIds.value).sort().join(',');\n const newOverflowState = Array.from(newOverflowIds).sort().join(',');\n\n if (currentOverflowState !== newOverflowState) {\n // Update overflow state and apply visibility\n updateOverflowState(newOverflowIds, directChildren, elementIdMap);\n\n // Sync more-actions content visibility\n syncMoreActionsVisibility(moreDropdownMenuRef.value, overflowIds.value);\n\n // Call callback if provided and state actually changed\n // Use nextTick to ensure CSS changes are applied before calculating visible elements width\n if (onOverflowChange) {\n nextTick(() => {\n onOverflowChange();\n });\n }\n }\n }\n },\n {\n root: actionsContainerRef.value,\n },\n );\n stopIntersectionObserver = stopIntersection;\n\n // Apply initial visibility to all elements\n directChildren.forEach((element) => {\n const elementId = elementIdMap.get(element) || element.getAttribute(DATA_ATTRIBUTES.ACTION_ID) || '';\n applyElementVisibility(element, elementId, overflowIds.value);\n });\n\n // Initial calculation\n calculateOverflow();\n\n syncMoreActionsVisibility(moreDropdownMenuRef.value, overflowIds.value);\n }\n\n function initObserve() {\n if (!actionsContainerRef.value) {\n return;\n }\n\n // If there's no more-actions slot, don't initialize\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n\n createObserver();\n\n // Set initial dropdown width - only if not already set\n if (moreDropdownWidth.value === 0) {\n moreDropdownWidth.value = calculateMoreButtonWidth();\n }\n\n // Setup MutationObserver once to watch for DOM changes\n // Only create if it doesn't exist to prevent duplicates\n if (!mutationObserver && actionsContainerRef.value) {\n mutationObserver = new MutationObserver(handleMutation);\n mutationObserver.observe(actionsContainerRef.value, {\n childList: true, // Watch for added/removed children\n subtree: false, // Only watch direct children\n });\n }\n }\n\n const debouncedInitObserve = debounce(\n () => {\n if (!isInitializing.value) {\n isInitializing.value = true;\n initObserve();\n isInitializing.value = false;\n }\n },\n DEBOUNCE.FAST,\n { leading: true },\n );\n\n onMounted(() => {\n // If there's no more-actions slot, skip initialization\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n initObserve();\n });\n\n onUpdated(() => {\n // If there's no more-actions slot, skip initialization\n if (!hasMoreActionsSlot.value) {\n return;\n }\n\n // Add data-action-id to first-level children\n addActionIds(actionsContainerRef.value);\n // Clear overflowIds if no actions are present\n if (actionsContainerRef.value) {\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n if (directChildren.length === 0) {\n clearOverflowState();\n }\n }\n cleanupObservers();\n cleanupCalculator();\n debouncedInitObserve();\n });\n\n onDeactivated(() => {\n cleanupObservers();\n cleanupCalculator();\n handleMutation.cancel();\n debouncedInitObserve.cancel();\n if (mutationObserver) {\n mutationObserver.disconnect();\n mutationObserver = null;\n }\n });\n\n onBeforeUnmount(() => {\n cleanupObservers();\n cleanupCalculator();\n handleMutation.cancel();\n debouncedInitObserve.cancel();\n if (mutationObserver) {\n mutationObserver.disconnect();\n mutationObserver = null;\n }\n });\n}\n","import { type ComputedRef, nextTick, ref, type ShallowRef, watch } from 'vue';\n\nimport Dropdown from '../Dropdown/Dropdown.vue';\n\n// Updated interface with Ref suffix naming convention\ninterface UseMoreDropdownWidthOptions {\n moreDropdownRef: ShallowRef<InstanceType<typeof Dropdown> | null>;\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n moreButtonAlign: 'separate' | 'together';\n hasOverflowActions: ComputedRef<boolean>;\n}\n\nexport function useMoreButtonWidth({\n moreDropdownRef,\n actionsContainerRef,\n moreButtonAlign,\n hasOverflowActions,\n}: UseMoreDropdownWidthOptions) {\n /**\n * Calculates the width of the More dropdown with gap consideration\n * When moreButtonAlign is 'separate', adds the gap between actions container and dropdown\n * When moreButtonAlign is 'together', returns only the dropdown width\n */\n const calculateMoreButtonWidth = (): number => {\n if (!moreDropdownRef.value?.$el) {\n return 0;\n }\n\n const dropdownWidth = moreDropdownRef.value.$el.getBoundingClientRect().width;\n\n // If moreButtonAlign is separate, add gap between actions container and dropdown\n if (moreButtonAlign === 'separate' && actionsContainerRef.value) {\n const computedStyle = window.getComputedStyle(actionsContainerRef.value);\n const gapWidth = parseFloat(computedStyle.gap) || 0;\n return dropdownWidth + gapWidth;\n }\n\n return dropdownWidth;\n };\n\n const moreButtonWidth = ref(0);\n\n watch(hasOverflowActions, (newValue) => {\n if (newValue && moreDropdownRef.value) {\n nextTick(() => {\n const calculatedWidth = calculateMoreButtonWidth();\n if (calculatedWidth > 0) {\n moreButtonWidth.value = calculatedWidth;\n }\n });\n }\n });\n\n return {\n calculateMoreButtonWidth,\n moreButtonWidth,\n };\n}\n","import { nextTick, type Ref, ref, type ShallowRef, watch } from 'vue';\n\nimport { DATA_ATTRIBUTES, FADE_ANIMATION_DURATION } from './constants';\n\ninterface UseVisibleElementsWidthOptions {\n actionsContainerRef: ShallowRef<HTMLElement | null>;\n overflowIds: Ref<Set<string>>;\n}\n\nexport function useVisibleElementsWidth({ actionsContainerRef, overflowIds }: UseVisibleElementsWidthOptions) {\n const visibleElementsWidth = ref(0);\n const isRecalculatingWidth = ref(false);\n const isRecalculatingWithDelay = ref(false);\n let widthCalculationTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Calculates the total width of currently visible elements\n * This is used for positioning the More button\n */\n const calculateVisibleElementsWidth = () => {\n if (!actionsContainerRef.value) {\n visibleElementsWidth.value = 0;\n return;\n }\n\n let totalWidth = 0;\n const directChildren = Array.from(actionsContainerRef.value.children) as HTMLElement[];\n\n directChildren.forEach((element, index) => {\n const elementId = element.getAttribute(DATA_ATTRIBUTES.ACTION_ID);\n\n // Check if element should be visible based on overflow state\n // Elements without data-action-id are always considered visible (never hidden by overflow logic)\n const shouldBeVisible = !elementId || !overflowIds.value.has(elementId);\n\n // Double-check with CSS classes as a fallback\n const isHiddenByCSS = element.classList.contains('invisible');\n\n // Element is considered visible if:\n // 1. It's not in overflowIds (should be visible) OR it has no data-action-id (always visible)\n // 2. AND it's not hidden by CSS classes\n if (shouldBeVisible && !isHiddenByCSS) {\n const rect = element.getBoundingClientRect();\n totalWidth += rect.width;\n\n // Add gap between elements\n if (index < directChildren.length - 1 && actionsContainerRef.value) {\n // Always get the most current gap width from CSS computed styles of the actions container\n const computedStyle = window.getComputedStyle(actionsContainerRef.value);\n const gapValue = computedStyle.columnGap || computedStyle.gap;\n const gapWidth = gapValue ? parseFloat(gapValue) : 0;\n totalWidth += gapWidth;\n }\n }\n });\n\n visibleElementsWidth.value = totalWidth;\n };\n\n /**\n * Calculates visible elements width with a delay to allow animations to complete\n * This ensures that width calculation happens after elements are actually hidden/shown\n */\n const calculateVisibleElementsWidthDelayed = () => {\n // Set recalculating state immediately to hide More button\n isRecalculatingWithDelay.value = true;\n\n // Clear any existing timeout\n if (widthCalculationTimeout) {\n clearTimeout(widthCalculationTimeout);\n }\n\n // Set a new timeout to calculate width after animation completes\n widthCalculationTimeout = setTimeout(() => {\n if (!isRecalculatingWidth.value) {\n isRecalculatingWidth.value = true;\n\n // Use double nextTick to ensure all DOM updates and CSS changes are applied\n nextTick(() => {\n nextTick(() => {\n calculateVisibleElementsWidth();\n isRecalculatingWidth.value = false;\n isRecalculatingWithDelay.value = false; // Show More button after calculation is complete\n });\n });\n }\n }, FADE_ANIMATION_DURATION + 100); // Add small buffer to ensure animation is complete\n };\n\n // Watch for changes in overflowIds to recalculate visible elements width with delay\n watch(overflowIds, () => {\n calculateVisibleElementsWidthDelayed();\n });\n\n /**\n * Cleanup function to clear any pending timeouts\n */\n const cleanup = () => {\n if (widthCalculationTimeout) {\n clearTimeout(widthCalculationTimeout);\n widthCalculationTimeout = null;\n }\n isRecalculatingWithDelay.value = false;\n };\n\n return {\n visibleElementsWidth,\n isRecalculatingWidth,\n isRecalculatingWithDelay,\n calculateVisibleElementsWidth,\n calculateVisibleElementsWidthDelayed,\n cleanup,\n };\n}\n","<script lang=\"ts\" setup>\n /**\n * MoreActions Component\n *\n * This component provides a responsive toolbar that automatically moves overflow items\n * into a \"More\" dropdown menu when space is limited.\n *\n * @example\n * <MoreActions>\n * <Button data-action-id=\"edit\">Edit</Button>\n * <Button data-action-id=\"delete\">Delete</Button>\n * <Button data-action-id=\"share\">Share</Button>\n *\n * <template #more-actions>\n * <DropdownItem data-action-id=\"edit\">Edit Item</DropdownItem>\n * <DropdownItem data-action-id=\"delete\">Delete Item</DropdownItem>\n * <DropdownItem data-action-id=\"share\">Share Item</DropdownItem>\n * </template>\n * </MoreActions>\n *\n * IMPORTANT:\n * - The #more-actions slot is REQUIRED. If not provided, the More dropdown will not be rendered.\n * - Each item in the default slot must have a corresponding item in the 'more-actions'\n * slot with the same data-action-id attribute.\n * - The component automatically shows/hides matching items based on available space:\n * - Items visible in toolbar → hidden in more-actions\n * - Items hidden in toolbar (overflow) → visible in more-actions\n */\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, onBeforeUnmount, ref, useSlots, useTemplateRef, watch } from 'vue';\n\n import { useToggleAnimation } from '../../composables/useToggleAnimation/useToggleAnimation';\n import { DEBOUNCE } from '../../constants';\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import Icon from '../Icon/Icon.vue';\n import { FADE_ANIMATION_DURATION, ID_PREFIXES, Z_INDEX } from './constants';\n import { createIntersectionObserver } from './createIntersectionObserver';\n import { useMoreButtonWidth } from './useMoreButtonWidth';\n import { useVisibleElementsWidth } from './useVisibleElementsWidth';\n\n export interface MoreActionsProps {\n /**\n * CSS class or classes to be applied to the actions container\n */\n actionsContainerClass?: string | Record<string, boolean> | undefined;\n /**\n * HTML element tag to use for the actions container\n * Useful when you need to maintain valid HTML semantics\n * (e.g., use 'ul' when children are <li> elements)\n * @default 'div'\n */\n actionsContainerTag?: string;\n /**\n * Text to display on the more actions button\n */\n moreButtonText?: string;\n /**\n * Optional width for the more-actions container\n * Applies style=\"width: {width}\" to the stash-more-actions element\n */\n width?: string | number;\n /**\n * Rendering mode for dropdown items\n * - 'default': Button-style rendering (current behavior)\n * - 'custom': Custom rendering through slots\n */\n dropdownMode?: 'default' | 'custom';\n /**\n * Alignment of the More button\n * - 'separate': Button is aligned to the right edge of the actions container (default)\n * - 'together': Button is aligned immediately after the last visible action\n */\n moreButtonAlign?: 'separate' | 'together';\n }\n\n const props = withDefaults(defineProps<MoreActionsProps>(), {\n actionsContainerClass: undefined,\n actionsContainerTag: 'div',\n moreButtonText: () => t('ll.more'),\n dropdownMode: 'default',\n moreButtonAlign: 'separate',\n width: undefined,\n });\n\n // Check if more-actions slot is provided (REQUIRED for dropdown to render)\n const slots = useSlots();\n const hasMoreActionsSlot = computed(() => !!slots['more-actions']);\n\n // Refs for DOM elements\n const actionsContainerRef = useTemplateRef<HTMLElement>('actionsContainerRef');\n const moreDropdownRef = useTemplateRef('moreDropdownRef');\n const moreDropdownMenuRef = useTemplateRef('moreDropdownMenuRef');\n const trackerElementRef = useTemplateRef('trackerElementRef');\n\n // State management\n const overflowIds = ref<Set<string>>(new Set());\n const isMoreMenuOpen = ref(false);\n const moreMenuId = uniqueId(ID_PREFIXES.MORE_MENU);\n const showButtonDelayTimeout = ref<ReturnType<typeof setTimeout> | null>(null);\n const isDelayedShowReady = ref(false);\n\n const {\n isVisible: isMoreButtonVisible,\n shouldShow: shouldMoreButtonShow,\n toggle: toggleMoreButtonAnimation,\n } = useToggleAnimation({\n duration: FADE_ANIMATION_DURATION,\n initialVisible: false,\n });\n\n const hasOverflowActions = computed(() => overflowIds.value.size > 0);\n\n // Updated to use new Ref suffix naming convention\n const { calculateMoreButtonWidth, moreButtonWidth } = useMoreButtonWidth({\n moreDropdownRef,\n actionsContainerRef,\n moreButtonAlign: props.moreButtonAlign,\n hasOverflowActions,\n });\n\n // Updated to use new Ref suffix naming convention\n const {\n visibleElementsWidth,\n isRecalculatingWithDelay,\n calculateVisibleElementsWidthDelayed,\n cleanup: cleanupVisibleElementsWidth,\n } = useVisibleElementsWidth({\n actionsContainerRef,\n overflowIds,\n });\n\n const shouldShowMoreButton = computed(() => {\n return (\n hasMoreActionsSlot.value &&\n hasOverflowActions.value &&\n !isRecalculatingWithDelay.value &&\n isDelayedShowReady.value\n );\n });\n\n const isMoreMenuOpenString = computed(() => isMoreMenuOpen.value.toString());\n\n const actionsContainerWidth = computed(() => {\n if (!shouldShowMoreButton.value) {\n return '100%';\n }\n\n return `calc(100% - ${moreButtonWidth.value}px)`;\n });\n\n const moreButtonPosition = computed(() => {\n if (props.moreButtonAlign === 'together') {\n return { left: `${visibleElementsWidth.value}px`, right: 'auto' };\n } else {\n // Default separate alignment\n return { right: '0', left: 'auto' };\n }\n });\n\n createIntersectionObserver({\n actionsContainerRef,\n overflowIds,\n moreDropdownMenuRef,\n trackerElementRef,\n moreDropdownWidth: moreButtonWidth,\n calculateMoreButtonWidth,\n hasMoreActionsSlot,\n onOverflowChange: calculateVisibleElementsWidthDelayed,\n });\n\n // Watch for when recalculation completes and overflow actions exist\n watch(\n () => hasMoreActionsSlot.value && hasOverflowActions.value && !isRecalculatingWithDelay.value,\n (isReady) => {\n // Clear any existing timeout\n if (showButtonDelayTimeout.value) {\n clearTimeout(showButtonDelayTimeout.value);\n showButtonDelayTimeout.value = null;\n }\n\n if (isReady) {\n // Add delay before showing the button\n showButtonDelayTimeout.value = setTimeout(() => {\n isDelayedShowReady.value = true;\n }, DEBOUNCE.FAST);\n } else {\n // Hide immediately when overflow actions are removed or slot is not available\n isDelayedShowReady.value = false;\n }\n },\n );\n\n // Watch for changes in shouldShowMoreButton to handle fade animations\n watch(shouldShowMoreButton, (newValue) => {\n toggleMoreButtonAnimation(newValue);\n });\n\n function handleDropdownToggle(event: boolean) {\n isMoreMenuOpen.value = event;\n }\n\n onBeforeUnmount(() => {\n cleanupVisibleElementsWidth();\n if (showButtonDelayTimeout.value) {\n clearTimeout(showButtonDelayTimeout.value);\n }\n });\n</script>\n\n<template>\n <div\n class=\"stash-more-actions relative overflow-x-hidden\"\n data-test=\"stash-more-actions\"\n :style=\"{ width: props.width }\"\n >\n <component\n :is=\"props.actionsContainerTag\"\n ref=\"actionsContainerRef\"\n data-test=\"stash-more-actions__container\"\n :style=\"{\n width: actionsContainerWidth,\n minWidth: moreButtonWidth ? `${moreButtonWidth}px` : undefined,\n }\"\n :class=\"['stash-more-actions__container flex items-center gap-2 overflow-x-hidden', props.actionsContainerClass]\"\n >\n <!-- Default slot for elements that can be hidden -->\n <slot></slot>\n </component>\n\n <!-- Tracker Element - to detect when action elements overlap with it, triggering overflow behavior -->\n <div\n ref=\"trackerElementRef\"\n class=\"stash-more-actions__tracker\"\n :style=\"{\n position: 'absolute',\n right: '0px',\n top: '0',\n visibility: 'hidden',\n width: moreButtonWidth + 'px',\n height: '100%',\n pointerEvents: 'none',\n zIndex: Z_INDEX.TRACKER,\n }\"\n ></div>\n\n <!-- Only render dropdown if more-actions slot is provided -->\n <Dropdown\n v-if=\"hasMoreActionsSlot\"\n ref=\"moreDropdownRef\"\n :class=\"[\n '!absolute top-0',\n shouldMoreButtonShow ? 'animate-fade-in' : 'animate-fade-out',\n { invisible: !isMoreButtonVisible },\n ]\"\n :style=\"moreButtonPosition\"\n @toggle=\"handleDropdownToggle\"\n >\n <template #toggle=\"{ toggle }\">\n <slot name=\"toggle\" :toggle=\"toggle\" :is-open=\"isMoreMenuOpen\">\n <Button\n class=\"button -border-gray-500 text-gray-500 flex w-full items-center justify-between -border\"\n secondary\n :aria-expanded=\"isMoreMenuOpenString\"\n @click=\"toggle\"\n >\n {{ props.moreButtonText }} <Icon class=\"-ml-1.5\" name=\"action-dots\" />\n </Button>\n </slot>\n </template>\n\n <template #default>\n <div\n :id=\"moreMenuId\"\n ref=\"moreDropdownMenuRef\"\n data-test=\"stash-more-actions__dropdown\"\n class=\"flex flex-col gap-1.5 p-1.5\"\n >\n <!-- More actions slot content (only overflow items will be shown) -->\n <slot name=\"more-actions\"></slot>\n </div>\n </template>\n </Dropdown>\n </div>\n</template>\n\n<style module>\n @layer utilities {\n :global([data-action-id]) {\n flex-shrink: 0;\n }\n }\n\n :global(.stash-more-actions__container [data-action-id]:not([data-more-actions-processed])) {\n visibility: hidden;\n }\n</style>\n"],"names":["useToggleAnimation","options","duration","initialVisible","isVisible","toggleIsVisible","useToggle","shouldShow","toggleShouldShow","shouldHide","toggleShouldHide","timeoutId","ref","clearExistingTimeout","setVisible","visible","toggle","show","hide","cleanup","onUnmounted","Z_INDEX","ID_PREFIXES","DATA_ATTRIBUTES","FADE_ANIMATION_DURATION","elementTimeouts","addActionIdsToFirstLevelChildren","actionsContainerEl","directChildren","existingIds","child","existingId","nextIndex","createElementIdMap","elementIdMap","index","actionId","cleanupOverflowIds","overflowIds","currentElementIds","idsToRemove","id","applyElementVisibility","element","elementId","existingTimeout","timeout","DEBOUNCE","syncMoreActionsVisibility","moreDropdownMenuEl","useOverflowCalculator","actionsContainerRef","moreDropdownMenuRef","trackerElementRef","onOverflowChange","isProcessing","lastOverflowState","trackerBounding","useElementBounding","updateOverflowState","newOverflowIds","calculateOverflowInternal","computedStyle","gapValue","gapWidth","elementRect","currentOverflowState","newOverflowState","nextTick","debouncedCalculateOverflow","debounce","calculateOverflow","updateTrackerBounding","createIntersectionObserver","moreDropdownWidth","calculateMoreButtonWidth","hasMoreActionsSlot","isInitializing","cleanupCalculator","mutationObserver","stopResizeObserver","stopIntersectionObserver","clearOverflowState","cleanupObservers","handleMutation","addActionIds","debouncedInitObserve","createObserver","stopResize","useResizeObserver","stopIntersection","useIntersectionObserver","entries","hasChanges","entry","initObserve","onMounted","onUpdated","onDeactivated","onBeforeUnmount","useMoreButtonWidth","moreDropdownRef","moreButtonAlign","hasOverflowActions","_a","dropdownWidth","moreButtonWidth","watch","newValue","calculatedWidth","useVisibleElementsWidth","visibleElementsWidth","isRecalculatingWidth","isRecalculatingWithDelay","widthCalculationTimeout","calculateVisibleElementsWidth","totalWidth","shouldBeVisible","isHiddenByCSS","rect","calculateVisibleElementsWidthDelayed","props","__props","slots","useSlots","computed","useTemplateRef","isMoreMenuOpen","moreMenuId","uniqueId","showButtonDelayTimeout","isDelayedShowReady","isMoreButtonVisible","shouldMoreButtonShow","toggleMoreButtonAnimation","cleanupVisibleElementsWidth","shouldShowMoreButton","isMoreMenuOpenString","actionsContainerWidth","moreButtonPosition","isReady","handleDropdownToggle","event","_createElementBlock","_normalizeStyle","_createBlock","_resolveDynamicComponent","_unref","_normalizeClass","_renderSlot","_ctx","_createElementVNode","Dropdown","_withCtx","_createVNode","Button","Icon"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ObfuscateText.js","sources":["../src/components/ObfuscateText/ObfuscateText.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref } from 'vue';\n\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({ name: 'll-obfuscate-text' });\n\n import obfuscateText, { ObfuscateTextOptions } from '../../utils/obfuscateText';\n\n export interface ObfuscateTextProps extends ObfuscateTextOptions {\n /**\n * The full text\n */\n text: string;\n\n /**\n * Whether to obfuscate all characters.\n * @deprecated omit the lengthToKeep prop to achieve the same result\n */\n obfuscateAll?: boolean;\n\n /**\n * Displays a button for toggling text visibility\n */\n showToggle?: boolean;\n }\n\n const isFullTextVisible = ref(false);\n\n const props = withDefaults(defineProps<ObfuscateTextProps>(), {\n maskChar: '•',\n maskCharCount: 10,\n lengthToKeep: 0,\n position: 'start',\n obfuscateAll: false,\n showToggle: false,\n });\n\n const obfuscatedText = computed(() => {\n if (props.showToggle && isFullTextVisible.value) {\n return props.text;\n }\n\n if (props.obfuscateAll) {\n return props.maskChar.repeat(props.maskCharCount);\n }\n\n return obfuscateText(props.text, {\n maskChar: props.maskChar,\n maskCharCount: props.maskCharCount,\n lengthToKeep: props.lengthToKeep,\n position: props.position,\n });\n });\n</script>\n\n<template>\n <span class=\"stash-obfuscate-text\" data-test=\"stash-obfuscate-text\">\n {{ obfuscatedText }}\n <Button\n v-if=\"props.showToggle\"\n class=\"ml-1 size-auto p-0\"\n icon\n type=\"button\"\n @click=\"isFullTextVisible = !isFullTextVisible\"\n >\n <Icon\n :name=\"isFullTextVisible ? 'hide' : 'show'\"\n class=\"cursor-pointer\"\n :class=\"isFullTextVisible ? 'stash-obfuscate-text__hide-toggle-icon' : 'stash-obfuscate-text__show-toggle-icon'\"\n :data-test=\"\n isFullTextVisible ? 'stash-obfuscate-text|hide-toggle-icon' : 'stash-obfuscate-text|show-toggle-icon'\n \"\n />\n </Button>\n </span>\n</template>\n"],"names":["isFullTextVisible","ref","props","__props","obfuscatedText","computed","obfuscateText"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4BE,UAAMA,IAAoBC,EAAI,EAAK,GAE7BC,IAAQC,GASRC,IAAiBC,EAAS,MAC1BH,EAAM,cAAcF,EAAkB,QACjCE,EAAM,OAGXA,EAAM,eACDA,EAAM,SAAS,OAAOA,EAAM,aAAa,IAG3CI,EAAcJ,EAAM,MAAM;AAAA,MAC/B,UAAUA,EAAM;AAAA,MAChB,eAAeA,EAAM;AAAA,MACrB,cAAcA,EAAM;AAAA,MACpB,UAAUA,EAAM;AAAA,IAAA,CACjB,CACF;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ObfuscateText.js","sources":["../src/components/ObfuscateText/ObfuscateText.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref } from 'vue';\n\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({ name: 'll-obfuscate-text' });\n\n import obfuscateText, { ObfuscateTextOptions } from '../../utils/obfuscateText';\n\n export interface ObfuscateTextProps extends ObfuscateTextOptions {\n /**\n * The full text\n */\n text: string;\n\n /**\n * Whether to obfuscate all characters.\n * @deprecated omit the lengthToKeep prop to achieve the same result\n */\n obfuscateAll?: boolean;\n\n /**\n * Displays a button for toggling text visibility\n */\n showToggle?: boolean;\n }\n\n const isFullTextVisible = ref(false);\n\n const props = withDefaults(defineProps<ObfuscateTextProps>(), {\n maskChar: '•',\n maskCharCount: 10,\n lengthToKeep: 0,\n position: 'start',\n obfuscateAll: false,\n showToggle: false,\n });\n\n const obfuscatedText = computed(() => {\n if (props.showToggle && isFullTextVisible.value) {\n return props.text;\n }\n\n if (props.obfuscateAll) {\n return props.maskChar.repeat(props.maskCharCount);\n }\n\n return obfuscateText(props.text, {\n maskChar: props.maskChar,\n maskCharCount: props.maskCharCount,\n lengthToKeep: props.lengthToKeep,\n position: props.position,\n });\n });\n</script>\n\n<template>\n <span class=\"stash-obfuscate-text\" data-test=\"stash-obfuscate-text\">\n {{ obfuscatedText }}\n <Button\n v-if=\"props.showToggle\"\n class=\"ml-1 size-auto p-0\"\n icon\n type=\"button\"\n @click=\"isFullTextVisible = !isFullTextVisible\"\n >\n <Icon\n :name=\"isFullTextVisible ? 'hide' : 'show'\"\n class=\"cursor-pointer\"\n :class=\"isFullTextVisible ? 'stash-obfuscate-text__hide-toggle-icon' : 'stash-obfuscate-text__show-toggle-icon'\"\n :data-test=\"\n isFullTextVisible ? 'stash-obfuscate-text|hide-toggle-icon' : 'stash-obfuscate-text|show-toggle-icon'\n \"\n />\n </Button>\n </span>\n</template>\n"],"names":["isFullTextVisible","ref","props","__props","obfuscatedText","computed","obfuscateText","_openBlock","_createElementBlock","_hoisted_1","_createTextVNode","_toDisplayString","_createBlock","Button","_cache","$event","_createVNode","Icon","_normalizeClass"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4BE,UAAMA,IAAoBC,EAAI,EAAK,GAE7BC,IAAQC,GASRC,IAAiBC,EAAS,MAC1BH,EAAM,cAAcF,EAAkB,QACjCE,EAAM,OAGXA,EAAM,eACDA,EAAM,SAAS,OAAOA,EAAM,aAAa,IAG3CI,EAAcJ,EAAM,MAAM;AAAA,MAC/B,UAAUA,EAAM;AAAA,MAChB,eAAeA,EAAM;AAAA,MACrB,cAAcA,EAAM;AAAA,MACpB,UAAUA,EAAM;AAAA,IAAA,CACjB,CACF;sBAIDK,EAAA,GAAAC,EAkBO,QAlBPC,GAkBO;AAAA,MAjBFC,EAAAC,EAAAP,EAAA,KAAc,IAAG,KACpB,CAAA;AAAA,MACQF,EAAM,mBADdU,EAeSC,GAAA;AAAA;QAbP,OAAM;AAAA,QACN,MAAA;AAAA,QACA,MAAK;AAAA,QACJ,SAAKC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEf,EAAA,QAAiB,CAAIA,EAAA;AAAA,MAAA;mBAE7B,MAOE;AAAA,UAPFgB,EAOEC,GAAA;AAAA,YANC,MAAMjB,EAAA,QAAiB,SAAA;AAAA,YACxB,OAAKkB,EAAA,CAAC,kBACElB,EAAA,QAAiB,2CAAA,wCAAA,CAAA;AAAA,YACxB,aAAsBA,EAAA,QAAiB,0CAAA;AAAA,UAAA;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PageContent.js","sources":["../src/components/PageContent/PageContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { useCssModule, useSlots } from 'vue';\n\n defineOptions({\n name: 'll-page-content',\n });\n\n export interface PageContentProps {\n /**\n * The active page navigation tab. If provided, the PageContent will render a tab panel as its root element.\n */\n activeTab?: string;\n }\n\n const props = withDefaults(defineProps<PageContentProps>(), {\n activeTab: undefined,\n });\n\n const slots = useSlots();\n const classes = useCssModule();\n</script>\n\n<template>\n <div\n :id=\"props.activeTab ? `tabpanel-${props.activeTab}` : undefined\"\n class=\"stash-page-content\"\n :class=\"[\n classes.root,\n {\n [classes['stash-page-content--has-sidebar']]: !!slots.sidebar,\n },\n ]\"\n data-test=\"stash-page-content\"\n :role=\"props.activeTab ? 'tabpanel' : undefined\"\n >\n <div :class=\"classes['stash-page-content__main']\">\n <!-- @slot Default content -->\n <slot name=\"default\"></slot>\n </div>\n\n <aside v-if=\"!!slots.sidebar\" :class=\"classes['stash-page-content__sidebar']\">\n <!-- @slot Sidebar content -->\n <slot name=\"sidebar\"></slot>\n </aside>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .root {\n max-width: var(--width-container); /* 1400px */\n padding-inline: var(--grid-gutter);\n position: relative;\n margin-inline: auto;\n width: 100%;\n }\n\n .stash-page-content--has-sidebar {\n display: flex;\n flex-direction: column;\n gap: var(--grid-gutter);\n }\n\n .stash-page-content--has-sidebar .stash-page-content__main {\n flex: 1; /* 12 cols */\n min-width: 0;\n }\n\n .stash-page-content--has-sidebar .stash-page-content__sidebar {\n flex: 0;\n min-width: 0;\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .stash-page-content--has-sidebar {\n flex-direction: row;\n }\n\n .stash-page-content--has-sidebar .stash-page-content__main {\n flex: 3; /* 9 cols */\n }\n\n .stash-page-content--has-sidebar .stash-page-content__sidebar {\n flex: 1; /* 3 cols */\n }\n }\n }\n</style>\n"],"names":["props","__props","slots","useSlots","classes","useCssModule"],"mappings":";;;;;;;;;AAcE,UAAMA,IAAQC,GAIRC,IAAQC,EAAA,GACRC,IAAUC,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"PageContent.js","sources":["../src/components/PageContent/PageContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { useCssModule, useSlots } from 'vue';\n\n defineOptions({\n name: 'll-page-content',\n });\n\n export interface PageContentProps {\n /**\n * The active page navigation tab. If provided, the PageContent will render a tab panel as its root element.\n */\n activeTab?: string;\n }\n\n const props = withDefaults(defineProps<PageContentProps>(), {\n activeTab: undefined,\n });\n\n const slots = useSlots();\n const classes = useCssModule();\n</script>\n\n<template>\n <div\n :id=\"props.activeTab ? `tabpanel-${props.activeTab}` : undefined\"\n class=\"stash-page-content\"\n :class=\"[\n classes.root,\n {\n [classes['stash-page-content--has-sidebar']]: !!slots.sidebar,\n },\n ]\"\n data-test=\"stash-page-content\"\n :role=\"props.activeTab ? 'tabpanel' : undefined\"\n >\n <div :class=\"classes['stash-page-content__main']\">\n <!-- @slot Default content -->\n <slot name=\"default\"></slot>\n </div>\n\n <aside v-if=\"!!slots.sidebar\" :class=\"classes['stash-page-content__sidebar']\">\n <!-- @slot Sidebar content -->\n <slot name=\"sidebar\"></slot>\n </aside>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .root {\n max-width: var(--width-container); /* 1400px */\n padding-inline: var(--grid-gutter);\n position: relative;\n margin-inline: auto;\n width: 100%;\n }\n\n .stash-page-content--has-sidebar {\n display: flex;\n flex-direction: column;\n gap: var(--grid-gutter);\n }\n\n .stash-page-content--has-sidebar .stash-page-content__main {\n flex: 1; /* 12 cols */\n min-width: 0;\n }\n\n .stash-page-content--has-sidebar .stash-page-content__sidebar {\n flex: 0;\n min-width: 0;\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .stash-page-content--has-sidebar {\n flex-direction: row;\n }\n\n .stash-page-content--has-sidebar .stash-page-content__main {\n flex: 3; /* 9 cols */\n }\n\n .stash-page-content--has-sidebar .stash-page-content__sidebar {\n flex: 1; /* 3 cols */\n }\n }\n }\n</style>\n"],"names":["props","__props","slots","useSlots","classes","useCssModule","_createElementBlock","_unref","_createElementVNode","_renderSlot","_ctx"],"mappings":";;;;;;;;;AAcE,UAAMA,IAAQC,GAIRC,IAAQC,EAAA,GACRC,IAAUC,EAAA;2BAIhBC,EAqBM,OAAA;AAAA,MApBH,IAAIN,EAAM,wBAAwBA,EAAM,SAAS,KAAK;AAAA,MACvD,UAAM,sBAAoB;AAAA,QACVO,EAAAH,CAAA,EAAQ;AAAA;WAAuBG,EAAAH,CAAA,EAAO,iCAAA,CAAA,GAAA,CAAA,CAAwCG,EAAAL,CAAA,EAAM;AAAA,QAAA;AAAA;MAMpG,aAAU;AAAA,MACT,MAAMF,EAAM,yBAAyB;AAAA,IAAA;MAEtCQ,EAGM,OAAA;AAAA,QAHA,SAAOD,EAAAH,CAAA,EAAO,0BAAA,CAAA;AAAA,MAAA;QAElBK,EAA4BC,EAAA,QAAA,SAAA;AAAA,MAAA;MAGfH,EAAAL,CAAA,EAAM,gBAArBI,EAGQ,SAAA;AAAA;QAHuB,SAAOC,EAAAH,CAAA,EAAO,6BAAA,CAAA;AAAA,MAAA;QAE3CK,EAA4BC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PageHeader.js","sources":["../src/components/PageHeader/PageHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule, useSlots } from 'vue';\n\n export interface PageHeaderProps {\n /**\n * The title of the page.\n */\n title?: string;\n /**\n * The description of the page.\n */\n description?: string;\n }\n\n defineOptions({\n name: 'll-page-header',\n });\n\n const props = withDefaults(defineProps<PageHeaderProps>(), {\n title: undefined,\n description: undefined,\n });\n\n const classes = useCssModule();\n const slots = useSlots();\n\n const hasActions = computed<boolean>(() => !!(slots['primary-action'] || slots['secondary-action']));\n</script>\n\n<template>\n <header\n class=\"stash-page-header\"\n :class=\"[classes.root, { [classes.grid]: hasActions }]\"\n data-test=\"stash-page-header\"\n >\n <div class=\"col-span-full flex items-center lg:col-span-1\">\n <div v-if=\"slots.media\" class=\"stash-page-header__media mr-3 self-center\" :class=\"classes.mediaTest\">\n <!-- @slot Receives a custom media -->\n <slot name=\"media\"></slot>\n </div>\n\n <div>\n <!-- @slot Receives a custom title -->\n <slot name=\"title\">\n <h1 v-if=\"props.title\" class=\"stash-page-header__title my-0\">{{ props.title }}</h1>\n </slot>\n\n <!-- @slot Receives a custom description -->\n <slot name=\"description\">\n <p v-if=\"props.description\" class=\"stash-page-header__description mb-0 mt-1.5\">\n {{ props.description }}\n </p>\n </slot>\n </div>\n </div>\n\n <div v-if=\"hasActions\" class=\"stash-page-header__actions col-span-full flex lg:col-span-1\" :class=\"classes.actions\">\n <!-- @slot Receives a custom secondary action -->\n <slot name=\"secondary-action\"> </slot>\n <!-- @slot Receives a custom primary action -->\n <slot name=\"primary-action\"> </slot>\n </div>\n </header>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .root {\n border-bottom: 0;\n display: grid;\n gap: var(--grid-gutter);\n margin: 0 auto;\n max-width: var(--width-container);\n padding: --spacing(6) var(--grid-gutter) --spacing(12);\n width: 100%;\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .root.grid {\n grid-template-columns: repeat(2, 1fr);\n }\n }\n\n .actions {\n align-self: flex-end;\n flex-direction: column-reverse;\n row-gap: var(--grid-gutter);\n }\n\n @media (width >= theme(--breakpoint-md)) {\n .actions {\n column-gap: var(--grid-gutter);\n flex-direction: row;\n row-gap: 0;\n }\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .actions {\n align-items: flex-end;\n flex-direction: row;\n justify-content: flex-end;\n }\n }\n\n /* max size for media/marketing illustration icons we would be passing to the slot */\n .media-test {\n max-width: 58px;\n max-height: 58px;\n }\n }\n</style>\n"],"names":["props","__props","classes","useCssModule","slots","useSlots","hasActions","computed"],"mappings":";;;;;;;;;;;;;;;;AAkBE,UAAMA,IAAQC,GAKRC,IAAUC,EAAA,GACVC,IAAQC,EAAA,GAERC,IAAaC,EAAkB,MAAM,CAAC,EAAEH,EAAM,gBAAgB,KAAKA,EAAM,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"PageHeader.js","sources":["../src/components/PageHeader/PageHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule, useSlots } from 'vue';\n\n export interface PageHeaderProps {\n /**\n * The title of the page.\n */\n title?: string;\n /**\n * The description of the page.\n */\n description?: string;\n }\n\n defineOptions({\n name: 'll-page-header',\n });\n\n const props = withDefaults(defineProps<PageHeaderProps>(), {\n title: undefined,\n description: undefined,\n });\n\n const classes = useCssModule();\n const slots = useSlots();\n\n const hasActions = computed<boolean>(() => !!(slots['primary-action'] || slots['secondary-action']));\n</script>\n\n<template>\n <header\n class=\"stash-page-header\"\n :class=\"[classes.root, { [classes.grid]: hasActions }]\"\n data-test=\"stash-page-header\"\n >\n <div class=\"col-span-full flex items-center lg:col-span-1\">\n <div v-if=\"slots.media\" class=\"stash-page-header__media mr-3 self-center\" :class=\"classes.mediaTest\">\n <!-- @slot Receives a custom media -->\n <slot name=\"media\"></slot>\n </div>\n\n <div>\n <!-- @slot Receives a custom title -->\n <slot name=\"title\">\n <h1 v-if=\"props.title\" class=\"stash-page-header__title my-0\">{{ props.title }}</h1>\n </slot>\n\n <!-- @slot Receives a custom description -->\n <slot name=\"description\">\n <p v-if=\"props.description\" class=\"stash-page-header__description mb-0 mt-1.5\">\n {{ props.description }}\n </p>\n </slot>\n </div>\n </div>\n\n <div v-if=\"hasActions\" class=\"stash-page-header__actions col-span-full flex lg:col-span-1\" :class=\"classes.actions\">\n <!-- @slot Receives a custom secondary action -->\n <slot name=\"secondary-action\"> </slot>\n <!-- @slot Receives a custom primary action -->\n <slot name=\"primary-action\"> </slot>\n </div>\n </header>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .root {\n border-bottom: 0;\n display: grid;\n gap: var(--grid-gutter);\n margin: 0 auto;\n max-width: var(--width-container);\n padding: --spacing(6) var(--grid-gutter) --spacing(12);\n width: 100%;\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .root.grid {\n grid-template-columns: repeat(2, 1fr);\n }\n }\n\n .actions {\n align-self: flex-end;\n flex-direction: column-reverse;\n row-gap: var(--grid-gutter);\n }\n\n @media (width >= theme(--breakpoint-md)) {\n .actions {\n column-gap: var(--grid-gutter);\n flex-direction: row;\n row-gap: 0;\n }\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .actions {\n align-items: flex-end;\n flex-direction: row;\n justify-content: flex-end;\n }\n }\n\n /* max size for media/marketing illustration icons we would be passing to the slot */\n .media-test {\n max-width: 58px;\n max-height: 58px;\n }\n }\n</style>\n"],"names":["props","__props","classes","useCssModule","slots","useSlots","hasActions","computed","_createElementBlock","_normalizeClass","_unref","_createElementVNode","_hoisted_1","_renderSlot","_ctx","_openBlock","_hoisted_2","_toDisplayString","_hoisted_3"],"mappings":";;;;;;;;;;;;;;;;AAkBE,UAAMA,IAAQC,GAKRC,IAAUC,EAAA,GACVC,IAAQC,EAAA,GAERC,IAAaC,EAAkB,MAAM,CAAC,EAAEH,EAAM,gBAAgB,KAAKA,EAAM,kBAAkB,EAAE;2BAInGI,EAgCS,UAAA;AAAA,MA/BP,OAAKC,EAAA,CAAC,qBAAmB,CAChBC,EAAAR,CAAA,EAAQ,MAAI,EAAA,CAAKQ,EAAAR,CAAA,EAAQ,IAAI,GAAGI,EAAA,MAAA,CAAU,CAAA,CAAA;AAAA,MACnD,aAAU;AAAA,IAAA;MAEVK,EAmBM,OAnBNC,GAmBM;AAAA,QAlBOF,EAAAN,CAAA,EAAM,cAAjBI,EAGM,OAAA;AAAA;UAHkB,OAAKC,EAAA,CAAC,6CAAoDC,EAAAR,CAAA,EAAQ,SAAS,CAAA;AAAA,QAAA;UAEjGW,EAA0BC,EAAA,QAAA,OAAA;AAAA,QAAA;QAG5BH,EAYM,OAAA,MAAA;AAAA,UAVJE,EAEOC,uBAFP,MAEO;AAAA,YADKd,EAAM,SAAhBe,EAAA,GAAAP,EAAmF,MAAnFQ,GAAmFC,EAAnBjB,EAAM,KAAK,GAAA,CAAA;;UAI7Ea,EAIOC,6BAJP,MAIO;AAAA,YAHId,EAAM,eAAfe,EAAA,GAAAP,EAEI,KAFJU,GAEID,EADCjB,EAAM,WAAW,GAAA,CAAA;;;;MAMjBM,EAAA,cAAXE,EAKM,OAAA;AAAA;QALiB,OAAKC,EAAA,CAAC,+DAAsEC,EAAAR,CAAA,EAAQ,OAAO,CAAA;AAAA,MAAA;QAEhHW,EAAsCC,EAAA,QAAA,kBAAA;AAAA,QAEtCD,EAAoCC,EAAA,QAAA,gBAAA;AAAA,MAAA;;;;;;;;;;;"}
@@ -6,7 +6,7 @@ import D from "./Badge.js";
6
6
  import E from "./Menu.js";
7
7
  import F from "./MenuItem.js";
8
8
  import L from "./Tab.js";
9
- import { _ as O } from "./Tabs.vue_vue_type_script_setup_true_lang-BFURXY_-.js";
9
+ import { _ as O } from "./Tabs.vue_vue_type_script_setup_true_lang-B3FBaVP5.js";
10
10
  const R = {
11
11
  class: "stash-page-navigation container",
12
12
  "data-test": "stash-page-navigation"
@@ -1 +1 @@
1
- {"version":3,"file":"PageNavigation.js","sources":["../src/components/PageNavigation/PageNavigation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import logger from '@leaflink/snitch';\n import kebabCase from 'lodash-es/kebabCase';\n import { onMounted, ref, watch } from 'vue';\n import { RouteLocationRaw, useRoute, useRouter } from 'vue-router';\n\n import Badge from '../Badge/Badge.vue';\n import Menu from '../Menu/Menu.vue';\n import MenuItem from '../MenuItem/MenuItem.vue';\n import Tab, { type TabProps } from '../Tab/Tab.vue';\n import Tabs from '../Tabs/Tabs.vue';\n\n defineOptions({\n name: 'll-page-navigation',\n });\n\n export interface NavItem extends Omit<TabProps, 'value'> {\n /**\n * The tab's label\n */\n label: string;\n\n /**\n * The tab's label\n */\n value?: string;\n }\n\n export interface PageNavigationProps {\n /**\n * Index of active tab (zero-based)\n * @deprecated Use v-model instead.\n */\n activeIndex?: number | string;\n\n /**\n * The currently active tab value\n */\n modelValue?: string;\n\n /**\n * Array of tabs. A `tab` is an object containing a `label` and either an `href` | `to`\n */\n items: NavItem[];\n }\n\n const props = withDefaults(defineProps<PageNavigationProps>(), {\n activeIndex: undefined,\n modelValue: '',\n });\n\n const emit = defineEmits<{\n /**\n * Emits the current active nav value\n */\n (e: 'update:modelValue', activeTab: string): void;\n\n /**\n * Emits the current active nav index\n * @deprecated - Use v-model instead.\n */\n (e: 'change', activeNavIndex: number): void;\n }>();\n\n if (props.activeIndex) {\n logger.info('The `activeIndex` prop is deprecated. Use `v-model` instead.');\n }\n\n const route = useRoute();\n const router = useRouter();\n\n // this ref is needed to keep track of the active tab even if v-model is not passed\n const activeTab = ref('');\n\n function onUpdateActiveTab(newActiveTab: string) {\n if (newActiveTab === activeTab.value) return;\n\n activeTab.value = newActiveTab;\n emit('update:modelValue', newActiveTab);\n }\n\n watch(\n () => props.modelValue,\n (newValue, oldValue) => {\n if (oldValue === newValue) return;\n\n // TODO: Remove this once activeIndex is removed\n const activeNavItemIndex = props.items.findIndex((item) => kebabCase(item.label) === newValue);\n emit('change', activeNavItemIndex);\n\n // Forcing updating activeTab when the component is in a keep alive state\n onUpdateActiveTab(newValue);\n },\n );\n\n onMounted(() => {\n if (!props.items.length) return;\n\n // TODO: Remove this once activeIndex is removed\n if (props.activeIndex !== undefined) {\n const activeTabItem = props.items[props.activeIndex];\n\n onUpdateActiveTab(kebabCase(activeTabItem.label));\n\n return;\n }\n\n if (props.modelValue !== activeTab.value) {\n onUpdateActiveTab(props.modelValue);\n return;\n }\n\n if (!router) return;\n\n const itemMatchingRoute = props.items.find((item) => {\n if (item?.disabled || (!item?.to && !item?.href)) return;\n\n const { path } = router.resolve((item?.to as RouteLocationRaw) || (item?.href as string));\n\n if (path === route.path) {\n return true;\n }\n\n if (!route.path.includes(path)) return;\n\n const sliceIndex = (route.path.length - route.path.lastIndexOf('/')) * -1;\n const parentPath = route.path.slice(0, sliceIndex);\n\n return path === parentPath;\n });\n\n if (!itemMatchingRoute) return;\n\n onUpdateActiveTab(itemMatchingRoute?.value || kebabCase(itemMatchingRoute.label));\n });\n</script>\n\n<template>\n <nav class=\"stash-page-navigation container\" data-test=\"stash-page-navigation\">\n <Tabs :active-tab=\"activeTab\" @update:active-tab=\"onUpdateActiveTab\">\n <Tab\n v-for=\"(item, index) in props.items\"\n :key=\"item.label\"\n :value=\"item?.value || kebabCase(item.label)\"\n :to=\"item.to\"\n :href=\"item.href\"\n :badge=\"item.badge\"\n :disabled=\"item.disabled\"\n :data-id=\"index\"\n :data-action-id=\"item?.value || kebabCase(item.label)\"\n >\n {{ item.label }}\n </Tab>\n\n <template #more-actions>\n <Menu>\n <MenuItem\n v-for=\"item in props.items\"\n :key=\"item.label\"\n :data-action-id=\"item?.value || kebabCase(item.label)\"\n :is-disabled=\"item.disabled\"\n >\n <Badge v-if=\"item.badge\" :content=\"item.badge\" position=\"inline\" color=\"red\">\n {{ item.label }}\n </Badge>\n <template v-else>\n {{ item.label }}\n </template>\n </MenuItem>\n </Menu>\n </template>\n </Tabs>\n </nav>\n</template>\n"],"names":["props","__props","emit","__emit","logger","route","useRoute","router","useRouter","activeTab","ref","onUpdateActiveTab","newActiveTab","watch","newValue","oldValue","activeNavItemIndex","item","kebabCase","onMounted","activeTabItem","itemMatchingRoute","path","sliceIndex","parentPath"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8CE,UAAMA,IAAQC,GAKRC,IAAOC;AAab,IAAIH,EAAM,eACRI,EAAO,KAAK,8DAA8D;AAG5E,UAAMC,IAAQC,EAAA,GACRC,IAASC,EAAA,GAGTC,IAAYC,EAAI,EAAE;AAExB,aAASC,EAAkBC,GAAsB;AAC/C,MAAIA,MAAiBH,EAAU,UAE/BA,EAAU,QAAQG,GAClBV,EAAK,qBAAqBU,CAAY;AAAA,IACxC;AAEA,WAAAC;AAAA,MACE,MAAMb,EAAM;AAAA,MACZ,CAACc,GAAUC,MAAa;AACtB,YAAIA,MAAaD,EAAU;AAG3B,cAAME,IAAqBhB,EAAM,MAAM,UAAU,CAACiB,MAASC,EAAUD,EAAK,KAAK,MAAMH,CAAQ;AAC7F,QAAAZ,EAAK,UAAUc,CAAkB,GAGjCL,EAAkBG,CAAQ;AAAA,MAC5B;AAAA,IAAA,GAGFK,EAAU,MAAM;AACd,UAAI,CAACnB,EAAM,MAAM,OAAQ;AAGzB,UAAIA,EAAM,gBAAgB,QAAW;AACnC,cAAMoB,IAAgBpB,EAAM,MAAMA,EAAM,WAAW;AAEnD,QAAAW,EAAkBO,EAAUE,EAAc,KAAK,CAAC;AAEhD;AAAA,MACF;AAEA,UAAIpB,EAAM,eAAeS,EAAU,OAAO;AACxC,QAAAE,EAAkBX,EAAM,UAAU;AAClC;AAAA,MACF;AAEA,UAAI,CAACO,EAAQ;AAEb,YAAMc,IAAoBrB,EAAM,MAAM,KAAK,CAACiB,MAAS;AACnD,YAAIA,KAAA,QAAAA,EAAM,YAAa,EAACA,KAAA,QAAAA,EAAM,OAAM,EAACA,KAAA,QAAAA,EAAM,MAAO;AAElD,cAAM,EAAE,MAAAK,MAASf,EAAO,SAASU,KAAA,gBAAAA,EAAM,QAA4BA,KAAA,gBAAAA,EAAM,KAAe;AAExF,YAAIK,MAASjB,EAAM;AACjB,iBAAO;AAGT,YAAI,CAACA,EAAM,KAAK,SAASiB,CAAI,EAAG;AAEhC,cAAMC,KAAclB,EAAM,KAAK,SAASA,EAAM,KAAK,YAAY,GAAG,KAAK,IACjEmB,IAAanB,EAAM,KAAK,MAAM,GAAGkB,CAAU;AAEjD,eAAOD,MAASE;AAAA,MAClB,CAAC;AAED,MAAKH,KAELV,GAAkBU,KAAA,gBAAAA,EAAmB,UAASH,EAAUG,EAAkB,KAAK,CAAC;AAAA,IAClF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"PageNavigation.js","sources":["../src/components/PageNavigation/PageNavigation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import logger from '@leaflink/snitch';\n import kebabCase from 'lodash-es/kebabCase';\n import { onMounted, ref, watch } from 'vue';\n import { RouteLocationRaw, useRoute, useRouter } from 'vue-router';\n\n import Badge from '../Badge/Badge.vue';\n import Menu from '../Menu/Menu.vue';\n import MenuItem from '../MenuItem/MenuItem.vue';\n import Tab, { type TabProps } from '../Tab/Tab.vue';\n import Tabs from '../Tabs/Tabs.vue';\n\n defineOptions({\n name: 'll-page-navigation',\n });\n\n export interface NavItem extends Omit<TabProps, 'value'> {\n /**\n * The tab's label\n */\n label: string;\n\n /**\n * The tab's label\n */\n value?: string;\n }\n\n export interface PageNavigationProps {\n /**\n * Index of active tab (zero-based)\n * @deprecated Use v-model instead.\n */\n activeIndex?: number | string;\n\n /**\n * The currently active tab value\n */\n modelValue?: string;\n\n /**\n * Array of tabs. A `tab` is an object containing a `label` and either an `href` | `to`\n */\n items: NavItem[];\n }\n\n const props = withDefaults(defineProps<PageNavigationProps>(), {\n activeIndex: undefined,\n modelValue: '',\n });\n\n const emit = defineEmits<{\n /**\n * Emits the current active nav value\n */\n (e: 'update:modelValue', activeTab: string): void;\n\n /**\n * Emits the current active nav index\n * @deprecated - Use v-model instead.\n */\n (e: 'change', activeNavIndex: number): void;\n }>();\n\n if (props.activeIndex) {\n logger.info('The `activeIndex` prop is deprecated. Use `v-model` instead.');\n }\n\n const route = useRoute();\n const router = useRouter();\n\n // this ref is needed to keep track of the active tab even if v-model is not passed\n const activeTab = ref('');\n\n function onUpdateActiveTab(newActiveTab: string) {\n if (newActiveTab === activeTab.value) return;\n\n activeTab.value = newActiveTab;\n emit('update:modelValue', newActiveTab);\n }\n\n watch(\n () => props.modelValue,\n (newValue, oldValue) => {\n if (oldValue === newValue) return;\n\n // TODO: Remove this once activeIndex is removed\n const activeNavItemIndex = props.items.findIndex((item) => kebabCase(item.label) === newValue);\n emit('change', activeNavItemIndex);\n\n // Forcing updating activeTab when the component is in a keep alive state\n onUpdateActiveTab(newValue);\n },\n );\n\n onMounted(() => {\n if (!props.items.length) return;\n\n // TODO: Remove this once activeIndex is removed\n if (props.activeIndex !== undefined) {\n const activeTabItem = props.items[props.activeIndex];\n\n onUpdateActiveTab(kebabCase(activeTabItem.label));\n\n return;\n }\n\n if (props.modelValue !== activeTab.value) {\n onUpdateActiveTab(props.modelValue);\n return;\n }\n\n if (!router) return;\n\n const itemMatchingRoute = props.items.find((item) => {\n if (item?.disabled || (!item?.to && !item?.href)) return;\n\n const { path } = router.resolve((item?.to as RouteLocationRaw) || (item?.href as string));\n\n if (path === route.path) {\n return true;\n }\n\n if (!route.path.includes(path)) return;\n\n const sliceIndex = (route.path.length - route.path.lastIndexOf('/')) * -1;\n const parentPath = route.path.slice(0, sliceIndex);\n\n return path === parentPath;\n });\n\n if (!itemMatchingRoute) return;\n\n onUpdateActiveTab(itemMatchingRoute?.value || kebabCase(itemMatchingRoute.label));\n });\n</script>\n\n<template>\n <nav class=\"stash-page-navigation container\" data-test=\"stash-page-navigation\">\n <Tabs :active-tab=\"activeTab\" @update:active-tab=\"onUpdateActiveTab\">\n <Tab\n v-for=\"(item, index) in props.items\"\n :key=\"item.label\"\n :value=\"item?.value || kebabCase(item.label)\"\n :to=\"item.to\"\n :href=\"item.href\"\n :badge=\"item.badge\"\n :disabled=\"item.disabled\"\n :data-id=\"index\"\n :data-action-id=\"item?.value || kebabCase(item.label)\"\n >\n {{ item.label }}\n </Tab>\n\n <template #more-actions>\n <Menu>\n <MenuItem\n v-for=\"item in props.items\"\n :key=\"item.label\"\n :data-action-id=\"item?.value || kebabCase(item.label)\"\n :is-disabled=\"item.disabled\"\n >\n <Badge v-if=\"item.badge\" :content=\"item.badge\" position=\"inline\" color=\"red\">\n {{ item.label }}\n </Badge>\n <template v-else>\n {{ item.label }}\n </template>\n </MenuItem>\n </Menu>\n </template>\n </Tabs>\n </nav>\n</template>\n"],"names":["props","__props","emit","__emit","logger","route","useRoute","router","useRouter","activeTab","ref","onUpdateActiveTab","newActiveTab","watch","newValue","oldValue","activeNavItemIndex","item","kebabCase","onMounted","activeTabItem","itemMatchingRoute","path","sliceIndex","parentPath","_openBlock","_createElementBlock","_hoisted_1","_createVNode","Tabs","Menu","_Fragment","_renderList","_createBlock","MenuItem","_unref","Badge","_createTextVNode","_toDisplayString","index","Tab"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8CE,UAAMA,IAAQC,GAKRC,IAAOC;AAab,IAAIH,EAAM,eACRI,EAAO,KAAK,8DAA8D;AAG5E,UAAMC,IAAQC,EAAA,GACRC,IAASC,EAAA,GAGTC,IAAYC,EAAI,EAAE;AAExB,aAASC,EAAkBC,GAAsB;AAC/C,MAAIA,MAAiBH,EAAU,UAE/BA,EAAU,QAAQG,GAClBV,EAAK,qBAAqBU,CAAY;AAAA,IACxC;AAEA,WAAAC;AAAA,MACE,MAAMb,EAAM;AAAA,MACZ,CAACc,GAAUC,MAAa;AACtB,YAAIA,MAAaD,EAAU;AAG3B,cAAME,IAAqBhB,EAAM,MAAM,UAAU,CAACiB,MAASC,EAAUD,EAAK,KAAK,MAAMH,CAAQ;AAC7F,QAAAZ,EAAK,UAAUc,CAAkB,GAGjCL,EAAkBG,CAAQ;AAAA,MAC5B;AAAA,IAAA,GAGFK,EAAU,MAAM;AACd,UAAI,CAACnB,EAAM,MAAM,OAAQ;AAGzB,UAAIA,EAAM,gBAAgB,QAAW;AACnC,cAAMoB,IAAgBpB,EAAM,MAAMA,EAAM,WAAW;AAEnD,QAAAW,EAAkBO,EAAUE,EAAc,KAAK,CAAC;AAEhD;AAAA,MACF;AAEA,UAAIpB,EAAM,eAAeS,EAAU,OAAO;AACxC,QAAAE,EAAkBX,EAAM,UAAU;AAClC;AAAA,MACF;AAEA,UAAI,CAACO,EAAQ;AAEb,YAAMc,IAAoBrB,EAAM,MAAM,KAAK,CAACiB,MAAS;AACnD,YAAIA,KAAA,QAAAA,EAAM,YAAa,EAACA,KAAA,QAAAA,EAAM,OAAM,EAACA,KAAA,QAAAA,EAAM,MAAO;AAElD,cAAM,EAAE,MAAAK,MAASf,EAAO,SAASU,KAAA,gBAAAA,EAAM,QAA4BA,KAAA,gBAAAA,EAAM,KAAe;AAExF,YAAIK,MAASjB,EAAM;AACjB,iBAAO;AAGT,YAAI,CAACA,EAAM,KAAK,SAASiB,CAAI,EAAG;AAEhC,cAAMC,KAAclB,EAAM,KAAK,SAASA,EAAM,KAAK,YAAY,GAAG,KAAK,IACjEmB,IAAanB,EAAM,KAAK,MAAM,GAAGkB,CAAU;AAEjD,eAAOD,MAASE;AAAA,MAClB,CAAC;AAED,MAAKH,KAELV,GAAkBU,KAAA,gBAAAA,EAAmB,UAASH,EAAUG,EAAkB,KAAK,CAAC;AAAA,IAClF,CAAC,cAIDI,EAAA,GAAAC,EAkCM,OAlCNC,GAkCM;AAAA,MAjCJC,EAgCOC,GAAA;AAAA,QAhCA,cAAYpB,EAAA;AAAA,QAAY,sBAAmBE;AAAA,MAAA;QAerC,kBACT,MAcO;AAAA,UAdPiB,EAcOE,GAAA,MAAA;AAAA,uBAZH,MAA2B;AAAA,eAD7BL,EAAA,EAAA,GAAAC,EAYWK,GAAA,MAAAC,EAXMhC,EAAM,QAAdiB,YADTgB,EAYWC,GAAA;AAAA,gBAVR,KAAKjB,EAAK;AAAA,gBACV,mBAAgBA,KAAA,gBAAAA,EAAM,UAASkB,EAAAjB,CAAA,EAAUD,EAAK,KAAK;AAAA,gBACnD,eAAaA,EAAK;AAAA,cAAA;2BAEnB,MAEQ;AAAA,kBAFKA,EAAK,cAAlBgB,EAEQG,GAAA;AAAA;oBAFkB,SAASnB,EAAK;AAAA,oBAAO,UAAS;AAAA,oBAAS,OAAM;AAAA,kBAAA;+BACrE,MAAgB;AAAA,sBAAboB,EAAAC,EAAArB,EAAK,KAAK,GAAA,CAAA;AAAA,oBAAA;;iDAEfS,EAEWK,GAAA,EAAA,KAAA,KAAA;AAAA,oBADNM,EAAAC,EAAArB,EAAK,KAAK,GAAA,CAAA;AAAA,kBAAA;;;;;;;;mBAzBnB,MAAoC;AAAA,WADtCQ,EAAA,EAAA,GAAAC,EAYMK,WAXoB/B,EAAM,OAAK,CAA3BiB,GAAMsB,YADhBN,EAYMO,GAAA;AAAA,YAVH,KAAKvB,EAAK;AAAA,YACV,QAAOA,KAAA,gBAAAA,EAAM,UAASkB,EAAAjB,CAAA,EAAUD,EAAK,KAAK;AAAA,YAC1C,IAAIA,EAAK;AAAA,YACT,MAAMA,EAAK;AAAA,YACX,OAAOA,EAAK;AAAA,YACZ,UAAUA,EAAK;AAAA,YACf,WAASsB;AAAA,YACT,mBAAgBtB,KAAA,gBAAAA,EAAM,UAASkB,EAAAjB,CAAA,EAAUD,EAAK,KAAK;AAAA,UAAA;uBAEpD,MAAgB;AAAA,cAAboB,EAAAC,EAAArB,EAAK,KAAK,GAAA,CAAA;AAAA,YAAA;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Paginate.js","sources":["../src/components/Paginate/Paginate.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, toRef, useCssModule } from 'vue';\n\n import usePaginationStats from '../../composables/usePaginationStats/usePaginationStats';\n import { t } from '../../locale';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({\n name: 'll-paginate',\n });\n\n export interface PaginateProps {\n /**\n * Current page number\n */\n currentPage?: number;\n /**\n * Total number of items in list\n */\n listLength?: number;\n /**\n * Number of items per page\n */\n pageSize?: number;\n /*\n * Optional override for the next button disabled state\n */\n isNextDisabled?: boolean;\n /**\n * Variant of the pagination component\n */\n variant?: 'standard' | 'stats';\n }\n\n const props = withDefaults(defineProps<PaginateProps>(), {\n currentPage: 1,\n listLength: 1,\n pageSize: 50,\n isNextDisabled: false,\n variant: 'standard',\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the page number changes.\n */\n (e: 'set-page', pageNumber: number): void;\n }>();\n\n const classes = useCssModule();\n\n const pageCount = computed(() => Math.ceil(props.listLength / props.pageSize));\n\n const pageStats =\n props.variant === 'stats'\n ? usePaginationStats({\n currentPage: toRef(() => props.currentPage),\n pageSize: toRef(() => props.pageSize),\n totalItems: toRef(() => props.listLength),\n })\n : null;\n\n /**\n * Emits current page to list view.\n */\n function updatePage(currentPage: number) {\n emit('set-page', currentPage);\n }\n\n /**\n * Sets current page to next page\n */\n function next() {\n if (props.currentPage < pageCount.value) {\n updatePage(props.currentPage + 1);\n }\n }\n\n /**\n * Sets current page to previous page\n */\n function prev() {\n if (props.currentPage > 1) {\n updatePage(props.currentPage - 1);\n }\n }\n\n /**\n * Determines whether to show page\n * @returns {boolean} - should show page in pagination component\n */\n function shouldShowPage(page: number): boolean {\n const pageDiff = Math.abs(props.currentPage - page);\n\n if (\n pageCount.value < 10 ||\n page === 1 ||\n page === pageCount.value ||\n (props.currentPage < 6 && page < 8) ||\n (pageCount.value - props.currentPage < 5 && pageCount.value - page < 7) ||\n pageDiff < 3\n ) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Determines whether to show the leading ellipsis\n * @returns {boolean} should show or not\n */\n function shouldShowFirstEllipsis(page: number): boolean {\n return pageCount.value > 9 && props.currentPage > 5 && page === 2;\n }\n\n /**\n * Determines whether to show the trailing ellipsis\n * @returns {boolean} should show or not\n */\n function shouldShowLastEllipsis(page: number): boolean {\n return pageCount.value > 9 && pageCount.value - props.currentPage > 4 && page === pageCount.value - 1;\n }\n</script>\n\n<template>\n <div class=\"stash-paginate flex justify-center\" data-test=\"stash-paginate\">\n <ul class=\"stash-paginate__list flex items-center\" :class=\"classes.pagination\" data-test=\"stash-paginate|list\">\n <button\n :aria-label=\"t('ll.previous')\"\n data-test=\"stash-paginate|prev-page\"\n :class=\"classes.prev\"\n :disabled=\"props.currentPage === 1\"\n @click=\"prev\"\n >\n <Icon size=\"small\" name=\"chevron-left\" />\n </button>\n <span v-if=\"props.variant === 'stats'\" class=\"mx-3 text-ice-900\">\n {{ t('ll.pageStats', pageStats) }}\n </span>\n <template v-for=\"page in pageCount\" v-else>\n <button\n v-if=\"shouldShowFirstEllipsis(page)\"\n :key=\"`${page}-ellipsis`\"\n class=\"pointer-events-none\"\n data-test=\"stash-paginate|first-ellipsis\"\n tabindex=\"-1\"\n >\n &#x2026;\n </button>\n <button\n v-if=\"shouldShowPage(page)\"\n :key=\"page\"\n data-test=\"stash-paginate|page-number\"\n :class=\"{ [classes['is-active']]: props.currentPage === page }\"\n @click=\"updatePage(page)\"\n >\n {{ page }}\n </button>\n <button\n v-if=\"shouldShowLastEllipsis(page)\"\n :key=\"`${page}-ellipsis`\"\n class=\"pointer-events-none\"\n data-test=\"stash-paginate|last-ellipsis\"\n tabindex=\"-1\"\n >\n &#x2026;\n </button>\n </template>\n <button\n :aria-label=\"t('ll.next')\"\n data-test=\"stash-paginate|next-page\"\n :class=\"classes.next\"\n :disabled=\"props.isNextDisabled || props.currentPage === pageCount\"\n @click=\"next\"\n >\n <Icon size=\"small\" class=\"rotate-180\" name=\"chevron-left\" />\n </button>\n </ul>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .pagination {\n /* Todo: We shouldn't really be making assumptions about the outer spacing of the pagination component */\n margin-top: --spacing(12);\n z-index: 0;\n\n a,\n button {\n @apply border border-solid border-ice-200;\n align-items: center;\n background-color: var(--color-white);\n color: var(--color-blue-500);\n cursor: pointer;\n display: flex;\n height: var(--height-input);\n justify-content: center;\n margin: 0 0 0 -1px;\n width: var(--height-input);\n\n &.prev {\n border-bottom-left-radius: var(--radius-sm);\n border-top-left-radius: var(--radius-sm);\n }\n\n &.next {\n border-bottom-right-radius: var(--radius-sm);\n border-top-right-radius: var(--radius-sm);\n }\n\n &:focus {\n outline: none;\n }\n\n &:hover {\n text-decoration: none;\n }\n\n &.is-active {\n background-color: var(--color-blue-500);\n color: var(--color-white);\n pointer-events: none;\n z-index: var(--z-index-control);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n &:not(:disabled):hover,\n &:not(:disabled):focus,\n &.is-active {\n @apply border border-solid border-blue-500;\n position: relative;\n }\n\n &.is-active:focus {\n @apply bg-blue-700 border-blue-700;\n }\n }\n }\n }\n</style>\n"],"names":["props","__props","emit","__emit","classes","useCssModule","pageCount","computed","pageStats","usePaginationStats","toRef","updatePage","currentPage","next","prev","shouldShowPage","page","pageDiff","shouldShowFirstEllipsis","shouldShowLastEllipsis"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAkCE,UAAMA,IAAQC,GAQRC,IAAOC,GAOPC,IAAUC,EAAA,GAEVC,IAAYC,EAAS,MAAM,KAAK,KAAKP,EAAM,aAAaA,EAAM,QAAQ,CAAC,GAEvEQ,IACJR,EAAM,YAAY,UACdS,EAAmB;AAAA,MACjB,aAAaC,EAAM,MAAMV,EAAM,WAAW;AAAA,MAC1C,UAAUU,EAAM,MAAMV,EAAM,QAAQ;AAAA,MACpC,YAAYU,EAAM,MAAMV,EAAM,UAAU;AAAA,IAAA,CACzC,IACD;AAKN,aAASW,EAAWC,GAAqB;AACvC,MAAAV,EAAK,YAAYU,CAAW;AAAA,IAC9B;AAKA,aAASC,IAAO;AACd,MAAIb,EAAM,cAAcM,EAAU,SAChCK,EAAWX,EAAM,cAAc,CAAC;AAAA,IAEpC;AAKA,aAASc,IAAO;AACd,MAAId,EAAM,cAAc,KACtBW,EAAWX,EAAM,cAAc,CAAC;AAAA,IAEpC;AAMA,aAASe,EAAeC,GAAuB;AAC7C,YAAMC,IAAW,KAAK,IAAIjB,EAAM,cAAcgB,CAAI;AAElD,aACEV,EAAU,QAAQ,MAClBU,MAAS,KACTA,MAASV,EAAU,SAClBN,EAAM,cAAc,KAAKgB,IAAO,KAChCV,EAAU,QAAQN,EAAM,cAAc,KAAKM,EAAU,QAAQU,IAAO,KACrEC,IAAW;AAAA,IAMf;AAMA,aAASC,EAAwBF,GAAuB;AACtD,aAAOV,EAAU,QAAQ,KAAKN,EAAM,cAAc,KAAKgB,MAAS;AAAA,IAClE;AAMA,aAASG,EAAuBH,GAAuB;AACrD,aAAOV,EAAU,QAAQ,KAAKA,EAAU,QAAQN,EAAM,cAAc,KAAKgB,MAASV,EAAU,QAAQ;AAAA,IACtG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Paginate.js","sources":["../src/components/Paginate/Paginate.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, toRef, useCssModule } from 'vue';\n\n import usePaginationStats from '../../composables/usePaginationStats/usePaginationStats';\n import { t } from '../../locale';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({\n name: 'll-paginate',\n });\n\n export interface PaginateProps {\n /**\n * Current page number\n */\n currentPage?: number;\n /**\n * Total number of items in list\n */\n listLength?: number;\n /**\n * Number of items per page\n */\n pageSize?: number;\n /*\n * Optional override for the next button disabled state\n */\n isNextDisabled?: boolean;\n /**\n * Variant of the pagination component\n */\n variant?: 'standard' | 'stats';\n }\n\n const props = withDefaults(defineProps<PaginateProps>(), {\n currentPage: 1,\n listLength: 1,\n pageSize: 50,\n isNextDisabled: false,\n variant: 'standard',\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the page number changes.\n */\n (e: 'set-page', pageNumber: number): void;\n }>();\n\n const classes = useCssModule();\n\n const pageCount = computed(() => Math.ceil(props.listLength / props.pageSize));\n\n const pageStats =\n props.variant === 'stats'\n ? usePaginationStats({\n currentPage: toRef(() => props.currentPage),\n pageSize: toRef(() => props.pageSize),\n totalItems: toRef(() => props.listLength),\n })\n : null;\n\n /**\n * Emits current page to list view.\n */\n function updatePage(currentPage: number) {\n emit('set-page', currentPage);\n }\n\n /**\n * Sets current page to next page\n */\n function next() {\n if (props.currentPage < pageCount.value) {\n updatePage(props.currentPage + 1);\n }\n }\n\n /**\n * Sets current page to previous page\n */\n function prev() {\n if (props.currentPage > 1) {\n updatePage(props.currentPage - 1);\n }\n }\n\n /**\n * Determines whether to show page\n * @returns {boolean} - should show page in pagination component\n */\n function shouldShowPage(page: number): boolean {\n const pageDiff = Math.abs(props.currentPage - page);\n\n if (\n pageCount.value < 10 ||\n page === 1 ||\n page === pageCount.value ||\n (props.currentPage < 6 && page < 8) ||\n (pageCount.value - props.currentPage < 5 && pageCount.value - page < 7) ||\n pageDiff < 3\n ) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Determines whether to show the leading ellipsis\n * @returns {boolean} should show or not\n */\n function shouldShowFirstEllipsis(page: number): boolean {\n return pageCount.value > 9 && props.currentPage > 5 && page === 2;\n }\n\n /**\n * Determines whether to show the trailing ellipsis\n * @returns {boolean} should show or not\n */\n function shouldShowLastEllipsis(page: number): boolean {\n return pageCount.value > 9 && pageCount.value - props.currentPage > 4 && page === pageCount.value - 1;\n }\n</script>\n\n<template>\n <div class=\"stash-paginate flex justify-center\" data-test=\"stash-paginate\">\n <ul class=\"stash-paginate__list flex items-center\" :class=\"classes.pagination\" data-test=\"stash-paginate|list\">\n <button\n :aria-label=\"t('ll.previous')\"\n data-test=\"stash-paginate|prev-page\"\n :class=\"classes.prev\"\n :disabled=\"props.currentPage === 1\"\n @click=\"prev\"\n >\n <Icon size=\"small\" name=\"chevron-left\" />\n </button>\n <span v-if=\"props.variant === 'stats'\" class=\"mx-3 text-ice-900\">\n {{ t('ll.pageStats', pageStats) }}\n </span>\n <template v-for=\"page in pageCount\" v-else>\n <button\n v-if=\"shouldShowFirstEllipsis(page)\"\n :key=\"`${page}-ellipsis`\"\n class=\"pointer-events-none\"\n data-test=\"stash-paginate|first-ellipsis\"\n tabindex=\"-1\"\n >\n &#x2026;\n </button>\n <button\n v-if=\"shouldShowPage(page)\"\n :key=\"page\"\n data-test=\"stash-paginate|page-number\"\n :class=\"{ [classes['is-active']]: props.currentPage === page }\"\n @click=\"updatePage(page)\"\n >\n {{ page }}\n </button>\n <button\n v-if=\"shouldShowLastEllipsis(page)\"\n :key=\"`${page}-ellipsis`\"\n class=\"pointer-events-none\"\n data-test=\"stash-paginate|last-ellipsis\"\n tabindex=\"-1\"\n >\n &#x2026;\n </button>\n </template>\n <button\n :aria-label=\"t('ll.next')\"\n data-test=\"stash-paginate|next-page\"\n :class=\"classes.next\"\n :disabled=\"props.isNextDisabled || props.currentPage === pageCount\"\n @click=\"next\"\n >\n <Icon size=\"small\" class=\"rotate-180\" name=\"chevron-left\" />\n </button>\n </ul>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .pagination {\n /* Todo: We shouldn't really be making assumptions about the outer spacing of the pagination component */\n margin-top: --spacing(12);\n z-index: 0;\n\n a,\n button {\n @apply border border-solid border-ice-200;\n align-items: center;\n background-color: var(--color-white);\n color: var(--color-blue-500);\n cursor: pointer;\n display: flex;\n height: var(--height-input);\n justify-content: center;\n margin: 0 0 0 -1px;\n width: var(--height-input);\n\n &.prev {\n border-bottom-left-radius: var(--radius-sm);\n border-top-left-radius: var(--radius-sm);\n }\n\n &.next {\n border-bottom-right-radius: var(--radius-sm);\n border-top-right-radius: var(--radius-sm);\n }\n\n &:focus {\n outline: none;\n }\n\n &:hover {\n text-decoration: none;\n }\n\n &.is-active {\n background-color: var(--color-blue-500);\n color: var(--color-white);\n pointer-events: none;\n z-index: var(--z-index-control);\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n &:not(:disabled):hover,\n &:not(:disabled):focus,\n &.is-active {\n @apply border border-solid border-blue-500;\n position: relative;\n }\n\n &.is-active:focus {\n @apply bg-blue-700 border-blue-700;\n }\n }\n }\n }\n</style>\n"],"names":["props","__props","emit","__emit","classes","useCssModule","pageCount","computed","pageStats","usePaginationStats","toRef","updatePage","currentPage","next","prev","shouldShowPage","page","pageDiff","shouldShowFirstEllipsis","shouldShowLastEllipsis","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_normalizeClass","_unref","t","_createVNode","Icon","_hoisted_3","_toDisplayString","_Fragment","_renderList","$event","_hoisted_4"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PlaidLink.js","sources":["../src/components/PlaidLink/PlaidLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import logger from '@leaflink/snitch';\n import { computed, ref } from 'vue';\n\n import { LinkTokenResponse, Plaid } from '../../../types/plaid';\n import usePlaidLink from '../../composables/usePlaidLink/usePlaidLink';\n\n export interface PlaidLinkProps {\n /**\n * @deprecated Plaid does not support other URLs for loading its SDK\n * Plaid initialization script url to be used\n */\n initScriptUrl?: string;\n\n /**\n * Key to be used in session storage for OAuth flow\n */\n storageKey?: string;\n\n /**\n * Url to be used to redirect the user from the OAuth flow\n */\n returnTo?: string;\n\n /**\n * Plaid link token\n */\n token?: string;\n\n /**\n * Plaid environment to connect\n */\n env?: Plaid.Environment;\n\n /**\n * Function that returns a link token object to be used with Plaid.\n * `link_token` takes precedence over `token` if informed.\n */\n createToken?: () => Promise<LinkTokenResponse>;\n }\n\n const props = withDefaults(defineProps<PlaidLinkProps>(), {\n initScriptUrl: 'https://cdn.plaid.com/link/v2/stable/link-initialize.js',\n storageKey: undefined,\n returnTo: window.location.href,\n env: 'sandbox',\n token: undefined,\n createToken: undefined,\n });\n\n const internalStorageKey = computed(() => {\n if (props.storageKey) {\n return props.storageKey;\n }\n\n // returns up to the last 3 parts of the host. e.g. for `subdomain.my.domain.com` it will return `my.domain.com`\n const host = window.location.host.split('.').splice(-3).join('.');\n\n return `${host}-plaid`;\n });\n\n const emit = defineEmits<{\n /**\n * Emitted whenever the exit event contains errors\n */\n (e: 'error', error: Plaid.Error | null | Error, metadata?: Plaid.OnExitMetaData): void;\n /**\n * Emitted whenever the user successfully links an item\n */\n (e: 'success', public_token: string, metadata: Plaid.OnSuccessMetaData): void;\n /**\n * Emitted whenever the user exits the Link flow\n */\n (e: 'exit', metadata: Plaid.OnExitMetaData): void;\n /**\n * Emitted when the Link is ready to be opened\n */\n (e: 'load'): void;\n /**\n * Emitted at specific points during the Link flow\n */\n (e: 'event', eventName: Plaid.EventName, metadata: Plaid.OnEventMetaData): void;\n }>();\n\n const isPlaidModalOpen = ref(false);\n\n const onExit: Plaid.OnExit = (error: Plaid.Error | null, metadata: Plaid.OnExitMetaData) => {\n isPlaidModalOpen.value = false;\n\n if (error) {\n logger.error(new Error('Plaid: Error trying to link an account'), {\n tags: { plaid: true },\n extra: { PlaidError: error },\n });\n emit('error', error, metadata);\n }\n\n sessionStorage.removeItem(internalStorageKey.value);\n\n emit('exit', metadata);\n };\n\n const onSuccess: Plaid.OnSuccess = (public_token: string, metadata: Plaid.OnSuccessMetaData) => {\n isPlaidModalOpen.value = false;\n\n sessionStorage.removeItem(internalStorageKey.value);\n\n emit('success', public_token, metadata);\n };\n\n const onLoad: Plaid.OnLoad = (...args) => emit('load', ...args);\n\n const onEvent: Plaid.OnEvent = (...args) => emit('event', ...args);\n\n const plaidLinkOptions = ref<Plaid.CreateConfig>({\n env: props.env,\n onSuccess,\n onEvent,\n onLoad,\n onExit,\n });\n\n const { open: openPlaidLink } = usePlaidLink(plaidLinkOptions);\n\n async function handleClick() {\n if (isPlaidModalOpen.value === true) {\n return;\n }\n\n isPlaidModalOpen.value = true;\n\n if (typeof props.createToken === 'function') {\n try {\n const { link_token } = await props.createToken();\n\n plaidLinkOptions.value.token = link_token;\n } catch (err) {\n const error = new Error('Plaid: Error trying to invoke createToken');\n\n logger.error(error, {\n tags: { plaid: true },\n extra: { error: err },\n });\n\n emit('error', error);\n }\n } else if (props.token) {\n plaidLinkOptions.value.token = props.token;\n }\n\n if (!plaidLinkOptions.value.token) {\n const error = new Error('Plaid: link token not found');\n\n logger.error(error, { tags: { plaid: true } });\n emit('error', error);\n\n isPlaidModalOpen.value = false;\n\n return;\n }\n\n sessionStorage.setItem(\n internalStorageKey.value,\n JSON.stringify({ token: plaidLinkOptions.value.token, returnTo: props.returnTo, env: props.env }),\n );\n\n openPlaidLink();\n }\n\n defineExpose({\n handleClick,\n });\n</script>\n\n<template>\n <span data-test=\"stash-plaid-link\" @click=\"handleClick\">\n <!-- @slot Default slot to trigger Plaid's modal -->\n <slot :open=\"isPlaidModalOpen\"></slot>\n </span>\n</template>\n"],"names":["props","__props","internalStorageKey","computed","emit","__emit","isPlaidModalOpen","ref","onExit","error","metadata","logger","onSuccess","public_token","onLoad","args","onEvent","plaidLinkOptions","openPlaidLink","usePlaidLink","handleClick","link_token","err","__expose"],"mappings":";;;;;;;;;;;;;;;AAyCE,UAAMA,IAAQC,GASRC,IAAqBC,EAAS,MAC9BH,EAAM,aACDA,EAAM,aAMR,GAFM,OAAO,SAAS,KAAK,MAAM,GAAG,EAAE,OAAO,EAAE,EAAE,KAAK,GAAG,CAElD,QACf,GAEKI,IAAOC,GAuBPC,IAAmBC,EAAI,EAAK,GAE5BC,IAAuB,CAACC,GAA2BC,MAAmC;AAC1F,MAAAJ,EAAiB,QAAQ,IAErBG,MACFE,EAAO,MAAM,IAAI,MAAM,wCAAwC,GAAG;AAAA,QAChE,MAAM,EAAE,OAAO,GAAA;AAAA,QACf,OAAO,EAAE,YAAYF,EAAA;AAAA,MAAM,CAC5B,GACDL,EAAK,SAASK,GAAOC,CAAQ,IAG/B,eAAe,WAAWR,EAAmB,KAAK,GAElDE,EAAK,QAAQM,CAAQ;AAAA,IACvB,GAEME,IAA6B,CAACC,GAAsBH,MAAsC;AAC9F,MAAAJ,EAAiB,QAAQ,IAEzB,eAAe,WAAWJ,EAAmB,KAAK,GAElDE,EAAK,WAAWS,GAAcH,CAAQ;AAAA,IACxC,GAEMI,IAAuB,IAAIC,MAASX,EAAK,QAAQ,GAAGW,CAAI,GAExDC,IAAyB,IAAID,MAASX,EAAK,SAAS,GAAGW,CAAI,GAE3DE,IAAmBV,EAAwB;AAAA,MAC/C,KAAKP,EAAM;AAAA,MACX,WAAAY;AAAA,MACA,SAAAI;AAAA,MACA,QAAAF;AAAA,MACA,QAAAN;AAAA,IAAA,CACD,GAEK,EAAE,MAAMU,MAAkBC,EAAaF,CAAgB;AAE7D,mBAAeG,IAAc;AAC3B,UAAId,EAAiB,UAAU,IAM/B;AAAA,YAFAA,EAAiB,QAAQ,IAErB,OAAON,EAAM,eAAgB;AAC/B,cAAI;AACF,kBAAM,EAAE,YAAAqB,EAAA,IAAe,MAAMrB,EAAM,YAAA;AAEnC,YAAAiB,EAAiB,MAAM,QAAQI;AAAA,UACjC,SAASC,GAAK;AACZ,kBAAMb,IAAQ,IAAI,MAAM,2CAA2C;AAEnE,YAAAE,EAAO,MAAMF,GAAO;AAAA,cAClB,MAAM,EAAE,OAAO,GAAA;AAAA,cACf,OAAO,EAAE,OAAOa,EAAA;AAAA,YAAI,CACrB,GAEDlB,EAAK,SAASK,CAAK;AAAA,UACrB;AAAA,YACF,CAAWT,EAAM,UACfiB,EAAiB,MAAM,QAAQjB,EAAM;AAGvC,YAAI,CAACiB,EAAiB,MAAM,OAAO;AACjC,gBAAMR,IAAQ,IAAI,MAAM,6BAA6B;AAErD,UAAAE,EAAO,MAAMF,GAAO,EAAE,MAAM,EAAE,OAAO,GAAA,GAAQ,GAC7CL,EAAK,SAASK,CAAK,GAEnBH,EAAiB,QAAQ;AAEzB;AAAA,QACF;AAEA,uBAAe;AAAA,UACbJ,EAAmB;AAAA,UACnB,KAAK,UAAU,EAAE,OAAOe,EAAiB,MAAM,OAAO,UAAUjB,EAAM,UAAU,KAAKA,EAAM,KAAK;AAAA,QAAA,GAGlGkB,EAAA;AAAA;AAAA,IACF;AAEA,WAAAK,EAAa;AAAA,MACX,aAAAH;AAAA,IAAA,CACD;;;;;;;;"}
1
+ {"version":3,"file":"PlaidLink.js","sources":["../src/components/PlaidLink/PlaidLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import logger from '@leaflink/snitch';\n import { computed, ref } from 'vue';\n\n import { LinkTokenResponse, Plaid } from '../../../types/plaid';\n import usePlaidLink from '../../composables/usePlaidLink/usePlaidLink';\n\n export interface PlaidLinkProps {\n /**\n * @deprecated Plaid does not support other URLs for loading its SDK\n * Plaid initialization script url to be used\n */\n initScriptUrl?: string;\n\n /**\n * Key to be used in session storage for OAuth flow\n */\n storageKey?: string;\n\n /**\n * Url to be used to redirect the user from the OAuth flow\n */\n returnTo?: string;\n\n /**\n * Plaid link token\n */\n token?: string;\n\n /**\n * Plaid environment to connect\n */\n env?: Plaid.Environment;\n\n /**\n * Function that returns a link token object to be used with Plaid.\n * `link_token` takes precedence over `token` if informed.\n */\n createToken?: () => Promise<LinkTokenResponse>;\n }\n\n const props = withDefaults(defineProps<PlaidLinkProps>(), {\n initScriptUrl: 'https://cdn.plaid.com/link/v2/stable/link-initialize.js',\n storageKey: undefined,\n returnTo: window.location.href,\n env: 'sandbox',\n token: undefined,\n createToken: undefined,\n });\n\n const internalStorageKey = computed(() => {\n if (props.storageKey) {\n return props.storageKey;\n }\n\n // returns up to the last 3 parts of the host. e.g. for `subdomain.my.domain.com` it will return `my.domain.com`\n const host = window.location.host.split('.').splice(-3).join('.');\n\n return `${host}-plaid`;\n });\n\n const emit = defineEmits<{\n /**\n * Emitted whenever the exit event contains errors\n */\n (e: 'error', error: Plaid.Error | null | Error, metadata?: Plaid.OnExitMetaData): void;\n /**\n * Emitted whenever the user successfully links an item\n */\n (e: 'success', public_token: string, metadata: Plaid.OnSuccessMetaData): void;\n /**\n * Emitted whenever the user exits the Link flow\n */\n (e: 'exit', metadata: Plaid.OnExitMetaData): void;\n /**\n * Emitted when the Link is ready to be opened\n */\n (e: 'load'): void;\n /**\n * Emitted at specific points during the Link flow\n */\n (e: 'event', eventName: Plaid.EventName, metadata: Plaid.OnEventMetaData): void;\n }>();\n\n const isPlaidModalOpen = ref(false);\n\n const onExit: Plaid.OnExit = (error: Plaid.Error | null, metadata: Plaid.OnExitMetaData) => {\n isPlaidModalOpen.value = false;\n\n if (error) {\n logger.error(new Error('Plaid: Error trying to link an account'), {\n tags: { plaid: true },\n extra: { PlaidError: error },\n });\n emit('error', error, metadata);\n }\n\n sessionStorage.removeItem(internalStorageKey.value);\n\n emit('exit', metadata);\n };\n\n const onSuccess: Plaid.OnSuccess = (public_token: string, metadata: Plaid.OnSuccessMetaData) => {\n isPlaidModalOpen.value = false;\n\n sessionStorage.removeItem(internalStorageKey.value);\n\n emit('success', public_token, metadata);\n };\n\n const onLoad: Plaid.OnLoad = (...args) => emit('load', ...args);\n\n const onEvent: Plaid.OnEvent = (...args) => emit('event', ...args);\n\n const plaidLinkOptions = ref<Plaid.CreateConfig>({\n env: props.env,\n onSuccess,\n onEvent,\n onLoad,\n onExit,\n });\n\n const { open: openPlaidLink } = usePlaidLink(plaidLinkOptions);\n\n async function handleClick() {\n if (isPlaidModalOpen.value === true) {\n return;\n }\n\n isPlaidModalOpen.value = true;\n\n if (typeof props.createToken === 'function') {\n try {\n const { link_token } = await props.createToken();\n\n plaidLinkOptions.value.token = link_token;\n } catch (err) {\n const error = new Error('Plaid: Error trying to invoke createToken');\n\n logger.error(error, {\n tags: { plaid: true },\n extra: { error: err },\n });\n\n emit('error', error);\n }\n } else if (props.token) {\n plaidLinkOptions.value.token = props.token;\n }\n\n if (!plaidLinkOptions.value.token) {\n const error = new Error('Plaid: link token not found');\n\n logger.error(error, { tags: { plaid: true } });\n emit('error', error);\n\n isPlaidModalOpen.value = false;\n\n return;\n }\n\n sessionStorage.setItem(\n internalStorageKey.value,\n JSON.stringify({ token: plaidLinkOptions.value.token, returnTo: props.returnTo, env: props.env }),\n );\n\n openPlaidLink();\n }\n\n defineExpose({\n handleClick,\n });\n</script>\n\n<template>\n <span data-test=\"stash-plaid-link\" @click=\"handleClick\">\n <!-- @slot Default slot to trigger Plaid's modal -->\n <slot :open=\"isPlaidModalOpen\"></slot>\n </span>\n</template>\n"],"names":["props","__props","internalStorageKey","computed","emit","__emit","isPlaidModalOpen","ref","onExit","error","metadata","logger","onSuccess","public_token","onLoad","args","onEvent","plaidLinkOptions","openPlaidLink","usePlaidLink","handleClick","link_token","err","__expose","_createElementBlock","_renderSlot","_ctx"],"mappings":";;;;;;;;;;;;;;;AAyCE,UAAMA,IAAQC,GASRC,IAAqBC,EAAS,MAC9BH,EAAM,aACDA,EAAM,aAMR,GAFM,OAAO,SAAS,KAAK,MAAM,GAAG,EAAE,OAAO,EAAE,EAAE,KAAK,GAAG,CAElD,QACf,GAEKI,IAAOC,GAuBPC,IAAmBC,EAAI,EAAK,GAE5BC,IAAuB,CAACC,GAA2BC,MAAmC;AAC1F,MAAAJ,EAAiB,QAAQ,IAErBG,MACFE,EAAO,MAAM,IAAI,MAAM,wCAAwC,GAAG;AAAA,QAChE,MAAM,EAAE,OAAO,GAAA;AAAA,QACf,OAAO,EAAE,YAAYF,EAAA;AAAA,MAAM,CAC5B,GACDL,EAAK,SAASK,GAAOC,CAAQ,IAG/B,eAAe,WAAWR,EAAmB,KAAK,GAElDE,EAAK,QAAQM,CAAQ;AAAA,IACvB,GAEME,IAA6B,CAACC,GAAsBH,MAAsC;AAC9F,MAAAJ,EAAiB,QAAQ,IAEzB,eAAe,WAAWJ,EAAmB,KAAK,GAElDE,EAAK,WAAWS,GAAcH,CAAQ;AAAA,IACxC,GAEMI,IAAuB,IAAIC,MAASX,EAAK,QAAQ,GAAGW,CAAI,GAExDC,IAAyB,IAAID,MAASX,EAAK,SAAS,GAAGW,CAAI,GAE3DE,IAAmBV,EAAwB;AAAA,MAC/C,KAAKP,EAAM;AAAA,MACX,WAAAY;AAAA,MACA,SAAAI;AAAA,MACA,QAAAF;AAAA,MACA,QAAAN;AAAA,IAAA,CACD,GAEK,EAAE,MAAMU,MAAkBC,EAAaF,CAAgB;AAE7D,mBAAeG,IAAc;AAC3B,UAAId,EAAiB,UAAU,IAM/B;AAAA,YAFAA,EAAiB,QAAQ,IAErB,OAAON,EAAM,eAAgB;AAC/B,cAAI;AACF,kBAAM,EAAE,YAAAqB,EAAA,IAAe,MAAMrB,EAAM,YAAA;AAEnC,YAAAiB,EAAiB,MAAM,QAAQI;AAAA,UACjC,SAASC,GAAK;AACZ,kBAAMb,IAAQ,IAAI,MAAM,2CAA2C;AAEnE,YAAAE,EAAO,MAAMF,GAAO;AAAA,cAClB,MAAM,EAAE,OAAO,GAAA;AAAA,cACf,OAAO,EAAE,OAAOa,EAAA;AAAA,YAAI,CACrB,GAEDlB,EAAK,SAASK,CAAK;AAAA,UACrB;AAAA,YACF,CAAWT,EAAM,UACfiB,EAAiB,MAAM,QAAQjB,EAAM;AAGvC,YAAI,CAACiB,EAAiB,MAAM,OAAO;AACjC,gBAAMR,IAAQ,IAAI,MAAM,6BAA6B;AAErD,UAAAE,EAAO,MAAMF,GAAO,EAAE,MAAM,EAAE,OAAO,GAAA,GAAQ,GAC7CL,EAAK,SAASK,CAAK,GAEnBH,EAAiB,QAAQ;AAEzB;AAAA,QACF;AAEA,uBAAe;AAAA,UACbJ,EAAmB;AAAA,UACnB,KAAK,UAAU,EAAE,OAAOe,EAAiB,MAAM,OAAO,UAAUjB,EAAM,UAAU,KAAKA,EAAM,KAAK;AAAA,QAAA,GAGlGkB,EAAA;AAAA;AAAA,IACF;AAEA,WAAAK,EAAa;AAAA,MACX,aAAAH;AAAA,IAAA,CACD,mBAIDI,EAGO,QAAA;AAAA,MAHD,aAAU;AAAA,MAAoB,SAAOJ;AAAA,IAAA;MAEzCK,EAAsCC,EAAA,QAAA,WAAA,EAA/B,MAAMpB,EAAA,OAAgB;AAAA,IAAA;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"QuickAction.js","sources":["../src/components/QuickAction/QuickAction.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule } from 'vue';\n import { type RouteLocationRaw } from 'vue-router';\n\n import { IconName } from '../Icon/Icon.types';\n import Icon from '../Icon/Icon.vue';\n\n export interface QuickActionProps {\n /**\n * The title prop will show the first line of text\n */\n title: string;\n\n /**\n * The subtitle prop will show the second line of text\n */\n subtitle: string;\n\n /**\n * The `to` prop for vue-router's `RouterLink` component\n */\n to?: RouteLocationRaw;\n\n /**\n * If defined, the quick action will render as an `<a />` tag.\n */\n href?: string;\n\n /**\n * Icon to render on the left side\n */\n icon: IconName;\n }\n\n const props = defineProps<QuickActionProps>();\n const classes = useCssModule();\n\n const is = computed(() => {\n if (props.to) {\n return 'router-link';\n }\n\n if (props.href) {\n return 'a';\n }\n\n return 'div';\n });\n\n const linkAttrs = computed(() => {\n if (props.to) {\n return {\n to: props.to,\n };\n }\n\n if (props.href) {\n return {\n href: props.href,\n };\n }\n\n return {};\n });\n</script>\n\n<template>\n <component\n :is=\"is\"\n v-bind=\"linkAttrs\"\n class=\"stash-quick-action rounded p-3 shadow\"\n :class=\"classes.root\"\n data-test=\"stash-quick-action\"\n >\n <div class=\"flex items-center gap-3\">\n <div class=\"flex items-center justify-center rounded bg-blue-100 p-3\">\n <Icon :name=\"props.icon\" class=\"text-blue-500\" />\n </div>\n <div class=\"flex-1\">\n <h4 class=\"text-blue-500\">{{ props.title }}</h4>\n <p class=\"text-xs font-normal text-ice-700 lg:mb-0\">\n {{ props.subtitle }}\n </p>\n </div>\n <Icon name=\"arrow-right\" class=\"text-blue-500\" />\n </div>\n </component>\n</template>\n\n<style module>\n @layer utilities {\n .root {\n background-color: #fff;\n border: 1px solid transparent; /* it prevents layout size shifting of extra height/width when hover */\n cursor: pointer;\n display: inline-block;\n }\n\n .root:hover,\n .root:active,\n .root:focus {\n border: 1px solid var(--color-blue-500);\n text-decoration: none;\n }\n }\n</style>\n"],"names":["props","__props","classes","useCssModule","is","computed","linkAttrs"],"mappings":";;;;;;;;;;;;;AAkCE,UAAMA,IAAQC,GACRC,IAAUC,EAAA,GAEVC,IAAKC,EAAS,MACdL,EAAM,KACD,gBAGLA,EAAM,OACD,MAGF,KACR,GAEKM,IAAYD,EAAS,MACrBL,EAAM,KACD;AAAA,MACL,IAAIA,EAAM;AAAA,IAAA,IAIVA,EAAM,OACD;AAAA,MACL,MAAMA,EAAM;AAAA,IAAA,IAIT,CAAA,CACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"QuickAction.js","sources":["../src/components/QuickAction/QuickAction.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule } from 'vue';\n import { type RouteLocationRaw } from 'vue-router';\n\n import { IconName } from '../Icon/Icon.types';\n import Icon from '../Icon/Icon.vue';\n\n export interface QuickActionProps {\n /**\n * The title prop will show the first line of text\n */\n title: string;\n\n /**\n * The subtitle prop will show the second line of text\n */\n subtitle: string;\n\n /**\n * The `to` prop for vue-router's `RouterLink` component\n */\n to?: RouteLocationRaw;\n\n /**\n * If defined, the quick action will render as an `<a />` tag.\n */\n href?: string;\n\n /**\n * Icon to render on the left side\n */\n icon: IconName;\n }\n\n const props = defineProps<QuickActionProps>();\n const classes = useCssModule();\n\n const is = computed(() => {\n if (props.to) {\n return 'router-link';\n }\n\n if (props.href) {\n return 'a';\n }\n\n return 'div';\n });\n\n const linkAttrs = computed(() => {\n if (props.to) {\n return {\n to: props.to,\n };\n }\n\n if (props.href) {\n return {\n href: props.href,\n };\n }\n\n return {};\n });\n</script>\n\n<template>\n <component\n :is=\"is\"\n v-bind=\"linkAttrs\"\n class=\"stash-quick-action rounded p-3 shadow\"\n :class=\"classes.root\"\n data-test=\"stash-quick-action\"\n >\n <div class=\"flex items-center gap-3\">\n <div class=\"flex items-center justify-center rounded bg-blue-100 p-3\">\n <Icon :name=\"props.icon\" class=\"text-blue-500\" />\n </div>\n <div class=\"flex-1\">\n <h4 class=\"text-blue-500\">{{ props.title }}</h4>\n <p class=\"text-xs font-normal text-ice-700 lg:mb-0\">\n {{ props.subtitle }}\n </p>\n </div>\n <Icon name=\"arrow-right\" class=\"text-blue-500\" />\n </div>\n </component>\n</template>\n\n<style module>\n @layer utilities {\n .root {\n background-color: #fff;\n border: 1px solid transparent; /* it prevents layout size shifting of extra height/width when hover */\n cursor: pointer;\n display: inline-block;\n }\n\n .root:hover,\n .root:active,\n .root:focus {\n border: 1px solid var(--color-blue-500);\n text-decoration: none;\n }\n }\n</style>\n"],"names":["props","__props","classes","useCssModule","is","computed","linkAttrs","_openBlock","_createBlock","_resolveDynamicComponent","_mergeProps","_unref","_createElementVNode","_hoisted_1","_hoisted_2","_createVNode","Icon","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5"],"mappings":";;;;;;;;;;;;;AAkCE,UAAMA,IAAQC,GACRC,IAAUC,EAAA,GAEVC,IAAKC,EAAS,MACdL,EAAM,KACD,gBAGLA,EAAM,OACD,MAGF,KACR,GAEKM,IAAYD,EAAS,MACrBL,EAAM,KACD;AAAA,MACL,IAAIA,EAAM;AAAA,IAAA,IAIVA,EAAM,OACD;AAAA,MACL,MAAMA,EAAM;AAAA,IAAA,IAIT,CAAA,CACR;sBAIDO,EAAA,GAAAC,EAmBYC,EAlBLL,EAAA,KAAE,GADTM,EAEUJ,EAiBE,OAjBO;AAAA,MACjB,OAAK,CAAC,yCACEK,EAAAT,CAAA,EAAQ,IAAI;AAAA,MACpB,aAAU;AAAA,IAAA;iBAEV,MAWM;AAAA,QAXNU,EAWM,OAXNC,GAWM;AAAA,UAVJD,EAEM,OAFNE,GAEM;AAAA,YADJC,EAAiDC,GAAA;AAAA,cAA1C,MAAMhB,EAAM;AAAA,cAAM,OAAM;AAAA,YAAA;;UAEjCY,EAKM,OALNK,GAKM;AAAA,YAJJL,EAAgD,MAAhDM,GAAgDC,EAAnBnB,EAAM,KAAK,GAAA,CAAA;AAAA,YACxCY,EAEI,KAFJQ,GAEID,EADCnB,EAAM,QAAQ,GAAA,CAAA;AAAA,UAAA;UAGrBe,EAAiDC,GAAA;AAAA,YAA3C,MAAK;AAAA,YAAc,OAAM;AAAA,UAAA;;;;;;;;;;;"}
package/dist/Radio.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","sources":["../src/components/Radio/Radio.vue"],"sourcesContent":["<script>\n import { useCssModule } from 'vue';\n\n /**\n * @deprecated use components/RadioNew/Radio instead.\n * if you need multiple Radio components considering using RadioGroup instead.\n */\n export default {\n name: 'll-radio',\n\n props: {\n /**\n * The checked/selected state of the radio button\n */\n checked: {\n type: [String, Number],\n default: undefined,\n },\n\n /**\n * @deprecated Use :checked or v-model:checked instead of :model-value and v-model.\n */\n modelValue: {\n type: [String, Number, null],\n default: null,\n validator(value) {\n if (value !== null) {\n throw new Error('ll-radio: use :checked or v-model:checked instead of :model-value and v-model.');\n }\n\n return true;\n },\n },\n\n /**\n * Adds error styling\n */\n hasError: Boolean,\n\n /**\n * A unique string to distinguish one Radio instance from another\n * and to link the label to the input; required for accessibility\n */\n id: {\n type: String,\n required: true,\n },\n\n /**\n * The description which appears to the right of the radio button\n */\n label: {\n type: String,\n default: '',\n },\n },\n\n emits: ['update:checked'],\n\n setup() {\n return {\n classes: useCssModule(),\n };\n },\n\n computed: {\n internalValue: {\n get() {\n return this.checked;\n },\n set(value) {\n this.$emit('update:checked', value);\n },\n },\n },\n\n created() {\n if (this.$attrs.onChange) {\n throw new Error('ll-radio: use the @update:checked event instead of @input');\n }\n },\n };\n</script>\n\n<template>\n <div class=\"stash-radio\" data-test=\"ll-radio\" :class=\"[classes.root, { error: hasError }]\">\n <input :id=\"id\" v-model=\"internalValue\" class=\"sr-only\" :class=\"classes.input\" type=\"radio\" v-bind=\"$attrs\" />\n\n <label :for=\"id\" :class=\"classes.label\">\n {{ label }}\n </label>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .root {\n position: relative;\n margin: --spacing(1.5) 0;\n }\n\n .label {\n color: var(--color-ice-700);\n cursor: pointer;\n display: inline-block;\n font-size: var(--text-sm);\n font-weight: var(--font-weight-normal);\n line-height: --spacing(6);\n min-height: --spacing(9);\n overflow: visible;\n padding: --spacing(1.5) 0 --spacing(1.5) calc(20px + --spacing(3));\n position: relative;\n vertical-align: top;\n }\n\n .label::before {\n background: var(--color-white);\n border: 1px solid var(--color-ice-500);\n content: '';\n display: inline-block;\n vertical-align: top;\n }\n\n .label::before,\n .label::after {\n height: 20px;\n left: 0;\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 20px;\n border-radius: 50%;\n }\n\n .error .label {\n color: var(--color-red-500);\n }\n\n .error .label::before,\n .error .input {\n border-color: var(--color-red-500);\n }\n\n .input:checked + .label::after {\n background: var(--color-blue-500);\n content: '';\n height: 14px;\n left: 3px;\n width: 14px;\n }\n\n .input:checked:disabled + .label::after {\n background: var(--color-ice-500);\n }\n\n .input:not(:disabled, :checked) + .label:hover::before {\n border-color: var(--color-blue-500);\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .root input {\n margin: 0;\n }\n }\n }\n</style>\n"],"names":["_sfc_main","value","useCssModule","_hoisted_1","_hoisted_2","_createElementBlock","_normalizeClass","$setup","$props","_withDirectives","_createElementVNode","_mergeProps","_cache","$event","$options","_ctx","_toDisplayString"],"mappings":";;;;;;;GAOOA,IAAU;AAAA,EACb,MAAM;AAAA,EAEN,OAAO;AAAA;AAAA;AAAA;AAAA,IAIL,SAAS;AAAA,MACP,MAAM,CAAC,QAAQ,MAAM;AAAA,MACrB,SAAS;AAAA;;;;IAMX,YAAY;AAAA,MACV,MAAM,CAAC,QAAQ,QAAQ,IAAI;AAAA,MAC3B,SAAS;AAAA,MACT,UAAUC,GAAO;AACf,YAAIA,MAAU;AACZ,gBAAM,IAAI,MAAM,gFAAgF;AAGlG,eAAO;AAAA,MACT;AAAA;;;;IAMF,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,IAMV,IAAI;AAAA,MACF,MAAM;AAAA,MACN,UAAU;AAAA;;;;IAMZ,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA;;EAIb,OAAO,CAAC,gBAAgB;AAAA,EAExB,QAAQ;AACN,WAAO;AAAA,MACL,SAASC,EAAY;AAAA;EAEzB;AAAA,EAEA,UAAU;AAAA,IACR,eAAe;AAAA,MACb,MAAM;AACJ,eAAO,KAAK;AAAA,MACd;AAAA,MACA,IAAID,GAAO;AACT,aAAK,MAAM,kBAAkBA,CAAK;AAAA,MACpC;AAAA;;EAIJ,UAAU;AACR,QAAI,KAAK,OAAO;AACd,YAAM,IAAI,MAAM,2DAA2D;AAAA,EAE/E;GAhFJE,IAAA,CAAA,IAAA,GAAAC,IAAA,CAAA,KAAA;;cAqFEC,EAMM,OAAA;AAAA,IAND,OArFPC,GAqFa,eAAa,CAA+BC,UAAQ,eAAeC,EAAA,SAAQ,CAAA,CAAA,CAAA;AAAA,IAA7D,aAAU;AAAA;IACjCC,EAAAC,EAA8G,SAA9GC,EAA8G;AAAA,MAAtG,IAAIH,EAAA;AAAA,MAtFhB,uBAAAI,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAsF6BC,EAAA,gBAAaD;AAAA,MAAE,OAAK,CAAC,WAAkBN,EAAA,QAAQ,KAAK;AAAA,MAAE,MAAK;AAAA,IAAgB,GAAAQ,EAAA,MAAM,GAAA,MAAA,IAtF9GZ,CAAA,GAAA;AAAA,UAsF6BW,EAAA,aAAa;AAAA;IAEtCJ,EAEQ,SAAA;AAAA,MAFA,KAAKF,EAAA;AAAA,MAAK,OAxFtBF,EAwF6BC,EAAA,QAAQ,KAAK;AAAA,IACjC,GAAAS,EAAAR,EAAA,KAAK,GAAA,IAzFdJ,CAAA;AAAA;;;;;"}
1
+ {"version":3,"file":"Radio.js","sources":["../src/components/Radio/Radio.vue"],"sourcesContent":["<script>\n import { useCssModule } from 'vue';\n\n /**\n * @deprecated use components/RadioNew/Radio instead.\n * if you need multiple Radio components considering using RadioGroup instead.\n */\n export default {\n name: 'll-radio',\n\n props: {\n /**\n * The checked/selected state of the radio button\n */\n checked: {\n type: [String, Number],\n default: undefined,\n },\n\n /**\n * @deprecated Use :checked or v-model:checked instead of :model-value and v-model.\n */\n modelValue: {\n type: [String, Number, null],\n default: null,\n validator(value) {\n if (value !== null) {\n throw new Error('ll-radio: use :checked or v-model:checked instead of :model-value and v-model.');\n }\n\n return true;\n },\n },\n\n /**\n * Adds error styling\n */\n hasError: Boolean,\n\n /**\n * A unique string to distinguish one Radio instance from another\n * and to link the label to the input; required for accessibility\n */\n id: {\n type: String,\n required: true,\n },\n\n /**\n * The description which appears to the right of the radio button\n */\n label: {\n type: String,\n default: '',\n },\n },\n\n emits: ['update:checked'],\n\n setup() {\n return {\n classes: useCssModule(),\n };\n },\n\n computed: {\n internalValue: {\n get() {\n return this.checked;\n },\n set(value) {\n this.$emit('update:checked', value);\n },\n },\n },\n\n created() {\n if (this.$attrs.onChange) {\n throw new Error('ll-radio: use the @update:checked event instead of @input');\n }\n },\n };\n</script>\n\n<template>\n <div class=\"stash-radio\" data-test=\"ll-radio\" :class=\"[classes.root, { error: hasError }]\">\n <input :id=\"id\" v-model=\"internalValue\" class=\"sr-only\" :class=\"classes.input\" type=\"radio\" v-bind=\"$attrs\" />\n\n <label :for=\"id\" :class=\"classes.label\">\n {{ label }}\n </label>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .root {\n position: relative;\n margin: --spacing(1.5) 0;\n }\n\n .label {\n color: var(--color-ice-700);\n cursor: pointer;\n display: inline-block;\n font-size: var(--text-sm);\n font-weight: var(--font-weight-normal);\n line-height: --spacing(6);\n min-height: --spacing(9);\n overflow: visible;\n padding: --spacing(1.5) 0 --spacing(1.5) calc(20px + --spacing(3));\n position: relative;\n vertical-align: top;\n }\n\n .label::before {\n background: var(--color-white);\n border: 1px solid var(--color-ice-500);\n content: '';\n display: inline-block;\n vertical-align: top;\n }\n\n .label::before,\n .label::after {\n height: 20px;\n left: 0;\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n width: 20px;\n border-radius: 50%;\n }\n\n .error .label {\n color: var(--color-red-500);\n }\n\n .error .label::before,\n .error .input {\n border-color: var(--color-red-500);\n }\n\n .input:checked + .label::after {\n background: var(--color-blue-500);\n content: '';\n height: 14px;\n left: 3px;\n width: 14px;\n }\n\n .input:checked:disabled + .label::after {\n background: var(--color-ice-500);\n }\n\n .input:not(:disabled, :checked) + .label:hover::before {\n border-color: var(--color-blue-500);\n }\n\n @media (width >= theme(--breakpoint-lg)) {\n .root input {\n margin: 0;\n }\n }\n }\n</style>\n"],"names":["_sfc_main","value","useCssModule","_createElementBlock","$setup","$props","_withDirectives","_createElementVNode","_mergeProps","$options","$event","_ctx","_hoisted_1","_normalizeClass","_hoisted_2"],"mappings":";;;;;;;GAOOA,IAAU;AAAA,EACb,MAAM;AAAA,EAEN,OAAO;AAAA;AAAA;AAAA;AAAA,IAIL,SAAS;AAAA,MACP,MAAM,CAAC,QAAQ,MAAM;AAAA,MACrB,SAAS;AAAA;;;;IAMX,YAAY;AAAA,MACV,MAAM,CAAC,QAAQ,QAAQ,IAAI;AAAA,MAC3B,SAAS;AAAA,MACT,UAAUC,GAAO;AACf,YAAIA,MAAU;AACZ,gBAAM,IAAI,MAAM,gFAAgF;AAGlG,eAAO;AAAA,MACT;AAAA;;;;IAMF,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,IAMV,IAAI;AAAA,MACF,MAAM;AAAA,MACN,UAAU;AAAA;;;;IAMZ,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA;;EAIb,OAAO,CAAC,gBAAgB;AAAA,EAExB,QAAQ;AACN,WAAO;AAAA,MACL,SAASC,EAAY;AAAA;EAEzB;AAAA,EAEA,UAAU;AAAA,IACR,eAAe;AAAA,MACb,MAAM;AACJ,eAAO,KAAK;AAAA,MACd;AAAA,MACA,IAAID,GAAO;AACT,aAAK,MAAM,kBAAkBA,CAAK;AAAA,MACpC;AAAA;;EAIJ,UAAU;AACR,QAAI,KAAK,OAAO;AACd,YAAM,IAAI,MAAM,2DAA2D;AAAA,EAE/E;;;cAKFE,EAMM,OAAA;AAAA,IAND,UAAM,eAAa,CAA+BC,UAAQ,eAAeC,EAAA,SAAQ,CAAA,CAAA,CAAA;AAAA,IAA7D,aAAU;AAAA;IACjCC,EAAAC,EAA8G,SAA9GC,EAA8G;AAAA,MAAtG,IAAIH,EAAA;AAAA,oDAAaI,EAAA,gBAAaC;AAAA,MAAE,OAAK,CAAC,WAAkBN,EAAA,QAAQ,KAAK;AAAA,MAAE,MAAK;AAAA,OAAgBO,EAAA,MAAM,GAAA,MAAA,IAAAC,CAAA,GAAA;AAAA,UAAjFH,EAAA,aAAa;AAAA;IAEtCF,EAEQ,SAAA;AAAA,MAFA,KAAKF,EAAA;AAAA,MAAK,OAAKQ,EAAET,EAAA,QAAQ,KAAK;AAAA,SACjCC,EAAA,KAAK,GAAA,IAAAS,CAAA;AAAA;;;;;"}
@@ -2,7 +2,7 @@ import { defineComponent as w, inject as V, useCssModule as g, createElementBloc
2
2
  import F from "lodash-es/uniqueId";
3
3
  import { R as k } from "./RadioGroup.keys-CqfiKkNz.js";
4
4
  import { _ as B } from "./_plugin-vue_export-helper-CHgC5LLL.js";
5
- import { _ as J } from "./Field.vue_vue_type_script_setup_true_lang-dAGKfjf5.js";
5
+ import { _ as J } from "./Field.vue_vue_type_script_setup_true_lang-D2I8xDEW.js";
6
6
  const H = ["id", "name", "value", "checked", "disabled"], K = ["for"], Q = /* @__PURE__ */ w({
7
7
  __name: "VariantButton",
8
8
  setup(p) {