@signalflare-ai/ui 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +102 -5
- package/README.md +1 -1
- package/ai/component-registry.json +531 -79
- package/ai/component-registry.md +4067 -6
- package/ai/schemas.ts +6 -1
- package/dist/.build-complete +1 -1
- package/dist/ai/schemas.d.ts +76 -58
- package/dist/ai/schemas.d.ts.map +1 -1
- package/dist/{ai-actions-DSVeQn4e.js → ai-actions-CBfz5XEf.js} +4 -4
- package/dist/{ai-actions-DSVeQn4e.js.map → ai-actions-CBfz5XEf.js.map} +1 -1
- package/dist/{ai-agent-card-BXHwhWAU.js → ai-agent-card-CByAUe0q.js} +3 -3
- package/dist/ai-agent-card-CByAUe0q.js.map +1 -0
- package/dist/{ai-approval-aa0qvjFN.js → ai-approval-Ci8N70a7.js} +4 -3
- package/dist/{ai-approval-aa0qvjFN.js.map → ai-approval-Ci8N70a7.js.map} +1 -1
- package/dist/{ai-code-block-BgtIxtZZ.js → ai-code-block-P9TJHvaC.js} +37 -39
- package/dist/ai-code-block-P9TJHvaC.js.map +1 -0
- package/dist/ai-conversation-Qslfdi1t.js +228 -0
- package/dist/ai-conversation-Qslfdi1t.js.map +1 -0
- package/dist/{ai-info-banner-uFxHHwBA.js → ai-info-banner-B_9vtGK3.js} +8 -4
- package/dist/ai-info-banner-B_9vtGK3.js.map +1 -0
- package/dist/{ai-message-BjnFznXy.js → ai-message-Ci3gwM7G.js} +29 -10
- package/dist/ai-message-Ci3gwM7G.js.map +1 -0
- package/dist/{ai-mission-header-08__gULL.js → ai-mission-header-CaBc19-t.js} +2 -2
- package/dist/{ai-mission-header-08__gULL.js.map → ai-mission-header-CaBc19-t.js.map} +1 -1
- package/dist/{ai-part-group-DBtgTgAn.js → ai-part-group-Dx1Mr92B.js} +5 -4
- package/dist/ai-part-group-Dx1Mr92B.js.map +1 -0
- package/dist/{ai-prompt-input-CuluUzpf.js → ai-prompt-input-Bm4XoSj2.js} +44 -55
- package/dist/ai-prompt-input-Bm4XoSj2.js.map +1 -0
- package/dist/{ai-question-CHHoDJMg.js → ai-question-OyJovxGe.js} +4 -3
- package/dist/{ai-question-CHHoDJMg.js.map → ai-question-OyJovxGe.js.map} +1 -1
- package/dist/{ai-reasoning-CnL6ZSr5.js → ai-reasoning-BLfBXx3F.js} +9 -5
- package/dist/ai-reasoning-BLfBXx3F.js.map +1 -0
- package/dist/{ai-response-BEUg3xvd.js → ai-response-hbVCZJmo.js} +9 -4
- package/dist/ai-response-hbVCZJmo.js.map +1 -0
- package/dist/{ai-shimmer-By5_L05p.js → ai-shimmer-BamNMNK3.js} +2 -2
- package/dist/{ai-shimmer-By5_L05p.js.map → ai-shimmer-BamNMNK3.js.map} +1 -1
- package/dist/{ai-status-badge-BGYGWYF6.js → ai-status-badge-BZLczdkI.js} +2 -2
- package/dist/{ai-status-badge-BGYGWYF6.js.map → ai-status-badge-BZLczdkI.js.map} +1 -1
- package/dist/{ai-streaming-text-CMfoThV0.js → ai-streaming-text-DgYu64UH.js} +44 -16
- package/dist/ai-streaming-text-DgYu64UH.js.map +1 -0
- package/dist/{ai-subagent-DcPRqkAA.js → ai-subagent-p97AI1h9.js} +14 -6
- package/dist/ai-subagent-p97AI1h9.js.map +1 -0
- package/dist/{ai-suggestion-MgeCg5Ar.js → ai-suggestion-Bj6vF7CT.js} +3 -3
- package/dist/{ai-suggestion-MgeCg5Ar.js.map → ai-suggestion-Bj6vF7CT.js.map} +1 -1
- package/dist/{ai-task-list-Da9zIm00.js → ai-task-list-C_UQYpk9.js} +15 -6
- package/dist/ai-task-list-C_UQYpk9.js.map +1 -0
- package/dist/{ai-timeline-Cwu045IR.js → ai-timeline-CePL1LOU.js} +3 -3
- package/dist/ai-timeline-CePL1LOU.js.map +1 -0
- package/dist/{ai-tool-Cn1O4xjP.js → ai-tool-CfRcwmHT.js} +35 -16
- package/dist/ai-tool-CfRcwmHT.js.map +1 -0
- package/dist/{ai-usage-bar-DjS12DMp.js → ai-usage-bar-45pVRCGA.js} +2 -2
- package/dist/{ai-usage-bar-DjS12DMp.js.map → ai-usage-bar-45pVRCGA.js.map} +1 -1
- package/dist/{badge-D_eaA6wv.js → badge-Beb-6uut.js} +5 -5
- package/dist/{badge-D_eaA6wv.js.map → badge-Beb-6uut.js.map} +1 -1
- package/dist/{banner-B_6oBrsu.js → banner-CCEksxPg.js} +8 -3
- package/dist/banner-CCEksxPg.js.map +1 -0
- package/dist/{breadcrumbs-BlmeYfgq.js → breadcrumbs-HiTmgaZ4.js} +5 -5
- package/dist/{breadcrumbs-BlmeYfgq.js.map → breadcrumbs-HiTmgaZ4.js.map} +1 -1
- package/dist/{button-De0267YU.js → button-BHOgXJRU.js} +4 -4
- package/dist/{button-De0267YU.js.map → button-BHOgXJRU.js.map} +1 -1
- package/dist/catalog.js +1 -1
- package/dist/catalog.js.map +1 -1
- package/dist/{chart-BK3sVPnD.js → chart-B9FfZdKs.js} +7 -7
- package/dist/chart-B9FfZdKs.js.map +1 -0
- package/dist/{checkbox-DYhUmZNw.js → checkbox-Cy_OCyay.js} +3 -3
- package/dist/{checkbox-DYhUmZNw.js.map → checkbox-Cy_OCyay.js.map} +1 -1
- package/dist/{clipboard-text-ssybngLw.js → clipboard-text-CKSvNp9L.js} +6 -5
- package/dist/clipboard-text-CKSvNp9L.js.map +1 -0
- package/dist/{cn-YROP2_ox.js → cn-CmAOpn49.js} +2 -2
- package/dist/{cn-YROP2_ox.js.map → cn-CmAOpn49.js.map} +1 -1
- package/dist/{code-Cx-QSoOT.js → code-JsQz-0G_.js} +4 -4
- package/dist/{code-Cx-QSoOT.js.map → code-JsQz-0G_.js.map} +1 -1
- package/dist/{collapsible-DWsXeXmS.js → collapsible-1kOZ-89L.js} +2 -2
- package/dist/{collapsible-DWsXeXmS.js.map → collapsible-1kOZ-89L.js.map} +1 -1
- package/dist/{combobox-C0iW6a0r.js → combobox-CQwDmqgA.js} +4 -4
- package/dist/{combobox-C0iW6a0r.js.map → combobox-CQwDmqgA.js.map} +1 -1
- package/dist/command-line/cli.js +3 -3
- package/dist/{command-palette-DGzioeki.js → command-palette-Bkuv3e6o.js} +20 -5
- package/dist/command-palette-Bkuv3e6o.js.map +1 -0
- package/dist/components/ai-actions.js +1 -1
- package/dist/components/ai-agent-card.js +1 -1
- package/dist/components/ai-approval.js +1 -1
- package/dist/components/ai-code-block.js +1 -1
- package/dist/components/ai-conversation.js +2 -2
- package/dist/components/ai-info-banner.js +1 -1
- package/dist/components/ai-message.js +1 -1
- package/dist/components/ai-mission-header.js +1 -1
- package/dist/components/ai-part-group.js +1 -1
- package/dist/components/ai-prompt-input.js +1 -1
- package/dist/components/ai-question.js +1 -1
- package/dist/components/ai-reasoning.js +1 -1
- package/dist/components/ai-response.js +1 -1
- package/dist/components/ai-shimmer.js +1 -1
- package/dist/components/ai-status-badge.js +1 -1
- package/dist/components/ai-streaming-text.js +2 -2
- package/dist/components/ai-subagent.js +1 -1
- package/dist/components/ai-suggestion.js +1 -1
- package/dist/components/ai-task-list.js +1 -1
- package/dist/components/ai-timeline.js +1 -1
- package/dist/components/ai-tool.js +1 -1
- package/dist/components/ai-usage-bar.js +1 -1
- package/dist/components/badge.js +1 -1
- package/dist/components/banner.js +1 -1
- package/dist/components/breadcrumbs.js +1 -1
- package/dist/components/button.js +1 -1
- package/dist/components/chart.js +2 -2
- package/dist/components/checkbox.js +1 -1
- package/dist/components/clipboard-text.js +1 -1
- package/dist/components/code.js +1 -1
- package/dist/components/collapsible.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/command-palette.js +1 -1
- package/dist/components/data-grid.js +1 -1
- package/dist/components/date-picker.js +1 -1
- package/dist/components/date-range-picker.js +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/dropdown.js +1 -1
- package/dist/components/empty.js +1 -1
- package/dist/components/field.js +1 -1
- package/dist/components/filters.js +1 -1
- package/dist/components/flow.js +1 -1
- package/dist/components/grid.js +1 -1
- package/dist/components/input.js +2 -2
- package/dist/components/label.js +1 -1
- package/dist/components/layer-card.js +1 -1
- package/dist/components/link.js +3 -3
- package/dist/components/link.js.map +1 -1
- package/dist/components/loader.js +2 -2
- package/dist/components/menubar.js +1 -1
- package/dist/components/meter.js +1 -1
- package/dist/components/pagination.js +1 -1
- package/dist/components/popover.js +1 -1
- package/dist/components/radio.js +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/sensitive-input.js +1 -1
- package/dist/components/sidebar.js +1 -1
- package/dist/components/signalflare-ai-logo.js +1 -1
- package/dist/components/sparkline.js +1 -1
- package/dist/components/stat-card.js +1 -1
- package/dist/components/surface.js +1 -1
- package/dist/components/switch.js +1 -1
- package/dist/components/table.js +1 -1
- package/dist/components/tabs.js +1 -1
- package/dist/components/text-roll.js +1 -1
- package/dist/components/text.js +1 -1
- package/dist/components/theme-toggle.js +1 -1
- package/dist/components/toast.js +1 -1
- package/dist/components/tooltip.js +1 -1
- package/dist/components/use-agent-harness.js +1 -1
- package/dist/{data-grid-CG76N_hK.js → data-grid-DDSFMHud.js} +136 -53
- package/dist/data-grid-DDSFMHud.js.map +1 -0
- package/dist/{date-picker-Dqg9L4xu.js → date-picker-O34AqG3f.js} +2 -2
- package/dist/{date-picker-Dqg9L4xu.js.map → date-picker-O34AqG3f.js.map} +1 -1
- package/dist/{date-range-picker-D75LLINc.js → date-range-picker-YKYvum_r.js} +29 -39
- package/dist/{date-range-picker-D75LLINc.js.map → date-range-picker-YKYvum_r.js.map} +1 -1
- package/dist/{dialog-CyHEQXEY.js → dialog-DYqu4aDO.js} +3 -3
- package/dist/{dialog-CyHEQXEY.js.map → dialog-DYqu4aDO.js.map} +1 -1
- package/dist/{dist-1-gcEL2L.js → dist-6AtBsaJE.js} +153 -47
- package/dist/dist-6AtBsaJE.js.map +1 -0
- package/dist/{dropdown-qnEYRFXZ.js → dropdown-XzbnRLYR.js} +15 -5
- package/dist/dropdown-XzbnRLYR.js.map +1 -0
- package/dist/{echart-DURZEyai.js → echart-DGBIVAv1.js} +23 -57
- package/dist/{echart-DURZEyai.js.map → echart-DGBIVAv1.js.map} +1 -1
- package/dist/{empty-D2TypIId.js → empty-C1tAkawe.js} +12 -7
- package/dist/empty-C1tAkawe.js.map +1 -0
- package/dist/{field-Y_UK1_Cg.js → field-DBpFzzBS.js} +3 -3
- package/dist/{field-Y_UK1_Cg.js.map → field-DBpFzzBS.js.map} +1 -1
- package/dist/{filters-Bw_U6ZTx.js → filters-SmEl93za.js} +10 -10
- package/dist/filters-SmEl93za.js.map +1 -0
- package/dist/{flow-BRsYUCJa.js → flow-BLzgbq1T.js} +6 -6
- package/dist/flow-BLzgbq1T.js.map +1 -0
- package/dist/genui.js +2 -2
- package/dist/genui.js.map +1 -1
- package/dist/{grid-qUAN9hFx.js → grid-CifjQL-5.js} +2 -2
- package/dist/{grid-qUAN9hFx.js.map → grid-CifjQL-5.js.map} +1 -1
- package/dist/{highlight-to-react-ClEfL81q.js → highlight-to-react-DN9dUCS2.js} +9 -15
- package/dist/highlight-to-react-DN9dUCS2.js.map +1 -0
- package/dist/index.js +72 -72
- package/dist/index.js.map +1 -1
- package/dist/{input-DddtBN-g.js → input-COmx2M_R.js} +5 -5
- package/dist/{input-DddtBN-g.js.map → input-COmx2M_R.js.map} +1 -1
- package/dist/{input-DXYUjGgD.js → input-GkfMQZC_.js} +3 -3
- package/dist/{input-DXYUjGgD.js.map → input-GkfMQZC_.js.map} +1 -1
- package/dist/{label-QtJxtJ4u.js → label-CiGZ464N.js} +3 -3
- package/dist/{label-QtJxtJ4u.js.map → label-CiGZ464N.js.map} +1 -1
- package/dist/{layer-card-BME0eljh.js → layer-card-8l8GuLQr.js} +2 -2
- package/dist/{layer-card-BME0eljh.js.map → layer-card-8l8GuLQr.js.map} +1 -1
- package/dist/layout-CWBE0qwx.js +6207 -0
- package/dist/layout-CWBE0qwx.js.map +1 -0
- package/dist/{link-provider-BUZKXaNE.js → link-provider-BSn8YJon.js} +2 -2
- package/dist/link-provider-BSn8YJon.js.map +1 -0
- package/dist/{loader-DAcc-Uag.js → loader-BEMz8pJO.js} +1 -1
- package/dist/{loader-DAcc-Uag.js.map → loader-BEMz8pJO.js.map} +1 -1
- package/dist/measured-text-CXkdw9Yr.js +305 -0
- package/dist/measured-text-CXkdw9Yr.js.map +1 -0
- package/dist/{menubar-C8NzAjfd.js → menubar-CoOr4ocj.js} +3 -3
- package/dist/{menubar-C8NzAjfd.js.map → menubar-CoOr4ocj.js.map} +1 -1
- package/dist/{meter-CpmTenEr.js → meter-Pf_VOl59.js} +2 -2
- package/dist/{meter-CpmTenEr.js.map → meter-Pf_VOl59.js.map} +1 -1
- package/dist/{pagination-BVqdlONY.js → pagination-DSY279Ta.js} +2 -2
- package/dist/{pagination-BVqdlONY.js.map → pagination-DSY279Ta.js.map} +1 -1
- package/dist/{popover-BRQZ2b6z.js → popover-BY-e9co1.js} +2 -2
- package/dist/{popover-BRQZ2b6z.js.map → popover-BY-e9co1.js.map} +1 -1
- package/dist/{radio-BNSwOt3B.js → radio-DZwL13j0.js} +2 -2
- package/dist/{radio-BNSwOt3B.js.map → radio-DZwL13j0.js.map} +1 -1
- package/dist/{select-1w2aebGQ.js → select-BFifYqHA.js} +6 -6
- package/dist/{select-1w2aebGQ.js.map → select-BFifYqHA.js.map} +1 -1
- package/dist/{sensitive-input-82Cez3vj.js → sensitive-input-DHLZcM73.js} +4 -4
- package/dist/{sensitive-input-82Cez3vj.js.map → sensitive-input-DHLZcM73.js.map} +1 -1
- package/dist/{sidebar-CAsCmSpM.js → sidebar-odGsdvG4.js} +6 -7
- package/dist/sidebar-odGsdvG4.js.map +1 -0
- package/dist/{signalflare-ai-logo-DDhxMJD6.js → signalflare-ai-logo-CNaDT_w8.js} +2 -2
- package/dist/{signalflare-ai-logo-DDhxMJD6.js.map → signalflare-ai-logo-CNaDT_w8.js.map} +1 -1
- package/dist/{skeleton-line-Do3UmGk9.js → skeleton-line-CxxYVTO2.js} +2 -2
- package/dist/{skeleton-line-Do3UmGk9.js.map → skeleton-line-CxxYVTO2.js.map} +1 -1
- package/dist/{sparkline-DdbeM4Ai.js → sparkline-BQ-4j2W2.js} +2 -2
- package/dist/{sparkline-DdbeM4Ai.js.map → sparkline-BQ-4j2W2.js.map} +1 -1
- package/dist/src/blocks/agent-harness/agent-harness.d.ts.map +1 -1
- package/dist/src/blocks/agent-harness/agent-harness.tsx +40 -16
- package/dist/src/blocks/commander/commander.tsx +15 -15
- package/dist/src/blocks/map-block/map-block.d.ts.map +1 -1
- package/dist/src/blocks/map-block/map-block.tsx +11 -7
- package/dist/src/components/ai-approval/ai-approval.d.ts.map +1 -1
- package/dist/src/components/ai-code-block/ai-code-block.d.ts +14 -13
- package/dist/src/components/ai-code-block/ai-code-block.d.ts.map +1 -1
- package/dist/src/components/ai-conversation/ai-conversation.d.ts +69 -37
- package/dist/src/components/ai-conversation/ai-conversation.d.ts.map +1 -1
- package/dist/src/components/ai-conversation/index.d.ts +2 -1
- package/dist/src/components/ai-conversation/index.d.ts.map +1 -1
- package/dist/src/components/ai-conversation/measurement-constants.d.ts +30 -0
- package/dist/src/components/ai-conversation/measurement-constants.d.ts.map +1 -0
- package/dist/src/components/ai-info-banner/ai-info-banner.d.ts.map +1 -1
- package/dist/src/components/ai-message/ai-message.d.ts +3 -0
- package/dist/src/components/ai-message/ai-message.d.ts.map +1 -1
- package/dist/src/components/ai-part-group/ai-part-group.d.ts.map +1 -1
- package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts +13 -3
- package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -1
- package/dist/src/components/ai-prompt-input/controller.d.ts.map +1 -1
- package/dist/src/components/ai-prompt-input/index.d.ts +1 -1
- package/dist/src/components/ai-prompt-input/index.d.ts.map +1 -1
- package/dist/src/components/ai-prompt-input/types.d.ts.map +1 -1
- package/dist/src/components/ai-question/ai-question.d.ts.map +1 -1
- package/dist/src/components/ai-reasoning/ai-reasoning.d.ts.map +1 -1
- package/dist/src/components/ai-response/ai-response.d.ts +12 -1
- package/dist/src/components/ai-response/ai-response.d.ts.map +1 -1
- package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts +27 -0
- package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts.map +1 -1
- package/dist/src/components/ai-streaming-text/index.d.ts +1 -1
- package/dist/src/components/ai-streaming-text/index.d.ts.map +1 -1
- package/dist/src/components/ai-subagent/ai-subagent.d.ts.map +1 -1
- package/dist/src/components/ai-task-list/ai-task-list.d.ts.map +1 -1
- package/dist/src/components/ai-tool/ai-tool.d.ts.map +1 -1
- package/dist/src/components/banner/banner.d.ts.map +1 -1
- package/dist/src/components/chart/echart.d.ts.map +1 -1
- package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -1
- package/dist/src/components/data-grid/data-grid.d.ts +2 -1
- package/dist/src/components/data-grid/data-grid.d.ts.map +1 -1
- package/dist/src/components/data-grid/features.d.ts +20 -0
- package/dist/src/components/data-grid/features.d.ts.map +1 -0
- package/dist/src/components/data-grid/types.d.ts +38 -7
- package/dist/src/components/data-grid/types.d.ts.map +1 -1
- package/dist/src/components/empty/empty.d.ts.map +1 -1
- package/dist/src/components/filters/filters.d.ts.map +1 -1
- package/dist/src/components/flow/use-children.d.ts +1 -1
- package/dist/src/components/link/link.d.ts.map +1 -1
- package/dist/src/components/sidebar/sidebar.d.ts +1 -1
- package/dist/src/components/signalflare-ai-logo/signalflare-ai-logo.d.ts.map +1 -1
- package/dist/src/components/stat-card/stat-card.d.ts +5 -0
- package/dist/src/components/stat-card/stat-card.d.ts.map +1 -1
- package/dist/src/components/text/text.d.ts +36 -1
- package/dist/src/components/text/text.d.ts.map +1 -1
- package/dist/src/components/text-roll/text-roll.d.ts.map +1 -1
- package/dist/src/components/theme-toggle/theme-toggle.d.ts.map +1 -1
- package/dist/src/components/toast/toast.d.ts.map +1 -1
- package/dist/src/components/tooltip/tooltip.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/utils/highlight-to-react.d.ts.map +1 -1
- package/dist/src/utils/index.d.ts +2 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/measured-text.d.ts +40 -0
- package/dist/src/utils/measured-text.d.ts.map +1 -0
- package/dist/src/utils/use-measured-text.d.ts +59 -0
- package/dist/src/utils/use-measured-text.d.ts.map +1 -0
- package/dist/{stat-card-CEZscNh8.js → stat-card-Bspk4XFr.js} +30 -12
- package/dist/stat-card-Bspk4XFr.js.map +1 -0
- package/dist/styles/sf-binding.css +1 -1
- package/dist/styles/sf-standalone.css +2 -2
- package/dist/styles/shadcn.css +1 -1
- package/dist/styles/theme-minimal.css +9 -9
- package/dist/styles/theme-sf.css +14 -20
- package/dist/styles/theme-vesper.css +91 -0
- package/dist/{surface-BduI7Ehl.js → surface-CWdSFVUx.js} +3 -3
- package/dist/{surface-BduI7Ehl.js.map → surface-CWdSFVUx.js.map} +1 -1
- package/dist/{switch-CzZBRBL7.js → switch-TA4cByCJ.js} +5 -5
- package/dist/switch-TA4cByCJ.js.map +1 -0
- package/dist/{table-Rv4JMy0B.js → table-BM8JBGBs.js} +3 -3
- package/dist/{table-Rv4JMy0B.js.map → table-BM8JBGBs.js.map} +1 -1
- package/dist/{tabs-1cHrYoel.js → tabs-bnH2vGLv.js} +2 -2
- package/dist/{tabs-1cHrYoel.js.map → tabs-bnH2vGLv.js.map} +1 -1
- package/dist/{text-KJmGkwnf.js → text-iQ0YUFNg.js} +27 -6
- package/dist/text-iQ0YUFNg.js.map +1 -0
- package/dist/{text-roll-BZ3I1umc.js → text-roll-C3U2jd2u.js} +5 -2
- package/dist/text-roll-C3U2jd2u.js.map +1 -0
- package/dist/{theme-toggle-Bhu681D7.js → theme-toggle-BTVxD-fD.js} +10 -9
- package/dist/theme-toggle-BTVxD-fD.js.map +1 -0
- package/dist/{toast-Nw28a5Cx.js → toast-CgZVaAkw.js} +3 -3
- package/dist/{toast-Nw28a5Cx.js.map → toast-CgZVaAkw.js.map} +1 -1
- package/dist/{tooltip-Cb7QW-7H.js → tooltip-uobk6Oh-.js} +9 -3
- package/dist/tooltip-uobk6Oh-.js.map +1 -0
- package/dist/{use-agent-harness-BMyF8pTq.js → use-agent-harness-Dl8w6X5O.js} +3 -3
- package/dist/{use-agent-harness-BMyF8pTq.js.map → use-agent-harness-Dl8w6X5O.js.map} +1 -1
- package/dist/utils.js +4 -3
- package/package.json +27 -24
- package/scripts/component-registry/discovery.ts +11 -10
- package/scripts/component-registry/example-cleanup.ts +8 -8
- package/scripts/component-registry/index.ts +6 -6
- package/scripts/component-registry/schema-generator.ts +1 -1
- package/scripts/component-registry/sub-components.ts +35 -23
- package/scripts/component-registry/utils.ts +11 -11
- package/scripts/component-registry/variant-parser.ts +17 -15
- package/scripts/convert-demos-to-stories.ts +5 -5
- package/scripts/css-build.ts +1 -1
- package/scripts/theme-generator/config.ts +28 -146
- package/scripts/theme-generator/generate-css.ts +1 -2
- package/scripts/theme-generator/index.ts +0 -1
- package/scripts/theme-generator/migrate.ts +3 -3
- package/dist/ai-agent-card-BXHwhWAU.js.map +0 -1
- package/dist/ai-code-block-BgtIxtZZ.js.map +0 -1
- package/dist/ai-conversation-CArP7C8K.js +0 -184
- package/dist/ai-conversation-CArP7C8K.js.map +0 -1
- package/dist/ai-info-banner-uFxHHwBA.js.map +0 -1
- package/dist/ai-message-BjnFznXy.js.map +0 -1
- package/dist/ai-part-group-DBtgTgAn.js.map +0 -1
- package/dist/ai-prompt-input-CuluUzpf.js.map +0 -1
- package/dist/ai-reasoning-CnL6ZSr5.js.map +0 -1
- package/dist/ai-response-BEUg3xvd.js.map +0 -1
- package/dist/ai-streaming-text-CMfoThV0.js.map +0 -1
- package/dist/ai-subagent-DcPRqkAA.js.map +0 -1
- package/dist/ai-task-list-Da9zIm00.js.map +0 -1
- package/dist/ai-timeline-Cwu045IR.js.map +0 -1
- package/dist/ai-tool-Cn1O4xjP.js.map +0 -1
- package/dist/banner-B_6oBrsu.js.map +0 -1
- package/dist/chart-BK3sVPnD.js.map +0 -1
- package/dist/clipboard-text-ssybngLw.js.map +0 -1
- package/dist/command-palette-DGzioeki.js.map +0 -1
- package/dist/data-grid-CG76N_hK.js.map +0 -1
- package/dist/dist-1-gcEL2L.js.map +0 -1
- package/dist/dropdown-qnEYRFXZ.js.map +0 -1
- package/dist/empty-D2TypIId.js.map +0 -1
- package/dist/filters-Bw_U6ZTx.js.map +0 -1
- package/dist/flow-BRsYUCJa.js.map +0 -1
- package/dist/highlight-to-react-ClEfL81q.js.map +0 -1
- package/dist/link-provider-BUZKXaNE.js.map +0 -1
- package/dist/sidebar-CAsCmSpM.js.map +0 -1
- package/dist/stat-card-CEZscNh8.js.map +0 -1
- package/dist/styles/theme-blue-tint.css +0 -98
- package/dist/switch-CzZBRBL7.js.map +0 -1
- package/dist/text-KJmGkwnf.js.map +0 -1
- package/dist/text-roll-BZ3I1umc.js.map +0 -1
- package/dist/theme-toggle-Bhu681D7.js.map +0 -1
- package/dist/tooltip-Cb7QW-7H.js.map +0 -1
package/dist/styles/shadcn.css
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* All values reference sf tokens by `var(--color-sf-*)` — there are zero
|
|
9
9
|
* hardcoded literals in this file. That means applying
|
|
10
|
-
* `[data-theme="fedramp"]` / `[data-theme="minimal"]` / `[data-theme="
|
|
10
|
+
* `[data-theme="fedramp"]` / `[data-theme="minimal"]` / `[data-theme="vesper"]`
|
|
11
11
|
* automatically restyles shadcn components too, because the cascade re-resolves
|
|
12
12
|
* the sf token at use time.
|
|
13
13
|
*
|
|
@@ -12,16 +12,16 @@
|
|
|
12
12
|
--text-color-sf-inactive: light-dark(oklch(0.65 0 0), oklch(0.35 0 0));
|
|
13
13
|
--text-color-sf-danger: light-dark(oklch(0.55 0.12 25), oklch(0.55 0.1 25));
|
|
14
14
|
--text-color-sf-warning: light-dark(oklch(0.55 0.08 66), oklch(0.65 0.08 66));
|
|
15
|
-
--color-sf-canvas: light-dark(oklch(0.95 0 0), oklch(0.
|
|
16
|
-
--color-sf-base: light-dark(oklch(0.97 0 0), oklch(0.
|
|
17
|
-
--color-sf-elevated: light-dark(oklch(1 0 0), oklch(0.
|
|
18
|
-
--color-sf-recessed: light-dark(oklch(0.92 0 0), oklch(0.
|
|
19
|
-
--color-sf-overlay: light-dark(oklch(0.93 0 0), oklch(0.
|
|
15
|
+
--color-sf-canvas: light-dark(oklch(0.95 0 0), oklch(0.173 0 0));
|
|
16
|
+
--color-sf-base: light-dark(oklch(0.97 0 0), oklch(0.1913 0 0));
|
|
17
|
+
--color-sf-elevated: light-dark(oklch(1 0 0), oklch(0.2002 0 0));
|
|
18
|
+
--color-sf-recessed: light-dark(oklch(0.92 0 0), oklch(0.173 0 0));
|
|
19
|
+
--color-sf-overlay: light-dark(oklch(0.93 0 0), oklch(0.173 0 0));
|
|
20
20
|
--color-sf-contrast: light-dark(oklch(0.35 0 0), oklch(0.75 0 0));
|
|
21
|
-
--color-sf-control: light-dark(oklch(0.95 0 0), oklch(0.
|
|
22
|
-
--color-sf-tint: light-dark(oklch(0.94 0 0), oklch(0.
|
|
23
|
-
--color-sf-fill: light-dark(oklch(0.91 0 0), oklch(0.
|
|
24
|
-
--color-sf-fill-hover: light-dark(oklch(0.88 0 0), oklch(0.
|
|
21
|
+
--color-sf-control: light-dark(oklch(0.95 0 0), oklch(0.2264 0 0));
|
|
22
|
+
--color-sf-tint: light-dark(oklch(0.94 0 0), oklch(0.2562 0 0));
|
|
23
|
+
--color-sf-fill: light-dark(oklch(0.91 0 0), oklch(0.2562 0 0));
|
|
24
|
+
--color-sf-fill-hover: light-dark(oklch(0.88 0 0), oklch(0.2768 0 0));
|
|
25
25
|
--color-sf-brand: light-dark(oklch(0.55 0.06 260), oklch(0.55 0.06 260));
|
|
26
26
|
--color-sf-brand-hover: light-dark(
|
|
27
27
|
oklch(0.48 0.05 264),
|
package/dist/styles/theme-sf.css
CHANGED
|
@@ -24,10 +24,7 @@
|
|
|
24
24
|
var(--color-blue-400, oklch(70.7% 0.165 254.624))
|
|
25
25
|
);
|
|
26
26
|
|
|
27
|
-
--text-color-sf-success: light-dark(
|
|
28
|
-
var(--color-green-500, oklch(72.3% 0.219 149.579)),
|
|
29
|
-
var(--color-green-500, oklch(72.3% 0.219 149.579))
|
|
30
|
-
);
|
|
27
|
+
--text-color-sf-success: light-dark(#99ffe4, #99ffe4);
|
|
31
28
|
|
|
32
29
|
--text-color-sf-danger: light-dark(oklch(0.5 0.15 25), oklch(0.68 0.16 25));
|
|
33
30
|
|
|
@@ -35,27 +32,27 @@
|
|
|
35
32
|
}
|
|
36
33
|
|
|
37
34
|
@theme {
|
|
38
|
-
--color-sf-canvas: light-dark(oklch(0.95 0 0), oklch(0.
|
|
35
|
+
--color-sf-canvas: light-dark(oklch(0.95 0 0), oklch(0.173 0 0));
|
|
39
36
|
|
|
40
|
-
--color-sf-base: light-dark(oklch(0.97 0 0), oklch(0.
|
|
37
|
+
--color-sf-base: light-dark(oklch(0.97 0 0), oklch(0.1913 0 0));
|
|
41
38
|
|
|
42
|
-
--color-sf-elevated: light-dark(oklch(1 0 0), oklch(0.
|
|
39
|
+
--color-sf-elevated: light-dark(oklch(1 0 0), oklch(0.2002 0 0));
|
|
43
40
|
|
|
44
|
-
--color-sf-recessed: light-dark(oklch(0.92 0 0), oklch(0.
|
|
41
|
+
--color-sf-recessed: light-dark(oklch(0.92 0 0), oklch(0.173 0 0));
|
|
45
42
|
|
|
46
|
-
--color-sf-overlay: light-dark(oklch(0.93 0 0), oklch(0.
|
|
43
|
+
--color-sf-overlay: light-dark(oklch(0.93 0 0), oklch(0.173 0 0));
|
|
47
44
|
|
|
48
45
|
--color-sf-contrast: light-dark(oklch(0.35 0 0), oklch(0.75 0 0));
|
|
49
46
|
|
|
50
|
-
--color-sf-control: light-dark(oklch(0.95 0 0), oklch(0.
|
|
47
|
+
--color-sf-control: light-dark(oklch(0.95 0 0), oklch(0.2264 0 0));
|
|
51
48
|
|
|
52
|
-
--color-sf-tint: light-dark(oklch(0.94 0 0), oklch(0.
|
|
49
|
+
--color-sf-tint: light-dark(oklch(0.94 0 0), oklch(0.2562 0 0));
|
|
53
50
|
|
|
54
|
-
--color-sf-interact: light-dark(oklch(0.8 0 0), oklch(0.
|
|
51
|
+
--color-sf-interact: light-dark(oklch(0.8 0 0), oklch(0.2768 0 0));
|
|
55
52
|
|
|
56
|
-
--color-sf-fill: light-dark(oklch(0.91 0 0), oklch(0.
|
|
53
|
+
--color-sf-fill: light-dark(oklch(0.91 0 0), oklch(0.2562 0 0));
|
|
57
54
|
|
|
58
|
-
--color-sf-fill-hover: light-dark(oklch(0.88 0 0), oklch(0.
|
|
55
|
+
--color-sf-fill-hover: light-dark(oklch(0.88 0 0), oklch(0.2768 0 0));
|
|
59
56
|
|
|
60
57
|
--color-sf-brand: light-dark(oklch(0.55 0.06 260), oklch(0.55 0.06 260));
|
|
61
58
|
|
|
@@ -64,13 +61,13 @@
|
|
|
64
61
|
oklch(0.48 0.05 264)
|
|
65
62
|
);
|
|
66
63
|
|
|
67
|
-
--color-sf-line: light-dark(oklch(0.85 0 0 / 0.5),
|
|
64
|
+
--color-sf-line: light-dark(oklch(0.85 0 0 / 0.5), #282828);
|
|
68
65
|
|
|
69
66
|
--color-sf-ring: light-dark(oklch(0.55 0 0), oklch(0.6 0 0));
|
|
70
67
|
|
|
71
68
|
--color-sf-tip-shadow: light-dark(transparent, transparent);
|
|
72
69
|
|
|
73
|
-
--color-sf-tip-stroke: light-dark(transparent,
|
|
70
|
+
--color-sf-tip-stroke: light-dark(transparent, #282828);
|
|
74
71
|
|
|
75
72
|
--color-sf-info: light-dark(oklch(0.55 0.06 260), oklch(0.55 0.06 260));
|
|
76
73
|
|
|
@@ -84,10 +81,7 @@
|
|
|
84
81
|
|
|
85
82
|
--color-sf-danger-tint: light-dark(oklch(0.94 0.02 25), oklch(0.16 0.04 25));
|
|
86
83
|
|
|
87
|
-
--color-sf-success: light-dark(
|
|
88
|
-
oklch(0.723 0.219 149.579),
|
|
89
|
-
oklch(0.723 0.219 149.579)
|
|
90
|
-
);
|
|
84
|
+
--color-sf-success: light-dark(#99ffe4, #99ffe4);
|
|
91
85
|
|
|
92
86
|
--color-sf-chart-1: light-dark(
|
|
93
87
|
oklch(0.646 0.222 41.116),
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vesper theme for SignalFlare AI
|
|
3
|
+
*
|
|
4
|
+
* Ported from the Vesper VS Code theme by raunofreiberg.
|
|
5
|
+
* Signature palette: near-black surfaces, warm peach accent (#FFC799),
|
|
6
|
+
* mint green strings (#99FFE4), and coral errors (#FF8080).
|
|
7
|
+
*
|
|
8
|
+
* Light mode intentionally falls back to the default SignalFlare palette.
|
|
9
|
+
* Vesper overrides only apply in dark mode.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
[data-theme="vesper"][data-mode="dark"] {
|
|
13
|
+
/* ── Text ────────────────────────────────────────────────────────── */
|
|
14
|
+
--text-color-sf-default: light-dark(#fff, #fff);
|
|
15
|
+
--text-color-sf-inverse: light-dark(#101010, #101010);
|
|
16
|
+
--text-color-sf-strong: light-dark(#fff, #fff);
|
|
17
|
+
/* A0A0A0 ≈ oklch(0.647 0 0) */
|
|
18
|
+
--text-color-sf-subtle: light-dark(#a0a0a0, #a0a0a0);
|
|
19
|
+
--text-color-sf-inactive: light-dark(#505050, #505050);
|
|
20
|
+
/* Brand text = peach */
|
|
21
|
+
--text-color-sf-brand: light-dark(#ffc799, #ffc799);
|
|
22
|
+
/* Links = peach */
|
|
23
|
+
--text-color-sf-link: light-dark(#ffc799, #ffc799);
|
|
24
|
+
/* Success/inserted = mint */
|
|
25
|
+
--text-color-sf-success: light-dark(#99ffe4, #99ffe4);
|
|
26
|
+
/* Danger = coral */
|
|
27
|
+
--text-color-sf-danger: light-dark(#ff8080, #ff8080);
|
|
28
|
+
/* Warning = amber (distinct from peach brand) */
|
|
29
|
+
--text-color-sf-warning: light-dark(#e8a84a, #e8a84a);
|
|
30
|
+
|
|
31
|
+
/* ── Surfaces ────────────────────────────────────────────────────── */
|
|
32
|
+
/* #101010 ≈ oklch(0.088 0 0) */
|
|
33
|
+
--color-sf-canvas: light-dark(#101010, #101010);
|
|
34
|
+
/* slightly lighter base */
|
|
35
|
+
--color-sf-base: light-dark(#141414, #141414);
|
|
36
|
+
/* #161616 = card / tab active */
|
|
37
|
+
--color-sf-elevated: light-dark(#161616, #161616);
|
|
38
|
+
--color-sf-recessed: light-dark(#101010, #101010);
|
|
39
|
+
--color-sf-overlay: light-dark(#101010, #101010);
|
|
40
|
+
/* for contrast text on surfaces */
|
|
41
|
+
--color-sf-contrast: light-dark(#a0a0a0, #a0a0a0);
|
|
42
|
+
|
|
43
|
+
/* ── Controls & fills ────────────────────────────────────────────── */
|
|
44
|
+
/* #1C1C1C = input background */
|
|
45
|
+
--color-sf-control: light-dark(#1c1c1c, #1c1c1c);
|
|
46
|
+
--color-sf-tint: light-dark(#1c1c1c, #1c1c1c);
|
|
47
|
+
/* #232323 = selected list item */
|
|
48
|
+
--color-sf-interact: light-dark(#282828, #282828);
|
|
49
|
+
--color-sf-fill: light-dark(#232323, #232323);
|
|
50
|
+
/* #282828 = list hover */
|
|
51
|
+
--color-sf-fill-hover: light-dark(#282828, #282828);
|
|
52
|
+
|
|
53
|
+
/* ── Brand / accent (peach) ──────────────────────────────────────── */
|
|
54
|
+
--color-sf-brand: light-dark(#ffc799, #ffc799);
|
|
55
|
+
--color-sf-brand-hover: light-dark(#ffcfa8, #ffcfa8);
|
|
56
|
+
|
|
57
|
+
/* ── Borders / rings ─────────────────────────────────────────────── */
|
|
58
|
+
/* ~#282828 at 60% opacity */
|
|
59
|
+
--color-sf-line: light-dark(#282828, #282828);
|
|
60
|
+
/* ring = peach on focus */
|
|
61
|
+
--color-sf-ring: light-dark(#ffc799, #ffc799);
|
|
62
|
+
|
|
63
|
+
/* ── Tooltip chrome ──────────────────────────────────────────────── */
|
|
64
|
+
--color-sf-tip-shadow: light-dark(transparent, transparent);
|
|
65
|
+
--color-sf-tip-stroke: light-dark(#282828, #282828);
|
|
66
|
+
|
|
67
|
+
/* ── Semantic: info (mint) ───────────────────────────────────────── */
|
|
68
|
+
--color-sf-info: light-dark(#99ffe4, #99ffe4);
|
|
69
|
+
--color-sf-info-tint: light-dark(#99ffe415, #99ffe415);
|
|
70
|
+
|
|
71
|
+
/* ── Semantic: warning (amber — distinct from peach brand) ─────────── */
|
|
72
|
+
--color-sf-warning: light-dark(#e8a84a, #e8a84a);
|
|
73
|
+
--color-sf-warning-tint: light-dark(#e8a84a20, #e8a84a20);
|
|
74
|
+
|
|
75
|
+
/* ── Semantic: danger (coral) ────────────────────────────────────── */
|
|
76
|
+
--color-sf-danger: light-dark(#ff8080, #ff8080);
|
|
77
|
+
--color-sf-danger-tint: light-dark(#ff808015, #ff808015);
|
|
78
|
+
|
|
79
|
+
/* ── Semantic: success (mint) ────────────────────────────────────── */
|
|
80
|
+
--color-sf-success: light-dark(#99ffe4, #99ffe4);
|
|
81
|
+
|
|
82
|
+
/* ── Syntax highlighting (sugar-high / shiki) ────────────────────── */
|
|
83
|
+
--color-sf-syntax-keyword: #a0a0a0;
|
|
84
|
+
--color-sf-syntax-identifier: #fff;
|
|
85
|
+
--color-sf-syntax-string: #99ffe4;
|
|
86
|
+
--color-sf-syntax-comment: #8b8b8b94;
|
|
87
|
+
--color-sf-syntax-jsxliterals: #ffc799;
|
|
88
|
+
--color-sf-syntax-property: #ffc799;
|
|
89
|
+
--color-sf-syntax-entity: #ffc799;
|
|
90
|
+
--color-sf-syntax-sign: #a0a0a0;
|
|
91
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as cn } from "./cn-
|
|
2
|
+
import { t as cn } from "./cn-CmAOpn49.js";
|
|
3
3
|
import { forwardRef } from "react";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region src/components/surface/surface.tsx
|
|
6
6
|
var defaultElement = "div";
|
|
7
|
-
var Surface = forwardRef(function
|
|
7
|
+
var Surface = forwardRef(function SurfaceImpl({ as, children, className, ...restProps }, ref) {
|
|
8
8
|
return /* @__PURE__ */ jsx(as ?? defaultElement, {
|
|
9
9
|
ref,
|
|
10
10
|
...restProps,
|
|
@@ -15,4 +15,4 @@ var Surface = forwardRef(function Surface({ as, children, className, ...restProp
|
|
|
15
15
|
//#endregion
|
|
16
16
|
export { Surface as t };
|
|
17
17
|
|
|
18
|
-
//# sourceMappingURL=surface-
|
|
18
|
+
//# sourceMappingURL=surface-CWdSFVUx.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface-
|
|
1
|
+
{"version":3,"file":"surface-CWdSFVUx.js","names":[],"sources":["../src/components/surface/surface.tsx"],"sourcesContent":["import React, {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ComponentPropsWithRef,\n type ElementType,\n type PropsWithChildren,\n} from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n/** Surface color variant definitions. */\nexport const SF_SURFACE_VARIANTS = {\n color: {\n primary: {\n classes: \"\",\n description: \"Primary surface color\",\n },\n secondary: {\n classes: \"\",\n description: \"Secondary surface color\",\n },\n },\n} as const;\n\nexport const SF_SURFACE_DEFAULT_VARIANTS = {\n color: \"primary\",\n} as const;\n\n// Derived types from SF_SURFACE_VARIANTS\nexport type SFSurfaceColor = keyof typeof SF_SURFACE_VARIANTS.color;\n\nexport interface SFSurfaceVariantsProps {\n /**\n * Surface color variant.\n * - `\"primary\"` — Primary surface color\n * - `\"secondary\"` — Secondary surface color\n * @default \"primary\"\n */\n color?: SFSurfaceColor;\n}\n\nexport function surfaceVariants({\n color = SF_SURFACE_DEFAULT_VARIANTS.color,\n}: SFSurfaceVariantsProps = {}) {\n return cn(\n // Base styles\n \"shadow-xs ring ring-sf-line\",\n // Apply color-specific styles\n SF_SURFACE_VARIANTS.color[color].classes\n );\n}\n\ntype PolymorphicAsProp<E extends ElementType> = {\n as?: E;\n};\n\ntype PolymorphicProps<E extends ElementType> = PropsWithChildren<\n ComponentPropsWithoutRef<E> & PolymorphicAsProp<E>\n>;\n\ntype PolymorphicRef<E extends ElementType> = ComponentPropsWithRef<E>[\"ref\"];\n\nconst defaultElement = \"div\";\n\ntype SurfacePropsGeneric<E extends ElementType = typeof defaultElement> =\n PolymorphicProps<E> & SFSurfaceVariantsProps;\n\n/**\n * Surface component props.\n *\n * @example\n * ```tsx\n * <Surface className=\"rounded-lg p-4\">Card content</Surface>\n * <Surface as=\"section\" className=\"rounded-lg p-6\">Section content</Surface>\n * ```\n */\nexport interface SurfaceProps {\n /** The HTML element type to render as (e.g. `\"div\"`, `\"section\"`, `\"article\"`). @default \"div\" */\n as?: ElementType;\n /** Surface color variant. @default \"primary\" */\n color?: SFSurfaceColor;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Content rendered inside the surface. */\n children?: React.ReactNode;\n}\n\ntype SurfaceComponent = <E extends ElementType = typeof defaultElement>(\n props: SurfacePropsGeneric<E> & { ref?: PolymorphicRef<E> }\n) => React.JSX.Element;\n\n/**\n * Polymorphic container with consistent background, shadow, and border styling.\n *\n * @example\n * ```tsx\n * <Surface className=\"rounded-lg p-4\">Card content</Surface>\n * ```\n */\nconst SurfaceImpl = function SurfaceImpl<\n E extends ElementType = typeof defaultElement,\n>(\n { as, children, className, ...restProps }: SurfacePropsGeneric<E>,\n ref: PolymorphicRef<E>\n) {\n const Component = as ?? defaultElement;\n return (\n <Component\n ref={ref}\n {...restProps}\n className={cn(\"bg-sf-base shadow-xs ring ring-sf-line\", className)}\n >\n {children}\n </Component>\n );\n};\n\nexport const Surface = forwardRef(\n SurfaceImpl as any\n) as unknown as SurfaceComponent;\n"],"mappings":";;;;;AA8DA,IAAM,iBAAiB;AAuDvB,IAAa,UAAU,WACrB,SAnB2B,YAG3B,EAAE,IAAI,UAAU,WAAW,GAAG,aAC9B,KACA;CAEA,OACE,oBAFgB,MAAM,gBAEtB;EACO;EACL,GAAI;EACJ,WAAW,GAAG,0CAA0C,SAAS;EAEhE;CACQ,CAAA;AAEf,CAIA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as cn } from "./cn-
|
|
3
|
-
import { t as Field } from "./field-
|
|
2
|
+
import { t as cn } from "./cn-CmAOpn49.js";
|
|
3
|
+
import { t as Field } from "./field-DBpFzzBS.js";
|
|
4
4
|
import { createContext, forwardRef, useContext } from "react";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
@@ -61,7 +61,7 @@ var SwitchBase = forwardRef(({ className, checked, disabled, size = "base", vari
|
|
|
61
61
|
"hover:bg-sf-danger/90": state.checked && !transitioning && !disabled && variant === "error",
|
|
62
62
|
"hover:bg-sf-interact": !state.checked && !transitioning && !disabled,
|
|
63
63
|
"cursor-not-allowed opacity-50": disabled
|
|
64
|
-
}, transitioning ? "cursor-wait" :
|
|
64
|
+
}, transitioning ? "cursor-wait" : disabled ? "" : "cursor-pointer", className, baseClassName);
|
|
65
65
|
const role = props.role ?? baseRole ?? "switch";
|
|
66
66
|
const checkedA11yProps = role === "switch" ? { "aria-checked": state.checked } : { "aria-pressed": state.checked };
|
|
67
67
|
return /* @__PURE__ */ jsx("button", {
|
|
@@ -110,7 +110,7 @@ var SwitchItem = forwardRef(({ className, checked, disabled, size = "base", vari
|
|
|
110
110
|
"hover:bg-sf-danger/90": state.checked && !transitioning && !disabled && variant === "error",
|
|
111
111
|
"hover:bg-sf-interact": !state.checked && !transitioning && !disabled,
|
|
112
112
|
"cursor-not-allowed opacity-50": disabled
|
|
113
|
-
}, transitioning ? "cursor-wait" :
|
|
113
|
+
}, transitioning ? "cursor-wait" : disabled ? "" : "cursor-pointer", baseClassName);
|
|
114
114
|
const role = baseRole ?? "switch";
|
|
115
115
|
const checkedA11yProps = role === "switch" ? { "aria-checked": state.checked } : { "aria-pressed": state.checked };
|
|
116
116
|
return /* @__PURE__ */ jsx("button", {
|
|
@@ -166,4 +166,4 @@ Switch$1.displayName = "Switch";
|
|
|
166
166
|
//#endregion
|
|
167
167
|
export { SF_SWITCH_VARIANTS as n, Switch$1 as r, SF_SWITCH_DEFAULT_VARIANTS as t };
|
|
168
168
|
|
|
169
|
-
//# sourceMappingURL=switch-
|
|
169
|
+
//# sourceMappingURL=switch-TA4cByCJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switch-TA4cByCJ.js","names":[],"sources":["../src/components/switch/switch.tsx"],"sourcesContent":["import { Fieldset } from \"@base-ui/react/fieldset\";\nimport { Switch as BaseSwitch } from \"@base-ui/react/switch\";\nimport {\n forwardRef,\n type ButtonHTMLAttributes,\n type Ref,\n type ReactNode,\n createContext,\n useContext,\n} from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { Field } from \"../field/field\";\n\n/** Switch size and variant definitions mapping names to their Tailwind classes. */\nexport const SF_SWITCH_VARIANTS = {\n size: {\n sm: {\n classes: \"h-5.5 w-8.5\",\n description: \"Small switch for compact UIs\",\n },\n base: {\n classes: \"h-6.5 w-10.5\",\n description: \"Default switch size\",\n },\n lg: {\n classes: \"h-7.5 w-12.5\",\n description: \"Large switch for prominent toggles\",\n },\n },\n variant: {\n default: {\n classes: \"\",\n description: \"Default switch appearance\",\n },\n error: {\n classes: \"ring-sf-danger\",\n description: \"Error state for validation failures\",\n },\n },\n} as const;\n\nexport const SF_SWITCH_DEFAULT_VARIANTS = {\n size: \"base\",\n variant: \"default\",\n} as const;\n\n// Derived types from SF_SWITCH_VARIANTS\nexport type SFSwitchSize = keyof typeof SF_SWITCH_VARIANTS.size;\nexport type SFSwitchVariant = keyof typeof SF_SWITCH_VARIANTS.variant;\n\nexport interface SFSwitchVariantsProps {\n /**\n * Switch size.\n * - `\"sm\"` — Small for compact UIs\n * - `\"base\"` — Default size\n * - `\"lg\"` — Large for prominent toggles\n * @default \"base\"\n */\n size?: SFSwitchSize;\n /**\n * Visual variant.\n * - `\"default\"` — Standard switch appearance\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: SFSwitchVariant;\n}\n\nexport function switchVariants({\n size = SF_SWITCH_DEFAULT_VARIANTS.size,\n variant = SF_SWITCH_DEFAULT_VARIANTS.variant,\n}: SFSwitchVariantsProps = {}) {\n return cn(\n SF_SWITCH_VARIANTS.size[size].classes,\n SF_SWITCH_VARIANTS.variant[variant].classes\n );\n}\n\n// Legacy type aliases for backwards compatibility\nexport type SwitchSize = SFSwitchSize;\nexport type SwitchVariant = SFSwitchVariant;\n\n// Context for passing controlFirst from Group to Items\nconst SwitchGroupContext = createContext<{ controlFirst: boolean }>({\n controlFirst: true,\n});\n\n/**\n * Single switch component props (with built-in Field)\n *\n * Usage patterns:\n *\n * Basic usage:\n * ```tsx\n * <Switch label=\"Enable notifications\" checked={true} onCheckedChange={setChecked} />\n * ```\n *\n * Label first layout:\n * ```tsx\n * <Switch label=\"Dark mode\" checked={false} onCheckedChange={setChecked} controlFirst={false} />\n * ```\n *\n * Error variant (visual only, no error text):\n * ```tsx\n * <Switch label=\"Required setting\" variant=\"error\" checked={false} onCheckedChange={setChecked} />\n * ```\n *\n * @property {string} label - Label text for the switch (Field wrapper is built-in)\n * @property {boolean} [controlFirst] - When true (default), switch appears before label\n */\nexport type SwitchProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\"\n> & {\n /** Visual variant: \"default\" or \"error\" for validation failures (visual only, no error text) */\n variant?: SwitchVariant;\n /** Label content for the switch (Field wrapper is built-in) - can be a string or any React node. Optional when used standalone for visual-only purposes. */\n label?: ReactNode;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /**\n * Whether the switch is required.\n * When explicitly false, shows \"(optional)\" text after the label.\n */\n required?: boolean;\n /** When true (default), switch appears before label. When false, label appears before switch. */\n controlFirst?: boolean;\n size?: SFSwitchSize;\n checked?: boolean;\n disabled?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n transitioning?: boolean;\n};\n\n/**\n * Switch group component props (with built-in Fieldset)\n *\n * Usage:\n * ```tsx\n * <Switch.Group\n * legend=\"Notification settings\"\n * error=\"You must enable at least one notification type\"\n * >\n * <Switch.Item label=\"Email notifications\" value=\"email\" />\n * <Switch.Item label=\"SMS notifications\" value=\"sms\" />\n * </Switch.Group>\n * ```\n */\nexport interface SwitchGroupProps {\n /** Legend text for the group */\n legend: string;\n /** Child Switch.Item components */\n children: ReactNode;\n /** Error message for the group (only appears in groups, not single switches) */\n error?: string;\n /** Helper text for the group */\n description?: ReactNode;\n /** Whether all switches in the group are disabled */\n disabled?: boolean;\n /** When true (default), switch appears before label. When false, label appears before switch. */\n controlFirst?: boolean;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Individual switch item within a group\n */\nexport type SwitchItemProps = {\n /** Visual variant: \"default\" or \"error\" for validation failures */\n variant?: SwitchVariant;\n /** Label text displayed next to switch */\n label: string;\n /** Additional CSS classes for the label wrapper */\n className?: string;\n checked?: boolean;\n disabled?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n size?: SFSwitchSize;\n transitioning?: boolean;\n};\n\n// Single switch with built-in Field\nconst SwitchBase = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n className,\n checked,\n disabled,\n size = \"base\",\n variant = \"default\",\n label,\n labelTooltip,\n required,\n controlFirst = true,\n onCheckedChange,\n transitioning,\n ...props\n },\n ref\n ) => {\n // For aria-label, only use string labels (ReactNode labels can't be used for aria-label)\n const ariaLabelFallback = typeof label === \"string\" ? label : \"Switch\";\n const switchControl = (\n <BaseSwitch.Root\n ref={ref}\n checked={checked}\n disabled={disabled}\n onCheckedChange={onCheckedChange}\n nativeButton\n render={(rootProps, state) => {\n const {\n ref: rootRef,\n className: baseClassName,\n role: baseRole,\n \"aria-checked\": _ariaChecked,\n \"aria-pressed\": _ariaPressed,\n ...restRootProps\n } = rootProps as typeof rootProps & {\n ref?: Ref<HTMLButtonElement>;\n className?: string;\n role?: string;\n \"aria-checked\"?: boolean;\n \"aria-pressed\"?: boolean;\n };\n\n const mergedClassName = cn(\n \"interactive flex items-center gap-2 rounded-full border border-transparent bg-sf-recessed p-1 transition-colors\",\n switchVariants({ size, variant }),\n {\n \"bg-sf-brand\": state.checked && !disabled && variant !== \"error\",\n \"bg-sf-danger\": state.checked && !disabled && variant === \"error\",\n \"hover:bg-sf-brand-hover\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant !== \"error\",\n \"hover:bg-sf-danger/90\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant === \"error\",\n \"hover:bg-sf-interact\":\n !state.checked && !transitioning && !disabled,\n \"cursor-not-allowed opacity-50\": disabled,\n },\n transitioning ? \"cursor-wait\" : disabled ? \"\" : \"cursor-pointer\",\n className,\n baseClassName\n );\n\n const role =\n (props.role as string | undefined) ?? baseRole ?? \"switch\";\n const checkedA11yProps =\n role === \"switch\"\n ? { \"aria-checked\": state.checked }\n : { \"aria-pressed\": state.checked };\n\n return (\n <button\n {...restRootProps}\n {...props}\n ref={rootRef}\n type=\"button\"\n role={role}\n {...checkedA11yProps}\n aria-busy={transitioning || undefined}\n aria-label={props[\"aria-label\"] ?? ariaLabelFallback}\n className={mergedClassName}\n >\n <BaseSwitch.Thumb\n className={cn(\n \"pointer-events-none aspect-square h-full rounded-full bg-white transition-all\",\n {\n \"translate-x-full rtl:translate-x-[-100%]\": state.checked,\n }\n )}\n />\n </button>\n );\n }}\n />\n );\n\n // Wrap in Field (built-in) - no description for single switches\n // If no label provided, return bare switch (for use in other components)\n if (!label) {\n return switchControl;\n }\n\n return (\n <Field\n label={label}\n required={required}\n labelTooltip={labelTooltip}\n controlFirst={controlFirst}\n >\n {switchControl}\n </Field>\n );\n }\n);\n\nSwitchBase.displayName = \"Switch\";\n\n// Switch.Item for use within Switch.Group\nconst SwitchItem = forwardRef<HTMLButtonElement, SwitchItemProps>(\n (\n {\n className,\n checked,\n disabled,\n size = \"base\",\n variant = \"default\",\n label,\n onCheckedChange,\n transitioning,\n },\n ref\n ) => {\n const { controlFirst } = useContext(SwitchGroupContext);\n\n return (\n <label\n className={cn(\n \"relative inline-flex items-center gap-2\",\n // Control first (default): switch before label\n // Label first: label before switch using flex-row-reverse\n !controlFirst && \"flex-row-reverse justify-end\",\n disabled ? \"cursor-not-allowed opacity-50\" : \"cursor-pointer\",\n className\n )}\n >\n <BaseSwitch.Root\n ref={ref}\n checked={checked}\n disabled={disabled}\n onCheckedChange={onCheckedChange}\n nativeButton\n render={(rootProps, state) => {\n const {\n ref: rootRef,\n className: baseClassName,\n role: baseRole,\n \"aria-checked\": _ariaChecked,\n \"aria-pressed\": _ariaPressed,\n ...restRootProps\n } = rootProps as typeof rootProps & {\n ref?: Ref<HTMLButtonElement>;\n className?: string;\n role?: string;\n \"aria-checked\"?: boolean;\n \"aria-pressed\"?: boolean;\n };\n\n const mergedClassName = cn(\n \"interactive flex items-center gap-2 rounded-full border border-transparent bg-sf-recessed p-1 transition-colors\",\n switchVariants({ size, variant }),\n {\n \"bg-sf-brand\":\n state.checked && !disabled && variant !== \"error\",\n \"bg-sf-danger\":\n state.checked && !disabled && variant === \"error\",\n \"hover:bg-sf-brand-hover\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant !== \"error\",\n \"hover:bg-sf-danger/90\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant === \"error\",\n \"hover:bg-sf-interact\":\n !state.checked && !transitioning && !disabled,\n \"cursor-not-allowed opacity-50\": disabled,\n },\n transitioning ? \"cursor-wait\" : disabled ? \"\" : \"cursor-pointer\",\n baseClassName\n );\n\n const role = baseRole ?? \"switch\";\n const checkedA11yProps =\n role === \"switch\"\n ? { \"aria-checked\": state.checked }\n : { \"aria-pressed\": state.checked };\n\n return (\n <button\n {...restRootProps}\n ref={rootRef}\n type=\"button\"\n role={role}\n {...checkedA11yProps}\n aria-busy={transitioning || undefined}\n className={mergedClassName}\n >\n <BaseSwitch.Thumb\n className={cn(\n \"pointer-events-none aspect-square h-full rounded-full bg-white transition-all\",\n {\n \"translate-x-full rtl:translate-x-[-100%]\": state.checked,\n }\n )}\n />\n </button>\n );\n }}\n />\n <span className=\"text-base font-medium text-sf-default\">{label}</span>\n </label>\n );\n }\n);\n\nSwitchItem.displayName = \"Switch.Item\";\n\n// Switch.Group with built-in Fieldset\nfunction SwitchGroup({\n legend,\n children,\n error,\n description,\n disabled,\n controlFirst = true,\n className,\n}: SwitchGroupProps) {\n return (\n <SwitchGroupContext.Provider value={{ controlFirst }}>\n <Fieldset.Root\n className={cn(\n \"flex flex-col gap-4 rounded-lg border border-sf-line p-4\",\n className\n )}\n disabled={disabled}\n >\n <Fieldset.Legend className=\"text-lg font-medium text-sf-default\">\n {legend}\n </Fieldset.Legend>\n <div className=\"flex flex-col gap-2\">{children}</div>\n {error && <p className=\"text-sm text-sf-danger\">{error}</p>}\n {description && <p className=\"text-sm text-sf-subtle\">{description}</p>}\n </Fieldset.Root>\n </SwitchGroupContext.Provider>\n );\n}\n\n// Compound component\nexport const Switch = Object.assign(SwitchBase, {\n Item: SwitchItem,\n Group: SwitchGroup,\n});\n\nSwitch.displayName = \"Switch\";\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as cn } from "./cn-
|
|
3
|
-
import { t as Checkbox } from "./checkbox-
|
|
2
|
+
import { t as cn } from "./cn-CmAOpn49.js";
|
|
3
|
+
import { t as Checkbox } from "./checkbox-Cy_OCyay.js";
|
|
4
4
|
import { forwardRef } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
//#region src/components/table/table.tsx
|
|
@@ -197,4 +197,4 @@ var Table = Object.assign(TableRoot, {
|
|
|
197
197
|
//#endregion
|
|
198
198
|
export { SF_TABLE_VARIANTS as n, Table as r, SF_TABLE_DEFAULT_VARIANTS as t };
|
|
199
199
|
|
|
200
|
-
//# sourceMappingURL=table-
|
|
200
|
+
//# sourceMappingURL=table-BM8JBGBs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-Rv4JMy0B.js","names":[],"sources":["../src/components/table/table.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { cn } from \"../../utils\";\nimport { Checkbox } from \"../checkbox\";\n\n/** Table layout and row variant definitions mapping names to their Tailwind classes. */\nexport const SF_TABLE_VARIANTS = {\n layout: {\n auto: {\n classes: \"\",\n description: \"Auto table layout - columns resize based on content\",\n },\n fixed: {\n classes: \"table-fixed\",\n description:\n \"Fixed table layout - columns have equal width, controlled via colgroup\",\n },\n },\n variant: {\n default: {\n classes: \"\",\n description: \"Default row variant\",\n },\n selected: {\n classes: \"bg-sf-tint\",\n description: \"Selected row variant\",\n },\n },\n} as const;\n\nexport const SF_TABLE_DEFAULT_VARIANTS = {\n layout: \"auto\",\n variant: \"default\",\n} as const;\n\nexport type SFTableRowVariant = keyof typeof SF_TABLE_VARIANTS.variant;\nexport type SFTableLayout = keyof typeof SF_TABLE_VARIANTS.layout;\n\n/**\n * Table root — applies layout, borders, padding, and header styles.\n *\n * @example\n * ```tsx\n * <Table layout=\"fixed\">\n * <Table.Header>\n * <Table.Row>\n * <Table.Head>Name</Table.Head>\n * <Table.Head>Status</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * <Table.Row>\n * <Table.Cell>Worker A</Table.Cell>\n * <Table.Cell>Active</Table.Cell>\n * </Table.Row>\n * </Table.Body>\n * </Table>\n * ```\n */\nconst TableRoot = forwardRef<\n HTMLTableElement,\n React.HTMLAttributes<HTMLTableElement> & {\n /**\n * Table layout algorithm.\n * - `\"auto\"` — columns resize based on content\n * - `\"fixed\"` — equal-width columns, controlled via `<colgroup>`\n * @default \"auto\"\n */\n layout?: SFTableLayout;\n }\n>(({ layout = \"auto\", ...props }, ref) => {\n const className = cn(\n \"w-full\",\n SF_TABLE_VARIANTS.layout[layout].classes,\n \"[&_tr_td]:border-b [&_tr_td]:border-sf-fill [&_tr:last-child_td]:border-b-0\", // Row border\n \"[&_tr_td]:p-3\", // Cell padding\n \"[&_tr_th]:border-b [&_tr_th]:border-sf-fill [&_tr_th]:p-3 [&_tr_th]:font-semibold\", // Header styles\n \"[&_tr_th]:bg-sf-base\", // Header background color\n \"text-left text-sf-default\",\n props.className\n );\n\n return <table ref={ref} {...props} className={className} />;\n});\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <thead ref={ref} {...props} />;\n});\n\nconst TableHead = forwardRef<\n HTMLTableCellElement,\n React.HTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n const className = cn(\"group relative\", props.className);\n return <th ref={ref} {...props} className={className} />;\n});\n\nconst TableRow = forwardRef<\n HTMLTableRowElement,\n React.HTMLAttributes<HTMLTableRowElement> & {\n variant?: SFTableRowVariant;\n }\n>(({ variant = SF_TABLE_DEFAULT_VARIANTS.variant, ...props }, ref) => {\n const className = cn(\n SF_TABLE_VARIANTS.variant[variant].classes,\n props.className\n );\n\n return <tr ref={ref} {...props} className={className} />;\n});\n\nconst TableBody = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tbody ref={ref} {...props} />;\n});\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n return <td ref={ref} {...props} />;\n});\n\nconst TableFooter = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tfoot ref={ref} {...props} />;\n});\n\nconst TableResizeHandle = forwardRef<\n HTMLButtonElement,\n React.HTMLAttributes<HTMLButtonElement>\n>((props, ref) => {\n return (\n <button\n ref={ref}\n {...props}\n type=\"button\"\n aria-label=\"Resize column\"\n className={cn(\n \"invisible h-full group-hover:visible\", // Make the handle invisible by default\n \"w-[10px]\", // Hitting area\n \"flex items-center justify-center\", // Center the handle\n \"cursor-col-resize touch-none select-none\", // Prevent selection and touch events\n \"absolute top-0 right-0\", // Position the handle\n \"m-0 bg-sf-base p-0\" // Override the stratus button styles\n )}\n >\n <span className=\"h-5 w-[2px] rounded bg-sf-ring\" />\n </button>\n );\n});\n\n/**\n * Special cell that makes the entire cell area a hit target for the checkbox.\n */\n\nconst TableCheckCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableCell\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select row\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableCell>\n );\n }\n);\n\nconst TableCheckHead = forwardRef<\n HTMLTableCellElement,\n React.ThHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableHead\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select all rows\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableHead>\n );\n }\n);\n\nTableRoot.displayName = \"Table\";\nTableBody.displayName = \"Table.Body\";\nTableHead.displayName = \"Table.Head\";\nTableRow.displayName = \"Table.Row\";\nTableCell.displayName = \"Table.Cell\";\nTableFooter.displayName = \"Table.Footer\";\nTableHeader.displayName = \"Table.Header\";\nTableResizeHandle.displayName = \"Table.ResizeHandle\";\nTableCheckCell.displayName = \"Table.CheckCell\";\nTableCheckHead.displayName = \"Table.CheckHead\";\n\n/**\n * Table — semantic HTML table with styled rows, cells, and selection support.\n *\n * Compound component: `Table` (Root), `.Header`, `.Head`, `.Body`, `.Row`,\n * `.Cell`, `.Footer`, `.CheckCell`, `.CheckHead`, `.ResizeHandle`.\n *\n * @example\n * ```tsx\n * <Table>\n * <Table.Header>\n * <Table.Row>\n * <Table.CheckHead checked={allSelected} onValueChange={toggleAll} />\n * <Table.Head>Name</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * {rows.map((row) => (\n * <Table.Row key={row.id} variant={selected.has(row.id) ? \"selected\" : \"default\"}>\n * <Table.CheckCell checked={selected.has(row.id)} onValueChange={() => toggle(row.id)} />\n * <Table.Cell>{row.name}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * </Table>\n * ```\n */\nexport const Table = Object.assign(TableRoot, {\n Header: TableHeader,\n Head: TableHead,\n Row: TableRow,\n Body: TableBody,\n Cell: TableCell,\n CheckCell: TableCheckCell,\n CheckHead: TableCheckHead,\n Footer: TableFooter,\n ResizeHandle: TableResizeHandle,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"table-BM8JBGBs.js","names":[],"sources":["../src/components/table/table.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { cn } from \"../../utils\";\nimport { Checkbox } from \"../checkbox\";\n\n/** Table layout and row variant definitions mapping names to their Tailwind classes. */\nexport const SF_TABLE_VARIANTS = {\n layout: {\n auto: {\n classes: \"\",\n description: \"Auto table layout - columns resize based on content\",\n },\n fixed: {\n classes: \"table-fixed\",\n description:\n \"Fixed table layout - columns have equal width, controlled via colgroup\",\n },\n },\n variant: {\n default: {\n classes: \"\",\n description: \"Default row variant\",\n },\n selected: {\n classes: \"bg-sf-tint\",\n description: \"Selected row variant\",\n },\n },\n} as const;\n\nexport const SF_TABLE_DEFAULT_VARIANTS = {\n layout: \"auto\",\n variant: \"default\",\n} as const;\n\nexport type SFTableRowVariant = keyof typeof SF_TABLE_VARIANTS.variant;\nexport type SFTableLayout = keyof typeof SF_TABLE_VARIANTS.layout;\n\n/**\n * Table root — applies layout, borders, padding, and header styles.\n *\n * @example\n * ```tsx\n * <Table layout=\"fixed\">\n * <Table.Header>\n * <Table.Row>\n * <Table.Head>Name</Table.Head>\n * <Table.Head>Status</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * <Table.Row>\n * <Table.Cell>Worker A</Table.Cell>\n * <Table.Cell>Active</Table.Cell>\n * </Table.Row>\n * </Table.Body>\n * </Table>\n * ```\n */\nconst TableRoot = forwardRef<\n HTMLTableElement,\n React.HTMLAttributes<HTMLTableElement> & {\n /**\n * Table layout algorithm.\n * - `\"auto\"` — columns resize based on content\n * - `\"fixed\"` — equal-width columns, controlled via `<colgroup>`\n * @default \"auto\"\n */\n layout?: SFTableLayout;\n }\n>(({ layout = \"auto\", ...props }, ref) => {\n const className = cn(\n \"w-full\",\n SF_TABLE_VARIANTS.layout[layout].classes,\n \"[&_tr_td]:border-b [&_tr_td]:border-sf-fill [&_tr:last-child_td]:border-b-0\", // Row border\n \"[&_tr_td]:p-3\", // Cell padding\n \"[&_tr_th]:border-b [&_tr_th]:border-sf-fill [&_tr_th]:p-3 [&_tr_th]:font-semibold\", // Header styles\n \"[&_tr_th]:bg-sf-base\", // Header background color\n \"text-left text-sf-default\",\n props.className\n );\n\n return <table ref={ref} {...props} className={className} />;\n});\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <thead ref={ref} {...props} />;\n});\n\nconst TableHead = forwardRef<\n HTMLTableCellElement,\n React.HTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n const className = cn(\"group relative\", props.className);\n return <th ref={ref} {...props} className={className} />;\n});\n\nconst TableRow = forwardRef<\n HTMLTableRowElement,\n React.HTMLAttributes<HTMLTableRowElement> & {\n variant?: SFTableRowVariant;\n }\n>(({ variant = SF_TABLE_DEFAULT_VARIANTS.variant, ...props }, ref) => {\n const className = cn(\n SF_TABLE_VARIANTS.variant[variant].classes,\n props.className\n );\n\n return <tr ref={ref} {...props} className={className} />;\n});\n\nconst TableBody = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tbody ref={ref} {...props} />;\n});\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n return <td ref={ref} {...props} />;\n});\n\nconst TableFooter = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tfoot ref={ref} {...props} />;\n});\n\nconst TableResizeHandle = forwardRef<\n HTMLButtonElement,\n React.HTMLAttributes<HTMLButtonElement>\n>((props, ref) => {\n return (\n <button\n ref={ref}\n {...props}\n type=\"button\"\n aria-label=\"Resize column\"\n className={cn(\n \"invisible h-full group-hover:visible\", // Make the handle invisible by default\n \"w-[10px]\", // Hitting area\n \"flex items-center justify-center\", // Center the handle\n \"cursor-col-resize touch-none select-none\", // Prevent selection and touch events\n \"absolute top-0 right-0\", // Position the handle\n \"m-0 bg-sf-base p-0\" // Override the stratus button styles\n )}\n >\n <span className=\"h-5 w-[2px] rounded bg-sf-ring\" />\n </button>\n );\n});\n\n/**\n * Special cell that makes the entire cell area a hit target for the checkbox.\n */\n\nconst TableCheckCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableCell\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select row\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableCell>\n );\n }\n);\n\nconst TableCheckHead = forwardRef<\n HTMLTableCellElement,\n React.ThHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableHead\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select all rows\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableHead>\n );\n }\n);\n\nTableRoot.displayName = \"Table\";\nTableBody.displayName = \"Table.Body\";\nTableHead.displayName = \"Table.Head\";\nTableRow.displayName = \"Table.Row\";\nTableCell.displayName = \"Table.Cell\";\nTableFooter.displayName = \"Table.Footer\";\nTableHeader.displayName = \"Table.Header\";\nTableResizeHandle.displayName = \"Table.ResizeHandle\";\nTableCheckCell.displayName = \"Table.CheckCell\";\nTableCheckHead.displayName = \"Table.CheckHead\";\n\n/**\n * Table — semantic HTML table with styled rows, cells, and selection support.\n *\n * Compound component: `Table` (Root), `.Header`, `.Head`, `.Body`, `.Row`,\n * `.Cell`, `.Footer`, `.CheckCell`, `.CheckHead`, `.ResizeHandle`.\n *\n * @example\n * ```tsx\n * <Table>\n * <Table.Header>\n * <Table.Row>\n * <Table.CheckHead checked={allSelected} onValueChange={toggleAll} />\n * <Table.Head>Name</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * {rows.map((row) => (\n * <Table.Row key={row.id} variant={selected.has(row.id) ? \"selected\" : \"default\"}>\n * <Table.CheckCell checked={selected.has(row.id)} onValueChange={() => toggle(row.id)} />\n * <Table.Cell>{row.name}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * </Table>\n * ```\n */\nexport const Table = Object.assign(TableRoot, {\n Header: TableHeader,\n Head: TableHead,\n Row: TableRow,\n Body: TableBody,\n Cell: TableCell,\n CheckCell: TableCheckCell,\n CheckHead: TableCheckHead,\n Footer: TableFooter,\n ResizeHandle: TableResizeHandle,\n});\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as cn } from "./cn-
|
|
2
|
+
import { t as cn } from "./cn-CmAOpn49.js";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { Tabs } from "@base-ui/react/tabs";
|
|
5
5
|
//#region src/components/tabs/tabs.tsx
|
|
@@ -51,4 +51,4 @@ function Tabs$1({ tabs, value, selectedValue, onValueChange, activateOnFocus, cl
|
|
|
51
51
|
//#endregion
|
|
52
52
|
export { Tabs$1 as t };
|
|
53
53
|
|
|
54
|
-
//# sourceMappingURL=tabs-
|
|
54
|
+
//# sourceMappingURL=tabs-bnH2vGLv.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs-
|
|
1
|
+
{"version":3,"file":"tabs-bnH2vGLv.js","names":[],"sources":["../src/components/tabs/tabs.tsx"],"sourcesContent":["import { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n/** Tabs variant definitions. */\nexport const SF_TABS_VARIANTS = {\n variant: [\"segmented\", \"underline\", \"pill\"],\n} as const;\n\nexport const SF_TABS_DEFAULT_VARIANTS = {\n variant: \"segmented\",\n} as const;\n\nexport const SF_TABS_STYLING = {\n container: {\n height: 34,\n borderRadius: 8,\n background: \"color-accent\",\n padding: 1,\n },\n tab: {\n paddingX: 10,\n verticalMargin: 1,\n fontSize: 16,\n fontWeight: 500,\n borderRadius: 8,\n activeColor: \"text-color-surface\",\n inactiveColor: \"text-color-label\",\n },\n indicator: {\n background: \"color-surface-secondary\",\n ring: \"color-color-2\",\n borderRadius: 6,\n shadow: \"shadow-sm\",\n },\n} as const;\n\n// Derived types from SF_TABS_VARIANTS\nexport interface SFTabsVariantsProps {\n /**\n * Tab style.\n * - `\"segmented\"` — Pill-shaped indicator on a filled track\n * - `\"underline\"` — Underline indicator below tab text\n * - `\"pill\"` — Fully rounded tabs, only selected has background\n * @default \"segmented\"\n */\n variant?: (typeof SF_TABS_VARIANTS.variant)[number];\n}\n\n/** Configuration for a single tab within the Tabs component. */\nexport type TabsItem = {\n /** Unique identifier for the tab, used as the controlled value. */\n value: string;\n /** Display content for the tab trigger. */\n label: ReactNode;\n /** Additional CSS classes for this tab trigger. */\n className?: string;\n /** Custom render function to replace the tab element (e.g. for link-based tabs). */\n render?: (props: Record<string, unknown>) => React.ReactElement;\n};\n\n/**\n * Tabs component props.\n *\n * @example\n * ```tsx\n * <Tabs\n * tabs={[\n * { value: \"overview\", label: \"Overview\" },\n * { value: \"settings\", label: \"Settings\" },\n * ]}\n * value={activeTab}\n * onValueChange={setActiveTab}\n * />\n * ```\n */\nexport type TabsProps = SFTabsVariantsProps & {\n /** Array of tab items to render. */\n tabs?: TabsItem[];\n /** Controlled value. When set, component becomes controlled. */\n value?: string;\n /** Default selected value for uncontrolled mode. Ignored when `value` is set. */\n selectedValue?: string;\n /** Callback fired when the active tab changes. */\n onValueChange?: (value: string) => void;\n /**\n * When `true`, tabs are activated immediately upon receiving focus via arrow keys.\n * When `false` (default), tabs receive focus but require Enter/Space to activate.\n */\n activateOnFocus?: boolean;\n /** Additional CSS classes for the root element. */\n className?: string;\n /** Additional CSS classes for the tab list element. */\n listClassName?: string;\n /** Additional CSS classes for the indicator element. */\n indicatorClassName?: string;\n};\n\n/**\n * Tab navigation component with segmented, underline, or pill style.\n * Built on Base UI Tabs with animated active indicator.\n *\n * @example\n * ```tsx\n * <Tabs\n * variant=\"segmented\"\n * tabs={[{ value: \"tab1\", label: \"Tab 1\" }, { value: \"tab2\", label: \"Tab 2\" }]}\n * value={active}\n * onValueChange={setActive}\n * />\n * <Tabs variant=\"pill\" tabs={[...]} value={active} />\n * ```\n */\nexport function Tabs({\n tabs,\n value,\n selectedValue,\n onValueChange,\n activateOnFocus,\n className,\n listClassName,\n indicatorClassName,\n variant = SF_TABS_DEFAULT_VARIANTS.variant,\n}: TabsProps) {\n const items: TabsItem[] = tabs ?? [];\n\n if (items.length === 0) {\n return null;\n }\n\n const fallbackValue = items[0]?.value;\n const isControlled = value !== undefined;\n const rootProps = {\n value: isControlled ? value : undefined,\n defaultValue: isControlled ? undefined : (selectedValue ?? fallbackValue),\n };\n\n const isSegmented = variant === \"segmented\";\n const isUnderline = variant === \"underline\";\n const isPill = variant === \"pill\";\n\n return (\n <TabsPrimitive.Root\n {...rootProps}\n className={cn(\"relative min-w-0 font-medium\", className)}\n onValueChange={(nextValue) => {\n const stringValue = String(nextValue);\n onValueChange?.(stringValue);\n }}\n >\n {/* Background element for segmented variant only */}\n {(isSegmented || isPill) && (\n <div\n className={cn(\n \"absolute inset-x-0 top-1/2 -z-10 h-8.5 -translate-y-1/2 rounded-lg\",\n isSegmented && \"bg-sf-tint\",\n isPill && \"hidden\"\n )}\n />\n )}\n <TabsPrimitive.List\n activateOnFocus={activateOnFocus}\n className={cn(\n \"scrollbar-hide relative flex min-w-0 shrink items-stretch\",\n isSegmented && \"h-8.5 rounded-lg bg-sf-tint px-px\",\n isUnderline && \"h-7 gap-4 border-b border-sf-line pb-2\",\n isPill && \"h-9 gap-1\",\n listClassName\n )}\n >\n {items.map((tab) => (\n <TabsPrimitive.Tab\n key={tab.value}\n value={tab.value}\n className={cn(\n \"relative z-10 flex cursor-pointer items-center whitespace-nowrap hover:border-sf-tint focus-visible:rounded-none focus-visible:ring-sf-ring focus-visible:outline-offset-3\",\n isSegmented &&\n \"my-px rounded-lg bg-transparent px-2.5 text-base text-sf-strong aria-selected:text-sf-default\",\n isUnderline &&\n \"mb-2 text-base text-sf-strong hover:text-sf-subtle aria-selected:font-medium aria-selected:text-sf-default\",\n isPill &&\n \"rounded-full px-3 text-sm text-sf-strong transition-colors hover:bg-sf-tint/50 hover:text-sf-subtle aria-selected:bg-sf-tint aria-selected:font-medium aria-selected:text-sf-default\",\n tab.className\n )}\n >\n {tab.label}\n </TabsPrimitive.Tab>\n ))}\n <TabsPrimitive.Indicator\n className={cn(\n \"absolute z-0 transition-[left,width,transform] duration-200 ease-out\",\n \"data-[rendered=false]:scale-90 data-[rendered=false]:opacity-0\",\n \"left-(--active-tab-left) w-(--active-tab-width)\",\n isSegmented &&\n \"top-(--active-tab-top) h-(--active-tab-height) rounded-lg bg-sf-overlay shadow-sm ring ring-sf-fill-hover\",\n isUnderline && \"bottom-0 h-0.5 bg-sf-brand\",\n isPill && \"hidden\",\n indicatorClassName\n )}\n />\n </TabsPrimitive.List>\n </TabsPrimitive.Root>\n );\n}\n"],"mappings":";;;;;AAUA,IAAa,2BAA2B,EACtC,SAAS,YACX;;;;;;;;;;;;;;;;AAsGA,SAAgB,OAAK,EACnB,MACA,OACA,eACA,eACA,iBACA,WACA,eACA,oBACA,UAAU,yBAAyB,WACvB;CACZ,MAAM,QAAoB,QAAQ,CAAC;CAEnC,IAAI,MAAM,WAAW,GACnB,OAAO;CAGT,MAAM,gBAAgB,MAAM,IAAI;CAChC,MAAM,eAAe,UAAU,KAAA;CAC/B,MAAM,YAAY;EAChB,OAAO,eAAe,QAAQ,KAAA;EAC9B,cAAc,eAAe,KAAA,IAAa,iBAAiB;CAC7D;CAEA,MAAM,cAAc,YAAY;CAChC,MAAM,cAAc,YAAY;CAChC,MAAM,SAAS,YAAY;CAE3B,OACE,qBAAC,KAAc,MAAf;EACE,GAAI;EACJ,WAAW,GAAG,gCAAgC,SAAS;EACvD,gBAAgB,cAAc;GAE5B,gBADoB,OAAO,SACX,CAAW;EAC7B;YANF,EASI,eAAe,WACf,oBAAC,OAAD,EACE,WAAW,GACT,sEACA,eAAe,cACf,UAAU,QACZ,EACD,CAAA,GAEH,qBAAC,KAAc,MAAf;GACmB;GACjB,WAAW,GACT,6DACA,eAAe,qCACf,eAAe,0CACf,UAAU,aACV,aACF;aARF,CAUG,MAAM,KAAK,QACV,oBAAC,KAAc,KAAf;IAEE,OAAO,IAAI;IACX,WAAW,GACT,8KACA,eACE,iGACF,eACE,8GACF,UACE,wLACF,IAAI,SACN;cAEC,IAAI;GACY,GAdZ,IAAI,KAcQ,CACpB,GACD,oBAAC,KAAc,WAAf,EACE,WAAW,GACT,wEACA,kEACA,mDACA,eACE,6GACF,eAAe,8BACf,UAAU,UACV,kBACF,EACD,CAAA,CACiB;IACF;;AAExB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as cn } from "./cn-
|
|
2
|
+
import { t as cn } from "./cn-CmAOpn49.js";
|
|
3
|
+
import { t as MeasuredText } from "./measured-text-CXkdw9Yr.js";
|
|
3
4
|
import { forwardRef, useMemo } from "react";
|
|
4
5
|
import { jsx } from "react/jsx-runtime";
|
|
5
6
|
//#region src/components/text/text.tsx
|
|
@@ -62,18 +63,24 @@ var SF_TEXT_VARIANTS = {
|
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
};
|
|
66
|
+
function getDefaultWrap(_variant) {
|
|
67
|
+
return "natural";
|
|
68
|
+
}
|
|
65
69
|
/**
|
|
66
70
|
* Typography component for rendering text with consistent styling.
|
|
67
71
|
* Automatically selects the appropriate HTML element based on variant
|
|
68
72
|
* (`h1`/`h2`/`h3` for headings, `p` for body, `span` for mono).
|
|
69
73
|
*
|
|
74
|
+
* Now includes pretext-driven layout for precise wrapping and spacing.
|
|
75
|
+
*
|
|
70
76
|
* @example
|
|
71
77
|
* ```tsx
|
|
72
78
|
* <Text variant="heading1">Dashboard</Text>
|
|
73
79
|
* <Text>Default body text</Text>
|
|
80
|
+
* <Text wrap="shrink">Compact bubble</Text>
|
|
74
81
|
* ```
|
|
75
82
|
*/
|
|
76
|
-
function _Text({ variant = "body", bold = false, size = "base", children, DANGEROUS_className, DANGEROUS_style, as, ...props }, ref) {
|
|
83
|
+
function _Text({ variant = "body", bold = false, size = "base", children, DANGEROUS_className, DANGEROUS_style, as, wrap, reserveLines, ...props }, ref) {
|
|
77
84
|
const isCopy = [
|
|
78
85
|
"body",
|
|
79
86
|
"secondary",
|
|
@@ -81,23 +88,37 @@ function _Text({ variant = "body", bold = false, size = "base", children, DANGER
|
|
|
81
88
|
"error"
|
|
82
89
|
].includes(variant);
|
|
83
90
|
const isMono = ["mono", "mono-secondary"].includes(variant);
|
|
84
|
-
|
|
91
|
+
const Component = useMemo(() => {
|
|
85
92
|
if (as) return as;
|
|
86
93
|
if (variant === "heading1") return "h1";
|
|
87
94
|
if (variant === "heading2") return "h2";
|
|
88
95
|
if (variant === "heading3") return "h3";
|
|
89
96
|
if (["mono", "mono-secondary"].includes(variant)) return "span";
|
|
90
97
|
return "p";
|
|
91
|
-
}, [variant, as])
|
|
98
|
+
}, [variant, as]);
|
|
99
|
+
const effectiveWrap = wrap ?? getDefaultWrap(variant);
|
|
100
|
+
const className = cn("text-sf-default", SF_TEXT_VARIANTS.variant[variant].classes, isCopy ? SF_TEXT_VARIANTS.size[size].classes : "", isCopy && bold ? "font-medium" : "", isMono && (size === "lg" ? SF_TEXT_VARIANTS.size.base.classes : SF_TEXT_VARIANTS.size.sm.classes), DANGEROUS_className);
|
|
101
|
+
if (effectiveWrap !== "natural" && effectiveWrap !== false) return /* @__PURE__ */ jsx(MeasuredText, {
|
|
102
|
+
ref,
|
|
103
|
+
as: Component,
|
|
104
|
+
wrap: effectiveWrap,
|
|
105
|
+
reserveLines,
|
|
106
|
+
className,
|
|
107
|
+
style: DANGEROUS_style,
|
|
108
|
+
...props,
|
|
109
|
+
children
|
|
110
|
+
});
|
|
111
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
92
112
|
ref,
|
|
93
|
-
className
|
|
113
|
+
className,
|
|
94
114
|
style: DANGEROUS_style,
|
|
95
115
|
...props,
|
|
96
116
|
children
|
|
97
117
|
});
|
|
98
118
|
}
|
|
99
119
|
var Text = forwardRef(_Text);
|
|
120
|
+
Text.displayName = "Text";
|
|
100
121
|
//#endregion
|
|
101
122
|
export { Text as t };
|
|
102
123
|
|
|
103
|
-
//# sourceMappingURL=text-
|
|
124
|
+
//# sourceMappingURL=text-iQ0YUFNg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-iQ0YUFNg.js","names":[],"sources":["../src/components/text/text.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ForwardedRef,\n forwardRef,\n useMemo,\n type ElementType,\n} from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { MeasuredText, type MeasuredTextMode } from \"../../utils/measured-text\";\n\n/** Text variant and size definitions mapping names to their Tailwind classes. */\nexport const SF_TEXT_VARIANTS = {\n variant: {\n heading1: {\n classes: \"text-3xl font-semibold\",\n description: \"Large heading for page titles\",\n },\n heading2: {\n classes: \"text-2xl font-semibold\",\n description: \"Medium heading for section titles\",\n },\n heading3: {\n classes: \"text-lg font-semibold\",\n description: \"Small heading for subsections\",\n },\n body: {\n classes: \"text-sf-default\",\n description: \"Default body text\",\n },\n secondary: {\n classes: \"text-sf-subtle\",\n description: \"Muted text for secondary information\",\n },\n success: {\n classes: \"text-sf-link\",\n description: \"Success state text\",\n },\n error: {\n classes: \"text-sf-danger\",\n description: \"Error state text\",\n },\n mono: {\n classes: \"font-mono\",\n description: \"Monospace text for code\",\n },\n \"mono-secondary\": {\n classes: \"font-mono text-sf-subtle\",\n description: \"Muted monospace text\",\n },\n },\n size: {\n xs: {\n classes: \"text-xs\",\n description: \"Extra small text\",\n },\n sm: {\n classes: \"text-sm\",\n description: \"Small text\",\n },\n base: {\n classes: \"text-base\",\n description: \"Default text size\",\n },\n lg: {\n classes: \"text-lg\",\n description: \"Large text\",\n },\n },\n} as const;\n\nexport const SF_TEXT_DEFAULT_VARIANTS = {\n variant: \"body\",\n size: \"base\",\n} as const;\n\n/**\n * SF_TEXT_STYLING - Typography metadata for Figma generator\n *\n * This export provides structured styling information extracted from text.tsx\n * for use by the Figma plugin generator. It documents font sizes, weights,\n * colors, and font families used across all Text variants.\n *\n * Source of truth chain:\n * text.tsx (this file) → component-registry.json → text.ts (Figma generator)\n */\nexport const SF_TEXT_STYLING = {\n fontSizes: {\n xs: 12,\n sm: 14,\n base: 16,\n lg: 18,\n xl: 20,\n \"2xl\": 24,\n \"3xl\": 30,\n },\n fontWeights: {\n normal: 400,\n medium: 500,\n semibold: 600,\n },\n baseColor: \"text-sf-default\",\n variantColors: {\n body: \"text-sf-default\",\n secondary: \"text-sf-subtle\",\n success: \"text-sf-link\",\n error: \"text-sf-danger\",\n mono: \"text-sf-default\",\n \"mono-secondary\": \"text-sf-subtle\",\n },\n fontFamilies: {\n default: \"sans-serif\",\n mono: \"monospace\",\n },\n} as const;\n\n// Derived types from SF_TEXT_VARIANTS\nexport type SFTextVariant = keyof typeof SF_TEXT_VARIANTS.variant;\nexport type SFTextSize = keyof typeof SF_TEXT_VARIANTS.size;\n\nexport interface SFTextVariantsProps {\n variant?: SFTextVariant;\n size?: SFTextSize;\n}\n\nexport function textVariants({\n variant = SF_TEXT_DEFAULT_VARIANTS.variant,\n size = SF_TEXT_DEFAULT_VARIANTS.size,\n}: SFTextVariantsProps = {}) {\n return cn(\n SF_TEXT_VARIANTS.variant[variant].classes,\n SF_TEXT_VARIANTS.size[size].classes\n );\n}\n\n// Legacy types for backwards compatibility\ntype Heading = \"heading1\" | \"heading2\" | \"heading3\";\ntype Copy = \"body\" | \"secondary\" | \"success\" | \"error\";\ntype Monospace = \"mono\" | \"mono-secondary\";\ntype TextSize = SFTextSize;\ntype TextVariant = SFTextVariant;\n\ntype BaseTextProps = Omit<\n ComponentPropsWithoutRef<\"span\">,\n \"className\" | \"style\"\n> & {\n DANGEROUS_className?: string;\n DANGEROUS_style?: CSSProperties;\n as?: ElementType;\n /**\n * Text layout strategy using pretext-driven measurement.\n * - `\"natural\"` — No measurement, normal browser wrapping (default for body).\n * - `\"balance\"` — Even wrapping, smallest maxWidth without adding lines (default for headings).\n * - `\"shrink\"` — Hug widest natural line (maxWidth = line width). Good for chat bubbles.\n * - `\"reserve\"` — Reserve height based on line count. Good for streaming text.\n * - `false` — Same as `\"natural\"`, explicit opt-out.\n * @default \"balance\" for headings, \"natural\" for body/mono/secondary.\n */\n wrap?: MeasuredTextMode | false;\n /**\n * For `wrap=\"reserve\"`: reserve this many lines of height.\n * If omitted, measures current content to determine line count.\n */\n reserveLines?: number;\n};\n\ntype TextPropsInternal<Variant extends TextVariant = \"body\"> = BaseTextProps &\n (Variant extends Copy\n ? {\n variant?: Variant;\n bold?: boolean;\n size?: TextSize;\n }\n : Variant extends Monospace\n ? {\n variant?: Variant;\n bold?: never;\n size?: \"lg\";\n }\n : Variant extends Heading\n ? {\n variant?: Variant;\n bold?: never;\n size?: never;\n }\n : never);\n\n/**\n * Text component props.\n *\n * @example\n * ```tsx\n * <Text variant=\"heading1\">Page Title</Text>\n * <Text variant=\"body\">Default paragraph text.</Text>\n * <Text variant=\"secondary\" size=\"sm\">Muted helper text</Text>\n * <Text variant=\"error\">Something went wrong</Text>\n * <Text variant=\"mono\">console.log(\"code\")</Text>\n * <Text wrap=\"shrink\">Hug content width</Text>\n * <Text wrap=\"reserve\" reserveLines={3}>Streaming content...</Text>\n * ```\n */\nexport interface TextProps {\n /**\n * Text style variant. Determines color, font, and weight.\n * - `\"heading1\"` — Large page title (30px, semibold)\n * - `\"heading2\"` — Section title (24px, semibold)\n * - `\"heading3\"` — Subsection title (18px, semibold)\n * - `\"body\"` — Default body text\n * - `\"secondary\"` — Muted text for secondary information\n * - `\"success\"` — Success state text\n * - `\"error\"` — Error state text\n * - `\"mono\"` — Monospace text for code\n * - `\"mono-secondary\"` — Muted monospace text\n * @default \"body\"\n */\n variant?: SFTextVariant;\n /**\n * Text size (only applies to body/secondary/success/error variants).\n * - `\"xs\"` — 12px\n * - `\"sm\"` — 14px\n * - `\"base\"` — 16px\n * - `\"lg\"` — 18px\n * @default \"base\"\n */\n size?: SFTextSize;\n /** Whether to use bold font weight (only applies to body variants). */\n bold?: boolean;\n /** The HTML element type to render as (e.g. `\"span\"`, `\"p\"`, `\"h1\"`). Auto-selected based on variant if omitted. */\n as?: ElementType;\n /** Text content. */\n children?: React.ReactNode;\n /**\n * Text layout strategy using pretext-driven measurement.\n * - `\"natural\"` — No measurement, normal browser wrapping (default for body).\n * - `\"balance\"` — Even wrapping, smallest maxWidth without adding lines (default for headings).\n * - `\"shrink\"` — Hug widest natural line (maxWidth = line width). Good for chat bubbles.\n * - `\"reserve\"` — Reserve height based on line count. Good for streaming text.\n * @default \"natural\" for all variants. Set `wrap=\"balance\"` explicitly to\n * enable balanced wrapping (only reliable inside width-constrained containers).\n */\n wrap?: MeasuredTextMode | false;\n /**\n * For `wrap=\"reserve\"`: reserve this many lines of height.\n * If omitted, measures current content to determine line count.\n */\n reserveLines?: number;\n}\n\nfunction getDefaultWrap(_variant: TextVariant): MeasuredTextMode | false {\n return \"natural\";\n}\n\n/**\n * Typography component for rendering text with consistent styling.\n * Automatically selects the appropriate HTML element based on variant\n * (`h1`/`h2`/`h3` for headings, `p` for body, `span` for mono).\n *\n * Now includes pretext-driven layout for precise wrapping and spacing.\n *\n * @example\n * ```tsx\n * <Text variant=\"heading1\">Dashboard</Text>\n * <Text>Default body text</Text>\n * <Text wrap=\"shrink\">Compact bubble</Text>\n * ```\n */\nfunction _Text<Variant extends TextVariant = \"body\">(\n {\n variant = \"body\" as Variant,\n bold = false,\n size = \"base\",\n children,\n DANGEROUS_className,\n DANGEROUS_style,\n as,\n wrap,\n reserveLines,\n ...props\n }: TextPropsInternal<Variant>,\n ref: ForwardedRef<HTMLHeadingElement>\n) {\n const isCopy = [\"body\", \"secondary\", \"success\", \"error\"].includes(variant);\n const isMono = [\"mono\", \"mono-secondary\"].includes(variant);\n\n const Component = useMemo(() => {\n if (as) return as;\n if (variant === \"heading1\") return \"h1\";\n if (variant === \"heading2\") return \"h2\";\n if (variant === \"heading3\") return \"h3\";\n if ([\"mono\", \"mono-secondary\"].includes(variant)) return \"span\";\n return \"p\";\n }, [variant, as]);\n\n const effectiveWrap = wrap ?? getDefaultWrap(variant);\n const className = cn(\n \"text-sf-default\",\n SF_TEXT_VARIANTS.variant[variant].classes,\n isCopy ? SF_TEXT_VARIANTS.size[size].classes : \"\",\n isCopy && bold ? \"font-medium\" : \"\",\n // Monospace fonts need to be 1pt smaller than body text to optically match\n isMono &&\n (size === \"lg\"\n ? SF_TEXT_VARIANTS.size.base.classes\n : SF_TEXT_VARIANTS.size.sm.classes),\n DANGEROUS_className\n );\n\n // Use MeasuredText for non-natural modes, or when reserveLines is set\n if (effectiveWrap !== \"natural\" && effectiveWrap !== false) {\n return (\n <MeasuredText\n ref={ref as React.RefObject<HTMLElement>}\n as={Component}\n wrap={effectiveWrap}\n reserveLines={reserveLines}\n className={className}\n style={DANGEROUS_style}\n {...props}\n >\n {children}\n </MeasuredText>\n );\n }\n\n // Natural mode: render directly without measurement overhead\n return (\n <Component\n ref={ref}\n className={className}\n style={DANGEROUS_style}\n {...props}\n >\n {children}\n </Component>\n );\n}\n\nexport const Text = forwardRef(_Text) as <Variant extends TextVariant = \"body\">(\n props: TextPropsInternal<Variant> & {\n ref?: ForwardedRef<ElementRef<\"span\">>;\n }\n) => React.ReactElement & { displayName?: string };\n\n// Cast needed because of the complex forwardRef type signature\n(Text as { displayName?: string }).displayName = \"Text\";\n"],"mappings":";;;;;;;AAcA,IAAa,mBAAmB;CAC9B,SAAS;EACP,UAAU;GACR,SAAS;GACT,aAAa;EACf;EACA,UAAU;GACR,SAAS;GACT,aAAa;EACf;EACA,UAAU;GACR,SAAS;GACT,aAAa;EACf;EACA,MAAM;GACJ,SAAS;GACT,aAAa;EACf;EACA,WAAW;GACT,SAAS;GACT,aAAa;EACf;EACA,SAAS;GACP,SAAS;GACT,aAAa;EACf;EACA,OAAO;GACL,SAAS;GACT,aAAa;EACf;EACA,MAAM;GACJ,SAAS;GACT,aAAa;EACf;EACA,kBAAkB;GAChB,SAAS;GACT,aAAa;EACf;CACF;CACA,MAAM;EACJ,IAAI;GACF,SAAS;GACT,aAAa;EACf;EACA,IAAI;GACF,SAAS;GACT,aAAa;EACf;EACA,MAAM;GACJ,SAAS;GACT,aAAa;EACf;EACA,IAAI;GACF,SAAS;GACT,aAAa;EACf;CACF;AACF;AAmLA,SAAS,eAAe,UAAiD;CACvE,OAAO;AACT;;;;;;;;;;;;;;;AAgBA,SAAS,MACP,EACE,UAAU,QACV,OAAO,OACP,OAAO,QACP,UACA,qBACA,iBACA,IACA,MACA,cACA,GAAG,SAEL,KACA;CACA,MAAM,SAAS;EAAC;EAAQ;EAAa;EAAW;CAAO,EAAE,SAAS,OAAO;CACzE,MAAM,SAAS,CAAC,QAAQ,gBAAgB,EAAE,SAAS,OAAO;CAE1D,MAAM,YAAY,cAAc;EAC9B,IAAI,IAAI,OAAO;EACf,IAAI,YAAY,YAAY,OAAO;EACnC,IAAI,YAAY,YAAY,OAAO;EACnC,IAAI,YAAY,YAAY,OAAO;EACnC,IAAI,CAAC,QAAQ,gBAAgB,EAAE,SAAS,OAAO,GAAG,OAAO;EACzD,OAAO;CACT,GAAG,CAAC,SAAS,EAAE,CAAC;CAEhB,MAAM,gBAAgB,QAAQ,eAAe,OAAO;CACpD,MAAM,YAAY,GAChB,mBACA,iBAAiB,QAAQ,SAAS,SAClC,SAAS,iBAAiB,KAAK,MAAM,UAAU,IAC/C,UAAU,OAAO,gBAAgB,IAEjC,WACG,SAAS,OACN,iBAAiB,KAAK,KAAK,UAC3B,iBAAiB,KAAK,GAAG,UAC/B,mBACF;CAGA,IAAI,kBAAkB,aAAa,kBAAkB,OACnD,OACE,oBAAC,cAAD;EACO;EACL,IAAI;EACJ,MAAM;EACQ;EACH;EACX,OAAO;EACP,GAAI;EAEH;CACW,CAAA;CAKlB,OACE,oBAAC,WAAD;EACO;EACM;EACX,OAAO;EACP,GAAI;EAEH;CACQ,CAAA;AAEf;AAEA,IAAa,OAAO,WAAW,KAAK;AAOpC,KAAmC,cAAc"}
|
|
@@ -12,6 +12,9 @@ var DEFAULT_VARIANTS = {
|
|
|
12
12
|
animate: { rotateX: 0 }
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
|
+
var DEFAULT_TRANSITION = { ease: "easeIn" };
|
|
16
|
+
var defaultEnterDelay = (index) => index * .1;
|
|
17
|
+
var defaultExitDelay = (index) => index * .1 + .2;
|
|
15
18
|
/**
|
|
16
19
|
* Letter-by-letter roll animation. Each character flips on the X axis: the
|
|
17
20
|
* current letter rolls up and out, the new letter rolls in from below.
|
|
@@ -27,7 +30,7 @@ var DEFAULT_VARIANTS = {
|
|
|
27
30
|
* <TextRoll key={title}>{title}</TextRoll>
|
|
28
31
|
* ```
|
|
29
32
|
*/
|
|
30
|
-
function TextRoll({ children, duration = .5, getEnterDelay =
|
|
33
|
+
function TextRoll({ children, duration = .5, getEnterDelay = defaultEnterDelay, getExitDelay = defaultExitDelay, className, transition = DEFAULT_TRANSITION, variants, onAnimationComplete }) {
|
|
31
34
|
const letters = children.split("");
|
|
32
35
|
return /* @__PURE__ */ jsxs("span", {
|
|
33
36
|
className,
|
|
@@ -76,4 +79,4 @@ TextRoll.displayName = "TextRoll";
|
|
|
76
79
|
//#endregion
|
|
77
80
|
export { TextRoll as t };
|
|
78
81
|
|
|
79
|
-
//# sourceMappingURL=text-roll-
|
|
82
|
+
//# sourceMappingURL=text-roll-C3U2jd2u.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-roll-C3U2jd2u.js","names":[],"sources":["../src/components/text-roll/text-roll.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n motion,\n type Target,\n type TargetAndTransition,\n type Transition,\n type VariantLabels,\n} from \"motion/react\";\n\nexport type TextRollVariants = {\n enter: {\n initial: Target | VariantLabels | boolean;\n animate: TargetAndTransition | VariantLabels;\n };\n exit: {\n initial: Target | VariantLabels | boolean;\n animate: TargetAndTransition | VariantLabels;\n };\n};\n\nexport type TextRollProps = {\n /** Text to animate. Each character rolls in / out independently. */\n children: string;\n /** Duration (seconds) of each letter's enter and exit tween. */\n duration?: number;\n /** Per-letter delay for the enter animation. */\n getEnterDelay?: (index: number) => number;\n /** Per-letter delay for the exit animation. */\n getExitDelay?: (index: number) => number;\n /** Additional CSS classes merged via `cn()`. Use sf semantic tokens only. */\n className?: string;\n /** Shared transition for both enter and exit tweens. */\n transition?: Transition;\n /** Override the default rotate-X roll with custom enter/exit variants. */\n variants?: TextRollVariants;\n /** Fires once the last letter's exit animation finishes. */\n onAnimationComplete?: () => void;\n};\n\nconst DEFAULT_VARIANTS: TextRollVariants = {\n enter: {\n initial: { rotateX: 0 },\n animate: { rotateX: 90 },\n },\n exit: {\n initial: { rotateX: 90 },\n animate: { rotateX: 0 },\n },\n};\n\nconst DEFAULT_TRANSITION: Transition = { ease: \"easeIn\" };\nconst defaultEnterDelay = (index: number) => index * 0.1;\nconst defaultExitDelay = (index: number) => index * 0.1 + 0.2;\n\n/**\n * Letter-by-letter roll animation. Each character flips on the X axis: the\n * current letter rolls up and out, the new letter rolls in from below.\n * Good for title changes (e.g. a streaming activity group swapping its\n * current-step label) where the text content is short and the change should\n * register visually.\n *\n * Wraps the string in an `aria-hidden` visual stack with a screen-reader-only\n * copy of the full text so a11y tools always read the real content.\n *\n * @example\n * ```tsx\n * <TextRoll key={title}>{title}</TextRoll>\n * ```\n */\nexport function TextRoll({\n children,\n duration = 0.5,\n getEnterDelay = defaultEnterDelay,\n getExitDelay = defaultExitDelay,\n className,\n transition = DEFAULT_TRANSITION,\n variants,\n onAnimationComplete,\n}: TextRollProps) {\n const letters = children.split(\"\");\n\n return (\n <span className={className}>\n {letters.map((letter, i) => {\n const display = letter === \" \" ? \"\\u00A0\" : letter;\n return (\n <span\n aria-hidden=\"true\"\n className=\"relative inline-block [perspective:10000px] [transform-style:preserve-3d] [width:auto]\"\n // Using index is intentional — letters are positional.\n // biome-ignore lint/suspicious/noArrayIndexKey: positional char animation\n key={i}\n >\n <motion.span\n animate={\n variants?.enter?.animate ?? DEFAULT_VARIANTS.enter.animate\n }\n className=\"absolute inline-block [backface-visibility:hidden] [transform-origin:50%_25%]\"\n initial={\n variants?.enter?.initial ?? DEFAULT_VARIANTS.enter.initial\n }\n transition={{\n ...transition,\n duration,\n delay: getEnterDelay(i),\n }}\n >\n {display}\n </motion.span>\n <motion.span\n animate={variants?.exit?.animate ?? DEFAULT_VARIANTS.exit.animate}\n className=\"absolute inline-block [backface-visibility:hidden] [transform-origin:50%_100%]\"\n initial={variants?.exit?.initial ?? DEFAULT_VARIANTS.exit.initial}\n onAnimationComplete={\n letters.length === i + 1 ? onAnimationComplete : undefined\n }\n transition={{\n ...transition,\n duration,\n delay: getExitDelay(i),\n }}\n >\n {display}\n </motion.span>\n <span className=\"invisible\">{display}</span>\n </span>\n );\n })}\n <span className=\"sr-only\">{children}</span>\n </span>\n );\n}\n\nTextRoll.displayName = \"TextRoll\";\n"],"mappings":";;;;AAwCA,IAAM,mBAAqC;CACzC,OAAO;EACL,SAAS,EAAE,SAAS,EAAE;EACtB,SAAS,EAAE,SAAS,GAAG;CACzB;CACA,MAAM;EACJ,SAAS,EAAE,SAAS,GAAG;EACvB,SAAS,EAAE,SAAS,EAAE;CACxB;AACF;AAEA,IAAM,qBAAiC,EAAE,MAAM,SAAS;AACxD,IAAM,qBAAqB,UAAkB,QAAQ;AACrD,IAAM,oBAAoB,UAAkB,QAAQ,KAAM;;;;;;;;;;;;;;;;AAiB1D,SAAgB,SAAS,EACvB,UACA,WAAW,IACX,gBAAgB,mBAChB,eAAe,kBACf,WACA,aAAa,oBACb,UACA,uBACgB;CAChB,MAAM,UAAU,SAAS,MAAM,EAAE;CAEjC,OACE,qBAAC,QAAD;EAAiB;YAAjB,CACG,QAAQ,KAAK,QAAQ,MAAM;GAC1B,MAAM,UAAU,WAAW,MAAM,SAAW;GAC5C,OACE,qBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAFZ;KAOE,oBAAC,OAAO,MAAR;MACE,SACE,UAAU,OAAO,WAAW,iBAAiB,MAAM;MAErD,WAAU;MACV,SACE,UAAU,OAAO,WAAW,iBAAiB,MAAM;MAErD,YAAY;OACV,GAAG;OACH;OACA,OAAO,cAAc,CAAC;MACxB;gBAEC;KACU,CAAA;KACb,oBAAC,OAAO,MAAR;MACE,SAAS,UAAU,MAAM,WAAW,iBAAiB,KAAK;MAC1D,WAAU;MACV,SAAS,UAAU,MAAM,WAAW,iBAAiB,KAAK;MAC1D,qBACE,QAAQ,WAAW,IAAI,IAAI,sBAAsB,KAAA;MAEnD,YAAY;OACV,GAAG;OACH;OACA,OAAO,aAAa,CAAC;MACvB;gBAEC;KACU,CAAA;KACb,oBAAC,QAAD;MAAM,WAAU;gBAAa;KAAc,CAAA;IACvC;MAlCC,CAkCD;EAEV,CAAC,GACD,oBAAC,QAAD;GAAM,WAAU;GAAW;EAAe,CAAA,CACtC;;AAEV;AAEA,SAAS,cAAc"}
|