@godxjp/ui 16.9.4 → 17.0.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 +30 -5
- package/dist/components/charts/chart-cartesian.js +1 -6
- package/dist/components/charts/pie-chart.js +1 -8
- package/dist/components/data-display/empty-state.d.ts +1 -1
- package/dist/components/data-display/empty-state.js +25 -7
- package/dist/components/data-display/progress.d.ts +9 -2
- package/dist/components/data-display/progress.js +6 -3
- package/dist/components/data-entry/form-field.js +13 -4
- package/dist/components/data-entry/search-select.d.ts +1 -1
- package/dist/components/data-entry/search-select.js +97 -19
- package/dist/components/data-entry/select.js +15 -4
- package/dist/components/feedback/alert.d.ts +11 -2
- package/dist/components/feedback/alert.js +51 -9
- package/dist/components/general/button.js +2 -0
- package/dist/components/general/index.d.ts +4 -0
- package/dist/components/general/index.js +4 -0
- package/dist/components/general/logo.d.ts +27 -0
- package/dist/components/general/logo.js +23 -0
- package/dist/components/general/reveal.d.ts +14 -0
- package/dist/components/general/reveal.js +21 -0
- package/dist/components/layout/auth-shell.d.ts +11 -0
- package/dist/components/layout/auth-shell.js +15 -0
- package/dist/components/layout/flex.js +1 -1
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/layout/page-container.js +4 -4
- package/dist/components/navigation/app-setting-picker.js +19 -4
- package/dist/components/navigation/pagination.d.ts +1 -1
- package/dist/components/navigation/pagination.js +2 -1
- package/dist/components/query/data-state.d.ts +1 -1
- package/dist/components/query/data-state.js +27 -4
- package/dist/components/query/index.d.ts +2 -0
- package/dist/components/query/index.js +4 -1
- package/dist/i18n/messages/en.json +30 -2
- package/dist/i18n/messages/ja.json +30 -2
- package/dist/i18n/messages/vi.json +30 -2
- package/dist/lib/query-error.d.ts +17 -0
- package/dist/lib/query-error.js +58 -0
- package/dist/props/components/app.prop.d.ts +9 -1
- package/dist/props/components/data-display.prop.d.ts +15 -0
- package/dist/props/components/data-entry.prop.d.ts +8 -0
- package/dist/props/components/feedback.prop.d.ts +6 -0
- package/dist/props/components/general.prop.d.ts +23 -1
- package/dist/props/components/layout.prop.d.ts +17 -0
- package/dist/props/components/query.prop.d.ts +7 -1
- package/dist/props/registry.d.ts +31 -2
- package/dist/props/registry.js +44 -2
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/props/vocabulary/interaction.prop.d.ts +16 -0
- package/dist/styles/alert-layout.css +1 -2
- package/dist/styles/card-layout.css +6 -6
- package/dist/styles/data-display-layout.css +18 -0
- package/dist/styles/index.css +2 -0
- package/dist/styles/layout.css +28 -0
- package/dist/styles/logo-layout.css +41 -0
- package/dist/styles/motion.css +52 -0
- package/dist/styles/shell-layout.css +42 -0
- package/dist/theme/famgia.service.css +44 -0
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/feedback.css +4 -0
- package/dist/tokens/components/logo.css +15 -0
- package/dist/tokens/components/shell.css +10 -0
- package/dist/tokens/foundation.css +8 -2
- package/package.json +7 -3
- package/scripts/visual-audit.mjs +293 -126
|
@@ -320,6 +320,8 @@ export type SearchSelectProp = {
|
|
|
320
320
|
searchPlaceholder?: PlaceholderProp;
|
|
321
321
|
emptyMessage?: EmptyMessageProp;
|
|
322
322
|
loadingMessage?: string;
|
|
323
|
+
/** Message shown when an async `loadOptions` rejects — a distinct state from empty/loading. */
|
|
324
|
+
errorMessage?: string;
|
|
323
325
|
clearLabel?: string;
|
|
324
326
|
/** Show a "clear" row when a value is selected (default true). */
|
|
325
327
|
clearable?: boolean;
|
|
@@ -328,6 +330,12 @@ export type SearchSelectProp = {
|
|
|
328
330
|
name?: NameProp;
|
|
329
331
|
id?: IdProp;
|
|
330
332
|
className?: ClassNameProp;
|
|
333
|
+
"aria-label"?: string;
|
|
334
|
+
"aria-labelledby"?: string;
|
|
335
|
+
"aria-describedby"?: string;
|
|
336
|
+
"aria-errormessage"?: string;
|
|
337
|
+
"aria-invalid"?: boolean | "true" | "false";
|
|
338
|
+
"aria-required"?: boolean | "true" | "false";
|
|
331
339
|
"data-testid"?: string;
|
|
332
340
|
};
|
|
333
341
|
/**
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Feedback component prop types — @see docs/COMPONENTS.md#feedback */
|
|
2
2
|
import type * as React from "react";
|
|
3
|
+
import type { QueryErrorCategory } from "../../lib/query-error.js";
|
|
3
4
|
import type { AlertVariantProp, CancelLabelProp, ChildrenProp, ClassNameProp, ConfirmLabelProp, ConfirmVariantProp, DescriptionProp, HandlerProp, IconProp, OpenProp, OnOpenChangeProp, PendingProp, ToneProp, TitleProp } from "../vocabulary/index.js";
|
|
4
5
|
/** @see AlertDialog */
|
|
5
6
|
export type AlertDialogProp = {
|
|
@@ -19,7 +20,12 @@ export type AlertDialogProp = {
|
|
|
19
20
|
/** @see Alert */
|
|
20
21
|
export type AlertQueryErrorProp = {
|
|
21
22
|
error: unknown;
|
|
23
|
+
/** Override the auto-classified cause. When omitted, the error is classified via `classifyQueryError`. */
|
|
24
|
+
category?: QueryErrorCategory;
|
|
25
|
+
/** Retry affordance — only shown for causes where retrying is meaningful (transient/network/5xx). */
|
|
22
26
|
onRetry?: HandlerProp;
|
|
27
|
+
/** Recovery for `auth` (401/expired token): renew the session or sign in again. Replaces Retry. */
|
|
28
|
+
onAuthAction?: HandlerProp;
|
|
23
29
|
className?: ClassNameProp;
|
|
24
30
|
};
|
|
25
31
|
/** @see Alert */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Foundation component prop types — @see docs/COMPONENTS.md#foundation */
|
|
2
2
|
import type * as React from "react";
|
|
3
|
-
import type { AsChildProp, ButtonSizeProp, ButtonVariantProp, DisabledProp, FontWeightProp, HeadingLevelProp, OnClickProp, PendingProp, ShapeProp, TextAlignProp, TextSizeProp, TextToneProp } from "../vocabulary/index.js";
|
|
3
|
+
import type { AsChildProp, ButtonSizeProp, ButtonVariantProp, ChildrenProp, ClassNameProp, DisabledProp, FontWeightProp, HeadingLevelProp, OnClickProp, PendingProp, RevealDelayProp, ShapeProp, TextAlignProp, TextSizeProp, TextToneProp } from "../vocabulary/index.js";
|
|
4
4
|
/** @see Text — typographic primitive; replaces hand-rolled `<span className="text-[13px] …">`. */
|
|
5
5
|
export type TextProp = Omit<React.HTMLAttributes<HTMLElement>, "color"> & {
|
|
6
6
|
/** Render element. Default `span`. Covers inline/block text + description-list + code/caption. */
|
|
@@ -71,3 +71,25 @@ export type ButtonProp = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
|
71
71
|
*/
|
|
72
72
|
showZero?: boolean;
|
|
73
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* @see Reveal — entrance-motion primitive (staggered fade-up). Wraps content in a real element
|
|
76
|
+
* that animates in on mount reading the DS motion tokens (`--duration-slow`, `--ease-emphasized`,
|
|
77
|
+
* `--reveal-distance`), replacing hand-rolled `@keyframes` + `.app-reveal`/`.d1..d6` classes.
|
|
78
|
+
* Honours `prefers-reduced-motion` — the animation is dropped and content stays fully visible with
|
|
79
|
+
* no layout shift.
|
|
80
|
+
*/
|
|
81
|
+
export type RevealProp = React.HTMLAttributes<HTMLDivElement> & {
|
|
82
|
+
/** Child content to reveal on enter. */
|
|
83
|
+
children?: ChildrenProp;
|
|
84
|
+
/**
|
|
85
|
+
* Stagger ordinal — an INDEX into the motion ladder (`0..6`), never a raw ms. Each step adds one
|
|
86
|
+
* `--reveal-stagger-step` of delay so sibling reveals cascade. Default `0` (enter immediately).
|
|
87
|
+
*/
|
|
88
|
+
delay?: RevealDelayProp;
|
|
89
|
+
/**
|
|
90
|
+
* Merge the reveal behaviour onto the single child element (Radix `Slot`) instead of rendering a
|
|
91
|
+
* wrapper `<div>` — use when an extra box would break a grid/flex layout. Default `false`.
|
|
92
|
+
*/
|
|
93
|
+
asChild?: AsChildProp;
|
|
94
|
+
className?: ClassNameProp;
|
|
95
|
+
};
|
|
@@ -67,6 +67,23 @@ export type AppShellProp = {
|
|
|
67
67
|
footer?: ReactNode;
|
|
68
68
|
sidebarCollapsed?: boolean;
|
|
69
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* @see AuthShell — centred auth/login page shell (login · mfa · passkey · device · reset). A
|
|
72
|
+
* top brand bar, a centred `main` that holds the auth `Card`, and an optional footer, over a
|
|
73
|
+
* `min-h-dvh` surface. The shell scopes `--control-height` to the comfortable tier (44px, the WCAG
|
|
74
|
+
* touch floor) and bumps the auth heading size so forms read at the right density — replacing
|
|
75
|
+
* consumers' hand-rolled `.auth-shell-*` / `.ui-auth-scope` classes. Motion is delegated to
|
|
76
|
+
* `Reveal` (wrap the card) so `prefers-reduced-motion` is honoured at one place.
|
|
77
|
+
*/
|
|
78
|
+
export type AuthShellProp = {
|
|
79
|
+
/** Centred content — typically a single auth `<Card>` with the form. */
|
|
80
|
+
children: ReactNode;
|
|
81
|
+
/** Brand bar slot pinned to the top (e.g. a `<Logo>` / product mark). */
|
|
82
|
+
brand?: ReactNode;
|
|
83
|
+
/** Footer slot pinned to the bottom (legal links, locale switch, support). */
|
|
84
|
+
footer?: ReactNode;
|
|
85
|
+
className?: ClassNameProp;
|
|
86
|
+
};
|
|
70
87
|
/** @see Sidebar */
|
|
71
88
|
export type SidebarProductProp = {
|
|
72
89
|
name: string;
|
|
@@ -8,13 +8,19 @@ import type { ClassNameProp, HandlerProp } from "../vocabulary/index.js";
|
|
|
8
8
|
export type DataStateProp<T> = {
|
|
9
9
|
query: UseQueryResult<T>;
|
|
10
10
|
skeleton: React.ReactNode;
|
|
11
|
+
/** Rendered when a query is disabled/unstarted (`fetchStatus: "idle"` with no data). */
|
|
12
|
+
prerequisite?: React.ReactNode;
|
|
11
13
|
empty?: React.ReactNode;
|
|
12
14
|
isEmpty?: (data: NonNullable<T>) => boolean;
|
|
13
15
|
errorRenderer?: (error: unknown, retry: () => void) => React.ReactNode;
|
|
14
|
-
/**
|
|
16
|
+
/** Force the Retry affordance even for non-transient causes. Retry is offered automatically for
|
|
17
|
+
* transient/network/5xx errors regardless of this flag; default `false` for all other causes. */
|
|
15
18
|
showRetry?: boolean;
|
|
16
19
|
/** Default `() => query.refetch()`. */
|
|
17
20
|
onRetry?: HandlerProp;
|
|
21
|
+
/** Recovery for authentication errors (401 / expired token): renew the session or sign in again.
|
|
22
|
+
* When provided, a 401 renders this action instead of Retry. */
|
|
23
|
+
onAuthError?: HandlerProp;
|
|
18
24
|
children: (data: NonNullable<T>) => React.ReactNode;
|
|
19
25
|
};
|
|
20
26
|
type MutationLike = Pick<UseMutationResult<unknown, unknown, unknown, unknown>, "isError" | "error" | "isPending">;
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -209,6 +209,11 @@ export declare const VOCABULARY_REGISTRY: {
|
|
|
209
209
|
readonly category: "interaction";
|
|
210
210
|
readonly description: "Badge visual variant (default | secondary | outline | dashed)";
|
|
211
211
|
};
|
|
212
|
+
readonly AppSettingPickerAppearanceProp: {
|
|
213
|
+
readonly file: "vocabulary/interaction.prop.ts";
|
|
214
|
+
readonly category: "interaction";
|
|
215
|
+
readonly description: "AppSettingPicker trigger presentation: labeled (icon + value) | icon (square icon-only topbar trigger)";
|
|
216
|
+
};
|
|
212
217
|
readonly ShapeProp: {
|
|
213
218
|
readonly file: "vocabulary/interaction.prop.ts";
|
|
214
219
|
readonly category: "interaction";
|
|
@@ -289,6 +294,11 @@ export declare const VOCABULARY_REGISTRY: {
|
|
|
289
294
|
readonly category: "interaction";
|
|
290
295
|
readonly description: "Active table sort";
|
|
291
296
|
};
|
|
297
|
+
readonly RevealDelayProp: {
|
|
298
|
+
readonly file: "vocabulary/interaction.prop.ts";
|
|
299
|
+
readonly category: "interaction";
|
|
300
|
+
readonly description: "Reveal entrance-stagger ordinal (0..6) — an index into the motion ladder, never a raw ms";
|
|
301
|
+
};
|
|
292
302
|
readonly BreadcrumbItemProp: {
|
|
293
303
|
readonly file: "vocabulary/navigation.prop.ts";
|
|
294
304
|
readonly category: "navigation";
|
|
@@ -380,7 +390,7 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
380
390
|
readonly AppSettingPickerProp: {
|
|
381
391
|
readonly group: "app";
|
|
382
392
|
readonly file: "components/app.prop.ts";
|
|
383
|
-
readonly vocabulary: readonly ["ValueProp", "OnValueChangeProp", "DisabledProp", "IdProp", "ClassNameProp"];
|
|
393
|
+
readonly vocabulary: readonly ["ValueProp", "OnValueChangeProp", "DisabledProp", "IdProp", "ClassNameProp", "AppSettingPickerAppearanceProp"];
|
|
384
394
|
};
|
|
385
395
|
readonly PageContainerProp: {
|
|
386
396
|
readonly group: "layout";
|
|
@@ -438,6 +448,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
438
448
|
readonly file: "components/layout.prop.ts";
|
|
439
449
|
readonly vocabulary: readonly ["ChildrenProp"];
|
|
440
450
|
};
|
|
451
|
+
readonly AuthShellProp: {
|
|
452
|
+
readonly group: "layout";
|
|
453
|
+
readonly file: "components/layout.prop.ts";
|
|
454
|
+
readonly vocabulary: readonly ["ChildrenProp", "ClassNameProp"];
|
|
455
|
+
};
|
|
441
456
|
readonly SidebarProductProp: {
|
|
442
457
|
readonly group: "layout";
|
|
443
458
|
readonly file: "components/layout.prop.ts";
|
|
@@ -468,6 +483,15 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
468
483
|
readonly file: "components/general.prop.ts";
|
|
469
484
|
readonly vocabulary: readonly ["ButtonVariantProp", "SizeProp", "ShapeProp", "AsChildProp", "DisabledProp", "OnClickProp", "PendingProp"];
|
|
470
485
|
};
|
|
486
|
+
readonly RevealProp: {
|
|
487
|
+
readonly group: "general";
|
|
488
|
+
readonly file: "components/general.prop.ts";
|
|
489
|
+
readonly vocabulary: readonly ["ChildrenProp", "RevealDelayProp", "AsChildProp", "ClassNameProp", {
|
|
490
|
+
readonly field: "delay";
|
|
491
|
+
readonly local: true;
|
|
492
|
+
readonly reason: "Reveal stagger ordinal — RevealDelayProp vocabulary.";
|
|
493
|
+
}];
|
|
494
|
+
};
|
|
471
495
|
readonly TextProp: {
|
|
472
496
|
readonly group: "general";
|
|
473
497
|
readonly file: "components/general.prop.ts";
|
|
@@ -663,7 +687,12 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
663
687
|
readonly EmptyStateProp: {
|
|
664
688
|
readonly group: "data-display";
|
|
665
689
|
readonly file: "components/data-display.prop.ts";
|
|
666
|
-
readonly vocabulary: readonly ["IconProp", "TitleProp", "DescriptionProp", "ActionProp"];
|
|
690
|
+
readonly vocabulary: readonly ["IconProp", "TitleProp", "DescriptionProp", "ActionProp", "ToneProp"];
|
|
691
|
+
};
|
|
692
|
+
readonly EmptyStateToneProp: {
|
|
693
|
+
readonly group: "data-display";
|
|
694
|
+
readonly file: "components/data-display.prop.ts";
|
|
695
|
+
readonly vocabulary: readonly [];
|
|
667
696
|
};
|
|
668
697
|
readonly DescriptionsProp: {
|
|
669
698
|
readonly group: "data-display";
|
package/dist/props/registry.js
CHANGED
|
@@ -208,6 +208,11 @@ const VOCABULARY_REGISTRY = {
|
|
|
208
208
|
category: "interaction",
|
|
209
209
|
description: "Badge visual variant (default | secondary | outline | dashed)"
|
|
210
210
|
},
|
|
211
|
+
AppSettingPickerAppearanceProp: {
|
|
212
|
+
file: "vocabulary/interaction.prop.ts",
|
|
213
|
+
category: "interaction",
|
|
214
|
+
description: "AppSettingPicker trigger presentation: labeled (icon + value) | icon (square icon-only topbar trigger)"
|
|
215
|
+
},
|
|
211
216
|
ShapeProp: {
|
|
212
217
|
file: "vocabulary/interaction.prop.ts",
|
|
213
218
|
category: "interaction",
|
|
@@ -288,6 +293,11 @@ const VOCABULARY_REGISTRY = {
|
|
|
288
293
|
category: "interaction",
|
|
289
294
|
description: "Active table sort"
|
|
290
295
|
},
|
|
296
|
+
RevealDelayProp: {
|
|
297
|
+
file: "vocabulary/interaction.prop.ts",
|
|
298
|
+
category: "interaction",
|
|
299
|
+
description: "Reveal entrance-stagger ordinal (0..6) \u2014 an index into the motion ladder, never a raw ms"
|
|
300
|
+
},
|
|
291
301
|
// navigation.prop.ts
|
|
292
302
|
BreadcrumbItemProp: {
|
|
293
303
|
file: "vocabulary/navigation.prop.ts",
|
|
@@ -376,7 +386,14 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
376
386
|
AppSettingPickerProp: {
|
|
377
387
|
group: "app",
|
|
378
388
|
file: "components/app.prop.ts",
|
|
379
|
-
vocabulary: [
|
|
389
|
+
vocabulary: [
|
|
390
|
+
"ValueProp",
|
|
391
|
+
"OnValueChangeProp",
|
|
392
|
+
"DisabledProp",
|
|
393
|
+
"IdProp",
|
|
394
|
+
"ClassNameProp",
|
|
395
|
+
"AppSettingPickerAppearanceProp"
|
|
396
|
+
]
|
|
380
397
|
},
|
|
381
398
|
PageContainerProp: {
|
|
382
399
|
group: "layout",
|
|
@@ -416,6 +433,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
416
433
|
file: "components/layout.prop.ts",
|
|
417
434
|
vocabulary: ["ChildrenProp"]
|
|
418
435
|
},
|
|
436
|
+
AuthShellProp: {
|
|
437
|
+
group: "layout",
|
|
438
|
+
file: "components/layout.prop.ts",
|
|
439
|
+
vocabulary: ["ChildrenProp", "ClassNameProp"]
|
|
440
|
+
},
|
|
419
441
|
SidebarProductProp: {
|
|
420
442
|
group: "layout",
|
|
421
443
|
file: "components/layout.prop.ts",
|
|
@@ -454,6 +476,21 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
454
476
|
"PendingProp"
|
|
455
477
|
]
|
|
456
478
|
},
|
|
479
|
+
RevealProp: {
|
|
480
|
+
group: "general",
|
|
481
|
+
file: "components/general.prop.ts",
|
|
482
|
+
vocabulary: [
|
|
483
|
+
"ChildrenProp",
|
|
484
|
+
"RevealDelayProp",
|
|
485
|
+
"AsChildProp",
|
|
486
|
+
"ClassNameProp",
|
|
487
|
+
{
|
|
488
|
+
field: "delay",
|
|
489
|
+
local: true,
|
|
490
|
+
reason: "Reveal stagger ordinal \u2014 RevealDelayProp vocabulary."
|
|
491
|
+
}
|
|
492
|
+
]
|
|
493
|
+
},
|
|
457
494
|
TextProp: {
|
|
458
495
|
group: "general",
|
|
459
496
|
file: "components/general.prop.ts",
|
|
@@ -705,7 +742,12 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
705
742
|
EmptyStateProp: {
|
|
706
743
|
group: "data-display",
|
|
707
744
|
file: "components/data-display.prop.ts",
|
|
708
|
-
vocabulary: ["IconProp", "TitleProp", "DescriptionProp", "ActionProp"]
|
|
745
|
+
vocabulary: ["IconProp", "TitleProp", "DescriptionProp", "ActionProp", "ToneProp"]
|
|
746
|
+
},
|
|
747
|
+
EmptyStateToneProp: {
|
|
748
|
+
group: "data-display",
|
|
749
|
+
file: "components/data-display.prop.ts",
|
|
750
|
+
vocabulary: []
|
|
709
751
|
},
|
|
710
752
|
DescriptionsProp: {
|
|
711
753
|
group: "data-display",
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
export type { ClassNameProp, ChildrenProp, IdProp, OpenProp, DefaultOpenProp, OnOpenChangeProp, HandlerProp, PendingProp, RequiredProp, DisabledProp, LabelProp, HelperProp, ErrorProp, PlaceholderProp, NameProp, ValueProp, DefaultValueProp, OnValueChangeProp, OnChangeProp, OnClickProp, AsChildProp, WidthProp, } from "./shared.prop.js";
|
|
3
3
|
export type { TitleProp, SubtitleProp, DescriptionProp, ExtraProp, FooterProp, ActionProp, IconProp, ConfirmLabelProp, CancelLabelProp, ActionsProp, EmptyMessageProp, } from "./content.prop.js";
|
|
4
4
|
export type { PageDensityProp, PageContainerVariantProp, TableDensityProp, DensityProp, GapProp, } from "./layout.prop.js";
|
|
5
|
-
export type { ButtonVariantProp, ButtonSizeProp, BadgeVariantProp, ShapeProp, TextSizeProp, TextToneProp, FontWeightProp, HeadingLevelProp, TextAlignProp, SizeProp, FormLayoutProp, BreakpointProp, ConfirmVariantProp, ToneProp, AlertVariantProp, SortDirectionProp, ColumnAlignProp, SortStateProp, } from "./interaction.prop.js";
|
|
5
|
+
export type { ButtonVariantProp, ButtonSizeProp, BadgeVariantProp, AppSettingPickerAppearanceProp, ShapeProp, TextSizeProp, TextToneProp, FontWeightProp, HeadingLevelProp, TextAlignProp, SizeProp, FormLayoutProp, BreakpointProp, ConfirmVariantProp, ToneProp, AlertVariantProp, SortDirectionProp, ColumnAlignProp, SortStateProp, RevealDelayProp, } from "./interaction.prop.js";
|
|
6
6
|
export type { BreadcrumbItemProp, BreadcrumbProp } from "./navigation.prop.js";
|
|
7
7
|
export type { GetRowIdProp, OnRowClickProp, ColumnDefProp, SelectedIdsProp, OnSelectChangeProp, OnTableDensityChangeProp, OnSortChangeProp, OnSearchChangeProp, OnClearFiltersProp, HasActiveFiltersProp, } from "./data.prop.js";
|
|
@@ -20,6 +20,16 @@ export type HeadingLevelProp = 1 | 2 | 3 | 4;
|
|
|
20
20
|
export type TextAlignProp = "start" | "center" | "end";
|
|
21
21
|
/** Badge visual style. */
|
|
22
22
|
export type BadgeVariantProp = "default" | "secondary" | "outline" | "dashed";
|
|
23
|
+
/**
|
|
24
|
+
* AppSettingPicker trigger presentation.
|
|
25
|
+
* - `labeled` (default) — the leading icon + the selected value inside a full-width control
|
|
26
|
+
* (settings forms, preference panels).
|
|
27
|
+
* - `icon` — a square, icon-only utility trigger (e.g. a topbar globe locale switcher). It
|
|
28
|
+
* STRUCTURALLY drops the value text and the picker's owned trigger width, keeping the localized
|
|
29
|
+
* `aria-label`, focus ring, keyboard behaviour and a `--control-height` tap target (which is
|
|
30
|
+
* ≥44px on coarse/touch pointers per Rule #24) — so consumers never hide internal nodes via CSS.
|
|
31
|
+
*/
|
|
32
|
+
export type AppSettingPickerAppearanceProp = "labeled" | "icon";
|
|
23
33
|
/** Button size preset. */
|
|
24
34
|
export type SizeProp = "xs" | "sm" | "md" | "lg";
|
|
25
35
|
/** Button size preset; icon-only sizes are a documented Button subset. */
|
|
@@ -46,3 +56,9 @@ export type SortStateProp = {
|
|
|
46
56
|
key: string;
|
|
47
57
|
direction: SortDirectionProp;
|
|
48
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* Entrance-stagger ordinal for `Reveal` — an INDEX into the motion ladder, never a raw ms.
|
|
61
|
+
* `0` = enter immediately; `1..6` each add one `--reveal-stagger-step` of delay so a column of
|
|
62
|
+
* revealed rows cascades in. Reduced-motion collapses every step to 0 (content stays visible).
|
|
63
|
+
*/
|
|
64
|
+
export type RevealDelayProp = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
@@ -107,8 +107,7 @@
|
|
|
107
107
|
grid-column: 1;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
[data-slot="alert-body"]:has(> [data-slot="alert-actions"])
|
|
111
|
-
> [data-slot="alert-actions"] {
|
|
110
|
+
[data-slot="alert-body"]:has(> [data-slot="alert-actions"]) > [data-slot="alert-actions"] {
|
|
112
111
|
grid-column: 2;
|
|
113
112
|
grid-row: 1;
|
|
114
113
|
}
|
|
@@ -34,8 +34,7 @@
|
|
|
34
34
|
* --card-background defaults to the LIVE --card role at the call site (re-resolves under a
|
|
35
35
|
* scoped theme); a service overrides --card-background to win. */
|
|
36
36
|
background:
|
|
37
|
-
linear-gradient(var(--card-tint), var(--card-tint)),
|
|
38
|
-
hsl(var(--card-background, var(--card)));
|
|
37
|
+
linear-gradient(var(--card-tint), var(--card-tint)), hsl(var(--card-background, var(--card)));
|
|
39
38
|
color: hsl(var(--card-foreground));
|
|
40
39
|
/* Resting elevation + opt-in brand glow — both quiet no-ops by default so a service theme can
|
|
41
40
|
* lift (--card-shadow) and/or glow (--card-glow) every card with no markup change. */
|
|
@@ -100,9 +99,7 @@
|
|
|
100
99
|
[data-slot="card"][data-accent] > [data-slot="card-header"],
|
|
101
100
|
[data-slot="card"][data-accent] > [data-slot="card-content"]:not([data-flush]),
|
|
102
101
|
[data-slot="card"][data-accent] > [data-slot="card-footer"]:not([data-flush]) {
|
|
103
|
-
padding-inline-start: calc(
|
|
104
|
-
var(--card-space-inset) - var(--card-accent-rail-width)
|
|
105
|
-
);
|
|
102
|
+
padding-inline-start: calc(var(--card-space-inset) - var(--card-accent-rail-width));
|
|
106
103
|
}
|
|
107
104
|
|
|
108
105
|
/* ── Header ──────────────────────────────────────────────────────────── */
|
|
@@ -156,7 +153,10 @@
|
|
|
156
153
|
}
|
|
157
154
|
|
|
158
155
|
.ui-card-header--banded {
|
|
159
|
-
border-bottom: var(
|
|
156
|
+
border-bottom: var(
|
|
157
|
+
--card-header-border-bottom,
|
|
158
|
+
1px solid hsl(var(--card-border, var(--border)))
|
|
159
|
+
);
|
|
160
160
|
background-color: hsl(
|
|
161
161
|
var(--card-header-background, var(--muted)) / var(--card-header-background-alpha)
|
|
162
162
|
);
|
|
@@ -56,6 +56,24 @@
|
|
|
56
56
|
background: hsl(var(--warning));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
.ui-progress[data-tone="destructive"] .ui-progress-bar {
|
|
60
|
+
background: hsl(var(--destructive));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* Over-capacity: keep the destructive fill but lay a diagonal hatch over it so an over-limit bar
|
|
64
|
+
* (value > 100, width still capped at 100%) is visually distinct from a full one. Placed after the
|
|
65
|
+
* tone rules so background-color wins; background-image carries the stripes. */
|
|
66
|
+
.ui-progress[data-over] .ui-progress-bar {
|
|
67
|
+
background-color: hsl(var(--destructive));
|
|
68
|
+
background-image: repeating-linear-gradient(
|
|
69
|
+
45deg,
|
|
70
|
+
hsl(var(--destructive-foreground) / 0.4) 0,
|
|
71
|
+
hsl(var(--destructive-foreground) / 0.4) 0.3rem,
|
|
72
|
+
transparent 0.3rem,
|
|
73
|
+
transparent 0.6rem
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
59
77
|
.ui-progress-label {
|
|
60
78
|
color: hsl(var(--muted-foreground));
|
|
61
79
|
font-size: var(--progress-label-font-size);
|
package/dist/styles/index.css
CHANGED
|
@@ -15,8 +15,10 @@
|
|
|
15
15
|
@import "./fonts.css";
|
|
16
16
|
@import "./base.css";
|
|
17
17
|
@import "./shell-layout.css";
|
|
18
|
+
@import "./motion.css";
|
|
18
19
|
@import "./layout.css";
|
|
19
20
|
@import "./control.css";
|
|
21
|
+
@import "./logo-layout.css";
|
|
20
22
|
@import "./card-layout.css";
|
|
21
23
|
@import "./text-layout.css";
|
|
22
24
|
@import "./table-layout.css";
|
package/dist/styles/layout.css
CHANGED
|
@@ -46,6 +46,15 @@
|
|
|
46
46
|
flex-direction: column;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
.ui-empty-state[data-variant="section"] {
|
|
50
|
+
padding: var(--empty-state-section-space-y) var(--empty-state-section-space-x);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.ui-empty-state[data-variant="compact"] {
|
|
54
|
+
padding: var(--empty-state-compact-space-y) var(--empty-state-compact-space-x);
|
|
55
|
+
gap: var(--space-stack-xs);
|
|
56
|
+
}
|
|
57
|
+
|
|
49
58
|
.ui-flex[data-wrap="true"] {
|
|
50
59
|
flex-wrap: wrap;
|
|
51
60
|
}
|
|
@@ -512,6 +521,25 @@
|
|
|
512
521
|
background-color: var(--empty-state-icon-tint, hsl(var(--muted)));
|
|
513
522
|
color: var(--empty-state-icon-foreground, hsl(var(--muted-foreground)));
|
|
514
523
|
}
|
|
524
|
+
|
|
525
|
+
/* tone — set the medallion foreground + tint from the matching role token, so a consumer never
|
|
526
|
+
* hand-rolls a `.ui-success-state` class. `muted` (default) keeps the neutral role fallback. */
|
|
527
|
+
.ui-empty-state[data-tone="success"] {
|
|
528
|
+
--empty-state-icon-foreground: hsl(var(--success));
|
|
529
|
+
--empty-state-icon-tint: hsl(var(--success) / 0.12);
|
|
530
|
+
}
|
|
531
|
+
.ui-empty-state[data-tone="warning"] {
|
|
532
|
+
--empty-state-icon-foreground: hsl(var(--warning));
|
|
533
|
+
--empty-state-icon-tint: hsl(var(--warning) / 0.12);
|
|
534
|
+
}
|
|
535
|
+
.ui-empty-state[data-tone="destructive"] {
|
|
536
|
+
--empty-state-icon-foreground: hsl(var(--destructive));
|
|
537
|
+
--empty-state-icon-tint: hsl(var(--destructive) / 0.12);
|
|
538
|
+
}
|
|
539
|
+
.ui-empty-state[data-tone="info"] {
|
|
540
|
+
--empty-state-icon-foreground: hsl(var(--info));
|
|
541
|
+
--empty-state-icon-tint: hsl(var(--info) / 0.12);
|
|
542
|
+
}
|
|
515
543
|
}
|
|
516
544
|
|
|
517
545
|
@layer components {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* LOGO — the product brand-mark box (a glyph on the primary fill). Replaces the hand-rolled
|
|
3
|
+
* `<span aria-hidden className="grid size-7 place-items-center rounded-md bg-primary …">g</span>`
|
|
4
|
+
* repeated across app shells and topbars (issue #116): size/radius/font-size are tokens (rule #45),
|
|
5
|
+
* colours read the primary role directly, and the type comes from a semantic class (not utilities
|
|
6
|
+
* on a bare span, rule #46).
|
|
7
|
+
*/
|
|
8
|
+
@layer components {
|
|
9
|
+
.ui-logo {
|
|
10
|
+
display: inline-grid;
|
|
11
|
+
place-items: center;
|
|
12
|
+
flex: 0 0 auto;
|
|
13
|
+
width: var(--logo-size-md);
|
|
14
|
+
height: var(--logo-size-md);
|
|
15
|
+
border-radius: var(--logo-radius);
|
|
16
|
+
background: hsl(var(--primary));
|
|
17
|
+
color: hsl(var(--primary-foreground));
|
|
18
|
+
font-weight: 700;
|
|
19
|
+
font-size: var(--logo-font-size-md);
|
|
20
|
+
line-height: 1;
|
|
21
|
+
user-select: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.ui-logo[data-size="xs"] {
|
|
25
|
+
width: var(--logo-size-xs);
|
|
26
|
+
height: var(--logo-size-xs);
|
|
27
|
+
font-size: var(--logo-font-size-xs);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.ui-logo[data-size="sm"] {
|
|
31
|
+
width: var(--logo-size-sm);
|
|
32
|
+
height: var(--logo-size-sm);
|
|
33
|
+
font-size: var(--logo-font-size-sm);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.ui-logo[data-size="lg"] {
|
|
37
|
+
width: var(--logo-size-lg);
|
|
38
|
+
height: var(--logo-size-lg);
|
|
39
|
+
font-size: var(--logo-font-size-lg);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MOTION — entrance/reveal animation for the `Reveal` primitive.
|
|
3
|
+
* Reads the DS motion tokens (--duration-slow / --ease-emphasized / --reveal-distance) instead of
|
|
4
|
+
* a hand-rolled @keyframes, and staggers via the --reveal-stagger-step ladder. Under
|
|
5
|
+
* prefers-reduced-motion the animation is dropped: content renders in its final, fully-visible
|
|
6
|
+
* position with no transform and no layout shift.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
@layer components {
|
|
10
|
+
.ui-reveal {
|
|
11
|
+
animation: ui-reveal-in var(--duration-slow) var(--ease-emphasized) both;
|
|
12
|
+
will-change: transform, opacity;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.ui-reveal[data-reveal-delay="1"] {
|
|
16
|
+
animation-delay: calc(var(--reveal-stagger-step) * 1);
|
|
17
|
+
}
|
|
18
|
+
.ui-reveal[data-reveal-delay="2"] {
|
|
19
|
+
animation-delay: calc(var(--reveal-stagger-step) * 2);
|
|
20
|
+
}
|
|
21
|
+
.ui-reveal[data-reveal-delay="3"] {
|
|
22
|
+
animation-delay: calc(var(--reveal-stagger-step) * 3);
|
|
23
|
+
}
|
|
24
|
+
.ui-reveal[data-reveal-delay="4"] {
|
|
25
|
+
animation-delay: calc(var(--reveal-stagger-step) * 4);
|
|
26
|
+
}
|
|
27
|
+
.ui-reveal[data-reveal-delay="5"] {
|
|
28
|
+
animation-delay: calc(var(--reveal-stagger-step) * 5);
|
|
29
|
+
}
|
|
30
|
+
.ui-reveal[data-reveal-delay="6"] {
|
|
31
|
+
animation-delay: calc(var(--reveal-stagger-step) * 6);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@keyframes ui-reveal-in {
|
|
35
|
+
from {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
transform: translateY(var(--reveal-distance));
|
|
38
|
+
}
|
|
39
|
+
to {
|
|
40
|
+
opacity: 1;
|
|
41
|
+
transform: none;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Accessibility: no motion → no animation, content stays visible (WCAG 2.3.3 / 2.2.2). */
|
|
46
|
+
@media (prefers-reduced-motion: reduce) {
|
|
47
|
+
.ui-reveal,
|
|
48
|
+
.ui-reveal[data-reveal-delay] {
|
|
49
|
+
animation: none;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -81,6 +81,48 @@
|
|
|
81
81
|
max-width: none;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/*
|
|
85
|
+
* AUTH SHELL — centred auth/login page shell (brand bar + centred card + footer).
|
|
86
|
+
* Comfortable control density + a larger auth heading are scoped to the shell so login/mfa/reset
|
|
87
|
+
* forms read at the right size without a consumer scope class. Everything reads a token knob.
|
|
88
|
+
*/
|
|
89
|
+
.ui-auth-shell {
|
|
90
|
+
--control-height: var(--auth-shell-control-height);
|
|
91
|
+
--heading-h1: var(--auth-shell-heading-size);
|
|
92
|
+
display: flex;
|
|
93
|
+
min-height: 100dvh;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
background:
|
|
96
|
+
linear-gradient(180deg, hsl(var(--primary) / 0.035), transparent 14rem),
|
|
97
|
+
hsl(var(--background));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.ui-auth-shell-bar {
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: center;
|
|
103
|
+
padding: var(--auth-shell-bar-padding);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.ui-auth-shell-main {
|
|
107
|
+
display: flex;
|
|
108
|
+
flex: 1 1 auto;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
align-items: center;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
padding: var(--auth-shell-main-padding);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.ui-auth-shell-card {
|
|
116
|
+
width: 100%;
|
|
117
|
+
max-width: var(--auth-shell-card-max-width);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.ui-auth-shell-footer {
|
|
121
|
+
padding: var(--auth-shell-footer-padding);
|
|
122
|
+
text-align: center;
|
|
123
|
+
color: hsl(var(--muted-foreground));
|
|
124
|
+
}
|
|
125
|
+
|
|
84
126
|
.app-topbar-rail {
|
|
85
127
|
display: flex;
|
|
86
128
|
min-width: 0;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* ───────────────────────────────────────────────────────────────
|
|
2
|
+
* Famgia service theme — ファムジア株式会社
|
|
3
|
+
* Re-themes @godxjp/ui via SEMANTIC TOKENS only (no component CSS).
|
|
4
|
+
* Brand: electric blue #2563EB (primary) + violet #7C3AED (accent gradient).
|
|
5
|
+
* Import this instead of "@godxjp/ui/styles".
|
|
6
|
+
* ─────────────────────────────────────────────────────────────── */
|
|
7
|
+
|
|
8
|
+
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Noto+Sans+JP:wght@400;500;700&display=swap");
|
|
9
|
+
@import "@godxjp/ui/styles";
|
|
10
|
+
|
|
11
|
+
/* ── Light (default) ── */
|
|
12
|
+
:root {
|
|
13
|
+
/* Brand primary ramp — electric blue */
|
|
14
|
+
--primary: 221 83% 53%; /* #2563EB */
|
|
15
|
+
--primary-foreground: 0 0% 100%;
|
|
16
|
+
--primary-hover: 224 71% 48%; /* #1D4ED8 */
|
|
17
|
+
--primary-active: 226 71% 40%; /* #1E40AF */
|
|
18
|
+
--ring: 221 83% 53%;
|
|
19
|
+
|
|
20
|
+
/* Brand-colored text (AA on tint/white) */
|
|
21
|
+
--text-link: 224 76% 45%;
|
|
22
|
+
--text-brand: 221 83% 53%;
|
|
23
|
+
--text-primary: 224 76% 42%;
|
|
24
|
+
|
|
25
|
+
/* Signature brand gradient: blue → violet */
|
|
26
|
+
--gradient-brand: linear-gradient(135deg, hsl(221 83% 53%), hsl(262 83% 58%));
|
|
27
|
+
|
|
28
|
+
/* Typography — Inter (Latin/VI) + Noto Sans JP (kana/kanji) */
|
|
29
|
+
--font-family-sans:
|
|
30
|
+
"Inter", "Noto Sans JP", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
31
|
+
"Helvetica Neue", Arial, sans-serif;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* ── Dark ── lifted blue for contrast */
|
|
35
|
+
.dark {
|
|
36
|
+
--primary: 221 90% 66%;
|
|
37
|
+
--primary-foreground: 222 47% 11%;
|
|
38
|
+
--primary-hover: 221 90% 72%;
|
|
39
|
+
--primary-active: 221 90% 60%;
|
|
40
|
+
--ring: 221 90% 66%;
|
|
41
|
+
--text-link: 221 90% 72%;
|
|
42
|
+
--text-brand: 221 90% 70%;
|
|
43
|
+
--text-primary: 221 90% 68%;
|
|
44
|
+
}
|
package/dist/tokens/base.css
CHANGED
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
--dialog-content-glow: 0 0 0 0 transparent;
|
|
23
23
|
--empty-state-space-y: var(--space-10);
|
|
24
24
|
--empty-state-space-x: var(--space-6);
|
|
25
|
+
--empty-state-section-space-y: var(--space-6);
|
|
26
|
+
--empty-state-section-space-x: var(--space-4);
|
|
27
|
+
--empty-state-compact-space-y: var(--space-3);
|
|
28
|
+
--empty-state-compact-space-x: var(--space-2);
|
|
25
29
|
/* EmptyState icon medallion colour — `initial` so the role defaults re-resolve at the call site
|
|
26
30
|
* under a scoped theme (rule #44). A service recolours the glyph (--empty-state-icon-foreground)
|
|
27
31
|
* or washes the medallion fill (--empty-state-icon-tint) without forking.
|