zudoku 0.14.0 → 0.15.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.
Files changed (67) hide show
  1. package/dist/cli/cli.js +1 -2
  2. package/dist/cli/cli.js.map +1 -1
  3. package/dist/config/validators/validate.d.ts +11 -0
  4. package/dist/config/validators/validate.js +6 -5
  5. package/dist/config/validators/validate.js.map +1 -1
  6. package/dist/lib/components/Header.js +3 -2
  7. package/dist/lib/components/Header.js.map +1 -1
  8. package/dist/lib/components/SlotletProvider.d.ts +2 -1
  9. package/dist/lib/components/SlotletProvider.js.map +1 -1
  10. package/dist/lib/plugins/custom-pages/CustomPage.js +2 -2
  11. package/dist/lib/plugins/redirect/index.d.ts +2 -5
  12. package/dist/lib/plugins/redirect/index.js +1 -1
  13. package/dist/lib/plugins/redirect/index.js.map +1 -1
  14. package/dist/lib/ui/Command.d.ts +80 -0
  15. package/dist/lib/ui/Command.js +31 -0
  16. package/dist/lib/ui/Command.js.map +1 -0
  17. package/dist/lib/util/useExposedProps.js +3 -2
  18. package/dist/lib/util/useExposedProps.js.map +1 -1
  19. package/dist/vite/build.js +5 -1
  20. package/dist/vite/build.js.map +1 -1
  21. package/dist/vite/config.d.ts +2 -8
  22. package/dist/vite/config.js +13 -53
  23. package/dist/vite/config.js.map +1 -1
  24. package/dist/vite/output.d.ts +101 -0
  25. package/dist/vite/output.js +30 -0
  26. package/dist/vite/output.js.map +1 -0
  27. package/dist/vite/plugin-config.d.ts +2 -3
  28. package/dist/vite/plugin-config.js +2 -3
  29. package/dist/vite/plugin-config.js.map +1 -1
  30. package/dist/vite/plugin.js +1 -1
  31. package/dist/vite/plugin.js.map +1 -1
  32. package/lib/Dialog-k70Qfukb.js +67 -0
  33. package/lib/Dialog-k70Qfukb.js.map +1 -0
  34. package/lib/{OperationList-DnaAtLxP.js → OperationList-Tj7ubW_t.js} +2 -2
  35. package/lib/{OperationList-DnaAtLxP.js.map → OperationList-Tj7ubW_t.js.map} +1 -1
  36. package/lib/{Route-DSbLrlig.js → Route-C3DGB6OS.js} +2 -2
  37. package/lib/{Route-DSbLrlig.js.map → Route-C3DGB6OS.js.map} +1 -1
  38. package/lib/{SlotletProvider-4Naek_5M.js → SlotletProvider-Da7eFgd2.js} +2 -2
  39. package/lib/{SlotletProvider-4Naek_5M.js.map → SlotletProvider-Da7eFgd2.js.map} +1 -1
  40. package/lib/{index-B3F9d8oi.js → index-AjWCJNGC.js} +1210 -1265
  41. package/lib/index-AjWCJNGC.js.map +1 -0
  42. package/lib/ui/Command.js +550 -0
  43. package/lib/ui/Command.js.map +1 -0
  44. package/lib/{urql-core-CqTI9H6N.js → urql-core-KJnLL26g.js} +261 -289
  45. package/lib/urql-core-KJnLL26g.js.map +1 -0
  46. package/lib/useExposedProps-ChOIUaS4.js +9 -0
  47. package/lib/useExposedProps-ChOIUaS4.js.map +1 -0
  48. package/lib/zudoku.components.js +44 -38
  49. package/lib/zudoku.components.js.map +1 -1
  50. package/lib/zudoku.openapi-worker.js +1 -1
  51. package/lib/zudoku.plugin-api-keys.js +1 -1
  52. package/lib/zudoku.plugin-custom-pages.js +13 -13
  53. package/lib/zudoku.plugin-custom-pages.js.map +1 -1
  54. package/lib/zudoku.plugin-openapi.js +2 -2
  55. package/lib/zudoku.plugin-redirect.js +1 -1
  56. package/lib/zudoku.plugin-redirect.js.map +1 -1
  57. package/package.json +3 -2
  58. package/src/lib/components/Header.tsx +9 -2
  59. package/src/lib/components/SlotletProvider.tsx +2 -0
  60. package/src/lib/plugins/custom-pages/CustomPage.tsx +2 -2
  61. package/src/lib/plugins/redirect/index.tsx +3 -7
  62. package/src/lib/ui/Command.tsx +151 -0
  63. package/src/lib/util/useExposedProps.tsx +8 -2
  64. package/lib/index-B3F9d8oi.js.map +0 -1
  65. package/lib/urql-core-CqTI9H6N.js.map +0 -1
  66. package/lib/useExposedProps-B9K-9GTc.js +0 -9
  67. package/lib/useExposedProps-B9K-9GTc.js.map +0 -1
@@ -15,7 +15,7 @@ var Sn = (t, e, n, i) => ({
15
15
  });
16
16
  import { a as $l } from "./index-LNp6rxyU.js";
17
17
  import { g as jl } from "./_commonjsHelpers-BkfeUUK-.js";
18
- import { C as Qa, b as Wa, m as Ha, f as Ya } from "./urql-core-CqTI9H6N.js";
18
+ import { C as Qa, b as Wa, m as Ha, f as Ya } from "./urql-core-KJnLL26g.js";
19
19
  function Pl(t, e) {
20
20
  for (var n = 0; n < e.length; n++) {
21
21
  const i = e[n];
@@ -1,5 +1,5 @@
1
1
  import { j as e } from "./jsx-runtime-B6kdoens.js";
2
- import { S as m, R as g } from "./SlotletProvider-4Naek_5M.js";
2
+ import { S as m, R as g } from "./SlotletProvider-Da7eFgd2.js";
3
3
  import { i as c } from "./invariant-Caa8-XvF.js";
4
4
  import { u as d, S as f, a as j, b as v, c as w, d as b, e as x } from "./Select-Bagt3Bme.js";
5
5
  import { a as k } from "./index.esm-C5mr_sKO.js";
@@ -1,22 +1,22 @@
1
- import { j as e } from "./jsx-runtime-B6kdoens.js";
1
+ import { j as o } from "./jsx-runtime-B6kdoens.js";
2
2
  import a from "react";
3
3
  import { P as n } from "./Markdown-BDcCAWwm.js";
4
4
  import { c } from "./cn-BmFQLtkS.js";
5
- import { u } from "./useExposedProps-B9K-9GTc.js";
6
- const l = ({
7
- element: s,
8
- render: t,
9
- prose: o = !0
5
+ import { u as p } from "./useExposedProps-ChOIUaS4.js";
6
+ const u = ({
7
+ element: t,
8
+ render: s,
9
+ prose: e = !0
10
10
  }) => {
11
- const r = u(), m = t ? a.createElement(t, r) : s;
12
- return /* @__PURE__ */ e.jsx("div", { className: c(o && n, "max-w-full"), children: m });
13
- }, g = (s) => ({
14
- getRoutes: () => s.map(({ path: t, ...o }) => ({
15
- path: t,
16
- element: /* @__PURE__ */ e.jsx(l, { ...o })
11
+ const r = p(), m = s ? a.createElement(s, r) : t;
12
+ return /* @__PURE__ */ o.jsx("div", { className: c(e && n, "max-w-full"), children: m });
13
+ }, d = (t) => ({
14
+ getRoutes: () => t.map(({ path: s, ...e }) => ({
15
+ path: s,
16
+ element: /* @__PURE__ */ o.jsx(u, { ...e })
17
17
  }))
18
18
  });
19
19
  export {
20
- g as customPagesPlugin
20
+ d as customPagesPlugin
21
21
  };
22
22
  //# sourceMappingURL=zudoku.plugin-custom-pages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zudoku.plugin-custom-pages.js","sources":["../src/lib/plugins/custom-pages/CustomPage.tsx","../src/lib/plugins/custom-pages/index.tsx"],"sourcesContent":["import React from \"react\";\nimport { ProseClasses } from \"../../components/Markdown.js\";\nimport { cn } from \"../../util/cn.js\";\nimport { useExposedProps } from \"../../util/useExposedProps.js\";\nimport type { CustomPageConfig } from \"./index.js\";\n\nexport const CustomPage = ({\n element,\n render,\n prose = true,\n}: Omit<CustomPageConfig, \"path\">) => {\n const slotletProps = useExposedProps();\n const content = render ? React.createElement(render, slotletProps) : element;\n\n return (\n <div className={cn(prose && ProseClasses, \"max-w-full\")}>{content}</div>\n );\n};\n","import { type ComponentType, type ReactNode } from \"react\";\nimport type { RouteObject } from \"react-router-dom\";\nimport { type ExposedComponentProps } from \"../../components/SlotletProvider.js\";\nimport type { DevPortalPlugin, NavigationPlugin } from \"../../core/plugins.js\";\nimport { CustomPage } from \"./CustomPage.js\";\n\nexport type CustomPageConfig = {\n path: string;\n prose?: boolean;\n element?: ReactNode;\n render?: ComponentType<ExposedComponentProps>;\n};\n\nexport const customPagesPlugin = (\n config: CustomPageConfig[],\n): DevPortalPlugin & NavigationPlugin => {\n return {\n getRoutes: (): RouteObject[] =>\n config.map(({ path, ...props }) => ({\n path,\n element: <CustomPage {...props} />,\n })),\n };\n};\n"],"names":["CustomPage","element","render","prose","slotletProps","useExposedProps","content","React","jsx","cn","ProseClasses","customPagesPlugin","config","path","props"],"mappings":";;;;;AAMO,MAAMA,IAAa,CAAC;AAAA,EACzB,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,OAAAC,IAAQ;AACV,MAAsC;AACpC,QAAMC,IAAeC,KACfC,IAAUJ,IAASK,EAAM,cAAcL,GAAQE,CAAY,IAAIH;AAGnE,SAAAO,gBAAAA,MAAC,SAAI,WAAWC,EAAGN,KAASO,GAAc,YAAY,GAAI,UAAQJ,EAAA,CAAA;AAEtE,GCJaK,IAAoB,CAC/BC,OAEO;AAAA,EACL,WAAW,MACTA,EAAO,IAAI,CAAC,EAAE,MAAAC,GAAM,GAAGC,SAAa;AAAA,IAClC,MAAAD;AAAA,IACA,SAASL,gBAAAA,EAAAA,IAACR,GAAY,EAAA,GAAGc,EAAO,CAAA;AAAA,EAAA,EAChC;AAAA;"}
1
+ {"version":3,"file":"zudoku.plugin-custom-pages.js","sources":["../src/lib/plugins/custom-pages/CustomPage.tsx","../src/lib/plugins/custom-pages/index.tsx"],"sourcesContent":["import React from \"react\";\nimport { ProseClasses } from \"../../components/Markdown.js\";\nimport { cn } from \"../../util/cn.js\";\nimport { useExposedProps } from \"../../util/useExposedProps.js\";\nimport type { CustomPageConfig } from \"./index.js\";\n\nexport const CustomPage = ({\n element,\n render,\n prose = true,\n}: Omit<CustomPageConfig, \"path\">) => {\n const exposedProps = useExposedProps();\n const content = render ? React.createElement(render, exposedProps) : element;\n\n return (\n <div className={cn(prose && ProseClasses, \"max-w-full\")}>{content}</div>\n );\n};\n","import { type ComponentType, type ReactNode } from \"react\";\nimport type { RouteObject } from \"react-router-dom\";\nimport { type ExposedComponentProps } from \"../../components/SlotletProvider.js\";\nimport type { DevPortalPlugin, NavigationPlugin } from \"../../core/plugins.js\";\nimport { CustomPage } from \"./CustomPage.js\";\n\nexport type CustomPageConfig = {\n path: string;\n prose?: boolean;\n element?: ReactNode;\n render?: ComponentType<ExposedComponentProps>;\n};\n\nexport const customPagesPlugin = (\n config: CustomPageConfig[],\n): DevPortalPlugin & NavigationPlugin => {\n return {\n getRoutes: (): RouteObject[] =>\n config.map(({ path, ...props }) => ({\n path,\n element: <CustomPage {...props} />,\n })),\n };\n};\n"],"names":["CustomPage","element","render","prose","exposedProps","useExposedProps","content","React","jsx","cn","ProseClasses","customPagesPlugin","config","path","props"],"mappings":";;;;;AAMO,MAAMA,IAAa,CAAC;AAAA,EACzB,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,OAAAC,IAAQ;AACV,MAAsC;AACpC,QAAMC,IAAeC,KACfC,IAAUJ,IAASK,EAAM,cAAcL,GAAQE,CAAY,IAAIH;AAGnE,SAAAO,gBAAAA,MAAC,SAAI,WAAWC,EAAGN,KAASO,GAAc,YAAY,GAAI,UAAQJ,EAAA,CAAA;AAEtE,GCJaK,IAAoB,CAC/BC,OAEO;AAAA,EACL,WAAW,MACTA,EAAO,IAAI,CAAC,EAAE,MAAAC,GAAM,GAAGC,SAAa;AAAA,IAClC,MAAAD;AAAA,IACA,SAASL,gBAAAA,EAAAA,IAACR,GAAY,EAAA,GAAGc,EAAO,CAAA;AAAA,EAAA,EAChC;AAAA;"}
@@ -1,12 +1,12 @@
1
1
  import "./jsx-runtime-B6kdoens.js";
2
- import { o as s } from "./index-B3F9d8oi.js";
2
+ import { o as s } from "./index-AjWCJNGC.js";
3
3
  import "./ZudokuContext-BKXGJTmu.js";
4
4
  import "lucide-react";
5
5
  import "zudoku/openapi-worker";
6
6
  import "./hook-sn0zMTkE.js";
7
7
  import "./Markdown-BDcCAWwm.js";
8
8
  import "./ui/Button.js";
9
- import "./urql-core-CqTI9H6N.js";
9
+ import "./urql-core-KJnLL26g.js";
10
10
  import "./router-BsfSoK2j.js";
11
11
  import "./index-CRo94sKK.js";
12
12
  export {
@@ -2,7 +2,7 @@ import { r as o } from "./router-BsfSoK2j.js";
2
2
  const a = (r) => ({
3
3
  getRoutes: () => r.redirects.map(({ from: e, to: t }) => ({
4
4
  path: e,
5
- loader: () => o(t)
5
+ loader: () => o(t, 301)
6
6
  }))
7
7
  });
8
8
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"zudoku.plugin-redirect.js","sources":["../src/lib/plugins/redirect/index.tsx"],"sourcesContent":["import { redirect } from \"react-router-dom\";\nimport type { DevPortalPlugin } from \"../../core/plugins.js\";\n\nexport type Redirect = {\n from: string;\n to: string;\n};\n\nexport const redirectPlugin = (options: {\n redirects: Redirect[];\n}): DevPortalPlugin => {\n return {\n getRoutes: () =>\n options.redirects.map(({ from, to }) => ({\n path: from,\n loader: () => redirect(to),\n })),\n };\n};\n"],"names":["redirectPlugin","options","from","to","redirect"],"mappings":";AAQa,MAAAA,IAAiB,CAACC,OAGtB;AAAA,EACL,WAAW,MACTA,EAAQ,UAAU,IAAI,CAAC,EAAE,MAAAC,GAAM,IAAAC,SAAU;AAAA,IACvC,MAAMD;AAAA,IACN,QAAQ,MAAME,EAASD,CAAE;AAAA,EAAA,EACzB;AAAA;"}
1
+ {"version":3,"file":"zudoku.plugin-redirect.js","sources":["../src/lib/plugins/redirect/index.tsx"],"sourcesContent":["import { redirect } from \"react-router-dom\";\nimport { ZudokuRedirect } from \"../../../config/validators/validate.js\";\nimport type { DevPortalPlugin } from \"../../core/plugins.js\";\n\nexport const redirectPlugin = (options: {\n redirects: ZudokuRedirect[];\n}): DevPortalPlugin => {\n return {\n getRoutes: () =>\n options.redirects.map(({ from, to }) => ({\n path: from,\n loader: () => redirect(to, 301),\n })),\n };\n};\n"],"names":["redirectPlugin","options","from","to","redirect"],"mappings":";AAIa,MAAAA,IAAiB,CAACC,OAGtB;AAAA,EACL,WAAW,MACTA,EAAQ,UAAU,IAAI,CAAC,EAAE,MAAAC,GAAM,IAAAC,SAAU;AAAA,IACvC,MAAMD;AAAA,IACN,QAAQ,MAAME,EAASD,GAAI,GAAG;AAAA,EAAA,EAC9B;AAAA;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "type": "module",
5
5
  "homepage": "https://zudoku.dev",
6
6
  "repository": {
@@ -141,12 +141,14 @@
141
141
  "@types/react": "18.3.11",
142
142
  "@types/react-dom": "18.3.1",
143
143
  "@vitejs/plugin-react": "4.3.1",
144
+ "@zudoku/config": "0.15.0",
144
145
  "@zudoku/httpsnippet": "10.0.9",
145
146
  "@zudoku/react-helmet-async": "2.0.4",
146
147
  "autoprefixer": "10.4.20",
147
148
  "chokidar": "3.6.0",
148
149
  "class-variance-authority": "0.7.0",
149
150
  "clsx": "2.1.1",
151
+ "cmdk": "1.0.4",
150
152
  "dotenv": "16.4.5",
151
153
  "embla-carousel-react": "8.3.1",
152
154
  "express": "4.21.1",
@@ -186,7 +188,6 @@
186
188
  "strip-ansi": "7.1.0",
187
189
  "tailwind-merge": "2.5.4",
188
190
  "tailwindcss": "3.4.13",
189
- "tsx": "4.19.1",
190
191
  "ulidx": "2.4.1",
191
192
  "unist-util-visit": "5.0.0",
192
193
  "urql": "4.1.0",
@@ -17,6 +17,7 @@ import {
17
17
  DropdownMenuTrigger,
18
18
  } from "../ui/DropdownMenu.js";
19
19
  import { cn } from "../util/cn.js";
20
+ import { joinPath } from "../util/joinPath.js";
20
21
  import { Banner } from "./Banner.js";
21
22
  import { useTheme } from "./context/ThemeContext.js";
22
23
  import { useZudoku } from "./context/ZudokuContext.js";
@@ -73,7 +74,10 @@ export const Header = memo(function HeaderInner() {
73
74
  src={
74
75
  /https?:\/\//.test(page.logo.src.light)
75
76
  ? page.logo.src.light
76
- : import.meta.env.BASE_URL + page.logo.src.light
77
+ : joinPath(
78
+ import.meta.env.BASE_URL,
79
+ page.logo.src.light,
80
+ )
77
81
  }
78
82
  alt={page.logo.alt ?? page.pageTitle}
79
83
  style={{ width: page.logo.width }}
@@ -84,7 +88,10 @@ export const Header = memo(function HeaderInner() {
84
88
  src={
85
89
  /https?:\/\//.test(page.logo.src.dark)
86
90
  ? page.logo.src.dark
87
- : import.meta.env.BASE_URL + page.logo.src.dark
91
+ : joinPath(
92
+ import.meta.env.BASE_URL,
93
+ page.logo.src.dark,
94
+ )
88
95
  }
89
96
  alt={page.logo.alt ?? page.pageTitle}
90
97
  style={{ width: page.logo.width }}
@@ -8,6 +8,7 @@ import { isValidElementType } from "react-is";
8
8
  import {
9
9
  type Location,
10
10
  type NavigateFunction,
11
+ type Params,
11
12
  type SetURLSearchParams,
12
13
  } from "react-router-dom";
13
14
  import { useExposedProps } from "../util/useExposedProps.js";
@@ -38,6 +39,7 @@ export type ExposedComponentProps = {
38
39
  navigate: NavigateFunction;
39
40
  searchParams: URLSearchParams;
40
41
  setSearchParams: SetURLSearchParams;
42
+ params: Params;
41
43
  };
42
44
 
43
45
  export const Slotlet = ({ name }: { name: string }) => {
@@ -9,8 +9,8 @@ export const CustomPage = ({
9
9
  render,
10
10
  prose = true,
11
11
  }: Omit<CustomPageConfig, "path">) => {
12
- const slotletProps = useExposedProps();
13
- const content = render ? React.createElement(render, slotletProps) : element;
12
+ const exposedProps = useExposedProps();
13
+ const content = render ? React.createElement(render, exposedProps) : element;
14
14
 
15
15
  return (
16
16
  <div className={cn(prose && ProseClasses, "max-w-full")}>{content}</div>
@@ -1,19 +1,15 @@
1
1
  import { redirect } from "react-router-dom";
2
+ import { ZudokuRedirect } from "../../../config/validators/validate.js";
2
3
  import type { DevPortalPlugin } from "../../core/plugins.js";
3
4
 
4
- export type Redirect = {
5
- from: string;
6
- to: string;
7
- };
8
-
9
5
  export const redirectPlugin = (options: {
10
- redirects: Redirect[];
6
+ redirects: ZudokuRedirect[];
11
7
  }): DevPortalPlugin => {
12
8
  return {
13
9
  getRoutes: () =>
14
10
  options.redirects.map(({ from, to }) => ({
15
11
  path: from,
16
- loader: () => redirect(to),
12
+ loader: () => redirect(to, 301),
17
13
  })),
18
14
  };
19
15
  };
@@ -0,0 +1,151 @@
1
+ import { type DialogProps } from "@radix-ui/react-dialog";
2
+ import { Command as CommandPrimitive } from "cmdk";
3
+ import { Search } from "lucide-react";
4
+ import * as React from "react";
5
+ import { Dialog, DialogContent } from "zudoku/ui/Dialog.js";
6
+ import { cn } from "../util/cn.js";
7
+
8
+ const Command = React.forwardRef<
9
+ React.ElementRef<typeof CommandPrimitive>,
10
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive>
11
+ >(({ className, ...props }, ref) => (
12
+ <CommandPrimitive
13
+ ref={ref}
14
+ className={cn(
15
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
16
+ className,
17
+ )}
18
+ {...props}
19
+ />
20
+ ));
21
+ Command.displayName = CommandPrimitive.displayName;
22
+
23
+ const CommandDialog = ({ children, ...props }: DialogProps) => {
24
+ return (
25
+ <Dialog {...props}>
26
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
27
+ <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
28
+ {children}
29
+ </Command>
30
+ </DialogContent>
31
+ </Dialog>
32
+ );
33
+ };
34
+
35
+ const CommandInput = React.forwardRef<
36
+ React.ElementRef<typeof CommandPrimitive.Input>,
37
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
38
+ >(({ className, ...props }, ref) => (
39
+ // eslint-disable-next-line react/no-unknown-property
40
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
41
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
42
+ <CommandPrimitive.Input
43
+ ref={ref}
44
+ className={cn(
45
+ "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
46
+ className,
47
+ )}
48
+ {...props}
49
+ />
50
+ </div>
51
+ ));
52
+
53
+ CommandInput.displayName = CommandPrimitive.Input.displayName;
54
+
55
+ const CommandList = React.forwardRef<
56
+ React.ElementRef<typeof CommandPrimitive.List>,
57
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
58
+ >(({ className, ...props }, ref) => (
59
+ <CommandPrimitive.List
60
+ ref={ref}
61
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
62
+ {...props}
63
+ />
64
+ ));
65
+
66
+ CommandList.displayName = CommandPrimitive.List.displayName;
67
+
68
+ const CommandEmpty = React.forwardRef<
69
+ React.ElementRef<typeof CommandPrimitive.Empty>,
70
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
71
+ >((props, ref) => (
72
+ <CommandPrimitive.Empty
73
+ ref={ref}
74
+ className="py-6 text-center text-sm"
75
+ {...props}
76
+ />
77
+ ));
78
+
79
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
80
+
81
+ const CommandGroup = React.forwardRef<
82
+ React.ElementRef<typeof CommandPrimitive.Group>,
83
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
84
+ >(({ className, ...props }, ref) => (
85
+ <CommandPrimitive.Group
86
+ ref={ref}
87
+ className={cn(
88
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
89
+ className,
90
+ )}
91
+ {...props}
92
+ />
93
+ ));
94
+
95
+ CommandGroup.displayName = CommandPrimitive.Group.displayName;
96
+
97
+ const CommandSeparator = React.forwardRef<
98
+ React.ElementRef<typeof CommandPrimitive.Separator>,
99
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
100
+ >(({ className, ...props }, ref) => (
101
+ <CommandPrimitive.Separator
102
+ ref={ref}
103
+ className={cn("-mx-1 h-px bg-border", className)}
104
+ {...props}
105
+ />
106
+ ));
107
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
108
+
109
+ const CommandItem = React.forwardRef<
110
+ React.ElementRef<typeof CommandPrimitive.Item>,
111
+ React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
112
+ >(({ className, ...props }, ref) => (
113
+ <CommandPrimitive.Item
114
+ ref={ref}
115
+ className={cn(
116
+ "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
117
+ className,
118
+ )}
119
+ {...props}
120
+ />
121
+ ));
122
+
123
+ CommandItem.displayName = CommandPrimitive.Item.displayName;
124
+
125
+ const CommandShortcut = ({
126
+ className,
127
+ ...props
128
+ }: React.HTMLAttributes<HTMLSpanElement>) => {
129
+ return (
130
+ <span
131
+ className={cn(
132
+ "ml-auto text-xs tracking-widest text-muted-foreground",
133
+ className,
134
+ )}
135
+ {...props}
136
+ />
137
+ );
138
+ };
139
+ CommandShortcut.displayName = "CommandShortcut";
140
+
141
+ export {
142
+ Command,
143
+ CommandDialog,
144
+ CommandEmpty,
145
+ CommandGroup,
146
+ CommandInput,
147
+ CommandItem,
148
+ CommandList,
149
+ CommandSeparator,
150
+ CommandShortcut,
151
+ };
@@ -1,10 +1,16 @@
1
- import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
1
+ import {
2
+ useLocation,
3
+ useNavigate,
4
+ useParams,
5
+ useSearchParams,
6
+ } from "react-router-dom";
2
7
  import type { ExposedComponentProps } from "../components/SlotletProvider.js";
3
8
 
4
9
  export const useExposedProps = (): ExposedComponentProps => {
5
10
  const location = useLocation();
6
11
  const navigate = useNavigate();
7
12
  const [searchParams, setSearchParams] = useSearchParams();
13
+ const params = useParams();
8
14
 
9
- return { location, navigate, searchParams, setSearchParams };
15
+ return { location, navigate, params, searchParams, setSearchParams };
10
16
  };