@pure-ds/storybook 0.1.0
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/.storybook/addons/description/preview.js +15 -0
- package/.storybook/addons/description/register.js +60 -0
- package/.storybook/addons/html-preview/Panel.jsx +327 -0
- package/.storybook/addons/html-preview/constants.js +6 -0
- package/.storybook/addons/html-preview/preview.js +178 -0
- package/.storybook/addons/html-preview/register.js +16 -0
- package/.storybook/addons/pds-configurator/SearchTool.js +44 -0
- package/.storybook/addons/pds-configurator/Tool.js +30 -0
- package/.storybook/addons/pds-configurator/constants.js +9 -0
- package/.storybook/addons/pds-configurator/preview.js +159 -0
- package/.storybook/addons/pds-configurator/register.js +24 -0
- package/.storybook/docs.css +35 -0
- package/.storybook/htmlPreview.css +103 -0
- package/.storybook/htmlPreview.js +271 -0
- package/.storybook/main.js +160 -0
- package/.storybook/preview-body.html +48 -0
- package/.storybook/preview-head.html +11 -0
- package/.storybook/preview.js +1563 -0
- package/README.md +266 -0
- package/bin/index.js +40 -0
- package/dist/pds-reference.json +2101 -0
- package/package.json +45 -0
- package/pds.config.js +6 -0
- package/public/assets/css/app.css +1216 -0
- package/public/assets/data/auto-design-advanced.json +704 -0
- package/public/assets/data/auto-design-simple.json +123 -0
- package/public/assets/img/icon-512x512.png +0 -0
- package/public/assets/img/logo-trans.png +0 -0
- package/public/assets/img/logo.png +0 -0
- package/public/assets/js/app.js +15088 -0
- package/public/assets/js/app.js.map +7 -0
- package/public/assets/js/lit.js +1176 -0
- package/public/assets/js/lit.js.map +7 -0
- package/public/assets/js/pds.js +9801 -0
- package/public/assets/js/pds.js.map +7 -0
- package/public/assets/pds/components/pds-calendar.js +837 -0
- package/public/assets/pds/components/pds-drawer.js +857 -0
- package/public/assets/pds/components/pds-icon.js +338 -0
- package/public/assets/pds/components/pds-jsonform.js +1775 -0
- package/public/assets/pds/components/pds-richtext.js +1035 -0
- package/public/assets/pds/components/pds-scrollrow.js +331 -0
- package/public/assets/pds/components/pds-splitpanel.js +401 -0
- package/public/assets/pds/components/pds-tabstrip.js +251 -0
- package/public/assets/pds/components/pds-toaster.js +446 -0
- package/public/assets/pds/components/pds-upload.js +657 -0
- package/public/assets/pds/custom-elements.json +2003 -0
- package/public/assets/pds/icons/pds-icons.svg +498 -0
- package/public/assets/pds/pds-css-complete.json +1861 -0
- package/public/assets/pds/pds-runtime-config.json +11 -0
- package/public/assets/pds/pds.css-data.json +2152 -0
- package/public/assets/pds/styles/pds-components.css +1944 -0
- package/public/assets/pds/styles/pds-components.css.js +3895 -0
- package/public/assets/pds/styles/pds-primitives.css +352 -0
- package/public/assets/pds/styles/pds-primitives.css.js +711 -0
- package/public/assets/pds/styles/pds-styles.css +3761 -0
- package/public/assets/pds/styles/pds-styles.css.js +7529 -0
- package/public/assets/pds/styles/pds-tokens.css +699 -0
- package/public/assets/pds/styles/pds-tokens.css.js +1405 -0
- package/public/assets/pds/styles/pds-utilities.css +763 -0
- package/public/assets/pds/styles/pds-utilities.css.js +1533 -0
- package/public/assets/pds/vscode-custom-data.json +824 -0
- package/scripts/build-pds-reference.mjs +807 -0
- package/scripts/generate-stories.js +542 -0
- package/scripts/package-build.js +86 -0
- package/src/js/app.js +17 -0
- package/src/js/common/ask.js +208 -0
- package/src/js/common/common.js +20 -0
- package/src/js/common/font-loader.js +200 -0
- package/src/js/common/msg.js +90 -0
- package/src/js/lit.js +40 -0
- package/src/js/pds-core/pds-config.js +1162 -0
- package/src/js/pds-core/pds-enhancer-metadata.js +75 -0
- package/src/js/pds-core/pds-enhancers.js +357 -0
- package/src/js/pds-core/pds-enums.js +86 -0
- package/src/js/pds-core/pds-generator.js +5317 -0
- package/src/js/pds-core/pds-ontology.js +256 -0
- package/src/js/pds-core/pds-paths.js +109 -0
- package/src/js/pds-core/pds-query.js +571 -0
- package/src/js/pds-core/pds-registry.js +129 -0
- package/src/js/pds-core/pds.d.ts +129 -0
- package/src/js/pds.d.ts +408 -0
- package/src/js/pds.js +1579 -0
- package/src/pds-core/pds-api.js +105 -0
- package/stories/GettingStarted.md +96 -0
- package/stories/GettingStarted.stories.js +144 -0
- package/stories/WhatIsPDS.md +194 -0
- package/stories/WhatIsPDS.stories.js +144 -0
- package/stories/components/PdsCalendar.stories.js +263 -0
- package/stories/components/PdsDrawer.stories.js +623 -0
- package/stories/components/PdsIcon.stories.js +78 -0
- package/stories/components/PdsJsonform.stories.js +1444 -0
- package/stories/components/PdsRichtext.stories.js +367 -0
- package/stories/components/PdsScrollrow.stories.js +140 -0
- package/stories/components/PdsSplitpanel.stories.js +502 -0
- package/stories/components/PdsTabstrip.stories.js +442 -0
- package/stories/components/PdsToaster.stories.js +186 -0
- package/stories/components/PdsUpload.stories.js +66 -0
- package/stories/enhancements/Dropdowns.stories.js +185 -0
- package/stories/enhancements/InteractiveStates.stories.js +625 -0
- package/stories/enhancements/MeshGradients.stories.js +320 -0
- package/stories/enhancements/OpenGroups.stories.js +227 -0
- package/stories/enhancements/RangeSliders.stories.js +232 -0
- package/stories/enhancements/RequiredFields.stories.js +189 -0
- package/stories/enhancements/Toggles.stories.js +167 -0
- package/stories/foundations/Colors.stories.js +283 -0
- package/stories/foundations/Icons.stories.js +305 -0
- package/stories/foundations/SmartSurfaces.stories.js +367 -0
- package/stories/foundations/Spacing.stories.js +175 -0
- package/stories/foundations/Typography.stories.js +960 -0
- package/stories/foundations/ZIndex.stories.js +325 -0
- package/stories/patterns/BorderEffects.stories.js +72 -0
- package/stories/patterns/Layout.stories.js +99 -0
- package/stories/patterns/Utilities.stories.js +107 -0
- package/stories/primitives/Accordion.stories.js +359 -0
- package/stories/primitives/Alerts.stories.js +64 -0
- package/stories/primitives/Badges.stories.js +183 -0
- package/stories/primitives/Buttons.stories.js +229 -0
- package/stories/primitives/Cards.stories.js +353 -0
- package/stories/primitives/FormGroups.stories.js +569 -0
- package/stories/primitives/Forms.stories.js +131 -0
- package/stories/primitives/Media.stories.js +203 -0
- package/stories/primitives/Tables.stories.js +232 -0
- package/stories/reference/ReferenceCatalog.stories.js +28 -0
- package/stories/reference/reference-catalog.js +413 -0
- package/stories/reference/reference-docs.js +302 -0
- package/stories/reference/reference-helpers.js +310 -0
- package/stories/utilities/GridSystem.stories.js +208 -0
- package/stories/utils/PdsAsk.stories.js +420 -0
- package/stories/utils/toast-utils.js +148 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks';
|
|
3
|
+
import { LitElement, html, nothing } from 'lit';
|
|
4
|
+
import referenceData from '../../dist/pds-reference.json' assert { type: 'json' };
|
|
5
|
+
import {
|
|
6
|
+
renderMarkdown,
|
|
7
|
+
renderCode,
|
|
8
|
+
renderDefault,
|
|
9
|
+
renderChipList,
|
|
10
|
+
renderTable,
|
|
11
|
+
navigateToStory
|
|
12
|
+
} from './reference-helpers.js';
|
|
13
|
+
|
|
14
|
+
const DOC_STYLE_ID = 'pds-reference-component-docs-styles';
|
|
15
|
+
const DOC_STYLE_CONTENT = `
|
|
16
|
+
.pds-reference-docs-wrapper {
|
|
17
|
+
padding: var(--spacing-5);
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: var(--spacing-5);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.pds-reference-docs-content {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: var(--spacing-5);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.pds-reference-docs-reset {
|
|
30
|
+
margin: 0;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.pds-reference-docs-list {
|
|
34
|
+
list-style: none;
|
|
35
|
+
margin: 0;
|
|
36
|
+
padding: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.pds-reference-docs-pre {
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding: var(--spacing-3);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.pds-reference-docs-content code {
|
|
45
|
+
white-space: normal;
|
|
46
|
+
word-break: break-word;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Override Storybook autodocs token styles that force nowrap chips */
|
|
50
|
+
.css-qa4clq :where(li:not(.sb-anchor, .sb-unstyled, .sb-unstyled li)) code {
|
|
51
|
+
line-height: inherit;
|
|
52
|
+
margin: 0;
|
|
53
|
+
padding: 0;
|
|
54
|
+
white-space: normal !important;
|
|
55
|
+
border-radius: 0;
|
|
56
|
+
font-size: inherit;
|
|
57
|
+
border: none;
|
|
58
|
+
color: inherit;
|
|
59
|
+
background-color: transparent;
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
function ensureDocStyles() {
|
|
64
|
+
if (typeof document === 'undefined') return;
|
|
65
|
+
if (document.getElementById(DOC_STYLE_ID)) return;
|
|
66
|
+
const style = document.createElement('style');
|
|
67
|
+
style.id = DOC_STYLE_ID;
|
|
68
|
+
style.textContent = DOC_STYLE_CONTENT;
|
|
69
|
+
document.head.append(style);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (typeof document !== 'undefined') {
|
|
73
|
+
ensureDocStyles();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
class PdsReferenceComponentDocs extends LitElement {
|
|
77
|
+
static properties = {
|
|
78
|
+
component: { type: String },
|
|
79
|
+
data: { type: Object }
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
constructor() {
|
|
83
|
+
super();
|
|
84
|
+
this.component = '';
|
|
85
|
+
this.data = referenceData;
|
|
86
|
+
|
|
87
|
+
ensureDocStyles();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
createRenderRoot() {
|
|
91
|
+
return this; // Use light DOM so existing design system styles apply.
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get componentData() {
|
|
95
|
+
if (!this.component) return null;
|
|
96
|
+
return this.data?.components?.[this.component] ?? null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
render() {
|
|
100
|
+
const component = this.componentData;
|
|
101
|
+
|
|
102
|
+
if (!component) {
|
|
103
|
+
return html`
|
|
104
|
+
<article class="card surface-base">
|
|
105
|
+
<p class="text-muted pds-reference-docs-reset">
|
|
106
|
+
No reference metadata found for <code>${this.component || '(unknown component)'}</code>.
|
|
107
|
+
Run <code>npm run build-reference</code> to refresh docs.
|
|
108
|
+
</p>
|
|
109
|
+
</article>
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return html`
|
|
114
|
+
<div class="flex flex-col gap-lg pds-reference-docs-content">
|
|
115
|
+
${this.renderHeader(component)}
|
|
116
|
+
${component.pdsTags?.length ? this.renderTags(component.pdsTags) : nothing}
|
|
117
|
+
${component.description ? this.renderManifestNotes(component.description) : nothing}
|
|
118
|
+
${component.notes?.length ? this.renderImplementationNotes(component.notes) : nothing}
|
|
119
|
+
${component.ontology ? this.renderOntology(component.ontology) : nothing}
|
|
120
|
+
${component.stories?.length ? this.renderStories(component.stories) : nothing}
|
|
121
|
+
${this.renderTableSection('Attributes', component.attributes, [
|
|
122
|
+
{ key: 'name', label: 'Attribute', render: (value) => renderCode(value) },
|
|
123
|
+
{ key: 'description', label: 'Description' },
|
|
124
|
+
{ key: 'type', label: 'Type', render: (value) => renderCode(value) },
|
|
125
|
+
{ key: 'default', label: 'Default', render: (value) => renderDefault(value) }
|
|
126
|
+
])}
|
|
127
|
+
${this.renderTableSection('Properties', component.properties, [
|
|
128
|
+
{ key: 'name', label: 'Property', render: (value) => renderCode(value) },
|
|
129
|
+
{ key: 'type', label: 'Type', render: (value) => renderCode(value) },
|
|
130
|
+
{ key: 'description', label: 'Description' },
|
|
131
|
+
{ key: 'default', label: 'Default', render: (value) => renderDefault(value) }
|
|
132
|
+
])}
|
|
133
|
+
${this.renderTableSection('Events', component.events, [
|
|
134
|
+
{ key: 'name', label: 'Event', render: (value) => renderCode(value) },
|
|
135
|
+
{ key: 'type', label: 'Type', render: (value) => renderCode(value) },
|
|
136
|
+
{ key: 'description', label: 'Description' }
|
|
137
|
+
])}
|
|
138
|
+
${this.renderTableSection('Methods', component.methods, [
|
|
139
|
+
{ key: 'name', label: 'Method', render: (value) => renderCode(value) },
|
|
140
|
+
{ key: 'description', label: 'Description' },
|
|
141
|
+
{
|
|
142
|
+
key: 'parameters',
|
|
143
|
+
label: 'Parameters',
|
|
144
|
+
render: (value) => {
|
|
145
|
+
if (!value || !value.length) {
|
|
146
|
+
return html`<span class="text-muted">—</span>`;
|
|
147
|
+
}
|
|
148
|
+
return html`
|
|
149
|
+
<ul class="pds-reference-docs-list flex flex-col gap-xs">
|
|
150
|
+
${value.map((param) => html`
|
|
151
|
+
<li class="flex flex-wrap gap-xs items-baseline">
|
|
152
|
+
<code>${param.name}${param.type ? `: ${param.type}` : ''}</code>
|
|
153
|
+
${param.description ? html`<span class="text-muted text-sm">- ${param.description}</span>` : nothing}
|
|
154
|
+
</li>
|
|
155
|
+
`)}
|
|
156
|
+
</ul>
|
|
157
|
+
`;
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{ key: 'return', label: 'Returns', render: (value) => renderCode(value) }
|
|
161
|
+
])}
|
|
162
|
+
${this.renderTableSection('Slots', component.slots, [
|
|
163
|
+
{ key: 'name', label: 'Slot' },
|
|
164
|
+
{ key: 'description', label: 'Description' }
|
|
165
|
+
])}
|
|
166
|
+
${this.renderTableSection('CSS Parts', component.cssParts, [
|
|
167
|
+
{ key: 'name', label: 'CSS Part' },
|
|
168
|
+
{ key: 'description', label: 'Description' }
|
|
169
|
+
])}
|
|
170
|
+
</div>
|
|
171
|
+
`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
renderHeader(component) {
|
|
175
|
+
return html`
|
|
176
|
+
<section class="card surface-base flex flex-col gap-sm">
|
|
177
|
+
<div class="flex flex-wrap gap-xs">
|
|
178
|
+
<span class="badge">Web Component</span>
|
|
179
|
+
${component.ontology?.id ? html`<span class="badge">${component.ontology.id}</span>` : nothing}
|
|
180
|
+
${component.superclass ? html`<span class="badge">extends ${component.superclass}</span>` : nothing}
|
|
181
|
+
</div>
|
|
182
|
+
<h2 class="pds-reference-docs-reset">${component.displayName}</h2>
|
|
183
|
+
<div class="flex flex-wrap gap-sm text-muted text-sm">
|
|
184
|
+
<span><code>${component.tag}</code></span>
|
|
185
|
+
${component.className ? html`<span>class <code>${component.className}</code></span>` : nothing}
|
|
186
|
+
${component.sourceModule ? html`<span>${component.sourceModule}</span>` : nothing}
|
|
187
|
+
</div>
|
|
188
|
+
${component.docsDescription ? html`<div>${renderMarkdown(component.docsDescription)}</div>` : nothing}
|
|
189
|
+
</section>
|
|
190
|
+
`;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
renderTags(tags) {
|
|
194
|
+
return html`
|
|
195
|
+
<section class="card surface-base flex flex-col gap-sm">
|
|
196
|
+
<h3 class="pds-reference-docs-reset">Experience Tags</h3>
|
|
197
|
+
${renderChipList(tags)}
|
|
198
|
+
</section>
|
|
199
|
+
`;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
renderManifestNotes(description) {
|
|
203
|
+
return html`
|
|
204
|
+
<section class="card surface-base flex flex-col gap-sm">
|
|
205
|
+
<h3 class="pds-reference-docs-reset">Manifest Notes</h3>
|
|
206
|
+
<pre class="surface-subtle radius-lg text-sm overflow-auto pds-reference-docs-pre">${description}</pre>
|
|
207
|
+
</section>
|
|
208
|
+
`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
renderImplementationNotes(notes) {
|
|
212
|
+
return html`
|
|
213
|
+
<section class="card surface-base flex flex-col gap-xs">
|
|
214
|
+
<h3 class="pds-reference-docs-reset">Implementation Notes</h3>
|
|
215
|
+
${notes.map((note) => html`<p class="text-muted pds-reference-docs-reset">${note}</p>`)}
|
|
216
|
+
</section>
|
|
217
|
+
`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
renderOntology(ontology) {
|
|
221
|
+
return html`
|
|
222
|
+
<section class="card surface-base flex flex-col gap-sm">
|
|
223
|
+
<h3 class="pds-reference-docs-reset">Ontology</h3>
|
|
224
|
+
<div class="flex flex-wrap gap-xs items-center">
|
|
225
|
+
<span class="badge">${ontology.id}</span>
|
|
226
|
+
${ontology.name ? html`<span class="badge">${ontology.name}</span>` : nothing}
|
|
227
|
+
</div>
|
|
228
|
+
${ontology.selectors?.length ? html`
|
|
229
|
+
<div class="flex flex-col gap-xs">
|
|
230
|
+
<span class="text-muted text-sm">Selectors</span>
|
|
231
|
+
${renderChipList(ontology.selectors)}
|
|
232
|
+
</div>
|
|
233
|
+
` : nothing}
|
|
234
|
+
</section>
|
|
235
|
+
`;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
renderStories(stories) {
|
|
239
|
+
return html`
|
|
240
|
+
<section class="card surface-base flex flex-col gap-md">
|
|
241
|
+
<h3 class="pds-reference-docs-reset">Storybook Coverage</h3>
|
|
242
|
+
<div class="grid grid-auto-md gap-md">
|
|
243
|
+
${stories.map((story) => html`
|
|
244
|
+
<div class="card surface-elevated flex flex-col gap-xs">
|
|
245
|
+
<a
|
|
246
|
+
href="/?path=/story/${story.id}"
|
|
247
|
+
@click=${(event) => this.handleStoryNavigation(event, story.id)}
|
|
248
|
+
>${story.name}</a>
|
|
249
|
+
<div class="flex flex-wrap gap-sm text-muted text-sm">
|
|
250
|
+
<span>${story.id}</span>
|
|
251
|
+
</div>
|
|
252
|
+
${story.description ? html`<p class="text-muted pds-reference-docs-reset">${story.description}</p>` : nothing}
|
|
253
|
+
${story.tags?.length ? renderChipList(story.tags) : nothing}
|
|
254
|
+
</div>
|
|
255
|
+
`)}
|
|
256
|
+
</div>
|
|
257
|
+
</section>
|
|
258
|
+
`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
handleStoryNavigation(event, storyId) {
|
|
262
|
+
event?.preventDefault?.();
|
|
263
|
+
event?.stopPropagation?.();
|
|
264
|
+
navigateToStory(storyId, 'story');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
renderTableSection(title, items, columns) {
|
|
268
|
+
if (!items || !items.length) return nothing;
|
|
269
|
+
return html`
|
|
270
|
+
<section class="card surface-base flex flex-col gap-sm">
|
|
271
|
+
<h3 class="pds-reference-docs-reset">${title}</h3>
|
|
272
|
+
${renderTable(items, columns)}
|
|
273
|
+
</section>
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (!customElements.get('pds-reference-component-docs')) {
|
|
279
|
+
customElements.define('pds-reference-component-docs', PdsReferenceComponentDocs);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function createComponentDocsPage(tag) {
|
|
283
|
+
return function ComponentDocsPage() {
|
|
284
|
+
return React.createElement(
|
|
285
|
+
React.Fragment,
|
|
286
|
+
null,
|
|
287
|
+
React.createElement(Title, null),
|
|
288
|
+
React.createElement(Subtitle, null),
|
|
289
|
+
React.createElement(Description, null),
|
|
290
|
+
React.createElement(Primary, null),
|
|
291
|
+
React.createElement(Controls, null),
|
|
292
|
+
React.createElement(
|
|
293
|
+
'div',
|
|
294
|
+
{
|
|
295
|
+
className: 'card surface-elevated pds-reference-docs-wrapper'
|
|
296
|
+
},
|
|
297
|
+
React.createElement('pds-reference-component-docs', { component: tag })
|
|
298
|
+
),
|
|
299
|
+
React.createElement(Stories, { includePrimary: false })
|
|
300
|
+
);
|
|
301
|
+
};
|
|
302
|
+
}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { html, nothing } from 'lit';
|
|
2
|
+
import { addons } from '@storybook/preview-api';
|
|
3
|
+
import { SELECT_STORY } from '@storybook/core-events';
|
|
4
|
+
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
5
|
+
import showdown from 'showdown';
|
|
6
|
+
|
|
7
|
+
const REF_HELPER_STYLE_ID = 'pds-reference-helper-styles';
|
|
8
|
+
const REF_HELPER_STYLE_CONTENT = `
|
|
9
|
+
.pds-reference-docs-pre {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: var(--spacing-3);
|
|
12
|
+
}
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
function ensureReferenceHelperStyles() {
|
|
16
|
+
if (typeof document === 'undefined') return;
|
|
17
|
+
if (document.getElementById(REF_HELPER_STYLE_ID)) return;
|
|
18
|
+
const style = document.createElement('style');
|
|
19
|
+
style.id = REF_HELPER_STYLE_ID;
|
|
20
|
+
style.textContent = REF_HELPER_STYLE_CONTENT;
|
|
21
|
+
document.head.append(style);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof document !== 'undefined') {
|
|
25
|
+
ensureReferenceHelperStyles();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const markdown = new showdown.Converter({
|
|
29
|
+
tables: true,
|
|
30
|
+
simplifiedAutoLink: true,
|
|
31
|
+
ghCodeBlocks: true,
|
|
32
|
+
simpleLineBreaks: true
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export function renderMarkdown(text) {
|
|
36
|
+
if (!text) return nothing;
|
|
37
|
+
return unsafeHTML(markdown.makeHtml(text));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function renderCode(value) {
|
|
41
|
+
if (!value) return html`<span class="text-muted">—</span>`;
|
|
42
|
+
return html`<code>${value}</code>`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function renderDefault(value) {
|
|
46
|
+
if (value === undefined || value === null || value === '') {
|
|
47
|
+
return html`<span class="text-muted">—</span>`;
|
|
48
|
+
}
|
|
49
|
+
if (typeof value === 'string') {
|
|
50
|
+
const trimmed = value.trim();
|
|
51
|
+
const unwrapped = trimmed.startsWith('"') && trimmed.endsWith('"')
|
|
52
|
+
? trimmed.slice(1, -1)
|
|
53
|
+
: trimmed;
|
|
54
|
+
return html`<code>${unwrapped}</code>`;
|
|
55
|
+
}
|
|
56
|
+
return html`<code>${String(value)}</code>`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function formatTimestamp(timestamp) {
|
|
60
|
+
if (!timestamp) return '\u2014';
|
|
61
|
+
try {
|
|
62
|
+
const date = new Date(timestamp);
|
|
63
|
+
return date.toLocaleString();
|
|
64
|
+
} catch (err) {
|
|
65
|
+
return timestamp;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const VOID_HTML_ELEMENTS = new Set([
|
|
70
|
+
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
|
|
71
|
+
'link', 'meta', 'param', 'source', 'track', 'wbr'
|
|
72
|
+
]);
|
|
73
|
+
|
|
74
|
+
const getStorySlug = (storyId) => {
|
|
75
|
+
if (typeof storyId !== 'string') return undefined;
|
|
76
|
+
const [slug] = storyId.split('--');
|
|
77
|
+
return slug;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export function navigateToStory(storyId, viewMode = 'story') {
|
|
81
|
+
if (!storyId || typeof window === 'undefined') return false;
|
|
82
|
+
|
|
83
|
+
let navigated = false;
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const channel = addons?.getChannel?.();
|
|
87
|
+
if (channel?.emit) {
|
|
88
|
+
channel.emit(SELECT_STORY, { storyId, viewMode });
|
|
89
|
+
navigated = true;
|
|
90
|
+
}
|
|
91
|
+
} catch (err) {
|
|
92
|
+
console.warn('PDS reference docs: channel navigation failed', err);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
window.parent?.postMessage(
|
|
97
|
+
{
|
|
98
|
+
source: 'pds-reference-docs',
|
|
99
|
+
type: 'pds-related:navigate',
|
|
100
|
+
storyId,
|
|
101
|
+
viewMode
|
|
102
|
+
},
|
|
103
|
+
'*'
|
|
104
|
+
);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
console.warn('PDS reference docs: postMessage navigation failed', err);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (navigated) return true;
|
|
110
|
+
|
|
111
|
+
const slug = getStorySlug(storyId);
|
|
112
|
+
const targetSearch = viewMode === 'docs' && slug
|
|
113
|
+
? `?path=/docs/${slug}--docs`
|
|
114
|
+
: `?path=/story/${storyId}`;
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
if (window.parent && window.parent !== window) {
|
|
118
|
+
window.parent.location.search = targetSearch;
|
|
119
|
+
} else {
|
|
120
|
+
window.location.search = targetSearch;
|
|
121
|
+
}
|
|
122
|
+
return true;
|
|
123
|
+
} catch (err) {
|
|
124
|
+
console.warn('PDS reference docs: fallback navigation failed', err);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export function formatDemoHtml(html) {
|
|
131
|
+
if (typeof html !== 'string') return '';
|
|
132
|
+
const tokens = html.trim().split(/(<[^>]+>)/g).filter(Boolean);
|
|
133
|
+
if (!tokens.length) return '';
|
|
134
|
+
|
|
135
|
+
const indentUnit = ' ';
|
|
136
|
+
let indent = 0;
|
|
137
|
+
let formatted = '';
|
|
138
|
+
|
|
139
|
+
for (const token of tokens) {
|
|
140
|
+
const isTag = token.startsWith('<');
|
|
141
|
+
if (!isTag) {
|
|
142
|
+
const text = token.replace(/\s+/g, ' ').trim();
|
|
143
|
+
if (text) {
|
|
144
|
+
formatted += `${indentUnit.repeat(indent)}${text}\n`;
|
|
145
|
+
}
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const isClosing = /^<\//.test(token);
|
|
150
|
+
const tagNameMatch = token.match(/^<\/?\s*([a-zA-Z0-9-]+)/);
|
|
151
|
+
const tagName = tagNameMatch ? tagNameMatch[1].toLowerCase() : '';
|
|
152
|
+
const isVoid = VOID_HTML_ELEMENTS.has(tagName) || /\/\s*>$/.test(token);
|
|
153
|
+
|
|
154
|
+
if (isClosing) {
|
|
155
|
+
indent = Math.max(0, indent - 1);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
formatted += `${indentUnit.repeat(indent)}${token.trim()}\n`;
|
|
159
|
+
|
|
160
|
+
if (!isClosing && !isVoid) {
|
|
161
|
+
indent += 1;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return formatted.trimEnd();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function escapeCodeFragment(text) {
|
|
169
|
+
return text
|
|
170
|
+
.replace(/&/g, '&')
|
|
171
|
+
.replace(/</g, '<')
|
|
172
|
+
.replace(/>/g, '>');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function highlightDemoHtml(html) {
|
|
176
|
+
if (!html) return '';
|
|
177
|
+
let result = '';
|
|
178
|
+
let index = 0;
|
|
179
|
+
const attrRegex = /([\w:-@.]+)(?:=(?:"([^"]*)"|'([^']*)'|([^\s>]*)))?/g;
|
|
180
|
+
|
|
181
|
+
while (index < html.length) {
|
|
182
|
+
if (html.startsWith('<!--', index)) {
|
|
183
|
+
const commentEnd = html.indexOf('-->', index);
|
|
184
|
+
if (commentEnd !== -1) {
|
|
185
|
+
const comment = html.substring(index, commentEnd + 3);
|
|
186
|
+
result += `<span class="html-token-comment">${escapeCodeFragment(comment)}</span>`;
|
|
187
|
+
index = commentEnd + 3;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const char = html[index];
|
|
193
|
+
|
|
194
|
+
if (char === '\n' || char === '\r' || char === '\t' || char === ' ') {
|
|
195
|
+
result += char;
|
|
196
|
+
index += 1;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (char === '<') {
|
|
201
|
+
const tagEnd = html.indexOf('>', index);
|
|
202
|
+
if (tagEnd !== -1) {
|
|
203
|
+
const tagContent = html.substring(index + 1, tagEnd);
|
|
204
|
+
result += '<';
|
|
205
|
+
|
|
206
|
+
if (tagContent.startsWith('/')) {
|
|
207
|
+
const tagName = tagContent.substring(1).split(/[\s>]/)[0];
|
|
208
|
+
result += '/';
|
|
209
|
+
result += `<span class="html-token-tag">${escapeCodeFragment(tagName)}</span>`;
|
|
210
|
+
} else {
|
|
211
|
+
const parts = tagContent.match(/^([\w:-@.]+)([\s\S]*?)(\/?)?$/);
|
|
212
|
+
if (parts) {
|
|
213
|
+
const [, tagName, attrsStr, trailingSlash] = parts;
|
|
214
|
+
result += `<span class="html-token-tag">${escapeCodeFragment(tagName)}</span>`;
|
|
215
|
+
|
|
216
|
+
if (attrsStr && attrsStr.trim()) {
|
|
217
|
+
let lastIndex = 0;
|
|
218
|
+
attrRegex.lastIndex = 0;
|
|
219
|
+
let match;
|
|
220
|
+
|
|
221
|
+
while ((match = attrRegex.exec(attrsStr)) !== null) {
|
|
222
|
+
result += escapeCodeFragment(attrsStr.substring(lastIndex, match.index));
|
|
223
|
+
const [fullMatch, attrName, doubleQuoted, singleQuoted, unquoted] = match;
|
|
224
|
+
result += `<span class="html-token-attr">${escapeCodeFragment(attrName)}</span>`;
|
|
225
|
+
|
|
226
|
+
if (doubleQuoted !== undefined) {
|
|
227
|
+
result += `=<span class="html-token-value">"${escapeCodeFragment(doubleQuoted)}"</span>`;
|
|
228
|
+
} else if (singleQuoted !== undefined) {
|
|
229
|
+
result += `=<span class="html-token-value">'${escapeCodeFragment(singleQuoted)}'</span>`;
|
|
230
|
+
} else if (unquoted !== undefined && unquoted !== '') {
|
|
231
|
+
result += `=<span class="html-token-value">${escapeCodeFragment(unquoted)}</span>`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
lastIndex = match.index + fullMatch.length;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
result += escapeCodeFragment(attrsStr.substring(lastIndex));
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (trailingSlash) {
|
|
241
|
+
result += '/';
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
result += escapeCodeFragment(tagContent);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
result += '>';
|
|
249
|
+
index = tagEnd + 1;
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
result += escapeCodeFragment(char);
|
|
255
|
+
index += 1;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export function renderChipList(values = []) {
|
|
262
|
+
if (!values.length) return nothing;
|
|
263
|
+
return html`
|
|
264
|
+
<div class="flex flex-wrap gap-xs">
|
|
265
|
+
${values.map((value) => html`<span class="badge">${value}</span>`)}
|
|
266
|
+
</div>
|
|
267
|
+
`;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function formatTableValue(value) {
|
|
271
|
+
if (value === undefined || value === null || value === '') {
|
|
272
|
+
return html`<span class="text-muted">—</span>`;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (Array.isArray(value)) {
|
|
276
|
+
if (!value.length) return html`<span class="text-muted">—</span>`;
|
|
277
|
+
return renderChipList(value.map((entry) => (typeof entry === 'object' ? JSON.stringify(entry) : entry)));
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (typeof value === 'object') {
|
|
281
|
+
return html`
|
|
282
|
+
<pre class="surface-subtle radius-lg text-sm overflow-auto pds-reference-docs-pre">
|
|
283
|
+
${JSON.stringify(value, null, 2)}
|
|
284
|
+
</pre>
|
|
285
|
+
`;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const text = String(value);
|
|
289
|
+
return /[<>&]/.test(text) ? unsafeHTML(text) : html`${text}`;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function renderTable(items = [], columns = []) {
|
|
293
|
+
if (!items.length) return nothing;
|
|
294
|
+
return html`
|
|
295
|
+
<table class="table-bordered table-compact">
|
|
296
|
+
<thead>
|
|
297
|
+
<tr>
|
|
298
|
+
${columns.map((col) => html`<th scope="col">${col.label}</th>`)}
|
|
299
|
+
</tr>
|
|
300
|
+
</thead>
|
|
301
|
+
<tbody>
|
|
302
|
+
${items.map((item) => html`
|
|
303
|
+
<tr>
|
|
304
|
+
${columns.map((col) => html`<td>${col.render ? col.render(item[col.key], item) : formatTableValue(col.format ? col.format(item[col.key], item) : item[col.key])}</td>`)}
|
|
305
|
+
</tr>
|
|
306
|
+
`)}
|
|
307
|
+
</tbody>
|
|
308
|
+
</table>
|
|
309
|
+
`;
|
|
310
|
+
}
|