fds-vue-core 2.0.88 → 2.1.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 (331) hide show
  1. package/README.md +1 -0
  2. package/configs/eslint.config.base.js +262 -0
  3. package/configs/prettier.config.js +13 -0
  4. package/configs/tsconfig.base.json +17 -0
  5. package/configs/vscode-settings.json +74 -0
  6. package/dist/fds-vue-core.cjs.js +5367 -5374
  7. package/dist/fds-vue-core.cjs.js.map +1 -1
  8. package/dist/fds-vue-core.es.js +5368 -5375
  9. package/dist/fds-vue-core.es.js.map +1 -1
  10. package/dist/global-components.d.ts +36 -36
  11. package/dist/index.d.ts +2 -80
  12. package/dist/slot-styles.css +1 -1
  13. package/dist/tokens.css +0 -1
  14. package/package.json +15 -6
  15. package/src/.DS_Store +0 -0
  16. package/src/App.vue +133 -0
  17. package/src/apply.css +60 -0
  18. package/src/assets/icons.ts +517 -0
  19. package/src/components/Blocks/FdsBlockAlert/FdsBlockAlert.stories.ts +94 -0
  20. package/src/components/Blocks/FdsBlockAlert/FdsBlockAlert.vue +112 -0
  21. package/src/components/Blocks/FdsBlockAlert/types.ts +12 -0
  22. package/src/components/Blocks/FdsBlockContent/FdsBlockContent.stories.ts +110 -0
  23. package/src/components/Blocks/FdsBlockContent/FdsBlockContent.vue +66 -0
  24. package/src/components/Blocks/FdsBlockContent/types.ts +6 -0
  25. package/src/components/Blocks/FdsBlockExpander/FdsBlockExpander.stories.ts +123 -0
  26. package/src/components/Blocks/FdsBlockExpander/FdsBlockExpander.vue +87 -0
  27. package/src/components/Blocks/FdsBlockExpander/types.ts +8 -0
  28. package/src/components/Blocks/FdsBlockInfo/FdsBlockInfo.stories.ts +110 -0
  29. package/src/components/Blocks/FdsBlockInfo/FdsBlockInfo.vue +98 -0
  30. package/src/components/Blocks/FdsBlockInfo/types.ts +8 -0
  31. package/src/components/Blocks/FdsBlockLink/FdsBlockLink.css +9 -0
  32. package/src/components/Blocks/FdsBlockLink/FdsBlockLink.stories.ts +179 -0
  33. package/src/components/Blocks/FdsBlockLink/FdsBlockLink.vue +149 -0
  34. package/src/components/Blocks/FdsBlockLink/types.ts +14 -0
  35. package/src/components/Buttons/ButtonBaseProps.ts +18 -0
  36. package/src/components/Buttons/FdsButtonCopy/FdsButtonCopy.stories.ts +53 -0
  37. package/src/components/Buttons/FdsButtonCopy/FdsButtonCopy.vue +87 -0
  38. package/src/components/Buttons/FdsButtonCopy/types.ts +8 -0
  39. package/src/components/Buttons/FdsButtonDownload/FdsButtonDownload.stories.ts +111 -0
  40. package/src/components/Buttons/FdsButtonDownload/FdsButtonDownload.vue +187 -0
  41. package/src/components/Buttons/FdsButtonIcon/FdsButtonIcon.stories.ts +55 -0
  42. package/src/components/Buttons/FdsButtonIcon/FdsButtonIcon.vue +57 -0
  43. package/src/components/Buttons/FdsButtonIcon/types.ts +12 -0
  44. package/src/components/Buttons/FdsButtonMinor/FdsButtonMinor.stories.ts +68 -0
  45. package/src/components/Buttons/FdsButtonMinor/FdsButtonMinor.vue +126 -0
  46. package/src/components/Buttons/FdsButtonPrimary/FdsButtonPrimary.stories.ts +86 -0
  47. package/src/components/Buttons/FdsButtonPrimary/FdsButtonPrimary.vue +107 -0
  48. package/src/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.stories.ts +68 -0
  49. package/src/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.vue +107 -0
  50. package/src/components/FdsIcon/FdsIcon.stories.ts +69 -0
  51. package/src/components/FdsIcon/FdsIcon.vue +34 -0
  52. package/src/components/FdsIcon/types.ts +9 -0
  53. package/src/components/FdsModal/FdsModal.stories.ts +241 -0
  54. package/src/components/FdsModal/FdsModal.vue +261 -0
  55. package/src/components/FdsModal/types.ts +12 -0
  56. package/src/components/FdsPagination/FdsPagination.stories.ts +109 -0
  57. package/src/components/FdsPagination/FdsPagination.vue +193 -0
  58. package/src/components/FdsPagination/types.ts +6 -0
  59. package/src/components/FdsSearchSelect/FdsSearchSelect.stories.ts +428 -0
  60. package/src/components/FdsSearchSelect/FdsSearchSelect.vue +610 -0
  61. package/src/components/FdsSearchSelect/types.ts +25 -0
  62. package/src/components/FdsSpinner/FdsSpinner.stories.ts +31 -0
  63. package/src/components/FdsSpinner/FdsSpinner.vue +90 -0
  64. package/src/components/FdsSpinner/types.ts +6 -0
  65. package/src/components/FdsSticker/FdsSticker.stories.ts +148 -0
  66. package/src/components/FdsSticker/FdsSticker.vue +44 -0
  67. package/src/components/FdsSticker/types.ts +4 -0
  68. package/src/components/FdsTreeView/FdsTreeView.stories.ts +136 -0
  69. package/src/components/FdsTreeView/FdsTreeView.vue +162 -0
  70. package/src/components/FdsTreeView/TreeNode.vue +383 -0
  71. package/src/components/FdsTreeView/types.ts +141 -0
  72. package/src/components/FdsTreeView/useTreeState.ts +607 -0
  73. package/src/components/FdsTreeView/utils.ts +65 -0
  74. package/src/components/FdsTruncatedText/FdsTruncatedText.stories.ts +78 -0
  75. package/src/components/FdsTruncatedText/FdsTruncatedText.vue +85 -0
  76. package/src/components/FdsTruncatedText/types.ts +6 -0
  77. package/src/components/Form/FdsCheckbox/FdsCheckbox.stories.ts +275 -0
  78. package/src/components/Form/FdsCheckbox/FdsCheckbox.vue +155 -0
  79. package/src/components/Form/FdsCheckbox/types.ts +10 -0
  80. package/src/components/Form/FdsInput/FdsInput.stories.ts +319 -0
  81. package/src/components/Form/FdsInput/FdsInput.vue +233 -0
  82. package/src/components/Form/FdsInput/types.ts +25 -0
  83. package/src/components/Form/FdsRadio/FdsRadio.stories.ts +63 -0
  84. package/src/components/Form/FdsRadio/FdsRadio.vue +88 -0
  85. package/src/components/Form/FdsRadio/types.ts +12 -0
  86. package/src/components/Form/FdsSelect/FdsSelect.stories.ts +78 -0
  87. package/src/components/Form/FdsSelect/FdsSelect.vue +136 -0
  88. package/src/components/Form/FdsSelect/types.ts +13 -0
  89. package/src/components/Form/FdsTextarea/FdsTextarea.stories.ts +52 -0
  90. package/src/components/Form/FdsTextarea/FdsTextarea.vue +110 -0
  91. package/src/components/Form/FdsTextarea/types.ts +12 -0
  92. package/src/components/Table/FdsTable/FdsTable.stories.ts +221 -0
  93. package/src/components/Table/FdsTable/FdsTable.vue +25 -0
  94. package/src/components/Table/FdsTable/types.ts +4 -0
  95. package/src/components/Table/FdsTableHead/FdsTableHead.stories.ts +151 -0
  96. package/src/components/Table/FdsTableHead/FdsTableHead.vue +54 -0
  97. package/src/components/Table/FdsTableHead/types.ts +5 -0
  98. package/src/components/Tabs/FdsTabs/FdsTabs.stories.ts +247 -0
  99. package/src/components/Tabs/FdsTabs/FdsTabs.vue +27 -0
  100. package/src/components/Tabs/FdsTabs/types.ts +4 -0
  101. package/src/components/Tabs/FdsTabsItem/FdsTabsItem.vue +125 -0
  102. package/src/components/Tabs/FdsTabsItem/types.ts +16 -0
  103. package/src/components/Typography/FdsHeading/FdsHeading.stories.ts +93 -0
  104. package/src/components/Typography/FdsHeading/FdsHeading.vue +51 -0
  105. package/src/components/Typography/FdsHeading/types.ts +5 -0
  106. package/src/components/Typography/FdsListHeading/FdsListHeading.stories.ts +58 -0
  107. package/src/components/Typography/FdsListHeading/FdsListHeading.vue +62 -0
  108. package/src/components/Typography/FdsListHeading/types.ts +8 -0
  109. package/src/components/Typography/FdsSeparator/FdsSeparator.stories.ts +31 -0
  110. package/src/components/Typography/FdsSeparator/FdsSeparator.vue +5 -0
  111. package/src/components/Typography/FdsText/FdsText.stories.ts +66 -0
  112. package/src/components/Typography/FdsText/FdsText.vue +28 -0
  113. package/src/components/Typography/FdsText/types.ts +3 -0
  114. package/src/composables/useBoldQuery.ts +29 -0
  115. package/src/composables/useElementFinalSize.ts +24 -0
  116. package/src/composables/useHasSlots.ts +17 -0
  117. package/src/composables/useIsPid.ts +48 -0
  118. package/src/docs/Start/Start.mdx +12 -0
  119. package/src/docs/Usage.md +117 -0
  120. package/src/fonts.css +28 -0
  121. package/src/global-components.ts +38 -0
  122. package/src/index.ts +180 -0
  123. package/src/main.ts +7 -0
  124. package/src/slot-styles.css +93 -0
  125. package/src/style.css +89 -0
  126. package/src/tokens.css +252 -0
  127. package/tsconfig.base.json +4 -0
  128. package/dist/App.vue.d.ts +0 -3
  129. package/dist/App.vue.d.ts.map +0 -1
  130. package/dist/assets/icons.d.ts +0 -5
  131. package/dist/assets/icons.d.ts.map +0 -1
  132. package/dist/components/Blocks/FdsBlockAlert/FdsBlockAlert.stories.d.ts +0 -9
  133. package/dist/components/Blocks/FdsBlockAlert/FdsBlockAlert.stories.d.ts.map +0 -1
  134. package/dist/components/Blocks/FdsBlockAlert/FdsBlockAlert.vue.d.ts +0 -30
  135. package/dist/components/Blocks/FdsBlockAlert/FdsBlockAlert.vue.d.ts.map +0 -1
  136. package/dist/components/Blocks/FdsBlockAlert/types.d.ts +0 -12
  137. package/dist/components/Blocks/FdsBlockAlert/types.d.ts.map +0 -1
  138. package/dist/components/Blocks/FdsBlockContent/FdsBlockContent.stories.d.ts +0 -9
  139. package/dist/components/Blocks/FdsBlockContent/FdsBlockContent.stories.d.ts.map +0 -1
  140. package/dist/components/Blocks/FdsBlockContent/FdsBlockContent.vue.d.ts +0 -19
  141. package/dist/components/Blocks/FdsBlockContent/FdsBlockContent.vue.d.ts.map +0 -1
  142. package/dist/components/Blocks/FdsBlockContent/types.d.ts +0 -7
  143. package/dist/components/Blocks/FdsBlockContent/types.d.ts.map +0 -1
  144. package/dist/components/Blocks/FdsBlockExpander/FdsBlockExpander.stories.d.ts +0 -11
  145. package/dist/components/Blocks/FdsBlockExpander/FdsBlockExpander.stories.d.ts.map +0 -1
  146. package/dist/components/Blocks/FdsBlockExpander/FdsBlockExpander.vue.d.ts +0 -23
  147. package/dist/components/Blocks/FdsBlockExpander/FdsBlockExpander.vue.d.ts.map +0 -1
  148. package/dist/components/Blocks/FdsBlockExpander/types.d.ts +0 -8
  149. package/dist/components/Blocks/FdsBlockExpander/types.d.ts.map +0 -1
  150. package/dist/components/Blocks/FdsBlockInfo/FdsBlockInfo.stories.d.ts +0 -9
  151. package/dist/components/Blocks/FdsBlockInfo/FdsBlockInfo.stories.d.ts.map +0 -1
  152. package/dist/components/Blocks/FdsBlockInfo/FdsBlockInfo.vue.d.ts +0 -20
  153. package/dist/components/Blocks/FdsBlockInfo/FdsBlockInfo.vue.d.ts.map +0 -1
  154. package/dist/components/Blocks/FdsBlockInfo/types.d.ts +0 -8
  155. package/dist/components/Blocks/FdsBlockInfo/types.d.ts.map +0 -1
  156. package/dist/components/Blocks/FdsBlockLink/FdsBlockLink.stories.d.ts +0 -14
  157. package/dist/components/Blocks/FdsBlockLink/FdsBlockLink.stories.d.ts.map +0 -1
  158. package/dist/components/Blocks/FdsBlockLink/FdsBlockLink.vue.d.ts +0 -30
  159. package/dist/components/Blocks/FdsBlockLink/FdsBlockLink.vue.d.ts.map +0 -1
  160. package/dist/components/Blocks/FdsBlockLink/types.d.ts +0 -14
  161. package/dist/components/Blocks/FdsBlockLink/types.d.ts.map +0 -1
  162. package/dist/components/Buttons/ButtonBaseProps.d.ts +0 -18
  163. package/dist/components/Buttons/ButtonBaseProps.d.ts.map +0 -1
  164. package/dist/components/Buttons/FdsButtonCopy/FdsButtonCopy.stories.d.ts +0 -7
  165. package/dist/components/Buttons/FdsButtonCopy/FdsButtonCopy.stories.d.ts.map +0 -1
  166. package/dist/components/Buttons/FdsButtonCopy/FdsButtonCopy.vue.d.ts +0 -14
  167. package/dist/components/Buttons/FdsButtonCopy/FdsButtonCopy.vue.d.ts.map +0 -1
  168. package/dist/components/Buttons/FdsButtonCopy/types.d.ts +0 -9
  169. package/dist/components/Buttons/FdsButtonCopy/types.d.ts.map +0 -1
  170. package/dist/components/Buttons/FdsButtonDownload/FdsButtonDownload.stories.d.ts +0 -10
  171. package/dist/components/Buttons/FdsButtonDownload/FdsButtonDownload.stories.d.ts.map +0 -1
  172. package/dist/components/Buttons/FdsButtonDownload/FdsButtonDownload.vue.d.ts +0 -25
  173. package/dist/components/Buttons/FdsButtonDownload/FdsButtonDownload.vue.d.ts.map +0 -1
  174. package/dist/components/Buttons/FdsButtonIcon/FdsButtonIcon.stories.d.ts +0 -7
  175. package/dist/components/Buttons/FdsButtonIcon/FdsButtonIcon.stories.d.ts.map +0 -1
  176. package/dist/components/Buttons/FdsButtonIcon/FdsButtonIcon.vue.d.ts +0 -14
  177. package/dist/components/Buttons/FdsButtonIcon/FdsButtonIcon.vue.d.ts.map +0 -1
  178. package/dist/components/Buttons/FdsButtonIcon/types.d.ts +0 -12
  179. package/dist/components/Buttons/FdsButtonIcon/types.d.ts.map +0 -1
  180. package/dist/components/Buttons/FdsButtonMinor/FdsButtonMinor.stories.d.ts +0 -7
  181. package/dist/components/Buttons/FdsButtonMinor/FdsButtonMinor.stories.d.ts.map +0 -1
  182. package/dist/components/Buttons/FdsButtonMinor/FdsButtonMinor.vue.d.ts +0 -25
  183. package/dist/components/Buttons/FdsButtonMinor/FdsButtonMinor.vue.d.ts.map +0 -1
  184. package/dist/components/Buttons/FdsButtonPrimary/FdsButtonPrimary.stories.d.ts +0 -9
  185. package/dist/components/Buttons/FdsButtonPrimary/FdsButtonPrimary.stories.d.ts.map +0 -1
  186. package/dist/components/Buttons/FdsButtonPrimary/FdsButtonPrimary.vue.d.ts +0 -20
  187. package/dist/components/Buttons/FdsButtonPrimary/FdsButtonPrimary.vue.d.ts.map +0 -1
  188. package/dist/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.stories.d.ts +0 -7
  189. package/dist/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.stories.d.ts.map +0 -1
  190. package/dist/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.vue.d.ts +0 -20
  191. package/dist/components/Buttons/FdsButtonSecondary/FdsButtonSecondary.vue.d.ts.map +0 -1
  192. package/dist/components/FdsIcon/FdsIcon.stories.d.ts +0 -8
  193. package/dist/components/FdsIcon/FdsIcon.stories.d.ts.map +0 -1
  194. package/dist/components/FdsIcon/FdsIcon.vue.d.ts +0 -7
  195. package/dist/components/FdsIcon/FdsIcon.vue.d.ts.map +0 -1
  196. package/dist/components/FdsIcon/types.d.ts +0 -8
  197. package/dist/components/FdsIcon/types.d.ts.map +0 -1
  198. package/dist/components/FdsModal/FdsModal.stories.d.ts +0 -13
  199. package/dist/components/FdsModal/FdsModal.stories.d.ts.map +0 -1
  200. package/dist/components/FdsModal/FdsModal.vue.d.ts +0 -33
  201. package/dist/components/FdsModal/FdsModal.vue.d.ts.map +0 -1
  202. package/dist/components/FdsModal/types.d.ts +0 -13
  203. package/dist/components/FdsModal/types.d.ts.map +0 -1
  204. package/dist/components/FdsPagination/FdsPagination.stories.d.ts +0 -11
  205. package/dist/components/FdsPagination/FdsPagination.stories.d.ts.map +0 -1
  206. package/dist/components/FdsPagination/FdsPagination.vue.d.ts +0 -21
  207. package/dist/components/FdsPagination/FdsPagination.vue.d.ts.map +0 -1
  208. package/dist/components/FdsPagination/types.d.ts +0 -7
  209. package/dist/components/FdsPagination/types.d.ts.map +0 -1
  210. package/dist/components/FdsSearchSelect/FdsSearchSelect.stories.d.ts +0 -15
  211. package/dist/components/FdsSearchSelect/FdsSearchSelect.stories.d.ts.map +0 -1
  212. package/dist/components/FdsSearchSelect/FdsSearchSelect.vue.d.ts +0 -41
  213. package/dist/components/FdsSearchSelect/FdsSearchSelect.vue.d.ts.map +0 -1
  214. package/dist/components/FdsSearchSelect/types.d.ts +0 -29
  215. package/dist/components/FdsSearchSelect/types.d.ts.map +0 -1
  216. package/dist/components/FdsSpinner/FdsSpinner.stories.d.ts +0 -7
  217. package/dist/components/FdsSpinner/FdsSpinner.stories.d.ts.map +0 -1
  218. package/dist/components/FdsSpinner/FdsSpinner.vue.d.ts +0 -15
  219. package/dist/components/FdsSpinner/FdsSpinner.vue.d.ts.map +0 -1
  220. package/dist/components/FdsSpinner/types.d.ts +0 -7
  221. package/dist/components/FdsSpinner/types.d.ts.map +0 -1
  222. package/dist/components/FdsSticker/FdsSticker.stories.d.ts +0 -15
  223. package/dist/components/FdsSticker/FdsSticker.stories.d.ts.map +0 -1
  224. package/dist/components/FdsSticker/FdsSticker.vue.d.ts +0 -17
  225. package/dist/components/FdsSticker/FdsSticker.vue.d.ts.map +0 -1
  226. package/dist/components/FdsSticker/types.d.ts +0 -5
  227. package/dist/components/FdsSticker/types.d.ts.map +0 -1
  228. package/dist/components/FdsTreeView/FdsTreeView.stories.d.ts +0 -7
  229. package/dist/components/FdsTreeView/FdsTreeView.stories.d.ts.map +0 -1
  230. package/dist/components/FdsTreeView/FdsTreeView.vue.d.ts +0 -29
  231. package/dist/components/FdsTreeView/FdsTreeView.vue.d.ts.map +0 -1
  232. package/dist/components/FdsTreeView/TreeNode.vue.d.ts +0 -21
  233. package/dist/components/FdsTreeView/TreeNode.vue.d.ts.map +0 -1
  234. package/dist/components/FdsTreeView/types.d.ts +0 -122
  235. package/dist/components/FdsTreeView/types.d.ts.map +0 -1
  236. package/dist/components/FdsTreeView/useTreeState.d.ts +0 -48
  237. package/dist/components/FdsTreeView/useTreeState.d.ts.map +0 -1
  238. package/dist/components/FdsTreeView/utils.d.ts +0 -4
  239. package/dist/components/FdsTreeView/utils.d.ts.map +0 -1
  240. package/dist/components/FdsTruncatedText/FdsTruncatedText.stories.d.ts +0 -9
  241. package/dist/components/FdsTruncatedText/FdsTruncatedText.stories.d.ts.map +0 -1
  242. package/dist/components/FdsTruncatedText/FdsTruncatedText.vue.d.ts +0 -26
  243. package/dist/components/FdsTruncatedText/FdsTruncatedText.vue.d.ts.map +0 -1
  244. package/dist/components/FdsTruncatedText/types.d.ts +0 -7
  245. package/dist/components/FdsTruncatedText/types.d.ts.map +0 -1
  246. package/dist/components/Form/FdsCheckbox/FdsCheckbox.stories.d.ts +0 -12
  247. package/dist/components/Form/FdsCheckbox/FdsCheckbox.stories.d.ts.map +0 -1
  248. package/dist/components/Form/FdsCheckbox/FdsCheckbox.vue.d.ts +0 -38
  249. package/dist/components/Form/FdsCheckbox/FdsCheckbox.vue.d.ts.map +0 -1
  250. package/dist/components/Form/FdsCheckbox/types.d.ts +0 -11
  251. package/dist/components/Form/FdsCheckbox/types.d.ts.map +0 -1
  252. package/dist/components/Form/FdsInput/FdsInput.stories.d.ts +0 -18
  253. package/dist/components/Form/FdsInput/FdsInput.stories.d.ts.map +0 -1
  254. package/dist/components/Form/FdsInput/FdsInput.vue.d.ts +0 -39
  255. package/dist/components/Form/FdsInput/FdsInput.vue.d.ts.map +0 -1
  256. package/dist/components/Form/FdsInput/types.d.ts +0 -26
  257. package/dist/components/Form/FdsInput/types.d.ts.map +0 -1
  258. package/dist/components/Form/FdsRadio/FdsRadio.stories.d.ts +0 -8
  259. package/dist/components/Form/FdsRadio/FdsRadio.stories.d.ts.map +0 -1
  260. package/dist/components/Form/FdsRadio/FdsRadio.vue.d.ts +0 -36
  261. package/dist/components/Form/FdsRadio/FdsRadio.vue.d.ts.map +0 -1
  262. package/dist/components/Form/FdsRadio/types.d.ts +0 -13
  263. package/dist/components/Form/FdsRadio/types.d.ts.map +0 -1
  264. package/dist/components/Form/FdsSelect/FdsSelect.stories.d.ts +0 -10
  265. package/dist/components/Form/FdsSelect/FdsSelect.stories.d.ts.map +0 -1
  266. package/dist/components/Form/FdsSelect/FdsSelect.vue.d.ts +0 -45
  267. package/dist/components/Form/FdsSelect/FdsSelect.vue.d.ts.map +0 -1
  268. package/dist/components/Form/FdsSelect/types.d.ts +0 -18
  269. package/dist/components/Form/FdsSelect/types.d.ts.map +0 -1
  270. package/dist/components/Form/FdsTextarea/FdsTextarea.stories.d.ts +0 -8
  271. package/dist/components/Form/FdsTextarea/FdsTextarea.stories.d.ts.map +0 -1
  272. package/dist/components/Form/FdsTextarea/FdsTextarea.vue.d.ts +0 -27
  273. package/dist/components/Form/FdsTextarea/FdsTextarea.vue.d.ts.map +0 -1
  274. package/dist/components/Form/FdsTextarea/types.d.ts +0 -13
  275. package/dist/components/Form/FdsTextarea/types.d.ts.map +0 -1
  276. package/dist/components/Table/FdsTable/FdsTable.stories.d.ts +0 -10
  277. package/dist/components/Table/FdsTable/FdsTable.stories.d.ts.map +0 -1
  278. package/dist/components/Table/FdsTable/FdsTable.vue.d.ts +0 -16
  279. package/dist/components/Table/FdsTable/FdsTable.vue.d.ts.map +0 -1
  280. package/dist/components/Table/FdsTable/types.d.ts +0 -5
  281. package/dist/components/Table/FdsTable/types.d.ts.map +0 -1
  282. package/dist/components/Table/FdsTableHead/FdsTableHead.stories.d.ts +0 -12
  283. package/dist/components/Table/FdsTableHead/FdsTableHead.stories.d.ts.map +0 -1
  284. package/dist/components/Table/FdsTableHead/FdsTableHead.vue.d.ts +0 -24
  285. package/dist/components/Table/FdsTableHead/FdsTableHead.vue.d.ts.map +0 -1
  286. package/dist/components/Table/FdsTableHead/types.d.ts +0 -6
  287. package/dist/components/Table/FdsTableHead/types.d.ts.map +0 -1
  288. package/dist/components/Tabs/FdsTabs/FdsTabs.stories.d.ts +0 -14
  289. package/dist/components/Tabs/FdsTabs/FdsTabs.stories.d.ts.map +0 -1
  290. package/dist/components/Tabs/FdsTabs/FdsTabs.vue.d.ts +0 -17
  291. package/dist/components/Tabs/FdsTabs/FdsTabs.vue.d.ts.map +0 -1
  292. package/dist/components/Tabs/FdsTabs/types.d.ts +0 -5
  293. package/dist/components/Tabs/FdsTabs/types.d.ts.map +0 -1
  294. package/dist/components/Tabs/FdsTabsItem/FdsTabsItem.vue.d.ts +0 -22
  295. package/dist/components/Tabs/FdsTabsItem/FdsTabsItem.vue.d.ts.map +0 -1
  296. package/dist/components/Tabs/FdsTabsItem/types.d.ts +0 -17
  297. package/dist/components/Tabs/FdsTabsItem/types.d.ts.map +0 -1
  298. package/dist/components/Typography/FdsHeading/FdsHeading.stories.d.ts +0 -11
  299. package/dist/components/Typography/FdsHeading/FdsHeading.stories.d.ts.map +0 -1
  300. package/dist/components/Typography/FdsHeading/FdsHeading.vue.d.ts +0 -6
  301. package/dist/components/Typography/FdsHeading/FdsHeading.vue.d.ts.map +0 -1
  302. package/dist/components/Typography/FdsHeading/types.d.ts +0 -6
  303. package/dist/components/Typography/FdsHeading/types.d.ts.map +0 -1
  304. package/dist/components/Typography/FdsListHeading/FdsListHeading.stories.d.ts +0 -11
  305. package/dist/components/Typography/FdsListHeading/FdsListHeading.stories.d.ts.map +0 -1
  306. package/dist/components/Typography/FdsListHeading/FdsListHeading.vue.d.ts +0 -7
  307. package/dist/components/Typography/FdsListHeading/FdsListHeading.vue.d.ts.map +0 -1
  308. package/dist/components/Typography/FdsListHeading/types.d.ts +0 -9
  309. package/dist/components/Typography/FdsListHeading/types.d.ts.map +0 -1
  310. package/dist/components/Typography/FdsSeparator/FdsSeparator.stories.d.ts +0 -7
  311. package/dist/components/Typography/FdsSeparator/FdsSeparator.stories.d.ts.map +0 -1
  312. package/dist/components/Typography/FdsSeparator/FdsSeparator.vue.d.ts +0 -3
  313. package/dist/components/Typography/FdsSeparator/FdsSeparator.vue.d.ts.map +0 -1
  314. package/dist/components/Typography/FdsText/FdsText.stories.d.ts +0 -9
  315. package/dist/components/Typography/FdsText/FdsText.stories.d.ts.map +0 -1
  316. package/dist/components/Typography/FdsText/FdsText.vue.d.ts +0 -16
  317. package/dist/components/Typography/FdsText/FdsText.vue.d.ts.map +0 -1
  318. package/dist/components/Typography/FdsText/types.d.ts +0 -4
  319. package/dist/components/Typography/FdsText/types.d.ts.map +0 -1
  320. package/dist/composables/useBoldQuery.d.ts +0 -10
  321. package/dist/composables/useBoldQuery.d.ts.map +0 -1
  322. package/dist/composables/useElementFinalSize.d.ts +0 -3
  323. package/dist/composables/useElementFinalSize.d.ts.map +0 -1
  324. package/dist/composables/useHasSlots.d.ts +0 -6
  325. package/dist/composables/useHasSlots.d.ts.map +0 -1
  326. package/dist/composables/useIsPid.d.ts +0 -16
  327. package/dist/composables/useIsPid.d.ts.map +0 -1
  328. package/dist/global-components.d.ts.map +0 -1
  329. package/dist/index.d.ts.map +0 -1
  330. package/dist/main.d.ts +0 -2
  331. package/dist/main.d.ts.map +0 -1
@@ -0,0 +1,607 @@
1
+ import { computed, reactive, ref, watch } from 'vue'
2
+ import type { FdsTreeNode, FdsTreeNodeArray, FdsTreeNodeItem } from './types'
3
+ import type { FdsIconName } from '@/components/FdsIcon/types'
4
+ import { getTitleFromProperties } from './utils'
5
+
6
+ interface TreeStateOptions {
7
+ expandChildrenOnParentCheck?: boolean
8
+ expandAllChildrenOnParentCheck?: boolean
9
+ showIndeterminateOnlyOnChildrenSelection?: boolean
10
+ searchExpandNodes?: boolean
11
+ titleTemplate?: string
12
+ searchInputTriggerLength?: number
13
+ nodes?: FdsTreeNodeArray
14
+ }
15
+
16
+ const useTreeState = (options: TreeStateOptions = {}) => {
17
+ /** Default the trigger length to 1 when not provided */
18
+ const triggerLength = options?.searchInputTriggerLength ?? 1
19
+ /**
20
+ * The set of selected nodes
21
+ */
22
+ const selectedNodes = reactive<Set<FdsTreeNode['nodeId']>>(new Set())
23
+ /**
24
+ * The array of selected node objects
25
+ */
26
+ const selectedNodeObjects = reactive<FdsTreeNode[]>([])
27
+ /**
28
+ * The set of expanded nodes
29
+ */
30
+ const expandedNodes = reactive<Set<FdsTreeNode['nodeId']>>(new Set())
31
+ /**
32
+ * The search term for filtering nodes
33
+ */
34
+ const searchTerm = ref<string>('')
35
+
36
+ /**
37
+ * If no results are found for the search term
38
+ */
39
+ const isEmptySearchResult = ref<boolean>(false)
40
+
41
+ // Watch for search term changes to update empty result flag
42
+ watch(searchTerm, (newTerm) => {
43
+ if (!newTerm.trim() || newTerm.length < triggerLength) {
44
+ isEmptySearchResult.value = false
45
+ } else if (options.nodes && options.nodes.length > 0) {
46
+ // Check if there are any results for the new search term
47
+ // The tree structure has a root node with children, so we need to check the root's children
48
+ const rootNode = options.nodes[0]
49
+ const nodesToCheck = rootNode?.children || []
50
+ const filtered = filterNodesRecursive(nodesToCheck, newTerm, ['title', 'nodeId'])
51
+ isEmptySearchResult.value = filtered.length === 0
52
+ }
53
+ })
54
+
55
+ /**
56
+ * Clears all selected nodes. Can be used to reset the selections to the initial state.
57
+ */
58
+ const clearAllSelectedNodes = () => {
59
+ selectedNodes.clear()
60
+ selectedNodeObjects.length = 0
61
+ }
62
+
63
+ /**
64
+ * Collapses all expanded nodes. Can be used to reset the tree to the initial state.
65
+ */
66
+ const collapseAllExpandedNodes = () => expandedNodes.clear()
67
+
68
+ /**
69
+ * Returns true if the node is selected
70
+ */
71
+ const isNodeSelected = (nodeId: FdsTreeNode['nodeId']) => selectedNodes.has(nodeId)
72
+
73
+ /**
74
+ * Returns true if the node is expanded
75
+ */
76
+ const isNodeExpanded = (nodeId: FdsTreeNode['nodeId']) => expandedNodes.has(nodeId)
77
+
78
+ /**
79
+ * Expands the specific node
80
+ */
81
+ const expandNode = (nodeId: FdsTreeNode['nodeId']) => expandedNodes.add(nodeId)
82
+
83
+ /**
84
+ * Collapses the specific node
85
+ */
86
+ const collapseNode = (nodeId: FdsTreeNode['nodeId']) => expandedNodes.delete(nodeId)
87
+ /**
88
+ * Selects the specific node and adds it to the selectedNodeObjects array.
89
+ * Used to access the node object and it's underlying data
90
+ */
91
+ const injectNode = (nodeObject: FdsTreeNode) => {
92
+ // Prevent duplicates
93
+ if (selectedNodes.has(nodeObject.nodeId)) return
94
+
95
+ selectedNodes.add(nodeObject.nodeId)
96
+ if (!selectedNodeObjects.some((n) => n.nodeId === nodeObject.nodeId)) {
97
+ selectedNodeObjects.push(nodeObject)
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Expands all children of the specific node
103
+ */
104
+ const expandAllChildren = (node: FdsTreeNode) => {
105
+ expandNode(node.nodeId)
106
+ if (node.children && node.children.length > 0) {
107
+ node.children.forEach(expandAllChildren)
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Selects this node and recursively selects all children nodes
113
+ */
114
+ const selectAllChildren = (node: FdsTreeNode) => {
115
+ // Deselect all children to avoid duplicates
116
+ if (node.children && node.children.length > 0) {
117
+ node.children.forEach(deselectNodeAndAllChildren)
118
+ }
119
+
120
+ // Inject the current node
121
+ injectNode(node)
122
+
123
+ if (node.children && node.children.length > 0) {
124
+ node.children.forEach(selectAllChildren)
125
+ }
126
+
127
+ // Only expand children if the option is enabled
128
+ if (options.expandChildrenOnParentCheck) {
129
+ expandAllChildren(node)
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Selects this node and recursively selects all children nodes
135
+ */
136
+ const selectNodeAndAllChildren = (nodeId: FdsTreeNode['nodeId']) => {
137
+ const node = findNodeObjectById(nodeId)
138
+
139
+ if (!node) return
140
+
141
+ // Select the current node
142
+ injectNode(node)
143
+
144
+ // Deselect all children to avoid duplicates
145
+ if (node.children && node.children.length > 0) {
146
+ node.children.forEach(selectAllChildren)
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Deselects the specific node
152
+ */
153
+ const deselectNode = (nodeId: FdsTreeNode['nodeId']) => {
154
+ selectedNodes.delete(nodeId)
155
+ const index = selectedNodeObjects.findIndex((node) => node.nodeId === nodeId)
156
+
157
+ if (index > -1) {
158
+ selectedNodeObjects.splice(index, 1)
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Deselects this node and recursively deselects all children nodes
164
+ */
165
+ const deselectNodeAndAllChildren = (node: FdsTreeNode) => {
166
+ // Remove the current node
167
+ deselectNode(node.nodeId)
168
+
169
+ // Recursively remove all children
170
+ if (node.children && node.children.length > 0) {
171
+ node.children.forEach(deselectNodeAndAllChildren)
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Deselects only the children of the specific node
177
+ */
178
+ const deselectChildrenOnly = (nodeId: FdsTreeNode['nodeId']) => {
179
+ const node = findNodeObjectById(nodeId)
180
+
181
+ if (!node) return
182
+
183
+ // Ensure parent remains selected
184
+ selectedNodes.add(node.nodeId)
185
+ if (!selectedNodeObjects.some((n) => n.nodeId === node.nodeId)) {
186
+ selectedNodeObjects.push(node)
187
+ }
188
+
189
+ // Recursively remove all children
190
+ if (node.children && node.children.length > 0) {
191
+ node.children.forEach(deselectNodeAndAllChildren)
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Finds a node by ID
197
+ */
198
+ const findNodeById = (nodes: FdsTreeNodeArray, nodeId: string): FdsTreeNodeItem | null => {
199
+ for (const node of nodes) {
200
+ if (node.nodeId === nodeId) {
201
+ return node
202
+ }
203
+ if (node.children) {
204
+ const found = findNodeById(node.children, nodeId)
205
+ if (found) return found
206
+ }
207
+ }
208
+ return null
209
+ }
210
+
211
+ /**
212
+ * Finds a node by ID
213
+ */
214
+ const findNodeObjectById = (nodeId: string): FdsTreeNodeItem | null => {
215
+ const nodes = Array.isArray(options.nodes) ? options.nodes : []
216
+ for (const node of nodes) {
217
+ if (node.nodeId === nodeId) {
218
+ return node
219
+ }
220
+ if (node.children) {
221
+ const found = findNodeById(node.children, nodeId)
222
+ if (found) return found
223
+ }
224
+ }
225
+ return null
226
+ }
227
+
228
+ /**
229
+ * Checks if a node has children
230
+ */
231
+ const hasChildrenNodes = (nodes: FdsTreeNodeArray) => nodes.length > 0
232
+
233
+ /**
234
+ * Checks if a parent or it's children are selected
235
+ */
236
+ const isParentOrChildrenSelected = (nodeId: FdsTreeNode['nodeId']): boolean => {
237
+ const node = findNodeObjectById(nodeId)
238
+
239
+ if (!node || !hasChildrenNodes(node.children || [])) return false
240
+
241
+ return selectedNodes.has(node.nodeId) || isAnyChildSelected(node.children || [])
242
+ }
243
+
244
+ /**
245
+ * Checks if a parent or it's children are selected
246
+ */
247
+ const isParentAndAllChildrenSelected = (nodeId: FdsTreeNode['nodeId']): boolean => {
248
+ const node = findNodeObjectById(nodeId)
249
+
250
+ if (!node) return false
251
+ // Parent must be selected and all children
252
+ return selectedNodes.has(node.nodeId) && isEveryChildSelected(node)
253
+ }
254
+
255
+ /**
256
+ * Checks if a parent or it's children are selected
257
+ */
258
+ const isParentOnlySelected = (nodeId: FdsTreeNode['nodeId']): boolean => {
259
+ const node = findNodeObjectById(nodeId)
260
+
261
+ if (!node || !hasChildrenNodes(node.children || [])) return false
262
+
263
+ return !isAnyChildSelected(node.children || []) && selectedNodes.has(node.nodeId)
264
+ }
265
+
266
+ /**
267
+ * Returns true if ALL children of a node are selected
268
+ */
269
+ const isEveryChildSelected = (node: FdsTreeNode): boolean => {
270
+ if (!node.children || node.children.length === 0) return true
271
+
272
+ return node.children.every((child) => selectedNodes.has(child.nodeId) && isEveryChildSelected(child))
273
+ }
274
+
275
+ /**
276
+ * Checks if any child of a node is selected
277
+ */
278
+ const isAnyChildSelected = (nodes: FdsTreeNodeArray): boolean => {
279
+ if (!nodes || nodes.length === 0) return false
280
+ return nodes.some(
281
+ (child) => selectedNodes.has(child.nodeId) || (child.children && isAnyChildSelected(child.children)),
282
+ )
283
+ }
284
+
285
+ /**
286
+ * Checks if a node is indeterminate (partially selected)
287
+ */
288
+ const isNodeIndeterminate = (nodes: FdsTreeNodeArray, parentNodeId?: string): boolean => {
289
+ if (!hasChildrenNodes(nodes)) return false
290
+
291
+ // Check each child's state
292
+ const childStates = nodes.map((node) => ({
293
+ isSelected: selectedNodes.has(node.nodeId),
294
+ isIndeterminate:
295
+ node.children && node.children.length > 0 ? isNodeIndeterminate(node.children, node.nodeId) : false,
296
+ }))
297
+
298
+ const hasSelected = childStates.some((child: { isSelected: boolean; isIndeterminate: boolean }) => child.isSelected)
299
+ const hasUnselected = childStates.some(
300
+ (child: { isSelected: boolean; isIndeterminate: boolean }) => !child.isSelected && !child.isIndeterminate,
301
+ )
302
+ const hasIndeterminate = childStates.some(
303
+ (child: { isSelected: boolean; isIndeterminate: boolean }) => child.isIndeterminate,
304
+ )
305
+
306
+ // If parent is selected, never show indeterminate
307
+ if (parentNodeId && selectedNodes.has(parentNodeId)) return false
308
+
309
+ // Standard behavior: some selected + some unselected, OR any child is indeterminate
310
+ if (!options.showIndeterminateOnlyOnChildrenSelection) {
311
+ return (hasSelected && hasUnselected) || hasIndeterminate
312
+ }
313
+
314
+ // Special behavior: any child selected OR any child indeterminate
315
+ return hasSelected || hasIndeterminate
316
+ }
317
+
318
+ const isNodeIndeterminateById = (nodeId: FdsTreeNode['nodeId']): boolean => {
319
+ const node = findNodeObjectById(nodeId)
320
+ if (!node) return false
321
+ return isNodeIndeterminate(node.children || [], nodeId)
322
+ }
323
+
324
+ /**
325
+ * Toggles the selection state of the specific node
326
+ */
327
+ const toggleSelectNode = (nodeId: string, title?: string, data?: Record<string, unknown>) => {
328
+ let node = findNodeObjectById(nodeId)
329
+
330
+ if (!node && nodeId) {
331
+ node = {
332
+ nodeId,
333
+ title,
334
+ children: [],
335
+ data,
336
+ }
337
+ }
338
+
339
+ if (!node) return
340
+
341
+ if (selectedNodes.has(nodeId)) {
342
+ deselectNodeAndAllChildren(node)
343
+ } else {
344
+ selectAllChildren(node)
345
+
346
+ if (selectedNodes.has(nodeId) && !expandedNodes.has(nodeId) && options.expandChildrenOnParentCheck) {
347
+ expandNode(nodeId)
348
+ }
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Toggles the expansion state of the specific node
354
+ */
355
+ const toggleExpandNode = (nodeId: FdsTreeNode['nodeId']) => {
356
+ if (isNodeExpanded(nodeId)) {
357
+ collapseNode(nodeId)
358
+ } else {
359
+ expandNode(nodeId)
360
+ }
361
+ }
362
+
363
+ /**
364
+ * Gets the icons for expanded and collapsed nodes
365
+ */
366
+ const getNodeIcon = (nodeId: FdsTreeNode['nodeId'], expandIcon: FdsIconName, collapseIcon: FdsIconName) =>
367
+ isNodeExpanded(nodeId) ? collapseIcon : expandIcon
368
+
369
+ /**
370
+ * Checks if a node matches the search term by searching through specified properties
371
+ */
372
+ const nodeMatchesSearch = (node: FdsTreeNode, term: string, searchParams?: string[]): boolean => {
373
+ if (!term.trim()) return true
374
+ if (!searchParams || !Array.isArray(searchParams)) return false
375
+
376
+ const normalizeForSearch = (value: unknown): string => {
377
+ const s = String(value ?? '')
378
+ return s
379
+ .toLowerCase()
380
+ .normalize('NFD')
381
+ .replace(/[\u0300-\u036f]/g, '')
382
+ .replace(/\s+/g, ' ')
383
+ .trim()
384
+ }
385
+
386
+ const searchLower = normalizeForSearch(term)
387
+
388
+ const getValueByPath = (obj: unknown, path: string): unknown => {
389
+ if (!obj) return undefined
390
+ // If data is an array, check each element
391
+ if (Array.isArray(obj)) {
392
+ for (const item of obj) {
393
+ const v = getValueByPath(item as Record<string, unknown>, path)
394
+ if (v !== undefined && v !== null) return v
395
+ }
396
+ return undefined
397
+ }
398
+ if (typeof obj !== 'object') return undefined
399
+ const segments = path.split('.')
400
+ let current: unknown = obj as Record<string, unknown>
401
+ for (const seg of segments) {
402
+ if (current && typeof current === 'object' && seg in (current as Record<string, unknown>)) {
403
+ current = (current as Record<string, unknown>)[seg]
404
+ } else {
405
+ return undefined
406
+ }
407
+ }
408
+ return current
409
+ }
410
+
411
+ for (const rawParam of searchParams) {
412
+ const param = rawParam.startsWith('data.') ? rawParam.slice(5) : rawParam
413
+ if (param === 'title') {
414
+ const renderedTitle = getTitleFromProperties(node, options?.titleTemplate)
415
+ const titleToMatch = normalizeForSearch(renderedTitle || node.title)
416
+ if (titleToMatch.includes(searchLower)) return true
417
+ }
418
+ if (param === 'nodeId' && normalizeForSearch(node.nodeId).includes(searchLower)) return true
419
+
420
+ const dataSource = node.data as unknown
421
+ if (Array.isArray(dataSource)) {
422
+ for (const item of dataSource) {
423
+ const v = getValueByPath(item, param)
424
+ if (v !== undefined && v !== null) {
425
+ try {
426
+ if (normalizeForSearch(v).includes(searchLower)) return true
427
+ } catch {}
428
+ }
429
+ }
430
+ } else {
431
+ const value = getValueByPath(dataSource, param)
432
+ if (value !== undefined && value !== null) {
433
+ try {
434
+ if (normalizeForSearch(value).includes(searchLower)) return true
435
+ } catch {}
436
+ }
437
+ }
438
+ }
439
+
440
+ return false
441
+ }
442
+
443
+ /**
444
+ * Internal recursive filtering function
445
+ */
446
+ const filterNodesRecursive = (nodes: FdsTreeNodeArray, term: string, searchParams?: string[]): FdsTreeNodeArray => {
447
+ if (!term.trim()) return nodes
448
+
449
+ const filtered: FdsTreeNodeArray = []
450
+
451
+ for (const node of nodes) {
452
+ const nodeMatches = nodeMatchesSearch(node, term, searchParams)
453
+ const filteredChildren = node.children ? filterNodesRecursive(node.children, term, searchParams) : []
454
+
455
+ // Include node if it matches OR has matching children
456
+ if (nodeMatches || filteredChildren.length > 0) {
457
+ filtered.push({
458
+ ...node,
459
+ children: filteredChildren.length > 0 ? filteredChildren : node.children,
460
+ })
461
+ }
462
+ }
463
+
464
+ return filtered
465
+ }
466
+
467
+ /**
468
+ * Counts how many nodes match the search term across the provided subtree.
469
+ */
470
+ const countMatchingNodesRecursive = (nodes: FdsTreeNodeArray, term: string, searchParams?: string[]): number => {
471
+ if (!Array.isArray(nodes) || nodes.length === 0) return 0
472
+ if (!term.trim()) return nodes.length
473
+
474
+ let count = 0
475
+ for (const node of nodes) {
476
+ if (nodeMatchesSearch(node, term, searchParams)) count += 1
477
+ if (node.children && node.children.length > 0) {
478
+ count += countMatchingNodesRecursive(node.children, term, searchParams)
479
+ }
480
+ }
481
+ return count
482
+ }
483
+
484
+ /**
485
+ * Counts all nodes in the provided subtree.
486
+ */
487
+ const countAllNodesRecursive = (nodes: FdsTreeNodeArray): number => {
488
+ if (!Array.isArray(nodes) || nodes.length === 0) return 0
489
+ let count = 0
490
+ for (const node of nodes) {
491
+ count += 1
492
+ if (node.children && node.children.length > 0) {
493
+ count += countAllNodesRecursive(node.children)
494
+ }
495
+ }
496
+ return count
497
+ }
498
+
499
+ /**
500
+ * Filters nodes based on search term, including children that match
501
+ */
502
+ const filterNodes = (nodes: FdsTreeNodeArray, term: string, searchParams?: string[]): FdsTreeNodeArray => {
503
+ if (!term.trim() || term.length < triggerLength) {
504
+ return nodes
505
+ }
506
+
507
+ const filtered = filterNodesRecursive(nodes, term, searchParams)
508
+
509
+ return filtered
510
+ }
511
+
512
+ /**
513
+ * Sets the search term
514
+ */
515
+ const setSearchTerm = (term: string) => {
516
+ searchTerm.value = term
517
+ if (!term.trim() || term.length < triggerLength) {
518
+ isEmptySearchResult.value = false
519
+ }
520
+ }
521
+
522
+ /**
523
+ * Clears the search term
524
+ */
525
+ const clearSearch = () => {
526
+ searchTerm.value = ''
527
+ isEmptySearchResult.value = false
528
+ }
529
+
530
+ /**
531
+ * Reactive total count of nodes matching the current search term.
532
+ * If there is no term, returns total nodes under the root's children.
533
+ */
534
+ const filteredMatchCount = computed<number>(() => {
535
+ const t = String(searchTerm.value || '').trim()
536
+ const rootNode = Array.isArray(options.nodes) && options.nodes.length > 0 ? options.nodes[0] : null
537
+ const nodesToCheck = rootNode?.children || []
538
+ if (!rootNode) return 0
539
+ if (!t || t.length < triggerLength) {
540
+ return countAllNodesRecursive(nodesToCheck)
541
+ }
542
+ return countMatchingNodesRecursive(nodesToCheck, t, ['title', 'nodeId'])
543
+ })
544
+
545
+ /**
546
+ * Reactive total node count under the root's children.
547
+ */
548
+ const totalNodeCount = computed<number>(() => {
549
+ const rootNode = Array.isArray(options.nodes) && options.nodes.length > 0 ? options.nodes[0] : null
550
+ const nodesToCheck = rootNode?.children || []
551
+ if (!rootNode) return 0
552
+ return countAllNodesRecursive(nodesToCheck)
553
+ })
554
+
555
+ /**
556
+ * Returns HTML string with hits from search term wrapped in <strong>.
557
+ */
558
+ const highlightText = (text: string | undefined, term: string | undefined): string => {
559
+ const source = String(text ?? '')
560
+ const t = String(term ?? '').trim()
561
+ if (!t) return source
562
+ try {
563
+ const re = new RegExp(t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'ig')
564
+ return source.replace(re, '<strong>$&</strong>')
565
+ } catch {
566
+ return source
567
+ }
568
+ }
569
+
570
+ return {
571
+ triggerLength,
572
+ clearSearch,
573
+ collapseAllExpandedNodes,
574
+ collapseNode,
575
+ deselectNodeAndAllChildren,
576
+ deselectChildrenOnly,
577
+ deselectNode,
578
+ expandAllChildren,
579
+ expandedNodes,
580
+ expandNode,
581
+ filterNodes,
582
+ getNodeIcon,
583
+ injectNode,
584
+ isNodeExpanded,
585
+ isNodeIndeterminate,
586
+ isNodeIndeterminateById,
587
+ isNodeSelected,
588
+ isParentOrChildrenSelected,
589
+ isParentAndAllChildrenSelected,
590
+ highlightText,
591
+ searchTerm,
592
+ filteredMatchCount,
593
+ totalNodeCount,
594
+ selectAllChildren,
595
+ selectedNodeObjects,
596
+ selectedNodes,
597
+ setSearchTerm,
598
+ toggleExpandNode,
599
+ toggleSelectNode,
600
+ isParentOnlySelected,
601
+ selectNodeAndAllChildren,
602
+ clearAllSelectedNodes,
603
+ isEmptySearchResult,
604
+ }
605
+ }
606
+
607
+ export default useTreeState
@@ -0,0 +1,65 @@
1
+ import type { FdsTreeNode } from './types'
2
+
3
+ const getTitleFromProperties = (node: FdsTreeNode, titleTemplate?: string) => {
4
+ if (!titleTemplate) {
5
+ return node.title
6
+ }
7
+
8
+ // Extract all occurrences of content inside [[]] in the template string
9
+ const templateVariables = extractTemplateVariables(titleTemplate)
10
+
11
+ // Replace template variables with actual values
12
+ let result = titleTemplate
13
+ templateVariables.forEach((variable) => {
14
+ const value = getNodePropertyValue(node, variable)
15
+ const regex = new RegExp(`\\[\\[${variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\]\\]`, 'g')
16
+ result = result.replace(regex, value)
17
+ })
18
+
19
+ return result
20
+ }
21
+
22
+ /**
23
+ * Extract all occurrences of content inside [[]] in a string
24
+ * @param template - The template string containing [[]] placeholders
25
+ * @returns Array of variable names found in the template
26
+ */
27
+ const extractTemplateVariables = (template: string): string[] => {
28
+ const regex = /\[\[([^\]]+)\]\]/g
29
+ const matches: string[] = []
30
+ let match
31
+
32
+ while ((match = regex.exec(template)) !== null) {
33
+ matches.push(match[1])
34
+ }
35
+
36
+ return matches
37
+ }
38
+
39
+ /**
40
+ * Get property value from node object
41
+ * @param node - The tree node
42
+ * @param property - The property name to extract
43
+ * @returns The property value as string
44
+ */
45
+ const getNodePropertyValue = (node: FdsTreeNode, property: string): string => {
46
+ // Handle direct properties
47
+ if (property in node) {
48
+ const value = node[property as keyof FdsTreeNode]
49
+ return value ? String(value) : ''
50
+ }
51
+
52
+ // Handle nested data properties
53
+ if (node.data && typeof node.data === 'object') {
54
+ const dataRecord = node.data as Record<string, unknown>
55
+ const dataValue = dataRecord[property]
56
+ if (dataValue !== undefined && dataValue !== null) {
57
+ return String(dataValue)
58
+ }
59
+ }
60
+
61
+ // Return empty string if property not found
62
+ return ''
63
+ }
64
+
65
+ export { getTitleFromProperties }