@pressy-pub/components 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/dist/content/index.d.ts +41 -0
- package/dist/content/index.js +368 -0
- package/dist/content/index.js.map +1 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.js +2618 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as preact from 'preact';
|
|
2
|
+
import { ComponentChildren, ComponentType } from 'preact';
|
|
3
|
+
|
|
4
|
+
interface FootnoteProps {
|
|
5
|
+
id: string | number;
|
|
6
|
+
children: ComponentChildren;
|
|
7
|
+
}
|
|
8
|
+
declare function Footnote({ id, children }: FootnoteProps): preact.JSX.Element;
|
|
9
|
+
|
|
10
|
+
interface AsideProps {
|
|
11
|
+
children: ComponentChildren;
|
|
12
|
+
title?: string;
|
|
13
|
+
}
|
|
14
|
+
declare function Aside({ children, title }: AsideProps): preact.JSX.Element;
|
|
15
|
+
|
|
16
|
+
interface FigureProps {
|
|
17
|
+
src: string;
|
|
18
|
+
alt?: string;
|
|
19
|
+
caption?: string;
|
|
20
|
+
wide?: boolean;
|
|
21
|
+
children?: ComponentChildren;
|
|
22
|
+
}
|
|
23
|
+
declare function Figure({ src, alt, caption, wide, children }: FigureProps): preact.JSX.Element;
|
|
24
|
+
|
|
25
|
+
type CalloutType = 'note' | 'tip' | 'warning' | 'important';
|
|
26
|
+
interface CalloutProps {
|
|
27
|
+
type?: CalloutType;
|
|
28
|
+
title?: string;
|
|
29
|
+
children: ComponentChildren;
|
|
30
|
+
}
|
|
31
|
+
declare function Callout({ type, title, children }: CalloutProps): preact.JSX.Element;
|
|
32
|
+
|
|
33
|
+
interface SceneBreakProps {
|
|
34
|
+
variant?: 'asterisks' | 'line' | 'ornament';
|
|
35
|
+
}
|
|
36
|
+
declare function SceneBreak({ variant }: SceneBreakProps): preact.JSX.Element;
|
|
37
|
+
|
|
38
|
+
declare function setMDXComponents(components: Record<string, ComponentType<any>>): void;
|
|
39
|
+
declare function useMDXComponents(): Record<string, ComponentType<any>>;
|
|
40
|
+
|
|
41
|
+
export { Aside, Callout, Figure, Footnote, SceneBreak, setMDXComponents, useMDXComponents };
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
// src/content/Footnote.tsx
|
|
2
|
+
import { useSignal } from "@preact/signals";
|
|
3
|
+
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
4
|
+
function Footnote({ id, children }) {
|
|
5
|
+
const isOpen = useSignal(false);
|
|
6
|
+
return /* @__PURE__ */ jsxs("span", { class: "pressy-footnote-wrapper", children: [
|
|
7
|
+
/* @__PURE__ */ jsx(
|
|
8
|
+
"button",
|
|
9
|
+
{
|
|
10
|
+
class: "pressy-footnote-ref",
|
|
11
|
+
onClick: () => isOpen.value = !isOpen.value,
|
|
12
|
+
"aria-describedby": `footnote-${id}`,
|
|
13
|
+
"aria-expanded": isOpen.value,
|
|
14
|
+
children: id
|
|
15
|
+
}
|
|
16
|
+
),
|
|
17
|
+
isOpen.value && /* @__PURE__ */ jsxs("span", { class: "pressy-footnote-content", id: `footnote-${id}`, role: "tooltip", children: [
|
|
18
|
+
children,
|
|
19
|
+
/* @__PURE__ */ jsx(
|
|
20
|
+
"button",
|
|
21
|
+
{
|
|
22
|
+
class: "pressy-footnote-close",
|
|
23
|
+
onClick: () => isOpen.value = false,
|
|
24
|
+
"aria-label": "Close footnote",
|
|
25
|
+
children: "\xD7"
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
] }),
|
|
29
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
30
|
+
.pressy-footnote-wrapper {
|
|
31
|
+
position: relative;
|
|
32
|
+
display: inline;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.pressy-footnote-ref {
|
|
36
|
+
display: inline-flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
min-width: 1.25em;
|
|
40
|
+
height: 1.25em;
|
|
41
|
+
padding: 0 0.25em;
|
|
42
|
+
font-size: 0.75em;
|
|
43
|
+
font-weight: 600;
|
|
44
|
+
color: var(--color-accent);
|
|
45
|
+
background: var(--color-bg-subtle);
|
|
46
|
+
border: none;
|
|
47
|
+
border-radius: 0.25em;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
vertical-align: super;
|
|
50
|
+
line-height: 1;
|
|
51
|
+
transition: background 0.15s;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.pressy-footnote-ref:hover {
|
|
55
|
+
background: var(--color-bg-muted);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.pressy-footnote-content {
|
|
59
|
+
position: absolute;
|
|
60
|
+
bottom: calc(100% + 0.5em);
|
|
61
|
+
left: 0;
|
|
62
|
+
z-index: 30;
|
|
63
|
+
display: block;
|
|
64
|
+
padding: 0.5em 2em 0.5em 0.75em;
|
|
65
|
+
font-size: var(--font-size-sm);
|
|
66
|
+
background: var(--color-bg-subtle);
|
|
67
|
+
border-radius: 0.375em;
|
|
68
|
+
border: 1px solid var(--color-border);
|
|
69
|
+
width: 300px;
|
|
70
|
+
max-width: 80vw;
|
|
71
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.pressy-footnote-close {
|
|
75
|
+
position: absolute;
|
|
76
|
+
top: 0.25em;
|
|
77
|
+
right: 0.25em;
|
|
78
|
+
width: 1.5em;
|
|
79
|
+
height: 1.5em;
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
justify-content: center;
|
|
83
|
+
font-size: 1em;
|
|
84
|
+
color: var(--color-text-muted);
|
|
85
|
+
background: none;
|
|
86
|
+
border: none;
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
border-radius: 0.25em;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.pressy-footnote-close:hover {
|
|
92
|
+
background: var(--color-bg-muted);
|
|
93
|
+
color: var(--color-text);
|
|
94
|
+
}
|
|
95
|
+
` })
|
|
96
|
+
] });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/content/Aside.tsx
|
|
100
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
101
|
+
function Aside({ children, title }) {
|
|
102
|
+
return /* @__PURE__ */ jsxs2("aside", { class: "pressy-aside", children: [
|
|
103
|
+
title && /* @__PURE__ */ jsx2("strong", { class: "pressy-aside-title", children: title }),
|
|
104
|
+
/* @__PURE__ */ jsx2("div", { class: "pressy-aside-content", children }),
|
|
105
|
+
/* @__PURE__ */ jsx2("style", { children: `
|
|
106
|
+
.pressy-aside {
|
|
107
|
+
font-size: var(--font-size-sm);
|
|
108
|
+
color: var(--color-text-muted);
|
|
109
|
+
border-left: 3px solid var(--color-accent);
|
|
110
|
+
padding-left: 1em;
|
|
111
|
+
margin-block: 1.5em;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.pressy-aside-title {
|
|
115
|
+
display: block;
|
|
116
|
+
color: var(--color-heading);
|
|
117
|
+
margin-bottom: 0.5em;
|
|
118
|
+
font-weight: 600;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.pressy-aside-content {
|
|
122
|
+
line-height: 1.5;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.pressy-aside-content p:first-child {
|
|
126
|
+
margin-top: 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.pressy-aside-content p:last-child {
|
|
130
|
+
margin-bottom: 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@media (min-width: 80ch) {
|
|
134
|
+
.pressy-aside {
|
|
135
|
+
float: right;
|
|
136
|
+
width: 40%;
|
|
137
|
+
margin-left: 2em;
|
|
138
|
+
margin-right: calc(-1 * ((100vw - 65ch) / 4));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
` })
|
|
142
|
+
] });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/content/Figure.tsx
|
|
146
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
147
|
+
function Figure({ src, alt, caption, wide, children }) {
|
|
148
|
+
return /* @__PURE__ */ jsxs3("figure", { class: `pressy-figure ${wide ? "pressy-figure-wide" : ""}`, children: [
|
|
149
|
+
/* @__PURE__ */ jsx3("img", { src, alt: alt || caption || "", loading: "lazy", decoding: "async" }),
|
|
150
|
+
(caption || children) && /* @__PURE__ */ jsx3("figcaption", { class: "pressy-figure-caption", children: caption || children }),
|
|
151
|
+
/* @__PURE__ */ jsx3("style", { children: `
|
|
152
|
+
.pressy-figure {
|
|
153
|
+
margin-block: 2em;
|
|
154
|
+
margin-inline: 0;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.pressy-figure img {
|
|
158
|
+
width: 100%;
|
|
159
|
+
height: auto;
|
|
160
|
+
border-radius: 0.5em;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.pressy-figure-caption {
|
|
164
|
+
font-size: var(--font-size-sm);
|
|
165
|
+
color: var(--color-text-muted);
|
|
166
|
+
text-align: center;
|
|
167
|
+
margin-top: 0.75em;
|
|
168
|
+
font-style: italic;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.pressy-figure-wide {
|
|
172
|
+
margin-inline: 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@media (min-width: 80ch) {
|
|
176
|
+
.pressy-figure-wide {
|
|
177
|
+
margin-inline: calc(-1 * ((100vw - 65ch) / 4));
|
|
178
|
+
max-width: none;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
` })
|
|
182
|
+
] });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/content/Callout.tsx
|
|
186
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
187
|
+
var icons = {
|
|
188
|
+
note: "\u{1F4DD}",
|
|
189
|
+
tip: "\u{1F4A1}",
|
|
190
|
+
warning: "\u26A0\uFE0F",
|
|
191
|
+
important: "\u2757"
|
|
192
|
+
};
|
|
193
|
+
var defaultTitles = {
|
|
194
|
+
note: "Note",
|
|
195
|
+
tip: "Tip",
|
|
196
|
+
warning: "Warning",
|
|
197
|
+
important: "Important"
|
|
198
|
+
};
|
|
199
|
+
function Callout({ type = "note", title, children }) {
|
|
200
|
+
return /* @__PURE__ */ jsxs4("div", { class: `pressy-callout pressy-callout-${type}`, children: [
|
|
201
|
+
/* @__PURE__ */ jsxs4("div", { class: "pressy-callout-header", children: [
|
|
202
|
+
/* @__PURE__ */ jsx4("span", { class: "pressy-callout-icon", children: icons[type] }),
|
|
203
|
+
/* @__PURE__ */ jsx4("strong", { class: "pressy-callout-title", children: title || defaultTitles[type] })
|
|
204
|
+
] }),
|
|
205
|
+
/* @__PURE__ */ jsx4("div", { class: "pressy-callout-content", children }),
|
|
206
|
+
/* @__PURE__ */ jsx4("style", { children: `
|
|
207
|
+
.pressy-callout {
|
|
208
|
+
border-radius: 0.5em;
|
|
209
|
+
padding: 1em 1.25em;
|
|
210
|
+
margin-block: 1.5em;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.pressy-callout-note {
|
|
214
|
+
background: #eff6ff;
|
|
215
|
+
border: 1px solid #bfdbfe;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.pressy-callout-tip {
|
|
219
|
+
background: #f0fdf4;
|
|
220
|
+
border: 1px solid #bbf7d0;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.pressy-callout-warning {
|
|
224
|
+
background: #fffbeb;
|
|
225
|
+
border: 1px solid #fde68a;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.pressy-callout-important {
|
|
229
|
+
background: #fef2f2;
|
|
230
|
+
border: 1px solid #fecaca;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.pressy-callout-header {
|
|
234
|
+
display: flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
gap: 0.5em;
|
|
237
|
+
margin-bottom: 0.5em;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.pressy-callout-icon {
|
|
241
|
+
font-size: 1.25em;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.pressy-callout-title {
|
|
245
|
+
font-weight: 600;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.pressy-callout-content {
|
|
249
|
+
font-size: var(--font-size-sm);
|
|
250
|
+
line-height: 1.5;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.pressy-callout-content p:first-child {
|
|
254
|
+
margin-top: 0;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.pressy-callout-content p:last-child {
|
|
258
|
+
margin-bottom: 0;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* Dark mode adjustments */
|
|
262
|
+
@media (prefers-color-scheme: dark) {
|
|
263
|
+
.pressy-callout-note {
|
|
264
|
+
background: #1e3a5f;
|
|
265
|
+
border-color: #1e40af;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.pressy-callout-tip {
|
|
269
|
+
background: #052e16;
|
|
270
|
+
border-color: #166534;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.pressy-callout-warning {
|
|
274
|
+
background: #422006;
|
|
275
|
+
border-color: #854d0e;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.pressy-callout-important {
|
|
279
|
+
background: #450a0a;
|
|
280
|
+
border-color: #991b1b;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
[data-theme="dark"] .pressy-callout-note {
|
|
285
|
+
background: #1e3a5f;
|
|
286
|
+
border-color: #1e40af;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
[data-theme="dark"] .pressy-callout-tip {
|
|
290
|
+
background: #052e16;
|
|
291
|
+
border-color: #166534;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
[data-theme="dark"] .pressy-callout-warning {
|
|
295
|
+
background: #422006;
|
|
296
|
+
border-color: #854d0e;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
[data-theme="dark"] .pressy-callout-important {
|
|
300
|
+
background: #450a0a;
|
|
301
|
+
border-color: #991b1b;
|
|
302
|
+
}
|
|
303
|
+
` })
|
|
304
|
+
] });
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// src/content/SceneBreak.tsx
|
|
308
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
|
|
309
|
+
function SceneBreak({ variant = "asterisks" }) {
|
|
310
|
+
return /* @__PURE__ */ jsxs5("div", { class: `pressy-scene-break pressy-scene-break-${variant}`, role: "separator", children: [
|
|
311
|
+
variant === "asterisks" && /* @__PURE__ */ jsx5("span", { children: "* * *" }),
|
|
312
|
+
variant === "ornament" && /* @__PURE__ */ jsx5("span", { children: "\u2767" }),
|
|
313
|
+
/* @__PURE__ */ jsx5("style", { children: `
|
|
314
|
+
.pressy-scene-break {
|
|
315
|
+
display: flex;
|
|
316
|
+
align-items: center;
|
|
317
|
+
justify-content: center;
|
|
318
|
+
margin-block: 3em;
|
|
319
|
+
color: var(--color-text-muted);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.pressy-scene-break-asterisks span {
|
|
323
|
+
letter-spacing: 0.5em;
|
|
324
|
+
font-size: 1.25em;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.pressy-scene-break-line {
|
|
328
|
+
width: 100%;
|
|
329
|
+
max-width: 10ch;
|
|
330
|
+
height: 1px;
|
|
331
|
+
background: var(--color-border);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.pressy-scene-break-ornament span {
|
|
335
|
+
font-size: 1.5em;
|
|
336
|
+
}
|
|
337
|
+
` })
|
|
338
|
+
] });
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// src/content/index.ts
|
|
342
|
+
var defaultComponents = {
|
|
343
|
+
Footnote,
|
|
344
|
+
Aside,
|
|
345
|
+
Figure,
|
|
346
|
+
Callout,
|
|
347
|
+
SceneBreak,
|
|
348
|
+
// Override default elements
|
|
349
|
+
img: Figure,
|
|
350
|
+
hr: SceneBreak
|
|
351
|
+
};
|
|
352
|
+
var customComponents = {};
|
|
353
|
+
function setMDXComponents(components) {
|
|
354
|
+
customComponents = components;
|
|
355
|
+
}
|
|
356
|
+
function useMDXComponents() {
|
|
357
|
+
return { ...defaultComponents, ...customComponents };
|
|
358
|
+
}
|
|
359
|
+
export {
|
|
360
|
+
Aside,
|
|
361
|
+
Callout,
|
|
362
|
+
Figure,
|
|
363
|
+
Footnote,
|
|
364
|
+
SceneBreak,
|
|
365
|
+
setMDXComponents,
|
|
366
|
+
useMDXComponents
|
|
367
|
+
};
|
|
368
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/content/Footnote.tsx","../../src/content/Aside.tsx","../../src/content/Figure.tsx","../../src/content/Callout.tsx","../../src/content/SceneBreak.tsx","../../src/content/index.ts"],"sourcesContent":["import { ComponentChildren } from 'preact'\nimport { useSignal } from '@preact/signals'\n\ninterface FootnoteProps {\n id: string | number\n children: ComponentChildren\n}\n\nexport function Footnote({ id, children }: FootnoteProps) {\n const isOpen = useSignal(false)\n\n return (\n <span class=\"pressy-footnote-wrapper\">\n <button\n class=\"pressy-footnote-ref\"\n onClick={() => (isOpen.value = !isOpen.value)}\n aria-describedby={`footnote-${id}`}\n aria-expanded={isOpen.value}\n >\n {id}\n </button>\n\n {isOpen.value && (\n <span class=\"pressy-footnote-content\" id={`footnote-${id}`} role=\"tooltip\">\n {children}\n <button\n class=\"pressy-footnote-close\"\n onClick={() => (isOpen.value = false)}\n aria-label=\"Close footnote\"\n >\n ×\n </button>\n </span>\n )}\n\n <style>{`\n .pressy-footnote-wrapper {\n position: relative;\n display: inline;\n }\n\n .pressy-footnote-ref {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 1.25em;\n height: 1.25em;\n padding: 0 0.25em;\n font-size: 0.75em;\n font-weight: 600;\n color: var(--color-accent);\n background: var(--color-bg-subtle);\n border: none;\n border-radius: 0.25em;\n cursor: pointer;\n vertical-align: super;\n line-height: 1;\n transition: background 0.15s;\n }\n\n .pressy-footnote-ref:hover {\n background: var(--color-bg-muted);\n }\n\n .pressy-footnote-content {\n position: absolute;\n bottom: calc(100% + 0.5em);\n left: 0;\n z-index: 30;\n display: block;\n padding: 0.5em 2em 0.5em 0.75em;\n font-size: var(--font-size-sm);\n background: var(--color-bg-subtle);\n border-radius: 0.375em;\n border: 1px solid var(--color-border);\n width: 300px;\n max-width: 80vw;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n }\n\n .pressy-footnote-close {\n position: absolute;\n top: 0.25em;\n right: 0.25em;\n width: 1.5em;\n height: 1.5em;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1em;\n color: var(--color-text-muted);\n background: none;\n border: none;\n cursor: pointer;\n border-radius: 0.25em;\n }\n\n .pressy-footnote-close:hover {\n background: var(--color-bg-muted);\n color: var(--color-text);\n }\n `}</style>\n </span>\n )\n}\n","import { ComponentChildren } from 'preact'\n\ninterface AsideProps {\n children: ComponentChildren\n title?: string\n}\n\nexport function Aside({ children, title }: AsideProps) {\n return (\n <aside class=\"pressy-aside\">\n {title && <strong class=\"pressy-aside-title\">{title}</strong>}\n <div class=\"pressy-aside-content\">{children}</div>\n\n <style>{`\n .pressy-aside {\n font-size: var(--font-size-sm);\n color: var(--color-text-muted);\n border-left: 3px solid var(--color-accent);\n padding-left: 1em;\n margin-block: 1.5em;\n }\n\n .pressy-aside-title {\n display: block;\n color: var(--color-heading);\n margin-bottom: 0.5em;\n font-weight: 600;\n }\n\n .pressy-aside-content {\n line-height: 1.5;\n }\n\n .pressy-aside-content p:first-child {\n margin-top: 0;\n }\n\n .pressy-aside-content p:last-child {\n margin-bottom: 0;\n }\n\n @media (min-width: 80ch) {\n .pressy-aside {\n float: right;\n width: 40%;\n margin-left: 2em;\n margin-right: calc(-1 * ((100vw - 65ch) / 4));\n }\n }\n `}</style>\n </aside>\n )\n}\n","import { ComponentChildren } from 'preact'\n\ninterface FigureProps {\n src: string\n alt?: string\n caption?: string\n wide?: boolean\n children?: ComponentChildren\n}\n\nexport function Figure({ src, alt, caption, wide, children }: FigureProps) {\n return (\n <figure class={`pressy-figure ${wide ? 'pressy-figure-wide' : ''}`}>\n <img src={src} alt={alt || caption || ''} loading=\"lazy\" decoding=\"async\" />\n {(caption || children) && (\n <figcaption class=\"pressy-figure-caption\">{caption || children}</figcaption>\n )}\n\n <style>{`\n .pressy-figure {\n margin-block: 2em;\n margin-inline: 0;\n }\n\n .pressy-figure img {\n width: 100%;\n height: auto;\n border-radius: 0.5em;\n }\n\n .pressy-figure-caption {\n font-size: var(--font-size-sm);\n color: var(--color-text-muted);\n text-align: center;\n margin-top: 0.75em;\n font-style: italic;\n }\n\n .pressy-figure-wide {\n margin-inline: 0;\n }\n\n @media (min-width: 80ch) {\n .pressy-figure-wide {\n margin-inline: calc(-1 * ((100vw - 65ch) / 4));\n max-width: none;\n }\n }\n `}</style>\n </figure>\n )\n}\n","import { ComponentChildren } from 'preact'\n\ntype CalloutType = 'note' | 'tip' | 'warning' | 'important'\n\ninterface CalloutProps {\n type?: CalloutType\n title?: string\n children: ComponentChildren\n}\n\nconst icons: Record<CalloutType, string> = {\n note: '📝',\n tip: '💡',\n warning: '⚠️',\n important: '❗',\n}\n\nconst defaultTitles: Record<CalloutType, string> = {\n note: 'Note',\n tip: 'Tip',\n warning: 'Warning',\n important: 'Important',\n}\n\nexport function Callout({ type = 'note', title, children }: CalloutProps) {\n return (\n <div class={`pressy-callout pressy-callout-${type}`}>\n <div class=\"pressy-callout-header\">\n <span class=\"pressy-callout-icon\">{icons[type]}</span>\n <strong class=\"pressy-callout-title\">{title || defaultTitles[type]}</strong>\n </div>\n <div class=\"pressy-callout-content\">{children}</div>\n\n <style>{`\n .pressy-callout {\n border-radius: 0.5em;\n padding: 1em 1.25em;\n margin-block: 1.5em;\n }\n\n .pressy-callout-note {\n background: #eff6ff;\n border: 1px solid #bfdbfe;\n }\n\n .pressy-callout-tip {\n background: #f0fdf4;\n border: 1px solid #bbf7d0;\n }\n\n .pressy-callout-warning {\n background: #fffbeb;\n border: 1px solid #fde68a;\n }\n\n .pressy-callout-important {\n background: #fef2f2;\n border: 1px solid #fecaca;\n }\n\n .pressy-callout-header {\n display: flex;\n align-items: center;\n gap: 0.5em;\n margin-bottom: 0.5em;\n }\n\n .pressy-callout-icon {\n font-size: 1.25em;\n }\n\n .pressy-callout-title {\n font-weight: 600;\n }\n\n .pressy-callout-content {\n font-size: var(--font-size-sm);\n line-height: 1.5;\n }\n\n .pressy-callout-content p:first-child {\n margin-top: 0;\n }\n\n .pressy-callout-content p:last-child {\n margin-bottom: 0;\n }\n\n /* Dark mode adjustments */\n @media (prefers-color-scheme: dark) {\n .pressy-callout-note {\n background: #1e3a5f;\n border-color: #1e40af;\n }\n\n .pressy-callout-tip {\n background: #052e16;\n border-color: #166534;\n }\n\n .pressy-callout-warning {\n background: #422006;\n border-color: #854d0e;\n }\n\n .pressy-callout-important {\n background: #450a0a;\n border-color: #991b1b;\n }\n }\n\n [data-theme=\"dark\"] .pressy-callout-note {\n background: #1e3a5f;\n border-color: #1e40af;\n }\n\n [data-theme=\"dark\"] .pressy-callout-tip {\n background: #052e16;\n border-color: #166534;\n }\n\n [data-theme=\"dark\"] .pressy-callout-warning {\n background: #422006;\n border-color: #854d0e;\n }\n\n [data-theme=\"dark\"] .pressy-callout-important {\n background: #450a0a;\n border-color: #991b1b;\n }\n `}</style>\n </div>\n )\n}\n","interface SceneBreakProps {\n variant?: 'asterisks' | 'line' | 'ornament'\n}\n\nexport function SceneBreak({ variant = 'asterisks' }: SceneBreakProps) {\n return (\n <div class={`pressy-scene-break pressy-scene-break-${variant}`} role=\"separator\">\n {variant === 'asterisks' && <span>* * *</span>}\n {variant === 'ornament' && <span>❧</span>}\n\n <style>{`\n .pressy-scene-break {\n display: flex;\n align-items: center;\n justify-content: center;\n margin-block: 3em;\n color: var(--color-text-muted);\n }\n\n .pressy-scene-break-asterisks span {\n letter-spacing: 0.5em;\n font-size: 1.25em;\n }\n\n .pressy-scene-break-line {\n width: 100%;\n max-width: 10ch;\n height: 1px;\n background: var(--color-border);\n }\n\n .pressy-scene-break-ornament span {\n font-size: 1.5em;\n }\n `}</style>\n </div>\n )\n}\n","import { ComponentType, ComponentChildren } from 'preact'\nimport { Footnote } from './Footnote.js'\nimport { Aside } from './Aside.js'\nimport { Figure } from './Figure.js'\nimport { Callout } from './Callout.js'\nimport { SceneBreak } from './SceneBreak.js'\n\nexport { Footnote } from './Footnote.js'\nexport { Aside } from './Aside.js'\nexport { Figure } from './Figure.js'\nexport { Callout } from './Callout.js'\nexport { SceneBreak } from './SceneBreak.js'\n\n// MDX components provider\nconst defaultComponents: Record<string, ComponentType<any>> = {\n Footnote,\n Aside,\n Figure,\n Callout,\n SceneBreak,\n // Override default elements\n img: Figure,\n hr: SceneBreak,\n}\n\nlet customComponents: Record<string, ComponentType<any>> = {}\n\nexport function setMDXComponents(components: Record<string, ComponentType<any>>) {\n customComponents = components\n}\n\nexport function useMDXComponents(): Record<string, ComponentType<any>> {\n return { ...defaultComponents, ...customComponents }\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import * as preact from 'preact';
|
|
2
|
+
import { ComponentType, ComponentChildren } from 'preact';
|
|
3
|
+
|
|
4
|
+
interface ProgressData {
|
|
5
|
+
page: number;
|
|
6
|
+
totalPages: number;
|
|
7
|
+
scrollPosition: number;
|
|
8
|
+
}
|
|
9
|
+
interface ChapterMapData {
|
|
10
|
+
chapterMap: Record<string, () => Promise<{
|
|
11
|
+
default: ComponentType<{
|
|
12
|
+
components?: Record<string, unknown>;
|
|
13
|
+
}>;
|
|
14
|
+
}>>;
|
|
15
|
+
chapterOrder: string[];
|
|
16
|
+
}
|
|
17
|
+
interface ReaderProps {
|
|
18
|
+
children: ComponentChildren;
|
|
19
|
+
title: string;
|
|
20
|
+
bookTitle?: string;
|
|
21
|
+
chapterSlug?: string;
|
|
22
|
+
prevChapter?: {
|
|
23
|
+
slug: string;
|
|
24
|
+
title: string;
|
|
25
|
+
};
|
|
26
|
+
nextChapter?: {
|
|
27
|
+
slug: string;
|
|
28
|
+
title: string;
|
|
29
|
+
};
|
|
30
|
+
showDropCap?: boolean;
|
|
31
|
+
paginationMode?: "scroll" | "paginated";
|
|
32
|
+
onSaveProgress?: (data: ProgressData) => void;
|
|
33
|
+
onRestoreProgress?: () => Promise<ProgressData | null>;
|
|
34
|
+
bookProgressPercent?: number;
|
|
35
|
+
initialContent?: ComponentType<{
|
|
36
|
+
components?: Record<string, unknown>;
|
|
37
|
+
}>;
|
|
38
|
+
chapterMapData?: ChapterMapData;
|
|
39
|
+
currentChapterSlug?: string;
|
|
40
|
+
allChapters?: Array<{
|
|
41
|
+
slug: string;
|
|
42
|
+
title: string;
|
|
43
|
+
wordCount?: number;
|
|
44
|
+
}>;
|
|
45
|
+
bookBasePath?: string;
|
|
46
|
+
onChapterChange?: (slug: string, page: number, totalPages: number) => void;
|
|
47
|
+
mdxComponents?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
declare function Reader({ children, bookTitle, prevChapter, nextChapter, showDropCap, paginationMode, onSaveProgress, onRestoreProgress, bookProgressPercent, initialContent, chapterMapData, currentChapterSlug, allChapters, bookBasePath, onChapterChange, mdxComponents, }: ReaderProps): preact.JSX.Element;
|
|
50
|
+
|
|
51
|
+
interface NavigationProps {
|
|
52
|
+
prev?: {
|
|
53
|
+
slug: string;
|
|
54
|
+
title: string;
|
|
55
|
+
};
|
|
56
|
+
next?: {
|
|
57
|
+
slug: string;
|
|
58
|
+
title: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
declare function Navigation({ prev, next }: NavigationProps): preact.JSX.Element | null;
|
|
62
|
+
|
|
63
|
+
interface TOCItem {
|
|
64
|
+
level: number;
|
|
65
|
+
text: string;
|
|
66
|
+
slug: string;
|
|
67
|
+
}
|
|
68
|
+
interface TableOfContentsProps {
|
|
69
|
+
items: TOCItem[];
|
|
70
|
+
onNavigate?: () => void;
|
|
71
|
+
activeSlug?: string;
|
|
72
|
+
}
|
|
73
|
+
declare function TableOfContents({ items, onNavigate, activeSlug }: TableOfContentsProps): preact.JSX.Element;
|
|
74
|
+
|
|
75
|
+
declare function TextShare(): preact.JSX.Element | null;
|
|
76
|
+
|
|
77
|
+
interface PaywallProps {
|
|
78
|
+
bookSlug: string;
|
|
79
|
+
bookTitle: string;
|
|
80
|
+
previewChapters: number;
|
|
81
|
+
currentChapter: number;
|
|
82
|
+
shopifyProductId?: string;
|
|
83
|
+
mode?: 'shopify' | 'email';
|
|
84
|
+
onUnlock?: () => void;
|
|
85
|
+
}
|
|
86
|
+
declare function Paywall({ bookSlug, bookTitle, previewChapters, currentChapter, shopifyProductId, mode, onUnlock, }: PaywallProps): preact.JSX.Element | null;
|
|
87
|
+
|
|
88
|
+
declare function ThemeSwitcher(): preact.JSX.Element;
|
|
89
|
+
|
|
90
|
+
declare function OfflineIndicator(): preact.JSX.Element | null;
|
|
91
|
+
|
|
92
|
+
interface DownloadBookProps {
|
|
93
|
+
bookSlug: string;
|
|
94
|
+
chapterUrls: string[];
|
|
95
|
+
/** Reactive signal: set of cached book slugs */
|
|
96
|
+
cachedBooks: {
|
|
97
|
+
value: Set<string>;
|
|
98
|
+
};
|
|
99
|
+
/** Reactive signal: current download progress or null */
|
|
100
|
+
cacheProgress: {
|
|
101
|
+
value: {
|
|
102
|
+
bookSlug: string;
|
|
103
|
+
current: number;
|
|
104
|
+
total: number;
|
|
105
|
+
} | null;
|
|
106
|
+
};
|
|
107
|
+
/** Called to start downloading the book */
|
|
108
|
+
onDownload: (bookSlug: string, chapterUrls: string[]) => void;
|
|
109
|
+
/** Called to remove the cached book */
|
|
110
|
+
onRemove: (bookSlug: string) => void;
|
|
111
|
+
}
|
|
112
|
+
declare function DownloadBook({ bookSlug, chapterUrls, cachedBooks, cacheProgress, onDownload, onRemove, }: DownloadBookProps): preact.JSX.Element;
|
|
113
|
+
|
|
114
|
+
interface BookProgressProps {
|
|
115
|
+
bookSlug: string;
|
|
116
|
+
chapters: Array<{
|
|
117
|
+
slug: string;
|
|
118
|
+
title: string;
|
|
119
|
+
order: number;
|
|
120
|
+
wordCount?: number;
|
|
121
|
+
}>;
|
|
122
|
+
basePath: string;
|
|
123
|
+
loadAllProgress: () => Promise<Array<{
|
|
124
|
+
chapterSlug: string;
|
|
125
|
+
page: number;
|
|
126
|
+
totalPages: number;
|
|
127
|
+
}>>;
|
|
128
|
+
}
|
|
129
|
+
declare function BookProgress({ chapters, basePath, bookSlug, loadAllProgress, }: BookProgressProps): preact.JSX.Element;
|
|
130
|
+
|
|
131
|
+
export { BookProgress, type BookProgressProps, type ChapterMapData, DownloadBook, type DownloadBookProps, Navigation, type NavigationProps, OfflineIndicator, Paywall, type PaywallProps, type ProgressData, Reader, type ReaderProps, type TOCItem, TableOfContents, type TableOfContentsProps, TextShare, ThemeSwitcher };
|