@eifi1/ui-kit 0.48.2 → 0.49.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 +26 -12
- 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 +11 -5
- package/dist/admin/user-roster.js +15 -4
- 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.js +2 -2
- 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/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/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/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 +48 -2
- package/dist/components/data-table-mobile.js +87 -10
- 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 +34 -9
- package/dist/components/data-table.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/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/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/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/pie-chart.js +2 -1
- package/dist/components/pie-chart.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/german.js +6 -2
- package/dist/i18n/german.js.map +1 -1
- package/dist/i18n/kit-labels.d.ts +31 -1
- package/dist/i18n/kit-labels.js +43 -2
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/en.js +6 -2
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/es.js +6 -2
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.js +6 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.js +6 -2
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.js +6 -2
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.js +6 -2
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/review.js +2 -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/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 +35 -10
- package/dist/lib/format.js +55 -11
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/minus.d.ts +22 -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/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.js +1 -1
- package/dist/tour/tour.js.map +1 -1
- package/dist/wizard/stepper-nav.d.ts +1 -1
- package/dist/wizard/stepper-nav.js +3 -3
- package/dist/wizard/stepper-nav.js.map +1 -1
- package/package.json +1 -1
- package/src/admin/admin-action-confirm.tsx +1 -1
- package/src/admin/invitations-panel.tsx +7 -3
- package/src/admin/user-roster.tsx +23 -6
- 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 +3 -3
- package/src/billing/plan-card.tsx +2 -2
- 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/confirm-context.ts +7 -0
- package/src/components/confirm-dialog.tsx +3 -3
- package/src/components/danger-confirm.tsx +3 -3
- package/src/components/data-table-fit.ts +41 -6
- package/src/components/data-table-mobile.tsx +162 -11
- package/src/components/data-table-row-actions.tsx +9 -1
- package/src/components/data-table-row.tsx +2 -0
- package/src/components/data-table.tsx +82 -18
- 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/icon-button.tsx +21 -8
- package/src/components/nav-pills.tsx +29 -2
- package/src/components/page-header-context.ts +8 -0
- package/src/components/page-header.tsx +34 -2
- package/src/components/pie-chart.tsx +2 -1
- 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/german.ts +4 -0
- package/src/i18n/kit-labels.tsx +76 -1
- 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/i18n/review.ts +2 -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/document-title.ts +41 -0
- package/src/lib/float-clearance.ts +19 -3
- package/src/lib/format.ts +115 -30
- package/src/lib/minus.ts +40 -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/theme/chart-palette.ts +102 -20
- package/src/theme/palette-presets.ts +121 -84
- package/src/tour/tour.tsx +1 -1
- package/src/wizard/stepper-nav.tsx +4 -4
- package/tokens.css +28 -18
|
@@ -15,11 +15,12 @@ import { X } from "lucide-react";
|
|
|
15
15
|
|
|
16
16
|
import { cn } from "../lib/cn";
|
|
17
17
|
import { FOCUS_RING } from "./focus-ring";
|
|
18
|
+
import { warnDeprecatedVariant } from "./button-look";
|
|
18
19
|
import { dirOf, type Direction } from "../lib/direction";
|
|
19
20
|
import { registerFloating } from "../lib/floating-stack";
|
|
20
21
|
import { useFloatClearance } from "../lib/float-clearance";
|
|
21
22
|
import { isComposing } from "../lib/ime";
|
|
22
|
-
import { takeEscape } from "../hooks/use-dismiss";
|
|
23
|
+
import { takeEscape, useOverlayOpen } from "../hooks/use-dismiss";
|
|
23
24
|
import { useKitLabels, useKitLink } from "../i18n/kit-labels";
|
|
24
25
|
import { assignRef } from "./field-parts";
|
|
25
26
|
import { pickLinkRenderer } from "./text-link";
|
|
@@ -137,13 +138,18 @@ export interface FloatingActionButtonProps extends Omit<ButtonHTMLAttributes<HTM
|
|
|
137
138
|
*/
|
|
138
139
|
live?: boolean;
|
|
139
140
|
/**
|
|
140
|
-
* `
|
|
141
|
-
* page's surface with a hairline border — for a FAB that is a
|
|
142
|
-
* call to action, as kastlan's offline pill is (a brand pill would
|
|
143
|
-
* at a user who is merely offline). Ignored while `pressed` is set; a
|
|
144
|
-
* own two looks.
|
|
141
|
+
* `accent` (default): the solid brand disc of a page's main action, as Button's
|
|
142
|
+
* `accent`. `surface`: the page's surface with a hairline border — for a FAB that is a
|
|
143
|
+
* status rather than a call to action, as kastlan's offline pill is (a brand pill would
|
|
144
|
+
* shout "press me" at a user who is merely offline). Ignored while `pressed` is set; a
|
|
145
|
+
* toggle has its own two looks. `primary` is a deprecated alias of `accent` (0.49; a
|
|
146
|
+
* development build warns once), removed in 0.51.
|
|
145
147
|
*/
|
|
146
|
-
variant?:
|
|
148
|
+
variant?:
|
|
149
|
+
| "accent"
|
|
150
|
+
| "surface"
|
|
151
|
+
/** @deprecated 0.49 — use `accent` (same look); removed in 0.51. */
|
|
152
|
+
| "primary";
|
|
147
153
|
/**
|
|
148
154
|
* Hover and focus label in the kit {@link Tooltip}, instead of the native `title` —
|
|
149
155
|
* keksdose has ONE tooltip (dev#523) and wrapped its assistant launcher by hand,
|
|
@@ -158,9 +164,23 @@ export interface FloatingActionButtonProps extends Omit<ButtonHTMLAttributes<HTM
|
|
|
158
164
|
/** Where the {@link tooltip} opens. Default `top`; the bubble is portalled and kept on
|
|
159
165
|
* screen, so a corner button's label is not pushed off the edge. */
|
|
160
166
|
tooltipSide?: TooltipSide;
|
|
167
|
+
/**
|
|
168
|
+
* 0.49 KIT-11: step aside (as `hidden` does: off screen, the room kept) while a dialog,
|
|
169
|
+
* a sheet, a popover, a hover menu or a list is open, instead of floating over it or
|
|
170
|
+
* beside it. Default `true`; `false` keeps it on screen. A tooltip does not count.
|
|
171
|
+
*/
|
|
172
|
+
hideWhenOverlay?: boolean;
|
|
161
173
|
ref?: Ref<HTMLButtonElement>;
|
|
162
174
|
}
|
|
163
175
|
|
|
176
|
+
/** FloatingActionButton's and FloatingAction's `primary` was always the solid brand
|
|
177
|
+
* fill: it reads as `accent` (warning once in development), never as Button's
|
|
178
|
+
* `default`. */
|
|
179
|
+
function deprecatedPrimary(component: string): "accent" {
|
|
180
|
+
warnDeprecatedVariant(component, "primary", "accent");
|
|
181
|
+
return "accent";
|
|
182
|
+
}
|
|
183
|
+
|
|
164
184
|
/**
|
|
165
185
|
* A round, icon-only button pinned to a corner of the viewport — the trigger of a
|
|
166
186
|
* {@link FloatingPanel}, and usable alone for a page's one primary action.
|
|
@@ -195,17 +215,22 @@ export function FloatingActionButton({
|
|
|
195
215
|
pressed,
|
|
196
216
|
extended = false,
|
|
197
217
|
live = false,
|
|
198
|
-
variant = "
|
|
218
|
+
variant: givenVariant = "accent",
|
|
199
219
|
tooltip,
|
|
200
220
|
tooltipSide = "top",
|
|
221
|
+
hideWhenOverlay = true,
|
|
201
222
|
className,
|
|
202
223
|
style,
|
|
203
224
|
type = "button",
|
|
204
225
|
title,
|
|
226
|
+
hidden: hiddenProp,
|
|
205
227
|
ref,
|
|
206
228
|
...rest
|
|
207
229
|
}: FloatingActionButtonProps) {
|
|
230
|
+
const overlay = useOverlayOpen(hideWhenOverlay);
|
|
231
|
+
const hidden = hiddenProp || overlay || undefined;
|
|
208
232
|
const [marker, dir] = usePortalDir();
|
|
233
|
+
const variant = givenVariant === "primary" ? deprecatedPrimary("FloatingActionButton variant") : givenVariant;
|
|
209
234
|
const toggle = pressed !== undefined;
|
|
210
235
|
const tip = tooltip === true ? label : tooltip === false || tooltip === "" ? undefined : tooltip;
|
|
211
236
|
const wrapped = tip !== undefined && tip !== null;
|
|
@@ -229,6 +254,7 @@ export function FloatingActionButton({
|
|
|
229
254
|
const button = (
|
|
230
255
|
<button
|
|
231
256
|
{...rest}
|
|
257
|
+
hidden={wrapped ? undefined : hidden}
|
|
232
258
|
ref={buttonRef}
|
|
233
259
|
type={type}
|
|
234
260
|
dir={dir}
|
|
@@ -243,7 +269,7 @@ export function FloatingActionButton({
|
|
|
243
269
|
extended ? "h-12 gap-2 px-4 text-sm font-medium [&_svg]:size-5" : "size-12 [&_svg]:size-6",
|
|
244
270
|
"shadow-lg transition-colors disabled:cursor-default",
|
|
245
271
|
!toggle &&
|
|
246
|
-
variant === "
|
|
272
|
+
variant === "accent" &&
|
|
247
273
|
"bg-brand text-brand-contrast hover:bg-brand-hover",
|
|
248
274
|
!toggle &&
|
|
249
275
|
variant === "surface" &&
|
|
@@ -280,7 +306,7 @@ export function FloatingActionButton({
|
|
|
280
306
|
<div
|
|
281
307
|
ref={setFixed}
|
|
282
308
|
dir={dir}
|
|
283
|
-
hidden={
|
|
309
|
+
hidden={hidden}
|
|
284
310
|
style={cornerStyle(corner, offset)}
|
|
285
311
|
className="fixed z-40 inline-flex"
|
|
286
312
|
>
|
|
@@ -350,6 +376,13 @@ export interface FloatingPanelProps {
|
|
|
350
376
|
* back and shorten the page under the reader's thumb.
|
|
351
377
|
*/
|
|
352
378
|
hidden?: boolean;
|
|
379
|
+
/**
|
|
380
|
+
* 0.49 KIT-11: the FAB steps aside while a dialog, a sheet, a popover, a hover menu or
|
|
381
|
+
* a list is open elsewhere (see {@link FloatingActionButtonProps.hideWhenOverlay}).
|
|
382
|
+
* Default `true`. An OPEN panel stays: what opens from inside it (a select, a date
|
|
383
|
+
* picker) is its own content.
|
|
384
|
+
*/
|
|
385
|
+
hideWhenOverlay?: boolean;
|
|
353
386
|
children: ReactNode;
|
|
354
387
|
}
|
|
355
388
|
|
|
@@ -400,7 +433,8 @@ export function FloatingPanel({
|
|
|
400
433
|
initialFocus,
|
|
401
434
|
className,
|
|
402
435
|
bodyClassName,
|
|
403
|
-
hidden = false,
|
|
436
|
+
hidden: hiddenProp = false,
|
|
437
|
+
hideWhenOverlay = true,
|
|
404
438
|
children,
|
|
405
439
|
}: FloatingPanelProps) {
|
|
406
440
|
const labels = useKitLabels(
|
|
@@ -410,6 +444,8 @@ export function FloatingPanel({
|
|
|
410
444
|
);
|
|
411
445
|
const [ownOpen, setOwnOpen] = useState(defaultOpen);
|
|
412
446
|
const open = openProp ?? ownOpen;
|
|
447
|
+
const overlay = useOverlayOpen(hideWhenOverlay && !open);
|
|
448
|
+
const hidden = hiddenProp || overlay;
|
|
413
449
|
const setOpen = (next: boolean) => {
|
|
414
450
|
if (openProp === undefined) setOwnOpen(next);
|
|
415
451
|
onOpenChange?.(next);
|
|
@@ -477,6 +513,7 @@ export function FloatingPanel({
|
|
|
477
513
|
nativeTitle={fabNativeTitle}
|
|
478
514
|
tooltip={fabTooltip}
|
|
479
515
|
hidden={hidden || undefined}
|
|
516
|
+
hideWhenOverlay={false}
|
|
480
517
|
aria-expanded={open}
|
|
481
518
|
aria-controls={open && !hidden ? panelId : undefined}
|
|
482
519
|
onClick={() => {
|
|
@@ -564,6 +601,9 @@ export interface FloatingActionGroupProps extends Omit<HTMLAttributes<HTMLDivEle
|
|
|
564
601
|
offset?: string;
|
|
565
602
|
/** {@link FloatingAction}s, in reading order. */
|
|
566
603
|
children: ReactNode;
|
|
604
|
+
/** 0.49 KIT-11: step aside while a dialog, a sheet, a popover, a hover menu or a list
|
|
605
|
+
* is open — see {@link FloatingActionButtonProps.hideWhenOverlay}. Default `true`. */
|
|
606
|
+
hideWhenOverlay?: boolean;
|
|
567
607
|
ref?: Ref<HTMLDivElement>;
|
|
568
608
|
}
|
|
569
609
|
|
|
@@ -587,12 +627,15 @@ export interface FloatingActionGroupProps extends Omit<HTMLAttributes<HTMLDivEle
|
|
|
587
627
|
export function FloatingActionGroup({
|
|
588
628
|
corner = "bottom-end",
|
|
589
629
|
offset = "1rem",
|
|
630
|
+
hideWhenOverlay = true,
|
|
631
|
+
hidden,
|
|
590
632
|
className,
|
|
591
633
|
style,
|
|
592
634
|
children,
|
|
593
635
|
...rest
|
|
594
636
|
}: FloatingActionGroupProps) {
|
|
595
637
|
const [marker, dir] = usePortalDir();
|
|
638
|
+
const overlay = useOverlayOpen(hideWhenOverlay);
|
|
596
639
|
// As the FAB's (keksdose dev#612): its 3rem members plus the frame's 1px borders.
|
|
597
640
|
useFloatClearance(offset, "2px");
|
|
598
641
|
return (
|
|
@@ -602,6 +645,7 @@ export function FloatingActionGroup({
|
|
|
602
645
|
createPortal(
|
|
603
646
|
<div
|
|
604
647
|
{...rest}
|
|
648
|
+
hidden={hidden || overlay || undefined}
|
|
605
649
|
role="group"
|
|
606
650
|
dir={dir}
|
|
607
651
|
data-corner={corner}
|
|
@@ -655,10 +699,16 @@ export interface FloatingActionProps extends Omit<ButtonHTMLAttributes<HTMLButto
|
|
|
655
699
|
*/
|
|
656
700
|
pressedStyle?: "tint" | "plain";
|
|
657
701
|
/**
|
|
658
|
-
* `
|
|
659
|
-
* "+")
|
|
702
|
+
* `accent`: the brand-filled member, for the group's main action (the /transactions
|
|
703
|
+
* "+"), as Button's `accent`. `default` (default): the quiet one. `primary` is a
|
|
704
|
+
* deprecated alias of `accent` (0.49; a development build warns once), removed no
|
|
705
|
+
* earlier than 0.51.
|
|
660
706
|
*/
|
|
661
|
-
variant?:
|
|
707
|
+
variant?:
|
|
708
|
+
| "default"
|
|
709
|
+
| "accent"
|
|
710
|
+
/** @deprecated 0.49 — use `accent` (same look); removed in 0.51. */
|
|
711
|
+
| "primary";
|
|
662
712
|
/**
|
|
663
713
|
* A count in a dot at the member's top end corner — the /transactions invoices link's
|
|
664
714
|
* pending count. Nothing is drawn for `0` or less; above 99 it reads `99+`. The count
|
|
@@ -704,7 +754,7 @@ export function FloatingAction({
|
|
|
704
754
|
icon,
|
|
705
755
|
pressed,
|
|
706
756
|
pressedStyle = "tint",
|
|
707
|
-
variant = "default",
|
|
757
|
+
variant: givenVariant = "default",
|
|
708
758
|
badge,
|
|
709
759
|
badgeLabel,
|
|
710
760
|
badgeTone = "warning",
|
|
@@ -723,12 +773,13 @@ export function FloatingAction({
|
|
|
723
773
|
const counted = badge !== undefined && badge > 0;
|
|
724
774
|
const name = counted ? `${label}, ${badgeLabel ?? labels.badge(badge)}` : label;
|
|
725
775
|
const isLink = href !== undefined;
|
|
776
|
+
const variant = givenVariant === "primary" ? deprecatedPrimary("FloatingAction variant") : givenVariant;
|
|
726
777
|
const look = cn(
|
|
727
778
|
"relative flex size-12 items-center justify-center transition-colors",
|
|
728
779
|
"outline-none focus-visible:ring-inset",
|
|
729
780
|
FOCUS_RING,
|
|
730
781
|
"disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:size-5",
|
|
731
|
-
variant === "
|
|
782
|
+
variant === "accent"
|
|
732
783
|
? "bg-brand text-brand-contrast hover:bg-brand-hover"
|
|
733
784
|
: pressed && !isLink && pressedStyle === "tint"
|
|
734
785
|
? "bg-brand-soft text-brand hover:bg-brand-soft-hover hover:text-brand-muted"
|
|
@@ -204,7 +204,7 @@ export interface FormActionsProps extends Omit<ComponentPropsWithoutRef<"div">,
|
|
|
204
204
|
* allows (the account's own settings, docs/billing-harmonization.md §12.36).
|
|
205
205
|
*/
|
|
206
206
|
commit?: CommitScope;
|
|
207
|
-
/** The save button's variant. Default `
|
|
207
|
+
/** The save button's variant. Default `accent`; `danger` for a save that destroys
|
|
208
208
|
* (kastlan's `destructive` flag on its own FormActions). */
|
|
209
209
|
submitVariant?: ButtonVariant;
|
|
210
210
|
/**
|
|
@@ -371,7 +371,7 @@ export function FormActions({
|
|
|
371
371
|
submitDisabled = false,
|
|
372
372
|
submitDisabledReason,
|
|
373
373
|
commit = false,
|
|
374
|
-
submitVariant = "
|
|
374
|
+
submitVariant = "accent",
|
|
375
375
|
cancelVariant = "secondary",
|
|
376
376
|
size = "md",
|
|
377
377
|
destructive,
|
|
@@ -28,8 +28,9 @@ import {
|
|
|
28
28
|
HIT_AREA_LARGE,
|
|
29
29
|
TOUCH_TARGET_LARGE,
|
|
30
30
|
buttonVariantClasses,
|
|
31
|
+
resolveButtonVariant,
|
|
31
32
|
} from "./button-look";
|
|
32
|
-
import type { ButtonVariant } from "./button-look";
|
|
33
|
+
import type { ButtonVariant, CanonicalButtonVariant } from "./button-look";
|
|
33
34
|
|
|
34
35
|
// Canonical square icon-only button. <Button> carries TEXT geometry — px-3 py-2
|
|
35
36
|
// gap-2 — so rendering a bare glyph through it gives a small icon in a wide,
|
|
@@ -199,12 +200,12 @@ function iconButtonToneClass(tone: IconButtonTone, quiet: boolean | undefined):
|
|
|
199
200
|
// and would out-rank a caller's plain `hover:` override), each variant pins its
|
|
200
201
|
// RESTING look under `disabled:hover:`, which out-ranks any `hover:` by specificity
|
|
201
202
|
// and only ever matches a disabled button.
|
|
202
|
-
const ICON_BUTTON_DISABLED_REST: Record<
|
|
203
|
-
|
|
203
|
+
const ICON_BUTTON_DISABLED_REST: Record<CanonicalButtonVariant | "overlay" | "shutter", string> = {
|
|
204
|
+
default: "disabled:hover:bg-surface-2",
|
|
204
205
|
secondary: "disabled:hover:bg-transparent",
|
|
205
206
|
ghost: "disabled:hover:bg-transparent",
|
|
206
207
|
danger: "disabled:hover:bg-danger",
|
|
207
|
-
|
|
208
|
+
accent: "disabled:hover:bg-brand",
|
|
208
209
|
link: "disabled:hover:bg-transparent disabled:hover:no-underline",
|
|
209
210
|
overlay: "disabled:hover:bg-[color-mix(in_srgb,var(--bg-inverse)_60%,transparent)]",
|
|
210
211
|
shutter: "disabled:hover:bg-media-scrim",
|
|
@@ -633,6 +634,7 @@ function iconButtonLook({
|
|
|
633
634
|
/** The label is drawn beside the glyph (see `labelVisible`). */
|
|
634
635
|
withText?: boolean;
|
|
635
636
|
}) {
|
|
637
|
+
const look = variant === "overlay" || variant === "shutter" ? variant : resolveButtonVariant(variant, "IconButton variant");
|
|
636
638
|
return cn(
|
|
637
639
|
ICON_BUTTON_BASE,
|
|
638
640
|
withText
|
|
@@ -644,13 +646,13 @@ function iconButtonLook({
|
|
|
644
646
|
withText ? TOUCH_TARGET_LARGE : ICON_BUTTON_TOUCH_LARGE[size],
|
|
645
647
|
glyphSize !== undefined && ICON_BUTTON_GLYPH_SIZES[glyphSize],
|
|
646
648
|
// After the size, so the overlay's `rounded-full` beats the small sizes' `rounded`.
|
|
647
|
-
|
|
649
|
+
look === "overlay"
|
|
648
650
|
? ICON_BUTTON_OVERLAY
|
|
649
|
-
:
|
|
651
|
+
: look === "shutter"
|
|
650
652
|
? ICON_BUTTON_SHUTTER
|
|
651
|
-
: buttonVariantClasses[
|
|
653
|
+
: buttonVariantClasses[look],
|
|
652
654
|
shape === "round" && "rounded-full",
|
|
653
|
-
ICON_BUTTON_DISABLED_REST[
|
|
655
|
+
ICON_BUTTON_DISABLED_REST[look],
|
|
654
656
|
iconButtonToneClass(tone, quiet),
|
|
655
657
|
toneColor !== undefined && typeof toneColor !== "string" && ICON_BUTTON_TONE_PAIR,
|
|
656
658
|
);
|
|
@@ -676,6 +678,17 @@ function withIconButtonBadge(control: ReactElement, badge: ReactNode, stretch: b
|
|
|
676
678
|
|
|
677
679
|
// Declared link-first, as Button is, so `<IconButton href>` picks the link props and
|
|
678
680
|
// `ComponentProps<typeof IconButton>` (the LAST signature) is still the button's.
|
|
681
|
+
/**
|
|
682
|
+
* An icon-only button whose `label` is its name and its tooltip.
|
|
683
|
+
*
|
|
684
|
+
* Destructive actions (0.49 KIT-12): a delete, revoke or erase is NOT an icon repeated in
|
|
685
|
+
* every row of a list — one stray tap away, and a bin per row draws the eye to the one
|
|
686
|
+
* thing nobody should do by accident. Put it in the row's menu, `RowActions` (where a
|
|
687
|
+
* `tone: "danger"` action goes by default and opens a `ConfirmDialog` first), or in the
|
|
688
|
+
* selection bar ("2 selected" → Delete), and confirm it through `useConfirm`. A single
|
|
689
|
+
* standalone delete — a card's own, a bulk bar's — may be an IconButton
|
|
690
|
+
* `tone="danger"`; it still asks first.
|
|
691
|
+
*/
|
|
679
692
|
export function IconButton(props: IconButtonLinkProps): ReactElement;
|
|
680
693
|
export function IconButton(props: IconButtonProps): ReactElement;
|
|
681
694
|
export function IconButton(props: IconButtonProps | IconButtonLinkProps): ReactElement {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { useLayoutEffect, useRef } from "react";
|
|
1
2
|
import type { ComponentPropsWithoutRef, ComponentType, MouseEvent, ReactElement, ReactNode, Ref } from "react";
|
|
2
3
|
import { cn } from "../lib/cn";
|
|
4
|
+
import { scrollIntoStrip, useStripFade } from "../lib/strip-fade";
|
|
3
5
|
import { useKitLink } from "../i18n/kit-labels";
|
|
4
6
|
import { FOCUS_RING } from "./focus-ring";
|
|
5
7
|
import { pickLinkRenderer, RenderedKitLink } from "./text-link";
|
|
@@ -50,6 +52,13 @@ export interface NavPillsProps<T extends string> extends Omit<ComponentPropsWith
|
|
|
50
52
|
landmark?: boolean;
|
|
51
53
|
/** Classes for every pill. */
|
|
52
54
|
itemClassName?: string;
|
|
55
|
+
/**
|
|
56
|
+
* 0.49: `wrap` (default) puts the pills on as many rows as they need. `scroll` keeps
|
|
57
|
+
* them on ONE row that scrolls sideways — faded at a cut edge, the current pill
|
|
58
|
+
* scrolled into view (the row only, never the page) — for a strip that must stay one
|
|
59
|
+
* line high, as {@link SectionNav} under a page title on a phone.
|
|
60
|
+
*/
|
|
61
|
+
layout?: "wrap" | "scroll";
|
|
53
62
|
/** The `<nav>` (or the `<div role="group">`) — hence `HTMLElement` (0.34, API-2,
|
|
54
63
|
* refactor audit 2026-10). */
|
|
55
64
|
ref?: Ref<HTMLElement>;
|
|
@@ -89,12 +98,22 @@ export function NavPills<T extends string>({
|
|
|
89
98
|
size = "md",
|
|
90
99
|
landmark = true,
|
|
91
100
|
itemClassName,
|
|
101
|
+
layout = "wrap",
|
|
92
102
|
className,
|
|
93
103
|
ref,
|
|
94
104
|
...rest
|
|
95
105
|
}: NavPillsProps<T>) {
|
|
96
106
|
const kitLink = useKitLink();
|
|
97
107
|
const Root = landmark ? "nav" : "div";
|
|
108
|
+
const scroll = layout === "scroll";
|
|
109
|
+
const listRef = useRef<HTMLUListElement>(null);
|
|
110
|
+
const fade = useStripFade(listRef);
|
|
111
|
+
// The current pill into view — the row only, never the page.
|
|
112
|
+
useLayoutEffect(() => {
|
|
113
|
+
const list = listRef.current;
|
|
114
|
+
const currentPill = list?.querySelector<HTMLElement>("[aria-current]");
|
|
115
|
+
if (scroll && list && currentPill) scrollIntoStrip(list, currentPill);
|
|
116
|
+
}, [scroll, current]);
|
|
98
117
|
return (
|
|
99
118
|
<Root
|
|
100
119
|
{...rest}
|
|
@@ -102,7 +121,15 @@ export function NavPills<T extends string>({
|
|
|
102
121
|
role={landmark ? undefined : "group"}
|
|
103
122
|
className={cn("min-w-0", className)}
|
|
104
123
|
>
|
|
105
|
-
<ul
|
|
124
|
+
<ul
|
|
125
|
+
ref={listRef}
|
|
126
|
+
className={cn(
|
|
127
|
+
"m-0 flex list-none gap-1 p-0",
|
|
128
|
+
scroll ? "flex-nowrap overflow-x-auto overscroll-x-contain [scrollbar-width:none]" : "flex-wrap",
|
|
129
|
+
)}
|
|
130
|
+
data-overflow={scroll ? fade.overflow : undefined}
|
|
131
|
+
style={scroll && fade.mask ? { maskImage: fade.mask, WebkitMaskImage: fade.mask } : undefined}
|
|
132
|
+
>
|
|
106
133
|
{items.map((item) => {
|
|
107
134
|
const isCurrent = item.value === current;
|
|
108
135
|
const Icon = item.icon;
|
|
@@ -152,7 +179,7 @@ export function NavPills<T extends string>({
|
|
|
152
179
|
);
|
|
153
180
|
}
|
|
154
181
|
return (
|
|
155
|
-
<li key={item.value} className="flex">
|
|
182
|
+
<li key={item.value} className={cn("flex", scroll && "shrink-0")}>
|
|
156
183
|
{pill}
|
|
157
184
|
</li>
|
|
158
185
|
);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Set by `PageHeader` around its `breadcrumbs` (0.49 KIT-9), so a `Breadcrumbs` there
|
|
5
|
+
* knows the page's title is already on screen: it hides its current entry by default
|
|
6
|
+
* (`hideCurrent`) and draws nothing when only the home entry would remain. Internal.
|
|
7
|
+
*/
|
|
8
|
+
export const PageHeaderTrailContext = createContext<{ titled: boolean } | null>(null);
|
|
@@ -2,6 +2,8 @@ import { useLayoutEffect, useRef, useState } from "react";
|
|
|
2
2
|
import type { ComponentPropsWithRef, ElementType, ReactNode } from "react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
4
|
import { SECTION_LABEL_CLASS } from "./text";
|
|
5
|
+
import { useDocumentTitle } from "../hooks/use-document-title";
|
|
6
|
+
import { PageHeaderTrailContext } from "./page-header-context";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* `md` (default) is kastlan's `text-2xl` page title from `sm` up, a step smaller on a
|
|
@@ -71,8 +73,20 @@ export interface PageHeaderProps extends Omit<ComponentPropsWithRef<"div">, "tit
|
|
|
71
73
|
/** Buttons for the page — "New", "Export". At the title's end from `sm` up; under it,
|
|
72
74
|
* wrapping, on a phone — unless {@link mobileLayout} is `inline`. */
|
|
73
75
|
actions?: ReactNode;
|
|
74
|
-
/** A `Breadcrumbs` trail, drawn above everything else.
|
|
76
|
+
/** A `Breadcrumbs` trail, drawn above everything else. Inside a header with a title
|
|
77
|
+
* it hides its current entry (the title names it) and is drawn only when an entry
|
|
78
|
+
* other than home is left — `Breadcrumbs.hideCurrent` (0.49 KIT-9). */
|
|
75
79
|
breadcrumbs?: ReactNode;
|
|
80
|
+
/**
|
|
81
|
+
* The window's title (`document.title`) while the header is mounted (0.49 KIT-9),
|
|
82
|
+
* through `useDocumentTitle` and the provider's format ("{page} · {section} · {app}",
|
|
83
|
+
* `appName` as the app). A string is the page; an array is `[page, section]` (or
|
|
84
|
+
* `[page, section, app]`); `false` leaves the window's title alone.
|
|
85
|
+
*
|
|
86
|
+
* Default: the `title` when it is a string, and only for the page's own header
|
|
87
|
+
* (`as="h1"`) — a tab's `h2` header does not rename the window.
|
|
88
|
+
*/
|
|
89
|
+
documentTitle?: string | ReadonlyArray<string | null | undefined> | false;
|
|
76
90
|
/** A small uppercase line above the title — the section or the kind of record
|
|
77
91
|
* ("Building", "Settings"). The section-label type. */
|
|
78
92
|
eyebrow?: ReactNode;
|
|
@@ -147,6 +161,9 @@ export interface PageHeaderProps extends Omit<ComponentPropsWithRef<"div">, "tit
|
|
|
147
161
|
truncateTitle?: boolean;
|
|
148
162
|
}
|
|
149
163
|
|
|
164
|
+
const TITLED = { titled: true };
|
|
165
|
+
const UNTITLED = { titled: false };
|
|
166
|
+
|
|
150
167
|
/**
|
|
151
168
|
* A page's head: optional breadcrumbs, an eyebrow, the title, a description, and the
|
|
152
169
|
* page's actions.
|
|
@@ -170,10 +187,23 @@ export function PageHeader({
|
|
|
170
187
|
secondaryActions,
|
|
171
188
|
actionsAlign,
|
|
172
189
|
truncateTitle = false,
|
|
190
|
+
documentTitle,
|
|
173
191
|
className,
|
|
174
192
|
...rest
|
|
175
193
|
}: PageHeaderProps) {
|
|
176
194
|
const Heading = as as ElementType;
|
|
195
|
+
useDocumentTitle(
|
|
196
|
+
documentTitle === false
|
|
197
|
+
? []
|
|
198
|
+
: documentTitle === undefined
|
|
199
|
+
? as === "h1" && typeof title === "string"
|
|
200
|
+
? [title]
|
|
201
|
+
: []
|
|
202
|
+
: typeof documentTitle === "string"
|
|
203
|
+
? [documentTitle]
|
|
204
|
+
: documentTitle,
|
|
205
|
+
);
|
|
206
|
+
const titled = title != null && title !== false && title !== "";
|
|
177
207
|
const hasSecondary = secondaryActions != null;
|
|
178
208
|
const wrapsSecondary = hasSecondary && mobileLayout === "inline";
|
|
179
209
|
const align = actionsAlign != null ? ROW_ALIGN[mobileLayout][actionsAlign] : undefined;
|
|
@@ -216,7 +246,9 @@ export function PageHeader({
|
|
|
216
246
|
}, [measuresWrap]);
|
|
217
247
|
return (
|
|
218
248
|
<div {...rest} className={cn("flex min-w-0 flex-col gap-2", className)}>
|
|
219
|
-
{breadcrumbs
|
|
249
|
+
{breadcrumbs != null && (
|
|
250
|
+
<PageHeaderTrailContext.Provider value={titled ? TITLED : UNTITLED}>{breadcrumbs}</PageHeaderTrailContext.Provider>
|
|
251
|
+
)}
|
|
220
252
|
{/* With a second group, `inline` wraps so that group's full-width basis puts it
|
|
221
253
|
on a row of its own on a phone (`stacked` is a column there already, and a
|
|
222
254
|
basis would size a column item's HEIGHT); from `sm` up the row stops wrapping
|
|
@@ -20,6 +20,7 @@ import { DEFAULT_PIE_CHART_LABELS, type PieChartLabels } from "./pie-chart-label
|
|
|
20
20
|
import { StaticLegend, ToggleLegend, toggleHidden, type LegendEntry } from "./toggle-legend";
|
|
21
21
|
import { useTextSize } from "../theme/text-size";
|
|
22
22
|
import { chartHeightProps, type ChartHeight } from "./chart-height";
|
|
23
|
+
import { formatWithMinus } from "../lib/minus";
|
|
23
24
|
|
|
24
25
|
/** One slice. */
|
|
25
26
|
export interface PieChartSlice {
|
|
@@ -186,7 +187,7 @@ export function PieChart({
|
|
|
186
187
|
// Memoised, like everything the sectors are drawn from: they must not be rebuilt on
|
|
187
188
|
// this component's own re-renders (see `pie` below).
|
|
188
189
|
const formatValue = useCallback(
|
|
189
|
-
(v: number) => (formatValueProp ? formatValueProp(v) : numberFormat
|
|
190
|
+
(v: number) => (formatValueProp ? formatValueProp(v) : formatWithMinus(numberFormat, v)),
|
|
190
191
|
[formatValueProp, numberFormat],
|
|
191
192
|
);
|
|
192
193
|
// One decimal under 10 %, where rounding to whole percents starts to lie — a slice
|
|
@@ -5,6 +5,7 @@ import { DEFAULT_COMMON_LABELS, useKitLabels, useKitLocale, type LabelOverride }
|
|
|
5
5
|
import { toneTextClass } from "./signed-amount";
|
|
6
6
|
import type { TextTone } from "./signed-amount";
|
|
7
7
|
import { DEFAULT_PROGRESS_BAR_LABELS } from "./progress-bar-labels";
|
|
8
|
+
import { formatWithMinus } from "../lib/minus";
|
|
8
9
|
|
|
9
10
|
/** The words a progress bar adds of its own. */
|
|
10
11
|
export interface ProgressBarLabels {
|
|
@@ -57,6 +58,7 @@ const TRACK_HEIGHT: Record<ProgressBarSize, string> = { sm: "h-1", slim: "h-1.5"
|
|
|
57
58
|
|
|
58
59
|
// A segment with no tone of its own takes the next categorical chart colour, so a
|
|
59
60
|
// stacked bar of unnamed parts is still a set of tellable parts rather than one fill.
|
|
61
|
+
// Eight, cycled like `paletteFor` (0.49): `--chart-9` only repeats slot 1.
|
|
60
62
|
const SERIES_FILL = [
|
|
61
63
|
"bg-[var(--chart-1)]",
|
|
62
64
|
"bg-[var(--chart-2)]",
|
|
@@ -66,7 +68,6 @@ const SERIES_FILL = [
|
|
|
66
68
|
"bg-[var(--chart-6)]",
|
|
67
69
|
"bg-[var(--chart-7)]",
|
|
68
70
|
"bg-[var(--chart-8)]",
|
|
69
|
-
"bg-[var(--chart-9)]",
|
|
70
71
|
];
|
|
71
72
|
|
|
72
73
|
/** Each segment's fill classes: its own classes, else its tone, else (with no `color`)
|
|
@@ -282,7 +283,7 @@ export function ProgressBar({
|
|
|
282
283
|
? undefined
|
|
283
284
|
: formatValue
|
|
284
285
|
? formatValue(value, Infinity, min)
|
|
285
|
-
: new Intl.NumberFormat(kitLocale)
|
|
286
|
+
: formatWithMinus(new Intl.NumberFormat(kitLocale), value);
|
|
286
287
|
return (
|
|
287
288
|
<Tag {...rest} ref={tagRef} className={cn("min-w-0", inlineClass, className)} data-state="unlimited">
|
|
288
289
|
<Tag className="flex items-baseline gap-2 text-sm">
|
|
@@ -325,7 +326,9 @@ export function ProgressBar({
|
|
|
325
326
|
const formatPart = (v: number) => {
|
|
326
327
|
if (!Number.isFinite(v)) return format(min);
|
|
327
328
|
if (formatValue) return formatValue(v, max, min);
|
|
328
|
-
|
|
329
|
+
// A part can be negative (a refund): U+2212, as everywhere (0.49, KIT-1).
|
|
330
|
+
return formatWithMinus(
|
|
331
|
+
new Intl.NumberFormat(kitLocale, { style: "percent", maximumFractionDigits: 0 }),
|
|
329
332
|
span <= 0 ? 0 : (v - min) / span,
|
|
330
333
|
);
|
|
331
334
|
};
|
|
@@ -7,4 +7,6 @@ import type { RowActionsLabels } from "./row-actions";
|
|
|
7
7
|
export const DEFAULT_ROW_ACTIONS_LABELS: RowActionsLabels = {
|
|
8
8
|
actions: "Actions",
|
|
9
9
|
actionsFor: (name) => `Actions for ${name}`,
|
|
10
|
+
confirmTitle: (action, name) => (name ? `${action} “${name}”?` : `${action}?`),
|
|
11
|
+
confirmBody: "This cannot be undone.",
|
|
10
12
|
};
|