@pure-ds/storybook 0.4.6 → 0.4.7
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/preview.js
CHANGED
|
@@ -287,7 +287,7 @@ const withGlobalsHandler = (story, context) => {
|
|
|
287
287
|
const DEFAULT_STORY_TAGS = new Set(['dev', 'test', 'story', 'stories', 'autodocs', 'example', 'examples']);
|
|
288
288
|
|
|
289
289
|
const TAG_SYNONYMS = new Map([
|
|
290
|
-
['padding', 'spacing'],
|
|
290
|
+
['padding', 'spacing', 'space'],
|
|
291
291
|
['gap', 'spacing'],
|
|
292
292
|
['grid', 'layout'],
|
|
293
293
|
['flex', 'layout'],
|
package/.storybook/shiki.js
CHANGED
|
@@ -1,105 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared Shiki syntax highlighter for PDS Storybook
|
|
3
3
|
* Provides consistent code highlighting across all stories and previews
|
|
4
|
+
*
|
|
5
|
+
* Re-exports from stories/utils/shiki.js to maintain a single source of truth
|
|
4
6
|
*/
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
export async function loadShiki() {
|
|
15
|
-
if (shikiInstance) return shikiInstance;
|
|
16
|
-
|
|
17
|
-
if (shikiLoading) {
|
|
18
|
-
return shikiLoadPromise;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
shikiLoading = true;
|
|
22
|
-
shikiLoadPromise = (async () => {
|
|
23
|
-
try {
|
|
24
|
-
const shiki = await import('https://esm.sh/shiki@1.0.0');
|
|
25
|
-
shikiInstance = await shiki.getHighlighter({
|
|
26
|
-
themes: ['github-dark', 'github-light'],
|
|
27
|
-
langs: ['html', 'css', 'javascript', 'typescript', 'json', 'bash', 'shell']
|
|
28
|
-
});
|
|
29
|
-
return shikiInstance;
|
|
30
|
-
} catch (error) {
|
|
31
|
-
console.error('Failed to load Shiki:', error);
|
|
32
|
-
return null;
|
|
33
|
-
} finally {
|
|
34
|
-
shikiLoading = false;
|
|
35
|
-
}
|
|
36
|
-
})();
|
|
37
|
-
|
|
38
|
-
return shikiLoadPromise;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Highlight code with Shiki
|
|
43
|
-
* @param {string} code - The code to highlight
|
|
44
|
-
* @param {string} lang - The language (html, css, js, json, etc.)
|
|
45
|
-
* @param {string} theme - The theme to use (github-dark or github-light)
|
|
46
|
-
* @returns {Promise<string>} - Highlighted HTML
|
|
47
|
-
*/
|
|
48
|
-
export async function highlight(code, lang = 'html', theme = 'github-dark') {
|
|
49
|
-
const highlighter = await loadShiki();
|
|
50
|
-
|
|
51
|
-
if (!highlighter) {
|
|
52
|
-
return escapeHtml(code);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
// Map common aliases
|
|
57
|
-
const langMap = {
|
|
58
|
-
'js': 'javascript',
|
|
59
|
-
'ts': 'typescript',
|
|
60
|
-
'sh': 'shell'
|
|
61
|
-
};
|
|
62
|
-
const resolvedLang = langMap[lang] || lang;
|
|
63
|
-
|
|
64
|
-
const html = highlighter.codeToHtml(code, {
|
|
65
|
-
lang: resolvedLang,
|
|
66
|
-
theme
|
|
67
|
-
});
|
|
68
|
-
return html;
|
|
69
|
-
} catch (error) {
|
|
70
|
-
console.error('Shiki highlighting failed:', error);
|
|
71
|
-
return `<pre><code>${escapeHtml(code)}</code></pre>`;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Get the current theme based on document/storybook theme
|
|
77
|
-
* @returns {string}
|
|
78
|
-
*/
|
|
79
|
-
export function getCurrentTheme() {
|
|
80
|
-
const isDark = document.documentElement.getAttribute('data-theme') === 'dark' ||
|
|
81
|
-
document.body.classList.contains('dark') ||
|
|
82
|
-
window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
83
|
-
return isDark ? 'github-dark' : 'github-light';
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Escape HTML special characters
|
|
88
|
-
* @param {string} text
|
|
89
|
-
* @returns {string}
|
|
90
|
-
*/
|
|
91
|
-
export function escapeHtml(text) {
|
|
92
|
-
return text
|
|
93
|
-
.replace(/&/g, '&')
|
|
94
|
-
.replace(/</g, '<')
|
|
95
|
-
.replace(/>/g, '>')
|
|
96
|
-
.replace(/"/g, '"')
|
|
97
|
-
.replace(/'/g, ''');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Pre-load Shiki in the background for faster first highlight
|
|
102
|
-
*/
|
|
103
|
-
export function preloadShiki() {
|
|
104
|
-
loadShiki();
|
|
105
|
-
}
|
|
8
|
+
export {
|
|
9
|
+
loadShiki,
|
|
10
|
+
highlight,
|
|
11
|
+
getCurrentTheme,
|
|
12
|
+
escapeHtml,
|
|
13
|
+
preloadShiki
|
|
14
|
+
} from '../stories/utils/shiki.js';
|
package/dist/pds-reference.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pure-ds/storybook",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"description": "Storybook showcase for Pure Design System with live configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"storybook:build": "npm run build-storybook"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@pure-ds/core": "^0.4.
|
|
38
|
+
"@pure-ds/core": "^0.4.7"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@custom-elements-manifest/analyzer": "^0.11.0",
|
|
@@ -3,7 +3,7 @@ import { addons } from '@storybook/preview-api';
|
|
|
3
3
|
import { SELECT_STORY } from '@storybook/core-events';
|
|
4
4
|
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
|
5
5
|
import showdown from 'showdown';
|
|
6
|
-
import { highlight as shikiHighlight, escapeHtml as shikiEscapeHtml } from '
|
|
6
|
+
import { highlight as shikiHighlight, escapeHtml as shikiEscapeHtml } from '../utils/shiki.js';
|
|
7
7
|
|
|
8
8
|
const REF_HELPER_STYLE_ID = 'pds-reference-helper-styles';
|
|
9
9
|
const REF_HELPER_STYLE_CONTENT = `
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import Showdown from 'showdown';
|
|
7
|
-
import { loadShiki, highlight, getCurrentTheme, escapeHtml, preloadShiki } from '
|
|
7
|
+
import { loadShiki, highlight, getCurrentTheme, escapeHtml, preloadShiki } from './shiki.js';
|
|
8
8
|
|
|
9
9
|
// Pre-load Shiki in background
|
|
10
10
|
preloadShiki();
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Shiki syntax highlighter for PDS Storybook stories
|
|
3
|
+
* Provides consistent code highlighting across all stories
|
|
4
|
+
*
|
|
5
|
+
* This file is located within the stories folder so it remains available
|
|
6
|
+
* when stories are copied or cached to other locations.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
let shikiInstance = null;
|
|
10
|
+
let shikiLoading = false;
|
|
11
|
+
let shikiLoadPromise = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Load and initialize Shiki highlighter
|
|
15
|
+
* @returns {Promise<import('shiki').Highlighter|null>}
|
|
16
|
+
*/
|
|
17
|
+
export async function loadShiki() {
|
|
18
|
+
if (shikiInstance) return shikiInstance;
|
|
19
|
+
|
|
20
|
+
if (shikiLoading) {
|
|
21
|
+
return shikiLoadPromise;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
shikiLoading = true;
|
|
25
|
+
shikiLoadPromise = (async () => {
|
|
26
|
+
try {
|
|
27
|
+
const shiki = await import('https://esm.sh/shiki@1.0.0');
|
|
28
|
+
shikiInstance = await shiki.getHighlighter({
|
|
29
|
+
themes: ['github-dark', 'github-light'],
|
|
30
|
+
langs: ['html', 'css', 'javascript', 'typescript', 'json', 'bash', 'shell']
|
|
31
|
+
});
|
|
32
|
+
return shikiInstance;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error('Failed to load Shiki:', error);
|
|
35
|
+
return null;
|
|
36
|
+
} finally {
|
|
37
|
+
shikiLoading = false;
|
|
38
|
+
}
|
|
39
|
+
})();
|
|
40
|
+
|
|
41
|
+
return shikiLoadPromise;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Highlight code with Shiki
|
|
46
|
+
* @param {string} code - The code to highlight
|
|
47
|
+
* @param {string} lang - The language (html, css, js, json, etc.)
|
|
48
|
+
* @param {string} theme - The theme to use (github-dark or github-light)
|
|
49
|
+
* @returns {Promise<string>} - Highlighted HTML
|
|
50
|
+
*/
|
|
51
|
+
export async function highlight(code, lang = 'html', theme = 'github-dark') {
|
|
52
|
+
const highlighter = await loadShiki();
|
|
53
|
+
|
|
54
|
+
if (!highlighter) {
|
|
55
|
+
return escapeHtml(code);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// Map common aliases
|
|
60
|
+
const langMap = {
|
|
61
|
+
'js': 'javascript',
|
|
62
|
+
'ts': 'typescript',
|
|
63
|
+
'sh': 'shell'
|
|
64
|
+
};
|
|
65
|
+
const resolvedLang = langMap[lang] || lang;
|
|
66
|
+
|
|
67
|
+
const html = highlighter.codeToHtml(code, {
|
|
68
|
+
lang: resolvedLang,
|
|
69
|
+
theme
|
|
70
|
+
});
|
|
71
|
+
return html;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('Shiki highlighting failed:', error);
|
|
74
|
+
return `<pre><code>${escapeHtml(code)}</code></pre>`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get the current theme based on document/storybook theme
|
|
80
|
+
* @returns {string}
|
|
81
|
+
*/
|
|
82
|
+
export function getCurrentTheme() {
|
|
83
|
+
const isDark = document.documentElement.getAttribute('data-theme') === 'dark' ||
|
|
84
|
+
document.body.classList.contains('dark') ||
|
|
85
|
+
window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
86
|
+
return isDark ? 'github-dark' : 'github-light';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Escape HTML special characters
|
|
91
|
+
* @param {string} text
|
|
92
|
+
* @returns {string}
|
|
93
|
+
*/
|
|
94
|
+
export function escapeHtml(text) {
|
|
95
|
+
return text
|
|
96
|
+
.replace(/&/g, '&')
|
|
97
|
+
.replace(/</g, '<')
|
|
98
|
+
.replace(/>/g, '>')
|
|
99
|
+
.replace(/"/g, '"')
|
|
100
|
+
.replace(/'/g, ''');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Pre-load Shiki in the background for faster first highlight
|
|
105
|
+
*/
|
|
106
|
+
export function preloadShiki() {
|
|
107
|
+
loadShiki();
|
|
108
|
+
}
|