@espressif/dashboard-ui-components 1.10.0 → 1.11.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 (340) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/dist/_vendor/@radix-ui/primitive/dist/index.js +9 -0
  3. package/dist/_vendor/@radix-ui/react-checkbox/dist/index.js +185 -0
  4. package/dist/_vendor/@radix-ui/react-compose-refs/dist/index.js +28 -0
  5. package/dist/_vendor/@radix-ui/react-context/dist/index.js +68 -0
  6. package/dist/_vendor/@radix-ui/react-presence/dist/index.js +127 -0
  7. package/dist/_vendor/@radix-ui/react-primitive/dist/index.js +42 -0
  8. package/dist/_vendor/@radix-ui/react-use-controllable-state/dist/index.js +55 -0
  9. package/dist/_vendor/@radix-ui/react-use-layout-effect/dist/index.js +5 -0
  10. package/dist/_vendor/@radix-ui/react-use-previous/dist/index.js +17 -0
  11. package/dist/_vendor/@radix-ui/react-use-size/dist/index.js +39 -0
  12. package/dist/_vendor/lottie-react/build/index.es.js +537 -0
  13. package/dist/_vendor/lottie-web/build/player/lottie.js +14149 -0
  14. package/dist/_virtual/_rolldown/runtime.js +24 -0
  15. package/dist/assets/illustrations/bulb-cloud-drawing.js +4 -0
  16. package/dist/assets/illustrations/rm-dashboard-update.js +4 -0
  17. package/dist/assets/illustrations/rm-data-download.js +4 -0
  18. package/dist/assets/logos/espressif/espressif-no-text.js +4 -0
  19. package/dist/assets/logos/espressif/espressif-with-text-dm.js +4 -0
  20. package/dist/assets/logos/espressif/espressif-with-text.js +4 -0
  21. package/dist/assets/logos/insights/insights-no-text.js +4 -0
  22. package/dist/assets/logos/insights/insights-with-text-dm.js +4 -0
  23. package/dist/assets/logos/insights/insights-with-text.js +4 -0
  24. package/dist/assets/logos/launchpad/launchpad-no-text-dm.js +4 -0
  25. package/dist/assets/logos/launchpad/launchpad-no-text.js +4 -0
  26. package/dist/assets/logos/launchpad/launchpad-with-text-dm.js +4 -0
  27. package/dist/assets/logos/launchpad/launchpad-with-text.js +4 -0
  28. package/dist/assets/logos/private-agents/private-agents-no-text.js +4 -0
  29. package/dist/assets/logos/private-agents/private-agents-with-text-dm.js +4 -0
  30. package/dist/assets/logos/private-agents/private-agents-with-text.js +4 -0
  31. package/dist/assets/logos/rainmaker/rainmaker-no-text.js +4 -0
  32. package/dist/assets/logos/rainmaker/rainmaker-with-text-dm.js +4 -0
  33. package/dist/assets/logos/rainmaker/rainmaker-with-text.js +4 -0
  34. package/dist/assets/logos/rainmaker-classic/rainmaker-classic-no-text-dm.js +4 -0
  35. package/dist/assets/logos/rainmaker-classic/rainmaker-classic-no-text.js +4 -0
  36. package/dist/assets/logos/rainmaker-classic/rainmaker-classic-with-text-dm.js +4 -0
  37. package/dist/assets/logos/rainmaker-classic/rainmaker-classic-with-text.js +4 -0
  38. package/dist/assets/logos/rainmaker-neo/rainmaker-neo-no-text.js +4 -0
  39. package/dist/assets/logos/rainmaker-neo/rainmaker-neo-with-text-dm.js +4 -0
  40. package/dist/assets/logos/rainmaker-neo/rainmaker-neo-with-text.js +4 -0
  41. package/dist/assets/logos/ui-components/ui-components-no-text.js +4 -0
  42. package/dist/assets/logos/ui-components/ui-components-with-text-dm.js +4 -0
  43. package/dist/assets/logos/ui-components/ui-components-with-text.js +4 -0
  44. package/dist/assets/logos/zerocode/zerocode-no-text.js +4 -0
  45. package/dist/assets/logos/zerocode/zerocode-with-text-dm.js +4 -0
  46. package/dist/assets/logos/zerocode/zerocode-with-text.js +4 -0
  47. package/dist/assets/logos/zerocode-ai/zerocode-ai-no-text.js +4 -0
  48. package/dist/assets/logos/zerocode-ai/zerocode-ai-with-text-dm.js +4 -0
  49. package/dist/assets/logos/zerocode-ai/zerocode-ai-with-text.js +4 -0
  50. package/dist/common/animated-rainmaker-logo/animated-rainmaker-logo.constants.js +18 -0
  51. package/dist/common/animated-rainmaker-logo/animated-rainmaker-logo.js +24 -0
  52. package/dist/common/animated-rainmaker-logo/rainmaker-c-logo.js +50 -0
  53. package/dist/common/animated-rainmaker-logo/use-animated-rainmaker-logo-animation.js +85 -0
  54. package/dist/common/app-logo/app-logo.js +59 -0
  55. package/dist/common/app-logo/logo-config.js +297 -0
  56. package/dist/common/copyright-card/copyright-card.js +39 -0
  57. package/dist/common/footer-card/footer-card.js +22 -0
  58. package/dist/common/index.js +8 -8
  59. package/dist/common/my-account-menu/my-account-menu.js +32 -0
  60. package/dist/common/page-loader/page-loader.js +21 -0
  61. package/dist/common/profile-card/profile-card.js +26 -0
  62. package/dist/components/accordion/accordion.js +52 -0
  63. package/dist/components/advanced-search-box/advanced-search-box.js +106 -0
  64. package/dist/components/alert/alert.js +85 -0
  65. package/dist/components/animated-containers/pop-collection-item.js +28 -0
  66. package/dist/components/async-multi-select/async-multi-select.js +199 -0
  67. package/dist/components/avatar/avatar.js +41 -0
  68. package/dist/components/button/button.js +191 -0
  69. package/dist/components/button/flash-button.js +110 -0
  70. package/dist/components/button/invert-button.js +13 -0
  71. package/dist/components/calendar/calendar.js +105 -0
  72. package/dist/components/cards/animated-card/animated-card-animations.js +57 -0
  73. package/dist/components/cards/animated-card/animated-card.js +42 -0
  74. package/dist/components/cards/basic-details-card.js +46 -0
  75. package/dist/components/cards/collapsible-card.js +48 -0
  76. package/dist/components/cards/no-data-card/no-data-card.js +30 -0
  77. package/dist/components/cards/section-card.js +265 -0
  78. package/dist/components/cards/simple-card.js +24 -0
  79. package/dist/components/carousel/carousel.js +158 -0
  80. package/dist/components/chart/area-chart.js +135 -0
  81. package/dist/components/chart/bar-chart.js +151 -0
  82. package/dist/components/chart/chart-colors.js +85 -0
  83. package/dist/components/chart/chart-series-data.js +53 -0
  84. package/dist/components/chart/chart.js +147 -0
  85. package/dist/components/chart/chart.types.js +7 -0
  86. package/dist/components/chart/composed-chart.js +182 -0
  87. package/dist/components/chart/donut-chart.js +177 -0
  88. package/dist/components/chart/line-chart.js +137 -0
  89. package/dist/components/chart/treemap-chart.js +294 -0
  90. package/dist/components/circular-progress/circular-progress.js +125 -0
  91. package/dist/components/code-editor/code-editor.js +235 -0
  92. package/dist/components/code-editor/code-editor.utils.js +122 -0
  93. package/dist/components/code-editor/use-code-editor-keys.js +79 -0
  94. package/dist/components/code-editor/use-highlighted-html.js +102 -0
  95. package/dist/components/confirmation-dialog/confirmation-dialog.js +72 -0
  96. package/dist/components/content-container/content-container.js +20 -0
  97. package/dist/components/copiable-text/copiable-text.js +46 -0
  98. package/dist/components/data-table/data-table.js +186 -0
  99. package/dist/components/data-table/responsive-columns.js +65 -0
  100. package/dist/components/data-table/row-actions.js +27 -0
  101. package/dist/components/data-table/sticky-columns.js +71 -0
  102. package/dist/components/data-table/table-body.js +57 -0
  103. package/dist/components/data-table/table-header.js +21 -0
  104. package/dist/components/date-picker/date-picker.js +95 -0
  105. package/dist/components/date-range-picker/date-range-picker.js +301 -0
  106. package/dist/components/date-range-picker/presets.js +174 -0
  107. package/dist/components/date-time-picker/date-time-picker.js +144 -0
  108. package/dist/components/date-time-picker/date-time-picker.utils.js +32 -0
  109. package/dist/components/device-icon/device-icon.config.js +194 -0
  110. package/dist/components/device-icon/device-icon.js +17 -0
  111. package/dist/components/device-icon/icons/air-conditioner.js +22 -0
  112. package/dist/components/device-icon/icons/blind.js +24 -0
  113. package/dist/components/device-icon/icons/dimmer.js +14 -0
  114. package/dist/components/device-icon/icons/extension-board.js +42 -0
  115. package/dist/components/device-icon/icons/fan.js +14 -0
  116. package/dist/components/device-icon/icons/knob.js +14 -0
  117. package/dist/components/device-icon/icons/led-strip.js +22 -0
  118. package/dist/components/device-icon/icons/light.js +14 -0
  119. package/dist/components/device-icon/icons/refrigerator.js +18 -0
  120. package/dist/components/device-icon/icons/retro-switch.js +18 -0
  121. package/dist/components/device-icon/icons/router.js +20 -0
  122. package/dist/components/device-icon/icons/sensor.js +20 -0
  123. package/dist/components/device-icon/icons/socket.js +19 -0
  124. package/dist/components/device-icon/icons/switch.js +19 -0
  125. package/dist/components/device-icon/icons/thermostat.js +21 -0
  126. package/dist/components/device-icon/icons/washing-machine.js +22 -0
  127. package/dist/components/device-icon/match-device.js +61 -0
  128. package/dist/components/dynamic-list/dynamic-list.js +445 -0
  129. package/dist/components/error-display/full-size-error/full-size-error.js +20 -0
  130. package/dist/components/error-display/inline-error/inline-error.js +12 -0
  131. package/dist/components/file-input/file-input.js +318 -0
  132. package/dist/components/file-upload/file-upload.js +317 -0
  133. package/dist/components/filters-bar/filters-bar.js +36 -0
  134. package/dist/components/fullscreen-dialog/fullscreen-dialog.js +68 -0
  135. package/dist/components/icon-avatar/icon-avatar.js +130 -0
  136. package/dist/components/icon-text-action-card/icon-text-action-card.js +190 -0
  137. package/dist/components/illustration/illustration-registry.js +37 -0
  138. package/dist/components/illustration/illustration-variants.js +21 -0
  139. package/dist/components/illustration/illustration.js +68 -0
  140. package/dist/components/index.d.ts +0 -20
  141. package/dist/components/index.js +134 -6
  142. package/dist/components/key-value-manager/key-value-manager-add-popover.js +126 -0
  143. package/dist/components/key-value-manager/key-value-manager-field.js +47 -0
  144. package/dist/components/key-value-manager/key-value-manager-table.js +188 -0
  145. package/dist/components/key-value-manager/key-value-manager.js +111 -0
  146. package/dist/components/key-value-manager/key-value-manager.props.js +28 -0
  147. package/dist/components/key-value-manager/key-value-manager.utils.js +21 -0
  148. package/dist/components/link/link.js +67 -0
  149. package/dist/components/list/dropdown-list-item.js +60 -0
  150. package/dist/components/list/list-item.utils.js +76 -0
  151. package/dist/components/list/list.js +49 -0
  152. package/dist/components/list/list.props.js +27 -0
  153. package/dist/components/list/standard-list-item.js +66 -0
  154. package/dist/components/list-details/list-details-item-button.js +46 -0
  155. package/dist/components/list-details/list-details-item-dropdown.js +112 -0
  156. package/dist/components/list-details/list-details-item-strip.js +125 -0
  157. package/dist/components/list-details/list-details.js +148 -0
  158. package/dist/components/lottie-animation-container/lottie-animation-container.js +31 -0
  159. package/dist/components/lottie-animations/animation-data/access-denied.js +3980 -0
  160. package/dist/components/lottie-animations/animation-data/active.js +825 -0
  161. package/dist/components/lottie-animations/animation-data/bar-chart.js +610 -0
  162. package/dist/components/lottie-animations/animation-data/chart-loading.js +5368 -0
  163. package/dist/components/lottie-animations/animation-data/cloud-download.js +1660 -0
  164. package/dist/components/lottie-animations/animation-data/cloud-sync.js +932 -0
  165. package/dist/components/lottie-animations/animation-data/coud-upload.js +7060 -0
  166. package/dist/components/lottie-animations/animation-data/cross-throb.js +1506 -0
  167. package/dist/components/lottie-animations/animation-data/dashboard-loading.js +14330 -0
  168. package/dist/components/lottie-animations/animation-data/error-spread-out.js +5567 -0
  169. package/dist/components/lottie-animations/animation-data/error.js +1211 -0
  170. package/dist/components/lottie-animations/animation-data/green-success.js +14826 -0
  171. package/dist/components/lottie-animations/animation-data/inactive.js +723 -0
  172. package/dist/components/lottie-animations/animation-data/light.js +2678 -0
  173. package/dist/components/lottie-animations/animation-data/lock.js +900 -0
  174. package/dist/components/lottie-animations/animation-data/lock2.js +1686 -0
  175. package/dist/components/lottie-animations/animation-data/locked.js +641 -0
  176. package/dist/components/lottie-animations/animation-data/search-error.js +954 -0
  177. package/dist/components/lottie-animations/animation-data/security.js +4121 -0
  178. package/dist/components/lottie-animations/animation-data/success.js +404 -0
  179. package/dist/components/lottie-animations/animation-data/verification-in-progress.js +10138 -0
  180. package/dist/components/lottie-animations/animation-data/warning.js +843 -0
  181. package/dist/components/lottie-animations/verification-in-progress/verification-in-progress.js +19 -0
  182. package/dist/components/markdown-content/markdown-content.components.js +114 -0
  183. package/dist/components/markdown-content/markdown-content.js +39 -0
  184. package/dist/components/menu/menu.js +19 -0
  185. package/dist/components/monospace-content/monospace-content.js +80 -0
  186. package/dist/components/nav-bar/nav-bar-details-panel.js +51 -0
  187. package/dist/components/nav-bar/nav-bar-mobile-menu.js +105 -0
  188. package/dist/components/nav-bar/nav-bar.js +449 -0
  189. package/dist/components/nav-bar/use-nav-bar-overflow.js +74 -0
  190. package/dist/components/nav-bar/use-nav-bar-scroll.js +42 -0
  191. package/dist/components/overflow-badge-list/overflow-badge-list.js +58 -0
  192. package/dist/components/page-container/page-container-skeleton.js +72 -0
  193. package/dist/components/page-container/page-container.js +93 -0
  194. package/dist/components/pagination/pagination.js +96 -0
  195. package/dist/components/pagination/pagination.props.js +16 -0
  196. package/dist/components/progress-bar/progress-bar.js +106 -0
  197. package/dist/components/radio-group/radio-group.js +41 -0
  198. package/dist/components/requirement-list/requirement-list.js +83 -0
  199. package/dist/components/scrollable-sections/scrollable-sections.js +270 -0
  200. package/dist/components/search-box/search-box.js +54 -0
  201. package/dist/components/search-field-shell.js +24 -0
  202. package/dist/components/selectable-card-list/checkbox-card-list.js +85 -0
  203. package/dist/components/selectable-card-list/radio-card-list.js +99 -0
  204. package/dist/components/selectable-card-list/selectable-card-list-shared.js +135 -0
  205. package/dist/components/selectable-card-list/selectable-card-list.js +34 -0
  206. package/dist/components/sidebar/sidebar.js +344 -0
  207. package/dist/components/sidebar/types.js +6 -0
  208. package/dist/components/simple-clickable-card/simple-clickable-card-shared.js +309 -0
  209. package/dist/components/simple-clickable-card/simple-clickable-card.js +106 -0
  210. package/dist/components/simple-info-card/simple-info-card.js +154 -0
  211. package/dist/components/simple-list/simple-list.js +146 -0
  212. package/dist/components/simple-paginated-list/simple-paginated-list.js +178 -0
  213. package/dist/components/simplified-date/simplified-date.js +56 -0
  214. package/dist/components/skeletons/table-skeleton.js +16 -0
  215. package/dist/components/spinner/spinner.js +25 -0
  216. package/dist/components/stat-card/stat-card.js +206 -0
  217. package/dist/components/status-badge/status-badge.js +108 -0
  218. package/dist/components/status-card-list/status-card-list.js +282 -0
  219. package/dist/components/tag/tag.js +144 -0
  220. package/dist/components/tag-input/tag-input.js +161 -0
  221. package/dist/components/text-effects/glitch-effect/glitch-text.js +115 -0
  222. package/dist/components/text-effects/gradient-text/gradient-text.js +32 -0
  223. package/dist/components/text-effects/highlight-text/highlight-text.js +35 -0
  224. package/dist/components/text-effects/parse-text-markup.js +53 -0
  225. package/dist/components/text-effects/shimmer-text/shimmer-text.js +67 -0
  226. package/dist/components/time-picker/time-picker.js +23 -0
  227. package/dist/components/toast/toast.js +126 -0
  228. package/dist/components/togglable-items-list/togglable-items-list.js +28 -0
  229. package/dist/components/tooltip/tooltip.js +21 -0
  230. package/dist/components/transfer-list/transfer-list.js +413 -0
  231. package/dist/components/truncated-line-with-tooltip/truncated-line-with-tooltip.js +61 -0
  232. package/dist/components/typography/typography-variants.js +41 -0
  233. package/dist/components/typography/typography.js +15 -0
  234. package/dist/components/user-type-badge/user-type-badge.js +40 -0
  235. package/dist/components/user-type-badge/user-type-badge.registry.js +17 -0
  236. package/dist/components/vertical-stepper/vertical-stepper.js +171 -0
  237. package/dist/core/alert.js +33 -0
  238. package/dist/core/animate-ui/components/animate/code-header.js +30 -0
  239. package/dist/core/animate-ui/components/animate/code.js +35 -0
  240. package/dist/core/animate-ui/components/animate/tabs.js +188 -0
  241. package/dist/core/animate-ui/components/animate/tooltip.js +39 -0
  242. package/dist/core/animate-ui/components/base/preview-card.js +29 -0
  243. package/dist/core/animate-ui/components/base/progress.js +32 -0
  244. package/dist/core/animate-ui/components/base/radio.js +24 -0
  245. package/dist/core/animate-ui/components/buttons/copy.js +95 -0
  246. package/dist/core/animate-ui/components/radix/accordion.js +36 -0
  247. package/dist/core/animate-ui/components/radix/dialog.js +60 -0
  248. package/dist/core/animate-ui/components/radix/dropdown-menu.js +129 -0
  249. package/dist/core/animate-ui/components/radix/sheet.js +110 -0
  250. package/dist/core/animate-ui/components/radix/sidebar.js +416 -0
  251. package/dist/core/animate-ui/components/radix/switch.js +34 -0
  252. package/dist/core/animate-ui/components/radix/toggle-group.js +115 -0
  253. package/dist/core/animate-ui/components/radix/toggle.js +24 -0
  254. package/dist/core/animate-ui/primitives/animate/code-block.js +131 -0
  255. package/dist/core/animate-ui/primitives/animate/escape-html.js +7 -0
  256. package/dist/core/animate-ui/primitives/animate/shiki-highlighter.js +64 -0
  257. package/dist/core/animate-ui/primitives/animate/slot.js +39 -0
  258. package/dist/core/animate-ui/primitives/animate/tabs.js +202 -0
  259. package/dist/core/animate-ui/primitives/animate/tooltip.js +351 -0
  260. package/dist/core/animate-ui/primitives/base/preview-card.js +107 -0
  261. package/dist/core/animate-ui/primitives/base/progress.js +60 -0
  262. package/dist/core/animate-ui/primitives/base/radio.js +83 -0
  263. package/dist/core/animate-ui/primitives/buttons/button.js +15 -0
  264. package/dist/core/animate-ui/primitives/effects/highlight.js +407 -0
  265. package/dist/core/animate-ui/primitives/radix/accordion.js +76 -0
  266. package/dist/core/animate-ui/primitives/radix/dialog.js +136 -0
  267. package/dist/core/animate-ui/primitives/radix/dropdown-menu.js +305 -0
  268. package/dist/core/animate-ui/primitives/radix/sheet.js +165 -0
  269. package/dist/core/animate-ui/primitives/radix/switch.js +86 -0
  270. package/dist/core/animate-ui/primitives/radix/toggle-group.js +100 -0
  271. package/dist/core/animate-ui/primitives/texts/counting-number.js +75 -0
  272. package/dist/core/avatar.js +32 -0
  273. package/dist/core/badge.js +27 -0
  274. package/dist/core/breadcrumb.js +62 -0
  275. package/dist/core/button/button.js +43 -0
  276. package/dist/core/button/craft-button.js +78 -0
  277. package/dist/core/button-group.js +38 -0
  278. package/dist/core/button.js +40 -0
  279. package/dist/core/card.js +42 -0
  280. package/dist/core/carousel/carousel.js +149 -0
  281. package/dist/core/checkbox/motion-checkbox.js +103 -0
  282. package/dist/core/collapsible.js +54 -0
  283. package/dist/core/combobox/combobox.js +85 -0
  284. package/dist/core/command.js +61 -0
  285. package/dist/core/field-end-icons.js +36 -0
  286. package/dist/core/field-label-row.js +33 -0
  287. package/dist/core/form.js +92 -0
  288. package/dist/core/hooks/use-controlled-state.js +27 -0
  289. package/dist/core/hooks/use-data-state.js +39 -0
  290. package/dist/core/hooks/use-is-in-view.js +18 -0
  291. package/dist/core/hooks/use-mobile.js +19 -0
  292. package/dist/core/hooks/use-reveal-on-scroll-up.js +141 -0
  293. package/dist/core/hooks/use-scroll-overflow.js +50 -0
  294. package/dist/core/index.js +18 -52
  295. package/dist/core/input/input-password.js +30 -0
  296. package/dist/core/input/input.js +147 -0
  297. package/dist/core/input-otp/input-otp.js +183 -0
  298. package/dist/core/label.js +15 -0
  299. package/dist/core/popover.js +31 -0
  300. package/dist/core/scroll-area.js +42 -0
  301. package/dist/core/select.js +121 -0
  302. package/dist/core/separator.js +40 -0
  303. package/dist/core/skeleton.js +11 -0
  304. package/dist/core/table.js +59 -0
  305. package/dist/core/textarea/textarea.js +97 -0
  306. package/dist/core/utils/get-strict-context.js +18 -0
  307. package/dist/index.js +148 -9
  308. package/dist/layouts/entry-layout/entry-layout-bg.js +4 -0
  309. package/dist/layouts/entry-layout/entry-layout.js +52 -0
  310. package/dist/layouts/index.js +7 -6
  311. package/dist/layouts/workspace-layout/account-menu/account-menu.js +108 -0
  312. package/dist/layouts/workspace-layout/breadcrumbs/derive-breadcrumbs.js +37 -0
  313. package/dist/layouts/workspace-layout/breadcrumbs/workspace-breadcrumbs.js +22 -0
  314. package/dist/layouts/workspace-layout/footer/footer.js +15 -0
  315. package/dist/layouts/workspace-layout/header/header.js +54 -0
  316. package/dist/layouts/workspace-layout/workspace-layout.js +157 -0
  317. package/dist/tailwind-preset.js +3 -4
  318. package/dist/utils/cn.js +8 -0
  319. package/dist/utils/color.js +72 -0
  320. package/dist/utils/index.js +3 -2
  321. package/dist/utils/path-match.js +17 -0
  322. package/dist/utils/silver-shine.js +63 -0
  323. package/dist/utils/variant-gradient-underlay.js +45 -0
  324. package/dist/utils/variant.js +426 -0
  325. package/package.json +7 -4
  326. package/dist/chunk-2GDYZAKR.js +0 -505
  327. package/dist/chunk-ALCWXFUC.js +0 -733
  328. package/dist/chunk-CDHBLANU.js +0 -59
  329. package/dist/chunk-LUESSJAF.js +0 -70068
  330. package/dist/chunk-TMORRNEB.js +0 -323
  331. package/dist/chunk-TRTQSARU.js +0 -31
  332. package/dist/chunk-VU4CZ76T.js +0 -43
  333. package/dist/chunk-XNLCVHBC.js +0 -364
  334. package/dist/chunk-Z4776NRY.js +0 -4347
  335. package/src/assets/illustrations/add-to-group.svg +0 -32
  336. package/src/assets/illustrations/chip.svg +0 -51
  337. package/src/assets/illustrations/create-new-group.svg +0 -27
  338. package/src/assets/illustrations/new-ota.svg +0 -61
  339. package/src/assets/illustrations/secured-key.svg +0 -48
  340. /package/dist/assets/{entry-layout-bg-JPI7GJ42.webp → entry-layout-bg-DUM0UhT3.webp} +0 -0
@@ -0,0 +1,21 @@
1
+ //#region src/components/key-value-manager/key-value-manager.utils.ts
2
+ function validateField(value, meta) {
3
+ if (!value.trim()) return false;
4
+ if (meta?.maxLength != null && value.length > meta.maxLength) return false;
5
+ if (meta?.options && !meta.options.includes(value)) return false;
6
+ if (meta?.regex) try {
7
+ if (!new RegExp(meta.regex, meta.regexFlags).test(value)) return false;
8
+ } catch {}
9
+ return true;
10
+ }
11
+ function filterKeyValueRows(items, searchQuery) {
12
+ const q = searchQuery.trim().toLowerCase();
13
+ const rows = items.map((item, sourceIndex) => ({
14
+ item,
15
+ sourceIndex
16
+ }));
17
+ if (!q) return rows;
18
+ return rows.filter(({ item }) => item.key.toLowerCase().includes(q) || item.value.toLowerCase().includes(q));
19
+ }
20
+ //#endregion
21
+ export { filterKeyValueRows, validateField };
@@ -0,0 +1,67 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import * as React$1 from "react";
3
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/link/link.tsx
5
+ var EXTERNAL_PROTOCOL = /^(https?:|mailto:|tel:|sms:|ftp:)/i;
6
+ var PROTOCOL_RELATIVE = /^\/\//;
7
+ function isExternalHref(to) {
8
+ return EXTERNAL_PROTOCOL.test(to) || PROTOCOL_RELATIVE.test(to);
9
+ }
10
+ var baseClasses = "inline-flex items-center gap-1.5 rounded-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0";
11
+ var colorClasses = {
12
+ primary: "px-2 h-8 text-sm font-medium text-primary hover:bg-primary/10",
13
+ secondary: "px-2 h-8 text-sm font-medium text-secondary hover:bg-secondary/10",
14
+ error: "px-2 h-8 text-sm font-medium text-error hover:bg-error/10",
15
+ info: "px-2 h-8 text-sm font-medium text-info hover:bg-info/10",
16
+ success: "px-2 h-8 text-sm font-medium text-success hover:bg-success/10",
17
+ warning: "px-2 h-8 text-sm font-medium text-warning hover:bg-warning/10",
18
+ gray: "px-2 h-8 text-sm font-medium text-gray hover:bg-gray/10"
19
+ };
20
+ var variantClasses = {
21
+ default: "",
22
+ ghost: "h-auto hover:bg-transparent p-0"
23
+ };
24
+ var underlineClasses = "relative no-underline after:absolute after:-bottom-0.5 after:left-0 after:h-px after:w-full after:bg-current hover:after:animate-underline-slide";
25
+ function renderIconSlot(icon) {
26
+ if (icon == null) return null;
27
+ return /* @__PURE__ */ jsx("span", {
28
+ className: "inline-flex shrink-0",
29
+ children: icon
30
+ });
31
+ }
32
+ var Link = React$1.forwardRef(function Link({ to, params, search, linkComponent, color = "primary", variant = "default", underline = false, startIcon, endIcon, className, children, ...rest }, ref) {
33
+ const merged = cn(baseClasses, color != null && colorClasses[color], variantClasses[variant], underline && underlineClasses, className);
34
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
35
+ renderIconSlot(startIcon),
36
+ children,
37
+ renderIconSlot(endIcon)
38
+ ] });
39
+ if (isExternalHref(to)) return /* @__PURE__ */ jsx("a", {
40
+ ...rest,
41
+ ref,
42
+ href: to,
43
+ target: "_blank",
44
+ rel: "noopener noreferrer",
45
+ className: merged,
46
+ children: content
47
+ });
48
+ if (linkComponent) return /* @__PURE__ */ jsx(linkComponent, {
49
+ ...rest,
50
+ ref,
51
+ to,
52
+ params,
53
+ search,
54
+ className: merged,
55
+ children: content
56
+ });
57
+ return /* @__PURE__ */ jsx("a", {
58
+ ...rest,
59
+ ref,
60
+ href: to,
61
+ className: merged,
62
+ children: content
63
+ });
64
+ });
65
+ Link.displayName = "Link";
66
+ //#endregion
67
+ export { Link };
@@ -0,0 +1,60 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { DropdownMenuItem, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger } from "../../core/animate-ui/components/radix/dropdown-menu.js";
3
+ import { getItemClassName, getItemStyles, renderItemContent } from "./list-item.utils.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/list/dropdown-list-item.tsx
6
+ /**
7
+ * Leaf menu row. With `href` plus an adapter the content is wrapped in a real link so
8
+ * right-click / middle-click / modifier-click work, while Radix keeps its keyboard and
9
+ * focus semantics on the surrounding menu item. Falls back to the click-only row
10
+ * otherwise.
11
+ *
12
+ * The link is nested inside the menu item rather than composed via `asChild`, because
13
+ * the underlying animate-ui primitive already consumes `asChild` for its motion
14
+ * wrapper. This mirrors how `Sidebar`'s collapsed flyout renders its links.
15
+ */
16
+ function DropdownLeafItem({ item, itemClassName, linkComponent: LinkComponent }) {
17
+ const itemStyles = getItemStyles(item);
18
+ if (item.href && LinkComponent) return /* @__PURE__ */ jsx(DropdownMenuItem, {
19
+ className: "p-0",
20
+ onClick: item.onClick,
21
+ children: /* @__PURE__ */ jsx(LinkComponent, {
22
+ to: item.href,
23
+ className: cn("gap-1.5 cursor-pointer", getItemClassName(item, itemClassName)),
24
+ style: itemStyles.style,
25
+ "aria-current": item.isSelected ? "page" : void 0,
26
+ children: renderItemContent(item)
27
+ })
28
+ });
29
+ return /* @__PURE__ */ jsx(DropdownMenuItem, {
30
+ className: cn("gap-1.5", getItemClassName(item, itemClassName)),
31
+ style: itemStyles.style,
32
+ onClick: item.onClick,
33
+ children: renderItemContent(item)
34
+ });
35
+ }
36
+ function DropdownListItem({ item, itemClassName, linkComponent }) {
37
+ if (item.items && item.items.length > 0) {
38
+ const itemStyles = getItemStyles(item);
39
+ return /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [/* @__PURE__ */ jsx(DropdownMenuSubTrigger, {
40
+ className: cn("gap-1.5", getItemClassName(item, itemClassName)),
41
+ style: itemStyles.style,
42
+ children: renderItemContent(item)
43
+ }), /* @__PURE__ */ jsx(DropdownMenuSubContent, {
44
+ sideOffset: 4,
45
+ className: "z-[60] min-w-[8rem]",
46
+ children: item.items?.map((subItem) => /* @__PURE__ */ jsx(DropdownLeafItem, {
47
+ item: subItem,
48
+ itemClassName,
49
+ linkComponent
50
+ }, subItem.id))
51
+ })] });
52
+ }
53
+ return /* @__PURE__ */ jsx(DropdownLeafItem, {
54
+ item,
55
+ itemClassName,
56
+ linkComponent
57
+ });
58
+ }
59
+ //#endregion
60
+ export { DropdownListItem as default };
@@ -0,0 +1,76 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { isPresetColor, resolveColor } from "../../utils/color.js";
3
+ import { LIST_CLASS_NAMES } from "./list.props.js";
4
+ import React from "react";
5
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/components/list/list-item.utils.tsx
7
+ var listItemBase = "min-h-[var(--menu-item-height)] w-full scroll-mt-[calc(var(--spacing)*1.5)] px-[calc(var(--spacing)*2.5)] py-[calc(var(--spacing)*1.5)] my-[calc(var(--spacing)*0.5)] text-sm leading-[var(--tw-leading,var(--text-sm--line-height))] select-none rounded-[10px] items-center flex relative no-underline";
8
+ /**
9
+ * Interaction classes shared by the `<button>` and link renderings of a row, so a
10
+ * linked item is visually identical to a clickable one.
11
+ */
12
+ var listItemInteractive = "w-full text-left cursor-pointer hover:bg-accent focus:bg-accent focus:outline-none";
13
+ var presetColorStyles = {
14
+ primary: "text-primary",
15
+ secondary: "text-secondary-foreground",
16
+ error: "text-error",
17
+ info: "text-info",
18
+ success: "text-success",
19
+ warning: "text-warning",
20
+ disabled: "text-disabled",
21
+ gray: "text-gray",
22
+ mist: "text-mist-foreground"
23
+ };
24
+ var sizeStyles = {
25
+ sm: "text-xs py-1 px-2",
26
+ default: "text-sm py-1.5 px-2",
27
+ lg: "text-base py-2 px-3"
28
+ };
29
+ function isListItem(item) {
30
+ return typeof item === "object" && item !== null && !React.isValidElement(item) && "id" in item && "label" in item && typeof item.id === "string" && typeof item.label === "string";
31
+ }
32
+ function getItemStyles(item) {
33
+ const color = item.color || "default";
34
+ const size = item.size || "default";
35
+ const isSelected = item.isSelected || false;
36
+ if (color === "default" || isPresetColor(color) && presetColorStyles[color]) return { className: cn(LIST_CLASS_NAMES.item, listItemBase, color === "default" ? "" : presetColorStyles[color], sizeStyles[size], isSelected && "bg-accent font-medium") };
37
+ const resolved = resolveColor(color, "text");
38
+ return {
39
+ className: cn(LIST_CLASS_NAMES.item, listItemBase, sizeStyles[size], isSelected && "bg-accent font-medium"),
40
+ style: resolved.style
41
+ };
42
+ }
43
+ /**
44
+ * Class string for a non-interactive row (dropdown items, submenu triggers).
45
+ *
46
+ * Caller-supplied classes come last — list-wide `itemClassName` first, then the row's own
47
+ * `className` — so they win over the component's defaults under tailwind-merge.
48
+ */
49
+ function getItemClassName(item, itemClassName) {
50
+ return cn(getItemStyles(item).className, itemClassName, item.className);
51
+ }
52
+ /**
53
+ * Class string for an interactive standard-list row, used by both the `<button>` and the
54
+ * link rendering. Ordering follows {@link getItemClassName}.
55
+ */
56
+ function getInteractiveItemClassName(item, itemClassName) {
57
+ return cn(getItemStyles(item).className, listItemInteractive, itemClassName, item.className);
58
+ }
59
+ function renderItemContent(item) {
60
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
61
+ item.startIcon && /* @__PURE__ */ jsx("span", {
62
+ className: "mr-2 flex-shrink-0",
63
+ children: item.startIcon
64
+ }),
65
+ /* @__PURE__ */ jsx("span", {
66
+ className: "flex-1",
67
+ children: item.label
68
+ }),
69
+ item.endIcon && /* @__PURE__ */ jsx("span", {
70
+ className: "ml-2 flex-shrink-0",
71
+ children: item.endIcon
72
+ })
73
+ ] });
74
+ }
75
+ //#endregion
76
+ export { getInteractiveItemClassName, getItemClassName, getItemStyles, isListItem, renderItemContent, sizeStyles };
@@ -0,0 +1,49 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { DropdownMenuLabel, DropdownMenuSeparator } from "../../core/animate-ui/components/radix/dropdown-menu.js";
3
+ import { LIST_CLASS_NAMES } from "./list.props.js";
4
+ import { isListItem } from "./list-item.utils.js";
5
+ import StandardListItem from "./standard-list-item.js";
6
+ import DropdownListItem from "./dropdown-list-item.js";
7
+ import React from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
+ //#region src/components/list/list.tsx
10
+ var groupLabelBase = "text-sm font-normal truncate overflow-ellipsis font-inter text-gray-400 flex items-center gap-2";
11
+ function List({ items, role = "list", showSeparators = true, className, itemClassName, separatorClassName, linkComponent }) {
12
+ const shouldShowSeparators = showSeparators && items.length > 1;
13
+ const isDropdown = role === "dropdown-list";
14
+ const ItemComponent = isDropdown ? DropdownListItem : StandardListItem;
15
+ return /* @__PURE__ */ jsx(isDropdown ? React.Fragment : ({ children }) => /* @__PURE__ */ jsx("div", {
16
+ className: cn(LIST_CLASS_NAMES.container, "flex flex-col", className),
17
+ children
18
+ }), { children: items.map((group, groupIndex) => {
19
+ const isLastGroup = groupIndex === items.length - 1;
20
+ const labelContent = group.label && /* @__PURE__ */ jsxs(Fragment$1, { children: [group.icon && /* @__PURE__ */ jsx("span", {
21
+ className: "flex-shrink-0",
22
+ children: group.icon
23
+ }), /* @__PURE__ */ jsx("span", { children: group.label })] });
24
+ const labelClassName = cn(LIST_CLASS_NAMES.groupLabel, groupLabelBase, !isDropdown && "px-2.5 py-1.5", group.labelClassName);
25
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
26
+ group.label && (isDropdown ? /* @__PURE__ */ jsx(DropdownMenuLabel, {
27
+ className: labelClassName,
28
+ children: labelContent
29
+ }) : /* @__PURE__ */ jsx("div", {
30
+ className: labelClassName,
31
+ children: labelContent
32
+ })),
33
+ group.items.map((item, index) => {
34
+ if (isListItem(item)) return /* @__PURE__ */ jsx(ItemComponent, {
35
+ item,
36
+ itemClassName,
37
+ linkComponent
38
+ }, item.id);
39
+ else return /* @__PURE__ */ jsx("div", {
40
+ className: cn(LIST_CLASS_NAMES.customItem, "px-2.5 py-1.5", itemClassName),
41
+ children: item
42
+ }, index);
43
+ }),
44
+ shouldShowSeparators && !isLastGroup && (isDropdown ? /* @__PURE__ */ jsx(DropdownMenuSeparator, { className: cn(LIST_CLASS_NAMES.separator, separatorClassName) }) : /* @__PURE__ */ jsx("hr", { className: cn(LIST_CLASS_NAMES.separator, "my-1 border-border", separatorClassName) }))
45
+ ] }, group.id);
46
+ }) });
47
+ }
48
+ //#endregion
49
+ export { List as default };
@@ -0,0 +1,27 @@
1
+ //#region src/components/list/list.props.ts
2
+ /**
3
+ * Stable class hooks on every rendered part of a `List`, so consumers can target them
4
+ * from Tailwind arbitrary variants (`[&_.espd-list-item]:rounded-none`) or plain CSS
5
+ * without depending on the component's internal utility classes.
6
+ *
7
+ * These are contract: they are always present, and they are emitted *before* any
8
+ * caller-supplied `className`, so caller utilities win under tailwind-merge.
9
+ *
10
+ * The `espd-` prefix is required, not cosmetic: an unprefixed `list-item` is a real
11
+ * Tailwind `display` utility, so `twMerge` would drop it as soon as the component added
12
+ * `flex` — and `list-*` is Tailwind's list-style namespace generally.
13
+ */
14
+ var LIST_CLASS_NAMES = {
15
+ /** Flex column wrapping every group. Standard (`role="list"`) rendering only. */
16
+ container: "espd-list",
17
+ /** Heading rendered for a {@link ListGroup.label}. */
18
+ groupLabel: "espd-list-group-label",
19
+ /** Every row rendered from a {@link ListItem}, in both roles and at any nesting depth. */
20
+ item: "espd-list-item",
21
+ /** Wrapper around a raw `ReactNode` passed in {@link ListGroup.items}. */
22
+ customItem: "espd-list-custom-item",
23
+ /** Divider drawn between groups. */
24
+ separator: "espd-list-separator"
25
+ };
26
+ //#endregion
27
+ export { LIST_CLASS_NAMES };
@@ -0,0 +1,66 @@
1
+ import { cn } from "../../utils/cn.js";
2
+ import { getInteractiveItemClassName, getItemStyles, renderItemContent } from "./list-item.utils.js";
3
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../core/collapsible.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { ChevronDown } from "lucide-react";
6
+ //#region src/components/list/standard-list-item.tsx
7
+ /**
8
+ * Leaf row: a real link when the item declares `href` and an adapter is available,
9
+ * otherwise the plain click button. Both share `getInteractiveItemClassName`, so the
10
+ * two renderings are visually identical.
11
+ */
12
+ function StandardLeafItem({ item, itemClassName, linkComponent: LinkComponent }) {
13
+ const itemStyles = getItemStyles(item);
14
+ const className = getInteractiveItemClassName(item, itemClassName);
15
+ if (item.href && LinkComponent) return /* @__PURE__ */ jsx(LinkComponent, {
16
+ to: item.href,
17
+ className,
18
+ style: itemStyles.style,
19
+ "aria-current": item.isSelected ? "page" : void 0,
20
+ children: renderItemContent(item)
21
+ });
22
+ return /* @__PURE__ */ jsx("button", {
23
+ type: "button",
24
+ className,
25
+ style: itemStyles.style,
26
+ onClick: item.onClick,
27
+ children: renderItemContent(item)
28
+ });
29
+ }
30
+ function StandardListItem({ item, itemClassName, linkComponent }) {
31
+ if (item.items && item.items.length > 0) {
32
+ const itemStyles = getItemStyles(item);
33
+ return /* @__PURE__ */ jsxs(Collapsible, {
34
+ className: "w-full",
35
+ children: [/* @__PURE__ */ jsx(CollapsibleTrigger, {
36
+ asChild: true,
37
+ children: /* @__PURE__ */ jsxs("button", {
38
+ type: "button",
39
+ className: cn("group", getInteractiveItemClassName(item, itemClassName)),
40
+ style: itemStyles.style,
41
+ children: [/* @__PURE__ */ jsx("span", {
42
+ className: "flex flex-1 items-center",
43
+ children: renderItemContent(item)
44
+ }), /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 transition-transform duration-200 group-data-[state=open]:rotate-180" })]
45
+ })
46
+ }), /* @__PURE__ */ jsx(CollapsibleContent, {
47
+ className: "w-full",
48
+ children: /* @__PURE__ */ jsx("div", {
49
+ className: "pl-4 w-full",
50
+ children: item.items?.map((subItem) => /* @__PURE__ */ jsx(StandardLeafItem, {
51
+ item: subItem,
52
+ itemClassName,
53
+ linkComponent
54
+ }, subItem.id))
55
+ })
56
+ })]
57
+ });
58
+ }
59
+ return /* @__PURE__ */ jsx(StandardLeafItem, {
60
+ item,
61
+ itemClassName,
62
+ linkComponent
63
+ });
64
+ }
65
+ //#endregion
66
+ export { StandardListItem as default };
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import { cn } from "../../utils/cn.js";
3
+ import { Button } from "../button/button.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { ChevronRight } from "lucide-react";
6
+ //#region src/components/list-details/list-details-item-button.tsx
7
+ /** One item of the vertical title list: the side panel, or the small-screen dropdown. */
8
+ function ListDetailsItemButton({ item, isSelected, onSelect, showDefaultEndIcon }) {
9
+ const defaultEndIcon = showDefaultEndIcon ? /* @__PURE__ */ jsx(ChevronRight, {
10
+ className: "size-4",
11
+ "aria-hidden": true
12
+ }) : null;
13
+ const endIcon = item.endIcon ?? defaultEndIcon;
14
+ if (typeof item.title !== "string") return /* @__PURE__ */ jsxs("button", {
15
+ type: "button",
16
+ onClick: () => onSelect(item.id),
17
+ "aria-pressed": isSelected,
18
+ className: cn("flex w-full items-center gap-2 rounded-md px-3 py-2 text-left", "border-0 bg-transparent shadow-none", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"),
19
+ children: [/* @__PURE__ */ jsx("span", {
20
+ className: "flex min-w-0 flex-1 items-center",
21
+ children: item.title
22
+ }), endIcon != null && /* @__PURE__ */ jsx("span", {
23
+ className: "shrink-0",
24
+ children: endIcon
25
+ })]
26
+ });
27
+ return /* @__PURE__ */ jsx(Button, {
28
+ type: "button",
29
+ variant: isSelected ? "outline" : "ghost",
30
+ color: isSelected ? "primary" : "gray",
31
+ onClick: () => onSelect(item.id),
32
+ "aria-pressed": isSelected,
33
+ className: !isSelected ? "border border-transparent" : "",
34
+ endIcon: endIcon ?? void 0,
35
+ hideRingOnHover: true,
36
+ children: /* @__PURE__ */ jsx("span", {
37
+ className: "flex min-w-0 flex-1 items-center",
38
+ children: /* @__PURE__ */ jsx("span", {
39
+ className: "min-w-0 truncate",
40
+ children: item.title
41
+ })
42
+ })
43
+ });
44
+ }
45
+ //#endregion
46
+ export { ListDetailsItemButton };
@@ -0,0 +1,112 @@
1
+ "use client";
2
+ import { cn } from "../../utils/cn.js";
3
+ import { Button } from "../button/button.js";
4
+ import { ScrollArea } from "../../core/scroll-area.js";
5
+ import { ListDetailsItemButton } from "./list-details-item-button.js";
6
+ import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../../core/popover.js";
7
+ import { useRef, useState } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { ChevronDown, ChevronLeft, ChevronRight } from "lucide-react";
10
+ //#region src/components/list-details/list-details-item-dropdown.tsx
11
+ function focusSelectedItem(list) {
12
+ list?.querySelector("[aria-pressed=\"true\"]")?.focus();
13
+ }
14
+ /**
15
+ * The item picker on small screens: previous/next arrows around a menu button
16
+ * showing the selected title. The menu lists every item, with the `footer`
17
+ * (e.g. "Load more") at its bottom, as under the side panel.
18
+ */
19
+ function ListDetailsItemDropdown({ data, selectedId, onSelect, footer, labels, className }) {
20
+ const [open, setOpen] = useState(false);
21
+ const listRef = useRef(null);
22
+ const selectedIndex = data.findIndex((item) => item.id === selectedId);
23
+ const selectedItem = data[selectedIndex];
24
+ const previousItem = selectedIndex > 0 ? data[selectedIndex - 1] : void 0;
25
+ const nextItem = selectedIndex >= 0 ? data[selectedIndex + 1] : void 0;
26
+ const handleSelect = (itemId) => {
27
+ onSelect(itemId);
28
+ setOpen(false);
29
+ };
30
+ return /* @__PURE__ */ jsxs(Popover, {
31
+ open,
32
+ onOpenChange: setOpen,
33
+ children: [/* @__PURE__ */ jsx(PopoverAnchor, {
34
+ asChild: true,
35
+ children: /* @__PURE__ */ jsxs("div", {
36
+ "data-slot": "list-details-item-dropdown",
37
+ className: cn("flex items-center gap-2", className),
38
+ children: [
39
+ /* @__PURE__ */ jsx(Button, {
40
+ type: "button",
41
+ size: "icon",
42
+ variant: "outline",
43
+ color: "gray",
44
+ "aria-label": labels.previousItem,
45
+ disabled: previousItem == null,
46
+ onClick: () => previousItem && onSelect(previousItem.id),
47
+ children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": true })
48
+ }),
49
+ /* @__PURE__ */ jsx(PopoverTrigger, {
50
+ asChild: true,
51
+ children: /* @__PURE__ */ jsx(Button, {
52
+ type: "button",
53
+ variant: "outline",
54
+ color: "gray",
55
+ className: "min-w-0 flex-1 justify-between px-3",
56
+ endIcon: /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": true }),
57
+ children: /* @__PURE__ */ jsxs("span", {
58
+ className: "flex min-w-0 flex-1 items-center",
59
+ children: [
60
+ /* @__PURE__ */ jsxs("span", {
61
+ className: "sr-only",
62
+ children: [labels.chooseItem, ":"]
63
+ }),
64
+ " ",
65
+ typeof selectedItem?.title === "string" ? /* @__PURE__ */ jsx("span", {
66
+ className: "min-w-0 truncate",
67
+ children: selectedItem.title
68
+ }) : selectedItem?.title
69
+ ]
70
+ })
71
+ })
72
+ }),
73
+ /* @__PURE__ */ jsx(Button, {
74
+ type: "button",
75
+ size: "icon",
76
+ variant: "outline",
77
+ color: "gray",
78
+ "aria-label": labels.nextItem,
79
+ disabled: nextItem == null,
80
+ onClick: () => nextItem && onSelect(nextItem.id),
81
+ children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true })
82
+ })
83
+ ]
84
+ })
85
+ }), /* @__PURE__ */ jsxs(PopoverContent, {
86
+ align: "start",
87
+ className: "flex w-[var(--radix-popover-trigger-width)] max-h-[min(24rem,var(--radix-popover-content-available-height))] flex-col gap-2 p-2",
88
+ onOpenAutoFocus: (event) => {
89
+ event.preventDefault();
90
+ focusSelectedItem(listRef.current);
91
+ },
92
+ children: [/* @__PURE__ */ jsx(ScrollArea, {
93
+ className: "min-h-0 flex-1",
94
+ children: /* @__PURE__ */ jsx("div", {
95
+ ref: listRef,
96
+ className: "flex flex-col gap-2",
97
+ children: data.map((item) => /* @__PURE__ */ jsx(ListDetailsItemButton, {
98
+ item,
99
+ isSelected: item.id === selectedId,
100
+ onSelect: handleSelect,
101
+ showDefaultEndIcon: false
102
+ }, item.id))
103
+ })
104
+ }), footer != null ? /* @__PURE__ */ jsx("div", {
105
+ className: "shrink-0",
106
+ children: footer
107
+ }) : null]
108
+ })]
109
+ });
110
+ }
111
+ //#endregion
112
+ export { ListDetailsItemDropdown };
@@ -0,0 +1,125 @@
1
+ "use client";
2
+ import { cn } from "../../utils/cn.js";
3
+ import { Button } from "../button/button.js";
4
+ import { useScrollOverflow } from "../../core/hooks/use-scroll-overflow.js";
5
+ import { useEffect, useRef } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { ChevronLeft, ChevronRight } from "lucide-react";
8
+ //#region src/components/list-details/list-details-item-strip.tsx
9
+ /** Width of the edge fade, and the margin kept beside the selected item when it is scrolled into view. */
10
+ var EDGE_SIZE = 24;
11
+ function prefersReducedMotion() {
12
+ return typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
13
+ }
14
+ function fadeMask(start, end) {
15
+ if (!start && !end) return {};
16
+ const image = `linear-gradient(to right, ${start ? `transparent, #000 ${EDGE_SIZE}px` : "#000"}, ${end ? `#000 calc(100% - ${EDGE_SIZE}px), transparent` : "#000"})`;
17
+ return {
18
+ maskImage: image,
19
+ WebkitMaskImage: image
20
+ };
21
+ }
22
+ var arrowButtonClass = "inline-flex size-8 shrink-0 items-center justify-center rounded-full border border-border bg-background text-muted-foreground transition-colors hover:text-foreground disabled:pointer-events-none disabled:opacity-40";
23
+ /**
24
+ * The item list on small screens: a single scrollable row with arrow buttons,
25
+ * shown above the details instead of the side panel.
26
+ */
27
+ function ListDetailsItemStrip({ data, selectedId, onSelect, className }) {
28
+ const scrollerRef = useRef(null);
29
+ const overflow = useScrollOverflow(scrollerRef, { getContent: (scroller) => scroller.firstElementChild });
30
+ const hasOverflow = overflow.start || overflow.end;
31
+ const mountedRef = useRef(false);
32
+ useEffect(() => {
33
+ const scroller = scrollerRef.current;
34
+ const selected = scroller?.querySelector("[aria-pressed=\"true\"]");
35
+ if (!scroller || !selected) return;
36
+ const scrollerRect = scroller.getBoundingClientRect();
37
+ if (scrollerRect.width === 0) return;
38
+ const itemRect = selected.getBoundingClientRect();
39
+ const overStart = itemRect.left - (scrollerRect.left + EDGE_SIZE);
40
+ const overEnd = itemRect.right - (scrollerRect.right - EDGE_SIZE);
41
+ let delta = 0;
42
+ if (overStart < 0) delta = overStart;
43
+ else if (overEnd > 0) delta = Math.min(overEnd, overStart);
44
+ const instant = !mountedRef.current || prefersReducedMotion();
45
+ mountedRef.current = true;
46
+ if (Math.abs(delta) >= 1) scroller.scrollBy({
47
+ left: delta,
48
+ behavior: instant ? "auto" : "smooth"
49
+ });
50
+ }, [selectedId, hasOverflow]);
51
+ const scrollByPage = (direction) => {
52
+ const scroller = scrollerRef.current;
53
+ if (!scroller) return;
54
+ scroller.scrollBy({
55
+ left: direction * scroller.clientWidth * .8,
56
+ behavior: prefersReducedMotion() ? "auto" : "smooth"
57
+ });
58
+ };
59
+ return /* @__PURE__ */ jsxs("div", {
60
+ "data-slot": "list-details-item-strip",
61
+ className: cn("flex items-center gap-1", className),
62
+ children: [
63
+ hasOverflow && /* @__PURE__ */ jsx("button", {
64
+ type: "button",
65
+ tabIndex: -1,
66
+ "aria-hidden": true,
67
+ disabled: !overflow.start,
68
+ className: arrowButtonClass,
69
+ onClick: () => scrollByPage(-1),
70
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" })
71
+ }),
72
+ /* @__PURE__ */ jsx("div", {
73
+ ref: scrollerRef,
74
+ className: "min-w-0 flex-1 overflow-x-auto overscroll-x-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
75
+ style: fadeMask(overflow.start, overflow.end),
76
+ children: /* @__PURE__ */ jsx("div", {
77
+ className: "flex w-max gap-2 p-1",
78
+ children: data.map((item) => {
79
+ const isSelected = selectedId === item.id;
80
+ if (typeof item.title !== "string") return /* @__PURE__ */ jsxs("button", {
81
+ type: "button",
82
+ onClick: () => onSelect(item.id),
83
+ "aria-pressed": isSelected,
84
+ className: cn("flex shrink-0 items-center gap-2 rounded-md px-3 py-2 text-left", "border-0 bg-transparent shadow-none", "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"),
85
+ children: [/* @__PURE__ */ jsx("span", {
86
+ className: "flex items-center",
87
+ children: item.title
88
+ }), item.endIcon != null && /* @__PURE__ */ jsx("span", {
89
+ className: "shrink-0",
90
+ children: item.endIcon
91
+ })]
92
+ }, item.id);
93
+ return /* @__PURE__ */ jsx(Button, {
94
+ type: "button",
95
+ fullWidth: false,
96
+ variant: isSelected ? "outline" : "ghost",
97
+ color: isSelected ? "primary" : "gray",
98
+ onClick: () => onSelect(item.id),
99
+ "aria-pressed": isSelected,
100
+ className: cn("shrink-0", !isSelected && "border border-transparent"),
101
+ endIcon: item.endIcon,
102
+ hideRingOnHover: true,
103
+ children: /* @__PURE__ */ jsx("span", {
104
+ className: "max-w-48 truncate",
105
+ title: item.title,
106
+ children: item.title
107
+ })
108
+ }, item.id);
109
+ })
110
+ })
111
+ }),
112
+ hasOverflow && /* @__PURE__ */ jsx("button", {
113
+ type: "button",
114
+ tabIndex: -1,
115
+ "aria-hidden": true,
116
+ disabled: !overflow.end,
117
+ className: arrowButtonClass,
118
+ onClick: () => scrollByPage(1),
119
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
120
+ })
121
+ ]
122
+ });
123
+ }
124
+ //#endregion
125
+ export { ListDetailsItemStrip };