@health-samurai/react-components 0.0.0-alpha.5 → 0.0.0-alpha.7
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/dist/bundle.css +318 -31
- package/dist/src/components/button-dropdown.d.ts +10 -0
- package/dist/src/components/button-dropdown.d.ts.map +1 -0
- package/dist/src/components/button-dropdown.js +70 -0
- package/dist/src/components/button-dropdown.js.map +1 -0
- package/dist/src/components/button-dropdown.stories.d.ts +11 -0
- package/dist/src/components/button-dropdown.stories.d.ts.map +1 -0
- package/dist/src/components/button-dropdown.stories.js +48 -0
- package/dist/src/components/button-dropdown.stories.js.map +1 -0
- package/dist/src/components/code-editor/index.d.ts +3 -2
- package/dist/src/components/code-editor/index.d.ts.map +1 -1
- package/dist/src/components/code-editor/index.js +152 -4
- package/dist/src/components/code-editor/index.js.map +1 -1
- package/dist/src/components/code-editor.stories.d.ts +1 -0
- package/dist/src/components/code-editor.stories.d.ts.map +1 -1
- package/dist/src/components/code-editor.stories.js +252 -1
- package/dist/src/components/code-editor.stories.js.map +1 -1
- package/dist/src/components/copy-icon.d.ts +5 -1
- package/dist/src/components/copy-icon.d.ts.map +1 -1
- package/dist/src/components/copy-icon.js +41 -3
- package/dist/src/components/copy-icon.js.map +1 -1
- package/dist/src/components/data-table.d.ts +9 -0
- package/dist/src/components/data-table.d.ts.map +1 -0
- package/dist/src/components/data-table.js +66 -0
- package/dist/src/components/data-table.js.map +1 -0
- package/dist/src/components/data-table.stories.d.ts +7 -0
- package/dist/src/components/data-table.stories.d.ts.map +1 -0
- package/dist/src/components/data-table.stories.js +240 -0
- package/dist/src/components/data-table.stories.js.map +1 -0
- package/dist/src/components/fhir-structure-view.d.ts +34 -0
- package/dist/src/components/fhir-structure-view.d.ts.map +1 -0
- package/dist/src/components/fhir-structure-view.js +226 -0
- package/dist/src/components/fhir-structure-view.js.map +1 -0
- package/dist/src/components/fhir-structure-view.stories.d.ts +7 -0
- package/dist/src/components/fhir-structure-view.stories.d.ts.map +1 -0
- package/dist/src/components/fhir-structure-view.stories.js +447 -0
- package/dist/src/components/fhir-structure-view.stories.js.map +1 -0
- package/dist/src/components/request-line-editor.d.ts +3 -1
- package/dist/src/components/request-line-editor.d.ts.map +1 -1
- package/dist/src/components/request-line-editor.js +26 -5
- package/dist/src/components/request-line-editor.js.map +1 -1
- package/dist/src/components/segment-control.d.ts +16 -0
- package/dist/src/components/segment-control.d.ts.map +1 -0
- package/dist/src/components/segment-control.js +48 -0
- package/dist/src/components/segment-control.js.map +1 -0
- package/dist/src/components/segment-control.stories.d.ts +15 -0
- package/dist/src/components/segment-control.stories.d.ts.map +1 -0
- package/dist/src/components/segment-control.stories.js +33 -0
- package/dist/src/components/segment-control.stories.js.map +1 -0
- package/dist/src/components/split-button.d.ts +5 -0
- package/dist/src/components/split-button.d.ts.map +1 -0
- package/dist/src/components/split-button.js +12 -0
- package/dist/src/components/split-button.js.map +1 -0
- package/dist/src/components/split-button.stories.d.ts +7 -0
- package/dist/src/components/split-button.stories.d.ts.map +1 -0
- package/dist/src/components/split-button.stories.js +57 -0
- package/dist/src/components/split-button.stories.js.map +1 -0
- package/dist/src/components/tree-view.d.ts +16 -7
- package/dist/src/components/tree-view.d.ts.map +1 -1
- package/dist/src/components/tree-view.js +75 -19
- package/dist/src/components/tree-view.js.map +1 -1
- package/dist/src/components/tree-view.stories.d.ts +3 -3
- package/dist/src/components/tree-view.stories.d.ts.map +1 -1
- package/dist/src/components/tree-view.stories.js +14 -5
- package/dist/src/components/tree-view.stories.js.map +1 -1
- package/dist/src/icons.d.ts +6 -0
- package/dist/src/icons.d.ts.map +1 -1
- package/dist/src/icons.js +235 -3
- package/dist/src/icons.js.map +1 -1
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/shadcn/components/ui/alert-dialog.d.ts +3 -1
- package/dist/src/shadcn/components/ui/alert-dialog.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/alert-dialog.js +5 -2
- package/dist/src/shadcn/components/ui/alert-dialog.js.map +1 -1
- package/dist/src/shadcn/components/ui/badge.d.ts +1 -1
- package/dist/src/shadcn/components/ui/card.d.ts +5 -1
- package/dist/src/shadcn/components/ui/card.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/card.js +21 -8
- package/dist/src/shadcn/components/ui/card.js.map +1 -1
- package/dist/src/shadcn/components/ui/card.stories.d.ts +302 -1
- package/dist/src/shadcn/components/ui/card.stories.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/card.stories.js +23 -2
- package/dist/src/shadcn/components/ui/card.stories.js.map +1 -1
- package/dist/src/shadcn/components/ui/combobox.d.ts +13 -0
- package/dist/src/shadcn/components/ui/combobox.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/combobox.js +102 -0
- package/dist/src/shadcn/components/ui/combobox.js.map +1 -1
- package/dist/src/shadcn/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/dropdown-menu.js +1 -1
- package/dist/src/shadcn/components/ui/dropdown-menu.js.map +1 -1
- package/dist/src/shadcn/components/ui/input.d.ts +3 -1
- package/dist/src/shadcn/components/ui/input.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/input.js +39 -1
- package/dist/src/shadcn/components/ui/input.js.map +1 -1
- package/dist/src/shadcn/components/ui/pagination.d.ts +8 -1
- package/dist/src/shadcn/components/ui/pagination.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/pagination.js +36 -19
- package/dist/src/shadcn/components/ui/pagination.js.map +1 -1
- package/dist/src/shadcn/components/ui/pagination.stories.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/pagination.stories.js +44 -37
- package/dist/src/shadcn/components/ui/pagination.stories.js.map +1 -1
- package/dist/src/shadcn/components/ui/table.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/table.js +1 -1
- package/dist/src/shadcn/components/ui/table.js.map +1 -1
- package/dist/src/shadcn/components/ui/tabs.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/tabs.js +1 -0
- package/dist/src/shadcn/components/ui/tabs.js.map +1 -1
- package/dist/src/shadcn/components/ui/tree.d.ts +10 -2
- package/dist/src/shadcn/components/ui/tree.d.ts.map +1 -1
- package/dist/src/shadcn/components/ui/tree.js +31 -8
- package/dist/src/shadcn/components/ui/tree.js.map +1 -1
- package/dist/src/typography.css +36 -8
- package/package.json +5 -1
- package/src/components/button-dropdown.stories.tsx +41 -0
- package/src/components/button-dropdown.tsx +95 -0
- package/src/components/code-editor/index.tsx +129 -4
- package/src/components/code-editor.stories.tsx +294 -0
- package/src/components/copy-icon.tsx +57 -3
- package/src/components/data-table.stories.tsx +89 -0
- package/src/components/data-table.tsx +120 -0
- package/src/components/fhir-structure-view.stories.tsx +439 -0
- package/src/components/fhir-structure-view.tsx +229 -0
- package/src/components/request-line-editor.tsx +30 -4
- package/src/components/segment-control.stories.tsx +29 -0
- package/src/components/segment-control.tsx +81 -0
- package/src/components/split-button.stories.tsx +49 -0
- package/src/components/split-button.tsx +17 -0
- package/src/components/tree-view.stories.tsx +20 -15
- package/src/components/tree-view.tsx +118 -15
- package/src/icons.tsx +245 -3
- package/src/index.tsx +10 -2
- package/src/shadcn/components/ui/alert-dialog.tsx +6 -2
- package/src/shadcn/components/ui/card.stories.tsx +17 -3
- package/src/shadcn/components/ui/card.tsx +52 -8
- package/src/shadcn/components/ui/combobox.tsx +127 -0
- package/src/shadcn/components/ui/dropdown-menu.tsx +1 -2
- package/src/shadcn/components/ui/input.tsx +119 -0
- package/src/shadcn/components/ui/pagination.stories.tsx +8 -2
- package/src/shadcn/components/ui/pagination.tsx +54 -3
- package/src/shadcn/components/ui/table.tsx +6 -1
- package/src/shadcn/components/ui/tabs.tsx +1 -0
- package/src/shadcn/components/ui/tree.tsx +63 -10
- package/src/typography.css +36 -8
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import type { ItemInstance } from "@headless-tree/core";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import {
|
|
4
|
+
Tooltip,
|
|
5
|
+
TooltipContent,
|
|
6
|
+
TooltipTrigger,
|
|
7
|
+
} from "#shadcn/components/ui/tooltip";
|
|
8
|
+
import { cn } from "#shadcn/lib/utils.js";
|
|
9
|
+
import * as CustomIcon from "../icons";
|
|
10
|
+
import { TreeView, type TreeViewItem } from "./tree-view";
|
|
11
|
+
|
|
12
|
+
type PackageSpec = {
|
|
13
|
+
name: string;
|
|
14
|
+
version: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type Coordinate = {
|
|
18
|
+
id: string;
|
|
19
|
+
packageSpec: PackageSpec;
|
|
20
|
+
"package-spec": PackageSpec;
|
|
21
|
+
label: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type FhirStructure = {
|
|
25
|
+
type?: string;
|
|
26
|
+
min?: string;
|
|
27
|
+
max?: string;
|
|
28
|
+
lastNode?: boolean;
|
|
29
|
+
isSummary?: boolean;
|
|
30
|
+
isModifier?: boolean;
|
|
31
|
+
mustSupport?: boolean;
|
|
32
|
+
datatype?: string;
|
|
33
|
+
short?: string;
|
|
34
|
+
desc?: string;
|
|
35
|
+
extensionUrl?: string;
|
|
36
|
+
extensionCoordinate?: Coordinate;
|
|
37
|
+
binding?: {
|
|
38
|
+
valueSet: string;
|
|
39
|
+
};
|
|
40
|
+
vsCoordinate?: Coordinate;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const FiledIcon = (item: ItemInstance<TreeViewItem<FhirStructure>>) => {
|
|
44
|
+
const filedType = item.getItemData()?.meta?.type;
|
|
45
|
+
|
|
46
|
+
switch (filedType) {
|
|
47
|
+
case "Resource":
|
|
48
|
+
return <CustomIcon.ResourceIcon />;
|
|
49
|
+
case "BackboneElement":
|
|
50
|
+
return <CustomIcon.BackoneElementIcon />;
|
|
51
|
+
case "Reference":
|
|
52
|
+
return <CustomIcon.ReferenceIcon />;
|
|
53
|
+
case "union":
|
|
54
|
+
return <CustomIcon.UnionIcon />;
|
|
55
|
+
case "instant":
|
|
56
|
+
case "time":
|
|
57
|
+
case "date":
|
|
58
|
+
case "dateTime":
|
|
59
|
+
case "decimal":
|
|
60
|
+
case "boolean":
|
|
61
|
+
case "integer":
|
|
62
|
+
case "string":
|
|
63
|
+
case "uri":
|
|
64
|
+
case "base64Binary":
|
|
65
|
+
case "code":
|
|
66
|
+
case "id":
|
|
67
|
+
case "oid":
|
|
68
|
+
case "unsignedInt":
|
|
69
|
+
case "positiveInt":
|
|
70
|
+
case "markdown":
|
|
71
|
+
case "url":
|
|
72
|
+
case "canonical":
|
|
73
|
+
case "uuid":
|
|
74
|
+
case "integer64":
|
|
75
|
+
return <CustomIcon.TypCodeIcon />;
|
|
76
|
+
default:
|
|
77
|
+
return <CustomIcon.ComplexTypeIcon />;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const customItemFieldNameClass = cn(
|
|
82
|
+
"flex",
|
|
83
|
+
"items-center",
|
|
84
|
+
"truncate",
|
|
85
|
+
"gap-2",
|
|
86
|
+
"min-w-[calc(260px-var(--tree-padding))]",
|
|
87
|
+
"w-[calc(260px-var(--tree-padding))]",
|
|
88
|
+
"in-data-[folder=true]:w-[calc(260px-var(--tree-padding))]",
|
|
89
|
+
"in-data-[folder=true]:min-w-[calc(260px-var(--tree-padding))]",
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const customItemView = (item: ItemInstance<TreeViewItem<FhirStructure>>) => {
|
|
93
|
+
const fieldName = item.getItemData()?.name;
|
|
94
|
+
const cardinalityMin = item.getItemData()?.meta?.min;
|
|
95
|
+
const cardinalityMax = item.getItemData()?.meta?.max;
|
|
96
|
+
const isSummary = item.getItemData()?.meta?.isSummary;
|
|
97
|
+
const isModifier = item.getItemData()?.meta?.isModifier;
|
|
98
|
+
const mustSupport = item.getItemData()?.meta?.mustSupport;
|
|
99
|
+
const datatype = item.getItemData()?.meta?.type;
|
|
100
|
+
const short = item.getItemData()?.meta?.short;
|
|
101
|
+
const desc = item.getItemData()?.meta?.desc;
|
|
102
|
+
const extensionUrl = item.getItemData()?.meta?.extensionUrl;
|
|
103
|
+
const extensionCoordinate = item.getItemData()?.meta?.extensionCoordinate;
|
|
104
|
+
const binding = item.getItemData()?.meta?.binding;
|
|
105
|
+
const vsCoordinate = item.getItemData()?.meta?.vsCoordinate;
|
|
106
|
+
return (
|
|
107
|
+
<div className="flex items-start gap-2 text-xs">
|
|
108
|
+
<div className={customItemFieldNameClass}>
|
|
109
|
+
{FiledIcon(item)}
|
|
110
|
+
{fieldName}
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<div className="flex items-center gap-1 min-w-[60px] w-[60px]">
|
|
114
|
+
{mustSupport && (
|
|
115
|
+
<Tooltip>
|
|
116
|
+
<TooltipTrigger asChild>
|
|
117
|
+
<span className="px-[2px] max-h-[20px] text-white bg-red-600 rounded cursor-help">
|
|
118
|
+
S
|
|
119
|
+
</span>
|
|
120
|
+
</TooltipTrigger>
|
|
121
|
+
<TooltipContent>
|
|
122
|
+
<p>Must be supported</p>
|
|
123
|
+
</TooltipContent>
|
|
124
|
+
</Tooltip>
|
|
125
|
+
)}
|
|
126
|
+
{isSummary && (
|
|
127
|
+
<Tooltip>
|
|
128
|
+
<TooltipTrigger asChild>
|
|
129
|
+
<span className="px-[2px] max-h-[20px] cursor-help">Σ</span>
|
|
130
|
+
</TooltipTrigger>
|
|
131
|
+
<TooltipContent>
|
|
132
|
+
<p>Part of the summary set</p>
|
|
133
|
+
</TooltipContent>
|
|
134
|
+
</Tooltip>
|
|
135
|
+
)}
|
|
136
|
+
{isModifier && (
|
|
137
|
+
<Tooltip>
|
|
138
|
+
<TooltipTrigger asChild>
|
|
139
|
+
<span className="px-[2px] max-h-[20px] cursor-help">!?</span>
|
|
140
|
+
</TooltipTrigger>
|
|
141
|
+
<TooltipContent>
|
|
142
|
+
<p>Modifying element</p>
|
|
143
|
+
</TooltipContent>
|
|
144
|
+
</Tooltip>
|
|
145
|
+
)}
|
|
146
|
+
</div>
|
|
147
|
+
<div className="flex items-center gap-1 min-w-[50px] w-[50px] typo-code">
|
|
148
|
+
{cardinalityMin && cardinalityMax
|
|
149
|
+
? `${cardinalityMin}..${cardinalityMax}`
|
|
150
|
+
: ""}
|
|
151
|
+
</div>
|
|
152
|
+
<div className="flex gap-1 w-[200px] min-w-[200px]">
|
|
153
|
+
{datatype !== "union" && datatype}
|
|
154
|
+
</div>
|
|
155
|
+
<div className="text-left overflow-hidden">
|
|
156
|
+
{short && <div className="line-clamp-2">{short}</div>}
|
|
157
|
+
{!short && desc && <div className="line-clamp-2">{desc}</div>}
|
|
158
|
+
{extensionUrl && (
|
|
159
|
+
<div className="flex items-center gap-1">
|
|
160
|
+
<span>URL:</span>
|
|
161
|
+
{extensionCoordinate?.id ? (
|
|
162
|
+
<a
|
|
163
|
+
href={`#/ig/${extensionCoordinate?.["package-spec"]?.name || extensionCoordinate?.packageSpec?.name}#${extensionCoordinate?.["package-spec"]?.version || extensionCoordinate?.packageSpec?.version}/sd/${extensionCoordinate?.id}`}
|
|
164
|
+
className="font-medium hover:underline"
|
|
165
|
+
>
|
|
166
|
+
{extensionCoordinate?.label || extensionUrl}
|
|
167
|
+
</a>
|
|
168
|
+
) : (
|
|
169
|
+
<span className="font-medium">
|
|
170
|
+
{extensionCoordinate?.label || extensionUrl}
|
|
171
|
+
</span>
|
|
172
|
+
)}
|
|
173
|
+
</div>
|
|
174
|
+
)}
|
|
175
|
+
{binding && (
|
|
176
|
+
<div className="flex items-center gap-1">
|
|
177
|
+
<span>Binding:</span>
|
|
178
|
+
{vsCoordinate?.id ? (
|
|
179
|
+
<a
|
|
180
|
+
href={`#/ig/${vsCoordinate?.["package-spec"]?.name || vsCoordinate?.packageSpec?.name}#${vsCoordinate?.["package-spec"]?.version || vsCoordinate?.packageSpec?.version}/vs/${vsCoordinate?.id}`}
|
|
181
|
+
className="font-medium hover:underline"
|
|
182
|
+
>
|
|
183
|
+
{vsCoordinate?.label || binding?.valueSet || "Binding"}
|
|
184
|
+
</a>
|
|
185
|
+
) : (
|
|
186
|
+
<span className="font-medium">
|
|
187
|
+
{vsCoordinate?.label || binding?.valueSet || "Binding"}
|
|
188
|
+
</span>
|
|
189
|
+
)}
|
|
190
|
+
</div>
|
|
191
|
+
)}
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const FhirStructureView = ({
|
|
198
|
+
tree,
|
|
199
|
+
}: {
|
|
200
|
+
tree: Record<string, TreeViewItem<FhirStructure>>;
|
|
201
|
+
}) => {
|
|
202
|
+
const expandedItemIds = React.useMemo(() => {
|
|
203
|
+
return Object.keys(tree ?? {});
|
|
204
|
+
}, [tree]);
|
|
205
|
+
|
|
206
|
+
return (
|
|
207
|
+
<div className="h-fit w-fit min-h-0 min-w-0">
|
|
208
|
+
<div className="flex items-center gap-2 font-semibold text-xs text-text-secondary border-b py-2 bg-bg-primary sticky top-0 z-20">
|
|
209
|
+
<div className="min-w-[260px] w-[260px] ml-4">Name</div>
|
|
210
|
+
<div className="min-w-[60px] w-[60px]">Flags</div>
|
|
211
|
+
<div className="min-w-[50px] w-[50px]">Card.</div>
|
|
212
|
+
<div className="min-w-[200px] w-[200px]">Type</div>
|
|
213
|
+
<div className="min-w-[200px] w-[200px]">Description</div>
|
|
214
|
+
</div>
|
|
215
|
+
<TreeView
|
|
216
|
+
hideChevron={true}
|
|
217
|
+
horizontalLines={true}
|
|
218
|
+
disableHover={true}
|
|
219
|
+
zebra={true}
|
|
220
|
+
rootItemId="root"
|
|
221
|
+
items={tree}
|
|
222
|
+
customItemView={customItemView}
|
|
223
|
+
expandedItemIds={expandedItemIds}
|
|
224
|
+
/>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export { FhirStructureView, type FhirStructure };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
import type * as React from "react";
|
|
3
|
+
import { toast } from "sonner";
|
|
3
4
|
import { Input } from "#shadcn/components/ui/input";
|
|
4
5
|
import {
|
|
5
6
|
Select,
|
|
@@ -51,9 +52,6 @@ function RequestMethodSelector({
|
|
|
51
52
|
value,
|
|
52
53
|
onValueChange,
|
|
53
54
|
}: RequestMethodSelectorProps) {
|
|
54
|
-
console.log(value);
|
|
55
|
-
console.log(requestMethodVariants());
|
|
56
|
-
console.log(requestMethodVariants(undefined));
|
|
57
55
|
return (
|
|
58
56
|
<Select
|
|
59
57
|
value={value}
|
|
@@ -81,6 +79,8 @@ function RequestMethodSelector({
|
|
|
81
79
|
|
|
82
80
|
type RequestLineEditorProps = {
|
|
83
81
|
method: string;
|
|
82
|
+
placeholder?: string;
|
|
83
|
+
autoFocus?: boolean;
|
|
84
84
|
onMethodChange: (newMethod: string) => void;
|
|
85
85
|
path?: string | undefined;
|
|
86
86
|
onPathChange?: React.ChangeEventHandler<HTMLInputElement>;
|
|
@@ -92,6 +92,8 @@ function RequestLineEditor({
|
|
|
92
92
|
method,
|
|
93
93
|
onMethodChange,
|
|
94
94
|
path,
|
|
95
|
+
placeholder,
|
|
96
|
+
autoFocus,
|
|
95
97
|
onPathChange,
|
|
96
98
|
}: RequestLineEditorProps) {
|
|
97
99
|
return (
|
|
@@ -100,7 +102,31 @@ function RequestLineEditor({
|
|
|
100
102
|
<Input
|
|
101
103
|
className="rounded-l-none"
|
|
102
104
|
value={path}
|
|
103
|
-
|
|
105
|
+
autoFocus={autoFocus}
|
|
106
|
+
placeholder={placeholder}
|
|
107
|
+
rightSlot={
|
|
108
|
+
<CopyIcon
|
|
109
|
+
text={`${method} ${path}`}
|
|
110
|
+
tooltipText="Copy request line"
|
|
111
|
+
showToast={false}
|
|
112
|
+
onCopy={(text) => {
|
|
113
|
+
// Custom toast for request line
|
|
114
|
+
const truncatedText =
|
|
115
|
+
text.length > 30 ? `${text.slice(0, 30)}...` : text;
|
|
116
|
+
toast(
|
|
117
|
+
<div className="flex flex-col gap-1">
|
|
118
|
+
<span className="typo-body">Request line copied</span>
|
|
119
|
+
<span className="typo-code text-text-secondary">
|
|
120
|
+
{truncatedText}
|
|
121
|
+
</span>
|
|
122
|
+
</div>,
|
|
123
|
+
{
|
|
124
|
+
duration: 2000,
|
|
125
|
+
},
|
|
126
|
+
);
|
|
127
|
+
}}
|
|
128
|
+
/>
|
|
129
|
+
}
|
|
104
130
|
{...(onPathChange !== undefined ? { onChange: onPathChange } : {})}
|
|
105
131
|
/>
|
|
106
132
|
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
|
|
3
|
+
import { SegmentControl, SegmentControlItem } from "./segment-control";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "Component/SegmentControl",
|
|
7
|
+
component: SegmentControl,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
} satisfies Meta<typeof SegmentControl>;
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
render: () => {
|
|
19
|
+
return (
|
|
20
|
+
<SegmentControl
|
|
21
|
+
defaultValue="yaml"
|
|
22
|
+
onValueChange={(value) => console.log("Selected:", value)}
|
|
23
|
+
>
|
|
24
|
+
<SegmentControlItem value="yaml">YAML</SegmentControlItem>
|
|
25
|
+
<SegmentControlItem value="json">JSON</SegmentControlItem>
|
|
26
|
+
</SegmentControl>
|
|
27
|
+
);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createContext, type ReactNode, useContext } from "react";
|
|
2
|
+
import { cn } from "#shadcn/lib/utils.js";
|
|
3
|
+
|
|
4
|
+
interface SegmentControlContextType {
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
onValueChange?: (value: string) => void;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const SegmentControlContext = createContext<SegmentControlContextType>({});
|
|
11
|
+
|
|
12
|
+
export interface SegmentControlProps {
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
onValueChange?: (value: string) => void;
|
|
15
|
+
name?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface SegmentControlItemProps {
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
value: string;
|
|
21
|
+
}
|
|
22
|
+
const segmentControlItemClass = cn(
|
|
23
|
+
"flex",
|
|
24
|
+
"items-center",
|
|
25
|
+
"justify-center",
|
|
26
|
+
"px-2",
|
|
27
|
+
"py-0.5",
|
|
28
|
+
"text-sm",
|
|
29
|
+
"cursor-pointer",
|
|
30
|
+
"rounded-2xl",
|
|
31
|
+
"text-white/80",
|
|
32
|
+
"peer-checked:bg-bg-primary",
|
|
33
|
+
"peer-checked:text-text-secondary",
|
|
34
|
+
"select-none",
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const SegmentControlItem = ({ children, value }: SegmentControlItemProps) => {
|
|
38
|
+
const { defaultValue, onValueChange, name } = useContext(
|
|
39
|
+
SegmentControlContext,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className="relative">
|
|
44
|
+
<input
|
|
45
|
+
type="radio"
|
|
46
|
+
id={`${name}-${value}`}
|
|
47
|
+
name={name}
|
|
48
|
+
value={value}
|
|
49
|
+
defaultChecked={value === defaultValue}
|
|
50
|
+
onChange={(e) => onValueChange?.(e.target.value)}
|
|
51
|
+
className="sr-only peer"
|
|
52
|
+
/>
|
|
53
|
+
<label htmlFor={`${name}-${value}`} className={segmentControlItemClass}>
|
|
54
|
+
{children}
|
|
55
|
+
</label>
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const SegmentControl = ({
|
|
61
|
+
children,
|
|
62
|
+
defaultValue,
|
|
63
|
+
onValueChange,
|
|
64
|
+
name,
|
|
65
|
+
}: SegmentControlProps & { children?: ReactNode }) => {
|
|
66
|
+
const contextValue: SegmentControlContextType = {
|
|
67
|
+
...(defaultValue !== undefined && { defaultValue }),
|
|
68
|
+
...(onValueChange !== undefined && { onValueChange }),
|
|
69
|
+
name: name || "react-components-segment-control",
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<SegmentControlContext.Provider value={contextValue}>
|
|
74
|
+
<div className="inline-flex bg-gray-500 p-0.5 gap-0 rounded-full">
|
|
75
|
+
{children}
|
|
76
|
+
</div>
|
|
77
|
+
</SegmentControlContext.Provider>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export { SegmentControl, SegmentControlItem };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { ChevronDown, Plus, Save } from "lucide-react";
|
|
3
|
+
import { Button } from "#shadcn/components/ui/button.js";
|
|
4
|
+
import {
|
|
5
|
+
DropdownMenu,
|
|
6
|
+
DropdownMenuContent,
|
|
7
|
+
DropdownMenuItem,
|
|
8
|
+
DropdownMenuLabel,
|
|
9
|
+
DropdownMenuSeparator,
|
|
10
|
+
DropdownMenuTrigger,
|
|
11
|
+
} from "#shadcn/components/ui/dropdown-menu.js";
|
|
12
|
+
import { SplitButton } from "./split-button";
|
|
13
|
+
|
|
14
|
+
const meta: Meta<typeof SplitButton> = {
|
|
15
|
+
title: "Component/SplitButton",
|
|
16
|
+
component: SplitButton,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default meta;
|
|
20
|
+
|
|
21
|
+
type Story = StoryObj<typeof SplitButton>;
|
|
22
|
+
|
|
23
|
+
export const Default: Story = {
|
|
24
|
+
render: () => (
|
|
25
|
+
<SplitButton>
|
|
26
|
+
<Button variant="secondary">
|
|
27
|
+
<Save />
|
|
28
|
+
Save
|
|
29
|
+
</Button>
|
|
30
|
+
<DropdownMenu>
|
|
31
|
+
<DropdownMenuTrigger asChild>
|
|
32
|
+
<Button variant="secondary">
|
|
33
|
+
<ChevronDown />
|
|
34
|
+
</Button>
|
|
35
|
+
</DropdownMenuTrigger>
|
|
36
|
+
<DropdownMenuContent>
|
|
37
|
+
<DropdownMenuLabel>Save to collection:</DropdownMenuLabel>
|
|
38
|
+
<DropdownMenuSeparator />
|
|
39
|
+
<DropdownMenuItem disabled>No collections</DropdownMenuItem>
|
|
40
|
+
<DropdownMenuSeparator />
|
|
41
|
+
<DropdownMenuItem>
|
|
42
|
+
<Plus className="text-fg-link" />
|
|
43
|
+
New collection
|
|
44
|
+
</DropdownMenuItem>
|
|
45
|
+
</DropdownMenuContent>
|
|
46
|
+
</DropdownMenu>
|
|
47
|
+
</SplitButton>
|
|
48
|
+
),
|
|
49
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cn } from "#shadcn/lib/utils";
|
|
2
|
+
|
|
3
|
+
const splitButtonStyles = cn(
|
|
4
|
+
"flex",
|
|
5
|
+
"*:data-[slot=button]:rounded-r-none",
|
|
6
|
+
"*:data-[slot=dropdown-menu-trigger]:px-1",
|
|
7
|
+
"*:data-[slot=dropdown-menu-trigger]:py-2",
|
|
8
|
+
"*:data-[slot=dropdown-menu-trigger]:rounded-l-none",
|
|
9
|
+
"*:data-[slot=dropdown-menu-trigger]:border-l-0",
|
|
10
|
+
"*:data-[slot=dropdown-menu-trigger]:border-l-0",
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const SplitButton = ({ children }: { children: React.ReactNode }) => {
|
|
14
|
+
return <div className={splitButtonStyles}>{children}</div>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { SplitButton };
|
|
@@ -5,8 +5,8 @@ import React from "react";
|
|
|
5
5
|
import { action } from "storybook/actions";
|
|
6
6
|
import { Button } from "#shadcn/components/ui/button.js";
|
|
7
7
|
import { PinIcon } from "../icons";
|
|
8
|
-
import type {
|
|
9
|
-
import TreeView from "./tree-view";
|
|
8
|
+
import type { TreeViewItem } from "./tree-view";
|
|
9
|
+
import { TreeView } from "./tree-view";
|
|
10
10
|
|
|
11
11
|
const meta: Meta<typeof TreeView> = {
|
|
12
12
|
title: "Component/Tree view",
|
|
@@ -16,17 +16,16 @@ const meta: Meta<typeof TreeView> = {
|
|
|
16
16
|
},
|
|
17
17
|
tags: ["autodocs"],
|
|
18
18
|
};
|
|
19
|
-
|
|
20
|
-
export default meta;
|
|
21
|
-
type Story = StoryObj<typeof TreeView<ItemMeta>>;
|
|
22
|
-
|
|
23
19
|
type ItemMeta = {
|
|
24
20
|
pinned?: boolean;
|
|
25
21
|
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
26
22
|
path?: string;
|
|
27
23
|
};
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
export default meta;
|
|
26
|
+
type Story = StoryObj<typeof TreeView<ItemMeta>>;
|
|
27
|
+
|
|
28
|
+
const items: Record<string, TreeViewItem<ItemMeta>> = {
|
|
30
29
|
root: {
|
|
31
30
|
name: "Root",
|
|
32
31
|
children: ["collection1", "collection2", "collection3"],
|
|
@@ -168,7 +167,7 @@ export const Default: Story = {
|
|
|
168
167
|
render: (args) => <TreeView {...args} />,
|
|
169
168
|
};
|
|
170
169
|
|
|
171
|
-
const customItemView = (item: ItemInstance<
|
|
170
|
+
const customItemView = (item: ItemInstance<TreeViewItem<ItemMeta>>) => {
|
|
172
171
|
const isRootLevel = item.getItemMeta().level === 0;
|
|
173
172
|
const hasChildren = item.getItemData()?.children !== undefined;
|
|
174
173
|
const requestMethhod = item.getItemData()?.meta?.method;
|
|
@@ -179,7 +178,7 @@ const customItemView = (item: ItemInstance<Item<ItemMeta>>) => {
|
|
|
179
178
|
switch (requestMethhod) {
|
|
180
179
|
case "GET":
|
|
181
180
|
return (
|
|
182
|
-
<div className="
|
|
181
|
+
<div className="opacity-50 group-hover/tree-item-label:opacity-100 in-data-[selected=true]:opacity-100 font-medium min-w-13 w-13 text-utility-green text-left">
|
|
183
182
|
GET
|
|
184
183
|
</div>
|
|
185
184
|
);
|
|
@@ -230,17 +229,23 @@ const customItemView = (item: ItemInstance<Item<ItemMeta>>) => {
|
|
|
230
229
|
</div>
|
|
231
230
|
<div className="gap-2 hidden group-hover/tree-item-label:flex items-center">
|
|
232
231
|
{isRootLevel && (
|
|
233
|
-
<Button variant="link" size="small" className="p-0 h-4">
|
|
234
|
-
|
|
232
|
+
<Button variant="link" size="small" className="p-0 h-4" asChild>
|
|
233
|
+
<span>
|
|
234
|
+
{item.getItemData()?.meta?.pinned ? <PinIcon /> : <Pin />}
|
|
235
|
+
</span>
|
|
235
236
|
</Button>
|
|
236
237
|
)}
|
|
237
238
|
{hasChildren && (
|
|
238
|
-
<Button variant="link" size="small" className="p-0 h-4">
|
|
239
|
-
<
|
|
239
|
+
<Button variant="link" size="small" className="p-0 h-4" asChild>
|
|
240
|
+
<span>
|
|
241
|
+
<Plus />
|
|
242
|
+
</span>
|
|
240
243
|
</Button>
|
|
241
244
|
)}
|
|
242
|
-
<Button variant="link" size="small" className="p-0 h-4">
|
|
243
|
-
<
|
|
245
|
+
<Button variant="link" size="small" className="p-0 h-4" asChild>
|
|
246
|
+
<span>
|
|
247
|
+
<Ellipsis />
|
|
248
|
+
</span>
|
|
244
249
|
</Button>
|
|
245
250
|
</div>
|
|
246
251
|
</div>
|