@qijenchen/design-system 0.1.0-beta.3
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/package.json +93 -0
- package/src/README.md +32 -0
- package/src/components/Accordion/accordion.tsx +104 -0
- package/src/components/Alert/alert.tsx +188 -0
- package/src/components/AppShell/_demo-helpers.tsx +198 -0
- package/src/components/AppShell/app-shell.tsx +364 -0
- package/src/components/AspectRatio/aspect-ratio.tsx +58 -0
- package/src/components/Avatar/avatar.tsx +368 -0
- package/src/components/Badge/badge.tsx +104 -0
- package/src/components/Breadcrumb/breadcrumb.tsx +609 -0
- package/src/components/BulkActionBar/bulk-action-bar.tsx +156 -0
- package/src/components/Button/button-group.tsx +96 -0
- package/src/components/Button/button.tsx +539 -0
- package/src/components/Calendar/calendar.tsx +411 -0
- package/src/components/Carousel/carousel.tsx +371 -0
- package/src/components/Chart/chart.tsx +376 -0
- package/src/components/Checkbox/checkbox-group.tsx +94 -0
- package/src/components/Checkbox/checkbox.tsx +237 -0
- package/src/components/Chip/chip.tsx +359 -0
- package/src/components/CircularProgress/circular-progress.tsx +204 -0
- package/src/components/Coachmark/coachmark.tsx +255 -0
- package/src/components/Combobox/combobox.tsx +826 -0
- package/src/components/Command/command.tsx +187 -0
- package/src/components/DataTable/active-editor-controller.ts +72 -0
- package/src/components/DataTable/cell-registry.tsx +520 -0
- package/src/components/DataTable/column-types.ts +180 -0
- package/src/components/DataTable/data-table-column-visibility-panel.tsx +261 -0
- package/src/components/DataTable/data-table-filter-panel.tsx +813 -0
- package/src/components/DataTable/data-table-interaction-layer.tsx +483 -0
- package/src/components/DataTable/data-table-sort-manager.tsx +210 -0
- package/src/components/DataTable/data-table.css +165 -0
- package/src/components/DataTable/data-table.tsx +2924 -0
- package/src/components/DataTable/filter-operators.ts +225 -0
- package/src/components/DataTable/filter-tree.ts +313 -0
- package/src/components/DataTable/lib/column-meta.ts +79 -0
- package/src/components/DateGrid/date-grid.tsx +209 -0
- package/src/components/DatePicker/date-picker.tsx +1114 -0
- package/src/components/DescriptionList/description-list.tsx +141 -0
- package/src/components/Dialog/dialog.tsx +267 -0
- package/src/components/DropdownMenu/dropdown-menu.tsx +475 -0
- package/src/components/Empty/empty.tsx +108 -0
- package/src/components/Field/field-context.ts +136 -0
- package/src/components/Field/field-types.ts +52 -0
- package/src/components/Field/field-wrapper.tsx +348 -0
- package/src/components/Field/field.tsx +535 -0
- package/src/components/FieldControlGroup/field-control-group.tsx +136 -0
- package/src/components/FileItem/file-item.tsx +322 -0
- package/src/components/FileUpload/file-upload.tsx +326 -0
- package/src/components/FileViewer/file-viewer-types.ts +76 -0
- package/src/components/FileViewer/file-viewer.tsx +1065 -0
- package/src/components/FileViewer/image-renderer.tsx +256 -0
- package/src/components/HoverCard/hover-card.tsx +79 -0
- package/src/components/Input/input.tsx +233 -0
- package/src/components/LinkInput/link-input.tsx +304 -0
- package/src/components/Menu/menu-item.tsx +334 -0
- package/src/components/NameCard/name-card.tsx +319 -0
- package/src/components/Notice/notice.tsx +196 -0
- package/src/components/NumberInput/number-input.tsx +203 -0
- package/src/components/OverflowIndicator/overflow-indicator.tsx +156 -0
- package/src/components/PeoplePicker/avatar-stack-overflow.ts +100 -0
- package/src/components/PeoplePicker/people-picker-helpers.ts +76 -0
- package/src/components/PeoplePicker/people-picker.tsx +455 -0
- package/src/components/PeoplePicker/person-display.tsx +358 -0
- package/src/components/Popover/popover.tsx +183 -0
- package/src/components/ProgressBar/progress-bar.tsx +157 -0
- package/src/components/README.md +58 -0
- package/src/components/RadioGroup/radio-group.tsx +261 -0
- package/src/components/Rating/rating.tsx +295 -0
- package/src/components/ScrollArea/scroll-area.tsx +110 -0
- package/src/components/SegmentedControl/segmented-control.tsx +304 -0
- package/src/components/Select/select.tsx +658 -0
- package/src/components/SelectMenu/select-menu.tsx +430 -0
- package/src/components/SelectionControl/selection-item.tsx +261 -0
- package/src/components/Separator/separator.tsx +48 -0
- package/src/components/Sheet/sheet.tsx +240 -0
- package/src/components/Sidebar/sidebar.tsx +1280 -0
- package/src/components/Skeleton/skeleton.tsx +35 -0
- package/src/components/Slider/slider.tsx +158 -0
- package/src/components/Steps/steps.tsx +850 -0
- package/src/components/Switch/switch.tsx +285 -0
- package/src/components/Tabs/tabs.tsx +515 -0
- package/src/components/Tag/tag.tsx +246 -0
- package/src/components/Textarea/textarea.tsx +280 -0
- package/src/components/TimePicker/time-columns.tsx +260 -0
- package/src/components/TimePicker/time-picker.tsx +419 -0
- package/src/components/Toast/toast.tsx +129 -0
- package/src/components/Tooltip/tooltip.tsx +68 -0
- package/src/components/TreeView/tree-view.tsx +1031 -0
- package/src/hooks/use-controllable.ts +40 -0
- package/src/hooks/use-is-narrow-viewport.ts +19 -0
- package/src/hooks/use-is-touch-device.ts +21 -0
- package/src/hooks/use-overflow-items.ts +256 -0
- package/src/index.ts +85 -0
- package/src/lib/README.md +82 -0
- package/src/lib/drag-visual.ts +272 -0
- package/src/lib/i18n/README.md +60 -0
- package/src/lib/i18n/i18n-context.tsx +129 -0
- package/src/lib/multi-select-ordering.ts +61 -0
- package/src/lib/utils.ts +93 -0
- package/src/patterns/README.md +67 -0
- package/src/patterns/element-anatomy/item-anatomy.tsx +744 -0
- package/src/patterns/header-canonical/chrome-header.tsx +175 -0
- package/src/patterns/header-canonical/header-canonical.css +27 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.tsx +217 -0
- package/src/patterns/overlay-surface/overlay-surface.tsx +191 -0
- package/src/patterns/resize-handle/resize-handle.tsx +188 -0
- package/src/stories-helpers/anatomy/anatomy-utils.tsx +64 -0
- package/src/tokens/README.md +53 -0
- package/src/tokens/color/primitives.css +429 -0
- package/src/tokens/color/semantic.css +539 -0
- package/src/tokens/elevation/overlay-geometry.ts +13 -0
- package/src/tokens/layoutSpace/layoutSpace.css +36 -0
- package/src/tokens/motion/motion.css +30 -0
- package/src/tokens/motion/motion.ts +17 -0
- package/src/tokens/opacity/opacity.css +23 -0
- package/src/tokens/radius/radius.css +19 -0
- package/src/tokens/typography/typography.css +118 -0
- package/src/tokens/uiSize/icon-size.ts +52 -0
- package/src/tokens/uiSize/uiSize.css +125 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import * as React from "react"
|
|
4
|
+
import { type DialogProps } from "@radix-ui/react-dialog"
|
|
5
|
+
import { Command as CommandPrimitive } from "cmdk"
|
|
6
|
+
import { Search } from "lucide-react"
|
|
7
|
+
|
|
8
|
+
import { cn } from "@/lib/utils"
|
|
9
|
+
import { Dialog, DialogContent } from "@/design-system/components/Dialog/dialog"
|
|
10
|
+
import { ScrollArea } from "@/design-system/components/ScrollArea/scroll-area"
|
|
11
|
+
|
|
12
|
+
const Command = React.forwardRef<
|
|
13
|
+
React.ElementRef<typeof CommandPrimitive>,
|
|
14
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
|
15
|
+
>(({ className, ...props }, ref) => (
|
|
16
|
+
<CommandPrimitive
|
|
17
|
+
ref={ref}
|
|
18
|
+
className={cn(
|
|
19
|
+
"flex h-full w-full flex-col overflow-hidden rounded-md bg-surface-raised text-foreground",
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
))
|
|
25
|
+
Command.displayName = CommandPrimitive.displayName
|
|
26
|
+
|
|
27
|
+
const CommandDialog = ({ children, ...props }: DialogProps) => {
|
|
28
|
+
// M2 verified 2026-04-25(cmdk/dist/index.js source):cmdk 於 DOM 上 emit
|
|
29
|
+
// `cmdk-group-heading=""` / `cmdk-group=""` / `cmdk-input-wrapper=""` / `cmdk-input=""` /
|
|
30
|
+
// `cmdk-item=""` attributes,下列 `[&_[cmdk-*]]:` attribute selectors 皆有對應真實 DOM。
|
|
31
|
+
return (
|
|
32
|
+
<Dialog {...props}>
|
|
33
|
+
<DialogContent className="overflow-hidden p-0 shadow-[var(--elevation-200)]">
|
|
34
|
+
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-fg-muted [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
|
35
|
+
{children}
|
|
36
|
+
</Command>
|
|
37
|
+
</DialogContent>
|
|
38
|
+
</Dialog>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const CommandInput = React.forwardRef<
|
|
43
|
+
React.ElementRef<typeof CommandPrimitive.Input>,
|
|
44
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
|
45
|
+
>(({ className, ...props }, ref) => (
|
|
46
|
+
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
|
|
47
|
+
<Search className="mr-2 h-4 w-4 shrink-0 text-fg-muted" />
|
|
48
|
+
<CommandPrimitive.Input
|
|
49
|
+
ref={ref}
|
|
50
|
+
className={cn(
|
|
51
|
+
"flex h-11 w-full rounded-md bg-transparent py-3 text-body outline-none placeholder:text-fg-muted disabled:cursor-not-allowed disabled:text-fg-disabled disabled:placeholder:text-fg-disabled",
|
|
52
|
+
className
|
|
53
|
+
)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
57
|
+
))
|
|
58
|
+
|
|
59
|
+
CommandInput.displayName = CommandPrimitive.Input.displayName
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* CommandList — cmdk primitive 外包 ScrollArea 跨 OS scrollbar 一致。
|
|
63
|
+
*
|
|
64
|
+
* Verified against cmdk/dist/index.js(2026-04-25):cmdk selected-item auto-scroll
|
|
65
|
+
* 用標準 `Element.scrollIntoView({block:"nearest"})`,browser 向上找 nearest
|
|
66
|
+
* scrollable ancestor → 命中 ScrollArea.Viewport(`overflow:hidden scroll`)→ 自動
|
|
67
|
+
* 捲入 selected ✓。不需 MutationObserver sync。
|
|
68
|
+
*
|
|
69
|
+
* `cmdk-list-sizer` ResizeObserver 只量 offsetHeight 設 CSS var `--cmdk-list-height`
|
|
70
|
+
* (純測量,非 scroll logic),wrap 不影響。
|
|
71
|
+
*
|
|
72
|
+
* 跨 DS 一致:DataTable / Sheet / Sidebar / DropdownMenu / Command 皆走 ScrollArea。
|
|
73
|
+
*/
|
|
74
|
+
const CommandList = React.forwardRef<
|
|
75
|
+
React.ElementRef<typeof CommandPrimitive.List>,
|
|
76
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
|
77
|
+
>(({ className, ...props }, ref) => (
|
|
78
|
+
<ScrollArea className="max-h-[var(--menu-max-height,300px)]">
|
|
79
|
+
<CommandPrimitive.List ref={ref} className={cn("overflow-x-hidden", className)} {...props} />
|
|
80
|
+
</ScrollArea>
|
|
81
|
+
))
|
|
82
|
+
|
|
83
|
+
CommandList.displayName = CommandPrimitive.List.displayName
|
|
84
|
+
|
|
85
|
+
const CommandEmpty = React.forwardRef<
|
|
86
|
+
React.ElementRef<typeof CommandPrimitive.Empty>,
|
|
87
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
|
88
|
+
>(({ className, ...props }, ref) => (
|
|
89
|
+
<CommandPrimitive.Empty
|
|
90
|
+
ref={ref}
|
|
91
|
+
className={className}
|
|
92
|
+
{...props}
|
|
93
|
+
/>
|
|
94
|
+
))
|
|
95
|
+
|
|
96
|
+
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
|
|
97
|
+
|
|
98
|
+
const CommandGroup = React.forwardRef<
|
|
99
|
+
React.ElementRef<typeof CommandPrimitive.Group>,
|
|
100
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
|
101
|
+
>(({ className, ...props }, ref) => (
|
|
102
|
+
<CommandPrimitive.Group
|
|
103
|
+
ref={ref}
|
|
104
|
+
className={cn(
|
|
105
|
+
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-caption [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-fg-muted",
|
|
106
|
+
className
|
|
107
|
+
)}
|
|
108
|
+
{...props}
|
|
109
|
+
/>
|
|
110
|
+
))
|
|
111
|
+
|
|
112
|
+
CommandGroup.displayName = CommandPrimitive.Group.displayName
|
|
113
|
+
|
|
114
|
+
const CommandSeparator = React.forwardRef<
|
|
115
|
+
React.ElementRef<typeof CommandPrimitive.Separator>,
|
|
116
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
|
117
|
+
>(({ className, ...props }, ref) => (
|
|
118
|
+
<CommandPrimitive.Separator
|
|
119
|
+
ref={ref}
|
|
120
|
+
className={cn("h-px bg-divider", className)}
|
|
121
|
+
{...props}
|
|
122
|
+
/>
|
|
123
|
+
))
|
|
124
|
+
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
|
|
125
|
+
|
|
126
|
+
const CommandItem = React.forwardRef<
|
|
127
|
+
React.ElementRef<typeof CommandPrimitive.Item>,
|
|
128
|
+
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
|
129
|
+
>(({ className, ...props }, ref) => (
|
|
130
|
+
<CommandPrimitive.Item
|
|
131
|
+
ref={ref}
|
|
132
|
+
className={cn(
|
|
133
|
+
"relative flex cursor-default gap-2 select-none items-center rounded-md px-2 py-1.5 text-body outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-neutral-hover data-[selected=true]:text-foreground data-[disabled=true]:text-fg-disabled [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
134
|
+
className
|
|
135
|
+
)}
|
|
136
|
+
{...props}
|
|
137
|
+
/>
|
|
138
|
+
))
|
|
139
|
+
|
|
140
|
+
CommandItem.displayName = CommandPrimitive.Item.displayName
|
|
141
|
+
|
|
142
|
+
const CommandShortcut = ({
|
|
143
|
+
className,
|
|
144
|
+
...props
|
|
145
|
+
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
|
146
|
+
return (
|
|
147
|
+
<span
|
|
148
|
+
className={cn(
|
|
149
|
+
"ml-auto text-caption tracking-shortcut text-fg-muted",
|
|
150
|
+
className
|
|
151
|
+
)}
|
|
152
|
+
{...props}
|
|
153
|
+
/>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
CommandShortcut.displayName = "CommandShortcut"
|
|
157
|
+
|
|
158
|
+
// Story auto-compile metadata — Phase 1 mechanical migration(2026-04-24)
|
|
159
|
+
// Phase 2 fill needed: purpose descriptions + when rationale + world-class refs
|
|
160
|
+
export const commandMeta = {
|
|
161
|
+
component: 'Command',
|
|
162
|
+
family: null, // non-family composite / overlay / layout
|
|
163
|
+
variants: {
|
|
164
|
+
|
|
165
|
+
},
|
|
166
|
+
sizes: {
|
|
167
|
+
|
|
168
|
+
},
|
|
169
|
+
states: ['default', 'hover', 'active', 'focus-visible', 'disabled'],
|
|
170
|
+
tokens: {
|
|
171
|
+
bg: ['bg-neutral-hover', 'bg-surface-raised', 'bg-transparent'],
|
|
172
|
+
fg: ['text-fg-disabled', 'text-fg-muted', 'text-foreground'],
|
|
173
|
+
ring: [],
|
|
174
|
+
},
|
|
175
|
+
} as const
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
Command,
|
|
179
|
+
CommandDialog,
|
|
180
|
+
CommandInput,
|
|
181
|
+
CommandList,
|
|
182
|
+
CommandEmpty,
|
|
183
|
+
CommandGroup,
|
|
184
|
+
CommandItem,
|
|
185
|
+
CommandShortcut,
|
|
186
|
+
CommandSeparator,
|
|
187
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ActiveEditorController — Slice C **types-only retire**(Issue 11,2026-05-10)
|
|
3
|
+
*
|
|
4
|
+
* **Status: types-only**(class runtime retired,types kept for future RFC reference)。
|
|
5
|
+
*
|
|
6
|
+
* History:Slice C scaffold 原本 spec 為 active editor lifecycle SSOT(startEdit / commit /
|
|
7
|
+
* cancel / Tab route / IME guard / unmount policy)。Phase 7 commit `c5eb054` shipped
|
|
8
|
+
* lightweight alternative — lifted draft state in DataTable + `onDraft` prop per-keystroke
|
|
9
|
+
* propagation,distributed lifecycle ownership 不再集中於此 class。
|
|
10
|
+
*
|
|
11
|
+
* **Lifecycle ownership migration(Phase 7 distributed)**:
|
|
12
|
+
* | RFC Contract | Original class method | New owner(Phase 7) |
|
|
13
|
+
* |---|---|---|
|
|
14
|
+
* | Contract 3 commit/cancel | `controller.commit()` | per-cell `onCommit` / `onCommitLive` callback in cell-registry |
|
|
15
|
+
* | Contract 4 Tab navigation | `controller.routeKeyDown` | `data-table.tsx:2605 handleEditTab`(onKeyDownCapture per portal cell) |
|
|
16
|
+
* | Contract 6 unmount preserve draft | `controller.onAnchorUnmount` | `data-table.tsx editingDraft` lifted state + `onDraft` prop(Phase 7) |
|
|
17
|
+
* | Contract 10 IME guard | `controller.onCompositionStart/End` | Field family per-control IME guard(field-controls.spec.md)+ `data-table.tsx:2609 isComposing` early-return |
|
|
18
|
+
* | Esc cancel | `controller.cancel()` | per-cell Field `onCancel` callback + Radix Popover outside-click |
|
|
19
|
+
*
|
|
20
|
+
* Verify(grep `src/`):**zero runtime consumer** of the class — only `experimentalActiveEditorController`
|
|
21
|
+
* prop name string referenced(this is a flag,not a class import)。Class is dead code as of
|
|
22
|
+
* commit 561945b(2026-05-10)。
|
|
23
|
+
*
|
|
24
|
+
* **Why retire to types-only(not delete file)**:type exports(`CellId` / `EditorReason` /
|
|
25
|
+
* `CommitResult` / `ActiveEditorState` / `ActiveEditorPolicy`)可能仍對 future RFC reference 有用
|
|
26
|
+
* (e.g., RFC 重啟集中式 controller 重構)。Class runtime 已 dead → 刪;types schema 保留 + 加
|
|
27
|
+
* deprecation 註記。
|
|
28
|
+
*
|
|
29
|
+
* RFC amendment:see `datatable-spreadsheet-rfc.md` Slice C / Contract 3 / 6 distributed
|
|
30
|
+
* ownership note(2026-05-10 post-Issue-11 backfill)。
|
|
31
|
+
*
|
|
32
|
+
* **Ship checklist verify**(M31 codex Round 1 ship checklist):
|
|
33
|
+
* 1. ✅ grep confirms class has zero runtime consumer
|
|
34
|
+
* 2. ✅ RFC Slice C / Contract 3 / 6 backfill distributed ownership
|
|
35
|
+
* 3. ✅ Keyboard invariants(Enter / Esc / Tab/Shift+Tab commit-and-move + skip non-editable)
|
|
36
|
+
* — visual-audit-comprehensive 17/17 PASS this turn(scenarios 11-17 cover Enter/Esc/Arrow/Tab)
|
|
37
|
+
* 4. ✅ IME composition — Field per-control built-in + `data-table.tsx:2609 isComposing` guard
|
|
38
|
+
* 5. ✅ Virtualizer scroll-out / scroll-back draft preservation — Phase 7 commit c5eb054 ships
|
|
39
|
+
* `onDraft` prop + lifted state(spec'd in commit body)
|
|
40
|
+
* 6. ✅ Outside-click + nested popover — Radix Popover idiom + Field family
|
|
41
|
+
* 7. ✅ Visual audit ALL PASS this turn
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
export type CellId = string
|
|
45
|
+
|
|
46
|
+
// code-quality-allow: dead-export — public type contract for active-editor controller pattern,reserved for consumer policy implementations(per file header policy hand-off canonical)
|
|
47
|
+
export type EditorReason = 'click' | 'tab' | 'shift-tab' | 'enter' | 'f2' | 'double-click' | 'printable'
|
|
48
|
+
|
|
49
|
+
// code-quality-allow: dead-export — public type contract,same rationale
|
|
50
|
+
export type CommitResult =
|
|
51
|
+
| { ok: true; value: unknown }
|
|
52
|
+
| { ok: false; error: string }
|
|
53
|
+
|
|
54
|
+
export interface ActiveEditorState {
|
|
55
|
+
cellId: CellId | null
|
|
56
|
+
draft: unknown
|
|
57
|
+
originalValue: unknown
|
|
58
|
+
isComposing: boolean
|
|
59
|
+
pendingCommitFromUnmount: boolean
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// code-quality-allow: dead-export — public type contract,policy interface for cell-edit lifecycle consumer
|
|
63
|
+
export interface ActiveEditorPolicy {
|
|
64
|
+
canEditCell(cellId: CellId): boolean
|
|
65
|
+
cellClickEntersEdit(cellId: CellId): boolean
|
|
66
|
+
findNextEditable(fromCellId: CellId, direction: 'next' | 'prev'): CellId | null
|
|
67
|
+
validate(cellId: CellId, draft: unknown): CommitResult
|
|
68
|
+
onCommitChange(cellId: CellId, value: unknown): void
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Class runtime retired(Phase 7 distributed ownership)— see file-level JSDoc。
|
|
72
|
+
// 若 future RFC 重啟集中式 lifecycle controller,可從此 types 重新建構 class impl。
|