@godxjp/ui 16.6.0 → 16.7.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/dist/components/data-display/badge.d.ts +6 -1
- package/dist/components/data-display/badge.js +2 -0
- package/dist/components/data-entry/input.d.ts +12 -0
- package/dist/components/data-entry/input.js +17 -2
- package/dist/components/general/typography.d.ts +1 -0
- package/dist/components/general/typography.js +2 -1
- package/dist/lib/control-styles.d.ts +5 -0
- package/dist/lib/control-styles.js +2 -0
- package/dist/props/components/data-display.prop.d.ts +2 -1
- package/dist/props/components/data-entry.prop.d.ts +4 -0
- package/dist/props/components/general.prop.d.ts +2 -0
- package/dist/styles/index.css +2 -1
- package/dist/styles/layout.css +10 -0
- package/dist/styles/text-layout.css +9 -4
- package/dist/tokens/foundation.css +17 -0
- package/package.json +1 -1
|
@@ -2,7 +2,12 @@ import * as React from "react";
|
|
|
2
2
|
import { type VariantProps } from "class-variance-authority";
|
|
3
3
|
import type { ShapeProp, ToneProp } from "../../props/vocabulary";
|
|
4
4
|
export type BadgeVariant = "default" | "secondary" | "outline" | "dashed";
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Badge tones extend the shared status `ToneProp` with a brand `primary` tone — a SOFT brand pill
|
|
7
|
+
* (tinted fill + brand text), the dashboard "role pill" pattern. The status tones stay status-only;
|
|
8
|
+
* for a SOLID brand fill use `variant="default"`.
|
|
9
|
+
*/
|
|
10
|
+
export type BadgeTone = ToneProp | "primary";
|
|
6
11
|
declare const badgeVariants: (props?: ({
|
|
7
12
|
variant?: "default" | "outline" | "dashed" | "secondary" | null | undefined;
|
|
8
13
|
shape?: "default" | "pill" | "sharp" | null | undefined;
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
toneInfoClass,
|
|
18
18
|
toneMutedClass,
|
|
19
19
|
toneNeutralClass,
|
|
20
|
+
tonePrimaryClass,
|
|
20
21
|
toneSuccessClass,
|
|
21
22
|
toneWarningClass
|
|
22
23
|
} from "../../lib/control-styles";
|
|
@@ -65,6 +66,7 @@ const badgeVariants = cva(
|
|
|
65
66
|
);
|
|
66
67
|
const badgeToneClass = {
|
|
67
68
|
default: void 0,
|
|
69
|
+
primary: cn("border-transparent", tonePrimaryClass),
|
|
68
70
|
success: cn("border-transparent", toneSuccessClass),
|
|
69
71
|
warning: cn("border-transparent", toneWarningClass),
|
|
70
72
|
destructive: cn("border-transparent", toneDestructiveClass),
|
|
@@ -4,6 +4,12 @@ export type InputProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
|
4
4
|
allowClear?: boolean;
|
|
5
5
|
/** Called after the field is cleared via the inline ✕. */
|
|
6
6
|
onClear?: () => void;
|
|
7
|
+
/**
|
|
8
|
+
* A leading affordance pinned inside the start of the field — e.g. a mail or
|
|
9
|
+
* search icon (the common auth/search pattern). Decorative by default; the
|
|
10
|
+
* input keeps the keyboard focus. Pairs with `trailingIcon`/`allowClear`.
|
|
11
|
+
*/
|
|
12
|
+
leadingIcon?: React.ReactNode;
|
|
7
13
|
/**
|
|
8
14
|
* A trailing affordance pinned inside the field — e.g. a calendar / clock popover
|
|
9
15
|
* trigger button. ONE trailing icon shows at a time: when `allowClear` and the field
|
|
@@ -16,6 +22,12 @@ export declare const Input: React.ForwardRefExoticComponent<React.InputHTMLAttri
|
|
|
16
22
|
allowClear?: boolean;
|
|
17
23
|
/** Called after the field is cleared via the inline ✕. */
|
|
18
24
|
onClear?: () => void;
|
|
25
|
+
/**
|
|
26
|
+
* A leading affordance pinned inside the start of the field — e.g. a mail or
|
|
27
|
+
* search icon (the common auth/search pattern). Decorative by default; the
|
|
28
|
+
* input keeps the keyboard focus. Pairs with `trailingIcon`/`allowClear`.
|
|
29
|
+
*/
|
|
30
|
+
leadingIcon?: React.ReactNode;
|
|
19
31
|
/**
|
|
20
32
|
* A trailing affordance pinned inside the field — e.g. a calendar / clock popover
|
|
21
33
|
* trigger button. ONE trailing icon shows at a time: when `allowClear` and the field
|
|
@@ -18,6 +18,7 @@ const Input = React.forwardRef(
|
|
|
18
18
|
type,
|
|
19
19
|
allowClear = false,
|
|
20
20
|
onClear,
|
|
21
|
+
leadingIcon,
|
|
21
22
|
trailingIcon,
|
|
22
23
|
value,
|
|
23
24
|
defaultValue,
|
|
@@ -58,7 +59,7 @@ const Input = React.forwardRef(
|
|
|
58
59
|
setHasText(false);
|
|
59
60
|
onClear?.();
|
|
60
61
|
};
|
|
61
|
-
if (!allowClear && trailingIcon == null) {
|
|
62
|
+
if (!allowClear && trailingIcon == null && leadingIcon == null) {
|
|
62
63
|
return /* @__PURE__ */ jsx(
|
|
63
64
|
"input",
|
|
64
65
|
{
|
|
@@ -86,6 +87,15 @@ const Input = React.forwardRef(
|
|
|
86
87
|
}
|
|
87
88
|
) : trailingIcon;
|
|
88
89
|
return /* @__PURE__ */ jsxs("span", { "data-slot": "input-affix-wrapper", className: "relative inline-flex w-full items-center", children: [
|
|
90
|
+
leadingIcon != null ? /* @__PURE__ */ jsx(
|
|
91
|
+
"span",
|
|
92
|
+
{
|
|
93
|
+
"data-slot": "input-leading",
|
|
94
|
+
"aria-hidden": "true",
|
|
95
|
+
className: "text-muted-foreground pointer-events-none absolute inset-y-0 start-2 inline-flex items-center",
|
|
96
|
+
children: leadingIcon
|
|
97
|
+
}
|
|
98
|
+
) : null,
|
|
89
99
|
/* @__PURE__ */ jsx(
|
|
90
100
|
"input",
|
|
91
101
|
{
|
|
@@ -95,7 +105,12 @@ const Input = React.forwardRef(
|
|
|
95
105
|
value,
|
|
96
106
|
defaultValue,
|
|
97
107
|
onChange: handleChange,
|
|
98
|
-
className: cn(
|
|
108
|
+
className: cn(
|
|
109
|
+
inputBaseClass,
|
|
110
|
+
leadingIcon != null && "ps-9",
|
|
111
|
+
(showClear || trailingIcon != null) && "pe-9",
|
|
112
|
+
className
|
|
113
|
+
),
|
|
99
114
|
...props
|
|
100
115
|
}
|
|
101
116
|
),
|
|
@@ -27,4 +27,5 @@ export declare const Heading: React.ForwardRefExoticComponent<Omit<React.HTMLAtt
|
|
|
27
27
|
tone?: import("../../props").TextToneProp;
|
|
28
28
|
align?: import("../../props").TextAlignProp;
|
|
29
29
|
truncate?: boolean;
|
|
30
|
+
weight?: import("../../props").FontWeightProp;
|
|
30
31
|
} & React.RefAttributes<HTMLHeadingElement>>;
|
|
@@ -28,12 +28,13 @@ const Text = React.forwardRef(
|
|
|
28
28
|
);
|
|
29
29
|
Text.displayName = "Text";
|
|
30
30
|
const Heading = React.forwardRef(
|
|
31
|
-
({ level = 2, as, tone = "default", align, truncate, className, ...props }, ref) => React.createElement(as ?? `h${level}`, {
|
|
31
|
+
({ level = 2, as, tone = "default", align, truncate, weight = "medium", className, ...props }, ref) => React.createElement(as ?? `h${level}`, {
|
|
32
32
|
ref,
|
|
33
33
|
"data-slot": "heading",
|
|
34
34
|
"data-level": level,
|
|
35
35
|
"data-tone": tone,
|
|
36
36
|
"data-align": align,
|
|
37
|
+
"data-weight": weight,
|
|
37
38
|
"data-truncate": truncate ? "" : void 0,
|
|
38
39
|
className: cn("ui-heading", className),
|
|
39
40
|
...props
|
|
@@ -23,6 +23,11 @@ export declare const tableCellPaddingClass = "py-[length:var(--table-cell-paddin
|
|
|
23
23
|
export declare const toneSuccessClass = "border-success/30 bg-success/10 text-success-strong";
|
|
24
24
|
export declare const toneWarningClass = "border-warning/30 bg-warning/10 text-warning-strong";
|
|
25
25
|
export declare const toneInfoClass = "border-info/30 bg-info/10 text-info-strong";
|
|
26
|
+
/** Soft BRAND pill — a tinted primary tone (border/fill keep the brand role; the TEXT uses the
|
|
27
|
+
* AA-strong brand colour `text-primary-strong`, darker than the fill, so a small brand label clears
|
|
28
|
+
* WCAG AA on the soft tint — `text-primary` alone is only 4.04:1 in light). For a SOLID brand fill
|
|
29
|
+
* use the Badge `default` variant instead. */
|
|
30
|
+
export declare const tonePrimaryClass = "border-primary/30 bg-primary/10 text-primary-strong";
|
|
26
31
|
export declare const toneDestructiveClass = "border-destructive/30 bg-destructive/10 text-error-strong";
|
|
27
32
|
export declare const toneMutedClass = "border-border bg-muted text-muted-foreground";
|
|
28
33
|
export declare const toneNeutralClass = "border-border bg-muted text-muted-foreground";
|
|
@@ -11,6 +11,7 @@ const tableCellPaddingClass = "py-[length:var(--table-cell-padding-y)]";
|
|
|
11
11
|
const toneSuccessClass = "border-success/30 bg-success/10 text-success-strong";
|
|
12
12
|
const toneWarningClass = "border-warning/30 bg-warning/10 text-warning-strong";
|
|
13
13
|
const toneInfoClass = "border-info/30 bg-info/10 text-info-strong";
|
|
14
|
+
const tonePrimaryClass = "border-primary/30 bg-primary/10 text-primary-strong";
|
|
14
15
|
const toneDestructiveClass = "border-destructive/30 bg-destructive/10 text-error-strong";
|
|
15
16
|
const toneMutedClass = "border-border bg-muted text-muted-foreground";
|
|
16
17
|
const toneNeutralClass = "border-border bg-muted text-muted-foreground";
|
|
@@ -29,6 +30,7 @@ export {
|
|
|
29
30
|
toneInfoClass,
|
|
30
31
|
toneMutedClass,
|
|
31
32
|
toneNeutralClass,
|
|
33
|
+
tonePrimaryClass,
|
|
32
34
|
toneSuccessClass,
|
|
33
35
|
toneWarningClass
|
|
34
36
|
};
|
|
@@ -23,7 +23,8 @@ export type DescriptionsItemProp = {
|
|
|
23
23
|
/** @see Badge */
|
|
24
24
|
export type BadgeProp = {
|
|
25
25
|
variant?: "default" | "secondary" | "outline";
|
|
26
|
-
tone
|
|
26
|
+
/** Status tones plus a brand `primary` tone (soft brand pill); solid brand = `variant="default"`. */
|
|
27
|
+
tone?: ToneProp | "primary";
|
|
27
28
|
status?: string;
|
|
28
29
|
icon?: React.ComponentType<{
|
|
29
30
|
className?: string;
|
|
@@ -15,6 +15,10 @@ export type InputProp = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
|
15
15
|
allowClear?: boolean;
|
|
16
16
|
/** Called after the field is cleared via the inline ✕. */
|
|
17
17
|
onClear?: () => void;
|
|
18
|
+
/** A leading affordance pinned inside the start of the field (e.g. a mail/lock icon). */
|
|
19
|
+
leadingIcon?: React.ReactNode;
|
|
20
|
+
/** A trailing affordance pinned inside the end of the field (replaced by the clear ✕ when `allowClear` + value). */
|
|
21
|
+
trailingIcon?: React.ReactNode;
|
|
18
22
|
};
|
|
19
23
|
/** @see Textarea */
|
|
20
24
|
export type TextareaProp = React.TextareaHTMLAttributes<HTMLTextAreaElement> & {
|
|
@@ -28,6 +28,8 @@ export type HeadingProp = Omit<React.HTMLAttributes<HTMLHeadingElement>, "color"
|
|
|
28
28
|
tone?: TextToneProp;
|
|
29
29
|
align?: TextAlignProp;
|
|
30
30
|
truncate?: boolean;
|
|
31
|
+
/** Weight (system canon: 400 · 500 · 700). Default `medium` — set `bold` for an emphasised title. */
|
|
32
|
+
weight?: FontWeightProp;
|
|
31
33
|
};
|
|
32
34
|
/** @see Button */
|
|
33
35
|
export type ButtonProp = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
package/dist/styles/index.css
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
@source inline("rounded-{xs,xl,2xl}");
|
|
43
43
|
@source inline("text-2xs");
|
|
44
44
|
@source inline("text-{3xl,4xl,5xl}");
|
|
45
|
-
@source inline("text-{success,warning,info,error}-strong");
|
|
45
|
+
@source inline("text-{primary,success,warning,info,error}-strong");
|
|
46
46
|
/* `.js` matters: the published package ships only compiled JS under dist (no
|
|
47
47
|
* .tsx sources), and this file is copied verbatim into dist/styles — without
|
|
48
48
|
* it Tailwind finds no component classes in consumers (unstyled popovers and
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
--color-attention-foreground: hsl(var(--attention-foreground));
|
|
104
104
|
/* AA-strong status TEXT colours (text-{success,warning,info,error}-strong) — darker than the
|
|
105
105
|
* fills so small coloured labels clear WCAG AA on white; flip light on the dark theme. */
|
|
106
|
+
--color-primary-strong: hsl(var(--text-primary));
|
|
106
107
|
--color-success-strong: hsl(var(--text-success));
|
|
107
108
|
--color-warning-strong: hsl(var(--text-warning));
|
|
108
109
|
--color-info-strong: hsl(var(--text-info));
|
package/dist/styles/layout.css
CHANGED
|
@@ -23,6 +23,16 @@
|
|
|
23
23
|
overflow: hidden;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/* Decorative brand SPOTLIGHT backdrop — the token-driven radial halo behind a hero / auth card,
|
|
27
|
+
* replacing a hand-authored `radial-gradient(... hsl(var(--primary)/.18) ...)`. Apply to an
|
|
28
|
+
* `aria-hidden` layer (e.g. an absolutely-positioned full-bleed div behind the card). All geometry
|
|
29
|
+
* and tint come from the `--brand-glow*` tokens, so a theme retints/repositions it with no markup
|
|
30
|
+
* change. `pointer-events:none` keeps the backdrop from stealing clicks from the card above it. */
|
|
31
|
+
.ui-brand-glow {
|
|
32
|
+
background-image: var(--brand-glow);
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
.ui-flex,
|
|
27
37
|
.ui-stack-xs {
|
|
28
38
|
display: flex;
|
|
@@ -33,14 +33,19 @@
|
|
|
33
33
|
font-size: var(--font-size-2xl);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
/* Weight — the dxs-kintai canon (400 body · 500 heading/label · 700 emphasis). No 600.
|
|
37
|
-
|
|
36
|
+
/* Weight — the dxs-kintai canon (400 body · 500 heading/label · 700 emphasis). No 600.
|
|
37
|
+
* Shared by text + heading; the two-attribute heading selectors outrank the base heading
|
|
38
|
+
* rule below, so `<Heading weight="bold">` renders a semantic, emphasised title. */
|
|
39
|
+
[data-slot="text"][data-weight="regular"],
|
|
40
|
+
[data-slot="heading"][data-weight="regular"] {
|
|
38
41
|
font-weight: var(--font-weight-normal);
|
|
39
42
|
}
|
|
40
|
-
[data-slot="text"][data-weight="medium"]
|
|
43
|
+
[data-slot="text"][data-weight="medium"],
|
|
44
|
+
[data-slot="heading"][data-weight="medium"] {
|
|
41
45
|
font-weight: var(--font-weight-medium);
|
|
42
46
|
}
|
|
43
|
-
[data-slot="text"][data-weight="bold"]
|
|
47
|
+
[data-slot="text"][data-weight="bold"],
|
|
48
|
+
[data-slot="heading"][data-weight="bold"] {
|
|
44
49
|
font-weight: var(--font-weight-bold);
|
|
45
50
|
}
|
|
46
51
|
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
/* Status TEXT colours — darker than the fill roles so small coloured text (a StatCard delta, an
|
|
41
41
|
* outline status badge label) clears WCAG AA 4.5:1 on white. The fill roles (--success/--warning/
|
|
42
42
|
* --info) stay the brighter wa-iro for badges/bars; only TEXT reads these via text-*-strong. */
|
|
43
|
+
--text-primary: 204 100% 30%; /* deep brand blue — AA brand text on the soft primary tint */
|
|
43
44
|
--text-success: 152 84% 22%; /* deep 若竹 — AA green text on white */
|
|
44
45
|
--text-warning: 36 100% 28%; /* dark 山吹 amber — yellow can never pass as text */
|
|
45
46
|
--text-info: 221 70% 38%; /* deep 群青 — AA blue text on white */
|
|
@@ -107,6 +108,21 @@
|
|
|
107
108
|
* — the CTA then carries a brand glow with no component change. */
|
|
108
109
|
--shadow-glow: 0 0 0 0 transparent;
|
|
109
110
|
|
|
111
|
+
/* Brand SPOTLIGHT — a decorative radial brand halo for hero / auth backdrops (the `.ui-brand-glow`
|
|
112
|
+
* utility paints this as a background-image on an aria-hidden layer). Every knob is a token, so a
|
|
113
|
+
* service retints (`--brand-glow-color`), softens (`--brand-glow-alpha`), resizes
|
|
114
|
+
* (`--brand-glow-size`) or repositions (`--brand-glow-position`) the halo with no markup change;
|
|
115
|
+
* override the whole `--brand-glow` for a bespoke gradient. Default: a soft primary glow up top. */
|
|
116
|
+
--brand-glow-color: var(--primary);
|
|
117
|
+
--brand-glow-alpha: 0.18;
|
|
118
|
+
--brand-glow-size: 60% 50%;
|
|
119
|
+
--brand-glow-position: 50% 0%;
|
|
120
|
+
--brand-glow: radial-gradient(
|
|
121
|
+
ellipse var(--brand-glow-size) at var(--brand-glow-position),
|
|
122
|
+
hsl(var(--brand-glow-color) / var(--brand-glow-alpha)),
|
|
123
|
+
transparent 70%
|
|
124
|
+
);
|
|
125
|
+
|
|
110
126
|
/* FOCUS RING — the two global knobs for the keyboard-focus affordance (WCAG 2.4.7 / 2.4.11).
|
|
111
127
|
* `--focus-ring-color` is the themeable hue (HSL components, defaults to --ring) and
|
|
112
128
|
* `--focus-ring-width` the standard thickness; override either ONCE — even scoped under a
|
|
@@ -345,6 +361,7 @@
|
|
|
345
361
|
--text-link: 204 90% 66%;
|
|
346
362
|
--text-brand: 204 90% 66%;
|
|
347
363
|
/* Status text on the dark spine reads LIGHT (AA on dark surfaces). */
|
|
364
|
+
--text-primary: 204 90% 64%; /* lifted brand blue — AA on the dark primary tint */
|
|
348
365
|
--text-success: 146 55% 64%;
|
|
349
366
|
--text-warning: 44 95% 62%;
|
|
350
367
|
--text-info: 221 70% 72%;
|