@refrakt-md/runes 0.15.0 → 0.16.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.
Files changed (73) hide show
  1. package/dist/aggregate-resolve.d.ts +4 -0
  2. package/dist/aggregate-resolve.d.ts.map +1 -0
  3. package/dist/aggregate-resolve.js +209 -0
  4. package/dist/aggregate-resolve.js.map +1 -0
  5. package/dist/collection-helpers.d.ts +101 -0
  6. package/dist/collection-helpers.d.ts.map +1 -0
  7. package/dist/collection-helpers.js +206 -0
  8. package/dist/collection-helpers.js.map +1 -0
  9. package/dist/collection-resolve.d.ts +5 -0
  10. package/dist/collection-resolve.d.ts.map +1 -0
  11. package/dist/collection-resolve.js +209 -0
  12. package/dist/collection-resolve.js.map +1 -0
  13. package/dist/config.d.ts +6 -0
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +55 -1
  16. package/dist/config.js.map +1 -1
  17. package/dist/deferred-body.d.ts +19 -0
  18. package/dist/deferred-body.d.ts.map +1 -0
  19. package/dist/deferred-body.js +70 -0
  20. package/dist/deferred-body.js.map +1 -0
  21. package/dist/expand-pipeline.js +25 -16
  22. package/dist/expand-pipeline.js.map +1 -1
  23. package/dist/field-match.d.ts +43 -0
  24. package/dist/field-match.d.ts.map +1 -0
  25. package/dist/field-match.js +121 -0
  26. package/dist/field-match.js.map +1 -0
  27. package/dist/functions.d.ts +36 -0
  28. package/dist/functions.d.ts.map +1 -0
  29. package/dist/functions.js +74 -0
  30. package/dist/functions.js.map +1 -0
  31. package/dist/index.d.ts +25 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +63 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/lib/index.d.ts +6 -0
  36. package/dist/lib/index.d.ts.map +1 -1
  37. package/dist/lib/index.js +9 -0
  38. package/dist/lib/index.js.map +1 -1
  39. package/dist/nodes.d.ts.map +1 -1
  40. package/dist/nodes.js +6 -1
  41. package/dist/nodes.js.map +1 -1
  42. package/dist/outline-scope.d.ts +17 -0
  43. package/dist/outline-scope.d.ts.map +1 -1
  44. package/dist/outline-scope.js +59 -0
  45. package/dist/outline-scope.js.map +1 -1
  46. package/dist/relationships-resolve.d.ts +4 -0
  47. package/dist/relationships-resolve.d.ts.map +1 -0
  48. package/dist/relationships-resolve.js +180 -0
  49. package/dist/relationships-resolve.js.map +1 -0
  50. package/dist/tags/aggregate.d.ts +19 -0
  51. package/dist/tags/aggregate.d.ts.map +1 -0
  52. package/dist/tags/aggregate.js +59 -0
  53. package/dist/tags/aggregate.js.map +1 -0
  54. package/dist/tags/card.d.ts +25 -0
  55. package/dist/tags/card.d.ts.map +1 -0
  56. package/dist/tags/card.js +138 -0
  57. package/dist/tags/card.js.map +1 -0
  58. package/dist/tags/collection.d.ts +10 -0
  59. package/dist/tags/collection.d.ts.map +1 -0
  60. package/dist/tags/collection.js +54 -0
  61. package/dist/tags/collection.js.map +1 -0
  62. package/dist/tags/conversation.d.ts.map +1 -1
  63. package/dist/tags/conversation.js +26 -6
  64. package/dist/tags/conversation.js.map +1 -1
  65. package/dist/tags/progress.d.ts +9 -0
  66. package/dist/tags/progress.d.ts.map +1 -0
  67. package/dist/tags/progress.js +96 -0
  68. package/dist/tags/progress.js.map +1 -0
  69. package/dist/tags/relationships.d.ts +12 -0
  70. package/dist/tags/relationships.d.ts.map +1 -0
  71. package/dist/tags/relationships.js +62 -0
  72. package/dist/tags/relationships.js.map +1 -0
  73. package/package.json +3 -3
@@ -0,0 +1,138 @@
1
+ import Markdoc from '@markdoc/markdoc';
2
+ const { Tag } = Markdoc;
3
+ import { createContentModelSchema, createComponentRenderable, asNodes } from '../lib/index.js';
4
+ import { RenderableNodeCursor } from '../lib/renderable.js';
5
+ import { SplitLayoutModel, buildLayoutMetas, extractMediaImage } from './common.js';
6
+ /**
7
+ * `card` (SPEC-070) — a generic, self-contained content card.
8
+ *
9
+ * The body is divided by `---` (hr) into up to three zones:
10
+ *
11
+ * [media] --- body [--- footer]
12
+ *
13
+ * - **media** (optional leading zone): any content — an image, a `{% codegroup %}`,
14
+ * a `{% sandbox %}`, etc. Reuses the shared split layout (`SplitLayoutModel`):
15
+ * side-by-side with the body on wide screens, a full-bleed header on mobile
16
+ * (`data-media-position="top"`).
17
+ * - **body**: the main content.
18
+ * - **footer** (optional trailing zone): a muted meta row (date · tags · …).
19
+ *
20
+ * Zone roles are positional by count: 1 → body; 2 → media + body; 3 → media +
21
+ * body + footer. A leading empty zone (`--- body --- footer`) means "no media".
22
+ *
23
+ * `href` makes the whole card a link (a stretched link overlay, so real links
24
+ * inside body/footer stay clickable). The card carries no `$item`/registry
25
+ * knowledge — it's plain and composable, standalone or fed by a collection
26
+ * body template.
27
+ */
28
+ export const card = createContentModelSchema({
29
+ base: SplitLayoutModel,
30
+ attributes: {
31
+ href: { type: String, required: false, default: '', description: 'Optional link target; makes the whole card clickable.' },
32
+ },
33
+ contentModel: {
34
+ type: 'sequence',
35
+ fields: [{ name: 'body', match: 'any', optional: true, greedy: true }],
36
+ },
37
+ transform(resolved, attrs, config) {
38
+ // Split the body nodes on `hr` (`---`) into zones.
39
+ const nodes = asNodes(resolved.body);
40
+ const zones = [[]];
41
+ for (const n of nodes) {
42
+ if (n.type === 'hr')
43
+ zones.push([]);
44
+ else
45
+ zones[zones.length - 1].push(n);
46
+ }
47
+ let mediaNodes = [];
48
+ let bodyNodes = [];
49
+ let footerNodes = [];
50
+ if (zones.length === 1) {
51
+ bodyNodes = zones[0];
52
+ }
53
+ else if (zones.length === 2) {
54
+ mediaNodes = zones[0];
55
+ bodyNodes = zones[1];
56
+ }
57
+ else {
58
+ mediaNodes = zones[0];
59
+ footerNodes = zones[zones.length - 1];
60
+ bodyNodes = zones.slice(1, -1).flat();
61
+ }
62
+ const { metas: layoutMetas, children: layoutChildren } = buildLayoutMetas(attrs);
63
+ const children = [...layoutChildren];
64
+ // Media zone — unwrap a bare image; otherwise render arbitrary content.
65
+ if (mediaNodes.length > 0) {
66
+ const mediaCursor = new RenderableNodeCursor(Markdoc.transform(mediaNodes, config));
67
+ const img = extractMediaImage(mediaCursor);
68
+ const inner = img ? [img] : mediaCursor.toArray();
69
+ children.push(new Tag('div', { 'data-section': 'media', 'data-name': 'media' }, inner));
70
+ }
71
+ // Eyebrow: a leading paragraph immediately followed by a heading becomes a
72
+ // kicker (the page-section / recipe pattern). The rest stays freeform body.
73
+ let eyebrowNode;
74
+ let mainBodyNodes = bodyNodes;
75
+ if (bodyNodes.length >= 2 &&
76
+ bodyNodes[0].type === 'paragraph' &&
77
+ bodyNodes[1].type === 'heading') {
78
+ eyebrowNode = bodyNodes[0];
79
+ mainBodyNodes = bodyNodes.slice(1);
80
+ }
81
+ // Content zone (body + optional footer) — one grid child so the split
82
+ // layout puts media | content; footer sits at the bottom of content.
83
+ const bodyInner = [];
84
+ let eyebrowTag;
85
+ if (eyebrowNode) {
86
+ const eyebrowCursor = new RenderableNodeCursor(Markdoc.transform([eyebrowNode], config));
87
+ const first = eyebrowCursor.toArray()[0];
88
+ if (Markdoc.Tag.isTag(first)) {
89
+ eyebrowTag = first;
90
+ bodyInner.push(eyebrowTag);
91
+ }
92
+ }
93
+ const bodyCursor = new RenderableNodeCursor(Markdoc.transform(mainBodyNodes, config));
94
+ const bodyRendered = bodyCursor.toArray();
95
+ // The body's leading heading is the card title — give it a hook so it can
96
+ // sit tight under an eyebrow instead of carrying default prose top margin.
97
+ let titleTag;
98
+ const firstBody = bodyRendered[0];
99
+ if (Markdoc.Tag.isTag(firstBody) && /^h[1-6]$/.test(firstBody.name)) {
100
+ titleTag = firstBody;
101
+ }
102
+ bodyInner.push(...bodyRendered);
103
+ const bodyDiv = new Tag('div', { 'data-name': 'body' }, bodyInner);
104
+ const contentChildren = [bodyDiv];
105
+ let footerTag;
106
+ if (footerNodes.length > 0) {
107
+ const footerCursor = new RenderableNodeCursor(Markdoc.transform(footerNodes, config));
108
+ footerTag = new Tag('footer', { 'data-name': 'footer' }, footerCursor.toArray());
109
+ contentChildren.push(footerTag);
110
+ }
111
+ const contentDiv = new Tag('div', { 'data-name': 'content' }, contentChildren);
112
+ children.push(contentDiv);
113
+ // Whole-card link as a stretched overlay (keeps nested links valid).
114
+ let linkTag;
115
+ const href = String(attrs.href ?? '');
116
+ if (href) {
117
+ linkTag = new Tag('a', { 'data-name': 'link', href, 'aria-hidden': 'true', tabindex: '-1' }, []);
118
+ children.push(linkTag);
119
+ }
120
+ const refs = { content: contentDiv, body: bodyDiv };
121
+ if (titleTag)
122
+ refs.title = titleTag;
123
+ if (eyebrowTag)
124
+ refs.eyebrow = eyebrowTag;
125
+ if (footerTag)
126
+ refs.footer = footerTag;
127
+ if (linkTag)
128
+ refs.link = linkTag;
129
+ return createComponentRenderable({
130
+ rune: 'card',
131
+ tag: 'div',
132
+ properties: { layout: layoutMetas.layout },
133
+ refs,
134
+ children,
135
+ });
136
+ },
137
+ });
138
+ //# sourceMappingURL=card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.js","sourceRoot":"","sources":["../../src/tags/card.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import Markdoc from '@markdoc/markdoc';
2
+ export declare const COLLECTION_SENTINEL = "__collection-sentinel";
3
+ /**
4
+ * `collection` (SPEC-070) — queries the entity registry for many entities and
5
+ * projects them into a layout. Emits a sentinel that the postProcess resolver
6
+ * (`resolveCollections`) fills with real entity data. The body, when present,
7
+ * is a per-entity template captured via the deferBody mechanism (WORK-262).
8
+ */
9
+ export declare const collection: Markdoc.Schema;
10
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/tags/collection.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAKvC,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,UAAU,gBA2CrB,CAAC"}
@@ -0,0 +1,54 @@
1
+ import Markdoc from '@markdoc/markdoc';
2
+ const { Tag } = Markdoc;
3
+ import { createContentModelSchema, createComponentRenderable } from '../lib/index.js';
4
+ import { readDeferredBody } from '../deferred-body.js';
5
+ export const COLLECTION_SENTINEL = '__collection-sentinel';
6
+ /**
7
+ * `collection` (SPEC-070) — queries the entity registry for many entities and
8
+ * projects them into a layout. Emits a sentinel that the postProcess resolver
9
+ * (`resolveCollections`) fills with real entity data. The body, when present,
10
+ * is a per-entity template captured via the deferBody mechanism (WORK-262).
11
+ */
12
+ export const collection = createContentModelSchema({
13
+ attributes: {
14
+ type: { type: String, required: false, default: '', description: 'Entity type(s), comma-separated.' },
15
+ filter: { type: String, required: false, default: '', description: 'field:value clauses (SPEC-070 grammar).' },
16
+ sort: { type: String, required: false, default: '', description: 'Sort field (prefix - for descending).' },
17
+ group: { type: String, required: false, default: '', description: 'Group-by field.' },
18
+ limit: { type: String, required: false, default: '', description: 'Max items.' },
19
+ show: { type: String, required: false, default: '', description: 'Alias for type (entity types to include).' },
20
+ fields: { type: String, required: false, default: '', description: 'Comma-separated data fields to project.' },
21
+ layout: { type: String, required: false, default: 'list', description: 'Arrangement: list (stacked) | grid (multi-column) | table (aligned columns). Item chrome comes from the item — the no-body built-in, or a rune like {% card %} in the body template.' },
22
+ 'group-display': { type: String, required: false, default: 'headings', matches: ['headings', 'accordion'], description: 'How groups are presented when `group` is set: headings (default) or accordion (collapsible native <details> panels, styled like the accordion rune, with a per-group count).' },
23
+ empty: { type: String, required: false, default: '', description: 'Fallback text shown when the query yields nothing (no-body form; body-template form uses a fallback zone). Absent → render nothing.' },
24
+ },
25
+ deferBody: true,
26
+ contentModel: { type: 'sequence', fields: [] },
27
+ transform(_resolved, attrs) {
28
+ const meta = (field, content) => new Tag('meta', { 'data-field': field, content });
29
+ const bodySource = readDeferredBody(attrs) ?? '';
30
+ const metas = [
31
+ meta('collection-type', String(attrs.type ?? attrs.show ?? '')),
32
+ meta('collection-filter', String(attrs.filter ?? '')),
33
+ meta('collection-sort', String(attrs.sort ?? '')),
34
+ meta('collection-group', String(attrs.group ?? '')),
35
+ meta('collection-limit', String(attrs.limit ?? '')),
36
+ meta('collection-fields', String(attrs.fields ?? '')),
37
+ meta('collection-layout', String(attrs.layout ?? 'list')),
38
+ meta('collection-group-display', String(attrs['group-display'] ?? 'headings')),
39
+ meta('collection-empty', String(attrs.empty ?? '')),
40
+ meta(COLLECTION_SENTINEL, 'true'),
41
+ ];
42
+ if (bodySource)
43
+ metas.push(meta('collection-body', bodySource));
44
+ const placeholder = new Tag('div', { 'data-name': 'items' }, []);
45
+ return createComponentRenderable({
46
+ rune: 'collection',
47
+ tag: 'section',
48
+ properties: {},
49
+ refs: { items: placeholder },
50
+ children: [...metas, placeholder],
51
+ });
52
+ },
53
+ });
54
+ //# sourceMappingURL=collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.js","sourceRoot":"","sources":["../../src/tags/collection.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/tags/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAMvC,eAAO,MAAM,mBAAmB,gBA8B9B,CAAC;AAkDH,eAAO,MAAM,YAAY,gBA2BvB,CAAC"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../src/tags/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAMvC,eAAO,MAAM,mBAAmB,gBA8B9B,CAAC;AAwEH,eAAO,MAAM,YAAY,gBA2BvB,CAAC"}
@@ -40,12 +40,21 @@ function convertConversationChildren(nodes, attrs) {
40
40
  if (node.type === 'blockquote') {
41
41
  let speaker = '';
42
42
  const children = [...node.children];
43
+ // Markdoc wraps a paragraph's inline content in an `inline` node, so
44
+ // the first paragraph's *content* is `firstPara.children[0].children`
45
+ // (when an inline wrapper is present) rather than `firstPara.children`
46
+ // directly. Both forms are handled.
47
+ const firstPara = children.length > 0 && children[0].type === 'paragraph'
48
+ ? children[0]
49
+ : null;
50
+ const inlineHost = firstPara && firstPara.children[0]?.type === 'inline'
51
+ ? firstPara.children[0]
52
+ : firstPara;
43
53
  // Try to extract speaker from first paragraph's bold text: **Name:** ...
44
- if (children.length > 0 && children[0].type === 'paragraph') {
45
- const firstPara = children[0];
46
- const firstChild = firstPara.children[0];
47
- if (firstChild && firstChild.type === 'strong') {
48
- const nameText = Array.from(firstChild.walk())
54
+ if (inlineHost) {
55
+ const firstInline = inlineHost.children[0];
56
+ if (firstInline && firstInline.type === 'strong') {
57
+ const nameText = Array.from(firstInline.walk())
49
58
  .filter(n => n.type === 'text')
50
59
  .map(n => n.attributes.content)
51
60
  .join('')
@@ -53,9 +62,20 @@ function convertConversationChildren(nodes, attrs) {
53
62
  speaker = nameText;
54
63
  }
55
64
  }
56
- // Fall back to alternating from speakers list
65
+ // Fall back to alternating from speakers list. Inject a bold
66
+ // `**Name:**` prefix at the start of the first paragraph so the
67
+ // rendering matches the explicit `> **Name**:` form — name reads as
68
+ // bold-inline inside the bubble rather than as a separate label
69
+ // above it.
57
70
  if (!speaker && speakerList.length > 0) {
58
71
  speaker = speakerList[messageIndex % speakerList.length];
72
+ if (inlineHost) {
73
+ const strongTag = new Ast.Node('strong', {}, [
74
+ new Ast.Node('text', { content: `${speaker}:` }, []),
75
+ ]);
76
+ const spaceText = new Ast.Node('text', { content: ' ' }, []);
77
+ inlineHost.children = [strongTag, spaceText, ...inlineHost.children];
78
+ }
59
79
  }
60
80
  const align = messageIndex % 2 === 0 ? 'left' : 'right';
61
81
  converted.push(new Ast.Node('tag', {
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/tags/conversation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/tags/conversation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import Markdoc from '@markdoc/markdoc';
2
+ /**
3
+ * `progress` — a generic, presentational completion bar (SPEC-072 / WORK-285).
4
+ * Renders a ratio from supplied numbers; computes nothing from the registry.
5
+ * `value`+`max` (primary) or `percent` (alternative, when there's no count);
6
+ * an optional body is the label. Identity-transform only, no resolver.
7
+ */
8
+ export declare const progress: Markdoc.Schema;
9
+ //# sourceMappingURL=progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/tags/progress.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAiBvC;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,gBA6EnB,CAAC"}
@@ -0,0 +1,96 @@
1
+ import Markdoc from '@markdoc/markdoc';
2
+ const { Tag } = Markdoc;
3
+ import { createContentModelSchema, createComponentRenderable, asNodes } from '../lib/index.js';
4
+ import { RenderableNodeCursor } from '../lib/renderable.js';
5
+ const displayValues = ['fraction', 'percent', 'none'];
6
+ const sentimentValues = ['positive', 'caution', 'negative'];
7
+ /** Best-effort plain-text of a rendered subtree, for the accessible name. */
8
+ function textContent(node) {
9
+ if (typeof node === 'string')
10
+ return node;
11
+ if (Array.isArray(node))
12
+ return node.map(textContent).join('');
13
+ if (Markdoc.Tag.isTag(node))
14
+ return textContent(node.children ?? []);
15
+ return '';
16
+ }
17
+ /**
18
+ * `progress` — a generic, presentational completion bar (SPEC-072 / WORK-285).
19
+ * Renders a ratio from supplied numbers; computes nothing from the registry.
20
+ * `value`+`max` (primary) or `percent` (alternative, when there's no count);
21
+ * an optional body is the label. Identity-transform only, no resolver.
22
+ */
23
+ export const progress = createContentModelSchema({
24
+ attributes: {
25
+ value: { type: Number, required: false, description: 'Completed amount (paired with `max`).' },
26
+ max: { type: Number, required: false, description: 'Total amount (paired with `value`).' },
27
+ percent: { type: Number, required: false, description: 'Direct percentage 0–100, when there is no count.' },
28
+ display: { type: String, required: false, matches: displayValues.slice(), description: 'Readout: fraction (default with value/max), percent, or none.' },
29
+ sentiment: { type: String, required: false, matches: sentimentValues.slice(), description: 'Tone cue: positive / caution / negative. Absent → the neutral primary fill.' },
30
+ },
31
+ contentModel: {
32
+ type: 'sequence',
33
+ fields: [{ name: 'body', match: 'any', optional: true, greedy: true }],
34
+ },
35
+ transform(resolved, attrs, config) {
36
+ const value = attrs.value != null ? Number(attrs.value) : undefined;
37
+ const max = attrs.max != null ? Number(attrs.max) : undefined;
38
+ const percentAttr = attrs.percent != null ? Number(attrs.percent) : undefined;
39
+ const clamp = (n) => Math.max(0, Math.min(100, n));
40
+ const hasRatio = value != null && max != null && Number.isFinite(value) && Number.isFinite(max) && max > 0;
41
+ const pct = hasRatio
42
+ ? clamp(Math.round((value / max) * 100))
43
+ : (percentAttr != null && Number.isFinite(percentAttr) ? clamp(percentAttr) : 0);
44
+ const display = attrs.display || (hasRatio ? 'fraction' : 'percent');
45
+ let readout = '';
46
+ if (display === 'fraction' && hasRatio)
47
+ readout = `${value}/${max}`;
48
+ else if (display === 'percent')
49
+ readout = `${pct}%`;
50
+ const labelNodes = new RenderableNodeCursor(Markdoc.transform(asNodes(resolved.body), config));
51
+ const labelArr = labelNodes.toArray();
52
+ const labelText = textContent(labelArr).trim();
53
+ // Optional tone cue — omit the meta entirely when absent so no modifier
54
+ // class is applied (the bar then uses the neutral primary fill).
55
+ const sentiment = attrs.sentiment;
56
+ const sentimentMeta = sentiment ? new Tag('meta', { content: sentiment }) : undefined;
57
+ const fillTag = new Tag('span', {}, []);
58
+ const trackTag = new Tag('span', {}, [fillTag]);
59
+ const refs = { track: trackTag, fill: fillTag };
60
+ const children = sentimentMeta ? [sentimentMeta] : [];
61
+ if (labelArr.length > 0) {
62
+ const labelTag = new Tag('span', {}, labelArr);
63
+ refs.label = labelTag;
64
+ children.push(labelTag);
65
+ }
66
+ if (readout) {
67
+ const valueTag = new Tag('span', {}, [readout]);
68
+ refs.value = valueTag;
69
+ children.push(valueTag);
70
+ }
71
+ children.push(trackTag);
72
+ const out = createComponentRenderable({
73
+ rune: 'progress',
74
+ tag: 'div',
75
+ properties: sentimentMeta ? { sentiment: sentimentMeta } : {},
76
+ refs,
77
+ children,
78
+ });
79
+ // Per-instance computed root attributes: accessible progressbar + fill width.
80
+ out.attributes.role = 'progressbar';
81
+ out.attributes['aria-valuemin'] = '0';
82
+ if (hasRatio) {
83
+ out.attributes['aria-valuenow'] = String(value);
84
+ out.attributes['aria-valuemax'] = String(max);
85
+ }
86
+ else {
87
+ out.attributes['aria-valuenow'] = String(pct);
88
+ out.attributes['aria-valuemax'] = '100';
89
+ }
90
+ if (labelText)
91
+ out.attributes['aria-label'] = labelText;
92
+ out.attributes.style = `--rf-progress: ${pct}%`;
93
+ return out;
94
+ },
95
+ });
96
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/tags/progress.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAEvC,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;AAC/D,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAErE,6EAA6E;AAC7E,SAAS,WAAW,CAAC,IAAa;IACjC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAa,CAAC;QAAE,OAAO,WAAW,CAAE,IAAiC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAC5G,OAAO,EAAE,CAAC;AACX,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,wBAAwB,CAAC;IAChD,UAAU,EAAE;QACX,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,uCAAuC,EAAE;QAC9F,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,qCAAqC,EAAE;QAC1F,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,kDAAkD,EAAE;QAC3G,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,+DAA+D,EAAE;QACxJ,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,6EAA6E,EAAE;KAC1K;IACD,YAAY,EAAE;QACb,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;KACtE;IACD,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACpE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9D,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9E,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAK,GAAc,GAAG,CAAC,CAAC;QACvH,MAAM,GAAG,GAAG,QAAQ;YACnB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAM,GAAG,GAAI,CAAC,GAAG,GAAG,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAElF,MAAM,OAAO,GAAI,KAAK,CAAC,OAAkB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACjF,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,OAAO,KAAK,UAAU,IAAI,QAAQ;YAAE,OAAO,GAAG,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC;aAC/D,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC;QAEpD,MAAM,UAAU,GAAG,IAAI,oBAAoB,CAC1C,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAyB,CACzE,CAAC;QACF,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAE/C,wEAAwE;QACxE,iEAAiE;QACjE,MAAM,SAAS,GAAG,KAAK,CAAC,SAA+B,CAAC;QACxD,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEtF,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,MAAM,IAAI,GAA6C,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1F,MAAM,QAAQ,GAAyB,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE5E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC/C,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;YAChD,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAExB,MAAM,GAAG,GAAG,yBAAyB,CAAC;YACrC,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,KAAK;YACV,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE;YAC7D,IAAI;YACJ,QAAQ;SACR,CAAC,CAAC;QAEH,8EAA8E;QAC9E,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,aAAa,CAAC;QACpC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC;QACtC,IAAI,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAChD,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACP,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9C,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,KAAK,CAAC;QACzC,CAAC;QACD,IAAI,SAAS;YAAE,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;QACxD,GAAG,CAAC,UAAU,CAAC,KAAK,GAAG,kBAAkB,GAAG,GAAG,CAAC;QAChD,OAAO,GAAG,CAAC;IACZ,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import Markdoc from '@markdoc/markdoc';
2
+ export declare const RELATIONSHIPS_SENTINEL = "__relationships-sentinel";
3
+ /**
4
+ * `relationships` (SPEC-072) — render an entity's relationship edges, grouped
5
+ * by kind. The plural-graph counterpart to `collection`: its source set is
6
+ * `registry.getRelated(of)` rather than a type-query. Emits a sentinel filled
7
+ * by the postProcess resolver (`resolveRelationships`). A body, when present,
8
+ * is the per-edge template (deferBody) with `$item` (the related entity) and
9
+ * `$kind` (the edge kind) bound.
10
+ */
11
+ export declare const relationships: Markdoc.Schema;
12
+ //# sourceMappingURL=relationships.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/tags/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAKvC,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AAEjE;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,gBAkDxB,CAAC"}
@@ -0,0 +1,62 @@
1
+ import Markdoc from '@markdoc/markdoc';
2
+ const { Tag } = Markdoc;
3
+ import { createContentModelSchema, createComponentRenderable } from '../lib/index.js';
4
+ import { readDeferredBody } from '../deferred-body.js';
5
+ export const RELATIONSHIPS_SENTINEL = '__relationships-sentinel';
6
+ /**
7
+ * `relationships` (SPEC-072) — render an entity's relationship edges, grouped
8
+ * by kind. The plural-graph counterpart to `collection`: its source set is
9
+ * `registry.getRelated(of)` rather than a type-query. Emits a sentinel filled
10
+ * by the postProcess resolver (`resolveRelationships`). A body, when present,
11
+ * is the per-edge template (deferBody) with `$item` (the related entity) and
12
+ * `$kind` (the edge kind) bound.
13
+ */
14
+ export const relationships = createContentModelSchema({
15
+ attributes: {
16
+ of: { type: String, required: false, default: '', description: 'Entity to describe — an id (e.g. `of=$item.id`) or a bound entity.' },
17
+ kind: { type: String, required: false, default: '', description: 'Edge kinds to include, comma-separated (e.g. "blocks,blocked-by").' },
18
+ type: { type: String, required: false, default: '', description: 'Restrict related entity types, comma-separated.' },
19
+ group: { type: String, required: false, default: 'kind', description: 'Group-by: kind (default) | type | none.' },
20
+ 'group-display': { type: String, required: false, default: 'headings', matches: ['headings', 'accordion'], description: 'How groups are presented: headings (default) or accordion (collapsible native <details> panels, styled like the accordion rune, with a per-group count).' },
21
+ sort: { type: String, required: false, default: '', description: 'Sort related entities by a field (prefix - for descending).' },
22
+ limit: { type: String, required: false, default: '', description: 'Max edges.' },
23
+ fields: { type: String, required: false, default: '', description: 'Comma-separated data fields to project in the no-body built-in.' },
24
+ layout: { type: String, required: false, default: 'list', description: 'Arrangement: list (stacked) | grid (multi-column). Item chrome comes from the item — the no-body built-in, or a rune like {% card %} in the body template.' },
25
+ empty: { type: String, required: false, default: '', description: 'Fallback text shown when there are no edges (no-body form; body form uses a fallback zone). Absent → render nothing.' },
26
+ },
27
+ deferBody: true,
28
+ contentModel: { type: 'sequence', fields: [] },
29
+ transform(_resolved, attrs) {
30
+ const meta = (field, content) => new Tag('meta', { 'data-field': field, content });
31
+ const bodySource = readDeferredBody(attrs) ?? '';
32
+ // `of` accepts an id string or a bound entity object ({ id, … }).
33
+ const ofRaw = attrs.of;
34
+ const of = ofRaw && typeof ofRaw === 'object'
35
+ ? String(ofRaw.id ?? '')
36
+ : String(ofRaw ?? '');
37
+ const metas = [
38
+ meta('relationships-of', of),
39
+ meta('relationships-kind', String(attrs.kind ?? '')),
40
+ meta('relationships-type', String(attrs.type ?? '')),
41
+ meta('relationships-group', String(attrs.group ?? 'kind')),
42
+ meta('relationships-group-display', String(attrs['group-display'] ?? 'headings')),
43
+ meta('relationships-sort', String(attrs.sort ?? '')),
44
+ meta('relationships-limit', String(attrs.limit ?? '')),
45
+ meta('relationships-fields', String(attrs.fields ?? '')),
46
+ meta('relationships-layout', String(attrs.layout ?? 'list')),
47
+ meta('relationships-empty', String(attrs.empty ?? '')),
48
+ meta(RELATIONSHIPS_SENTINEL, 'true'),
49
+ ];
50
+ if (bodySource)
51
+ metas.push(meta('relationships-body', bodySource));
52
+ const placeholder = new Tag('div', { 'data-name': 'items' }, []);
53
+ return createComponentRenderable({
54
+ rune: 'relationships',
55
+ tag: 'section',
56
+ properties: {},
57
+ refs: { items: placeholder },
58
+ children: [...metas, placeholder],
59
+ });
60
+ },
61
+ });
62
+ //# sourceMappingURL=relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/tags/relationships.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@refrakt-md/runes",
3
3
  "description": "Semantic Markdoc runes for refrakt.md",
4
- "version": "0.15.0",
4
+ "version": "0.16.0",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -29,8 +29,8 @@
29
29
  "build": "tsc"
30
30
  },
31
31
  "dependencies": {
32
- "@refrakt-md/types": "0.15.0",
33
- "@refrakt-md/transform": "0.15.0",
32
+ "@refrakt-md/types": "0.16.0",
33
+ "@refrakt-md/transform": "0.16.0",
34
34
  "@markdoc/markdoc": "0.4.0",
35
35
  "reflect-metadata": "^0.2.0",
36
36
  "fast-xml-parser": "4.5.1",