@hjmds/design-contracts 0.8.2
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/README.md +208 -0
- package/dist/alert-dialog.d.ts +102 -0
- package/dist/alert-dialog.d.ts.map +1 -0
- package/dist/alert-dialog.js +136 -0
- package/dist/alert-dialog.js.map +1 -0
- package/dist/base-recipes.d.ts +184 -0
- package/dist/base-recipes.d.ts.map +1 -0
- package/dist/base-recipes.js +129 -0
- package/dist/base-recipes.js.map +1 -0
- package/dist/behaviors.d.ts +1254 -0
- package/dist/behaviors.d.ts.map +1 -0
- package/dist/behaviors.js +972 -0
- package/dist/behaviors.js.map +1 -0
- package/dist/bottom-navigation-defaults.d.ts +13 -0
- package/dist/bottom-navigation-defaults.d.ts.map +1 -0
- package/dist/bottom-navigation-defaults.js +10 -0
- package/dist/bottom-navigation-defaults.js.map +1 -0
- package/dist/bottom-navigation.d.ts +114 -0
- package/dist/bottom-navigation.d.ts.map +1 -0
- package/dist/bottom-navigation.js +223 -0
- package/dist/bottom-navigation.js.map +1 -0
- package/dist/breadcrumb.d.ts +97 -0
- package/dist/breadcrumb.d.ts.map +1 -0
- package/dist/breadcrumb.js +99 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/calendar.d.ts +285 -0
- package/dist/calendar.d.ts.map +1 -0
- package/dist/calendar.js +297 -0
- package/dist/calendar.js.map +1 -0
- package/dist/card.d.ts +39 -0
- package/dist/card.d.ts.map +1 -0
- package/dist/card.js +50 -0
- package/dist/card.js.map +1 -0
- package/dist/carousel.d.ts +180 -0
- package/dist/carousel.d.ts.map +1 -0
- package/dist/carousel.js +172 -0
- package/dist/carousel.js.map +1 -0
- package/dist/catalog.d.ts +7158 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +220 -0
- package/dist/catalog.js.map +1 -0
- package/dist/collection.d.ts +123 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +211 -0
- package/dist/collection.js.map +1 -0
- package/dist/color-references.d.ts +46 -0
- package/dist/color-references.d.ts.map +1 -0
- package/dist/color-references.js +39 -0
- package/dist/color-references.js.map +1 -0
- package/dist/colors.d.ts +56 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +90 -0
- package/dist/colors.js.map +1 -0
- package/dist/command-palette.d.ts +240 -0
- package/dist/command-palette.d.ts.map +1 -0
- package/dist/command-palette.js +97 -0
- package/dist/command-palette.js.map +1 -0
- package/dist/component-contracts.d.ts +137 -0
- package/dist/component-contracts.d.ts.map +1 -0
- package/dist/component-contracts.js +53 -0
- package/dist/component-contracts.js.map +1 -0
- package/dist/component-definitions.d.ts +135 -0
- package/dist/component-definitions.d.ts.map +1 -0
- package/dist/component-definitions.js +142 -0
- package/dist/component-definitions.js.map +1 -0
- package/dist/component-recipes.d.ts +3583 -0
- package/dist/component-recipes.d.ts.map +1 -0
- package/dist/component-recipes.js +1503 -0
- package/dist/component-recipes.js.map +1 -0
- package/dist/component-references.d.ts +416 -0
- package/dist/component-references.d.ts.map +1 -0
- package/dist/component-references.js +140 -0
- package/dist/component-references.js.map +1 -0
- package/dist/content-state.d.ts +104 -0
- package/dist/content-state.d.ts.map +1 -0
- package/dist/content-state.js +116 -0
- package/dist/content-state.js.map +1 -0
- package/dist/counter-badge-recipe.d.ts +80 -0
- package/dist/counter-badge-recipe.d.ts.map +1 -0
- package/dist/counter-badge-recipe.js +44 -0
- package/dist/counter-badge-recipe.js.map +1 -0
- package/dist/counter-badge.d.ts +12 -0
- package/dist/counter-badge.d.ts.map +1 -0
- package/dist/counter-badge.js +21 -0
- package/dist/counter-badge.js.map +1 -0
- package/dist/data-table.d.ts +203 -0
- package/dist/data-table.d.ts.map +1 -0
- package/dist/data-table.js +182 -0
- package/dist/data-table.js.map +1 -0
- package/dist/date-picker.d.ts +268 -0
- package/dist/date-picker.d.ts.map +1 -0
- package/dist/date-picker.js +168 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/description-list.d.ts +68 -0
- package/dist/description-list.d.ts.map +1 -0
- package/dist/description-list.js +85 -0
- package/dist/description-list.js.map +1 -0
- package/dist/design-system-provider.d.ts +80 -0
- package/dist/design-system-provider.d.ts.map +1 -0
- package/dist/design-system-provider.js +147 -0
- package/dist/design-system-provider.js.map +1 -0
- package/dist/evidence.d.ts +49 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +133 -0
- package/dist/evidence.js.map +1 -0
- package/dist/file-picker.d.ts +183 -0
- package/dist/file-picker.d.ts.map +1 -0
- package/dist/file-picker.js +224 -0
- package/dist/file-picker.js.map +1 -0
- package/dist/floating-action-button.d.ts +143 -0
- package/dist/floating-action-button.d.ts.map +1 -0
- package/dist/floating-action-button.js +149 -0
- package/dist/floating-action-button.js.map +1 -0
- package/dist/form.d.ts +143 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +206 -0
- package/dist/form.js.map +1 -0
- package/dist/foundations.d.ts +300 -0
- package/dist/foundations.d.ts.map +1 -0
- package/dist/foundations.js +238 -0
- package/dist/foundations.js.map +1 -0
- package/dist/grid.d.ts +75 -0
- package/dist/grid.d.ts.map +1 -0
- package/dist/grid.js +133 -0
- package/dist/grid.js.map +1 -0
- package/dist/icon-button-recipe.d.ts +99 -0
- package/dist/icon-button-recipe.d.ts.map +1 -0
- package/dist/icon-button-recipe.js +53 -0
- package/dist/icon-button-recipe.js.map +1 -0
- package/dist/icon.d.ts +41 -0
- package/dist/icon.d.ts.map +1 -0
- package/dist/icon.js +147 -0
- package/dist/icon.js.map +1 -0
- package/dist/image.d.ts +82 -0
- package/dist/image.d.ts.map +1 -0
- package/dist/image.js +100 -0
- package/dist/image.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +118 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +118 -0
- package/dist/layout.js.map +1 -0
- package/dist/link.d.ts +57 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +142 -0
- package/dist/link.js.map +1 -0
- package/dist/load-more.d.ts +64 -0
- package/dist/load-more.d.ts.map +1 -0
- package/dist/load-more.js +124 -0
- package/dist/load-more.js.map +1 -0
- package/dist/mentions.d.ts +67 -0
- package/dist/mentions.d.ts.map +1 -0
- package/dist/mentions.js +107 -0
- package/dist/mentions.js.map +1 -0
- package/dist/number-field.d.ts +208 -0
- package/dist/number-field.d.ts.map +1 -0
- package/dist/number-field.js +247 -0
- package/dist/number-field.js.map +1 -0
- package/dist/otp-field.d.ts +152 -0
- package/dist/otp-field.d.ts.map +1 -0
- package/dist/otp-field.js +117 -0
- package/dist/otp-field.js.map +1 -0
- package/dist/pagination.d.ts +181 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +226 -0
- package/dist/pagination.js.map +1 -0
- package/dist/password-field.d.ts +187 -0
- package/dist/password-field.d.ts.map +1 -0
- package/dist/password-field.js +120 -0
- package/dist/password-field.js.map +1 -0
- package/dist/popover.d.ts +152 -0
- package/dist/popover.d.ts.map +1 -0
- package/dist/popover.js +137 -0
- package/dist/popover.js.map +1 -0
- package/dist/progress-recipe.d.ts +43 -0
- package/dist/progress-recipe.d.ts.map +1 -0
- package/dist/progress-recipe.js +16 -0
- package/dist/progress-recipe.js.map +1 -0
- package/dist/recipes.d.ts +31 -0
- package/dist/recipes.d.ts.map +1 -0
- package/dist/recipes.js +46 -0
- package/dist/recipes.js.map +1 -0
- package/dist/responsive.d.ts +27 -0
- package/dist/responsive.d.ts.map +1 -0
- package/dist/responsive.js +66 -0
- package/dist/responsive.js.map +1 -0
- package/dist/result.d.ts +111 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +97 -0
- package/dist/result.js.map +1 -0
- package/dist/selection-helpers.d.ts +16 -0
- package/dist/selection-helpers.d.ts.map +1 -0
- package/dist/selection-helpers.js +52 -0
- package/dist/selection-helpers.js.map +1 -0
- package/dist/semantic-colors.d.ts +275 -0
- package/dist/semantic-colors.d.ts.map +1 -0
- package/dist/semantic-colors.js +84 -0
- package/dist/semantic-colors.js.map +1 -0
- package/dist/sheet.d.ts +51 -0
- package/dist/sheet.d.ts.map +1 -0
- package/dist/sheet.js +69 -0
- package/dist/sheet.js.map +1 -0
- package/dist/showcase.d.ts +153 -0
- package/dist/showcase.d.ts.map +1 -0
- package/dist/showcase.js +210 -0
- package/dist/showcase.js.map +1 -0
- package/dist/side-panel.d.ts +199 -0
- package/dist/side-panel.d.ts.map +1 -0
- package/dist/side-panel.js +111 -0
- package/dist/side-panel.js.map +1 -0
- package/dist/slider.d.ts +138 -0
- package/dist/slider.d.ts.map +1 -0
- package/dist/slider.js +150 -0
- package/dist/slider.js.map +1 -0
- package/dist/splitter.d.ts +113 -0
- package/dist/splitter.d.ts.map +1 -0
- package/dist/splitter.js +99 -0
- package/dist/splitter.js.map +1 -0
- package/dist/statistic.d.ts +41 -0
- package/dist/statistic.d.ts.map +1 -0
- package/dist/statistic.js +76 -0
- package/dist/statistic.js.map +1 -0
- package/dist/steps.d.ts +196 -0
- package/dist/steps.d.ts.map +1 -0
- package/dist/steps.js +160 -0
- package/dist/steps.js.map +1 -0
- package/dist/tag.d.ts +128 -0
- package/dist/tag.d.ts.map +1 -0
- package/dist/tag.js +93 -0
- package/dist/tag.js.map +1 -0
- package/dist/timeline.d.ts +147 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +127 -0
- package/dist/timeline.js.map +1 -0
- package/dist/toast.d.ts +164 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +529 -0
- package/dist/toast.js.map +1 -0
- package/dist/tokens.d.ts +9 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +9 -0
- package/dist/tokens.js.map +1 -0
- package/dist/tooltip.d.ts +44 -0
- package/dist/tooltip.d.ts.map +1 -0
- package/dist/tooltip.js +88 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/tour.d.ts +218 -0
- package/dist/tour.d.ts.map +1 -0
- package/dist/tour.js +211 -0
- package/dist/tour.js.map +1 -0
- package/dist/transfer-list.d.ts +207 -0
- package/dist/transfer-list.d.ts.map +1 -0
- package/dist/transfer-list.js +193 -0
- package/dist/transfer-list.js.map +1 -0
- package/dist/tree-select.d.ts +78 -0
- package/dist/tree-select.d.ts.map +1 -0
- package/dist/tree-select.js +132 -0
- package/dist/tree-select.js.map +1 -0
- package/dist/tree.d.ts +206 -0
- package/dist/tree.d.ts.map +1 -0
- package/dist/tree.js +223 -0
- package/dist/tree.js.map +1 -0
- package/dist/upload-item.d.ts +173 -0
- package/dist/upload-item.d.ts.map +1 -0
- package/dist/upload-item.js +156 -0
- package/dist/upload-item.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/docs/affix.md +63 -0
- package/docs/anchor.md +59 -0
- package/docs/ant-design-coverage.md +119 -0
- package/docs/app-provider.md +50 -0
- package/docs/app-rn-adoption.md +227 -0
- package/docs/architecture.md +320 -0
- package/docs/authoring-brief.md +87 -0
- package/docs/border-beam.md +66 -0
- package/docs/bottom-navigation.md +127 -0
- package/docs/breadcrumb.md +82 -0
- package/docs/calendar.md +154 -0
- package/docs/carousel.md +130 -0
- package/docs/cascader.md +93 -0
- package/docs/catalog-decision-status.md +306 -0
- package/docs/color-picker.md +72 -0
- package/docs/command-palette.md +116 -0
- package/docs/confirm-popover.md +93 -0
- package/docs/consistency-audit.md +383 -0
- package/docs/consumer-release-gate.md +90 -0
- package/docs/content-state.md +156 -0
- package/docs/context-panel.md +88 -0
- package/docs/cross-platform-core-normalization.md +118 -0
- package/docs/data-table.md +79 -0
- package/docs/date-picker.md +84 -0
- package/docs/description-list.md +75 -0
- package/docs/design-system-provider.md +139 -0
- package/docs/dropdown.md +78 -0
- package/docs/expansion-roadmap.md +285 -0
- package/docs/file-picker.md +59 -0
- package/docs/floating-action-button.md +111 -0
- package/docs/form.md +134 -0
- package/docs/generated/component-maturity.md +103 -0
- package/docs/generated/renderer-evidence.json +5597 -0
- package/docs/generated/renderer-evidence.md +132 -0
- package/docs/generated/showcase-manifest.json +3732 -0
- package/docs/icon.md +22 -0
- package/docs/identity.md +121 -0
- package/docs/image.md +84 -0
- package/docs/implementation-0.5.md +85 -0
- package/docs/layout-primitives.md +107 -0
- package/docs/layout.md +83 -0
- package/docs/library-reference-decisions.md +123 -0
- package/docs/link.md +67 -0
- package/docs/load-more.md +31 -0
- package/docs/mentions.md +82 -0
- package/docs/migration-0.2.md +108 -0
- package/docs/migration-0.3.md +72 -0
- package/docs/migration-0.5.md +82 -0
- package/docs/migration-0.6.md +197 -0
- package/docs/notification.md +54 -0
- package/docs/number-field.md +82 -0
- package/docs/otp-field.md +103 -0
- package/docs/pagination.md +139 -0
- package/docs/password-field.md +98 -0
- package/docs/popover.md +124 -0
- package/docs/promotion-candidates.md +169 -0
- package/docs/qr-code.md +69 -0
- package/docs/rating.md +58 -0
- package/docs/responsive-grid.md +90 -0
- package/docs/result.md +96 -0
- package/docs/showcase.md +97 -0
- package/docs/side-panel.md +71 -0
- package/docs/slider.md +79 -0
- package/docs/splitter.md +55 -0
- package/docs/statistic.md +16 -0
- package/docs/steps.md +115 -0
- package/docs/tag.md +57 -0
- package/docs/time-picker.md +88 -0
- package/docs/timeline.md +146 -0
- package/docs/toast.md +127 -0
- package/docs/tooltip.md +58 -0
- package/docs/tour.md +136 -0
- package/docs/transfer-list.md +94 -0
- package/docs/tree-select.md +101 -0
- package/docs/tree.md +123 -0
- package/docs/upload-item.md +68 -0
- package/docs/utility.md +53 -0
- package/docs/virtual-list.md +70 -0
- package/docs/watermark.md +58 -0
- package/package.json +402 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import type { CollectionKey, ComboboxInput, MenuItemDescriptor } from "./behaviors.js";
|
|
2
|
+
import type { CollectionSource, ComboboxCollectionState } from "./collection.js";
|
|
3
|
+
/**
|
|
4
|
+
* antd has no direct crosswalk target for CommandPalette — it is not in
|
|
5
|
+
* `antDesignReferenceComponents`. The nearest antd surface, `AutoComplete`/
|
|
6
|
+
* `Select` with `showSearch`, is exactly the composition question this
|
|
7
|
+
* module answers below, not a separate coverage gap.
|
|
8
|
+
*
|
|
9
|
+
* Decisive difference from Combobox: **a result is an action, not a
|
|
10
|
+
* persisted value.** Committing a Combobox sets `selectedKey` as the field's
|
|
11
|
+
* ongoing value, and `inputValue` goes on mirroring it. Running "새 트윗
|
|
12
|
+
* 작성" has no ongoing value anywhere to remember — the palette closes and
|
|
13
|
+
* resets. Forcing `selectedKey`/`onCommit` onto that would create a
|
|
14
|
+
* phantom value that is always `null` again the instant the palette reopens,
|
|
15
|
+
* the same category of dead-state mistake `docs/dropdown.md` avoided by not
|
|
16
|
+
* re-defining Menu's problem under a second name. So items here are shaped
|
|
17
|
+
* like `MenuItemDescriptor` (carries `shortcut`/`tone` for destructive
|
|
18
|
+
* commands), not `SelectItemDescriptor` (which deliberately strips both,
|
|
19
|
+
* because a Select option is a value, not an action).
|
|
20
|
+
*
|
|
21
|
+
* Everything else composes from existing contracts without changes:
|
|
22
|
+
* - **Heterogeneous sources** ("최근" / "명령어" / "검색 결과" in one list):
|
|
23
|
+
* already representable — `CollectionSource`'s `sections` is exactly
|
|
24
|
+
* grouped items, no new data model.
|
|
25
|
+
* - **Search/filter text**: `ComboboxInput` (inputValue/defaultInputValue/
|
|
26
|
+
* onInputValueChange) and `ComboboxCollectionState` (local vs. external
|
|
27
|
+
* filtering, `queryValue`/`resultQuery` staleness guard) are reused
|
|
28
|
+
* verbatim — a command search is the same async-search problem Combobox
|
|
29
|
+
* already solved, just over commands instead of selectable values.
|
|
30
|
+
* - **Keyboard navigation/typeahead across sections**: `getCollectionNavigationTarget`/
|
|
31
|
+
* `getCollectionTypeaheadMatch` (`src/collection.ts`) already generalize
|
|
32
|
+
* over any `CollectionSource`; nothing palette-specific to add.
|
|
33
|
+
* - **Global keyboard shortcut** (⌘K): explicitly out of scope. Which key
|
|
34
|
+
* combination opens the palette, and whether it is global or scoped, is a
|
|
35
|
+
* product/app decision — the same reason Link does not own navigation and
|
|
36
|
+
* BottomNavigation does not own the router's route state.
|
|
37
|
+
*/
|
|
38
|
+
export type CommandPaletteItemDescriptor<Key extends CollectionKey = CollectionKey> = MenuItemDescriptor<Key>;
|
|
39
|
+
export type CommandPaletteSource<Key extends CollectionKey = CollectionKey, SectionKey extends CollectionKey = CollectionKey> = CollectionSource<Key, SectionKey>;
|
|
40
|
+
export type CommandPaletteInput = ComboboxInput;
|
|
41
|
+
export type CommandPaletteQueryState = ComboboxCollectionState;
|
|
42
|
+
export type CommandPaletteActivateReason = "pointer" | "keyboard";
|
|
43
|
+
/**
|
|
44
|
+
* Mirrors Menu's `onAction`/`onActionAfterDismiss` split (`behaviorRegistry.menu`)
|
|
45
|
+
* without importing it — Menu, like Dialog, predates the per-component
|
|
46
|
+
* `src/<name>.ts` convention and has no exported type of its own to import,
|
|
47
|
+
* only string literals in the shared registry. `onActivate` fires
|
|
48
|
+
* immediately; `onActivateAfterDismiss` fires once the exit transition
|
|
49
|
+
* completes, for a command that itself opens another overlay (the same
|
|
50
|
+
* "close first, open the next surface after exit completes" ordering
|
|
51
|
+
* `docs/architecture.md`'s overlay-stack rule already requires).
|
|
52
|
+
*/
|
|
53
|
+
export type CommandPaletteActivateHandler<Key extends CollectionKey = CollectionKey> = (itemId: Key, reason: CommandPaletteActivateReason) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Web-only modal overlay (catalog: `platform: "web"`) — there is no `modal`
|
|
56
|
+
* axis the way SidePanel needs one; a command palette is always a modal
|
|
57
|
+
* takeover, never an inline non-modal surface. No `back`/`swipe` for the
|
|
58
|
+
* same web-only reason `SidePanelDismissReason` excludes them.
|
|
59
|
+
*
|
|
60
|
+
* `"activation"` is a dismiss reason, not merely an event: running a command
|
|
61
|
+
* always closes the palette, which is why `canDismissCommandPalette` treats
|
|
62
|
+
* it like `"programmatic"` — an owner-level certainty no policy can veto.
|
|
63
|
+
* There is no `busy` axis blocking dismissal while a command executes: the
|
|
64
|
+
* palette itself is fire-and-forget (`onActivate` fires and the palette
|
|
65
|
+
* closes); if the command's own effect is asynchronous, that runs after the
|
|
66
|
+
* palette is already gone, the same ordering Menu's `onActionAfterDismiss`
|
|
67
|
+
* already models. Recreating AlertDialog's `idle→busy→error` session here
|
|
68
|
+
* would be guessing at a requirement (a command that must block the palette
|
|
69
|
+
* open until it settles) with no measured product need.
|
|
70
|
+
*/
|
|
71
|
+
export type CommandPaletteDismissReason = "close-action" | "outside" | "escape" | "activation" | "programmatic";
|
|
72
|
+
export type CommandPaletteOpenChangeDetails = Readonly<{
|
|
73
|
+
reason: "trigger" | CommandPaletteDismissReason;
|
|
74
|
+
}>;
|
|
75
|
+
export type ControlledCommandPaletteOpenState = Readonly<{
|
|
76
|
+
open: boolean;
|
|
77
|
+
defaultOpen?: never;
|
|
78
|
+
onOpenChange(open: boolean, details: CommandPaletteOpenChangeDetails): void;
|
|
79
|
+
}>;
|
|
80
|
+
export type UncontrolledCommandPaletteOpenState = Readonly<{
|
|
81
|
+
open?: never;
|
|
82
|
+
defaultOpen?: boolean;
|
|
83
|
+
onOpenChange?: (open: boolean, details: CommandPaletteOpenChangeDetails) => void;
|
|
84
|
+
}>;
|
|
85
|
+
export type CommandPaletteOpenState = ControlledCommandPaletteOpenState | UncontrolledCommandPaletteOpenState;
|
|
86
|
+
export type CommandPaletteDismissPolicy = Readonly<{
|
|
87
|
+
dismissible: boolean;
|
|
88
|
+
outsideDismiss: boolean;
|
|
89
|
+
escapeDismiss: boolean;
|
|
90
|
+
}>;
|
|
91
|
+
export declare const commandPaletteBehaviorDefaults: {
|
|
92
|
+
readonly dismissible: true;
|
|
93
|
+
readonly outsideDismiss: true;
|
|
94
|
+
readonly escapeDismiss: true;
|
|
95
|
+
};
|
|
96
|
+
export declare function canDismissCommandPalette(reason: CommandPaletteDismissReason, policy?: CommandPaletteDismissPolicy): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* `accessibilityLabel` is required, not optional like Popover's — a command
|
|
99
|
+
* palette's `role="dialog"` surface has no visible heading the way Dialog's
|
|
100
|
+
* `title` slot or typical Popover content provides; the search field alone
|
|
101
|
+
* is not a reliable accessible name across renderers. `searchPlaceholder` is
|
|
102
|
+
* required for the same reason `LoadMoreLabels`/`PaginationLabels` require
|
|
103
|
+
* every field: a renderer must not invent untranslated fallback copy.
|
|
104
|
+
*/
|
|
105
|
+
export type CommandPaletteDescriptor = Readonly<{
|
|
106
|
+
accessibilityLabel: string;
|
|
107
|
+
searchPlaceholder: string;
|
|
108
|
+
}>;
|
|
109
|
+
export declare function validateCommandPaletteDescriptor(descriptor: CommandPaletteDescriptor): void;
|
|
110
|
+
/**
|
|
111
|
+
* Anatomy only — chrome for the modal shell and the pinned search field,
|
|
112
|
+
* reusing the exact tokens Dialog-family and Menu-family recipes already use
|
|
113
|
+
* (`floatingSurfaceContract`, `fieldFrameContract`, `collectionItemContract`)
|
|
114
|
+
* instead of inventing new ones. Result rows and section labels reuse
|
|
115
|
+
* `collectionItemContract` the same way `menuRecipe`/`treeRecipe` do — a
|
|
116
|
+
* command result is chrome-identical to a Menu item, it just lives in a
|
|
117
|
+
* modal instead of an anchored popup.
|
|
118
|
+
*/
|
|
119
|
+
export declare const commandPaletteRecipe: {
|
|
120
|
+
readonly slots: readonly ["backdrop", "positioner", "content", "searchField", "viewport", "section", "sectionLabel", "item", "leading", "copy", "label", "description", "shortcut", "emptyState"];
|
|
121
|
+
readonly backdrop: {
|
|
122
|
+
readonly color: "#000000";
|
|
123
|
+
readonly opacity: 0.6;
|
|
124
|
+
};
|
|
125
|
+
readonly content: {
|
|
126
|
+
readonly background: Readonly<{
|
|
127
|
+
source: "theme";
|
|
128
|
+
key: "bg";
|
|
129
|
+
alpha?: number;
|
|
130
|
+
}>;
|
|
131
|
+
readonly border: Readonly<{
|
|
132
|
+
source: "theme";
|
|
133
|
+
key: "border";
|
|
134
|
+
alpha?: number;
|
|
135
|
+
}>;
|
|
136
|
+
readonly borderWidth: 1;
|
|
137
|
+
readonly radius: "lg";
|
|
138
|
+
readonly shadow: {
|
|
139
|
+
readonly color: "#000000";
|
|
140
|
+
readonly opacity: 0.12;
|
|
141
|
+
readonly radius: 12;
|
|
142
|
+
readonly offsetY: 4;
|
|
143
|
+
};
|
|
144
|
+
readonly maxWidth: 560;
|
|
145
|
+
readonly maxHeight: 420;
|
|
146
|
+
};
|
|
147
|
+
readonly searchField: {
|
|
148
|
+
readonly minHeight: 44;
|
|
149
|
+
readonly paddingHorizontal: 16;
|
|
150
|
+
readonly borderColor: Readonly<{
|
|
151
|
+
source: "theme";
|
|
152
|
+
key: "textMuted";
|
|
153
|
+
alpha?: number;
|
|
154
|
+
}>;
|
|
155
|
+
};
|
|
156
|
+
readonly item: {
|
|
157
|
+
readonly minHeight: 44;
|
|
158
|
+
readonly paddingHorizontal: 12;
|
|
159
|
+
readonly gap: 12;
|
|
160
|
+
readonly radius: "md";
|
|
161
|
+
readonly label: {
|
|
162
|
+
readonly color: Readonly<{
|
|
163
|
+
source: "theme";
|
|
164
|
+
key: "textBody";
|
|
165
|
+
alpha?: number;
|
|
166
|
+
}>;
|
|
167
|
+
readonly textVariant: "body";
|
|
168
|
+
};
|
|
169
|
+
readonly description: {
|
|
170
|
+
readonly color: Readonly<{
|
|
171
|
+
source: "theme";
|
|
172
|
+
key: "textMuted";
|
|
173
|
+
alpha?: number;
|
|
174
|
+
}>;
|
|
175
|
+
readonly textVariant: "label";
|
|
176
|
+
};
|
|
177
|
+
readonly highlightedBackground: Readonly<{
|
|
178
|
+
source: "theme";
|
|
179
|
+
key: "text";
|
|
180
|
+
alpha?: number;
|
|
181
|
+
}>;
|
|
182
|
+
readonly focus: {
|
|
183
|
+
readonly color: Readonly<{
|
|
184
|
+
source: "theme";
|
|
185
|
+
key: "contentBrand";
|
|
186
|
+
alpha?: number;
|
|
187
|
+
}>;
|
|
188
|
+
readonly width: 2;
|
|
189
|
+
readonly offset: 2;
|
|
190
|
+
};
|
|
191
|
+
readonly selectedBackground: Readonly<{
|
|
192
|
+
source: "theme";
|
|
193
|
+
key: "primary";
|
|
194
|
+
alpha?: number;
|
|
195
|
+
}>;
|
|
196
|
+
readonly selectedIndicator: Readonly<{
|
|
197
|
+
source: "theme";
|
|
198
|
+
key: "contentBrand";
|
|
199
|
+
alpha?: number;
|
|
200
|
+
}>;
|
|
201
|
+
readonly danger: Readonly<{
|
|
202
|
+
source: "theme";
|
|
203
|
+
key: "danger";
|
|
204
|
+
alpha?: number;
|
|
205
|
+
}>;
|
|
206
|
+
};
|
|
207
|
+
readonly sectionLabel: {
|
|
208
|
+
readonly color: Readonly<{
|
|
209
|
+
source: "theme";
|
|
210
|
+
key: "textMuted";
|
|
211
|
+
alpha?: number;
|
|
212
|
+
}>;
|
|
213
|
+
readonly textVariant: "label";
|
|
214
|
+
readonly paddingHorizontal: 12;
|
|
215
|
+
readonly paddingVertical: 8;
|
|
216
|
+
};
|
|
217
|
+
readonly emptyState: {
|
|
218
|
+
readonly color: Readonly<{
|
|
219
|
+
source: "theme";
|
|
220
|
+
key: "textMuted";
|
|
221
|
+
alpha?: number;
|
|
222
|
+
}>;
|
|
223
|
+
readonly textVariant: "body";
|
|
224
|
+
readonly paddingVertical: 24;
|
|
225
|
+
};
|
|
226
|
+
readonly transition: {
|
|
227
|
+
readonly enter: {
|
|
228
|
+
readonly duration: 200;
|
|
229
|
+
readonly easing: "enter";
|
|
230
|
+
readonly reducedMotion: "opacity";
|
|
231
|
+
};
|
|
232
|
+
readonly exit: {
|
|
233
|
+
readonly duration: 120;
|
|
234
|
+
readonly easing: "exit";
|
|
235
|
+
readonly reducedMotion: "instant";
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
export declare const commandPaletteBehaviorScenarios: readonly ["activating-a-result-always-closes-the-palette-regardless-of-dismiss-policy", "escape-and-outside-close-without-running-any-command", "sections-merge-recents-static-commands-and-search-results-without-a-new-data-model", "keyboard-navigation-and-typeahead-reuse-the-shared-collection-helpers-unchanged", "local-vs-external-filtering-reuses-comboboxcollectionstate-staleness-guard-unchanged", "empty-result-state-is-announced-once-not-per-section", "no-global-shortcut-binding-is-owned-here-the-product-decides-the-trigger-key", "activate-after-dismiss-lets-a-command-open-the-next-overlay-only-once-exit-completes"];
|
|
240
|
+
//# sourceMappingURL=command-palette.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-palette.d.ts","sourceRoot":"","sources":["../src/command-palette.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AASjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,MAAM,4BAA4B,CAAC,GAAG,SAAS,aAAa,GAAG,aAAa,IAChF,kBAAkB,CAAC,GAAG,CAAC,CAAC;AAE1B,MAAM,MAAM,oBAAoB,CAC9B,GAAG,SAAS,aAAa,GAAG,aAAa,EACzC,UAAU,SAAS,aAAa,GAAG,aAAa,IAC9C,gBAAgB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAEtC,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAChD,MAAM,MAAM,wBAAwB,GAAG,uBAAuB,CAAC;AAE/D,MAAM,MAAM,4BAA4B,GAAG,SAAS,GAAG,UAAU,CAAC;AAElE;;;;;;;;;GASG;AACH,MAAM,MAAM,6BAA6B,CAAC,GAAG,SAAS,aAAa,GAAG,aAAa,IAAI,CACrF,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,4BAA4B,KACjC,IAAI,CAAC;AAEV;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,2BAA2B,GACnC,cAAc,GACd,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,cAAc,CAAC;AAEnB,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACrD,MAAM,EAAE,SAAS,GAAG,2BAA2B,CAAC;CACjD,CAAC,CAAC;AAEH,MAAM,MAAM,iCAAiC,GAAG,QAAQ,CAAC;IACvD,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,+BAA+B,GAAG,IAAI,CAAC;CAC7E,CAAC,CAAC;AAEH,MAAM,MAAM,mCAAmC,GAAG,QAAQ,CAAC;IACzD,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CACb,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,+BAA+B,KACrC,IAAI,CAAC;CACX,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAC/B,iCAAiC,GACjC,mCAAmC,CAAC;AAExC,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;CAIK,CAAC;AAEjD,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,2BAA2B,EACnC,MAAM,GAAE,2BAA4D,GACnE,OAAO,CAMT;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC,CAAC;AAQH,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,wBAAwB,GACnC,IAAI,CAMN;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CvB,CAAC;AAEX,eAAO,MAAM,+BAA+B,knBASlC,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { collectionItemContract, fieldFrameContract, floatingSurfaceContract, } from "./component-contracts.js";
|
|
2
|
+
import { backdrop, motionPreset, spacing } from "./foundations.js";
|
|
3
|
+
import { semanticColors } from "./semantic-colors.js";
|
|
4
|
+
export const commandPaletteBehaviorDefaults = {
|
|
5
|
+
dismissible: true,
|
|
6
|
+
outsideDismiss: true,
|
|
7
|
+
escapeDismiss: true,
|
|
8
|
+
};
|
|
9
|
+
export function canDismissCommandPalette(reason, policy = commandPaletteBehaviorDefaults) {
|
|
10
|
+
if (reason === "programmatic" || reason === "activation")
|
|
11
|
+
return true;
|
|
12
|
+
if (!policy.dismissible)
|
|
13
|
+
return false;
|
|
14
|
+
if (reason === "outside")
|
|
15
|
+
return policy.outsideDismiss;
|
|
16
|
+
if (reason === "escape")
|
|
17
|
+
return policy.escapeDismiss;
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
function assertNonEmpty(value, field) {
|
|
21
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
22
|
+
throw new TypeError(`CommandPalette ${field} must not be empty`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function validateCommandPaletteDescriptor(descriptor) {
|
|
26
|
+
if (descriptor === null || typeof descriptor !== "object") {
|
|
27
|
+
throw new TypeError("CommandPalette descriptor must be an object");
|
|
28
|
+
}
|
|
29
|
+
assertNonEmpty(descriptor.accessibilityLabel, "accessibilityLabel");
|
|
30
|
+
assertNonEmpty(descriptor.searchPlaceholder, "searchPlaceholder");
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Anatomy only — chrome for the modal shell and the pinned search field,
|
|
34
|
+
* reusing the exact tokens Dialog-family and Menu-family recipes already use
|
|
35
|
+
* (`floatingSurfaceContract`, `fieldFrameContract`, `collectionItemContract`)
|
|
36
|
+
* instead of inventing new ones. Result rows and section labels reuse
|
|
37
|
+
* `collectionItemContract` the same way `menuRecipe`/`treeRecipe` do — a
|
|
38
|
+
* command result is chrome-identical to a Menu item, it just lives in a
|
|
39
|
+
* modal instead of an anchored popup.
|
|
40
|
+
*/
|
|
41
|
+
export const commandPaletteRecipe = {
|
|
42
|
+
slots: [
|
|
43
|
+
"backdrop",
|
|
44
|
+
"positioner",
|
|
45
|
+
"content",
|
|
46
|
+
"searchField",
|
|
47
|
+
"viewport",
|
|
48
|
+
"section",
|
|
49
|
+
"sectionLabel",
|
|
50
|
+
"item",
|
|
51
|
+
"leading",
|
|
52
|
+
"copy",
|
|
53
|
+
"label",
|
|
54
|
+
"description",
|
|
55
|
+
"shortcut",
|
|
56
|
+
"emptyState",
|
|
57
|
+
],
|
|
58
|
+
backdrop: backdrop.modal,
|
|
59
|
+
content: {
|
|
60
|
+
background: floatingSurfaceContract.background,
|
|
61
|
+
border: floatingSurfaceContract.border,
|
|
62
|
+
borderWidth: floatingSurfaceContract.borderWidth,
|
|
63
|
+
radius: "lg",
|
|
64
|
+
shadow: floatingSurfaceContract.shadow,
|
|
65
|
+
maxWidth: 560,
|
|
66
|
+
maxHeight: 420,
|
|
67
|
+
},
|
|
68
|
+
searchField: {
|
|
69
|
+
minHeight: fieldFrameContract.minHeight,
|
|
70
|
+
paddingHorizontal: fieldFrameContract.paddingHorizontal,
|
|
71
|
+
borderColor: fieldFrameContract.border,
|
|
72
|
+
},
|
|
73
|
+
item: collectionItemContract,
|
|
74
|
+
sectionLabel: {
|
|
75
|
+
color: semanticColors.content.secondary,
|
|
76
|
+
textVariant: "label",
|
|
77
|
+
paddingHorizontal: spacing.sm,
|
|
78
|
+
paddingVertical: spacing.xs,
|
|
79
|
+
},
|
|
80
|
+
emptyState: {
|
|
81
|
+
color: semanticColors.content.secondary,
|
|
82
|
+
textVariant: "body",
|
|
83
|
+
paddingVertical: spacing.xl,
|
|
84
|
+
},
|
|
85
|
+
transition: { enter: motionPreset.enter, exit: motionPreset.exit },
|
|
86
|
+
};
|
|
87
|
+
export const commandPaletteBehaviorScenarios = [
|
|
88
|
+
"activating-a-result-always-closes-the-palette-regardless-of-dismiss-policy",
|
|
89
|
+
"escape-and-outside-close-without-running-any-command",
|
|
90
|
+
"sections-merge-recents-static-commands-and-search-results-without-a-new-data-model",
|
|
91
|
+
"keyboard-navigation-and-typeahead-reuse-the-shared-collection-helpers-unchanged",
|
|
92
|
+
"local-vs-external-filtering-reuses-comboboxcollectionstate-staleness-guard-unchanged",
|
|
93
|
+
"empty-result-state-is-announced-once-not-per-section",
|
|
94
|
+
"no-global-shortcut-binding-is-owned-here-the-product-decides-the-trigger-key",
|
|
95
|
+
"activate-after-dismiss-lets-a-command-open-the-next-overlay-only-once-exit-completes",
|
|
96
|
+
];
|
|
97
|
+
//# sourceMappingURL=command-palette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-palette.js","sourceRoot":"","sources":["../src/command-palette.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAsHtD,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,IAAI;CAC2B,CAAC;AAEjD,MAAM,UAAU,wBAAwB,CACtC,MAAmC,EACnC,SAAsC,8BAA8B;IAEpE,IAAI,MAAM,KAAK,cAAc,IAAI,MAAM,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,cAAc,CAAC;IACvD,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,aAAa,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC;AAeD,SAAS,cAAc,CAAC,KAAa,EAAE,KAAa;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,SAAS,CAAC,kBAAkB,KAAK,oBAAoB,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,UAAoC;IAEpC,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAC;IACrE,CAAC;IACD,cAAc,CAAC,UAAU,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC;IACpE,cAAc,CAAC,UAAU,CAAC,iBAAiB,EAAE,mBAAmB,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,KAAK,EAAE;QACL,UAAU;QACV,YAAY;QACZ,SAAS;QACT,aAAa;QACb,UAAU;QACV,SAAS;QACT,cAAc;QACd,MAAM;QACN,SAAS;QACT,MAAM;QACN,OAAO;QACP,aAAa;QACb,UAAU;QACV,YAAY;KACJ;IACV,QAAQ,EAAE,QAAQ,CAAC,KAAK;IACxB,OAAO,EAAE;QACP,UAAU,EAAE,uBAAuB,CAAC,UAAU;QAC9C,MAAM,EAAE,uBAAuB,CAAC,MAAM;QACtC,WAAW,EAAE,uBAAuB,CAAC,WAAW;QAChD,MAAM,EAAE,IAAa;QACrB,MAAM,EAAE,uBAAuB,CAAC,MAAM;QACtC,QAAQ,EAAE,GAAG;QACb,SAAS,EAAE,GAAG;KACf;IACD,WAAW,EAAE;QACX,SAAS,EAAE,kBAAkB,CAAC,SAAS;QACvC,iBAAiB,EAAE,kBAAkB,CAAC,iBAAiB;QACvD,WAAW,EAAE,kBAAkB,CAAC,MAAM;KACvC;IACD,IAAI,EAAE,sBAAsB;IAC5B,YAAY,EAAE;QACZ,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,SAAS;QACvC,WAAW,EAAE,OAAgB;QAC7B,iBAAiB,EAAE,OAAO,CAAC,EAAE;QAC7B,eAAe,EAAE,OAAO,CAAC,EAAE;KAC5B;IACD,UAAU,EAAE;QACV,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,SAAS;QACvC,WAAW,EAAE,MAAe;QAC5B,eAAe,EAAE,OAAO,CAAC,EAAE;KAC5B;IACD,UAAU,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE;CAC1D,CAAC;AAEX,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,4EAA4E;IAC5E,sDAAsD;IACtD,oFAAoF;IACpF,iFAAiF;IACjF,sFAAsF;IACtF,sDAAsD;IACtD,8EAA8E;IAC9E,sFAAsF;CAC9E,CAAC","sourcesContent":["import type { CollectionKey, ComboboxInput, MenuItemDescriptor } from \"./behaviors.js\";\nimport type { CollectionSource, ComboboxCollectionState } from \"./collection.js\";\nimport {\n collectionItemContract,\n fieldFrameContract,\n floatingSurfaceContract,\n} from \"./component-contracts.js\";\nimport { backdrop, motionPreset, spacing } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\n/**\n * antd has no direct crosswalk target for CommandPalette — it is not in\n * `antDesignReferenceComponents`. The nearest antd surface, `AutoComplete`/\n * `Select` with `showSearch`, is exactly the composition question this\n * module answers below, not a separate coverage gap.\n *\n * Decisive difference from Combobox: **a result is an action, not a\n * persisted value.** Committing a Combobox sets `selectedKey` as the field's\n * ongoing value, and `inputValue` goes on mirroring it. Running \"새 트윗\n * 작성\" has no ongoing value anywhere to remember — the palette closes and\n * resets. Forcing `selectedKey`/`onCommit` onto that would create a\n * phantom value that is always `null` again the instant the palette reopens,\n * the same category of dead-state mistake `docs/dropdown.md` avoided by not\n * re-defining Menu's problem under a second name. So items here are shaped\n * like `MenuItemDescriptor` (carries `shortcut`/`tone` for destructive\n * commands), not `SelectItemDescriptor` (which deliberately strips both,\n * because a Select option is a value, not an action).\n *\n * Everything else composes from existing contracts without changes:\n * - **Heterogeneous sources** (\"최근\" / \"명령어\" / \"검색 결과\" in one list):\n * already representable — `CollectionSource`'s `sections` is exactly\n * grouped items, no new data model.\n * - **Search/filter text**: `ComboboxInput` (inputValue/defaultInputValue/\n * onInputValueChange) and `ComboboxCollectionState` (local vs. external\n * filtering, `queryValue`/`resultQuery` staleness guard) are reused\n * verbatim — a command search is the same async-search problem Combobox\n * already solved, just over commands instead of selectable values.\n * - **Keyboard navigation/typeahead across sections**: `getCollectionNavigationTarget`/\n * `getCollectionTypeaheadMatch` (`src/collection.ts`) already generalize\n * over any `CollectionSource`; nothing palette-specific to add.\n * - **Global keyboard shortcut** (⌘K): explicitly out of scope. Which key\n * combination opens the palette, and whether it is global or scoped, is a\n * product/app decision — the same reason Link does not own navigation and\n * BottomNavigation does not own the router's route state.\n */\nexport type CommandPaletteItemDescriptor<Key extends CollectionKey = CollectionKey> =\n MenuItemDescriptor<Key>;\n\nexport type CommandPaletteSource<\n Key extends CollectionKey = CollectionKey,\n SectionKey extends CollectionKey = CollectionKey,\n> = CollectionSource<Key, SectionKey>;\n\nexport type CommandPaletteInput = ComboboxInput;\nexport type CommandPaletteQueryState = ComboboxCollectionState;\n\nexport type CommandPaletteActivateReason = \"pointer\" | \"keyboard\";\n\n/**\n * Mirrors Menu's `onAction`/`onActionAfterDismiss` split (`behaviorRegistry.menu`)\n * without importing it — Menu, like Dialog, predates the per-component\n * `src/<name>.ts` convention and has no exported type of its own to import,\n * only string literals in the shared registry. `onActivate` fires\n * immediately; `onActivateAfterDismiss` fires once the exit transition\n * completes, for a command that itself opens another overlay (the same\n * \"close first, open the next surface after exit completes\" ordering\n * `docs/architecture.md`'s overlay-stack rule already requires).\n */\nexport type CommandPaletteActivateHandler<Key extends CollectionKey = CollectionKey> = (\n itemId: Key,\n reason: CommandPaletteActivateReason,\n) => void;\n\n/**\n * Web-only modal overlay (catalog: `platform: \"web\"`) — there is no `modal`\n * axis the way SidePanel needs one; a command palette is always a modal\n * takeover, never an inline non-modal surface. No `back`/`swipe` for the\n * same web-only reason `SidePanelDismissReason` excludes them.\n *\n * `\"activation\"` is a dismiss reason, not merely an event: running a command\n * always closes the palette, which is why `canDismissCommandPalette` treats\n * it like `\"programmatic\"` — an owner-level certainty no policy can veto.\n * There is no `busy` axis blocking dismissal while a command executes: the\n * palette itself is fire-and-forget (`onActivate` fires and the palette\n * closes); if the command's own effect is asynchronous, that runs after the\n * palette is already gone, the same ordering Menu's `onActionAfterDismiss`\n * already models. Recreating AlertDialog's `idle→busy→error` session here\n * would be guessing at a requirement (a command that must block the palette\n * open until it settles) with no measured product need.\n */\nexport type CommandPaletteDismissReason =\n | \"close-action\"\n | \"outside\"\n | \"escape\"\n | \"activation\"\n | \"programmatic\";\n\nexport type CommandPaletteOpenChangeDetails = Readonly<{\n reason: \"trigger\" | CommandPaletteDismissReason;\n}>;\n\nexport type ControlledCommandPaletteOpenState = Readonly<{\n open: boolean;\n defaultOpen?: never;\n onOpenChange(open: boolean, details: CommandPaletteOpenChangeDetails): void;\n}>;\n\nexport type UncontrolledCommandPaletteOpenState = Readonly<{\n open?: never;\n defaultOpen?: boolean;\n onOpenChange?: (\n open: boolean,\n details: CommandPaletteOpenChangeDetails,\n ) => void;\n}>;\n\nexport type CommandPaletteOpenState =\n | ControlledCommandPaletteOpenState\n | UncontrolledCommandPaletteOpenState;\n\nexport type CommandPaletteDismissPolicy = Readonly<{\n dismissible: boolean;\n outsideDismiss: boolean;\n escapeDismiss: boolean;\n}>;\n\nexport const commandPaletteBehaviorDefaults = {\n dismissible: true,\n outsideDismiss: true,\n escapeDismiss: true,\n} as const satisfies CommandPaletteDismissPolicy;\n\nexport function canDismissCommandPalette(\n reason: CommandPaletteDismissReason,\n policy: CommandPaletteDismissPolicy = commandPaletteBehaviorDefaults,\n): boolean {\n if (reason === \"programmatic\" || reason === \"activation\") return true;\n if (!policy.dismissible) return false;\n if (reason === \"outside\") return policy.outsideDismiss;\n if (reason === \"escape\") return policy.escapeDismiss;\n return true;\n}\n\n/**\n * `accessibilityLabel` is required, not optional like Popover's — a command\n * palette's `role=\"dialog\"` surface has no visible heading the way Dialog's\n * `title` slot or typical Popover content provides; the search field alone\n * is not a reliable accessible name across renderers. `searchPlaceholder` is\n * required for the same reason `LoadMoreLabels`/`PaginationLabels` require\n * every field: a renderer must not invent untranslated fallback copy.\n */\nexport type CommandPaletteDescriptor = Readonly<{\n accessibilityLabel: string;\n searchPlaceholder: string;\n}>;\n\nfunction assertNonEmpty(value: string, field: string): void {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new TypeError(`CommandPalette ${field} must not be empty`);\n }\n}\n\nexport function validateCommandPaletteDescriptor(\n descriptor: CommandPaletteDescriptor,\n): void {\n if (descriptor === null || typeof descriptor !== \"object\") {\n throw new TypeError(\"CommandPalette descriptor must be an object\");\n }\n assertNonEmpty(descriptor.accessibilityLabel, \"accessibilityLabel\");\n assertNonEmpty(descriptor.searchPlaceholder, \"searchPlaceholder\");\n}\n\n/**\n * Anatomy only — chrome for the modal shell and the pinned search field,\n * reusing the exact tokens Dialog-family and Menu-family recipes already use\n * (`floatingSurfaceContract`, `fieldFrameContract`, `collectionItemContract`)\n * instead of inventing new ones. Result rows and section labels reuse\n * `collectionItemContract` the same way `menuRecipe`/`treeRecipe` do — a\n * command result is chrome-identical to a Menu item, it just lives in a\n * modal instead of an anchored popup.\n */\nexport const commandPaletteRecipe = {\n slots: [\n \"backdrop\",\n \"positioner\",\n \"content\",\n \"searchField\",\n \"viewport\",\n \"section\",\n \"sectionLabel\",\n \"item\",\n \"leading\",\n \"copy\",\n \"label\",\n \"description\",\n \"shortcut\",\n \"emptyState\",\n ] as const,\n backdrop: backdrop.modal,\n content: {\n background: floatingSurfaceContract.background,\n border: floatingSurfaceContract.border,\n borderWidth: floatingSurfaceContract.borderWidth,\n radius: \"lg\" as const,\n shadow: floatingSurfaceContract.shadow,\n maxWidth: 560,\n maxHeight: 420,\n },\n searchField: {\n minHeight: fieldFrameContract.minHeight,\n paddingHorizontal: fieldFrameContract.paddingHorizontal,\n borderColor: fieldFrameContract.border,\n },\n item: collectionItemContract,\n sectionLabel: {\n color: semanticColors.content.secondary,\n textVariant: \"label\" as const,\n paddingHorizontal: spacing.sm,\n paddingVertical: spacing.xs,\n },\n emptyState: {\n color: semanticColors.content.secondary,\n textVariant: \"body\" as const,\n paddingVertical: spacing.xl,\n },\n transition: { enter: motionPreset.enter, exit: motionPreset.exit },\n} as const;\n\nexport const commandPaletteBehaviorScenarios = [\n \"activating-a-result-always-closes-the-palette-regardless-of-dismiss-policy\",\n \"escape-and-outside-close-without-running-any-command\",\n \"sections-merge-recents-static-commands-and-search-results-without-a-new-data-model\",\n \"keyboard-navigation-and-typeahead-reuse-the-shared-collection-helpers-unchanged\",\n \"local-vs-external-filtering-reuses-comboboxcollectionstate-staleness-guard-unchanged\",\n \"empty-result-state-is-announced-once-not-per-section\",\n \"no-global-shortcut-binding-is-owned-here-the-product-decides-the-trigger-key\",\n \"activate-after-dismiss-lets-a-command-open-the-next-overlay-only-once-exit-completes\",\n] as const;\n"]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/** Internal visual fragments keep future recipes from inventing new chrome. */
|
|
2
|
+
export declare const focusIndicatorContract: {
|
|
3
|
+
readonly color: Readonly<{
|
|
4
|
+
source: "theme";
|
|
5
|
+
key: "contentBrand";
|
|
6
|
+
alpha?: number;
|
|
7
|
+
}>;
|
|
8
|
+
readonly width: 2;
|
|
9
|
+
readonly offset: 2;
|
|
10
|
+
};
|
|
11
|
+
export declare const fieldFrameContract: {
|
|
12
|
+
readonly background: Readonly<{
|
|
13
|
+
source: "theme";
|
|
14
|
+
key: "surface";
|
|
15
|
+
alpha?: number;
|
|
16
|
+
}>;
|
|
17
|
+
readonly border: Readonly<{
|
|
18
|
+
source: "theme";
|
|
19
|
+
key: "textMuted";
|
|
20
|
+
alpha?: number;
|
|
21
|
+
}>;
|
|
22
|
+
readonly focusBorder: Readonly<{
|
|
23
|
+
source: "theme";
|
|
24
|
+
key: "contentBrand";
|
|
25
|
+
alpha?: number;
|
|
26
|
+
}>;
|
|
27
|
+
readonly invalidBorder: Readonly<{
|
|
28
|
+
source: "theme";
|
|
29
|
+
key: "danger";
|
|
30
|
+
alpha?: number;
|
|
31
|
+
}>;
|
|
32
|
+
readonly radius: "md";
|
|
33
|
+
readonly borderWidth: 1;
|
|
34
|
+
readonly minHeight: 44;
|
|
35
|
+
readonly paddingHorizontal: 16;
|
|
36
|
+
};
|
|
37
|
+
export declare const formSupportContract: {
|
|
38
|
+
readonly label: {
|
|
39
|
+
readonly color: Readonly<{
|
|
40
|
+
source: "theme";
|
|
41
|
+
key: "textBody";
|
|
42
|
+
alpha?: number;
|
|
43
|
+
}>;
|
|
44
|
+
readonly textVariant: "body";
|
|
45
|
+
readonly fontWeight: "600";
|
|
46
|
+
};
|
|
47
|
+
readonly hint: {
|
|
48
|
+
readonly color: Readonly<{
|
|
49
|
+
source: "theme";
|
|
50
|
+
key: "textMuted";
|
|
51
|
+
alpha?: number;
|
|
52
|
+
}>;
|
|
53
|
+
readonly textVariant: "label";
|
|
54
|
+
};
|
|
55
|
+
readonly error: {
|
|
56
|
+
readonly color: Readonly<{
|
|
57
|
+
source: "theme";
|
|
58
|
+
key: "danger";
|
|
59
|
+
alpha?: number;
|
|
60
|
+
}>;
|
|
61
|
+
readonly textVariant: "label";
|
|
62
|
+
};
|
|
63
|
+
readonly gap: 8;
|
|
64
|
+
};
|
|
65
|
+
export declare const floatingSurfaceContract: {
|
|
66
|
+
readonly background: Readonly<{
|
|
67
|
+
source: "theme";
|
|
68
|
+
key: "bg";
|
|
69
|
+
alpha?: number;
|
|
70
|
+
}>;
|
|
71
|
+
readonly border: Readonly<{
|
|
72
|
+
source: "theme";
|
|
73
|
+
key: "border";
|
|
74
|
+
alpha?: number;
|
|
75
|
+
}>;
|
|
76
|
+
readonly borderWidth: 1;
|
|
77
|
+
readonly radius: "md";
|
|
78
|
+
readonly shadow: {
|
|
79
|
+
readonly color: "#000000";
|
|
80
|
+
readonly opacity: 0.12;
|
|
81
|
+
readonly radius: 12;
|
|
82
|
+
readonly offsetY: 4;
|
|
83
|
+
};
|
|
84
|
+
readonly padding: 8;
|
|
85
|
+
};
|
|
86
|
+
export declare const collectionItemContract: {
|
|
87
|
+
readonly minHeight: 44;
|
|
88
|
+
readonly paddingHorizontal: 12;
|
|
89
|
+
readonly gap: 12;
|
|
90
|
+
readonly radius: "md";
|
|
91
|
+
readonly label: {
|
|
92
|
+
readonly color: Readonly<{
|
|
93
|
+
source: "theme";
|
|
94
|
+
key: "textBody";
|
|
95
|
+
alpha?: number;
|
|
96
|
+
}>;
|
|
97
|
+
readonly textVariant: "body";
|
|
98
|
+
};
|
|
99
|
+
readonly description: {
|
|
100
|
+
readonly color: Readonly<{
|
|
101
|
+
source: "theme";
|
|
102
|
+
key: "textMuted";
|
|
103
|
+
alpha?: number;
|
|
104
|
+
}>;
|
|
105
|
+
readonly textVariant: "label";
|
|
106
|
+
};
|
|
107
|
+
readonly highlightedBackground: Readonly<{
|
|
108
|
+
source: "theme";
|
|
109
|
+
key: "text";
|
|
110
|
+
alpha?: number;
|
|
111
|
+
}>;
|
|
112
|
+
readonly focus: {
|
|
113
|
+
readonly color: Readonly<{
|
|
114
|
+
source: "theme";
|
|
115
|
+
key: "contentBrand";
|
|
116
|
+
alpha?: number;
|
|
117
|
+
}>;
|
|
118
|
+
readonly width: 2;
|
|
119
|
+
readonly offset: 2;
|
|
120
|
+
};
|
|
121
|
+
readonly selectedBackground: Readonly<{
|
|
122
|
+
source: "theme";
|
|
123
|
+
key: "primary";
|
|
124
|
+
alpha?: number;
|
|
125
|
+
}>;
|
|
126
|
+
readonly selectedIndicator: Readonly<{
|
|
127
|
+
source: "theme";
|
|
128
|
+
key: "contentBrand";
|
|
129
|
+
alpha?: number;
|
|
130
|
+
}>;
|
|
131
|
+
readonly danger: Readonly<{
|
|
132
|
+
source: "theme";
|
|
133
|
+
key: "danger";
|
|
134
|
+
alpha?: number;
|
|
135
|
+
}>;
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=component-contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-contracts.d.ts","sourceRoot":"","sources":["../src/component-contracts.ts"],"names":[],"mappings":"AAGA,+EAA+E;AAC/E,eAAO,MAAM,sBAAsB;;;;;;;;CAIzB,CAAC;AAEX,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;CASrB,CAAC;AAEX,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;CAStB,CAAC;AAEX,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;CAO1B,CAAC;AAEX,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAezB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { fontWeight, shadow, spacing, stroke } from "./foundations.js";
|
|
2
|
+
import { semanticColors } from "./semantic-colors.js";
|
|
3
|
+
/** Internal visual fragments keep future recipes from inventing new chrome. */
|
|
4
|
+
export const focusIndicatorContract = {
|
|
5
|
+
color: semanticColors.border.focus,
|
|
6
|
+
width: stroke.focus,
|
|
7
|
+
offset: 2,
|
|
8
|
+
};
|
|
9
|
+
export const fieldFrameContract = {
|
|
10
|
+
background: semanticColors.surface.default,
|
|
11
|
+
border: semanticColors.content.secondary,
|
|
12
|
+
focusBorder: semanticColors.border.focus,
|
|
13
|
+
invalidBorder: semanticColors.border.danger,
|
|
14
|
+
radius: "md",
|
|
15
|
+
borderWidth: stroke.default,
|
|
16
|
+
minHeight: 44,
|
|
17
|
+
paddingHorizontal: spacing.md,
|
|
18
|
+
};
|
|
19
|
+
export const formSupportContract = {
|
|
20
|
+
label: {
|
|
21
|
+
color: semanticColors.content.body,
|
|
22
|
+
textVariant: "body",
|
|
23
|
+
fontWeight: fontWeight.semibold,
|
|
24
|
+
},
|
|
25
|
+
hint: { color: semanticColors.content.secondary, textVariant: "label" },
|
|
26
|
+
error: { color: semanticColors.content.danger, textVariant: "label" },
|
|
27
|
+
gap: spacing.xs,
|
|
28
|
+
};
|
|
29
|
+
export const floatingSurfaceContract = {
|
|
30
|
+
background: semanticColors.canvas,
|
|
31
|
+
border: semanticColors.border.default,
|
|
32
|
+
borderWidth: stroke.default,
|
|
33
|
+
radius: "md",
|
|
34
|
+
shadow: shadow.floating,
|
|
35
|
+
padding: spacing.xs,
|
|
36
|
+
};
|
|
37
|
+
export const collectionItemContract = {
|
|
38
|
+
minHeight: 44,
|
|
39
|
+
paddingHorizontal: spacing.sm,
|
|
40
|
+
gap: spacing.sm,
|
|
41
|
+
radius: "md",
|
|
42
|
+
label: { color: semanticColors.content.body, textVariant: "body" },
|
|
43
|
+
description: {
|
|
44
|
+
color: semanticColors.content.secondary,
|
|
45
|
+
textVariant: "label",
|
|
46
|
+
},
|
|
47
|
+
highlightedBackground: semanticColors.interaction.hover,
|
|
48
|
+
focus: focusIndicatorContract,
|
|
49
|
+
selectedBackground: semanticColors.interaction.selected,
|
|
50
|
+
selectedIndicator: semanticColors.border.focus,
|
|
51
|
+
danger: semanticColors.content.danger,
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=component-contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-contracts.js","sourceRoot":"","sources":["../src/component-contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,KAAK,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK;IAClC,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,MAAM,EAAE,CAAC;CACD,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,UAAU,EAAE,cAAc,CAAC,OAAO,CAAC,OAAO;IAC1C,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,SAAS;IACxC,WAAW,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK;IACxC,aAAa,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM;IAC3C,MAAM,EAAE,IAAa;IACrB,WAAW,EAAE,MAAM,CAAC,OAAO;IAC3B,SAAS,EAAE,EAAE;IACb,iBAAiB,EAAE,OAAO,CAAC,EAAE;CACrB,CAAC;AAEX,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE;QACL,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,IAAI;QAClC,WAAW,EAAE,MAAe;QAC5B,UAAU,EAAE,UAAU,CAAC,QAAQ;KAChC;IACD,IAAI,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAgB,EAAE;IAChF,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,OAAgB,EAAE;IAC9E,GAAG,EAAE,OAAO,CAAC,EAAE;CACP,CAAC;AAEX,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,UAAU,EAAE,cAAc,CAAC,MAAM;IACjC,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO;IACrC,WAAW,EAAE,MAAM,CAAC,OAAO;IAC3B,MAAM,EAAE,IAAa;IACrB,MAAM,EAAE,MAAM,CAAC,QAAQ;IACvB,OAAO,EAAE,OAAO,CAAC,EAAE;CACX,CAAC;AAEX,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,SAAS,EAAE,EAAE;IACb,iBAAiB,EAAE,OAAO,CAAC,EAAE;IAC7B,GAAG,EAAE,OAAO,CAAC,EAAE;IACf,MAAM,EAAE,IAAa;IACrB,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,MAAe,EAAE;IAC3E,WAAW,EAAE;QACX,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,SAAS;QACvC,WAAW,EAAE,OAAgB;KAC9B;IACD,qBAAqB,EAAE,cAAc,CAAC,WAAW,CAAC,KAAK;IACvD,KAAK,EAAE,sBAAsB;IAC7B,kBAAkB,EAAE,cAAc,CAAC,WAAW,CAAC,QAAQ;IACvD,iBAAiB,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK;IAC9C,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,MAAM;CAC7B,CAAC","sourcesContent":["import { fontWeight, shadow, spacing, stroke } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\n/** Internal visual fragments keep future recipes from inventing new chrome. */\nexport const focusIndicatorContract = {\n color: semanticColors.border.focus,\n width: stroke.focus,\n offset: 2,\n} as const;\n\nexport const fieldFrameContract = {\n background: semanticColors.surface.default,\n border: semanticColors.content.secondary,\n focusBorder: semanticColors.border.focus,\n invalidBorder: semanticColors.border.danger,\n radius: \"md\" as const,\n borderWidth: stroke.default,\n minHeight: 44,\n paddingHorizontal: spacing.md,\n} as const;\n\nexport const formSupportContract = {\n label: {\n color: semanticColors.content.body,\n textVariant: \"body\" as const,\n fontWeight: fontWeight.semibold,\n },\n hint: { color: semanticColors.content.secondary, textVariant: \"label\" as const },\n error: { color: semanticColors.content.danger, textVariant: \"label\" as const },\n gap: spacing.xs,\n} as const;\n\nexport const floatingSurfaceContract = {\n background: semanticColors.canvas,\n border: semanticColors.border.default,\n borderWidth: stroke.default,\n radius: \"md\" as const,\n shadow: shadow.floating,\n padding: spacing.xs,\n} as const;\n\nexport const collectionItemContract = {\n minHeight: 44,\n paddingHorizontal: spacing.sm,\n gap: spacing.sm,\n radius: \"md\" as const,\n label: { color: semanticColors.content.body, textVariant: \"body\" as const },\n description: {\n color: semanticColors.content.secondary,\n textVariant: \"label\" as const,\n },\n highlightedBackground: semanticColors.interaction.hover,\n focus: focusIndicatorContract,\n selectedBackground: semanticColors.interaction.selected,\n selectedIndicator: semanticColors.border.focus,\n danger: semanticColors.content.danger,\n} as const;\n"]}
|