@pindoba/core-code 0.0.0-alpha-20260829223243 → 0.0.0-alpha-20261110151933

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/index.d.ts CHANGED
@@ -1,3 +1,4 @@
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 };
1
+ import { CODE_COPIED_MS, codeCopyLabel, codeExpandLabel, createCodeCopy } from "./src/code-actions.js";
2
+ import { _ as ConnectCodeOptions, a as CodeCardFrameNodes, b as PanelRootProps, c as CodeLineItem, d as CodeSize, f as CodeSlotPassThrough, g as CodeTone, h as CodeTokenItem, i as CodeCardDefaults, l as CodePassThrough, m as CodeToken, n as CodeBaseProps, o as CodeCardProps, p as CodeSlots, r as CodeCardChrome, s as CodeLine, t as CodeApi, u as CodeResolvedCardFrame, v as ElementAttributes, y as PanelElement } from "./types-DcQoTmcO.js";
3
+ import { codeDefaults, connectCode, resolveCodeCardFrame } from "./src/connect-code.js";
4
+ export { CODE_COPIED_MS, type CodeApi, type CodeBaseProps, type CodeCardChrome, type CodeCardDefaults, type CodeCardFrameNodes, type CodeCardProps, type CodeLine, type CodeLineItem, type CodePassThrough, type CodeResolvedCardFrame, type CodeSize, type CodeSlotPassThrough, type CodeSlots, type CodeToken, type CodeTokenItem, type CodeTone, type ConnectCodeOptions, type ElementAttributes, type PanelElement, type PanelRootProps, codeCopyLabel, codeDefaults, codeExpandLabel, connectCode, createCodeCopy, resolveCodeCardFrame };
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
- import { codeDefaults, connectCode } from "./src/connect-code.js";
2
- export { codeDefaults, connectCode };
1
+ import { CODE_COPIED_MS, codeCopyLabel, codeExpandLabel, createCodeCopy } from "./src/code-actions.js";
2
+ import { codeDefaults, connectCode, resolveCodeCardFrame } from "./src/connect-code.js";
3
+ export { CODE_COPIED_MS, codeCopyLabel, codeDefaults, codeExpandLabel, connectCode, createCodeCopy, resolveCodeCardFrame };
@@ -0,0 +1,23 @@
1
+ //#region src/code-actions.d.ts
2
+ /**
3
+ * The behaviour of a code block, framework-free: the clipboard write with its
4
+ * "Copied" tone window and the button labels. The Code runtime
5
+ * (`./runtime`) wires them; every interactive Astro block hydrates on it.
6
+ */
7
+ /** How long the copy button shows its "Copied" state. */
8
+ export declare const CODE_COPIED_MS = 2000;
9
+ /**
10
+ * The copy action: write `text` to the clipboard, flip the copied state on for
11
+ * `resetMs`, and report the text to `onCopy`. A denied clipboard permission
12
+ * must not break the block, so a failed write changes nothing.
13
+ */
14
+ export declare function createCodeCopy(setCopied: (copied: boolean) => void, resetMs?: number): {
15
+ copy(text: string, onCopy?: (text: string) => void): Promise<void>;
16
+ dispose(): void;
17
+ };
18
+ /** The expand button's label. */
19
+ export declare function codeExpandLabel(expanded: boolean, lineCount: number): string;
20
+ /** The copy button's label. */
21
+ export declare function codeCopyLabel(copied: boolean): string;
22
+ //#endregion
23
+ //# sourceMappingURL=code-actions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-actions.d.ts","names":[],"sources":["../../src/code-actions.ts"],"mappings":";;;;;;;qBAOa;;;;;;wBAOG,eACd,YAAY,0BACZ;EAEA,KAAK,cAAc,UAAU,wBAAwB;EACrD;;;wBAsBc,gBAAgB,mBAAmB;;wBAKnC,cAAc"}
@@ -0,0 +1,44 @@
1
+ //#region src/code-actions.ts
2
+ /**
3
+ * The behaviour of a code block, framework-free: the clipboard write with its
4
+ * "Copied" tone window and the button labels. The Code runtime
5
+ * (`./runtime`) wires them; every interactive Astro block hydrates on it.
6
+ */
7
+ /** How long the copy button shows its "Copied" state. */
8
+ const CODE_COPIED_MS = 2e3;
9
+ /**
10
+ * The copy action: write `text` to the clipboard, flip the copied state on for
11
+ * `resetMs`, and report the text to `onCopy`. A denied clipboard permission
12
+ * must not break the block, so a failed write changes nothing.
13
+ */
14
+ function createCodeCopy(setCopied, resetMs = CODE_COPIED_MS) {
15
+ let timer;
16
+ return {
17
+ async copy(text, onCopy) {
18
+ try {
19
+ await navigator.clipboard.writeText(text);
20
+ } catch {
21
+ return;
22
+ }
23
+ setCopied(true);
24
+ onCopy?.(text);
25
+ clearTimeout(timer);
26
+ timer = setTimeout(() => setCopied(false), resetMs);
27
+ },
28
+ dispose() {
29
+ clearTimeout(timer);
30
+ }
31
+ };
32
+ }
33
+ /** The expand button's label. */
34
+ function codeExpandLabel(expanded, lineCount) {
35
+ return expanded ? "Show less" : `Show all ${lineCount} lines`;
36
+ }
37
+ /** The copy button's label. */
38
+ function codeCopyLabel(copied) {
39
+ return copied ? "Copied" : "Copy";
40
+ }
41
+ //#endregion
42
+ export { CODE_COPIED_MS, codeCopyLabel, codeExpandLabel, createCodeCopy };
43
+
44
+ //# sourceMappingURL=code-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-actions.js","names":[],"sources":["../../src/code-actions.ts"],"sourcesContent":["/**\n * The behaviour of a code block, framework-free: the clipboard write with its\n * \"Copied\" tone window and the button labels. The Code runtime\n * (`./runtime`) wires them; every interactive Astro block hydrates on it.\n */\n\n/** How long the copy button shows its \"Copied\" state. */\nexport const CODE_COPIED_MS = 2000;\n\n/**\n * The copy action: write `text` to the clipboard, flip the copied state on for\n * `resetMs`, and report the text to `onCopy`. A denied clipboard permission\n * must not break the block, so a failed write changes nothing.\n */\nexport function createCodeCopy(\n setCopied: (copied: boolean) => void,\n resetMs: number = CODE_COPIED_MS,\n): {\n copy(text: string, onCopy?: (text: string) => void): Promise<void>;\n dispose(): void;\n} {\n let timer: ReturnType<typeof setTimeout> | undefined;\n return {\n async copy(text, onCopy) {\n try {\n await navigator.clipboard.writeText(text);\n } catch {\n return;\n }\n setCopied(true);\n onCopy?.(text);\n clearTimeout(timer);\n timer = setTimeout(() => setCopied(false), resetMs);\n },\n dispose() {\n clearTimeout(timer);\n },\n };\n}\n\n/** The expand button's label. */\nexport function codeExpandLabel(expanded: boolean, lineCount: number): string {\n return expanded ? \"Show less\" : `Show all ${lineCount} lines`;\n}\n\n/** The copy button's label. */\nexport function codeCopyLabel(copied: boolean): string {\n return copied ? \"Copied\" : \"Copy\";\n}\n"],"mappings":";;;;;;;AAOA,MAAa,iBAAiB;;;;;;AAO9B,SAAgB,eACd,WACA,UAAkB,gBAIlB;CACA,IAAI;CACJ,OAAO;EACL,MAAM,KAAK,MAAM,QAAQ;GACvB,IAAI;IACF,MAAM,UAAU,UAAU,UAAU,IAAI;GAC1C,QAAQ;IACN;GACF;GACA,UAAU,IAAI;GACd,SAAS,IAAI;GACb,aAAa,KAAK;GAClB,QAAQ,iBAAiB,UAAU,KAAK,GAAG,OAAO;EACpD;EACA,UAAU;GACR,aAAa,KAAK;EACpB;CACF;AACF;;AAGA,SAAgB,gBAAgB,UAAmB,WAA2B;CAC5E,OAAO,WAAW,cAAc,YAAY,UAAU;AACxD;;AAGA,SAAgB,cAAc,QAAyB;CACrD,OAAO,SAAS,WAAW;AAC7B"}
@@ -1,8 +1,9 @@
1
- import { CodeApi, ConnectCodeOptions } from "./types.js";
1
+ import { _ as ConnectCodeOptions, a as CodeCardFrameNodes, r as CodeCardChrome, t as CodeApi, u as CodeResolvedCardFrame } from "../types-DcQoTmcO.js";
2
+ import { CardFrameProps } from "@pindoba/core-card";
2
3
  //#region src/connect-code.d.ts
3
- declare const codeDefaults: {
4
+ export declare const codeDefaults: {
4
5
  readonly size: "sm";
5
- readonly feedback: "neutral";
6
+ readonly tone: "neutral";
6
7
  readonly wrap: false;
7
8
  readonly showLineNumbers: false;
8
9
  readonly startLine: 1;
@@ -26,7 +27,22 @@ declare const codeDefaults: {
26
27
  * `code` as plain text, so a block without a highlighter is still readable
27
28
  * rather than empty.
28
29
  */
29
- declare function connectCode(options?: ConnectCodeOptions): CodeApi;
30
+ export declare function connectCode(options?: ConnectCodeOptions): CodeApi;
31
+ /**
32
+ * Resolve a framed block's Card: the consumer's `card` prop over the block's
33
+ * own defaults (`api.cardChrome`), with the framework's chrome appended AFTER
34
+ * the consumer's slots — the copy button into the header's trailing slot, the
35
+ * expand button into the footer's trailing slot. The same call in all four
36
+ * frameworks; they differ only in their slot type (Svelte snippets, React /
37
+ * Vue nodes; Astro fills `chrome-*` slots and passes none).
38
+ *
39
+ * - `card.heading` / `card.eyebrow` win over `title` / `lang`.
40
+ * - `card.content` merges over the block's `padding: "none"` default, so
41
+ * `{ contentBackground }` keeps the code edge to edge on an inset panel.
42
+ * - `card.passThrough` merges over `passThrough.card` and the frame styles.
43
+ * - `data-card-kind` (root) and the clamp markers (content) are re-applied
44
+ * last: nothing overrides them.
45
+ */
46
+ export declare function resolveCodeCardFrame<TSlot>(card: CardFrameProps<TSlot> | false | undefined, chrome: CodeCardChrome, nodes?: CodeCardFrameNodes<TSlot>): CodeResolvedCardFrame<TSlot>;
30
47
  //#endregion
31
- export { codeDefaults, connectCode };
32
48
  //# sourceMappingURL=connect-code.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-code.d.ts","names":[],"sources":["../../src/connect-code.ts"],"mappings":";;cAaa;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyDG,YAAY,UAAS,qBAA0B"}
1
+ {"version":3,"file":"connect-code.d.ts","names":[],"sources":["../../src/connect-code.ts"],"mappings":";;;qBAyBa;;;;;;;;;;;;;;;;;;;;;;;;;;wBAyDG,YAAY,UAAS,qBAA0B;;;;;;;;;;;;;;;;wBA2Z/C,qBAAqB,OACnC,MAAM,eAAe,4BACrB,QAAQ,gBACR,QAAO,mBAAmB,SACzB,sBAAsB"}
@@ -1,11 +1,13 @@
1
1
  import { css, cx } from "@pindoba/styled-system/css";
2
2
  import { connectPanel } from "@pindoba/core-panel";
3
- import { defineConnect } from "@pindoba/normalize-props";
3
+ import { reactiveConfig } from "@pindoba/core-runtime/reactive-config";
4
+ import { resolveCardContentSurface, resolveCardFrame } from "@pindoba/core-card";
5
+ import { defineConnect, toClassString } from "@pindoba/normalize-props";
4
6
  import { codeStyles } from "@pindoba/styles-code";
5
7
  //#region src/connect-code.ts
6
8
  const codeDefaults = {
7
9
  size: "sm",
8
- feedback: "neutral",
10
+ tone: "neutral",
9
11
  wrap: false,
10
12
  showLineNumbers: false,
11
13
  startLine: 1,
@@ -42,15 +44,29 @@ function sourceFromLines(lines) {
42
44
  * rather than empty.
43
45
  */
44
46
  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;
47
+ const { lines, code = "", lang, size = codeDefaults.size, tone = codeDefaults.tone, 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, title, card, 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;
48
+ const { reactive: _reactive, ...configInputs } = options;
49
+ const configProps = reactive ? reactiveConfig("code", configInputs) : null;
46
50
  const resolvedLines = lines ?? (code ? linesFromSource(code) : []);
47
51
  const lineCount = resolvedLines.length;
48
52
  const overflowable = maxLines != null && maxLines > 0 && lineCount > maxLines;
49
53
  const clamped = overflowable && !expanded;
54
+ const framed = card != null && card !== false;
55
+ const frameInput = framed ? card : {};
56
+ const cardContent = {
57
+ padding: "none",
58
+ ...frameInput.content
59
+ };
60
+ const { inset, surface: contentSurface } = resolveCardContentSurface(cardContent, frameInput.contentBackground);
61
+ const surfaceBackground = inset ? contentSurface.background : frameInput.background ?? background;
50
62
  const classes = codeStyles.raw({
51
63
  size,
52
64
  wrap,
53
- showLineNumbers
65
+ showLineNumbers,
66
+ ...framed ? {
67
+ framed: true,
68
+ fadeSurface: surfaceBackground
69
+ } : null
54
70
  });
55
71
  const highlighted = new Set(highlightLines ?? []);
56
72
  const items = resolvedLines.map((line, index) => {
@@ -85,14 +101,14 @@ function connectCode(options = {}) {
85
101
  };
86
102
  });
87
103
  const copyText = lines ? sourceFromLines(lines) : code;
88
- const showToolbar = Boolean(lang) || copyable;
104
+ const showToolbar = Boolean(lang) || copyable || Boolean(title);
89
105
  const showExpand = Boolean(collapsible && overflowable);
90
106
  const panelApi = connectPanel({
91
107
  as,
92
108
  dataComponent: "code",
93
109
  background,
94
110
  emphasis,
95
- feedback,
111
+ tone,
96
112
  translucent,
97
113
  padding,
98
114
  radius,
@@ -114,6 +130,7 @@ function connectCode(options = {}) {
114
130
  style: passThrough?.root?.style,
115
131
  props: {
116
132
  ...passThrough?.root?.props,
133
+ ...configProps,
117
134
  "data-component": "code",
118
135
  "data-lang": lang ?? "",
119
136
  "data-clamped": clamped ? "true" : "false",
@@ -123,6 +140,53 @@ function connectCode(options = {}) {
123
140
  class: className,
124
141
  ...rest
125
142
  });
143
+ const rootId = "id" in rest ? rest.id : void 0;
144
+ const cardPassThrough = passThrough?.card ?? {};
145
+ const invariantContentProps = {
146
+ "data-code-body": "",
147
+ "data-lang": lang ?? "",
148
+ "data-clamped": clamped ? "true" : "false",
149
+ ...maxLines != null ? { style: `--code-max-lines:${maxLines}` } : {}
150
+ };
151
+ const cardDefaults = {
152
+ size,
153
+ background,
154
+ tone,
155
+ emphasis,
156
+ ...translucent !== void 0 ? { translucent } : null,
157
+ radius,
158
+ border,
159
+ shadow,
160
+ ...inset ? null : { divided: true },
161
+ content: { padding: "none" }
162
+ };
163
+ const cardChrome = {
164
+ heading: title || void 0,
165
+ eyebrow: lang || void 0,
166
+ headingId: typeof rootId === "string" && rootId !== "" ? `${rootId}-heading` : void 0,
167
+ defaults: cardDefaults,
168
+ rootProps: {
169
+ "data-card-flushable": "",
170
+ ...rest,
171
+ ...passThrough?.root?.props,
172
+ ...configProps
173
+ },
174
+ invariantRootProps: { "data-card-kind": "code" },
175
+ invariantContentProps,
176
+ passThrough: {
177
+ ...cardPassThrough,
178
+ ...passThrough?.root?.style || cardPassThrough.root ? { root: {
179
+ ...cardPassThrough.root,
180
+ style: css.raw(passThrough?.root?.style, cardPassThrough.root?.style)
181
+ } } : null,
182
+ content: {
183
+ ...cardPassThrough.content,
184
+ style: css.raw(classes.frameContent, cardPassThrough.content?.style)
185
+ }
186
+ },
187
+ class: toClassString(className)
188
+ };
189
+ const { card: _cardPassThrough, ...slotPassThrough } = passThrough ?? {};
126
190
  return {
127
191
  ...defineConnect({
128
192
  slots: {
@@ -131,6 +195,10 @@ function connectCode(options = {}) {
131
195
  "data-code-toolbar": "",
132
196
  class: css(classes.toolbar, passThrough?.toolbar?.style)
133
197
  },
198
+ title: {
199
+ "data-code-title": "",
200
+ class: css(classes.title, passThrough?.title?.style)
201
+ },
134
202
  language: {
135
203
  "data-code-language": "",
136
204
  class: css(classes.language, passThrough?.language?.style)
@@ -177,13 +245,16 @@ function connectCode(options = {}) {
177
245
  size: "xs",
178
246
  "aria-expanded": expanded ? "true" : "false",
179
247
  class: css(classes.expandButton, passThrough?.expandButton?.style)
180
- }
248
+ },
249
+ frameContent: { class: css(classes.frameContent) }
181
250
  },
182
251
  passThrough: {
183
- ...passThrough,
252
+ ...slotPassThrough,
184
253
  root: void 0
185
254
  }
186
255
  }),
256
+ frame: framed ? "card" : "bare",
257
+ cardChrome,
187
258
  rootProps: panelApi.rootProps,
188
259
  element: panelApi.element,
189
260
  items,
@@ -194,7 +265,91 @@ function connectCode(options = {}) {
194
265
  lineCount
195
266
  };
196
267
  }
268
+ /** Merge one card slot's passThrough: `over` wins (styles merged, props spread). */
269
+ function mergeCardSlot(base, over) {
270
+ if (!base) return over;
271
+ if (!over) return base;
272
+ return {
273
+ style: css.raw(base.style, over.style),
274
+ props: {
275
+ ...base.props,
276
+ ...over.props
277
+ }
278
+ };
279
+ }
280
+ function slotOf(bag, key) {
281
+ if (!bag) return void 0;
282
+ const entry = Reflect.get(bag, key);
283
+ return typeof entry === "object" && entry !== null ? entry : void 0;
284
+ }
285
+ /** Merge two card passThrough bags slot by slot (`over` wins). */
286
+ function mergeCardPassThrough(base, over) {
287
+ const merged = {};
288
+ const keys = /* @__PURE__ */ new Set([...Object.keys(base), ...Object.keys(over ?? {})]);
289
+ for (const key of keys) merged[key] = mergeCardSlot(slotOf(base, key), slotOf(over, key));
290
+ return merged;
291
+ }
292
+ /**
293
+ * Resolve a framed block's Card: the consumer's `card` prop over the block's
294
+ * own defaults (`api.cardChrome`), with the framework's chrome appended AFTER
295
+ * the consumer's slots — the copy button into the header's trailing slot, the
296
+ * expand button into the footer's trailing slot. The same call in all four
297
+ * frameworks; they differ only in their slot type (Svelte snippets, React /
298
+ * Vue nodes; Astro fills `chrome-*` slots and passes none).
299
+ *
300
+ * - `card.heading` / `card.eyebrow` win over `title` / `lang`.
301
+ * - `card.content` merges over the block's `padding: "none"` default, so
302
+ * `{ contentBackground }` keeps the code edge to edge on an inset panel.
303
+ * - `card.passThrough` merges over `passThrough.card` and the frame styles.
304
+ * - `data-card-kind` (root) and the clamp markers (content) are re-applied
305
+ * last: nothing overrides them.
306
+ */
307
+ function resolveCodeCardFrame(card, chrome, nodes = {}) {
308
+ const frame = card || {};
309
+ const eyebrow = frame.eyebrow ?? chrome.eyebrow;
310
+ const resolved = resolveCardFrame({
311
+ ...frame,
312
+ ...eyebrow !== void 0 ? { eyebrow } : null,
313
+ content: {
314
+ ...chrome.defaults.content,
315
+ ...frame.content
316
+ },
317
+ passThrough: mergeCardPassThrough(chrome.passThrough, frame.passThrough)
318
+ }, {
319
+ heading: chrome.heading,
320
+ headingId: chrome.headingId,
321
+ defaults: chrome.defaults,
322
+ rootProps: chrome.rootProps,
323
+ trailing: nodes.copy,
324
+ footerTrailing: nodes.expand
325
+ });
326
+ const passThrough = resolved.cardProps.passThrough;
327
+ return {
328
+ ...resolved,
329
+ cardProps: {
330
+ ...resolved.cardProps,
331
+ passThrough: {
332
+ ...passThrough,
333
+ root: {
334
+ ...passThrough.root,
335
+ props: {
336
+ ...passThrough.root?.props,
337
+ ...chrome.invariantRootProps
338
+ }
339
+ },
340
+ content: {
341
+ ...passThrough.content,
342
+ props: {
343
+ ...passThrough.content?.props,
344
+ ...chrome.invariantContentProps
345
+ }
346
+ }
347
+ },
348
+ ...chrome.class !== void 0 ? { class: chrome.class } : null
349
+ }
350
+ };
351
+ }
197
352
  //#endregion
198
- export { codeDefaults, connectCode };
353
+ export { codeDefaults, connectCode, resolveCodeCardFrame };
199
354
 
200
355
  //# sourceMappingURL=connect-code.js.map
@@ -1 +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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"}
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 { reactiveConfig } from \"@pindoba/core-runtime/reactive-config\";\nimport {\n resolveCardContentSurface,\n resolveCardFrame,\n type CardFrameProps,\n type CardPassThrough,\n type CardSlotPassThrough,\n} from \"@pindoba/core-card\";\nimport { defineConnect, toClassString } from \"@pindoba/normalize-props\";\nimport { codeStyles } from \"@pindoba/styles-code\";\nimport type {\n CodeApi,\n CodeBaseProps,\n CodeCardChrome,\n CodeCardDefaults,\n CodeCardFrameNodes,\n CodeResolvedCardFrame,\n CodeLine,\n CodeLineItem,\n CodeToken,\n ConnectCodeOptions,\n} from \"./types.js\";\n\nexport const codeDefaults = {\n size: \"sm\",\n tone: \"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 tone = codeDefaults.tone,\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 title,\n card,\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 // The client runtime's hydration payload (`reactive`): every input, so\n // `getPindoba(el, \"code\")` can `update()` the block. Rides the block's root\n // bag — the Card root when framed.\n const { reactive: _reactive, ...configInputs } = options;\n const configProps = reactive ? reactiveConfig(\"code\", configInputs) : null;\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 // Card-optional: bare unless a card object is passed. The bare path must\n // stay byte-identical to the pre-card block, so the card-only recipe\n // variants are added ONLY when framed.\n const framed = card != null && card !== false;\n const frameInput: CardFrameProps = framed ? card : {};\n const cardContent = { padding: \"none\" as const, ...frameInput.content };\n const { inset, surface: contentSurface } = resolveCardContentSurface(\n cardContent,\n frameInput.contentBackground,\n );\n const surfaceBackground = inset\n ? contentSurface.background\n : (frameInput.background ?? background);\n\n const classes = codeStyles.raw({\n size,\n wrap,\n showLineNumbers,\n ...(framed ? { framed: true, fadeSurface: surfaceBackground } : null),\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 || Boolean(title);\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`. `tone` reaches the recipe's\n // `colorPalette.*` reads through the panel's own tone variant.\n const panelApi = connectPanel({\n as,\n dataComponent: \"code\",\n background,\n emphasis,\n tone,\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 ...configProps,\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 // --- Card frame input (used only when `frame === \"card\"`) ---------------\n const rootId: unknown = \"id\" in rest ? rest.id : undefined;\n const cardPassThrough: CardPassThrough = passThrough?.card ?? {};\n // The clamp host: in card mode the content region wraps the scroller + fade,\n // so the markers the bare root carries (and the recipe's `[data-clamped]\n // > &` rules and the Astro boot read) move here. Invariant — a consumer's\n // `card.passThrough.content.props` must not unclamp the block.\n const invariantContentProps: Record<string, unknown> = {\n \"data-code-body\": \"\",\n \"data-lang\": lang ?? \"\",\n \"data-clamped\": clamped ? \"true\" : \"false\",\n ...(maxLines != null ? { style: `--code-max-lines:${maxLines}` } : {}),\n };\n const cardDefaults: CodeCardDefaults = {\n size,\n background,\n tone,\n emphasis,\n ...(translucent !== undefined ? { translucent } : null),\n radius,\n border,\n shadow,\n // A hairline under the header / over the footer stands in for the old\n // toolbar's bottom border. An inset card separates by its panel instead.\n ...(inset ? null : { divided: true }),\n content: { padding: \"none\" },\n };\n const cardChrome: CodeCardChrome = {\n heading: title || undefined,\n eyebrow: lang || undefined,\n headingId:\n typeof rootId === \"string\" && rootId !== \"\"\n ? `${rootId}-heading`\n : undefined,\n defaults: cardDefaults,\n rootProps: {\n \"data-card-flushable\": \"\",\n ...rest,\n ...passThrough?.root?.props,\n ...configProps,\n },\n invariantRootProps: { \"data-card-kind\": \"code\" },\n invariantContentProps,\n passThrough: {\n ...cardPassThrough,\n ...(passThrough?.root?.style || cardPassThrough.root\n ? {\n root: {\n ...cardPassThrough.root,\n style: css.raw(\n passThrough?.root?.style,\n cardPassThrough.root?.style,\n ),\n },\n }\n : null),\n content: {\n ...cardPassThrough.content,\n style: css.raw(classes.frameContent, cardPassThrough.content?.style),\n },\n },\n class: toClassString(className),\n };\n\n // `passThrough.card` is the Card's, not a Code slot's.\n const { card: _cardPassThrough, ...slotPassThrough } = passThrough ?? {};\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 title: {\n \"data-code-title\": \"\",\n class: css(classes.title, passThrough?.title?.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 // Card mode only: the frame styles ride `cardChrome.passThrough.content`\n // into the Card's content bag; nothing spreads this one directly.\n frameContent: {\n class: css(classes.frameContent),\n },\n },\n passThrough: { ...slotPassThrough, root: undefined },\n });\n\n return {\n ...api,\n frame: framed ? \"card\" : \"bare\",\n cardChrome,\n rootProps: panelApi.rootProps,\n element: panelApi.element,\n items,\n copyText,\n showToolbar,\n showExpand,\n overflowable,\n lineCount,\n };\n}\n\n/** Merge one card slot's passThrough: `over` wins (styles merged, props spread). */\nfunction mergeCardSlot(\n base: CardSlotPassThrough | undefined,\n over: CardSlotPassThrough | undefined,\n): CardSlotPassThrough | undefined {\n if (!base) return over;\n if (!over) return base;\n return {\n style: css.raw(base.style, over.style),\n props: { ...base.props, ...over.props },\n };\n}\n\nfunction slotOf(\n bag: CardPassThrough | undefined,\n key: string,\n): CardSlotPassThrough | undefined {\n if (!bag) return undefined;\n const entry: unknown = Reflect.get(bag, key);\n return typeof entry === \"object\" && entry !== null ? entry : undefined;\n}\n\n/** Merge two card passThrough bags slot by slot (`over` wins). */\nfunction mergeCardPassThrough(\n base: CardPassThrough,\n over: CardPassThrough | undefined,\n): CardPassThrough {\n const merged: Record<string, CardSlotPassThrough | undefined> = {};\n const keys = new Set([...Object.keys(base), ...Object.keys(over ?? {})]);\n for (const key of keys) {\n merged[key] = mergeCardSlot(slotOf(base, key), slotOf(over, key));\n }\n return merged;\n}\n\n/**\n * Resolve a framed block's Card: the consumer's `card` prop over the block's\n * own defaults (`api.cardChrome`), with the framework's chrome appended AFTER\n * the consumer's slots — the copy button into the header's trailing slot, the\n * expand button into the footer's trailing slot. The same call in all four\n * frameworks; they differ only in their slot type (Svelte snippets, React /\n * Vue nodes; Astro fills `chrome-*` slots and passes none).\n *\n * - `card.heading` / `card.eyebrow` win over `title` / `lang`.\n * - `card.content` merges over the block's `padding: \"none\"` default, so\n * `{ contentBackground }` keeps the code edge to edge on an inset panel.\n * - `card.passThrough` merges over `passThrough.card` and the frame styles.\n * - `data-card-kind` (root) and the clamp markers (content) are re-applied\n * last: nothing overrides them.\n */\nexport function resolveCodeCardFrame<TSlot>(\n card: CardFrameProps<TSlot> | false | undefined,\n chrome: CodeCardChrome,\n nodes: CodeCardFrameNodes<TSlot> = {},\n): CodeResolvedCardFrame<TSlot> {\n const frame: CardFrameProps<TSlot> = card || {};\n const eyebrow = frame.eyebrow ?? chrome.eyebrow;\n const resolved = resolveCardFrame<TSlot>(\n {\n ...frame,\n ...(eyebrow !== undefined ? { eyebrow } : null),\n content: { ...chrome.defaults.content, ...frame.content },\n passThrough: mergeCardPassThrough(chrome.passThrough, frame.passThrough),\n },\n {\n heading: chrome.heading,\n headingId: chrome.headingId,\n defaults: chrome.defaults,\n rootProps: chrome.rootProps,\n trailing: nodes.copy,\n footerTrailing: nodes.expand,\n },\n );\n const passThrough = resolved.cardProps.passThrough;\n return {\n ...resolved,\n cardProps: {\n ...resolved.cardProps,\n passThrough: {\n ...passThrough,\n root: {\n ...passThrough.root,\n props: { ...passThrough.root?.props, ...chrome.invariantRootProps },\n },\n content: {\n ...passThrough.content,\n props: {\n ...passThrough.content?.props,\n ...chrome.invariantContentProps,\n },\n },\n },\n ...(chrome.class !== undefined ? { class: chrome.class } : null),\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { n as CodeBaseProps, v as ElementAttributes } from "../types-DcQoTmcO.js";
2
+ import { Snippet } from "@pindoba/core-card/runtime";
3
+ import { ComponentRuntime } from "@pindoba/core-runtime";
4
+ //#region src/runtime.d.ts
5
+ export type CodeRuntimeProps = Partial<CodeBaseProps<ElementAttributes, Snippet>> & {
6
+ /** Called after the source has been written to the clipboard. */
7
+ onCopy?: (text: string) => void;
8
+ [key: string]: unknown;
9
+ };
10
+ /** Bare and framed share one state, so `copied` / `expanded` survive a `card` change. */
11
+ export declare const codeRuntime: ComponentRuntime<CodeRuntimeProps>;
12
+ //#endregion
13
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","names":[],"sources":["../../src/runtime.ts"],"mappings":";;;;YAiDY,mBAAmB,QAC7B,cAAc,mBAAmB;;EAGjC,UAAU;GACT;;;qBAoRU,aAAa,iBAAiB"}
@@ -0,0 +1,253 @@
1
+ import { codeCopyLabel, codeExpandLabel, createCodeCopy } from "./code-actions.js";
2
+ import { connectCode, resolveCodeCardFrame } from "./connect-code.js";
3
+ import { buttonRuntime } from "@pindoba/core-button/runtime";
4
+ import { cardFramePropsOf, cardRuntime, componentSnippet, nth, switchMode, textSnippet, treeRegion } from "@pindoba/core-card/runtime";
5
+ import { adopt, computed, onCleanup, rootComponent, scope, untrack } from "@pindoba/core-runtime";
6
+ //#region src/runtime.ts
7
+ /**
8
+ * Code — the vanilla runtime of `code.svelte`.
9
+ *
10
+ * Bare: the Panel root, the optional toolbar (title, language, copy button),
11
+ * the scroller with its lines, the overflow fade and the expand button. Framed
12
+ * (`card`): the Card runtime renders the block from `resolveCodeCardFrame` —
13
+ * the scroller is the card's content, the copy button lands in the header's
14
+ * trailing flank and the expand button in the footer's — exactly the Svelte
15
+ * tree. A structural change re-renders in place (the card root, or the bare
16
+ * root, stays); `card` itself may change too, which swaps the block's root
17
+ * (the hydrated instance follows it).
18
+ *
19
+ * Like the Svelte component it owns `copied` / `expanded` (a click writes
20
+ * them, an incoming prop adopts a new value). The clipboard behaviour is core
21
+ * (`createCodeCopy`); the labels are core (`codeCopyLabel`,
22
+ * `codeExpandLabel`). The buttons are child pindoba components, rendered
23
+ * through the Button runtime.
24
+ */
25
+ function createState(props) {
26
+ const copied = adopt(() => props().copied ?? false);
27
+ const expanded = adopt(() => props().expanded ?? false);
28
+ const copier = createCodeCopy((value) => copied(value));
29
+ onCleanup(() => copier.dispose());
30
+ return {
31
+ copied,
32
+ expanded,
33
+ copier,
34
+ view: computed(() => ({
35
+ api: connectCode({
36
+ ...props(),
37
+ copied: copied(),
38
+ expanded: expanded()
39
+ }),
40
+ props: props()
41
+ }))
42
+ };
43
+ }
44
+ /** The lines (`{#each api.items}`) — rebuilt when their structure changes. */
45
+ function linesShape({ api, props }) {
46
+ return JSON.stringify([Boolean(props.showLineNumbers), api.items.map((l) => [
47
+ l.id,
48
+ Boolean(l.marker && l.markerProps),
49
+ l.tokens.length
50
+ ])]);
51
+ }
52
+ function lineKids(view) {
53
+ const { api, props } = view();
54
+ const lineNumbers = Boolean(props.showLineNumbers);
55
+ return api.items.map((line, i) => {
56
+ const at = () => view().api.items[i];
57
+ const kids = [];
58
+ let child = 0;
59
+ if (lineNumbers) kids.push({
60
+ el: "span",
61
+ select: nth(child++),
62
+ bag: () => at()?.lineNumberProps ?? {},
63
+ kids: [{ text: () => String(at()?.number ?? "") }]
64
+ });
65
+ if (line.marker && line.markerProps) kids.push({
66
+ el: "span",
67
+ select: nth(child++),
68
+ bag: () => at()?.markerProps ?? {},
69
+ kids: [{ text: () => at()?.marker ?? "" }]
70
+ });
71
+ kids.push({
72
+ el: "span",
73
+ select: nth(child),
74
+ bag: () => at()?.lineContentProps ?? {},
75
+ kids: line.tokens.map((_, j) => ({
76
+ el: "span",
77
+ select: nth(j),
78
+ bag: () => at()?.tokens[j]?.tokenProps ?? {},
79
+ kids: [{ text: () => at()?.tokens[j]?.text ?? "" }]
80
+ }))
81
+ });
82
+ return {
83
+ el: "span",
84
+ select: nth(i),
85
+ bag: () => at()?.lineProps ?? {},
86
+ kids
87
+ };
88
+ });
89
+ }
90
+ /** The scroller and (when the block can overflow) its fade (`{#snippet scroller()}`). */
91
+ function scrollerKids(view, fade) {
92
+ const out = [{
93
+ el: "div",
94
+ select: "[data-code-scroller]",
95
+ bag: () => view().api.scrollerProps,
96
+ kids: [{
97
+ el: "pre",
98
+ select: ":scope > pre",
99
+ bag: () => view().api.preProps,
100
+ kids: [{
101
+ el: "code",
102
+ select: ":scope > code",
103
+ bag: () => view().api.codeElProps,
104
+ ref: (code) => treeRegion(code, () => linesShape(view()), () => lineKids(view))
105
+ }]
106
+ }]
107
+ }];
108
+ if (fade) out.push({
109
+ el: "div",
110
+ select: "[data-code-fade]",
111
+ bag: () => view().api.overflowFadeProps
112
+ });
113
+ return out;
114
+ }
115
+ function copyNode(state) {
116
+ return {
117
+ component: buttonRuntime,
118
+ select: "[data-code-copy]",
119
+ props: () => ({
120
+ ...state.view().api.copyButtonProps,
121
+ onclick: () => {
122
+ const { api, props } = state.view();
123
+ state.copier.copy(api.copyText, props.onCopy);
124
+ }
125
+ }),
126
+ children: textSnippet(() => codeCopyLabel(state.copied()))
127
+ };
128
+ }
129
+ function expandNode(state) {
130
+ return {
131
+ component: buttonRuntime,
132
+ select: "[data-code-expand]",
133
+ props: () => ({
134
+ ...state.view().api.expandButtonProps,
135
+ onclick: () => state.expanded(!state.expanded())
136
+ }),
137
+ children: textSnippet(() => codeExpandLabel(state.expanded(), state.view().api.lineCount))
138
+ };
139
+ }
140
+ function bareShape({ api, props }) {
141
+ return JSON.stringify([
142
+ api.showToolbar,
143
+ Boolean(props.title),
144
+ Boolean(props.copyable),
145
+ api.overflowable,
146
+ api.showExpand
147
+ ]);
148
+ }
149
+ function bareKids(state) {
150
+ const { api, props } = state.view();
151
+ const view = state.view;
152
+ const kids = [];
153
+ if (api.showToolbar) {
154
+ const toolbar = [];
155
+ if (props.title) toolbar.push({
156
+ el: "span",
157
+ select: "[data-code-title]",
158
+ bag: () => view().api.titleProps,
159
+ kids: [{ text: () => String(view().props.title ?? "") }]
160
+ });
161
+ toolbar.push({
162
+ el: "span",
163
+ select: "[data-code-language]",
164
+ bag: () => view().api.languageProps,
165
+ kids: [{ text: () => view().props.lang ?? "" }]
166
+ });
167
+ if (props.copyable) toolbar.push(copyNode(state));
168
+ kids.push({
169
+ el: "div",
170
+ select: "[data-code-toolbar]",
171
+ bag: () => view().api.toolbarProps,
172
+ kids: toolbar
173
+ });
174
+ }
175
+ kids.push(...scrollerKids(view, api.overflowable));
176
+ if (api.showExpand) kids.push(expandNode(state));
177
+ return kids;
178
+ }
179
+ const bare = rootComponent({
180
+ state: (props) => untrack(props),
181
+ api: (_props, state) => ({
182
+ tag: state.view().api.element,
183
+ root: state.view().api.rootProps
184
+ }),
185
+ layout: [],
186
+ bind(root, _api, state) {
187
+ treeRegion(root, () => bareShape(state.view()), () => bareKids(state));
188
+ }
189
+ });
190
+ /** The Card the framed block renders (card-frame.svelte over `resolveCodeCardFrame`). */
191
+ function framedProps(state) {
192
+ const copy = componentSnippet(copyNode(state));
193
+ const expand = componentSnippet(expandNode(state));
194
+ const body = (fade) => {
195
+ const snippet = () => {
196
+ const host = document.createElement("div");
197
+ treeRegion(host, () => "", () => scrollerKids(state.view, fade));
198
+ return [...host.childNodes];
199
+ };
200
+ snippet.hydrate = (_nodes, parent) => treeRegion(parent, () => "", () => scrollerKids(state.view, fade));
201
+ return snippet;
202
+ };
203
+ const bodies = {
204
+ true: body(true),
205
+ false: body(false)
206
+ };
207
+ const cache = /* @__PURE__ */ new Map();
208
+ return () => {
209
+ const { api, props } = state.view();
210
+ const frame = resolveCodeCardFrame(props.card, api.cardChrome, {
211
+ copy: props.copyable ? copy : void 0,
212
+ expand: api.showExpand ? expand : void 0
213
+ });
214
+ return {
215
+ ...cardFramePropsOf(frame, cache),
216
+ children: bodies[String(api.overflowable)]
217
+ };
218
+ };
219
+ }
220
+ const isFramed = (props) => props.card != null && props.card !== false;
221
+ function render(state) {
222
+ let cardProps;
223
+ const card = () => cardProps ??= framedProps(state);
224
+ return {
225
+ mount: (mode) => mode === "card" ? cardRuntime.mount(card(), {}) : bare.mount(() => state, {}),
226
+ hydrate: (mode, root) => mode === "card" ? cardRuntime.hydrate(root, card()) : bare.hydrate(root, () => state)
227
+ };
228
+ }
229
+ const modeOf = (state) => () => isFramed(state.view().props) ? "card" : "bare";
230
+ /** Bare and framed share one state, so `copied` / `expanded` survive a `card` change. */
231
+ const codeRuntime = {
232
+ mount(props) {
233
+ let nodes = [];
234
+ const dispose = scope(() => {
235
+ const state = createState(props);
236
+ nodes = switchMode(modeOf(state), render(state));
237
+ });
238
+ return {
239
+ nodes,
240
+ dispose
241
+ };
242
+ },
243
+ hydrate(root, props) {
244
+ return { destroy: scope(() => {
245
+ const state = createState(props);
246
+ switchMode(modeOf(state), render(state), root);
247
+ }) };
248
+ }
249
+ };
250
+ //#endregion
251
+ export { codeRuntime };
252
+
253
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","names":[],"sources":["../../src/runtime.ts"],"sourcesContent":["/**\n * Code — the vanilla runtime of `code.svelte`.\n *\n * Bare: the Panel root, the optional toolbar (title, language, copy button),\n * the scroller with its lines, the overflow fade and the expand button. Framed\n * (`card`): the Card runtime renders the block from `resolveCodeCardFrame` —\n * the scroller is the card's content, the copy button lands in the header's\n * trailing flank and the expand button in the footer's — exactly the Svelte\n * tree. A structural change re-renders in place (the card root, or the bare\n * root, stays); `card` itself may change too, which swaps the block's root\n * (the hydrated instance follows it).\n *\n * Like the Svelte component it owns `copied` / `expanded` (a click writes\n * them, an incoming prop adopts a new value). The clipboard behaviour is core\n * (`createCodeCopy`); the labels are core (`codeCopyLabel`,\n * `codeExpandLabel`). The buttons are child pindoba components, rendered\n * through the Button runtime.\n */\nimport { buttonRuntime } from \"@pindoba/core-button/runtime\";\nimport {\n cardFramePropsOf,\n cardRuntime,\n componentSnippet,\n nth,\n switchMode,\n textSnippet,\n treeRegion,\n type CardFramePlanCache,\n type Snippet,\n type TreeNode,\n} from \"@pindoba/core-card/runtime\";\nimport {\n adopt,\n computed,\n onCleanup,\n rootComponent,\n scope,\n untrack,\n type Accessor,\n type ComponentRuntime,\n} from \"@pindoba/core-runtime\";\nimport {\n codeCopyLabel,\n codeExpandLabel,\n createCodeCopy,\n} from \"./code-actions.js\";\nimport { connectCode, resolveCodeCardFrame } from \"./connect-code.js\";\nimport type { CodeApi, CodeBaseProps, ElementAttributes } from \"./types.js\";\n\nexport type CodeRuntimeProps = Partial<\n CodeBaseProps<ElementAttributes, Snippet>\n> & {\n /** Called after the source has been written to the clipboard. */\n onCopy?: (text: string) => void;\n [key: string]: unknown;\n};\n\ninterface View {\n api: CodeApi;\n props: CodeRuntimeProps;\n}\n\nfunction createState(props: Accessor<CodeRuntimeProps>) {\n const copied = adopt(() => props().copied ?? false);\n const expanded = adopt(() => props().expanded ?? false);\n const copier = createCodeCopy((value) => copied(value));\n onCleanup(() => copier.dispose());\n const view = computed<View>(() => ({\n api: connectCode({\n ...props(),\n copied: copied(),\n expanded: expanded(),\n }),\n props: props(),\n }));\n return { copied, expanded, copier, view };\n}\ntype State = ReturnType<typeof createState>;\n\n/** The lines (`{#each api.items}`) — rebuilt when their structure changes. */\nfunction linesShape({ api, props }: View): string {\n return JSON.stringify([\n Boolean(props.showLineNumbers),\n api.items.map((l) => [\n l.id,\n Boolean(l.marker && l.markerProps),\n l.tokens.length,\n ]),\n ]);\n}\n\nfunction lineKids(view: Accessor<View>): TreeNode[] {\n const { api, props } = view();\n const lineNumbers = Boolean(props.showLineNumbers);\n return api.items.map((line, i) => {\n const at = () => view().api.items[i];\n const kids: TreeNode[] = [];\n let child = 0;\n if (lineNumbers) {\n kids.push({\n el: \"span\",\n select: nth(child++),\n bag: () => at()?.lineNumberProps ?? {},\n kids: [{ text: () => String(at()?.number ?? \"\") }],\n });\n }\n if (line.marker && line.markerProps) {\n kids.push({\n el: \"span\",\n select: nth(child++),\n bag: () => at()?.markerProps ?? {},\n kids: [{ text: () => at()?.marker ?? \"\" }],\n });\n }\n kids.push({\n el: \"span\",\n select: nth(child),\n bag: () => at()?.lineContentProps ?? {},\n kids: line.tokens.map((_, j) => ({\n el: \"span\",\n select: nth(j),\n bag: () => at()?.tokens[j]?.tokenProps ?? {},\n kids: [{ text: () => at()?.tokens[j]?.text ?? \"\" }],\n })),\n });\n return {\n el: \"span\",\n select: nth(i),\n bag: () => at()?.lineProps ?? {},\n kids,\n };\n });\n}\n\n/** The scroller and (when the block can overflow) its fade (`{#snippet scroller()}`). */\nfunction scrollerKids(view: Accessor<View>, fade: boolean): TreeNode[] {\n const out: TreeNode[] = [\n {\n el: \"div\",\n select: \"[data-code-scroller]\",\n bag: () => view().api.scrollerProps,\n kids: [\n {\n el: \"pre\",\n select: \":scope > pre\",\n bag: () => view().api.preProps,\n kids: [\n {\n el: \"code\",\n select: \":scope > code\",\n bag: () => view().api.codeElProps,\n ref: (code) =>\n treeRegion(\n code,\n () => linesShape(view()),\n () => lineKids(view),\n ),\n },\n ],\n },\n ],\n },\n ];\n if (fade) {\n out.push({\n el: \"div\",\n select: \"[data-code-fade]\",\n bag: () => view().api.overflowFadeProps,\n });\n }\n return out;\n}\n\nfunction copyNode(state: State): TreeNode {\n return {\n component: buttonRuntime,\n select: \"[data-code-copy]\",\n props: () => ({\n ...state.view().api.copyButtonProps,\n onclick: () => {\n const { api, props } = state.view();\n void state.copier.copy(api.copyText, props.onCopy);\n },\n }),\n children: textSnippet(() => codeCopyLabel(state.copied())),\n };\n}\n\nfunction expandNode(state: State): TreeNode {\n return {\n component: buttonRuntime,\n select: \"[data-code-expand]\",\n props: () => ({\n ...state.view().api.expandButtonProps,\n onclick: () => state.expanded(!state.expanded()),\n }),\n children: textSnippet(() =>\n codeExpandLabel(state.expanded(), state.view().api.lineCount),\n ),\n };\n}\n\n// ─── bare ───────────────────────────────────────────────────────────────────\n\nfunction bareShape({ api, props }: View): string {\n return JSON.stringify([\n api.showToolbar,\n Boolean(props.title),\n Boolean(props.copyable),\n api.overflowable,\n api.showExpand,\n ]);\n}\n\nfunction bareKids(state: State): TreeNode[] {\n const { api, props } = state.view();\n const view = state.view;\n const kids: TreeNode[] = [];\n if (api.showToolbar) {\n const toolbar: TreeNode[] = [];\n if (props.title) {\n toolbar.push({\n el: \"span\",\n select: \"[data-code-title]\",\n bag: () => view().api.titleProps,\n kids: [{ text: () => String(view().props.title ?? \"\") }],\n });\n }\n toolbar.push({\n el: \"span\",\n select: \"[data-code-language]\",\n bag: () => view().api.languageProps,\n kids: [{ text: () => view().props.lang ?? \"\" }],\n });\n if (props.copyable) toolbar.push(copyNode(state));\n kids.push({\n el: \"div\",\n select: \"[data-code-toolbar]\",\n bag: () => view().api.toolbarProps,\n kids: toolbar,\n });\n }\n kids.push(...scrollerKids(view, api.overflowable));\n if (api.showExpand) kids.push(expandNode(state));\n return kids;\n}\n\nconst bare = rootComponent<State, State>({\n // The props are the shared state itself (see `codeRuntime`).\n state: (props) => untrack(props),\n api: (_props, state) => ({\n tag: state.view().api.element,\n root: state.view().api.rootProps,\n }),\n layout: [],\n bind(root, _api, state) {\n treeRegion(\n root,\n () => bareShape(state.view()),\n () => bareKids(state),\n );\n },\n});\n\n// ─── framed ─────────────────────────────────────────────────────────────────\n\n/** The Card the framed block renders (card-frame.svelte over `resolveCodeCardFrame`). */\nfunction framedProps(state: State) {\n const copy = componentSnippet(copyNode(state));\n const expand = componentSnippet(expandNode(state));\n // The scroller is the card's content; a different snippet per fade\n // presence, so the body re-renders when the block starts / stops\n // overflowing (and is left alone otherwise).\n const body = (fade: boolean): Snippet => {\n const snippet: Snippet = () => {\n const host = document.createElement(\"div\");\n treeRegion(\n host,\n () => \"\",\n () => scrollerKids(state.view, fade),\n );\n return [...host.childNodes];\n };\n snippet.hydrate = (_nodes, parent) =>\n treeRegion(\n parent,\n () => \"\",\n () => scrollerKids(state.view, fade),\n );\n return snippet;\n };\n const bodies = { true: body(true), false: body(false) };\n const cache: CardFramePlanCache = new Map();\n return () => {\n const { api, props } = state.view();\n const frame = resolveCodeCardFrame<Snippet>(props.card, api.cardChrome, {\n copy: props.copyable ? copy : undefined,\n expand: api.showExpand ? expand : undefined,\n });\n return {\n ...cardFramePropsOf(frame, cache),\n children: bodies[String(api.overflowable) as \"true\" | \"false\"],\n };\n };\n}\n\n// ─── the runtime ────────────────────────────────────────────────────────────\n\nconst isFramed = (props: CodeRuntimeProps) =>\n props.card != null && props.card !== false;\n\nfunction render(state: State) {\n let cardProps: ReturnType<typeof framedProps> | undefined;\n const card = () => (cardProps ??= framedProps(state));\n return {\n mount: (mode: \"card\" | \"bare\") =>\n mode === \"card\"\n ? cardRuntime.mount(card(), {})\n : bare.mount(() => state, {}),\n hydrate: (mode: \"card\" | \"bare\", root: Element) =>\n mode === \"card\"\n ? cardRuntime.hydrate(root, card())\n : bare.hydrate(root, () => state),\n };\n}\n\nconst modeOf = (state: State) => () =>\n isFramed(state.view().props) ? (\"card\" as const) : (\"bare\" as const);\n\n/** Bare and framed share one state, so `copied` / `expanded` survive a `card` change. */\nexport const codeRuntime: ComponentRuntime<CodeRuntimeProps> = {\n mount(props) {\n let nodes: Node[] = [];\n const dispose = scope(() => {\n const state = createState(props);\n nodes = switchMode(modeOf(state), render(state));\n });\n return { nodes, dispose };\n },\n hydrate(root, props) {\n const destroy = scope(() => {\n const state = createState(props);\n switchMode(modeOf(state), render(state), root);\n });\n return { destroy };\n },\n};\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { CodeLine } from "./types.js";
1
+ import { s as CodeLine } from "../types-DcQoTmcO.js";
2
2
  //#region src/shiki.d.ts
3
3
  /** The shape of a Shiki themed token — structurally, not by import. */
4
- interface ShikiThemedToken {
4
+ export interface ShikiThemedToken {
5
5
  content: string;
6
6
  color?: string;
7
7
  /** Shiki's font-style bitfield: 1 italic, 2 bold, 4 underline. */
@@ -9,11 +9,11 @@ interface ShikiThemedToken {
9
9
  htmlStyle?: Record<string, string> | string;
10
10
  }
11
11
  /** Shiki's `codeToTokens()` result, narrowed to what the adapter reads. */
12
- interface ShikiTokensResult {
12
+ export interface ShikiTokensResult {
13
13
  tokens: ShikiThemedToken[][];
14
14
  }
15
15
  /** Translate Shiki's bitfield into a CSS declaration string. */
16
- declare function shikiFontStyle(fontStyle: number | undefined): string | undefined;
16
+ export declare function shikiFontStyle(fontStyle: number | undefined): string | undefined;
17
17
  /**
18
18
  * Convert `codeToTokens()` output into the `lines` a `Code` component takes.
19
19
  *
@@ -26,12 +26,11 @@ declare function shikiFontStyle(fontStyle: number | undefined): string | undefin
26
26
  * );
27
27
  * ```
28
28
  */
29
- declare function shikiToLines(result: ShikiTokensResult): CodeLine[];
29
+ export declare function shikiToLines(result: ShikiTokensResult): CodeLine[];
30
30
  /**
31
31
  * Same conversion from a bare token grid, for callers holding
32
32
  * `result.tokens` rather than the whole result object.
33
33
  */
34
- declare function shikiTokensToLines(tokens: ShikiThemedToken[][]): CodeLine[];
34
+ export declare function shikiTokensToLines(tokens: ShikiThemedToken[][]): CodeLine[];
35
35
  //#endregion
36
- export { ShikiThemedToken, ShikiTokensResult, shikiFontStyle, shikiToLines, shikiTokensToLines };
37
36
  //# sourceMappingURL=shiki.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"shiki.d.ts","names":[],"sources":["../../src/shiki.ts"],"mappings":";;;iBAgBiB;EACf;EACA;;EAEA;EACA,YAAY;;;iBAIG;EACf,QAAQ;;;wBASM,eACd;;;;;;;;;;;;;wBAgCc,aAAa,QAAQ,oBAAoB;;;;;wBAQzC,mBAAmB,QAAQ,uBAAuB"}
@@ -1,12 +1,13 @@
1
1
  import { PanelElement, PanelElement as PanelElement$1, PanelInheritedProps, PanelRootProps, PanelRootProps as PanelRootProps$1 } from "@pindoba/core-panel";
2
+ import { CardFrameProps, CardFrameSlotInput, CardPassThrough, ResolvedCardFrame } from "@pindoba/core-card";
2
3
  import { ConnectReturn } from "@pindoba/normalize-props";
3
4
  import { CodeSlots, CodeStyleProps } from "@pindoba/styles-code";
4
5
  import { SystemStyleObject } from "@pindoba/styled-system/types";
5
- import { PanelStyleProps } from "@pindoba/styles-panel";
6
+ import { PanelTone } from "@pindoba/styles-panel";
6
7
  //#region src/types.d.ts
7
8
  type ElementAttributes = Partial<Record<string, unknown>>;
8
9
  type CodeSize = NonNullable<CodeStyleProps["size"]>;
9
- type CodeFeedback = NonNullable<PanelStyleProps["feedback"]>;
10
+ type CodeTone = PanelTone;
10
11
  /**
11
12
  * One coloured run of text within a line.
12
13
  *
@@ -40,8 +41,22 @@ interface CodeSlotPassThrough<T = ElementAttributes> {
40
41
  style?: SystemStyleObject;
41
42
  props?: T;
42
43
  }
43
- type CodePassThrough<RootElementAttributes = ElementAttributes> = { [K in CodeSlots]?: CodeSlotPassThrough<K extends "root" ? RootElementAttributes : ElementAttributes>; };
44
- interface CodeBaseProps<RootElementAttributes = ElementAttributes> extends Omit<PanelInheritedProps<RootElementAttributes>, "passThrough"> {
44
+ /** Recipe slots that are card-mode styling hooks, not consumer-addressable elements. */
45
+ type CodeInternalSlots = "frameContent";
46
+ type CodePassThrough<RootElementAttributes = ElementAttributes> = { [K in Exclude<CodeSlots, CodeInternalSlots>]?: CodeSlotPassThrough<K extends "root" ? RootElementAttributes : ElementAttributes>; } & {
47
+ /**
48
+ * Card mode: passThrough forwarded to the Card (`root`, `header`, `content`,
49
+ * `footer`, …). Merged under `card.passThrough`. In card mode
50
+ * `passThrough.root` still reaches the Card root.
51
+ */
52
+ card?: CardPassThrough;
53
+ };
54
+ /**
55
+ * The `card` prop: frame the block in a Card. Every Card frame prop is
56
+ * accepted; `heading` defaults to `title` and `eyebrow` to `lang`.
57
+ */
58
+ type CodeCardProps<TSlot = unknown> = CardFrameProps<TSlot>;
59
+ interface CodeBaseProps<RootElementAttributes = ElementAttributes, TSlot = unknown> extends Omit<PanelInheritedProps<RootElementAttributes>, "passThrough"> {
45
60
  /**
46
61
  * Pre-tokenized lines from a highlighter. When omitted, `code` is rendered
47
62
  * as unhighlighted plain text — so the component degrades to a readable
@@ -56,11 +71,26 @@ interface CodeBaseProps<RootElementAttributes = ElementAttributes> extends Omit<
56
71
  */
57
72
  code?: string;
58
73
  /**
59
- * Language label shown in the toolbar. Purely presentational — the component
60
- * does no highlighting of its own.
74
+ * Language label shown in the toolbar (the card eyebrow when framed).
75
+ * Purely presentational — the component does no highlighting of its own.
61
76
  * @group Content
62
77
  */
63
78
  lang?: string;
79
+ /**
80
+ * A title for the block, e.g. its filename. Bare: the toolbar's leading
81
+ * text, before the language label. Framed (`card`): the card heading.
82
+ * @group Content
83
+ */
84
+ title?: string;
85
+ /**
86
+ * Frame the block in a Card. Unset or `false` renders the bare block (the
87
+ * default). With an object, `title` becomes the card heading, `lang` the
88
+ * eyebrow, the copy button moves to the header's trailing slot, the expand
89
+ * button to the footer, and the scroller is the card content
90
+ * (`content.padding: "none"`; set `contentBackground` for an inset panel).
91
+ * @group Appearance
92
+ */
93
+ card?: CodeCardProps<TSlot> | false;
64
94
  /**
65
95
  * Type scale of the block. `xs` and `sm` currently render at the same font
66
96
  * size — the scale's smallest step is `xs`, so separating them means moving
@@ -158,11 +188,63 @@ interface CodeLineItem {
158
188
  markerProps?: Record<string, unknown>;
159
189
  tokens: CodeTokenItem[];
160
190
  }
191
+ /** The card defaults the block derives from its own surface props. */
192
+ type CodeCardDefaults = Pick<CardFrameProps, "size" | "background" | "tone" | "emphasis" | "translucent" | "radius" | "border" | "shadow" | "divided" | "content">;
193
+ /**
194
+ * Everything `connectCode` resolves for the block's Card frame except the
195
+ * framework's own chrome nodes (copy / expand buttons). Feed it to
196
+ * `resolveCodeCardFrame(card, api.cardChrome, nodes)`.
197
+ */
198
+ interface CodeCardChrome {
199
+ /** The card heading the block derives itself — its `title`. */
200
+ heading: string | undefined;
201
+ /** The card eyebrow the block derives itself — its `lang`. */
202
+ eyebrow: string | undefined;
203
+ /** Deterministic heading id (`${id}-heading`) when the block has an `id`. */
204
+ headingId: string | undefined;
205
+ /** The block's surface as card defaults (under the consumer's `card`). */
206
+ defaults: CodeCardDefaults;
207
+ /** Card root attributes: flush marker, the block's HTML attributes, `passThrough.root.props`. */
208
+ rootProps: Record<string, unknown>;
209
+ /** Card root attributes nothing may override (`data-card-kind`). */
210
+ invariantRootProps: Record<string, unknown>;
211
+ /**
212
+ * Card content attributes nothing may override: the clamp host markers
213
+ * (`data-code-body`, `data-lang`, `data-clamped`, `--code-max-lines`).
214
+ */
215
+ invariantContentProps: Record<string, unknown>;
216
+ /** `passThrough.card` + the block's frame styles (`passThrough.root.style` included). */
217
+ passThrough: CardPassThrough;
218
+ /** The consumer's `class`, merged onto the card root. */
219
+ class: string | undefined;
220
+ }
221
+ /** The chrome a framework relocates into the block's Card. */
222
+ interface CodeCardFrameNodes<TSlot> {
223
+ /** The copy button → header trailing (after the consumer's `card.trailing`). */
224
+ copy?: CardFrameSlotInput<TSlot>;
225
+ /** The expand button → footer trailing (after the consumer's `card.footer.trailing`). */
226
+ expand?: CardFrameSlotInput<TSlot>;
227
+ }
228
+ /** `resolveCodeCardFrame()` — a resolved card frame whose root also carries the block's `class`. */
229
+ type CodeResolvedCardFrame<TSlot> = ResolvedCardFrame<TSlot> & {
230
+ cardProps: {
231
+ class?: string;
232
+ };
233
+ };
161
234
  type CodeApi = ConnectReturn<CodeSlots> & {
235
+ /**
236
+ * `"bare"` (default, and `card={false}`) — render the block root
237
+ * `<element {...rootProps}>` with its toolbar. `"card"` (`card={{…}}`) —
238
+ * render `<CardFrame>` from `resolveCodeCardFrame(card, cardChrome, nodes)`
239
+ * with the scroller + fade as its content.
240
+ */
241
+ frame: "card" | "bare";
242
+ /** The card frame input (card mode). See {@link CodeCardChrome}. */
243
+ cardChrome: CodeCardChrome;
162
244
  /** The panel-produced root bag (`data-component="code"` + the nest hook). */
163
- rootProps: PanelRootProps$1;
245
+ rootProps: PanelRootProps;
164
246
  /** Resolved root tag from `as` — templates render this element. */
165
- element: PanelElement$1;
247
+ element: PanelElement;
166
248
  /** Per-line bags, in order. */
167
249
  items: CodeLineItem[];
168
250
  /** The exact text the copy button should write to the clipboard. */
@@ -181,5 +263,5 @@ type CodeApi = ConnectReturn<CodeSlots> & {
181
263
  lineCount: number;
182
264
  };
183
265
  //#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
266
+ export { ConnectCodeOptions as _, CodeCardFrameNodes as a, PanelRootProps$1 as b, CodeLineItem as c, CodeSize as d, CodeSlotPassThrough as f, CodeTone as g, CodeTokenItem as h, CodeCardDefaults as i, CodePassThrough as l, CodeToken as m, CodeBaseProps as n, CodeCardProps as o, CodeSlots as p, CodeCardChrome as r, CodeLine as s, CodeApi as t, CodeResolvedCardFrame as u, ElementAttributes as v, PanelElement$1 as y };
267
+ //# sourceMappingURL=types-DcQoTmcO.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-DcQoTmcO.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;KAmBY,oBAAoB,QAAQ;KAE5B,WAAW,YAAY;KACvB,WAAW;;;;;;;;;;;;;;;UAkBN;EACf;;EAEA;;EAEA;;EAEA;;;UAIe;EACf,QAAQ;;EAER;;UAKe,oBAAoB,IAAI;EACvC,QAAQ;EACR,QAAQ;;;KAIL;KAEO,gBAAgB,wBAAwB,wBACjD,KAAK,QAAQ,WAAW,sBAAsB,oBAC7C,mBAAmB,wBAAwB;;;;;;EAQ7C,OAAO;;;;;;KASG,cAAc,mBAAmB,eAAe;UAE3C,cACf,wBAAwB,mBACxB,yBAOQ,KAAK,oBAAoB;;;;;;;EAOjC,QAAQ;;;;;;EAMR;;;;;;EAMA;;;;;;EAMA;;;;;;;;;EASA,OAAO,cAAc;;;;;;;;EAQrB,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;;;KAIE,mBAAmB,KAC7B;;;;;;UAkBe;;EAEf;;EAEA;;EAEA;;EAEA,UAAU;;EAEV,WAAW;;EAEX,oBAAoB;;;;;EAKpB,uBAAuB;;EAEvB,aAAa;;EAEb;;;UAIe,mBAAmB;;EAElC,OAAO,mBAAmB;;EAE1B,SAAS,mBAAmB;;;KAIlB,sBAAsB,SAAS,kBAAkB;EAC3D;IAAa;;;KAGH,UAAU,cAAc;;;;;;;EAOlC;;EAEA,YAAY;;EAEZ,WAAW;;EAEX,SAAS;;EAET,OAAO;;EAEP;;EAEA;;EAEA;;;;;;EAMA;;EAEA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pindoba/core-code",
3
- "version": "0.0.0-alpha-20260829223243",
3
+ "version": "0.0.0-alpha-20261110151933",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
@@ -11,24 +11,33 @@
11
11
  "types": "./dist/index.d.ts",
12
12
  "import": "./dist/index.js"
13
13
  },
14
+ "./runtime": {
15
+ "types": "./dist/src/runtime.d.ts",
16
+ "import": "./dist/src/runtime.js"
17
+ },
14
18
  "./shiki": {
15
19
  "types": "./dist/src/shiki.d.ts",
16
20
  "import": "./dist/src/shiki.js"
17
21
  }
18
22
  },
19
23
  "files": [
20
- "dist"
24
+ "dist",
25
+ "!dist/**/__test__"
21
26
  ],
22
27
  "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
+ "@pindoba/core-button": "0.0.0-alpha-20261110151933",
29
+ "@pindoba/core-card": "0.0.0-alpha-20261110151933",
30
+ "@pindoba/core-panel": "0.0.0-alpha-20261110151933",
31
+ "@pindoba/core-runtime": "0.0.0-alpha-20261110151933",
32
+ "@pindoba/normalize-props": "0.0.0-alpha-20261107033529",
33
+ "@pindoba/styled-system": "0.0.0-alpha-20261110151933",
34
+ "@pindoba/styles-code": "0.0.0-alpha-20261110151933",
35
+ "@pindoba/styles-panel": "0.0.0-alpha-20261110151933"
28
36
  },
29
37
  "devDependencies": {
38
+ "@pindoba/build-config": "0.0.0",
30
39
  "@pindoba/typescript-config": "0.0.0-alpha-20260320034942",
31
- "tsdown": "^0.22.14",
40
+ "tsdown": "^0.23.0",
32
41
  "typescript": "^7.0.2"
33
42
  },
34
43
  "peerDependencies": {
@@ -1 +0,0 @@
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"}
package/dist/src/types.js DELETED
@@ -1 +0,0 @@
1
- export {};