@tulipfarm/sprout 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +183 -2
- package/dist/components/accordion.d.ts +28 -0
- package/dist/components/accordion.js +26 -0
- package/dist/components/alert-dialog.d.ts +60 -0
- package/dist/components/alert-dialog.js +69 -0
- package/dist/components/alert.d.ts +30 -0
- package/dist/components/alert.js +35 -0
- package/dist/components/aspect-ratio.d.ts +7 -0
- package/dist/components/aspect-ratio.js +6 -0
- package/dist/components/attachment.d.ts +118 -0
- package/dist/components/attachment.js +285 -0
- package/dist/components/avatar.d.ts +32 -0
- package/dist/components/avatar.js +73 -0
- package/dist/components/badge.d.ts +21 -0
- package/dist/components/badge.js +27 -0
- package/dist/components/brand-icon.d.ts +28 -0
- package/dist/components/brand-icon.js +82 -0
- package/dist/components/breadcrumb.d.ts +29 -0
- package/dist/components/breadcrumb.js +44 -0
- package/dist/components/button-group.d.ts +28 -0
- package/dist/components/button-group.js +36 -0
- package/dist/components/button.d.ts +79 -0
- package/dist/components/button.js +93 -0
- package/dist/components/calendar.d.ts +27 -0
- package/dist/components/calendar.js +107 -0
- package/dist/components/canvas.d.ts +78 -0
- package/dist/components/canvas.js +180 -0
- package/dist/components/card.d.ts +43 -0
- package/dist/components/card.js +42 -0
- package/dist/components/carousel.d.ts +57 -0
- package/dist/components/carousel.js +422 -0
- package/dist/components/chart.d.ts +112 -0
- package/dist/components/chart.js +172 -0
- package/dist/components/chat-confirmation.d.ts +42 -0
- package/dist/components/chat-confirmation.js +62 -0
- package/dist/components/chat-input.d.ts +94 -0
- package/dist/components/chat-input.js +279 -0
- package/dist/components/chat-plan.d.ts +21 -0
- package/dist/components/chat-plan.js +35 -0
- package/dist/components/chat-sources.d.ts +64 -0
- package/dist/components/chat-sources.js +66 -0
- package/dist/components/checkbox.d.ts +16 -0
- package/dist/components/checkbox.js +17 -0
- package/dist/components/choice-list.d.ts +53 -0
- package/dist/components/choice-list.js +36 -0
- package/dist/components/code-block.d.ts +35 -0
- package/dist/components/code-block.js +64 -0
- package/dist/components/collapsible.d.ts +24 -0
- package/dist/components/collapsible.js +27 -0
- package/dist/components/combobox.d.ts +95 -0
- package/dist/components/combobox.js +106 -0
- package/dist/components/command.d.ts +94 -0
- package/dist/components/command.js +414 -0
- package/dist/components/context-menu.d.ts +57 -0
- package/dist/components/context-menu.js +60 -0
- package/dist/components/dialog.d.ts +60 -0
- package/dist/components/dialog.js +79 -0
- package/dist/components/direction.d.ts +6 -0
- package/dist/components/direction.js +6 -0
- package/dist/components/dropdown-menu.d.ts +62 -0
- package/dist/components/dropdown-menu.js +59 -0
- package/dist/components/field.d.ts +117 -0
- package/dist/components/field.js +150 -0
- package/dist/components/file-explorer.d.ts +27 -0
- package/dist/components/file-explorer.js +300 -0
- package/dist/components/file-viewer.d.ts +137 -0
- package/dist/components/file-viewer.js +400 -0
- package/dist/components/form.d.ts +87 -0
- package/dist/components/form.js +55 -0
- package/dist/components/glass-banner.d.ts +27 -0
- package/dist/components/glass-banner.js +116 -0
- package/dist/components/gradient-banner.d.ts +37 -0
- package/dist/components/gradient-banner.js +43 -0
- package/dist/components/hover-card.d.ts +27 -0
- package/dist/components/hover-card.js +26 -0
- package/dist/components/input-group.d.ts +68 -0
- package/dist/components/input-group.js +88 -0
- package/dist/components/input-otp.d.ts +38 -0
- package/dist/components/input-otp.js +43 -0
- package/dist/components/input.d.ts +16 -0
- package/dist/components/input.js +18 -0
- package/dist/components/kbd.d.ts +12 -0
- package/dist/components/kbd.js +11 -0
- package/dist/components/label.d.ts +8 -0
- package/dist/components/label.js +10 -0
- package/dist/components/mention-list.d.ts +54 -0
- package/dist/components/mention-list.js +31 -0
- package/dist/components/menubar.d.ts +64 -0
- package/dist/components/menubar.js +68 -0
- package/dist/components/message-actions.d.ts +34 -0
- package/dist/components/message-actions.js +68 -0
- package/dist/components/message-response.d.ts +20 -0
- package/dist/components/message-response.js +46 -0
- package/dist/components/message-scroller.d.ts +71 -0
- package/dist/components/message-scroller.js +217 -0
- package/dist/components/message.d.ts +49 -0
- package/dist/components/message.js +59 -0
- package/dist/components/navigation-menu.d.ts +45 -0
- package/dist/components/navigation-menu.js +54 -0
- package/dist/components/notice-banner.d.ts +14 -0
- package/dist/components/notice-banner.js +11 -0
- package/dist/components/page-content.d.ts +7 -0
- package/dist/components/page-content.js +9 -0
- package/dist/components/page-header.d.ts +37 -0
- package/dist/components/page-header.js +53 -0
- package/dist/components/pagination.d.ts +29 -0
- package/dist/components/pagination.js +29 -0
- package/dist/components/plan-outline.d.ts +60 -0
- package/dist/components/plan-outline.js +108 -0
- package/dist/components/popover.d.ts +34 -0
- package/dist/components/popover.js +35 -0
- package/dist/components/progress.d.ts +27 -0
- package/dist/components/progress.js +35 -0
- package/dist/components/prompt-list.d.ts +23 -0
- package/dist/components/prompt-list.js +11 -0
- package/dist/components/questionnaire.d.ts +148 -0
- package/dist/components/questionnaire.js +1002 -0
- package/dist/components/radio-group.d.ts +16 -0
- package/dist/components/radio-group.js +21 -0
- package/dist/components/reasoning-effort.d.ts +24 -0
- package/dist/components/reasoning-effort.js +269 -0
- package/dist/components/resizable.d.ts +67 -0
- package/dist/components/resizable.js +536 -0
- package/dist/components/result-card.d.ts +58 -0
- package/dist/components/result-card.js +88 -0
- package/dist/components/review-card.d.ts +62 -0
- package/dist/components/review-card.js +49 -0
- package/dist/components/rich-text-editor.d.ts +51 -0
- package/dist/components/rich-text-editor.js +248 -0
- package/dist/components/schema-diagram.d.ts +52 -0
- package/dist/components/schema-diagram.js +226 -0
- package/dist/components/scroll-area.d.ts +22 -0
- package/dist/components/scroll-area.js +19 -0
- package/dist/components/search-dialog.d.ts +103 -0
- package/dist/components/search-dialog.js +65 -0
- package/dist/components/search-field.d.ts +17 -0
- package/dist/components/search-field.js +27 -0
- package/dist/components/select.d.ts +57 -0
- package/dist/components/select.js +57 -0
- package/dist/components/selection-slot.d.ts +18 -0
- package/dist/components/selection-slot.js +53 -0
- package/dist/components/separator.d.ts +48 -0
- package/dist/components/separator.js +54 -0
- package/dist/components/settings-list.d.ts +26 -0
- package/dist/components/settings-list.js +17 -0
- package/dist/components/sheet.d.ts +70 -0
- package/dist/components/sheet.js +77 -0
- package/dist/components/sidebar.d.ts +70 -0
- package/dist/components/sidebar.js +187 -0
- package/dist/components/skeleton.d.ts +31 -0
- package/dist/components/skeleton.js +32 -0
- package/dist/components/slider.d.ts +17 -0
- package/dist/components/slider.js +24 -0
- package/dist/components/spinner.d.ts +37 -0
- package/dist/components/spinner.js +43 -0
- package/dist/components/state-panel-samples.d.ts +25 -0
- package/dist/components/state-panel-samples.js +423 -0
- package/dist/components/state-panel.d.ts +35 -0
- package/dist/components/state-panel.js +29 -0
- package/dist/components/state-sample.d.ts +63 -0
- package/dist/components/state-sample.js +42 -0
- package/dist/components/switch.d.ts +12 -0
- package/dist/components/switch.js +14 -0
- package/dist/components/table-nuqs.d.ts +16 -0
- package/dist/components/table-nuqs.js +59 -0
- package/dist/components/table.d.ts +120 -0
- package/dist/components/table.js +663 -0
- package/dist/components/tabs.d.ts +37 -0
- package/dist/components/tabs.js +36 -0
- package/dist/components/textarea.d.ts +18 -0
- package/dist/components/textarea.js +19 -0
- package/dist/components/toast.d.ts +45 -0
- package/dist/components/toast.js +83 -0
- package/dist/components/toggle-group.d.ts +30 -0
- package/dist/components/toggle-group.js +39 -0
- package/dist/components/toggle.d.ts +27 -0
- package/dist/components/toggle.js +21 -0
- package/dist/components/tool-activity.d.ts +79 -0
- package/dist/components/tool-activity.js +226 -0
- package/dist/components/toolbar-status.d.ts +21 -0
- package/dist/components/toolbar-status.js +14 -0
- package/dist/components/tooltip.d.ts +31 -0
- package/dist/components/tooltip.js +99 -0
- package/dist/components/typed-text.d.ts +17 -0
- package/dist/components/typed-text.js +56 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +90 -0
- package/dist/internal/brand-glyphs.d.ts +370 -0
- package/dist/internal/brand-glyphs.js +262 -0
- package/dist/internal/classes.d.ts +3 -0
- package/dist/internal/classes.js +20 -0
- package/dist/internal/code-tokens.d.ts +4 -0
- package/dist/internal/code-tokens.js +34 -0
- package/dist/internal/fieldset.d.ts +6 -0
- package/dist/internal/fieldset.js +38 -0
- package/dist/internal/file-kind.d.ts +4 -0
- package/dist/internal/file-kind.js +62 -0
- package/dist/internal/languages.d.ts +7 -0
- package/dist/internal/languages.js +1010 -0
- package/dist/internal/message-scroller.d.ts +102 -0
- package/dist/internal/message-scroller.js +637 -0
- package/dist/internal/pressable.d.ts +2 -0
- package/dist/internal/pressable.js +29 -0
- package/dist/internal/syntax.d.ts +14 -0
- package/dist/internal/syntax.js +137 -0
- package/dist/styles/accordion.css +102 -0
- package/dist/styles/alert-dialog.css +198 -0
- package/dist/styles/alert.css +149 -0
- package/dist/styles/aspect-ratio.css +8 -0
- package/dist/styles/attachment.css +700 -0
- package/dist/styles/avatar.css +186 -0
- package/dist/styles/badge.css +178 -0
- package/dist/styles/brand-icon.css +104 -0
- package/dist/styles/breadcrumb.css +121 -0
- package/dist/styles/button-group.css +113 -0
- package/dist/styles/button.css +380 -0
- package/dist/styles/calendar.css +295 -0
- package/dist/styles/canvas.css +313 -0
- package/dist/styles/card.css +146 -0
- package/dist/styles/carousel.css +107 -0
- package/dist/styles/chart.css +227 -0
- package/dist/styles/chat-confirmation.css +29 -0
- package/dist/styles/chat-input.css +240 -0
- package/dist/styles/chat-plan.css +109 -0
- package/dist/styles/chat-sources.css +191 -0
- package/dist/styles/checkbox.css +122 -0
- package/dist/styles/choice-list.css +343 -0
- package/dist/styles/code-block.css +211 -0
- package/dist/styles/collapsible.css +72 -0
- package/dist/styles/combobox.css +347 -0
- package/dist/styles/command.css +233 -0
- package/dist/styles/context-menu.css +151 -0
- package/dist/styles/dialog.css +237 -0
- package/dist/styles/dropdown-menu.css +150 -0
- package/dist/styles/field.css +340 -0
- package/dist/styles/file-explorer.css +517 -0
- package/dist/styles/file-viewer.css +375 -0
- package/dist/styles/form.css +155 -0
- package/dist/styles/glass-banner.css +308 -0
- package/dist/styles/gradient-banner.css +256 -0
- package/dist/styles/hover-card.css +95 -0
- package/dist/styles/index.css +268 -0
- package/dist/styles/input-group.css +285 -0
- package/dist/styles/input-otp.css +138 -0
- package/dist/styles/input.css +98 -0
- package/dist/styles/kbd.css +59 -0
- package/dist/styles/label.css +89 -0
- package/dist/styles/mention-list.css +166 -0
- package/dist/styles/menubar.css +226 -0
- package/dist/styles/message-actions.css +83 -0
- package/dist/styles/message-response.css +176 -0
- package/dist/styles/message-scroller.css +136 -0
- package/dist/styles/message.css +310 -0
- package/dist/styles/navigation-menu.css +291 -0
- package/dist/styles/notice-banner.css +68 -0
- package/dist/styles/page-content.css +21 -0
- package/dist/styles/page-header.css +156 -0
- package/dist/styles/pagination.css +72 -0
- package/dist/styles/plan-outline.css +393 -0
- package/dist/styles/popover.css +140 -0
- package/dist/styles/progress.css +93 -0
- package/dist/styles/prompt-list.css +165 -0
- package/dist/styles/questionnaire.css +308 -0
- package/dist/styles/radio-group.css +119 -0
- package/dist/styles/reasoning-effort.css +157 -0
- package/dist/styles/resizable.css +108 -0
- package/dist/styles/result-card.css +215 -0
- package/dist/styles/review-card.css +235 -0
- package/dist/styles/rich-text-editor.css +169 -0
- package/dist/styles/schema-diagram.css +419 -0
- package/dist/styles/scroll-area.css +77 -0
- package/dist/styles/search-dialog.css +280 -0
- package/dist/styles/search-field.css +17 -0
- package/dist/styles/select.css +285 -0
- package/dist/styles/selection-slot.css +31 -0
- package/dist/styles/separator.css +206 -0
- package/dist/styles/settings-list.css +81 -0
- package/dist/styles/sheet.css +361 -0
- package/dist/styles/sidebar.css +363 -0
- package/dist/styles/skeleton.css +80 -0
- package/dist/styles/slider.css +142 -0
- package/dist/styles/spinner.css +39 -0
- package/dist/styles/state-panel-samples.css +41 -0
- package/dist/styles/state-panel.css +173 -0
- package/dist/styles/state-sample.css +285 -0
- package/dist/styles/switch.css +128 -0
- package/dist/styles/table.css +604 -0
- package/dist/styles/tabs.css +223 -0
- package/dist/styles/textarea.css +77 -0
- package/dist/styles/themes/chatgpt.css +125 -0
- package/dist/styles/themes/claude.css +125 -0
- package/dist/styles/themes/cloudflare.css +125 -0
- package/dist/styles/themes/discord.css +125 -0
- package/dist/styles/themes/github.css +125 -0
- package/dist/styles/themes/grok.css +125 -0
- package/dist/styles/themes/linear.css +126 -0
- package/dist/styles/themes/neutral.css +125 -0
- package/dist/styles/themes/notion.css +125 -0
- package/dist/styles/themes/perplexity.css +125 -0
- package/dist/styles/themes/raycast.css +125 -0
- package/dist/styles/themes/spotify.css +125 -0
- package/dist/styles/themes/stripe.css +125 -0
- package/dist/styles/themes/supabase.css +125 -0
- package/dist/styles/themes/tulipfarm.css +115 -0
- package/dist/styles/themes/vercel.css +126 -0
- package/dist/styles/toast.css +197 -0
- package/dist/styles/toggle-group.css +161 -0
- package/dist/styles/toggle.css +119 -0
- package/dist/styles/tool-activity.css +396 -0
- package/dist/styles/toolbar-status.css +52 -0
- package/dist/styles/tooltip.css +122 -0
- package/dist/styles/typed-text.css +17 -0
- package/package.json +452 -4
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
3
|
+
export declare const messageAlignNames: readonly ["start", "end"];
|
|
4
|
+
export declare const messageBubbleVariantNames: readonly ["default", "secondary", "muted", "tinted", "outline", "ghost", "destructive"];
|
|
5
|
+
export declare const messageReactionsSideNames: readonly ["top", "bottom"];
|
|
6
|
+
export type MessageAlign = (typeof messageAlignNames)[number];
|
|
7
|
+
export type MessageBubbleVariant = (typeof messageBubbleVariantNames)[number];
|
|
8
|
+
export type MessageReactionsSide = (typeof messageReactionsSideNames)[number];
|
|
9
|
+
export type MessageGroupProps = ComponentProps<"div">;
|
|
10
|
+
/** Stacks messages 8px apart. */
|
|
11
|
+
export declare function MessageGroup({ className, ...props }: MessageGroupProps): import("react").JSX.Element;
|
|
12
|
+
export interface MessageProps extends ComponentProps<"div"> {
|
|
13
|
+
/** `"end"` puts the message on the trailing side, for your own messages. */
|
|
14
|
+
align?: MessageAlign;
|
|
15
|
+
}
|
|
16
|
+
/** One chat message: an optional avatar beside its content. */
|
|
17
|
+
export declare function Message({ align, className, ...props }: MessageProps): import("react").JSX.Element;
|
|
18
|
+
export type MessageAvatarProps = ComponentProps<"div">;
|
|
19
|
+
/** Holds an avatar at the bottom of the message, beside the last bubble. */
|
|
20
|
+
export declare function MessageAvatar({ className, ...props }: MessageAvatarProps): import("react").JSX.Element;
|
|
21
|
+
export type MessageContentProps = ComponentProps<"div">;
|
|
22
|
+
/** The column of header, bubbles, cards, and footer. Slotted children follow `align`. */
|
|
23
|
+
export declare function MessageContent({ className, ...props }: MessageContentProps): import("react").JSX.Element;
|
|
24
|
+
export type MessageHeaderProps = ComponentProps<"div">;
|
|
25
|
+
/** A small muted line above the content, such as a name and time. */
|
|
26
|
+
export declare function MessageHeader({ className, ...props }: MessageHeaderProps): import("react").JSX.Element;
|
|
27
|
+
export type MessageFooterProps = ComponentProps<"div">;
|
|
28
|
+
/** A small muted line below the content, such as delivery or reply status. */
|
|
29
|
+
export declare function MessageFooter({ className, ...props }: MessageFooterProps): import("react").JSX.Element;
|
|
30
|
+
export interface MessageBubbleState extends Record<string, unknown> {
|
|
31
|
+
slot: "message-bubble";
|
|
32
|
+
variant: MessageBubbleVariant;
|
|
33
|
+
}
|
|
34
|
+
export type MessageBubbleProps = useRender.ComponentProps<"div", MessageBubbleState> & {
|
|
35
|
+
/** Fill. `"ghost"` drops the fill and padding and may span the full width. */
|
|
36
|
+
variant?: MessageBubbleVariant | undefined;
|
|
37
|
+
/** A `MessageReactions` pill pinned over the bubble's edge. */
|
|
38
|
+
reactions?: ReactNode;
|
|
39
|
+
};
|
|
40
|
+
/** A filled chat bubble. Use `render` for a `button` or `a` to make the whole bubble act. */
|
|
41
|
+
export declare function MessageBubble({ variant, reactions, className, render, ref, ...props }: MessageBubbleProps): import("react").JSX.Element;
|
|
42
|
+
export interface MessageReactionsProps extends ComponentProps<"div"> {
|
|
43
|
+
/** Edge of the bubble the pill overlaps. */
|
|
44
|
+
side?: MessageReactionsSide | undefined;
|
|
45
|
+
/** Corner of that edge, 12px in from the bubble's side. */
|
|
46
|
+
align?: MessageAlign | undefined;
|
|
47
|
+
}
|
|
48
|
+
/** A small pill of reactions for the `reactions` prop of `MessageBubble`. */
|
|
49
|
+
export declare function MessageReactions({ side, align, className, ...props }: MessageReactionsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { mergeProps } from "@base-ui/react/merge-props";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
|
+
import { cn } from "../internal/classes.js";
|
|
5
|
+
export const messageAlignNames = ["start", "end"];
|
|
6
|
+
export const messageBubbleVariantNames = [
|
|
7
|
+
"default",
|
|
8
|
+
"secondary",
|
|
9
|
+
"muted",
|
|
10
|
+
"tinted",
|
|
11
|
+
"outline",
|
|
12
|
+
"ghost",
|
|
13
|
+
"destructive",
|
|
14
|
+
];
|
|
15
|
+
export const messageReactionsSideNames = ["top", "bottom"];
|
|
16
|
+
/** Stacks messages 8px apart. */
|
|
17
|
+
export function MessageGroup({ className, ...props }) {
|
|
18
|
+
return (_jsx("div", { "data-slot": "message-group", className: cn("sprout-message-group", className), ...props }));
|
|
19
|
+
}
|
|
20
|
+
/** One chat message: an optional avatar beside its content. */
|
|
21
|
+
export function Message({ align = "start", className, ...props }) {
|
|
22
|
+
return (_jsx("div", { "data-slot": "message", "data-align": align, className: cn("sprout-message", className), ...props }));
|
|
23
|
+
}
|
|
24
|
+
/** Holds an avatar at the bottom of the message, beside the last bubble. */
|
|
25
|
+
export function MessageAvatar({ className, ...props }) {
|
|
26
|
+
return (_jsx("div", { "data-slot": "message-avatar", className: cn("sprout-message-avatar", className), ...props }));
|
|
27
|
+
}
|
|
28
|
+
/** The column of header, bubbles, cards, and footer. Slotted children follow `align`. */
|
|
29
|
+
export function MessageContent({ className, ...props }) {
|
|
30
|
+
return (_jsx("div", { "data-slot": "message-content", className: cn("sprout-message-content", className), ...props }));
|
|
31
|
+
}
|
|
32
|
+
/** A small muted line above the content, such as a name and time. */
|
|
33
|
+
export function MessageHeader({ className, ...props }) {
|
|
34
|
+
return (_jsx("div", { "data-slot": "message-header", className: cn("sprout-message-header", className), ...props }));
|
|
35
|
+
}
|
|
36
|
+
/** A small muted line below the content, such as delivery or reply status. */
|
|
37
|
+
export function MessageFooter({ className, ...props }) {
|
|
38
|
+
return (_jsx("div", { "data-slot": "message-footer", className: cn("sprout-message-footer", className), ...props }));
|
|
39
|
+
}
|
|
40
|
+
/** A filled chat bubble. Use `render` for a `button` or `a` to make the whole bubble act. */
|
|
41
|
+
export function MessageBubble({ variant = "default", reactions, className, render, ref, ...props }) {
|
|
42
|
+
const bubble = useRender({
|
|
43
|
+
defaultTagName: "div",
|
|
44
|
+
ref,
|
|
45
|
+
render,
|
|
46
|
+
props: mergeProps({
|
|
47
|
+
className: cn("sprout-message-bubble", `sprout-message-bubble-${variant}`, className),
|
|
48
|
+
}, props),
|
|
49
|
+
state: { slot: "message-bubble", variant },
|
|
50
|
+
});
|
|
51
|
+
if (reactions == null || reactions === false)
|
|
52
|
+
return bubble;
|
|
53
|
+
// Reactions often hold buttons, which can't sit inside a bubble rendered as a button or link.
|
|
54
|
+
return (_jsxs("div", { "data-slot": "message-bubble-frame", "data-variant": variant, className: "sprout-message-bubble-frame", children: [bubble, reactions] }));
|
|
55
|
+
}
|
|
56
|
+
/** A small pill of reactions for the `reactions` prop of `MessageBubble`. */
|
|
57
|
+
export function MessageReactions({ side = "bottom", align = "end", className, ...props }) {
|
|
58
|
+
return (_jsx("div", { "data-slot": "message-reactions", "data-align": align, "data-side": side, className: cn("sprout-message-reactions", className), ...props }));
|
|
59
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { NavigationMenu as NavigationMenuPrimitive } from "@base-ui/react/navigation-menu";
|
|
2
|
+
type Align = NonNullable<NavigationMenuPrimitive.Positioner.Props["align"]>;
|
|
3
|
+
export interface NavigationMenuProps extends NavigationMenuPrimitive.Root.Props {
|
|
4
|
+
/** Where the shared panel lines up with the open trigger. Defaults to `"start"`. */
|
|
5
|
+
align?: Align;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A row of site links where some items open a panel of more links. It
|
|
9
|
+
* renders the shared panel itself, so put `NavigationMenuList` directly inside.
|
|
10
|
+
*/
|
|
11
|
+
export declare function NavigationMenu({ align, className, children, ...props }: NavigationMenuProps): import("react").JSX.Element;
|
|
12
|
+
export type NavigationMenuListProps = NavigationMenuPrimitive.List.Props;
|
|
13
|
+
export declare function NavigationMenuList({ className, ...props }: NavigationMenuListProps): import("react").JSX.Element;
|
|
14
|
+
export type NavigationMenuItemProps = NavigationMenuPrimitive.Item.Props;
|
|
15
|
+
export declare function NavigationMenuItem({ className, ...props }: NavigationMenuItemProps): import("react").JSX.Element;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the trigger class string. Add it to a top-level `NavigationMenuLink`
|
|
18
|
+
* (or any link) so it matches the triggers beside it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function navigationMenuTriggerStyle(className?: string): string;
|
|
21
|
+
export type NavigationMenuTriggerProps = NavigationMenuPrimitive.Trigger.Props;
|
|
22
|
+
/** Opens its item's `NavigationMenuContent`. A chevron turns while open. */
|
|
23
|
+
export declare function NavigationMenuTrigger({ className, children, ...props }: NavigationMenuTriggerProps): import("react").JSX.Element;
|
|
24
|
+
export type NavigationMenuContentProps = NavigationMenuPrimitive.Content.Props;
|
|
25
|
+
/** The panel for one item. It is moved into the shared popup while open. */
|
|
26
|
+
export declare function NavigationMenuContent({ className, ...props }: NavigationMenuContentProps): import("react").JSX.Element;
|
|
27
|
+
export type NavigationMenuPositionerProps = NavigationMenuPrimitive.Positioner.Props;
|
|
28
|
+
/**
|
|
29
|
+
* The portal, positioner, popup, and viewport that show the open panel.
|
|
30
|
+
* `NavigationMenu` already renders one; use this only to build a root by hand.
|
|
31
|
+
*/
|
|
32
|
+
export declare function NavigationMenuPositioner({ className, side, sideOffset, align, alignOffset, collisionPadding, ...props }: NavigationMenuPositionerProps): import("react").JSX.Element;
|
|
33
|
+
export type NavigationMenuLinkProps = NavigationMenuPrimitive.Link.Props;
|
|
34
|
+
/**
|
|
35
|
+
* A link in the list or inside a panel. Pass `active` for the current page
|
|
36
|
+
* (sets `aria-current="page"`) and your router link through `render`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function NavigationMenuLink({ className, ...props }: NavigationMenuLinkProps): import("react").JSX.Element;
|
|
39
|
+
export type NavigationMenuIndicatorProps = NavigationMenuPrimitive.Icon.Props;
|
|
40
|
+
/**
|
|
41
|
+
* A small pointer under an item's trigger that shows while its panel is open.
|
|
42
|
+
* Place it inside `NavigationMenuItem`, after the trigger.
|
|
43
|
+
*/
|
|
44
|
+
export declare function NavigationMenuIndicator({ className, children, ...props }: NavigationMenuIndicatorProps): import("react").JSX.Element;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { NavigationMenu as NavigationMenuPrimitive } from "@base-ui/react/navigation-menu";
|
|
4
|
+
import { ChevronDown } from "reicon-react/icons/ChevronDown";
|
|
5
|
+
import { cn, stateClassName } from "../internal/classes.js";
|
|
6
|
+
/**
|
|
7
|
+
* A row of site links where some items open a panel of more links. It
|
|
8
|
+
* renders the shared panel itself, so put `NavigationMenuList` directly inside.
|
|
9
|
+
*/
|
|
10
|
+
export function NavigationMenu({ align = "start", className, children, ...props }) {
|
|
11
|
+
return (_jsxs(NavigationMenuPrimitive.Root, { "data-slot": "navigation-menu", ...props, className: stateClassName("sprout-navigation-menu", className), children: [children, _jsx(NavigationMenuPositioner, { align: align })] }));
|
|
12
|
+
}
|
|
13
|
+
export function NavigationMenuList({ className, ...props }) {
|
|
14
|
+
return (_jsx(NavigationMenuPrimitive.List, { "data-slot": "navigation-menu-list", ...props, className: stateClassName("sprout-navigation-menu-list", className) }));
|
|
15
|
+
}
|
|
16
|
+
export function NavigationMenuItem({ className, ...props }) {
|
|
17
|
+
return (_jsx(NavigationMenuPrimitive.Item, { "data-slot": "navigation-menu-item", ...props, className: stateClassName("sprout-navigation-menu-item", className) }));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns the trigger class string. Add it to a top-level `NavigationMenuLink`
|
|
21
|
+
* (or any link) so it matches the triggers beside it.
|
|
22
|
+
*/
|
|
23
|
+
export function navigationMenuTriggerStyle(className) {
|
|
24
|
+
return cn("sprout-navigation-menu-trigger", className);
|
|
25
|
+
}
|
|
26
|
+
/** Opens its item's `NavigationMenuContent`. A chevron turns while open. */
|
|
27
|
+
export function NavigationMenuTrigger({ className, children, ...props }) {
|
|
28
|
+
return (_jsxs(NavigationMenuPrimitive.Trigger, { "data-slot": "navigation-menu-trigger", ...props, className: stateClassName("sprout-navigation-menu-trigger", className), children: [children, _jsx(NavigationMenuPrimitive.Icon, { "data-slot": "navigation-menu-chevron", className: "sprout-navigation-menu-chevron", children: _jsx(ChevronDown, {}) })] }));
|
|
29
|
+
}
|
|
30
|
+
/** The panel for one item. It is moved into the shared popup while open. */
|
|
31
|
+
export function NavigationMenuContent({ className, ...props }) {
|
|
32
|
+
return (_jsx(NavigationMenuPrimitive.Content, { "data-slot": "navigation-menu-content", ...props, className: stateClassName("sprout-navigation-menu-content", className) }));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The portal, positioner, popup, and viewport that show the open panel.
|
|
36
|
+
* `NavigationMenu` already renders one; use this only to build a root by hand.
|
|
37
|
+
*/
|
|
38
|
+
export function NavigationMenuPositioner({ className, side = "bottom", sideOffset = 8, align = "start", alignOffset = 0, collisionPadding = 8, ...props }) {
|
|
39
|
+
return (_jsx(NavigationMenuPrimitive.Portal, { "data-slot": "navigation-menu-portal", children: _jsx(NavigationMenuPrimitive.Positioner, { "data-slot": "navigation-menu-positioner", side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset, collisionPadding: collisionPadding, ...props, className: stateClassName("sprout-navigation-menu-positioner", className), children: _jsx(NavigationMenuPrimitive.Popup, { "data-slot": "navigation-menu-popup", className: "sprout-navigation-menu-popup", children: _jsx(NavigationMenuPrimitive.Viewport, { "data-slot": "navigation-menu-viewport", className: "sprout-navigation-menu-viewport" }) }) }) }));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A link in the list or inside a panel. Pass `active` for the current page
|
|
43
|
+
* (sets `aria-current="page"`) and your router link through `render`.
|
|
44
|
+
*/
|
|
45
|
+
export function NavigationMenuLink({ className, ...props }) {
|
|
46
|
+
return (_jsx(NavigationMenuPrimitive.Link, { "data-slot": "navigation-menu-link", ...props, className: stateClassName("sprout-navigation-menu-link", className) }));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A small pointer under an item's trigger that shows while its panel is open.
|
|
50
|
+
* Place it inside `NavigationMenuItem`, after the trigger.
|
|
51
|
+
*/
|
|
52
|
+
export function NavigationMenuIndicator({ className, children, ...props }) {
|
|
53
|
+
return (_jsx(NavigationMenuPrimitive.Icon, { "data-slot": "navigation-menu-indicator", ...props, className: stateClassName("sprout-navigation-menu-indicator", className), children: children ?? _jsx("span", { className: "sprout-navigation-menu-indicator-arrow" }) }));
|
|
54
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
export interface NoticeBannerProps extends Omit<ComponentProps<"section">, "children"> {
|
|
3
|
+
/** The message. Put `role="status"` or `role="alert"` on it when it changes. */
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/** Controls for the notice, such as buttons or a select. They wrap. */
|
|
6
|
+
actions?: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A full-width strip at the top of a page for something that needs action,
|
|
10
|
+
* such as an integration that needs authorization. The message and actions
|
|
11
|
+
* stack on narrow screens and sit on one row from 640px. Name the region
|
|
12
|
+
* with `aria-label`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function NoticeBanner({ children, actions, className, ...props }: NoticeBannerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../internal/classes.js";
|
|
3
|
+
/**
|
|
4
|
+
* A full-width strip at the top of a page for something that needs action,
|
|
5
|
+
* such as an integration that needs authorization. The message and actions
|
|
6
|
+
* stack on narrow screens and sit on one row from 640px. Name the region
|
|
7
|
+
* with `aria-label`.
|
|
8
|
+
*/
|
|
9
|
+
export function NoticeBanner({ children, actions, className, ...props }) {
|
|
10
|
+
return (_jsxs("section", { "data-slot": "notice-banner", className: cn("sprout-notice-banner", className), ...props, children: [_jsx("div", { "data-slot": "notice-banner-content", className: "sprout-notice-banner-content", children: children }), actions != null && actions !== false && (_jsx("div", { "data-slot": "notice-banner-actions", className: "sprout-notice-banner-actions", children: actions }))] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
export type PageContentProps = ComponentProps<"div">;
|
|
3
|
+
/**
|
|
4
|
+
* The padded column that holds a page's header and sections. Direct children
|
|
5
|
+
* are stacked 16px apart. Put it inside your own scroll region.
|
|
6
|
+
*/
|
|
7
|
+
export declare function PageContent({ className, ...props }: PageContentProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../internal/classes.js";
|
|
3
|
+
/**
|
|
4
|
+
* The padded column that holds a page's header and sections. Direct children
|
|
5
|
+
* are stacked 16px apart. Put it inside your own scroll region.
|
|
6
|
+
*/
|
|
7
|
+
export function PageContent({ className, ...props }) {
|
|
8
|
+
return (_jsx("div", { "data-slot": "page-content", className: cn("sprout-page-content", className), ...props }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ReactElement, type ReactNode, type Ref } from "react";
|
|
2
|
+
export interface PageChrome {
|
|
3
|
+
/** App header element that receives the back link and page title. */
|
|
4
|
+
title: HTMLElement | null;
|
|
5
|
+
/** App header element that receives page actions. */
|
|
6
|
+
actions: HTMLElement | null;
|
|
7
|
+
/** Formats `document.title` from a string page title. Omit to leave it alone. */
|
|
8
|
+
documentTitle?: ((title: string) => string) | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare const PageChromeContext: import("react").Context<PageChrome>;
|
|
11
|
+
export interface PageLink {
|
|
12
|
+
/** Visible text, and the accessible name when the back label is hidden. */
|
|
13
|
+
label: string;
|
|
14
|
+
/** Link element to render, such as `<a href />` or a router link. */
|
|
15
|
+
link: ReactElement;
|
|
16
|
+
}
|
|
17
|
+
export interface PageHeaderProps {
|
|
18
|
+
title: ReactNode;
|
|
19
|
+
description?: ReactNode;
|
|
20
|
+
actions?: ReactNode;
|
|
21
|
+
/** Back link above the title. Below 640px only its chevron shows. */
|
|
22
|
+
back?: PageLink | undefined;
|
|
23
|
+
/** Shows the title as the last step of a breadcrumb under this parent page. */
|
|
24
|
+
parent?: PageLink | undefined;
|
|
25
|
+
titleId?: string | undefined;
|
|
26
|
+
titleRef?: Ref<HTMLHeadingElement> | undefined;
|
|
27
|
+
/** Lets code move focus to the title, for example after navigation. */
|
|
28
|
+
focusable?: boolean | undefined;
|
|
29
|
+
className?: string | undefined;
|
|
30
|
+
}
|
|
31
|
+
export declare function PageHeader({ title, description, actions, back, parent, titleId, titleRef, focusable, className, }: PageHeaderProps): import("react").JSX.Element;
|
|
32
|
+
export interface PageActionsProps {
|
|
33
|
+
children: ReactNode;
|
|
34
|
+
className?: string | undefined;
|
|
35
|
+
}
|
|
36
|
+
/** Page-level actions without a header: moved into the app header when one is provided. */
|
|
37
|
+
export declare function PageActions({ children, className }: PageActionsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useEffect, } from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
6
|
+
import { ChevronLeft } from "reicon-react/icons/ChevronLeft";
|
|
7
|
+
import { ChevronRight } from "reicon-react/icons/ChevronRight";
|
|
8
|
+
import { cn } from "../internal/classes.js";
|
|
9
|
+
import { Button } from "./button.js";
|
|
10
|
+
export const PageChromeContext = createContext({
|
|
11
|
+
title: null,
|
|
12
|
+
actions: null,
|
|
13
|
+
});
|
|
14
|
+
function ParentLink({ link, label }) {
|
|
15
|
+
return useRender({
|
|
16
|
+
defaultTagName: "a",
|
|
17
|
+
render: link,
|
|
18
|
+
props: {
|
|
19
|
+
"data-slot": "page-breadcrumb-link",
|
|
20
|
+
className: "sprout-page-header-breadcrumb-link",
|
|
21
|
+
children: label,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function PageHeader({ title, description, actions, back, parent, titleId, titleRef, focusable, className, }) {
|
|
26
|
+
const chrome = useContext(PageChromeContext);
|
|
27
|
+
const format = chrome.documentTitle;
|
|
28
|
+
const text = typeof title === "string" ? title : null;
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!text || !format)
|
|
31
|
+
return;
|
|
32
|
+
const previous = document.title;
|
|
33
|
+
document.title = format(text);
|
|
34
|
+
return () => {
|
|
35
|
+
document.title = previous;
|
|
36
|
+
};
|
|
37
|
+
}, [text, format]);
|
|
38
|
+
const inChrome = !!(chrome.title && chrome.actions);
|
|
39
|
+
const placement = inChrome ? "chrome" : "page";
|
|
40
|
+
const heading = (_jsx("h1", { id: titleId, ref: titleRef, tabIndex: focusable ? -1 : undefined, "data-slot": "page-title", "data-placement": placement, className: "sprout-page-header-title", children: title }));
|
|
41
|
+
const trail = parent && (_jsx("nav", { "aria-label": "Breadcrumb", "data-slot": "page-breadcrumb", "data-placement": placement, className: "sprout-page-header-breadcrumb", children: _jsxs("ol", { className: "sprout-page-header-breadcrumb-list", children: [_jsx("li", { className: "sprout-page-header-breadcrumb-item", children: _jsx(ParentLink, { ...parent }) }), _jsx("li", { role: "presentation", "aria-hidden": "true", className: "sprout-page-header-breadcrumb-separator", children: _jsx(ChevronRight, { size: 14 }) }), _jsx("li", { "aria-current": "page", className: "sprout-page-header-breadcrumb-item sprout-page-header-breadcrumb-current", children: heading })] }) }));
|
|
42
|
+
const backButton = back && (_jsxs(Button, { variant: "ghost", size: "back", nativeButton: false, render: back.link, "data-slot": "page-back", className: "sprout-page-header-back", children: [_jsx(ChevronLeft, { "data-icon": "inline-start", "aria-hidden": "true" }), _jsx("span", { className: "sprout-page-header-back-label", children: back.label })] }));
|
|
43
|
+
if (inChrome) {
|
|
44
|
+
return (_jsxs(_Fragment, { children: [createPortal(_jsxs(_Fragment, { children: [backButton, trail ?? heading] }), chrome.title), actions &&
|
|
45
|
+
createPortal(_jsx("div", { "data-slot": "page-actions", "data-placement": "chrome", className: "sprout-page-header-actions", children: actions }), chrome.actions), description && (_jsx("p", { "data-slot": "page-description", className: cn("sprout-page-header-description", className), children: description }))] }));
|
|
46
|
+
}
|
|
47
|
+
return (_jsxs("header", { "data-slot": "page-header", className: cn("sprout-page-header", className), children: [backButton, _jsxs("div", { className: "sprout-page-header-row", children: [_jsxs("div", { className: "sprout-page-header-text", children: [trail ?? heading, description && (_jsx("p", { "data-slot": "page-description", className: "sprout-page-header-description", children: description }))] }), actions && (_jsx("div", { "data-slot": "page-actions", "data-placement": "page", className: "sprout-page-header-actions", children: actions }))] })] }));
|
|
48
|
+
}
|
|
49
|
+
/** Page-level actions without a header: moved into the app header when one is provided. */
|
|
50
|
+
export function PageActions({ children, className }) {
|
|
51
|
+
const { actions } = useContext(PageChromeContext);
|
|
52
|
+
return actions ? (createPortal(_jsx("div", { "data-slot": "page-actions", "data-placement": "chrome", className: cn("sprout-page-header-actions", className), children: children }), actions)) : (_jsx("div", { "data-slot": "page-actions", "data-placement": "inline", className: cn("sprout-page-header-actions", className), children: children }));
|
|
53
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import { type ButtonProps, type ButtonSize } from "./button.js";
|
|
3
|
+
export type PaginationProps = ComponentProps<"nav">;
|
|
4
|
+
export declare function Pagination({ className, "aria-label": label, ...props }: PaginationProps): import("react").JSX.Element;
|
|
5
|
+
export type PaginationContentProps = ComponentProps<"ul">;
|
|
6
|
+
export declare function PaginationContent({ className, ...props }: PaginationContentProps): import("react").JSX.Element;
|
|
7
|
+
export type PaginationItemProps = ComponentProps<"li">;
|
|
8
|
+
export declare function PaginationItem({ className, ...props }: PaginationItemProps): import("react").JSX.Element;
|
|
9
|
+
export interface PaginationLinkProps extends Omit<ComponentProps<"a">, "className"> {
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Marks the current page: outline style and `aria-current="page"`. */
|
|
12
|
+
isActive?: boolean;
|
|
13
|
+
/** Any Sprout `Button` size. Page numbers default to `icon`. */
|
|
14
|
+
size?: ButtonSize;
|
|
15
|
+
/** Sets `aria-disabled`, removes the link from the tab order, and blocks clicks. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Swap the `a` for a router link, as with Base UI `render`. */
|
|
18
|
+
render?: ButtonProps["render"];
|
|
19
|
+
}
|
|
20
|
+
export declare function PaginationLink({ className, isActive, size, render, ...props }: PaginationLinkProps): import("react").JSX.Element;
|
|
21
|
+
export interface PaginationDirectionProps extends PaginationLinkProps {
|
|
22
|
+
/** Visible label. It is hidden below 640px, where only the chevron shows. */
|
|
23
|
+
text?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function PaginationPrevious({ className, text, ...props }: PaginationDirectionProps): import("react").JSX.Element;
|
|
26
|
+
export declare function PaginationNext({ className, text, ...props }: PaginationDirectionProps): import("react").JSX.Element;
|
|
27
|
+
export type PaginationEllipsisProps = ComponentProps<"span">;
|
|
28
|
+
/** Marks skipped pages. It is hidden from screen readers. */
|
|
29
|
+
export declare function PaginationEllipsis({ className, ...props }: PaginationEllipsisProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronLeft } from "reicon-react/icons/ChevronLeft";
|
|
4
|
+
import { ChevronRight } from "reicon-react/icons/ChevronRight";
|
|
5
|
+
import { MoreH } from "reicon-react/icons/MoreH";
|
|
6
|
+
import { cn } from "../internal/classes.js";
|
|
7
|
+
import { Button } from "./button.js";
|
|
8
|
+
export function Pagination({ className, "aria-label": label = "pagination", ...props }) {
|
|
9
|
+
return (_jsx("nav", { role: "navigation", "aria-label": label, "data-slot": "pagination", className: cn("sprout-pagination", className), ...props }));
|
|
10
|
+
}
|
|
11
|
+
export function PaginationContent({ className, ...props }) {
|
|
12
|
+
return (_jsx("ul", { "data-slot": "pagination-content", className: cn("sprout-pagination-content", className), ...props }));
|
|
13
|
+
}
|
|
14
|
+
export function PaginationItem({ className, ...props }) {
|
|
15
|
+
return (_jsx("li", { "data-slot": "pagination-item", className: cn("sprout-pagination-item", className), ...props }));
|
|
16
|
+
}
|
|
17
|
+
export function PaginationLink({ className, isActive, size = "icon", render, ...props }) {
|
|
18
|
+
return (_jsx(Button, { variant: isActive ? "outline" : "ghost", size: size, nativeButton: false, render: render, ...props, "aria-current": isActive ? "page" : undefined, "data-slot": "pagination-link", "data-active": isActive ? "true" : undefined, className: cn("sprout-pagination-link", className) }));
|
|
19
|
+
}
|
|
20
|
+
export function PaginationPrevious({ className, text = "Previous", ...props }) {
|
|
21
|
+
return (_jsxs(PaginationLink, { "aria-label": "Go to previous page", size: "default", className: cn("sprout-pagination-previous", className), ...props, children: [_jsx(ChevronLeft, { "data-icon": "inline-start", "aria-hidden": "true" }), _jsx("span", { className: "sprout-pagination-label", children: text })] }));
|
|
22
|
+
}
|
|
23
|
+
export function PaginationNext({ className, text = "Next", ...props }) {
|
|
24
|
+
return (_jsxs(PaginationLink, { "aria-label": "Go to next page", size: "default", className: cn("sprout-pagination-next", className), ...props, children: [_jsx("span", { className: "sprout-pagination-label", children: text }), _jsx(ChevronRight, { "data-icon": "inline-end", "aria-hidden": "true" })] }));
|
|
25
|
+
}
|
|
26
|
+
/** Marks skipped pages. It is hidden from screen readers. */
|
|
27
|
+
export function PaginationEllipsis({ className, ...props }) {
|
|
28
|
+
return (_jsxs("span", { "aria-hidden": "true", "data-slot": "pagination-ellipsis", className: cn("sprout-pagination-ellipsis", className), ...props, children: [_jsx(MoreH, {}), _jsx("span", { className: "sprout-pagination-sr-only", children: "More pages" })] }));
|
|
29
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactNode } from "react";
|
|
2
|
+
export declare const planOutlineMarkNames: readonly ["pending", "running", "attention", "blocked", "done", "failed", "cancelled"];
|
|
3
|
+
/** How a task row is marked. Every mark is paired with a text label; color is never the only signal. */
|
|
4
|
+
export type PlanOutlineMark = (typeof planOutlineMarkNames)[number];
|
|
5
|
+
export declare const planOutlineToneNames: readonly ["active", "attention", "done", "failed", "neutral"];
|
|
6
|
+
/** The color of the plan's status badge. */
|
|
7
|
+
export type PlanOutlineTone = (typeof planOutlineToneNames)[number];
|
|
8
|
+
export type PlanOutlineDependency = {
|
|
9
|
+
/** The `id` of the task this one waits for. The title links to its row. */
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
/** That task's state in words, such as “Done” or “Working”. */
|
|
13
|
+
label: string;
|
|
14
|
+
};
|
|
15
|
+
export type PlanOutlineTask = {
|
|
16
|
+
id: string;
|
|
17
|
+
title: string;
|
|
18
|
+
mark: PlanOutlineMark;
|
|
19
|
+
/** The state in words, shown at the end of the row. */
|
|
20
|
+
label: string;
|
|
21
|
+
/** Who does the task. Shown under the title with a person icon. */
|
|
22
|
+
assignee?: string | undefined;
|
|
23
|
+
/** What the task is about. Groups show it above their tasks. */
|
|
24
|
+
brief?: string | undefined;
|
|
25
|
+
/** Shown as “Done when”. */
|
|
26
|
+
criteria?: readonly string[] | undefined;
|
|
27
|
+
/** Shown as “Starts after”, each linking to its row. */
|
|
28
|
+
dependencies?: readonly PlanOutlineDependency[] | undefined;
|
|
29
|
+
/** Why the task is blocked or failed. Failed reasons use the danger color. */
|
|
30
|
+
reason?: string | undefined;
|
|
31
|
+
/** Buttons or extra content at the end of the task's details. */
|
|
32
|
+
action?: ReactNode;
|
|
33
|
+
/** Makes the row a group. Groups start open and list these tasks. */
|
|
34
|
+
children?: readonly PlanOutlineTask[] | undefined;
|
|
35
|
+
};
|
|
36
|
+
export interface PlanOutlineProps extends Omit<ComponentProps<"section">, "title" | "children"> {
|
|
37
|
+
/** The plan name. It names the section and shows as an `h3`. */
|
|
38
|
+
title: string;
|
|
39
|
+
/** One paragraph under the title. */
|
|
40
|
+
brief?: string | undefined;
|
|
41
|
+
/** The plan's state in words, shown in a badge. */
|
|
42
|
+
status: string;
|
|
43
|
+
/** The badge color for `status`. */
|
|
44
|
+
tone: PlanOutlineTone;
|
|
45
|
+
/** Progress in words under the bar, such as “3 of 8 done · 1 working”. */
|
|
46
|
+
progress: string;
|
|
47
|
+
/** Alerts or sections under the progress, such as why the plan paused. */
|
|
48
|
+
notice?: ReactNode;
|
|
49
|
+
/** Tasks and groups, in order. With none, the outline says so. */
|
|
50
|
+
tasks: readonly PlanOutlineTask[];
|
|
51
|
+
/** A note that the plan shown is out of date, under the notice. */
|
|
52
|
+
stale?: ReactNode;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A read-only task outline for an agent's plan. People can expand rows and
|
|
56
|
+
* follow links; they cannot tick, edit, reorder, or assign tasks. Groups list
|
|
57
|
+
* their tasks and start open; tasks reveal their brief, completion criteria,
|
|
58
|
+
* dependencies, reason, and actions on demand.
|
|
59
|
+
*/
|
|
60
|
+
export declare function PlanOutline({ title, brief, status, tone, progress, notice, tasks, stale, className, ...props }: PlanOutlineProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Collapsible } from "@base-ui/react/collapsible";
|
|
4
|
+
import { createContext, useContext, useId, } from "react";
|
|
5
|
+
import { Ban } from "reicon-react/icons/Ban";
|
|
6
|
+
import { Check } from "reicon-react/icons/Check";
|
|
7
|
+
import { ChevronRight } from "reicon-react/icons/ChevronRight";
|
|
8
|
+
import { Clock } from "reicon-react/icons/Clock";
|
|
9
|
+
import { HelpCircle } from "reicon-react/icons/HelpCircle";
|
|
10
|
+
import { Lock } from "reicon-react/icons/Lock";
|
|
11
|
+
import { User } from "reicon-react/icons/User";
|
|
12
|
+
import { Warning } from "reicon-react/icons/Warning";
|
|
13
|
+
import { cn } from "../internal/classes.js";
|
|
14
|
+
import { Badge } from "./badge.js";
|
|
15
|
+
import { Spinner } from "./spinner.js";
|
|
16
|
+
export const planOutlineMarkNames = [
|
|
17
|
+
"pending",
|
|
18
|
+
"running",
|
|
19
|
+
"attention",
|
|
20
|
+
"blocked",
|
|
21
|
+
"done",
|
|
22
|
+
"failed",
|
|
23
|
+
"cancelled",
|
|
24
|
+
];
|
|
25
|
+
export const planOutlineToneNames = [
|
|
26
|
+
"active",
|
|
27
|
+
"attention",
|
|
28
|
+
"done",
|
|
29
|
+
"failed",
|
|
30
|
+
"neutral",
|
|
31
|
+
];
|
|
32
|
+
const markIcons = {
|
|
33
|
+
pending: _jsx(Clock, { size: 14 }),
|
|
34
|
+
attention: _jsx(HelpCircle, { size: 14 }),
|
|
35
|
+
blocked: _jsx(Lock, { size: 14 }),
|
|
36
|
+
done: _jsx(Check, { size: 14 }),
|
|
37
|
+
failed: _jsx(Warning, { size: 14 }),
|
|
38
|
+
cancelled: _jsx(Ban, { size: 14 }),
|
|
39
|
+
};
|
|
40
|
+
const toneBadges = {
|
|
41
|
+
active: "info",
|
|
42
|
+
attention: "warning",
|
|
43
|
+
done: "success",
|
|
44
|
+
failed: "destructive",
|
|
45
|
+
neutral: "secondary",
|
|
46
|
+
};
|
|
47
|
+
function leaves(tasks) {
|
|
48
|
+
return tasks.flatMap((task) => task.children
|
|
49
|
+
? leaves(task.children)
|
|
50
|
+
: task.mark === "cancelled"
|
|
51
|
+
? []
|
|
52
|
+
: [task]);
|
|
53
|
+
}
|
|
54
|
+
const Scope = createContext("plan");
|
|
55
|
+
function useTaskId() {
|
|
56
|
+
const scope = useContext(Scope);
|
|
57
|
+
return (id) => `${scope}-task-${id}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A read-only task outline for an agent's plan. People can expand rows and
|
|
61
|
+
* follow links; they cannot tick, edit, reorder, or assign tasks. Groups list
|
|
62
|
+
* their tasks and start open; tasks reveal their brief, completion criteria,
|
|
63
|
+
* dependencies, reason, and actions on demand.
|
|
64
|
+
*/
|
|
65
|
+
export function PlanOutline({ title, brief, status, tone, progress, notice, tasks, stale, className, ...props }) {
|
|
66
|
+
const scope = `plan-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
67
|
+
const work = leaves(tasks);
|
|
68
|
+
return (_jsx(Scope, { value: scope, children: _jsxs("section", { "data-slot": "plan-outline", "aria-label": title, ...props, className: cn("sprout-plan-outline", className), children: [_jsxs("header", { className: "sprout-plan-outline-header", children: [_jsxs("div", { className: "sprout-plan-outline-heading", children: [_jsx("h3", { className: "sprout-plan-outline-title", children: title }), _jsx(Badge, { variant: toneBadges[tone], "data-tone": tone, className: "sprout-plan-outline-status", children: status })] }), brief && _jsx("p", { className: "sprout-plan-outline-brief", children: brief }), _jsxs("div", { className: "sprout-plan-outline-progress", children: [work.length > 0 && (_jsx("div", { "aria-hidden": "true", "data-slot": "plan-outline-rail", className: "sprout-plan-outline-rail", children: work.map((task) => (_jsx("span", { "data-mark": task.mark, className: "sprout-plan-outline-segment" }, task.id))) })), _jsx("p", { className: "sprout-plan-outline-progress-text", children: progress })] }), notice, stale] }), tasks.length === 0 ? (_jsx("p", { className: "sprout-plan-outline-empty", children: "No tasks have been added yet." })) : (_jsx(TaskList, { tasks: tasks, label: "Tasks", level: 0 }))] }) }));
|
|
69
|
+
}
|
|
70
|
+
function TaskList({ tasks, label, level, }) {
|
|
71
|
+
return (_jsx("ol", { "aria-label": label, "data-level": level, className: level === 0
|
|
72
|
+
? "sprout-plan-outline-list"
|
|
73
|
+
: "sprout-plan-outline-list sprout-plan-outline-sublist", children: tasks.map((task) => (_jsx(TaskRow, { task: task, level: level }, task.id))) }));
|
|
74
|
+
}
|
|
75
|
+
function Mark({ mark }) {
|
|
76
|
+
return (_jsx("span", { "aria-hidden": "true", className: "sprout-plan-outline-mark", children: mark === "running" ? _jsx(Spinner, { "aria-hidden": "true" }) : markIcons[mark] }));
|
|
77
|
+
}
|
|
78
|
+
function TaskRow({ task, level }) {
|
|
79
|
+
const taskId = useTaskId();
|
|
80
|
+
const group = !!task.children;
|
|
81
|
+
const hasDetail = group ||
|
|
82
|
+
!!(task.brief ||
|
|
83
|
+
task.criteria?.length ||
|
|
84
|
+
task.dependencies?.length ||
|
|
85
|
+
task.reason ||
|
|
86
|
+
task.action);
|
|
87
|
+
const head = (_jsxs(_Fragment, { children: [_jsx(Mark, { mark: task.mark }), _jsxs("span", { className: "sprout-plan-outline-text", children: [_jsx("span", { className: "sprout-plan-outline-task-title", children: task.title }), task.assignee && (_jsxs("span", { className: "sprout-plan-outline-assignee", children: [_jsx(User, { size: 12, "aria-hidden": "true" }), _jsx("span", { children: task.assignee })] }))] }), _jsx("span", { className: "sprout-plan-outline-label", children: task.label }), hasDetail && (_jsx(ChevronRight, { size: 14, "aria-hidden": "true", className: "sprout-plan-outline-chevron" }))] }));
|
|
88
|
+
const rowProps = {
|
|
89
|
+
id: taskId(task.id),
|
|
90
|
+
tabIndex: -1,
|
|
91
|
+
"data-slot": "plan-outline-task",
|
|
92
|
+
"data-kind": group ? "group" : "task",
|
|
93
|
+
"data-mark": task.mark,
|
|
94
|
+
"data-level": level,
|
|
95
|
+
className: "sprout-plan-outline-task",
|
|
96
|
+
};
|
|
97
|
+
if (!hasDetail)
|
|
98
|
+
return (_jsx("li", { ...rowProps, children: _jsx("div", { className: "sprout-plan-outline-row", children: head }) }));
|
|
99
|
+
return (_jsxs(Collapsible.Root, { defaultOpen: group, render: _jsx("li", { ...rowProps }), children: [_jsx(Collapsible.Trigger, { className: "sprout-plan-outline-row sprout-plan-outline-trigger", children: head }), _jsx(Collapsible.Panel, { hiddenUntilFound: group, "data-slot": "plan-outline-panel", className: "sprout-plan-outline-panel", children: group ? (_jsxs(_Fragment, { children: [task.brief && (_jsx("p", { className: "sprout-plan-outline-group-brief", children: task.brief })), task.children.length ? (_jsx(TaskList, { tasks: task.children, label: `${task.title} tasks`, level: level + 1 })) : (_jsx("p", { className: "sprout-plan-outline-group-empty", children: "This group has no tasks yet." }))] })) : (_jsx(TaskDetail, { task: task })) })] }));
|
|
100
|
+
}
|
|
101
|
+
// The browser follows the link, which also opens a closed group; then focus moves to the row.
|
|
102
|
+
function followDependency(target) {
|
|
103
|
+
requestAnimationFrame(() => document.getElementById(target)?.focus({ preventScroll: true }));
|
|
104
|
+
}
|
|
105
|
+
function TaskDetail({ task }) {
|
|
106
|
+
const taskId = useTaskId();
|
|
107
|
+
return (_jsxs("div", { "data-slot": "plan-outline-detail", className: "sprout-plan-outline-detail", children: [task.reason && (_jsx("p", { className: "sprout-plan-outline-reason", children: task.reason })), task.brief && (_jsx("p", { className: "sprout-plan-outline-task-brief", children: task.brief })), !!task.criteria?.length && (_jsxs("div", { className: "sprout-plan-outline-field", children: [_jsx("p", { className: "sprout-plan-outline-field-title", children: "Done when" }), _jsx("ul", { className: "sprout-plan-outline-criteria", children: task.criteria.map((item, index) => (_jsx("li", { children: item }, index))) })] })), !!task.dependencies?.length && (_jsxs("div", { className: "sprout-plan-outline-field", children: [_jsx("p", { className: "sprout-plan-outline-field-title", children: "Starts after" }), _jsx("ul", { className: "sprout-plan-outline-dependencies", children: task.dependencies.map((dependency) => (_jsxs("li", { children: [_jsx("a", { href: `#${taskId(dependency.id)}`, onClick: () => followDependency(taskId(dependency.id)), className: "sprout-plan-outline-link", children: dependency.title }), _jsx("span", { className: "sprout-plan-outline-dependency-label", children: dependency.label })] }, dependency.id))) })] })), task.action && (_jsx("div", { className: "sprout-plan-outline-action", children: task.action }))] }));
|
|
108
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
|
|
3
|
+
export declare const popoverContentSizeNames: readonly ["default", "menu", "picker", "panel", "work-list", "app-actions", "bud"];
|
|
4
|
+
export type PopoverContentSize = (typeof popoverContentSizeNames)[number];
|
|
5
|
+
export type PopoverProps = PopoverPrimitive.Root.Props;
|
|
6
|
+
export declare function Popover(props: PopoverProps): import("react").JSX.Element;
|
|
7
|
+
export type PopoverTriggerProps = PopoverPrimitive.Trigger.Props;
|
|
8
|
+
export declare function PopoverTrigger(props: PopoverTriggerProps): import("react").JSX.Element;
|
|
9
|
+
type PositionerProps = Pick<PopoverPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset" | "anchor" | "collisionPadding" | "collisionAvoidance" | "sticky" | "positionMethod">;
|
|
10
|
+
export interface PopoverContentProps extends PopoverPrimitive.Popup.Props, PositionerProps {
|
|
11
|
+
/**
|
|
12
|
+
* `default` is an 18rem padded panel for text. `menu`, `picker`, and `panel`
|
|
13
|
+
* are unpadded hosts for search lists and forms. `work-list` caps the height
|
|
14
|
+
* for a header, a scrolling list, and a footer. `app-actions` is a padded
|
|
15
|
+
* 20rem panel that scrolls. `bud` is a fixed-height quick chat window.
|
|
16
|
+
*/
|
|
17
|
+
size?: PopoverContentSize;
|
|
18
|
+
/** Keep the content in the DOM while closed, for example to preserve chat state. */
|
|
19
|
+
keepMounted?: PopoverPrimitive.Portal.Props["keepMounted"];
|
|
20
|
+
/** Where the portal renders. Defaults to `document.body`. */
|
|
21
|
+
container?: PopoverPrimitive.Portal.Props["container"];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The floating panel. It renders its own portal and positioner, so place it
|
|
25
|
+
* directly inside `Popover`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function PopoverContent({ align, alignOffset, side, sideOffset, collisionPadding, collisionAvoidance, sticky, positionMethod, anchor, size, keepMounted, container, className, ...props }: PopoverContentProps): import("react").JSX.Element;
|
|
28
|
+
export type PopoverHeaderProps = ComponentProps<"div">;
|
|
29
|
+
export declare function PopoverHeader({ className, ...props }: PopoverHeaderProps): import("react").JSX.Element;
|
|
30
|
+
export type PopoverTitleProps = PopoverPrimitive.Title.Props;
|
|
31
|
+
export declare function PopoverTitle({ className, ...props }: PopoverTitleProps): import("react").JSX.Element;
|
|
32
|
+
export type PopoverDescriptionProps = PopoverPrimitive.Description.Props;
|
|
33
|
+
export declare function PopoverDescription({ className, ...props }: PopoverDescriptionProps): import("react").JSX.Element;
|
|
34
|
+
export {};
|