@republicroad/seal-appshell 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +74 -0
- package/dist/assets/custom-node-schema.json.d.ts +549 -0
- package/dist/components/__tests__/skinned-decision-graph.test.d.ts +1 -0
- package/dist/components/__tests__/skinned-header.test.d.ts +1 -0
- package/dist/components/__tests__/skinned-panels.test.d.ts +1 -0
- package/dist/components/__tests__/skinned-simulator-panel.test.d.ts +1 -0
- package/dist/components/__tests__/skinned-simulator.test.d.ts +1 -0
- package/dist/components/custom-node/__tests__/custom-node-button.test.d.ts +1 -0
- package/dist/components/custom-node/__tests__/schema-container-tab.test.d.ts +1 -0
- package/dist/components/custom-node/crypto-node.d.ts +5 -0
- package/dist/components/custom-node/current-date-node.d.ts +8 -0
- package/dist/components/custom-node/http-request-node.d.ts +5 -0
- package/dist/components/custom-node/key-value-editor.d.ts +16 -0
- package/dist/components/custom-node/locked-corner-badge.d.ts +2 -0
- package/dist/components/custom-node/query-list-node.d.ts +5 -0
- package/dist/components/custom-node/schema-container-tab.d.ts +13 -0
- package/dist/components/icons/code.d.ts +3 -0
- package/dist/components/icons/flash-circle.d.ts +3 -0
- package/dist/components/reui/alert.d.ts +9 -0
- package/dist/components/reui/autocomplete.d.ts +40 -0
- package/dist/components/reui/badge.d.ts +14 -0
- package/dist/components/reui/cascader/cascader-async.d.ts +86 -0
- package/dist/components/reui/cascader/cascader-columns.d.ts +26 -0
- package/dist/components/reui/cascader/cascader-context.d.ts +190 -0
- package/dist/components/reui/cascader/cascader-footer.d.ts +83 -0
- package/dist/components/reui/cascader/cascader-i18n.d.ts +13 -0
- package/dist/components/reui/cascader/cascader-item.d.ts +112 -0
- package/dist/components/reui/cascader/cascader-lib.d.ts +137 -0
- package/dist/components/reui/cascader/cascader-nav.d.ts +56 -0
- package/dist/components/reui/cascader/cascader-types.d.ts +179 -0
- package/dist/components/reui/cascader/cascader-virtual.d.ts +62 -0
- package/dist/components/reui/cascader/cascader.d.ts +325 -0
- package/dist/components/shell-header.d.ts +20 -0
- package/dist/components/skinned-decision-graph.d.ts +19 -0
- package/dist/components/ui/alert-dialog.d.ts +20 -0
- package/dist/components/ui/avatar.d.ts +5 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/components/ui/field.d.ts +24 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/label.d.ts +4 -0
- package/dist/components/ui/scroll-area.d.ts +4 -0
- package/dist/components/ui/select.d.ts +13 -0
- package/dist/components/ui/separator.d.ts +3 -0
- package/dist/components/ui/sheet.d.ts +23 -0
- package/dist/components/ui/sonner.d.ts +5 -0
- package/dist/components/ui/spinner.d.ts +2 -0
- package/dist/components/ui/switch.d.ts +3 -0
- package/dist/components/ui/tabs.d.ts +6 -0
- package/dist/components/ui/toggle-group.d.ts +13 -0
- package/dist/components/ui/toggle.d.ts +12 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/components/version-history/__tests__/version-history-panel.test.d.ts +1 -0
- package/dist/components/version-history/version-history-panel.d.ts +40 -0
- package/dist/context/theme.provider.d.ts +29 -0
- package/dist/hooks/useCustomNodes.d.ts +16 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +121959 -0
- package/dist/integration/decision-graph-appshell.stories.d.ts +10 -0
- package/dist/lib/__tests__/crypto-protocol.test.d.ts +1 -0
- package/dist/lib/__tests__/custom-node-registry.test.d.ts +1 -0
- package/dist/lib/__tests__/http-request-protocol.test.d.ts +1 -0
- package/dist/lib/__tests__/json-path-protocol.test.d.ts +1 -0
- package/dist/lib/__tests__/storage-key.test.d.ts +1 -0
- package/dist/lib/auth/__tests__/adapter.test.d.ts +1 -0
- package/dist/lib/auth/adapter.d.ts +7 -0
- package/dist/lib/auth-client.d.ts +3 -0
- package/dist/lib/crypto-protocol.d.ts +28 -0
- package/dist/lib/custom-node-plans.d.ts +24 -0
- package/dist/lib/custom-node-registry.d.ts +13 -0
- package/dist/lib/custom-node-schema-source.d.ts +6 -0
- package/dist/lib/custom-node-types.d.ts +73 -0
- package/dist/lib/http-request-protocol.d.ts +47 -0
- package/dist/lib/json-path-protocol.d.ts +11 -0
- package/dist/lib/roster-source.d.ts +12 -0
- package/dist/lib/storage-key.d.ts +5 -0
- package/dist/lib/user-resolver.d.ts +6 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/reui/icons/animated/duotone/lock.d.ts +3 -0
- package/dist/reui/icons/animated/outline/play-circle.d.ts +3 -0
- package/dist/reui/icons/default/outline/plus-circle.d.ts +3 -0
- package/dist/reui/icons/default/outline/shield-search.d.ts +3 -0
- package/dist/reui/icons/default/outline/trash-square.d.ts +3 -0
- package/dist/setupTests.d.ts +0 -0
- package/dist/shell/__tests__/default-simulate.test.d.ts +1 -0
- package/dist/shell/__tests__/graphs-http-adapter.test.d.ts +1 -0
- package/dist/shell/__tests__/indexed-db-adapter.test.d.ts +0 -0
- package/dist/shell/__tests__/restore.test.d.ts +0 -0
- package/dist/shell/default-simulate.d.ts +3 -0
- package/dist/shell/editor-shell.context.d.ts +22 -0
- package/dist/shell/execute-simulate.d.ts +8 -0
- package/dist/shell/graphs-http-adapter.d.ts +7 -0
- package/dist/shell/index.d.ts +10 -0
- package/dist/shell/indexed-db-adapter.d.ts +16 -0
- package/dist/shell/persistence.d.ts +89 -0
- package/dist/shell/restore.d.ts +21 -0
- package/dist/shell/types.d.ts +20 -0
- package/dist/skin/__tests__/apply.test.d.ts +1 -0
- package/dist/skin/apply.d.ts +7 -0
- package/dist/skin/layout.d.ts +17 -0
- package/dist/skin/types.d.ts +73 -0
- package/dist/style.css +2 -0
- package/package.json +73 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export declare const Hint: React.FC<{
|
|
3
|
+
label: string;
|
|
4
|
+
children: React.ReactElement;
|
|
5
|
+
}>;
|
|
6
|
+
export interface KeyValueEditorProps {
|
|
7
|
+
label: string;
|
|
8
|
+
addLabel: string;
|
|
9
|
+
deleteLabel: string;
|
|
10
|
+
valuePlaceholder: string;
|
|
11
|
+
rawPlaceholder: string;
|
|
12
|
+
value: string;
|
|
13
|
+
onChange: (next: string) => void;
|
|
14
|
+
}
|
|
15
|
+
/** `{ k: expr, ... }` 对象字面量 ⇄ 键值行编辑器;无法解析时自动切原始表达式模式 */
|
|
16
|
+
export declare const KeyValueEditor: React.FC<KeyValueEditorProps>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { CustomFunctionTool } from '../../lib/custom-node-types';
|
|
3
|
+
type SchemaContainerTabProps = {
|
|
4
|
+
id: string;
|
|
5
|
+
tools: CustomFunctionTool[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* schema 驱动集合容器节点的编辑面板(udf-lab 缺陷修复):
|
|
9
|
+
* 左列 key 文本框可编辑;右列函数用下拉展示(限定命名空间工具集);
|
|
10
|
+
* 参数按位置序渲染表达式输入(字面量参数由调用方自带引号)。
|
|
11
|
+
*/
|
|
12
|
+
export declare const SchemaContainerTab: React.FC<SchemaContainerTabProps>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { VariantProps } from 'class-variance-authority';
|
|
2
|
+
declare const alertVariants: (props?: ({
|
|
3
|
+
variant?: "default" | "destructive" | "success" | "warning" | "info" | "invert" | null | undefined;
|
|
4
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
5
|
+
declare function Alert({ className, variant, ...props }: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>): import('react').JSX.Element;
|
|
6
|
+
declare function AlertTitle({ className, ...props }: React.ComponentProps<'div'>): import('react').JSX.Element;
|
|
7
|
+
declare function AlertDescription({ className, ...props }: React.ComponentProps<'div'>): import('react').JSX.Element;
|
|
8
|
+
declare function AlertAction({ className, ...props }: React.ComponentProps<'div'>): import('react').JSX.Element;
|
|
9
|
+
export { Alert, AlertTitle, AlertDescription, AlertAction };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Autocomplete as AutocompletePrimitive } from '@base-ui/react/autocomplete';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const inputVariants: (props?: ({
|
|
4
|
+
size?: "default" | "sm" | "lg" | null | undefined;
|
|
5
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
6
|
+
declare const Autocomplete: typeof AutocompletePrimitive.Root;
|
|
7
|
+
declare function AutocompleteValue({ ...props }: AutocompletePrimitive.Value.Props): import('react').JSX.Element;
|
|
8
|
+
declare function AutocompleteInput({ className, size, showClear, showTrigger, ...props }: Omit<AutocompletePrimitive.Input.Props, 'size'> & VariantProps<typeof inputVariants> & {
|
|
9
|
+
showClear?: boolean;
|
|
10
|
+
showTrigger?: boolean;
|
|
11
|
+
}): import('react').JSX.Element;
|
|
12
|
+
declare function AutocompleteStatus({ className, ...props }: AutocompletePrimitive.Status.Props): import('react').JSX.Element;
|
|
13
|
+
declare function AutocompletePortal({ ...props }: AutocompletePrimitive.Portal.Props): import('react').JSX.Element;
|
|
14
|
+
declare function AutocompleteBackdrop({ ...props }: AutocompletePrimitive.Backdrop.Props): import('react').JSX.Element;
|
|
15
|
+
declare function AutocompletePositioner({ className, ...props }: AutocompletePrimitive.Positioner.Props): import('react').JSX.Element;
|
|
16
|
+
declare function AutocompleteList({ className, scrollAreaClassName, ...props }: AutocompletePrimitive.List.Props & {
|
|
17
|
+
scrollAreaClassName?: string;
|
|
18
|
+
scrollFade?: boolean;
|
|
19
|
+
scrollbarGutter?: boolean;
|
|
20
|
+
}): import('react').JSX.Element;
|
|
21
|
+
declare function AutocompleteCollection({ ...props }: React.ComponentProps<typeof AutocompletePrimitive.Collection>): import('react').JSX.Element;
|
|
22
|
+
declare function AutocompleteRow({ className, ...props }: React.ComponentProps<typeof AutocompletePrimitive.Row>): import('react').JSX.Element;
|
|
23
|
+
declare function AutocompleteItem({ className, ...props }: React.ComponentProps<typeof AutocompletePrimitive.Item>): import('react').JSX.Element;
|
|
24
|
+
export interface AutocompleteContentProps extends React.ComponentProps<typeof AutocompletePrimitive.Popup> {
|
|
25
|
+
align?: AutocompletePrimitive.Positioner.Props['align'];
|
|
26
|
+
sideOffset?: AutocompletePrimitive.Positioner.Props['sideOffset'];
|
|
27
|
+
alignOffset?: AutocompletePrimitive.Positioner.Props['alignOffset'];
|
|
28
|
+
side?: AutocompletePrimitive.Positioner.Props['side'];
|
|
29
|
+
anchor?: AutocompletePrimitive.Positioner.Props['anchor'];
|
|
30
|
+
showBackdrop?: boolean;
|
|
31
|
+
}
|
|
32
|
+
declare function AutocompleteContent({ className, children, showBackdrop, align, sideOffset, alignOffset, side, anchor, ...props }: AutocompleteContentProps): import('react').JSX.Element;
|
|
33
|
+
declare function AutocompleteGroup({ ...props }: React.ComponentProps<typeof AutocompletePrimitive.Group>): import('react').JSX.Element;
|
|
34
|
+
declare function AutocompleteGroupLabel({ className, ...props }: React.ComponentProps<typeof AutocompletePrimitive.GroupLabel>): import('react').JSX.Element;
|
|
35
|
+
declare function AutocompleteEmpty({ className, ...props }: React.ComponentProps<typeof AutocompletePrimitive.Empty>): import('react').JSX.Element;
|
|
36
|
+
declare function AutocompleteClear({ className, ...props }: React.ComponentProps<typeof AutocompletePrimitive.Clear>): import('react').JSX.Element;
|
|
37
|
+
declare function AutocompleteTrigger({ className, ...props }: React.ComponentProps<typeof AutocompletePrimitive.Trigger>): import('react').JSX.Element;
|
|
38
|
+
declare function AutocompleteArrow({ ...props }: React.ComponentProps<typeof AutocompletePrimitive.Arrow>): import('react').JSX.Element;
|
|
39
|
+
declare function AutocompleteSeparator({ className, ...props }: React.ComponentProps<typeof AutocompletePrimitive.Separator>): import('react').JSX.Element;
|
|
40
|
+
export { Autocomplete, AutocompleteValue, AutocompleteTrigger, AutocompleteInput, AutocompleteStatus, AutocompletePortal, AutocompleteBackdrop, AutocompletePositioner, AutocompleteContent, AutocompleteList, AutocompleteCollection, AutocompleteRow, AutocompleteItem, AutocompleteGroup, AutocompleteGroupLabel, AutocompleteEmpty, AutocompleteClear, AutocompleteArrow, AutocompleteSeparator, };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const badgeVariants: (props?: ({
|
|
4
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "focus" | "success" | "warning" | "info" | "invert" | "primary-light" | "warning-light" | "success-light" | "info-light" | "destructive-light" | "invert-light" | "focus-light" | "primary-outline" | "warning-outline" | "success-outline" | "info-outline" | "destructive-outline" | "invert-outline" | "focus-outline" | null | undefined;
|
|
5
|
+
size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
|
|
6
|
+
radius?: "default" | "full" | null | undefined;
|
|
7
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
8
|
+
interface BadgeProps extends useRender.ComponentProps<'span'> {
|
|
9
|
+
variant?: VariantProps<typeof badgeVariants>['variant'];
|
|
10
|
+
size?: VariantProps<typeof badgeVariants>['size'];
|
|
11
|
+
radius?: VariantProps<typeof badgeVariants>['radius'];
|
|
12
|
+
}
|
|
13
|
+
declare function Badge({ className, variant, size, radius, render, ...props }: BadgeProps): import('react').ReactElement<any, string | import('react').JSXElementConstructor<any>>;
|
|
14
|
+
export { Badge, badgeVariants, type BadgeProps };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { CascaderIndex, CascaderLoadContext, CascaderLoadReason, CascaderLoadResult, CascaderLoadState, CascaderNode, CascaderSearchContext } from '../../../components/reui/cascader/cascader-types';
|
|
2
|
+
/**
|
|
3
|
+
* Async data for the cascader. Loaded pages live in their own store and are
|
|
4
|
+
* MERGED onto the index built from `items`, never folded into that build:
|
|
5
|
+
* `items` changes identity on any parent re-render, and folding would discard
|
|
6
|
+
* every level the user drilled into. Map membership is the load discriminator:
|
|
7
|
+
* no `states` entry means never fetched, while an entry with no `loading`, no
|
|
8
|
+
* `error` and no children means empty for real.
|
|
9
|
+
*/
|
|
10
|
+
/** Fetches one level. `node` is `null` for the root level. */
|
|
11
|
+
export type CascaderGetChildren<T = unknown> = (node: CascaderNode<T> | null, context: CascaderLoadContext) => CascaderNode<T>[] | CascaderLoadResult<T> | Promise<CascaderNode<T>[] | CascaderLoadResult<T>>;
|
|
12
|
+
/** Server-side search, replacing the local index scan while the query is set. */
|
|
13
|
+
export type CascaderOnSearch<T = unknown> = (query: string, context: CascaderSearchContext) => CascaderNode<T>[] | CascaderLoadResult<T> | Promise<CascaderNode<T>[] | CascaderLoadResult<T>>;
|
|
14
|
+
/** Resolves a selected value to its ancestor chain, root first, node last. */
|
|
15
|
+
export type CascaderResolveValue<T = unknown> = (value: string, context: CascaderLoadContext) => CascaderNode<T>[] | Promise<CascaderNode<T>[]>;
|
|
16
|
+
export interface CascaderLoaderStore<T = unknown> {
|
|
17
|
+
/** Keyed by LEVEL: a parent's value, or `CASCADER_ROOT_KEY` for the root. */
|
|
18
|
+
pages: Map<string, CascaderNode<T>[]>;
|
|
19
|
+
states: Map<string, CascaderLoadState>;
|
|
20
|
+
/** Keyed by node value: search hits and resolved selections, level-less. */
|
|
21
|
+
detached: Map<string, CascaderNode<T>>;
|
|
22
|
+
}
|
|
23
|
+
export interface UseCascaderLoaderOptions<T = unknown> {
|
|
24
|
+
/** The index built from `items`, before any pages are merged in. */
|
|
25
|
+
base: CascaderIndex<T>;
|
|
26
|
+
getChildren?: CascaderGetChildren<T>;
|
|
27
|
+
onSearch?: CascaderOnSearch<T>;
|
|
28
|
+
resolveValue?: CascaderResolveValue<T>;
|
|
29
|
+
/** Milliseconds of quiet before `onSearch` fires. */
|
|
30
|
+
searchDebounce?: number;
|
|
31
|
+
/** Changing this drops every cached page, state and detached node. */
|
|
32
|
+
loadKey?: unknown;
|
|
33
|
+
/** Speculatively fetch a branch's children when it is highlighted. */
|
|
34
|
+
prefetch?: boolean;
|
|
35
|
+
/** Called when a request fails. Never for an aborted or superseded one. */
|
|
36
|
+
onLoadError?: (error: unknown, context: {
|
|
37
|
+
parent: string | null;
|
|
38
|
+
reason: string;
|
|
39
|
+
}) => void;
|
|
40
|
+
/** Whether the panel is live: the popup is open, or the cascader is inline. */
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
query: string;
|
|
43
|
+
/** Level keys that are currently on screen. Root is `CASCADER_ROOT_KEY`. */
|
|
44
|
+
levels: string[];
|
|
45
|
+
/** The navigation path, handed to `onSearch` as its scope. */
|
|
46
|
+
path: string[];
|
|
47
|
+
/** Current selection, for `resolveValue`. */
|
|
48
|
+
values: string[];
|
|
49
|
+
}
|
|
50
|
+
export interface CascaderLoader<T = unknown> {
|
|
51
|
+
/** Whether a `getChildren` loader is configured at all. */
|
|
52
|
+
active: boolean;
|
|
53
|
+
store: CascaderLoaderStore<T>;
|
|
54
|
+
states: ReadonlyMap<string, CascaderLoadState>;
|
|
55
|
+
/**
|
|
56
|
+
* Async search hits, `null` when no `onSearch` is running. EMPTY while the
|
|
57
|
+
* first request is in flight, so the level behind is not shown as the answer.
|
|
58
|
+
*/
|
|
59
|
+
searchResults: CascaderNode<T>[] | null;
|
|
60
|
+
searchState: CascaderLoadState | null;
|
|
61
|
+
/**
|
|
62
|
+
* Fetches a level's FIRST page. No-ops on a `states` entry (in flight,
|
|
63
|
+
* loaded or failed) or when `items` fills the level; pages are never
|
|
64
|
+
* consulted, so a `resolveValue` chain still fetches. The level effect fires
|
|
65
|
+
* only for on-screen levels, so a branch merely PRESSED is asked for by hand.
|
|
66
|
+
*/
|
|
67
|
+
ensureLevel: (parentKey: string, reason: CascaderLoadReason) => void;
|
|
68
|
+
/** Fetches the next page of a level. No-ops unless one is available. */
|
|
69
|
+
loadMore: (parentKey: string) => void;
|
|
70
|
+
/** Refires a failed level. No-ops unless that level is in an error state. */
|
|
71
|
+
retryLevel: (parentKey: string) => void;
|
|
72
|
+
/** Schedules a speculative fetch. Safe to call on every highlight move. */
|
|
73
|
+
prefetchNode: (node: CascaderNode<T> | null | undefined) => void;
|
|
74
|
+
/**
|
|
75
|
+
* Evicts ONE level: aborts its request, drops its `states`/`pages` entries
|
|
76
|
+
* and paging latch, so the level effect refetches it. `null` = root level.
|
|
77
|
+
*/
|
|
78
|
+
invalidateLevel: (value: string | null) => void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The loader. A SIBLING of the `buildCascaderIndex` memo, never inside it: the
|
|
82
|
+
* build stays pure in `items`, the merge pure in that build plus this store.
|
|
83
|
+
*/
|
|
84
|
+
export declare function useCascaderLoader<T = unknown>({ base, getChildren, onSearch, resolveValue, searchDebounce, loadKey, prefetch, onLoadError, enabled, query, levels, path, values, }: UseCascaderLoaderOptions<T>): CascaderLoader<T>;
|
|
85
|
+
/** One level's load state, `null` when never fetched. Omit for the root. */
|
|
86
|
+
export declare function useCascaderLoadState(parent?: string | null): CascaderLoadState | null;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CascaderColumn } from '../../../components/reui/cascader/cascader-context';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
export interface CascaderColumnsProps extends Omit<React.ComponentProps<'div'>, 'children'> {
|
|
4
|
+
/** Width of each column. */
|
|
5
|
+
columnWidth?: number | string;
|
|
6
|
+
/** Height CAP per column. Falls back to the root `maxHeight`, then 24rem. */
|
|
7
|
+
maxHeight?: number | string;
|
|
8
|
+
/** Replaces the default panel; the seam a windowed column plugs into. */
|
|
9
|
+
children?: (column: CascaderColumn) => React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Miller columns: the open trail side by side, one panel per level. Only the
|
|
13
|
+
* DEEPEST column is a real listbox (Base UI owns exactly one list); the trail
|
|
14
|
+
* behind is plain buttons, which keeps one state machine instead of a second,
|
|
15
|
+
* 2D one. `CascaderInput` moves between columns with ArrowLeft/ArrowRight.
|
|
16
|
+
*/
|
|
17
|
+
declare function CascaderColumns({ className, columnWidth, maxHeight: maxHeightProp, children, ...props }: CascaderColumnsProps): React.JSX.Element | null;
|
|
18
|
+
export interface CascaderColumnPanelProps {
|
|
19
|
+
column: CascaderColumn;
|
|
20
|
+
/** Replaces the panel's rows; the empty state still wins on an empty column. */
|
|
21
|
+
children?: React.ReactNode;
|
|
22
|
+
/** Containing block for the windowed column's absolutely positioned rows. */
|
|
23
|
+
virtualized?: boolean;
|
|
24
|
+
}
|
|
25
|
+
declare function CascaderColumnPanel({ column, children, virtualized }: CascaderColumnPanelProps): React.JSX.Element;
|
|
26
|
+
export { CascaderColumnPanel, CascaderColumns };
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { CascaderActionItem, CascaderChangeReason, CascaderFlatNode, CascaderIndex, CascaderLabels, CascaderLoadState, CascaderMode, CascaderNode, CascaderSearchScope } from '../../../components/reui/cascader/cascader-types';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Four contexts, not one: actions (config and callbacks, near-stable), state
|
|
5
|
+
* (every keystroke), render (`renderItem` identity) and highlight (every arrow
|
|
6
|
+
* key and pointer move). One combined context re-rendered every row on every
|
|
7
|
+
* keystroke, which is what made `React.memo` on the row worth nothing.
|
|
8
|
+
*/
|
|
9
|
+
export interface CascaderColumn<T = unknown> {
|
|
10
|
+
parent: CascaderNode<T> | null;
|
|
11
|
+
items: CascaderNode<T>[];
|
|
12
|
+
depth: number;
|
|
13
|
+
/** The node in this column that is drilled into, if any. */
|
|
14
|
+
activeValue: string | null;
|
|
15
|
+
/** Whether this is the deepest column, the one Base UI owns. */
|
|
16
|
+
active: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface CascaderItemState<T = unknown> {
|
|
19
|
+
branch: boolean;
|
|
20
|
+
selected: boolean;
|
|
21
|
+
disabled: boolean;
|
|
22
|
+
depth: number;
|
|
23
|
+
count: number;
|
|
24
|
+
/** Ancestor chain, root first. Populated for deep-search rows. */
|
|
25
|
+
path: CascaderNode<T>[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Everything derived from the query, the path and the selection. One keystroke
|
|
29
|
+
* rebuilds most of it, so never subscribe to it from a row.
|
|
30
|
+
*/
|
|
31
|
+
export interface CascaderStateContextValue<T = unknown> {
|
|
32
|
+
/** Same `useMemo` identity as the actions context's `index`. */
|
|
33
|
+
index: CascaderIndex<T>;
|
|
34
|
+
path: string[];
|
|
35
|
+
expanded: ReadonlySet<string>;
|
|
36
|
+
query: string;
|
|
37
|
+
currentParent: CascaderNode<T> | null;
|
|
38
|
+
/** Rows for the current level, already filtered. */
|
|
39
|
+
levelItems: CascaderNode<T>[];
|
|
40
|
+
deepResults: CascaderNode<T>[] | null;
|
|
41
|
+
/** What `Combobox.Root` is currently rendering, in render order. */
|
|
42
|
+
renderedItems: CascaderNode<T>[];
|
|
43
|
+
columns: CascaderColumn<T>[];
|
|
44
|
+
treeRows: CascaderFlatNode<T>[];
|
|
45
|
+
selectedValues: string[];
|
|
46
|
+
/** Selected nodes below each value, at any depth. Absent means zero. */
|
|
47
|
+
selectedDescendants: ReadonlyMap<string, number>;
|
|
48
|
+
/**
|
|
49
|
+
* Per level, keyed by parent value or `CASCADER_ROOT_KEY`. MEMBERSHIP is the
|
|
50
|
+
* discriminator: no entry means never fetched, an entry with no `loading`, no
|
|
51
|
+
* `error` and no children means fetched and genuinely empty.
|
|
52
|
+
*/
|
|
53
|
+
loadStates: ReadonlyMap<string, CascaderLoadState>;
|
|
54
|
+
/** Async search, `null` when idle. Separate: a search belongs to no level. */
|
|
55
|
+
searchState: CascaderLoadState | null;
|
|
56
|
+
announcement: string;
|
|
57
|
+
}
|
|
58
|
+
declare const CascaderStateContext: React.Context<CascaderStateContextValue<unknown> | undefined>;
|
|
59
|
+
/**
|
|
60
|
+
* One provider serves every `T`, so the context holds an erased `unknown` value
|
|
61
|
+
* and this cast restores it. The primitive never inspects the payload.
|
|
62
|
+
*/
|
|
63
|
+
export declare function useCascaderState<T = unknown>(): CascaderStateContextValue<T>;
|
|
64
|
+
/**
|
|
65
|
+
* Config and callbacks, slow enough that a memoised row can subscribe: the
|
|
66
|
+
* mutators are `[]`-dep callbacks over a latest-props ref. The three predicates
|
|
67
|
+
* are the exception, read DURING RENDER where a ref written in an effect would
|
|
68
|
+
* return the previous commit's answer, so each is memoised on its own input.
|
|
69
|
+
*/
|
|
70
|
+
export interface CascaderActionsContextValue<T = unknown> {
|
|
71
|
+
index: CascaderIndex<T>;
|
|
72
|
+
mode: CascaderMode;
|
|
73
|
+
multiple: boolean;
|
|
74
|
+
/** Multi-select only: a commit propagates over the LOADED subtree. */
|
|
75
|
+
cascade: boolean;
|
|
76
|
+
/** Whether a BRANCH is committable. Per-LIST: the check gutter is a COLUMN. */
|
|
77
|
+
branchesSelectable: boolean;
|
|
78
|
+
/** Draws the SINGLE-SELECT check and its gutter. Ignored in multi-select. */
|
|
79
|
+
indicator: boolean;
|
|
80
|
+
expandTrigger?: 'click' | 'hover';
|
|
81
|
+
actions: CascaderActionItem[];
|
|
82
|
+
searchScope: CascaderSearchScope;
|
|
83
|
+
maxHeight?: number | string;
|
|
84
|
+
inline: boolean;
|
|
85
|
+
invalid: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Id prefix; columns are `${baseId}-column-${depth}`. The SCHEME is contract:
|
|
88
|
+
* the filters primitive's `FilterMenuPinKeeper` restores its highlight across
|
|
89
|
+
* a live re-pin through `${baseId}-column-0` and the `cascader-item` slot.
|
|
90
|
+
*/
|
|
91
|
+
baseId: string;
|
|
92
|
+
labels: CascaderLabels;
|
|
93
|
+
/**
|
|
94
|
+
* Whether rows are WINDOWED. Also handed to `Combobox.Root`, which is what
|
|
95
|
+
* makes an explicit row `index` legal: forwarding one while this is false
|
|
96
|
+
* makes `aria-activedescendant` resolve to nothing. Latched per level.
|
|
97
|
+
*/
|
|
98
|
+
virtualized: boolean;
|
|
99
|
+
/** Mounts a windowing renderer, returns its unregister. LAYOUT effect only. */
|
|
100
|
+
registerVirtualRenderer: () => () => void;
|
|
101
|
+
/** The root's `virtualize` prop. `undefined` means "decide by count". */
|
|
102
|
+
virtualize?: boolean;
|
|
103
|
+
virtualizeThreshold: number;
|
|
104
|
+
estimateRowSize: number;
|
|
105
|
+
overscan: number;
|
|
106
|
+
/** Tells "this level is empty" from "not fetched yet" before a load state. */
|
|
107
|
+
hasLoader: boolean;
|
|
108
|
+
/** Next page of a level. Latched: a page with nothing new is not re-asked. */
|
|
109
|
+
loadMore: (parentKey: string) => void;
|
|
110
|
+
retryLevel: (parentKey: string) => void;
|
|
111
|
+
/**
|
|
112
|
+
* Evicts one level's async cache, `null` for the root, so membership reads
|
|
113
|
+
* never-loaded. A level that is on screen when evicted refetches at once.
|
|
114
|
+
*/
|
|
115
|
+
invalidateLevel: (value: string | null) => void;
|
|
116
|
+
/** Index as of the last commit. Use in the stable callbacks, not `index`. */
|
|
117
|
+
getIndex: () => CascaderIndex<T>;
|
|
118
|
+
getState: () => CascaderStateContextValue<T>;
|
|
119
|
+
/** Highlighted row or null. A getter: the highlight moves per arrow key. */
|
|
120
|
+
getHighlighted: () => CascaderNode<T> | null;
|
|
121
|
+
setPath: (next: string[] | ((prev: string[]) => string[])) => void;
|
|
122
|
+
pushLevel: (value: string) => void;
|
|
123
|
+
popLevel: () => void;
|
|
124
|
+
goToDepth: (depth: number) => void;
|
|
125
|
+
toggleExpanded: (value: string) => void;
|
|
126
|
+
/**
|
|
127
|
+
* Registers a footer submenu as open or closed. `Combobox` has no
|
|
128
|
+
* `FloatingTree`, so one Escape would dismiss the flyout AND the cascader;
|
|
129
|
+
* the root's `onOpenChange` guard cancels the close while any is open, from a
|
|
130
|
+
* ref so it reads as of that event without re-rendering the root.
|
|
131
|
+
*/
|
|
132
|
+
setFlyoutOpen: (key: string, open: boolean) => void;
|
|
133
|
+
hasOpenFlyout: () => boolean;
|
|
134
|
+
setQuery: (next: string) => void;
|
|
135
|
+
/**
|
|
136
|
+
* Replaces the selection. `onValueChange` diffs it against the current one
|
|
137
|
+
* for its node and reason; pass `reason` only when the caller knows better.
|
|
138
|
+
*/
|
|
139
|
+
setSelection: (values: string[], reason?: CascaderChangeReason) => void;
|
|
140
|
+
/** Commits a node, for rows outside the listbox such as ancestor columns. */
|
|
141
|
+
commit: (node: CascaderNode<T>) => void;
|
|
142
|
+
navigate: (node: CascaderNode<T>) => void;
|
|
143
|
+
/** Into `node` as a child of `depth`, replacing anything deeper. */
|
|
144
|
+
navigateAt: (node: CascaderNode<T>, depth: number) => void;
|
|
145
|
+
/** Never undefined: falls back to a remembered label, then a synthetic node. */
|
|
146
|
+
resolveNode: (value: string) => CascaderNode<T>;
|
|
147
|
+
isBranch: (node: CascaderNode<T>) => boolean;
|
|
148
|
+
isSelectable: (node: CascaderNode<T>) => boolean;
|
|
149
|
+
isSelected: (node: CascaderNode<T>) => boolean;
|
|
150
|
+
/** Always `false` without `cascade`: partial selection needs propagation. */
|
|
151
|
+
isIndeterminate: (node: CascaderNode<T>) => boolean;
|
|
152
|
+
/**
|
|
153
|
+
* O(1) read of `selectedDescendants`; a memoised row may not subscribe.
|
|
154
|
+
* Unlike `isIndeterminate` this answers in every mode.
|
|
155
|
+
*/
|
|
156
|
+
selectedDescendantCount: (node: CascaderNode<T>) => number;
|
|
157
|
+
}
|
|
158
|
+
declare const CascaderActionsContext: React.Context<CascaderActionsContextValue<unknown> | undefined>;
|
|
159
|
+
export declare function useCascaderActions<T = unknown>(): CascaderActionsContextValue<T>;
|
|
160
|
+
/**
|
|
161
|
+
* Their own context, republished every render. They cannot ride on the actions
|
|
162
|
+
* context: an inline closure read off a memoised object is whichever closure
|
|
163
|
+
* that object captured, so the row would call a stale prop over stale state.
|
|
164
|
+
*/
|
|
165
|
+
export interface CascaderRenderContextValue<T = unknown> {
|
|
166
|
+
renderItem?: (node: CascaderNode<T>, state: CascaderItemState<T>) => React.ReactNode;
|
|
167
|
+
renderLabel?: (node: CascaderNode<T>, state: CascaderItemState<T>) => React.ReactNode;
|
|
168
|
+
}
|
|
169
|
+
declare const CascaderRenderContext: React.Context<CascaderRenderContextValue<unknown>>;
|
|
170
|
+
export declare function useCascaderRender<T = unknown>(): CascaderRenderContextValue<T>;
|
|
171
|
+
export interface CascaderHighlight {
|
|
172
|
+
index: number;
|
|
173
|
+
value: string | null;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* An external store, deliberately NOT React state: `onItemHighlighted` fires on
|
|
177
|
+
* every arrow key AND every pointer move over the list, so `setState` would
|
|
178
|
+
* re-render the whole root at mousemove rate. A store re-renders subscribers
|
|
179
|
+
* only, which inside the primitive is the virtualizer.
|
|
180
|
+
*/
|
|
181
|
+
export interface CascaderHighlightStore {
|
|
182
|
+
subscribe: (onStoreChange: () => void) => () => void;
|
|
183
|
+
getSnapshot: () => CascaderHighlight;
|
|
184
|
+
set: (next: CascaderHighlight) => void;
|
|
185
|
+
}
|
|
186
|
+
export declare function createCascaderHighlightStore(): CascaderHighlightStore;
|
|
187
|
+
declare const CascaderHighlightContext: React.Context<CascaderHighlightStore>;
|
|
188
|
+
/** Subscribes to the highlight. Re-renders ONLY the calling component. */
|
|
189
|
+
export declare function useCascaderHighlight(): CascaderHighlight;
|
|
190
|
+
export { CascaderActionsContext, CascaderHighlightContext, CascaderRenderContext, CascaderStateContext };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Popover as PopoverPrimitive } from '@base-ui/react';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
export type CascaderFooterProps = React.ComponentProps<'div'>;
|
|
4
|
+
/**
|
|
5
|
+
* Actions pinned below the list, a SIBLING of `CascaderList`. Children win
|
|
6
|
+
* over the root's `actions` prop; with neither it renders nothing.
|
|
7
|
+
*/
|
|
8
|
+
declare function CascaderFooter({ className, children, onKeyDown, ...props }: CascaderFooterProps): React.JSX.Element | null;
|
|
9
|
+
export interface CascaderActionProps extends Omit<React.ComponentProps<'button'>, 'onSelect'> {
|
|
10
|
+
icon?: React.ReactNode;
|
|
11
|
+
/** Fires on press, after `onClick`, and not at all when disabled. */
|
|
12
|
+
onSelect?: () => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* One footer command, shaped like a row and deliberately NOT one. A real
|
|
16
|
+
* `<button>`, never a `Combobox.Item`: an item would join the arrow-key ring,
|
|
17
|
+
* appear in `filteredItems`, and vanish the moment a query matched nothing -
|
|
18
|
+
* exactly when "Create new attribute" is most useful. Disabled is
|
|
19
|
+
* `aria-disabled`, never the native attribute: that one is not a tab stop and
|
|
20
|
+
* the panel's Tab order reads `button:not([disabled])`, so a footer whose ONLY
|
|
21
|
+
* row is a disabled command had no stop after the search field (measured on
|
|
22
|
+
* `c-cascader-8`). Staying focusable costs the guards below, plus the
|
|
23
|
+
* greyed-out look: `CASCADER_ACTION_CLASS` keys that off `aria-disabled`
|
|
24
|
+
* instead of `:disabled`.
|
|
25
|
+
*/
|
|
26
|
+
declare function CascaderAction({ className, icon, children, onSelect, onClick, onKeyDown, disabled, ...props }: CascaderActionProps): React.JSX.Element;
|
|
27
|
+
interface CascaderSubmenuContextValue {
|
|
28
|
+
rowRef: React.MutableRefObject<HTMLButtonElement | null>;
|
|
29
|
+
open: boolean;
|
|
30
|
+
setOpen: (open: boolean) => void;
|
|
31
|
+
close: () => void;
|
|
32
|
+
/** Names the flyout: a menu is labelled by the control that opens it. */
|
|
33
|
+
triggerId: string;
|
|
34
|
+
/**
|
|
35
|
+
* Whether the pending open came from the KEYBOARD. Base UI's own `openType`
|
|
36
|
+
* calls the opening arrow a POINTER open, because the trigger intercepts it
|
|
37
|
+
* and calls `setOpen` (measured: focus landed on the popup, not the first
|
|
38
|
+
* entry). A ref, so reading it in the focus phase cannot render.
|
|
39
|
+
*/
|
|
40
|
+
keyboardRef: React.MutableRefObject<boolean>;
|
|
41
|
+
}
|
|
42
|
+
/** The flyout's own state. `close()` is the one a custom entry usually wants. */
|
|
43
|
+
export declare function useCascaderSubmenu(): CascaderSubmenuContextValue;
|
|
44
|
+
export interface CascaderSubmenuProps {
|
|
45
|
+
open?: boolean;
|
|
46
|
+
defaultOpen?: boolean;
|
|
47
|
+
onOpenChange?: (open: boolean) => void;
|
|
48
|
+
children?: React.ReactNode;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A footer row plus the flyout it opens. Registers with the cascader root
|
|
52
|
+
* while open, which turns one Escape into two. Cleared in an EFFECT, so the
|
|
53
|
+
* flyout still reads as open during the event that closed it.
|
|
54
|
+
*/
|
|
55
|
+
declare function CascaderSubmenu({ open: openProp, defaultOpen, onOpenChange, children }: CascaderSubmenuProps): React.JSX.Element;
|
|
56
|
+
export interface CascaderSubmenuTriggerProps extends Omit<React.ComponentProps<'button'>, 'onSelect'> {
|
|
57
|
+
icon?: React.ReactNode;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The footer row that opens the flyout, and its anchor. `aria-haspopup="menu"`
|
|
61
|
+
* rather than the `dialog` Base UI would announce: what opens is a list of
|
|
62
|
+
* commands with roving focus. `disabled` is intercepted, not forwarded:
|
|
63
|
+
* `Popover.Trigger` runs it through `useButton`, which writes the NATIVE
|
|
64
|
+
* attribute for a native `<button>` and takes the row out of the panel's Tab
|
|
65
|
+
* ring, the defect `CascaderAction` documents, and this component exposes no
|
|
66
|
+
* `focusableWhenDisabled` to opt out. Published as `aria-disabled`, with the
|
|
67
|
+
* arrow keys, Enter and Space, and the click closed by hand (`useClick`
|
|
68
|
+
* ignores `defaultPrevented`).
|
|
69
|
+
*/
|
|
70
|
+
declare function CascaderSubmenuTrigger({ className, icon, children, onKeyDown, onClick, disabled, ...props }: CascaderSubmenuTriggerProps): React.JSX.Element;
|
|
71
|
+
export interface CascaderSubmenuContentProps extends PopoverPrimitive.Popup.Props, Pick<PopoverPrimitive.Positioner.Props, 'side' | 'align' | 'sideOffset' | 'alignOffset'> {
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The flyout itself. `Portal` with NO `container`: a nested portal resolves to
|
|
75
|
+
* the parent portal node, the mechanism the file header describes.
|
|
76
|
+
*/
|
|
77
|
+
declare function CascaderSubmenuContent({ className, children, onKeyDown, side, align, sideOffset, alignOffset, ...props }: CascaderSubmenuContentProps): React.JSX.Element;
|
|
78
|
+
/**
|
|
79
|
+
* Whether the footer would render anything, for a wrapper (a separator, a grid
|
|
80
|
+
* row) that has to make the same call `CascaderFooter` already makes.
|
|
81
|
+
*/
|
|
82
|
+
export declare function useCascaderHasActions(): boolean;
|
|
83
|
+
export { CascaderAction, CascaderFooter, CascaderSubmenu, CascaderSubmenuContent, CascaderSubmenuTrigger };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CascaderLabels } from '../../../components/reui/cascader/cascader-types';
|
|
2
|
+
/**
|
|
3
|
+
* English defaults. Every string the primitive can render lives here, so a
|
|
4
|
+
* consumer can translate the whole surface by passing `labels`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CASCADER_LABELS: CascaderLabels;
|
|
7
|
+
/**
|
|
8
|
+
* Shallow-merges consumer overrides over the defaults, so `labels` can carry a
|
|
9
|
+
* single key without restating the rest.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveCascaderLabels(labels?: Partial<CascaderLabels>): CascaderLabels;
|
|
12
|
+
/** Resolves the search placeholder, which may be a string or a function. */
|
|
13
|
+
export declare function resolveCascaderSearchLabel(labels: CascaderLabels, parentLabel?: string): string;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { Combobox as ComboboxPrimitive } from '@base-ui/react';
|
|
2
|
+
import { CascaderLoadState, CascaderNode } from '../../../components/reui/cascader/cascader-types';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
type VetoableEvent = {
|
|
5
|
+
preventBaseUIHandler?: () => void;
|
|
6
|
+
};
|
|
7
|
+
/** A row press. The veto hook is optional: an `as="button"` row is outside Base
|
|
8
|
+
* UI's listbox and gets a plain React event. */
|
|
9
|
+
export type CascaderRowEvent = React.MouseEvent<HTMLElement> & VetoableEvent;
|
|
10
|
+
/** A footer COMMAND: the row theme, so it cannot drift from the list, plus the
|
|
11
|
+
* hover and `focus-visible` fills a plain button never gets. Fills, never a
|
|
12
|
+
* ring: a ring under rows that all paint with a fill read as a different
|
|
13
|
+
* widget bolted on. `focus-visible`, not `focus`, so a pointer press does not
|
|
14
|
+
* leave a command painted as if it were still hovered. Disabled keys off
|
|
15
|
+
* `aria-disabled`, not `:disabled`, to keep it FOCUSABLE: a footer whose only
|
|
16
|
+
* row is disabled has no tab stop. */
|
|
17
|
+
export declare const CASCADER_ACTION_CLASS = "data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground [&_svg:not([class*='size-'])]:size-4 rounded-md py-1 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [--cascader-row-inset:6px] text-sm ps-[var(--cascader-row-inset,8px)]! pe-[var(--cascader-row-inset,8px)]! hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground cursor-pointer gap-2 transition-colors aria-disabled:pointer-events-none aria-disabled:opacity-50";
|
|
18
|
+
export interface CascaderItemProps extends Omit<ComboboxPrimitive.Item.Props, 'value' | 'children' | 'className' | 'style' | 'onClick' | 'onMouseUp'> {
|
|
19
|
+
/** No state callback: the row merges `className` and `style` itself. */
|
|
20
|
+
className?: string;
|
|
21
|
+
style?: React.CSSProperties;
|
|
22
|
+
onClick?: (event: CascaderRowEvent) => void;
|
|
23
|
+
onMouseUp?: (event: CascaderRowEvent) => void;
|
|
24
|
+
node: CascaderNode;
|
|
25
|
+
/** Explicit render index. Required while virtualized and DELIBERATELY IGNORED
|
|
26
|
+
* otherwise: it self-registers the row and breaks `aria-activedescendant`. */
|
|
27
|
+
index?: number;
|
|
28
|
+
/** Indentation depth. Drives `--cascader-indent` in tree mode. */
|
|
29
|
+
depth?: number;
|
|
30
|
+
/** Renders the ancestor chain under the label, for deep-search results. */
|
|
31
|
+
showPath?: boolean;
|
|
32
|
+
/** `option` renders a real `Combobox.Item`; `button` renders identical markup
|
|
33
|
+
* outside the listbox, for the ancestor columns in columns mode. */
|
|
34
|
+
as?: 'option' | 'button';
|
|
35
|
+
/** Tree mode: this row is an expanded branch. */
|
|
36
|
+
expanded?: boolean;
|
|
37
|
+
/** Indent each depth by this many pixels. Tree mode only. */
|
|
38
|
+
indent?: number;
|
|
39
|
+
/** Whether the node has children. Defaults to the cascader's own answer, as do
|
|
40
|
+
* the three below: callers pass them because they already hold the level,
|
|
41
|
+
* which keeps a memoised row off the volatile context. */
|
|
42
|
+
branch?: boolean;
|
|
43
|
+
/** Whether the node may be committed. Defaults to the cascader's own answer. */
|
|
44
|
+
selectable?: boolean;
|
|
45
|
+
/** Whether the node is currently selected. Defaults to the cascader's answer. */
|
|
46
|
+
selected?: boolean;
|
|
47
|
+
/** Some but not all of the loaded subtree selected. `cascade` only. */
|
|
48
|
+
indeterminate?: boolean;
|
|
49
|
+
/** Selected nodes below this one, at any depth. Drives the trailing count. */
|
|
50
|
+
selectedCount?: number;
|
|
51
|
+
/** Paging row only: a request for this level is in flight. */
|
|
52
|
+
loading?: boolean;
|
|
53
|
+
/** Paging row only: this level's last request failed. */
|
|
54
|
+
error?: boolean;
|
|
55
|
+
/** Branch row only: this node's OWN children are being fetched. The chevron
|
|
56
|
+
* (or, in tree mode, the expander) becomes a spinner IN PLACE, in the same
|
|
57
|
+
* 16px box: no skeleton row appears below, nothing reflows. */
|
|
58
|
+
childrenLoading?: boolean;
|
|
59
|
+
/** Branch row only: the last fetch of this node's children failed. The same
|
|
60
|
+
* box becomes the retry. The press path is unchanged: it goes through
|
|
61
|
+
* `navigate`, which refires the failed level rather than moving. */
|
|
62
|
+
childrenError?: boolean;
|
|
63
|
+
children?: React.ReactNode;
|
|
64
|
+
}
|
|
65
|
+
/** One row. Branch presses navigate instead of selecting, vetoed here with
|
|
66
|
+
* `preventBaseUIHandler()` on `onClick` (Enter too) and on `onMouseUp`. */
|
|
67
|
+
declare const CascaderItem: React.NamedExoticComponent<CascaderItemProps>;
|
|
68
|
+
/** Every load-derived prop a row needs. A PAGING row reports the level it
|
|
69
|
+
* belongs to, a BRANCH row the level it OWNS; mutually exclusive, so one call
|
|
70
|
+
* answers both. Exported because a memoised row cannot read them itself. */
|
|
71
|
+
export declare function getCascaderMoreProps(node: CascaderNode, loadStates: ReadonlyMap<string, CascaderLoadState>): {
|
|
72
|
+
loading: boolean;
|
|
73
|
+
error: boolean;
|
|
74
|
+
childrenLoading: boolean;
|
|
75
|
+
childrenError: boolean;
|
|
76
|
+
};
|
|
77
|
+
export interface CascaderItemsProps {
|
|
78
|
+
/** Replaces the default row for every item. */
|
|
79
|
+
children?: (node: CascaderNode, index: number) => React.ReactNode;
|
|
80
|
+
}
|
|
81
|
+
/** Whatever the active view is: the current level, the deepest column, or the
|
|
82
|
+
* flattened tree rows. Lives here so `cascader.tsx` never imports a row
|
|
83
|
+
* component, which would cycle with the context. `index` is deliberately not
|
|
84
|
+
* passed; see `CascaderItemProps`. */
|
|
85
|
+
declare function CascaderItems({ children }: CascaderItemsProps): React.JSX.Element;
|
|
86
|
+
export interface CascaderGroupProps extends Omit<ComboboxPrimitive.Group.Props, 'className'> {
|
|
87
|
+
/** Base UI also accepts a state callback here; the group has no state. */
|
|
88
|
+
className?: string;
|
|
89
|
+
}
|
|
90
|
+
/** A run of related rows, named by the `CascaderLabel` inside it: the group is
|
|
91
|
+
* `role="group"` and Base UI points its `aria-labelledby` at the label, where a
|
|
92
|
+
* heading alone inside a listbox is dropped from the accessibility tree.
|
|
93
|
+
* Grouping is composition, not data: `CascaderItems` renders one flat run per
|
|
94
|
+
* level, so its indices line up with `listRef`. */
|
|
95
|
+
declare function CascaderGroup({ className, ...props }: CascaderGroupProps): React.JSX.Element;
|
|
96
|
+
export interface CascaderLabelProps extends Omit<ComboboxPrimitive.GroupLabel.Props, 'className' | 'style'> {
|
|
97
|
+
/** No state callback; outside a group this is not a Base UI part at all. */
|
|
98
|
+
className?: string;
|
|
99
|
+
style?: React.CSSProperties;
|
|
100
|
+
}
|
|
101
|
+
/** A heading. Inside `CascaderGroup` it is the group's accessible name; outside
|
|
102
|
+
* one (the footer flyout is a menu, not a listbox) it is decoration only. */
|
|
103
|
+
declare function CascaderLabel(props: CascaderLabelProps): React.JSX.Element;
|
|
104
|
+
export interface CascaderSeparatorProps extends Omit<ComboboxPrimitive.Separator.Props, 'className'> {
|
|
105
|
+
/** Base UI also accepts a state callback here; only the orientation varies. */
|
|
106
|
+
className?: string;
|
|
107
|
+
}
|
|
108
|
+
/** Decorative on purpose: Base UI's separator is `role="separator"`, which a
|
|
109
|
+
* `listbox` may not own, and a run that needs separating for a screen reader
|
|
110
|
+
* needs a `CascaderGroup`, not a line. A consumer can pass the role back. */
|
|
111
|
+
declare function CascaderSeparator({ className, ...props }: CascaderSeparatorProps): React.JSX.Element;
|
|
112
|
+
export { CascaderGroup, CascaderItem, CascaderItems, CascaderLabel, CascaderSeparator };
|