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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.0.37] - 2026-07-03
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **The component page is a live API reference.** The separate Controls
|
|
15
|
+
panel is gone — controls sit inside the API tables, on the row of the
|
|
16
|
+
prop or CSS custom property they drive. Props, CSS Props, Events, and
|
|
17
|
+
Snippets share a composite row layout: name (with a red `*` when
|
|
18
|
+
required), type and description stacked in the middle, an explicit
|
|
19
|
+
Default column (`—` when absent), and a fixed control rail. Reset moved
|
|
20
|
+
next to the Props title.
|
|
21
|
+
- **Sections instead of collapsible panels.** The reference sections render
|
|
22
|
+
flat with icon titles; only the preview and its code stay in the bordered
|
|
23
|
+
card (Preview Code still collapses). "State" is now "States", matching
|
|
24
|
+
the plural sibling sections. The page grew to 1120px.
|
|
25
|
+
- **Color-coded types and values.** Type chips are tinted by kind — strings
|
|
26
|
+
green, numbers and dimensions amber, booleans purple, callbacks blue,
|
|
27
|
+
snippets pink, colors cyan, `void` slate — union members render as
|
|
28
|
+
individual chips, and default/state literals are colored plain text.
|
|
29
|
+
Both themes are handled explicitly.
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **Run buttons for methods.** Zero-argument methods can be invoked
|
|
34
|
+
directly from the Methods table and act on the live preview; methods
|
|
35
|
+
with parameters show a disabled button.
|
|
36
|
+
- **Live state values.** The States table shows each exported state's
|
|
37
|
+
current value, streamed from the preview as it changes.
|
|
38
|
+
- Section icons (sliders, palette, zap, function, database) join the UI
|
|
39
|
+
icon set.
|
|
40
|
+
|
|
41
|
+
## [0.0.36] - 2026-07-03
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- **Usage code is syntax-highlighted in static builds.** The usage snippet
|
|
46
|
+
regenerates in the browser as controls change and used to be highlighted
|
|
47
|
+
through a dev-server endpoint — deployed builds fell back to plain text.
|
|
48
|
+
Highlighting now runs client-side (lazy-loaded Shiki with the JavaScript
|
|
49
|
+
regex engine), identical on the dev server and any static host; the
|
|
50
|
+
dev-server endpoint is gone.
|
|
51
|
+
|
|
10
52
|
## [0.0.35] - 2026-07-03
|
|
11
53
|
|
|
12
54
|
### Fixed
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Client-side Shiki for code that's generated in the browser (the usage
|
|
2
|
+
// snippet re-renders as controls change). Everything loads lazily on first
|
|
3
|
+
// use so the Explorer bundle stays lean, and the JavaScript regex engine
|
|
4
|
+
// avoids shipping wasm — highlighting works the same on the dev server and
|
|
5
|
+
// in static builds.
|
|
6
|
+
let highlighterPromise;
|
|
7
|
+
async function getHighlighter() {
|
|
8
|
+
highlighterPromise ??= (async () => {
|
|
9
|
+
const [{ createHighlighterCore }, { createJavaScriptRegexEngine }, { bundledLanguages }, { bundledThemes }] = await Promise.all([
|
|
10
|
+
import('shiki/core'),
|
|
11
|
+
import('shiki/engine/javascript'),
|
|
12
|
+
import('shiki/langs'),
|
|
13
|
+
import('shiki/themes'),
|
|
14
|
+
]);
|
|
15
|
+
return createHighlighterCore({
|
|
16
|
+
langs: [bundledLanguages.svelte],
|
|
17
|
+
themes: [bundledThemes['github-light'], bundledThemes['github-dark']],
|
|
18
|
+
engine: createJavaScriptRegexEngine({ forgiving: true }),
|
|
19
|
+
});
|
|
20
|
+
})();
|
|
21
|
+
return highlighterPromise;
|
|
22
|
+
}
|
|
23
|
+
/** Highlight Svelte code, matching the build-time highlighter's output shape */
|
|
24
|
+
export async function highlightSvelte(code) {
|
|
25
|
+
const highlighter = await getHighlighter();
|
|
26
|
+
return highlighter.codeToHtml(code, {
|
|
27
|
+
lang: 'svelte',
|
|
28
|
+
themes: {
|
|
29
|
+
light: 'github-light',
|
|
30
|
+
dark: 'github-dark',
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { typeClass, typeParts, valueClass } from './format.js';
|
|
4
|
+
|
|
5
|
+
interface Row {
|
|
6
|
+
name: string;
|
|
7
|
+
type?: string | null;
|
|
8
|
+
default?: string | null;
|
|
9
|
+
description?: string | null;
|
|
10
|
+
required?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface Props {
|
|
14
|
+
rows: Row[];
|
|
15
|
+
/** Renders the per-row control in the fixed right rail */
|
|
16
|
+
control?: Snippet<[Row]>;
|
|
17
|
+
/** Show the Default column (rows without defaults, e.g. events, turn it off) */
|
|
18
|
+
showDefault?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let { rows, control, showDefault = true }: Props = $props();
|
|
22
|
+
|
|
23
|
+
const gridColumns = $derived(
|
|
24
|
+
['200px', 'minmax(0, 1fr)', ...(showDefault ? ['120px'] : []), ...(control ? ['200px'] : [])].join(' '),
|
|
25
|
+
);
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
{#if rows.length > 0}
|
|
29
|
+
<div class="sdocs-api-list">
|
|
30
|
+
<div class="sdocs-api-header" style:grid-template-columns={gridColumns}>
|
|
31
|
+
<div>Name</div>
|
|
32
|
+
<div>Details</div>
|
|
33
|
+
{#if showDefault}<div>Default</div>{/if}
|
|
34
|
+
{#if control}<div>Control</div>{/if}
|
|
35
|
+
</div>
|
|
36
|
+
{#each rows as row (row.name)}
|
|
37
|
+
<div class="sdocs-api-row" style:grid-template-columns={gridColumns}>
|
|
38
|
+
<div class="sdocs-api-name">
|
|
39
|
+
{row.name}{#if row.required}<span class="sdocs-api-required" title="Required">*</span>{/if}
|
|
40
|
+
</div>
|
|
41
|
+
<div class="sdocs-api-middle">
|
|
42
|
+
{#if row.type}
|
|
43
|
+
<div class="sdocs-api-meta">
|
|
44
|
+
{#each typeParts(row.type) as part, i (i)}
|
|
45
|
+
{#if i > 0}<span class="sdocs-typesep">|</span>{/if}
|
|
46
|
+
<code class="sdocs-type-{typeClass(row.type)}">{part}</code>
|
|
47
|
+
{/each}
|
|
48
|
+
</div>
|
|
49
|
+
{/if}
|
|
50
|
+
{#if row.description}
|
|
51
|
+
<div class="sdocs-api-desc">{row.description}</div>
|
|
52
|
+
{/if}
|
|
53
|
+
</div>
|
|
54
|
+
{#if showDefault}
|
|
55
|
+
<div class="sdocs-api-default">
|
|
56
|
+
{#if row.default != null}
|
|
57
|
+
<span class="sdocs-value sdocs-value-{valueClass(row.default)}">{row.default}</span>
|
|
58
|
+
{:else}
|
|
59
|
+
<span class="sdocs-api-empty">—</span>
|
|
60
|
+
{/if}
|
|
61
|
+
</div>
|
|
62
|
+
{/if}
|
|
63
|
+
{#if control}
|
|
64
|
+
<div class="sdocs-api-control">
|
|
65
|
+
{@render control(row)}
|
|
66
|
+
</div>
|
|
67
|
+
{/if}
|
|
68
|
+
</div>
|
|
69
|
+
{/each}
|
|
70
|
+
</div>
|
|
71
|
+
{:else}
|
|
72
|
+
<p class="sdocs-api-none">None</p>
|
|
73
|
+
{/if}
|
|
74
|
+
|
|
75
|
+
<style>
|
|
76
|
+
.sdocs-api-list {
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
}
|
|
80
|
+
.sdocs-api-header {
|
|
81
|
+
display: grid;
|
|
82
|
+
grid-template-columns: 200px minmax(0, 1fr) 120px 200px;
|
|
83
|
+
gap: 20px;
|
|
84
|
+
padding: 6px 12px;
|
|
85
|
+
border-bottom: 2px solid var(--color-base-200);
|
|
86
|
+
font-size: 12px;
|
|
87
|
+
font-weight: 600;
|
|
88
|
+
color: var(--color-base-600);
|
|
89
|
+
}
|
|
90
|
+
.sdocs-api-row {
|
|
91
|
+
display: grid;
|
|
92
|
+
grid-template-columns: 200px minmax(0, 1fr) 120px 200px;
|
|
93
|
+
gap: 20px;
|
|
94
|
+
align-items: start;
|
|
95
|
+
padding: 12px 12px;
|
|
96
|
+
border-bottom: 1px solid var(--color-base-100);
|
|
97
|
+
font-size: 13px;
|
|
98
|
+
}
|
|
99
|
+
.sdocs-api-name {
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
color: var(--color-base-900);
|
|
102
|
+
overflow-wrap: break-word;
|
|
103
|
+
}
|
|
104
|
+
.sdocs-api-required {
|
|
105
|
+
color: var(--color-red-500);
|
|
106
|
+
}
|
|
107
|
+
.sdocs-api-middle {
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
gap: 8px;
|
|
111
|
+
min-width: 0;
|
|
112
|
+
}
|
|
113
|
+
.sdocs-api-meta {
|
|
114
|
+
display: flex;
|
|
115
|
+
flex-wrap: wrap;
|
|
116
|
+
align-items: baseline;
|
|
117
|
+
gap: 6px;
|
|
118
|
+
}
|
|
119
|
+
.sdocs-api-desc {
|
|
120
|
+
color: var(--color-base-500);
|
|
121
|
+
}
|
|
122
|
+
.sdocs-api-default {
|
|
123
|
+
overflow-wrap: break-word;
|
|
124
|
+
min-width: 0;
|
|
125
|
+
}
|
|
126
|
+
.sdocs-api-empty {
|
|
127
|
+
color: var(--color-base-300);
|
|
128
|
+
}
|
|
129
|
+
.sdocs-api-control {
|
|
130
|
+
min-width: 0;
|
|
131
|
+
}
|
|
132
|
+
.sdocs-api-none {
|
|
133
|
+
color: var(--color-base-400);
|
|
134
|
+
font-size: 13px;
|
|
135
|
+
font-style: italic;
|
|
136
|
+
margin: 0;
|
|
137
|
+
}
|
|
138
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
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 ApiTableProps = typeof __propDef.props;
|
|
10
|
+
export type ApiTableEvents = typeof __propDef.events;
|
|
11
|
+
export type ApiTableSlots = typeof __propDef.slots;
|
|
12
|
+
export default class ApiTable extends SvelteComponentTyped<ApiTableProps, ApiTableEvents, ApiTableSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { DocEntry } from '../../types.js';
|
|
3
3
|
import { Icon } from '../../ui/Icon/index.js';
|
|
4
|
+
import { highlightSvelte } from '../highlighter.js';
|
|
4
5
|
import CollapsiblePanel from './CollapsiblePanel.svelte';
|
|
5
6
|
import PreviewFrame from './PreviewFrame.svelte';
|
|
6
|
-
import ControlsPanel from './ControlsPanel.svelte';
|
|
7
7
|
import DataTable from './DataTable.svelte';
|
|
8
|
+
import ApiTable from './ApiTable.svelte';
|
|
9
|
+
import PropControl from './PropControl.svelte';
|
|
10
|
+
import CssPropControl from './CssPropControl.svelte';
|
|
8
11
|
|
|
9
12
|
interface Props {
|
|
10
13
|
doc: DocEntry;
|
|
@@ -31,6 +34,10 @@
|
|
|
31
34
|
let propValues = $state<Record<string, unknown>>({});
|
|
32
35
|
let cssValues = $state<Record<string, string>>({});
|
|
33
36
|
|
|
37
|
+
// Live wiring to the default preview: method invocation + exported state values
|
|
38
|
+
let defaultPreview = $state<{ callMethod: (name: string) => void }>();
|
|
39
|
+
let liveStateValues = $state<Record<string, unknown>>({});
|
|
40
|
+
|
|
34
41
|
// Initialize from meta.args (build new objects to avoid read+write loop)
|
|
35
42
|
$effect(() => {
|
|
36
43
|
propValues = { ...(meta.args ?? {}) };
|
|
@@ -169,36 +176,20 @@
|
|
|
169
176
|
return generateFallbackCode(componentName, propValues, cssValues);
|
|
170
177
|
});
|
|
171
178
|
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
//
|
|
179
|
+
// Usage code is generated in the browser, so it's highlighted client-side
|
|
180
|
+
// (lazy Shiki — see ../highlighter.ts). Debounced while controls change;
|
|
181
|
+
// stale results are dropped.
|
|
175
182
|
let highlightedUsageHtml = $state('');
|
|
176
183
|
let highlightTimer: ReturnType<typeof setTimeout> | undefined;
|
|
177
|
-
let highlightAvailable = true;
|
|
178
184
|
|
|
179
185
|
$effect(() => {
|
|
180
186
|
const code = usageCode;
|
|
181
187
|
clearTimeout(highlightTimer);
|
|
182
|
-
if (!highlightAvailable) {
|
|
183
|
-
highlightedUsageHtml = '';
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
188
|
highlightTimer = setTimeout(async () => {
|
|
187
189
|
try {
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
headers: { 'Content-Type': 'application/json' },
|
|
191
|
-
body: JSON.stringify({ code, lang: 'svelte' }),
|
|
192
|
-
});
|
|
193
|
-
if (res.ok) {
|
|
194
|
-
const { html } = await res.json();
|
|
195
|
-
highlightedUsageHtml = html;
|
|
196
|
-
} else {
|
|
197
|
-
highlightAvailable = false;
|
|
198
|
-
highlightedUsageHtml = '';
|
|
199
|
-
}
|
|
190
|
+
const html = await highlightSvelte(code);
|
|
191
|
+
if (code === usageCode) highlightedUsageHtml = html;
|
|
200
192
|
} catch {
|
|
201
|
-
highlightAvailable = false;
|
|
202
193
|
highlightedUsageHtml = '';
|
|
203
194
|
}
|
|
204
195
|
}, 150);
|
|
@@ -215,13 +206,17 @@
|
|
|
215
206
|
cssValues = newCss;
|
|
216
207
|
}
|
|
217
208
|
|
|
209
|
+
const hasEditableControls = $derived(
|
|
210
|
+
!!cd && (cd.props.some((p) => p.category === 'prop') || cd.cssProps.length > 0),
|
|
211
|
+
);
|
|
212
|
+
|
|
218
213
|
// Table data builders
|
|
219
214
|
const propsRows = $derived(
|
|
220
215
|
(cd?.props ?? []).filter((p) => p.category === 'prop').map((p) => ({
|
|
221
216
|
name: p.name,
|
|
222
217
|
type: p.type,
|
|
223
218
|
default: p.default,
|
|
224
|
-
required: p.required
|
|
219
|
+
required: p.required,
|
|
225
220
|
description: p.description,
|
|
226
221
|
})),
|
|
227
222
|
);
|
|
@@ -262,6 +257,7 @@
|
|
|
262
257
|
|
|
263
258
|
const stateRows = $derived(
|
|
264
259
|
(cd?.state ?? []).map((s) => ({
|
|
260
|
+
value: s.name in liveStateValues ? JSON.stringify(liveStateValues[s.name]) : undefined,
|
|
265
261
|
name: s.name,
|
|
266
262
|
type: s.type,
|
|
267
263
|
description: s.description,
|
|
@@ -297,10 +293,12 @@
|
|
|
297
293
|
{#if defaultSnippet}
|
|
298
294
|
<div class="sdocs-preview-wrapper">
|
|
299
295
|
<PreviewFrame
|
|
296
|
+
bind:this={defaultPreview}
|
|
300
297
|
src={defaultSnippet.previewUrl ?? ''}
|
|
301
298
|
props={propValues}
|
|
302
299
|
cssVars={cssValues}
|
|
303
300
|
{activeStylesheet}
|
|
301
|
+
onStateValues={(values) => (liveStateValues = values)}
|
|
304
302
|
/>
|
|
305
303
|
</div>
|
|
306
304
|
|
|
@@ -314,92 +312,101 @@
|
|
|
314
312
|
</div>
|
|
315
313
|
</CollapsiblePanel>
|
|
316
314
|
{/if}
|
|
315
|
+
</div>
|
|
317
316
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
cssProps={cd.cssProps}
|
|
323
|
-
{propValues}
|
|
324
|
-
{cssValues}
|
|
325
|
-
onPropChange={handlePropChange}
|
|
326
|
-
onCssChange={handleCssChange}
|
|
327
|
-
onReset={handleReset}
|
|
328
|
-
/>
|
|
329
|
-
</CollapsiblePanel>
|
|
317
|
+
{#snippet propControl(row: Record<string, unknown>)}
|
|
318
|
+
{@const prop = cd?.props.find((p) => p.name === row.name && p.category === 'prop')}
|
|
319
|
+
{#if prop}
|
|
320
|
+
<PropControl {prop} value={propValues[prop.name]} onchange={(v) => handlePropChange(prop.name, v)} />
|
|
330
321
|
{/if}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
/>
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
/>
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
<
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
</
|
|
322
|
+
{/snippet}
|
|
323
|
+
|
|
324
|
+
{#snippet methodControl(row: Record<string, unknown>)}
|
|
325
|
+
{@const hasParams = String(row.params ?? '').trim().length > 0}
|
|
326
|
+
<button
|
|
327
|
+
class="sdocs-run-btn"
|
|
328
|
+
disabled={hasParams || !defaultPreview}
|
|
329
|
+
title={hasParams ? 'Only methods without parameters can be run here' : `Run ${row.name}() on the preview`}
|
|
330
|
+
onclick={() => defaultPreview?.callMethod(String(row.name))}
|
|
331
|
+
>
|
|
332
|
+
Run
|
|
333
|
+
</button>
|
|
334
|
+
{/snippet}
|
|
335
|
+
|
|
336
|
+
{#snippet cssPropControl(row: Record<string, unknown>)}
|
|
337
|
+
{@const cssProp = cd?.cssProps.find((p) => p.name === row.name)}
|
|
338
|
+
{#if cssProp}
|
|
339
|
+
<CssPropControl {cssProp} value={cssValues[cssProp.name]} onchange={(v) => handleCssChange(cssProp.name, v)} />
|
|
340
|
+
{/if}
|
|
341
|
+
{/snippet}
|
|
342
|
+
|
|
343
|
+
<section class="sdocs-doc-section">
|
|
344
|
+
<h2 class="sdocs-doc-section-title">
|
|
345
|
+
<Icon name="sliders-horizontal" --w="15px" --h="15px" --fill="var(--color-base-500)" />
|
|
346
|
+
Props
|
|
347
|
+
{#if hasEditableControls}
|
|
348
|
+
<button class="sdocs-reset-btn" onclick={handleReset}>Reset</button>
|
|
349
|
+
{/if}
|
|
350
|
+
</h2>
|
|
351
|
+
<ApiTable rows={propsRows} control={propControl} />
|
|
352
|
+
</section>
|
|
353
|
+
|
|
354
|
+
<section class="sdocs-doc-section">
|
|
355
|
+
<h2 class="sdocs-doc-section-title">
|
|
356
|
+
<Icon name="palette" --w="15px" --h="15px" --fill="var(--color-base-500)" />
|
|
357
|
+
CSS Props
|
|
358
|
+
</h2>
|
|
359
|
+
<ApiTable rows={cssPropsRows} control={cssPropControl} />
|
|
360
|
+
</section>
|
|
361
|
+
|
|
362
|
+
<section class="sdocs-doc-section">
|
|
363
|
+
<h2 class="sdocs-doc-section-title">
|
|
364
|
+
<Icon name="zap" --w="15px" --h="15px" --fill="var(--color-base-500)" />
|
|
365
|
+
Events
|
|
366
|
+
</h2>
|
|
367
|
+
<ApiTable rows={eventsRows} showDefault={false} />
|
|
368
|
+
</section>
|
|
369
|
+
|
|
370
|
+
<section class="sdocs-doc-section">
|
|
371
|
+
<h2 class="sdocs-doc-section-title">
|
|
372
|
+
<Icon name="code" --w="15px" --h="15px" --fill="var(--color-base-500)" />
|
|
373
|
+
Snippets
|
|
374
|
+
</h2>
|
|
375
|
+
<ApiTable rows={snippetsRows} showDefault={false} />
|
|
376
|
+
</section>
|
|
377
|
+
|
|
378
|
+
<section class="sdocs-doc-section">
|
|
379
|
+
<h2 class="sdocs-doc-section-title">
|
|
380
|
+
<Icon name="square-function" --w="15px" --h="15px" --fill="var(--color-base-500)" />
|
|
381
|
+
Methods
|
|
382
|
+
</h2>
|
|
383
|
+
<DataTable
|
|
384
|
+
columns={[
|
|
385
|
+
{ key: 'name', label: 'Name', kind: 'name' },
|
|
386
|
+
{ key: 'params', label: 'Parameters' },
|
|
387
|
+
{ key: 'returns', label: 'Returns', kind: 'type' },
|
|
388
|
+
{ key: 'description', label: 'Description', kind: 'text' },
|
|
389
|
+
]}
|
|
390
|
+
rows={methodsRows}
|
|
391
|
+
control={methodsRows.length > 0 ? methodControl : undefined}
|
|
392
|
+
/>
|
|
393
|
+
</section>
|
|
394
|
+
|
|
395
|
+
<section class="sdocs-doc-section">
|
|
396
|
+
<h2 class="sdocs-doc-section-title">
|
|
397
|
+
<Icon name="database" --w="15px" --h="15px" --fill="var(--color-base-500)" />
|
|
398
|
+
States
|
|
399
|
+
</h2>
|
|
400
|
+
<DataTable
|
|
401
|
+
columns={[
|
|
402
|
+
{ key: 'name', label: 'Name', kind: 'name' },
|
|
403
|
+
{ key: 'type', label: 'Type', kind: 'type' },
|
|
404
|
+
{ key: 'value', label: 'Current value', kind: 'value' },
|
|
405
|
+
{ key: 'description', label: 'Description', kind: 'text' },
|
|
406
|
+
]}
|
|
407
|
+
rows={stateRows}
|
|
408
|
+
/>
|
|
409
|
+
</section>
|
|
403
410
|
|
|
404
411
|
{#if exampleSnippets.length > 0}
|
|
405
412
|
<hr class="sdocs-divider" />
|
|
@@ -436,9 +443,54 @@
|
|
|
436
443
|
<style>
|
|
437
444
|
.sdocs-component-view {
|
|
438
445
|
padding: 24px 32px;
|
|
439
|
-
max-width:
|
|
446
|
+
max-width: 1120px;
|
|
440
447
|
font-family: var(--sans);
|
|
441
448
|
}
|
|
449
|
+
.sdocs-doc-section {
|
|
450
|
+
margin-top: 28px;
|
|
451
|
+
}
|
|
452
|
+
.sdocs-doc-section-title {
|
|
453
|
+
display: flex;
|
|
454
|
+
align-items: center;
|
|
455
|
+
gap: 8px;
|
|
456
|
+
margin: 0 0 10px;
|
|
457
|
+
font-size: 14px;
|
|
458
|
+
font-weight: 600;
|
|
459
|
+
color: var(--color-base-800);
|
|
460
|
+
}
|
|
461
|
+
.sdocs-doc-section-title .sdocs-reset-btn {
|
|
462
|
+
margin-left: auto;
|
|
463
|
+
}
|
|
464
|
+
.sdocs-reset-btn {
|
|
465
|
+
padding: 4px 12px;
|
|
466
|
+
border: 1px solid var(--color-base-200);
|
|
467
|
+
border-radius: 4px;
|
|
468
|
+
background: var(--color-base-0);
|
|
469
|
+
font: inherit;
|
|
470
|
+
font-size: 12px;
|
|
471
|
+
color: var(--color-base-600);
|
|
472
|
+
cursor: pointer;
|
|
473
|
+
}
|
|
474
|
+
.sdocs-reset-btn:hover {
|
|
475
|
+
background: var(--color-base-100);
|
|
476
|
+
}
|
|
477
|
+
.sdocs-run-btn {
|
|
478
|
+
padding: 3px 12px;
|
|
479
|
+
border: 1px solid var(--color-base-200);
|
|
480
|
+
border-radius: 4px;
|
|
481
|
+
background: var(--color-base-0);
|
|
482
|
+
font: inherit;
|
|
483
|
+
font-size: 12px;
|
|
484
|
+
color: var(--color-base-600);
|
|
485
|
+
cursor: pointer;
|
|
486
|
+
}
|
|
487
|
+
.sdocs-run-btn:hover:not(:disabled) {
|
|
488
|
+
background: var(--color-base-100);
|
|
489
|
+
}
|
|
490
|
+
.sdocs-run-btn:disabled {
|
|
491
|
+
opacity: 0.4;
|
|
492
|
+
cursor: default;
|
|
493
|
+
}
|
|
442
494
|
.sdocs-view-header {
|
|
443
495
|
margin-bottom: 24px;
|
|
444
496
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ParsedCssProp } from '../../types.js';
|
|
3
|
+
import { Text as TextControl, Color as ColorControl, Dimension as DimensionControl } from '../../ui/Control/index.js';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
cssProp: ParsedCssProp;
|
|
7
|
+
value: string | undefined;
|
|
8
|
+
onchange: (value: string) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { cssProp, value, onchange }: Props = $props();
|
|
12
|
+
|
|
13
|
+
const controlType = $derived.by(() => {
|
|
14
|
+
const t = cssProp.type?.toLowerCase() ?? '';
|
|
15
|
+
if (t === 'color') return 'color';
|
|
16
|
+
if (t === 'dimension') return 'dimension';
|
|
17
|
+
return 'text';
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
{#if controlType === 'color'}
|
|
22
|
+
<ColorControl value={value ?? cssProp.default ?? '#000000'} {onchange} />
|
|
23
|
+
{:else if controlType === 'dimension'}
|
|
24
|
+
<DimensionControl value={value ?? cssProp.default ?? '0px'} {onchange} />
|
|
25
|
+
{:else}
|
|
26
|
+
<TextControl value={value ?? cssProp.default ?? ''} {onchange} />
|
|
27
|
+
{/if}
|
|
@@ -0,0 +1,14 @@
|
|
|
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 CssPropControlProps = typeof __propDef.props;
|
|
10
|
+
export type CssPropControlEvents = typeof __propDef.events;
|
|
11
|
+
export type CssPropControlSlots = typeof __propDef.slots;
|
|
12
|
+
export default class CssPropControl extends SvelteComponentTyped<CssPropControlProps, CssPropControlEvents, CssPropControlSlots> {
|
|
13
|
+
}
|
|
14
|
+
export {};
|