@ps1ui/core 0.0.0 → 0.0.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.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/dist/base.css +378 -0
  3. package/dist/components/Anchor/Anchor.d.mts +12 -0
  4. package/dist/components/Anchor/Anchor.mjs +15 -0
  5. package/dist/components/Anchor/Anchor.mjs.map +1 -0
  6. package/dist/components/Button/Button.d.mts +24 -0
  7. package/dist/components/Button/Button.mjs +17 -0
  8. package/dist/components/Button/Button.mjs.map +1 -0
  9. package/dist/components/Card/Card.d.mts +7 -0
  10. package/dist/components/Card/Card.mjs +14 -0
  11. package/dist/components/Card/Card.mjs.map +1 -0
  12. package/dist/components/Checkbox/Checkbox.d.mts +9 -0
  13. package/dist/components/Checkbox/Checkbox.mjs +23 -0
  14. package/dist/components/Checkbox/Checkbox.mjs.map +1 -0
  15. package/dist/components/Code/Code.d.mts +7 -0
  16. package/dist/components/Code/Code.mjs +14 -0
  17. package/dist/components/Code/Code.mjs.map +1 -0
  18. package/dist/components/CodeBlock/CodeBlock.d.mts +12 -0
  19. package/dist/components/CodeBlock/CodeBlock.mjs +44 -0
  20. package/dist/components/CodeBlock/CodeBlock.mjs.map +1 -0
  21. package/dist/components/CodeBlock/refractor.d.mts +7 -0
  22. package/dist/components/CodeBlock/refractor.mjs +26 -0
  23. package/dist/components/CodeBlock/refractor.mjs.map +1 -0
  24. package/dist/components/Container/Container.d.mts +13 -0
  25. package/dist/components/Container/Container.mjs +24 -0
  26. package/dist/components/Container/Container.mjs.map +1 -0
  27. package/dist/components/Details/Details.d.mts +9 -0
  28. package/dist/components/Details/Details.mjs +20 -0
  29. package/dist/components/Details/Details.mjs.map +1 -0
  30. package/dist/components/Grid/Grid.d.mts +13 -0
  31. package/dist/components/Grid/Grid.mjs +24 -0
  32. package/dist/components/Grid/Grid.mjs.map +1 -0
  33. package/dist/components/GridItem/GridItem.d.mts +10 -0
  34. package/dist/components/GridItem/GridItem.mjs +21 -0
  35. package/dist/components/GridItem/GridItem.mjs.map +1 -0
  36. package/dist/components/Heading/Heading.d.mts +22 -0
  37. package/dist/components/Heading/Heading.mjs +53 -0
  38. package/dist/components/Heading/Heading.mjs.map +1 -0
  39. package/dist/components/Input/Input.d.mts +7 -0
  40. package/dist/components/Input/Input.mjs +15 -0
  41. package/dist/components/Input/Input.mjs.map +1 -0
  42. package/dist/components/Label/Label.d.mts +7 -0
  43. package/dist/components/Label/Label.mjs +14 -0
  44. package/dist/components/Label/Label.mjs.map +1 -0
  45. package/dist/components/List/List.d.mts +11 -0
  46. package/dist/components/List/List.mjs +15 -0
  47. package/dist/components/List/List.mjs.map +1 -0
  48. package/dist/components/ListItem/ListItem.d.mts +7 -0
  49. package/dist/components/ListItem/ListItem.mjs +13 -0
  50. package/dist/components/ListItem/ListItem.mjs.map +1 -0
  51. package/dist/components/PS1Root/PS1Root.d.mts +7 -0
  52. package/dist/components/PS1Root/PS1Root.mjs +13 -0
  53. package/dist/components/PS1Root/PS1Root.mjs.map +1 -0
  54. package/dist/components/Stack/Stack.d.mts +19 -0
  55. package/dist/components/Stack/Stack.mjs +48 -0
  56. package/dist/components/Stack/Stack.mjs.map +1 -0
  57. package/dist/components/Table/Table.d.mts +7 -0
  58. package/dist/components/Table/Table.mjs +25 -0
  59. package/dist/components/Table/Table.mjs.map +1 -0
  60. package/dist/components/Tbody/Tbody.d.mts +7 -0
  61. package/dist/components/Tbody/Tbody.mjs +13 -0
  62. package/dist/components/Tbody/Tbody.mjs.map +1 -0
  63. package/dist/components/Td/Td.d.mts +7 -0
  64. package/dist/components/Td/Td.mjs +13 -0
  65. package/dist/components/Td/Td.mjs.map +1 -0
  66. package/dist/components/Text/Text.d.mts +23 -0
  67. package/dist/components/Text/Text.mjs +34 -0
  68. package/dist/components/Text/Text.mjs.map +1 -0
  69. package/dist/components/Th/Th.d.mts +7 -0
  70. package/dist/components/Th/Th.mjs +13 -0
  71. package/dist/components/Th/Th.mjs.map +1 -0
  72. package/dist/components/Thead/Thead.d.mts +7 -0
  73. package/dist/components/Thead/Thead.mjs +13 -0
  74. package/dist/components/Thead/Thead.mjs.map +1 -0
  75. package/dist/components/Tr/Tr.d.mts +7 -0
  76. package/dist/components/Tr/Tr.mjs +13 -0
  77. package/dist/components/Tr/Tr.mjs.map +1 -0
  78. package/dist/components.css +1870 -0
  79. package/dist/index.d.mts +28 -0
  80. package/dist/index.mjs +25 -0
  81. package/dist/styles.css +1930 -0
  82. package/dist/utils/cx.mjs +8 -0
  83. package/dist/utils/cx.mjs.map +1 -0
  84. package/dist/utils/numbers.mjs +8 -0
  85. package/dist/utils/numbers.mjs.map +1 -0
  86. package/dist/utils/responsive.d.mts +6 -0
  87. package/dist/utils/responsive.mjs +39 -0
  88. package/dist/utils/responsive.mjs.map +1 -0
  89. package/dist/utils/spacing.d.mts +5 -0
  90. package/dist/utils/spacing.mjs +8 -0
  91. package/dist/utils/spacing.mjs.map +1 -0
  92. package/dist/utils/typography.d.mts +5 -0
  93. package/dist/utils/typography.mjs +16 -0
  94. package/dist/utils/typography.mjs.map +1 -0
  95. package/dist/utils/useMergedRef.mjs +30 -0
  96. package/dist/utils/useMergedRef.mjs.map +1 -0
  97. package/dist/utils/useScrollableFocus.mjs +29 -0
  98. package/dist/utils/useScrollableFocus.mjs.map +1 -0
  99. package/package.json +84 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Koki Sato
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/base.css ADDED
@@ -0,0 +1,378 @@
1
+ @import "@fontsource-variable/jetbrains-mono";
2
+ /* Palette hexes are mirrored in .storybook/ps1uiTheme.ts — see note there. */
3
+ :root {
4
+ --ps1ui-font-mono:
5
+ "JetBrains Mono Variable", ui-monospace, "SF Mono", Menlo, Monaco, "Cascadia Mono", Consolas,
6
+ monospace;
7
+
8
+ --ps1ui-color-bg: #0b0f14;
9
+ --ps1ui-color-surface: #0f1520;
10
+ --ps1ui-color-border: #21262d;
11
+ --ps1ui-color-border-strong: #30363d;
12
+ --ps1ui-color-fg: #c7d5df;
13
+ --ps1ui-color-fg-muted: #8b98a5;
14
+ /* fg-subtle must maintain ≥ 4.5:1 (WCAG AA) vs BOTH --ps1ui-color-bg and --ps1ui-color-surface.
15
+ Surface is the tighter case; verified by Text.contrast.test.tsx. */
16
+ --ps1ui-color-fg-subtle: #7a8593;
17
+ --ps1ui-color-primary: #7ee787;
18
+ --ps1ui-color-primary-hover: #56d364;
19
+ --ps1ui-color-primary-active: #3fb950;
20
+ --ps1ui-color-primary-fg: #0b0f14;
21
+ --ps1ui-color-accent: #ffa657;
22
+ --ps1ui-color-focus-ring-soft: color-mix(in srgb, var(--ps1ui-color-primary) 14%, transparent);
23
+ --ps1ui-shadow-focus-ring: 0 0 0 3px var(--ps1ui-color-focus-ring-soft);
24
+
25
+ /* Syntax-highlight palette for CodeBlock. Every value is verified ≥ 4.5:1 vs
26
+ BOTH --ps1ui-color-bg and --ps1ui-color-surface by CodeBlock.contrast.test.tsx. */
27
+ --ps1ui-code-comment: #7a8593;
28
+ --ps1ui-code-string: #f0c880;
29
+ --ps1ui-code-keyword: #ff7b95;
30
+ --ps1ui-code-function: #79c0ff;
31
+ --ps1ui-code-constant: #ffa657;
32
+ --ps1ui-code-type: #5eead4;
33
+ --ps1ui-code-tag: #ff9587;
34
+ --ps1ui-code-attr: #ffdc99;
35
+ --ps1ui-code-punctuation: #7a8593;
36
+ /* Diff-specific: green = added, rose = removed. Kept separate from tag/string so
37
+ the semantic overlap doesn't leak between grammars (a removed diff line has
38
+ nothing to do with an HTML <tag>, and an added line isn't a string literal). */
39
+ --ps1ui-code-inserted: #7ee787;
40
+ --ps1ui-code-deleted: #ff8896;
41
+
42
+ --ps1ui-radius-md: 3px;
43
+ --ps1ui-radius-lg: 4px;
44
+
45
+ --ps1ui-space-xs: 4px;
46
+ --ps1ui-space-sm: 8px;
47
+ --ps1ui-space-md: 12px;
48
+ --ps1ui-space-lg: 16px;
49
+ --ps1ui-space-xl: 24px;
50
+ --ps1ui-space-2xl: 32px;
51
+
52
+ /* Vertical padding for 1px-bordered controls (Button, Input): border +
53
+ padding = --ps1ui-space-sm (8px), so this is a derived value, not a new
54
+ spacing step. */
55
+ --ps1ui-control-padding-y: 7px;
56
+
57
+ /* Container max-widths, in rem so they scale with the user's browser
58
+ font-size preference (WCAG-friendly). Numeric equivalents at the
59
+ browser-default 16px root: 40 = 640, 48 = 768, 64 = 1024, 80 = 1280.
60
+ Doubles as the breakpoint scale — see --ps1ui-breakpoint-* below. */
61
+ --ps1ui-container-sm: 40rem;
62
+ --ps1ui-container-md: 48rem;
63
+ --ps1ui-container-lg: 64rem;
64
+ --ps1ui-container-xl: 80rem;
65
+
66
+ /* Responsive breakpoints, in rem for the same accessibility reason.
67
+ Values are identical to --ps1ui-container-* by design: a Container
68
+ of size=lg (64rem) fills at exactly the `lg` breakpoint. These are
69
+ documentation tokens — @container / @media conditions cannot use
70
+ `var()` per the CSS spec, so the same numeric values are also
71
+ hardcoded in each component's CSS. Keep in sync. */
72
+ --ps1ui-breakpoint-sm: 40rem;
73
+ --ps1ui-breakpoint-md: 48rem;
74
+ --ps1ui-breakpoint-lg: 64rem;
75
+ --ps1ui-breakpoint-xl: 80rem;
76
+
77
+ /* Type scale, in rem so text tracks the user's browser font-size preference
78
+ (same rationale as the container/breakpoint tokens above). All values sit
79
+ on the 0.125rem (2px) grid; px equivalents at the default 16px root:
80
+ 12 / 14 / 16 / 18 / 22 / 26 / 32. */
81
+ --ps1ui-font-size-xs: 0.75rem;
82
+ --ps1ui-font-size-sm: 0.875rem;
83
+ --ps1ui-font-size-md: 1rem;
84
+ --ps1ui-font-size-lg: 1.125rem;
85
+ --ps1ui-font-size-xl: 1.375rem;
86
+ --ps1ui-font-size-2xl: 1.625rem;
87
+ --ps1ui-font-size-3xl: 2rem;
88
+
89
+ --ps1ui-transition-fast: 120ms ease;
90
+ }
91
+ /* ==========================================================================
92
+ * Reset
93
+ * --------------------------------------------------------------------------
94
+ * Included in base.css (and therefore in styles.css) so consumers who commit
95
+ * fully to the PS1 UI look get a consistent baseline across browsers.
96
+ *
97
+ * NEVER duplicate any of these rules in components.css — that entry is for
98
+ * consumers embedding PS1 UI into a foreign design system, where a global
99
+ * reset would collide with the host system. The invariant is enforced by
100
+ * scripts/check-css-split.mjs at build time.
101
+ *
102
+ * Consumer heads-up: raw semantic tags rendered outside PS1 UI's own
103
+ * components lose their UA appearance under this reset — a bare <a> paints
104
+ * with inherited color/no underline (route through <Anchor>), a bare <h1>
105
+ * collapses to body text (route through <Heading>), a bare <button> has no
106
+ * chrome (route through <Button>), <img> becomes block (breaks inline avatar
107
+ * layouts unless you set display:inline explicitly), <ul>/<ol> lose their
108
+ * bullets. Locked in by src/styles/reset.test.tsx.
109
+ * ========================================================================== */
110
+ /* Box model + border baseline. Applied to `*` only — NOT to ::before/::after
111
+ /::backdrop/::file-selector-button. Pseudo-elements with border-drawn
112
+ glyphs (the classic rotated-L checkmark, tooltip carets, radio-dot rings)
113
+ need the initial `box-sizing: content-box` so their declared width/height
114
+ sit INSIDE the border. Josh Comeau's reset excludes pseudos for this
115
+ exact reason; Tailwind Preflight includes them but then has to document
116
+ the "authors doing border tricks must override" caveat. We pick the
117
+ Comeau side because ps1ui components (Checkbox) already use the trick.
118
+ Locked in by reset.test.tsx's "reset does not touch pseudos" block. */
119
+ * {
120
+ box-sizing: border-box;
121
+ border: 0 solid;
122
+ }
123
+ body,
124
+ blockquote,
125
+ dl,
126
+ dd,
127
+ figure,
128
+ fieldset,
129
+ h1,
130
+ h2,
131
+ h3,
132
+ h4,
133
+ h5,
134
+ h6,
135
+ hr,
136
+ menu,
137
+ ol,
138
+ p,
139
+ pre,
140
+ ul {
141
+ margin: 0;
142
+ }
143
+ fieldset,
144
+ legend,
145
+ menu,
146
+ ol,
147
+ ul {
148
+ padding: 0;
149
+ }
150
+ html {
151
+ color-scheme: dark;
152
+ line-height: 1.5;
153
+ -webkit-text-size-adjust: 100%;
154
+ -webkit-tap-highlight-color: transparent;
155
+ -moz-tab-size: 4;
156
+ -o-tab-size: 4;
157
+ tab-size: 4;
158
+ text-rendering: optimizeLegibility;
159
+ }
160
+ body {
161
+ min-height: 100dvh;
162
+ -webkit-font-smoothing: antialiased;
163
+ -moz-osx-font-smoothing: grayscale;
164
+ }
165
+ /* Heading responsibility belongs to <Heading>; raw h1..h6 inherit so a bare
166
+ <h1> outside <Heading> doesn't blow up to the UA default. */
167
+ h1,
168
+ h2,
169
+ h3,
170
+ h4,
171
+ h5,
172
+ h6 {
173
+ font-size: inherit;
174
+ font-weight: inherit;
175
+ text-wrap: balance;
176
+ overflow-wrap: break-word;
177
+ }
178
+ p {
179
+ text-wrap: pretty;
180
+ overflow-wrap: break-word;
181
+ }
182
+ ol,
183
+ ul,
184
+ menu {
185
+ list-style: none;
186
+ }
187
+ img,
188
+ svg,
189
+ video,
190
+ canvas,
191
+ audio,
192
+ iframe,
193
+ embed,
194
+ object {
195
+ display: block;
196
+ vertical-align: middle;
197
+ }
198
+ img,
199
+ video {
200
+ max-width: 100%;
201
+ height: auto;
202
+ }
203
+ /* Anchor responsibility belongs to <Anchor>; raw <a> inherits color/decoration
204
+ so it doesn't paint as UA blue underline against the dark canvas. */
205
+ a {
206
+ color: inherit;
207
+ text-decoration: inherit;
208
+ }
209
+ /* UA still refuses to inherit font/color into form controls in 2026.
210
+ Inherit font-feature-settings / font-variation-settings too so JetBrains
211
+ Mono Variable's axes stay live inside <input> / <textarea>. */
212
+ button,
213
+ input,
214
+ optgroup,
215
+ select,
216
+ textarea,
217
+ ::file-selector-button {
218
+ font: inherit;
219
+ font-feature-settings: inherit;
220
+ font-variation-settings: inherit;
221
+ letter-spacing: inherit;
222
+ color: inherit;
223
+ background-color: transparent;
224
+ border-radius: 0;
225
+ opacity: 1;
226
+ }
227
+ :where(select:is([multiple], [size])) optgroup {
228
+ font-weight: bolder;
229
+ }
230
+ button,
231
+ select {
232
+ text-transform: none;
233
+ }
234
+ button,
235
+ input:where([type="button"], [type="reset"], [type="submit"]),
236
+ ::file-selector-button {
237
+ -moz-appearance: button;
238
+ appearance: button;
239
+ -webkit-appearance: button;
240
+ }
241
+ button {
242
+ cursor: pointer;
243
+ }
244
+ textarea {
245
+ resize: vertical;
246
+ }
247
+ /* `in srgb` for consistency with the library's other color-mix calls. The
248
+ space is irrelevant when mixing with `transparent` (premultiplied-alpha
249
+ interpolation, CSS Color 4), so diverging from Tailwind Preflight's oklab
250
+ here is visually a no-op. */
251
+ ::-moz-placeholder {
252
+ opacity: 1;
253
+ color: color-mix(in srgb, currentcolor 55%, transparent);
254
+ }
255
+ ::placeholder {
256
+ opacity: 1;
257
+ color: color-mix(in srgb, currentcolor 55%, transparent);
258
+ }
259
+ ::-webkit-date-and-time-value {
260
+ min-height: 1lh;
261
+ text-align: inherit;
262
+ }
263
+ ::-webkit-datetime-edit {
264
+ display: inline-flex;
265
+ padding: 0;
266
+ }
267
+ ::-webkit-datetime-edit-fields-wrapper {
268
+ padding: 0;
269
+ }
270
+ ::-webkit-inner-spin-button,
271
+ ::-webkit-outer-spin-button {
272
+ -webkit-appearance: none;
273
+ margin: 0;
274
+ height: auto;
275
+ }
276
+ /* number spinner: Chromium is already handled by ::-webkit-inner/outer-spin-button
277
+ { appearance: none } above. Firefox needs its own vendor prefix — the unprefixed
278
+ `appearance: textfield` is deprecated per CSS UI Level 4 (moved to compatibility
279
+ appendix) and dropped by Tailwind v4 Preflight, so we omit it. */
280
+ input[type="number"] {
281
+ -moz-appearance: textfield;
282
+ }
283
+ [type="search"] {
284
+ -webkit-appearance: textfield;
285
+ outline-offset: -2px;
286
+ }
287
+ ::-webkit-search-decoration,
288
+ ::-webkit-search-cancel-button {
289
+ -webkit-appearance: none;
290
+ }
291
+ :-moz-ui-invalid {
292
+ box-shadow: none;
293
+ }
294
+ :-moz-focusring:where(:not(iframe)) {
295
+ outline: auto;
296
+ }
297
+ b,
298
+ strong {
299
+ font-weight: bolder;
300
+ }
301
+ small {
302
+ font-size: 80%;
303
+ }
304
+ code,
305
+ kbd,
306
+ samp,
307
+ pre {
308
+ font-family: var(--ps1ui-font-mono);
309
+ font-size: 1em;
310
+ }
311
+ abbr:where([title]) {
312
+ -webkit-text-decoration: underline dotted;
313
+ text-decoration: underline dotted;
314
+ }
315
+ q::before,
316
+ q::after {
317
+ content: "";
318
+ }
319
+ /* Keeps sub/sup from expanding the parent line-height. */
320
+ sub,
321
+ sup {
322
+ font-size: 75%;
323
+ line-height: 0;
324
+ position: relative;
325
+ vertical-align: baseline;
326
+ }
327
+ sub {
328
+ bottom: -0.25em;
329
+ }
330
+ sup {
331
+ top: -0.5em;
332
+ }
333
+ table {
334
+ text-indent: 0;
335
+ border-color: inherit;
336
+ border-collapse: collapse;
337
+ }
338
+ hr {
339
+ height: 0;
340
+ color: inherit;
341
+ border-top: 1px solid;
342
+ }
343
+ summary {
344
+ display: list-item;
345
+ }
346
+ /* [hidden] would lose to `display: flex` etc. without this. */
347
+ [hidden]:where(:not([hidden="until-found"])) {
348
+ display: none !important;
349
+ }
350
+ @media (prefers-reduced-motion: no-preference) {
351
+ html {
352
+ interpolate-size: allow-keywords;
353
+ }
354
+ }
355
+ /* ==========================================================================
356
+ * Ambient environment
357
+ * --------------------------------------------------------------------------
358
+ * `background`/`color`/`font-family` intentionally live on `html`, not `body`.
359
+ * Rationale: the reset above zeros `body { margin }`, but the browser still
360
+ * paints the area beyond `body` (macOS/iOS rubber-band overscroll region,
361
+ * horizontal-scroll overflow, viewport slack) using the canvas root's
362
+ * background — which is `html`. If these rules were on `body`, that overscroll
363
+ * area would reveal the light UA default and flash white on scroll. `color`
364
+ * and `font-family` cascade down to `body` and descendants naturally.
365
+ * ========================================================================== */
366
+ html {
367
+ background: var(--ps1ui-color-bg);
368
+ color: var(--ps1ui-color-fg);
369
+ font-family: var(--ps1ui-font-mono);
370
+ }
371
+ ::-moz-selection {
372
+ background: var(--ps1ui-color-primary);
373
+ color: var(--ps1ui-color-primary-fg);
374
+ }
375
+ ::selection {
376
+ background: var(--ps1ui-color-primary);
377
+ color: var(--ps1ui-color-primary-fg);
378
+ }
@@ -0,0 +1,12 @@
1
+ import { ComponentPropsWithoutRef, ElementType } from "react";
2
+ //#region src/components/Anchor/Anchor.d.ts
3
+ type AnchorVariant = "primary" | "subtle";
4
+ type AnchorOwnProps<E extends ElementType> = {
5
+ as?: E;
6
+ variant?: AnchorVariant;
7
+ };
8
+ type AnchorProps<E extends ElementType = "a"> = AnchorOwnProps<E> & Omit<ComponentPropsWithoutRef<E>, keyof AnchorOwnProps<E>>;
9
+ declare function Anchor<E extends ElementType = "a">({ as, variant, className, ...rest }: AnchorProps<E>): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
10
+ //#endregion
11
+ export { Anchor, AnchorProps, AnchorVariant };
12
+ //# sourceMappingURL=Anchor.d.mts.map
@@ -0,0 +1,15 @@
1
+ import { cx } from "../../utils/cx.mjs";
2
+ import { createElement } from "react";
3
+ //#region src/components/Anchor/Anchor.tsx
4
+ function Anchor({ as, variant = "primary", className, ...rest }) {
5
+ const tag = as ?? "a";
6
+ const classes = cx("ps1ui-anchor", `ps1ui-anchor--${variant}`, className);
7
+ return createElement(tag, {
8
+ ...rest,
9
+ className: classes
10
+ });
11
+ }
12
+ //#endregion
13
+ export { Anchor };
14
+
15
+ //# sourceMappingURL=Anchor.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Anchor.mjs","names":[],"sources":["../../../src/components/Anchor/Anchor.tsx"],"sourcesContent":["import { createElement } from \"react\";\nimport type { ComponentPropsWithoutRef, ElementType } from \"react\";\nimport { cx } from \"../../utils/cx\";\n\nexport type AnchorVariant = \"primary\" | \"subtle\";\n\ntype AnchorOwnProps<E extends ElementType> = {\n as?: E;\n variant?: AnchorVariant;\n};\n\n// Deliberate exception to the general \"use ComponentProps<'tag'>\" rule other components follow —\n// same reasoning as Text: with a polymorphic `as` prop TypeScript cannot correctly narrow the\n// `ref` prop's type. Anchor accepts both string tags and React component types (`as={NextLink}`),\n// so a loose ref type would silently accept mismatched refs; dropping ref from the prop type is\n// safer than a misleading loose type.\nexport type AnchorProps<E extends ElementType = \"a\"> = AnchorOwnProps<E> &\n Omit<ComponentPropsWithoutRef<E>, keyof AnchorOwnProps<E>>;\n\nexport function Anchor<E extends ElementType = \"a\">({\n as,\n variant = \"primary\",\n className,\n ...rest\n}: AnchorProps<E>) {\n const tag = as ?? \"a\";\n const classes = cx(\"ps1ui-anchor\", `ps1ui-anchor--${variant}`, className);\n return createElement(tag, { ...rest, className: classes });\n}\n"],"mappings":";;;AAmBA,SAAgB,OAAoC,EAClD,IACA,UAAU,WACV,WACA,GAAG,QACc;CACjB,MAAM,MAAM,MAAM;CAClB,MAAM,UAAU,GAAG,gBAAgB,iBAAiB,WAAW,SAAS;CACxE,OAAO,cAAc,KAAK;EAAE,GAAG;EAAM,WAAW;CAAQ,CAAC;AAC3D"}
@@ -0,0 +1,24 @@
1
+ import { ComponentPropsWithoutRef, ElementType } from "react";
2
+ //#region src/components/Button/Button.d.ts
3
+ type ButtonVariant = "primary" | "secondary";
4
+ type ButtonOwnProps<E extends ElementType> = {
5
+ as?: E;
6
+ variant?: ButtonVariant;
7
+ };
8
+ /**
9
+ * Props for {@link Button}. Derived from the props of the rendered element `E`,
10
+ * so what's accepted follows the `as` target.
11
+ *
12
+ * `disabled` and polymorphism: `disabled` only exists on form elements, so
13
+ * `<Button as="a" href="…" disabled>` is a type error (`ComponentPropsWithoutRef<"a">`
14
+ * has no `disabled` — locked in by `Button.test-d.tsx`). This is intentional and
15
+ * matches the ARIA Authoring Practices: links are not disabled. When the action is
16
+ * unavailable, render a native `<Button disabled>` (or no link at all) instead of a
17
+ * link. Untyped JS callers and `as={Component}` escapes that pass `disabled` anyway
18
+ * get a leaked no-op attribute — no visual or behavioral disabling happens.
19
+ */
20
+ type ButtonProps<E extends ElementType = "button"> = ButtonOwnProps<E> & Omit<ComponentPropsWithoutRef<E>, keyof ButtonOwnProps<E>>;
21
+ declare function Button<E extends ElementType = "button">({ as, variant, className, ...rest }: ButtonProps<E>): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
22
+ //#endregion
23
+ export { Button, ButtonProps, ButtonVariant };
24
+ //# sourceMappingURL=Button.d.mts.map
@@ -0,0 +1,17 @@
1
+ import { cx } from "../../utils/cx.mjs";
2
+ import { createElement } from "react";
3
+ //#region src/components/Button/Button.tsx
4
+ function Button({ as, variant = "primary", className, ...rest }) {
5
+ const tag = as ?? "button";
6
+ const classes = cx("ps1ui-button", `ps1ui-button--${variant}`, className);
7
+ const props = {
8
+ ...rest,
9
+ className: classes
10
+ };
11
+ if (tag === "button" && props.type === void 0) props.type = "button";
12
+ return createElement(tag, props);
13
+ }
14
+ //#endregion
15
+ export { Button };
16
+
17
+ //# sourceMappingURL=Button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.mjs","names":[],"sources":["../../../src/components/Button/Button.tsx"],"sourcesContent":["import { createElement } from \"react\";\nimport type { ComponentPropsWithoutRef, ElementType } from \"react\";\nimport { cx } from \"../../utils/cx\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\";\n\ntype ButtonOwnProps<E extends ElementType> = {\n as?: E;\n variant?: ButtonVariant;\n};\n\n// Deliberate exception to the general \"use ComponentProps<'tag'>\" rule other components follow —\n// same reasoning as Anchor / Text: with a polymorphic `as` prop TypeScript cannot correctly\n// narrow the `ref` prop's type against the resolved element E. Button accepts both string tags\n// (`as=\"a\"`) and React component types (`as={NextLink}`) so consumers can render a link that\n// looks like a button; a loose ref type would silently accept mismatched refs, so dropping ref\n// from the prop type is safer than a misleading loose type.\n/**\n * Props for {@link Button}. Derived from the props of the rendered element `E`,\n * so what's accepted follows the `as` target.\n *\n * `disabled` and polymorphism: `disabled` only exists on form elements, so\n * `<Button as=\"a\" href=\"…\" disabled>` is a type error (`ComponentPropsWithoutRef<\"a\">`\n * has no `disabled` — locked in by `Button.test-d.tsx`). This is intentional and\n * matches the ARIA Authoring Practices: links are not disabled. When the action is\n * unavailable, render a native `<Button disabled>` (or no link at all) instead of a\n * link. Untyped JS callers and `as={Component}` escapes that pass `disabled` anyway\n * get a leaked no-op attribute — no visual or behavioral disabling happens.\n */\nexport type ButtonProps<E extends ElementType = \"button\"> = ButtonOwnProps<E> &\n Omit<ComponentPropsWithoutRef<E>, keyof ButtonOwnProps<E>>;\n\nexport function Button<E extends ElementType = \"button\">({\n as,\n variant = \"primary\",\n className,\n ...rest\n}: ButtonProps<E>) {\n const tag: ElementType = as ?? \"button\";\n const classes = cx(\"ps1ui-button\", `ps1ui-button--${variant}`, className);\n const props: Record<string, unknown> = { ...rest, className: classes };\n // `type=\"button\"` is a defensive default so a native <button> inside a <form> never\n // submits implicitly. It only makes sense on the native tag — <a>, <NextLink>, and\n // other host/component targets have no such attribute, and stamping one on them\n // would leak an invalid attribute through to the DOM. Explicit callers still win.\n if (tag === \"button\" && props.type === undefined) {\n props.type = \"button\";\n }\n return createElement(tag, props);\n}\n"],"mappings":";;;AAgCA,SAAgB,OAAyC,EACvD,IACA,UAAU,WACV,WACA,GAAG,QACc;CACjB,MAAM,MAAmB,MAAM;CAC/B,MAAM,UAAU,GAAG,gBAAgB,iBAAiB,WAAW,SAAS;CACxE,MAAM,QAAiC;EAAE,GAAG;EAAM,WAAW;CAAQ;CAKrE,IAAI,QAAQ,YAAY,MAAM,SAAS,KAAA,GACrC,MAAM,OAAO;CAEf,OAAO,cAAc,KAAK,KAAK;AACjC"}
@@ -0,0 +1,7 @@
1
+ import { ComponentProps } from "react";
2
+ //#region src/components/Card/Card.d.ts
3
+ type CardProps = ComponentProps<"div">;
4
+ declare function Card({ className, ...rest }: CardProps): import("react").JSX.Element;
5
+ //#endregion
6
+ export { Card, CardProps };
7
+ //# sourceMappingURL=Card.d.mts.map
@@ -0,0 +1,14 @@
1
+ import { cx } from "../../utils/cx.mjs";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/Card/Card.tsx
4
+ function Card({ className, ...rest }) {
5
+ const classes = cx("ps1ui-card", className);
6
+ return /* @__PURE__ */ jsx("div", {
7
+ ...rest,
8
+ className: classes
9
+ });
10
+ }
11
+ //#endregion
12
+ export { Card };
13
+
14
+ //# sourceMappingURL=Card.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.mjs","names":[],"sources":["../../../src/components/Card/Card.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport { cx } from \"../../utils/cx\";\n\nexport type CardProps = ComponentProps<\"div\">;\n\nexport function Card({ className, ...rest }: CardProps) {\n const classes = cx(\"ps1ui-card\", className);\n return <div {...rest} className={classes} />;\n}\n"],"mappings":";;;AAKA,SAAgB,KAAK,EAAE,WAAW,GAAG,QAAmB;CACtD,MAAM,UAAU,GAAG,cAAc,SAAS;CAC1C,OAAO,oBAAC,OAAD;EAAK,GAAI;EAAM,WAAW;CAAU,CAAA;AAC7C"}
@@ -0,0 +1,9 @@
1
+ import { ComponentProps } from "react";
2
+ //#region src/components/Checkbox/Checkbox.d.ts
3
+ type CheckboxProps = Omit<ComponentProps<"input">, "type"> & {
4
+ indeterminate?: boolean;
5
+ };
6
+ declare function Checkbox({ className, indeterminate, ref: forwardedRef, ...rest }: CheckboxProps): import("react").JSX.Element;
7
+ //#endregion
8
+ export { Checkbox, CheckboxProps };
9
+ //# sourceMappingURL=Checkbox.d.mts.map
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import { cx } from "../../utils/cx.mjs";
3
+ import { useMergedRef } from "../../utils/useMergedRef.mjs";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { useLayoutEffect, useRef } from "react";
6
+ //#region src/components/Checkbox/Checkbox.tsx
7
+ function Checkbox({ className, indeterminate = false, ref: forwardedRef, ...rest }) {
8
+ const localRef = useRef(null);
9
+ useLayoutEffect(() => {
10
+ localRef.current.indeterminate = indeterminate;
11
+ }, [indeterminate]);
12
+ const mergedRef = useMergedRef(localRef, forwardedRef);
13
+ return /* @__PURE__ */ jsx("input", {
14
+ ...rest,
15
+ ref: mergedRef,
16
+ type: "checkbox",
17
+ className: cx("ps1ui-checkbox", className)
18
+ });
19
+ }
20
+ //#endregion
21
+ export { Checkbox };
22
+
23
+ //# sourceMappingURL=Checkbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.mjs","names":[],"sources":["../../../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["\"use client\";\n\nimport { useLayoutEffect, useRef, type ComponentProps } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport { useMergedRef } from \"../../utils/useMergedRef\";\n\nexport type CheckboxProps = Omit<ComponentProps<\"input\">, \"type\"> & {\n indeterminate?: boolean;\n};\n\nexport function Checkbox({\n className,\n indeterminate = false,\n ref: forwardedRef,\n ...rest\n}: CheckboxProps) {\n const localRef = useRef<HTMLInputElement>(null);\n\n // useLayoutEffect syncs .indeterminate before paint, avoiding a ✓-glyph flash on mount.\n useLayoutEffect(() => {\n localRef.current!.indeterminate = indeterminate;\n }, [indeterminate]);\n\n // Both the indeterminate sync above and the caller get the <input> node.\n const mergedRef = useMergedRef(localRef, forwardedRef);\n\n return (\n <input {...rest} ref={mergedRef} type=\"checkbox\" className={cx(\"ps1ui-checkbox\", className)} />\n );\n}\n"],"mappings":";;;;;;AAUA,SAAgB,SAAS,EACvB,WACA,gBAAgB,OAChB,KAAK,cACL,GAAG,QACa;CAChB,MAAM,WAAW,OAAyB,IAAI;CAG9C,sBAAsB;EACpB,SAAS,QAAS,gBAAgB;CACpC,GAAG,CAAC,aAAa,CAAC;CAGlB,MAAM,YAAY,aAAa,UAAU,YAAY;CAErD,OACE,oBAAC,SAAD;EAAO,GAAI;EAAM,KAAK;EAAW,MAAK;EAAW,WAAW,GAAG,kBAAkB,SAAS;CAAI,CAAA;AAElG"}
@@ -0,0 +1,7 @@
1
+ import { ComponentProps } from "react";
2
+ //#region src/components/Code/Code.d.ts
3
+ type CodeProps = ComponentProps<"code">;
4
+ declare function Code({ className, ...rest }: CodeProps): import("react").JSX.Element;
5
+ //#endregion
6
+ export { Code, CodeProps };
7
+ //# sourceMappingURL=Code.d.mts.map
@@ -0,0 +1,14 @@
1
+ import { cx } from "../../utils/cx.mjs";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/Code/Code.tsx
4
+ function Code({ className, ...rest }) {
5
+ const classes = cx("ps1ui-code", className);
6
+ return /* @__PURE__ */ jsx("code", {
7
+ ...rest,
8
+ className: classes
9
+ });
10
+ }
11
+ //#endregion
12
+ export { Code };
13
+
14
+ //# sourceMappingURL=Code.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Code.mjs","names":[],"sources":["../../../src/components/Code/Code.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\";\nimport { cx } from \"../../utils/cx\";\n\nexport type CodeProps = ComponentProps<\"code\">;\n\nexport function Code({ className, ...rest }: CodeProps) {\n const classes = cx(\"ps1ui-code\", className);\n return <code {...rest} className={classes} />;\n}\n"],"mappings":";;;AAKA,SAAgB,KAAK,EAAE,WAAW,GAAG,QAAmB;CACtD,MAAM,UAAU,GAAG,cAAc,SAAS;CAC1C,OAAO,oBAAC,QAAD;EAAM,GAAI;EAAM,WAAW;CAAU,CAAA;AAC9C"}
@@ -0,0 +1,12 @@
1
+ import { CodeBlockLanguage } from "./refractor.mjs";
2
+ import { ComponentProps } from "react";
3
+ //#region src/components/CodeBlock/CodeBlock.d.ts
4
+ type CodeBlockProps = Omit<ComponentProps<"pre">, "children"> & {
5
+ code?: string;
6
+ children?: string;
7
+ language?: CodeBlockLanguage | (string & {});
8
+ };
9
+ declare function CodeBlock({ code, children, language, className, onBlur, ref: forwardedRef, ...rest }: CodeBlockProps): import("react").JSX.Element;
10
+ //#endregion
11
+ export { CodeBlock, type CodeBlockLanguage, CodeBlockProps };
12
+ //# sourceMappingURL=CodeBlock.d.mts.map
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { cx } from "../../utils/cx.mjs";
3
+ import { useMergedRef } from "../../utils/useMergedRef.mjs";
4
+ import { useScrollableFocus } from "../../utils/useScrollableFocus.mjs";
5
+ import { refractor } from "./refractor.mjs";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Fragment, useLayoutEffect, useMemo } from "react";
8
+ import { toJsxRuntime } from "hast-util-to-jsx-runtime";
9
+ //#region src/components/CodeBlock/CodeBlock.tsx
10
+ function CodeBlock({ code, children, language, className, onBlur, ref: forwardedRef, ...rest }) {
11
+ const source = code ?? children ?? "";
12
+ const { highlighted, registered } = useMemo(() => {
13
+ const isRegistered = !!language && refractor.registered(language);
14
+ return {
15
+ registered: isRegistered,
16
+ highlighted: isRegistered ? toJsxRuntime(refractor.highlight(source, language), {
17
+ Fragment,
18
+ jsx,
19
+ jsxs
20
+ }) : source
21
+ };
22
+ }, [source, language]);
23
+ const { scrollerRef, tabIndex, measure } = useScrollableFocus();
24
+ useLayoutEffect(() => measure(), [measure, source]);
25
+ const mergedRef = useMergedRef(scrollerRef, forwardedRef);
26
+ return /* @__PURE__ */ jsx("pre", {
27
+ tabIndex,
28
+ ...rest,
29
+ ref: mergedRef,
30
+ className: cx("ps1ui-codeblock", className),
31
+ onBlur: (event) => {
32
+ onBlur?.(event);
33
+ measure();
34
+ },
35
+ children: /* @__PURE__ */ jsx("code", {
36
+ className: registered ? `language-${language}` : void 0,
37
+ children: highlighted
38
+ })
39
+ });
40
+ }
41
+ //#endregion
42
+ export { CodeBlock };
43
+
44
+ //# sourceMappingURL=CodeBlock.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeBlock.mjs","names":[],"sources":["../../../src/components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["\"use client\";\n\nimport { Fragment, useLayoutEffect, useMemo, type ComponentProps } from \"react\";\nimport { jsx, jsxs } from \"react/jsx-runtime\";\nimport { toJsxRuntime } from \"hast-util-to-jsx-runtime\";\nimport { cx } from \"../../utils/cx\";\nimport { useMergedRef } from \"../../utils/useMergedRef\";\nimport { useScrollableFocus } from \"../../utils/useScrollableFocus\";\nimport { refractor, type CodeBlockLanguage } from \"./refractor\";\n\nexport type { CodeBlockLanguage };\n\n// `language` is a new prop (not the native HTML `lang` attribute). HTML `lang`\n// is a BCP47 natural-language tag (\"en\", \"ja\") — a different concept that\n// remains part of the base <pre> attrs and passes through untouched. See\n// CodeBlock.test.tsx for the passthrough assertion.\n//\n// `code` is an alternative to `children` for environments that wrap JSX\n// children on the way to a React tree — e.g. Astro's `.astro` → React island\n// boundary rewraps `children` as an AstroComponentInstance, breaking the\n// `children: string` contract. Named props are passed through as-is, so\n// `<CodeBlock code={snippet}>` survives that boundary. `code` wins when both\n// are supplied; the same string appears in the rendered DOM either way.\nexport type CodeBlockProps = Omit<ComponentProps<\"pre\">, \"children\"> & {\n code?: string;\n children?: string;\n // `CodeBlockLanguage | (string & {})` is TypeScript's \"loose union\" pattern:\n // canonical language names surface in autocomplete, but aliases (`ts`, `html`, ...)\n // and dynamically-sourced strings (e.g. from a markdown fenced-code parser) still\n // pass through the type and are resolved at runtime via refractor's alias table.\n language?: CodeBlockLanguage | (string & {});\n};\n\nexport function CodeBlock({\n code,\n children,\n language,\n className,\n onBlur,\n ref: forwardedRef,\n ...rest\n}: CodeBlockProps) {\n // `code` takes precedence — see the type doc for the Astro/RSC-wrapped-children\n // rationale. Empty string is the \"neither provided\" fallback so the component\n // renders a valid empty <pre> instead of throwing on `.highlight(undefined)`.\n const source = code ?? children ?? \"\";\n // `registered` captures both \"language was provided\" and \"refractor knows it\" —\n // used for the highlight path, the language-<x> class, and to keep the class\n // off unhighlighted blocks (so downstream tools and consumer Prism themes\n // don't mistake a raw-text fallback for a highlighted block).\n //\n // useMemo keyed on (children, language) collapses repeated tokenization when a\n // frequently-re-rendering parent forces this component to re-render with the\n // same code — Prism tokenization of a multi-KB snippet + hast → JSX rebuild\n // is not cheap.\n const { highlighted, registered } = useMemo(() => {\n const isRegistered = !!language && refractor.registered(language);\n return {\n registered: isRegistered,\n highlighted: isRegistered\n ? toJsxRuntime(refractor.highlight(source, language), { Fragment, jsx, jsxs })\n : source,\n };\n }, [source, language]);\n\n // Keyboard reachability of the <pre> (its own scroll container) — tabIndex\n // only while the code actually overflows, kept while focused, safe-side\n // under static SSR — is the shared useScrollableFocus contract (see the\n // hook's header for the full account). The overflowing content is the\n // inline <code>, whose box a ResizeObserver can't watch, so content-driven\n // re-measures are keyed on the source string instead.\n const { scrollerRef, tabIndex, measure } = useScrollableFocus<HTMLPreElement>();\n useLayoutEffect(() => measure(), [measure, source]);\n\n // Merge the caller's ref with the hook's so both get the <pre> node.\n const mergedRef = useMergedRef(scrollerRef, forwardedRef);\n\n return (\n <pre\n // oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- axe scrollable-region-focusable requires the <pre> be keyboard-reachable when its content overflows; useScrollableFocus gates this on measured overflow so short snippets stay out of the tab order.\n tabIndex={tabIndex}\n {...rest}\n ref={mergedRef}\n className={cx(\"ps1ui-codeblock\", className)}\n // Chained (not spread) so the caller's handler still runs: the\n // re-measure drops the kept-while-focused tab stop once focus leaves —\n // see useScrollableFocus.\n onBlur={(event) => {\n onBlur?.(event);\n measure();\n }}\n >\n <code className={registered ? `language-${language}` : undefined}>{highlighted}</code>\n </pre>\n );\n}\n"],"mappings":";;;;;;;;;AAiCA,SAAgB,UAAU,EACxB,MACA,UACA,UACA,WACA,QACA,KAAK,cACL,GAAG,QACc;CAIjB,MAAM,SAAS,QAAQ,YAAY;CAUnC,MAAM,EAAE,aAAa,eAAe,cAAc;EAChD,MAAM,eAAe,CAAC,CAAC,YAAY,UAAU,WAAW,QAAQ;EAChE,OAAO;GACL,YAAY;GACZ,aAAa,eACT,aAAa,UAAU,UAAU,QAAQ,QAAQ,GAAG;IAAE;IAAU;IAAK;GAAK,CAAC,IAC3E;EACN;CACF,GAAG,CAAC,QAAQ,QAAQ,CAAC;CAQrB,MAAM,EAAE,aAAa,UAAU,YAAY,mBAAmC;CAC9E,sBAAsB,QAAQ,GAAG,CAAC,SAAS,MAAM,CAAC;CAGlD,MAAM,YAAY,aAAa,aAAa,YAAY;CAExD,OACE,oBAAC,OAAD;EAEY;EACV,GAAI;EACJ,KAAK;EACL,WAAW,GAAG,mBAAmB,SAAS;EAI1C,SAAS,UAAU;GACjB,SAAS,KAAK;GACd,QAAQ;EACV;YAEA,oBAAC,QAAD;GAAM,WAAW,aAAa,YAAY,aAAa,KAAA;aAAY;EAAkB,CAAA;CAClF,CAAA;AAET"}
@@ -0,0 +1,7 @@
1
+ import "refractor";
2
+ //#region src/components/CodeBlock/refractor.d.ts
3
+ declare const KNOWN_LANGS: readonly ["arduino", "bash", "basic", "c", "cpp", "csharp", "css", "diff", "go", "ini", "java", "javascript", "json", "kotlin", "less", "lua", "makefile", "markdown", "markup", "objectivec", "perl", "php", "python", "r", "regex", "ruby", "rust", "sass", "scss", "sql", "swift", "typescript", "vbnet", "yaml", "dart", "docker", "graphql", "jsx", "nginx", "powershell", "shell-session", "toml", "tsx", "zig"];
4
+ type CodeBlockLanguage = (typeof KNOWN_LANGS)[number];
5
+ //#endregion
6
+ export { CodeBlockLanguage };
7
+ //# sourceMappingURL=refractor.d.mts.map