@moontra/moonui 3.3.0 → 3.4.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/dist/index.js CHANGED
@@ -1717,14 +1717,14 @@ var CarouselNext = React10__namespace.forwardRef(({ className, variant = "outlin
1717
1717
  });
1718
1718
  CarouselNext.displayName = "CarouselNext";
1719
1719
  var checkboxVariants = classVarianceAuthority.cva(
1720
- "peer shrink-0 border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:text-primary-foreground",
1720
+ "peer shrink-0 border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:text-primary-foreground data-[state=indeterminate]:text-primary-foreground",
1721
1721
  {
1722
1722
  variants: {
1723
1723
  variant: {
1724
- default: "border-border bg-background data-[state=checked]:bg-primary data-[state=checked]:border-primary",
1725
- outline: "border-border bg-transparent data-[state=checked]:bg-primary data-[state=checked]:border-primary",
1726
- muted: "border-border bg-accent data-[state=checked]:bg-primary data-[state=checked]:border-primary",
1727
- ghost: "border-transparent bg-transparent hover:bg-accent data-[state=checked]:bg-primary data-[state=checked]:border-primary"
1724
+ default: "border-border bg-background data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary",
1725
+ outline: "border-border bg-transparent data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary",
1726
+ muted: "border-border bg-accent data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary",
1727
+ ghost: "border-transparent bg-transparent hover:bg-accent data-[state=checked]:bg-primary data-[state=checked]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:border-primary"
1728
1728
  },
1729
1729
  size: {
1730
1730
  sm: "h-3.5 w-3.5",
@@ -1765,11 +1765,7 @@ var Checkbox = React10__namespace.forwardRef(({
1765
1765
  checked,
1766
1766
  ...props
1767
1767
  }, ref) => {
1768
- const [isIndeterminate, setIsIndeterminate] = React10__namespace.useState(indeterminate);
1769
- React10__namespace.useEffect(() => {
1770
- setIsIndeterminate(indeterminate);
1771
- }, [indeterminate]);
1772
- const effectiveChecked = isIndeterminate ? false : checked;
1768
+ const effectiveChecked = indeterminate ? "indeterminate" : checked;
1773
1769
  return /* @__PURE__ */ jsxRuntime.jsx(
1774
1770
  CheckboxPrimitive__namespace.Root,
1775
1771
  {
@@ -1784,7 +1780,7 @@ var Checkbox = React10__namespace.forwardRef(({
1784
1780
  "flex items-center justify-center text-current",
1785
1781
  animation === "bounce" && "data-[state=checked]:animate-bounce"
1786
1782
  ),
1787
- children: isIndeterminate ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { className: "h-[65%] w-[65%]" }) : icon ? icon : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-[65%] w-[65%]" })
1783
+ children: indeterminate ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Minus, { className: "h-[65%] w-[65%]" }) : icon ? icon : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-[65%] w-[65%]" })
1788
1784
  }
1789
1785
  )
1790
1786
  }
@@ -2576,6 +2572,44 @@ var Slider = React10__namespace.forwardRef(({
2576
2572
  document.addEventListener("mousemove", handleMouseMove);
2577
2573
  document.addEventListener("mouseup", handleMouseUp);
2578
2574
  };
2575
+ const handleThumbKeyDown = (index) => (event) => {
2576
+ if (disabled)
2577
+ return;
2578
+ const largeStep = step * 10;
2579
+ const current = sliderValue[index];
2580
+ let next;
2581
+ switch (event.key) {
2582
+ case "ArrowRight":
2583
+ case "ArrowUp":
2584
+ next = current + step;
2585
+ break;
2586
+ case "ArrowLeft":
2587
+ case "ArrowDown":
2588
+ next = current - step;
2589
+ break;
2590
+ case "PageUp":
2591
+ next = current + largeStep;
2592
+ break;
2593
+ case "PageDown":
2594
+ next = current - largeStep;
2595
+ break;
2596
+ case "Home":
2597
+ next = min;
2598
+ break;
2599
+ case "End":
2600
+ next = max;
2601
+ break;
2602
+ default:
2603
+ return;
2604
+ }
2605
+ event.preventDefault();
2606
+ const lowerBound = index > 0 ? sliderValue[index - 1] : min;
2607
+ const upperBound = index < sliderValue.length - 1 ? sliderValue[index + 1] : max;
2608
+ const bounded = Math.max(lowerBound, Math.min(upperBound, next));
2609
+ const newValues = [...sliderValue];
2610
+ newValues[index] = bounded;
2611
+ handleValueChange(newValues);
2612
+ };
2579
2613
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full", ref, ...props, children: [
2580
2614
  showValueLabel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
2581
2615
  "flex justify-end mb-1 text-sm text-muted-foreground",
@@ -2625,6 +2659,7 @@ var Slider = React10__namespace.forwardRef(({
2625
2659
  cursor: disabled ? "not-allowed" : "pointer"
2626
2660
  },
2627
2661
  onMouseDown: handleThumbMouseDown(i),
2662
+ onKeyDown: handleThumbKeyDown(i),
2628
2663
  "aria-label": `Thumb ${i + 1}`,
2629
2664
  tabIndex: disabled ? -1 : 0,
2630
2665
  role: "slider",
@@ -3143,8 +3178,12 @@ function ColorPicker({
3143
3178
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-10 gap-1", children: presets.map((presetColor) => /* @__PURE__ */ jsxRuntime.jsx(
3144
3179
  "button",
3145
3180
  {
3181
+ type: "button",
3182
+ "aria-label": `Select color ${presetColor}`,
3183
+ "aria-pressed": color === presetColor,
3146
3184
  className: cn(
3147
3185
  "h-7 w-7 rounded border-2 transition-all hover:scale-110",
3186
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3148
3187
  color === presetColor ? "border-primary" : "border-transparent"
3149
3188
  ),
3150
3189
  style: { backgroundColor: presetColor },
@@ -3171,8 +3210,12 @@ function SimpleColorPicker({
3171
3210
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("moonui-theme", "flex flex-wrap gap-2", className), children: colors.map((color) => /* @__PURE__ */ jsxRuntime.jsx(
3172
3211
  "button",
3173
3212
  {
3213
+ type: "button",
3214
+ "aria-label": `Select color ${color}`,
3215
+ "aria-pressed": value === color,
3174
3216
  className: cn(
3175
3217
  "rounded-full border-2 transition-all hover:scale-110",
3218
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
3176
3219
  sizeClasses[size],
3177
3220
  value === color ? "border-primary ring-2 ring-primary/20" : "border-transparent"
3178
3221
  ),
@@ -6129,16 +6172,41 @@ var radioGroupItemVariants = classVarianceAuthority.cva(
6129
6172
  );
6130
6173
  var RadioGroupContext = React10__namespace.createContext({});
6131
6174
  var RadioGroup2 = React10__namespace.forwardRef(
6132
- ({ className, value, onValueChange, disabled, name, ...props }, ref) => {
6133
- return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupContext.Provider, { value: { value, onValueChange, disabled, name }, children: /* @__PURE__ */ jsxRuntime.jsx(
6134
- "div",
6175
+ ({ className, value, defaultValue, onValueChange, disabled, name, ...props }, ref) => {
6176
+ const [internalValue, setInternalValue] = React10__namespace.useState(
6177
+ defaultValue
6178
+ );
6179
+ const isControlled = value !== void 0;
6180
+ const currentValue = isControlled ? value : internalValue;
6181
+ const handleValueChange = React10__namespace.useCallback(
6182
+ (next) => {
6183
+ if (!isControlled) {
6184
+ setInternalValue(next);
6185
+ }
6186
+ onValueChange?.(next);
6187
+ },
6188
+ [isControlled, onValueChange]
6189
+ );
6190
+ return /* @__PURE__ */ jsxRuntime.jsx(
6191
+ RadioGroupContext.Provider,
6135
6192
  {
6136
- ref,
6137
- role: "radiogroup",
6138
- className: cn("moonui-theme", "grid gap-2", className),
6139
- ...props
6193
+ value: {
6194
+ value: currentValue,
6195
+ onValueChange: handleValueChange,
6196
+ disabled,
6197
+ name
6198
+ },
6199
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6200
+ "div",
6201
+ {
6202
+ ref,
6203
+ role: "radiogroup",
6204
+ className: cn("moonui-theme", "grid gap-2", className),
6205
+ ...props
6206
+ }
6207
+ )
6140
6208
  }
6141
- ) });
6209
+ );
6142
6210
  }
6143
6211
  );
6144
6212
  RadioGroup2.displayName = "RadioGroup";
@@ -6167,7 +6235,7 @@ var RadioGroupItem = React10__namespace.forwardRef(({ className, variant, size,
6167
6235
  disabled: disabled || radioGroup.disabled,
6168
6236
  name: radioGroup.name,
6169
6237
  onChange: handleChange,
6170
- className: "sr-only",
6238
+ className: "peer sr-only",
6171
6239
  ...props
6172
6240
  }
6173
6241
  ),
@@ -6178,7 +6246,12 @@ var RadioGroupItem = React10__namespace.forwardRef(({ className, variant, size,
6178
6246
  className: cn(
6179
6247
  radioGroupItemVariants({ variant, size }),
6180
6248
  "rounded-full",
6181
- "focus-visible:ring-primary/50",
6249
+ // Gerçekte odaklanan eleman görsel olarak gizli `sr-only` input'tur.
6250
+ // Görünür label onun KARDEŞİ olduğu için label'da `:focus-visible` hiç
6251
+ // tetiklenmiyor, dolayısıyla klavye kullanıcısı hiçbir focus izi
6252
+ // görmüyordu. Tailwind `peer` deseniyle (input `peer` sınıfını taşır ve
6253
+ // DOM'da label'dan önce gelir) focus izi görünür elemana taşınır.
6254
+ "peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary/50",
6182
6255
  "relative inline-flex shrink-0 cursor-pointer items-center justify-center overflow-hidden",
6183
6256
  disabled && "cursor-not-allowed opacity-50",
6184
6257
  className
@@ -8512,6 +8585,10 @@ var ToggleGroup = React10__namespace.forwardRef(({ className, variant, size, chi
8512
8585
  ref,
8513
8586
  className: cn(
8514
8587
  "moonui-theme inline-flex items-center justify-center gap-1",
8588
+ // Radix roving-focus kök elemana `data-orientation` yazar; dikey yerleşim
8589
+ // buna bağlanır. Yatay/tanımsız durumda taban sınıflar geçerli kalır —
8590
+ // yani mevcut render değişmez. Kardeş `button-group` ile desen paritesi.
8591
+ "data-[orientation=vertical]:flex-col data-[orientation=vertical]:items-stretch data-[orientation=vertical]:justify-start",
8515
8592
  className
8516
8593
  ),
8517
8594
  ...props,