@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,251 +0,0 @@
1
- import { defineStory, useSelect, useBoolean } from '@djangocfg/playground';
2
- import Mermaid, {
3
- FlowDiagram,
4
- SequenceDiagram,
5
- JourneyDiagram,
6
- useStylePresets,
7
- useBoxColors,
8
- } from './index';
9
-
10
- export default defineStory({
11
- title: 'Tools/Mermaid',
12
- component: Mermaid,
13
- description: 'Mermaid diagram renderer with declarative type-safe builders.',
14
- });
15
-
16
- // ============================================================================
17
- // Diagram Generators
18
- // ============================================================================
19
-
20
- function useFlowDiagram() {
21
- type Nodes = 'start' | 'check' | 'success' | 'debug' | 'finish';
22
- const flow = FlowDiagram<Nodes>({ direction: 'TB' });
23
- const presets = useStylePresets();
24
-
25
- flow.node('start').rect('Start');
26
- flow.node('check').rhombus('Is it working?');
27
- flow.node('success').rect('Great!');
28
- flow.node('debug').rect('Debug');
29
- flow.node('finish').stadium('End');
30
-
31
- flow.edge('start').to('check').solid();
32
- flow.edge('check').to('success').solid('Yes');
33
- flow.edge('check').to('debug').solid('No');
34
- flow.edge('debug').to('check').dotted();
35
- flow.edge('success').to('finish').solid();
36
-
37
- flow.style.define('success', presets.success);
38
- flow.style.define('primary', presets.primary);
39
- flow.style.apply('success', 'success', 'finish');
40
- flow.style.apply('primary', 'start');
41
-
42
- return flow.toString();
43
- }
44
-
45
- function useSequenceDiagram() {
46
- const boxes = useBoxColors();
47
-
48
- const { d, rect, alt, loop, blank, toString } = SequenceDiagram({
49
- User: 'actor',
50
- App: 'participant',
51
- Auth: 'participant',
52
- DB: 'participant',
53
- }, { autoNumber: true });
54
-
55
- rect(boxes.primary, () => {
56
- d.User.sync.App.msg('Enter credentials');
57
- d.App.sync.Auth.msg('Validate credentials');
58
-
59
- alt('Valid credentials', () => {
60
- d.Auth.sync.DB.msg('Get user profile');
61
- d.DB.syncReply.Auth.msg('Profile data');
62
- d.Auth.syncReply.App.msg('Auth token');
63
- d.App.syncReply.User.msg('Welcome!');
64
- }).else('Invalid credentials', () => {
65
- d.Auth.syncReply.App.msg('Auth failed');
66
- d.App.syncReply.User.msg('Error message');
67
- });
68
- });
69
-
70
- blank();
71
-
72
- loop('Every 15 minutes', () => {
73
- d.App.async.Auth.msg('Refresh token');
74
- d.Auth.asyncReply.App.msg('New token');
75
- });
76
-
77
- return toString();
78
- }
79
-
80
- function useJourneyDiagram() {
81
- const journey = JourneyDiagram({ title: 'User Onboarding' });
82
-
83
- journey.section('Discovery')
84
- .task('Visit landing page', 5, 'User')
85
- .task('Read features', 4, 'User');
86
-
87
- journey.section('Sign Up')
88
- .task('Click Sign Up', 5, 'User')
89
- .task('Fill form', 2, 'User')
90
- .task('Verify email', 4, ['User', 'System']);
91
-
92
- journey.section('Onboarding')
93
- .task('Complete profile', 3, 'User')
94
- .task('Create first project', 5, 'User');
95
-
96
- return journey.toString();
97
- }
98
-
99
- /**
100
- * Example using dynamic methods for runtime participant names
101
- * Useful when participants are not known at compile time
102
- */
103
- function useDynamicSequenceDiagram() {
104
- const boxes = useBoxColors();
105
-
106
- // Participants from dynamic data (e.g., from API)
107
- const participants = ['Alice', 'Bob', 'Charlie'];
108
- const participantsObj: Record<string, 'participant'> = {};
109
- participants.forEach(p => { participantsObj[p] = 'participant'; });
110
-
111
- const seq = SequenceDiagram(participantsObj, { autoNumber: true });
112
-
113
- // Using dynamic methods - no type assertions needed
114
- seq.rect(boxes.primary, () => {
115
- seq.noteOver('Alice', 'Starting conversation');
116
- seq.message('Alice', 'Bob', 'Hello Bob!');
117
- seq.message('Bob', 'Alice', 'Hi Alice!', 'syncReply');
118
- });
119
-
120
- seq.blank();
121
-
122
- seq.rect(boxes.success, () => {
123
- seq.noteOverSpan('Alice', 'Charlie', 'Group discussion');
124
- seq.message('Alice', 'Charlie', 'Hey Charlie!');
125
- seq.message('Charlie', 'Bob', 'Bob, join us!');
126
- seq.message('Bob', 'Charlie', 'On my way!', 'async');
127
- });
128
-
129
- return seq.toString();
130
- }
131
-
132
- function useArchitectureDiagram() {
133
- type Nodes = 'client' | 'nginx' | 'api1' | 'api2' | 'db' | 'cache' | 'queue';
134
- const flow = FlowDiagram<Nodes>({ direction: 'TB' });
135
- const presets = useStylePresets();
136
-
137
- flow.subgraph('Frontend', (sub) => {
138
- sub.direction('LR');
139
- sub.node('client').round('Browser');
140
- });
141
-
142
- flow.subgraph('Load Balancer', (sub) => {
143
- sub.node('nginx').hexagon('Nginx');
144
- });
145
-
146
- flow.subgraph('API Servers', (sub) => {
147
- sub.direction('LR');
148
- sub.node('api1').rect('API Server 1');
149
- sub.node('api2').rect('API Server 2');
150
- });
151
-
152
- flow.subgraph('Data Layer', (sub) => {
153
- sub.direction('LR');
154
- sub.node('db').cylinder('PostgreSQL');
155
- sub.node('cache').cylinder('Redis');
156
- sub.node('queue').cylinder('RabbitMQ');
157
- });
158
-
159
- flow.edge('client').to('nginx').solid();
160
- flow.edge('nginx').to('api1').solid();
161
- flow.edge('nginx').to('api2').solid();
162
- flow.edge('api1').to('db').solid();
163
- flow.edge('api2').to('db').solid();
164
- flow.edge('api1').to('cache').dotted();
165
- flow.edge('api2').to('cache').dotted();
166
- flow.edge('api1').to('queue').dotted();
167
-
168
- flow.style.define('frontend', presets.info);
169
- flow.style.define('backend', presets.success);
170
- flow.style.define('data', presets.warning);
171
- flow.style.apply('frontend', 'client', 'nginx');
172
- flow.style.apply('backend', 'api1', 'api2');
173
- flow.style.apply('data', 'db', 'cache', 'queue');
174
-
175
- return flow.toString();
176
- }
177
-
178
- // ============================================================================
179
- // Stories
180
- // ============================================================================
181
-
182
- export const Interactive = () => {
183
- const [diagramType] = useSelect('diagramType', {
184
- options: ['flow', 'sequence', 'sequenceDynamic', 'journey', 'architecture'] as const,
185
- defaultValue: 'flow',
186
- label: 'Diagram Type',
187
- });
188
-
189
- const [fullscreen] = useBoolean('fullscreen', {
190
- defaultValue: false,
191
- label: 'Enable Fullscreen',
192
- });
193
-
194
- const flowChart = useFlowDiagram();
195
- const sequenceChart = useSequenceDiagram();
196
- const sequenceDynamicChart = useDynamicSequenceDiagram();
197
- const journeyChart = useJourneyDiagram();
198
- const architectureChart = useArchitectureDiagram();
199
-
200
- const charts = {
201
- flow: flowChart,
202
- sequence: sequenceChart,
203
- sequenceDynamic: sequenceDynamicChart,
204
- journey: journeyChart,
205
- architecture: architectureChart,
206
- };
207
-
208
- const chart = charts[diagramType];
209
-
210
- return (
211
- <div className="space-y-4">
212
- <Mermaid chart={chart} fullscreen={fullscreen} />
213
- <details className="text-xs">
214
- <summary className="cursor-pointer text-muted-foreground">Generated Mermaid code</summary>
215
- <pre className="mt-2 p-3 bg-muted rounded overflow-auto">{chart}</pre>
216
- </details>
217
- </div>
218
- );
219
- };
220
-
221
- export const Flow = () => {
222
- const chart = useFlowDiagram();
223
- return <Mermaid chart={chart} />;
224
- };
225
-
226
- export const Sequence = () => {
227
- const chart = useSequenceDiagram();
228
- return <Mermaid chart={chart} />;
229
- };
230
-
231
- export const Journey = () => {
232
- const chart = useJourneyDiagram();
233
- return <Mermaid chart={chart} />;
234
- };
235
-
236
- export const Architecture = () => {
237
- const chart = useArchitectureDiagram();
238
- return <Mermaid chart={chart} />;
239
- };
240
-
241
- export const WithFullscreen = () => {
242
- const chart = useFlowDiagram();
243
- return (
244
- <div className="space-y-2">
245
- <p className="text-sm text-muted-foreground">
246
- Click the expand button to open fullscreen
247
- </p>
248
- <Mermaid chart={chart} fullscreen />
249
- </div>
250
- );
251
- };
@@ -1,230 +0,0 @@
1
- import { defineStory, useSelect, useValue, useBoolean } from '@djangocfg/playground';
2
- import { Playground } from './index';
3
- import { LazyOpenapiViewer } from './lazy';
4
- import type { PlaygroundConfig } from './types';
5
-
6
- export default defineStory({
7
- title: 'Tools/OpenapiViewer',
8
- component: Playground,
9
- description:
10
- 'Interactive OpenAPI schema viewer. Sidebar + docs longread with a slide-in two-column playground (Request + Response) when an endpoint is selected.',
11
- });
12
-
13
- // ============================================================================
14
- // Schema fixtures
15
- // ============================================================================
16
-
17
- // Petstore's own ``servers[0].url`` is just ``/api/v3`` (relative),
18
- // which makes code samples look like they target ``localhost`` when
19
- // viewed from the playground. Override with the canonical public host
20
- // so the generated curl/fetch/etc snippets are runnable as-is.
21
- const PETSTORE_SCHEMA = {
22
- id: 'petstore',
23
- name: 'Petstore API',
24
- url: 'https://petstore3.swagger.io/api/v3/openapi.json',
25
- baseUrl: 'https://petstore3.swagger.io/api/v3',
26
- } as const;
27
-
28
- const HTTPBIN_SCHEMA = {
29
- id: 'httpbin',
30
- name: 'HTTPBin API',
31
- url: 'https://httpbin.org/spec.json',
32
- } as const;
33
-
34
- const MULTI_SCHEMAS = [PETSTORE_SCHEMA, HTTPBIN_SCHEMA] as const;
35
-
36
- // Simulates a real multi-group setup (like cmdop with 5+ API groups).
37
- // All clones share the canonical Petstore host so code samples
38
- // render with a real runnable URL.
39
- const PETSTORE_BASE = 'https://petstore3.swagger.io/api/v3';
40
- const MANY_SCHEMAS = [
41
- PETSTORE_SCHEMA,
42
- HTTPBIN_SCHEMA,
43
- { id: 'machines', name: 'Machines API', url: 'https://petstore3.swagger.io/api/v3/openapi.json', baseUrl: PETSTORE_BASE },
44
- { id: 'terminal', name: 'Terminal API', url: 'https://petstore3.swagger.io/api/v3/openapi.json', baseUrl: PETSTORE_BASE },
45
- { id: 'skills', name: 'Skills API', url: 'https://petstore3.swagger.io/api/v3/openapi.json', baseUrl: PETSTORE_BASE },
46
- { id: 'system', name: 'System API', url: 'https://petstore3.swagger.io/api/v3/openapi.json', baseUrl: PETSTORE_BASE },
47
- { id: 'site', name: 'Site API', url: 'https://petstore3.swagger.io/api/v3/openapi.json', baseUrl: PETSTORE_BASE },
48
- ] as const;
49
-
50
- // ============================================================================
51
- // Stories
52
- // ============================================================================
53
-
54
- /**
55
- * Default — single-schema mode with the most common configuration knobs
56
- * exposed as toggles. Replaces the earlier Interactive / SingleSchema /
57
- * WithBaseUrl / NoDefault / CustomUrl stories, which were all "this
58
- * component with different props" variations.
59
- */
60
- export const Default = () => {
61
- const [schemaUrl] = useValue('schemaUrl', {
62
- defaultValue: PETSTORE_SCHEMA.url,
63
- label: 'Schema URL',
64
- description: 'Any OpenAPI 3.x JSON endpoint',
65
- });
66
-
67
- const [baseUrl] = useValue('baseUrl', {
68
- defaultValue: '',
69
- label: 'Base URL override',
70
- description: 'Empty = use servers[0].url from the schema',
71
- });
72
-
73
- const [autoSelect] = useBoolean('autoSelectDefault', {
74
- defaultValue: true,
75
- label: 'Auto-select default schema',
76
- description: 'When off, tests the "no defaultSchemaId" code path',
77
- });
78
-
79
- const config: PlaygroundConfig = {
80
- schemas: [{ id: 'custom', name: 'Schema', url: schemaUrl }],
81
- defaultSchemaId: autoSelect ? 'custom' : undefined,
82
- baseUrl: baseUrl || undefined,
83
- };
84
-
85
- return (
86
- <div className="min-h-[600px]">
87
- <Playground config={config} />
88
- </div>
89
- );
90
- };
91
-
92
- /**
93
- * MultiSchema — multiple schemas with the Combobox switcher. Count
94
- * is adjustable to exercise both the short-list layout and the
95
- * long-list behaviour (cmdop-style setups with 7+ APIs).
96
- */
97
- export const MultiSchema = () => {
98
- const [count] = useSelect('count', {
99
- options: ['2', '7'] as const,
100
- defaultValue: '2',
101
- label: 'Schema count',
102
- description: '2 uses Petstore+HTTPBin; 7 stress-tests the Combobox',
103
- });
104
-
105
- const config: PlaygroundConfig = {
106
- schemas: count === '2' ? [...MULTI_SCHEMAS] : [...MANY_SCHEMAS],
107
- defaultSchemaId: 'petstore',
108
- };
109
-
110
- return (
111
- <div className="min-h-[600px]">
112
- <Playground config={config} />
113
- </div>
114
- );
115
- };
116
-
117
- /**
118
- * SectionsGrouping — alternate layout: every schema's endpoints get
119
- * rendered on the same page as top-level sections, with a sidebar
120
- * that stacks them. URL hash sync writes ``#<schemaId>/<anchor>``
121
- * as the user scrolls so deep-linking keeps working.
122
- */
123
- export const SectionsGrouping = () => {
124
- const [urlSync] = useBoolean('urlSync', {
125
- defaultValue: true,
126
- label: 'URL hash sync',
127
- description: 'Writes #<schemaId>/<anchor> as you scroll',
128
- });
129
-
130
- const config: PlaygroundConfig = {
131
- schemas: [...MULTI_SCHEMAS],
132
- defaultSchemaId: 'petstore',
133
- schemaGrouping: 'sections',
134
- urlSync,
135
- };
136
-
137
- return (
138
- <div className="min-h-[600px]">
139
- <Playground config={config} />
140
- </div>
141
- );
142
- };
143
-
144
- /**
145
- * Errors — consolidated failure paths. Pick a scenario via the toggle:
146
- * - ``broken``: single schema that 404s → full-panel error state.
147
- * - ``mixed``: valid + broken side-by-side → tests switching between.
148
- * - ``empty``: no schemas configured at all → empty-state UI.
149
- */
150
- export const Errors = () => {
151
- const [scenario] = useSelect('scenario', {
152
- options: ['broken', 'mixed', 'empty'] as const,
153
- defaultValue: 'broken',
154
- label: 'Failure scenario',
155
- });
156
-
157
- const config: PlaygroundConfig = (() => {
158
- switch (scenario) {
159
- case 'broken':
160
- return {
161
- schemas: [{ id: 'broken', name: 'Broken API', url: 'https://httpbin.org/status/404' }],
162
- defaultSchemaId: 'broken',
163
- };
164
- case 'mixed':
165
- return {
166
- schemas: [
167
- PETSTORE_SCHEMA,
168
- { id: 'broken', name: 'Broken API (404)', url: 'https://httpbin.org/status/404' },
169
- ],
170
- defaultSchemaId: 'petstore',
171
- };
172
- case 'empty':
173
- return { schemas: [] };
174
- }
175
- })();
176
-
177
- return (
178
- <div className="min-h-[600px]">
179
- <Playground config={config} />
180
- </div>
181
- );
182
- };
183
-
184
- /**
185
- * UnfilledPathParams — regression guard for the ``%7Bid%7D`` bug.
186
- *
187
- * When a path template like ``/pet/{petId}`` is rendered before the
188
- * user types a value, the path stays a template — not a percent-
189
- * encoded string. Previously the URL parser turned ``{`` / ``}`` into
190
- * ``%7B`` / ``%7D``, and the same encoded form leaked into every
191
- * generated code sample (curl, axios, python, …) via the HAR
192
- * intermediate.
193
- *
194
- * To verify visually:
195
- * 1. Open any endpoint with a path param, e.g. ``GET /pet/{petId}``,
196
- * ``GET /store/order/{orderId}``, or ``GET /user/{username}``.
197
- * 2. Without filling the parameter, look at the header path and
198
- * every Code Samples tab.
199
- * 3. All occurrences must read ``{petId}``, never ``%7BpetId%7D``.
200
- */
201
- export const UnfilledPathParams = () => {
202
- const config: PlaygroundConfig = {
203
- schemas: [PETSTORE_SCHEMA],
204
- defaultSchemaId: 'petstore',
205
- };
206
-
207
- return (
208
- <div className="min-h-[600px]">
209
- <Playground config={config} />
210
- </div>
211
- );
212
- };
213
-
214
- /**
215
- * Lazy — production lazy-loaded variant. Shows the loading spinner
216
- * while the ~400 KB OpenAPI viewer chunk is fetched. Only path you
217
- * should use in an actual app bundle.
218
- */
219
- export const Lazy = () => {
220
- const config: PlaygroundConfig = {
221
- schemas: [...MULTI_SCHEMAS],
222
- defaultSchemaId: 'petstore',
223
- };
224
-
225
- return (
226
- <div className="min-h-[600px]">
227
- <LazyOpenapiViewer config={config} />
228
- </div>
229
- );
230
- };