@fangxinyan/lumina 0.4.0 → 0.5.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.
@@ -0,0 +1,257 @@
1
+ 'use strict';
2
+
3
+ require('./tokens-BIIUTPKN.css');
4
+ require('./shared-NJHRNLRH.css');
5
+ require('./Slider-3JKA5EW6.css');
6
+ var React = require('react');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
+
29
+ // src/components/Slider/Slider.tsx
30
+ function clamp(v, lo, hi) {
31
+ return Math.max(lo, Math.min(hi, v));
32
+ }
33
+ function snap(raw, step, min) {
34
+ return Math.round((raw - min) / step) * step + min;
35
+ }
36
+ function lerpColor(colors, t) {
37
+ const pos = Math.max(0, Math.min(1, t)) * (colors.length - 1);
38
+ const i = Math.min(Math.floor(pos), colors.length - 2);
39
+ const frac = pos - i;
40
+ if (frac === 0) return colors[i];
41
+ return `color-mix(in oklch, ${colors[i + 1]} ${Math.round(frac * 100)}%, ${colors[i]})`;
42
+ }
43
+ var Slider = React__namespace.forwardRef(
44
+ (props, ref) => {
45
+ const {
46
+ min = 0,
47
+ max = 100,
48
+ step = 1,
49
+ disabled,
50
+ showValue,
51
+ tone = "accent",
52
+ colors,
53
+ marks,
54
+ className = ""
55
+ } = props;
56
+ const range = props.range === true;
57
+ const controlled = props.value;
58
+ const defaultVal = props.defaultValue;
59
+ const onChange = props.onChange;
60
+ const initRef = React__namespace.useRef(
61
+ defaultVal !== void 0 ? Array.isArray(defaultVal) ? [...defaultVal] : [defaultVal] : range ? [min, max] : [min]
62
+ );
63
+ const [inner, setInner] = React__namespace.useState(initRef.current);
64
+ const isControlled = controlled !== void 0;
65
+ const vals = isControlled ? Array.isArray(controlled) ? controlled : [controlled] : inner;
66
+ const valsRef = React__namespace.useRef(vals);
67
+ valsRef.current = vals;
68
+ const trackRef = React__namespace.useRef(null);
69
+ const thumbEls = React__namespace.useRef([]);
70
+ const dragging = React__namespace.useRef(null);
71
+ const pct = (n) => (n - min) / (max - min) * 100;
72
+ const commit = React__namespace.useCallback(
73
+ (next) => {
74
+ if (!isControlled) setInner(next);
75
+ if (range) {
76
+ onChange?.([next[0], next[1]]);
77
+ } else {
78
+ onChange?.(next[0]);
79
+ }
80
+ },
81
+ [isControlled, range, onChange]
82
+ );
83
+ const setAt = React__namespace.useCallback(
84
+ (index, raw) => {
85
+ const snapped = snap(clamp(raw, min, max), step, min);
86
+ const clamped = clamp(snapped, min, max);
87
+ const out = [...valsRef.current];
88
+ out[index] = clamped;
89
+ if (range && out.length === 2 && out[0] > out[1]) out.sort((a, b) => a - b);
90
+ commit(out);
91
+ },
92
+ [min, max, step, range, commit]
93
+ );
94
+ const valFromX = React__namespace.useCallback(
95
+ (clientX) => {
96
+ const rect = trackRef.current?.getBoundingClientRect();
97
+ if (!rect) return min;
98
+ const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);
99
+ return min + ratio * (max - min);
100
+ },
101
+ [min, max]
102
+ );
103
+ const closerIndex = React__namespace.useCallback(
104
+ (target) => {
105
+ const v = valsRef.current;
106
+ if (!range || v.length < 2) return 0;
107
+ const d0 = Math.abs(v[0] - target);
108
+ const d1 = Math.abs(v[1] - target);
109
+ if (d0 === d1) return target < v[0] ? 0 : 1;
110
+ return d0 < d1 ? 0 : 1;
111
+ },
112
+ [range]
113
+ );
114
+ const onPointerDown = React__namespace.useCallback(
115
+ (e) => {
116
+ if (disabled) return;
117
+ e.preventDefault();
118
+ const val = valFromX(e.clientX);
119
+ const idx = closerIndex(val);
120
+ dragging.current = idx;
121
+ setAt(idx, val);
122
+ trackRef.current?.setPointerCapture(e.pointerId);
123
+ thumbEls.current[idx]?.focus();
124
+ },
125
+ [disabled, valFromX, closerIndex, setAt]
126
+ );
127
+ const onPointerMove = React__namespace.useCallback(
128
+ (e) => {
129
+ if (dragging.current === null) return;
130
+ setAt(dragging.current, valFromX(e.clientX));
131
+ },
132
+ [valFromX, setAt]
133
+ );
134
+ const onPointerUp = React__namespace.useCallback(() => {
135
+ dragging.current = null;
136
+ }, []);
137
+ const handleKey = React__namespace.useCallback(
138
+ (index, e) => {
139
+ if (disabled) return;
140
+ let delta = 0;
141
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") delta = step;
142
+ else if (e.key === "ArrowLeft" || e.key === "ArrowDown") delta = -step;
143
+ else if (e.key === "Home") {
144
+ setAt(index, min);
145
+ return;
146
+ } else if (e.key === "End") {
147
+ setAt(index, max);
148
+ return;
149
+ } else return;
150
+ e.preventDefault();
151
+ setAt(index, valsRef.current[index] + delta);
152
+ },
153
+ [disabled, step, min, max, setAt]
154
+ );
155
+ const handleMarkClick = React__namespace.useCallback(
156
+ (mark) => {
157
+ if (disabled) return;
158
+ setAt(closerIndex(mark), mark);
159
+ },
160
+ [disabled, closerIndex, setAt]
161
+ );
162
+ const fillLeft = range ? pct(Math.min(vals[0], vals[1])) : 0;
163
+ const fillRight = range ? 100 - pct(Math.max(vals[0], vals[1])) : 100 - pct(vals[0]);
164
+ const hasGradient = colors && colors.length >= 2;
165
+ const fillStyle = {
166
+ left: `${fillLeft}%`,
167
+ right: `${fillRight}%`
168
+ };
169
+ if (hasGradient) {
170
+ const w = 100 - fillLeft - fillRight;
171
+ if (w > 0) {
172
+ const stops = colors.map((c, i) => {
173
+ const orig = i / (colors.length - 1) * 100;
174
+ return `${c} ${((orig - fillLeft) / w * 100).toFixed(2)}%`;
175
+ }).join(", ");
176
+ fillStyle.background = `linear-gradient(to right, ${stops})`;
177
+ fillStyle.boxShadow = "none";
178
+ }
179
+ }
180
+ return /* @__PURE__ */ jsxRuntime.jsxs(
181
+ "div",
182
+ {
183
+ ref,
184
+ className: `slider ${range ? "range" : ""} ${hasGradient ? "gradient" : tone} ${disabled ? "disabled" : ""} ${marks ? "has-marks" : ""} ${className}`,
185
+ children: [
186
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "slider-rail", children: [
187
+ /* @__PURE__ */ jsxRuntime.jsx(
188
+ "div",
189
+ {
190
+ className: "slider-track",
191
+ ref: trackRef,
192
+ onPointerDown,
193
+ onPointerMove,
194
+ onPointerUp,
195
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "slider-fill", style: fillStyle })
196
+ }
197
+ ),
198
+ vals.map((n, i) => {
199
+ const thumbStyle = { left: `${pct(n)}%` };
200
+ if (hasGradient) {
201
+ thumbStyle["--slider-thumb-color"] = lerpColor(colors, (n - min) / (max - min));
202
+ }
203
+ return /* @__PURE__ */ jsxRuntime.jsx(
204
+ "div",
205
+ {
206
+ ref: (el) => {
207
+ thumbEls.current[i] = el;
208
+ },
209
+ className: "slider-thumb",
210
+ style: thumbStyle,
211
+ role: "slider",
212
+ tabIndex: disabled ? -1 : 0,
213
+ "aria-valuemin": min,
214
+ "aria-valuemax": max,
215
+ "aria-valuenow": n,
216
+ "aria-disabled": disabled || void 0,
217
+ onKeyDown: (e) => handleKey(i, e),
218
+ onPointerDown: (e) => {
219
+ if (disabled) return;
220
+ e.preventDefault();
221
+ e.stopPropagation();
222
+ dragging.current = i;
223
+ trackRef.current?.setPointerCapture(e.pointerId);
224
+ e.currentTarget.focus();
225
+ }
226
+ },
227
+ i
228
+ );
229
+ }),
230
+ marks && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "slider-marks", children: Object.entries(marks).map(([k, label]) => {
231
+ const n = Number(k);
232
+ const active = range ? n >= Math.min(vals[0], vals[1]) && n <= Math.max(vals[0], vals[1]) : n <= vals[0];
233
+ return /* @__PURE__ */ jsxRuntime.jsxs(
234
+ "span",
235
+ {
236
+ className: `slider-mark ${active ? "active" : ""}`,
237
+ style: { left: `${pct(n)}%` },
238
+ onClick: () => handleMarkClick(n),
239
+ children: [
240
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "slider-mark-dot" }),
241
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "slider-mark-label", children: label })
242
+ ]
243
+ },
244
+ k
245
+ );
246
+ }) })
247
+ ] }),
248
+ showValue && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "slider-value", children: range ? `${vals[0]} \u2013 ${vals[1]}` : vals[0] })
249
+ ]
250
+ }
251
+ );
252
+ }
253
+ );
254
+
255
+ exports.Slider = Slider;
256
+ //# sourceMappingURL=chunk-N6ZLZUBF.cjs.map
257
+ //# sourceMappingURL=chunk-N6ZLZUBF.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Slider/Slider.tsx"],"names":["React","jsxs","jsx"],"mappings":"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","file":"chunk-N6ZLZUBF.cjs","sourcesContent":["import \"../../styles/tokens.css\";\nimport \"../../styles/shared.css\";\nimport \"./Slider.css\";\nimport * as React from \"react\";\n\nexport type SliderRangeValue = [number, number];\nexport type SliderValue = number | SliderRangeValue;\n\ninterface SliderBaseProps {\n min?: number;\n max?: number;\n step?: number;\n disabled?: boolean;\n showValue?: boolean;\n tone?: \"accent\" | \"success\" | \"warning\" | \"danger\";\n /** Custom gradient colors mapped from min→max. Overrides `tone` for fill & thumb. */\n colors?: string[];\n /** Tick marks with labels. Clicking a mark snaps to it. */\n marks?: Record<number, React.ReactNode>;\n className?: string;\n}\n\nexport interface SliderSingleProps extends SliderBaseProps {\n range?: false;\n value?: number;\n defaultValue?: number;\n onChange?: (value: number) => void;\n}\n\nexport interface SliderRangeProps extends SliderBaseProps {\n range: true;\n value?: SliderRangeValue;\n defaultValue?: SliderRangeValue;\n onChange?: (value: SliderRangeValue) => void;\n}\n\nexport type SliderProps = SliderSingleProps | SliderRangeProps;\n\nfunction clamp(v: number, lo: number, hi: number) {\n return Math.max(lo, Math.min(hi, v));\n}\n\nfunction snap(raw: number, step: number, min: number) {\n return Math.round((raw - min) / step) * step + min;\n}\n\nfunction lerpColor(colors: string[], t: number): string {\n const pos = Math.max(0, Math.min(1, t)) * (colors.length - 1);\n const i = Math.min(Math.floor(pos), colors.length - 2);\n const frac = pos - i;\n if (frac === 0) return colors[i];\n return `color-mix(in oklch, ${colors[i + 1]} ${Math.round(frac * 100)}%, ${colors[i]})`;\n}\n\n/** `Slider` — neumorphic range input with grooved track.\n * @example <Slider defaultValue={40} showValue />\n */\nexport const Slider = React.forwardRef<HTMLDivElement, SliderProps>(\n (props, ref) => {\n const {\n min = 0,\n max = 100,\n step = 1,\n disabled,\n showValue,\n tone = \"accent\",\n colors,\n marks,\n className = \"\",\n } = props;\n\n const range = (props as SliderRangeProps).range === true;\n const controlled = (props as { value?: SliderValue }).value;\n const defaultVal = (props as { defaultValue?: SliderValue }).defaultValue;\n const onChange = (props as { onChange?: (v: any) => void }).onChange;\n\n const initRef = React.useRef<number[]>(\n defaultVal !== undefined\n ? Array.isArray(defaultVal)\n ? [...defaultVal]\n : [defaultVal]\n : range\n ? [min, max]\n : [min]\n );\n const [inner, setInner] = React.useState<number[]>(initRef.current);\n\n const isControlled = controlled !== undefined;\n const vals = isControlled\n ? Array.isArray(controlled)\n ? controlled\n : [controlled]\n : inner;\n\n const valsRef = React.useRef(vals);\n valsRef.current = vals;\n\n const trackRef = React.useRef<HTMLDivElement>(null);\n const thumbEls = React.useRef<(HTMLDivElement | null)[]>([]);\n const dragging = React.useRef<number | null>(null);\n\n const pct = (n: number) => ((n - min) / (max - min)) * 100;\n\n const commit = React.useCallback(\n (next: number[]) => {\n if (!isControlled) setInner(next);\n if (range) {\n onChange?.([next[0], next[1]] as SliderRangeValue);\n } else {\n onChange?.(next[0]);\n }\n },\n [isControlled, range, onChange]\n );\n\n const setAt = React.useCallback(\n (index: number, raw: number) => {\n const snapped = snap(clamp(raw, min, max), step, min);\n const clamped = clamp(snapped, min, max);\n const out = [...valsRef.current];\n out[index] = clamped;\n if (range && out.length === 2 && out[0] > out[1]) out.sort((a, b) => a - b);\n commit(out);\n },\n [min, max, step, range, commit]\n );\n\n const valFromX = React.useCallback(\n (clientX: number) => {\n const rect = trackRef.current?.getBoundingClientRect();\n if (!rect) return min;\n const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);\n return min + ratio * (max - min);\n },\n [min, max]\n );\n\n const closerIndex = React.useCallback(\n (target: number) => {\n const v = valsRef.current;\n if (!range || v.length < 2) return 0;\n const d0 = Math.abs(v[0] - target);\n const d1 = Math.abs(v[1] - target);\n if (d0 === d1) return target < v[0] ? 0 : 1;\n return d0 < d1 ? 0 : 1;\n },\n [range]\n );\n\n const onPointerDown = React.useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.preventDefault();\n const val = valFromX(e.clientX);\n const idx = closerIndex(val);\n dragging.current = idx;\n setAt(idx, val);\n trackRef.current?.setPointerCapture(e.pointerId);\n thumbEls.current[idx]?.focus();\n },\n [disabled, valFromX, closerIndex, setAt]\n );\n\n const onPointerMove = React.useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (dragging.current === null) return;\n setAt(dragging.current, valFromX(e.clientX));\n },\n [valFromX, setAt]\n );\n\n const onPointerUp = React.useCallback(() => {\n dragging.current = null;\n }, []);\n\n const handleKey = React.useCallback(\n (index: number, e: React.KeyboardEvent) => {\n if (disabled) return;\n let delta = 0;\n if (e.key === \"ArrowRight\" || e.key === \"ArrowUp\") delta = step;\n else if (e.key === \"ArrowLeft\" || e.key === \"ArrowDown\") delta = -step;\n else if (e.key === \"Home\") { setAt(index, min); return; }\n else if (e.key === \"End\") { setAt(index, max); return; }\n else return;\n e.preventDefault();\n setAt(index, valsRef.current[index] + delta);\n },\n [disabled, step, min, max, setAt]\n );\n\n const handleMarkClick = React.useCallback(\n (mark: number) => {\n if (disabled) return;\n setAt(closerIndex(mark), mark);\n },\n [disabled, closerIndex, setAt]\n );\n\n const fillLeft = range ? pct(Math.min(vals[0], vals[1])) : 0;\n const fillRight = range\n ? 100 - pct(Math.max(vals[0], vals[1]))\n : 100 - pct(vals[0]);\n\n const hasGradient = colors && colors.length >= 2;\n\n const fillStyle: React.CSSProperties = {\n left: `${fillLeft}%`,\n right: `${fillRight}%`,\n };\n if (hasGradient) {\n const w = 100 - fillLeft - fillRight;\n if (w > 0) {\n const stops = colors.map((c, i) => {\n const orig = (i / (colors.length - 1)) * 100;\n return `${c} ${((orig - fillLeft) / w * 100).toFixed(2)}%`;\n }).join(\", \");\n fillStyle.background = `linear-gradient(to right, ${stops})`;\n fillStyle.boxShadow = \"none\";\n }\n }\n\n return (\n <div\n ref={ref}\n className={`slider ${range ? \"range\" : \"\"} ${hasGradient ? \"gradient\" : tone} ${disabled ? \"disabled\" : \"\"} ${marks ? \"has-marks\" : \"\"} ${className}`}\n >\n <div className=\"slider-rail\">\n <div\n className=\"slider-track\"\n ref={trackRef}\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={onPointerUp}\n >\n <div className=\"slider-fill\" style={fillStyle} />\n </div>\n\n {vals.map((n, i) => {\n const thumbStyle: React.CSSProperties = { left: `${pct(n)}%` };\n if (hasGradient) {\n (thumbStyle as any)[\"--slider-thumb-color\"] = lerpColor(colors, (n - min) / (max - min));\n }\n return (\n <div\n key={i}\n ref={(el) => { thumbEls.current[i] = el; }}\n className=\"slider-thumb\"\n style={thumbStyle}\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={n}\n aria-disabled={disabled || undefined}\n onKeyDown={(e) => handleKey(i, e)}\n onPointerDown={(e) => {\n if (disabled) return;\n e.preventDefault();\n e.stopPropagation();\n dragging.current = i;\n trackRef.current?.setPointerCapture(e.pointerId);\n e.currentTarget.focus();\n }}\n />\n );\n })}\n\n {marks && (\n <div className=\"slider-marks\">\n {Object.entries(marks).map(([k, label]) => {\n const n = Number(k);\n const active = range\n ? n >= Math.min(vals[0], vals[1]) && n <= Math.max(vals[0], vals[1])\n : n <= vals[0];\n return (\n <span\n key={k}\n className={`slider-mark ${active ? \"active\" : \"\"}`}\n style={{ left: `${pct(n)}%` }}\n onClick={() => handleMarkClick(n)}\n >\n <span className=\"slider-mark-dot\" />\n <span className=\"slider-mark-label\">{label}</span>\n </span>\n );\n })}\n </div>\n )}\n </div>\n\n {showValue && (\n <span className=\"slider-value\">\n {range ? `${vals[0]} – ${vals[1]}` : vals[0]}\n </span>\n )}\n </div>\n );\n }\n);\n"]}
package/dist/index.cjs CHANGED
@@ -11,7 +11,7 @@ var chunkO2HMH5BI_cjs = require('./chunk-O2HMH5BI.cjs');
11
11
  var chunk5BFETKVP_cjs = require('./chunk-5BFETKVP.cjs');
12
12
  var chunkT4PI2ZX7_cjs = require('./chunk-T4PI2ZX7.cjs');
13
13
  var chunkRQV7SMIZ_cjs = require('./chunk-RQV7SMIZ.cjs');
14
- var chunkB5JH7NRZ_cjs = require('./chunk-B5JH7NRZ.cjs');
14
+ var chunkN6ZLZUBF_cjs = require('./chunk-N6ZLZUBF.cjs');
15
15
  var chunk7T2SLRNL_cjs = require('./chunk-7T2SLRNL.cjs');
16
16
  var chunk7YQWG7HR_cjs = require('./chunk-7YQWG7HR.cjs');
17
17
  var chunkYZ2I7CDF_cjs = require('./chunk-YZ2I7CDF.cjs');
@@ -41,7 +41,7 @@ var chunkXYVJ3FBQ_cjs = require('./chunk-XYVJ3FBQ.cjs');
41
41
  var chunkYCHUHMNP_cjs = require('./chunk-YCHUHMNP.cjs');
42
42
 
43
43
  // src/index.ts
44
- var VERSION = "0.4.0";
44
+ var VERSION = "0.5.0";
45
45
 
46
46
  Object.defineProperty(exports, "Table", {
47
47
  enumerable: true,
@@ -157,7 +157,7 @@ Object.defineProperty(exports, "Tag", {
157
157
  });
158
158
  Object.defineProperty(exports, "Slider", {
159
159
  enumerable: true,
160
- get: function () { return chunkB5JH7NRZ_cjs.Slider; }
160
+ get: function () { return chunkN6ZLZUBF_cjs.Slider; }
161
161
  });
162
162
  Object.defineProperty(exports, "Splitter", {
163
163
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CO,IAAM,OAAA,GAAU","file":"index.cjs","sourcesContent":["/* lumina — public exports */\n\nexport * from \"./components/Icon\";\nexport * from \"./components/Button\";\nexport * from \"./components/Input\";\nexport * from \"./components/Switch\";\nexport * from \"./components/Checkbox\";\nexport * from \"./components/Slider\";\nexport * from \"./components/Select\";\nexport * from \"./components/Tabs\";\nexport * from \"./components/Accordion\";\nexport * from \"./components/Card\";\nexport * from \"./components/Tag\";\nexport * from \"./components/Avatar\";\nexport * from \"./components/Divider\";\nexport * from \"./components/Progress\";\nexport * from \"./components/Modal\";\nexport * from \"./components/Toast\";\nexport * from \"./components/Tooltip\";\nexport * from \"./components/Popover\";\nexport * from \"./components/Alert\";\nexport * from \"./components/Table\";\nexport * from \"./components/Pagination\";\nexport * from \"./components/Calendar\";\nexport * from \"./components/List\";\nexport * from \"./components/AppShell\";\nexport * from \"./components/StatusBar\";\nexport * from \"./components/Splitter\";\nexport * from \"./components/ContextMenu\";\nexport * from \"./components/CommandPalette\";\nexport * from \"./components/InputNumber\";\nexport * from \"./components/AutoComplete\";\nexport * from \"./components/Form\";\nexport * from \"./components/Empty\";\nexport * from \"./components/Image\";\nexport * from \"./components/Cascader\";\nexport * from \"./components/Typography\";\nexport * from \"./components/ColorPicker\";\nexport * from \"./components/Drawer\";\nexport * from \"./components/Theme\";\n\n/** Package version — bumped by release scripts. */\nexport const VERSION = \"0.4.0\";\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CO,IAAM,OAAA,GAAU","file":"index.cjs","sourcesContent":["/* lumina — public exports */\n\nexport * from \"./components/Icon\";\nexport * from \"./components/Button\";\nexport * from \"./components/Input\";\nexport * from \"./components/Switch\";\nexport * from \"./components/Checkbox\";\nexport * from \"./components/Slider\";\nexport * from \"./components/Select\";\nexport * from \"./components/Tabs\";\nexport * from \"./components/Accordion\";\nexport * from \"./components/Card\";\nexport * from \"./components/Tag\";\nexport * from \"./components/Avatar\";\nexport * from \"./components/Divider\";\nexport * from \"./components/Progress\";\nexport * from \"./components/Modal\";\nexport * from \"./components/Toast\";\nexport * from \"./components/Tooltip\";\nexport * from \"./components/Popover\";\nexport * from \"./components/Alert\";\nexport * from \"./components/Table\";\nexport * from \"./components/Pagination\";\nexport * from \"./components/Calendar\";\nexport * from \"./components/List\";\nexport * from \"./components/AppShell\";\nexport * from \"./components/StatusBar\";\nexport * from \"./components/Splitter\";\nexport * from \"./components/ContextMenu\";\nexport * from \"./components/CommandPalette\";\nexport * from \"./components/InputNumber\";\nexport * from \"./components/AutoComplete\";\nexport * from \"./components/Form\";\nexport * from \"./components/Empty\";\nexport * from \"./components/Image\";\nexport * from \"./components/Cascader\";\nexport * from \"./components/Typography\";\nexport * from \"./components/ColorPicker\";\nexport * from \"./components/Drawer\";\nexport * from \"./components/Theme\";\n\n/** Package version — bumped by release scripts. */\nexport const VERSION = \"0.5.0\";\n"]}
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@ export { Button, ButtonProps, ButtonSize, ButtonVariant, IconButton, IconButtonP
3
3
  export { Input, InputProps, Textarea, TextareaProps } from './Input.cjs';
4
4
  export { Switch, SwitchProps } from './Switch.cjs';
5
5
  export { Checkbox, CheckboxProps, RadioGroup, RadioGroupProps, RadioOption } from './Checkbox.cjs';
6
- export { Slider, SliderProps, SliderRangeProps, SliderRangeValue, SliderSingleProps, SliderSingleValue, SliderValue } from './Slider.cjs';
6
+ export { Slider, SliderProps, SliderRangeProps, SliderRangeValue, SliderSingleProps, SliderValue } from './Slider.cjs';
7
7
  export { MultiSelectProps, Select, SelectItem, SelectOption, SelectOptionGroup, SelectProps, SingleSelectProps } from './Select.cjs';
8
8
  export { Segmented, SegmentedProps, TabItem, Tabs, TabsProps } from './Tabs.cjs';
9
9
  export { Accordion, AccordionItem, AccordionProps } from './Accordion.cjs';
@@ -40,6 +40,6 @@ import 'react';
40
40
  import 'react/jsx-runtime';
41
41
 
42
42
  /** Package version — bumped by release scripts. */
43
- declare const VERSION = "0.4.0";
43
+ declare const VERSION = "0.5.0";
44
44
 
45
45
  export { VERSION };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { Button, ButtonProps, ButtonSize, ButtonVariant, IconButton, IconButtonP
3
3
  export { Input, InputProps, Textarea, TextareaProps } from './Input.js';
4
4
  export { Switch, SwitchProps } from './Switch.js';
5
5
  export { Checkbox, CheckboxProps, RadioGroup, RadioGroupProps, RadioOption } from './Checkbox.js';
6
- export { Slider, SliderProps, SliderRangeProps, SliderRangeValue, SliderSingleProps, SliderSingleValue, SliderValue } from './Slider.js';
6
+ export { Slider, SliderProps, SliderRangeProps, SliderRangeValue, SliderSingleProps, SliderValue } from './Slider.js';
7
7
  export { MultiSelectProps, Select, SelectItem, SelectOption, SelectOptionGroup, SelectProps, SingleSelectProps } from './Select.js';
8
8
  export { Segmented, SegmentedProps, TabItem, Tabs, TabsProps } from './Tabs.js';
9
9
  export { Accordion, AccordionItem, AccordionProps } from './Accordion.js';
@@ -40,6 +40,6 @@ import 'react';
40
40
  import 'react/jsx-runtime';
41
41
 
42
42
  /** Package version — bumped by release scripts. */
43
- declare const VERSION = "0.4.0";
43
+ declare const VERSION = "0.5.0";
44
44
 
45
45
  export { VERSION };
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ export { Popover } from './chunk-3UU2PUK4.js';
9
9
  export { Progress, Ring } from './chunk-5PREWYTB.js';
10
10
  export { Select } from './chunk-6XZ362VL.js';
11
11
  export { Badge, Tag } from './chunk-LXNR6TQK.js';
12
- export { Slider } from './chunk-QJGKI2BD.js';
12
+ export { Slider } from './chunk-2TZ2R7L2.js';
13
13
  export { Splitter } from './chunk-47Z4NIU4.js';
14
14
  export { StatusBar, StatusBarItem } from './chunk-OWNVDXRQ.js';
15
15
  export { Switch } from './chunk-6GNFRP2H.js';
@@ -39,7 +39,7 @@ export { Calendar } from './chunk-XCYE4OQV.js';
39
39
  export { ICON_NAMES, Icon } from './chunk-QOGROEVD.js';
40
40
 
41
41
  // src/index.ts
42
- var VERSION = "0.4.0";
42
+ var VERSION = "0.5.0";
43
43
 
44
44
  export { VERSION };
45
45
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CO,IAAM,OAAA,GAAU","file":"index.js","sourcesContent":["/* lumina — public exports */\n\nexport * from \"./components/Icon\";\nexport * from \"./components/Button\";\nexport * from \"./components/Input\";\nexport * from \"./components/Switch\";\nexport * from \"./components/Checkbox\";\nexport * from \"./components/Slider\";\nexport * from \"./components/Select\";\nexport * from \"./components/Tabs\";\nexport * from \"./components/Accordion\";\nexport * from \"./components/Card\";\nexport * from \"./components/Tag\";\nexport * from \"./components/Avatar\";\nexport * from \"./components/Divider\";\nexport * from \"./components/Progress\";\nexport * from \"./components/Modal\";\nexport * from \"./components/Toast\";\nexport * from \"./components/Tooltip\";\nexport * from \"./components/Popover\";\nexport * from \"./components/Alert\";\nexport * from \"./components/Table\";\nexport * from \"./components/Pagination\";\nexport * from \"./components/Calendar\";\nexport * from \"./components/List\";\nexport * from \"./components/AppShell\";\nexport * from \"./components/StatusBar\";\nexport * from \"./components/Splitter\";\nexport * from \"./components/ContextMenu\";\nexport * from \"./components/CommandPalette\";\nexport * from \"./components/InputNumber\";\nexport * from \"./components/AutoComplete\";\nexport * from \"./components/Form\";\nexport * from \"./components/Empty\";\nexport * from \"./components/Image\";\nexport * from \"./components/Cascader\";\nexport * from \"./components/Typography\";\nexport * from \"./components/ColorPicker\";\nexport * from \"./components/Drawer\";\nexport * from \"./components/Theme\";\n\n/** Package version — bumped by release scripts. */\nexport const VERSION = \"0.4.0\";\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CO,IAAM,OAAA,GAAU","file":"index.js","sourcesContent":["/* lumina — public exports */\n\nexport * from \"./components/Icon\";\nexport * from \"./components/Button\";\nexport * from \"./components/Input\";\nexport * from \"./components/Switch\";\nexport * from \"./components/Checkbox\";\nexport * from \"./components/Slider\";\nexport * from \"./components/Select\";\nexport * from \"./components/Tabs\";\nexport * from \"./components/Accordion\";\nexport * from \"./components/Card\";\nexport * from \"./components/Tag\";\nexport * from \"./components/Avatar\";\nexport * from \"./components/Divider\";\nexport * from \"./components/Progress\";\nexport * from \"./components/Modal\";\nexport * from \"./components/Toast\";\nexport * from \"./components/Tooltip\";\nexport * from \"./components/Popover\";\nexport * from \"./components/Alert\";\nexport * from \"./components/Table\";\nexport * from \"./components/Pagination\";\nexport * from \"./components/Calendar\";\nexport * from \"./components/List\";\nexport * from \"./components/AppShell\";\nexport * from \"./components/StatusBar\";\nexport * from \"./components/Splitter\";\nexport * from \"./components/ContextMenu\";\nexport * from \"./components/CommandPalette\";\nexport * from \"./components/InputNumber\";\nexport * from \"./components/AutoComplete\";\nexport * from \"./components/Form\";\nexport * from \"./components/Empty\";\nexport * from \"./components/Image\";\nexport * from \"./components/Cascader\";\nexport * from \"./components/Typography\";\nexport * from \"./components/ColorPicker\";\nexport * from \"./components/Drawer\";\nexport * from \"./components/Theme\";\n\n/** Package version — bumped by release scripts. */\nexport const VERSION = \"0.5.0\";\n"]}
package/dist/styles.css CHANGED
@@ -592,14 +592,23 @@ input, textarea, select { font-family: inherit; color: inherit; }
592
592
  /* ============ Slider ============ */
593
593
  .slider {
594
594
  position: relative;
595
- height: 36px;
596
595
  width: 100%;
597
596
  display: flex;
598
597
  align-items: center;
598
+ gap: 10px;
599
599
  cursor: pointer;
600
+ min-height: 36px;
600
601
  }
601
602
  .slider.has-marks { padding-bottom: 26px; }
602
603
  .slider.disabled { opacity: 0.5; cursor: not-allowed; }
604
+ /* Rail: positioning context for track + thumbs + marks */
605
+ .slider-rail {
606
+ position: relative;
607
+ flex: 1 1 0%;
608
+ height: 36px;
609
+ display: flex;
610
+ align-items: center;
611
+ }
603
612
  .slider-track {
604
613
  position: relative;
605
614
  width: 100%;
@@ -607,7 +616,8 @@ input, textarea, select { font-family: inherit; color: inherit; }
607
616
  border-radius: 999px;
608
617
  background: var(--bg);
609
618
  box-shadow: var(--neu-in-sm);
610
- overflow: hidden;
619
+ touch-action: none;
620
+ z-index: 1;
611
621
  }
612
622
  .slider-fill {
613
623
  position: absolute;
@@ -616,6 +626,7 @@ input, textarea, select { font-family: inherit; color: inherit; }
616
626
  box-shadow: 0 0 12px var(--accent-glow);
617
627
  border-radius: 999px;
618
628
  transition: left var(--dur-fast) var(--ease), right var(--dur-fast) var(--ease);
629
+ pointer-events: none;
619
630
  }
620
631
  .slider-thumb {
621
632
  position: absolute;
@@ -627,42 +638,42 @@ input, textarea, select { font-family: inherit; color: inherit; }
627
638
  transform: translate(-50%, -50%);
628
639
  transition: all var(--dur-fast) var(--ease);
629
640
  display: grid; place-items: center;
630
- pointer-events: none;
641
+ z-index: 3;
642
+ outline: none;
643
+ touch-action: none;
631
644
  }
632
- .slider.has-marks .slider-thumb { top: calc(50% - 13px); }
633
- .slider.has-marks .slider-track { margin-top: -26px; }
634
645
  .slider-thumb::after {
635
646
  content: "";
636
647
  width: 6px; height: 6px;
637
648
  border-radius: 999px;
638
- background: var(--accent);
649
+ background: var(--slider-thumb-color, var(--accent));
650
+ }
651
+ .slider-thumb:focus-visible {
652
+ box-shadow: var(--neu-out-sm), 0 0 0 3px var(--accent-glow);
639
653
  }
640
654
  .slider:hover .slider-thumb { transform: translate(-50%, -50%) scale(1.08); }
641
- .slider input[type="range"] {
642
- position: absolute;
643
- inset: 0;
644
- width: 100%; height: 100%;
645
- opacity: 0;
646
- cursor: inherit;
647
- margin: 0;
648
- pointer-events: auto;
655
+ .slider-value {
656
+ font-family: var(--font-mono);
657
+ font-size: 12px;
658
+ color: var(--accent-ink);
659
+ flex-shrink: 0;
660
+ white-space: nowrap;
649
661
  }
650
- /* In range mode (two stacked inputs), split the hit zones by half so the user can drag either thumb */
651
- .slider input[type="range"]:nth-of-type(1):not(:only-of-type) { right: 50%; }
652
- .slider input[type="range"]:nth-of-type(2) { left: 50%; }
653
- .slider.has-marks input[type="range"] { height: calc(100% - 26px); }
654
- .slider-value { font-family: var(--font-mono); font-size: 12px; color: var(--accent-ink); margin-left: 10px; }
662
+ /* Tone variants */
663
+ .slider.success .slider-thumb { --slider-thumb-color: var(--success); }
655
664
  .slider.success .slider-fill { background: linear-gradient(90deg, color-mix(in oklch, var(--success) 70%, white), var(--success)); box-shadow: 0 0 10px color-mix(in oklch, var(--success) 35%, transparent); }
656
- .slider.success .slider-thumb::after { background: var(--success); }
665
+ .slider.success .slider-thumb:focus-visible { box-shadow: var(--neu-out-sm), 0 0 0 3px color-mix(in oklch, var(--success) 35%, transparent); }
666
+ .slider.warning .slider-thumb { --slider-thumb-color: var(--warning); }
657
667
  .slider.warning .slider-fill { background: linear-gradient(90deg, color-mix(in oklch, var(--warning) 70%, white), var(--warning)); box-shadow: 0 0 10px color-mix(in oklch, var(--warning) 35%, transparent); }
658
- .slider.warning .slider-thumb::after { background: var(--warning); }
668
+ .slider.warning .slider-thumb:focus-visible { box-shadow: var(--neu-out-sm), 0 0 0 3px color-mix(in oklch, var(--warning) 35%, transparent); }
669
+ .slider.danger .slider-thumb { --slider-thumb-color: var(--danger); }
659
670
  .slider.danger .slider-fill { background: linear-gradient(90deg, color-mix(in oklch, var(--danger) 70%, white), var(--danger)); box-shadow: 0 0 10px color-mix(in oklch, var(--danger) 35%, transparent); }
660
- .slider.danger .slider-thumb::after { background: var(--danger); }
671
+ .slider.danger .slider-thumb:focus-visible { box-shadow: var(--neu-out-sm), 0 0 0 3px color-mix(in oklch, var(--danger) 35%, transparent); }
661
672
  /* Marks */
662
673
  .slider-marks {
663
674
  position: absolute;
664
675
  left: 0; right: 0;
665
- bottom: 0;
676
+ bottom: -26px;
666
677
  height: 22px;
667
678
  pointer-events: none;
668
679
  }
@@ -684,8 +695,10 @@ input, textarea, select { font-family: inherit; color: inherit; }
684
695
  border-radius: 999px;
685
696
  background: var(--bg);
686
697
  box-shadow: var(--neu-in-sm);
687
- margin-top: -18px;
688
- position: relative;
698
+ position: absolute;
699
+ top: -12px;
700
+ left: 50%;
701
+ transform: translateX(-50%);
689
702
  z-index: 1;
690
703
  }
691
704
  .slider-mark.active .slider-mark-dot { background: var(--accent); box-shadow: 0 0 6px var(--accent-glow); }
package/docs/llms/form.md CHANGED
@@ -52,6 +52,32 @@ Checkbox / Switch 的绑定属性不是 value,需要用 valuePropName 指定;对
52
52
  </Form.Item>
53
53
  ```
54
54
 
55
+ ### 实时值预览
56
+
57
+ onValuesChange 可以监听任何字段变化。下方面板会实时展示 form.getFieldsValue() 的结果。
58
+
59
+ ```tsx
60
+ <Form onValuesChange={(changed, all) => setSnapshot(all)}>
61
+ ...
62
+ </Form>
63
+ <pre>{JSON.stringify(snapshot, null, 2)}</pre>
64
+ ```
65
+
66
+ ### 横排复选 (嵌套 Form.Item)
67
+
68
+ 外层 Form.Item 只做布局(无 name),内层若干 Form.Item 各自绑定字段并加 noStyle。my-assistant 里 "新建角色" 弹窗用的就是这个模式。
69
+
70
+ ```tsx
71
+ <Form.Item className="checkbox-row">
72
+ <Form.Item name="addToHistory" valuePropName="checked" initialValue={true} noStyle>
73
+ <Checkbox label="添加到登录列表" />
74
+ </Form.Item>
75
+ <Form.Item name="setAsLast" valuePropName="checked" initialValue={false} noStyle>
76
+ <Checkbox label="设为最近登录" />
77
+ </Form.Item>
78
+ </Form.Item>
79
+ ```
80
+
55
81
  ### 命令式 API
56
82
 
57
83
  通过 Form.useForm() 拿到实例,外部可主动 setFieldsValue / validateFields / resetFields。
@@ -41,14 +41,24 @@ const [v, setV] = useState<[number, number]>([20, 70]);
41
41
  <Slider range value={v} onChange={setV} showValue />
42
42
  ```
43
43
 
44
- ### 刻度标记
44
+ ### 渐变色
45
45
 
46
- marks 提供可点击刻度,点击即可跳到该值。
46
+ colors 传入颜色数组,填充和滑块圆点会按当前位置动态插值。
47
+
48
+ ```tsx
49
+ <Slider defaultValue={60} showValue
50
+ colors={["#3b82f6", "#22c55e", "#eab308", "#ef4444"]} />
51
+ ```
52
+
53
+ ### 刻度标记 + 渐变
54
+
55
+ marks 配合 colors 可直观表达冷暖等语义。
47
56
 
48
57
  ```tsx
49
58
  <Slider
50
59
  defaultValue={37}
51
60
  marks={{ 0: "0°C", 26: "冷", 37: "正常", 100: "100°C" }}
61
+ colors={["#3b82f6", "#22c55e", "#eab308", "#ef4444"]}
52
62
  />
53
63
  ```
54
64
 
@@ -64,6 +74,7 @@ marks 提供可点击刻度,点击即可跳到该值。
64
74
  | range | `boolean` | `false` | 是否为双滑块区间模式 |
65
75
  | marks | `Record<number, ReactNode>` | — | 刻度,点击可跳到对应值 |
66
76
  | tone | `"accent" | "success" | "warning" | "danger"` | `"accent"` | 色调 |
77
+ | colors | `string[]` | — | 渐变色数组,按位置插值;覆盖 tone |
67
78
  | showValue | `boolean` | `false` | 显示数值 |
68
79
  | disabled | `boolean` | `false` | 禁用 |
69
80
 
package/docs/llms.md CHANGED
@@ -3,7 +3,7 @@
3
3
  > 拟态风格的 React 18 组件库,目标是 Electron 桌面应用。**写给 AI 编程助手**的按需文档 —— 每个组件单独一个 `.md`,避免一次性读取全部。示例源自 playground 的 demo,可直接复制运行。
4
4
 
5
5
  - **包名**: `@fangxinyan/lumina`
6
- - **版本**: `0.4.0`
6
+ - **版本**: `0.5.0`
7
7
  - **React 最低版本**: 18
8
8
  - **环境**: 带打包器的 React 工程(Vite / Next.js / Webpack / Remix / Electron + Vite 等)
9
9
  - **零运行时依赖**: 只依赖 `react` / `react-dom` (peer deps)
@@ -69,16 +69,16 @@
69
69
  - [Tag 标签](./llms/tag.md) — 标记关键词、状态或分类。
70
70
  - [Badge 徽标数](./llms/badge.md) — 右上角的小型计数或状态指示器。
71
71
  - [Avatar 头像](./llms/avatar.md) — 用图像、首字母代表用户或事物。
72
+ - [Image 图片](./llms/image.md) — 凹陷外框包裹的图片容器,带预览、错误占位。
72
73
  - [Divider 分隔符](./llms/divider.md) — 对内容进行分割。
73
74
  - [Progress 进度](./llms/progress.md) — 条形进度 Progress 与环形进度 Ring。
74
75
  - [List 列表](./llms/list.md) — 承载一组结构化的同质化数据。
75
76
  - [Table 表格](./llms/table.md) — 结构化数据展示。
76
77
  - [Table Pro](./llms/tablepro.md) — 带工具栏 / 搜索 / 筛选 / 排序 / 多选 / 分页的全功能表格。
77
- - [Image 图片](./llms/image.md) — 凹陷外框包裹的图片容器,带预览、错误占位。
78
- - [Calendar 日历](./llms/calendar.md) — 查看与选择日期。
79
78
  - [Pagination 分页](./llms/pagination.md) — 分页控件,支持快速跳转与每页条数切换。
80
79
  - [Tabs 选项卡](./llms/tabs.md) — 同一层级的内容分组,通过标签切换。
81
80
  - [Accordion 折叠面板](./llms/accordion.md) — 纵向折叠面板。
81
+ - [Calendar 日历](./llms/calendar.md) — 查看与选择日期。
82
82
 
83
83
  ### 反馈
84
84
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fangxinyan/lumina",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Lumina — Neumorphic component library for Electron & React apps",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",