@fusion.dev/helix-headless 0.0.0-dev
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/custom-elements.json +75202 -0
- package/dist/accordion/index.d.ts +2 -0
- package/dist/accordion/index.js +2 -0
- package/dist/accordion/item/accordion-item.d.ts +141 -0
- package/dist/accordion/item/accordion-item.js +214 -0
- package/dist/accordion/root/accordion-root.d.ts +57 -0
- package/dist/accordion/root/accordion-root.js +96 -0
- package/dist/announcement/index.d.ts +1 -0
- package/dist/announcement/index.js +1 -0
- package/dist/announcement/root/announcement-root.d.ts +106 -0
- package/dist/announcement/root/announcement-root.js +144 -0
- package/dist/app-header/index.d.ts +1 -0
- package/dist/app-header/index.js +1 -0
- package/dist/app-header/root/app-header-root.d.ts +113 -0
- package/dist/app-header/root/app-header-root.js +147 -0
- package/dist/avatar/group/avatar-group.d.ts +116 -0
- package/dist/avatar/group/avatar-group.js +136 -0
- package/dist/avatar/index.d.ts +2 -0
- package/dist/avatar/index.js +2 -0
- package/dist/avatar/root/avatar-root.d.ts +71 -0
- package/dist/avatar/root/avatar-root.js +147 -0
- package/dist/badge/index.d.ts +1 -0
- package/dist/badge/index.js +1 -0
- package/dist/badge/root/badge-root.d.ts +61 -0
- package/dist/badge/root/badge-root.js +121 -0
- package/dist/bar-chart/index.d.ts +1 -0
- package/dist/bar-chart/index.js +1 -0
- package/dist/bar-chart/root/bar-chart-root.d.ts +266 -0
- package/dist/bar-chart/root/bar-chart-root.js +515 -0
- package/dist/blockquote/index.d.ts +1 -0
- package/dist/blockquote/index.js +1 -0
- package/dist/blockquote/root/blockquote-root.d.ts +51 -0
- package/dist/blockquote/root/blockquote-root.js +84 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.d.ts +104 -0
- package/dist/breadcrumbs/breadcrumb/breadcrumb.js +137 -0
- package/dist/breadcrumbs/index.d.ts +2 -0
- package/dist/breadcrumbs/index.js +2 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.d.ts +77 -0
- package/dist/breadcrumbs/root/breadcrumbs-root.js +94 -0
- package/dist/button/index.d.ts +1 -0
- package/dist/button/index.js +1 -0
- package/dist/button/root/button-root.d.ts +251 -0
- package/dist/button/root/button-root.js +401 -0
- package/dist/button-group/index.d.ts +1 -0
- package/dist/button-group/index.js +1 -0
- package/dist/button-group/root/button-group-root.d.ts +62 -0
- package/dist/button-group/root/button-group-root.js +62 -0
- package/dist/callout/index.d.ts +1 -0
- package/dist/callout/index.js +1 -0
- package/dist/callout/root/callout-root.d.ts +72 -0
- package/dist/callout/root/callout-root.js +90 -0
- package/dist/card/index.d.ts +1 -0
- package/dist/card/index.js +1 -0
- package/dist/card/root/card-root.d.ts +54 -0
- package/dist/card/root/card-root.js +71 -0
- package/dist/carousel/index.d.ts +1 -0
- package/dist/carousel/index.js +1 -0
- package/dist/carousel/root/carousel-root.d.ts +399 -0
- package/dist/carousel/root/carousel-root.js +723 -0
- package/dist/chat/composer/chat-composer.d.ts +160 -0
- package/dist/chat/composer/chat-composer.js +273 -0
- package/dist/chat/index.d.ts +3 -0
- package/dist/chat/index.js +3 -0
- package/dist/chat/message/chat-message.d.ts +170 -0
- package/dist/chat/message/chat-message.js +271 -0
- package/dist/chat/root/chat-root.d.ts +216 -0
- package/dist/chat/root/chat-root.js +389 -0
- package/dist/checkbox/index.d.ts +1 -0
- package/dist/checkbox/index.js +1 -0
- package/dist/checkbox/root/checkbox-root.d.ts +108 -0
- package/dist/checkbox/root/checkbox-root.js +207 -0
- package/dist/checkbox-group/index.d.ts +1 -0
- package/dist/checkbox-group/index.js +1 -0
- package/dist/checkbox-group/root/checkbox-group-root.d.ts +155 -0
- package/dist/checkbox-group/root/checkbox-group-root.js +293 -0
- package/dist/code/index.d.ts +1 -0
- package/dist/code/index.js +1 -0
- package/dist/code/root/code-root.d.ts +36 -0
- package/dist/code/root/code-root.js +43 -0
- package/dist/code-block/index.d.ts +1 -0
- package/dist/code-block/index.js +1 -0
- package/dist/code-block/root/code-block-root.d.ts +112 -0
- package/dist/code-block/root/code-block-root.js +155 -0
- package/dist/color-input/index.d.ts +1 -0
- package/dist/color-input/index.js +1 -0
- package/dist/color-input/root/color-input-root.d.ts +227 -0
- package/dist/color-input/root/color-input-root.js +456 -0
- package/dist/color-picker/color.d.ts +74 -0
- package/dist/color-picker/color.js +238 -0
- package/dist/color-picker/index.d.ts +2 -0
- package/dist/color-picker/index.js +2 -0
- package/dist/color-picker/root/color-picker-root.d.ts +303 -0
- package/dist/color-picker/root/color-picker-root.js +576 -0
- package/dist/combobox/index.d.ts +1 -0
- package/dist/combobox/index.js +1 -0
- package/dist/combobox/root/combobox-root.d.ts +396 -0
- package/dist/combobox/root/combobox-root.js +808 -0
- package/dist/command/index.d.ts +1 -0
- package/dist/command/index.js +1 -0
- package/dist/command/root/command-root.d.ts +166 -0
- package/dist/command/root/command-root.js +353 -0
- package/dist/copy-button/index.d.ts +1 -0
- package/dist/copy-button/index.js +1 -0
- package/dist/copy-button/root/copy-button-root.d.ts +154 -0
- package/dist/copy-button/root/copy-button-root.js +225 -0
- package/dist/data-table/index.d.ts +2 -0
- package/dist/data-table/index.js +2 -0
- package/dist/data-table/root/data-table-root.d.ts +392 -0
- package/dist/data-table/root/data-table-root.js +729 -0
- package/dist/data-table/root/order.d.ts +116 -0
- package/dist/data-table/root/order.js +175 -0
- package/dist/date-input/index.d.ts +1 -0
- package/dist/date-input/index.js +1 -0
- package/dist/date-input/root/date-input-root.d.ts +361 -0
- package/dist/date-input/root/date-input-root.js +791 -0
- package/dist/date-picker/index.d.ts +1 -0
- package/dist/date-picker/index.js +1 -0
- package/dist/date-picker/root/date-picker-root.d.ts +361 -0
- package/dist/date-picker/root/date-picker-root.js +837 -0
- package/dist/dialog/index.d.ts +1 -0
- package/dist/dialog/index.js +1 -0
- package/dist/dialog/root/dialog-root.d.ts +185 -0
- package/dist/dialog/root/dialog-root.js +319 -0
- package/dist/divider/index.d.ts +1 -0
- package/dist/divider/index.js +1 -0
- package/dist/divider/root/divider-root.d.ts +68 -0
- package/dist/divider/root/divider-root.js +116 -0
- package/dist/donut-chart/index.d.ts +1 -0
- package/dist/donut-chart/index.js +1 -0
- package/dist/donut-chart/root/donut-chart-root.d.ts +209 -0
- package/dist/donut-chart/root/donut-chart-root.js +395 -0
- package/dist/drawer/index.d.ts +1 -0
- package/dist/drawer/index.js +1 -0
- package/dist/drawer/root/drawer-root.d.ts +144 -0
- package/dist/drawer/root/drawer-root.js +222 -0
- package/dist/drilldown/index.d.ts +2 -0
- package/dist/drilldown/index.js +2 -0
- package/dist/drilldown/item/drilldown-item.d.ts +87 -0
- package/dist/drilldown/item/drilldown-item.js +152 -0
- package/dist/drilldown/root/drilldown-root.d.ts +115 -0
- package/dist/drilldown/root/drilldown-root.js +263 -0
- package/dist/element-events.generated.d.ts +1 -0
- package/dist/element-events.generated.js +125 -0
- package/dist/empty/index.d.ts +1 -0
- package/dist/empty/index.js +1 -0
- package/dist/empty/root/empty-root.d.ts +47 -0
- package/dist/empty/root/empty-root.js +68 -0
- package/dist/file-input/index.d.ts +1 -0
- package/dist/file-input/index.js +1 -0
- package/dist/file-input/root/file-input-root.d.ts +196 -0
- package/dist/file-input/root/file-input-root.js +488 -0
- package/dist/format-date/index.d.ts +1 -0
- package/dist/format-date/index.js +1 -0
- package/dist/format-date/root/format-date-root.d.ts +151 -0
- package/dist/format-date/root/format-date-root.js +266 -0
- package/dist/heatmap/index.d.ts +2 -0
- package/dist/heatmap/index.js +2 -0
- package/dist/heatmap/root/buckets.d.ts +62 -0
- package/dist/heatmap/root/buckets.js +85 -0
- package/dist/heatmap/root/heatmap-root.d.ts +330 -0
- package/dist/heatmap/root/heatmap-root.js +526 -0
- package/dist/icon/index.d.ts +1 -0
- package/dist/icon/index.js +1 -0
- package/dist/icon/root/icon-root.d.ts +53 -0
- package/dist/icon/root/icon-root.js +93 -0
- package/dist/icon-button/index.d.ts +1 -0
- package/dist/icon-button/index.js +1 -0
- package/dist/icon-button/root/icon-button-root.d.ts +40 -0
- package/dist/icon-button/root/icon-button-root.js +46 -0
- package/dist/image/index.d.ts +1 -0
- package/dist/image/index.js +1 -0
- package/dist/image/root/image-root.d.ts +213 -0
- package/dist/image/root/image-root.js +335 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +99 -0
- package/dist/input/index.d.ts +1 -0
- package/dist/input/index.js +1 -0
- package/dist/input/root/input-root.d.ts +281 -0
- package/dist/input/root/input-root.js +472 -0
- package/dist/kbd/index.d.ts +1 -0
- package/dist/kbd/index.js +1 -0
- package/dist/kbd/root/kbd-root.d.ts +98 -0
- package/dist/kbd/root/kbd-root.js +230 -0
- package/dist/legend/index.d.ts +1 -0
- package/dist/legend/index.js +1 -0
- package/dist/legend/root/legend-root.d.ts +83 -0
- package/dist/legend/root/legend-root.js +125 -0
- package/dist/line-chart/index.d.ts +1 -0
- package/dist/line-chart/index.js +1 -0
- package/dist/line-chart/root/line-chart-root.d.ts +238 -0
- package/dist/line-chart/root/line-chart-root.js +365 -0
- package/dist/list/index.d.ts +2 -0
- package/dist/list/index.js +2 -0
- package/dist/list/item/list-item.d.ts +95 -0
- package/dist/list/item/list-item.js +148 -0
- package/dist/list/root/list-root.d.ts +72 -0
- package/dist/list/root/list-root.js +61 -0
- package/dist/listbox/index.d.ts +1 -0
- package/dist/listbox/index.js +1 -0
- package/dist/listbox/root/listbox-root.d.ts +357 -0
- package/dist/listbox/root/listbox-root.js +890 -0
- package/dist/loader/index.d.ts +1 -0
- package/dist/loader/index.js +1 -0
- package/dist/loader/root/loader-root.d.ts +52 -0
- package/dist/loader/root/loader-root.js +74 -0
- package/dist/megamenu/index.d.ts +1 -0
- package/dist/megamenu/index.js +1 -0
- package/dist/megamenu/root/megamenu-root.d.ts +254 -0
- package/dist/megamenu/root/megamenu-root.js +526 -0
- package/dist/menu/index.d.ts +2 -0
- package/dist/menu/index.js +2 -0
- package/dist/menu/item/menu-item.d.ts +231 -0
- package/dist/menu/item/menu-item.js +405 -0
- package/dist/menu/root/menu-root.d.ts +158 -0
- package/dist/menu/root/menu-root.js +422 -0
- package/dist/meter/index.d.ts +1 -0
- package/dist/meter/index.js +1 -0
- package/dist/meter/root/meter-root.d.ts +234 -0
- package/dist/meter/root/meter-root.js +316 -0
- package/dist/navigation/index.d.ts +1 -0
- package/dist/navigation/index.js +1 -0
- package/dist/navigation/root/navigation-root.d.ts +55 -0
- package/dist/navigation/root/navigation-root.js +130 -0
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.js +2 -0
- package/dist/notifications/notification/notification.d.ts +181 -0
- package/dist/notifications/notification/notification.js +305 -0
- package/dist/notifications/root/notifications-root.d.ts +168 -0
- package/dist/notifications/root/notifications-root.js +291 -0
- package/dist/number-input/index.d.ts +1 -0
- package/dist/number-input/index.js +1 -0
- package/dist/number-input/root/number-input-root.d.ts +282 -0
- package/dist/number-input/root/number-input-root.js +592 -0
- package/dist/option/group/option-group.d.ts +38 -0
- package/dist/option/group/option-group.js +58 -0
- package/dist/option/index.d.ts +2 -0
- package/dist/option/index.js +2 -0
- package/dist/option/root/option-root.d.ts +194 -0
- package/dist/option/root/option-root.js +247 -0
- package/dist/outline/index.d.ts +1 -0
- package/dist/outline/index.js +1 -0
- package/dist/outline/root/outline-root.d.ts +237 -0
- package/dist/outline/root/outline-root.js +519 -0
- package/dist/pagination/index.d.ts +3 -0
- package/dist/pagination/index.js +3 -0
- package/dist/pagination/root/pagination-root.d.ts +390 -0
- package/dist/pagination/root/pagination-root.js +695 -0
- package/dist/pagination/size/pagination-size.d.ts +127 -0
- package/dist/pagination/size/pagination-size.js +232 -0
- package/dist/pagination/summary/pagination-summary.d.ts +90 -0
- package/dist/pagination/summary/pagination-summary.js +145 -0
- package/dist/pin-input/index.d.ts +1 -0
- package/dist/pin-input/index.js +1 -0
- package/dist/pin-input/root/pin-input-root.d.ts +292 -0
- package/dist/pin-input/root/pin-input-root.js +553 -0
- package/dist/popover/index.d.ts +1 -0
- package/dist/popover/index.js +1 -0
- package/dist/popover/root/popover-root.d.ts +108 -0
- package/dist/popover/root/popover-root.js +231 -0
- package/dist/progress/index.d.ts +1 -0
- package/dist/progress/index.js +1 -0
- package/dist/progress/root/progress-root.d.ts +125 -0
- package/dist/progress/root/progress-root.js +212 -0
- package/dist/qr-code/index.d.ts +1 -0
- package/dist/qr-code/index.js +1 -0
- package/dist/qr-code/root/qr-code-root.d.ts +93 -0
- package/dist/qr-code/root/qr-code-root.js +233 -0
- package/dist/quote/index.d.ts +1 -0
- package/dist/quote/index.js +1 -0
- package/dist/quote/root/quote-root.d.ts +36 -0
- package/dist/quote/root/quote-root.js +50 -0
- package/dist/radio/group/radio-group.d.ts +84 -0
- package/dist/radio/group/radio-group.js +170 -0
- package/dist/radio/index.d.ts +2 -0
- package/dist/radio/index.js +2 -0
- package/dist/radio/root/radio-root.d.ts +102 -0
- package/dist/radio/root/radio-root.js +151 -0
- package/dist/rating/index.d.ts +1 -0
- package/dist/rating/index.js +1 -0
- package/dist/rating/root/rating-root.d.ts +242 -0
- package/dist/rating/root/rating-root.js +484 -0
- package/dist/scroll-area/index.d.ts +1 -0
- package/dist/scroll-area/index.js +1 -0
- package/dist/scroll-area/root/scroll-area-root.d.ts +96 -0
- package/dist/scroll-area/root/scroll-area-root.js +215 -0
- package/dist/select/index.d.ts +1 -0
- package/dist/select/index.js +1 -0
- package/dist/select/root/select-root.d.ts +170 -0
- package/dist/select/root/select-root.js +419 -0
- package/dist/skeleton/index.d.ts +1 -0
- package/dist/skeleton/index.js +1 -0
- package/dist/skeleton/root/skeleton-root.d.ts +31 -0
- package/dist/skeleton/root/skeleton-root.js +42 -0
- package/dist/slider/index.d.ts +1 -0
- package/dist/slider/index.js +1 -0
- package/dist/slider/root/slider-root.d.ts +235 -0
- package/dist/slider/root/slider-root.js +488 -0
- package/dist/sparkline/index.d.ts +1 -0
- package/dist/sparkline/index.js +1 -0
- package/dist/sparkline/root/sparkline-root.d.ts +147 -0
- package/dist/sparkline/root/sparkline-root.js +278 -0
- package/dist/speed-dial/index.d.ts +2 -0
- package/dist/speed-dial/index.js +2 -0
- package/dist/speed-dial/item/speed-dial-item.d.ts +71 -0
- package/dist/speed-dial/item/speed-dial-item.js +113 -0
- package/dist/speed-dial/root/speed-dial-root.d.ts +122 -0
- package/dist/speed-dial/root/speed-dial-root.js +251 -0
- package/dist/splitter/index.d.ts +1 -0
- package/dist/splitter/index.js +1 -0
- package/dist/splitter/root/splitter-root.d.ts +491 -0
- package/dist/splitter/root/splitter-root.js +1030 -0
- package/dist/stat/group/stat-group.d.ts +30 -0
- package/dist/stat/group/stat-group.js +47 -0
- package/dist/stat/index.d.ts +2 -0
- package/dist/stat/index.js +2 -0
- package/dist/stat/root/stat-root.d.ts +62 -0
- package/dist/stat/root/stat-root.js +51 -0
- package/dist/steps/index.d.ts +2 -0
- package/dist/steps/index.js +2 -0
- package/dist/steps/root/steps-root.d.ts +110 -0
- package/dist/steps/root/steps-root.js +130 -0
- package/dist/steps/step/step.d.ts +139 -0
- package/dist/steps/step/step.js +215 -0
- package/dist/switch/index.d.ts +1 -0
- package/dist/switch/index.js +1 -0
- package/dist/switch/root/switch-root.d.ts +74 -0
- package/dist/switch/root/switch-root.js +153 -0
- package/dist/table/cell/table-cell.d.ts +34 -0
- package/dist/table/cell/table-cell.js +52 -0
- package/dist/table/column/table-column.d.ts +165 -0
- package/dist/table/column/table-column.js +222 -0
- package/dist/table/index.d.ts +4 -0
- package/dist/table/index.js +4 -0
- package/dist/table/root/table-root.d.ts +98 -0
- package/dist/table/root/table-root.js +161 -0
- package/dist/table/row/table-row.d.ts +27 -0
- package/dist/table/row/table-row.js +42 -0
- package/dist/tabs/index.d.ts +3 -0
- package/dist/tabs/index.js +3 -0
- package/dist/tabs/panel/tab-panel.d.ts +67 -0
- package/dist/tabs/panel/tab-panel.js +98 -0
- package/dist/tabs/root/tabs-root.d.ts +123 -0
- package/dist/tabs/root/tabs-root.js +217 -0
- package/dist/tabs/tab/tab.d.ts +64 -0
- package/dist/tabs/tab/tab.js +116 -0
- package/dist/tag/index.d.ts +1 -0
- package/dist/tag/index.js +1 -0
- package/dist/tag/root/tag-root.d.ts +41 -0
- package/dist/tag/root/tag-root.js +67 -0
- package/dist/textarea/index.d.ts +1 -0
- package/dist/textarea/index.js +1 -0
- package/dist/textarea/root/textarea-root.d.ts +215 -0
- package/dist/textarea/root/textarea-root.js +380 -0
- package/dist/time-input/index.d.ts +1 -0
- package/dist/time-input/index.js +1 -0
- package/dist/time-input/root/time-input-root.d.ts +322 -0
- package/dist/time-input/root/time-input-root.js +661 -0
- package/dist/time-picker/index.d.ts +1 -0
- package/dist/time-picker/index.js +1 -0
- package/dist/time-picker/root/time-picker-root.d.ts +380 -0
- package/dist/time-picker/root/time-picker-root.js +669 -0
- package/dist/timeline/index.d.ts +2 -0
- package/dist/timeline/index.js +2 -0
- package/dist/timeline/item/timeline-item.d.ts +81 -0
- package/dist/timeline/item/timeline-item.js +128 -0
- package/dist/timeline/root/timeline-root.d.ts +52 -0
- package/dist/timeline/root/timeline-root.js +72 -0
- package/dist/toast/index.d.ts +2 -0
- package/dist/toast/index.js +2 -0
- package/dist/toast/item/toast-item.d.ts +183 -0
- package/dist/toast/item/toast-item.js +345 -0
- package/dist/toast/root/toast-root.d.ts +72 -0
- package/dist/toast/root/toast-root.js +87 -0
- package/dist/toggle/group/toggle-group.d.ts +140 -0
- package/dist/toggle/group/toggle-group.js +278 -0
- package/dist/toggle/index.d.ts +2 -0
- package/dist/toggle/index.js +2 -0
- package/dist/toggle/root/toggle-root.d.ts +99 -0
- package/dist/toggle/root/toggle-root.js +146 -0
- package/dist/toolbar/index.d.ts +1 -0
- package/dist/toolbar/index.js +1 -0
- package/dist/toolbar/root/toolbar-root.d.ts +105 -0
- package/dist/toolbar/root/toolbar-root.js +260 -0
- package/dist/tooltip/index.d.ts +1 -0
- package/dist/tooltip/index.js +1 -0
- package/dist/tooltip/root/tooltip-root.d.ts +388 -0
- package/dist/tooltip/root/tooltip-root.js +707 -0
- package/dist/tour/index.d.ts +2 -0
- package/dist/tour/index.js +2 -0
- package/dist/tour/root/tour-root.d.ts +161 -0
- package/dist/tour/root/tour-root.js +351 -0
- package/dist/tour/stop/tour-stop.d.ts +131 -0
- package/dist/tour/stop/tour-stop.js +249 -0
- package/dist/tree/index.d.ts +2 -0
- package/dist/tree/index.js +2 -0
- package/dist/tree/item/tree-item.d.ts +208 -0
- package/dist/tree/item/tree-item.js +381 -0
- package/dist/tree/root/tree-root.d.ts +88 -0
- package/dist/tree/root/tree-root.js +287 -0
- package/dist/trend/index.d.ts +1 -0
- package/dist/trend/index.js +1 -0
- package/dist/trend/root/trend-root.d.ts +67 -0
- package/dist/trend/root/trend-root.js +106 -0
- package/dist/video/index.d.ts +1 -0
- package/dist/video/index.js +1 -0
- package/dist/video/root/video-root.d.ts +711 -0
- package/dist/video/root/video-root.js +1821 -0
- package/dist/video-playlist/index.d.ts +3 -0
- package/dist/video-playlist/index.js +3 -0
- package/dist/video-playlist/item/video-playlist-item.d.ts +101 -0
- package/dist/video-playlist/item/video-playlist-item.js +162 -0
- package/dist/video-playlist/menu/video-playlist-menu.d.ts +121 -0
- package/dist/video-playlist/menu/video-playlist-menu.js +237 -0
- package/dist/video-playlist/root/video-playlist-root.d.ts +108 -0
- package/dist/video-playlist/root/video-playlist-root.js +218 -0
- package/dist/virtual-list/index.d.ts +1 -0
- package/dist/virtual-list/index.js +1 -0
- package/dist/virtual-list/root/virtual-list-root.d.ts +121 -0
- package/dist/virtual-list/root/virtual-list-root.js +221 -0
- package/jsx.d.ts +49767 -0
- package/package.json +77 -0
- package/svelte.d.ts +129 -0
- package/vue.d.ts +9242 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary Where the reader writes their turn.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* **A separate element because it is separately replaceable.** A consumer with
|
|
8
|
+
* attachments, slash commands or a model picker replaces the composer and keeps
|
|
9
|
+
* the transcript, which is only possible if the two were never one component.
|
|
10
|
+
*
|
|
11
|
+
* **Enter sends and Shift+Enter opens a line, and it is configurable rather than
|
|
12
|
+
* decided.** The convention is near-universal in messaging and near-inverted in
|
|
13
|
+
* anything that is really a document editor, and a component that picks one
|
|
14
|
+
* makes the other consumer reimplement the composer. `submit-on` takes `enter`
|
|
15
|
+
* or `button`, and the second is what a long-form composer wants.
|
|
16
|
+
*
|
|
17
|
+
* The composer clears only when nobody refused the send, because a composer that
|
|
18
|
+
* empties itself and then hears the request failed has thrown away the only copy
|
|
19
|
+
* of what the reader wrote.
|
|
20
|
+
*
|
|
21
|
+
* @since 0.1.0
|
|
22
|
+
* @status experimental
|
|
23
|
+
* @category forms
|
|
24
|
+
* @aliases Message box, Prompt input
|
|
25
|
+
* @documentation https://helix.fusion.dev/components/chat
|
|
26
|
+
*
|
|
27
|
+
* @slot end - Under the field, beside the send control.
|
|
28
|
+
* @slot start - Under the field, at the leading edge: attachments, a model picker.
|
|
29
|
+
*
|
|
30
|
+
* @event {HelixSendEvent} helix-send - Fired when the reader offers their turn, and cancelable.
|
|
31
|
+
*
|
|
32
|
+
* @csspart composer - The whole composer.
|
|
33
|
+
* @csspart end - The trailing slot's box.
|
|
34
|
+
* @csspart field - The text field.
|
|
35
|
+
* @csspart mark - The glyph inside the send control.
|
|
36
|
+
* @csspart send - The control that offers the turn.
|
|
37
|
+
* @csspart start - The leading slot's box.
|
|
38
|
+
* @csspart tools - The row under the field.
|
|
39
|
+
*/
|
|
40
|
+
export declare class HelixHeadlessChatComposer extends HelixElement {
|
|
41
|
+
/**
|
|
42
|
+
* What the reader has written.
|
|
43
|
+
*
|
|
44
|
+
* Read it, or set it to seed a draft.
|
|
45
|
+
*/
|
|
46
|
+
value: string;
|
|
47
|
+
/**
|
|
48
|
+
* Shown in an empty field.
|
|
49
|
+
*/
|
|
50
|
+
placeholder: string;
|
|
51
|
+
/**
|
|
52
|
+
* What sends: pressing Enter, or only the control.
|
|
53
|
+
*
|
|
54
|
+
* `enter` is the messaging convention and makes Shift+Enter the line break.
|
|
55
|
+
* `button` is what a composer holding several paragraphs wants, where Enter
|
|
56
|
+
* has to mean a new line and nothing else.
|
|
57
|
+
*/
|
|
58
|
+
submitOn: 'button' | 'enter';
|
|
59
|
+
/**
|
|
60
|
+
* Whether the composer refuses input, while a turn is in flight say.
|
|
61
|
+
*/
|
|
62
|
+
disabled: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Accessible name for the field.
|
|
65
|
+
*/
|
|
66
|
+
label: string;
|
|
67
|
+
/**
|
|
68
|
+
* Label for the control that sends.
|
|
69
|
+
*/
|
|
70
|
+
sendLabel: string;
|
|
71
|
+
/**
|
|
72
|
+
* How many rows the field opens at.
|
|
73
|
+
*
|
|
74
|
+
* It grows from there.
|
|
75
|
+
*/
|
|
76
|
+
rows: number;
|
|
77
|
+
private draft;
|
|
78
|
+
/**
|
|
79
|
+
* @internal Read by the transcript to find the composer among its children.
|
|
80
|
+
*/
|
|
81
|
+
readonly isChatComposer = true;
|
|
82
|
+
/** What is in the field, whoever last wrote it. */
|
|
83
|
+
private get text();
|
|
84
|
+
/**
|
|
85
|
+
* Offers what is written, and reports whether it stood.
|
|
86
|
+
*
|
|
87
|
+
* Public because a consumer's own send control is as likely to ask as this
|
|
88
|
+
* element's is, and because a keyboard shortcut somewhere else on the page is
|
|
89
|
+
* a reasonable way to send.
|
|
90
|
+
*/
|
|
91
|
+
send(): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Says on each tool box whether anything is in it.
|
|
94
|
+
*
|
|
95
|
+
* They are boxes in a flex row, so an empty one still takes the gap beside it
|
|
96
|
+
* and the send control drifts inward by one for every slot a consumer left
|
|
97
|
+
* alone. No selector can ask this: a slot's assigned nodes are not its DOM
|
|
98
|
+
* children, so `:empty` describes the fallback rather than the fill.
|
|
99
|
+
*/
|
|
100
|
+
private markEmpty;
|
|
101
|
+
protected updated(changed: PropertyValues): void;
|
|
102
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
103
|
+
/**
|
|
104
|
+
* The control that offers the turn, behind a seam so a tier can draw its own.
|
|
105
|
+
*
|
|
106
|
+
* **A glyph with the label as its accessible name, rather than the label as
|
|
107
|
+
* text.** The word "Send" beside a field is the widest thing in the row and
|
|
108
|
+
* says nothing a return key does not, and every composer a reader has used in
|
|
109
|
+
* the last five years marks it rather than spells it. The return glyph is the
|
|
110
|
+
* mark because Enter is what actually sends, which `submit-on` says out loud:
|
|
111
|
+
* the control and the key are one affordance and should look like it.
|
|
112
|
+
*
|
|
113
|
+
* `send-label` is unchanged and is now the accessible name rather than the
|
|
114
|
+
* visible one, so a screen reader hears the same word it always did.
|
|
115
|
+
*/
|
|
116
|
+
protected renderSend(): TemplateResult;
|
|
117
|
+
/**
|
|
118
|
+
* The field, and a row of tools under it.
|
|
119
|
+
*
|
|
120
|
+
* **One row was the wrong shape and it got worse the more a composer had to
|
|
121
|
+
* carry.** Everything sat on a single line: an attachment control, the field,
|
|
122
|
+
* a stop control and a send button, so the field was squeezed from both sides
|
|
123
|
+
* and every tool a consumer added took width away from the thing being typed
|
|
124
|
+
* into. Under it, the field spans the whole composer at every width and the
|
|
125
|
+
* tools have a line of their own to grow along.
|
|
126
|
+
*
|
|
127
|
+
* Send is at the trailing end of that line rather than in the field, which is
|
|
128
|
+
* the same corner and costs no overlay: a control positioned inside a
|
|
129
|
+
* scrolling textarea either covers the last line of a long draft or scrolls
|
|
130
|
+
* away with it.
|
|
131
|
+
*/
|
|
132
|
+
protected render(): TemplateResult;
|
|
133
|
+
/**
|
|
134
|
+
* Records the draft, and stops the textarea speaking in this element's name.
|
|
135
|
+
*
|
|
136
|
+
* **The stop is not incidental.** `input` is composed by specification, so the
|
|
137
|
+
* `<textarea>` in this shadow root sent its own past this host and on through
|
|
138
|
+
* whatever `<helix-chat>` it is slotted into, and neither element declares an
|
|
139
|
+
* `input`: a consumer binding one on either received an undeclared event whose
|
|
140
|
+
* target was a control they cannot reach. What a composer offers is
|
|
141
|
+
* `helix-send`, once, when the reader is done. See 308.
|
|
142
|
+
*/
|
|
143
|
+
private readonly handleInput;
|
|
144
|
+
private readonly handleSend;
|
|
145
|
+
/**
|
|
146
|
+
* Enter sends where that is what `submit-on` says, and never mid-composition.
|
|
147
|
+
*
|
|
148
|
+
* **`isComposing` is the part that is easy to leave out and breaks a whole
|
|
149
|
+
* writing system.** A reader typing Japanese, Chinese or Korean presses Enter
|
|
150
|
+
* to accept the candidate their input method is offering, and a composer that
|
|
151
|
+
* reads it as send fires off a half-finished word every time. The flag is on
|
|
152
|
+
* the event for exactly this and costs one condition.
|
|
153
|
+
*/
|
|
154
|
+
private readonly handleKey;
|
|
155
|
+
}
|
|
156
|
+
declare global {
|
|
157
|
+
interface HTMLElementTagNameMap {
|
|
158
|
+
'helix-headless-chat-composer': HelixHeadlessChatComposer;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { customElement, HelixElement, HelixSendEvent, hostAria, slotFilled, } from '@fusion.dev/helix-core';
|
|
8
|
+
import { arrowElbowDownLeft } from '@fusion.dev/helix-icons';
|
|
9
|
+
import { html } from 'lit';
|
|
10
|
+
import { property, state } from 'lit/decorators.js';
|
|
11
|
+
import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
|
|
12
|
+
/**
|
|
13
|
+
* @summary Where the reader writes their turn.
|
|
14
|
+
*
|
|
15
|
+
* @description
|
|
16
|
+
* **A separate element because it is separately replaceable.** A consumer with
|
|
17
|
+
* attachments, slash commands or a model picker replaces the composer and keeps
|
|
18
|
+
* the transcript, which is only possible if the two were never one component.
|
|
19
|
+
*
|
|
20
|
+
* **Enter sends and Shift+Enter opens a line, and it is configurable rather than
|
|
21
|
+
* decided.** The convention is near-universal in messaging and near-inverted in
|
|
22
|
+
* anything that is really a document editor, and a component that picks one
|
|
23
|
+
* makes the other consumer reimplement the composer. `submit-on` takes `enter`
|
|
24
|
+
* or `button`, and the second is what a long-form composer wants.
|
|
25
|
+
*
|
|
26
|
+
* The composer clears only when nobody refused the send, because a composer that
|
|
27
|
+
* empties itself and then hears the request failed has thrown away the only copy
|
|
28
|
+
* of what the reader wrote.
|
|
29
|
+
*
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
* @status experimental
|
|
32
|
+
* @category forms
|
|
33
|
+
* @aliases Message box, Prompt input
|
|
34
|
+
* @documentation https://helix.fusion.dev/components/chat
|
|
35
|
+
*
|
|
36
|
+
* @slot end - Under the field, beside the send control.
|
|
37
|
+
* @slot start - Under the field, at the leading edge: attachments, a model picker.
|
|
38
|
+
*
|
|
39
|
+
* @event {HelixSendEvent} helix-send - Fired when the reader offers their turn, and cancelable.
|
|
40
|
+
*
|
|
41
|
+
* @csspart composer - The whole composer.
|
|
42
|
+
* @csspart end - The trailing slot's box.
|
|
43
|
+
* @csspart field - The text field.
|
|
44
|
+
* @csspart mark - The glyph inside the send control.
|
|
45
|
+
* @csspart send - The control that offers the turn.
|
|
46
|
+
* @csspart start - The leading slot's box.
|
|
47
|
+
* @csspart tools - The row under the field.
|
|
48
|
+
*/
|
|
49
|
+
let HelixHeadlessChatComposer = class HelixHeadlessChatComposer extends HelixElement {
|
|
50
|
+
constructor() {
|
|
51
|
+
super(...arguments);
|
|
52
|
+
/**
|
|
53
|
+
* What the reader has written.
|
|
54
|
+
*
|
|
55
|
+
* Read it, or set it to seed a draft.
|
|
56
|
+
*/
|
|
57
|
+
this.value = '';
|
|
58
|
+
/**
|
|
59
|
+
* Shown in an empty field.
|
|
60
|
+
*/
|
|
61
|
+
this.placeholder = '';
|
|
62
|
+
/**
|
|
63
|
+
* What sends: pressing Enter, or only the control.
|
|
64
|
+
*
|
|
65
|
+
* `enter` is the messaging convention and makes Shift+Enter the line break.
|
|
66
|
+
* `button` is what a composer holding several paragraphs wants, where Enter
|
|
67
|
+
* has to mean a new line and nothing else.
|
|
68
|
+
*/
|
|
69
|
+
this.submitOn = 'enter';
|
|
70
|
+
/**
|
|
71
|
+
* Whether the composer refuses input, while a turn is in flight say.
|
|
72
|
+
*/
|
|
73
|
+
this.disabled = false;
|
|
74
|
+
/**
|
|
75
|
+
* Accessible name for the field.
|
|
76
|
+
*/
|
|
77
|
+
this.label = 'Message';
|
|
78
|
+
/**
|
|
79
|
+
* Label for the control that sends.
|
|
80
|
+
*/
|
|
81
|
+
this.sendLabel = 'Send';
|
|
82
|
+
/**
|
|
83
|
+
* How many rows the field opens at.
|
|
84
|
+
*
|
|
85
|
+
* It grows from there.
|
|
86
|
+
*/
|
|
87
|
+
this.rows = 1;
|
|
88
|
+
this.draft = '';
|
|
89
|
+
/**
|
|
90
|
+
* @internal Read by the transcript to find the composer among its children.
|
|
91
|
+
*/
|
|
92
|
+
this.isChatComposer = true;
|
|
93
|
+
/**
|
|
94
|
+
* Records the draft, and stops the textarea speaking in this element's name.
|
|
95
|
+
*
|
|
96
|
+
* **The stop is not incidental.** `input` is composed by specification, so the
|
|
97
|
+
* `<textarea>` in this shadow root sent its own past this host and on through
|
|
98
|
+
* whatever `<helix-chat>` it is slotted into, and neither element declares an
|
|
99
|
+
* `input`: a consumer binding one on either received an undeclared event whose
|
|
100
|
+
* target was a control they cannot reach. What a composer offers is
|
|
101
|
+
* `helix-send`, once, when the reader is done. See 308.
|
|
102
|
+
*/
|
|
103
|
+
this.handleInput = (event) => {
|
|
104
|
+
event.stopPropagation();
|
|
105
|
+
this.draft = event.target.value;
|
|
106
|
+
};
|
|
107
|
+
this.handleSend = () => {
|
|
108
|
+
this.send();
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Enter sends where that is what `submit-on` says, and never mid-composition.
|
|
112
|
+
*
|
|
113
|
+
* **`isComposing` is the part that is easy to leave out and breaks a whole
|
|
114
|
+
* writing system.** A reader typing Japanese, Chinese or Korean presses Enter
|
|
115
|
+
* to accept the candidate their input method is offering, and a composer that
|
|
116
|
+
* reads it as send fires off a half-finished word every time. The flag is on
|
|
117
|
+
* the event for exactly this and costs one condition.
|
|
118
|
+
*/
|
|
119
|
+
this.handleKey = (event) => {
|
|
120
|
+
if (event.key !== 'Enter' || this.submitOn !== 'enter') {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (event.shiftKey || event.isComposing) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
this.send();
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/** What is in the field, whoever last wrote it. */
|
|
131
|
+
get text() {
|
|
132
|
+
return this.draft || this.value;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Offers what is written, and reports whether it stood.
|
|
136
|
+
*
|
|
137
|
+
* Public because a consumer's own send control is as likely to ask as this
|
|
138
|
+
* element's is, and because a keyboard shortcut somewhere else on the page is
|
|
139
|
+
* a reasonable way to send.
|
|
140
|
+
*/
|
|
141
|
+
send() {
|
|
142
|
+
const value = this.text.trim();
|
|
143
|
+
if (value === '' || this.disabled) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
if (!this.dispatchEvent(new HelixSendEvent({ value }))) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
/* Cleared only here, after nobody refused. A composer that empties itself
|
|
150
|
+
first and hears about the failure afterwards has thrown away the only copy
|
|
151
|
+
of what the reader wrote. */
|
|
152
|
+
this.draft = '';
|
|
153
|
+
this.value = '';
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Says on each tool box whether anything is in it.
|
|
158
|
+
*
|
|
159
|
+
* They are boxes in a flex row, so an empty one still takes the gap beside it
|
|
160
|
+
* and the send control drifts inward by one for every slot a consumer left
|
|
161
|
+
* alone. No selector can ask this: a slot's assigned nodes are not its DOM
|
|
162
|
+
* children, so `:empty` describes the fallback rather than the fill.
|
|
163
|
+
*/
|
|
164
|
+
markEmpty() {
|
|
165
|
+
for (const name of ['start', 'end']) {
|
|
166
|
+
const region = this.renderRoot?.querySelector(`[part="${name}"]`);
|
|
167
|
+
const empty = !slotFilled(this.renderRoot?.querySelector(`slot[name="${name}"]`));
|
|
168
|
+
region?.toggleAttribute('data-empty', empty);
|
|
169
|
+
region?.toggleAttribute('hidden', empty);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
updated(changed) {
|
|
173
|
+
super.updated(changed);
|
|
174
|
+
this.markEmpty();
|
|
175
|
+
}
|
|
176
|
+
willUpdate(changed) {
|
|
177
|
+
super.willUpdate(changed);
|
|
178
|
+
hostAria(this.internals, { label: this.label, role: 'group' });
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* The control that offers the turn, behind a seam so a tier can draw its own.
|
|
182
|
+
*
|
|
183
|
+
* **A glyph with the label as its accessible name, rather than the label as
|
|
184
|
+
* text.** The word "Send" beside a field is the widest thing in the row and
|
|
185
|
+
* says nothing a return key does not, and every composer a reader has used in
|
|
186
|
+
* the last five years marks it rather than spells it. The return glyph is the
|
|
187
|
+
* mark because Enter is what actually sends, which `submit-on` says out loud:
|
|
188
|
+
* the control and the key are one affordance and should look like it.
|
|
189
|
+
*
|
|
190
|
+
* `send-label` is unchanged and is now the accessible name rather than the
|
|
191
|
+
* visible one, so a screen reader hears the same word it always did.
|
|
192
|
+
*/
|
|
193
|
+
renderSend() {
|
|
194
|
+
return html `<button
|
|
195
|
+
part="send"
|
|
196
|
+
type="button"
|
|
197
|
+
aria-label=${this.sendLabel}
|
|
198
|
+
?disabled=${this.disabled}
|
|
199
|
+
@click=${this.handleSend}
|
|
200
|
+
>
|
|
201
|
+
<svg
|
|
202
|
+
part="mark"
|
|
203
|
+
fill="currentColor"
|
|
204
|
+
viewBox=${arrowElbowDownLeft.viewBox}
|
|
205
|
+
aria-hidden="true"
|
|
206
|
+
>
|
|
207
|
+
${unsafeSVG(arrowElbowDownLeft.content)}
|
|
208
|
+
</svg>
|
|
209
|
+
</button>`;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The field, and a row of tools under it.
|
|
213
|
+
*
|
|
214
|
+
* **One row was the wrong shape and it got worse the more a composer had to
|
|
215
|
+
* carry.** Everything sat on a single line: an attachment control, the field,
|
|
216
|
+
* a stop control and a send button, so the field was squeezed from both sides
|
|
217
|
+
* and every tool a consumer added took width away from the thing being typed
|
|
218
|
+
* into. Under it, the field spans the whole composer at every width and the
|
|
219
|
+
* tools have a line of their own to grow along.
|
|
220
|
+
*
|
|
221
|
+
* Send is at the trailing end of that line rather than in the field, which is
|
|
222
|
+
* the same corner and costs no overlay: a control positioned inside a
|
|
223
|
+
* scrolling textarea either covers the last line of a long draft or scrolls
|
|
224
|
+
* away with it.
|
|
225
|
+
*/
|
|
226
|
+
render() {
|
|
227
|
+
return html `<div part="composer">
|
|
228
|
+
<textarea
|
|
229
|
+
part="field"
|
|
230
|
+
.value=${this.text}
|
|
231
|
+
aria-label=${this.label}
|
|
232
|
+
placeholder=${this.placeholder}
|
|
233
|
+
rows=${this.rows}
|
|
234
|
+
?disabled=${this.disabled}
|
|
235
|
+
@input=${this.handleInput}
|
|
236
|
+
@keydown=${this.handleKey}
|
|
237
|
+
></textarea>
|
|
238
|
+
<div part="tools">
|
|
239
|
+
<span part="start"><slot name="start"></slot></span>
|
|
240
|
+
<span part="end"><slot name="end"></slot></span>
|
|
241
|
+
${this.renderSend()}
|
|
242
|
+
</div>
|
|
243
|
+
</div>`;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
__decorate([
|
|
247
|
+
property()
|
|
248
|
+
], HelixHeadlessChatComposer.prototype, "value", void 0);
|
|
249
|
+
__decorate([
|
|
250
|
+
property()
|
|
251
|
+
], HelixHeadlessChatComposer.prototype, "placeholder", void 0);
|
|
252
|
+
__decorate([
|
|
253
|
+
property({ attribute: 'submit-on' })
|
|
254
|
+
], HelixHeadlessChatComposer.prototype, "submitOn", void 0);
|
|
255
|
+
__decorate([
|
|
256
|
+
property({ reflect: true, type: Boolean })
|
|
257
|
+
], HelixHeadlessChatComposer.prototype, "disabled", void 0);
|
|
258
|
+
__decorate([
|
|
259
|
+
property()
|
|
260
|
+
], HelixHeadlessChatComposer.prototype, "label", void 0);
|
|
261
|
+
__decorate([
|
|
262
|
+
property({ attribute: 'send-label' })
|
|
263
|
+
], HelixHeadlessChatComposer.prototype, "sendLabel", void 0);
|
|
264
|
+
__decorate([
|
|
265
|
+
property({ type: Number })
|
|
266
|
+
], HelixHeadlessChatComposer.prototype, "rows", void 0);
|
|
267
|
+
__decorate([
|
|
268
|
+
state()
|
|
269
|
+
], HelixHeadlessChatComposer.prototype, "draft", void 0);
|
|
270
|
+
HelixHeadlessChatComposer = __decorate([
|
|
271
|
+
customElement('helix-headless-chat-composer')
|
|
272
|
+
], HelixHeadlessChatComposer);
|
|
273
|
+
export { HelixHeadlessChatComposer };
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { HelixElement } from '@fusion.dev/helix-core';
|
|
2
|
+
import { nothing, type PropertyValues, type TemplateResult } from 'lit';
|
|
3
|
+
/**
|
|
4
|
+
* @summary One turn in a conversation, and what has happened to it.
|
|
5
|
+
*
|
|
6
|
+
* @description
|
|
7
|
+
* **The states are the component.** Bubbles are paint; what a chat message has
|
|
8
|
+
* to carry is whether it is on its way, arrived, still arriving, or failed, and
|
|
9
|
+
* a failed message needs a retry that is a real action rather than a toast the
|
|
10
|
+
* reader has to catch.
|
|
11
|
+
*
|
|
12
|
+
* `streaming` is the state everything else is arranged around. A message
|
|
13
|
+
* arriving token by token changes height on every frame, so it is marked
|
|
14
|
+
* `aria-busy` while it arrives and announced once when it settles: a screen
|
|
15
|
+
* reader reading a stream character by character is unusable, and announcing on
|
|
16
|
+
* completion is the only version of this that works.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.1.0
|
|
19
|
+
* @status experimental
|
|
20
|
+
* @category feedback
|
|
21
|
+
* @aliases Message, Bubble, Turn
|
|
22
|
+
* @documentation https://helix.fusion.dev/components/chat
|
|
23
|
+
*
|
|
24
|
+
* @slot - What was said.
|
|
25
|
+
* @slot actions - What can be done with it: copy, retry, react.
|
|
26
|
+
* @slot avatar - Who said it.
|
|
27
|
+
* @slot sources - What it was said from: citations, documents, a retrieved page.
|
|
28
|
+
*
|
|
29
|
+
* @event {HelixSendEvent} helix-send - Fired when the reader asks to send a failed message again, and cancelable.
|
|
30
|
+
*
|
|
31
|
+
* @csspart actions - The controls offered on the turn, beside its time.
|
|
32
|
+
* @csspart avatar - The leading slot's box.
|
|
33
|
+
* @csspart body - What was said, and the line under it.
|
|
34
|
+
* @csspart content - The consumer's own markup.
|
|
35
|
+
* @csspart mark - The status glyph beside a failure.
|
|
36
|
+
* @csspart message - The whole turn.
|
|
37
|
+
* @csspart meta - The line under a turn: its time, its state, and its controls.
|
|
38
|
+
* @csspart retry - The control offered on a failed message.
|
|
39
|
+
* @csspart sources - What the turn was drawn from, under it and outside the bubble.
|
|
40
|
+
* @csspart state - What has happened to it, where that is worth saying.
|
|
41
|
+
* @csspart time - When it was said.
|
|
42
|
+
*/
|
|
43
|
+
export declare class HelixHeadlessChatMessage extends HelixElement {
|
|
44
|
+
/**
|
|
45
|
+
* Who said it.
|
|
46
|
+
*
|
|
47
|
+
* Free text rather than a two-value union, because a conversation is not
|
|
48
|
+
* always two-sided: a transcript with a system turn, a tool call and three
|
|
49
|
+
* participants is the ordinary case for anything worth building this for.
|
|
50
|
+
* `me` and `them` are the conventional values and the stylesheet knows them;
|
|
51
|
+
* anything else is a name the consumer styles.
|
|
52
|
+
*/
|
|
53
|
+
author?: string;
|
|
54
|
+
/**
|
|
55
|
+
* What has happened to it.
|
|
56
|
+
*
|
|
57
|
+
* Reflected, because every one of the four is a visual state and a stylesheet
|
|
58
|
+
* has no other way to know. Absent is a settled message with nothing to
|
|
59
|
+
* report, which is what most of a transcript is, and it is the absence of the
|
|
60
|
+
* attribute rather than a value of it: there is no initializer, so nothing is
|
|
61
|
+
* reflected until something happens.
|
|
62
|
+
*/
|
|
63
|
+
state?: 'failed' | 'sending' | 'sent' | 'streaming';
|
|
64
|
+
/**
|
|
65
|
+
* When it was said, as anything `Date` parses.
|
|
66
|
+
*/
|
|
67
|
+
at: string;
|
|
68
|
+
/**
|
|
69
|
+
* Locale for the timestamp.
|
|
70
|
+
*
|
|
71
|
+
* Empty is the runtime's own.
|
|
72
|
+
*/
|
|
73
|
+
locale: string;
|
|
74
|
+
/**
|
|
75
|
+
* What to call each state, for a reader who cannot see it.
|
|
76
|
+
*/
|
|
77
|
+
sendingLabel: string;
|
|
78
|
+
/**
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
failedLabel: string;
|
|
82
|
+
/**
|
|
83
|
+
* Label for the control offered on a failed message.
|
|
84
|
+
*/
|
|
85
|
+
retryLabel: string;
|
|
86
|
+
/**
|
|
87
|
+
* @internal Read by the transcript to identify its children across the light
|
|
88
|
+
* DOM, which is cheaper than `instanceof`. Not a consumer's to read or set.
|
|
89
|
+
*/
|
|
90
|
+
readonly isChatMessage = true;
|
|
91
|
+
private clock;
|
|
92
|
+
/** The timestamp, or nothing where there is not one to read. */
|
|
93
|
+
private get moment();
|
|
94
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
95
|
+
private renderTime;
|
|
96
|
+
/**
|
|
97
|
+
* The status glyph, behind a seam so a tier can draw its own.
|
|
98
|
+
*
|
|
99
|
+
* `TONE_MARKS.danger` rather than a glyph chosen here: the library has one
|
|
100
|
+
* status vocabulary, `Callout`, `Toast.Item` and `Announcement` all read from
|
|
101
|
+
* it, and a reader meets these four marks in a passage, in a message and now
|
|
102
|
+
* on a turn and has to read them as the same four things. It carries the
|
|
103
|
+
* accessible name with it, which is the half that matters: `danger` is the
|
|
104
|
+
* word the API uses and "Error" is the word a reader understands.
|
|
105
|
+
*/
|
|
106
|
+
protected renderMark(): TemplateResult;
|
|
107
|
+
/**
|
|
108
|
+
* What has happened to it, in words, and the way back from a failure.
|
|
109
|
+
*
|
|
110
|
+
* A seam of its own, because the styled tier draws a failure as an icon and a
|
|
111
|
+
* consumer may want neither. `sent` says nothing: every settled message is
|
|
112
|
+
* sent, and a transcript that labels each one is a transcript of the word
|
|
113
|
+
* "sent".
|
|
114
|
+
*/
|
|
115
|
+
protected renderState(): TemplateResult | typeof nothing;
|
|
116
|
+
/**
|
|
117
|
+
* Says on each region whether anything is in it.
|
|
118
|
+
*
|
|
119
|
+
* Three of them need the answer and no selector can give it: a slot's assigned
|
|
120
|
+
* nodes are not its DOM children, so `:empty` and `:has(*)` both describe the
|
|
121
|
+
* fallback rather than the fill. `sources` and `actions` are regions that cost
|
|
122
|
+
* a gap when they are boxes at all, which most turns should not pay. `content`
|
|
123
|
+
* is the one that is not about space: a turn that is `streaming` with nothing
|
|
124
|
+
* in it yet is what the typing indicator is drawn for, and "nothing in it yet"
|
|
125
|
+
* is exactly this question.
|
|
126
|
+
*/
|
|
127
|
+
private markEmpty;
|
|
128
|
+
protected updated(changed: PropertyValues): void;
|
|
129
|
+
/**
|
|
130
|
+
* The turn: who said it, what was said, what it was drawn from, and its line.
|
|
131
|
+
*
|
|
132
|
+
* **`sources` and `actions` are inside the body rather than beside it**, and
|
|
133
|
+
* the second of those moved twice. `actions` was a third grid column, so a
|
|
134
|
+
* copy control on a fifteen-word turn sat at the container's trailing edge
|
|
135
|
+
* with a hundred and fifty pixels of nothing between it and the bubble it
|
|
136
|
+
* acted on, on both sides of the conversation. Moved into the body as a
|
|
137
|
+
* column of its own it was no better: a bubble spanning two auto tracks
|
|
138
|
+
* inflates both, so the controls landed under the middle of the turn.
|
|
139
|
+
*
|
|
140
|
+
* So they are inside `meta`, which is the line under a turn rather than only
|
|
141
|
+
* its timestamp, and that line is one flex row: time, state, controls, all
|
|
142
|
+
* hugging whichever edge the turn is against. Nothing has to be sized against
|
|
143
|
+
* anything else for that to hold at every width.
|
|
144
|
+
*/
|
|
145
|
+
protected render(): TemplateResult;
|
|
146
|
+
/**
|
|
147
|
+
* A turn's own content arrives and changes no property here.
|
|
148
|
+
*
|
|
149
|
+
* It is the streaming case that needs this rather than a tidiness one: the
|
|
150
|
+
* first token of an answer is a light-DOM child appearing under an element
|
|
151
|
+
* nothing else told to look again, and it is exactly the moment the typing
|
|
152
|
+
* indicator has to stop being drawn.
|
|
153
|
+
*/
|
|
154
|
+
private readonly handleFill;
|
|
155
|
+
/**
|
|
156
|
+
* Retry is `helix-send` again, from the message rather than the composer.
|
|
157
|
+
*
|
|
158
|
+
* **Not an event of its own**, because a retry is the same request: the reader
|
|
159
|
+
* is offering what they wrote, and the only difference is which element is
|
|
160
|
+
* offering it. A listener that wants to tell them apart has `event.target`,
|
|
161
|
+
* which is the message on a retry and the composer on a first send, and that
|
|
162
|
+
* is a distinction the DOM already makes without a second name for it.
|
|
163
|
+
*/
|
|
164
|
+
private readonly handleRetry;
|
|
165
|
+
}
|
|
166
|
+
declare global {
|
|
167
|
+
interface HTMLElementTagNameMap {
|
|
168
|
+
'helix-headless-chat-message': HelixHeadlessChatMessage;
|
|
169
|
+
}
|
|
170
|
+
}
|