modern-cmdk 1.4.0 → 1.5.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/README.md +31 -27
- package/THIRD-PARTY-NOTICES.md +303 -0
- package/dist/codemod/bin.mjs +14 -0
- package/dist/codemod/chunk-jscodeshift.mjs +36210 -0
- package/dist/codemod/chunk-print-options.mjs +43 -0
- package/dist/codemod/chunk-worker.mjs +476 -0
- package/dist/codemod/cli.mjs +297 -43660
- package/dist/codemod/transforms/data-attrs.mjs +551 -38
- package/dist/codemod/transforms/forward-ref.mjs +197 -32
- package/dist/codemod/transforms/import-rewrite.mjs +389 -30
- package/dist/codemod/transforms/should-filter.mjs +199 -10
- package/dist/codemod/worker.mjs +1 -0
- package/dist/core/index.d.mts +6 -1
- package/dist/core/index.mjs +12 -4
- package/dist/react/dialog.mjs +0 -1
- package/dist/react/index.d.mts +21 -3
- package/dist/react/index.mjs +45 -16
- package/package.json +5 -7
package/dist/core/index.mjs
CHANGED
|
@@ -1051,6 +1051,7 @@ function createCommandMachine(options = {}) {
|
|
|
1051
1051
|
const scheduler = createScheduler();
|
|
1052
1052
|
const emitter = new TypedEmitter();
|
|
1053
1053
|
const keyboardRegistry = new KeyboardShortcutRegistry();
|
|
1054
|
+
const pendingSources = /* @__PURE__ */ new Set();
|
|
1054
1055
|
let frecencyEngine = null;
|
|
1055
1056
|
if (options.frecency?.enabled) {
|
|
1056
1057
|
frecencyEngine = new FrecencyEngine(options.frecency);
|
|
@@ -1224,12 +1225,19 @@ function createCommandMachine(options = {}) {
|
|
|
1224
1225
|
case "ITEMS_LOADED":
|
|
1225
1226
|
registry.registerItems(event.items);
|
|
1226
1227
|
searchEngine.index(event.items);
|
|
1227
|
-
state = {
|
|
1228
|
-
...state,
|
|
1229
|
-
loading: false
|
|
1230
|
-
};
|
|
1231
1228
|
refilter(state.search);
|
|
1232
1229
|
break;
|
|
1230
|
+
case "LOADING": {
|
|
1231
|
+
if (event.pending) pendingSources.add(event.source);
|
|
1232
|
+
else pendingSources.delete(event.source);
|
|
1233
|
+
const loading = pendingSources.size > 0;
|
|
1234
|
+
if (loading !== state.loading) setState({
|
|
1235
|
+
...state,
|
|
1236
|
+
loading,
|
|
1237
|
+
lastUpdated: Date.now()
|
|
1238
|
+
});
|
|
1239
|
+
break;
|
|
1240
|
+
}
|
|
1233
1241
|
case "REGISTER_ITEM":
|
|
1234
1242
|
registry.registerItem(event.item);
|
|
1235
1243
|
searchEngine.index([event.item]);
|
package/dist/react/dialog.mjs
CHANGED
package/dist/react/index.d.mts
CHANGED
|
@@ -17,14 +17,19 @@ interface CommandActivityProps {
|
|
|
17
17
|
*/
|
|
18
18
|
export declare function CommandActivity({ mode, children }: CommandActivityProps): ReactNode;
|
|
19
19
|
interface CommandAsyncItemsProps {
|
|
20
|
-
/** Promise that resolves to items */
|
|
20
|
+
/** Promise that resolves to items; keep it stable across renders (state, a ref, or `useMemo`) or the boundary re-suspends on every render */
|
|
21
21
|
readonly items: Promise<readonly CommandItem$1[]>;
|
|
22
22
|
/** Fallback content while loading */
|
|
23
23
|
readonly fallback?: ReactNode;
|
|
24
24
|
/** Render function for resolved items */
|
|
25
25
|
readonly children: (items: readonly CommandItem$1[]) => ReactNode;
|
|
26
26
|
}
|
|
27
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Suspense-based async item loader that resolves a promise of items using React 19 `use()`.
|
|
29
|
+
*
|
|
30
|
+
* The `items` promise must be kept stable across renders (held in state, a ref, or `useMemo`):
|
|
31
|
+
* a new promise on every render, such as `items={fetchItems()}`, suspends again on every render.
|
|
32
|
+
*/
|
|
28
33
|
export declare function CommandAsyncItems({ items, fallback, children }: CommandAsyncItemsProps): ReactNode;
|
|
29
34
|
interface CommandBadgeProps extends ComponentPropsWithRef<"span"> {}
|
|
30
35
|
/** Inline badge for categorization or status indicators on command items. */
|
|
@@ -60,6 +65,7 @@ export declare function CommandInput({ ref, placeholder, onValueChange, ...props
|
|
|
60
65
|
interface CommandItemProps extends Omit<ComponentPropsWithRef<"div">, "onSelect" | "value"> {
|
|
61
66
|
readonly value: string;
|
|
62
67
|
readonly keywords?: readonly string[];
|
|
68
|
+
/** Called when the item is selected by click, Enter or shortcut (no argument in 1.x; the value arrives in 2.0) */
|
|
63
69
|
readonly onSelect?: () => void;
|
|
64
70
|
readonly disabled?: boolean;
|
|
65
71
|
readonly shortcut?: string;
|
|
@@ -181,7 +187,16 @@ interface CommandGroupContextValue {
|
|
|
181
187
|
}
|
|
182
188
|
interface CommandErrorBoundaryProps {
|
|
183
189
|
readonly children: ReactNode;
|
|
184
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Rendered in place of the children after an error. A function receives the error and a `reset`
|
|
192
|
+
* callback that clears it, so the children render again (a retry button, for example).
|
|
193
|
+
*/
|
|
194
|
+
readonly fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
195
|
+
/**
|
|
196
|
+
* While the boundary shows its fallback, a change in these values (compared entry by entry with
|
|
197
|
+
* `Object.is`; a different length counts as a change) clears the error and renders the children again.
|
|
198
|
+
*/
|
|
199
|
+
readonly resetKeys?: readonly unknown[];
|
|
185
200
|
readonly onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
186
201
|
}
|
|
187
202
|
interface CommandErrorBoundaryState {
|
|
@@ -192,6 +207,9 @@ export declare class CommandErrorBoundary extends Component<CommandErrorBoundary
|
|
|
192
207
|
override state: CommandErrorBoundaryState;
|
|
193
208
|
static getDerivedStateFromError(error: Error): CommandErrorBoundaryState;
|
|
194
209
|
override componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
210
|
+
override componentDidUpdate(prevProps: CommandErrorBoundaryProps, prevState: CommandErrorBoundaryState): void;
|
|
211
|
+
/** Clears the captured error so the children render again. */
|
|
212
|
+
reset: () => void;
|
|
195
213
|
override render(): ReactNode;
|
|
196
214
|
}
|
|
197
215
|
interface UseCommandReturn {
|
package/dist/react/index.mjs
CHANGED
|
@@ -33,14 +33,42 @@ function AsyncItemsInner({ items: itemsPromise, children }) {
|
|
|
33
33
|
}, [stable.machine, items]);
|
|
34
34
|
return /* @__PURE__ */ jsx(Fragment, { children: children(items) });
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Rendered next to the Suspense fallback: while it is mounted its source counts as pending,
|
|
38
|
+
* so `state.loading` (Command.Loading, the list's aria-busy) follows the suspended promise.
|
|
39
|
+
* The fallback unmounts when the items resolve, reject into an error boundary, or this
|
|
40
|
+
* AsyncItems unmounts, and the cleanup then clears the source.
|
|
41
|
+
*/
|
|
42
|
+
function PendingSignal() {
|
|
43
|
+
const stable = useStableContext("Command.AsyncItems");
|
|
44
|
+
const source = useId();
|
|
45
|
+
useLayoutEffect(() => {
|
|
46
|
+
stable.machine.send({
|
|
47
|
+
type: "LOADING",
|
|
48
|
+
source,
|
|
49
|
+
pending: true
|
|
50
|
+
});
|
|
51
|
+
return () => {
|
|
52
|
+
stable.machine.send({
|
|
53
|
+
type: "LOADING",
|
|
54
|
+
source,
|
|
55
|
+
pending: false
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
}, [stable.machine, source]);
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Suspense-based async item loader that resolves a promise of items using React 19 `use()`.
|
|
63
|
+
*
|
|
64
|
+
* The `items` promise must be kept stable across renders (held in state, a ref, or `useMemo`):
|
|
65
|
+
* a new promise on every render, such as `items={fetchItems()}`, suspends again on every render.
|
|
66
|
+
*/
|
|
37
67
|
function CommandAsyncItems({ items, fallback, children }) {
|
|
38
|
-
const stableRef = useRef(items);
|
|
39
|
-
if (stableRef.current !== items) stableRef.current = items;
|
|
40
68
|
return /* @__PURE__ */ jsx(Suspense, {
|
|
41
|
-
fallback,
|
|
69
|
+
fallback: /* @__PURE__ */ jsxs(Fragment, { children: [fallback, /* @__PURE__ */ jsx(PendingSignal, {})] }),
|
|
42
70
|
children: /* @__PURE__ */ jsx(AsyncItemsInner, {
|
|
43
|
-
items
|
|
71
|
+
items,
|
|
44
72
|
children
|
|
45
73
|
})
|
|
46
74
|
});
|
|
@@ -678,10 +706,20 @@ var CommandErrorBoundary = class extends Component {
|
|
|
678
706
|
componentDidCatch(error, errorInfo) {
|
|
679
707
|
this.props.onError?.(error, errorInfo);
|
|
680
708
|
}
|
|
709
|
+
componentDidUpdate(prevProps, prevState) {
|
|
710
|
+
if (this.state.error === null || prevState.error === null) return;
|
|
711
|
+
const prev = prevProps.resetKeys;
|
|
712
|
+
const next = this.props.resetKeys;
|
|
713
|
+
if (prev !== next && (prev?.length !== next?.length || next?.some((key, index) => !Object.is(key, prev?.[index])))) this.reset();
|
|
714
|
+
}
|
|
715
|
+
/** Clears the captured error so the children render again. */
|
|
716
|
+
reset = () => {
|
|
717
|
+
this.setState(INITIAL_STATE);
|
|
718
|
+
};
|
|
681
719
|
render() {
|
|
682
720
|
if (this.state.error) {
|
|
683
721
|
const { fallback } = this.props;
|
|
684
|
-
if (typeof fallback === "function") return fallback(this.state.error);
|
|
722
|
+
if (typeof fallback === "function") return fallback(this.state.error, this.reset);
|
|
685
723
|
if (fallback) return fallback;
|
|
686
724
|
return null;
|
|
687
725
|
}
|
|
@@ -696,15 +734,7 @@ function useCommandState(selector) {
|
|
|
696
734
|
const getSnapshot = useCallback(() => selectorRef.current ? selectorRef.current(stable.machine.getState()) : stable.machine.getState(), [stable.machine]);
|
|
697
735
|
return useSyncExternalStore(stable.machine.subscribe, getSnapshot, getSnapshot);
|
|
698
736
|
}
|
|
699
|
-
// src/
|
|
700
|
-
/**
|
|
701
|
-
* `true` unless `process.env.NODE_ENV` is `'production'`.
|
|
702
|
-
*
|
|
703
|
-
* Consumer bundlers (Vite, webpack, Next, esbuild) replace `process.env.NODE_ENV` statically,
|
|
704
|
-
* so the dev-only branches guarded by this flag fold away in production builds. A browser
|
|
705
|
-
* running the unbundled module throws a ReferenceError on the bare `process` reference;
|
|
706
|
-
* the catch turns that into the production value (`false`), so dev-only code stays off.
|
|
707
|
-
*/
|
|
737
|
+
// src/react/hooks/use-devtools.ts
|
|
708
738
|
const isDev = (() => {
|
|
709
739
|
try {
|
|
710
740
|
return process.env.NODE_ENV !== "production";
|
|
@@ -712,7 +742,6 @@ const isDev = (() => {
|
|
|
712
742
|
return false;
|
|
713
743
|
}
|
|
714
744
|
})();
|
|
715
|
-
// src/react/hooks/use-devtools.ts
|
|
716
745
|
/** Branded key for the global devtools instance map */
|
|
717
746
|
const DEVTOOLS_KEY = "__CRIMSON_COMMAND_DEVTOOLS__";
|
|
718
747
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modern-cmdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The definitive command palette engine for the modern web",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,11 +30,12 @@
|
|
|
30
30
|
"main": "./dist/core/index.mjs",
|
|
31
31
|
"types": "./dist/core/index.d.mts",
|
|
32
32
|
"bin": {
|
|
33
|
-
"modern-cmdk": "./dist/codemod/
|
|
33
|
+
"modern-cmdk": "./dist/codemod/bin.mjs"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"dist",
|
|
37
|
-
"LICENSE"
|
|
37
|
+
"LICENSE",
|
|
38
|
+
"THIRD-PARTY-NOTICES.md"
|
|
38
39
|
],
|
|
39
40
|
"sideEffects": [
|
|
40
41
|
"./dist/react/styles.css"
|
|
@@ -56,10 +57,7 @@
|
|
|
56
57
|
"idb-keyval": "6.3.0"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
|
-
"
|
|
60
|
-
"jscodeshift": "17.4.0",
|
|
61
|
-
"radix-ui": "1.8.2-rc.1791984254107",
|
|
62
|
-
"@types/jscodeshift": "17.3.0"
|
|
60
|
+
"radix-ui": "1.8.2-rc.1791984254107"
|
|
63
61
|
},
|
|
64
62
|
"keywords": [
|
|
65
63
|
"command-palette",
|