@enonic/ui 0.23.0 → 0.24.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.
@@ -1,14 +1,29 @@
1
1
  import { ComponentPropsWithoutRef, ReactElement, ReactNode } from 'react';
2
2
  import { IconButtonProps } from '../icon-button';
3
3
  import { LucideIcon } from '../../types';
4
- export type TreeListProps<T extends TreeNode = TreeNode> = {
4
+ export declare const LOADING_SUFFIX = "__loading__";
5
+ export declare const ROOT_PARENT_ID = "__root__";
6
+ export type TreeData = {
7
+ id: string;
8
+ hasChildren: boolean;
9
+ };
10
+ export type TreeItems<TreeData> = {
11
+ nodes: Record<string, TreeData | undefined>;
12
+ children: Record<string, string[] | undefined>;
13
+ hasMore: Record<string, boolean | undefined>;
14
+ };
15
+ export type FlatTreeNode<TData extends TreeData> = {
16
+ id: string;
17
+ data: TData;
18
+ level: number;
19
+ parentId: string | null;
20
+ nodeType: 'node' | 'loading' | 'error';
21
+ };
22
+ export type TreeListProps<TData extends TreeData = TreeData> = {
5
23
  className?: string;
6
- items?: T[];
7
- setItems?: (items: T[]) => void;
8
- isItemSelectable?: (item: T) => boolean;
9
- fetchChildren: (parentNode: T | undefined, offset: number) => Promise<{
10
- items: T[];
11
- total: number;
24
+ fetchChildren: (parentId: string | undefined, offset: number) => Promise<{
25
+ items: TData[];
26
+ hasMore: boolean;
12
27
  }>;
13
28
  expanded?: ReadonlySet<string>;
14
29
  onExpandedChange?: (expanded: ReadonlySet<string>) => void;
@@ -18,75 +33,85 @@ export type TreeListProps<T extends TreeNode = TreeNode> = {
18
33
  active?: string | null;
19
34
  defaultActive?: string;
20
35
  setActive?: (active: string | null | undefined) => void;
36
+ isItemSelectable?: (item: TData) => boolean;
37
+ items?: TreeItems<TData>;
38
+ onItemsChange?: (items: TreeItems<TData>) => void;
21
39
  children?: ReactNode;
22
40
  } & ComponentPropsWithoutRef<'div'>;
23
- export type TreeListContentProps = {
41
+ export type TreeListContainerProps = {
24
42
  children?: ReactNode;
25
- load?: boolean;
43
+ className?: string;
44
+ } & ComponentPropsWithoutRef<'div'>;
45
+ export type DefaultTreeListLoadingRowViewProps<TData extends TreeData> = {
46
+ item: FlatTreeNode<TData>;
26
47
  } & ComponentPropsWithoutRef<'div'>;
27
- type TreeListContainerProps = {
48
+ export type TreeListLoadingRowProps<TData extends TreeData> = {
49
+ item: FlatTreeNode<TData>;
50
+ renderLoading?: (item: FlatTreeNode<TData>) => ReactNode;
28
51
  children?: ReactNode;
52
+ intersectionProps?: IntersectionObserverInit;
53
+ } & ComponentPropsWithoutRef<'div'>;
54
+ export type TreeListErrorRowProps<TData extends TreeData> = {
55
+ item: FlatTreeNode<TData>;
56
+ renderError?: (item: FlatTreeNode<TData>) => ReactNode;
29
57
  className?: string;
58
+ onRetry?: () => void;
30
59
  } & ComponentPropsWithoutRef<'div'>;
31
- type TreeListRowLeftProps = {
60
+ export type TreeListContentProps<TData extends TreeData> = {
61
+ renderNode: (item: FlatTreeNode<TData>) => ReactNode;
62
+ renderLoading?: (item: FlatTreeNode<TData>) => ReactNode;
63
+ renderError?: (item: FlatTreeNode<TData>) => ReactNode;
64
+ };
65
+ export type TreeListRowLeftProps = {
32
66
  children?: ReactNode;
33
67
  className?: string;
34
68
  } & ComponentPropsWithoutRef<'div'>;
35
- type TreeListRowRightProps = {
69
+ export type TreeListRowRightProps = {
36
70
  children?: ReactNode;
37
71
  className?: string;
38
72
  } & ComponentPropsWithoutRef<'div'>;
39
- type TreeListRowLevelSpacerProps = {
73
+ export type TreeListRowLevelSpacerProps = {
40
74
  level?: number;
41
75
  className?: string;
42
76
  } & ComponentPropsWithoutRef<'div'>;
43
- type TreeListRowExpandControlProps = {
44
- data: TreeNode;
77
+ export type TreeListRowExpandControlProps<TData extends TreeData> = {
78
+ data: FlatTreeNode<TData>;
45
79
  icon?: LucideIcon;
46
80
  } & Omit<IconButtonProps, 'icon'>;
47
- type TreeListRowContentProps = {
81
+ export type TreeListRowContentProps = {
48
82
  children?: ReactNode;
49
83
  className?: string;
50
84
  } & ComponentPropsWithoutRef<'div'>;
51
- type TreeListRowSelectionControlProps = {
52
- data: TreeNode;
85
+ export type TreeListRowSelectionControlProps<TData extends TreeData> = {
86
+ data: FlatTreeNode<TData>;
53
87
  className?: string;
54
88
  } & ComponentPropsWithoutRef<'div'>;
55
- type TreeListRowProps<T extends TreeNode> = {
56
- item: T;
89
+ export type TreeListRowProps<TData extends TreeData> = {
90
+ item: FlatTreeNode<TData>;
57
91
  children: ReactNode;
58
92
  className?: string;
59
93
  } & ComponentPropsWithoutRef<'div'>;
60
- export type TreeListLoadingRowProps = {
61
- item: TreeNode;
62
- children?: ReactNode;
63
- intersectionProps?: IntersectionObserverInit;
64
- } & ComponentPropsWithoutRef<'div'>;
65
- export declare const TreeListRoot: <T extends TreeNode = TreeNode>({ className, items: controlledItems, setItems: setItemsControlled, fetchChildren, selection: controlledSelection, expanded: controlledExpanded, onSelectionChange, onExpandedChange, active: controlledActive, defaultActive, setActive, selectionMode, isItemSelectable, children, ...props }: TreeListProps<T>) => ReactElement;
66
- export type TreeNode = {
67
- id: string;
68
- hasChildren?: boolean;
69
- children?: TreeNode[];
70
- hasMoreChildren?: boolean;
71
- path: string[];
72
- };
73
- export declare function isLoadingPlaceholder(node: TreeNode): boolean;
74
- export declare const TreeList: (<T extends TreeNode = TreeNode>({ className, items: controlledItems, setItems: setItemsControlled, fetchChildren, selection: controlledSelection, expanded: controlledExpanded, onSelectionChange, onExpandedChange, active: controlledActive, defaultActive, setActive, selectionMode, isItemSelectable, children, ...props }: TreeListProps<T>) => ReactElement) & {
75
- Root: <T extends TreeNode = TreeNode>({ className, items: controlledItems, setItems: setItemsControlled, fetchChildren, selection: controlledSelection, expanded: controlledExpanded, onSelectionChange, onExpandedChange, active: controlledActive, defaultActive, setActive, selectionMode, isItemSelectable, children, ...props }: TreeListProps<T>) => ReactElement;
94
+ export declare const TreeList: (<TData extends TreeData = TreeData>({ className, fetchChildren, selection: controlledSelection, expanded: controlledExpanded, onSelectionChange, onExpandedChange, active: controlledActive, defaultActive, setActive, selectionMode, isItemSelectable, items: controlledItems, onItemsChange, children, ...props }: TreeListProps<TData>) => ReactElement) & {
95
+ Root: <TData extends TreeData = TreeData>({ className, fetchChildren, selection: controlledSelection, expanded: controlledExpanded, onSelectionChange, onExpandedChange, active: controlledActive, defaultActive, setActive, selectionMode, isItemSelectable, items: controlledItems, onItemsChange, children, ...props }: TreeListProps<TData>) => ReactElement;
76
96
  Container: {
77
97
  ({ children, className, ...props }: TreeListContainerProps): ReactElement<TreeListContainerProps>;
78
98
  displayName: string;
79
99
  };
80
100
  Content: {
81
- ({ children, load }: TreeListContentProps): ReactElement;
101
+ <TData extends TreeData>({ renderNode, renderLoading, renderError, }: TreeListContentProps<TData>): ReactElement;
82
102
  displayName: string;
83
103
  };
84
104
  Row: {
85
- <T extends TreeNode>({ item, children, className, ...props }: TreeListRowProps<T>): ReactElement;
105
+ <TData extends TreeData>({ item, children, className, ...props }: TreeListRowProps<TData>): ReactElement;
86
106
  displayName: string;
87
107
  };
88
108
  LoadingRow: {
89
- ({ item, children, intersectionProps, ...props }: TreeListLoadingRowProps): ReactElement;
109
+ <TData extends TreeData>({ item, renderLoading, className, children, intersectionProps, ...props }: TreeListLoadingRowProps<TData>): ReactElement;
110
+ displayName: string;
111
+ };
112
+ DefaultLoadingRowView: <TData extends TreeData>({ item, className, children, ...props }: DefaultTreeListLoadingRowViewProps<TData>) => ReactElement;
113
+ ErrorRow: {
114
+ <TData extends TreeData>({ item, onRetry, renderError, className, ...props }: TreeListErrorRowProps<TData>): ReactElement;
90
115
  displayName: string;
91
116
  };
92
117
  RowLeft: {
@@ -94,15 +119,15 @@ export declare const TreeList: (<T extends TreeNode = TreeNode>({ className, ite
94
119
  displayName: string;
95
120
  };
96
121
  RowRight: {
97
- ({ children, className, ...props }: TreeListRowRightProps): ReactElement<TreeListRowLeftProps>;
122
+ ({ children, className, ...props }: TreeListRowRightProps): ReactElement<TreeListRowRightProps>;
98
123
  displayName: string;
99
124
  };
100
125
  RowLevelSpacer: {
101
- ({ level, className, ...props }: TreeListRowLevelSpacerProps): ReactElement<TreeListRowLeftProps> | undefined;
126
+ ({ level, className, ...props }: TreeListRowLevelSpacerProps): ReactElement<TreeListRowLevelSpacerProps> | null;
102
127
  displayName: string;
103
128
  };
104
129
  RowExpandControl: {
105
- ({ data, icon, className, ...props }: TreeListRowExpandControlProps): ReactElement<TreeListRowExpandControlProps>;
130
+ <TData extends TreeData>({ data, icon, className, ...props }: TreeListRowExpandControlProps<TData>): ReactElement<TreeListRowExpandControlProps<TData>>;
106
131
  displayName: string;
107
132
  };
108
133
  RowContent: {
@@ -110,8 +135,7 @@ export declare const TreeList: (<T extends TreeNode = TreeNode>({ className, ite
110
135
  displayName: string;
111
136
  };
112
137
  RowSelectionControl: {
113
- ({ data, className, ...props }: TreeListRowSelectionControlProps): ReactElement;
138
+ <TData extends TreeData>({ data, className, ...props }: TreeListRowSelectionControlProps<TData>): ReactElement;
114
139
  displayName: string;
115
140
  };
116
141
  };
117
- export {};
@@ -4,8 +4,11 @@ export { useControlledState } from './use-controlled-state';
4
4
  export { useControlledStateWithNull } from './use-controlled-state-with-null';
5
5
  export { type FloatingPosition, type UseFloatingPositionConfig, useFloatingPosition } from './use-floating-position';
6
6
  export { type ItemMetadata, type UseItemRegistryReturn, useItemRegistry } from './use-item-registry';
7
+ export { type UseItemTextRegistryReturn, useItemTextRegistry } from './use-item-text-registry';
7
8
  export { type KeyboardNavigationConfig, type UseKeyboardNavigationReturn, useKeyboardNavigation, } from './use-keyboard-navigation';
8
9
  export { type UseRovingTabIndexConfig, type UseRovingTabIndexReturn, useRovingTabIndex } from './use-roving-tabindex';
9
10
  export { type UseScrollActiveIntoViewConfig, useScrollActiveIntoView } from './use-scroll-active-into-view';
10
11
  export { useScrollLock } from './use-scroll-lock';
12
+ export { type UseSelectorKeyboardConfig, type UseSelectorKeyboardReturn, useSelectorKeyboard, } from './use-selector-keyboard';
11
13
  export { useSyncValue } from './use-sync-value';
14
+ export { type UseTypeAheadConfig, type UseTypeAheadReturn, useTypeAhead } from './use-type-ahead';
@@ -0,0 +1,29 @@
1
+ export type UseItemTextRegistryReturn = {
2
+ /**
3
+ * Register text content for an item (for type-ahead matching)
4
+ */
5
+ registerItemText: (id: string, text: string) => void;
6
+ /**
7
+ * Unregister text content for an item
8
+ */
9
+ unregisterItemText: (id: string) => void;
10
+ /**
11
+ * Get the text content for an item
12
+ */
13
+ getItemText: (id: string) => string | undefined;
14
+ };
15
+ /**
16
+ * Hook for managing item text content registry.
17
+ * Used for type-ahead search functionality.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const { registerItemText, getItemText } = useItemTextRegistry();
22
+ *
23
+ * // In item component:
24
+ * useEffect(() => {
25
+ * registerItemText(id, textContent);
26
+ * }, [id, textContent]);
27
+ * ```
28
+ */
29
+ export declare function useItemTextRegistry(): UseItemTextRegistryReturn;
@@ -0,0 +1,68 @@
1
+ export type UseSelectorKeyboardConfig = {
2
+ /**
3
+ * Get all item IDs in order
4
+ */
5
+ getItems: () => string[];
6
+ /**
7
+ * Check if an item is disabled
8
+ */
9
+ isItemDisabled: (id: string) => boolean;
10
+ /**
11
+ * Get the text content for an item (for type-ahead matching)
12
+ */
13
+ getItemText: (id: string) => string | undefined;
14
+ /**
15
+ * Currently active item ID
16
+ */
17
+ active: string | undefined;
18
+ /**
19
+ * Set the active item ID
20
+ */
21
+ setActive: (id: string | undefined) => void;
22
+ /**
23
+ * Currently selected value
24
+ */
25
+ value: string | undefined;
26
+ /**
27
+ * Whether the dropdown is open
28
+ */
29
+ open: boolean;
30
+ /**
31
+ * Set open state (internal, doesn't return focus)
32
+ */
33
+ setOpenInternal: (open: boolean) => void;
34
+ /**
35
+ * Set open state (with focus return handling)
36
+ */
37
+ setOpen: (open: boolean) => void;
38
+ /**
39
+ * Whether the selector is disabled
40
+ */
41
+ disabled: boolean;
42
+ /**
43
+ * Called when an item is selected
44
+ */
45
+ onSelect: (id: string) => void;
46
+ };
47
+ export type UseSelectorKeyboardReturn = {
48
+ /**
49
+ * Combined keyboard event handler
50
+ */
51
+ keyHandler: (e: React.KeyboardEvent<HTMLElement>) => void;
52
+ };
53
+ /**
54
+ * Hook for Selector keyboard handling.
55
+ *
56
+ * Combines keyboard navigation, type-ahead, and selector-specific behaviors:
57
+ * - Arrow keys, Home/End for navigation
58
+ * - Enter/Space for selection
59
+ * - Escape to close
60
+ * - Tab to select and close
61
+ * - PageUp/PageDown for large jumps
62
+ * - Type-ahead search (single char cycling, multi-char search)
63
+ * - Opens dropdown on navigation keys when closed
64
+ *
65
+ * @param config - Configuration object
66
+ * @returns Object with keyHandler
67
+ */
68
+ export declare function useSelectorKeyboard(config: UseSelectorKeyboardConfig): UseSelectorKeyboardReturn;
@@ -0,0 +1,76 @@
1
+ export type UseTypeAheadConfig = {
2
+ /**
3
+ * Get all item IDs in order
4
+ */
5
+ getItems: () => string[];
6
+ /**
7
+ * Check if an item is disabled
8
+ */
9
+ isItemDisabled: (id: string) => boolean;
10
+ /**
11
+ * Get the text content for an item (for matching)
12
+ */
13
+ getItemText: (id: string) => string | undefined;
14
+ /**
15
+ * Currently active item ID
16
+ */
17
+ active: string | undefined;
18
+ /**
19
+ * Set the active item ID
20
+ */
21
+ setActive: (id: string | undefined) => void;
22
+ /**
23
+ * Called when a match is found
24
+ */
25
+ onMatch?: (id: string) => void;
26
+ /**
27
+ * Timeout in ms before search string resets
28
+ * @default 500
29
+ */
30
+ timeout?: number;
31
+ };
32
+ export type UseTypeAheadReturn = {
33
+ /**
34
+ * Handle a typed character for type-ahead search
35
+ */
36
+ handleTypeAhead: (char: string) => void;
37
+ /**
38
+ * Reset the search string manually
39
+ */
40
+ resetSearch: () => void;
41
+ };
42
+ /**
43
+ * Hook for type-ahead search in a list of items.
44
+ *
45
+ * Behavior:
46
+ * - Single character: cycles through items starting with that character
47
+ * - Multiple characters typed quickly: finds first match for full string
48
+ * - Case-insensitive matching
49
+ * - Skips disabled items
50
+ * - Resets after timeout (default 500ms)
51
+ *
52
+ * **Important**: The `getItemText` function must return the searchable text for each item.
53
+ * When using complex children (e.g., `<ItemText>{label}</ItemText>`), you must either:
54
+ * 1. Provide a `textValue` prop to register searchable text explicitly
55
+ * 2. Extract text from DOM after mount using `element.textContent`
56
+ *
57
+ * Plain string children work automatically, but wrapped content requires explicit registration.
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * const { handleTypeAhead } = useTypeAhead({
62
+ * getItems,
63
+ * isItemDisabled,
64
+ * getItemText,
65
+ * active,
66
+ * setActive,
67
+ * onMatch: (id) => console.log('Found:', id),
68
+ * });
69
+ *
70
+ * // In keyboard handler:
71
+ * if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
72
+ * handleTypeAhead(e.key);
73
+ * }
74
+ * ```
75
+ */
76
+ export declare function useTypeAhead(config: UseTypeAheadConfig): UseTypeAheadReturn;
@@ -7,6 +7,7 @@ export * from './menu-provider';
7
7
  export * from './menubar-menu-provider';
8
8
  export * from './menubar-provider';
9
9
  export * from './search-field-provider';
10
+ export * from './selector-provider';
10
11
  export * from './toast-provider';
11
12
  export * from './toggle-group-provider';
12
13
  export * from './tree-list-provider';
@@ -1,5 +1,6 @@
1
1
  import { ReactElement, ReactNode, RefObject } from 'react';
2
2
  export type MenuContextValue = {
3
+ baseId: string;
3
4
  open: boolean;
4
5
  setOpen: (open: boolean) => void;
5
6
  active: string | undefined;
@@ -8,8 +9,6 @@ export type MenuContextValue = {
8
9
  unregisterItem: (id: string) => void;
9
10
  getItems: () => string[];
10
11
  isItemDisabled: (id: string) => boolean;
11
- triggerId: string;
12
- menuId: string;
13
12
  triggerRef: RefObject<HTMLButtonElement> | null;
14
13
  };
15
14
  export type MenuProviderProps = {
@@ -0,0 +1,33 @@
1
+ import { ReactElement, ReactNode, RefObject } from 'react';
2
+ export type SelectorContextValue = {
3
+ baseId: string;
4
+ value: string | undefined;
5
+ setValue: (value: string) => void;
6
+ open: boolean;
7
+ setOpen: (next: boolean) => void;
8
+ active: string | undefined;
9
+ setActive: (id: string | undefined) => void;
10
+ disabled: boolean;
11
+ error: boolean;
12
+ required: boolean;
13
+ name?: string;
14
+ form?: string;
15
+ registerItem: (id: string, disabled?: boolean) => void;
16
+ unregisterItem: (id: string) => void;
17
+ getItems: () => string[];
18
+ isItemDisabled: (id: string) => boolean;
19
+ registerItemText: (id: string, text: string) => void;
20
+ unregisterItemText: (id: string) => void;
21
+ getItemText: (id: string) => string | undefined;
22
+ keyHandler: (e: React.KeyboardEvent<HTMLElement>) => void;
23
+ triggerRef: RefObject<HTMLButtonElement>;
24
+ };
25
+ export type SelectorProviderProps = {
26
+ value: SelectorContextValue;
27
+ children?: ReactNode;
28
+ };
29
+ export declare const SelectorProvider: {
30
+ ({ value, children }: SelectorProviderProps): ReactElement;
31
+ displayName: string;
32
+ };
33
+ export declare const useSelector: () => SelectorContextValue;
@@ -1,21 +1,23 @@
1
- import { ReactElement, ReactNode } from 'react';
2
- import { TreeNode } from '../components/tree-list/tree-list';
3
- export type TreeListContextValue<T extends TreeNode = TreeNode> = {
1
+ import { ReactElement, ReactNode, RefObject } from 'react';
2
+ import { FlatTreeNode, TreeData } from '../components/tree-list/tree-list';
3
+ export type TreeListContextValue<T extends TreeData = TreeData> = {
4
4
  baseId: string;
5
- items: readonly T[];
6
- loadMore: (parent?: string) => void;
5
+ items: readonly FlatTreeNode<T>[];
6
+ loadMore: (parent?: string) => Promise<void>;
7
7
  isItemSelectable: (item: T) => boolean;
8
8
  active?: string;
9
9
  selection?: ReadonlySet<string>;
10
10
  expanded?: ReadonlySet<string>;
11
- toggleSelection?: (id: string) => void;
11
+ toggleSelection: (id: string) => void;
12
12
  toggleExpanded: (id: string) => void;
13
+ updateActive: (id: string | undefined) => void;
13
14
  selectionMode: 'single' | 'multiple';
14
15
  isFocused: boolean;
16
+ scrollRootRef?: RefObject<HTMLDivElement>;
15
17
  };
16
- export type TreeListProviderProps<T extends TreeNode = TreeNode> = {
18
+ export type TreeListProviderProps<T extends TreeData = TreeData> = {
17
19
  value: TreeListContextValue<T>;
18
20
  children?: ReactNode;
19
21
  };
20
- export declare const TreeListProvider: <T extends TreeNode = TreeNode>({ value, children, }: TreeListProviderProps<T>) => ReactElement;
21
- export declare const useTreeList: <T extends TreeNode = TreeNode>() => TreeListContextValue<T>;
22
+ export declare const TreeListProvider: <T extends TreeData = TreeData>({ value, children, }: TreeListProviderProps<T>) => ReactElement;
23
+ export declare const useTreeList: <T extends TreeData = TreeData>() => TreeListContextValue<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enonic/ui",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Enonic UI Component Library",
5
5
  "author": "Enonic",
6
6
  "license": "MIT",
@@ -47,35 +47,6 @@
47
47
  "./base.css": "./dist/styles/base.css",
48
48
  "./utilities.css": "./dist/styles/utilities.css"
49
49
  },
50
- "scripts": {
51
- "build": "pnpm clean && pnpm build:ui",
52
- "build:ui": "pnpm --color /^build:ui:.*$/",
53
- "build:ui:lib": "vite build --config vite.config.ts",
54
- "build:ui:css": "vite build --config vite.config.css.ts",
55
- "build:storybook": "storybook build",
56
- "build:all": "pnpm build && pnpm build:storybook",
57
- "dev": "storybook dev -p 6006",
58
- "clean": "rm -rf dist coverage reports storybook-static",
59
- "check": "pnpm typecheck && pnpm lint && pnpm format:check",
60
- "typecheck": "pnpm typecheck:app && pnpm typecheck:node",
61
- "typecheck:app": "tsc --noEmit --project tsconfig.app.json",
62
- "typecheck:node": "tsc --noEmit --project tsconfig.node.json",
63
- "lint": "biome check . && eslint --cache '**/*.{ts,tsx}' --max-warnings 0 --concurrency auto",
64
- "lint:fix": "biome check --write --unsafe . && eslint --cache 'src/**/*.{ts,tsx}' --fix --concurrency auto",
65
- "lint:ci": "biome check . && eslint --no-cache 'src/**/*.{ts,tsx}' --max-warnings 0 --concurrency auto",
66
- "format": "biome format --write .",
67
- "format:check": "biome format .",
68
- "test": "exit 0",
69
- "test:ci": "exit 0",
70
- "prepack": "echo 'Packaging...'",
71
- "prepublishOnly": "pnpm check && pnpm build && pnpm size",
72
- "release": "npm publish --access public",
73
- "release:dry": "pnpm publish --dry-run --no-git-checks",
74
- "analyze": "pnpm build && open dist/stats.html",
75
- "size": "size-limit",
76
- "preview": "pnpm dlx serve . -p 4000",
77
- "prepare": "husky"
78
- },
79
50
  "dependencies": {
80
51
  "class-variance-authority": "~0.7.1",
81
52
  "clsx": "~2.1.1",
@@ -138,13 +109,6 @@
138
109
  "vite-plugin-dts": "~4.5.4",
139
110
  "vite-plugin-environment": "~1.1.3"
140
111
  },
141
- "pnpm": {
142
- "ignoredBuiltDependencies": [
143
- "@tailwindcss/oxide",
144
- "esbuild",
145
- "unrs-resolver"
146
- ]
147
- },
148
112
  "browserslist": {
149
113
  "production": [
150
114
  ">0.2%",
@@ -162,7 +126,6 @@
162
126
  "pnpm": ">=10.24.0",
163
127
  "npm": ">=11.6.2"
164
128
  },
165
- "packageManager": "pnpm@10.24.0",
166
129
  "lint-staged": {
167
130
  "*.{ts,tsx}": [
168
131
  "biome check --write --unsafe --no-errors-on-unmatched",
@@ -189,5 +152,30 @@
189
152
  "path": "dist/styles/preset.css",
190
153
  "limit": "2 KB"
191
154
  }
192
- ]
193
- }
155
+ ],
156
+ "scripts": {
157
+ "build": "pnpm clean && pnpm build:ui",
158
+ "build:ui": "pnpm --color /^build:ui:.*$/",
159
+ "build:ui:lib": "vite build --config vite.config.ts",
160
+ "build:ui:css": "vite build --config vite.config.css.ts",
161
+ "build:storybook": "storybook build",
162
+ "build:all": "pnpm build && pnpm build:storybook",
163
+ "dev": "storybook dev -p 6006",
164
+ "clean": "rm -rf dist coverage reports storybook-static",
165
+ "check": "pnpm typecheck && pnpm lint && pnpm format:check",
166
+ "typecheck": "pnpm typecheck:app && pnpm typecheck:node",
167
+ "typecheck:app": "tsc --noEmit --project tsconfig.app.json",
168
+ "typecheck:node": "tsc --noEmit --project tsconfig.node.json",
169
+ "lint": "biome check . && eslint --cache '**/*.{ts,tsx}' --max-warnings 0 --concurrency auto",
170
+ "lint:fix": "biome check --write --unsafe . && eslint --cache 'src/**/*.{ts,tsx}' --fix --concurrency auto",
171
+ "lint:ci": "biome check . && eslint --no-cache 'src/**/*.{ts,tsx}' --max-warnings 0 --concurrency auto",
172
+ "format": "biome format --write .",
173
+ "format:check": "biome format .",
174
+ "test": "exit 0",
175
+ "test:ci": "exit 0",
176
+ "release:dry": "pnpm publish --dry-run --no-git-checks",
177
+ "analyze": "pnpm build && open dist/stats.html",
178
+ "size": "size-limit",
179
+ "preview": "pnpm dlx serve . -p 4000"
180
+ }
181
+ }