@tulipfarm/sprout 0.3.0 → 0.4.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 +45 -40
- package/dist/components/accordion.d.ts +2 -2
- package/dist/components/accordion.js +9 -9
- package/dist/components/agent-fanout.d.ts +2 -2
- package/dist/components/agent-fanout.js +65 -87
- package/dist/components/alert-dialog.d.ts +6 -6
- package/dist/components/alert-dialog.js +20 -20
- package/dist/components/alert.d.ts +6 -6
- package/dist/components/alert.js +13 -13
- package/dist/components/aspect-ratio.d.ts +2 -2
- package/dist/components/aspect-ratio.js +2 -2
- package/dist/components/attachment.d.ts +17 -17
- package/dist/components/attachment.js +82 -115
- package/dist/components/avatar.d.ts +10 -10
- package/dist/components/avatar.js +14 -14
- package/dist/components/badge.d.ts +4 -4
- package/dist/components/badge.js +18 -18
- package/dist/components/board.d.ts +107 -0
- package/dist/components/board.js +640 -0
- package/dist/components/brand-icon.d.ts +6 -6
- package/dist/components/brand-icon.js +55 -63
- package/dist/components/breadcrumb.d.ts +11 -11
- package/dist/components/breadcrumb.js +16 -18
- package/dist/components/button-group.d.ts +6 -6
- package/dist/components/button-group.js +14 -14
- package/dist/components/button.d.ts +11 -11
- package/dist/components/button.js +46 -56
- package/dist/components/calendar.d.ts +5 -5
- package/dist/components/calendar.js +44 -53
- package/dist/components/canvas.d.ts +4 -4
- package/dist/components/canvas.js +39 -46
- package/dist/components/card.d.ts +6 -6
- package/dist/components/card.js +17 -17
- package/dist/components/carousel.d.ts +7 -7
- package/dist/components/carousel.js +57 -75
- package/dist/components/chart.d.ts +5 -112
- package/dist/components/chart.js +5 -172
- package/dist/components/chat-confirmation.d.ts +13 -11
- package/dist/components/chat-confirmation.js +32 -38
- package/dist/components/chat-input.d.ts +4 -4
- package/dist/components/chat-input.js +74 -81
- package/dist/components/chat-plan.d.ts +2 -2
- package/dist/components/chat-plan.js +15 -20
- package/dist/components/chat-sources.d.ts +8 -8
- package/dist/components/chat-sources.js +18 -27
- package/dist/components/checkbox.d.ts +1 -1
- package/dist/components/checkbox.js +9 -9
- package/dist/components/choice-list.d.ts +2 -2
- package/dist/components/choice-list.js +16 -18
- package/dist/components/code-block.d.ts +5 -5
- package/dist/components/code-block.js +26 -26
- package/dist/components/collapsible.d.ts +1 -1
- package/dist/components/collapsible.js +7 -11
- package/dist/components/combobox.d.ts +3 -3
- package/dist/components/combobox.js +24 -24
- package/dist/components/command.d.ts +13 -13
- package/dist/components/command.js +61 -73
- package/dist/components/context-menu.d.ts +5 -5
- package/dist/components/context-menu.js +22 -22
- package/dist/components/dialog.d.ts +6 -6
- package/dist/components/dialog.js +23 -28
- package/dist/components/direction.d.ts +1 -1
- package/dist/components/direction.js +1 -1
- package/dist/components/dropdown-menu.d.ts +5 -5
- package/dist/components/dropdown-menu.js +20 -20
- package/dist/components/field.d.ts +11 -11
- package/dist/components/field.js +41 -61
- package/dist/components/file-explorer.d.ts +2 -2
- package/dist/components/file-explorer.js +89 -105
- package/dist/components/file-viewer.d.ts +10 -10
- package/dist/components/file-viewer.js +112 -140
- package/dist/components/form.d.ts +7 -7
- package/dist/components/form.js +24 -28
- package/dist/components/glass-banner.d.ts +3 -3
- package/dist/components/glass-banner.js +21 -24
- package/dist/components/gradient-banner.d.ts +5 -5
- package/dist/components/gradient-banner.js +13 -22
- package/dist/components/hover-card.d.ts +4 -4
- package/dist/components/hover-card.js +6 -6
- package/dist/components/input-group.d.ts +11 -11
- package/dist/components/input-group.js +22 -36
- package/dist/components/input-otp.d.ts +10 -10
- package/dist/components/input-otp.js +13 -15
- package/dist/components/input.d.ts +1 -1
- package/dist/components/input.js +7 -7
- package/dist/components/kbd.d.ts +3 -3
- package/dist/components/kbd.js +5 -5
- package/dist/components/label.d.ts +2 -2
- package/dist/components/label.js +2 -2
- package/dist/components/mention-list.d.ts +3 -3
- package/dist/components/mention-list.js +10 -10
- package/dist/components/menubar.d.ts +6 -6
- package/dist/components/menubar.js +22 -22
- package/dist/components/message-actions.d.ts +2 -2
- package/dist/components/message-actions.js +29 -31
- package/dist/components/message-response.d.ts +3 -3
- package/dist/components/message-response.js +18 -18
- package/dist/components/message-scroller.d.ts +12 -12
- package/dist/components/message-scroller.js +44 -56
- package/dist/components/message.d.ts +11 -11
- package/dist/components/message.js +25 -25
- package/dist/components/navigation-menu.d.ts +2 -2
- package/dist/components/navigation-menu.js +15 -15
- package/dist/components/notice-banner.d.ts +2 -2
- package/dist/components/notice-banner.js +2 -2
- package/dist/components/page-content.d.ts +2 -2
- package/dist/components/page-content.js +2 -2
- package/dist/components/page-header.d.ts +1 -1
- package/dist/components/page-header.js +16 -16
- package/dist/components/pagination.d.ts +9 -9
- package/dist/components/pagination.js +17 -17
- package/dist/components/plan-outline.d.ts +2 -2
- package/dist/components/plan-outline.js +43 -60
- package/dist/components/popover.d.ts +6 -6
- package/dist/components/popover.js +15 -15
- package/dist/components/presence-cursor.d.ts +2 -2
- package/dist/components/presence-cursor.js +3 -3
- package/dist/components/progress.d.ts +1 -1
- package/dist/components/progress.js +8 -8
- package/dist/components/prompt-list.d.ts +3 -3
- package/dist/components/prompt-list.js +6 -6
- package/dist/components/questionnaire.d.ts +19 -19
- package/dist/components/questionnaire.js +183 -242
- package/dist/components/radio-group.d.ts +2 -2
- package/dist/components/radio-group.js +6 -6
- package/dist/components/reasoning-effort.d.ts +3 -3
- package/dist/components/reasoning-effort.js +9 -12
- package/dist/components/record-list.d.ts +66 -0
- package/dist/components/record-list.js +151 -0
- package/dist/components/resizable.d.ts +5 -5
- package/dist/components/resizable.js +76 -102
- package/dist/components/result-card.d.ts +10 -5
- package/dist/components/result-card.js +42 -53
- package/dist/components/result-notice.d.ts +18 -0
- package/dist/components/result-notice.js +29 -0
- package/dist/components/review-card.d.ts +6 -6
- package/dist/components/review-card.js +18 -18
- package/dist/components/rich-text-editor.d.ts +2 -2
- package/dist/components/rich-text-editor.js +56 -72
- package/dist/components/schema-diagram.d.ts +3 -3
- package/dist/components/schema-diagram.js +39 -53
- package/dist/components/scroll-area.d.ts +1 -1
- package/dist/components/scroll-area.js +10 -14
- package/dist/components/search-dialog.d.ts +6 -6
- package/dist/components/search-dialog.js +16 -16
- package/dist/components/search-field.d.ts +1 -1
- package/dist/components/search-field.js +11 -11
- package/dist/components/select.d.ts +3 -3
- package/dist/components/select.js +20 -20
- package/dist/components/selection-slot.d.ts +2 -2
- package/dist/components/selection-slot.js +6 -9
- package/dist/components/separator.d.ts +15 -15
- package/dist/components/separator.js +22 -27
- package/dist/components/settings-list.d.ts +3 -3
- package/dist/components/settings-list.js +5 -5
- package/dist/components/sheet.d.ts +6 -6
- package/dist/components/sheet.js +27 -27
- package/dist/components/sidebar.d.ts +22 -22
- package/dist/components/sidebar.js +57 -58
- package/dist/components/skeleton.d.ts +5 -5
- package/dist/components/skeleton.js +14 -21
- package/dist/components/slider.d.ts +2 -2
- package/dist/components/slider.js +6 -6
- package/dist/components/spinner.d.ts +5 -5
- package/dist/components/spinner.js +22 -26
- package/dist/components/sql-viewer.d.ts +14 -14
- package/dist/components/sql-viewer.js +99 -128
- package/dist/components/state-panel-samples.d.ts +2 -2
- package/dist/components/state-panel-samples.js +209 -245
- package/dist/components/state-panel.d.ts +2 -35
- package/dist/components/state-panel.js +2 -29
- package/dist/components/state-sample.d.ts +7 -7
- package/dist/components/state-sample.js +18 -31
- package/dist/components/switch.d.ts +1 -1
- package/dist/components/switch.js +7 -7
- package/dist/components/table-nuqs.d.ts +2 -2
- package/dist/components/table-nuqs.js +11 -12
- package/dist/components/table.d.ts +4 -4
- package/dist/components/table.js +166 -235
- package/dist/components/tabs.d.ts +2 -2
- package/dist/components/tabs.js +12 -12
- package/dist/components/textarea.d.ts +2 -2
- package/dist/components/textarea.js +6 -8
- package/dist/components/timeline.d.ts +3 -0
- package/dist/components/timeline.js +3 -0
- package/dist/components/toast.d.ts +2 -2
- package/dist/components/toast.js +19 -25
- package/dist/components/toggle-group.d.ts +2 -2
- package/dist/components/toggle-group.js +18 -20
- package/dist/components/toggle.d.ts +2 -2
- package/dist/components/toggle.js +8 -8
- package/dist/components/tool-activity.d.ts +1 -1
- package/dist/components/tool-activity.js +83 -110
- package/dist/components/toolbar-status.d.ts +2 -2
- package/dist/components/toolbar-status.js +7 -7
- package/dist/components/tooltip.d.ts +5 -5
- package/dist/components/tooltip.js +12 -11
- package/dist/components/typed-text.d.ts +2 -2
- package/dist/components/typed-text.js +10 -12
- package/dist/components/view-switcher.d.ts +51 -0
- package/dist/components/view-switcher.js +114 -0
- package/dist/index.d.ts +98 -93
- package/dist/index.js +98 -93
- package/dist/internal/chart-kit.d.ts +142 -0
- package/dist/internal/chart-kit.js +200 -0
- package/dist/internal/charts/bars.d.ts +61 -0
- package/dist/internal/charts/bars.js +86 -0
- package/dist/internal/charts/lines.d.ts +67 -0
- package/dist/internal/charts/lines.js +70 -0
- package/dist/internal/charts/more.d.ts +77 -0
- package/dist/internal/charts/more.js +68 -0
- package/dist/internal/charts/parts.d.ts +54 -0
- package/dist/internal/charts/parts.js +82 -0
- package/dist/internal/charts/timeline-dates.d.ts +38 -0
- package/dist/internal/charts/timeline-dates.js +113 -0
- package/dist/internal/charts/timeline-window.d.ts +31 -0
- package/dist/internal/charts/timeline-window.js +26 -0
- package/dist/internal/charts/timeline.d.ts +72 -0
- package/dist/internal/charts/timeline.js +287 -0
- package/dist/internal/classes.d.ts +1 -1
- package/dist/internal/classes.js +7 -9
- package/dist/internal/code-tokens.d.ts +2 -2
- package/dist/internal/code-tokens.js +12 -12
- package/dist/internal/fieldset.d.ts +1 -1
- package/dist/internal/fieldset.js +6 -6
- package/dist/internal/file-kind.d.ts +1 -1
- package/dist/internal/file-kind.js +43 -51
- package/dist/internal/flow.d.ts +4 -4
- package/dist/internal/flow.js +20 -23
- package/dist/internal/languages.js +999 -999
- package/dist/internal/message-scroller.d.ts +3 -3
- package/dist/internal/message-scroller.js +64 -112
- package/dist/internal/pressable.d.ts +1 -1
- package/dist/internal/pressable.js +7 -7
- package/dist/internal/state-panel.d.ts +35 -0
- package/dist/internal/state-panel.js +22 -0
- package/dist/internal/syntax.d.ts +2 -2
- package/dist/internal/syntax.js +36 -47
- package/dist/styles/accordion.css +3 -5
- package/dist/styles/agent-fanout.css +64 -60
- package/dist/styles/alert-dialog.css +12 -26
- package/dist/styles/alert.css +10 -15
- package/dist/styles/attachment.css +51 -93
- package/dist/styles/avatar.css +17 -24
- package/dist/styles/badge.css +11 -36
- package/dist/styles/board.css +571 -0
- package/dist/styles/brand-icon.css +7 -8
- package/dist/styles/breadcrumb.css +4 -7
- package/dist/styles/button-group.css +8 -14
- package/dist/styles/button.css +22 -27
- package/dist/styles/calendar.css +24 -36
- package/dist/styles/canvas.css +2 -3
- package/dist/styles/card.css +7 -23
- package/dist/styles/carousel.css +11 -12
- package/dist/styles/chart.css +215 -31
- package/dist/styles/chat-input.css +15 -39
- package/dist/styles/chat-plan.css +3 -4
- package/dist/styles/chat-sources.css +3 -6
- package/dist/styles/checkbox.css +11 -25
- package/dist/styles/choice-list.css +17 -31
- package/dist/styles/code-block.css +11 -25
- package/dist/styles/collapsible.css +10 -15
- package/dist/styles/combobox.css +11 -15
- package/dist/styles/command.css +5 -8
- package/dist/styles/context-menu.css +2 -2
- package/dist/styles/dialog.css +5 -16
- package/dist/styles/dropdown-menu.css +2 -2
- package/dist/styles/field.css +15 -21
- package/dist/styles/file-explorer.css +19 -33
- package/dist/styles/file-viewer.css +13 -17
- package/dist/styles/form.css +3 -3
- package/dist/styles/glass-banner.css +12 -47
- package/dist/styles/gradient-banner.css +17 -35
- package/dist/styles/hover-card.css +9 -15
- package/dist/styles/index.css +116 -108
- package/dist/styles/input-group.css +25 -41
- package/dist/styles/input-otp.css +5 -6
- package/dist/styles/input.css +5 -5
- package/dist/styles/kbd.css +1 -1
- package/dist/styles/label.css +9 -30
- package/dist/styles/mention-list.css +6 -8
- package/dist/styles/menubar.css +5 -6
- package/dist/styles/message-actions.css +1 -1
- package/dist/styles/message-response.css +3 -5
- package/dist/styles/message-scroller.css +14 -21
- package/dist/styles/message.css +23 -60
- package/dist/styles/navigation-menu.css +14 -29
- package/dist/styles/notice-banner.css +1 -2
- package/dist/styles/page-header.css +7 -10
- package/dist/styles/pagination.css +1 -4
- package/dist/styles/plan-outline.css +20 -37
- package/dist/styles/popover.css +10 -19
- package/dist/styles/presence-cursor.css +1 -2
- package/dist/styles/progress.css +2 -4
- package/dist/styles/prompt-list.css +6 -17
- package/dist/styles/questionnaire.css +16 -40
- package/dist/styles/radio-group.css +12 -23
- package/dist/styles/reasoning-effort.css +8 -15
- package/dist/styles/record-list.css +243 -0
- package/dist/styles/resizable.css +10 -11
- package/dist/styles/result-card.css +17 -3
- package/dist/styles/result-notice.css +80 -0
- package/dist/styles/review-card.css +2 -3
- package/dist/styles/rich-text-editor.css +1 -2
- package/dist/styles/schema-diagram.css +12 -17
- package/dist/styles/scroll-area.css +8 -10
- package/dist/styles/search-dialog.css +1 -5
- package/dist/styles/search-field.css +1 -2
- package/dist/styles/select.css +7 -7
- package/dist/styles/selection-slot.css +1 -2
- package/dist/styles/separator.css +7 -8
- package/dist/styles/settings-list.css +1 -2
- package/dist/styles/sheet.css +40 -73
- package/dist/styles/sidebar.css +17 -21
- package/dist/styles/skeleton.css +9 -11
- package/dist/styles/slider.css +11 -21
- package/dist/styles/spinner.css +2 -2
- package/dist/styles/sql-viewer.css +29 -29
- package/dist/styles/state-panel.css +8 -9
- package/dist/styles/state-sample.css +20 -33
- package/dist/styles/switch.css +11 -18
- package/dist/styles/table.css +51 -77
- package/dist/styles/tabs.css +12 -16
- package/dist/styles/textarea.css +3 -3
- package/dist/styles/themes/chatgpt.css +11 -23
- package/dist/styles/themes/claude.css +12 -24
- package/dist/styles/themes/cloudflare.css +11 -23
- package/dist/styles/themes/discord.css +11 -23
- package/dist/styles/themes/github.css +11 -23
- package/dist/styles/themes/grok.css +11 -23
- package/dist/styles/themes/linear.css +12 -25
- package/dist/styles/themes/neutral.css +11 -23
- package/dist/styles/themes/notion.css +11 -23
- package/dist/styles/themes/perplexity.css +11 -23
- package/dist/styles/themes/raycast.css +11 -23
- package/dist/styles/themes/spotify.css +11 -23
- package/dist/styles/themes/stripe.css +11 -23
- package/dist/styles/themes/supabase.css +11 -23
- package/dist/styles/themes/tulipfarm.css +9 -10
- package/dist/styles/themes/vercel.css +12 -25
- package/dist/styles/timeline.css +276 -0
- package/dist/styles/toast.css +13 -20
- package/dist/styles/toggle-group.css +17 -23
- package/dist/styles/toggle.css +8 -8
- package/dist/styles/tool-activity.css +7 -13
- package/dist/styles/toolbar-status.css +2 -7
- package/dist/styles/tooltip.css +15 -21
- package/dist/styles/view-switcher.css +279 -0
- package/package.json +21 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Children, createContext, Fragment, isValidElement, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from
|
|
4
|
-
import { cn } from
|
|
5
|
-
export const resizableOrientationNames = [
|
|
3
|
+
import { Children, createContext, Fragment, isValidElement, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore, } from 'react';
|
|
4
|
+
import { cn } from '../internal/classes.js';
|
|
5
|
+
export const resizableOrientationNames = ['horizontal', 'vertical'];
|
|
6
6
|
const GroupContext = createContext(null);
|
|
7
7
|
function useGroup(part) {
|
|
8
8
|
const context = useContext(GroupContext);
|
|
@@ -10,12 +10,12 @@ function useGroup(part) {
|
|
|
10
10
|
throw new Error(`${part} must be used inside ResizablePanelGroup.`);
|
|
11
11
|
return context;
|
|
12
12
|
}
|
|
13
|
-
const useIsomorphicLayoutEffect = typeof window ===
|
|
13
|
+
const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
|
|
14
14
|
const KEYBOARD_STEP = 5;
|
|
15
15
|
const EPSILON = 0.001;
|
|
16
16
|
/** Percent value of a size that can be resolved without measuring, or undefined. */
|
|
17
17
|
function staticPercent(size) {
|
|
18
|
-
if (typeof size !==
|
|
18
|
+
if (typeof size !== 'string')
|
|
19
19
|
return undefined;
|
|
20
20
|
const value = size.trim();
|
|
21
21
|
if (/^-?[\d.]+%?$/.test(value))
|
|
@@ -31,22 +31,22 @@ function toPercent(size, available, element) {
|
|
|
31
31
|
if (available <= 0)
|
|
32
32
|
return undefined;
|
|
33
33
|
let pixels;
|
|
34
|
-
if (typeof size ===
|
|
34
|
+
if (typeof size === 'number')
|
|
35
35
|
pixels = size;
|
|
36
36
|
else {
|
|
37
37
|
const value = Number.parseFloat(size);
|
|
38
|
-
const unit = size.trim().replace(/^-?[\d.]+/,
|
|
38
|
+
const unit = size.trim().replace(/^-?[\d.]+/, '');
|
|
39
39
|
const view = element.ownerDocument.defaultView;
|
|
40
|
-
const font = (node) => Number.parseFloat(view?.getComputedStyle(node).fontSize ??
|
|
41
|
-
if (unit ===
|
|
40
|
+
const font = (node) => Number.parseFloat(view?.getComputedStyle(node).fontSize ?? '') || 16;
|
|
41
|
+
if (unit === 'px')
|
|
42
42
|
pixels = value;
|
|
43
|
-
else if (unit ===
|
|
43
|
+
else if (unit === 'rem')
|
|
44
44
|
pixels = value * font(element.ownerDocument.documentElement);
|
|
45
|
-
else if (unit ===
|
|
45
|
+
else if (unit === 'em')
|
|
46
46
|
pixels = value * font(element);
|
|
47
|
-
else if (unit ===
|
|
47
|
+
else if (unit === 'vw')
|
|
48
48
|
pixels = (value * (view?.innerWidth ?? 0)) / 100;
|
|
49
|
-
else if (unit ===
|
|
49
|
+
else if (unit === 'vh')
|
|
50
50
|
pixels = (value * (view?.innerHeight ?? 0)) / 100;
|
|
51
51
|
else
|
|
52
52
|
return undefined;
|
|
@@ -62,18 +62,14 @@ function validate(sizes, bounds) {
|
|
|
62
62
|
const diff = 100 - total(next);
|
|
63
63
|
if (Math.abs(diff) < EPSILON)
|
|
64
64
|
break;
|
|
65
|
-
const open = next.flatMap((size, index) => (diff > 0 ? size < bounds[index].max : size > bounds[index].min)
|
|
66
|
-
? [index]
|
|
67
|
-
: []);
|
|
65
|
+
const open = next.flatMap((size, index) => (diff > 0 ? size < bounds[index].max : size > bounds[index].min) ? [index] : []);
|
|
68
66
|
if (!open.length)
|
|
69
67
|
break;
|
|
70
68
|
for (const index of open)
|
|
71
69
|
next[index] = clamp(next[index] + diff / open.length, bounds[index]);
|
|
72
70
|
}
|
|
73
71
|
const sum = total(next);
|
|
74
|
-
return Math.abs(sum - 100) < EPSILON || sum <= 0
|
|
75
|
-
? next
|
|
76
|
-
: next.map((size) => (size / sum) * 100);
|
|
72
|
+
return Math.abs(sum - 100) < EPSILON || sum <= 0 ? next : next.map(size => (size / sum) * 100);
|
|
77
73
|
}
|
|
78
74
|
/**
|
|
79
75
|
* Move the boundary after panel `pivot` by `delta` percent. The adjacent panel
|
|
@@ -91,7 +87,7 @@ function resize(base, bounds, pivot, delta) {
|
|
|
91
87
|
.map((_, index) => index)
|
|
92
88
|
.slice(0, pivot + 1)
|
|
93
89
|
.reverse();
|
|
94
|
-
const room = Math.min(bounds[grow].max - next[grow], total(shrink.map(
|
|
90
|
+
const room = Math.min(bounds[grow].max - next[grow], total(shrink.map(index => next[index] - bounds[index].min)));
|
|
95
91
|
let remaining = Math.max(0, Math.min(Math.abs(delta), room));
|
|
96
92
|
next[grow] = next[grow] + remaining;
|
|
97
93
|
for (const index of shrink) {
|
|
@@ -105,11 +101,10 @@ function resize(base, bounds, pivot, delta) {
|
|
|
105
101
|
}
|
|
106
102
|
function sameLayout(a, b) {
|
|
107
103
|
const keys = Object.keys(a);
|
|
108
|
-
return
|
|
109
|
-
keys.every((key) => key in b && Math.abs(a[key] - b[key]) < EPSILON));
|
|
104
|
+
return keys.length === Object.keys(b).length && keys.every(key => key in b && Math.abs(a[key] - b[key]) < EPSILON);
|
|
110
105
|
}
|
|
111
106
|
function collectPanelProps(children, found = []) {
|
|
112
|
-
Children.forEach(children,
|
|
107
|
+
Children.forEach(children, child => {
|
|
113
108
|
if (!isValidElement(child))
|
|
114
109
|
return;
|
|
115
110
|
if (child.type === ResizablePanel)
|
|
@@ -120,13 +115,13 @@ function collectPanelProps(children, found = []) {
|
|
|
120
115
|
return found;
|
|
121
116
|
}
|
|
122
117
|
function assignRef(ref, value) {
|
|
123
|
-
if (typeof ref ===
|
|
118
|
+
if (typeof ref === 'function')
|
|
124
119
|
ref(value);
|
|
125
120
|
else if (ref)
|
|
126
121
|
ref.current = value;
|
|
127
122
|
}
|
|
128
123
|
/** A row or column of resizable panels separated by `ResizableHandle`s. */
|
|
129
|
-
export function ResizablePanelGroup({ orientation =
|
|
124
|
+
export function ResizablePanelGroup({ orientation = 'horizontal', defaultLayout, onLayoutChange, onLayoutChanged, className, children, ref, ...props }) {
|
|
130
125
|
const element = useRef(null);
|
|
131
126
|
const panels = useRef(new Map());
|
|
132
127
|
const separators = useRef(new Map());
|
|
@@ -142,17 +137,14 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
142
137
|
const interacted = useRef(false);
|
|
143
138
|
const callbacks = useRef({ onLayoutChange, onLayoutChanged });
|
|
144
139
|
callbacks.current = { onLayoutChange, onLayoutChanged };
|
|
145
|
-
const horizontal = orientation ===
|
|
140
|
+
const horizontal = orientation === 'horizontal';
|
|
146
141
|
const autoSize = useMemo(() => {
|
|
147
|
-
const declared = collectPanelProps(children).map(
|
|
148
|
-
const unknown = declared.filter(
|
|
142
|
+
const declared = collectPanelProps(children).map(panel => staticPercent(panel.defaultSize));
|
|
143
|
+
const unknown = declared.filter(size => size === undefined).length;
|
|
149
144
|
const known = total(declared.filter((size) => size !== undefined));
|
|
150
145
|
return unknown ? Math.max(0, 100 - known) / unknown : 0;
|
|
151
146
|
}, [children]);
|
|
152
|
-
const ordered = useCallback(() => [...panels.current.values()].sort((a, b) => a.element.compareDocumentPosition(b.element) &
|
|
153
|
-
Node.DOCUMENT_POSITION_FOLLOWING
|
|
154
|
-
? -1
|
|
155
|
-
: 1), []);
|
|
147
|
+
const ordered = useCallback(() => [...panels.current.values()].sort((a, b) => a.element.compareDocumentPosition(b.element) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1), []);
|
|
156
148
|
const available = useCallback(() => {
|
|
157
149
|
const root = element.current;
|
|
158
150
|
if (!root)
|
|
@@ -164,7 +156,7 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
164
156
|
}, [horizontal]);
|
|
165
157
|
const measureBounds = useCallback((entries) => {
|
|
166
158
|
const space = available();
|
|
167
|
-
return entries.map(
|
|
159
|
+
return entries.map(entry => {
|
|
168
160
|
const min = toPercent(entry.minSize, space, entry.element) ?? 0;
|
|
169
161
|
const max = toPercent(entry.maxSize, space, entry.element) ?? 100;
|
|
170
162
|
return {
|
|
@@ -185,11 +177,11 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
185
177
|
if (settled)
|
|
186
178
|
callbacks.current.onLayoutChanged?.(next, settled);
|
|
187
179
|
}, []);
|
|
188
|
-
const defaultLayoutKey = defaultLayout ? JSON.stringify(defaultLayout) :
|
|
180
|
+
const defaultLayoutKey = defaultLayout ? JSON.stringify(defaultLayout) : '';
|
|
189
181
|
useIsomorphicLayoutEffect(() => {
|
|
190
182
|
const entries = ordered();
|
|
191
|
-
const ids = entries.map(
|
|
192
|
-
const key = ids.join(
|
|
183
|
+
const ids = entries.map(entry => entry.id);
|
|
184
|
+
const key = ids.join('\u0000');
|
|
193
185
|
const limits = measureBounds(entries);
|
|
194
186
|
const changedPanels = key !== panelKey.current;
|
|
195
187
|
const changedDefaults = defaultLayoutKey !== defaultsKey.current;
|
|
@@ -197,24 +189,22 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
197
189
|
interacted.current = false;
|
|
198
190
|
let sizes;
|
|
199
191
|
if (changedPanels || (changedDefaults && !interacted.current)) {
|
|
200
|
-
const saved = defaultLayout &&
|
|
201
|
-
ids.
|
|
202
|
-
ids.every((id) => typeof defaultLayout[id] === "number")
|
|
203
|
-
? ids.map((id) => defaultLayout[id])
|
|
192
|
+
const saved = defaultLayout && ids.length && ids.every(id => typeof defaultLayout[id] === 'number')
|
|
193
|
+
? ids.map(id => defaultLayout[id])
|
|
204
194
|
: null;
|
|
205
195
|
if (saved)
|
|
206
196
|
sizes = saved;
|
|
207
197
|
else {
|
|
208
198
|
const space = available();
|
|
209
|
-
const declared = entries.map(
|
|
210
|
-
const unknown = declared.filter(
|
|
211
|
-
const rest = Math.max(0, 100 -
|
|
212
|
-
|
|
213
|
-
sizes = declared.map(
|
|
199
|
+
const declared = entries.map(entry => toPercent(entry.defaultSize, space, entry.element));
|
|
200
|
+
const unknown = declared.filter(size => size === undefined).length;
|
|
201
|
+
const rest = Math.max(0, 100 - total(declared.filter((size) => size !== undefined))) /
|
|
202
|
+
Math.max(unknown, 1);
|
|
203
|
+
sizes = declared.map(size => size ?? rest);
|
|
214
204
|
}
|
|
215
205
|
}
|
|
216
206
|
else
|
|
217
|
-
sizes = ids.map(
|
|
207
|
+
sizes = ids.map(id => layoutRef.current[id] ?? 0);
|
|
218
208
|
const before = layoutRef.current;
|
|
219
209
|
const next = validate(sizes, limits);
|
|
220
210
|
const nextLayout = Object.fromEntries(ids.map((id, index) => [id, next[index]]));
|
|
@@ -226,16 +216,13 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
226
216
|
panelKey.current = key;
|
|
227
217
|
defaultsKey.current = defaultLayoutKey;
|
|
228
218
|
const nextBounds = Object.fromEntries(ids.map((id, index) => [id, limits[index]]));
|
|
229
|
-
setBounds(
|
|
230
|
-
? current
|
|
231
|
-
: nextBounds);
|
|
219
|
+
setBounds(current => (JSON.stringify(current) === JSON.stringify(nextBounds) ? current : nextBounds));
|
|
232
220
|
const nextLinks = {};
|
|
233
221
|
for (const [separatorId, separator] of separators.current) {
|
|
234
222
|
let previous;
|
|
235
223
|
let following;
|
|
236
224
|
for (const entry of entries) {
|
|
237
|
-
if (separator.compareDocumentPosition(entry.element) &
|
|
238
|
-
Node.DOCUMENT_POSITION_PRECEDING)
|
|
225
|
+
if (separator.compareDocumentPosition(entry.element) & Node.DOCUMENT_POSITION_PRECEDING)
|
|
239
226
|
previous = entry;
|
|
240
227
|
else {
|
|
241
228
|
following = entry;
|
|
@@ -245,21 +232,11 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
245
232
|
if (previous && following)
|
|
246
233
|
nextLinks[separatorId] = { before: previous.id, after: following.id };
|
|
247
234
|
}
|
|
248
|
-
setLinks(
|
|
249
|
-
|
|
250
|
-
: nextLinks);
|
|
251
|
-
}, [
|
|
252
|
-
version,
|
|
253
|
-
extent,
|
|
254
|
-
defaultLayoutKey,
|
|
255
|
-
ordered,
|
|
256
|
-
measureBounds,
|
|
257
|
-
available,
|
|
258
|
-
commit,
|
|
259
|
-
]);
|
|
235
|
+
setLinks(current => (JSON.stringify(current) === JSON.stringify(nextLinks) ? current : nextLinks));
|
|
236
|
+
}, [version, extent, defaultLayoutKey, ordered, measureBounds, available, commit]);
|
|
260
237
|
useEffect(() => {
|
|
261
238
|
const root = element.current;
|
|
262
|
-
if (!root || typeof ResizeObserver ===
|
|
239
|
+
if (!root || typeof ResizeObserver === 'undefined')
|
|
263
240
|
return;
|
|
264
241
|
const observer = new ResizeObserver(() => setExtent(Math.round(available())));
|
|
265
242
|
observer.observe(root);
|
|
@@ -267,19 +244,19 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
267
244
|
}, [available]);
|
|
268
245
|
const registerPanel = useCallback((entry) => {
|
|
269
246
|
panels.current.set(entry.id, entry);
|
|
270
|
-
setVersion(
|
|
247
|
+
setVersion(value => value + 1);
|
|
271
248
|
return () => {
|
|
272
249
|
if (panels.current.get(entry.id) === entry)
|
|
273
250
|
panels.current.delete(entry.id);
|
|
274
|
-
setVersion(
|
|
251
|
+
setVersion(value => value + 1);
|
|
275
252
|
};
|
|
276
253
|
}, []);
|
|
277
254
|
const registerSeparator = useCallback((id, node) => {
|
|
278
255
|
separators.current.set(id, node);
|
|
279
|
-
setVersion(
|
|
256
|
+
setVersion(value => value + 1);
|
|
280
257
|
return () => {
|
|
281
258
|
separators.current.delete(id);
|
|
282
|
-
setVersion(
|
|
259
|
+
setVersion(value => value + 1);
|
|
283
260
|
};
|
|
284
261
|
}, []);
|
|
285
262
|
const pivotFor = useCallback((separatorId) => {
|
|
@@ -289,23 +266,20 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
289
266
|
const entries = ordered();
|
|
290
267
|
let pivot = -1;
|
|
291
268
|
entries.forEach((entry, index) => {
|
|
292
|
-
if (separator.compareDocumentPosition(entry.element) &
|
|
293
|
-
Node.DOCUMENT_POSITION_PRECEDING)
|
|
269
|
+
if (separator.compareDocumentPosition(entry.element) & Node.DOCUMENT_POSITION_PRECEDING)
|
|
294
270
|
pivot = index;
|
|
295
271
|
});
|
|
296
272
|
if (pivot < 0 || pivot >= entries.length - 1)
|
|
297
273
|
return null;
|
|
298
|
-
const ids = entries.map(
|
|
274
|
+
const ids = entries.map(entry => entry.id);
|
|
299
275
|
return {
|
|
300
276
|
ids,
|
|
301
277
|
pivot,
|
|
302
|
-
base: ids.map(
|
|
278
|
+
base: ids.map(id => layoutRef.current[id] ?? 0),
|
|
303
279
|
limits: measureBounds(entries),
|
|
304
280
|
};
|
|
305
281
|
}, [ordered, measureBounds]);
|
|
306
|
-
const reversed = useCallback(() => horizontal &&
|
|
307
|
-
!!element.current &&
|
|
308
|
-
getComputedStyle(element.current).direction === "rtl", [horizontal]);
|
|
282
|
+
const reversed = useCallback(() => horizontal && !!element.current && getComputedStyle(element.current).direction === 'rtl', [horizontal]);
|
|
309
283
|
const startDrag = useCallback((separatorId, event) => {
|
|
310
284
|
const target = pivotFor(separatorId);
|
|
311
285
|
if (!target)
|
|
@@ -320,8 +294,8 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
320
294
|
const root = ownerDocument.documentElement;
|
|
321
295
|
const previousCursor = root.style.cursor;
|
|
322
296
|
const previousSelect = root.style.userSelect;
|
|
323
|
-
root.style.cursor = horizontal ?
|
|
324
|
-
root.style.userSelect =
|
|
297
|
+
root.style.cursor = horizontal ? 'col-resize' : 'row-resize';
|
|
298
|
+
root.style.userSelect = 'none';
|
|
325
299
|
handle.setPointerCapture?.(pointerId);
|
|
326
300
|
handle.focus({ preventScroll: true });
|
|
327
301
|
setDragging(separatorId);
|
|
@@ -337,9 +311,9 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
337
311
|
const end = (endEvent) => {
|
|
338
312
|
if (endEvent.pointerId !== pointerId)
|
|
339
313
|
return;
|
|
340
|
-
handle.removeEventListener(
|
|
341
|
-
handle.removeEventListener(
|
|
342
|
-
handle.removeEventListener(
|
|
314
|
+
handle.removeEventListener('pointermove', move);
|
|
315
|
+
handle.removeEventListener('pointerup', end);
|
|
316
|
+
handle.removeEventListener('pointercancel', end);
|
|
343
317
|
handle.releasePointerCapture?.(pointerId);
|
|
344
318
|
root.style.cursor = previousCursor;
|
|
345
319
|
root.style.userSelect = previousSelect;
|
|
@@ -347,9 +321,9 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
347
321
|
interacted.current = true;
|
|
348
322
|
commit(target.ids, latest, { isUserInteraction: true });
|
|
349
323
|
};
|
|
350
|
-
handle.addEventListener(
|
|
351
|
-
handle.addEventListener(
|
|
352
|
-
handle.addEventListener(
|
|
324
|
+
handle.addEventListener('pointermove', move);
|
|
325
|
+
handle.addEventListener('pointerup', end);
|
|
326
|
+
handle.addEventListener('pointercancel', end);
|
|
353
327
|
}, [pivotFor, horizontal, available, reversed, commit]);
|
|
354
328
|
const resizeWithKey = useCallback((separatorId, key) => {
|
|
355
329
|
const target = pivotFor(separatorId);
|
|
@@ -358,13 +332,13 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
358
332
|
const { base, limits, pivot } = target;
|
|
359
333
|
const forward = reversed() ? -KEYBOARD_STEP : KEYBOARD_STEP;
|
|
360
334
|
let delta;
|
|
361
|
-
if (key === (horizontal ?
|
|
335
|
+
if (key === (horizontal ? 'ArrowRight' : 'ArrowDown'))
|
|
362
336
|
delta = forward;
|
|
363
|
-
else if (key === (horizontal ?
|
|
337
|
+
else if (key === (horizontal ? 'ArrowLeft' : 'ArrowUp'))
|
|
364
338
|
delta = -forward;
|
|
365
|
-
else if (key ===
|
|
339
|
+
else if (key === 'Home')
|
|
366
340
|
delta = limits[pivot].min - base[pivot];
|
|
367
|
-
else if (key ===
|
|
341
|
+
else if (key === 'End')
|
|
368
342
|
delta = limits[pivot].max - base[pivot];
|
|
369
343
|
else
|
|
370
344
|
return false;
|
|
@@ -397,14 +371,14 @@ export function ResizablePanelGroup({ orientation = "horizontal", defaultLayout,
|
|
|
397
371
|
startDrag,
|
|
398
372
|
resizeWithKey,
|
|
399
373
|
]);
|
|
400
|
-
return (_jsx(GroupContext, { value: context, children: _jsx("div", { "data-slot": "resizable-panel-group", "data-orientation": orientation, "data-dragging": dragging ?
|
|
374
|
+
return (_jsx(GroupContext, { value: context, children: _jsx("div", { "data-slot": "resizable-panel-group", "data-orientation": orientation, "data-dragging": dragging ? '' : undefined, className: cn('sprout-resizable-group', className), ref: node => {
|
|
401
375
|
element.current = node;
|
|
402
376
|
assignRef(ref, node);
|
|
403
377
|
}, ...props, children: children }) }));
|
|
404
378
|
}
|
|
405
379
|
/** One resizable region. It must be a direct child of `ResizablePanelGroup`. */
|
|
406
380
|
export function ResizablePanel({ id: idProp, defaultSize, minSize, maxSize, className, style, ref, ...props }) {
|
|
407
|
-
const group = useGroup(
|
|
381
|
+
const group = useGroup('ResizablePanel');
|
|
408
382
|
const generated = useId();
|
|
409
383
|
const id = idProp ?? generated;
|
|
410
384
|
const element = useRef(null);
|
|
@@ -422,7 +396,7 @@ export function ResizablePanel({ id: idProp, defaultSize, minSize, maxSize, clas
|
|
|
422
396
|
}, [registerPanel, id, defaultSize, minSize, maxSize]);
|
|
423
397
|
const size = group.layout[id] ?? staticPercent(defaultSize) ?? group.autoSize;
|
|
424
398
|
const flex = { flexGrow: size, flexShrink: 1, flexBasis: 0 };
|
|
425
|
-
return (_jsx("div", { "data-slot": "resizable-panel", "data-panel-id": id, id: id, className: cn(
|
|
399
|
+
return (_jsx("div", { "data-slot": "resizable-panel", "data-panel-id": id, id: id, className: cn('sprout-resizable-panel', className), ref: node => {
|
|
426
400
|
element.current = node;
|
|
427
401
|
assignRef(ref, node);
|
|
428
402
|
}, ...props, style: { ...style, ...flex } }));
|
|
@@ -432,7 +406,7 @@ export function ResizablePanel({ id: idProp, defaultSize, minSize, maxSize, clas
|
|
|
432
406
|
* Home and End move it to the first panel's minimum and maximum size.
|
|
433
407
|
*/
|
|
434
408
|
export function ResizableHandle({ withHandle = false, className, children, onPointerDown, onKeyDown, ref, ...props }) {
|
|
435
|
-
const group = useGroup(
|
|
409
|
+
const group = useGroup('ResizableHandle');
|
|
436
410
|
const id = useId();
|
|
437
411
|
const element = useRef(null);
|
|
438
412
|
const { registerSeparator } = group;
|
|
@@ -452,11 +426,11 @@ export function ResizableHandle({ withHandle = false, className, children, onPoi
|
|
|
452
426
|
max: Math.min(own.max, 100 - total(others.map(([, bound]) => bound.min))),
|
|
453
427
|
};
|
|
454
428
|
}
|
|
455
|
-
const lineOrientation = group.orientation ===
|
|
456
|
-
return (_jsxs("div", { role: "separator", tabIndex: 0, "aria-orientation": lineOrientation, "aria-controls": link?.before, "aria-valuenow": value === undefined ? undefined : Math.round(value), "aria-valuemin": limits ? Math.round(limits.min) : 0, "aria-valuemax": limits ? Math.round(limits.max) : 100, "data-slot": "resizable-handle", "data-orientation": lineOrientation, "data-with-handle": withHandle ?
|
|
429
|
+
const lineOrientation = group.orientation === 'horizontal' ? 'vertical' : 'horizontal';
|
|
430
|
+
return (_jsxs("div", { role: "separator", tabIndex: 0, "aria-orientation": lineOrientation, "aria-controls": link?.before, "aria-valuenow": value === undefined ? undefined : Math.round(value), "aria-valuemin": limits ? Math.round(limits.min) : 0, "aria-valuemax": limits ? Math.round(limits.max) : 100, "data-slot": "resizable-handle", "data-orientation": lineOrientation, "data-with-handle": withHandle ? '' : undefined, "data-dragging": group.dragging === id ? '' : undefined, className: cn('sprout-resizable-handle', className), ref: node => {
|
|
457
431
|
element.current = node;
|
|
458
432
|
assignRef(ref, node);
|
|
459
|
-
}, onPointerDown:
|
|
433
|
+
}, onPointerDown: event => {
|
|
460
434
|
onPointerDown?.(event);
|
|
461
435
|
if (event.defaultPrevented || event.button !== 0)
|
|
462
436
|
return;
|
|
@@ -467,12 +441,12 @@ export function ResizableHandle({ withHandle = false, className, children, onPoi
|
|
|
467
441
|
return;
|
|
468
442
|
if (group.resizeWithKey(id, event.key))
|
|
469
443
|
event.preventDefault();
|
|
470
|
-
}, ...props, children: [withHandle &&
|
|
444
|
+
}, ...props, children: [withHandle && _jsx("span", { "aria-hidden": "true", "data-slot": "resizable-handle-grip", className: "sprout-resizable-grip" }), children] }));
|
|
471
445
|
}
|
|
472
446
|
const storageListeners = new Set();
|
|
473
447
|
function browserStorage() {
|
|
474
448
|
try {
|
|
475
|
-
return typeof window ===
|
|
449
|
+
return typeof window === 'undefined' ? undefined : window.localStorage;
|
|
476
450
|
}
|
|
477
451
|
catch {
|
|
478
452
|
return undefined;
|
|
@@ -483,13 +457,13 @@ function browserStorage() {
|
|
|
483
457
|
* `ResizablePanelGroup` as `defaultLayout` and `onLayoutChanged`.
|
|
484
458
|
*/
|
|
485
459
|
export function useResizableLayout({ id, panelIds, onlySaveAfterUserInteractions = false, storage, }) {
|
|
486
|
-
const key = `sprout-resizable:${id}${panelIds ? `:${panelIds.join(
|
|
460
|
+
const key = `sprout-resizable:${id}${panelIds ? `:${panelIds.join(',')}` : ''}`;
|
|
487
461
|
const subscribe = useCallback((listener) => {
|
|
488
462
|
storageListeners.add(listener);
|
|
489
|
-
window.addEventListener(
|
|
463
|
+
window.addEventListener('storage', listener);
|
|
490
464
|
return () => {
|
|
491
465
|
storageListeners.delete(listener);
|
|
492
|
-
window.removeEventListener(
|
|
466
|
+
window.removeEventListener('storage', listener);
|
|
493
467
|
};
|
|
494
468
|
}, []);
|
|
495
469
|
const raw = useSyncExternalStore(subscribe, () => {
|
|
@@ -505,10 +479,10 @@ export function useResizableLayout({ id, panelIds, onlySaveAfterUserInteractions
|
|
|
505
479
|
return undefined;
|
|
506
480
|
try {
|
|
507
481
|
const parsed = JSON.parse(raw);
|
|
508
|
-
if (!parsed || typeof parsed !==
|
|
482
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
509
483
|
return undefined;
|
|
510
484
|
const entries = Object.entries(parsed);
|
|
511
|
-
return entries.every(([, size]) => typeof size ===
|
|
485
|
+
return entries.every(([, size]) => typeof size === 'number' && Number.isFinite(size))
|
|
512
486
|
? Object.fromEntries(entries)
|
|
513
487
|
: undefined;
|
|
514
488
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ComponentProps, ReactNode } from
|
|
2
|
-
import { type Brand } from
|
|
1
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
+
import { type Brand } from './brand-icon.js';
|
|
3
3
|
export declare const resultCardKindNames: readonly ["File", "Plan", "Workflow", "Action", "Calendar", "Table", "Activity", "Agent", "Skill"];
|
|
4
4
|
export declare const resultCardStateNames: readonly ["default", "loading", "running", "disabled", "error", "success"];
|
|
5
5
|
export declare const resultAppActionStateNames: readonly ["completed", "pending", "running", "failed", "unknown", "blocked", "cancelled", "skipped"];
|
|
@@ -10,10 +10,15 @@ export type ResultAppAction = {
|
|
|
10
10
|
label: string;
|
|
11
11
|
state: ResultAppActionState;
|
|
12
12
|
};
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* One app that took part in a result. `brand: null` shows `icon`, or a
|
|
15
|
+
* generic plug when no icon is given.
|
|
16
|
+
*/
|
|
14
17
|
export type ResultApp = {
|
|
15
18
|
brand: Brand | null;
|
|
16
19
|
name: string;
|
|
20
|
+
/** Shown when `brand` is null, such as a table icon for your own data. */
|
|
21
|
+
icon?: ReactNode;
|
|
17
22
|
actions: readonly ResultAppAction[];
|
|
18
23
|
};
|
|
19
24
|
export type ResultCardAction = {
|
|
@@ -21,7 +26,7 @@ export type ResultCardAction = {
|
|
|
21
26
|
onClick: () => void;
|
|
22
27
|
disabled?: boolean | undefined;
|
|
23
28
|
};
|
|
24
|
-
export interface ResultCardProps extends Omit<ComponentProps<
|
|
29
|
+
export interface ResultCardProps extends Omit<ComponentProps<'section'>, 'title' | 'children'> {
|
|
25
30
|
title: string;
|
|
26
31
|
kind: ResultCardKind;
|
|
27
32
|
/** Apps used. Repeated brands merge; two tiles show, the rest fold into “+N”. */
|
|
@@ -46,7 +51,7 @@ export interface ResultCardProps extends Omit<ComponentProps<"section">, "title"
|
|
|
46
51
|
* live status, and offers one action such as “Open in Canvas”.
|
|
47
52
|
*/
|
|
48
53
|
export declare function ResultCard({ title, kind, apps, status, state, action, icon, children, className, ...props }: ResultCardProps): import("react").JSX.Element;
|
|
49
|
-
export interface ResultAppActionsProps extends Omit<ComponentProps<
|
|
54
|
+
export interface ResultAppActionsProps extends Omit<ComponentProps<'div'>, 'children'> {
|
|
50
55
|
apps: readonly ResultApp[];
|
|
51
56
|
/** Show each app’s icon and name above its actions. Defaults to `true`. */
|
|
52
57
|
showAppNames?: boolean | undefined;
|
|
@@ -1,59 +1,50 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Check } from
|
|
4
|
-
import { Danger } from
|
|
5
|
-
import { Plug } from
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { BrandIcon, BrandTile } from
|
|
8
|
-
import { Button } from
|
|
9
|
-
import { Popover, PopoverContent, PopoverTitle, PopoverTrigger
|
|
10
|
-
import { Spinner } from
|
|
3
|
+
import { Check } from 'reicon-react/icons/Check';
|
|
4
|
+
import { Danger } from 'reicon-react/icons/Danger';
|
|
5
|
+
import { Plug } from 'reicon-react/icons/Plug';
|
|
6
|
+
import { cn } from '../internal/classes.js';
|
|
7
|
+
import { BrandIcon, BrandTile } from './brand-icon.js';
|
|
8
|
+
import { Button } from './button.js';
|
|
9
|
+
import { Popover, PopoverContent, PopoverTitle, PopoverTrigger } from './popover.js';
|
|
10
|
+
import { Spinner } from './spinner.js';
|
|
11
11
|
export const resultCardKindNames = [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
];
|
|
22
|
-
export const resultCardStateNames = [
|
|
23
|
-
"default",
|
|
24
|
-
"loading",
|
|
25
|
-
"running",
|
|
26
|
-
"disabled",
|
|
27
|
-
"error",
|
|
28
|
-
"success",
|
|
12
|
+
'File',
|
|
13
|
+
'Plan',
|
|
14
|
+
'Workflow',
|
|
15
|
+
'Action',
|
|
16
|
+
'Calendar',
|
|
17
|
+
'Table',
|
|
18
|
+
'Activity',
|
|
19
|
+
'Agent',
|
|
20
|
+
'Skill',
|
|
29
21
|
];
|
|
22
|
+
export const resultCardStateNames = ['default', 'loading', 'running', 'disabled', 'error', 'success'];
|
|
30
23
|
export const resultAppActionStateNames = [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
24
|
+
'completed',
|
|
25
|
+
'pending',
|
|
26
|
+
'running',
|
|
27
|
+
'failed',
|
|
28
|
+
'unknown',
|
|
29
|
+
'blocked',
|
|
30
|
+
'cancelled',
|
|
31
|
+
'skipped',
|
|
39
32
|
];
|
|
40
33
|
const actionPrefixes = {
|
|
41
|
-
failed:
|
|
42
|
-
unknown:
|
|
43
|
-
pending:
|
|
44
|
-
running:
|
|
45
|
-
blocked:
|
|
46
|
-
cancelled:
|
|
47
|
-
skipped:
|
|
34
|
+
failed: 'Failed:',
|
|
35
|
+
unknown: 'Unconfirmed:',
|
|
36
|
+
pending: 'Pending:',
|
|
37
|
+
running: 'In progress:',
|
|
38
|
+
blocked: 'Blocked:',
|
|
39
|
+
cancelled: 'Cancelled:',
|
|
40
|
+
skipped: 'Skipped:',
|
|
48
41
|
};
|
|
49
42
|
function mergeApps(apps) {
|
|
50
43
|
const byKey = new Map();
|
|
51
44
|
for (const app of apps) {
|
|
52
45
|
const key = app.brand ?? app.name;
|
|
53
46
|
const existing = byKey.get(key);
|
|
54
|
-
byKey.set(key, existing
|
|
55
|
-
? { ...existing, actions: [...existing.actions, ...app.actions] }
|
|
56
|
-
: app);
|
|
47
|
+
byKey.set(key, existing ? { ...existing, actions: [...existing.actions, ...app.actions] } : app);
|
|
57
48
|
}
|
|
58
49
|
return [...byKey.values()];
|
|
59
50
|
}
|
|
@@ -62,27 +53,25 @@ function mergeApps(apps) {
|
|
|
62
53
|
* action, calendar read, or table result. It names the apps used, shows a
|
|
63
54
|
* live status, and offers one action such as “Open in Canvas”.
|
|
64
55
|
*/
|
|
65
|
-
export function ResultCard({ title, kind, apps, status, state =
|
|
56
|
+
export function ResultCard({ title, kind, apps, status, state = 'default', action, icon, children, className, ...props }) {
|
|
66
57
|
const unique = mergeApps(apps);
|
|
67
58
|
const visible = unique.slice(0, 2);
|
|
68
59
|
const hidden = unique.slice(2);
|
|
69
|
-
const busy = state ===
|
|
70
|
-
const disabled = state ===
|
|
71
|
-
return (_jsxs("section", { "data-slot": "result-card", "data-state": state, "data-kind": kind, "aria-label": `${kind}: ${title}`, "aria-busy": busy, ...props, className: cn(
|
|
60
|
+
const busy = state === 'loading' || state === 'running';
|
|
61
|
+
const disabled = state === 'disabled';
|
|
62
|
+
return (_jsxs("section", { "data-slot": "result-card", "data-state": state, "data-kind": kind, "aria-label": `${kind}: ${title}`, "aria-busy": busy, ...props, className: cn('sprout-result-card', className), children: [_jsxs("div", { className: "sprout-result-card-header", children: [visible.length > 0 ? (_jsxs("div", { role: "group", "aria-label": "Apps used", className: "sprout-result-card-apps", children: [visible.map(app => (_jsx("span", { "data-result-app": app.brand ?? 'connected-app', className: "sprout-result-card-app", children: _jsx(AppActionsPopover, { apps: [app], disabled: disabled }) }, app.brand ?? app.name))), hidden.length > 0 && (_jsx("span", { "data-result-overflow": hidden.length, className: "sprout-result-card-app", children: _jsx(AppActionsPopover, { apps: hidden, overflow: true, disabled: disabled }) }))] })) : (icon && (_jsx(BrandTile, { "aria-hidden": "true", className: "sprout-result-card-icon", children: icon }))), _jsxs("div", { className: "sprout-result-card-main", children: [_jsxs("div", { className: "sprout-result-card-text", children: [_jsx("h3", { className: "sprout-result-card-title", children: title }), _jsxs("div", { className: "sprout-result-card-meta", children: [_jsx("span", { children: kind }), _jsx("span", { "aria-hidden": "true", children: "\u00B7" }), _jsxs("span", { role: "status", "data-tone": state === 'success' || state === 'error' ? state : undefined, className: "sprout-result-card-status", children: [busy ? (_jsx(Spinner, { "aria-hidden": "true" })) : state === 'success' ? (_jsx(Check, { size: 14, "aria-hidden": "true" })) : state === 'error' ? (_jsx(Danger, { size: 14, "aria-hidden": "true" })) : null, status] })] })] }), action && (_jsx("div", { className: "sprout-result-card-action", children: _jsx(Button, { variant: "outline", size: "result-card", disabled: state === 'loading' || disabled || action.disabled === true, onClick: action.onClick, children: action.label }) }))] })] }), children && _jsx("div", { className: "sprout-result-card-body", children: children })] }));
|
|
72
63
|
}
|
|
73
64
|
function AppActionsPopover({ apps, overflow = false, disabled, }) {
|
|
74
65
|
const first = apps[0];
|
|
75
66
|
if (!first)
|
|
76
67
|
return null;
|
|
77
|
-
const title = overflow
|
|
78
|
-
|
|
79
|
-
: `${first.name} actions`;
|
|
80
|
-
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { openOnHover: true, delay: 800, closeDelay: 200, render: _jsx(BrandTile, { size: "action", render: _jsx(Button, { variant: "ghost", size: "icon", disabled: disabled }) }), "aria-label": title, children: overflow ? (_jsxs("span", { className: "sprout-result-card-overflow", children: ["+", apps.length] })) : first.brand ? (_jsx(BrandIcon, { brand: first.brand, size: "fill" })) : (_jsx(Plug, { size: 18, "aria-hidden": "true" })) }), _jsxs(PopoverContent, { size: "app-actions", align: "start", sideOffset: 8, initialFocus: (interaction) => interaction !== "mouse", children: [_jsx(PopoverTitle, { children: title }), _jsx(ResultAppActions, { apps: apps, showAppNames: overflow })] })] }));
|
|
68
|
+
const title = overflow ? `${apps.length} more ${apps.length === 1 ? 'app' : 'apps'}` : `${first.name} actions`;
|
|
69
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { openOnHover: true, delay: 800, closeDelay: 200, render: _jsx(BrandTile, { size: "action", render: _jsx(Button, { variant: "ghost", size: "icon", disabled: disabled }) }), "aria-label": title, children: overflow ? (_jsxs("span", { className: "sprout-result-card-overflow", children: ["+", apps.length] })) : first.brand ? (_jsx(BrandIcon, { brand: first.brand, size: "fill" })) : first.icon ? (_jsx("span", { "aria-hidden": "true", className: "sprout-result-app-icon", children: first.icon })) : (_jsx(Plug, { size: 18, "aria-hidden": "true" })) }), _jsxs(PopoverContent, { size: "app-actions", align: "start", sideOffset: 8, initialFocus: interaction => interaction !== 'mouse', children: [_jsx(PopoverTitle, { children: title }), _jsx(ResultAppActions, { apps: apps, showAppNames: overflow })] })] }));
|
|
81
70
|
}
|
|
82
71
|
/**
|
|
83
72
|
* The actions each app took, grouped by app. A check marks completed
|
|
84
73
|
* actions; every other state is spelled out, such as “Unconfirmed:”.
|
|
85
74
|
*/
|
|
86
75
|
export function ResultAppActions({ apps, showAppNames = true, className, ...props }) {
|
|
87
|
-
return (_jsx("div", { "data-slot": "result-app-actions", ...props, className: cn(
|
|
76
|
+
return (_jsx("div", { "data-slot": "result-app-actions", ...props, className: cn('sprout-result-app-actions', className), children: apps.map(app => (_jsxs("section", { "aria-label": app.name, className: "sprout-result-app", children: [showAppNames && (_jsxs("div", { className: "sprout-result-app-name", children: [app.brand ? (_jsx(BrandIcon, { brand: app.brand, size: "glyph" })) : app.icon ? (_jsx("span", { "aria-hidden": "true", className: "sprout-result-app-icon", children: app.icon })) : (_jsx(Plug, { size: 20, "aria-hidden": "true" })), _jsx("h4", { children: app.name })] })), app.actions.length === 0 ? (_jsx("p", { className: "sprout-result-app-empty", children: "No action details were recorded." })) : (_jsx("ul", { className: "sprout-result-app-list", children: app.actions.map((action, index) => (_jsxs("li", { "data-state": action.state, className: "sprout-result-app-action", children: [action.state === 'completed' ? (_jsxs("span", { className: "sprout-result-app-check", children: [_jsx(Check, { size: 16, "aria-hidden": "true" }), _jsx("span", { className: "sprout-result-sr-only", children: "Completed:" })] })) : (_jsx("span", { className: "sprout-result-app-prefix", children: actionPrefixes[action.state] })), _jsx("span", { className: "sprout-result-app-label", children: action.label })] }, `${action.label}:${index}`))) }))] }, app.brand ?? app.name))) }));
|
|
88
77
|
}
|