@godxjp/ui 31.28.3 → 31.29.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/agent/START-HERE.md +5 -5
- package/agent/components/AppLauncher.json +5 -0
- package/agent/components/Avatar.json +1 -0
- package/agent/components/Dialog.json +3 -1
- package/agent/components/ResponsiveGrid.json +7 -0
- package/agent/components/Sidebar.json +5 -0
- package/agent/components/SortableList.json +78 -0
- package/agent/components/TopbarItem.json +1 -1
- package/agent/components-index.json +5 -0
- package/agent/components.json +100 -2
- package/agent/index.json +6 -6
- package/agent/llms.txt +6 -6
- package/agent/tokens.json +74 -2
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/data-entry/sortable-list.d.ts +10 -0
- package/dist/components/data-entry/sortable-list.js +237 -0
- package/dist/components/feedback/dialog.d.ts +8 -2
- package/dist/components/feedback/dialog.js +8 -1
- package/dist/components/feedback/sheet.js +1 -1
- package/dist/components/layout/app-launcher.d.ts +1 -1
- package/dist/components/layout/app-launcher.js +18 -14
- package/dist/components/layout/responsive-grid.d.ts +17 -2
- package/dist/components/layout/responsive-grid.js +17 -4
- package/dist/components/layout/sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar.js +3 -0
- package/dist/components/layout/topbar-item.js +8 -2
- package/dist/components/ui/avatar.d.ts +3 -1
- package/dist/components/ui/avatar.js +2 -1
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +8 -0
- package/dist/i18n/messages/ja.json +8 -0
- package/dist/i18n/messages/vi.json +8 -0
- package/dist/props/components/data-display.prop.d.ts +9 -0
- package/dist/props/components/data-entry.prop.d.ts +34 -0
- package/dist/props/components/feedback.prop.d.ts +6 -1
- package/dist/props/components/layout.prop.d.ts +22 -0
- package/dist/props/registry.d.ts +33 -2
- package/dist/props/registry.js +44 -1
- package/dist/styles/control.css +50 -0
- package/dist/styles/data-display-layout.css +4 -0
- package/dist/styles/dialog-layout.css +14 -1
- package/dist/styles/layers.json +6 -1
- package/dist/styles/layout.css +29 -7
- package/dist/styles/shell-layout.css +26 -0
- package/dist/tokens/components/control.css +5 -0
- package/dist/tokens/components/feedback.css +6 -0
- package/dist/tokens/components/shell.css +6 -0
- package/dist/tokens/semantic/layout.css +1 -4
- package/docs/FRAME-COVERAGE-REPORT.md +3 -2
- package/docs/data-display/avatar.tsx +32 -0
- package/docs/data-entry/sortable-list.tsx +76 -0
- package/docs/feedback/dialog.tsx +37 -1
- package/docs/i18n/messages/en.json +51 -0
- package/docs/i18n/messages/ja.json +51 -0
- package/docs/i18n/messages/vi.json +51 -0
- package/docs/layout/app-launcher.tsx +17 -1
- package/docs/layout/responsive-grid.tsx +23 -0
- package/docs/layout/sidebar.tsx +24 -0
- package/docs/layout/topbar-item.tsx +11 -0
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Feedback component prop types — @see docs/COMPONENTS.md#feedback */
|
|
2
2
|
import type * as React from "react";
|
|
3
3
|
import type { QueryErrorCategory } from "../../lib/query-error.js";
|
|
4
|
-
import type { AlertVariantProp, AvatarShapeProp, CalloutKindProp, CancelLabelProp, ChildrenProp, ClassNameProp, ConfirmLabelProp, ConfirmVariantProp, DefaultOpenProp, DescriptionProp, HandlerProp, IconProp, OpenProp, OnOpenChangeProp, PendingProp, ShapeProp, SizeProp, ToneProp, TitleProp } from "../vocabulary/index.js";
|
|
4
|
+
import type { AlertVariantProp, AvatarShapeProp, CalloutKindProp, CancelLabelProp, ChildrenProp, ClassNameProp, ConfirmLabelProp, ConfirmVariantProp, DefaultOpenProp, DescriptionProp, HandlerProp, IconProp, OpenProp, OnOpenChangeProp, PendingProp, ShapeProp, SizeProp, ToneProp, TitleProp, WidthProp } from "../vocabulary/index.js";
|
|
5
5
|
/**
|
|
6
6
|
* @see Dialog — the compound modal ROOT.
|
|
7
7
|
*
|
|
@@ -38,6 +38,11 @@ export type DialogContentProp = {
|
|
|
38
38
|
showClose?: boolean;
|
|
39
39
|
/** Semantic class for the scrim the surface owns (RAC nests overlay → modal → dialog). */
|
|
40
40
|
overlayClassName?: ClassNameProp;
|
|
41
|
+
/**
|
|
42
|
+
* Panel width (antd Modal `width`; same vocabulary as SheetContent `width`): number = px, string
|
|
43
|
+
* = any CSS length. Capped at the viewport minus `--dialog-viewport-inset`. Default 32rem.
|
|
44
|
+
*/
|
|
45
|
+
width?: WidthProp;
|
|
41
46
|
className?: ClassNameProp;
|
|
42
47
|
children?: ChildrenProp;
|
|
43
48
|
};
|
|
@@ -1430,6 +1430,16 @@ export type AppLauncherProp = {
|
|
|
1430
1430
|
*/
|
|
1431
1431
|
side?: "top" | "right" | "bottom" | "left";
|
|
1432
1432
|
align?: "start" | "center" | "end";
|
|
1433
|
+
/**
|
|
1434
|
+
* Secondary links UNDER the grid — "Request access", "All apps", "Add apps": the row Google
|
|
1435
|
+
* Workspace, Okta and Microsoft My Apps put below their launcher grid (gh#1172). Pass the links
|
|
1436
|
+
* themselves (`<a>` or a router link); the launcher draws the row (a hairline above it, the
|
|
1437
|
+
* small type step, `--app-launcher-footer-*`) outside the scrolling grid, so it stays in view and
|
|
1438
|
+
* comes after the tiles in focus order. Rendered in every state — loading, error and empty
|
|
1439
|
+
* included — because "request access" is most needed when there is nothing to open. Not a tile:
|
|
1440
|
+
* a link dressed as an app reads as an app.
|
|
1441
|
+
*/
|
|
1442
|
+
footer?: ReactNode;
|
|
1433
1443
|
open?: boolean;
|
|
1434
1444
|
onOpenChange?: (open: boolean) => void;
|
|
1435
1445
|
className?: ClassNameProp;
|
|
@@ -1463,6 +1473,14 @@ export type SidebarProp = {
|
|
|
1463
1473
|
* not belong here — see AppShell's `navRail` for where it goes and why.
|
|
1464
1474
|
*/
|
|
1465
1475
|
brand?: ReactNode | ((collapsed: boolean) => ReactNode);
|
|
1476
|
+
/**
|
|
1477
|
+
* The rail's ONE primary action ("New issue", "+ Create", "New page"), rendered between `brand`
|
|
1478
|
+
* and the scrolling nav and never scrolling with it. Put exactly one primary control here: a
|
|
1479
|
+
* `Button` (variant primary) full width when expanded, icon-only with an `aria-label` + tooltip
|
|
1480
|
+
* when collapsed. It takes a function for the same reason `brand` and `footer` do: it receives the
|
|
1481
|
+
* EFFECTIVE collapsed value, so the mobile drawer (which never collapses) gets the full button.
|
|
1482
|
+
*/
|
|
1483
|
+
action?: ReactNode | ((collapsed: boolean) => ReactNode);
|
|
1466
1484
|
collapsed?: boolean;
|
|
1467
1485
|
children?: ChildrenProp;
|
|
1468
1486
|
/**
|
|
@@ -1620,6 +1638,10 @@ export type TopbarItemProp = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
|
1620
1638
|
*
|
|
1621
1639
|
* The count is not an accessible name: give the cell an `aria-label` that says what the number
|
|
1622
1640
|
* means (`aria-label={t("topbar.notifications.unread", { count })}`).
|
|
1641
|
+
*
|
|
1642
|
+
* Drawn under `asChild` too (gh#1171): the pill goes inside the child element, after its own
|
|
1643
|
+
* children, so a bell that is a link (`<TopbarItem asChild badge={3}><a …/></TopbarItem>`) keeps
|
|
1644
|
+
* its count.
|
|
1623
1645
|
*/
|
|
1624
1646
|
badge?: ReactNode;
|
|
1625
1647
|
/**
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -2017,6 +2017,11 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
2017
2017
|
readonly file: "components/data-display.prop.ts";
|
|
2018
2018
|
readonly vocabulary: readonly [];
|
|
2019
2019
|
};
|
|
2020
|
+
readonly AvatarImageFitProp: {
|
|
2021
|
+
readonly group: "data-display";
|
|
2022
|
+
readonly file: "components/data-display.prop.ts";
|
|
2023
|
+
readonly vocabulary: readonly [];
|
|
2024
|
+
};
|
|
2020
2025
|
readonly BadgeProp: {
|
|
2021
2026
|
readonly group: "data-display";
|
|
2022
2027
|
readonly file: "components/data-display.prop.ts";
|
|
@@ -2428,7 +2433,7 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
2428
2433
|
readonly DialogContentProp: {
|
|
2429
2434
|
readonly group: "feedback";
|
|
2430
2435
|
readonly file: "components/feedback.prop.ts";
|
|
2431
|
-
readonly vocabulary: readonly ["ConfirmVariantProp", "ClassNameProp", "ChildrenProp", {
|
|
2436
|
+
readonly vocabulary: readonly ["ConfirmVariantProp", "ClassNameProp", "ChildrenProp", "WidthProp", {
|
|
2432
2437
|
readonly field: "showCloseButton";
|
|
2433
2438
|
readonly local: true;
|
|
2434
2439
|
readonly reason: 'Corner ✕ opt-out; defaults to false under variant="destructive".';
|
|
@@ -3312,13 +3317,39 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
3312
3317
|
readonly reason: "antd `onDrop` info: true when it lands as a sibling, false inside.";
|
|
3313
3318
|
}];
|
|
3314
3319
|
};
|
|
3320
|
+
readonly SortableListItemProp: {
|
|
3321
|
+
readonly group: "data-entry";
|
|
3322
|
+
readonly file: "components/data-entry.prop.ts";
|
|
3323
|
+
readonly vocabulary: readonly ["ValueProp", "LabelProp", "DisabledProp"];
|
|
3324
|
+
};
|
|
3325
|
+
readonly SortableListProp: {
|
|
3326
|
+
readonly group: "data-entry";
|
|
3327
|
+
readonly file: "components/data-entry.prop.ts";
|
|
3328
|
+
readonly vocabulary: readonly ["ValueProp", "DefaultValueProp", "OnValueChangeProp", "DisabledProp", "IdProp", "ClassNameProp", {
|
|
3329
|
+
readonly field: "items";
|
|
3330
|
+
readonly local: true;
|
|
3331
|
+
readonly reason: "The rows to order — key + spoken label + per-item disabled; not select options (nothing is chosen, the order is the value).";
|
|
3332
|
+
}, {
|
|
3333
|
+
readonly field: "renderItem";
|
|
3334
|
+
readonly local: true;
|
|
3335
|
+
readonly reason: "Draws an item's content beside the grip, with its index and whether it is held.";
|
|
3336
|
+
}, {
|
|
3337
|
+
readonly field: "layout";
|
|
3338
|
+
readonly local: true;
|
|
3339
|
+
readonly reason: "list (stacked rows) vs grid (auto-filled tiles) — the same keyboard order either way; not OrientationProp, a grid is neither axis.";
|
|
3340
|
+
}, {
|
|
3341
|
+
readonly field: "aria-label";
|
|
3342
|
+
readonly local: true;
|
|
3343
|
+
readonly reason: "Accessible name of the list.";
|
|
3344
|
+
}];
|
|
3345
|
+
};
|
|
3315
3346
|
readonly EmojiPickerProp: {
|
|
3316
3347
|
readonly group: "data-entry";
|
|
3317
3348
|
readonly file: "components/data-entry.prop.ts";
|
|
3318
3349
|
readonly vocabulary: readonly ["ValueProp", "DefaultValueProp", "OnValueChangeProp", "OpenProp", "DefaultOpenProp", "OnOpenChangeProp", "SizeProp", "DisabledProp", "IdProp", "ClassNameProp", {
|
|
3319
3350
|
readonly field: "removable";
|
|
3320
3351
|
readonly local: true;
|
|
3321
|
-
readonly reason:
|
|
3352
|
+
readonly reason: 'Whether "remove icon" is offered while a value is set — a picker for an OPTIONAL icon (gh#1164), not AllowClearProp\'s inline ✕ on a field.';
|
|
3322
3353
|
}, {
|
|
3323
3354
|
readonly field: "recentsKey";
|
|
3324
3355
|
readonly local: true;
|
package/dist/props/registry.js
CHANGED
|
@@ -2417,6 +2417,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
2417
2417
|
file: "components/data-display.prop.ts",
|
|
2418
2418
|
vocabulary: []
|
|
2419
2419
|
},
|
|
2420
|
+
AvatarImageFitProp: {
|
|
2421
|
+
group: "data-display",
|
|
2422
|
+
file: "components/data-display.prop.ts",
|
|
2423
|
+
vocabulary: []
|
|
2424
|
+
},
|
|
2420
2425
|
BadgeProp: {
|
|
2421
2426
|
group: "data-display",
|
|
2422
2427
|
file: "components/data-display.prop.ts",
|
|
@@ -2850,6 +2855,7 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
2850
2855
|
"ConfirmVariantProp",
|
|
2851
2856
|
"ClassNameProp",
|
|
2852
2857
|
"ChildrenProp",
|
|
2858
|
+
"WidthProp",
|
|
2853
2859
|
{
|
|
2854
2860
|
field: "showCloseButton",
|
|
2855
2861
|
local: true,
|
|
@@ -3917,6 +3923,39 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
3917
3923
|
}
|
|
3918
3924
|
]
|
|
3919
3925
|
},
|
|
3926
|
+
SortableListItemProp: {
|
|
3927
|
+
group: "data-entry",
|
|
3928
|
+
file: "components/data-entry.prop.ts",
|
|
3929
|
+
vocabulary: ["ValueProp", "LabelProp", "DisabledProp"]
|
|
3930
|
+
},
|
|
3931
|
+
SortableListProp: {
|
|
3932
|
+
group: "data-entry",
|
|
3933
|
+
file: "components/data-entry.prop.ts",
|
|
3934
|
+
vocabulary: [
|
|
3935
|
+
"ValueProp",
|
|
3936
|
+
"DefaultValueProp",
|
|
3937
|
+
"OnValueChangeProp",
|
|
3938
|
+
"DisabledProp",
|
|
3939
|
+
"IdProp",
|
|
3940
|
+
"ClassNameProp",
|
|
3941
|
+
{
|
|
3942
|
+
field: "items",
|
|
3943
|
+
local: true,
|
|
3944
|
+
reason: "The rows to order \u2014 key + spoken label + per-item disabled; not select options (nothing is chosen, the order is the value)."
|
|
3945
|
+
},
|
|
3946
|
+
{
|
|
3947
|
+
field: "renderItem",
|
|
3948
|
+
local: true,
|
|
3949
|
+
reason: "Draws an item's content beside the grip, with its index and whether it is held."
|
|
3950
|
+
},
|
|
3951
|
+
{
|
|
3952
|
+
field: "layout",
|
|
3953
|
+
local: true,
|
|
3954
|
+
reason: "list (stacked rows) vs grid (auto-filled tiles) \u2014 the same keyboard order either way; not OrientationProp, a grid is neither axis."
|
|
3955
|
+
},
|
|
3956
|
+
{ field: "aria-label", local: true, reason: "Accessible name of the list." }
|
|
3957
|
+
]
|
|
3958
|
+
},
|
|
3920
3959
|
EmojiPickerProp: {
|
|
3921
3960
|
group: "data-entry",
|
|
3922
3961
|
file: "components/data-entry.prop.ts",
|
|
@@ -3946,7 +3985,11 @@ const COMPONENT_PROP_REGISTRY = {
|
|
|
3946
3985
|
local: true,
|
|
3947
3986
|
reason: "Replaces the default trigger button (a page icon drawn large, a reaction chip) \u2014 a ReactNode slot, not a TriggerProp mode."
|
|
3948
3987
|
},
|
|
3949
|
-
{
|
|
3988
|
+
{
|
|
3989
|
+
field: "aria-label",
|
|
3990
|
+
local: true,
|
|
3991
|
+
reason: "Accessible name of the trigger and the popover."
|
|
3992
|
+
}
|
|
3950
3993
|
]
|
|
3951
3994
|
},
|
|
3952
3995
|
TreeProp: {
|
package/dist/styles/control.css
CHANGED
|
@@ -1026,6 +1026,56 @@
|
|
|
1026
1026
|
background-color: hsl(var(--accent));
|
|
1027
1027
|
}
|
|
1028
1028
|
|
|
1029
|
+
.ui-sortable-list-items {
|
|
1030
|
+
display: flex;
|
|
1031
|
+
flex-direction: column;
|
|
1032
|
+
gap: var(--sortable-list-gap);
|
|
1033
|
+
margin: 0;
|
|
1034
|
+
padding: 0;
|
|
1035
|
+
list-style: none;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
.ui-sortable-list[data-layout="grid"] .ui-sortable-list-items {
|
|
1039
|
+
display: grid;
|
|
1040
|
+
grid-template-columns: repeat(
|
|
1041
|
+
auto-fill,
|
|
1042
|
+
minmax(min(100%, var(--sortable-list-grid-item-min-inline-size)), 1fr)
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
.ui-sortable-list-item {
|
|
1047
|
+
display: flex;
|
|
1048
|
+
min-inline-size: 0;
|
|
1049
|
+
align-items: center;
|
|
1050
|
+
gap: var(--sortable-list-gap);
|
|
1051
|
+
border: var(--stroke-hairline) solid hsl(var(--border));
|
|
1052
|
+
border-radius: var(--sortable-list-item-radius);
|
|
1053
|
+
background: hsl(var(--card));
|
|
1054
|
+
padding: var(--sortable-list-item-padding);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
.ui-sortable-list-item[data-dragging] {
|
|
1058
|
+
position: relative;
|
|
1059
|
+
z-index: 1;
|
|
1060
|
+
border-color: hsl(var(--ring));
|
|
1061
|
+
box-shadow: var(--shadow-md);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
.ui-sortable-list-content {
|
|
1065
|
+
min-inline-size: 0;
|
|
1066
|
+
flex: 1 1 0%;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
.ui-sortable-list-handle {
|
|
1070
|
+
flex-shrink: 0;
|
|
1071
|
+
cursor: grab;
|
|
1072
|
+
touch-action: none;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
.ui-sortable-list-item[data-dragging] .ui-sortable-list-handle {
|
|
1076
|
+
cursor: grabbing;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1029
1079
|
.ui-emoji-picker-grid {
|
|
1030
1080
|
display: flex;
|
|
1031
1081
|
flex-direction: column;
|
|
@@ -47,7 +47,12 @@
|
|
|
47
47
|
top: 50%;
|
|
48
48
|
z-index: var(--overlay-z-index);
|
|
49
49
|
display: grid;
|
|
50
|
-
width: min(
|
|
50
|
+
width: min(
|
|
51
|
+
var(--dialog-width, var(--dialog-width-default)),
|
|
52
|
+
calc(100% - var(--dialog-viewport-inset))
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
--tw-animation-duration: var(--dialog-motion-duration, var(--duration-fast));
|
|
51
56
|
max-width: none;
|
|
52
57
|
transform: translate(-50%, -50%);
|
|
53
58
|
gap: var(--dialog-space-gap);
|
|
@@ -424,6 +429,14 @@
|
|
|
424
429
|
inset: 0;
|
|
425
430
|
}
|
|
426
431
|
|
|
432
|
+
.ui-sheet-panel[data-state="open"] {
|
|
433
|
+
--tw-animation-duration: var(--sheet-enter-duration, var(--duration-fast));
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.ui-sheet-panel[data-state="closed"] {
|
|
437
|
+
--tw-animation-duration: var(--sheet-exit-duration, var(--duration-fast));
|
|
438
|
+
}
|
|
439
|
+
|
|
427
440
|
.ui-sheet-panel {
|
|
428
441
|
|
|
429
442
|
background-color: var(--sheet-surface-background, hsl(var(--background)));
|
package/dist/styles/layers.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "31.
|
|
2
|
+
"version": "31.29.0",
|
|
3
3
|
"generatedBy": "scripts/gen-style-layers.mjs — do not edit by hand; run `pnpm gen:style-layers`",
|
|
4
4
|
"base": "base.css",
|
|
5
5
|
"fonts": "fonts.css",
|
|
@@ -1035,6 +1035,11 @@
|
|
|
1035
1035
|
"control.css"
|
|
1036
1036
|
]
|
|
1037
1037
|
},
|
|
1038
|
+
"SortableList": {
|
|
1039
|
+
"layers": [
|
|
1040
|
+
"control.css"
|
|
1041
|
+
]
|
|
1042
|
+
},
|
|
1038
1043
|
"SpaceCompact": {
|
|
1039
1044
|
"layers": [
|
|
1040
1045
|
"layout.css"
|
package/dist/styles/layout.css
CHANGED
|
@@ -138,7 +138,10 @@
|
|
|
138
138
|
min-inline-size: 0;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
.ui-space-compact[data-orientation="horizontal"][data-full-width="true"]
|
|
141
|
+
.ui-space-compact[data-orientation="horizontal"][data-full-width="true"]
|
|
142
|
+
> [data-slot="space-compact-item"]:not(
|
|
143
|
+
:has(.ui-control, .ui-control-multiline, .ui-tag-input)
|
|
144
|
+
) {
|
|
142
145
|
flex: none;
|
|
143
146
|
}
|
|
144
147
|
|
|
@@ -146,16 +149,21 @@
|
|
|
146
149
|
flex-direction: column;
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
.ui-space-compact[data-orientation="vertical"][data-full-width="true"]
|
|
152
|
+
.ui-space-compact[data-orientation="vertical"][data-full-width="true"]
|
|
153
|
+
> [data-slot="space-compact-item"] {
|
|
150
154
|
min-inline-size: auto;
|
|
151
155
|
min-block-size: 0;
|
|
152
156
|
}
|
|
153
157
|
|
|
154
|
-
.ui-space-compact[data-orientation="horizontal"]
|
|
158
|
+
.ui-space-compact[data-orientation="horizontal"]
|
|
159
|
+
> [data-slot="space-compact-item"]
|
|
160
|
+
+ [data-slot="space-compact-item"] {
|
|
155
161
|
margin-inline-start: calc(var(--control-border-width, var(--stroke-hairline)) * -1);
|
|
156
162
|
}
|
|
157
163
|
|
|
158
|
-
.ui-space-compact[data-orientation="vertical"]
|
|
164
|
+
.ui-space-compact[data-orientation="vertical"]
|
|
165
|
+
> [data-slot="space-compact-item"]
|
|
166
|
+
+ [data-slot="space-compact-item"] {
|
|
159
167
|
margin-block-start: calc(var(--control-border-width, var(--stroke-hairline)) * -1);
|
|
160
168
|
}
|
|
161
169
|
|
|
@@ -175,12 +183,14 @@
|
|
|
175
183
|
z-index: 1;
|
|
176
184
|
}
|
|
177
185
|
|
|
178
|
-
.ui-space-compact[data-orientation="horizontal"]
|
|
186
|
+
.ui-space-compact[data-orientation="horizontal"]
|
|
187
|
+
> [data-slot="space-compact-item"]:not(:first-child) {
|
|
179
188
|
--input-radius-start: 0;
|
|
180
189
|
--control-trigger-radius-start: 0;
|
|
181
190
|
}
|
|
182
191
|
|
|
183
|
-
.ui-space-compact[data-orientation="horizontal"]
|
|
192
|
+
.ui-space-compact[data-orientation="horizontal"]
|
|
193
|
+
> [data-slot="space-compact-item"]:not(:last-child) {
|
|
184
194
|
--input-radius-end: 0;
|
|
185
195
|
--control-trigger-radius-end: 0;
|
|
186
196
|
}
|
|
@@ -410,6 +420,10 @@
|
|
|
410
420
|
align-items: start;
|
|
411
421
|
}
|
|
412
422
|
|
|
423
|
+
.ui-responsive-grid[data-dense] {
|
|
424
|
+
grid-auto-flow: row dense;
|
|
425
|
+
}
|
|
426
|
+
|
|
413
427
|
.ui-responsive-grid[data-align="start"] {
|
|
414
428
|
align-items: start;
|
|
415
429
|
}
|
|
@@ -926,7 +940,10 @@
|
|
|
926
940
|
|
|
927
941
|
.ui-page-container[data-header-scale="display"] .ui-page-title,
|
|
928
942
|
.ui-page-container[data-header-scale="display"] .ui-page-header .ui-page-title {
|
|
929
|
-
font-size: var(
|
|
943
|
+
font-size: var(
|
|
944
|
+
--page-title-font-size-display,
|
|
945
|
+
var(--font-size-4xl, calc(var(--font-size-display) / var(--font-size-display-ratio)))
|
|
946
|
+
);
|
|
930
947
|
font-weight: var(--font-weight-semibold);
|
|
931
948
|
line-height: var(--page-title-line-height-display);
|
|
932
949
|
text-wrap: balance;
|
|
@@ -1966,22 +1983,27 @@
|
|
|
1966
1983
|
.ui-master-detail[data-rail-width="wide"] {
|
|
1967
1984
|
--master-detail-rail-size: var(--master-detail-rail-wide);
|
|
1968
1985
|
}
|
|
1986
|
+
|
|
1969
1987
|
.ui-responsive-grid-item {
|
|
1970
1988
|
grid-column: span min(var(--responsive-grid-base, 1), var(--responsive-grid-item-base, 1));
|
|
1989
|
+
grid-row: span var(--responsive-grid-item-row-base, 1);
|
|
1971
1990
|
}
|
|
1972
1991
|
@container responsive-grid (min-width: 40rem) {
|
|
1973
1992
|
.ui-responsive-grid-item {
|
|
1974
1993
|
grid-column: span min(var(--responsive-grid-sm, 1), var(--responsive-grid-item-sm, 1));
|
|
1994
|
+
grid-row: span var(--responsive-grid-item-row-sm, 1);
|
|
1975
1995
|
}
|
|
1976
1996
|
}
|
|
1977
1997
|
@container responsive-grid (min-width: 48rem) {
|
|
1978
1998
|
.ui-responsive-grid-item {
|
|
1979
1999
|
grid-column: span min(var(--responsive-grid-md, 1), var(--responsive-grid-item-md, 1));
|
|
2000
|
+
grid-row: span var(--responsive-grid-item-row-md, 1);
|
|
1980
2001
|
}
|
|
1981
2002
|
}
|
|
1982
2003
|
@container responsive-grid (min-width: 64rem) {
|
|
1983
2004
|
.ui-responsive-grid-item {
|
|
1984
2005
|
grid-column: span min(var(--responsive-grid-lg, 1), var(--responsive-grid-item-lg, 1));
|
|
2006
|
+
grid-row: span var(--responsive-grid-item-row-lg, 1);
|
|
1985
2007
|
}
|
|
1986
2008
|
}
|
|
1987
2009
|
.ui-separator[data-label-size="2xs"] .ui-separator-label {
|
|
@@ -1504,6 +1504,21 @@
|
|
|
1504
1504
|
font-weight: var(--font-weight-medium);
|
|
1505
1505
|
}
|
|
1506
1506
|
|
|
1507
|
+
.ui-app-launcher-footer {
|
|
1508
|
+
display: flex;
|
|
1509
|
+
flex-wrap: wrap;
|
|
1510
|
+
align-items: center;
|
|
1511
|
+
gap: var(--app-launcher-footer-gap);
|
|
1512
|
+
margin-block-start: var(--app-launcher-footer-space-block);
|
|
1513
|
+
padding-block-start: var(--app-launcher-footer-space-block);
|
|
1514
|
+
border-block-start: var(--stroke-hairline) solid hsl(var(--border));
|
|
1515
|
+
font-size: var(--app-launcher-footer-font-size);
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
.ui-app-launcher-launchpad .ui-app-launcher-footer {
|
|
1519
|
+
justify-content: center;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1507
1522
|
.ui-app-launcher-state {
|
|
1508
1523
|
display: flex;
|
|
1509
1524
|
min-height: var(--app-launcher-state-min-height);
|
|
@@ -1606,6 +1621,17 @@
|
|
|
1606
1621
|
height: var(--sidebar-product-caret-icon-size);
|
|
1607
1622
|
}
|
|
1608
1623
|
|
|
1624
|
+
.sb-action {
|
|
1625
|
+
display: flex;
|
|
1626
|
+
flex-shrink: 0;
|
|
1627
|
+
flex-direction: column;
|
|
1628
|
+
padding: var(--sidebar-action-padding);
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
.sb-root[data-collapsed="true"] .sb-action {
|
|
1632
|
+
align-items: center;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1609
1635
|
.sb-nav-scroll {
|
|
1610
1636
|
flex: 1;
|
|
1611
1637
|
min-height: 0;
|
|
@@ -470,6 +470,11 @@
|
|
|
470
470
|
);
|
|
471
471
|
--emoji-picker-glyph-size: var(--icon-size-lg);
|
|
472
472
|
--emoji-picker-grid-max-block-size: 16rem;
|
|
473
|
+
|
|
474
|
+
--sortable-list-gap: var(--space-2);
|
|
475
|
+
--sortable-list-item-padding: var(--space-2);
|
|
476
|
+
--sortable-list-item-radius: var(--control-radius);
|
|
477
|
+
--sortable-list-grid-item-min-inline-size: 12rem;
|
|
473
478
|
}
|
|
474
479
|
|
|
475
480
|
@media (pointer: coarse) {
|
|
@@ -29,6 +29,12 @@
|
|
|
29
29
|
--sheet-close-rest-alpha: 0.7;
|
|
30
30
|
--sheet-header-close-space-inline-end: var(--space-8);
|
|
31
31
|
--dialog-width-default: 32rem;
|
|
32
|
+
|
|
33
|
+
--dialog-width: initial;
|
|
34
|
+
|
|
35
|
+
--dialog-motion-duration: initial;
|
|
36
|
+
--sheet-enter-duration: initial;
|
|
37
|
+
--sheet-exit-duration: initial;
|
|
32
38
|
--dialog-viewport-inset: 1.5rem;
|
|
33
39
|
--dialog-overlay-background: initial;
|
|
34
40
|
|
|
@@ -139,6 +139,8 @@
|
|
|
139
139
|
|
|
140
140
|
--sidebar-nav-item-radius: initial;
|
|
141
141
|
--sidebar-nav-scroll-padding: var(--space-3) var(--space-2);
|
|
142
|
+
|
|
143
|
+
--sidebar-action-padding: var(--space-3) var(--space-2) 0;
|
|
142
144
|
--sidebar-section-gap: var(--space-4);
|
|
143
145
|
--sidebar-section-label-padding-x: var(--space-2);
|
|
144
146
|
--sidebar-section-label-padding-bottom: var(--space-1);
|
|
@@ -240,6 +242,10 @@
|
|
|
240
242
|
--app-launcher-group-label-color: initial;
|
|
241
243
|
--app-launcher-state-min-height: 8rem;
|
|
242
244
|
|
|
245
|
+
--app-launcher-footer-space-block: var(--space-2);
|
|
246
|
+
--app-launcher-footer-gap: var(--space-3);
|
|
247
|
+
--app-launcher-footer-font-size: var(--font-size-sm, var(--font-size-base));
|
|
248
|
+
|
|
243
249
|
--app-launcher-launchpad-backdrop-background: initial;
|
|
244
250
|
--app-launcher-launchpad-backdrop-blur-size: var(--blur-lg);
|
|
245
251
|
--app-launcher-launchpad-backdrop-alpha: 55%;
|
|
@@ -91,10 +91,7 @@
|
|
|
91
91
|
|
|
92
92
|
--page-title-font-size-chrome: var(--heading-h3, var(--font-size-base));
|
|
93
93
|
|
|
94
|
-
--page-title-font-size-display:
|
|
95
|
-
--font-size-4xl,
|
|
96
|
-
calc(var(--font-size-display) / var(--font-size-display-ratio))
|
|
97
|
-
);
|
|
94
|
+
--page-title-font-size-display: initial;
|
|
98
95
|
--page-title-line-height-display: 1.4;
|
|
99
96
|
|
|
100
97
|
--page-icon-size: var(--icon-size-4xl);
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
> Generated by `scripts/frame-coverage.mjs` (issue #163). Do not edit by hand — run `pnpm check:frame-coverage`.
|
|
4
4
|
> Standard: [FRAME-COVERAGE-STANDARD.md](./FRAME-COVERAGE-STANDARD.md). A missing dimension is **UNTESTED**, never a pass.
|
|
5
5
|
|
|
6
|
-
- Public components: **
|
|
7
|
-
- With ≥1 frame: **
|
|
6
|
+
- Public components: **185**
|
|
7
|
+
- With ≥1 frame: **161** · zero-frame: **24**
|
|
8
8
|
- Fully covered (every contract axis declared): **0**
|
|
9
9
|
|
|
10
10
|
## UNTESTED — no `/frame/**` route
|
|
@@ -195,6 +195,7 @@ Legend: ✓ covered · N/A reasoned skip · · UNTESTED (blank cell = UNTESTED).
|
|
|
195
195
|
| PieChart | ✓ | ✓ | N/A | N/A | · | · | · | · | · | · |
|
|
196
196
|
| CommandPalette | ✓ | N/A | · | · | · | · | · | · | · | · |
|
|
197
197
|
| EmojiPicker | ✓ | · | · | · | · | · | · | · | · | · |
|
|
198
|
+
| SortableList | ✓ | N/A | · | · | · | · | · | · | · | · |
|
|
198
199
|
| TwoFactorSetup | ✓ | N/A | · | · | · | · | · | · | · | · |
|
|
199
200
|
| AuthDivider | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
|
|
200
201
|
| AuthFooter | ✓ | N/A | N/A | N/A | · | · | · | · | · | · |
|
|
@@ -11,9 +11,11 @@ import {
|
|
|
11
11
|
} from "@godxjp/ui/data-display";
|
|
12
12
|
import { Button, Text } from "@godxjp/ui/general";
|
|
13
13
|
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
14
|
+
import { useTranslation } from "@godxjp/ui/i18n";
|
|
14
15
|
import { Building2, KeyRound, ShieldCheck, Sparkles } from "lucide-react";
|
|
15
16
|
|
|
16
17
|
import portraitAmber from "../assets/portrait-amber.svg";
|
|
18
|
+
import shotLandscape from "../assets/shot-landscape.svg";
|
|
17
19
|
import portraitClay from "../assets/portrait-clay.svg";
|
|
18
20
|
import portraitIndigo from "../assets/portrait-indigo.svg";
|
|
19
21
|
import portraitIris from "../assets/portrait-iris.svg";
|
|
@@ -39,9 +41,39 @@ import portraitSlate from "../assets/portrait-slate.svg";
|
|
|
39
41
|
* Composed only from real @godxjp/ui components.
|
|
40
42
|
*/
|
|
41
43
|
export default function Demo() {
|
|
44
|
+
const { t } = useTranslation();
|
|
42
45
|
return (
|
|
43
46
|
<PageContainer title="Avatar" subtitle="Identity image with a readable fallback">
|
|
44
47
|
<Flex direction="col" gap="lg">
|
|
48
|
+
<Card>
|
|
49
|
+
<CardHeader>
|
|
50
|
+
<CardTitle level={2}>{t("avatarDocs.fitTitle")}</CardTitle>
|
|
51
|
+
<CardDescription>{t("avatarDocs.fitDescription")}</CardDescription>
|
|
52
|
+
</CardHeader>
|
|
53
|
+
<CardContent>
|
|
54
|
+
{/* gh#1176: a wide logo — cover crops it, contain shows it whole. */}
|
|
55
|
+
<Flex direction="row" wrap align="center" gap="md">
|
|
56
|
+
<Flex direction="col" align="center" gap="xs">
|
|
57
|
+
<Avatar shape="square" size="lg">
|
|
58
|
+
<AvatarImage src={shotLandscape} alt={t("avatarDocs.logo")} />
|
|
59
|
+
<AvatarFallback>AC</AvatarFallback>
|
|
60
|
+
</Avatar>
|
|
61
|
+
<Text size="sm" tone="muted">
|
|
62
|
+
cover
|
|
63
|
+
</Text>
|
|
64
|
+
</Flex>
|
|
65
|
+
<Flex direction="col" align="center" gap="xs">
|
|
66
|
+
<Avatar shape="square" size="lg">
|
|
67
|
+
<AvatarImage src={shotLandscape} alt={t("avatarDocs.logo")} fit="contain" />
|
|
68
|
+
<AvatarFallback>AC</AvatarFallback>
|
|
69
|
+
</Avatar>
|
|
70
|
+
<Text size="sm" tone="muted">
|
|
71
|
+
contain
|
|
72
|
+
</Text>
|
|
73
|
+
</Flex>
|
|
74
|
+
</Flex>
|
|
75
|
+
</CardContent>
|
|
76
|
+
</Card>
|
|
45
77
|
<Card>
|
|
46
78
|
<CardHeader>
|
|
47
79
|
<CardTitle level={2}>Image + fallback</CardTitle>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@godxjp/ui/data-display";
|
|
3
|
+
import { SortableList } from "@godxjp/ui/data-entry";
|
|
4
|
+
import { Text } from "@godxjp/ui/general";
|
|
5
|
+
import { useTranslation } from "@godxjp/ui/i18n";
|
|
6
|
+
import { Flex, PageContainer } from "@godxjp/ui/layout";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* SortableList (gh#1173) — a desktop editor's widget order (tiles) and a settings list of tabs,
|
|
10
|
+
* reordered by dragging a grip or by the keyboard, every step announced.
|
|
11
|
+
*/
|
|
12
|
+
export default function Demo() {
|
|
13
|
+
const { t, locale } = useTranslation();
|
|
14
|
+
const list = new Intl.ListFormat(locale, { style: "narrow", type: "unit" });
|
|
15
|
+
const ordinal = new Intl.NumberFormat(locale);
|
|
16
|
+
const widgets = [
|
|
17
|
+
{ value: "calendar", label: t("sortableListDocs.calendar") },
|
|
18
|
+
{ value: "mail", label: t("sortableListDocs.mail") },
|
|
19
|
+
{ value: "tasks", label: t("sortableListDocs.tasks") },
|
|
20
|
+
{ value: "notes", label: t("sortableListDocs.notes") },
|
|
21
|
+
];
|
|
22
|
+
const tabs = [
|
|
23
|
+
{ value: "overview", label: t("sortableListDocs.overview") },
|
|
24
|
+
{ value: "members", label: t("sortableListDocs.members") },
|
|
25
|
+
{ value: "billing", label: t("sortableListDocs.billing"), disabled: true },
|
|
26
|
+
{ value: "audit", label: t("sortableListDocs.audit") },
|
|
27
|
+
];
|
|
28
|
+
const [order, setOrder] = React.useState(widgets.map((w) => w.value));
|
|
29
|
+
return (
|
|
30
|
+
<PageContainer title="SortableList" subtitle={t("sortableListDocs.subtitle")}>
|
|
31
|
+
<Flex direction="col" gap="lg">
|
|
32
|
+
<Card>
|
|
33
|
+
<CardHeader>
|
|
34
|
+
<CardTitle level={2}>{t("sortableListDocs.widgetsTitle")}</CardTitle>
|
|
35
|
+
<CardDescription>{t("sortableListDocs.widgetsDescription")}</CardDescription>
|
|
36
|
+
</CardHeader>
|
|
37
|
+
<CardContent>
|
|
38
|
+
<Flex direction="col" gap="sm">
|
|
39
|
+
<SortableList
|
|
40
|
+
aria-label={t("sortableListDocs.widgetsTitle")}
|
|
41
|
+
layout="grid"
|
|
42
|
+
items={widgets}
|
|
43
|
+
value={order}
|
|
44
|
+
onValueChange={setOrder}
|
|
45
|
+
renderItem={(item, { index }) => (
|
|
46
|
+
<Flex direction="col" gap="xs">
|
|
47
|
+
<Text weight="medium">{item.label}</Text>
|
|
48
|
+
<Text size="sm" tone="muted">
|
|
49
|
+
{t("sortableListDocs.slot", { position: ordinal.format(index + 1) })}
|
|
50
|
+
</Text>
|
|
51
|
+
</Flex>
|
|
52
|
+
)}
|
|
53
|
+
/>
|
|
54
|
+
<Text size="sm" tone="muted">
|
|
55
|
+
{t("sortableListDocs.saved", {
|
|
56
|
+
order: list.format(
|
|
57
|
+
order.map((key) => widgets.find((w) => w.value === key)?.label ?? key),
|
|
58
|
+
),
|
|
59
|
+
})}
|
|
60
|
+
</Text>
|
|
61
|
+
</Flex>
|
|
62
|
+
</CardContent>
|
|
63
|
+
</Card>
|
|
64
|
+
<Card>
|
|
65
|
+
<CardHeader>
|
|
66
|
+
<CardTitle level={2}>{t("sortableListDocs.tabsTitle")}</CardTitle>
|
|
67
|
+
<CardDescription>{t("sortableListDocs.tabsDescription")}</CardDescription>
|
|
68
|
+
</CardHeader>
|
|
69
|
+
<CardContent>
|
|
70
|
+
<SortableList aria-label={t("sortableListDocs.tabsTitle")} items={tabs} />
|
|
71
|
+
</CardContent>
|
|
72
|
+
</Card>
|
|
73
|
+
</Flex>
|
|
74
|
+
</PageContainer>
|
|
75
|
+
);
|
|
76
|
+
}
|