@stcn52/pro 0.0.0-stage → 0.2.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/CHANGELOG.md +621 -0
- package/CONVENTIONS.md +152 -0
- package/LICENSE +21 -0
- package/README.md +226 -2
- package/RELEASING.md +51 -0
- package/THIRD_PARTY_NOTICES.md +52 -0
- package/dist/index.cjs +23272 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5068 -0
- package/dist/index.d.ts +5068 -0
- package/dist/index.js +23060 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +10485 -0
- package/dist/tokens.css +322 -0
- package/docs/antd-alignment-plan.md +983 -0
- package/docs/api.md +3669 -0
- package/docs/components.md +1706 -0
- package/docs/measurements.md +152 -0
- package/docs/qa/README.md +50 -0
- package/docs/qa/browser-checks.json +394 -0
- package/docs/qa/d-chrome-checklist-dark.png +0 -0
- package/docs/qa/d-chrome-checks.json +234 -0
- package/docs/qa/d-chrome-detail-dark.png +0 -0
- package/docs/qa/d-chrome-filters-dark.png +0 -0
- package/docs/qa/d-chrome-shell-dark.png +0 -0
- package/docs/qa/d-detail-checks.json +222 -0
- package/docs/qa/d-detail-comments-failed-dark.png +0 -0
- package/docs/qa/d-detail-preview-dark.png +0 -0
- package/docs/qa/d-entity-checks.json +294 -0
- package/docs/qa/d-entity-failed-dark.png +0 -0
- package/docs/qa/d-workbench-canvas-dark.png +0 -0
- package/docs/qa/d-workbench-checks.json +338 -0
- package/docs/qa/d-workbench-edit-failed-dark.png +0 -0
- package/docs/qa/d-workbench-roadmap-dark.png +0 -0
- package/docs/qa/d-workbench-wizard-failed-dark.png +0 -0
- package/docs/qa/date-range-mobile-dark.jpg +0 -0
- package/docs/qa/p0-cascader-checks.json +228 -0
- package/docs/qa/p0-cascader-multiple-dark.png +0 -0
- package/docs/qa/p0-config-checks.json +430 -0
- package/docs/qa/p0-config-nested-dark.png +0 -0
- package/docs/qa/p0-date-checks.json +595 -0
- package/docs/qa/p0-date-time-dark.png +0 -0
- package/docs/qa/p0-form-lifecycle-checks.json +30 -0
- package/docs/qa/p0-form-lifecycle.png +0 -0
- package/docs/qa/p0-select-checks.json +378 -0
- package/docs/qa/p0-select-virtual-dark.png +0 -0
- package/docs/qa/p0-table-checks.json +290 -0
- package/docs/qa/p0-table-virtual-dark.png +0 -0
- package/docs/qa/p0-transfer-checks.json +322 -0
- package/docs/qa/p0-transfer-pagination-dark.png +0 -0
- package/docs/qa/p0-tree-checks.json +242 -0
- package/docs/qa/p0-tree-range-dark.png +0 -0
- package/docs/qa/p1-app-browser-checks.json +34 -0
- package/docs/qa/p1-app-feedback-dark.png +0 -0
- package/docs/qa/p1-avatar-checks.json +370 -0
- package/docs/qa/p1-avatar-dark.png +0 -0
- package/docs/qa/p1-browser-checks.json +218 -0
- package/docs/qa/p1-card-checks.json +262 -0
- package/docs/qa/p1-card-dark.png +0 -0
- package/docs/qa/p1-content-navigation-browser-checks.json +114 -0
- package/docs/qa/p1-controls-browser-checks.json +86 -0
- package/docs/qa/p1-controls-desktop-dark.png +0 -0
- package/docs/qa/p1-dialog-nested-dark.png +0 -0
- package/docs/qa/p1-display-browser-checks.json +114 -0
- package/docs/qa/p1-display-desktop-dark.png +0 -0
- package/docs/qa/p1-divider-dark.png +0 -0
- package/docs/qa/p1-drawer-browser-checks.json +302 -0
- package/docs/qa/p1-drawer-rtl-dark.png +0 -0
- package/docs/qa/p1-general-input-browser-checks.json +114 -0
- package/docs/qa/p1-general-input-desktop-dark.png +0 -0
- package/docs/qa/p1-image-browser-checks.json +38 -0
- package/docs/qa/p1-image-preview-dark.png +0 -0
- package/docs/qa/p1-inline-browser-checks.json +58 -0
- package/docs/qa/p1-inline-desktop-dark.png +0 -0
- package/docs/qa/p1-layout-browser-checks.json +114 -0
- package/docs/qa/p1-layout-desktop-dark.png +0 -0
- package/docs/qa/p1-menu-checks.json +357 -0
- package/docs/qa/p1-menu-long-dark.png +0 -0
- package/docs/qa/p1-nav-dark.png +0 -0
- package/docs/qa/p1-nav-sidebar-checks.json +218 -0
- package/docs/qa/p1-navigation-browser-checks.json +114 -0
- package/docs/qa/p1-navigation-mobile-dark.png +0 -0
- package/docs/qa/p1-pagination-checks.json +309 -0
- package/docs/qa/p1-pagination-dark.png +0 -0
- package/docs/qa/p1-pagination-mobile-dark.png +0 -0
- package/docs/qa/p1-popup-actions-browser-checks.json +58 -0
- package/docs/qa/p1-popup-actions-desktop-dark.png +0 -0
- package/docs/qa/p1-progress-browser-checks.json +30 -0
- package/docs/qa/p1-progress-desktop-dark.png +0 -0
- package/docs/qa/p1-rate-half-desktop-dark.png +0 -0
- package/docs/qa/p1-segment-checks.json +426 -0
- package/docs/qa/p1-segment-dark.png +0 -0
- package/docs/qa/p1-sidebar-dark.png +0 -0
- package/docs/qa/p1-slider-rate-browser-checks.json +114 -0
- package/docs/qa/p1-states-browser-checks.json +34 -0
- package/docs/qa/p1-states-checks.json +342 -0
- package/docs/qa/p1-states-dark.png +0 -0
- package/docs/qa/p1-states-mobile-dark.png +0 -0
- package/docs/qa/p1-tabs-editable-dark.png +0 -0
- package/docs/qa/p1-tag-dark.png +0 -0
- package/docs/qa/p1-tag-divider-checks.json +330 -0
- package/docs/qa/p1-upload-browser-checks.json +30 -0
- package/docs/qa/p1-upload-list-dark.png +0 -0
- package/docs/qa/p2-ai-panel-checks.json +401 -0
- package/docs/qa/p2-ai-panel-dark.png +0 -0
- package/docs/qa/p2-alert-dark.png +0 -0
- package/docs/qa/p2-app-final-checks.json +309 -0
- package/docs/qa/p2-app-final-dark.png +0 -0
- package/docs/qa/p2-badge-alert-checks.json +466 -0
- package/docs/qa/p2-beam-motion-checks.json +58 -0
- package/docs/qa/p2-calendar-dark.png +0 -0
- package/docs/qa/p2-calendar-timeline-checks.json +254 -0
- package/docs/qa/p2-charts-checks.json +242 -0
- package/docs/qa/p2-charts-dark.png +0 -0
- package/docs/qa/p2-color-gradient-dark.png +0 -0
- package/docs/qa/p2-content-navigation-checks.json +794 -0
- package/docs/qa/p2-dialog-popover-dark.png +0 -0
- package/docs/qa/p2-display-checks.json +128 -0
- package/docs/qa/p2-display-dark.png +0 -0
- package/docs/qa/p2-drawer-final-dark.png +0 -0
- package/docs/qa/p2-extras-checks.json +482 -0
- package/docs/qa/p2-general-inputs-checks.json +154 -0
- package/docs/qa/p2-general-inputs-dark.png +0 -0
- package/docs/qa/p2-icon-checks.json +466 -0
- package/docs/qa/p2-icon-dark.png +0 -0
- package/docs/qa/p2-image-dark.png +0 -0
- package/docs/qa/p2-inline-editors-checks.json +199 -0
- package/docs/qa/p2-input-button-checks.json +778 -0
- package/docs/qa/p2-input-dark.png +0 -0
- package/docs/qa/p2-layout-final-checks.json +136 -0
- package/docs/qa/p2-layout-final-dark.png +0 -0
- package/docs/qa/p2-lists-checks.json +290 -0
- package/docs/qa/p2-masonry-dark.png +0 -0
- package/docs/qa/p2-media-checks.json +212 -0
- package/docs/qa/p2-mentions-color-checks.json +362 -0
- package/docs/qa/p2-overlay-checks.json +370 -0
- package/docs/qa/p2-people-picker-dark.png +0 -0
- package/docs/qa/p2-popconfirm-final-dark.png +0 -0
- package/docs/qa/p2-popup-final-checks.json +223 -0
- package/docs/qa/p2-qr-browser-decode.json +30 -0
- package/docs/qa/p2-quick-select-dark.png +0 -0
- package/docs/qa/p2-quick-text-dark.png +0 -0
- package/docs/qa/p2-rate-dark.png +0 -0
- package/docs/qa/p2-scroll-navigation-checks.json +198 -0
- package/docs/qa/p2-scroll-navigation-dark.png +0 -0
- package/docs/qa/p2-selection-bar-checks.json +302 -0
- package/docs/qa/p2-selection-bar-dark.png +0 -0
- package/docs/qa/p2-slider-rate-checks.json +262 -0
- package/docs/qa/p2-switch-dark.png +0 -0
- package/docs/qa/p2-tabs-dark.png +0 -0
- package/docs/qa/p2-timeline-dark.png +0 -0
- package/docs/qa/p2-toast-dark.png +0 -0
- package/docs/qa/p2-toggle-checks.json +834 -0
- package/docs/qa/p2-tour-dark.png +0 -0
- package/docs/qa/p2-upload-dark.png +0 -0
- package/docs/qa/table-details.md +26 -0
- package/docs/qa/table-mobile-dark.jpg +0 -0
- package/docs/qa/transfer-mobile-light.jpg +0 -0
- package/docs/qa/tree-browser-checks.json +226 -0
- package/docs/qa/tree-details.md +25 -0
- package/docs/qa/tree-directory-mobile-dark.jpg +0 -0
- package/docs/tokens.md +255 -0
- package/package.json +95 -4
|
@@ -0,0 +1,1706 @@
|
|
|
1
|
+
# Component reference
|
|
2
|
+
|
|
3
|
+
Every component below ships from `@stcn52/pro`. Props are the ones exported from
|
|
4
|
+
`src/`, states are the ones actually styled, and the keyboard column is what the
|
|
5
|
+
implementation handles — not an intention.
|
|
6
|
+
|
|
7
|
+
Conventions used throughout:
|
|
8
|
+
|
|
9
|
+
- **Controlled by default where it matters.** Anything with a selection
|
|
10
|
+
(`Nav`, `Tree`, `Segment`, `Select`, `DataTable`, `DetailSheet`) takes a value
|
|
11
|
+
and an `onChange`; the host owns the state and the URL.
|
|
12
|
+
- **Refs are forwarded** on every form control (`Button`, `Input`, `Select`,
|
|
13
|
+
`Checkbox`, `Switch`), so a page can `searchRef.current?.focus()` — that is how
|
|
14
|
+
`⌘K` works.
|
|
15
|
+
- **One focus ring.** Defined once in `base.css` as `:focus-visible` with
|
|
16
|
+
`outline: 2px solid var(--accent)`; components never invent their own.
|
|
17
|
+
- **Tokens only.** No component hard-codes a colour, radius or duration.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Actions
|
|
22
|
+
|
|
23
|
+
### `Button`
|
|
24
|
+
|
|
25
|
+
`variant: 'primary' | 'default' | 'text' | 'danger'` · `size: 'sm' | 'md' | 'lg'` ·
|
|
26
|
+
`icon?` / `iconAfter?` (`IconName`) · `block?` · `loading?` · ref forwarded.
|
|
27
|
+
|
|
28
|
+
- `loading` renders an inline spinner **and** sets `disabled` + `aria-busy`, so
|
|
29
|
+
the label width never jumps.
|
|
30
|
+
- Icon-only (no children) adds `pro-btn--icon-only` for a square hit area.
|
|
31
|
+
- States: hover, pressed (0.5px sink), focus-visible, disabled, loading.
|
|
32
|
+
|
|
33
|
+
### `ActionButton`
|
|
34
|
+
|
|
35
|
+
`icon` (required) · `label` (required) · `size` · `active?` · `tone?: 'default' | 'accent'`.
|
|
36
|
+
|
|
37
|
+
The bare icon button used by the chrome, toolbars and rows. `label` becomes both
|
|
38
|
+
`aria-label` and `title`; `active` sets `aria-pressed` and the accent tint. If you
|
|
39
|
+
pass `children` it becomes a pill-shaped button with an icon.
|
|
40
|
+
|
|
41
|
+
### `SplitButton`
|
|
42
|
+
|
|
43
|
+
`label` · `onPrimary` · `menuLabel` · `menuItems?` · `menuOpen?` / `onToggleMenu?`.
|
|
44
|
+
|
|
45
|
+
The product's "New ▾" control. The caret owns its own `Popover` + `Menu`
|
|
46
|
+
anchored to itself, so a host only supplies the items; pass `menuOpen` +
|
|
47
|
+
`onToggleMenu` to control it instead.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 2. Forms
|
|
52
|
+
|
|
53
|
+
### `Input` / `Textarea` / `SearchInput`
|
|
54
|
+
|
|
55
|
+
`size?: 'md' | 'lg'` · `invalid?` · ref forwarded. `invalid` sets
|
|
56
|
+
`aria-invalid` and the red border; `SearchInput` adds a leading magnifier and a
|
|
57
|
+
`suffix` slot (used for the `⌘K` hint), and forwards a ref.
|
|
58
|
+
|
|
59
|
+
### `Field`
|
|
60
|
+
|
|
61
|
+
`label?` · `required?` · `hint?` · `error?` · `htmlFor?`.
|
|
62
|
+
|
|
63
|
+
Wraps any control: generates an `id` with `useId` when none is given, wires
|
|
64
|
+
`label[for]`, renders the required asterisk, and shows `error` (with an icon,
|
|
65
|
+
`role="alert"`) **instead of** the hint. The rule the pages follow: pass an error
|
|
66
|
+
only after the first blur or a submit attempt, and clear it the moment the value
|
|
67
|
+
becomes valid.
|
|
68
|
+
|
|
69
|
+
### `Select` / `MultiSelect`
|
|
70
|
+
|
|
71
|
+
`value: string | null` · `options: { value, label, icon?, color?, disabled? }[]` ·
|
|
72
|
+
`onChange` · `placeholder?` · `size?` · `invalid?` · `disabled?`.
|
|
73
|
+
|
|
74
|
+
- Trigger shows `pro-select-trigger--placeholder` when nothing is chosen; the
|
|
75
|
+
caret rotates with `aria-expanded`.
|
|
76
|
+
- Options can be rich (a `StatusTag`, a colour dot), which is how the status
|
|
77
|
+
pickers render.
|
|
78
|
+
- Opening from the keyboard puts focus on the first item; choosing one closes
|
|
79
|
+
the layer by requesting `onOpenChange(false)`.
|
|
80
|
+
- `MultiSelect` takes `values: string[]` and an optional `label` before the count badge.
|
|
81
|
+
- `searchable` defaults to false for Select and true for MultiSelect. `searchValue`
|
|
82
|
+
controls the query; `onSearch` reports typing and a nonempty query reset on close.
|
|
83
|
+
`searchPlaceholder` customizes the search field. Arrows enter enabled choices;
|
|
84
|
+
MultiSelect also supports arrow navigation between checkboxes.
|
|
85
|
+
- Default filtering reads text from rich label children. Supply `searchText` for
|
|
86
|
+
opaque custom labels, or `filterOption(query, option)` for a custom predicate.
|
|
87
|
+
`filterOption={false}` leaves filtering to a remote host. Optional `filterSort`
|
|
88
|
+
sorts within each group without changing the supplied options.
|
|
89
|
+
- A controlled query stays host-owned; update `searchValue` in response to
|
|
90
|
+
`onSearch`. Search is ignored when `searchable={false}`.
|
|
91
|
+
|
|
92
|
+
- `virtual` opts into fixed-height windowing. `listHeight` defaults to 256 and
|
|
93
|
+
`itemHeight` to 36. Match `itemHeight` to your custom row geometry. Arrows,
|
|
94
|
+
Home/End and typeahead navigate the complete result set; a focused row remains
|
|
95
|
+
mounted during wheel scrolling. Use `virtual={false}` to render all options.
|
|
96
|
+
- `MultiSelect` supports `mode="tags"`: Enter or a checkbox commits a trimmed
|
|
97
|
+
custom value. Created tags remain selectable and clearable through `values`.
|
|
98
|
+
`tokenSeparators={[',', ';']}` commits complete tokens from typing/paste and
|
|
99
|
+
leaves the trailing fragment in the search field. In multiple mode, tokens
|
|
100
|
+
resolve existing values/label text only. IME text is committed after composition.
|
|
101
|
+
- `maxCount` limits distinct values in MultiSelect, including values absent from
|
|
102
|
+
the current options. At the limit, new choices are disabled, selected choices
|
|
103
|
+
remain removable, and excess batch tokens are ignored. Disabled selections
|
|
104
|
+
remain locked. Tags mode always displays the search field.
|
|
105
|
+
|
|
106
|
+
- Both controls forward a native button ref and attributes, accept controlled
|
|
107
|
+
`open` / `onOpenChange` or `defaultOpen`, and keep search intact when a host
|
|
108
|
+
refuses to close. Queries reset only after the popup actually closes.
|
|
109
|
+
- Groups use `{ key?, label, options, disabled? }`; their disabled flag applies
|
|
110
|
+
to every child. Values remain unique strings. Group headers count toward
|
|
111
|
+
virtual geometry but not option positions or keyboard selection.
|
|
112
|
+
- `labelInValue` changes single values to `{ value, label? } | null` and multiple
|
|
113
|
+
values to arrays of those objects. Selected labels survive remote option
|
|
114
|
+
replacement; unknown values display their supplied label or literal value.
|
|
115
|
+
`defaultValue` / `defaultValues` enable uncontrolled selection.
|
|
116
|
+
- Single `allowClear` adds a separate accessible clear button and emits `null`;
|
|
117
|
+
its callback therefore accepts `string | null`. Without it, the existing
|
|
118
|
+
string-only callback contract is unchanged. MultiSelect keeps its default
|
|
119
|
+
Clear footer and in multiple mode preserves values absent from current options; explicit
|
|
120
|
+
`allowClear={true}` also clears unknown values and `allowClear={false}` hides
|
|
121
|
+
it. Tags mode also clears created tags by default. Disabled selections stay locked.
|
|
122
|
+
- `optionRender(option, { index })` customizes presentation without replacing
|
|
123
|
+
native option keyboard/disabled semantics; keep interactive controls outside
|
|
124
|
+
the rendered option. `labelRender` customizes the single selected label;
|
|
125
|
+
MultiSelect `tagRender({ value, label, disabled, closable, onClose })` renders
|
|
126
|
+
accessible removable tags beside the trigger without nested buttons.
|
|
127
|
+
- `loading`, `error` and `notFoundContent` present host-owned async state;
|
|
128
|
+
requests, cancellation and option updates remain the host's responsibility.
|
|
129
|
+
Existing options remain usable while loading.
|
|
130
|
+
- Klun retains separate Select/MultiSelect, string keys, native button refs and
|
|
131
|
+
dialog/menu or checkbox semantics. AntD's numeric values, combobox imperative
|
|
132
|
+
handle, popup internals and full prop naming are not drop-in compatible.
|
|
133
|
+
|
|
134
|
+
### `Checkbox` / `Switch`
|
|
135
|
+
|
|
136
|
+
`Checkbox`: `label?` · `indeterminate?` · `compact?`. The indeterminate flag is
|
|
137
|
+
applied to the DOM node in an effect (React has no prop for it); the box is
|
|
138
|
+
`.pro-checkbox__box` so the focus ring can sit on the visual square.
|
|
139
|
+
`Switch`: `label` (required) · `size?: 'sm' | 'md'`; renders `role="switch"` and a
|
|
140
|
+
36×20 track (20×16 in `sm`).
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 3. Overlays
|
|
145
|
+
|
|
146
|
+
### `Dialog`
|
|
147
|
+
|
|
148
|
+
`open` · `onClose` · `title` · `tools?` · `footer?` · `size?: 'sm'|'md'|'lg'|'xl'` ·
|
|
149
|
+
`dismissable?` · `bodyClassName?`.
|
|
150
|
+
|
|
151
|
+
Portalled to `<body>`; locks body scroll; **traps Tab** (wraps at both ends);
|
|
152
|
+
`Esc` and scrim click only close when `dismissable` (false while a form is
|
|
153
|
+
dirty); focuses the first control on open and **restores focus to the opener** on
|
|
154
|
+
close.
|
|
155
|
+
|
|
156
|
+
### `Popover`
|
|
157
|
+
|
|
158
|
+
`anchor: HTMLElement | null` · `open` · `onClose` · `placement?` · `matchAnchorWidth?` ·
|
|
159
|
+
`dismissOnOutsideClick?` · `autoFocus?`.
|
|
160
|
+
|
|
161
|
+
A single floating layer: measured against the anchor, flipped when the preferred
|
|
162
|
+
side has no room, clamped to the viewport, re-measured on scroll/resize. Hides
|
|
163
|
+
itself with `visibility` until it has coordinates (so it never flashes at 0,0),
|
|
164
|
+
focuses its first control when opened from the keyboard, and returns focus to the
|
|
165
|
+
anchor when Escape closes it. Provides `usePopoverClose()` so nested menus can
|
|
166
|
+
dismiss it.
|
|
167
|
+
|
|
168
|
+
### `Menu`
|
|
169
|
+
|
|
170
|
+
`items: { id, label, icon?, hint?, danger?, disabled?, checked?, onSelect? }[]` ·
|
|
171
|
+
`searchable?` · `onSelect?`.
|
|
172
|
+
|
|
173
|
+
`role="menu"` with `menuitem` / `menuitemradio` (the latter when `checked` is
|
|
174
|
+
defined). Keyboard: **↑ ↓** move, **Home/End** jump, a printable character runs
|
|
175
|
+
typeahead, **Enter/Space** activate (native button), and choosing an item closes
|
|
176
|
+
the surrounding popover. `hint` is the right-aligned shortcut/count slot.
|
|
177
|
+
|
|
178
|
+
### `ContextMenu`
|
|
179
|
+
|
|
180
|
+
`items` · `onOpen?` · render-prop `children({ onContextMenu })` · `aria-label`.
|
|
181
|
+
|
|
182
|
+
Opens at the **pointer** (not the element rect), flipped and clamped to an 8px
|
|
183
|
+
viewport margin, portalled to `body` so `overflow: hidden` never clips it.
|
|
184
|
+
Dividers, disabled and danger items; `role="menu"` with roving focus, ↑↓,
|
|
185
|
+
Home/End and typeahead. The **Menu key** and **Shift+F10** open it on the focused
|
|
186
|
+
trigger; Escape closes and returns focus to the element that was right-clicked;
|
|
187
|
+
the native menu is suppressed only while a non-empty menu shows. `useContextMenu(items)`
|
|
188
|
+
is the imperative form — `openAt(x, y, context)` → `onSelect(context)`.
|
|
189
|
+
|
|
190
|
+
A press inside a **stacked** layer (`.pro-popover`, `.pro-portal`,
|
|
191
|
+
`[role=listbox]`, `[role=menu]`) does not dismiss the parent — without that guard
|
|
192
|
+
a `Select` inside a `Popover` could never be used with a mouse.
|
|
193
|
+
|
|
194
|
+
### `Tooltip`
|
|
195
|
+
|
|
196
|
+
`label` · `delay = 400` · `placement?: 'top' | 'bottom'`.
|
|
197
|
+
|
|
198
|
+
Shows on hover after the delay and **immediately on focus**; hides on blur,
|
|
199
|
+
Escape and any scroll. Portalled, `role="tooltip"`, non-interactive.
|
|
200
|
+
|
|
201
|
+
### `Menu` submenus and dividers
|
|
202
|
+
|
|
203
|
+
An item may carry `items` — it then renders a caret, `aria-haspopup="menu"` /
|
|
204
|
+
`aria-expanded`, and opens those entries beside its own row while the parent menu
|
|
205
|
+
stays open (choosing in the child closes the whole tree). `ArrowRight` opens it,
|
|
206
|
+
`ArrowLeft` closes it and returns the focus to the row. A `divider: true` item
|
|
207
|
+
renders the hairline between groups that `ContextMenuItem` already had.
|
|
208
|
+
|
|
209
|
+
### `Toast` — `ToastProvider` + `useToast()`
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
useToast().push(tone, message, options?) // returns the id, so the host can dismiss it early
|
|
213
|
+
useToast().dismiss(id)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
- **tone** `'info' | 'success' | 'warning' | 'error'` — the hairline and the glyph
|
|
217
|
+
carry it (`warning` is the product's amber; the sprite has no warning mark, so
|
|
218
|
+
it reuses the filled disc, and `icon` overrides the glyph outright).
|
|
219
|
+
- **options** `{ duration?, title?, action?, variant?, closeable?, icon? }`. The
|
|
220
|
+
third argument also still takes a bare number, which is the duration.
|
|
221
|
+
`duration: 0` keeps a toast until it is dismissed; `title` prints a bold line
|
|
222
|
+
with the message as the description under it; `action: { label, onClick }` adds
|
|
223
|
+
one inline command (Undo, View, Retry) and does **not** dismiss anything itself.
|
|
224
|
+
- **placement** on the provider: `top-left | top-center | top-right | bottom-left |
|
|
225
|
+
bottom-center | bottom-right`. The stack grows away from the pinned edge and the
|
|
226
|
+
toast animates in from it. The default, `top-center`, is where the product
|
|
227
|
+
raises its messages.
|
|
228
|
+
- **variant** `'surface'` (the white card, default) or `'filled'` (the message on
|
|
229
|
+
the tone's own colour; amber keeps dark ink because white on `--amber-500` is
|
|
230
|
+
illegible).
|
|
231
|
+
- **`max`** caps the stack; the oldest toast leaves first.
|
|
232
|
+
|
|
233
|
+
One live region (`aria-live="polite"`) exists **before** any content arrives;
|
|
234
|
+
each toast has a dismiss button (unless `closeable: false`) and **pausing on
|
|
235
|
+
hover** (the timer is cleared on `mouseenter`, restarted at 1.5s on
|
|
236
|
+
`mouseleave`). Outside a provider `useToast` degrades to `console.info`, so the
|
|
237
|
+
library never crashes a host.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 4. Display
|
|
242
|
+
|
|
243
|
+
| Component | Props that matter | Notes |
|
|
244
|
+
| ---------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
245
|
+
| `Icon` | `name`, `size`, `label?`, `style?` | 146 glyphs taken verbatim from the product's sprite. `size` sets `font-size` (the SVG is 1em). `label` → `role="img"`; otherwise `aria-hidden`. An unknown name warns and renders an empty box instead of throwing. |
|
|
246
|
+
| `Tag` | `variant: solid \| soft \| outline`, `color`, `icon`, `pill` | `StatusTag` maps 12 status words onto the measured palette; `LevelTag` renders the L0–L4 badge; `CountTag` the counted badge. |
|
|
247
|
+
| `Avatar` | `name`, `src`, `size: xs \| sm \| md \| lg`, `title` | Initials + a deterministic colour hashed from the name, so the same person is always the same colour. `AvatarStack` overlaps up to `max` and shows `+N`; `AvatarPlaceholder` is the dashed "not set" ring. |
|
|
248
|
+
| `Card` | `title?`, `extra?`, `flush?` | Section shell. `KeyValue` renders label/value rows; `Progress` takes 0–1 (clamped) with a tone and `aria-valuenow`; `Metric` is the label/value/delta/trend/icon tile. |
|
|
249
|
+
| `BarChart` / `Donut` / `Sparkline` | `data[]`, sizing props | No chart dependency: bars are flex heights, the donut is a `conic-gradient` with a punched hole and a legend, the sparkline is an SVG polyline. |
|
|
250
|
+
| `Crumbs` | `items: { id, label, onClick? }[]` | Marks the last item `aria-current="page"`. |
|
|
251
|
+
| `Divider` | `orientation` | Horizontal / vertical hairline on the divider token. |
|
|
252
|
+
| `States` | see below | `EmptyState` (`variant: empty \| error \| offline`, `title`, `hint`, `action`, `compact`) always renders **title + explanation + action**; `ErrorState` answers what/why/what-now and offers a retry; `EmptyArt` is the product's `</null>` illustration; `Skeleton`, `TableSkeleton`, `LoadingBlock`, `InlineSpinner`, `Banner`. |
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## 5. Navigation
|
|
257
|
+
|
|
258
|
+
| Component | Props | Behaviour |
|
|
259
|
+
| -------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
260
|
+
| `Nav` | `items`, `value`, `onChange`, `overflowItems?` | The product tab strip. The 2px ink bar is **measured from the live DOM** (and re-measured with a `ResizeObserver`) so variable-width and CJK labels stay centred. **← →** move the selection and focus; extra destinations fold into a "More" menu. |
|
|
261
|
+
| `Tree` / `TreeGroup` | `nodes`, `value`, `onSelect`, `defaultExpanded` | Accessible tree outline with optional controlled state, checks, lazy loading, virtual scrolling, and reorder callbacks. |
|
|
262
|
+
| `Sidebar` | `title`, `operations?`, `footer?`, `defaultWidth = 260`, `minWidth`, `maxWidth`, `collapsed?` | The category column, **resizable** by dragging the gutter (pointer capture) or with ← → on the handle, which exposes `role="separator"` + `aria-value*`. |
|
|
263
|
+
| `Segment` / `Chip` | `options`/`pressed`, `onChange` | Compact view switchers and filter pills; both use `aria-pressed`. |
|
|
264
|
+
| `Pagination` | `page`, `pageSize`, `total`, `onPageChange`, `onPageSizeChange?`, `pageSizeOptions?`, `left?`, `children?` | A windowed page list with an ellipsis, a page-size menu, and a "Go to" field (digits only, commits on Enter, clamped). Prev/next disable at the bounds. |
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## 6. `DataTable<T>` — the grid everything sits on
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
<DataTable
|
|
272
|
+
columns={columns} rows={rows} rowKey={rowKey}
|
|
273
|
+
status="ready" // loading | error | ready
|
|
274
|
+
sort={sort} onSortChange={setSort}
|
|
275
|
+
selectable selectedKeys onSelectedKeysChange
|
|
276
|
+
groupBy={(row) => row.status} // grouped <tbody> blocks, foldable
|
|
277
|
+
expandedGroups={open} onExpandedGroupsChange={setOpen} // or uncontrolled
|
|
278
|
+
showIndex rowActions onRowClick
|
|
279
|
+
emptyState={…} errorState={…} loadingRows={8} loadingColumns={[…]}
|
|
280
|
+
ariaLabel="All ideas"
|
|
281
|
+
/>
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
- **Five states are structural**: `loading` renders skeleton rows at the real row
|
|
285
|
+
height, `error`/`empty` render the supplied nodes in an overlay, `ready` with
|
|
286
|
+
rows renders the grid, and any column can carry edge content.
|
|
287
|
+
- Column definition: `{ id, header, width?, align?, sortable?, fixed?, render(row, index), className? }`.
|
|
288
|
+
`fixed: 'left' | 'right'` pins a column while the grid scrolls sideways; the
|
|
289
|
+
component measures the offsets from the numeric `width`s of the columns pinned
|
|
290
|
+
before it, and the outer column of each pinned run carries the edge shadow. A
|
|
291
|
+
non-numeric width still pins, it just cannot be offset. The checkbox and actions
|
|
292
|
+
columns join their edge **only when a data column is frozen** — an unfrozen grid
|
|
293
|
+
has no frozen edge, and pinning them anyway left a shadow and an opaque
|
|
294
|
+
background with nothing to mark.
|
|
295
|
+
- **The selection bar covers the header row.** While rows are selected the table
|
|
296
|
+
renders `SelectionBar` over the header (50px, full width, white), so the columns
|
|
297
|
+
never move: the box centres in the pick column, the count starts at the first
|
|
298
|
+
data column, and the covered header is `inert` — its select-all is not rendered
|
|
299
|
+
twice. Cancel clears the selection.
|
|
300
|
+
- A **selected row** wears `--surface-table-row-selected` — the head's neutral tone,
|
|
301
|
+
not the accent: the product's grid keeps the accent for the checkbox, so a
|
|
302
|
+
selected row still reads as a row. Everything else keeps `--surface-selected`.
|
|
303
|
+
- **Commands can live inside a cell**: `Column.actions` (`[{ id, icon, label,
|
|
304
|
+
onSelect }]`) renders boxes over the cell's right edge, revealed by the pointer
|
|
305
|
+
being on that cell, each with its tooltip. The row's own commands (`rowActions`)
|
|
306
|
+
are a different layer and sit at the row's **end** — the actions cell is
|
|
307
|
+
zero-width and must stay out of the positioning chain, or the overlay anchors to
|
|
308
|
+
the scrollport instead of the row.
|
|
309
|
+
- The pointer is **two levels**: the row under it takes the light wash (the pick
|
|
310
|
+
cell's gutter with it) and the cell under it the accent tint — the row reads as a
|
|
311
|
+
row, the cell as the target.
|
|
312
|
+
- The pick cell's **checkbox** appears when that cell is pointed at (or the row is
|
|
313
|
+
selected, holds the cursor, or a bulk selection is running) — never because the
|
|
314
|
+
pointer happens to be somewhere else in the row.
|
|
315
|
+
- The bar is exactly the header row's height (`--table-head-height`, shared with
|
|
316
|
+
`thead th`): it stands in for that row, so it must not be taller than it.
|
|
317
|
+
- The pick column is the grid's **gutter**: it wears the header's tone
|
|
318
|
+
(`--surface-table-head`) on every row, while a hovered or selected row keeps its
|
|
319
|
+
own colour there too.
|
|
320
|
+
- **The grid is drawn as a grid**: every column carries a hairline on its right, so
|
|
321
|
+
the columns are divided as well as the rows. The filler and the structural cells
|
|
322
|
+
(pick, row actions, header tools) draw no trailing edge — they are not columns.
|
|
323
|
+
- **The grid behaves like a spreadsheet.** `cursor` turns the keyboard cursor into
|
|
324
|
+
a **cell**: ← → walk the columns, ↑ ↓ the rows, Home/End jump to the ends of a
|
|
325
|
+
row, Enter opens the record, Space toggles its selection; focus follows the
|
|
326
|
+
cursor through a roving tabindex (one tab stop for the whole grid). Hovering
|
|
327
|
+
lights up the cell under the pointer, never the row.
|
|
328
|
+
- **Selection needs a writer.** The 44px pick column keeps its row number whenever
|
|
329
|
+
`selectable` is on, but the checkbox (and the select-all box) only renders when
|
|
330
|
+
`onSelectedKeysChange` is given — a control that cannot write is worse than no
|
|
331
|
+
control. A column that declares `sortable` is disabled with a title when the
|
|
332
|
+
host passed no `onSortChange`.
|
|
333
|
+
- The pick cell is the product's: the row number at rest, the checkbox on hover,
|
|
334
|
+
on a selected row, while a bulk selection is active, and on the **cursor row**
|
|
335
|
+
(the keyboard's hover — the number steps aside only when a checkbox exists).
|
|
336
|
+
- **The column menu** (`onColumnCommand`): each data column's header grows the
|
|
337
|
+
product's ⋯ (on hover or focus) with Sort by (a submenu: Ascending / Descending
|
|
338
|
+
/ Clear sort, the active one checked when the column is sorted), Move left,
|
|
339
|
+
Move right (disabled at the ends), Insert left, Insert right, Freeze or Unfreeze
|
|
340
|
+
and Remove this column. The library reports a `ColumnCommand` and changes
|
|
341
|
+
nothing: the host rewrites its `columns` and hands the array back, exactly like
|
|
342
|
+
`sort` / `onSortChange`.
|
|
343
|
+
- **The bulk bar is built here**, not in a page. `bulk` supplies the data and the
|
|
344
|
+
write for the product's commands; the component owns the bar, the submenus, the
|
|
345
|
+
round-robin spread, the confirmation and the dialog:
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
bulk={{
|
|
349
|
+
statuses: { options, apply(keys, value) },
|
|
350
|
+
baselines: { options, apply(keys, id) }, // "Move in baseline"
|
|
351
|
+
schedules: { options, apply(keys, id) }, // "Schedule"
|
|
352
|
+
distribute: { people, apply(key, person) }, // round-robin, one write per row
|
|
353
|
+
properties: { fields, initialValues?, title?, apply(keys, values) },
|
|
354
|
+
}}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
The order is the product's — Update status, Move in baseline, Schedule,
|
|
358
|
+
Distribute workitems, Edit properties — then anything `bulkActions(keys)` adds,
|
|
359
|
+
then the workbench's More (export / delete) and Cancel. Only the capabilities the
|
|
360
|
+
host supplied appear. Items sharing a `group` fold into one submenu (named after
|
|
361
|
+
the group, icon from `groupIcon`); an item with no group stays a button of its
|
|
362
|
+
own, keeping its label, icon and handler.
|
|
363
|
+
|
|
364
|
+
- **Frozen columns belong to the view.** `ListView.frozen` is the list of column
|
|
365
|
+
ids pinned to the left edge (the product's "frozen columns"), kept next to
|
|
366
|
+
`sort` and `group` because it is part of the view: `ListWorkbench` applies
|
|
367
|
+
`fixed: 'left'` to those columns and answers the column menu's Freeze /
|
|
368
|
+
Unfreeze itself, while Move / Insert / Remove rewrite the host's `columns` array
|
|
369
|
+
and leave through `onColumnCommand`. The demo freezes `id`, which is how the
|
|
370
|
+
product's grid opens: the checkbox column and the ID scroll together and the
|
|
371
|
+
rest goes under them. Host-defined `column.fixed` remains host-owned: Unfreeze
|
|
372
|
+
forwards to `onColumnCommand`, and the host updates `columns` to remove it.
|
|
373
|
+
Without that callback the workbench locally unpins the column for this session.
|
|
374
|
+
Selected export requires every selected record to be present in `rows`; missing
|
|
375
|
+
records produce an error rather than an incomplete file.
|
|
376
|
+
- **The keyboard cursor is the cell.** `cursor` makes the body one tab stop whose
|
|
377
|
+
unit is the **cell** — ← → walk the columns, ↑ ↓ the rows, Home / End jump to
|
|
378
|
+
the ends of the row, Enter opens the record, Space toggles its row's selection
|
|
379
|
+
when the host can write one, a pointer click parks the cursor on the cell it
|
|
380
|
+
landed in, and focus rides with the cursor through a roving tabindex. The
|
|
381
|
+
cursor is clamped when the rows shrink under it, and it follows the columns too,
|
|
382
|
+
so removing one cannot leave it pointing at a cell that is gone.
|
|
383
|
+
`ListWorkbench` turns it on, which is what the product's grid does; without it
|
|
384
|
+
every row that has an `onRowClick` is its own tab stop.
|
|
385
|
+
- **A widget inside a cell keeps its own keys.** The row's key listener sits on
|
|
386
|
+
the `<tr>`, so everything pressed inside a cell bubbles to it; the grid answers
|
|
387
|
+
only when the key is not the widget's (`src/components/table/keyboard.ts`). A
|
|
388
|
+
rename field takes its space and keeps its caret, an in-cell editor walks its
|
|
389
|
+
own text, and a `Column.actions` box answers Enter itself instead of opening the
|
|
390
|
+
record. The rule is a list of roles — `input`, `button`, `a[href]`,
|
|
391
|
+
`[contenteditable]`, the combobox / listbox / textbox roles — so a host's own
|
|
392
|
+
editor inside a cell gets the same treatment without having to remember
|
|
393
|
+
`stopPropagation`.
|
|
394
|
+
- **The frozen geometry is shared.** The pinned offsets, the edge shadow and the
|
|
395
|
+
skeleton rows all read the same measured offsets
|
|
396
|
+
(`src/components/table/geometry.ts`), so a loading grid does not jump sideways
|
|
397
|
+
when the data lands, and the row cursor stays put.
|
|
398
|
+
- **Density** `'default'` (45px rows, the measured grid) or `'compact'` (36px
|
|
399
|
+
rows and header, `--text-sm` cells). Compact also reserves the actions column —
|
|
400
|
+
a 36px row has no room for the floating command overlay — which is what
|
|
401
|
+
`.pro-table__cell--actions` right-aligns.
|
|
402
|
+
- **Groups fold** from their own header (`aria-expanded`), uncontrolled and open
|
|
403
|
+
by default, or controlled through `expandedGroups` / `onExpandedGroupsChange`.
|
|
404
|
+
String/number results are wrapped in a truncating span automatically, so a
|
|
405
|
+
value like `SLC-T1` never wraps and the row keeps its measured 52px pitch.
|
|
406
|
+
- Sorting is three-state (`asc → desc → none`) and sets `aria-sort`; the header
|
|
407
|
+
is a real `<button>`.
|
|
408
|
+
- Row checkboxes are a **hover affordance** (hidden until hover/selection/focus);
|
|
409
|
+
the select-all header checkbox supports `indeterminate`.
|
|
410
|
+
- Rows are keyboard-activatable when `onRowClick` is given (`Enter`/`Space`) and
|
|
411
|
+
announce via a live region.
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## 7. Ship surface
|
|
416
|
+
|
|
417
|
+
| Component | Props | Behaviour |
|
|
418
|
+
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
419
|
+
| `AppRail` | `items`, `footerItems?`, `activeId?` | The 60px product switcher; the active item gets the lighter band and `aria-current="page"`. |
|
|
420
|
+
| `AppHeader` / `ProductHeader` | `search`, `searchRef`, `actions`, `tabs`, `activeTab`, `onTabChange`, `overflowTabs`, `starred`, `onToggleStar`, `products?`, `onSelectProduct?`, `onCollapseSidebar?`, `sidebarCollapsed?` | Products level vs workbench level. `searchRef` is what `⌘K` focuses; `search.onSubmit` fires on Enter; the product name opens a switcher when `products` is given; the outdent control reports its pressed state. |
|
|
421
|
+
| `HeaderActions` | `onCreate?`, `onHelp?`, `onNotifications?`, `unread?`, `user` | The `+`, `?`, bell (with a dot badge) and avatar cluster; the avatar's click receives the event so the host can anchor a menu to it. |
|
|
422
|
+
| `BrandMark` | `size?` | The four-dot product mark, drawn inline so the brand colour stays under our control. |
|
|
423
|
+
| `ListHeader` | `title`, `titleIcon?`, `actions?` | The 48px strip above a grid. |
|
|
424
|
+
| `ListToolbar` | `search`, `count?`, `fields?`, `rules?`, `onRulesChange?`, `sortFields?`, `sort?`, `onSortChange?`, `groupFields?`, `group?`, `onGroupChange?`, `onToggleExpand?`, `expanded?`, `extraControls?` | Search, then Filter / Sort / Group / More, with the count pinned right and active filters rendered as removable chips. Opening the filter builder on a blank slate seeds one condition, as the product does. |
|
|
425
|
+
| `FilterPanel` / `FilterChip` | `fields`, `rules`, `onRulesChange` | Field / condition / value rows with add, clear-all and apply. |
|
|
426
|
+
| `DetailSheet` | `kind`, `code`, `title`, `tools?`, `properties?`, `tabs`, `activeTab`, `onTabChange`, `aside`, `composer?`, `onClose` | The entity panel that covers everything right of the rail: identity bar, title, property strip, tabs, main column, metadata rail. `DetailSection` is a collapsible rail group, `DetailField` a labelled row, `Feed` a comment/activity timeline, `FeedFilter` its chip bar, `CommentComposer` the composer with a mention affordance. |
|
|
427
|
+
| `TypeBadge` | `kind` (11 entity kinds) | The coloured square in front of every entity title. `TitleCell` = badge + truncating title with a completed strikethrough; `ProductCell` = module icon + name + lock; `StarButton`, `QuickStart`, `TableBanner`, `SelectionBar` fill out the chrome. |
|
|
428
|
+
| `BoardView` / `RoadmapView` / `DocSplit` | `columns` / `periods`+`lanes` / `tree`+children | Kanban columns, the quarter timeline grid, and the document tree + body split. |
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## 8. Extracted composites (third pass)
|
|
433
|
+
|
|
434
|
+
These nine components were store-coupled inside the demo site and are now pure and
|
|
435
|
+
controlled, so any host can drive them. Their store wiring lives in the demo's
|
|
436
|
+
`src/app/adapters/*`.
|
|
437
|
+
|
|
438
|
+
| Component | Controlled props | Behaviour kept |
|
|
439
|
+
| --------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
440
|
+
| `CommentThread` | `comments`, `currentUser`, `onAdd`, `onUpdate`, `onRemove`, `onReact` | replies nest, inline edit with an "edited" marker, delete confirmation naming the comment, emoji reactions with `aria-pressed`, `@mention` highlighting |
|
|
441
|
+
| `AttachmentUpload` | `files`, `onUpload`, `onRemove`, `maxSizeMb` | drag-and-drop + picker, per-file progress that completes, oversize refused before reading, attached rows with preview and unlink |
|
|
442
|
+
| `LinkPicker` | `targets`, `selected`, `candidates`, `onLink`, `onUnlink` | dialog with a target segment, search, already-linked rows disabled, current links grouped with unlink |
|
|
443
|
+
| `FilePreview` | `file`, `open`, `onClose` | md/txt/csv document view, csv table, image frame, unsupported-type state, zoom, real download |
|
|
444
|
+
| `TransitionsTimeline` | `entries`, `statuses`, `currentStatus` | newest-first rail, flow strip, `old → new` chips, status-coloured dots, real empty state |
|
|
445
|
+
| `EntityDialog` | `fields`, `initialValues`, `onSubmit` | two-column sheet, blur-then-validate, reset on `open` only (typing never wiped), drag/scroll guard |
|
|
446
|
+
| `ShareDialog` | `value`, `onChange`, `onSave`, `onCopy` | visibility, copyable link, expiry menu, scheduled export with validation |
|
|
447
|
+
| `ReportCanvas` | `widgets`, `onChange`, `loading` | drag reorder, 4/6/12 width, keyboard ▲▼, remove confirmation, empty state, live-region announcements |
|
|
448
|
+
| `RoadmapEditor` | `lanes`, `periods`, `bars`, `onChange` | drag between quarters, ←/→ moves, inline rename, recolour, zoom, weekend toggle, bounded weekend maths |
|
|
449
|
+
|
|
450
|
+
## 9. Extracted in the fourth pass
|
|
451
|
+
|
|
452
|
+
Lifted out of the demo site once its own copies had drifted into four variants of
|
|
453
|
+
the same thing. Everything below is pure: the store, the router and the demo's
|
|
454
|
+
seed data stay in the host.
|
|
455
|
+
|
|
456
|
+
| Component | Props that matter | Behaviour kept |
|
|
457
|
+
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
458
|
+
| `DetailBlock` | `title?`, `actions?`, `children`, `className` | The content block a detail sheet is written with — heading row plus optional right-aligned actions — so a page never reaches for `pro-detail-block__*` itself. |
|
|
459
|
+
| `DetailTool` | `icon?`, `label?`, `children`, `onClick` | The compact tool in the identity bar ("Attachments", "Links", "Export"). With only `label` it is icon-only and the label becomes its accessible name; tooltips stay with the host. |
|
|
460
|
+
| `EditableText` | `title`, `text`, `onSave`, `rows`, `label`, `editSeed`, `paragraphs`, `note`, `readOnly`, `editing`/`draft` (controlled or not) | Read view, editor and Cancel/Save row in one place: uncontrolled by default so two blocks on a sheet never share state, liftable when a host owns the state machine, and a blank draft re-commits the current text rather than blanking a record. |
|
|
461
|
+
| `EntityPicker<T>` | `rows`, `rowKey`, `value`, `onChange`, `onConfirm`, `linked`, `variant` (`list` \| `table`), `scopes`, `search`, `fields`/`rules`/`sortFields`, `hint`, `confirmLabel` | "Select ideas" in both shapes the product uses: the compact tick list (a plan picking what it scores) and the workbench table with a scope tree (a roadmap picking from the whole product). `linked` is what turns ticks into `N to link · M to unlink`, and the dialog is only dismissable when nothing would be written. |
|
|
462
|
+
| `ScatterPlot` | `points: { id, label, x, y, name?, render? }[]`, `xLabel`, `yLabel`, `title`, `extra`, `onSelect?`, `emptyState`, `height` | The Plan matrix: percentage-positioned points with computed ticks, so a point can never fall outside the frame. No chart dependency; points are `role="img"` with the value in their accessible name unless `onSelect` makes them buttons. |
|
|
463
|
+
| `ProjectWizard` | `types`, `members`, `owner`, `existingKeys?`, `belongsToOptions?`, `categoryOptions?`, `onSubmit(draft)`, `onClose` | The three-step `New project` modal: the type preview pane, the type cards with arrow-key roving focus, blur-then-validate details, the member step with its own roster dialog, and the discard guard. |
|
|
464
|
+
|
|
465
|
+
| `AccountMenu` | `user: { name, email? }`, `items`, `label?` | The account popover body: identity row, then the menu. The host keeps the anchor and the popover. |
|
|
466
|
+
| `ShortcutsDialog` | `open`, `onClose`, `shortcuts: { keys, label }[]`, `title?` | The keyboard help sheet — `<kbd>` on the left, the action on the right. |
|
|
467
|
+
| `QuickStartDialog` | `open`, `onClose`, `steps`, `checked`, `onToggle`, `onGo?`, `onReset?`, `intro?` | The getting-started checklist: progress bar, one tickable row per step, and a "go" action for the steps that lead somewhere. |
|
|
468
|
+
|
|
469
|
+
Alongside them: `VoteCount`, `QuickStart` grew `done` / `total` for the checklist
|
|
470
|
+
counter, `Tag` grew `tone="accent"` and `size="sm"` for the quarter chip, and
|
|
471
|
+
`primaryComponents` / `componentLine` moved in with the wizard.
|
|
472
|
+
|
|
473
|
+
## 10. Hooks and helpers
|
|
474
|
+
|
|
475
|
+
| Export | Use |
|
|
476
|
+
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
477
|
+
| `useToast()` | Push a toast from anywhere under `ToastProvider`. |
|
|
478
|
+
| `useControllableState({ value, defaultValue, onChange })` | The pattern behind every controlled/uncontrolled component. |
|
|
479
|
+
| `usePopoverClose()` | Lets a menu close the popover that hosts it. |
|
|
480
|
+
| `useAnchorRef()` · `useSelectAnchor()` | Keep a trigger element in state so an anchored layer can measure it. |
|
|
481
|
+
| `formatListTime` | `Today 15:44` / `Yesterday 09:12` / `Tuesday 09:12` / `Mar 3` — the product's relative list timestamps. |
|
|
482
|
+
| `formatDateTime` · `formatDay` · `formatNumber` · `formatCount` · `formatCompact` · `pluralize` | All through `Intl`; nothing is hand-formatted. |
|
|
483
|
+
| `cx` · `statusColor` · `avatarColor` · `initials` · `nextRuleId` | Class joining, status→token mapping, deterministic avatar colours, initials, filter-rule ids. |
|
|
484
|
+
|
|
485
|
+
## 11. Inline editors, the assistant and the newer surfaces
|
|
486
|
+
|
|
487
|
+
The components added after the fourth pass, in the order a host meets them.
|
|
488
|
+
|
|
489
|
+
| Component | Props that matter | Behaviour |
|
|
490
|
+
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
491
|
+
| `PeoplePicker` | `tabs`, `value`, `onPick`, `searchPlaceholder`, `emptyHint`, `onClose` | The inline assignee editor the grid opens on a cell: the person already assigned starts the cursor (or `Unassigned`), type to filter, ↑↓ walk the rows, Enter picks. Returns `null` for the `Unassigned` row. |
|
|
492
|
+
| `QuickSelect` | `options`, `value`, `onPick`, `placeholder`, `allowClear`, `renderOption`, `onClose` | The enum cell editor: the field is the control, the list is portalled, typeahead jumps to an option, Escape closes, and `allowClear` adds the row that empties the field. |
|
|
493
|
+
| `QuickText` | `value`, `onCommit`, `display`, `trigger`, `maxLength`, `onClose` | The inline rename editor. `trigger` is `click` or `dblclick`; `display` is normally the very node the column already draws, so opening the editor changes nothing but the input. An unchanged value never commits. |
|
|
494
|
+
| `useListCursor` / `useSelectAnchor` | `count` / — | The two shared pieces behind those editors: the cursor arithmetic that keeps ↑↓ inside a shrinking list, and the anchor ref a portalled list measures against. |
|
|
495
|
+
| `ContextMenuList` / `useContextMenu` | `items`, `quick`, `aria-label` / `items` | The menu the right-click layer renders, and its imperative form (`openAt(x, y, context)`) for a host that owns the gesture itself. |
|
|
496
|
+
| `IconAvatar` | `icon`, `label?`, `tone`, `size` | The avatar shell carrying a glyph instead of initials — a row whose leading mark identifies a kind of record. Decorative unless `label` is given. |
|
|
497
|
+
| `RichTextToolbar` | — | The inert rich-text strip that sits above a description textarea (the editor itself is out of scope). |
|
|
498
|
+
| `AiPanel` / `PingMark` | `open`, `messages`, `onSubmit`, `pending`, `suggestions`, `quickChips`, `onClose` | The assistant side panel: a `role="dialog"` whose transcript is one `role="log"`, a composer that submits on Enter, suggestion cards and quick chips that fill the composer. It never invents a reply — the host owns the transcript and the thinking state. |
|
|
499
|
+
| `SidebarCollapseProvider` / `useSidebarCollapsed` | `collapsed` | Collapsing a sidebar is a shell decision, so a shell wraps its page tree once and every `Sidebar` inside follows; a `collapsed` prop on one sidebar still wins. |
|
|
500
|
+
| `ListWorkbench<T>` | `rows`, `columns`, `view` + `onViewChange`, `selection`, `title`/`noun`, `status`, `searchText`, `matches`, `compare`, `views`, `boardView`, `enumFields`/`textFields`/`assigneeField`, `bulkActions`, `onDelete` | The whole list screen in one component: header, toolbar (search / filter / sort / group / view switch), the five states, inline cell editors, selection with its bulk bar, pagination and the row commands. Everything it cannot decide alone — how to search, filter, compare, open, export — arrives as a callback. |
|
|
501
|
+
| `DEFAULT_SHARING` | — | The value a report's sharing starts from (`ReportSharing`): visibility, link, expiry, schedule, hour, recipients, format. |
|
|
502
|
+
|
|
503
|
+
## Additional common components
|
|
504
|
+
|
|
505
|
+
### `Radio` / `RadioGroup`
|
|
506
|
+
|
|
507
|
+
`Radio` forwards its input ref and native input attributes, with a `label` slot.
|
|
508
|
+
`RadioGroup` takes string-valued `options`, `value` / `defaultValue`, `onChange`,
|
|
509
|
+
`name`, `disabled`, `required`, and `orientation`. An `aria-label` is required.
|
|
510
|
+
Same-name native radios provide arrow-key selection, Space activation and form submission.
|
|
511
|
+
Each group gets a unique name when omitted.
|
|
512
|
+
|
|
513
|
+
### `Tabs`
|
|
514
|
+
|
|
515
|
+
`items: { key, label, children, disabled? }[]`, `activeKey` / `defaultActiveKey`,
|
|
516
|
+
`onChange`, `keepMounted`, and a required `aria-label`. Left/Right wrap past disabled
|
|
517
|
+
tabs; Home/End select the first/last enabled tab. One tab is in the Tab sequence.
|
|
518
|
+
Linked tab panels retain their content when `keepMounted` is true; otherwise inactive
|
|
519
|
+
content unmounts. A removed or disabled active key displays the first enabled tab.
|
|
520
|
+
|
|
521
|
+
### `Collapse`
|
|
522
|
+
|
|
523
|
+
`items: { key, label, children, disabled? }[]`, `activeKeys` / `defaultActiveKeys`,
|
|
524
|
+
`onChange`, and `accordion`. Native buttons respond to Enter/Space and expose
|
|
525
|
+
`aria-expanded` / `aria-controls`. Accordion opens at most one panel. Hidden content
|
|
526
|
+
remains mounted to preserve input state.
|
|
527
|
+
|
|
528
|
+
### `Badge`
|
|
529
|
+
|
|
530
|
+
`count`, `overflowCount` (99), `showZero`, `dot`, `label`, and optional `children`.
|
|
531
|
+
Counts above the limit display `99+` while retaining the full accessible count.
|
|
532
|
+
Zero is hidden by default; negative and non-finite counts are hidden. Children
|
|
533
|
+
receive an attached badge. Supply a descriptive `label` for dots.
|
|
534
|
+
|
|
535
|
+
Reference: [Ant Design component library](https://github.com/ant-design/ant-design).
|
|
536
|
+
These are independent token-based implementations, not drop-in antd replacements.
|
|
537
|
+
|
|
538
|
+
### `Slider`
|
|
539
|
+
|
|
540
|
+
Native single-thumb `input[type="range"]`, with forwarded ref and input attributes.
|
|
541
|
+
`min` (0), `max` (100), `step` (1), native `value` / `defaultValue`, `disabled`,
|
|
542
|
+
`name`, and `onChange(event)` work like `Input`. Supply a visible `Field` label or
|
|
543
|
+
`aria-label`. Arrow keys, Home/End, rounding, bounds and form submission are native
|
|
544
|
+
browser behaviour. No custom multi-thumb range or tooltip is provided.
|
|
545
|
+
|
|
546
|
+
### `Steps`
|
|
547
|
+
|
|
548
|
+
`items: { key, title, description?, disabled? }[]`, zero-based `current`,
|
|
549
|
+
`status: 'process' | 'error'`, `orientation`, optional `onChange(index)`, and a required
|
|
550
|
+
`aria-label`. An ordered list exposes the current step with `aria-current="step"`
|
|
551
|
+
and names each step's status. Passing `current={items.length}` marks all complete;
|
|
552
|
+
out-of-range indices are clamped. With `onChange`, native buttons allow Enter/Space
|
|
553
|
+
activation and respect disabled steps; the host controls progression and validation.
|
|
554
|
+
|
|
555
|
+
### `Alert`
|
|
556
|
+
|
|
557
|
+
`message`, `description`, `type: 'info' | 'success' | 'warning' | 'error'`, `showIcon`,
|
|
558
|
+
`action`, `closable`, `closeLabel`, `open` / `defaultOpen`, `onOpenChange`, `onClose`.
|
|
559
|
+
Persistent inline feedback with `role="alert"` for errors and `role="status"` otherwise.
|
|
560
|
+
Closing uses a labelled native button, supports Enter/Space, and reports visibility
|
|
561
|
+
changes. For temporary notifications use `useToast`; for table strips use `Banner`.
|
|
562
|
+
|
|
563
|
+
References: [Slider](https://ant.design/components/slider/),
|
|
564
|
+
[Steps](https://ant.design/components/steps/), [Alert](https://ant.design/components/alert/).
|
|
565
|
+
|
|
566
|
+
### `CheckboxGroup`
|
|
567
|
+
|
|
568
|
+
`options: { value, label, disabled? }[]`, string-array `value` / `defaultValue`,
|
|
569
|
+
`onChange`, `name`, `disabled`, `orientation`, and required `aria-label`.
|
|
570
|
+
Reuses `Checkbox`; Tab reaches enabled choices and Space toggles them.
|
|
571
|
+
Native same-name checkbox inputs submit multiple form values. Selection is
|
|
572
|
+
preserved when options change; the host owns removal of obsolete selections.
|
|
573
|
+
|
|
574
|
+
### `PasswordInput`
|
|
575
|
+
|
|
576
|
+
Reuses `Input` and forwards its ref, value, native input attributes, `size`, and
|
|
577
|
+
`invalid`. Visibility uses `visible` / `defaultVisible` (false), `onVisibleChange`,
|
|
578
|
+
`showLabel` / `hideLabel`. A labelled toggle supports Enter/Space and exposes
|
|
579
|
+
`aria-pressed`; pointer toggles keep focus in the field. `disabled` disables both
|
|
580
|
+
controls. Works with `Field`; supply the appropriate password `autoComplete` value.
|
|
581
|
+
|
|
582
|
+
### `Rate`
|
|
583
|
+
|
|
584
|
+
Whole-star rating from 0 to 5. `value` / `defaultValue`, `onChange(number)`,
|
|
585
|
+
`disabled`, `readOnly`, `allowClear` (true), `clearLabel`, `name`, and required
|
|
586
|
+
`aria-label`. Reuses native `RadioGroup` for arrow navigation and Space selection.
|
|
587
|
+
The clear button resets to zero. Read-only mode exposes a labelled image without
|
|
588
|
+
interactive controls. Non-finite values display zero; others round and clamp.
|
|
589
|
+
Half-star input and hover previews are not implemented.
|
|
590
|
+
|
|
591
|
+
References: [Checkbox](https://ant.design/components/checkbox/),
|
|
592
|
+
[Input](https://ant.design/components/input/), [Rate](https://ant.design/components/rate/).
|
|
593
|
+
|
|
594
|
+
### `Cascader`
|
|
595
|
+
|
|
596
|
+
Hierarchical leaf selection with `options: { value, label, disabled?, children? }[]`,
|
|
597
|
+
string-array `value` / `defaultValue`, `onChange`, `searchable`, `allowClear`,
|
|
598
|
+
`disabled`, `invalid`, and required `aria-label`. Values are the complete path.
|
|
599
|
+
Reuses `Popover` and `Menu`: Up/Down, Home/End and typeahead walk each level; Right
|
|
600
|
+
opens a child menu, Left returns, Enter chooses and Escape closes. Search matches
|
|
601
|
+
full leaf paths; disabled ancestors also disable descendants. Closing returns focus
|
|
602
|
+
to the trigger. Rich labels use their text for full-path search.
|
|
603
|
+
|
|
604
|
+
`multiple` changes value/defaultValue/onChange to arrays of complete string paths.
|
|
605
|
+
Parent/child checks share Tree's conduction engine; `showCheckedStrategy` is
|
|
606
|
+
`'SHOW_PARENT'` by default or `'SHOW_CHILD'` for leaf paths. Disabled ancestors
|
|
607
|
+
block descendants; `disableCheckbox` blocks that node's check conduction while
|
|
608
|
+
children remain independently checkable. Search toggles retain checks outside
|
|
609
|
+
results. Unknown selected paths survive changes; selected labels survive remote
|
|
610
|
+
options replacement, including leaf values displayed through parent compaction.
|
|
611
|
+
Multi clear preserves disabled/checkbox-disabled paths.
|
|
612
|
+
|
|
613
|
+
`changeOnSelect` allows intermediate single paths: pointer selection keeps the
|
|
614
|
+
hierarchy open, while keyboard selection or a leaf requests closing.
|
|
615
|
+
`loadData(selectedOptions)` resolves child options or lets the host update options
|
|
616
|
+
and resolve void. Set `isLeaf={false}` on unloaded branches. Loads deduplicate,
|
|
617
|
+
show loading, offer Retry on failure, and reject stale source/loader replacements
|
|
618
|
+
or late unmounted results. Returned children are validated against the full
|
|
619
|
+
hierarchy before display. Keep source objects immutable and loader callbacks stable;
|
|
620
|
+
changing their identity invalidates pending requests and loaded metadata.
|
|
621
|
+
|
|
622
|
+
`fieldNames` maps value/label/children; string values are required and unique per
|
|
623
|
+
complete path. Cyclic input, malformed children and duplicate paths are rejected.
|
|
624
|
+
`displayRender(labels, selectedOptions)` and `optionRender(option)` customize
|
|
625
|
+
presentation. `filterOption(query, selectedOptions)`, searchValue/onSearch and
|
|
626
|
+
notFoundContent support host search. `open`/`defaultOpen`/`onOpenChange` keep popup
|
|
627
|
+
ownership explicit; a refused close does not erase its query. loading presents
|
|
628
|
+
host-owned async state; requests remain the host's responsibility. Native button
|
|
629
|
+
attributes and ref support Form and focus.
|
|
630
|
+
|
|
631
|
+
Klun keeps the original single Menu/submenu UI and string paths. Multiple,
|
|
632
|
+
intermediate and lazy hierarchy use existing Tree semantics rather than copying
|
|
633
|
+
AntD's column UI or private combobox handle. It does not alias numeric/null values,
|
|
634
|
+
hover expansion, Panel, semantic styles or every AntD prop. Menu closeOnSelect can
|
|
635
|
+
be disabled when a composite control owns closing, keeping single radio semantics.
|
|
636
|
+
|
|
637
|
+
### `Transfer`
|
|
638
|
+
|
|
639
|
+
`items: { key, label, disabled? }[]`, `targetKeys` / `defaultTargetKeys`, `onChange`,
|
|
640
|
+
`titles`, `searchable`, `disabled`, `status`, `emptyState` / `errorState`, and required
|
|
641
|
+
`aria-label`. Two checkbox lists support Tab/Space and labelled move buttons. Search
|
|
642
|
+
and select-all affect visible enabled rows; moves preserve unknown and disabled
|
|
643
|
+
target keys. A live region reports selected counts. Compact viewports stack the lists.
|
|
644
|
+
|
|
645
|
+
`selectedKeys` / `defaultSelectedKeys` control the checked rows independently of
|
|
646
|
+
`targetKeys`; `onSelectChange(leftKeys, rightKeys)` reports both partitions.
|
|
647
|
+
`onChange(targetKeys, direction, moveKeys)` reports only known enabled rows that
|
|
648
|
+
actually move, with `right` meaning add to targets and `left` meaning remove.
|
|
649
|
+
Existing single-argument callbacks remain assignable. A controlled host can refuse
|
|
650
|
+
both target and check changes; each displayed state stays supplied by the host.
|
|
651
|
+
|
|
652
|
+
`pagination` enables independent pages per side, default size 10;
|
|
653
|
+
`pagination={{ pageSize, showSizeChanger?, pageSizeOptions? }}` sets a controlled
|
|
654
|
+
size when supplied. Search resets that side to page 1 and reduced totals clamp the
|
|
655
|
+
visible page. Checks survive page/search changes; select-all touches only enabled
|
|
656
|
+
rows on the displayed page. `filterOption(query, item, direction)` and
|
|
657
|
+
`onSearch(direction, query)` support host filtering. Rich labels use their text by
|
|
658
|
+
default, or `searchText` for opaque content; `render(item)` changes row presentation.
|
|
659
|
+
|
|
660
|
+
A render-function child receives `direction`, `disabled`, `dataSource`,
|
|
661
|
+
`filteredItems`, `selectedKeys`, `onItemSelect` and `onItemSelectAll`; custom lists
|
|
662
|
+
own paging, as in AntD. Selection callbacks reject disabled, unknown and wrong-side
|
|
663
|
+
keys, including saved callbacks after the component becomes disabled/loading.
|
|
664
|
+
Bulk selection accepts true/false or `'replace'`; replace preserves disabled checks
|
|
665
|
+
and checks on the opposite side. `showSelectAll={false}` hides the checkbox header;
|
|
666
|
+
`footer(listProps)` adds per-side content. Native div attributes and refs are forwarded.
|
|
667
|
+
|
|
668
|
+
Klun keeps `items`, string keys, textual titles and ready/loading/error status;
|
|
669
|
+
it does not alias AntD's `dataSource`, numeric keys, oneWay or semantic style APIs.
|
|
670
|
+
|
|
671
|
+
### `DatePicker` / `DateRangePicker`
|
|
672
|
+
|
|
673
|
+
ISO calendar dates (`YYYY-MM-DD`) avoid implicit time-zone conversions. `DatePicker`
|
|
674
|
+
forwards an input ref, `name`, `id`, and `required`; accepts `value` / `defaultValue`,
|
|
675
|
+
`onChange(string)`, `min`, `max`, `disabledDate`, `locale`, `disabled`, `invalid`, and
|
|
676
|
+
required `aria-label`. Native date entry and a themed calendar share the same bounds.
|
|
677
|
+
Custom disabled dates also fail native form validity when provided by the host.
|
|
678
|
+
|
|
679
|
+
The calendar offers month/year selection, previous/next month, Today and Clear.
|
|
680
|
+
Left/Right move a day, Up/Down a week, Home/End within the week and PageUp/PageDown
|
|
681
|
+
a month (clamping the day for shorter months). Enter/Space chooses; unavailable
|
|
682
|
+
days can be inspected with keyboard focus but cannot be selected. Escape closes
|
|
683
|
+
and restores trigger focus. Locale controls calendar names; the browser localizes
|
|
684
|
+
native input display. Invalid host dates are marked invalid and never normalized
|
|
685
|
+
into a different date. Calendar values use years 0001 through 9999.
|
|
686
|
+
|
|
687
|
+
`DateRangePicker` accepts a `[start, end]` tuple, optional `names`, and shared date
|
|
688
|
+
constraints. Each endpoint bounds the other; partial ranges are allowed, reversed
|
|
689
|
+
ranges fail native validation. Time and multi-date selection are separate needs
|
|
690
|
+
and are not included in this date-only contract.
|
|
691
|
+
|
|
692
|
+
### MultiSelect corrections
|
|
693
|
+
|
|
694
|
+
The trigger opens a labelled dialog containing a checkbox group. Choices expose
|
|
695
|
+
actual checkbox semantics; disabled items cannot be toggled or cleared. Clear
|
|
696
|
+
removes enabled selections present in this options page and preserves locked or
|
|
697
|
+
unknown keys. The panel closes when the whole control becomes disabled.
|
|
698
|
+
|
|
699
|
+
References: [Cascader](https://ant.design/components/cascader/),
|
|
700
|
+
[Transfer](https://ant.design/components/transfer/),
|
|
701
|
+
[DatePicker](https://ant.design/components/date-picker/).
|
|
702
|
+
|
|
703
|
+
### DataTable: paging, filtering and row details
|
|
704
|
+
|
|
705
|
+
`pagination` reuses `Pagination` and stays controlled. By default the table derives
|
|
706
|
+
`total` from supplied rows and slices locally. Set `mode: 'remote'` for server-paged
|
|
707
|
+
rows; the host then supplies the total and fetches on `onPageChange`. Invalid or
|
|
708
|
+
out-of-range page values are clamped for display. Row numbers and render indexes
|
|
709
|
+
are relative to the current page.
|
|
710
|
+
|
|
711
|
+
A column `sorter(a, b)` enables local sorting without mutating `rows`. Columns with
|
|
712
|
+
only `sortable` retain the existing host-managed sorting contract. `defaultSort`
|
|
713
|
+
and `defaultFilters` initialize uncontrolled state; `sort` and `filters` make it
|
|
714
|
+
controlled. A column's `filters` supplies named choices, and `onFilter(values, row)`
|
|
715
|
+
implements its local predicate. Without a predicate the host handles the filter
|
|
716
|
+
callback. The pipeline is filter → sort → page, and filter changes request page 1.
|
|
717
|
+
For remote data omit local predicates/comparators and perform them on the server.
|
|
718
|
+
|
|
719
|
+
`isRowSelectable` disables selection per row. Select-all touches only eligible
|
|
720
|
+
rows on the current page, preserving locked and off-page keys. Selection remains
|
|
721
|
+
host-managed through `selectedKeys`/`onSelectedKeysChange`.
|
|
722
|
+
|
|
723
|
+
`expandedRowRender` supplies detail content, including a nested table when needed.
|
|
724
|
+
`rowExpandable` excludes individual rows. Expansion is uncontrolled by default;
|
|
725
|
+
use `defaultExpandedRowKeys`, or control it with `expandedRowKeys` and
|
|
726
|
+
`onExpandedRowKeysChange`.
|
|
727
|
+
|
|
728
|
+
Columns support `hidden`, `ellipsis: false` for wrapping (disables fixed-height virtual scrolling), and `onCell` for native
|
|
729
|
+
cell attributes. Use `rowSpan`/`colSpan` and a zero span on covered cells. Keep
|
|
730
|
+
`onCell` pure: layout and cursor navigation both read it. Cursor navigation skips
|
|
731
|
+
omitted cells and follows visible grouped rows in their rendered order.
|
|
732
|
+
|
|
733
|
+
`title`, `footer`, `rowClassName`, `summary` (native rows inside `tfoot`),
|
|
734
|
+
`showHeader`, `stickyHeader` and `scroll: { x, y }` cover layout customization.
|
|
735
|
+
The default empty and error states provide feedback even without custom content.
|
|
736
|
+
Interactive controls within cells keep their own click and keyboard behavior.
|
|
737
|
+
|
|
738
|
+
### Tree and DirectoryTree — full hierarchy interactions
|
|
739
|
+
|
|
740
|
+
Both accept existing `nodes: { id, label, children }[]` or `treeData:
|
|
741
|
+
{ key, title, children }[]`. `fieldNames` maps custom data fields. Keys must be
|
|
742
|
+
unique across the entire tree; duplicate keys and cycles are rejected. Numeric
|
|
743
|
+
treeData keys normalize to strings, including keys used by state and `scrollTo`.
|
|
744
|
+
|
|
745
|
+
| Capability | Props and behavior |
|
|
746
|
+
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
747
|
+
| Expansion | `expandedKeys` / `defaultExpandedKeys` (`defaultExpanded` remains compatible), `defaultExpandAll`, `defaultExpandParent`, `autoExpandParent`, `onExpand` |
|
|
748
|
+
| Selection | `selectedKeys` / `defaultSelectedKeys`, `multiple`, `selectable`, `onSelectionChange(keys, info)`; legacy `value` / `onSelect(node)` remain unchanged |
|
|
749
|
+
| Checks | `checkable`, `checkedKeys` / `defaultCheckedKeys`, `onCheck`; hierarchical checks report full checked keys plus half-checked keys in info |
|
|
750
|
+
| Strict checks | `checkStrictly` disables parent/child conduction and accepts/reports `{ checked, halfChecked }` |
|
|
751
|
+
| Node boundaries | `disabled`, `disableCheckbox`, `checkable: false`, `selectable: false`; disabled check nodes stop conduction without disabling descendants independently |
|
|
752
|
+
| Async branches | `loadData(node)` resolves children or updates host data and resolves void; `isLeaf`, `loadedKeys`, `defaultLoadedKeys`, `onLoad`, `onLoadError`; requests deduplicate, retry after failure and reject stale replacements |
|
|
753
|
+
| Search | `searchValue` highlights labels and reveals ancestors; `filterTreeNode` highlights predicate matches without removing nodes; `titleRender` owns custom content |
|
|
754
|
+
| Appearance | `showLine` (including custom leaf icons), `showIcon`, `icon`, `switcherIcon`, `switcherLoadingIcon`, `blockNode`, `indent`, CSS `motion`, semantic `classNames` / `styles`, node `className` / `style` |
|
|
755
|
+
| Dragging | `draggable` boolean, predicate or icon/config object; `movable`, `allowDrop`, `onMove`, all drag lifecycle callbacks and `onDrop`; cycles and disabled targets are refused; hovering a closed branch opens it |
|
|
756
|
+
| Virtual rows | `height`, `itemHeight`, `virtual`; fixed-height windowing retains an active descendant for accessibility; set `virtual={false}` for the complete DOM |
|
|
757
|
+
| Imperative control | `ref: TreeRef` exposes `nativeElement`, `focus()` and `scrollTo({ key, align, offset })`; nested keys reveal their ancestors, controlled expansion must be accepted by the host |
|
|
758
|
+
| Directory behavior | `DirectoryTree` defaults to click expansion and folder/file icons; `expandAction` also supports `doubleClick` and `false`; Ctrl/Meta toggles and Shift ranges merge the last ordinary/Ctrl selection; directory selection stays independent of expandAction |
|
|
759
|
+
| Commands | `nodeActions`, `nodeContextMenu`, `onRightClick`, `onDoubleClick`; visible command equivalents must accompany right-click menus |
|
|
760
|
+
|
|
761
|
+
Keyboard: Up/Down walk visible nodes; Right opens or enters a branch; Left closes
|
|
762
|
+
or goes to its parent; Home/End jump; typing searches visible labels; `*` opens
|
|
763
|
+
sibling branches; Enter selects; Space checks (or selects without checks).
|
|
764
|
+
RTL mirrors Left/Right navigation and Alt nesting/lifting. IME keys do not
|
|
765
|
+
change tree state. Ctrl/Meta+Space supports additive directory selection, Shift+navigation extends
|
|
766
|
+
ranges, and Alt+arrows reorder/nest/lift through the same move validation used
|
|
767
|
+
by pointer dragging. Embedded controls retain their own keys. Disabled nodes
|
|
768
|
+
remain discoverable by navigation while refusing changes.
|
|
769
|
+
|
|
770
|
+
Keep host data immutable and retain node identities while an async request is
|
|
771
|
+
in flight. A newly replaced node invalidates the old request/cache. When using
|
|
772
|
+
controlled `loadedKeys`, update them from `onLoad` and clear replaced nodes yourself.
|
|
773
|
+
Use a node’s `ariaLabel` when its rich title needs an explicit accessible name. Newly loaded children inherit
|
|
774
|
+
checked ancestor state in hierarchical mode. Default values are initialization
|
|
775
|
+
values; changing them later does not overwrite user state.
|
|
776
|
+
|
|
777
|
+
Virtualization uses a fixed `itemHeight` and truncates labels to one line, as
|
|
778
|
+
Ant Design's virtual Tree does. CSS transitions respect reduced motion; `motion`
|
|
779
|
+
is a boolean here, not Ant Design's private rc-motion configuration. This is
|
|
780
|
+
capability alignment with existing Klun APIs, not a drop-in `antd` import.
|
|
781
|
+
|
|
782
|
+
DirectoryTree caches the selection from the last plain/Ctrl/Meta pick, merging
|
|
783
|
+
Shift ranges with that base; a later Shift pick shrinks only its previous range.
|
|
784
|
+
Ctrl/Meta wins when held together with Shift. A plain directory pick replaces the
|
|
785
|
+
selection even with `expandAction={false}`, and Directory selection info reports
|
|
786
|
+
`selected: true`, including Ctrl deselection, matching AntD DirectoryTree.
|
|
787
|
+
Regular Tree keeps its existing additive multiple selection independently of
|
|
788
|
+
click expansion. Boolean `showLine={{ showLeafIcon: true }}` renders the default
|
|
789
|
+
file icon; false keeps only the connector, and functions receive node state.
|
|
790
|
+
|
|
791
|
+
Native dragging resolves upper-half gaps through the previous visible node,
|
|
792
|
+
inside expanded branches and horizontal nesting/lifting of last descendants,
|
|
793
|
+
mirrored in RTL. `allowDrop.dropPosition` remains relative (-1/0/1).
|
|
794
|
+
**Migration:** `onDrop.dropPosition` now matches AntD's target sibling index plus
|
|
795
|
+
relative direction; use `onDrop.relativeDropPosition` for the previous relative
|
|
796
|
+
meaning. `onMove` keeps before/after/inside. Unknown targets, cycles, disabled
|
|
797
|
+
boundaries, no-op moves and explicit leaves reject invalid drops. The host owns
|
|
798
|
+
reordering. Numeric treeData keys (including 0) intentionally normalize to string
|
|
799
|
+
state/callback/ref keys; 1 and '1' collide and are rejected. Nonfinite numeric
|
|
800
|
+
keys are invalid. This avoids changing existing TreeSelect/route string APIs.
|
|
801
|
+
|
|
802
|
+
## Global configuration and Form foundation
|
|
803
|
+
|
|
804
|
+
`ConfigProvider` inherits `locale`, `direction` and `disabled` from its parent.
|
|
805
|
+
Omitted options inherit; explicit `disabled={false}` overrides the provider.
|
|
806
|
+
`useProConfig()` reads configuration and `useComponentDisabled(disabled)` resolves
|
|
807
|
+
the disabled fallback for custom controls. Core input controls, Button,
|
|
808
|
+
ActionButton, Select/MultiSelect, radio/checkbox groups, DatePicker, Cascader,
|
|
809
|
+
Transfer, Rate and Tree consume it. Portalled Dialog, Popover, Tooltip and Toast
|
|
810
|
+
retain provider language and direction. This provides native text direction;
|
|
811
|
+
full mirroring of every physical CSS offset and Ship business control is not
|
|
812
|
+
implemented. Locale currently supplies Form messages and DatePicker date labels;
|
|
813
|
+
other existing English copy is unchanged.
|
|
814
|
+
|
|
815
|
+
`Form` / `FormItem` use `NamePath`: a string or number is a literal key; an array
|
|
816
|
+
of string/number segments describes a nested object/array path. `user.name`
|
|
817
|
+
remains a literal key; `['user', 'name']` accesses the nested value. Numeric array
|
|
818
|
+
indexes are nonnegative integers below 100,000; string numeric keys remain object
|
|
819
|
+
keys. Records/arrays are copied at store boundaries; reserved prototype keys,
|
|
820
|
+
cycles and structures deeper than 100 levels are rejected before writing.
|
|
821
|
+
Other object types must remain immutable.
|
|
822
|
+
|
|
823
|
+
`initialValues` initializes the instance and is the reset baseline; changing
|
|
824
|
+
that prop does not overwrite edits. Unmounted fields preserve values but clear
|
|
825
|
+
errors and pending validation. `setFieldsValue` merges records recursively and
|
|
826
|
+
replaces arrays; `setFieldValue` changes one exact path. Partial updates retain
|
|
827
|
+
unmodified sibling metadata. Reset can target a subtree and remounts affected
|
|
828
|
+
controls/lists, including multiple resets in one React batch. Dependencies and
|
|
829
|
+
externally controlled field metadata are not implemented yet.
|
|
830
|
+
|
|
831
|
+
```tsx
|
|
832
|
+
const [form] = useForm();
|
|
833
|
+
|
|
834
|
+
<Form form={form} initialValues={{ name: '', subscribed: true }} onFinish={save}>
|
|
835
|
+
<FormItem name="name" label="Name" required rules={[{ min: 2, message: 'Too short' }]}>
|
|
836
|
+
<Input />
|
|
837
|
+
</FormItem>
|
|
838
|
+
<FormItem name="subscribed" valuePropName="checked">
|
|
839
|
+
<Checkbox label="Receive updates" />
|
|
840
|
+
</FormItem>
|
|
841
|
+
<Button type="submit">Save</Button>
|
|
842
|
+
</Form>;
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
Rules support required, whitespace, min/max (numeric value or string/array
|
|
846
|
+
length), regular expressions and synchronous/asynchronous `validator(value,
|
|
847
|
+
values)`. Validators return a message or throw/reject an Error to fail. Omitted
|
|
848
|
+
messages use provider locale. `validateTrigger` defaults to `onBlur`; use
|
|
849
|
+
`onChange` when desired. `onFinish` runs only for valid, current values; repeated
|
|
850
|
+
submissions are suppressed while pending. `onFinishFailed` receives validation
|
|
851
|
+
failures; `onSubmitError` receives rejected submissions, which also show a retry
|
|
852
|
+
message without clearing values. Stale edits, reset, superseded validation and
|
|
853
|
+
unmount prevent old results from becoming current errors.
|
|
854
|
+
|
|
855
|
+
`useForm()` returns `[form]`. The instance exposes `getFieldValue`,
|
|
856
|
+
`getFieldsValue`, `setFieldValue`, `setFieldsValue`, `getFieldError`,
|
|
857
|
+
`isFieldTouched`, `isFieldValidating`, `resetFields`, `validateFields`,
|
|
858
|
+
`scrollToField` and `submit`. Programmatic setters do not emit `onValuesChange`.
|
|
859
|
+
`useFormInstance()` reads the enclosing instance; `useWatch(name, form?)`
|
|
860
|
+
subscribes to one field. Do not attach one instance to multiple Forms at once.
|
|
861
|
+
|
|
862
|
+
FormItem binds one child control and preserves its change/blur handlers. Native
|
|
863
|
+
inputs use `value`; Checkbox/Switch use `valuePropName="checked"`. For array
|
|
864
|
+
controls provide `emptyValue={[]}`; MultiSelect additionally needs
|
|
865
|
+
`valuePropName="values"`, while DateRangePicker needs `emptyValue={['', '']}`.
|
|
866
|
+
`getValueFromEvent` adapts custom callback arguments. Custom controls must forward
|
|
867
|
+
the supplied id, aria attributes and blur callback to their actual control;
|
|
868
|
+
groups should supply their own `aria-label`. Errors use a live alert and are
|
|
869
|
+
linked to supporting controls with `aria-describedby`.
|
|
870
|
+
|
|
871
|
+
### Dynamic Form lists
|
|
872
|
+
|
|
873
|
+
`FormList` and `Form.List` are the same component; `Form.Item` aliases `FormItem`,
|
|
874
|
+
and `Form.useForm`, `Form.useFormInstance`, `Form.useWatch` alias the named hooks.
|
|
875
|
+
List callbacks receive `{ name: index, key: stableIdentity }[]`, operations
|
|
876
|
+
`add(value?, index?)`, `remove(index | indexes)` and `move(from, to)`, plus
|
|
877
|
+
`{ errors }`. Child field/list names are relative to their enclosing list.
|
|
878
|
+
Imperative instance methods and `useWatch` always use absolute paths.
|
|
879
|
+
|
|
880
|
+
```tsx
|
|
881
|
+
<Form initialValues={{ people: [{ name: 'Ada' }] }} onFinish={save}>
|
|
882
|
+
<Form.List name="people" rules={[{ required: true, message: 'Add a person' }]}>
|
|
883
|
+
{(fields, operations, meta) => (
|
|
884
|
+
<>
|
|
885
|
+
{fields.map((field) => (
|
|
886
|
+
<div key={field.key}>
|
|
887
|
+
<Form.Item name={[field.name, 'name']} label="Name" required>
|
|
888
|
+
<Input />
|
|
889
|
+
</Form.Item>
|
|
890
|
+
<Button onClick={() => operations.remove(field.name)}>Remove</Button>
|
|
891
|
+
</div>
|
|
892
|
+
))}
|
|
893
|
+
<Button onClick={() => operations.add({ name: '' })}>Add person</Button>
|
|
894
|
+
{meta.errors.map((error) => (
|
|
895
|
+
<p key={error} role="alert">
|
|
896
|
+
{error}
|
|
897
|
+
</p>
|
|
898
|
+
))}
|
|
899
|
+
</>
|
|
900
|
+
)}
|
|
901
|
+
</Form.List>
|
|
902
|
+
<Button type="submit">Save</Button>
|
|
903
|
+
</Form>
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
Always use `field.key` as React key and `field.name` in field paths. Moves and
|
|
907
|
+
insertions preserve the existing rows' identities. Structural list changes
|
|
908
|
+
clear descendant validation/touched metadata and invalidate pending validators
|
|
909
|
+
so errors cannot attach to the wrong row. List rules validate after operations;
|
|
910
|
+
child rules validate through blur/change/submit. `meta.errors` is rendered by the
|
|
911
|
+
host. Provider/Form disabled state prevents list operations. Arrays initialize
|
|
912
|
+
from Form `initialValues`; list-level `initialValue` is not supported.
|
|
913
|
+
|
|
914
|
+
`validateFields(names?)` validates each selected path and its registered
|
|
915
|
+
descendants; pass `{ recursive: false }` as its second argument for exact fields.
|
|
916
|
+
Validation errors preserve string names for legacy fields and array paths for
|
|
917
|
+
nested/list fields. Programmatic array replacements preserve keys by index;
|
|
918
|
+
reset remounts rows. Dynamic lists support nesting and multiple operations in
|
|
919
|
+
one event. There is no automatic dependency-validation engine in this batch.
|
|
920
|
+
|
|
921
|
+
### Form dependencies
|
|
922
|
+
|
|
923
|
+
`FormItem.dependencies` takes absolute form `NamePath[]`, including the complete
|
|
924
|
+
list prefix and index (e.g. `dependencies={[["users", 0, "password"]]}`). A user
|
|
925
|
+
change revalidates dependent fields that have been touched or previously
|
|
926
|
+
validated; pristine fields do not immediately display errors. Transitive
|
|
927
|
+
relationships are traversed once per field, including cyclic dependencies.
|
|
928
|
+
Validators receive a snapshot of all current values, and superseded async
|
|
929
|
+
results cannot overwrite newer validation results.
|
|
930
|
+
|
|
931
|
+
As in the reference AntD contract, programmatic `setFieldValue`/`setFieldsValue`
|
|
932
|
+
writes do not trigger dependency validation. Use `validateFields` explicitly
|
|
933
|
+
when required, and `useWatch` for conditional content. `shouldUpdate` and
|
|
934
|
+
render-function FormItem children remain unsupported.
|
|
935
|
+
|
|
936
|
+
### P1 pagination and display contracts
|
|
937
|
+
|
|
938
|
+
Pagination accepts controlled `page`/`pageSize` or `defaultPage` (1) /
|
|
939
|
+
`defaultPageSize` (20). Existing `onPageChange`/`onPageSizeChange` callbacks remain;
|
|
940
|
+
`onChange(page, pageSize)` combines them. Size changes reset to page 1.
|
|
941
|
+
`showSizeChanger`, `showQuickJumper` (true), `hideOnSinglePage`, `showTotal(total,
|
|
942
|
+
range)` and provider-aware `disabled` configure the footer. Displayed page/range
|
|
943
|
+
are clamped to valid finite totals and sizes. DataTable pagination retains its
|
|
944
|
+
required controlled page/pageSize/onPageChange contract.
|
|
945
|
+
|
|
946
|
+
Segment adds defaultValue, per-option/provider disabled state and vertical
|
|
947
|
+
orientation. Arrow/Home/End keys move focus and select enabled options; horizontal
|
|
948
|
+
arrows follow the provider's direction. Existing group/pressed-button semantics
|
|
949
|
+
are retained rather than exposing AntD radio-style markup.
|
|
950
|
+
|
|
951
|
+
Avatar accepts native span attributes/ref, children/icon fallback, numeric size,
|
|
952
|
+
circle/square shape and gap-based text scaling measured with ResizeObserver.
|
|
953
|
+
Images support srcSet (including srcSet-only), crossOrigin and loading; failure
|
|
954
|
+
falls back unless onError returns false, and changing src/srcSet retries.
|
|
955
|
+
The wrapper owns the accessible name; its image is decorative. Unicode initials
|
|
956
|
+
preserve graphemes with Intl.Segmenter (older engines use code points).
|
|
957
|
+
AvatarStack applies size/shape to every member and +N, and exposes hidden names
|
|
958
|
+
in the overflow label/title. IconAvatar supports numeric size/native span ref;
|
|
959
|
+
AvatarPlaceholder forwards native button attributes/ref and provider disabled.
|
|
960
|
+
Klun retains deterministic name colors, xs/sm/md/lg dimensions and people/max
|
|
961
|
+
stack data. AntD responsive breakpoint sizes, ReactNode src, Group children
|
|
962
|
+
context/popover and semantic style maps are not part of this contract.
|
|
963
|
+
|
|
964
|
+
Tag supports closable/onClose (preventDefault cancels removal), closeLabel,
|
|
965
|
+
checkable/checked/defaultChecked/onChange and disabled. Check and close use
|
|
966
|
+
separate native buttons so both interactions remain reachable by keyboard.
|
|
967
|
+
Color remains a CSS color; existing Klun variants and icons are preserved.
|
|
968
|
+
|
|
969
|
+
Card adds loading, cover, actions, bordered and hoverable; extra renders even
|
|
970
|
+
without a title. Loading hides pending children and announces status. Progress
|
|
971
|
+
maps nonfinite values to zero. Divider adds children/titlePlacement and dashed
|
|
972
|
+
rails with logical start/end alignment. These APIs preserve Klun's existing
|
|
973
|
+
geometry. Card now exposes Grid/Meta composition; semantic-style APIs remain outside the contract.
|
|
974
|
+
|
|
975
|
+
### P1 menu and navigation contracts
|
|
976
|
+
|
|
977
|
+
Menu retains action-menu defaults. Set `selectable` for selectedKeys /
|
|
978
|
+
defaultSelectedKeys / onSelectedKeysChange; `multiple` uses checkbox semantics
|
|
979
|
+
and keeps the menu open while toggling. Existing item.checked and onSelect(id)
|
|
980
|
+
remain available. openKeys / defaultOpenKeys / onOpenChange control expansion;
|
|
981
|
+
vertical/horizontal modes use popup submenus, inline mode displays nested rows.
|
|
982
|
+
Single leaf selection closes standalone popup submenus and the surrounding
|
|
983
|
+
Popover. Controlled state changes are requested through callbacks. Item IDs
|
|
984
|
+
must be unique throughout a hierarchy. Rich label children are searchable;
|
|
985
|
+
opaque labels can provide searchText. Arrow keys, Home/End, typeahead and disabled
|
|
986
|
+
choices work across supported modes; directions follow ConfigProvider.
|
|
987
|
+
|
|
988
|
+
Independent Menu/Select instances do not inherit the selection or expansion of
|
|
989
|
+
a containing menu. Only internal recursive submenus share that state. Klun's
|
|
990
|
+
item.id and onSelect(id) contracts remain distinct from AntD key/event objects;
|
|
991
|
+
AntD hover delays, horizontal overflow and inlineCollapsed are not supplied.
|
|
992
|
+
|
|
993
|
+
Nav stays route-controlled and adds provider-aware disabled, RTL arrows and
|
|
994
|
+
Home/End. Arbitrary IDs are matched as data, without CSS selector interpolation.
|
|
995
|
+
Sidebar adds controlled width/onWidthChange; finite min/max bounds apply to both
|
|
996
|
+
rendered dimensions and resizing, with RTL pointer/keyboard arithmetic and a
|
|
997
|
+
logical content-edge gutter. Collapsed sidebars are inert and hidden from the
|
|
998
|
+
accessibility tree. Existing mobile hiding and shell collapse provider remain.
|
|
999
|
+
|
|
1000
|
+
ContextMenu and ContextMenuList consume disabled defaults (explicit false wins).
|
|
1001
|
+
Disabled requests cannot open or persist an imperative menu; disabled parents
|
|
1002
|
+
hide and lock submenus. Context menu portals retain dir/lang, and submenu
|
|
1003
|
+
placement/navigation respects RTL. Pointer-bound menus remain separate from
|
|
1004
|
+
AntD Dropdown, keeping the existing openAt/row context and icon-strip contracts.
|
|
1005
|
+
|
|
1006
|
+
### P1 general feedback
|
|
1007
|
+
|
|
1008
|
+
`Empty` adds the general Empty entry alongside `EmptyState`: custom image nodes
|
|
1009
|
+
or image URLs, description (null/false hides it), children as actions and localized
|
|
1010
|
+
English/Chinese defaults. `Spin` supports controlled spinning, cancellable delay,
|
|
1011
|
+
custom indicator, description, three sizes and fullscreen; busy child content is
|
|
1012
|
+
inert until loading finishes. `Skeleton` preserves the original single block API
|
|
1013
|
+
and adds title/avatar/paragraph placeholders, static animation and loading=false
|
|
1014
|
+
content. `Result` supports success/error/info/warning and 403/404/500, custom icon,
|
|
1015
|
+
title, subtitle, actions and detail content; static results are not live alerts.
|
|
1016
|
+
|
|
1017
|
+
These entries reuse Klun tokens and existing feedback primitives. AntD's semantic
|
|
1018
|
+
classNames/styles API, global indicator setter and Spin auto-percent animation
|
|
1019
|
+
are not exposed. Existing Progress retains the 0–1 value contract in Card.
|
|
1020
|
+
|
|
1021
|
+
### P1 Slider and Rate
|
|
1022
|
+
|
|
1023
|
+
`Slider` preserves native single-value `onChange(event)` and adds a discriminated
|
|
1024
|
+
`range` mode with `[start,end]` value/defaultValue/onChange, distinct form names,
|
|
1025
|
+
non-crossing handles, dynamic accessible bounds, step normalization, marks,
|
|
1026
|
+
vertical layout, native title tooltips and onChangeComplete. The forwarded ref
|
|
1027
|
+
points to the first native input. Tooltips use the browser title UI, not a popup;
|
|
1028
|
+
AntD's editable multi-handle range, draggable whole track and null-step marks-only
|
|
1029
|
+
selection are not exposed.
|
|
1030
|
+
|
|
1031
|
+
`Rate` adds count, allowHalf, hover preview/onHoverChange, per-star tooltips and
|
|
1032
|
+
custom characters. Native same-name radios keep form submission and arrow keys;
|
|
1033
|
+
readonly values expose one accessible rating name. Clear remains an explicit
|
|
1034
|
+
button. Half-star labels expose each 0.5 choice so keyboard and pointer interaction
|
|
1035
|
+
share the same discrete values.
|
|
1036
|
+
|
|
1037
|
+
### P1 general Progress
|
|
1038
|
+
|
|
1039
|
+
`Progress` keeps value in 0–1 and adds percent in 0–100 (value takes precedence),
|
|
1040
|
+
line/circle/dashboard, active/success/exception styling, segmented steps, bounded
|
|
1041
|
+
success overlays, custom colors/format/ARIA naming, size/stroke controls and
|
|
1042
|
+
logical dashboard gap placement in RTL. showInfo controls formatted percentages;
|
|
1043
|
+
showValue remains the existing line label option. SVG rings use local paths;
|
|
1044
|
+
AntD gradient objects, arbitrary semantic styles and percentage-position variants
|
|
1045
|
+
are not part of this API.
|
|
1046
|
+
|
|
1047
|
+
### P1 Tabs, Collapse and Steps
|
|
1048
|
+
|
|
1049
|
+
`Tabs` adds top/bottom/start/end placement, RTL and vertical keyboard navigation,
|
|
1050
|
+
provider disabled, card/editable-card, add/remove requests and focus recovery after
|
|
1051
|
+
closing either active or inactive tabs. Hosts own edited items via onEdit(action,
|
|
1052
|
+
key). Dynamic removal repairs uncontrolled selection without resurrecting stale
|
|
1053
|
+
keys. keepMounted preserves the previous API; item forceRender and destroyOnHidden
|
|
1054
|
+
control content lifecycle. forceRender takes precedence over destroyOnHidden,
|
|
1055
|
+
as in the underlying rc-motion stable hidden branch. Overflow uses native scrolling.
|
|
1056
|
+
|
|
1057
|
+
`Collapse` adds provider disabled, Up/Down/Home/End header focus, independent extra
|
|
1058
|
+
actions, borderless/ghost and keepMounted=false teardown; accordion ignores keys
|
|
1059
|
+
for removed items. Extra actions are separate controls outside the toggle button.
|
|
1060
|
+
`Steps` adds item status/icon/subTitle, initial numbering and current/onChange
|
|
1061
|
+
absolute step offsets, localized status, provider disabled and direction keys that
|
|
1062
|
+
move focus without changing the step until activation. Horizontal responsive
|
|
1063
|
+
stacking remains the existing CSS behavior.
|
|
1064
|
+
|
|
1065
|
+
AntD animated panel motion, tabs automatic overflow menu/custom tab-bar rendering,
|
|
1066
|
+
Steps panel/dot types and semantic styling are separate remaining differences.
|
|
1067
|
+
|
|
1068
|
+
### P1 input and action enhancements
|
|
1069
|
+
|
|
1070
|
+
Input preserves the native input ref and event contract. It adds `sm`, prefix/suffix,
|
|
1071
|
+
`allowClear`, `showCount` (UTF-16 length, optional formatter), warning/error status and
|
|
1072
|
+
outlined/filled/borderless/underlined variants. Clearing emits the native input event
|
|
1073
|
+
and restores focus; read-only/disabled fields hide the clear button. Runtime feature
|
|
1074
|
+
changes preserve the input node and uncontrolled value. Native form reset updates counts.
|
|
1075
|
+
PasswordInput inherits these props. Textarea retains its existing native API.
|
|
1076
|
+
|
|
1077
|
+
Button adds dashed/link variants, round/circle shape, ghost and danger combinations.
|
|
1078
|
+
ActionButton and Switch support loading (busy and disabled). Switch supports checked /
|
|
1079
|
+
unchecked text and Left=off / Right=on keyboard operation; its native checkbox events,
|
|
1080
|
+
form value and ref remain intact. RadioGroup and CheckboxGroup options accept native
|
|
1081
|
+
id/title/required/style/change handlers; checkbox changes report registered values in
|
|
1082
|
+
option order. Group values remain strings to preserve the existing typed API. AntD
|
|
1083
|
+
semantic styles, delayed loading, numeric group values and boolean Switch value aliases
|
|
1084
|
+
are not provided by these native-control APIs.
|
|
1085
|
+
|
|
1086
|
+
### P1 inline feedback enhancements
|
|
1087
|
+
|
|
1088
|
+
Badge adds rich counts, status/text, custom color, small size, logical attached offsets,
|
|
1089
|
+
null/false title suppression and native span attributes/ref. Numeric overflow keeps the
|
|
1090
|
+
full accessible description; invalid numeric counts are hidden. The original explicit
|
|
1091
|
+
`dot` remains visible at zero. Processing uses a reduced-motion-aware pulse. AntD Ribbon
|
|
1092
|
+
and animated rolling digits remain compatibility gaps.
|
|
1093
|
+
|
|
1094
|
+
Alert adds a `title` alias (preferred over message), warning banner, filled variant,
|
|
1095
|
+
custom decorative icon, native div attributes/ref and configurable close button. Close
|
|
1096
|
+
handlers may preventDefault; inherited disabled can be explicitly overridden. Controlled
|
|
1097
|
+
hosts retain ownership of visibility. afterClose runs after actual removal, once, with no
|
|
1098
|
+
exit animation. Existing showIcon=true and open/defaultOpen contracts remain unchanged.
|
|
1099
|
+
AntD semantic style callbacks and animated exit are not implemented.
|
|
1100
|
+
|
|
1101
|
+
### `InputNumber`
|
|
1102
|
+
|
|
1103
|
+
Numeric `value/defaultValue` and `onChange(number | null)` integrate with Form; native
|
|
1104
|
+
input ref/attributes, affixes, status and variants come from Input. Invalid/incomplete
|
|
1105
|
+
editing drafts stay visible while focused, and valid in-range edits update the value.
|
|
1106
|
+
Blur aligns range/precision and restores the host's controlled value. External values
|
|
1107
|
+
update focused drafts. Step controls and Up/Down support Shift×10, disabled/read-only,
|
|
1108
|
+
precision, formatter/parser and onStep. Uses JavaScript numbers (small IEEE-754 artifacts
|
|
1109
|
+
are rounded without truncating large precise values); AntD stringMode/high-precision arithmetic and press-and-hold are gaps.
|
|
1110
|
+
`formatter` receives userTyping/input to preserve caret-friendly drafts. Composition
|
|
1111
|
+
commits once at its end, with modified/IME navigation protected; finite stepping rejects
|
|
1112
|
+
unrepresentable results and bound no-ops without calling onStep. Step controls use locale.
|
|
1113
|
+
Host formatter/parser exceptions remain host-owned; no stringMode or arbitrary precision.
|
|
1114
|
+
|
|
1115
|
+
### `AutoComplete`
|
|
1116
|
+
|
|
1117
|
+
Editable string value, options `{value,label?,disabled?,searchText?}`, filtering/custom
|
|
1118
|
+
filter, onSearch/onSelect, controlled open, clear and native ref. Combobox focus stays
|
|
1119
|
+
in the input; Up/Down skip disabled options, active choices scroll into view, Enter
|
|
1120
|
+
selects, Escape closes. IME composition avoids premature search/selection. Empty options
|
|
1121
|
+
never render a popup. Uses the existing Popover with autofocus disabled; grouped options,
|
|
1122
|
+
virtual suggestions and arbitrary custom input children remain compatibility gaps.
|
|
1123
|
+
Selecting the existing value still calls onSelect but not onChange/onSearch. Disabled or
|
|
1124
|
+
read-only drops uncontrolled popup state; explicit controlled open remains host-owned.
|
|
1125
|
+
Modified and key229 navigation is ignored. Native input form/reset semantics are retained.
|
|
1126
|
+
|
|
1127
|
+
### `TreeSelect`
|
|
1128
|
+
|
|
1129
|
+
Tree data uses `{value: string,title,children?,disabled?,disableCheckbox?,selectable?,isLeaf?}`.
|
|
1130
|
+
Single values are string/null; multiple or treeCheckable values are string arrays. Change
|
|
1131
|
+
receives values and labels. Reuses Tree expansion, lazy loading, checks, search and virtual
|
|
1132
|
+
scrolling via treeProps; lazy node identities and selected labels survive parent renders.
|
|
1133
|
+
Checkbox mode selects via checkboxes and returns Tree's full checked keys; AntD strategy
|
|
1134
|
+
constants / labelInValue / numeric values are compatibility gaps. Native trigger ref,
|
|
1135
|
+
ARIA, hidden named form values, clear, controlled open and Form blur validation are supported.
|
|
1136
|
+
Node identities remain nonempty strings as required by Tree (null clears). Repeated identical selection does not
|
|
1137
|
+
notify onChange. Locale covers placeholder/search/clear; explicit disabled=false reaches
|
|
1138
|
+
both search and Tree under a disabled provider. Disabling drops uncontrolled popup state.
|
|
1139
|
+
Search clears on actual close; rejected controlled close requests retain the search.
|
|
1140
|
+
|
|
1141
|
+
### `TimePicker`
|
|
1142
|
+
|
|
1143
|
+
Native local-clock input: string HH:mm / HH:mm:ss (empty clears), min/max, second-based
|
|
1144
|
+
step, native ref/attributes, Input affixes/variants/clear, Form and ConfigProvider. DisabledTime
|
|
1145
|
+
marks unavailable values invalid without discarding drafts, with a localized validity
|
|
1146
|
+
message. Native min/max supports overnight ranges; repeated same-value changes do not
|
|
1147
|
+
notify. Values remain local clock strings and explicit disabled=false is supported. No Date or timezone conversion.
|
|
1148
|
+
The native picker provides localized interaction; AntD Dayjs, custom time columns, range
|
|
1149
|
+
picker, 12-hour formatting and disabled unit callbacks are not provided by this entry.
|
|
1150
|
+
|
|
1151
|
+
### General information display
|
|
1152
|
+
|
|
1153
|
+
`Breadcrumb` complements Crumbs with native links, configurable separators, disabled
|
|
1154
|
+
items, custom rendering and current-page semantics. `Descriptions` complements KeyValue
|
|
1155
|
+
with responsive columns (xs→xxxl), horizontal/vertical layout, borders, header/extra and
|
|
1156
|
+
bounded spans; overflow spans truncate to the current row, and the final cell fills it.
|
|
1157
|
+
Breadcrumb labels follow locale, a null per-item separator hides it; host itemRender owns
|
|
1158
|
+
its own interaction/disabled behavior. Descriptions preserves zero labels and values.
|
|
1159
|
+
Both forward native attributes/ref. Legacy Crumbs and KeyValue APIs remain intact.
|
|
1160
|
+
|
|
1161
|
+
`Statistic` complements Metric with string-preserving digit grouping, configurable
|
|
1162
|
+
separators/precision, prefix/suffix, formatter, loading and value style. Precision truncates
|
|
1163
|
+
and pads decimals as in AntD's Number.tsx; fractional-only strings gain a leading zero,
|
|
1164
|
+
empty string displays zero, punctuation-only strings remain raw; it does not round or convert big integer strings.
|
|
1165
|
+
Timer/countdown and semantic style callbacks remain compatibility gaps.
|
|
1166
|
+
|
|
1167
|
+
`Typography.Text/Title/Paragraph/Link` provide native text/heading/link semantics, emphasis,
|
|
1168
|
+
code/keyboard/mark/delete, CSS multi-line ellipsis with controlled expansion, copying and
|
|
1169
|
+
editing. Clipboard errors expose retry and invoke onError; async copy stays busy. Editing
|
|
1170
|
+
accepts empty strings, supports Enter-save/Escape-cancel and restores focus; disabled
|
|
1171
|
+
configuration blocks actions. Copy/edit labels follow locale, and copy requires
|
|
1172
|
+
the native Clipboard API. Measurement-based suffix ellipsis, autosizing editor, semantic
|
|
1173
|
+
styling and HTML clipboard formats remain gaps. Link uses safe defaults for target=_blank.
|
|
1174
|
+
|
|
1175
|
+
### Layout / Grid / Flex / Space / Splitter
|
|
1176
|
+
|
|
1177
|
+
Layout 提供 Header/Footer/Content/Sider;Sider 支持受控/默认折叠、零宽、响应式断点、触发器和折叠原因回调。Sider仅实际折叠状态变化通知onCollapse,onBreakpoint仍报告初始/变化断点;支持locale与显式disabled=false、有限非负数字width。Sider xxxl保持AntD1840阈值,Grid xxxl保留原库1920,不强改已有断点。Row/Col 使用 24 栅格、逻辑方向 gutter/offset/push/pull、响应式尺寸/排列;Grid.useBreakpoint 返回断点状态。Flex 使用原生 CSS flex,有限非负数字gap;Col数字flex/order防止NaN/Infinity;Space 支持间距、分隔及 Compact 输入/按钮连接。
|
|
1178
|
+
|
|
1179
|
+
Splitter.Panel 提供数字像素或百分比 size/defaultSize/min/max,受控尺寸、指针/方向键/Home/End 调整、折叠恢复、保留或销毁隐藏内容。回调返回像素尺寸,宿主控制 size 时必须写回才能持久更新;尺寸计算扣除每个 8px 分隔条。整组受控尺寸按可用空间比例归一化,部分受控面板保持固定尺寸。未提供 size 的面板内部管理调整结果。拖动结束/取消/lost capture只提交当前pointer draft一次,非当前pointer不终止;axis/RTL/extent/disabled/panel身份变化使旧draft失效,修饰键/IME不resize;不可满足pair min/max时保留当前分配而不制造越界。复杂对象 collapsible、拖动预览延迟、多panel穿透resize、dragger doubleclick、AntD semantic 样式入口仍未提供。
|
|
1180
|
+
|
|
1181
|
+
### Dropdown / Popconfirm
|
|
1182
|
+
|
|
1183
|
+
Dropdown 使用原生 Button 触发器(children 是按钮内容,ref 指向按钮),menu 接收现有 MenuProps。支持 open/defaultOpen/onOpenChange、方向键打开、嵌套菜单、禁用、选择关闭及现有 Placement 定位。IME/key229/修饰键不打开;外部loading阻止内置交互,禁用/loading丢弃非受控开关但保留host受控open,重复相同开关不通知。多选菜单遵循 Menu 保留打开的规则。未复制 AntD 的任意子元素克隆、hover/contextMenu 触发、Dropdown.Button 或 popupRender 扩展。
|
|
1184
|
+
|
|
1185
|
+
Popconfirm 同样使用原生 Button 触发器,title 是字符串可访问名称,description 支持 ReactNode。onConfirm 可以异步,false 保留打开,拒绝会显示重试提示并通知 onError;等待期间阻止重复、取消和外部关闭。onCancel 表示取消按钮操作。受控 open 必须由宿主写回,禁用/关闭/卸载使旧请求结果失效。使用现有 Popover 的焦点恢复和上下文;文本可通过 okText/cancelText 自定义,locale提供确认/取消/失败重试默认,0 description和button内容不丢失。外部loading隐藏内置操作;禁用丢弃非受控popup且使pending generation失效,受控open仍由host拥有。未实现参考的任意子元素触发、函数 title/description、箭头和完整 semantic 样式。
|
|
1186
|
+
|
|
1187
|
+
### Drawer
|
|
1188
|
+
|
|
1189
|
+
Drawer 复用 Dialog 的模态栈、焦点循环/恢复、滚动锁及配置上下文。open 由宿主管理;placement 支持 top/right/bottom/left 物理边缘,RTL 不交换指定边缘。width/height 接收像素数字或 CSS 长度并限制到视口;默认 378px,非法非有限数字回退378,负数归0。title/tools/footer/bodyClassName/style 使用 Dialog 协议,keyboard/maskClosable/closable 独立控制关闭方式;dismissable 仍作为前两项默认值。关闭时销毁内容,原 DetailSheet 业务组件保持独立。参考的 push、resizable、destroyOnHidden=false、动画结束回调、非模态/自定义挂载与 semantic 样式尚未提供。
|
|
1190
|
+
|
|
1191
|
+
### Image
|
|
1192
|
+
|
|
1193
|
+
Image 使用真实原生 img,alt 必填,ref 指向图片;src/fallback/placeholder 处理加载及失败,原生 img 属性透传。preview=false 关闭预览,配置对象支持 open/defaultOpen/onOpenChange/src;预览使用 Dialog,提供缩放、旋转、重置和焦点恢复。disabled 消费配置,取消 onClick 默认行为可阻止打开。className/style 作用于包裹容器,width/height 作用于 img。
|
|
1194
|
+
|
|
1195
|
+
预览/工具/关闭沿用locale;禁用丢弃非受控预览,受控open仍由host持有。旋转按360度归一化,0 placeholder可见。
|
|
1196
|
+
|
|
1197
|
+
Image.PreviewGroup 使用显式 items(src/alt)列表,支持 current/defaultCurrent/onChange、受控开关和前后导航;重复打开当前图片不重复通知onChange;子 Image 的 src 匹配列表时打开分组,否则打开独立预览。未实现参考的自动子图片注册、拖动/滚轮/翻转、下载、自定义动作、进度/semantic 样式;业务 FilePreview 仍仅展示附件元数据,不代替此真实图片组件。
|
|
1198
|
+
|
|
1199
|
+
### Upload
|
|
1200
|
+
|
|
1201
|
+
Upload 的 originFileObj 是实际 File,ref 指向原生 file input,children 是按钮内容。默认无传输,只保留手动列表;指定 action 后发送 POST multipart(name/data/headers/withCredentials),或 customRequest 获得实际 file 和 progress/success/error 回调,可返回 abort。成功 response 是 XHR 原始文本,由宿主解析。
|
|
1202
|
+
|
|
1203
|
+
beforeUpload 支持异步,false 保留手动项,Upload.LIST_IGNORE 忽略,File/Blob 转换实际字节;失败(包括falsy拒绝原因)保留 error 项。accept 在选择和拖放时都检查,multiple/maxCount 控制数量,maxCount=1 替换并取消旧请求。fileList/defaultFileList/onChange 提供受控/默认列表,onRemove false 或拒绝保留文件;删除/卸载后旧回调不再更新;异步移除结束检查最新列表,已移除项不重复通知。异步预处理完成后使用最新传输配置/maxCount/回调;禁用期间不开始新请求,已开始的请求仍由移除/卸载取消。中文locale覆盖列表与控件;显式disabled=false传给内置按钮。列表只展示文本/进度/错误和删除,不自动渲染不可信文件链接。beforeUpload 是客户端检查,服务端仍需验证文件。目录、粘贴、缩略图列表、自动重试、任意 trigger 克隆、动态 action/data、完整 semantic 样式仍为参考扩展差距;AttachmentUpload 业务元数据契约保持独立。
|
|
1204
|
+
|
|
1205
|
+
### App / message / notification
|
|
1206
|
+
|
|
1207
|
+
App 内包含独立 ToastProvider 栈,message 默认顶部居中,notification 默认右上,配置支持 placement/max,嵌套 App 按字段继承父配置但各自持有独立栈;max=0 抑制展示;默认右上通知在窄屏移至右下以避免与顶部 message 重叠。放在 ConfigProvider 内即可继承 direction/locale。App.useApp() 返回最近 App 的绑定 API;根导出的 message/notification 调用最后注册且仍挂载的 App,没有宿主时抛出明确错误,不创建丢失上下文的独立根。
|
|
1208
|
+
|
|
1209
|
+
message.open({content,type,key,duration,onClose})、notification.open({message,description,type,key,duration,onClose}) notification 返回可用于 destroy 的字符串 key;message 返回可调用关闭且可 await 的句柄(key 属性可用于 destroy),提供 info/success/warning/error/loading,loading 默认持续至关闭。duration 继续使用 Klun 的毫秒契约,0 为持久;destroy() 删除本栈全部,destroy(key) 删除指定项。同 key 更新替换原内容并重置计时,注册的 onClose 在最终移除时各执行一次;封顶删除和卸载清理计时器。已关闭句柄再次调用不会删除后来复用相同 key 的消息;批量移除先清理旧项,再执行全部回调,回调抛错仍结清所有等待者并保留新消息计时,随后向宿主抛出首个错误。悬停或键盘焦点暂停正数计时,离开后沿用原有 1500ms 宽限;持久项不会因悬停而关闭。现有 useToast.push/dismiss 保持兼容,新增 key/onClose 和无参数 dismiss。
|
|
1210
|
+
|
|
1211
|
+
参考的独立 useMessage/useNotification contextHolder、自定义静态根/config、可堆叠折叠/进度条、App DOM wrapper/modal API 和任意挂载点有意不提供;静态 API 推荐只在单根 App 中使用,多根/嵌套场景使用 App.useApp 绑定准确上下文。
|
|
1212
|
+
|
|
1213
|
+
### Form 条件项与字段生命周期
|
|
1214
|
+
|
|
1215
|
+
无 name 的 Form.Item 可接收 `(form) => ReactNode`,shouldUpdate=true 默认监听值变化,比较函数接收前后值快照;单独 dependencies 时只跟随指定路径变化。noStyle 支持无名输出或命名控件的 display:contents 包装。命名项仍要求单个可绑定控制元素。
|
|
1216
|
+
|
|
1217
|
+
Form/Item preserve 默认 true,Item 可覆盖 Form。preserve=false 实际卸载后恢复 Form initialValues,无初始值则删除路径;列表子字段没有单字段初始值,且清理保护列表重排/移位、StrictMode 重注册、父列表整体卸载和宿主最新写值。卸载清理在微任务中发生,读取最终值时等待提交后的微任务。字段错误与请求元数据同时清理。scrollToField 支持 focus/block/behavior,保持原默认聚焦;focusField 只定位可见、可用控制,不聚焦隐藏输入或禁用字段集。
|
|
1218
|
+
|
|
1219
|
+
validateTrigger 支持 onChange/onBlur、事件数组及 false;false 关闭自动校验,显式 validateFields/submit 仍校验。保持 Klun 默认 onBlur,已出现错误的字段在修改时自动复验(false 除外)。scrollToFirstError 支持 false 或 focus/block/behavior,保持 Klun 默认 true;AntD 默认不自动滚动,这一差异用于兼容既有调用。
|
|
1220
|
+
|
|
1221
|
+
### Calendar / Timeline
|
|
1222
|
+
|
|
1223
|
+
Calendar 是独立月/年日历,value/defaultValue 使用 YYYY-MM-DD ISO 字符串,与 DatePicker 共用校验与日期运算;mode/defaultMode 为 month/year,fullscreen=false 为紧凑单元格。onChange 只在日期变化时触发,onSelect 额外给出 date/month/year/customize 来源;onPanelChange 在面板年月或模式改变时通知。validRange 是含端点有效范围,disabledDate 与 ConfigProvider.disabled 组合限制选择。cellRender 追加内容,fullCellRender 替换内容;headerRender 接收 value/type/onChange/onTypeChange,自定义操作仍受范围/禁用限制。网格方向键/Home/End/PageUp/PageDown 支持跨月聚焦和 RTL。时间、周编号和 Dayjs 类型不属于这一入口,保留 Klun 日期字符串契约。
|
|
1224
|
+
|
|
1225
|
+
Timeline 使用语义 ol/li,items 支持 key/title/content/icon/color/loading/placement,以及 AntD 的 label/children/dot 别名。pending 追加加载项,reverse 复制后反转,不改宿主数组;orientation 为 vertical/horizontal,mode 为 start/end/alternate(left/right 兼容逻辑别名)。空数据输出空列表,具体空状态由宿主组合 Empty;水平列表在窄屏内部滚动,颜色和布局随主题/方向变化。业务 TransitionsTimeline 仍负责活动含义与时间格式,不混入通用数据模型。
|
|
1226
|
+
|
|
1227
|
+
### List / Listy / Masonry
|
|
1228
|
+
|
|
1229
|
+
List 泛型 dataSource/renderItem/rowKey 配合现有 Pagination(Klun 的 page/pageSize 命名)、受控/非受控页码和容量;数据缩短会夹到有效页。header/footer/loadMore、bordered/split/size/itemLayout、grid 响应式列数与 gutter、loading 和 emptyText 可组合。List.Item 支持 actions/extra,List.Item.Meta(也导出 ListItem/ListItemMeta)支持 avatar/title/description;原生 li 保留,不产生嵌套列表项。children 分页忽略 null/false,与总数采用同一集合。
|
|
1230
|
+
|
|
1231
|
+
Listy 为独立泛型长列表,items/rowKey/itemRender、group.key/title、sticky、height 和 virtual。无有效 height 时使用正常流;virtual=true 使用固定 itemHeight(默认44,分组标题也同高),只渲染可见区及3行缓冲,并保留完整滚动高度与 aria-posinset/setsize。变高内容请使用普通 Listy 或 Masonry,不承诺 rc-listy 动态测量行高。ref.nativeElement 和 scrollTo(number / {top,left} / {key,align,offset} / {groupKey,align,offset}) 支持定位;align 为 top/bottom/auto。分组保持首次出现的分组顺序,itemRender 的 index 保留原数据索引;可访问序号按最终分组顺序。
|
|
1232
|
+
|
|
1233
|
+
Masonry items 的 key/data/children/height/column 与 itemRender 配合;columns 支持断点对象,gutter 支持数字或 [横向,纵向]。使用原生 ResizeObserver 测实际单元高度,依次放入最短列;column 可固定列且夹到有效范围,改变高度/列数/内容自动重算。DOM 顺序保持数据顺序,RTL 使用逻辑位置。onLayoutChange 通知 key/column 分配变化,不复制 AntD motion/fresh 动画或语义样式注入。旧浏览器无 ResizeObserver 时仅挂载/属性更新时测量;宿主需要动态媒体尺寸更新应提供原生 ResizeObserver 支持。
|
|
1234
|
+
|
|
1235
|
+
### Affix / Anchor / FloatButton / BackTop
|
|
1236
|
+
|
|
1237
|
+
Affix 在 window 或 target() 返回的滚动容器边缘固定同一个子 DOM,offsetTop 默认0、offsetBottom 可选;占位保留测量高度,滚动/resize/原生 ResizeObserver 重算位置,onChange 仅通知固定状态变化。ref.nativeElement/updatePosition 可主动更新;无目标解除固定,卸载移除监听和动画帧。使用 CSS fixed,宿主须避免会改变 fixed 包含块的 transformed 祖先;不引入复制节点或门户导致表单/焦点重新挂载。
|
|
1238
|
+
|
|
1239
|
+
Anchor 是 nav/原生链接,items 支持 key/href/title/children/target/disabled,提供纵横方向、affix、offsetTop/targetOffset/bounds、getContainer、getCurrentAnchor、onChange/onClick 和 replace。字面 ID 使用 getElementById/decodeURIComponent;只拦截同页普通主键点击,Ctrl/Meta/外部 target 保持浏览器行为,preventDefault 可取消。href 只接受 HTTP/HTTPS/mailto/tel 或相对地址,不执行脚本协议。消费 ConfigProvider disabled/locale,滚动检测活动章节。更换容器时更新 getContainer 函数身份,以重新绑定监听;不复制弃用 Anchor.Link 或 semantic 样式。
|
|
1240
|
+
|
|
1241
|
+
FloatButton 保留 Button 原生属性、ref、variant 和原生 type,扩展 icon/content(description 别名)/shape/tooltip/badge;icon-only 需 aria-label 或文字 tooltip。FloatButton.Group(也导出 FloatButtonGroup)支持常驻组与 click/hover、open/defaultOpen/onOpenChange,禁用原生字段集阻止所有按钮;Escape 关闭后恢复内部焦点,鼠标离开但键盘仍在组内时保留,随后失焦关闭。逻辑角落位置可通过 style 覆盖;不重复实现链接按钮协议或语义样式注入。
|
|
1242
|
+
|
|
1243
|
+
AntD 6.6.5 独立 BackTop 已弃用并推荐 FloatButton.BackTop;Klun 同时提供这两个入口并复用同一实现。target 接受 Window/Document/HTMLElement,visibilityHeight 默认400、showProgress 显示0–100滚动进度;behavior 默认 smooth,系统减少动画时自动 auto。onClick.preventDefault 可取消滚动,target 不存在时隐藏,监听在卸载时移除。沿用浏览器平滑滚动,不提供毫秒 duration 动画引擎。
|
|
1244
|
+
|
|
1245
|
+
## Mentions
|
|
1246
|
+
|
|
1247
|
+
Native textarea ref; string value/defaultValue/onChange integrates with Form. options accepts value/label/disabled;
|
|
1248
|
+
prefix supports one or multiple nonempty tokens, split defaults to space. Searches the last prefix before the collapsed caret,
|
|
1249
|
+
filters case-insensitively by value (filterOption=false for remote search), invokes onSearch(query,prefix), and inserts onSelect.
|
|
1250
|
+
IME delays suggestions until composition ends. Up/Down skips disabled options and scrolls the active option into view;
|
|
1251
|
+
Enter inserts without submitting a form, Escape closes, and Tab retains normal navigation. onKeyDown may cancel default handling.
|
|
1252
|
+
Loading and notFoundContent represent pending/empty results. Mentions.getMentions parses completed prefix tokens.
|
|
1253
|
+
Controlled refusal leaves the original text and focus unchanged after the selection event. Disable/readOnly suppress editing suggestions.
|
|
1254
|
+
|
|
1255
|
+
Compared with AntD 6.6.5 and @rc-component/mentions 1.12.0: textarea anchored Popover rather than mirrored caret geometry;
|
|
1256
|
+
no deprecated Option children, semantic styles, popup container or auto-size wrapper. The replacement reuses matching trailing text
|
|
1257
|
+
and adds split boundaries without deleting unrelated trailing characters. Multiple-character split is supported.
|
|
1258
|
+
|
|
1259
|
+
## ColorPicker
|
|
1260
|
+
|
|
1261
|
+
Native Button ref; string/null or gradient stop array controlled/default values, onChange(value), onChangeComplete(value), controlled open/defaultOpen/onOpenChange.
|
|
1262
|
+
Solid colors and each gradient stop accept #RGB/#RGBA/#RRGGBB/#RRGGBBAA, comma RGB/RGBA (including percentages), HSB/HSBA with percentage saturation/brightness,
|
|
1263
|
+
and transparent. Invalid/out-of-range input is rejected before callbacks or swatch CSS; unsupported external values display an empty swatch.
|
|
1264
|
+
HEX/RGB/HSB format switching changes presentation; native color input and keyboard-operable hue/saturation/brightness/opacity ranges edit values.
|
|
1265
|
+
HSB stays internal for grayscale/black so changing opacity or restoring saturation retains hue. disabledAlpha forces opacity on user edits.
|
|
1266
|
+
Completion fires on typed commit, presets, clear, range release/navigation or native picker blur. allowClear emits null and onClear.
|
|
1267
|
+
Presets label/colors/defaultOpen, showText, panelRender and resolved global disabled settings are supported.
|
|
1268
|
+
|
|
1269
|
+
Compared with AntD 6.6.5 and @rc-component/color-picker 3.1.1: strings replace AggregationColor objects;
|
|
1270
|
+
uses native color selection and accessible channel ranges rather than a custom 2D drag plane. Gradient values use {color,percent}[]; native stop selection/add/remove/position editing supports at least two stops, validates CSS, sorts only the preview and preserves input order. mode selects available single/gradient modes; controlled values determine the current mode. No custom stop drag plane, hover trigger, semantic styles or popup mounting.
|
|
1271
|
+
|
|
1272
|
+
## Carousel
|
|
1273
|
+
|
|
1274
|
+
Single-visible-slide carousel; current/initialSlide/onChange, beforeChange/afterChange, ref nativeElement/goTo/next/prev.
|
|
1275
|
+
Finite/infinite bounds, arrow/dot navigation, horizontal/vertical/RTL keyboard, optional native pointer swipe,
|
|
1276
|
+
fade/scrollx entrance effects and logical dot placement. Inactive slides stay mounted but hidden and unfocusable.
|
|
1277
|
+
Autoplay pauses on pointer hover, focus, document hiding or reduced motion; a Play/Pause control is always available.
|
|
1278
|
+
Changing speed during navigation does not discard the completion event; unmount or later navigation cancels superseded timers.
|
|
1279
|
+
Compared with fixed AntD/react-slick: no clone track, multi-slide/slick settings, internal slider or legacy autoplay imperative API;
|
|
1280
|
+
CSS entry transitions replace outgoing track animation. initialSlide is the uncontrolled seed, current controls later changes.
|
|
1281
|
+
|
|
1282
|
+
## Tour
|
|
1283
|
+
|
|
1284
|
+
Target-aware modal tour reuses Dialog's stack, keyboard trapping, Escape, focus restoration and scroll lock;
|
|
1285
|
+
Dialog now accepts maskStyle/maskContent for custom visual masks. steps title/description/cover/target/placement/mask,
|
|
1286
|
+
current/defaultCurrent/onChange, open/defaultOpen/onOpenChange, onClose(current)/onFinish.
|
|
1287
|
+
Default open is true when steps exist (reference behavior). Target is scrolled into view, followed on scroll/resize,
|
|
1288
|
+
and highlighted through an SVG mask; missing targets center the panel. Gap, mask color, primary border,
|
|
1289
|
+
custom indicators/actions and cancellable next/previous button props are supported. Resolved disabled=false overrides provider disable.
|
|
1290
|
+
Compared with @rc-component/tour: target interactions remain blocked during this modal flow;
|
|
1291
|
+
no nonmodal focus behavior, animation placeholder, arbitrary popup mounting or semantic styles. Positions use viewport bounds.
|
|
1292
|
+
|
|
1293
|
+
## QRCode
|
|
1294
|
+
|
|
1295
|
+
Uses the exact reference @rc-component/qrcode 2.0.0 encoder, rather than decorative modules. SVG default/canvas,
|
|
1296
|
+
UTF-8 strings or segment arrays, errorLevel L/M/Q/H, boostLevel, four-module quiet margin,
|
|
1297
|
+
size/color/bgColor, embedded icon/imageSettings, bordered, active/loading/expired/scanned and refresh/custom status controls.
|
|
1298
|
+
Native wrapper ref. Empty values have a visible state; excessive payloads show an alert rather than crashing callers;
|
|
1299
|
+
valid value changes recover an encoding failure. Keep high contrast and quiet margins for scanning.
|
|
1300
|
+
The exact encoding package is a build-time dependency bundled into the artifact with its MIT notices; public types do not reference it. jsqr is a development-only independent decoder used by tests.
|
|
1301
|
+
SVG default intentionally differs from AntD canvas default, with no semantic style injection or QR internals exposed.
|
|
1302
|
+
|
|
1303
|
+
## Watermark
|
|
1304
|
+
|
|
1305
|
+
Native repeated DOM tiles support text/multiple styled lines, native image/failure fallback, font, rotation,
|
|
1306
|
+
width/height, gap/offset and zIndex; ResizeObserver follows content dimensions. Text and controls remain usable.
|
|
1307
|
+
Native root ref. MutationObserver reattaches the same removed overlay or tile and restores altered overlay styles,
|
|
1308
|
+
then invokes onRemove. Normal React dimension/content/style updates do not count as tampering.
|
|
1309
|
+
Compared with AntD: DOM marks replace raster canvas caching, image requests use native browser loading,
|
|
1310
|
+
no inherited watermark context; tamper repair is visual deterrence, never access control.
|
|
1311
|
+
Very dense surfaces are limited to 4096 tiles; use larger tile/gap values for large scroll documents.
|
|
1312
|
+
|
|
1313
|
+
## BorderBeam
|
|
1314
|
+
|
|
1315
|
+
A layout wrapper with native root ref adds pointer-transparent SVG perimeter segments, independent of child DOM refs.
|
|
1316
|
+
Responsive measurement, count (1..32), duration seconds, pixel size/lineWidth/outset and validated solid/gradient colors.
|
|
1317
|
+
Native SVG gradient stops use finite bounded percentages. Reduced motion keeps stationary segments.
|
|
1318
|
+
Compared with AntD: wrapper layout and top-left uniform corner radius replace child-host injection and nonuniform corner geometry;
|
|
1319
|
+
SVG dash motion replaces CSS offset-path and tail coloring. Numeric dimensions avoid CSS-unit measurement dependencies.
|
|
1320
|
+
|
|
1321
|
+
### DataTable: hierarchy, header groups and virtual windows
|
|
1322
|
+
|
|
1323
|
+
`columns` accepts `ColumnDefinition<T>`: either an existing `Column<T>` or a
|
|
1324
|
+
`ColumnGroup<T>` with `id`, `header`, `children`, `hidden` and `className`. Hidden
|
|
1325
|
+
branches disappear; native colSpan/rowSpan reflect the visible leaves. Numeric
|
|
1326
|
+
leaf widths also size grouped headers through colgroup. Group headers pin only
|
|
1327
|
+
when all their leaves share the same fixed edge. Duplicate column IDs are rejected.
|
|
1328
|
+
|
|
1329
|
+
`getChildren(row)` opts into hierarchy; root records are filtered, sorted and
|
|
1330
|
+
paged before expanded descendants are flattened. Sorting and filters apply at
|
|
1331
|
+
all levels, with a failed parent filter excluding its branch. Original records
|
|
1332
|
+
remain unchanged. Use the existing expansion keys/callback, `rowExpandable` and
|
|
1333
|
+
`indentSize` (20px default). Duplicate or empty row keys, including cycles, are
|
|
1334
|
+
rejected. Row indexes refer to the visible flattened page. `groupBy` groups that
|
|
1335
|
+
visible page; `expandedRowRender` can coexist with tree expansion.
|
|
1336
|
+
|
|
1337
|
+
`sortPriority` enables additive multi-sort (higher numbers first). `sorts`,
|
|
1338
|
+
`defaultSorts` and `onSortsChange` expose the array; each header cycles asc → desc →
|
|
1339
|
+
removed. Existing controlled `sort` stays single-sort unless the array API is
|
|
1340
|
+
explicitly used. `onSortChange` retains its nullable single-state payload.
|
|
1341
|
+
`onChange(change)` reports sort/filter/paginate once, including proposed filters,
|
|
1342
|
+
sorts, pagination and processed **root records before pagination** in
|
|
1343
|
+
`currentDataSource`. Controlled rejection does not suppress proposed events.
|
|
1344
|
+
`summary(rows)` now receives that pre-pagination root scope, matching AntD's
|
|
1345
|
+
summary scope; render native rows/cells inside the supplied tfoot.
|
|
1346
|
+
|
|
1347
|
+
`selectionMode="single"` renders same-name native radios without select-all or a
|
|
1348
|
+
bulk selection bar; a pick replaces the selected keys and disabled rows cannot
|
|
1349
|
+
be picked. Multiple selection retains its existing page selection contract.
|
|
1350
|
+
|
|
1351
|
+
`virtual` enables a fixed-height native table window, or use
|
|
1352
|
+
`{ rowHeight, overscan }` (45px/36px according to density, three overscan rows by
|
|
1353
|
+
default). `scroll.y` supplies viewport height, otherwise 300px. Rich cells are
|
|
1354
|
+
clipped to this pitch; choose a sufficient height. Tree expansion, grouped
|
|
1355
|
+
headers, fixed columns and cursor navigation work within the window. The active
|
|
1356
|
+
row stays mounted outside the window until focus leaves, preserving editors and
|
|
1357
|
+
keyboard navigation. Non-finite dimensions fall back to valid defaults. Grouped
|
|
1358
|
+
bodies, detail expansion and any `onCell` use full rendering, preserving merged
|
|
1359
|
+
cell geometry. This is an intentional difference from AntD's measured virtual
|
|
1360
|
+
rows and merged-span repair. Arbitrary variable-height virtual content and its
|
|
1361
|
+
internal rc-table ref are not exposed. Klun keeps string keys, rows/rowKey,
|
|
1362
|
+
getChildren and its existing native table semantics.
|
|
1363
|
+
|
|
1364
|
+
### DatePicker / DateRangePicker: periods, local time and typed formats
|
|
1365
|
+
|
|
1366
|
+
The existing ISO string/native input ref contract is retained. `picker` is date,
|
|
1367
|
+
week, month, quarter or year; emitted period values use the ISO Monday, first day
|
|
1368
|
+
of the month/quarter, or January 1. Native week input uses ISO week years (for
|
|
1369
|
+
example 2021-01-01 displays 2020-W53). Period bounds compare their period starts,
|
|
1370
|
+
so a mid-month min/max does not discard the entire boundary month. `disabledDate`
|
|
1371
|
+
receives the candidate ISO day/period and `{ type }`.
|
|
1372
|
+
|
|
1373
|
+
`showTime` (date mode only) emits local `YYYY-MM-DDTHH:mm[:ss]` without timezone
|
|
1374
|
+
conversion. Use `{ defaultValue: '09:00', step: 1 }` to supply the initial clock
|
|
1375
|
+
and expose seconds. `min`/`max` accept local datetimes; a plain-date maximum ends
|
|
1376
|
+
at 23:59:59. `disabledTime(value)` rejects the complete local datetime. Date
|
|
1377
|
+
availability is independent of clock availability: select the day, then adjust
|
|
1378
|
+
its clock. `needConfirm` defaults to true with time, false otherwise. Calendar
|
|
1379
|
+
choices remain provisional until Apply when enabled; Escape/reopen cancels the
|
|
1380
|
+
proposal. Native entry and preset commits are immediate. `onOk` reports Apply.
|
|
1381
|
+
|
|
1382
|
+
`multiple` changes value/defaultValue/onChange to `string[]`, toggles dates or
|
|
1383
|
+
periods, sorts and deduplicates the proposal, keeps the panel open, and renders
|
|
1384
|
+
controlled removable tags. Time is excluded from this mode. With needConfirm,
|
|
1385
|
+
panel selections are staged until Apply. The ref points to the entry input;
|
|
1386
|
+
`name` submits a hidden JSON array and required validation reads committed dates.
|
|
1387
|
+
An explicit disabled=false also enables nested month/time controls under a
|
|
1388
|
+
disabled ConfigProvider. readOnly blocks both entry and panel edits.
|
|
1389
|
+
|
|
1390
|
+
`presets` contain a ReactNode label and ISO value or lazy function, evaluated on
|
|
1391
|
+
click and checked against constraints. `open/defaultOpen/onOpenChange` control
|
|
1392
|
+
the popup; rejected closing retains the panel. `format` accepts strict token
|
|
1393
|
+
strings YYYY/MM/DD/HH/mm/ss/Q with literal separators, or an explicit
|
|
1394
|
+
`{ format(value), parse(text) }` pair. Invalid typed drafts do not emit and fail
|
|
1395
|
+
native validity; blur restores the committed display. Display format changes do
|
|
1396
|
+
not change ISO values. Locale affects panel labels and native controls; token
|
|
1397
|
+
parsing is explicit and locale-independent.
|
|
1398
|
+
|
|
1399
|
+
DateRangePicker keeps editable partial tuples and never silently swaps endpoints.
|
|
1400
|
+
Shared date/time bounds constrain both endpoints, including same-day clocks.
|
|
1401
|
+
Its disabledDate/disabledTime receive `{ from, range: 'start' | 'end' }`; preset
|
|
1402
|
+
pairs are strictly checked, normalized to the picker period, then atomically
|
|
1403
|
+
validated and committed. Range open is 'start', 'end' or null, with only one
|
|
1404
|
+
panel open at once. Range presets use tuple values/lazy functions.
|
|
1405
|
+
|
|
1406
|
+
These are Klun ISO values and native refs, rather than AntD Dayjs objects and
|
|
1407
|
+
picker handles. Year/quarter panels and strict formats cover the documented
|
|
1408
|
+
contract; decade drilldown, masked editing, arbitrary Dayjs tokens/locale parsing,
|
|
1409
|
+
millisecond/12-hour column panels and measured rc-picker internals are not exposed.
|
|
1410
|
+
|
|
1411
|
+
### ConfigProvider: inherited themes and portalled controls
|
|
1412
|
+
|
|
1413
|
+
`theme="light" | "dark"` chooses a subtree theme; omission inherits the nearest
|
|
1414
|
+
provider, or the document theme when no provider selects one. `tokens` merges Klun
|
|
1415
|
+
CSS custom properties (`--accent`, `--fg`, etc.) with the parent. Undefined options
|
|
1416
|
+
and token values inherit, and explicit component `disabled={false}` enables a
|
|
1417
|
+
control inside a disabled provider. Dialog, Popover, Tooltip, Toast, ContextMenu,
|
|
1418
|
+
fullscreen Spin and AiPanel carry language/direction/theme/tokens into their body
|
|
1419
|
+
portals. Native browser controls retain the browser's own formatting and UI.
|
|
1420
|
+
|
|
1421
|
+
Pagination consumes Chinese/English text and mirrors navigation arrows. Select,
|
|
1422
|
+
MultiSelect and Cascader localize built-in entry/search/loading labels while
|
|
1423
|
+
preserving caller-provided content; DatePicker localizes calendar actions.
|
|
1424
|
+
DataTable consumes configuration for selection/sort/filter/paging and live status;
|
|
1425
|
+
its fixed left/right column runs mirror to leading/trailing edges in RTL, including
|
|
1426
|
+
loading rows. Host-rendered cell actions remain owned by the host. Text spacing,
|
|
1427
|
+
borders and edge affordances use logical CSS; chart coordinates and centered
|
|
1428
|
+
transforms retain physical geometry.
|
|
1429
|
+
|
|
1430
|
+
This configuration uses Klun CSS tokens, not AntD's CSS-in-JS token algorithms or
|
|
1431
|
+
AntD component configuration objects. It does not claim compatibility with AntD
|
|
1432
|
+
`theme.algorithm`, `prefixCls`, `getPopupContainer` or arbitrary locale objects.
|
|
1433
|
+
|
|
1434
|
+
### Menu and ContextMenu: complete navigation contract
|
|
1435
|
+
|
|
1436
|
+
Menu supports controlled/default selectedKeys and openKeys, single/multiple
|
|
1437
|
+
selection, vertical/horizontal/inline modes, nested items, disabled branches and
|
|
1438
|
+
per-item callbacks. A standalone root has one Tab entry; commands use programmatic
|
|
1439
|
+
focus, arrow keys/Home/End/typeahead, and native Enter/Space activation. Inline
|
|
1440
|
+
navigation walks expanded descendants. Popup Escape/backward closes only the
|
|
1441
|
+
focused level and restores its trigger, including RTL and deeper nesting. Selecting
|
|
1442
|
+
a leaf dismisses the tree unless closeOnSelect=false (the default for multiple).
|
|
1443
|
+
When the focused command disappears or becomes disabled, focus moves to the first
|
|
1444
|
+
available command without stealing focus from an external control.
|
|
1445
|
+
|
|
1446
|
+
ContextMenu supports pointer/ContextMenu-key/Shift+F10 opening, typed context passed
|
|
1447
|
+
to commands, icon strips, nested menus and host cancellation through preventDefault
|
|
1448
|
+
in onOpen or the trigger handler. Internal menu scrolling preserves the menu;
|
|
1449
|
+
page scroll dismisses the pointer anchor. Long menus are bounded and scroll within
|
|
1450
|
+
the viewport, submenus flip to available space, and Escape/backward restores one
|
|
1451
|
+
level at a time. Omitted configuration inherits through all portal levels.
|
|
1452
|
+
|
|
1453
|
+
Klun uses string ids/items and command callbacks instead of AntD key/domEvent/
|
|
1454
|
+
keyPath info objects. Root menus remain visible components; a host owns overall
|
|
1455
|
+
opening via Popover/Dropdown. Search is a Klun level filter, not an AntD API.
|
|
1456
|
+
AntD Menu.Item/ItemGroup/children syntax, inlineCollapsed, overflow collection,
|
|
1457
|
+
hover-delay configuration and CSS-in-JS semantic customization are not replicated.
|
|
1458
|
+
ContextMenu is the Klun command surface corresponding to AntD Dropdown's
|
|
1459
|
+
contextMenu trigger; its hook/list APIs and quick strip remain Klun-specific.
|
|
1460
|
+
|
|
1461
|
+
### Pagination: state and boundary behavior
|
|
1462
|
+
|
|
1463
|
+
`page`/`pageSize` are controlled when supplied, otherwise defaultPage/defaultPageSize
|
|
1464
|
+
initialize internal state. User changes notify onPageChange/onPageSizeChange and
|
|
1465
|
+
onChange with the proposed pair even if a controlled host refuses the update.
|
|
1466
|
+
Clicking the active page is a no-op; empty results show a disabled page 1 and do
|
|
1467
|
+
not notify. showTotal receives the normalized total and inclusive visible range
|
|
1468
|
+
(`[0, 0]` for empty results). Numeric boundaries are finite integer values capped
|
|
1469
|
+
at Number.MAX_SAFE_INTEGER; invalid pageSize falls back to 20, negative total to 0.
|
|
1470
|
+
|
|
1471
|
+
A shrinking total clamps the displayed page without a synthetic event. If results
|
|
1472
|
+
return, the originally requested page returns until the user changes it, matching
|
|
1473
|
+
the reference state model. Klun preserves its existing page-size contract: selecting
|
|
1474
|
+
a size resets the proposed page to 1 (AntD preserves/clamps the current page).
|
|
1475
|
+
Choices deduplicate and reject non-positive or unsafe integer values. The uncontrolled
|
|
1476
|
+
size menu discards open state when disabled/hidden. The numeric quick jumper commits
|
|
1477
|
+
on Enter, clamps to the available range, discards its draft on blur and leaves IME
|
|
1478
|
+
Enter untouched. hideOnSinglePage, showQuickJumper/showSizeChanger and host slots
|
|
1479
|
+
remain independent. Chinese/English labels and RTL arrows inherit configuration;
|
|
1480
|
+
the existing footer layout wraps for narrow viewports.
|
|
1481
|
+
|
|
1482
|
+
The API keeps page/onPageChange rather than AntD current/onShowSizeChange. It does
|
|
1483
|
+
not add AntD simple mode, prev/next/jump itemRender or arbitrary native prop forwarding.
|
|
1484
|
+
|
|
1485
|
+
### Card: composition and narrow content
|
|
1486
|
+
|
|
1487
|
+
Card retains its section/flush API and forwards native attributes/style/ref.
|
|
1488
|
+
size="small", type="inner" and variant (taking precedence over bordered) select
|
|
1489
|
+
compact/inner/borderless layouts. Loading hides the pending body and localizes
|
|
1490
|
+
its status label, while cover/actions remain available. Card.Grid/Card.Meta are
|
|
1491
|
+
also exported as CardGrid/CardMeta, with native div attributes/ref. Grid defaults
|
|
1492
|
+
to three columns and one column below 480px; host width styles override defaults.
|
|
1493
|
+
Titles, metadata and action slots wrap inside their available width. Existing
|
|
1494
|
+
Tabs can be composed in extra/body rather than adding Card tabList aliases.
|
|
1495
|
+
Klun does not implement AntD prefixCls/semantic style maps or its breakpoint grid
|
|
1496
|
+
system inside Card; use the library Grid for custom responsive columns.
|
|
1497
|
+
|
|
1498
|
+
### Tag and Divider: native composition
|
|
1499
|
+
|
|
1500
|
+
Tag forwards native span attributes/ref and lets host style override its CSS
|
|
1501
|
+
color. icon accepts existing Icon names or ReactNode. Close stops propagation
|
|
1502
|
+
before onClose; preventDefault retains the tag and the check state. Check/close
|
|
1503
|
+
use separate native buttons, so Enter/Space and disabled semantics work without
|
|
1504
|
+
nested controls. checked is controlled; defaultChecked initializes local state.
|
|
1505
|
+
Close labels consume locale; disabled=false overrides provider disabled. Long
|
|
1506
|
+
labels truncate inside the available width while preserving their full accessible
|
|
1507
|
+
text (supply title for a pointer tooltip). Klun retains CSS color/variants and
|
|
1508
|
+
pressed-button semantics rather than AntD preset color maps/CheckableTag aliases.
|
|
1509
|
+
|
|
1510
|
+
Divider forwards native div attributes/style/ref. orientation remains
|
|
1511
|
+
horizontal/vertical; titlePlacement start/center/end follows inherited direction.
|
|
1512
|
+
variant solid/dashed/dotted takes precedence over the legacy dashed flag. Host
|
|
1513
|
+
style controls spacing; captions wrap on narrow screens, and vertical captions
|
|
1514
|
+
are ignored. Klun keeps logical placement and existing margin geometry rather
|
|
1515
|
+
than AntD physical left/right aliases, semantic style maps or responsive sizes.
|
|
1516
|
+
|
|
1517
|
+
### Segment: focus and dynamic data
|
|
1518
|
+
|
|
1519
|
+
Segment retains string-valued options and group/pressed-button semantics. There
|
|
1520
|
+
is one tab stop among enabled options. Horizontal arrows follow provider RTL;
|
|
1521
|
+
vertical arrows use Up/Down; Home/End skip disabled options. Re-selecting the
|
|
1522
|
+
current value sends no change. Missing selected values remain host-owned, with
|
|
1523
|
+
a first-enabled keyboard entry; removing/disabling the focused option restores
|
|
1524
|
+
owned focus without stealing external focus. IME and canceled native key events
|
|
1525
|
+
are ignored. Empty/all-disabled groups have a focusable root. Native div
|
|
1526
|
+
attributes/ref/style, ReactNode icon/label and block layout are supported; label
|
|
1527
|
+
content must be noninteractive. Chip forwards native button/ref and consumes
|
|
1528
|
+
global disabled with explicit overrides. Default View labels consume locale.
|
|
1529
|
+
Klun keeps its string values/button markup rather than AntD radio/name form
|
|
1530
|
+
submission, primitive/number option shorthand, size/shape or semantic aliases.
|
|
1531
|
+
|
|
1532
|
+
### Nav / Sidebar: host-owned navigation and shell state
|
|
1533
|
+
|
|
1534
|
+
Nav keeps route value/onChange controlled; current clicks send no change.
|
|
1535
|
+
Arrow/Home/End navigation starts from the focused destination even when the host
|
|
1536
|
+
refuses a route change. More and portaled menus keep their own keyboard behavior;
|
|
1537
|
+
disabling Nav/removing overflow discards pending open state. Item context commands
|
|
1538
|
+
inherit item/Nav disabled, including explicit false under disabled provider.
|
|
1539
|
+
Rich-label command names use their text. Missing routes do not auto-commit;
|
|
1540
|
+
removing/disabling a focused destination restores owned focus. Ink tracks both
|
|
1541
|
+
strip and destination resizes. Nav native attributes/style/ref are forwarded;
|
|
1542
|
+
internal built-in labels consume locale. It is page navigation (aria-current),
|
|
1543
|
+
not a Tabs tabpanel controller or an automatic horizontal overflow collector.
|
|
1544
|
+
|
|
1545
|
+
Sidebar forwards aside attributes/style/ref; shell provider collapse can be
|
|
1546
|
+
explicitly overridden. Collapsed content stays mounted but inert/aria-hidden.
|
|
1547
|
+
Configured finite min/max bounds constrain pointer and keyboard proposals;
|
|
1548
|
+
controlled hosts may refuse them. Only primary-pointer drags resize; lost
|
|
1549
|
+
capture/cancel ends a drag. RTL reverses drag/arrow direction; Home/End reach
|
|
1550
|
+
bounds, composing/modified keys are ignored. Categories/resize labels consume
|
|
1551
|
+
locale. Existing CSS hides Sidebar at <=1024px; shell owns the external collapse
|
|
1552
|
+
control/focus and mobile navigation. Nested Menu provides navigation expansion.
|
|
1553
|
+
Klun retains 300px default and zero-width collapse instead of AntD Sider's
|
|
1554
|
+
breakpoint callbacks, built-in trigger/80px rail, theme and collapsed state aliases.
|
|
1555
|
+
|
|
1556
|
+
### States and general feedback: mapping and boundaries
|
|
1557
|
+
|
|
1558
|
+
EmptyState is the illustrated empty/offline explanation; ErrorState is the
|
|
1559
|
+
existing alert with optional host-owned retry; Empty is the general image/
|
|
1560
|
+
description/action entry; Result displays status/exception outcomes without
|
|
1561
|
+
an automatic live alert. LoadingBlock/InlineSpinner/Spin announce loading;
|
|
1562
|
+
Skeleton/TableSkeleton are decorative. Default state/retry/loading/progress
|
|
1563
|
+
names consume locale; explicit host content is preserved. Empty/Spin/Result
|
|
1564
|
+
forward native div refs and attributes. Spin delay changes restart the wait,
|
|
1565
|
+
cancel/unmount clear timers, nested content becomes inert only while shown, and
|
|
1566
|
+
fullscreen uses the configured body portal. It is a loading overlay, not a
|
|
1567
|
+
modal focus trap or a replacement for host request cancellation.
|
|
1568
|
+
|
|
1569
|
+
Primitive Skeleton defaults to 12px height and sanitizes nonfinite geometry;
|
|
1570
|
+
compound placeholders retain avatar/title/paragraph/loading/active behavior.
|
|
1571
|
+
Skeleton/TableSkeleton rows and Progress visual steps cap at 1000 to prevent
|
|
1572
|
+
unbounded DOM allocation; use virtual data lists/continuous progress above that.
|
|
1573
|
+
Progress retains the 0–1 value contract (precedence over percent), line/circle/
|
|
1574
|
+
dashboard, bounded success, RTL logical gap placement, explicit formatting and
|
|
1575
|
+
accessible values. format returning null hides info, and label=0 stays visible.
|
|
1576
|
+
Step gaps shrink to fit narrow containers. State descriptions/actions wrap;
|
|
1577
|
+
table placeholders scroll locally. Existing Klun art/status geometry remains.
|
|
1578
|
+
AntD semantic style maps, compound Skeleton element aliases, Spin percent=auto/
|
|
1579
|
+
global indicator and gradient/array Progress colors remain intentional differences.
|
|
1580
|
+
|
|
1581
|
+
### Icon: names, fallback and meaning
|
|
1582
|
+
|
|
1583
|
+
Icon resolves only own glyph definitions; prototype-like names safely use the
|
|
1584
|
+
same empty box as unknown names and warn. The fallback preserves a supplied
|
|
1585
|
+
label/aria-label. Decorative icons remain aria-hidden; meaningful spans use
|
|
1586
|
+
role=img and their SVG stays nonfocusable/hidden. Native span attributes/ref and
|
|
1587
|
+
host styles are forwarded. Numeric sizes include zero, negative values clamp to
|
|
1588
|
+
zero and nonfinite values use CSS defaults; CSS dimensions remain supported.
|
|
1589
|
+
Klun retains the PingCode glyph catalog rather than importing AntD icon exports,
|
|
1590
|
+
two-tone colors, icon-font scripts or component/viewBox aliases. Use a real Button
|
|
1591
|
+
or ActionButton for interactive actions rather than relying on an icon alone.
|
|
1592
|
+
|
|
1593
|
+
### Charts: finite data, empty states and descriptions
|
|
1594
|
+
|
|
1595
|
+
AntD core has no equivalent chart family; Klun preserves its bar, CSS donut,
|
|
1596
|
+
SVG trend and positioned score/effort matrix, composing the existing Card/Avatar.
|
|
1597
|
+
Bars/donuts treat negative or nonfinite amounts as zero; zero bars have no height.
|
|
1598
|
+
Donut totals scale before summing so very large finite data retains proportions;
|
|
1599
|
+
empty/zero distributions use a neutral rail. Sparkline preserves finite signed
|
|
1600
|
+
values, scales before measuring its range, uses zero for nonfinite samples and
|
|
1601
|
+
shows a dot for one sample. Invalid/nonpositive dimensions use defaults.
|
|
1602
|
+
Scatter drops nonfinite coordinates and clamps negative score/effort positions
|
|
1603
|
+
to its nonnegative origin; math axes stay physical in RTL. Empty charts have
|
|
1604
|
+
localized feedback; explicit emptyState and accessible names are retained.
|
|
1605
|
+
Bar/Sparkline provide data descriptions; Donut keeps its data name (or description
|
|
1606
|
+
when a host name is supplied); points expose coordinate descriptions and consume
|
|
1607
|
+
provider disabled, with explicit overrides. Duplicate category names are allowed;
|
|
1608
|
+
point IDs remain unique host keys. Rings retain aspect ratio and legends wrap,
|
|
1609
|
+
long labels truncate, and chart overflow stays local on narrow screens. These
|
|
1610
|
+
are lightweight displays, not Ant Design Charts axis/tooltip/zoom replacements.
|
|
1611
|
+
|
|
1612
|
+
### SelectionBar batch contract
|
|
1613
|
+
|
|
1614
|
+
SelectionBar composes Checkbox/Menu/Popover; AntD 6.6.5 core has no matching bulk strip. The reference is `table/hooks/useSelection.tsx` for selection ownership and Menu/Popover for command interaction. Preserve the Klun table-header-height overlay (`--table-head-height`, currently 44px) and use `overlay={false}` for a wrapping board strip. Excess overlay commands scroll locally.
|
|
1615
|
+
|
|
1616
|
+
Counts are finite nonnegative integers; zero selections disable commands, while Cancel and select-all remain available. `disabled` consumes ConfigProvider with explicit false overriding it; each action's disabled remains authoritative. Default count, Cancel, More and select-all labels consume locale. Only the count has live status semantics; interactive commands remain exposed in a labelled group.
|
|
1617
|
+
|
|
1618
|
+
`loading` locks selection and all commands for host-owned work. Commands returning a Promise are automatically locked, expose aria-busy and prevent repeat clicks until settlement. Throws/rejections retain the selection, show a retryable error and invoke `onError`; the next command clears the error. Menus close when disabled/loading or removed and do not reopen after unlock. Focus owned by an inline command or its menu trigger is preserved across pending work; unrelated external focus is left alone.
|
|
1619
|
+
|
|
1620
|
+
`BulkActions.apply` accepts void or Promise<void>. Standard status/baseline/schedule and round-robin commands notify and clear only after success. Round-robin waits for every started write, including rejected writes; empty people disable distribution. Hosts own request cancellation, authorization, stale selection reconciliation, error details and transactional rollback for partially successful distribution. Extra/More commands retain host-owned notifications and clearing. No AntD semantic style/prefixCls API or server mutation layer is introduced.
|
|
1621
|
+
|
|
1622
|
+
### Inline editor contracts
|
|
1623
|
+
|
|
1624
|
+
PeoplePicker/QuickSelect are Klun cell controls composed from Select-style listbox/search behavior, Avatar, Tag and Popover; compare AntD 6.6.5 `components/select/index.tsx` and `@rc-component/select@1.10.1` `Select.js`/`OptionList.js`. QuickText maps to `components/typography/Editable.tsx` while retaining a single-line cell input, untrimmed commit values and the 220ms click/double-click distinction. No new runtime dependency or AntD API aliases are introduced.
|
|
1625
|
+
|
|
1626
|
+
All three consume ConfigProvider disabled with explicit false override and preserve host-owned controlled values, including unknown choices. Default text consumes locale; custom labels stay intact. QuickSelect and QuickText additionally support readOnly. ListWorkbench forwards the field configurations: TextField disabled/readOnly/validate(row,next)/onError(row,error), EnumField disabled/readOnly, and AssigneeField disabled/loading/error/onRetry. Workbench assignee triggers honor the same resolved disabled state as their picker.
|
|
1627
|
+
|
|
1628
|
+
QuickText offers a keyboard entry even without an interactive display node. Enter/F2/Space opens, Enter/blur commits once, Escape cancels; IME and modified commit keys do not save/cancel. `validate(next)` returns an accessible error and keeps the draft; synchronous write failures show retry feedback and call onError. Successful keyboard completion restores its own display focus, external blur retains external focus. Empty nonnullable drafts and unchanged writes keep the existing behavior; invalid maxLength is ignored, finite nonnegative lengths use native UTF-16 counting. Mid-edit external values do not replace the draft; disabling/readOnly cancels without a write. QuickText validation/commit are synchronous; hosts manage async writes and reconciliation.
|
|
1629
|
+
|
|
1630
|
+
QuickSelect skips disabled options for keyboard/pointer picks, suppresses unchanged writes, retains typed search on keyboard opening, scrolls the active option and keeps combobox focus. Unknown values remain visible. Clear is a separate command row, so a real `\u0000clear` value is safe; clearing still returns the existing empty-string API. There is no pending multi-value confirmation mode: a pick commits immediately and Escape/outside dismisses without a write. Hosts keep option values unique and provide immutable lists.
|
|
1631
|
+
|
|
1632
|
+
PeoplePicker supports disabled people/sources, fallback when a tab disappears, RTL tab navigation and real row focus for Arrow/Home/End. Unknown assigned IDs remain unselected, and `__unassigned__` can be a real ID. Loading and error are host-owned; cached rows are protected during them, onRetry requests a host retry, and async results recover owned removed/disabled focus without moving external focus. It is a single-select picker; Unassigned returns null, unchanged picks close without redundant writes. Requests, authorization, caching and cancellation belong to the host.
|
|
1633
|
+
|
|
1634
|
+
### AiPanel interaction contract
|
|
1635
|
+
|
|
1636
|
+
AntD 6.6.5 core has no AI panel; map its layer to `components/modal/Modal.tsx` and `@rc-component/dialog@1.10.0` `Dialog/index.js`, and compose a native multiline input. AiPanel and Dialog now share the existing focus/scroll stack with ordered modal z-index, topmost-only Escape, hidden/inert focus filtering and opener restoration. Callback changes do not refocus the composer. Preserve the Klun floating panel/brand geometry, with viewport-bounded width/height, logical RTL placement and reduced-motion styling.
|
|
1637
|
+
|
|
1638
|
+
`onSubmit(text)` receives trimmed plain text and may return void or Promise<void>. Host pending or a returned Promise locks sending, suggestions/chips/history/attachment; the composer stays readable while pending. Throws/rejections keep the draft, show a local error and call onError. `error` and `onRetry` also support host-owned failures; retry uses the host callback when present, otherwise resubmits the retained draft. Successful submission clears the draft; stale completions after close/reopen/unmount cannot modify the new session. Close remains available while pending; hosts own aborting requests.
|
|
1639
|
+
|
|
1640
|
+
Enter sends, Shift+Enter inserts a newline, IME/modified keys do not submit or dismiss. Default greeting/control/status text consumes locale, disabled consumes ConfigProvider with explicit false override, and existing portal theme/tokens remain intact. Body scrolling follows new or streamed text only while the reader remains near the end. The log exposes only host-supplied plain-text messages; pending/error feedback remains separately announced. History/attachment invoke host callbacks and are unavailable when no callback exists. No model, network, upload, Markdown execution, transcript persistence or automatic assistant reply is introduced; host controls messages, request cancellation and business authorization.
|
|
1641
|
+
|
|
1642
|
+
Typography interaction alignment: editor composition, key229, modified and repeated keys
|
|
1643
|
+
cannot submit/cancel. Finishing restores only owned focus; external focus and child updates
|
|
1644
|
+
are preserved. Controls follow locale; native textarea draft/Shift+Enter and synchronous
|
|
1645
|
+
host save callbacks retain the existing contract. Async copy text stops before clipboard
|
|
1646
|
+
write after unmount/disable, serializes one attempt and reports failure with retry. Once a
|
|
1647
|
+
native clipboard write has begun, it cannot be canceled. CSS ellipsis remains line-clamp
|
|
1648
|
+
without AntD text measurement/suffix/tooltip algorithms; no typography autosize/onBlur-save,
|
|
1649
|
+
copy fallback API or Promise-based edit validation is added. Title runtime levels stay1–5.
|
|
1650
|
+
|
|
1651
|
+
### Ship chrome 与阅读/编辑组合契约
|
|
1652
|
+
|
|
1653
|
+
这些业务模块没有 AntD 核心库的一对一组件,按组合行为对照固定 6.6.5 的 Layout/Menu/Tabs/Input/Typography/Empty/Modal/Progress,并复用本库已验收的 Nav、Menu、Popover、Input、Dialog、Checkbox 和 Progress;不引入业务路由、存储或请求依赖。
|
|
1654
|
+
|
|
1655
|
+
| 模块 | 已支持能力 | 有意保留的边界 |
|
|
1656
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
1657
|
+
| Rail | 受控 activeId、主/底部按钮、aria-current、中文导航名、provider 禁用及 item.disabled 显式覆盖 | 路由由 onClick 宿主实现;不模拟 Menu 的选择模型 |
|
|
1658
|
+
| Header | 受控 search/tabs、搜索 ref、产品切换、账户/通知/Ping/收藏/sidebar 操作、IME/修饰/重复 Enter 保护,禁用和中文名称 | actions 是宿主 ReactNode;快捷键全局注册和通知加载由宿主实现 |
|
|
1659
|
+
| Toolbar | 受控搜索/rules/sort/group、builder/菜单/可移除chip、零值、空schema安全、切字段重置operator、动态禁用关闭popup | operators/freeText 是宿主声明;不执行查询/校验业务筛选语义,不提供异步加载API |
|
|
1660
|
+
| Bits | 有限size/未知类型fallback、title F2或双击编辑、IME保护/trim/空值保留/恢复焦点、收藏/快捷入口/提示条、provider 禁用 | title同步onEdit,空标题不提交;统计数据/权限和富suffix由宿主提供 |
|
|
1661
|
+
| Views | Board/quarter Roadmap/DocSplit 受控阅读数据、中文空状态、内部滚动/移动布局;零period不生成非法CSS,无动作卡片不占tab位置 | 无看板拖放/卡片提交/请求;RoadmapView按顺序周期分配,不替代有日期的 RoadmapEditor |
|
|
1662
|
+
| ShellSurfaces | AccountMenu复用Menu;Shortcuts/QuickStart复用Dialog;受控checked/toggle/go/reset、实际checkbox下一值、中文labels、0 intro | 身份、快捷键注册、权限/导航/持久化由host提供;没有请求的空状态是实际空列表 |
|
|
1663
|
+
| DetailBlock | 可省略/零标题actions、原生section/h3;DetailTool原生按钮provider禁用 | host自定义actions自行处理禁用/权限 |
|
|
1664
|
+
| EditableText | text/editSeed、受控/默认editing与draft、readOnly/disabled显式覆盖、中文save/cancel、editor及触发器焦点、paragraph/note | 同步onSave;空draft重提交原文兼容防误删,Promise提交/失败/授权由host封装,不假报异步成功 |
|
|
1665
|
+
|
|
1666
|
+
窄屏 Header/Toolbar换行,Board/Roadmap横向滚动限定在本身,DocSplit上下排布;保留既有主题tokens与API。组合验收示例见 Ship/Alignment/Chrome,回归见 ShipChromeAlignment.test.tsx。
|
|
1667
|
+
|
|
1668
|
+
### Ship 详情、评论与附件组合契约
|
|
1669
|
+
|
|
1670
|
+
对照固定 AntD 6.6.5 ActionButton 的异步提交锁、Input/TextArea、Modal、Upload 和 Timeline/Steps 的组合行为,业务模块继续采用本库组件,不冒充 AntD 的业务扩展。
|
|
1671
|
+
|
|
1672
|
+
| 模块 | 行为 | 保留差异 |
|
|
1673
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
1674
|
+
| DetailSheet / CommentComposer | 受控详情/分区/字段/过滤,零内容;provider 禁用、中文操作名称;IME 安全发送,Promise 待定锁,失败保留草稿并提示,false 不清空,成功仅清空提交时草稿;关闭/禁用隔离旧结果,恢复本组件拥有的焦点 | Pin 暂无宿主回调而禁用;加粗/代码是展示工具;附件、引用、授权和业务请求由宿主实现 |
|
|
1675
|
+
| CommentThread | 受控评论/回复/编辑/删除/反应;Promise 提交防重复,失败保留草稿并可重试;确认删除,剪贴板结果提示;孤儿和循环父链有限遍历,RTL 缩进 | 评论 ID 必须唯一;实体切换由宿主重新挂载;无虚拟列表或自动网络请求,部分宿主文本/时间格式保留原文 |
|
|
1676
|
+
| AttachmentUpload | 文件选择/拖入、读取前大小限制、真实 FileReader 读取、有限进度、读取后最新回调;Promise 失败提示,计时器/reader 卸载清理;provider 禁用,预览/删除确认/复制真实结果 | onUpload 仍收到 name/size 元数据,不传送或保存文件字节;读取与进度不是服务器上传。需要真实传输时使用 Upload 或宿主传输层 |
|
|
1677
|
+
| LinkPicker | 受控关系、按类型候选/搜索/已关联状态,候选移除后禁止提交,类型失效重置,provider 禁用也保护自定义 opener,卸载关联确认 | onLink/onUnlink 为同步宿主提交;候选加载、错误和业务授权由宿主管理;不凭空查询远端实体 |
|
|
1678
|
+
| FilePreview | 受控元数据预览,按文件身份重置缩放,RTL 缩放原点;下载生成与当前展示一致的示意内容,CSV 防公式并正确转义,URL 延后释放 | 没有原始文件字节/鉴权地址,预览和下载明确为示意,不表示原始附件下载成功;下载提示仅表示交给浏览器 |
|
|
1679
|
+
| TransitionsTimeline | 受控活动/当前状态/工作流标签、空状态、本地化和 RTL;排除空/重复状态,安全处理状态 ID | 只读展示,保留既有状态词汇和摘要识别规则;不执行工作流、不持久化、不替代通用 Timeline |
|
|
1680
|
+
|
|
1681
|
+
验收示例 Ship/Alignment/Detail;回归 ShipDetailAlignment.test.tsx。无需新增依赖。
|
|
1682
|
+
|
|
1683
|
+
### Ship 实体与分享弹窗契约
|
|
1684
|
+
|
|
1685
|
+
对照固定 AntD6.6.5 Modal/ActionButton、Form(实际 form1.8.6)以及本库 Dialog、Field、Select、DataTable、Tree、Menu;复用宿主受控协议,不创建请求或权限系统。
|
|
1686
|
+
|
|
1687
|
+
| 模块 | 已支持行为 | 边界 |
|
|
1688
|
+
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
1689
|
+
| EntityDialog | 字段/侧栏/初始值、blur 与提交必填校验、唯一 label ID、零计数、prototype 字段安全;打开捕获基线,不因 inline fields 改变清空草稿;关闭重开重置;Promise 提交锁/失败提示/retry/继续创建;禁用与关闭隔离旧结果 | 不再人工延时;宿主 onSubmit 负责真实提交,工具节点由宿主管理;附件/工单尚无 host callback 的按钮明确禁用;无富文本、远端字段校验、通用 Form 实例 |
|
|
1690
|
+
| EntityPicker | list/table、scope/search/filter/sort、受控选择与差异计数、去重,保留跨页 ID;provider 禁用不能被非零 counts 覆盖;Promise confirm 锁/错误/retry,原标签缺失时 ID 提供 accessible name | rows 和分页候选由 host 提供;本身不因当前页缺少 ID 删除选择;成功是否关闭由 onConfirm 宿主决定,toolbar 需要 search 配置;无服务端查询/授权 |
|
|
1691
|
+
| ShareDialog | 打开/报表切换重置草稿,分享范围/expiry/schedule/hour/recipients/format;定时发送必须有效非空收件人且 hour 为6–20整数;Promise save/copy 锁和失败重试,旧会话结果忽略,复制成功才 Copied | link 必须来自 host,空 link 不伪造示例地址;onCopy 缺失或空 link 禁用复制;保留 onChange→onSave 顺序,onChange 收到尝试值,持久化失败时 host 负责回滚外部状态;UI 不执行后台导出或授予实际访问权 |
|
|
1692
|
+
|
|
1693
|
+
中文 RTL、空链接及失败重试故事见 Ship/Alignment/Entity,回归 ShipEntityAlignment.test.tsx;选项值是既有英文枚举,宿主业务文本不自动翻译。
|
|
1694
|
+
|
|
1695
|
+
### Ship 画布、路线图、工作台与项目向导契约
|
|
1696
|
+
|
|
1697
|
+
没有 AntD 核心库对应的业务编辑器。按固定6.6.5 Card/Layout、Table/InternalTable 与实际 table1.11.1、Timeline/Steps 与实际 steps1.2.3、Form 与实际 form1.8.6、Modal/ActionButton,以及本库的已验收组合行为审查。
|
|
1698
|
+
|
|
1699
|
+
| 模块 | 已支持行为 | 有意保留的边界 |
|
|
1700
|
+
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1701
|
+
| ReportCanvas | 受控 widgets、5种内置主体、宿主 dataset/renderBody/actions、12列宽度、按钮与自身拖动排序、删除确认/新增/公告;provider禁用/loading保护自定义 opener和写事件;自身handle与active drag ID验证,禁用旧drag失效;IME安全新增、unique label ID、非法span回退6,窄屏全宽卡片 | 无持久化/请求、跨画布拖放、布局碰撞算法;缺少有效 chartTypes 时回退现有五类。自定义 body/controls由host管理;onChange同步,host失败状态由host展示,未假报服务器保存 |
|
|
1702
|
+
| RoadmapEditor | 受控 lane/period/bar、rename/recolour/move/add/delete、按钮路径/自身drag、状态公告、weekends/zoom/fit;每个period独立year,quarter参数整数/日期范围保护及year0正确;空lane/period禁止创建、动态候选校验;provider禁用/RTL箭头/IME、unique IDs | quarter/month是既有显示粒度,不生成真实月级日期跨度;未知lane过滤,host IDs/periods须唯一;onChange/onRename同步,不运行排程或持久化。时间线横向滚动在本身;只提供已声明颜色,不创建存储 |
|
|
1703
|
+
| ListWorkbench | 受控 view/selection,过滤/排序/分组/table/board/paging/列设置、行与批量菜单、表格inline editors;同tick patches合并、最新callback、卸载/identity/禁用取消旧patch、finite page/size、原型字段安全;board也遵守loading/error/empty;Promise create/edit/bulk-properties/import/delete与真实clipboard结果,失败保留选择/草稿并提示,等待期间新选择保留;CSV引号/转义/多行/CRLF/BOM解析,拒绝坏header/列数/引号,导出公式保护与延迟URL释放 | 全量客户端rows过滤分页,无服务端查询/授权/路由/持久化;CSV仅平坦primitive,host自定义onExport负责自身内容安全;import读取完成用最新callback,卸载不启动写,已开始host请求不能自动撤销;onChange类view/inline协议保持同步,其他bulk能力沿SelectionBar协议;identity变化重置本地会话,entity切换host须正确设置identity |
|
|
1704
|
+
| ProjectWizard | 三步type/details/members、radio键盘/RTL/IME保护、step focus/公告、脏草稿退出确认、唯一field IDs;挂载捕获baseline不被inline defaults清空;empty catalogue与name256/key15/enum/candidate校验;owner包含且不可移除、成员去重、过期roster选择拒绝;Promise提交锁/error/retry/禁用与卸载旧结果隔离 | open由host通过mount/unmount管理,每次重开需重新挂载,owner/initialdefaults为会话配置;member协议仍name,重名唯一性由host负责;onSubmit成功的关闭由host决定;无创建网络、邀请、身份或真正权限授予 |
|
|
1705
|
+
|
|
1706
|
+
中文 RTL及loading/error/empty/disabled示例见 Ship/Alignment/Workbench;部分既有领域枚举、菜单、提示和统计说明仍为英文,宿主内容不自动翻译。回归 ShipWorkbenchAlignment.test.tsx。画布和路线图文案只声明应用更改,不再虚构 browser/localStorage 保存。
|