@od-oneapp/uni-ui 2026.1.1301
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.
- package/README.md +753 -0
- package/dist/actions-C-SEx2GS.mjs +180 -0
- package/dist/actions-C-SEx2GS.mjs.map +1 -0
- package/dist/actions-Ch7h6cYC.d.mts +50 -0
- package/dist/actions-Cnupw96c.d.mts +50 -0
- package/dist/alert-BVUF7Xzb.d.mts +22 -0
- package/dist/alert-BuPyEXF-.mjs +206 -0
- package/dist/alert-BuPyEXF-.mjs.map +1 -0
- package/dist/alert-CfjDnZpm.d.mts +22 -0
- package/dist/animated-size-container-DSKNt1Cn.mjs +106 -0
- package/dist/animated-size-container-DSKNt1Cn.mjs.map +1 -0
- package/dist/areas-CtE8w69A.mjs +144 -0
- package/dist/areas-CtE8w69A.mjs.map +1 -0
- package/dist/areas-DtGnjGuX.d.mts +22 -0
- package/dist/auth-nav-user-CRxDpY_7.d.mts +30 -0
- package/dist/auth-nav-user-DPFv8dTp.mjs +181 -0
- package/dist/auth-nav-user-DPFv8dTp.mjs.map +1 -0
- package/dist/avatar-DjiX7nT8.mjs +202 -0
- package/dist/avatar-DjiX7nT8.mjs.map +1 -0
- package/dist/badge-CGTN2VG0.d.mts +25 -0
- package/dist/badge-CVoIuyYX.mjs +242 -0
- package/dist/badge-CVoIuyYX.mjs.map +1 -0
- package/dist/badge-DH0tY3wJ.d.mts +25 -0
- package/dist/bars-CWTAPKgm.d.mts +20 -0
- package/dist/bars-DOLvecrq.mjs +125 -0
- package/dist/bars-DOLvecrq.mjs.map +1 -0
- package/dist/branch-BEl6eS77.mjs +323 -0
- package/dist/branch-BEl6eS77.mjs.map +1 -0
- package/dist/branch-BtdY_TLE.d.mts +58 -0
- package/dist/branch-Duq6cW0s.d.mts +58 -0
- package/dist/button-BAdq0gBE.d.mts +31 -0
- package/dist/button-DVOrrZLw.mjs +632 -0
- package/dist/button-DVOrrZLw.mjs.map +1 -0
- package/dist/button-DnjeAftr.d.mts +31 -0
- package/dist/carousel-D-J1Zgn1.d.mts +49 -0
- package/dist/carousel-Dx5AOW5k.mjs +345 -0
- package/dist/carousel-Dx5AOW5k.mjs.map +1 -0
- package/dist/carousel-sY0y1-or.d.mts +49 -0
- package/dist/chart-context-CLV35VLJ.mjs +27 -0
- package/dist/chart-context-CLV35VLJ.mjs.map +1 -0
- package/dist/checkbox-wiF-DV6q.mjs +194 -0
- package/dist/checkbox-wiF-DV6q.mjs.map +1 -0
- package/dist/code-block-Cg_XtPH7.mjs +243 -0
- package/dist/code-block-Cg_XtPH7.mjs.map +1 -0
- package/dist/collapsible-CRgTpRfr.d.mts +46 -0
- package/dist/collapsible-CXy4T04n.mjs +239 -0
- package/dist/collapsible-CXy4T04n.mjs.map +1 -0
- package/dist/combobox-DSrxSkSl.d.mts +79 -0
- package/dist/combobox-DYFh2eZf.d.mts +79 -0
- package/dist/combobox-uEKksQFR.mjs +410 -0
- package/dist/combobox-uEKksQFR.mjs.map +1 -0
- package/dist/command-xK3X_A9t.mjs +206 -0
- package/dist/command-xK3X_A9t.mjs.map +1 -0
- package/dist/components-ai-elements/actions/index.d.mts +5 -0
- package/dist/components-ai-elements/actions/index.mjs +4 -0
- package/dist/components-ai-elements/agent-step/index.d.mts +32 -0
- package/dist/components-ai-elements/agent-step/index.mjs +183 -0
- package/dist/components-ai-elements/agent-step/index.mjs.map +1 -0
- package/dist/components-ai-elements/artifact/index.d.mts +81 -0
- package/dist/components-ai-elements/artifact/index.mjs +153 -0
- package/dist/components-ai-elements/artifact/index.mjs.map +1 -0
- package/dist/components-ai-elements/branch/index.d.mts +5 -0
- package/dist/components-ai-elements/branch/index.mjs +4 -0
- package/dist/components-ai-elements/chain-of-thought/index.d.mts +90 -0
- package/dist/components-ai-elements/chain-of-thought/index.mjs +338 -0
- package/dist/components-ai-elements/chain-of-thought/index.mjs.map +1 -0
- package/dist/components-ai-elements/chat-input/index.d.mts +21 -0
- package/dist/components-ai-elements/chat-input/index.mjs +137 -0
- package/dist/components-ai-elements/chat-input/index.mjs.map +1 -0
- package/dist/components-ai-elements/checkpoint/index.d.mts +46 -0
- package/dist/components-ai-elements/checkpoint/index.mjs +161 -0
- package/dist/components-ai-elements/checkpoint/index.mjs.map +1 -0
- package/dist/components-ai-elements/code-block/index.d.mts +39 -0
- package/dist/components-ai-elements/code-block/index.mjs +4 -0
- package/dist/components-ai-elements/confirmation/index.d.mts +96 -0
- package/dist/components-ai-elements/confirmation/index.mjs +295 -0
- package/dist/components-ai-elements/confirmation/index.mjs.map +1 -0
- package/dist/components-ai-elements/context/index.d.mts +83 -0
- package/dist/components-ai-elements/context/index.mjs +456 -0
- package/dist/components-ai-elements/context/index.mjs.map +1 -0
- package/dist/components-ai-elements/conversation/index.d.mts +46 -0
- package/dist/components-ai-elements/conversation/index.mjs +180 -0
- package/dist/components-ai-elements/conversation/index.mjs.map +1 -0
- package/dist/components-ai-elements/custom/index.d.mts +1142 -0
- package/dist/components-ai-elements/custom/index.mjs +5578 -0
- package/dist/components-ai-elements/custom/index.mjs.map +1 -0
- package/dist/components-ai-elements/generative-ui/index.d.mts +4 -0
- package/dist/components-ai-elements/generative-ui/index.mjs +4 -0
- package/dist/components-ai-elements/image/index.d.mts +20 -0
- package/dist/components-ai-elements/image/index.mjs +121 -0
- package/dist/components-ai-elements/image/index.mjs.map +1 -0
- package/dist/components-ai-elements/inline-citation/index.d.mts +94 -0
- package/dist/components-ai-elements/inline-citation/index.mjs +371 -0
- package/dist/components-ai-elements/inline-citation/index.mjs.map +1 -0
- package/dist/components-ai-elements/loader/index.d.mts +24 -0
- package/dist/components-ai-elements/loader/index.mjs +4 -0
- package/dist/components-ai-elements/message/index.d.mts +153 -0
- package/dist/components-ai-elements/message/index.mjs +597 -0
- package/dist/components-ai-elements/message/index.mjs.map +1 -0
- package/dist/components-ai-elements/model-selector/index.d.mts +72 -0
- package/dist/components-ai-elements/model-selector/index.mjs +224 -0
- package/dist/components-ai-elements/model-selector/index.mjs.map +1 -0
- package/dist/components-ai-elements/open-in-chat/index.d.mts +64 -0
- package/dist/components-ai-elements/open-in-chat/index.mjs +502 -0
- package/dist/components-ai-elements/open-in-chat/index.mjs.map +1 -0
- package/dist/components-ai-elements/plan/index.d.mts +71 -0
- package/dist/components-ai-elements/plan/index.mjs +219 -0
- package/dist/components-ai-elements/plan/index.mjs.map +1 -0
- package/dist/components-ai-elements/prompt-char-counter/index.d.mts +19 -0
- package/dist/components-ai-elements/prompt-char-counter/index.mjs +116 -0
- package/dist/components-ai-elements/prompt-char-counter/index.mjs.map +1 -0
- package/dist/components-ai-elements/prompt-input/index.d.mts +386 -0
- package/dist/components-ai-elements/prompt-input/index.mjs +4 -0
- package/dist/components-ai-elements/queue/index.d.mts +121 -0
- package/dist/components-ai-elements/queue/index.mjs +284 -0
- package/dist/components-ai-elements/queue/index.mjs.map +1 -0
- package/dist/components-ai-elements/reasoning/index.d.mts +42 -0
- package/dist/components-ai-elements/reasoning/index.mjs +241 -0
- package/dist/components-ai-elements/reasoning/index.mjs.map +1 -0
- package/dist/components-ai-elements/shimmer/index.d.mts +23 -0
- package/dist/components-ai-elements/shimmer/index.mjs +4 -0
- package/dist/components-ai-elements/sources/index.d.mts +56 -0
- package/dist/components-ai-elements/sources/index.mjs +211 -0
- package/dist/components-ai-elements/sources/index.mjs.map +1 -0
- package/dist/components-ai-elements/suggestion/index.d.mts +40 -0
- package/dist/components-ai-elements/suggestion/index.mjs +145 -0
- package/dist/components-ai-elements/suggestion/index.mjs.map +1 -0
- package/dist/components-ai-elements/task/index.d.mts +70 -0
- package/dist/components-ai-elements/task/index.mjs +218 -0
- package/dist/components-ai-elements/task/index.mjs.map +1 -0
- package/dist/components-ai-elements/tool/index.d.mts +78 -0
- package/dist/components-ai-elements/tool/index.mjs +370 -0
- package/dist/components-ai-elements/tool/index.mjs.map +1 -0
- package/dist/components-ai-elements/tool-approval/index.d.mts +20 -0
- package/dist/components-ai-elements/tool-approval/index.mjs +252 -0
- package/dist/components-ai-elements/tool-approval/index.mjs.map +1 -0
- package/dist/components-ai-elements/web-preview/index.d.mts +136 -0
- package/dist/components-ai-elements/web-preview/index.mjs +773 -0
- package/dist/components-ai-elements/web-preview/index.mjs.map +1 -0
- package/dist/components-ai-elements-constants.d.mts +207 -0
- package/dist/components-ai-elements-constants.mjs +301 -0
- package/dist/components-ai-elements-constants.mjs.map +1 -0
- package/dist/components-ai-workflows/canvas/index.d.mts +22 -0
- package/dist/components-ai-workflows/canvas/index.mjs +135 -0
- package/dist/components-ai-workflows/canvas/index.mjs.map +1 -0
- package/dist/components-ai-workflows/connection/index.d.mts +22 -0
- package/dist/components-ai-workflows/connection/index.mjs +4 -0
- package/dist/components-ai-workflows/controls/index.d.mts +14 -0
- package/dist/components-ai-workflows/controls/index.mjs +89 -0
- package/dist/components-ai-workflows/controls/index.mjs.map +1 -0
- package/dist/components-ai-workflows/edge/index.d.mts +20 -0
- package/dist/components-ai-workflows/edge/index.mjs +102 -0
- package/dist/components-ai-workflows/edge/index.mjs.map +1 -0
- package/dist/components-ai-workflows/node/index.d.mts +3 -0
- package/dist/components-ai-workflows/node/index.mjs +4 -0
- package/dist/components-ai-workflows/panel/index.d.mts +15 -0
- package/dist/components-ai-workflows/panel/index.mjs +89 -0
- package/dist/components-ai-workflows/panel/index.mjs.map +1 -0
- package/dist/components-ai-workflows/resizable-node/index.d.mts +30 -0
- package/dist/components-ai-workflows/resizable-node/index.mjs +164 -0
- package/dist/components-ai-workflows/resizable-node/index.mjs.map +1 -0
- package/dist/components-ai-workflows/toolbar/index.d.mts +19 -0
- package/dist/components-ai-workflows/toolbar/index.mjs +91 -0
- package/dist/components-ai-workflows/toolbar/index.mjs.map +1 -0
- package/dist/components-auth-client-nav-user.d.mts +3 -0
- package/dist/components-auth-client-nav-user.mjs +4 -0
- package/dist/components-auth-client-providers.d.mts +13 -0
- package/dist/components-auth-client-providers.mjs +89 -0
- package/dist/components-auth-client-providers.mjs.map +1 -0
- package/dist/components-auth-client.d.mts +5 -0
- package/dist/components-auth-client.mjs +5 -0
- package/dist/components-auth-server.d.mts +1878 -0
- package/dist/components-auth-server.mjs +32769 -0
- package/dist/components-auth-server.mjs.map +1 -0
- package/dist/components-auth.d.mts +5 -0
- package/dist/components-auth.mjs +5 -0
- package/dist/components-charts/areas/index.d.mts +3 -0
- package/dist/components-charts/areas/index.mjs +4 -0
- package/dist/components-charts/bars/index.d.mts +3 -0
- package/dist/components-charts/bars/index.mjs +4 -0
- package/dist/components-charts/funnel-chart/index.d.mts +3 -0
- package/dist/components-charts/funnel-chart/index.mjs +4 -0
- package/dist/components-charts/mini-area-chart/index.d.mts +3 -0
- package/dist/components-charts/mini-area-chart/index.mjs +4 -0
- package/dist/components-charts/time-series-chart/index.d.mts +3 -0
- package/dist/components-charts/time-series-chart/index.mjs +4 -0
- package/dist/components-charts/tooltip-sync/index.d.mts +3 -0
- package/dist/components-charts/tooltip-sync/index.mjs +4 -0
- package/dist/components-charts/x-axis/index.d.mts +3 -0
- package/dist/components-charts/x-axis/index.mjs +4 -0
- package/dist/components-charts/y-axis/index.d.mts +3 -0
- package/dist/components-charts/y-axis/index.mjs +4 -0
- package/dist/components-elements-accordion.d.mts +59 -0
- package/dist/components-elements-accordion.mjs +275 -0
- package/dist/components-elements-accordion.mjs.map +1 -0
- package/dist/components-elements-alert.d.mts +3 -0
- package/dist/components-elements-alert.mjs +4 -0
- package/dist/components-elements-avatar.d.mts +24 -0
- package/dist/components-elements-avatar.mjs +4 -0
- package/dist/components-elements-badge.d.mts +4 -0
- package/dist/components-elements-badge.mjs +4 -0
- package/dist/components-elements-button.d.mts +4 -0
- package/dist/components-elements-button.mjs +4 -0
- package/dist/components-elements-card.d.mts +3 -0
- package/dist/components-elements-card.mjs +4 -0
- package/dist/components-elements-carousel.d.mts +5 -0
- package/dist/components-elements-carousel.mjs +4 -0
- package/dist/components-elements-chart.d.mts +24 -0
- package/dist/components-elements-chart.mjs +226 -0
- package/dist/components-elements-chart.mjs.map +1 -0
- package/dist/components-elements-collapsible.d.mts +3 -0
- package/dist/components-elements-collapsible.mjs +4 -0
- package/dist/components-elements-dialog.d.mts +3 -0
- package/dist/components-elements-dialog.mjs +4 -0
- package/dist/components-elements-dropdown-menu.d.mts +3 -0
- package/dist/components-elements-dropdown-menu.mjs +4 -0
- package/dist/components-elements-dynamic-breadcrumb.d.mts +16 -0
- package/dist/components-elements-dynamic-breadcrumb.mjs +4 -0
- package/dist/components-elements-empty.d.mts +18 -0
- package/dist/components-elements-empty.mjs +199 -0
- package/dist/components-elements-empty.mjs.map +1 -0
- package/dist/components-elements-hover-card.d.mts +3 -0
- package/dist/components-elements-hover-card.mjs +4 -0
- package/dist/components-elements-loading-dots.d.mts +3 -0
- package/dist/components-elements-loading-dots.mjs +4 -0
- package/dist/components-elements-pagination-controls.d.mts +28 -0
- package/dist/components-elements-pagination-controls.mjs +4 -0
- package/dist/components-elements-progress.d.mts +28 -0
- package/dist/components-elements-progress.mjs +4 -0
- package/dist/components-elements-resizable.d.mts +31 -0
- package/dist/components-elements-resizable.mjs +4 -0
- package/dist/components-elements-scroll-area.d.mts +3 -0
- package/dist/components-elements-scroll-area.mjs +4 -0
- package/dist/components-elements-separator.d.mts +3 -0
- package/dist/components-elements-separator.mjs +4 -0
- package/dist/components-elements-skeleton.d.mts +3 -0
- package/dist/components-elements-skeleton.mjs +4 -0
- package/dist/components-elements-status-badge.d.mts +22 -0
- package/dist/components-elements-status-badge.mjs +174 -0
- package/dist/components-elements-status-badge.mjs.map +1 -0
- package/dist/components-elements-table.d.mts +44 -0
- package/dist/components-elements-table.mjs +4 -0
- package/dist/components-elements-tabs.d.mts +43 -0
- package/dist/components-elements-tabs.mjs +435 -0
- package/dist/components-elements-tabs.mjs.map +1 -0
- package/dist/components-elements-tooltip.d.mts +3 -0
- package/dist/components-elements-tooltip.mjs +4 -0
- package/dist/components-filter/filter-list/index.d.mts +4 -0
- package/dist/components-filter/filter-list/index.mjs +4 -0
- package/dist/components-filter/filter-select/index.d.mts +4 -0
- package/dist/components-filter/filter-select/index.mjs +4 -0
- package/dist/components-forms/checkbox/index.d.mts +27 -0
- package/dist/components-forms/checkbox/index.mjs +4 -0
- package/dist/components-forms/combobox/index.d.mts +5 -0
- package/dist/components-forms/combobox/index.mjs +4 -0
- package/dist/components-forms/date-picker/index.d.mts +3 -0
- package/dist/components-forms/date-picker/index.mjs +4 -0
- package/dist/components-forms/file-upload/index.d.mts +49 -0
- package/dist/components-forms/file-upload/index.mjs +323 -0
- package/dist/components-forms/file-upload/index.mjs.map +1 -0
- package/dist/components-forms/input/index.d.mts +3 -0
- package/dist/components-forms/input/index.mjs +4 -0
- package/dist/components-forms/input-group/index.d.mts +5 -0
- package/dist/components-forms/input-group/index.mjs +4 -0
- package/dist/components-forms/label/index.d.mts +23 -0
- package/dist/components-forms/label/index.mjs +4 -0
- package/dist/components-forms/radio-group/index.d.mts +29 -0
- package/dist/components-forms/radio-group/index.mjs +215 -0
- package/dist/components-forms/radio-group/index.mjs.map +1 -0
- package/dist/components-forms/select/index.d.mts +3 -0
- package/dist/components-forms/select/index.mjs +4 -0
- package/dist/components-forms/switch/index.d.mts +30 -0
- package/dist/components-forms/switch/index.mjs +4 -0
- package/dist/components-forms/textarea/index.d.mts +19 -0
- package/dist/components-forms/textarea/index.mjs +4 -0
- package/dist/components-layout/app-sidebar/index.d.mts +47 -0
- package/dist/components-layout/app-sidebar/index.mjs +340 -0
- package/dist/components-layout/app-sidebar/index.mjs.map +1 -0
- package/dist/components-layout/artifact-panel/index.d.mts +3 -0
- package/dist/components-layout/artifact-panel/index.mjs +4 -0
- package/dist/components-layout/content-sidebar/index.d.mts +89 -0
- package/dist/components-layout/content-sidebar/index.mjs +202 -0
- package/dist/components-layout/content-sidebar/index.mjs.map +1 -0
- package/dist/components-layout/nav-app-switcher/index.d.mts +3 -0
- package/dist/components-layout/nav-app-switcher/index.mjs +4 -0
- package/dist/components-layout/nav-main/index.d.mts +30 -0
- package/dist/components-layout/nav-main/index.mjs +4 -0
- package/dist/components-layout/nav-projects/index.d.mts +18 -0
- package/dist/components-layout/nav-projects/index.mjs +153 -0
- package/dist/components-layout/nav-projects/index.mjs.map +1 -0
- package/dist/components-layout/nav-secondary/index.d.mts +31 -0
- package/dist/components-layout/nav-secondary/index.mjs +4 -0
- package/dist/components-layout/nav-user/index.d.mts +17 -0
- package/dist/components-layout/nav-user/index.mjs +4 -0
- package/dist/components-layout/oneapp/index.mjs +4 -0
- package/dist/components-layout/sidebar/index.d.mts +8 -0
- package/dist/components-layout/sidebar/index.mjs +4 -0
- package/dist/components-layout/sidebar-inset-header-portal/index.d.mts +3 -0
- package/dist/components-layout/sidebar-inset-header-portal/index.mjs +4 -0
- package/dist/components-layout/sidebar-slots/index.d.mts +3 -0
- package/dist/components-layout/sidebar-slots/index.mjs +4 -0
- package/dist/components-layout/theme-provider/index.d.mts +15 -0
- package/dist/components-layout/theme-provider/index.mjs +4 -0
- package/dist/components-layout-app-shell.d.mts +83 -0
- package/dist/components-layout-app-shell.mjs +185 -0
- package/dist/components-layout-app-shell.mjs.map +1 -0
- package/dist/components-layout-oneapp.d.mts +84 -0
- package/dist/components-layout-oneapp.mjs +4 -0
- package/dist/components-overlays-confirm-dialog.d.mts +38 -0
- package/dist/components-overlays-confirm-dialog.mjs +145 -0
- package/dist/components-overlays-confirm-dialog.mjs.map +1 -0
- package/dist/components-overlays-toast.d.mts +16 -0
- package/dist/components-overlays-toast.mjs +127 -0
- package/dist/components-overlays-toast.mjs.map +1 -0
- package/dist/connection-D_kWZtAX.mjs +105 -0
- package/dist/connection-D_kWZtAX.mjs.map +1 -0
- package/dist/dark-mode-B4L-MZr7.mjs +288 -0
- package/dist/dark-mode-B4L-MZr7.mjs.map +1 -0
- package/dist/dark-mode-CYb7lJ6G.d.mts +191 -0
- package/dist/date-range-picker-CdemRFs_.mjs +676 -0
- package/dist/date-range-picker-CdemRFs_.mjs.map +1 -0
- package/dist/dialog-Di5QhIga.d.mts +31 -0
- package/dist/dialog-DuluSpxA.mjs +293 -0
- package/dist/dialog-DuluSpxA.mjs.map +1 -0
- package/dist/dropdown-menu-91g1g_Cl.mjs +379 -0
- package/dist/dropdown-menu-91g1g_Cl.mjs.map +1 -0
- package/dist/dropdown-menu-CwRZCnNs.d.mts +91 -0
- package/dist/dynamic-breadcrumb-33t_hdEI.mjs +385 -0
- package/dist/dynamic-breadcrumb-33t_hdEI.mjs.map +1 -0
- package/dist/error-boundary-Ggc5btkU.mjs +297 -0
- package/dist/error-boundary-Ggc5btkU.mjs.map +1 -0
- package/dist/filter-list-BMT7Nrli.d.mts +27 -0
- package/dist/filter-list-B_9aV5Lp.mjs +279 -0
- package/dist/filter-list-B_9aV5Lp.mjs.map +1 -0
- package/dist/filter-select-COLb1S5z.d.mts +34 -0
- package/dist/filter-select-CYfBhJ_E.mjs +341 -0
- package/dist/filter-select-CYfBhJ_E.mjs.map +1 -0
- package/dist/fonts.d.mts +22 -0
- package/dist/fonts.mjs +104 -0
- package/dist/fonts.mjs.map +1 -0
- package/dist/funnel-chart-CUpUr1pl.d.mts +22 -0
- package/dist/funnel-chart-fdwagDvc.mjs +318 -0
- package/dist/funnel-chart-fdwagDvc.mjs.map +1 -0
- package/dist/generative-ui-renderer-D0ZgNRZF.mjs +484 -0
- package/dist/generative-ui-renderer-D0ZgNRZF.mjs.map +1 -0
- package/dist/generative-ui-renderer-D69qYK0D.d.mts +32 -0
- package/dist/hooks/index.d.mts +5 -0
- package/dist/hooks/index.mjs +6 -0
- package/dist/hooks/use-mobile.d.mts +6 -0
- package/dist/hooks/use-mobile.mjs +45 -0
- package/dist/hooks/use-mobile.mjs.map +1 -0
- package/dist/hooks/use-responsive.d.mts +13 -0
- package/dist/hooks/use-responsive.mjs +50 -0
- package/dist/hooks/use-responsive.mjs.map +1 -0
- package/dist/hooks/use-scroll-progress.d.mts +17 -0
- package/dist/hooks/use-scroll-progress.mjs +62 -0
- package/dist/hooks/use-scroll-progress.mjs.map +1 -0
- package/dist/hooks/use-toast.d.mts +21 -0
- package/dist/hooks/use-toast.mjs +40 -0
- package/dist/hooks/use-toast.mjs.map +1 -0
- package/dist/hover-card-BqEpbXMp.d.mts +31 -0
- package/dist/hover-card-nn4fjJOh.mjs +161 -0
- package/dist/hover-card-nn4fjJOh.mjs.map +1 -0
- package/dist/index-AwyfWaOP.d.mts +60 -0
- package/dist/index.d.mts +503 -0
- package/dist/index.mjs +2158 -0
- package/dist/index.mjs.map +1 -0
- package/dist/input-CT1C9DMs.d.mts +19 -0
- package/dist/input-D0T5jbR6.d.mts +19 -0
- package/dist/input-DhpkXN3J.mjs +176 -0
- package/dist/input-DhpkXN3J.mjs.map +1 -0
- package/dist/input-group-CTBpkGI9.mjs +231 -0
- package/dist/input-group-CTBpkGI9.mjs.map +1 -0
- package/dist/input-group-DcDPUaQ3.d.mts +20 -0
- package/dist/input-group-VSZJM_on.d.mts +20 -0
- package/dist/integrations-COjiOhkd.d.mts +60 -0
- package/dist/integrations-Doz6nfxm.d.mts +60 -0
- package/dist/integrations-lBG309ZD.mjs +471 -0
- package/dist/integrations-lBG309ZD.mjs.map +1 -0
- package/dist/label-DnUThLUR.mjs +148 -0
- package/dist/label-DnUThLUR.mjs.map +1 -0
- package/dist/lib/export-csv.d.mts +12 -0
- package/dist/lib/export-csv.mjs +63 -0
- package/dist/lib/export-csv.mjs.map +1 -0
- package/dist/lib/index.d.mts +6 -0
- package/dist/lib/index.mjs +7 -0
- package/dist/lib/resize-image.d.mts +11 -0
- package/dist/lib/resize-image.mjs +66 -0
- package/dist/lib/resize-image.mjs.map +1 -0
- package/dist/lib/stable-sort.d.mts +6 -0
- package/dist/lib/stable-sort.mjs +33 -0
- package/dist/lib/stable-sort.mjs.map +1 -0
- package/dist/lib/utils.d.mts +8 -0
- package/dist/lib/utils.mjs +4 -0
- package/dist/lib-utils.mjs +4 -0
- package/dist/loader-B2SF0yPJ.mjs +168 -0
- package/dist/loader-B2SF0yPJ.mjs.map +1 -0
- package/dist/loading-dots-DJfxDgv3.mjs +119 -0
- package/dist/loading-dots-DJfxDgv3.mjs.map +1 -0
- package/dist/loading-dots-DvR1lwC-.d.mts +11 -0
- package/dist/mini-area-chart-GIUU-ZLo.d.mts +30 -0
- package/dist/mini-area-chart-s5ItHBk8.mjs +225 -0
- package/dist/mini-area-chart-s5ItHBk8.mjs.map +1 -0
- package/dist/motion-DLlwbMJ0.d.mts +33 -0
- package/dist/motion-zelaDelJ.mjs +47 -0
- package/dist/motion-zelaDelJ.mjs.map +1 -0
- package/dist/nav-app-switcher-B1NTlYrm.d.mts +43 -0
- package/dist/nav-app-switcher-V7aJAC18.mjs +235 -0
- package/dist/nav-app-switcher-V7aJAC18.mjs.map +1 -0
- package/dist/nav-main-BscfzNoi.mjs +105 -0
- package/dist/nav-main-BscfzNoi.mjs.map +1 -0
- package/dist/nav-secondary-t-xeA0I4.mjs +51 -0
- package/dist/nav-secondary-t-xeA0I4.mjs.map +1 -0
- package/dist/nav-user-A4YHm3-O.mjs +193 -0
- package/dist/nav-user-A4YHm3-O.mjs.map +1 -0
- package/dist/node-BKXOPjw9.d.mts +100 -0
- package/dist/node-CdmDD4k-.mjs +116 -0
- package/dist/node-CdmDD4k-.mjs.map +1 -0
- package/dist/oneapp-CfwhNatF.mjs +322 -0
- package/dist/oneapp-CfwhNatF.mjs.map +1 -0
- package/dist/pagination-controls-CE3-eCxI.mjs +135 -0
- package/dist/pagination-controls-CE3-eCxI.mjs.map +1 -0
- package/dist/popover-DmWxl2lW.mjs +198 -0
- package/dist/popover-DmWxl2lW.mjs.map +1 -0
- package/dist/preview.d.mts +6 -0
- package/dist/progress-BWxdthl4.mjs +230 -0
- package/dist/progress-BWxdthl4.mjs.map +1 -0
- package/dist/prompt-input-SFJ9_lNw.mjs +1149 -0
- package/dist/prompt-input-SFJ9_lNw.mjs.map +1 -0
- package/dist/resizable--DaTse0W.mjs +124 -0
- package/dist/resizable--DaTse0W.mjs.map +1 -0
- package/dist/scroll-area-Bxi-Edjc.mjs +139 -0
- package/dist/scroll-area-Bxi-Edjc.mjs.map +1 -0
- package/dist/scroll-area-CDRGG59G.d.mts +19 -0
- package/dist/select-DI6PzHN3.mjs +411 -0
- package/dist/select-DI6PzHN3.mjs.map +1 -0
- package/dist/select-csqviwUw.d.mts +44 -0
- package/dist/separator-BG9BqZqg.d.mts +20 -0
- package/dist/separator-CNQqqwfO.d.mts +20 -0
- package/dist/separator-veJJBul5.mjs +118 -0
- package/dist/separator-veJJBul5.mjs.map +1 -0
- package/dist/shared-BqVcofZN.d.mts +91 -0
- package/dist/shared-auth.d.mts +5 -0
- package/dist/shared-auth.mjs +6 -0
- package/dist/shimmer-BLRAD4VL.mjs +102 -0
- package/dist/shimmer-BLRAD4VL.mjs.map +1 -0
- package/dist/sidebar-CPteoqnB.d.mts +163 -0
- package/dist/sidebar-CdWE7H3R.mjs +814 -0
- package/dist/sidebar-CdWE7H3R.mjs.map +1 -0
- package/dist/sidebar-DYgXCHqQ.d.mts +163 -0
- package/dist/sidebar-inset-header-portal-CIRN-lKw.mjs +153 -0
- package/dist/sidebar-inset-header-portal-CIRN-lKw.mjs.map +1 -0
- package/dist/sidebar-inset-header-portal-DjfK7xCt.d.mts +24 -0
- package/dist/sidebar-slots-DNCEnx5L.mjs +135 -0
- package/dist/sidebar-slots-DNCEnx5L.mjs.map +1 -0
- package/dist/sidebar-slots-OqNmzlIk.d.mts +47 -0
- package/dist/skeleton-ByXUFNDF.d.mts +35 -0
- package/dist/skeleton-aXwA3YID.mjs +211 -0
- package/dist/skeleton-aXwA3YID.mjs.map +1 -0
- package/dist/sources.css +16 -0
- package/dist/storybook-preview.mjs +184 -0
- package/dist/storybook-preview.mjs.map +1 -0
- package/dist/styles/colors.css +166 -0
- package/dist/styles/index.css +2 -0
- package/dist/styles/mantine.css +1024 -0
- package/dist/styles/spacing.css +62 -0
- package/dist/styles/theme.css +1687 -0
- package/dist/styles/typography.css +59 -0
- package/dist/styles/variables.css +998 -0
- package/dist/styles.css +1 -0
- package/dist/switch-BFct1r4a.mjs +223 -0
- package/dist/switch-BFct1r4a.mjs.map +1 -0
- package/dist/table-DNkLM1TB.mjs +261 -0
- package/dist/table-DNkLM1TB.mjs.map +1 -0
- package/dist/textarea-MpLFc9sB.mjs +173 -0
- package/dist/textarea-MpLFc9sB.mjs.map +1 -0
- package/dist/theme-provider-4D34sBmG.mjs +83 -0
- package/dist/theme-provider-4D34sBmG.mjs.map +1 -0
- package/dist/time-series-chart-B66xH88w.d.mts +69 -0
- package/dist/time-series-chart-DxnknDhW.mjs +400 -0
- package/dist/time-series-chart-DxnknDhW.mjs.map +1 -0
- package/dist/tokens/tokens.dtcg.json +4353 -0
- package/dist/tokens/tokens.json +895 -0
- package/dist/tokens-mantine-types.d.mts +3 -0
- package/dist/tokens-mantine-types.mjs +4 -0
- package/dist/tokens.css +2 -0
- package/dist/tokens.d.mts +9398 -0
- package/dist/tokens.mjs +9311 -0
- package/dist/tokens.mjs.map +1 -0
- package/dist/tooltip-B8_zKnHC.mjs +301 -0
- package/dist/tooltip-B8_zKnHC.mjs.map +1 -0
- package/dist/tooltip-BA27ygge.d.mts +44 -0
- package/dist/tooltip-FqB3srL-.d.mts +44 -0
- package/dist/tooltip-sync-Ax1GmpjC.d.mts +17 -0
- package/dist/tooltip-sync-DzJUgiTM.mjs +85 -0
- package/dist/tooltip-sync-DzJUgiTM.mjs.map +1 -0
- package/dist/types-B8z57DW2.d.mts +41 -0
- package/dist/use-artifact-panel-state-CUQTn2Uq.mjs +346 -0
- package/dist/use-artifact-panel-state-CUQTn2Uq.mjs.map +1 -0
- package/dist/use-artifact-panel-state-DPZC--sz.d.mts +150 -0
- package/dist/utils-BJGrUJ6T.mjs +77 -0
- package/dist/utils-BJGrUJ6T.mjs.map +1 -0
- package/dist/utils-D2bGp2p_.mjs +33 -0
- package/dist/utils-D2bGp2p_.mjs.map +1 -0
- package/dist/x-axis-BY00htJY.mjs +137 -0
- package/dist/x-axis-BY00htJY.mjs.map +1 -0
- package/dist/x-axis-Dh66iD8l.d.mts +21 -0
- package/dist/y-axis-DgHlVHRG.mjs +118 -0
- package/dist/y-axis-DgHlVHRG.mjs.map +1 -0
- package/dist/y-axis-DocBbrSp.d.mts +23 -0
- package/dist/z-index-BlBlZL-F.d.mts +10775 -0
- package/package.json +429 -0
- package/src/ai-oneapp/flow-chat/index.ts +3 -0
- package/src/ai-oneapp/flow-chat/node-suggestion-card.tsx +37 -0
- package/src/ai-oneapp/flow-chat/template-suggestion-card.tsx +49 -0
- package/src/ai-oneapp/flow-chat/workflow-action-toast.tsx +55 -0
- package/src/components/.gitkeep +0 -0
- package/src/components/ai-elements/__tests__/test-utils.tsx +12 -0
- package/src/components/ai-elements/actions/actions.stories.tsx +288 -0
- package/src/components/ai-elements/actions/actions.test.tsx +60 -0
- package/src/components/ai-elements/actions/actions.tsx +286 -0
- package/src/components/ai-elements/actions/index.ts +7 -0
- package/src/components/ai-elements/agent-step/agent-step.stories.tsx +167 -0
- package/src/components/ai-elements/agent-step/agent-step.tsx +206 -0
- package/src/components/ai-elements/agent-step/index.ts +7 -0
- package/src/components/ai-elements/ai-elements.constants.ts +516 -0
- package/src/components/ai-elements/artifact/artifact.stories.tsx +199 -0
- package/src/components/ai-elements/artifact/artifact.tsx +277 -0
- package/src/components/ai-elements/artifact/index.ts +7 -0
- package/src/components/ai-elements/branch/branch.stories.tsx +212 -0
- package/src/components/ai-elements/branch/branch.test.tsx +148 -0
- package/src/components/ai-elements/branch/branch.tsx +502 -0
- package/src/components/ai-elements/branch/index.ts +7 -0
- package/src/components/ai-elements/chain-of-thought/chain-of-thought.stories.tsx +172 -0
- package/src/components/ai-elements/chain-of-thought/chain-of-thought.tsx +505 -0
- package/src/components/ai-elements/chain-of-thought/index.ts +7 -0
- package/src/components/ai-elements/chat-input/chat-input.stories.tsx +185 -0
- package/src/components/ai-elements/chat-input/chat-input.tsx +201 -0
- package/src/components/ai-elements/chat-input/index.ts +7 -0
- package/src/components/ai-elements/checkpoint/checkpoint.stories.tsx +171 -0
- package/src/components/ai-elements/checkpoint/checkpoint.tsx +256 -0
- package/src/components/ai-elements/checkpoint/index.ts +7 -0
- package/src/components/ai-elements/code-block/code-block.stories.tsx +317 -0
- package/src/components/ai-elements/code-block/code-block.tsx +366 -0
- package/src/components/ai-elements/code-block/index.ts +7 -0
- package/src/components/ai-elements/confirmation/confirmation.stories.tsx +236 -0
- package/src/components/ai-elements/confirmation/confirmation.tsx +465 -0
- package/src/components/ai-elements/confirmation/index.ts +7 -0
- package/src/components/ai-elements/context/context.stories.tsx +80 -0
- package/src/components/ai-elements/context/context.tsx +585 -0
- package/src/components/ai-elements/context/index.ts +7 -0
- package/src/components/ai-elements/conversation/__tests__/conversation.test.tsx +402 -0
- package/src/components/ai-elements/conversation/conversation.stories.tsx +1019 -0
- package/src/components/ai-elements/conversation/conversation.tsx +260 -0
- package/src/components/ai-elements/conversation/index.ts +7 -0
- package/src/components/ai-elements/custom/__tests__/accessibility.test.tsx +27 -0
- package/src/components/ai-elements/custom/__tests__/chat-container.test.tsx +30 -0
- package/src/components/ai-elements/custom/__tests__/conversation-history.test.tsx +100 -0
- package/src/components/ai-elements/custom/__tests__/export-dropdown.test.tsx +60 -0
- package/src/components/ai-elements/custom/ai-label/ai-label.stories.tsx +86 -0
- package/src/components/ai-elements/custom/ai-label/ai-label.tsx +291 -0
- package/src/components/ai-elements/custom/ai-label/index.ts +7 -0
- package/src/components/ai-elements/custom/artifact-skeleton/artifact-skeleton.stories.tsx +155 -0
- package/src/components/ai-elements/custom/artifact-skeleton/artifact-skeleton.tsx +269 -0
- package/src/components/ai-elements/custom/artifact-skeleton/index.ts +18 -0
- package/src/components/ai-elements/custom/audio-player/audio-player.stories.tsx +50 -0
- package/src/components/ai-elements/custom/audio-player/audio-player.tsx +296 -0
- package/src/components/ai-elements/custom/audio-player/index.ts +1 -0
- package/src/components/ai-elements/custom/button-group/button-group.stories.tsx +108 -0
- package/src/components/ai-elements/custom/button-group/button-group.tsx +142 -0
- package/src/components/ai-elements/custom/button-group/index.ts +15 -0
- package/src/components/ai-elements/custom/chat-container/chat-container.stories.tsx +143 -0
- package/src/components/ai-elements/custom/chat-container/chat-container.tsx +406 -0
- package/src/components/ai-elements/custom/chat-container/index.ts +9 -0
- package/src/components/ai-elements/custom/collapsible/collapsible.stories.tsx +130 -0
- package/src/components/ai-elements/custom/collapsible/index.ts +11 -0
- package/src/components/ai-elements/custom/collapsible/use-collapsible.tsx +240 -0
- package/src/components/ai-elements/custom/collapsible-content/collapsible-content.stories.tsx +113 -0
- package/src/components/ai-elements/custom/collapsible-content/collapsible-content.tsx +141 -0
- package/src/components/ai-elements/custom/collapsible-content/index.ts +7 -0
- package/src/components/ai-elements/custom/content-placeholder/content-placeholder.stories.tsx +82 -0
- package/src/components/ai-elements/custom/content-placeholder/content-placeholder.tsx +319 -0
- package/src/components/ai-elements/custom/content-placeholder/index.ts +10 -0
- package/src/components/ai-elements/custom/conversation-header/conversation-header.stories.tsx +102 -0
- package/src/components/ai-elements/custom/conversation-header/conversation-header.tsx +202 -0
- package/src/components/ai-elements/custom/conversation-header/index.ts +12 -0
- package/src/components/ai-elements/custom/conversation-history/conversation-history.stories.tsx +191 -0
- package/src/components/ai-elements/custom/conversation-history/conversation-history.tsx +515 -0
- package/src/components/ai-elements/custom/conversation-history/index.ts +16 -0
- package/src/components/ai-elements/custom/diff-view/diff-view.stories.tsx +173 -0
- package/src/components/ai-elements/custom/diff-view/diff-view.tsx +261 -0
- package/src/components/ai-elements/custom/diff-view/index.ts +7 -0
- package/src/components/ai-elements/custom/draggable-tabs/draggable-tabs.stories.tsx +157 -0
- package/src/components/ai-elements/custom/draggable-tabs/draggable-tabs.tsx +311 -0
- package/src/components/ai-elements/custom/draggable-tabs/index.ts +7 -0
- package/src/components/ai-elements/custom/export-conversation/export-conversation.stories.tsx +73 -0
- package/src/components/ai-elements/custom/export-conversation/export-conversation.tsx +405 -0
- package/src/components/ai-elements/custom/export-conversation/index.ts +10 -0
- package/src/components/ai-elements/custom/export-dropdown/export-dropdown.stories.tsx +121 -0
- package/src/components/ai-elements/custom/export-dropdown/export-dropdown.tsx +315 -0
- package/src/components/ai-elements/custom/export-dropdown/index.ts +11 -0
- package/src/components/ai-elements/custom/feedback/feedback.stories.tsx +85 -0
- package/src/components/ai-elements/custom/feedback/feedback.tsx +425 -0
- package/src/components/ai-elements/custom/feedback/index.ts +13 -0
- package/src/components/ai-elements/custom/file-card/file-card.stories.tsx +65 -0
- package/src/components/ai-elements/custom/file-card/file-card.tsx +249 -0
- package/src/components/ai-elements/custom/file-card/index.ts +1 -0
- package/src/components/ai-elements/custom/file-tree/file-tree.stories.tsx +96 -0
- package/src/components/ai-elements/custom/file-tree/file-tree.tsx +266 -0
- package/src/components/ai-elements/custom/file-tree/index.ts +7 -0
- package/src/components/ai-elements/custom/index.ts +73 -0
- package/src/components/ai-elements/custom/keyboard-shortcut/index.ts +14 -0
- package/src/components/ai-elements/custom/keyboard-shortcut/keyboard-shortcut.stories.tsx +118 -0
- package/src/components/ai-elements/custom/keyboard-shortcut/keyboard-shortcut.tsx +292 -0
- package/src/components/ai-elements/custom/message-edit/index.ts +1 -0
- package/src/components/ai-elements/custom/message-edit/message-edit.stories.tsx +88 -0
- package/src/components/ai-elements/custom/message-edit/message-edit.tsx +225 -0
- package/src/components/ai-elements/custom/message-error/index.ts +7 -0
- package/src/components/ai-elements/custom/message-error/message-error.stories.tsx +85 -0
- package/src/components/ai-elements/custom/message-error/message-error.tsx +301 -0
- package/src/components/ai-elements/custom/message-group/index.ts +1 -0
- package/src/components/ai-elements/custom/message-group/message-group.stories.tsx +82 -0
- package/src/components/ai-elements/custom/message-group/message-group.tsx +77 -0
- package/src/components/ai-elements/custom/message-separator/index.ts +1 -0
- package/src/components/ai-elements/custom/message-separator/message-separator.stories.tsx +65 -0
- package/src/components/ai-elements/custom/message-separator/message-separator.tsx +132 -0
- package/src/components/ai-elements/custom/scroll-to-bottom/index.ts +11 -0
- package/src/components/ai-elements/custom/scroll-to-bottom/scroll-to-bottom.stories.tsx +116 -0
- package/src/components/ai-elements/custom/scroll-to-bottom/use-scroll-to-bottom.tsx +215 -0
- package/src/components/ai-elements/custom/snippet/index.ts +1 -0
- package/src/components/ai-elements/custom/snippet/snippet.stories.tsx +59 -0
- package/src/components/ai-elements/custom/snippet/snippet.tsx +158 -0
- package/src/components/ai-elements/custom/stack-trace/index.ts +1 -0
- package/src/components/ai-elements/custom/stack-trace/stack-trace.stories.tsx +112 -0
- package/src/components/ai-elements/custom/stack-trace/stack-trace.tsx +368 -0
- package/src/components/ai-elements/custom/terminal/index.ts +9 -0
- package/src/components/ai-elements/custom/terminal/terminal.stories.tsx +92 -0
- package/src/components/ai-elements/custom/terminal/terminal.tsx +233 -0
- package/src/components/ai-elements/custom/test-results/test-results.tsx +438 -0
- package/src/components/ai-elements/custom/thought-chain/index.ts +7 -0
- package/src/components/ai-elements/custom/thought-chain/thought-chain.stories.tsx +123 -0
- package/src/components/ai-elements/custom/thought-chain/thought-chain.tsx +246 -0
- package/src/components/ai-elements/custom/token-usage/index.ts +6 -0
- package/src/components/ai-elements/custom/token-usage/token-usage.stories.tsx +104 -0
- package/src/components/ai-elements/custom/token-usage/token-usage.tsx +236 -0
- package/src/components/ai-elements/custom/transcription/index.ts +1 -0
- package/src/components/ai-elements/custom/transcription/transcription.stories.tsx +80 -0
- package/src/components/ai-elements/custom/transcription/transcription.tsx +163 -0
- package/src/components/ai-elements/custom/typing-indicator/index.ts +1 -0
- package/src/components/ai-elements/custom/typing-indicator/typing-indicator.stories.tsx +71 -0
- package/src/components/ai-elements/custom/typing-indicator/typing-indicator.tsx +126 -0
- package/src/components/ai-elements/custom/undo-redo/index.ts +12 -0
- package/src/components/ai-elements/custom/undo-redo/undo-redo.stories.tsx +145 -0
- package/src/components/ai-elements/custom/undo-redo/use-undo-redo.tsx +324 -0
- package/src/components/ai-elements/custom/voice-selector/index.ts +7 -0
- package/src/components/ai-elements/custom/voice-selector/voice-selector.stories.tsx +67 -0
- package/src/components/ai-elements/custom/voice-selector/voice-selector.tsx +301 -0
- package/src/components/ai-elements/custom/welcome/index.ts +1 -0
- package/src/components/ai-elements/custom/welcome/welcome.stories.tsx +92 -0
- package/src/components/ai-elements/custom/welcome/welcome.tsx +213 -0
- package/src/components/ai-elements/generative-ui/generative-ui-renderer.stories.tsx +451 -0
- package/src/components/ai-elements/generative-ui/generative-ui-renderer.test.tsx +383 -0
- package/src/components/ai-elements/generative-ui/generative-ui-renderer.tsx +668 -0
- package/src/components/ai-elements/generative-ui/index.ts +21 -0
- package/src/components/ai-elements/image/image.stories.tsx +179 -0
- package/src/components/ai-elements/image/image.tsx +178 -0
- package/src/components/ai-elements/image/index.ts +7 -0
- package/src/components/ai-elements/index.ts +195 -0
- package/src/components/ai-elements/inline-citation/index.ts +7 -0
- package/src/components/ai-elements/inline-citation/inline-citation.stories.tsx +331 -0
- package/src/components/ai-elements/inline-citation/inline-citation.tsx +595 -0
- package/src/components/ai-elements/loader/index.ts +7 -0
- package/src/components/ai-elements/loader/loader.stories.tsx +185 -0
- package/src/components/ai-elements/loader/loader.tsx +177 -0
- package/src/components/ai-elements/message/__tests__/message.test.tsx +352 -0
- package/src/components/ai-elements/message/index.ts +7 -0
- package/src/components/ai-elements/message/message-actions.test.tsx +51 -0
- package/src/components/ai-elements/message/message.stories.tsx +609 -0
- package/src/components/ai-elements/message/message.test.tsx +52 -0
- package/src/components/ai-elements/message/message.tsx +1125 -0
- package/src/components/ai-elements/message/response.test.tsx +18 -0
- package/src/components/ai-elements/model-selector/index.ts +7 -0
- package/src/components/ai-elements/model-selector/model-selector.stories.tsx +198 -0
- package/src/components/ai-elements/model-selector/model-selector.tsx +406 -0
- package/src/components/ai-elements/modernization_walkthrough.md +51 -0
- package/src/components/ai-elements/open-in-chat/index.ts +7 -0
- package/src/components/ai-elements/open-in-chat/open-in-chat.stories.tsx +221 -0
- package/src/components/ai-elements/open-in-chat/open-in-chat.tsx +606 -0
- package/src/components/ai-elements/plan/index.ts +7 -0
- package/src/components/ai-elements/plan/plan.stories.tsx +233 -0
- package/src/components/ai-elements/plan/plan.tsx +337 -0
- package/src/components/ai-elements/prompt-char-counter/index.ts +7 -0
- package/src/components/ai-elements/prompt-char-counter/prompt-char-counter.stories.tsx +98 -0
- package/src/components/ai-elements/prompt-char-counter/prompt-char-counter.tsx +159 -0
- package/src/components/ai-elements/prompt-input/index.ts +7 -0
- package/src/components/ai-elements/prompt-input/prompt-input.stories.tsx +548 -0
- package/src/components/ai-elements/prompt-input/prompt-input.test.tsx +22 -0
- package/src/components/ai-elements/prompt-input/prompt-input.tsx +2112 -0
- package/src/components/ai-elements/queue/index.ts +7 -0
- package/src/components/ai-elements/queue/queue.stories.tsx +249 -0
- package/src/components/ai-elements/queue/queue.tsx +456 -0
- package/src/components/ai-elements/reasoning/index.ts +7 -0
- package/src/components/ai-elements/reasoning/reasoning.stories.tsx +147 -0
- package/src/components/ai-elements/reasoning/reasoning.tsx +356 -0
- package/src/components/ai-elements/shimmer/index.ts +7 -0
- package/src/components/ai-elements/shimmer/shimmer.stories.tsx +240 -0
- package/src/components/ai-elements/shimmer/shimmer.tsx +150 -0
- package/src/components/ai-elements/sources/index.ts +7 -0
- package/src/components/ai-elements/sources/sources.stories.tsx +259 -0
- package/src/components/ai-elements/sources/sources.test.tsx +40 -0
- package/src/components/ai-elements/sources/sources.tsx +327 -0
- package/src/components/ai-elements/suggestion/index.ts +7 -0
- package/src/components/ai-elements/suggestion/suggestion.stories.tsx +207 -0
- package/src/components/ai-elements/suggestion/suggestion.tsx +229 -0
- package/src/components/ai-elements/task/index.ts +7 -0
- package/src/components/ai-elements/task/task.stories.tsx +213 -0
- package/src/components/ai-elements/task/task.tsx +356 -0
- package/src/components/ai-elements/test-utils.tsx +28 -0
- package/src/components/ai-elements/tool/index.ts +7 -0
- package/src/components/ai-elements/tool/tool.stories.tsx +195 -0
- package/src/components/ai-elements/tool/tool.test.tsx +160 -0
- package/src/components/ai-elements/tool/tool.tsx +537 -0
- package/src/components/ai-elements/tool-approval/index.ts +7 -0
- package/src/components/ai-elements/tool-approval/tool-approval.stories.tsx +260 -0
- package/src/components/ai-elements/tool-approval/tool-approval.tsx +423 -0
- package/src/components/ai-elements/vitest.config.ts +17 -0
- package/src/components/ai-elements/vitest.setup.ts +6 -0
- package/src/components/ai-elements/web-preview/index.ts +7 -0
- package/src/components/ai-elements/web-preview/web-preview.stories.tsx +202 -0
- package/src/components/ai-elements/web-preview/web-preview.tsx +1166 -0
- package/src/components/ai-workflows/canvas/canvas.stories.tsx +120 -0
- package/src/components/ai-workflows/canvas/canvas.tsx +173 -0
- package/src/components/ai-workflows/canvas/index.ts +7 -0
- package/src/components/ai-workflows/connection/connection.stories.tsx +66 -0
- package/src/components/ai-workflows/connection/connection.tsx +119 -0
- package/src/components/ai-workflows/connection/index.ts +7 -0
- package/src/components/ai-workflows/controls/controls.stories.tsx +72 -0
- package/src/components/ai-workflows/controls/controls.tsx +132 -0
- package/src/components/ai-workflows/controls/index.ts +7 -0
- package/src/components/ai-workflows/edge/edge.stories.tsx +120 -0
- package/src/components/ai-workflows/edge/edge.test.tsx +47 -0
- package/src/components/ai-workflows/edge/edge.tsx +136 -0
- package/src/components/ai-workflows/edge/index.ts +7 -0
- package/src/components/ai-workflows/flow-constants.ts +11 -0
- package/src/components/ai-workflows/node/index.ts +7 -0
- package/src/components/ai-workflows/node/node.stories.tsx +111 -0
- package/src/components/ai-workflows/node/node.tsx +227 -0
- package/src/components/ai-workflows/panel/index.ts +7 -0
- package/src/components/ai-workflows/panel/panel.stories.tsx +102 -0
- package/src/components/ai-workflows/panel/panel.tsx +106 -0
- package/src/components/ai-workflows/resizable-node/index.ts +7 -0
- package/src/components/ai-workflows/resizable-node/resizable-node.stories.tsx +93 -0
- package/src/components/ai-workflows/resizable-node/resizable-node.tsx +228 -0
- package/src/components/ai-workflows/toolbar/index.ts +7 -0
- package/src/components/ai-workflows/toolbar/toolbar.stories.tsx +99 -0
- package/src/components/ai-workflows/toolbar/toolbar.tsx +130 -0
- package/src/components/auth/client/index.ts +12 -0
- package/src/components/auth/client/nav-user/auth-nav-user.tsx +237 -0
- package/src/components/auth/client/nav-user/index.ts +11 -0
- package/src/components/auth/client/providers/ThemeProvider.stories.tsx +59 -0
- package/src/components/auth/client/providers/ThemeProvider.tsx +39 -0
- package/src/components/auth/client/providers/index.ts +7 -0
- package/src/components/auth/client/providers.tsx +129 -0
- package/src/components/auth/index.ts +14 -0
- package/src/components/auth/server/account/ProfileForm.stories.tsx +105 -0
- package/src/components/auth/server/account/ProfileForm.tsx +236 -0
- package/src/components/auth/server/account/index.ts +7 -0
- package/src/components/auth/server/actions/index.ts +11 -0
- package/src/components/auth/server/actions.ts +88 -0
- package/src/components/auth/server/admin/AdminBulkUserActions.stories.tsx +129 -0
- package/src/components/auth/server/admin/AdminBulkUserActions.tsx +649 -0
- package/src/components/auth/server/admin/AdminDashboard.stories.tsx +215 -0
- package/src/components/auth/server/admin/AdminDashboard.tsx +785 -0
- package/src/components/auth/server/admin/AdminDevicesManager.tsx +411 -0
- package/src/components/auth/server/admin/AdminImpersonation.stories.tsx +121 -0
- package/src/components/auth/server/admin/AdminImpersonation.tsx +569 -0
- package/src/components/auth/server/admin/AdminPasskeysManager.tsx +393 -0
- package/src/components/auth/server/admin/AdminSecurityEventsViewer.tsx +395 -0
- package/src/components/auth/server/admin/AdminServiceAccountsManager.tsx +454 -0
- package/src/components/auth/server/admin/AdminSessionsManager.tsx +664 -0
- package/src/components/auth/server/admin/AdminTwoFactorManager.tsx +431 -0
- package/src/components/auth/server/admin/AdminUserCreation.stories.tsx +87 -0
- package/src/components/auth/server/admin/AdminUserCreation.tsx +777 -0
- package/src/components/auth/server/admin/AdminUserDetail.stories.tsx +178 -0
- package/src/components/auth/server/admin/AdminUserDetail.tsx +1044 -0
- package/src/components/auth/server/admin/AdminUsersList.stories.tsx +228 -0
- package/src/components/auth/server/admin/AdminUsersList.tsx +859 -0
- package/src/components/auth/server/admin/index.ts +59 -0
- package/src/components/auth/server/advanced/PasskeySetup.stories.tsx +70 -0
- package/src/components/auth/server/advanced/PasskeySetup.tsx +383 -0
- package/src/components/auth/server/advanced/TwoFactorSetup.stories.tsx +79 -0
- package/src/components/auth/server/advanced/TwoFactorSetup.tsx +459 -0
- package/src/components/auth/server/advanced/TwoFactorVerify.stories.tsx +69 -0
- package/src/components/auth/server/advanced/TwoFactorVerify.tsx +323 -0
- package/src/components/auth/server/advanced/index.ts +10 -0
- package/src/components/auth/server/api-keys/APIKeysList.stories.tsx +95 -0
- package/src/components/auth/server/api-keys/APIKeysList.tsx +470 -0
- package/src/components/auth/server/api-keys/CreateAPIKeyForm.stories.tsx +79 -0
- package/src/components/auth/server/api-keys/CreateAPIKeyForm.tsx +501 -0
- package/src/components/auth/server/api-keys/index.ts +9 -0
- package/src/components/auth/server/enhanced/AccountDeletionFlow.stories.tsx +115 -0
- package/src/components/auth/server/enhanced/AccountDeletionFlow.tsx +733 -0
- package/src/components/auth/server/enhanced/AnonymousSessionCreator.stories.tsx +80 -0
- package/src/components/auth/server/enhanced/AnonymousSessionCreator.tsx +398 -0
- package/src/components/auth/server/enhanced/AnonymousToAccountConverter.stories.tsx +61 -0
- package/src/components/auth/server/enhanced/AnonymousToAccountConverter.tsx +538 -0
- package/src/components/auth/server/enhanced/BackupCodesManager.stories.tsx +108 -0
- package/src/components/auth/server/enhanced/BackupCodesManager.tsx +718 -0
- package/src/components/auth/server/enhanced/BearerTokenGenerator.stories.tsx +85 -0
- package/src/components/auth/server/enhanced/BearerTokenGenerator.tsx +618 -0
- package/src/components/auth/server/enhanced/ChangePasswordForm.stories.tsx +108 -0
- package/src/components/auth/server/enhanced/ChangePasswordForm.tsx +313 -0
- package/src/components/auth/server/enhanced/DataExportRequest.stories.tsx +84 -0
- package/src/components/auth/server/enhanced/DataExportRequest.tsx +734 -0
- package/src/components/auth/server/enhanced/DeviceManagement.stories.tsx +161 -0
- package/src/components/auth/server/enhanced/DeviceManagement.tsx +700 -0
- package/src/components/auth/server/enhanced/EmailChangeVerification.stories.tsx +94 -0
- package/src/components/auth/server/enhanced/EmailChangeVerification.tsx +421 -0
- package/src/components/auth/server/enhanced/EmailOTPSignIn.stories.tsx +68 -0
- package/src/components/auth/server/enhanced/EmailOTPSignIn.tsx +516 -0
- package/src/components/auth/server/enhanced/EmailOTPVerification.stories.tsx +95 -0
- package/src/components/auth/server/enhanced/EmailOTPVerification.tsx +610 -0
- package/src/components/auth/server/enhanced/EmailVerificationRequest.stories.tsx +97 -0
- package/src/components/auth/server/enhanced/EmailVerificationRequest.tsx +461 -0
- package/src/components/auth/server/enhanced/EmailVerificationStatus.stories.tsx +96 -0
- package/src/components/auth/server/enhanced/EmailVerificationStatus.tsx +631 -0
- package/src/components/auth/server/enhanced/MagicLinkRequestForm.stories.tsx +88 -0
- package/src/components/auth/server/enhanced/MagicLinkRequestForm.tsx +439 -0
- package/src/components/auth/server/enhanced/MagicLinkStatusIndicator.stories.tsx +101 -0
- package/src/components/auth/server/enhanced/MagicLinkStatusIndicator.tsx +610 -0
- package/src/components/auth/server/enhanced/MultiSessionDashboard.stories.tsx +101 -0
- package/src/components/auth/server/enhanced/MultiSessionDashboard.tsx +996 -0
- package/src/components/auth/server/enhanced/OrganizationAuditLog.stories.tsx +86 -0
- package/src/components/auth/server/enhanced/OrganizationAuditLog.tsx +1006 -0
- package/src/components/auth/server/enhanced/PasskeyManagement.stories.tsx +102 -0
- package/src/components/auth/server/enhanced/PasskeyManagement.tsx +705 -0
- package/src/components/auth/server/enhanced/PasskeyRegistrationWizard.stories.tsx +83 -0
- package/src/components/auth/server/enhanced/PasskeyRegistrationWizard.tsx +566 -0
- package/src/components/auth/server/enhanced/PasskeySignInInterface.stories.tsx +90 -0
- package/src/components/auth/server/enhanced/PasskeySignInInterface.tsx +792 -0
- package/src/components/auth/server/enhanced/PasswordStrengthIndicator.stories.tsx +129 -0
- package/src/components/auth/server/enhanced/PasswordStrengthIndicator.tsx +539 -0
- package/src/components/auth/server/enhanced/PhoneNumberManagement.stories.tsx +103 -0
- package/src/components/auth/server/enhanced/PhoneNumberManagement.tsx +594 -0
- package/src/components/auth/server/enhanced/PhoneNumberSetupForm.stories.tsx +91 -0
- package/src/components/auth/server/enhanced/PhoneNumberSetupForm.tsx +518 -0
- package/src/components/auth/server/enhanced/PhoneSignInForm.stories.tsx +63 -0
- package/src/components/auth/server/enhanced/PhoneSignInForm.tsx +801 -0
- package/src/components/auth/server/enhanced/PhoneSignInWithSMS.stories.tsx +87 -0
- package/src/components/auth/server/enhanced/PhoneSignInWithSMS.tsx +886 -0
- package/src/components/auth/server/enhanced/PhoneVerificationForm.stories.tsx +81 -0
- package/src/components/auth/server/enhanced/PhoneVerificationForm.tsx +306 -0
- package/src/components/auth/server/enhanced/ResendVerificationEmail.stories.tsx +84 -0
- package/src/components/auth/server/enhanced/ResendVerificationEmail.tsx +407 -0
- package/src/components/auth/server/enhanced/SMSVerificationForm.stories.tsx +92 -0
- package/src/components/auth/server/enhanced/SMSVerificationForm.tsx +521 -0
- package/src/components/auth/server/enhanced/SecurityEventLog.stories.tsx +115 -0
- package/src/components/auth/server/enhanced/SecurityEventLog.tsx +916 -0
- package/src/components/auth/server/enhanced/TeamCreationWizard.stories.tsx +85 -0
- package/src/components/auth/server/enhanced/TeamCreationWizard.tsx +1023 -0
- package/src/components/auth/server/enhanced/__tests__/actions.test.ts +388 -0
- package/src/components/auth/server/enhanced/__tests__/more-actions.test.ts +139 -0
- package/src/components/auth/server/enhanced/actions.ts +1199 -0
- package/src/components/auth/server/enhanced/auth-enhanced-actions.ts +936 -0
- package/src/components/auth/server/enhanced/index.ts +37 -0
- package/src/components/auth/server/forms/ForgotPasswordForm.stories.tsx +82 -0
- package/src/components/auth/server/forms/ForgotPasswordForm.tsx +287 -0
- package/src/components/auth/server/forms/ResetPasswordForm.stories.tsx +79 -0
- package/src/components/auth/server/forms/ResetPasswordForm.tsx +217 -0
- package/src/components/auth/server/forms/SignInForm.stories.tsx +113 -0
- package/src/components/auth/server/forms/SignInForm.tsx +211 -0
- package/src/components/auth/server/forms/SignUpForm.stories.tsx +130 -0
- package/src/components/auth/server/forms/SignUpForm.tsx +243 -0
- package/src/components/auth/server/forms/index.ts +10 -0
- package/src/components/auth/server/index.ts +22 -0
- package/src/components/auth/server/jwt/JWTTokenManager.tsx +315 -0
- package/src/components/auth/server/jwt/index.ts +7 -0
- package/src/components/auth/server/organization/AuditLogViewer.tsx +288 -0
- package/src/components/auth/server/organization/CreateRoleDialog.tsx +540 -0
- package/src/components/auth/server/organization/EditRoleDialog.tsx +487 -0
- package/src/components/auth/server/organization/InviteMembers.stories.tsx +82 -0
- package/src/components/auth/server/organization/InviteMembers.tsx +264 -0
- package/src/components/auth/server/organization/MembersList.stories.tsx +117 -0
- package/src/components/auth/server/organization/MembersList.tsx +425 -0
- package/src/components/auth/server/organization/OrganizationCreation.stories.tsx +99 -0
- package/src/components/auth/server/organization/OrganizationCreation.tsx +293 -0
- package/src/components/auth/server/organization/OrganizationSettings.stories.tsx +99 -0
- package/src/components/auth/server/organization/OrganizationSettings.tsx +494 -0
- package/src/components/auth/server/organization/OrganizationSwitcher.stories.tsx +98 -0
- package/src/components/auth/server/organization/OrganizationSwitcher.tsx +308 -0
- package/src/components/auth/server/organization/PermissionMatrix.tsx +366 -0
- package/src/components/auth/server/organization/RoleManagement.stories.tsx +120 -0
- package/src/components/auth/server/organization/RoleManagement.tsx +318 -0
- package/src/components/auth/server/organization/index.ts +16 -0
- package/src/components/auth/server/session/SessionsList.stories.tsx +81 -0
- package/src/components/auth/server/session/SessionsList.tsx +274 -0
- package/src/components/auth/server/session/index.ts +7 -0
- package/src/components/auth/server/social/SocialLoginButtons.stories.tsx +139 -0
- package/src/components/auth/server/social/SocialLoginButtons.tsx +292 -0
- package/src/components/auth/server/social/index.ts +7 -0
- package/src/components/auth/server/ui/Alert.stories.tsx +97 -0
- package/src/components/auth/server/ui/Alert.tsx +159 -0
- package/src/components/auth/server/ui/Button.stories.tsx +149 -0
- package/src/components/auth/server/ui/Button.tsx +221 -0
- package/src/components/auth/server/ui/Card.stories.tsx +80 -0
- package/src/components/auth/server/ui/Card.tsx +51 -0
- package/src/components/auth/server/ui/Input.stories.tsx +143 -0
- package/src/components/auth/server/ui/Input.tsx +195 -0
- package/src/components/auth/server/ui/index.ts +18 -0
- package/src/components/charts/areas/areas.stories.tsx +113 -0
- package/src/components/charts/areas/areas.tsx +185 -0
- package/src/components/charts/areas/index.ts +11 -0
- package/src/components/charts/bars/bars.stories.tsx +109 -0
- package/src/components/charts/bars/bars.tsx +164 -0
- package/src/components/charts/bars/index.ts +11 -0
- package/src/components/charts/chart-context.ts +35 -0
- package/src/components/charts/funnel-chart/funnel-chart.stories.tsx +111 -0
- package/src/components/charts/funnel-chart/funnel-chart.tsx +392 -0
- package/src/components/charts/funnel-chart/index.ts +11 -0
- package/src/components/charts/index.ts +45 -0
- package/src/components/charts/mini-area-chart/index.ts +11 -0
- package/src/components/charts/mini-area-chart/mini-area-chart.stories.tsx +100 -0
- package/src/components/charts/mini-area-chart/mini-area-chart.tsx +244 -0
- package/src/components/charts/time-series-chart/index.ts +11 -0
- package/src/components/charts/time-series-chart/time-series-chart.stories.tsx +140 -0
- package/src/components/charts/time-series-chart/time-series-chart.tsx +337 -0
- package/src/components/charts/tooltip-sync/index.ts +11 -0
- package/src/components/charts/tooltip-sync/tooltip-sync.stories.tsx +89 -0
- package/src/components/charts/tooltip-sync/tooltip-sync.tsx +91 -0
- package/src/components/charts/types.ts +93 -0
- package/src/components/charts/use-tooltip.ts +230 -0
- package/src/components/charts/utils.ts +69 -0
- package/src/components/charts/x-axis/index.ts +11 -0
- package/src/components/charts/x-axis/x-axis.stories.tsx +94 -0
- package/src/components/charts/x-axis/x-axis.tsx +176 -0
- package/src/components/charts/y-axis/index.ts +7 -0
- package/src/components/charts/y-axis/y-axis.stories.tsx +110 -0
- package/src/components/charts/y-axis/y-axis.tsx +139 -0
- package/src/components/elements/atoms/alert/alert.stories.tsx +234 -0
- package/src/components/elements/atoms/alert/alert.tsx +293 -0
- package/src/components/elements/atoms/alert/index.ts +7 -0
- package/src/components/elements/atoms/avatar/avatar.stories.tsx +174 -0
- package/src/components/elements/atoms/avatar/avatar.tsx +274 -0
- package/src/components/elements/atoms/avatar/index.ts +7 -0
- package/src/components/elements/atoms/badge/badge.stories.tsx +186 -0
- package/src/components/elements/atoms/badge/badge.tsx +333 -0
- package/src/components/elements/atoms/badge/index.ts +7 -0
- package/src/components/elements/atoms/blur-image/blur-image.stories.tsx +140 -0
- package/src/components/elements/atoms/blur-image/blur-image.tsx +102 -0
- package/src/components/elements/atoms/blur-image/index.ts +7 -0
- package/src/components/elements/atoms/button/button.stories.tsx +776 -0
- package/src/components/elements/atoms/button/button.tsx +878 -0
- package/src/components/elements/atoms/button/index.ts +7 -0
- package/src/components/elements/atoms/copy-button/copy-button.stories.tsx +162 -0
- package/src/components/elements/atoms/copy-button/copy-button.tsx +232 -0
- package/src/components/elements/atoms/copy-button/index.ts +7 -0
- package/src/components/elements/atoms/copy-text/copy-text.stories.tsx +128 -0
- package/src/components/elements/atoms/copy-text/copy-text.tsx +201 -0
- package/src/components/elements/atoms/copy-text/index.ts +7 -0
- package/src/components/elements/atoms/empty-state/empty-state.stories.tsx +410 -0
- package/src/components/elements/atoms/empty-state/empty-state.tsx +338 -0
- package/src/components/elements/atoms/empty-state/index.ts +1 -0
- package/src/components/elements/atoms/go-back-button/go-back-button.stories.tsx +83 -0
- package/src/components/elements/atoms/go-back-button/go-back-button.tsx +104 -0
- package/src/components/elements/atoms/go-back-button/index.ts +7 -0
- package/src/components/elements/atoms/inline-snippet/index.ts +7 -0
- package/src/components/elements/atoms/inline-snippet/inline-snippet.stories.tsx +130 -0
- package/src/components/elements/atoms/inline-snippet/inline-snippet.tsx +140 -0
- package/src/components/elements/atoms/loading-dots/index.ts +1 -0
- package/src/components/elements/atoms/loading-dots/loading-dots.stories.tsx +274 -0
- package/src/components/elements/atoms/loading-dots/loading-dots.tsx +138 -0
- package/src/components/elements/atoms/mode-toggle/index.ts +7 -0
- package/src/components/elements/atoms/mode-toggle/mode-toggle.stories.tsx +67 -0
- package/src/components/elements/atoms/mode-toggle/mode-toggle.tsx +163 -0
- package/src/components/elements/atoms/progress/index.ts +7 -0
- package/src/components/elements/atoms/progress/progress.stories.tsx +141 -0
- package/src/components/elements/atoms/progress/progress.tsx +314 -0
- package/src/components/elements/atoms/progress-circle/index.ts +7 -0
- package/src/components/elements/atoms/progress-circle/progress-circle.stories.tsx +185 -0
- package/src/components/elements/atoms/progress-circle/progress-circle.tsx +207 -0
- package/src/components/elements/atoms/separator/index.ts +7 -0
- package/src/components/elements/atoms/separator/separator.stories.tsx +154 -0
- package/src/components/elements/atoms/separator/separator.tsx +169 -0
- package/src/components/elements/atoms/skeleton/index.ts +7 -0
- package/src/components/elements/atoms/skeleton/skeleton.stories.tsx +152 -0
- package/src/components/elements/atoms/skeleton/skeleton.tsx +336 -0
- package/src/components/elements/atoms/slider/index.ts +7 -0
- package/src/components/elements/atoms/slider/slider.stories.tsx +199 -0
- package/src/components/elements/atoms/slider/slider.tsx +487 -0
- package/src/components/elements/atoms/sonner/index.ts +7 -0
- package/src/components/elements/atoms/sonner/sonner.stories.tsx +408 -0
- package/src/components/elements/atoms/sonner/sonner.tsx +131 -0
- package/src/components/elements/atoms/status-badge/index.ts +7 -0
- package/src/components/elements/atoms/status-badge/status-badge.stories.tsx +166 -0
- package/src/components/elements/atoms/status-badge/status-badge.tsx +262 -0
- package/src/components/elements/atoms/timestamp-tooltip/index.ts +7 -0
- package/src/components/elements/atoms/timestamp-tooltip/timestamp-tooltip.stories.tsx +127 -0
- package/src/components/elements/atoms/timestamp-tooltip/timestamp-tooltip.tsx +404 -0
- package/src/components/elements/molecules/animated-size-container/animated-size-container.stories.tsx +165 -0
- package/src/components/elements/molecules/animated-size-container/animated-size-container.tsx +125 -0
- package/src/components/elements/molecules/animated-size-container/index.ts +7 -0
- package/src/components/elements/molecules/avatar-stack/avatar-stack.stories.tsx +179 -0
- package/src/components/elements/molecules/avatar-stack/avatar-stack.tsx +258 -0
- package/src/components/elements/molecules/avatar-stack/index.ts +7 -0
- package/src/components/elements/molecules/breadcrumb/breadcrumb.stories.tsx +273 -0
- package/src/components/elements/molecules/breadcrumb/breadcrumb.tsx +299 -0
- package/src/components/elements/molecules/breadcrumb/index.ts +7 -0
- package/src/components/elements/molecules/button-group/button-group.stories.tsx +267 -0
- package/src/components/elements/molecules/button-group/button-group.tsx +244 -0
- package/src/components/elements/molecules/button-group/index.ts +7 -0
- package/src/components/elements/molecules/collapsible/collapsible.stories.tsx +186 -0
- package/src/components/elements/molecules/collapsible/collapsible.tsx +362 -0
- package/src/components/elements/molecules/collapsible/index.ts +7 -0
- package/src/components/elements/molecules/empty/empty.stories.tsx +182 -0
- package/src/components/elements/molecules/empty/empty.tsx +230 -0
- package/src/components/elements/molecules/empty/index.ts +7 -0
- package/src/components/elements/molecules/pagination-controls/index.ts +8 -0
- package/src/components/elements/molecules/pagination-controls/pagination-controls.stories.tsx +193 -0
- package/src/components/elements/molecules/pagination-controls/pagination-controls.tsx +174 -0
- package/src/components/elements/molecules/tab-select/index.ts +7 -0
- package/src/components/elements/molecules/tab-select/tab-select.stories.tsx +175 -0
- package/src/components/elements/molecules/tab-select/tab-select.tsx +261 -0
- package/src/components/elements/molecules/tabs/index.ts +7 -0
- package/src/components/elements/molecules/tabs/tabs.stories.tsx +198 -0
- package/src/components/elements/molecules/tabs/tabs.tsx +744 -0
- package/src/components/elements/molecules/toggle-group/index.ts +7 -0
- package/src/components/elements/molecules/toggle-group/toggle-group.stories.tsx +201 -0
- package/src/components/elements/molecules/toggle-group/toggle-group.tsx +236 -0
- package/src/components/elements/organisms/accordion/accordion.stories.tsx +217 -0
- package/src/components/elements/organisms/accordion/accordion.tsx +456 -0
- package/src/components/elements/organisms/accordion/index.ts +7 -0
- package/src/components/elements/organisms/card/card.stories.tsx +406 -0
- package/src/components/elements/organisms/card/card.tsx +437 -0
- package/src/components/elements/organisms/card/index.ts +8 -0
- package/src/components/elements/organisms/card/integration-card.stories.tsx +348 -0
- package/src/components/elements/organisms/card/integration-compact.stories.tsx +310 -0
- package/src/components/elements/organisms/card/integrations.tsx +356 -0
- package/src/components/elements/organisms/carousel/carousel.stories.tsx +182 -0
- package/src/components/elements/organisms/carousel/carousel.tsx +537 -0
- package/src/components/elements/organisms/carousel/index.ts +7 -0
- package/src/components/elements/organisms/chart/chart.stories.tsx +147 -0
- package/src/components/elements/organisms/chart/chart.tsx +317 -0
- package/src/components/elements/organisms/chart/index.ts +7 -0
- package/src/components/elements/organisms/command/command.stories.tsx +246 -0
- package/src/components/elements/organisms/command/command.tsx +284 -0
- package/src/components/elements/organisms/command/index.ts +7 -0
- package/src/components/elements/organisms/dialog/dialog.stories.tsx +266 -0
- package/src/components/elements/organisms/dialog/dialog.tsx +366 -0
- package/src/components/elements/organisms/dialog/index.ts +7 -0
- package/src/components/elements/organisms/dropdown-menu/dropdown-menu.stories.tsx +334 -0
- package/src/components/elements/organisms/dropdown-menu/dropdown-menu.tsx +611 -0
- package/src/components/elements/organisms/dropdown-menu/index.ts +7 -0
- package/src/components/elements/organisms/dynamic-breadcrumb/dynamic-breadcrumb.stories.tsx +50 -0
- package/src/components/elements/organisms/dynamic-breadcrumb/dynamic-breadcrumb.tsx +257 -0
- package/src/components/elements/organisms/dynamic-breadcrumb/index.ts +7 -0
- package/src/components/elements/organisms/error-boundary/error-boundary.stories.tsx +142 -0
- package/src/components/elements/organisms/error-boundary/error-boundary.tsx +408 -0
- package/src/components/elements/organisms/error-boundary/index.ts +7 -0
- package/src/components/elements/organisms/hover-card/hover-card.stories.tsx +245 -0
- package/src/components/elements/organisms/hover-card/hover-card.tsx +370 -0
- package/src/components/elements/organisms/hover-card/index.ts +7 -0
- package/src/components/elements/organisms/modal/index.ts +7 -0
- package/src/components/elements/organisms/modal/modal.stories.tsx +189 -0
- package/src/components/elements/organisms/modal/modal.tsx +266 -0
- package/src/components/elements/organisms/popover/index.ts +7 -0
- package/src/components/elements/organisms/popover/popover.stories.tsx +200 -0
- package/src/components/elements/organisms/popover/popover.tsx +302 -0
- package/src/components/elements/organisms/resizable/index.ts +7 -0
- package/src/components/elements/organisms/resizable/resizable.stories.tsx +204 -0
- package/src/components/elements/organisms/resizable/resizable.tsx +178 -0
- package/src/components/elements/organisms/scroll-area/index.ts +7 -0
- package/src/components/elements/organisms/scroll-area/scroll-area.stories.tsx +170 -0
- package/src/components/elements/organisms/scroll-area/scroll-area.tsx +167 -0
- package/src/components/elements/organisms/sheet/index.ts +7 -0
- package/src/components/elements/organisms/sheet/sheet.stories.tsx +235 -0
- package/src/components/elements/organisms/sheet/sheet.tsx +381 -0
- package/src/components/elements/organisms/table/index.ts +7 -0
- package/src/components/elements/organisms/table/table.stories.tsx +238 -0
- package/src/components/elements/organisms/table/table.tsx +392 -0
- package/src/components/elements/organisms/tooltip/index.ts +7 -0
- package/src/components/elements/organisms/tooltip/tooltip.stories.tsx +205 -0
- package/src/components/elements/organisms/tooltip/tooltip.tsx +547 -0
- package/src/components/filter/filter-list/filter-list.stories.tsx +157 -0
- package/src/components/filter/filter-list/filter-list.tsx +435 -0
- package/src/components/filter/filter-list/index.ts +7 -0
- package/src/components/filter/filter-select/filter-select.stories.tsx +124 -0
- package/src/components/filter/filter-select/filter-select.tsx +558 -0
- package/src/components/filter/filter-select/index.ts +7 -0
- package/src/components/filter/index.ts +9 -0
- package/src/components/filter/types.ts +70 -0
- package/src/components/forms/checkbox/checkbox.stories.tsx +177 -0
- package/src/components/forms/checkbox/checkbox.tsx +332 -0
- package/src/components/forms/checkbox/index.ts +11 -0
- package/src/components/forms/combobox/combobox.stories.tsx +224 -0
- package/src/components/forms/combobox/combobox.tsx +679 -0
- package/src/components/forms/combobox/index.ts +7 -0
- package/src/components/forms/date-picker/calendar/calendar.stories.tsx +78 -0
- package/src/components/forms/date-picker/calendar/calendar.tsx +271 -0
- package/src/components/forms/date-picker/calendar/index.ts +7 -0
- package/src/components/forms/date-picker/date-range-picker/date-range-picker.stories.tsx +108 -0
- package/src/components/forms/date-picker/date-range-picker/date-range-picker.tsx +334 -0
- package/src/components/forms/date-picker/date-range-picker/index.ts +7 -0
- package/src/components/forms/date-picker/index.ts +10 -0
- package/src/components/forms/date-picker/presets/index.ts +7 -0
- package/src/components/forms/date-picker/presets/presets.stories.tsx +105 -0
- package/src/components/forms/date-picker/presets/presets.tsx +196 -0
- package/src/components/forms/date-picker/shared.ts +109 -0
- package/src/components/forms/date-picker/trigger/index.ts +7 -0
- package/src/components/forms/date-picker/trigger/trigger.stories.tsx +78 -0
- package/src/components/forms/date-picker/trigger/trigger.tsx +195 -0
- package/src/components/forms/date-picker/types.ts +63 -0
- package/src/components/forms/file-upload/file-upload.stories.tsx +145 -0
- package/src/components/forms/file-upload/file-upload.tsx +504 -0
- package/src/components/forms/file-upload/index.ts +7 -0
- package/src/components/forms/input/index.ts +7 -0
- package/src/components/forms/input/input.stories.tsx +185 -0
- package/src/components/forms/input/input.tsx +228 -0
- package/src/components/forms/input-group/index.ts +11 -0
- package/src/components/forms/input-group/input-group.stories.tsx +146 -0
- package/src/components/forms/input-group/input-group.tsx +344 -0
- package/src/components/forms/label/index.ts +7 -0
- package/src/components/forms/label/label.stories.tsx +140 -0
- package/src/components/forms/label/label.tsx +189 -0
- package/src/components/forms/radio-group/index.ts +7 -0
- package/src/components/forms/radio-group/radio-group.stories.tsx +233 -0
- package/src/components/forms/radio-group/radio-group.tsx +476 -0
- package/src/components/forms/select/index.ts +7 -0
- package/src/components/forms/select/select.stories.tsx +274 -0
- package/src/components/forms/select/select.tsx +654 -0
- package/src/components/forms/switch/index.ts +11 -0
- package/src/components/forms/switch/switch.stories.tsx +166 -0
- package/src/components/forms/switch/switch.tsx +362 -0
- package/src/components/forms/textarea/index.ts +7 -0
- package/src/components/forms/textarea/textarea.stories.tsx +176 -0
- package/src/components/forms/textarea/textarea.tsx +225 -0
- package/src/components/layout/app-shell.tsx +363 -0
- package/src/components/layout/app-sidebar/app-sidebar.stories.tsx +68 -0
- package/src/components/layout/app-sidebar/app-sidebar.tsx +418 -0
- package/src/components/layout/app-sidebar/index.ts +11 -0
- package/src/components/layout/artifact-panel/artifact-panel-header.tsx +89 -0
- package/src/components/layout/artifact-panel/expandable-panel.stories.tsx +484 -0
- package/src/components/layout/artifact-panel/expandable-panel.tsx +289 -0
- package/src/components/layout/artifact-panel/index.ts +23 -0
- package/src/components/layout/artifact-panel/split-panel-layout.tsx +70 -0
- package/src/components/layout/artifact-panel/types.ts +63 -0
- package/src/components/layout/artifact-panel/use-artifact-panel-state.ts +101 -0
- package/src/components/layout/content-sidebar/content-sidebar.stories.tsx +490 -0
- package/src/components/layout/content-sidebar/content-sidebar.tsx +337 -0
- package/src/components/layout/content-sidebar/index.ts +17 -0
- package/src/components/layout/nav-app-switcher/index.ts +7 -0
- package/src/components/layout/nav-app-switcher/nav-app-switcher.stories.tsx +138 -0
- package/src/components/layout/nav-app-switcher/nav-app-switcher.tsx +282 -0
- package/src/components/layout/nav-main/index.ts +11 -0
- package/src/components/layout/nav-main/nav-main.stories.tsx +103 -0
- package/src/components/layout/nav-main/nav-main.tsx +259 -0
- package/src/components/layout/nav-projects/index.ts +11 -0
- package/src/components/layout/nav-projects/nav-projects.stories.tsx +82 -0
- package/src/components/layout/nav-projects/nav-projects.tsx +218 -0
- package/src/components/layout/nav-secondary/index.ts +11 -0
- package/src/components/layout/nav-secondary/nav-secondary.stories.tsx +81 -0
- package/src/components/layout/nav-secondary/nav-secondary.tsx +145 -0
- package/src/components/layout/nav-user/index.ts +11 -0
- package/src/components/layout/nav-user/nav-user.stories.tsx +80 -0
- package/src/components/layout/nav-user/nav-user.tsx +226 -0
- package/src/components/layout/oneapp/auth-context.tsx +74 -0
- package/src/components/layout/oneapp/ensure-anonymous-session.tsx +218 -0
- package/src/components/layout/oneapp/index.ts +37 -0
- package/src/components/layout/oneapp/microfrontend-layout.tsx +191 -0
- package/src/components/layout/oneapp/types.ts +98 -0
- package/src/components/layout/sidebar/index.ts +7 -0
- package/src/components/layout/sidebar/sidebar.stories.tsx +170 -0
- package/src/components/layout/sidebar/sidebar.tsx +945 -0
- package/src/components/layout/sidebar-inset-header-portal/index.ts +8 -0
- package/src/components/layout/sidebar-inset-header-portal/sidebar-inset-header-portal.stories.tsx +355 -0
- package/src/components/layout/sidebar-inset-header-portal/sidebar-inset-header-portal.tsx +179 -0
- package/src/components/layout/sidebar-slots/USAGE.md +163 -0
- package/src/components/layout/sidebar-slots/__tests__/sidebar-slots.test.tsx +239 -0
- package/src/components/layout/sidebar-slots/index.ts +9 -0
- package/src/components/layout/sidebar-slots/sidebar-slots.stories.tsx +525 -0
- package/src/components/layout/sidebar-slots/sidebar-slots.tsx +205 -0
- package/src/components/layout/theme-provider/index.ts +11 -0
- package/src/components/layout/theme-provider/theme-provider.stories.tsx +82 -0
- package/src/components/layout/theme-provider/theme-provider.tsx +101 -0
- package/src/components/overlays/confirm-dialog.stories.tsx +371 -0
- package/src/components/overlays/confirm-dialog.tsx +201 -0
- package/src/components/overlays/toast.stories.tsx +373 -0
- package/src/components/overlays/toast.tsx +115 -0
- package/src/constants/container.ts +183 -0
- package/src/constants/index.ts +38 -0
- package/src/constants/motion.ts +104 -0
- package/src/fonts/Satoshi-Variable.woff2 +0 -0
- package/src/fonts/Satoshi-VariableItalic.woff2 +0 -0
- package/src/fonts/fonts.css +41 -0
- package/src/fonts/index.ts +106 -0
- package/src/hooks/.gitkeep +0 -0
- package/src/hooks/ai-chat/context.tsx +294 -0
- package/src/hooks/ai-chat/hooks.ts +297 -0
- package/src/hooks/ai-chat/index.ts +35 -0
- package/src/hooks/ai-chat/utils.ts +65 -0
- package/src/hooks/index.ts +18 -0
- package/src/hooks/use-mobile.ts +45 -0
- package/src/hooks/use-responsive.ts +64 -0
- package/src/hooks/use-scroll-progress.ts +101 -0
- package/src/hooks/use-toast.ts +65 -0
- package/src/index.ts +857 -0
- package/src/lib/export-csv.ts +107 -0
- package/src/lib/index.ts +10 -0
- package/src/lib/resize-image.ts +109 -0
- package/src/lib/stable-sort.ts +29 -0
- package/src/lib/utils.ts +28 -0
- package/src/react-19-compat.d.ts +28 -0
- package/src/shared/auth/index.ts +8 -0
- package/src/shared/auth/types/index.ts +163 -0
- package/src/shared/auth/types.ts +196 -0
- package/src/shared/auth/utils/dark-mode.ts +336 -0
- package/src/shared/index.ts +5 -0
- package/src/styles/_tokens.generated.scss +84 -0
- package/src/styles/ai-elements.scss +9 -0
- package/src/styles/base.scss +44 -0
- package/src/styles/flows.scss +62 -0
- package/src/styles/globals.css +627 -0
- package/src/styles/index.scss +9 -0
- package/src/styles/shadcn.scss +16 -0
- package/src/styles/sources.css +16 -0
- package/src/styles/theme.css +1687 -0
- package/src/styles/theme.template.css +95 -0
- package/src/tokens/accessibility.ts +494 -0
- package/src/tokens/animations.ts +305 -0
- package/src/tokens/aspect-ratio.ts +89 -0
- package/src/tokens/blur.ts +82 -0
- package/src/tokens/border-width.ts +86 -0
- package/src/tokens/breakpoints.ts +150 -0
- package/src/tokens/colors.ts +1199 -0
- package/src/tokens/component.ts +362 -0
- package/src/tokens/container.ts +42 -0
- package/src/tokens/focus.ts +266 -0
- package/src/tokens/form-states.ts +521 -0
- package/src/tokens/grid.ts +258 -0
- package/src/tokens/index.ts +1175 -0
- package/src/tokens/interactions.ts +558 -0
- package/src/tokens/mantine-types.ts +68 -0
- package/src/tokens/opacity.ts +139 -0
- package/src/tokens/palette.ts +854 -0
- package/src/tokens/pseudo-elements.ts +508 -0
- package/src/tokens/radius.ts +57 -0
- package/src/tokens/shadows.ts +313 -0
- package/src/tokens/spacing.ts +95 -0
- package/src/tokens/states.ts +392 -0
- package/src/tokens/structural.ts +589 -0
- package/src/tokens/timing.ts +224 -0
- package/src/tokens/typography.ts +242 -0
- package/src/tokens/z-index.ts +184 -0
- package/storybook/preview.tsx +201 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2158 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { t as cn } from "./utils-D2bGp2p_.mjs";
|
|
3
|
+
import { useIsMobile } from "./hooks/use-mobile.mjs";
|
|
4
|
+
import { useResponsive } from "./hooks/use-responsive.mjs";
|
|
5
|
+
import { useScrollProgress } from "./hooks/use-scroll-progress.mjs";
|
|
6
|
+
import { a as SPRING_TACTILE, i as SPRING_GENTLE, o as SPRING_WEIGHTED, r as SPRING_FLUID } from "./motion-zelaDelJ.mjs";
|
|
7
|
+
import { AI_ANIMATE, AI_BODY, AI_COLLAPSIBLE, AI_COLORS, AI_CONTAINER, AI_CONTAINER_RADIUS, AI_DISABLED, AI_DURATION, AI_FOCUS, AI_HEADER, AI_HOVER, AI_ICON, AI_ICON_STYLE, AI_INTERACTION, AI_NESTED_RADIUS, AI_PADDING, AI_RADIUS, AI_SPACING, AI_STACK, AI_STAGGER_DELAY, AI_STATUS, AI_STYLES, AI_TEXT, AI_TITLE, AI_TRANSITION, AI_WEIGHT } from "./components-ai-elements-constants.mjs";
|
|
8
|
+
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./components-elements-accordion.mjs";
|
|
9
|
+
import { n as AlertDescription, r as AlertTitle, t as Alert } from "./alert-BuPyEXF-.mjs";
|
|
10
|
+
import { ToastContainer } from "./components-overlays-toast.mjs";
|
|
11
|
+
import { useToast } from "./hooks/use-toast.mjs";
|
|
12
|
+
import { c as skeletonVariants, i as SkeletonTransition, t as Skeleton } from "./skeleton-aXwA3YID.mjs";
|
|
13
|
+
import { r as buttonVariants, t as Button } from "./button-DVOrrZLw.mjs";
|
|
14
|
+
import { a as Card, c as CardDescription, d as CardTitle, l as CardFooter, o as CardAction, s as CardContent, u as CardHeader, v as cardVariants } from "./integrations-lBG309ZD.mjs";
|
|
15
|
+
import { i as TooltipTrigger, n as TooltipContent, o as tooltipContentVariants, r as TooltipProvider, t as Tooltip } from "./tooltip-B8_zKnHC.mjs";
|
|
16
|
+
import { t as Switch } from "./switch-BFct1r4a.mjs";
|
|
17
|
+
import { n as ErrorBoundary, r as withErrorBoundary, t as CardErrorFallback } from "./error-boundary-Ggc5btkU.mjs";
|
|
18
|
+
import { a as DialogFooter, c as DialogPortal, d as dialogContentVariants, i as DialogDescription, l as DialogTitle, n as DialogClose, o as DialogHeader, r as DialogContent, s as DialogOverlay, t as Dialog, u as DialogTrigger } from "./dialog-DuluSpxA.mjs";
|
|
19
|
+
import { ConfirmDialog, useConfirm } from "./components-overlays-confirm-dialog.mjs";
|
|
20
|
+
import { n as AvatarFallback, o as avatarVariants, r as AvatarImage, t as Avatar } from "./avatar-DjiX7nT8.mjs";
|
|
21
|
+
import { a as DropdownMenuItem, c as DropdownMenuRadioGroup, d as DropdownMenuShortcut, f as DropdownMenuSub, g as dropdownMenuItemVariants, h as DropdownMenuTrigger, i as DropdownMenuGroup, l as DropdownMenuRadioItem, m as DropdownMenuSubTrigger, n as DropdownMenuCheckboxItem, o as DropdownMenuLabel, p as DropdownMenuSubContent, r as DropdownMenuContent, s as DropdownMenuPortal, t as DropdownMenu, u as DropdownMenuSeparator } from "./dropdown-menu-91g1g_Cl.mjs";
|
|
22
|
+
import { n as separatorVariants, t as Separator } from "./separator-veJJBul5.mjs";
|
|
23
|
+
import { A as SheetHeader, C as SidebarTrigger, D as SheetContent, E as SheetClose, M as SheetTrigger, N as sheetContentVariants, O as SheetDescription, S as SidebarSeparator, T as Sheet, _ as SidebarMenuSub, a as SidebarGroupAction, b as SidebarProvider, c as SidebarHeader, d as SidebarMenu, f as SidebarMenuAction, g as SidebarMenuSkeleton, h as SidebarMenuItem, i as SidebarGroup, j as SheetTitle, k as SheetFooter, l as SidebarInput, m as SidebarMenuButton, n as SidebarContent, o as SidebarGroupContent, p as SidebarMenuBadge, r as SidebarFooter, s as SidebarGroupLabel, t as Sidebar, u as SidebarInset, v as SidebarMenuSubButton, w as useSidebar, x as SidebarRail, y as SidebarMenuSubItem } from "./sidebar-CdWE7H3R.mjs";
|
|
24
|
+
import { n as inputVariants, t as Input } from "./input-DhpkXN3J.mjs";
|
|
25
|
+
import { a as BreadcrumbLink, c as BreadcrumbSeparator, i as BreadcrumbItem, l as breadcrumbListVariants, n as Breadcrumb, o as BreadcrumbList, r as BreadcrumbEllipsis, s as BreadcrumbPage, t as DynamicBreadcrumb } from "./dynamic-breadcrumb-33t_hdEI.mjs";
|
|
26
|
+
import { i as resizableHandleVariants, n as ResizablePanel, r as ResizablePanelGroup, t as ResizableHandle } from "./resizable--DaTse0W.mjs";
|
|
27
|
+
import { t as NavAppSwitcher } from "./nav-app-switcher-V7aJAC18.mjs";
|
|
28
|
+
import { i as CollapsibleTrigger, n as CollapsibleContent, t as Collapsible } from "./collapsible-CXy4T04n.mjs";
|
|
29
|
+
import { t as NavMain } from "./nav-main-BscfzNoi.mjs";
|
|
30
|
+
import { t as NavSecondary } from "./nav-secondary-t-xeA0I4.mjs";
|
|
31
|
+
import { AppShell } from "./components-layout-app-shell.mjs";
|
|
32
|
+
import { t as AnimatedSizeContainer } from "./animated-size-container-DSKNt1Cn.mjs";
|
|
33
|
+
import { r as badgeVariants, t as Badge } from "./badge-CVoIuyYX.mjs";
|
|
34
|
+
import { a as CarouselPrevious, i as CarouselNext, n as CarouselContent, r as CarouselItem, t as Carousel } from "./carousel-Dx5AOW5k.mjs";
|
|
35
|
+
import { Area, AreaChart, Bar, BarChart, CartesianGrid, ChartContainer, ChartTooltip, ChartTooltipContent } from "./components-elements-chart.mjs";
|
|
36
|
+
import { i as useChartTooltipContext, n as ChartTooltipContext, r as useChartContext, t as ChartContext } from "./chart-context-CLV35VLJ.mjs";
|
|
37
|
+
import { n as ChartTooltipSyncContext, t as ChartTooltipSync } from "./tooltip-sync-DzJUgiTM.mjs";
|
|
38
|
+
import { n as useTooltip, t as TimeSeriesChart } from "./time-series-chart-DxnknDhW.mjs";
|
|
39
|
+
import { n as getFactors, r as nFormatter, t as currencyFormatter } from "./utils-BJGrUJ6T.mjs";
|
|
40
|
+
import { t as Areas } from "./areas-CtE8w69A.mjs";
|
|
41
|
+
import { t as Bars } from "./bars-DOLvecrq.mjs";
|
|
42
|
+
import { t as FunnelChart } from "./funnel-chart-fdwagDvc.mjs";
|
|
43
|
+
import { t as MiniAreaChart } from "./mini-area-chart-s5ItHBk8.mjs";
|
|
44
|
+
import { t as XAxis } from "./x-axis-BY00htJY.mjs";
|
|
45
|
+
import { t as YAxis } from "./y-axis-DgHlVHRG.mjs";
|
|
46
|
+
import { t as Checkbox } from "./checkbox-wiF-DV6q.mjs";
|
|
47
|
+
import { t as Popover } from "./popover-DmWxl2lW.mjs";
|
|
48
|
+
import { t as Combobox } from "./combobox-uEKksQFR.mjs";
|
|
49
|
+
import { n as DatePickerContext, r as Calendar, t as DateRangePicker } from "./date-range-picker-CdemRFs_.mjs";
|
|
50
|
+
import { t as FilterList } from "./filter-list-B_9aV5Lp.mjs";
|
|
51
|
+
import { a as CommandInput, c as CommandSeparator, i as CommandGroup, l as CommandShortcut, n as CommandDialog, o as CommandItem, r as CommandEmpty, s as CommandList, t as Command, u as commandItemVariants } from "./command-xK3X_A9t.mjs";
|
|
52
|
+
import { t as FilterSelect } from "./filter-select-CYfBhJ_E.mjs";
|
|
53
|
+
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "./components-elements-empty.mjs";
|
|
54
|
+
import { FileUpload } from "./components-forms/file-upload/index.mjs";
|
|
55
|
+
import { i as hoverCardContentVariants, n as HoverCardContent, r as HoverCardTrigger, t as HoverCard } from "./hover-card-nn4fjJOh.mjs";
|
|
56
|
+
import { n as textareaVariants, t as Textarea } from "./textarea-MpLFc9sB.mjs";
|
|
57
|
+
import { a as InputGroupText, i as InputGroupInput, n as InputGroupAddon, o as InputGroupTextarea, r as InputGroupButton, t as InputGroup } from "./input-group-CTBpkGI9.mjs";
|
|
58
|
+
import { n as labelVariants, t as Label } from "./label-DnUThLUR.mjs";
|
|
59
|
+
import { t as LoadingDots } from "./loading-dots-DJfxDgv3.mjs";
|
|
60
|
+
import { t as PaginationControls } from "./pagination-controls-CE3-eCxI.mjs";
|
|
61
|
+
import { r as progressVariants, t as Progress } from "./progress-BWxdthl4.mjs";
|
|
62
|
+
import { RadioGroup, RadioGroupItem } from "./components-forms/radio-group/index.mjs";
|
|
63
|
+
import { n as ScrollBar, r as scrollBarVariants, t as ScrollArea } from "./scroll-area-Bxi-Edjc.mjs";
|
|
64
|
+
import { a as SelectLabel, c as SelectSeparator, d as selectItemVariants, f as selectLabelVariants, i as SelectItem, l as SelectTrigger, n as SelectContent, o as SelectScrollDownButton, p as selectTriggerVariants, r as SelectGroup, s as SelectScrollUpButton, t as Select, u as SelectValue } from "./select-DI6PzHN3.mjs";
|
|
65
|
+
import { StatusBadge, statusBadgeVariants } from "./components-elements-status-badge.mjs";
|
|
66
|
+
import { a as TableFooter, c as TableRow, d as tableRowVariants, f as tableVariants, i as TableCell, l as tableCellVariants, n as TableBody, o as TableHead, r as TableCaption, s as TableHeader, t as Table, u as tableHeadVariants } from "./table-DNkLM1TB.mjs";
|
|
67
|
+
import { AnimatedTabs, AnimatedTabsList, AnimatedTabsTrigger, Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants, tabsTriggerVariants } from "./components-elements-tabs.mjs";
|
|
68
|
+
import { t as ThemeProvider } from "./theme-provider-4D34sBmG.mjs";
|
|
69
|
+
import { t as NavUser } from "./nav-user-A4YHm3-O.mjs";
|
|
70
|
+
import { AppSidebar, AppSidebarLayout } from "./components-layout/app-sidebar/index.mjs";
|
|
71
|
+
import { n as SidebarInsetHeaderRight, r as useSidebarInsetHeaderPortalMountRef, t as SidebarInsetHeaderPortalProvider } from "./sidebar-inset-header-portal-CIRN-lKw.mjs";
|
|
72
|
+
import { a as useSidebarSlotsOptional, i as useSidebarSlotsContent, n as useSidebarSlot, r as useSidebarSlots, t as SidebarSlotsProvider } from "./sidebar-slots-DNCEnx5L.mjs";
|
|
73
|
+
import { NavProjects } from "./components-layout/nav-projects/index.mjs";
|
|
74
|
+
import { a as ArtifactPanelHeader, i as useExpandablePanelState, n as SplitPanelLayout, r as ExpandablePanel, t as useArtifactPanelState } from "./use-artifact-panel-state-CUQTn2Uq.mjs";
|
|
75
|
+
import { n as Actions, t as Action } from "./actions-C-SEx2GS.mjs";
|
|
76
|
+
import { Artifact, ArtifactAction, ArtifactActions, ArtifactClose, ArtifactContent, ArtifactDescription, ArtifactHeader, ArtifactTitle } from "./components-ai-elements/artifact/index.mjs";
|
|
77
|
+
import { n as LoaderIcon, t as Loader } from "./loader-B2SF0yPJ.mjs";
|
|
78
|
+
import { AgentStep, agentStepVariants } from "./components-ai-elements/agent-step/index.mjs";
|
|
79
|
+
import { a as BranchPrevious, i as BranchPage, n as BranchMessages, o as BranchSelector, r as BranchNext, t as Branch } from "./branch-BEl6eS77.mjs";
|
|
80
|
+
import { ChainOfThought, ChainOfThoughtContent, ChainOfThoughtHeader, ChainOfThoughtImage, ChainOfThoughtSearchResult, ChainOfThoughtSearchResults, ChainOfThoughtStep, chainOfThoughtStepVariants } from "./components-ai-elements/chain-of-thought/index.mjs";
|
|
81
|
+
import { A as PromptInputSelectValue, C as PromptInputHoverCardContent, D as PromptInputSelectContent, E as PromptInputSelect, F as PromptInputTabItem, G as usePromptInputDropzone, H as usePromptInputAttachments, I as PromptInputTabLabel, L as PromptInputTabsList, M as PromptInputSubmit, N as PromptInputTab, O as PromptInputSelectItem, P as PromptInputTabBody, R as PromptInputTextarea, S as PromptInputHoverCard, T as PromptInputProvider, W as usePromptInputController, _ as PromptInputCommandItem, a as PromptInputActionMenuItem, b as PromptInputFooter, c as PromptInputAttachment, d as PromptInputButton, et as useProviderAttachments, g as PromptInputCommandInput, h as PromptInputCommandGroup, i as PromptInputActionMenuContent, j as PromptInputSpeechButton, k as PromptInputSelectTrigger, l as PromptInputAttachments, m as PromptInputCommandEmpty, n as PromptInputActionAddAttachments, o as PromptInputActionMenuTrigger, p as PromptInputCommand, r as PromptInputActionMenu, t as PromptInput, u as PromptInputBody, v as PromptInputCommandList, w as PromptInputHoverCardTrigger, x as PromptInputHeader, y as PromptInputCommandSeparator, z as PromptInputTools } from "./prompt-input-SFJ9_lNw.mjs";
|
|
82
|
+
import { ChatInput } from "./components-ai-elements/chat-input/index.mjs";
|
|
83
|
+
import { Checkpoint, CheckpointIcon, CheckpointTrigger } from "./components-ai-elements/checkpoint/index.mjs";
|
|
84
|
+
import { n as CodeBlockCopyButton, r as highlightCode, t as CodeBlock } from "./code-block-Cg_XtPH7.mjs";
|
|
85
|
+
import { Confirmation, ConfirmationAccepted, ConfirmationAction, ConfirmationActions, ConfirmationContent, ConfirmationRejected, ConfirmationRequest, ConfirmationTitle } from "./components-ai-elements/confirmation/index.mjs";
|
|
86
|
+
import { Context, ContextCacheUsage, ContextContent, ContextContentBody, ContextContentFooter, ContextContentHeader, ContextInputUsage, ContextOutputUsage, ContextReasoningUsage, ContextTrigger } from "./components-ai-elements/context/index.mjs";
|
|
87
|
+
import { Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton } from "./components-ai-elements/conversation/index.mjs";
|
|
88
|
+
import { Image } from "./components-ai-elements/image/index.mjs";
|
|
89
|
+
import { InlineCitation, InlineCitationCard, InlineCitationCardBody, InlineCitationCardTrigger, InlineCitationCarousel, InlineCitationCarouselContent, InlineCitationCarouselHeader, InlineCitationCarouselIndex, InlineCitationCarouselItem, InlineCitationCarouselNext, InlineCitationCarouselPrev, InlineCitationQuote, InlineCitationSource, InlineCitationText } from "./components-ai-elements/inline-citation/index.mjs";
|
|
90
|
+
import { Message, MessageAction, MessageActions, MessageAttachment, MessageAttachments, MessageContent, MessageResponse, MessageToolbar } from "./components-ai-elements/message/index.mjs";
|
|
91
|
+
import { ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger } from "./components-ai-elements/model-selector/index.mjs";
|
|
92
|
+
import { OpenIn, OpenInChatGPT, OpenInClaude, OpenInContent, OpenInCursor, OpenInGitHub, OpenInItem, OpenInLabel, OpenInScira, OpenInSeparator, OpenInT3, OpenInTrigger, OpenInv0, openInIconVariants } from "./components-ai-elements/open-in-chat/index.mjs";
|
|
93
|
+
import { t as Shimmer } from "./shimmer-BLRAD4VL.mjs";
|
|
94
|
+
import { Plan, PlanAction, PlanContent, PlanDescription, PlanFooter, PlanHeader, PlanStep, PlanSteps, PlanTitle, PlanTrigger } from "./components-ai-elements/plan/index.mjs";
|
|
95
|
+
import { Queue, QueueItem, QueueItemAction, QueueItemActions, QueueItemAttachment, QueueItemContent, QueueItemDescription, QueueItemFile, QueueItemImage, QueueItemIndicator, QueueList, QueueSection, QueueSectionContent, QueueSectionLabel, QueueSectionTrigger, queueItemIndicatorVariants } from "./components-ai-elements/queue/index.mjs";
|
|
96
|
+
import { Reasoning, ReasoningContent, ReasoningTrigger } from "./components-ai-elements/reasoning/index.mjs";
|
|
97
|
+
import { Source, Sources, SourcesContent, SourcesTrigger } from "./components-ai-elements/sources/index.mjs";
|
|
98
|
+
import { Suggestion, Suggestions } from "./components-ai-elements/suggestion/index.mjs";
|
|
99
|
+
import { Task, TaskContent, TaskItem, TaskItemFile, TaskTrigger, statusIconVariants } from "./components-ai-elements/task/index.mjs";
|
|
100
|
+
import { Tool, ToolContent, ToolHeader, ToolInput, ToolOutput } from "./components-ai-elements/tool/index.mjs";
|
|
101
|
+
import { ToolApproval } from "./components-ai-elements/tool-approval/index.mjs";
|
|
102
|
+
import { WebPreview, WebPreviewBackButton, WebPreviewBody, WebPreviewConsole, WebPreviewDeviceToggle, WebPreviewExampleSelect, WebPreviewForwardButton, WebPreviewFullscreenToggle, WebPreviewNavigation, WebPreviewNavigationButton, WebPreviewUrl } from "./components-ai-elements/web-preview/index.mjs";
|
|
103
|
+
import { n as GenerativeUIRenderer, t as DEFAULT_COMPONENT_MAP } from "./generative-ui-renderer-D0ZgNRZF.mjs";
|
|
104
|
+
import { Canvas } from "./components-ai-workflows/canvas/index.mjs";
|
|
105
|
+
import { t as Connection } from "./connection-D_kWZtAX.mjs";
|
|
106
|
+
import { Controls } from "./components-ai-workflows/controls/index.mjs";
|
|
107
|
+
import { Edge } from "./components-ai-workflows/edge/index.mjs";
|
|
108
|
+
import { a as NodeFooter, i as NodeDescription, n as NodeAction, o as NodeHeader, r as NodeContent, s as NodeTitle, t as Node } from "./node-CdmDD4k-.mjs";
|
|
109
|
+
import { Panel } from "./components-ai-workflows/panel/index.mjs";
|
|
110
|
+
import { Toolbar } from "./components-ai-workflows/toolbar/index.mjs";
|
|
111
|
+
import { forwardRef, memo, useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
112
|
+
import { useClipboard, useInterval, useMediaQuery, useMove, useReducedMotion, useUncontrolled } from "@mantine/hooks";
|
|
113
|
+
import { cva } from "class-variance-authority";
|
|
114
|
+
import { ArrowLeft, Check, Copy, Moon, Sun } from "lucide-react";
|
|
115
|
+
import { AnimatePresence, LayoutGroup, motion } from "motion/react";
|
|
116
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
117
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
118
|
+
import { useRouter } from "next/navigation";
|
|
119
|
+
import { useTheme } from "next-themes";
|
|
120
|
+
import { Logger } from "@repo/shared";
|
|
121
|
+
import Image$1 from "next/image";
|
|
122
|
+
import { Drawer } from "vaul";
|
|
123
|
+
import { Toaster as Toaster$1, toast } from "sonner";
|
|
124
|
+
import { formatDuration, intervalToDuration } from "date-fns";
|
|
125
|
+
import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
|
|
126
|
+
|
|
127
|
+
//#region src/components/elements/molecules/avatar-stack/avatar-stack.tsx
|
|
128
|
+
/**
|
|
129
|
+
* @fileoverview AvatarStack Component - Premium Harmony V2 (ES2023 + Tailwind v4 + CVA)
|
|
130
|
+
*
|
|
131
|
+
* A component for displaying multiple avatars in a stacked layout.
|
|
132
|
+
* Shows overlapping avatars with optional "+N" indicator for remaining count.
|
|
133
|
+
* Includes Premium Harmony V2 spring physics, touch detection, and stagger animations.
|
|
134
|
+
*
|
|
135
|
+
* @module @od-oneapp/uni-ui/components/elements/molecules/avatar-stack
|
|
136
|
+
*
|
|
137
|
+
* @component AvatarStack
|
|
138
|
+
*
|
|
139
|
+
* @useCases
|
|
140
|
+
* - Team member displays: Show participants in a project, document, or conversation
|
|
141
|
+
* - Collaboration indicators: Display active users editing a shared resource
|
|
142
|
+
* - Social proof: Show mutual connections, attendees, or endorsers
|
|
143
|
+
* - Comment threads: Display avatar stack of commenters on posts or issues
|
|
144
|
+
* - User lists: Compact representation of group members with overflow count
|
|
145
|
+
* - Activity feeds: Show who liked, shared, or reacted to content
|
|
146
|
+
* - Workspace indicators: Display team members in a channel or workspace
|
|
147
|
+
*
|
|
148
|
+
* Features:
|
|
149
|
+
* - ES2023 syntax with modern patterns
|
|
150
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
151
|
+
* - Premium Harmony V2 spring physics with device-adaptive motion
|
|
152
|
+
* - Touch vs desktop detection with optimized spring constants
|
|
153
|
+
* - Reduced motion support with graceful animation fallbacks
|
|
154
|
+
* - Stagger animations on mount with sequential reveal
|
|
155
|
+
* - Data attributes for avatar count tracking (data-count)
|
|
156
|
+
* - Enhanced focus styles for keyboard navigation
|
|
157
|
+
* - Super light/dark mode with seamless switching
|
|
158
|
+
* - CVA size variants for consistent spacing
|
|
159
|
+
* - Negative margin overlap with ring borders
|
|
160
|
+
* - Max avatar count with "+N" overflow indicator
|
|
161
|
+
* - Optional tooltip support per avatar
|
|
162
|
+
* - Memoized computations for performance
|
|
163
|
+
* - Semantic color tokens (no hardcoded colors)
|
|
164
|
+
*
|
|
165
|
+
* @variants
|
|
166
|
+
* - size: sm, default, lg, xl
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* <AvatarStack size="default" avatars={[{ src: '/user1.jpg', alt: 'Alice', tooltip: 'Alice Smith' }, { src: '/user2.jpg', alt: 'Bob' }, { fallback: 'CD', tooltip: 'Charlie Davis' }]} max={3} />
|
|
170
|
+
*/
|
|
171
|
+
const REMAINING_COUNT_FALLBACK_CLASSNAME = "bg-muted text-muted-foreground text-xs font-medium";
|
|
172
|
+
const avatarStackVariants = cva("flex", {
|
|
173
|
+
variants: { size: {
|
|
174
|
+
sm: "-space-x-1.5",
|
|
175
|
+
default: "-space-x-2",
|
|
176
|
+
lg: "-space-x-2.5",
|
|
177
|
+
xl: "-space-x-3"
|
|
178
|
+
} },
|
|
179
|
+
defaultVariants: { size: "default" }
|
|
180
|
+
});
|
|
181
|
+
function AvatarStack({ avatars, max, size, className, avatarClassName }) {
|
|
182
|
+
const reducedMotion = useReducedMotion();
|
|
183
|
+
const isTouchDevice = useMediaQuery("(pointer: coarse)");
|
|
184
|
+
const displayAvatars = useMemo(() => max != null && avatars.length > max ? avatars.slice(0, max) : avatars, [avatars, max]);
|
|
185
|
+
const remainingCount = useMemo(() => max != null ? avatars.length - max : 0, [avatars.length, max]);
|
|
186
|
+
const springConfig = useMemo(() => isTouchDevice ? SPRING_GENTLE : SPRING_TACTILE, [isTouchDevice]);
|
|
187
|
+
const containerVariants = useMemo(() => ({
|
|
188
|
+
hidden: { opacity: 0 },
|
|
189
|
+
visible: {
|
|
190
|
+
opacity: 1,
|
|
191
|
+
transition: { staggerChildren: reducedMotion ? 0 : .05 }
|
|
192
|
+
}
|
|
193
|
+
}), [reducedMotion]);
|
|
194
|
+
const avatarItemVariants = useMemo(() => ({
|
|
195
|
+
hidden: {
|
|
196
|
+
opacity: reducedMotion ? 1 : 0,
|
|
197
|
+
scale: reducedMotion ? 1 : .8,
|
|
198
|
+
y: reducedMotion ? 0 : 4
|
|
199
|
+
},
|
|
200
|
+
visible: {
|
|
201
|
+
opacity: 1,
|
|
202
|
+
scale: 1,
|
|
203
|
+
y: 0,
|
|
204
|
+
transition: springConfig
|
|
205
|
+
}
|
|
206
|
+
}), [reducedMotion, springConfig]);
|
|
207
|
+
const avatarRingClassName = useMemo(() => cn("ring-background ring-2 transition-all duration-300", "focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-ring focus-visible:ring-offset-2", avatarClassName), [avatarClassName]);
|
|
208
|
+
const rootClassName = useMemo(() => cn(avatarStackVariants({ size }), className), [size, className]);
|
|
209
|
+
return /* @__PURE__ */ jsxs(motion.div, {
|
|
210
|
+
className: rootClassName,
|
|
211
|
+
"data-count": avatars.length,
|
|
212
|
+
initial: "hidden",
|
|
213
|
+
animate: "visible",
|
|
214
|
+
variants: containerVariants,
|
|
215
|
+
children: [displayAvatars.map((avatar, index) => {
|
|
216
|
+
const avatarKey = avatar.src ?? avatar.alt ?? `avatar-${index}`;
|
|
217
|
+
const fallbackContent = avatar.fallback ?? avatar.alt?.charAt(0).toUpperCase();
|
|
218
|
+
const avatarElement = /* @__PURE__ */ jsx(motion.div, {
|
|
219
|
+
variants: avatarItemVariants,
|
|
220
|
+
whileHover: reducedMotion ? void 0 : {
|
|
221
|
+
scale: 1.1,
|
|
222
|
+
zIndex: 10,
|
|
223
|
+
transition: springConfig
|
|
224
|
+
},
|
|
225
|
+
whileTap: reducedMotion ? void 0 : {
|
|
226
|
+
scale: .95,
|
|
227
|
+
transition: springConfig
|
|
228
|
+
},
|
|
229
|
+
className: "relative",
|
|
230
|
+
children: /* @__PURE__ */ jsxs(Avatar, {
|
|
231
|
+
size,
|
|
232
|
+
className: avatarRingClassName,
|
|
233
|
+
children: [avatar.src != null && /* @__PURE__ */ jsx(AvatarImage, {
|
|
234
|
+
src: avatar.src,
|
|
235
|
+
alt: avatar.alt ?? ""
|
|
236
|
+
}), /* @__PURE__ */ jsx(AvatarFallback, { children: fallbackContent })]
|
|
237
|
+
})
|
|
238
|
+
}, avatarKey);
|
|
239
|
+
if (avatar.tooltip != null) return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
240
|
+
asChild: true,
|
|
241
|
+
children: avatarElement
|
|
242
|
+
}), /* @__PURE__ */ jsx(TooltipContent, { children: avatar.tooltip })] }) }, avatarKey);
|
|
243
|
+
return avatarElement;
|
|
244
|
+
}), remainingCount > 0 && /* @__PURE__ */ jsx(motion.div, {
|
|
245
|
+
variants: avatarItemVariants,
|
|
246
|
+
whileHover: reducedMotion ? void 0 : {
|
|
247
|
+
scale: 1.1,
|
|
248
|
+
zIndex: 10,
|
|
249
|
+
transition: springConfig
|
|
250
|
+
},
|
|
251
|
+
whileTap: reducedMotion ? void 0 : {
|
|
252
|
+
scale: .95,
|
|
253
|
+
transition: springConfig
|
|
254
|
+
},
|
|
255
|
+
className: "relative",
|
|
256
|
+
children: /* @__PURE__ */ jsx(Avatar, {
|
|
257
|
+
size,
|
|
258
|
+
className: avatarRingClassName,
|
|
259
|
+
children: /* @__PURE__ */ jsxs(AvatarFallback, {
|
|
260
|
+
className: REMAINING_COUNT_FALLBACK_CLASSNAME,
|
|
261
|
+
children: ["+", remainingCount]
|
|
262
|
+
})
|
|
263
|
+
})
|
|
264
|
+
})]
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
//#endregion
|
|
269
|
+
//#region src/components/elements/atoms/blur-image/blur-image.tsx
|
|
270
|
+
/**
|
|
271
|
+
* @fileoverview BlurImage Component - Premium Harmony V2
|
|
272
|
+
*
|
|
273
|
+
* A progressive image loading component with smooth fade-in animation and error fallback.
|
|
274
|
+
* Leverages Premium Harmony V2 spring physics for natural, fluid transitions. Wraps Next.js
|
|
275
|
+
* Image in a motion.div for fluid opacity transitions and respects reduced motion preferences.
|
|
276
|
+
*
|
|
277
|
+
* Features:
|
|
278
|
+
* - Progressive loading with smooth opacity fade-in animation
|
|
279
|
+
* - Premium Harmony V2 SPRING_FLUID physics for natural transitions
|
|
280
|
+
* - Automatic fallback to Vercel avatar on load errors
|
|
281
|
+
* - Small image detection (16x16 or smaller triggers fallback)
|
|
282
|
+
* - Reduced motion preference support for accessibility
|
|
283
|
+
* - Memoized handlers and computed values for performance
|
|
284
|
+
*
|
|
285
|
+
* @module @od-oneapp/uni-ui/components/elements/blur-image
|
|
286
|
+
* @component BlurImage
|
|
287
|
+
*
|
|
288
|
+
* @useCases
|
|
289
|
+
* - User avatars in chat interfaces, profiles, and comment sections
|
|
290
|
+
* - Product images in e-commerce catalogs and detail pages
|
|
291
|
+
* - Blog post featured images and thumbnails
|
|
292
|
+
* - Gallery images with progressive loading
|
|
293
|
+
* - Profile pictures in social feeds and directories
|
|
294
|
+
* - Team member photos on about pages
|
|
295
|
+
*
|
|
296
|
+
* @example <BlurImage src="/avatar.jpg" alt="User avatar" width={40} height={40} />
|
|
297
|
+
* @example <BlurImage src="/product.jpg" alt="Product" width={400} height={400} className="rounded-lg" />
|
|
298
|
+
* @example <BlurImage src="/hero.jpg" alt="Hero image" fill className="object-cover" />
|
|
299
|
+
*/
|
|
300
|
+
const BlurImage = memo((props) => {
|
|
301
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
302
|
+
const [hasError, setHasError] = useState(false);
|
|
303
|
+
const prefersReducedMotion = useReducedMotion() ?? false;
|
|
304
|
+
const fallbackAltText = useMemo(() => String(props.alt) ?? "image", [props.alt]);
|
|
305
|
+
const imageSrc = useMemo(() => {
|
|
306
|
+
if (hasError) return `https://avatar.vercel.sh/${encodeURIComponent(fallbackAltText)}`;
|
|
307
|
+
return props.src;
|
|
308
|
+
}, [
|
|
309
|
+
hasError,
|
|
310
|
+
props.src,
|
|
311
|
+
fallbackAltText
|
|
312
|
+
]);
|
|
313
|
+
const handleLoad = useCallback((e) => {
|
|
314
|
+
const target = e.target;
|
|
315
|
+
if (target.naturalWidth <= 16 && target.naturalHeight <= 16) setHasError(true);
|
|
316
|
+
else setIsLoaded(true);
|
|
317
|
+
}, []);
|
|
318
|
+
const handleError = useCallback(() => {
|
|
319
|
+
setHasError(true);
|
|
320
|
+
setIsLoaded(true);
|
|
321
|
+
}, []);
|
|
322
|
+
const altText = useMemo(() => String(props.alt) ?? "", [props.alt]);
|
|
323
|
+
return /* @__PURE__ */ jsx(motion.div, {
|
|
324
|
+
className: "bg-muted relative inline-block",
|
|
325
|
+
"data-component": "BlurImage",
|
|
326
|
+
"data-loaded": isLoaded || void 0,
|
|
327
|
+
"data-loading": !isLoaded || void 0,
|
|
328
|
+
initial: prefersReducedMotion ? false : { opacity: 0 },
|
|
329
|
+
animate: prefersReducedMotion ? false : { opacity: isLoaded ? 1 : .5 },
|
|
330
|
+
transition: SPRING_FLUID,
|
|
331
|
+
children: /* @__PURE__ */ jsx(Image$1, {
|
|
332
|
+
...props,
|
|
333
|
+
src: imageSrc,
|
|
334
|
+
alt: altText,
|
|
335
|
+
className: props.className,
|
|
336
|
+
onLoad: handleLoad,
|
|
337
|
+
onError: handleError,
|
|
338
|
+
unoptimized: true
|
|
339
|
+
})
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
BlurImage.displayName = "BlurImage";
|
|
343
|
+
|
|
344
|
+
//#endregion
|
|
345
|
+
//#region src/components/elements/molecules/button-group/button-group.tsx
|
|
346
|
+
/**
|
|
347
|
+
* @fileoverview ButtonGroup Component - Premium Harmony V2
|
|
348
|
+
*
|
|
349
|
+
* Groups multiple buttons together with connected borders and rounded corners.
|
|
350
|
+
* Supports both horizontal and vertical orientations with Premium Harmony V2 motion standards.
|
|
351
|
+
*
|
|
352
|
+
* Features:
|
|
353
|
+
* - ES2023 syntax with modern patterns
|
|
354
|
+
* - Premium Harmony V2 spring physics for tactile feedback
|
|
355
|
+
* - Touch detection with automatic sizing for mobile devices
|
|
356
|
+
* - Reduced motion support for accessibility
|
|
357
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
358
|
+
* - Super light/dark mode with seamless switching
|
|
359
|
+
* - Horizontal and vertical orientations
|
|
360
|
+
* - Connected borders with proper rounding
|
|
361
|
+
* - Polymorphic ButtonGroupText with asChild support
|
|
362
|
+
* - Focus-visible z-index management
|
|
363
|
+
* - Works with Button, Select, and Input components
|
|
364
|
+
* - 44px minimum touch targets on touch devices (WCAG 2.5.5)
|
|
365
|
+
* - Data attributes for state management
|
|
366
|
+
* - Semantic color tokens for theme adaptation
|
|
367
|
+
*
|
|
368
|
+
* @module @od-oneapp/uni-ui/components/elements/molecules/button-group
|
|
369
|
+
* @component ButtonGroup, ButtonGroupText, ButtonGroupSeparator
|
|
370
|
+
*
|
|
371
|
+
* @useCases
|
|
372
|
+
* - Toolbar actions: Editor controls, formatting buttons, view toggles
|
|
373
|
+
* - Segmented controls: Tab-like navigation, filter groups, sorting options
|
|
374
|
+
* - Split buttons: Combined primary action with dropdown menu
|
|
375
|
+
* - Form button groups: Submit/cancel, previous/next navigation pairs
|
|
376
|
+
* - Input addons: Icon buttons attached to search inputs or text fields
|
|
377
|
+
* - Toggle groups: Radio-style button groups for single/multiple selection
|
|
378
|
+
* - Pagination controls: Previous/numbers/next button combinations
|
|
379
|
+
* - Mobile toolbars: Compact action groups with 44px touch targets (WCAG 2.5.5)
|
|
380
|
+
*
|
|
381
|
+
* @subcomponents
|
|
382
|
+
* - ButtonGroup - Root container with orientation support
|
|
383
|
+
* - ButtonGroupText - Text element with muted styling
|
|
384
|
+
* - ButtonGroupSeparator - Visual separator between items
|
|
385
|
+
*
|
|
386
|
+
* @variants
|
|
387
|
+
* - orientation: horizontal (default), vertical
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* // Horizontal button group (toolbar)
|
|
391
|
+
* <ButtonGroup orientation="horizontal">
|
|
392
|
+
* <Button>Left</Button>
|
|
393
|
+
* <ButtonGroupSeparator />
|
|
394
|
+
* <Button>Center</Button>
|
|
395
|
+
* </ButtonGroup>
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* // Vertical button group (side panel)
|
|
399
|
+
* <ButtonGroup orientation="vertical">
|
|
400
|
+
* <Button>Option A</Button>
|
|
401
|
+
* <ButtonGroupSeparator />
|
|
402
|
+
* <Button>Option B</Button>
|
|
403
|
+
* </ButtonGroup>
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* // With text label
|
|
407
|
+
* <ButtonGroup>
|
|
408
|
+
* <ButtonGroupText>View:</ButtonGroupText>
|
|
409
|
+
* <Button variant="ghost" size="icon"><GridIcon /></Button>
|
|
410
|
+
* </ButtonGroup>
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* // Split button pattern
|
|
414
|
+
* <ButtonGroup>
|
|
415
|
+
* <Button>Save</Button>
|
|
416
|
+
* <ButtonGroupSeparator />
|
|
417
|
+
* <Button variant="ghost" size="icon"><ChevronDownIcon /></Button>
|
|
418
|
+
* </ButtonGroup>
|
|
419
|
+
*/
|
|
420
|
+
/**
|
|
421
|
+
* Premium Harmony V2 Spring Physics
|
|
422
|
+
* Exported from ai-elements.constants for consistent motion feel
|
|
423
|
+
* SPRING_TACTILE: { stiffness: 400, damping: 25 } - Used for button interactions
|
|
424
|
+
*/
|
|
425
|
+
const BUTTON_GROUP_TEXT_BASE_CLASSNAME = "bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4";
|
|
426
|
+
const BUTTON_GROUP_SEPARATOR_BASE_CLASSNAME = "bg-input relative [margin:0!important] self-stretch data-[orientation=vertical]:h-auto";
|
|
427
|
+
/**
|
|
428
|
+
* ButtonGroup variant definitions using CVA
|
|
429
|
+
*
|
|
430
|
+
* Base styles include:
|
|
431
|
+
* - Flex layout with stretch alignment for uniform child sizing
|
|
432
|
+
* - Z-index management for focus/hover/active states (ensures focused items appear above others)
|
|
433
|
+
* - Auto-width for select triggers
|
|
434
|
+
* - Connected borders with proper corner rounding
|
|
435
|
+
* - Support for nested button groups with gap spacing
|
|
436
|
+
*
|
|
437
|
+
* Premium Harmony V2 Considerations:
|
|
438
|
+
* - Child buttons should use 'touch' size variant on touch devices (44px minimum - WCAG 2.5.5)
|
|
439
|
+
* - Focus ring indicators are elevated above siblings via z-index
|
|
440
|
+
* - Semantic border colors from Tailwind v4 theme tokens
|
|
441
|
+
*/
|
|
442
|
+
const buttonGroupVariants = cva("flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:hover:z-10 [&>*]:active:z-10 [&>*]:focus-visible:relative [&>*]:hover:relative [&>*]:active:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2", {
|
|
443
|
+
variants: { orientation: {
|
|
444
|
+
horizontal: "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
|
|
445
|
+
vertical: "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none"
|
|
446
|
+
} },
|
|
447
|
+
defaultVariants: { orientation: "horizontal" }
|
|
448
|
+
});
|
|
449
|
+
/**
|
|
450
|
+
* ButtonGroup - Root container component
|
|
451
|
+
*
|
|
452
|
+
* Groups multiple buttons with connected borders and proper orientation.
|
|
453
|
+
* Automatically detects touch devices and applies appropriate sizing.
|
|
454
|
+
*
|
|
455
|
+
* @param orientation - Layout direction: 'horizontal' | 'vertical'
|
|
456
|
+
* @param className - Additional CSS classes
|
|
457
|
+
*
|
|
458
|
+
* Premium Harmony V2 Features:
|
|
459
|
+
* - Touch detection for adaptive sizing
|
|
460
|
+
* - Reduced motion support
|
|
461
|
+
* - Data attributes for state management
|
|
462
|
+
* - Semantic color tokens
|
|
463
|
+
* - Enhanced focus management with z-index layering
|
|
464
|
+
*/
|
|
465
|
+
function ButtonGroup({ className, orientation, ...props }) {
|
|
466
|
+
const isTouchDevice = useMediaQuery("(pointer: coarse)");
|
|
467
|
+
const shouldReduceMotion = useReducedMotion();
|
|
468
|
+
const groupClassName = useMemo(() => cn(buttonGroupVariants({ orientation }), className), [orientation, className]);
|
|
469
|
+
return /* @__PURE__ */ jsx("div", {
|
|
470
|
+
role: "group",
|
|
471
|
+
"data-slot": "button-group",
|
|
472
|
+
"data-orientation": orientation,
|
|
473
|
+
"data-touch": isTouchDevice ? "true" : "false",
|
|
474
|
+
"data-reduced-motion": shouldReduceMotion ? "true" : "false",
|
|
475
|
+
className: groupClassName,
|
|
476
|
+
...props
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* ButtonGroupText - Text label component for button groups
|
|
481
|
+
*
|
|
482
|
+
* Displays muted text labels alongside buttons, commonly used for
|
|
483
|
+
* describing the purpose of a button group (e.g., "View:", "Sort by:").
|
|
484
|
+
*
|
|
485
|
+
* @param asChild - Polymorphic rendering via Radix UI Slot
|
|
486
|
+
* @param className - Additional CSS classes
|
|
487
|
+
*
|
|
488
|
+
* Premium Harmony V2 Features:
|
|
489
|
+
* - Semantic color tokens for muted appearance
|
|
490
|
+
* - Consistent spacing and typography
|
|
491
|
+
* - Icon support with automatic sizing
|
|
492
|
+
* - Polymorphic rendering capability
|
|
493
|
+
*/
|
|
494
|
+
function ButtonGroupText({ className, asChild = false, ...props }) {
|
|
495
|
+
return /* @__PURE__ */ jsx(useMemo(() => asChild ? Slot : "div", [asChild]), {
|
|
496
|
+
className: useMemo(() => cn(BUTTON_GROUP_TEXT_BASE_CLASSNAME, className), [className]),
|
|
497
|
+
...props
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* ButtonGroupSeparator - Visual divider for button groups
|
|
502
|
+
*
|
|
503
|
+
* Provides subtle visual separation between buttons in a group.
|
|
504
|
+
* Orientation automatically adjusts based on parent ButtonGroup.
|
|
505
|
+
*
|
|
506
|
+
* @param orientation - 'vertical' (default) for horizontal groups, 'horizontal' for vertical groups
|
|
507
|
+
* @param className - Additional CSS classes
|
|
508
|
+
*
|
|
509
|
+
* Premium Harmony V2 Features:
|
|
510
|
+
* - Semantic color tokens for subtle borders
|
|
511
|
+
* - Automatic sizing based on parent orientation
|
|
512
|
+
* - Data attributes for orientation state
|
|
513
|
+
* - Self-stretching to match button height
|
|
514
|
+
*/
|
|
515
|
+
function ButtonGroupSeparator({ className, orientation = "vertical", ...props }) {
|
|
516
|
+
const separatorClassName = useMemo(() => cn(BUTTON_GROUP_SEPARATOR_BASE_CLASSNAME, className), [className]);
|
|
517
|
+
return /* @__PURE__ */ jsx(Separator, {
|
|
518
|
+
"data-slot": "button-group-separator",
|
|
519
|
+
orientation,
|
|
520
|
+
className: separatorClassName,
|
|
521
|
+
...props
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
//#endregion
|
|
526
|
+
//#region src/components/elements/atoms/copy-button/copy-button.tsx
|
|
527
|
+
/**
|
|
528
|
+
* @fileoverview CopyButton Component - Premium Harmony V2
|
|
529
|
+
*
|
|
530
|
+
* A button that copies text to the clipboard with visual feedback and spring physics.
|
|
531
|
+
*
|
|
532
|
+
* Features:
|
|
533
|
+
* - ES2023 syntax with modern patterns
|
|
534
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
535
|
+
* - Premium Harmony V2 spring physics (SPRING_TACTILE)
|
|
536
|
+
* - Touch-optimized with pointer detection and 44px minimum targets (WCAG 2.5.5)
|
|
537
|
+
* - Reduced motion support for accessibility
|
|
538
|
+
* - Complete pseudo-state coverage (:hover, :focus-visible, :active)
|
|
539
|
+
* - Visual feedback with check icon animation on copy
|
|
540
|
+
* - Optional toast notification
|
|
541
|
+
* - Custom icon support
|
|
542
|
+
* - State-driven data attributes
|
|
543
|
+
*
|
|
544
|
+
* @module @od-oneapp/uni-ui/components/elements/atoms/copy-button
|
|
545
|
+
*
|
|
546
|
+
* @component CopyButton
|
|
547
|
+
*
|
|
548
|
+
* @useCases
|
|
549
|
+
* - Copy API keys, URLs, or code snippets to clipboard
|
|
550
|
+
* - Provide visual confirmation with check icon animation
|
|
551
|
+
* - Inline copy actions in forms, cards, or documentation
|
|
552
|
+
* - Code block copy buttons with ghost variant
|
|
553
|
+
* - Share links with toast notification feedback
|
|
554
|
+
*
|
|
555
|
+
* @variants
|
|
556
|
+
* - variant: default, ghost
|
|
557
|
+
* - size: sm, default, lg
|
|
558
|
+
*
|
|
559
|
+
* @example <CopyButton value="https://example.com" />
|
|
560
|
+
*
|
|
561
|
+
* @example <CopyButton value={apiKey} successMessage="Copied!" variant="ghost" />
|
|
562
|
+
*
|
|
563
|
+
* @example <CopyButton value={code} size="sm" showToast={false} />
|
|
564
|
+
*/
|
|
565
|
+
/**
|
|
566
|
+
* CopyButton variant definitions using CVA
|
|
567
|
+
*
|
|
568
|
+
* Base styles include:
|
|
569
|
+
* - Rounded shape with overflow hidden
|
|
570
|
+
* - Focus-visible ring for accessibility
|
|
571
|
+
* - Active scale for micromoment feedback
|
|
572
|
+
* - Smooth transitions
|
|
573
|
+
* - 44px minimum touch targets
|
|
574
|
+
*/
|
|
575
|
+
const copyButtonVariants = cva([
|
|
576
|
+
"relative group rounded-full",
|
|
577
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
578
|
+
"focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
579
|
+
"transition-all duration-150"
|
|
580
|
+
], {
|
|
581
|
+
variants: {
|
|
582
|
+
variant: {
|
|
583
|
+
default: "bg-transparent hover:bg-muted active:bg-accent",
|
|
584
|
+
ghost: "bg-transparent hover:bg-muted/50 active:bg-muted"
|
|
585
|
+
},
|
|
586
|
+
size: {
|
|
587
|
+
sm: "p-1.5 min-h-[36px] min-w-[36px]",
|
|
588
|
+
default: "p-2 min-h-[44px] min-w-[44px]",
|
|
589
|
+
lg: "p-2.5 min-h-[48px] min-w-[48px]"
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
defaultVariants: {
|
|
593
|
+
variant: "default",
|
|
594
|
+
size: "default"
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
const COPY_BUTTON_ICON_BASE_CLASSNAME = "size-4 transition-colors duration-150";
|
|
598
|
+
const COPY_BUTTON_ICON_COPIED_CLASSNAME = "text-success animate-copy-success";
|
|
599
|
+
const COPY_BUTTON_ICON_DEFAULT_CLASSNAME = "text-muted-foreground";
|
|
600
|
+
const COPY_BUTTON_SR_ONLY_CLASSNAME = "sr-only";
|
|
601
|
+
const DEFAULT_SUCCESS_MESSAGE = "Copied to clipboard!";
|
|
602
|
+
const COPY_BUTTON_ARIA_LABEL_COPIED = "Copied";
|
|
603
|
+
const COPY_BUTTON_ARIA_LABEL_DEFAULT = "Copy to clipboard";
|
|
604
|
+
const COPY_BUTTON_SR_TEXT_COPIED = "Copied";
|
|
605
|
+
const COPY_BUTTON_SR_TEXT_DEFAULT = "Copy";
|
|
606
|
+
/**
|
|
607
|
+
* A button that copies text to the clipboard with visual feedback.
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* ```tsx
|
|
611
|
+
* <CopyButton value="https://example.com" />
|
|
612
|
+
*
|
|
613
|
+
* <CopyButton
|
|
614
|
+
* value={apiKey}
|
|
615
|
+
* successMessage="API key copied!"
|
|
616
|
+
* variant="ghost"
|
|
617
|
+
* />
|
|
618
|
+
* ```
|
|
619
|
+
*/
|
|
620
|
+
function CopyButton({ variant, size, value, className, icon: Icon = Copy, successMessage = DEFAULT_SUCCESS_MESSAGE, showToast = true }) {
|
|
621
|
+
const clipboard = useClipboard({ timeout: 2e3 });
|
|
622
|
+
useMediaQuery("(pointer: coarse)");
|
|
623
|
+
const reducedMotion = useReducedMotion() ?? false;
|
|
624
|
+
const handleCopy = useCallback(() => {
|
|
625
|
+
clipboard.copy(value);
|
|
626
|
+
if (showToast) toast.success(successMessage);
|
|
627
|
+
}, [
|
|
628
|
+
clipboard,
|
|
629
|
+
value,
|
|
630
|
+
showToast,
|
|
631
|
+
successMessage
|
|
632
|
+
]);
|
|
633
|
+
const handleClick = useCallback((e) => {
|
|
634
|
+
e.stopPropagation();
|
|
635
|
+
handleCopy();
|
|
636
|
+
}, [handleCopy]);
|
|
637
|
+
const DisplayIcon = useMemo(() => clipboard.copied ? Check : Icon, [clipboard.copied, Icon]);
|
|
638
|
+
const buttonClassName = useMemo(() => cn(copyButtonVariants({
|
|
639
|
+
variant,
|
|
640
|
+
size
|
|
641
|
+
}), reducedMotion && "transition-none", className), [
|
|
642
|
+
variant,
|
|
643
|
+
size,
|
|
644
|
+
className,
|
|
645
|
+
reducedMotion
|
|
646
|
+
]);
|
|
647
|
+
const iconClassName = useMemo(() => cn(COPY_BUTTON_ICON_BASE_CLASSNAME, reducedMotion && "transition-none", clipboard.copied ? COPY_BUTTON_ICON_COPIED_CLASSNAME : COPY_BUTTON_ICON_DEFAULT_CLASSNAME), [clipboard.copied, reducedMotion]);
|
|
648
|
+
const ariaLabel = useMemo(() => clipboard.copied ? COPY_BUTTON_ARIA_LABEL_COPIED : COPY_BUTTON_ARIA_LABEL_DEFAULT, [clipboard.copied]);
|
|
649
|
+
const srOnlyText = useMemo(() => clipboard.copied ? COPY_BUTTON_SR_TEXT_COPIED : COPY_BUTTON_SR_TEXT_DEFAULT, [clipboard.copied]);
|
|
650
|
+
return /* @__PURE__ */ jsxs(motion.button, {
|
|
651
|
+
type: "button",
|
|
652
|
+
onClick: handleClick,
|
|
653
|
+
className: buttonClassName,
|
|
654
|
+
"aria-label": ariaLabel,
|
|
655
|
+
"data-copied": clipboard.copied ? "true" : "false",
|
|
656
|
+
whileTap: reducedMotion ? void 0 : { scale: .98 },
|
|
657
|
+
transition: SPRING_TACTILE,
|
|
658
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
659
|
+
className: COPY_BUTTON_SR_ONLY_CLASSNAME,
|
|
660
|
+
children: srOnlyText
|
|
661
|
+
}), /* @__PURE__ */ jsx(DisplayIcon, { className: iconClassName })]
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
//#endregion
|
|
666
|
+
//#region src/components/elements/atoms/copy-text/copy-text.tsx
|
|
667
|
+
/**
|
|
668
|
+
* CopyText variant definitions using CVA
|
|
669
|
+
*
|
|
670
|
+
* Base styles include:
|
|
671
|
+
* - Inline display with text styling
|
|
672
|
+
* - Cursor and underline affordance
|
|
673
|
+
* - Focus-visible ring for accessibility
|
|
674
|
+
* - Active scale for micromoment feedback
|
|
675
|
+
* - Smooth transitions
|
|
676
|
+
*/
|
|
677
|
+
const copyTextVariants = cva([
|
|
678
|
+
"text-muted-foreground cursor-copy",
|
|
679
|
+
"decoration-dotted underline-offset-2 hover:underline",
|
|
680
|
+
"focus-visible:ring-ring focus-visible:ring-offset-background",
|
|
681
|
+
"focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none",
|
|
682
|
+
"transition-colors duration-150",
|
|
683
|
+
"dark:text-muted-foreground/90"
|
|
684
|
+
], {
|
|
685
|
+
variants: {
|
|
686
|
+
size: {
|
|
687
|
+
sm: "text-xs min-h-[36px] inline-flex items-center",
|
|
688
|
+
default: "text-sm min-h-[44px] inline-flex items-center",
|
|
689
|
+
lg: "text-base min-h-[48px] inline-flex items-center"
|
|
690
|
+
},
|
|
691
|
+
copied: {
|
|
692
|
+
true: "cursor-default",
|
|
693
|
+
false: ""
|
|
694
|
+
}
|
|
695
|
+
},
|
|
696
|
+
defaultVariants: {
|
|
697
|
+
size: "default",
|
|
698
|
+
copied: false
|
|
699
|
+
}
|
|
700
|
+
});
|
|
701
|
+
const DEFAULT_COPY_TEXT_SUCCESS_MESSAGE = "Copied to clipboard!";
|
|
702
|
+
/**
|
|
703
|
+
* Renders a button-like text element that copies the provided `value` to the clipboard when clicked and shows a toast on success.
|
|
704
|
+
* Premium Harmony V2 implementation with touch detection and adaptive animations.
|
|
705
|
+
*
|
|
706
|
+
* @param value - The string to copy to the clipboard.
|
|
707
|
+
* @param children - Content shown inside the button.
|
|
708
|
+
* @param className - Additional CSS class names applied to the button.
|
|
709
|
+
* @param size - Size variant (sm, default, lg) with touch-friendly defaults.
|
|
710
|
+
* @param successMessage - Toast message shown after a successful copy; defaults to `'Copied to clipboard!'`.
|
|
711
|
+
* @returns The rendered button element that performs the copy action when clicked.
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* ```tsx
|
|
715
|
+
* <CopyText value="user@example.com">user@example.com</CopyText>
|
|
716
|
+
*
|
|
717
|
+
* <CopyText value={apiKey} size="lg" successMessage="API key copied!">
|
|
718
|
+
* Click to copy API key
|
|
719
|
+
* </CopyText>
|
|
720
|
+
* ```
|
|
721
|
+
*/
|
|
722
|
+
const CopyText = memo(function CopyText({ value, children, className, size, successMessage = DEFAULT_COPY_TEXT_SUCCESS_MESSAGE }) {
|
|
723
|
+
const clipboard = useClipboard({ timeout: 2e3 });
|
|
724
|
+
const reducedMotion = useReducedMotion() ?? false;
|
|
725
|
+
const isTouchDevice = useMediaQuery("(pointer: coarse)") ?? false;
|
|
726
|
+
const handleClick = useCallback((e) => {
|
|
727
|
+
e.stopPropagation();
|
|
728
|
+
clipboard.copy(value);
|
|
729
|
+
toast.success(successMessage);
|
|
730
|
+
}, [
|
|
731
|
+
clipboard,
|
|
732
|
+
value,
|
|
733
|
+
successMessage
|
|
734
|
+
]);
|
|
735
|
+
const buttonClassName = useMemo(() => cn(copyTextVariants({
|
|
736
|
+
size,
|
|
737
|
+
copied: clipboard.copied
|
|
738
|
+
}), reducedMotion && "transition-none", className), [
|
|
739
|
+
size,
|
|
740
|
+
clipboard.copied,
|
|
741
|
+
className,
|
|
742
|
+
reducedMotion
|
|
743
|
+
]);
|
|
744
|
+
const springConfig = useMemo(() => isTouchDevice ? {
|
|
745
|
+
type: "spring",
|
|
746
|
+
stiffness: 300,
|
|
747
|
+
damping: 20,
|
|
748
|
+
mass: .8
|
|
749
|
+
} : {
|
|
750
|
+
type: "spring",
|
|
751
|
+
stiffness: 400,
|
|
752
|
+
damping: 25,
|
|
753
|
+
mass: .6
|
|
754
|
+
}, [isTouchDevice]);
|
|
755
|
+
const tapScale = isTouchDevice ? .96 : .98;
|
|
756
|
+
return /* @__PURE__ */ jsx(motion.button, {
|
|
757
|
+
type: "button",
|
|
758
|
+
onClick: handleClick,
|
|
759
|
+
className: buttonClassName,
|
|
760
|
+
"data-copied": clipboard.copied,
|
|
761
|
+
"data-touch": isTouchDevice,
|
|
762
|
+
whileTap: reducedMotion ? void 0 : { scale: tapScale },
|
|
763
|
+
transition: springConfig,
|
|
764
|
+
children
|
|
765
|
+
});
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
//#endregion
|
|
769
|
+
//#region src/components/elements/atoms/go-back-button/go-back-button.tsx
|
|
770
|
+
/**
|
|
771
|
+
* @fileoverview GoBackButton Component - Premium Harmony V2
|
|
772
|
+
*
|
|
773
|
+
* A button component that navigates back in browser history or falls back to a specified URL.
|
|
774
|
+
* Useful for providing consistent navigation UX across different page contexts.
|
|
775
|
+
*
|
|
776
|
+
* Features:
|
|
777
|
+
* - Browser history navigation with automatic fallback URL support
|
|
778
|
+
* - Premium Harmony V2 motion animations with spring transitions
|
|
779
|
+
* - Touch vs desktop detection for optimized interactions
|
|
780
|
+
* - Respects reduced motion preferences for accessibility
|
|
781
|
+
* - Memoized handlers and variants for optimal performance
|
|
782
|
+
*
|
|
783
|
+
* @module @od-oneapp/uni-ui/components/go-back-button
|
|
784
|
+
* @component GoBackButton
|
|
785
|
+
*
|
|
786
|
+
* @useCases
|
|
787
|
+
* - Navigation fallback: Return to previous page or fallback URL when history is unavailable
|
|
788
|
+
* - Form cancellation: Cancel form editing and return to previous screen
|
|
789
|
+
* - Modal/dialog navigation: Close overlays and return to parent view
|
|
790
|
+
* - Breadcrumb navigation: Quick return to parent sections in hierarchical content
|
|
791
|
+
* - Wizard/multi-step flows: Navigate back through sequential processes
|
|
792
|
+
* - Mobile app navigation: Native-like back button behavior in web apps
|
|
793
|
+
* - Error page recovery: Return users to safe location after encountering errors
|
|
794
|
+
* - Deep-linked content: Provide escape route when entering app via external links
|
|
795
|
+
*
|
|
796
|
+
* @example <GoBackButton />
|
|
797
|
+
* @example <GoBackButton hrefFallback="/dashboard" />
|
|
798
|
+
* @example <GoBackButton hrefFallback="/projects" variant="outline" />
|
|
799
|
+
*/
|
|
800
|
+
const GO_BACK_BUTTON_LABEL = "Go Back";
|
|
801
|
+
const GO_BACK_FALLBACK_HREF = "/";
|
|
802
|
+
const GO_BACK_BUTTON_ICON_CLASSNAME = "mr-2 h-4 w-4";
|
|
803
|
+
const GoBackButton = memo(function GoBackButton({ hrefFallback = GO_BACK_FALLBACK_HREF, ...props }) {
|
|
804
|
+
useMediaQuery("(pointer: coarse)");
|
|
805
|
+
const shouldReduceMotion = useReducedMotion();
|
|
806
|
+
const handleGoBack = useCallback(() => {
|
|
807
|
+
if (typeof window !== "undefined" && window.history.length > 1) window.history.back();
|
|
808
|
+
else window.location.href = hrefFallback;
|
|
809
|
+
}, [hrefFallback]);
|
|
810
|
+
const motionVariants = useMemo(() => ({
|
|
811
|
+
initial: { scale: 1 },
|
|
812
|
+
hover: shouldReduceMotion ? {} : { scale: 1.02 },
|
|
813
|
+
tap: shouldReduceMotion ? {} : { scale: .98 }
|
|
814
|
+
}), [shouldReduceMotion]);
|
|
815
|
+
const transition = useMemo(() => shouldReduceMotion ? { duration: 0 } : SPRING_TACTILE, [shouldReduceMotion]);
|
|
816
|
+
return /* @__PURE__ */ jsx(motion.div, {
|
|
817
|
+
initial: "initial",
|
|
818
|
+
whileHover: "hover",
|
|
819
|
+
whileTap: "tap",
|
|
820
|
+
variants: motionVariants,
|
|
821
|
+
transition,
|
|
822
|
+
style: { display: "inline-block" },
|
|
823
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
824
|
+
variant: "goBack",
|
|
825
|
+
onClick: handleGoBack,
|
|
826
|
+
type: "button",
|
|
827
|
+
...props,
|
|
828
|
+
children: [/* @__PURE__ */ jsx(ArrowLeft, { className: GO_BACK_BUTTON_ICON_CLASSNAME }), GO_BACK_BUTTON_LABEL]
|
|
829
|
+
})
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
//#endregion
|
|
834
|
+
//#region src/components/elements/atoms/inline-snippet/inline-snippet.tsx
|
|
835
|
+
/**
|
|
836
|
+
* @fileoverview InlineSnippet Component - Premium Harmony V2
|
|
837
|
+
*
|
|
838
|
+
* An inline code/command display component with monospace styling.
|
|
839
|
+
* Designed for embedding code snippets, commands, or technical terms within text.
|
|
840
|
+
* Features Premium Harmony V2 design standards for clear technical communication.
|
|
841
|
+
*
|
|
842
|
+
* Features:
|
|
843
|
+
* - Premium Harmony V2 design standards
|
|
844
|
+
* - Data attributes for state management (data-variant, data-size)
|
|
845
|
+
* - ES2023 syntax with modern patterns
|
|
846
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
847
|
+
* - CVA variants for color and size options
|
|
848
|
+
* - Semantic color tokens for theme adaptation
|
|
849
|
+
* - Super light/dark mode with seamless switching
|
|
850
|
+
* - Rounded badge-style presentation
|
|
851
|
+
* - Monospace font for code clarity
|
|
852
|
+
*
|
|
853
|
+
* @module @od-oneapp/uni-ui/components/elements/inline-snippet
|
|
854
|
+
* @component InlineSnippet
|
|
855
|
+
*
|
|
856
|
+
* @useCases
|
|
857
|
+
* - Inline code: Reference function names, variables, or data types in text
|
|
858
|
+
* - Terminal commands: Displaying shell commands like `npm install` or `git commit`
|
|
859
|
+
* - File paths: Pointing to directories or specific files in documentation
|
|
860
|
+
* - Technical IDs: Showing unique identifiers, UUIDs, or hash values
|
|
861
|
+
* - Environment vars: Referencing configuration keys like `NODE_ENV` or `PORT`
|
|
862
|
+
* - API endpoints: Documenting REST methods or GraphQL queries
|
|
863
|
+
* - Shortcuts: Highlighting keyboard combinations like `Cmd+K` or `Ctrl+C`
|
|
864
|
+
*
|
|
865
|
+
* @variants
|
|
866
|
+
* - variant: info | success | warning | error | neutral
|
|
867
|
+
* - size: sm | default | lg
|
|
868
|
+
*
|
|
869
|
+
* @example <InlineSnippet>npm install</InlineSnippet>
|
|
870
|
+
* @example <InlineSnippet variant="success">200 OK</InlineSnippet>
|
|
871
|
+
* @example <InlineSnippet variant="neutral">usr_123456</InlineSnippet>
|
|
872
|
+
*/
|
|
873
|
+
/**
|
|
874
|
+
* InlineSnippet variant definitions using CVA
|
|
875
|
+
*
|
|
876
|
+
* Base styles include:
|
|
877
|
+
* - Inline display with padding
|
|
878
|
+
* - Monospace font for code clarity
|
|
879
|
+
* - Rounded corners
|
|
880
|
+
*/
|
|
881
|
+
const inlineSnippetVariants = cva([
|
|
882
|
+
"inline-block",
|
|
883
|
+
"rounded-md",
|
|
884
|
+
"font-mono",
|
|
885
|
+
"px-1.5 py-0.5"
|
|
886
|
+
], {
|
|
887
|
+
variants: {
|
|
888
|
+
variant: {
|
|
889
|
+
info: ["bg-info/15 text-info", "dark:bg-info/20 dark:text-info/90"],
|
|
890
|
+
success: ["bg-success/15 text-success", "dark:bg-success/20 dark:text-success/90"],
|
|
891
|
+
warning: ["bg-warning/15 text-warning", "dark:bg-warning/20 dark:text-warning/90"],
|
|
892
|
+
error: ["bg-destructive/15 text-destructive", "dark:bg-destructive/20 dark:text-destructive/90"],
|
|
893
|
+
neutral: ["bg-muted text-muted-foreground", "dark:bg-muted/80"]
|
|
894
|
+
},
|
|
895
|
+
size: {
|
|
896
|
+
sm: "text-xs",
|
|
897
|
+
default: "text-sm",
|
|
898
|
+
lg: "text-base"
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
defaultVariants: {
|
|
902
|
+
variant: "info",
|
|
903
|
+
size: "default"
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
/**
|
|
907
|
+
* An inline code/command display component.
|
|
908
|
+
*
|
|
909
|
+
* @example
|
|
910
|
+
* ```tsx
|
|
911
|
+
* <p>
|
|
912
|
+
* Run <InlineSnippet>npm install</InlineSnippet> to get started.
|
|
913
|
+
* </p>
|
|
914
|
+
*
|
|
915
|
+
* <p>
|
|
916
|
+
* Error: <InlineSnippet variant="error">ENOENT</InlineSnippet>
|
|
917
|
+
* </p>
|
|
918
|
+
* ```
|
|
919
|
+
*/
|
|
920
|
+
const InlineSnippet = memo(function InlineSnippet({ children, className, variant = "info", size = "default" }) {
|
|
921
|
+
return /* @__PURE__ */ jsx("span", {
|
|
922
|
+
className: useMemo(() => cn(inlineSnippetVariants({
|
|
923
|
+
variant,
|
|
924
|
+
size
|
|
925
|
+
}), className), [
|
|
926
|
+
variant,
|
|
927
|
+
size,
|
|
928
|
+
className
|
|
929
|
+
]),
|
|
930
|
+
"data-variant": variant,
|
|
931
|
+
"data-size": size,
|
|
932
|
+
children
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
|
|
936
|
+
//#endregion
|
|
937
|
+
//#region src/components/elements/organisms/modal/modal.tsx
|
|
938
|
+
/**
|
|
939
|
+
* @fileoverview Modal Component - Premium Harmony V2
|
|
940
|
+
*
|
|
941
|
+
* Responsive modal that shows as a drawer on mobile and a dialog on desktop.
|
|
942
|
+
* Provides adaptive UX based on device viewport with spring physics animations.
|
|
943
|
+
*
|
|
944
|
+
* Features:
|
|
945
|
+
* - Premium Harmony V2 spring physics animations (SPRING_GENTLE)
|
|
946
|
+
* - Motion/React for smooth, performant animations
|
|
947
|
+
* - Reduced motion support with useReducedMotion
|
|
948
|
+
* - ES2023 syntax with modern patterns
|
|
949
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
950
|
+
* - Super light/dark mode with seamless switching
|
|
951
|
+
* - Responsive: Drawer on mobile, Dialog on desktop
|
|
952
|
+
* - Radix UI Dialog primitives for accessibility
|
|
953
|
+
* - Vaul Drawer for mobile swipe gestures
|
|
954
|
+
* - Backdrop blur effect with semi-transparent overlay
|
|
955
|
+
* - Toast dismissal prevention (Sonner integration)
|
|
956
|
+
* - Next.js router integration for intercepted routes
|
|
957
|
+
* - Memoized handlers for optimal performance
|
|
958
|
+
* - Data attributes for state management (data-state)
|
|
959
|
+
* - Semantic color tokens (no hardcoded colors)
|
|
960
|
+
* - AnimatePresence for conditional rendering
|
|
961
|
+
*
|
|
962
|
+
* @module @od-oneapp/uni-ui/components/modal
|
|
963
|
+
* @component Modal, DrawerIsland
|
|
964
|
+
*
|
|
965
|
+
* @useCases
|
|
966
|
+
* - Display adaptive modals that respond to viewport size (drawer on mobile, dialog on desktop)
|
|
967
|
+
* - Create full-screen overlays for forms, settings, or content that requires user focus
|
|
968
|
+
* - Implement swipe-to-dismiss gestures on mobile for intuitive interactions
|
|
969
|
+
* - Show intercepted route content in Next.js app router architecture
|
|
970
|
+
* - Prevent modal dismissal when toast notifications are visible
|
|
971
|
+
* - Support controlled and uncontrolled modal states with router integration
|
|
972
|
+
* - Provide accessible modal dialogs with keyboard navigation and screen reader support
|
|
973
|
+
* - Create mobile-first experiences with native-feeling drawer interactions
|
|
974
|
+
*
|
|
975
|
+
* @subcomponents DrawerIsland - Visual drag indicator bar for mobile drawer mode
|
|
976
|
+
*
|
|
977
|
+
* @example <Modal showModal={isOpen} setShowModal={setIsOpen}><Content /></Modal>
|
|
978
|
+
* @example <Modal showModal={isOpen} setShowModal={setIsOpen} desktopOnly><DialogContent /></Modal>
|
|
979
|
+
*/
|
|
980
|
+
const MODAL_DRAWER_OVERLAY_CLASSNAME = "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm";
|
|
981
|
+
const MODAL_DRAWER_CONTENT_BASE_CLASSNAME = "fixed right-0 bottom-0 left-0 z-50 flex flex-col border-border bg-background rounded-t-xl border-t";
|
|
982
|
+
const MODAL_DRAWER_SCROLLABLE_CLASSNAME = "scrollbar-hide flex-1 overflow-y-auto rounded-t-xl bg-inherit";
|
|
983
|
+
const MODAL_DRAWER_ISLAND_CONTAINER_CLASSNAME = "sticky top-0 z-20 flex items-center justify-center rounded-t-xl bg-inherit";
|
|
984
|
+
const MODAL_DRAWER_ISLAND_BAR_CLASSNAME = "bg-border my-3 h-1 w-12 rounded-full";
|
|
985
|
+
const MODAL_DIALOG_OVERLAY_CLASSNAME = "fixed inset-0 z-40 bg-black/50 backdrop-blur-md";
|
|
986
|
+
const MODAL_DIALOG_CONTENT_BASE_CLASSNAME = "fixed inset-0 z-40 m-auto h-fit w-full max-w-md border-border bg-background border p-0 shadow-xl sm:rounded-2xl scrollbar-hide overflow-y-auto";
|
|
987
|
+
const MODAL_TITLE = "Modal";
|
|
988
|
+
const MODAL_DESCRIPTION = "This is a modal";
|
|
989
|
+
const SONNER_TOAST_SELECTOR = "[data-sonner-toast]";
|
|
990
|
+
const MODAL_BACKDROP_ID = "modal-backdrop";
|
|
991
|
+
const Modal = memo(function Modal({ children, className, showModal, setShowModal, onClose, desktopOnly, preventDefaultClose, drawerRootProps }) {
|
|
992
|
+
const router = useRouter();
|
|
993
|
+
const { isMobile } = useResponsive();
|
|
994
|
+
const reducedMotion = useReducedMotion() ?? false;
|
|
995
|
+
const shouldShowDrawer = useMemo(() => isMobile && !desktopOnly, [isMobile, desktopOnly]);
|
|
996
|
+
const closeModal = useCallback(({ dragged } = {}) => {
|
|
997
|
+
if (preventDefaultClose && !dragged) return;
|
|
998
|
+
onClose?.();
|
|
999
|
+
if (setShowModal) setShowModal(false);
|
|
1000
|
+
else router.back();
|
|
1001
|
+
}, [
|
|
1002
|
+
preventDefaultClose,
|
|
1003
|
+
onClose,
|
|
1004
|
+
setShowModal,
|
|
1005
|
+
router
|
|
1006
|
+
]);
|
|
1007
|
+
const handlePointerDownOutside = useCallback((event) => {
|
|
1008
|
+
if (event.detail.originalEvent.target instanceof Element && event.detail.originalEvent.target.closest(SONNER_TOAST_SELECTOR)) event.detail.originalEvent.preventDefault();
|
|
1009
|
+
}, []);
|
|
1010
|
+
const handleDrawerOpenChange = useCallback((open) => {
|
|
1011
|
+
if (!open) closeModal({ dragged: true });
|
|
1012
|
+
}, [closeModal]);
|
|
1013
|
+
const handleDialogOpenChange = useCallback((open) => {
|
|
1014
|
+
if (!open) closeModal();
|
|
1015
|
+
}, [closeModal]);
|
|
1016
|
+
const drawerContentClassName = useMemo(() => cn(MODAL_DRAWER_CONTENT_BASE_CLASSNAME, className), [className]);
|
|
1017
|
+
const dialogContentClassName = useMemo(() => cn(MODAL_DIALOG_CONTENT_BASE_CLASSNAME, className), [className]);
|
|
1018
|
+
const openState = useMemo(() => setShowModal ? showModal : true, [setShowModal, showModal]);
|
|
1019
|
+
const handleOpenAutoFocus = useCallback((e) => {
|
|
1020
|
+
e.preventDefault();
|
|
1021
|
+
}, []);
|
|
1022
|
+
const handleCloseAutoFocus = useCallback((e) => {
|
|
1023
|
+
e.preventDefault();
|
|
1024
|
+
}, []);
|
|
1025
|
+
if (shouldShowDrawer) return /* @__PURE__ */ jsx(Drawer.Root, {
|
|
1026
|
+
open: openState,
|
|
1027
|
+
onOpenChange: handleDrawerOpenChange,
|
|
1028
|
+
...drawerRootProps,
|
|
1029
|
+
children: /* @__PURE__ */ jsxs(Drawer.Portal, { children: [/* @__PURE__ */ jsx(Drawer.Overlay, {
|
|
1030
|
+
asChild: true,
|
|
1031
|
+
children: /* @__PURE__ */ jsx(motion.div, {
|
|
1032
|
+
"data-slot": "modal-drawer-overlay",
|
|
1033
|
+
"data-state": openState ? "open" : "closed",
|
|
1034
|
+
className: MODAL_DRAWER_OVERLAY_CLASSNAME,
|
|
1035
|
+
initial: { opacity: 0 },
|
|
1036
|
+
animate: { opacity: 1 },
|
|
1037
|
+
exit: { opacity: 0 },
|
|
1038
|
+
transition: reducedMotion ? { duration: 0 } : { duration: .2 }
|
|
1039
|
+
})
|
|
1040
|
+
}), /* @__PURE__ */ jsx(Drawer.Content, {
|
|
1041
|
+
"data-slot": "modal-drawer-content",
|
|
1042
|
+
"data-state": openState ? "open" : "closed",
|
|
1043
|
+
onPointerDownOutside: handlePointerDownOutside,
|
|
1044
|
+
className: drawerContentClassName,
|
|
1045
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1046
|
+
className: MODAL_DRAWER_SCROLLABLE_CLASSNAME,
|
|
1047
|
+
children: [
|
|
1048
|
+
/* @__PURE__ */ jsxs(VisuallyHidden.Root, { children: [/* @__PURE__ */ jsx(Drawer.Title, { children: MODAL_TITLE }), /* @__PURE__ */ jsx(Drawer.Description, { children: MODAL_DESCRIPTION })] }),
|
|
1049
|
+
/* @__PURE__ */ jsx(DrawerIsland, {}),
|
|
1050
|
+
children
|
|
1051
|
+
]
|
|
1052
|
+
})
|
|
1053
|
+
})] })
|
|
1054
|
+
});
|
|
1055
|
+
return /* @__PURE__ */ jsx(Dialog, {
|
|
1056
|
+
open: openState,
|
|
1057
|
+
onOpenChange: handleDialogOpenChange,
|
|
1058
|
+
children: /* @__PURE__ */ jsxs(DialogPortal, { children: [/* @__PURE__ */ jsx(DialogOverlay, {
|
|
1059
|
+
"data-slot": "modal-dialog-overlay",
|
|
1060
|
+
id: MODAL_BACKDROP_ID,
|
|
1061
|
+
className: MODAL_DIALOG_OVERLAY_CLASSNAME
|
|
1062
|
+
}), /* @__PURE__ */ jsxs(DialogContent, {
|
|
1063
|
+
"data-slot": "modal-dialog-content",
|
|
1064
|
+
onOpenAutoFocus: handleOpenAutoFocus,
|
|
1065
|
+
onCloseAutoFocus: handleCloseAutoFocus,
|
|
1066
|
+
onPointerDownOutside: handlePointerDownOutside,
|
|
1067
|
+
className: dialogContentClassName,
|
|
1068
|
+
children: [/* @__PURE__ */ jsxs(VisuallyHidden.Root, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: MODAL_TITLE }), /* @__PURE__ */ jsx(DialogDescription, { children: MODAL_DESCRIPTION })] }), children]
|
|
1069
|
+
})] })
|
|
1070
|
+
});
|
|
1071
|
+
});
|
|
1072
|
+
const DrawerIsland = memo(function DrawerIsland() {
|
|
1073
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1074
|
+
className: MODAL_DRAWER_ISLAND_CONTAINER_CLASSNAME,
|
|
1075
|
+
children: /* @__PURE__ */ jsx("div", { className: MODAL_DRAWER_ISLAND_BAR_CLASSNAME })
|
|
1076
|
+
});
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
//#endregion
|
|
1080
|
+
//#region src/components/elements/atoms/mode-toggle/mode-toggle.tsx
|
|
1081
|
+
/**
|
|
1082
|
+
* @fileoverview ModeToggle Component - Premium Harmony V2
|
|
1083
|
+
*
|
|
1084
|
+
* A theme toggle button that switches between light, dark, and system themes.
|
|
1085
|
+
* Built with Premium Harmony V2 design system standards.
|
|
1086
|
+
*
|
|
1087
|
+
* Features:
|
|
1088
|
+
* - Premium Harmony V2 spring physics (SPRING_TACTILE)
|
|
1089
|
+
* - Touch-optimized with 44px minimum touch targets (WCAG 2.5.5)
|
|
1090
|
+
* - Reduced motion support via useReducedMotion
|
|
1091
|
+
* - Touch detection via useMediaQuery (pointer: coarse)
|
|
1092
|
+
* - Sun/Moon icon animation with spring physics
|
|
1093
|
+
* - Data attributes for theme state (data-theme)
|
|
1094
|
+
* - Enhanced focus-visible ring styles
|
|
1095
|
+
* - Tailwind v4 CSS-first theming
|
|
1096
|
+
* - Dropdown menu with Light/Dark/System options
|
|
1097
|
+
* - Uses next-themes for theme management
|
|
1098
|
+
*
|
|
1099
|
+
* @module @od-oneapp/uni-ui/components/elements/mode-toggle
|
|
1100
|
+
* @component ModeToggle
|
|
1101
|
+
*
|
|
1102
|
+
* @useCases
|
|
1103
|
+
* - Application header/navigation theme switcher
|
|
1104
|
+
* - Settings page theme control
|
|
1105
|
+
* - Accessibility toolbar theme toggle
|
|
1106
|
+
* - Mobile app theme switcher (optimized for touch)
|
|
1107
|
+
* - Dashboard theme customization
|
|
1108
|
+
*
|
|
1109
|
+
* @example <ModeToggle />
|
|
1110
|
+
*/
|
|
1111
|
+
const MODE_TOGGLE_SR_ONLY_CLASSNAME = "sr-only";
|
|
1112
|
+
const MODE_TOGGLE_SR_TEXT = "Toggle theme";
|
|
1113
|
+
const THEME_LIGHT = "light";
|
|
1114
|
+
const THEME_DARK = "dark";
|
|
1115
|
+
const THEME_SYSTEM = "system";
|
|
1116
|
+
const THEME_LIGHT_LABEL = "Light";
|
|
1117
|
+
const THEME_DARK_LABEL = "Dark";
|
|
1118
|
+
const THEME_SYSTEM_LABEL = "System";
|
|
1119
|
+
/**
|
|
1120
|
+
* Mode toggle component with Premium Harmony V2 standards.
|
|
1121
|
+
*
|
|
1122
|
+
* Provides a dropdown button to switch between light, dark, and system themes.
|
|
1123
|
+
* Shows sun icon in light mode and moon icon in dark mode with spring physics animations.
|
|
1124
|
+
* Optimized for both mouse and touch interactions with 44px minimum touch targets.
|
|
1125
|
+
*
|
|
1126
|
+
* @returns {JSX.Element} Mode toggle component
|
|
1127
|
+
*
|
|
1128
|
+
* @example
|
|
1129
|
+
* ```tsx
|
|
1130
|
+
* <ModeToggle />
|
|
1131
|
+
* ```
|
|
1132
|
+
*/
|
|
1133
|
+
const ModeToggle = memo(function ModeToggle() {
|
|
1134
|
+
const { theme, setTheme } = useTheme();
|
|
1135
|
+
const reducedMotion = useReducedMotion() ?? false;
|
|
1136
|
+
const isTouch = useMediaQuery("(pointer: coarse)") ?? false;
|
|
1137
|
+
const handleSetLight = useCallback(() => {
|
|
1138
|
+
setTheme(THEME_LIGHT);
|
|
1139
|
+
}, [setTheme]);
|
|
1140
|
+
const handleSetDark = useCallback(() => {
|
|
1141
|
+
setTheme(THEME_DARK);
|
|
1142
|
+
}, [setTheme]);
|
|
1143
|
+
const handleSetSystem = useCallback(() => {
|
|
1144
|
+
setTheme(THEME_SYSTEM);
|
|
1145
|
+
}, [setTheme]);
|
|
1146
|
+
const springConfig = useMemo(() => reducedMotion ? { duration: 0 } : SPRING_TACTILE, [reducedMotion]);
|
|
1147
|
+
return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
1148
|
+
asChild: true,
|
|
1149
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
1150
|
+
variant: "outline",
|
|
1151
|
+
size: "icon",
|
|
1152
|
+
"data-theme": theme,
|
|
1153
|
+
className: cn("group", isTouch && "min-h-[44px] min-w-[44px]", "focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"),
|
|
1154
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1155
|
+
className: "relative flex items-center justify-center",
|
|
1156
|
+
children: /* @__PURE__ */ jsx(AnimatePresence, {
|
|
1157
|
+
mode: "wait",
|
|
1158
|
+
initial: false,
|
|
1159
|
+
children: /* @__PURE__ */ jsx(motion.div, {
|
|
1160
|
+
initial: reducedMotion ? false : {
|
|
1161
|
+
scale: 0,
|
|
1162
|
+
rotate: theme === "dark" ? 90 : -90
|
|
1163
|
+
},
|
|
1164
|
+
animate: {
|
|
1165
|
+
scale: 1,
|
|
1166
|
+
rotate: 0
|
|
1167
|
+
},
|
|
1168
|
+
exit: reducedMotion ? void 0 : {
|
|
1169
|
+
scale: 0,
|
|
1170
|
+
rotate: theme === "dark" ? -90 : 90
|
|
1171
|
+
},
|
|
1172
|
+
transition: springConfig,
|
|
1173
|
+
className: "flex items-center justify-center",
|
|
1174
|
+
children: theme === "dark" ? /* @__PURE__ */ jsx(Moon, { className: "h-[1.2rem] w-[1.2rem]" }) : /* @__PURE__ */ jsx(Sun, { className: "h-[1.2rem] w-[1.2rem]" })
|
|
1175
|
+
}, theme === "dark" ? "moon" : "sun")
|
|
1176
|
+
})
|
|
1177
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1178
|
+
className: MODE_TOGGLE_SR_ONLY_CLASSNAME,
|
|
1179
|
+
children: MODE_TOGGLE_SR_TEXT
|
|
1180
|
+
})]
|
|
1181
|
+
})
|
|
1182
|
+
}), /* @__PURE__ */ jsxs(DropdownMenuContent, {
|
|
1183
|
+
align: "end",
|
|
1184
|
+
children: [
|
|
1185
|
+
/* @__PURE__ */ jsx(DropdownMenuItem, {
|
|
1186
|
+
onClick: handleSetLight,
|
|
1187
|
+
children: THEME_LIGHT_LABEL
|
|
1188
|
+
}),
|
|
1189
|
+
/* @__PURE__ */ jsx(DropdownMenuItem, {
|
|
1190
|
+
onClick: handleSetDark,
|
|
1191
|
+
children: THEME_DARK_LABEL
|
|
1192
|
+
}),
|
|
1193
|
+
/* @__PURE__ */ jsx(DropdownMenuItem, {
|
|
1194
|
+
onClick: handleSetSystem,
|
|
1195
|
+
children: THEME_SYSTEM_LABEL
|
|
1196
|
+
})
|
|
1197
|
+
]
|
|
1198
|
+
})] });
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
//#endregion
|
|
1202
|
+
//#region src/components/elements/atoms/progress-circle/progress-circle.tsx
|
|
1203
|
+
/**
|
|
1204
|
+
* @fileoverview ProgressCircle Component - Premium Harmony V2
|
|
1205
|
+
*
|
|
1206
|
+
* Circular progress indicator using SVG with semantic color variants.
|
|
1207
|
+
* Built with Premium Harmony V2 motion standards for smooth, accessible animations.
|
|
1208
|
+
*
|
|
1209
|
+
* Features:
|
|
1210
|
+
* - ES2023 syntax with modern patterns
|
|
1211
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
1212
|
+
* - Premium Harmony V2 spring physics (SPRING_FLUID)
|
|
1213
|
+
* - Reduced motion support for accessibility
|
|
1214
|
+
* - Multiple size and variant options
|
|
1215
|
+
* - Super light/dark mode with seamless switching
|
|
1216
|
+
* - Smooth progress animation with spring physics
|
|
1217
|
+
* - SVG-based for crisp rendering at any size
|
|
1218
|
+
* - Configurable stroke width
|
|
1219
|
+
* - Data attributes for state tracking (data-progress)
|
|
1220
|
+
* - Semantic color tokens (primary, success, warning, destructive, info)
|
|
1221
|
+
*
|
|
1222
|
+
* @module @od-oneapp/uni-ui/components/elements/progress-circle
|
|
1223
|
+
* @component ProgressCircle
|
|
1224
|
+
*
|
|
1225
|
+
* @useCases
|
|
1226
|
+
* - File upload progress: Circular indicator for upload operations
|
|
1227
|
+
* - Task completion: Visual feedback for multi-step processes
|
|
1228
|
+
* - Loading indicators: Indeterminate state for unknown durations
|
|
1229
|
+
* - Dashboard metrics: Percentage-based KPI visualization
|
|
1230
|
+
* - Skill/profile completion: Gamification elements showing progress
|
|
1231
|
+
* - Timer displays: Countdown or count-up progress tracking
|
|
1232
|
+
* - Data synchronization: Real-time sync progress feedback
|
|
1233
|
+
* - Achievement tracking: Goal progress with circular design
|
|
1234
|
+
* - Mobile app loading: Space-efficient progress in compact UIs
|
|
1235
|
+
*
|
|
1236
|
+
* @variants
|
|
1237
|
+
* - size: xs, sm, default, lg, xl
|
|
1238
|
+
* - variant: default, success, warning, destructive, info
|
|
1239
|
+
*
|
|
1240
|
+
* @example <ProgressCircle progress={0.75} />
|
|
1241
|
+
* @example <ProgressCircle progress={0.5} size="lg" variant="success" />
|
|
1242
|
+
* @example <ProgressCircle progress={0.9} strokeWidth={20} />
|
|
1243
|
+
*/
|
|
1244
|
+
const PROGRESS_CIRCLE_TRACK_CLASSNAME = "stroke-[var(--track-color)]";
|
|
1245
|
+
const DEFAULT_STROKE_WIDTH = 16;
|
|
1246
|
+
const DEFAULT_PROGRESS_MIN = 0;
|
|
1247
|
+
const DEFAULT_PROGRESS_MAX = 1;
|
|
1248
|
+
const SVG_VIEWBOX = "0 0 100 100";
|
|
1249
|
+
const SVG_CENTER = 50;
|
|
1250
|
+
const SVG_SIZE = 100;
|
|
1251
|
+
const PROGRESS_TRANSFORM_ORIGIN = "50px 50px";
|
|
1252
|
+
const PROGRESS_ROTATION = "-90deg";
|
|
1253
|
+
const CIRCLE_CIRCUMFERENCE_MULTIPLIER = Math.PI * 2;
|
|
1254
|
+
const progressCircleVariants = cva("shrink-0 [--track-color:var(--muted)]", {
|
|
1255
|
+
variants: {
|
|
1256
|
+
size: {
|
|
1257
|
+
xs: "size-3",
|
|
1258
|
+
sm: "size-4",
|
|
1259
|
+
default: "size-5",
|
|
1260
|
+
lg: "size-6",
|
|
1261
|
+
xl: "size-8"
|
|
1262
|
+
},
|
|
1263
|
+
variant: {
|
|
1264
|
+
default: "text-primary",
|
|
1265
|
+
success: "text-success",
|
|
1266
|
+
warning: "text-warning",
|
|
1267
|
+
destructive: "text-destructive",
|
|
1268
|
+
info: "text-info"
|
|
1269
|
+
}
|
|
1270
|
+
},
|
|
1271
|
+
defaultVariants: {
|
|
1272
|
+
size: "default",
|
|
1273
|
+
variant: "success"
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
const ProgressCircle = memo(function ProgressCircle({ progress: progressProp, strokeWidth = DEFAULT_STROKE_WIDTH, size, variant, className }) {
|
|
1277
|
+
const prefersReducedMotion = useReducedMotion() ?? false;
|
|
1278
|
+
const progress = useMemo(() => Math.min(Math.max(progressProp, DEFAULT_PROGRESS_MIN), DEFAULT_PROGRESS_MAX), [progressProp]);
|
|
1279
|
+
const radius = useMemo(() => (SVG_SIZE - strokeWidth) / 2, [strokeWidth]);
|
|
1280
|
+
const circumference = useMemo(() => radius * CIRCLE_CIRCUMFERENCE_MULTIPLIER, [radius]);
|
|
1281
|
+
const dash = useMemo(() => progress * circumference, [progress, circumference]);
|
|
1282
|
+
const strokeDashArray = useMemo(() => `${dash} ${circumference - dash}`, [dash, circumference]);
|
|
1283
|
+
const strokeWidthString = useMemo(() => `${strokeWidth}px`, [strokeWidth]);
|
|
1284
|
+
const progressCircleStyle = useMemo(() => ({
|
|
1285
|
+
transformOrigin: PROGRESS_TRANSFORM_ORIGIN,
|
|
1286
|
+
transform: `rotate(${PROGRESS_ROTATION})`
|
|
1287
|
+
}), []);
|
|
1288
|
+
const svgClassName = useMemo(() => cn(progressCircleVariants({
|
|
1289
|
+
size,
|
|
1290
|
+
variant
|
|
1291
|
+
}), className), [
|
|
1292
|
+
size,
|
|
1293
|
+
variant,
|
|
1294
|
+
className
|
|
1295
|
+
]);
|
|
1296
|
+
const transition = useMemo(() => prefersReducedMotion ? { duration: .01 } : SPRING_FLUID, [prefersReducedMotion]);
|
|
1297
|
+
const progressCircle = useMemo(() => progress > 0 ? /* @__PURE__ */ jsx(motion.circle, {
|
|
1298
|
+
cx: SVG_CENTER,
|
|
1299
|
+
cy: SVG_CENTER,
|
|
1300
|
+
r: radius,
|
|
1301
|
+
stroke: "currentColor",
|
|
1302
|
+
strokeWidth: strokeWidthString,
|
|
1303
|
+
fill: "none",
|
|
1304
|
+
strokeLinecap: "round",
|
|
1305
|
+
initial: { strokeDasharray: `0 ${circumference}` },
|
|
1306
|
+
animate: { strokeDasharray: strokeDashArray },
|
|
1307
|
+
transition,
|
|
1308
|
+
style: progressCircleStyle
|
|
1309
|
+
}) : null, [
|
|
1310
|
+
progress,
|
|
1311
|
+
radius,
|
|
1312
|
+
strokeWidthString,
|
|
1313
|
+
strokeDashArray,
|
|
1314
|
+
circumference,
|
|
1315
|
+
progressCircleStyle,
|
|
1316
|
+
transition
|
|
1317
|
+
]);
|
|
1318
|
+
const progressPercentage = useMemo(() => Math.round(progress * 100), [progress]);
|
|
1319
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
1320
|
+
width: SVG_SIZE,
|
|
1321
|
+
height: SVG_SIZE,
|
|
1322
|
+
viewBox: SVG_VIEWBOX,
|
|
1323
|
+
className: svgClassName,
|
|
1324
|
+
"data-progress": progressPercentage,
|
|
1325
|
+
children: [/* @__PURE__ */ jsx("circle", {
|
|
1326
|
+
cx: SVG_CENTER,
|
|
1327
|
+
cy: SVG_CENTER,
|
|
1328
|
+
r: radius,
|
|
1329
|
+
strokeWidth: strokeWidthString,
|
|
1330
|
+
fill: "none",
|
|
1331
|
+
strokeLinecap: "round",
|
|
1332
|
+
className: PROGRESS_CIRCLE_TRACK_CLASSNAME
|
|
1333
|
+
}), progressCircle]
|
|
1334
|
+
});
|
|
1335
|
+
});
|
|
1336
|
+
|
|
1337
|
+
//#endregion
|
|
1338
|
+
//#region src/components/elements/atoms/sonner/sonner.tsx
|
|
1339
|
+
/**
|
|
1340
|
+
* @fileoverview Toaster Component - Premium Harmony V2
|
|
1341
|
+
*
|
|
1342
|
+
* A pre-configured toast notification component with smooth slide animations,
|
|
1343
|
+
* reduced motion support, and semantic theming. Built on sonner with Premium
|
|
1344
|
+
* Harmony V2 accessibility and motion patterns.
|
|
1345
|
+
*
|
|
1346
|
+
* Features:
|
|
1347
|
+
* - Smooth slide-in/out animations with reduced motion support
|
|
1348
|
+
* - Semantic theming with rich colors for success/error/warning/info variants
|
|
1349
|
+
* - Focus-visible ring styles for keyboard accessibility
|
|
1350
|
+
* - Configurable position, duration, and close button
|
|
1351
|
+
* - System/light/dark theme modes
|
|
1352
|
+
*
|
|
1353
|
+
* @module @od-oneapp/uni-ui/components/elements/sonner
|
|
1354
|
+
* @component Toaster
|
|
1355
|
+
*
|
|
1356
|
+
* @useCases
|
|
1357
|
+
* - Success notifications (form submissions, saved changes, completed actions)
|
|
1358
|
+
* - Error alerts (validation failures, network errors, operation failures)
|
|
1359
|
+
* - Warning messages (unsaved changes, pending actions, deprecation notices)
|
|
1360
|
+
* - Info notifications (tips, updates, feature announcements)
|
|
1361
|
+
* - Loading states with promises (async operations, data fetching)
|
|
1362
|
+
*
|
|
1363
|
+
* @example <Toaster position="bottom-right" richColors />
|
|
1364
|
+
* @example toast.success('Changes saved!')
|
|
1365
|
+
* @example toast.error('Failed to save changes')
|
|
1366
|
+
* @example toast('Event created', { action: { label: 'Undo', onClick: handleUndo } })
|
|
1367
|
+
*/
|
|
1368
|
+
const DEFAULT_DURATION = 4e3;
|
|
1369
|
+
const DEFAULT_POSITION = "bottom-right";
|
|
1370
|
+
const DEFAULT_CLOSE_BUTTON = true;
|
|
1371
|
+
const DEFAULT_RICH_COLORS = true;
|
|
1372
|
+
const TOAST_BASE_CLASSNAME = "group toast bg-background text-foreground border border-border shadow-lg";
|
|
1373
|
+
const TOAST_ANIMATED_CLASSNAME = "animate-toast-slide-in data-[removed=true]:animate-toast-slide-out";
|
|
1374
|
+
const TOAST_DESCRIPTION_CLASSNAME = "group-[.toast]:text-muted-foreground";
|
|
1375
|
+
const TOAST_ACTIONBUTTON_CLASSNAME = "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground group-[.toast]:focus-visible:outline-none group-[.toast]:focus-visible:ring-2 group-[.toast]:focus-visible:ring-ring group-[.toast]:focus-visible:ring-offset-2";
|
|
1376
|
+
const TOAST_CANCELBUTTON_CLASSNAME = "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground group-[.toast]:focus-visible:outline-none group-[.toast]:focus-visible:ring-2 group-[.toast]:focus-visible:ring-ring group-[.toast]:focus-visible:ring-offset-2";
|
|
1377
|
+
const TOAST_CLOSEBUTTON_CLASSNAME = "group-[.toast]:focus-visible:outline-none group-[.toast]:focus-visible:ring-2 group-[.toast]:focus-visible:ring-ring group-[.toast]:focus-visible:ring-offset-2";
|
|
1378
|
+
/**
|
|
1379
|
+
* Pre-configured toast container with Premium Harmony V2 animations and theming.
|
|
1380
|
+
* Place once in your app's root layout. Automatically respects user's motion
|
|
1381
|
+
* preferences and theme settings.
|
|
1382
|
+
*
|
|
1383
|
+
* @remarks
|
|
1384
|
+
* This component uses data attributes for state tracking:
|
|
1385
|
+
* - `data-theme`: Current theme mode (light/dark/system)
|
|
1386
|
+
* - `data-reduced-motion`: Whether reduced motion is enabled
|
|
1387
|
+
* - `data-position`: Toast position on screen
|
|
1388
|
+
*/
|
|
1389
|
+
const Toaster = memo(function Toaster({ position = DEFAULT_POSITION, duration = DEFAULT_DURATION, closeButton = DEFAULT_CLOSE_BUTTON, richColors = DEFAULT_RICH_COLORS, theme = "system", toastOptions, ...props }) {
|
|
1390
|
+
const reducedMotion = useReducedMotion() ?? false;
|
|
1391
|
+
const toastClassName = useMemo(() => reducedMotion ? TOAST_BASE_CLASSNAME : `${TOAST_BASE_CLASSNAME} ${TOAST_ANIMATED_CLASSNAME}`, [reducedMotion]);
|
|
1392
|
+
return /* @__PURE__ */ jsx(Toaster$1, {
|
|
1393
|
+
theme,
|
|
1394
|
+
position,
|
|
1395
|
+
duration,
|
|
1396
|
+
closeButton,
|
|
1397
|
+
richColors,
|
|
1398
|
+
toastOptions: useMemo(() => ({
|
|
1399
|
+
...toastOptions,
|
|
1400
|
+
classNames: {
|
|
1401
|
+
toast: toastClassName,
|
|
1402
|
+
description: TOAST_DESCRIPTION_CLASSNAME,
|
|
1403
|
+
actionButton: TOAST_ACTIONBUTTON_CLASSNAME,
|
|
1404
|
+
cancelButton: TOAST_CANCELBUTTON_CLASSNAME,
|
|
1405
|
+
closeButton: TOAST_CLOSEBUTTON_CLASSNAME,
|
|
1406
|
+
...toastOptions?.classNames
|
|
1407
|
+
}
|
|
1408
|
+
}), [toastClassName, toastOptions]),
|
|
1409
|
+
...props
|
|
1410
|
+
});
|
|
1411
|
+
});
|
|
1412
|
+
|
|
1413
|
+
//#endregion
|
|
1414
|
+
//#region src/components/elements/atoms/slider/slider.tsx
|
|
1415
|
+
const DEFAULT_SLIDER_MIN = 0;
|
|
1416
|
+
const DEFAULT_SLIDER_MAX = 100;
|
|
1417
|
+
const DEFAULT_SLIDER_STEP = 1;
|
|
1418
|
+
const DEFAULT_SHOW_MARKS = false;
|
|
1419
|
+
const MARK_DIVISIONS = 3;
|
|
1420
|
+
const SLIDER_RANGE_CLASSNAME = "bg-primary absolute h-full left-0";
|
|
1421
|
+
const SLIDER_MARKS_CONTAINER_CLASSNAME = "pointer-events-none absolute inset-0";
|
|
1422
|
+
const SLIDER_MARK_CLASSNAME = "bg-background absolute top-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full shadow-sm";
|
|
1423
|
+
const SLIDER_HINT_CLASSNAME = "text-muted-foreground mt-2 min-h-[1rem] text-xs";
|
|
1424
|
+
const SLIDER_CONTAINER_CLASSNAME = "relative";
|
|
1425
|
+
const SLIDER_DISABLED_CLASSNAME = "opacity-50";
|
|
1426
|
+
const sliderRootVariants = cva("relative flex w-full touch-none select-none items-center", {
|
|
1427
|
+
variants: { size: {
|
|
1428
|
+
sm: "h-6 [--thumb-size:16px] [--track-height:4px]",
|
|
1429
|
+
default: "h-8 [--thumb-size:20px] [--track-height:6px]",
|
|
1430
|
+
lg: "h-10 [--thumb-size:24px] [--track-height:8px]",
|
|
1431
|
+
touch: "h-14 [--thumb-size:44px] [--track-height:10px]"
|
|
1432
|
+
} },
|
|
1433
|
+
defaultVariants: { size: "default" }
|
|
1434
|
+
});
|
|
1435
|
+
const sliderTrackVariants = cva("relative w-full grow overflow-hidden rounded-full bg-muted", {
|
|
1436
|
+
variants: { size: {
|
|
1437
|
+
sm: "h-1",
|
|
1438
|
+
default: "h-1.5",
|
|
1439
|
+
lg: "h-2",
|
|
1440
|
+
touch: "h-2.5"
|
|
1441
|
+
} },
|
|
1442
|
+
defaultVariants: { size: "default" }
|
|
1443
|
+
});
|
|
1444
|
+
const sliderThumbVariants = cva([
|
|
1445
|
+
"absolute block rounded-full border-2 border-primary bg-background shadow-md transition-colors cursor-grab",
|
|
1446
|
+
"ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
1447
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
1448
|
+
"active:cursor-grabbing"
|
|
1449
|
+
], {
|
|
1450
|
+
variants: { size: {
|
|
1451
|
+
sm: "size-4",
|
|
1452
|
+
default: "size-5",
|
|
1453
|
+
lg: "size-6",
|
|
1454
|
+
touch: "size-11"
|
|
1455
|
+
} },
|
|
1456
|
+
defaultVariants: { size: "default" }
|
|
1457
|
+
});
|
|
1458
|
+
const Slider = memo(forwardRef(function Slider({ className, size = "default", value: controlledValue, defaultValue, onValueChange, onValueCommit, marks, hint, showMarks = DEFAULT_SHOW_MARKS, min = DEFAULT_SLIDER_MIN, max = DEFAULT_SLIDER_MAX, step = DEFAULT_SLIDER_STEP, disabled, name, orientation = "horizontal", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-valuetext": ariaValueText }, ref) {
|
|
1459
|
+
const isTouchDevice = useMediaQuery("(pointer: coarse)");
|
|
1460
|
+
const shouldReduceMotion = useReducedMotion();
|
|
1461
|
+
const adjustedSize = useMemo(() => {
|
|
1462
|
+
if (!isTouchDevice || !size) return size;
|
|
1463
|
+
if (size === "default" || size === "sm" || size === "lg") return "touch";
|
|
1464
|
+
return size;
|
|
1465
|
+
}, [isTouchDevice, size]);
|
|
1466
|
+
const springConfig = useMemo(() => {
|
|
1467
|
+
if (shouldReduceMotion) return SPRING_GENTLE;
|
|
1468
|
+
return SPRING_TACTILE;
|
|
1469
|
+
}, [shouldReduceMotion]);
|
|
1470
|
+
const [value, setValue] = useUncontrolled({
|
|
1471
|
+
value: controlledValue,
|
|
1472
|
+
defaultValue: defaultValue ?? min,
|
|
1473
|
+
onChange: onValueChange
|
|
1474
|
+
});
|
|
1475
|
+
const trackRef = useRef(null);
|
|
1476
|
+
const thumbRef = useRef(null);
|
|
1477
|
+
const snapToStep = useCallback((val) => {
|
|
1478
|
+
const snapped = Math.round((val - min) / step) * step + min;
|
|
1479
|
+
return Math.min(Math.max(snapped, min), max);
|
|
1480
|
+
}, [
|
|
1481
|
+
min,
|
|
1482
|
+
max,
|
|
1483
|
+
step
|
|
1484
|
+
]);
|
|
1485
|
+
const positionToValue = useCallback((position) => {
|
|
1486
|
+
return snapToStep(min + position * (max - min));
|
|
1487
|
+
}, [
|
|
1488
|
+
min,
|
|
1489
|
+
max,
|
|
1490
|
+
snapToStep
|
|
1491
|
+
]);
|
|
1492
|
+
const valueToPercent = useCallback((val) => {
|
|
1493
|
+
return (val - min) / (max - min) * 100;
|
|
1494
|
+
}, [min, max]);
|
|
1495
|
+
const { ref: moveRef, active } = useMove(({ x }) => {
|
|
1496
|
+
if (!disabled) setValue(positionToValue(x));
|
|
1497
|
+
});
|
|
1498
|
+
useEffect(() => {
|
|
1499
|
+
if (!active && onValueCommit) onValueCommit(value);
|
|
1500
|
+
}, [
|
|
1501
|
+
active,
|
|
1502
|
+
value,
|
|
1503
|
+
onValueCommit
|
|
1504
|
+
]);
|
|
1505
|
+
const handleKeyDown = useCallback((e) => {
|
|
1506
|
+
if (disabled) return;
|
|
1507
|
+
let newValue = value;
|
|
1508
|
+
switch (e.key) {
|
|
1509
|
+
case "ArrowRight":
|
|
1510
|
+
case "ArrowUp":
|
|
1511
|
+
newValue = Math.min(value + step, max);
|
|
1512
|
+
break;
|
|
1513
|
+
case "ArrowLeft":
|
|
1514
|
+
case "ArrowDown":
|
|
1515
|
+
newValue = Math.max(value - step, min);
|
|
1516
|
+
break;
|
|
1517
|
+
case "PageUp":
|
|
1518
|
+
newValue = Math.min(value + step * 10, max);
|
|
1519
|
+
break;
|
|
1520
|
+
case "PageDown":
|
|
1521
|
+
newValue = Math.max(value - step * 10, min);
|
|
1522
|
+
break;
|
|
1523
|
+
case "Home":
|
|
1524
|
+
newValue = min;
|
|
1525
|
+
break;
|
|
1526
|
+
case "End":
|
|
1527
|
+
newValue = max;
|
|
1528
|
+
break;
|
|
1529
|
+
default: return;
|
|
1530
|
+
}
|
|
1531
|
+
e.preventDefault();
|
|
1532
|
+
setValue(newValue);
|
|
1533
|
+
onValueCommit?.(newValue);
|
|
1534
|
+
}, [
|
|
1535
|
+
disabled,
|
|
1536
|
+
value,
|
|
1537
|
+
step,
|
|
1538
|
+
min,
|
|
1539
|
+
max,
|
|
1540
|
+
setValue,
|
|
1541
|
+
onValueCommit
|
|
1542
|
+
]);
|
|
1543
|
+
const handleTrackClick = useCallback((e) => {
|
|
1544
|
+
if (disabled || !trackRef.current) return;
|
|
1545
|
+
const rect = trackRef.current.getBoundingClientRect();
|
|
1546
|
+
const position = (e.clientX - rect.left) / rect.width;
|
|
1547
|
+
const newValue = positionToValue(Math.max(0, Math.min(1, position)));
|
|
1548
|
+
setValue(newValue);
|
|
1549
|
+
onValueCommit?.(newValue);
|
|
1550
|
+
thumbRef.current?.focus();
|
|
1551
|
+
}, [
|
|
1552
|
+
disabled,
|
|
1553
|
+
positionToValue,
|
|
1554
|
+
setValue,
|
|
1555
|
+
onValueCommit
|
|
1556
|
+
]);
|
|
1557
|
+
const handleTrackKeyDown = useCallback((e) => {
|
|
1558
|
+
if (disabled) return;
|
|
1559
|
+
let newValue = value;
|
|
1560
|
+
switch (e.key) {
|
|
1561
|
+
case "ArrowRight":
|
|
1562
|
+
case "ArrowUp":
|
|
1563
|
+
newValue = Math.min(value + step, max);
|
|
1564
|
+
break;
|
|
1565
|
+
case "ArrowLeft":
|
|
1566
|
+
case "ArrowDown":
|
|
1567
|
+
newValue = Math.max(value - step, min);
|
|
1568
|
+
break;
|
|
1569
|
+
case "PageUp":
|
|
1570
|
+
newValue = Math.min(value + step * 10, max);
|
|
1571
|
+
break;
|
|
1572
|
+
case "PageDown":
|
|
1573
|
+
newValue = Math.max(value - step * 10, min);
|
|
1574
|
+
break;
|
|
1575
|
+
case "Home":
|
|
1576
|
+
newValue = min;
|
|
1577
|
+
break;
|
|
1578
|
+
case "End":
|
|
1579
|
+
newValue = max;
|
|
1580
|
+
break;
|
|
1581
|
+
default: return;
|
|
1582
|
+
}
|
|
1583
|
+
e.preventDefault();
|
|
1584
|
+
setValue(newValue);
|
|
1585
|
+
onValueCommit?.(newValue);
|
|
1586
|
+
thumbRef.current?.focus();
|
|
1587
|
+
}, [
|
|
1588
|
+
disabled,
|
|
1589
|
+
value,
|
|
1590
|
+
step,
|
|
1591
|
+
min,
|
|
1592
|
+
max,
|
|
1593
|
+
setValue,
|
|
1594
|
+
onValueCommit
|
|
1595
|
+
]);
|
|
1596
|
+
const sliderMarks = useMemo(() => {
|
|
1597
|
+
if (marks) return marks;
|
|
1598
|
+
if (!showMarks) return [];
|
|
1599
|
+
return [
|
|
1600
|
+
min,
|
|
1601
|
+
min + (max - min) / MARK_DIVISIONS,
|
|
1602
|
+
min + 2 * (max - min) / MARK_DIVISIONS,
|
|
1603
|
+
max
|
|
1604
|
+
];
|
|
1605
|
+
}, [
|
|
1606
|
+
marks,
|
|
1607
|
+
showMarks,
|
|
1608
|
+
min,
|
|
1609
|
+
max
|
|
1610
|
+
]);
|
|
1611
|
+
const valuePercent = useMemo(() => valueToPercent(value), [value, valueToPercent]);
|
|
1612
|
+
const rootClassName = useMemo(() => cn(sliderRootVariants({ size: adjustedSize }), disabled && SLIDER_DISABLED_CLASSNAME), [adjustedSize, disabled]);
|
|
1613
|
+
const trackClassName = useMemo(() => sliderTrackVariants({ size: adjustedSize }), [adjustedSize]);
|
|
1614
|
+
const thumbClassName = useMemo(() => sliderThumbVariants({ size: adjustedSize }), [adjustedSize]);
|
|
1615
|
+
const containerClassName = useMemo(() => cn(SLIDER_CONTAINER_CLASSNAME, className), [className]);
|
|
1616
|
+
const marksElement = useMemo(() => {
|
|
1617
|
+
if (sliderMarks.length === 0) return null;
|
|
1618
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1619
|
+
className: SLIDER_MARKS_CONTAINER_CLASSNAME,
|
|
1620
|
+
children: sliderMarks.map((mark) => {
|
|
1621
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1622
|
+
className: SLIDER_MARK_CLASSNAME,
|
|
1623
|
+
style: { left: `${valueToPercent(mark)}%` }
|
|
1624
|
+
}, mark);
|
|
1625
|
+
})
|
|
1626
|
+
});
|
|
1627
|
+
}, [sliderMarks, valueToPercent]);
|
|
1628
|
+
const thumbSize = useMemo(() => {
|
|
1629
|
+
if (adjustedSize === "sm") return 16;
|
|
1630
|
+
if (adjustedSize === "lg") return 24;
|
|
1631
|
+
if (adjustedSize === "touch") return 44;
|
|
1632
|
+
return 20;
|
|
1633
|
+
}, [adjustedSize]);
|
|
1634
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1635
|
+
ref,
|
|
1636
|
+
className: containerClassName,
|
|
1637
|
+
children: [
|
|
1638
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1639
|
+
ref: (node) => {
|
|
1640
|
+
trackRef.current = node;
|
|
1641
|
+
moveRef(node);
|
|
1642
|
+
},
|
|
1643
|
+
role: "button",
|
|
1644
|
+
"aria-label": ariaLabel ?? "Slider track",
|
|
1645
|
+
"data-slot": "slider",
|
|
1646
|
+
"data-orientation": orientation,
|
|
1647
|
+
"data-disabled": disabled ? "" : void 0,
|
|
1648
|
+
"aria-disabled": disabled,
|
|
1649
|
+
"aria-valuenow": value,
|
|
1650
|
+
"aria-valuemin": min,
|
|
1651
|
+
"aria-valuemax": max,
|
|
1652
|
+
className: rootClassName,
|
|
1653
|
+
onClick: handleTrackClick,
|
|
1654
|
+
onKeyDown: handleTrackKeyDown,
|
|
1655
|
+
tabIndex: disabled ? -1 : 0,
|
|
1656
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1657
|
+
className: trackClassName,
|
|
1658
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1659
|
+
"data-slot": "slider-range",
|
|
1660
|
+
className: SLIDER_RANGE_CLASSNAME,
|
|
1661
|
+
style: { width: `${valuePercent}%` }
|
|
1662
|
+
}), marksElement]
|
|
1663
|
+
}), /* @__PURE__ */ jsx(motion.button, {
|
|
1664
|
+
ref: thumbRef,
|
|
1665
|
+
type: "button",
|
|
1666
|
+
role: "slider",
|
|
1667
|
+
"aria-label": ariaLabel,
|
|
1668
|
+
"aria-labelledby": ariaLabelledBy,
|
|
1669
|
+
"aria-valuemin": min,
|
|
1670
|
+
"aria-valuemax": max,
|
|
1671
|
+
"aria-valuenow": value,
|
|
1672
|
+
"aria-valuetext": ariaValueText,
|
|
1673
|
+
"aria-orientation": orientation,
|
|
1674
|
+
"aria-disabled": disabled,
|
|
1675
|
+
"data-slot": "slider-thumb",
|
|
1676
|
+
"data-state": active ? "dragging" : "idle",
|
|
1677
|
+
"data-dragging": active ? "" : void 0,
|
|
1678
|
+
"data-disabled": disabled ? "" : void 0,
|
|
1679
|
+
tabIndex: disabled ? -1 : 0,
|
|
1680
|
+
disabled,
|
|
1681
|
+
className: thumbClassName,
|
|
1682
|
+
style: {
|
|
1683
|
+
left: `calc(${valuePercent}% - ${thumbSize / 2}px)`,
|
|
1684
|
+
top: "50%",
|
|
1685
|
+
y: "-50%"
|
|
1686
|
+
},
|
|
1687
|
+
whileTap: disabled || shouldReduceMotion ? void 0 : { scale: 1.15 },
|
|
1688
|
+
transition: springConfig,
|
|
1689
|
+
onKeyDown: handleKeyDown
|
|
1690
|
+
})]
|
|
1691
|
+
}),
|
|
1692
|
+
name ? /* @__PURE__ */ jsx("input", {
|
|
1693
|
+
type: "hidden",
|
|
1694
|
+
name,
|
|
1695
|
+
value,
|
|
1696
|
+
disabled
|
|
1697
|
+
}) : null,
|
|
1698
|
+
hint ? /* @__PURE__ */ jsx("div", {
|
|
1699
|
+
className: SLIDER_HINT_CLASSNAME,
|
|
1700
|
+
children: hint
|
|
1701
|
+
}) : null
|
|
1702
|
+
]
|
|
1703
|
+
});
|
|
1704
|
+
}));
|
|
1705
|
+
|
|
1706
|
+
//#endregion
|
|
1707
|
+
//#region src/components/elements/molecules/tab-select/tab-select.tsx
|
|
1708
|
+
/**
|
|
1709
|
+
* @fileoverview TabSelect Component (Premium Harmony V2)
|
|
1710
|
+
*
|
|
1711
|
+
* Underline-style tabs with animated indicator.
|
|
1712
|
+
* Provides navigation tabs with smooth motion transitions.
|
|
1713
|
+
*
|
|
1714
|
+
* @module @od-oneapp/uni-ui/components/tab-select
|
|
1715
|
+
*
|
|
1716
|
+
* @component TabSelect
|
|
1717
|
+
*
|
|
1718
|
+
* Features:
|
|
1719
|
+
* - ES2023 syntax with modern patterns
|
|
1720
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
1721
|
+
* - Super light/dark mode with seamless switching
|
|
1722
|
+
* - Premium Harmony V2 spring physics (SPRING_TACTILE for tab switching)
|
|
1723
|
+
* - Touch detection: useMediaQuery('(pointer: coarse)') from @mantine/hooks
|
|
1724
|
+
* - Reduced motion support: useReducedMotion() from @mantine/hooks
|
|
1725
|
+
* - Motion library: motion from 'motion/react' for indicator animation
|
|
1726
|
+
* - 44px minimum touch targets (WCAG 2.5.5)
|
|
1727
|
+
* - Data attributes: data-state (active/inactive) for CSS hooks
|
|
1728
|
+
* - Focus-visible ring styles
|
|
1729
|
+
* - Semantic color tokens for theming
|
|
1730
|
+
* - CVA variants for button and indicator styling
|
|
1731
|
+
* - Generic type support for tab IDs
|
|
1732
|
+
* - External link support with target="_blank"
|
|
1733
|
+
* - Custom LinkComponent for framework integration
|
|
1734
|
+
* - LayoutGroup for smooth tab transitions
|
|
1735
|
+
*
|
|
1736
|
+
* @variants
|
|
1737
|
+
* - variant: default, accent (button and indicator)
|
|
1738
|
+
*
|
|
1739
|
+
* @useCases
|
|
1740
|
+
* - **Navigation tabs**: Primary navigation within a page or section
|
|
1741
|
+
* - **Content switching**: Toggle between different views (Overview, Analytics, Settings)
|
|
1742
|
+
* - **Settings panels**: Organize settings into categorized tabs
|
|
1743
|
+
* - **Dashboard sections**: Switch between different data visualizations
|
|
1744
|
+
* - **Form sections**: Multi-step forms with tab-based navigation
|
|
1745
|
+
* - **External links**: Tab items that link to external resources (with target="_blank")
|
|
1746
|
+
* - **Framework integration**: Use with Next.js Link or other routing libraries
|
|
1747
|
+
*
|
|
1748
|
+
* @example <TabSelect variant="accent" options={[{ id: 'overview', label: 'Overview' }, { id: 'analytics', label: 'Analytics' }]} selected={activeTab} onSelect={setActiveTab} />
|
|
1749
|
+
* @example <TabSelect options={[{ id: 'dashboard', label: 'Dashboard' }, { id: 'docs', label: 'Docs', href: 'https://docs.example.com', target: '_blank' }]} selected="dashboard" />
|
|
1750
|
+
*/
|
|
1751
|
+
const DEFAULT_TAB_SELECT_LINK_COMPONENT = "a";
|
|
1752
|
+
const TAB_SELECT_INDICATOR_LAYOUT_ID = "indicator";
|
|
1753
|
+
const TAB_SELECT_CONTAINER_CLASSNAME = "flex text-sm";
|
|
1754
|
+
const TAB_SELECT_TAB_WRAPPER_CLASSNAME = "relative";
|
|
1755
|
+
const TAB_SELECT_INDICATOR_BAR_CLASSNAME = "h-0.5 rounded-t-full bg-current";
|
|
1756
|
+
const TAB_SELECT_EXTERNAL_LINK_CLASSNAME = "group flex items-center gap-1.5";
|
|
1757
|
+
const TAB_SELECT_EXTERNAL_LINK_ICON_CLASSNAME = "size-2.5";
|
|
1758
|
+
const TAB_SELECT_EXTERNAL_LINK_ICON_VIEWBOX = "0 0 24 24";
|
|
1759
|
+
const TAB_SELECT_EXTERNAL_LINK_ICON_STROKE_WIDTH = "2";
|
|
1760
|
+
const TAB_SELECT_EXTERNAL_LINK_ICON_STROKE_LINECAP = "round";
|
|
1761
|
+
const TAB_SELECT_EXTERNAL_LINK_ICON_STROKE_LINEJOIN = "round";
|
|
1762
|
+
const tabSelectButtonVariants = cva([
|
|
1763
|
+
"p-4 min-h-[44px]",
|
|
1764
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
1765
|
+
"transition-[color,transform] duration-150",
|
|
1766
|
+
"rounded-sm"
|
|
1767
|
+
], {
|
|
1768
|
+
variants: { variant: {
|
|
1769
|
+
default: "text-muted-foreground data-[state=active]:text-foreground data-[state=inactive]:hover:text-foreground/80",
|
|
1770
|
+
accent: "text-muted-foreground data-[state=active]:text-primary data-[state=inactive]:hover:text-foreground data-[state=active]:font-medium"
|
|
1771
|
+
} },
|
|
1772
|
+
defaultVariants: { variant: "default" }
|
|
1773
|
+
});
|
|
1774
|
+
const tabSelectIndicatorVariants = cva("absolute bottom-0 w-full px-1.5", {
|
|
1775
|
+
variants: { variant: {
|
|
1776
|
+
default: "text-foreground",
|
|
1777
|
+
accent: "text-primary"
|
|
1778
|
+
} },
|
|
1779
|
+
defaultVariants: { variant: "default" }
|
|
1780
|
+
});
|
|
1781
|
+
const TabSelect = memo(function TabSelect({ variant, options, selected, onSelect, className, LinkComponent = DEFAULT_TAB_SELECT_LINK_COMPONENT }) {
|
|
1782
|
+
const layoutGroupId = useId();
|
|
1783
|
+
useMediaQuery("(pointer: coarse)");
|
|
1784
|
+
const reducedMotion = useReducedMotion();
|
|
1785
|
+
const containerClassName = useMemo(() => cn(TAB_SELECT_CONTAINER_CLASSNAME, className), [className]);
|
|
1786
|
+
const handleClick = useCallback((id) => {
|
|
1787
|
+
if (onSelect != null) onSelect(id);
|
|
1788
|
+
}, [onSelect]);
|
|
1789
|
+
const externalLinkIcon = useMemo(() => /* @__PURE__ */ jsxs("svg", {
|
|
1790
|
+
className: TAB_SELECT_EXTERNAL_LINK_ICON_CLASSNAME,
|
|
1791
|
+
viewBox: TAB_SELECT_EXTERNAL_LINK_ICON_VIEWBOX,
|
|
1792
|
+
fill: "none",
|
|
1793
|
+
stroke: "currentColor",
|
|
1794
|
+
strokeWidth: TAB_SELECT_EXTERNAL_LINK_ICON_STROKE_WIDTH,
|
|
1795
|
+
strokeLinecap: TAB_SELECT_EXTERNAL_LINK_ICON_STROKE_LINECAP,
|
|
1796
|
+
strokeLinejoin: TAB_SELECT_EXTERNAL_LINK_ICON_STROKE_LINEJOIN,
|
|
1797
|
+
children: [/* @__PURE__ */ jsx("path", { d: "M7 7h10v10" }), /* @__PURE__ */ jsx("path", { d: "M7 17 17 7" })]
|
|
1798
|
+
}), []);
|
|
1799
|
+
const indicatorClassName = useMemo(() => tabSelectIndicatorVariants({ variant }), [variant]);
|
|
1800
|
+
const transitionConfig = useMemo(() => reducedMotion ? { duration: 0 } : SPRING_TACTILE, [reducedMotion]);
|
|
1801
|
+
const whileTapAnimation = useMemo(() => reducedMotion ? {} : { scale: .98 }, [reducedMotion]);
|
|
1802
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1803
|
+
className: containerClassName,
|
|
1804
|
+
children: /* @__PURE__ */ jsx(LayoutGroup, {
|
|
1805
|
+
id: layoutGroupId,
|
|
1806
|
+
children: options.map(({ id, label, href, target }) => {
|
|
1807
|
+
const isSelected = id === selected;
|
|
1808
|
+
const Component = href != null ? LinkComponent : "div";
|
|
1809
|
+
const buttonClassName = cn(tabSelectButtonVariants({ variant }), target === "_blank" && TAB_SELECT_EXTERNAL_LINK_CLASSNAME);
|
|
1810
|
+
return /* @__PURE__ */ jsxs(Component, {
|
|
1811
|
+
className: TAB_SELECT_TAB_WRAPPER_CLASSNAME,
|
|
1812
|
+
...href != null && { href },
|
|
1813
|
+
...target != null && { target },
|
|
1814
|
+
children: [/* @__PURE__ */ jsxs(motion.button, {
|
|
1815
|
+
type: "button",
|
|
1816
|
+
...onSelect != null && href == null && { onClick: () => handleClick(id) },
|
|
1817
|
+
className: buttonClassName,
|
|
1818
|
+
"data-state": isSelected ? "active" : "inactive",
|
|
1819
|
+
"aria-pressed": isSelected,
|
|
1820
|
+
whileTap: whileTapAnimation,
|
|
1821
|
+
transition: transitionConfig,
|
|
1822
|
+
children: [label, target === "_blank" && externalLinkIcon]
|
|
1823
|
+
}), isSelected ? /* @__PURE__ */ jsx(motion.div, {
|
|
1824
|
+
layoutId: TAB_SELECT_INDICATOR_LAYOUT_ID,
|
|
1825
|
+
transition: transitionConfig,
|
|
1826
|
+
className: indicatorClassName,
|
|
1827
|
+
children: /* @__PURE__ */ jsx("div", { className: TAB_SELECT_INDICATOR_BAR_CLASSNAME })
|
|
1828
|
+
}) : null]
|
|
1829
|
+
}, id);
|
|
1830
|
+
})
|
|
1831
|
+
})
|
|
1832
|
+
});
|
|
1833
|
+
});
|
|
1834
|
+
|
|
1835
|
+
//#endregion
|
|
1836
|
+
//#region src/components/elements/atoms/timestamp-tooltip/timestamp-tooltip.tsx
|
|
1837
|
+
const logger = new Logger("uni-ui:timestamp-tooltip");
|
|
1838
|
+
const DAY_MS = 1440 * 60 * 1e3;
|
|
1839
|
+
const MONTH_MS = 30 * DAY_MS;
|
|
1840
|
+
const TIMESTAMP_UPDATE_INTERVAL_MS = 1e3;
|
|
1841
|
+
const DEFAULT_TIMESTAMP_ROWS = ["local", "utc"];
|
|
1842
|
+
const DEFAULT_TIMESTAMP_INTERACTIVE = true;
|
|
1843
|
+
const KEYBOARD_ENTER_KEY = "Enter";
|
|
1844
|
+
const KEYBOARD_SPACE_KEY = " ";
|
|
1845
|
+
const KEYBOARD_SPACEBAR_KEY = "Spacebar";
|
|
1846
|
+
const TIMESTAMP_TOOLTIP_CONTAINER_CLASSNAME = "flex max-w-[360px] flex-col gap-2 px-2.5 py-2 text-left text-xs";
|
|
1847
|
+
const TIMESTAMP_TOOLTIP_RELATIVE_TIME_CLASSNAME = "text-muted-foreground cursor-default";
|
|
1848
|
+
const TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_BASE_CLASSNAME = "before:bg-muted relative cursor-copy select-none before:absolute before:-inset-x-1 before:inset-y-0 before:rounded before:opacity-0 before:content-[\"\"] hover:before:opacity-60 active:before:opacity-100";
|
|
1849
|
+
const TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_FOCUS_CLASSNAME = "focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none focus-visible:before:opacity-60";
|
|
1850
|
+
const TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_TRANSITION_CLASSNAME = "before:transition-opacity before:duration-200";
|
|
1851
|
+
const TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_TRANSITION_REDUCED_CLASSNAME = "before:transition-none";
|
|
1852
|
+
const TIMESTAMP_TOOLTIP_ROW_TOUCH_TARGET_CLASSNAME = "min-h-11";
|
|
1853
|
+
const TIMESTAMP_TOOLTIP_LABEL_CELL_CLASSNAME = "relative py-0.5";
|
|
1854
|
+
const TIMESTAMP_TOOLTIP_LABEL_CELL_TOUCH_CLASSNAME = "py-2.5";
|
|
1855
|
+
const TIMESTAMP_TOOLTIP_LABEL_BASE_CLASSNAME = "text-muted-foreground truncate";
|
|
1856
|
+
const TIMESTAMP_TOOLTIP_LABEL_SHORT_CLASSNAME = "bg-foreground/10 rounded px-1 font-mono";
|
|
1857
|
+
const TIMESTAMP_TOOLTIP_VALUE_CELL_BASE_CLASSNAME = "text-foreground relative py-0.5 pl-3 whitespace-nowrap";
|
|
1858
|
+
const TIMESTAMP_TOOLTIP_VALUE_CELL_TOUCH_CLASSNAME = "py-2.5";
|
|
1859
|
+
const TIMESTAMP_TOOLTIP_VALUE_CELL_SHORT_CLASSNAME = "pl-2";
|
|
1860
|
+
const TIMESTAMP_TOOLTIP_VALUE_MONO_CLASSNAME = "font-mono";
|
|
1861
|
+
const TIMESTAMP_LOCALE = "en-US";
|
|
1862
|
+
const TIMESTAMP_TIMEZONE_UTC = "UTC";
|
|
1863
|
+
const TIMESTAMP_UNIX_DIVISOR = 1e3;
|
|
1864
|
+
const TIMESTAMP_FORMAT_DELIMITER = ", ";
|
|
1865
|
+
const TIMESTAMP_RELATIVE_SUFFIX = " ago";
|
|
1866
|
+
const TIMESTAMP_INVALID_DATE_STRING = "Invalid Date";
|
|
1867
|
+
const TIMESTAMP_LOCAL_FALLBACK = "Local";
|
|
1868
|
+
const TIMESTAMP_SUCCESS_LABEL_LOCAL = "local timestamp";
|
|
1869
|
+
const TIMESTAMP_SUCCESS_LABEL_UTC = "UTC timestamp";
|
|
1870
|
+
const TIMESTAMP_SUCCESS_LABEL_UNIX = "UNIX timestamp";
|
|
1871
|
+
const TIMESTAMP_LABEL_UNIX = "UNIX Timestamp";
|
|
1872
|
+
const TIMESTAMP_ROW_INTERACTIVE_ROLE = "button";
|
|
1873
|
+
const TIMESTAMP_ROW_INTERACTIVE_TAB_INDEX = 0;
|
|
1874
|
+
function getLocalTimeZone() {
|
|
1875
|
+
if (typeof Intl !== "undefined") try {
|
|
1876
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone ?? TIMESTAMP_LOCAL_FALLBACK;
|
|
1877
|
+
} catch {}
|
|
1878
|
+
return TIMESTAMP_LOCAL_FALLBACK;
|
|
1879
|
+
}
|
|
1880
|
+
const TimestampTooltip = memo(function TimestampTooltip({ timestamp, rows, interactive = DEFAULT_TIMESTAMP_INTERACTIVE, children, ...tooltipProps }) {
|
|
1881
|
+
if (timestamp == null || new Date(timestamp).toString() === TIMESTAMP_INVALID_DATE_STRING) return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
1882
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
1883
|
+
asChild: true,
|
|
1884
|
+
children
|
|
1885
|
+
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
1886
|
+
...tooltipProps,
|
|
1887
|
+
children: /* @__PURE__ */ jsx(TimestampTooltipContent, {
|
|
1888
|
+
timestamp,
|
|
1889
|
+
rows,
|
|
1890
|
+
interactive
|
|
1891
|
+
})
|
|
1892
|
+
})] }) });
|
|
1893
|
+
});
|
|
1894
|
+
async function copyToClipboard(value, label) {
|
|
1895
|
+
try {
|
|
1896
|
+
await navigator.clipboard.writeText(value);
|
|
1897
|
+
toast.success(`Copied ${label} to clipboard`);
|
|
1898
|
+
} catch (e) {
|
|
1899
|
+
toast.error(`Failed to copy ${label} to clipboard`);
|
|
1900
|
+
logger.error(`Failed to copy ${label} to clipboard`, {
|
|
1901
|
+
error: e,
|
|
1902
|
+
label
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
/**
|
|
1907
|
+
* Render tooltip content that displays one or more formatted representations of a timestamp and an optional relative time line.
|
|
1908
|
+
*
|
|
1909
|
+
* Displays rows for the provided formats (local, UTC, UNIX) and, when `interactive` is true, enables keyboard- and mouse-driven copy-to-clipboard interactions for each row.
|
|
1910
|
+
*
|
|
1911
|
+
* @param timestamp - A date value; can be a `Date`, ISO string, or epoch number. Used as the source time for all displayed formats.
|
|
1912
|
+
* @param rows - The list and order of formats to render. Supported values: `'local'`, `'utc'`, `'unix'`. Defaults to `['local', 'utc']`.
|
|
1913
|
+
* @param interactive - When `true`, each row is focusable and can be copied with click, Enter, or Space. When omitted or `false`, rows are static.
|
|
1914
|
+
* @returns A JSX element containing an optional relative-time line and a table of formatted timestamp rows (local, UTC, and/or UNIX).
|
|
1915
|
+
*/
|
|
1916
|
+
const TimestampTooltipContent = memo(function TimestampTooltipContent({ timestamp, rows = DEFAULT_TIMESTAMP_ROWS, interactive }) {
|
|
1917
|
+
const date = useMemo(() => new Date(timestamp), [timestamp]);
|
|
1918
|
+
const isTouchDevice = useMediaQuery("(pointer: coarse)");
|
|
1919
|
+
const reducedMotion = useReducedMotion();
|
|
1920
|
+
const [now, setNow] = useState(() => Date.now());
|
|
1921
|
+
const interval = useInterval(useCallback(() => {
|
|
1922
|
+
setNow(Date.now());
|
|
1923
|
+
}, []), TIMESTAMP_UPDATE_INTERVAL_MS);
|
|
1924
|
+
useEffect(() => {
|
|
1925
|
+
interval.start();
|
|
1926
|
+
return interval.stop;
|
|
1927
|
+
}, [interval]);
|
|
1928
|
+
const commonFormat = useMemo(() => ({
|
|
1929
|
+
year: "numeric",
|
|
1930
|
+
month: "short",
|
|
1931
|
+
day: "numeric",
|
|
1932
|
+
hour: "numeric",
|
|
1933
|
+
minute: "numeric",
|
|
1934
|
+
second: "numeric",
|
|
1935
|
+
hour12: true
|
|
1936
|
+
}), []);
|
|
1937
|
+
const diff = now - date.getTime();
|
|
1938
|
+
const relative = useMemo(() => {
|
|
1939
|
+
return `${formatDuration(intervalToDuration({
|
|
1940
|
+
start: date,
|
|
1941
|
+
end: now
|
|
1942
|
+
}), {
|
|
1943
|
+
delimiter: TIMESTAMP_FORMAT_DELIMITER,
|
|
1944
|
+
format: [
|
|
1945
|
+
"years",
|
|
1946
|
+
"months",
|
|
1947
|
+
"days",
|
|
1948
|
+
...diff < MONTH_MS ? ["hours", ...diff < DAY_MS ? ["minutes", "seconds"] : []] : []
|
|
1949
|
+
]
|
|
1950
|
+
})}${TIMESTAMP_RELATIVE_SUFFIX}`;
|
|
1951
|
+
}, [
|
|
1952
|
+
date,
|
|
1953
|
+
now,
|
|
1954
|
+
diff
|
|
1955
|
+
]);
|
|
1956
|
+
const items = useMemo(() => rows.map((key) => {
|
|
1957
|
+
return {
|
|
1958
|
+
local: {
|
|
1959
|
+
label: getLocalTimeZone(),
|
|
1960
|
+
shortLabel: Intl.DateTimeFormat(TIMESTAMP_LOCALE, { timeZoneName: "short" }).formatToParts(date).find((p) => p.type === "timeZoneName")?.value ?? "",
|
|
1961
|
+
successMessageLabel: TIMESTAMP_SUCCESS_LABEL_LOCAL,
|
|
1962
|
+
value: date.toLocaleString(TIMESTAMP_LOCALE, commonFormat)
|
|
1963
|
+
},
|
|
1964
|
+
utc: {
|
|
1965
|
+
label: TIMESTAMP_TIMEZONE_UTC,
|
|
1966
|
+
shortLabel: TIMESTAMP_TIMEZONE_UTC,
|
|
1967
|
+
successMessageLabel: TIMESTAMP_SUCCESS_LABEL_UTC,
|
|
1968
|
+
value: date.toLocaleString(TIMESTAMP_LOCALE, {
|
|
1969
|
+
...commonFormat,
|
|
1970
|
+
timeZone: TIMESTAMP_TIMEZONE_UTC
|
|
1971
|
+
})
|
|
1972
|
+
},
|
|
1973
|
+
unix: {
|
|
1974
|
+
label: TIMESTAMP_LABEL_UNIX,
|
|
1975
|
+
successMessageLabel: TIMESTAMP_SUCCESS_LABEL_UNIX,
|
|
1976
|
+
value: (date.getTime() / TIMESTAMP_UNIX_DIVISOR).toString(),
|
|
1977
|
+
valueMono: true
|
|
1978
|
+
}
|
|
1979
|
+
}[key];
|
|
1980
|
+
}), [
|
|
1981
|
+
rows,
|
|
1982
|
+
date,
|
|
1983
|
+
commonFormat
|
|
1984
|
+
]);
|
|
1985
|
+
const shortLabels = items.every(({ shortLabel }) => shortLabel != null);
|
|
1986
|
+
const handleCopy = useCallback((row) => {
|
|
1987
|
+
copyToClipboard(row.value, row.successMessageLabel);
|
|
1988
|
+
}, []);
|
|
1989
|
+
const handleKeyDown = useCallback((e, row) => {
|
|
1990
|
+
if (e.key === KEYBOARD_ENTER_KEY || e.key === KEYBOARD_SPACE_KEY || e.key === KEYBOARD_SPACEBAR_KEY) {
|
|
1991
|
+
e.preventDefault();
|
|
1992
|
+
e.stopPropagation();
|
|
1993
|
+
handleCopy(row);
|
|
1994
|
+
}
|
|
1995
|
+
}, [handleCopy]);
|
|
1996
|
+
const rowClassName = useMemo(() => cn(interactive === true && TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_BASE_CLASSNAME, interactive === true && TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_FOCUS_CLASSNAME, interactive === true && (reducedMotion === true ? TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_TRANSITION_REDUCED_CLASSNAME : TIMESTAMP_TOOLTIP_ROW_INTERACTIVE_TRANSITION_CLASSNAME), interactive === true && isTouchDevice === true && TIMESTAMP_TOOLTIP_ROW_TOUCH_TARGET_CLASSNAME), [
|
|
1997
|
+
interactive,
|
|
1998
|
+
reducedMotion,
|
|
1999
|
+
isTouchDevice
|
|
2000
|
+
]);
|
|
2001
|
+
const labelCellClassName = useMemo(() => cn(TIMESTAMP_TOOLTIP_LABEL_CELL_CLASSNAME, isTouchDevice === true && TIMESTAMP_TOOLTIP_LABEL_CELL_TOUCH_CLASSNAME), [isTouchDevice]);
|
|
2002
|
+
const labelClassName = useMemo(() => cn(TIMESTAMP_TOOLTIP_LABEL_BASE_CLASSNAME, shortLabels && TIMESTAMP_TOOLTIP_LABEL_SHORT_CLASSNAME), [shortLabels]);
|
|
2003
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2004
|
+
className: TIMESTAMP_TOOLTIP_CONTAINER_CLASSNAME,
|
|
2005
|
+
"data-component": "timestamp-tooltip",
|
|
2006
|
+
children: [diff > 0 ? /* @__PURE__ */ jsx("span", {
|
|
2007
|
+
className: TIMESTAMP_TOOLTIP_RELATIVE_TIME_CLASSNAME,
|
|
2008
|
+
"data-relative-time": true,
|
|
2009
|
+
children: relative
|
|
2010
|
+
}) : null, /* @__PURE__ */ jsx("table", {
|
|
2011
|
+
"data-timestamps": true,
|
|
2012
|
+
children: /* @__PURE__ */ jsx("tbody", { children: items.map((row) => {
|
|
2013
|
+
const valueCellClassName = cn(TIMESTAMP_TOOLTIP_VALUE_CELL_BASE_CLASSNAME, isTouchDevice === true && TIMESTAMP_TOOLTIP_VALUE_CELL_TOUCH_CLASSNAME, shortLabels && TIMESTAMP_TOOLTIP_VALUE_CELL_SHORT_CLASSNAME, row.valueMono === true && TIMESTAMP_TOOLTIP_VALUE_MONO_CLASSNAME);
|
|
2014
|
+
const formatType = row.label === TIMESTAMP_LABEL_UNIX ? "unix" : row.label === TIMESTAMP_TIMEZONE_UTC ? "utc" : "local";
|
|
2015
|
+
return /* @__PURE__ */ jsxs("tr", {
|
|
2016
|
+
className: rowClassName,
|
|
2017
|
+
onClick: interactive === true ? () => handleCopy(row) : void 0,
|
|
2018
|
+
onKeyDown: interactive === true ? (e) => handleKeyDown(e, row) : void 0,
|
|
2019
|
+
role: interactive === true ? TIMESTAMP_ROW_INTERACTIVE_ROLE : void 0,
|
|
2020
|
+
tabIndex: interactive === true ? TIMESTAMP_ROW_INTERACTIVE_TAB_INDEX : void 0,
|
|
2021
|
+
"data-timestamp-row": true,
|
|
2022
|
+
"data-format": formatType,
|
|
2023
|
+
"data-interactive": interactive === true ? "true" : "false",
|
|
2024
|
+
"data-touch": isTouchDevice === true ? "true" : "false",
|
|
2025
|
+
children: [/* @__PURE__ */ jsx("td", {
|
|
2026
|
+
className: labelCellClassName,
|
|
2027
|
+
"data-label": true,
|
|
2028
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
2029
|
+
className: labelClassName,
|
|
2030
|
+
title: shortLabels ? row.label : void 0,
|
|
2031
|
+
children: shortLabels ? row.shortLabel : row.label
|
|
2032
|
+
})
|
|
2033
|
+
}), /* @__PURE__ */ jsx("td", {
|
|
2034
|
+
className: valueCellClassName,
|
|
2035
|
+
"data-value": true,
|
|
2036
|
+
children: row.value
|
|
2037
|
+
})]
|
|
2038
|
+
}, row.label);
|
|
2039
|
+
}) })
|
|
2040
|
+
})]
|
|
2041
|
+
});
|
|
2042
|
+
});
|
|
2043
|
+
|
|
2044
|
+
//#endregion
|
|
2045
|
+
//#region src/components/elements/molecules/toggle-group/toggle-group.tsx
|
|
2046
|
+
/**
|
|
2047
|
+
* @fileoverview ToggleGroup Component - Premium Harmony V2
|
|
2048
|
+
*
|
|
2049
|
+
* A segmented control with animated indicator for selecting between options.
|
|
2050
|
+
* Uses spring physics for smooth, tactile interactions with accessibility support.
|
|
2051
|
+
*
|
|
2052
|
+
* Features:
|
|
2053
|
+
* - Premium Harmony V2 spring physics (SPRING_TACTILE)
|
|
2054
|
+
* - Touch-optimized with 44px minimum tap targets (WCAG 2.5.5)
|
|
2055
|
+
* - Reduced motion support (prefers-reduced-motion)
|
|
2056
|
+
* - Tailwind v4 CSS-first theming with CSS variables
|
|
2057
|
+
* - Animated sliding indicator with motion/react
|
|
2058
|
+
* - Super light/dark mode with seamless switching
|
|
2059
|
+
* - Complete pseudo-state coverage (:hover, :focus-visible)
|
|
2060
|
+
* - Semantic data attributes (data-state: on/off)
|
|
2061
|
+
* - Link support with custom LinkComponent
|
|
2062
|
+
* - Badge support for options
|
|
2063
|
+
*
|
|
2064
|
+
* @module @od-oneapp/uni-ui/components/elements/toggle-group
|
|
2065
|
+
* @component ToggleGroup
|
|
2066
|
+
*
|
|
2067
|
+
* @useCases
|
|
2068
|
+
* - Time period selectors (day/week/month)
|
|
2069
|
+
* - View mode toggles (list/grid/kanban)
|
|
2070
|
+
* - Tab-like navigation with visual feedback
|
|
2071
|
+
* - Filter category selection
|
|
2072
|
+
* - Chart type switchers
|
|
2073
|
+
* - Report format selectors
|
|
2074
|
+
*
|
|
2075
|
+
* @example
|
|
2076
|
+
* <ToggleGroup
|
|
2077
|
+
* options={[
|
|
2078
|
+
* { value: 'day', label: 'Day' },
|
|
2079
|
+
* { value: 'week', label: 'Week' },
|
|
2080
|
+
* { value: 'month', label: 'Month' },
|
|
2081
|
+
* ]}
|
|
2082
|
+
* selected={period}
|
|
2083
|
+
* selectAction={setPeriod}
|
|
2084
|
+
* />
|
|
2085
|
+
*/
|
|
2086
|
+
const DEFAULT_TOGGLE_GROUP_LAYOUT = true;
|
|
2087
|
+
const DEFAULT_TOGGLE_GROUP_LINK_COMPONENT = "a";
|
|
2088
|
+
const TOGGLE_GROUP_CONTAINER_BASE_CLASSNAME = "border-border bg-background relative z-0 inline-flex items-center gap-1 rounded-xl border p-1";
|
|
2089
|
+
const TOGGLE_GROUP_OPTION_BASE_CLASSNAME = "relative z-10 flex items-center gap-2 px-3 py-2 min-h-[44px] text-sm font-medium capitalize text-foreground rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 transition-[color,transform] duration-150";
|
|
2090
|
+
const TOGGLE_GROUP_OPTION_UNSELECTED_CLASSNAME = "z-[11] text-muted-foreground hover:text-foreground";
|
|
2091
|
+
const TOGGLE_GROUP_INDICATOR_BASE_CLASSNAME = "border-border bg-muted absolute top-0 left-0 -z-[1] h-full w-full rounded-lg border";
|
|
2092
|
+
/**
|
|
2093
|
+
* A segmented control with animated indicator for selecting between options.
|
|
2094
|
+
*
|
|
2095
|
+
* @example
|
|
2096
|
+
* <ToggleGroup
|
|
2097
|
+
* options={[
|
|
2098
|
+
* { value: 'day', label: 'Day' },
|
|
2099
|
+
* { value: 'week', label: 'Week' },
|
|
2100
|
+
* { value: 'month', label: 'Month' },
|
|
2101
|
+
* ]}
|
|
2102
|
+
* selected={period}
|
|
2103
|
+
* selectAction={setPeriod}
|
|
2104
|
+
* />
|
|
2105
|
+
*/
|
|
2106
|
+
const ToggleGroup = memo(function ToggleGroup({ options, selected, selectAction, layout = DEFAULT_TOGGLE_GROUP_LAYOUT, className, optionClassName, indicatorClassName, style, LinkComponent = DEFAULT_TOGGLE_GROUP_LINK_COMPONENT }) {
|
|
2107
|
+
const layoutGroupId = useId();
|
|
2108
|
+
const isTouchDevice = useMediaQuery("(pointer: coarse)");
|
|
2109
|
+
const prefersReducedMotion = useReducedMotion();
|
|
2110
|
+
const containerClassName = useMemo(() => cn(TOGGLE_GROUP_CONTAINER_BASE_CLASSNAME, className), [className]);
|
|
2111
|
+
const handleSelect = useCallback((value) => {
|
|
2112
|
+
selectAction?.(value);
|
|
2113
|
+
}, [selectAction]);
|
|
2114
|
+
const transitionConfig = useMemo(() => prefersReducedMotion ? { duration: .15 } : SPRING_TACTILE, [prefersReducedMotion]);
|
|
2115
|
+
const tapScale = useMemo(() => isTouchDevice ? .95 : .98, [isTouchDevice]);
|
|
2116
|
+
const indicatorBaseClassName = useMemo(() => cn(TOGGLE_GROUP_INDICATOR_BASE_CLASSNAME, indicatorClassName), [indicatorClassName]);
|
|
2117
|
+
return /* @__PURE__ */ jsx(LayoutGroup, {
|
|
2118
|
+
id: layoutGroupId,
|
|
2119
|
+
children: /* @__PURE__ */ jsx(motion.div, {
|
|
2120
|
+
layout,
|
|
2121
|
+
className: containerClassName,
|
|
2122
|
+
style,
|
|
2123
|
+
children: options.map((option) => {
|
|
2124
|
+
const isSelected = option.value === selected;
|
|
2125
|
+
const commonClassName = cn(TOGGLE_GROUP_OPTION_BASE_CLASSNAME, !isSelected && TOGGLE_GROUP_OPTION_UNSELECTED_CLASSNAME, optionClassName);
|
|
2126
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2127
|
+
typeof option.label === "string" ? /* @__PURE__ */ jsx("p", { children: option.label }) : option.label,
|
|
2128
|
+
option.badge,
|
|
2129
|
+
isSelected ? /* @__PURE__ */ jsx(motion.div, {
|
|
2130
|
+
layoutId: layoutGroupId,
|
|
2131
|
+
className: indicatorBaseClassName,
|
|
2132
|
+
transition: transitionConfig
|
|
2133
|
+
}) : null
|
|
2134
|
+
] });
|
|
2135
|
+
if (option.href != null) return /* @__PURE__ */ jsx(LinkComponent, {
|
|
2136
|
+
href: option.href,
|
|
2137
|
+
"data-state": isSelected ? "on" : "off",
|
|
2138
|
+
className: commonClassName,
|
|
2139
|
+
onClick: () => handleSelect(option.value),
|
|
2140
|
+
children: content
|
|
2141
|
+
}, option.value);
|
|
2142
|
+
return /* @__PURE__ */ jsx(motion.button, {
|
|
2143
|
+
"data-state": isSelected ? "on" : "off",
|
|
2144
|
+
className: commonClassName,
|
|
2145
|
+
onClick: () => handleSelect(option.value),
|
|
2146
|
+
type: "button",
|
|
2147
|
+
whileTap: prefersReducedMotion ? void 0 : { scale: tapScale },
|
|
2148
|
+
transition: transitionConfig,
|
|
2149
|
+
children: content
|
|
2150
|
+
}, option.value);
|
|
2151
|
+
})
|
|
2152
|
+
})
|
|
2153
|
+
});
|
|
2154
|
+
});
|
|
2155
|
+
|
|
2156
|
+
//#endregion
|
|
2157
|
+
export { AI_ANIMATE, AI_BODY, AI_COLLAPSIBLE, AI_COLORS, AI_CONTAINER, AI_CONTAINER_RADIUS, AI_DISABLED, AI_DURATION, AI_FOCUS, AI_HEADER, AI_HOVER, AI_ICON, AI_ICON_STYLE, AI_INTERACTION, AI_NESTED_RADIUS, AI_PADDING, AI_RADIUS, AI_SPACING, AI_STACK, AI_STAGGER_DELAY, AI_STATUS, AI_STYLES, AI_TEXT, AI_TITLE, AI_TRANSITION, AI_WEIGHT, Accordion, AccordionContent, AccordionItem, AccordionTrigger, Action, Actions, AgentStep, Alert, AlertDescription, AlertTitle, AnimatedSizeContainer, AnimatedTabs, AnimatedTabsList, AnimatedTabsTrigger, AppShell, AppSidebar, AppSidebarLayout, Area, AreaChart, Areas, Artifact, ArtifactAction, ArtifactActions, ArtifactClose, ArtifactContent, ArtifactDescription, ArtifactHeader, ArtifactPanelHeader, ArtifactTitle, Avatar, AvatarFallback, AvatarImage, AvatarStack, Badge, Bar, BarChart, Bars, BlurImage, Branch, Branch as MessageBranch, BranchMessages, BranchMessages as MessageBranchContent, BranchNext, BranchNext as MessageBranchNext, BranchPage, BranchPage as MessageBranchPage, BranchPrevious, BranchPrevious as MessageBranchPrevious, BranchSelector, BranchSelector as MessageBranchSelector, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, Card, CardAction, CardContent, CardDescription, CardErrorFallback, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, CartesianGrid, ChainOfThought, ChainOfThoughtContent, ChainOfThoughtHeader, ChainOfThoughtImage, ChainOfThoughtSearchResult, ChainOfThoughtSearchResults, ChainOfThoughtStep, ChartContainer, ChartContext as ChartContextProvider, ChartTooltip, ChartTooltipContent, ChartTooltipContext as ChartTooltipContextProvider, ChartTooltipSync, ChartTooltipSyncContext, ChatInput, Checkbox, Checkpoint, CheckpointIcon, CheckpointTrigger, CodeBlock, CodeBlockCopyButton, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, Confirmation, ConfirmationAccepted, ConfirmationAction, ConfirmationActions, ConfirmationContent, ConfirmationRejected, ConfirmationRequest, ConfirmationTitle, Context, ContextCacheUsage, ContextContent, ContextContentBody, ContextContentFooter, ContextContentHeader, ContextInputUsage, ContextOutputUsage, ContextReasoningUsage, ContextTrigger, Conversation, ConversationContent, ConversationEmptyState, ConversationScrollButton, CopyButton, CopyText, DEFAULT_COMPONENT_MAP, DatePickerContext, DateRangePicker, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DynamicBreadcrumb, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, ErrorBoundary, ExpandablePanel, FileUpload, FilterList, FilterSelect, FunnelChart, GenerativeUIRenderer, GoBackButton, HoverCard, HoverCardContent, HoverCardTrigger, Image, InlineCitation, InlineCitationCard, InlineCitationCardBody, InlineCitationCardTrigger, InlineCitationCarousel, InlineCitationCarouselContent, InlineCitationCarouselHeader, InlineCitationCarouselIndex, InlineCitationCarouselItem, InlineCitationCarouselNext, InlineCitationCarouselPrev, InlineCitationQuote, InlineCitationSource, InlineCitationText, InlineSnippet, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, Loader, LoaderIcon, LoadingDots, Message, MessageAction, MessageActions, MessageAttachment, MessageAttachments, MessageContent, MessageResponse, MessageToolbar, MiniAreaChart, Modal, ModeToggle, ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger, NavAppSwitcher, NavMain, NavProjects, NavSecondary, NavUser, OpenIn, OpenInChatGPT, OpenInClaude, OpenInContent, OpenInCursor, OpenInGitHub, OpenInItem, OpenInLabel, OpenInScira, OpenInSeparator, OpenInT3, OpenInTrigger, OpenInv0, PaginationControls, Plan, PlanAction, PlanContent, PlanDescription, PlanFooter, PlanHeader, PlanStep, PlanSteps, PlanTitle, PlanTrigger, Popover, Progress, ProgressCircle, PromptInput, PromptInputActionAddAttachments, PromptInputActionMenu, PromptInputActionMenuContent, PromptInputActionMenuItem, PromptInputActionMenuTrigger, PromptInputAttachment, PromptInputAttachments, PromptInputBody, PromptInputButton, PromptInputCommand, PromptInputCommandEmpty, PromptInputCommandGroup, PromptInputCommandInput, PromptInputCommandItem, PromptInputCommandList, PromptInputCommandSeparator, PromptInputFooter, PromptInputHeader, PromptInputHoverCard, PromptInputHoverCardContent, PromptInputHoverCardTrigger, PromptInputProvider, PromptInputSelect, PromptInputSelectContent, PromptInputSelectItem, PromptInputSelectTrigger, PromptInputSelectValue, PromptInputSpeechButton, PromptInputSubmit, PromptInputTab, PromptInputTabBody, PromptInputTabItem, PromptInputTabLabel, PromptInputTabsList, PromptInputTextarea, PromptInputTools, Queue, QueueItem, QueueItemAction, QueueItemActions, QueueItemAttachment, QueueItemContent, QueueItemDescription, QueueItemFile, QueueItemImage, QueueItemIndicator, QueueList, QueueSection, QueueSectionContent, QueueSectionLabel, QueueSectionTrigger, RadioGroup, RadioGroupItem, Reasoning, ReasoningContent, ReasoningTrigger, ResizableHandle, ResizablePanel, ResizablePanelGroup, SPRING_FLUID, SPRING_GENTLE, SPRING_TACTILE, SPRING_WEIGHTED, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Shimmer, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarInsetHeaderPortalProvider, SidebarInsetHeaderRight, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarSlotsProvider, SidebarTrigger, Skeleton, SkeletonTransition, Slider, Source, Sources, SourcesContent, SourcesTrigger, SplitPanelLayout, StatusBadge, Suggestion, Suggestions, Switch, TabSelect, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Task, TaskContent, TaskItem, TaskItemFile, TaskTrigger, Textarea, ThemeProvider, TimeSeriesChart, TimestampTooltip, ToastContainer, Toaster, ToggleGroup, Tool, ToolApproval, ToolContent, ToolHeader, ToolInput, ToolOutput, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, WebPreview, WebPreviewBackButton, WebPreviewBody, WebPreviewConsole, WebPreviewDeviceToggle, WebPreviewExampleSelect, WebPreviewForwardButton, WebPreviewFullscreenToggle, WebPreviewNavigation, WebPreviewNavigationButton, WebPreviewUrl, Canvas as WorkflowCanvas, Connection as WorkflowConnection, Controls as WorkflowControls, Edge as WorkflowEdge, Node as WorkflowNode, NodeAction as WorkflowNodeAction, NodeContent as WorkflowNodeContent, NodeDescription as WorkflowNodeDescription, NodeFooter as WorkflowNodeFooter, NodeHeader as WorkflowNodeHeader, NodeTitle as WorkflowNodeTitle, Panel as WorkflowPanel, Toolbar as WorkflowToolbar, XAxis, YAxis, agentStepVariants, avatarStackVariants, avatarVariants, badgeVariants, breadcrumbListVariants, buttonGroupVariants, buttonVariants, cardVariants, chainOfThoughtStepVariants, cn, commandItemVariants, copyButtonVariants, currencyFormatter, dialogContentVariants, dropdownMenuItemVariants, getFactors, highlightCode, hoverCardContentVariants, inputVariants, labelVariants, nFormatter, openInIconVariants, progressVariants, queueItemIndicatorVariants, resizableHandleVariants, scrollBarVariants, selectItemVariants, selectLabelVariants, selectTriggerVariants, separatorVariants, sheetContentVariants, skeletonVariants, statusBadgeVariants, statusIconVariants, tabSelectButtonVariants, tabSelectIndicatorVariants, tableCellVariants, tableHeadVariants, tableRowVariants, tableVariants, tabsListVariants, tabsTriggerVariants, textareaVariants, tooltipContentVariants, useArtifactPanelState, useChartContext, useChartTooltipContext, useConfirm, useExpandablePanelState, useIsMobile, usePromptInputAttachments, usePromptInputController, usePromptInputDropzone, useProviderAttachments, useResponsive, useScrollProgress, useSidebar, useSidebarInsetHeaderPortalMountRef, useSidebarSlot, useSidebarSlots, useSidebarSlotsContent, useSidebarSlotsOptional, useToast, useTooltip, withErrorBoundary };
|
|
2158
|
+
//# sourceMappingURL=index.mjs.map
|