@microbit/ui 0.1.0-alpha.3 → 0.1.0-alpha.30

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 (114) hide show
  1. package/LICENSE.md +40 -0
  2. package/README.md +256 -26
  3. package/lang/ui.ca.json +43 -3
  4. package/lang/ui.cy.json +62 -0
  5. package/lang/ui.de.json +62 -0
  6. package/lang/ui.en-us.json +40 -0
  7. package/lang/ui.en.json +40 -0
  8. package/lang/ui.es-es.json +43 -3
  9. package/lang/ui.fr.json +44 -4
  10. package/lang/ui.ga-ie.json +62 -0
  11. package/lang/ui.it.json +62 -0
  12. package/lang/ui.ja.json +44 -4
  13. package/lang/ui.ko.json +44 -4
  14. package/lang/ui.lo.json +62 -0
  15. package/lang/ui.lol.json +40 -0
  16. package/lang/ui.nl.json +44 -4
  17. package/lang/ui.pl.json +44 -4
  18. package/lang/ui.pt-br.json +44 -4
  19. package/lang/ui.vi.json +62 -0
  20. package/lang/ui.zh-cn.json +62 -0
  21. package/lang/ui.zh-tw.json +44 -4
  22. package/package.json +19 -10
  23. package/postcss-legacy-safari.cjs +96 -0
  24. package/reset.css +35 -0
  25. package/src/Avatar.recipe.ts +166 -0
  26. package/src/Avatar.tsx +278 -0
  27. package/src/Breadcrumb.recipe.ts +39 -0
  28. package/src/Breadcrumb.tsx +114 -0
  29. package/src/Button.recipe.ts +88 -50
  30. package/src/Button.tsx +64 -26
  31. package/src/ButtonGroup.tsx +37 -15
  32. package/src/Card.recipe.ts +1 -2
  33. package/src/Card.tsx +2 -1
  34. package/src/Checkbox.recipe.ts +49 -14
  35. package/src/Checkbox.tsx +111 -32
  36. package/src/CheckboxGroup.tsx +70 -0
  37. package/src/CloseButton.tsx +3 -3
  38. package/src/CloseIcon.tsx +6 -4
  39. package/src/Code.tsx +20 -0
  40. package/src/Collapse.tsx +179 -0
  41. package/src/ComboBox.tsx +246 -0
  42. package/src/Divider.tsx +72 -8
  43. package/src/Drawer.recipe.ts +4 -5
  44. package/src/Drawer.tsx +3 -4
  45. package/src/ExternalLink.tsx +43 -0
  46. package/src/Fade.tsx +62 -0
  47. package/src/Field.recipe.ts +114 -0
  48. package/src/Field.tsx +187 -0
  49. package/src/GridList.recipe.ts +57 -0
  50. package/src/GridList.tsx +81 -0
  51. package/src/Heading.recipe.ts +20 -1
  52. package/src/Heading.tsx +3 -3
  53. package/src/Icon.tsx +23 -7
  54. package/src/IconButton.tsx +7 -12
  55. package/src/Image.tsx +1 -1
  56. package/src/Input.recipe.ts +41 -28
  57. package/src/Input.tsx +23 -7
  58. package/src/InputGroup.tsx +21 -8
  59. package/src/Kbd.tsx +26 -0
  60. package/src/Link.tsx +3 -3
  61. package/src/LinkBox.tsx +2 -3
  62. package/src/LinkButton.tsx +81 -0
  63. package/src/List.tsx +8 -6
  64. package/src/ListBox.recipe.ts +43 -0
  65. package/src/ListBox.tsx +88 -0
  66. package/src/Menu.recipe.ts +51 -17
  67. package/src/Menu.tsx +117 -2
  68. package/src/Modal.recipe.ts +14 -9
  69. package/src/Modal.tsx +137 -24
  70. package/src/MoreMenuButton.tsx +63 -0
  71. package/src/NativeSelect.tsx +39 -12
  72. package/src/NativeSelectField.tsx +84 -0
  73. package/src/NumberField.recipe.ts +108 -0
  74. package/src/NumberField.tsx +138 -0
  75. package/src/PopoverArrow.tsx +19 -5
  76. package/src/ProgressBar.tsx +3 -5
  77. package/src/Radio.recipe.ts +108 -0
  78. package/src/Radio.tsx +62 -0
  79. package/src/RadioGroup.tsx +68 -0
  80. package/src/Select.recipe.ts +211 -0
  81. package/src/Select.tsx +194 -0
  82. package/src/SharedUIProvider.tsx +51 -7
  83. package/src/Skeleton.tsx +146 -0
  84. package/src/Slide.tsx +2 -2
  85. package/src/Slider.recipe.ts +24 -15
  86. package/src/Slider.tsx +65 -5
  87. package/src/Spinner.tsx +11 -9
  88. package/src/Svg.tsx +2 -3
  89. package/src/Switch.recipe.ts +58 -13
  90. package/src/Switch.tsx +39 -7
  91. package/src/Text.recipe.ts +26 -0
  92. package/src/Text.tsx +6 -2
  93. package/src/TextField.tsx +54 -40
  94. package/src/Toast.recipe.ts +49 -12
  95. package/src/Toast.tsx +151 -46
  96. package/src/Tooltip.recipe.ts +32 -0
  97. package/src/Tooltip.tsx +51 -28
  98. package/src/TooltipButton.tsx +229 -0
  99. package/src/UnmountCallback.tsx +2 -2
  100. package/src/VisuallyHidden.tsx +1 -1
  101. package/src/base-preset.ts +336 -84
  102. package/src/{chakra-tokens.ts → base-tokens.ts} +7 -7
  103. package/src/button-icon.ts +22 -0
  104. package/src/data-attrs.ts +16 -0
  105. package/src/dense-preset.ts +107 -0
  106. package/src/hooks/useBreakpointValue.ts +4 -4
  107. package/src/hooks/useClipboard.ts +63 -0
  108. package/src/hooks/useDisclosure.ts +31 -0
  109. package/src/hooks/useMediaQuery.ts +27 -0
  110. package/src/hooks/usePrevious.ts +15 -0
  111. package/src/index.ts +29 -3
  112. package/src/rac-locale.ts +33 -0
  113. package/src/system.ts +22 -1
  114. package/src/TextField.recipe.ts +0 -54
package/LICENSE.md CHANGED
@@ -19,3 +19,43 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+ ---
24
+
25
+ ## Third-party notices
26
+
27
+ This package includes design tokens and component styling derived from
28
+ [Chakra UI](https://github.com/chakra-ui/chakra-ui) v2: the token scales in
29
+ `src/base-tokens.ts` were snapshotted from `@chakra-ui/theme`'s default
30
+ values, and the component recipes were ported from Chakra's component styles.
31
+ Chakra UI is used under the MIT License:
32
+
33
+ > MIT License
34
+ >
35
+ > Copyright (c) 2019 Segun Adebayo
36
+ >
37
+ > Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ > of this software and associated documentation files (the "Software"), to deal
39
+ > in the Software without restriction, including without limitation the rights
40
+ > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ > copies of the Software, and to permit persons to whom the Software is
42
+ > furnished to do so, subject to the following conditions:
43
+ >
44
+ > The above copyright notice and this permission notice shall be included in all
45
+ > copies or substantial portions of the Software.
46
+ >
47
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50
+ > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
53
+ > SOFTWARE.
54
+
55
+ This package's `lang/ui.<locale>.json` catalogs include translations of a few
56
+ user-interface strings copied from
57
+ [React Spectrum](https://github.com/adobe/react-spectrum) — from react-aria at
58
+ tag `react-aria-components@1.19.0`, and from the Spectrum 2 InlineAlert
59
+ component's catalogs (see the README's "Strings" section for which). React
60
+ Spectrum is copyright Adobe and its contributors, and is used under the Apache
61
+ License, Version 2.0: <https://www.apache.org/licenses/LICENSE-2.0>.
package/README.md CHANGED
@@ -1,32 +1,34 @@
1
1
  # @microbit/ui
2
2
 
3
3
  react-aria-components + Panda CSS primitives with a design language ported from
4
- the Micro:bit Educational Foundation apps' original Chakra UI v2 themes.
4
+ the Micro:bit Educational Foundation apps' original
5
+ [Chakra UI](https://chakra-ui.com/) v2 themes (see
6
+ [Chakra UI heritage](#chakra-ui-heritage-and-license)).
5
7
 
6
8
  The package **ships as source**: components import `styled-system/*`, which
7
9
  each consumer generates with its own Panda preset stack. There is no build
8
- step and no CSS shipped — the consumer's codegen produces exactly the styles
9
- its tree uses.
10
+ step and no CSS shipped — the consumer's Panda run produces exactly the styles
11
+ its tree uses (`panda codegen` for the `styled-system/*` helpers, the Panda
12
+ PostCSS plugin for the CSS).
10
13
 
11
14
  ## App-side installation
12
15
 
13
- This package's own Storybook (`.storybook/` + `panda.config.ts`) is a
14
- worked example of the setup below, minus the app/brand presets. Everything
15
- an app must do:
16
+ The repo's Storybook harness (`apps/storybook`) is a worked example of the
17
+ setup below, minus the app/brand presets. Everything an app must do:
16
18
 
17
19
  1. **Panda preset stack** (`panda.config.ts`): `@pandacss/preset-base`, then
18
20
  the **base preset** (`@microbit/ui/base-preset` — the complete micro:bit
19
- design system , then optionally the app's own preset, then optionally a
20
- **private brand preset** (these are used for Foundation colours, licensed
21
- fonts).
21
+ design system), then optionally `@microbit/ui/dense-preset` (the × 0.88
22
+ spacing / × 0.9 font-size density the information-dense apps use), then
23
+ optionally the app's own preset, then optionally a **private brand
24
+ preset** (Foundation colours, licensed fonts).
22
25
 
23
26
  Later presets override earlier ones token-by-token — the base recipes and
24
27
  semantic tokens reference the brand tokens, which is how a brand swap
25
28
  restyles everything without touching recipes. Set `eject: true` (the stack
26
29
  supplies the full token system). After changing an _external_ preset
27
- dependency, regenerate clean: `rm -rf styled-system styled-system.css &&
28
- npm run panda` — incremental codegen does not detect external preset
29
- changes.
30
+ dependency, regenerate clean: `rm -rf styled-system && npm run panda` —
31
+ incremental codegen does not detect external preset changes.
30
32
 
31
33
  2. **Include this package's source** in `panda.config.ts` so Panda extracts
32
34
  the styles the components use:
@@ -39,11 +41,40 @@ npm run panda` — incremental codegen does not detect external preset
39
41
  3. **Resolve `styled-system/*` onto the generated output** for all
40
42
  importers, this package's source included — a `styled-system` alias in
41
43
  both `tsconfig.json` `paths` and the bundler config (see the
42
- `viteFinal` in `.storybook/main.ts`).
43
- 4. **Cascade layers** (`src/layers.css`, imported first): declares the
44
- document-wide layer order including the `vendor` layer for third-party
45
- stylesheets import any vendor CSS with `@import "..." layer(vendor)`
46
- so it beats the preflight but loses to app styling.
44
+ `viteFinal` in `apps/storybook`'s `.storybook/main.ts`).
45
+ 4. **Generate and load the CSS** with Panda's PostCSS plugin. Keep Vite's
46
+ default transformer do **not** set `css.transformer: "lightningcss"`,
47
+ which disables PostCSS. Add a `postcss.config.cjs`:
48
+
49
+ ```js
50
+ module.exports = { plugins: { "@pandacss/dev/postcss": {} } };
51
+ ```
52
+
53
+ Run `panda codegen` as a `prepare`/`predev` step so the `styled-system/*`
54
+ helpers exist before `tsc`; the plugin generates the CSS during the bundle.
55
+ Import **one** entry stylesheet — first, before app styles — that declares
56
+ the cascade-layer order; the plugin injects the generated CSS into it (the
57
+ declaration must list all of Panda's layers, hence ≥5 names):
58
+
59
+ ```css
60
+ /* e.g. src/layers.css, imported once at the app root */
61
+ @layer reset, vendor, base, tokens, recipes, utilities;
62
+
63
+ @import "@microbit/ui/reset.css" layer(reset);
64
+ ```
65
+
66
+ The `reset.css` import is **required**: it carries the
67
+ `* { border-color; word-wrap }` defaults, which must sit in the bottom
68
+ layer (the legacy-Safari cascade-layer flattening specificity-boosts
69
+ higher layers above CSS it can't see — runtime-injected styles, other
70
+ files). Without it, elements that set a border
71
+ width but no colour render `currentColor` borders.
72
+ The `vendor` layer is for third-party stylesheets: import any vendor CSS
73
+ with `@import "..." layer(vendor)` so it beats the preflight reset but
74
+ loses to app styling. See `apps/storybook`'s
75
+ `.storybook/{layers.css,preview.tsx,main.ts}` + `postcss.config.cjs` for
76
+ the worked example.
77
+
47
78
  5. **react-intl**: an `IntlProvider` above any shared-ui usage. English
48
79
  works with no setup (components carry inline `defaultMessage`); for
49
80
  other locales compile this package's `lang/ui.<locale>.json` into the
@@ -53,10 +84,97 @@ node_modules/@microbit/ui/lang/ui.fr.json --ast --out-file ...` (multiple
53
84
  input files merge; ids are `ui.`-namespaced so they can't collide). This
54
85
  keeps the strings in the app's lazily loaded locale chunks rather than
55
86
  an eagerly bundled catalog-of-all-locales.
56
- 6. **`ToastProvider`** once near the root, inside the `IntlProvider`.
57
- 7. Optionally **`SharedUIProvider`** with an overlay-close registrar so the
58
- app can dismiss open menus from outside the tree (e.g. the Android
59
- hardware back button). Apps without one can omit the provider.
87
+
88
+ The `locale` you pass must be the language the app actually renders in,
89
+ which is not always the user's language setting: apps that list languages
90
+ only an embedded product (e.g. MakeCode) is translated into fall back to
91
+ their English catalog for those, and should then pass `en`, keeping the
92
+ chosen language in their own settings for the embed. Everything downstream
93
+ reads this locale as a statement about the rendered page — `<html lang>`
94
+ via `SharedUIProvider`, react-aria's text direction and built-in strings,
95
+ `Intl` number/date formatting and plural rules. A catalog that loads but
96
+ has per-message gaps (an incomplete translation) is still that language;
97
+ only a wholesale fallback to the English catalog should claim `en`.
98
+
99
+ 6. **`SharedUIProvider`** inside the `IntlProvider`, wrapping the app. It
100
+ passes the locale on to react-aria, which translates its own built-in
101
+ strings (see [Strings](#strings)); without it those follow the browser
102
+ rather than the app's language setting. It also keeps `<html lang>` in
103
+ step with the locale so assistive tech announces the page in the app's
104
+ language — pass `setDocumentLang={false}` where the app doesn't own the
105
+ document it's mounted in (an embedded widget). Also takes an optional
106
+ overlay-close registrar, so the app can dismiss open menus from outside
107
+ the tree (e.g. the Android hardware back button).
108
+ 7. **`ToastProvider`** once near the root, inside the two providers above.
109
+
110
+ ## Upgrading in an app
111
+
112
+ After bumping the `@microbit/ui` version:
113
+
114
+ 1. `npm install` — the apps' postinstall runs `panda codegen`, but incremental
115
+ codegen does not detect external preset changes, so regenerate clean:
116
+ `rm -rf styled-system && npm run panda`.
117
+ 2. `npm run i18n:compile` — recompiles the app's per-locale catalogs so new
118
+ and retranslated `ui.*` strings ship (otherwise they fall back to English,
119
+ or stay missing).
120
+
121
+ ## Legacy browser support (Safari < 15) — temporary
122
+
123
+ Panda's output uses two things Safari below 15 mishandles. If an app must
124
+ support that far back (e.g. Safari 14.1 web views), add the app-side wiring
125
+ below. **All of it is meant to be deleted once the app's support floor rises
126
+ past these browsers** — it lives entirely in the consuming app's build config,
127
+ never in shipped component source. This package's own Storybook does _not_ use
128
+ any of it (it targets modern browsers, where these work natively).
129
+
130
+ Two concerns:
131
+
132
+ 1. **`@layer`** — Safari < 15.4 drops `@layer` blocks wholesale, leaving the
133
+ app unstyled. Flatten them with `@csstools/postcss-cascade-layers` (which
134
+ rewrites layers into `:not(#\#)` specificity fallbacks; ~+8% gzipped CSS,
135
+ mostly compressible).
136
+ 2. **Logical shorthands + `var()`** — Safari 14.x silently drops
137
+ `padding-inline: var(--…)` and friends (a literal value, or the -start/-end
138
+ longhands, both work). Panda emits these shorthands for its px/py/mx/my
139
+ utilities, so most token spacing collapses. Expand them to longhands with
140
+ this package's `postcss-legacy-safari` plugin (kept logical, so RTL flips).
141
+
142
+ ```bash
143
+ npm i -D @csstools/postcss-cascade-layers
144
+ ```
145
+
146
+ ```js
147
+ // postcss.config.cjs — the two legacy plugins run AFTER Panda's (step 4), so
148
+ // switch that config to array form:
149
+ const {
150
+ expandLogicalShorthands,
151
+ } = require("@microbit/ui/postcss-legacy-safari");
152
+
153
+ module.exports = {
154
+ plugins: [
155
+ require("@pandacss/dev/postcss")(),
156
+ expandLogicalShorthands(),
157
+ require("@csstools/postcss-cascade-layers"),
158
+ ],
159
+ };
160
+ ```
161
+
162
+ ```ts
163
+ // vite.config.ts — pin the CSS/JS floor. Otherwise the lightningcss minifier
164
+ // inherits build.target and downlevels logical longhands into fragile
165
+ // :lang()-based physical rules. Keep in sync with package.json "browserslist".
166
+ const BUILD_TARGETS = ["safari14.1", "ios14.5", "chrome90", "edge90", "firefox88"];
167
+ // ...
168
+ build: {
169
+ target: BUILD_TARGETS,
170
+ cssTarget: BUILD_TARGETS,
171
+ cssMinify: "lightningcss", // lightningcss as minifier only, not the transformer
172
+ },
173
+ ```
174
+
175
+ To drop it all: raise `BUILD_TARGETS`/`browserslist` past the affected
176
+ browsers, then remove the two PostCSS plugins (and this package's
177
+ `postcss-legacy-safari` export).
60
178
 
61
179
  ## The CSS-variable contract
62
180
 
@@ -75,15 +193,59 @@ keep them stable:
75
193
  - Brand/app presets may change token _values_, never token _names_.
76
194
 
77
195
  Semantic tokens (`languageText`, `statusBarBg`, `danger.*`, `toast*Bg`,
78
- `controlCheckedBg`, `focusBorder`, …) are the extension points brand presets
79
- override; they resolve through var indirection, so overrides apply wherever
80
- the token is consumed.
196
+ `button.*`, `controlCheckedBg`, `focusBorder`, …) are the extension points
197
+ brand presets override; they resolve through var indirection, so overrides
198
+ apply wherever the token is consumed.
199
+
200
+ `focusRing` and `focusBorder` need more care: their values are condition
201
+ objects and a merge replaces a value wholesale, so the flat form drops the
202
+ on-dark flip below. Keep the shape:
203
+
204
+ ```ts
205
+ focusBorder: { value: { base: "{colors.brand.700}", _onDark: "{colors.white}" } };
206
+ ```
207
+
208
+ ## Dark surfaces
209
+
210
+ Focus indicators are surface-aware through one tag. The default focus ring
211
+ is ink; on a dark surface it must be white, so tag the surface element by
212
+ spreading the exported constant:
213
+
214
+ ```tsx
215
+ import { darkSurface } from "@microbit/ui";
216
+
217
+ <header {...darkSurface}>…</header>; // a black toolbar, a coloured sidebar bar
218
+ ```
219
+
220
+ Custom properties inherit, so tagging the bar covers the bar itself and
221
+ every control inside it — including ones added later. If the tagged element
222
+ is focusable, tag one level in instead: its own ring is drawn _outside_ it,
223
+ on whatever is behind it. (The Toast does this — the card is dark and
224
+ focusable, so the tag sits on its close button.) Portalled overlays (a
225
+ modal opened from a dark toolbar) escape the tag with the DOM, which is
226
+ correct. Under the hood it is `data-surface="dark"`, which the preset's
227
+ `onDark` condition scopes the `focusRing`/`focusBorder` token flips to.
228
+
229
+ Two rules:
230
+
231
+ - **Dark surfaces must tag** — the ink ring is near-invisible on them, and
232
+ there is no automatic detection.
233
+ - **Tag surfaces, not themes**: "dark" describes the surface's own
234
+ luminance, so tag surfaces that are dark by design (a black toolbar, a
235
+ coloured sidebar bar) rather than anything relative to the app's overall
236
+ look. This is what will let the tag survive a dark mode if we ship one:
237
+ designed-dark surfaces stay dark and keep their tags; everything else
238
+ stays untagged, and a dark mode would flip the untagged defaults via
239
+ token conditions, never via markup.
240
+
241
+ Rule of thumb for coloured bars: tag when the surface lacks 3:1 contrast
242
+ against ink — roughly, darker than the grey ramp's 500.
81
243
 
82
244
  ## Runtime token lookups
83
245
 
84
246
  For values that feed _computation_ rather than stylesheets (canvas painting,
85
- colour math, inline `style` for data-driven values see gotcha #9 in
86
- RAC-MIGRATION.md), import the runtime lookup:
247
+ colour math, inline `style` for data-driven values that Panda's static
248
+ extraction can't see), import the runtime lookup:
87
249
 
88
250
  ```ts
89
251
  import { token } from "@microbit/ui"; // re-exports styled-system/tokens
@@ -116,3 +278,71 @@ Crowdin via the repo-root `npm run update-translations -- <path to extracted
116
278
  Crowdin ZIP>` (config-driven over packages in
117
279
  `bin/update-translations.cjs`), after which you run `npm run i18n:tidy`
118
280
  from the root.
281
+
282
+ `bin/i18n-packages.cjs` lists every locale a consuming app ships, so a string
283
+ translated for one app is in place for the next. `i18n:tidy` backfills anything
284
+ missing from English, so an untranslated string renders English rather than
285
+ blank.
286
+
287
+ Until this package's Crowdin project is wired up, the non-English catalogs are
288
+ pre-Crowdin seeds — some strings AI-drafted, all of them for Crowdin to review
289
+ — credited as follows. Translations of the same strings elsewhere in the
290
+ micro:bit translation programme: ml-trainer and python-editor-v3, and
291
+ MakeCode's editor strings, which are not in the pxt repo but can be fetched per
292
+ locale from
293
+ `https://makecode.microbit.org/api/translations?lang=<locale>&filename=strings.json&approved=true`.
294
+ The `ui.toast-status-*` words come from Spectrum 2's InlineAlert catalogs
295
+ (`@react-spectrum/s2/intl/*.json`, keys `inlinealert.informative` / `notice` /
296
+ `negative` / `positive`), under the same licence and notice as the react-aria
297
+ seed below.
298
+
299
+ ### react-aria's own strings
300
+
301
+ Separately from all of the above, react-aria has built-in strings of its own
302
+ and translates them from catalogs it bundles, nothing to do with react-intl.
303
+ `SharedUIProvider` hands it the app's locale so the two agree. It bundles 34
304
+ locales; of ours, ca, cy, ga-IE, lo and vi (and the `lol` pseudo-locale) are not
305
+ among them and fall back to English, and there is no supported way to teach it
306
+ more (the rest resolve, including where our id is less specific than
307
+ react-aria's — `fr` finds its fr-FR).
308
+
309
+ Where react-aria lets a prop replace one of those strings, the component
310
+ passes our own react-intl message instead, so the string rides `lang/` and
311
+ Crowdin like everything else and the missing locales can catch up:
312
+
313
+ - `ui.numberfield-increase` / `ui.numberfield-decrease` — NumberField's
314
+ stepper button labels
315
+ - `ui.toast-region` — the toast region's landmark label (counts the visible
316
+ toasts, as react-aria's does)
317
+ - `ui.combobox-trigger` / `ui.combobox-listbox` — the button that opens a
318
+ ComboBox and its popup list
319
+ - `ui.select-placeholder` — Select's placeholder when the caller passes none
320
+ - `ui.select-row-action` — the name of a `slot="selection"` checkbox in a
321
+ GridList row, read together with the row's content. (A future Table's
322
+ select-all header checkbox shares the slot name and will need its own
323
+ message.)
324
+
325
+ Their non-English translations were pre-seeded from react-aria's own catalogs
326
+ ([adobe/react-spectrum](https://github.com/adobe/react-spectrum) at tag
327
+ `react-aria-components@1.19.0`, Apache 2.0 — see the notice in
328
+ [LICENSE.md](LICENSE.md)) for the locales both sides cover; the five above had
329
+ no such source. That provenance is recorded here rather than in `lang/` because
330
+ Crowdin roundtrips rewrite those files.
331
+
332
+ What react-aria does not expose as a prop — live announcements ("2 items
333
+ selected"), its hidden dismiss buttons — still comes from its bundled catalogs
334
+ and falls back to English in the locales above.
335
+
336
+ ## Chakra UI heritage and license
337
+
338
+ This package's design language began as a faithful port of
339
+ [Chakra UI](https://chakra-ui.com/) v2's, done so the apps it serves could
340
+ leave Chakra without a redesign: `src/base-tokens.ts` was snapshotted from
341
+ `@chakra-ui/theme`'s default token scales, and the `*.recipe.ts` files were
342
+ ported from Chakra's component styles onto Panda config recipes.
343
+ However far it evolves from that starting point, it owes its foundations to
344
+ Chakra. Thanks to Segun Adebayo and the Chakra UI contributors.
345
+
346
+ The package is [MIT](LICENSE.md) © Micro:bit Educational Foundation and
347
+ contributors; Chakra UI is MIT © Segun Adebayo, and its notice is carried
348
+ in [LICENSE.md](LICENSE.md).
package/lang/ui.ca.json CHANGED
@@ -1,22 +1,62 @@
1
1
  {
2
+ "ui.breadcrumb": {
3
+ "defaultMessage": "Rastres de navegació",
4
+ "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
+ },
2
6
  "ui.close-action": {
3
7
  "defaultMessage": "Tanca ",
4
8
  "description": "Close button text or label"
5
9
  },
10
+ "ui.combobox-listbox": {
11
+ "defaultMessage": "Suggeriments",
12
+ "description": "Accessible label for a ComboBox's dropdown list of suggestions"
13
+ },
14
+ "ui.combobox-trigger": {
15
+ "defaultMessage": "Mostra els suggeriments",
16
+ "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
+ },
18
+ "ui.loading": {
19
+ "defaultMessage": "S'està carregant",
20
+ "description": "Announced by screen readers for a button showing a loading spinner"
21
+ },
22
+ "ui.new-tab-notice": {
23
+ "defaultMessage": "opens in a new tab",
24
+ "description": "Visually hidden suffix on links that open a new tab, announced by screen readers"
25
+ },
26
+ "ui.numberfield-decrease": {
27
+ "defaultMessage": "Decrementa {fieldLabel}",
28
+ "description": "Accessible label for a number field's decrement stepper; fieldLabel is the field's label and may be empty"
29
+ },
30
+ "ui.numberfield-increase": {
31
+ "defaultMessage": "Incrementa {fieldLabel}",
32
+ "description": "Accessible label for a number field's increment stepper; fieldLabel is the field's label and may be empty"
33
+ },
34
+ "ui.select-placeholder": {
35
+ "defaultMessage": "Selecciona un element",
36
+ "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
37
+ },
38
+ "ui.select-row-action": {
39
+ "defaultMessage": "Selecciona",
40
+ "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
41
+ },
42
+ "ui.toast-region": {
43
+ "defaultMessage": "{count, plural, one {# notificació} other {# notificacions}}.",
44
+ "description": "Accessible label for the notifications area; count is the number of notifications showing"
45
+ },
6
46
  "ui.toast-status-error": {
7
47
  "defaultMessage": "Error",
8
48
  "description": "Announced by screen readers before an error notification"
9
49
  },
10
50
  "ui.toast-status-info": {
11
- "defaultMessage": "Information",
51
+ "defaultMessage": "Informació",
12
52
  "description": "Announced by screen readers before an informational notification"
13
53
  },
14
54
  "ui.toast-status-success": {
15
- "defaultMessage": "Success",
55
+ "defaultMessage": "Completat amb èxit",
16
56
  "description": "Announced by screen readers before a success notification"
17
57
  },
18
58
  "ui.toast-status-warning": {
19
- "defaultMessage": "Warning",
59
+ "defaultMessage": "Advertència",
20
60
  "description": "Announced by screen readers before a warning notification"
21
61
  }
22
62
  }
@@ -0,0 +1,62 @@
1
+ {
2
+ "ui.breadcrumb": {
3
+ "defaultMessage": "Briwsionyn Bara",
4
+ "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
+ },
6
+ "ui.close-action": {
7
+ "defaultMessage": "Cau",
8
+ "description": "Close button text or label"
9
+ },
10
+ "ui.combobox-listbox": {
11
+ "defaultMessage": "Suggestions",
12
+ "description": "Accessible label for a ComboBox's dropdown list of suggestions"
13
+ },
14
+ "ui.combobox-trigger": {
15
+ "defaultMessage": "Show suggestions",
16
+ "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
+ },
18
+ "ui.loading": {
19
+ "defaultMessage": "Wrthi'n Llwytho",
20
+ "description": "Announced by screen readers for a button showing a loading spinner"
21
+ },
22
+ "ui.new-tab-notice": {
23
+ "defaultMessage": "opens in a new tab",
24
+ "description": "Visually hidden suffix on links that open a new tab, announced by screen readers"
25
+ },
26
+ "ui.numberfield-decrease": {
27
+ "defaultMessage": "Decrease {fieldLabel}",
28
+ "description": "Accessible label for a number field's decrement stepper; fieldLabel is the field's label and may be empty"
29
+ },
30
+ "ui.numberfield-increase": {
31
+ "defaultMessage": "Increase {fieldLabel}",
32
+ "description": "Accessible label for a number field's increment stepper; fieldLabel is the field's label and may be empty"
33
+ },
34
+ "ui.select-placeholder": {
35
+ "defaultMessage": "Select an item",
36
+ "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
37
+ },
38
+ "ui.select-row-action": {
39
+ "defaultMessage": "Dewis",
40
+ "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
41
+ },
42
+ "ui.toast-region": {
43
+ "defaultMessage": "{count, plural, one {# notification} other {# notifications}}.",
44
+ "description": "Accessible label for the notifications area; count is the number of notifications showing"
45
+ },
46
+ "ui.toast-status-error": {
47
+ "defaultMessage": "Gwall",
48
+ "description": "Announced by screen readers before an error notification"
49
+ },
50
+ "ui.toast-status-info": {
51
+ "defaultMessage": "Information",
52
+ "description": "Announced by screen readers before an informational notification"
53
+ },
54
+ "ui.toast-status-success": {
55
+ "defaultMessage": "Llwyddiant",
56
+ "description": "Announced by screen readers before a success notification"
57
+ },
58
+ "ui.toast-status-warning": {
59
+ "defaultMessage": "Rhybudd",
60
+ "description": "Announced by screen readers before a warning notification"
61
+ }
62
+ }
@@ -0,0 +1,62 @@
1
+ {
2
+ "ui.breadcrumb": {
3
+ "defaultMessage": "Navigationspfad",
4
+ "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
+ },
6
+ "ui.close-action": {
7
+ "defaultMessage": "Schließen",
8
+ "description": "Close button text or label"
9
+ },
10
+ "ui.combobox-listbox": {
11
+ "defaultMessage": "Empfehlungen",
12
+ "description": "Accessible label for a ComboBox's dropdown list of suggestions"
13
+ },
14
+ "ui.combobox-trigger": {
15
+ "defaultMessage": "Empfehlungen anzeigen",
16
+ "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
+ },
18
+ "ui.loading": {
19
+ "defaultMessage": "Laden",
20
+ "description": "Announced by screen readers for a button showing a loading spinner"
21
+ },
22
+ "ui.new-tab-notice": {
23
+ "defaultMessage": "opens in a new tab",
24
+ "description": "Visually hidden suffix on links that open a new tab, announced by screen readers"
25
+ },
26
+ "ui.numberfield-decrease": {
27
+ "defaultMessage": "{fieldLabel} verringern",
28
+ "description": "Accessible label for a number field's decrement stepper; fieldLabel is the field's label and may be empty"
29
+ },
30
+ "ui.numberfield-increase": {
31
+ "defaultMessage": "{fieldLabel} erhöhen",
32
+ "description": "Accessible label for a number field's increment stepper; fieldLabel is the field's label and may be empty"
33
+ },
34
+ "ui.select-placeholder": {
35
+ "defaultMessage": "Element wählen",
36
+ "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
37
+ },
38
+ "ui.select-row-action": {
39
+ "defaultMessage": "Auswählen",
40
+ "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
41
+ },
42
+ "ui.toast-region": {
43
+ "defaultMessage": "{count, plural, one {# Benachrichtigung} other {# Benachrichtigungen}}.",
44
+ "description": "Accessible label for the notifications area; count is the number of notifications showing"
45
+ },
46
+ "ui.toast-status-error": {
47
+ "defaultMessage": "Fehler",
48
+ "description": "Announced by screen readers before an error notification"
49
+ },
50
+ "ui.toast-status-info": {
51
+ "defaultMessage": "Informationen",
52
+ "description": "Announced by screen readers before an informational notification"
53
+ },
54
+ "ui.toast-status-success": {
55
+ "defaultMessage": "Erfolg",
56
+ "description": "Announced by screen readers before a success notification"
57
+ },
58
+ "ui.toast-status-warning": {
59
+ "defaultMessage": "Warnung",
60
+ "description": "Announced by screen readers before a warning notification"
61
+ }
62
+ }
@@ -1,8 +1,48 @@
1
1
  {
2
+ "ui.breadcrumb": {
3
+ "defaultMessage": "Breadcrumb",
4
+ "description": "Accessible label for the breadcrumb navigation trail (the WAI-ARIA APG's conventional name)"
5
+ },
2
6
  "ui.close-action": {
3
7
  "defaultMessage": "Close",
4
8
  "description": "Close button text or label"
5
9
  },
10
+ "ui.combobox-listbox": {
11
+ "defaultMessage": "Suggestions",
12
+ "description": "Accessible label for a ComboBox's dropdown list of suggestions"
13
+ },
14
+ "ui.combobox-trigger": {
15
+ "defaultMessage": "Show suggestions",
16
+ "description": "Accessible label for the button that opens a ComboBox's suggestions dropdown"
17
+ },
18
+ "ui.loading": {
19
+ "defaultMessage": "Loading",
20
+ "description": "Announced by screen readers for a button showing a loading spinner"
21
+ },
22
+ "ui.new-tab-notice": {
23
+ "defaultMessage": "opens in a new tab",
24
+ "description": "Visually hidden suffix on links that open a new tab, announced by screen readers"
25
+ },
26
+ "ui.numberfield-decrease": {
27
+ "defaultMessage": "Decrease {fieldLabel}",
28
+ "description": "Accessible label for a number field's decrement stepper; fieldLabel is the field's label and may be empty"
29
+ },
30
+ "ui.numberfield-increase": {
31
+ "defaultMessage": "Increase {fieldLabel}",
32
+ "description": "Accessible label for a number field's increment stepper; fieldLabel is the field's label and may be empty"
33
+ },
34
+ "ui.select-placeholder": {
35
+ "defaultMessage": "Select an item",
36
+ "description": "Shown in a Select's trigger while nothing is chosen and the app supplies no placeholder"
37
+ },
38
+ "ui.select-row-action": {
39
+ "defaultMessage": "Select",
40
+ "description": "Accessible label for a row-selection checkbox in a list or table; screen readers read it together with the row's content"
41
+ },
42
+ "ui.toast-region": {
43
+ "defaultMessage": "{count, plural, one {# notification} other {# notifications}}.",
44
+ "description": "Accessible label for the notifications area; count is the number of notifications showing"
45
+ },
6
46
  "ui.toast-status-error": {
7
47
  "defaultMessage": "Error",
8
48
  "description": "Announced by screen readers before an error notification"