@nocoo/basalt 2.2.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/ai/COMPATIBILITY.md +11 -1
- package/ai/DESIGN.md +398 -0
- package/ai/INTEGRATION.md +255 -129
- package/ai/RECIPES.md +51 -26
- package/ai/USAGE.md +4 -4
- package/ai/registry.json +3018 -271
- package/dist/charts/config.d.ts +11 -11
- package/dist/charts/config.js +4 -4
- package/dist/charts/config.js.map +1 -1
- package/dist/charts/date-navigation.js +10 -10
- package/dist/charts/date-navigation.js.map +1 -1
- package/dist/charts/donut.js +1 -1
- package/dist/charts/donut.js.map +1 -1
- package/dist/charts/frame.d.ts +1 -1
- package/dist/charts/frame.js +4 -4
- package/dist/charts/frame.js.map +1 -1
- package/dist/charts/gauge.js +5 -5
- package/dist/charts/gauge.js.map +1 -1
- package/dist/charts/heatmap-calendar.js +11 -11
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/heatmap-matrix.js +8 -8
- package/dist/charts/heatmap-matrix.js.map +1 -1
- package/dist/charts/item-list.js +1 -1
- package/dist/charts/item-list.js.map +1 -1
- package/dist/charts/legend.js +19 -19
- package/dist/charts/legend.js.map +1 -1
- package/dist/charts/palette.js +2 -2
- package/dist/charts/palette.js.map +1 -1
- package/dist/charts/slot-bar.js +2 -2
- package/dist/charts/slot-bar.js.map +1 -1
- package/dist/charts/sparkline.js +38 -23
- package/dist/charts/sparkline.js.map +1 -1
- package/dist/charts/stat-card.d.ts +2 -2
- package/dist/charts/stat-card.js +61 -58
- package/dist/charts/stat-card.js.map +1 -1
- package/dist/charts/timeline.js +18 -9
- package/dist/charts/timeline.js.map +1 -1
- package/dist/charts/tooltip.js +16 -16
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/accordion.js +1 -1
- package/dist/components/accordion.js.map +1 -1
- package/dist/components/alert-dialog.js +4 -4
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/app-header.js +8 -8
- package/dist/components/app-header.js.map +1 -1
- package/dist/components/app-shell.js +1 -1
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/approval-card.d.ts +13 -0
- package/dist/components/approval-card.js +161 -0
- package/dist/components/approval-card.js.map +1 -0
- package/dist/components/avatar.d.ts +12 -0
- package/dist/components/avatar.js +39 -18
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/badge.js +8 -8
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.d.ts +2 -2
- package/dist/components/banner.js +9 -8
- package/dist/components/banner.js.map +1 -1
- package/dist/components/basalt-mark.js +1 -1
- package/dist/components/basalt-mark.js.map +1 -1
- package/dist/components/battery-meter.js +5 -5
- package/dist/components/battery-meter.js.map +1 -1
- package/dist/components/breadcrumbs.js +6 -6
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/button.js +10 -10
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-bubble.js +4 -3
- package/dist/components/chat-bubble.js.map +1 -1
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/chat-composer.js +126 -60
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/chat-header.js +6 -6
- package/dist/components/chat-header.js.map +1 -1
- package/dist/components/chat-inbox.js +34 -30
- package/dist/components/chat-inbox.js.map +1 -1
- package/dist/components/chat-markdown.d.ts +8 -0
- package/dist/components/chat-markdown.js +122 -0
- package/dist/components/chat-markdown.js.map +1 -0
- package/dist/components/chat-message.d.ts +26 -0
- package/dist/components/chat-message.js +145 -0
- package/dist/components/chat-message.js.map +1 -0
- package/dist/components/checkbox.js +11 -11
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/clipboard-text.js +3 -3
- package/dist/components/clipboard-text.js.map +1 -1
- package/dist/components/code.d.ts +22 -20
- package/dist/components/code.js +94 -32
- package/dist/components/code.js.map +1 -1
- package/dist/components/collapsible.js +8 -4
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/command-palette.js +73 -47
- package/dist/components/command-palette.js.map +1 -1
- package/dist/components/context-cards.d.ts +15 -0
- package/dist/components/context-cards.js +148 -0
- package/dist/components/context-cards.js.map +1 -0
- package/dist/components/context-menu.d.ts +1 -1
- package/dist/components/context-menu.js +18 -14
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.d.ts +14 -2
- package/dist/components/data-table.js +185 -135
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.js +13 -13
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/delete-resource.js +1 -1
- package/dist/components/delete-resource.js.map +1 -1
- package/dist/components/description-list.js +3 -3
- package/dist/components/description-list.js.map +1 -1
- package/dist/components/dialog.d.ts +2 -2
- package/dist/components/dialog.js +8 -8
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/diff-table.d.ts +15 -0
- package/dist/components/diff-table.js +151 -0
- package/dist/components/diff-table.js.map +1 -0
- package/dist/components/dock.js +2 -2
- package/dist/components/dock.js.map +1 -1
- package/dist/components/dropdown-menu.js +23 -18
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/editable-nav-item.js +63 -58
- package/dist/components/editable-nav-item.js.map +1 -1
- package/dist/components/empty.js +6 -6
- package/dist/components/empty.js.map +1 -1
- package/dist/components/fab.js +1 -1
- package/dist/components/fab.js.map +1 -1
- package/dist/components/field.js +3 -3
- package/dist/components/field.js.map +1 -1
- package/dist/components/file-dropzone.js +7 -7
- package/dist/components/file-dropzone.js.map +1 -1
- package/dist/components/filter-bar.js +6 -6
- package/dist/components/filter-bar.js.map +1 -1
- package/dist/components/flow.js +4 -3
- package/dist/components/flow.js.map +1 -1
- package/dist/components/grid.d.ts +3 -1
- package/dist/components/grid.js +15 -8
- package/dist/components/grid.js.map +1 -1
- package/dist/components/hover-card.js +1 -1
- package/dist/components/hover-card.js.map +1 -1
- package/dist/components/icon-picker.d.ts +8 -2
- package/dist/components/icon-picker.js +75 -47
- package/dist/components/icon-picker.js.map +1 -1
- package/dist/components/inline-editable.js +6 -6
- package/dist/components/inline-editable.js.map +1 -1
- package/dist/components/input-area.js +3 -3
- package/dist/components/input-area.js.map +1 -1
- package/dist/components/input-group.js +5 -5
- package/dist/components/input-group.js.map +1 -1
- package/dist/components/input.js +4 -4
- package/dist/components/input.js.map +1 -1
- package/dist/components/label.js +3 -3
- package/dist/components/label.js.map +1 -1
- package/dist/components/layer-card.d.ts +9 -4
- package/dist/components/layer-card.js +72 -67
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/loader.d.ts +16 -10
- package/dist/components/loader.js +46 -53
- package/dist/components/loader.js.map +1 -1
- package/dist/components/loading-screen.js +3 -3
- package/dist/components/loading-screen.js.map +1 -1
- package/dist/components/menu-bar.js +32 -27
- package/dist/components/menu-bar.js.map +1 -1
- package/dist/components/meter.d.ts +5 -5
- package/dist/components/meter.js +25 -12
- package/dist/components/meter.js.map +1 -1
- package/dist/components/multi-select.js +66 -62
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/navigation-menu.d.ts +2 -2
- package/dist/components/navigation-menu.js +22 -8
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/overlay.js +2 -2
- package/dist/components/overlay.js.map +1 -1
- package/dist/components/page-header.d.ts +3 -1
- package/dist/components/page-header.js +12 -12
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/pagination.js +3 -3
- package/dist/components/pagination.js.map +1 -1
- package/dist/components/popover.js +18 -23
- package/dist/components/popover.js.map +1 -1
- package/dist/components/prompt-bar.d.ts +16 -0
- package/dist/components/prompt-bar.js +49 -0
- package/dist/components/prompt-bar.js.map +1 -0
- package/dist/components/radio.js +9 -9
- package/dist/components/radio.js.map +1 -1
- package/dist/components/recommendation-card.d.ts +13 -0
- package/dist/components/recommendation-card.js +123 -0
- package/dist/components/recommendation-card.js.map +1 -0
- package/dist/components/resource-list.js +1 -1
- package/dist/components/resource-list.js.map +1 -1
- package/dist/components/responsive-master-detail.js +4 -4
- package/dist/components/responsive-master-detail.js.map +1 -1
- package/dist/components/scroll-area.js +3 -3
- package/dist/components/scroll-area.js.map +1 -1
- package/dist/components/section-rule.d.ts +5 -3
- package/dist/components/section-rule.js +12 -12
- package/dist/components/section-rule.js.map +1 -1
- package/dist/components/segment-control.js +3 -3
- package/dist/components/segment-control.js.map +1 -1
- package/dist/components/select.js +47 -32
- package/dist/components/select.js.map +1 -1
- package/dist/components/sensitive-input.js +17 -19
- package/dist/components/sensitive-input.js.map +1 -1
- package/dist/components/sheet.d.ts +4 -4
- package/dist/components/sheet.js +11 -10
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/sidebar.js +149 -137
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.d.ts +1 -1
- package/dist/components/skeleton-line.js +2 -2
- package/dist/components/skeleton-line.js.map +1 -1
- package/dist/components/slider.js +2 -2
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stat-strip.js +5 -4
- package/dist/components/stat-strip.js.map +1 -1
- package/dist/components/switch.js +6 -6
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table-of-contents.js +5 -5
- package/dist/components/table-of-contents.js.map +1 -1
- package/dist/components/table-pager.js +2 -2
- package/dist/components/table-pager.js.map +1 -1
- package/dist/components/table.d.ts +39 -2
- package/dist/components/table.js +48 -17
- package/dist/components/table.js.map +1 -1
- package/dist/components/tabs.js +7 -6
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-badge.d.ts +10 -10
- package/dist/components/tag-badge.js +11 -11
- package/dist/components/tag-badge.js.map +1 -1
- package/dist/components/tag-color-picker.d.ts +8 -1
- package/dist/components/tag-color-picker.js +33 -25
- package/dist/components/tag-color-picker.js.map +1 -1
- package/dist/components/text.js +5 -5
- package/dist/components/text.js.map +1 -1
- package/dist/components/theme-toggle.js +1 -1
- package/dist/components/theme-toggle.js.map +1 -1
- package/dist/components/thinking.d.ts +16 -0
- package/dist/components/thinking.js +85 -0
- package/dist/components/thinking.js.map +1 -0
- package/dist/components/toast.js +25 -20
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +6 -5
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.js +6 -6
- package/dist/components/toggle.js.map +1 -1
- package/dist/components/tool-chips.d.ts +12 -0
- package/dist/components/tool-chips.js +138 -0
- package/dist/components/tool-chips.js.map +1 -0
- package/dist/components/toolbar.js +3 -3
- package/dist/components/toolbar.js.map +1 -1
- package/dist/components/tooltip.js +1 -1
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/typeahead-field.js +59 -56
- package/dist/components/typeahead-field.js.map +1 -1
- package/dist/components/upload-queue.js +15 -14
- package/dist/components/upload-queue.js.map +1 -1
- package/dist/models/agent-feedback.d.ts +44 -0
- package/dist/models/agent-feedback.js +28 -0
- package/dist/models/agent-feedback.js.map +1 -0
- package/dist/models/avatar.d.ts +2 -0
- package/dist/models/avatar.js +15 -0
- package/dist/models/avatar.js.map +1 -0
- package/dist/models/code.d.ts +6 -0
- package/dist/models/code.js +24 -0
- package/dist/models/code.js.map +1 -0
- package/dist/models/context-cards.d.ts +13 -0
- package/dist/models/context-cards.js +17 -0
- package/dist/models/context-cards.js.map +1 -0
- package/dist/models/diff-table.d.ts +12 -0
- package/dist/models/diff-table.js +9 -0
- package/dist/models/diff-table.js.map +1 -0
- package/dist/models/recommendation.d.ts +26 -0
- package/dist/models/recommendation.js +23 -0
- package/dist/models/recommendation.js.map +1 -0
- package/dist/styles/base.css +14 -2
- package/dist/styles/standalone.css +1901 -943
- package/dist/styles/tailwind.css +180 -13
- package/dist/styles/tokens.css +681 -20
- package/dist/utils/cn.js +25 -4
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/control-surface.d.ts +1 -1
- package/dist/utils/control-surface.js +1 -1
- package/dist/utils/control-surface.js.map +1 -1
- package/dist/utils/navigation.d.ts +3 -0
- package/dist/utils/navigation.js +8 -0
- package/dist/utils/navigation.js.map +1 -0
- package/dist/utils/selection-indicator.d.ts +1 -1
- package/dist/utils/selection-indicator.js +49 -72
- package/dist/utils/selection-indicator.js.map +1 -1
- package/dist/utils/use-hover-highlight.d.ts +4 -0
- package/dist/utils/use-hover-highlight.js +82 -0
- package/dist/utils/use-hover-highlight.js.map +1 -0
- package/dist/viewmodels/use-approval-card.d.ts +20 -0
- package/dist/viewmodels/use-approval-card.js +83 -0
- package/dist/viewmodels/use-approval-card.js.map +1 -0
- package/dist/viewmodels/use-chat-composer.d.ts +16 -0
- package/dist/viewmodels/use-chat-composer.js +34 -0
- package/dist/viewmodels/use-chat-composer.js.map +1 -0
- package/dist/viewmodels/use-chat-message.d.ts +16 -0
- package/dist/viewmodels/use-chat-message.js +26 -0
- package/dist/viewmodels/use-chat-message.js.map +1 -0
- package/dist/viewmodels/use-code-block.d.ts +8 -0
- package/dist/viewmodels/use-code-block.js +38 -0
- package/dist/viewmodels/use-code-block.js.map +1 -0
- package/dist/viewmodels/use-context-cards.d.ts +17 -0
- package/dist/viewmodels/use-context-cards.js +18 -0
- package/dist/viewmodels/use-context-cards.js.map +1 -0
- package/dist/viewmodels/use-diff-table.d.ts +16 -0
- package/dist/viewmodels/use-diff-table.js +42 -0
- package/dist/viewmodels/use-diff-table.js.map +1 -0
- package/dist/viewmodels/use-loader.d.ts +4 -0
- package/dist/viewmodels/use-loader.js +22 -0
- package/dist/viewmodels/use-loader.js.map +1 -0
- package/dist/viewmodels/use-recommendation-card.d.ts +17 -0
- package/dist/viewmodels/use-recommendation-card.js +41 -0
- package/dist/viewmodels/use-recommendation-card.js.map +1 -0
- package/dist/viewmodels/use-thinking.d.ts +13 -0
- package/dist/viewmodels/use-thinking.js +18 -0
- package/dist/viewmodels/use-thinking.js.map +1 -0
- package/dist/viewmodels/use-tool-chips.d.ts +10 -0
- package/dist/viewmodels/use-tool-chips.js +20 -0
- package/dist/viewmodels/use-tool-chips.js.map +1 -0
- package/package.json +28 -26
package/dist/utils/cn.js
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { clsx as e } from "clsx";
|
|
3
|
-
import {
|
|
3
|
+
import { extendTailwindMerge as t } from "tailwind-merge";
|
|
4
4
|
//#region src/utils/cn.ts
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
var n = t({ extend: { theme: {
|
|
6
|
+
spacing: [(e) => e.startsWith("basalt-")],
|
|
7
|
+
radius: [(e) => e.startsWith("basalt-")],
|
|
8
|
+
text: [
|
|
9
|
+
"basalt-xs",
|
|
10
|
+
"basalt-sm",
|
|
11
|
+
"basalt-code",
|
|
12
|
+
"basalt-base",
|
|
13
|
+
"basalt-lg",
|
|
14
|
+
"basalt-xl",
|
|
15
|
+
"basalt-2xl",
|
|
16
|
+
"basalt-3xl",
|
|
17
|
+
"basalt-4xl",
|
|
18
|
+
"basalt-5xl",
|
|
19
|
+
"basalt-6xl",
|
|
20
|
+
"basalt-7xl",
|
|
21
|
+
"basalt-8xl",
|
|
22
|
+
"basalt-9xl",
|
|
23
|
+
"basalt-10xl"
|
|
24
|
+
]
|
|
25
|
+
} } });
|
|
26
|
+
function r(...t) {
|
|
27
|
+
return n(e(t));
|
|
7
28
|
}
|
|
8
29
|
//#endregion
|
|
9
|
-
export {
|
|
30
|
+
export { r as cn };
|
|
10
31
|
|
|
11
32
|
//# sourceMappingURL=cn.js.map
|
package/dist/utils/cn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cn.js","names":["
|
|
1
|
+
{"version":3,"file":"cn.js","names":["twMerge","extendTailwindMerge","value","cn","inputs","clsx"],"sources":["../../src/utils/cn.ts"],"sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\nconst twMerge = extendTailwindMerge({\n\textend: {\n\t\ttheme: {\n\t\t\tspacing: [(value: string) => value.startsWith(\"basalt-\")],\n\t\t\tradius: [(value: string) => value.startsWith(\"basalt-\")],\n\t\t\ttext: [\n\t\t\t\t\"basalt-xs\",\n\t\t\t\t\"basalt-sm\",\n\t\t\t\t\"basalt-code\",\n\t\t\t\t\"basalt-base\",\n\t\t\t\t\"basalt-lg\",\n\t\t\t\t\"basalt-xl\",\n\t\t\t\t\"basalt-2xl\",\n\t\t\t\t\"basalt-3xl\",\n\t\t\t\t\"basalt-4xl\",\n\t\t\t\t\"basalt-5xl\",\n\t\t\t\t\"basalt-6xl\",\n\t\t\t\t\"basalt-7xl\",\n\t\t\t\t\"basalt-8xl\",\n\t\t\t\t\"basalt-9xl\",\n\t\t\t\t\"basalt-10xl\",\n\t\t\t],\n\t\t},\n\t},\n});\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n"],"mappings":";;;;AAGA,IAAMA,IAAUC,EAAoB,EACnC,QAAQ,EACP,OAAO;CACN,SAAS,EAAE,MAAkBC,EAAM,WAAW,SAAS,CAAC;CACxD,QAAQ,EAAE,MAAkBA,EAAM,WAAW,SAAS,CAAC;CACvD,MAAM;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD;AACD,EACD,EACD,CAAC;AAED,SAAgBC,EAAG,GAAGC,GAAsB;CAC3C,OAAOJ,EAAQK,EAAKD,CAAM,CAAC;AAC5B"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const BASALT_UI_CLASS = "basalt-ui";
|
|
2
|
-
export declare const CONTROL_SURFACE_CLASS = "basalt-ui rounded-basalt-md border border-basalt-border bg-basalt-control
|
|
2
|
+
export declare const CONTROL_SURFACE_CLASS = "basalt-ui rounded-basalt-md border border-basalt-border bg-basalt-control";
|
|
3
3
|
export declare function controlSurfaceClass(className?: string): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn as e } from "./cn.js";
|
|
3
3
|
//#region src/utils/control-surface.ts
|
|
4
|
-
var t = "basalt-ui", n = "basalt-ui rounded-basalt-md border border-basalt-border bg-basalt-control
|
|
4
|
+
var t = "basalt-ui", n = "basalt-ui rounded-basalt-md border border-basalt-border bg-basalt-control";
|
|
5
5
|
function r(t) {
|
|
6
6
|
return e(n, t);
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-surface.js","names":["BASALT_UI_CLASS","CONTROL_SURFACE_CLASS","controlSurfaceClass","cn","className"],"sources":["../../src/utils/control-surface.ts"],"sourcesContent":["import { cn } from \"./cn\";\n\nexport const BASALT_UI_CLASS = \"basalt-ui\";\n\nexport const CONTROL_SURFACE_CLASS =\n\t\"basalt-ui rounded-basalt-md border border-basalt-border bg-basalt-control
|
|
1
|
+
{"version":3,"file":"control-surface.js","names":["BASALT_UI_CLASS","CONTROL_SURFACE_CLASS","controlSurfaceClass","cn","className"],"sources":["../../src/utils/control-surface.ts"],"sourcesContent":["import { cn } from \"./cn\";\n\nexport const BASALT_UI_CLASS = \"basalt-ui\";\n\nexport const CONTROL_SURFACE_CLASS =\n\t\"basalt-ui rounded-basalt-md border border-basalt-border bg-basalt-control\";\n\nexport function controlSurfaceClass(className?: string) {\n\treturn cn(CONTROL_SURFACE_CLASS, className);\n}\n"],"mappings":";;;AAEA,IAAaA,IAAkB,aAElBC,IACZ;AAED,SAAgBC,EAAoB,GAAoB;CACvD,OAAOC,EAAGF,GAAuBG,CAAS;AAC3C"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const NAV_LIST_CLASS = "basalt-ui basalt-hover-list flex gap-basalt-nav-gap p-basalt-nav-inset";
|
|
2
|
+
export declare const NAV_ROW_CLASS = "flex min-w-0 shrink-0 min-h-basalt-control items-center gap-basalt-row-gap rounded-basalt-md px-basalt-row-x py-basalt-row-y text-left text-basalt-base font-normal leading-basalt-row [&>svg]:size-basalt-icon-lg [&>svg]:shrink-0";
|
|
3
|
+
export declare const NAV_ITEM_CLASS = "basalt-ui basalt-nav-item flex min-w-0 shrink-0 min-h-basalt-control items-center gap-basalt-row-gap rounded-basalt-md px-basalt-row-x py-basalt-row-y text-left text-basalt-base font-normal leading-basalt-row [&>svg]:size-basalt-icon-lg [&>svg]:shrink-0 outline-hidden focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-basalt-ring";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { FOCUS_INSET as e } from "../components/overlay.js";
|
|
3
|
+
//#region src/utils/navigation.ts
|
|
4
|
+
var t = "basalt-ui basalt-hover-list flex gap-basalt-nav-gap p-basalt-nav-inset", n = "flex min-w-0 shrink-0 min-h-basalt-control items-center gap-basalt-row-gap rounded-basalt-md px-basalt-row-x py-basalt-row-y text-left text-basalt-base font-normal leading-basalt-row [&>svg]:size-basalt-icon-lg [&>svg]:shrink-0", r = `basalt-ui basalt-nav-item ${n} ${e}`;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { r as NAV_ITEM_CLASS, t as NAV_LIST_CLASS, n as NAV_ROW_CLASS };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","names":["NAV_LIST_CLASS","NAV_ROW_CLASS","NAV_ITEM_CLASS","FOCUS_INSET"],"sources":["../../src/utils/navigation.ts"],"sourcesContent":["import { FOCUS_INSET } from \"../components/overlay\";\n\nexport const NAV_LIST_CLASS =\n\t\"basalt-ui basalt-hover-list flex gap-basalt-nav-gap p-basalt-nav-inset\";\n\nexport const NAV_ROW_CLASS =\n\t\"flex min-w-0 shrink-0 min-h-basalt-control items-center gap-basalt-row-gap rounded-basalt-md px-basalt-row-x py-basalt-row-y text-left text-basalt-base font-normal leading-basalt-row [&>svg]:size-basalt-icon-lg [&>svg]:shrink-0\";\n\nexport const NAV_ITEM_CLASS = `basalt-ui basalt-nav-item ${NAV_ROW_CLASS} ${FOCUS_INSET}`;\n"],"mappings":";;;AAEA,IAAaA,IACZ,0EAEYC,IACZ,uOAEYC,IAAiB,6BAA6BD,EAAc,GAAGE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
export declare const SELECTION_INDICATOR_MOTION_CLASS = "
|
|
2
|
+
export declare const SELECTION_INDICATOR_MOTION_CLASS = "basalt-selection-motion";
|
|
3
3
|
export type SelectionGeometry = {
|
|
4
4
|
left: number;
|
|
5
5
|
width: number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import * as e from "react";
|
|
3
3
|
//#region src/utils/selection-indicator.ts
|
|
4
|
-
var t = "
|
|
4
|
+
var t = "basalt-selection-motion", n = {
|
|
5
5
|
left: 0,
|
|
6
6
|
width: 0,
|
|
7
7
|
top: 0,
|
|
@@ -18,91 +18,68 @@ function i(e) {
|
|
|
18
18
|
height: e.offsetHeight
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
function a() {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
let t = [e];
|
|
26
|
-
for (let n of e.children) n instanceof HTMLElement && n.getAttribute("aria-hidden") !== "true" && t.push(n);
|
|
27
|
-
return t;
|
|
28
|
-
}
|
|
29
|
-
function s({ itemSelector: s, enabled: c = !0, mapGeometry: l, ref: u }) {
|
|
30
|
-
let d = e.useRef(null), f = e.useMemo(() => (e) => {
|
|
31
|
-
d.current = e, r(u, e);
|
|
32
|
-
}, [u]), [p, m] = e.useState({
|
|
21
|
+
function a({ itemSelector: a, enabled: o = !0, mapGeometry: s, ref: c }) {
|
|
22
|
+
let l = e.useRef(null), u = e.useCallback((e) => {
|
|
23
|
+
l.current = e, r(c, e);
|
|
24
|
+
}, [c]), [d, f] = e.useState({
|
|
33
25
|
...n,
|
|
34
26
|
visible: !1,
|
|
35
27
|
animated: !1
|
|
36
|
-
})
|
|
37
|
-
e.
|
|
38
|
-
let e =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
let _ = e.useCallback(() => {
|
|
42
|
-
let e = d.current;
|
|
43
|
-
if (!e || !c) {
|
|
44
|
-
m((e) => ({
|
|
45
|
-
...e,
|
|
28
|
+
});
|
|
29
|
+
return e.useLayoutEffect(() => {
|
|
30
|
+
let e = l.current;
|
|
31
|
+
if (!e || !o) {
|
|
32
|
+
f({
|
|
46
33
|
...n,
|
|
47
34
|
visible: !1,
|
|
48
35
|
animated: !1
|
|
49
|
-
})
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
let t = e.querySelector(s);
|
|
53
|
-
if (!t) {
|
|
54
|
-
m((e) => ({
|
|
55
|
-
...e,
|
|
56
|
-
width: 0,
|
|
57
|
-
height: 0,
|
|
58
|
-
visible: !1,
|
|
59
|
-
animated: !1
|
|
60
|
-
}));
|
|
36
|
+
});
|
|
61
37
|
return;
|
|
62
38
|
}
|
|
63
|
-
let r = (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}), r = () => {
|
|
81
|
-
n.disconnect();
|
|
82
|
-
for (let t of o(e)) n.observe(t);
|
|
83
|
-
};
|
|
84
|
-
r(), _();
|
|
85
|
-
let i = new MutationObserver(() => {
|
|
86
|
-
cancelAnimationFrame(t), t = requestAnimationFrame(() => {
|
|
87
|
-
r(), _();
|
|
88
|
-
});
|
|
39
|
+
let t = null, r = 0, c = window.matchMedia("(prefers-reduced-motion: reduce)"), u = () => {
|
|
40
|
+
r = 0;
|
|
41
|
+
let o = e.querySelector(a), l = o ? (s ?? i)(o, e) : n, u = !!o && o.offsetWidth > 0 && o.offsetHeight > 0, d = u && !!t && t !== o && !c.matches;
|
|
42
|
+
t = u ? o : null;
|
|
43
|
+
let p = {
|
|
44
|
+
...l,
|
|
45
|
+
visible: u,
|
|
46
|
+
animated: d
|
|
47
|
+
};
|
|
48
|
+
f((e) => e.visible === u && e.left === l.left && e.top === l.top && e.width === l.width && e.height === l.height && !(c.matches && e.animated) ? e : p);
|
|
49
|
+
}, d = () => {
|
|
50
|
+
r ||= requestAnimationFrame(u);
|
|
51
|
+
}, p = new ResizeObserver(d), m = () => {
|
|
52
|
+
p.disconnect(), p.observe(e);
|
|
53
|
+
for (let t of e.children) t instanceof HTMLElement && t.getAttribute("aria-hidden") !== "true" && p.observe(t);
|
|
54
|
+
}, h = new MutationObserver((e) => {
|
|
55
|
+
e.some((e) => e.type === "childList") && m(), d();
|
|
89
56
|
});
|
|
90
|
-
return
|
|
91
|
-
attributes: !0,
|
|
57
|
+
return m(), u(), h.observe(e, {
|
|
92
58
|
subtree: !0,
|
|
93
59
|
childList: !0,
|
|
94
|
-
|
|
95
|
-
attributeFilter: [
|
|
96
|
-
|
|
97
|
-
|
|
60
|
+
attributes: !0,
|
|
61
|
+
attributeFilter: [
|
|
62
|
+
"data-state",
|
|
63
|
+
"aria-checked",
|
|
64
|
+
"aria-current",
|
|
65
|
+
"data-selected",
|
|
66
|
+
"data-disabled",
|
|
67
|
+
"hidden"
|
|
68
|
+
]
|
|
69
|
+
}), c.addEventListener("change", d), () => {
|
|
70
|
+
cancelAnimationFrame(r), p.disconnect(), h.disconnect(), c.removeEventListener("change", d);
|
|
98
71
|
};
|
|
99
|
-
}, [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
72
|
+
}, [
|
|
73
|
+
o,
|
|
74
|
+
a,
|
|
75
|
+
s
|
|
76
|
+
]), {
|
|
77
|
+
ref: u,
|
|
78
|
+
state: d,
|
|
79
|
+
motionClassName: d.animated ? t : void 0
|
|
103
80
|
};
|
|
104
81
|
}
|
|
105
82
|
//#endregion
|
|
106
|
-
export { t as SELECTION_INDICATOR_MOTION_CLASS, r as assignRef, i as measureSelectionItem,
|
|
83
|
+
export { t as SELECTION_INDICATOR_MOTION_CLASS, r as assignRef, i as measureSelectionItem, a as useSelectionIndicator };
|
|
107
84
|
|
|
108
85
|
//# sourceMappingURL=selection-indicator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-indicator.js","names":["React","SELECTION_INDICATOR_MOTION_CLASS","EMPTY","assignRef","ref","value","measureSelectionItem","item","
|
|
1
|
+
{"version":3,"file":"selection-indicator.js","names":["React","SELECTION_INDICATOR_MOTION_CLASS","EMPTY","assignRef","ref","value","measureSelectionItem","item","useSelectionIndicator","rootRef","composedRef","node","state","setState","root","enabled","previous","frame","media","sync","itemSelector","box","mapGeometry","visible","animated","next","current","schedule","resize","observe","child","mutations","records","record"],"sources":["../../src/utils/selection-indicator.ts"],"sourcesContent":["import * as React from \"react\";\n\nexport const SELECTION_INDICATOR_MOTION_CLASS = \"basalt-selection-motion\";\n\nexport type SelectionGeometry = { left: number; width: number; top: number; height: number };\nexport type SelectionIndicatorState = SelectionGeometry & { visible: boolean; animated: boolean };\nconst EMPTY: SelectionGeometry = { left: 0, width: 0, top: 0, height: 0 };\n\nexport function assignRef<T>(ref: React.Ref<T> | undefined, value: T | null) {\n\tif (typeof ref === \"function\") ref(value);\n\telse if (ref) (ref as React.MutableRefObject<T | null>).current = value;\n}\n\nexport function measureSelectionItem(item: HTMLElement): SelectionGeometry {\n\treturn {\n\t\tleft: item.offsetLeft,\n\t\twidth: item.offsetWidth,\n\t\ttop: item.offsetTop,\n\t\theight: item.offsetHeight,\n\t};\n}\n\nexport function useSelectionIndicator({\n\titemSelector,\n\tenabled = true,\n\tmapGeometry,\n\tref,\n}: {\n\titemSelector: string;\n\tenabled?: boolean;\n\tmapGeometry?: (item: HTMLElement, root: HTMLElement) => SelectionGeometry;\n\tref?: React.Ref<HTMLElement | null>;\n}) {\n\tconst rootRef = React.useRef<HTMLElement | null>(null);\n\tconst composedRef = React.useCallback(\n\t\t(node: HTMLElement | null) => {\n\t\t\trootRef.current = node;\n\t\t\tassignRef(ref, node);\n\t\t},\n\t\t[ref],\n\t);\n\tconst [state, setState] = React.useState<SelectionIndicatorState>({\n\t\t...EMPTY,\n\t\tvisible: false,\n\t\tanimated: false,\n\t});\n\tReact.useLayoutEffect(() => {\n\t\tconst root = rootRef.current;\n\t\tif (!root || !enabled) {\n\t\t\tsetState({ ...EMPTY, visible: false, animated: false });\n\t\t\treturn;\n\t\t}\n\t\tlet previous: HTMLElement | null = null;\n\t\tlet frame = 0;\n\t\tconst media = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n\t\tconst sync = () => {\n\t\t\tframe = 0;\n\t\t\tconst item = root.querySelector<HTMLElement>(itemSelector);\n\t\t\tconst box = item ? (mapGeometry ?? measureSelectionItem)(item, root) : EMPTY;\n\t\t\t// Hidden panels measure zero. They must never become the animation's origin.\n\t\t\tconst visible = !!item && item.offsetWidth > 0 && item.offsetHeight > 0;\n\t\t\tconst animated = visible && !!previous && previous !== item && !media.matches;\n\t\t\tprevious = visible ? item : null;\n\t\t\tconst next = { ...box, visible, animated };\n\t\t\tsetState((current) => {\n\t\t\t\tconst unchanged =\n\t\t\t\t\tcurrent.visible === visible &&\n\t\t\t\t\tcurrent.left === box.left &&\n\t\t\t\t\tcurrent.top === box.top &&\n\t\t\t\t\tcurrent.width === box.width &&\n\t\t\t\t\tcurrent.height === box.height;\n\t\t\t\t// Initial ResizeObserver delivery must not cancel an in-flight selection.\n\t\t\t\treturn unchanged && !(media.matches && current.animated) ? current : next;\n\t\t\t});\n\t\t};\n\t\tconst schedule = () => {\n\t\t\tif (!frame) frame = requestAnimationFrame(sync);\n\t\t};\n\t\tconst resize = new ResizeObserver(schedule);\n\t\tconst observe = () => {\n\t\t\tresize.disconnect();\n\t\t\tresize.observe(root);\n\t\t\tfor (const child of root.children)\n\t\t\t\tif (child instanceof HTMLElement && child.getAttribute(\"aria-hidden\") !== \"true\")\n\t\t\t\t\tresize.observe(child);\n\t\t};\n\t\tconst mutations = new MutationObserver((records) => {\n\t\t\tif (records.some((record) => record.type === \"childList\")) observe();\n\t\t\tschedule();\n\t\t});\n\t\tobserve();\n\t\tsync();\n\t\tmutations.observe(root, {\n\t\t\tsubtree: true,\n\t\t\tchildList: true,\n\t\t\tattributes: true,\n\t\t\tattributeFilter: [\n\t\t\t\t\"data-state\",\n\t\t\t\t\"aria-checked\",\n\t\t\t\t\"aria-current\",\n\t\t\t\t\"data-selected\",\n\t\t\t\t\"data-disabled\",\n\t\t\t\t\"hidden\",\n\t\t\t],\n\t\t});\n\t\tmedia.addEventListener(\"change\", schedule);\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(frame);\n\t\t\tresize.disconnect();\n\t\t\tmutations.disconnect();\n\t\t\tmedia.removeEventListener(\"change\", schedule);\n\t\t};\n\t}, [enabled, itemSelector, mapGeometry]);\n\treturn {\n\t\tref: composedRef,\n\t\tstate,\n\t\tmotionClassName: state.animated ? SELECTION_INDICATOR_MOTION_CLASS : undefined,\n\t};\n}\n"],"mappings":";;;AAEA,IAAaC,IAAmC,2BAI1CC,IAA2B;CAAE,MAAM;CAAG,OAAO;CAAG,KAAK;CAAG,QAAQ;AAAE;AAExE,SAAgBC,EAAa,GAA+B,GAAiB;CAC5E,AAAI,OAAOC,KAAQ,aAAYA,EAAIC,CAAK,IAC/BD,MAAK,EAA0C,UAAUC;AACnE;AAEA,SAAgBC,EAAqB,GAAsC;CAC1E,OAAO;EACN,MAAMC,EAAK;EACX,OAAOA,EAAK;EACZ,KAAKA,EAAK;EACV,QAAQA,EAAK;CACd;AACD;AAEA,SAAgBC,EAAsB,EACrC,iBACA,aAAU,IACV,gBACA,UAME;CACF,IAAMC,IAAUT,EAAM,OAA2B,IAAI,GAC/CU,IAAcV,EAAM,aACxB,MAA6B;EAE7B,AADA,EAAQ,UAAUW,GAClBR,EAAUC,GAAKO,CAAI;CACpB,GACA,CAACP,CAAG,CACL,GACM,CAACQ,GAAOC,KAAYb,EAAM,SAAkC;EACjE,GAAGE;EACH,SAAS;EACT,UAAU;CACX,CAAC;CAoED,OAnEAF,EAAM,sBAAsB;EAC3B,IAAMc,IAAOL,EAAQ;EACrB,IAAI,CAACK,KAAQ,CAACC,GAAS;GACtB,EAAS;IAAE,GAAGb;IAAO,SAAS;IAAO,UAAU;GAAM,CAAC;GACtD;EACD;EACA,IAAIc,IAA+B,MAC/BC,IAAQ,GACNC,IAAQ,OAAO,WAAW,kCAAkC,GAC5DC,UAAa;GAClB,IAAQ;GACR,IAAMZ,IAAOO,EAAK,cAA2BM,CAAY,GACnDC,IAAMd,KAAQe,KAAehB,EAAA,CAAsBC,GAAMO,CAAI,IAAIZ,GAEjEqB,IAAU,CAAC,CAAChB,KAAQA,EAAK,cAAc,KAAKA,EAAK,eAAe,GAChEiB,IAAWD,KAAW,CAAC,CAACP,KAAYA,MAAaT,KAAQ,CAACW,EAAM;GACtE,IAAWK,IAAUhB,IAAO;GAC5B,IAAMkB,IAAO;IAAE,GAAGJ;IAAK;IAAS;GAAS;GACzC,GAAU,MAERK,EAAQ,YAAYH,KACpBG,EAAQ,SAASL,EAAI,QACrBK,EAAQ,QAAQL,EAAI,OACpBK,EAAQ,UAAUL,EAAI,SACtBK,EAAQ,WAAWL,EAAI,UAEJ,EAAEH,EAAM,WAAWQ,EAAQ,YAAYA,IAAUD,CACrE;EACF,GACME,UAAiB;GACtB,AAAYV,MAAQ,sBAAsBE,CAAI;EAC/C,GACMS,IAAS,IAAI,eAAeD,CAAQ,GACpCE,UAAgB;GAErB,AADAD,EAAO,WAAW,GAClBA,EAAO,QAAQd,CAAI;GACnB,KAAK,IAAMgB,KAAShB,EAAK,UACxB,AAAIgB,aAAiB,eAAeA,EAAM,aAAa,aAAa,MAAM,UACzEF,EAAO,QAAQE,CAAK;EACvB,GACMC,IAAY,IAAI,kBAAkB,MAAY;GAEnD,AADIC,EAAQ,MAAM,MAAWC,EAAO,SAAS,WAAW,KAAGJ,EAAQ,GACnEF,EAAS;EACV,CAAC;EAiBD,OAhBAE,EAAQ,GACRV,EAAK,GACLY,EAAU,QAAQjB,GAAM;GACvB,SAAS;GACT,WAAW;GACX,YAAY;GACZ,iBAAiB;IAChB;IACA;IACA;IACA;IACA;IACA;GACD;EACD,CAAC,GACDI,EAAM,iBAAiB,UAAUS,CAAQ,SAC5B;GAIZ,AAHA,qBAAqBV,CAAK,GAC1BW,EAAO,WAAW,GAClBG,EAAU,WAAW,GACrBb,EAAM,oBAAoB,UAAUS,CAAQ;EAC7C;CACD,GAAG;EAACZ;EAASK;EAAcE;CAAW,CAAC,GAChC;EACN,KAAKZ;EACL;EACA,iBAAiBE,EAAM,WAAWX,IAAmC,KAAA;CACtE;AACD"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { assignRef as e } from "./selection-indicator.js";
|
|
3
|
+
import { useCallback as t } from "react";
|
|
4
|
+
//#region src/utils/use-hover-highlight.ts
|
|
5
|
+
var n = "[data-basalt-hover-item]", r = "[data-highlighted], [data-hover-active=\"true\"], [aria-selected=\"true\"], [data-state=\"checked\"], [data-hover-selected=\"true\"], [data-selected=\"true\"]";
|
|
6
|
+
function i(i, { restoreOnPointerLeave: a = !0 } = {}) {
|
|
7
|
+
return t((t) => {
|
|
8
|
+
if (e(i, t), !t) return;
|
|
9
|
+
let o = null, s = !1, c = !1, l = null, u = null, d = null, f = null, p = !0, m = 0, h = "", g = !0, _ = (e) => e && t.contains(e) && e.matches(n) && e.closest(".basalt-hover-list") === t && !e.closest("[hidden], [disabled], [aria-disabled=\"true\"], [data-disabled=\"\"], [data-disabled=\"true\"]") ? e : null, v = (e) => _(e instanceof Element ? e.closest(n) : null), y = new ResizeObserver(() => {
|
|
10
|
+
g = !0, x();
|
|
11
|
+
}), b = () => {
|
|
12
|
+
if (m = 0, p) {
|
|
13
|
+
f = null, d = null;
|
|
14
|
+
for (let e of t.querySelectorAll(`${n}:is(${r})`)) if (_(e) && (d ||= e, e.matches("[data-highlighted], [data-hover-active=\"true\"]"))) {
|
|
15
|
+
f = e;
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
p = !1;
|
|
19
|
+
}
|
|
20
|
+
let e = c;
|
|
21
|
+
c = !1, e && (t.dataset.hoverAnimated = "false");
|
|
22
|
+
let i = s ? null : a ? _(f) ?? _(o) ?? _(l) ?? _(d) : _(o);
|
|
23
|
+
if (i === u && !g) return;
|
|
24
|
+
i !== u && (u && y.unobserve(u), i && y.observe(i));
|
|
25
|
+
let v = i?.offsetWidth ?? 0, b = i?.offsetHeight ?? 0;
|
|
26
|
+
if (!i || !v || !b) {
|
|
27
|
+
a || (t.dataset.hoverAnimated = "false"), t.dataset.hoverVisible = "false", u = null, h = "", g = !1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
let x = 0, S = 0;
|
|
31
|
+
for (let e = i; e && e !== t; e = e.offsetParent) x += e.offsetLeft, S += e.offsetTop;
|
|
32
|
+
for (let e = i.parentElement; e && e !== t; e = e.parentElement) x -= e.scrollLeft, S -= e.scrollTop;
|
|
33
|
+
let C = `${x},${S},${v},${b}`;
|
|
34
|
+
C !== h && (t.dataset.hoverAnimated = u && u !== i && !g && !e ? "true" : "false", t.style.setProperty("--basalt-hover-x", `${x}px`), t.style.setProperty("--basalt-hover-y", `${S}px`), t.style.setProperty("--basalt-hover-width", `${v}px`), t.style.setProperty("--basalt-hover-height", `${b}px`), h = C), t.dataset.hoverVisible = "true", u = i, g = !1;
|
|
35
|
+
};
|
|
36
|
+
function x() {
|
|
37
|
+
m ||= requestAnimationFrame(b);
|
|
38
|
+
}
|
|
39
|
+
let S = (e) => {
|
|
40
|
+
if (e.pointerType === "touch") return;
|
|
41
|
+
s = !1;
|
|
42
|
+
let t = v(e.target);
|
|
43
|
+
t !== o && (!a && (!t || !o) && (c = !0), o = t, x());
|
|
44
|
+
}, C = () => {
|
|
45
|
+
o = null, s = !a, a || (c = !0), x();
|
|
46
|
+
}, w = (e) => {
|
|
47
|
+
l = v(e.target), a && (s = !1, o = null, x());
|
|
48
|
+
}, T = (e) => {
|
|
49
|
+
l = v(e.relatedTarget), a && x();
|
|
50
|
+
}, E = (e) => {
|
|
51
|
+
e.target instanceof Element && (t.contains(e.target) || t.id && e.target.getAttribute("aria-controls") === t.id) && a && (o = null, s = !1, x());
|
|
52
|
+
}, D = (e) => {
|
|
53
|
+
(e.target !== t || e.type === "scroll") && (g = !0, x());
|
|
54
|
+
}, O = new MutationObserver((e) => {
|
|
55
|
+
p = !0, e.some((e) => e.type === "childList" || e.attributeName === "hidden") && (g = !0), x();
|
|
56
|
+
});
|
|
57
|
+
return O.observe(t, {
|
|
58
|
+
subtree: !0,
|
|
59
|
+
childList: !0,
|
|
60
|
+
attributes: !0,
|
|
61
|
+
attributeFilter: [
|
|
62
|
+
"data-basalt-hover-item",
|
|
63
|
+
"data-highlighted",
|
|
64
|
+
"data-state",
|
|
65
|
+
"aria-selected",
|
|
66
|
+
"data-selected",
|
|
67
|
+
"data-hover-active",
|
|
68
|
+
"data-hover-selected",
|
|
69
|
+
"disabled",
|
|
70
|
+
"aria-disabled",
|
|
71
|
+
"data-disabled",
|
|
72
|
+
"hidden"
|
|
73
|
+
]
|
|
74
|
+
}), y.observe(t), t.addEventListener("pointerover", S), t.addEventListener("pointerleave", C), t.addEventListener("focusin", w), t.addEventListener("focusout", T), t.ownerDocument.addEventListener("keydown", E), t.addEventListener("scroll", D, !0), t.addEventListener("animationend", D), t.addEventListener("transitionend", D), x(), () => {
|
|
75
|
+
cancelAnimationFrame(m), y.disconnect(), O.disconnect(), t.removeEventListener("pointerover", S), t.removeEventListener("pointerleave", C), t.removeEventListener("focusin", w), t.removeEventListener("focusout", T), t.ownerDocument.removeEventListener("keydown", E), t.removeEventListener("scroll", D, !0), t.removeEventListener("animationend", D), t.removeEventListener("transitionend", D), e(i, null);
|
|
76
|
+
};
|
|
77
|
+
}, [i, a]);
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
export { i as useHoverHighlight };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=use-hover-highlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-hover-highlight.js","names":["ROW","ACTIVE","useHoverHighlight","useCallback","assignRef","ref","root","hovered","pointerExited","sequenceBroken","focused","previous","selected","active","selectionDirty","frame","geometry","layoutChanged","eligible","node","row","target","resize","schedule","update","broken","item","restoreOnPointerLeave","width","height","y","next","over","event","leave","focus","blur","keyboard","layout","mutations","records","record"],"sources":["../../src/utils/use-hover-highlight.ts"],"sourcesContent":["import { type Ref, useCallback } from \"react\";\nimport { assignRef } from \"./selection-indicator\";\n\nconst ROW = \"[data-basalt-hover-item]\";\nconst ACTIVE =\n\t'[data-highlighted], [data-hover-active=\"true\"], [aria-selected=\"true\"], [data-state=\"checked\"], [data-hover-selected=\"true\"], [data-selected=\"true\"]';\n\nexport function useHoverHighlight(\n\tref?: Ref<HTMLElement | null>,\n\t{ restoreOnPointerLeave = true }: { restoreOnPointerLeave?: boolean } = {},\n) {\n\treturn useCallback(\n\t\t(root: HTMLElement | null) => {\n\t\t\tassignRef(ref, root);\n\t\t\tif (!root) return;\n\t\t\tlet hovered: HTMLElement | null = null;\n\t\t\tlet pointerExited = false;\n\t\t\tlet sequenceBroken = false;\n\t\t\tlet focused: HTMLElement | null = null;\n\t\t\tlet previous: HTMLElement | null = null;\n\t\t\tlet selected: HTMLElement | null = null;\n\t\t\tlet active: HTMLElement | null = null;\n\t\t\tlet selectionDirty = true;\n\t\t\tlet frame = 0;\n\t\t\tlet geometry = \"\";\n\t\t\tlet layoutChanged = true;\n\t\t\tconst eligible = (node: HTMLElement | null) =>\n\t\t\t\tnode &&\n\t\t\t\troot.contains(node) &&\n\t\t\t\tnode.matches(ROW) &&\n\t\t\t\tnode.closest(\".basalt-hover-list\") === root &&\n\t\t\t\t!node.closest(\n\t\t\t\t\t'[hidden], [disabled], [aria-disabled=\"true\"], [data-disabled=\"\"], [data-disabled=\"true\"]',\n\t\t\t\t)\n\t\t\t\t\t? node\n\t\t\t\t\t: null;\n\t\t\tconst row = (target: EventTarget | null) =>\n\t\t\t\teligible(target instanceof Element ? target.closest<HTMLElement>(ROW) : null);\n\t\t\tconst resize = new ResizeObserver(() => {\n\t\t\t\tlayoutChanged = true;\n\t\t\t\tschedule();\n\t\t\t});\n\t\t\tconst update = () => {\n\t\t\t\tframe = 0;\n\t\t\t\tif (selectionDirty) {\n\t\t\t\t\tactive = null;\n\t\t\t\t\tselected = null;\n\t\t\t\t\tfor (const node of root.querySelectorAll<HTMLElement>(`${ROW}:is(${ACTIVE})`)) {\n\t\t\t\t\t\tif (!eligible(node)) continue;\n\t\t\t\t\t\tif (!selected) selected = node;\n\t\t\t\t\t\tif (node.matches('[data-highlighted], [data-hover-active=\"true\"]')) {\n\t\t\t\t\t\t\tactive = node;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tselectionDirty = false;\n\t\t\t\t}\n\t\t\t\tconst broken = sequenceBroken;\n\t\t\t\tsequenceBroken = false;\n\t\t\t\tif (broken) root.dataset.hoverAnimated = \"false\";\n\t\t\t\tconst item = pointerExited\n\t\t\t\t\t? null\n\t\t\t\t\t: restoreOnPointerLeave\n\t\t\t\t\t\t? (eligible(active) ?? eligible(hovered) ?? eligible(focused) ?? eligible(selected))\n\t\t\t\t\t\t: eligible(hovered);\n\t\t\t\tif (item === previous && !layoutChanged) return;\n\t\t\t\tif (item !== previous) {\n\t\t\t\t\tif (previous) resize.unobserve(previous);\n\t\t\t\t\tif (item) resize.observe(item);\n\t\t\t\t}\n\t\t\t\tconst width = item?.offsetWidth ?? 0;\n\t\t\t\tconst height = item?.offsetHeight ?? 0;\n\t\t\t\tif (!item || !width || !height) {\n\t\t\t\t\tif (!restoreOnPointerLeave) root.dataset.hoverAnimated = \"false\";\n\t\t\t\t\troot.dataset.hoverVisible = \"false\";\n\t\t\t\t\tprevious = null;\n\t\t\t\t\tgeometry = \"\";\n\t\t\t\t\tlayoutChanged = false;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet x = 0,\n\t\t\t\t\ty = 0;\n\t\t\t\tfor (\n\t\t\t\t\tlet node: HTMLElement | null = item;\n\t\t\t\t\tnode && node !== root;\n\t\t\t\t\tnode = node.offsetParent as HTMLElement | null\n\t\t\t\t) {\n\t\t\t\t\tx += node.offsetLeft;\n\t\t\t\t\ty += node.offsetTop;\n\t\t\t\t}\n\t\t\t\tfor (let node = item.parentElement; node && node !== root; node = node.parentElement) {\n\t\t\t\t\tx -= node.scrollLeft;\n\t\t\t\t\ty -= node.scrollTop;\n\t\t\t\t}\n\t\t\t\tconst next = `${x},${y},${width},${height}`;\n\t\t\t\tif (next !== geometry) {\n\t\t\t\t\troot.dataset.hoverAnimated =\n\t\t\t\t\t\tprevious && previous !== item && !layoutChanged && !broken ? \"true\" : \"false\";\n\t\t\t\t\troot.style.setProperty(\"--basalt-hover-x\", `${x}px`);\n\t\t\t\t\troot.style.setProperty(\"--basalt-hover-y\", `${y}px`);\n\t\t\t\t\troot.style.setProperty(\"--basalt-hover-width\", `${width}px`);\n\t\t\t\t\troot.style.setProperty(\"--basalt-hover-height\", `${height}px`);\n\t\t\t\t\tgeometry = next;\n\t\t\t\t}\n\t\t\t\troot.dataset.hoverVisible = \"true\";\n\t\t\t\tprevious = item;\n\t\t\t\tlayoutChanged = false;\n\t\t\t};\n\t\t\tfunction schedule() {\n\t\t\t\tif (!frame) frame = requestAnimationFrame(update);\n\t\t\t}\n\t\t\tconst over = (event: PointerEvent) => {\n\t\t\t\tif (event.pointerType === \"touch\") return;\n\t\t\t\tpointerExited = false;\n\t\t\t\tconst next = row(event.target);\n\t\t\t\tif (next !== hovered) {\n\t\t\t\t\tif (!restoreOnPointerLeave && (!next || !hovered)) sequenceBroken = true;\n\t\t\t\t\thovered = next;\n\t\t\t\t\tschedule();\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst leave = () => {\n\t\t\t\thovered = null;\n\t\t\t\tpointerExited = !restoreOnPointerLeave;\n\t\t\t\tif (!restoreOnPointerLeave) sequenceBroken = true;\n\t\t\t\tschedule();\n\t\t\t};\n\t\t\tconst focus = (event: FocusEvent) => {\n\t\t\t\tfocused = row(event.target);\n\t\t\t\tif (!restoreOnPointerLeave) return;\n\t\t\t\tpointerExited = false;\n\t\t\t\thovered = null;\n\t\t\t\tschedule();\n\t\t\t};\n\t\t\tconst blur = (event: FocusEvent) => {\n\t\t\t\tfocused = row(event.relatedTarget);\n\t\t\t\tif (!restoreOnPointerLeave) return;\n\t\t\t\tschedule();\n\t\t\t};\n\t\t\tconst keyboard = (event: KeyboardEvent) => {\n\t\t\t\tif (\n\t\t\t\t\t!(event.target instanceof Element) ||\n\t\t\t\t\t(!root.contains(event.target) &&\n\t\t\t\t\t\t(!root.id || event.target.getAttribute(\"aria-controls\") !== root.id))\n\t\t\t\t)\n\t\t\t\t\treturn;\n\t\t\t\tif (!restoreOnPointerLeave) return;\n\t\t\t\thovered = null;\n\t\t\t\tpointerExited = false;\n\t\t\t\tschedule();\n\t\t\t};\n\t\t\tconst layout = (event: Event) => {\n\t\t\t\t// Our pseudo-element transition cannot change row geometry.\n\t\t\t\tif (event.target === root && event.type !== \"scroll\") return;\n\t\t\t\tlayoutChanged = true;\n\t\t\t\tschedule();\n\t\t\t};\n\t\t\tconst mutations = new MutationObserver((records) => {\n\t\t\t\tselectionDirty = true;\n\t\t\t\tif (\n\t\t\t\t\trecords.some((record) => record.type === \"childList\" || record.attributeName === \"hidden\")\n\t\t\t\t)\n\t\t\t\t\tlayoutChanged = true;\n\t\t\t\tschedule();\n\t\t\t});\n\t\t\tmutations.observe(root, {\n\t\t\t\tsubtree: true,\n\t\t\t\tchildList: true,\n\t\t\t\tattributes: true,\n\t\t\t\tattributeFilter: [\n\t\t\t\t\t\"data-basalt-hover-item\",\n\t\t\t\t\t\"data-highlighted\",\n\t\t\t\t\t\"data-state\",\n\t\t\t\t\t\"aria-selected\",\n\t\t\t\t\t\"data-selected\",\n\t\t\t\t\t\"data-hover-active\",\n\t\t\t\t\t\"data-hover-selected\",\n\t\t\t\t\t\"disabled\",\n\t\t\t\t\t\"aria-disabled\",\n\t\t\t\t\t\"data-disabled\",\n\t\t\t\t\t\"hidden\",\n\t\t\t\t],\n\t\t\t});\n\t\t\tresize.observe(root);\n\t\t\troot.addEventListener(\"pointerover\", over);\n\t\t\troot.addEventListener(\"pointerleave\", leave);\n\t\t\troot.addEventListener(\"focusin\", focus);\n\t\t\troot.addEventListener(\"focusout\", blur);\n\t\t\troot.ownerDocument.addEventListener(\"keydown\", keyboard);\n\t\t\troot.addEventListener(\"scroll\", layout, true);\n\t\t\troot.addEventListener(\"animationend\", layout);\n\t\t\troot.addEventListener(\"transitionend\", layout);\n\t\t\tschedule();\n\t\t\treturn () => {\n\t\t\t\tcancelAnimationFrame(frame);\n\t\t\t\tresize.disconnect();\n\t\t\t\tmutations.disconnect();\n\t\t\t\troot.removeEventListener(\"pointerover\", over);\n\t\t\t\troot.removeEventListener(\"pointerleave\", leave);\n\t\t\t\troot.removeEventListener(\"focusin\", focus);\n\t\t\t\troot.removeEventListener(\"focusout\", blur);\n\t\t\t\troot.ownerDocument.removeEventListener(\"keydown\", keyboard);\n\t\t\t\troot.removeEventListener(\"scroll\", layout, true);\n\t\t\t\troot.removeEventListener(\"animationend\", layout);\n\t\t\t\troot.removeEventListener(\"transitionend\", layout);\n\t\t\t\tassignRef(ref, null);\n\t\t\t};\n\t\t},\n\t\t[ref, restoreOnPointerLeave],\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ApprovalAnswers, type ApprovalQuestion } from "../models/agent-feedback.js";
|
|
2
|
+
export declare function useApprovalCardViewModel({ questions, onSubmit, autoAdvance, }: {
|
|
3
|
+
questions: readonly ApprovalQuestion[];
|
|
4
|
+
onSubmit: (answers: ApprovalAnswers) => void | Promise<void>;
|
|
5
|
+
autoAdvance?: boolean;
|
|
6
|
+
}): {
|
|
7
|
+
position: number;
|
|
8
|
+
focusToken: number;
|
|
9
|
+
question: ApprovalQuestion;
|
|
10
|
+
answer: import("../models/agent-feedback.js").ApprovalAnswer | undefined;
|
|
11
|
+
status: "editing" | "submitted" | "submitting";
|
|
12
|
+
error: string;
|
|
13
|
+
canContinue: boolean;
|
|
14
|
+
last: boolean;
|
|
15
|
+
choose: (id: string) => void;
|
|
16
|
+
move: (next: number) => void;
|
|
17
|
+
setCustom(value: string): void;
|
|
18
|
+
continue(): void;
|
|
19
|
+
skip(): void;
|
|
20
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { approvalSnapshot as e, validApprovalAnswer as t } from "../models/agent-feedback.js";
|
|
3
|
+
import { useEffect as n, useRef as r, useState as i } from "react";
|
|
4
|
+
//#region src/viewmodels/use-approval-card.ts
|
|
5
|
+
function a({ questions: a, onSubmit: o, autoAdvance: s = !0 }) {
|
|
6
|
+
let [c, l] = i(0), [u, d] = i(0), [f, p] = i({}), [m, h] = i("editing"), [g, _] = i(""), v = r(!1), y = r(!0), b = r(void 0), x = () => {
|
|
7
|
+
clearTimeout(b.current), b.current = void 0;
|
|
8
|
+
};
|
|
9
|
+
n(() => (y.current = !0, () => {
|
|
10
|
+
y.current = !1, clearTimeout(b.current);
|
|
11
|
+
}), []);
|
|
12
|
+
let S = Math.min(c, Math.max(0, a.length - 1)), C = a[S], w = C ? f[C.id] : void 0, T = S === a.length - 1, E = !!(C && t(C, w)), D = (e) => {
|
|
13
|
+
l(e), d((e) => e + 1);
|
|
14
|
+
}, O = (e) => {
|
|
15
|
+
v.current || a.length === 0 || (x(), D(Math.min(Math.max(0, e), a.length - 1)), _(""));
|
|
16
|
+
}, k = (e) => {
|
|
17
|
+
if (!C || v.current || !C.options.some((t) => t.id === e && !t.disabled)) return;
|
|
18
|
+
x();
|
|
19
|
+
let t = w?.selected ?? [];
|
|
20
|
+
p({
|
|
21
|
+
...f,
|
|
22
|
+
[C.id]: {
|
|
23
|
+
...w,
|
|
24
|
+
skipped: !1,
|
|
25
|
+
selected: C.type === "single" ? [e] : t.includes(e) ? t.filter((t) => t !== e) : [...t, e]
|
|
26
|
+
}
|
|
27
|
+
}), _(""), C.type === "single" && s && !T && (b.current = setTimeout(() => D(S + 1), 240));
|
|
28
|
+
}, A = async (n) => {
|
|
29
|
+
if (v.current || a.length === 0) return;
|
|
30
|
+
let r = a.findIndex((e) => !t(e, n[e.id]));
|
|
31
|
+
if (r >= 0) {
|
|
32
|
+
D(r);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
v.current = !0, h("submitting"), _(""), x();
|
|
36
|
+
try {
|
|
37
|
+
await o(e(a, n)), y.current && h("submitted");
|
|
38
|
+
} catch (e) {
|
|
39
|
+
y.current && (_(e instanceof Error ? e.message : "Could not submit answers. Try again."), h("editing"));
|
|
40
|
+
} finally {
|
|
41
|
+
v.current = !1;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
position: S,
|
|
46
|
+
focusToken: u,
|
|
47
|
+
question: C,
|
|
48
|
+
answer: w,
|
|
49
|
+
status: m,
|
|
50
|
+
error: g,
|
|
51
|
+
canContinue: E,
|
|
52
|
+
last: T,
|
|
53
|
+
choose: k,
|
|
54
|
+
move: O,
|
|
55
|
+
setCustom(e) {
|
|
56
|
+
C?.allowCustom && !v.current && (x(), p({
|
|
57
|
+
...f,
|
|
58
|
+
[C.id]: {
|
|
59
|
+
selected: w?.selected ?? [],
|
|
60
|
+
custom: e
|
|
61
|
+
}
|
|
62
|
+
}));
|
|
63
|
+
},
|
|
64
|
+
continue() {
|
|
65
|
+
E && !v.current && (T ? A(f) : O(S + 1));
|
|
66
|
+
},
|
|
67
|
+
skip() {
|
|
68
|
+
if (C?.required !== !1 || v.current) return;
|
|
69
|
+
let e = {
|
|
70
|
+
...f,
|
|
71
|
+
[C.id]: {
|
|
72
|
+
selected: [],
|
|
73
|
+
skipped: !0
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
p(e), T ? A(e) : O(S + 1);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { a as useApprovalCardViewModel };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=use-approval-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-approval-card.js","names":["useApprovalCardViewModel","index","setIndex","useState","focusToken","setFocusToken","answers","setAnswers","status","setStatus","error","setError","locked","useRef","mounted","advanceTimer","cancelAdvance","position","questions","question","answer","last","canContinue","validApprovalAnswer","show","next","token","move","choose","option","id","selected","value","autoAdvance","submit","missing","item","nextAnswers","onSubmit","approvalSnapshot","reason"],"sources":["../../src/viewmodels/use-approval-card.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n\ttype ApprovalAnswers,\n\ttype ApprovalQuestion,\n\tapprovalSnapshot,\n\tvalidApprovalAnswer,\n} from \"../models/agent-feedback\";\n\nexport function useApprovalCardViewModel({\n\tquestions,\n\tonSubmit,\n\tautoAdvance = true,\n}: {\n\tquestions: readonly ApprovalQuestion[];\n\tonSubmit: (answers: ApprovalAnswers) => void | Promise<void>;\n\tautoAdvance?: boolean;\n}) {\n\tconst [index, setIndex] = useState(0);\n\tconst [focusToken, setFocusToken] = useState(0);\n\tconst [answers, setAnswers] = useState<ApprovalAnswers>({});\n\tconst [status, setStatus] = useState<\"editing\" | \"submitting\" | \"submitted\">(\"editing\");\n\tconst [error, setError] = useState(\"\");\n\tconst locked = useRef(false);\n\tconst mounted = useRef(true);\n\tconst advanceTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\tconst cancelAdvance = () => {\n\t\tclearTimeout(advanceTimer.current);\n\t\tadvanceTimer.current = undefined;\n\t};\n\tuseEffect(() => {\n\t\tmounted.current = true;\n\t\treturn () => {\n\t\t\tmounted.current = false;\n\t\t\tclearTimeout(advanceTimer.current);\n\t\t};\n\t}, []);\n\tconst position = Math.min(index, Math.max(0, questions.length - 1));\n\tconst question = questions[position];\n\tconst answer = question ? answers[question.id] : undefined;\n\tconst last = position === questions.length - 1;\n\tconst canContinue = Boolean(question && validApprovalAnswer(question, answer));\n\t/** Every programmatic question change asks the view to keep focus inside the card. */\n\tconst show = (next: number) => {\n\t\tsetIndex(next);\n\t\tsetFocusToken((token) => token + 1);\n\t};\n\tconst move = (next: number) => {\n\t\tif (locked.current || questions.length === 0) return;\n\t\tcancelAdvance();\n\t\tshow(Math.min(Math.max(0, next), questions.length - 1));\n\t\tsetError(\"\");\n\t};\n\tconst choose = (id: string) => {\n\t\tif (\n\t\t\t!question ||\n\t\t\tlocked.current ||\n\t\t\t!question.options.some((option) => option.id === id && !option.disabled)\n\t\t)\n\t\t\treturn;\n\t\tcancelAdvance();\n\t\tconst selected = answer?.selected ?? [];\n\t\tsetAnswers({\n\t\t\t...answers,\n\t\t\t[question.id]: {\n\t\t\t\t...answer,\n\t\t\t\tskipped: false,\n\t\t\t\tselected:\n\t\t\t\t\tquestion.type === \"single\"\n\t\t\t\t\t\t? [id]\n\t\t\t\t\t\t: selected.includes(id)\n\t\t\t\t\t\t\t? selected.filter((value) => value !== id)\n\t\t\t\t\t\t\t: [...selected, id],\n\t\t\t},\n\t\t});\n\t\tsetError(\"\");\n\t\tif (question.type === \"single\" && autoAdvance && !last)\n\t\t\tadvanceTimer.current = setTimeout(() => show(position + 1), 240);\n\t};\n\tconst submit = async (nextAnswers: ApprovalAnswers) => {\n\t\tif (locked.current || questions.length === 0) return;\n\t\tconst missing = questions.findIndex((item) => !validApprovalAnswer(item, nextAnswers[item.id]));\n\t\tif (missing >= 0) {\n\t\t\tshow(missing);\n\t\t\treturn;\n\t\t}\n\t\tlocked.current = true;\n\t\tsetStatus(\"submitting\");\n\t\tsetError(\"\");\n\t\tcancelAdvance();\n\t\ttry {\n\t\t\tawait onSubmit(approvalSnapshot(questions, nextAnswers));\n\t\t\tif (mounted.current) setStatus(\"submitted\");\n\t\t} catch (reason) {\n\t\t\tif (mounted.current) {\n\t\t\t\tsetError(reason instanceof Error ? reason.message : \"Could not submit answers. Try again.\");\n\t\t\t\tsetStatus(\"editing\");\n\t\t\t}\n\t\t} finally {\n\t\t\tlocked.current = false;\n\t\t}\n\t};\n\treturn {\n\t\tposition,\n\t\tfocusToken,\n\t\tquestion,\n\t\tanswer,\n\t\tstatus,\n\t\terror,\n\t\tcanContinue,\n\t\tlast,\n\t\tchoose,\n\t\tmove,\n\t\tsetCustom(value: string) {\n\t\t\tif (!question?.allowCustom || locked.current) return;\n\t\t\tcancelAdvance();\n\t\t\tsetAnswers({\n\t\t\t\t...answers,\n\t\t\t\t[question.id]: { selected: answer?.selected ?? [], custom: value },\n\t\t\t});\n\t\t},\n\t\tcontinue() {\n\t\t\tif (!canContinue || locked.current) return;\n\t\t\tif (last) void submit(answers);\n\t\t\telse move(position + 1);\n\t\t},\n\t\tskip() {\n\t\t\tif (question?.required !== false || locked.current) return;\n\t\t\tconst next = { ...answers, [question.id]: { selected: [], skipped: true } };\n\t\t\tsetAnswers(next);\n\t\t\tif (last) void submit(next);\n\t\t\telse move(position + 1);\n\t\t},\n\t};\n}\n"],"mappings":";;;;AAQA,SAAgBA,EAAyB,EACxC,cACA,aACA,iBAAc,MAKZ;CACF,IAAM,CAACC,GAAOC,KAAYC,EAAS,CAAC,GAC9B,CAACC,GAAYC,KAAiBF,EAAS,CAAC,GACxC,CAACG,GAASC,KAAcJ,EAA0B,CAAC,CAAC,GACpD,CAACK,GAAQC,KAAaN,EAAiD,SAAS,GAChF,CAACO,GAAOC,KAAYR,EAAS,EAAE,GAC/BS,IAASC,EAAO,EAAK,GACrBC,IAAUD,EAAO,EAAI,GACrBE,IAAeF,EAAkD,KAAA,CAAS,GAC1EG,UAAsB;EAE3B,AADA,aAAaD,EAAa,OAAO,GACjC,EAAa,UAAU,KAAA;CACxB;CACA,SACC,EAAQ,UAAU,UACL;EAEZ,AADA,EAAQ,UAAU,IAClB,aAAaA,EAAa,OAAO;CAClC,IACE,CAAC,CAAC;CACL,IAAME,IAAW,KAAK,IAAIhB,GAAO,KAAK,IAAI,GAAGiB,EAAU,SAAS,CAAC,CAAC,GAC5DC,IAAWD,EAAUD,IACrBG,IAASD,IAAWb,EAAQa,EAAS,MAAM,KAAA,GAC3CE,IAAOJ,MAAaC,EAAU,SAAS,GACvCI,IAAc,GAAQH,KAAYI,EAAoBJ,GAAUC,CAAM,IAEtEI,KAAQ,MAAiB;EAE9B,AADAtB,EAASuB,CAAI,GACbpB,GAAe,MAAUqB,IAAQ,CAAC;CACnC,GACMC,KAAQ,MAAiB;EAC9B,AAAIf,EAAO,WAAWM,EAAU,WAAW,MAC3CF,EAAc,GACdQ,EAAK,KAAK,IAAI,KAAK,IAAI,GAAGC,CAAI,GAAGP,EAAU,SAAS,CAAC,CAAC,GACtDP,EAAS,EAAE;CACZ,GACMiB,KAAU,MAAe;EAC9B,IACC,CAACT,KACDP,EAAO,WACP,CAACO,EAAS,QAAQ,MAAM,MAAWU,EAAO,OAAOC,KAAM,CAACD,EAAO,QAAQ,GAEvE;EACD,EAAc;EACd,IAAME,IAAWX,GAAQ,YAAY,CAAC;EAetC,AAdAb,EAAW;GACV,GAAGD;IACFa,EAAS,KAAK;IACd,GAAGC;IACH,SAAS;IACT,UACCD,EAAS,SAAS,WACf,CAACW,CAAE,IACHC,EAAS,SAASD,CAAE,IACnBC,EAAS,QAAQ,MAAUC,MAAUF,CAAE,IACvC,CAAC,GAAGC,GAAUD,CAAE;GACtB;EACD,CAAC,GACDnB,EAAS,EAAE,GACPQ,EAAS,SAAS,YAAYc,KAAe,CAACZ,MACjD,EAAa,UAAU,iBAAiBG,EAAKP,IAAW,CAAC,GAAG,GAAG;CACjE,GACMiB,IAAS,OAAO,MAAiC;EACtD,IAAItB,EAAO,WAAWM,EAAU,WAAW,GAAG;EAC9C,IAAMiB,IAAUjB,EAAU,WAAW,MAAS,CAACK,EAAoBa,GAAMC,EAAYD,EAAK,GAAG,CAAC;EAC9F,IAAID,KAAW,GAAG;GACjB,EAAKA,CAAO;GACZ;EACD;EAIA,AAHA,EAAO,UAAU,IACjB1B,EAAU,YAAY,GACtBE,EAAS,EAAE,GACXK,EAAc;EACd,IAAI;GAEH,AADA,MAAMsB,EAASC,EAAiBrB,GAAWmB,CAAW,CAAC,GACnDvB,EAAQ,WAASL,EAAU,WAAW;EAC3C,SAAS+B,GAAQ;GAChB,AAAI1B,EAAQ,YACXH,EAAS6B,aAAkB,QAAQA,EAAO,UAAU,sCAAsC,GAC1F/B,EAAU,SAAS;EAErB,UAAU;GACT,EAAO,UAAU;EAClB;CACD;CACA,OAAO;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU,GAAe;GACxB,AAAKU,GAAU,eAAe,GAAO,YACrCH,EAAc,GACdT,EAAW;IACV,GAAGD;KACFa,EAAS,KAAK;KAAE,UAAUC,GAAQ,YAAY,CAAC;KAAG,QAAQY;IAAM;GAClE,CAAC;EACF;EACA,WAAW;GACV,AAAKV,KAAe,GAAO,YACvBD,IAAMa,EAAY5B,CAAO,IACxBqB,EAAKV,IAAW,CAAC;EACvB;EACA,OAAO;GACN,IAAIE,GAAU,aAAa,MAASP,EAAO,SAAS;GACpD,IAAMa,IAAO;IAAE,GAAGnB;KAAUa,EAAS,KAAK;KAAE,UAAU,CAAC;KAAG,SAAS;IAAK;GAAE;GAE1E,AADAZ,EAAWkB,CAAI,GACXJ,IAAMa,EAAYT,CAAI,IACrBE,EAAKV,IAAW,CAAC;EACvB;CACD;AACD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function useChatComposer({ value, defaultValue, onValueChange, onSend, disabled, streaming, hasAttachments, }: {
|
|
2
|
+
value?: string;
|
|
3
|
+
defaultValue?: string;
|
|
4
|
+
onValueChange?: (value: string) => void;
|
|
5
|
+
onSend: (text: string) => void | Promise<void>;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
streaming: boolean;
|
|
8
|
+
hasAttachments: boolean;
|
|
9
|
+
}): {
|
|
10
|
+
value: string;
|
|
11
|
+
update: (next: string) => void;
|
|
12
|
+
pending: boolean;
|
|
13
|
+
error: string;
|
|
14
|
+
canSend: boolean;
|
|
15
|
+
send(): Promise<boolean>;
|
|
16
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect as e, useRef as t, useState as n } from "react";
|
|
3
|
+
//#region src/viewmodels/use-chat-composer.ts
|
|
4
|
+
function r({ value: r, defaultValue: i = "", onValueChange: a, onSend: o, disabled: s, streaming: c, hasAttachments: l }) {
|
|
5
|
+
let [u, d] = n(i), [f, p] = n(!1), [m, h] = n(""), g = t(!1), _ = t(!0);
|
|
6
|
+
e(() => (_.current = !0, () => {
|
|
7
|
+
_.current = !1;
|
|
8
|
+
}), []);
|
|
9
|
+
let v = r ?? u;
|
|
10
|
+
return {
|
|
11
|
+
value: v,
|
|
12
|
+
update: (e) => {
|
|
13
|
+
g.current || s || (r === void 0 && d(e), a?.(e), h(""));
|
|
14
|
+
},
|
|
15
|
+
pending: f,
|
|
16
|
+
error: m,
|
|
17
|
+
canSend: !s && !c && !f && (!!v.trim() || l),
|
|
18
|
+
async send() {
|
|
19
|
+
if (g.current || s || c || !v.trim() && !l) return !1;
|
|
20
|
+
g.current = !0, p(!0), h("");
|
|
21
|
+
try {
|
|
22
|
+
return await o(v.trim()), _.current && (r === void 0 && d(""), a?.("")), !0;
|
|
23
|
+
} catch (e) {
|
|
24
|
+
return _.current && h(e instanceof Error ? e.message : "Could not send message. Try again."), !1;
|
|
25
|
+
} finally {
|
|
26
|
+
g.current = !1, _.current && p(!1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { r as useChatComposer };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=use-chat-composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-chat-composer.js","names":["useChatComposer","draft","setDraft","useState","defaultValue","pending","setPending","error","setError","locked","useRef","mounted","text","value","disabled","next","onValueChange","streaming","hasAttachments","onSend","reason"],"sources":["../../src/viewmodels/use-chat-composer.ts"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\n\nexport function useChatComposer({\n\tvalue,\n\tdefaultValue = \"\",\n\tonValueChange,\n\tonSend,\n\tdisabled,\n\tstreaming,\n\thasAttachments,\n}: {\n\tvalue?: string;\n\tdefaultValue?: string;\n\tonValueChange?: (value: string) => void;\n\tonSend: (text: string) => void | Promise<void>;\n\tdisabled: boolean;\n\tstreaming: boolean;\n\thasAttachments: boolean;\n}) {\n\tconst [draft, setDraft] = useState(defaultValue);\n\tconst [pending, setPending] = useState(false);\n\tconst [error, setError] = useState(\"\");\n\tconst locked = useRef(false);\n\tconst mounted = useRef(true);\n\tuseEffect(() => {\n\t\tmounted.current = true;\n\t\treturn () => {\n\t\t\tmounted.current = false;\n\t\t};\n\t}, []);\n\tconst text = value ?? draft;\n\tconst update = (next: string) => {\n\t\tif (locked.current || disabled) return;\n\t\tif (value === undefined) setDraft(next);\n\t\tonValueChange?.(next);\n\t\tsetError(\"\");\n\t};\n\treturn {\n\t\tvalue: text,\n\t\tupdate,\n\t\tpending,\n\t\terror,\n\t\tcanSend: !disabled && !streaming && !pending && (Boolean(text.trim()) || hasAttachments),\n\t\tasync send() {\n\t\t\tif (locked.current || disabled || streaming || (!text.trim() && !hasAttachments))\n\t\t\t\treturn false;\n\t\t\tlocked.current = true;\n\t\t\tsetPending(true);\n\t\t\tsetError(\"\");\n\t\t\ttry {\n\t\t\t\tawait onSend(text.trim());\n\t\t\t\tif (mounted.current) {\n\t\t\t\t\tif (value === undefined) setDraft(\"\");\n\t\t\t\t\tonValueChange?.(\"\");\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t} catch (reason) {\n\t\t\t\tif (mounted.current)\n\t\t\t\t\tsetError(reason instanceof Error ? reason.message : \"Could not send message. Try again.\");\n\t\t\t\treturn false;\n\t\t\t} finally {\n\t\t\t\tlocked.current = false;\n\t\t\t\tif (mounted.current) setPending(false);\n\t\t\t}\n\t\t},\n\t};\n}\n"],"mappings":";;;AAEA,SAAgBA,EAAgB,EAC/B,UACA,kBAAe,IACf,kBACA,WACA,aACA,cACA,qBASE;CACF,IAAM,CAACC,GAAOC,KAAYC,EAASC,CAAY,GACzC,CAACC,GAASC,KAAcH,EAAS,EAAK,GACtC,CAACI,GAAOC,KAAYL,EAAS,EAAE,GAC/BM,IAASC,EAAO,EAAK,GACrBC,IAAUD,EAAO,EAAI;CAC3B,SACC,EAAQ,UAAU,UACL;EACZ,EAAQ,UAAU;CACnB,IACE,CAAC,CAAC;CACL,IAAME,IAAOC,KAASZ;CAOtB,OAAO;EACN,OAAOW;EACP,SARe,MAAiB;GAChC,AAAIH,EAAO,WAAWK,MAClBD,MAAU,KAAA,KAAWX,EAASa,CAAI,GACtCC,IAAgBD,CAAI,GACpBP,EAAS,EAAE;EACZ;EAIC;EACA;EACA,SAAS,CAACM,KAAY,CAACG,KAAa,CAACZ,MAAY,EAAQO,EAAK,KAAK,KAAMM;EACzE,MAAM,OAAO;GACZ,IAAIT,EAAO,WAAWK,KAAYG,KAAc,CAACL,EAAK,KAAK,KAAK,CAACM,GAChE,OAAO;GAGR,AAFA,EAAO,UAAU,IACjBZ,EAAW,EAAI,GACfE,EAAS,EAAE;GACX,IAAI;IAMH,OALA,MAAMW,EAAOP,EAAK,KAAK,CAAC,GACpBD,EAAQ,YACPE,MAAU,KAAA,KAAWX,EAAS,EAAE,GACpCc,IAAgB,EAAE,IAEZ;GACR,SAASI,GAAQ;IAGhB,OAFIT,EAAQ,WACXH,EAASY,aAAkB,QAAQA,EAAO,UAAU,oCAAoC,GAClF;GACR,UAAU;IAET,AADA,EAAO,UAAU,IACbT,EAAQ,WAASL,EAAW,EAAK;GACtC;EACD;CACD;AACD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function useChatMessage(content: string, sources: readonly {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
type?: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
}[]): {
|
|
7
|
+
copied: boolean;
|
|
8
|
+
copyError: boolean;
|
|
9
|
+
sources: {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
type?: string;
|
|
13
|
+
href: string | undefined;
|
|
14
|
+
}[];
|
|
15
|
+
copy(write: (text: string) => Promise<void>): Promise<void>;
|
|
16
|
+
};
|