@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,71 @@
|
|
|
1
|
+
import { useState, useId } from 'react';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/components/forms/RadioGroup.tsx
|
|
5
|
+
function RadioGroup({ name, options = [], value, defaultValue, onChange, disabled, style }) {
|
|
6
|
+
const [internal, setInternal] = useState(defaultValue);
|
|
7
|
+
const current = value !== void 0 ? value : internal;
|
|
8
|
+
const generatedName = useId();
|
|
9
|
+
const groupName = name || generatedName;
|
|
10
|
+
const select = (v) => {
|
|
11
|
+
if (disabled) return;
|
|
12
|
+
if (value === void 0) setInternal(v);
|
|
13
|
+
onChange?.(v);
|
|
14
|
+
};
|
|
15
|
+
return /* @__PURE__ */ jsx("div", { role: "radiogroup", style: { display: "grid", gap: 10, ...style }, children: options.map((o) => {
|
|
16
|
+
const opt = typeof o === "string" ? { value: o, label: o } : o;
|
|
17
|
+
const on = opt.value === current;
|
|
18
|
+
return /* @__PURE__ */ jsxs(
|
|
19
|
+
"label",
|
|
20
|
+
{
|
|
21
|
+
style: {
|
|
22
|
+
display: "flex",
|
|
23
|
+
alignItems: "flex-start",
|
|
24
|
+
gap: 10,
|
|
25
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
26
|
+
opacity: disabled ? 0.55 : 1
|
|
27
|
+
},
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ jsx(
|
|
30
|
+
"input",
|
|
31
|
+
{
|
|
32
|
+
type: "radio",
|
|
33
|
+
name: groupName,
|
|
34
|
+
checked: on,
|
|
35
|
+
onChange: () => select(opt.value),
|
|
36
|
+
disabled,
|
|
37
|
+
style: { position: "absolute", opacity: 0, width: 0, height: 0 }
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
"span",
|
|
42
|
+
{
|
|
43
|
+
style: {
|
|
44
|
+
width: 18,
|
|
45
|
+
height: 18,
|
|
46
|
+
marginTop: 1,
|
|
47
|
+
flex: "0 0 auto",
|
|
48
|
+
borderRadius: 9999,
|
|
49
|
+
display: "grid",
|
|
50
|
+
placeItems: "center",
|
|
51
|
+
background: "var(--dt-surface)",
|
|
52
|
+
border: `1.5px solid ${on ? "var(--dt-accent)" : "var(--dt-border-strong)"}`,
|
|
53
|
+
transition: "border-color 130ms"
|
|
54
|
+
},
|
|
55
|
+
children: on ? /* @__PURE__ */ jsx("span", { style: { width: 9, height: 9, borderRadius: 9999, background: "var(--dt-accent)" } }) : null
|
|
56
|
+
}
|
|
57
|
+
),
|
|
58
|
+
/* @__PURE__ */ jsxs("span", { style: { display: "grid", gap: 2 }, children: [
|
|
59
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 14, color: "var(--dt-ink)", lineHeight: 1.3 }, children: opt.label }),
|
|
60
|
+
opt.hint ? /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "var(--dt-muted)" }, children: opt.hint }) : null
|
|
61
|
+
] })
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
opt.value
|
|
65
|
+
);
|
|
66
|
+
}) });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { RadioGroup };
|
|
70
|
+
//# sourceMappingURL=RadioGroup.mjs.map
|
|
71
|
+
//# sourceMappingURL=RadioGroup.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/RadioGroup.tsx"],"names":[],"mappings":"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","file":"RadioGroup.mjs","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,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/components/forms/SegmentedControl.tsx
|
|
7
|
+
function SegmentedControl({
|
|
8
|
+
options = [],
|
|
9
|
+
value,
|
|
10
|
+
defaultValue,
|
|
11
|
+
onChange,
|
|
12
|
+
size = "md",
|
|
13
|
+
style
|
|
14
|
+
}) {
|
|
15
|
+
const firstOption = typeof options[0] === "string" ? options[0] : options[0]?.value;
|
|
16
|
+
const [internal, setInternal] = react.useState(defaultValue ?? firstOption);
|
|
17
|
+
const current = value !== void 0 ? value : internal;
|
|
18
|
+
const select = (v) => {
|
|
19
|
+
if (value === void 0) setInternal(v);
|
|
20
|
+
onChange?.(v);
|
|
21
|
+
};
|
|
22
|
+
const pad = size === "sm" ? "5px 11px" : "7px 14px";
|
|
23
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
24
|
+
"div",
|
|
25
|
+
{
|
|
26
|
+
style: {
|
|
27
|
+
display: "inline-flex",
|
|
28
|
+
padding: 3,
|
|
29
|
+
gap: 2,
|
|
30
|
+
background: "var(--dt-surface-sunken)",
|
|
31
|
+
borderRadius: "var(--dt-radius-md)",
|
|
32
|
+
...style
|
|
33
|
+
},
|
|
34
|
+
children: options.map((o) => {
|
|
35
|
+
const opt = typeof o === "string" ? { value: o, label: o } : o;
|
|
36
|
+
const on = opt.value === current;
|
|
37
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
38
|
+
"button",
|
|
39
|
+
{
|
|
40
|
+
type: "button",
|
|
41
|
+
onClick: () => select(opt.value),
|
|
42
|
+
style: {
|
|
43
|
+
border: "none",
|
|
44
|
+
cursor: "pointer",
|
|
45
|
+
padding: pad,
|
|
46
|
+
borderRadius: "var(--dt-radius-sm)",
|
|
47
|
+
fontSize: size === "sm" ? 12 : 13,
|
|
48
|
+
fontWeight: 600,
|
|
49
|
+
fontFamily: "inherit",
|
|
50
|
+
whiteSpace: "nowrap",
|
|
51
|
+
color: on ? "var(--dt-ink-strong)" : "var(--dt-muted)",
|
|
52
|
+
background: on ? "var(--dt-surface)" : "transparent",
|
|
53
|
+
boxShadow: on ? "var(--dt-ring), var(--dt-shadow-xs)" : "none",
|
|
54
|
+
transition: "color 130ms, background-color 130ms"
|
|
55
|
+
},
|
|
56
|
+
children: opt.label
|
|
57
|
+
},
|
|
58
|
+
opt.value
|
|
59
|
+
);
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.SegmentedControl = SegmentedControl;
|
|
66
|
+
//# sourceMappingURL=SegmentedControl.cjs.map
|
|
67
|
+
//# sourceMappingURL=SegmentedControl.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/SegmentedControl.tsx"],"names":["useState","jsx"],"mappings":";;;;;;AAkBO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,UAAU,EAAC;AAAA,EACX,KAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,WAAA,GAAc,OAAO,OAAA,CAAQ,CAAC,CAAA,KAAM,QAAA,GAAW,OAAA,CAAQ,CAAC,CAAA,GAAI,OAAA,CAAQ,CAAC,CAAA,EAAG,KAAA;AAC9E,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAA,CAAS,gBAAgB,WAAW,CAAA;AACpE,EAAA,MAAM,OAAA,GAAU,KAAA,KAAU,MAAA,GAAY,KAAA,GAAQ,QAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAc;AAC5B,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,WAAA,CAAY,CAAC,CAAA;AACtC,IAAA,QAAA,GAAW,CAAC,CAAA;AAAA,EACd,CAAA;AACA,EAAA,MAAM,GAAA,GAAM,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,UAAA;AACzC,EAAA,uBACEC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,aAAA;AAAA,QACT,OAAA,EAAS,CAAA;AAAA,QACT,GAAA,EAAK,CAAA;AAAA,QACL,UAAA,EAAY,0BAAA;AAAA,QACZ,YAAA,EAAc,qBAAA;AAAA,QACd,GAAG;AAAA,OACL;AAAA,MAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AAClB,QAAA,MAAM,GAAA,GAAM,OAAO,CAAA,KAAM,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,EAAG,KAAA,EAAO,CAAA,EAAE,GAAI,CAAA;AAC7D,QAAA,MAAM,EAAA,GAAK,IAAI,KAAA,KAAU,OAAA;AACzB,QAAA,uBACEA,cAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,YAC/B,KAAA,EAAO;AAAA,cACL,MAAA,EAAQ,MAAA;AAAA,cACR,MAAA,EAAQ,SAAA;AAAA,cACR,OAAA,EAAS,GAAA;AAAA,cACT,YAAA,EAAc,qBAAA;AAAA,cACd,QAAA,EAAU,IAAA,KAAS,IAAA,GAAO,EAAA,GAAK,EAAA;AAAA,cAC/B,UAAA,EAAY,GAAA;AAAA,cACZ,UAAA,EAAY,SAAA;AAAA,cACZ,UAAA,EAAY,QAAA;AAAA,cACZ,KAAA,EAAO,KAAK,sBAAA,GAAyB,iBAAA;AAAA,cACrC,UAAA,EAAY,KAAK,mBAAA,GAAsB,aAAA;AAAA,cACvC,SAAA,EAAW,KAAK,qCAAA,GAAwC,MAAA;AAAA,cACxD,UAAA,EAAY;AAAA,aACd;AAAA,YAEC,QAAA,EAAA,GAAA,CAAI;AAAA,WAAA;AAAA,UAlBA,GAAA,CAAI;AAAA,SAmBX;AAAA,MAEJ,CAAC;AAAA;AAAA,GACH;AAEJ","file":"SegmentedControl.cjs","sourcesContent":["import { useState } from 'react';\nimport type { CSSProperties, HTMLAttributes } from 'react';\n\nexport interface SegmentOption {\n value: string;\n label: string;\n}\n\nexport interface SegmentedControlProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'style'> {\n options?: Array<string | SegmentOption>;\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n size?: 'sm' | 'md';\n style?: CSSProperties;\n}\n\n/** Inset segmented control for 2–4 short, exclusive options. */\nexport function SegmentedControl({\n options = [],\n value,\n defaultValue,\n onChange,\n size = 'md',\n style,\n}: SegmentedControlProps) {\n const firstOption = typeof options[0] === 'string' ? options[0] : options[0]?.value;\n const [internal, setInternal] = useState(defaultValue ?? firstOption);\n const current = value !== undefined ? value : internal;\n const select = (v: string) => {\n if (value === undefined) setInternal(v);\n onChange?.(v);\n };\n const pad = size === 'sm' ? '5px 11px' : '7px 14px';\n return (\n <div\n style={{\n display: 'inline-flex',\n padding: 3,\n gap: 2,\n background: 'var(--dt-surface-sunken)',\n borderRadius: 'var(--dt-radius-md)',\n ...style,\n }}\n >\n {options.map((o) => {\n const opt = typeof o === 'string' ? { value: o, label: o } : o;\n const on = opt.value === current;\n return (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => select(opt.value)}\n style={{\n border: 'none',\n cursor: 'pointer',\n padding: pad,\n borderRadius: 'var(--dt-radius-sm)',\n fontSize: size === 'sm' ? 12 : 13,\n fontWeight: 600,\n fontFamily: 'inherit',\n whiteSpace: 'nowrap',\n color: on ? 'var(--dt-ink-strong)' : 'var(--dt-muted)',\n background: on ? 'var(--dt-surface)' : 'transparent',\n boxShadow: on ? 'var(--dt-ring), var(--dt-shadow-xs)' : 'none',\n transition: 'color 130ms, background-color 130ms',\n }}\n >\n {opt.label}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface SegmentOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
interface SegmentedControlProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'style'> {
|
|
9
|
+
options?: Array<string | SegmentOption>;
|
|
10
|
+
value?: string;
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
onChange?: (value: string) => void;
|
|
13
|
+
size?: 'sm' | 'md';
|
|
14
|
+
style?: CSSProperties;
|
|
15
|
+
}
|
|
16
|
+
/** Inset segmented control for 2–4 short, exclusive options. */
|
|
17
|
+
declare function SegmentedControl({ options, value, defaultValue, onChange, size, style, }: SegmentedControlProps): react.JSX.Element;
|
|
18
|
+
|
|
19
|
+
export { type SegmentOption, SegmentedControl, type SegmentedControlProps };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { HTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface SegmentOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
interface SegmentedControlProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'style'> {
|
|
9
|
+
options?: Array<string | SegmentOption>;
|
|
10
|
+
value?: string;
|
|
11
|
+
defaultValue?: string;
|
|
12
|
+
onChange?: (value: string) => void;
|
|
13
|
+
size?: 'sm' | 'md';
|
|
14
|
+
style?: CSSProperties;
|
|
15
|
+
}
|
|
16
|
+
/** Inset segmented control for 2–4 short, exclusive options. */
|
|
17
|
+
declare function SegmentedControl({ options, value, defaultValue, onChange, size, style, }: SegmentedControlProps): react.JSX.Element;
|
|
18
|
+
|
|
19
|
+
export { type SegmentOption, SegmentedControl, type SegmentedControlProps };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/components/forms/SegmentedControl.tsx
|
|
5
|
+
function SegmentedControl({
|
|
6
|
+
options = [],
|
|
7
|
+
value,
|
|
8
|
+
defaultValue,
|
|
9
|
+
onChange,
|
|
10
|
+
size = "md",
|
|
11
|
+
style
|
|
12
|
+
}) {
|
|
13
|
+
const firstOption = typeof options[0] === "string" ? options[0] : options[0]?.value;
|
|
14
|
+
const [internal, setInternal] = useState(defaultValue ?? firstOption);
|
|
15
|
+
const current = value !== void 0 ? value : internal;
|
|
16
|
+
const select = (v) => {
|
|
17
|
+
if (value === void 0) setInternal(v);
|
|
18
|
+
onChange?.(v);
|
|
19
|
+
};
|
|
20
|
+
const pad = size === "sm" ? "5px 11px" : "7px 14px";
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
"div",
|
|
23
|
+
{
|
|
24
|
+
style: {
|
|
25
|
+
display: "inline-flex",
|
|
26
|
+
padding: 3,
|
|
27
|
+
gap: 2,
|
|
28
|
+
background: "var(--dt-surface-sunken)",
|
|
29
|
+
borderRadius: "var(--dt-radius-md)",
|
|
30
|
+
...style
|
|
31
|
+
},
|
|
32
|
+
children: options.map((o) => {
|
|
33
|
+
const opt = typeof o === "string" ? { value: o, label: o } : o;
|
|
34
|
+
const on = opt.value === current;
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
onClick: () => select(opt.value),
|
|
40
|
+
style: {
|
|
41
|
+
border: "none",
|
|
42
|
+
cursor: "pointer",
|
|
43
|
+
padding: pad,
|
|
44
|
+
borderRadius: "var(--dt-radius-sm)",
|
|
45
|
+
fontSize: size === "sm" ? 12 : 13,
|
|
46
|
+
fontWeight: 600,
|
|
47
|
+
fontFamily: "inherit",
|
|
48
|
+
whiteSpace: "nowrap",
|
|
49
|
+
color: on ? "var(--dt-ink-strong)" : "var(--dt-muted)",
|
|
50
|
+
background: on ? "var(--dt-surface)" : "transparent",
|
|
51
|
+
boxShadow: on ? "var(--dt-ring), var(--dt-shadow-xs)" : "none",
|
|
52
|
+
transition: "color 130ms, background-color 130ms"
|
|
53
|
+
},
|
|
54
|
+
children: opt.label
|
|
55
|
+
},
|
|
56
|
+
opt.value
|
|
57
|
+
);
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { SegmentedControl };
|
|
64
|
+
//# sourceMappingURL=SegmentedControl.mjs.map
|
|
65
|
+
//# sourceMappingURL=SegmentedControl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/SegmentedControl.tsx"],"names":[],"mappings":";;;;AAkBO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,UAAU,EAAC;AAAA,EACX,KAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,WAAA,GAAc,OAAO,OAAA,CAAQ,CAAC,CAAA,KAAM,QAAA,GAAW,OAAA,CAAQ,CAAC,CAAA,GAAI,OAAA,CAAQ,CAAC,CAAA,EAAG,KAAA;AAC9E,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,QAAA,CAAS,gBAAgB,WAAW,CAAA;AACpE,EAAA,MAAM,OAAA,GAAU,KAAA,KAAU,MAAA,GAAY,KAAA,GAAQ,QAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAc;AAC5B,IAAA,IAAI,KAAA,KAAU,MAAA,EAAW,WAAA,CAAY,CAAC,CAAA;AACtC,IAAA,QAAA,GAAW,CAAC,CAAA;AAAA,EACd,CAAA;AACA,EAAA,MAAM,GAAA,GAAM,IAAA,KAAS,IAAA,GAAO,UAAA,GAAa,UAAA;AACzC,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,aAAA;AAAA,QACT,OAAA,EAAS,CAAA;AAAA,QACT,GAAA,EAAK,CAAA;AAAA,QACL,UAAA,EAAY,0BAAA;AAAA,QACZ,YAAA,EAAc,qBAAA;AAAA,QACd,GAAG;AAAA,OACL;AAAA,MAEC,QAAA,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AAClB,QAAA,MAAM,GAAA,GAAM,OAAO,CAAA,KAAM,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,EAAG,KAAA,EAAO,CAAA,EAAE,GAAI,CAAA;AAC7D,QAAA,MAAM,EAAA,GAAK,IAAI,KAAA,KAAU,OAAA;AACzB,QAAA,uBACE,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAEC,IAAA,EAAK,QAAA;AAAA,YACL,OAAA,EAAS,MAAM,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,YAC/B,KAAA,EAAO;AAAA,cACL,MAAA,EAAQ,MAAA;AAAA,cACR,MAAA,EAAQ,SAAA;AAAA,cACR,OAAA,EAAS,GAAA;AAAA,cACT,YAAA,EAAc,qBAAA;AAAA,cACd,QAAA,EAAU,IAAA,KAAS,IAAA,GAAO,EAAA,GAAK,EAAA;AAAA,cAC/B,UAAA,EAAY,GAAA;AAAA,cACZ,UAAA,EAAY,SAAA;AAAA,cACZ,UAAA,EAAY,QAAA;AAAA,cACZ,KAAA,EAAO,KAAK,sBAAA,GAAyB,iBAAA;AAAA,cACrC,UAAA,EAAY,KAAK,mBAAA,GAAsB,aAAA;AAAA,cACvC,SAAA,EAAW,KAAK,qCAAA,GAAwC,MAAA;AAAA,cACxD,UAAA,EAAY;AAAA,aACd;AAAA,YAEC,QAAA,EAAA,GAAA,CAAI;AAAA,WAAA;AAAA,UAlBA,GAAA,CAAI;AAAA,SAmBX;AAAA,MAEJ,CAAC;AAAA;AAAA,GACH;AAEJ","file":"SegmentedControl.mjs","sourcesContent":["import { useState } from 'react';\nimport type { CSSProperties, HTMLAttributes } from 'react';\n\nexport interface SegmentOption {\n value: string;\n label: string;\n}\n\nexport interface SegmentedControlProps extends Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange' | 'style'> {\n options?: Array<string | SegmentOption>;\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n size?: 'sm' | 'md';\n style?: CSSProperties;\n}\n\n/** Inset segmented control for 2–4 short, exclusive options. */\nexport function SegmentedControl({\n options = [],\n value,\n defaultValue,\n onChange,\n size = 'md',\n style,\n}: SegmentedControlProps) {\n const firstOption = typeof options[0] === 'string' ? options[0] : options[0]?.value;\n const [internal, setInternal] = useState(defaultValue ?? firstOption);\n const current = value !== undefined ? value : internal;\n const select = (v: string) => {\n if (value === undefined) setInternal(v);\n onChange?.(v);\n };\n const pad = size === 'sm' ? '5px 11px' : '7px 14px';\n return (\n <div\n style={{\n display: 'inline-flex',\n padding: 3,\n gap: 2,\n background: 'var(--dt-surface-sunken)',\n borderRadius: 'var(--dt-radius-md)',\n ...style,\n }}\n >\n {options.map((o) => {\n const opt = typeof o === 'string' ? { value: o, label: o } : o;\n const on = opt.value === current;\n return (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => select(opt.value)}\n style={{\n border: 'none',\n cursor: 'pointer',\n padding: pad,\n borderRadius: 'var(--dt-radius-sm)',\n fontSize: size === 'sm' ? 12 : 13,\n fontWeight: 600,\n fontFamily: 'inherit',\n whiteSpace: 'nowrap',\n color: on ? 'var(--dt-ink-strong)' : 'var(--dt-muted)',\n background: on ? 'var(--dt-surface)' : 'transparent',\n boxShadow: on ? 'var(--dt-ring), var(--dt-shadow-xs)' : 'none',\n transition: 'color 130ms, background-color 130ms',\n }}\n >\n {opt.label}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
// src/components/forms/Select.tsx
|
|
6
|
+
function Select({ label, hint, options = [], value, defaultValue, onChange, placeholder, disabled, id, style }) {
|
|
7
|
+
const selId = id || (label ? `sel-${label.replace(/\s+/g, "-")}` : void 0);
|
|
8
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 7 }, children: [
|
|
9
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: selId, style: { fontSize: 13, fontWeight: 600, color: "var(--dt-muted-strong)" }, children: label }) : null,
|
|
10
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", display: "flex" }, children: [
|
|
11
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
12
|
+
"select",
|
|
13
|
+
{
|
|
14
|
+
id: selId,
|
|
15
|
+
className: "dt-field",
|
|
16
|
+
value,
|
|
17
|
+
defaultValue,
|
|
18
|
+
disabled,
|
|
19
|
+
onChange: (e) => onChange?.(e.target.value),
|
|
20
|
+
style: {
|
|
21
|
+
appearance: "none",
|
|
22
|
+
WebkitAppearance: "none",
|
|
23
|
+
width: "100%",
|
|
24
|
+
padding: "10px 36px 10px 13px",
|
|
25
|
+
fontSize: 14,
|
|
26
|
+
fontFamily: "inherit",
|
|
27
|
+
color: "var(--dt-ink-strong)",
|
|
28
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
29
|
+
opacity: disabled ? 0.55 : 1,
|
|
30
|
+
...style
|
|
31
|
+
},
|
|
32
|
+
children: [
|
|
33
|
+
placeholder ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }) : null,
|
|
34
|
+
options.map((o) => {
|
|
35
|
+
const opt = typeof o === "string" ? { value: o, label: o } : o;
|
|
36
|
+
return /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.value, children: opt.label }, opt.value);
|
|
37
|
+
})
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
),
|
|
41
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
42
|
+
"svg",
|
|
43
|
+
{
|
|
44
|
+
width: "16",
|
|
45
|
+
height: "16",
|
|
46
|
+
viewBox: "0 0 24 24",
|
|
47
|
+
fill: "none",
|
|
48
|
+
"aria-hidden": "true",
|
|
49
|
+
style: {
|
|
50
|
+
position: "absolute",
|
|
51
|
+
right: 11,
|
|
52
|
+
top: "50%",
|
|
53
|
+
transform: "translateY(-50%)",
|
|
54
|
+
pointerEvents: "none",
|
|
55
|
+
color: "var(--dt-muted)"
|
|
56
|
+
},
|
|
57
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
] }),
|
|
61
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "var(--dt-muted)" }, children: hint }) : null
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
exports.Select = Select;
|
|
66
|
+
//# sourceMappingURL=Select.cjs.map
|
|
67
|
+
//# sourceMappingURL=Select.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/Select.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"Select.cjs","sourcesContent":["import type { CSSProperties, SelectHTMLAttributes } from 'react';\n\nexport interface SelectOption {\n value: string;\n label: string;\n}\n\nexport interface SelectProps\n extends Omit<\n SelectHTMLAttributes<HTMLSelectElement>,\n 'defaultValue' | 'disabled' | 'id' | 'onChange' | 'style' | 'value'\n > {\n label?: string;\n hint?: string;\n options?: Array<string | SelectOption>;\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n id?: string;\n style?: CSSProperties;\n}\n\n/** Flat native-backed select with a persimmon focus ring. */\nexport function Select({ label, hint, options = [], value, defaultValue, onChange, placeholder, disabled, id, style }: SelectProps) {\n const selId = id || (label ? `sel-${label.replace(/\\s+/g, '-')}` : undefined);\n return (\n <div style={{ display: 'grid', gap: 7 }}>\n {label ? (\n <label htmlFor={selId} style={{ fontSize: 13, fontWeight: 600, color: 'var(--dt-muted-strong)' }}>\n {label}\n </label>\n ) : null}\n <div style={{ position: 'relative', display: 'flex' }}>\n <select\n id={selId}\n className=\"dt-field\"\n value={value}\n defaultValue={defaultValue}\n disabled={disabled}\n onChange={(e) => onChange?.(e.target.value)}\n style={{\n appearance: 'none',\n WebkitAppearance: 'none',\n width: '100%',\n padding: '10px 36px 10px 13px',\n fontSize: 14,\n fontFamily: 'inherit',\n color: 'var(--dt-ink-strong)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.55 : 1,\n ...style,\n }}\n >\n {placeholder ? (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n ) : null}\n {options.map((o) => {\n const opt = typeof o === 'string' ? { value: o, label: o } : o;\n return (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n );\n })}\n </select>\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n right: 11,\n top: '50%',\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n color: 'var(--dt-muted)',\n }}\n >\n <path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n {hint ? <span style={{ fontSize: 12, color: 'var(--dt-muted)' }}>{hint}</span> : null}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { SelectHTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface SelectOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'defaultValue' | 'disabled' | 'id' | 'onChange' | 'style' | 'value'> {
|
|
9
|
+
label?: string;
|
|
10
|
+
hint?: string;
|
|
11
|
+
options?: Array<string | SelectOption>;
|
|
12
|
+
value?: string;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
onChange?: (value: string) => void;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
id?: string;
|
|
18
|
+
style?: CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
/** Flat native-backed select with a persimmon focus ring. */
|
|
21
|
+
declare function Select({ label, hint, options, value, defaultValue, onChange, placeholder, disabled, id, style }: SelectProps): react.JSX.Element;
|
|
22
|
+
|
|
23
|
+
export { Select, type SelectOption, type SelectProps };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { SelectHTMLAttributes, CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
interface SelectOption {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'defaultValue' | 'disabled' | 'id' | 'onChange' | 'style' | 'value'> {
|
|
9
|
+
label?: string;
|
|
10
|
+
hint?: string;
|
|
11
|
+
options?: Array<string | SelectOption>;
|
|
12
|
+
value?: string;
|
|
13
|
+
defaultValue?: string;
|
|
14
|
+
onChange?: (value: string) => void;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
id?: string;
|
|
18
|
+
style?: CSSProperties;
|
|
19
|
+
}
|
|
20
|
+
/** Flat native-backed select with a persimmon focus ring. */
|
|
21
|
+
declare function Select({ label, hint, options, value, defaultValue, onChange, placeholder, disabled, id, style }: SelectProps): react.JSX.Element;
|
|
22
|
+
|
|
23
|
+
export { Select, type SelectOption, type SelectProps };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
// src/components/forms/Select.tsx
|
|
4
|
+
function Select({ label, hint, options = [], value, defaultValue, onChange, placeholder, disabled, id, style }) {
|
|
5
|
+
const selId = id || (label ? `sel-${label.replace(/\s+/g, "-")}` : void 0);
|
|
6
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 7 }, children: [
|
|
7
|
+
label ? /* @__PURE__ */ jsx("label", { htmlFor: selId, style: { fontSize: 13, fontWeight: 600, color: "var(--dt-muted-strong)" }, children: label }) : null,
|
|
8
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative", display: "flex" }, children: [
|
|
9
|
+
/* @__PURE__ */ jsxs(
|
|
10
|
+
"select",
|
|
11
|
+
{
|
|
12
|
+
id: selId,
|
|
13
|
+
className: "dt-field",
|
|
14
|
+
value,
|
|
15
|
+
defaultValue,
|
|
16
|
+
disabled,
|
|
17
|
+
onChange: (e) => onChange?.(e.target.value),
|
|
18
|
+
style: {
|
|
19
|
+
appearance: "none",
|
|
20
|
+
WebkitAppearance: "none",
|
|
21
|
+
width: "100%",
|
|
22
|
+
padding: "10px 36px 10px 13px",
|
|
23
|
+
fontSize: 14,
|
|
24
|
+
fontFamily: "inherit",
|
|
25
|
+
color: "var(--dt-ink-strong)",
|
|
26
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
27
|
+
opacity: disabled ? 0.55 : 1,
|
|
28
|
+
...style
|
|
29
|
+
},
|
|
30
|
+
children: [
|
|
31
|
+
placeholder ? /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }) : null,
|
|
32
|
+
options.map((o) => {
|
|
33
|
+
const opt = typeof o === "string" ? { value: o, label: o } : o;
|
|
34
|
+
return /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value);
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
),
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
"svg",
|
|
41
|
+
{
|
|
42
|
+
width: "16",
|
|
43
|
+
height: "16",
|
|
44
|
+
viewBox: "0 0 24 24",
|
|
45
|
+
fill: "none",
|
|
46
|
+
"aria-hidden": "true",
|
|
47
|
+
style: {
|
|
48
|
+
position: "absolute",
|
|
49
|
+
right: 11,
|
|
50
|
+
top: "50%",
|
|
51
|
+
transform: "translateY(-50%)",
|
|
52
|
+
pointerEvents: "none",
|
|
53
|
+
color: "var(--dt-muted)"
|
|
54
|
+
},
|
|
55
|
+
children: /* @__PURE__ */ jsx("path", { d: "M6 9l6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
] }),
|
|
59
|
+
hint ? /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "var(--dt-muted)" }, children: hint }) : null
|
|
60
|
+
] });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { Select };
|
|
64
|
+
//# sourceMappingURL=Select.mjs.map
|
|
65
|
+
//# sourceMappingURL=Select.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/Select.tsx"],"names":[],"mappings":"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","file":"Select.mjs","sourcesContent":["import type { CSSProperties, SelectHTMLAttributes } from 'react';\n\nexport interface SelectOption {\n value: string;\n label: string;\n}\n\nexport interface SelectProps\n extends Omit<\n SelectHTMLAttributes<HTMLSelectElement>,\n 'defaultValue' | 'disabled' | 'id' | 'onChange' | 'style' | 'value'\n > {\n label?: string;\n hint?: string;\n options?: Array<string | SelectOption>;\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n placeholder?: string;\n disabled?: boolean;\n id?: string;\n style?: CSSProperties;\n}\n\n/** Flat native-backed select with a persimmon focus ring. */\nexport function Select({ label, hint, options = [], value, defaultValue, onChange, placeholder, disabled, id, style }: SelectProps) {\n const selId = id || (label ? `sel-${label.replace(/\\s+/g, '-')}` : undefined);\n return (\n <div style={{ display: 'grid', gap: 7 }}>\n {label ? (\n <label htmlFor={selId} style={{ fontSize: 13, fontWeight: 600, color: 'var(--dt-muted-strong)' }}>\n {label}\n </label>\n ) : null}\n <div style={{ position: 'relative', display: 'flex' }}>\n <select\n id={selId}\n className=\"dt-field\"\n value={value}\n defaultValue={defaultValue}\n disabled={disabled}\n onChange={(e) => onChange?.(e.target.value)}\n style={{\n appearance: 'none',\n WebkitAppearance: 'none',\n width: '100%',\n padding: '10px 36px 10px 13px',\n fontSize: 14,\n fontFamily: 'inherit',\n color: 'var(--dt-ink-strong)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.55 : 1,\n ...style,\n }}\n >\n {placeholder ? (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n ) : null}\n {options.map((o) => {\n const opt = typeof o === 'string' ? { value: o, label: o } : o;\n return (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n );\n })}\n </select>\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n right: 11,\n top: '50%',\n transform: 'translateY(-50%)',\n pointerEvents: 'none',\n color: 'var(--dt-muted)',\n }}\n >\n <path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n {hint ? <span style={{ fontSize: 12, color: 'var(--dt-muted)' }}>{hint}</span> : null}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/components/forms/Slider.tsx
|
|
7
|
+
function Slider({
|
|
8
|
+
label,
|
|
9
|
+
min = 0,
|
|
10
|
+
max = 100,
|
|
11
|
+
step = 1,
|
|
12
|
+
value,
|
|
13
|
+
defaultValue,
|
|
14
|
+
onChange,
|
|
15
|
+
unit = "",
|
|
16
|
+
hint,
|
|
17
|
+
id,
|
|
18
|
+
style
|
|
19
|
+
}) {
|
|
20
|
+
const [internal, setInternal] = react.useState(defaultValue ?? min);
|
|
21
|
+
const v = value != null ? value : internal;
|
|
22
|
+
const trackRef = react.useRef(null);
|
|
23
|
+
const sId = id || (label ? `sl-${label.replace(/\s+/g, "-")}` : void 0);
|
|
24
|
+
const pct = (v - min) / (max - min) * 100;
|
|
25
|
+
const set = (nv) => {
|
|
26
|
+
const clamped = Math.min(max, Math.max(min, Math.round(nv / step) * step));
|
|
27
|
+
if (value == null) setInternal(clamped);
|
|
28
|
+
onChange?.(clamped);
|
|
29
|
+
};
|
|
30
|
+
const fromClientX = (clientX) => {
|
|
31
|
+
const r = trackRef.current.getBoundingClientRect();
|
|
32
|
+
const ratio = Math.min(1, Math.max(0, (clientX - r.left) / r.width));
|
|
33
|
+
return min + ratio * (max - min);
|
|
34
|
+
};
|
|
35
|
+
const onPointerDown = (e) => {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
set(fromClientX(e.clientX));
|
|
38
|
+
const move = (ev) => set(fromClientX(ev.clientX));
|
|
39
|
+
const up = () => {
|
|
40
|
+
window.removeEventListener("pointermove", move);
|
|
41
|
+
window.removeEventListener("pointerup", up);
|
|
42
|
+
};
|
|
43
|
+
window.addEventListener("pointermove", move);
|
|
44
|
+
window.addEventListener("pointerup", up);
|
|
45
|
+
};
|
|
46
|
+
const onKey = (e) => {
|
|
47
|
+
if (e.key === "ArrowRight" || e.key === "ArrowUp") {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
set(v + step);
|
|
50
|
+
} else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
set(v - step);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 9, ...style }, children: [
|
|
56
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "baseline", justifyContent: "space-between" }, children: [
|
|
57
|
+
label ? /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: sId, style: { fontSize: 13, fontWeight: 600, color: "var(--dt-muted-strong)" }, children: label }) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
59
|
+
"span",
|
|
60
|
+
{
|
|
61
|
+
style: {
|
|
62
|
+
fontFamily: "var(--dt-font-mono)",
|
|
63
|
+
fontSize: 13,
|
|
64
|
+
fontWeight: 600,
|
|
65
|
+
color: "var(--dt-ink-strong)",
|
|
66
|
+
fontVariantNumeric: "tabular-nums"
|
|
67
|
+
},
|
|
68
|
+
children: [
|
|
69
|
+
v,
|
|
70
|
+
unit ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--dt-muted)", fontWeight: 400 }, children: unit }) : null
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
)
|
|
74
|
+
] }),
|
|
75
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
ref: trackRef,
|
|
79
|
+
id: sId,
|
|
80
|
+
role: "slider",
|
|
81
|
+
tabIndex: 0,
|
|
82
|
+
"aria-valuemin": min,
|
|
83
|
+
"aria-valuemax": max,
|
|
84
|
+
"aria-valuenow": v,
|
|
85
|
+
onPointerDown,
|
|
86
|
+
onKeyDown: onKey,
|
|
87
|
+
style: { position: "relative", height: 20, display: "flex", alignItems: "center", cursor: "pointer", outline: "none" },
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
90
|
+
"div",
|
|
91
|
+
{
|
|
92
|
+
style: {
|
|
93
|
+
position: "absolute",
|
|
94
|
+
left: 0,
|
|
95
|
+
right: 0,
|
|
96
|
+
height: 4,
|
|
97
|
+
borderRadius: 2,
|
|
98
|
+
background: "var(--dt-surface-sunken)",
|
|
99
|
+
boxShadow: "inset 0 0 0 1px var(--dt-border-strong)"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
),
|
|
103
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", left: 0, width: `${pct}%`, height: 4, borderRadius: 2, background: "var(--dt-accent)" } }),
|
|
104
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
105
|
+
"div",
|
|
106
|
+
{
|
|
107
|
+
style: {
|
|
108
|
+
position: "absolute",
|
|
109
|
+
left: `${pct}%`,
|
|
110
|
+
transform: "translateX(-50%)",
|
|
111
|
+
width: 16,
|
|
112
|
+
height: 16,
|
|
113
|
+
borderRadius: "var(--dt-radius-sm)",
|
|
114
|
+
background: "var(--dt-surface)",
|
|
115
|
+
boxShadow: "0 0 0 1.5px var(--dt-accent)",
|
|
116
|
+
border: "3px solid var(--dt-surface)"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
),
|
|
123
|
+
hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "var(--dt-muted)" }, children: hint }) : null
|
|
124
|
+
] });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
exports.Slider = Slider;
|
|
128
|
+
//# sourceMappingURL=Slider.cjs.map
|
|
129
|
+
//# sourceMappingURL=Slider.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/forms/Slider.tsx"],"names":["useState","useRef","jsxs","jsx"],"mappings":"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","file":"Slider.cjs","sourcesContent":["import { useRef, useState } from 'react';\nimport type { CSSProperties, InputHTMLAttributes, KeyboardEvent, PointerEvent } from 'react';\n\nexport interface SliderProps\n extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'defaultValue' | 'id' | 'max' | 'min' | 'onChange' | 'step' | 'style' | 'value'\n > {\n label?: string;\n min?: number;\n max?: number;\n step?: number;\n value?: number;\n defaultValue?: number;\n onChange?: (value: number) => void;\n /** Suffix shown after the value readout, e.g. \"회/일\" or \"ms\". */\n unit?: string;\n hint?: string;\n id?: string;\n style?: CSSProperties;\n}\n\n/**\n * Numeric range input — hairline track, persimmon fill, tabular value readout.\n * @startingPoint section=\"Forms\" subtitle=\"Numeric range with tabular readout\" viewport=\"420x90\"\n */\nexport function Slider({\n label,\n min = 0,\n max = 100,\n step = 1,\n value,\n defaultValue,\n onChange,\n unit = '',\n hint,\n id,\n style,\n}: SliderProps) {\n const [internal, setInternal] = useState(defaultValue ?? min);\n const v = value != null ? value : internal;\n const trackRef = useRef<HTMLDivElement>(null);\n const sId = id || (label ? `sl-${label.replace(/\\s+/g, '-')}` : undefined);\n const pct = ((v - min) / (max - min)) * 100;\n\n const set = (nv: number) => {\n const clamped = Math.min(max, Math.max(min, Math.round(nv / step) * step));\n if (value == null) setInternal(clamped);\n onChange?.(clamped);\n };\n\n const fromClientX = (clientX: number) => {\n const r = trackRef.current!.getBoundingClientRect();\n const ratio = Math.min(1, Math.max(0, (clientX - r.left) / r.width));\n return min + ratio * (max - min);\n };\n\n const onPointerDown = (e: PointerEvent<HTMLDivElement>) => {\n e.preventDefault();\n set(fromClientX(e.clientX));\n const move = (ev: globalThis.PointerEvent) => set(fromClientX(ev.clientX));\n const up = () => {\n window.removeEventListener('pointermove', move);\n window.removeEventListener('pointerup', up);\n };\n window.addEventListener('pointermove', move);\n window.addEventListener('pointerup', up);\n };\n\n const onKey = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'ArrowRight' || e.key === 'ArrowUp') {\n e.preventDefault();\n set(v + step);\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowDown') {\n e.preventDefault();\n set(v - step);\n }\n };\n\n return (\n <div style={{ display: 'grid', gap: 9, ...style }}>\n <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between' }}>\n {label ? (\n <label htmlFor={sId} style={{ fontSize: 13, fontWeight: 600, color: 'var(--dt-muted-strong)' }}>\n {label}\n </label>\n ) : (\n <span />\n )}\n <span\n style={{\n fontFamily: 'var(--dt-font-mono)',\n fontSize: 13,\n fontWeight: 600,\n color: 'var(--dt-ink-strong)',\n fontVariantNumeric: 'tabular-nums',\n }}\n >\n {v}\n {unit ? <span style={{ color: 'var(--dt-muted)', fontWeight: 400 }}>{unit}</span> : null}\n </span>\n </div>\n <div\n ref={trackRef}\n id={sId}\n role=\"slider\"\n tabIndex={0}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={v}\n onPointerDown={onPointerDown}\n onKeyDown={onKey}\n style={{ position: 'relative', height: 20, display: 'flex', alignItems: 'center', cursor: 'pointer', outline: 'none' }}\n >\n <div\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n height: 4,\n borderRadius: 2,\n background: 'var(--dt-surface-sunken)',\n boxShadow: 'inset 0 0 0 1px var(--dt-border-strong)',\n }}\n />\n <div style={{ position: 'absolute', left: 0, width: `${pct}%`, height: 4, borderRadius: 2, background: 'var(--dt-accent)' }} />\n <div\n style={{\n position: 'absolute',\n left: `${pct}%`,\n transform: 'translateX(-50%)',\n width: 16,\n height: 16,\n borderRadius: 'var(--dt-radius-sm)',\n background: 'var(--dt-surface)',\n boxShadow: '0 0 0 1.5px var(--dt-accent)',\n border: '3px solid var(--dt-surface)',\n }}\n />\n </div>\n {hint ? <span style={{ fontSize: 12, color: 'var(--dt-muted)' }}>{hint}</span> : null}\n </div>\n );\n}\n"]}
|