@siemens/ix-docs 0.0.0-pr-2238-20251103095443

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.
@@ -0,0 +1,529 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: 2024 Siemens AG
3
+ *
4
+ * SPDX-License-Identifier: MIT
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+
10
+ import path from 'path';
11
+ import fs, { writeFile } from 'fs-extra';
12
+ import Mustache from 'mustache';
13
+ import componentDoc from '@siemens/ix/component-doc.json';
14
+ import { convertDocsTagsToTSXElement } from './utils/docs-tags';
15
+ import { generateTypeScriptDocs } from './typedoc-generator';
16
+ import { escapeBackticks, parseJSDocsToMarkdown } from './utils/escape';
17
+ import { collectHTMLExamples } from './collector/collectHTMLExamples';
18
+ import { collectReactExamples } from './collector/collectReactExamples';
19
+ import { collectVueExamples } from './collector/collectVueExamples';
20
+ import { collectAngularExamples } from './collector/collectAngularExamples';
21
+
22
+ type OutputType = 'html' | 'react' | 'angular' | 'angular_standalone' | 'vue';
23
+
24
+ const version = 'v2';
25
+
26
+ const __root = path.resolve(__dirname, '../');
27
+
28
+ const __core = path.join(__dirname, '../node_modules', '@siemens', 'ix');
29
+ const __packages = path.join(__dirname, '../node_modules');
30
+
31
+ const __htmlTestAppRoot = path.join(__packages, 'html-test-app');
32
+ const __htmlTestAppDist = path.join(__htmlTestAppRoot, 'dist');
33
+
34
+ const __mobileTestAppDist = path.join(__packages, 'ionic-test-app', 'dist');
35
+
36
+ const __htmlTestApp = path.join(
37
+ __packages,
38
+ 'html-test-app',
39
+ 'src',
40
+ 'preview-examples'
41
+ );
42
+
43
+ const __reactTestAppRoot = path.join(__packages, 'react-test-app');
44
+ const __reactTestApp = path.join(__reactTestAppRoot, 'src', 'preview-examples');
45
+
46
+ const __angularTestApp = path.join(
47
+ __packages,
48
+ 'angular-test-app',
49
+ 'src',
50
+ 'preview-examples'
51
+ );
52
+ const __angularStandaloneTestApp = path.join(
53
+ __packages,
54
+ 'angular-standalone-test-app',
55
+ 'src',
56
+ 'preview-examples'
57
+ );
58
+ const __vueTestApp = path.join(
59
+ __packages,
60
+ 'vue-test-app',
61
+ 'src',
62
+ 'preview-examples'
63
+ );
64
+
65
+ const __storybookStatic = path.join(
66
+ __packages,
67
+ 'storybook-docs',
68
+ 'storybook-static'
69
+ );
70
+
71
+ const __build = path.join(__root, 'build');
72
+
73
+ const __docs = path.join(__build, 'docs');
74
+ const __autogenerated = path.join(__docs, 'autogenerated');
75
+ const __autogeneratedPrompt = path.join(__autogenerated, 'prompt');
76
+ const __autogeneratedApi = path.join(__autogenerated, 'api');
77
+ const __autogeneratedPlayground = path.join(__autogenerated, 'playground');
78
+ const __autogeneratedUtils = path.join(__autogenerated, 'utils');
79
+ const __changelog = path.join(__docs, 'home', 'releases', 'changelog.md');
80
+
81
+ const __static = path.join(__build, 'static');
82
+ const __demo = path.join(__static, 'demo', version);
83
+ const __preview = path.join(__demo, 'preview');
84
+ const __previewHtml = path.join(__preview, 'html');
85
+ const __previewStorybook = path.join(__static, 'storybook-static');
86
+
87
+ const __exampleCodeHtml = path.join(__demo, 'html');
88
+
89
+ export const __componentUsageByComponentJson = path.join(
90
+ __htmlTestAppRoot,
91
+ 'component-usage-by-component.json'
92
+ );
93
+
94
+ const __usage = path.join(__autogenerated, 'usage');
95
+
96
+ const __templates = path.join(__dirname, 'templates');
97
+
98
+ function kebabToCamelCase(str: string): string {
99
+ return str
100
+ .toLowerCase()
101
+ .split('-')
102
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
103
+ .join('');
104
+ }
105
+
106
+ async function copyStaticFiles() {
107
+ console.log('Copying demo source');
108
+
109
+ fs.copyFileSync(
110
+ path.join(__htmlTestAppRoot, 'component-usage.json'),
111
+ path.join(__build, 'component-usage.json')
112
+ );
113
+
114
+ fs.copyFileSync(
115
+ __componentUsageByComponentJson,
116
+ path.join(__build, 'component-usage-by-component.json')
117
+ );
118
+
119
+ fs.copySync(__htmlTestAppDist, __previewHtml);
120
+ fs.copySync(__mobileTestAppDist, path.join(__demo, 'preview', 'mobile'));
121
+
122
+ fs.copySync(__htmlTestApp, __exampleCodeHtml);
123
+ fs.copySync(__reactTestApp, path.join(__demo, 'react'));
124
+ fs.copySync(__angularTestApp, path.join(__demo, 'angular'));
125
+ fs.copySync(
126
+ __angularStandaloneTestApp,
127
+ path.join(__demo, 'angular_standalone')
128
+ );
129
+ fs.copySync(__vueTestApp, path.join(__demo, 'vue'));
130
+ }
131
+
132
+ async function copyUsage() {
133
+ console.log('Generate usage markdown');
134
+
135
+ function stripComments(code: string) {
136
+ return code
137
+ .replace(/\/\*[^]*?\*\//gs, '')
138
+ .replace(/<!--[^]*?-->/gs, '')
139
+ .trim();
140
+ }
141
+
142
+ function generateSourceCodeMarkdown(testAppPath: string, type: OutputType) {
143
+ fs.readdirSync(testAppPath).forEach((file) => {
144
+ if (file.match(/.*.(html|css|tsx|ts|vue)/)) {
145
+ const code = stripComments(
146
+ fs.readFileSync(path.join(testAppPath, file), 'utf-8')
147
+ );
148
+ const fileType = file.split('.').pop();
149
+
150
+ const output = Mustache.render(
151
+ fs.readFileSync(path.join(__templates, 'usage.mustache'), 'utf-8'),
152
+ {
153
+ code,
154
+ type: fileType,
155
+ }
156
+ );
157
+
158
+ fs.ensureDirSync(path.join(__usage, type));
159
+ fs.writeFileSync(path.join(__usage, type, `${file}.md`), output);
160
+ }
161
+ });
162
+ }
163
+
164
+ generateSourceCodeMarkdown(__htmlTestApp, 'html');
165
+ generateSourceCodeMarkdown(__reactTestApp, 'react');
166
+ generateSourceCodeMarkdown(__angularTestApp, 'angular');
167
+ generateSourceCodeMarkdown(__angularStandaloneTestApp, 'angular_standalone');
168
+ generateSourceCodeMarkdown(__vueTestApp, 'vue');
169
+ }
170
+
171
+ async function generatePlaygroundMarkdown(extendedPlayground: string[] = []) {
172
+ const __playgroundTemplate = path.join(__templates, 'playground.mustache');
173
+ const playgroundFilesTemplate = fs.readFileSync(
174
+ path.join(__templates, 'playground-files.mustache'),
175
+ 'utf-8'
176
+ );
177
+ const playgroundMarkdownTemplate = fs.readFileSync(
178
+ path.join(__templates, 'playground-markdown.mustache'),
179
+ 'utf-8'
180
+ );
181
+ const playgroundTemplate = fs.readFileSync(__playgroundTemplate, 'utf-8');
182
+
183
+ const files = await fs.readdir(__htmlTestApp);
184
+ const demoFiles = files.filter((file) => file.endsWith('.html'));
185
+
186
+ extendedPlayground = extendedPlayground.map((f) => f + '.html');
187
+
188
+ for (const file of [...demoFiles, ...extendedPlayground]) {
189
+ const reactFiles: Record<string, string> = {};
190
+ const angularFiles: Record<string, string> = {};
191
+ const angularStandaloneFiles: Record<string, string> = {};
192
+ const vueFiles: Record<string, string> = {};
193
+ const htmlFiles: Record<string, string> = {};
194
+
195
+ let isPreviewAvailable = false;
196
+
197
+ const name = file.replace('.html', '');
198
+
199
+ const imports: string[] = [];
200
+
201
+ if (fs.existsSync(path.join(__reactTestApp, `${name}.tsx`))) {
202
+ reactFiles[`${name}.tsx`] = `react/${name}.tsx`;
203
+ }
204
+
205
+ if (fs.existsSync(path.join(__reactTestApp, `${name}.scoped.css`))) {
206
+ reactFiles[`${name}.scoped.css`] = `react/${name}.scoped.css`;
207
+ }
208
+
209
+ if (fs.existsSync(path.join(__angularTestApp, `${name}.ts`))) {
210
+ angularFiles[`${name}.ts`] = `angular/${name}.ts`;
211
+ }
212
+
213
+ if (fs.existsSync(path.join(__angularTestApp, `${name}.html`))) {
214
+ angularFiles[`${name}.html`] = `angular/${name}.html`;
215
+ }
216
+
217
+ if (fs.existsSync(path.join(__angularTestApp, `${name}.css`))) {
218
+ angularFiles[`${name}.css`] = `angular/${name}.css`;
219
+ }
220
+
221
+ if (fs.existsSync(path.join(__angularStandaloneTestApp, `${name}.ts`))) {
222
+ angularStandaloneFiles[`${name}.ts`] = `angular_standalone/${name}.ts`;
223
+ }
224
+
225
+ if (fs.existsSync(path.join(__angularStandaloneTestApp, `${name}.html`))) {
226
+ angularStandaloneFiles[
227
+ `${name}.html`
228
+ ] = `angular_standalone/${name}.html`;
229
+ }
230
+
231
+ if (fs.existsSync(path.join(__angularStandaloneTestApp, `${name}.css`))) {
232
+ angularStandaloneFiles[`${name}.css`] = `angular_standalone/${name}.css`;
233
+ }
234
+
235
+ if (fs.existsSync(path.join(__vueTestApp, `${name}.vue`))) {
236
+ vueFiles[`${name}.vue`] = `vue/${name}.vue`;
237
+ }
238
+
239
+ if (fs.existsSync(path.join(__vueTestApp, `${name}.css`))) {
240
+ vueFiles[`${name}.css`] = `vue/${name}.css`;
241
+ }
242
+
243
+ if (fs.existsSync(path.join(__htmlTestApp, `${name}.html`))) {
244
+ htmlFiles[`${name}.html`] = `html/${name}.html`;
245
+ isPreviewAvailable = true;
246
+ }
247
+
248
+ if (fs.existsSync(path.join(__htmlTestApp, `${name}.css`))) {
249
+ htmlFiles[`${name}.css`] = `html/${name}.css`;
250
+ }
251
+
252
+ function collectMarkdownImports(
253
+ files: Record<string, string>,
254
+ type: OutputType
255
+ ) {
256
+ Object.keys(files).forEach((key) => {
257
+ const importStatement = `import ${kebabToCamelCase(
258
+ key.replaceAll('.', '_')
259
+ )}_${type} from '@site/docs/autogenerated/usage/${type}/${key}.md';`;
260
+ imports.push(importStatement);
261
+ });
262
+ }
263
+
264
+ collectMarkdownImports(reactFiles, 'react');
265
+ collectMarkdownImports(angularFiles, 'angular');
266
+ collectMarkdownImports(angularStandaloneFiles, 'angular_standalone');
267
+ collectMarkdownImports(vueFiles, 'vue');
268
+ collectMarkdownImports(htmlFiles, 'html');
269
+
270
+ function mapValues(files: Record<string, string>) {
271
+ return Object.keys(files).map((key) => ({
272
+ key,
273
+ value: files[key],
274
+ }));
275
+ }
276
+
277
+ function mapMarkdownImports(
278
+ files: Record<string, string>,
279
+ type: OutputType
280
+ ) {
281
+ return Object.keys(files).map((key) => ({
282
+ key,
283
+ value: `${kebabToCamelCase(key.replaceAll('.', '_'))}_${type}`,
284
+ }));
285
+ }
286
+
287
+ const view = {
288
+ name,
289
+ imports,
290
+ isPreviewAvailable: !isPreviewAvailable,
291
+ react: mapValues(reactFiles),
292
+ angular: mapValues(angularFiles),
293
+ angular_standalone: mapValues(angularStandaloneFiles),
294
+ vue: mapValues(vueFiles),
295
+ html: mapValues(htmlFiles),
296
+
297
+ reactMarkdown: mapMarkdownImports(reactFiles, 'react'),
298
+ angularMarkdown: mapMarkdownImports(angularFiles, 'angular'),
299
+ angularStandaloneMarkdown: mapMarkdownImports(
300
+ angularStandaloneFiles,
301
+ 'angular_standalone'
302
+ ),
303
+ vueMarkdown: mapMarkdownImports(vueFiles, 'vue'),
304
+ htmlMarkdown: mapMarkdownImports(htmlFiles, 'html'),
305
+ };
306
+
307
+ const output = Mustache.render(
308
+ playgroundTemplate,
309
+ view,
310
+ {
311
+ files: playgroundFilesTemplate,
312
+ markdown: playgroundMarkdownTemplate,
313
+ },
314
+ {
315
+ tags: ['<%', '%>'],
316
+ }
317
+ );
318
+
319
+ await fs.ensureDir(__autogeneratedPlayground);
320
+
321
+ await fs.writeFile(
322
+ path.join(__autogeneratedPlayground, `${name}.mdx`),
323
+ output
324
+ );
325
+ }
326
+ }
327
+
328
+ async function generateApiMarkdown() {
329
+ const components = componentDoc.components;
330
+
331
+ const __propertyTemplate = path.join(__templates, 'property-table.mustache');
332
+ const __eventTemplate = path.join(__templates, 'event-table.mustache');
333
+ const __slotTemplate = path.join(__templates, 'slot-table.mustache');
334
+ const __apiTemplate = path.join(__templates, 'api.mustache');
335
+ const __tagsTemplate = path.join(__templates, 'tags.mustache');
336
+ const propertyTemplate = fs.readFileSync(__propertyTemplate, 'utf-8');
337
+ const eventTemplate = fs.readFileSync(__eventTemplate, 'utf-8');
338
+ const slotTemplate = fs.readFileSync(__slotTemplate, 'utf-8');
339
+ const apiTemplate = fs.readFileSync(__apiTemplate, 'utf-8');
340
+ const tagsTemplate = fs.readFileSync(__tagsTemplate, 'utf-8');
341
+
342
+ for (const component of components) {
343
+ const { props, events, slots } = component;
344
+
345
+ const propertyOutput = Mustache.render(propertyTemplate, {
346
+ tag: component.tag,
347
+ props: props.map((prop) => ({
348
+ ...prop,
349
+ docsTags: convertDocsTagsToTSXElement(component.tag, prop.docsTags),
350
+ docs: parseJSDocsToMarkdown(escapeBackticks(prop.docs)),
351
+ })),
352
+ });
353
+
354
+ const eventOutput = Mustache.render(eventTemplate, {
355
+ tag: component.tag,
356
+ events: events.map((event) => ({
357
+ ...event,
358
+ docsTags: convertDocsTagsToTSXElement(component.tag, event.docsTags),
359
+ docs: parseJSDocsToMarkdown(escapeBackticks(event.docs)),
360
+ })),
361
+ });
362
+
363
+ const slotOutput = Mustache.render(slotTemplate, {
364
+ slots: slots.map((tag) => ({
365
+ ...tag,
366
+ docsTags: convertDocsTagsToTSXElement(component.tag, []),
367
+ docs: parseJSDocsToMarkdown(escapeBackticks(tag.docs)),
368
+ })),
369
+ });
370
+
371
+ const tagsOutput = Mustache.render(tagsTemplate, {
372
+ docsTags: convertDocsTagsToTSXElement(component.tag, component.docsTags),
373
+ });
374
+
375
+ const apiOutput = Mustache.render(apiTemplate, {
376
+ tag: component.tag,
377
+ hasSlots: slots.length > 0,
378
+ hasEvents: events.length > 0,
379
+ hasProps: props.length > 0,
380
+ properties: propertyOutput,
381
+ events: eventOutput,
382
+ slots: slotOutput,
383
+ });
384
+
385
+ const __component = path.join(__autogeneratedApi, component.tag);
386
+ await fs.ensureDir(__component);
387
+ await fs.writeFile(path.join(__component, `props.mdx`), propertyOutput);
388
+ await fs.writeFile(path.join(__component, `events.mdx`), eventOutput);
389
+ await fs.writeFile(path.join(__component, `slots.mdx`), slotOutput);
390
+ await fs.writeFile(path.join(__component, `api.mdx`), apiOutput);
391
+ await fs.writeFile(path.join(__component, `tags.mdx`), tagsOutput);
392
+ }
393
+ }
394
+
395
+ async function copyStorybook() {
396
+ await fs.copy(__storybookStatic, __previewStorybook, { overwrite: true });
397
+ }
398
+
399
+ async function copyComponentReadme() {
400
+ const components = componentDoc.components;
401
+
402
+ for (const component of components) {
403
+ const readmePath = path.join(__core, component.filePath, '..', 'readme.md');
404
+ const readme = await fs.readFile(readmePath, 'utf-8');
405
+
406
+ await fs.ensureDir(path.join(__autogeneratedPrompt, component.tag));
407
+
408
+ const htmlExampleMarkdown = await collectHTMLExamples(
409
+ __componentUsageByComponentJson,
410
+ __htmlTestAppRoot,
411
+ component.tag
412
+ );
413
+
414
+ const reactExampleMarkdown = await collectReactExamples(
415
+ __componentUsageByComponentJson,
416
+ __reactTestApp,
417
+ component.tag
418
+ );
419
+
420
+ const vueExampleMarkdown = await collectVueExamples(
421
+ __componentUsageByComponentJson,
422
+ __vueTestApp,
423
+ component.tag
424
+ );
425
+
426
+ const angularExampleMarkdown = await collectAngularExamples(
427
+ __componentUsageByComponentJson,
428
+ __angularTestApp,
429
+ component.tag
430
+ );
431
+
432
+ const angularStandaloneExampleMarkdown = await collectAngularExamples(
433
+ __componentUsageByComponentJson,
434
+ __angularStandaloneTestApp,
435
+ component.tag
436
+ );
437
+
438
+ const exampleMarkdown = [
439
+ `## HTML Examples\n\n${htmlExampleMarkdown}`,
440
+ `## React Examples\n\n${reactExampleMarkdown}`,
441
+ `## Vue Examples\n\n${vueExampleMarkdown}`,
442
+ `## Angular Examples\n\n${angularExampleMarkdown}`,
443
+ `## Angular Standalone Examples\n\n${angularStandaloneExampleMarkdown}`,
444
+ ].join('\n\n');
445
+
446
+ await fs.writeFile(
447
+ path.join(__autogeneratedPrompt, component.tag, 'readme.md'),
448
+ readme.replace(
449
+ `# ${component.tag}`,
450
+ `# ${component.tag}\n\n${exampleMarkdown}`
451
+ )
452
+ );
453
+ }
454
+ }
455
+
456
+ async function writeLibraryVersion() {
457
+ const pkgPath = path.join(__core, 'package.json');
458
+ const version = fs.readJSONSync(pkgPath).version;
459
+ await writeFile(
460
+ path.join(__autogenerated, 'version.json'),
461
+ JSON.stringify({ version })
462
+ );
463
+ }
464
+
465
+ (async () => {
466
+ await fs.remove(__autogenerated);
467
+ await fs.ensureDir(__autogenerated);
468
+ await fs.ensureDir(__autogeneratedUtils);
469
+
470
+ try {
471
+ const typeScriptDocsPromise = generateTypeScriptDocs(
472
+ [
473
+ path.join(
474
+ __root,
475
+ '..',
476
+ 'core',
477
+ 'src',
478
+ 'components',
479
+ 'utils',
480
+ 'modal',
481
+ 'modal.ts'
482
+ ),
483
+ path.join(
484
+ __root,
485
+ '..',
486
+ 'angular',
487
+ 'src',
488
+ 'providers',
489
+ 'modal',
490
+ 'modal.service.ts'
491
+ ),
492
+ path.join(
493
+ __root,
494
+ '..',
495
+ 'core',
496
+ 'src',
497
+ 'components',
498
+ 'toast',
499
+ 'toast-utils.ts'
500
+ ),
501
+ path.join(
502
+ __root,
503
+ '..',
504
+ 'angular',
505
+ 'src',
506
+ 'providers',
507
+ 'toast',
508
+ 'toast.service.ts'
509
+ ),
510
+ ],
511
+ __autogenerated
512
+ );
513
+ const mainTasksPromise = [
514
+ copyStaticFiles(),
515
+ copyUsage(),
516
+ copyStorybook(),
517
+ generatePlaygroundMarkdown(['form-validation']),
518
+ generateApiMarkdown(),
519
+ ];
520
+ await Promise.all([typeScriptDocsPromise, ...mainTasksPromise]);
521
+ await copyComponentReadme();
522
+ await writeLibraryVersion();
523
+ } catch (e: any) {
524
+ console.error(e.message);
525
+ process.exit(1);
526
+ }
527
+
528
+ console.log('All documentation generation tasks completed');
529
+ })();
@@ -0,0 +1,50 @@
1
+ import fs from 'fs-extra';
2
+ import {
3
+ collectExamplesForTag,
4
+ resolveExampleFile,
5
+ readIfExists,
6
+ sectionedExample,
7
+ } from './util';
8
+ import { removeTypescriptHeaderComments } from '../utils/escape';
9
+
10
+ export async function collectAngularExamples(
11
+ __componentUsageByComponentJson: string,
12
+ __angularTestAppRoot: string,
13
+ tag: string
14
+ ): Promise<string> {
15
+ return collectExamplesForTag(
16
+ __componentUsageByComponentJson,
17
+ tag,
18
+ async (exampleName) => {
19
+ // Mandatory .ts file
20
+ const tsFile = resolveExampleFile(
21
+ __angularTestAppRoot,
22
+ exampleName,
23
+ 'ts'
24
+ );
25
+ if (!fs.existsSync(tsFile)) {
26
+ console.warn(`Example file not found: ${tsFile}`);
27
+ return null;
28
+ }
29
+ const tsContent = await fs.readFile(tsFile, 'utf-8');
30
+
31
+ const htmlContent = await readIfExists(
32
+ resolveExampleFile(__angularTestAppRoot, exampleName, 'html')
33
+ );
34
+
35
+ const combined = sectionedExample([
36
+ {
37
+ heading: 'Component typescript',
38
+ lang: 'typescript',
39
+ code: tsContent,
40
+ },
41
+ { heading: 'Component template', lang: 'html', code: htmlContent },
42
+ ]);
43
+
44
+ return {
45
+ exampleName,
46
+ example: removeTypescriptHeaderComments(combined).trim(),
47
+ };
48
+ }
49
+ );
50
+ }
@@ -0,0 +1,29 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+ import { removeHTMLComments } from '../utils/escape';
4
+ import { collectExamplesForTag } from './util';
5
+
6
+ export async function collectHTMLExamples(
7
+ __componentUsageByComponentJson: string,
8
+ __htmlTestAppRoot: string,
9
+ tag: string
10
+ ): Promise<string> {
11
+ return collectExamplesForTag(
12
+ __componentUsageByComponentJson,
13
+ tag,
14
+ async (exampleName, relativeExamplePath) => {
15
+ const filePath = path.join(__htmlTestAppRoot, relativeExamplePath);
16
+ if (!fs.existsSync(filePath)) {
17
+ console.warn(`Example file not found: ${filePath}`);
18
+ return null;
19
+ }
20
+ const content = await fs.readFile(filePath, 'utf-8');
21
+ return {
22
+ exampleName,
23
+ example: ['```html', removeHTMLComments(content).trim(), '```'].join(
24
+ '\n'
25
+ ),
26
+ };
27
+ }
28
+ );
29
+ }
@@ -0,0 +1,33 @@
1
+ import fs from 'fs-extra';
2
+ import {
3
+ collectExamplesForTag,
4
+ resolveExampleFile,
5
+ } from './util';
6
+ import { removeTypescriptHeaderComments } from '../utils/escape';
7
+
8
+ export async function collectReactExamples(
9
+ __componentUsageByComponentJson: string,
10
+ __reactTestAppRoot: string,
11
+ tag: string
12
+ ): Promise<string> {
13
+ return collectExamplesForTag(
14
+ __componentUsageByComponentJson,
15
+ tag,
16
+ async (exampleName) => {
17
+ const tsxFile = resolveExampleFile(
18
+ __reactTestAppRoot,
19
+ exampleName,
20
+ 'tsx'
21
+ );
22
+ if (!fs.existsSync(tsxFile)) {
23
+ console.warn(`Example file not found: ${tsxFile}`);
24
+ return null;
25
+ }
26
+ const content = await fs.readFile(tsxFile, 'utf-8');
27
+ return {
28
+ exampleName,
29
+ example: ['```tsx', removeTypescriptHeaderComments(content).trim(), '```'].join('\n'),
30
+ };
31
+ }
32
+ );
33
+ }
@@ -0,0 +1,30 @@
1
+ import fs from 'fs-extra';
2
+ import { collectExamplesForTag, resolveExampleFile } from './util';
3
+ import { removeHTMLComments } from '../utils/escape';
4
+
5
+ export async function collectVueExamples(
6
+ __componentUsageByComponentJson: string,
7
+ __vueTestAppRoot: string,
8
+ tag: string
9
+ ): Promise<string> {
10
+ return collectExamplesForTag(
11
+ __componentUsageByComponentJson,
12
+ tag,
13
+ async (exampleName) => {
14
+ const vueFile = resolveExampleFile(
15
+ __vueTestAppRoot,
16
+ exampleName,
17
+ 'vue'
18
+ );
19
+ if (!fs.existsSync(vueFile)) {
20
+ console.warn(`Example file not found: ${vueFile}`);
21
+ return null;
22
+ }
23
+ const content = await fs.readFile(vueFile, 'utf-8');
24
+ return {
25
+ exampleName,
26
+ example: ['```tsx', removeHTMLComments(content).trim(), '```'].join('\n'),
27
+ };
28
+ }
29
+ );
30
+ }