@uniweb/kit 0.19.10 → 0.19.12

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/kit",
3
- "version": "0.19.10",
3
+ "version": "0.19.12",
4
4
  "description": "Standard component library for Uniweb foundations",
5
5
  "type": "module",
6
6
  "exports": {
@@ -43,11 +43,11 @@
43
43
  "shiki": "^3.0.0",
44
44
  "tailwind-merge": "^3.6.0",
45
45
  "temml": "^0.13.2",
46
- "@uniweb/projections": "^0.7.10",
46
+ "@uniweb/semantic-parser": "^1.5.0",
47
+ "@uniweb/core": "^0.35.0",
47
48
  "@uniweb/scene": "^0.1.3",
48
- "@uniweb/schemas": "^0.9.0",
49
- "@uniweb/core": "^0.34.0",
50
- "@uniweb/semantic-parser": "^1.4.1"
49
+ "@uniweb/schemas": "^0.9.3",
50
+ "@uniweb/projections": "^0.7.11"
51
51
  },
52
52
  "peerDependencies": {
53
53
  "react": "^19.0.0",
@@ -131,13 +131,17 @@ export function FileLogo({ filename, size = '24', className, ...props }) {
131
131
  const ext = getExtension(filename)
132
132
  const iconType = FILE_ICONS[ext] || 'default'
133
133
  const icon = ICONS[iconType]
134
+ // A number or a string of digits is pixels. React appends `px` to a number and
135
+ // to nothing else, so the default `'24'` rendered `width:24` — invalid CSS the
136
+ // browser drops — until 2026-09-29. Any other string (`'1.5em'`) is kept as written.
137
+ const dimension = /^\d+(\.\d+)?$/.test(String(size)) ? `${size}px` : size
134
138
 
135
139
  return (
136
140
  <svg
137
141
  viewBox="0 0 24 24"
138
142
  fill="currentColor"
139
143
  className={cn('inline-block', className)}
140
- style={{ width: size, height: size }}
144
+ style={{ width: dimension, height: dimension }}
141
145
  aria-hidden="true"
142
146
  {...props}
143
147
  >
@@ -54,6 +54,7 @@ import { Image } from '../../components/Image/index.js'
54
54
  import { Media } from '../../components/Media/index.js'
55
55
  import { Icon } from '../../components/Icon/index.js'
56
56
  import { Link } from '../../components/Link/index.js'
57
+ import { FileLogo } from '../../components/FileLogo/index.js'
57
58
  import { Code } from '../Section/renderers/Code.jsx'
58
59
  import { Divider } from '../Section/renderers/Divider.jsx'
59
60
 
@@ -98,7 +99,6 @@ export const NOT_RENDERED = {
98
99
  'inset_ref nodes, and they render nothing.',
99
100
  form: 'an editor node; its data reaches components as content.data[schemaId]',
100
101
  'card-group': 'an editor node, deprecated — maps to content.data[cardType]',
101
- 'document-group': 'an editor node — its documents reach content.links',
102
102
  }
103
103
 
104
104
  /**
@@ -114,6 +114,11 @@ export const NOT_RENDERED = {
114
114
  * internal links. Until 2026-07-31 nothing emitted it, so an authored id
115
115
  * existed only inside the registry and never reached the document.
116
116
  */
117
+ /** A file's name from its address — the last path segment, without a query or fragment. */
118
+ function fileNameOf(url) {
119
+ return String(url || '').split(/[?#]/)[0].split('/').pop() || ''
120
+ }
121
+
117
122
  function authoredId(element) {
118
123
  return element?.attrs?.id ?? element?.id ?? undefined
119
124
  }
@@ -312,6 +317,33 @@ export function SequenceElement({ element, block, components }) {
312
317
  )
313
318
  }
314
319
 
320
+ // A file — a PDF — with an optional preview: one link to the file, holding
321
+ // the preview (or a file badge, when there is none) and the document's name.
322
+ // The author and description describe the RESOURCE, so they sit in the
323
+ // caption, and the preview's alt is empty — the name labels the link. <Link>
324
+ // treats a file address as a download and applies the base path. Until
325
+ // 2026-09-29 the parser delivered a document as an image, and this drew
326
+ // `<img src="report.pdf">`.
327
+ case 'document': {
328
+ const { url, alt, caption, preview, author, description } = element.attrs || {}
329
+ const name = caption || alt || fileNameOf(url)
330
+ return (
331
+ <figure id={authoredId(element)} data-kind="document">
332
+ <Link to={url}>
333
+ {preview ? <Image src={preview} alt="" /> : <FileLogo filename={url} />}
334
+ <span>{name}</span>
335
+ </Link>
336
+ {(author || description) && (
337
+ <figcaption>
338
+ {author && <span>{author}</span>}
339
+ {author && description && ' — '}
340
+ {description && <span>{description}</span>}
341
+ </figcaption>
342
+ )}
343
+ </figure>
344
+ )
345
+ }
346
+
315
347
  // Spread rather than cherry-pick: a markdown video carries poster and the
316
348
  // playback flags, and <Media> reads all of them.
317
349
  case 'video':