@tulipfarm/sprout 0.3.1 → 0.5.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 +75 -68
- package/dist/components/accordion.d.ts +2 -2
- package/dist/components/accordion.js +9 -9
- package/dist/components/agent-avatar.d.ts +27 -0
- package/dist/components/agent-avatar.js +67 -0
- package/dist/components/agent-fanout.d.ts +2 -2
- package/dist/components/agent-fanout.js +65 -87
- package/dist/components/alert-dialog.d.ts +8 -8
- package/dist/components/alert-dialog.js +21 -21
- 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 +18 -18
- package/dist/components/attachment.js +82 -115
- package/dist/components/avatar.d.ts +9 -17
- package/dist/components/avatar.js +14 -51
- 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 +13 -13
- package/dist/components/button.js +31 -57
- 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 +7 -7
- 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 +10 -10
- 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 +12 -6
- package/dist/components/combobox.js +27 -26
- 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 +7 -7
- 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 +18 -18
- package/dist/components/input-group.js +25 -39
- package/dist/components/input-otp.d.ts +14 -10
- package/dist/components/input-otp.js +15 -15
- package/dist/components/input.d.ts +3 -3
- 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 +17 -17
- 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 +4 -4
- 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 +5 -5
- 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 +3 -3
- 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 +5 -9
- 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 +7 -7
- 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 +8 -8
- package/dist/components/state-sample.js +18 -31
- package/dist/components/switch.d.ts +3 -3
- 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 +4 -4
- package/dist/components/toggle-group.js +18 -20
- package/dist/components/toggle.d.ts +4 -4
- 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 +99 -93
- package/dist/index.js +99 -93
- package/dist/internal/agent-avatar-artwork.d.ts +4 -0
- package/dist/internal/agent-avatar-artwork.js +219 -0
- 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/hash.d.ts +1 -0
- package/dist/internal/hash.js +9 -0
- 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 +56 -98
- package/dist/styles/avatar.css +14 -33
- 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 +9 -15
- package/dist/styles/button.css +45 -175
- 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 +4 -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 +24 -17
- package/dist/styles/command.css +8 -9
- package/dist/styles/context-menu.css +4 -2
- package/dist/styles/dialog.css +5 -16
- package/dist/styles/dropdown-menu.css +4 -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 +16 -39
- package/dist/styles/hover-card.css +9 -15
- package/dist/styles/index.css +121 -112
- package/dist/styles/input-group.css +61 -69
- package/dist/styles/input-otp.css +18 -9
- package/dist/styles/input.css +19 -11
- 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 +9 -8
- 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 +15 -30
- package/dist/styles/notice-banner.css +1 -2
- package/dist/styles/page-header.css +11 -10
- package/dist/styles/pagination.css +12 -6
- 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 +4 -4
- package/dist/styles/result-notice.css +80 -0
- package/dist/styles/review-card.css +2 -3
- package/dist/styles/rich-text-editor.css +4 -5
- 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 +15 -19
- 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 +32 -34
- 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 +62 -81
- package/dist/styles/tabs.css +13 -19
- 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 +23 -29
- package/dist/styles/toggle.css +14 -14
- 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 +297 -0
- package/package.json +25 -1
|
@@ -1,51 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { Background, BaseEdge, EdgeLabelRenderer, getSmoothStepPath, Handle, Position, ReactFlow, ReactFlowProvider, } from
|
|
4
|
-
import { useId, useMemo } from
|
|
5
|
-
import { Key } from
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { FitOnResize, flowMaxZoom as maxZoom, flowMinZoom as minZoom, useKeyboardView, useViewportMobile, ZoomControls, } from
|
|
8
|
-
import { Badge } from
|
|
9
|
-
export const schemaTableStateNames = [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"unchanged",
|
|
13
|
-
"linked",
|
|
14
|
-
];
|
|
15
|
-
export const schemaChangeNames = ["added", "changed", "removed"];
|
|
16
|
-
export const schemaDiagramLayoutNames = [
|
|
17
|
-
"auto",
|
|
18
|
-
"horizontal",
|
|
19
|
-
"vertical",
|
|
20
|
-
];
|
|
3
|
+
import { Background, BaseEdge, EdgeLabelRenderer, getSmoothStepPath, Handle, Position, ReactFlow, ReactFlowProvider, } from '@xyflow/react';
|
|
4
|
+
import { useId, useMemo } from 'react';
|
|
5
|
+
import { Key } from 'reicon-react/icons/Key';
|
|
6
|
+
import { cn } from '../internal/classes.js';
|
|
7
|
+
import { FitOnResize, flowMaxZoom as maxZoom, flowMinZoom as minZoom, useKeyboardView, useViewportMobile, ZoomControls, } from '../internal/flow.js';
|
|
8
|
+
import { Badge } from './badge.js';
|
|
9
|
+
export const schemaTableStateNames = ['new', 'changed', 'unchanged', 'linked'];
|
|
10
|
+
export const schemaChangeNames = ['added', 'changed', 'removed'];
|
|
11
|
+
export const schemaDiagramLayoutNames = ['auto', 'horizontal', 'vertical'];
|
|
21
12
|
const tableWidth = 264;
|
|
22
13
|
const columnGap = 80;
|
|
23
14
|
const rowGap = 48;
|
|
24
15
|
const fitOptions = { padding: 0.15, maxZoom: 1 };
|
|
25
|
-
const tableHeight = (table) => 44 +
|
|
26
|
-
(table.fields.length === 0
|
|
27
|
-
? 32
|
|
28
|
-
: table.fields.reduce((sum, field) => sum + (field.detail ? 48 : 32), 0));
|
|
16
|
+
const tableHeight = (table) => 44 + (table.fields.length === 0 ? 32 : table.fields.reduce((sum, field) => sum + (field.detail ? 48 : 32), 0));
|
|
29
17
|
const stateBadge = {
|
|
30
|
-
new: { label:
|
|
31
|
-
changed: { label:
|
|
32
|
-
linked: { label:
|
|
18
|
+
new: { label: 'New', variant: 'success' },
|
|
19
|
+
changed: { label: 'Changed', variant: 'warning' },
|
|
20
|
+
linked: { label: 'Existing', variant: 'secondary' },
|
|
33
21
|
unchanged: null,
|
|
34
22
|
};
|
|
35
23
|
/** Referenced tables sit one column right of (or below) the tables that link to them. */
|
|
36
24
|
function layout(tables, links, direction) {
|
|
37
25
|
const node = (table, x, y) => ({
|
|
38
26
|
id: table.id,
|
|
39
|
-
type:
|
|
27
|
+
type: 'table',
|
|
40
28
|
position: { x, y },
|
|
41
29
|
data: { table, direction },
|
|
42
|
-
ariaRole:
|
|
30
|
+
ariaRole: 'group',
|
|
43
31
|
ariaLabel: `${table.label} table`,
|
|
44
|
-
domAttributes: {
|
|
45
|
-
sourcePosition: direction ===
|
|
46
|
-
targetPosition: direction ===
|
|
32
|
+
domAttributes: { 'aria-roledescription': 'table card' },
|
|
33
|
+
sourcePosition: direction === 'vertical' ? Position.Bottom : Position.Right,
|
|
34
|
+
targetPosition: direction === 'vertical' ? Position.Top : Position.Left,
|
|
47
35
|
});
|
|
48
|
-
if (direction ===
|
|
36
|
+
if (direction === 'vertical') {
|
|
49
37
|
const ordered = [];
|
|
50
38
|
const seen = new Set();
|
|
51
39
|
const add = (table) => {
|
|
@@ -56,24 +44,22 @@ function layout(tables, links, direction) {
|
|
|
56
44
|
};
|
|
57
45
|
for (const link of links)
|
|
58
46
|
for (const id of [link.source, link.target])
|
|
59
|
-
add(tables.find(
|
|
47
|
+
add(tables.find(table => table.id === id));
|
|
60
48
|
for (const table of tables)
|
|
61
49
|
add(table);
|
|
62
50
|
let y = 0;
|
|
63
|
-
return ordered.map(
|
|
51
|
+
return ordered.map(table => {
|
|
64
52
|
const placed = node(table, 0, y);
|
|
65
53
|
y += tableHeight(table) + rowGap;
|
|
66
54
|
return placed;
|
|
67
55
|
});
|
|
68
56
|
}
|
|
69
|
-
const depth = new Map(tables.map(
|
|
57
|
+
const depth = new Map(tables.map(table => [table.id, 0]));
|
|
70
58
|
for (let pass = 0; pass < tables.length; pass++) {
|
|
71
59
|
let moved = false;
|
|
72
60
|
for (const link of links) {
|
|
73
61
|
const next = (depth.get(link.source) ?? 0) + 1;
|
|
74
|
-
if (link.source !== link.target &&
|
|
75
|
-
next > (depth.get(link.target) ?? 0) &&
|
|
76
|
-
next < tables.length) {
|
|
62
|
+
if (link.source !== link.target && next > (depth.get(link.target) ?? 0) && next < tables.length) {
|
|
77
63
|
depth.set(link.target, next);
|
|
78
64
|
moved = true;
|
|
79
65
|
}
|
|
@@ -82,7 +68,7 @@ function layout(tables, links, direction) {
|
|
|
82
68
|
break;
|
|
83
69
|
}
|
|
84
70
|
const columns = new Map();
|
|
85
|
-
return tables.map(
|
|
71
|
+
return tables.map(table => {
|
|
86
72
|
const column = depth.get(table.id) ?? 0;
|
|
87
73
|
const y = columns.get(column) ?? 0;
|
|
88
74
|
columns.set(column, y + tableHeight(table) + rowGap);
|
|
@@ -91,8 +77,8 @@ function layout(tables, links, direction) {
|
|
|
91
77
|
}
|
|
92
78
|
function TableCard({ data: { table, direction } }) {
|
|
93
79
|
const badge = stateBadge[table.state];
|
|
94
|
-
const vertical = direction ===
|
|
95
|
-
return (_jsxs("section", { "data-slot": "schema-table", "data-state": table.state, className: "sprout-schema-table", children: [_jsx(Handle, { type: "target", position: vertical ? Position.Top : Position.Left, isConnectable: false, className: "sprout-schema-handle sprout-schema-handle-target" }), _jsxs("header", { className: "sprout-schema-table-header", children: [_jsx("h3", { className: "sprout-schema-table-title", title: table.label, children: table.label }), badge && _jsx(Badge, { variant: badge.variant, children: badge.label })] }), table.fields.length === 0 ? (_jsx("p", { className: "sprout-schema-table-empty", children: table.state ===
|
|
80
|
+
const vertical = direction === 'vertical';
|
|
81
|
+
return (_jsxs("section", { "data-slot": "schema-table", "data-state": table.state, className: "sprout-schema-table", children: [_jsx(Handle, { type: "target", position: vertical ? Position.Top : Position.Left, isConnectable: false, className: "sprout-schema-handle sprout-schema-handle-target" }), _jsxs("header", { className: "sprout-schema-table-header", children: [_jsx("h3", { className: "sprout-schema-table-title", title: table.label, children: table.label }), badge && _jsx(Badge, { variant: badge.variant, children: badge.label })] }), table.fields.length === 0 ? (_jsx("p", { className: "sprout-schema-table-empty", children: table.state === 'linked' ? 'Fields not shown' : 'No fields' })) : (_jsx("ul", { className: "sprout-schema-fields", children: table.fields.map(field => (_jsxs("li", { "data-slot": "schema-field", "data-change": field.change, className: "sprout-schema-field", children: [_jsxs("div", { className: "sprout-schema-field-line", children: [_jsx("span", { className: "sprout-schema-field-key", children: field.unique && _jsx(Key, { size: 11, "aria-label": "Unique", role: "img" }) }), _jsxs("span", { className: "sprout-schema-field-name", title: field.label, children: [field.label, field.required && (_jsxs("span", { className: "sprout-schema-field-required", children: [_jsx("span", { "aria-hidden": "true", children: " *" }), _jsx("span", { className: "sprout-schema-sr-only", children: ", required" })] }))] }), _jsx("span", { className: "sprout-schema-field-type", children: field.type }), field.change && _jsxs("span", { className: "sprout-schema-sr-only", children: [", ", field.change] })] }), field.detail && (_jsx("p", { className: "sprout-schema-field-detail", title: field.detail, children: field.detail })), _jsx(Handle, { id: field.id, type: "source", position: vertical ? Position.Bottom : Position.Right, isConnectable: false, className: "sprout-schema-handle" })] }, field.id))) }))] }));
|
|
96
82
|
}
|
|
97
83
|
function LinkLine({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data, }) {
|
|
98
84
|
const [path, labelX, labelY] = getSmoothStepPath({
|
|
@@ -111,32 +97,32 @@ function LinkLine({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targ
|
|
|
111
97
|
}
|
|
112
98
|
const nodeTypes = { table: TableCard };
|
|
113
99
|
const edgeTypes = { link: LinkLine };
|
|
114
|
-
const keyboardHint =
|
|
100
|
+
const keyboardHint = 'Arrow keys pan, plus and minus zoom, and 0 fits the diagram. Tab moves between tables.';
|
|
115
101
|
function DiagramFlow({ nodes, edges, direction, label, hintId, }) {
|
|
116
102
|
const onKeyDown = useKeyboardView(fitOptions);
|
|
117
103
|
return (_jsxs(ReactFlow, { className: "sprout-schema-flow", "data-slot": "schema-diagram-viewport", "aria-label": label, "aria-describedby": hintId, tabIndex: 0, onKeyDown: onKeyDown, nodes: nodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, fitView: true, fitViewOptions: fitOptions, minZoom: minZoom, maxZoom: maxZoom, nodesConnectable: false, elementsSelectable: false, edgesFocusable: false, ariaLabelConfig: {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}, proOptions: { hideAttribution: true }, children: [_jsx(Background, { gap: 16, size: 1 }), _jsx(FitOnResize, { nodes: nodes, fit: fitOptions }), _jsx(ZoomControls, { position: direction ===
|
|
104
|
+
'node.a11yDescription.default': keyboardHint,
|
|
105
|
+
'node.a11yDescription.keyboardDisabled': keyboardHint,
|
|
106
|
+
}, proOptions: { hideAttribution: true }, children: [_jsx(Background, { gap: 16, size: 1 }), _jsx(FitOnResize, { nodes: nodes, fit: fitOptions }), _jsx(ZoomControls, { position: direction === 'vertical' ? 'top-right' : 'bottom-right', fit: fitOptions, className: "sprout-schema-controls", slot: "schema-diagram-controls" })] }));
|
|
121
107
|
}
|
|
122
108
|
/**
|
|
123
109
|
* A pan-and-zoom diagram of tables, their fields, and the links between them,
|
|
124
110
|
* with proposed changes marked on each table and field.
|
|
125
111
|
*/
|
|
126
|
-
export function SchemaDiagram({ tables, links, label, layout: layoutName =
|
|
112
|
+
export function SchemaDiagram({ tables, links, label, layout: layoutName = 'auto', className, ...props }) {
|
|
127
113
|
const mobile = useViewportMobile();
|
|
128
|
-
const direction = layoutName ===
|
|
114
|
+
const direction = layoutName === 'auto' ? (mobile ? 'vertical' : 'horizontal') : layoutName;
|
|
129
115
|
const hintId = useId();
|
|
130
116
|
const nodes = useMemo(() => layout(tables, links, direction), [tables, links, direction]);
|
|
131
117
|
const edges = useMemo(() => {
|
|
132
|
-
const names = new Map(tables.map(
|
|
118
|
+
const names = new Map(tables.map(table => [table.id, table]));
|
|
133
119
|
return links.map((link) => {
|
|
134
120
|
const source = names.get(link.source);
|
|
135
|
-
const field = source?.fields.find(
|
|
136
|
-
const from = `${source?.label ?? link.source}${field ? ` ${field.label}` :
|
|
121
|
+
const field = source?.fields.find(candidate => candidate.id === link.field);
|
|
122
|
+
const from = `${source?.label ?? link.source}${field ? ` ${field.label}` : ''}`;
|
|
137
123
|
return {
|
|
138
124
|
id: link.id,
|
|
139
|
-
type:
|
|
125
|
+
type: 'link',
|
|
140
126
|
source: link.source,
|
|
141
127
|
sourceHandle: link.field,
|
|
142
128
|
target: link.target,
|
|
@@ -145,9 +131,9 @@ export function SchemaDiagram({ tables, links, label, layout: layoutName = "auto
|
|
|
145
131
|
};
|
|
146
132
|
});
|
|
147
133
|
}, [tables, links]);
|
|
148
|
-
return (_jsxs("div", { ...props, role: "figure", "aria-label": label, "data-slot": "schema-diagram", "data-layout": direction, className: cn(
|
|
134
|
+
return (_jsxs("div", { ...props, role: "figure", "aria-label": label, "data-slot": "schema-diagram", "data-layout": direction, className: cn('sprout-schema-diagram', className), children: [_jsx("p", { id: hintId, className: "sprout-schema-sr-only", children: keyboardHint }), _jsx(ReactFlowProvider, { children: _jsx(DiagramFlow, { nodes: nodes, edges: edges, direction: direction, label: label, hintId: hintId }) }, direction)] }));
|
|
149
135
|
}
|
|
150
136
|
/** Explains the change colors, the unique key, and the required mark. */
|
|
151
137
|
export function SchemaLegend({ className, ...props }) {
|
|
152
|
-
return (_jsxs("ul", { "aria-label": "Legend", "data-slot": "schema-legend", ...props, className: cn(
|
|
138
|
+
return (_jsxs("ul", { "aria-label": "Legend", "data-slot": "schema-legend", ...props, className: cn('sprout-schema-legend', className), children: [schemaChangeNames.map(change => (_jsxs("li", { className: "sprout-schema-legend-item", children: [_jsx("span", { "aria-hidden": "true", "data-change": change, className: "sprout-schema-legend-swatch" }), change[0].toUpperCase() + change.slice(1)] }, change))), _jsxs("li", { className: "sprout-schema-legend-item", children: [_jsx(Key, { size: 11, "aria-hidden": "true" }), "Unique"] }), _jsx("li", { className: "sprout-schema-legend-item", children: "* Required" })] }));
|
|
153
139
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ScrollArea as BaseScrollArea } from
|
|
2
|
-
export declare const scrollAreaSizeNames: readonly ["
|
|
1
|
+
import { ScrollArea as BaseScrollArea } from '@base-ui/react/scroll-area';
|
|
2
|
+
export declare const scrollAreaSizeNames: readonly ["sm", "md"];
|
|
3
3
|
export declare const scrollAreaVariantNames: readonly ["plain", "table"];
|
|
4
4
|
export declare const scrollAreaOrientationNames: readonly ["vertical", "horizontal", "both"];
|
|
5
5
|
export type ScrollAreaSize = (typeof scrollAreaSizeNames)[number];
|
|
6
6
|
export type ScrollAreaVariant = (typeof scrollAreaVariantNames)[number];
|
|
7
7
|
export type ScrollAreaOrientation = (typeof scrollAreaOrientationNames)[number];
|
|
8
8
|
export interface ScrollAreaProps extends BaseScrollArea.Root.Props {
|
|
9
|
-
/** `"sm"` is 10rem tall, `"md"` is 16rem tall.
|
|
9
|
+
/** `"sm"` is 10rem tall, `"md"` is 16rem tall. Leave it out to follow the content or your className. */
|
|
10
10
|
size?: ScrollAreaSize;
|
|
11
11
|
/** `"table"` adds a bordered surface, caps the height at 60dvh, and makes the viewport a labeled region. */
|
|
12
12
|
variant?: ScrollAreaVariant;
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { ScrollArea as BaseScrollArea } from
|
|
4
|
-
import { stateClassName } from
|
|
5
|
-
export const scrollAreaSizeNames = [
|
|
6
|
-
export const scrollAreaVariantNames = [
|
|
7
|
-
export const scrollAreaOrientationNames = [
|
|
8
|
-
"vertical",
|
|
9
|
-
"horizontal",
|
|
10
|
-
"both",
|
|
11
|
-
];
|
|
3
|
+
import { ScrollArea as BaseScrollArea } from '@base-ui/react/scroll-area';
|
|
4
|
+
import { stateClassName } from '../internal/classes.js';
|
|
5
|
+
export const scrollAreaSizeNames = ['sm', 'md'];
|
|
6
|
+
export const scrollAreaVariantNames = ['plain', 'table'];
|
|
7
|
+
export const scrollAreaOrientationNames = ['vertical', 'horizontal', 'both'];
|
|
12
8
|
/** A scrolling region with thin, theme-aware scrollbars that keeps native keyboard and wheel scrolling. */
|
|
13
|
-
export function ScrollArea({ className, children, size
|
|
14
|
-
return (_jsxs(BaseScrollArea.Root, { "data-slot": "scroll-area", "data-size": size, "data-variant": variant, className: stateClassName(
|
|
9
|
+
export function ScrollArea({ className, children, size, variant = 'plain', orientation = 'vertical', viewportLabel, ...props }) {
|
|
10
|
+
return (_jsxs(BaseScrollArea.Root, { "data-slot": "scroll-area", "data-size": size, "data-variant": variant, className: stateClassName('sprout-scroll-area', className), ...props, children: [_jsx(BaseScrollArea.Viewport, { "data-slot": "scroll-area-viewport", role: variant === 'table' ? 'region' : undefined, "aria-label": viewportLabel, className: "sprout-scroll-area-viewport", children: children }), orientation !== 'horizontal' && _jsx(ScrollBar, {}), orientation !== 'vertical' && _jsx(ScrollBar, { orientation: "horizontal" }), _jsx(BaseScrollArea.Corner, { "data-slot": "scroll-area-corner", className: "sprout-scroll-area-corner" })] }));
|
|
15
11
|
}
|
|
16
12
|
/** One scrollbar track and thumb. `ScrollArea` draws these for you from `orientation`. */
|
|
17
|
-
export function ScrollBar({ className, orientation =
|
|
18
|
-
return (_jsx(BaseScrollArea.Scrollbar, { "data-slot": "scroll-area-scrollbar", orientation: orientation, className: stateClassName(
|
|
13
|
+
export function ScrollBar({ className, orientation = 'vertical', ...props }) {
|
|
14
|
+
return (_jsx(BaseScrollArea.Scrollbar, { "data-slot": "scroll-area-scrollbar", orientation: orientation, className: stateClassName('sprout-scroll-area-scrollbar', className), ...props, children: _jsx(BaseScrollArea.Thumb, { "data-slot": "scroll-area-thumb", className: "sprout-scroll-area-thumb" }) }));
|
|
19
15
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ReactNode, type Ref } from
|
|
2
|
-
import { type DialogContentProps } from
|
|
1
|
+
import { type ReactNode, type Ref } from 'react';
|
|
2
|
+
import { type DialogContentProps } from './dialog.js';
|
|
3
3
|
export interface SearchDialogProps {
|
|
4
4
|
open: boolean;
|
|
5
5
|
onOpenChange: (open: boolean) => void;
|
|
@@ -9,7 +9,7 @@ export interface SearchDialogProps {
|
|
|
9
9
|
description: string;
|
|
10
10
|
className?: string;
|
|
11
11
|
/** Where the portal renders. Defaults to `document.body`. */
|
|
12
|
-
container?: DialogContentProps[
|
|
12
|
+
container?: DialogContentProps['container'];
|
|
13
13
|
children: ReactNode;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
@@ -43,7 +43,7 @@ export interface SearchFilterProps {
|
|
|
43
43
|
children: ReactNode;
|
|
44
44
|
}
|
|
45
45
|
/** A pressable filter chip. */
|
|
46
|
-
export declare function SearchFilter({ pressed, onPressedChange, icon, children
|
|
46
|
+
export declare function SearchFilter({ pressed, onPressedChange, icon, children }: SearchFilterProps): import("react").JSX.Element;
|
|
47
47
|
export interface SearchListProps {
|
|
48
48
|
/** Accessible name of the results listbox. */
|
|
49
49
|
label: string;
|
|
@@ -79,7 +79,7 @@ export interface SearchItemProps {
|
|
|
79
79
|
trailing?: ReactNode;
|
|
80
80
|
}
|
|
81
81
|
/** One result. The active item shows an Enter key hint. */
|
|
82
|
-
export declare function SearchItem({ value, onSelect, media, title, meta, detail, trailing
|
|
82
|
+
export declare function SearchItem({ value, onSelect, media, title, meta, detail, trailing }: SearchItemProps): import("react").JSX.Element;
|
|
83
83
|
export interface SearchEmptyProps {
|
|
84
84
|
/** One to three icons shown as fanned tiles over a faint grid. */
|
|
85
85
|
media?: ReactNode;
|
|
@@ -89,7 +89,7 @@ export interface SearchEmptyProps {
|
|
|
89
89
|
action?: ReactNode;
|
|
90
90
|
}
|
|
91
91
|
/** Fills the list when nothing matches and is announced as a status. */
|
|
92
|
-
export declare function SearchEmpty({ media, title, description, action
|
|
92
|
+
export declare function SearchEmpty({ media, title, description, action }: SearchEmptyProps): import("react").JSX.Element;
|
|
93
93
|
export interface SearchFooterProps {
|
|
94
94
|
children: ReactNode;
|
|
95
95
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import { Children, Fragment, isValidElement
|
|
4
|
-
import { X } from
|
|
5
|
-
import { cn } from
|
|
6
|
-
import { Button } from
|
|
7
|
-
import { Kbd } from
|
|
8
|
-
import { Toggle } from
|
|
9
|
-
import { Command, CommandGroup, CommandInput, CommandItem, CommandList
|
|
10
|
-
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogTitle, } from
|
|
3
|
+
import { Children, Fragment, isValidElement } from 'react';
|
|
4
|
+
import { X } from 'reicon-react/icons/X';
|
|
5
|
+
import { cn } from '../internal/classes.js';
|
|
6
|
+
import { Button } from './button.js';
|
|
7
|
+
import { Kbd } from './kbd.js';
|
|
8
|
+
import { Toggle } from './toggle.js';
|
|
9
|
+
import { Command, CommandGroup, CommandInput, CommandItem, CommandList } from './command.js';
|
|
10
|
+
import { Dialog, DialogClose, DialogContent, DialogDescription, DialogTitle, } from './dialog.js';
|
|
11
11
|
/**
|
|
12
12
|
* A wide search palette pinned near the top of the viewport. You filter and
|
|
13
13
|
* group results yourself; arrow keys wrap and Enter opens the active item.
|
|
14
14
|
*/
|
|
15
15
|
export function SearchDialog({ open, onOpenChange, title, description, className, container, children, }) {
|
|
16
|
-
return (_jsx(Dialog, { open: open, onOpenChange:
|
|
16
|
+
return (_jsx(Dialog, { open: open, onOpenChange: next => onOpenChange(next), children: _jsxs(DialogContent, { "data-slot": "search-dialog", placement: "top", showCloseButton: false, container: container, className: cn('sprout-search-dialog', className), children: [_jsx(DialogTitle, { className: "sprout-command-sr-only", children: title }), _jsx(DialogDescription, { className: "sprout-command-sr-only", children: description }), _jsx(Command, { shouldFilter: false, loop: true, label: title, className: "sprout-search-command", children: children })] }) }));
|
|
17
17
|
}
|
|
18
18
|
/** The search field with a leading magnifier and a trailing close button. */
|
|
19
|
-
export function SearchInput({ ref, value, onValueChange, placeholder, label, closeLabel =
|
|
19
|
+
export function SearchInput({ ref, value, onValueChange, placeholder, label, closeLabel = 'Close search', }) {
|
|
20
20
|
return (_jsxs("div", { "data-slot": "search-input", className: "sprout-search-input", children: [_jsx(CommandInput, { ref: ref, value: value, onValueChange: onValueChange, placeholder: placeholder, "aria-label": label }), _jsx(DialogClose, { render: _jsx(Button, { variant: "ghost", size: "icon-sm", "aria-label": closeLabel }), children: _jsx(X, { size: 16, "aria-hidden": "true" }) })] }));
|
|
21
21
|
}
|
|
22
22
|
/** A row of toggle filters under the input. It scrolls sideways when narrow. */
|
|
@@ -24,8 +24,8 @@ export function SearchFilters({ label, children }) {
|
|
|
24
24
|
return (_jsx("div", { "data-slot": "search-filters", role: "group", "aria-label": label, className: "sprout-search-filters", children: children }));
|
|
25
25
|
}
|
|
26
26
|
/** A pressable filter chip. */
|
|
27
|
-
export function SearchFilter({ pressed, onPressedChange, icon, children
|
|
28
|
-
return (_jsxs(Toggle, { "data-slot": "search-filter", variant: "outline", size: "sm", pressed: pressed, onPressedChange:
|
|
27
|
+
export function SearchFilter({ pressed, onPressedChange, icon, children }) {
|
|
28
|
+
return (_jsxs(Toggle, { "data-slot": "search-filter", variant: "outline", size: "sm", pressed: pressed, onPressedChange: next => onPressedChange(next), children: [icon, children] }));
|
|
29
29
|
}
|
|
30
30
|
/** The scrolling results area. It keeps a steady height so typing does not resize the dialog. */
|
|
31
31
|
export function SearchList({ label, children }) {
|
|
@@ -35,14 +35,14 @@ export function SearchList({ label, children }) {
|
|
|
35
35
|
export function SearchGroup({ heading, count, children }) {
|
|
36
36
|
if (count === 0)
|
|
37
37
|
return null;
|
|
38
|
-
return (_jsx(CommandGroup, { className: "sprout-search-group", heading: _jsxs("span", { className: "sprout-search-group-heading", children: [heading,
|
|
38
|
+
return (_jsx(CommandGroup, { className: "sprout-search-group", heading: _jsxs("span", { className: "sprout-search-group-heading", children: [heading, ' ', _jsx("span", { "data-slot": "search-group-count", className: "sprout-search-group-count", children: count })] }), children: children }));
|
|
39
39
|
}
|
|
40
40
|
/** A muted icon tile for an item's `media`. */
|
|
41
41
|
export function SearchItemIcon({ children }) {
|
|
42
42
|
return (_jsx("span", { "data-slot": "search-item-icon", className: "sprout-search-item-icon", children: children }));
|
|
43
43
|
}
|
|
44
44
|
/** One result. The active item shows an Enter key hint. */
|
|
45
|
-
export function SearchItem({ value, onSelect, media, title, meta, detail, trailing
|
|
45
|
+
export function SearchItem({ value, onSelect, media, title, meta, detail, trailing }) {
|
|
46
46
|
return (_jsxs(CommandItem, { value: value, onSelect: () => onSelect(), className: "sprout-search-item", children: [_jsx("span", { "data-slot": "search-item-media", className: "sprout-search-item-media", children: media }), _jsxs("span", { className: "sprout-search-item-text", children: [_jsxs("span", { className: "sprout-search-item-line", children: [_jsx("span", { "data-slot": "search-item-title", className: "sprout-search-item-title", children: title }), meta && (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": "true", className: "sprout-search-item-dot", children: "\u00B7" }), _jsx("span", { "data-slot": "search-item-meta", className: "sprout-search-item-meta", children: meta })] }))] }), detail && (_jsx("span", { "data-slot": "search-item-detail", className: "sprout-search-item-detail", children: detail }))] }), trailing && (_jsx("span", { "data-slot": "search-item-trailing", className: "sprout-search-item-trailing", children: trailing })), _jsx(Kbd, { variant: "outline", "aria-hidden": "true", className: "sprout-search-item-enter", children: "\u21B5" })] }));
|
|
47
47
|
}
|
|
48
48
|
function tiles(media) {
|
|
@@ -52,7 +52,7 @@ function tiles(media) {
|
|
|
52
52
|
return Children.toArray(nodes).map((node, index) => (_jsx("span", { "data-slot": "search-empty-tile", className: "sprout-search-empty-tile", children: node }, index)));
|
|
53
53
|
}
|
|
54
54
|
/** Fills the list when nothing matches and is announced as a status. */
|
|
55
|
-
export function SearchEmpty({ media, title, description, action
|
|
55
|
+
export function SearchEmpty({ media, title, description, action }) {
|
|
56
56
|
return (_jsxs("div", { "data-slot": "search-empty", role: "status", className: "sprout-search-empty", children: [media && (_jsx("div", { "aria-hidden": "true", className: "sprout-search-empty-media", children: _jsx("span", { className: "sprout-search-empty-tiles", children: tiles(media) }) })), _jsxs("div", { className: "sprout-search-empty-text", children: [_jsx("p", { className: "sprout-search-empty-title", children: title }), _jsx("p", { className: "sprout-search-empty-description", children: description })] }), action] }));
|
|
57
57
|
}
|
|
58
58
|
/** A tinted strip of keyboard hints. Hidden below 640px, where there is no keyboard to hint at. */
|
|
@@ -14,4 +14,4 @@ export interface SearchFieldProps {
|
|
|
14
14
|
* that appears once there is text. Clear and Escape empty the value and keep
|
|
15
15
|
* focus in the input. A disabled ancestor `fieldset` disables both controls.
|
|
16
16
|
*/
|
|
17
|
-
export declare function SearchField({ label, value, onChange, placeholder, maxLength, id, className
|
|
17
|
+
export declare function SearchField({ label, value, onChange, placeholder, maxLength, id, className }: SearchFieldProps): import("react").JSX.Element;
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useRef } from
|
|
4
|
-
import { Search } from
|
|
5
|
-
import { X } from
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput
|
|
3
|
+
import { useRef } from 'react';
|
|
4
|
+
import { Search } from 'reicon-react/icons/Search';
|
|
5
|
+
import { X } from 'reicon-react/icons/X';
|
|
6
|
+
import { cn } from '../internal/classes.js';
|
|
7
|
+
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from './input-group.js';
|
|
8
8
|
/**
|
|
9
9
|
* An `InputGroup` preset for search: a leading magnifier and a clear button
|
|
10
10
|
* that appears once there is text. Clear and Escape empty the value and keep
|
|
11
11
|
* focus in the input. A disabled ancestor `fieldset` disables both controls.
|
|
12
12
|
*/
|
|
13
|
-
export function SearchField({ label, value, onChange, placeholder, maxLength, id, className
|
|
13
|
+
export function SearchField({ label, value, onChange, placeholder, maxLength, id, className }) {
|
|
14
14
|
const input = useRef(null);
|
|
15
15
|
// The first Escape clears the text; with no text it reaches popovers and dialogs.
|
|
16
16
|
const onKeyDown = (event) => {
|
|
17
|
-
if (event.key !==
|
|
17
|
+
if (event.key !== 'Escape' || !value)
|
|
18
18
|
return;
|
|
19
19
|
event.preventDefault();
|
|
20
20
|
event.stopPropagation();
|
|
21
|
-
onChange(
|
|
21
|
+
onChange('');
|
|
22
22
|
};
|
|
23
|
-
return (_jsxs(InputGroup, { "data-slot": "search-field", className: cn(
|
|
24
|
-
onChange(
|
|
23
|
+
return (_jsxs(InputGroup, { "data-slot": "search-field", className: cn('sprout-search-field', className), children: [_jsx(InputGroupAddon, { children: _jsx(Search, { size: 16, "aria-hidden": "true" }) }), _jsx(InputGroupInput, { ref: input, id: id, type: "search", "aria-label": label, maxLength: maxLength, value: value, placeholder: placeholder ?? label, autoComplete: "off", spellCheck: false, onChange: event => onChange(event.currentTarget.value), onKeyDown: onKeyDown }), value && (_jsx(InputGroupAddon, { align: "inline-end", children: _jsx(InputGroupButton, { "data-slot": "search-field-clear", size: "icon", "aria-label": "Clear search", className: "sprout-search-field-clear", onClick: () => {
|
|
24
|
+
onChange('');
|
|
25
25
|
input.current?.focus();
|
|
26
26
|
}, children: _jsx(X, { size: 14, "aria-hidden": "true" }) }) }))] }));
|
|
27
27
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Select as SelectPrimitive } from
|
|
2
|
-
export declare const selectTriggerSizeNames: readonly ["
|
|
1
|
+
import { Select as SelectPrimitive } from '@base-ui/react/select';
|
|
2
|
+
export declare const selectTriggerSizeNames: readonly ["md", "sm", "lg"];
|
|
3
3
|
export declare const selectTriggerWidthNames: readonly ["fit", "full"];
|
|
4
4
|
export type SelectTriggerSize = (typeof selectTriggerSizeNames)[number];
|
|
5
5
|
export type SelectTriggerWidth = (typeof selectTriggerWidthNames)[number];
|
|
@@ -19,20 +19,16 @@ export type SelectValueProps = SelectPrimitive.Value.Props;
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function SelectValue({ className, ...props }: SelectValueProps): import("react").JSX.Element;
|
|
21
21
|
export interface SelectTriggerProps extends SelectPrimitive.Trigger.Props {
|
|
22
|
-
/**
|
|
23
|
-
* `default` is 32px for forms. `sm` is 28px for toolbars, filters, table
|
|
24
|
-
* rows, and inline sentences. `calendar` is a 32px control with small text
|
|
25
|
-
* for calendar headers.
|
|
26
|
-
*/
|
|
22
|
+
/** `sm` is 28px, `md` is 32px (`--sprout-control-height`), and `lg` is 36px. */
|
|
27
23
|
size?: SelectTriggerSize;
|
|
28
24
|
/** `fit` sizes to the value. `full` fills the parent, as in form fields. */
|
|
29
25
|
width?: SelectTriggerWidth;
|
|
30
26
|
}
|
|
31
27
|
export declare function SelectTrigger({ className, size, width, children, ...rest }: SelectTriggerProps): import("react").JSX.Element;
|
|
32
|
-
type PositionerProps = Pick<SelectPrimitive.Positioner.Props,
|
|
28
|
+
type PositionerProps = Pick<SelectPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset' | 'alignItemWithTrigger' | 'collisionPadding' | 'collisionAvoidance' | 'sticky' | 'positionMethod'>;
|
|
33
29
|
export interface SelectContentProps extends SelectPrimitive.Popup.Props, PositionerProps {
|
|
34
30
|
/** Where the portal renders. Defaults to `document.body`. */
|
|
35
|
-
container?: SelectPrimitive.Portal.Props[
|
|
31
|
+
container?: SelectPrimitive.Portal.Props['container'];
|
|
36
32
|
}
|
|
37
33
|
/**
|
|
38
34
|
* The list surface. It renders its own portal, positioner, list, and scroll
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Select as SelectPrimitive } from
|
|
4
|
-
import { Check } from
|
|
5
|
-
import { ChevronDown } from
|
|
6
|
-
import { ChevronUp } from
|
|
7
|
-
import { cn, stateClassName } from
|
|
8
|
-
import { useFieldControl } from
|
|
9
|
-
export const selectTriggerSizeNames = [
|
|
10
|
-
export const selectTriggerWidthNames = [
|
|
3
|
+
import { Select as SelectPrimitive } from '@base-ui/react/select';
|
|
4
|
+
import { Check } from 'reicon-react/icons/Check';
|
|
5
|
+
import { ChevronDown } from 'reicon-react/icons/ChevronDown';
|
|
6
|
+
import { ChevronUp } from 'reicon-react/icons/ChevronUp';
|
|
7
|
+
import { cn, stateClassName } from '../internal/classes.js';
|
|
8
|
+
import { useFieldControl } from './field.js';
|
|
9
|
+
export const selectTriggerSizeNames = ['md', 'sm', 'lg'];
|
|
10
|
+
export const selectTriggerWidthNames = ['fit', 'full'];
|
|
11
11
|
/**
|
|
12
12
|
* Holds the value and open state. It takes every Base UI select root prop,
|
|
13
13
|
* including `items`, `value`, `defaultValue`, `onValueChange`, `disabled`,
|
|
@@ -15,43 +15,43 @@ export const selectTriggerWidthNames = ["fit", "full"];
|
|
|
15
15
|
*/
|
|
16
16
|
export const Select = SelectPrimitive.Root;
|
|
17
17
|
export function SelectGroup({ className, ...props }) {
|
|
18
|
-
return (_jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props, className: stateClassName(
|
|
18
|
+
return (_jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props, className: stateClassName('sprout-select-group', className) }));
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Shows the chosen item. Pass `placeholder` for the empty state, or children
|
|
22
22
|
* to show a custom label such as a name looked up from the value.
|
|
23
23
|
*/
|
|
24
24
|
export function SelectValue({ className, ...props }) {
|
|
25
|
-
return (_jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props, className: stateClassName(
|
|
25
|
+
return (_jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props, className: stateClassName('sprout-select-value', className) }));
|
|
26
26
|
}
|
|
27
|
-
export function SelectTrigger({ className, size =
|
|
27
|
+
export function SelectTrigger({ className, size = 'md', width = 'fit', children, ...rest }) {
|
|
28
28
|
const props = useFieldControl(rest);
|
|
29
|
-
return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, "data-width": width, ...props, className: stateClassName(cn(
|
|
29
|
+
return (_jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, "data-width": width, ...props, className: stateClassName(cn('sprout-select-trigger', `sprout-select-trigger-${size}`, `sprout-select-trigger-${width}`), className), children: [children, _jsx(SelectPrimitive.Icon, { className: "sprout-select-icon", children: _jsx(ChevronDown, { "aria-hidden": "true" }) })] }));
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* The list surface. It renders its own portal, positioner, list, and scroll
|
|
33
33
|
* arrows. By default the chosen item lines up over the trigger; pass
|
|
34
34
|
* `alignItemWithTrigger={false}` to open below it instead.
|
|
35
35
|
*/
|
|
36
|
-
export function SelectContent({ side =
|
|
37
|
-
return (_jsx(SelectPrimitive.Portal, { container: container, children: _jsx(SelectPrimitive.Positioner, { className: "sprout-select-positioner", side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, alignItemWithTrigger: alignItemWithTrigger, collisionPadding: collisionPadding, collisionAvoidance: collisionAvoidance, sticky: sticky, positionMethod: positionMethod, children: _jsxs(SelectPrimitive.Popup, { "data-slot": "select-content", "data-align-trigger": alignItemWithTrigger, ...props, className: stateClassName(
|
|
36
|
+
export function SelectContent({ side = 'bottom', sideOffset = 4, align = 'center', alignOffset = 0, alignItemWithTrigger = true, collisionPadding = 8, collisionAvoidance, sticky, positionMethod, container, className, children, ...props }) {
|
|
37
|
+
return (_jsx(SelectPrimitive.Portal, { container: container, children: _jsx(SelectPrimitive.Positioner, { className: "sprout-select-positioner", side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, alignItemWithTrigger: alignItemWithTrigger, collisionPadding: collisionPadding, collisionAvoidance: collisionAvoidance, sticky: sticky, positionMethod: positionMethod, children: _jsxs(SelectPrimitive.Popup, { "data-slot": "select-content", "data-align-trigger": alignItemWithTrigger, ...props, className: stateClassName('sprout-select-content', className), children: [_jsx(SelectScrollUpButton, {}), _jsx(SelectPrimitive.List, { className: "sprout-select-list", children: children }), _jsx(SelectScrollDownButton, {})] }) }) }));
|
|
38
38
|
}
|
|
39
39
|
export function SelectLabel({ className, ...props }) {
|
|
40
|
-
return (_jsx(SelectPrimitive.GroupLabel, { "data-slot": "select-label", ...props, className: stateClassName(
|
|
40
|
+
return (_jsx(SelectPrimitive.GroupLabel, { "data-slot": "select-label", ...props, className: stateClassName('sprout-select-label', className) }));
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* One choice. Children may hold an icon, rich content, or plain text. Long
|
|
44
44
|
* text wraps instead of being cut off.
|
|
45
45
|
*/
|
|
46
46
|
export function SelectItem({ className, children, ...props }) {
|
|
47
|
-
return (_jsxs(SelectPrimitive.Item, { "data-slot": "select-item", ...props, className: stateClassName(
|
|
47
|
+
return (_jsxs(SelectPrimitive.Item, { "data-slot": "select-item", ...props, className: stateClassName('sprout-select-item', className), children: [_jsx(SelectPrimitive.ItemText, { className: "sprout-select-item-text", children: children }), _jsx(SelectPrimitive.ItemIndicator, { className: "sprout-select-item-indicator", children: _jsx(Check, { "aria-hidden": "true" }) })] }));
|
|
48
48
|
}
|
|
49
49
|
export function SelectSeparator({ className, ...props }) {
|
|
50
|
-
return (_jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", ...props, className: stateClassName(
|
|
50
|
+
return (_jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", ...props, className: stateClassName('sprout-select-separator', className) }));
|
|
51
51
|
}
|
|
52
52
|
export function SelectScrollUpButton({ className, ...props }) {
|
|
53
|
-
return (_jsx(SelectPrimitive.ScrollUpArrow, { "data-slot": "select-scroll-up-button", ...props, className: stateClassName(
|
|
53
|
+
return (_jsx(SelectPrimitive.ScrollUpArrow, { "data-slot": "select-scroll-up-button", ...props, className: stateClassName('sprout-select-scroll-button sprout-select-scroll-up', className), children: _jsx(ChevronUp, { "aria-hidden": "true" }) }));
|
|
54
54
|
}
|
|
55
55
|
export function SelectScrollDownButton({ className, ...props }) {
|
|
56
|
-
return (_jsx(SelectPrimitive.ScrollDownArrow, { "data-slot": "select-scroll-down-button", ...props, className: stateClassName(
|
|
56
|
+
return (_jsx(SelectPrimitive.ScrollDownArrow, { "data-slot": "select-scroll-down-button", ...props, className: stateClassName('sprout-select-scroll-button sprout-select-scroll-down', className), children: _jsx(ChevronDown, { "aria-hidden": "true" }) }));
|
|
57
57
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type ComponentProps, type ReactNode } from
|
|
2
|
-
export interface SelectionSlotProps extends Omit<ComponentProps<
|
|
1
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
+
export interface SelectionSlotProps extends Omit<ComponentProps<'div'>, 'children'> {
|
|
3
3
|
/** Shows `selection` in place of `children`. */
|
|
4
4
|
active: boolean;
|
|
5
5
|
/** The toolbar for the current selection, such as a count and bulk actions. */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useLayoutEffect, useRef
|
|
4
|
-
import { cn } from
|
|
3
|
+
import { useLayoutEffect, useRef } from 'react';
|
|
4
|
+
import { cn } from '../internal/classes.js';
|
|
5
5
|
const tabbable = 'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]), [contenteditable="true"]';
|
|
6
6
|
function focusable(root) {
|
|
7
|
-
return Array.from(root?.querySelectorAll(tabbable) ?? []).find(
|
|
7
|
+
return Array.from(root?.querySelectorAll(tabbable) ?? []).find(node => !node.closest('[inert]') && node.getClientRects().length > 0);
|
|
8
8
|
}
|
|
9
9
|
function lost() {
|
|
10
10
|
const current = document.activeElement;
|
|
@@ -27,10 +27,7 @@ export function SelectionSlot({ active, selection, children, className, ...props
|
|
|
27
27
|
useLayoutEffect(() => {
|
|
28
28
|
if (active && !previous.current) {
|
|
29
29
|
const current = document.activeElement;
|
|
30
|
-
origin.current =
|
|
31
|
-
current instanceof HTMLElement && current !== document.body
|
|
32
|
-
? current
|
|
33
|
-
: null;
|
|
30
|
+
origin.current = current instanceof HTMLElement && current !== document.body ? current : null;
|
|
34
31
|
if (origin.current && tools.current?.contains(origin.current))
|
|
35
32
|
focusable(selected.current)?.focus({ preventScroll: true });
|
|
36
33
|
}
|
|
@@ -44,7 +41,7 @@ export function SelectionSlot({ active, selection, children, className, ...props
|
|
|
44
41
|
inside.current = false;
|
|
45
42
|
previous.current = active;
|
|
46
43
|
}, [active]);
|
|
47
|
-
return (_jsxs("div", { "data-slot": "selection-slot", "data-active": active || undefined, className: cn(
|
|
44
|
+
return (_jsxs("div", { "data-slot": "selection-slot", "data-active": active || undefined, className: cn('sprout-selection-slot', className), ...props, children: [_jsx("div", { ref: tools, "data-slot": "selection-slot-default", className: "sprout-selection-slot-layer", inert: active, "aria-hidden": active || undefined, children: children }), active && (_jsx("div", { ref: selected, onFocus: () => (inside.current = true), onBlur: event => {
|
|
48
45
|
// A null target means focus was dropped, as when the focused button is disabled.
|
|
49
46
|
const next = event.relatedTarget;
|
|
50
47
|
if (next && !event.currentTarget.contains(next))
|