@godxjp/ui 23.0.0 → 23.2.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/app/date-format-labels.d.ts +14 -2
- package/dist/app/date-format-labels.js +1 -1
- package/dist/app/date-formats.d.ts +14 -2
- package/dist/app/date-formats.js +9 -2
- package/dist/components/data-display/card.d.ts +45 -2
- package/dist/components/data-display/card.js +4 -2
- package/dist/components/data-display/data-table.d.ts +8 -1
- package/dist/components/data-display/data-table.js +9 -2
- package/dist/components/data-display/feature-list.d.ts +26 -0
- package/dist/components/data-display/feature-list.js +29 -0
- package/dist/components/data-display/index.d.ts +6 -0
- package/dist/components/data-display/index.js +6 -0
- package/dist/components/data-display/swatch.d.ts +24 -0
- package/dist/components/data-display/swatch.js +19 -0
- package/dist/components/data-display/thumbnail.d.ts +37 -0
- package/dist/components/data-display/thumbnail.js +20 -0
- package/dist/components/data-entry/checkbox.js +1 -1
- package/dist/components/data-entry/form-field.js +2 -2
- package/dist/components/data-entry/input.js +1 -1
- package/dist/components/data-entry/number-input.js +27 -6
- package/dist/components/data-entry/radio.js +1 -1
- package/dist/components/data-entry/switch.js +1 -1
- package/dist/components/feedback/dialog.js +2 -2
- package/dist/components/feedback/index.d.ts +2 -2
- package/dist/components/feedback/index.js +19 -1
- package/dist/components/feedback/sheet.js +2 -22
- package/dist/components/feedback/skeleton.d.ts +33 -3
- package/dist/components/feedback/skeleton.js +154 -3
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +17 -5
- package/dist/components/layout/sidebar.js +9 -2
- package/dist/components/navigation/filter-bar.js +2 -1
- package/dist/components/navigation/tabs-scroll.d.ts +27 -0
- package/dist/components/navigation/tabs-scroll.js +36 -1
- package/dist/components/navigation/tabs.d.ts +2 -2
- package/dist/components/navigation/tabs.js +60 -16
- package/dist/i18n/messages/en.json +10 -1
- package/dist/i18n/messages/ja.json +10 -1
- package/dist/i18n/messages/vi.json +10 -1
- package/dist/lib/breakpoint-token.d.ts +8 -0
- package/dist/lib/breakpoint-token.js +29 -0
- package/dist/props/components/data-display.prop.d.ts +101 -1
- package/dist/props/components/feedback.prop.d.ts +85 -1
- package/dist/props/components/layout.prop.d.ts +72 -1
- package/dist/props/components/navigation.prop.d.ts +80 -2
- package/dist/props/registry.d.ts +124 -1
- package/dist/props/registry.js +140 -0
- package/dist/props/vocabulary/data.prop.d.ts +5 -0
- package/dist/props/vocabulary/index.d.ts +1 -1
- package/dist/styles/alert-layout.css +139 -0
- package/dist/styles/card-layout.css +48 -0
- package/dist/styles/control.css +41 -5
- package/dist/styles/data-display-layout.css +88 -0
- package/dist/styles/focus-ring.css +28 -0
- package/dist/styles/form-layout.css +4 -0
- package/dist/styles/layout.css +2 -1
- package/dist/styles/navigation-layout.css +89 -5
- package/dist/styles/shell-layout.css +22 -0
- package/dist/styles/table-layout.css +5 -2
- package/dist/tokens/components/card.css +2 -0
- package/dist/tokens/components/control.css +8 -3
- package/dist/tokens/components/data-display.css +23 -0
- package/dist/tokens/components/feedback.css +18 -0
- package/dist/tokens/components/navigation.css +4 -0
- package/dist/tokens/foundation.css +18 -16
- package/docs/CONSUMER-RULES.md +8 -3
- package/docs/CUSTOMER-THEMING.md +18 -8
- package/docs/DATETIME.md +11 -2
- package/docs/DESIGN-AUTHORITY.md +2 -1
- package/docs/FRAME-COVERAGE-REPORT.md +29 -3
- package/docs/SPACING.md +35 -5
- package/docs/TOKENS.md +1 -1
- package/docs/assets/shot-landscape.svg +12 -0
- package/docs/assets/shot-portrait.svg +10 -0
- package/docs/data-display/card/index.tsx +40 -0
- package/docs/data-display/data-table/index.tsx +17 -2
- package/docs/data-display/feature-list.tsx +159 -0
- package/docs/data-display/swatch.tsx +107 -0
- package/docs/data-display/table.tsx +1 -1
- package/docs/data-display/thumbnail.tsx +128 -0
- package/docs/data-entry/segmented-in-filter-row.tsx +77 -0
- package/docs/feedback/skeleton.tsx +57 -0
- package/docs/layout/flex.tsx +29 -0
- package/docs/layout/sidebar.tsx +66 -10
- package/docs/navigation/dropdown-menu.tsx +4 -4
- package/docs/navigation/tabs.tsx +131 -0
- package/docs/roadmap/ai-chat-components.md +1 -2
- package/docs/roadmap/tree-components.md +0 -1
- package/package.json +12 -21
- package/scripts/_agent-setup.mjs +18 -0
- package/scripts/consumer-rule.md +16 -0
- package/scripts/guinea-pig-skill.md +12 -6
- package/scripts/ui-audit.mjs +184 -7
|
@@ -6,8 +6,8 @@ export { TwoFactorSetup } from "./two-factor-setup.js";
|
|
|
6
6
|
export type { TwoFactorSetupLabels, TwoFactorSetupProps } from "./two-factor-setup.js";
|
|
7
7
|
export { Toaster } from "./sonner.js";
|
|
8
8
|
export { toast } from "./use-toast.js";
|
|
9
|
-
export { Skeleton, SkeletonRows, SkeletonTable, SkeletonDetail, SkeletonStat } from "./skeleton.js";
|
|
10
|
-
export type { SkeletonProps } from "./skeleton.js";
|
|
9
|
+
export { Skeleton, SkeletonRows, SkeletonTable, SkeletonDetail, SkeletonStat, SkeletonArticle, SkeletonAvatar, SkeletonButton, SkeletonInput, SkeletonNode, SkeletonImage, } from "./skeleton.js";
|
|
10
|
+
export type { SkeletonProp, SkeletonProps, SkeletonWidth, SkeletonArticleProp, SkeletonArticleProps, SkeletonAvatarProp, SkeletonAvatarProps, SkeletonButtonProp, SkeletonButtonProps, SkeletonInputProp, SkeletonInputProps, SkeletonNodeProp, SkeletonNodeProps, SkeletonImageProp, SkeletonImageProps, } from "./skeleton.js";
|
|
11
11
|
export { Banner } from "./banner.js";
|
|
12
12
|
export type { BannerProp, BannerProps } from "./banner.js";
|
|
13
13
|
export { Alert, AlertTitle, AlertContent, AlertDescription, AlertActions, AlertQueryError, } from "./alert.js";
|
|
@@ -42,7 +42,19 @@ import {
|
|
|
42
42
|
import { TwoFactorSetup } from "./two-factor-setup.js";
|
|
43
43
|
import { Toaster } from "./sonner.js";
|
|
44
44
|
import { toast } from "./use-toast.js";
|
|
45
|
-
import {
|
|
45
|
+
import {
|
|
46
|
+
Skeleton,
|
|
47
|
+
SkeletonRows,
|
|
48
|
+
SkeletonTable,
|
|
49
|
+
SkeletonDetail,
|
|
50
|
+
SkeletonStat,
|
|
51
|
+
SkeletonArticle,
|
|
52
|
+
SkeletonAvatar,
|
|
53
|
+
SkeletonButton,
|
|
54
|
+
SkeletonInput,
|
|
55
|
+
SkeletonNode,
|
|
56
|
+
SkeletonImage
|
|
57
|
+
} from "./skeleton.js";
|
|
46
58
|
import { Banner } from "./banner.js";
|
|
47
59
|
import {
|
|
48
60
|
Alert,
|
|
@@ -98,7 +110,13 @@ export {
|
|
|
98
110
|
SheetTitle,
|
|
99
111
|
SheetTrigger,
|
|
100
112
|
Skeleton,
|
|
113
|
+
SkeletonArticle,
|
|
114
|
+
SkeletonAvatar,
|
|
115
|
+
SkeletonButton,
|
|
101
116
|
SkeletonDetail,
|
|
117
|
+
SkeletonImage,
|
|
118
|
+
SkeletonInput,
|
|
119
|
+
SkeletonNode,
|
|
102
120
|
SkeletonRows,
|
|
103
121
|
SkeletonStat,
|
|
104
122
|
SkeletonTable,
|
|
@@ -6,7 +6,7 @@ import { chain, mergeRefs } from "@react-aria/utils";
|
|
|
6
6
|
import { Dialog as RacDialog, Modal, ModalOverlay } from "react-aria-components";
|
|
7
7
|
import { cva } from "class-variance-authority";
|
|
8
8
|
import { X } from "lucide-react";
|
|
9
|
-
import {
|
|
9
|
+
import { useMaxWidthBreakpoint } from "../../lib/breakpoint-token.js";
|
|
10
10
|
import { cn } from "../../lib/utils.js";
|
|
11
11
|
import { Slot } from "../../lib/slot.js";
|
|
12
12
|
import { overlayHeaderToneClass } from "./overlay-header-tone.js";
|
|
@@ -15,28 +15,8 @@ import { useTranslation } from "../../i18n/use-translation.js";
|
|
|
15
15
|
const toCssLength = (v) => typeof v === "number" ? `${v}px` : v;
|
|
16
16
|
const SHEET_BREAKPOINT_TOKEN = "--sheet-responsive-breakpoint-width";
|
|
17
17
|
const SHEET_BREAKPOINT_FALLBACK_QUERY = "(max-width: 768px)";
|
|
18
|
-
function cssLengthToPx(value, rootFontSize) {
|
|
19
|
-
const match = /^(-?\d*\.?\d+)(px|rem|em)?$/.exec(value.trim());
|
|
20
|
-
if (match == null) return void 0;
|
|
21
|
-
const amount = Number(match[1]);
|
|
22
|
-
if (!Number.isFinite(amount)) return void 0;
|
|
23
|
-
return match[2] === "rem" || match[2] === "em" ? amount * rootFontSize : amount;
|
|
24
|
-
}
|
|
25
|
-
function readSheetBreakpointQuery() {
|
|
26
|
-
if (typeof document === "undefined" || typeof window.getComputedStyle !== "function") {
|
|
27
|
-
return SHEET_BREAKPOINT_FALLBACK_QUERY;
|
|
28
|
-
}
|
|
29
|
-
const rootStyle = window.getComputedStyle(document.documentElement);
|
|
30
|
-
const rootFontSize = cssLengthToPx(rootStyle.fontSize || "16px", 16) ?? 16;
|
|
31
|
-
const px = cssLengthToPx(rootStyle.getPropertyValue(SHEET_BREAKPOINT_TOKEN), rootFontSize);
|
|
32
|
-
return px == null ? SHEET_BREAKPOINT_FALLBACK_QUERY : `(max-width: ${String(px)}px)`;
|
|
33
|
-
}
|
|
34
18
|
function useSheetResponsiveMode(responsive = "side") {
|
|
35
|
-
const
|
|
36
|
-
React.useEffect(() => {
|
|
37
|
-
setQuery(readSheetBreakpointQuery());
|
|
38
|
-
}, []);
|
|
39
|
-
const compact = useMediaQuery(query);
|
|
19
|
+
const compact = useMaxWidthBreakpoint(SHEET_BREAKPOINT_TOKEN, SHEET_BREAKPOINT_FALLBACK_QUERY);
|
|
40
20
|
if (responsive === "side" || responsive === "bottom") return responsive;
|
|
41
21
|
return compact ? "bottom" : "side";
|
|
42
22
|
}
|
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
export
|
|
2
|
+
import type { SkeletonArticleProp, SkeletonAvatarProp, SkeletonButtonProp, SkeletonImageProp, SkeletonInputProp, SkeletonNodeProp, SkeletonProp } from "../../props/components/feedback.prop.js";
|
|
3
|
+
export type { SkeletonProp, SkeletonProp as SkeletonProps, SkeletonWidth, SkeletonArticleProp, SkeletonArticleProp as SkeletonArticleProps, SkeletonAvatarProp, SkeletonAvatarProp as SkeletonAvatarProps, SkeletonButtonProp, SkeletonButtonProp as SkeletonButtonProps, SkeletonInputProp, SkeletonInputProp as SkeletonInputProps, SkeletonNodeProp, SkeletonNodeProp as SkeletonNodeProps, SkeletonImageProp, SkeletonImageProp as SkeletonImageProps, } from "../../props/components/feedback.prop.js";
|
|
4
|
+
declare function SkeletonBlock({ active, loading, className, children, ...props }: SkeletonProp): React.JSX.Element;
|
|
5
|
+
/** Stands in for an `Avatar` — circle for a person, square for an entity mark. */
|
|
6
|
+
export declare function SkeletonAvatar({ size, shape, active, className }: SkeletonAvatarProp): React.JSX.Element;
|
|
7
|
+
/** Stands in for a `Button` — two control-heights wide, like antd's `controlHeight * 2`. */
|
|
8
|
+
export declare function SkeletonButton({ size, shape, block, active, className }: SkeletonButtonProp): React.JSX.Element;
|
|
9
|
+
/** Stands in for an `Input` — five control-heights wide, like antd's `controlHeight * 5`. */
|
|
10
|
+
export declare function SkeletonInput({ size, block, active, className }: SkeletonInputProp): React.JSX.Element;
|
|
11
|
+
/** A square placeholder for a media or custom slot; `children` centre inside it. */
|
|
12
|
+
export declare function SkeletonNode({ active, children, className }: SkeletonNodeProp): React.JSX.Element;
|
|
13
|
+
/** `SkeletonNode` carrying the image glyph — antd ships its own path; here it is the DS icon. */
|
|
14
|
+
export declare function SkeletonImage({ active, className }: SkeletonImageProp): React.JSX.Element;
|
|
15
|
+
/**
|
|
16
|
+
* SkeletonArticle — antd's own `<Skeleton>` shape: an optional avatar beside a heading line and a
|
|
17
|
+
* paragraph. Reach for it for a comment, a profile card or a feed item; `Skeleton` stays the bare
|
|
18
|
+
* block, and `SkeletonRows` / `SkeletonTable` / `SkeletonDetail` / `SkeletonStat` stay the house
|
|
19
|
+
* shapes for a list, a table, a record and a KPI tile.
|
|
20
|
+
*/
|
|
21
|
+
export declare function SkeletonArticle({ avatar, title, paragraph, round, active, loading, children, className, }: SkeletonArticleProp): React.JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* Skeleton — the placeholder BLOCK, and the namespace antd hangs its element presets on. The
|
|
24
|
+
* statics are the antd spelling (`Skeleton.Button`); the same components are also named exports, so
|
|
25
|
+
* a consumer importing `SkeletonButton` finds it in the catalog.
|
|
26
|
+
*/
|
|
27
|
+
export declare const Skeleton: typeof SkeletonBlock & {
|
|
28
|
+
Avatar: typeof SkeletonAvatar;
|
|
29
|
+
Button: typeof SkeletonButton;
|
|
30
|
+
Input: typeof SkeletonInput;
|
|
31
|
+
Node: typeof SkeletonNode;
|
|
32
|
+
Image: typeof SkeletonImage;
|
|
33
|
+
Article: typeof SkeletonArticle;
|
|
34
|
+
};
|
|
4
35
|
interface SkeletonRowsProps {
|
|
5
36
|
rows?: number;
|
|
6
37
|
columns?: number;
|
|
@@ -14,4 +45,3 @@ export declare function SkeletonTable({ rows, columns }: SkeletonRowsProps): Rea
|
|
|
14
45
|
export declare function SkeletonDetail(): React.JSX.Element;
|
|
15
46
|
/** Skeleton matching a stat card / dashboard tile. */
|
|
16
47
|
export declare function SkeletonStat(): React.JSX.Element;
|
|
17
|
-
export {};
|
|
@@ -1,17 +1,162 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ImageIcon } from "lucide-react";
|
|
2
3
|
import { cn } from "../../lib/utils.js";
|
|
3
4
|
import { tableCellPaddingClass, tableRowHeightClass } from "../../lib/control-styles.js";
|
|
4
|
-
function
|
|
5
|
+
function measureStyle(width) {
|
|
6
|
+
if (width === void 0) return void 0;
|
|
7
|
+
const value = typeof width === "number" ? `${width}px` : width;
|
|
8
|
+
return { "--skeleton-line-width": value };
|
|
9
|
+
}
|
|
10
|
+
function SkeletonBlock({ active, loading, className, children, ...props }) {
|
|
11
|
+
if (loading === false) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
5
12
|
return /* @__PURE__ */ jsx(
|
|
6
13
|
"div",
|
|
7
14
|
{
|
|
8
15
|
"aria-busy": "true",
|
|
9
16
|
"aria-live": "polite",
|
|
17
|
+
"data-active": active ? "" : void 0,
|
|
10
18
|
className: cn("ui-skeleton-block", className),
|
|
11
|
-
...props
|
|
19
|
+
...props,
|
|
20
|
+
children
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
function SkeletonElement({
|
|
25
|
+
kind,
|
|
26
|
+
size,
|
|
27
|
+
shape,
|
|
28
|
+
block,
|
|
29
|
+
active,
|
|
30
|
+
className,
|
|
31
|
+
children
|
|
32
|
+
}) {
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
SkeletonBlock,
|
|
35
|
+
{
|
|
36
|
+
active,
|
|
37
|
+
"data-skeleton-element": kind,
|
|
38
|
+
"data-size": size,
|
|
39
|
+
"data-shape": shape,
|
|
40
|
+
"data-block": block ? "" : void 0,
|
|
41
|
+
className,
|
|
42
|
+
children
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
function SkeletonAvatar({ size, shape = "circle", active, className }) {
|
|
47
|
+
return /* @__PURE__ */ jsx(
|
|
48
|
+
SkeletonElement,
|
|
49
|
+
{
|
|
50
|
+
kind: "avatar",
|
|
51
|
+
size,
|
|
52
|
+
shape,
|
|
53
|
+
active,
|
|
54
|
+
className
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
function SkeletonButton({ size, shape, block, active, className }) {
|
|
59
|
+
return /* @__PURE__ */ jsx(
|
|
60
|
+
SkeletonElement,
|
|
61
|
+
{
|
|
62
|
+
kind: "button",
|
|
63
|
+
size,
|
|
64
|
+
shape,
|
|
65
|
+
block,
|
|
66
|
+
active,
|
|
67
|
+
className
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
function SkeletonInput({ size, block, active, className }) {
|
|
72
|
+
return /* @__PURE__ */ jsx(SkeletonElement, { kind: "input", size, block, active, className });
|
|
73
|
+
}
|
|
74
|
+
function SkeletonNode({ active, children, className }) {
|
|
75
|
+
return /* @__PURE__ */ jsx(SkeletonElement, { kind: "node", active, className, children });
|
|
76
|
+
}
|
|
77
|
+
function SkeletonImage({ active, className }) {
|
|
78
|
+
return /* @__PURE__ */ jsx(SkeletonElement, { kind: "image", active, className, children: /* @__PURE__ */ jsx(ImageIcon, { "aria-hidden": "true", focusable: "false", className: "ui-skeleton-image-glyph" }) });
|
|
79
|
+
}
|
|
80
|
+
function avatarDefaults(hasTitle, hasParagraph) {
|
|
81
|
+
if (hasTitle && !hasParagraph) return { size: "lg", shape: "square" };
|
|
82
|
+
return { size: "lg", shape: "circle" };
|
|
83
|
+
}
|
|
84
|
+
function titleDefaultWidth(hasAvatar, hasParagraph) {
|
|
85
|
+
if (!hasAvatar && hasParagraph) return "38%";
|
|
86
|
+
if (hasAvatar && hasParagraph) return "50%";
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
function paragraphDefaults(hasAvatar, hasTitle) {
|
|
90
|
+
return {
|
|
91
|
+
rows: !hasAvatar && hasTitle ? 3 : 2,
|
|
92
|
+
width: !hasAvatar || !hasTitle ? "61%" : void 0
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function rowWidth(index, rows, width) {
|
|
96
|
+
if (Array.isArray(width)) return width[index];
|
|
97
|
+
return rows - 1 === index ? width : void 0;
|
|
98
|
+
}
|
|
99
|
+
function SkeletonArticle({
|
|
100
|
+
avatar = false,
|
|
101
|
+
title = true,
|
|
102
|
+
paragraph = true,
|
|
103
|
+
round,
|
|
104
|
+
active,
|
|
105
|
+
loading,
|
|
106
|
+
children,
|
|
107
|
+
className
|
|
108
|
+
}) {
|
|
109
|
+
if (loading === false) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
110
|
+
const hasAvatar = Boolean(avatar);
|
|
111
|
+
const hasTitle = Boolean(title);
|
|
112
|
+
const hasParagraph = Boolean(paragraph);
|
|
113
|
+
const avatarProps = {
|
|
114
|
+
...avatarDefaults(hasTitle, hasParagraph),
|
|
115
|
+
...typeof avatar === "object" ? avatar : {}
|
|
116
|
+
};
|
|
117
|
+
const titleWidth = (typeof title === "object" ? title.width : void 0) ?? titleDefaultWidth(hasAvatar, hasParagraph);
|
|
118
|
+
const paragraphBase = paragraphDefaults(hasAvatar, hasTitle);
|
|
119
|
+
const paragraphProps = typeof paragraph === "object" ? paragraph : {};
|
|
120
|
+
const rows = paragraphProps.rows ?? paragraphBase.rows;
|
|
121
|
+
const paragraphWidth = paragraphProps.width ?? paragraphBase.width;
|
|
122
|
+
return /* @__PURE__ */ jsxs(
|
|
123
|
+
"div",
|
|
124
|
+
{
|
|
125
|
+
"aria-busy": "true",
|
|
126
|
+
"data-slot": "skeleton-article",
|
|
127
|
+
"data-avatar": hasAvatar ? "" : void 0,
|
|
128
|
+
"data-active": active ? "" : void 0,
|
|
129
|
+
"data-round": round ? "" : void 0,
|
|
130
|
+
className: cn("ui-skeleton-article", className),
|
|
131
|
+
children: [
|
|
132
|
+
hasAvatar ? /* @__PURE__ */ jsx("div", { className: "ui-skeleton-article-header", children: /* @__PURE__ */ jsx(SkeletonAvatar, { ...avatarProps }) }) : null,
|
|
133
|
+
hasTitle || hasParagraph ? /* @__PURE__ */ jsxs("div", { className: "ui-skeleton-article-section", children: [
|
|
134
|
+
hasTitle ? /* @__PURE__ */ jsx(SkeletonBlock, { className: "ui-skeleton-article-title", style: measureStyle(titleWidth) }) : null,
|
|
135
|
+
hasParagraph ? (
|
|
136
|
+
// Deliberately divs, not antd's <ul><li>: its rows carry no text, so a real list would
|
|
137
|
+
// announce "list, 3 items" out of an already `aria-busy` region.
|
|
138
|
+
/* @__PURE__ */ jsx("div", { className: "ui-skeleton-article-paragraph", children: Array.from({ length: rows }).map((_, index) => /* @__PURE__ */ jsx(
|
|
139
|
+
SkeletonBlock,
|
|
140
|
+
{
|
|
141
|
+
className: "ui-skeleton-article-line",
|
|
142
|
+
style: measureStyle(rowWidth(index, rows, paragraphWidth))
|
|
143
|
+
},
|
|
144
|
+
index
|
|
145
|
+
)) })
|
|
146
|
+
) : null
|
|
147
|
+
] }) : null
|
|
148
|
+
]
|
|
12
149
|
}
|
|
13
150
|
);
|
|
14
151
|
}
|
|
152
|
+
const Skeleton = Object.assign(SkeletonBlock, {
|
|
153
|
+
Avatar: SkeletonAvatar,
|
|
154
|
+
Button: SkeletonButton,
|
|
155
|
+
Input: SkeletonInput,
|
|
156
|
+
Node: SkeletonNode,
|
|
157
|
+
Image: SkeletonImage,
|
|
158
|
+
Article: SkeletonArticle
|
|
159
|
+
});
|
|
15
160
|
function SkeletonRows({ rows = 6, columns = 4, className }) {
|
|
16
161
|
return /* @__PURE__ */ jsx("div", { className: cn("ui-skeleton-rows", className), "aria-busy": "true", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsx("div", { className: "ui-skeleton-row", children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ jsx(
|
|
17
162
|
Skeleton,
|
|
@@ -56,7 +201,13 @@ function SkeletonStat() {
|
|
|
56
201
|
}
|
|
57
202
|
export {
|
|
58
203
|
Skeleton,
|
|
204
|
+
SkeletonArticle,
|
|
205
|
+
SkeletonAvatar,
|
|
206
|
+
SkeletonButton,
|
|
59
207
|
SkeletonDetail,
|
|
208
|
+
SkeletonImage,
|
|
209
|
+
SkeletonInput,
|
|
210
|
+
SkeletonNode,
|
|
60
211
|
SkeletonRows,
|
|
61
212
|
SkeletonStat,
|
|
62
213
|
SkeletonTable
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { FlexProp } from "../../props/components/layout.prop.js";
|
|
2
2
|
export type { FlexAlignProp, FlexDirectionProp, FlexJustifyProp, FlexProp, FlexProp as FlexProps, } from "../../props/components/layout.prop.js";
|
|
3
|
-
export declare function Flex({ as: Element, direction, grow, shrink, surface, bleed, reveal, gap, gapRaw, pad, padRaw, align, justify, wrap, hideBelow, hideFrom, fill, width, className, style, children, ...props }: FlexProp): import("react").JSX.Element;
|
|
3
|
+
export declare function Flex({ as: Element, direction, grow, shrink, surface, bleed, reveal, gap, gapRaw, pad, padRaw, align, justify, wrap, hideBelow, hideFrom, hideBelowRaw, hideFromRaw, fill, width, className, style, children, ...props }: FlexProp): import("react").JSX.Element;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { mergeAriaIds } from "../../lib/field-a11y.js";
|
|
4
4
|
import { cn } from "../../lib/utils.js";
|
|
5
5
|
import { flexGapClass, padStyle, padStepToken } from "../../lib/variants.js";
|
|
6
6
|
const toCssLength = (value) => typeof value === "number" ? `${value}px` : value;
|
|
7
|
+
const rawBreakpoint = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
8
|
+
const rawBreakpointRule = (axis, px) => `@media (width ${axis === "below" ? "<" : ">="} ${px}px){.ui-flex[data-hide-${axis}-raw="${px}"]{display:none}}`;
|
|
7
9
|
function Flex({
|
|
8
10
|
as: Element = "div",
|
|
9
11
|
direction = "row",
|
|
@@ -21,6 +23,8 @@ function Flex({
|
|
|
21
23
|
wrap = false,
|
|
22
24
|
hideBelow,
|
|
23
25
|
hideFrom,
|
|
26
|
+
hideBelowRaw,
|
|
27
|
+
hideFromRaw,
|
|
24
28
|
fill = false,
|
|
25
29
|
width,
|
|
26
30
|
className,
|
|
@@ -42,6 +46,8 @@ function Flex({
|
|
|
42
46
|
"aria-describedby": mergeAriaIds(props["aria-describedby"], ariaErrorMessage)
|
|
43
47
|
};
|
|
44
48
|
}
|
|
49
|
+
const belowRaw = rawBreakpoint(hideBelowRaw);
|
|
50
|
+
const fromRaw = rawBreakpoint(hideFromRaw);
|
|
45
51
|
const responsive = typeof direction === "object";
|
|
46
52
|
const axes = responsive ? direction : { base: direction };
|
|
47
53
|
const cssDirection = (axis) => axis === "col" ? "column" : axis;
|
|
@@ -51,7 +57,7 @@ function Flex({
|
|
|
51
57
|
cssDirection(axis)
|
|
52
58
|
])
|
|
53
59
|
) : {};
|
|
54
|
-
return /* @__PURE__ */
|
|
60
|
+
return /* @__PURE__ */ jsxs(
|
|
55
61
|
Element,
|
|
56
62
|
{
|
|
57
63
|
"data-direction": responsive ? "responsive" : direction,
|
|
@@ -63,8 +69,10 @@ function Flex({
|
|
|
63
69
|
"data-align": align,
|
|
64
70
|
"data-justify": justify,
|
|
65
71
|
"data-wrap": wrap ? "true" : void 0,
|
|
66
|
-
"data-hide-below": hideBelow,
|
|
67
|
-
"data-hide-from": hideFrom,
|
|
72
|
+
"data-hide-below": belowRaw === void 0 ? hideBelow : void 0,
|
|
73
|
+
"data-hide-from": fromRaw === void 0 ? hideFrom : void 0,
|
|
74
|
+
"data-hide-below-raw": belowRaw,
|
|
75
|
+
"data-hide-from-raw": fromRaw,
|
|
68
76
|
"data-fill": fill ? "" : void 0,
|
|
69
77
|
"data-width-raw": width === void 0 ? void 0 : "",
|
|
70
78
|
"data-gap-raw": gapRaw,
|
|
@@ -79,7 +87,11 @@ function Flex({
|
|
|
79
87
|
...padStyle(pad, padRaw)
|
|
80
88
|
},
|
|
81
89
|
...domProps,
|
|
82
|
-
children
|
|
90
|
+
children: [
|
|
91
|
+
belowRaw === void 0 ? null : /* @__PURE__ */ jsx("style", { href: `ui-flex-hide-below-raw-${belowRaw}`, precedence: "ui-flex-raw-breakpoint", children: rawBreakpointRule("below", belowRaw) }),
|
|
92
|
+
fromRaw === void 0 ? null : /* @__PURE__ */ jsx("style", { href: `ui-flex-hide-from-raw-${fromRaw}`, precedence: "ui-flex-raw-breakpoint", children: rawBreakpointRule("from", fromRaw) }),
|
|
93
|
+
children
|
|
94
|
+
]
|
|
83
95
|
}
|
|
84
96
|
);
|
|
85
97
|
}
|
|
@@ -27,6 +27,11 @@ function SidebarSection({
|
|
|
27
27
|
function SidebarIcon({ icon: Icon }) {
|
|
28
28
|
return /* @__PURE__ */ jsx("span", { className: "sb-icon", children: Icon ? /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }) : null });
|
|
29
29
|
}
|
|
30
|
+
function SidebarTrailingIcon({
|
|
31
|
+
icon: Icon
|
|
32
|
+
}) {
|
|
33
|
+
return /* @__PURE__ */ jsx("span", { className: "sb-trailing-icon", children: /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" }) });
|
|
34
|
+
}
|
|
30
35
|
function SidebarRowContent({
|
|
31
36
|
item,
|
|
32
37
|
sub = false,
|
|
@@ -48,7 +53,8 @@ function SidebarRowContent({
|
|
|
48
53
|
children: item.badge
|
|
49
54
|
}
|
|
50
55
|
)
|
|
51
|
-
) : null
|
|
56
|
+
) : null,
|
|
57
|
+
item.trailingIcon ? /* @__PURE__ */ jsx(SidebarTrailingIcon, { icon: item.trailingIcon }) : null
|
|
52
58
|
] });
|
|
53
59
|
}
|
|
54
60
|
function SidebarItem({
|
|
@@ -305,6 +311,7 @@ function Sidebar({
|
|
|
305
311
|
const surface = useNavSurface();
|
|
306
312
|
collapsed = surface === "drawer" ? false : collapsed;
|
|
307
313
|
const brandNode = typeof brand === "function" ? brand(collapsed) : brand;
|
|
314
|
+
const footerNode = typeof footer === "function" ? footer(collapsed) : footer;
|
|
308
315
|
return /* @__PURE__ */ jsxs("div", { className: "sb-root", "data-collapsed": collapsed ? "true" : void 0, children: [
|
|
309
316
|
brand !== void 0 ? /* @__PURE__ */ jsx(SidebarHeader, { children: brandNode }) : product ? (() => {
|
|
310
317
|
const interactive = onProductClick != null;
|
|
@@ -385,7 +392,7 @@ function Sidebar({
|
|
|
385
392
|
))
|
|
386
393
|
}
|
|
387
394
|
),
|
|
388
|
-
|
|
395
|
+
footerNode ? /* @__PURE__ */ jsx("div", { className: "sb-footer", children: footerNode }) : null
|
|
389
396
|
] });
|
|
390
397
|
}
|
|
391
398
|
export {
|
|
@@ -96,7 +96,8 @@ function Toolbar({
|
|
|
96
96
|
defaultValue: filter.defaultSelected,
|
|
97
97
|
onValueChange: (selected) => filter.onSelectedChange?.(selected),
|
|
98
98
|
placeholder: filter.placeholder,
|
|
99
|
-
disabled: disabled || filter.disabled
|
|
99
|
+
disabled: disabled || filter.disabled,
|
|
100
|
+
clearLabel: typeof filter.label === "string" ? t("navigation.filterBar.clearFilter", { label: filter.label }) : void 0
|
|
100
101
|
}
|
|
101
102
|
)
|
|
102
103
|
},
|
|
@@ -47,6 +47,33 @@ export declare function useKeepActiveTabVisible(listRef: React.RefObject<HTMLEle
|
|
|
47
47
|
* it are the ones that hand it real geometry.
|
|
48
48
|
*/
|
|
49
49
|
export declare function resolveHiddenTabValues(list: HTMLElement, values: readonly string[]): string[];
|
|
50
|
+
/**
|
|
51
|
+
* The LOGICAL scroll offset of a strip: how far it has moved from its own start edge, growing
|
|
52
|
+
* towards `end` on whichever axis the strip is on and in whichever direction it is written.
|
|
53
|
+
*
|
|
54
|
+
* `scrollLeft` cannot be read raw. Per CSSOM-View an RTL scroller reports `0` at its START edge
|
|
55
|
+
* (the right one) and goes NEGATIVE towards the end, so "scrollLeft went up" means opposite things
|
|
56
|
+
* in the two directions — exactly the bug `start`/`end` exist to prevent, and it would have been
|
|
57
|
+
* invisible in an LTR test suite.
|
|
58
|
+
*/
|
|
59
|
+
export declare function readTabsScrollOffset(list: HTMLElement, vertical: boolean): number;
|
|
60
|
+
/**
|
|
61
|
+
* Ant Design `onTabScroll`'s one piece of logic: which edge a movement of the scroll offset went
|
|
62
|
+
* towards. `null` when the offset did not move, so a scroll event that reports the same position
|
|
63
|
+
* (momentum settling, a programmatic re-pin that was already in place) reports nothing.
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolveTabsScrollDirection(previous: number, next: number): "start" | "end" | null;
|
|
66
|
+
/**
|
|
67
|
+
* Reports every real movement of the strip's own scrollport to `onScroll` — Ant Design
|
|
68
|
+
* `onTabScroll`. The handler is held in a ref so a consumer's inline arrow function does not
|
|
69
|
+
* re-arm the listener on every render (same contract as `useTabsOverflowValues` above).
|
|
70
|
+
*
|
|
71
|
+
* It reports a `scrollIntoView` re-pin too, and deliberately: antd's does the same, and "the strip
|
|
72
|
+
* moved" is the fact a consumer is subscribing to — not "the user moved it".
|
|
73
|
+
*/
|
|
74
|
+
export declare function useTabsScrollReporter(listRef: React.RefObject<HTMLElement | null>, vertical: boolean, onScroll: ((info: {
|
|
75
|
+
direction: "start" | "end";
|
|
76
|
+
}) => void) | undefined): void;
|
|
50
77
|
/**
|
|
51
78
|
* Keeps `onChange` fed with the values currently out of the scrollport, recomputing on the two
|
|
52
79
|
* things that can move them: the strip resizing (a viewport change, a font swap, a tab added or
|
|
@@ -78,6 +78,38 @@ function resolveHiddenTabValues(list, values) {
|
|
|
78
78
|
});
|
|
79
79
|
return hidden;
|
|
80
80
|
}
|
|
81
|
+
function readTabsScrollOffset(list, vertical) {
|
|
82
|
+
if (vertical) return list.scrollTop;
|
|
83
|
+
const rtl = list.ownerDocument?.defaultView?.getComputedStyle(list).direction === "rtl" || list.closest("[dir]")?.getAttribute("dir") === "rtl";
|
|
84
|
+
return rtl ? -list.scrollLeft : list.scrollLeft;
|
|
85
|
+
}
|
|
86
|
+
function resolveTabsScrollDirection(previous, next) {
|
|
87
|
+
if (next === previous) return null;
|
|
88
|
+
return next > previous ? "end" : "start";
|
|
89
|
+
}
|
|
90
|
+
function useTabsScrollReporter(listRef, vertical, onScroll) {
|
|
91
|
+
const onScrollRef = React.useRef(onScroll);
|
|
92
|
+
React.useEffect(() => {
|
|
93
|
+
onScrollRef.current = onScroll;
|
|
94
|
+
});
|
|
95
|
+
const armed = onScroll !== void 0;
|
|
96
|
+
React.useEffect(() => {
|
|
97
|
+
if (!armed) return void 0;
|
|
98
|
+
const list = listRef.current;
|
|
99
|
+
if (!list) return void 0;
|
|
100
|
+
let last = readTabsScrollOffset(list, vertical);
|
|
101
|
+
const report = () => {
|
|
102
|
+
const next = readTabsScrollOffset(list, vertical);
|
|
103
|
+
const direction = resolveTabsScrollDirection(last, next);
|
|
104
|
+
last = next;
|
|
105
|
+
if (direction) onScrollRef.current?.({ direction });
|
|
106
|
+
};
|
|
107
|
+
list.addEventListener("scroll", report, { passive: true });
|
|
108
|
+
return () => {
|
|
109
|
+
list.removeEventListener("scroll", report);
|
|
110
|
+
};
|
|
111
|
+
}, [armed, listRef, vertical]);
|
|
112
|
+
}
|
|
81
113
|
function useTabsOverflowValues(listRef, values, onChange) {
|
|
82
114
|
const onChangeRef = React.useRef(onChange);
|
|
83
115
|
React.useEffect(() => {
|
|
@@ -119,9 +151,12 @@ function useTabsOverflowValues(listRef, values, onChange) {
|
|
|
119
151
|
export {
|
|
120
152
|
isTabFullyVisible,
|
|
121
153
|
prefersReducedMotion,
|
|
154
|
+
readTabsScrollOffset,
|
|
122
155
|
resolveHiddenTabValues,
|
|
123
156
|
resolveTabScrollTarget,
|
|
157
|
+
resolveTabsScrollDirection,
|
|
124
158
|
syncActiveTabIntoView,
|
|
125
159
|
useKeepActiveTabVisible,
|
|
126
|
-
useTabsOverflowValues
|
|
160
|
+
useTabsOverflowValues,
|
|
161
|
+
useTabsScrollReporter
|
|
127
162
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { TabItemProp, TabsProp } from "../../props/components/navigation.prop.js";
|
|
3
|
-
export type { TabItemProp, TabsProp, TabsVariantProp, TabsPlacementProp, TabsExtraProp, TabsOverflowProp, } from "../../props/components/navigation.prop.js";
|
|
3
|
+
export type { TabItemProp, TabsProp, TabsVariantProp, TabsPlacementProp, TabsExtraProp, TabsOverflowProp, TabsAnimatedProp, TabsIndicatorProp, TabsIndicatorSizeProp, TabsScrollDirectionProp, TabsOnScrollProp, } from "../../props/components/navigation.prop.js";
|
|
4
4
|
export type TabsOrientation = "vertical" | "horizontal";
|
|
5
5
|
export type TabsItem = TabItemProp;
|
|
6
6
|
export type TabsProps = Omit<React.ComponentPropsWithoutRef<"div">, "defaultValue" | "dir"> & TabsProp & {
|
|
@@ -8,7 +8,7 @@ export type TabsProps = Omit<React.ComponentPropsWithoutRef<"div">, "defaultValu
|
|
|
8
8
|
dir?: "ltr" | "rtl";
|
|
9
9
|
activationMode?: "manual" | "automatic";
|
|
10
10
|
};
|
|
11
|
-
export declare function Tabs({ className, orientation, items, value, defaultValue, onValueChange, activationMode, dir, variant, tabPlacement, size, centered, extra, destroyOnHidden, onEdit, addIcon, hideAdd, closeIcon, onTabClick, overflow, listClassName, contentClassName, children, ...props }: TabsProps): React.JSX.Element;
|
|
11
|
+
export declare function Tabs({ className, orientation, items, value, defaultValue, onValueChange, activationMode, dir, variant, tabPlacement, size, centered, extra, destroyOnHidden, onEdit, addIcon, hideAdd, closeIcon, onTabClick, overflow, animated, indicator, moreIcon, onTabScroll, listClassName, contentClassName, children, ...props }: TabsProps): React.JSX.Element;
|
|
12
12
|
export declare const TabsList: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
13
13
|
variant?: "default" | "line";
|
|
14
14
|
/**
|