@eifi1/ui-kit 0.34.0 → 0.35.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/README.md +82 -38
- package/dist/billing/billing-banner.d.ts +5 -2
- package/dist/billing/billing-banner.js.map +1 -1
- package/dist/billing/plan-limit-notice.d.ts +5 -2
- package/dist/billing/plan-limit-notice.js.map +1 -1
- package/dist/chart.js.map +1 -1
- package/dist/components/amount-input.d.ts +0 -3
- package/dist/components/amount-input.js +2 -2
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/calculator.d.ts +1 -4
- package/dist/components/calculator.js +1 -3
- package/dist/components/calculator.js.map +1 -1
- package/dist/components/chart-zoom.d.ts +0 -37
- package/dist/components/chart-zoom.js +1 -28
- package/dist/components/chart-zoom.js.map +1 -1
- package/dist/components/chip-input.d.ts +0 -4
- package/dist/components/chip-input.js +1 -5
- package/dist/components/chip-input.js.map +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/copy-button.d.ts +5 -1
- package/dist/components/copy-button.js.map +1 -1
- package/dist/components/currency-option-list.d.ts +3 -8
- package/dist/components/currency-option-list.js +1 -29
- package/dist/components/currency-option-list.js.map +1 -1
- package/dist/components/danger-confirm.d.ts +3 -3
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-filter-popover.d.ts +1 -1
- package/dist/components/data-table-filter-popover.js +1 -1
- package/dist/components/data-table-filter-popover.js.map +1 -1
- package/dist/components/data-table-labels.d.ts +1 -42
- package/dist/components/data-table-labels.js +2 -31
- package/dist/components/data-table-labels.js.map +1 -1
- package/dist/components/data-table-shared.d.ts +17 -1
- package/dist/components/data-table-shared.js +22 -0
- package/dist/components/data-table-shared.js.map +1 -1
- package/dist/components/data-table.d.ts +12 -2
- package/dist/components/data-table.js +18 -14
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/dialog-frame.d.ts +3 -1
- package/dist/components/dialog-frame.js.map +1 -1
- package/dist/components/dropdown.d.ts +18 -15
- package/dist/components/dropdown.js +11 -3
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/entity-combobox.d.ts +1 -1
- package/dist/components/entity-combobox.js.map +1 -1
- package/dist/components/field-base.d.ts +0 -5
- package/dist/components/field-base.js +0 -5
- package/dist/components/field-base.js.map +1 -1
- package/dist/components/field-parts.d.ts +3 -11
- package/dist/components/field-parts.js +1 -9
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-strip.d.ts +8 -23
- package/dist/components/field-strip.js +24 -22
- package/dist/components/field-strip.js.map +1 -1
- package/dist/components/field-sync.d.ts +0 -4
- package/dist/components/field-sync.js +0 -4
- package/dist/components/field-sync.js.map +1 -1
- package/dist/components/field.d.ts +4 -4
- package/dist/components/field.js.map +1 -1
- package/dist/components/full-bleed-dialog.js +2 -2
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/hover-menu.d.ts +6 -13
- package/dist/components/hover-menu.js +3 -3
- package/dist/components/hover-menu.js.map +1 -1
- package/dist/components/inline-entity-combobox.d.ts +1 -1
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/modal.d.ts +9 -1
- package/dist/components/modal.js +7 -4
- package/dist/components/modal.js.map +1 -1
- package/dist/components/multi-select.d.ts +5 -16
- package/dist/components/multi-select.js +5 -10
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/number-input.d.ts +0 -3
- package/dist/components/number-input.js +2 -4
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/popover.js +2 -2
- package/dist/components/popover.js.map +1 -1
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/server-wake.d.ts +0 -6
- package/dist/components/server-wake.js.map +1 -1
- package/dist/components/settings-fields.d.ts +4 -2
- package/dist/components/settings-fields.js.map +1 -1
- package/dist/components/stat-tile.d.ts +8 -2
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/swipeable-row.d.ts +2 -17
- package/dist/components/swipeable-row.js +11 -16
- package/dist/components/swipeable-row.js.map +1 -1
- package/dist/components/tooltip.d.ts +9 -1
- package/dist/components/tooltip.js +20 -5
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/translation-review.d.ts +10 -2
- package/dist/components/translation-review.js +11 -3
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/use-table-state.d.ts +31 -3
- package/dist/components/use-table-state.js +53 -8
- package/dist/components/use-table-state.js.map +1 -1
- package/dist/components/user-avatar.d.ts +2 -2
- package/dist/components/user-avatar.js.map +1 -1
- package/dist/components/wizard-stepper.d.ts +1 -4
- package/dist/components/wizard-stepper.js +2 -3
- package/dist/components/wizard-stepper.js.map +1 -1
- package/dist/currencies.d.ts +23 -0
- package/dist/currencies.js +38 -0
- package/dist/currencies.js.map +1 -0
- package/dist/demo/demo-banner.d.ts +7 -2
- package/dist/demo/demo-banner.js.map +1 -1
- package/dist/eslint/index.d.ts +83 -0
- package/dist/eslint/index.js +69 -0
- package/dist/eslint/index.js.map +1 -0
- package/dist/eslint/role-utilities.d.ts +48 -0
- package/dist/eslint/role-utilities.generated.d.ts +2 -0
- package/dist/eslint/role-utilities.generated.js +143 -0
- package/dist/eslint/role-utilities.generated.js.map +1 -0
- package/dist/eslint/role-utilities.js +43 -0
- package/dist/eslint/role-utilities.js.map +1 -0
- package/dist/feedback/feedback-menu.d.ts +2 -2
- package/dist/feedback/feedback-menu.js.map +1 -1
- package/dist/feedback/feedback-thread.d.ts +3 -8
- package/dist/feedback/feedback-thread.js +0 -2
- package/dist/feedback/feedback-thread.js.map +1 -1
- package/dist/hooks/use-dismiss.d.ts +16 -3
- package/dist/hooks/use-dismiss.js +14 -2
- package/dist/hooks/use-dismiss.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +14 -4
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +1 -1
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/fr.js +3 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/it.js +3 -2
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/refs.d.ts +13 -0
- package/dist/lib/refs.js +15 -0
- package/dist/lib/refs.js.map +1 -0
- package/dist/rhf/fields.d.ts +10 -10
- package/dist/rhf/fields.js.map +1 -1
- package/dist/rhf/form-core.d.ts +5 -4
- package/dist/rhf/form-core.js.map +1 -1
- package/dist/rhf/form.d.ts +7 -36
- package/dist/rhf/form.js +1 -16
- package/dist/rhf/form.js.map +1 -1
- package/dist/rhf/line-items.d.ts +1 -1
- package/dist/rhf/line-items.js.map +1 -1
- package/dist/rhf/use-rhf-wizard-step.js.map +1 -1
- package/dist/rhf.js.map +1 -1
- package/dist/shell/option-switcher-menu.d.ts +5 -17
- package/dist/shell/option-switcher-menu.js +1 -3
- package/dist/shell/option-switcher-menu.js.map +1 -1
- package/dist/shell/role-switcher.d.ts +1 -4
- package/dist/shell/role-switcher.js +2 -3
- package/dist/shell/role-switcher.js.map +1 -1
- package/dist/shell/topbar-action-menu.d.ts +7 -19
- package/dist/shell/topbar-action-menu.js +1 -3
- package/dist/shell/topbar-action-menu.js.map +1 -1
- package/dist/shell/topbar-controls.d.ts +3 -12
- package/dist/shell/topbar-controls.js +6 -9
- package/dist/shell/topbar-controls.js.map +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +2 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/viewport.d.ts +25 -2
- package/dist/testing/viewport.js +61 -10
- package/dist/testing/viewport.js.map +1 -1
- package/dist/theme/palette-presets.d.ts +0 -7
- package/dist/theme/palette-presets.js +0 -279
- package/dist/theme/palette-presets.js.map +1 -1
- package/dist/wizard/types.d.ts +0 -5
- package/dist/wizard/types.js +1 -5
- package/dist/wizard/types.js.map +1 -1
- package/package.json +9 -1
- package/src/billing/billing-banner.tsx +5 -2
- package/src/billing/plan-limit-notice.tsx +5 -2
- package/src/chart.ts +5 -3
- package/src/components/amount-input.tsx +2 -6
- package/src/components/calculator.tsx +2 -7
- package/src/components/chart-zoom.tsx +4 -47
- package/src/components/chip-input.tsx +0 -7
- package/src/components/combobox.tsx +1 -1
- package/src/components/copy-button.tsx +5 -1
- package/src/components/currency-option-list.tsx +8 -42
- package/src/components/danger-confirm.tsx +3 -3
- package/src/components/data-table-filter-popover.tsx +2 -1
- package/src/components/data-table-labels.ts +2 -84
- package/src/components/data-table-shared.tsx +55 -2
- package/src/components/data-table.tsx +29 -17
- package/src/components/dialog-frame.tsx +3 -1
- package/src/components/dropdown.tsx +42 -18
- package/src/components/entity-combobox.tsx +1 -1
- package/src/components/field-base.tsx +0 -11
- package/src/components/field-parts.tsx +5 -19
- package/src/components/field-strip.tsx +9 -25
- package/src/components/field-sync.tsx +0 -7
- package/src/components/field.tsx +4 -4
- package/src/components/full-bleed-dialog.tsx +4 -3
- package/src/components/hover-menu.tsx +12 -16
- package/src/components/inline-entity-combobox.tsx +1 -1
- package/src/components/modal.tsx +20 -4
- package/src/components/multi-select.tsx +13 -30
- package/src/components/number-input.tsx +3 -8
- package/src/components/popover.tsx +5 -3
- package/src/components/series-chart.tsx +1 -1
- package/src/components/server-wake.tsx +0 -6
- package/src/components/settings-fields.tsx +4 -2
- package/src/components/stat-tile.tsx +8 -2
- package/src/components/swipeable-row.tsx +15 -37
- package/src/components/tooltip.tsx +37 -6
- package/src/components/translation-review.tsx +25 -7
- package/src/components/use-table-state.ts +91 -10
- package/src/components/user-avatar.tsx +2 -2
- package/src/components/wizard-stepper.tsx +2 -6
- package/src/currencies.ts +70 -0
- package/src/demo/demo-banner.tsx +7 -2
- package/src/eslint/index.ts +161 -0
- package/src/eslint/role-utilities.generated.ts +146 -0
- package/src/eslint/role-utilities.ts +99 -0
- package/src/feedback/feedback-menu.tsx +2 -2
- package/src/feedback/feedback-thread.tsx +3 -8
- package/src/hooks/use-dismiss.ts +39 -4
- package/src/i18n/kit-labels.tsx +15 -5
- package/src/i18n/locales/fr.ts +3 -2
- package/src/i18n/locales/it.ts +3 -2
- package/src/index.ts +3 -1
- package/src/lib/refs.ts +22 -0
- package/src/rhf/fields.tsx +10 -10
- package/src/rhf/form-core.tsx +5 -4
- package/src/rhf/form.tsx +7 -43
- package/src/rhf/line-items.tsx +1 -1
- package/src/rhf/use-rhf-wizard-step.ts +4 -4
- package/src/rhf.ts +3 -2
- package/src/shell/option-switcher-menu.tsx +5 -22
- package/src/shell/role-switcher.tsx +2 -6
- package/src/shell/topbar-action-menu.tsx +7 -24
- package/src/shell/topbar-controls.tsx +6 -18
- package/src/testing/index.ts +3 -1
- package/src/testing/viewport.ts +125 -19
- package/src/theme/palette-presets.ts +7 -293
- package/src/wizard/types.ts +0 -8
package/README.md
CHANGED
|
@@ -94,6 +94,12 @@ currency picker and the language menu. It was a 5.6 MB hard dependency through 0
|
|
|
94
94
|
installed into every consumer and imported by nothing — so it may still be in your tree
|
|
95
95
|
transitively after upgrading. Depend on it explicitly if you render any of the three.
|
|
96
96
|
|
|
97
|
+
**Shipping only the flags you render.** `@eifi1/ui-kit/currencies` (0.34.1) is the
|
|
98
|
+
currency list as plain data — `CURRENCIES`, and `CURRENCY_COUNTRIES` (code → the lowercase
|
|
99
|
+
country flag-icons names the flag by: `CHF` → `"ch"`, `EUR` → `"eu"`). It imports nothing,
|
|
100
|
+
so a build script or a Vite plugin can import it in Node to generate a flag subset. Read
|
|
101
|
+
it there, never out of a file under `dist/`: those move between versions.
|
|
102
|
+
|
|
97
103
|
## Wiring
|
|
98
104
|
|
|
99
105
|
### 1. Vite — dedupe shared singletons
|
|
@@ -226,8 +232,10 @@ name with the property's own prefix dropped (`--bg-surface` → `bg-surface`,
|
|
|
226
232
|
The names are **property-scoped**: a text role makes a `text-*` utility and nothing else,
|
|
227
233
|
so `bg-muted` does not exist and a role cannot land on the wrong property by accident. An
|
|
228
234
|
app's own `--color-*` names (shadcn-style) do not collide with them. Keep `[var(--…)]` for a
|
|
229
|
-
role with no utility: the chart colours
|
|
230
|
-
|
|
235
|
+
role with no utility: the chart colours and `--status-*`. The ring offsets
|
|
236
|
+
(`ring-offset-surface`, `ring-offset-page`) and the money colours (`text-money-income`,
|
|
237
|
+
`bg-money-expense` …, the table below) are utilities since 0.34 and take variants, unlike
|
|
238
|
+
the plain money classes further down. The kit's own
|
|
231
239
|
markup follows this rule with no exceptions: `check:tokens` allows no `[var(--role)]` where
|
|
232
240
|
a utility exists.
|
|
233
241
|
|
|
@@ -329,6 +337,35 @@ Theme values: `text-micro` (font size 0.625rem), `text-caption` (font size 0.687
|
|
|
329
337
|
|
|
330
338
|
<!-- END GENERATED: styling -->
|
|
331
339
|
|
|
340
|
+
### Lint: the role utilities in an app
|
|
341
|
+
|
|
342
|
+
`@eifi1/ui-kit/eslint` (0.35) is `check:tokens`' role rule for an app's own markup: an ESLint
|
|
343
|
+
flat-config plugin whose `role-utilities` rule reports a `[var(--role)]` class wherever that
|
|
344
|
+
property has a utility for the role, and names it. It reads every string literal and
|
|
345
|
+
template-literal part, so a JSX `className`, a `cn()` / `clsx()` argument and a class constant
|
|
346
|
+
alike. Where one utility fits, `eslint --fix` writes it and keeps the variants and the opacity:
|
|
347
|
+
`hover:text-[var(--text-muted)]/70` → `hover:text-muted/70`. A token with no utility on that
|
|
348
|
+
property is left alone (`text-[var(--chart-1)]`, `--status-*`, `bg-[var(--border)]` as a
|
|
349
|
+
divider), and so are comments. The rule reads the table above, so a role that gains a utility is
|
|
350
|
+
flagged from the release that adds it.
|
|
351
|
+
|
|
352
|
+
```js
|
|
353
|
+
// eslint.config.js
|
|
354
|
+
import uiKit from "@eifi1/ui-kit/eslint";
|
|
355
|
+
|
|
356
|
+
export default defineConfig([ // or tseslint.config(…): either takes it
|
|
357
|
+
// … the app's own entries, which say which files are linted …
|
|
358
|
+
uiKit.configs.recommended,
|
|
359
|
+
]);
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
`configs.recommended` registers the plugin as `@eifi1/ui-kit` and turns
|
|
363
|
+
`@eifi1/ui-kit/role-utilities` on as an error for every linted file except tests
|
|
364
|
+
(`**/__tests__/**`, `*.test.*`, `*.spec.*`), which may name an old class to assert it is gone.
|
|
365
|
+
To scope it yourself, register the plugin and set the rule:
|
|
366
|
+
`{ files: ["src/**/*.tsx"], plugins: { "@eifi1/ui-kit": uiKit }, rules: { "@eifi1/ui-kit/role-utilities": "error" } }`.
|
|
367
|
+
It runs on ESLint 9 and 10 and imports no package of its own.
|
|
368
|
+
|
|
332
369
|
### Text size and More contrast
|
|
333
370
|
|
|
334
371
|
ONE scale on `<html>`: `data-text-size="normal" | "large" | "xlarge"` is 100 / 125 / 150 %
|
|
@@ -505,25 +542,27 @@ columns, strings and permissions (see the note at the top of `src/feedback/feedb
|
|
|
505
542
|
|
|
506
543
|
<!-- BEGIN GENERATED: exports — node scripts/gen-export-inventory.mjs -->
|
|
507
544
|
|
|
508
|
-
**
|
|
545
|
+
**1878 names from 302 modules** — 868 values and 1010 types. _Italic_ is a type-only export.
|
|
509
546
|
|
|
510
547
|
Generated from `dist/index.d.ts` by `node scripts/gen-export-inventory.mjs`; the count
|
|
511
548
|
is pinned by `src/__tests__/public-surface.test.ts`. Do not edit between the markers.
|
|
512
549
|
|
|
513
550
|
| Entry point | Names |
|
|
514
551
|
|---|---|
|
|
515
|
-
| `@eifi1/ui-kit` |
|
|
516
|
-
| `@eifi1/ui-kit/chart` |
|
|
552
|
+
| `@eifi1/ui-kit` | 1878 |
|
|
553
|
+
| `@eifi1/ui-kit/chart` | 92 |
|
|
517
554
|
| `@eifi1/ui-kit/shell` | 77 |
|
|
518
|
-
| `@eifi1/ui-kit/data-table` |
|
|
519
|
-
| `@eifi1/ui-kit/wizard` |
|
|
555
|
+
| `@eifi1/ui-kit/data-table` | 51 |
|
|
556
|
+
| `@eifi1/ui-kit/wizard` | 24 |
|
|
520
557
|
| `@eifi1/ui-kit/tour` | 7 |
|
|
521
|
-
| `@eifi1/ui-kit/feedback` |
|
|
558
|
+
| `@eifi1/ui-kit/feedback` | 164 |
|
|
522
559
|
| `@eifi1/ui-kit/search` | 23 |
|
|
523
560
|
| `@eifi1/ui-kit/dates` | 22 |
|
|
524
561
|
| `@eifi1/ui-kit/table-text` | 14 |
|
|
525
|
-
| `@eifi1/ui-kit/
|
|
526
|
-
| `@eifi1/ui-kit/
|
|
562
|
+
| `@eifi1/ui-kit/currencies` | 3 |
|
|
563
|
+
| `@eifi1/ui-kit/eslint` | 1 |
|
|
564
|
+
| `@eifi1/ui-kit/testing` | 11 |
|
|
565
|
+
| `@eifi1/ui-kit/rhf` | 48 |
|
|
527
566
|
|
|
528
567
|
Everything below is reachable from the main `@eifi1/ui-kit` barrel. The subpaths are a
|
|
529
568
|
re-slicing of it, never a second API.
|
|
@@ -584,7 +623,7 @@ re-slicing of it, never a second API.
|
|
|
584
623
|
|---|---|
|
|
585
624
|
| `theme/color` | `contrast`, `deltaE`, `hexToOklch`, `luminance`, `oklchToHex`, `oklchToRgb`, `parseHex`, `rgbToOklch`, `simulateCvd`, `solveLightness`, `toHex`, _`CvdType`_, _`Oklch`_, _`Rgb`_ |
|
|
586
625
|
| `theme/palette-derive` | `auditChartRamp`, `auditPalette`, `deriveChartRamp`, `derivePalette`, `describe`, _`AnchorRole`_, _`ChartRampReport`_, _`ContrastCheck`_, _`ContrastReport`_, _`DerivedPalette`_, _`DeriveOptions`_, _`PaletteAnchors`_, _`SemanticTokens`_ |
|
|
587
|
-
| `theme/palette-presets` | `
|
|
626
|
+
| `theme/palette-presets` | `applyTokenSet`, `DEFAULT_PRESET`, `DERIVED_PRESETS`, `IMPRINT_PRESET`, `PALETTES`, `presetById`, _`PalettePreset`_, _`TokenSet`_ |
|
|
588
627
|
| `theme/theme-store` | `applyPersistedTheme`, `createThemeStore`, _`ThemeMode`_, _`ThemePreference`_, _`ThemeState`_, _`ThemeStore`_ |
|
|
589
628
|
| `theme/palette-store` | `applyPersistedPalette`, `createPaletteStore`, _`PaletteStore`_ |
|
|
590
629
|
| `theme/text-size` | `applyPersistedTextSize`, `applyTextSize`, `createTextSizeStore`, `isTextSize`, `readPersistedTextSize`, `readTextSize`, `resolveTextSize`, `TEXT_SCALE`, `TEXT_SIZE_INLINE_SCRIPT`, `TEXT_SIZES`, `useTextSize`, _`ApplyTextSizeOptions`_, _`PersistedAppearanceOptions`_, _`PersistedTextSize`_, _`TextSize`_, _`TextSizeInfo`_, _`TextSizeState`_, _`TextSizeStore`_ |
|
|
@@ -608,7 +647,7 @@ re-slicing of it, never a second API.
|
|
|
608
647
|
| `components/button` | `Button`, _`ButtonLinkProps`_, _`ButtonProps`_ |
|
|
609
648
|
| `components/button-look` | `buttonClasses`, `TOUCH_TARGET_LARGE`, _`ButtonClassesOptions`_, _`ButtonSize`_, _`ButtonTone`_, _`ButtonVariant`_ |
|
|
610
649
|
| `components/icon-button` | `IconButton`, _`IconButtonGlyphSize`_, _`IconButtonLinkProps`_, _`IconButtonProps`_, _`IconButtonSize`_, _`IconButtonTone`_, _`IconButtonToneColor`_, _`IconButtonVariant`_ |
|
|
611
|
-
| `components/field-base` | `DEFAULT_CHARACTER_COUNT_LABELS`, `DEFAULT_PASSWORD_REVEAL_LABELS`, `FIELD_BASE`, `FIELD_DISPLAY`, `FIELD_FLOATING_PAD`, `FIELD_INVALID`, `FIELD_TOUCH_TEXT`, `FIELD_TRIGGER`, `FIELD_WRITABLE_LOOK`, `FieldChevron`, `FLOATING_INPUT_CLASS`, `FLOATING_LABEL_CLASS`, `FloatingField`, `Label`,
|
|
650
|
+
| `components/field-base` | `DEFAULT_CHARACTER_COUNT_LABELS`, `DEFAULT_PASSWORD_REVEAL_LABELS`, `FIELD_BASE`, `FIELD_DISPLAY`, `FIELD_FLOATING_PAD`, `FIELD_INVALID`, `FIELD_TOUCH_TEXT`, `FIELD_TRIGGER`, `FIELD_WRITABLE_LOOK`, `FieldChevron`, `FLOATING_INPUT_CLASS`, `FLOATING_LABEL_CLASS`, `FloatingField`, `Label`, _`CharacterCountLabels`_, _`FieldChevronProps`_, _`FloatingFieldProps`_, _`LabelProps`_, _`PasswordRevealLabels`_ |
|
|
612
651
|
| `components/input` | `Input`, _`InputProps`_ |
|
|
613
652
|
| `components/select` | `Select`, _`SelectProps`_ |
|
|
614
653
|
| `components/textarea` | `Textarea`, _`TextareaProps`_ |
|
|
@@ -638,7 +677,7 @@ re-slicing of it, never a second API.
|
|
|
638
677
|
| `components/tooltip` | `placeTooltip`, `Tooltip`, _`TooltipPlacement`_, _`TooltipProps`_, _`TooltipSide`_, _`TooltipSize`_, _`TooltipTap`_, _`TooltipViewport`_ |
|
|
639
678
|
| `components/user-avatar` | `avatarInitials`, `UserAvatar`, _`UserAvatarBadge`_, _`UserAvatarProps`_ |
|
|
640
679
|
| `components/settings-fields` | `ContrastSetting`, `LanguageSetting`, `TextSizeSetting`, `ThemeSetting`, _`ContrastSettingProps`_, _`LanguageSettingProps`_, _`TextSizeSettingProps`_, _`ThemeSettingProps`_, _`ThemeSettingSelectProps`_, _`ThemeSettingToggleProps`_ |
|
|
641
|
-
| `components/field-sync` | `DEFAULT_FIELD_SYNC_LABELS`, `FIELD_SYNC_FRAME`, `FIELD_SYNC_SAVED_MS`, `FieldSyncIndicator`, `FieldSyncRow`, `
|
|
680
|
+
| `components/field-sync` | `DEFAULT_FIELD_SYNC_LABELS`, `FIELD_SYNC_FRAME`, `FIELD_SYNC_SAVED_MS`, `FieldSyncIndicator`, `FieldSyncRow`, `useFieldSync`, _`FieldSyncIndicatorProps`_, _`FieldSyncLabels`_, _`FieldSyncRowProps`_, _`FieldSyncState`_, _`UseFieldSyncOptions`_, _`UseFieldSyncReturn`_ |
|
|
642
681
|
| `components/month-picker` | `DEFAULT_MONTH_PICKER_LABELS`, `MonthPicker`, _`MonthPickerLabels`_, _`MonthPickerProps`_ |
|
|
643
682
|
| `components/checkbox` | `Checkbox`, _`CheckboxProps`_ |
|
|
644
683
|
| `components/switch` | `Switch`, _`SwitchProps`_, _`SwitchSize`_ |
|
|
@@ -667,7 +706,6 @@ re-slicing of it, never a second API.
|
|
|
667
706
|
| `components/treemap` | `fitLabel`, `Treemap`, `TreemapCell`, _`TreemapCellProps`_, _`TreemapNode`_, _`TreemapProps`_ |
|
|
668
707
|
| `components/series-chart` | `resolveTooltipPlacement`, `SeriesChart`, `seriesLegendEntries`, `StaticSeriesChart`, _`SeriesChartAxis`_, _`SeriesChartHit`_, _`SeriesChartMarker`_, _`SeriesChartPoint`_, _`SeriesChartProps`_, _`SeriesChartReference`_, _`SeriesChartRow`_, _`SeriesChartSeries`_, _`SeriesChartSpan`_, _`SeriesChartTickValues`_, _`SeriesChartTone`_, _`SeriesChartTooltip`_, _`SeriesChartTooltipPlacement`_, _`SeriesChartType`_, _`SeriesChartX`_, _`SeriesChartXTick`_, _`SeriesChartXValue`_, _`SeriesLegendAxes`_ |
|
|
669
708
|
| `components/chart-height` | _`ChartHeight`_ |
|
|
670
|
-
| `components/chart-zoom` | `axisExtent`, `DEFAULT_Y_AXIS`, `defaultZoomAxes`, `fitXToY`, `fitYToX`, `NO_ZOOM`, `selectionFromDrag`, `withChartZoom`, `ZOOM_MIN_DRAG`, `ZOOM_SQUARE_ENOUGH`, `zoomAfter`, `zoomAxesFor`, `zoomDomains` |
|
|
671
709
|
| `components/chart-zoom-core` | `SharedXZoom`, _`ZoomAxes`_, _`ZoomAxesSetting`_, _`ZoomBinding`_, _`ZoomDrag`_, _`ZoomFitSeries`_, _`ZoomFitSource`_, _`ZoomRow`_, _`ZoomSelection`_, _`ZoomState`_, _`ZoomTarget`_ |
|
|
672
710
|
| `components/toggle-legend` | `LegendColumn`, `LegendGroup`, `StaticLegend`, `STEP_DASH`, `STROKE_PATTERNS`, `strokeDash`, `toggleHidden`, `ToggleLegend`, _`LegendEntry`_, _`StaticLegendProps`_, _`ToggleLegendProps`_ |
|
|
673
711
|
| `components/facing-pair` | `FACING_SIDES`, `facingAxes`, `facingBand`, `facingHeadingPad`, _`FacingSide`_ |
|
|
@@ -679,7 +717,7 @@ re-slicing of it, never a second API.
|
|
|
679
717
|
| `components/toggle-group` | `ToggleGroup`, _`ToggleGroupBaseProps`_, _`ToggleGroupClearableProps`_, _`ToggleGroupProps`_, _`ToggleGroupRequiredProps`_, _`ToggleOption`_ |
|
|
680
718
|
| `components/nav-pills` | `NavPills`, _`NavPillItem`_, _`NavPillLinkProps`_, _`NavPillsCurrent`_, _`NavPillsProps`_ |
|
|
681
719
|
| `components/chip` | `Chip`, _`ChipHue`_, _`ChipLinkProps`_, _`ChipProps`_, _`ChipShape`_, _`ChipSize`_, _`ChipTone`_, _`ChipVariant`_ |
|
|
682
|
-
| `components/chip-input` | `ChipInput`, `DEFAULT_CHIP_INPUT_LABELS`,
|
|
720
|
+
| `components/chip-input` | `ChipInput`, `DEFAULT_CHIP_INPUT_LABELS`, _`ChipInputLabels`_, _`ChipInputProps`_ |
|
|
683
721
|
| `components/wizard-stepper` | `WizardStepper` |
|
|
684
722
|
| `components/hover-menu` | `HoverMenu`, _`HoverMenuProps`_ |
|
|
685
723
|
| `components/modal` | `Modal`, `ModalCloseContext`, `useBackdropClose`, _`ModalProps`_ |
|
|
@@ -732,9 +770,9 @@ re-slicing of it, never a second API.
|
|
|
732
770
|
| `components/country-select` | `CountrySelect`, `DEFAULT_COUNTRY_SELECT_LABELS`, _`CountrySelectLabels`_, _`CountrySelectProps`_ |
|
|
733
771
|
| `components/iban-input` | `DEFAULT_IBAN_INPUT_LABELS`, `IbanInput`, _`IbanInputLabels`_, _`IbanInputProps`_ |
|
|
734
772
|
| `components/phone-input` | `DEFAULT_PHONE_INPUT_LABELS`, `PhoneInput`, _`PhoneInputLabels`_, _`PhoneInputProps`_ |
|
|
735
|
-
| `components/field-strip` | `FieldStrip`, _`FieldStripIds`_, _`
|
|
773
|
+
| `components/field-strip` | `FieldStrip`, _`FieldStripIds`_, _`FieldStripProps`_ |
|
|
736
774
|
| `components/column-mapper` | `ColumnMapper`, `ColumnRoleTable`, `DEFAULT_COLUMN_MAPPER_LABELS`, _`ColumnMapperLabels`_, _`ColumnMapperProps`_, _`ColumnRoleTableBodyProps`_, _`ColumnRoleTableProps`_, _`ColumnRoleTableRowProps`_ |
|
|
737
|
-
| `components/data-table-labels` | `DEFAULT_DATA_TABLE_LABELS`,
|
|
775
|
+
| `components/data-table-labels` | `DEFAULT_DATA_TABLE_LABELS`, _`DataTableLabels`_ |
|
|
738
776
|
| `components/data-table-sort` | `decodeSorts`, `encodeSorts`, `nextSorts`, `normalizeSorts`, _`SortCycle`_, _`SortDir`_, _`SortState`_, _`SortStepOptions`_ |
|
|
739
777
|
| `components/data-table-filters` | `dateFilter`, `decodeFilterValue`, `decodeFilterValueOfType`, `defaultFilterState`, `encodeFilterValue`, `filterHref`, `isFilterActive`, `numberFilter`, `resolveFilter`, `rowMatches`, `selectFilter`, `textFilter`, _`ColumnFilter`_, _`FilterValue`_ |
|
|
740
778
|
| `components/data-table-pagination` | `PAGE_SIZE_OPTIONS`, `Pagination` |
|
|
@@ -801,7 +839,7 @@ re-slicing of it, never a second API.
|
|
|
801
839
|
| `feedback/feedback-attachment` | `DEFAULT_ATTACHMENT_ACCEPT`, `DEFAULT_FEEDBACK_ATTACHMENT_LABELS`, `DEFAULT_MAX_ATTACHMENT_BYTES`, `DEFAULT_MAX_ATTACHMENTS`, `FeedbackAttachmentField`, `pastedName`, _`FeedbackAttachmentError`_, _`FeedbackAttachmentErrorInfo`_, _`FeedbackAttachmentFieldLabels`_, _`FeedbackAttachmentFieldMultipleProps`_, _`FeedbackAttachmentFieldProps`_, _`FeedbackAttachmentFieldRefsProps`_, _`FeedbackAttachmentFieldSingleProps`_, _`FeedbackAttachmentRef`_, _`FeedbackAttachmentRefsError`_ |
|
|
802
840
|
| `feedback/feedback-dialog` | `DEFAULT_FEEDBACK_DIALOG_LABELS`, `FeedbackDialog`, _`FeedbackAttachmentLabels`_, _`FeedbackCategoryOption`_, _`FeedbackDialogLabels`_, _`FeedbackDialogMultipleProps`_, _`FeedbackDialogProps`_, _`FeedbackDialogSingleProps`_, _`FeedbackDialogTextLabels`_, _`FeedbackMultipleSubmission`_, _`FeedbackSubmission`_, _`FeedbackSubmitHint`_ |
|
|
803
841
|
| `feedback/feedback-inbox` | `FeedbackCategoryBadge`, `FeedbackDetail`, `FeedbackDetailSection`, `FeedbackNoteEditor`, `FeedbackProse`, `FeedbackStatusBadge`, `FeedbackStatusTransitions`, _`FeedbackNoteAttachment`_ |
|
|
804
|
-
| `feedback/feedback-thread` | `ChatComposer`, `DEFAULT_FEEDBACK_COMPOSER_LABELS`, `DEFAULT_FEEDBACK_THREAD_LABELS`, `
|
|
842
|
+
| `feedback/feedback-thread` | `ChatComposer`, `DEFAULT_FEEDBACK_COMPOSER_LABELS`, `DEFAULT_FEEDBACK_THREAD_LABELS`, `FeedbackThread`, _`ChatComposerHandle`_, _`ChatComposerLabels`_, _`ChatComposerProps`_, _`ChatComposerSlotContext`_, _`FeedbackComposerAttachment`_, _`FeedbackComposerHandle`_, _`FeedbackComposerLabels`_, _`FeedbackComposerProps`_, _`FeedbackComposerSlotContext`_, _`FeedbackThreadAttachment`_, _`FeedbackThreadEvent`_, _`FeedbackThreadItem`_, _`FeedbackThreadLabels`_, _`FeedbackThreadMessage`_, _`FeedbackThreadProps`_ |
|
|
805
843
|
| `feedback/feedback-record` | `appendRework`, `attachmentName`, `FEEDBACK_ATTACHMENT_ACCEPT`, `FEEDBACK_AUTHOR_EDITABLE_STATUSES`, `FEEDBACK_AWAITING_STATUSES`, `FEEDBACK_PICKABLE_CATEGORIES`, `FEEDBACK_REWORKABLE_STATUSES`, `feedbackAttachmentLine`, `isImageAttachment`, `replaceDescription`, `reworkCount`, `splitBodyAttachments`, `splitDescription`, _`FeedbackContext`_, _`FeedbackEnvironment`_, _`FeedbackRecord`_ |
|
|
806
844
|
| `feedback/feedback-labels` | `DEFAULT_FEEDBACK_CATEGORY_LABELS`, `DEFAULT_FEEDBACK_STATUS_LABELS`, `DEFAULT_FEEDBACK_TOAST_LABELS`, `useFeedbackCategoryLabels`, `useFeedbackStatusLabels`, `useFeedbackToastLabels`, _`FeedbackCategoryLabels`_, _`FeedbackStatusLabels`_, _`FeedbackToastLabels`_ |
|
|
807
845
|
| `feedback/feedback-status-undo` | `FEEDBACK_UNDO_DURATION`, `useFeedbackStatusUndo`, _`FeedbackStatusChange`_, _`FeedbackStatusMutate`_, _`FeedbackStatusPatch`_, _`FeedbackStatusRow`_, _`FeedbackStatusUndoOptions`_ |
|
|
@@ -819,7 +857,7 @@ re-slicing of it, never a second API.
|
|
|
819
857
|
|
|
820
858
|
| Module | Exports |
|
|
821
859
|
|---|---|
|
|
822
|
-
| `wizard/types` | `DEFAULT_WIZARD_LABELS`,
|
|
860
|
+
| `wizard/types` | `DEFAULT_WIZARD_LABELS`, _`FieldErrors`_, _`StepStatus`_, _`SummaryItem`_, _`SummarySection`_, _`UseWizardOptions`_, _`UseWizardReturn`_, _`ValidateResult`_, _`WizardLabels`_, _`WizardStepConfig`_, _`WizardUrlSync`_ |
|
|
823
861
|
| `wizard/use-wizard` | `useWizard` |
|
|
824
862
|
| `wizard/wizard-context` | `useOptionalWizardContext`, `useWizardContext`, `useWizardNextGate`, `useWizardStepValidate`, `WizardContextProvider`, _`WizardContextValue`_ |
|
|
825
863
|
| `wizard/validation` | `requiredFieldsValidator`, _`RequiredFieldSpec`_ |
|
|
@@ -915,6 +953,12 @@ re-slicing of it, never a second API.
|
|
|
915
953
|
| `demo/demo-banner` | `DemoBanner`, _`DemoBannerProps`_ |
|
|
916
954
|
| `demo/demo-ended` | `DemoEnded`, _`DemoEndedProps`_ |
|
|
917
955
|
|
|
956
|
+
### root
|
|
957
|
+
|
|
958
|
+
| Module | Exports |
|
|
959
|
+
|---|---|
|
|
960
|
+
| `currencies` | `CURRENCY_COUNTRIES` |
|
|
961
|
+
|
|
918
962
|
<!-- END GENERATED: exports -->
|
|
919
963
|
|
|
920
964
|
## Forms / refs
|
|
@@ -926,36 +970,36 @@ element that takes focus: the `<input>` of `Input`, `NumberField`, `AmountInput`
|
|
|
926
970
|
on its checked option. So they work directly with react-hook-form:
|
|
927
971
|
`<Input {...field} />` (from `Controller`/`register`) attaches RHF's ref, giving
|
|
928
972
|
focus-and-scroll-to-error for free. A component that spreads its props onto an element
|
|
929
|
-
(`Card`, `EmptyState`, `PageHeader`, …) takes that element's `ref` too. For
|
|
930
|
-
|
|
973
|
+
(`Card`, `EmptyState`, `PageHeader`, …) takes that element's `ref` too. For fields bound
|
|
974
|
+
to a react-hook-form form in one line each, see `@eifi1/ui-kit/rhf` below.
|
|
931
975
|
|
|
932
976
|
### react-hook-form — `@eifi1/ui-kit/rhf` (optional)
|
|
933
977
|
|
|
934
|
-
|
|
935
|
-
`
|
|
936
|
-
|
|
978
|
+
The react-hook-form adapter: `Form`, the bound fields (`RhfTextField`, `RhfNumberField`,
|
|
979
|
+
`RhfMoneyField`, `RhfDateField`, `RhfSelect`, `RhfCombobox`, `RhfCheckbox`, …) and
|
|
980
|
+
`RhfField` for a control of your own, and the only entry that needs `react-hook-form` (an
|
|
981
|
+
**optional** peer, `^7.55.0`). The main barrel does not import it, so apps without a form
|
|
982
|
+
library install nothing.
|
|
937
983
|
|
|
938
984
|
```tsx
|
|
939
|
-
import { Form,
|
|
985
|
+
import { Form, RhfField, RhfNumberField, RhfTextField } from "@eifi1/ui-kit/rhf";
|
|
940
986
|
|
|
941
987
|
<Form {...form}>
|
|
942
|
-
<
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
<NumberField value={field.value} onCommit={field.onChange} />
|
|
947
|
-
</FormControl>
|
|
948
|
-
<FormMessage />
|
|
949
|
-
</FormItem>
|
|
988
|
+
<RhfTextField name="title" label="Title" required rules={{ required: "Give it a title." }} />
|
|
989
|
+
<RhfNumberField name="amount" label="Amount" unit="EUR" hint="Net of VAT." />
|
|
990
|
+
<RhfField name="street" label="Street" render={({ field, invalid }) => (
|
|
991
|
+
<AddressAutocomplete {...field} invalid={invalid} />
|
|
950
992
|
)} />
|
|
951
993
|
</Form>
|
|
952
994
|
```
|
|
953
995
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
996
|
+
Each bound field is a label, the control, a hint and the form's message wired to each
|
|
997
|
+
other: the control's `aria-describedby` names only the hint and message actually rendered
|
|
998
|
+
(merged after the control's own), `aria-invalid` and `invalid` come from the field state,
|
|
999
|
+
and `field.ref` reaches the focusable element, so a failed submit focuses the first field
|
|
1000
|
+
in error. The message is the form's own; the kit adds no text. The shadcn scaffold the
|
|
1001
|
+
adapter started as (`FormField`, `FormItem`, `FormLabel`, `FormControl`,
|
|
1002
|
+
`FormDescription`, `FormMessage`, `useFormField`) left the public surface in 0.35.
|
|
959
1003
|
|
|
960
1004
|
### Pasted and imported tables — `@eifi1/ui-kit/table-text`
|
|
961
1005
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ComponentPropsWithRef } from "react";
|
|
2
2
|
import type { LabelOverride } from "../i18n/kit-labels.js";
|
|
3
3
|
import type { AlertSize, AlertTone } from "../components/alert-banner.js";
|
|
4
4
|
import type { BillingLabels } from "./billing-labels.js";
|
|
@@ -15,7 +15,10 @@ import type { BillingLabels } from "./billing-labels.js";
|
|
|
15
15
|
* - `processing` — back from checkout before the webhook landed (§12.21).
|
|
16
16
|
*/
|
|
17
17
|
export type BillingBannerKind = "trial-ending" | "grant-ending" | "payment-failed" | "plan-ended" | "guest" | "processing";
|
|
18
|
-
|
|
18
|
+
/** A `div`'s props, `ref` included since 0.35 (round 0.35 R4, the follow-up to API-2): they
|
|
19
|
+
* go on to the {@link AlertBanner}, so the ref is the banner's `<div>` — with an × too,
|
|
20
|
+
* since the banner has no `href` or `onClick` that would make its row a link or a button. */
|
|
21
|
+
interface BillingBannerBaseProps extends Omit<ComponentPropsWithRef<"div">, "children" | "onClick"> {
|
|
19
22
|
/**
|
|
20
23
|
* Over the kind's tone: `trial-ending` and `grant-ending` are `info` until the last
|
|
21
24
|
* three days and `warning` in them; `payment-failed` is `danger` (money did not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/billing/billing-banner.tsx"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../../src/billing/billing-banner.tsx"],"sourcesContent":["import type { ComponentPropsWithRef, ReactNode } from \"react\";\nimport { CreditCard, Hourglass, PencilOff } from \"lucide-react\";\n\nimport type { LabelOverride } from \"../i18n/kit-labels\";\nimport { AlertBanner } from \"../components/alert-banner\";\nimport type { AlertSize, AlertTone } from \"../components/alert-banner\";\nimport { Button } from \"../components/button\";\nimport { Spinner } from \"../components/spinner\";\nimport { useBillingLabels } from \"./billing-labels\";\nimport type { BillingLabels } from \"./billing-labels\";\n\n/**\n * The billing banners (docs/billing-harmonization.md §3.3, §7, §12.6, §12.21):\n *\n * - `trial-ending` — from 7 days before `trial_ends_at` (§3.3);\n * - `grant-ending` — from 7 days before `comped_until`: a beta user's 12 months, an\n * operator's grant;\n * - `payment-failed` — from the first failed payment (`past_due`), while the provider\n * retries;\n * - `plan-ended` — out of good standing: read-only, never locked (§2.3);\n * - `guest` — a guest in someone else's read-only item (§12.6);\n * - `processing` — back from checkout before the webhook landed (§12.21).\n */\nexport type BillingBannerKind =\n | \"trial-ending\"\n | \"grant-ending\"\n | \"payment-failed\"\n | \"plan-ended\"\n | \"guest\"\n | \"processing\";\n\n/** A `div`'s props, `ref` included since 0.35 (round 0.35 R4, the follow-up to API-2): they\n * go on to the {@link AlertBanner}, so the ref is the banner's `<div>` — with an × too,\n * since the banner has no `href` or `onClick` that would make its row a link or a button. */\ninterface BillingBannerBaseProps extends Omit<ComponentPropsWithRef<\"div\">, \"children\" | \"onClick\"> {\n /**\n * Over the kind's tone: `trial-ending` and `grant-ending` are `info` until the last\n * three days and `warning` in them; `payment-failed` is `danger` (money did not\n * arrive — kastlan's past-due strip was red); `plan-ended` is `warning`, a state with\n * everything still there rather than an error; `guest` and `processing` are `info`.\n */\n tone?: AlertTone;\n /** `strip` (default): the band under the top bar, on every page. `box`: the same\n * message on the subscription page itself. */\n variant?: \"strip\" | \"box\";\n /** Default `sm` for a strip (the demo's banner), `md` for a box. */\n size?: AlertSize;\n /**\n * Where the action goes — the subscription page, say. The app's action, as an `href`\n * or as {@link onAction}; without either there is no button. Never a write-locked\n * commit: billing itself always works (§3.3).\n */\n actionHref?: string;\n /** What the action does — the app's portal call (`POST /billing/portal`, then off to\n * its `url`): for `payment-failed` with `{target: \"payment_method\"}`, the portal's\n * page for the card (§14.5); for `processing`, `useCheckoutProcessing`'s\n * `checkAgain`. The kit sends no request. */\n onAction?: () => void;\n /**\n * Over the kind's action words: \"Choose a plan\" (trial, grant, plan ended), \"Update\n * payment method\" (payment failed), \"Check again\" (processing). The guest banner has\n * none of its own: an action there needs this.\n */\n actionLabel?: string;\n /** The action is under way: the button's spinner, no second press. */\n actionPending?: boolean;\n /** An × that calls this; the app removes the banner and remembers that it did. */\n onDismiss?: () => void;\n dismissLabel?: string;\n /** Prop > `<UiKitProvider labels={{ billing }}>` > English. */\n labels?: LabelOverride<BillingLabels>;\n}\n\nexport type BillingBannerProps = BillingBannerBaseProps &\n (\n | {\n kind: \"trial-ending\" | \"grant-ending\";\n /** Calendar days left — `billingDaysLeft(trial_ends_at)`. 0 is today. */\n daysLeft: number;\n item?: never;\n }\n | {\n kind: \"guest\";\n /** The item's own name (\"Household 2026\"), or nothing. NEVER the owner's status:\n * the banner says \"for now\" and nothing more (§12.6). */\n item?: string;\n daysLeft?: never;\n }\n | {\n kind: \"payment-failed\" | \"plan-ended\" | \"processing\";\n daysLeft?: never;\n item?: never;\n }\n );\n\n/** The last days, in which an ending trial or grant turns from news into a warning. */\nconst LAST_DAYS = 3;\n\nfunction defaultTone(kind: BillingBannerKind, daysLeft: number | undefined): AlertTone {\n switch (kind) {\n case \"trial-ending\":\n case \"grant-ending\":\n return (daysLeft ?? 0) > LAST_DAYS ? \"info\" : \"warning\";\n case \"payment-failed\":\n return \"danger\";\n case \"plan-ended\":\n return \"warning\";\n default:\n return \"info\";\n }\n}\n\n/**\n * One of the billing banners, as a kit `AlertBanner` strip (§7): the kind's sentence, its\n * glyph and tone, and the app's action. Carries `data-billing-banner` with the kind.\n *\n * The app decides WHICH banner shows, from `GET /billing/overview` (and hides all of them\n * while billing is off, §4); the kit only says it. A guest's banner takes no status at\n * all — the type does not let one in — so the owner's payment state cannot leak into it\n * by a wrong prop (§12.6).\n *\n * `processing` is a live region (`role=\"status\"`): it appears when the person comes back\n * from checkout and goes when the overview catches up (§12.21), and a screen reader\n * should hear both. The others are page furniture, role-less as the strip is.\n */\nexport function BillingBanner(props: BillingBannerProps) {\n const {\n kind,\n daysLeft,\n item,\n tone,\n variant = \"strip\",\n size,\n actionHref,\n onAction,\n actionLabel,\n actionPending,\n onDismiss,\n dismissLabel,\n labels: labelsProp,\n role,\n ...rest\n } = props;\n const labels = useBillingLabels(labelsProp);\n const days = Math.max(0, Math.floor(daysLeft ?? 0));\n\n let text: string;\n let icon: ReactNode;\n let ownAction: string | undefined;\n switch (kind) {\n case \"trial-ending\":\n text = labels.trialEnding(days);\n icon = <Hourglass />;\n ownAction = labels.choosePlan;\n break;\n case \"grant-ending\":\n text = labels.grantEnding(days);\n icon = <Hourglass />;\n ownAction = labels.choosePlan;\n break;\n case \"payment-failed\":\n text = labels.paymentFailed;\n icon = <CreditCard />;\n ownAction = labels.updatePayment;\n break;\n case \"plan-ended\":\n text = labels.planEnded;\n icon = <PencilOff />;\n ownAction = labels.choosePlan;\n break;\n case \"guest\":\n text = labels.guestReadOnly(item);\n icon = <PencilOff />;\n ownAction = undefined;\n break;\n case \"processing\":\n text = labels.processing;\n icon = <Spinner label={null} />;\n ownAction = labels.checkAgain;\n break;\n }\n\n const words = actionLabel ?? ownAction;\n const action =\n words === undefined || (actionHref === undefined && onAction === undefined) ? undefined : actionHref !== undefined ? (\n <Button href={actionHref} variant=\"secondary\" size=\"sm\">\n {words}\n </Button>\n ) : (\n <Button type=\"button\" variant=\"secondary\" size=\"sm\" onClick={onAction} pending={actionPending}>\n {words}\n </Button>\n );\n\n return (\n <AlertBanner\n {...rest}\n role={role ?? (kind === \"processing\" ? \"status\" : undefined)}\n variant={variant}\n size={size ?? (variant === \"strip\" ? \"sm\" : \"md\")}\n tone={tone ?? defaultTone(kind, days)}\n icon={icon}\n action={action}\n onDismiss={onDismiss}\n dismissLabel={dismissLabel}\n data-billing-banner={kind}\n >\n {text}\n </AlertBanner>\n );\n}\n"],"mappings":";AAwJa;AAvJb,SAAS,YAAY,WAAW,iBAAiB;AAGjD,SAAS,mBAAmB;AAE5B,SAAS,cAAc;AACvB,SAAS,eAAe;AACxB,SAAS,wBAAwB;AAwFjC,MAAM,YAAY;AAElB,SAAS,YAAY,MAAyB,UAAyC;AACrF,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,YAAY,KAAK,YAAY,SAAS;AAAA,IAChD,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAeO,SAAS,cAAc,OAA2B;AACvD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,SAAS,iBAAiB,UAAU;AAC1C,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,CAAC,CAAC;AAElD,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,OAAO,YAAY,IAAI;AAC9B,aAAO,oBAAC,aAAU;AAClB,kBAAY,OAAO;AACnB;AAAA,IACF,KAAK;AACH,aAAO,OAAO,YAAY,IAAI;AAC9B,aAAO,oBAAC,aAAU;AAClB,kBAAY,OAAO;AACnB;AAAA,IACF,KAAK;AACH,aAAO,OAAO;AACd,aAAO,oBAAC,cAAW;AACnB,kBAAY,OAAO;AACnB;AAAA,IACF,KAAK;AACH,aAAO,OAAO;AACd,aAAO,oBAAC,aAAU;AAClB,kBAAY,OAAO;AACnB;AAAA,IACF,KAAK;AACH,aAAO,OAAO,cAAc,IAAI;AAChC,aAAO,oBAAC,aAAU;AAClB,kBAAY;AACZ;AAAA,IACF,KAAK;AACH,aAAO,OAAO;AACd,aAAO,oBAAC,WAAQ,OAAO,MAAM;AAC7B,kBAAY,OAAO;AACnB;AAAA,EACJ;AAEA,QAAM,QAAQ,eAAe;AAC7B,QAAM,SACJ,UAAU,UAAc,eAAe,UAAa,aAAa,SAAa,SAAY,eAAe,SACvG,oBAAC,UAAO,MAAM,YAAY,SAAQ,aAAY,MAAK,MAChD,iBACH,IAEA,oBAAC,UAAO,MAAK,UAAS,SAAQ,aAAY,MAAK,MAAK,SAAS,UAAU,SAAS,eAC7E,iBACH;AAGJ,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,MAAM,SAAS,SAAS,eAAe,WAAW;AAAA,MAClD;AAAA,MACA,MAAM,SAAS,YAAY,UAAU,OAAO;AAAA,MAC5C,MAAM,QAAQ,YAAY,MAAM,IAAI;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,uBAAqB;AAAA,MAEpB;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ComponentPropsWithRef } from "react";
|
|
2
2
|
import type { LabelOverride } from "../i18n/kit-labels.js";
|
|
3
3
|
import type { AlertTone } from "../components/alert-banner.js";
|
|
4
4
|
import type { BillingLabels } from "./billing-labels.js";
|
|
5
5
|
/** The `contact` mode's mail: to support, its subject naming the dimension. */
|
|
6
6
|
export declare function planLimitMailto(email: string, subject: string): string;
|
|
7
|
-
|
|
7
|
+
/** A `div`'s props, `ref` included since 0.35 (round 0.35 R4, the follow-up to API-2): they
|
|
8
|
+
* go on to the {@link AlertBanner}, so the ref is the notice's `<div>` — its `href` is the
|
|
9
|
+
* action button's, never the banner's, so the frame is never a link. */
|
|
10
|
+
interface PlanLimitNoticeBaseProps extends Omit<ComponentPropsWithRef<"div">, "children" | "onClick"> {
|
|
8
11
|
/** The dimension as the refusal names it (`"budgets"`, `"seats"`) — `isPlanLimit(err)`'s
|
|
9
12
|
* `dimension`. Carried as `data-dimension`. */
|
|
10
13
|
dimension: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/billing/plan-limit-notice.tsx"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"sources":["../../src/billing/plan-limit-notice.tsx"],"sourcesContent":["import type { ComponentPropsWithRef } from \"react\";\n\nimport { useKitLocale } from \"../i18n/kit-labels\";\nimport type { LabelOverride } from \"../i18n/kit-labels\";\nimport { formatNumber } from \"../lib/format\";\nimport { AlertBanner } from \"../components/alert-banner\";\nimport type { AlertTone } from \"../components/alert-banner\";\nimport { ProgressBar } from \"../components/progress-bar\";\nimport { Button } from \"../components/button\";\nimport { useBillingLabels } from \"./billing-labels\";\nimport type { BillingLabels } from \"./billing-labels\";\n\n/** RFC 3986 percent-encoding, `!'()*` too — a mail client that splits on `'` is the one\n * that breaks \"Plan limit: Ada's plots\" (landing/access.ts keeps the same rule). */\nfunction encodeStrict(value: string): string {\n return encodeURIComponent(value).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);\n}\n\n/** The `contact` mode's mail: to support, its subject naming the dimension. */\nexport function planLimitMailto(email: string, subject: string): string {\n const to = encodeStrict(email).replace(/%40/g, \"@\");\n return `mailto:${to}?subject=${encodeStrict(subject)}`;\n}\n\n/** A `div`'s props, `ref` included since 0.35 (round 0.35 R4, the follow-up to API-2): they\n * go on to the {@link AlertBanner}, so the ref is the notice's `<div>` — its `href` is the\n * action button's, never the banner's, so the frame is never a link. */\ninterface PlanLimitNoticeBaseProps extends Omit<ComponentPropsWithRef<\"div\">, \"children\" | \"onClick\"> {\n /** The dimension as the refusal names it (`\"budgets\"`, `\"seats\"`) — `isPlanLimit(err)`'s\n * `dimension`. Carried as `data-dimension`. */\n dimension: string;\n /** The app's name for it, in the reader's language: \"Budgets\". Default: the key. */\n dimensionLabel?: string;\n /** How many there are. Left out (keksdose's legacy `plan_budget_limit` body has no\n * `used`), it is read as `limit`: the create was refused for being at it. */\n used?: number;\n /** The plan's limit for the dimension. Left out — a body without one — the notice says\n * its words and draws no meter. */\n limit?: number;\n /** The payer's plan code, as `isPlanLimit` reads it — carried as `data-plan`, so the\n * refusal can be spread in whole: `<PlanLimitNotice {...isPlanLimit(err)} …/>`. */\n plan?: string;\n /** How a figure is written — kastlan's storage limit is bytes (`formatFileSize`).\n * Default: a number in the kit's locale. */\n formatValue?: (value: number) => string;\n /** Over the provider's locale, for the default figures. */\n locale?: string;\n /** Default `warning`. */\n tone?: AlertTone;\n /** Prop > `<UiKitProvider labels={{ billing }}>` > English. */\n labels?: LabelOverride<BillingLabels>;\n}\n\nexport type PlanLimitNoticeProps = PlanLimitNoticeBaseProps &\n (\n | {\n /** Plans are bought: \"Choose a plan\" → the app's subscription page. */\n mode: \"upgrade\";\n /** The subscription page. */\n href: string;\n email?: never;\n }\n | {\n /** The operator grants plans by hand (keksdose's today): \"Ask for more\" → a mail. */\n mode: \"contact\";\n /** The support address: `support@` the app's domain. */\n email: string;\n href?: never;\n }\n );\n\n/**\n * A create refused at the plan's limit (docs/billing-harmonization.md §3.4): \"Plan limit\n * reached\", what to do, the dimension's meter (\"Budgets — 3 of 3\") and the app's way to\n * more — `upgrade`, a link to the subscription page, or `contact`, a mail to support.\n *\n * A limit gates CREATION only: a downgrade never deletes or hides what is over the new\n * limit (§3.4), so `used` may be past `limit`; the meter then fills and turns red. Feed it\n * the refusal: `const hit = isPlanLimit(err); hit && <PlanLimitNotice {...hit} …/>`. The\n * kit sends nothing — the mail opens the reader's own client.\n */\nexport function PlanLimitNotice(props: PlanLimitNoticeProps) {\n const {\n dimension,\n dimensionLabel,\n used: usedProp,\n limit,\n plan,\n formatValue,\n locale: localeProp,\n tone = \"warning\",\n labels: labelsProp,\n mode,\n href,\n email,\n className,\n ...rest\n } = props;\n const labels = useBillingLabels(labelsProp);\n const locale = useKitLocale(localeProp);\n const used = usedProp ?? limit ?? 0;\n const name = dimensionLabel ?? dimension;\n const figure = (value: number) => (formatValue ? formatValue(value) : formatNumber(value, { locale }));\n\n const action =\n mode === \"upgrade\" ? (\n <Button href={href} variant=\"secondary\" size=\"sm\">\n {labels.choosePlan}\n </Button>\n ) : (\n <Button href={planLimitMailto(email, labels.contactSubject(name))} variant=\"secondary\" size=\"sm\">\n {labels.askForMore}\n </Button>\n );\n\n return (\n <AlertBanner\n {...rest}\n tone={tone}\n action={action}\n data-plan-limit-mode={mode}\n data-dimension={dimension}\n data-plan={plan}\n className={className}\n >\n <span className=\"block font-medium\">{labels.limitReached}</span>\n <span className=\"block\">{mode === \"upgrade\" ? labels.limitUpgrade : labels.limitContact}</span>\n {limit !== undefined && (\n <ProgressBar\n as=\"span\"\n variant=\"meter\"\n size=\"slim\"\n value={used}\n max={limit}\n label={name}\n showValue\n // The bar is clamped at `max` and hands its formatter the clamped value; the\n // figures are the real ones, so \"5 of 3\" after a downgrade says what the bar\n // cannot draw.\n formatValue={() => labels.usage(figure(used), figure(limit))}\n tone={used > limit ? \"danger\" : \"warning\"}\n className=\"mt-2\"\n locale={locale}\n />\n )}\n </AlertBanner>\n );\n}\n"],"mappings":";AA0GM,cAUF,YAVE;AAxGN,SAAS,oBAAoB;AAE7B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAE5B,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AACvB,SAAS,wBAAwB;AAKjC,SAAS,aAAa,OAAuB;AAC3C,SAAO,mBAAmB,KAAK,EAAE,QAAQ,YAAY,CAAC,MAAM,IAAI,EAAE,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE,YAAY,CAAC,EAAE;AAC9G;AAGO,SAAS,gBAAgB,OAAe,SAAyB;AACtE,QAAM,KAAK,aAAa,KAAK,EAAE,QAAQ,QAAQ,GAAG;AAClD,SAAO,UAAU,EAAE,YAAY,aAAa,OAAO,CAAC;AACtD;AA2DO,SAAS,gBAAgB,OAA6B;AAC3D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AACJ,QAAM,SAAS,iBAAiB,UAAU;AAC1C,QAAM,SAAS,aAAa,UAAU;AACtC,QAAM,OAAO,YAAY,SAAS;AAClC,QAAM,OAAO,kBAAkB;AAC/B,QAAM,SAAS,CAAC,UAAmB,cAAc,YAAY,KAAK,IAAI,aAAa,OAAO,EAAE,OAAO,CAAC;AAEpG,QAAM,SACJ,SAAS,YACP,oBAAC,UAAO,MAAY,SAAQ,aAAY,MAAK,MAC1C,iBAAO,YACV,IAEA,oBAAC,UAAO,MAAM,gBAAgB,OAAO,OAAO,eAAe,IAAI,CAAC,GAAG,SAAQ,aAAY,MAAK,MACzF,iBAAO,YACV;AAGJ,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA;AAAA,MACA,wBAAsB;AAAA,MACtB,kBAAgB;AAAA,MAChB,aAAW;AAAA,MACX;AAAA,MAEA;AAAA,4BAAC,UAAK,WAAU,qBAAqB,iBAAO,cAAa;AAAA,QACzD,oBAAC,UAAK,WAAU,SAAS,mBAAS,YAAY,OAAO,eAAe,OAAO,cAAa;AAAA,QACvF,UAAU,UACT;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,OAAO;AAAA,YACP,KAAK;AAAA,YACL,OAAO;AAAA,YACP,WAAS;AAAA,YAIT,aAAa,MAAM,OAAO,MAAM,OAAO,IAAI,GAAG,OAAO,KAAK,CAAC;AAAA,YAC3D,MAAM,OAAO,QAAQ,WAAW;AAAA,YAChC,WAAU;AAAA,YACV;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
|
package/dist/chart.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chart.ts"],"sourcesContent":["// `@eifi1/ui-kit/chart` — the chart shell and its colour system.\n//\n// A re-slicing of what the main barrel already exports, not a new API. It exists so a\n// consumer can reach the chart kit WITHOUT the barrel: `import(\"@eifi1/ui-kit/chart\")`\n// is a 31KB chunk, where the same lazy import through the barrel pulls 221KB, because\n// a dynamic import of the barrel cannot be tree-shaken down to one of its members.\n//\n// It is about chunk size, not about the peer: `recharts` is a REQUIRED peer (since 0.5.0),\n// because the main barrel re-exports everything here too, so `import { Button } from\n// \"@eifi1/ui-kit\"` reaches recharts as well (packaging-contract.test.ts asserts it).\nexport * from \"./components/chart\";\nexport * from \"./theme/chart-palette\";\n\n// The tile chart (treemap) the apps share — moved here from keksdose so every consumer\n// derives it from the package rather than from a copy.\nexport * from \"./components/treemap\";\n\n// lenkbank's zoomable series chart, its synced x-zoom, the toggle legend and the\n// mirrored-pair axis geometry — moved here so the apps derive them from the package.\nexport * from \"./components/series-chart\";\n// 0.32.1 (keksdose's 0.32 report): the height every chart takes, for an app's wrappers.\nexport type { ChartHeight } from \"./components/chart-height\";\nexport * from \"./components/chart-zoom\";\n// The
|
|
1
|
+
{"version":3,"sources":["../src/chart.ts"],"sourcesContent":["// `@eifi1/ui-kit/chart` — the chart shell and its colour system.\n//\n// A re-slicing of what the main barrel already exports, not a new API. It exists so a\n// consumer can reach the chart kit WITHOUT the barrel: `import(\"@eifi1/ui-kit/chart\")`\n// is a 31KB chunk, where the same lazy import through the barrel pulls 221KB, because\n// a dynamic import of the barrel cannot be tree-shaken down to one of its members.\n//\n// It is about chunk size, not about the peer: `recharts` is a REQUIRED peer (since 0.5.0),\n// because the main barrel re-exports everything here too, so `import { Button } from\n// \"@eifi1/ui-kit\"` reaches recharts as well (packaging-contract.test.ts asserts it).\nexport * from \"./components/chart\";\nexport * from \"./theme/chart-palette\";\n\n// The tile chart (treemap) the apps share — moved here from keksdose so every consumer\n// derives it from the package rather than from a copy.\nexport * from \"./components/treemap\";\n\n// lenkbank's zoomable series chart, its synced x-zoom, the toggle legend and the\n// mirrored-pair axis geometry — moved here so the apps derive them from the package.\nexport * from \"./components/series-chart\";\n// 0.32.1 (keksdose's 0.32 report): the height every chart takes, for an app's wrappers.\nexport type { ChartHeight } from \"./components/chart-height\";\n// SharedXZoom and the zoom's types: the public face of ./chart-zoom-core, whose arithmetic\n// stays the kit's (refactor audit 2026-10, API-6b; off the surface in 0.35).\nexport * from \"./components/chart-zoom\";\n// The same binding, named from the module that holds it and the drag layer (recharts): the\n// packaging contract reads this entry's own imports to know which modules may import\n// recharts, so chart-zoom-core has to be one of them (MOD-6).\nexport { SharedXZoom } from \"./components/chart-zoom-core\";\nexport * from \"./components/toggle-legend\";\nexport * from \"./components/facing-pair\";\nexport * from \"./components/series-chart-labels\";\n\n// The part-to-whole chart (donut / pie) — moved here from kastlan's dashboard and reports.\nexport * from \"./components/pie-chart\";\nexport * from \"./components/pie-chart-labels\";\n"],"mappings":";AAUA,cAAc;AACd,cAAc;AAId,cAAc;AAId,cAAc;AAKd,cAAc;AAId,SAAS,mBAAmB;AAC5B,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -62,9 +62,6 @@ export interface AmountInputProps {
|
|
|
62
62
|
id?: string;
|
|
63
63
|
/** Names the field when it has no visible `label` (a table cell, the display shape). */
|
|
64
64
|
"aria-label"?: string;
|
|
65
|
-
/** @deprecated 0.34 — use `aria-label`; removed in 0.35 (refactor audit 2026-10, API-1).
|
|
66
|
-
* Names the field only when `aria-label` is absent. */
|
|
67
|
-
ariaLabel?: string;
|
|
68
65
|
/**
|
|
69
66
|
* Set on the `<input>`, with `id` above. Declared so `Field`'s render-prop spread —
|
|
70
67
|
* `{(ids) => <AmountInput {...ids} … />}` — is typed and reaches the input: the
|
|
@@ -62,7 +62,7 @@ function isResultOf(previous, text, settle) {
|
|
|
62
62
|
return n !== null && settle(formatResult(n)) === text.trim();
|
|
63
63
|
}
|
|
64
64
|
function AmountInput(props) {
|
|
65
|
-
const { ref, value, onChange, currency, onCurrencyChange, placeholder, label, className, inputClassName, id, "aria-label":
|
|
65
|
+
const { ref, value, onChange, currency, onCurrencyChange, placeholder, label, className, inputClassName, id, "aria-label": ariaLabel, "aria-required": ariaRequired, autoFocus, tone = "neutral", negative = false, onNegativeChange, align = "start", labels, currencyNames, currencyOptions, digits: digitsProp, min, max, onCommit, disabledReasonDisplay } = props;
|
|
66
66
|
const generatedId = useId();
|
|
67
67
|
const fieldId = id ?? generatedId;
|
|
68
68
|
const signOwned = onNegativeChange !== void 0;
|
|
@@ -135,7 +135,7 @@ function AmountInput(props) {
|
|
|
135
135
|
{
|
|
136
136
|
ref: setRefs,
|
|
137
137
|
id: fieldId,
|
|
138
|
-
"aria-label":
|
|
138
|
+
"aria-label": ariaLabel,
|
|
139
139
|
type: "text",
|
|
140
140
|
autoFocus,
|
|
141
141
|
inputMode: isMobile ? "none" : "decimal",
|