@mieweb/ui 0.1.0 → 0.2.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.
Files changed (88) hide show
  1. package/LICENSE +39 -15
  2. package/README.md +9 -1
  3. package/dist/brands/index.cjs +7 -7
  4. package/dist/brands/index.js +2 -2
  5. package/dist/{chunk-CLNOI5J7.js → chunk-4SMSH4OY.js} +4 -4
  6. package/dist/chunk-4SMSH4OY.js.map +1 -0
  7. package/dist/chunk-4T2ZNPTC.js +220 -0
  8. package/dist/chunk-4T2ZNPTC.js.map +1 -0
  9. package/dist/chunk-5T3AWNHG.cjs +471 -0
  10. package/dist/chunk-5T3AWNHG.cjs.map +1 -0
  11. package/dist/{chunk-LEE3NMNP.cjs → chunk-5UUL5EEO.cjs} +131 -81
  12. package/dist/chunk-5UUL5EEO.cjs.map +1 -0
  13. package/dist/chunk-74K3RRU7.cjs +4 -0
  14. package/dist/{chunk-ZO46CFVN.cjs.map → chunk-74K3RRU7.cjs.map} +1 -1
  15. package/dist/{chunk-VWXGUNBR.cjs → chunk-AKTUXJPI.cjs} +107 -18
  16. package/dist/chunk-AKTUXJPI.cjs.map +1 -0
  17. package/dist/chunk-BV75DAKO.cjs +245 -0
  18. package/dist/chunk-BV75DAKO.cjs.map +1 -0
  19. package/dist/{chunk-6DP6RKUA.cjs → chunk-CLJZHS7Y.cjs} +2 -2
  20. package/dist/{chunk-6DP6RKUA.cjs.map → chunk-CLJZHS7Y.cjs.map} +1 -1
  21. package/dist/{chunk-NH2JVQ6V.cjs → chunk-I7L6CQXR.cjs} +21 -9
  22. package/dist/chunk-I7L6CQXR.cjs.map +1 -0
  23. package/dist/{chunk-BR2XGATJ.cjs → chunk-NNEFAUHV.cjs} +4 -4
  24. package/dist/chunk-NNEFAUHV.cjs.map +1 -0
  25. package/dist/{chunk-KJOFWJHV.js → chunk-QSMMFATL.js} +131 -81
  26. package/dist/chunk-QSMMFATL.js.map +1 -0
  27. package/dist/{chunk-FIUNOH6W.js → chunk-S4DK5WN6.js} +2 -2
  28. package/dist/{chunk-FIUNOH6W.js.map → chunk-S4DK5WN6.js.map} +1 -1
  29. package/dist/chunk-SCV7C55E.cjs +11 -0
  30. package/dist/chunk-SCV7C55E.cjs.map +1 -0
  31. package/dist/{chunk-D5IBXXF2.js → chunk-SD44QJIP.js} +20 -8
  32. package/dist/chunk-SD44QJIP.js.map +1 -0
  33. package/dist/{chunk-QBWVTJKF.js → chunk-UBRDKNLQ.js} +107 -18
  34. package/dist/chunk-UBRDKNLQ.js.map +1 -0
  35. package/dist/chunk-V2DF2GUE.js +3 -0
  36. package/dist/{chunk-ZQ4XMJH7.js.map → chunk-V2DF2GUE.js.map} +1 -1
  37. package/dist/chunk-VSQF22GL.js +9 -0
  38. package/dist/chunk-VSQF22GL.js.map +1 -0
  39. package/dist/chunk-XVZ4SLQB.js +447 -0
  40. package/dist/chunk-XVZ4SLQB.js.map +1 -0
  41. package/dist/components/AudioPlayer/index.cjs +6 -6
  42. package/dist/components/AudioPlayer/index.d.cts +5 -1
  43. package/dist/components/AudioPlayer/index.d.ts +5 -1
  44. package/dist/components/AudioPlayer/index.js +1 -1
  45. package/dist/components/Modal/index.cjs +11 -10
  46. package/dist/components/Modal/index.js +3 -2
  47. package/dist/components/RecordButton/index.cjs +4 -8
  48. package/dist/components/RecordButton/index.d.cts +57 -44
  49. package/dist/components/RecordButton/index.d.ts +57 -44
  50. package/dist/components/RecordButton/index.js +1 -1
  51. package/dist/components/Select/index.cjs +3 -4
  52. package/dist/components/Select/index.js +1 -2
  53. package/dist/components/Slider/index.cjs +25 -0
  54. package/dist/components/Slider/index.cjs.map +1 -0
  55. package/dist/components/Slider/index.d.cts +82 -0
  56. package/dist/components/Slider/index.d.ts +82 -0
  57. package/dist/components/Slider/index.js +4 -0
  58. package/dist/components/Slider/index.js.map +1 -0
  59. package/dist/components/Spinner/index.d.cts +1 -1
  60. package/dist/components/Spinner/index.d.ts +1 -1
  61. package/dist/hooks/index.cjs +3 -2
  62. package/dist/hooks/index.js +2 -1
  63. package/dist/index.cjs +1899 -1238
  64. package/dist/index.cjs.map +1 -1
  65. package/dist/index.d.cts +68 -25
  66. package/dist/index.d.ts +68 -25
  67. package/dist/index.js +1793 -1148
  68. package/dist/index.js.map +1 -1
  69. package/dist/styles.css +1 -1
  70. package/dist/utils/index.cjs +6 -1
  71. package/dist/utils/index.d.cts +14 -1
  72. package/dist/utils/index.d.ts +14 -1
  73. package/dist/utils/index.js +2 -1
  74. package/package.json +7 -7
  75. package/dist/chunk-BR2XGATJ.cjs.map +0 -1
  76. package/dist/chunk-CLNOI5J7.js.map +0 -1
  77. package/dist/chunk-D5IBXXF2.js.map +0 -1
  78. package/dist/chunk-FQ5G7J24.js +0 -297
  79. package/dist/chunk-FQ5G7J24.js.map +0 -1
  80. package/dist/chunk-HLW3XD5R.cjs +0 -322
  81. package/dist/chunk-HLW3XD5R.cjs.map +0 -1
  82. package/dist/chunk-KJOFWJHV.js.map +0 -1
  83. package/dist/chunk-LEE3NMNP.cjs.map +0 -1
  84. package/dist/chunk-NH2JVQ6V.cjs.map +0 -1
  85. package/dist/chunk-QBWVTJKF.js.map +0 -1
  86. package/dist/chunk-VWXGUNBR.cjs.map +0 -1
  87. package/dist/chunk-ZO46CFVN.cjs +0 -4
  88. package/dist/chunk-ZQ4XMJH7.js +0 -3
package/LICENSE CHANGED
@@ -1,21 +1,45 @@
1
- MIT License
1
+ @mieweb/ui - Source Available License
2
2
 
3
- Copyright (c) 2026 MIE Web Team
3
+ Copyright (c) 2026 Medical Informatics Engineering, LLC. All rights reserved.
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ This software and associated documentation files (the "Software") are the
6
+ proprietary property of Medical Informatics Engineering, LLC. ("MIE").
11
7
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
8
+ OPEN SOURCE / NON-COMMERCIAL USE
9
+
10
+ Permission is hereby granted, free of charge, to any person or organization
11
+ obtaining a copy of this Software, to use, copy, modify, merge, and distribute
12
+ the Software for non-commercial purposes, subject to the following conditions:
13
+
14
+ 1. Attribution Required: The above copyright notice, this permission notice,
15
+ and clear attribution to Medical Informatics Engineering, LLC. shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ 2. Open Source Requirement: If you distribute the Software or any derivative
19
+ works, you must do so under an open source license approved by the Open
20
+ Source Initiative (OSI) and make the source code publicly available.
21
+
22
+ 3. Non-Commercial Use Only: This license does not grant permission to use the
23
+ Software for commercial purposes. "Commercial purposes" means any use
24
+ intended for or directed toward commercial advantage or monetary
25
+ compensation.
26
+
27
+ COMMERCIAL USE
28
+
29
+ For commercial use, including but not limited to:
30
+ - Use in proprietary/closed-source products
31
+ - Use in products or services sold for profit
32
+ - Use by for-profit organizations for internal business operations
33
+
34
+ You must obtain a separate commercial license from Medical Informatics
35
+ Engineering, LLC. Contact: https://www.mieweb.com or helpdesk@mieweb.com
36
+
37
+ NO WARRANTY
14
38
 
15
39
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
40
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
41
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
42
+ MEDICAL INFORMATICS ENGINEERING, LLC. OR ITS AFFILIATES BE LIABLE FOR ANY
43
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
44
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
45
+ OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -693,4 +693,12 @@ We welcome contributions! Here's how to get started:
693
693
 
694
694
  ## License
695
695
 
696
- MIT © MIE Web Team
696
+ Copyright © 2026 Medical Informatics Engineering, Inc. All rights reserved.
697
+
698
+ This software is **source available** with the following terms:
699
+
700
+ - ✅ **Free for open source projects** - Use, modify, and distribute freely in open source projects with attribution
701
+ - ✅ **Free for non-commercial use** - Personal projects, education, research
702
+ - 💼 **Commercial license required** - For proprietary products or commercial use, contact [licensing@mieweb.com](mailto:licensing@mieweb.com)
703
+
704
+ See the [LICENSE](LICENSE) file for full details.
@@ -1,19 +1,23 @@
1
1
  'use strict';
2
2
 
3
- var chunk6DP6RKUA_cjs = require('../chunk-6DP6RKUA.cjs');
3
+ var chunkCLJZHS7Y_cjs = require('../chunk-CLJZHS7Y.cjs');
4
+ var chunkP52GA3GJ_cjs = require('../chunk-P52GA3GJ.cjs');
4
5
  var chunkS6UNPMAS_cjs = require('../chunk-S6UNPMAS.cjs');
5
6
  var chunkSWV5E75F_cjs = require('../chunk-SWV5E75F.cjs');
6
7
  var chunkZ3TFPXVN_cjs = require('../chunk-Z3TFPXVN.cjs');
7
8
  var chunkFFJVCQ5R_cjs = require('../chunk-FFJVCQ5R.cjs');
8
9
  var chunk4LNS5QDP_cjs = require('../chunk-4LNS5QDP.cjs');
9
10
  var chunkO5HS7ZND_cjs = require('../chunk-O5HS7ZND.cjs');
10
- var chunkP52GA3GJ_cjs = require('../chunk-P52GA3GJ.cjs');
11
11
 
12
12
 
13
13
 
14
14
  Object.defineProperty(exports, "brands", {
15
15
  enumerable: true,
16
- get: function () { return chunk6DP6RKUA_cjs.brands; }
16
+ get: function () { return chunkCLJZHS7Y_cjs.brands; }
17
+ });
18
+ Object.defineProperty(exports, "enterpriseHealthBrand", {
19
+ enumerable: true,
20
+ get: function () { return chunkP52GA3GJ_cjs.enterpriseHealthBrand; }
17
21
  });
18
22
  Object.defineProperty(exports, "miewebBrand", {
19
23
  enumerable: true,
@@ -47,9 +51,5 @@ Object.defineProperty(exports, "defaultBrand", {
47
51
  enumerable: true,
48
52
  get: function () { return chunkO5HS7ZND_cjs.defaultBrand; }
49
53
  });
50
- Object.defineProperty(exports, "enterpriseHealthBrand", {
51
- enumerable: true,
52
- get: function () { return chunkP52GA3GJ_cjs.enterpriseHealthBrand; }
53
- });
54
54
  //# sourceMappingURL=index.cjs.map
55
55
  //# sourceMappingURL=index.cjs.map
@@ -1,10 +1,10 @@
1
- export { brands } from '../chunk-FIUNOH6W.js';
1
+ export { brands } from '../chunk-S4DK5WN6.js';
2
+ export { enterpriseHealthBrand } from '../chunk-MTZPVOP6.js';
2
3
  export { miewebBrand } from '../chunk-UHSPAFY6.js';
3
4
  export { wagglelineBrand } from '../chunk-OWPWP46L.js';
4
5
  export { webchartBrand } from '../chunk-C6MDPPPL.js';
5
6
  export { createBrandPreset, generateBrandCSS, generateTailwindTheme } from '../chunk-SOFX4T7M.js';
6
7
  export { bluehiveBrand } from '../chunk-ULOA7WBW.js';
7
8
  export { defaultBrand } from '../chunk-4LTN2LEN.js';
8
- export { enterpriseHealthBrand } from '../chunk-MTZPVOP6.js';
9
9
  //# sourceMappingURL=index.js.map
10
10
  //# sourceMappingURL=index.js.map
@@ -1,10 +1,10 @@
1
+ import { isStorybookDocsMode } from './chunk-VSQF22GL.js';
1
2
  import { useRef, useEffect } from 'react';
2
3
 
3
- // src/hooks/useFocusTrap.ts
4
4
  function useFocusTrap(enabled = true) {
5
5
  const containerRef = useRef(null);
6
6
  useEffect(() => {
7
- if (!enabled || !containerRef.current) return;
7
+ if (!enabled || !containerRef.current || isStorybookDocsMode()) return;
8
8
  const container = containerRef.current;
9
9
  const focusableElements = container.querySelectorAll(
10
10
  'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
@@ -34,5 +34,5 @@ function useFocusTrap(enabled = true) {
34
34
  }
35
35
 
36
36
  export { useFocusTrap };
37
- //# sourceMappingURL=chunk-CLNOI5J7.js.map
38
- //# sourceMappingURL=chunk-CLNOI5J7.js.map
37
+ //# sourceMappingURL=chunk-4SMSH4OY.js.map
38
+ //# sourceMappingURL=chunk-4SMSH4OY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useFocusTrap.ts"],"names":[],"mappings":";;;AAuBO,SAAS,YAAA,CACd,UAAU,IAAA,EACW;AACrB,EAAA,MAAM,YAAA,GAAe,OAAU,IAAI,CAAA;AAEnC,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,YAAA,CAAa,OAAA,IAAW,qBAAoB,EAAG;AAEhE,IAAA,MAAM,YAAY,YAAA,CAAa,OAAA;AAC/B,IAAA,MAAM,oBAAoB,SAAA,CAAU,gBAAA;AAAA,MAClC;AAAA,KACF;AAEA,IAAA,IAAI,iBAAA,CAAkB,WAAW,CAAA,EAAG;AAEpC,IAAA,MAAM,YAAA,GAAe,kBAAkB,CAAC,CAAA;AACxC,IAAA,MAAM,WAAA,GAAc,iBAAA,CAAkB,iBAAA,CAAkB,MAAA,GAAS,CAAC,CAAA;AAGlE,IAAA,YAAA,CAAa,KAAA,EAAM;AAEnB,IAAA,MAAM,aAAA,GAAgB,CAAC,KAAA,KAAoC;AACzD,MAAA,IAAI,KAAA,CAAM,QAAQ,KAAA,EAAO;AAEzB,MAAA,IAAI,MAAM,QAAA,EAAU;AAElB,QAAA,IAAI,QAAA,CAAS,kBAAkB,YAAA,EAAc;AAC3C,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,WAAA,CAAY,KAAA,EAAM;AAAA,QACpB;AAAA,MACF,CAAA,MAAO;AAEL,QAAA,IAAI,QAAA,CAAS,kBAAkB,WAAA,EAAa;AAC1C,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,YAAA,CAAa,KAAA,EAAM;AAAA,QACrB;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,SAAA,CAAU,gBAAA,CAAiB,WAAW,aAAa,CAAA;AACnD,IAAA,OAAO,MAAM,SAAA,CAAU,mBAAA,CAAoB,SAAA,EAAW,aAAa,CAAA;AAAA,EACrE,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,OAAO,YAAA;AACT","file":"chunk-4SMSH4OY.js","sourcesContent":["import { useEffect, useRef, type RefObject } from 'react';\nimport { isStorybookDocsMode } from '../utils/environment';\n\n/**\n * Hook that traps focus within a container element.\n * Essential for accessibility in modals and dialogs.\n *\n * @param enabled - Whether focus trapping is active\n * @returns ref to attach to the container element\n *\n * @example\n * ```tsx\n * function Modal({ isOpen }: { isOpen: boolean }) {\n * const containerRef = useFocusTrap<HTMLDivElement>(isOpen);\n * return (\n * <div ref={containerRef} role=\"dialog\" aria-modal=\"true\">\n * <button>First focusable</button>\n * <button>Last focusable</button>\n * </div>\n * );\n * }\n * ```\n */\nexport function useFocusTrap<T extends HTMLElement>(\n enabled = true\n): RefObject<T | null> {\n const containerRef = useRef<T>(null);\n\n useEffect(() => {\n // Skip focus trap in Storybook docs mode to prevent auto-scroll\n if (!enabled || !containerRef.current || isStorybookDocsMode()) return;\n\n const container = containerRef.current;\n const focusableElements = container.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n );\n\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n // Focus the first element when trap is enabled\n firstElement.focus();\n\n const handleKeyDown = (event: globalThis.KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n\n if (event.shiftKey) {\n // Shift + Tab\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n // Tab\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n container.addEventListener('keydown', handleKeyDown);\n return () => container.removeEventListener('keydown', handleKeyDown);\n }, [enabled]);\n\n return containerRef;\n}\n"]}
@@ -0,0 +1,220 @@
1
+ import { cn } from './chunk-F3SOEIN2.js';
2
+ import * as React from 'react';
3
+ import { cva } from 'class-variance-authority';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ var sliderTrackVariants = cva(
7
+ [
8
+ "relative w-full overflow-hidden rounded-full",
9
+ "bg-neutral-200 dark:bg-neutral-700",
10
+ "cursor-pointer",
11
+ "group-data-[disabled=true]:cursor-not-allowed group-data-[disabled=true]:opacity-50"
12
+ ],
13
+ {
14
+ variants: {
15
+ size: {
16
+ sm: "h-1",
17
+ md: "h-2",
18
+ lg: "h-3"
19
+ }
20
+ },
21
+ defaultVariants: {
22
+ size: "md"
23
+ }
24
+ }
25
+ );
26
+ var sliderRangeVariants = cva(
27
+ ["absolute h-full rounded-full transition-all duration-75 ease-out"],
28
+ {
29
+ variants: {
30
+ variant: {
31
+ default: "bg-primary-500",
32
+ success: "bg-green-500",
33
+ warning: "bg-yellow-500",
34
+ danger: "bg-red-500",
35
+ neutral: "bg-neutral-500"
36
+ }
37
+ },
38
+ defaultVariants: {
39
+ variant: "default"
40
+ }
41
+ }
42
+ );
43
+ var sliderThumbVariants = cva(
44
+ [
45
+ "absolute top-1/2 -translate-y-1/2 -translate-x-1/2",
46
+ "rounded-full border-2 bg-white",
47
+ "shadow-md transition-shadow duration-150",
48
+ "peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2",
49
+ "peer-hover:shadow-lg",
50
+ "peer-active:shadow-xl peer-active:scale-110",
51
+ "group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50"
52
+ ],
53
+ {
54
+ variants: {
55
+ size: {
56
+ sm: "h-3.5 w-3.5",
57
+ md: "h-5 w-5",
58
+ lg: "h-6 w-6"
59
+ },
60
+ variant: {
61
+ default: "border-primary-500",
62
+ success: "border-green-500",
63
+ warning: "border-yellow-500",
64
+ danger: "border-red-500",
65
+ neutral: "border-neutral-500"
66
+ }
67
+ },
68
+ defaultVariants: {
69
+ size: "md",
70
+ variant: "default"
71
+ }
72
+ }
73
+ );
74
+ var Slider = React.forwardRef(
75
+ ({
76
+ value: controlledValue,
77
+ defaultValue = 0,
78
+ min = 0,
79
+ max = 100,
80
+ step = 1,
81
+ onValueChange,
82
+ onValueCommit,
83
+ disabled = false,
84
+ label,
85
+ showValue = false,
86
+ formatValue,
87
+ description,
88
+ minLabel,
89
+ maxLabel,
90
+ variant,
91
+ size,
92
+ className,
93
+ trackClassName,
94
+ id,
95
+ name,
96
+ "aria-label": ariaLabelProp,
97
+ "aria-labelledby": ariaLabelledByProp
98
+ }, ref) => {
99
+ const hasExplicitLabel = !!label;
100
+ const ariaLabelledBy = ariaLabelledByProp;
101
+ const ariaLabel = ariaLabelProp ?? (!hasExplicitLabel && !ariaLabelledByProp ? "Slider" : void 0);
102
+ const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
103
+ const isControlled = controlledValue !== void 0;
104
+ const currentValue = isControlled ? controlledValue : uncontrolledValue;
105
+ const clampedValue = Math.min(Math.max(currentValue, min), max);
106
+ const percentage = max !== min ? (clampedValue - min) / (max - min) * 100 : 0;
107
+ const generatedId = React.useId();
108
+ const inputId = id ?? generatedId;
109
+ const handleChange = (e) => {
110
+ const newValue = parseFloat(e.target.value);
111
+ if (!isControlled) {
112
+ setUncontrolledValue(newValue);
113
+ }
114
+ onValueChange?.(newValue);
115
+ };
116
+ const handleCommit = () => {
117
+ onValueCommit?.(clampedValue);
118
+ };
119
+ const displayValue = formatValue ? formatValue(clampedValue) : String(clampedValue);
120
+ return /* @__PURE__ */ jsxs(
121
+ "div",
122
+ {
123
+ className: cn("w-full", className),
124
+ "data-disabled": disabled || void 0,
125
+ children: [
126
+ (label || showValue) && /* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex items-baseline justify-between", children: [
127
+ label && /* @__PURE__ */ jsxs(
128
+ "label",
129
+ {
130
+ htmlFor: inputId,
131
+ className: cn(
132
+ "text-foreground text-sm font-medium",
133
+ disabled && "opacity-50"
134
+ ),
135
+ children: [
136
+ label,
137
+ showValue && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground ml-1", children: displayValue })
138
+ ]
139
+ }
140
+ ),
141
+ !label && showValue && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: displayValue })
142
+ ] }),
143
+ description && /* @__PURE__ */ jsx(
144
+ "p",
145
+ {
146
+ className: cn(
147
+ "text-muted-foreground mb-2 text-xs",
148
+ disabled && "opacity-50"
149
+ ),
150
+ children: description
151
+ }
152
+ ),
153
+ /* @__PURE__ */ jsxs("div", { className: "group relative", "data-disabled": disabled || void 0, children: [
154
+ /* @__PURE__ */ jsx("div", { className: cn(sliderTrackVariants({ size }), trackClassName), children: /* @__PURE__ */ jsx(
155
+ "div",
156
+ {
157
+ className: sliderRangeVariants({ variant }),
158
+ style: { width: `${percentage}%` }
159
+ }
160
+ ) }),
161
+ /* @__PURE__ */ jsx(
162
+ "input",
163
+ {
164
+ ref,
165
+ type: "range",
166
+ className: cn(
167
+ "peer absolute inset-0 h-full w-full cursor-pointer opacity-0",
168
+ disabled && "cursor-not-allowed"
169
+ ),
170
+ id: inputId,
171
+ name,
172
+ min,
173
+ max,
174
+ step,
175
+ value: clampedValue,
176
+ onChange: handleChange,
177
+ onMouseUp: handleCommit,
178
+ onTouchEnd: handleCommit,
179
+ onKeyUp: handleCommit,
180
+ onBlur: handleCommit,
181
+ disabled,
182
+ "aria-label": ariaLabel,
183
+ "aria-labelledby": ariaLabelledBy,
184
+ "aria-valuemin": min,
185
+ "aria-valuemax": max,
186
+ "aria-valuenow": clampedValue
187
+ }
188
+ ),
189
+ /* @__PURE__ */ jsx(
190
+ "div",
191
+ {
192
+ className: sliderThumbVariants({ size, variant }),
193
+ style: { left: `${percentage}%` },
194
+ "aria-hidden": "true"
195
+ }
196
+ )
197
+ ] }),
198
+ (minLabel || maxLabel) && /* @__PURE__ */ jsxs(
199
+ "div",
200
+ {
201
+ className: cn(
202
+ "text-muted-foreground mt-1 flex justify-between text-xs",
203
+ disabled && "opacity-50"
204
+ ),
205
+ children: [
206
+ /* @__PURE__ */ jsx("span", { children: minLabel }),
207
+ /* @__PURE__ */ jsx("span", { children: maxLabel })
208
+ ]
209
+ }
210
+ )
211
+ ]
212
+ }
213
+ );
214
+ }
215
+ );
216
+ Slider.displayName = "Slider";
217
+
218
+ export { Slider, sliderRangeVariants, sliderThumbVariants, sliderTrackVariants };
219
+ //# sourceMappingURL=chunk-4T2ZNPTC.js.map
220
+ //# sourceMappingURL=chunk-4T2ZNPTC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Slider/Slider.tsx"],"names":[],"mappings":"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","file":"chunk-4T2ZNPTC.js","sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\n\n// ============================================================================\n// Slider Variants\n// ============================================================================\n\nconst sliderTrackVariants = cva(\n [\n 'relative w-full overflow-hidden rounded-full',\n 'bg-neutral-200 dark:bg-neutral-700',\n 'cursor-pointer',\n 'group-data-[disabled=true]:cursor-not-allowed group-data-[disabled=true]:opacity-50',\n ],\n {\n variants: {\n size: {\n sm: 'h-1',\n md: 'h-2',\n lg: 'h-3',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n }\n);\n\nconst sliderRangeVariants = cva(\n ['absolute h-full rounded-full transition-all duration-75 ease-out'],\n {\n variants: {\n variant: {\n default: 'bg-primary-500',\n success: 'bg-green-500',\n warning: 'bg-yellow-500',\n danger: 'bg-red-500',\n neutral: 'bg-neutral-500',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\nconst sliderThumbVariants = cva(\n [\n 'absolute top-1/2 -translate-y-1/2 -translate-x-1/2',\n 'rounded-full border-2 bg-white',\n 'shadow-md transition-shadow duration-150',\n 'peer-focus-visible:outline-none peer-focus-visible:ring-2 peer-focus-visible:ring-ring peer-focus-visible:ring-offset-2',\n 'peer-hover:shadow-lg',\n 'peer-active:shadow-xl peer-active:scale-110',\n 'group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50',\n ],\n {\n variants: {\n size: {\n sm: 'h-3.5 w-3.5',\n md: 'h-5 w-5',\n lg: 'h-6 w-6',\n },\n variant: {\n default: 'border-primary-500',\n success: 'border-green-500',\n warning: 'border-yellow-500',\n danger: 'border-red-500',\n neutral: 'border-neutral-500',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n }\n);\n\n// ============================================================================\n// Slider Component\n// ============================================================================\n\nexport interface SliderProps\n extends\n VariantProps<typeof sliderTrackVariants>,\n VariantProps<typeof sliderRangeVariants> {\n /** Current value (controlled) */\n value?: number;\n /** Default value (uncontrolled) */\n defaultValue?: number;\n /** Minimum value */\n min?: number;\n /** Maximum value */\n max?: number;\n /** Step increment */\n step?: number;\n /** Callback when value changes */\n onValueChange?: (value: number) => void;\n /** Callback when interaction ends (mouseup / touchend) */\n onValueCommit?: (value: number) => void;\n /** Whether the slider is disabled */\n disabled?: boolean;\n /** Label for the slider */\n label?: string;\n /** Show the current value */\n showValue?: boolean;\n /** Format the displayed value */\n formatValue?: (value: number) => string;\n /** Description text below the label */\n description?: string;\n /** Min label displayed below the track (left) */\n minLabel?: string;\n /** Max label displayed below the track (right) */\n maxLabel?: string;\n /** Additional class name for the root container */\n className?: string;\n /** Additional class name for the track */\n trackClassName?: string;\n /** ID for the underlying input */\n id?: string;\n /** Name for form submission */\n name?: string;\n /** Accessible label for the slider */\n 'aria-label'?: string;\n /** ID of the element that labels the slider */\n 'aria-labelledby'?: string;\n}\n\n/**\n * A fully branded, accessible slider/range input component.\n *\n * Uses brand design tokens for colors, border-radius, and sizing.\n * Supports controlled and uncontrolled usage, labels, descriptions,\n * min/max labels, value display, and multiple color variants.\n *\n * @example\n * ```tsx\n * <Slider label=\"Volume\" min={0} max={100} defaultValue={50} />\n * <Slider\n * label=\"Border Radius\"\n * min={0}\n * max={32}\n * value={radius}\n * onValueChange={setRadius}\n * showValue\n * formatValue={(v) => `${v}px`}\n * minLabel=\"Square\"\n * maxLabel=\"Rounded\"\n * />\n * ```\n */\nconst Slider = React.forwardRef<HTMLInputElement, SliderProps>(\n (\n {\n value: controlledValue,\n defaultValue = 0,\n min = 0,\n max = 100,\n step = 1,\n onValueChange,\n onValueCommit,\n disabled = false,\n label,\n showValue = false,\n formatValue,\n description,\n minLabel,\n maxLabel,\n variant,\n size,\n className,\n trackClassName,\n id,\n name,\n 'aria-label': ariaLabelProp,\n 'aria-labelledby': ariaLabelledByProp,\n },\n ref\n ) => {\n const hasExplicitLabel = !!label;\n const ariaLabelledBy = ariaLabelledByProp;\n const ariaLabel =\n ariaLabelProp ??\n (!hasExplicitLabel && !ariaLabelledByProp ? 'Slider' : undefined);\n const [uncontrolledValue, setUncontrolledValue] =\n React.useState(defaultValue);\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : uncontrolledValue;\n\n // Clamp value to min/max\n const clampedValue = Math.min(Math.max(currentValue, min), max);\n\n // Percentage for visual fill\n const percentage =\n max !== min ? ((clampedValue - min) / (max - min)) * 100 : 0;\n\n const generatedId = React.useId();\n const inputId = id ?? generatedId;\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isControlled) {\n setUncontrolledValue(newValue);\n }\n onValueChange?.(newValue);\n };\n\n const handleCommit = () => {\n onValueCommit?.(clampedValue);\n };\n\n const displayValue = formatValue\n ? formatValue(clampedValue)\n : String(clampedValue);\n\n return (\n <div\n className={cn('w-full', className)}\n data-disabled={disabled || undefined}\n >\n {/* Label row */}\n {(label || showValue) && (\n <div className=\"mb-1.5 flex items-baseline justify-between\">\n {label && (\n <label\n htmlFor={inputId}\n className={cn(\n 'text-foreground text-sm font-medium',\n disabled && 'opacity-50'\n )}\n >\n {label}\n {showValue && (\n <span className=\"text-muted-foreground ml-1\">\n {displayValue}\n </span>\n )}\n </label>\n )}\n {!label && showValue && (\n <span className=\"text-muted-foreground text-sm\">\n {displayValue}\n </span>\n )}\n </div>\n )}\n\n {/* Description */}\n {description && (\n <p\n className={cn(\n 'text-muted-foreground mb-2 text-xs',\n disabled && 'opacity-50'\n )}\n >\n {description}\n </p>\n )}\n\n {/* Track + Thumb */}\n <div className=\"group relative\" data-disabled={disabled || undefined}>\n {/* Visual track background */}\n <div className={cn(sliderTrackVariants({ size }), trackClassName)}>\n {/* Filled range */}\n <div\n className={sliderRangeVariants({ variant })}\n style={{ width: `${percentage}%` }}\n />\n </div>\n\n {/* Native range input — stretched to fill, made invisible */}\n <input\n ref={ref}\n type=\"range\"\n className={cn(\n 'peer absolute inset-0 h-full w-full cursor-pointer opacity-0',\n disabled && 'cursor-not-allowed'\n )}\n id={inputId}\n name={name}\n min={min}\n max={max}\n step={step}\n value={clampedValue}\n onChange={handleChange}\n onMouseUp={handleCommit}\n onTouchEnd={handleCommit}\n onKeyUp={handleCommit}\n onBlur={handleCommit}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-valuenow={clampedValue}\n />\n\n {/* Thumb indicator (visual only) */}\n <div\n className={sliderThumbVariants({ size, variant })}\n style={{ left: `${percentage}%` }}\n aria-hidden=\"true\"\n />\n </div>\n\n {/* Min / Max labels */}\n {(minLabel || maxLabel) && (\n <div\n className={cn(\n 'text-muted-foreground mt-1 flex justify-between text-xs',\n disabled && 'opacity-50'\n )}\n >\n <span>{minLabel}</span>\n <span>{maxLabel}</span>\n </div>\n )}\n </div>\n );\n }\n);\n\nSlider.displayName = 'Slider';\n\nexport {\n Slider,\n sliderTrackVariants,\n sliderRangeVariants,\n sliderThumbVariants,\n};\n"]}