@drivenets/design-system 0.1.0 → 0.2.0

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 (170) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/components/ds-avatar/ds-avatar.cjs +98 -0
  3. package/dist/components/ds-avatar/ds-avatar.d.cts +12 -0
  4. package/dist/components/ds-avatar/ds-avatar.d.cts.map +1 -0
  5. package/dist/components/ds-avatar/ds-avatar.d.ts +12 -0
  6. package/dist/components/ds-avatar/ds-avatar.d.ts.map +1 -0
  7. package/dist/components/ds-avatar/ds-avatar.js +97 -0
  8. package/dist/components/ds-avatar/ds-avatar.js.map +1 -0
  9. package/dist/components/ds-avatar/ds-avatar.module.cjs +17 -0
  10. package/dist/components/ds-avatar/ds-avatar.module.js +17 -0
  11. package/dist/components/ds-avatar/ds-avatar.module.js.map +1 -0
  12. package/dist/components/ds-avatar/ds-avatar.types.d.cts +44 -0
  13. package/dist/components/ds-avatar/ds-avatar.types.d.cts.map +1 -0
  14. package/dist/components/ds-avatar/ds-avatar.types.d.ts +44 -0
  15. package/dist/components/ds-avatar/ds-avatar.types.d.ts.map +1 -0
  16. package/dist/components/ds-avatar/index.cjs +1 -0
  17. package/dist/components/ds-avatar/index.d.ts +2 -0
  18. package/dist/components/ds-avatar/index.js +1 -0
  19. package/dist/components/ds-avatar-group/ds-avatar-group.cjs +93 -0
  20. package/dist/components/ds-avatar-group/ds-avatar-group.d.cts +12 -0
  21. package/dist/components/ds-avatar-group/ds-avatar-group.d.cts.map +1 -0
  22. package/dist/components/ds-avatar-group/ds-avatar-group.d.ts +12 -0
  23. package/dist/components/ds-avatar-group/ds-avatar-group.d.ts.map +1 -0
  24. package/dist/components/ds-avatar-group/ds-avatar-group.js +92 -0
  25. package/dist/components/ds-avatar-group/ds-avatar-group.js.map +1 -0
  26. package/dist/components/ds-avatar-group/ds-avatar-group.module.cjs +19 -0
  27. package/dist/components/ds-avatar-group/ds-avatar-group.module.js +19 -0
  28. package/dist/components/ds-avatar-group/ds-avatar-group.module.js.map +1 -0
  29. package/dist/components/ds-avatar-group/ds-avatar-group.types.d.cts +31 -0
  30. package/dist/components/ds-avatar-group/ds-avatar-group.types.d.cts.map +1 -0
  31. package/dist/components/ds-avatar-group/ds-avatar-group.types.d.ts +32 -0
  32. package/dist/components/ds-avatar-group/ds-avatar-group.types.d.ts.map +1 -0
  33. package/dist/components/ds-avatar-group/index.cjs +1 -0
  34. package/dist/components/ds-avatar-group/index.d.ts +2 -0
  35. package/dist/components/ds-avatar-group/index.js +1 -0
  36. package/dist/components/ds-button/ds-button.d.ts +2 -2
  37. package/dist/components/ds-button/ds-button.d.ts.map +1 -1
  38. package/dist/components/ds-chip/ds-chip.cjs +2 -1
  39. package/dist/components/ds-chip/ds-chip.d.cts +2 -1
  40. package/dist/components/ds-chip/ds-chip.d.cts.map +1 -1
  41. package/dist/components/ds-chip/ds-chip.d.ts +2 -1
  42. package/dist/components/ds-chip/ds-chip.d.ts.map +1 -1
  43. package/dist/components/ds-chip/ds-chip.js +2 -1
  44. package/dist/components/ds-chip/ds-chip.js.map +1 -1
  45. package/dist/components/ds-chip/ds-chip.types.d.cts +13 -0
  46. package/dist/components/ds-chip/ds-chip.types.d.cts.map +1 -1
  47. package/dist/components/ds-chip/ds-chip.types.d.ts +13 -0
  48. package/dist/components/ds-chip/ds-chip.types.d.ts.map +1 -1
  49. package/dist/components/ds-chip-group/ds-chip-group.cjs +2 -2
  50. package/dist/components/ds-chip-group/ds-chip-group.d.cts +2 -2
  51. package/dist/components/ds-chip-group/ds-chip-group.d.ts +2 -2
  52. package/dist/components/ds-chip-group/ds-chip-group.js +2 -2
  53. package/dist/components/ds-chip-group/ds-chip-group.js.map +1 -1
  54. package/dist/components/ds-chip-group/ds-chip-group.types.d.cts +9 -0
  55. package/dist/components/ds-chip-group/ds-chip-group.types.d.cts.map +1 -1
  56. package/dist/components/ds-chip-group/ds-chip-group.types.d.ts +9 -0
  57. package/dist/components/ds-chip-group/ds-chip-group.types.d.ts.map +1 -1
  58. package/dist/components/ds-confirmation/ds-confirmation.d.cts +8 -8
  59. package/dist/components/ds-confirmation/ds-confirmation.d.ts +8 -8
  60. package/dist/components/ds-date-input/ds-date-input.d.cts +2 -2
  61. package/dist/components/ds-date-input/ds-date-input.d.cts.map +1 -1
  62. package/dist/components/ds-date-input/ds-date-input.d.ts +2 -2
  63. package/dist/components/ds-date-input/ds-date-input.js +2 -2
  64. package/dist/components/ds-date-input/ds-date-input.js.map +1 -1
  65. package/dist/components/ds-drawer/ds-drawer.d.cts +9 -9
  66. package/dist/components/ds-drawer/ds-drawer.d.ts +9 -9
  67. package/dist/components/ds-drawer/ds-drawer.js +2 -2
  68. package/dist/components/ds-dropdown-menu/ds-dropdown-menu.js +3 -3
  69. package/dist/components/ds-dropdown-menu/ds-dropdown-menu.js.map +1 -1
  70. package/dist/components/ds-expandable-text-input/ds-expandable-text-input.d.cts +2 -2
  71. package/dist/components/ds-expandable-text-input/ds-expandable-text-input.d.ts +2 -2
  72. package/dist/components/ds-file-upload/components/file-upload-item/file-upload-item.cjs +2 -2
  73. package/dist/components/ds-file-upload/components/file-upload-item/file-upload-item.js +2 -2
  74. package/dist/components/ds-form-control/ds-form-control.d.cts +8 -8
  75. package/dist/components/ds-modal/ds-modal.d.cts +8 -8
  76. package/dist/components/ds-panel/ds-panel.d.cts +2 -2
  77. package/dist/components/ds-panel/ds-panel.d.ts +2 -2
  78. package/dist/components/ds-select/ds-select.d.cts +2 -2
  79. package/dist/components/ds-select/ds-select.d.ts +2 -2
  80. package/dist/components/ds-smart-tabs/ds-smart-tabs.d.cts +2 -2
  81. package/dist/components/ds-smart-tabs/ds-smart-tabs.d.ts +2 -2
  82. package/dist/components/ds-smart-tabs/ds-smart-tabs.d.ts.map +1 -1
  83. package/dist/components/ds-stepper/components/ds-step-content.d.cts +2 -2
  84. package/dist/components/ds-stepper/components/ds-step-content.d.ts +2 -2
  85. package/dist/components/ds-stepper/components/ds-step-next-button.d.cts +2 -2
  86. package/dist/components/ds-stepper/components/ds-step-next-button.d.ts +2 -2
  87. package/dist/components/ds-stepper/components/ds-step.d.cts +2 -2
  88. package/dist/components/ds-stepper/components/ds-step.d.ts +2 -2
  89. package/dist/components/ds-stepper/ds-stepper.d.cts +2 -2
  90. package/dist/components/ds-stepper/ds-stepper.d.ts +2 -2
  91. package/dist/components/ds-table/ds-table.d.cts +2 -2
  92. package/dist/components/ds-table/ds-table.d.ts +2 -2
  93. package/dist/components/ds-tag/ds-tag.cjs +254 -0
  94. package/dist/components/ds-tag/ds-tag.d.cts +25 -0
  95. package/dist/components/ds-tag/ds-tag.d.cts.map +1 -0
  96. package/dist/components/ds-tag/ds-tag.d.ts +25 -0
  97. package/dist/components/ds-tag/ds-tag.d.ts.map +1 -0
  98. package/dist/components/ds-tag/ds-tag.js +253 -0
  99. package/dist/components/ds-tag/ds-tag.js.map +1 -0
  100. package/dist/components/ds-tag/ds-tag.module.cjs +17 -0
  101. package/dist/components/ds-tag/ds-tag.module.js +17 -0
  102. package/dist/components/ds-tag/ds-tag.module.js.map +1 -0
  103. package/dist/components/ds-tag/ds-tag.types.d.cts +68 -0
  104. package/dist/components/ds-tag/ds-tag.types.d.cts.map +1 -0
  105. package/dist/components/ds-tag/ds-tag.types.d.ts +68 -0
  106. package/dist/components/ds-tag/ds-tag.types.d.ts.map +1 -0
  107. package/dist/components/ds-tag/index.cjs +1 -0
  108. package/dist/components/ds-tag/index.d.ts +2 -0
  109. package/dist/components/ds-tag/index.js +1 -0
  110. package/dist/components/ds-tag-filter/ds-tag-filter.cjs +325 -0
  111. package/dist/components/ds-tag-filter/ds-tag-filter.d.cts +24 -0
  112. package/dist/components/ds-tag-filter/ds-tag-filter.d.cts.map +1 -0
  113. package/dist/components/ds-tag-filter/ds-tag-filter.d.ts +24 -0
  114. package/dist/components/ds-tag-filter/ds-tag-filter.d.ts.map +1 -0
  115. package/dist/components/ds-tag-filter/ds-tag-filter.js +324 -0
  116. package/dist/components/ds-tag-filter/ds-tag-filter.js.map +1 -0
  117. package/dist/components/ds-tag-filter/ds-tag-filter.module.cjs +17 -0
  118. package/dist/components/ds-tag-filter/ds-tag-filter.module.js +17 -0
  119. package/dist/components/ds-tag-filter/ds-tag-filter.module.js.map +1 -0
  120. package/dist/components/ds-tag-filter/ds-tag-filter.types.d.cts +71 -0
  121. package/dist/components/ds-tag-filter/ds-tag-filter.types.d.cts.map +1 -0
  122. package/dist/components/ds-tag-filter/ds-tag-filter.types.d.ts +72 -0
  123. package/dist/components/ds-tag-filter/ds-tag-filter.types.d.ts.map +1 -0
  124. package/dist/components/ds-tag-filter/hooks/use-tag-overflow-calculation.cjs +137 -0
  125. package/dist/components/ds-tag-filter/hooks/use-tag-overflow-calculation.js +137 -0
  126. package/dist/components/ds-tag-filter/hooks/use-tag-overflow-calculation.js.map +1 -0
  127. package/dist/components/ds-tag-filter/index.cjs +1 -0
  128. package/dist/components/ds-tag-filter/index.d.ts +2 -0
  129. package/dist/components/ds-tag-filter/index.js +1 -0
  130. package/dist/components/ds-tag-filter/utils.cjs +54 -0
  131. package/dist/components/ds-tag-filter/utils.js +52 -0
  132. package/dist/components/ds-tag-filter/utils.js.map +1 -0
  133. package/dist/components/ds-text-input/ds-text-input.js +2 -2
  134. package/dist/components/ds-toggle/ds-toggle.d.cts +2 -2
  135. package/dist/components/ds-toggle/ds-toggle.d.ts +2 -2
  136. package/dist/components/ds-vertical-tabs/ds-vertical-tabs.d.cts +5 -5
  137. package/dist/components/ds-vertical-tabs/ds-vertical-tabs.d.ts +5 -5
  138. package/dist/index.cjs +14 -2
  139. package/dist/index.d.cts +9 -1
  140. package/dist/index.d.ts +13 -1
  141. package/dist/index.js +11 -3
  142. package/dist/index.min.css +1 -1
  143. package/package.json +6 -2
  144. package/src/components/ds-avatar/_mixins.scss +45 -0
  145. package/src/components/ds-avatar/ds-avatar.module.scss +52 -0
  146. package/src/components/ds-avatar/ds-avatar.tsx +42 -0
  147. package/src/components/ds-avatar/ds-avatar.types.ts +41 -0
  148. package/src/components/ds-avatar/index.ts +2 -0
  149. package/src/components/ds-avatar-group/ds-avatar-group.module.scss +70 -0
  150. package/src/components/ds-avatar-group/ds-avatar-group.tsx +51 -0
  151. package/src/components/ds-avatar-group/ds-avatar-group.types.ts +27 -0
  152. package/src/components/ds-avatar-group/index.ts +2 -0
  153. package/src/components/ds-chip/ds-chip.tsx +2 -1
  154. package/src/components/ds-chip/ds-chip.types.tsx +13 -0
  155. package/src/components/ds-chip/index.tsx +8 -0
  156. package/src/components/ds-chip-group/ds-chip-group.tsx +2 -2
  157. package/src/components/ds-chip-group/ds-chip-group.types.ts +8 -0
  158. package/src/components/ds-chip-group/index.ts +1 -0
  159. package/src/components/ds-tag/ds-tag.module.scss +112 -0
  160. package/src/components/ds-tag/ds-tag.tsx +124 -0
  161. package/src/components/ds-tag/ds-tag.types.tsx +67 -0
  162. package/src/components/ds-tag/index.tsx +2 -0
  163. package/src/components/ds-tag-filter/ds-tag-filter.module.scss +72 -0
  164. package/src/components/ds-tag-filter/ds-tag-filter.tsx +178 -0
  165. package/src/components/ds-tag-filter/ds-tag-filter.types.ts +68 -0
  166. package/src/components/ds-tag-filter/hooks/use-tag-overflow-calculation.ts +135 -0
  167. package/src/components/ds-tag-filter/index.ts +2 -0
  168. package/src/components/ds-tag-filter/utils.test.ts +401 -0
  169. package/src/components/ds-tag-filter/utils.ts +65 -0
  170. package/src/index.ts +4 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ds-tag-filter.js","names":["useRef","useState","createPortal","classNames","styles","DsTagFilterProps","TagFilterItem","useTagOverflowCalculation","DsTypography","DsTag","DsButton","DsIcon","DsTagFilter","t0","$","_c","items","locale","t1","className","style","onClearAll","onItemDelete","onItemSelect","onExpand","t2","undefined","expanded","setExpanded","containerRef","measurementRef","t3","length","totalItems","row1TagCount","row2TagCount","hasOverflow","label","t4","clearButton","t5","hiddenCountPlural","t6","hiddenCountSingular","t7","collapseTagLabel","t8","measurementContainer","t10","t11","t12","t13","t14","t9","Symbol","for","bb0","row1Tags","slice","row2Tags","t15","hiddenTags","hiddenCount","hasRow2Content","t16","item","tagProps","slotProps","tag","id","selected","renderTag","t17","newExpanded","handleExpandToggle","t18","t19","t20","item_0","map","clearContent","t21","expandTag","t22","t23","container","t24","t25","item_1","t26","t27","row1","row2","item_2","String","document","body"],"sources":["../../../src/components/ds-tag-filter/ds-tag-filter.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport classNames from 'classnames';\nimport styles from './ds-tag-filter.module.scss';\nimport type { DsTagFilterProps, TagFilterItem } from './ds-tag-filter.types';\nimport { useTagOverflowCalculation } from './hooks/use-tag-overflow-calculation';\nimport { DsTypography } from '../ds-typography';\nimport { DsTag } from '../ds-tag';\nimport { DsButton } from '../ds-button';\nimport { DsIcon } from '../ds-icon';\n\n/**\n * Design system TagFilter component\n *\n * A component for displaying active filters as tags with overflow handling.\n * Shows visible tags in up to 2 rows, with the Expand button to show hidden items.\n */\nconst DsTagFilter = ({\n\titems,\n\tlocale = {},\n\tclassName,\n\tstyle,\n\tonClearAll,\n\tonItemDelete,\n\tonItemSelect,\n\tonExpand,\n}: DsTagFilterProps) => {\n\tconst [expanded, setExpanded] = useState(false);\n\tconst containerRef = useRef<HTMLDivElement>(null);\n\tconst measurementRef = useRef<HTMLDivElement>(null);\n\n\tconst { row1TagCount, row2TagCount, hasOverflow } = useTagOverflowCalculation({\n\t\tcontainerRef,\n\t\tmeasurementRef,\n\t\ttotalItems: items.length,\n\t\texpanded,\n\t});\n\n\tconst {\n\t\tlabel = 'Filtered by:',\n\t\tclearButton = 'Clear all filters',\n\t\thiddenCountPlural = 'filters',\n\t\thiddenCountSingular = 'filter',\n\t\tcollapseTagLabel = 'Collapse',\n\t} = locale;\n\n\t// Split items into row sections\n\tconst row1Tags = items.slice(0, row1TagCount);\n\tconst row2Tags = items.slice(row1TagCount, row1TagCount + row2TagCount);\n\tconst hiddenTags = expanded ? [] : items.slice(row1TagCount + row2TagCount);\n\n\tif (items.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst hiddenCount = hiddenTags.length;\n\tconst hasRow2Content = row2Tags.length > 0 || hasOverflow;\n\n\tconst renderTag = (item: TagFilterItem) => {\n\t\tconst tagProps = item.slotProps?.tag || {};\n\n\t\treturn (\n\t\t\t<DsTag\n\t\t\t\t{...tagProps}\n\t\t\t\tkey={item.id}\n\t\t\t\tlabel={item.label}\n\t\t\t\tselected={item.selected}\n\t\t\t\tonClick={onItemSelect ? () => onItemSelect(item) : undefined}\n\t\t\t\tonDelete={onItemDelete ? () => onItemDelete(item) : undefined}\n\t\t\t/>\n\t\t);\n\t};\n\n\tconst handleExpandToggle = () => {\n\t\tconst newExpanded = !expanded;\n\t\tsetExpanded(newExpanded);\n\t\tonExpand?.(newExpanded);\n\t};\n\n\t// Measurement container rendered via portal to keep it outside the component's DOM tree\n\t// This prevents Testing Library from finding duplicate elements\n\t// We use it to calculate the number of remaining tags to render\n\tconst measurementContainer = (\n\t\t<div ref={measurementRef} className={styles.measurementContainer} aria-hidden=\"true\">\n\t\t\t{label && (\n\t\t\t\t<span data-measure-label=\"\">\n\t\t\t\t\t<DsTypography variant=\"body-sm-reg\" className={styles.label}>\n\t\t\t\t\t\t{label}\n\t\t\t\t\t</DsTypography>\n\t\t\t\t</span>\n\t\t\t)}\n\t\t\t{items.map((item) => (\n\t\t\t\t<DsTag\n\t\t\t\t\tkey={item.id}\n\t\t\t\t\tdata-measure-tag=\"\"\n\t\t\t\t\tlabel={item.label}\n\t\t\t\t\tselected={item.selected}\n\t\t\t\t\tonClick={onItemSelect ? () => onItemSelect(item) : undefined}\n\t\t\t\t\tonDelete={onItemDelete ? () => onItemDelete(item) : undefined}\n\t\t\t\t/>\n\t\t\t))}\n\t\t\t{onClearAll && (\n\t\t\t\t<DsButton\n\t\t\t\t\tdata-measure-clear=\"\"\n\t\t\t\t\tdesign=\"v1.2\"\n\t\t\t\t\tbuttonType=\"tertiary\"\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tclassName={styles.clearButton}\n\t\t\t\t\tcontentClassName={styles.clearContent}\n\t\t\t\t\tsize=\"small\"\n\t\t\t\t>\n\t\t\t\t\t<DsIcon icon=\"close\" />\n\t\t\t\t\t{clearButton}\n\t\t\t\t</DsButton>\n\t\t\t)}\n\t\t\t<DsTag data-measure-expand=\"\" label=\"+99 filters\" className={styles.expandTag} />\n\t\t</div>\n\t);\n\n\t/**\n\t * IMPORTANT!\n\t * If you make any changes to this layout (styling, JSX, anything that affects it.)\n\t * please, apply the exact same changes to the \"measurementContainer\"\n\t */\n\treturn (\n\t\t<>\n\t\t\t<div\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName={classNames(styles.container, expanded && styles.expanded, className)}\n\t\t\t\tstyle={style}\n\t\t\t>\n\t\t\t\t<div className={styles.row1}>\n\t\t\t\t\t{label && (\n\t\t\t\t\t\t<DsTypography variant=\"body-sm-reg\" className={styles.label}>\n\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t</DsTypography>\n\t\t\t\t\t)}\n\t\t\t\t\t{row1Tags.map((item) => renderTag(item))}\n\t\t\t\t\t{onClearAll && (\n\t\t\t\t\t\t<DsButton\n\t\t\t\t\t\t\tdesign=\"v1.2\"\n\t\t\t\t\t\t\tbuttonType=\"tertiary\"\n\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\tclassName={styles.clearButton}\n\t\t\t\t\t\t\tcontentClassName={styles.clearContent}\n\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\tonClick={onClearAll}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<DsIcon icon=\"close\" />\n\t\t\t\t\t\t\t{clearButton}\n\t\t\t\t\t\t</DsButton>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t{hasRow2Content && (\n\t\t\t\t\t<div className={styles.row2}>\n\t\t\t\t\t\t{row2Tags.map((item) => renderTag(item))}\n\t\t\t\t\t\t{hasOverflow && (\n\t\t\t\t\t\t\t<DsTag\n\t\t\t\t\t\t\t\tlabel={\n\t\t\t\t\t\t\t\t\texpanded\n\t\t\t\t\t\t\t\t\t\t? collapseTagLabel\n\t\t\t\t\t\t\t\t\t\t: `+${String(hiddenCount)} ${hiddenCount === 1 ? hiddenCountSingular : hiddenCountPlural}`\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tselected={expanded}\n\t\t\t\t\t\t\t\tclassName={styles.expandTag}\n\t\t\t\t\t\t\t\tonClick={handleExpandToggle}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{createPortal(measurementContainer, document.body)}\n\t\t</>\n\t);\n};\n\nexport default DsTagFilter;\n"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+
2
+ //#region src/components/ds-tag-filter/ds-tag-filter.module.scss
3
+ var ds_tag_filter_module_default = {
4
+ "container": "_container_1jmga_1",
5
+ "expanded": "_expanded_1jmga_1",
6
+ "row1": "_row1_1jmga_1",
7
+ "row2": "_row2_1jmga_1",
8
+ "label": "_label_1jmga_1",
9
+ "expandTag": "_expandTag_1jmga_1",
10
+ "itemCheckbox": "_itemCheckbox_1jmga_1",
11
+ "clearContent": "_clearContent_1jmga_1",
12
+ "clearButton": "_clearButton_1jmga_1",
13
+ "measurementContainer": "_measurementContainer_1jmga_1"
14
+ };
15
+
16
+ //#endregion
17
+ exports.default = ds_tag_filter_module_default;
@@ -0,0 +1,17 @@
1
+ //#region src/components/ds-tag-filter/ds-tag-filter.module.scss
2
+ var ds_tag_filter_module_default = {
3
+ "container": "_container_1jmga_1",
4
+ "expanded": "_expanded_1jmga_1",
5
+ "row1": "_row1_1jmga_1",
6
+ "row2": "_row2_1jmga_1",
7
+ "label": "_label_1jmga_1",
8
+ "expandTag": "_expandTag_1jmga_1",
9
+ "itemCheckbox": "_itemCheckbox_1jmga_1",
10
+ "clearContent": "_clearContent_1jmga_1",
11
+ "clearButton": "_clearButton_1jmga_1",
12
+ "measurementContainer": "_measurementContainer_1jmga_1"
13
+ };
14
+
15
+ //#endregion
16
+ export { ds_tag_filter_module_default as default };
17
+ //# sourceMappingURL=ds-tag-filter.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ds-tag-filter.module.js","names":[],"sources":["../../../src/components/ds-tag-filter/ds-tag-filter.module.scss"],"sourcesContent":[".container {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--spacing-xs);\n\tpadding: var(--spacing-xs) var(--spacing-standard);\n\tbackground: var(--color-background-selected-weak);\n\tborder: 1px solid var(--color-outline-weak);\n\tborder-radius: var(--spacing-3xs);\n\tmax-height: 88px; // hardcoded value required in the design\n\toverflow: hidden;\n\n\t&.expanded {\n\t\tmax-height: none;\n\t}\n}\n\n.row1 {\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tgap: var(--spacing-xs);\n\tflex-shrink: 0;\n}\n\n.row2 {\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tgap: var(--spacing-xs);\n\tflex-wrap: wrap;\n}\n\n.label {\n\tcolor: var(--color-font-secondary);\n\twhite-space: nowrap;\n\tflex-shrink: 0;\n}\n\n.expandTag {\n\tcursor: pointer;\n\tflex-shrink: 0;\n}\n\n.itemCheckbox {\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.clearContent {\n\tbackground: transparent !important;\n}\n\n.clearButton {\n\tmargin-left: auto;\n\tpadding: 0;\n\tflex-shrink: 0;\n}\n\n// Hidden container for measuring element widths\n// Must render all elements to get accurate measurements\n.measurementContainer {\n\tpointer-events: none;\n\tdisplay: flex;\n\talign-items: center;\n\tgap: var(--spacing-xs);\n\n\t// Ensure it doesn't affect layout\n\theight: 0;\n\toverflow: hidden;\n\tposition: absolute;\n\tvisibility: hidden;\n}\n"],"mappings":""}
@@ -0,0 +1,71 @@
1
+ import { DsTagProps } from "../ds-tag/ds-tag.types.cjs";
2
+ import { CSSProperties } from "react";
3
+
4
+ //#region src/components/ds-tag-filter/ds-tag-filter.types.d.ts
5
+ interface TagFilterItem {
6
+ /**
7
+ * Unique identifier for the tag
8
+ */
9
+ id: string;
10
+ /**
11
+ * The label text to display in the tag
12
+ */
13
+ label: string;
14
+ /**
15
+ * Additional metadata to store with the tag
16
+ */
17
+ metadata?: Record<string, unknown>;
18
+ /**
19
+ * Whether the tag is selected/checked
20
+ */
21
+ selected?: boolean;
22
+ /**
23
+ * Additional props to pass to the components
24
+ */
25
+ slotProps?: {
26
+ tag?: Partial<DsTagProps>;
27
+ };
28
+ }
29
+ interface DsTagFilterProps {
30
+ /**
31
+ * Array of tag items to display
32
+ */
33
+ items: TagFilterItem[];
34
+ /**
35
+ * Locale object (you can pass custom strings for localization)
36
+ */
37
+ locale?: {
38
+ label?: string;
39
+ clearButton?: string;
40
+ collapseTagLabel?: string;
41
+ hiddenCountSingular?: string;
42
+ hiddenCountPlural?: string;
43
+ };
44
+ /**
45
+ * Callback when "Clear all" is clicked
46
+ */
47
+ onClearAll?: () => void;
48
+ /**
49
+ * Callback when a tag is deleted/removed
50
+ */
51
+ onItemDelete?: (item: TagFilterItem) => void;
52
+ /**
53
+ * Callback when a tag is selected
54
+ */
55
+ onItemSelect?: (item: TagFilterItem) => void;
56
+ /**
57
+ * Callback when the Expand button is clicked
58
+ */
59
+ onExpand?: (expanded?: boolean) => void;
60
+ /**
61
+ * Additional CSS class names
62
+ */
63
+ className?: string;
64
+ /**
65
+ * Additional styles to apply to the component
66
+ */
67
+ style?: CSSProperties;
68
+ }
69
+ //#endregion
70
+ export { DsTagFilterProps, TagFilterItem };
71
+ //# sourceMappingURL=ds-tag-filter.types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ds-tag-filter.types.d.cts","names":[],"sources":["../../../src/components/ds-tag-filter/ds-tag-filter.types.ts"],"sourcesContent":[],"mappings":";;;;UAGiB,aAAA;;AAAjB;;EAqBgB,EAAA,EAAA,MAAA;EAAR;;AAIR;EAIQ,KAAA,EAAA,MAAA;EAkBe;;;EAgBD,QAAA,CAAA,EAnDV,MAmDU,CAAA,MAAA,EAAA,OAAA,CAAA;;;;;;;;;UA1Cd,QAAQ;;;UAIC,gBAAA;;;;SAIT;;;;;;;;;;;;;;;;;;wBAkBe;;;;wBAIA;;;;;;;;;;;;UAYd"}
@@ -0,0 +1,72 @@
1
+ import { DsTagProps } from "../ds-tag/ds-tag.types.js";
2
+ import "../ds-tag/index.js";
3
+ import { CSSProperties } from "react";
4
+
5
+ //#region src/components/ds-tag-filter/ds-tag-filter.types.d.ts
6
+ interface TagFilterItem {
7
+ /**
8
+ * Unique identifier for the tag
9
+ */
10
+ id: string;
11
+ /**
12
+ * The label text to display in the tag
13
+ */
14
+ label: string;
15
+ /**
16
+ * Additional metadata to store with the tag
17
+ */
18
+ metadata?: Record<string, unknown>;
19
+ /**
20
+ * Whether the tag is selected/checked
21
+ */
22
+ selected?: boolean;
23
+ /**
24
+ * Additional props to pass to the components
25
+ */
26
+ slotProps?: {
27
+ tag?: Partial<DsTagProps>;
28
+ };
29
+ }
30
+ interface DsTagFilterProps {
31
+ /**
32
+ * Array of tag items to display
33
+ */
34
+ items: TagFilterItem[];
35
+ /**
36
+ * Locale object (you can pass custom strings for localization)
37
+ */
38
+ locale?: {
39
+ label?: string;
40
+ clearButton?: string;
41
+ collapseTagLabel?: string;
42
+ hiddenCountSingular?: string;
43
+ hiddenCountPlural?: string;
44
+ };
45
+ /**
46
+ * Callback when "Clear all" is clicked
47
+ */
48
+ onClearAll?: () => void;
49
+ /**
50
+ * Callback when a tag is deleted/removed
51
+ */
52
+ onItemDelete?: (item: TagFilterItem) => void;
53
+ /**
54
+ * Callback when a tag is selected
55
+ */
56
+ onItemSelect?: (item: TagFilterItem) => void;
57
+ /**
58
+ * Callback when the Expand button is clicked
59
+ */
60
+ onExpand?: (expanded?: boolean) => void;
61
+ /**
62
+ * Additional CSS class names
63
+ */
64
+ className?: string;
65
+ /**
66
+ * Additional styles to apply to the component
67
+ */
68
+ style?: CSSProperties;
69
+ }
70
+ //#endregion
71
+ export { DsTagFilterProps, TagFilterItem };
72
+ //# sourceMappingURL=ds-tag-filter.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ds-tag-filter.types.d.ts","names":[],"sources":["../../../src/components/ds-tag-filter/ds-tag-filter.types.ts"],"sourcesContent":[],"mappings":";;;;;UAGiB,aAAA;;;AAAjB;EAYY,EAAA,EAAA,MAAA;EASI;;;EAIC,KAAA,EAAA,MAAA;EAIT;;;EAkCC,QAAA,CAAA,EAnDG,MAmDH,CAAA,MAAA,EAAA,OAAA,CAAA;EAAa;;;;;;;;UA1Cd,QAAQ;;;UAIC,gBAAA;;;;SAIT;;;;;;;;;;;;;;;;;;wBAkBe;;;;wBAIA;;;;;;;;;;;;UAYd"}
@@ -0,0 +1,137 @@
1
+ const require_rolldown_runtime = require('../../../_virtual/rolldown_runtime.cjs');
2
+ const require_utils = require('../utils.cjs');
3
+ let react_compiler_runtime = require("react/compiler-runtime");
4
+ let react = require("react");
5
+
6
+ //#region src/components/ds-tag-filter/hooks/use-tag-overflow-calculation.ts
7
+ const TAG_HOVER_BUTTON_SPACE = 20;
8
+ /**
9
+ * Custom hook to calculate how many tags can fit in 2 rows.
10
+ *
11
+ * Row 1: Label + Tags + Clear Button
12
+ * Row 2: Remaining Tags + Expand Tag (only if overflow)
13
+ *
14
+ * Measures actual element widths to determine optimal placement.
15
+ */
16
+ const useTagOverflowCalculation = (t0) => {
17
+ const $ = (0, react_compiler_runtime.c)(16);
18
+ const { containerRef, measurementRef, totalItems, expanded } = t0;
19
+ let t1;
20
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
21
+ t1 = {
22
+ row1TagCount: 0,
23
+ row2TagCount: 0,
24
+ hasOverflow: false
25
+ };
26
+ $[0] = t1;
27
+ } else t1 = $[0];
28
+ const [state, setState] = (0, react.useState)(t1);
29
+ let t2;
30
+ if ($[1] !== containerRef || $[2] !== measurementRef) {
31
+ t2 = () => {
32
+ if (!containerRef.current || !measurementRef.current) return;
33
+ const container = containerRef.current;
34
+ const measurementContainer = measurementRef.current;
35
+ const { tagWidths, labelWidth, clearButtonWidth, expandTagWidth, gap } = require_utils.getElementMeasurements(measurementContainer);
36
+ if (tagWidths.length === 0) {
37
+ setState({
38
+ row1TagCount: 0,
39
+ row2TagCount: 0,
40
+ hasOverflow: false
41
+ });
42
+ return;
43
+ }
44
+ const containerWidth = require_utils.getContainerAvailableWidth(container);
45
+ const row1Result = require_utils.fitTagsInRow(tagWidths, containerWidth - labelWidth - clearButtonWidth - TAG_HOVER_BUTTON_SPACE, gap);
46
+ const remainingTags = tagWidths.slice(row1Result.count);
47
+ if (remainingTags.length === 0) {
48
+ setState({
49
+ row1TagCount: row1Result.count,
50
+ row2TagCount: 0,
51
+ hasOverflow: false
52
+ });
53
+ return;
54
+ }
55
+ const row2WithExpandResult = require_utils.fitTagsInRow(remainingTags, containerWidth - expandTagWidth - TAG_HOVER_BUTTON_SPACE, gap);
56
+ if (remainingTags.length > row2WithExpandResult.count) setState({
57
+ row1TagCount: row1Result.count,
58
+ row2TagCount: row2WithExpandResult.count,
59
+ hasOverflow: true
60
+ });
61
+ else {
62
+ const row2FullResult = require_utils.fitTagsInRow(remainingTags, containerWidth - TAG_HOVER_BUTTON_SPACE, gap);
63
+ if (row2FullResult.count < remainingTags.length) setState({
64
+ row1TagCount: row1Result.count,
65
+ row2TagCount: row2WithExpandResult.count,
66
+ hasOverflow: true
67
+ });
68
+ else setState({
69
+ row1TagCount: row1Result.count,
70
+ row2TagCount: row2FullResult.count,
71
+ hasOverflow: false
72
+ });
73
+ }
74
+ };
75
+ $[1] = containerRef;
76
+ $[2] = measurementRef;
77
+ $[3] = t2;
78
+ } else t2 = $[3];
79
+ const calculateLayout = t2;
80
+ let t3;
81
+ if ($[4] !== calculateLayout || $[5] !== containerRef) {
82
+ t3 = () => {
83
+ const rafId = requestAnimationFrame(() => {
84
+ calculateLayout();
85
+ });
86
+ const resizeObserver = new ResizeObserver(() => {
87
+ requestAnimationFrame(() => {
88
+ calculateLayout();
89
+ });
90
+ });
91
+ if (containerRef.current) resizeObserver.observe(containerRef.current);
92
+ return () => {
93
+ cancelAnimationFrame(rafId);
94
+ resizeObserver.disconnect();
95
+ };
96
+ };
97
+ $[4] = calculateLayout;
98
+ $[5] = containerRef;
99
+ $[6] = t3;
100
+ } else t3 = $[6];
101
+ let t4;
102
+ if ($[7] !== calculateLayout || $[8] !== containerRef || $[9] !== expanded || $[10] !== measurementRef || $[11] !== totalItems) {
103
+ t4 = [
104
+ containerRef,
105
+ measurementRef,
106
+ totalItems,
107
+ expanded,
108
+ calculateLayout
109
+ ];
110
+ $[7] = calculateLayout;
111
+ $[8] = containerRef;
112
+ $[9] = expanded;
113
+ $[10] = measurementRef;
114
+ $[11] = totalItems;
115
+ $[12] = t4;
116
+ } else t4 = $[12];
117
+ (0, react.useLayoutEffect)(t3, t4);
118
+ if (expanded) {
119
+ const t5 = totalItems - state.row1TagCount;
120
+ let t6;
121
+ if ($[13] !== state.row1TagCount || $[14] !== t5) {
122
+ t6 = {
123
+ row1TagCount: state.row1TagCount,
124
+ row2TagCount: t5,
125
+ hasOverflow: true
126
+ };
127
+ $[13] = state.row1TagCount;
128
+ $[14] = t5;
129
+ $[15] = t6;
130
+ } else t6 = $[15];
131
+ return t6;
132
+ }
133
+ return state;
134
+ };
135
+
136
+ //#endregion
137
+ exports.useTagOverflowCalculation = useTagOverflowCalculation;
@@ -0,0 +1,137 @@
1
+ import { fitTagsInRow, getContainerAvailableWidth, getElementMeasurements } from "../utils.js";
2
+ import { c } from "react/compiler-runtime";
3
+ import { useLayoutEffect, useState } from "react";
4
+
5
+ //#region src/components/ds-tag-filter/hooks/use-tag-overflow-calculation.ts
6
+ const TAG_HOVER_BUTTON_SPACE = 20;
7
+ /**
8
+ * Custom hook to calculate how many tags can fit in 2 rows.
9
+ *
10
+ * Row 1: Label + Tags + Clear Button
11
+ * Row 2: Remaining Tags + Expand Tag (only if overflow)
12
+ *
13
+ * Measures actual element widths to determine optimal placement.
14
+ */
15
+ const useTagOverflowCalculation = (t0) => {
16
+ const $ = c(16);
17
+ const { containerRef, measurementRef, totalItems, expanded } = t0;
18
+ let t1;
19
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
20
+ t1 = {
21
+ row1TagCount: 0,
22
+ row2TagCount: 0,
23
+ hasOverflow: false
24
+ };
25
+ $[0] = t1;
26
+ } else t1 = $[0];
27
+ const [state, setState] = useState(t1);
28
+ let t2;
29
+ if ($[1] !== containerRef || $[2] !== measurementRef) {
30
+ t2 = () => {
31
+ if (!containerRef.current || !measurementRef.current) return;
32
+ const container = containerRef.current;
33
+ const measurementContainer = measurementRef.current;
34
+ const { tagWidths, labelWidth, clearButtonWidth, expandTagWidth, gap } = getElementMeasurements(measurementContainer);
35
+ if (tagWidths.length === 0) {
36
+ setState({
37
+ row1TagCount: 0,
38
+ row2TagCount: 0,
39
+ hasOverflow: false
40
+ });
41
+ return;
42
+ }
43
+ const containerWidth = getContainerAvailableWidth(container);
44
+ const row1Result = fitTagsInRow(tagWidths, containerWidth - labelWidth - clearButtonWidth - TAG_HOVER_BUTTON_SPACE, gap);
45
+ const remainingTags = tagWidths.slice(row1Result.count);
46
+ if (remainingTags.length === 0) {
47
+ setState({
48
+ row1TagCount: row1Result.count,
49
+ row2TagCount: 0,
50
+ hasOverflow: false
51
+ });
52
+ return;
53
+ }
54
+ const row2WithExpandResult = fitTagsInRow(remainingTags, containerWidth - expandTagWidth - TAG_HOVER_BUTTON_SPACE, gap);
55
+ if (remainingTags.length > row2WithExpandResult.count) setState({
56
+ row1TagCount: row1Result.count,
57
+ row2TagCount: row2WithExpandResult.count,
58
+ hasOverflow: true
59
+ });
60
+ else {
61
+ const row2FullResult = fitTagsInRow(remainingTags, containerWidth - TAG_HOVER_BUTTON_SPACE, gap);
62
+ if (row2FullResult.count < remainingTags.length) setState({
63
+ row1TagCount: row1Result.count,
64
+ row2TagCount: row2WithExpandResult.count,
65
+ hasOverflow: true
66
+ });
67
+ else setState({
68
+ row1TagCount: row1Result.count,
69
+ row2TagCount: row2FullResult.count,
70
+ hasOverflow: false
71
+ });
72
+ }
73
+ };
74
+ $[1] = containerRef;
75
+ $[2] = measurementRef;
76
+ $[3] = t2;
77
+ } else t2 = $[3];
78
+ const calculateLayout = t2;
79
+ let t3;
80
+ if ($[4] !== calculateLayout || $[5] !== containerRef) {
81
+ t3 = () => {
82
+ const rafId = requestAnimationFrame(() => {
83
+ calculateLayout();
84
+ });
85
+ const resizeObserver = new ResizeObserver(() => {
86
+ requestAnimationFrame(() => {
87
+ calculateLayout();
88
+ });
89
+ });
90
+ if (containerRef.current) resizeObserver.observe(containerRef.current);
91
+ return () => {
92
+ cancelAnimationFrame(rafId);
93
+ resizeObserver.disconnect();
94
+ };
95
+ };
96
+ $[4] = calculateLayout;
97
+ $[5] = containerRef;
98
+ $[6] = t3;
99
+ } else t3 = $[6];
100
+ let t4;
101
+ if ($[7] !== calculateLayout || $[8] !== containerRef || $[9] !== expanded || $[10] !== measurementRef || $[11] !== totalItems) {
102
+ t4 = [
103
+ containerRef,
104
+ measurementRef,
105
+ totalItems,
106
+ expanded,
107
+ calculateLayout
108
+ ];
109
+ $[7] = calculateLayout;
110
+ $[8] = containerRef;
111
+ $[9] = expanded;
112
+ $[10] = measurementRef;
113
+ $[11] = totalItems;
114
+ $[12] = t4;
115
+ } else t4 = $[12];
116
+ useLayoutEffect(t3, t4);
117
+ if (expanded) {
118
+ const t5 = totalItems - state.row1TagCount;
119
+ let t6;
120
+ if ($[13] !== state.row1TagCount || $[14] !== t5) {
121
+ t6 = {
122
+ row1TagCount: state.row1TagCount,
123
+ row2TagCount: t5,
124
+ hasOverflow: true
125
+ };
126
+ $[13] = state.row1TagCount;
127
+ $[14] = t5;
128
+ $[15] = t6;
129
+ } else t6 = $[15];
130
+ return t6;
131
+ }
132
+ return state;
133
+ };
134
+
135
+ //#endregion
136
+ export { useTagOverflowCalculation };
137
+ //# sourceMappingURL=use-tag-overflow-calculation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tag-overflow-calculation.js","names":["RefObject","useCallback","useLayoutEffect","useState","fitTagsInRow","getContainerAvailableWidth","getElementMeasurements","UseTagOverflowCalculationOptions","containerRef","HTMLDivElement","measurementRef","totalItems","expanded","UseTagOverflowCalculationResult","row1TagCount","row2TagCount","hasOverflow","TAG_HOVER_BUTTON_SPACE","useTagOverflowCalculation","t0","$","_c","t1","Symbol","for","state","setState","t2","current","container","measurementContainer","tagWidths","labelWidth","clearButtonWidth","expandTagWidth","gap","length","containerWidth","row1AvailableWidth","row1Result","remainingTags","slice","count","row2AvailableWithExpand","row2WithExpandResult","overflowExists","row2AvailableWithoutExpand","row2FullResult","calculateLayout","t3","rafId","requestAnimationFrame","resizeObserver","ResizeObserver","observe","cancelAnimationFrame","disconnect","t4","t5","t6"],"sources":["../../../../src/components/ds-tag-filter/hooks/use-tag-overflow-calculation.ts"],"sourcesContent":["import { type RefObject, useCallback, useLayoutEffect, useState } from 'react';\nimport { fitTagsInRow, getContainerAvailableWidth, getElementMeasurements } from '../utils';\n\ninterface UseTagOverflowCalculationOptions {\n\tcontainerRef: RefObject<HTMLDivElement | null>;\n\tmeasurementRef: RefObject<HTMLDivElement | null>;\n\ttotalItems: number;\n\texpanded: boolean;\n}\n\ninterface UseTagOverflowCalculationResult {\n\trow1TagCount: number;\n\trow2TagCount: number;\n\thasOverflow: boolean;\n}\n\n// Extra space needed per row for animated delete button that appears on hover\nconst TAG_HOVER_BUTTON_SPACE = 20;\n\n/**\n * Custom hook to calculate how many tags can fit in 2 rows.\n *\n * Row 1: Label + Tags + Clear Button\n * Row 2: Remaining Tags + Expand Tag (only if overflow)\n *\n * Measures actual element widths to determine optimal placement.\n */\nexport const useTagOverflowCalculation = ({\n\tcontainerRef,\n\tmeasurementRef,\n\ttotalItems,\n\texpanded,\n}: UseTagOverflowCalculationOptions): UseTagOverflowCalculationResult => {\n\tconst [state, setState] = useState<UseTagOverflowCalculationResult>({\n\t\trow1TagCount: 0,\n\t\trow2TagCount: 0,\n\t\thasOverflow: false,\n\t});\n\n\tconst calculateLayout = useCallback(() => {\n\t\tif (!containerRef.current || !measurementRef.current) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst container = containerRef.current;\n\t\tconst measurementContainer = measurementRef.current;\n\n\t\tconst { tagWidths, labelWidth, clearButtonWidth, expandTagWidth, gap } =\n\t\t\tgetElementMeasurements(measurementContainer);\n\n\t\tif (tagWidths.length === 0) {\n\t\t\tsetState({ row1TagCount: 0, row2TagCount: 0, hasOverflow: false });\n\t\t\treturn;\n\t\t}\n\n\t\tconst containerWidth = getContainerAvailableWidth(container);\n\n\t\t// Calculate Row 1 available space (Label + Tags + Clear Button)\n\t\tconst row1AvailableWidth = containerWidth - labelWidth - clearButtonWidth - TAG_HOVER_BUTTON_SPACE;\n\n\t\t// Calculate how many tags fit in Row 1\n\t\tconst row1Result = fitTagsInRow(tagWidths, row1AvailableWidth, gap);\n\t\tconst remainingTags = tagWidths.slice(row1Result.count);\n\n\t\tif (remainingTags.length === 0) {\n\t\t\t// All tags fit in Row 1, no overflow\n\t\t\tsetState({ row1TagCount: row1Result.count, row2TagCount: 0, hasOverflow: false });\n\t\t\treturn;\n\t\t}\n\n\t\t// Calculate with expand tag reserved (pessimistic)\n\t\tconst row2AvailableWithExpand = containerWidth - expandTagWidth - TAG_HOVER_BUTTON_SPACE;\n\t\tconst row2WithExpandResult = fitTagsInRow(remainingTags, row2AvailableWithExpand, gap);\n\n\t\t// Check if there's overflow (more remaining tags than fit in Row 2 with expand)\n\t\tconst overflowExists = remainingTags.length > row2WithExpandResult.count;\n\n\t\tif (overflowExists) {\n\t\t\t// Use the count with expand tag space reserved\n\t\t\tsetState({\n\t\t\t\trow1TagCount: row1Result.count,\n\t\t\t\trow2TagCount: row2WithExpandResult.count,\n\t\t\t\thasOverflow: true,\n\t\t\t});\n\t\t} else {\n\t\t\t// No overflow - recalculate Row 2 without reserving expand tag space\n\t\t\tconst row2AvailableWithoutExpand = containerWidth - TAG_HOVER_BUTTON_SPACE;\n\t\t\tconst row2FullResult = fitTagsInRow(remainingTags, row2AvailableWithoutExpand, gap);\n\n\t\t\t// Double-check: if even without expand tag we can't fit all, we have overflow\n\t\t\tif (row2FullResult.count < remainingTags.length) {\n\t\t\t\tsetState({\n\t\t\t\t\trow1TagCount: row1Result.count,\n\t\t\t\t\trow2TagCount: row2WithExpandResult.count,\n\t\t\t\t\thasOverflow: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tsetState({ row1TagCount: row1Result.count, row2TagCount: row2FullResult.count, hasOverflow: false });\n\t\t\t}\n\t\t}\n\t}, [containerRef, measurementRef]);\n\n\tuseLayoutEffect(() => {\n\t\t// Use requestAnimationFrame to ensure DOM is fully laid out\n\t\tconst rafId = requestAnimationFrame(() => {\n\t\t\tcalculateLayout();\n\t\t});\n\n\t\tconst resizeObserver = new ResizeObserver(() => {\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tcalculateLayout();\n\t\t\t});\n\t\t});\n\n\t\tif (containerRef.current) {\n\t\t\tresizeObserver.observe(containerRef.current);\n\t\t}\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(rafId);\n\t\t\tresizeObserver.disconnect();\n\t\t};\n\t}, [containerRef, measurementRef, totalItems, expanded, calculateLayout]);\n\n\t// When expanded, show all tags\n\tif (expanded) {\n\t\treturn {\n\t\t\trow1TagCount: state.row1TagCount,\n\t\t\trow2TagCount: totalItems - state.row1TagCount,\n\t\t\thasOverflow: true, // Keep expand button visible to allow collapse\n\t\t};\n\t}\n\n\treturn state;\n};\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ const require_ds_tag_filter = require('./ds-tag-filter.cjs');
@@ -0,0 +1,2 @@
1
+ import { DsTagFilterProps, TagFilterItem } from "./ds-tag-filter.types.js";
2
+ import { DsTagFilter } from "./ds-tag-filter.js";
@@ -0,0 +1 @@
1
+ import ds_tag_filter_default from "./ds-tag-filter.js";
@@ -0,0 +1,54 @@
1
+
2
+ //#region src/components/ds-tag-filter/utils.ts
3
+ /**
4
+ * Calculate how many tags fit within the available width.
5
+ * Pure function for easy testing.
6
+ */
7
+ function fitTagsInRow(tagWidths, availableWidth, gap) {
8
+ let usedWidth = 0;
9
+ let count = 0;
10
+ for (const tagWidth of tagWidths) {
11
+ const widthWithGap = tagWidth + (count > 0 ? gap : 0);
12
+ if (usedWidth + widthWithGap <= availableWidth) {
13
+ usedWidth += widthWithGap;
14
+ count++;
15
+ } else break;
16
+ }
17
+ return {
18
+ count,
19
+ usedWidth
20
+ };
21
+ }
22
+ /**
23
+ * Calculate the available width inside a container, accounting for padding.
24
+ */
25
+ function getContainerAvailableWidth(container) {
26
+ const containerRect = container.getBoundingClientRect();
27
+ const containerStyle = getComputedStyle(container);
28
+ const paddingLeft = parseFloat(containerStyle.paddingLeft) || 0;
29
+ const paddingRight = parseFloat(containerStyle.paddingRight) || 0;
30
+ return containerRect.width - paddingLeft - paddingRight;
31
+ }
32
+ /**
33
+ * Measure all relevant elements (tags, label, buttons) inside the measurement container.
34
+ */
35
+ function getElementMeasurements(measurementContainer) {
36
+ const tags = Array.from(measurementContainer.querySelectorAll("[data-measure-tag]"));
37
+ const label = measurementContainer.querySelector("[data-measure-label]");
38
+ const clearButton = measurementContainer.querySelector("[data-measure-clear]");
39
+ const expandTag = measurementContainer.querySelector("[data-measure-expand]");
40
+ const computedStyle = getComputedStyle(measurementContainer);
41
+ const gap = parseFloat(computedStyle.gap) || 8;
42
+ return {
43
+ tagWidths: tags.map((tag) => tag.getBoundingClientRect().width),
44
+ labelWidth: label ? label.getBoundingClientRect().width + gap : 0,
45
+ clearButtonWidth: clearButton ? clearButton.getBoundingClientRect().width + gap : 0,
46
+ expandTagWidth: expandTag ? expandTag.getBoundingClientRect().width + gap : 100,
47
+ gap
48
+ };
49
+ }
50
+
51
+ //#endregion
52
+ exports.fitTagsInRow = fitTagsInRow;
53
+ exports.getContainerAvailableWidth = getContainerAvailableWidth;
54
+ exports.getElementMeasurements = getElementMeasurements;
@@ -0,0 +1,52 @@
1
+ //#region src/components/ds-tag-filter/utils.ts
2
+ /**
3
+ * Calculate how many tags fit within the available width.
4
+ * Pure function for easy testing.
5
+ */
6
+ function fitTagsInRow(tagWidths, availableWidth, gap) {
7
+ let usedWidth = 0;
8
+ let count = 0;
9
+ for (const tagWidth of tagWidths) {
10
+ const widthWithGap = tagWidth + (count > 0 ? gap : 0);
11
+ if (usedWidth + widthWithGap <= availableWidth) {
12
+ usedWidth += widthWithGap;
13
+ count++;
14
+ } else break;
15
+ }
16
+ return {
17
+ count,
18
+ usedWidth
19
+ };
20
+ }
21
+ /**
22
+ * Calculate the available width inside a container, accounting for padding.
23
+ */
24
+ function getContainerAvailableWidth(container) {
25
+ const containerRect = container.getBoundingClientRect();
26
+ const containerStyle = getComputedStyle(container);
27
+ const paddingLeft = parseFloat(containerStyle.paddingLeft) || 0;
28
+ const paddingRight = parseFloat(containerStyle.paddingRight) || 0;
29
+ return containerRect.width - paddingLeft - paddingRight;
30
+ }
31
+ /**
32
+ * Measure all relevant elements (tags, label, buttons) inside the measurement container.
33
+ */
34
+ function getElementMeasurements(measurementContainer) {
35
+ const tags = Array.from(measurementContainer.querySelectorAll("[data-measure-tag]"));
36
+ const label = measurementContainer.querySelector("[data-measure-label]");
37
+ const clearButton = measurementContainer.querySelector("[data-measure-clear]");
38
+ const expandTag = measurementContainer.querySelector("[data-measure-expand]");
39
+ const computedStyle = getComputedStyle(measurementContainer);
40
+ const gap = parseFloat(computedStyle.gap) || 8;
41
+ return {
42
+ tagWidths: tags.map((tag) => tag.getBoundingClientRect().width),
43
+ labelWidth: label ? label.getBoundingClientRect().width + gap : 0,
44
+ clearButtonWidth: clearButton ? clearButton.getBoundingClientRect().width + gap : 0,
45
+ expandTagWidth: expandTag ? expandTag.getBoundingClientRect().width + gap : 100,
46
+ gap
47
+ };
48
+ }
49
+
50
+ //#endregion
51
+ export { fitTagsInRow, getContainerAvailableWidth, getElementMeasurements };
52
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":["FitTagsResult","count","usedWidth","ElementMeasurements","tagWidths","labelWidth","clearButtonWidth","expandTagWidth","gap","fitTagsInRow","availableWidth","tagWidth","widthWithGap","getContainerAvailableWidth","container","HTMLDivElement","containerRect","getBoundingClientRect","containerStyle","getComputedStyle","paddingLeft","parseFloat","paddingRight","width","getElementMeasurements","measurementContainer","tags","Array","from","querySelectorAll","label","querySelector","clearButton","expandTag","computedStyle","map","tag"],"sources":["../../../src/components/ds-tag-filter/utils.ts"],"sourcesContent":["export interface FitTagsResult {\n\tcount: number;\n\tusedWidth: number;\n}\n\nexport interface ElementMeasurements {\n\ttagWidths: number[];\n\tlabelWidth: number;\n\tclearButtonWidth: number;\n\texpandTagWidth: number;\n\tgap: number;\n}\n\n/**\n * Calculate how many tags fit within the available width.\n * Pure function for easy testing.\n */\nexport function fitTagsInRow(tagWidths: number[], availableWidth: number, gap: number): FitTagsResult {\n\tlet usedWidth = 0;\n\tlet count = 0;\n\n\tfor (const tagWidth of tagWidths) {\n\t\tconst widthWithGap = tagWidth + (count > 0 ? gap : 0);\n\t\tif (usedWidth + widthWithGap <= availableWidth) {\n\t\t\tusedWidth += widthWithGap;\n\t\t\tcount++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn { count, usedWidth };\n}\n\n/**\n * Calculate the available width inside a container, accounting for padding.\n */\nexport function getContainerAvailableWidth(container: HTMLDivElement): number {\n\tconst containerRect = container.getBoundingClientRect();\n\tconst containerStyle = getComputedStyle(container);\n\tconst paddingLeft = parseFloat(containerStyle.paddingLeft) || 0;\n\tconst paddingRight = parseFloat(containerStyle.paddingRight) || 0;\n\treturn containerRect.width - paddingLeft - paddingRight;\n}\n\n/**\n * Measure all relevant elements (tags, label, buttons) inside the measurement container.\n */\nexport function getElementMeasurements(measurementContainer: HTMLDivElement): ElementMeasurements {\n\tconst tags = Array.from(measurementContainer.querySelectorAll('[data-measure-tag]'));\n\tconst label = measurementContainer.querySelector('[data-measure-label]');\n\tconst clearButton = measurementContainer.querySelector('[data-measure-clear]');\n\tconst expandTag = measurementContainer.querySelector('[data-measure-expand]');\n\n\tconst computedStyle = getComputedStyle(measurementContainer);\n\tconst gap = parseFloat(computedStyle.gap) || 8;\n\n\tconst tagWidths = tags.map((tag) => tag.getBoundingClientRect().width);\n\tconst labelWidth = label ? label.getBoundingClientRect().width + gap : 0;\n\tconst clearButtonWidth = clearButton ? clearButton.getBoundingClientRect().width + gap : 0;\n\t// Fallback width for expand tag (~100px for \"+99 filters\" text) if measurement fails\n\tconst expandTagWidth = expandTag ? expandTag.getBoundingClientRect().width + gap : 100;\n\n\treturn { tagWidths, labelWidth, clearButtonWidth, expandTagWidth, gap };\n}\n"],"mappings":";;;;;AAiBA,SAAgBS,aAAaL,WAAqBM,gBAAwBF,KAA4B;CACrG,IAAIN,YAAY;CAChB,IAAID,QAAQ;AAEZ,MAAK,MAAMU,YAAYP,WAAW;EACjC,MAAMQ,eAAeD,YAAYV,QAAQ,IAAIO,MAAM;AACnD,MAAIN,YAAYU,gBAAgBF,gBAAgB;AAC/CR,gBAAaU;AACbX;QAEA;;AAIF,QAAO;EAAEA;EAAOC;EAAW;;;;;AAM5B,SAAgBW,2BAA2BC,WAAmC;CAC7E,MAAME,gBAAgBF,UAAUG,uBAAuB;CACvD,MAAMC,iBAAiBC,iBAAiBL,UAAU;CAClD,MAAMM,cAAcC,WAAWH,eAAeE,YAAY,IAAI;CAC9D,MAAME,eAAeD,WAAWH,eAAeI,aAAa,IAAI;AAChE,QAAON,cAAcO,QAAQH,cAAcE;;;;;AAM5C,SAAgBE,uBAAuBC,sBAA2D;CACjG,MAAMC,OAAOC,MAAMC,KAAKH,qBAAqBI,iBAAiB,qBAAqB,CAAC;CACpF,MAAMC,QAAQL,qBAAqBM,cAAc,uBAAuB;CACxE,MAAMC,cAAcP,qBAAqBM,cAAc,uBAAuB;CAC9E,MAAME,YAAYR,qBAAqBM,cAAc,wBAAwB;CAE7E,MAAMG,gBAAgBf,iBAAiBM,qBAAqB;CAC5D,MAAMjB,MAAMa,WAAWa,cAAc1B,IAAI,IAAI;AAQ7C,QAAO;EAAEJ,WANSsB,KAAKS,KAAKC,QAAQA,IAAInB,uBAAuB,CAACM,MAAM;EAMlDlB,YALDyB,QAAQA,MAAMb,uBAAuB,CAACM,QAAQf,MAAM;EAKvCF,kBAJP0B,cAAcA,YAAYf,uBAAuB,CAACM,QAAQf,MAAM;EAIvCD,gBAF3B0B,YAAYA,UAAUhB,uBAAuB,CAACM,QAAQf,MAAM;EAEjBA;EAAK"}