@refrakt-md/cli 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +66 -0
- package/dist/bin.js.map +1 -1
- package/dist/commands/gallery.d.ts +16 -0
- package/dist/commands/gallery.d.ts.map +1 -0
- package/dist/commands/gallery.js +323 -0
- package/dist/commands/gallery.js.map +1 -0
- package/dist/commands/inspect.js +5 -3
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/migrate.d.ts +11 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +170 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/plugin-validate.d.ts.map +1 -1
- package/dist/commands/plugin-validate.js +54 -6
- package/dist/commands/plugin-validate.js.map +1 -1
- package/dist/lib/fixtures.d.ts +9 -6
- package/dist/lib/fixtures.d.ts.map +1 -1
- package/dist/lib/fixtures.js +20 -119
- package/dist/lib/fixtures.js.map +1 -1
- package/dist/lib/gallery.d.ts +60 -0
- package/dist/lib/gallery.d.ts.map +1 -0
- package/dist/lib/gallery.js +192 -0
- package/dist/lib/gallery.js.map +1 -0
- package/package.json +7 -5
package/dist/lib/fixtures.js
CHANGED
|
@@ -1,135 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Fixture resolution for the inspect/gallery commands.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* The example content itself is the unified, generated `RUNE_EXAMPLES` manifest
|
|
5
|
+
* from `@refrakt-md/runes` (source: `packages/runes/fixtures/*.md` — SPEC-102 /
|
|
6
|
+
* WORK-411). Plugin fixtures layer on top at the call site; this module just
|
|
7
|
+
* resolves a rune name to a source string and applies attribute overrides.
|
|
6
8
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## Configuration
|
|
16
|
-
Theme configuration is defined in a TypeScript file that exports a ThemeConfig object.
|
|
17
|
-
|
|
18
|
-
## Deployment
|
|
19
|
-
Once your theme is ready, publish it to npm and register it in the theme marketplace.
|
|
20
|
-
{% /accordion %}`,
|
|
21
|
-
details: `{% details %}
|
|
22
|
-
## Implementation Notes
|
|
23
|
-
This section contains additional technical details about how the transform pipeline processes rune content. The identity transform reads meta tags, applies BEM classes, and injects structural elements before the content reaches the renderer.
|
|
24
|
-
{% /details %}`,
|
|
25
|
-
grid: `{% grid %}
|
|
26
|
-
First column content with enough text to demonstrate layout behavior.
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
Second column content showing how grid cells are separated by horizontal rules.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
Third column content completing the three-column grid layout example.
|
|
35
|
-
{% /grid %}`,
|
|
36
|
-
figure: `{% figure size="large" align="center" %}
|
|
37
|
-

|
|
38
|
-
|
|
39
|
-
A panoramic view of the Norwegian fjords at sunset, captured from the summit of Trolltunga.
|
|
40
|
-
{% /figure %}`,
|
|
41
|
-
tabs: `{% tabs %}
|
|
42
|
-
# JavaScript
|
|
43
|
-
\`\`\`js
|
|
44
|
-
const greeting = "Hello, world!";
|
|
45
|
-
console.log(greeting);
|
|
46
|
-
\`\`\`
|
|
47
|
-
|
|
48
|
-
# TypeScript
|
|
49
|
-
\`\`\`ts
|
|
50
|
-
const greeting: string = "Hello, world!";
|
|
51
|
-
console.log(greeting);
|
|
52
|
-
\`\`\`
|
|
53
|
-
|
|
54
|
-
# Python
|
|
55
|
-
\`\`\`python
|
|
56
|
-
greeting = "Hello, world!"
|
|
57
|
-
print(greeting)
|
|
58
|
-
\`\`\`
|
|
59
|
-
{% /tabs %}`,
|
|
60
|
-
conversation: `{% conversation %}
|
|
61
|
-
> **Alice** — Have you tried the new inspect command?
|
|
62
|
-
|
|
63
|
-
> **Bob** — Yes! It shows exactly what HTML the identity transform produces. No more guessing which selectors to target.
|
|
64
|
-
|
|
65
|
-
> **Alice** — The variant expansion is my favorite part. You can see every modifier value at once.
|
|
66
|
-
{% /conversation %}`,
|
|
67
|
-
sidenote: `{% sidenote variant="sidenote" %}
|
|
68
|
-
This is a margin note that appears alongside the main content, providing additional context without interrupting the reading flow.
|
|
69
|
-
{% /sidenote %}`,
|
|
70
|
-
diff: `{% diff mode="unified" %}
|
|
71
|
-
\`\`\`ts
|
|
72
|
-
const config = {
|
|
73
|
-
prefix: 'rf',
|
|
74
|
-
runes: {}
|
|
75
|
-
};
|
|
76
|
-
\`\`\`
|
|
77
|
-
|
|
78
|
-
\`\`\`ts
|
|
79
|
-
const config = {
|
|
80
|
-
prefix: 'rf',
|
|
81
|
-
tokenPrefix: '--rf',
|
|
82
|
-
icons: {},
|
|
83
|
-
runes: {}
|
|
84
|
-
};
|
|
85
|
-
\`\`\`
|
|
86
|
-
{% /diff %}`,
|
|
87
|
-
datatable: `{% datatable %}
|
|
88
|
-
| Name | Role | Department | Status |
|
|
89
|
-
|------|------|------------|--------|
|
|
90
|
-
| Alice | Engineer | Platform | Active |
|
|
91
|
-
| Bob | Designer | Product | Active |
|
|
92
|
-
| Carol | Manager | Engineering | On Leave |
|
|
93
|
-
{% /datatable %}`,
|
|
94
|
-
form: `{% form method="POST" variant="stacked" %}
|
|
95
|
-
- Name
|
|
96
|
-
- Email
|
|
97
|
-
- Message (textarea)
|
|
98
|
-
|
|
99
|
-
> How did you hear about us?
|
|
100
|
-
- Search engine
|
|
101
|
-
- Social media
|
|
102
|
-
- Friend referral
|
|
103
|
-
- Other
|
|
104
|
-
|
|
105
|
-
**Submit**
|
|
106
|
-
{% /form %}`,
|
|
107
|
-
nav: `{% nav %}
|
|
108
|
-
- [Docs](/docs)
|
|
109
|
-
- [Blog](/blog)
|
|
110
|
-
|
|
111
|
-
## Product
|
|
112
|
-
- pricing
|
|
113
|
-
- features
|
|
114
|
-
|
|
115
|
-
## Resources
|
|
116
|
-
- about
|
|
117
|
-
- changelog
|
|
118
|
-
{% /nav %}`,
|
|
119
|
-
pagination: `{% pagination prev="install" next="configuration" /%}`,
|
|
120
|
-
};
|
|
9
|
+
import { RUNE_EXAMPLES } from '@refrakt-md/runes';
|
|
10
|
+
/** Built-in fixture strings, keyed by rune name. Generated from fixtures/*.md. */
|
|
11
|
+
export const fixtures = RUNE_EXAMPLES;
|
|
12
|
+
/** Whether a rune has a real fixture (plugin fixture or the unified manifest),
|
|
13
|
+
* i.e. `getFixture` would return authored content rather than the stub. */
|
|
14
|
+
export function hasFixture(runeName, packageFixtures) {
|
|
15
|
+
return Boolean(packageFixtures?.[runeName] ?? fixtures[runeName]);
|
|
16
|
+
}
|
|
121
17
|
/** Get a fixture for a rune, with optional attribute overrides applied to the source */
|
|
122
18
|
export function getFixture(runeName, attrOverrides) {
|
|
123
|
-
// Look up by primary name or try as-is
|
|
124
19
|
const source = fixtures[runeName];
|
|
125
20
|
if (!source) {
|
|
126
21
|
// Generate a minimal fixture for unknown runes
|
|
127
22
|
return `{% ${runeName} %}\nSample content for the ${runeName} rune.\n{% /${runeName} %}`;
|
|
128
23
|
}
|
|
24
|
+
return applyFixtureOverrides(source, runeName, attrOverrides);
|
|
25
|
+
}
|
|
26
|
+
/** Apply attribute overrides to an arbitrary fixture source (e.g. a plugin
|
|
27
|
+
* fixture). Returns the source unchanged when there are no overrides. Shared by
|
|
28
|
+
* `getFixture` and the inspect/gallery variant matrices so plugin fixtures get
|
|
29
|
+
* the same variant expansion as core ones. */
|
|
30
|
+
export function applyFixtureOverrides(source, runeName, attrOverrides) {
|
|
129
31
|
if (!attrOverrides || Object.keys(attrOverrides).length === 0) {
|
|
130
32
|
return source;
|
|
131
33
|
}
|
|
132
|
-
// Apply attribute overrides by modifying the opening tag
|
|
133
34
|
return applyOverrides(source, runeName, attrOverrides);
|
|
134
35
|
}
|
|
135
36
|
/** Replace or add attributes in the opening tag of a fixture */
|
package/dist/lib/fixtures.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/lib/fixtures.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/lib/fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,kFAAkF;AAClF,MAAM,CAAC,MAAM,QAAQ,GAA2B,aAAa,CAAC;AAE9D;4EAC4E;AAC5E,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,eAAwC;IACpF,OAAO,OAAO,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,UAAU,CAAC,QAAgB,EAAE,aAAsC;IAClF,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,+CAA+C;QAC/C,OAAO,MAAM,QAAQ,+BAA+B,QAAQ,eAAe,QAAQ,KAAK,CAAC;IAC1F,CAAC;IAED,OAAO,qBAAqB,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AAC/D,CAAC;AAED;;;+CAG+C;AAC/C,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,QAAgB,EAAE,aAAsC;IAC7G,IAAI,CAAC,aAAa,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AACxD,CAAC;AAED,gEAAgE;AAChE,SAAS,cAAc,CAAC,MAAc,EAAE,OAAe,EAAE,SAAiC;IACzF,iEAAiE;IACjE,MAAM,cAAc,GAAG,IAAI,MAAM,CAAC,YAAY,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACvF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAE1B,qFAAqF;IACrF,IAAI,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACtD,oCAAoC;QACpC,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9D,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,GAAG,KAAK,KAAK,GAAG,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACP,oBAAoB;YACpB,UAAU,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC;QAC3D,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,OAAO,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively inline `@import` statements into a single CSS string so the gallery
|
|
3
|
+
* is self-contained (no path/serving concerns, deterministic for screenshots).
|
|
4
|
+
*
|
|
5
|
+
* Handles three forms so the skeleton/skin split (SPEC-094 §3) renders faithfully:
|
|
6
|
+
* - relative imports (`@import './x.css';`) — inlined from disk;
|
|
7
|
+
* - bare package specifiers (`@import '@refrakt-md/skeleton';`) — resolved via
|
|
8
|
+
* node (the package's CSS `.` export) and inlined, so the shared structural
|
|
9
|
+
* layer is part of the gallery;
|
|
10
|
+
* - layered imports (`@import './x.css' layer(skeleton);`) — inlined and wrapped
|
|
11
|
+
* in `@layer <name> { … }` so the cascade-layer ordering survives flattening
|
|
12
|
+
* (otherwise layered structure inlines as unlayered and would beat the skin).
|
|
13
|
+
*
|
|
14
|
+
* A `seen` set guards against import cycles; genuinely-remote imports (web fonts)
|
|
15
|
+
* are left untouched.
|
|
16
|
+
*/
|
|
17
|
+
export declare function flattenCssImports(entryPath: string, seen?: Set<string>): string;
|
|
18
|
+
/** One rendered rune variant in the gallery. */
|
|
19
|
+
export interface GalleryCell {
|
|
20
|
+
/** Rune name (e.g. `hint`). */
|
|
21
|
+
rune: string;
|
|
22
|
+
/** Variant key (e.g. `default`, `type-warning`). */
|
|
23
|
+
variant: string;
|
|
24
|
+
/** Rendered HTML for this variant. */
|
|
25
|
+
html: string;
|
|
26
|
+
}
|
|
27
|
+
export interface GalleryDocumentOptions {
|
|
28
|
+
mode: 'light' | 'dark';
|
|
29
|
+
/** Flattened, self-contained theme CSS. */
|
|
30
|
+
themeCss: string;
|
|
31
|
+
cells: GalleryCell[];
|
|
32
|
+
/** Optional override for the font `<link>` tags injected into `<head>`. */
|
|
33
|
+
fontLinks?: string;
|
|
34
|
+
/** Optional bundled behaviors IIFE, inlined before `</body>` so interactive /
|
|
35
|
+
* lifecycle runes (tabs, diagram, chart, nav) enhance/render. */
|
|
36
|
+
behaviorScript?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface LayoutDocumentOptions {
|
|
39
|
+
mode: 'light' | 'dark';
|
|
40
|
+
themeCss: string;
|
|
41
|
+
/** The layout's rendered HTML (from `layoutTransform` → `renderToHtml`). */
|
|
42
|
+
bodyHtml: string;
|
|
43
|
+
/** Layout name, for the document title. */
|
|
44
|
+
name: string;
|
|
45
|
+
fontLinks?: string;
|
|
46
|
+
behaviorScript?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Render a standalone full-page document for a layout fixture — the layout's
|
|
50
|
+
* own chrome *is* the page (no gallery cell grid), so the harness can shoot it
|
|
51
|
+
* whole-page at multiple viewports.
|
|
52
|
+
*/
|
|
53
|
+
export declare function renderLayoutDocument(opts: LayoutDocumentOptions): string;
|
|
54
|
+
/**
|
|
55
|
+
* Render the full self-contained gallery HTML document for one mode. Cells are
|
|
56
|
+
* grouped by rune; each carries a stable `data-gallery-cell="<rune>--<variant>"`
|
|
57
|
+
* anchor so the harness ({% WORK-409 %}) can clip per variant.
|
|
58
|
+
*/
|
|
59
|
+
export declare function renderGalleryDocument(opts: GalleryDocumentOptions): string;
|
|
60
|
+
//# sourceMappingURL=gallery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gallery.d.ts","sourceRoot":"","sources":["../../src/lib/gallery.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,GAAG,MAAM,CAyB1F;AAED,gDAAgD;AAChD,MAAM,WAAW,WAAW;IAC3B,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;sEACkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAyED,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CAsBxE;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CA8C1E"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
const requireFrom = createRequire(import.meta.url);
|
|
5
|
+
/**
|
|
6
|
+
* Recursively inline `@import` statements into a single CSS string so the gallery
|
|
7
|
+
* is self-contained (no path/serving concerns, deterministic for screenshots).
|
|
8
|
+
*
|
|
9
|
+
* Handles three forms so the skeleton/skin split (SPEC-094 §3) renders faithfully:
|
|
10
|
+
* - relative imports (`@import './x.css';`) — inlined from disk;
|
|
11
|
+
* - bare package specifiers (`@import '@refrakt-md/skeleton';`) — resolved via
|
|
12
|
+
* node (the package's CSS `.` export) and inlined, so the shared structural
|
|
13
|
+
* layer is part of the gallery;
|
|
14
|
+
* - layered imports (`@import './x.css' layer(skeleton);`) — inlined and wrapped
|
|
15
|
+
* in `@layer <name> { … }` so the cascade-layer ordering survives flattening
|
|
16
|
+
* (otherwise layered structure inlines as unlayered and would beat the skin).
|
|
17
|
+
*
|
|
18
|
+
* A `seen` set guards against import cycles; genuinely-remote imports (web fonts)
|
|
19
|
+
* are left untouched.
|
|
20
|
+
*/
|
|
21
|
+
export function flattenCssImports(entryPath, seen = new Set()) {
|
|
22
|
+
const abs = resolve(entryPath);
|
|
23
|
+
if (seen.has(abs))
|
|
24
|
+
return '';
|
|
25
|
+
seen.add(abs);
|
|
26
|
+
const dir = dirname(abs);
|
|
27
|
+
const css = readFileSync(abs, 'utf-8');
|
|
28
|
+
return css.replace(/@import\s+(?:url\()?['"]([^'"]+)['"]\)?\s*(?:layer\(([^)]*)\))?\s*;/g, (match, importPath, layerName) => {
|
|
29
|
+
let resolved;
|
|
30
|
+
if (importPath.startsWith('.')) {
|
|
31
|
+
resolved = resolve(dir, importPath);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
try {
|
|
35
|
+
resolved = requireFrom.resolve(importPath);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return match; // leave unresolvable/remote imports as-is
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const inlined = flattenCssImports(resolved, seen);
|
|
42
|
+
return layerName !== undefined ? `@layer ${layerName.trim()} {\n${inlined}\n}` : inlined;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** Default web-font links — tactically Lumina's families (WORK-407 defers the
|
|
46
|
+
* theme-owned-font system). The harness needs fonts actually loaded for stable
|
|
47
|
+
* screenshots. */
|
|
48
|
+
const DEFAULT_FONT_LINKS = [
|
|
49
|
+
'<link rel="preconnect" href="https://fonts.googleapis.com">',
|
|
50
|
+
'<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>',
|
|
51
|
+
'<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300..700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">',
|
|
52
|
+
].join('\n');
|
|
53
|
+
/** Gallery chrome + determinism CSS. Kills animation/transition/caret so
|
|
54
|
+
* screenshots are stable; lays out runes in labelled cells. */
|
|
55
|
+
const GALLERY_CSS = `
|
|
56
|
+
*, *::before, *::after {
|
|
57
|
+
animation-duration: 0s !important;
|
|
58
|
+
animation-delay: 0s !important;
|
|
59
|
+
transition-duration: 0s !important;
|
|
60
|
+
transition-delay: 0s !important;
|
|
61
|
+
caret-color: transparent !important;
|
|
62
|
+
scroll-behavior: auto !important;
|
|
63
|
+
}
|
|
64
|
+
body.rf-gallery {
|
|
65
|
+
background: var(--rf-color-bg);
|
|
66
|
+
color: var(--rf-color-text);
|
|
67
|
+
font-family: var(--rf-font-sans, sans-serif);
|
|
68
|
+
margin: 0;
|
|
69
|
+
padding: 2.5rem 1.5rem;
|
|
70
|
+
}
|
|
71
|
+
.rf-gallery__inner { max-width: 72rem; margin: 0 auto; }
|
|
72
|
+
.rf-gallery__rune { margin: 0 0 3.5rem; }
|
|
73
|
+
.rf-gallery__rune-title {
|
|
74
|
+
font-family: var(--rf-font-mono, monospace);
|
|
75
|
+
font-size: 0.75rem;
|
|
76
|
+
text-transform: uppercase;
|
|
77
|
+
letter-spacing: 0.08em;
|
|
78
|
+
color: var(--rf-color-muted, #888);
|
|
79
|
+
border-bottom: 1px solid var(--rf-color-border, #ddd);
|
|
80
|
+
padding-bottom: 0.5rem;
|
|
81
|
+
margin: 0 0 1.5rem;
|
|
82
|
+
}
|
|
83
|
+
.rf-gallery__cell { margin: 0 0 2rem; }
|
|
84
|
+
.rf-gallery__gap {
|
|
85
|
+
font-family: var(--rf-font-mono, monospace);
|
|
86
|
+
font-size: 0.75rem;
|
|
87
|
+
color: var(--rf-color-muted, #999);
|
|
88
|
+
border: 1px dashed var(--rf-color-border, #ccc);
|
|
89
|
+
border-radius: var(--rf-radius-sm, 4px);
|
|
90
|
+
padding: 0.75rem 1rem;
|
|
91
|
+
}
|
|
92
|
+
.rf-gallery__cell-label {
|
|
93
|
+
display: block;
|
|
94
|
+
font-family: var(--rf-font-mono, monospace);
|
|
95
|
+
font-size: 0.6875rem;
|
|
96
|
+
color: var(--rf-color-muted, #999);
|
|
97
|
+
margin: 0 0 0.5rem;
|
|
98
|
+
}
|
|
99
|
+
`.trim();
|
|
100
|
+
/** Determinism reset for layout fixtures (no gallery chrome — the layout *is*
|
|
101
|
+
* the page). Kills animation/transition/caret so screenshots are stable. */
|
|
102
|
+
const LAYOUT_RESET_CSS = `
|
|
103
|
+
*, *::before, *::after {
|
|
104
|
+
animation-duration: 0s !important;
|
|
105
|
+
animation-delay: 0s !important;
|
|
106
|
+
transition-duration: 0s !important;
|
|
107
|
+
transition-delay: 0s !important;
|
|
108
|
+
caret-color: transparent !important;
|
|
109
|
+
scroll-behavior: auto !important;
|
|
110
|
+
}
|
|
111
|
+
body { margin: 0; background: var(--rf-color-bg); color: var(--rf-color-text); font-family: var(--rf-font-sans, sans-serif); }
|
|
112
|
+
`.trim();
|
|
113
|
+
/**
|
|
114
|
+
* Render a standalone full-page document for a layout fixture — the layout's
|
|
115
|
+
* own chrome *is* the page (no gallery cell grid), so the harness can shoot it
|
|
116
|
+
* whole-page at multiple viewports.
|
|
117
|
+
*/
|
|
118
|
+
export function renderLayoutDocument(opts) {
|
|
119
|
+
const { mode, themeCss, bodyHtml, name, fontLinks = DEFAULT_FONT_LINKS, behaviorScript } = opts;
|
|
120
|
+
const htmlAttr = mode === 'dark' ? ' data-theme="dark"' : '';
|
|
121
|
+
const tail = behaviorScript
|
|
122
|
+
? `<script type="application/json" id="rf-context">{"pages":[],"currentUrl":"/"}</script>\n<script>${behaviorScript}</script>\n`
|
|
123
|
+
: '';
|
|
124
|
+
return `<!DOCTYPE html>
|
|
125
|
+
<html lang="en"${htmlAttr}>
|
|
126
|
+
<head>
|
|
127
|
+
<meta charset="utf-8">
|
|
128
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
129
|
+
<meta name="color-scheme" content="light dark">
|
|
130
|
+
<title>refrakt layout — ${name} (${mode})</title>
|
|
131
|
+
${fontLinks}
|
|
132
|
+
<style>${themeCss}</style>
|
|
133
|
+
<style>${LAYOUT_RESET_CSS}</style>
|
|
134
|
+
</head>
|
|
135
|
+
<body>
|
|
136
|
+
${bodyHtml}
|
|
137
|
+
${tail}</body>
|
|
138
|
+
</html>
|
|
139
|
+
`;
|
|
140
|
+
}
|
|
141
|
+
function escapeHtml(s) {
|
|
142
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Render the full self-contained gallery HTML document for one mode. Cells are
|
|
146
|
+
* grouped by rune; each carries a stable `data-gallery-cell="<rune>--<variant>"`
|
|
147
|
+
* anchor so the harness ({% WORK-409 %}) can clip per variant.
|
|
148
|
+
*/
|
|
149
|
+
export function renderGalleryDocument(opts) {
|
|
150
|
+
const { mode, themeCss, cells, fontLinks = DEFAULT_FONT_LINKS, behaviorScript } = opts;
|
|
151
|
+
// Group cells by rune, preserving insertion order.
|
|
152
|
+
const byRune = new Map();
|
|
153
|
+
for (const cell of cells) {
|
|
154
|
+
const list = byRune.get(cell.rune) ?? [];
|
|
155
|
+
list.push(cell);
|
|
156
|
+
byRune.set(cell.rune, list);
|
|
157
|
+
}
|
|
158
|
+
const sections = [];
|
|
159
|
+
for (const [rune, runeCells] of byRune) {
|
|
160
|
+
const cellHtml = runeCells.map(cell => {
|
|
161
|
+
const anchor = `${cell.rune}--${cell.variant}`;
|
|
162
|
+
return ` <div class="rf-gallery__cell" data-gallery-cell="${escapeHtml(anchor)}" data-rune="${escapeHtml(cell.rune)}" data-variant="${escapeHtml(cell.variant)}">
|
|
163
|
+
<span class="rf-gallery__cell-label">${escapeHtml(cell.variant)}</span>
|
|
164
|
+
${cell.html}
|
|
165
|
+
</div>`;
|
|
166
|
+
}).join('\n');
|
|
167
|
+
sections.push(` <section class="rf-gallery__rune" data-gallery-rune="${escapeHtml(rune)}">
|
|
168
|
+
<h2 class="rf-gallery__rune-title">${escapeHtml(rune)}</h2>
|
|
169
|
+
${cellHtml}
|
|
170
|
+
</section>`);
|
|
171
|
+
}
|
|
172
|
+
const htmlAttr = mode === 'dark' ? ' data-theme="dark"' : '';
|
|
173
|
+
return `<!DOCTYPE html>
|
|
174
|
+
<html lang="en"${htmlAttr}>
|
|
175
|
+
<head>
|
|
176
|
+
<meta charset="utf-8">
|
|
177
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
178
|
+
<meta name="color-scheme" content="light dark">
|
|
179
|
+
<title>refrakt gallery (${mode})</title>
|
|
180
|
+
${fontLinks}
|
|
181
|
+
<style>${themeCss}</style>
|
|
182
|
+
<style>${GALLERY_CSS}</style>
|
|
183
|
+
</head>
|
|
184
|
+
<body class="rf-gallery">
|
|
185
|
+
<div class="rf-gallery__inner">
|
|
186
|
+
${sections.join('\n')}
|
|
187
|
+
</div>
|
|
188
|
+
${behaviorScript ? `<script type="application/json" id="rf-context">{"pages":[],"currentUrl":"/"}</script>\n<script>${behaviorScript}</script>\n` : ''}</body>
|
|
189
|
+
</html>
|
|
190
|
+
`;
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=gallery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gallery.js","sourceRoot":"","sources":["../../src/lib/gallery.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refrakt-md/cli",
|
|
3
3
|
"description": "CLI tools for refrakt.md",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.23.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -36,10 +36,12 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@markdoc/markdoc": "0.4.0",
|
|
39
|
-
"@refrakt-md/ai": "0.
|
|
40
|
-
"@refrakt-md/editor": "0.
|
|
41
|
-
"@refrakt-md/
|
|
42
|
-
"@refrakt-md/
|
|
39
|
+
"@refrakt-md/ai": "0.23.0",
|
|
40
|
+
"@refrakt-md/editor": "0.23.0",
|
|
41
|
+
"@refrakt-md/html": "0.23.0",
|
|
42
|
+
"@refrakt-md/runes": "0.23.0",
|
|
43
|
+
"@refrakt-md/transform": "0.23.0",
|
|
44
|
+
"esbuild": "^0.27.5",
|
|
43
45
|
"postcss": "^8.4.0"
|
|
44
46
|
}
|
|
45
47
|
}
|