@beatzball/create-litro 0.3.0 → 0.4.1
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 +19 -0
- package/LICENSE +78 -62
- package/dist/recipes/starlight/template/package.json +1 -0
- package/dist/recipes/starlight/template/pages/docs/[slug].ts +75 -2
- package/dist/recipes/starlight/template/public/styles/highlight.css +108 -0
- package/dist/recipes/starlight/template/src/components/starlight-header.ts +125 -29
- package/dist/recipes/starlight/template/src/components/starlight-page.ts +48 -4
- package/dist/recipes/starlight/template/src/highlight.ts +40 -0
- package/dist/recipes/starlight/template/src/route-meta.ts +1 -0
- package/package.json +16 -2
- package/recipes/starlight/template/package.json +1 -0
- package/recipes/starlight/template/pages/docs/[slug].ts +75 -2
- package/recipes/starlight/template/public/styles/highlight.css +108 -0
- package/recipes/starlight/template/src/components/starlight-header.ts +125 -29
- package/recipes/starlight/template/src/components/starlight-page.ts +48 -4
- package/recipes/starlight/template/src/highlight.ts +40 -0
- package/recipes/starlight/template/src/route-meta.ts +1 -0
|
@@ -36,6 +36,7 @@ export class StarlightPage extends LitElement {
|
|
|
36
36
|
currentSlug: { type: String },
|
|
37
37
|
currentPath: { type: String },
|
|
38
38
|
noSidebar: { type: Boolean },
|
|
39
|
+
_navOpen: { state: true },
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
static override styles = css`
|
|
@@ -102,6 +103,14 @@ export class StarlightPage extends LitElement {
|
|
|
102
103
|
line-height: 1.15;
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
.nav-backdrop {
|
|
107
|
+
position: fixed;
|
|
108
|
+
inset: 0;
|
|
109
|
+
top: var(--sl-nav-height, 3.5rem);
|
|
110
|
+
background: rgba(0, 0, 0, 0.4);
|
|
111
|
+
z-index: 49;
|
|
112
|
+
}
|
|
113
|
+
|
|
105
114
|
/* Responsive: hide sidebar and TOC on narrow screens */
|
|
106
115
|
@media (max-width: 72rem) {
|
|
107
116
|
.body {
|
|
@@ -110,7 +119,20 @@ export class StarlightPage extends LitElement {
|
|
|
110
119
|
}
|
|
111
120
|
|
|
112
121
|
.sidebar-wrap {
|
|
113
|
-
|
|
122
|
+
grid-area: unset;
|
|
123
|
+
position: fixed;
|
|
124
|
+
top: var(--sl-nav-height, 3.5rem);
|
|
125
|
+
left: 0;
|
|
126
|
+
z-index: 50;
|
|
127
|
+
height: calc(100vh - var(--sl-nav-height, 3.5rem));
|
|
128
|
+
width: var(--sl-sidebar-width, 16rem);
|
|
129
|
+
transform: translateX(-100%);
|
|
130
|
+
transition: transform 0.2s ease;
|
|
131
|
+
box-shadow: 2px 0 16px rgba(0, 0, 0, 0.12);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.sidebar-wrap.nav-open {
|
|
135
|
+
transform: translateX(0);
|
|
114
136
|
}
|
|
115
137
|
}
|
|
116
138
|
|
|
@@ -134,18 +156,40 @@ export class StarlightPage extends LitElement {
|
|
|
134
156
|
currentSlug = '';
|
|
135
157
|
currentPath = '';
|
|
136
158
|
noSidebar = false;
|
|
159
|
+
_navOpen = false;
|
|
160
|
+
|
|
161
|
+
override updated(changed: Map<string, unknown>) {
|
|
162
|
+
if (changed.has('currentPath') && this._navOpen) {
|
|
163
|
+
this._navOpen = false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private _handleNavToggle() {
|
|
168
|
+
this._navOpen = !this._navOpen;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private _closeNav() {
|
|
172
|
+
this._navOpen = false;
|
|
173
|
+
}
|
|
137
174
|
|
|
138
175
|
override render() {
|
|
176
|
+
const hasSidebar = !this.noSidebar;
|
|
139
177
|
return html`
|
|
140
178
|
<div class="page-wrap">
|
|
141
179
|
<starlight-header
|
|
142
180
|
siteTitle="${this.siteTitle}"
|
|
143
181
|
.nav="${this.nav}"
|
|
144
182
|
currentPath="${this.currentPath}"
|
|
183
|
+
.navOpen="${this._navOpen}"
|
|
184
|
+
.hasSidebar="${hasSidebar}"
|
|
185
|
+
@sl-nav-toggle="${this._handleNavToggle}"
|
|
145
186
|
></starlight-header>
|
|
187
|
+
${hasSidebar && this._navOpen ? html`
|
|
188
|
+
<div class="nav-backdrop" @click="${this._closeNav}"></div>
|
|
189
|
+
` : ''}
|
|
146
190
|
<div class="body${this.noSidebar ? ' no-sidebar' : ''}">
|
|
147
|
-
${
|
|
148
|
-
<aside class="sidebar-wrap">
|
|
191
|
+
${hasSidebar ? html`
|
|
192
|
+
<aside class="sidebar-wrap${this._navOpen ? ' nav-open' : ''}">
|
|
149
193
|
<starlight-sidebar
|
|
150
194
|
.groups="${this.sidebar}"
|
|
151
195
|
currentSlug="${this.currentSlug}"
|
|
@@ -158,7 +202,7 @@ export class StarlightPage extends LitElement {
|
|
|
158
202
|
<slot name="content"></slot>
|
|
159
203
|
</div>
|
|
160
204
|
</main>
|
|
161
|
-
${
|
|
205
|
+
${hasSidebar ? html`
|
|
162
206
|
<aside class="toc-wrap">
|
|
163
207
|
<starlight-toc .entries="${this.toc}"></starlight-toc>
|
|
164
208
|
</aside>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import hljs from 'highlight.js';
|
|
2
|
+
|
|
3
|
+
const NAMED_ENTITY_MAP: Record<string, string> = {
|
|
4
|
+
'&': '&',
|
|
5
|
+
'<': '<',
|
|
6
|
+
'>': '>',
|
|
7
|
+
'"': '"',
|
|
8
|
+
''': "'",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function decodeEntities(str: string): string {
|
|
12
|
+
return str.replace(/&#x[0-9a-fA-F]+;|&#[0-9]+;|&|<|>|"|'/g, m => {
|
|
13
|
+
if (m.startsWith('&#x')) return String.fromCodePoint(parseInt(m.slice(3, -1), 16));
|
|
14
|
+
if (m.startsWith('&#')) return String.fromCodePoint(parseInt(m.slice(2, -1), 10));
|
|
15
|
+
return NAMED_ENTITY_MAP[m]!;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Post-processes an HTML string, replacing every
|
|
21
|
+
* <pre><code class="language-*">…</code></pre>
|
|
22
|
+
* with a syntax-highlighted version produced by highlight.js.
|
|
23
|
+
*
|
|
24
|
+
* Must be called server-side only (SSG build time).
|
|
25
|
+
*/
|
|
26
|
+
export function applyHighlighting(html: string): string {
|
|
27
|
+
return html.replace(
|
|
28
|
+
/<pre><code class="language-([^"]+)">([\s\S]*?)<\/code><\/pre>/g,
|
|
29
|
+
(_match, lang: string, encoded: string) => {
|
|
30
|
+
const code = decodeEntities(encoded);
|
|
31
|
+
let highlighted: string;
|
|
32
|
+
try {
|
|
33
|
+
highlighted = hljs.highlight(code, { language: lang, ignoreIllegals: true }).value;
|
|
34
|
+
} catch {
|
|
35
|
+
highlighted = hljs.highlightAuto(code).value;
|
|
36
|
+
}
|
|
37
|
+
return `<pre><code class="hljs language-${lang}">${highlighted}</code></pre>`;
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export const starlightHead = [
|
|
11
11
|
'<link rel="stylesheet" href="/shoelace/themes/light.css" />',
|
|
12
12
|
'<link rel="stylesheet" href="/styles/starlight.css" />',
|
|
13
|
+
'<link rel="stylesheet" href="/styles/highlight.css" />',
|
|
13
14
|
'<script>(function(){',
|
|
14
15
|
'var s=localStorage.getItem("sl-theme");',
|
|
15
16
|
'var t=s||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light");',
|