@eifi1/ui-kit 0.34.0 → 0.36.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 +115 -41
- package/dist/admin/role-select.d.ts +3 -2
- package/dist/admin/role-select.js +2 -0
- package/dist/admin/role-select.js.map +1 -1
- 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 +2 -5
- package/dist/components/amount-input.js +2 -2
- package/dist/components/amount-input.js.map +1 -1
- package/dist/components/autocomplete.d.ts +2 -2
- package/dist/components/autocomplete.js +2 -1
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/button-look.d.ts +1 -1
- package/dist/components/button-look.js +9 -4
- package/dist/components/button-look.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/checkbox-group.d.ts +5 -2
- package/dist/components/checkbox-group.js +15 -4
- package/dist/components/checkbox-group.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/column-mapper.d.ts +5 -3
- package/dist/components/column-mapper.js +2 -0
- package/dist/components/column-mapper.js.map +1 -1
- package/dist/components/combobox.d.ts +3 -3
- package/dist/components/combobox.js +2 -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/country-select.d.ts +3 -3
- package/dist/components/country-select.js +3 -0
- package/dist/components/country-select.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/currency-select.d.ts +3 -2
- package/dist/components/currency-select.js +10 -1
- package/dist/components/currency-select.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/date-field.d.ts +2 -1
- package/dist/components/date-field.js.map +1 -1
- package/dist/components/date-picker.js +3 -0
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/date-range-picker.js +3 -0
- package/dist/components/date-range-picker.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 +3 -3
- package/dist/components/entity-combobox.js +2 -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 +69 -22
- package/dist/components/field-parts.js +33 -19
- package/dist/components/field-parts.js.map +1 -1
- package/dist/components/field-strip.d.ts +9 -23
- package/dist/components/field-strip.js +26 -23
- 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 +7 -6
- package/dist/components/field.js +24 -15
- 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/help-popover.d.ts +9 -7
- package/dist/components/help-popover.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/icon-picker.d.ts +3 -2
- package/dist/components/icon-picker.js +3 -0
- package/dist/components/icon-picker.js.map +1 -1
- package/dist/components/inline-entity-combobox.d.ts +3 -3
- package/dist/components/inline-entity-combobox.js +2 -1
- package/dist/components/inline-entity-combobox.js.map +1 -1
- package/dist/components/input.d.ts +2 -2
- package/dist/components/input.js +2 -1
- package/dist/components/input.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/month-picker.d.ts +2 -1
- package/dist/components/month-picker.js +8 -1
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/multi-entity-combobox.d.ts +2 -2
- package/dist/components/multi-entity-combobox.js +2 -1
- package/dist/components/multi-entity-combobox.js.map +1 -1
- package/dist/components/multi-select.d.ts +7 -18
- package/dist/components/multi-select.js +8 -10
- package/dist/components/multi-select.js.map +1 -1
- package/dist/components/number-input.d.ts +2 -5
- package/dist/components/number-input.js +2 -4
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/numeric-field.d.ts +5 -2
- package/dist/components/numeric-field.js +4 -1
- package/dist/components/numeric-field.js.map +1 -1
- package/dist/components/one-time-code-input.d.ts +2 -1
- package/dist/components/one-time-code-input.js +2 -1
- package/dist/components/one-time-code-input.js.map +1 -1
- package/dist/components/phone-input.d.ts +1 -1
- package/dist/components/phone-input.js +4 -0
- package/dist/components/phone-input.js.map +1 -1
- package/dist/components/popover.js +3 -3
- package/dist/components/popover.js.map +1 -1
- package/dist/components/select.d.ts +4 -3
- package/dist/components/select.js +2 -1
- package/dist/components/select.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/slider.d.ts +3 -2
- package/dist/components/slider.js +7 -1
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stat-tile.d.ts +8 -2
- package/dist/components/stat-tile.js +2 -11
- package/dist/components/stat-tile.js.map +1 -1
- package/dist/components/swatch-picker.d.ts +3 -2
- package/dist/components/swatch-picker.js +3 -0
- package/dist/components/swatch-picker.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/text-link.js +3 -1
- package/dist/components/text-link.js.map +1 -1
- package/dist/components/textarea.d.ts +2 -1
- package/dist/components/textarea.js +9 -3
- package/dist/components/textarea.js.map +1 -1
- package/dist/components/toggle-group.d.ts +2 -2
- package/dist/components/toggle-group.js +7 -3
- package/dist/components/toggle-group.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/defaults.js +5 -1
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.js +97 -1
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +29 -4
- package/dist/i18n/kit-labels.js +21 -1
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +104 -3
- package/dist/i18n/locales/en.js.map +3 -3
- package/dist/i18n/locales/es.js +95 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +99 -3
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +95 -1
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +99 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +95 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +13 -0
- package/dist/i18n/review.js.map +1 -1
- package/dist/i18n/shared-labels.js +3 -1
- package/dist/i18n/shared-labels.js.map +1 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +40 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/device-settings.d.ts +72 -0
- package/dist/lib/device-settings.js +64 -0
- package/dist/lib/device-settings.js.map +1 -0
- package/dist/lib/plain-text.d.ts +11 -0
- package/dist/lib/plain-text.js +16 -0
- package/dist/lib/plain-text.js.map +1 -0
- 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/lib/safe-storage.d.ts +6 -0
- package/dist/lib/safe-storage.js +11 -0
- package/dist/lib/safe-storage.js.map +1 -1
- package/dist/notifications/notification-parts.d.ts +39 -0
- package/dist/notifications/notification-parts.js +47 -0
- package/dist/notifications/notification-parts.js.map +1 -0
- package/dist/notifications/notification-types-setting.d.ts +62 -0
- package/dist/notifications/notification-types-setting.js +192 -0
- package/dist/notifications/notification-types-setting.js.map +1 -0
- package/dist/notifications/notification-types.d.ts +75 -0
- package/dist/notifications/notification-types.js +2 -0
- package/dist/notifications/notification-types.js.map +1 -0
- package/dist/notifications/notifications-labels.d.ts +131 -0
- package/dist/notifications/notifications-labels.js +83 -0
- package/dist/notifications/notifications-labels.js.map +1 -0
- package/dist/notifications/push-device-setting.d.ts +37 -0
- package/dist/notifications/push-device-setting.js +164 -0
- package/dist/notifications/push-device-setting.js.map +1 -0
- package/dist/notifications/push-devices-setting.d.ts +44 -0
- package/dist/notifications/push-devices-setting.js +203 -0
- package/dist/notifications/push-devices-setting.js.map +1 -0
- package/dist/notifications/quiet-hours-setting.d.ts +47 -0
- package/dist/notifications/quiet-hours-setting.js +131 -0
- package/dist/notifications/quiet-hours-setting.js.map +1 -0
- package/dist/notifications/time-zone-select.d.ts +50 -0
- package/dist/notifications/time-zone-select.js +76 -0
- package/dist/notifications/time-zone-select.js.map +1 -0
- package/dist/notifications/unsubscribe-panel.d.ts +53 -0
- package/dist/notifications/unsubscribe-panel.js +139 -0
- package/dist/notifications/unsubscribe-panel.js.map +1 -0
- package/dist/notifications/use-push-device.d.ts +122 -0
- package/dist/notifications/use-push-device.js +230 -0
- package/dist/notifications/use-push-device.js.map +1 -0
- package/dist/rhf/fields.d.ts +36 -29
- package/dist/rhf/fields.js +51 -22
- 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/settings/device-reset-setting-labels.d.ts +3 -0
- package/dist/settings/device-reset-setting-labels.js +15 -0
- package/dist/settings/device-reset-setting-labels.js.map +1 -0
- package/dist/settings/device-reset-setting.d.ts +58 -0
- package/dist/settings/device-reset-setting.js +51 -0
- package/dist/settings/device-reset-setting.js.map +1 -0
- package/dist/shell/app-shell.js +5 -0
- package/dist/shell/app-shell.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/contrast-tokens.d.ts +42 -4
- package/dist/theme/contrast-tokens.js +56 -9
- package/dist/theme/contrast-tokens.js.map +1 -1
- package/dist/theme/contrast.d.ts +4 -2
- package/dist/theme/contrast.js +13 -0
- package/dist/theme/contrast.js.map +1 -1
- package/dist/theme/palette-derive.d.ts +15 -1
- package/dist/theme/palette-derive.js +37 -8
- package/dist/theme/palette-derive.js.map +1 -1
- package/dist/theme/palette-presets.d.ts +2 -8
- package/dist/theme/palette-presets.js +5 -284
- package/dist/theme/palette-presets.js.map +1 -1
- package/dist/theme/palette-store.js +6 -0
- package/dist/theme/palette-store.js.map +1 -1
- package/dist/theme/text-size.js +6 -0
- package/dist/theme/text-size.js.map +1 -1
- package/dist/theme/theme-store.js +6 -0
- package/dist/theme/theme-store.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/admin/role-select.tsx +4 -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 +4 -7
- package/src/components/autocomplete.tsx +5 -2
- package/src/components/button-look.ts +15 -5
- package/src/components/calculator.tsx +2 -7
- package/src/components/chart-zoom.tsx +4 -47
- package/src/components/checkbox-group.tsx +22 -4
- package/src/components/chip-input.tsx +0 -7
- package/src/components/column-mapper.tsx +6 -2
- package/src/components/combobox.tsx +6 -3
- package/src/components/copy-button.tsx +5 -1
- package/src/components/country-select.tsx +6 -1
- package/src/components/currency-option-list.tsx +8 -42
- package/src/components/currency-select.tsx +12 -3
- 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/date-field.tsx +2 -2
- package/src/components/date-picker.tsx +3 -0
- package/src/components/date-range-picker.tsx +3 -0
- package/src/components/dialog-frame.tsx +3 -1
- package/src/components/dropdown.tsx +42 -18
- package/src/components/entity-combobox.tsx +6 -3
- package/src/components/field-base.tsx +0 -11
- package/src/components/field-parts.tsx +112 -38
- package/src/components/field-strip.tsx +12 -27
- package/src/components/field-sync.tsx +0 -7
- package/src/components/field.tsx +32 -19
- package/src/components/full-bleed-dialog.tsx +4 -3
- package/src/components/help-popover.tsx +9 -7
- package/src/components/hover-menu.tsx +12 -16
- package/src/components/icon-picker.tsx +8 -3
- package/src/components/inline-entity-combobox.tsx +6 -3
- package/src/components/input.tsx +4 -2
- package/src/components/modal.tsx +20 -4
- package/src/components/month-picker.tsx +10 -3
- package/src/components/multi-entity-combobox.tsx +5 -2
- package/src/components/multi-select.tsx +19 -31
- package/src/components/number-input.tsx +5 -10
- package/src/components/numeric-field.ts +10 -2
- package/src/components/one-time-code-input.tsx +5 -3
- package/src/components/phone-input.tsx +4 -0
- package/src/components/popover.tsx +8 -4
- package/src/components/select.tsx +6 -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/slider.tsx +10 -3
- package/src/components/stat-tile.tsx +11 -20
- package/src/components/swatch-picker.tsx +9 -4
- package/src/components/swipeable-row.tsx +15 -37
- package/src/components/text-link.tsx +3 -1
- package/src/components/textarea.tsx +11 -4
- package/src/components/toggle-group.tsx +21 -5
- 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/defaults.ts +4 -0
- package/src/i18n/german.ts +113 -0
- package/src/i18n/kit-labels.tsx +66 -6
- package/src/i18n/locales/en.ts +6 -0
- package/src/i18n/locales/es.ts +106 -0
- package/src/i18n/locales/fr.ts +109 -2
- package/src/i18n/locales/hu.ts +104 -0
- package/src/i18n/locales/it.ts +108 -2
- package/src/i18n/locales/zh.ts +96 -0
- package/src/i18n/review.ts +13 -0
- package/src/i18n/shared-labels.ts +2 -0
- package/src/index.ts +53 -1
- package/src/lib/device-settings.ts +146 -0
- package/src/lib/plain-text.ts +22 -0
- package/src/lib/refs.ts +22 -0
- package/src/lib/safe-storage.ts +16 -0
- package/src/notifications/notification-parts.tsx +83 -0
- package/src/notifications/notification-types-setting.tsx +309 -0
- package/src/notifications/notification-types.ts +80 -0
- package/src/notifications/notifications-labels.ts +238 -0
- package/src/notifications/push-device-setting.tsx +224 -0
- package/src/notifications/push-devices-setting.tsx +306 -0
- package/src/notifications/quiet-hours-setting.tsx +185 -0
- package/src/notifications/time-zone-select.tsx +126 -0
- package/src/notifications/unsubscribe-panel.tsx +203 -0
- package/src/notifications/use-push-device.ts +392 -0
- package/src/rhf/fields.tsx +87 -39
- 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/settings/device-reset-setting-labels.ts +20 -0
- package/src/settings/device-reset-setting.tsx +119 -0
- package/src/shell/app-shell.tsx +8 -0
- 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/contrast-tokens.ts +106 -12
- package/src/theme/contrast.ts +30 -4
- package/src/theme/palette-derive.ts +68 -7
- package/src/theme/palette-presets.ts +16 -299
- package/src/theme/palette-store.ts +12 -0
- package/src/theme/text-size.ts +8 -0
- package/src/theme/theme-store.ts +10 -0
- package/src/wizard/types.ts +0 -8
- package/tokens.css +38 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { contrast, oklchToRgb, parseHex, rgbToOklch, toHex } from "./color";
|
|
1
|
+
import { contrast, hexToOklch, luminance, oklchToHex, oklchToRgb, parseHex, rgbToOklch, solveLightness, toHex } from "./color";
|
|
2
2
|
import type { TokenSet } from "./palette-presets";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -20,17 +20,48 @@ import type { TokenSet } from "./palette-presets";
|
|
|
20
20
|
* - `--border` moves toward `--text-primary` until it clears 3:1 against the worst of the
|
|
21
21
|
* three surfaces (WCAG 1.4.11, a field's boundary), and never less far than
|
|
22
22
|
* `--border-strong`'s 45 % — so every border is at least as strong as a "strong" one was.
|
|
23
|
-
* `--border-strong` stays derived in tokens.css and grows with it
|
|
23
|
+
* `--border-strong` stays derived in tokens.css and grows with it;
|
|
24
|
+
* - in a LIGHT set only (0.36, docs/colour-roles-harmonization.md §13): the well
|
|
25
|
+
* (`--bg-surface-2`) becomes {@link WELL_INK_MORE} of `--text-primary` mixed into the
|
|
26
|
+
* card, and each of the four money colours that falls under 4.5:1 on that well is
|
|
27
|
+
* solved darker at its own hue and chroma. The border above is solved against the
|
|
28
|
+
* stepped well. A dark set's well stands 1.11–1.13:1 from its card already, and its
|
|
29
|
+
* money has no room: nothing of it steps.
|
|
30
|
+
*
|
|
31
|
+
* What does NOT move here, because it is not inline: the light status, hue and field-sync
|
|
32
|
+
* literals and `--bg-active` step in tokens.css's `:root[data-contrast="more"]:not(.dark)`
|
|
33
|
+
* block, solved over these stepped wells.
|
|
24
34
|
*/
|
|
25
35
|
|
|
26
|
-
/** The custom properties a contrast step writes. */
|
|
27
|
-
export const CONTRAST_STEPPED_VARS = [
|
|
36
|
+
/** The custom properties a contrast step writes. The last five only for a light set. */
|
|
37
|
+
export const CONTRAST_STEPPED_VARS = [
|
|
38
|
+
"--text-secondary",
|
|
39
|
+
"--text-muted",
|
|
40
|
+
"--text-placeholder",
|
|
41
|
+
"--border",
|
|
42
|
+
"--bg-surface-2",
|
|
43
|
+
"--money-income",
|
|
44
|
+
"--money-expense",
|
|
45
|
+
"--money-net",
|
|
46
|
+
"--money-neutral",
|
|
47
|
+
] as const;
|
|
48
|
+
|
|
49
|
+
/** The light well under More contrast and the money that reads on it (§13.4). */
|
|
50
|
+
export interface WellStep {
|
|
51
|
+
bgSurface2: string;
|
|
52
|
+
moneyIncome: string;
|
|
53
|
+
moneyExpense: string;
|
|
54
|
+
moneyNet: string;
|
|
55
|
+
moneyNeutral: string;
|
|
56
|
+
}
|
|
28
57
|
|
|
29
58
|
export interface ContrastStep {
|
|
30
59
|
textSecondary: string;
|
|
31
60
|
textMuted: string;
|
|
32
61
|
textPlaceholder: string;
|
|
33
62
|
border: string;
|
|
63
|
+
/** The stepped well and money, or null for a dark set (which does not step them). */
|
|
64
|
+
well: WellStep | null;
|
|
34
65
|
}
|
|
35
66
|
|
|
36
67
|
interface Lab {
|
|
@@ -82,6 +113,63 @@ export function hoverFill(t: Pick<TokenSet, "textPrimary" | "bgSurface">): strin
|
|
|
82
113
|
return mix(t.textPrimary, t.bgSurface, HOVER_INK);
|
|
83
114
|
}
|
|
84
115
|
|
|
116
|
+
/**
|
|
117
|
+
* The light well under More contrast: this share of `--text-primary` mixed into the card,
|
|
118
|
+
* `--bg-hover`'s formula at a larger share (0.36, docs/colour-roles-harmonization.md §13).
|
|
119
|
+
*
|
|
120
|
+
* In light the well is the page (§5.3), 1.09–1.11:1 from the card. At 10 % it stands
|
|
121
|
+
* 1.19–1.24:1 from it, about twice that. The rule it is held to: **the stepped well stands
|
|
122
|
+
* at least 1.17:1 from the card**, two of the hover rule's 1.08 steps; 9 % is the least
|
|
123
|
+
* that clears it in every shipped preset, with no room. The step cannot ship alone: on a
|
|
124
|
+
* 10 % well money, status and two hues read 4.07–4.28:1, so the money is solved with it
|
|
125
|
+
* here and the status and hue literals in tokens.css.
|
|
126
|
+
*/
|
|
127
|
+
export const WELL_INK_MORE = 0.1;
|
|
128
|
+
|
|
129
|
+
/** The least the stepped light well stands from the card (§13.3, decision 2). */
|
|
130
|
+
export const WELL_STEP_MIN = 1.17;
|
|
131
|
+
|
|
132
|
+
/** True when `t` is a light set: its body ink darker than its card. */
|
|
133
|
+
function isLightSet(t: Pick<TokenSet, "textPrimary" | "bgSurface">): boolean | null {
|
|
134
|
+
const ink = parseHex(t.textPrimary);
|
|
135
|
+
const card = parseHex(t.bgSurface);
|
|
136
|
+
if (!ink || !card) return null;
|
|
137
|
+
return luminance(ink) < luminance(card);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Money as text: WCAG 1.4.3 AA. */
|
|
141
|
+
const MONEY_TARGET = 4.5;
|
|
142
|
+
|
|
143
|
+
/** `color` as it is when it clears 4.5:1 on `well`, else solved darker at its own hue and
|
|
144
|
+
* chroma until it does — measured on the hex (`solveLightness`). */
|
|
145
|
+
function moneyOn(color: string, well: string): string {
|
|
146
|
+
if (contrast(color, well) >= MONEY_TARGET) return color;
|
|
147
|
+
const lch = hexToOklch(color);
|
|
148
|
+
const bg = parseHex(well);
|
|
149
|
+
if (!lch || !bg) return color;
|
|
150
|
+
const l = solveLightness(MONEY_TARGET, bg, lch.h, lch.c, "darker");
|
|
151
|
+
return oklchToHex({ l, c: lch.c, h: lch.h });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** The light well under More contrast for `t`, or null for a dark set (or one whose ink or
|
|
155
|
+
* card is not hex, which cannot be mixed). The deriver solves the brand against it. */
|
|
156
|
+
export function steppedWellFill(t: Pick<TokenSet, "textPrimary" | "bgSurface">): string | null {
|
|
157
|
+
return isLightSet(t) ? mix(t.textPrimary, t.bgSurface, WELL_INK_MORE) : null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** The stepped well and money of a light set, or null (see {@link steppedWellFill}). */
|
|
161
|
+
function wellStep(t: TokenSet): WellStep | null {
|
|
162
|
+
const well = steppedWellFill(t);
|
|
163
|
+
if (!well) return null;
|
|
164
|
+
return {
|
|
165
|
+
bgSurface2: well,
|
|
166
|
+
moneyIncome: moneyOn(t.moneyIncome, well),
|
|
167
|
+
moneyExpense: moneyOn(t.moneyExpense, well),
|
|
168
|
+
moneyNet: moneyOn(t.moneyNet, well),
|
|
169
|
+
moneyNeutral: moneyOn(t.moneyNeutral, well),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
85
173
|
/**
|
|
86
174
|
* `--brand-muted` in tokens.css: this share of `--brand` mixed into `--text-primary`.
|
|
87
175
|
*
|
|
@@ -118,32 +206,38 @@ const BORDER_TARGET = 3;
|
|
|
118
206
|
/** `--border-strong` in tokens.css: 55 % border, 45 % text. */
|
|
119
207
|
const BORDER_STRONG_SHARE = 0.45;
|
|
120
208
|
|
|
121
|
-
|
|
122
|
-
|
|
209
|
+
/** The worst of the three surfaces; `well`, when the step has one, in place of the set's. */
|
|
210
|
+
function worstContrast(color: string, t: TokenSet, well: string): number {
|
|
211
|
+
return Math.min(contrast(color, t.bgPage), contrast(color, t.bgSurface), contrast(color, well));
|
|
123
212
|
}
|
|
124
213
|
|
|
125
|
-
function steppedBorder(t: TokenSet): string {
|
|
214
|
+
function steppedBorder(t: TokenSet, well: WellStep | null): string {
|
|
126
215
|
// The share of `--text-primary` in the border: at least --border-strong's, more until
|
|
127
216
|
// 3:1. Monotonic in the share (the mix walks from the border to the text, away from
|
|
128
|
-
// every surface), so a bisection finds the least that clears it.
|
|
217
|
+
// every surface), so a bisection finds the least that clears it. Against the stepped
|
|
218
|
+
// light well (§13.4), which is the darkest surface under More contrast.
|
|
219
|
+
const surface2 = well?.bgSurface2 ?? t.bgSurface2;
|
|
129
220
|
let lo = BORDER_STRONG_SHARE;
|
|
130
|
-
if (worstContrast(mix(t.border, t.textPrimary, 1 - lo), t) >= BORDER_TARGET) return mix(t.border, t.textPrimary, 1 - lo);
|
|
221
|
+
if (worstContrast(mix(t.border, t.textPrimary, 1 - lo), t, surface2) >= BORDER_TARGET) return mix(t.border, t.textPrimary, 1 - lo);
|
|
131
222
|
let hi = 1;
|
|
132
223
|
for (let i = 0; i < 16; i++) {
|
|
133
224
|
const mid = (lo + hi) / 2;
|
|
134
|
-
if (worstContrast(mix(t.border, t.textPrimary, 1 - mid), t) >= BORDER_TARGET) hi = mid;
|
|
225
|
+
if (worstContrast(mix(t.border, t.textPrimary, 1 - mid), t, surface2) >= BORDER_TARGET) hi = mid;
|
|
135
226
|
else lo = mid;
|
|
136
227
|
}
|
|
137
228
|
return mix(t.border, t.textPrimary, 1 - hi);
|
|
138
229
|
}
|
|
139
230
|
|
|
140
|
-
/** The
|
|
231
|
+
/** The stepped values for `t`: the four text and line tokens, and for a light set the
|
|
232
|
+
* well and money (`well`, null in dark). Pure. */
|
|
141
233
|
export function contrastStep(t: TokenSet): ContrastStep {
|
|
234
|
+
const well = wellStep(t);
|
|
142
235
|
return {
|
|
143
236
|
textSecondary: mix(t.textSecondary, t.textPrimary, 0.5),
|
|
144
237
|
textMuted: t.textSecondary,
|
|
145
238
|
textPlaceholder: t.textMuted,
|
|
146
|
-
border: steppedBorder(t),
|
|
239
|
+
border: steppedBorder(t, well),
|
|
240
|
+
well,
|
|
147
241
|
};
|
|
148
242
|
}
|
|
149
243
|
|
package/src/theme/contrast.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { create } from "zustand";
|
|
|
3
3
|
import { persist } from "zustand/middleware";
|
|
4
4
|
import { logger } from "../lib/logger";
|
|
5
5
|
import { readStored } from "../lib/safe-storage";
|
|
6
|
+
import { registerDeviceSetting } from "../lib/device-settings";
|
|
6
7
|
import { useMediaQuery } from "../hooks/use-media-query";
|
|
7
8
|
import { CONTRAST_STEPPED_VARS, contrastStep, rememberedTokenSet } from "./contrast-tokens";
|
|
8
9
|
import { applyTokenSet, DEFAULT_PRESET } from "./palette-presets";
|
|
@@ -16,8 +17,10 @@ import type { PersistedAppearanceOptions } from "./text-size";
|
|
|
16
17
|
* In force it is `<html data-contrast="more">` (else `"standard"`), which does two things:
|
|
17
18
|
* - the inline colour tokens are re-written one step stronger (`applyTokenSet`'s
|
|
18
19
|
* contrast flag — see contrast-tokens.ts for what moves and why it is JS);
|
|
19
|
-
* - tokens.css raises `--focus-ring-width` from 2 to 3 px
|
|
20
|
-
*
|
|
20
|
+
* - tokens.css raises `--focus-ring-width` from 2 to 3 px, in light deepens the status,
|
|
21
|
+
* hue and field-sync literals and `--bg-active` to read on the stepped well (0.36,
|
|
22
|
+
* colour-roles §13), and turns on the `contrast:` variant for anything else a
|
|
23
|
+
* component wants to change.
|
|
21
24
|
*
|
|
22
25
|
* The names below are frozen like the text size's: server-kit's `CONTRAST_MODES`, the
|
|
23
26
|
* stored format, the attribute.
|
|
@@ -75,8 +78,15 @@ export function readContrastLevel(): ContrastLevel {
|
|
|
75
78
|
*
|
|
76
79
|
* With a palette layer (`applyTokenSet` has written a set here), that set is applied
|
|
77
80
|
* again and steps itself. Without one — an app whose base tokens come from tokens.css,
|
|
78
|
-
* like Kurvenschmiede's — the
|
|
79
|
-
*
|
|
81
|
+
* like Kurvenschmiede's — the stepped tokens are written over the stylesheet for the
|
|
82
|
+
* default preset in the current light/dark, or removed again: the four text and line
|
|
83
|
+
* tokens in both modes, and in light the well and the four money colours too (0.36,
|
|
84
|
+
* docs/colour-roles-harmonization.md §13.3 decision 10). In dark those five stay removed,
|
|
85
|
+
* so the stylesheet's dark well and money paint.
|
|
86
|
+
*
|
|
87
|
+
* It never calls `applyTokenSet` here: that would remember a token set on `<html>`, and
|
|
88
|
+
* this app would then take the palette branch above, which a theme switch does not re-run
|
|
89
|
+
* (the class observer in `useApplyContrast` re-writes only while nothing is remembered).
|
|
80
90
|
*/
|
|
81
91
|
function reapplyContrastTokens(el: HTMLElement): void {
|
|
82
92
|
const written = rememberedTokenSet(el);
|
|
@@ -91,6 +101,14 @@ function reapplyContrastTokens(el: HTMLElement): void {
|
|
|
91
101
|
el.style.setProperty("--text-muted", step.textMuted);
|
|
92
102
|
el.style.setProperty("--text-placeholder", step.textPlaceholder);
|
|
93
103
|
el.style.setProperty("--border", step.border);
|
|
104
|
+
// One line per variable, not a loop: the step's fields are not the variables' names.
|
|
105
|
+
if (step.well) {
|
|
106
|
+
el.style.setProperty("--bg-surface-2", step.well.bgSurface2);
|
|
107
|
+
el.style.setProperty("--money-income", step.well.moneyIncome);
|
|
108
|
+
el.style.setProperty("--money-expense", step.well.moneyExpense);
|
|
109
|
+
el.style.setProperty("--money-net", step.well.moneyNet);
|
|
110
|
+
el.style.setProperty("--money-neutral", step.well.moneyNeutral);
|
|
111
|
+
}
|
|
94
112
|
}
|
|
95
113
|
|
|
96
114
|
/** Put `level` on `<html>` and re-write the colour tokens for it. */
|
|
@@ -197,6 +215,14 @@ export function createContrastStore(storageKey: string) {
|
|
|
197
215
|
"contrast",
|
|
198
216
|
),
|
|
199
217
|
);
|
|
218
|
+
// Reset this device's settings (docs/settings-harmonization.md §11.4): no choice on
|
|
219
|
+
// this device, so `useApplyContrast` re-resolves to the account's mode, else "system",
|
|
220
|
+
// and re-steps the tokens.
|
|
221
|
+
registerDeviceSetting({
|
|
222
|
+
key: storageKey,
|
|
223
|
+
kind: "appearance",
|
|
224
|
+
reset: () => useContrastStore.getState().setContrast(null),
|
|
225
|
+
});
|
|
200
226
|
|
|
201
227
|
function useApplyContrast({ account }: ApplyContrastOptions = {}): ContrastLevel {
|
|
202
228
|
const device = useContrastStore((s) => s.contrast);
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
solveLightness,
|
|
14
14
|
} from "./color";
|
|
15
15
|
import type { CvdType, Oklch } from "./color";
|
|
16
|
-
import {
|
|
16
|
+
import type { ContrastLevel } from "./contrast";
|
|
17
|
+
import { brandSoft, contrastStep, hoverFill, steppedWellFill, WELL_STEP_MIN } from "./contrast-tokens";
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Build a whole palette from one brand colour, plus any number of colours pinned by
|
|
@@ -104,6 +105,8 @@ export interface ContrastReport {
|
|
|
104
105
|
export interface DerivedPalette {
|
|
105
106
|
tokens: TokenSet;
|
|
106
107
|
semantic: SemanticTokens;
|
|
108
|
+
/** {@link auditPalette} at both contrast levels: the More-contrast checks carry a
|
|
109
|
+
* " (More contrast)" suffix (0.36). */
|
|
107
110
|
audit: ContrastReport;
|
|
108
111
|
/** Compromises the deriver had to make, in plain words. Never silent. */
|
|
109
112
|
warnings: string[];
|
|
@@ -310,15 +313,24 @@ export function derivePalette({
|
|
|
310
313
|
// ── Brand. Keep the hue the caller asked for; move only the lightness, and only as
|
|
311
314
|
// far as 3:1 against the worst surface — WCAG 1.4.11, since a brand-filled control is
|
|
312
315
|
// a graphical object whose boundary has to be perceivable.
|
|
316
|
+
//
|
|
317
|
+
// In light the worst surface includes More contrast's well (0.36, colour-roles §13.4):
|
|
318
|
+
// 10 % ink into the card, darker than the page. The step is applied, not derived, but
|
|
319
|
+
// the brand is not stepped, so both brand solves measure there too and a derived
|
|
320
|
+
// palette holds at both levels.
|
|
321
|
+
const moreWell = steppedWellFill({ textPrimary, bgSurface: surfaces.bgSurface });
|
|
322
|
+
const brandGround = moreWell
|
|
323
|
+
? [worstSurface, moreWell].reduce((a, b) => (contrast(a, "#000000") < contrast(b, "#000000") ? a : b))
|
|
324
|
+
: worstSurface;
|
|
313
325
|
const brandChroma = Math.max(brand.c, 0.06);
|
|
314
|
-
const brandRatio = contrast(anchors.brand,
|
|
326
|
+
const brandRatio = contrast(anchors.brand, brandGround);
|
|
315
327
|
// NORMALISED, never the caller's raw string. `parseHex` accepts "4f46e5" and "#abc",
|
|
316
328
|
// and passing either through unchanged put a value in the TokenSet that is not a CSS
|
|
317
329
|
// colour — it then fails silently at paint time, three layers from here.
|
|
318
330
|
let brandHex =
|
|
319
331
|
brandRatio >= 3
|
|
320
332
|
? toHex(parseHex(anchors.brand)!)
|
|
321
|
-
: solveAgainst(brand.h, brandChroma, 3,
|
|
333
|
+
: solveAgainst(brand.h, brandChroma, 3, brandGround, mode);
|
|
322
334
|
if (brandRatio < 3) {
|
|
323
335
|
warnings.push(
|
|
324
336
|
`brand ${anchors.brand} sits at ${brandRatio.toFixed(2)}:1 against the ${mode} surfaces, ` +
|
|
@@ -338,6 +350,8 @@ export function derivePalette({
|
|
|
338
350
|
contrast(soft.brandMuted, worstText),
|
|
339
351
|
contrast(soft.brandMuted, soft.brandBg),
|
|
340
352
|
contrast(soft.brandMuted, soft.brandBgHover),
|
|
353
|
+
// …and on More contrast's light well, where a link button reads it (§13.3).
|
|
354
|
+
moreWell ? contrast(soft.brandMuted, moreWell) : Infinity,
|
|
341
355
|
);
|
|
342
356
|
};
|
|
343
357
|
for (let i = 0; i < 40 && brandMutedWorst(brandHex) < 4.5; i++) {
|
|
@@ -525,7 +539,15 @@ export function derivePalette({
|
|
|
525
539
|
heat: deriveHeat(moneyIncome, moneyExpense, surfaces, mode),
|
|
526
540
|
};
|
|
527
541
|
|
|
528
|
-
|
|
542
|
+
// Audited at both contrast levels (0.36, colour-roles §13.5): More contrast steps the
|
|
543
|
+
// text, the border and, in light, the well and money of this set. The derived semantic
|
|
544
|
+
// colours are audited at Standard only: they are solved for the standard grounds, and
|
|
545
|
+
// only tokens.css's shipped literals step for the darker well.
|
|
546
|
+
const standard = auditPalette(tokens, semantic);
|
|
547
|
+
const more = auditPalette(tokens, undefined, { level: "more" });
|
|
548
|
+
const checks = [...standard.checks, ...more.checks];
|
|
549
|
+
const failures = checks.filter((c) => !c.passes);
|
|
550
|
+
return { tokens, semantic, audit: { checks, failures, passes: failures.length === 0 }, warnings };
|
|
529
551
|
}
|
|
530
552
|
|
|
531
553
|
/**
|
|
@@ -560,8 +582,40 @@ function deriveHeat(
|
|
|
560
582
|
* This is the part the shipped presets were missing. `derivePalette` runs it on the way
|
|
561
583
|
* out, and the preset test runs it over everything the package ships, so a palette that
|
|
562
584
|
* does not hold up cannot be merged with a comment claiming that it does.
|
|
585
|
+
*
|
|
586
|
+
* **`level: "more"`** (0.36, docs/colour-roles-harmonization.md §13.5) measures the set as
|
|
587
|
+
* More contrast paints it: the stepped secondary, muted and border, and in a light set the
|
|
588
|
+
* stepped well (as `bgSurface2`) and money — the same pairs, named with a " (More
|
|
589
|
+
* contrast)" suffix. Two things change with the level: the border is a field's boundary
|
|
590
|
+
* there, held to WCAG 1.4.11's 3:1 rather than the hairline's 1.1, and a light set's well
|
|
591
|
+
* must stand {@link WELL_STEP_MIN}:1 from the card. Pass `semantic` with tokens.css's More
|
|
592
|
+
* literals for a light set (the status colours step there); the status text is then
|
|
593
|
+
* measured on the stepped well too.
|
|
563
594
|
*/
|
|
564
|
-
export function auditPalette(
|
|
595
|
+
export function auditPalette(
|
|
596
|
+
set: TokenSet,
|
|
597
|
+
semantic?: SemanticTokens,
|
|
598
|
+
options: { level?: ContrastLevel } = {},
|
|
599
|
+
): ContrastReport {
|
|
600
|
+
const more = options.level === "more";
|
|
601
|
+
const step = more ? contrastStep(set) : null;
|
|
602
|
+
// The set as it paints at this level: what `applyTokenSet` writes for it.
|
|
603
|
+
const t: TokenSet = step
|
|
604
|
+
? {
|
|
605
|
+
...set,
|
|
606
|
+
textSecondary: step.textSecondary,
|
|
607
|
+
textMuted: step.textMuted,
|
|
608
|
+
border: step.border,
|
|
609
|
+
...(step.well && {
|
|
610
|
+
bgSurface2: step.well.bgSurface2,
|
|
611
|
+
moneyIncome: step.well.moneyIncome,
|
|
612
|
+
moneyExpense: step.well.moneyExpense,
|
|
613
|
+
moneyNet: step.well.moneyNet,
|
|
614
|
+
moneyNeutral: step.well.moneyNeutral,
|
|
615
|
+
}),
|
|
616
|
+
}
|
|
617
|
+
: set;
|
|
618
|
+
const suffix = more ? " (More contrast)" : "";
|
|
565
619
|
const checks: ContrastCheck[] = [];
|
|
566
620
|
const surfaces: Array<[string, string]> = [
|
|
567
621
|
["bgPage", t.bgPage],
|
|
@@ -585,12 +639,17 @@ export function auditPalette(t: TokenSet, semantic?: SemanticTokens): ContrastRe
|
|
|
585
639
|
const add = (pair: string, fg: string, bg: string, required: number, rule: string) => {
|
|
586
640
|
const ratio = contrast(fg, bg);
|
|
587
641
|
const slack = MIXED.test(pair) ? 0.05 : 0;
|
|
588
|
-
checks.push({ pair, ratio, required, rule, passes: ratio >= required - slack });
|
|
642
|
+
checks.push({ pair: pair + suffix, ratio, required, rule, passes: ratio >= required - slack });
|
|
589
643
|
};
|
|
590
644
|
|
|
591
645
|
for (const [name, bg] of surfaces) {
|
|
592
646
|
add(`brand on ${name}`, t.brand, bg, 3, "WCAG 1.4.11 graphical object");
|
|
593
|
-
add(`border on ${name}`, t.border, bg,
|
|
647
|
+
if (more) add(`border on ${name}`, t.border, bg, 3, "WCAG 1.4.11 — under More contrast a border bounds a field");
|
|
648
|
+
else add(`border on ${name}`, t.border, bg, 1.1, "house rule: a hairline must be findable");
|
|
649
|
+
}
|
|
650
|
+
// The stepped light well, a hex `applyTokenSet` writes (§13.3, decision 2).
|
|
651
|
+
if (step?.well) {
|
|
652
|
+
add("bgSurface2 on bgSurface", t.bgSurface2, t.bgSurface, WELL_STEP_MIN, "house rule: the well stands two hover steps from the card");
|
|
594
653
|
}
|
|
595
654
|
for (const [name, bg] of textGrounds) {
|
|
596
655
|
add(`textPrimary on ${name}`, t.textPrimary, bg, 7, "WCAG 1.4.6 AAA body text");
|
|
@@ -628,6 +687,8 @@ export function auditPalette(t: TokenSet, semantic?: SemanticTokens): ContrastRe
|
|
|
628
687
|
] as const) {
|
|
629
688
|
add(`${name} on bgSurface`, fg, t.bgSurface, 4.5, "WCAG 1.4.3 — rendered as text");
|
|
630
689
|
add(`${name} on bgHover`, fg, hover, 4.5, "WCAG 1.4.3 — rendered as text, on a hovered row");
|
|
690
|
+
// The darker light well the More literals were solved for (§13.3).
|
|
691
|
+
if (step?.well) add(`${name} on bgSurface2`, fg, t.bgSurface2, 4.5, "WCAG 1.4.3 — rendered as text, on the well");
|
|
631
692
|
}
|
|
632
693
|
add("danger on dangerBg", semantic.danger, semantic.dangerBg, 4.5, "WCAG 1.4.3 — badge text");
|
|
633
694
|
add("warning on warningBg", semantic.warning, semantic.warningBg, 4.5, "WCAG 1.4.3 — badge text");
|