@justai/cuts 0.30.0 → 0.31.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justai/cuts",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "description": "A persona's named parts — the page shell that holds them, and the cuts themselves.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -24,13 +24,13 @@
24
24
  "./ground.css": "./src/ground.css"
25
25
  },
26
26
  "peerDependencies": {
27
- "@justai/ui": ">=0.3.0",
28
27
  "astro": ">=5"
29
28
  },
30
29
  "publishConfig": {
31
30
  "access": "public"
32
31
  },
33
32
  "dependencies": {
34
- "@justai/core": "^0.5.0"
33
+ "@justai/core": "^0.5.0",
34
+ "@justai/ui": "^0.3.0"
35
35
  }
36
36
  }
@@ -50,7 +50,11 @@ const ordered = orderLocales(locales);
50
50
  every page). `name` answers it without the one risk an `id` would carry — an id must be
51
51
  unique in a document. The value is never submitted: this input lives in no form and filters
52
52
  the list client-side. */}
53
- <input type="search" class="search" name="lang-search" placeholder={searchLabel} autocomplete="off" spellcheck="false" data-search aria-label={searchLabel} />
53
+ {/* `id` as well as `name` now. The id is the runtime-i18n hook (see <Sheet>'s title): a
54
+ consumer that translates in the browser re-writes this placeholder from its own dictionary.
55
+ Safe because the picker already assumes one instance per page — <Sheet> requires a unique
56
+ id and this file hardcodes `lang-sheet`. */}
57
+ <input type="search" class="search" id="lang-search" name="lang-search" placeholder={searchLabel} autocomplete="off" spellcheck="false" data-search aria-label={searchLabel} />
54
58
  <div class="list" role="listbox" aria-label={label} data-list>
55
59
  {ordered.map((l) => (
56
60
  <a
package/src/Sheet.astro CHANGED
@@ -61,7 +61,12 @@ interface Props {
61
61
  const { id, title, detent = "medium" } = Astro.props;
62
62
  ---
63
63
 
64
- <dialog class="sheet" id={id} data-detent={detent} aria-label={title}>
64
+ {/* aria-labelledby over aria-label when there IS a title, so the accessible name and the visible
65
+ one are the same string — and `${id}-title` is a STABLE HOOK, the same contract ConfirmSheet
66
+ exposes. A surface that translates at RUNTIME (the vault, the feed — one bundle, thirteen
67
+ languages, no per-locale routes) renders this cut in English and re-labels it from its own
68
+ dictionary. Without the hook such a consumer cannot adopt the cut at all, and writes its own. */}
69
+ <dialog class="sheet" id={id} data-detent={detent} aria-labelledby={title ? `${id}-title` : undefined} aria-label={title ? undefined : "Sheet"}>
65
70
  {/* tabindex="-1" so the PANEL can take the focus when the sheet opens. Without it, showModal()
66
71
  hands focus to the first focusable descendant — which for a picker is the search field, and on
67
72
  a phone that throws the software keyboard over the list the visitor opened the sheet to read.
@@ -72,7 +77,7 @@ const { id, title, detent = "medium" } = Astro.props;
72
77
  the thing you see is the thing you can grab. Hidden from AX: Escape and the backdrop are the
73
78
  keyboard/assistive paths, and a decorative pill announced as a control is noise. */}
74
79
  <div class="sheet-grip" data-grip aria-hidden="true"><span></span></div>
75
- {title && <h2 class="sheet-title">{title}</h2>}
80
+ {title && <h2 class="sheet-title" id={`${id}-title`}>{title}</h2>}
76
81
  <div class="sheet-body"><slot /></div>
77
82
  </div>
78
83
  </dialog>