@uniweb/kit 0.10.5 → 0.10.7
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/package.json +3 -3
- package/src/prose-tokens.css +28 -0
- package/src/styled/Render/index.jsx +21 -3
- package/src/xref/Ref.jsx +17 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/kit",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.7",
|
|
4
4
|
"description": "Standard component library for Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"shiki": "^3.0.0",
|
|
44
44
|
"tailwind-merge": "^3.6.0",
|
|
45
45
|
"@uniweb/core": "0.8.0",
|
|
46
|
-
"@uniweb/
|
|
47
|
-
"@uniweb/
|
|
46
|
+
"@uniweb/scene": "0.1.2",
|
|
47
|
+
"@uniweb/semantic-parser": "1.2.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"react": "^19.0.0",
|
package/src/prose-tokens.css
CHANGED
|
@@ -101,3 +101,31 @@
|
|
|
101
101
|
.prose :is(h1, h2, h3, h4) {
|
|
102
102
|
scroll-margin-top: calc(var(--header-height, 4rem) + 1rem);
|
|
103
103
|
}
|
|
104
|
+
|
|
105
|
+
/* ─── Math (Temml → MathML) ────────────────────────────────────────────────────
|
|
106
|
+
Browsers render MathML natively, so it is easy to conclude math needs no CSS.
|
|
107
|
+
It needs these, for two separate reasons.
|
|
108
|
+
|
|
109
|
+
Temml emits class hooks and expects a stylesheet to define them: `tml-left`
|
|
110
|
+
and `tml-right` carry the `&` column alignment of an `aligned` environment,
|
|
111
|
+
`tml-jot` its extra row spacing. Undefined, a derivation's `=` signs drift
|
|
112
|
+
out of line and its rows sit flush. Those three declarations are Temml's own.
|
|
113
|
+
|
|
114
|
+
The `math mtd` rule is not. Temml's stylesheet only *adjusts* row spacing for
|
|
115
|
+
jot, on the stated assumption that mtd already gets 0.5ex of vertical padding
|
|
116
|
+
"per MathML-Core and user-agent CSS" — but a pristine mtd measures 0px in
|
|
117
|
+
Chrome (2026-07). A pmatrix or cases carries no tml-* class at all, so
|
|
118
|
+
Temml's stylesheet alone fixes the derivation and leaves the matrix touching.
|
|
119
|
+
|
|
120
|
+
These live here rather than in their own opt-in file because correct math
|
|
121
|
+
metrics are not a design choice the way callout colours are — a site that
|
|
122
|
+
sets its typography should not also have to know this.
|
|
123
|
+
|
|
124
|
+
press ships the same declarations to the EPUB and Paged.js lanes, which have
|
|
125
|
+
their own stylesheets and cannot import this one. That duplicate is pinned by
|
|
126
|
+
`framework/_contracts/math-css-parity.test.js`, not by trust. */
|
|
127
|
+
.tml-right { text-align: right; }
|
|
128
|
+
.tml-left { text-align: left; }
|
|
129
|
+
.tml-sml-pad { padding-left: 0.05em; }
|
|
130
|
+
math mtd { padding-top: 0.5ex; padding-bottom: 0.5ex; }
|
|
131
|
+
math mtable.tml-jot mtd { padding-top: 0.7ex; padding-bottom: 0.7ex; }
|
|
@@ -84,6 +84,23 @@ export const NOT_RENDERED = {
|
|
|
84
84
|
'document-group': 'an editor node — its documents reach content.links',
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/**
|
|
88
|
+
* The author's `{#id}`, if they wrote one.
|
|
89
|
+
*
|
|
90
|
+
* Reads the same two places the xref registry reads
|
|
91
|
+
* (`@uniweb/kit/xref/registry.js`), because an id that numbers a figure and an
|
|
92
|
+
* id that anchors it must be the same string — otherwise `[#fig-cells]` would
|
|
93
|
+
* resolve to "Figure 3" and link to nothing.
|
|
94
|
+
*
|
|
95
|
+
* Emitting it matters beyond cross-references: it is what makes
|
|
96
|
+
* `/page#fig-cells` land on the figure, and what gives EPUB and Paged.js real
|
|
97
|
+
* internal links. Until 2026-07-31 nothing emitted it, so an authored id
|
|
98
|
+
* existed only inside the registry and never reached the document.
|
|
99
|
+
*/
|
|
100
|
+
function authoredId(element) {
|
|
101
|
+
return element?.attrs?.id ?? element?.id ?? undefined
|
|
102
|
+
}
|
|
103
|
+
|
|
87
104
|
/**
|
|
88
105
|
* Normalize whatever a caller passed into a sequence.
|
|
89
106
|
*
|
|
@@ -213,7 +230,7 @@ export function SequenceElement({ element, block, components }) {
|
|
|
213
230
|
// The id is the anchor `useHeadings()` and every in-page nav link
|
|
214
231
|
// resolve against, so it is behaviour rather than decoration.
|
|
215
232
|
return (
|
|
216
|
-
<Tag id={headingId(element.text || '')}>
|
|
233
|
+
<Tag id={authoredId(element) || headingId(element.text || '')}>
|
|
217
234
|
<SafeHtml value={element.text} as="span" />
|
|
218
235
|
</Tag>
|
|
219
236
|
)
|
|
@@ -235,7 +252,7 @@ export function SequenceElement({ element, block, components }) {
|
|
|
235
252
|
const { url, src, alt, caption, role } = element.attrs || {}
|
|
236
253
|
if (role === 'icon') return <Icon {...element.attrs} />
|
|
237
254
|
return (
|
|
238
|
-
<figure>
|
|
255
|
+
<figure id={authoredId(element)}>
|
|
239
256
|
<Image src={url || src} alt={alt || caption || ''} />
|
|
240
257
|
{caption && <figcaption>{caption}</figcaption>}
|
|
241
258
|
</figure>
|
|
@@ -262,6 +279,7 @@ export function SequenceElement({ element, block, components }) {
|
|
|
262
279
|
const Tag = display ? 'div' : 'span'
|
|
263
280
|
return (
|
|
264
281
|
<Tag
|
|
282
|
+
id={authoredId(element)}
|
|
265
283
|
className={display ? 'math-display' : 'math-inline'}
|
|
266
284
|
dangerouslySetInnerHTML={{ __html: element.mathml }}
|
|
267
285
|
/>
|
|
@@ -319,7 +337,7 @@ export function SequenceElement({ element, block, components }) {
|
|
|
319
337
|
// reference table on a phone.
|
|
320
338
|
return (
|
|
321
339
|
<div className="overflow-x-auto">
|
|
322
|
-
<table>
|
|
340
|
+
<table id={authoredId(element)}>
|
|
323
341
|
{hasHeader && <thead>{renderRow(first, 'h')}</thead>}
|
|
324
342
|
<tbody>{(hasHeader ? rest : rows).map((row, i) => renderRow(row, i))}</tbody>
|
|
325
343
|
</table>
|
package/src/xref/Ref.jsx
CHANGED
|
@@ -136,6 +136,23 @@ export function Ref({ params, block }) {
|
|
|
136
136
|
const missingTail = resolved.filter((r) => r.missing).map((r) => `[?${r.id}]`).join(', ')
|
|
137
137
|
const body = [text, missingTail].filter(Boolean).join(', ')
|
|
138
138
|
|
|
139
|
+
// A reference to exactly one target links to it. The renderer emits the
|
|
140
|
+
// author's `{#id}` onto the labelled element, so `#fig-cells` is a real
|
|
141
|
+
// anchor in the page, in an EPUB, and in a Paged.js document.
|
|
142
|
+
//
|
|
143
|
+
// Only the single case. A cluster reads "Figures 1 and 2" — one href
|
|
144
|
+
// could only point at one of them, and linking the whole phrase to the
|
|
145
|
+
// first target is a worse answer than linking none of it. Making each
|
|
146
|
+
// number its own link means `renderGroupSameKind` returning nodes rather
|
|
147
|
+
// than a string; worth doing when someone needs it, not before.
|
|
148
|
+
if (onlyResolved.length === 1 && resolved.length === 1) {
|
|
149
|
+
return (
|
|
150
|
+
<a className="xref" href={`#${onlyResolved[0].id}`}>
|
|
151
|
+
{body}{locator}
|
|
152
|
+
</a>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
139
156
|
return <span className="xref">{body}{locator}</span>
|
|
140
157
|
}
|
|
141
158
|
|