@djangocfg/widget-code 0.1.18 → 0.1.21

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.
@@ -1,353 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { LazyPrettyCode as PrettyCode } from './lazy';
3
-
4
- // ─── Samples ──────────────────────────────────────────────────────────────────
5
-
6
- const TS_SAMPLE = `import { useCallback, useEffect, useRef, useState } from 'react';
7
-
8
- export type Status = 'idle' | 'loading' | 'success' | 'error';
9
-
10
- export interface PaginationParams {
11
- page: number;
12
- pageSize: number;
13
- sortBy?: string;
14
- sortOrder?: 'asc' | 'desc';
15
- }
16
-
17
- export function useVehicles(initialParams?: Partial<PaginationParams>) {
18
- const [status, setStatus] = useState<Status>('idle');
19
- const [data, setData] = useState<unknown[]>([]);
20
- const abortRef = useRef<AbortController | null>(null);
21
-
22
- const fetch = useCallback(async (p: PaginationParams) => {
23
- abortRef.current?.abort();
24
- abortRef.current = new AbortController();
25
- setStatus('loading');
26
- const res = await window.fetch(\`/api/vehicles?page=\${p.page}\`, {
27
- signal: abortRef.current.signal,
28
- });
29
- const json = await res.json();
30
- setData(json.data);
31
- setStatus('success');
32
- }, []);
33
-
34
- useEffect(() => {
35
- fetch(initialParams as PaginationParams);
36
- return () => abortRef.current?.abort();
37
- }, []);
38
-
39
- return { status, data };
40
- }`;
41
-
42
- const JSON_SAMPLE = {
43
- framework: 'next',
44
- version: '16.2.2',
45
- features: ['app-router', 'rsc', 'turbopack'],
46
- flags: { strictMode: true, experimentalRSC: true },
47
- routes: [
48
- { path: '/', component: 'HomePage' },
49
- { path: '/about', component: 'AboutPage' },
50
- ],
51
- };
52
-
53
- const PYTHON_SAMPLE = `from __future__ import annotations
54
-
55
- import asyncio
56
- from dataclasses import dataclass
57
- from datetime import datetime
58
- from enum import StrEnum
59
-
60
- import httpx
61
- from pydantic import BaseModel, Field, field_validator
62
-
63
-
64
- class FuelType(StrEnum):
65
- GASOLINE = "gasoline"
66
- DIESEL = "diesel"
67
- ELECTRIC = "electric"
68
-
69
-
70
- class Vehicle(BaseModel):
71
- id: str
72
- make: str
73
- model: str
74
- year: int
75
- fuel_type: FuelType
76
- created_at: datetime = Field(default_factory=datetime.utcnow)
77
-
78
- @field_validator("year")
79
- @classmethod
80
- def validate_year(cls, v: int) -> int:
81
- if not (1900 <= v <= datetime.utcnow().year + 1):
82
- raise ValueError(f"Invalid year: {v}")
83
- return v
84
-
85
-
86
- @dataclass
87
- class VehicleRepository:
88
- base_url: str
89
-
90
- async def list(self, page: int = 1) -> list[Vehicle]:
91
- async with httpx.AsyncClient(base_url=self.base_url) as client:
92
- response = await client.get("/vehicles", params={"page": page})
93
- response.raise_for_status()
94
- return [Vehicle.model_validate(v) for v in response.json()["data"]]`;
95
-
96
- const BASH_SAMPLE = `#!/usr/bin/env bash
97
- set -euo pipefail
98
-
99
- # Deploy script for production
100
- ENV="\${1:-staging}"
101
- TAG="\${2:-latest}"
102
-
103
- echo "Deploying to $ENV with tag $TAG"
104
-
105
- docker build -t myapp:$TAG .
106
- docker push registry.example.com/myapp:$TAG
107
-
108
- kubectl set image deployment/myapp app=registry.example.com/myapp:$TAG
109
- kubectl rollout status deployment/myapp --timeout=2m
110
-
111
- echo "Done."`;
112
-
113
- const SQL_SAMPLE = `-- Top selling vehicles in the last 30 days
114
- WITH recent_sales AS (
115
- SELECT
116
- v.id,
117
- v.make,
118
- v.model,
119
- COUNT(s.id) AS sales_count,
120
- SUM(s.amount) AS revenue
121
- FROM vehicles v
122
- INNER JOIN sales s ON s.vehicle_id = v.id
123
- WHERE s.created_at >= NOW() - INTERVAL '30 days'
124
- GROUP BY v.id, v.make, v.model
125
- )
126
- SELECT *
127
- FROM recent_sales
128
- WHERE sales_count > 5
129
- ORDER BY revenue DESC
130
- LIMIT 20;`;
131
-
132
- const YAML_SAMPLE = `version: '3.9'
133
-
134
- services:
135
- api:
136
- image: registry.example.com/myapp:latest
137
- environment:
138
- DATABASE_URL: postgres://db/app
139
- REDIS_URL: redis://cache:6379
140
- depends_on:
141
- - db
142
- - cache
143
- ports:
144
- - "8000:8000"
145
-
146
- db:
147
- image: postgres:16-alpine
148
- volumes:
149
- - db_data:/var/lib/postgresql/data
150
- environment:
151
- POSTGRES_DB: app
152
- POSTGRES_PASSWORD: secret
153
-
154
- cache:
155
- image: redis:7-alpine
156
-
157
- volumes:
158
- db_data:`;
159
-
160
- const LONG_SAMPLE = Array.from(
161
- { length: 60 },
162
- (_, i) => `const value_${i} = ${i * 3}; // computed entry ${i + 1}`,
163
- ).join('\n');
164
-
165
- // ─── Meta ─────────────────────────────────────────────────────────────────────
166
-
167
- const meta = {
168
- title: 'Widgets/Code/PrettyCode',
169
- component: PrettyCode,
170
- tags: ['autodocs'],
171
- argTypes: {
172
- data: { control: 'text', table: { category: 'Content' } },
173
- language: {
174
- control: 'select',
175
- options: [
176
- 'tsx',
177
- 'ts',
178
- 'js',
179
- 'jsx',
180
- 'json',
181
- 'python',
182
- 'bash',
183
- 'sql',
184
- 'yaml',
185
- 'css',
186
- 'html',
187
- 'go',
188
- 'rust',
189
- 'markdown',
190
- ],
191
- table: { category: 'Content' },
192
- },
193
- mode: {
194
- control: 'inline-radio',
195
- options: ['dark', 'light'],
196
- table: { category: 'Appearance' },
197
- },
198
- variant: {
199
- control: 'inline-radio',
200
- options: ['card', 'plain'],
201
- table: { category: 'Appearance' },
202
- },
203
- inline: { control: 'boolean', table: { category: 'Appearance' } },
204
- isCompact: { control: 'boolean', table: { category: 'Appearance' } },
205
- customBg: { control: 'text', table: { category: 'Appearance' } },
206
- scrollIsolation: { control: 'boolean', table: { category: 'Behaviour' } },
207
- maxLines: { control: { type: 'number', min: 0, step: 1 }, table: { category: 'Behaviour' } },
208
- },
209
- } satisfies Meta<typeof PrettyCode>;
210
-
211
- export default meta;
212
-
213
- type Story = StoryObj<typeof meta>;
214
-
215
- const Frame = ({ children }: { children: React.ReactNode }) => (
216
- <div className="w-[720px]">{children}</div>
217
- );
218
-
219
- // ─── Playground ───────────────────────────────────────────────────────────────
220
-
221
- export const Playground: Story = {
222
- args: {
223
- data: TS_SAMPLE,
224
- language: 'tsx',
225
- mode: 'dark',
226
- variant: 'card',
227
- inline: false,
228
- isCompact: false,
229
- scrollIsolation: true,
230
- },
231
- render: (args) => (
232
- <Frame>
233
- <PrettyCode {...args} />
234
- </Frame>
235
- ),
236
- };
237
-
238
- // ─── Curated presets ──────────────────────────────────────────────────────────
239
-
240
- export const TypeScript: Story = {
241
- args: { data: TS_SAMPLE, language: 'tsx' },
242
- render: (args) => (
243
- <Frame>
244
- <PrettyCode {...args} />
245
- </Frame>
246
- ),
247
- };
248
-
249
- export const Json: Story = {
250
- args: { data: JSON_SAMPLE, language: 'json' },
251
- render: (args) => (
252
- <Frame>
253
- <PrettyCode {...args} />
254
- </Frame>
255
- ),
256
- };
257
-
258
- export const Python: Story = {
259
- args: { data: PYTHON_SAMPLE, language: 'python' },
260
- render: (args) => (
261
- <Frame>
262
- <PrettyCode {...args} />
263
- </Frame>
264
- ),
265
- };
266
-
267
- export const Bash: Story = {
268
- args: { data: BASH_SAMPLE, language: 'bash' },
269
- render: (args) => (
270
- <Frame>
271
- <PrettyCode {...args} />
272
- </Frame>
273
- ),
274
- };
275
-
276
- export const Sql: Story = {
277
- args: { data: SQL_SAMPLE, language: 'sql' },
278
- render: (args) => (
279
- <Frame>
280
- <PrettyCode {...args} />
281
- </Frame>
282
- ),
283
- };
284
-
285
- export const Yaml: Story = {
286
- args: { data: YAML_SAMPLE, language: 'yaml' },
287
- render: (args) => (
288
- <Frame>
289
- <PrettyCode {...args} />
290
- </Frame>
291
- ),
292
- };
293
-
294
- export const LongFileWithScroll: Story = {
295
- args: {
296
- data: LONG_SAMPLE,
297
- language: 'ts',
298
- maxLines: 20,
299
- },
300
- render: (args) => (
301
- <Frame>
302
- <PrettyCode {...args} />
303
- </Frame>
304
- ),
305
- };
306
-
307
- export const Inline: Story = {
308
- args: {
309
- data: `const status: 'ok' | 'err' = 'ok';`,
310
- language: 'ts',
311
- inline: true,
312
- },
313
- render: (args) => (
314
- <div className="text-sm">
315
- The variable <PrettyCode {...args} /> represents the result state.
316
- </div>
317
- ),
318
- };
319
-
320
- export const Compact: Story = {
321
- args: {
322
- data: `const port = 3000;`,
323
- language: 'ts',
324
- isCompact: true,
325
- },
326
- render: (args) => <PrettyCode {...args} />,
327
- };
328
-
329
- export const LightMode: Story = {
330
- args: {
331
- data: TS_SAMPLE,
332
- language: 'tsx',
333
- mode: 'light',
334
- },
335
- render: (args) => (
336
- <Frame>
337
- <PrettyCode {...args} />
338
- </Frame>
339
- ),
340
- };
341
-
342
- export const PlainVariant: Story = {
343
- args: {
344
- data: TS_SAMPLE,
345
- language: 'tsx',
346
- variant: 'plain',
347
- },
348
- render: (args) => (
349
- <Frame>
350
- <PrettyCode {...args} />
351
- </Frame>
352
- ),
353
- };
@@ -1,116 +0,0 @@
1
- /**
2
- * Register extra Prism language grammars onto the vendored Prism
3
- * instance that ``prism-react-renderer`` ships.
4
- *
5
- * Why this file exists:
6
- * ``prism-react-renderer@2.x`` bundles only a small set of core
7
- * languages (javascript, typescript, python, go, json, css,
8
- * markup, clike, …). Anything else — ``bash``, ``ruby``, ``java``,
9
- * ``php`` — isn't in the bundle, so passing ``language="bash"`` to
10
- * ``<Highlight>`` silently renders as plain text.
11
- *
12
- * Canonical solution (per the official README):
13
- * - Grab the exported ``Prism`` instance.
14
- * - Hang it off ``globalThis`` so that ``prismjs`` language
15
- * components can find it when they self-register (they read
16
- * ``window.Prism`` / ``global.Prism`` at module-evaluation time).
17
- * - Load each grammar via dynamic ``import()`` — bare ``require``
18
- * doesn't work in ESM/Vite and static ``import 'prismjs/…'``
19
- * runs before we can hang Prism on the global.
20
- *
21
- * Runs once on module load, with a guard so repeated imports in
22
- * different bundles are a no-op. Safe for SSR: the grammars don't
23
- * touch the DOM and the dynamic import is awaited asynchronously —
24
- * server renders just miss the extra grammars, client renders pick
25
- * them up after hydration which is when the <Highlight> components
26
- * actually render anyway.
27
- */
28
-
29
- /* eslint-disable @typescript-eslint/no-explicit-any */
30
-
31
- import { useSyncExternalStore } from 'react';
32
- import { Prism } from 'prism-react-renderer';
33
-
34
- // Hang the vendored Prism on the global so ``prismjs`` language
35
- // components can find it when their self-registration runs.
36
- const globalScope: any = typeof globalThis !== 'undefined' ? globalThis : {};
37
- if (!globalScope.Prism) {
38
- globalScope.Prism = Prism;
39
- }
40
-
41
- // Ready-state machinery: one-shot boolean + subscribers. When loading
42
- // finishes we flip ``ready`` and notify listeners so components that
43
- // rendered before the grammars loaded can re-render and pick them up.
44
- let ready = false;
45
- let loading: Promise<void> | null = null;
46
- const listeners = new Set<() => void>();
47
-
48
- function subscribe(cb: () => void): () => void {
49
- listeners.add(cb);
50
- return () => listeners.delete(cb);
51
- }
52
-
53
- function getSnapshot(): boolean {
54
- return ready;
55
- }
56
-
57
- // Server snapshot — always ``true`` so SSR doesn't trip the
58
- // ``server ≠ client`` warning. The actual registration only runs on
59
- // the client; server renders fall back to the bundled Prism set,
60
- // which for the OpenAPI viewer means JS / Python / Go highlight
61
- // server-side and bash / java / ruby / php render plain until hydration.
62
- function getServerSnapshot(): boolean {
63
- return true;
64
- }
65
-
66
- export async function ensurePrismLanguages(): Promise<void> {
67
- if (ready) return;
68
- if (loading) return loading;
69
-
70
- loading = (async () => {
71
- // Dynamic imports so these modules evaluate AFTER we've
72
- // attached Prism to the global scope above.
73
- //
74
- // `as string` because the grammar files are untyped side-effect
75
- // modules — `prismjs` ships no declarations for `components/*` and
76
- // there is no `@types/prismjs` here. It widens the specifier, not a
77
- // value, so nothing about the loaded module is being asserted.
78
- //
79
- // Load order matters: ``prism-php`` calls
80
- // ``Prism.languages.markup.tokenizePlaceholders`` at module
81
- // evaluation time, which is only defined after
82
- // ``markup-templating`` loads — so that must come first.
83
- // ``bash`` / ``java`` / ``ruby`` only depend on ``clike``
84
- // which is already bundled in ``prism-react-renderer``.
85
- await import('prismjs/components/prism-markup-templating' as string);
86
- await Promise.all([
87
- import('prismjs/components/prism-bash' as string),
88
- import('prismjs/components/prism-java' as string),
89
- import('prismjs/components/prism-ruby' as string),
90
- import('prismjs/components/prism-php' as string),
91
- ]);
92
- ready = true;
93
- listeners.forEach((cb) => cb());
94
- })();
95
-
96
- return loading;
97
- }
98
-
99
- /** Hook that triggers a re-render when the extra grammars finish
100
- * loading. Used by ``PrettyCode`` so the first render (which might
101
- * happen before loading completes) gets re-highlighted once the
102
- * grammars are available. */
103
- export function useEnsurePrismLanguages(): boolean {
104
- const loaded = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
105
- if (!loaded) {
106
- // Kick off loading (idempotent — re-entry is cheap) so the
107
- // next store update flips ``ready`` and we re-render.
108
- void ensurePrismLanguages();
109
- }
110
- return loaded;
111
- }
112
-
113
- // Also kick off on module load so the grammars start loading as
114
- // early as possible — by the time the user clicks a code-sample tab
115
- // they've usually finished.
116
- void ensurePrismLanguages();