@pindoba/core-code 0.0.0-alpha-20260829223243

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/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ Copyright 2025 Eduardo Lopes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
8
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
9
+ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
10
+ FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
11
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
12
+ DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ import { CodeApi, CodeBaseProps, CodeFeedback, CodeLine, CodeLineItem, CodePassThrough, CodeSize, CodeSlotPassThrough, CodeSlots, CodeToken, CodeTokenItem, ConnectCodeOptions, ElementAttributes, PanelElement, PanelRootProps } from "./src/types.js";
2
+ import { codeDefaults, connectCode } from "./src/connect-code.js";
3
+ export { type CodeApi, type CodeBaseProps, type CodeFeedback, type CodeLine, type CodeLineItem, type CodePassThrough, type CodeSize, type CodeSlotPassThrough, type CodeSlots, type CodeToken, type CodeTokenItem, type ConnectCodeOptions, type ElementAttributes, type PanelElement, type PanelRootProps, codeDefaults, connectCode };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import { codeDefaults, connectCode } from "./src/connect-code.js";
2
+ export { codeDefaults, connectCode };
@@ -0,0 +1,32 @@
1
+ import { CodeApi, ConnectCodeOptions } from "./types.js";
2
+ //#region src/connect-code.d.ts
3
+ declare const codeDefaults: {
4
+ readonly size: "sm";
5
+ readonly feedback: "neutral";
6
+ readonly wrap: false;
7
+ readonly showLineNumbers: false;
8
+ readonly startLine: 1;
9
+ readonly collapsible: false;
10
+ readonly expanded: false;
11
+ readonly copyable: false;
12
+ readonly copied: false;
13
+ readonly label: "Code block";
14
+ readonly emphasis: "secondary";
15
+ readonly background: "surface.hill";
16
+ readonly padding: "none";
17
+ readonly radius: "sm";
18
+ readonly border: "muted";
19
+ readonly shadow: "none";
20
+ };
21
+ /**
22
+ * Connect Contract v1.1 — the `Code` bags.
23
+ *
24
+ * Highlighting is somebody else's job: this takes already-tokenized `lines` and
25
+ * turns them into spreadable bags. With no `lines` it falls back to rendering
26
+ * `code` as plain text, so a block without a highlighter is still readable
27
+ * rather than empty.
28
+ */
29
+ declare function connectCode(options?: ConnectCodeOptions): CodeApi;
30
+ //#endregion
31
+ export { codeDefaults, connectCode };
32
+ //# sourceMappingURL=connect-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-code.d.ts","names":[],"sources":["../../src/connect-code.ts"],"mappings":";;cAaa;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyDG,YAAY,UAAS,qBAA0B"}
@@ -0,0 +1,200 @@
1
+ import { css, cx } from "@pindoba/styled-system/css";
2
+ import { connectPanel } from "@pindoba/core-panel";
3
+ import { defineConnect } from "@pindoba/normalize-props";
4
+ import { codeStyles } from "@pindoba/styles-code";
5
+ //#region src/connect-code.ts
6
+ const codeDefaults = {
7
+ size: "sm",
8
+ feedback: "neutral",
9
+ wrap: false,
10
+ showLineNumbers: false,
11
+ startLine: 1,
12
+ collapsible: false,
13
+ expanded: false,
14
+ copyable: false,
15
+ copied: false,
16
+ label: "Code block",
17
+ emphasis: "secondary",
18
+ background: "surface.hill",
19
+ padding: "none",
20
+ radius: "sm",
21
+ border: "muted",
22
+ shadow: "none"
23
+ };
24
+ /** Split raw source into single-token lines — the unhighlighted fallback. */
25
+ function linesFromSource(code) {
26
+ return (code.endsWith("\n") ? code.slice(0, -1) : code).split("\n").map((text) => ({ tokens: [{ text }] }));
27
+ }
28
+ /** A token's per-instance theme styling, as an inline CSS string. */
29
+ function tokenStyle(token) {
30
+ return [token.color != null ? `color:${token.color}` : "", token.fontStyle != null ? `font-style:${token.fontStyle}` : ""].filter(Boolean).join(";");
31
+ }
32
+ /** Reconstruct the plain text of tokenized lines, for the clipboard. */
33
+ function sourceFromLines(lines) {
34
+ return lines.map((line) => line.tokens.map((t) => t.text).join("")).join("\n");
35
+ }
36
+ /**
37
+ * Connect Contract v1.1 — the `Code` bags.
38
+ *
39
+ * Highlighting is somebody else's job: this takes already-tokenized `lines` and
40
+ * turns them into spreadable bags. With no `lines` it falls back to rendering
41
+ * `code` as plain text, so a block without a highlighter is still readable
42
+ * rather than empty.
43
+ */
44
+ function connectCode(options = {}) {
45
+ const { lines, code = "", lang, size = codeDefaults.size, feedback = codeDefaults.feedback, wrap = codeDefaults.wrap, showLineNumbers = codeDefaults.showLineNumbers, startLine = codeDefaults.startLine, highlightLines, maxLines, collapsible = codeDefaults.collapsible, expanded = codeDefaults.expanded, copyable = codeDefaults.copyable, copied = codeDefaults.copied, label = codeDefaults.label, as = "div", background = codeDefaults.background, emphasis = codeDefaults.emphasis, translucent, padding = codeDefaults.padding, radius = codeDefaults.radius, radiusTop, radiusBottom, radiusLeft, radiusRight, border = codeDefaults.border, borderInteract, borderActive, reserveBorderSpace, shadow = codeDefaults.shadow, interactive, active, activeEmphasis, reactive, passThrough, class: className, ...rest } = options;
46
+ const resolvedLines = lines ?? (code ? linesFromSource(code) : []);
47
+ const lineCount = resolvedLines.length;
48
+ const overflowable = maxLines != null && maxLines > 0 && lineCount > maxLines;
49
+ const clamped = overflowable && !expanded;
50
+ const classes = codeStyles.raw({
51
+ size,
52
+ wrap,
53
+ showLineNumbers
54
+ });
55
+ const highlighted = new Set(highlightLines ?? []);
56
+ const items = resolvedLines.map((line, index) => {
57
+ const number = startLine + index;
58
+ const isHighlighted = highlighted.has(number);
59
+ return {
60
+ id: `line-${number}`,
61
+ number,
62
+ marker: line.marker,
63
+ lineProps: {
64
+ "data-line": String(number),
65
+ "data-highlighted": isHighlighted ? "true" : "false",
66
+ class: css(classes.line, passThrough?.line?.style)
67
+ },
68
+ lineNumberProps: {
69
+ "aria-hidden": "true",
70
+ class: css(classes.lineNumber, passThrough?.lineNumber?.style)
71
+ },
72
+ lineContentProps: { class: css(classes.lineContent, passThrough?.lineContent?.style) },
73
+ ...line.marker != null ? { markerProps: {
74
+ "aria-hidden": "true",
75
+ class: css(classes.marker, passThrough?.marker?.style)
76
+ } } : {},
77
+ tokens: line.tokens.map((token, tokenIndex) => ({
78
+ id: `line-${number}-token-${tokenIndex}`,
79
+ text: token.text,
80
+ tokenProps: {
81
+ ...tokenStyle(token) ? { style: tokenStyle(token) } : {},
82
+ class: cx(css(classes.token, passThrough?.token?.style), token.className)
83
+ }
84
+ }))
85
+ };
86
+ });
87
+ const copyText = lines ? sourceFromLines(lines) : code;
88
+ const showToolbar = Boolean(lang) || copyable;
89
+ const showExpand = Boolean(collapsible && overflowable);
90
+ const panelApi = connectPanel({
91
+ as,
92
+ dataComponent: "code",
93
+ background,
94
+ emphasis,
95
+ feedback,
96
+ translucent,
97
+ padding,
98
+ radius,
99
+ radiusTop,
100
+ radiusBottom,
101
+ radiusLeft,
102
+ radiusRight,
103
+ border,
104
+ borderInteract,
105
+ borderActive,
106
+ reserveBorderSpace,
107
+ shadow,
108
+ interactive,
109
+ active,
110
+ activeEmphasis,
111
+ reactive,
112
+ inheritedStyle: classes.root,
113
+ passThrough: { root: {
114
+ style: passThrough?.root?.style,
115
+ props: {
116
+ ...passThrough?.root?.props,
117
+ "data-component": "code",
118
+ "data-lang": lang ?? "",
119
+ "data-clamped": clamped ? "true" : "false",
120
+ ...maxLines != null ? { style: `--code-max-lines:${maxLines}` } : {}
121
+ }
122
+ } },
123
+ class: className,
124
+ ...rest
125
+ });
126
+ return {
127
+ ...defineConnect({
128
+ slots: {
129
+ root: { class: "" },
130
+ toolbar: {
131
+ "data-code-toolbar": "",
132
+ class: css(classes.toolbar, passThrough?.toolbar?.style)
133
+ },
134
+ language: {
135
+ "data-code-language": "",
136
+ class: css(classes.language, passThrough?.language?.style)
137
+ },
138
+ copyButton: {
139
+ "data-code-copy": "",
140
+ type: "button",
141
+ emphasis: "ghost",
142
+ size: "xs",
143
+ "aria-label": copied ? "Copied" : "Copy code",
144
+ "data-copied": copied ? "true" : "false",
145
+ class: css(classes.copyButton, passThrough?.copyButton?.style)
146
+ },
147
+ scroller: {
148
+ "data-code-scroller": "",
149
+ tabindex: 0,
150
+ role: "region",
151
+ "aria-label": label,
152
+ class: css(classes.scroller, passThrough?.scroller?.style)
153
+ },
154
+ pre: { class: css(classes.pre, passThrough?.pre?.style) },
155
+ codeEl: {
156
+ ...lang ? { "data-language": lang } : {},
157
+ class: css(classes.codeEl, passThrough?.codeEl?.style)
158
+ },
159
+ lineNumbers: {
160
+ "aria-hidden": "true",
161
+ class: css(classes.lineNumbers, passThrough?.lineNumbers?.style)
162
+ },
163
+ line: { class: css(classes.line, passThrough?.line?.style) },
164
+ lineNumber: { class: css(classes.lineNumber, passThrough?.lineNumber?.style) },
165
+ lineContent: { class: css(classes.lineContent, passThrough?.lineContent?.style) },
166
+ token: { class: css(classes.token, passThrough?.token?.style) },
167
+ marker: { class: css(classes.marker, passThrough?.marker?.style) },
168
+ overflowFade: {
169
+ "data-code-fade": "",
170
+ "aria-hidden": "true",
171
+ class: css(classes.overflowFade, passThrough?.overflowFade?.style)
172
+ },
173
+ expandButton: {
174
+ "data-code-expand": "",
175
+ type: "button",
176
+ emphasis: "secondary",
177
+ size: "xs",
178
+ "aria-expanded": expanded ? "true" : "false",
179
+ class: css(classes.expandButton, passThrough?.expandButton?.style)
180
+ }
181
+ },
182
+ passThrough: {
183
+ ...passThrough,
184
+ root: void 0
185
+ }
186
+ }),
187
+ rootProps: panelApi.rootProps,
188
+ element: panelApi.element,
189
+ items,
190
+ copyText,
191
+ showToolbar,
192
+ showExpand,
193
+ overflowable,
194
+ lineCount
195
+ };
196
+ }
197
+ //#endregion
198
+ export { codeDefaults, connectCode };
199
+
200
+ //# sourceMappingURL=connect-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-code.js","names":[],"sources":["../../src/connect-code.ts"],"sourcesContent":["import { css, cx } from \"@pindoba/styled-system/css\";\nimport { connectPanel } from \"@pindoba/core-panel\";\nimport { defineConnect } from \"@pindoba/normalize-props\";\nimport { codeStyles } from \"@pindoba/styles-code\";\nimport type {\n CodeApi,\n CodeBaseProps,\n CodeLine,\n CodeLineItem,\n CodeToken,\n ConnectCodeOptions,\n} from \"./types.js\";\n\nexport const codeDefaults = {\n size: \"sm\",\n feedback: \"neutral\",\n wrap: false,\n showLineNumbers: false,\n startLine: 1,\n collapsible: false,\n expanded: false,\n copyable: false,\n copied: false,\n label: \"Code block\",\n // --- Panel surface defaults ---\n // The root is a Panel; these reproduce the surface the recipe used to paint\n // by hand (`colorPalette.surface.hill` + a 1px muted border + an `sm`\n // corner). `padding: \"none\"` because the block's inset lives on the toolbar /\n // scroller, not the root — so no `--panel-out-padding` republish is needed.\n emphasis: \"secondary\",\n background: \"surface.hill\",\n padding: \"none\",\n radius: \"sm\",\n border: \"muted\",\n shadow: \"none\",\n} as const satisfies Partial<CodeBaseProps>;\n\n/** Split raw source into single-token lines — the unhighlighted fallback. */\nfunction linesFromSource(code: string): CodeLine[] {\n // A trailing newline is a line terminator, not an empty final line; keeping\n // it would render a stray blank row under every file.\n const body = code.endsWith(\"\\n\") ? code.slice(0, -1) : code;\n return body.split(\"\\n\").map((text) => ({ tokens: [{ text }] }));\n}\n\n/** A token's per-instance theme styling, as an inline CSS string. */\nfunction tokenStyle(token: CodeToken): string {\n return [\n token.color != null ? `color:${token.color}` : \"\",\n token.fontStyle != null ? `font-style:${token.fontStyle}` : \"\",\n ]\n .filter(Boolean)\n .join(\";\");\n}\n\n/** Reconstruct the plain text of tokenized lines, for the clipboard. */\nfunction sourceFromLines(lines: CodeLine[]): string {\n return lines\n .map((line) => line.tokens.map((t) => t.text).join(\"\"))\n .join(\"\\n\");\n}\n\n/**\n * Connect Contract v1.1 — the `Code` bags.\n *\n * Highlighting is somebody else's job: this takes already-tokenized `lines` and\n * turns them into spreadable bags. With no `lines` it falls back to rendering\n * `code` as plain text, so a block without a highlighter is still readable\n * rather than empty.\n */\nexport function connectCode(options: ConnectCodeOptions = {}): CodeApi {\n const {\n lines,\n code = \"\",\n lang,\n size = codeDefaults.size,\n feedback = codeDefaults.feedback,\n wrap = codeDefaults.wrap,\n showLineNumbers = codeDefaults.showLineNumbers,\n startLine = codeDefaults.startLine,\n highlightLines,\n maxLines,\n collapsible = codeDefaults.collapsible,\n expanded = codeDefaults.expanded,\n copyable = codeDefaults.copyable,\n copied = codeDefaults.copied,\n label = codeDefaults.label,\n // --- Panel surface axes (delegated to connectPanel) ---\n as = \"div\",\n background = codeDefaults.background,\n emphasis = codeDefaults.emphasis,\n translucent,\n padding = codeDefaults.padding,\n radius = codeDefaults.radius,\n radiusTop,\n radiusBottom,\n radiusLeft,\n radiusRight,\n border = codeDefaults.border,\n borderInteract,\n borderActive,\n reserveBorderSpace,\n shadow = codeDefaults.shadow,\n interactive,\n active,\n activeEmphasis,\n reactive,\n passThrough,\n class: className,\n ...rest\n } = options;\n\n const resolvedLines: CodeLine[] =\n lines ?? (code ? linesFromSource(code) : []);\n const lineCount = resolvedLines.length;\n\n // Clamp only when there is genuinely more than fits — a `maxLines` larger\n // than the content must not paint a fade over nothing.\n const overflowable = maxLines != null && maxLines > 0 && lineCount > maxLines;\n const clamped = overflowable && !expanded;\n\n const classes = codeStyles.raw({\n size,\n wrap,\n showLineNumbers,\n });\n const highlighted = new Set(highlightLines ?? []);\n\n const items: CodeLineItem[] = resolvedLines.map((line, index) => {\n const number = startLine + index;\n const isHighlighted = highlighted.has(number);\n return {\n id: `line-${number}`,\n number,\n marker: line.marker,\n lineProps: {\n \"data-line\": String(number),\n \"data-highlighted\": isHighlighted ? \"true\" : \"false\",\n class: css(classes.line, passThrough?.line?.style),\n },\n lineNumberProps: {\n // The number is decoration duplicated by `data-line`; announcing it\n // before every line would bury the code itself.\n \"aria-hidden\": \"true\",\n class: css(classes.lineNumber, passThrough?.lineNumber?.style),\n },\n lineContentProps: {\n class: css(classes.lineContent, passThrough?.lineContent?.style),\n },\n ...(line.marker != null\n ? {\n markerProps: {\n \"aria-hidden\": \"true\",\n class: css(classes.marker, passThrough?.marker?.style),\n },\n }\n : {}),\n tokens: line.tokens.map((token, tokenIndex) => ({\n id: `line-${number}-token-${tokenIndex}`,\n text: token.text,\n tokenProps: {\n // Theme colour arrives per token and is inherently per-instance, so\n // it stays an inline style (which the contract allowlists) rather\n // than becoming an unbounded set of generated classes.\n //\n // A **string**, not an object: that is what connect bags emit\n // (`reactProps` converts it for React; Vue accepts either), and\n // Svelte drops most properties of a spread style object.\n ...(tokenStyle(token) ? { style: tokenStyle(token) } : {}),\n class: cx(\n css(classes.token, passThrough?.token?.style),\n token.className,\n ),\n },\n })),\n };\n });\n\n const copyText = lines ? sourceFromLines(lines) : code;\n const showToolbar = Boolean(lang) || copyable;\n const showExpand = Boolean(collapsible && overflowable);\n\n // The root's surface (background / border / corner) belongs to Panel; the\n // recipe keeps only layout + typography and rides the `inheritedStyle`\n // channel, so the compose order stays panel recipe → code recipe → consumer\n // `passThrough.root.style` → literal `class`. `feedback` reaches the recipe's\n // `colorPalette.*` reads through the panel's own feedback variant.\n const panelApi = connectPanel({\n as,\n dataComponent: \"code\",\n background,\n emphasis,\n feedback,\n translucent,\n padding,\n radius,\n radiusTop,\n radiusBottom,\n radiusLeft,\n radiusRight,\n border,\n borderInteract,\n borderActive,\n reserveBorderSpace,\n shadow,\n interactive,\n active,\n activeEmphasis,\n reactive,\n inheritedStyle: classes.root,\n passThrough: {\n root: {\n style: passThrough?.root?.style,\n props: {\n // The consumer's overrides go FIRST so everything below stays an\n // invariant, exactly as when these were baked after the rest spread:\n // the Astro boot script keys its copy/expand wiring off\n // `data-component=\"code\"` + `data-clamped`, and the recipe reads the\n // clamp height from the inline `--code-max-lines`. Extra root styling\n // belongs on `passThrough.root.style` (the Panda channel), which is\n // merged into the class rather than fighting this attribute.\n ...passThrough?.root?.props,\n \"data-component\": \"code\",\n \"data-lang\": lang ?? \"\",\n \"data-clamped\": clamped ? \"true\" : \"false\",\n ...(maxLines != null\n ? { style: `--code-max-lines:${maxLines}` }\n : {}),\n },\n },\n },\n class: className,\n ...rest,\n });\n\n const api = defineConnect({\n slots: {\n // Placeholder: the panel owns the real root bag (including its\n // `passThrough.root` merge, where the invariants sit ON TOP of the\n // consumer's props). `defineConnect`'s slot map is keyed by the recipe's\n // slot union so `root` has to be present, but the value below is\n // discarded — `rootProps` is replaced with `panelApi.rootProps` in the\n // returned api. `passThrough.root` is withheld here so the consumer's\n // props are not re-applied last and allowed to clobber the markers.\n root: { class: \"\" },\n toolbar: {\n \"data-code-toolbar\": \"\",\n class: css(classes.toolbar, passThrough?.toolbar?.style),\n },\n language: {\n \"data-code-language\": \"\",\n class: css(classes.language, passThrough?.language?.style),\n },\n copyButton: {\n \"data-code-copy\": \"\",\n type: \"button\",\n emphasis: \"ghost\" as const,\n size: \"xs\" as const,\n // The label carries the state, so a screen reader hears the result of\n // the press rather than a button whose name never changes.\n \"aria-label\": copied ? \"Copied\" : \"Copy code\",\n \"data-copied\": copied ? \"true\" : \"false\",\n class: css(classes.copyButton, passThrough?.copyButton?.style),\n },\n scroller: {\n \"data-code-scroller\": \"\",\n // A horizontally scrollable region must be keyboard-reachable, or the\n // overflow is unreadable without a pointer.\n tabindex: 0,\n role: \"region\",\n \"aria-label\": label,\n class: css(classes.scroller, passThrough?.scroller?.style),\n },\n pre: {\n class: css(classes.pre, passThrough?.pre?.style),\n },\n codeEl: {\n ...(lang ? { \"data-language\": lang } : {}),\n class: css(classes.codeEl, passThrough?.codeEl?.style),\n },\n lineNumbers: {\n \"aria-hidden\": \"true\",\n class: css(classes.lineNumbers, passThrough?.lineNumbers?.style),\n },\n line: {\n class: css(classes.line, passThrough?.line?.style),\n },\n lineNumber: {\n class: css(classes.lineNumber, passThrough?.lineNumber?.style),\n },\n lineContent: {\n class: css(classes.lineContent, passThrough?.lineContent?.style),\n },\n token: {\n class: css(classes.token, passThrough?.token?.style),\n },\n marker: {\n class: css(classes.marker, passThrough?.marker?.style),\n },\n overflowFade: {\n \"data-code-fade\": \"\",\n \"aria-hidden\": \"true\",\n class: css(classes.overflowFade, passThrough?.overflowFade?.style),\n },\n expandButton: {\n \"data-code-expand\": \"\",\n type: \"button\",\n emphasis: \"secondary\" as const,\n size: \"xs\" as const,\n \"aria-expanded\": expanded ? \"true\" : \"false\",\n class: css(classes.expandButton, passThrough?.expandButton?.style),\n },\n },\n passThrough: { ...passThrough, root: undefined },\n });\n\n return {\n ...api,\n rootProps: panelApi.rootProps,\n element: panelApi.element,\n items,\n copyText,\n showToolbar,\n showExpand,\n overflowable,\n lineCount,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { CodeLine } from "./types.js";
2
+ //#region src/shiki.d.ts
3
+ /** The shape of a Shiki themed token — structurally, not by import. */
4
+ interface ShikiThemedToken {
5
+ content: string;
6
+ color?: string;
7
+ /** Shiki's font-style bitfield: 1 italic, 2 bold, 4 underline. */
8
+ fontStyle?: number;
9
+ htmlStyle?: Record<string, string> | string;
10
+ }
11
+ /** Shiki's `codeToTokens()` result, narrowed to what the adapter reads. */
12
+ interface ShikiTokensResult {
13
+ tokens: ShikiThemedToken[][];
14
+ }
15
+ /** Translate Shiki's bitfield into a CSS declaration string. */
16
+ declare function shikiFontStyle(fontStyle: number | undefined): string | undefined;
17
+ /**
18
+ * Convert `codeToTokens()` output into the `lines` a `Code` component takes.
19
+ *
20
+ * ```ts
21
+ * import { codeToTokens } from "shiki";
22
+ * import { shikiToLines } from "@pindoba/core-code/shiki";
23
+ *
24
+ * const lines = shikiToLines(
25
+ * await codeToTokens(source, { lang: "ts", theme: "github-dark" }),
26
+ * );
27
+ * ```
28
+ */
29
+ declare function shikiToLines(result: ShikiTokensResult): CodeLine[];
30
+ /**
31
+ * Same conversion from a bare token grid, for callers holding
32
+ * `result.tokens` rather than the whole result object.
33
+ */
34
+ declare function shikiTokensToLines(tokens: ShikiThemedToken[][]): CodeLine[];
35
+ //#endregion
36
+ export { ShikiThemedToken, ShikiTokensResult, shikiFontStyle, shikiToLines, shikiTokensToLines };
37
+ //# sourceMappingURL=shiki.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shiki.d.ts","names":[],"sources":["../../src/shiki.ts"],"mappings":";;;UAgBiB;EACf;EACA;;EAEA;EACA,YAAY;;;UAIG;EACf,QAAQ;;;iBASM,eACd;;;;;;;;;;;;;iBAgCc,aAAa,QAAQ,oBAAoB;;;;;iBAQzC,mBAAmB,QAAQ,uBAAuB"}
@@ -0,0 +1,44 @@
1
+ //#region src/shiki.ts
2
+ const ITALIC = 1;
3
+ /** Translate Shiki's bitfield into a CSS declaration string. */
4
+ function shikiFontStyle(fontStyle) {
5
+ if (!fontStyle) return void 0;
6
+ const parts = [];
7
+ if (fontStyle & ITALIC) parts.push("italic");
8
+ if (parts.length === 0 && fontStyle & 6) return void 0;
9
+ return parts.length > 0 ? parts.join(" ") : void 0;
10
+ }
11
+ function toToken(token) {
12
+ const fontStyle = shikiFontStyle(token.fontStyle);
13
+ return {
14
+ text: token.content,
15
+ ...token.color != null ? { color: token.color } : {},
16
+ ...fontStyle != null ? { fontStyle } : {}
17
+ };
18
+ }
19
+ /**
20
+ * Convert `codeToTokens()` output into the `lines` a `Code` component takes.
21
+ *
22
+ * ```ts
23
+ * import { codeToTokens } from "shiki";
24
+ * import { shikiToLines } from "@pindoba/core-code/shiki";
25
+ *
26
+ * const lines = shikiToLines(
27
+ * await codeToTokens(source, { lang: "ts", theme: "github-dark" }),
28
+ * );
29
+ * ```
30
+ */
31
+ function shikiToLines(result) {
32
+ return result.tokens.map((tokens) => ({ tokens: tokens.map(toToken) }));
33
+ }
34
+ /**
35
+ * Same conversion from a bare token grid, for callers holding
36
+ * `result.tokens` rather than the whole result object.
37
+ */
38
+ function shikiTokensToLines(tokens) {
39
+ return tokens.map((row) => ({ tokens: row.map(toToken) }));
40
+ }
41
+ //#endregion
42
+ export { shikiFontStyle, shikiToLines, shikiTokensToLines };
43
+
44
+ //# sourceMappingURL=shiki.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shiki.js","names":[],"sources":["../../src/shiki.ts"],"sourcesContent":["/**\n * @fileoverview Optional Shiki adapter — converts Shiki output into `CodeLine[]`.\n *\n * A **separate entry point** (`@pindoba/core-code/shiki`) with `shiki` as an\n * optional peer dependency, so importing `Code` never pulls a highlighting\n * engine and its grammars into the bundle. Consumers that want highlighting opt\n * in explicitly; everyone else renders plain text and pays nothing.\n *\n * Nothing here imports Shiki either: the functions take Shiki's *output*. That\n * keeps the adapter usable with any Shiki version (and with a highlighter\n * running in a worker or on the server) without a version lock.\n */\n\nimport type { CodeLine, CodeToken } from \"./types.js\";\n\n/** The shape of a Shiki themed token — structurally, not by import. */\nexport interface ShikiThemedToken {\n content: string;\n color?: string;\n /** Shiki's font-style bitfield: 1 italic, 2 bold, 4 underline. */\n fontStyle?: number;\n htmlStyle?: Record<string, string> | string;\n}\n\n/** Shiki's `codeToTokens()` result, narrowed to what the adapter reads. */\nexport interface ShikiTokensResult {\n tokens: ShikiThemedToken[][];\n}\n\n// Shiki encodes font style as a bitfield rather than CSS.\nconst ITALIC = 1;\nconst BOLD = 2;\nconst UNDERLINE = 4;\n\n/** Translate Shiki's bitfield into a CSS declaration string. */\nexport function shikiFontStyle(\n fontStyle: number | undefined,\n): string | undefined {\n if (!fontStyle) return undefined;\n const parts: string[] = [];\n if (fontStyle & ITALIC) parts.push(\"italic\");\n // `font-style` cannot express weight or decoration; those are dropped rather\n // than silently mis-applied. Callers wanting them can theme via `className`.\n if (parts.length === 0 && fontStyle & (BOLD | UNDERLINE)) return undefined;\n return parts.length > 0 ? parts.join(\" \") : undefined;\n}\n\nfunction toToken(token: ShikiThemedToken): CodeToken {\n const fontStyle = shikiFontStyle(token.fontStyle);\n return {\n text: token.content,\n ...(token.color != null ? { color: token.color } : {}),\n ...(fontStyle != null ? { fontStyle } : {}),\n };\n}\n\n/**\n * Convert `codeToTokens()` output into the `lines` a `Code` component takes.\n *\n * ```ts\n * import { codeToTokens } from \"shiki\";\n * import { shikiToLines } from \"@pindoba/core-code/shiki\";\n *\n * const lines = shikiToLines(\n * await codeToTokens(source, { lang: \"ts\", theme: \"github-dark\" }),\n * );\n * ```\n */\nexport function shikiToLines(result: ShikiTokensResult): CodeLine[] {\n return result.tokens.map((tokens) => ({ tokens: tokens.map(toToken) }));\n}\n\n/**\n * Same conversion from a bare token grid, for callers holding\n * `result.tokens` rather than the whole result object.\n */\nexport function shikiTokensToLines(tokens: ShikiThemedToken[][]): CodeLine[] {\n return tokens.map((row) => ({ tokens: row.map(toToken) }));\n}\n"],"mappings":";AA8BA,MAAM,SAAS;;AAKf,SAAgB,eACd,WACoB;CACpB,IAAI,CAAC,WAAW,OAAO,KAAA;CACvB,MAAM,QAAkB,CAAC;CACzB,IAAI,YAAY,QAAQ,MAAM,KAAK,QAAQ;CAG3C,IAAI,MAAM,WAAW,KAAK,YAAa,GAAmB,OAAO,KAAA;CACjE,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,GAAG,IAAI,KAAA;AAC9C;AAEA,SAAS,QAAQ,OAAoC;CACnD,MAAM,YAAY,eAAe,MAAM,SAAS;CAChD,OAAO;EACL,MAAM,MAAM;EACZ,GAAI,MAAM,SAAS,OAAO,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;EACpD,GAAI,aAAa,OAAO,EAAE,UAAU,IAAI,CAAC;CAC3C;AACF;;;;;;;;;;;;;AAcA,SAAgB,aAAa,QAAuC;CAClE,OAAO,OAAO,OAAO,KAAK,YAAY,EAAE,QAAQ,OAAO,IAAI,OAAO,EAAE,EAAE;AACxE;;;;;AAMA,SAAgB,mBAAmB,QAA0C;CAC3E,OAAO,OAAO,KAAK,SAAS,EAAE,QAAQ,IAAI,IAAI,OAAO,EAAE,EAAE;AAC3D"}
@@ -0,0 +1,185 @@
1
+ import { PanelElement, PanelElement as PanelElement$1, PanelInheritedProps, PanelRootProps, PanelRootProps as PanelRootProps$1 } from "@pindoba/core-panel";
2
+ import { ConnectReturn } from "@pindoba/normalize-props";
3
+ import { CodeSlots, CodeStyleProps } from "@pindoba/styles-code";
4
+ import { SystemStyleObject } from "@pindoba/styled-system/types";
5
+ import { PanelStyleProps } from "@pindoba/styles-panel";
6
+ //#region src/types.d.ts
7
+ type ElementAttributes = Partial<Record<string, unknown>>;
8
+ type CodeSize = NonNullable<CodeStyleProps["size"]>;
9
+ type CodeFeedback = NonNullable<PanelStyleProps["feedback"]>;
10
+ /**
11
+ * One coloured run of text within a line.
12
+ *
13
+ * This is the entire contract between `Code` and a syntax highlighter, and it
14
+ * is deliberately the smallest thing that can express highlighted output:
15
+ * `core-code` never imports a grammar, a theme, or a highlighting engine. Shiki
16
+ * alone is a multi-megabyte dependency with its own theme format, and baking it
17
+ * in would make every consumer of the design system pay for it whether or not
18
+ * they render code.
19
+ *
20
+ * `@pindoba/core-code/shiki` is an optional adapter that converts Shiki output
21
+ * into this shape; anything else that can produce `{ text, color }` runs works
22
+ * just as well, including a hand-rolled tokenizer or none at all.
23
+ */
24
+ interface CodeToken {
25
+ text: string;
26
+ /** CSS colour for this run, applied inline (that is how themes ship). */
27
+ color?: string;
28
+ /** Extra class, for highlighters that theme via CSS rather than inline colour. */
29
+ className?: string;
30
+ /** `font-style` / `font-weight` a theme may set on a run. */
31
+ fontStyle?: string;
32
+ }
33
+ /** One rendered line: its tokens, plus any per-line decoration. */
34
+ interface CodeLine {
35
+ tokens: CodeToken[];
36
+ /** Optional gutter marker — `+`, `-`, `>` for a diff or a callout. */
37
+ marker?: string;
38
+ }
39
+ interface CodeSlotPassThrough<T = ElementAttributes> {
40
+ style?: SystemStyleObject;
41
+ props?: T;
42
+ }
43
+ type CodePassThrough<RootElementAttributes = ElementAttributes> = { [K in CodeSlots]?: CodeSlotPassThrough<K extends "root" ? RootElementAttributes : ElementAttributes>; };
44
+ interface CodeBaseProps<RootElementAttributes = ElementAttributes> extends Omit<PanelInheritedProps<RootElementAttributes>, "passThrough"> {
45
+ /**
46
+ * Pre-tokenized lines from a highlighter. When omitted, `code` is rendered
47
+ * as unhighlighted plain text — so the component degrades to a readable
48
+ * block rather than nothing.
49
+ * @group Content
50
+ */
51
+ lines?: CodeLine[];
52
+ /**
53
+ * Raw source. Used verbatim when `lines` is absent, and always used as the
54
+ * text the copy button puts on the clipboard.
55
+ * @group Content
56
+ */
57
+ code?: string;
58
+ /**
59
+ * Language label shown in the toolbar. Purely presentational — the component
60
+ * does no highlighting of its own.
61
+ * @group Content
62
+ */
63
+ lang?: string;
64
+ /**
65
+ * Type scale of the block. `xs` and `sm` currently render at the same font
66
+ * size — the scale's smallest step is `xs`, so separating them means moving
67
+ * `sm`/`md` up, which is a deliberate visual change that hasn't been made.
68
+ * @default "sm"
69
+ * @group Appearance
70
+ */
71
+ size?: CodeSize;
72
+ /**
73
+ * Wrap long lines instead of scrolling horizontally.
74
+ * @default false
75
+ * @group Layout
76
+ */
77
+ wrap?: boolean;
78
+ /**
79
+ * Show a line number beside each line.
80
+ * @default false
81
+ * @group Layout
82
+ */
83
+ showLineNumbers?: boolean;
84
+ /**
85
+ * Number the first line as this. Lets an excerpt report its real position in
86
+ * the file rather than restarting at 1.
87
+ * @default 1
88
+ * @group Layout
89
+ */
90
+ startLine?: number;
91
+ /**
92
+ * Line numbers (in displayed terms, honouring `startLine`) to emphasise.
93
+ * @group Appearance
94
+ */
95
+ highlightLines?: number[];
96
+ /**
97
+ * Clamp the block to this many lines, fading the overflow.
98
+ * @group Layout
99
+ */
100
+ maxLines?: number;
101
+ /**
102
+ * Offer an expand control when clamped by `maxLines`.
103
+ * @default false
104
+ * @group Behavior
105
+ */
106
+ collapsible?: boolean;
107
+ /**
108
+ * Whether the block is currently expanded past `maxLines`. Frameworks feed
109
+ * their reactive state in; the component is controlled.
110
+ * @default false
111
+ * @group Behavior
112
+ */
113
+ expanded?: boolean;
114
+ /**
115
+ * Render a copy-to-clipboard button in the toolbar.
116
+ * @default false
117
+ * @group Behavior
118
+ */
119
+ copyable?: boolean;
120
+ /**
121
+ * Whether the copy button is in its just-copied state. Frameworks own the
122
+ * timer that flips it back.
123
+ * @default false
124
+ * @group Behavior
125
+ */
126
+ copied?: boolean;
127
+ /**
128
+ * Accessible label for the block.
129
+ * @default "Code block"
130
+ * @group Accessibility
131
+ */
132
+ label?: string;
133
+ /**
134
+ * Per-slot style and HTML-attribute overrides.
135
+ * @group Advanced
136
+ */
137
+ passThrough?: CodePassThrough<RootElementAttributes>;
138
+ }
139
+ interface ConnectCodeOptions extends Partial<CodeBaseProps<ElementAttributes>> {
140
+ class?: unknown;
141
+ [key: string]: unknown;
142
+ }
143
+ /** One token's spreadable bag, plus the text to render inside it. */
144
+ interface CodeTokenItem {
145
+ id: string;
146
+ text: string;
147
+ tokenProps: Record<string, unknown>;
148
+ }
149
+ /** One line's bags — Contract v1.1 Rule 3. */
150
+ interface CodeLineItem {
151
+ id: string;
152
+ /** Displayed line number, already offset by `startLine`. */
153
+ number: number;
154
+ marker?: string;
155
+ lineProps: Record<string, unknown>;
156
+ lineNumberProps: Record<string, unknown>;
157
+ lineContentProps: Record<string, unknown>;
158
+ markerProps?: Record<string, unknown>;
159
+ tokens: CodeTokenItem[];
160
+ }
161
+ type CodeApi = ConnectReturn<CodeSlots> & {
162
+ /** The panel-produced root bag (`data-component="code"` + the nest hook). */
163
+ rootProps: PanelRootProps$1;
164
+ /** Resolved root tag from `as` — templates render this element. */
165
+ element: PanelElement$1;
166
+ /** Per-line bags, in order. */
167
+ items: CodeLineItem[];
168
+ /** The exact text the copy button should write to the clipboard. */
169
+ copyText: string;
170
+ /** Whether a toolbar should be rendered at all. */
171
+ showToolbar: boolean;
172
+ /** Whether the expand affordance should be rendered. */
173
+ showExpand: boolean;
174
+ /**
175
+ * Whether the block has more lines than `maxLines`, so the overflow fade
176
+ * should be rendered. Distinct from `showExpand`: a non-`collapsible` block
177
+ * still clamps and still fades, it just offers no way out.
178
+ */
179
+ overflowable: boolean;
180
+ /** Total line count, before any clamping. */
181
+ lineCount: number;
182
+ };
183
+ //#endregion
184
+ export { CodeApi, CodeBaseProps, CodeFeedback, CodeLine, CodeLineItem, CodePassThrough, CodeSize, CodeSlotPassThrough, type CodeSlots, CodeToken, CodeTokenItem, ConnectCodeOptions, ElementAttributes, type PanelElement, type PanelRootProps };
185
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/types.ts"],"mappings":";;;;;;KAaY,oBAAoB,QAAQ;KAE5B,WAAW,YAAY;KACvB,eAAe,YAAY;;;;;;;;;;;;;;;UAkBtB;EACf;;EAEA;;EAEA;;EAEA;;;UAIe;EACf,QAAQ;;EAER;;UAKe,oBAAoB,IAAI;EACvC,QAAQ;EACR,QAAQ;;KAGE,gBAAgB,wBAAwB,wBACjD,KAAK,aAAa,oBACjB,mBAAmB,wBAAwB;UAM9B,cAAc,wBAAwB,2BAM7C,KAAK,oBAAoB;;;;;;;EAOjC,QAAQ;;;;;;EAMR;;;;;;EAMA;;;;;;;;EAQA,OAAO;;;;;;EAMP;;;;;;EAMA;;;;;;;EAOA;;;;;EAKA;;;;;EAKA;;;;;;EAMA;;;;;;;EAOA;;;;;;EAMA;;;;;;;EAOA;;;;;;EAMA;;;;;EAKA,cAAc,gBAAgB;;UAKf,2BAA2B,QAC1C,cAAc;EAEd;GACC;;;UAIc;EACf;EACA;EACA,YAAY;;;UAIG;EACf;;EAEA;EACA;EACA,WAAW;EACX,iBAAiB;EACjB,kBAAkB;EAClB,cAAc;EACd,QAAQ;;KAGE,UAAU,cAAc;;EAElC,WAAW;;EAEX,SAAS;;EAET,OAAO;;EAEP;;EAEA;;EAEA;;;;;;EAMA;;EAEA"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@pindoba/core-code",
3
+ "version": "0.0.0-alpha-20260829223243",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "sideEffects": false,
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ },
14
+ "./shiki": {
15
+ "types": "./dist/src/shiki.d.ts",
16
+ "import": "./dist/src/shiki.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "dependencies": {
23
+ "@pindoba/core-panel": "0.0.0-alpha-20260829223243",
24
+ "@pindoba/normalize-props": "0.0.0-alpha-20260829223243",
25
+ "@pindoba/styled-system": "0.0.0-alpha-20260829223243",
26
+ "@pindoba/styles-code": "0.0.0-alpha-20260829223243",
27
+ "@pindoba/styles-panel": "0.0.0-alpha-20260829223243"
28
+ },
29
+ "devDependencies": {
30
+ "@pindoba/typescript-config": "0.0.0-alpha-20260320034942",
31
+ "tsdown": "^0.22.14",
32
+ "typescript": "^7.0.2"
33
+ },
34
+ "peerDependencies": {
35
+ "shiki": ">=1"
36
+ },
37
+ "peerDependenciesMeta": {
38
+ "shiki": {
39
+ "optional": true
40
+ }
41
+ },
42
+ "scripts": {
43
+ "build": "tsdown",
44
+ "dev": "tsdown --watch",
45
+ "clean": "rm -rf dist && rm -rf node_modules && rm -rf .turbo",
46
+ "check": "tsc --noEmit",
47
+ "lint": "TIMING=1 eslint . --max-warnings 0",
48
+ "lint:fix": "TIMING=1 eslint . --fix --max-warnings 0",
49
+ "format": "prettier --check . --ignore-path \"$PRETTIER_IGNORE_PATH\"",
50
+ "format:fix": "prettier --write . --ignore-path \"$PRETTIER_IGNORE_PATH\""
51
+ }
52
+ }