@uniweb/kit 0.10.0 → 0.10.2
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 +4 -3
- package/src/prose-tokens.css +32 -2
- package/src/styled/Render/index.jsx +46 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uniweb/kit",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Standard component library for Uniweb foundations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -36,13 +36,14 @@
|
|
|
36
36
|
"node": ">=20.19"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@tailwindcss/typography": "^0.5.20",
|
|
39
40
|
"clsx": "^2.1.0",
|
|
40
41
|
"fuse.js": "^7.0.0",
|
|
41
42
|
"shiki": "^3.0.0",
|
|
42
43
|
"tailwind-merge": "^3.6.0",
|
|
43
|
-
"@uniweb/semantic-parser": "1.2.0",
|
|
44
44
|
"@uniweb/core": "0.8.0",
|
|
45
|
-
"@uniweb/scene": "0.1.2"
|
|
45
|
+
"@uniweb/scene": "0.1.2",
|
|
46
|
+
"@uniweb/semantic-parser": "1.2.0"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
49
|
"react": "^19.0.0",
|
package/src/prose-tokens.css
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tailwind Typography, wired to the theme.
|
|
3
3
|
*
|
|
4
|
-
* Usage —
|
|
4
|
+
* Usage — one line, in the foundation's stylesheet:
|
|
5
5
|
*
|
|
6
|
-
* @plugin "@tailwindcss/typography";
|
|
7
6
|
* @import "@uniweb/kit/prose-tokens.css";
|
|
8
7
|
*
|
|
8
|
+
* That is the whole setup: this file brings the plugin with it (below) and then
|
|
9
|
+
* overrides its greys. It used to take two lines, and the foundation had to
|
|
10
|
+
* install the plugin itself and remember that the order mattered.
|
|
11
|
+
*
|
|
9
12
|
* `prose` ships its own greys, which means long-form body copy is the one part
|
|
10
13
|
* of a foundation that ignores the site's theme.yml unless someone bridges it
|
|
11
14
|
* by hand. Everyone does bridge it by hand, identically, and the bridge is easy
|
|
@@ -29,6 +32,33 @@
|
|
|
29
32
|
* other one only supplies column width and padding.
|
|
30
33
|
*/
|
|
31
34
|
|
|
35
|
+
/*
|
|
36
|
+
* The plugin comes from kit, and the ORDER below is the reason.
|
|
37
|
+
*
|
|
38
|
+
* A `@plugin` inside a package's own CSS resolves from that package's
|
|
39
|
+
* dependencies, so a foundation importing this file needs nothing installed
|
|
40
|
+
* (verified 2026-07-30: a foundation with no typography dependency and no
|
|
41
|
+
* `@plugin` line of its own emitted `.prose :where(p){margin-top:1.25em}` in a
|
|
42
|
+
* production build).
|
|
43
|
+
*
|
|
44
|
+
* Why it moved here rather than staying the foundation's job. The overrides
|
|
45
|
+
* below have to come AFTER the plugin's own declarations or they lose on equal
|
|
46
|
+
* specificity — which made "install this, then import that, in this order" a
|
|
47
|
+
* three-part instruction a foundation could get subtly wrong, and the failure
|
|
48
|
+
* is silent: the variables are set, the rules they modify do not exist, and
|
|
49
|
+
* prose renders with no margins at all. Measured on a foundation missing only
|
|
50
|
+
* the plugin: `--tw-prose-body` present, every paragraph `margin-top: 0px`, no
|
|
51
|
+
* warning from anywhere. Owning both halves here makes the order unorderable.
|
|
52
|
+
*
|
|
53
|
+
* The precedent is `shiki` and `fuse.js` — kit takes DIRECT dependencies on
|
|
54
|
+
* what its own code needs at build time rather than asking a foundation to
|
|
55
|
+
* supply them (framework CLAUDE.md gotcha #10). This is that rule applied to
|
|
56
|
+
* the CSS layer. A foundation that never writes `prose` pays disk only:
|
|
57
|
+
* Tailwind emits utilities that are used, so an unused plugin generates
|
|
58
|
+
* nothing.
|
|
59
|
+
*/
|
|
60
|
+
@plugin "@tailwindcss/typography";
|
|
61
|
+
|
|
32
62
|
.prose {
|
|
33
63
|
--tw-prose-body: var(--body);
|
|
34
64
|
--tw-prose-headings: var(--heading);
|
|
@@ -144,6 +144,51 @@ function renderAll(sequence, block, components) {
|
|
|
144
144
|
))
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* A table cell's contents, with a lone block UNWRAPPED.
|
|
149
|
+
*
|
|
150
|
+
* The schema declares `tableCell` as `paragraph+`, so a markdown cell is always
|
|
151
|
+
* exactly one block — and emitting its `<p>` faithfully is what a typography
|
|
152
|
+
* layer then gives paragraph margins to. Measured on a real docs site: 17.5px
|
|
153
|
+
* top and bottom inside every cell, turning a one-line reference row into 75px.
|
|
154
|
+
*
|
|
155
|
+
* TWO shapes reach a cell, which is easy to miss and was: an ordinary paragraph,
|
|
156
|
+
* and a `link` — because the parser PROMOTES a paragraph holding nothing but a
|
|
157
|
+
* link, which is what makes a link on its own line a call to action in prose.
|
|
158
|
+
* A cell whose whole content is a link is the same promotion arriving somewhere
|
|
159
|
+
* it means nothing, so it unwraps too. Fixing only the paragraph left every
|
|
160
|
+
* link-only cell tall, which is how this was found: 17 of them on one page.
|
|
161
|
+
*
|
|
162
|
+
* A cell holding genuinely several blocks still gets them, because that is what
|
|
163
|
+
* it is.
|
|
164
|
+
*/
|
|
165
|
+
function renderCell(cell, block, components) {
|
|
166
|
+
const children = cell.children || []
|
|
167
|
+
if (children.length !== 1) return renderAll(children, block, components)
|
|
168
|
+
|
|
169
|
+
const [only] = children
|
|
170
|
+
|
|
171
|
+
if (only?.type === 'paragraph') {
|
|
172
|
+
if (!only.text) return null
|
|
173
|
+
return /<uniweb-inset/.test(only.text) ? (
|
|
174
|
+
renderParagraphWithInsets(only.text, block)
|
|
175
|
+
) : (
|
|
176
|
+
<SafeHtml value={only.text} as="span" />
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (only?.type === 'link') {
|
|
181
|
+
const { href, label } = only.attrs || {}
|
|
182
|
+
return <Link to={href}>{label}</Link>
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (only?.type === 'button') {
|
|
186
|
+
return <Link to={only.attrs?.href}>{only.text}</Link>
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return renderAll(children, block, components)
|
|
190
|
+
}
|
|
191
|
+
|
|
147
192
|
/**
|
|
148
193
|
* One element of a sequence.
|
|
149
194
|
*
|
|
@@ -255,7 +300,7 @@ export function SequenceElement({ element, block, components }) {
|
|
|
255
300
|
colSpan={cell.colspan > 1 ? cell.colspan : undefined}
|
|
256
301
|
rowSpan={cell.rowspan > 1 ? cell.rowspan : undefined}
|
|
257
302
|
>
|
|
258
|
-
{
|
|
303
|
+
{renderCell(cell, block, components)}
|
|
259
304
|
</CellTag>
|
|
260
305
|
)
|
|
261
306
|
})}
|