@eifi1/ui-kit 0.32.0 → 0.32.1
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/dist/account/delete-account-setting.d.ts +1 -1
- package/dist/admin/admin-action-confirm.d.ts +1 -1
- package/dist/admin/admin-action-log.d.ts +1 -1
- package/dist/admin/admin-action-log.js +4 -2
- package/dist/admin/admin-action-log.js.map +1 -1
- package/dist/admin/invitations-panel.d.ts +1 -1
- package/dist/admin/reviewer-scope-editor.d.ts +1 -1
- package/dist/admin/role-select.d.ts +1 -1
- package/dist/admin/transfer-ownership-dialog.d.ts +1 -1
- package/dist/admin/user-roster.d.ts +1 -1
- package/dist/auth/register-form.d.ts +1 -1
- package/dist/billing/billing-banner.d.ts +1 -1
- package/dist/billing/billing-labels.d.ts +1 -1
- package/dist/billing/billing-labels.js +3 -1
- package/dist/billing/billing-labels.js.map +1 -1
- package/dist/billing/billing-lock.d.ts +1 -1
- package/dist/billing/billing-standing.d.ts +1 -1
- package/dist/billing/plan-card.d.ts +1 -1
- package/dist/billing/plan-card.js +1 -1
- package/dist/billing/plan-card.js.map +1 -1
- package/dist/billing/plan-limit-notice.d.ts +1 -1
- package/dist/billing/subscription-actions.d.ts +1 -1
- package/dist/billing/subscription-status-chip.d.ts +1 -1
- package/dist/chart.d.ts +2 -2
- package/dist/chart.js.map +1 -1
- package/dist/components/alert-banner.js +1 -1
- package/dist/components/alert-banner.js.map +1 -1
- package/dist/components/amount-input.d.ts +1 -1
- package/dist/components/appearance-labels.d.ts +6 -0
- package/dist/components/appearance-labels.js +2 -1
- package/dist/components/appearance-labels.js.map +1 -1
- package/dist/components/button-group.d.ts +1 -1
- package/dist/components/button-group.js +7 -1
- package/dist/components/button-group.js.map +1 -1
- package/dist/components/calculator.d.ts +1 -1
- package/dist/components/chip.js +7 -2
- package/dist/components/chip.js.map +1 -1
- package/dist/components/choice-card.js +1 -1
- package/dist/components/choice-card.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +1 -1
- package/dist/components/copy-button.d.ts +1 -1
- package/dist/components/danger-confirm.d.ts +1 -1
- package/dist/components/data-table-pagination.d.ts +2 -1
- package/dist/components/data-table-pagination.js +15 -6
- package/dist/components/data-table-pagination.js.map +1 -1
- package/dist/components/data-table.js +2 -2
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.js +11 -1
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/facing-pair.d.ts +1 -1
- package/dist/components/file-button.d.ts +1 -1
- package/dist/components/file-dropzone.d.ts +1 -1
- package/dist/components/form-actions.d.ts +1 -1
- package/dist/components/iban-input.d.ts +1 -1
- package/dist/components/inline-edit-field.js +4 -1
- package/dist/components/inline-edit-field.js.map +1 -1
- package/dist/components/language-select.d.ts +1 -1
- package/dist/components/legal-page.d.ts +1 -1
- package/dist/components/legal.d.ts +1 -1
- package/dist/components/money-field.d.ts +1 -1
- package/dist/components/month-picker.js +41 -34
- package/dist/components/month-picker.js.map +1 -1
- package/dist/components/number-field.d.ts +1 -1
- package/dist/components/number-input.d.ts +1 -1
- package/dist/components/numpad-sheet.d.ts +1 -1
- package/dist/components/phone-input.d.ts +1 -1
- package/dist/components/phone-input.js +2 -2
- package/dist/components/phone-input.js.map +1 -1
- package/dist/components/row-actions.d.ts +1 -1
- package/dist/components/row-actions.js +103 -37
- package/dist/components/row-actions.js.map +1 -1
- package/dist/components/series-chart.d.ts +1 -1
- package/dist/components/settings-fields.d.ts +7 -3
- package/dist/components/settings-fields.js +2 -1
- package/dist/components/settings-fields.js.map +1 -1
- package/dist/components/share-card.d.ts +1 -1
- package/dist/components/share-card.js +6 -2
- package/dist/components/share-card.js.map +1 -1
- package/dist/components/status-dot.js +9 -2
- package/dist/components/status-dot.js.map +1 -1
- package/dist/components/swipeable-row.js +8 -1
- package/dist/components/swipeable-row.js.map +1 -1
- package/dist/components/text-link.d.ts +1 -1
- package/dist/components/time-input.d.ts +1 -1
- package/dist/components/toggle-group.d.ts +9 -2
- package/dist/components/toggle-group.js +3 -3
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/translation-review-editor.js +1 -1
- 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/ui.d.ts +1 -1
- package/dist/components/ui.js +5 -5
- package/dist/components/ui.js.map +1 -1
- package/dist/components/wizard-stepper.js +20 -14
- package/dist/components/wizard-stepper.js.map +1 -1
- package/dist/{delete-account-setting-BvdQdbv3.d.ts → delete-account-setting-FLyJf-kZ.d.ts} +43 -8
- package/dist/feedback/feedback-attachment.d.ts +1 -1
- package/dist/feedback/feedback-context.d.ts +1 -1
- package/dist/feedback/feedback-crash.d.ts +1 -1
- package/dist/feedback/feedback-dialog.d.ts +1 -1
- package/dist/feedback/feedback-inbox.d.ts +1 -1
- package/dist/feedback/feedback-labels.d.ts +1 -1
- package/dist/feedback/feedback-menu.d.ts +1 -1
- package/dist/feedback/feedback-record.d.ts +1 -1
- package/dist/feedback/feedback-row-detail.d.ts +1 -1
- package/dist/feedback/feedback-status-undo.d.ts +1 -1
- package/dist/feedback/feedback-submit.d.ts +1 -1
- package/dist/feedback/feedback-swipe.d.ts +1 -1
- package/dist/feedback/feedback-table.d.ts +1 -1
- package/dist/feedback/feedback-thread.d.ts +1 -1
- package/dist/feedback.d.ts +1 -1
- package/dist/hooks/use-breakpoint.d.ts +19 -8
- package/dist/hooks/use-breakpoint.js +1 -1
- package/dist/hooks/use-breakpoint.js.map +1 -1
- package/dist/hooks/use-file-drop.d.ts +1 -1
- package/dist/i18n/defaults.d.ts +1 -1
- package/dist/i18n/german.d.ts +1 -1
- package/dist/i18n/german.js +7 -3
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +1 -1
- package/dist/i18n/languages.d.ts +1 -1
- package/dist/i18n/locales/de-CH.d.ts +1 -1
- package/dist/i18n/locales/en.d.ts +1 -1
- package/dist/i18n/locales/es.d.ts +1 -1
- package/dist/i18n/locales/es.js +7 -3
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +1 -1
- package/dist/i18n/locales/fr.js +7 -3
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +1 -1
- package/dist/i18n/locales/hu.js +7 -3
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +1 -1
- package/dist/i18n/locales/it.js +7 -3
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +1 -1
- package/dist/i18n/locales/zh.js +7 -3
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.d.ts +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/landing/landing-actions.d.ts +1 -1
- package/dist/landing/landing-sections.d.ts +1 -1
- package/dist/landing/landing-sections.js +7 -3
- package/dist/landing/landing-sections.js.map +1 -1
- package/dist/landing/public-header.d.ts +1 -1
- package/dist/landing/routing.d.ts +1 -1
- package/dist/rhf/fields.d.ts +1 -1
- package/dist/rhf/form.d.ts +1 -1
- package/dist/rhf.d.ts +1 -1
- package/dist/settings/settings-section.d.ts +1 -1
- package/dist/settings/use-account-appearance.d.ts +1 -1
- package/dist/settings/use-account-appearance.js.map +1 -1
- package/dist/shell/app-shell.d.ts +1 -1
- package/dist/shell/top-bar-brand.d.ts +1 -1
- package/dist/shell.d.ts +1 -1
- package/dist/theme/contrast.d.ts +3 -2
- package/dist/theme/contrast.js.map +1 -1
- package/dist/theme/text-size.d.ts +19 -3
- package/dist/theme/text-size.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +1 -1
- package/dist/wizard/wizard-summary.js +1 -1
- package/dist/wizard/wizard-summary.js.map +1 -1
- package/dist/wizard.d.ts +1 -1
- package/package.json +1 -1
- package/src/admin/admin-action-log.tsx +6 -1
- package/src/billing/billing-labels.ts +16 -0
- package/src/billing/plan-card.tsx +1 -1
- package/src/chart.ts +2 -0
- package/src/components/alert-banner.tsx +5 -1
- package/src/components/appearance-labels.ts +7 -0
- package/src/components/button-group.tsx +21 -0
- package/src/components/chip.tsx +34 -6
- package/src/components/choice-card.tsx +1 -1
- package/src/components/data-table-pagination.tsx +60 -31
- package/src/components/data-table.tsx +8 -4
- package/src/components/date-picker.tsx +32 -1
- package/src/components/inline-edit-field.tsx +20 -1
- package/src/components/month-picker.tsx +6 -1
- package/src/components/phone-input.tsx +7 -2
- package/src/components/row-actions.tsx +155 -49
- package/src/components/settings-fields.tsx +8 -3
- package/src/components/share-card.tsx +21 -2
- package/src/components/status-dot.tsx +25 -2
- package/src/components/swipeable-row.tsx +8 -1
- package/src/components/toggle-group.tsx +26 -12
- package/src/components/translation-review-editor.tsx +1 -1
- package/src/components/translation-review.tsx +5 -4
- package/src/components/ui.tsx +22 -8
- package/src/components/wizard-stepper.tsx +5 -1
- package/src/hooks/use-breakpoint.ts +20 -9
- package/src/i18n/german.ts +4 -0
- package/src/i18n/locales/es.ts +4 -0
- package/src/i18n/locales/fr.ts +4 -0
- package/src/i18n/locales/hu.ts +4 -0
- package/src/i18n/locales/it.ts +4 -0
- package/src/i18n/locales/zh.ts +4 -0
- package/src/index.ts +4 -2
- package/src/landing/landing-sections.tsx +7 -3
- package/src/settings/use-account-appearance.ts +1 -1
- package/src/theme/contrast.ts +3 -2
- package/src/theme/text-size.ts +19 -3
- package/src/wizard/wizard-summary.tsx +4 -2
- package/tokens.css +15 -7
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
DISABLED_REASON_LINE_CLASS,
|
|
10
10
|
FIELD_CAPTION_CLASS,
|
|
11
11
|
hasContent,
|
|
12
|
+
isTextHint,
|
|
12
13
|
LabelStrip,
|
|
13
14
|
useDisabledReasonLine,
|
|
14
15
|
useInlineHint,
|
|
@@ -130,8 +131,15 @@ export interface ToggleGroupBaseProps<T extends string>
|
|
|
130
131
|
* two stack and both keep their corners.
|
|
131
132
|
*/
|
|
132
133
|
chromeClassName?: string;
|
|
133
|
-
/**
|
|
134
|
-
*
|
|
134
|
+
/**
|
|
135
|
+
* As on a labelled {@link Select}: a {@link FieldHint} "?" on the label line, and plain
|
|
136
|
+
* text (a string) as a caption under the group. Only with `label`.
|
|
137
|
+
*
|
|
138
|
+
* 0.32.1 (keksdose's 0.32 report): text went on the label line in every placement, so
|
|
139
|
+
* `TextSizeSetting`'s hint with `labelPlacement="above"` sat beside the label in body
|
|
140
|
+
* type, and at Extra large became a column one word wide — on the setting a reader who
|
|
141
|
+
* needs large text opens first. The label line holds the "?" only (`isTextHint`).
|
|
142
|
+
*/
|
|
135
143
|
hint?: ReactNode;
|
|
136
144
|
/** The message under the field when it is wrong: paints the field's border with
|
|
137
145
|
* `--danger`, marks the group `aria-invalid` and describes it with the message, as
|
|
@@ -196,9 +204,9 @@ const CHROME_PAD: Record<"sm" | "md", string> = { md: "pt-5 pb-0.5", sm: "pt-5 p
|
|
|
196
204
|
const CHROME_SEGMENT: Record<"sm" | "md", string> = { md: "py-0 leading-[1.125rem]", sm: "py-0 leading-4" };
|
|
197
205
|
|
|
198
206
|
/**
|
|
199
|
-
* A
|
|
207
|
+
* A group at Large and Extra large (0.32,
|
|
200
208
|
* docs/text-size-harmonization.md §4 "nothing truncates", §3.3): the segments flow onto a
|
|
201
|
-
* second row inside the
|
|
209
|
+
* second row inside the group's frame instead of overflowing it. At 125 % a 390 px phone
|
|
202
210
|
* is 312 px of Normal type, and "Month / Quarter / Half-year / Year" in one row of the
|
|
203
211
|
* field ran 7 px past it: a one-row flex group is as wide as all its labels end to end
|
|
204
212
|
* when a grid or a stretched column asks how small it can get, however its segments
|
|
@@ -212,12 +220,16 @@ const CHROME_SEGMENT: Record<"sm" | "md", string> = { md: "py-0 leading-[1.125re
|
|
|
212
220
|
* Only where it has to: `flex-wrap` breaks a row only when the segments do not fit, so
|
|
213
221
|
* a wide field at Large stays one row, and a segment shares out what its row leaves
|
|
214
222
|
* (`flex-1`); a label wider than the whole row still truncates as the last resort.
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
223
|
+
* A `large:` class, so it costs no render and is right on the first paint.
|
|
224
|
+
* `overflow="wrap"` wraps at every size already.
|
|
225
|
+
*
|
|
226
|
+
* 0.32.1 (Kurvenschmiede's 0.32 report): every count and every placement but the
|
|
227
|
+
* strip, not only a field of four or more. Since a row breaks only where its labels do
|
|
228
|
+
* not fit, a wrap only ever replaces a truncation — and three options in a card at
|
|
229
|
+
* Extra large on a 360 px phone read "Syst… Li… D…". The strip keeps one row: its
|
|
230
|
+
* 26 px group is what lines it up with the 42 px fields beside it (`STRIP_SEGMENT`).
|
|
218
231
|
*/
|
|
219
232
|
const WRAP_AT_LARGE = "large:flex-wrap";
|
|
220
|
-
const WRAP_AT_LARGE_FROM = 4;
|
|
221
233
|
|
|
222
234
|
/**
|
|
223
235
|
* The strip placement's segments: a 26px group (1 + 2 + 20 + 2 + 1) under the 16px
|
|
@@ -335,9 +347,10 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
335
347
|
const locked = hasContent(disabledReason);
|
|
336
348
|
// §4: at Large and on touch the reason is a line under the group, not a bubble.
|
|
337
349
|
const reasonLine = useDisabledReasonLine(disabledReasonDisplay) && locked;
|
|
338
|
-
// §4: likewise a FieldHint "?" on the label line becomes a caption under the group
|
|
350
|
+
// §4: likewise a FieldHint "?" on the label line becomes a caption under the group at
|
|
351
|
+
// Large and on touch; text is a caption at every size, as Select's (see `hint`).
|
|
339
352
|
const inlineHint = useInlineHint(hint);
|
|
340
|
-
const hintAsCaption = inlineHint !== hint ? inlineHint : undefined;
|
|
353
|
+
const hintAsCaption = isTextHint(hint) ? hint : inlineHint !== hint ? inlineHint : undefined;
|
|
341
354
|
const labelHint = hintAsCaption === undefined ? hint : undefined;
|
|
342
355
|
// Locked looks disabled — the dimmed group, the not-allowed cursor, no hover offer —
|
|
343
356
|
// but stays focusable; `disabled` alone also takes the segments out of the tab order.
|
|
@@ -346,10 +359,11 @@ export function ToggleGroup<T extends string>(props: ToggleGroupProps<T>): React
|
|
|
346
359
|
// `field` is the chrome; a label placed above or in a strip keeps the bare group's
|
|
347
360
|
// own box.
|
|
348
361
|
const field = labelled && labelPlacement === "field";
|
|
349
|
-
// At Large and Extra large a FIELD of four or more options wraps (see WRAP_AT_LARGE).
|
|
350
|
-
const wrapAtLarge = field && overflow === "truncate" && options.length >= WRAP_AT_LARGE_FROM;
|
|
351
362
|
const above = labelled && labelPlacement === "above";
|
|
352
363
|
const strip = labelled && labelPlacement === "strip";
|
|
364
|
+
// At Large and Extra large a truncating group wraps instead, the strip excepted (see
|
|
365
|
+
// WRAP_AT_LARGE).
|
|
366
|
+
const wrapAtLarge = overflow === "truncate" && !strip;
|
|
353
367
|
const hasError = labelled && hasContent(error);
|
|
354
368
|
// Taken off the rest so neither reaches the DOM; `props` keeps them paired, which is
|
|
355
369
|
// what lets the `onChange` below be called with `null` only in the mode that allows it.
|
|
@@ -150,7 +150,7 @@ export function TranslationReviewEditor({
|
|
|
150
150
|
<div className={cn("min-w-0 space-y-3 text-sm", className)}>
|
|
151
151
|
<code className="block break-all text-xs text-[var(--text-muted)]">{row.key}</code>
|
|
152
152
|
|
|
153
|
-
<div className="grid gap-3 md:grid-cols-2">
|
|
153
|
+
<div className="grid grid-cols-1 gap-3 md:grid-cols-2">
|
|
154
154
|
<div className="min-w-0">
|
|
155
155
|
<SectionLabel as="span" size="xs">
|
|
156
156
|
{referenceLabel}
|
|
@@ -2,7 +2,7 @@ import { useEffect, useId, useMemo, useRef, useState } from "react";
|
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
3
|
import { Check, ListChecks, PencilLine, RotateCcw } from "lucide-react";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { usePhoneLayout } from "../hooks/use-breakpoint";
|
|
6
6
|
import { useKitLabels, useKitLocale } from "../i18n/kit-labels";
|
|
7
7
|
import { cn } from "../lib/cn";
|
|
8
8
|
import {
|
|
@@ -458,9 +458,10 @@ export function TranslationReviewPanel({
|
|
|
458
458
|
const labels = useKitLabels("translationReview", DEFAULT_TRANSLATION_REVIEW_LABELS, labelsProp);
|
|
459
459
|
const locale = useKitLocale();
|
|
460
460
|
const lock = useWriteLock();
|
|
461
|
-
// The
|
|
462
|
-
//
|
|
463
|
-
|
|
461
|
+
// The phone layout DataTable switches its layout on, so "a phone" means the same here
|
|
462
|
+
// as in the table, at every text size: `usePhoneLayout()` itself (§10.4; 0.32.1,
|
|
463
|
+
// keksdose's 0.32 report — `!useBreakpoint("md")` could disagree with it at 767.5 px).
|
|
464
|
+
const phone = usePhoneLayout();
|
|
464
465
|
const baseId = useId();
|
|
465
466
|
const rootRef = useRef<HTMLDivElement>(null);
|
|
466
467
|
const editable = !readOnly && onSave !== undefined;
|
package/src/components/ui.tsx
CHANGED
|
@@ -3218,8 +3218,14 @@ export interface CardHeaderProps extends ComponentPropsWithoutRef<"div"> {
|
|
|
3218
3218
|
* description instead of beside them. For an action that is wider than an icon —
|
|
3219
3219
|
* a "Set up two-factor" button, a checkbox and a filter — which, kept in the
|
|
3220
3220
|
* top-end column on a 390px phone, squeezed the title into a ribbon two words wide
|
|
3221
|
-
* (keksdose's settings cards). Off by default: an icon action (the wizard
|
|
3222
|
-
* pencil) is narrow enough to stay beside the title at every width.
|
|
3221
|
+
* (keksdose's settings cards). Off by default at Normal: an icon action (the wizard
|
|
3222
|
+
* summary's pencil) is narrow enough to stay beside the title at every width.
|
|
3223
|
+
*
|
|
3224
|
+
* Unset, it stacks at Large and Extra large only (0.32.1, the 360 px Extra-large
|
|
3225
|
+
* sweep; docs/text-size-harmonization.md §4): there an IconButton shows its label as
|
|
3226
|
+
* text, so the "icon" action is a word-wide pill, and "Refresh sessions" beside
|
|
3227
|
+
* "Sessions" ran 47 px past a 360 px phone. `false` keeps the action beside the title
|
|
3228
|
+
* at every size, for an action the caller knows stays narrow (`labelVisible={false}`).
|
|
3223
3229
|
*/
|
|
3224
3230
|
stackAction?: boolean;
|
|
3225
3231
|
}
|
|
@@ -3239,7 +3245,18 @@ export type CardActionProps = ComponentPropsWithoutRef<"div">;
|
|
|
3239
3245
|
export type CardContentProps = ComponentPropsWithoutRef<"div">;
|
|
3240
3246
|
export type CardFooterProps = ComponentPropsWithoutRef<"div">;
|
|
3241
3247
|
|
|
3242
|
-
|
|
3248
|
+
/** {@link CardHeaderProps.stackAction}: one column under `sm`, and the action back into
|
|
3249
|
+
* the flow (DOM order, so after the description when it is written after it), at the
|
|
3250
|
+
* start edge. The descendant selector outranks CardAction's own placement classes. */
|
|
3251
|
+
const CARD_STACK_ACTION =
|
|
3252
|
+
"max-sm:grid-cols-1 max-sm:[&>[data-slot=card-action]]:col-start-1 max-sm:[&>[data-slot=card-action]]:row-span-1 max-sm:[&>[data-slot=card-action]]:row-start-auto max-sm:[&>[data-slot=card-action]]:justify-self-start";
|
|
3253
|
+
/** The same at Large and Extra large only — `stackAction` unset (see its note). A
|
|
3254
|
+
* `large:` class over the scaled `max-sm`, so it costs no render and is right on the
|
|
3255
|
+
* first paint. */
|
|
3256
|
+
const CARD_STACK_ACTION_AT_LARGE =
|
|
3257
|
+
"large:max-sm:grid-cols-1 large:max-sm:[&>[data-slot=card-action]]:col-start-1 large:max-sm:[&>[data-slot=card-action]]:row-span-1 large:max-sm:[&>[data-slot=card-action]]:row-start-auto large:max-sm:[&>[data-slot=card-action]]:justify-self-start";
|
|
3258
|
+
|
|
3259
|
+
export function CardHeader({ className, stackAction, ...props }: CardHeaderProps) {
|
|
3243
3260
|
const padded = useContext(CardPaddedContext);
|
|
3244
3261
|
const compact = useContext(CardDensityContext) === "compact";
|
|
3245
3262
|
return (
|
|
@@ -3261,11 +3278,8 @@ export function CardHeader({ className, stackAction = false, ...props }: CardHea
|
|
|
3261
3278
|
"grid auto-rows-min items-start gap-1.5 [--card-header-cols:1fr] has-data-[slot=card-action]:[--card-header-cols:1fr_auto] grid-cols-[var(--card-header-cols,1fr)]",
|
|
3262
3279
|
padded ? "px-0 pt-0" : "px-6 pt-6",
|
|
3263
3280
|
compact && "gap-0.5",
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
// The descendant selector outranks CardAction's own placement classes.
|
|
3267
|
-
stackAction &&
|
|
3268
|
-
"max-sm:grid-cols-1 max-sm:[&>[data-slot=card-action]]:col-start-1 max-sm:[&>[data-slot=card-action]]:row-span-1 max-sm:[&>[data-slot=card-action]]:row-start-auto max-sm:[&>[data-slot=card-action]]:justify-self-start",
|
|
3281
|
+
stackAction === true && CARD_STACK_ACTION,
|
|
3282
|
+
stackAction === undefined && CARD_STACK_ACTION_AT_LARGE,
|
|
3269
3283
|
className,
|
|
3270
3284
|
)}
|
|
3271
3285
|
{...props}
|
|
@@ -13,7 +13,11 @@ export function WizardStepper({
|
|
|
13
13
|
}) {
|
|
14
14
|
const currentIndex = steps.findIndex((s) => s.key === current);
|
|
15
15
|
return (
|
|
16
|
-
|
|
16
|
+
// `flex-wrap`: the steps flow onto a second line rather than past the screen
|
|
17
|
+
// (0.32.1, the 360 px Extra-large sweep; docs/text-size-harmonization.md §4).
|
|
18
|
+
// "Upload — Map columns — Confirm" ran 22 px past a 360 px phone at Extra large.
|
|
19
|
+
// Where the steps fit, they stay one row.
|
|
20
|
+
<ol className="flex flex-wrap items-center gap-1 text-xs" aria-label={ariaLabel}>
|
|
17
21
|
{steps.map((step, i) => (
|
|
18
22
|
<li key={step.key} className="flex items-center gap-1">
|
|
19
23
|
{i > 0 && <span className="w-4 border-t border-[var(--border)]" />}
|
|
@@ -82,21 +82,32 @@ export function lengthPx(length: number | RemLength | undefined, rootRemPx: numb
|
|
|
82
82
|
/**
|
|
83
83
|
* The media query a breakpoint variant means at `scale` (`TEXT_SCALE` of the size in
|
|
84
84
|
* force). `"md"` → `(min-width: 768px)` at Normal, `(min-width: 960px)` at Large;
|
|
85
|
-
* `"max-md"` → `(
|
|
86
|
-
*
|
|
87
|
-
*
|
|
85
|
+
* `"max-md"` → `(width < 768px)` at Normal. In px, scaled by the browser's own default
|
|
86
|
+
* font size as well, so a person who set 20 px in the browser gets 960 px for `md` at
|
|
87
|
+
* Normal — as the CSS does.
|
|
88
88
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
89
|
+
* `max-*` is written in range syntax, `(width < N)`, against the same `N` its `min-*`
|
|
90
|
+
* twin starts at, so the two are exact complements at EVERY width: exactly one of
|
|
91
|
+
* `md` and `max-md` matches, as with tokens.css's `width >= 48rem` / `width < 48rem`
|
|
92
|
+
* (and Tailwind's own `max-*`). Until 0.32.1 it was `(max-width: 767px)`, which left a
|
|
93
|
+
* gap: on a fractional viewport width (767.5 px under zoom or at some Android
|
|
94
|
+
* device-pixel ratios) neither query matched, so DataTable, asking `!md`, said phone
|
|
95
|
+
* while `usePhoneLayout()`, asking `max-md`, said not (0.32.1, keksdose's 0.32 report;
|
|
96
|
+
* docs/text-size-harmonization.md §3.3: "the CSS and JS answers always agree").
|
|
97
|
+
*
|
|
98
|
+
* Range syntax in media queries is Chrome / Edge 104, Firefox 63, Safari 16.4. That is
|
|
99
|
+
* inside the floor the kit already sets: tokens.css's breakpoint variants are written in
|
|
100
|
+
* it, and Tailwind v4 itself needs Safari 16.4, Chrome 111 and Firefox 128.
|
|
101
|
+
*
|
|
102
|
+
* A test's `matchMedia` stub that keyed on the old string (`"max-width: 767px"`, the
|
|
103
|
+
* deprecated `PHONE_QUERY`) has to answer `(width < 768px)` now. `min-*` is unchanged,
|
|
104
|
+
* character for character.
|
|
94
105
|
*/
|
|
95
106
|
export function breakpointQuery(variant: BreakpointVariant, scale = 1, remPx: number = readBrowserRemPx()): string {
|
|
96
107
|
const max = variant.startsWith("max-");
|
|
97
108
|
const name = (max ? variant.slice(4) : variant) as Breakpoint;
|
|
98
109
|
const px = Math.round(BREAKPOINT_REM[name] * remPx * scale);
|
|
99
|
-
return max ? `(
|
|
110
|
+
return max ? `(width < ${px}px)` : `(min-width: ${px}px)`;
|
|
100
111
|
}
|
|
101
112
|
|
|
102
113
|
/**
|
package/src/i18n/german.ts
CHANGED
|
@@ -1203,6 +1203,7 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
1203
1203
|
deletion_request: "Löschung beantragt",
|
|
1204
1204
|
deletion_cancel: "Löschung aufgehoben",
|
|
1205
1205
|
erase: "Konto endgültig gelöscht",
|
|
1206
|
+
plan: "Tarif geändert",
|
|
1206
1207
|
},
|
|
1207
1208
|
},
|
|
1208
1209
|
transferOwnership: {
|
|
@@ -1533,6 +1534,8 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
1533
1534
|
: `${n(count)} Änderungen warten auf einen Tarif`,
|
|
1534
1535
|
// "Verwerfen", as `wizard.cancelConfirmLabel`.
|
|
1535
1536
|
discardWaiting: "Wartende Änderungen verwerfen",
|
|
1537
|
+
notConfigured: "Zahlungen sind noch nicht eingerichtet. Bitte versuchen Sie es später noch einmal.",
|
|
1538
|
+
disabled: "Abonnements sind hier nicht verfügbar.",
|
|
1536
1539
|
},
|
|
1537
1540
|
// 0.32.0 — docs/text-size-harmonization.md §6: the text-size and contrast settings in
|
|
1538
1541
|
// the "Darstellung" group.
|
|
@@ -1544,6 +1547,7 @@ export function germanLabels(numberLocale: string): UiKitLabels {
|
|
|
1544
1547
|
contrastHelp:
|
|
1545
1548
|
"Mehr Kontrast macht dezente Texte und Linien dunkler und Fokusrahmen dicker. „System“ richtet sich nach diesem Gerät.",
|
|
1546
1549
|
contrastModes: { system: "System", standard: "Standard", more: "Mehr" },
|
|
1550
|
+
saveFailed: "Konnte nicht in Ihrem Konto gespeichert werden. Auf diesem Gerät gilt es trotzdem.",
|
|
1547
1551
|
},
|
|
1548
1552
|
rowActions: {
|
|
1549
1553
|
actions: "Aktionen",
|
package/src/i18n/locales/es.ts
CHANGED
|
@@ -1175,6 +1175,7 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
1175
1175
|
deletion_request: "Eliminación solicitada",
|
|
1176
1176
|
deletion_cancel: "Eliminación cancelada",
|
|
1177
1177
|
erase: "Cuenta borrada",
|
|
1178
|
+
plan: "Plan cambiado",
|
|
1178
1179
|
},
|
|
1179
1180
|
},
|
|
1180
1181
|
transferOwnership: {
|
|
@@ -1489,6 +1490,8 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
1489
1490
|
waitingChanges: (count) => `${n(count)} ${plural(count, "cambio", "cambios")} a la espera de un plan`,
|
|
1490
1491
|
// "Descartar", as `wizard.cancelConfirmLabel`.
|
|
1491
1492
|
discardWaiting: "Descartar los cambios en espera",
|
|
1493
|
+
notConfigured: "Los pagos aún no están configurados. Inténtelo de nuevo más tarde.",
|
|
1494
|
+
disabled: "Las suscripciones no están disponibles aquí.",
|
|
1492
1495
|
},
|
|
1493
1496
|
// 0.32.0 — docs/text-size-harmonization.md §6: the text-size and contrast settings in
|
|
1494
1497
|
// the "Apariencia" group.
|
|
@@ -1500,6 +1503,7 @@ export function uiKitLabelsEs(numberLocale = "es-ES"): UiKitLabels {
|
|
|
1500
1503
|
contrastHelp:
|
|
1501
1504
|
"El contraste aumentado oscurece los textos tenues y las líneas, y engrosa los marcos de foco. «Sistema» sigue el ajuste de este dispositivo.",
|
|
1502
1505
|
contrastModes: { system: "Sistema", standard: "Estándar", more: "Aumentado" },
|
|
1506
|
+
saveFailed: "No se ha podido guardar en su cuenta. En este dispositivo se aplica igualmente.",
|
|
1503
1507
|
},
|
|
1504
1508
|
rowActions: {
|
|
1505
1509
|
actions: "Acciones",
|
package/src/i18n/locales/fr.ts
CHANGED
|
@@ -1201,6 +1201,7 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
1201
1201
|
deletion_request: "Suppression demandée",
|
|
1202
1202
|
deletion_cancel: "Suppression annulée",
|
|
1203
1203
|
erase: "Compte effacé",
|
|
1204
|
+
plan: "Formule modifiée",
|
|
1204
1205
|
},
|
|
1205
1206
|
},
|
|
1206
1207
|
transferOwnership: {
|
|
@@ -1521,6 +1522,8 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
1521
1522
|
`${n(count)} ${plural(count, "modification en attente", "modifications en attente")} d’une formule`,
|
|
1522
1523
|
// "Abandonner", as `wizard.cancelConfirmLabel`.
|
|
1523
1524
|
discardWaiting: "Abandonner les modifications en attente",
|
|
1525
|
+
notConfigured: "Les paiements ne sont pas encore configurés. Veuillez réessayer plus tard.",
|
|
1526
|
+
disabled: "Les abonnements ne sont pas disponibles ici.",
|
|
1524
1527
|
},
|
|
1525
1528
|
// 0.32.0 — docs/text-size-harmonization.md §6: the text-size and contrast settings in
|
|
1526
1529
|
// the "Apparence" group. The steps agree with "taille", the modes with "contraste".
|
|
@@ -1532,6 +1535,7 @@ export function uiKitLabelsFr(numberLocale = "fr-FR"): UiKitLabels {
|
|
|
1532
1535
|
contrastHelp:
|
|
1533
1536
|
"Le contraste renforcé assombrit les textes discrets et les lignes, et épaissit les contours de focus. «\u202fSystème\u202f» suit le réglage de cet appareil.",
|
|
1534
1537
|
contrastModes: { system: "Système", standard: "Standard", more: "Renforcé" },
|
|
1538
|
+
saveFailed: "Impossible de l’enregistrer dans votre compte. Le réglage s’applique tout de même sur cet appareil.",
|
|
1535
1539
|
},
|
|
1536
1540
|
rowActions: {
|
|
1537
1541
|
actions: "Actions",
|
package/src/i18n/locales/hu.ts
CHANGED
|
@@ -1178,6 +1178,7 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
1178
1178
|
deletion_request: "Törlés kérelmezve",
|
|
1179
1179
|
deletion_cancel: "Törlés visszavonva",
|
|
1180
1180
|
erase: "Fiók véglegesen törölve",
|
|
1181
|
+
plan: "Csomag módosítva",
|
|
1181
1182
|
},
|
|
1182
1183
|
},
|
|
1183
1184
|
transferOwnership: {
|
|
@@ -1493,6 +1494,8 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
1493
1494
|
waitingChanges: (count) => `${n(count)} módosítás csomagra vár`,
|
|
1494
1495
|
// "Elvetés", as `wizard.cancelConfirmLabel`.
|
|
1495
1496
|
discardWaiting: "Várakozó módosítások elvetése",
|
|
1497
|
+
notConfigured: "A fizetés még nincs beállítva. Kérjük, próbálja újra később.",
|
|
1498
|
+
disabled: "Az előfizetés itt nem érhető el.",
|
|
1496
1499
|
},
|
|
1497
1500
|
// 0.32.0 — docs/text-size-harmonization.md §6: the text-size and contrast settings in
|
|
1498
1501
|
// the "Megjelenés" group.
|
|
@@ -1504,6 +1507,7 @@ export function uiKitLabelsHu(numberLocale = "hu-HU"): UiKitLabels {
|
|
|
1504
1507
|
contrastHelp:
|
|
1505
1508
|
"A fokozott kontraszt sötétebbé teszi a halvány szövegeket és vonalakat, a fókuszkereteket pedig vastagabbá. A „Rendszer” ennek az eszköznek a beállítását követi.",
|
|
1506
1509
|
contrastModes: { system: "Rendszer", standard: "Normál", more: "Fokozott" },
|
|
1510
|
+
saveFailed: "Nem sikerült menteni a fiókjába. Ezen az eszközön ettől még érvényes.",
|
|
1507
1511
|
},
|
|
1508
1512
|
rowActions: {
|
|
1509
1513
|
actions: "Műveletek",
|
package/src/i18n/locales/it.ts
CHANGED
|
@@ -1184,6 +1184,7 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
1184
1184
|
deletion_request: "Eliminazione richiesta",
|
|
1185
1185
|
deletion_cancel: "Eliminazione annullata",
|
|
1186
1186
|
erase: "Account cancellato",
|
|
1187
|
+
plan: "Piano modificato",
|
|
1187
1188
|
},
|
|
1188
1189
|
},
|
|
1189
1190
|
transferOwnership: {
|
|
@@ -1505,6 +1506,8 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
1505
1506
|
`${n(count)} ${plural(count, "modifica in attesa", "modifiche in attesa")} di un piano`,
|
|
1506
1507
|
// "Scarta", as `wizard.cancelConfirmLabel`.
|
|
1507
1508
|
discardWaiting: "Scarta le modifiche in attesa",
|
|
1509
|
+
notConfigured: "I pagamenti non sono ancora configurati. Riprovi più tardi.",
|
|
1510
|
+
disabled: "Gli abbonamenti non sono disponibili qui.",
|
|
1508
1511
|
},
|
|
1509
1512
|
// 0.32.0 — docs/text-size-harmonization.md §6: the text-size and contrast settings in
|
|
1510
1513
|
// the "Aspetto" group.
|
|
@@ -1516,6 +1519,7 @@ export function uiKitLabelsIt(numberLocale = "it-IT"): UiKitLabels {
|
|
|
1516
1519
|
contrastHelp:
|
|
1517
1520
|
"Il contrasto aumentato scurisce i testi tenui e le linee e ispessisce i riquadri di focus. «Sistema» segue l’impostazione di questo dispositivo.",
|
|
1518
1521
|
contrastModes: { system: "Sistema", standard: "Standard", more: "Aumentato" },
|
|
1522
|
+
saveFailed: "Non è stato possibile salvarlo nel Suo account. Su questo dispositivo vale comunque.",
|
|
1519
1523
|
},
|
|
1520
1524
|
rowActions: {
|
|
1521
1525
|
actions: "Azioni",
|
package/src/i18n/locales/zh.ts
CHANGED
|
@@ -1131,6 +1131,7 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
1131
1131
|
deletion_request: "已申请删除",
|
|
1132
1132
|
deletion_cancel: "已取消删除",
|
|
1133
1133
|
erase: "账户已永久删除",
|
|
1134
|
+
plan: "套餐已更改",
|
|
1134
1135
|
},
|
|
1135
1136
|
},
|
|
1136
1137
|
transferOwnership: {
|
|
@@ -1429,6 +1430,8 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
1429
1430
|
waitingChanges: (count) => `${n(count)} 项修改正在等待套餐`,
|
|
1430
1431
|
// "放弃", as `wizard.cancelConfirmLabel`.
|
|
1431
1432
|
discardWaiting: "放弃等待中的修改",
|
|
1433
|
+
notConfigured: "付款尚未设置,请稍后再试。",
|
|
1434
|
+
disabled: "此处不提供订阅。",
|
|
1432
1435
|
},
|
|
1433
1436
|
// 0.32.0 — docs/text-size-harmonization.md §6: the text-size and contrast settings in
|
|
1434
1437
|
// the "外观" group.
|
|
@@ -1439,6 +1442,7 @@ export function uiKitLabelsZh(numberLocale = "zh-CN"): UiKitLabels {
|
|
|
1439
1442
|
contrast: "对比度",
|
|
1440
1443
|
contrastHelp: "增强对比度会加深浅色文字和线条,并加粗焦点框。“跟随系统”沿用此设备的设置。",
|
|
1441
1444
|
contrastModes: { system: "跟随系统", standard: "标准", more: "增强" },
|
|
1445
|
+
saveFailed: "无法保存到您的账户。此设备上仍然生效。",
|
|
1442
1446
|
},
|
|
1443
1447
|
rowActions: {
|
|
1444
1448
|
actions: "操作",
|
package/src/index.ts
CHANGED
|
@@ -173,6 +173,8 @@ export type {
|
|
|
173
173
|
} from "./components/file-button";
|
|
174
174
|
export * from "./components/treemap";
|
|
175
175
|
export * from "./components/series-chart";
|
|
176
|
+
// 0.32.1 (keksdose's 0.32 report): the height every chart takes, for an app's wrappers.
|
|
177
|
+
export type { ChartHeight } from "./components/chart-height";
|
|
176
178
|
export * from "./components/chart-zoom";
|
|
177
179
|
export * from "./components/toggle-legend";
|
|
178
180
|
export * from "./components/facing-pair";
|
|
@@ -759,8 +761,8 @@ export type {
|
|
|
759
761
|
// ── 0.32.0: text size and contrast (docs/text-size-harmonization.md) ──
|
|
760
762
|
export * from "./theme/text-size";
|
|
761
763
|
export * from "./theme/contrast";
|
|
762
|
-
export { useBreakpoint, usePhoneLayout, breakpointQuery, BREAKPOINT_REM } from "./hooks/use-breakpoint";
|
|
763
|
-
export type { Breakpoint, BreakpointVariant } from "./hooks/use-breakpoint";
|
|
764
|
+
export { useBreakpoint, usePhoneLayout, breakpointQuery, BREAKPOINT_REM, remPx, useRemPx } from "./hooks/use-breakpoint";
|
|
765
|
+
export type { Breakpoint, BreakpointVariant, RemLength } from "./hooks/use-breakpoint";
|
|
764
766
|
export { useAccountAppearance, resolveAccountAppearance } from "./settings/use-account-appearance";
|
|
765
767
|
export type {
|
|
766
768
|
AppearanceSource,
|
|
@@ -97,7 +97,11 @@ export function Hero({
|
|
|
97
97
|
{...rest}
|
|
98
98
|
data-slot="landing-hero"
|
|
99
99
|
className={cn(
|
|
100
|
-
|
|
100
|
+
// `grid-cols-1` below `lg` (0.32.1, Kurvenschmiede's 0.32 report): without a
|
|
101
|
+
// template the one column is `auto` and grows to the visual's longest unwrapped
|
|
102
|
+
// line — 80 px past a 360 px phone at Extra large. `minmax(0, 1fr)` holds it to
|
|
103
|
+
// the page. The same in FeatureRow and TrustStrip.
|
|
104
|
+
"mx-auto grid max-w-6xl grid-cols-1 items-center gap-12 px-4 py-16 sm:py-24",
|
|
101
105
|
visual != null && "lg:grid-cols-2",
|
|
102
106
|
className,
|
|
103
107
|
)}
|
|
@@ -186,7 +190,7 @@ export function FeatureRow({
|
|
|
186
190
|
<div
|
|
187
191
|
{...rest}
|
|
188
192
|
data-slot="landing-feature-row"
|
|
189
|
-
className={cn("group/feature grid items-center gap-8 py-10", visual != null && "lg:grid-cols-2 lg:gap-16", className)}
|
|
193
|
+
className={cn("group/feature grid grid-cols-1 items-center gap-8 py-10", visual != null && "lg:grid-cols-2 lg:gap-16", className)}
|
|
190
194
|
>
|
|
191
195
|
<div className="lg:group-even/feature:order-last">
|
|
192
196
|
{(icon != null || eyebrow != null) && (
|
|
@@ -245,7 +249,7 @@ export interface TrustStripProps extends Omit<ComponentPropsWithoutRef<"section"
|
|
|
245
249
|
export function TrustStrip({ items, headingAs: Heading = "h3", className, ...rest }: TrustStripProps) {
|
|
246
250
|
return (
|
|
247
251
|
<section {...rest} data-slot="landing-trust" className={cn("mx-auto max-w-6xl px-4 py-12 sm:py-16", className)}>
|
|
248
|
-
<ul className={cn("grid gap-8 sm:grid-cols-2", items.length === 3 ? "lg:grid-cols-3" : "lg:grid-cols-4")}>
|
|
252
|
+
<ul className={cn("grid grid-cols-1 gap-8 sm:grid-cols-2", items.length === 3 ? "lg:grid-cols-3" : "lg:grid-cols-4")}>
|
|
249
253
|
{items.map((item, i) => (
|
|
250
254
|
<li key={i}>
|
|
251
255
|
{item.icon != null && (
|
|
@@ -79,7 +79,7 @@ export interface UseAccountAppearanceOptions {
|
|
|
79
79
|
export interface AccountAppearance extends ResolvedAccountAppearance {
|
|
80
80
|
/** The user picked a size: it becomes the device's choice and — signed in, and not a
|
|
81
81
|
* demo — the account's. The promise is `save`'s; the device keeps the pick if it
|
|
82
|
-
* fails, and the app says so. */
|
|
82
|
+
* fails, and the app says so (`appearance.saveFailed`, 0.32.1). */
|
|
83
83
|
pickTextSize: (size: TextSize) => Promise<unknown>;
|
|
84
84
|
/** As {@link pickTextSize}, for the contrast mode. */
|
|
85
85
|
pickContrast: (mode: ContrastMode) => Promise<unknown>;
|
package/src/theme/contrast.ts
CHANGED
|
@@ -130,9 +130,10 @@ export function readPersistedContrast(storageKey: string): ContrastMode | null {
|
|
|
130
130
|
/**
|
|
131
131
|
* Pre-paint (§10.3, §10.5): this device's choice under `storageKey` — else the account's
|
|
132
132
|
* last known value, else "system" — resolved against `prefers-contrast` and applied
|
|
133
|
-
* BEFORE `createRoot`. Call it next to `applyPersistedPalette`, in
|
|
133
|
+
* BEFORE `createRoot`. Call it next to `applyPersistedPalette`, in EITHER order — the
|
|
134
134
|
* palette steps itself when `data-contrast` is already set, and this re-applies the
|
|
135
|
-
* palette's set when it is not
|
|
135
|
+
* palette's set when it is not; no app has to put one first (0.32.1, keksdose's 0.32
|
|
136
|
+
* report asked which). Returns the level applied.
|
|
136
137
|
*/
|
|
137
138
|
export function applyPersistedContrast(storageKey: string, options: PersistedAppearanceOptions = {}): ContrastLevel {
|
|
138
139
|
let account: unknown;
|
package/src/theme/text-size.ts
CHANGED
|
@@ -119,6 +119,11 @@ export function useTextSize(): TextSizeInfo {
|
|
|
119
119
|
*
|
|
120
120
|
* `size` is one of {@link TEXT_SIZES}, or `null` / absent when this device never chose.
|
|
121
121
|
* A future change adds a key; it never renames `state.size` or changes its values.
|
|
122
|
+
*
|
|
123
|
+
* A hand-written seed (a test, a screenshot script) must carry `"version":1`: the store
|
|
124
|
+
* drops a stored state of another version as a migration it doesn't know, silently
|
|
125
|
+
* (keksdose's 0.32 report). The inline snippet reads `state.size` whatever the version,
|
|
126
|
+
* so the two would disagree. In the kit's showcase, `?text-size=` needs no seed.
|
|
122
127
|
*/
|
|
123
128
|
export interface PersistedTextSize {
|
|
124
129
|
state?: { size?: TextSize | null };
|
|
@@ -189,9 +194,20 @@ export function applyPersistedTextSize(storageKey: string, options: PersistedApp
|
|
|
189
194
|
* ```
|
|
190
195
|
*
|
|
191
196
|
* Paste the constant's value in place of `(function(k,a){…})`. It reads the frozen
|
|
192
|
-
* {@link PersistedTextSize} format, never throws, and sets only `data-text-size
|
|
193
|
-
*
|
|
194
|
-
*
|
|
197
|
+
* {@link PersistedTextSize} format, never throws, and sets only `data-text-size`.
|
|
198
|
+
*
|
|
199
|
+
* The splash sizes in rem, and needs the root rules inline beside it, since the app's
|
|
200
|
+
* stylesheet is a separate request and arrives after the splash paints (0.32.1,
|
|
201
|
+
* keksdose's 0.32 report: that is every app, not an edge case):
|
|
202
|
+
*
|
|
203
|
+
* ```html
|
|
204
|
+
* <style>html[data-text-size=large]{font-size:125%}html[data-text-size=xlarge]{font-size:150%}</style>
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* Under a hash-based Content Security Policy (`script-src 'sha256-…'`) this is a second
|
|
208
|
+
* inline script with its own hash: add it to the policy, and recompute it whenever the
|
|
209
|
+
* storage key or the account function in the call changes (keksdose added it to both
|
|
210
|
+
* its Caddyfiles, and its guard test hashes every inline script).
|
|
195
211
|
*/
|
|
196
212
|
export const TEXT_SIZE_INLINE_SCRIPT =
|
|
197
213
|
"(function(k,a){function ok(v){return v==='normal'||v==='large'||v==='xlarge'}" +
|
|
@@ -40,8 +40,10 @@ export function WizardSummary({
|
|
|
40
40
|
<Card key={sIdx}>
|
|
41
41
|
{/* CardHeader is a grid, and CardAction is the top-right column it
|
|
42
42
|
reserves — the edit button has to go through it or it stacks under
|
|
43
|
-
the title instead of sitting beside it.
|
|
44
|
-
|
|
43
|
+
the title instead of sitting beside it. `stackAction={false}`: the pencil
|
|
44
|
+
is named by `aria-label` and stays an icon at Large, so it keeps its
|
|
45
|
+
place beside the title there too (0.32.1). */}
|
|
46
|
+
<CardHeader className="pb-2" stackAction={false}>
|
|
45
47
|
<CardTitle className="text-base">{section.label}</CardTitle>
|
|
46
48
|
{section.stepIndex !== undefined && onEditStep && (
|
|
47
49
|
<CardAction>
|
package/tokens.css
CHANGED
|
@@ -693,10 +693,18 @@ body {
|
|
|
693
693
|
.animate-drill { animation-name: overlay-fade-in; }
|
|
694
694
|
}
|
|
695
695
|
|
|
696
|
-
/* Scrollbars: keep light defaults; theme to
|
|
696
|
+
/* Scrollbars: keep light defaults; theme to the palette when dark mode is active.
|
|
697
|
+
*
|
|
698
|
+
* From the tokens, not literals (0.32.1, keksdose's 0.32 report): the thumb is a border
|
|
699
|
+
* (`--border`) on the page (`--bg-page`), so a palette preset carries through, and so
|
|
700
|
+
* does More contrast (§5), which steps `--border` until it clears 3:1 against every
|
|
701
|
+
* surface, the page among them: WCAG 1.4.11's floor for a control's visible part. At
|
|
702
|
+
* standard contrast it is as quiet as the slate-700-on-slate-900 it replaces (1.5:1
|
|
703
|
+
* against 1.7:1 in the default dark preset). Hover takes `--border-strong`, the border
|
|
704
|
+
* pulled toward the text, which grows with it. */
|
|
697
705
|
.dark {
|
|
698
706
|
color-scheme: dark;
|
|
699
|
-
scrollbar-color:
|
|
707
|
+
scrollbar-color: var(--border) var(--bg-page);
|
|
700
708
|
}
|
|
701
709
|
|
|
702
710
|
.dark ::-webkit-scrollbar {
|
|
@@ -705,19 +713,19 @@ body {
|
|
|
705
713
|
}
|
|
706
714
|
|
|
707
715
|
.dark ::-webkit-scrollbar-track {
|
|
708
|
-
background-color:
|
|
716
|
+
background-color: var(--bg-page);
|
|
709
717
|
}
|
|
710
718
|
|
|
711
719
|
.dark ::-webkit-scrollbar-thumb {
|
|
712
|
-
background-color:
|
|
720
|
+
background-color: var(--border);
|
|
713
721
|
border-radius: 6px;
|
|
714
|
-
border: 2px solid
|
|
722
|
+
border: 2px solid var(--bg-page); /* the track's colour: inset padding */
|
|
715
723
|
}
|
|
716
724
|
|
|
717
725
|
.dark ::-webkit-scrollbar-thumb:hover {
|
|
718
|
-
background-color:
|
|
726
|
+
background-color: var(--border-strong);
|
|
719
727
|
}
|
|
720
728
|
|
|
721
729
|
.dark ::-webkit-scrollbar-corner {
|
|
722
|
-
background-color:
|
|
730
|
+
background-color: var(--bg-page);
|
|
723
731
|
}
|