@djangocfg/ui-tools 2.1.382 → 2.1.384

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.
Files changed (89) hide show
  1. package/dist/ChatRoot-JVR3M3H2.mjs +5 -0
  2. package/dist/{ChatRoot-6IZFM5HM.mjs.map → ChatRoot-JVR3M3H2.mjs.map} +1 -1
  3. package/dist/ChatRoot-LXIUBOXF.cjs +14 -0
  4. package/dist/{ChatRoot-LW4XNIKP.cjs.map → ChatRoot-LXIUBOXF.cjs.map} +1 -1
  5. package/dist/DictationField-U25MEYAL.mjs +4 -0
  6. package/dist/{DictationField-2ZLQWLYV.mjs.map → DictationField-U25MEYAL.mjs.map} +1 -1
  7. package/dist/DictationField-XWR5VOID.cjs +13 -0
  8. package/dist/{DictationField-IPPJ54CU.cjs.map → DictationField-XWR5VOID.cjs.map} +1 -1
  9. package/dist/{chunk-KMSBGNVC.cjs → chunk-4PFW7MIJ.cjs} +4 -2
  10. package/dist/chunk-4PFW7MIJ.cjs.map +1 -0
  11. package/dist/{chunk-4LXG3NBV.mjs → chunk-C2YN6WEO.mjs} +3 -3
  12. package/dist/chunk-C2YN6WEO.mjs.map +1 -0
  13. package/dist/{chunk-OZAU3QWD.cjs → chunk-HPK3EWBF.cjs} +8 -8
  14. package/dist/chunk-HPK3EWBF.cjs.map +1 -0
  15. package/dist/{chunk-UWVP6LCW.mjs → chunk-PEKBT75W.mjs} +8 -8
  16. package/dist/chunk-PEKBT75W.mjs.map +1 -0
  17. package/dist/index.cjs +192 -55
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +78 -6
  20. package/dist/index.d.ts +78 -6
  21. package/dist/index.mjs +143 -8
  22. package/dist/index.mjs.map +1 -1
  23. package/package.json +6 -13
  24. package/src/tools/Chat/core/audio/defaults.ts +16 -11
  25. package/src/tools/Chat/core/audio/sounds/error.ts +3 -0
  26. package/src/tools/Chat/core/audio/sounds/mention.ts +3 -0
  27. package/src/tools/Chat/core/audio/sounds/notification.ts +3 -0
  28. package/src/tools/Chat/core/audio/sounds/received.ts +3 -0
  29. package/src/tools/Chat/core/audio/sounds/sent.ts +3 -0
  30. package/src/tools/Chat/core/audio/sounds/start.ts +3 -0
  31. package/src/tools/Chat/index.ts +15 -0
  32. package/src/tools/SpeechRecognition/core/audio/defaults.ts +4 -4
  33. package/dist/ChatRoot-6IZFM5HM.mjs +0 -5
  34. package/dist/ChatRoot-LW4XNIKP.cjs +0 -14
  35. package/dist/DictationField-2ZLQWLYV.mjs +0 -4
  36. package/dist/DictationField-IPPJ54CU.cjs +0 -13
  37. package/dist/chunk-4LXG3NBV.mjs.map +0 -1
  38. package/dist/chunk-KMSBGNVC.cjs.map +0 -1
  39. package/dist/chunk-OZAU3QWD.cjs.map +0 -1
  40. package/dist/chunk-UWVP6LCW.mjs.map +0 -1
  41. package/src/audio-assets.d.ts +0 -8
  42. package/src/components/markdown/MarkdownMessage/MarkdownMessage.story.tsx +0 -771
  43. package/src/stories/index.ts +0 -63
  44. package/src/tools/AudioPlayer/AudioPlayer.story.tsx +0 -481
  45. package/src/tools/Chat/core/audio/sounds/error.mp3 +0 -0
  46. package/src/tools/Chat/core/audio/sounds/mention.mp3 +0 -0
  47. package/src/tools/Chat/core/audio/sounds/notification.mp3 +0 -0
  48. package/src/tools/Chat/core/audio/sounds/received.mp3 +0 -0
  49. package/src/tools/Chat/core/audio/sounds/sent.mp3 +0 -0
  50. package/src/tools/Chat/core/audio/sounds/start.mp3 +0 -0
  51. package/src/tools/Chat/stories/01-basic.story.tsx +0 -64
  52. package/src/tools/Chat/stories/02-bubbles.story.tsx +0 -21
  53. package/src/tools/Chat/stories/03-tool-calls.story.tsx +0 -59
  54. package/src/tools/Chat/stories/04-personas.story.tsx +0 -78
  55. package/src/tools/Chat/stories/05-launcher.story.tsx +0 -321
  56. package/src/tools/Chat/stories/06-header.story.tsx +0 -147
  57. package/src/tools/Chat/stories/07-audio-actions.story.tsx +0 -112
  58. package/src/tools/Chat/stories/shared/Frame.tsx +0 -21
  59. package/src/tools/Chat/stories/shared/index.ts +0 -5
  60. package/src/tools/Chat/stories/shared/messages.ts +0 -39
  61. package/src/tools/Chat/stories/shared/personas.ts +0 -13
  62. package/src/tools/Chat/stories/shared/seeds.ts +0 -92
  63. package/src/tools/Chat/stories/shared/transports.ts +0 -36
  64. package/src/tools/CodeEditor/CodeEditor.story.tsx +0 -202
  65. package/src/tools/CronScheduler/CronScheduler.story.tsx +0 -300
  66. package/src/tools/Gallery/Gallery.story.tsx +0 -237
  67. package/src/tools/ImageViewer/ImageViewer.story.tsx +0 -85
  68. package/src/tools/JsonForm/JsonForm.story.tsx +0 -350
  69. package/src/tools/JsonTree/JsonTree.story.tsx +0 -141
  70. package/src/tools/LottiePlayer/LottiePlayer.story.tsx +0 -95
  71. package/src/tools/Map/Map.story.tsx +0 -458
  72. package/src/tools/MarkdownEditor/MarkdownEditor.story.tsx +0 -225
  73. package/src/tools/Mermaid/Mermaid.story.tsx +0 -251
  74. package/src/tools/OpenapiViewer/OpenapiViewer.story.tsx +0 -230
  75. package/src/tools/PrettyCode/PrettyCode.story.tsx +0 -304
  76. package/src/tools/SpeechRecognition/stories/01-basic.story.tsx +0 -32
  77. package/src/tools/SpeechRecognition/stories/02-dictation-field.story.tsx +0 -32
  78. package/src/tools/SpeechRecognition/stories/03-push-to-talk.story.tsx +0 -27
  79. package/src/tools/SpeechRecognition/stories/04-mic-meter.story.tsx +0 -35
  80. package/src/tools/SpeechRecognition/stories/05-custom-engine-http.story.tsx +0 -40
  81. package/src/tools/SpeechRecognition/stories/06-custom-engine-ws.story.tsx +0 -48
  82. package/src/tools/SpeechRecognition/stories/07-language-device.story.tsx +0 -57
  83. package/src/tools/SpeechRecognition/stories/08-errors-permissions.story.tsx +0 -25
  84. package/src/tools/SpeechRecognition/stories/09-chat-voice.story.tsx +0 -90
  85. package/src/tools/SpeechRecognition/stories/shared.tsx +0 -123
  86. package/src/tools/Tour/Tour.story.tsx +0 -279
  87. package/src/tools/Tree/Tree.story.tsx +0 -620
  88. package/src/tools/Uploader/Uploader.story.tsx +0 -415
  89. package/src/tools/VideoPlayer/VideoPlayer.story.tsx +0 -87
@@ -1,90 +0,0 @@
1
- import { useMemo } from 'react';
2
-
3
- import { defineStory } from '@djangocfg/playground';
4
-
5
- import { Composer } from '../../Chat/components/Composer';
6
- import { EmptyState } from '../../Chat/components/EmptyState';
7
- import { MessageList } from '../../Chat/components/MessageList';
8
- import { ChatProvider, useChatContext } from '../../Chat/context';
9
- import { useChatComposer } from '../../Chat/hooks/useChatComposer';
10
- import { ChatHeader } from '../../Chat/launcher/ChatHeader';
11
- import { ChatHeaderLanguageButton } from '../../Chat/launcher/ChatHeaderLanguageButton';
12
- import { SEED_BASIC, makeBasicTransport } from '../../Chat/stories/shared';
13
- import { Frame as ChatFrame } from '../../Chat/stories/shared/Frame';
14
- import { VoiceComposerSlot } from '../widgets/VoiceComposerSlot';
15
- import type { RecognitionEngine } from '../types';
16
- import { createMockEngine } from './shared';
17
-
18
- export default defineStory({
19
- title: 'Tools/Chat/Voice composer',
20
- component: VoiceComposerSlot,
21
- description:
22
- 'Live dictation slot wired into the Chat composer. `InsideComposer` uses the real browser Web Speech API + a kebab settings menu in the header for picking the speech-recognition language (persists in `useSpeechPrefs`). `MockedDemo` uses a deterministic mock engine so screenshots / CI never prompt for microphone access. The slot auto-hides on Firefox / in-app browsers / missing getUserMedia.',
23
- });
24
-
25
- function VoiceChat({ engine }: { engine?: RecognitionEngine }) {
26
- const chat = useChatContext();
27
- const composer = useChatComposer({
28
- onSubmit: (content, attachments) => chat.sendMessage(content, attachments),
29
- disabled: chat.isStreaming,
30
- });
31
-
32
- return (
33
- <div className="flex h-full min-h-0 flex-col">
34
- <ChatHeader
35
- title="Assistant"
36
- actions={<ChatHeaderLanguageButton />}
37
- />
38
- <MessageList
39
- renderEmpty={() => (
40
- <EmptyState greeting="Open the settings menu (⋯) to pick the speech language, then press the mic." />
41
- )}
42
- />
43
- <Composer
44
- composer={composer}
45
- placeholder="Type or press the mic…"
46
- toolbarEnd={
47
- <VoiceComposerSlot
48
- value={composer.value}
49
- onChange={composer.setValue}
50
- engine={engine}
51
- />
52
- }
53
- />
54
- </div>
55
- );
56
- }
57
-
58
- /**
59
- * Real browser Web Speech API + kebab settings menu with the language
60
- * picker. The choice persists in `useSpeechPrefs` (localStorage), so it
61
- * survives reloads. Defaults are resolved in order: prop → prefs → i18n
62
- * → `navigator.language` → `en-US`.
63
- */
64
- export const InsideComposer = () => {
65
- const transport = useMemo(() => makeBasicTransport(SEED_BASIC), []);
66
- return (
67
- <ChatFrame>
68
- <ChatProvider transport={transport}>
69
- <VoiceChat />
70
- </ChatProvider>
71
- </ChatFrame>
72
- );
73
- };
74
-
75
- /**
76
- * Deterministic mock engine — types a scripted phrase into the composer
77
- * without touching the microphone. Useful for screenshots, CI, and
78
- * environments where granting mic permission is not desired.
79
- */
80
- export const MockedDemo = () => {
81
- const transport = useMemo(() => makeBasicTransport(SEED_BASIC), []);
82
- const engine = useMemo(() => createMockEngine({ partialIntervalMs: 90 }), []);
83
- return (
84
- <ChatFrame>
85
- <ChatProvider transport={transport}>
86
- <VoiceChat engine={engine} />
87
- </ChatProvider>
88
- </ChatFrame>
89
- );
90
- };
@@ -1,123 +0,0 @@
1
- /**
2
- * Deterministic mock engine — emits scripted partials/finals on a timer
3
- * so stories render the same thing every load and don't beg the browser
4
- * for microphone permission.
5
- */
6
-
7
- import { createEngineBus } from '../core/engine';
8
- import { newSegmentId } from '../core/ids';
9
- import type {
10
- EngineStartOptions,
11
- RecognitionEngine,
12
- Unsub,
13
- } from '../types';
14
-
15
- export interface MockEngineOptions {
16
- /** Final phrases the mock will emit, one after another. */
17
- phrases?: string[];
18
- /** ms between partial chunks. Default 120. */
19
- partialIntervalMs?: number;
20
- /** ms between final segments. Default 1500. */
21
- finalIntervalMs?: number;
22
- /** Override id (default `'mock'`). */
23
- id?: string;
24
- }
25
-
26
- const DEFAULT_PHRASES = [
27
- 'Hello and welcome to the dictation demo.',
28
- 'This text is being typed by the mock engine.',
29
- 'Try the buttons on the right to control the session.',
30
- ];
31
-
32
- export function createMockEngine(
33
- opts: MockEngineOptions = {},
34
- ): RecognitionEngine {
35
- const bus = createEngineBus();
36
- const phrases = opts.phrases ?? DEFAULT_PHRASES;
37
- const partialMs = opts.partialIntervalMs ?? 120;
38
- const finalMs = opts.finalIntervalMs ?? 1500;
39
-
40
- let timers: ReturnType<typeof setTimeout>[] = [];
41
- let running = false;
42
-
43
- function clearTimers(): void {
44
- timers.forEach(clearTimeout);
45
- timers = [];
46
- }
47
-
48
- function run(): void {
49
- let phraseIdx = 0;
50
- let charIdx = 0;
51
- let segmentId = newSegmentId();
52
- let baseTime = 0;
53
-
54
- const tick = (): void => {
55
- if (!running) return;
56
- const phrase = phrases[phraseIdx % phrases.length];
57
- charIdx = Math.min(charIdx + 2, phrase.length);
58
- bus.emit('partial', phrase.slice(0, charIdx), segmentId);
59
- if (charIdx >= phrase.length) {
60
- const tFinal = setTimeout(() => {
61
- if (!running) return;
62
- bus.emit('final', phrase, segmentId);
63
- phraseIdx += 1;
64
- charIdx = 0;
65
- segmentId = newSegmentId();
66
- baseTime += finalMs;
67
- const tNext = setTimeout(tick, partialMs);
68
- timers.push(tNext);
69
- }, finalMs - partialMs);
70
- timers.push(tFinal);
71
- return;
72
- }
73
- const tNext = setTimeout(tick, partialMs);
74
- timers.push(tNext);
75
- };
76
- tick();
77
- }
78
-
79
- return {
80
- id: opts.id ?? 'mock',
81
- isSupported: true,
82
- on(event, cb): Unsub {
83
- return bus.on(event, cb);
84
- },
85
- async start(_opts: EngineStartOptions): Promise<void> {
86
- if (running) return;
87
- running = true;
88
- bus.emit('state', 'listening');
89
- run();
90
- },
91
- async stop(): Promise<void> {
92
- running = false;
93
- clearTimers();
94
- bus.emit('state', 'closed');
95
- },
96
- abort(): void {
97
- running = false;
98
- clearTimers();
99
- bus.emit('state', 'closed');
100
- },
101
- };
102
- }
103
-
104
- import type { ReactNode } from 'react';
105
-
106
- export function Frame({
107
- children,
108
- w = 480,
109
- h = 'auto' as number | string,
110
- }: {
111
- children: ReactNode;
112
- w?: number | string;
113
- h?: number | string;
114
- }) {
115
- return (
116
- <div
117
- className="rounded-lg border border-border bg-background p-4 shadow-sm"
118
- style={{ width: w, height: h }}
119
- >
120
- {children}
121
- </div>
122
- );
123
- }
@@ -1,279 +0,0 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
- import { defineStory, useSelect } from '@djangocfg/playground';
5
- import { Button, Card, CardContent, CardHeader, CardTitle } from '@djangocfg/ui-core/components';
6
- import { Tour, useTour } from './index';
7
- import type { Tour as TourConfig } from './types';
8
-
9
- export default defineStory({
10
- title: 'Tools/Tour',
11
- component: Tour,
12
- description: 'Onboarding tours with spotlight highlighting and keyboard navigation.',
13
- });
14
-
15
- // Demo tours
16
- const demoTours: TourConfig[] = [
17
- {
18
- id: 'basic',
19
- steps: [
20
- {
21
- id: 'welcome',
22
- target: '[data-tour-step-id="header"]',
23
- title: 'Welcome to the Demo',
24
- content: 'This tour will show you the main features of this page.',
25
- position: 'bottom',
26
- },
27
- {
28
- id: 'sidebar',
29
- target: '[data-tour-step-id="sidebar"]',
30
- title: 'Navigation Sidebar',
31
- content: 'Use this sidebar to navigate between different sections.',
32
- position: 'right',
33
- },
34
- {
35
- id: 'content',
36
- target: '[data-tour-step-id="main-content"]',
37
- title: 'Main Content Area',
38
- content: 'This is where all your content will be displayed.',
39
- position: 'top',
40
- },
41
- {
42
- id: 'actions',
43
- target: '[data-tour-step-id="action-button"]',
44
- title: 'Quick Actions',
45
- content: 'Click here to perform quick actions.',
46
- position: 'left',
47
- },
48
- ],
49
- },
50
- {
51
- id: 'cards',
52
- defaults: {
53
- spotlightPadding: 12,
54
- },
55
- steps: [
56
- {
57
- id: 'step-1',
58
- target: '[data-tour-step-id="card-1"]',
59
- title: 'First Card',
60
- content: 'This card shows important information.',
61
- position: 'bottom',
62
- },
63
- {
64
- id: 'step-2',
65
- target: '[data-tour-step-id="card-2"]',
66
- title: 'Second Card',
67
- content: 'Another important card with different data.',
68
- position: 'bottom',
69
- },
70
- {
71
- id: 'step-3',
72
- target: '[data-tour-step-id="card-3"]',
73
- title: 'Third Card',
74
- content: 'The last card in this row.',
75
- position: 'bottom',
76
- nextLabel: 'Complete Tour',
77
- },
78
- ],
79
- },
80
- ];
81
-
82
- // Demo component with tour targets
83
- function DemoLayout() {
84
- const { start, isActive, currentStepIndex, totalSteps } = useTour();
85
-
86
- return (
87
- <div className="min-h-[500px] rounded-lg bg-muted/30 p-4">
88
- {/* Header */}
89
- <header
90
- data-tour-step-id="header"
91
- className="mb-4 rounded-lg bg-primary p-4 text-primary-foreground"
92
- >
93
- <div className="flex items-center justify-between">
94
- <h1 className="text-xl font-bold">Tour Demo</h1>
95
- <div className="flex gap-2">
96
- <Button
97
- variant="secondary"
98
- size="sm"
99
- onClick={() => start('basic')}
100
- disabled={isActive}
101
- >
102
- Basic Tour
103
- </Button>
104
- <Button
105
- variant="secondary"
106
- size="sm"
107
- onClick={() => start('cards')}
108
- disabled={isActive}
109
- >
110
- Cards Tour
111
- </Button>
112
- </div>
113
- </div>
114
- </header>
115
-
116
- <div className="flex gap-4">
117
- {/* Sidebar */}
118
- <aside
119
- data-tour-step-id="sidebar"
120
- className="w-48 rounded-lg bg-card p-4 shadow"
121
- >
122
- <nav className="space-y-2">
123
- <div className="rounded bg-muted p-2 text-sm">Dashboard</div>
124
- <div className="rounded p-2 text-sm hover:bg-muted">Settings</div>
125
- <div className="rounded p-2 text-sm hover:bg-muted">Profile</div>
126
- <div className="rounded p-2 text-sm hover:bg-muted">Help</div>
127
- </nav>
128
- </aside>
129
-
130
- {/* Main content */}
131
- <main className="flex-1 space-y-4">
132
- <div
133
- data-tour-step-id="main-content"
134
- className="rounded-lg bg-card p-6 shadow"
135
- >
136
- <h2 className="mb-4 text-lg font-semibold">Main Content</h2>
137
- <p className="text-muted-foreground">
138
- This is the main content area.
139
- {isActive && (
140
- <span className="ml-2 text-primary">
141
- (Step {currentStepIndex + 1} of {totalSteps})
142
- </span>
143
- )}
144
- </p>
145
-
146
- <Button data-tour-step-id="action-button" className="mt-4">
147
- Quick Action
148
- </Button>
149
- </div>
150
-
151
- {/* Cards row */}
152
- <div className="grid grid-cols-3 gap-4">
153
- <Card data-tour-step-id="card-1">
154
- <CardHeader>
155
- <CardTitle className="text-base">Card 1</CardTitle>
156
- </CardHeader>
157
- <CardContent>
158
- <p className="text-sm text-muted-foreground">First card content.</p>
159
- </CardContent>
160
- </Card>
161
-
162
- <Card data-tour-step-id="card-2">
163
- <CardHeader>
164
- <CardTitle className="text-base">Card 2</CardTitle>
165
- </CardHeader>
166
- <CardContent>
167
- <p className="text-sm text-muted-foreground">Second card content.</p>
168
- </CardContent>
169
- </Card>
170
-
171
- <Card data-tour-step-id="card-3">
172
- <CardHeader>
173
- <CardTitle className="text-base">Card 3</CardTitle>
174
- </CardHeader>
175
- <CardContent>
176
- <p className="text-sm text-muted-foreground">Third card content.</p>
177
- </CardContent>
178
- </Card>
179
- </div>
180
- </main>
181
- </div>
182
- </div>
183
- );
184
- }
185
-
186
- export const Interactive = () => {
187
- const [progressVariant] = useSelect('progressVariant', {
188
- options: ['dots', 'bar', 'fraction', 'none'] as const,
189
- defaultValue: 'dots',
190
- label: 'Progress Variant',
191
- });
192
-
193
- return (
194
- <Tour
195
- tours={demoTours}
196
- progressVariant={progressVariant}
197
- onStart={(id) => console.log('Tour started:', id)}
198
- onComplete={(id) => console.log('Tour completed:', id)}
199
- onSkip={(id, step) => console.log('Tour skipped:', id, 'at step', step)}
200
- onStepChange={(index, step, direction) =>
201
- console.log('Step:', index, step.id, direction)
202
- }
203
- >
204
- <DemoLayout />
205
- </Tour>
206
- );
207
- };
208
-
209
- export const WithProgressBar = () => (
210
- <Tour tours={demoTours} progressVariant="bar">
211
- <DemoLayout />
212
- </Tour>
213
- );
214
-
215
- export const WithFraction = () => (
216
- <Tour tours={demoTours} progressVariant="fraction">
217
- <DemoLayout />
218
- </Tour>
219
- );
220
-
221
- export const NoSpotlight = () => (
222
- <Tour tours={demoTours} spotlight={false}>
223
- <DemoLayout />
224
- </Tour>
225
- );
226
-
227
- export const CloseOnOverlayClick = () => (
228
- <Tour tours={demoTours} closeOnOverlayClick>
229
- <DemoLayout />
230
- </Tour>
231
- );
232
-
233
- export const NoSkipButton = () => (
234
- <Tour tours={demoTours} showSkipButton={false}>
235
- <DemoLayout />
236
- </Tour>
237
- );
238
-
239
- export const WithArrow = () => (
240
- <Tour tours={demoTours} showArrow>
241
- <DemoLayout />
242
- </Tour>
243
- );
244
-
245
- export const WithBlur = () => (
246
- <Tour tours={demoTours} spotlightBlur={4} spotlightOpacity={0.3}>
247
- <DemoLayout />
248
- </Tour>
249
- );
250
-
251
- export const WithArrowAndBlur = () => (
252
- <Tour tours={demoTours} showArrow spotlightBlur={3} spotlightOpacity={0.4}>
253
- <DemoLayout />
254
- </Tour>
255
- );
256
-
257
- export const WithPulseRing = () => (
258
- <Tour tours={demoTours} pulseRing>
259
- <DemoLayout />
260
- </Tour>
261
- );
262
-
263
- export const NoAnimation = () => (
264
- <Tour tours={demoTours} animated={false}>
265
- <DemoLayout />
266
- </Tour>
267
- );
268
-
269
- export const FullFeatured = () => (
270
- <Tour
271
- tours={demoTours}
272
- showArrow
273
- spotlightBlur={2}
274
- spotlightOpacity={0.4}
275
- pulseRing
276
- >
277
- <DemoLayout />
278
- </Tour>
279
- );