sdocs 0.0.35 → 0.0.37
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/CHANGELOG.md +42 -0
- package/dist/explorer/highlighter.d.ts +2 -0
- package/dist/explorer/highlighter.js +33 -0
- package/dist/explorer/views/ApiTable.svelte +138 -0
- package/dist/explorer/views/ApiTable.svelte.d.ts +14 -0
- package/dist/explorer/views/ComponentView.svelte +160 -108
- package/dist/explorer/views/CssPropControl.svelte +27 -0
- package/dist/explorer/views/CssPropControl.svelte.d.ts +14 -0
- package/dist/explorer/views/DataTable.svelte +46 -4
- package/dist/explorer/views/PreviewFrame.svelte +11 -1
- package/dist/explorer/views/PreviewFrame.svelte.d.ts +4 -1
- package/dist/explorer/views/PropControl.svelte +69 -0
- package/dist/explorer/views/PropControl.svelte.d.ts +14 -0
- package/dist/explorer/views/format.d.ts +6 -0
- package/dist/explorer/views/format.js +44 -0
- package/dist/server/snippet-compiler.d.ts +3 -2
- package/dist/server/snippet-compiler.js +36 -4
- package/dist/ui/Control/Checkbox.svelte +6 -3
- package/dist/ui/Control/Color.svelte +6 -3
- package/dist/ui/Control/Dimension.svelte +8 -4
- package/dist/ui/Control/Number.svelte +6 -4
- package/dist/ui/Control/Select.svelte +6 -4
- package/dist/ui/Control/Text.svelte +6 -3
- package/dist/ui/Icon/Icon.svelte +10 -0
- package/dist/ui/Icon/icons/database.svg +5 -0
- package/dist/ui/Icon/icons/palette.svg +7 -0
- package/dist/ui/Icon/icons/sliders-horizontal.svg +11 -0
- package/dist/ui/Icon/icons/square-function.svg +5 -0
- package/dist/ui/Icon/icons/zap.svg +3 -0
- package/dist/ui/styles/sdocs.css +49 -0
- package/dist/vite.js +2 -20
- package/package.json +1 -1
- package/dist/explorer/views/ControlsPanel.svelte +0 -186
- package/dist/explorer/views/ControlsPanel.svelte.d.ts +0 -14
package/dist/ui/styles/sdocs.css
CHANGED
|
@@ -28,6 +28,55 @@
|
|
|
28
28
|
text-decoration: none;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/* Type chips and value literals, color-coded by kind (shared by doc tables) */
|
|
32
|
+
.sdocs-app code[class*='sdocs-type-'] {
|
|
33
|
+
font-family: var(--mono);
|
|
34
|
+
font-size: 12px;
|
|
35
|
+
padding: 1px 4px;
|
|
36
|
+
border-radius: 3px;
|
|
37
|
+
}
|
|
38
|
+
.sdocs-app code.sdocs-type-string { color: var(--color-green-700); background: var(--color-green-100); }
|
|
39
|
+
.sdocs-app code.sdocs-type-number { color: var(--color-amber-700); background: var(--color-amber-100); }
|
|
40
|
+
.sdocs-app code.sdocs-type-boolean { color: var(--color-purple-700); background: var(--color-purple-100); }
|
|
41
|
+
.sdocs-app code.sdocs-type-function { color: var(--color-blue-700); background: var(--color-blue-100); }
|
|
42
|
+
.sdocs-app code.sdocs-type-snippet { color: var(--color-pink-700); background: var(--color-pink-100); }
|
|
43
|
+
.sdocs-app code.sdocs-type-color { color: var(--color-cyan-700); background: var(--color-cyan-100); }
|
|
44
|
+
.sdocs-app code.sdocs-type-dimension { color: var(--color-amber-700); background: var(--color-amber-100); }
|
|
45
|
+
.sdocs-app code.sdocs-type-void { color: var(--color-slate-500); background: var(--color-slate-100); }
|
|
46
|
+
.sdocs-app code.sdocs-type-other { color: var(--color-base-700); background: var(--color-base-100); }
|
|
47
|
+
|
|
48
|
+
.sdocs-app .sdocs-typesep {
|
|
49
|
+
font-family: var(--mono);
|
|
50
|
+
font-size: 12px;
|
|
51
|
+
color: var(--color-base-300);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.sdocs-app .sdocs-value {
|
|
55
|
+
font-family: var(--mono);
|
|
56
|
+
font-size: 12px;
|
|
57
|
+
}
|
|
58
|
+
.sdocs-app .sdocs-value-string { color: var(--color-green-700); }
|
|
59
|
+
.sdocs-app .sdocs-value-number { color: var(--color-amber-700); }
|
|
60
|
+
.sdocs-app .sdocs-value-boolean { color: var(--color-purple-700); }
|
|
61
|
+
.sdocs-app .sdocs-value-dimension { color: var(--color-amber-700); }
|
|
62
|
+
.sdocs-app .sdocs-value-color { color: var(--color-cyan-700); }
|
|
63
|
+
.sdocs-app .sdocs-value-other { color: var(--color-base-600); }
|
|
64
|
+
|
|
65
|
+
/* Raw hue tokens don't invert with the theme; flip shades for dark */
|
|
66
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-string { color: var(--color-green-400); background: var(--color-green-950); }
|
|
67
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-number { color: var(--color-amber-400); background: var(--color-amber-950); }
|
|
68
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-boolean { color: var(--color-purple-400); background: var(--color-purple-950); }
|
|
69
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-function { color: var(--color-blue-400); background: var(--color-blue-950); }
|
|
70
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-snippet { color: var(--color-pink-400); background: var(--color-pink-950); }
|
|
71
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-color { color: var(--color-cyan-400); background: var(--color-cyan-950); }
|
|
72
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-dimension { color: var(--color-amber-400); background: var(--color-amber-950); }
|
|
73
|
+
.sdocs-app[data-sdocs-theme='dark'] code.sdocs-type-void { color: var(--color-slate-400); background: var(--color-slate-950); }
|
|
74
|
+
.sdocs-app[data-sdocs-theme='dark'] .sdocs-value-string { color: var(--color-green-400); }
|
|
75
|
+
.sdocs-app[data-sdocs-theme='dark'] .sdocs-value-number { color: var(--color-amber-400); }
|
|
76
|
+
.sdocs-app[data-sdocs-theme='dark'] .sdocs-value-boolean { color: var(--color-purple-400); }
|
|
77
|
+
.sdocs-app[data-sdocs-theme='dark'] .sdocs-value-dimension { color: var(--color-amber-400); }
|
|
78
|
+
.sdocs-app[data-sdocs-theme='dark'] .sdocs-value-color { color: var(--color-cyan-400); }
|
|
79
|
+
|
|
31
80
|
.sdocs-app[data-sdocs-theme='dark'] {
|
|
32
81
|
/* base — layouts, backgrounds, surfaces, borders, text (inverted) */
|
|
33
82
|
--color-base-0: var(--color-zinc-1000);
|
package/dist/vite.js
CHANGED
|
@@ -72,25 +72,6 @@ export function sdocsPlugin(userConfig) {
|
|
|
72
72
|
res.end('Internal error');
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
|
-
// API: highlight code on demand
|
|
76
|
-
server.middlewares.use((req, res, next) => {
|
|
77
|
-
if (req.url !== '/__sdocs/highlight' || req.method !== 'POST')
|
|
78
|
-
return next();
|
|
79
|
-
let body = '';
|
|
80
|
-
req.on('data', (chunk) => { body += chunk; });
|
|
81
|
-
req.on('end', async () => {
|
|
82
|
-
try {
|
|
83
|
-
const { code, lang } = JSON.parse(body);
|
|
84
|
-
const html = await highlight(code, lang);
|
|
85
|
-
res.setHeader('Content-Type', 'application/json');
|
|
86
|
-
res.end(JSON.stringify({ html }));
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
res.statusCode = 400;
|
|
90
|
-
res.end('Invalid request');
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
75
|
// Watch for .sdoc file add/unlink/change
|
|
95
76
|
server.watcher.on('add', async (filePath) => {
|
|
96
77
|
if (isDocFile(filePath)) {
|
|
@@ -235,7 +216,8 @@ export function sdocsPlugin(userConfig) {
|
|
|
235
216
|
if (!snippet)
|
|
236
217
|
return null;
|
|
237
218
|
const absoluteImports = docImportsCache.get(parsed.docFilePath) ?? [];
|
|
238
|
-
|
|
219
|
+
const stateNames = (entry.componentData?.state ?? []).map((s) => s.name);
|
|
220
|
+
return generateIframeComponent(absoluteImports, snippet.body, stateNames);
|
|
239
221
|
}
|
|
240
222
|
// Virtual mount script for an emitted preview page
|
|
241
223
|
if (id.startsWith('\0' + MOUNT_PREFIX)) {
|
package/package.json
CHANGED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { ParsedProp, ParsedCssProp } from '../../types.js';
|
|
3
|
-
import { Text as TextControl, Number as NumberControl, Checkbox as CheckboxControl, Color as ColorControl, Dimension as DimensionControl, Select as SelectControl } from '../../ui/Control/index.js';
|
|
4
|
-
|
|
5
|
-
interface Props {
|
|
6
|
-
componentProps: ParsedProp[];
|
|
7
|
-
cssProps: ParsedCssProp[];
|
|
8
|
-
propValues: Record<string, unknown>;
|
|
9
|
-
cssValues: Record<string, string>;
|
|
10
|
-
onPropChange: (name: string, value: unknown) => void;
|
|
11
|
-
onCssChange: (name: string, value: string) => void;
|
|
12
|
-
onReset: () => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let { componentProps, cssProps, propValues, cssValues, onPropChange, onCssChange, onReset }: Props = $props();
|
|
16
|
-
|
|
17
|
-
// Only show controls for regular props (not events or snippets)
|
|
18
|
-
const editableProps = $derived(componentProps.filter((p) => p.category === 'prop'));
|
|
19
|
-
|
|
20
|
-
/** Parse union type strings like "'sm' | 'md' | 'lg'" or "1 | 2 | 3" into option arrays */
|
|
21
|
-
function parseUnionOptions(type: string | null): string[] | null {
|
|
22
|
-
if (!type || !type.includes('|')) return null;
|
|
23
|
-
const parts = type.split('|').map((s) => s.trim());
|
|
24
|
-
const values: string[] = [];
|
|
25
|
-
let allStrings = true;
|
|
26
|
-
let allNumbers = true;
|
|
27
|
-
for (const part of parts) {
|
|
28
|
-
// Quoted string: 'value' or "value"
|
|
29
|
-
const strMatch = part.match(/^['"](.+)['"]$/);
|
|
30
|
-
if (strMatch) {
|
|
31
|
-
values.push(strMatch[1]);
|
|
32
|
-
allNumbers = false;
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
// Bare number: 1, 2, 3
|
|
36
|
-
if (/^\d+(\.\d+)?$/.test(part)) {
|
|
37
|
-
values.push(part);
|
|
38
|
-
allStrings = false;
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
// Mixed or unsupported (e.g. 'medium' | number) → null
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
if (values.length > 0 && (allStrings || allNumbers)) return values;
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function getControlType(prop: ParsedProp): 'text' | 'number' | 'boolean' | 'select' | 'readonly' {
|
|
49
|
-
const t = prop.type?.toLowerCase() ?? '';
|
|
50
|
-
if (t === 'string') return 'text';
|
|
51
|
-
if (t === 'number') return 'number';
|
|
52
|
-
if (t === 'boolean') return 'boolean';
|
|
53
|
-
if (parseUnionOptions(prop.type)) return 'select';
|
|
54
|
-
return 'readonly';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function getCssControlType(cssProp: ParsedCssProp): 'color' | 'dimension' | 'text' {
|
|
58
|
-
const t = cssProp.type?.toLowerCase() ?? '';
|
|
59
|
-
if (t === 'color') return 'color';
|
|
60
|
-
if (t === 'dimension') return 'dimension';
|
|
61
|
-
return 'text';
|
|
62
|
-
}
|
|
63
|
-
</script>
|
|
64
|
-
|
|
65
|
-
<div class="sdocs-controls">
|
|
66
|
-
{#if editableProps.length > 0}
|
|
67
|
-
<div class="sdocs-controls-section">
|
|
68
|
-
<div class="sdocs-controls-section-title">Props</div>
|
|
69
|
-
{#each editableProps as prop (prop.name)}
|
|
70
|
-
{@const controlType = getControlType(prop)}
|
|
71
|
-
{#if controlType === 'text'}
|
|
72
|
-
<TextControl
|
|
73
|
-
label={prop.name}
|
|
74
|
-
value={String(propValues[prop.name] ?? prop.default ?? '')}
|
|
75
|
-
onchange={(v) => onPropChange(prop.name, v)}
|
|
76
|
-
/>
|
|
77
|
-
{:else if controlType === 'number'}
|
|
78
|
-
<NumberControl
|
|
79
|
-
label={prop.name}
|
|
80
|
-
value={Number(propValues[prop.name] ?? prop.default ?? 0)}
|
|
81
|
-
onchange={(v) => onPropChange(prop.name, v)}
|
|
82
|
-
/>
|
|
83
|
-
{:else if controlType === 'boolean'}
|
|
84
|
-
<CheckboxControl
|
|
85
|
-
label={prop.name}
|
|
86
|
-
value={Boolean(propValues[prop.name] ?? (prop.default === 'true'))}
|
|
87
|
-
onchange={(v) => onPropChange(prop.name, v)}
|
|
88
|
-
/>
|
|
89
|
-
{:else if controlType === 'select'}
|
|
90
|
-
{@const options = parseUnionOptions(prop.type) ?? []}
|
|
91
|
-
<SelectControl
|
|
92
|
-
label={prop.name}
|
|
93
|
-
value={String(propValues[prop.name] ?? prop.default ?? options[0] ?? '')}
|
|
94
|
-
{options}
|
|
95
|
-
onchange={(v) => onPropChange(prop.name, v)}
|
|
96
|
-
/>
|
|
97
|
-
{:else}
|
|
98
|
-
<div class="sdocs-control-readonly">
|
|
99
|
-
<span class="sdocs-control-label">{prop.name}</span>
|
|
100
|
-
<span class="sdocs-control-type">{prop.type ?? 'unknown'}</span>
|
|
101
|
-
</div>
|
|
102
|
-
{/if}
|
|
103
|
-
{/each}
|
|
104
|
-
</div>
|
|
105
|
-
{/if}
|
|
106
|
-
|
|
107
|
-
{#if cssProps.length > 0}
|
|
108
|
-
<div class="sdocs-controls-section">
|
|
109
|
-
<div class="sdocs-controls-section-title">CSS Custom Properties</div>
|
|
110
|
-
{#each cssProps as cssProp (cssProp.name)}
|
|
111
|
-
{@const cssType = getCssControlType(cssProp)}
|
|
112
|
-
{#if cssType === 'color'}
|
|
113
|
-
<ColorControl
|
|
114
|
-
label={cssProp.name}
|
|
115
|
-
value={cssValues[cssProp.name] ?? cssProp.default ?? '#000000'}
|
|
116
|
-
onchange={(v) => onCssChange(cssProp.name, v)}
|
|
117
|
-
/>
|
|
118
|
-
{:else if cssType === 'dimension'}
|
|
119
|
-
<DimensionControl
|
|
120
|
-
label={cssProp.name}
|
|
121
|
-
value={cssValues[cssProp.name] ?? cssProp.default ?? '0px'}
|
|
122
|
-
onchange={(v) => onCssChange(cssProp.name, v)}
|
|
123
|
-
/>
|
|
124
|
-
{:else}
|
|
125
|
-
<TextControl
|
|
126
|
-
label={cssProp.name}
|
|
127
|
-
value={cssValues[cssProp.name] ?? cssProp.default ?? ''}
|
|
128
|
-
onchange={(v) => onCssChange(cssProp.name, v)}
|
|
129
|
-
/>
|
|
130
|
-
{/if}
|
|
131
|
-
{/each}
|
|
132
|
-
</div>
|
|
133
|
-
{/if}
|
|
134
|
-
|
|
135
|
-
<button class="sdocs-reset-btn" onclick={onReset}>Reset</button>
|
|
136
|
-
</div>
|
|
137
|
-
|
|
138
|
-
<style>
|
|
139
|
-
.sdocs-controls {
|
|
140
|
-
display: flex;
|
|
141
|
-
flex-direction: column;
|
|
142
|
-
gap: 12px;
|
|
143
|
-
}
|
|
144
|
-
.sdocs-controls-section {
|
|
145
|
-
display: flex;
|
|
146
|
-
flex-direction: column;
|
|
147
|
-
gap: 8px;
|
|
148
|
-
}
|
|
149
|
-
.sdocs-controls-section-title {
|
|
150
|
-
font-size: 11px;
|
|
151
|
-
font-weight: 600;
|
|
152
|
-
color: var(--color-base-400);
|
|
153
|
-
text-transform: uppercase;
|
|
154
|
-
letter-spacing: 0.05em;
|
|
155
|
-
}
|
|
156
|
-
.sdocs-control-readonly {
|
|
157
|
-
display: flex;
|
|
158
|
-
align-items: center;
|
|
159
|
-
gap: 8px;
|
|
160
|
-
font-size: 13px;
|
|
161
|
-
}
|
|
162
|
-
.sdocs-control-label {
|
|
163
|
-
min-width: 100px;
|
|
164
|
-
color: var(--color-base-600);
|
|
165
|
-
font-weight: 500;
|
|
166
|
-
}
|
|
167
|
-
.sdocs-control-type {
|
|
168
|
-
color: var(--color-base-400);
|
|
169
|
-
font-family: var(--mono);
|
|
170
|
-
font-size: 12px;
|
|
171
|
-
}
|
|
172
|
-
.sdocs-reset-btn {
|
|
173
|
-
align-self: flex-start;
|
|
174
|
-
padding: 4px 12px;
|
|
175
|
-
border: 1px solid var(--color-base-200);
|
|
176
|
-
border-radius: 4px;
|
|
177
|
-
background: var(--color-base-0);
|
|
178
|
-
font: inherit;
|
|
179
|
-
font-size: 12px;
|
|
180
|
-
color: var(--color-base-600);
|
|
181
|
-
cursor: pointer;
|
|
182
|
-
}
|
|
183
|
-
.sdocs-reset-btn:hover {
|
|
184
|
-
background: var(--color-base-100);
|
|
185
|
-
}
|
|
186
|
-
</style>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
declare const __propDef: {
|
|
3
|
-
props: Record<string, never>;
|
|
4
|
-
events: {
|
|
5
|
-
[evt: string]: CustomEvent<any>;
|
|
6
|
-
};
|
|
7
|
-
slots: {};
|
|
8
|
-
};
|
|
9
|
-
export type ControlsPanelProps = typeof __propDef.props;
|
|
10
|
-
export type ControlsPanelEvents = typeof __propDef.events;
|
|
11
|
-
export type ControlsPanelSlots = typeof __propDef.slots;
|
|
12
|
-
export default class ControlsPanel extends SvelteComponentTyped<ControlsPanelProps, ControlsPanelEvents, ControlsPanelSlots> {
|
|
13
|
-
}
|
|
14
|
-
export {};
|