@k8ordo/ui 2.0.0 → 2.2.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/README.md +197 -187
- package/dist/components/_internal/focus-ring.css +37 -0
- package/dist/components/_internal/focus-ring.module.mjs +9 -0
- package/dist/components/_internal/form-value.d.mts +34 -0
- package/dist/components/_internal/form-value.mjs +91 -0
- package/dist/components/_internal/high-contrast.css +18 -0
- package/dist/components/_internal/high-contrast.module.mjs +5 -0
- package/dist/components/_internal/ignore-changes.d.mts +20 -0
- package/dist/components/_internal/ignore-changes.mjs +37 -0
- package/dist/components/_internal/nav-link.css +78 -0
- package/dist/components/_internal/nav-link.d.mts +5 -0
- package/dist/components/_internal/nav-link.mjs +8 -0
- package/dist/components/_internal/nav-link.module.mjs +14 -0
- package/dist/components/_internal/sr-only.css +17 -0
- package/dist/components/_internal/sr-only.module.mjs +5 -0
- package/dist/components/_internal/status-tone.css +37 -0
- package/dist/components/_internal/status-tone.d.mts +20 -0
- package/dist/components/_internal/status-tone.mjs +22 -0
- package/dist/components/_internal/status-tone.module.mjs +14 -0
- package/dist/components/ai/_internal/attachment-preview.css +75 -0
- package/dist/components/ai/_internal/attachment-preview.d.mts +15 -0
- package/dist/components/ai/_internal/attachment-preview.mjs +50 -0
- package/dist/components/ai/_internal/attachment-preview.module.mjs +14 -0
- package/dist/components/ai/_internal/collapsible.css +62 -0
- package/dist/components/ai/_internal/collapsible.d.mts +4 -2
- package/dist/components/ai/_internal/collapsible.mjs +42 -33
- package/dist/components/ai/_internal/collapsible.module.mjs +12 -0
- package/dist/components/ai/_internal/icons.d.mts +8 -0
- package/dist/components/ai/_internal/icons.mjs +14 -0
- package/dist/components/ai/_internal/streaming-cursor.css +28 -0
- package/dist/components/ai/_internal/streaming-cursor.d.mts +2 -3
- package/dist/components/ai/_internal/streaming-cursor.mjs +2 -1
- package/dist/components/ai/_internal/streaming-cursor.module.mjs +8 -0
- package/dist/components/ai/attachment/attachment.css +17 -0
- package/dist/components/ai/attachment/attachment.d.mts +15 -0
- package/dist/components/ai/attachment/attachment.mjs +25 -0
- package/dist/components/ai/attachment/attachment.module.mjs +8 -0
- package/dist/components/ai/attachment/index.d.mts +13 -0
- package/dist/components/ai/attachment/index.mjs +8 -0
- package/dist/components/ai/conversation/conversation.css +71 -0
- package/dist/components/ai/conversation/conversation.d.mts +4 -4
- package/dist/components/ai/conversation/conversation.mjs +38 -34
- package/dist/components/ai/conversation/conversation.module.mjs +11 -0
- package/dist/components/ai/conversation/index.d.mts +2 -3
- package/dist/components/ai/index.d.mts +4 -2
- package/dist/components/ai/index.mjs +3 -1
- package/dist/components/ai/message/index.d.mts +29 -3
- package/dist/components/ai/message/index.mjs +7 -2
- package/dist/components/ai/message/message.css +71 -0
- package/dist/components/ai/message/message.d.mts +34 -3
- package/dist/components/ai/message/message.mjs +99 -9
- package/dist/components/ai/message/message.module.mjs +18 -0
- package/dist/components/ai/prompt-input/index.d.mts +11 -4
- package/dist/components/ai/prompt-input/index.mjs +3 -1
- package/dist/components/ai/prompt-input/prompt-input.css +101 -0
- package/dist/components/ai/prompt-input/prompt-input.d.mts +15 -5
- package/dist/components/ai/prompt-input/prompt-input.mjs +152 -37
- package/dist/components/ai/prompt-input/prompt-input.module.mjs +15 -0
- package/dist/components/ai/reasoning/index.mjs +1 -2
- package/dist/components/ai/reasoning/reasoning.css +16 -0
- package/dist/components/ai/reasoning/reasoning.d.mts +2 -2
- package/dist/components/ai/reasoning/reasoning.mjs +5 -5
- package/dist/components/ai/reasoning/reasoning.module.mjs +8 -0
- package/dist/components/ai/response/index.mjs +1 -2
- package/dist/components/ai/response/response.css +453 -0
- package/dist/components/ai/response/response.d.mts +4 -5
- package/dist/components/ai/response/response.mjs +20 -15
- package/dist/components/ai/response/response.module.mjs +8 -0
- package/dist/components/ai/source/index.d.mts +12 -0
- package/dist/components/ai/source/index.mjs +8 -0
- package/dist/components/ai/source/source.css +54 -0
- package/dist/components/ai/source/source.d.mts +14 -0
- package/dist/components/ai/source/source.mjs +51 -0
- package/dist/components/ai/source/source.module.mjs +12 -0
- package/dist/components/ai/suggestion/index.d.mts +2 -3
- package/dist/components/ai/suggestion/suggestion.css +32 -0
- package/dist/components/ai/suggestion/suggestion.d.mts +3 -3
- package/dist/components/ai/suggestion/suggestion.mjs +7 -6
- package/dist/components/ai/suggestion/suggestion.module.mjs +8 -0
- package/dist/components/ai/tool-invocation/approval-bar.css +26 -0
- package/dist/components/ai/tool-invocation/approval-bar.d.mts +12 -0
- package/dist/components/ai/tool-invocation/approval-bar.mjs +59 -0
- package/dist/components/ai/tool-invocation/approval-bar.module.mjs +9 -0
- package/dist/components/ai/tool-invocation/index.mjs +1 -2
- package/dist/components/ai/tool-invocation/tool-invocation.css +55 -0
- package/dist/components/ai/tool-invocation/tool-invocation.d.mts +5 -4
- package/dist/components/ai/tool-invocation/tool-invocation.mjs +39 -18
- package/dist/components/ai/tool-invocation/tool-invocation.module.mjs +15 -0
- package/dist/components/ai/types.d.mts +21 -4
- package/dist/components/buttons/button/button.css +158 -0
- package/dist/components/buttons/button/button.d.mts +32 -8
- package/dist/components/buttons/button/button.mjs +46 -36
- package/dist/components/buttons/button/button.module.mjs +23 -0
- package/dist/components/buttons/button/index.d.mts +2 -2
- package/dist/components/buttons/button/index.mjs +1 -2
- package/dist/components/buttons/copy-button/copy-button.css +15 -0
- package/dist/components/buttons/copy-button/copy-button.d.mts +10 -0
- package/dist/components/buttons/copy-button/copy-button.mjs +70 -0
- package/dist/components/buttons/copy-button/copy-button.module.mjs +8 -0
- package/dist/components/buttons/copy-button/index.d.mts +2 -0
- package/dist/components/buttons/copy-button/index.mjs +1 -0
- package/dist/components/buttons/icon-button/icon-button.css +81 -0
- package/dist/components/buttons/icon-button/icon-button.d.mts +39 -11
- package/dist/components/buttons/icon-button/icon-button.mjs +70 -57
- package/dist/components/buttons/icon-button/icon-button.module.mjs +15 -0
- package/dist/components/buttons/icon-button/index.d.mts +2 -2
- package/dist/components/buttons/icon-button/index.mjs +1 -2
- package/dist/components/buttons/toolbar/index.d.mts +14 -0
- package/dist/components/buttons/toolbar/index.mjs +9 -0
- package/dist/components/buttons/toolbar/toolbar.css +30 -0
- package/dist/components/buttons/toolbar/toolbar.d.mts +19 -0
- package/dist/components/buttons/toolbar/toolbar.mjs +111 -0
- package/dist/components/buttons/toolbar/toolbar.module.mjs +9 -0
- package/dist/components/data-display/accordion/accordion-button.css +48 -0
- package/dist/components/data-display/accordion/accordion-button.d.mts +2 -3
- package/dist/components/data-display/accordion/accordion-button.mjs +5 -4
- package/dist/components/data-display/accordion/accordion-button.module.mjs +9 -0
- package/dist/components/data-display/accordion/accordion-item.css +11 -0
- package/dist/components/data-display/accordion/accordion-item.d.mts +2 -3
- package/dist/components/data-display/accordion/accordion-item.mjs +2 -1
- package/dist/components/data-display/accordion/accordion-item.module.mjs +5 -0
- package/dist/components/data-display/accordion/accordion-panel.css +9 -0
- package/dist/components/data-display/accordion/accordion-panel.d.mts +2 -3
- package/dist/components/data-display/accordion/accordion-panel.mjs +2 -2
- package/dist/components/data-display/accordion/accordion-panel.module.mjs +5 -0
- package/dist/components/data-display/accordion/accordion.css +19 -0
- package/dist/components/data-display/accordion/accordion.d.mts +2 -3
- package/dist/components/data-display/accordion/accordion.mjs +2 -1
- package/dist/components/data-display/accordion/accordion.module.mjs +5 -0
- package/dist/components/data-display/accordion/context.d.mts +3 -3
- package/dist/components/data-display/accordion/index.d.mts +2 -3
- package/dist/components/data-display/avatar/avatar.css +95 -0
- package/dist/components/data-display/avatar/avatar.d.mts +2 -2
- package/dist/components/data-display/avatar/avatar.mjs +22 -6
- package/dist/components/data-display/avatar/avatar.module.mjs +18 -0
- package/dist/components/data-display/avatar/index.mjs +1 -2
- package/dist/components/data-display/badge/badge.css +160 -0
- package/dist/components/data-display/badge/badge.d.mts +2 -2
- package/dist/components/data-display/badge/badge.mjs +30 -5
- package/dist/components/data-display/badge/badge.module.mjs +21 -0
- package/dist/components/data-display/badge/index.mjs +1 -2
- package/dist/components/data-display/card/card.css +44 -0
- package/dist/components/data-display/card/card.d.mts +2 -2
- package/dist/components/data-display/card/card.mjs +12 -2
- package/dist/components/data-display/card/card.module.mjs +12 -0
- package/dist/components/data-display/card/index.mjs +1 -2
- package/dist/components/data-display/carousel/carousel.css +83 -0
- package/dist/components/data-display/carousel/carousel.d.mts +12 -0
- package/dist/components/data-display/carousel/carousel.mjs +186 -0
- package/dist/components/data-display/carousel/carousel.module.mjs +18 -0
- package/dist/components/data-display/carousel/index.d.mts +11 -0
- package/dist/components/data-display/carousel/index.mjs +8 -0
- package/dist/components/data-display/code/code.css +37 -0
- package/dist/components/data-display/code/code.d.mts +2 -2
- package/dist/components/data-display/code/code.mjs +7 -6
- package/dist/components/data-display/code/code.module.mjs +9 -0
- package/dist/components/data-display/code/find-all-colors.d.mts +2 -2
- package/dist/components/data-display/code/find-all-colors.mjs +0 -161
- package/dist/components/data-display/code/index.mjs +1 -2
- package/dist/components/data-display/code-block/code-block.css +161 -0
- package/dist/components/data-display/code-block/code-block.d.mts +13 -0
- package/dist/components/data-display/code-block/code-block.mjs +44 -0
- package/dist/components/data-display/code-block/code-block.module.mjs +11 -0
- package/dist/components/data-display/code-block/highlight.d.mts +10 -0
- package/dist/components/data-display/code-block/highlight.mjs +54 -0
- package/dist/components/data-display/code-block/index.d.mts +2 -0
- package/dist/components/data-display/code-block/index.mjs +1 -0
- package/dist/components/data-display/data-table/data-table.css +74 -0
- package/dist/components/data-display/data-table/data-table.d.mts +32 -0
- package/dist/components/data-display/data-table/data-table.mjs +155 -0
- package/dist/components/data-display/data-table/data-table.module.mjs +14 -0
- package/dist/components/data-display/data-table/index.d.mts +2 -0
- package/dist/components/data-display/data-table/index.mjs +1 -0
- package/dist/components/data-display/heading/heading.css +99 -0
- package/dist/components/data-display/heading/heading.d.mts +2 -2
- package/dist/components/data-display/heading/heading.mjs +15 -14
- package/dist/components/data-display/heading/heading.module.mjs +20 -0
- package/dist/components/data-display/heading/index.mjs +1 -2
- package/dist/components/data-display/kbd/index.d.mts +2 -0
- package/dist/components/data-display/kbd/index.mjs +1 -0
- package/dist/components/data-display/kbd/kbd.css +21 -0
- package/dist/components/data-display/kbd/kbd.d.mts +9 -0
- package/dist/components/data-display/kbd/kbd.mjs +17 -0
- package/dist/components/data-display/kbd/kbd.module.mjs +5 -0
- package/dist/components/data-display/prose/index.d.mts +2 -0
- package/dist/components/data-display/prose/index.mjs +1 -0
- package/dist/components/data-display/prose/prose.css +253 -0
- package/dist/components/data-display/prose/prose.d.mts +6 -0
- package/dist/components/data-display/prose/prose.mjs +10 -0
- package/dist/components/data-display/prose/prose.module.mjs +5 -0
- package/dist/components/data-display/table/index.mjs +1 -2
- package/dist/components/data-display/table/table.css +107 -0
- package/dist/components/data-display/table/table.d.mts +10 -8
- package/dist/components/data-display/table/table.mjs +26 -15
- package/dist/components/data-display/table/table.module.mjs +22 -0
- package/dist/components/data-display/tree/index.d.mts +2 -0
- package/dist/components/data-display/tree/index.mjs +1 -0
- package/dist/components/data-display/tree/tree.css +70 -0
- package/dist/components/data-display/tree/tree.d.mts +21 -0
- package/dist/components/data-display/tree/tree.mjs +144 -0
- package/dist/components/data-display/tree/tree.module.mjs +14 -0
- package/dist/components/feedback/alert/alert.css +42 -0
- package/dist/components/feedback/alert/alert.d.mts +3 -3
- package/dist/components/feedback/alert/alert.mjs +20 -23
- package/dist/components/feedback/alert/alert.module.mjs +14 -0
- package/dist/components/feedback/alert/index.mjs +1 -2
- package/dist/components/feedback/callout/callout.css +38 -0
- package/dist/components/feedback/callout/callout.d.mts +11 -0
- package/dist/components/feedback/callout/callout.mjs +38 -0
- package/dist/components/feedback/callout/callout.module.mjs +11 -0
- package/dist/components/feedback/callout/index.d.mts +2 -0
- package/dist/components/feedback/callout/index.mjs +1 -0
- package/dist/components/feedback/empty-state/empty-state.css +36 -0
- package/dist/components/feedback/empty-state/empty-state.d.mts +11 -0
- package/dist/components/feedback/empty-state/empty-state.mjs +27 -0
- package/dist/components/feedback/empty-state/empty-state.module.mjs +11 -0
- package/dist/components/feedback/empty-state/index.d.mts +2 -0
- package/dist/components/feedback/empty-state/index.mjs +1 -0
- package/dist/components/feedback/progress/index.mjs +1 -2
- package/dist/components/feedback/progress/progress.css +78 -0
- package/dist/components/feedback/progress/progress.d.mts +5 -4
- package/dist/components/feedback/progress/progress.mjs +17 -3
- package/dist/components/feedback/progress/progress.module.mjs +12 -0
- package/dist/components/feedback/skeleton/index.mjs +1 -2
- package/dist/components/feedback/skeleton/skeleton.css +64 -0
- package/dist/components/feedback/skeleton/skeleton.d.mts +2 -2
- package/dist/components/feedback/skeleton/skeleton.mjs +19 -2
- package/dist/components/feedback/skeleton/skeleton.module.mjs +17 -0
- package/dist/components/feedback/spinner/index.mjs +1 -2
- package/dist/components/feedback/spinner/spinner.css +40 -0
- package/dist/components/feedback/spinner/spinner.d.mts +2 -2
- package/dist/components/feedback/spinner/spinner.mjs +13 -7
- package/dist/components/feedback/spinner/spinner.module.mjs +12 -0
- package/dist/components/feedback/toast/context.d.mts +8 -9
- package/dist/components/feedback/toast/provider.css +69 -0
- package/dist/components/feedback/toast/provider.d.mts +2 -3
- package/dist/components/feedback/toast/provider.mjs +17 -13
- package/dist/components/feedback/toast/provider.module.mjs +12 -0
- package/dist/components/feedback/toast/toast.d.mts +2 -2
- package/dist/components/form/autocomplete/autocomplete.css +154 -0
- package/dist/components/form/autocomplete/autocomplete.d.mts +2 -2
- package/dist/components/form/autocomplete/autocomplete.mjs +70 -46
- package/dist/components/form/autocomplete/autocomplete.module.mjs +21 -0
- package/dist/components/form/autocomplete/index.mjs +1 -2
- package/dist/components/form/calendar/calendar.css +98 -0
- package/dist/components/form/calendar/calendar.d.mts +15 -0
- package/dist/components/form/calendar/calendar.mjs +182 -0
- package/dist/components/form/calendar/calendar.module.mjs +18 -0
- package/dist/components/form/calendar/index.d.mts +2 -0
- package/dist/components/form/calendar/index.mjs +1 -0
- package/dist/components/form/checkbox/checkbox.css +90 -0
- package/dist/components/form/checkbox/checkbox.d.mts +4 -2
- package/dist/components/form/checkbox/checkbox.mjs +29 -27
- package/dist/components/form/checkbox/checkbox.module.mjs +13 -0
- package/dist/components/form/checkbox/index.mjs +1 -2
- package/dist/components/form/checkbox-card/checkbox-card.css +138 -0
- package/dist/components/form/checkbox-card/checkbox-card.d.mts +3 -3
- package/dist/components/form/checkbox-card/checkbox-card.mjs +17 -23
- package/dist/components/form/checkbox-card/checkbox-card.module.mjs +17 -0
- package/dist/components/form/checkbox-card/index.mjs +1 -2
- package/dist/components/form/checkbox-group/checkbox-group.css +15 -0
- package/dist/components/form/checkbox-group/checkbox-group.d.mts +7 -5
- package/dist/components/form/checkbox-group/checkbox-group.mjs +12 -16
- package/dist/components/form/checkbox-group/checkbox-group.module.mjs +8 -0
- package/dist/components/form/checkbox-group/index.d.mts +4 -3
- package/dist/components/form/color-picker/color-picker.css +172 -0
- package/dist/components/form/color-picker/color-picker.d.mts +29 -0
- package/dist/components/form/color-picker/color-picker.mjs +239 -0
- package/dist/components/form/color-picker/color-picker.module.mjs +20 -0
- package/dist/components/form/color-picker/index.d.mts +2 -0
- package/dist/components/form/color-picker/index.mjs +1 -0
- package/dist/components/form/combobox/combobox.css +143 -0
- package/dist/components/form/combobox/combobox.d.mts +33 -0
- package/dist/components/form/combobox/combobox.mjs +278 -0
- package/dist/components/form/combobox/combobox.module.mjs +19 -0
- package/dist/components/form/combobox/index.d.mts +2 -0
- package/dist/components/form/combobox/index.mjs +1 -0
- package/dist/components/form/date-field/date-field.css +31 -0
- package/dist/components/form/date-field/date-field.d.mts +9 -0
- package/dist/components/form/date-field/date-field.mjs +20 -0
- package/dist/components/form/date-field/date-field.module.mjs +5 -0
- package/dist/components/form/date-field/index.d.mts +2 -0
- package/dist/components/form/date-field/index.mjs +1 -0
- package/dist/components/form/date-picker/date-picker.css +90 -0
- package/dist/components/form/date-picker/date-picker.d.mts +13 -0
- package/dist/components/form/date-picker/date-picker.mjs +77 -0
- package/dist/components/form/date-picker/date-picker.module.mjs +14 -0
- package/dist/components/form/date-picker/index.d.mts +2 -0
- package/dist/components/form/date-picker/index.mjs +1 -0
- package/dist/components/form/file-field/file-field.css +88 -0
- package/dist/components/form/file-field/file-field.d.mts +9 -6
- package/dist/components/form/file-field/file-field.mjs +130 -37
- package/dist/components/form/file-field/file-field.module.mjs +17 -0
- package/dist/components/form/file-field/index.d.mts +5 -3
- package/dist/components/form/file-field/index.mjs +2 -1
- package/dist/components/form/form/form.css +11 -0
- package/dist/components/form/form/form.d.mts +4 -3
- package/dist/components/form/form/form.mjs +2 -1
- package/dist/components/form/form/form.module.mjs +5 -0
- package/dist/components/form/form/index.mjs +1 -2
- package/dist/components/form/form-control/form-control.css +43 -0
- package/dist/components/form/form-control/form-control.d.mts +2 -2
- package/dist/components/form/form-control/form-control.mjs +11 -10
- package/dist/components/form/form-control/form-control.module.mjs +12 -0
- package/dist/components/form/form-control/index.mjs +1 -2
- package/dist/components/form/number-field/cast.d.mts +2 -3
- package/dist/components/form/number-field/cast.mjs +3 -22
- package/dist/components/form/number-field/index.mjs +1 -2
- package/dist/components/form/number-field/number-field.css +122 -0
- package/dist/components/form/number-field/number-field.d.mts +10 -9
- package/dist/components/form/number-field/number-field.mjs +126 -54
- package/dist/components/form/number-field/number-field.module.mjs +10 -0
- package/dist/components/form/password-input/index.mjs +1 -2
- package/dist/components/form/password-input/password-input.css +88 -0
- package/dist/components/form/password-input/password-input.d.mts +2 -2
- package/dist/components/form/password-input/password-input.mjs +15 -12
- package/dist/components/form/password-input/password-input.module.mjs +12 -0
- package/dist/components/form/radio/index.mjs +1 -2
- package/dist/components/form/radio/radio.css +89 -0
- package/dist/components/form/radio/radio.d.mts +3 -2
- package/dist/components/form/radio/radio.mjs +15 -19
- package/dist/components/form/radio/radio.module.mjs +16 -0
- package/dist/components/form/radio-card/index.mjs +1 -2
- package/dist/components/form/radio-card/radio-card.css +147 -0
- package/dist/components/form/radio-card/radio-card.d.mts +4 -3
- package/dist/components/form/radio-card/radio-card.mjs +17 -23
- package/dist/components/form/radio-card/radio-card.module.mjs +19 -0
- package/dist/components/form/range-slider/index.d.mts +2 -0
- package/dist/components/form/range-slider/index.mjs +1 -0
- package/dist/components/form/range-slider/range-slider.css +67 -0
- package/dist/components/form/range-slider/range-slider.d.mts +31 -0
- package/dist/components/form/range-slider/range-slider.mjs +135 -0
- package/dist/components/form/range-slider/range-slider.module.mjs +14 -0
- package/dist/components/form/select/index.mjs +1 -2
- package/dist/components/form/select/select.css +74 -0
- package/dist/components/form/select/select.d.mts +2 -2
- package/dist/components/form/select/select.mjs +25 -8
- package/dist/components/form/select/select.module.mjs +12 -0
- package/dist/components/form/slider/index.mjs +1 -2
- package/dist/components/form/slider/range-input-class.css +97 -0
- package/dist/components/form/slider/range-input-class.d.mts +7 -0
- package/dist/components/form/slider/range-input-class.mjs +10 -0
- package/dist/components/form/slider/range-input-class.module.mjs +8 -0
- package/dist/components/form/slider/slider.css +55 -0
- package/dist/components/form/slider/slider.d.mts +6 -6
- package/dist/components/form/slider/slider.mjs +44 -11
- package/dist/components/form/slider/slider.module.mjs +12 -0
- package/dist/components/form/switch/index.mjs +1 -2
- package/dist/components/form/switch/switch.css +103 -0
- package/dist/components/form/switch/switch.d.mts +2 -2
- package/dist/components/form/switch/switch.mjs +14 -17
- package/dist/components/form/switch/switch.module.mjs +16 -0
- package/dist/components/form/text-field/index.mjs +1 -2
- package/dist/components/form/text-field/text-field.css +41 -0
- package/dist/components/form/text-field/text-field.d.mts +4 -4
- package/dist/components/form/text-field/text-field.mjs +2 -3
- package/dist/components/form/text-field/text-field.module.mjs +5 -0
- package/dist/components/form/textarea/index.mjs +1 -2
- package/dist/components/form/textarea/textarea.css +50 -0
- package/dist/components/form/textarea/textarea.d.mts +3 -2
- package/dist/components/form/textarea/textarea.mjs +6 -20
- package/dist/components/form/textarea/textarea.module.mjs +9 -0
- package/dist/components/icons/base.css +40 -0
- package/dist/components/icons/base.d.mts +4 -5
- package/dist/components/icons/base.mjs +10 -10
- package/dist/components/icons/base.module.mjs +13 -0
- package/dist/components/icons/browsers.d.mts +5 -6
- package/dist/components/icons/color-scale.d.mts +2 -3
- package/dist/components/icons/github-mark.d.mts +2 -3
- package/dist/components/icons/logo.css +17 -0
- package/dist/components/icons/logo.d.mts +3 -4
- package/dist/components/icons/logo.mjs +4 -3
- package/dist/components/icons/logo.module.mjs +9 -0
- package/dist/components/icons/lucide-deep.d.mts +3 -1
- package/dist/components/icons/lucide-imports.d.mts +3 -1
- package/dist/components/icons/lucide-imports.mjs +3 -1
- package/dist/components/icons/lucide.d.mts +60 -60
- package/dist/components/icons/qiita.d.mts +2 -3
- package/dist/components/icons/twitter.css +9 -0
- package/dist/components/icons/twitter.d.mts +2 -3
- package/dist/components/icons/twitter.mjs +2 -1
- package/dist/components/icons/twitter.module.mjs +5 -0
- package/dist/components/icons/vertical-writing.d.mts +2 -3
- package/dist/components/index.d.mts +48 -9
- package/dist/components/index.mjs +32 -10
- package/dist/components/layout/_shared/gap.css +25 -0
- package/dist/components/layout/_shared/gap.d.mts +8 -9
- package/dist/components/layout/_shared/gap.mjs +6 -5
- package/dist/components/layout/_shared/gap.module.mjs +11 -0
- package/dist/components/layout/_shared/padding.css +25 -0
- package/dist/components/layout/_shared/padding.d.mts +8 -9
- package/dist/components/layout/_shared/padding.mjs +6 -5
- package/dist/components/layout/_shared/padding.module.mjs +11 -0
- package/dist/components/layout/grid/grid.css +93 -0
- package/dist/components/layout/grid/grid.d.mts +5 -6
- package/dist/components/layout/grid/grid.mjs +21 -20
- package/dist/components/layout/grid/grid.module.mjs +25 -0
- package/dist/components/layout/grid/index.mjs +1 -2
- package/dist/components/layout/resizable-panels/index.d.mts +18 -0
- package/dist/components/layout/resizable-panels/index.mjs +9 -0
- package/dist/components/layout/resizable-panels/resizable-panels.css +77 -0
- package/dist/components/layout/resizable-panels/resizable-panels.d.mts +22 -0
- package/dist/components/layout/resizable-panels/resizable-panels.mjs +164 -0
- package/dist/components/layout/resizable-panels/resizable-panels.module.mjs +16 -0
- package/dist/components/layout/separator/index.mjs +1 -2
- package/dist/components/layout/separator/separator.css +37 -0
- package/dist/components/layout/separator/separator.d.mts +2 -2
- package/dist/components/layout/separator/separator.mjs +12 -9
- package/dist/components/layout/separator/separator.module.mjs +12 -0
- package/dist/components/layout/stack/index.mjs +1 -2
- package/dist/components/layout/stack/stack.css +49 -0
- package/dist/components/layout/stack/stack.d.mts +3 -4
- package/dist/components/layout/stack/stack.mjs +11 -10
- package/dist/components/layout/stack/stack.module.mjs +17 -0
- package/dist/components/navigation/anchor/anchor.css +29 -0
- package/dist/components/navigation/anchor/anchor.d.mts +2 -2
- package/dist/components/navigation/anchor/anchor.mjs +5 -2
- package/dist/components/navigation/anchor/anchor.module.mjs +8 -0
- package/dist/components/navigation/anchor/index.mjs +1 -2
- package/dist/components/navigation/breadcrumb/breadcrumb.css +72 -0
- package/dist/components/navigation/breadcrumb/breadcrumb.d.mts +5 -5
- package/dist/components/navigation/breadcrumb/breadcrumb.mjs +15 -9
- package/dist/components/navigation/breadcrumb/breadcrumb.module.mjs +14 -0
- package/dist/components/navigation/breadcrumb/index.d.mts +2 -3
- package/dist/components/navigation/pagination/index.mjs +1 -2
- package/dist/components/navigation/pagination/pagination.css +36 -0
- package/dist/components/navigation/pagination/pagination.d.mts +2 -2
- package/dist/components/navigation/pagination/pagination.mjs +9 -8
- package/dist/components/navigation/pagination/pagination.module.mjs +11 -0
- package/dist/components/navigation/side-nav/index.d.mts +16 -0
- package/dist/components/navigation/side-nav/index.mjs +10 -0
- package/dist/components/navigation/side-nav/side-nav.css +73 -0
- package/dist/components/navigation/side-nav/side-nav.d.mts +32 -0
- package/dist/components/navigation/side-nav/side-nav.mjs +62 -0
- package/dist/components/navigation/side-nav/side-nav.module.mjs +11 -0
- package/dist/components/navigation/stepper/index.d.mts +2 -0
- package/dist/components/navigation/stepper/index.mjs +1 -0
- package/dist/components/navigation/stepper/stepper.css +151 -0
- package/dist/components/navigation/stepper/stepper.d.mts +20 -0
- package/dist/components/navigation/stepper/stepper.mjs +87 -0
- package/dist/components/navigation/stepper/stepper.module.mjs +29 -0
- package/dist/components/navigation/table-of-contents/index.d.mts +2 -0
- package/dist/components/navigation/table-of-contents/index.mjs +1 -0
- package/dist/components/navigation/table-of-contents/table-of-contents.css +17 -0
- package/dist/components/navigation/table-of-contents/table-of-contents.d.mts +12 -0
- package/dist/components/navigation/table-of-contents/table-of-contents.mjs +94 -0
- package/dist/components/navigation/table-of-contents/table-of-contents.module.mjs +8 -0
- package/dist/components/navigation/tabs/index.d.mts +2 -3
- package/dist/components/navigation/tabs/tabs.css +70 -0
- package/dist/components/navigation/tabs/tabs.d.mts +5 -6
- package/dist/components/navigation/tabs/tabs.mjs +51 -42
- package/dist/components/navigation/tabs/tabs.module.mjs +12 -0
- package/dist/components/observers/fragment-instance.d.mts +1 -0
- package/dist/components/observers/in-view/in-view.d.mts +11 -0
- package/dist/components/observers/in-view/in-view.mjs +60 -0
- package/dist/components/observers/in-view/index.d.mts +2 -0
- package/dist/components/observers/in-view/index.mjs +1 -0
- package/dist/components/observers/resize/index.d.mts +2 -0
- package/dist/components/observers/resize/index.mjs +1 -0
- package/dist/components/observers/resize/resize.d.mts +7 -0
- package/dist/components/observers/resize/resize.mjs +25 -0
- package/dist/components/overlays/_internal/modal-dialog-context.d.mts +4 -5
- package/dist/components/overlays/_internal/use-can-hover.d.mts +2 -3
- package/dist/components/overlays/_internal/use-hover-intent.d.mts +3 -4
- package/dist/components/overlays/_internal/use-list-navigation.d.mts +17 -11
- package/dist/components/overlays/_internal/use-list-navigation.mjs +42 -26
- package/dist/components/overlays/command-palette/command-palette.css +91 -0
- package/dist/components/overlays/command-palette/command-palette.d.mts +25 -0
- package/dist/components/overlays/command-palette/command-palette.mjs +139 -0
- package/dist/components/overlays/command-palette/command-palette.module.mjs +14 -0
- package/dist/components/overlays/command-palette/index.d.mts +2 -0
- package/dist/components/overlays/command-palette/index.mjs +1 -0
- package/dist/components/overlays/context-menu/context-menu.d.mts +13 -0
- package/dist/components/overlays/context-menu/context-menu.mjs +79 -0
- package/dist/components/overlays/context-menu/index.d.mts +21 -0
- package/dist/components/overlays/context-menu/index.mjs +13 -0
- package/dist/components/overlays/dialog/dialog.css +31 -0
- package/dist/components/overlays/dialog/dialog.d.mts +4 -5
- package/dist/components/overlays/dialog/dialog.mjs +10 -7
- package/dist/components/overlays/dialog/dialog.module.mjs +10 -0
- package/dist/components/overlays/dialog/index.d.mts +2 -3
- package/dist/components/overlays/drawer/drawer.css +48 -0
- package/dist/components/overlays/drawer/drawer.d.mts +2 -3
- package/dist/components/overlays/drawer/drawer.mjs +11 -10
- package/dist/components/overlays/drawer/drawer.module.mjs +13 -0
- package/dist/components/overlays/drawer/index.mjs +1 -2
- package/dist/components/overlays/dropdown-menu/dropdown-menu.d.mts +7 -10
- package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +10 -9
- package/dist/components/overlays/dropdown-menu/hooks.d.mts +7 -6
- package/dist/components/overlays/dropdown-menu/hooks.mjs +3 -3
- package/dist/components/overlays/dropdown-menu/index.d.mts +8 -10
- package/dist/components/overlays/dropdown-menu/shared.css +51 -0
- package/dist/components/overlays/dropdown-menu/shared.d.mts +3 -6
- package/dist/components/overlays/dropdown-menu/shared.mjs +4 -6
- package/dist/components/overlays/dropdown-menu/shared.module.mjs +8 -0
- package/dist/components/overlays/dropdown-menu/sub-menu.css +28 -0
- package/dist/components/overlays/dropdown-menu/sub-menu.d.mts +3 -6
- package/dist/components/overlays/dropdown-menu/sub-menu.mjs +15 -15
- package/dist/components/overlays/dropdown-menu/sub-menu.module.mjs +9 -0
- package/dist/components/overlays/dropdown-menu/use-safe-triangle.d.mts +2 -3
- package/dist/components/overlays/list-box/hooks.d.mts +6 -5
- package/dist/components/overlays/list-box/hooks.mjs +5 -4
- package/dist/components/overlays/list-box/index.d.mts +2 -3
- package/dist/components/overlays/list-box/list-box.css +74 -0
- package/dist/components/overlays/list-box/list-box.d.mts +5 -6
- package/dist/components/overlays/list-box/list-box.mjs +15 -13
- package/dist/components/overlays/list-box/list-box.module.mjs +10 -0
- package/dist/components/overlays/modal/index.mjs +1 -2
- package/dist/components/overlays/modal/modal.css +119 -0
- package/dist/components/overlays/modal/modal.d.mts +2 -3
- package/dist/components/overlays/modal/modal.mjs +14 -11
- package/dist/components/overlays/modal/modal.module.mjs +11 -0
- package/dist/components/overlays/popover/anchor-positioning.d.mts +4 -4
- package/dist/components/overlays/popover/escape-stack.d.mts +2 -3
- package/dist/components/overlays/popover/hooks.d.mts +7 -7
- package/dist/components/overlays/popover/index.d.mts +2 -2
- package/dist/components/overlays/popover/popover.css +51 -0
- package/dist/components/overlays/popover/popover.d.mts +4 -4
- package/dist/components/overlays/popover/popover.mjs +11 -5
- package/dist/components/overlays/popover/popover.module.mjs +11 -0
- package/dist/components/overlays/tooltip/bridge.css +68 -0
- package/dist/components/overlays/tooltip/bridge.d.mts +2 -3
- package/dist/components/overlays/tooltip/bridge.mjs +7 -21
- package/dist/components/overlays/tooltip/bridge.module.mjs +11 -0
- package/dist/components/overlays/tooltip/index.d.mts +2 -2
- package/dist/components/overlays/tooltip/tooltip.css +15 -0
- package/dist/components/overlays/tooltip/tooltip.d.mts +5 -6
- package/dist/components/overlays/tooltip/tooltip.mjs +3 -2
- package/dist/components/overlays/tooltip/tooltip.module.mjs +5 -0
- package/dist/components/providers/index.d.mts +1 -2
- package/dist/components/providers/portal-root.d.mts +9 -7
- package/dist/components/providers/portal-root.mjs +7 -7
- package/dist/components/providers/ui-provider.d.mts +2 -6
- package/dist/components/providers/ui-provider.mjs +1 -5
- package/dist/helpers/chain.d.mts +2 -2
- package/dist/helpers/chain.mjs +0 -23
- package/dist/helpers/create-safe-context.d.mts +2 -2
- package/dist/helpers/create-safe-context.mjs +0 -17
- package/dist/helpers/index.d.mts +1 -2
- package/dist/helpers/index.mjs +2 -3
- package/dist/helpers/merge-props.d.mts +2 -2
- package/dist/helpers/merge-props.mjs +2 -37
- package/dist/helpers/merge-refs.d.mts +2 -3
- package/dist/helpers/merge-refs.mjs +0 -32
- package/dist/hooks/click-away/index.d.mts +2 -3
- package/dist/hooks/controllable-state/index.d.mts +2 -2
- package/dist/hooks/controllable-state/index.mjs +9 -11
- package/dist/hooks/index.d.mts +2 -20
- package/dist/hooks/index.mjs +2 -19
- package/dist/hooks/writing-mode/index.d.mts +15 -5
- package/dist/hooks/writing-mode/index.mjs +21 -14
- package/dist/i18n/current.d.mts +23 -0
- package/dist/i18n/current.mjs +43 -0
- package/dist/i18n/en.d.mts +2 -3
- package/dist/i18n/en.mjs +46 -0
- package/dist/i18n/index.d.mts +3 -2
- package/dist/i18n/index.mjs +4 -3
- package/dist/i18n/ja.d.mts +2 -3
- package/dist/i18n/ja.mjs +46 -0
- package/dist/i18n/messages.d.mts +81 -3
- package/dist/i18n/usage.d.mts +8 -0
- package/dist/i18n/usage.mjs +131 -0
- package/dist/index.d.mts +29 -34
- package/dist/index.mjs +32 -35
- package/dist/integrations/_shared/openui-defs.d.mts +3 -4
- package/dist/integrations/_shared/openui-defs.mjs +123 -54
- package/dist/integrations/_shared/renderers.css +50 -0
- package/dist/integrations/_shared/renderers.d.mts +71 -52
- package/dist/integrations/_shared/renderers.mjs +288 -30
- package/dist/integrations/_shared/renderers.module.mjs +14 -0
- package/dist/integrations/_shared/schemas.d.mts +384 -102
- package/dist/integrations/_shared/schemas.mjs +165 -27
- package/dist/integrations/ai-sdk/index.d.mts +2 -2
- package/dist/integrations/ai-sdk/index.mjs +1 -2
- package/dist/integrations/ai-sdk/map-parts.d.mts +25 -7
- package/dist/integrations/ai-sdk/map-parts.mjs +28 -3
- package/dist/integrations/json-render/catalog.d.mts +336 -17
- package/dist/integrations/json-render/catalog.mjs +120 -57
- package/dist/integrations/json-render/registry.d.mts +3 -4
- package/dist/integrations/json-render/registry.mjs +38 -4
- package/dist/integrations/openui/form-views.d.mts +23 -18
- package/dist/integrations/openui/form-views.mjs +27 -3
- package/dist/integrations/openui/library.d.mts +59 -6
- package/dist/integrations/openui/library.mjs +18 -3
- package/dist/integrations/openui/prompt.d.mts +2 -3
- package/dist/internal/accepts-file.d.mts +8 -0
- package/dist/internal/accepts-file.mjs +19 -0
- package/dist/internal/carries-files.d.mts +3 -0
- package/dist/internal/carries-files.mjs +4 -0
- package/dist/internal/clamp.d.mts +2 -3
- package/dist/internal/clamp.mjs +0 -11
- package/dist/internal/commit-input-value.d.mts +10 -0
- package/dist/internal/commit-input-value.mjs +15 -0
- package/dist/internal/dropped-files.d.mts +3 -0
- package/dist/internal/dropped-files.mjs +8 -0
- package/dist/internal/focus-trap.d.mts +5 -6
- package/dist/internal/focus-trap.mjs +4 -4
- package/dist/internal/hex-color.d.mts +22 -0
- package/dist/internal/hex-color.mjs +53 -0
- package/dist/internal/iso-date.d.mts +39 -0
- package/dist/internal/iso-date.mjs +98 -0
- package/dist/internal/to-precision.d.mts +2 -3
- package/dist/internal/to-precision.mjs +0 -8
- package/dist/styles/index.css +513 -2526
- package/dist/styles/tailwind.css +217 -17
- package/dist/styles/tokens.d.mts +1 -2
- package/dist/styles/tokens.mjs +1 -2
- package/dist/types/variables.d.mts +7 -9
- package/docs/GUIDE.md +239 -72
- package/docs/llms.txt +11 -7
- package/docs/props.generated.json +2156 -309
- package/docs/references/ai-chat.md +345 -62
- package/docs/references/color.md +222 -78
- package/docs/references/components.md +1667 -242
- package/docs/references/generative-ui.md +126 -17
- package/docs/references/interaction-design.md +65 -35
- package/docs/references/spatial-design.md +83 -63
- package/docs/references/types.md +101 -0
- package/docs/references/typography.md +159 -51
- package/package.json +65 -63
- package/dist/components/_internal/focus-ring.d.mts +0 -8
- package/dist/components/_internal/focus-ring.mjs +0 -8
- package/dist/components/layout/scroll-linked/index.d.mts +0 -2
- package/dist/components/layout/scroll-linked/index.mjs +0 -2
- package/dist/components/layout/scroll-linked/scroll-linked.d.mts +0 -14
- package/dist/components/layout/scroll-linked/scroll-linked.mjs +0 -59
- package/dist/helpers/cn.d.mts +0 -5
- package/dist/helpers/cn.mjs +0 -27
- package/dist/hooks/breakpoint/index.d.mts +0 -5
- package/dist/hooks/breakpoint/index.mjs +0 -24
- package/dist/hooks/client/index.d.mts +0 -4
- package/dist/hooks/client/index.mjs +0 -6
- package/dist/hooks/clipboard/index.d.mts +0 -7
- package/dist/hooks/clipboard/index.mjs +0 -15
- package/dist/hooks/debounced-transition/index.d.mts +0 -5
- package/dist/hooks/debounced-transition/index.mjs +0 -49
- package/dist/hooks/deferred-debounce/index.d.mts +0 -4
- package/dist/hooks/deferred-debounce/index.mjs +0 -9
- package/dist/hooks/disclosure/index.d.mts +0 -10
- package/dist/hooks/disclosure/index.mjs +0 -20
- package/dist/hooks/hover/index.d.mts +0 -12
- package/dist/hooks/hover/index.mjs +0 -19
- package/dist/hooks/intersection-observer/index.d.mts +0 -3
- package/dist/hooks/intersection-observer/index.mjs +0 -3
- package/dist/hooks/intersection-observer/use-in-view.d.mts +0 -11
- package/dist/hooks/intersection-observer/use-in-view.mjs +0 -18
- package/dist/hooks/intersection-observer/use-intersection-observer.d.mts +0 -11
- package/dist/hooks/intersection-observer/use-intersection-observer.mjs +0 -33
- package/dist/hooks/interval/index.d.mts +0 -4
- package/dist/hooks/interval/index.mjs +0 -19
- package/dist/hooks/resize/index.d.mts +0 -8
- package/dist/hooks/resize/index.mjs +0 -24
- package/dist/hooks/scroll-direction/index.d.mts +0 -13
- package/dist/hooks/scroll-direction/index.mjs +0 -67
- package/dist/hooks/scroll-lock/index.d.mts +0 -9
- package/dist/hooks/scroll-lock/index.mjs +0 -59
- package/dist/hooks/step/index.d.mts +0 -15
- package/dist/hooks/step/index.mjs +0 -39
- package/dist/hooks/timeout/index.d.mts +0 -4
- package/dist/hooks/timeout/index.mjs +0 -19
- package/dist/hooks/window-resize/index.d.mts +0 -11
- package/dist/hooks/window-resize/index.mjs +0 -21
- package/dist/hooks/window-size/index.d.mts +0 -8
- package/dist/hooks/window-size/index.mjs +0 -31
- package/dist/i18n/context.d.mts +0 -9
- package/dist/i18n/context.mjs +0 -19
- package/dist/styles/base.css +0 -315
- package/dist/styles/tokens.css +0 -380
- package/dist/styles/tokens.generated.d.mts +0 -840
- package/dist/styles/tokens.generated.mjs +0 -813
- package/dist/styles/utilities.css +0 -62
- package/docs/references/helpers.md +0 -223
- package/docs/references/hooks.md +0 -301
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
# @k8ordo/ui AI chat components
|
|
2
2
|
|
|
3
|
-
Components for building an AI chat UI: the conversation log, messages, the input box, reasoning display,
|
|
3
|
+
Components for building an AI chat UI: the conversation log, messages and their actions, the input box with attachments, reasoning display, tool-invocation display with approval, attachments, and sources. Import them from their dedicated subpaths rather than from the root.
|
|
4
4
|
|
|
5
5
|
## Importing
|
|
6
6
|
|
|
7
7
|
```tsx
|
|
8
8
|
// Core components (no extra dependencies)
|
|
9
9
|
import {
|
|
10
|
+
Attachment,
|
|
10
11
|
Conversation,
|
|
11
12
|
Message,
|
|
12
13
|
PromptInput,
|
|
13
14
|
Reasoning,
|
|
15
|
+
Source,
|
|
14
16
|
Suggestion,
|
|
15
17
|
ToolInvocation,
|
|
16
18
|
} from '@k8ordo/ui/ai';
|
|
17
|
-
|
|
18
|
-
// Streaming-aware Markdown rendering (optional peer: streamdown)
|
|
19
|
-
import { Response } from '@k8ordo/ui/ai/response';
|
|
20
|
-
|
|
21
19
|
// AI SDK integration (optional peer: ai)
|
|
22
20
|
import { mapMessageParts } from '@k8ordo/ui/ai-sdk';
|
|
21
|
+
// Streaming-aware Markdown rendering (optional peer: streamdown)
|
|
22
|
+
import { Response } from '@k8ordo/ui/ai/response';
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
The types are exported from `@k8ordo/ui/ai` too:
|
|
26
26
|
|
|
27
27
|
- `ChatStatus`: `'ready' | 'submitted' | 'streaming' | 'error'` (compatible with the AI SDK's `status`)
|
|
28
28
|
- `ToolState`: `'input-streaming' | 'input-available' | 'approval-requested' | 'approval-responded' | 'output-available' | 'output-error' | 'output-denied'` (1:1 with the AI SDK v7 tool states)
|
|
29
|
+
- `ToolApproval`: `{ id: string; approved?: boolean; reason?: string; requestReason?: string; isAutomatic?: boolean }` (the shape of the AI SDK's `part.approval`, so the part's own object can be passed as is)
|
|
30
|
+
- `ToolApprovalResponse`: `{ id: string; approved: boolean }` (what `ToolInvocation` answers with)
|
|
31
|
+
- `MessageFeedback`: `'positive' | 'negative'`
|
|
29
32
|
|
|
30
33
|
### Setting up the optional peers
|
|
31
34
|
|
|
@@ -38,30 +41,28 @@ pnpm add streamdown
|
|
|
38
41
|
pnpm add ai
|
|
39
42
|
```
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
`Response` styles what streamdown renders itself, through the
|
|
45
|
+
`data-streamdown` attribute streamdown puts on every element, so it needs no
|
|
46
|
+
Tailwind. Load streamdown's own stylesheet only when you turn on its `animated`
|
|
47
|
+
option, which keeps its keyframes there:
|
|
42
48
|
|
|
43
49
|
```tsx
|
|
44
50
|
import 'streamdown/styles.css';
|
|
45
51
|
```
|
|
46
52
|
|
|
47
|
-
```css
|
|
48
|
-
/* Add to your app's CSS entry (the path is relative from the CSS file to node_modules) */
|
|
49
|
-
@source '../node_modules/streamdown/dist/*.js';
|
|
50
|
-
```
|
|
51
|
-
|
|
52
53
|
The `useChat` used in the examples below comes from the AI SDK's React bindings (`pnpm add @ai-sdk/react`).
|
|
53
54
|
|
|
54
|
-
The "default" shown for `label`, `sendLabel`, and similar props below is the
|
|
55
|
+
The "default" shown for `label`, `sendLabel`, and similar props below is the built-in Japanese dictionary's. The text actually used follows `@k8ordo/i18n`'s current locale (see [i18n](components.md)). Passing the prop directly wins over the dictionary.
|
|
55
56
|
|
|
56
57
|
## The whole picture
|
|
57
58
|
|
|
58
|
-
`Conversation` (the log), `Message` (a bubble), and `PromptInput` (the input box) form the skeleton. `Response`, `Reasoning`,
|
|
59
|
+
`Conversation` (the log), `Message` (a bubble), and `PromptInput` (the input box) form the skeleton. `Response`, `Reasoning`, `ToolInvocation`, `Attachment`, `Source`, and the message actions can be added later — [AI SDK integration](#ai-sdk-integration-mapmessageparts) shows all of them together.
|
|
59
60
|
|
|
60
61
|
```tsx
|
|
61
62
|
'use client';
|
|
63
|
+
import { useChat } from '@ai-sdk/react';
|
|
62
64
|
import { Avatar, AssistantIcon } from '@k8ordo/ui';
|
|
63
65
|
import { Conversation, Message, PromptInput } from '@k8ordo/ui/ai';
|
|
64
|
-
import { useChat } from '@ai-sdk/react';
|
|
65
66
|
import type { UIMessage } from 'ai';
|
|
66
67
|
|
|
67
68
|
const textOf = (m: UIMessage) =>
|
|
@@ -71,22 +72,31 @@ export function Chat() {
|
|
|
71
72
|
const { messages, sendMessage, status, stop } = useChat();
|
|
72
73
|
|
|
73
74
|
return (
|
|
74
|
-
<div
|
|
75
|
+
<div
|
|
76
|
+
style={{
|
|
77
|
+
display: 'flex',
|
|
78
|
+
height: '100%',
|
|
79
|
+
flexDirection: 'column',
|
|
80
|
+
gap: 'calc(var(--spacing) * 3)',
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
75
83
|
<Conversation.Root>
|
|
76
84
|
<Conversation.Messages isStreaming={status === 'streaming'}>
|
|
77
85
|
{messages.map((m) => (
|
|
78
86
|
<Message.Root
|
|
87
|
+
avatar={
|
|
88
|
+
m.role === 'user' ? undefined : (
|
|
89
|
+
<Avatar
|
|
90
|
+
color="primary"
|
|
91
|
+
icon={<AssistantIcon />}
|
|
92
|
+
name="AI"
|
|
93
|
+
size="sm"
|
|
94
|
+
/>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
79
97
|
from={m.role === 'user' ? 'user' : 'assistant'}
|
|
80
98
|
key={m.id}
|
|
81
99
|
>
|
|
82
|
-
{m.role !== 'user' && (
|
|
83
|
-
<Avatar
|
|
84
|
-
color="primary"
|
|
85
|
-
icon={<AssistantIcon />}
|
|
86
|
-
name="AI"
|
|
87
|
-
size="sm"
|
|
88
|
-
/>
|
|
89
|
-
)}
|
|
90
100
|
<Message.Content>{textOf(m)}</Message.Content>
|
|
91
101
|
</Message.Root>
|
|
92
102
|
))}
|
|
@@ -133,7 +143,7 @@ Props (Conversation.ScrollButton):
|
|
|
133
143
|
|
|
134
144
|
## Message
|
|
135
145
|
|
|
136
|
-
A single message. `from="user"` renders as a right-aligned bubble; `from="assistant"` renders as running text.
|
|
146
|
+
A single message. `from="user"` renders as a right-aligned bubble; `from="assistant"` renders as running text. `avatar` sits beside the message, and the children stack in a column next to it — attachments, the content, sources, and the actions each get their own row.
|
|
137
147
|
|
|
138
148
|
```tsx
|
|
139
149
|
import { Message } from '@k8ordo/ui/ai';
|
|
@@ -142,7 +152,7 @@ import { Message } from '@k8ordo/ui/ai';
|
|
|
142
152
|
<Message.Content>Hello</Message.Content>
|
|
143
153
|
</Message.Root>
|
|
144
154
|
|
|
145
|
-
<Message.Root from="assistant">
|
|
155
|
+
<Message.Root avatar={<Avatar icon={<AssistantIcon />} name="AI" size="sm" />} from="assistant">
|
|
146
156
|
<Message.Content isStreaming>Text still streaming…</Message.Content>
|
|
147
157
|
</Message.Root>
|
|
148
158
|
```
|
|
@@ -150,14 +160,68 @@ import { Message } from '@k8ordo/ui/ai';
|
|
|
150
160
|
Props (Message.Root):
|
|
151
161
|
|
|
152
162
|
- `from`: `'user'` | `'assistant'` (required)
|
|
163
|
+
- `avatar`: ReactNode (shown beside the message: left for the assistant, right for the user)
|
|
164
|
+
- plus the other `div` attributes (`className` and `style` excluded)
|
|
153
165
|
|
|
154
166
|
Props (Message.Content):
|
|
155
167
|
|
|
156
168
|
- `isStreaming`: boolean (shows the streaming cursor when true)
|
|
169
|
+
- plus the other `div` attributes (`className` and `style` excluded)
|
|
170
|
+
|
|
171
|
+
### Message actions
|
|
172
|
+
|
|
173
|
+
`Message.Actions` is the row of icon buttons under a message. `Copy`, `Regenerate`, and `Feedback` carry their own icons and dictionary labels; `Action` is the generic one for anything else. Each shows its label as a tooltip.
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
<Message.Root avatar={avatar} from="assistant">
|
|
177
|
+
<Message.Content>{text}</Message.Content>
|
|
178
|
+
<Message.Actions>
|
|
179
|
+
<Message.Copy value={text} />
|
|
180
|
+
<Message.Regenerate
|
|
181
|
+
disabled={status === 'submitted' || status === 'streaming'}
|
|
182
|
+
onAction={() => regenerate({ messageId: message.id })}
|
|
183
|
+
/>
|
|
184
|
+
<Message.Feedback onChange={(value) => saveFeedback(message.id, value)} />
|
|
185
|
+
<Message.Action label="Share" onAction={() => share(message.id)}>
|
|
186
|
+
<LinkIcon size="sm" />
|
|
187
|
+
</Message.Action>
|
|
188
|
+
</Message.Actions>
|
|
189
|
+
</Message.Root>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
- `Copy` is an icon-only, `sm` [`CopyButton`](components.md#copybutton): it writes `value` to the clipboard, shows a check icon — or an error icon when the clipboard refuses — for two seconds, and announces 「コピーしました」 or 「コピーできませんでした」 through a `status` region. Nothing is thrown either way.
|
|
193
|
+
- `Regenerate` and `Action` take `onAction`; a returned promise keeps the button busy (`aria-busy`, `aria-disabled`, presses ignored) until it settles, so `() => regenerate(...)` does not need its own pending state. The button keeps focus meanwhile.
|
|
194
|
+
- `Feedback` is a pair of toggle buttons (`aria-pressed`). Pressing the pressed one again clears it, so `onChange` receives `null`.
|
|
195
|
+
|
|
196
|
+
Props (Message.Actions):
|
|
197
|
+
|
|
198
|
+
- `label`: string (default: `'メッセージの操作'`, used as the group's aria-label)
|
|
199
|
+
|
|
200
|
+
Props (Message.Action):
|
|
201
|
+
|
|
202
|
+
- `label`: string (required; the accessible name and the tooltip)
|
|
203
|
+
- `onAction`: `() => void | Promise<void>`
|
|
204
|
+
- `disabled`: boolean
|
|
205
|
+
- `children`: ReactNode (the icon, `size="sm"`)
|
|
206
|
+
|
|
207
|
+
Props (Message.Copy):
|
|
208
|
+
|
|
209
|
+
- `value`: string (required; the text to copy)
|
|
210
|
+
- `label`: string (default: `'コピー'`)
|
|
211
|
+
|
|
212
|
+
Props (Message.Regenerate):
|
|
213
|
+
|
|
214
|
+
- `onAction`: `() => void | Promise<void>` (required)
|
|
215
|
+
- `label`: string (default: `'再生成'`)
|
|
216
|
+
- `disabled`: boolean
|
|
217
|
+
|
|
218
|
+
Props (Message.Feedback):
|
|
219
|
+
|
|
220
|
+
- `value` / `defaultValue` / `onChange`: `MessageFeedback | null`, controlled or uncontrolled (`onChange` is `(value: MessageFeedback | null) => void`; `null` is no feedback)
|
|
157
221
|
|
|
158
222
|
## PromptInput
|
|
159
223
|
|
|
160
|
-
The submit form. Enter sends; Shift+Enter inserts a newline; the Enter that commits an IME conversion does not send. While `status` is `'submitted'` or `'streaming'`, `Submit` turns into a stop button. The body is trimmed, and
|
|
224
|
+
The submit form. Enter sends; Shift+Enter inserts a newline; the Enter that commits an IME conversion does not send. While `status` is `'submitted'` or `'streaming'`, `Submit` turns into a stop button. The body is trimmed, and a message with neither text nor attachments is never sent.
|
|
161
225
|
|
|
162
226
|
```tsx
|
|
163
227
|
import { PromptInput } from '@k8ordo/ui/ai';
|
|
@@ -172,12 +236,47 @@ import { PromptInput } from '@k8ordo/ui/ai';
|
|
|
172
236
|
</PromptInput.Root>;
|
|
173
237
|
```
|
|
174
238
|
|
|
239
|
+
### Attachments
|
|
240
|
+
|
|
241
|
+
Pass `accept` to take files. It turns on all three ways in — the `Attach` button's file picker, dropping files onto the input, and pasting them into the textarea — and filters every one of them by the same rule as `<input accept>` (the browser applies it only to the picker). A dropped folder is skipped, as on `FileField.Dropzone`. Without `accept` the input takes text only: `Attach` renders nothing, a pasted file is not taken, and a file dragged over the input shows the not-allowed cursor — the drop is still cancelled, so the browser never opens the file and leaves the chat.
|
|
242
|
+
|
|
243
|
+
`PromptInput.Attachments` lists the files waiting to be sent, image thumbnails included, each with a remove button. `onSubmit` receives them as a `FileList` in its second argument, which the AI SDK's `sendMessage` takes as is. The list empties after each submit, and a message with attachments but no text can be sent — pass `{ files }` alone then, since `sendMessage` turns `text: ''` into an empty text part that some providers reject.
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
<PromptInput.Root
|
|
247
|
+
accept="image/*,application/pdf"
|
|
248
|
+
maxFiles={4}
|
|
249
|
+
onStop={stop}
|
|
250
|
+
onSubmit={(text, files) =>
|
|
251
|
+
sendMessage(text === '' ? { files } : { text, files })
|
|
252
|
+
}
|
|
253
|
+
status={status}
|
|
254
|
+
>
|
|
255
|
+
<PromptInput.Attachments />
|
|
256
|
+
<PromptInput.Attach />
|
|
257
|
+
<PromptInput.Textarea placeholder="Type a message" />
|
|
258
|
+
<PromptInput.Submit />
|
|
259
|
+
</PromptInput.Root>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Put `Attachments` first: it takes a row of its own above the textarea. Choose `accept` from what your model reads — the AI SDK turns `image/*` and `text/*` into model input by itself, and other types need handling on your server.
|
|
263
|
+
|
|
175
264
|
Props (PromptInput.Root):
|
|
176
265
|
|
|
177
266
|
- `status`: ChatStatus (default: `'ready'`)
|
|
178
267
|
- `value` / `defaultValue` / `onChange`: supports both controlled and uncontrolled use (`onChange` is `(value: string) => void`)
|
|
179
|
-
- `onSubmit`: `(message: string) => void` (the trimmed body)
|
|
268
|
+
- `onSubmit`: `(message: string, files: FileList) => void` (the trimmed body, and the attachments — an empty `FileList` when there are none)
|
|
180
269
|
- `onStop`: `() => void` (when the stop button is pressed mid-send)
|
|
270
|
+
- `accept`: string (the file types to take, in `<input accept>` syntax; omit to take no files)
|
|
271
|
+
- `maxFiles`: number (files beyond it are dropped, first come first kept; `1` also makes the picker single-select)
|
|
272
|
+
|
|
273
|
+
Props (PromptInput.Attachments):
|
|
274
|
+
|
|
275
|
+
- `label`: string (default: `'添付ファイル'`, used as the list's aria-label)
|
|
276
|
+
|
|
277
|
+
Props (PromptInput.Attach):
|
|
278
|
+
|
|
279
|
+
- `label`: string (default: `'ファイルを添付'`)
|
|
181
280
|
|
|
182
281
|
Props (PromptInput.Textarea):
|
|
183
282
|
|
|
@@ -188,6 +287,62 @@ Props (PromptInput.Submit):
|
|
|
188
287
|
- `sendLabel`: string (default: `'送信'`)
|
|
189
288
|
- `stopLabel`: string (default: `'停止'`)
|
|
190
289
|
|
|
290
|
+
## Attachment
|
|
291
|
+
|
|
292
|
+
Files attached to a sent message. An image (`image/*`, or the bare `image` the AI SDK allows) shows as a thumbnail with `filename` as its alt text; anything else shows as a chip with its name and media type.
|
|
293
|
+
|
|
294
|
+
```tsx
|
|
295
|
+
import { Attachment } from '@k8ordo/ui/ai';
|
|
296
|
+
|
|
297
|
+
<Message.Root from="user">
|
|
298
|
+
<Attachment.List>
|
|
299
|
+
{files.map((file) => (
|
|
300
|
+
<Attachment.Item
|
|
301
|
+
filename={file.filename}
|
|
302
|
+
key={file.url}
|
|
303
|
+
mediaType={file.mediaType}
|
|
304
|
+
url={file.url}
|
|
305
|
+
/>
|
|
306
|
+
))}
|
|
307
|
+
</Attachment.List>
|
|
308
|
+
<Message.Content>{text}</Message.Content>
|
|
309
|
+
</Message.Root>;
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Props (Attachment.List):
|
|
313
|
+
|
|
314
|
+
- `label`: string (default: `'添付ファイル'`, used as the list's aria-label)
|
|
315
|
+
|
|
316
|
+
Props (Attachment.Item):
|
|
317
|
+
|
|
318
|
+
- `url`: string (required; a hosted URL or a data URL)
|
|
319
|
+
- `mediaType`: string (required)
|
|
320
|
+
- `filename`: string (without it an image's alt text is 「添付画像」 and a file chip shows the media type)
|
|
321
|
+
|
|
322
|
+
An image `url` is loaded as soon as the item renders, with no click in between. Pass URLs your own server produced or vouches for — a data URL, or your storage — rather than an arbitrary URL a model or tool wrote, which could point anywhere (a tracking pixel, an internal address). The AI SDK already turns files a provider generates into data URLs.
|
|
323
|
+
|
|
324
|
+
## Source
|
|
325
|
+
|
|
326
|
+
The sources a response cites. An item with an `http(s)` `href` is a link that opens in a new tab, labelled by `title` or else the host name; anything else — a document source, or a URL with another scheme — is plain text. The URL comes from the model, so a `javascript:` URL never becomes a link.
|
|
327
|
+
|
|
328
|
+
```tsx
|
|
329
|
+
import { Source } from '@k8ordo/ui/ai';
|
|
330
|
+
|
|
331
|
+
<Source.List>
|
|
332
|
+
<Source.Item href="https://ordo.k8o.me/ui/ai/chat" title="AI chat" />
|
|
333
|
+
<Source.Item title="Internal design doc v3" />
|
|
334
|
+
</Source.List>;
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
Props (Source.List):
|
|
338
|
+
|
|
339
|
+
- `label`: string (default: `'出典'`, used as the list's aria-label)
|
|
340
|
+
|
|
341
|
+
Props (Source.Item):
|
|
342
|
+
|
|
343
|
+
- `href`: string (the source's URL)
|
|
344
|
+
- `title`: string (the source's title; falls back to the host name)
|
|
345
|
+
|
|
191
346
|
## Reasoning
|
|
192
347
|
|
|
193
348
|
A collapsible view of the model's reasoning. While streaming, the label reads 「思考中…」.
|
|
@@ -209,7 +364,6 @@ A streaming-aware Markdown renderer. It renders half-finished Markdown — an un
|
|
|
209
364
|
|
|
210
365
|
```tsx
|
|
211
366
|
import { Response } from '@k8ordo/ui/ai/response';
|
|
212
|
-
import 'streamdown/styles.css';
|
|
213
367
|
|
|
214
368
|
<Message.Content>
|
|
215
369
|
<Response isStreaming={isStreaming}>{markdown}</Response>
|
|
@@ -220,9 +374,9 @@ Props:
|
|
|
220
374
|
|
|
221
375
|
- `children`: string (the Markdown, required)
|
|
222
376
|
- `isStreaming`: boolean
|
|
223
|
-
- Every other streamdown prop (`translations`, `controls`, `linkSafety`, `plugins`, `components`, `urlTransform`, `dir`, …) passes straight through. The library owns `className
|
|
377
|
+
- Every other streamdown prop (`translations`, `controls`, `linkSafety`, `plugins`, `components`, `urlTransform`, `dir`, …) passes straight through. The library owns `className`, `mode` (`mode` is derived from `isStreaming`) and `portal`: the confirmation dialog and a table's full screen open inside the `Response`, where its styles reach them
|
|
224
378
|
|
|
225
|
-
The wording comes from the i18n dictionary, so
|
|
379
|
+
The wording comes from the i18n dictionary of the current locale, so strings such as `responseCopyCode` and `responseDownloadTable` follow the rest of the components. Pass `translations` to change individual strings (prop > dictionary > streamdown's own default).
|
|
226
380
|
|
|
227
381
|
The library **defaults `linkSafety` to off**. With streamdown's own default (on), links render as `<button>` rather than `<a>`, which loses ⌘-click, middle-click, copying the link address, and the link role for assistive technology. Turn it on explicitly if you want the confirmation dialog:
|
|
228
382
|
|
|
@@ -258,7 +412,7 @@ Props (Suggestion.Item):
|
|
|
258
412
|
|
|
259
413
|
## ToolInvocation
|
|
260
414
|
|
|
261
|
-
A collapsible view of a tool call. The icon switches between spinner, success, error, and denied according to `state` (
|
|
415
|
+
A collapsible view of a tool call. The icon switches between spinner, success, error, and denied according to `state` (approval responded and input streaming count as in-progress and show the spinner).
|
|
262
416
|
|
|
263
417
|
```tsx
|
|
264
418
|
import { ToolInvocation } from '@k8ordo/ui/ai';
|
|
@@ -271,6 +425,27 @@ import { ToolInvocation } from '@k8ordo/ui/ai';
|
|
|
271
425
|
/>;
|
|
272
426
|
```
|
|
273
427
|
|
|
428
|
+
### Approval
|
|
429
|
+
|
|
430
|
+
When `state` is `'approval-requested'`, the tool is waiting for the user. Pass the part's `approval` and an `onApprovalResponse`, and a question with Deny / Allow buttons appears below the header — outside the collapsible panel, so it is visible without expanding the call; the input stays one click away in the panel. Pressing one calls `onApprovalResponse({ id: approval.id, approved })`, which is exactly what the AI SDK's `addToolApprovalResponse` takes. Until a returned promise settles, both buttons are `aria-disabled` and ignore presses; they are not natively `disabled`, so the pressed one keeps focus while the answer is sent. Once the state moves on, the question disappears; if it held focus, focus moves to the tool's header instead of falling to `body`.
|
|
431
|
+
|
|
432
|
+
```tsx
|
|
433
|
+
<ToolInvocation
|
|
434
|
+
name={part.name}
|
|
435
|
+
state={part.state}
|
|
436
|
+
input={part.input}
|
|
437
|
+
approval={part.approval}
|
|
438
|
+
onApprovalResponse={addToolApprovalResponse}
|
|
439
|
+
/>
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
- The question is `approval.requestReason` when the server gave one, 「このツールの実行を許可しますか?」 otherwise.
|
|
443
|
+
- An automatic decision (`approval.isAutomatic`) shows no question and no buttons; there is nothing for the user to answer.
|
|
444
|
+
- Without `onApprovalResponse`, the question shows but the buttons do not.
|
|
445
|
+
- In `'output-denied'`, the panel explains the denial with `approval.reason`, falling back to the default wording.
|
|
446
|
+
|
|
447
|
+
With the AI SDK, send the answer back automatically with `sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses` on `useChat`; otherwise nothing happens after the user answers.
|
|
448
|
+
|
|
274
449
|
Props:
|
|
275
450
|
|
|
276
451
|
- `name`: string (required, the tool name)
|
|
@@ -278,7 +453,8 @@ Props:
|
|
|
278
453
|
- `input`: unknown (anything other than a string is shown as JSON)
|
|
279
454
|
- `output`: ReactNode (a string is shown in a `pre`; an element renders as-is)
|
|
280
455
|
- `errorText`: string (shown when `state="output-error"`; falls back to the default wording)
|
|
281
|
-
- `
|
|
456
|
+
- `approval`: ToolApproval (the approval being asked for or answered; its `reason` explains an `output-denied` call)
|
|
457
|
+
- `onApprovalResponse`: `(response: ToolApprovalResponse) => void | PromiseLike<void>` (called with the approval `id` and the user's answer)
|
|
282
458
|
- `isOpen` / `defaultOpen` / `onChange`: open state, controlled or uncontrolled
|
|
283
459
|
|
|
284
460
|
## AI SDK integration (mapMessageParts)
|
|
@@ -297,45 +473,152 @@ type MappedPart =
|
|
|
297
473
|
input?: unknown;
|
|
298
474
|
output?: unknown;
|
|
299
475
|
errorText?: string;
|
|
300
|
-
|
|
301
|
-
}
|
|
476
|
+
approval?: ToolApproval; // the part's own approval object, id included
|
|
477
|
+
}
|
|
478
|
+
| { kind: 'file'; url: string; mediaType: string; filename?: string }
|
|
479
|
+
| {
|
|
480
|
+
kind: 'source'; // both source-url and source-document
|
|
481
|
+
id: string;
|
|
482
|
+
url?: string; // source-url only
|
|
483
|
+
title?: string;
|
|
484
|
+
mediaType?: string; // source-document only
|
|
485
|
+
filename?: string; // source-document only
|
|
486
|
+
}
|
|
487
|
+
| { kind: 'data'; name: string; id?: string; data: unknown }; // `data-weather` → name 'weather'
|
|
302
488
|
```
|
|
303
489
|
|
|
304
|
-
|
|
490
|
+
Order is preserved. `step-start`, `custom`, and `reasoning-file` parts are skipped.
|
|
491
|
+
|
|
492
|
+
Render each part as its own row under `Message.Root` — the children stack in a column. Files and sources read better as one list each, so pull them out with `filter` and skip them in the loop. A `data` part is yours: pick the ones you know by `name`, and validate what the model put in them before drawing it.
|
|
305
493
|
|
|
306
494
|
```tsx
|
|
495
|
+
'use client';
|
|
496
|
+
import { useChat } from '@ai-sdk/react';
|
|
497
|
+
import { Avatar, AssistantIcon } from '@k8ordo/ui';
|
|
498
|
+
import {
|
|
499
|
+
Attachment,
|
|
500
|
+
Message,
|
|
501
|
+
Reasoning,
|
|
502
|
+
Source,
|
|
503
|
+
ToolInvocation,
|
|
504
|
+
} from '@k8ordo/ui/ai';
|
|
307
505
|
import { mapMessageParts } from '@k8ordo/ui/ai-sdk';
|
|
308
|
-
import { Reasoning, ToolInvocation } from '@k8ordo/ui/ai';
|
|
309
506
|
import { Response } from '@k8ordo/ui/ai/response';
|
|
507
|
+
import { validateGeneratedSpec } from '@k8ordo/ui/json-render';
|
|
508
|
+
import { JsonRenderUI } from '@k8ordo/ui/json-render/registry';
|
|
509
|
+
import { lastAssistantMessageIsCompleteWithApprovalResponses } from 'ai';
|
|
510
|
+
import type { UIMessage } from 'ai';
|
|
310
511
|
|
|
311
|
-
<
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
512
|
+
type Chat = ReturnType<typeof useChat>;
|
|
513
|
+
|
|
514
|
+
function ChatMessage({ message, chat }: { message: UIMessage; chat: Chat }) {
|
|
515
|
+
const parts = mapMessageParts(message);
|
|
516
|
+
const files = parts.filter((part) => part.kind === 'file');
|
|
517
|
+
const sources = parts.filter((part) => part.kind === 'source');
|
|
518
|
+
const text = parts
|
|
519
|
+
.map((part) => (part.kind === 'text' ? part.text : ''))
|
|
520
|
+
.join('');
|
|
521
|
+
const isUser = message.role === 'user';
|
|
522
|
+
|
|
523
|
+
return (
|
|
524
|
+
<Message.Root
|
|
525
|
+
avatar={
|
|
526
|
+
isUser ? undefined : (
|
|
527
|
+
<Avatar icon={<AssistantIcon />} name="AI" size="sm" />
|
|
528
|
+
)
|
|
529
|
+
}
|
|
530
|
+
from={isUser ? 'user' : 'assistant'}
|
|
531
|
+
>
|
|
532
|
+
{files.length > 0 && (
|
|
533
|
+
<Attachment.List>
|
|
534
|
+
{files.map((file) => (
|
|
535
|
+
<Attachment.Item
|
|
536
|
+
filename={file.filename}
|
|
537
|
+
key={file.url}
|
|
538
|
+
mediaType={file.mediaType}
|
|
539
|
+
url={file.url}
|
|
540
|
+
/>
|
|
541
|
+
))}
|
|
542
|
+
</Attachment.List>
|
|
543
|
+
)}
|
|
544
|
+
{parts.map((part, i) => {
|
|
545
|
+
const key = `${message.id}-${i}`;
|
|
546
|
+
if (part.kind === 'text') {
|
|
547
|
+
return (
|
|
548
|
+
<Message.Content key={key}>
|
|
549
|
+
<Response>{part.text}</Response>
|
|
550
|
+
</Message.Content>
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
if (part.kind === 'reasoning') {
|
|
554
|
+
return <Reasoning key={key}>{part.text}</Reasoning>;
|
|
555
|
+
}
|
|
556
|
+
if (part.kind === 'tool') {
|
|
557
|
+
return (
|
|
558
|
+
<ToolInvocation
|
|
559
|
+
approval={part.approval}
|
|
560
|
+
errorText={part.errorText}
|
|
561
|
+
input={part.input}
|
|
562
|
+
key={part.toolCallId}
|
|
563
|
+
name={part.name}
|
|
564
|
+
onApprovalResponse={chat.addToolApprovalResponse}
|
|
565
|
+
// output is unknown, so convert it to a ReactNode first
|
|
566
|
+
output={
|
|
567
|
+
part.output === undefined
|
|
568
|
+
? undefined
|
|
569
|
+
: JSON.stringify(part.output, null, 2)
|
|
570
|
+
}
|
|
571
|
+
state={part.state}
|
|
572
|
+
/>
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
if (part.kind === 'data' && part.name === 'ui') {
|
|
576
|
+
const result = validateGeneratedSpec(part.data);
|
|
577
|
+
return result.ok ? (
|
|
578
|
+
<JsonRenderUI key={key} spec={result.spec} />
|
|
579
|
+
) : null;
|
|
580
|
+
}
|
|
581
|
+
return null;
|
|
582
|
+
})}
|
|
583
|
+
{sources.length > 0 && (
|
|
584
|
+
<Source.List>
|
|
585
|
+
{sources.map((source) => (
|
|
586
|
+
<Source.Item
|
|
587
|
+
href={source.url}
|
|
588
|
+
key={source.id}
|
|
589
|
+
title={source.title}
|
|
590
|
+
/>
|
|
591
|
+
))}
|
|
592
|
+
</Source.List>
|
|
593
|
+
)}
|
|
594
|
+
{!isUser && text !== '' && (
|
|
595
|
+
<Message.Actions>
|
|
596
|
+
<Message.Copy value={text} />
|
|
597
|
+
<Message.Regenerate
|
|
598
|
+
disabled={
|
|
599
|
+
chat.status === 'submitted' || chat.status === 'streaming'
|
|
600
|
+
}
|
|
601
|
+
onAction={() => chat.regenerate({ messageId: message.id })}
|
|
602
|
+
/>
|
|
603
|
+
<Message.Feedback />
|
|
604
|
+
</Message.Actions>
|
|
605
|
+
)}
|
|
606
|
+
</Message.Root>
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export function Chat() {
|
|
611
|
+
const chat = useChat({
|
|
612
|
+
// sends the answers back as soon as every pending approval has one
|
|
613
|
+
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,
|
|
614
|
+
});
|
|
615
|
+
// … Conversation.Root / chat.messages.map((message) => <ChatMessage … />) / PromptInput
|
|
616
|
+
}
|
|
336
617
|
```
|
|
337
618
|
|
|
338
|
-
|
|
619
|
+
`examples/ui-integrations` in the repository runs this against the real `useChat`, with a scripted transport in place of a model.
|
|
620
|
+
|
|
621
|
+
`@k8ordo/ui/ai-sdk` exports the `MappedPart` type, and re-exports the `ChatStatus`, `ToolState`, `ToolApproval`, and `ToolApprovalResponse` types as well.
|
|
339
622
|
|
|
340
623
|
## Combining with generative UI
|
|
341
624
|
|