@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,17 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from
|
|
4
|
-
import { ChevronLeft } from
|
|
5
|
-
import { ChevronRight } from
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { Button } from
|
|
8
|
-
export const carouselOrientationNames = [
|
|
9
|
-
export const carouselAlignNames = [
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
4
|
+
import { ChevronLeft } from 'reicon-react/icons/ChevronLeft';
|
|
5
|
+
import { ChevronRight } from 'reicon-react/icons/ChevronRight';
|
|
6
|
+
import { cn } from '../internal/classes.js';
|
|
7
|
+
import { Button } from './button.js';
|
|
8
|
+
export const carouselOrientationNames = ['horizontal', 'vertical'];
|
|
9
|
+
export const carouselAlignNames = ['start', 'center', 'end'];
|
|
10
10
|
const CarouselContext = createContext(null);
|
|
11
11
|
export function useCarousel() {
|
|
12
12
|
const context = useContext(CarouselContext);
|
|
13
13
|
if (!context)
|
|
14
|
-
throw new Error(
|
|
14
|
+
throw new Error('useCarousel must be used within a <Carousel />');
|
|
15
15
|
return context;
|
|
16
16
|
}
|
|
17
17
|
const typing = 'input, textarea, select, [contenteditable="true"]';
|
|
@@ -27,11 +27,7 @@ function measure(viewport, horizontal, align) {
|
|
|
27
27
|
const box = slide.getBoundingClientRect();
|
|
28
28
|
const start = (horizontal ? box.left - frame.left : box.top - frame.top) + position;
|
|
29
29
|
const length = horizontal ? box.width : box.height;
|
|
30
|
-
const target = align ===
|
|
31
|
-
? start
|
|
32
|
-
: align === "center"
|
|
33
|
-
? start + length / 2 - view / 2
|
|
34
|
-
: start + length - view;
|
|
30
|
+
const target = align === 'start' ? start : align === 'center' ? start + length / 2 - view / 2 : start + length - view;
|
|
35
31
|
snaps.push(Math.round(Math.min(max, Math.max(0, target))));
|
|
36
32
|
}
|
|
37
33
|
// Like a contained scroll: the first stop is the start and the last is the end.
|
|
@@ -56,9 +52,9 @@ const initialState = {
|
|
|
56
52
|
snapCount: 0,
|
|
57
53
|
viewportFocusable: false,
|
|
58
54
|
};
|
|
59
|
-
export function Carousel({ orientation =
|
|
60
|
-
const horizontal = orientation ===
|
|
61
|
-
const align = opts?.align ??
|
|
55
|
+
export function Carousel({ orientation = 'horizontal', opts, setApi, className, children, onKeyDownCapture, ...props }) {
|
|
56
|
+
const horizontal = orientation === 'horizontal';
|
|
57
|
+
const align = opts?.align ?? 'start';
|
|
62
58
|
const loop = opts?.loop ?? false;
|
|
63
59
|
const viewport = useRef(null);
|
|
64
60
|
const settings = useRef({ horizontal, align, loop });
|
|
@@ -79,7 +75,7 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
79
75
|
const api = apiRef.current;
|
|
80
76
|
if (!api)
|
|
81
77
|
return;
|
|
82
|
-
listeners.current.get(event)?.forEach(
|
|
78
|
+
listeners.current.get(event)?.forEach(listener => listener(api));
|
|
83
79
|
}, []);
|
|
84
80
|
const update = useCallback(() => {
|
|
85
81
|
const node = viewport.current;
|
|
@@ -102,7 +98,7 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
102
98
|
};
|
|
103
99
|
const changed = next.selectedIndex !== selected.current;
|
|
104
100
|
selected.current = next.selectedIndex;
|
|
105
|
-
setState(
|
|
101
|
+
setState(current => current.canScrollPrev === next.canScrollPrev &&
|
|
106
102
|
current.canScrollNext === next.canScrollNext &&
|
|
107
103
|
current.selectedIndex === next.selectedIndex &&
|
|
108
104
|
current.snapCount === next.snapCount &&
|
|
@@ -110,7 +106,7 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
110
106
|
? current
|
|
111
107
|
: next);
|
|
112
108
|
if (changed)
|
|
113
|
-
emit(
|
|
109
|
+
emit('select');
|
|
114
110
|
}, [emit, geometry]);
|
|
115
111
|
const go = useCallback((target, instant = false) => {
|
|
116
112
|
const node = viewport.current;
|
|
@@ -125,10 +121,10 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
125
121
|
update();
|
|
126
122
|
}, 700),
|
|
127
123
|
};
|
|
128
|
-
const key = settings.current.horizontal ?
|
|
124
|
+
const key = settings.current.horizontal ? 'left' : 'top';
|
|
129
125
|
node.scrollTo({
|
|
130
126
|
[key]: target,
|
|
131
|
-
...(instant ? { behavior:
|
|
127
|
+
...(instant ? { behavior: 'instant' } : {}),
|
|
132
128
|
});
|
|
133
129
|
update();
|
|
134
130
|
}, [update]);
|
|
@@ -145,8 +141,8 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
145
141
|
return;
|
|
146
142
|
const from = pending.current?.target ?? shape.position;
|
|
147
143
|
const target = direction > 0
|
|
148
|
-
? shape.snaps.find(
|
|
149
|
-
: [...shape.snaps].reverse().find(
|
|
144
|
+
? shape.snaps.find(snap => snap > from + 1)
|
|
145
|
+
: [...shape.snaps].reverse().find(snap => snap < from - 1);
|
|
150
146
|
if (target !== undefined)
|
|
151
147
|
go(target);
|
|
152
148
|
else if (settings.current.loop && shape.snaps.length > 1)
|
|
@@ -158,20 +154,18 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
158
154
|
const api = {
|
|
159
155
|
scrollPrev: () => step(-1),
|
|
160
156
|
scrollNext: () => step(1),
|
|
161
|
-
scrollTo:
|
|
157
|
+
scrollTo: index => scrollTo(index),
|
|
162
158
|
canScrollPrev: () => {
|
|
163
159
|
const shape = geometry();
|
|
164
160
|
if (!shape)
|
|
165
161
|
return false;
|
|
166
|
-
return (
|
|
167
|
-
shape.position > 1);
|
|
162
|
+
return (settings.current.loop && shape.snaps.length > 1) || shape.position > 1;
|
|
168
163
|
},
|
|
169
164
|
canScrollNext: () => {
|
|
170
165
|
const shape = geometry();
|
|
171
166
|
if (!shape)
|
|
172
167
|
return false;
|
|
173
|
-
return (
|
|
174
|
-
shape.position < shape.max - 1);
|
|
168
|
+
return (settings.current.loop && shape.snaps.length > 1) || shape.position < shape.max - 1;
|
|
175
169
|
},
|
|
176
170
|
selectedScrollSnap: () => selected.current,
|
|
177
171
|
scrollSnapList: () => geometry()?.snaps ?? [],
|
|
@@ -202,7 +196,7 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
202
196
|
const startIndex = opts?.startIndex ?? 0;
|
|
203
197
|
const started = useRef(false);
|
|
204
198
|
const [node, setNode] = useState(null);
|
|
205
|
-
const carouselRef = useCallback(
|
|
199
|
+
const carouselRef = useCallback(element => {
|
|
206
200
|
viewport.current = element;
|
|
207
201
|
setNode(element);
|
|
208
202
|
}, []);
|
|
@@ -211,7 +205,7 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
211
205
|
return;
|
|
212
206
|
const reInit = () => {
|
|
213
207
|
update();
|
|
214
|
-
emit(
|
|
208
|
+
emit('reInit');
|
|
215
209
|
};
|
|
216
210
|
if (!started.current) {
|
|
217
211
|
started.current = true;
|
|
@@ -235,13 +229,13 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
235
229
|
resize.observe(slide);
|
|
236
230
|
mutation.observe(track, { childList: true, subtree: true });
|
|
237
231
|
}
|
|
238
|
-
node.addEventListener(
|
|
239
|
-
node.addEventListener(
|
|
232
|
+
node.addEventListener('scroll', scheduleUpdate, { passive: true });
|
|
233
|
+
node.addEventListener('scrollend', update);
|
|
240
234
|
return () => {
|
|
241
235
|
resize.disconnect();
|
|
242
236
|
mutation.disconnect();
|
|
243
|
-
node.removeEventListener(
|
|
244
|
-
node.removeEventListener(
|
|
237
|
+
node.removeEventListener('scroll', scheduleUpdate);
|
|
238
|
+
node.removeEventListener('scrollend', update);
|
|
245
239
|
cancelAnimationFrame(frame.current);
|
|
246
240
|
frame.current = 0;
|
|
247
241
|
};
|
|
@@ -251,7 +245,7 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
251
245
|
if (!node)
|
|
252
246
|
return;
|
|
253
247
|
update();
|
|
254
|
-
emit(
|
|
248
|
+
emit('reInit');
|
|
255
249
|
}, [node, horizontal, align, loop, update, emit]);
|
|
256
250
|
useEffect(() => {
|
|
257
251
|
if (!setApi)
|
|
@@ -264,24 +258,21 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
264
258
|
}, []);
|
|
265
259
|
const handleKeyDown = (event) => {
|
|
266
260
|
onKeyDownCapture?.(event);
|
|
267
|
-
if (event.defaultPrevented ||
|
|
268
|
-
event.altKey ||
|
|
269
|
-
event.ctrlKey ||
|
|
270
|
-
event.metaKey)
|
|
261
|
+
if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey)
|
|
271
262
|
return;
|
|
272
263
|
if (event.target.closest(typing))
|
|
273
264
|
return;
|
|
274
|
-
const back = event.key ===
|
|
275
|
-
const forward = event.key ===
|
|
265
|
+
const back = event.key === 'ArrowLeft' || (!horizontal && event.key === 'ArrowUp');
|
|
266
|
+
const forward = event.key === 'ArrowRight' || (!horizontal && event.key === 'ArrowDown');
|
|
276
267
|
if (back || forward) {
|
|
277
268
|
event.preventDefault();
|
|
278
269
|
step(back ? -1 : 1);
|
|
279
270
|
}
|
|
280
|
-
else if (event.key ===
|
|
271
|
+
else if (event.key === 'Home' || event.key === 'End') {
|
|
281
272
|
if (!event.target.closest('[data-slot="carousel-content"]'))
|
|
282
273
|
return;
|
|
283
274
|
event.preventDefault();
|
|
284
|
-
scrollTo(event.key ===
|
|
275
|
+
scrollTo(event.key === 'Home' ? 0 : Number.MAX_SAFE_INTEGER);
|
|
285
276
|
}
|
|
286
277
|
};
|
|
287
278
|
const value = useMemo(() => ({
|
|
@@ -296,32 +287,23 @@ export function Carousel({ orientation = "horizontal", opts, setApi, className,
|
|
|
296
287
|
canScrollNext: state.canScrollNext,
|
|
297
288
|
selectedIndex: state.selectedIndex,
|
|
298
289
|
snapCount: state.snapCount,
|
|
299
|
-
}), [
|
|
300
|
-
|
|
301
|
-
api,
|
|
302
|
-
opts,
|
|
303
|
-
orientation,
|
|
304
|
-
scrollPrev,
|
|
305
|
-
scrollNext,
|
|
306
|
-
scrollTo,
|
|
307
|
-
state,
|
|
308
|
-
]);
|
|
309
|
-
return (_jsx(CarouselContext.Provider, { value: value, children: _jsx(ViewportFocus.Provider, { value: state.viewportFocusable, children: _jsx("div", { role: "region", "aria-roledescription": "carousel", "data-slot": "carousel", "data-orientation": orientation, className: cn("sprout-carousel", className), onKeyDownCapture: handleKeyDown, ...props, children: children }) }) }));
|
|
290
|
+
}), [carouselRef, api, opts, orientation, scrollPrev, scrollNext, scrollTo, state]);
|
|
291
|
+
return (_jsx(CarouselContext.Provider, { value: value, children: _jsx(ViewportFocus.Provider, { value: state.viewportFocusable, children: _jsx("div", { role: "region", "aria-roledescription": "carousel", "data-slot": "carousel", "data-orientation": orientation, className: cn('sprout-carousel', className), onKeyDownCapture: handleKeyDown, ...props, children: children }) }) }));
|
|
310
292
|
}
|
|
311
293
|
const ViewportFocus = createContext(false);
|
|
312
294
|
export function CarouselContent({ className, ...props }) {
|
|
313
295
|
const { carouselRef, orientation, opts, api } = useCarousel();
|
|
314
296
|
const focusableViewport = useContext(ViewportFocus);
|
|
315
|
-
const horizontal = orientation ===
|
|
297
|
+
const horizontal = orientation === 'horizontal';
|
|
316
298
|
const drag = useRef(null);
|
|
317
299
|
const node = useRef(null);
|
|
318
|
-
const ref = useCallback(
|
|
300
|
+
const ref = useCallback(element => {
|
|
319
301
|
node.current = element;
|
|
320
302
|
carouselRef(element);
|
|
321
303
|
}, [carouselRef]);
|
|
322
|
-
const coordinate = (event) => horizontal ? event.clientX : event.clientY;
|
|
304
|
+
const coordinate = (event) => (horizontal ? event.clientX : event.clientY);
|
|
323
305
|
const onPointerDown = (event) => {
|
|
324
|
-
if (event.pointerType !==
|
|
306
|
+
if (event.pointerType !== 'mouse' || event.button !== 0)
|
|
325
307
|
return;
|
|
326
308
|
if (event.target.closest(typing))
|
|
327
309
|
return;
|
|
@@ -343,7 +325,7 @@ export function CarouselContent({ className, ...props }) {
|
|
|
343
325
|
return;
|
|
344
326
|
current.moved = true;
|
|
345
327
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
346
|
-
event.currentTarget.setAttribute(
|
|
328
|
+
event.currentTarget.setAttribute('data-dragging', '');
|
|
347
329
|
}
|
|
348
330
|
const viewport = event.currentTarget;
|
|
349
331
|
if (horizontal)
|
|
@@ -365,11 +347,11 @@ export function CarouselContent({ className, ...props }) {
|
|
|
365
347
|
click.preventDefault();
|
|
366
348
|
click.stopPropagation();
|
|
367
349
|
};
|
|
368
|
-
window.addEventListener(
|
|
369
|
-
window.setTimeout(() => window.removeEventListener(
|
|
350
|
+
window.addEventListener('click', swallow, { capture: true, once: true });
|
|
351
|
+
window.setTimeout(() => window.removeEventListener('click', swallow, { capture: true }), 0);
|
|
370
352
|
const release = () => {
|
|
371
353
|
if (!drag.current)
|
|
372
|
-
viewport.removeAttribute(
|
|
354
|
+
viewport.removeAttribute('data-dragging');
|
|
373
355
|
};
|
|
374
356
|
if (opts?.dragFree)
|
|
375
357
|
return release();
|
|
@@ -392,31 +374,31 @@ export function CarouselContent({ className, ...props }) {
|
|
|
392
374
|
let timer = 0;
|
|
393
375
|
const settle = () => {
|
|
394
376
|
window.clearTimeout(timer);
|
|
395
|
-
viewport.removeEventListener(
|
|
377
|
+
viewport.removeEventListener('scrollend', settle);
|
|
396
378
|
release();
|
|
397
379
|
};
|
|
398
|
-
viewport.addEventListener(
|
|
380
|
+
viewport.addEventListener('scrollend', settle);
|
|
399
381
|
timer = window.setTimeout(settle, 700);
|
|
400
|
-
const smooth = window.matchMedia(
|
|
382
|
+
const smooth = window.matchMedia('(prefers-reduced-motion: no-preference)').matches;
|
|
401
383
|
viewport.scrollTo({
|
|
402
|
-
[horizontal ?
|
|
403
|
-
behavior: smooth ?
|
|
384
|
+
[horizontal ? 'left' : 'top']: target,
|
|
385
|
+
behavior: smooth ? 'smooth' : 'instant',
|
|
404
386
|
});
|
|
405
387
|
};
|
|
406
|
-
return (_jsx("div", { ref: ref, "data-slot": "carousel-content", "data-orientation": orientation, "data-align": opts?.align ??
|
|
388
|
+
return (_jsx("div", { ref: ref, "data-slot": "carousel-content", "data-orientation": orientation, "data-align": opts?.align ?? 'start', "data-drag-free": opts?.dragFree ? '' : undefined, tabIndex: focusableViewport ? 0 : undefined, className: "sprout-carousel-content", onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerEnd, onPointerCancel: onPointerEnd, onDragStart: event => {
|
|
407
389
|
if (drag.current)
|
|
408
390
|
event.preventDefault();
|
|
409
|
-
}, children: _jsx("div", { "data-slot": "carousel-track", className: cn(
|
|
391
|
+
}, children: _jsx("div", { "data-slot": "carousel-track", className: cn('sprout-carousel-track', className), ...props }) }));
|
|
410
392
|
}
|
|
411
393
|
export function CarouselItem({ className, ...props }) {
|
|
412
394
|
const { orientation } = useCarousel();
|
|
413
|
-
return (_jsx("div", { role: "group", "aria-roledescription": "slide", "data-slot": "carousel-item", "data-orientation": orientation, className: cn(
|
|
395
|
+
return (_jsx("div", { role: "group", "aria-roledescription": "slide", "data-slot": "carousel-item", "data-orientation": orientation, className: cn('sprout-carousel-item', className), ...props }));
|
|
414
396
|
}
|
|
415
|
-
export function CarouselPrevious({ className, variant =
|
|
397
|
+
export function CarouselPrevious({ className, variant = 'secondary', size = 'icon', children, ...props }) {
|
|
416
398
|
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
|
417
|
-
return (_jsx(Button, { "data-slot": "carousel-previous", "data-orientation": orientation, variant: variant, size: size, "aria-label": "Previous slide", focusableWhenDisabled: true, className: cn(
|
|
399
|
+
return (_jsx(Button, { "data-slot": "carousel-previous", "data-orientation": orientation, variant: variant, size: size, "aria-label": "Previous slide", focusableWhenDisabled: true, className: cn('sprout-carousel-control', 'sprout-carousel-previous', className), disabled: !canScrollPrev, onClick: scrollPrev, ...props, children: children ?? _jsx(ChevronLeft, { "aria-hidden": "true" }) }));
|
|
418
400
|
}
|
|
419
|
-
export function CarouselNext({ className, variant =
|
|
401
|
+
export function CarouselNext({ className, variant = 'secondary', size = 'icon', children, ...props }) {
|
|
420
402
|
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
|
421
|
-
return (_jsx(Button, { "data-slot": "carousel-next", "data-orientation": orientation, variant: variant, size: size, "aria-label": "Next slide", focusableWhenDisabled: true, className: cn(
|
|
403
|
+
return (_jsx(Button, { "data-slot": "carousel-next", "data-orientation": orientation, variant: variant, size: size, "aria-label": "Next slide", focusableWhenDisabled: true, className: cn('sprout-carousel-control', 'sprout-carousel-next', className), disabled: !canScrollNext, onClick: scrollNext, ...props, children: children ?? _jsx(ChevronRight, { "aria-hidden": "true" }) }));
|
|
422
404
|
}
|
|
@@ -1,112 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly dark: ".dark";
|
|
7
|
-
};
|
|
8
|
-
export declare const chartIndicatorNames: readonly ["dot", "line", "dashed"];
|
|
9
|
-
export type ChartIndicator = (typeof chartIndicatorNames)[number];
|
|
10
|
-
export type ChartConfig = Record<string, {
|
|
11
|
-
label?: ReactNode;
|
|
12
|
-
icon?: ComponentType;
|
|
13
|
-
} & ({
|
|
14
|
-
color?: string;
|
|
15
|
-
theme?: never;
|
|
16
|
-
} | {
|
|
17
|
-
color?: never;
|
|
18
|
-
theme: Record<keyof typeof THEMES, string>;
|
|
19
|
-
})>;
|
|
20
|
-
/**
|
|
21
|
-
* The CSS variable a `ChartContainer` sets for one config key. Pass it as a
|
|
22
|
-
* series `fill` or `stroke`, for example `fill={chartColor("tasks")}`.
|
|
23
|
-
*/
|
|
24
|
-
export declare function chartColor(key: string): string;
|
|
25
|
-
export type ChartContainerProps = ComponentProps<"div"> & {
|
|
26
|
-
config: ChartConfig;
|
|
27
|
-
children: ComponentProps<typeof ResponsiveContainer>["children"];
|
|
28
|
-
/** Size used before the container is measured, and on the server. */
|
|
29
|
-
initialDimension?: {
|
|
30
|
-
width: number;
|
|
31
|
-
height: number;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Sizes a Recharts chart to its box and turns `config` into series colors
|
|
36
|
-
* and labels for the tooltip and legend. The box is 16:9 unless `className`
|
|
37
|
-
* or `style` gives it a height.
|
|
38
|
-
*/
|
|
39
|
-
export declare function ChartContainer({ id, className, children, config, initialDimension, ...props }: ChartContainerProps): import("react").JSX.Element;
|
|
40
|
-
/**
|
|
41
|
-
* Writes `--sprout-chart-color-<key>` for every colored config entry, with a
|
|
42
|
-
* dark value for entries that pass `theme`. `ChartContainer` renders it.
|
|
43
|
-
*/
|
|
44
|
-
export declare function ChartStyle({ id, config, }: {
|
|
45
|
-
id: string;
|
|
46
|
-
config: ChartConfig;
|
|
47
|
-
}): import("react").JSX.Element | null;
|
|
48
|
-
export type ChartTooltipProps = ComponentProps<typeof Tooltip>;
|
|
49
|
-
/**
|
|
50
|
-
* Recharts' `Tooltip`, moving in 160ms. Pass `content={<ChartTooltipContent />}`.
|
|
51
|
-
* It stays still when reduced motion is on.
|
|
52
|
-
*/
|
|
53
|
-
export declare function ChartTooltip(props: ChartTooltipProps): import("react").JSX.Element;
|
|
54
|
-
type TooltipNameType = number | string;
|
|
55
|
-
export type ChartTooltipContentProps = ComponentProps<typeof Tooltip> & ComponentProps<"div"> & {
|
|
56
|
-
hideLabel?: boolean;
|
|
57
|
-
hideIndicator?: boolean;
|
|
58
|
-
indicator?: ChartIndicator;
|
|
59
|
-
nameKey?: string;
|
|
60
|
-
labelKey?: string;
|
|
61
|
-
} & Omit<DefaultTooltipContentProps<TooltipValueType, TooltipNameType>, "accessibilityLayer">;
|
|
62
|
-
/**
|
|
63
|
-
* The tooltip card: a label, then one row per series with its indicator,
|
|
64
|
-
* config label, and value. Recharts passes `active`, `payload`, and `label`.
|
|
65
|
-
*/
|
|
66
|
-
export declare function ChartTooltipContent({ active, payload, className, indicator, hideLabel, hideIndicator, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, }: ChartTooltipContentProps): import("react").JSX.Element | null;
|
|
67
|
-
/** Recharts' `Legend`. Pass `content={<ChartLegendContent />}`. */
|
|
68
|
-
export declare const ChartLegend: import("react").MemoExoticComponent<(outsideProps: import("recharts").LegendProps) => React.ReactPortal | null>;
|
|
69
|
-
export type ChartLegendContentProps = ComponentProps<"div"> & {
|
|
70
|
-
hideIcon?: boolean;
|
|
71
|
-
nameKey?: string;
|
|
72
|
-
} & DefaultLegendContentProps;
|
|
73
|
-
/** A centered row of swatches and config labels, one per series. */
|
|
74
|
-
export declare function ChartLegendContent({ className, hideIcon, payload, verticalAlign, nameKey, }: ChartLegendContentProps): import("react").JSX.Element | null;
|
|
75
|
-
/** One bar series: its data key, legend and tooltip label, and color. */
|
|
76
|
-
export type UsageSeries = {
|
|
77
|
-
key: string;
|
|
78
|
-
label: string;
|
|
79
|
-
color: string;
|
|
80
|
-
};
|
|
81
|
-
export type UsageDay = {
|
|
82
|
-
date: string;
|
|
83
|
-
} & Record<string, number | string | null>;
|
|
84
|
-
export interface UsageChartProps {
|
|
85
|
-
/** One row per UTC day (`YYYY-MM-DD`), keyed by series. */
|
|
86
|
-
days: UsageDay[];
|
|
87
|
-
series: UsageSeries[];
|
|
88
|
-
/** Names the chart for screen readers. */
|
|
89
|
-
title?: string;
|
|
90
|
-
/** Locale for day labels. Defaults to the reader's. */
|
|
91
|
-
locale?: string;
|
|
92
|
-
className?: string;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Stacked daily bars, 256px tall. Days are rows keyed by series; a missing or
|
|
96
|
-
* null value keeps that series out of the day's tooltip. The top series gets
|
|
97
|
-
* rounded corners.
|
|
98
|
-
*/
|
|
99
|
-
export declare function UsageChart({ days, series, title, locale, className, }: UsageChartProps): import("react").JSX.Element;
|
|
100
|
-
export interface CategoryChartProps {
|
|
101
|
-
/** One row per category, keyed by `category` and by each series key. */
|
|
102
|
-
rows: Record<string, number | string>[];
|
|
103
|
-
/** The row key whose value names each group of bars. */
|
|
104
|
-
category: string;
|
|
105
|
-
series: UsageSeries[];
|
|
106
|
-
/** Names the chart for screen readers. */
|
|
107
|
-
title?: string;
|
|
108
|
-
className?: string;
|
|
109
|
-
}
|
|
110
|
-
/** Side-by-side bars per category with a legend in series order, 288px tall. */
|
|
111
|
-
export declare function CategoryChart({ rows, category, series, title, className, }: CategoryChartProps): import("react").JSX.Element;
|
|
112
|
-
export {};
|
|
1
|
+
export { ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, chartColor, chartIndicatorNames, chartOtherColor, chartPalette, chartShade, type ChartConfig, type ChartContainerProps, type ChartIndicator, type ChartLegendContentProps, type ChartRow, type ChartSeries, type ChartStack, type ChartTooltipContentProps, type ChartTooltipProps, type UsageSeries, type ValueFormatter, } from '../internal/chart-kit.js';
|
|
2
|
+
export * from '../internal/charts/bars.js';
|
|
3
|
+
export * from '../internal/charts/lines.js';
|
|
4
|
+
export * from '../internal/charts/parts.js';
|
|
5
|
+
export * from '../internal/charts/more.js';
|
package/dist/components/chart.js
CHANGED
|
@@ -1,172 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
/** Theme names a `ChartConfig` entry can color, and the selector each one uses. */
|
|
7
|
-
const THEMES = { light: "", dark: ".dark" };
|
|
8
|
-
const INITIAL_DIMENSION = { width: 320, height: 200 };
|
|
9
|
-
export const chartIndicatorNames = ["dot", "line", "dashed"];
|
|
10
|
-
const cssKey = (key) => key.replace(/[^\w-]/g, "_");
|
|
11
|
-
/**
|
|
12
|
-
* The CSS variable a `ChartContainer` sets for one config key. Pass it as a
|
|
13
|
-
* series `fill` or `stroke`, for example `fill={chartColor("tasks")}`.
|
|
14
|
-
*/
|
|
15
|
-
export function chartColor(key) {
|
|
16
|
-
return `var(--sprout-chart-color-${cssKey(key)})`;
|
|
17
|
-
}
|
|
18
|
-
const ChartContext = createContext(null);
|
|
19
|
-
function useChart() {
|
|
20
|
-
const context = useContext(ChartContext);
|
|
21
|
-
if (!context)
|
|
22
|
-
throw new Error("useChart must be used within a <ChartContainer />");
|
|
23
|
-
return context;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Sizes a Recharts chart to its box and turns `config` into series colors
|
|
27
|
-
* and labels for the tooltip and legend. The box is 16:9 unless `className`
|
|
28
|
-
* or `style` gives it a height.
|
|
29
|
-
*/
|
|
30
|
-
export function ChartContainer({ id, className, children, config, initialDimension = INITIAL_DIMENSION, ...props }) {
|
|
31
|
-
const uniqueId = useId();
|
|
32
|
-
const chartId = `chart-${cssKey(id ?? uniqueId)}`;
|
|
33
|
-
const value = useMemo(() => ({ config }), [config]);
|
|
34
|
-
return (_jsx(ChartContext.Provider, { value: value, children: _jsxs("div", { "data-slot": "chart", "data-chart": chartId, className: cn("sprout-chart", className), ...props, children: [_jsx(ChartStyle, { id: chartId, config: config }), _jsx(ResponsiveContainer, { initialDimension: initialDimension, children: children })] }) }));
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Writes `--sprout-chart-color-<key>` for every colored config entry, with a
|
|
38
|
-
* dark value for entries that pass `theme`. `ChartContainer` renders it.
|
|
39
|
-
*/
|
|
40
|
-
export function ChartStyle({ id, config, }) {
|
|
41
|
-
const colorConfig = Object.entries(config).filter(([, item]) => item.theme ?? item.color);
|
|
42
|
-
if (!colorConfig.length)
|
|
43
|
-
return null;
|
|
44
|
-
const rules = (theme) => colorConfig
|
|
45
|
-
.map(([key, item]) => {
|
|
46
|
-
const color = item.theme?.[theme] ?? item.color;
|
|
47
|
-
return color
|
|
48
|
-
? ` --sprout-chart-color-${cssKey(key)}: ${color};`
|
|
49
|
-
: null;
|
|
50
|
-
})
|
|
51
|
-
.filter(Boolean)
|
|
52
|
-
.join("\n");
|
|
53
|
-
const scope = `[data-chart="${cssKey(id)}"]`;
|
|
54
|
-
const themed = colorConfig.some(([, item]) => item.theme);
|
|
55
|
-
const css = [
|
|
56
|
-
`${scope} {\n${rules("light")}\n}`,
|
|
57
|
-
themed ? `${THEMES.dark} ${scope} {\n${rules("dark")}\n}` : "",
|
|
58
|
-
themed
|
|
59
|
-
? `@media (prefers-color-scheme: dark) {\n:root:not(.light):not(.dark) ${scope} {\n${rules("dark")}\n}\n}`
|
|
60
|
-
: "",
|
|
61
|
-
]
|
|
62
|
-
.filter(Boolean)
|
|
63
|
-
.join("\n");
|
|
64
|
-
return _jsx("style", { dangerouslySetInnerHTML: { __html: css } });
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Recharts' `Tooltip`, moving in 160ms. Pass `content={<ChartTooltipContent />}`.
|
|
68
|
-
* It stays still when reduced motion is on.
|
|
69
|
-
*/
|
|
70
|
-
export function ChartTooltip(props) {
|
|
71
|
-
return _jsx(Tooltip, { animationDuration: 160, ...props });
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* The tooltip card: a label, then one row per series with its indicator,
|
|
75
|
-
* config label, and value. Recharts passes `active`, `payload`, and `label`.
|
|
76
|
-
*/
|
|
77
|
-
export function ChartTooltipContent({ active, payload, className, indicator = "dot", hideLabel = false, hideIndicator = false, label, labelFormatter, labelClassName, formatter, color, nameKey, labelKey, }) {
|
|
78
|
-
const { config } = useChart();
|
|
79
|
-
const tooltipLabel = useMemo(() => {
|
|
80
|
-
if (hideLabel || !payload?.length)
|
|
81
|
-
return null;
|
|
82
|
-
const [item] = payload;
|
|
83
|
-
const key = `${labelKey ?? item?.dataKey ?? item?.name ?? "value"}`;
|
|
84
|
-
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
85
|
-
const value = !labelKey && typeof label === "string"
|
|
86
|
-
? (config[label]?.label ?? label)
|
|
87
|
-
: itemConfig?.label;
|
|
88
|
-
if (labelFormatter)
|
|
89
|
-
return (_jsx("div", { className: cn("sprout-chart-tooltip-label", labelClassName), children: labelFormatter(value, payload) }));
|
|
90
|
-
if (!value)
|
|
91
|
-
return null;
|
|
92
|
-
return (_jsx("div", { className: cn("sprout-chart-tooltip-label", labelClassName), children: value }));
|
|
93
|
-
}, [
|
|
94
|
-
label,
|
|
95
|
-
labelFormatter,
|
|
96
|
-
payload,
|
|
97
|
-
hideLabel,
|
|
98
|
-
labelClassName,
|
|
99
|
-
config,
|
|
100
|
-
labelKey,
|
|
101
|
-
]);
|
|
102
|
-
if (!active || !payload?.length)
|
|
103
|
-
return null;
|
|
104
|
-
const nestLabel = payload.length === 1 && indicator !== "dot";
|
|
105
|
-
return (_jsxs("div", { "data-slot": "chart-tooltip", "data-indicator": indicator, className: cn("sprout-chart-tooltip", className), children: [!nestLabel ? tooltipLabel : null, _jsx("div", { className: "sprout-chart-tooltip-items", children: payload
|
|
106
|
-
.filter((item) => item.type !== "none")
|
|
107
|
-
.map((item, index) => {
|
|
108
|
-
const key = `${nameKey ?? item.name ?? item.dataKey ?? "value"}`;
|
|
109
|
-
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
110
|
-
const indicatorColor = color ??
|
|
111
|
-
item.payload?.fill ??
|
|
112
|
-
item.color;
|
|
113
|
-
return (_jsx("div", { "data-slot": "chart-tooltip-item", className: "sprout-chart-tooltip-item", children: formatter && item?.value !== undefined && item.name ? (formatter(item.value, item.name, item, index, item.payload)) : (_jsxs(_Fragment, { children: [itemConfig?.icon ? (_jsx(itemConfig.icon, {})) : (!hideIndicator && (_jsx("span", { "aria-hidden": "true", "data-slot": "chart-tooltip-indicator", className: "sprout-chart-tooltip-indicator", style: {
|
|
114
|
-
"--sprout-chart-indicator": indicatorColor,
|
|
115
|
-
} }))), _jsxs("div", { className: "sprout-chart-tooltip-row", "data-nested": nestLabel || undefined, children: [_jsxs("div", { className: "sprout-chart-tooltip-name", children: [nestLabel ? tooltipLabel : null, _jsx("span", { children: itemConfig?.label ?? item.name })] }), item.value != null && (_jsx("span", { className: "sprout-chart-tooltip-value", children: typeof item.value === "number"
|
|
116
|
-
? item.value.toLocaleString()
|
|
117
|
-
: String(item.value) }))] })] })) }, index));
|
|
118
|
-
}) })] }));
|
|
119
|
-
}
|
|
120
|
-
/** Recharts' `Legend`. Pass `content={<ChartLegendContent />}`. */
|
|
121
|
-
export const ChartLegend = Legend;
|
|
122
|
-
/** A centered row of swatches and config labels, one per series. */
|
|
123
|
-
export function ChartLegendContent({ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey, }) {
|
|
124
|
-
const { config } = useChart();
|
|
125
|
-
if (!payload?.length)
|
|
126
|
-
return null;
|
|
127
|
-
return (_jsx("div", { "data-slot": "chart-legend", "data-align": verticalAlign === "top" ? "top" : "bottom", className: cn("sprout-chart-legend", className), children: payload
|
|
128
|
-
.filter((item) => item.type !== "none")
|
|
129
|
-
.map((item, index) => {
|
|
130
|
-
const key = `${nameKey ?? item.dataKey ?? "value"}`;
|
|
131
|
-
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
132
|
-
return (_jsxs("div", { "data-slot": "chart-legend-item", className: "sprout-chart-legend-item", children: [itemConfig?.icon && !hideIcon ? (_jsx(itemConfig.icon, {})) : (_jsx("span", { "aria-hidden": "true", className: "sprout-chart-legend-swatch", style: { backgroundColor: item.color } })), itemConfig?.label] }, index));
|
|
133
|
-
}) }));
|
|
134
|
-
}
|
|
135
|
-
function getPayloadConfigFromPayload(config, payload, key) {
|
|
136
|
-
if (typeof payload !== "object" || payload === null)
|
|
137
|
-
return undefined;
|
|
138
|
-
const inner = "payload" in payload &&
|
|
139
|
-
typeof payload.payload === "object" &&
|
|
140
|
-
payload.payload !== null
|
|
141
|
-
? payload.payload
|
|
142
|
-
: undefined;
|
|
143
|
-
const outer = payload;
|
|
144
|
-
let configLabelKey = key;
|
|
145
|
-
if (typeof outer[key] === "string")
|
|
146
|
-
configLabelKey = outer[key];
|
|
147
|
-
else if (inner && typeof inner[key] === "string")
|
|
148
|
-
configLabelKey = inner[key];
|
|
149
|
-
return configLabelKey in config ? config[configLabelKey] : config[key];
|
|
150
|
-
}
|
|
151
|
-
const seriesConfig = (series) => Object.fromEntries(series.map((item) => [item.key, { label: item.label, color: item.color }]));
|
|
152
|
-
const tooltipCursor = { fill: "var(--sprout-hover)" };
|
|
153
|
-
/**
|
|
154
|
-
* Stacked daily bars, 256px tall. Days are rows keyed by series; a missing or
|
|
155
|
-
* null value keeps that series out of the day's tooltip. The top series gets
|
|
156
|
-
* rounded corners.
|
|
157
|
-
*/
|
|
158
|
-
export function UsageChart({ days, series, title = "Usage by day", locale, className, }) {
|
|
159
|
-
const config = useMemo(() => seriesConfig(series), [series]);
|
|
160
|
-
const usageDay = (date) => new Date(`${String(date)}T00:00:00Z`).toLocaleDateString(locale, {
|
|
161
|
-
month: "short",
|
|
162
|
-
day: "numeric",
|
|
163
|
-
timeZone: "UTC",
|
|
164
|
-
});
|
|
165
|
-
return (_jsx(ChartContainer, { "data-variant": "usage", className: cn("sprout-chart-usage", className), config: config, children: _jsxs(BarChart, { data: days, accessibilityLayer: true, title: title, barCategoryGap: "20%", children: [_jsx(CartesianGrid, { vertical: false }), _jsx(XAxis, { dataKey: "date", tickFormatter: usageDay, tickLine: false, axisLine: false, minTickGap: 24 }), _jsx(YAxis, { width: 40, tickLine: false, axisLine: false, allowDecimals: false }), _jsx(ChartTooltip, { cursor: tooltipCursor, content: _jsx(ChartTooltipContent, { labelFormatter: usageDay }) }), series.map((item, index) => (_jsx(Bar, { dataKey: item.key, stackId: "usage", fill: chartColor(item.key), radius: index === series.length - 1 ? [3, 3, 0, 0] : 0, isAnimationActive: false }, item.key)))] }) }));
|
|
166
|
-
}
|
|
167
|
-
/** Side-by-side bars per category with a legend in series order, 288px tall. */
|
|
168
|
-
export function CategoryChart({ rows, category, series, title, className, }) {
|
|
169
|
-
const config = useMemo(() => seriesConfig(series), [series]);
|
|
170
|
-
const name = title ?? `${series.map((item) => item.label).join(", ")} by ${category}`;
|
|
171
|
-
return (_jsx(ChartContainer, { "data-variant": "category", className: cn("sprout-chart-category", className), config: config, children: _jsxs(BarChart, { data: rows, accessibilityLayer: true, title: name, barCategoryGap: "24%", children: [_jsx(CartesianGrid, { vertical: false }), _jsx(XAxis, { dataKey: category, tickLine: false, axisLine: false, minTickGap: 16 }), _jsx(YAxis, { width: 40, tickLine: false, axisLine: false, allowDecimals: false }), _jsx(ChartTooltip, { cursor: tooltipCursor, content: _jsx(ChartTooltipContent, {}) }), _jsx(ChartLegend, { itemSorter: null, content: _jsx(ChartLegendContent, {}) }), series.map((item) => (_jsx(Bar, { dataKey: item.key, fill: chartColor(item.key), radius: [3, 3, 0, 0], isAnimationActive: false }, item.key)))] }) }));
|
|
172
|
-
}
|
|
1
|
+
export { ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, chartColor, chartIndicatorNames, chartOtherColor, chartPalette, chartShade, } from '../internal/chart-kit.js';
|
|
2
|
+
export * from '../internal/charts/bars.js';
|
|
3
|
+
export * from '../internal/charts/lines.js';
|
|
4
|
+
export * from '../internal/charts/parts.js';
|
|
5
|
+
export * from '../internal/charts/more.js';
|