@bridger-kr/react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -0
- package/dist/components/core/Badge.cjs +36 -0
- package/dist/components/core/Badge.cjs.map +1 -0
- package/dist/components/core/Badge.d.cts +18 -0
- package/dist/components/core/Badge.d.ts +18 -0
- package/dist/components/core/Badge.mjs +34 -0
- package/dist/components/core/Badge.mjs.map +1 -0
- package/dist/components/core/Button.cjs +57 -0
- package/dist/components/core/Button.cjs.map +1 -0
- package/dist/components/core/Button.d.cts +26 -0
- package/dist/components/core/Button.d.ts +26 -0
- package/dist/components/core/Button.mjs +55 -0
- package/dist/components/core/Button.mjs.map +1 -0
- package/dist/components/core/Card.cjs +57 -0
- package/dist/components/core/Card.cjs.map +1 -0
- package/dist/components/core/Card.d.cts +27 -0
- package/dist/components/core/Card.d.ts +27 -0
- package/dist/components/core/Card.mjs +54 -0
- package/dist/components/core/Card.mjs.map +1 -0
- package/dist/components/core/FilterChip.cjs +54 -0
- package/dist/components/core/FilterChip.cjs.map +1 -0
- package/dist/components/core/FilterChip.d.cts +23 -0
- package/dist/components/core/FilterChip.d.ts +23 -0
- package/dist/components/core/FilterChip.mjs +52 -0
- package/dist/components/core/FilterChip.mjs.map +1 -0
- package/dist/components/core/Input.cjs +67 -0
- package/dist/components/core/Input.cjs.map +1 -0
- package/dist/components/core/Input.d.cts +20 -0
- package/dist/components/core/Input.d.ts +20 -0
- package/dist/components/core/Input.mjs +65 -0
- package/dist/components/core/Input.mjs.map +1 -0
- package/dist/components/core/StatusPill.cjs +57 -0
- package/dist/components/core/StatusPill.cjs.map +1 -0
- package/dist/components/core/StatusPill.d.cts +19 -0
- package/dist/components/core/StatusPill.d.ts +19 -0
- package/dist/components/core/StatusPill.mjs +55 -0
- package/dist/components/core/StatusPill.mjs.map +1 -0
- package/dist/components/core/Surface.cjs +52 -0
- package/dist/components/core/Surface.cjs.map +1 -0
- package/dist/components/core/Surface.d.cts +24 -0
- package/dist/components/core/Surface.d.ts +24 -0
- package/dist/components/core/Surface.mjs +47 -0
- package/dist/components/core/Surface.mjs.map +1 -0
- package/dist/components/core/Tabs.cjs +64 -0
- package/dist/components/core/Tabs.cjs.map +1 -0
- package/dist/components/core/Tabs.d.cts +24 -0
- package/dist/components/core/Tabs.d.ts +24 -0
- package/dist/components/core/Tabs.mjs +62 -0
- package/dist/components/core/Tabs.mjs.map +1 -0
- package/dist/components/data/Avatar.cjs +40 -0
- package/dist/components/data/Avatar.cjs.map +1 -0
- package/dist/components/data/Avatar.d.cts +24 -0
- package/dist/components/data/Avatar.d.ts +24 -0
- package/dist/components/data/Avatar.mjs +38 -0
- package/dist/components/data/Avatar.mjs.map +1 -0
- package/dist/components/data/CodeBlock.cjs +92 -0
- package/dist/components/data/CodeBlock.cjs.map +1 -0
- package/dist/components/data/CodeBlock.d.cts +20 -0
- package/dist/components/data/CodeBlock.d.ts +20 -0
- package/dist/components/data/CodeBlock.mjs +90 -0
- package/dist/components/data/CodeBlock.mjs.map +1 -0
- package/dist/components/data/KeyValue.cjs +55 -0
- package/dist/components/data/KeyValue.cjs.map +1 -0
- package/dist/components/data/KeyValue.d.cts +24 -0
- package/dist/components/data/KeyValue.d.ts +24 -0
- package/dist/components/data/KeyValue.mjs +53 -0
- package/dist/components/data/KeyValue.mjs.map +1 -0
- package/dist/components/data/LogRow.cjs +55 -0
- package/dist/components/data/LogRow.cjs.map +1 -0
- package/dist/components/data/LogRow.d.cts +23 -0
- package/dist/components/data/LogRow.d.ts +23 -0
- package/dist/components/data/LogRow.mjs +53 -0
- package/dist/components/data/LogRow.mjs.map +1 -0
- package/dist/components/data/Pagination.cjs +44 -0
- package/dist/components/data/Pagination.cjs.map +1 -0
- package/dist/components/data/Pagination.d.cts +13 -0
- package/dist/components/data/Pagination.d.ts +13 -0
- package/dist/components/data/Pagination.mjs +42 -0
- package/dist/components/data/Pagination.mjs.map +1 -0
- package/dist/components/data/StatTile.cjs +20 -0
- package/dist/components/data/StatTile.cjs.map +1 -0
- package/dist/components/data/StatTile.d.cts +19 -0
- package/dist/components/data/StatTile.d.ts +19 -0
- package/dist/components/data/StatTile.mjs +18 -0
- package/dist/components/data/StatTile.mjs.map +1 -0
- package/dist/components/data/Table.cjs +45 -0
- package/dist/components/data/Table.cjs.map +1 -0
- package/dist/components/data/Table.d.cts +27 -0
- package/dist/components/data/Table.d.ts +27 -0
- package/dist/components/data/Table.mjs +43 -0
- package/dist/components/data/Table.mjs.map +1 -0
- package/dist/components/data/UsageMeter.cjs +28 -0
- package/dist/components/data/UsageMeter.cjs.map +1 -0
- package/dist/components/data/UsageMeter.d.cts +19 -0
- package/dist/components/data/UsageMeter.d.ts +19 -0
- package/dist/components/data/UsageMeter.mjs +26 -0
- package/dist/components/data/UsageMeter.mjs.map +1 -0
- package/dist/components/feedback/Alert.cjs +78 -0
- package/dist/components/feedback/Alert.cjs.map +1 -0
- package/dist/components/feedback/Alert.d.cts +29 -0
- package/dist/components/feedback/Alert.d.ts +29 -0
- package/dist/components/feedback/Alert.mjs +74 -0
- package/dist/components/feedback/Alert.mjs.map +1 -0
- package/dist/components/feedback/Dialog.cjs +62 -0
- package/dist/components/feedback/Dialog.cjs.map +1 -0
- package/dist/components/feedback/Dialog.d.cts +17 -0
- package/dist/components/feedback/Dialog.d.ts +17 -0
- package/dist/components/feedback/Dialog.mjs +60 -0
- package/dist/components/feedback/Dialog.mjs.map +1 -0
- package/dist/components/feedback/Drawer.cjs +58 -0
- package/dist/components/feedback/Drawer.cjs.map +1 -0
- package/dist/components/feedback/Drawer.d.cts +22 -0
- package/dist/components/feedback/Drawer.d.ts +22 -0
- package/dist/components/feedback/Drawer.mjs +56 -0
- package/dist/components/feedback/Drawer.mjs.map +1 -0
- package/dist/components/feedback/EmptyState.cjs +36 -0
- package/dist/components/feedback/EmptyState.cjs.map +1 -0
- package/dist/components/feedback/EmptyState.d.cts +14 -0
- package/dist/components/feedback/EmptyState.d.ts +14 -0
- package/dist/components/feedback/EmptyState.mjs +34 -0
- package/dist/components/feedback/EmptyState.mjs.map +1 -0
- package/dist/components/feedback/Skeleton.cjs +19 -0
- package/dist/components/feedback/Skeleton.cjs.map +1 -0
- package/dist/components/feedback/Skeleton.d.cts +12 -0
- package/dist/components/feedback/Skeleton.d.ts +12 -0
- package/dist/components/feedback/Skeleton.mjs +17 -0
- package/dist/components/feedback/Skeleton.mjs.map +1 -0
- package/dist/components/feedback/Spinner.cjs +17 -0
- package/dist/components/feedback/Spinner.cjs.map +1 -0
- package/dist/components/feedback/Spinner.d.cts +12 -0
- package/dist/components/feedback/Spinner.d.ts +12 -0
- package/dist/components/feedback/Spinner.mjs +15 -0
- package/dist/components/feedback/Spinner.mjs.map +1 -0
- package/dist/components/feedback/Toast.cjs +32 -0
- package/dist/components/feedback/Toast.cjs.map +1 -0
- package/dist/components/feedback/Toast.d.cts +20 -0
- package/dist/components/feedback/Toast.d.ts +20 -0
- package/dist/components/feedback/Toast.mjs +30 -0
- package/dist/components/feedback/Toast.mjs.map +1 -0
- package/dist/components/feedback/Tooltip.cjs +51 -0
- package/dist/components/feedback/Tooltip.cjs.map +1 -0
- package/dist/components/feedback/Tooltip.d.cts +11 -0
- package/dist/components/feedback/Tooltip.d.ts +11 -0
- package/dist/components/feedback/Tooltip.mjs +49 -0
- package/dist/components/feedback/Tooltip.mjs.map +1 -0
- package/dist/components/forms/Checkbox.cjs +74 -0
- package/dist/components/forms/Checkbox.cjs.map +1 -0
- package/dist/components/forms/Checkbox.d.cts +16 -0
- package/dist/components/forms/Checkbox.d.ts +16 -0
- package/dist/components/forms/Checkbox.mjs +72 -0
- package/dist/components/forms/Checkbox.mjs.map +1 -0
- package/dist/components/forms/Combobox.cjs +217 -0
- package/dist/components/forms/Combobox.cjs.map +1 -0
- package/dist/components/forms/Combobox.d.cts +27 -0
- package/dist/components/forms/Combobox.d.ts +27 -0
- package/dist/components/forms/Combobox.mjs +215 -0
- package/dist/components/forms/Combobox.mjs.map +1 -0
- package/dist/components/forms/FileUpload.cjs +187 -0
- package/dist/components/forms/FileUpload.cjs.map +1 -0
- package/dist/components/forms/FileUpload.d.cts +26 -0
- package/dist/components/forms/FileUpload.d.ts +26 -0
- package/dist/components/forms/FileUpload.mjs +185 -0
- package/dist/components/forms/FileUpload.mjs.map +1 -0
- package/dist/components/forms/RadioGroup.cjs +73 -0
- package/dist/components/forms/RadioGroup.cjs.map +1 -0
- package/dist/components/forms/RadioGroup.d.cts +21 -0
- package/dist/components/forms/RadioGroup.d.ts +21 -0
- package/dist/components/forms/RadioGroup.mjs +71 -0
- package/dist/components/forms/RadioGroup.mjs.map +1 -0
- package/dist/components/forms/SegmentedControl.cjs +67 -0
- package/dist/components/forms/SegmentedControl.cjs.map +1 -0
- package/dist/components/forms/SegmentedControl.d.cts +19 -0
- package/dist/components/forms/SegmentedControl.d.ts +19 -0
- package/dist/components/forms/SegmentedControl.mjs +65 -0
- package/dist/components/forms/SegmentedControl.mjs.map +1 -0
- package/dist/components/forms/Select.cjs +67 -0
- package/dist/components/forms/Select.cjs.map +1 -0
- package/dist/components/forms/Select.d.cts +23 -0
- package/dist/components/forms/Select.d.ts +23 -0
- package/dist/components/forms/Select.mjs +65 -0
- package/dist/components/forms/Select.mjs.map +1 -0
- package/dist/components/forms/Slider.cjs +129 -0
- package/dist/components/forms/Slider.cjs.map +1 -0
- package/dist/components/forms/Slider.d.cts +24 -0
- package/dist/components/forms/Slider.d.ts +24 -0
- package/dist/components/forms/Slider.mjs +127 -0
- package/dist/components/forms/Slider.mjs.map +1 -0
- package/dist/components/forms/Switch.cjs +101 -0
- package/dist/components/forms/Switch.cjs.map +1 -0
- package/dist/components/forms/Switch.d.cts +24 -0
- package/dist/components/forms/Switch.d.ts +24 -0
- package/dist/components/forms/Switch.mjs +98 -0
- package/dist/components/forms/Switch.mjs.map +1 -0
- package/dist/components/forms/Textarea.cjs +35 -0
- package/dist/components/forms/Textarea.cjs.map +1 -0
- package/dist/components/forms/Textarea.d.cts +15 -0
- package/dist/components/forms/Textarea.d.ts +15 -0
- package/dist/components/forms/Textarea.mjs +33 -0
- package/dist/components/forms/Textarea.mjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.cjs +27 -0
- package/dist/components/navigation/Breadcrumb.cjs.map +1 -0
- package/dist/components/navigation/Breadcrumb.d.cts +15 -0
- package/dist/components/navigation/Breadcrumb.d.ts +15 -0
- package/dist/components/navigation/Breadcrumb.mjs +25 -0
- package/dist/components/navigation/Breadcrumb.mjs.map +1 -0
- package/dist/components/navigation/CommandPalette.cjs +136 -0
- package/dist/components/navigation/CommandPalette.cjs.map +1 -0
- package/dist/components/navigation/CommandPalette.d.cts +26 -0
- package/dist/components/navigation/CommandPalette.d.ts +26 -0
- package/dist/components/navigation/CommandPalette.mjs +134 -0
- package/dist/components/navigation/CommandPalette.mjs.map +1 -0
- package/dist/components/navigation/Menu.cjs +104 -0
- package/dist/components/navigation/Menu.cjs.map +1 -0
- package/dist/components/navigation/Menu.d.cts +20 -0
- package/dist/components/navigation/Menu.d.ts +20 -0
- package/dist/components/navigation/Menu.mjs +102 -0
- package/dist/components/navigation/Menu.mjs.map +1 -0
- package/dist/components/navigation/Sidebar.cjs +60 -0
- package/dist/components/navigation/Sidebar.cjs.map +1 -0
- package/dist/components/navigation/Sidebar.d.cts +30 -0
- package/dist/components/navigation/Sidebar.d.ts +30 -0
- package/dist/components/navigation/Sidebar.mjs +58 -0
- package/dist/components/navigation/Sidebar.mjs.map +1 -0
- package/dist/components/navigation/Stepper.cjs +55 -0
- package/dist/components/navigation/Stepper.cjs.map +1 -0
- package/dist/components/navigation/Stepper.d.cts +21 -0
- package/dist/components/navigation/Stepper.d.ts +21 -0
- package/dist/components/navigation/Stepper.mjs +53 -0
- package/dist/components/navigation/Stepper.mjs.map +1 -0
- package/dist/components/product/BrandLogo.cjs +159 -0
- package/dist/components/product/BrandLogo.cjs.map +1 -0
- package/dist/components/product/BrandLogo.d.cts +28 -0
- package/dist/components/product/BrandLogo.d.ts +28 -0
- package/dist/components/product/BrandLogo.mjs +156 -0
- package/dist/components/product/BrandLogo.mjs.map +1 -0
- package/dist/components/product/ProductActionPill.cjs +57 -0
- package/dist/components/product/ProductActionPill.cjs.map +1 -0
- package/dist/components/product/ProductActionPill.d.cts +31 -0
- package/dist/components/product/ProductActionPill.d.ts +31 -0
- package/dist/components/product/ProductActionPill.mjs +52 -0
- package/dist/components/product/ProductActionPill.mjs.map +1 -0
- package/dist/components/product/ProductCinematic.cjs +69 -0
- package/dist/components/product/ProductCinematic.cjs.map +1 -0
- package/dist/components/product/ProductCinematic.d.cts +33 -0
- package/dist/components/product/ProductCinematic.d.ts +33 -0
- package/dist/components/product/ProductCinematic.mjs +63 -0
- package/dist/components/product/ProductCinematic.mjs.map +1 -0
- package/dist/components/product/ProductPageHeader.cjs +35 -0
- package/dist/components/product/ProductPageHeader.cjs.map +1 -0
- package/dist/components/product/ProductPageHeader.d.cts +13 -0
- package/dist/components/product/ProductPageHeader.d.ts +13 -0
- package/dist/components/product/ProductPageHeader.mjs +33 -0
- package/dist/components/product/ProductPageHeader.mjs.map +1 -0
- package/dist/components/product/SectionCard.cjs +72 -0
- package/dist/components/product/SectionCard.cjs.map +1 -0
- package/dist/components/product/SectionCard.d.cts +20 -0
- package/dist/components/product/SectionCard.d.ts +20 -0
- package/dist/components/product/SectionCard.mjs +70 -0
- package/dist/components/product/SectionCard.mjs.map +1 -0
- package/dist/components/product/ToolCard.cjs +70 -0
- package/dist/components/product/ToolCard.cjs.map +1 -0
- package/dist/components/product/ToolCard.d.cts +22 -0
- package/dist/components/product/ToolCard.d.ts +22 -0
- package/dist/components/product/ToolCard.mjs +68 -0
- package/dist/components/product/ToolCard.mjs.map +1 -0
- package/dist/index.cjs +2593 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.mjs +2532 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles.css +463 -0
- package/package.json +50 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/components/forms/FileUpload.tsx
|
|
7
|
+
function fmtSize(bytes) {
|
|
8
|
+
if (bytes == null) return "";
|
|
9
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
10
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
|
|
11
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
12
|
+
}
|
|
13
|
+
function FileUpload({
|
|
14
|
+
label,
|
|
15
|
+
accept = ".json,.yaml,.yml",
|
|
16
|
+
hint = "OpenAPI \uC2A4\uD399 \xB7 JSON \uB610\uB294 YAML",
|
|
17
|
+
file,
|
|
18
|
+
onFiles,
|
|
19
|
+
onRemove,
|
|
20
|
+
id,
|
|
21
|
+
style
|
|
22
|
+
}) {
|
|
23
|
+
const [drag, setDrag] = react.useState(false);
|
|
24
|
+
const inputRef = react.useRef(null);
|
|
25
|
+
const fId = id || "fu";
|
|
26
|
+
const handle = (files) => {
|
|
27
|
+
if (files && files.length) onFiles?.(files);
|
|
28
|
+
};
|
|
29
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 7, ...style }, children: [
|
|
30
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "var(--dt-muted-strong)" }, children: label }) : null,
|
|
31
|
+
file ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
32
|
+
"div",
|
|
33
|
+
{
|
|
34
|
+
style: {
|
|
35
|
+
display: "flex",
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
gap: 12,
|
|
38
|
+
padding: "12px 14px",
|
|
39
|
+
background: "var(--dt-surface)",
|
|
40
|
+
border: "1px solid var(--dt-border-strong)",
|
|
41
|
+
borderRadius: "var(--dt-radius-lg)"
|
|
42
|
+
},
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
45
|
+
"span",
|
|
46
|
+
{
|
|
47
|
+
style: {
|
|
48
|
+
width: 34,
|
|
49
|
+
height: 34,
|
|
50
|
+
flex: "0 0 auto",
|
|
51
|
+
display: "grid",
|
|
52
|
+
placeItems: "center",
|
|
53
|
+
borderRadius: "var(--dt-radius-md)",
|
|
54
|
+
background: "var(--dt-tint-accent)",
|
|
55
|
+
color: "var(--dt-accent)"
|
|
56
|
+
},
|
|
57
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
59
|
+
"path",
|
|
60
|
+
{
|
|
61
|
+
d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
|
|
62
|
+
stroke: "currentColor",
|
|
63
|
+
strokeWidth: "2",
|
|
64
|
+
strokeLinejoin: "round"
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14 2v6h6", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" })
|
|
68
|
+
] })
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
72
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
73
|
+
"div",
|
|
74
|
+
{
|
|
75
|
+
style: {
|
|
76
|
+
fontFamily: "var(--dt-font-mono)",
|
|
77
|
+
fontSize: 13,
|
|
78
|
+
fontWeight: 600,
|
|
79
|
+
color: "var(--dt-ink-strong)",
|
|
80
|
+
overflow: "hidden",
|
|
81
|
+
textOverflow: "ellipsis",
|
|
82
|
+
whiteSpace: "nowrap"
|
|
83
|
+
},
|
|
84
|
+
children: file.name
|
|
85
|
+
}
|
|
86
|
+
),
|
|
87
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "var(--dt-muted)", marginTop: 2 }, children: [
|
|
88
|
+
fmtSize(file.size),
|
|
89
|
+
" \xB7 \uC5C5\uB85C\uB4DC \uC644\uB8CC"
|
|
90
|
+
] })
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
93
|
+
"button",
|
|
94
|
+
{
|
|
95
|
+
type: "button",
|
|
96
|
+
onClick: onRemove,
|
|
97
|
+
"aria-label": "\uC81C\uAC70",
|
|
98
|
+
style: {
|
|
99
|
+
flex: "0 0 auto",
|
|
100
|
+
width: 30,
|
|
101
|
+
height: 30,
|
|
102
|
+
display: "grid",
|
|
103
|
+
placeItems: "center",
|
|
104
|
+
border: "none",
|
|
105
|
+
background: "var(--dt-surface-sunken)",
|
|
106
|
+
borderRadius: "var(--dt-radius-sm)",
|
|
107
|
+
color: "var(--dt-muted-strong)",
|
|
108
|
+
cursor: "pointer"
|
|
109
|
+
},
|
|
110
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6l12 12", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
|
|
111
|
+
}
|
|
112
|
+
)
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
116
|
+
"label",
|
|
117
|
+
{
|
|
118
|
+
htmlFor: fId,
|
|
119
|
+
onDragOver: (e) => {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
setDrag(true);
|
|
122
|
+
},
|
|
123
|
+
onDragLeave: () => setDrag(false),
|
|
124
|
+
onDrop: (e) => {
|
|
125
|
+
e.preventDefault();
|
|
126
|
+
setDrag(false);
|
|
127
|
+
handle(e.dataTransfer.files);
|
|
128
|
+
},
|
|
129
|
+
style: {
|
|
130
|
+
display: "grid",
|
|
131
|
+
placeItems: "center",
|
|
132
|
+
gap: 8,
|
|
133
|
+
padding: "26px 20px",
|
|
134
|
+
textAlign: "center",
|
|
135
|
+
cursor: "pointer",
|
|
136
|
+
borderRadius: "var(--dt-radius-lg)",
|
|
137
|
+
border: `1.5px dashed ${drag ? "var(--dt-accent)" : "var(--dt-border-strong)"}`,
|
|
138
|
+
background: drag ? "var(--dt-tint-accent)" : "var(--dt-surface-sunken)",
|
|
139
|
+
transition: "background-color var(--dt-motion-fast), border-color var(--dt-motion-fast)"
|
|
140
|
+
},
|
|
141
|
+
children: [
|
|
142
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: drag ? "var(--dt-accent)" : "var(--dt-muted)" }, children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
143
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
144
|
+
"path",
|
|
145
|
+
{
|
|
146
|
+
d: "M12 16V4m0 0L7 9m5-5l5 5",
|
|
147
|
+
stroke: "currentColor",
|
|
148
|
+
strokeWidth: "2",
|
|
149
|
+
strokeLinecap: "round",
|
|
150
|
+
strokeLinejoin: "round"
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
154
|
+
"path",
|
|
155
|
+
{
|
|
156
|
+
d: "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2",
|
|
157
|
+
stroke: "currentColor",
|
|
158
|
+
strokeWidth: "2",
|
|
159
|
+
strokeLinecap: "round"
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
] }) }),
|
|
163
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 13.5, color: "var(--dt-ink-strong)" }, children: [
|
|
164
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600, color: "var(--dt-accent)" }, children: "\uD30C\uC77C \uC120\uD0DD" }),
|
|
165
|
+
" \uB610\uB294 \uB04C\uC5B4\uB2E4 \uB193\uAE30"
|
|
166
|
+
] }),
|
|
167
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "var(--dt-muted)" }, children: hint }),
|
|
168
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
169
|
+
"input",
|
|
170
|
+
{
|
|
171
|
+
ref: inputRef,
|
|
172
|
+
id: fId,
|
|
173
|
+
type: "file",
|
|
174
|
+
accept,
|
|
175
|
+
onChange: (e) => handle(e.target.files),
|
|
176
|
+
style: { display: "none" }
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
] });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
exports.FileUpload = FileUpload;
|
|
186
|
+
//# sourceMappingURL=FileUpload.cjs.map
|
|
187
|
+
//# sourceMappingURL=FileUpload.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/FileUpload.tsx"],"names":["useState","useRef","jsxs","jsx"],"mappings":"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","file":"FileUpload.cjs","sourcesContent":["import { useRef, useState } from 'react';\nimport type { CSSProperties, DragEvent, HTMLAttributes } from 'react';\n\nfunction fmtSize(bytes?: number) {\n if (bytes == null) return '';\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;\n return `${(bytes / 1024 / 1024).toFixed(1)} MB`;\n}\n\nexport interface UploadedFile {\n name: string;\n size?: number;\n}\n\nexport interface FileUploadProps extends Omit<HTMLAttributes<HTMLDivElement>, 'id' | 'style'> {\n label?: string;\n /** Accepted file types, passed to the native input. */\n accept?: string;\n hint?: string;\n /** Current file — when set, the filled state renders instead of the dropzone. */\n file?: UploadedFile | null;\n onFiles?: (files: FileList) => void;\n onRemove?: () => void;\n id?: string;\n style?: CSSProperties;\n}\n\n/**\n * Dashed hairline dropzone for uploading an OpenAPI spec. Idle / drag / filled.\n * @startingPoint section=\"Forms\" subtitle=\"Dropzone for an OpenAPI spec\" viewport=\"460x180\"\n */\nexport function FileUpload({\n label,\n accept = '.json,.yaml,.yml',\n hint = 'OpenAPI 스펙 · JSON 또는 YAML',\n file,\n onFiles,\n onRemove,\n id,\n style,\n}: FileUploadProps) {\n const [drag, setDrag] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const fId = id || 'fu';\n\n const handle = (files: FileList | null) => {\n if (files && files.length) onFiles?.(files);\n };\n\n return (\n <div style={{ display: 'grid', gap: 7, ...style }}>\n {label ? <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--dt-muted-strong)' }}>{label}</span> : null}\n\n {file ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: 'var(--dt-surface)',\n border: '1px solid var(--dt-border-strong)',\n borderRadius: 'var(--dt-radius-lg)',\n }}\n >\n <span\n style={{\n width: 34,\n height: 34,\n flex: '0 0 auto',\n display: 'grid',\n placeItems: 'center',\n borderRadius: 'var(--dt-radius-md)',\n background: 'var(--dt-tint-accent)',\n color: 'var(--dt-accent)',\n }}\n >\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M14 2v6h6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinejoin=\"round\" />\n </svg>\n </span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontFamily: 'var(--dt-font-mono)',\n fontSize: 13,\n fontWeight: 600,\n color: 'var(--dt-ink-strong)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {file.name}\n </div>\n <div style={{ fontFamily: 'var(--dt-font-mono)', fontSize: 11, color: 'var(--dt-muted)', marginTop: 2 }}>\n {fmtSize(file.size)} · 업로드 완료\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onRemove}\n aria-label=\"제거\"\n style={{\n flex: '0 0 auto',\n width: 30,\n height: 30,\n display: 'grid',\n placeItems: 'center',\n border: 'none',\n background: 'var(--dt-surface-sunken)',\n borderRadius: 'var(--dt-radius-sm)',\n color: 'var(--dt-muted-strong)',\n cursor: 'pointer',\n }}\n >\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M18 6L6 18M6 6l12 12\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n ) : (\n <label\n htmlFor={fId}\n onDragOver={(e: DragEvent<HTMLLabelElement>) => {\n e.preventDefault();\n setDrag(true);\n }}\n onDragLeave={() => setDrag(false)}\n onDrop={(e: DragEvent<HTMLLabelElement>) => {\n e.preventDefault();\n setDrag(false);\n handle(e.dataTransfer.files);\n }}\n style={{\n display: 'grid',\n placeItems: 'center',\n gap: 8,\n padding: '26px 20px',\n textAlign: 'center',\n cursor: 'pointer',\n borderRadius: 'var(--dt-radius-lg)',\n border: `1.5px dashed ${drag ? 'var(--dt-accent)' : 'var(--dt-border-strong)'}`,\n background: drag ? 'var(--dt-tint-accent)' : 'var(--dt-surface-sunken)',\n transition: 'background-color var(--dt-motion-fast), border-color var(--dt-motion-fast)',\n }}\n >\n <span style={{ color: drag ? 'var(--dt-accent)' : 'var(--dt-muted)' }}>\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 16V4m0 0L7 9m5-5l5 5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </span>\n <span style={{ fontSize: 13.5, color: 'var(--dt-ink-strong)' }}>\n <span style={{ fontWeight: 600, color: 'var(--dt-accent)' }}>파일 선택</span> 또는 끌어다 놓기\n </span>\n <span style={{ fontFamily: 'var(--dt-font-mono)', fontSize: 11, color: 'var(--dt-muted)' }}>{hint}</span>\n <input\n ref={inputRef}\n id={fId}\n type=\"file\"\n accept={accept}\n onChange={(e) => handle(e.target.files)}\n style={{ display: 'none' }}\n />\n </label>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface UploadedFile {
|
|
5
|
+
name: string;
|
|
6
|
+
size?: number;
|
|
7
|
+
}
|
|
8
|
+
interface FileUploadProps extends Omit<HTMLAttributes<HTMLDivElement>, 'id' | 'style'> {
|
|
9
|
+
label?: string;
|
|
10
|
+
/** Accepted file types, passed to the native input. */
|
|
11
|
+
accept?: string;
|
|
12
|
+
hint?: string;
|
|
13
|
+
/** Current file — when set, the filled state renders instead of the dropzone. */
|
|
14
|
+
file?: UploadedFile | null;
|
|
15
|
+
onFiles?: (files: FileList) => void;
|
|
16
|
+
onRemove?: () => void;
|
|
17
|
+
id?: string;
|
|
18
|
+
style?: CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Dashed hairline dropzone for uploading an OpenAPI spec. Idle / drag / filled.
|
|
22
|
+
* @startingPoint section="Forms" subtitle="Dropzone for an OpenAPI spec" viewport="460x180"
|
|
23
|
+
*/
|
|
24
|
+
declare function FileUpload({ label, accept, hint, file, onFiles, onRemove, id, style, }: FileUploadProps): react.JSX.Element;
|
|
25
|
+
|
|
26
|
+
export { FileUpload, type FileUploadProps, type UploadedFile };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface UploadedFile {
|
|
5
|
+
name: string;
|
|
6
|
+
size?: number;
|
|
7
|
+
}
|
|
8
|
+
interface FileUploadProps extends Omit<HTMLAttributes<HTMLDivElement>, 'id' | 'style'> {
|
|
9
|
+
label?: string;
|
|
10
|
+
/** Accepted file types, passed to the native input. */
|
|
11
|
+
accept?: string;
|
|
12
|
+
hint?: string;
|
|
13
|
+
/** Current file — when set, the filled state renders instead of the dropzone. */
|
|
14
|
+
file?: UploadedFile | null;
|
|
15
|
+
onFiles?: (files: FileList) => void;
|
|
16
|
+
onRemove?: () => void;
|
|
17
|
+
id?: string;
|
|
18
|
+
style?: CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Dashed hairline dropzone for uploading an OpenAPI spec. Idle / drag / filled.
|
|
22
|
+
* @startingPoint section="Forms" subtitle="Dropzone for an OpenAPI spec" viewport="460x180"
|
|
23
|
+
*/
|
|
24
|
+
declare function FileUpload({ label, accept, hint, file, onFiles, onRemove, id, style, }: FileUploadProps): react.JSX.Element;
|
|
25
|
+
|
|
26
|
+
export { FileUpload, type FileUploadProps, type UploadedFile };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { useState, useRef } from 'react';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/components/forms/FileUpload.tsx
|
|
5
|
+
function fmtSize(bytes) {
|
|
6
|
+
if (bytes == null) return "";
|
|
7
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
8
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
|
|
9
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
10
|
+
}
|
|
11
|
+
function FileUpload({
|
|
12
|
+
label,
|
|
13
|
+
accept = ".json,.yaml,.yml",
|
|
14
|
+
hint = "OpenAPI \uC2A4\uD399 \xB7 JSON \uB610\uB294 YAML",
|
|
15
|
+
file,
|
|
16
|
+
onFiles,
|
|
17
|
+
onRemove,
|
|
18
|
+
id,
|
|
19
|
+
style
|
|
20
|
+
}) {
|
|
21
|
+
const [drag, setDrag] = useState(false);
|
|
22
|
+
const inputRef = useRef(null);
|
|
23
|
+
const fId = id || "fu";
|
|
24
|
+
const handle = (files) => {
|
|
25
|
+
if (files && files.length) onFiles?.(files);
|
|
26
|
+
};
|
|
27
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 7, ...style }, children: [
|
|
28
|
+
label ? /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "var(--dt-muted-strong)" }, children: label }) : null,
|
|
29
|
+
file ? /* @__PURE__ */ jsxs(
|
|
30
|
+
"div",
|
|
31
|
+
{
|
|
32
|
+
style: {
|
|
33
|
+
display: "flex",
|
|
34
|
+
alignItems: "center",
|
|
35
|
+
gap: 12,
|
|
36
|
+
padding: "12px 14px",
|
|
37
|
+
background: "var(--dt-surface)",
|
|
38
|
+
border: "1px solid var(--dt-border-strong)",
|
|
39
|
+
borderRadius: "var(--dt-radius-lg)"
|
|
40
|
+
},
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
"span",
|
|
44
|
+
{
|
|
45
|
+
style: {
|
|
46
|
+
width: 34,
|
|
47
|
+
height: 34,
|
|
48
|
+
flex: "0 0 auto",
|
|
49
|
+
display: "grid",
|
|
50
|
+
placeItems: "center",
|
|
51
|
+
borderRadius: "var(--dt-radius-md)",
|
|
52
|
+
background: "var(--dt-tint-accent)",
|
|
53
|
+
color: "var(--dt-accent)"
|
|
54
|
+
},
|
|
55
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
56
|
+
/* @__PURE__ */ jsx(
|
|
57
|
+
"path",
|
|
58
|
+
{
|
|
59
|
+
d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
|
|
60
|
+
stroke: "currentColor",
|
|
61
|
+
strokeWidth: "2",
|
|
62
|
+
strokeLinejoin: "round"
|
|
63
|
+
}
|
|
64
|
+
),
|
|
65
|
+
/* @__PURE__ */ jsx("path", { d: "M14 2v6h6", stroke: "currentColor", strokeWidth: "2", strokeLinejoin: "round" })
|
|
66
|
+
] })
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
"div",
|
|
72
|
+
{
|
|
73
|
+
style: {
|
|
74
|
+
fontFamily: "var(--dt-font-mono)",
|
|
75
|
+
fontSize: 13,
|
|
76
|
+
fontWeight: 600,
|
|
77
|
+
color: "var(--dt-ink-strong)",
|
|
78
|
+
overflow: "hidden",
|
|
79
|
+
textOverflow: "ellipsis",
|
|
80
|
+
whiteSpace: "nowrap"
|
|
81
|
+
},
|
|
82
|
+
children: file.name
|
|
83
|
+
}
|
|
84
|
+
),
|
|
85
|
+
/* @__PURE__ */ jsxs("div", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "var(--dt-muted)", marginTop: 2 }, children: [
|
|
86
|
+
fmtSize(file.size),
|
|
87
|
+
" \xB7 \uC5C5\uB85C\uB4DC \uC644\uB8CC"
|
|
88
|
+
] })
|
|
89
|
+
] }),
|
|
90
|
+
/* @__PURE__ */ jsx(
|
|
91
|
+
"button",
|
|
92
|
+
{
|
|
93
|
+
type: "button",
|
|
94
|
+
onClick: onRemove,
|
|
95
|
+
"aria-label": "\uC81C\uAC70",
|
|
96
|
+
style: {
|
|
97
|
+
flex: "0 0 auto",
|
|
98
|
+
width: 30,
|
|
99
|
+
height: 30,
|
|
100
|
+
display: "grid",
|
|
101
|
+
placeItems: "center",
|
|
102
|
+
border: "none",
|
|
103
|
+
background: "var(--dt-surface-sunken)",
|
|
104
|
+
borderRadius: "var(--dt-radius-sm)",
|
|
105
|
+
color: "var(--dt-muted-strong)",
|
|
106
|
+
cursor: "pointer"
|
|
107
|
+
},
|
|
108
|
+
children: /* @__PURE__ */ jsx("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M18 6L6 18M6 6l12 12", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
) : /* @__PURE__ */ jsxs(
|
|
114
|
+
"label",
|
|
115
|
+
{
|
|
116
|
+
htmlFor: fId,
|
|
117
|
+
onDragOver: (e) => {
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
setDrag(true);
|
|
120
|
+
},
|
|
121
|
+
onDragLeave: () => setDrag(false),
|
|
122
|
+
onDrop: (e) => {
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
setDrag(false);
|
|
125
|
+
handle(e.dataTransfer.files);
|
|
126
|
+
},
|
|
127
|
+
style: {
|
|
128
|
+
display: "grid",
|
|
129
|
+
placeItems: "center",
|
|
130
|
+
gap: 8,
|
|
131
|
+
padding: "26px 20px",
|
|
132
|
+
textAlign: "center",
|
|
133
|
+
cursor: "pointer",
|
|
134
|
+
borderRadius: "var(--dt-radius-lg)",
|
|
135
|
+
border: `1.5px dashed ${drag ? "var(--dt-accent)" : "var(--dt-border-strong)"}`,
|
|
136
|
+
background: drag ? "var(--dt-tint-accent)" : "var(--dt-surface-sunken)",
|
|
137
|
+
transition: "background-color var(--dt-motion-fast), border-color var(--dt-motion-fast)"
|
|
138
|
+
},
|
|
139
|
+
children: [
|
|
140
|
+
/* @__PURE__ */ jsx("span", { style: { color: drag ? "var(--dt-accent)" : "var(--dt-muted)" }, children: /* @__PURE__ */ jsxs("svg", { width: "22", height: "22", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: [
|
|
141
|
+
/* @__PURE__ */ jsx(
|
|
142
|
+
"path",
|
|
143
|
+
{
|
|
144
|
+
d: "M12 16V4m0 0L7 9m5-5l5 5",
|
|
145
|
+
stroke: "currentColor",
|
|
146
|
+
strokeWidth: "2",
|
|
147
|
+
strokeLinecap: "round",
|
|
148
|
+
strokeLinejoin: "round"
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
/* @__PURE__ */ jsx(
|
|
152
|
+
"path",
|
|
153
|
+
{
|
|
154
|
+
d: "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2",
|
|
155
|
+
stroke: "currentColor",
|
|
156
|
+
strokeWidth: "2",
|
|
157
|
+
strokeLinecap: "round"
|
|
158
|
+
}
|
|
159
|
+
)
|
|
160
|
+
] }) }),
|
|
161
|
+
/* @__PURE__ */ jsxs("span", { style: { fontSize: 13.5, color: "var(--dt-ink-strong)" }, children: [
|
|
162
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600, color: "var(--dt-accent)" }, children: "\uD30C\uC77C \uC120\uD0DD" }),
|
|
163
|
+
" \uB610\uB294 \uB04C\uC5B4\uB2E4 \uB193\uAE30"
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsx("span", { style: { fontFamily: "var(--dt-font-mono)", fontSize: 11, color: "var(--dt-muted)" }, children: hint }),
|
|
166
|
+
/* @__PURE__ */ jsx(
|
|
167
|
+
"input",
|
|
168
|
+
{
|
|
169
|
+
ref: inputRef,
|
|
170
|
+
id: fId,
|
|
171
|
+
type: "file",
|
|
172
|
+
accept,
|
|
173
|
+
onChange: (e) => handle(e.target.files),
|
|
174
|
+
style: { display: "none" }
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
)
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export { FileUpload };
|
|
184
|
+
//# sourceMappingURL=FileUpload.mjs.map
|
|
185
|
+
//# sourceMappingURL=FileUpload.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/FileUpload.tsx"],"names":[],"mappings":"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","file":"FileUpload.mjs","sourcesContent":["import { useRef, useState } from 'react';\nimport type { CSSProperties, DragEvent, HTMLAttributes } from 'react';\n\nfunction fmtSize(bytes?: number) {\n if (bytes == null) return '';\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;\n return `${(bytes / 1024 / 1024).toFixed(1)} MB`;\n}\n\nexport interface UploadedFile {\n name: string;\n size?: number;\n}\n\nexport interface FileUploadProps extends Omit<HTMLAttributes<HTMLDivElement>, 'id' | 'style'> {\n label?: string;\n /** Accepted file types, passed to the native input. */\n accept?: string;\n hint?: string;\n /** Current file — when set, the filled state renders instead of the dropzone. */\n file?: UploadedFile | null;\n onFiles?: (files: FileList) => void;\n onRemove?: () => void;\n id?: string;\n style?: CSSProperties;\n}\n\n/**\n * Dashed hairline dropzone for uploading an OpenAPI spec. Idle / drag / filled.\n * @startingPoint section=\"Forms\" subtitle=\"Dropzone for an OpenAPI spec\" viewport=\"460x180\"\n */\nexport function FileUpload({\n label,\n accept = '.json,.yaml,.yml',\n hint = 'OpenAPI 스펙 · JSON 또는 YAML',\n file,\n onFiles,\n onRemove,\n id,\n style,\n}: FileUploadProps) {\n const [drag, setDrag] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const fId = id || 'fu';\n\n const handle = (files: FileList | null) => {\n if (files && files.length) onFiles?.(files);\n };\n\n return (\n <div style={{ display: 'grid', gap: 7, ...style }}>\n {label ? <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--dt-muted-strong)' }}>{label}</span> : null}\n\n {file ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '12px 14px',\n background: 'var(--dt-surface)',\n border: '1px solid var(--dt-border-strong)',\n borderRadius: 'var(--dt-radius-lg)',\n }}\n >\n <span\n style={{\n width: 34,\n height: 34,\n flex: '0 0 auto',\n display: 'grid',\n placeItems: 'center',\n borderRadius: 'var(--dt-radius-md)',\n background: 'var(--dt-tint-accent)',\n color: 'var(--dt-accent)',\n }}\n >\n <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n />\n <path d=\"M14 2v6h6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinejoin=\"round\" />\n </svg>\n </span>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontFamily: 'var(--dt-font-mono)',\n fontSize: 13,\n fontWeight: 600,\n color: 'var(--dt-ink-strong)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {file.name}\n </div>\n <div style={{ fontFamily: 'var(--dt-font-mono)', fontSize: 11, color: 'var(--dt-muted)', marginTop: 2 }}>\n {fmtSize(file.size)} · 업로드 완료\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onRemove}\n aria-label=\"제거\"\n style={{\n flex: '0 0 auto',\n width: 30,\n height: 30,\n display: 'grid',\n placeItems: 'center',\n border: 'none',\n background: 'var(--dt-surface-sunken)',\n borderRadius: 'var(--dt-radius-sm)',\n color: 'var(--dt-muted-strong)',\n cursor: 'pointer',\n }}\n >\n <svg width=\"15\" height=\"15\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M18 6L6 18M6 6l12 12\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n </button>\n </div>\n ) : (\n <label\n htmlFor={fId}\n onDragOver={(e: DragEvent<HTMLLabelElement>) => {\n e.preventDefault();\n setDrag(true);\n }}\n onDragLeave={() => setDrag(false)}\n onDrop={(e: DragEvent<HTMLLabelElement>) => {\n e.preventDefault();\n setDrag(false);\n handle(e.dataTransfer.files);\n }}\n style={{\n display: 'grid',\n placeItems: 'center',\n gap: 8,\n padding: '26px 20px',\n textAlign: 'center',\n cursor: 'pointer',\n borderRadius: 'var(--dt-radius-lg)',\n border: `1.5px dashed ${drag ? 'var(--dt-accent)' : 'var(--dt-border-strong)'}`,\n background: drag ? 'var(--dt-tint-accent)' : 'var(--dt-surface-sunken)',\n transition: 'background-color var(--dt-motion-fast), border-color var(--dt-motion-fast)',\n }}\n >\n <span style={{ color: drag ? 'var(--dt-accent)' : 'var(--dt-muted)' }}>\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M12 16V4m0 0L7 9m5-5l5 5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </span>\n <span style={{ fontSize: 13.5, color: 'var(--dt-ink-strong)' }}>\n <span style={{ fontWeight: 600, color: 'var(--dt-accent)' }}>파일 선택</span> 또는 끌어다 놓기\n </span>\n <span style={{ fontFamily: 'var(--dt-font-mono)', fontSize: 11, color: 'var(--dt-muted)' }}>{hint}</span>\n <input\n ref={inputRef}\n id={fId}\n type=\"file\"\n accept={accept}\n onChange={(e) => handle(e.target.files)}\n style={{ display: 'none' }}\n />\n </label>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/components/forms/RadioGroup.tsx
|
|
7
|
+
function RadioGroup({ name, options = [], value, defaultValue, onChange, disabled, style }) {
|
|
8
|
+
const [internal, setInternal] = react.useState(defaultValue);
|
|
9
|
+
const current = value !== void 0 ? value : internal;
|
|
10
|
+
const generatedName = react.useId();
|
|
11
|
+
const groupName = name || generatedName;
|
|
12
|
+
const select = (v) => {
|
|
13
|
+
if (disabled) return;
|
|
14
|
+
if (value === void 0) setInternal(v);
|
|
15
|
+
onChange?.(v);
|
|
16
|
+
};
|
|
17
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "radiogroup", style: { display: "grid", gap: 10, ...style }, children: options.map((o) => {
|
|
18
|
+
const opt = typeof o === "string" ? { value: o, label: o } : o;
|
|
19
|
+
const on = opt.value === current;
|
|
20
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
21
|
+
"label",
|
|
22
|
+
{
|
|
23
|
+
style: {
|
|
24
|
+
display: "flex",
|
|
25
|
+
alignItems: "flex-start",
|
|
26
|
+
gap: 10,
|
|
27
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
28
|
+
opacity: disabled ? 0.55 : 1
|
|
29
|
+
},
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
32
|
+
"input",
|
|
33
|
+
{
|
|
34
|
+
type: "radio",
|
|
35
|
+
name: groupName,
|
|
36
|
+
checked: on,
|
|
37
|
+
onChange: () => select(opt.value),
|
|
38
|
+
disabled,
|
|
39
|
+
style: { position: "absolute", opacity: 0, width: 0, height: 0 }
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
43
|
+
"span",
|
|
44
|
+
{
|
|
45
|
+
style: {
|
|
46
|
+
width: 18,
|
|
47
|
+
height: 18,
|
|
48
|
+
marginTop: 1,
|
|
49
|
+
flex: "0 0 auto",
|
|
50
|
+
borderRadius: 9999,
|
|
51
|
+
display: "grid",
|
|
52
|
+
placeItems: "center",
|
|
53
|
+
background: "var(--dt-surface)",
|
|
54
|
+
border: `1.5px solid ${on ? "var(--dt-accent)" : "var(--dt-border-strong)"}`,
|
|
55
|
+
transition: "border-color 130ms"
|
|
56
|
+
},
|
|
57
|
+
children: on ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { width: 9, height: 9, borderRadius: 9999, background: "var(--dt-accent)" } }) : null
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "grid", gap: 2 }, children: [
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 14, color: "var(--dt-ink)", lineHeight: 1.3 }, children: opt.label }),
|
|
62
|
+
opt.hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "var(--dt-muted)" }, children: opt.hint }) : null
|
|
63
|
+
] })
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
opt.value
|
|
67
|
+
);
|
|
68
|
+
}) });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
exports.RadioGroup = RadioGroup;
|
|
72
|
+
//# sourceMappingURL=RadioGroup.cjs.map
|
|
73
|
+
//# sourceMappingURL=RadioGroup.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/RadioGroup.tsx"],"names":["useState","useId","jsxs","jsx"],"mappings":"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","file":"RadioGroup.cjs","sourcesContent":["import { useId, useState } from 'react';\nimport type { CSSProperties, HTMLAttributes } from 'react';\n\nexport interface RadioOption {\n value: string;\n label: string;\n hint?: string;\n}\n\nexport interface RadioGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'style'> {\n name?: string;\n options?: Array<string | RadioOption>;\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n disabled?: boolean;\n style?: CSSProperties;\n}\n\n/** Radio group with optional per-option hint text. */\nexport function RadioGroup({ name, options = [], value, defaultValue, onChange, disabled, style }: RadioGroupProps) {\n const [internal, setInternal] = useState(defaultValue);\n const current = value !== undefined ? value : internal;\n const generatedName = useId();\n const groupName = name || generatedName;\n const select = (v: string) => {\n if (disabled) return;\n if (value === undefined) setInternal(v);\n onChange?.(v);\n };\n return (\n <div role=\"radiogroup\" style={{ display: 'grid', gap: 10, ...style }}>\n {options.map((o) => {\n const opt = typeof o === 'string' ? { value: o, label: o } : o;\n const on = opt.value === current;\n return (\n <label\n key={opt.value}\n style={{\n display: 'flex',\n alignItems: 'flex-start',\n gap: 10,\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.55 : 1,\n }}\n >\n <input\n type=\"radio\"\n name={groupName}\n checked={on}\n onChange={() => select(opt.value)}\n disabled={disabled}\n style={{ position: 'absolute', opacity: 0, width: 0, height: 0 }}\n />\n <span\n style={{\n width: 18,\n height: 18,\n marginTop: 1,\n flex: '0 0 auto',\n borderRadius: 9999,\n display: 'grid',\n placeItems: 'center',\n background: 'var(--dt-surface)',\n border: `1.5px solid ${on ? 'var(--dt-accent)' : 'var(--dt-border-strong)'}`,\n transition: 'border-color 130ms',\n }}\n >\n {on ? <span style={{ width: 9, height: 9, borderRadius: 9999, background: 'var(--dt-accent)' }} /> : null}\n </span>\n <span style={{ display: 'grid', gap: 2 }}>\n <span style={{ fontSize: 14, color: 'var(--dt-ink)', lineHeight: 1.3 }}>{opt.label}</span>\n {opt.hint ? <span style={{ fontSize: 12, color: 'var(--dt-muted)' }}>{opt.hint}</span> : null}\n </span>\n </label>\n );\n })}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface RadioOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
hint?: string;
|
|
8
|
+
}
|
|
9
|
+
interface RadioGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'style'> {
|
|
10
|
+
name?: string;
|
|
11
|
+
options?: Array<string | RadioOption>;
|
|
12
|
+
value?: string;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
onChange?: (value: string) => void;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
style?: CSSProperties;
|
|
17
|
+
}
|
|
18
|
+
/** Radio group with optional per-option hint text. */
|
|
19
|
+
declare function RadioGroup({ name, options, value, defaultValue, onChange, disabled, style }: RadioGroupProps): react.JSX.Element;
|
|
20
|
+
|
|
21
|
+
export { RadioGroup, type RadioGroupProps, type RadioOption };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface RadioOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
hint?: string;
|
|
8
|
+
}
|
|
9
|
+
interface RadioGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'style'> {
|
|
10
|
+
name?: string;
|
|
11
|
+
options?: Array<string | RadioOption>;
|
|
12
|
+
value?: string;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
onChange?: (value: string) => void;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
style?: CSSProperties;
|
|
17
|
+
}
|
|
18
|
+
/** Radio group with optional per-option hint text. */
|
|
19
|
+
declare function RadioGroup({ name, options, value, defaultValue, onChange, disabled, style }: RadioGroupProps): react.JSX.Element;
|
|
20
|
+
|
|
21
|
+
export { RadioGroup, type RadioGroupProps, type RadioOption };
|