@djangocfg/ui-tools 2.1.415 → 2.1.417
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/dist/audio-player/index.cjs +2099 -0
- package/dist/audio-player/index.cjs.map +1 -0
- package/dist/audio-player/index.css +65 -0
- package/dist/audio-player/index.css.map +1 -0
- package/dist/audio-player/index.d.cts +174 -0
- package/dist/audio-player/index.d.ts +174 -0
- package/dist/audio-player/index.mjs +2076 -0
- package/dist/audio-player/index.mjs.map +1 -0
- package/dist/composer-registry/index.cjs +45 -0
- package/dist/composer-registry/index.cjs.map +1 -0
- package/dist/composer-registry/index.d.cts +73 -0
- package/dist/composer-registry/index.d.ts +73 -0
- package/dist/composer-registry/index.mjs +39 -0
- package/dist/composer-registry/index.mjs.map +1 -0
- package/dist/file-icon/index.d.cts +1 -1
- package/dist/file-icon/index.d.ts +1 -1
- package/dist/slots-ClRpIzoh.d.cts +88 -0
- package/dist/slots-ClRpIzoh.d.ts +88 -0
- package/dist/tree/index.cjs +2019 -279
- package/dist/tree/index.cjs.map +1 -1
- package/dist/tree/index.d.cts +731 -72
- package/dist/tree/index.d.ts +731 -72
- package/dist/tree/index.mjs +2009 -282
- package/dist/tree/index.mjs.map +1 -1
- package/package.json +18 -9
- package/src/tools/chat/README.md +111 -1
- package/src/tools/chat/composer/Composer.tsx +146 -25
- package/src/tools/chat/composer/ComposerRichTextarea.tsx +25 -0
- package/src/tools/chat/composer/index.ts +22 -0
- package/src/tools/chat/composer/slash/README.md +187 -0
- package/src/tools/chat/composer/slash/SlashHighlightTextarea.tsx +144 -0
- package/src/tools/chat/composer/slash/SlashMenu.tsx +142 -0
- package/src/tools/chat/composer/slash/SlashToken.tsx +57 -0
- package/src/tools/chat/composer/slash/index.ts +44 -0
- package/src/tools/chat/composer/slash/labels.ts +19 -0
- package/src/tools/chat/composer/slash/state.ts +168 -0
- package/src/tools/chat/composer/slash/types.ts +64 -0
- package/src/tools/chat/composer/slash/useSlashCommands.ts +204 -0
- package/src/tools/chat/composer/types.ts +8 -0
- package/src/tools/chat/context/ChatProvider.tsx +13 -78
- package/src/tools/chat/hooks/useAutoFocusOnStreamEnd.ts +12 -15
- package/src/tools/chat/hooks/useFocusOnEmptyClick.ts +4 -5
- package/src/tools/chat/launcher/header/ChatHeader.tsx +14 -19
- package/src/tools/chat/launcher/header/ChatHeaderActionButton.tsx +8 -12
- package/src/tools/chat/shell/SuggestedPrompts.tsx +194 -0
- package/src/tools/chat/shell/index.ts +6 -0
- package/src/tools/data/Listbox/lazy.tsx +1 -1
- package/src/tools/data/Masonry/lazy.tsx +1 -1
- package/src/tools/data/Timeline/lazy.tsx +1 -1
- package/src/tools/data/Tree/FinderTree.tsx +42 -0
- package/src/tools/data/Tree/README.md +337 -208
- package/src/tools/data/Tree/TreeDndProvider.tsx +137 -0
- package/src/tools/data/Tree/TreeRoot.tsx +111 -72
- package/src/tools/data/Tree/__tests__/dnd.test.ts +160 -0
- package/src/tools/data/Tree/__tests__/keyboard.test.ts +137 -0
- package/src/tools/data/Tree/__tests__/renameUtils.test.ts +52 -0
- package/src/tools/data/Tree/__tests__/selection.test.ts +227 -0
- package/src/tools/data/Tree/components/TreeDropIndicator.tsx +65 -0
- package/src/tools/data/Tree/components/TreeEmptyArea.tsx +160 -0
- package/src/tools/data/Tree/components/TreeRenameInput.tsx +114 -0
- package/src/tools/data/Tree/components/TreeRow.tsx +103 -8
- package/src/tools/data/Tree/components/index.ts +6 -0
- package/src/tools/data/Tree/context/TreeContext.tsx +223 -363
- package/src/tools/data/Tree/context/TreeContextValue.ts +139 -0
- package/src/tools/data/Tree/context/async-children/collect-ids.ts +27 -0
- package/src/tools/data/Tree/context/async-children/index.ts +8 -0
- package/src/tools/data/Tree/context/async-children/use-async-children.ts +157 -0
- package/src/tools/data/Tree/context/clipboard/index.ts +4 -0
- package/src/tools/data/Tree/context/clipboard/use-clipboard.ts +115 -0
- package/src/tools/data/Tree/context/dnd/index.ts +8 -0
- package/src/tools/data/Tree/context/dnd/use-dnd.ts +194 -0
- package/src/tools/data/Tree/context/expansion/index.ts +4 -0
- package/src/tools/data/Tree/context/expansion/use-expansion.ts +55 -0
- package/src/tools/data/Tree/context/hooks.ts +68 -1
- package/src/tools/data/Tree/context/index.ts +3 -0
- package/src/tools/data/Tree/context/menu/builtin-actions.ts +357 -0
- package/src/tools/data/Tree/context/menu/index.ts +11 -0
- package/src/tools/data/Tree/context/menu/render.tsx +75 -0
- package/src/tools/data/Tree/context/menu/use-resolved-menu.ts +141 -0
- package/src/tools/data/Tree/context/persist/index.ts +4 -0
- package/src/tools/data/Tree/context/persist/use-persist-sync.ts +74 -0
- package/src/tools/data/Tree/context/rename/index.ts +4 -0
- package/src/tools/data/Tree/context/rename/use-rename.ts +113 -0
- package/src/tools/data/Tree/context/selection/index.ts +4 -0
- package/src/tools/data/Tree/context/selection/use-selection.ts +146 -0
- package/src/tools/data/Tree/context/state/index.ts +6 -0
- package/src/tools/data/Tree/context/state/initial.ts +41 -0
- package/src/tools/data/Tree/context/state/reducer.ts +76 -0
- package/src/tools/data/Tree/context/state/types.ts +46 -0
- package/src/tools/data/Tree/data/clipboard.ts +33 -0
- package/src/tools/data/Tree/data/dnd.ts +123 -0
- package/src/tools/data/Tree/data/finderShortcuts.ts +67 -0
- package/src/tools/data/Tree/data/index.ts +19 -0
- package/src/tools/data/Tree/data/renameUtils.ts +51 -0
- package/src/tools/data/Tree/data/selection.ts +157 -0
- package/src/tools/data/Tree/hooks/finder-hotkeys/build-ctx.ts +48 -0
- package/src/tools/data/Tree/hooks/finder-hotkeys/index.ts +8 -0
- package/src/tools/data/Tree/hooks/finder-hotkeys/use-tree-finder-hotkeys.ts +166 -0
- package/src/tools/data/Tree/hooks/index.ts +23 -4
- package/src/tools/data/Tree/hooks/keyboard/activation.ts +27 -0
- package/src/tools/data/Tree/hooks/keyboard/arrow-nav.ts +26 -0
- package/src/tools/data/Tree/hooks/keyboard/expand-collapse.ts +54 -0
- package/src/tools/data/Tree/hooks/keyboard/index.ts +10 -0
- package/src/tools/data/Tree/hooks/keyboard/types.ts +39 -0
- package/src/tools/data/Tree/hooks/keyboard/use-tree-keyboard.ts +196 -0
- package/src/tools/data/Tree/hooks/type-ahead/index.ts +5 -0
- package/src/tools/data/Tree/hooks/type-ahead/match-prefix.ts +42 -0
- package/src/tools/data/Tree/hooks/{useTreeTypeAhead.ts → type-ahead/use-tree-type-ahead.ts} +8 -19
- package/src/tools/data/Tree/index.tsx +26 -2
- package/src/tools/data/Tree/types/activation.ts +30 -0
- package/src/tools/data/Tree/types/adapter.ts +70 -0
- package/src/tools/data/Tree/types/index.ts +27 -0
- package/src/tools/data/Tree/types/labels.ts +97 -0
- package/src/tools/data/Tree/types/loader.ts +9 -0
- package/src/tools/data/Tree/types/node.ts +38 -0
- package/src/tools/data/Tree/types/root-props.ts +158 -0
- package/src/tools/data/Tree/types/selection.ts +3 -0
- package/src/tools/data/Tree/types/slots.ts +64 -0
- package/src/tools/dev/OpenapiViewer/components/DocsLayout/EndpointDoc/Header/MetaActions.tsx +6 -9
- package/src/tools/dev/OpenapiViewer/components/DocsLayout/index.tsx +2 -4
- package/src/tools/forms/MarkdownEditor/MarkdownEditor.tsx +85 -0
- package/src/tools/forms/MarkdownEditor/index.ts +1 -0
- package/src/tools/forms/MarkdownEditor/lazy.tsx +6 -0
- package/src/tools/forms/MarkdownEditor/slash/SlashCommandNode.ts +162 -0
- package/src/tools/forms/MarkdownEditor/slash/index.ts +4 -0
- package/src/tools/forms/MarkdownEditor/slash/syncSlashNode.ts +97 -0
- package/src/tools/forms/MarkdownEditor/slash/types.ts +13 -0
- package/src/tools/forms/MarkdownEditor/styles.css +18 -0
- package/src/tools/input/SpeechRecognition/widgets/VoiceComposerSlot.tsx +11 -12
- package/src/tools/integration/ComposerRegistry/index.ts +105 -0
- package/src/tools/media/AudioPlayer/Player.tsx +2 -0
- package/src/tools/media/AudioPlayer/PlayerShell.tsx +37 -22
- package/src/tools/media/AudioPlayer/lazy.tsx +30 -42
- package/src/tools/media/AudioPlayer/parts/Controls/IconButton.tsx +10 -11
- package/src/tools/media/AudioPlayer/parts/Controls/VolumeControl.tsx +52 -115
- package/src/tools/media/AudioPlayer/types.ts +15 -0
- package/dist/types-j2vhn4Kv.d.cts +0 -241
- package/dist/types-j2vhn4Kv.d.ts +0 -241
- package/src/tools/data/Tree/hooks/useTreeKeyboard.ts +0 -171
- package/src/tools/data/Tree/types.ts +0 -217
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import { useCallback, useRef } from 'react';
|
|
4
4
|
import type { MouseEvent as ReactMouseEvent, RefObject } from 'react';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { getActiveComposer } from '@djangocfg/ui-tools/composer-registry';
|
|
7
|
+
|
|
8
|
+
import { useChatContextOptional } from '../context';
|
|
7
9
|
import type { Focusable } from './useAutoFocusOnStreamEnd';
|
|
8
10
|
|
|
9
11
|
export interface UseFocusOnEmptyClickOptions {
|
|
@@ -51,9 +53,6 @@ export function useFocusOnEmptyClick(
|
|
|
51
53
|
const { targetRef, enabled = true, skipWhileStreaming = true } = options;
|
|
52
54
|
const ctx = useChatContextOptional();
|
|
53
55
|
|
|
54
|
-
const composerHandleRef = useRef<ComposerHandle | null>(null);
|
|
55
|
-
composerHandleRef.current = ctx?.composer ?? null;
|
|
56
|
-
|
|
57
56
|
const isStreamingRef = useRef(false);
|
|
58
57
|
isStreamingRef.current = ctx?.isStreaming ?? false;
|
|
59
58
|
|
|
@@ -83,7 +82,7 @@ export function useFocusOnEmptyClick(
|
|
|
83
82
|
explicit.focus?.();
|
|
84
83
|
return;
|
|
85
84
|
}
|
|
86
|
-
|
|
85
|
+
getActiveComposer()?.focus?.();
|
|
87
86
|
},
|
|
88
87
|
[enabled, skipWhileStreaming, targetRef],
|
|
89
88
|
);
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
Button,
|
|
8
8
|
Tooltip,
|
|
9
9
|
TooltipContent,
|
|
10
|
-
TooltipProvider,
|
|
11
10
|
TooltipTrigger,
|
|
12
11
|
} from '@djangocfg/ui-core/components';
|
|
13
12
|
import { cn } from '@djangocfg/ui-core/lib';
|
|
@@ -66,24 +65,20 @@ export function ChatHeader({
|
|
|
66
65
|
{actions}
|
|
67
66
|
{closeSlot ??
|
|
68
67
|
(showClose && onClose && (
|
|
69
|
-
<
|
|
70
|
-
<
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
tier, already above the dock — no override needed. */}
|
|
84
|
-
<TooltipContent side="bottom">{closeLabel}</TooltipContent>
|
|
85
|
-
</Tooltip>
|
|
86
|
-
</TooltipProvider>
|
|
68
|
+
<Tooltip>
|
|
69
|
+
<TooltipTrigger asChild>
|
|
70
|
+
<Button
|
|
71
|
+
variant="ghost"
|
|
72
|
+
size="sm"
|
|
73
|
+
onClick={onClose}
|
|
74
|
+
aria-label={closeLabel}
|
|
75
|
+
className="-mr-1 h-7 w-7 p-0"
|
|
76
|
+
>
|
|
77
|
+
<X className="h-4 w-4" />
|
|
78
|
+
</Button>
|
|
79
|
+
</TooltipTrigger>
|
|
80
|
+
<TooltipContent side="bottom">{closeLabel}</TooltipContent>
|
|
81
|
+
</Tooltip>
|
|
87
82
|
))}
|
|
88
83
|
</div>
|
|
89
84
|
</header>
|
|
@@ -6,7 +6,6 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
|
|
6
6
|
import {
|
|
7
7
|
Tooltip,
|
|
8
8
|
TooltipContent,
|
|
9
|
-
TooltipProvider,
|
|
10
9
|
TooltipTrigger,
|
|
11
10
|
} from '@djangocfg/ui-core/components';
|
|
12
11
|
import { cn } from '@djangocfg/ui-core/lib';
|
|
@@ -102,19 +101,16 @@ export const ChatHeaderActionButton = forwardRef<HTMLButtonElement, ChatHeaderAc
|
|
|
102
101
|
// Opted out — keep the native `title` only.
|
|
103
102
|
if (tooltip === false) return button;
|
|
104
103
|
|
|
105
|
-
// Floating tooltip on hover *and* keyboard focus.
|
|
106
|
-
//
|
|
107
|
-
// host wiring an ambient provider; Radix dedupes nested providers.
|
|
104
|
+
// Floating tooltip on hover *and* keyboard focus.
|
|
105
|
+
// Host app mounts <UiProviders> (which includes TooltipProvider).
|
|
108
106
|
const tooltipLabel = tooltip ?? ariaLabel;
|
|
109
107
|
return (
|
|
110
|
-
<
|
|
111
|
-
<
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
</Tooltip>
|
|
117
|
-
</TooltipProvider>
|
|
108
|
+
<Tooltip>
|
|
109
|
+
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
110
|
+
{/* Tooltip portals to <body> in ui-core's anchored-overlay tier,
|
|
111
|
+
already above the dock — no z-index override needed. */}
|
|
112
|
+
<TooltipContent side="bottom">{tooltipLabel}</TooltipContent>
|
|
113
|
+
</Tooltip>
|
|
118
114
|
);
|
|
119
115
|
},
|
|
120
116
|
);
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
import { cn } from '@djangocfg/ui-core/lib';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* SuggestedPrompts — chat empty-state "starter prompts" surface.
|
|
9
|
+
*
|
|
10
|
+
* The pattern every chat consumer wants: a small hero (optional), a
|
|
11
|
+
* title + description (optional), and a row/grid of clickable prompts
|
|
12
|
+
* that seed the composer. Pluggable enough to cover ChatGPT-style
|
|
13
|
+
* card grids and cmdop-style flat chips with the same component.
|
|
14
|
+
*
|
|
15
|
+
* Typical wiring inside `<ChatRoot slots={{ empty: ({ setValue, focus }) =>
|
|
16
|
+
* <SuggestedPrompts items={...} onPick={(p) => { setValue(p.prompt); focus(); }} />
|
|
17
|
+
* }} />`.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export type SuggestedPromptItem = {
|
|
21
|
+
id: string;
|
|
22
|
+
/** Displayed on the chip / card. */
|
|
23
|
+
label: string;
|
|
24
|
+
/** Sent on click (often equal to `label`). */
|
|
25
|
+
prompt: string;
|
|
26
|
+
/** Optional leading icon. */
|
|
27
|
+
icon?: ReactNode;
|
|
28
|
+
/** Optional secondary line (rendered in `grid` layout, ignored by `chips`). */
|
|
29
|
+
description?: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type SuggestedPromptsLayout = 'chips' | 'grid';
|
|
33
|
+
|
|
34
|
+
export interface SuggestedPromptsProps {
|
|
35
|
+
items: readonly SuggestedPromptItem[];
|
|
36
|
+
onPick: (item: SuggestedPromptItem) => void;
|
|
37
|
+
/** Optional title above the chips. */
|
|
38
|
+
title?: ReactNode;
|
|
39
|
+
/** Optional subtitle/description above the chips. */
|
|
40
|
+
description?: ReactNode;
|
|
41
|
+
/** Optional hero element above the title (icon, logo, …). */
|
|
42
|
+
hero?: ReactNode;
|
|
43
|
+
/** Layout — `chips` (flat rounded-full buttons, default) or `grid` (2-col cards). */
|
|
44
|
+
layout?: SuggestedPromptsLayout;
|
|
45
|
+
/** Container className. */
|
|
46
|
+
className?: string;
|
|
47
|
+
/** ARIA label for the region wrapper. Default `Suggested prompts`. */
|
|
48
|
+
ariaLabel?: string;
|
|
49
|
+
/** Custom render override for one item (escape hatch). */
|
|
50
|
+
renderItem?: (item: SuggestedPromptItem, idx: number) => ReactNode;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function SuggestedPrompts({
|
|
54
|
+
items,
|
|
55
|
+
onPick,
|
|
56
|
+
title,
|
|
57
|
+
description,
|
|
58
|
+
hero,
|
|
59
|
+
layout = 'chips',
|
|
60
|
+
className,
|
|
61
|
+
ariaLabel = 'Suggested prompts',
|
|
62
|
+
renderItem,
|
|
63
|
+
}: SuggestedPromptsProps) {
|
|
64
|
+
const hasHeader = hero != null || title != null || description != null;
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<section
|
|
68
|
+
role="region"
|
|
69
|
+
aria-label={ariaLabel}
|
|
70
|
+
className={cn(
|
|
71
|
+
'flex w-full flex-col items-center text-center',
|
|
72
|
+
className,
|
|
73
|
+
)}
|
|
74
|
+
>
|
|
75
|
+
{hasHeader ? (
|
|
76
|
+
<div className="mb-4 flex flex-col items-center gap-1.5">
|
|
77
|
+
{hero != null ? (
|
|
78
|
+
<div className="text-foreground/90">{hero}</div>
|
|
79
|
+
) : null}
|
|
80
|
+
{title != null ? (
|
|
81
|
+
<h3 className="text-base font-semibold text-foreground">
|
|
82
|
+
{title}
|
|
83
|
+
</h3>
|
|
84
|
+
) : null}
|
|
85
|
+
{description != null ? (
|
|
86
|
+
<p className="max-w-md text-sm leading-snug text-muted-foreground">
|
|
87
|
+
{description}
|
|
88
|
+
</p>
|
|
89
|
+
) : null}
|
|
90
|
+
</div>
|
|
91
|
+
) : null}
|
|
92
|
+
|
|
93
|
+
{layout === 'grid' ? (
|
|
94
|
+
<div
|
|
95
|
+
className="grid w-full max-w-xl grid-cols-1 gap-2 sm:grid-cols-2"
|
|
96
|
+
role="list"
|
|
97
|
+
>
|
|
98
|
+
{items.map((item, idx) =>
|
|
99
|
+
renderItem ? (
|
|
100
|
+
<span key={item.id} role="listitem">
|
|
101
|
+
{renderItem(item, idx)}
|
|
102
|
+
</span>
|
|
103
|
+
) : (
|
|
104
|
+
<GridCard key={item.id} item={item} onPick={onPick} />
|
|
105
|
+
),
|
|
106
|
+
)}
|
|
107
|
+
</div>
|
|
108
|
+
) : (
|
|
109
|
+
<div
|
|
110
|
+
className="flex w-full max-w-xl flex-wrap justify-center gap-2"
|
|
111
|
+
role="list"
|
|
112
|
+
>
|
|
113
|
+
{items.map((item, idx) =>
|
|
114
|
+
renderItem ? (
|
|
115
|
+
<span key={item.id} role="listitem">
|
|
116
|
+
{renderItem(item, idx)}
|
|
117
|
+
</span>
|
|
118
|
+
) : (
|
|
119
|
+
<Chip key={item.id} item={item} onPick={onPick} />
|
|
120
|
+
),
|
|
121
|
+
)}
|
|
122
|
+
</div>
|
|
123
|
+
)}
|
|
124
|
+
</section>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function Chip({
|
|
129
|
+
item,
|
|
130
|
+
onPick,
|
|
131
|
+
}: {
|
|
132
|
+
item: SuggestedPromptItem;
|
|
133
|
+
onPick: (item: SuggestedPromptItem) => void;
|
|
134
|
+
}) {
|
|
135
|
+
return (
|
|
136
|
+
<button
|
|
137
|
+
type="button"
|
|
138
|
+
role="listitem"
|
|
139
|
+
onClick={() => onPick(item)}
|
|
140
|
+
className={cn(
|
|
141
|
+
'inline-flex items-center gap-1.5 rounded-full border border-border',
|
|
142
|
+
'bg-card/60 px-3 py-1.5 text-xs text-muted-foreground',
|
|
143
|
+
'transition-colors duration-150',
|
|
144
|
+
'hover:border-primary/40 hover:bg-card hover:text-foreground',
|
|
145
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
146
|
+
'active:scale-[0.97]',
|
|
147
|
+
)}
|
|
148
|
+
>
|
|
149
|
+
{item.icon != null ? (
|
|
150
|
+
<span aria-hidden className="shrink-0 text-muted-foreground">
|
|
151
|
+
{item.icon}
|
|
152
|
+
</span>
|
|
153
|
+
) : null}
|
|
154
|
+
<span>{item.label}</span>
|
|
155
|
+
</button>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function GridCard({
|
|
160
|
+
item,
|
|
161
|
+
onPick,
|
|
162
|
+
}: {
|
|
163
|
+
item: SuggestedPromptItem;
|
|
164
|
+
onPick: (item: SuggestedPromptItem) => void;
|
|
165
|
+
}) {
|
|
166
|
+
return (
|
|
167
|
+
<button
|
|
168
|
+
type="button"
|
|
169
|
+
role="listitem"
|
|
170
|
+
onClick={() => onPick(item)}
|
|
171
|
+
className={cn(
|
|
172
|
+
'group flex flex-col gap-1 rounded-md border border-border',
|
|
173
|
+
'bg-card/60 p-3 text-left',
|
|
174
|
+
'transition-colors duration-150',
|
|
175
|
+
'hover:border-primary/40 hover:bg-card',
|
|
176
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
177
|
+
)}
|
|
178
|
+
>
|
|
179
|
+
<span className="flex items-center gap-2 text-sm font-medium text-foreground">
|
|
180
|
+
{item.icon != null ? (
|
|
181
|
+
<span aria-hidden className="shrink-0 text-muted-foreground group-hover:text-foreground">
|
|
182
|
+
{item.icon}
|
|
183
|
+
</span>
|
|
184
|
+
) : null}
|
|
185
|
+
<span>{item.label}</span>
|
|
186
|
+
</span>
|
|
187
|
+
{item.description ? (
|
|
188
|
+
<span className="text-xs leading-snug text-muted-foreground">
|
|
189
|
+
{item.description}
|
|
190
|
+
</span>
|
|
191
|
+
) : null}
|
|
192
|
+
</button>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
@@ -13,3 +13,9 @@ export {
|
|
|
13
13
|
} from './ChatRoot';
|
|
14
14
|
export { EmptyState, type EmptyStateProps } from './EmptyState';
|
|
15
15
|
export { ErrorBanner, type ErrorBannerProps } from './ErrorBanner';
|
|
16
|
+
export {
|
|
17
|
+
SuggestedPrompts,
|
|
18
|
+
type SuggestedPromptsProps,
|
|
19
|
+
type SuggestedPromptItem,
|
|
20
|
+
type SuggestedPromptsLayout,
|
|
21
|
+
} from './SuggestedPrompts';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { createLazyComponent, LoadingFallback } from '../../../components/lazy-wrapper';
|
|
4
|
-
import type { ListboxRootProps } from './
|
|
4
|
+
import type { ListboxRootProps } from './types';
|
|
5
5
|
|
|
6
6
|
export const LazyListbox = createLazyComponent<ListboxRootProps>(
|
|
7
7
|
() => import('./context/ListboxProvider').then((m) => ({ default: m.ListboxRoot })),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { createLazyComponent, LoadingFallback } from '../../../components/lazy-wrapper';
|
|
4
|
-
import type { MasonryProps } from './
|
|
4
|
+
import type { MasonryProps } from './types';
|
|
5
5
|
|
|
6
6
|
export const LazyMasonry = createLazyComponent<MasonryProps>(
|
|
7
7
|
() => import('./context/MasonryProvider').then((m) => ({ default: m.Masonry })),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { createLazyComponent, LoadingFallback } from '../../../components/lazy-wrapper';
|
|
4
|
-
import type { TimelineProps } from './
|
|
4
|
+
import type { TimelineProps } from './types';
|
|
5
5
|
|
|
6
6
|
export const LazyTimeline = createLazyComponent<TimelineProps>(
|
|
7
7
|
() => import('./context/TimelineProvider').then((m) => ({ default: m.Timeline })),
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { TreeRoot } from './TreeRoot';
|
|
4
|
+
import type { TreeRootProps } from './types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `<FinderTree>` — opinionated Finder/Explorer-style preset.
|
|
8
|
+
*
|
|
9
|
+
* Equivalent to `<TreeRoot>` with multi-selection, double-click activation,
|
|
10
|
+
* inline rename, indent guides, and a cozy appearance turned on. Pass an
|
|
11
|
+
* `adapter` to get the built-in CRUD menu wired to `window.dialog.*`.
|
|
12
|
+
*
|
|
13
|
+
* Override any preset default by simply passing the same prop:
|
|
14
|
+
*
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <FinderTree<FsNode>
|
|
17
|
+
* data={data}
|
|
18
|
+
* getItemName={(n) => n.data.name}
|
|
19
|
+
* adapter={fsAdapter}
|
|
20
|
+
* // override one preset default — everything else stays Finder-y:
|
|
21
|
+
* activationMode="single-click-preview"
|
|
22
|
+
* />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function FinderTree<T>(props: TreeRootProps<T>) {
|
|
26
|
+
return (
|
|
27
|
+
<TreeRoot<T>
|
|
28
|
+
// Finder/Explorer defaults — every one is overridable via `props`.
|
|
29
|
+
selectionMode="multiple"
|
|
30
|
+
activationMode="double-click"
|
|
31
|
+
enableInlineRename
|
|
32
|
+
enableFinderHotkeys
|
|
33
|
+
enableDnD
|
|
34
|
+
enableTypeAhead
|
|
35
|
+
showIndentGuides
|
|
36
|
+
appearance={{ density: 'cozy' }}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default FinderTree;
|