@ambientcss/components 1.0.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 ADDED
@@ -0,0 +1,27 @@
1
+ # @ambientcss/components
2
+
3
+ React components built with Ambient CSS.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @ambientcss/components @ambientcss/css
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import "@ambientcss/css/ambient.css";
15
+ import "@ambientcss/components/styles.css";
16
+
17
+ import { AmbientButton, AmbientKnob, AmbientProvider } from "@ambientcss/components";
18
+
19
+ export function Example() {
20
+ return (
21
+ <AmbientProvider theme={{ keyLight: 0.45, fillLight: 0.18, lightX: -1, lightY: -1 }}>
22
+ <AmbientButton>Play</AmbientButton>
23
+ <AmbientKnob value={40} onChange={(next) => console.log(next)} />
24
+ </AmbientProvider>
25
+ );
26
+ }
27
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,470 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AmbientButton: () => AmbientButton,
24
+ AmbientFader: () => AmbientFader,
25
+ AmbientKnob: () => AmbientKnob,
26
+ AmbientPanel: () => AmbientPanel,
27
+ AmbientProvider: () => AmbientProvider,
28
+ AmbientSlider: () => AmbientSlider,
29
+ AmbientSwitch: () => AmbientSwitch
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/components/AmbientProvider.tsx
34
+ var import_jsx_runtime = require("react/jsx-runtime");
35
+ var VAR_MAP = {
36
+ "--amb-light-x": "lightX",
37
+ "--amb-light-y": "lightY",
38
+ "--amb-key-light-intensity": "keyLight",
39
+ "--amb-fill-light-intensity": "fillLight",
40
+ "--amb-light-hue": "lightHue",
41
+ "--amb-light-saturation": "lightSaturation",
42
+ "--amb-highlight-color": "highlightColor",
43
+ "--amb-lume-hue": "lumeHue"
44
+ };
45
+ function AmbientProvider({ children, className, style, theme }) {
46
+ const themeVars = {};
47
+ for (const [varName, key] of Object.entries(VAR_MAP)) {
48
+ const value = theme?.[key];
49
+ if (value !== void 0) {
50
+ themeVars[varName] = key === "lightSaturation" ? `${value}%` : String(value);
51
+ }
52
+ }
53
+ const mergedStyle = { ...themeVars, ...style };
54
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className, style: mergedStyle, children });
55
+ }
56
+
57
+ // src/lib/cn.ts
58
+ function cn(...values) {
59
+ return values.filter(Boolean).join(" ");
60
+ }
61
+
62
+ // src/components/AmbientPanel.tsx
63
+ var import_jsx_runtime2 = require("react/jsx-runtime");
64
+ function AmbientPanel({ className, ...props }) {
65
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("ambient amb-surface amb-chamfer amb-elevation-2 ambx-panel", className), ...props });
66
+ }
67
+
68
+ // src/components/AmbientButton.tsx
69
+ var import_jsx_runtime3 = require("react/jsx-runtime");
70
+ function AmbientButton({ className, children, ...props }) {
71
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
72
+ "button",
73
+ {
74
+ type: "button",
75
+ className: cn("ambient amb-button amb-chamfer amb-elevation-1 ambx-button amb-heading-3", className),
76
+ ...props,
77
+ children
78
+ }
79
+ );
80
+ }
81
+
82
+ // src/components/AmbientSwitch.tsx
83
+ var import_react = require("react");
84
+ var import_jsx_runtime4 = require("react/jsx-runtime");
85
+ function AmbientSwitch({
86
+ className,
87
+ checked,
88
+ defaultChecked,
89
+ onCheckedChange,
90
+ onClick,
91
+ size = "md",
92
+ label,
93
+ led,
94
+ children,
95
+ ...props
96
+ }) {
97
+ const labelId = (0, import_react.useId)();
98
+ const isControlled = checked !== void 0;
99
+ const [internalChecked, setInternalChecked] = (0, import_react.useState)(defaultChecked ?? false);
100
+ const active = isControlled ? checked ?? false : internalChecked;
101
+ const button = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
102
+ "button",
103
+ {
104
+ type: "button",
105
+ role: "switch",
106
+ "aria-checked": active,
107
+ "aria-labelledby": label ? labelId : props["aria-labelledby"],
108
+ className: cn(
109
+ "ambient amb-switch amb-chamfer amb-elevation-1 amb-heading-3",
110
+ active ? "amb-surface-convex amb-switch-on" : "amb-surface-concave",
111
+ "ambx-switch",
112
+ `ambx-switch-${size}`,
113
+ className
114
+ ),
115
+ onClick: (event) => {
116
+ const next = !active;
117
+ if (!isControlled) setInternalChecked(next);
118
+ onCheckedChange?.(next);
119
+ onClick?.(event);
120
+ },
121
+ ...props,
122
+ children: [
123
+ led ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
124
+ "span",
125
+ {
126
+ className: cn("amb-led", !active && "amb-led-off"),
127
+ style: typeof led === "string" ? { "--amb-led-color": led } : void 0
128
+ }
129
+ ) : null,
130
+ children
131
+ ]
132
+ }
133
+ );
134
+ if (!label) return button;
135
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ambx-stack", children: [
136
+ button,
137
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { id: labelId, className: "ambx-label", children: label })
138
+ ] });
139
+ }
140
+
141
+ // src/components/AmbientKnob.tsx
142
+ var import_react2 = require("react");
143
+ var import_jsx_runtime5 = require("react/jsx-runtime");
144
+ function clamp(value, min, max) {
145
+ return Math.min(max, Math.max(min, value));
146
+ }
147
+ function AmbientKnob({
148
+ value,
149
+ min = 0,
150
+ max = 100,
151
+ step = 1,
152
+ label,
153
+ onChange,
154
+ className,
155
+ ...props
156
+ }) {
157
+ const id = (0, import_react2.useId)();
158
+ const dragStateRef = (0, import_react2.useRef)(null);
159
+ const safeStep = step > 0 ? step : 1;
160
+ const percent = (value - min) / (max - min || 1);
161
+ const rotation = percent * 270 - 135;
162
+ const updateFromPointer = (event) => {
163
+ const drag = dragStateRef.current;
164
+ if (!drag) return;
165
+ const delta = drag.startY - event.clientY;
166
+ const range = max - min;
167
+ const sensitivity = range / 180;
168
+ const raw = drag.startValue + delta * sensitivity;
169
+ const snapped = Math.round(raw / safeStep) * safeStep;
170
+ onChange?.(clamp(snapped, min, max));
171
+ };
172
+ const setValue = (nextValue) => {
173
+ const snapped = Math.round(nextValue / safeStep) * safeStep;
174
+ onChange?.(clamp(snapped, min, max));
175
+ };
176
+ const onKeyDown = (event) => {
177
+ const pageStep = safeStep * 10;
178
+ switch (event.key) {
179
+ case "ArrowUp":
180
+ case "ArrowRight":
181
+ event.preventDefault();
182
+ setValue(value + safeStep);
183
+ break;
184
+ case "ArrowDown":
185
+ case "ArrowLeft":
186
+ event.preventDefault();
187
+ setValue(value - safeStep);
188
+ break;
189
+ case "PageUp":
190
+ event.preventDefault();
191
+ setValue(value + pageStep);
192
+ break;
193
+ case "PageDown":
194
+ event.preventDefault();
195
+ setValue(value - pageStep);
196
+ break;
197
+ case "Home":
198
+ event.preventDefault();
199
+ setValue(min);
200
+ break;
201
+ case "End":
202
+ event.preventDefault();
203
+ setValue(max);
204
+ break;
205
+ default:
206
+ break;
207
+ }
208
+ };
209
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("ambx-stack", className), ...props, children: [
210
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
211
+ "div",
212
+ {
213
+ className: "ambient amb-knob amb-chamfer amb-elevation-2 amb-surface ambx-knob",
214
+ role: "slider",
215
+ "aria-label": label,
216
+ "aria-valuemin": min,
217
+ "aria-valuemax": max,
218
+ "aria-valuenow": value,
219
+ "aria-labelledby": label ? id : void 0,
220
+ "aria-orientation": "vertical",
221
+ tabIndex: 0,
222
+ onPointerDown: (event) => {
223
+ event.currentTarget.setPointerCapture(event.pointerId);
224
+ dragStateRef.current = { startY: event.clientY, startValue: value };
225
+ },
226
+ onPointerMove: updateFromPointer,
227
+ onPointerUp: () => {
228
+ dragStateRef.current = null;
229
+ },
230
+ onPointerCancel: () => {
231
+ dragStateRef.current = null;
232
+ },
233
+ onKeyDown,
234
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ambx-knob-rotation", style: { transform: `rotate(${rotation}deg)` }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "amb-knob-indicator", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "amb-knob-grip", children: [
235
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "amb-fader-dot" }),
236
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "amb-fader-dot" }),
237
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "amb-fader-dot" })
238
+ ] }) }) })
239
+ }
240
+ ),
241
+ label ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id, className: "ambx-label", children: label }) : null
242
+ ] });
243
+ }
244
+
245
+ // src/components/AmbientFader.tsx
246
+ var import_react3 = require("react");
247
+ var import_jsx_runtime6 = require("react/jsx-runtime");
248
+ function clamp2(value, min, max) {
249
+ return Math.min(max, Math.max(min, value));
250
+ }
251
+ function AmbientFader({
252
+ value,
253
+ min = 0,
254
+ max = 100,
255
+ step = 1,
256
+ label,
257
+ onChange,
258
+ className,
259
+ ...props
260
+ }) {
261
+ const id = (0, import_react3.useId)();
262
+ const trackRef = (0, import_react3.useRef)(null);
263
+ const safeStep = step > 0 ? step : 1;
264
+ const percent = (value - min) / (max - min || 1) * 100;
265
+ const updateFromClientY = (clientY) => {
266
+ const track = trackRef.current;
267
+ if (!track) return;
268
+ const rect = track.getBoundingClientRect();
269
+ const ratio = 1 - (clientY - rect.top) / rect.height;
270
+ const nextValue = min + clamp2(ratio, 0, 1) * (max - min);
271
+ const snapped = Math.round(nextValue / safeStep) * safeStep;
272
+ onChange?.(clamp2(snapped, min, max));
273
+ };
274
+ const setValue = (nextValue) => {
275
+ const snapped = Math.round(nextValue / safeStep) * safeStep;
276
+ onChange?.(clamp2(snapped, min, max));
277
+ };
278
+ const onKeyDown = (event) => {
279
+ const pageStep = safeStep * 10;
280
+ switch (event.key) {
281
+ case "ArrowUp":
282
+ case "ArrowRight":
283
+ event.preventDefault();
284
+ setValue(value + safeStep);
285
+ break;
286
+ case "ArrowDown":
287
+ case "ArrowLeft":
288
+ event.preventDefault();
289
+ setValue(value - safeStep);
290
+ break;
291
+ case "PageUp":
292
+ event.preventDefault();
293
+ setValue(value + pageStep);
294
+ break;
295
+ case "PageDown":
296
+ event.preventDefault();
297
+ setValue(value - pageStep);
298
+ break;
299
+ case "Home":
300
+ event.preventDefault();
301
+ setValue(min);
302
+ break;
303
+ case "End":
304
+ event.preventDefault();
305
+ setValue(max);
306
+ break;
307
+ default:
308
+ break;
309
+ }
310
+ };
311
+ const onPointerMove = (event) => {
312
+ if (event.buttons !== 1) return;
313
+ updateFromClientY(event.clientY);
314
+ };
315
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: cn("ambx-stack", className), ...props, children: [
316
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
317
+ "div",
318
+ {
319
+ className: "amb-fader ambx-fader",
320
+ ref: trackRef,
321
+ role: "slider",
322
+ "aria-label": label,
323
+ "aria-labelledby": label ? id : void 0,
324
+ "aria-valuemin": min,
325
+ "aria-valuemax": max,
326
+ "aria-valuenow": value,
327
+ "aria-orientation": "vertical",
328
+ tabIndex: 0,
329
+ onPointerDown: (event) => {
330
+ event.currentTarget.setPointerCapture(event.pointerId);
331
+ updateFromClientY(event.clientY);
332
+ },
333
+ onPointerMove,
334
+ onKeyDown,
335
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
336
+ "div",
337
+ {
338
+ className: "amb-fader-thumb ambient amb-fillet amb-elevation-1 amb-surface-concave ambx-fader-thumb",
339
+ style: { top: `${100 - percent}%` },
340
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "amb-fader-grip", children: [
341
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "amb-fader-dot" }),
342
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "amb-fader-dot" }),
343
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "amb-fader-dot" })
344
+ ] })
345
+ }
346
+ )
347
+ }
348
+ ),
349
+ label ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { id, className: "ambx-label", children: label }) : null
350
+ ] });
351
+ }
352
+
353
+ // src/components/AmbientSlider.tsx
354
+ var import_react4 = require("react");
355
+ var import_jsx_runtime7 = require("react/jsx-runtime");
356
+ function clamp3(value, min, max) {
357
+ return Math.min(max, Math.max(min, value));
358
+ }
359
+ function AmbientSlider({
360
+ value,
361
+ min = 0,
362
+ max = 100,
363
+ step = 1,
364
+ label,
365
+ onChange,
366
+ className,
367
+ ...props
368
+ }) {
369
+ const id = (0, import_react4.useId)();
370
+ const trackRef = (0, import_react4.useRef)(null);
371
+ const safeStep = step > 0 ? step : 1;
372
+ const percent = (value - min) / (max - min || 1) * 100;
373
+ const updateFromClientX = (clientX) => {
374
+ const track = trackRef.current;
375
+ if (!track) return;
376
+ const rect = track.getBoundingClientRect();
377
+ const ratio = (clientX - rect.left) / rect.width;
378
+ const nextValue = min + clamp3(ratio, 0, 1) * (max - min);
379
+ const snapped = Math.round(nextValue / safeStep) * safeStep;
380
+ onChange?.(clamp3(snapped, min, max));
381
+ };
382
+ const setValue = (nextValue) => {
383
+ const snapped = Math.round(nextValue / safeStep) * safeStep;
384
+ onChange?.(clamp3(snapped, min, max));
385
+ };
386
+ const onKeyDown = (event) => {
387
+ const pageStep = safeStep * 10;
388
+ switch (event.key) {
389
+ case "ArrowRight":
390
+ case "ArrowUp":
391
+ event.preventDefault();
392
+ setValue(value + safeStep);
393
+ break;
394
+ case "ArrowLeft":
395
+ case "ArrowDown":
396
+ event.preventDefault();
397
+ setValue(value - safeStep);
398
+ break;
399
+ case "PageUp":
400
+ event.preventDefault();
401
+ setValue(value + pageStep);
402
+ break;
403
+ case "PageDown":
404
+ event.preventDefault();
405
+ setValue(value - pageStep);
406
+ break;
407
+ case "Home":
408
+ event.preventDefault();
409
+ setValue(min);
410
+ break;
411
+ case "End":
412
+ event.preventDefault();
413
+ setValue(max);
414
+ break;
415
+ default:
416
+ break;
417
+ }
418
+ };
419
+ const onPointerMove = (event) => {
420
+ if (event.buttons !== 1) return;
421
+ updateFromClientX(event.clientX);
422
+ };
423
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("ambx-stack", className), ...props, children: [
424
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
425
+ "div",
426
+ {
427
+ className: "amb-slider ambx-slider",
428
+ ref: trackRef,
429
+ role: "slider",
430
+ "aria-label": label,
431
+ "aria-labelledby": label ? id : void 0,
432
+ "aria-valuemin": min,
433
+ "aria-valuemax": max,
434
+ "aria-valuenow": value,
435
+ "aria-orientation": "horizontal",
436
+ tabIndex: 0,
437
+ onPointerDown: (event) => {
438
+ event.currentTarget.setPointerCapture(event.pointerId);
439
+ updateFromClientX(event.clientX);
440
+ },
441
+ onPointerMove,
442
+ onKeyDown,
443
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
444
+ "div",
445
+ {
446
+ className: "amb-slider-thumb ambient amb-fillet amb-elevation-1 amb-surface-concave-h ambx-slider-thumb",
447
+ style: { left: `${percent}%` },
448
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "amb-slider-grip", children: [
449
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "amb-fader-dot" }),
450
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "amb-fader-dot" }),
451
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "amb-fader-dot" })
452
+ ] })
453
+ }
454
+ )
455
+ }
456
+ ),
457
+ label ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { id, className: "ambx-label", children: label }) : null
458
+ ] });
459
+ }
460
+ // Annotate the CommonJS export names for ESM import in node:
461
+ 0 && (module.exports = {
462
+ AmbientButton,
463
+ AmbientFader,
464
+ AmbientKnob,
465
+ AmbientPanel,
466
+ AmbientProvider,
467
+ AmbientSlider,
468
+ AmbientSwitch
469
+ });
470
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/components/AmbientProvider.tsx","../src/lib/cn.ts","../src/components/AmbientPanel.tsx","../src/components/AmbientButton.tsx","../src/components/AmbientSwitch.tsx","../src/components/AmbientKnob.tsx","../src/components/AmbientFader.tsx","../src/components/AmbientSlider.tsx"],"sourcesContent":["export { AmbientProvider } from \"./components/AmbientProvider\";\nexport type { AmbientProviderProps, AmbientTheme } from \"./components/AmbientProvider\";\n\nexport { AmbientPanel } from \"./components/AmbientPanel\";\nexport type { AmbientPanelProps } from \"./components/AmbientPanel\";\n\nexport { AmbientButton } from \"./components/AmbientButton\";\nexport type { AmbientButtonProps } from \"./components/AmbientButton\";\n\nexport { AmbientSwitch } from \"./components/AmbientSwitch\";\nexport type { AmbientSwitchProps, AmbientSwitchSize } from \"./components/AmbientSwitch\";\n\nexport { AmbientKnob } from \"./components/AmbientKnob\";\nexport type { AmbientKnobProps } from \"./components/AmbientKnob\";\n\nexport { AmbientFader } from \"./components/AmbientFader\";\nexport type { AmbientFaderProps } from \"./components/AmbientFader\";\n\nexport { AmbientSlider } from \"./components/AmbientSlider\";\nexport type { AmbientSliderProps } from \"./components/AmbientSlider\";\n","import type { CSSProperties, PropsWithChildren } from \"react\";\n\nexport type AmbientTheme = {\n lightX?: number;\n lightY?: number;\n keyLight?: number;\n fillLight?: number;\n lightHue?: number;\n lightSaturation?: number;\n highlightColor?: string;\n lumeHue?: number;\n};\n\nexport type AmbientProviderProps = PropsWithChildren<{\n className?: string;\n style?: CSSProperties;\n theme?: AmbientTheme;\n}>;\n\nconst VAR_MAP: Record<string, keyof AmbientTheme> = {\n \"--amb-light-x\": \"lightX\",\n \"--amb-light-y\": \"lightY\",\n \"--amb-key-light-intensity\": \"keyLight\",\n \"--amb-fill-light-intensity\": \"fillLight\",\n \"--amb-light-hue\": \"lightHue\",\n \"--amb-light-saturation\": \"lightSaturation\",\n \"--amb-highlight-color\": \"highlightColor\",\n \"--amb-lume-hue\": \"lumeHue\",\n};\n\nexport function AmbientProvider({ children, className, style, theme }: AmbientProviderProps) {\n const themeVars: Record<string, string> = {};\n for (const [varName, key] of Object.entries(VAR_MAP)) {\n const value = theme?.[key];\n if (value !== undefined) {\n themeVars[varName] = key === \"lightSaturation\" ? `${value}%` : String(value);\n }\n }\n const mergedStyle = { ...themeVars, ...style } as CSSProperties;\n\n return (\n <div className={className} style={mergedStyle}>\n {children}\n </div>\n );\n}\n","export function cn(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n","import type { HTMLAttributes } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type AmbientPanelProps = HTMLAttributes<HTMLDivElement>;\n\nexport function AmbientPanel({ className, ...props }: AmbientPanelProps) {\n return <div className={cn(\"ambient amb-surface amb-chamfer amb-elevation-2 ambx-panel\", className)} {...props} />;\n}\n","import type { ButtonHTMLAttributes } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type AmbientButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport function AmbientButton({ className, children, ...props }: AmbientButtonProps) {\n return (\n <button\n type=\"button\"\n className={cn(\"ambient amb-button amb-chamfer amb-elevation-1 ambx-button amb-heading-3\", className)}\n {...props}\n >\n {children}\n </button>\n );\n}\n","import { useId, useState } from \"react\";\nimport type { ButtonHTMLAttributes } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type AmbientSwitchSize = \"sm\" | \"md\" | \"lg\";\n\nexport type AmbientSwitchProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"onChange\"> & {\n checked?: boolean;\n defaultChecked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n size?: AmbientSwitchSize;\n label?: string;\n /** Show a small LED indicator that lights up when the switch is on. Pass `true` for default green or a CSS color string. */\n led?: boolean | string;\n};\n\nexport function AmbientSwitch({\n className,\n checked,\n defaultChecked,\n onCheckedChange,\n onClick,\n size = \"md\",\n label,\n led,\n children,\n ...props\n}: AmbientSwitchProps) {\n const labelId = useId();\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false);\n const active = isControlled ? (checked ?? false) : internalChecked;\n\n const button = (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={active}\n aria-labelledby={label ? labelId : props[\"aria-labelledby\"]}\n className={cn(\n \"ambient amb-switch amb-chamfer amb-elevation-1 amb-heading-3\",\n active ? \"amb-surface-convex amb-switch-on\" : \"amb-surface-concave\",\n \"ambx-switch\",\n `ambx-switch-${size}`,\n className\n )}\n onClick={(event) => {\n const next = !active;\n if (!isControlled) setInternalChecked(next);\n onCheckedChange?.(next);\n onClick?.(event);\n }}\n {...props}\n >\n {led ? (\n <span\n className={cn(\"amb-led\", !active && \"amb-led-off\")}\n style={typeof led === \"string\" ? { \"--amb-led-color\": led } as React.CSSProperties : undefined}\n />\n ) : null}\n {children}\n </button>\n );\n\n if (!label) return button;\n\n return (\n <div className=\"ambx-stack\">\n {button}\n <span id={labelId} className=\"ambx-label\">\n {label}\n </span>\n </div>\n );\n}\n","import { useId, useRef } from \"react\";\nimport type { HTMLAttributes, KeyboardEvent, PointerEvent } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type AmbientKnobProps = Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> & {\n value: number;\n min?: number;\n max?: number;\n step?: number;\n label?: string;\n onChange?: (nextValue: number) => void;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport function AmbientKnob({\n value,\n min = 0,\n max = 100,\n step = 1,\n label,\n onChange,\n className,\n ...props\n}: AmbientKnobProps) {\n const id = useId();\n const dragStateRef = useRef<{ startY: number; startValue: number } | null>(null);\n const safeStep = step > 0 ? step : 1;\n\n const percent = (value - min) / (max - min || 1);\n const rotation = percent * 270 - 135;\n\n const updateFromPointer = (event: PointerEvent<HTMLDivElement>) => {\n const drag = dragStateRef.current;\n if (!drag) return;\n\n const delta = drag.startY - event.clientY;\n const range = max - min;\n const sensitivity = range / 180;\n const raw = drag.startValue + delta * sensitivity;\n const snapped = Math.round(raw / safeStep) * safeStep;\n onChange?.(clamp(snapped, min, max));\n };\n\n const setValue = (nextValue: number) => {\n const snapped = Math.round(nextValue / safeStep) * safeStep;\n onChange?.(clamp(snapped, min, max));\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const pageStep = safeStep * 10;\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowRight\":\n event.preventDefault();\n setValue(value + safeStep);\n break;\n case \"ArrowDown\":\n case \"ArrowLeft\":\n event.preventDefault();\n setValue(value - safeStep);\n break;\n case \"PageUp\":\n event.preventDefault();\n setValue(value + pageStep);\n break;\n case \"PageDown\":\n event.preventDefault();\n setValue(value - pageStep);\n break;\n case \"Home\":\n event.preventDefault();\n setValue(min);\n break;\n case \"End\":\n event.preventDefault();\n setValue(max);\n break;\n default:\n break;\n }\n };\n\n return (\n <div className={cn(\"ambx-stack\", className)} {...props}>\n <div\n className=\"ambient amb-knob amb-chamfer amb-elevation-2 amb-surface ambx-knob\"\n role=\"slider\"\n aria-label={label}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={value}\n aria-labelledby={label ? id : undefined}\n aria-orientation=\"vertical\"\n tabIndex={0}\n onPointerDown={(event) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n dragStateRef.current = { startY: event.clientY, startValue: value };\n }}\n onPointerMove={updateFromPointer}\n onPointerUp={() => {\n dragStateRef.current = null;\n }}\n onPointerCancel={() => {\n dragStateRef.current = null;\n }}\n onKeyDown={onKeyDown}\n >\n <div className=\"ambx-knob-rotation\" style={{ transform: `rotate(${rotation}deg)` }}>\n <div className=\"amb-knob-indicator\">\n <div className=\"amb-knob-grip\">\n <span className=\"amb-fader-dot\" />\n <span className=\"amb-fader-dot\" />\n <span className=\"amb-fader-dot\" />\n </div>\n </div>\n </div>\n </div>\n {label ? (\n <span id={id} className=\"ambx-label\">\n {label}\n </span>\n ) : null}\n </div>\n );\n}\n","import { useId, useRef } from \"react\";\nimport type { HTMLAttributes, KeyboardEvent, PointerEvent } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type AmbientFaderProps = Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> & {\n value: number;\n min?: number;\n max?: number;\n step?: number;\n label?: string;\n onChange?: (nextValue: number) => void;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport function AmbientFader({\n value,\n min = 0,\n max = 100,\n step = 1,\n label,\n onChange,\n className,\n ...props\n}: AmbientFaderProps) {\n const id = useId();\n const trackRef = useRef<HTMLDivElement | null>(null);\n const safeStep = step > 0 ? step : 1;\n\n const percent = ((value - min) / (max - min || 1)) * 100;\n\n const updateFromClientY = (clientY: number) => {\n const track = trackRef.current;\n if (!track) return;\n\n const rect = track.getBoundingClientRect();\n const ratio = 1 - (clientY - rect.top) / rect.height;\n const nextValue = min + clamp(ratio, 0, 1) * (max - min);\n const snapped = Math.round(nextValue / safeStep) * safeStep;\n onChange?.(clamp(snapped, min, max));\n };\n\n const setValue = (nextValue: number) => {\n const snapped = Math.round(nextValue / safeStep) * safeStep;\n onChange?.(clamp(snapped, min, max));\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const pageStep = safeStep * 10;\n switch (event.key) {\n case \"ArrowUp\":\n case \"ArrowRight\":\n event.preventDefault();\n setValue(value + safeStep);\n break;\n case \"ArrowDown\":\n case \"ArrowLeft\":\n event.preventDefault();\n setValue(value - safeStep);\n break;\n case \"PageUp\":\n event.preventDefault();\n setValue(value + pageStep);\n break;\n case \"PageDown\":\n event.preventDefault();\n setValue(value - pageStep);\n break;\n case \"Home\":\n event.preventDefault();\n setValue(min);\n break;\n case \"End\":\n event.preventDefault();\n setValue(max);\n break;\n default:\n break;\n }\n };\n\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n if (event.buttons !== 1) return;\n updateFromClientY(event.clientY);\n };\n\n return (\n <div className={cn(\"ambx-stack\", className)} {...props}>\n <div\n className=\"amb-fader ambx-fader\"\n ref={trackRef}\n role=\"slider\"\n aria-label={label}\n aria-labelledby={label ? id : undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={value}\n aria-orientation=\"vertical\"\n tabIndex={0}\n onPointerDown={(event) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n updateFromClientY(event.clientY);\n }}\n onPointerMove={onPointerMove}\n onKeyDown={onKeyDown}\n >\n <div\n className=\"amb-fader-thumb ambient amb-fillet amb-elevation-1 amb-surface-concave ambx-fader-thumb\"\n style={{ top: `${100 - percent}%` }}\n >\n <div className=\"amb-fader-grip\">\n <span className=\"amb-fader-dot\" />\n <span className=\"amb-fader-dot\" />\n <span className=\"amb-fader-dot\" />\n </div>\n </div>\n </div>\n {label ? (\n <span id={id} className=\"ambx-label\">\n {label}\n </span>\n ) : null}\n </div>\n );\n}\n","import { useId, useRef } from \"react\";\nimport type { HTMLAttributes, KeyboardEvent, PointerEvent } from \"react\";\nimport { cn } from \"../lib/cn\";\n\nexport type AmbientSliderProps = Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> & {\n value: number;\n min?: number;\n max?: number;\n step?: number;\n label?: string;\n onChange?: (nextValue: number) => void;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n\nexport function AmbientSlider({\n value,\n min = 0,\n max = 100,\n step = 1,\n label,\n onChange,\n className,\n ...props\n}: AmbientSliderProps) {\n const id = useId();\n const trackRef = useRef<HTMLDivElement | null>(null);\n const safeStep = step > 0 ? step : 1;\n\n const percent = ((value - min) / (max - min || 1)) * 100;\n\n const updateFromClientX = (clientX: number) => {\n const track = trackRef.current;\n if (!track) return;\n\n const rect = track.getBoundingClientRect();\n const ratio = (clientX - rect.left) / rect.width;\n const nextValue = min + clamp(ratio, 0, 1) * (max - min);\n const snapped = Math.round(nextValue / safeStep) * safeStep;\n onChange?.(clamp(snapped, min, max));\n };\n\n const setValue = (nextValue: number) => {\n const snapped = Math.round(nextValue / safeStep) * safeStep;\n onChange?.(clamp(snapped, min, max));\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const pageStep = safeStep * 10;\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowUp\":\n event.preventDefault();\n setValue(value + safeStep);\n break;\n case \"ArrowLeft\":\n case \"ArrowDown\":\n event.preventDefault();\n setValue(value - safeStep);\n break;\n case \"PageUp\":\n event.preventDefault();\n setValue(value + pageStep);\n break;\n case \"PageDown\":\n event.preventDefault();\n setValue(value - pageStep);\n break;\n case \"Home\":\n event.preventDefault();\n setValue(min);\n break;\n case \"End\":\n event.preventDefault();\n setValue(max);\n break;\n default:\n break;\n }\n };\n\n const onPointerMove = (event: PointerEvent<HTMLDivElement>) => {\n if (event.buttons !== 1) return;\n updateFromClientX(event.clientX);\n };\n\n return (\n <div className={cn(\"ambx-stack\", className)} {...props}>\n <div\n className=\"amb-slider ambx-slider\"\n ref={trackRef}\n role=\"slider\"\n aria-label={label}\n aria-labelledby={label ? id : undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={value}\n aria-orientation=\"horizontal\"\n tabIndex={0}\n onPointerDown={(event) => {\n event.currentTarget.setPointerCapture(event.pointerId);\n updateFromClientX(event.clientX);\n }}\n onPointerMove={onPointerMove}\n onKeyDown={onKeyDown}\n >\n <div\n className=\"amb-slider-thumb ambient amb-fillet amb-elevation-1 amb-surface-concave-h ambx-slider-thumb\"\n style={{ left: `${percent}%` }}\n >\n <div className=\"amb-slider-grip\">\n <span className=\"amb-fader-dot\" />\n <span className=\"amb-fader-dot\" />\n <span className=\"amb-fader-dot\" />\n </div>\n </div>\n </div>\n {label ? (\n <span id={id} className=\"ambx-label\">\n {label}\n </span>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","clamp","import_react","import_jsx_runtime","clamp"]}
@@ -0,0 +1,69 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { PropsWithChildren, CSSProperties, HTMLAttributes, ButtonHTMLAttributes } from 'react';
3
+
4
+ type AmbientTheme = {
5
+ lightX?: number;
6
+ lightY?: number;
7
+ keyLight?: number;
8
+ fillLight?: number;
9
+ lightHue?: number;
10
+ lightSaturation?: number;
11
+ highlightColor?: string;
12
+ lumeHue?: number;
13
+ };
14
+ type AmbientProviderProps = PropsWithChildren<{
15
+ className?: string;
16
+ style?: CSSProperties;
17
+ theme?: AmbientTheme;
18
+ }>;
19
+ declare function AmbientProvider({ children, className, style, theme }: AmbientProviderProps): react_jsx_runtime.JSX.Element;
20
+
21
+ type AmbientPanelProps = HTMLAttributes<HTMLDivElement>;
22
+ declare function AmbientPanel({ className, ...props }: AmbientPanelProps): react_jsx_runtime.JSX.Element;
23
+
24
+ type AmbientButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
25
+ declare function AmbientButton({ className, children, ...props }: AmbientButtonProps): react_jsx_runtime.JSX.Element;
26
+
27
+ type AmbientSwitchSize = "sm" | "md" | "lg";
28
+ type AmbientSwitchProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, "onChange"> & {
29
+ checked?: boolean;
30
+ defaultChecked?: boolean;
31
+ onCheckedChange?: (checked: boolean) => void;
32
+ size?: AmbientSwitchSize;
33
+ label?: string;
34
+ /** Show a small LED indicator that lights up when the switch is on. Pass `true` for default green or a CSS color string. */
35
+ led?: boolean | string;
36
+ };
37
+ declare function AmbientSwitch({ className, checked, defaultChecked, onCheckedChange, onClick, size, label, led, children, ...props }: AmbientSwitchProps): react_jsx_runtime.JSX.Element;
38
+
39
+ type AmbientKnobProps = Omit<HTMLAttributes<HTMLDivElement>, "onChange"> & {
40
+ value: number;
41
+ min?: number;
42
+ max?: number;
43
+ step?: number;
44
+ label?: string;
45
+ onChange?: (nextValue: number) => void;
46
+ };
47
+ declare function AmbientKnob({ value, min, max, step, label, onChange, className, ...props }: AmbientKnobProps): react_jsx_runtime.JSX.Element;
48
+
49
+ type AmbientFaderProps = Omit<HTMLAttributes<HTMLDivElement>, "onChange"> & {
50
+ value: number;
51
+ min?: number;
52
+ max?: number;
53
+ step?: number;
54
+ label?: string;
55
+ onChange?: (nextValue: number) => void;
56
+ };
57
+ declare function AmbientFader({ value, min, max, step, label, onChange, className, ...props }: AmbientFaderProps): react_jsx_runtime.JSX.Element;
58
+
59
+ type AmbientSliderProps = Omit<HTMLAttributes<HTMLDivElement>, "onChange"> & {
60
+ value: number;
61
+ min?: number;
62
+ max?: number;
63
+ step?: number;
64
+ label?: string;
65
+ onChange?: (nextValue: number) => void;
66
+ };
67
+ declare function AmbientSlider({ value, min, max, step, label, onChange, className, ...props }: AmbientSliderProps): react_jsx_runtime.JSX.Element;
68
+
69
+ export { AmbientButton, type AmbientButtonProps, AmbientFader, type AmbientFaderProps, AmbientKnob, type AmbientKnobProps, AmbientPanel, type AmbientPanelProps, AmbientProvider, type AmbientProviderProps, AmbientSlider, type AmbientSliderProps, AmbientSwitch, type AmbientSwitchProps, type AmbientSwitchSize, type AmbientTheme };