zudoku 0.3.1-dev.1 → 0.3.1-dev.11

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 (55) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/lib/plugins/openapi/OperationList.js +3 -4
  3. package/dist/lib/plugins/openapi/OperationList.js.map +1 -1
  4. package/dist/lib/plugins/openapi/OperationListItem.js +2 -3
  5. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  6. package/dist/lib/plugins/openapi/ParameterListItem.js +1 -1
  7. package/dist/lib/plugins/openapi/ParameterListItem.js.map +1 -1
  8. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js +2 -2
  9. package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
  10. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.d.ts +9 -0
  11. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.js +14 -0
  12. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.js.map +1 -0
  13. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.d.ts +6 -0
  14. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.js +17 -0
  15. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.js.map +1 -0
  16. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.d.ts +7 -0
  17. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.js +10 -0
  18. package/dist/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.js.map +1 -0
  19. package/dist/lib/plugins/openapi/schema/SchemaComponents.d.ts +3 -3
  20. package/dist/lib/plugins/openapi/schema/SchemaComponents.js +15 -15
  21. package/dist/lib/plugins/openapi/schema/SchemaComponents.js.map +1 -1
  22. package/dist/lib/plugins/openapi/schema/SchemaView.js +1 -1
  23. package/dist/lib/plugins/openapi/schema/SchemaView.js.map +1 -1
  24. package/dist/lib/plugins/openapi/schema/utils.d.ts +6 -0
  25. package/dist/lib/plugins/openapi/schema/utils.js +5 -0
  26. package/dist/lib/plugins/openapi/schema/utils.js.map +1 -1
  27. package/lib/{Input-DB9VROFR.js → Input-CzXNm7xb.js} +2 -1
  28. package/lib/{Input-DB9VROFR.js.map → Input-CzXNm7xb.js.map} +1 -1
  29. package/lib/OperationList-CYyaboNz.js +589 -0
  30. package/lib/OperationList-CYyaboNz.js.map +1 -0
  31. package/lib/{Route-DfAFiR7v.js → Route-C3Jb0axy.js} +2 -2
  32. package/lib/{Route-DfAFiR7v.js.map → Route-C3Jb0axy.js.map} +1 -1
  33. package/lib/{index-D-9zqIOh.js → index-B1he6g8N.js} +532 -514
  34. package/lib/index-B1he6g8N.js.map +1 -0
  35. package/lib/zudoku.plugin-api-keys.js +1 -1
  36. package/lib/zudoku.plugin-openapi.js +1 -1
  37. package/package.json +79 -99
  38. package/src/app/main.css +26 -1
  39. package/src/lib/plugins/openapi/OperationList.tsx +3 -7
  40. package/src/lib/plugins/openapi/OperationListItem.tsx +3 -4
  41. package/src/lib/plugins/openapi/ParameterListItem.tsx +1 -1
  42. package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +27 -5
  43. package/src/lib/plugins/openapi/schema/LogicalGroup/LogicalGroup.tsx +47 -0
  44. package/src/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupConnector.tsx +54 -0
  45. package/src/lib/plugins/openapi/schema/LogicalGroup/LogicalGroupItem.tsx +30 -0
  46. package/src/lib/plugins/openapi/schema/SchemaComponents.tsx +41 -41
  47. package/src/lib/plugins/openapi/schema/SchemaView.tsx +4 -4
  48. package/src/lib/plugins/openapi/schema/utils.ts +8 -0
  49. package/dist/lib/plugins/openapi/util/prose.d.ts +0 -1
  50. package/dist/lib/plugins/openapi/util/prose.js +0 -4
  51. package/dist/lib/plugins/openapi/util/prose.js.map +0 -1
  52. package/lib/OperationList-Cxiw2Z-v.js +0 -457
  53. package/lib/OperationList-Cxiw2Z-v.js.map +0 -1
  54. package/lib/index-D-9zqIOh.js.map +0 -1
  55. package/src/lib/plugins/openapi/util/prose.ts +0 -7
@@ -1,6 +1,6 @@
1
1
  import { j as e } from "./jsx-runtime-B6kdoens.js";
2
2
  import { S as p, R as f } from "./SlotletProvider-ByLSCZQa.js";
3
- import { u as g, a as u, I as j, S as k, b as v, c as w, d as b, e as K, f as y } from "./Input-DB9VROFR.js";
3
+ import { u as g, a as u, I as j, S as k, b as v, c as w, d as b, e as K, f as y } from "./Input-CzXNm7xb.js";
4
4
  import { b as N, L as x, O as E } from "./index-7kcHaXD6.js";
5
5
  import { u as h, t as A, j as S } from "./ZudokuContext-BIZ8zHbZ.js";
6
6
  import { B as l, p as I } from "./Combination-DTfV-c98.js";
@@ -1,5 +1,5 @@
1
1
  import "./jsx-runtime-B6kdoens.js";
2
- import { o as l } from "./index-D-9zqIOh.js";
2
+ import { o as l } from "./index-B1he6g8N.js";
3
3
  import "./urql-DrBfkb92.js";
4
4
  import "./ZudokuContext-BIZ8zHbZ.js";
5
5
  import "zudoku/openapi-worker";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.3.1-dev.1",
3
+ "version": "0.3.1-dev.11",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -13,104 +13,73 @@
13
13
  "zudoku": "./cli.js"
14
14
  },
15
15
  "exports": {
16
- ".": "./src/index.ts",
17
- "./internal": "./src/internal.ts",
18
- "./auth/clerk": "./src/lib/authentication/providers/clerk.ts",
19
- "./auth/auth0": "./src/lib/authentication/providers/auth0.ts",
20
- "./auth/openid": "./src/lib/authentication/providers/openid.ts",
21
- "./plugins/api-keys": "./src/lib/plugins/api-keys/index.ts",
22
- "./plugins/markdown": "./src/lib/plugins/markdown/index.ts",
23
- "./plugins/openapi": "./src/lib/plugins/openapi/index.ts",
24
- "./plugins/redirect": "./src/lib/plugins/redirect/index.ts",
25
- "./plugins/custom-page": "./src/lib/plugins/custom-page/index.ts",
26
- "./plugins/search-inkeep": "./src/lib/plugins/search-inkeep/index.ts",
27
- "./openapi-worker": "./src/lib/plugins/openapi-worker.ts",
28
- "./components": "./src/lib/components/index.ts",
29
- "./vite": "./src/vite/plugin.ts",
30
- "./tailwind": "./src/app/tailwind.ts",
31
- "./app/*": "./src/app/*"
32
- },
33
- "publishConfig": {
34
- "module": "./dist/index.js",
35
- "types": "./dist/index.d.ts",
36
- "exports": {
37
- ".": {
38
- "import": "./dist/index.js",
39
- "types": "./dist/index.d.ts"
40
- },
41
- "./internal": {
42
- "import": "./dist/internal.js"
43
- },
44
- "./auth/clerk": {
45
- "import": "./lib/zudoku.auth-clerk.js",
46
- "types": "./dist/lib/authentication/providers/clerk.d.ts"
47
- },
48
- "./auth/auth0": {
49
- "import": "./lib/zudoku.auth-auth0.js",
50
- "types": "./dist/lib/authentication/providers/auth0.d.ts"
51
- },
52
- "./auth/openid": {
53
- "import": "./lib/zudoku.auth-openid.js",
54
- "types": "./dist/lib/authentication/providers/openid.d.ts"
55
- },
56
- "./plugins/api-keys": {
57
- "import": "./lib/zudoku.plugin-api-keys.js",
58
- "types": "./dist/lib/plugins/api-keys/index.d.ts"
59
- },
60
- "./plugins/markdown": {
61
- "import": "./lib/zudoku.plugin-markdown.js",
62
- "types": "./dist/lib/plugins/markdown/index.d.ts"
63
- },
64
- "./plugins/openapi": {
65
- "import": "./lib/zudoku.plugin-openapi.js",
66
- "types": "./dist/lib/plugins/openapi/index.d.ts"
67
- },
68
- "./plugins/redirect": {
69
- "import": "./lib/zudoku.plugin-redirect.js",
70
- "types": "./dist/lib/plugins/redirect/index.d.ts"
71
- },
72
- "./plugins/custom-page": {
73
- "import": "./lib/zudoku.plugin-custom-page.js",
74
- "types": "./dist/lib/plugins/custom-page/index.d.ts"
75
- },
76
- "./plugins/search-inkeep": {
77
- "import": "./lib/zudoku.plugin-search-inkeep.js",
78
- "types": "./dist/lib/plugins/search-inkeep/index.d.ts"
79
- },
80
- "./openapi-worker": {
81
- "import": "./lib/zudoku.openapi-worker.js",
82
- "types": "./dist/lib/plugins/openapi-worker.d.ts"
83
- },
84
- "./components": {
85
- "import": "./lib/zudoku.components.js",
86
- "types": "./dist/lib/components/index.d.ts"
87
- },
88
- "./vite": {
89
- "require": "./dist/vite/plugin.js",
90
- "import": "./dist/vite/plugin.js"
91
- },
92
- "./tailwind": {
93
- "require": "./dist/app/tailwind.js",
94
- "import": "./dist/app/tailwind.js"
95
- },
96
- "./main.css": {
97
- "require": "./src/app/main.css",
98
- "import": "./src/app/main.css"
99
- },
100
- "./app/*": {
101
- "import": "./src/app/*"
102
- }
16
+ ".": {
17
+ "import": "./dist/index.js",
18
+ "types": "./dist/index.d.ts"
19
+ },
20
+ "./internal": {
21
+ "import": "./dist/internal.js"
22
+ },
23
+ "./auth/clerk": {
24
+ "import": "./lib/zudoku.auth-clerk.js",
25
+ "types": "./dist/lib/authentication/providers/clerk.d.ts"
26
+ },
27
+ "./auth/auth0": {
28
+ "import": "./lib/zudoku.auth-auth0.js",
29
+ "types": "./dist/lib/authentication/providers/auth0.d.ts"
30
+ },
31
+ "./auth/openid": {
32
+ "import": "./lib/zudoku.auth-openid.js",
33
+ "types": "./dist/lib/authentication/providers/openid.d.ts"
34
+ },
35
+ "./plugins/api-keys": {
36
+ "import": "./lib/zudoku.plugin-api-keys.js",
37
+ "types": "./dist/lib/plugins/api-keys/index.d.ts"
38
+ },
39
+ "./plugins/markdown": {
40
+ "import": "./lib/zudoku.plugin-markdown.js",
41
+ "types": "./dist/lib/plugins/markdown/index.d.ts"
42
+ },
43
+ "./plugins/openapi": {
44
+ "import": "./lib/zudoku.plugin-openapi.js",
45
+ "types": "./dist/lib/plugins/openapi/index.d.ts"
46
+ },
47
+ "./plugins/redirect": {
48
+ "import": "./lib/zudoku.plugin-redirect.js",
49
+ "types": "./dist/lib/plugins/redirect/index.d.ts"
50
+ },
51
+ "./plugins/custom-page": {
52
+ "import": "./lib/zudoku.plugin-custom-page.js",
53
+ "types": "./dist/lib/plugins/custom-page/index.d.ts"
54
+ },
55
+ "./plugins/search-inkeep": {
56
+ "import": "./lib/zudoku.plugin-search-inkeep.js",
57
+ "types": "./dist/lib/plugins/search-inkeep/index.d.ts"
58
+ },
59
+ "./openapi-worker": {
60
+ "import": "./lib/zudoku.openapi-worker.js",
61
+ "types": "./dist/lib/plugins/openapi-worker.d.ts"
62
+ },
63
+ "./components": {
64
+ "import": "./lib/zudoku.components.js",
65
+ "types": "./dist/lib/components/index.d.ts"
66
+ },
67
+ "./vite": {
68
+ "require": "./dist/vite/plugin.js",
69
+ "import": "./dist/vite/plugin.js"
70
+ },
71
+ "./tailwind": {
72
+ "require": "./dist/app/tailwind.js",
73
+ "import": "./dist/app/tailwind.js"
74
+ },
75
+ "./main.css": {
76
+ "require": "./src/app/main.css",
77
+ "import": "./src/app/main.css"
78
+ },
79
+ "./app/*": {
80
+ "import": "./src/app/*"
103
81
  }
104
82
  },
105
- "scripts": {
106
- "build": "tsc --project tsconfig.json",
107
- "build:vite": "vite build && pnpm run hack:fix-worker-paths lib",
108
- "build:standalone:vite": "vite build --mode standalone --config vite.standalone.config.ts",
109
- "build:standalone:html": "cp ./src/app/standalone.html ./standalone/standalone.html && cp ./src/app/demo.html ./standalone/demo.html && cp ./src/app/demo-cdn.html ./standalone/index.html",
110
- "hack:fix-worker-paths": "node ./scripts/hack-worker.mjs",
111
- "clean": "tsc --build --clean",
112
- "test": "node --test --enable-source-maps"
113
- },
114
83
  "dependencies": {
115
84
  "@envelop/core": "5.0.1",
116
85
  "@graphql-typed-document-node/core": "3.2.0",
@@ -216,5 +185,16 @@
216
185
  "optionalDependencies": {
217
186
  "@clerk/clerk-js": "5.11.0",
218
187
  "@inkeep/widgets": "^0.2.289"
219
- }
220
- }
188
+ },
189
+ "scripts": {
190
+ "build": "tsc --project tsconfig.json",
191
+ "build:vite": "vite build && pnpm run hack:fix-worker-paths lib",
192
+ "build:standalone:vite": "vite build --mode standalone --config vite.standalone.config.ts",
193
+ "build:standalone:html": "cp ./src/app/standalone.html ./standalone/standalone.html && cp ./src/app/demo.html ./standalone/demo.html && cp ./src/app/demo-cdn.html ./standalone/index.html",
194
+ "hack:fix-worker-paths": "node ./scripts/hack-worker.mjs",
195
+ "clean": "tsc --build --clean",
196
+ "test": "node --test --enable-source-maps"
197
+ },
198
+ "module": "./dist/index.js",
199
+ "types": "./dist/index.d.ts"
200
+ }
package/src/app/main.css CHANGED
@@ -192,6 +192,31 @@
192
192
  background: transparent;
193
193
  }
194
194
 
195
+ .wavy-line {
196
+ @apply bg-primary w-full;
197
+
198
+ --s: 3px; /* size of the wave */
199
+ --b: 2px; /* thickness of the line */
200
+ --m: 1; /* curvature of the wave [0 2] */
201
+
202
+ --R: calc(var(--s) * sqrt(var(--m) * var(--m) + 1) + var(--b) / 2);
203
+ height: calc(2 * var(--R));
204
+ --_g: #0000 calc(99% - var(--b)), #000 calc(101% - var(--b)) 99%, #0000 101%;
205
+ mask:
206
+ radial-gradient(
207
+ var(--R) at left 50% bottom calc(-1 * var(--m) * var(--s)),
208
+ var(--_g)
209
+ )
210
+ calc(50% - 2 * var(--s)) calc(50% - var(--s) / 2 - var(--b) / 2) /
211
+ calc(4 * var(--s)) calc(var(--s) + var(--b)) repeat-x,
212
+ radial-gradient(
213
+ var(--R) at left 50% top calc(-1 * var(--m) * var(--s)),
214
+ var(--_g)
215
+ )
216
+ 50% calc(50% + var(--s) / 2 + var(--b) / 2) / calc(4 * var(--s))
217
+ calc(var(--s) + var(--b)) repeat-x;
218
+ }
219
+
195
220
  /* Theme */
196
221
  :root {
197
222
  --background: 0 0% 100%;
@@ -224,7 +249,7 @@
224
249
  --popover: 222.2 84% 4.9%;
225
250
  --popover-foreground: 210 40% 98%;
226
251
  --primary: 217.2 91.2% 59.8%;
227
- --primary-foreground: 222.2 47.4% 11.2%;
252
+ --primary-foreground: 210 40% 98%;
228
253
  --secondary: 217.2 32.6% 17.5%;
229
254
  --secondary-foreground: 210 40% 98%;
230
255
  --muted: 217.2 32.6% 17.5%;
@@ -4,14 +4,13 @@ import { DeveloperHint } from "../../components/DeveloperHint.js";
4
4
  import { ErrorPage } from "../../components/ErrorPage.js";
5
5
  import { Heading } from "../../components/Heading.js";
6
6
  import { InlineCode } from "../../components/InlineCode.js";
7
- import { Markdown } from "../../components/Markdown.js";
7
+ import { Markdown, ProseClasses } from "../../components/Markdown.js";
8
8
  import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
9
9
  import { cn } from "../../util/cn.js";
10
10
  import { OperationListItem } from "./OperationListItem.js";
11
11
  import StaggeredRender from "./StaggeredRender.js";
12
12
  import { useOasConfig } from "./context.js";
13
13
  import { graphql } from "./graphql/index.js";
14
- import { SchemaProseClasses } from "./util/prose.js";
15
14
  import { useQuery } from "./util/urql.js";
16
15
 
17
16
  export const OperationsFragment = graphql(/* GraphQL */ `
@@ -124,10 +123,7 @@ export const OperationList = () => {
124
123
  return (
125
124
  <div className="pt-[--padding-content-top]">
126
125
  <div
127
- className={cn(
128
- SchemaProseClasses,
129
- "mb-16 max-w-full prose-img:max-w-prose",
130
- )}
126
+ className={cn(ProseClasses, "mb-16 max-w-full prose-img:max-w-prose")}
131
127
  >
132
128
  <CategoryHeading>Overview</CategoryHeading>
133
129
  <Heading level={1} id="description" registerSidebarAnchor>
@@ -142,7 +138,7 @@ export const OperationList = () => {
142
138
  {tag.name && <CategoryHeading>{tag.name}</CategoryHeading>}
143
139
  {tag.description && (
144
140
  <Markdown
145
- className={`${SchemaProseClasses} mt-2 mb-12`}
141
+ className={`${ProseClasses} max-w-full prose-img:max-w-prose w-full mt-2 mb-12`}
146
142
  content={tag.description}
147
143
  />
148
144
  )}
@@ -1,6 +1,6 @@
1
1
  import { useState } from "react";
2
2
  import { Heading } from "../../components/Heading.js";
3
- import { Markdown } from "../../components/Markdown.js";
3
+ import { Markdown, ProseClasses } from "../../components/Markdown.js";
4
4
  import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../ui/Tabs.js";
5
5
  import { groupBy } from "../../util/groupBy.js";
6
6
  import { renderIf } from "../../util/renderIf.js";
@@ -9,7 +9,6 @@ import { ParameterList } from "./ParameterList.js";
9
9
  import { Sidecar } from "./Sidecar.js";
10
10
  import { FragmentType, useFragment } from "./graphql/index.js";
11
11
  import { SchemaView } from "./schema/SchemaView.js";
12
- import { SchemaProseClasses } from "./util/prose.js";
13
12
 
14
13
  export const PARAM_GROUPS = ["path", "query", "header", "cookie"] as const;
15
14
  export type ParameterGroup = (typeof PARAM_GROUPS)[number];
@@ -39,7 +38,7 @@ export const OperationListItem = ({
39
38
  </Heading>
40
39
  {operation.description && (
41
40
  <Markdown
42
- className={SchemaProseClasses}
41
+ className={`${ProseClasses} max-w-full prose-img:max-w-prose`}
43
42
  content={operation.description}
44
43
  />
45
44
  )}
@@ -89,7 +88,7 @@ export const OperationListItem = ({
89
88
  ))}
90
89
  </TabsList>
91
90
  )}
92
- <ul className="list-none m-0 px-0 overflow-hidden">
91
+ <ul className="list-none m-0 px-0">
93
92
  {operation.responses.map((response) => (
94
93
  <TabsContent
95
94
  value={response.statusCode}
@@ -55,7 +55,7 @@ export const ParameterListItem = ({
55
55
  {parameter.description && (
56
56
  <Markdown
57
57
  content={parameter.description}
58
- className="text-sm prose-p:my-1"
58
+ className="text-sm prose-p:my-1 prose-code:whitespace-pre-line"
59
59
  />
60
60
  )}
61
61
  </li>
@@ -1,5 +1,4 @@
1
1
  import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
2
- import { CirclePlayIcon } from "lucide-react";
3
2
  import { type PropsWithChildren, useState } from "react";
4
3
  import {
5
4
  Dialog,
@@ -11,16 +10,39 @@ import { Playground, type PlaygroundContentProps } from "./Playground.js";
11
10
 
12
11
  export type PlaygroundDialogProps = PropsWithChildren<PlaygroundContentProps>;
13
12
 
13
+ const HeroPlayIcon = ({
14
+ className,
15
+ size = 16,
16
+ }: {
17
+ className?: string;
18
+ size?: number;
19
+ }) => (
20
+ <svg
21
+ xmlns="http://www.w3.org/2000/svg"
22
+ viewBox="0 0 24 24"
23
+ fill="currentColor"
24
+ className={className}
25
+ width={size}
26
+ height={size}
27
+ >
28
+ <path
29
+ fillRule="evenodd"
30
+ d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm14.024-.983a1.125 1.125 0 0 1 0 1.966l-5.603 3.113A1.125 1.125 0 0 1 9 15.113V8.887c0-.857.921-1.4 1.671-.983l5.603 3.113Z"
31
+ clipRule="evenodd"
32
+ />
33
+ </svg>
34
+ );
35
+
14
36
  const PlaygroundDialog = (props: PlaygroundDialogProps) => {
15
37
  const [open, setOpen] = useState(false);
16
38
  return (
17
39
  <Dialog onOpenChange={(open) => setOpen(open)}>
18
40
  <DialogTrigger asChild>
19
41
  {props.children ?? (
20
- <CirclePlayIcon
21
- className="cursor-pointer text-primary hover:text-primary/80"
22
- size={16}
23
- />
42
+ <button className="flex gap-1 items-center px-2 py-1 rounded-md bg-primary/80 hover:bg-primary transition text-primary-foreground text-xs">
43
+ Test
44
+ <HeroPlayIcon className="" size={14} />
45
+ </button>
24
46
  )}
25
47
  </DialogTrigger>
26
48
 
@@ -0,0 +1,47 @@
1
+ import * as Collapsible from "@radix-ui/react-collapsible";
2
+ import { SquareMinusIcon, SquarePlusIcon } from "lucide-react";
3
+ import type { SchemaObject } from "../../../../oas/parser/index.js";
4
+ import { Card } from "../../../../ui/Card.js";
5
+ import type { LogicalGroupType } from "../utils.js";
6
+ import { LogicalGroupItem } from "./LogicalGroupItem.js";
7
+
8
+ const typeLabel = {
9
+ AND: "All of",
10
+ OR: "Any of",
11
+ ONE: "One of",
12
+ };
13
+
14
+ export const LogicalGroup = ({
15
+ schemas,
16
+ type,
17
+ isOpen,
18
+ level,
19
+ toggleOpen,
20
+ }: {
21
+ schemas: SchemaObject[];
22
+ type: LogicalGroupType;
23
+ isOpen: boolean;
24
+ toggleOpen: () => void;
25
+ level: number;
26
+ }) => (
27
+ <Collapsible.Root open={isOpen} onOpenChange={toggleOpen} asChild>
28
+ <Card className="px-6">
29
+ <Collapsible.Trigger className="flex gap-2 items-center py-2 w-full text-sm text-muted-foreground -translate-x-1.5">
30
+ {isOpen ? <SquareMinusIcon size={14} /> : <SquarePlusIcon size={14} />}
31
+ <span>{typeLabel[type]}</span>
32
+ </Collapsible.Trigger>
33
+
34
+ <Collapsible.Content className="pb-4">
35
+ {schemas.map((subSchema, index) => (
36
+ // eslint-disable-next-line react/no-array-index-key
37
+ <LogicalGroupItem
38
+ key={index}
39
+ type={type}
40
+ schema={subSchema}
41
+ level={level}
42
+ />
43
+ ))}
44
+ </Collapsible.Content>
45
+ </Card>
46
+ </Collapsible.Root>
47
+ );
@@ -0,0 +1,54 @@
1
+ import {
2
+ ChevronDownIcon,
3
+ CircleDotIcon,
4
+ CircleFadingPlusIcon,
5
+ CircleIcon,
6
+ } from "lucide-react";
7
+ import { cn } from "../../../../util/cn.js";
8
+
9
+ import type { LogicalGroupType } from "../utils.js";
10
+
11
+ const iconMap = {
12
+ AND: <CircleFadingPlusIcon size={16} className="fill-card" />,
13
+ OR: <CircleDotIcon size={16} className="fill-card" />,
14
+ ONE: <CircleIcon size={14} className="fill-card" />,
15
+ } as const;
16
+
17
+ const colorClass = {
18
+ AND: "text-green-500 dark:text-green-300/60",
19
+ OR: "text-blue-400 dark:text-blue-500",
20
+ ONE: "text-purple-500 dark:text-purple-300/60",
21
+ } as const;
22
+
23
+ export const LogicalGroupConnector = ({
24
+ type,
25
+ isOpen,
26
+ className,
27
+ }: {
28
+ type: LogicalGroupType;
29
+ isOpen: boolean;
30
+ className?: string;
31
+ }) => {
32
+ return (
33
+ <div
34
+ className={cn(
35
+ colorClass[type],
36
+ "relative text-sm flex py-2",
37
+ "before:border-l before:absolute before:-top-2 before:-bottom-2 before:border-border before:border-dashed before:content-['']",
38
+ className,
39
+ )}
40
+ >
41
+ <div className="-translate-x-[7px] flex gap-1 items-center">
42
+ {iconMap[type]}
43
+ <div
44
+ className={cn(
45
+ "translate-y-px mx-px opacity-0 group-hover:opacity-100 transition",
46
+ !isOpen && "-rotate-90",
47
+ )}
48
+ >
49
+ <ChevronDownIcon size={16} />
50
+ </div>
51
+ </div>
52
+ </div>
53
+ );
54
+ };
@@ -0,0 +1,30 @@
1
+ import * as Collapsible from "@radix-ui/react-collapsible";
2
+ import { useState } from "react";
3
+ import type { SchemaObject } from "../../../../oas/parser/index.js";
4
+ import { SchemaView } from "../SchemaView.js";
5
+ import type { LogicalGroupType } from "../utils.js";
6
+ import { LogicalGroupConnector } from "./LogicalGroupConnector.js";
7
+
8
+ export const LogicalGroupItem = (props: {
9
+ type: LogicalGroupType;
10
+ schema: SchemaObject;
11
+ level: number;
12
+ }) => {
13
+ const [isOpen, setIsOpen] = useState(true);
14
+
15
+ return (
16
+ <Collapsible.Root
17
+ open={isOpen}
18
+ onOpenChange={() => setIsOpen((prev) => !prev)}
19
+ className="group"
20
+ >
21
+ <Collapsible.Trigger>
22
+ <LogicalGroupConnector type={props.type} isOpen={isOpen} />
23
+ </Collapsible.Trigger>
24
+ {!isOpen && <div className="wavy-line bg-border translate-y-1" />}
25
+ <Collapsible.Content>
26
+ <SchemaView schema={props.schema} level={props.level + 1} />
27
+ </Collapsible.Content>
28
+ </Collapsible.Root>
29
+ );
30
+ };