@godxjp/ui 27.4.1 → 27.6.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/range-timeline.js +9 -6
- package/dist/components/data-entry/upload-file-kind.d.ts +25 -0
- package/dist/components/data-entry/upload-file-kind.js +88 -0
- package/dist/components/data-entry/upload.d.ts +2 -2
- package/dist/components/data-entry/upload.js +10 -6
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.js +2 -0
- package/dist/components/ui/segmented.d.ts +7 -2
- package/dist/components/ui/toggle.d.ts +2 -2
- package/dist/components/ui/toggle.js +4 -0
- package/dist/contracts/measurement.json +1 -1
- package/dist/props/components/data-display.prop.d.ts +14 -0
- package/dist/props/components/data-entry.prop.d.ts +28 -2
- package/dist/props/registry.d.ts +6 -1
- package/dist/props/registry.js +6 -1
- package/dist/styles/control.css +18 -6
- package/dist/styles/data-display-layout.css +40 -8
- package/dist/styles/data-entry-layout.css +22 -0
- package/dist/tokens/components/control.css +1 -0
- package/dist/tokens/components/data-display.css +26 -0
- package/dist/tokens/components/segmented.css +4 -0
- package/dist/tokens/components/upload.css +4 -0
- package/docs/CUSTOMER-THEMING.md +26 -0
- package/docs/data-display/avatar.tsx +128 -11
- package/docs/data-display/prose.tsx +64 -0
- package/docs/data-display/timeline.tsx +36 -0
- package/docs/data-entry/calendar.tsx +2 -3
- package/docs/data-entry/segmented.tsx +55 -5
- package/docs/data-entry/toggle-group.tsx +15 -3
- package/docs/data-entry/toggle.tsx +39 -1
- package/docs/data-entry/upload.tsx +38 -0
- package/package.json +2 -2
- package/scripts/_agent-setup.mjs +80 -1
- package/scripts/cli.mjs +5 -1
- package/scripts/init-agent-kit.mjs +3 -0
- package/scripts/postinstall.mjs +5 -0
|
@@ -44,7 +44,10 @@ const RangeTimeline = React.forwardRef(
|
|
|
44
44
|
"div",
|
|
45
45
|
{
|
|
46
46
|
className: "ui-range-timeline-canvas",
|
|
47
|
-
style: {
|
|
47
|
+
style: {
|
|
48
|
+
"--range-timeline-columns": Math.max(1, columns.length),
|
|
49
|
+
"--range-timeline-units": units
|
|
50
|
+
},
|
|
48
51
|
children: [
|
|
49
52
|
bands && bands.length > 0 && /* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-header", children: [
|
|
50
53
|
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-label", "aria-hidden": "true" }),
|
|
@@ -52,7 +55,7 @@ const RangeTimeline = React.forwardRef(
|
|
|
52
55
|
"div",
|
|
53
56
|
{
|
|
54
57
|
className: "ui-range-timeline-column",
|
|
55
|
-
style: {
|
|
58
|
+
style: { gridColumn: `span ${band.units}` },
|
|
56
59
|
children: /* @__PURE__ */ jsx(Text, { size: "xs", weight: "medium", children: band.label })
|
|
57
60
|
},
|
|
58
61
|
index
|
|
@@ -64,15 +67,15 @@ const RangeTimeline = React.forwardRef(
|
|
|
64
67
|
"div",
|
|
65
68
|
{
|
|
66
69
|
className: "ui-range-timeline-column",
|
|
67
|
-
style: {
|
|
70
|
+
style: { gridColumn: `span ${column.units}` },
|
|
68
71
|
children: /* @__PURE__ */ jsx(Text, { size: "xs", children: column.label })
|
|
69
72
|
},
|
|
70
73
|
index
|
|
71
74
|
)) })
|
|
72
75
|
] }),
|
|
73
76
|
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-body", children: [
|
|
74
|
-
(bordered || columns.some((column) => column.muted)) && // Decorative: the same
|
|
75
|
-
//
|
|
77
|
+
(bordered || columns.some((column) => column.muted)) && // Decorative: the same unit tracks as the header columns, laid once behind every row so
|
|
78
|
+
// each vertical rule runs the full body height exactly under its header column.
|
|
76
79
|
/* @__PURE__ */ jsxs("div", { className: "ui-range-timeline-grid", "aria-hidden": "true", children: [
|
|
77
80
|
/* @__PURE__ */ jsx("div", {}),
|
|
78
81
|
/* @__PURE__ */ jsx("div", { className: "ui-range-timeline-columns", children: columns.map((column, index) => /* @__PURE__ */ jsx(
|
|
@@ -80,7 +83,7 @@ const RangeTimeline = React.forwardRef(
|
|
|
80
83
|
{
|
|
81
84
|
className: "ui-range-timeline-grid-column",
|
|
82
85
|
"data-muted": column.muted ? "true" : void 0,
|
|
83
|
-
style: {
|
|
86
|
+
style: { gridColumn: `span ${column.units}` }
|
|
84
87
|
},
|
|
85
88
|
index
|
|
86
89
|
)) })
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a listed file IS, at the coarseness a row can actually draw (gh#720).
|
|
3
|
+
*
|
|
4
|
+
* A picture list shows a thumbnail for an image and a glyph for everything else, so the buckets
|
|
5
|
+
* are exactly the marks we have: five, not one per MIME type. The kind is also written onto the
|
|
6
|
+
* row as `data-file-kind`, so a service can retint a bucket without forking the component.
|
|
7
|
+
*/
|
|
8
|
+
export type UploadFileKind = "image" | "pdf" | "archive" | "text" | "file";
|
|
9
|
+
/** The kind of one listed file, from its MIME type when it has one and its extension otherwise. */
|
|
10
|
+
export declare function uploadFileKind(item: {
|
|
11
|
+
name?: string;
|
|
12
|
+
mimeType?: string;
|
|
13
|
+
}): UploadFileKind;
|
|
14
|
+
/**
|
|
15
|
+
* The mark per kind. PDF takes the prose-lines document (`FileText`) because lucide ships no PDF
|
|
16
|
+
* glyph, which is also why plain/structured text takes the `</>` mark rather than the same one: a
|
|
17
|
+
* `.pdf` and a `.json` on adjacent rows must not draw identically.
|
|
18
|
+
*/
|
|
19
|
+
export declare const UPLOAD_FILE_KIND_GLYPHS: {
|
|
20
|
+
readonly image: import("react").ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
21
|
+
readonly pdf: import("react").ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
22
|
+
readonly archive: import("react").ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
23
|
+
readonly text: import("react").ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
24
|
+
readonly file: import("react").ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
|
25
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { File as FileGlyph, FileArchive, FileCode, FileImage, FileText } from "lucide-react";
|
|
2
|
+
const MIME_KINDS = {
|
|
3
|
+
"application/pdf": "pdf",
|
|
4
|
+
"application/x-pdf": "pdf",
|
|
5
|
+
"application/zip": "archive",
|
|
6
|
+
"application/x-zip-compressed": "archive",
|
|
7
|
+
"application/x-7z-compressed": "archive",
|
|
8
|
+
"application/vnd.rar": "archive",
|
|
9
|
+
"application/x-rar-compressed": "archive",
|
|
10
|
+
"application/gzip": "archive",
|
|
11
|
+
"application/x-tar": "archive",
|
|
12
|
+
"application/x-bzip": "archive",
|
|
13
|
+
"application/x-bzip2": "archive",
|
|
14
|
+
"application/json": "text",
|
|
15
|
+
"application/ld+json": "text",
|
|
16
|
+
"application/xml": "text",
|
|
17
|
+
"application/yaml": "text",
|
|
18
|
+
"application/x-yaml": "text"
|
|
19
|
+
};
|
|
20
|
+
const EXTENSION_KINDS = {
|
|
21
|
+
png: "image",
|
|
22
|
+
jpg: "image",
|
|
23
|
+
jpeg: "image",
|
|
24
|
+
gif: "image",
|
|
25
|
+
webp: "image",
|
|
26
|
+
avif: "image",
|
|
27
|
+
svg: "image",
|
|
28
|
+
bmp: "image",
|
|
29
|
+
ico: "image",
|
|
30
|
+
heic: "image",
|
|
31
|
+
heif: "image",
|
|
32
|
+
tif: "image",
|
|
33
|
+
tiff: "image",
|
|
34
|
+
pdf: "pdf",
|
|
35
|
+
zip: "archive",
|
|
36
|
+
tar: "archive",
|
|
37
|
+
gz: "archive",
|
|
38
|
+
tgz: "archive",
|
|
39
|
+
rar: "archive",
|
|
40
|
+
"7z": "archive",
|
|
41
|
+
bz2: "archive",
|
|
42
|
+
xz: "archive",
|
|
43
|
+
zst: "archive",
|
|
44
|
+
txt: "text",
|
|
45
|
+
md: "text",
|
|
46
|
+
markdown: "text",
|
|
47
|
+
json: "text",
|
|
48
|
+
jsonl: "text",
|
|
49
|
+
csv: "text",
|
|
50
|
+
tsv: "text",
|
|
51
|
+
log: "text",
|
|
52
|
+
xml: "text",
|
|
53
|
+
yml: "text",
|
|
54
|
+
yaml: "text",
|
|
55
|
+
html: "text",
|
|
56
|
+
htm: "text",
|
|
57
|
+
css: "text",
|
|
58
|
+
js: "text",
|
|
59
|
+
ts: "text"
|
|
60
|
+
};
|
|
61
|
+
function uploadFileKind(item) {
|
|
62
|
+
const mime = item.mimeType?.trim().toLowerCase();
|
|
63
|
+
if (mime) {
|
|
64
|
+
if (mime.startsWith("image/")) return "image";
|
|
65
|
+
if (mime.startsWith("text/")) return "text";
|
|
66
|
+
const known = MIME_KINDS[mime];
|
|
67
|
+
if (known) return known;
|
|
68
|
+
}
|
|
69
|
+
const name = item.name ?? "";
|
|
70
|
+
const dot = name.lastIndexOf(".");
|
|
71
|
+
if (dot > 0) {
|
|
72
|
+
const extension = name.slice(dot + 1).toLowerCase();
|
|
73
|
+
const known = EXTENSION_KINDS[extension];
|
|
74
|
+
if (known) return known;
|
|
75
|
+
}
|
|
76
|
+
return "file";
|
|
77
|
+
}
|
|
78
|
+
const UPLOAD_FILE_KIND_GLYPHS = {
|
|
79
|
+
image: FileImage,
|
|
80
|
+
pdf: FileText,
|
|
81
|
+
archive: FileArchive,
|
|
82
|
+
text: FileCode,
|
|
83
|
+
file: FileGlyph
|
|
84
|
+
};
|
|
85
|
+
export {
|
|
86
|
+
UPLOAD_FILE_KIND_GLYPHS,
|
|
87
|
+
uploadFileKind
|
|
88
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { UploadProp } from "../../props/components/data-entry.prop.js";
|
|
3
|
-
export type { UploadProp, UploadProp as UploadProps, UploadFileItemProp, UploadVariantProp, } from "../../props/components/data-entry.prop.js";
|
|
3
|
+
export type { UploadProp, UploadProp as UploadProps, UploadFileItemProp, UploadVariantProp, UploadListTypeProp, } from "../../props/components/data-entry.prop.js";
|
|
4
4
|
export type { UploadFileItem, UploadVariant, UploadCommitAction } from "./upload-types.js";
|
|
5
5
|
export { collectUploadCommitActions, createUploadItem, UPLOAD_LIST_IGNORE } from "./upload-types.js";
|
|
6
6
|
export { useUploadDraft } from "./use-upload-draft.js";
|
|
7
|
-
export declare function Upload({ variant, triggerSize, triggerVariant, value, defaultValue, onValueChange, accept: acceptProp, multiple: multipleProp, maxCount: maxCountProp, maxSizeBytes, disabled: disabledProp, readOnly, directory, pastable, openFileDialogOnClick, name, action, method, headers, data, withCredentials, beforeUpload, onReject, onRemove, onPreview, onDownload, previewFile, onDrop, showUploadList, itemRender, removable, onUpload, id, className, children, ...ariaProps }: UploadProp): React.JSX.Element;
|
|
7
|
+
export declare function Upload({ variant, listType, triggerSize, triggerVariant, value, defaultValue, onValueChange, accept: acceptProp, multiple: multipleProp, maxCount: maxCountProp, maxSizeBytes, disabled: disabledProp, readOnly, directory, pastable, openFileDialogOnClick, name, action, method, headers, data, withCredentials, beforeUpload, onReject, onRemove, onPreview, onDownload, previewFile, onDrop, showUploadList, itemRender, removable, onUpload, id, className, children, ...ariaProps }: UploadProp): React.JSX.Element;
|
|
@@ -15,9 +15,10 @@ import { useTranslation } from "../../i18n/use-translation.js";
|
|
|
15
15
|
import { formatBytes } from "../../lib/format.js";
|
|
16
16
|
import { cn } from "../../lib/utils.js";
|
|
17
17
|
import { resolveFieldA11y } from "../../lib/field-a11y.js";
|
|
18
|
-
import { controlIconClass } from "../../lib/control-styles.js";
|
|
19
18
|
import { Button } from "../general/button.js";
|
|
19
|
+
import { Icon } from "../general/icon.js";
|
|
20
20
|
import { UploadCropDialog } from "./upload-crop-dialog.js";
|
|
21
|
+
import { UPLOAD_FILE_KIND_GLYPHS, uploadFileKind } from "./upload-file-kind.js";
|
|
21
22
|
import {
|
|
22
23
|
UPLOAD_LIST_IGNORE,
|
|
23
24
|
createUploadItem,
|
|
@@ -66,6 +67,7 @@ function useUploadList(controlled, defaultValue, onValueChange) {
|
|
|
66
67
|
}
|
|
67
68
|
function Upload({
|
|
68
69
|
variant = "dropzone",
|
|
70
|
+
listType,
|
|
69
71
|
triggerSize,
|
|
70
72
|
triggerVariant = "outline",
|
|
71
73
|
value,
|
|
@@ -109,6 +111,7 @@ function Upload({
|
|
|
109
111
|
triggerOwnsAriaLabel ? { ...ariaProps, "aria-label": void 0 } : ariaProps,
|
|
110
112
|
t("dataEntry.upload.inputLabel")
|
|
111
113
|
);
|
|
114
|
+
const resolvedListType = listType ?? (variant === "picture" ? "picture" : "text");
|
|
112
115
|
const accept = acceptProp ?? defaultAcceptForVariant(variant);
|
|
113
116
|
const maxCount = maxCountProp ?? defaultMaxCount(variant);
|
|
114
117
|
const multiple = multipleProp ?? (maxCount === 1 ? false : true);
|
|
@@ -380,7 +383,7 @@ function Upload({
|
|
|
380
383
|
hasCustomPreview: Boolean(onPreview),
|
|
381
384
|
onDownload,
|
|
382
385
|
itemRender,
|
|
383
|
-
|
|
386
|
+
listType: resolvedListType
|
|
384
387
|
}
|
|
385
388
|
) : null;
|
|
386
389
|
const hiddenInput = /* @__PURE__ */ jsx(
|
|
@@ -571,7 +574,7 @@ function Upload({
|
|
|
571
574
|
onClick: openPicker,
|
|
572
575
|
className: "ui-upload-picture-empty",
|
|
573
576
|
children: [
|
|
574
|
-
/* @__PURE__ */ jsx(ImagePlus, { className:
|
|
577
|
+
/* @__PURE__ */ jsx(ImagePlus, { className: "ui-upload-picture-empty-icon", "aria-hidden": "true" }),
|
|
575
578
|
/* @__PURE__ */ jsx("span", { className: "ui-upload-picture-empty-label", children: t("dataEntry.upload.addImage") })
|
|
576
579
|
]
|
|
577
580
|
}
|
|
@@ -621,7 +624,7 @@ function Upload({
|
|
|
621
624
|
className: "ui-upload-avatar ui-focus-ring",
|
|
622
625
|
"aria-label": t("dataEntry.upload.avatarLabel"),
|
|
623
626
|
children: [
|
|
624
|
-
!showPlaceholder && item?.previewUrl ? /* @__PURE__ */ jsx("img", { src: item.previewUrl, alt: "", className: "ui-upload-avatar-image" }) : /* @__PURE__ */ jsx("span", { className: "ui-upload-avatar-placeholder", children: /* @__PURE__ */ jsx(Camera, { className:
|
|
627
|
+
!showPlaceholder && item?.previewUrl ? /* @__PURE__ */ jsx("img", { src: item.previewUrl, alt: "", className: "ui-upload-avatar-image" }) : /* @__PURE__ */ jsx("span", { className: "ui-upload-avatar-placeholder", children: /* @__PURE__ */ jsx(Camera, { className: "ui-upload-avatar-icon", "aria-hidden": "true" }) }),
|
|
625
628
|
!disabled && /* @__PURE__ */ jsx("span", { className: "ui-upload-avatar-change", children: t("dataEntry.upload.change") })
|
|
626
629
|
]
|
|
627
630
|
}
|
|
@@ -750,12 +753,13 @@ function UploadFileList({
|
|
|
750
753
|
hasCustomPreview,
|
|
751
754
|
onDownload,
|
|
752
755
|
itemRender,
|
|
753
|
-
|
|
756
|
+
listType
|
|
754
757
|
}) {
|
|
755
758
|
const { t } = useTranslation();
|
|
756
759
|
return /* @__PURE__ */ jsx("ul", { className: "ui-stack-xs", children: items.map((item) => {
|
|
760
|
+
const kind = uploadFileKind(item);
|
|
757
761
|
const node = /* @__PURE__ */ jsxs("div", { className: "ui-upload-row", children: [
|
|
758
|
-
|
|
762
|
+
listType === "picture" && (item.previewUrl ? /* @__PURE__ */ jsx("img", { src: item.previewUrl, alt: "", className: "ui-upload-list-thumb" }) : /* @__PURE__ */ jsx("span", { className: "ui-upload-list-glyph", "data-file-kind": kind, children: /* @__PURE__ */ jsx(Icon, { as: UPLOAD_FILE_KIND_GLYPHS[kind], size: "lg" }) })),
|
|
759
763
|
/* @__PURE__ */ jsxs("div", { className: "ui-upload-row-main", children: [
|
|
760
764
|
/* @__PURE__ */ jsx("div", { className: "truncate font-medium", children: item.name }),
|
|
761
765
|
/* @__PURE__ */ jsxs("div", { className: "text-muted-foreground text-xs", children: [
|
|
@@ -19,7 +19,7 @@ import type { AvatarProp } from "../../props/components/data-display.prop.js";
|
|
|
19
19
|
type ImageLoadingStatus = "idle" | "loading" | "loaded" | "error";
|
|
20
20
|
export declare const Avatar: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
|
|
21
21
|
asChild?: boolean;
|
|
22
|
-
} & Pick<AvatarProp, "appearance" | "presence" | "presenceLabel" | "shape"> & React.RefAttributes<HTMLSpanElement>>;
|
|
22
|
+
} & Pick<AvatarProp, "appearance" | "presence" | "presenceLabel" | "shape" | "size"> & React.RefAttributes<HTMLSpanElement>>;
|
|
23
23
|
export declare const AvatarImage: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "ref"> & {
|
|
24
24
|
asChild?: boolean;
|
|
25
25
|
onLoadingStatusChange?: (status: ImageLoadingStatus) => void;
|
|
@@ -53,6 +53,7 @@ const Avatar = React.forwardRef(
|
|
|
53
53
|
({
|
|
54
54
|
className,
|
|
55
55
|
shape = "circle",
|
|
56
|
+
size = "md",
|
|
56
57
|
appearance = "default",
|
|
57
58
|
presence,
|
|
58
59
|
presenceLabel,
|
|
@@ -73,6 +74,7 @@ const Avatar = React.forwardRef(
|
|
|
73
74
|
ref,
|
|
74
75
|
"data-slot": "avatar",
|
|
75
76
|
"data-shape": shape === "square" ? "square" : void 0,
|
|
77
|
+
"data-size": size === "md" ? void 0 : size,
|
|
76
78
|
"data-appearance": appearance === "tinted" ? "tinted" : void 0,
|
|
77
79
|
"data-presence": presence,
|
|
78
80
|
className: cn("ui-avatar", className),
|
|
@@ -42,8 +42,13 @@ export type SegmentedProp = {
|
|
|
42
42
|
block?: boolean;
|
|
43
43
|
/** antd `vertical` — stack the choices in a column. Arrow keys follow the axis. */
|
|
44
44
|
vertical?: boolean;
|
|
45
|
-
/**
|
|
46
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Control height tier: `md` (default), `xs`, `sm` or `lg` — the same `--control-height-*` tier
|
|
47
|
+
* every other control reads. `xs` is the fourth step (gh#719, the one Toggle/ToggleGroup took in
|
|
48
|
+
* gh#716): a 24px-dense row can carry a real segmented control instead of a hand-rolled row of
|
|
49
|
+
* Buttons.
|
|
50
|
+
*/
|
|
51
|
+
size?: "xs" | "sm" | "md" | "lg";
|
|
47
52
|
/** Disable the whole group. */
|
|
48
53
|
disabled?: boolean;
|
|
49
54
|
/** Form field name — submits the selected value with the form. */
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { type VariantProps } from "class-variance-authority";
|
|
3
3
|
declare const toggleVariants: (props?: ({
|
|
4
4
|
variant?: "default" | "outline" | null | undefined;
|
|
5
|
-
size?: "lg" | "md" | "sm" | null | undefined;
|
|
5
|
+
size?: "lg" | "md" | "sm" | "xs" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
/**
|
|
8
8
|
* Not exported on its own — it is folded into `ToggleProp` and `ToggleGroupItemProp` so there is
|
|
@@ -69,7 +69,7 @@ export type ToggleProp = React.ComponentPropsWithoutRef<"button"> & TogglePresse
|
|
|
69
69
|
export type ToggleProps = ToggleProp;
|
|
70
70
|
export declare const Toggle: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref"> & TogglePressedFields & VariantProps<(props?: ({
|
|
71
71
|
variant?: "default" | "outline" | null | undefined;
|
|
72
|
-
size?: "lg" | "md" | "sm" | null | undefined;
|
|
72
|
+
size?: "lg" | "md" | "sm" | "xs" | null | undefined;
|
|
73
73
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & ToggleCountFields & React.RefAttributes<HTMLButtonElement>>;
|
|
74
74
|
export { toggleVariants, useCounterPill, restoreDomProps };
|
|
75
75
|
export type { ToggleCountFields, TogglePressedFields };
|
|
@@ -13,6 +13,10 @@ const toggleVariants = cva("ui-toggle", {
|
|
|
13
13
|
outline: "ui-toggle-outline"
|
|
14
14
|
},
|
|
15
15
|
size: {
|
|
16
|
+
// The fourth step of the shared control ladder (gh#716): 24px, `--control-height-xs`, the
|
|
17
|
+
// same tier `Button size="xs"` reads — so a 24px-dense row can carry a segmented control
|
|
18
|
+
// instead of someone hand-rolling one out of Buttons.
|
|
19
|
+
xs: "ui-toggle-xs",
|
|
16
20
|
sm: "ui-toggle-sm",
|
|
17
21
|
md: "ui-toggle-default-size",
|
|
18
22
|
lg: "ui-toggle-lg"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "AUTO-GENERATED by scripts/gen-measurement-contract.mjs — do not edit. Read this instead of guessing: docs/MEASUREMENT-CONTRACT.md.",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.6.0",
|
|
4
4
|
"targetSize": {
|
|
5
5
|
"standard": "WCAG 2.2 SC 2.5.8 Target Size (Minimum), level AA — 24×24 CSS px",
|
|
6
6
|
"min": 24,
|
|
@@ -208,6 +208,20 @@ export type DescriptionsItemProp = {
|
|
|
208
208
|
*/
|
|
209
209
|
export type AvatarProp = React.ComponentPropsWithoutRef<"span"> & {
|
|
210
210
|
shape?: AvatarShapeProp;
|
|
211
|
+
/**
|
|
212
|
+
* Box size on the shared control ladder — `md` (default) is `--control-height`, and `xs`/`sm`/
|
|
213
|
+
* `lg` are `--control-height-xs/-sm/-lg`, the SAME tier Button and Input read. State it when the
|
|
214
|
+
* mark has to sit in a row the row's height already decided: inside an `icon-sm` trigger, in a
|
|
215
|
+
* 24px dense table row, beside a `size="sm"` Button. Before gh#716 the box was welded to
|
|
216
|
+
* `--control-height`, so a 32px mark inside a 28px trigger overflowed it and the only legal move
|
|
217
|
+
* left was raising the whole row.
|
|
218
|
+
*
|
|
219
|
+
* The initials' type step and a glyph's box move with the box — one step of the type scale and
|
|
220
|
+
* one step of the `--icon-size-*` scale per step — so a small mark is small, not clipped.
|
|
221
|
+
* `shape="square"` rides the identical ladder. Beyond the ladder (a 96px profile mark) is a
|
|
222
|
+
* `className` size utility, exactly as before; the ladder is for the control row.
|
|
223
|
+
*/
|
|
224
|
+
size?: SizeProp;
|
|
211
225
|
appearance?: AvatarAppearanceProp;
|
|
212
226
|
/**
|
|
213
227
|
* Presence — WHO is reachable right now, drawn as an indicator at the block-end/inline-end
|
|
@@ -745,8 +745,9 @@ export type CalendarProp = DayPickerProps & CalendarFooterProp & {
|
|
|
745
745
|
*
|
|
746
746
|
* Default `true` — the owner's call, from a real screen: with no ruling the month read as a
|
|
747
747
|
* cloud of numbers and was "very hard to read". Pass `bordered={false}` for the floating-button
|
|
748
|
-
* look. The line colour is `--calendar-grid-border-color` (default `--input
|
|
749
|
-
*
|
|
748
|
+
* look. The line colour is `--calendar-grid-border-color` (default `--input` at 0.5 alpha,
|
|
749
|
+
* 1.74:1 light / 1.95:1 dark on the popover; the full `--input` read too dark, and the
|
|
750
|
+
* decorative `--border` measured 1.15:1 and was invisible as a 1px ruling).
|
|
750
751
|
*/
|
|
751
752
|
bordered?: boolean;
|
|
752
753
|
/** Decorate a day cell — 祝日, a booked day, a deadline. @see CalendarCellRenderProp */
|
|
@@ -1464,9 +1465,34 @@ export type SelectDataProp = SearchSelectBaseProp & {
|
|
|
1464
1465
|
export type UploadFileItemProp = UploadFileItem;
|
|
1465
1466
|
/** @see Upload */
|
|
1466
1467
|
export type UploadVariantProp = "dropzone" | "button" | "picture-card" | "picture" | "avatar" | "avatar-crop";
|
|
1468
|
+
/**
|
|
1469
|
+
* Upload `listType` — HOW THE CHOSEN FILES ARE LISTED, ported from antd (gh#720).
|
|
1470
|
+
*
|
|
1471
|
+
* antd separates two axes and this component had only one: `variant` says how a file is PICKED
|
|
1472
|
+
* (drag area, button, tile grid, avatar), `listType` says how the picked ones are DRAWN. Welding
|
|
1473
|
+
* the second onto the first meant a `variant="dropzone"` could not show a thumbnail even for an
|
|
1474
|
+
* item that already carried a `previewUrl`, and its rows carried no per-type mark at all — a
|
|
1475
|
+
* drawer listing a `.png` beside a `.json` and a `.txt` could draw only three identical
|
|
1476
|
+
* name-and-size rows.
|
|
1477
|
+
*
|
|
1478
|
+
* - `text` — name, size, actions. The row every dropzone/button list has always drawn.
|
|
1479
|
+
* - `picture` — a leading box on every row: the thumbnail when the item has a `previewUrl`, and
|
|
1480
|
+
* otherwise the glyph for its file kind (image / pdf / archive / text / generic). Both boxes are
|
|
1481
|
+
* the same size, so a mixed list keeps one row height.
|
|
1482
|
+
*
|
|
1483
|
+
* antd's third value, `picture-card`, is `variant="picture-card"` here: in that variant the tile
|
|
1484
|
+
* grid IS the picker (the add tile sits inside the grid), so it is not a listing that can be put
|
|
1485
|
+
* under a different trigger. It is deliberately not offered as a `listType`.
|
|
1486
|
+
*/
|
|
1487
|
+
export type UploadListTypeProp = "text" | "picture";
|
|
1467
1488
|
/** @see Upload — presentational; wire `onUpload` to media-service in app api.ts */
|
|
1468
1489
|
export type UploadProp = FieldA11yProps & {
|
|
1469
1490
|
variant?: UploadVariantProp;
|
|
1491
|
+
/**
|
|
1492
|
+
* @see UploadListTypeProp — an axis of its own, independent of `variant`. Defaults to the
|
|
1493
|
+
* listing each variant already drew: `picture` for `variant="picture"`, `text` everywhere else.
|
|
1494
|
+
*/
|
|
1495
|
+
listType?: UploadListTypeProp;
|
|
1470
1496
|
value?: ValueProp<UploadFileItemProp[]>;
|
|
1471
1497
|
defaultValue?: DefaultValueProp<UploadFileItemProp[]>;
|
|
1472
1498
|
onValueChange?: OnValueChangeProp<UploadFileItemProp[]>;
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -1650,6 +1650,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1650
1650
|
readonly file: "components/data-entry.prop.ts";
|
|
1651
1651
|
readonly vocabulary: readonly [];
|
|
1652
1652
|
};
|
|
1653
|
+
readonly UploadListTypeProp: {
|
|
1654
|
+
readonly group: "data-entry";
|
|
1655
|
+
readonly file: "components/data-entry.prop.ts";
|
|
1656
|
+
readonly vocabulary: readonly [];
|
|
1657
|
+
};
|
|
1653
1658
|
readonly TreeOptionProp: {
|
|
1654
1659
|
readonly group: "data-entry";
|
|
1655
1660
|
readonly file: "components/data-entry.prop.ts";
|
|
@@ -1708,7 +1713,7 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1708
1713
|
readonly AvatarProp: {
|
|
1709
1714
|
readonly group: "data-display";
|
|
1710
1715
|
readonly file: "components/data-display.prop.ts";
|
|
1711
|
-
readonly vocabulary: readonly ["AvatarShapeProp", "LabelProp", "ChildrenProp", "ClassNameProp"];
|
|
1716
|
+
readonly vocabulary: readonly ["AvatarShapeProp", "SizeProp", "LabelProp", "ChildrenProp", "ClassNameProp"];
|
|
1712
1717
|
};
|
|
1713
1718
|
readonly AvatarAppearanceProp: {
|
|
1714
1719
|
readonly group: "data-display";
|
package/dist/props/registry.js
CHANGED
|
@@ -1935,6 +1935,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
1935
1935
|
vocabulary: []
|
|
1936
1936
|
},
|
|
1937
1937
|
UploadVariantProp: { group: "data-entry", file: "components/data-entry.prop.ts", vocabulary: [] },
|
|
1938
|
+
UploadListTypeProp: {
|
|
1939
|
+
group: "data-entry",
|
|
1940
|
+
file: "components/data-entry.prop.ts",
|
|
1941
|
+
vocabulary: []
|
|
1942
|
+
},
|
|
1938
1943
|
TreeOptionProp: {
|
|
1939
1944
|
group: "data-entry",
|
|
1940
1945
|
file: "components/data-entry.prop.ts",
|
|
@@ -2042,7 +2047,7 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
2042
2047
|
AvatarProp: {
|
|
2043
2048
|
group: "data-display",
|
|
2044
2049
|
file: "components/data-display.prop.ts",
|
|
2045
|
-
vocabulary: ["AvatarShapeProp", "LabelProp", "ChildrenProp", "ClassNameProp"]
|
|
2050
|
+
vocabulary: ["AvatarShapeProp", "SizeProp", "LabelProp", "ChildrenProp", "ClassNameProp"]
|
|
2046
2051
|
},
|
|
2047
2052
|
AvatarAppearanceProp: {
|
|
2048
2053
|
group: "data-display",
|
package/dist/styles/control.css
CHANGED
|
@@ -31,6 +31,12 @@
|
|
|
31
31
|
padding-inline: var(--space-3);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
.ui-toggle-xs {
|
|
35
|
+
min-height: var(--control-height-xs);
|
|
36
|
+
padding-inline: var(--space-1);
|
|
37
|
+
font-size: var(--toggle-xs-font-size);
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
.ui-toggle-sm {
|
|
35
41
|
min-height: var(--control-height-sm);
|
|
36
42
|
padding-inline: var(--space-2);
|
|
@@ -2223,13 +2229,13 @@
|
|
|
2223
2229
|
|
|
2224
2230
|
.ui-calendar[data-bordered="true"] .ui-calendar-day,
|
|
2225
2231
|
.ui-calendar[data-bordered="true"] .ui-calendar-weekday {
|
|
2226
|
-
border-inline-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input)));
|
|
2227
|
-
border-block-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input)));
|
|
2232
|
+
border-inline-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input) / 0.5));
|
|
2233
|
+
border-block-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input) / 0.5));
|
|
2228
2234
|
}
|
|
2229
2235
|
|
|
2230
2236
|
.ui-calendar[data-bordered="true"] .ui-calendar-week,
|
|
2231
2237
|
.ui-calendar[data-bordered="true"] .ui-calendar-weekdays {
|
|
2232
|
-
border-inline-end: 1px solid var(--calendar-grid-border-color, hsl(var(--input)));
|
|
2238
|
+
border-inline-end: 1px solid var(--calendar-grid-border-color, hsl(var(--input) / 0.5));
|
|
2233
2239
|
}
|
|
2234
2240
|
|
|
2235
2241
|
.ui-calendar[data-bordered="true"] .ui-calendar-weekday {
|
|
@@ -2241,7 +2247,7 @@
|
|
|
2241
2247
|
}
|
|
2242
2248
|
|
|
2243
2249
|
.ui-calendar[data-bordered="true"] .ui-calendar-grid {
|
|
2244
|
-
border-block-end: 1px solid var(--calendar-grid-border-color, hsl(var(--input)));
|
|
2250
|
+
border-block-end: 1px solid var(--calendar-grid-border-color, hsl(var(--input) / 0.5));
|
|
2245
2251
|
}
|
|
2246
2252
|
|
|
2247
2253
|
.ui-calendar[data-bordered="true"] .ui-calendar-day.invisible {
|
|
@@ -2262,8 +2268,8 @@
|
|
|
2262
2268
|
|
|
2263
2269
|
.ui-calendar[data-bordered="true"] .ui-calendar-week-number,
|
|
2264
2270
|
.ui-calendar[data-bordered="true"] .ui-calendar-week-number-header {
|
|
2265
|
-
border-inline-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input)));
|
|
2266
|
-
border-block-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input)));
|
|
2271
|
+
border-inline-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input) / 0.5));
|
|
2272
|
+
border-block-start: 1px solid var(--calendar-grid-border-color, hsl(var(--input) / 0.5));
|
|
2267
2273
|
}
|
|
2268
2274
|
|
|
2269
2275
|
.ui-calendar[data-bordered="true"] .ui-calendar-day {
|
|
@@ -3135,6 +3141,12 @@
|
|
|
3135
3141
|
justify-content: flex-start;
|
|
3136
3142
|
}
|
|
3137
3143
|
|
|
3144
|
+
.ui-segmented[data-size="xs"] {
|
|
3145
|
+
--control-height: var(--control-height-xs);
|
|
3146
|
+
--segmented-item-padding-inline: var(--segmented-xs-item-padding-inline);
|
|
3147
|
+
font-size: var(--segmented-xs-font-size);
|
|
3148
|
+
}
|
|
3149
|
+
|
|
3138
3150
|
.ui-segmented[data-size="sm"] {
|
|
3139
3151
|
--control-height: var(--control-height-sm);
|
|
3140
3152
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
.ui-avatar {
|
|
3
3
|
position: relative;
|
|
4
4
|
display: inline-flex;
|
|
5
|
-
width: var(--
|
|
6
|
-
height: var(--
|
|
5
|
+
width: var(--avatar-size);
|
|
6
|
+
height: var(--avatar-size);
|
|
7
7
|
flex-shrink: 0;
|
|
8
8
|
align-items: center;
|
|
9
9
|
justify-content: center;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
linear-gradient(var(--avatar-tint), var(--avatar-tint)),
|
|
14
14
|
var(--avatar-background, hsl(var(--muted)));
|
|
15
15
|
color: hsl(var(--muted-foreground));
|
|
16
|
-
font-size: var(--font-size
|
|
16
|
+
font-size: var(--avatar-font-size);
|
|
17
17
|
font-weight: var(--font-weight-medium);
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -36,6 +36,36 @@
|
|
|
36
36
|
flex: none;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
.ui-avatar[data-size="xs"] {
|
|
40
|
+
--avatar-size: var(--avatar-size-xs);
|
|
41
|
+
--avatar-square-size: var(--avatar-size-xs);
|
|
42
|
+
--avatar-font-size: var(--avatar-font-size-xs);
|
|
43
|
+
--avatar-glyph-size: var(--avatar-glyph-size-xs);
|
|
44
|
+
--avatar-tinted-glyph-size: var(--avatar-glyph-size-xs);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.ui-avatar[data-size="sm"] {
|
|
48
|
+
--avatar-size: var(--avatar-size-sm);
|
|
49
|
+
--avatar-square-size: var(--avatar-size-sm);
|
|
50
|
+
--avatar-font-size: var(--avatar-font-size-sm);
|
|
51
|
+
--avatar-glyph-size: var(--avatar-glyph-size-sm);
|
|
52
|
+
--avatar-tinted-glyph-size: var(--avatar-glyph-size-sm);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ui-avatar[data-size="lg"] {
|
|
56
|
+
--avatar-size: var(--avatar-size-lg);
|
|
57
|
+
--avatar-square-size: var(--avatar-size-lg);
|
|
58
|
+
--avatar-font-size: var(--avatar-font-size-lg);
|
|
59
|
+
--avatar-glyph-size: var(--avatar-glyph-size-lg);
|
|
60
|
+
--avatar-tinted-glyph-size: var(--avatar-glyph-size-lg);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.ui-avatar[data-size] svg {
|
|
64
|
+
inline-size: var(--avatar-glyph-size);
|
|
65
|
+
block-size: var(--avatar-glyph-size);
|
|
66
|
+
flex: none;
|
|
67
|
+
}
|
|
68
|
+
|
|
39
69
|
.ui-avatar-image {
|
|
40
70
|
width: 100%;
|
|
41
71
|
height: 100%;
|
|
@@ -1066,8 +1096,8 @@
|
|
|
1066
1096
|
}
|
|
1067
1097
|
|
|
1068
1098
|
.ui-prose a {
|
|
1069
|
-
color: hsl(var(--primary));
|
|
1070
|
-
text-decoration:
|
|
1099
|
+
color: hsl(var(--prose-link-color, var(--primary)));
|
|
1100
|
+
text-decoration-line: var(--prose-link-decoration-line);
|
|
1071
1101
|
}
|
|
1072
1102
|
|
|
1073
1103
|
.ui-prose table {
|
|
@@ -1321,8 +1351,10 @@
|
|
|
1321
1351
|
padding: var(--space-2);
|
|
1322
1352
|
border-inline-end: 1px solid hsl(var(--range-timeline-border-color));
|
|
1323
1353
|
}
|
|
1354
|
+
|
|
1324
1355
|
.ui-range-timeline-columns {
|
|
1325
|
-
display:
|
|
1356
|
+
display: grid;
|
|
1357
|
+
grid-template-columns: repeat(var(--range-timeline-units, 1), minmax(0, 1fr));
|
|
1326
1358
|
}
|
|
1327
1359
|
.ui-range-timeline-column {
|
|
1328
1360
|
min-inline-size: 0;
|
|
@@ -1360,12 +1392,12 @@
|
|
|
1360
1392
|
.ui-range-timeline[data-bordered="true"] .ui-range-timeline-column,
|
|
1361
1393
|
.ui-range-timeline[data-bordered="true"] .ui-range-timeline-label,
|
|
1362
1394
|
.ui-range-timeline[data-bordered="true"] .ui-range-timeline-grid-column {
|
|
1363
|
-
border-inline-end-color: var(--range-timeline-grid-color, hsl(var(--input)));
|
|
1395
|
+
border-inline-end-color: var(--range-timeline-grid-color, hsl(var(--input) / 0.5));
|
|
1364
1396
|
}
|
|
1365
1397
|
.ui-range-timeline[data-bordered="true"] .ui-range-timeline-header + .ui-range-timeline-header,
|
|
1366
1398
|
.ui-range-timeline[data-bordered="true"] .ui-range-timeline-row {
|
|
1367
1399
|
border-block-start: var(--range-timeline-grid-width) solid
|
|
1368
|
-
var(--range-timeline-grid-color, hsl(var(--input)));
|
|
1400
|
+
var(--range-timeline-grid-color, hsl(var(--input) / 0.5));
|
|
1369
1401
|
}
|
|
1370
1402
|
.ui-range-timeline-outside {
|
|
1371
1403
|
position: absolute;
|
|
@@ -199,6 +199,18 @@
|
|
|
199
199
|
flex-shrink: 0;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
.ui-upload-list-glyph {
|
|
203
|
+
display: flex;
|
|
204
|
+
align-items: center;
|
|
205
|
+
justify-content: center;
|
|
206
|
+
inline-size: var(--control-height-lg);
|
|
207
|
+
block-size: var(--control-height-lg);
|
|
208
|
+
border-radius: var(--radius);
|
|
209
|
+
background-color: hsl(var(--muted));
|
|
210
|
+
color: hsl(var(--muted-foreground));
|
|
211
|
+
flex-shrink: 0;
|
|
212
|
+
}
|
|
213
|
+
|
|
202
214
|
.ui-upload-picture-item {
|
|
203
215
|
inline-size: var(--upload-tile-size);
|
|
204
216
|
overflow-wrap: anywhere;
|
|
@@ -336,6 +348,11 @@
|
|
|
336
348
|
border-color: hsl(var(--primary));
|
|
337
349
|
}
|
|
338
350
|
|
|
351
|
+
.ui-upload-picture-empty-icon {
|
|
352
|
+
inline-size: var(--upload-picture-icon-size);
|
|
353
|
+
block-size: var(--upload-picture-icon-size);
|
|
354
|
+
}
|
|
355
|
+
|
|
339
356
|
.ui-upload-picture-empty-label {
|
|
340
357
|
margin-block-start: var(--upload-picture-empty-label-space-block-start);
|
|
341
358
|
font-size: var(--upload-picture-empty-label-font-size);
|
|
@@ -370,6 +387,11 @@
|
|
|
370
387
|
color: hsl(var(--muted-foreground));
|
|
371
388
|
}
|
|
372
389
|
|
|
390
|
+
.ui-upload-avatar-icon {
|
|
391
|
+
inline-size: var(--upload-avatar-icon-size);
|
|
392
|
+
block-size: var(--upload-avatar-icon-size);
|
|
393
|
+
}
|
|
394
|
+
|
|
373
395
|
.ui-upload-avatar-change {
|
|
374
396
|
position: absolute;
|
|
375
397
|
inset-inline: 0;
|
|
@@ -166,6 +166,7 @@
|
|
|
166
166
|
--search-input-label-font-size: var(--font-size-xs);
|
|
167
167
|
--tag-input-chip-font-size: var(--font-size-xs);
|
|
168
168
|
--toggle-sm-font-size: var(--font-size-xs);
|
|
169
|
+
--toggle-xs-font-size: var(--font-size-xs);
|
|
169
170
|
--button-sm-font-size: var(--font-size-xs);
|
|
170
171
|
}
|
|
171
172
|
|