@dowel-ui/react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/blocks/admin-users/meta.js +27 -0
- package/dist/blocks/admin-users/meta.js.map +1 -0
- package/dist/blocks/ai-chat/meta.js +30 -0
- package/dist/blocks/ai-chat/meta.js.map +1 -0
- package/dist/blocks/dashboard/meta.js +23 -0
- package/dist/blocks/dashboard/meta.js.map +1 -0
- package/dist/blocks/forgot-password/meta.js +24 -0
- package/dist/blocks/forgot-password/meta.js.map +1 -0
- package/dist/blocks/login/meta.js +26 -0
- package/dist/blocks/login/meta.js.map +1 -0
- package/dist/blocks/pricing/meta.js +24 -0
- package/dist/blocks/pricing/meta.js.map +1 -0
- package/dist/blocks/settings/meta.js +29 -0
- package/dist/blocks/settings/meta.js.map +1 -0
- package/dist/blocks/signup/meta.js +25 -0
- package/dist/blocks/signup/meta.js.map +1 -0
- package/dist/components/accordion/accordion.d.ts +19 -0
- package/dist/components/accordion/accordion.d.ts.map +1 -0
- package/dist/components/accordion/accordion.js +58 -0
- package/dist/components/accordion/accordion.js.map +1 -0
- package/dist/components/accordion/index.d.ts +2 -0
- package/dist/components/accordion/index.js +2 -0
- package/dist/components/accordion/meta.js +17 -0
- package/dist/components/accordion/meta.js.map +1 -0
- package/dist/components/activity-feed/activity-feed.d.ts +39 -0
- package/dist/components/activity-feed/activity-feed.d.ts.map +1 -0
- package/dist/components/activity-feed/activity-feed.js +77 -0
- package/dist/components/activity-feed/activity-feed.js.map +1 -0
- package/dist/components/activity-feed/index.d.ts +2 -0
- package/dist/components/activity-feed/index.js +2 -0
- package/dist/components/activity-feed/meta.js +17 -0
- package/dist/components/activity-feed/meta.js.map +1 -0
- package/dist/components/ai-agent-status/ai-agent-status.d.ts +30 -0
- package/dist/components/ai-agent-status/ai-agent-status.d.ts.map +1 -0
- package/dist/components/ai-agent-status/ai-agent-status.js +43 -0
- package/dist/components/ai-agent-status/ai-agent-status.js.map +1 -0
- package/dist/components/ai-agent-status/index.d.ts +2 -0
- package/dist/components/ai-agent-status/index.js +2 -0
- package/dist/components/ai-agent-status/meta.js +17 -0
- package/dist/components/ai-agent-status/meta.js.map +1 -0
- package/dist/components/ai-conversation/ai-conversation.d.ts +45 -0
- package/dist/components/ai-conversation/ai-conversation.d.ts.map +1 -0
- package/dist/components/ai-conversation/ai-conversation.js +138 -0
- package/dist/components/ai-conversation/ai-conversation.js.map +1 -0
- package/dist/components/ai-conversation/index.d.ts +2 -0
- package/dist/components/ai-conversation/index.js +2 -0
- package/dist/components/ai-conversation/meta.js +17 -0
- package/dist/components/ai-conversation/meta.js.map +1 -0
- package/dist/components/ai-message/ai-message.d.ts +56 -0
- package/dist/components/ai-message/ai-message.d.ts.map +1 -0
- package/dist/components/ai-message/ai-message.js +90 -0
- package/dist/components/ai-message/ai-message.js.map +1 -0
- package/dist/components/ai-message/index.d.ts +2 -0
- package/dist/components/ai-message/index.js +2 -0
- package/dist/components/ai-message/meta.js +17 -0
- package/dist/components/ai-message/meta.js.map +1 -0
- package/dist/components/ai-model-selector/ai-model-selector.d.ts +42 -0
- package/dist/components/ai-model-selector/ai-model-selector.d.ts.map +1 -0
- package/dist/components/ai-model-selector/ai-model-selector.js +48 -0
- package/dist/components/ai-model-selector/ai-model-selector.js.map +1 -0
- package/dist/components/ai-model-selector/index.d.ts +2 -0
- package/dist/components/ai-model-selector/index.js +2 -0
- package/dist/components/ai-model-selector/meta.js +17 -0
- package/dist/components/ai-model-selector/meta.js.map +1 -0
- package/dist/components/ai-prompt-input/ai-prompt-input.d.ts +61 -0
- package/dist/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -0
- package/dist/components/ai-prompt-input/ai-prompt-input.js +170 -0
- package/dist/components/ai-prompt-input/ai-prompt-input.js.map +1 -0
- package/dist/components/ai-prompt-input/index.d.ts +2 -0
- package/dist/components/ai-prompt-input/index.js +2 -0
- package/dist/components/ai-prompt-input/meta.js +17 -0
- package/dist/components/ai-prompt-input/meta.js.map +1 -0
- package/dist/components/ai-reasoning/ai-reasoning.d.ts +24 -0
- package/dist/components/ai-reasoning/ai-reasoning.d.ts.map +1 -0
- package/dist/components/ai-reasoning/ai-reasoning.js +64 -0
- package/dist/components/ai-reasoning/ai-reasoning.js.map +1 -0
- package/dist/components/ai-reasoning/index.d.ts +2 -0
- package/dist/components/ai-reasoning/index.js +2 -0
- package/dist/components/ai-reasoning/meta.js +17 -0
- package/dist/components/ai-reasoning/meta.js.map +1 -0
- package/dist/components/ai-response/ai-response.d.ts +36 -0
- package/dist/components/ai-response/ai-response.d.ts.map +1 -0
- package/dist/components/ai-response/ai-response.js +46 -0
- package/dist/components/ai-response/ai-response.js.map +1 -0
- package/dist/components/ai-response/index.d.ts +2 -0
- package/dist/components/ai-response/index.js +2 -0
- package/dist/components/ai-response/meta.js +17 -0
- package/dist/components/ai-response/meta.js.map +1 -0
- package/dist/components/ai-sources/ai-sources.d.ts +44 -0
- package/dist/components/ai-sources/ai-sources.d.ts.map +1 -0
- package/dist/components/ai-sources/ai-sources.js +112 -0
- package/dist/components/ai-sources/ai-sources.js.map +1 -0
- package/dist/components/ai-sources/index.d.ts +2 -0
- package/dist/components/ai-sources/index.js +2 -0
- package/dist/components/ai-sources/meta.js +17 -0
- package/dist/components/ai-sources/meta.js.map +1 -0
- package/dist/components/ai-token-usage/ai-token-usage.d.ts +34 -0
- package/dist/components/ai-token-usage/ai-token-usage.d.ts.map +1 -0
- package/dist/components/ai-token-usage/ai-token-usage.js +58 -0
- package/dist/components/ai-token-usage/ai-token-usage.js.map +1 -0
- package/dist/components/ai-token-usage/index.d.ts +2 -0
- package/dist/components/ai-token-usage/index.js +2 -0
- package/dist/components/ai-token-usage/meta.js +17 -0
- package/dist/components/ai-token-usage/meta.js.map +1 -0
- package/dist/components/ai-tool/ai-tool.d.ts +50 -0
- package/dist/components/ai-tool/ai-tool.d.ts.map +1 -0
- package/dist/components/ai-tool/ai-tool.js +129 -0
- package/dist/components/ai-tool/ai-tool.js.map +1 -0
- package/dist/components/ai-tool/index.d.ts +2 -0
- package/dist/components/ai-tool/index.js +2 -0
- package/dist/components/ai-tool/meta.js +17 -0
- package/dist/components/ai-tool/meta.js.map +1 -0
- package/dist/components/alert/alert.d.ts +32 -0
- package/dist/components/alert/alert.d.ts.map +1 -0
- package/dist/components/alert/alert.js +49 -0
- package/dist/components/alert/alert.js.map +1 -0
- package/dist/components/alert/index.d.ts +2 -0
- package/dist/components/alert/index.js +2 -0
- package/dist/components/alert/meta.js +17 -0
- package/dist/components/alert/meta.js.map +1 -0
- package/dist/components/avatar/avatar.d.ts +23 -0
- package/dist/components/avatar/avatar.d.ts.map +1 -0
- package/dist/components/avatar/avatar.js +44 -0
- package/dist/components/avatar/avatar.js.map +1 -0
- package/dist/components/avatar/index.d.ts +2 -0
- package/dist/components/avatar/index.js +2 -0
- package/dist/components/avatar/meta.js +17 -0
- package/dist/components/avatar/meta.js.map +1 -0
- package/dist/components/badge/badge.d.ts +20 -0
- package/dist/components/badge/badge.d.ts.map +1 -0
- package/dist/components/badge/badge.js +47 -0
- package/dist/components/badge/badge.js.map +1 -0
- package/dist/components/badge/index.d.ts +2 -0
- package/dist/components/badge/index.js +2 -0
- package/dist/components/badge/meta.js +17 -0
- package/dist/components/badge/meta.js.map +1 -0
- package/dist/components/button/button.d.ts +28 -0
- package/dist/components/button/button.d.ts.map +1 -0
- package/dist/components/button/button.js +77 -0
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/button/index.js +2 -0
- package/dist/components/button/meta.js +17 -0
- package/dist/components/button/meta.js.map +1 -0
- package/dist/components/calendar/calendar.d.ts +16 -0
- package/dist/components/calendar/calendar.d.ts.map +1 -0
- package/dist/components/calendar/calendar.js +70 -0
- package/dist/components/calendar/calendar.js.map +1 -0
- package/dist/components/calendar/index.d.ts +2 -0
- package/dist/components/calendar/index.js +2 -0
- package/dist/components/calendar/meta.js +17 -0
- package/dist/components/calendar/meta.js.map +1 -0
- package/dist/components/card/card.d.ts +23 -0
- package/dist/components/card/card.d.ts.map +1 -0
- package/dist/components/card/card.js +53 -0
- package/dist/components/card/card.js.map +1 -0
- package/dist/components/card/index.d.ts +2 -0
- package/dist/components/card/index.js +2 -0
- package/dist/components/card/meta.js +17 -0
- package/dist/components/card/meta.js.map +1 -0
- package/dist/components/checkbox/checkbox.d.ts +15 -0
- package/dist/components/checkbox/checkbox.d.ts.map +1 -0
- package/dist/components/checkbox/checkbox.js +45 -0
- package/dist/components/checkbox/checkbox.js.map +1 -0
- package/dist/components/checkbox/index.d.ts +2 -0
- package/dist/components/checkbox/index.js +2 -0
- package/dist/components/checkbox/meta.js +17 -0
- package/dist/components/checkbox/meta.js.map +1 -0
- package/dist/components/code-block/code-block.d.ts +46 -0
- package/dist/components/code-block/code-block.d.ts.map +1 -0
- package/dist/components/code-block/code-block.js +110 -0
- package/dist/components/code-block/code-block.js.map +1 -0
- package/dist/components/code-block/index.d.ts +2 -0
- package/dist/components/code-block/index.js +2 -0
- package/dist/components/code-block/meta.js +17 -0
- package/dist/components/code-block/meta.js.map +1 -0
- package/dist/components/combobox/combobox.d.ts +59 -0
- package/dist/components/combobox/combobox.d.ts.map +1 -0
- package/dist/components/combobox/combobox.js +346 -0
- package/dist/components/combobox/combobox.js.map +1 -0
- package/dist/components/combobox/index.d.ts +2 -0
- package/dist/components/combobox/index.js +2 -0
- package/dist/components/combobox/meta.js +17 -0
- package/dist/components/combobox/meta.js.map +1 -0
- package/dist/components/command/command.d.ts +65 -0
- package/dist/components/command/command.d.ts.map +1 -0
- package/dist/components/command/command.js +330 -0
- package/dist/components/command/command.js.map +1 -0
- package/dist/components/command/index.d.ts +2 -0
- package/dist/components/command/index.js +2 -0
- package/dist/components/command/meta.js +17 -0
- package/dist/components/command/meta.js.map +1 -0
- package/dist/components/data-table/data-table.d.ts +91 -0
- package/dist/components/data-table/data-table.d.ts.map +1 -0
- package/dist/components/data-table/data-table.js +263 -0
- package/dist/components/data-table/data-table.js.map +1 -0
- package/dist/components/data-table/index.d.ts +2 -0
- package/dist/components/data-table/index.js +2 -0
- package/dist/components/data-table/meta.js +22 -0
- package/dist/components/data-table/meta.js.map +1 -0
- package/dist/components/date-picker/date-picker.d.ts +31 -0
- package/dist/components/date-picker/date-picker.d.ts.map +1 -0
- package/dist/components/date-picker/date-picker.js +123 -0
- package/dist/components/date-picker/date-picker.js.map +1 -0
- package/dist/components/date-picker/index.d.ts +2 -0
- package/dist/components/date-picker/index.js +2 -0
- package/dist/components/date-picker/meta.js +21 -0
- package/dist/components/date-picker/meta.js.map +1 -0
- package/dist/components/dialog/dialog.d.ts +30 -0
- package/dist/components/dialog/dialog.d.ts.map +1 -0
- package/dist/components/dialog/dialog.js +79 -0
- package/dist/components/dialog/dialog.js.map +1 -0
- package/dist/components/dialog/index.d.ts +2 -0
- package/dist/components/dialog/index.js +2 -0
- package/dist/components/dialog/meta.js +17 -0
- package/dist/components/dialog/meta.js.map +1 -0
- package/dist/components/drawer/drawer.d.ts +32 -0
- package/dist/components/drawer/drawer.d.ts.map +1 -0
- package/dist/components/drawer/drawer.js +153 -0
- package/dist/components/drawer/drawer.js.map +1 -0
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/drawer/index.js +2 -0
- package/dist/components/drawer/meta.js +17 -0
- package/dist/components/drawer/meta.js.map +1 -0
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +43 -0
- package/dist/components/dropdown-menu/dropdown-menu.d.ts.map +1 -0
- package/dist/components/dropdown-menu/dropdown-menu.js +130 -0
- package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -0
- package/dist/components/dropdown-menu/index.d.ts +2 -0
- package/dist/components/dropdown-menu/index.js +2 -0
- package/dist/components/dropdown-menu/meta.js +17 -0
- package/dist/components/dropdown-menu/meta.js.map +1 -0
- package/dist/components/empty-state/empty-state.d.ts +24 -0
- package/dist/components/empty-state/empty-state.d.ts.map +1 -0
- package/dist/components/empty-state/empty-state.js +73 -0
- package/dist/components/empty-state/empty-state.js.map +1 -0
- package/dist/components/empty-state/index.d.ts +2 -0
- package/dist/components/empty-state/index.js +2 -0
- package/dist/components/empty-state/meta.js +17 -0
- package/dist/components/empty-state/meta.js.map +1 -0
- package/dist/components/form/form.d.ts +43 -0
- package/dist/components/form/form.d.ts.map +1 -0
- package/dist/components/form/form.js +127 -0
- package/dist/components/form/form.js.map +1 -0
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.js +2 -0
- package/dist/components/form/meta.js +17 -0
- package/dist/components/form/meta.js.map +1 -0
- package/dist/components/input/index.d.ts +2 -0
- package/dist/components/input/index.js +2 -0
- package/dist/components/input/input.d.ts +21 -0
- package/dist/components/input/input.d.ts.map +1 -0
- package/dist/components/input/input.js +34 -0
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/input/meta.js +17 -0
- package/dist/components/input/meta.js.map +1 -0
- package/dist/components/label/index.d.ts +2 -0
- package/dist/components/label/index.js +2 -0
- package/dist/components/label/label.d.ts +14 -0
- package/dist/components/label/label.d.ts.map +1 -0
- package/dist/components/label/label.js +20 -0
- package/dist/components/label/label.js.map +1 -0
- package/dist/components/label/meta.js +17 -0
- package/dist/components/label/meta.js.map +1 -0
- package/dist/components/pagination/index.d.ts +2 -0
- package/dist/components/pagination/index.js +2 -0
- package/dist/components/pagination/meta.js +17 -0
- package/dist/components/pagination/meta.js.map +1 -0
- package/dist/components/pagination/pagination.d.ts +33 -0
- package/dist/components/pagination/pagination.d.ts.map +1 -0
- package/dist/components/pagination/pagination.js +143 -0
- package/dist/components/pagination/pagination.js.map +1 -0
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/popover/index.js +2 -0
- package/dist/components/popover/meta.js +17 -0
- package/dist/components/popover/meta.js.map +1 -0
- package/dist/components/popover/popover.d.ts +24 -0
- package/dist/components/popover/popover.d.ts.map +1 -0
- package/dist/components/popover/popover.js +60 -0
- package/dist/components/popover/popover.js.map +1 -0
- package/dist/components/progress/index.d.ts +2 -0
- package/dist/components/progress/index.js +2 -0
- package/dist/components/progress/meta.js +17 -0
- package/dist/components/progress/meta.js.map +1 -0
- package/dist/components/progress/progress.d.ts +21 -0
- package/dist/components/progress/progress.d.ts.map +1 -0
- package/dist/components/progress/progress.js +55 -0
- package/dist/components/progress/progress.js.map +1 -0
- package/dist/components/radio-group/index.d.ts +2 -0
- package/dist/components/radio-group/index.js +2 -0
- package/dist/components/radio-group/meta.js +17 -0
- package/dist/components/radio-group/meta.js.map +1 -0
- package/dist/components/radio-group/radio-group.d.ts +17 -0
- package/dist/components/radio-group/radio-group.d.ts.map +1 -0
- package/dist/components/radio-group/radio-group.js +29 -0
- package/dist/components/radio-group/radio-group.js.map +1 -0
- package/dist/components/select/index.d.ts +2 -0
- package/dist/components/select/index.js +2 -0
- package/dist/components/select/meta.js +17 -0
- package/dist/components/select/meta.js.map +1 -0
- package/dist/components/select/select.d.ts +37 -0
- package/dist/components/select/select.d.ts.map +1 -0
- package/dist/components/select/select.js +128 -0
- package/dist/components/select/select.js.map +1 -0
- package/dist/components/separator/index.d.ts +2 -0
- package/dist/components/separator/index.js +2 -0
- package/dist/components/separator/meta.js +17 -0
- package/dist/components/separator/meta.js.map +1 -0
- package/dist/components/separator/separator.d.ts +15 -0
- package/dist/components/separator/separator.d.ts.map +1 -0
- package/dist/components/separator/separator.js +23 -0
- package/dist/components/separator/separator.js.map +1 -0
- package/dist/components/sheet/index.d.ts +2 -0
- package/dist/components/sheet/index.js +2 -0
- package/dist/components/sheet/meta.js +17 -0
- package/dist/components/sheet/meta.js.map +1 -0
- package/dist/components/sheet/sheet.d.ts +31 -0
- package/dist/components/sheet/sheet.d.ts.map +1 -0
- package/dist/components/sheet/sheet.js +90 -0
- package/dist/components/sheet/sheet.js.map +1 -0
- package/dist/components/skeleton/index.d.ts +2 -0
- package/dist/components/skeleton/index.js +2 -0
- package/dist/components/skeleton/meta.js +17 -0
- package/dist/components/skeleton/meta.js.map +1 -0
- package/dist/components/skeleton/skeleton.d.ts +20 -0
- package/dist/components/skeleton/skeleton.d.ts.map +1 -0
- package/dist/components/skeleton/skeleton.js +29 -0
- package/dist/components/skeleton/skeleton.js.map +1 -0
- package/dist/components/slider/index.d.ts +2 -0
- package/dist/components/slider/index.js +2 -0
- package/dist/components/slider/meta.js +17 -0
- package/dist/components/slider/meta.js.map +1 -0
- package/dist/components/slider/slider.d.ts +29 -0
- package/dist/components/slider/slider.d.ts.map +1 -0
- package/dist/components/slider/slider.js +61 -0
- package/dist/components/slider/slider.js.map +1 -0
- package/dist/components/spinner/index.d.ts +2 -0
- package/dist/components/spinner/index.js +2 -0
- package/dist/components/spinner/meta.js +17 -0
- package/dist/components/spinner/meta.js.map +1 -0
- package/dist/components/spinner/spinner.d.ts +21 -0
- package/dist/components/spinner/spinner.d.ts.map +1 -0
- package/dist/components/spinner/spinner.js +45 -0
- package/dist/components/spinner/spinner.js.map +1 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/index.js +2 -0
- package/dist/components/switch/meta.js +17 -0
- package/dist/components/switch/meta.js.map +1 -0
- package/dist/components/switch/switch.d.ts +15 -0
- package/dist/components/switch/switch.d.ts.map +1 -0
- package/dist/components/switch/switch.js +21 -0
- package/dist/components/switch/switch.js.map +1 -0
- package/dist/components/table/index.d.ts +2 -0
- package/dist/components/table/index.js +2 -0
- package/dist/components/table/meta.js +17 -0
- package/dist/components/table/meta.js.map +1 -0
- package/dist/components/table/table.d.ts +41 -0
- package/dist/components/table/table.d.ts.map +1 -0
- package/dist/components/table/table.js +78 -0
- package/dist/components/table/table.js.map +1 -0
- package/dist/components/tabs/index.d.ts +2 -0
- package/dist/components/tabs/index.js +2 -0
- package/dist/components/tabs/meta.js +17 -0
- package/dist/components/tabs/meta.js.map +1 -0
- package/dist/components/tabs/tabs.d.ts +28 -0
- package/dist/components/tabs/tabs.d.ts.map +1 -0
- package/dist/components/tabs/tabs.js +58 -0
- package/dist/components/tabs/tabs.js.map +1 -0
- package/dist/components/toast/index.d.ts +3 -0
- package/dist/components/toast/index.js +3 -0
- package/dist/components/toast/meta.js +17 -0
- package/dist/components/toast/meta.js.map +1 -0
- package/dist/components/toast/toast-store.d.ts +84 -0
- package/dist/components/toast/toast-store.d.ts.map +1 -0
- package/dist/components/toast/toast-store.js +115 -0
- package/dist/components/toast/toast-store.js.map +1 -0
- package/dist/components/toast/toast.d.ts +39 -0
- package/dist/components/toast/toast.d.ts.map +1 -0
- package/dist/components/toast/toast.js +140 -0
- package/dist/components/toast/toast.js.map +1 -0
- package/dist/components/tooltip/index.d.ts +2 -0
- package/dist/components/tooltip/index.js +2 -0
- package/dist/components/tooltip/meta.js +17 -0
- package/dist/components/tooltip/meta.js.map +1 -0
- package/dist/components/tooltip/tooltip.d.ts +24 -0
- package/dist/components/tooltip/tooltip.d.ts.map +1 -0
- package/dist/components/tooltip/tooltip.js +38 -0
- package/dist/components/tooltip/tooltip.js.map +1 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.js +51 -0
- package/dist/lib/styles.d.ts +21 -0
- package/dist/lib/styles.d.ts.map +1 -0
- package/dist/lib/styles.js +22 -0
- package/dist/lib/styles.js.map +1 -0
- package/dist/lib/utils.d.ts +11 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +21 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/registry/blocks.d.ts +15 -0
- package/dist/registry/blocks.d.ts.map +1 -0
- package/dist/registry/blocks.js +32 -0
- package/dist/registry/blocks.js.map +1 -0
- package/dist/registry/components.d.ts +18 -0
- package/dist/registry/components.d.ts.map +1 -0
- package/dist/registry/components.js +112 -0
- package/dist/registry/components.js.map +1 -0
- package/dist/registry/schema.d.ts +44 -0
- package/dist/registry/schema.d.ts.map +1 -0
- package/dist/registry/schema.js +33 -0
- package/dist/registry/schema.js.map +1 -0
- package/package.json +74 -0
- package/src/blocks/admin-users/admin-users.stories.tsx +83 -0
- package/src/blocks/admin-users/admin-users.test.tsx +159 -0
- package/src/blocks/admin-users/admin-users.tsx +251 -0
- package/src/blocks/admin-users/index.ts +1 -0
- package/src/blocks/admin-users/meta.ts +27 -0
- package/src/blocks/ai-chat/ai-chat.stories.tsx +149 -0
- package/src/blocks/ai-chat/ai-chat.test.tsx +166 -0
- package/src/blocks/ai-chat/ai-chat.tsx +280 -0
- package/src/blocks/ai-chat/index.ts +7 -0
- package/src/blocks/ai-chat/meta.ts +32 -0
- package/src/blocks/dashboard/dashboard.stories.tsx +106 -0
- package/src/blocks/dashboard/dashboard.test.tsx +94 -0
- package/src/blocks/dashboard/dashboard.tsx +192 -0
- package/src/blocks/dashboard/index.ts +6 -0
- package/src/blocks/dashboard/meta.ts +18 -0
- package/src/blocks/forgot-password/forgot-password.stories.tsx +41 -0
- package/src/blocks/forgot-password/forgot-password.test.tsx +62 -0
- package/src/blocks/forgot-password/forgot-password.tsx +158 -0
- package/src/blocks/forgot-password/index.ts +1 -0
- package/src/blocks/forgot-password/meta.ts +18 -0
- package/src/blocks/login/index.ts +1 -0
- package/src/blocks/login/login.stories.tsx +46 -0
- package/src/blocks/login/login.test.tsx +100 -0
- package/src/blocks/login/login.tsx +178 -0
- package/src/blocks/login/meta.ts +18 -0
- package/src/blocks/pricing/index.ts +1 -0
- package/src/blocks/pricing/meta.ts +18 -0
- package/src/blocks/pricing/pricing.stories.tsx +62 -0
- package/src/blocks/pricing/pricing.test.tsx +101 -0
- package/src/blocks/pricing/pricing.tsx +176 -0
- package/src/blocks/settings/index.ts +6 -0
- package/src/blocks/settings/meta.ts +29 -0
- package/src/blocks/settings/settings.stories.tsx +94 -0
- package/src/blocks/settings/settings.test.tsx +167 -0
- package/src/blocks/settings/settings.tsx +317 -0
- package/src/blocks/signup/index.ts +1 -0
- package/src/blocks/signup/meta.ts +18 -0
- package/src/blocks/signup/signup.stories.tsx +27 -0
- package/src/blocks/signup/signup.test.tsx +97 -0
- package/src/blocks/signup/signup.tsx +240 -0
- package/src/components/accordion/accordion.stories.tsx +90 -0
- package/src/components/accordion/accordion.test.tsx +156 -0
- package/src/components/accordion/accordion.tsx +88 -0
- package/src/components/accordion/index.ts +9 -0
- package/src/components/accordion/meta.ts +16 -0
- package/src/components/activity-feed/activity-feed.stories.tsx +163 -0
- package/src/components/activity-feed/activity-feed.test.tsx +125 -0
- package/src/components/activity-feed/activity-feed.tsx +115 -0
- package/src/components/activity-feed/index.ts +12 -0
- package/src/components/activity-feed/meta.ts +17 -0
- package/src/components/ai-agent-status/ai-agent-status.stories.tsx +86 -0
- package/src/components/ai-agent-status/ai-agent-status.test.tsx +66 -0
- package/src/components/ai-agent-status/ai-agent-status.tsx +88 -0
- package/src/components/ai-agent-status/index.ts +6 -0
- package/src/components/ai-agent-status/meta.ts +17 -0
- package/src/components/ai-conversation/ai-conversation.stories.tsx +126 -0
- package/src/components/ai-conversation/ai-conversation.test.tsx +144 -0
- package/src/components/ai-conversation/ai-conversation.tsx +229 -0
- package/src/components/ai-conversation/index.ts +9 -0
- package/src/components/ai-conversation/meta.ts +20 -0
- package/src/components/ai-message/ai-message.stories.tsx +106 -0
- package/src/components/ai-message/ai-message.test.tsx +160 -0
- package/src/components/ai-message/ai-message.tsx +162 -0
- package/src/components/ai-message/index.ts +13 -0
- package/src/components/ai-message/meta.ts +17 -0
- package/src/components/ai-model-selector/ai-model-selector.stories.tsx +66 -0
- package/src/components/ai-model-selector/ai-model-selector.test.tsx +120 -0
- package/src/components/ai-model-selector/ai-model-selector.tsx +112 -0
- package/src/components/ai-model-selector/index.ts +1 -0
- package/src/components/ai-model-selector/meta.ts +17 -0
- package/src/components/ai-prompt-input/ai-prompt-input.stories.tsx +145 -0
- package/src/components/ai-prompt-input/ai-prompt-input.test.tsx +273 -0
- package/src/components/ai-prompt-input/ai-prompt-input.tsx +306 -0
- package/src/components/ai-prompt-input/index.ts +11 -0
- package/src/components/ai-prompt-input/meta.ts +18 -0
- package/src/components/ai-reasoning/ai-reasoning.stories.tsx +60 -0
- package/src/components/ai-reasoning/ai-reasoning.test.tsx +95 -0
- package/src/components/ai-reasoning/ai-reasoning.tsx +106 -0
- package/src/components/ai-reasoning/index.ts +7 -0
- package/src/components/ai-reasoning/meta.ts +17 -0
- package/src/components/ai-response/ai-response.stories.tsx +75 -0
- package/src/components/ai-response/ai-response.test.tsx +96 -0
- package/src/components/ai-response/ai-response.tsx +95 -0
- package/src/components/ai-response/index.ts +7 -0
- package/src/components/ai-response/meta.ts +17 -0
- package/src/components/ai-sources/ai-sources.stories.tsx +93 -0
- package/src/components/ai-sources/ai-sources.test.tsx +102 -0
- package/src/components/ai-sources/ai-sources.tsx +186 -0
- package/src/components/ai-sources/index.ts +11 -0
- package/src/components/ai-sources/meta.ts +17 -0
- package/src/components/ai-token-usage/ai-token-usage.stories.tsx +59 -0
- package/src/components/ai-token-usage/ai-token-usage.test.tsx +83 -0
- package/src/components/ai-token-usage/ai-token-usage.tsx +105 -0
- package/src/components/ai-token-usage/index.ts +6 -0
- package/src/components/ai-token-usage/meta.ts +16 -0
- package/src/components/ai-tool/ai-tool.stories.tsx +96 -0
- package/src/components/ai-tool/ai-tool.test.tsx +137 -0
- package/src/components/ai-tool/ai-tool.tsx +235 -0
- package/src/components/ai-tool/index.ts +13 -0
- package/src/components/ai-tool/meta.ts +17 -0
- package/src/components/alert/alert.stories.tsx +101 -0
- package/src/components/alert/alert.test.tsx +94 -0
- package/src/components/alert/alert.tsx +89 -0
- package/src/components/alert/index.ts +8 -0
- package/src/components/alert/meta.ts +16 -0
- package/src/components/avatar/avatar.stories.tsx +58 -0
- package/src/components/avatar/avatar.test.tsx +64 -0
- package/src/components/avatar/avatar.tsx +68 -0
- package/src/components/avatar/index.ts +9 -0
- package/src/components/avatar/meta.ts +15 -0
- package/src/components/badge/badge.stories.tsx +68 -0
- package/src/components/badge/badge.test.tsx +61 -0
- package/src/components/badge/badge.tsx +54 -0
- package/src/components/badge/index.ts +1 -0
- package/src/components/badge/meta.ts +15 -0
- package/src/components/button/button.stories.tsx +128 -0
- package/src/components/button/button.test.tsx +224 -0
- package/src/components/button/button.tsx +114 -0
- package/src/components/button/index.ts +1 -0
- package/src/components/button/meta.ts +16 -0
- package/src/components/calendar/calendar.stories.tsx +105 -0
- package/src/components/calendar/calendar.test.tsx +255 -0
- package/src/components/calendar/calendar.tsx +115 -0
- package/src/components/calendar/index.ts +1 -0
- package/src/components/calendar/meta.ts +17 -0
- package/src/components/card/card.stories.tsx +61 -0
- package/src/components/card/card.test.tsx +66 -0
- package/src/components/card/card.tsx +81 -0
- package/src/components/card/index.ts +9 -0
- package/src/components/card/meta.ts +16 -0
- package/src/components/checkbox/checkbox.stories.tsx +124 -0
- package/src/components/checkbox/checkbox.test.tsx +121 -0
- package/src/components/checkbox/checkbox.tsx +66 -0
- package/src/components/checkbox/index.ts +1 -0
- package/src/components/checkbox/meta.ts +16 -0
- package/src/components/code-block/code-block.stories.tsx +62 -0
- package/src/components/code-block/code-block.test.tsx +139 -0
- package/src/components/code-block/code-block.tsx +188 -0
- package/src/components/code-block/index.ts +1 -0
- package/src/components/code-block/meta.ts +17 -0
- package/src/components/combobox/combobox.stories.tsx +171 -0
- package/src/components/combobox/combobox.test.tsx +429 -0
- package/src/components/combobox/combobox.tsx +544 -0
- package/src/components/combobox/index.ts +15 -0
- package/src/components/combobox/meta.ts +17 -0
- package/src/components/command/command.stories.tsx +152 -0
- package/src/components/command/command.test.tsx +380 -0
- package/src/components/command/command.tsx +482 -0
- package/src/components/command/index.ts +17 -0
- package/src/components/command/meta.ts +18 -0
- package/src/components/data-table/data-table.stories.tsx +151 -0
- package/src/components/data-table/data-table.test.tsx +288 -0
- package/src/components/data-table/data-table.tsx +485 -0
- package/src/components/data-table/index.ts +13 -0
- package/src/components/data-table/meta.ts +19 -0
- package/src/components/date-picker/date-picker.stories.tsx +103 -0
- package/src/components/date-picker/date-picker.test.tsx +205 -0
- package/src/components/date-picker/date-picker.tsx +198 -0
- package/src/components/date-picker/index.ts +6 -0
- package/src/components/date-picker/meta.ts +18 -0
- package/src/components/dialog/dialog.stories.tsx +140 -0
- package/src/components/dialog/dialog.test.tsx +186 -0
- package/src/components/dialog/dialog.tsx +132 -0
- package/src/components/dialog/index.ts +16 -0
- package/src/components/dialog/meta.ts +16 -0
- package/src/components/drawer/drawer.stories.tsx +111 -0
- package/src/components/drawer/drawer.test.tsx +187 -0
- package/src/components/drawer/drawer.tsx +293 -0
- package/src/components/drawer/index.ts +16 -0
- package/src/components/drawer/meta.ts +16 -0
- package/src/components/dropdown-menu/dropdown-menu.stories.tsx +128 -0
- package/src/components/dropdown-menu/dropdown-menu.test.tsx +321 -0
- package/src/components/dropdown-menu/dropdown-menu.tsx +242 -0
- package/src/components/dropdown-menu/index.ts +21 -0
- package/src/components/dropdown-menu/meta.ts +17 -0
- package/src/components/empty-state/empty-state.stories.tsx +70 -0
- package/src/components/empty-state/empty-state.test.tsx +97 -0
- package/src/components/empty-state/empty-state.tsx +92 -0
- package/src/components/empty-state/index.ts +9 -0
- package/src/components/empty-state/meta.ts +16 -0
- package/src/components/form/form.stories.tsx +144 -0
- package/src/components/form/form.test.tsx +203 -0
- package/src/components/form/form.tsx +221 -0
- package/src/components/form/index.ts +13 -0
- package/src/components/form/meta.ts +17 -0
- package/src/components/input/index.ts +1 -0
- package/src/components/input/input.stories.tsx +84 -0
- package/src/components/input/input.test.tsx +108 -0
- package/src/components/input/input.tsx +51 -0
- package/src/components/input/meta.ts +15 -0
- package/src/components/label/index.ts +1 -0
- package/src/components/label/label.stories.tsx +51 -0
- package/src/components/label/label.test.tsx +55 -0
- package/src/components/label/label.tsx +26 -0
- package/src/components/label/meta.ts +15 -0
- package/src/components/pagination/index.ts +10 -0
- package/src/components/pagination/meta.ts +17 -0
- package/src/components/pagination/pagination.stories.tsx +129 -0
- package/src/components/pagination/pagination.test.tsx +119 -0
- package/src/components/pagination/pagination.tsx +142 -0
- package/src/components/popover/index.ts +9 -0
- package/src/components/popover/meta.ts +18 -0
- package/src/components/popover/popover.stories.tsx +84 -0
- package/src/components/popover/popover.test.tsx +163 -0
- package/src/components/popover/popover.tsx +89 -0
- package/src/components/progress/index.ts +1 -0
- package/src/components/progress/meta.ts +17 -0
- package/src/components/progress/progress.stories.tsx +90 -0
- package/src/components/progress/progress.test.tsx +78 -0
- package/src/components/progress/progress.tsx +70 -0
- package/src/components/radio-group/index.ts +6 -0
- package/src/components/radio-group/meta.ts +16 -0
- package/src/components/radio-group/radio-group.stories.tsx +102 -0
- package/src/components/radio-group/radio-group.test.tsx +152 -0
- package/src/components/radio-group/radio-group.tsx +53 -0
- package/src/components/select/index.ts +14 -0
- package/src/components/select/meta.ts +16 -0
- package/src/components/select/select.stories.tsx +137 -0
- package/src/components/select/select.test.tsx +209 -0
- package/src/components/select/select.tsx +222 -0
- package/src/components/separator/index.ts +1 -0
- package/src/components/separator/meta.ts +15 -0
- package/src/components/separator/separator.stories.tsx +42 -0
- package/src/components/separator/separator.test.tsx +46 -0
- package/src/components/separator/separator.tsx +33 -0
- package/src/components/sheet/index.ts +14 -0
- package/src/components/sheet/meta.ts +16 -0
- package/src/components/sheet/sheet.stories.tsx +107 -0
- package/src/components/sheet/sheet.test.tsx +152 -0
- package/src/components/sheet/sheet.tsx +160 -0
- package/src/components/skeleton/index.ts +1 -0
- package/src/components/skeleton/meta.ts +15 -0
- package/src/components/skeleton/skeleton.stories.tsx +46 -0
- package/src/components/skeleton/skeleton.test.tsx +57 -0
- package/src/components/skeleton/skeleton.tsx +28 -0
- package/src/components/slider/index.ts +1 -0
- package/src/components/slider/meta.ts +19 -0
- package/src/components/slider/slider.stories.tsx +87 -0
- package/src/components/slider/slider.test.tsx +148 -0
- package/src/components/slider/slider.tsx +135 -0
- package/src/components/spinner/index.ts +1 -0
- package/src/components/spinner/meta.ts +15 -0
- package/src/components/spinner/spinner.stories.tsx +47 -0
- package/src/components/spinner/spinner.test.tsx +41 -0
- package/src/components/spinner/spinner.tsx +68 -0
- package/src/components/switch/index.ts +1 -0
- package/src/components/switch/meta.ts +15 -0
- package/src/components/switch/switch.stories.tsx +70 -0
- package/src/components/switch/switch.test.tsx +101 -0
- package/src/components/switch/switch.tsx +42 -0
- package/src/components/table/index.ts +11 -0
- package/src/components/table/meta.ts +17 -0
- package/src/components/table/table.stories.tsx +131 -0
- package/src/components/table/table.test.tsx +153 -0
- package/src/components/table/table.tsx +138 -0
- package/src/components/tabs/index.ts +11 -0
- package/src/components/tabs/meta.ts +17 -0
- package/src/components/tabs/tabs.stories.tsx +139 -0
- package/src/components/tabs/tabs.test.tsx +148 -0
- package/src/components/tabs/tabs.tsx +106 -0
- package/src/components/toast/index.ts +24 -0
- package/src/components/toast/meta.ts +18 -0
- package/src/components/toast/toast-store.ts +181 -0
- package/src/components/toast/toast.stories.tsx +167 -0
- package/src/components/toast/toast.test.tsx +306 -0
- package/src/components/toast/toast.tsx +241 -0
- package/src/components/tooltip/index.ts +8 -0
- package/src/components/tooltip/meta.ts +17 -0
- package/src/components/tooltip/tooltip.stories.tsx +89 -0
- package/src/components/tooltip/tooltip.test.tsx +120 -0
- package/src/components/tooltip/tooltip.tsx +58 -0
- package/src/index.ts +50 -0
- package/src/lib/styles.ts +26 -0
- package/src/lib/utils.test.ts +32 -0
- package/src/lib/utils.ts +24 -0
- package/src/registry/blocks.ts +30 -0
- package/src/registry/components.ts +114 -0
- package/src/registry/meta.test.ts +234 -0
- package/src/registry/schema.ts +58 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
//#region src/components/ai-agent-status/ai-agent-status.tsx
|
|
6
|
+
const STATE_LABEL = {
|
|
7
|
+
idle: "Idle",
|
|
8
|
+
thinking: "Thinking",
|
|
9
|
+
working: "Working",
|
|
10
|
+
waiting: "Waiting for input",
|
|
11
|
+
done: "Done",
|
|
12
|
+
error: "Error"
|
|
13
|
+
};
|
|
14
|
+
const agentStatusVariants = cva("inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium", {
|
|
15
|
+
variants: { state: {
|
|
16
|
+
idle: "border-border bg-muted text-muted-foreground",
|
|
17
|
+
thinking: "border-info/30 bg-info/10 text-info",
|
|
18
|
+
working: "border-primary/30 bg-primary/10 text-primary",
|
|
19
|
+
waiting: "border-warning/35 bg-warning/10 text-warning",
|
|
20
|
+
done: "border-success/30 bg-success/10 text-success",
|
|
21
|
+
error: "border-destructive/30 bg-destructive/10 text-destructive"
|
|
22
|
+
} },
|
|
23
|
+
defaultVariants: { state: "idle" }
|
|
24
|
+
});
|
|
25
|
+
function AgentStatus({ className, state = "idle", label, live = false, children, ...props }) {
|
|
26
|
+
const busy = state === "thinking" || state === "working";
|
|
27
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
28
|
+
"data-slot": "agent-status",
|
|
29
|
+
"data-state": state,
|
|
30
|
+
role: live ? "status" : void 0,
|
|
31
|
+
"aria-live": live ? "polite" : void 0,
|
|
32
|
+
className: cn(agentStatusVariants({ state }), className),
|
|
33
|
+
...props,
|
|
34
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
35
|
+
"aria-hidden": "true",
|
|
36
|
+
className: cn("size-1.5 rounded-full bg-current", busy && "animate-pulse-soft")
|
|
37
|
+
}), children ?? label ?? STATE_LABEL[state]]
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { AgentStatus, agentStatusVariants };
|
|
42
|
+
|
|
43
|
+
//# sourceMappingURL=ai-agent-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-agent-status.js","names":[],"sources":["../../../src/components/ai-agent-status/ai-agent-status.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * What an agent is doing right now.\n *\n * Always a word, never only a colour. Agent states matter most when something\n * has gone wrong, which is exactly when a colour-only signal fails the people\n * who most need to notice.\n */\n\nexport type AgentState = \"idle\" | \"thinking\" | \"working\" | \"waiting\" | \"done\" | \"error\";\n\nconst STATE_LABEL: Record<AgentState, string> = {\n idle: \"Idle\",\n thinking: \"Thinking\",\n working: \"Working\",\n waiting: \"Waiting for input\",\n done: \"Done\",\n error: \"Error\",\n};\n\nconst agentStatusVariants = cva(\n \"inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium\",\n {\n variants: {\n state: {\n idle: \"border-border bg-muted text-muted-foreground\",\n thinking: \"border-info/30 bg-info/10 text-info\",\n working: \"border-primary/30 bg-primary/10 text-primary\",\n waiting: \"border-warning/35 bg-warning/10 text-warning\",\n done: \"border-success/30 bg-success/10 text-success\",\n error: \"border-destructive/30 bg-destructive/10 text-destructive\",\n },\n },\n defaultVariants: {\n state: \"idle\",\n },\n },\n);\n\nexport interface AgentStatusProps\n extends ComponentPropsWithRef<\"span\">, VariantProps<typeof agentStatusVariants> {\n state?: AgentState;\n /** Overrides the wording. The state must still be readable as text. */\n label?: string;\n /**\n * Announce changes politely.\n *\n * Off by default: several agents each announcing their own transitions turns\n * a dashboard into noise. Turn it on for the one agent the user is watching.\n */\n live?: boolean;\n}\n\nexport function AgentStatus({\n className,\n state = \"idle\",\n label,\n live = false,\n children,\n ...props\n}: AgentStatusProps) {\n const busy = state === \"thinking\" || state === \"working\";\n\n return (\n <span\n data-slot=\"agent-status\"\n data-state={state}\n role={live ? \"status\" : undefined}\n aria-live={live ? \"polite\" : undefined}\n className={cn(agentStatusVariants({ state }), className)}\n {...props}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\"size-1.5 rounded-full bg-current\", busy && \"animate-pulse-soft\")}\n />\n {children ?? label ?? STATE_LABEL[state]}\n </span>\n );\n}\n\nexport { agentStatusVariants };\n"],"mappings":";;;;;AAiBA,MAAM,cAA0C;CAC9C,MAAM;CACN,UAAU;CACV,SAAS;CACT,SAAS;CACT,MAAM;CACN,OAAO;AACT;AAEA,MAAM,sBAAsB,IAC1B,wFACA;CACE,UAAU,EACR,OAAO;EACL,MAAM;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACT,MAAM;EACN,OAAO;CACT,EACF;CACA,iBAAiB,EACf,OAAO,OACT;AACF,CACF;AAgBA,SAAgB,YAAY,EAC1B,WACA,QAAQ,QACR,OACA,OAAO,OACP,UACA,GAAG,SACgB;CACnB,MAAM,OAAO,UAAU,cAAc,UAAU;CAE/C,OACE,qBAAC,QAAD;EACE,aAAU;EACV,cAAY;EACZ,MAAM,OAAO,WAAW,KAAA;EACxB,aAAW,OAAO,WAAW,KAAA;EAC7B,WAAW,GAAG,oBAAoB,EAAE,MAAM,CAAC,GAAG,SAAS;EACvD,GAAI;EANN,UAAA,CAQE,oBAAC,QAAD;GACE,eAAY;GACZ,WAAW,GAAG,oCAAoC,QAAQ,oBAAoB;EAC/E,CAAA,GACA,YAAY,SAAS,YAAY,MAC9B;;AAEV"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/components/ai-agent-status/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "ai-agent-status",
|
|
5
|
+
title: "AI Agent Status",
|
|
6
|
+
description: "A pill showing what an agent is doing, in words as well as colour.",
|
|
7
|
+
category: "ai",
|
|
8
|
+
status: "stable",
|
|
9
|
+
dependencies: ["class-variance-authority"],
|
|
10
|
+
registryDependencies: [],
|
|
11
|
+
files: ["ai-agent-status.tsx"],
|
|
12
|
+
a11y: "The state is always text. Agent states matter most when something has failed, which is exactly when a colour-only signal fails the people who most need to see it. Live announcements are off by default — several agents each announcing their transitions turns a dashboard into noise; enable it for the one agent being watched."
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { meta };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/components/ai-agent-status/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"ai-agent-status\",\n title: \"AI Agent Status\",\n description: \"A pill showing what an agent is doing, in words as well as colour.\",\n category: \"ai\",\n status: \"stable\",\n dependencies: [\"class-variance-authority\"],\n registryDependencies: [],\n files: [\"ai-agent-status.tsx\"],\n a11y:\n \"The state is always text. Agent states matter most when something has failed, which is \" +\n \"exactly when a colour-only signal fails the people who most need to see it. Live \" +\n \"announcements are off by default — several agents each announcing their transitions turns a \" +\n \"dashboard into noise; enable it for the one agent being watched.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,OAAO;CACP,aAAa;CACb,UAAU;CACV,QAAQ;CACR,cAAc,CAAC,0BAA0B;CACzC,sBAAsB,CAAC;CACvB,OAAO,CAAC,qBAAqB;CAC7B,MACE;AAIJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, ReactNode } from "react";
|
|
2
|
+
//#region src/components/ai-conversation/ai-conversation.d.ts
|
|
3
|
+
interface ConversationProps extends ComponentPropsWithRef<"div"> {
|
|
4
|
+
/**
|
|
5
|
+
* Follow new content while the reader is at the bottom.
|
|
6
|
+
*
|
|
7
|
+
* Turning this off never scrolls automatically; it does not pin the view.
|
|
8
|
+
*/
|
|
9
|
+
autoScroll?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare function Conversation({ className, autoScroll, children, ...props }: ConversationProps): import("react").JSX.Element;
|
|
12
|
+
/**
|
|
13
|
+
* The transcript.
|
|
14
|
+
*
|
|
15
|
+
* An ordered list, deliberately not a live region — see the note on
|
|
16
|
+
* `Conversation`. Order is meaning here, and list semantics give a screen
|
|
17
|
+
* reader user position and count ("3 of 12") as they move through it.
|
|
18
|
+
*/
|
|
19
|
+
declare function ConversationMessages({ className, ...props }: ComponentPropsWithRef<"ol">): import("react").JSX.Element;
|
|
20
|
+
interface ConversationStatusProps extends ComponentPropsWithRef<"div"> {
|
|
21
|
+
/** Announced politely when it changes. Keep it short: state, never content. */
|
|
22
|
+
children?: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A polite live region for conversation state.
|
|
26
|
+
*
|
|
27
|
+
* This is where "generating response" and "response complete" belong. Putting
|
|
28
|
+
* the response *text* here instead is the mistake this component exists to
|
|
29
|
+
* prevent.
|
|
30
|
+
*/
|
|
31
|
+
declare function ConversationStatus({ className, children, ...props }: ConversationStatusProps): import("react").JSX.Element;
|
|
32
|
+
interface ConversationScrollButtonProps extends ComponentPropsWithRef<"button"> {
|
|
33
|
+
label?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns the reader to the newest message.
|
|
37
|
+
*
|
|
38
|
+
* Rendered only when they have scrolled away, and removed from the DOM
|
|
39
|
+
* otherwise so it is never a focus stop pointing at where the reader already
|
|
40
|
+
* is.
|
|
41
|
+
*/
|
|
42
|
+
declare function ConversationScrollButton({ className, label, ...props }: ConversationScrollButtonProps): import("react").JSX.Element | null;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { Conversation, ConversationMessages, ConversationProps, ConversationScrollButton, ConversationScrollButtonProps, ConversationStatus, ConversationStatusProps };
|
|
45
|
+
//# sourceMappingURL=ai-conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-conversation.d.ts","names":[],"sources":["../../../src/components/ai-conversation/ai-conversation.tsx"],"mappings":";;UAuDiB,0BAA0B;;;;;;EAMzC;;iBAGc,eACd,WACA,YACA,aACG,SACF,oCAAiB,IAAA;;;;;;;;iBA4EJ,uBAAuB,cAAc,SAAS,8CAA2B,IAAA;UAUxE,gCAAgC;;EAE/C,WAAW;;;;;;;;;iBAUG,qBAAqB,WAAW,aAAa,SAAS,0CAAuB,IAAA;UAc5E,sCAAsC;EACrD;;;;;;;;;iBAUc,2BACd,WACA,UACG,SACF,gDAA6B,IAAA"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
//#region src/components/ai-conversation/ai-conversation.tsx
|
|
6
|
+
const ConversationContext = createContext(null);
|
|
7
|
+
function useConversation(component) {
|
|
8
|
+
const context = useContext(ConversationContext);
|
|
9
|
+
if (!context) throw new Error(`${component} must be rendered inside <Conversation>.`);
|
|
10
|
+
return context;
|
|
11
|
+
}
|
|
12
|
+
/** How close to the bottom still counts as "at the bottom", in pixels. */
|
|
13
|
+
const BOTTOM_THRESHOLD = 32;
|
|
14
|
+
function Conversation({ className, autoScroll = true, children, ...props }) {
|
|
15
|
+
const viewportRef = useRef(null);
|
|
16
|
+
const [atBottom, setAtBottom] = useState(true);
|
|
17
|
+
const scrollToBottom = useCallback((behavior = "smooth") => {
|
|
18
|
+
const viewport = viewportRef.current;
|
|
19
|
+
if (!viewport) return;
|
|
20
|
+
viewport.scrollTo({
|
|
21
|
+
top: viewport.scrollHeight,
|
|
22
|
+
behavior
|
|
23
|
+
});
|
|
24
|
+
}, []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const viewport = viewportRef.current;
|
|
27
|
+
if (!viewport) return;
|
|
28
|
+
function handleScroll() {
|
|
29
|
+
if (!viewport) return;
|
|
30
|
+
const distance = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;
|
|
31
|
+
setAtBottom(distance <= BOTTOM_THRESHOLD);
|
|
32
|
+
}
|
|
33
|
+
handleScroll();
|
|
34
|
+
viewport.addEventListener("scroll", handleScroll, { passive: true });
|
|
35
|
+
return () => {
|
|
36
|
+
viewport.removeEventListener("scroll", handleScroll);
|
|
37
|
+
};
|
|
38
|
+
}, []);
|
|
39
|
+
useLayoutEffect(() => {
|
|
40
|
+
const viewport = viewportRef.current;
|
|
41
|
+
if (!viewport || !autoScroll) return;
|
|
42
|
+
const observer = new ResizeObserver(() => {
|
|
43
|
+
if (atBottom) viewport.scrollTop = viewport.scrollHeight;
|
|
44
|
+
});
|
|
45
|
+
for (const child of viewport.children) observer.observe(child);
|
|
46
|
+
return () => {
|
|
47
|
+
observer.disconnect();
|
|
48
|
+
};
|
|
49
|
+
}, [autoScroll, atBottom]);
|
|
50
|
+
const context = useMemo(() => ({
|
|
51
|
+
viewportRef,
|
|
52
|
+
atBottom,
|
|
53
|
+
scrollToBottom
|
|
54
|
+
}), [atBottom, scrollToBottom]);
|
|
55
|
+
return /* @__PURE__ */ jsx(ConversationContext.Provider, {
|
|
56
|
+
value: context,
|
|
57
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
58
|
+
"data-slot": "conversation",
|
|
59
|
+
"data-at-bottom": atBottom || void 0,
|
|
60
|
+
className: cn("relative flex min-h-0 flex-1 flex-col", className),
|
|
61
|
+
...props,
|
|
62
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
63
|
+
ref: viewportRef,
|
|
64
|
+
"data-slot": "conversation-viewport",
|
|
65
|
+
className: "flex-1 overflow-y-auto overscroll-contain",
|
|
66
|
+
children
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The transcript.
|
|
73
|
+
*
|
|
74
|
+
* An ordered list, deliberately not a live region — see the note on
|
|
75
|
+
* `Conversation`. Order is meaning here, and list semantics give a screen
|
|
76
|
+
* reader user position and count ("3 of 12") as they move through it.
|
|
77
|
+
*/
|
|
78
|
+
function ConversationMessages({ className, ...props }) {
|
|
79
|
+
return /* @__PURE__ */ jsx("ol", {
|
|
80
|
+
"data-slot": "conversation-messages",
|
|
81
|
+
className: cn("flex flex-col gap-6 p-4", className),
|
|
82
|
+
...props
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A polite live region for conversation state.
|
|
87
|
+
*
|
|
88
|
+
* This is where "generating response" and "response complete" belong. Putting
|
|
89
|
+
* the response *text* here instead is the mistake this component exists to
|
|
90
|
+
* prevent.
|
|
91
|
+
*/
|
|
92
|
+
function ConversationStatus({ className, children, ...props }) {
|
|
93
|
+
return /* @__PURE__ */ jsx("div", {
|
|
94
|
+
"data-slot": "conversation-status",
|
|
95
|
+
role: "status",
|
|
96
|
+
"aria-live": "polite",
|
|
97
|
+
className: cn("px-4 text-xs text-muted-foreground", className),
|
|
98
|
+
...props,
|
|
99
|
+
children
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Returns the reader to the newest message.
|
|
104
|
+
*
|
|
105
|
+
* Rendered only when they have scrolled away, and removed from the DOM
|
|
106
|
+
* otherwise so it is never a focus stop pointing at where the reader already
|
|
107
|
+
* is.
|
|
108
|
+
*/
|
|
109
|
+
function ConversationScrollButton({ className, label = "Jump to latest", ...props }) {
|
|
110
|
+
const { atBottom, scrollToBottom } = useConversation("ConversationScrollButton");
|
|
111
|
+
if (atBottom) return null;
|
|
112
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
113
|
+
type: "button",
|
|
114
|
+
"data-slot": "conversation-scroll-button",
|
|
115
|
+
onClick: () => {
|
|
116
|
+
scrollToBottom();
|
|
117
|
+
},
|
|
118
|
+
className: cn("absolute bottom-3 left-1/2 z-[var(--z-sticky)] flex -translate-x-1/2 items-center gap-1.5", "rounded-full border border-border bg-popover px-3 py-1.5 text-xs font-medium shadow-md", "transition-colors duration-[var(--duration-fast)] hover:bg-accent", "outline-none focus-visible:ring-2 focus-visible:ring-ring/55", className),
|
|
119
|
+
...props,
|
|
120
|
+
children: [/* @__PURE__ */ jsx("svg", {
|
|
121
|
+
viewBox: "0 0 24 24",
|
|
122
|
+
fill: "none",
|
|
123
|
+
"aria-hidden": "true",
|
|
124
|
+
className: "size-3.5",
|
|
125
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
126
|
+
d: "M12 5v14m0 0-6-6m6 6 6-6",
|
|
127
|
+
stroke: "currentColor",
|
|
128
|
+
strokeWidth: "2",
|
|
129
|
+
strokeLinecap: "round",
|
|
130
|
+
strokeLinejoin: "round"
|
|
131
|
+
})
|
|
132
|
+
}), label]
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { Conversation, ConversationMessages, ConversationScrollButton, ConversationStatus };
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=ai-conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-conversation.js","names":[],"sources":["../../../src/components/ai-conversation/ai-conversation.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithRef,\n type ReactNode,\n} from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * The scrolling container for a conversation.\n *\n * Two problems here are easy to get wrong and unpleasant to live with.\n *\n * **Scrolling.** A chat should follow new content, but only while the reader is\n * already at the bottom. The moment someone scrolls up to re-read something,\n * yanking them back down is worse than not following at all — so this tracks\n * whether they are pinned to the bottom and stops following as soon as they are\n * not, offering an explicit way back instead.\n *\n * **Announcements.** The obvious thing is to make the transcript a live region.\n * Do not: a live region that updates on every token produces a stream of\n * interruptions that is unusable with a screen reader, and it is the single\n * most common accessibility failure in chat interfaces. The transcript here is\n * an ordinary list, navigable at the reader's pace, and a *separate* status\n * region announces state — \"generating\", \"response complete\" — never content.\n */\n\ninterface ConversationContextValue {\n viewportRef: React.RefObject<HTMLDivElement | null>;\n atBottom: boolean;\n scrollToBottom: (behavior?: ScrollBehavior) => void;\n}\n\nconst ConversationContext = createContext<ConversationContextValue | null>(null);\n\nfunction useConversation(component: string): ConversationContextValue {\n const context = useContext(ConversationContext);\n if (!context) {\n throw new Error(`${component} must be rendered inside <Conversation>.`);\n }\n return context;\n}\n\n/** How close to the bottom still counts as \"at the bottom\", in pixels. */\nconst BOTTOM_THRESHOLD = 32;\n\nexport interface ConversationProps extends ComponentPropsWithRef<\"div\"> {\n /**\n * Follow new content while the reader is at the bottom.\n *\n * Turning this off never scrolls automatically; it does not pin the view.\n */\n autoScroll?: boolean;\n}\n\nexport function Conversation({\n className,\n autoScroll = true,\n children,\n ...props\n}: ConversationProps) {\n const viewportRef = useRef<HTMLDivElement | null>(null);\n const [atBottom, setAtBottom] = useState(true);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"smooth\") => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n viewport.scrollTo({ top: viewport.scrollHeight, behavior });\n }, []);\n\n useEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n\n function handleScroll() {\n if (!viewport) return;\n const distance = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight;\n setAtBottom(distance <= BOTTOM_THRESHOLD);\n }\n\n handleScroll();\n viewport.addEventListener(\"scroll\", handleScroll, { passive: true });\n return () => {\n viewport.removeEventListener(\"scroll\", handleScroll);\n };\n }, []);\n\n // Follows content as it grows, but only while the reader is pinned to the\n // bottom. Layout effect so the jump happens before paint rather than as a\n // visible lurch.\n useLayoutEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport || !autoScroll) return;\n\n const observer = new ResizeObserver(() => {\n if (atBottom) viewport.scrollTop = viewport.scrollHeight;\n });\n\n for (const child of viewport.children) observer.observe(child);\n return () => {\n observer.disconnect();\n };\n }, [autoScroll, atBottom]);\n\n const context = useMemo<ConversationContextValue>(\n () => ({ viewportRef, atBottom, scrollToBottom }),\n [atBottom, scrollToBottom],\n );\n\n return (\n <ConversationContext.Provider value={context}>\n <div\n data-slot=\"conversation\"\n data-at-bottom={atBottom || undefined}\n className={cn(\"relative flex min-h-0 flex-1 flex-col\", className)}\n {...props}\n >\n <div\n ref={viewportRef}\n data-slot=\"conversation-viewport\"\n className=\"flex-1 overflow-y-auto overscroll-contain\"\n >\n {children}\n </div>\n </div>\n </ConversationContext.Provider>\n );\n}\n\n/**\n * The transcript.\n *\n * An ordered list, deliberately not a live region — see the note on\n * `Conversation`. Order is meaning here, and list semantics give a screen\n * reader user position and count (\"3 of 12\") as they move through it.\n */\nexport function ConversationMessages({ className, ...props }: ComponentPropsWithRef<\"ol\">) {\n return (\n <ol\n data-slot=\"conversation-messages\"\n className={cn(\"flex flex-col gap-6 p-4\", className)}\n {...props}\n />\n );\n}\n\nexport interface ConversationStatusProps extends ComponentPropsWithRef<\"div\"> {\n /** Announced politely when it changes. Keep it short: state, never content. */\n children?: ReactNode;\n}\n\n/**\n * A polite live region for conversation state.\n *\n * This is where \"generating response\" and \"response complete\" belong. Putting\n * the response *text* here instead is the mistake this component exists to\n * prevent.\n */\nexport function ConversationStatus({ className, children, ...props }: ConversationStatusProps) {\n return (\n <div\n data-slot=\"conversation-status\"\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\"px-4 text-xs text-muted-foreground\", className)}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nexport interface ConversationScrollButtonProps extends ComponentPropsWithRef<\"button\"> {\n label?: string;\n}\n\n/**\n * Returns the reader to the newest message.\n *\n * Rendered only when they have scrolled away, and removed from the DOM\n * otherwise so it is never a focus stop pointing at where the reader already\n * is.\n */\nexport function ConversationScrollButton({\n className,\n label = \"Jump to latest\",\n ...props\n}: ConversationScrollButtonProps) {\n const { atBottom, scrollToBottom } = useConversation(\"ConversationScrollButton\");\n if (atBottom) return null;\n\n return (\n <button\n type=\"button\"\n data-slot=\"conversation-scroll-button\"\n onClick={() => {\n scrollToBottom();\n }}\n className={cn(\n \"absolute bottom-3 left-1/2 z-[var(--z-sticky)] flex -translate-x-1/2 items-center gap-1.5\",\n \"rounded-full border border-border bg-popover px-3 py-1.5 text-xs font-medium shadow-md\",\n \"transition-colors duration-[var(--duration-fast)] hover:bg-accent\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-ring/55\",\n className,\n )}\n {...props}\n >\n <svg viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\" className=\"size-3.5\">\n <path\n d=\"M12 5v14m0 0-6-6m6 6 6-6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n {label}\n </button>\n );\n}\n"],"mappings":";;;;;AA0CA,MAAM,sBAAsB,cAA+C,IAAI;AAE/E,SAAS,gBAAgB,WAA6C;CACpE,MAAM,UAAU,WAAW,mBAAmB;CAC9C,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,GAAG,UAAU,yCAAyC;CAExE,OAAO;AACT;;AAGA,MAAM,mBAAmB;AAWzB,SAAgB,aAAa,EAC3B,WACA,aAAa,MACb,UACA,GAAG,SACiB;CACpB,MAAM,cAAc,OAA8B,IAAI;CACtD,MAAM,CAAC,UAAU,eAAe,SAAS,IAAI;CAE7C,MAAM,iBAAiB,aAAa,WAA2B,aAAa;EAC1E,MAAM,WAAW,YAAY;EAC7B,IAAI,CAAC,UAAU;EACf,SAAS,SAAS;GAAE,KAAK,SAAS;GAAc;EAAS,CAAC;CAC5D,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,MAAM,WAAW,YAAY;EAC7B,IAAI,CAAC,UAAU;EAEf,SAAS,eAAe;GACtB,IAAI,CAAC,UAAU;GACf,MAAM,WAAW,SAAS,eAAe,SAAS,YAAY,SAAS;GACvE,YAAY,YAAY,gBAAgB;EAC1C;EAEA,aAAa;EACb,SAAS,iBAAiB,UAAU,cAAc,EAAE,SAAS,KAAK,CAAC;EACnE,aAAa;GACX,SAAS,oBAAoB,UAAU,YAAY;EACrD;CACF,GAAG,CAAC,CAAC;CAKL,sBAAsB;EACpB,MAAM,WAAW,YAAY;EAC7B,IAAI,CAAC,YAAY,CAAC,YAAY;EAE9B,MAAM,WAAW,IAAI,qBAAqB;GACxC,IAAI,UAAU,SAAS,YAAY,SAAS;EAC9C,CAAC;EAED,KAAK,MAAM,SAAS,SAAS,UAAU,SAAS,QAAQ,KAAK;EAC7D,aAAa;GACX,SAAS,WAAW;EACtB;CACF,GAAG,CAAC,YAAY,QAAQ,CAAC;CAEzB,MAAM,UAAU,eACP;EAAE;EAAa;EAAU;CAAe,IAC/C,CAAC,UAAU,cAAc,CAC3B;CAEA,OACE,oBAAC,oBAAoB,UAArB;EAA8B,OAAO;EACnC,UAAA,oBAAC,OAAD;GACE,aAAU;GACV,kBAAgB,YAAY,KAAA;GAC5B,WAAW,GAAG,yCAAyC,SAAS;GAChE,GAAI;GAEJ,UAAA,oBAAC,OAAD;IACE,KAAK;IACL,aAAU;IACV,WAAU;IAET;GACE,CAAA;EACF,CAAA;CACuB,CAAA;AAElC;;;;;;;;AASA,SAAgB,qBAAqB,EAAE,WAAW,GAAG,SAAsC;CACzF,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GAAG,2BAA2B,SAAS;EAClD,GAAI;CACL,CAAA;AAEL;;;;;;;;AAcA,SAAgB,mBAAmB,EAAE,WAAW,UAAU,GAAG,SAAkC;CAC7F,OACE,oBAAC,OAAD;EACE,aAAU;EACV,MAAK;EACL,aAAU;EACV,WAAW,GAAG,sCAAsC,SAAS;EAC7D,GAAI;EAEH;CACE,CAAA;AAET;;;;;;;;AAaA,SAAgB,yBAAyB,EACvC,WACA,QAAQ,kBACR,GAAG,SAC6B;CAChC,MAAM,EAAE,UAAU,mBAAmB,gBAAgB,0BAA0B;CAC/E,IAAI,UAAU,OAAO;CAErB,OACE,qBAAC,UAAD;EACE,MAAK;EACL,aAAU;EACV,eAAe;GACb,eAAe;EACjB;EACA,WAAW,GACT,6FACA,0FACA,qEACA,gEACA,SACF;EACA,GAAI;EAbN,UAAA,CAeE,oBAAC,OAAD;GAAK,SAAQ;GAAY,MAAK;GAAO,eAAY;GAAO,WAAU;GAChE,UAAA,oBAAC,QAAD;IACE,GAAE;IACF,QAAO;IACP,aAAY;IACZ,eAAc;IACd,gBAAe;GAChB,CAAA;EACE,CAAA,GACJ,KACK;;AAEZ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Conversation, ConversationMessages, ConversationProps, ConversationScrollButton, ConversationScrollButtonProps, ConversationStatus, ConversationStatusProps } from "./ai-conversation.js";
|
|
2
|
+
export { Conversation, ConversationMessages, type ConversationProps, ConversationScrollButton, type ConversationScrollButtonProps, ConversationStatus, type ConversationStatusProps };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/components/ai-conversation/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "ai-conversation",
|
|
5
|
+
title: "AI Conversation",
|
|
6
|
+
description: "The scrolling transcript container, with follow-on-new-content and a status region.",
|
|
7
|
+
category: "ai",
|
|
8
|
+
status: "stable",
|
|
9
|
+
dependencies: [],
|
|
10
|
+
registryDependencies: [],
|
|
11
|
+
files: ["ai-conversation.tsx"],
|
|
12
|
+
a11y: "The transcript is an ordered list, NOT a live region. A live region that updates on every streamed token is unusable with a screen reader, and is the most common accessibility failure in chat interfaces. Announce state — \"generating\", \"response complete\" — through ConversationStatus instead, and let the reader navigate the transcript at their own pace. Auto-scroll stops the moment the reader scrolls up, and ConversationScrollButton is the explicit way back."
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { meta };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/components/ai-conversation/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"ai-conversation\",\n title: \"AI Conversation\",\n description:\n \"The scrolling transcript container, with follow-on-new-content and a status region.\",\n category: \"ai\",\n status: \"stable\",\n dependencies: [],\n registryDependencies: [],\n files: [\"ai-conversation.tsx\"],\n a11y:\n \"The transcript is an ordered list, NOT a live region. A live region that updates on every \" +\n \"streamed token is unusable with a screen reader, and is the most common accessibility \" +\n 'failure in chat interfaces. Announce state — \"generating\", \"response complete\" — through ' +\n \"ConversationStatus instead, and let the reader navigate the transcript at their own pace. \" +\n \"Auto-scroll stops the moment the reader scrolls up, and ConversationScrollButton is the \" +\n \"explicit way back.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,OAAO;CACP,aACE;CACF,UAAU;CACV,QAAQ;CACR,cAAc,CAAC;CACf,sBAAsB,CAAC;CACvB,OAAO,CAAC,qBAAqB;CAC7B,MACE;AAMJ,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { VariantProps } from "class-variance-authority";
|
|
2
|
+
import { ComponentPropsWithRef } from "react";
|
|
3
|
+
//#region src/components/ai-message/ai-message.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* One turn in a conversation.
|
|
6
|
+
*
|
|
7
|
+
* The role is stated in text, not only in layout. Alignment and colour are how
|
|
8
|
+
* a sighted reader tells a question from an answer; a screen reader user gets
|
|
9
|
+
* nothing from either, so every message carries a visually hidden label naming
|
|
10
|
+
* who is speaking.
|
|
11
|
+
*/
|
|
12
|
+
declare const messageVariants: (props?: ({
|
|
13
|
+
role?: "user" | "assistant" | "system" | null | undefined;
|
|
14
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
15
|
+
declare const messageBodyVariants: (props?: ({
|
|
16
|
+
role?: "user" | "assistant" | "system" | null | undefined;
|
|
17
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
18
|
+
type MessageRole = "user" | "assistant" | "system";
|
|
19
|
+
interface MessageProps extends ComponentPropsWithRef<"li">, Omit<VariantProps<typeof messageVariants>, "role"> {
|
|
20
|
+
/**
|
|
21
|
+
* Who is speaking.
|
|
22
|
+
*
|
|
23
|
+
* Named `from` rather than `role` on purpose. `role` is a global HTML
|
|
24
|
+
* attribute, and a component prop that shadows it cannot be told apart from
|
|
25
|
+
* the real thing by static analysis — every consumer's accessibility linter
|
|
26
|
+
* would flag ordinary usage of this component. The values are still the
|
|
27
|
+
* familiar conversation roles.
|
|
28
|
+
*/
|
|
29
|
+
from?: MessageRole;
|
|
30
|
+
/** Overrides the visually hidden speaker label. */
|
|
31
|
+
fromLabel?: string;
|
|
32
|
+
}
|
|
33
|
+
declare function Message({ className, from, fromLabel, children, ...props }: MessageProps): import("react").JSX.Element;
|
|
34
|
+
interface MessageBodyProps extends ComponentPropsWithRef<"div">, Omit<VariantProps<typeof messageBodyVariants>, "role"> {
|
|
35
|
+
/** Who is speaking. See the note on MessageProps for why not `role`. */
|
|
36
|
+
from?: MessageRole;
|
|
37
|
+
}
|
|
38
|
+
declare function MessageBody({ className, from, ...props }: MessageBodyProps): import("react").JSX.Element;
|
|
39
|
+
interface MessageAvatarProps extends ComponentPropsWithRef<"div"> {
|
|
40
|
+
asChild?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** Decorative: the speaker is already named by the hidden label on Message. */
|
|
43
|
+
declare function MessageAvatar({ className, asChild, ...props }: MessageAvatarProps): import("react").JSX.Element;
|
|
44
|
+
/**
|
|
45
|
+
* Per-message controls: copy, regenerate, feedback.
|
|
46
|
+
*
|
|
47
|
+
* Revealed on hover for pointer users but always present in the DOM and in the
|
|
48
|
+
* tab order — hiding controls behind hover makes them unreachable by keyboard
|
|
49
|
+
* and invisible on touch.
|
|
50
|
+
*/
|
|
51
|
+
declare function MessageActions({ className, ...props }: ComponentPropsWithRef<"div">): import("react").JSX.Element;
|
|
52
|
+
/** Attachments, citations and other content that hangs off a message. */
|
|
53
|
+
declare function MessageFooter({ className, ...props }: ComponentPropsWithRef<"div">): import("react").JSX.Element;
|
|
54
|
+
//#endregion
|
|
55
|
+
export { Message, MessageActions, MessageAvatar, MessageAvatarProps, MessageBody, MessageBodyProps, MessageFooter, MessageProps, MessageRole, messageBodyVariants, messageVariants };
|
|
56
|
+
//# sourceMappingURL=ai-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-message.d.ts","names":[],"sources":["../../../src/components/ai-message/ai-message.tsx"],"mappings":";;;;;;;;;;;cAiBM,kBAAe;;6CAWnB;cAEI,sBAAmB;;6CAYvB;KAEU;UAEK,qBACP,6BAA6B,KAAK,oBAAoB;;;;;;;;;;EAU9D,OAAO;;EAEP;;iBASc,UACd,WACA,MACA,WACA,aACG,SACF,+BAAY,IAAA;UAeE,yBACP,8BAA8B,KAAK,oBAAoB;;EAE/D,OAAO;;iBAGO,cAAc,WAAW,SAAuB,SAAS,mCAAgB,IAAA;UAUxE,2BAA2B;EAC1C;;;iBAIc,gBAAgB,WAAW,YAAY,SAAS,qCAAkB,IAAA;;;;;;;;iBAyBlE,iBAAiB,cAAc,SAAS,+CAA4B,IAAA;;iBAgBpE,gBAAgB,cAAc,SAAS,+CAA4B,IAAA"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Slot } from "radix-ui";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
//#region src/components/ai-message/ai-message.tsx
|
|
7
|
+
/**
|
|
8
|
+
* One turn in a conversation.
|
|
9
|
+
*
|
|
10
|
+
* The role is stated in text, not only in layout. Alignment and colour are how
|
|
11
|
+
* a sighted reader tells a question from an answer; a screen reader user gets
|
|
12
|
+
* nothing from either, so every message carries a visually hidden label naming
|
|
13
|
+
* who is speaking.
|
|
14
|
+
*/
|
|
15
|
+
const messageVariants = cva("group/message flex w-full gap-3", {
|
|
16
|
+
variants: { role: {
|
|
17
|
+
user: "flex-row-reverse",
|
|
18
|
+
assistant: "flex-row",
|
|
19
|
+
system: "flex-row"
|
|
20
|
+
} },
|
|
21
|
+
defaultVariants: { role: "assistant" }
|
|
22
|
+
});
|
|
23
|
+
const messageBodyVariants = cva("min-w-0 rounded-xl px-4 py-3 text-sm", {
|
|
24
|
+
variants: { role: {
|
|
25
|
+
user: "max-w-[85%] bg-primary text-primary-foreground",
|
|
26
|
+
assistant: "w-full bg-transparent px-0 py-0 text-foreground",
|
|
27
|
+
system: "w-full border border-dashed border-border bg-muted/40 text-xs text-muted-foreground"
|
|
28
|
+
} },
|
|
29
|
+
defaultVariants: { role: "assistant" }
|
|
30
|
+
});
|
|
31
|
+
const DEFAULT_ROLE_LABELS = {
|
|
32
|
+
user: "You said",
|
|
33
|
+
assistant: "Assistant said",
|
|
34
|
+
system: "System"
|
|
35
|
+
};
|
|
36
|
+
function Message({ className, from = "assistant", fromLabel, children, ...props }) {
|
|
37
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
38
|
+
"data-slot": "message",
|
|
39
|
+
"data-from": from,
|
|
40
|
+
className: cn(messageVariants({ role: from }), className),
|
|
41
|
+
...props,
|
|
42
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
43
|
+
className: "sr-only",
|
|
44
|
+
children: [fromLabel ?? DEFAULT_ROLE_LABELS[from], ":"]
|
|
45
|
+
}), children]
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function MessageBody({ className, from = "assistant", ...props }) {
|
|
49
|
+
return /* @__PURE__ */ jsx("div", {
|
|
50
|
+
"data-slot": "message-body",
|
|
51
|
+
className: cn(messageBodyVariants({ role: from }), className),
|
|
52
|
+
...props
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** Decorative: the speaker is already named by the hidden label on Message. */
|
|
56
|
+
function MessageAvatar({ className, asChild, ...props }) {
|
|
57
|
+
const Comp = asChild ? Slot.Root : "div";
|
|
58
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
59
|
+
"data-slot": "message-avatar",
|
|
60
|
+
"aria-hidden": "true",
|
|
61
|
+
className: cn("grid size-7 shrink-0 place-items-center rounded-full border border-border bg-muted", "text-xs font-medium text-muted-foreground", "[&_svg:not([class*='size-'])]:size-3.5", className),
|
|
62
|
+
...props
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Per-message controls: copy, regenerate, feedback.
|
|
67
|
+
*
|
|
68
|
+
* Revealed on hover for pointer users but always present in the DOM and in the
|
|
69
|
+
* tab order — hiding controls behind hover makes them unreachable by keyboard
|
|
70
|
+
* and invisible on touch.
|
|
71
|
+
*/
|
|
72
|
+
function MessageActions({ className, ...props }) {
|
|
73
|
+
return /* @__PURE__ */ jsx("div", {
|
|
74
|
+
"data-slot": "message-actions",
|
|
75
|
+
className: cn("mt-1.5 flex items-center gap-1", "opacity-0 transition-opacity duration-[var(--duration-fast)]", "group-focus-within/message:opacity-100 group-hover/message:opacity-100", className),
|
|
76
|
+
...props
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/** Attachments, citations and other content that hangs off a message. */
|
|
80
|
+
function MessageFooter({ className, ...props }) {
|
|
81
|
+
return /* @__PURE__ */ jsx("div", {
|
|
82
|
+
"data-slot": "message-footer",
|
|
83
|
+
className: cn("mt-2 flex flex-wrap items-center gap-2", className),
|
|
84
|
+
...props
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { Message, MessageActions, MessageAvatar, MessageBody, MessageFooter, messageBodyVariants, messageVariants };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=ai-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-message.js","names":[],"sources":["../../../src/components/ai-message/ai-message.tsx"],"sourcesContent":["\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\nimport type { ComponentPropsWithRef } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\n/**\n * One turn in a conversation.\n *\n * The role is stated in text, not only in layout. Alignment and colour are how\n * a sighted reader tells a question from an answer; a screen reader user gets\n * nothing from either, so every message carries a visually hidden label naming\n * who is speaking.\n */\n\nconst messageVariants = cva(\"group/message flex w-full gap-3\", {\n variants: {\n role: {\n user: \"flex-row-reverse\",\n assistant: \"flex-row\",\n system: \"flex-row\",\n },\n },\n defaultVariants: {\n role: \"assistant\",\n },\n});\n\nconst messageBodyVariants = cva(\"min-w-0 rounded-xl px-4 py-3 text-sm\", {\n variants: {\n role: {\n user: \"max-w-[85%] bg-primary text-primary-foreground\",\n assistant: \"w-full bg-transparent px-0 py-0 text-foreground\",\n system:\n \"w-full border border-dashed border-border bg-muted/40 text-xs text-muted-foreground\",\n },\n },\n defaultVariants: {\n role: \"assistant\",\n },\n});\n\nexport type MessageRole = \"user\" | \"assistant\" | \"system\";\n\nexport interface MessageProps\n extends ComponentPropsWithRef<\"li\">, Omit<VariantProps<typeof messageVariants>, \"role\"> {\n /**\n * Who is speaking.\n *\n * Named `from` rather than `role` on purpose. `role` is a global HTML\n * attribute, and a component prop that shadows it cannot be told apart from\n * the real thing by static analysis — every consumer's accessibility linter\n * would flag ordinary usage of this component. The values are still the\n * familiar conversation roles.\n */\n from?: MessageRole;\n /** Overrides the visually hidden speaker label. */\n fromLabel?: string;\n}\n\nconst DEFAULT_ROLE_LABELS: Record<MessageRole, string> = {\n user: \"You said\",\n assistant: \"Assistant said\",\n system: \"System\",\n};\n\nexport function Message({\n className,\n from = \"assistant\",\n fromLabel,\n children,\n ...props\n}: MessageProps) {\n return (\n <li\n data-slot=\"message\"\n data-from={from}\n className={cn(messageVariants({ role: from }), className)}\n {...props}\n >\n {/* Names the speaker for anyone who cannot see the layout. */}\n <span className=\"sr-only\">{fromLabel ?? DEFAULT_ROLE_LABELS[from]}:</span>\n {children}\n </li>\n );\n}\n\nexport interface MessageBodyProps\n extends ComponentPropsWithRef<\"div\">, Omit<VariantProps<typeof messageBodyVariants>, \"role\"> {\n /** Who is speaking. See the note on MessageProps for why not `role`. */\n from?: MessageRole;\n}\n\nexport function MessageBody({ className, from = \"assistant\", ...props }: MessageBodyProps) {\n return (\n <div\n data-slot=\"message-body\"\n className={cn(messageBodyVariants({ role: from }), className)}\n {...props}\n />\n );\n}\n\nexport interface MessageAvatarProps extends ComponentPropsWithRef<\"div\"> {\n asChild?: boolean;\n}\n\n/** Decorative: the speaker is already named by the hidden label on Message. */\nexport function MessageAvatar({ className, asChild, ...props }: MessageAvatarProps) {\n const Comp = asChild ? Slot.Root : \"div\";\n\n return (\n <Comp\n data-slot=\"message-avatar\"\n aria-hidden=\"true\"\n className={cn(\n \"grid size-7 shrink-0 place-items-center rounded-full border border-border bg-muted\",\n \"text-xs font-medium text-muted-foreground\",\n \"[&_svg:not([class*='size-'])]:size-3.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/**\n * Per-message controls: copy, regenerate, feedback.\n *\n * Revealed on hover for pointer users but always present in the DOM and in the\n * tab order — hiding controls behind hover makes them unreachable by keyboard\n * and invisible on touch.\n */\nexport function MessageActions({ className, ...props }: ComponentPropsWithRef<\"div\">) {\n return (\n <div\n data-slot=\"message-actions\"\n className={cn(\n \"mt-1.5 flex items-center gap-1\",\n \"opacity-0 transition-opacity duration-[var(--duration-fast)]\",\n \"group-focus-within/message:opacity-100 group-hover/message:opacity-100\",\n className,\n )}\n {...props}\n />\n );\n}\n\n/** Attachments, citations and other content that hangs off a message. */\nexport function MessageFooter({ className, ...props }: ComponentPropsWithRef<\"div\">) {\n return (\n <div\n data-slot=\"message-footer\"\n className={cn(\"mt-2 flex flex-wrap items-center gap-2\", className)}\n {...props}\n />\n );\n}\n\nexport { messageBodyVariants, messageVariants };\n"],"mappings":";;;;;;;;;;;;;;AAiBA,MAAM,kBAAkB,IAAI,mCAAmC;CAC7D,UAAU,EACR,MAAM;EACJ,MAAM;EACN,WAAW;EACX,QAAQ;CACV,EACF;CACA,iBAAiB,EACf,MAAM,YACR;AACF,CAAC;AAED,MAAM,sBAAsB,IAAI,wCAAwC;CACtE,UAAU,EACR,MAAM;EACJ,MAAM;EACN,WAAW;EACX,QACE;CACJ,EACF;CACA,iBAAiB,EACf,MAAM,YACR;AACF,CAAC;AAoBD,MAAM,sBAAmD;CACvD,MAAM;CACN,WAAW;CACX,QAAQ;AACV;AAEA,SAAgB,QAAQ,EACtB,WACA,OAAO,aACP,WACA,UACA,GAAG,SACY;CACf,OACE,qBAAC,MAAD;EACE,aAAU;EACV,aAAW;EACX,WAAW,GAAG,gBAAgB,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS;EACxD,GAAI;EAJN,UAAA,CAOE,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CAA2B,aAAa,oBAAoB,OAAM,GAAO;EACxE,CAAA,GAAA,QACC;;AAER;AAQA,SAAgB,YAAY,EAAE,WAAW,OAAO,aAAa,GAAG,SAA2B;CACzF,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,oBAAoB,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS;EAC5D,GAAI;CACL,CAAA;AAEL;;AAOA,SAAgB,cAAc,EAAE,WAAW,SAAS,GAAG,SAA6B;CAClF,MAAM,OAAO,UAAU,KAAK,OAAO;CAEnC,OACE,oBAAC,MAAD;EACE,aAAU;EACV,eAAY;EACZ,WAAW,GACT,sFACA,6CACA,0CACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;;;;;;;;AASA,SAAgB,eAAe,EAAE,WAAW,GAAG,SAAuC;CACpF,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,kCACA,gEACA,0EACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;;AAGA,SAAgB,cAAc,EAAE,WAAW,GAAG,SAAuC;CACnF,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,0CAA0C,SAAS;EACjE,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { Message, MessageActions, MessageAvatar, MessageAvatarProps, MessageBody, MessageBodyProps, MessageFooter, MessageProps, MessageRole, messageBodyVariants, messageVariants } from "./ai-message.js";
|
|
2
|
+
export { Message, MessageActions, MessageAvatar, type MessageAvatarProps, MessageBody, type MessageBodyProps, MessageFooter, type MessageProps, type MessageRole, messageBodyVariants, messageVariants };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineMeta } from "../../registry/schema.js";
|
|
2
|
+
//#region src/components/ai-message/meta.ts
|
|
3
|
+
const meta = defineMeta({
|
|
4
|
+
name: "ai-message",
|
|
5
|
+
title: "AI Message",
|
|
6
|
+
description: "One turn in a conversation, with role, avatar, actions and footer slots.",
|
|
7
|
+
category: "ai",
|
|
8
|
+
status: "stable",
|
|
9
|
+
dependencies: ["class-variance-authority", "radix-ui"],
|
|
10
|
+
registryDependencies: [],
|
|
11
|
+
files: ["ai-message.tsx"],
|
|
12
|
+
a11y: "Every message carries a visually hidden label naming the speaker. Alignment and colour tell a sighted reader who is talking and tell a screen reader user nothing, so the role is always in text. Message actions fade in on hover but stay in the DOM and in the tab order — a control that only exists on hover is unreachable by keyboard and invisible on touch."
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { meta };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","names":[],"sources":["../../../src/components/ai-message/meta.ts"],"sourcesContent":["import { defineMeta } from \"@/registry/schema\";\n\nexport const meta = defineMeta({\n name: \"ai-message\",\n title: \"AI Message\",\n description: \"One turn in a conversation, with role, avatar, actions and footer slots.\",\n category: \"ai\",\n status: \"stable\",\n dependencies: [\"class-variance-authority\", \"radix-ui\"],\n registryDependencies: [],\n files: [\"ai-message.tsx\"],\n a11y:\n \"Every message carries a visually hidden label naming the speaker. Alignment and colour tell \" +\n \"a sighted reader who is talking and tell a screen reader user nothing, so the role is always \" +\n \"in text. Message actions fade in on hover but stay in the DOM and in the tab order — a \" +\n \"control that only exists on hover is unreachable by keyboard and invisible on touch.\",\n});\n"],"mappings":";;AAEA,MAAa,OAAO,WAAW;CAC7B,MAAM;CACN,OAAO;CACP,aAAa;CACb,UAAU;CACV,QAAQ;CACR,cAAc,CAAC,4BAA4B,UAAU;CACrD,sBAAsB,CAAC;CACvB,OAAO,CAAC,gBAAgB;CACxB,MACE;AAIJ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SelectTrigger } from "../select/select.js";
|
|
2
|
+
import "../select/index.js";
|
|
3
|
+
import { ComponentPropsWithRef, ReactNode } from "react";
|
|
4
|
+
//#region src/components/ai-model-selector/ai-model-selector.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Picks the model a conversation runs on.
|
|
7
|
+
*
|
|
8
|
+
* A thin, opinionated layer over Select rather than a new control: model
|
|
9
|
+
* pickers differ between products in what they show, not in how they behave.
|
|
10
|
+
* What this adds is the shape of the option — a name, a short description, and
|
|
11
|
+
* the fact that some models are unavailable on the current plan — which is the
|
|
12
|
+
* part every implementation gets wrong in the same way, by hiding the reason a
|
|
13
|
+
* model cannot be chosen.
|
|
14
|
+
*/
|
|
15
|
+
interface ModelOption {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
/** One line on what the model is for. */
|
|
19
|
+
description?: string;
|
|
20
|
+
/** Grouping, for example a provider name. */
|
|
21
|
+
group?: string;
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Why it is unavailable.
|
|
25
|
+
*
|
|
26
|
+
* Shown and announced alongside the name. A disabled option with no reason
|
|
27
|
+
* makes the user think the interface is broken.
|
|
28
|
+
*/
|
|
29
|
+
disabledReason?: string;
|
|
30
|
+
badge?: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
interface ModelSelectorProps extends Omit<ComponentPropsWithRef<typeof SelectTrigger>, "children"> {
|
|
33
|
+
models: ModelOption[];
|
|
34
|
+
value?: string;
|
|
35
|
+
defaultValue?: string;
|
|
36
|
+
onValueChange?: (value: string) => void;
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
}
|
|
39
|
+
declare function ModelSelector({ className, models, value, defaultValue, onValueChange, placeholder, ...props }: ModelSelectorProps): import("react").JSX.Element;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { ModelOption, ModelSelector, ModelSelectorProps };
|
|
42
|
+
//# sourceMappingURL=ai-model-selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-model-selector.d.ts","names":[],"sources":["../../../src/components/ai-model-selector/ai-model-selector.tsx"],"mappings":";;;;;;;;;;;;;;UA0BiB;EACf;EACA;;EAEA;;EAEA;EACA;;;;;;;EAOA;EACA,QAAQ;;UAGO,2BAA2B,KAC1C,6BAA6B;EAG7B,QAAQ;EACR;EACA;EACA,iBAAiB;EACjB;;iBAGc,gBACd,WACA,QACA,OACA,cACA,eACA,gBACG,SACF,qCAAkB,IAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/utils.js";
|
|
3
|
+
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "../select/select.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/ai-model-selector/ai-model-selector.tsx
|
|
6
|
+
function ModelSelector({ className, models, value, defaultValue, onValueChange, placeholder = "Select a model", ...props }) {
|
|
7
|
+
const groups = /* @__PURE__ */ new Map();
|
|
8
|
+
for (const model of models) {
|
|
9
|
+
const key = model.group ?? "";
|
|
10
|
+
groups.set(key, [...groups.get(key) ?? [], model]);
|
|
11
|
+
}
|
|
12
|
+
return /* @__PURE__ */ jsxs(Select, {
|
|
13
|
+
value,
|
|
14
|
+
defaultValue,
|
|
15
|
+
onValueChange,
|
|
16
|
+
children: [/* @__PURE__ */ jsx(SelectTrigger, {
|
|
17
|
+
"data-slot": "model-selector",
|
|
18
|
+
className: cn("w-auto min-w-44 gap-2", className),
|
|
19
|
+
...props,
|
|
20
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder })
|
|
21
|
+
}), /* @__PURE__ */ jsx(SelectContent, {
|
|
22
|
+
className: "min-w-64",
|
|
23
|
+
children: [...groups].map(([group, groupModels]) => /* @__PURE__ */ jsxs(SelectGroup, { children: [group ? /* @__PURE__ */ jsx(SelectLabel, { children: group }) : null, groupModels.map((model) => /* @__PURE__ */ jsx(SelectItem, {
|
|
24
|
+
value: model.id,
|
|
25
|
+
disabled: model.disabled,
|
|
26
|
+
textValue: model.name,
|
|
27
|
+
label: model.name,
|
|
28
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
29
|
+
className: "flex min-w-0 flex-col gap-0.5",
|
|
30
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
31
|
+
className: "flex items-center gap-2",
|
|
32
|
+
children: model.badge
|
|
33
|
+
}), model.disabled && model.disabledReason ? /* @__PURE__ */ jsx("span", {
|
|
34
|
+
className: "text-2xs text-muted-foreground",
|
|
35
|
+
children: model.disabledReason
|
|
36
|
+
}) : model.description ? /* @__PURE__ */ jsx("span", {
|
|
37
|
+
className: "text-2xs text-muted-foreground",
|
|
38
|
+
children: model.description
|
|
39
|
+
}) : null]
|
|
40
|
+
})
|
|
41
|
+
}, model.id))] }, group || "ungrouped"))
|
|
42
|
+
})]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { ModelSelector };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=ai-model-selector.js.map
|