@eifi1/ui-kit 0.48.2 → 0.50.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 +34 -16
- package/dist/admin/admin-action-confirm.js +1 -1
- package/dist/admin/admin-action-confirm.js.map +1 -1
- package/dist/admin/invitations-panel.js +5 -1
- package/dist/admin/invitations-panel.js.map +1 -1
- package/dist/admin/user-roster.d.ts +24 -12
- package/dist/admin/user-roster.js +21 -6
- package/dist/admin/user-roster.js.map +1 -1
- package/dist/auth/accept-invitation.js +2 -2
- package/dist/auth/accept-invitation.js.map +1 -1
- package/dist/auth/not-found-page.js +1 -1
- package/dist/auth/not-found-page.js.map +1 -1
- package/dist/auth/reset-password-form.js +2 -2
- package/dist/auth/reset-password-form.js.map +1 -1
- package/dist/auth/verify-email.d.ts +9 -1
- package/dist/auth/verify-email.js +5 -3
- package/dist/auth/verify-email.js.map +1 -1
- package/dist/billing/plan-card.js +2 -2
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/components/amount-input.d.ts +2 -1
- package/dist/components/amount-input.js +3 -2
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.js +1 -0
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/breadcrumbs.d.ts +19 -1
- package/dist/components/breadcrumbs.js +11 -4
- package/dist/components/breadcrumbs.js.map +1 -1
- package/dist/components/button-look.d.ts +37 -7
- package/dist/components/button-look.js +33 -6
- package/dist/components/button-look.js.map +1 -1
- package/dist/components/button.d.ts +4 -1
- package/dist/components/button.js +2 -2
- package/dist/components/button.js.map +1 -1
- package/dist/components/calendar-heatmap.js +2 -1
- package/dist/components/calendar-heatmap.js.map +1 -1
- package/dist/components/chart-edge.d.ts +10 -0
- package/dist/components/chart-edge.js +57 -0
- package/dist/components/chart-edge.js.map +1 -0
- package/dist/components/chart.js +2 -1
- package/dist/components/chart.js.map +1 -1
- package/dist/components/chip.d.ts +8 -1
- package/dist/components/chip.js +4 -1
- package/dist/components/chip.js.map +1 -1
- package/dist/components/combobox-core.js +1 -0
- package/dist/components/combobox-core.js.map +1 -1
- package/dist/components/combobox-suggestions.js +1 -0
- package/dist/components/combobox-suggestions.js.map +1 -1
- package/dist/components/confirm-context.d.ts +5 -0
- package/dist/components/confirm-context.js +7 -0
- package/dist/components/confirm-context.js.map +1 -0
- package/dist/components/confirm-dialog.js +3 -3
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/currency-select.d.ts +28 -2
- package/dist/components/currency-select.js +56 -10
- package/dist/components/currency-select.js.map +1 -1
- package/dist/components/danger-confirm.d.ts +2 -2
- package/dist/components/danger-confirm.js +1 -1
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-fit.js +21 -3
- package/dist/components/data-table-fit.js.map +1 -1
- package/dist/components/data-table-mobile.d.ts +58 -3
- package/dist/components/data-table-mobile.js +147 -16
- package/dist/components/data-table-mobile.js.map +1 -1
- package/dist/components/data-table-row-actions.d.ts +2 -1
- package/dist/components/data-table-row-actions.js +7 -0
- package/dist/components/data-table-row-actions.js.map +1 -1
- package/dist/components/data-table-row.d.ts +1 -1
- package/dist/components/data-table-row.js.map +1 -1
- package/dist/components/data-table.d.ts +34 -1
- package/dist/components/data-table.js +37 -10
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/dropdown.js +1 -0
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/error-boundary.js +2 -2
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/floating-panel.d.ts +36 -13
- package/dist/components/floating-panel.js +27 -7
- package/dist/components/floating-panel.js.map +1 -1
- package/dist/components/form-actions.d.ts +1 -1
- package/dist/components/form-actions.js +1 -1
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/full-bleed-dialog.js +1 -0
- package/dist/components/full-bleed-dialog.js.map +1 -1
- package/dist/components/icon-button.d.ts +11 -0
- package/dist/components/icon-button.js +7 -5
- package/dist/components/icon-button.js.map +1 -1
- package/dist/components/modal.js +1 -0
- package/dist/components/modal.js.map +1 -1
- package/dist/components/nav-pills.d.ts +8 -1
- package/dist/components/nav-pills.js +61 -38
- package/dist/components/nav-pills.js.map +1 -1
- package/dist/components/number-input.d.ts +2 -1
- package/dist/components/number-input.js +6 -2
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numpad-sheet.js +2 -0
- package/dist/components/numpad-sheet.js.map +1 -1
- package/dist/components/page-header-context.d.ts +8 -0
- package/dist/components/page-header-context.js +7 -0
- package/dist/components/page-header-context.js.map +1 -0
- package/dist/components/page-header.d.ts +14 -2
- package/dist/components/page-header.js +10 -1
- package/dist/components/page-header.js.map +1 -1
- package/dist/components/picker-sheet.js +2 -0
- package/dist/components/picker-sheet.js.map +1 -1
- package/dist/components/pie-chart.js +2 -1
- package/dist/components/pie-chart.js.map +1 -1
- package/dist/components/popover.js +1 -0
- package/dist/components/popover.js.map +1 -1
- package/dist/components/progress-bar.js +5 -4
- package/dist/components/progress-bar.js.map +1 -1
- package/dist/components/reauth-dialog.js +1 -1
- package/dist/components/reauth-dialog.js.map +1 -1
- package/dist/components/row-actions-labels.js +3 -1
- package/dist/components/row-actions-labels.js.map +1 -1
- package/dist/components/row-actions.d.ts +43 -9
- package/dist/components/row-actions.js +78 -15
- package/dist/components/row-actions.js.map +1 -1
- package/dist/components/section-nav.d.ts +37 -0
- package/dist/components/section-nav.js +33 -0
- package/dist/components/section-nav.js.map +1 -0
- package/dist/components/series-chart.js +8 -3
- package/dist/components/series-chart.js.map +1 -1
- package/dist/components/share-card.js +1 -1
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/signature-pad.js +1 -1
- package/dist/components/signature-pad.js.map +1 -1
- package/dist/components/sparkline.js +2 -1
- package/dist/components/sparkline.js.map +1 -1
- package/dist/components/stat-tile.js +14 -7
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/status-dot.d.ts +5 -1
- package/dist/components/status-dot.js +4 -1
- package/dist/components/status-dot.js.map +1 -1
- package/dist/components/tooltip.js +1 -1
- package/dist/components/tooltip.js.map +1 -1
- package/dist/components/translation-review-editor.js +2 -2
- package/dist/components/translation-review-editor.js.map +1 -1
- package/dist/components/translation-review.js +2 -2
- package/dist/components/translation-review.js.map +1 -1
- package/dist/components/treemap.d.ts +5 -2
- package/dist/components/treemap.js +26 -6
- package/dist/components/treemap.js.map +1 -1
- package/dist/components/use-table-state.js +37 -6
- package/dist/components/use-table-state.js.map +1 -1
- package/dist/data-table.js.map +1 -1
- package/dist/demo/demo-banner.js +1 -1
- package/dist/demo/demo-banner.js.map +1 -1
- package/dist/demo/demo-ended.js +1 -1
- package/dist/demo/demo-ended.js.map +1 -1
- package/dist/demo/demo-start.js +1 -1
- package/dist/demo/demo-start.js.map +1 -1
- package/dist/eslint/index.js +1 -1
- package/dist/feedback/feedback-inbox.js +1 -1
- package/dist/feedback/feedback-inbox.js.map +1 -1
- package/dist/hooks/use-dismiss.d.ts +9 -1
- package/dist/hooks/use-dismiss.js +25 -5
- package/dist/hooks/use-dismiss.js.map +1 -1
- package/dist/hooks/use-document-title.d.ts +14 -0
- package/dist/hooks/use-document-title.js +22 -0
- package/dist/hooks/use-document-title.js.map +1 -0
- package/dist/i18n/defaults.js +2 -0
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +20 -3
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +34 -1
- package/dist/i18n/kit-labels.js +43 -2
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +22 -3
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +20 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +20 -3
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +20 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +20 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +20 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +3 -0
- package/dist/i18n/review.js.map +1 -1
- package/dist/i18n/shared-labels.js +1 -0
- package/dist/i18n/shared-labels.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-actions.js +2 -2
- package/dist/landing/landing-actions.js.map +1 -1
- package/dist/landing/public-header.js +2 -2
- package/dist/landing/public-header.js.map +1 -1
- package/dist/lib/clipboard-minus.d.ts +27 -0
- package/dist/lib/clipboard-minus.js +63 -0
- package/dist/lib/clipboard-minus.js.map +1 -0
- package/dist/lib/data-attributes.d.ts +11 -0
- package/dist/lib/data-attributes.js +10 -0
- package/dist/lib/data-attributes.js.map +1 -0
- package/dist/lib/document-title.d.ts +17 -0
- package/dist/lib/document-title.js +29 -0
- package/dist/lib/document-title.js.map +1 -0
- package/dist/lib/float-clearance.js +8 -2
- package/dist/lib/float-clearance.js.map +1 -1
- package/dist/lib/format.d.ts +36 -10
- package/dist/lib/format.js +57 -11
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/minus.d.ts +32 -0
- package/dist/lib/minus.js +14 -0
- package/dist/lib/minus.js.map +1 -0
- package/dist/lib/status-tone.d.ts +30 -0
- package/dist/lib/status-tone.js +17 -0
- package/dist/lib/status-tone.js.map +1 -0
- package/dist/settings/settings-layout.js +3 -2
- package/dist/settings/settings-layout.js.map +1 -1
- package/dist/shell/account-menu-language.d.ts +1 -1
- package/dist/shell/account-menu-language.js +9 -1
- package/dist/shell/account-menu-language.js.map +1 -1
- package/dist/shell/app-shell-labels.js +2 -1
- package/dist/shell/app-shell-labels.js.map +1 -1
- package/dist/shell/app-shell.d.ts +58 -16
- package/dist/shell/app-shell.js +151 -43
- package/dist/shell/app-shell.js.map +1 -1
- package/dist/shell/language-code.d.ts +3 -0
- package/dist/shell/language-code.js +8 -0
- package/dist/shell/language-code.js.map +1 -0
- package/dist/shell/topbar-controls.d.ts +14 -6
- package/dist/shell/topbar-controls.js +14 -17
- package/dist/shell/topbar-controls.js.map +1 -1
- package/dist/testing/css-variables.generated.d.ts +1 -1
- package/dist/testing/css-variables.generated.js +1 -1
- package/dist/testing/css-variables.generated.js.map +1 -1
- package/dist/testing/react.d.ts +25 -0
- package/dist/testing/react.js +19 -0
- package/dist/testing/react.js.map +1 -0
- package/dist/theme/chart-palette.d.ts +82 -15
- package/dist/theme/chart-palette.js +51 -24
- package/dist/theme/chart-palette.js.map +1 -1
- package/dist/theme/palette-presets.d.ts +9 -0
- package/dist/theme/palette-presets.js +77 -62
- package/dist/theme/palette-presets.js.map +1 -1
- package/dist/tour/tour-dock.d.ts +42 -0
- package/dist/tour/tour-dock.js +80 -0
- package/dist/tour/tour-dock.js.map +1 -0
- package/dist/tour/tour-gates.d.ts +71 -0
- package/dist/tour/tour-gates.js +114 -0
- package/dist/tour/tour-gates.js.map +1 -0
- package/dist/tour/tour-guide-button.d.ts +27 -0
- package/dist/tour/tour-guide-button.js +45 -0
- package/dist/tour/tour-guide-button.js.map +1 -0
- package/dist/tour/tour-guide-labels.d.ts +8 -0
- package/dist/tour/tour-guide-labels.js +9 -0
- package/dist/tour/tour-guide-labels.js.map +1 -0
- package/dist/tour/tour-labels.js +9 -1
- package/dist/tour/tour-labels.js.map +1 -1
- package/dist/tour/tour.d.ts +133 -9
- package/dist/tour/tour.js +594 -70
- package/dist/tour/tour.js.map +1 -1
- package/dist/tour/use-tour-url-sync.d.ts +5 -2
- package/dist/tour/use-tour-url-sync.js +7 -1
- package/dist/tour/use-tour-url-sync.js.map +1 -1
- package/dist/tour.d.ts +2 -0
- package/dist/tour.js +3 -0
- package/dist/tour.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +1 -1
- package/dist/wizard/stepper-nav.js +18 -5
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/dist/wizard/types.d.ts +11 -0
- package/dist/wizard/types.js.map +1 -1
- package/dist/wizard/use-wizard.js +11 -5
- package/dist/wizard/use-wizard.js.map +1 -1
- package/package.json +9 -1
- package/src/admin/admin-action-confirm.tsx +1 -1
- package/src/admin/invitations-panel.tsx +7 -3
- package/src/admin/user-roster.tsx +41 -14
- package/src/auth/accept-invitation.tsx +3 -3
- package/src/auth/not-found-page.tsx +1 -1
- package/src/auth/reset-password-form.tsx +3 -3
- package/src/auth/verify-email.tsx +13 -3
- package/src/billing/plan-card.tsx +2 -2
- package/src/components/amount-input.tsx +5 -4
- package/src/components/autocomplete.tsx +2 -0
- package/src/components/breadcrumbs.tsx +32 -4
- package/src/components/button-look.ts +86 -15
- package/src/components/button.tsx +6 -3
- package/src/components/calendar-heatmap.tsx +2 -1
- package/src/components/chart-edge.ts +73 -0
- package/src/components/chart.tsx +3 -1
- package/src/components/chip.tsx +10 -1
- package/src/components/combobox-core.tsx +2 -0
- package/src/components/combobox-suggestions.tsx +2 -0
- package/src/components/confirm-context.ts +7 -0
- package/src/components/confirm-dialog.tsx +3 -3
- package/src/components/currency-select.tsx +95 -6
- package/src/components/danger-confirm.tsx +3 -3
- package/src/components/data-table-fit.ts +41 -6
- package/src/components/data-table-mobile.tsx +259 -17
- package/src/components/data-table-row-actions.tsx +9 -1
- package/src/components/data-table-row.tsx +3 -0
- package/src/components/data-table.tsx +91 -19
- package/src/components/dropdown.tsx +2 -0
- package/src/components/error-boundary.tsx +2 -2
- package/src/components/floating-panel.tsx +67 -16
- package/src/components/form-actions.tsx +2 -2
- package/src/components/full-bleed-dialog.tsx +3 -0
- package/src/components/icon-button.tsx +21 -8
- package/src/components/modal.tsx +3 -0
- package/src/components/nav-pills.tsx +29 -2
- package/src/components/number-input.tsx +8 -3
- package/src/components/numpad-sheet.tsx +4 -0
- package/src/components/page-header-context.ts +8 -0
- package/src/components/page-header.tsx +34 -2
- package/src/components/picker-sheet.tsx +4 -0
- package/src/components/pie-chart.tsx +2 -1
- package/src/components/popover.tsx +2 -0
- package/src/components/progress-bar.tsx +6 -3
- package/src/components/reauth-dialog.tsx +1 -1
- package/src/components/row-actions-labels.ts +2 -0
- package/src/components/row-actions.tsx +154 -33
- package/src/components/section-nav.tsx +65 -0
- package/src/components/series-chart.tsx +12 -3
- package/src/components/share-card.tsx +1 -1
- package/src/components/signature-pad.tsx +1 -1
- package/src/components/sparkline.tsx +2 -1
- package/src/components/stat-tile.tsx +19 -7
- package/src/components/status-dot.tsx +7 -1
- package/src/components/tooltip.tsx +3 -1
- package/src/components/translation-review-editor.tsx +2 -2
- package/src/components/translation-review.tsx +2 -2
- package/src/components/treemap.tsx +34 -8
- package/src/components/use-table-state.ts +63 -8
- package/src/data-table.ts +3 -3
- package/src/demo/demo-banner.tsx +1 -1
- package/src/demo/demo-ended.tsx +1 -1
- package/src/demo/demo-start.tsx +1 -1
- package/src/feedback/feedback-inbox.tsx +1 -1
- package/src/hooks/use-dismiss.ts +43 -4
- package/src/hooks/use-document-title.ts +31 -0
- package/src/i18n/defaults.ts +2 -0
- package/src/i18n/german.ts +17 -0
- package/src/i18n/kit-labels.tsx +79 -1
- package/src/i18n/locales/es.ts +17 -0
- package/src/i18n/locales/fr.ts +17 -0
- package/src/i18n/locales/hu.ts +17 -0
- package/src/i18n/locales/it.ts +17 -0
- package/src/i18n/locales/zh.ts +17 -0
- package/src/i18n/review.ts +3 -0
- package/src/i18n/shared-labels.ts +1 -0
- package/src/index.ts +13 -0
- package/src/landing/landing-actions.tsx +2 -2
- package/src/landing/public-header.tsx +2 -2
- package/src/lib/clipboard-minus.ts +94 -0
- package/src/lib/data-attributes.ts +14 -0
- package/src/lib/document-title.ts +41 -0
- package/src/lib/float-clearance.ts +19 -3
- package/src/lib/format.ts +117 -30
- package/src/lib/minus.ts +50 -0
- package/src/lib/status-tone.ts +43 -0
- package/src/settings/settings-layout.tsx +3 -2
- package/src/shell/account-menu-language.tsx +14 -2
- package/src/shell/app-shell-labels.ts +1 -0
- package/src/shell/app-shell.tsx +291 -68
- package/src/shell/language-code.ts +5 -0
- package/src/shell/topbar-controls.tsx +35 -15
- package/src/testing/css-variables.generated.ts +6 -6
- package/src/testing/react.ts +59 -0
- package/src/theme/chart-palette.ts +102 -20
- package/src/theme/palette-presets.ts +121 -84
- package/src/tour/tour-dock.ts +132 -0
- package/src/tour/tour-gates.ts +195 -0
- package/src/tour/tour-guide-button.tsx +64 -0
- package/src/tour/tour-guide-labels.ts +15 -0
- package/src/tour/tour-labels.ts +8 -0
- package/src/tour/tour.tsx +949 -86
- package/src/tour/use-tour-url-sync.ts +14 -4
- package/src/tour.ts +3 -0
- package/src/wizard/stepper-nav.tsx +27 -7
- package/src/wizard/types.ts +12 -0
- package/src/wizard/use-wizard.ts +16 -9
- package/tokens.css +28 -18
package/src/i18n/locales/fr.ts
CHANGED
|
@@ -551,6 +551,7 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
551
551
|
theme: "Changer de thème",
|
|
552
552
|
palette: "Préréglage d’apparence",
|
|
553
553
|
language: "Langue",
|
|
554
|
+
languageCurrent: (name) => `Choisir la langue, actuelle\u00a0: ${name}`,
|
|
554
555
|
switchRole: "Changer de rôle",
|
|
555
556
|
role: (value) => `Rôle\u00a0: ${value}`,
|
|
556
557
|
},
|
|
@@ -631,6 +632,19 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
631
632
|
awaitClickHint: "Cliquez sur l’élément mis en évidence pour continuer",
|
|
632
633
|
awaitInputHint: "Saisissez une valeur dans le champ mis en évidence pour continuer", // 0.46: TourStep.awaitInput (keksdose live #436).
|
|
633
634
|
step: (current, total) => `${n(current)} / ${n(total)}`,
|
|
635
|
+
// 0.50: guided form tours (docs/tours-harmonization.md §11).
|
|
636
|
+
leaveEmpty: "Laisser vide",
|
|
637
|
+
optional: "Facultatif",
|
|
638
|
+
gateHint: "Remplissez le champ mis en évidence pour continuer",
|
|
639
|
+
gateReady: "Prêt. Appuyez sur Suivant ou sur Entrée pour continuer.",
|
|
640
|
+
awaitGateHint: "Enregistrez pour continuer",
|
|
641
|
+
awaitGateRefused: "Ce n’est pas encore enregistré. Vérifiez le formulaire et réessayez.",
|
|
642
|
+
backToStep: (title) => `Retour à «\u202f${title}\u202f»`,
|
|
643
|
+
},
|
|
644
|
+
// 0.50: the form's "Guide me" (TourGuideButton, docs/tours-harmonization.md §11).
|
|
645
|
+
tourGuide: {
|
|
646
|
+
label: "Me guider",
|
|
647
|
+
description: "Vous guide dans ce formulaire, champ par champ",
|
|
634
648
|
},
|
|
635
649
|
// 0.43.0 — docs/tours-harmonization.md §3, §8: the tours page. keksdose's reviewed words.
|
|
636
650
|
tourCatalogue: {
|
|
@@ -1909,10 +1923,13 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
1909
1923
|
rowActions: {
|
|
1910
1924
|
actions: "Actions",
|
|
1911
1925
|
actionsFor: (name) => `Actions pour ${name}`,
|
|
1926
|
+
confirmTitle: (action, name) => (name ? `${action} «\u00a0${name}\u00a0»\u00a0?` : `${action}\u00a0?`),
|
|
1927
|
+
confirmBody: "Cette action est irréversible.",
|
|
1912
1928
|
},
|
|
1913
1929
|
appShellMore: {
|
|
1914
1930
|
more: "Plus",
|
|
1915
1931
|
moreTitle: "Autres pages",
|
|
1932
|
+
overview: "Vue d’ensemble",
|
|
1916
1933
|
},
|
|
1917
1934
|
// 0.42.0 — docs/admin-harmonization.md §3.1: the admin area's shared words.
|
|
1918
1935
|
mailTestCard: {
|
package/src/i18n/locales/hu.ts
CHANGED
|
@@ -541,6 +541,7 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
541
541
|
theme: "Téma váltása",
|
|
542
542
|
palette: "Megjelenési séma",
|
|
543
543
|
language: "Nyelv",
|
|
544
|
+
languageCurrent: (name) => `Nyelv kiválasztása, jelenlegi: ${name}`,
|
|
544
545
|
switchRole: "Szerepkör váltása",
|
|
545
546
|
role: (value) => `Szerepkör: ${value}`,
|
|
546
547
|
},
|
|
@@ -618,6 +619,19 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
618
619
|
awaitClickHint: "A folytatáshoz kattintson a kiemelt elemre",
|
|
619
620
|
awaitInputHint: "A folytatáshoz adjon meg egy értéket a kiemelt mezőben", // 0.46: TourStep.awaitInput (keksdose live #436).
|
|
620
621
|
step: (current, total) => `${n(current)} / ${n(total)}`,
|
|
622
|
+
// 0.50: guided form tours (docs/tours-harmonization.md §11).
|
|
623
|
+
leaveEmpty: "Hagyja üresen",
|
|
624
|
+
optional: "Nem kötelező",
|
|
625
|
+
gateHint: "A folytatáshoz töltse ki a kiemelt mezőt",
|
|
626
|
+
gateReady: "Kész. A folytatáshoz nyomja meg a Tovább gombot vagy az Entert.",
|
|
627
|
+
awaitGateHint: "A folytatáshoz mentsen",
|
|
628
|
+
awaitGateRefused: "Ez még nincs mentve. Ellenőrizze az űrlapot, és próbálja újra.",
|
|
629
|
+
backToStep: (title) => `Vissza ide: „${title}”`,
|
|
630
|
+
},
|
|
631
|
+
// 0.50: the form's "Guide me" (TourGuideButton, docs/tours-harmonization.md §11).
|
|
632
|
+
tourGuide: {
|
|
633
|
+
label: "Vezessen végig",
|
|
634
|
+
description: "Mezőről mezőre végigvezeti az űrlapon",
|
|
621
635
|
},
|
|
622
636
|
// 0.43.0 — docs/tours-harmonization.md §3, §8: the tours page.
|
|
623
637
|
tourCatalogue: {
|
|
@@ -1875,10 +1889,13 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
1875
1889
|
rowActions: {
|
|
1876
1890
|
actions: "Műveletek",
|
|
1877
1891
|
actionsFor: (name) => `${name} – műveletek`,
|
|
1892
|
+
confirmTitle: (action, name) => (name ? `${action}: „${name}”?` : `${action}?`),
|
|
1893
|
+
confirmBody: "Ez nem vonható vissza.",
|
|
1878
1894
|
},
|
|
1879
1895
|
appShellMore: {
|
|
1880
1896
|
more: "Továbbiak",
|
|
1881
1897
|
moreTitle: "További oldalak",
|
|
1898
|
+
overview: "Áttekintés",
|
|
1882
1899
|
},
|
|
1883
1900
|
// 0.42.0 — docs/admin-harmonization.md §3.1: the admin area's shared words. "Ön", as
|
|
1884
1901
|
// the rest of the catalogue.
|
package/src/i18n/locales/it.ts
CHANGED
|
@@ -546,6 +546,7 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
546
546
|
theme: "Cambia tema",
|
|
547
547
|
palette: "Preset di aspetto",
|
|
548
548
|
language: "Lingua",
|
|
549
|
+
languageCurrent: (name) => `Scegli la lingua, attuale: ${name}`,
|
|
549
550
|
switchRole: "Cambia ruolo",
|
|
550
551
|
role: (value) => `Ruolo: ${value}`,
|
|
551
552
|
},
|
|
@@ -620,6 +621,19 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
620
621
|
awaitClickHint: "Faccia clic sull’elemento evidenziato per continuare",
|
|
621
622
|
awaitInputHint: "Inserisca un valore nel campo evidenziato per continuare", // 0.46: TourStep.awaitInput (keksdose live #436).
|
|
622
623
|
step: (current, total) => `${n(current)} / ${n(total)}`,
|
|
624
|
+
// 0.50: guided form tours (docs/tours-harmonization.md §11).
|
|
625
|
+
leaveEmpty: "Lascia vuoto",
|
|
626
|
+
optional: "Facoltativo",
|
|
627
|
+
gateHint: "Compili il campo evidenziato per continuare",
|
|
628
|
+
gateReady: "Pronto. Prema Avanti o Invio per continuare.",
|
|
629
|
+
awaitGateHint: "Salvi per continuare",
|
|
630
|
+
awaitGateRefused: "Non è ancora stato salvato. Controlli il modulo e riprovi.",
|
|
631
|
+
backToStep: (title) => `Torna a «${title}»`,
|
|
632
|
+
},
|
|
633
|
+
// 0.50: the form's "Guide me" (TourGuideButton, docs/tours-harmonization.md §11).
|
|
634
|
+
tourGuide: {
|
|
635
|
+
label: "Guidami",
|
|
636
|
+
description: "La guida in questo modulo, campo per campo",
|
|
623
637
|
},
|
|
624
638
|
// 0.43.0 — docs/tours-harmonization.md §3, §8: the tours page. keksdose's reviewed words.
|
|
625
639
|
tourCatalogue: {
|
|
@@ -1888,10 +1902,13 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
1888
1902
|
rowActions: {
|
|
1889
1903
|
actions: "Azioni",
|
|
1890
1904
|
actionsFor: (name) => `Azioni per ${name}`,
|
|
1905
|
+
confirmTitle: (action, name) => (name ? `${action} «${name}»?` : `${action}?`),
|
|
1906
|
+
confirmBody: "Questa azione non può essere annullata.",
|
|
1891
1907
|
},
|
|
1892
1908
|
appShellMore: {
|
|
1893
1909
|
more: "Altro",
|
|
1894
1910
|
moreTitle: "Altre pagine",
|
|
1911
|
+
overview: "Panoramica",
|
|
1895
1912
|
},
|
|
1896
1913
|
// 0.42.0 — docs/admin-harmonization.md §3.1: the admin area's shared words. "Lei", as
|
|
1897
1914
|
// the rest of the catalogue.
|
package/src/i18n/locales/zh.ts
CHANGED
|
@@ -529,6 +529,7 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
529
529
|
theme: "切换主题",
|
|
530
530
|
palette: "外观预设",
|
|
531
531
|
language: "语言",
|
|
532
|
+
languageCurrent: (name) => `选择语言,当前:${name}`,
|
|
532
533
|
switchRole: "切换角色",
|
|
533
534
|
role: (value) => `角色:${value}`,
|
|
534
535
|
},
|
|
@@ -599,6 +600,19 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
599
600
|
awaitClickHint: "点击高亮的元素以继续",
|
|
600
601
|
awaitInputHint: "在高亮的字段中输入一个值以继续", // 0.46: TourStep.awaitInput (keksdose live #436).
|
|
601
602
|
step: (current, total) => `${n(current)} / ${n(total)}`,
|
|
603
|
+
// 0.50: guided form tours (docs/tours-harmonization.md §11).
|
|
604
|
+
leaveEmpty: "留空",
|
|
605
|
+
optional: "可选",
|
|
606
|
+
gateHint: "填写高亮的字段以继续",
|
|
607
|
+
gateReady: "已就绪。按“下一步”或回车键继续。",
|
|
608
|
+
awaitGateHint: "保存以继续",
|
|
609
|
+
awaitGateRefused: "尚未保存。请检查表单后重试。",
|
|
610
|
+
backToStep: (title) => `返回“${title}”`,
|
|
611
|
+
},
|
|
612
|
+
// 0.50: the form's "Guide me" (TourGuideButton, docs/tours-harmonization.md §11).
|
|
613
|
+
tourGuide: {
|
|
614
|
+
label: "引导我",
|
|
615
|
+
description: "逐个字段引导您填写此表单",
|
|
602
616
|
},
|
|
603
617
|
// 0.43.0 — docs/tours-harmonization.md §3, §8: the tours page.
|
|
604
618
|
tourCatalogue: {
|
|
@@ -1795,10 +1809,13 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
1795
1809
|
rowActions: {
|
|
1796
1810
|
actions: "操作",
|
|
1797
1811
|
actionsFor: (name) => `${name} 的操作`,
|
|
1812
|
+
confirmTitle: (action, name) => (name ? `${action}“${name}”?` : `${action}?`),
|
|
1813
|
+
confirmBody: "此操作无法撤销。",
|
|
1798
1814
|
},
|
|
1799
1815
|
appShellMore: {
|
|
1800
1816
|
more: "更多",
|
|
1801
1817
|
moreTitle: "更多页面",
|
|
1818
|
+
overview: "概览",
|
|
1802
1819
|
},
|
|
1803
1820
|
// 0.42.0 — docs/admin-harmonization.md §3.1: the admin area's shared words.
|
|
1804
1821
|
mailTestCard: {
|
package/src/i18n/review.ts
CHANGED
|
@@ -153,9 +153,11 @@ export const KIT_LABEL_SAMPLES: Readonly<Record<string, readonly (readonly unkno
|
|
|
153
153
|
"tabs.remove": [["{{tab}}"]],
|
|
154
154
|
"appShell.toggleGroup": [["{{group}}"]],
|
|
155
155
|
"topBar.role": [["{{role}}"]],
|
|
156
|
+
"topBar.languageCurrent": [["{{name}}"]],
|
|
156
157
|
"file.size": [[2_500_000]],
|
|
157
158
|
"wizard.step": [[2, 4]],
|
|
158
159
|
"tour.step": [[2, 4]],
|
|
160
|
+
"tour.backToStep": [["{{title}}"]],
|
|
159
161
|
"globalSearch.shortcut": [["{{keys}}"]],
|
|
160
162
|
"pieChart.slice": [["{{label}}", "{{value}}", "{{percent}}"]],
|
|
161
163
|
"sparkline.rising": [["{{first}}", "{{last}}"]],
|
|
@@ -279,6 +281,7 @@ export const KIT_LABEL_SAMPLES: Readonly<Record<string, readonly (readonly unkno
|
|
|
279
281
|
"signChip.direction": [["{{current}}", "{{next}}"]],
|
|
280
282
|
"signChip.switchTo": [["{{next}}"]],
|
|
281
283
|
"rowActions.actionsFor": [["{{name}}"]],
|
|
284
|
+
"rowActions.confirmTitle": [["{{action}}", "{{name}}"], ["{{action}}"]],
|
|
282
285
|
"columnMapper.readError": [["{{name}}"]],
|
|
283
286
|
"columnMapper.summary": [
|
|
284
287
|
[1, 1],
|
|
@@ -106,6 +106,7 @@ export const DEFAULT_TOP_BAR_LABELS: TopBarLabels = {
|
|
|
106
106
|
theme: "Toggle theme",
|
|
107
107
|
palette: "Appearance preset",
|
|
108
108
|
language: "Language",
|
|
109
|
+
languageCurrent: (name) => `Choose language, current: ${name}`,
|
|
109
110
|
switchRole: "Switch role",
|
|
110
111
|
role: (value) => `Role: ${value}`,
|
|
111
112
|
};
|
package/src/index.ts
CHANGED
|
@@ -154,6 +154,12 @@ export { useCloseTransition, OVERLAY_EXIT_MS } from "./hooks/use-close-transitio
|
|
|
154
154
|
export { useRowSwipe } from "./hooks/use-row-swipe";
|
|
155
155
|
// 0.28: keksdose's noindex marker, for the legal and auth pages of every app.
|
|
156
156
|
export { useNoIndex } from "./hooks/use-noindex";
|
|
157
|
+
// 0.49 KIT-9: the window's title from page, section and app, in the provider's format.
|
|
158
|
+
export { useDocumentTitle } from "./hooks/use-document-title";
|
|
159
|
+
// 0.49 KIT-1b: U+2212 before a number as "-", the copy handler's rule, for an app's text.
|
|
160
|
+
export { asciiMinusInNumbers } from "./lib/clipboard-minus";
|
|
161
|
+
export { DEFAULT_DOCUMENT_TITLE_FORMAT, formatDocumentTitle } from "./lib/document-title";
|
|
162
|
+
export type { DocumentTitleParts } from "./lib/document-title";
|
|
157
163
|
export type { SwipeStage, RowSwipeOptions, RowSwipeReturn } from "./hooks/use-row-swipe";
|
|
158
164
|
// Any element as a file drop target, screened like FileButton (kastlan).
|
|
159
165
|
export { useFileDrop, dragHasFiles } from "./hooks/use-file-drop";
|
|
@@ -381,10 +387,15 @@ export * from "./components/alert-banner";
|
|
|
381
387
|
export * from "./components/toggle-group";
|
|
382
388
|
// A wrapping set of links/buttons marked `aria-current` — Tabs-like looks, not tabs.
|
|
383
389
|
export * from "./components/nav-pills";
|
|
390
|
+
// 0.49.0 (KIT-6): a section's pages on the phone, one scrolling row of pills.
|
|
391
|
+
export * from "./components/section-nav";
|
|
384
392
|
// A pill carrying one VALUE — inert, a link, or a toggle, depending on which prop it is
|
|
385
393
|
// given — and the list field built from it. Distinct from Button on purpose: a row of
|
|
386
394
|
// buttons reads as "choose an action", a row of chips as "here are the things".
|
|
387
395
|
export * from "./components/chip";
|
|
396
|
+
// 0.49.0 (KIT-8): five domain-free status kinds and their tones — Chip/StatusDot `status`.
|
|
397
|
+
export { statusTone, STATUS_KINDS } from "./lib/status-tone";
|
|
398
|
+
export type { StatusKind, StatusTone } from "./lib/status-tone";
|
|
388
399
|
// ChipInput's own module since MOD-9: it renders Chip, so chip.tsx re-exports only its types.
|
|
389
400
|
export * from "./components/chip-input";
|
|
390
401
|
export * from "./components/wizard-stepper";
|
|
@@ -589,6 +600,8 @@ export type {
|
|
|
589
600
|
RowActionsColumnOptions,
|
|
590
601
|
RowActionsHeadProps,
|
|
591
602
|
RowActionTone,
|
|
603
|
+
// 0.49 KIT-12: a danger action's confirmation words.
|
|
604
|
+
RowActionConfirm,
|
|
592
605
|
} from "./components/row-actions";
|
|
593
606
|
// 0.22.0: the inputs round (kastlan's, keksdose's and Kurvenschmiede's audits).
|
|
594
607
|
export * from "./components/checkbox-group";
|
|
@@ -77,12 +77,12 @@ export function LandingActions({
|
|
|
77
77
|
className={cn("flex flex-col gap-3 sm:flex-row", align === "center" && "sm:justify-center", className)}
|
|
78
78
|
>
|
|
79
79
|
{session === "user" ? (
|
|
80
|
-
<Button href={openAppHref} variant="
|
|
80
|
+
<Button href={openAppHref} variant="accent" size={buttonSize} className={extra}>
|
|
81
81
|
{labels.openApp}
|
|
82
82
|
</Button>
|
|
83
83
|
) : (
|
|
84
84
|
<>
|
|
85
|
-
<Button href={accessLink.href} variant="
|
|
85
|
+
<Button href={accessLink.href} variant="accent" size={buttonSize} className={extra}>
|
|
86
86
|
{accessLink.label}
|
|
87
87
|
</Button>
|
|
88
88
|
{demoHref !== null && (
|
|
@@ -82,7 +82,7 @@ export function PublicHeader({
|
|
|
82
82
|
|
|
83
83
|
const actions =
|
|
84
84
|
session === "user" ? (
|
|
85
|
-
<Button href={openAppHref} variant="
|
|
85
|
+
<Button href={openAppHref} variant="accent" size={size}>
|
|
86
86
|
{labels.openApp}
|
|
87
87
|
</Button>
|
|
88
88
|
) : (
|
|
@@ -96,7 +96,7 @@ export function PublicHeader({
|
|
|
96
96
|
{labels.signIn}
|
|
97
97
|
</Button>
|
|
98
98
|
)}
|
|
99
|
-
<Button href={accessLink.href} variant="
|
|
99
|
+
<Button href={accessLink.href} variant="accent" size={size}>
|
|
100
100
|
{accessLink.label}
|
|
101
101
|
</Button>
|
|
102
102
|
</>
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The copy handler for the one minus sign (0.49 KIT-1b, Marcel's follow-up to KIT-1).
|
|
3
|
+
*
|
|
4
|
+
* The kit prints a negative with U+2212 (lib/minus.ts). A spreadsheet does not read that
|
|
5
|
+
* as a number: a figure copied out of a kit table and pasted into Excel landed as text.
|
|
6
|
+
* So while a selection inside the page is copied, every U+2212 standing directly before a
|
|
7
|
+
* number — optionally after a currency code or symbol and spaces: "−CHF 1,250.50",
|
|
8
|
+
* "−€2,000", "−12%" — becomes the ASCII "-" in the clipboard, in `text/plain` AND in
|
|
9
|
+
* `text/html` (Excel pastes the HTML flavour, as cells). The page keeps "−".
|
|
10
|
+
*
|
|
11
|
+
* A copy with no such minus is left to the browser untouched, and so is any copy out of an
|
|
12
|
+
* input, a textarea or an editable element: what the person typed is theirs.
|
|
13
|
+
*
|
|
14
|
+
* Installed once per document by `UiKitProvider` (`copyAsciiMinus`, default `true`) —
|
|
15
|
+
* the one part every app mounts, the signed-out pages included.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** U+2212, then (optionally) a currency code or symbol, then spaces, then a digit. */
|
|
19
|
+
const MINUS_BEFORE_NUMBER = /\u2212(?=(?:[A-Z]{3}|\p{Sc})?[\s\u00a0\u202f]*\d)/gu;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `text` with each U+2212 that stands before a number (in the sense above) as the ASCII
|
|
23
|
+
* hyphen-minus, every other character as it was — for text an app hands a machine that
|
|
24
|
+
* did not come from a formatter's `minus: "ascii"`.
|
|
25
|
+
*/
|
|
26
|
+
export function asciiMinusInNumbers(text: string): string {
|
|
27
|
+
return text.replace(MINUS_BEFORE_NUMBER, "-");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function hasMinusBeforeNumber(text: string): boolean {
|
|
31
|
+
MINUS_BEFORE_NUMBER.lastIndex = 0;
|
|
32
|
+
const found = MINUS_BEFORE_NUMBER.test(text);
|
|
33
|
+
MINUS_BEFORE_NUMBER.lastIndex = 0;
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** An input, a textarea or an editable element: a copy there is the person's own text. */
|
|
38
|
+
function isEditable(node: Node | null | undefined): boolean {
|
|
39
|
+
const el = node instanceof Element ? node : node?.parentElement;
|
|
40
|
+
if (!el) return false;
|
|
41
|
+
if (el.closest("input, textarea, select")) return true;
|
|
42
|
+
return (el as HTMLElement).isContentEditable === true || el.closest('[contenteditable=""], [contenteditable="true"]') !== null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Table parts copied alone are wrapped back into a table, which Excel reads as cells. */
|
|
46
|
+
function wrapTableParts(container: HTMLElement): string {
|
|
47
|
+
const first = container.firstElementChild?.tagName;
|
|
48
|
+
const html = container.innerHTML;
|
|
49
|
+
if (first === "TD" || first === "TH") return `<table><tbody><tr>${html}</tr></tbody></table>`;
|
|
50
|
+
if (first === "TR") return `<table><tbody>${html}</tbody></table>`;
|
|
51
|
+
if (first === "TBODY" || first === "THEAD" || first === "TFOOT") return `<table>${html}</table>`;
|
|
52
|
+
return html;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function onCopy(event: ClipboardEvent): void {
|
|
56
|
+
if (event.defaultPrevented || !event.clipboardData) return;
|
|
57
|
+
const doc = (event.target as Node | null)?.ownerDocument ?? document;
|
|
58
|
+
if (isEditable(event.target as Node | null) || isEditable(doc.activeElement)) return;
|
|
59
|
+
const selection = doc.getSelection();
|
|
60
|
+
if (!selection || selection.rangeCount === 0 || selection.isCollapsed) return;
|
|
61
|
+
if (isEditable(selection.anchorNode) || isEditable(selection.focusNode)) return;
|
|
62
|
+
const text = selection.toString();
|
|
63
|
+
if (!hasMinusBeforeNumber(text)) return;
|
|
64
|
+
|
|
65
|
+
const container = doc.createElement("div");
|
|
66
|
+
for (let i = 0; i < selection.rangeCount; i++) container.appendChild(selection.getRangeAt(i).cloneContents());
|
|
67
|
+
const walker = doc.createTreeWalker(container, NodeFilter.SHOW_TEXT);
|
|
68
|
+
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
|
|
69
|
+
node.nodeValue = asciiMinusInNumbers(node.nodeValue ?? "");
|
|
70
|
+
}
|
|
71
|
+
event.clipboardData.setData("text/plain", asciiMinusInNumbers(text));
|
|
72
|
+
event.clipboardData.setData("text/html", wrapTableParts(container));
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const installs = new WeakMap<Document, number>();
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Listen for copies on `doc` until the returned function is called. Counted: nested
|
|
80
|
+
* providers install it once, and the last one to go removes it.
|
|
81
|
+
*/
|
|
82
|
+
export function installClipboardMinus(doc: Document = document): () => void {
|
|
83
|
+
const count = installs.get(doc) ?? 0;
|
|
84
|
+
if (count === 0) doc.addEventListener("copy", onCopy);
|
|
85
|
+
installs.set(doc, count + 1);
|
|
86
|
+
let done = false;
|
|
87
|
+
return () => {
|
|
88
|
+
if (done) return;
|
|
89
|
+
done = true;
|
|
90
|
+
const left = (installs.get(doc) ?? 1) - 1;
|
|
91
|
+
installs.set(doc, left);
|
|
92
|
+
if (left === 0) doc.removeEventListener("copy", onCopy);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A component's `data-*` props, for its root element (0.50, keksdose): `data-tour`,
|
|
3
|
+
* `data-testid` and the like reach the DOM even when the props are not spread there
|
|
4
|
+
* whole. TypeScript does not check hyphenated JSX attributes, so without this a
|
|
5
|
+
* `data-tour` on such a component vanished without an error.
|
|
6
|
+
*/
|
|
7
|
+
export type DataAttributes = { [attribute: `data-${string}`]: string | number | boolean | undefined };
|
|
8
|
+
|
|
9
|
+
/** Only the `data-*` entries of `props`. */
|
|
10
|
+
export function dataAttributes(props: object): DataAttributes {
|
|
11
|
+
const out: DataAttributes = {};
|
|
12
|
+
for (const [k, v] of Object.entries(props)) if (k.startsWith("data-")) out[k as `data-${string}`] = v;
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The window's title from its parts (0.49 KIT-9): `{page}`, `{section}` and `{app}` in a
|
|
3
|
+
* format, by default "{page} · {section} · {app}" — "Invoices · Finance · Kastlan".
|
|
4
|
+
*
|
|
5
|
+
* A part that is missing (undefined, null, empty or blank) is dropped WITH the separator
|
|
6
|
+
* before it, so "Invoices · Kastlan" never reads "Invoices · · Kastlan". The text between
|
|
7
|
+
* two parts is the separator; text before the first part and after the last is kept as
|
|
8
|
+
* written ("[{page} – {app}]" → "[KS]"). No part at all gives "".
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_DOCUMENT_TITLE_FORMAT = "{page} · {section} · {app}";
|
|
11
|
+
|
|
12
|
+
/** The parts {@link formatDocumentTitle} fills in. */
|
|
13
|
+
export interface DocumentTitleParts {
|
|
14
|
+
page?: string | null;
|
|
15
|
+
section?: string | null;
|
|
16
|
+
app?: string | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const PLACEHOLDER = /\{(page|section|app)\}/g;
|
|
20
|
+
|
|
21
|
+
export function formatDocumentTitle(format: string, parts: DocumentTitleParts): string {
|
|
22
|
+
let prefix = "";
|
|
23
|
+
let out = "";
|
|
24
|
+
let pending = "";
|
|
25
|
+
let last = 0;
|
|
26
|
+
let seen = false;
|
|
27
|
+
for (const m of format.matchAll(PLACEHOLDER)) {
|
|
28
|
+
const literal = format.slice(last, m.index!);
|
|
29
|
+
last = m.index! + m[0].length;
|
|
30
|
+
if (!seen) prefix = literal;
|
|
31
|
+
else pending = out === "" ? "" : literal || pending;
|
|
32
|
+
seen = true;
|
|
33
|
+
const value = parts[m[1] as keyof DocumentTitleParts]?.trim();
|
|
34
|
+
if (!value) continue;
|
|
35
|
+
out += (out === "" ? "" : pending) + value;
|
|
36
|
+
pending = "";
|
|
37
|
+
}
|
|
38
|
+
if (!seen) return format;
|
|
39
|
+
if (out === "") return "";
|
|
40
|
+
return prefix + out + format.slice(last);
|
|
41
|
+
}
|
|
@@ -2,7 +2,8 @@ import { useEffect } from "react";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The room the floating launchers take above the bottom nav, published as
|
|
5
|
-
* `--app-float-clearance` on `<html>` so `AppShell` can pad `<main>` past them
|
|
5
|
+
* `--app-float-clearance` on `<html>` so `AppShell` can pad `<main>` past them, and with
|
|
6
|
+
* the nav included as `--kit-floating-inset` (0.49 KIT-11, below).
|
|
6
7
|
*
|
|
7
8
|
* keksdose dev#612 (UX-1.3, "the help button covers content"): the shell padded `<main>`
|
|
8
9
|
* for the nav plus 1.5rem, so on a phone the last row of every page ended under the help
|
|
@@ -23,12 +24,27 @@ import { useEffect } from "react";
|
|
|
23
24
|
|
|
24
25
|
const claims = new Map<symbol, string>();
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* 0.49 KIT-11: `--kit-floating-inset` is the same room measured from the screen's bottom
|
|
29
|
+
* edge — the phone's bottom nav (`--app-nav-h`, 0px from `md` up) or the home indicator,
|
|
30
|
+
* whichever is taller, plus `--app-float-clearance` — so a page's own fixed or sticky
|
|
31
|
+
* footer, or its last row, can clear the launchers with one length at every width.
|
|
32
|
+
* Unset while no launcher is mounted, like `--app-float-clearance`: write
|
|
33
|
+
* `var(--kit-floating-inset, var(--app-nav-h, 0px))`.
|
|
34
|
+
*/
|
|
35
|
+
const NAV_OR_HOME_INDICATOR = "max(var(--app-nav-h, 0px), env(safe-area-inset-bottom, 0px))";
|
|
36
|
+
|
|
26
37
|
function publish() {
|
|
27
38
|
if (typeof document === "undefined") return;
|
|
28
39
|
const root = document.documentElement;
|
|
29
40
|
const values = [...claims.values()];
|
|
30
|
-
if (values.length === 0)
|
|
31
|
-
|
|
41
|
+
if (values.length === 0) {
|
|
42
|
+
root.style.removeProperty("--app-float-clearance");
|
|
43
|
+
root.style.removeProperty("--kit-floating-inset");
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
root.style.setProperty("--app-float-clearance", values.length === 1 ? values[0] : `max(${values.join(", ")})`);
|
|
47
|
+
root.style.setProperty("--kit-floating-inset", `calc(${NAV_OR_HOME_INDICATOR} + var(--app-float-clearance))`);
|
|
32
48
|
}
|
|
33
49
|
|
|
34
50
|
/** Claim `value` (a CSS length: the launcher's top edge above the nav, plus a gap) until
|