zudoku 0.32.6 → 0.33.1

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 (205) hide show
  1. package/cli.js +3 -0
  2. package/dist/app/main.js +1 -1
  3. package/dist/app/main.js.map +1 -1
  4. package/dist/cli/build/handler.d.ts +1 -3
  5. package/dist/cli/build/handler.js +7 -0
  6. package/dist/cli/build/handler.js.map +1 -1
  7. package/dist/cli/cli.js +5 -0
  8. package/dist/cli/cli.js.map +1 -1
  9. package/dist/cli/cmds/build.d.ts +11 -3
  10. package/dist/cli/cmds/build.js +20 -13
  11. package/dist/cli/cmds/build.js.map +1 -1
  12. package/dist/cli/cmds/preview.d.ts +16 -0
  13. package/dist/cli/cmds/preview.js +25 -0
  14. package/dist/cli/cmds/preview.js.map +1 -0
  15. package/dist/cli/preview/handler.d.ts +3 -0
  16. package/dist/cli/preview/handler.js +37 -0
  17. package/dist/cli/preview/handler.js.map +1 -0
  18. package/dist/config/common.d.ts +5 -2
  19. package/dist/config/config.d.ts +2 -7
  20. package/dist/config/loader.d.ts +4 -4
  21. package/dist/config/loader.js +7 -4
  22. package/dist/config/loader.js.map +1 -1
  23. package/dist/config/validators/validate.d.ts +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +1 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/lib/authentication/providers/auth0.d.ts +2 -2
  28. package/dist/lib/authentication/providers/auth0.js +1 -0
  29. package/dist/lib/authentication/providers/auth0.js.map +1 -1
  30. package/dist/lib/authentication/providers/openid.d.ts +4 -3
  31. package/dist/lib/authentication/providers/openid.js +4 -2
  32. package/dist/lib/authentication/providers/openid.js.map +1 -1
  33. package/dist/lib/authentication/state.js +8 -2
  34. package/dist/lib/authentication/state.js.map +1 -1
  35. package/dist/lib/components/ThemeSwitch.js +1 -1
  36. package/dist/lib/components/ThemeSwitch.js.map +1 -1
  37. package/dist/lib/components/Zudoku.d.ts +1 -1
  38. package/dist/lib/components/Zudoku.js +7 -6
  39. package/dist/lib/components/Zudoku.js.map +1 -1
  40. package/dist/lib/components/context/RouterEventsEmitter.d.ts +1 -0
  41. package/dist/lib/components/context/RouterEventsEmitter.js +17 -0
  42. package/dist/lib/components/context/RouterEventsEmitter.js.map +1 -0
  43. package/dist/lib/components/index.d.ts +1 -1
  44. package/dist/lib/core/RouteGuard.d.ts +1 -1
  45. package/dist/lib/core/RouteGuard.js +23 -18
  46. package/dist/lib/core/RouteGuard.js.map +1 -1
  47. package/dist/lib/core/ZudokuContext.d.ts +10 -0
  48. package/dist/lib/core/ZudokuContext.js +17 -1
  49. package/dist/lib/core/ZudokuContext.js.map +1 -1
  50. package/dist/lib/core/plugins.d.ts +8 -2
  51. package/dist/lib/core/plugins.js +1 -0
  52. package/dist/lib/core/plugins.js.map +1 -1
  53. package/dist/lib/hooks/index.d.ts +3 -0
  54. package/dist/lib/hooks/index.js +5 -0
  55. package/dist/lib/hooks/index.js.map +1 -0
  56. package/dist/lib/hooks/useEvent.d.ts +11 -0
  57. package/dist/lib/hooks/useEvent.js +19 -0
  58. package/dist/lib/hooks/useEvent.js.map +1 -0
  59. package/dist/lib/hooks/useEvent.test.d.ts +1 -0
  60. package/dist/lib/hooks/useEvent.test.js +100 -0
  61. package/dist/lib/hooks/useEvent.test.js.map +1 -0
  62. package/dist/lib/plugins/openapi/Sidecar.js +1 -1
  63. package/dist/lib/plugins/openapi/Sidecar.js.map +1 -1
  64. package/dist/lib/ui/Stepper.d.ts +4 -0
  65. package/dist/lib/ui/Stepper.js +7 -0
  66. package/dist/lib/ui/Stepper.js.map +1 -0
  67. package/dist/lib/util/MdxComponents.d.ts +3 -1
  68. package/dist/lib/util/MdxComponents.js +3 -0
  69. package/dist/lib/util/MdxComponents.js.map +1 -1
  70. package/dist/vite/config.d.ts +2 -5
  71. package/dist/vite/config.js +21 -28
  72. package/dist/vite/config.js.map +1 -1
  73. package/dist/vite/config.test.js +1 -1
  74. package/dist/vite/config.test.js.map +1 -1
  75. package/dist/vite/css/plugin.d.ts +2 -2
  76. package/dist/vite/css/plugin.js.map +1 -1
  77. package/dist/vite/dev-server.js.map +1 -1
  78. package/dist/vite/plugin-api-keys.d.ts +2 -2
  79. package/dist/vite/plugin-api-keys.js +3 -3
  80. package/dist/vite/plugin-api-keys.js.map +1 -1
  81. package/dist/vite/plugin-api.d.ts +2 -2
  82. package/dist/vite/plugin-api.js +5 -5
  83. package/dist/vite/plugin-api.js.map +1 -1
  84. package/dist/vite/plugin-auth.d.ts +2 -2
  85. package/dist/vite/plugin-auth.js +3 -3
  86. package/dist/vite/plugin-auth.js.map +1 -1
  87. package/dist/vite/plugin-component.d.ts +2 -2
  88. package/dist/vite/plugin-component.js +3 -2
  89. package/dist/vite/plugin-component.js.map +1 -1
  90. package/dist/vite/plugin-config-reload.d.ts +4 -3
  91. package/dist/vite/plugin-config-reload.js +11 -8
  92. package/dist/vite/plugin-config-reload.js.map +1 -1
  93. package/dist/vite/plugin-config.d.ts +2 -2
  94. package/dist/vite/plugin-config.js +2 -2
  95. package/dist/vite/plugin-config.js.map +1 -1
  96. package/dist/vite/plugin-custom-pages.d.ts +2 -2
  97. package/dist/vite/plugin-custom-pages.js +3 -3
  98. package/dist/vite/plugin-custom-pages.js.map +1 -1
  99. package/dist/vite/plugin-docs.d.ts +2 -2
  100. package/dist/vite/plugin-docs.js +5 -5
  101. package/dist/vite/plugin-docs.js.map +1 -1
  102. package/dist/vite/plugin-frontmatter.d.ts +2 -2
  103. package/dist/vite/plugin-frontmatter.js +5 -4
  104. package/dist/vite/plugin-frontmatter.js.map +1 -1
  105. package/dist/vite/plugin-mdx.d.ts +2 -2
  106. package/dist/vite/plugin-mdx.js +1 -1
  107. package/dist/vite/plugin-mdx.js.map +1 -1
  108. package/dist/vite/plugin-redirect.d.ts +2 -2
  109. package/dist/vite/plugin-redirect.js +3 -3
  110. package/dist/vite/plugin-redirect.js.map +1 -1
  111. package/dist/vite/plugin-search.d.ts +2 -2
  112. package/dist/vite/plugin-search.js +1 -1
  113. package/dist/vite/plugin-search.js.map +1 -1
  114. package/dist/vite/plugin-sidebar.d.ts +2 -2
  115. package/dist/vite/plugin-sidebar.js +2 -2
  116. package/dist/vite/plugin-sidebar.js.map +1 -1
  117. package/dist/vite/plugin-theme-css.d.ts +2 -2
  118. package/dist/vite/plugin-theme-css.js.map +1 -1
  119. package/dist/vite/plugin.d.ts +2 -2
  120. package/dist/vite/plugin.js.map +1 -1
  121. package/dist/vite/prerender/FileWritingResponse.d.ts +2 -1
  122. package/dist/vite/prerender/FileWritingResponse.js +4 -1
  123. package/dist/vite/prerender/FileWritingResponse.js.map +1 -1
  124. package/dist/vite/prerender/worker.d.ts +1 -1
  125. package/dist/vite/prerender/worker.js +3 -0
  126. package/dist/vite/prerender/worker.js.map +1 -1
  127. package/lib/{AuthenticationPlugin-BlxA4Mbn.js → AuthenticationPlugin-CiO1FM6Q.js} +2 -2
  128. package/lib/{AuthenticationPlugin-BlxA4Mbn.js.map → AuthenticationPlugin-CiO1FM6Q.js.map} +1 -1
  129. package/lib/Dialog-DIKGQxQc.js +83 -0
  130. package/lib/Dialog-DIKGQxQc.js.map +1 -0
  131. package/lib/{Markdown-Cr9sYpR_.js → Markdown-DePfm7oQ.js} +1384 -1381
  132. package/lib/{Markdown-Cr9sYpR_.js.map → Markdown-DePfm7oQ.js.map} +1 -1
  133. package/lib/{MdxPage-Dt-UEQl8.js → MdxPage-DZTt9ld7.js} +4 -4
  134. package/lib/{MdxPage-Dt-UEQl8.js.map → MdxPage-DZTt9ld7.js.map} +1 -1
  135. package/lib/{OasProvider-WVtvHP5H.js → OasProvider-SzD9mHJc.js} +3 -3
  136. package/lib/{OasProvider-WVtvHP5H.js.map → OasProvider-SzD9mHJc.js.map} +1 -1
  137. package/lib/{OperationList-DhOwupvv.js → OperationList-DDs9NblY.js} +242 -241
  138. package/lib/OperationList-DDs9NblY.js.map +1 -0
  139. package/lib/{Select-D9hI1G-y.js → Select-Dqtcn53H.js} +36 -36
  140. package/lib/{Select-D9hI1G-y.js.map → Select-Dqtcn53H.js.map} +1 -1
  141. package/lib/{SlotletProvider-CEfNOA8i.js → SlotletProvider-DdtIOUi6.js} +2 -2
  142. package/lib/{SlotletProvider-CEfNOA8i.js.map → SlotletProvider-DdtIOUi6.js.map} +1 -1
  143. package/lib/{createServer-DMf6O2Rz.js → createServer-DmusVVsi.js} +987 -967
  144. package/lib/createServer-DmusVVsi.js.map +1 -0
  145. package/lib/{hook-CWwSAAlH.js → hook-CN__aZIt.js} +67 -63
  146. package/lib/{hook-CWwSAAlH.js.map → hook-CN__aZIt.js.map} +1 -1
  147. package/lib/{index-Do_30Hpk.js → index-CibzSNks.js} +95 -93
  148. package/lib/{index-Do_30Hpk.js.map → index-CibzSNks.js.map} +1 -1
  149. package/lib/index-DwT-v3zK.js +86 -0
  150. package/lib/index-DwT-v3zK.js.map +1 -0
  151. package/lib/index-gQD2h1wX.js +447 -0
  152. package/lib/index-gQD2h1wX.js.map +1 -0
  153. package/lib/{mutation-B0wxqzSN.js → mutation-EclmI0is.js} +2 -2
  154. package/lib/{mutation-B0wxqzSN.js.map → mutation-EclmI0is.js.map} +1 -1
  155. package/lib/objectEntries-yMIkr2mI.js +5 -0
  156. package/lib/objectEntries-yMIkr2mI.js.map +1 -0
  157. package/lib/ui/Command.js +21 -20
  158. package/lib/ui/Command.js.map +1 -1
  159. package/lib/ui/Stepper.js +6 -0
  160. package/lib/ui/Stepper.js.map +1 -0
  161. package/lib/ui/SyntaxHighlight.js +2902 -7
  162. package/lib/ui/SyntaxHighlight.js.map +1 -1
  163. package/lib/{useScrollToAnchor-C-sRxs9o.js → useScrollToAnchor-C7ilRSts.js} +3 -3
  164. package/lib/{useScrollToAnchor-C-sRxs9o.js.map → useScrollToAnchor-C7ilRSts.js.map} +1 -1
  165. package/lib/zudoku.auth-auth0.js +15 -14
  166. package/lib/zudoku.auth-auth0.js.map +1 -1
  167. package/lib/zudoku.auth-clerk.js +2 -2
  168. package/lib/zudoku.auth-openid.js +126 -124
  169. package/lib/zudoku.auth-openid.js.map +1 -1
  170. package/lib/zudoku.components.js +441 -395
  171. package/lib/zudoku.components.js.map +1 -1
  172. package/lib/zudoku.css +1 -0
  173. package/lib/zudoku.hooks.js +19 -0
  174. package/lib/zudoku.hooks.js.map +1 -0
  175. package/lib/zudoku.plugin-api-catalog.js +2 -2
  176. package/lib/zudoku.plugin-api-keys.js +5 -5
  177. package/lib/zudoku.plugin-custom-pages.js +1 -1
  178. package/lib/zudoku.plugin-markdown.js +1 -1
  179. package/lib/zudoku.plugin-openapi.js +2 -2
  180. package/lib/zudoku.plugins.js +9 -8
  181. package/lib/zudoku.plugins.js.map +1 -1
  182. package/package.json +12 -4
  183. package/src/app/main.tsx +1 -1
  184. package/src/lib/authentication/providers/auth0.tsx +3 -2
  185. package/src/lib/authentication/providers/openid.tsx +8 -5
  186. package/src/lib/authentication/state.ts +8 -2
  187. package/src/lib/components/ThemeSwitch.tsx +1 -1
  188. package/src/lib/components/Zudoku.tsx +9 -5
  189. package/src/lib/components/context/RouterEventsEmitter.tsx +19 -0
  190. package/src/lib/core/RouteGuard.tsx +43 -18
  191. package/src/lib/core/ZudokuContext.ts +31 -0
  192. package/src/lib/core/plugins.ts +16 -2
  193. package/src/lib/hooks/index.ts +5 -0
  194. package/src/lib/hooks/useEvent.test.tsx +149 -0
  195. package/src/lib/hooks/useEvent.ts +41 -0
  196. package/src/lib/plugins/openapi/Sidecar.tsx +1 -1
  197. package/src/lib/ui/Stepper.css +43 -0
  198. package/src/lib/ui/Stepper.tsx +8 -0
  199. package/src/lib/util/MdxComponents.tsx +4 -1
  200. package/lib/OperationList-DhOwupvv.js.map +0 -1
  201. package/lib/SyntaxHighlight-CcnUjERD.js +0 -2986
  202. package/lib/SyntaxHighlight-CcnUjERD.js.map +0 -1
  203. package/lib/createServer-DMf6O2Rz.js.map +0 -1
  204. package/lib/index-Du5aNddU.js +0 -509
  205. package/lib/index-Du5aNddU.js.map +0 -1
@@ -0,0 +1,149 @@
1
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
2
+ import { act, renderHook, waitFor } from "@testing-library/react";
3
+ import { type PropsWithChildren } from "react";
4
+ import { type Location } from "react-router";
5
+ import { assertType, describe, expect, it, vi } from "vitest";
6
+ import { ZudokuProvider } from "../components/context/ZudokuProvider.js";
7
+ import { ZudokuContext, type ZudokuEvents } from "../core/ZudokuContext.js";
8
+ import { useEvent } from "./useEvent.js";
9
+
10
+ /**
11
+ * @vitest-environment happy-dom
12
+ */
13
+
14
+ const createTestContext = () => {
15
+ const context = new ZudokuContext({});
16
+ const queryClient = new QueryClient();
17
+ const wrapper = ({ children }: PropsWithChildren) => (
18
+ <QueryClientProvider client={queryClient}>
19
+ <ZudokuProvider context={context}>{children}</ZudokuProvider>
20
+ </QueryClientProvider>
21
+ );
22
+
23
+ return { context, wrapper };
24
+ };
25
+
26
+ const locationData = {
27
+ pathname: "/test",
28
+ hash: "",
29
+ search: "",
30
+ key: "",
31
+ state: {},
32
+ } satisfies Location;
33
+
34
+ describe("useEvent", () => {
35
+ it("returns latest event data without callback", async () => {
36
+ const { context, wrapper } = createTestContext();
37
+ const { result } = renderHook(() => useEvent("location"), { wrapper });
38
+
39
+ await act(() => Promise.resolve());
40
+ await act(async () => {
41
+ context.emitEvent("location", { to: locationData });
42
+ });
43
+
44
+ expect(result.current).toEqual([{ to: locationData }]);
45
+ });
46
+
47
+ it("transforms event data with callback", async () => {
48
+ const { context, wrapper } = createTestContext();
49
+ const { result } = renderHook(
50
+ () => useEvent("location", ({ to }) => to.pathname),
51
+ { wrapper },
52
+ );
53
+
54
+ await act(() => Promise.resolve());
55
+ await act(async () => {
56
+ context.emitEvent("location", { to: locationData });
57
+ });
58
+
59
+ await waitFor(() => expect(result.current).toEqual("/test"));
60
+ });
61
+
62
+ it("handles side effects without return value", async () => {
63
+ const { context, wrapper } = createTestContext();
64
+ const sideEffect = vi.fn();
65
+
66
+ const { result } = renderHook(
67
+ () =>
68
+ useEvent("location", (event) => {
69
+ sideEffect(event);
70
+ }),
71
+ { wrapper },
72
+ );
73
+
74
+ await act(() => Promise.resolve());
75
+ await act(async () => {
76
+ context.emitEvent("location", { to: locationData });
77
+ });
78
+
79
+ expect(result.current).toBeUndefined();
80
+ expect(sideEffect).toHaveBeenCalledWith({ to: locationData });
81
+ expect(sideEffect).toHaveBeenCalledTimes(1);
82
+ });
83
+
84
+ it("removes event listener on cleanup", async () => {
85
+ const { context, wrapper } = createTestContext();
86
+ const sideEffect = vi.fn();
87
+
88
+ const { unmount } = renderHook(
89
+ () =>
90
+ useEvent("location", (event) => {
91
+ sideEffect(event);
92
+ }),
93
+ { wrapper },
94
+ );
95
+
96
+ await act(() => Promise.resolve());
97
+
98
+ // First event emission
99
+ await act(async () => {
100
+ context.emitEvent("location", { to: locationData });
101
+ });
102
+ expect(sideEffect).toHaveBeenCalledTimes(1);
103
+
104
+ // Unmount the hook
105
+ unmount();
106
+
107
+ // Second event emission after unmount
108
+ await act(async () => {
109
+ context.emitEvent("location", { to: locationData });
110
+ });
111
+
112
+ // The callback should not have been called again
113
+ expect(sideEffect).toHaveBeenCalledTimes(1);
114
+ });
115
+
116
+ describe("types", () => {
117
+ const { wrapper } = createTestContext();
118
+
119
+ it("infers event type when no callback is provided", () => {
120
+ const hook = renderHook(() => useEvent("location"), { wrapper });
121
+ assertType<Parameters<ZudokuEvents["location"]> | undefined>(
122
+ hook.result.current,
123
+ );
124
+ });
125
+
126
+ it("infers string type from pathname callback", () => {
127
+ const hook = renderHook(
128
+ () => useEvent("location", ({ to }) => to.pathname),
129
+ { wrapper },
130
+ );
131
+ assertType<string>(hook.result.current);
132
+ });
133
+
134
+ it("infers object type from object callback", () => {
135
+ const hook = renderHook(
136
+ () => useEvent("location", ({ to }) => ({ query: to.search })),
137
+ { wrapper },
138
+ );
139
+ assertType<{ query: string }>(hook.result.current);
140
+ });
141
+
142
+ it("infers void type from empty callback", () => {
143
+ const hook = renderHook(() => useEvent("location", () => {}), {
144
+ wrapper,
145
+ });
146
+ assertType<void>(hook.result.current);
147
+ });
148
+ });
149
+ });
@@ -0,0 +1,41 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useZudoku } from "../components/context/ZudokuContext.js";
3
+ import type { ZudokuEvents } from "../core/ZudokuContext.js";
4
+
5
+ type EventParameters<Event extends keyof ZudokuEvents> = Parameters<
6
+ ZudokuEvents[Event]
7
+ >;
8
+
9
+ /**
10
+ * Hook to subscribe to Zudoku events with automatic cleanup
11
+ * @param event The event to subscribe to
12
+ * @param callback Optional callback to be called when the event is emitted
13
+ * @returns The latest event data if no callback is provided, or the callback's return value if it returns something
14
+ */
15
+ export function useEvent<E extends keyof ZudokuEvents>(
16
+ event: E,
17
+ ): EventParameters<E>;
18
+ export function useEvent<E extends keyof ZudokuEvents, R>(
19
+ event: E,
20
+ callback: (...args: EventParameters<E>) => R,
21
+ ): R;
22
+ export function useEvent<E extends keyof ZudokuEvents, R>(
23
+ event: E,
24
+ callback?: (...args: EventParameters<E>) => R,
25
+ ) {
26
+ const zudoku = useZudoku();
27
+ const [latestData, setLatestData] = useState<R | EventParameters<E>>();
28
+
29
+ useEffect(() => {
30
+ return zudoku.addEventListener(event, ((...args: EventParameters<E>) => {
31
+ if (callback) {
32
+ const result = callback(...args);
33
+ setLatestData(result);
34
+ } else {
35
+ setLatestData(args);
36
+ }
37
+ }) as ZudokuEvents[E]);
38
+ }, [zudoku, event, callback]);
39
+
40
+ return latestData;
41
+ }
@@ -178,7 +178,7 @@ export const Sidecar = ({
178
178
  >
179
179
  <SidecarBox.Root>
180
180
  <SidecarBox.Head className="flex justify-between items-center flex-nowrap py-2.5 gap-2 text-xs">
181
- <span className="font-mono break-words">
181
+ <span className="font-mono break-words leading-6">
182
182
  <span className={cn("font-semibold", methodTextColor)}>
183
183
  {operation.method.toLocaleUpperCase()}
184
184
  </span>
@@ -0,0 +1,43 @@
1
+ @tailwind components;
2
+
3
+ @layer components {
4
+ .stepper {
5
+ /* @apply mb-6; */
6
+ }
7
+
8
+ .stepper > ol {
9
+ --bullet-size: 1.75rem;
10
+ --line-spacing: 0.25rem;
11
+ @apply flex flex-col list-none p-0 m-0;
12
+ counter-reset: step-counter;
13
+ }
14
+
15
+ .stepper > ol > li {
16
+ @apply relative ps-12 pb-6 my-0;
17
+ counter-increment: step-counter;
18
+ }
19
+
20
+ .stepper > ol > li:last-child {
21
+ @apply pb-0;
22
+ }
23
+
24
+ /* Bullet with number */
25
+ .stepper > ol > li::before {
26
+ @apply absolute left-0 flex items-center justify-center size-[--bullet-size];
27
+ @apply bg-muted/80 border border-border text-muted-foreground text-[calc(var(--bullet-size)/2)] font-semibold rounded-full;
28
+ content: counter(step-counter);
29
+ }
30
+
31
+ /* Vertical line */
32
+ .stepper > ol > li::after {
33
+ @apply absolute content-[''] w-[2px] bg-border -translate-x-1/2;
34
+ left: calc(var(--bullet-size) / 2);
35
+ top: calc(var(--bullet-size) + var(--line-spacing));
36
+ height: calc(100% - var(--bullet-size) - (2 * var(--line-spacing)));
37
+ }
38
+
39
+ .stepper > ol > li > :first-child {
40
+ @apply mt-0 pt-0;
41
+ transform: translateY(calc((var(--bullet-size) - 1lh) / 2));
42
+ }
43
+ }
@@ -0,0 +1,8 @@
1
+ import type { PropsWithChildren } from "react";
2
+ import "./Stepper.css";
3
+
4
+ const Stepper = ({ children }: PropsWithChildren) => {
5
+ return <div className="stepper">{children}</div>;
6
+ };
7
+
8
+ export { Stepper };
@@ -1,8 +1,9 @@
1
- import { MDXComponents } from "mdx/types.js";
1
+ import { type MDXComponents } from "mdx/types.js";
2
2
  import { Link } from "react-router";
3
3
  import { Heading } from "../components/Heading.js";
4
4
  import { InlineCode } from "../components/InlineCode.js";
5
5
  import { Callout } from "../ui/Callout.js";
6
+ import { Stepper } from "../ui/Stepper.js";
6
7
  import { SyntaxHighlight } from "../ui/SyntaxHighlight.js";
7
8
 
8
9
  export type MdxComponentsType = Readonly<MDXComponents> | null | undefined;
@@ -51,6 +52,8 @@ export const MdxComponents = {
51
52
  <a href={href} target="_blank" {...props} rel="noreferrer" />
52
53
  ),
53
54
  Callout,
55
+ Stepper,
56
+ SyntaxHighlight,
54
57
  tip: (props) => <Callout type="tip" {...props} />,
55
58
  info: (props) => <Callout type="info" {...props} />,
56
59
  note: (props) => <Callout type="note" {...props} />,