@godxjp/ui 31.27.0 → 31.28.1
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 +7 -7
- package/agent/components/BlockEditor.json +8 -0
- package/agent/components/CommandPalette.json +5 -0
- package/agent/components/EmojiPicker.json +78 -0
- package/agent/components/Markdown.json +11 -0
- package/agent/components/PageContainer.json +11 -1
- package/agent/components/PageCover.json +75 -0
- package/agent/components/Tree.json +6 -0
- package/agent/components-index.json +10 -0
- package/agent/components.json +194 -1
- package/agent/index.json +8 -8
- package/agent/llms.txt +7 -7
- package/agent/tokens.json +79 -1
- package/dist/components/data-display/tree.js +5 -0
- package/dist/components/data-entry/command-palette.d.ts +5 -0
- package/dist/components/data-entry/command-palette.js +1 -0
- package/dist/components/data-entry/emoji-data.d.ts +43 -0
- package/dist/components/data-entry/emoji-data.js +54 -0
- package/dist/components/data-entry/emoji-picker.d.ts +13 -0
- package/dist/components/data-entry/emoji-picker.js +272 -0
- package/dist/components/data-entry/index.d.ts +2 -0
- package/dist/components/data-entry/index.js +2 -0
- package/dist/components/layout/index.d.ts +2 -0
- package/dist/components/layout/index.js +2 -0
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +8 -1
- package/dist/components/layout/page-cover.d.ts +14 -0
- package/dist/components/layout/page-cover.js +127 -0
- package/dist/contracts/measurement.json +1 -1
- package/dist/i18n/messages/en.json +25 -0
- package/dist/i18n/messages/ja.json +25 -0
- package/dist/i18n/messages/vi.json +25 -0
- package/dist/props/components/data-display.prop.d.ts +6 -0
- package/dist/props/components/data-entry.prop.d.ts +26 -0
- package/dist/props/components/layout.prop.d.ts +49 -2
- package/dist/props/registry.d.ts +85 -1
- package/dist/props/registry.js +95 -1
- package/dist/styles/control.css +81 -0
- package/dist/styles/data-display-layout.css +94 -0
- package/dist/styles/focus-ring.css +2 -0
- package/dist/styles/layers.json +17 -1
- package/dist/styles/layout.css +113 -0
- package/dist/tokens/components/control.css +10 -0
- package/dist/tokens/components/data-display.css +1 -0
- package/dist/tokens/semantic/layout.css +14 -0
- package/docs/FORMS.md +5 -0
- package/docs/FRAME-COVERAGE-REPORT.md +4 -2
- package/docs/data-entry/emoji-picker.tsx +35 -0
- package/docs/i18n/messages/en.json +16 -0
- package/docs/i18n/messages/ja.json +16 -0
- package/docs/i18n/messages/vi.json +16 -0
- package/docs/layout/page-cover.tsx +56 -0
- package/package.json +5 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PageContainer } from "./page-container.js";
|
|
2
|
+
import { PageCover } from "./page-cover.js";
|
|
2
3
|
import { Flex } from "./flex.js";
|
|
3
4
|
import { SpaceCompact } from "./space-compact.js";
|
|
4
5
|
import { ResizablePanel, ResizablePanelGroup, ResizableHandle } from "./resizable.js";
|
|
@@ -55,6 +56,7 @@ export {
|
|
|
55
56
|
NavList,
|
|
56
57
|
OrgSwitcher,
|
|
57
58
|
PageContainer,
|
|
59
|
+
PageCover,
|
|
58
60
|
ResizableHandle,
|
|
59
61
|
ResizablePanel,
|
|
60
62
|
ResizablePanelGroup,
|
|
@@ -2,7 +2,7 @@ import type { PageContainerProp, PageInsetProp } from "../../props/components/la
|
|
|
2
2
|
export type { PageContainerProp, PageContainerProp as PageContainerProps, PageContainerExtraProp, } from "../../props/components/layout.prop.js";
|
|
3
3
|
export type { BreadcrumbItemProp, BreadcrumbItemProp as BreadcrumbItem, } from "../../props/vocabulary/navigation.prop.js";
|
|
4
4
|
export declare function PageContainerInset({ className, children, ...props }: PageInsetProp): import("react").JSX.Element;
|
|
5
|
-
declare function PageContainerRoot({ title, subtitle, status, extra, toolbar, footer, toolbarPad, footerPad, breadcrumb, breadcrumbLabel, breadcrumbAriaLabel, linkComponent: LinkComponent, headerLoading, titleRef, density, variant, preset, headerLayout, headerScale, measure, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react").JSX.Element;
|
|
5
|
+
declare function PageContainerRoot({ title, subtitle, status, extra, toolbar, footer, toolbarPad, footerPad, breadcrumb, breadcrumbLabel, breadcrumbAriaLabel, linkComponent: LinkComponent, headerLoading, titleRef, density, variant, preset, headerLayout, headerScale, icon, cover, measure, stickyFooter, footerReveal, fill, children, className, }: PageContainerProp): import("react").JSX.Element;
|
|
6
6
|
export declare const PageContainer: typeof PageContainerRoot & {
|
|
7
7
|
Inset: typeof PageContainerInset;
|
|
8
8
|
};
|
|
@@ -51,6 +51,8 @@ function PageContainerRoot({
|
|
|
51
51
|
preset = "default",
|
|
52
52
|
headerLayout = "stack",
|
|
53
53
|
headerScale = "document",
|
|
54
|
+
icon,
|
|
55
|
+
cover,
|
|
54
56
|
measure = "default",
|
|
55
57
|
stickyFooter = false,
|
|
56
58
|
footerReveal = "always",
|
|
@@ -63,12 +65,14 @@ function PageContainerRoot({
|
|
|
63
65
|
const { t } = useTranslation();
|
|
64
66
|
const { start: extraStart, end: extraEnd } = resolvePageExtra(extra);
|
|
65
67
|
const titleFocus = titleRef === void 0 ? void 0 : { ref: titleRef, tabIndex: -1 };
|
|
68
|
+
const coverVariant = cover == null || cover === false ? void 0 : isValidElement(cover) && cover.props.variant === "eyecatch" ? "eyecatch" : "banner";
|
|
66
69
|
return /* @__PURE__ */ jsxs(
|
|
67
70
|
"div",
|
|
68
71
|
{
|
|
69
72
|
"data-preset": preset,
|
|
70
73
|
"data-measure": measure,
|
|
71
|
-
"data-header-scale": headerScale === "
|
|
74
|
+
"data-header-scale": headerScale === "document" ? void 0 : headerScale,
|
|
75
|
+
"data-cover": coverVariant,
|
|
72
76
|
"data-revealed": revealed ? "true" : void 0,
|
|
73
77
|
className: cn(
|
|
74
78
|
"ui-page-container",
|
|
@@ -82,6 +86,7 @@ function PageContainerRoot({
|
|
|
82
86
|
className
|
|
83
87
|
),
|
|
84
88
|
children: [
|
|
89
|
+
coverVariant === "banner" ? /* @__PURE__ */ jsx("div", { className: "ui-page-cover-slot", children: cover }) : null,
|
|
85
90
|
/* @__PURE__ */ jsxs(
|
|
86
91
|
"header",
|
|
87
92
|
{
|
|
@@ -134,8 +139,10 @@ function PageContainerRoot({
|
|
|
134
139
|
}) })
|
|
135
140
|
}
|
|
136
141
|
),
|
|
142
|
+
coverVariant === "eyecatch" ? /* @__PURE__ */ jsx("div", { className: "ui-page-cover-slot", children: cover }) : null,
|
|
137
143
|
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-row", children: [
|
|
138
144
|
/* @__PURE__ */ jsxs("div", { className: "ui-page-header-heading", children: [
|
|
145
|
+
icon != null && icon !== false ? /* @__PURE__ */ jsx("div", { className: "ui-page-header-icon", children: icon }) : null,
|
|
139
146
|
headerLoading ? /* @__PURE__ */ jsx(
|
|
140
147
|
"h1",
|
|
141
148
|
{
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { PageCoverProp } from "../../props/components/layout.prop.js";
|
|
3
|
+
export type { PageCoverProp, PageCoverProp as PageCoverProps, } from "../../props/components/layout.prop.js";
|
|
4
|
+
/**
|
|
5
|
+
* PageCover (gh#1160) — a page's cover image: Notion's banner across the top, or note.com's
|
|
6
|
+
* eyecatch in the reading column (`variant="eyecatch"`, ~1.91:1, rounded). Put it in
|
|
7
|
+
* `PageContainer cover`, which places it and lets the page `icon` overlap its bottom edge.
|
|
8
|
+
*
|
|
9
|
+
* The focal point is `positionY` (0 top – 100 bottom), applied as `object-position: 50% y%`.
|
|
10
|
+
* While `repositioning`, the image IS the control: a vertical WAI-ARIA slider that follows a drag
|
|
11
|
+
* (pixels map to percent through the image's real overflow, so the picture tracks the pointer)
|
|
12
|
+
* and the slider keys (arrows ±1, PageUp / PageDown ±10, Home / End); Enter or Escape ends it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PageCover: React.ForwardRefExoticComponent<PageCoverProp & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { useTranslation } from "../../i18n/use-translation.js";
|
|
5
|
+
import { cn } from "../../lib/utils.js";
|
|
6
|
+
const clamp = (value) => Math.min(100, Math.max(0, Math.round(value)));
|
|
7
|
+
const PageCover = React.forwardRef(function PageCover2({
|
|
8
|
+
src,
|
|
9
|
+
alt,
|
|
10
|
+
positionY = 50,
|
|
11
|
+
onPositionChange,
|
|
12
|
+
repositioning = false,
|
|
13
|
+
onRepositioningChange,
|
|
14
|
+
variant = "banner",
|
|
15
|
+
height = "md",
|
|
16
|
+
actions,
|
|
17
|
+
id,
|
|
18
|
+
className
|
|
19
|
+
}, ref) {
|
|
20
|
+
const { t } = useTranslation();
|
|
21
|
+
const frameRef = React.useRef(null);
|
|
22
|
+
const imageRef = React.useRef(null);
|
|
23
|
+
const drag = React.useRef(null);
|
|
24
|
+
const y = clamp(positionY);
|
|
25
|
+
const overflow = () => {
|
|
26
|
+
const frame = frameRef.current;
|
|
27
|
+
const image = imageRef.current;
|
|
28
|
+
if (!frame || !image || !image.naturalWidth) return 0;
|
|
29
|
+
const rendered = frame.clientWidth / image.naturalWidth * image.naturalHeight;
|
|
30
|
+
return Math.max(0, rendered - frame.clientHeight);
|
|
31
|
+
};
|
|
32
|
+
const onKeyDown = (event) => {
|
|
33
|
+
if (!repositioning) return;
|
|
34
|
+
const step = {
|
|
35
|
+
ArrowUp: 1,
|
|
36
|
+
ArrowRight: 1,
|
|
37
|
+
ArrowDown: -1,
|
|
38
|
+
ArrowLeft: -1,
|
|
39
|
+
PageUp: 10,
|
|
40
|
+
PageDown: -10
|
|
41
|
+
}[event.key];
|
|
42
|
+
let next = null;
|
|
43
|
+
if (step !== void 0) next = clamp(y + step);
|
|
44
|
+
else if (event.key === "Home") next = 0;
|
|
45
|
+
else if (event.key === "End") next = 100;
|
|
46
|
+
else if (event.key === "Enter" || event.key === "Escape") {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
onRepositioningChange?.(false);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (next === null) return;
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
if (next !== y) onPositionChange?.(next);
|
|
54
|
+
};
|
|
55
|
+
const onPointerDown = (event) => {
|
|
56
|
+
if (!repositioning || event.button !== 0) return;
|
|
57
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
58
|
+
drag.current = { pointer: event.pointerId, startY: event.clientY, startValue: y };
|
|
59
|
+
};
|
|
60
|
+
const onPointerMove = (event) => {
|
|
61
|
+
const active = drag.current;
|
|
62
|
+
if (!active || active.pointer !== event.pointerId) return;
|
|
63
|
+
const travel = overflow();
|
|
64
|
+
if (travel <= 0) return;
|
|
65
|
+
const next = clamp(active.startValue - (event.clientY - active.startY) / travel * 100);
|
|
66
|
+
if (next !== y) onPositionChange?.(next);
|
|
67
|
+
};
|
|
68
|
+
const endDrag = (event) => {
|
|
69
|
+
if (drag.current?.pointer === event.pointerId) drag.current = null;
|
|
70
|
+
};
|
|
71
|
+
const slider = repositioning ? {
|
|
72
|
+
role: "slider",
|
|
73
|
+
tabIndex: 0,
|
|
74
|
+
"aria-orientation": "vertical",
|
|
75
|
+
"aria-valuemin": 0,
|
|
76
|
+
"aria-valuemax": 100,
|
|
77
|
+
"aria-valuenow": y,
|
|
78
|
+
"aria-valuetext": t("layout.pageCover.valueText", { value: y }),
|
|
79
|
+
"aria-label": t("layout.pageCover.position")
|
|
80
|
+
} : {};
|
|
81
|
+
return /* @__PURE__ */ jsxs(
|
|
82
|
+
"div",
|
|
83
|
+
{
|
|
84
|
+
ref,
|
|
85
|
+
id,
|
|
86
|
+
"data-slot": "page-cover",
|
|
87
|
+
"data-variant": variant,
|
|
88
|
+
"data-height": variant === "banner" ? height : void 0,
|
|
89
|
+
"data-repositioning": repositioning ? "" : void 0,
|
|
90
|
+
className: cn("ui-page-cover", className),
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsxs(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
ref: frameRef,
|
|
96
|
+
className: "ui-page-cover-frame ui-focus-ring",
|
|
97
|
+
onKeyDown,
|
|
98
|
+
onPointerDown,
|
|
99
|
+
onPointerMove,
|
|
100
|
+
onPointerUp: endDrag,
|
|
101
|
+
onPointerCancel: endDrag,
|
|
102
|
+
...slider,
|
|
103
|
+
children: [
|
|
104
|
+
/* @__PURE__ */ jsx(
|
|
105
|
+
"img",
|
|
106
|
+
{
|
|
107
|
+
ref: imageRef,
|
|
108
|
+
className: "ui-page-cover-image",
|
|
109
|
+
src,
|
|
110
|
+
alt,
|
|
111
|
+
draggable: false,
|
|
112
|
+
style: { objectPosition: `50% ${y}%` }
|
|
113
|
+
}
|
|
114
|
+
),
|
|
115
|
+
repositioning ? /* @__PURE__ */ jsx("span", { className: "ui-page-cover-hint", "aria-hidden": "true", children: t("layout.pageCover.hint") }) : null
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
actions != null ? /* @__PURE__ */ jsx("div", { className: "ui-page-cover-actions", children: actions }) : null
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
PageCover.displayName = "PageCover";
|
|
125
|
+
export {
|
|
126
|
+
PageCover
|
|
127
|
+
};
|
|
@@ -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": "31.
|
|
3
|
+
"version": "31.28.1",
|
|
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,
|
|
@@ -212,6 +212,26 @@
|
|
|
212
212
|
"openDialog": "Choose from list",
|
|
213
213
|
"openSearch": "Search",
|
|
214
214
|
"suggestions": "Suggestions"
|
|
215
|
+
},
|
|
216
|
+
"emojiPicker": {
|
|
217
|
+
"trigger": "Choose an icon",
|
|
218
|
+
"search": "Search emoji",
|
|
219
|
+
"recent": "Recently used",
|
|
220
|
+
"remove": "Remove icon",
|
|
221
|
+
"empty": "No emoji found",
|
|
222
|
+
"loading": "Loading emoji…",
|
|
223
|
+
"grid": "Emoji",
|
|
224
|
+
"categories": {
|
|
225
|
+
"smileys": "Smileys & emotion",
|
|
226
|
+
"people": "People & body",
|
|
227
|
+
"animals": "Animals & nature",
|
|
228
|
+
"food": "Food & drink",
|
|
229
|
+
"travel": "Travel & places",
|
|
230
|
+
"activities": "Activities",
|
|
231
|
+
"objects": "Objects",
|
|
232
|
+
"symbols": "Symbols",
|
|
233
|
+
"flags": "Flags"
|
|
234
|
+
}
|
|
215
235
|
}
|
|
216
236
|
},
|
|
217
237
|
"feedback": {
|
|
@@ -301,6 +321,11 @@
|
|
|
301
321
|
},
|
|
302
322
|
"draggablePanel": {
|
|
303
323
|
"moveLabel": "Move panel. Use the arrow keys to move it, or hold Shift for larger steps."
|
|
324
|
+
},
|
|
325
|
+
"pageCover": {
|
|
326
|
+
"position": "Cover position",
|
|
327
|
+
"hint": "Drag the image, or use the arrow keys, to reposition it",
|
|
328
|
+
"valueText": "{value}% from the top"
|
|
304
329
|
}
|
|
305
330
|
},
|
|
306
331
|
"dataDisplay": {
|
|
@@ -208,6 +208,26 @@
|
|
|
208
208
|
"openDialog": "一覧から選択",
|
|
209
209
|
"openSearch": "検索",
|
|
210
210
|
"suggestions": "候補"
|
|
211
|
+
},
|
|
212
|
+
"emojiPicker": {
|
|
213
|
+
"trigger": "アイコンを選ぶ",
|
|
214
|
+
"search": "絵文字を検索",
|
|
215
|
+
"recent": "最近使った絵文字",
|
|
216
|
+
"remove": "アイコンを削除",
|
|
217
|
+
"empty": "該当する絵文字がありません",
|
|
218
|
+
"loading": "絵文字を読み込み中…",
|
|
219
|
+
"grid": "絵文字",
|
|
220
|
+
"categories": {
|
|
221
|
+
"smileys": "顔と感情",
|
|
222
|
+
"people": "人と体",
|
|
223
|
+
"animals": "動物と自然",
|
|
224
|
+
"food": "食べ物と飲み物",
|
|
225
|
+
"travel": "旅行と場所",
|
|
226
|
+
"activities": "活動",
|
|
227
|
+
"objects": "もの",
|
|
228
|
+
"symbols": "記号",
|
|
229
|
+
"flags": "旗"
|
|
230
|
+
}
|
|
211
231
|
}
|
|
212
232
|
},
|
|
213
233
|
"feedback": {
|
|
@@ -294,6 +314,11 @@
|
|
|
294
314
|
},
|
|
295
315
|
"draggablePanel": {
|
|
296
316
|
"moveLabel": "パネルを移動。矢印キーで移動、Shift キーを押しながらで大きく移動します。"
|
|
317
|
+
},
|
|
318
|
+
"pageCover": {
|
|
319
|
+
"position": "カバー画像の位置",
|
|
320
|
+
"hint": "画像をドラッグするか矢印キーで位置を調整",
|
|
321
|
+
"valueText": "上から {value}%"
|
|
297
322
|
}
|
|
298
323
|
},
|
|
299
324
|
"dataDisplay": {
|
|
@@ -209,6 +209,26 @@
|
|
|
209
209
|
"openDialog": "Chọn từ danh sách",
|
|
210
210
|
"openSearch": "Tìm kiếm",
|
|
211
211
|
"suggestions": "Gợi ý"
|
|
212
|
+
},
|
|
213
|
+
"emojiPicker": {
|
|
214
|
+
"trigger": "Chọn biểu tượng",
|
|
215
|
+
"search": "Tìm emoji",
|
|
216
|
+
"recent": "Dùng gần đây",
|
|
217
|
+
"remove": "Gỡ biểu tượng",
|
|
218
|
+
"empty": "Không tìm thấy emoji",
|
|
219
|
+
"loading": "Đang tải emoji…",
|
|
220
|
+
"grid": "Emoji",
|
|
221
|
+
"categories": {
|
|
222
|
+
"smileys": "Mặt cười & cảm xúc",
|
|
223
|
+
"people": "Con người & cơ thể",
|
|
224
|
+
"animals": "Động vật & thiên nhiên",
|
|
225
|
+
"food": "Đồ ăn & thức uống",
|
|
226
|
+
"travel": "Du lịch & địa điểm",
|
|
227
|
+
"activities": "Hoạt động",
|
|
228
|
+
"objects": "Đồ vật",
|
|
229
|
+
"symbols": "Ký hiệu",
|
|
230
|
+
"flags": "Cờ"
|
|
231
|
+
}
|
|
212
232
|
}
|
|
213
233
|
},
|
|
214
234
|
"feedback": {
|
|
@@ -295,6 +315,11 @@
|
|
|
295
315
|
},
|
|
296
316
|
"draggablePanel": {
|
|
297
317
|
"moveLabel": "Di chuyển bảng. Dùng phím mũi tên để dời, giữ Shift để bước dài hơn."
|
|
318
|
+
},
|
|
319
|
+
"pageCover": {
|
|
320
|
+
"position": "Vị trí ảnh bìa",
|
|
321
|
+
"hint": "Kéo ảnh hoặc dùng phím mũi tên để chỉnh vị trí",
|
|
322
|
+
"valueText": "{value}% tính từ trên"
|
|
298
323
|
}
|
|
299
324
|
},
|
|
300
325
|
"dataDisplay": {
|
|
@@ -781,6 +781,12 @@ export type TreeProp = {
|
|
|
781
781
|
onExpandedValuesChange?: (values: string[]) => void;
|
|
782
782
|
/** Start with every branch open (antd `defaultExpandAll`). Seeded once, never re-applied. */
|
|
783
783
|
defaultExpandAll?: boolean;
|
|
784
|
+
/**
|
|
785
|
+
* Expand a parent by clicking its ROW, not only its switcher (antd `DirectoryTree expandAction`,
|
|
786
|
+
* gh#1162): `"click"` selects AND toggles, `"doubleClick"` toggles on a double click. Default
|
|
787
|
+
* `false` — the switcher alone expands. The keyboard keeps the APG map (→ / ← expand).
|
|
788
|
+
*/
|
|
789
|
+
expandAction?: false | "click" | "doubleClick";
|
|
784
790
|
/**
|
|
785
791
|
* Lazy children (antd `loadData`). Called when a branch with no `children` and
|
|
786
792
|
* `isLeaf !== true` is expanded, and never again once its promise RESOLVES; push the fetched
|
|
@@ -2360,3 +2360,29 @@ export type AttachmentsRefProp = {
|
|
|
2360
2360
|
multiple?: boolean;
|
|
2361
2361
|
}) => void;
|
|
2362
2362
|
};
|
|
2363
|
+
/**
|
|
2364
|
+
* @see EmojiPicker — a page icon / reaction picker (gh#1164): search by ja / en / vi keywords
|
|
2365
|
+
* (emojibase-data, loaded for the active locale on first open), categories, per-user recents, a
|
|
2366
|
+
* WAI-ARIA grid, and "remove icon". No skin tones.
|
|
2367
|
+
*/
|
|
2368
|
+
export type EmojiPickerProp = {
|
|
2369
|
+
/** The chosen emoji (a Unicode string), or null for none. Controlled with `onValueChange`. */
|
|
2370
|
+
value?: ValueProp<string | null>;
|
|
2371
|
+
defaultValue?: DefaultValueProp<string | null>;
|
|
2372
|
+
/** Called with the picked emoji, or null when "remove icon" is chosen. */
|
|
2373
|
+
onValueChange?: OnValueChangeProp<string | null>;
|
|
2374
|
+
open?: OpenProp;
|
|
2375
|
+
defaultOpen?: DefaultOpenProp;
|
|
2376
|
+
onOpenChange?: OnOpenChangeProp;
|
|
2377
|
+
/** Offer "remove icon" while a value is set. Default true. */
|
|
2378
|
+
removable?: boolean;
|
|
2379
|
+
/** localStorage key for the per-user recents. Default `godxjp-ui:emoji-recents`. */
|
|
2380
|
+
recentsKey?: string;
|
|
2381
|
+
size?: SizeProp;
|
|
2382
|
+
disabled?: DisabledProp;
|
|
2383
|
+
/** Replace the default trigger button (it must accept a ref and onClick). */
|
|
2384
|
+
trigger?: React.ReactNode;
|
|
2385
|
+
"aria-label"?: string;
|
|
2386
|
+
id?: IdProp;
|
|
2387
|
+
className?: ClassNameProp;
|
|
2388
|
+
};
|
|
@@ -21,7 +21,7 @@ export type PageContainerMeasureProp = "default" | "narrow" | "medium";
|
|
|
21
21
|
* What the page's top row IS — the question that decides its type step, not how big you want it.
|
|
22
22
|
* `document` (default) — the row is the page's TITLE: a record, a form, a collection, a report.
|
|
23
23
|
*/
|
|
24
|
-
export type PageContainerHeaderScaleProp = "document" | "chrome";
|
|
24
|
+
export type PageContainerHeaderScaleProp = "document" | "chrome" | "display";
|
|
25
25
|
/**
|
|
26
26
|
* @see PageContainer — the header's trailing slot, one node or two named sub-slots.
|
|
27
27
|
*
|
|
@@ -99,9 +99,22 @@ export type PageContainerProp = {
|
|
|
99
99
|
/**
|
|
100
100
|
* Whether the page's top row is a DOCUMENT TITLE or the surface's own CHROME. Pass `chrome` when
|
|
101
101
|
* the row names the thing the user is already inside rather than announcing a document: a chat
|
|
102
|
-
* channel, a mail thread, an IDE tab.
|
|
102
|
+
* channel, a mail thread, an IDE tab. Pass `display` for an ARTICLE whose title is the page's
|
|
103
|
+
* headline (a Notion / note.com page): a larger, token-owned step that scales from phone to
|
|
104
|
+
* desktop, a CJK-friendly line height, and balanced wrapping (gh#1160).
|
|
103
105
|
*/
|
|
104
106
|
headerScale?: PageContainerHeaderScaleProp;
|
|
107
|
+
/**
|
|
108
|
+
* The page's icon — an emoji or a glyph — drawn large above the title, overlapping a banner
|
|
109
|
+
* `cover`'s bottom edge (gh#1160). Decorative by default reading: give it `aria-hidden` unless
|
|
110
|
+
* it is itself a control (a "change icon" button).
|
|
111
|
+
*/
|
|
112
|
+
icon?: React.ReactNode;
|
|
113
|
+
/**
|
|
114
|
+
* A `PageCover`. The banner variant spans the page edge to edge above the header; the
|
|
115
|
+
* `eyecatch` variant sits inside the header's reading column, above the title (gh#1160).
|
|
116
|
+
*/
|
|
117
|
+
cover?: React.ReactNode;
|
|
105
118
|
/**
|
|
106
119
|
* Bounded page measure shared by the header and the body. `narrow` (624px surface) / `medium`
|
|
107
120
|
* (720px surface) cap BOTH bands to one token-owned measure (`--page-measure-{narrow,medium}`),
|
|
@@ -970,6 +983,40 @@ export type ErrorSurfaceMaintenanceProp = {
|
|
|
970
983
|
* All product COPY stays consumer-owned (`title` / `description` / `action` come from the app's own
|
|
971
984
|
* `t()`); the surface owns only its own metadata labels, which it localizes itself.
|
|
972
985
|
*/
|
|
986
|
+
/** @see PageCover — banner across the page top, or an article's eyecatch in the reading column. */
|
|
987
|
+
export type PageCoverVariantProp = "banner" | "eyecatch";
|
|
988
|
+
/** @see PageCover — the banner's token-owned height step (phone → desktop). */
|
|
989
|
+
export type PageCoverHeightProp = "md" | "lg";
|
|
990
|
+
/**
|
|
991
|
+
* @see PageCover — a page's cover image (gh#1160): Notion's banner above the title, or note.com's
|
|
992
|
+
* eyecatch in the reading column. The focal point is a vertical position, and the cover can be
|
|
993
|
+
* repositioned by drag OR keyboard: while `repositioning`, the image is a WAI-ARIA slider.
|
|
994
|
+
*/
|
|
995
|
+
export type PageCoverProp = {
|
|
996
|
+
/** The image URL. */
|
|
997
|
+
src: string;
|
|
998
|
+
/** Alternative text; `""` for a purely decorative cover. */
|
|
999
|
+
alt: string;
|
|
1000
|
+
/** Vertical focal point, 0 (top) – 100 (bottom): the image's `object-position` y. Default 50. */
|
|
1001
|
+
positionY?: number;
|
|
1002
|
+
/** Called while repositioning with the new focal point (drag, arrows, Home / End). */
|
|
1003
|
+
onPositionChange?: (positionY: number) => void;
|
|
1004
|
+
/** Reposition mode: the image becomes a vertical slider (drag + keyboard). Controlled. */
|
|
1005
|
+
repositioning?: boolean;
|
|
1006
|
+
/** Reposition mode ended from inside the cover (Enter / Escape). */
|
|
1007
|
+
onRepositioningChange?: (repositioning: boolean) => void;
|
|
1008
|
+
/** `banner` (default) spans the page above the header; `eyecatch` sits in the reading column. */
|
|
1009
|
+
variant?: PageCoverVariantProp;
|
|
1010
|
+
/** Banner height step, token-owned for phone and desktop. Default `md`. */
|
|
1011
|
+
height?: PageCoverHeightProp;
|
|
1012
|
+
/**
|
|
1013
|
+
* Cover actions (change / reposition / remove). Over the cover's bottom edge on a wide screen,
|
|
1014
|
+
* BELOW the image on a narrow one, so they never sit on the focal area.
|
|
1015
|
+
*/
|
|
1016
|
+
actions?: React.ReactNode;
|
|
1017
|
+
id?: IdProp;
|
|
1018
|
+
className?: ClassNameProp;
|
|
1019
|
+
};
|
|
973
1020
|
export type ErrorSurfaceProp = {
|
|
974
1021
|
/** Where the surface lives — `application` = AppShell body (400/403/404), `system` = own page (500/503). */
|
|
975
1022
|
mode: ErrorSurfaceModeProp;
|
package/dist/props/registry.d.ts
CHANGED
|
@@ -784,7 +784,15 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
784
784
|
}, {
|
|
785
785
|
readonly field: "headerScale";
|
|
786
786
|
readonly local: true;
|
|
787
|
-
readonly reason: "What the page's top row IS — a document title
|
|
787
|
+
readonly reason: "What the page's top row IS — a document title, the surface's own chrome, or an article headline (document | chrome | display; display = gh#1160) — which selects the title's type step via --page-title-font-size-chrome AND opens the page flush with the frame via --page-pad-block-start-chrome (chrome sits on the edge; a document title gets the page's top margin). A fourth orthogonal axis: PageContainerVariantProp owns chrome WEIGHT (ghost drops the divider and header pad), headerLayout owns the header ARRANGEMENT, measure owns the inline cap; none of them can say that the h1 is a channel name rather than a headline.";
|
|
788
|
+
}, {
|
|
789
|
+
readonly field: "icon";
|
|
790
|
+
readonly local: true;
|
|
791
|
+
readonly reason: "The PAGE's icon (an emoji or glyph) drawn large above the h1 and over a banner cover's edge — a page identity slot, not the small IconProp glyph a control carries (gh#1160).";
|
|
792
|
+
}, {
|
|
793
|
+
readonly field: "cover";
|
|
794
|
+
readonly local: true;
|
|
795
|
+
readonly reason: "Slot for a PageCover; the container reads its variant to place it full-bleed above the header (banner) or in the reading column (eyecatch) (gh#1160).";
|
|
788
796
|
}, {
|
|
789
797
|
readonly field: "measure";
|
|
790
798
|
readonly local: true;
|
|
@@ -1187,6 +1195,57 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
1187
1195
|
readonly reason: "Server-sent 0–100 completion of the maintenance window; deriving it from the client clock would break hydration.";
|
|
1188
1196
|
}];
|
|
1189
1197
|
};
|
|
1198
|
+
readonly PageCoverVariantProp: {
|
|
1199
|
+
readonly group: "layout";
|
|
1200
|
+
readonly file: "components/layout.prop.ts";
|
|
1201
|
+
readonly vocabulary: readonly [];
|
|
1202
|
+
};
|
|
1203
|
+
readonly PageCoverHeightProp: {
|
|
1204
|
+
readonly group: "layout";
|
|
1205
|
+
readonly file: "components/layout.prop.ts";
|
|
1206
|
+
readonly vocabulary: readonly [];
|
|
1207
|
+
};
|
|
1208
|
+
readonly PageCoverProp: {
|
|
1209
|
+
readonly group: "layout";
|
|
1210
|
+
readonly file: "components/layout.prop.ts";
|
|
1211
|
+
readonly vocabulary: readonly ["IdProp", "ClassNameProp", {
|
|
1212
|
+
readonly field: "src";
|
|
1213
|
+
readonly local: true;
|
|
1214
|
+
readonly reason: "The native img src attribute.";
|
|
1215
|
+
}, {
|
|
1216
|
+
readonly field: "alt";
|
|
1217
|
+
readonly local: true;
|
|
1218
|
+
readonly reason: "The native img alt attribute.";
|
|
1219
|
+
}, {
|
|
1220
|
+
readonly field: "positionY";
|
|
1221
|
+
readonly local: true;
|
|
1222
|
+
readonly reason: "The cover's vertical FOCAL POINT, 0–100, applied as object-position y — a geometric value of this image, not a ValueProp a form submits (gh#1160).";
|
|
1223
|
+
}, {
|
|
1224
|
+
readonly field: "onPositionChange";
|
|
1225
|
+
readonly local: true;
|
|
1226
|
+
readonly reason: "Paired change handler of positionY, named after the value it reports (drag / slider keys).";
|
|
1227
|
+
}, {
|
|
1228
|
+
readonly field: "repositioning";
|
|
1229
|
+
readonly local: true;
|
|
1230
|
+
readonly reason: "Controlled MODE flag: while true the image is a vertical WAI-ARIA slider. Not OpenProp — nothing opens; the cover becomes a control.";
|
|
1231
|
+
}, {
|
|
1232
|
+
readonly field: "onRepositioningChange";
|
|
1233
|
+
readonly local: true;
|
|
1234
|
+
readonly reason: "Paired change handler of repositioning, called when Enter / Escape ends the mode from inside.";
|
|
1235
|
+
}, {
|
|
1236
|
+
readonly field: "variant";
|
|
1237
|
+
readonly local: true;
|
|
1238
|
+
readonly reason: "PageCoverVariantProp (banner | eyecatch) — WHERE the cover sits and its shape, not a tone or a visual style variant.";
|
|
1239
|
+
}, {
|
|
1240
|
+
readonly field: "height";
|
|
1241
|
+
readonly local: true;
|
|
1242
|
+
readonly reason: "PageCoverHeightProp (md | lg) — the banner's token-owned viewport-scaled height step; SizeProp means control density, not this.";
|
|
1243
|
+
}, {
|
|
1244
|
+
readonly field: "actions";
|
|
1245
|
+
readonly local: true;
|
|
1246
|
+
readonly reason: "Slot for the host's cover controls (change / reposition / remove), laid out off the focal area — a ReactNode slot, not the ActionsProp item list.";
|
|
1247
|
+
}];
|
|
1248
|
+
};
|
|
1190
1249
|
readonly ErrorSurfaceProp: {
|
|
1191
1250
|
readonly group: "layout";
|
|
1192
1251
|
readonly file: "components/layout.prop.ts";
|
|
@@ -3253,10 +3312,35 @@ export declare const COMPONENT_PROP_REGISTRY: {
|
|
|
3253
3312
|
readonly reason: "antd `onDrop` info: true when it lands as a sibling, false inside.";
|
|
3254
3313
|
}];
|
|
3255
3314
|
};
|
|
3315
|
+
readonly EmojiPickerProp: {
|
|
3316
|
+
readonly group: "data-entry";
|
|
3317
|
+
readonly file: "components/data-entry.prop.ts";
|
|
3318
|
+
readonly vocabulary: readonly ["ValueProp", "DefaultValueProp", "OnValueChangeProp", "OpenProp", "DefaultOpenProp", "OnOpenChangeProp", "SizeProp", "DisabledProp", "IdProp", "ClassNameProp", {
|
|
3319
|
+
readonly field: "removable";
|
|
3320
|
+
readonly local: true;
|
|
3321
|
+
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
|
+
}, {
|
|
3323
|
+
readonly field: "recentsKey";
|
|
3324
|
+
readonly local: true;
|
|
3325
|
+
readonly reason: "localStorage key the per-user recents are kept under, so two pickers (page icons, reactions) can keep separate lists.";
|
|
3326
|
+
}, {
|
|
3327
|
+
readonly field: "trigger";
|
|
3328
|
+
readonly local: true;
|
|
3329
|
+
readonly reason: "Replaces the default trigger button (a page icon drawn large, a reaction chip) — a ReactNode slot, not a TriggerProp mode.";
|
|
3330
|
+
}, {
|
|
3331
|
+
readonly field: "aria-label";
|
|
3332
|
+
readonly local: true;
|
|
3333
|
+
readonly reason: "Accessible name of the trigger and the popover.";
|
|
3334
|
+
}];
|
|
3335
|
+
};
|
|
3256
3336
|
readonly TreeProp: {
|
|
3257
3337
|
readonly group: "data-display";
|
|
3258
3338
|
readonly file: "components/data-display.prop.ts";
|
|
3259
3339
|
readonly vocabulary: readonly ["ValueProp", "DefaultValueProp", "OnValueChangeProp", "DisabledProp", "SizeProp", "ClassNameProp", "IdProp", {
|
|
3340
|
+
readonly field: "expandAction";
|
|
3341
|
+
readonly local: true;
|
|
3342
|
+
readonly reason: "antd DirectoryTree's `expandAction` (false | click | doubleClick): whether a ROW click / double click also toggles a parent's expansion, beside the switcher (gh#1162). An interaction mode of the tree, not an OpenProp.";
|
|
3343
|
+
}, {
|
|
3260
3344
|
readonly field: "divided";
|
|
3261
3345
|
readonly local: true;
|
|
3262
3346
|
readonly reason: "Rules between the rows — a hairline on every node's block-start but the outline's first, full row width at every depth (gh#732). Default false, because chrome defaults quiet here (#44). Not antd's spelling: antd's Tree has no such capability, and `bordered` already means a grid's frame plus column rules on Table / Calendar / RangeTimeline; see docs/DESIGN-AUTHORITY.md.";
|