@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.
- package/dist/ChatRoot-JVR3M3H2.mjs +5 -0
- package/dist/{ChatRoot-6IZFM5HM.mjs.map → ChatRoot-JVR3M3H2.mjs.map} +1 -1
- package/dist/ChatRoot-LXIUBOXF.cjs +14 -0
- package/dist/{ChatRoot-LW4XNIKP.cjs.map → ChatRoot-LXIUBOXF.cjs.map} +1 -1
- package/dist/DictationField-U25MEYAL.mjs +4 -0
- package/dist/{DictationField-2ZLQWLYV.mjs.map → DictationField-U25MEYAL.mjs.map} +1 -1
- package/dist/DictationField-XWR5VOID.cjs +13 -0
- package/dist/{DictationField-IPPJ54CU.cjs.map → DictationField-XWR5VOID.cjs.map} +1 -1
- package/dist/{chunk-KMSBGNVC.cjs → chunk-4PFW7MIJ.cjs} +4 -2
- package/dist/chunk-4PFW7MIJ.cjs.map +1 -0
- package/dist/{chunk-4LXG3NBV.mjs → chunk-C2YN6WEO.mjs} +3 -3
- package/dist/chunk-C2YN6WEO.mjs.map +1 -0
- package/dist/{chunk-OZAU3QWD.cjs → chunk-HPK3EWBF.cjs} +8 -8
- package/dist/chunk-HPK3EWBF.cjs.map +1 -0
- package/dist/{chunk-UWVP6LCW.mjs → chunk-PEKBT75W.mjs} +8 -8
- package/dist/chunk-PEKBT75W.mjs.map +1 -0
- package/dist/index.cjs +192 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -6
- package/dist/index.d.ts +78 -6
- package/dist/index.mjs +143 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -13
- package/src/tools/Chat/core/audio/defaults.ts +16 -11
- package/src/tools/Chat/core/audio/sounds/error.ts +3 -0
- package/src/tools/Chat/core/audio/sounds/mention.ts +3 -0
- package/src/tools/Chat/core/audio/sounds/notification.ts +3 -0
- package/src/tools/Chat/core/audio/sounds/received.ts +3 -0
- package/src/tools/Chat/core/audio/sounds/sent.ts +3 -0
- package/src/tools/Chat/core/audio/sounds/start.ts +3 -0
- package/src/tools/Chat/index.ts +15 -0
- package/src/tools/SpeechRecognition/core/audio/defaults.ts +4 -4
- package/dist/ChatRoot-6IZFM5HM.mjs +0 -5
- package/dist/ChatRoot-LW4XNIKP.cjs +0 -14
- package/dist/DictationField-2ZLQWLYV.mjs +0 -4
- package/dist/DictationField-IPPJ54CU.cjs +0 -13
- package/dist/chunk-4LXG3NBV.mjs.map +0 -1
- package/dist/chunk-KMSBGNVC.cjs.map +0 -1
- package/dist/chunk-OZAU3QWD.cjs.map +0 -1
- package/dist/chunk-UWVP6LCW.mjs.map +0 -1
- package/src/audio-assets.d.ts +0 -8
- package/src/components/markdown/MarkdownMessage/MarkdownMessage.story.tsx +0 -771
- package/src/stories/index.ts +0 -63
- package/src/tools/AudioPlayer/AudioPlayer.story.tsx +0 -481
- package/src/tools/Chat/core/audio/sounds/error.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/mention.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/notification.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/received.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/sent.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/start.mp3 +0 -0
- package/src/tools/Chat/stories/01-basic.story.tsx +0 -64
- package/src/tools/Chat/stories/02-bubbles.story.tsx +0 -21
- package/src/tools/Chat/stories/03-tool-calls.story.tsx +0 -59
- package/src/tools/Chat/stories/04-personas.story.tsx +0 -78
- package/src/tools/Chat/stories/05-launcher.story.tsx +0 -321
- package/src/tools/Chat/stories/06-header.story.tsx +0 -147
- package/src/tools/Chat/stories/07-audio-actions.story.tsx +0 -112
- package/src/tools/Chat/stories/shared/Frame.tsx +0 -21
- package/src/tools/Chat/stories/shared/index.ts +0 -5
- package/src/tools/Chat/stories/shared/messages.ts +0 -39
- package/src/tools/Chat/stories/shared/personas.ts +0 -13
- package/src/tools/Chat/stories/shared/seeds.ts +0 -92
- package/src/tools/Chat/stories/shared/transports.ts +0 -36
- package/src/tools/CodeEditor/CodeEditor.story.tsx +0 -202
- package/src/tools/CronScheduler/CronScheduler.story.tsx +0 -300
- package/src/tools/Gallery/Gallery.story.tsx +0 -237
- package/src/tools/ImageViewer/ImageViewer.story.tsx +0 -85
- package/src/tools/JsonForm/JsonForm.story.tsx +0 -350
- package/src/tools/JsonTree/JsonTree.story.tsx +0 -141
- package/src/tools/LottiePlayer/LottiePlayer.story.tsx +0 -95
- package/src/tools/Map/Map.story.tsx +0 -458
- package/src/tools/MarkdownEditor/MarkdownEditor.story.tsx +0 -225
- package/src/tools/Mermaid/Mermaid.story.tsx +0 -251
- package/src/tools/OpenapiViewer/OpenapiViewer.story.tsx +0 -230
- package/src/tools/PrettyCode/PrettyCode.story.tsx +0 -304
- package/src/tools/SpeechRecognition/stories/01-basic.story.tsx +0 -32
- package/src/tools/SpeechRecognition/stories/02-dictation-field.story.tsx +0 -32
- package/src/tools/SpeechRecognition/stories/03-push-to-talk.story.tsx +0 -27
- package/src/tools/SpeechRecognition/stories/04-mic-meter.story.tsx +0 -35
- package/src/tools/SpeechRecognition/stories/05-custom-engine-http.story.tsx +0 -40
- package/src/tools/SpeechRecognition/stories/06-custom-engine-ws.story.tsx +0 -48
- package/src/tools/SpeechRecognition/stories/07-language-device.story.tsx +0 -57
- package/src/tools/SpeechRecognition/stories/08-errors-permissions.story.tsx +0 -25
- package/src/tools/SpeechRecognition/stories/09-chat-voice.story.tsx +0 -90
- package/src/tools/SpeechRecognition/stories/shared.tsx +0 -123
- package/src/tools/Tour/Tour.story.tsx +0 -279
- package/src/tools/Tree/Tree.story.tsx +0 -620
- package/src/tools/Uploader/Uploader.story.tsx +0 -415
- 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
|
-
);
|