@bubo-squared/ui-framework 0.2.22 → 0.2.24

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.d.cts CHANGED
@@ -11,7 +11,7 @@ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
11
11
  import { ClassValue } from 'clsx';
12
12
 
13
13
  declare const buttonVariants: (props?: ({
14
- variant?: "primary" | "secondary" | "ghost" | "outline" | "destructive" | null | undefined;
14
+ variant?: "primary" | "secondary" | "ghost" | "outline" | "destructive" | "destructive-outline" | null | undefined;
15
15
  size?: "sm" | "md" | "lg" | "xl" | null | undefined;
16
16
  } & class_variance_authority_types.ClassProp) | undefined) => string;
17
17
  interface ButtonProps$1 extends React$1.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -274,7 +274,7 @@ interface TagProps extends VariantProps<typeof tagVariants> {
274
274
  trailingIcon?: React$1.ReactElement<{
275
275
  disabled?: boolean;
276
276
  }>;
277
- size: "sm" | "md";
277
+ size?: "sm" | "md";
278
278
  disabled?: boolean;
279
279
  }
280
280
  declare const Tag: React$1.ForwardRefExoticComponent<TagProps & React$1.RefAttributes<HTMLDivElement>>;
@@ -540,10 +540,13 @@ type SliderBaseProps = {
540
540
  tooltipPlacement?: SliderTooltipPlacement;
541
541
  /**
542
542
  * Custom formatter for tooltip / numeric / accessibility text.
543
- * Receives the current slider value and should return a display string.
543
+ * Receives the current slider value and should return display content.
544
544
  * If provided, it takes precedence over `showPercentage`.
545
+ *
546
+ * Accessibility note: when the formatter returns non-text content,
547
+ * `aria-valuetext` falls back to the default numeric/percentage string.
545
548
  */
546
- tooltipFormatter?: (value: number) => string;
549
+ tooltipFormatter?: (value: number) => React$1.ReactNode;
547
550
  /**
548
551
  * When true (default), values are rendered as percentages (e.g. "30%").
549
552
  * When false, raw numbers are shown instead.
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
11
11
  import { ClassValue } from 'clsx';
12
12
 
13
13
  declare const buttonVariants: (props?: ({
14
- variant?: "primary" | "secondary" | "ghost" | "outline" | "destructive" | null | undefined;
14
+ variant?: "primary" | "secondary" | "ghost" | "outline" | "destructive" | "destructive-outline" | null | undefined;
15
15
  size?: "sm" | "md" | "lg" | "xl" | null | undefined;
16
16
  } & class_variance_authority_types.ClassProp) | undefined) => string;
17
17
  interface ButtonProps$1 extends React$1.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -274,7 +274,7 @@ interface TagProps extends VariantProps<typeof tagVariants> {
274
274
  trailingIcon?: React$1.ReactElement<{
275
275
  disabled?: boolean;
276
276
  }>;
277
- size: "sm" | "md";
277
+ size?: "sm" | "md";
278
278
  disabled?: boolean;
279
279
  }
280
280
  declare const Tag: React$1.ForwardRefExoticComponent<TagProps & React$1.RefAttributes<HTMLDivElement>>;
@@ -540,10 +540,13 @@ type SliderBaseProps = {
540
540
  tooltipPlacement?: SliderTooltipPlacement;
541
541
  /**
542
542
  * Custom formatter for tooltip / numeric / accessibility text.
543
- * Receives the current slider value and should return a display string.
543
+ * Receives the current slider value and should return display content.
544
544
  * If provided, it takes precedence over `showPercentage`.
545
+ *
546
+ * Accessibility note: when the formatter returns non-text content,
547
+ * `aria-valuetext` falls back to the default numeric/percentage string.
545
548
  */
546
- tooltipFormatter?: (value: number) => string;
549
+ tooltipFormatter?: (value: number) => React$1.ReactNode;
547
550
  /**
548
551
  * When true (default), values are rendered as percentages (e.g. "30%").
549
552
  * When false, raw numbers are shown instead.
package/dist/index.js CHANGED
@@ -66,6 +66,10 @@ var buttonVariants = cva(
66
66
  destructive: [
67
67
  "btn-destructive",
68
68
  "focus-ring-error"
69
+ ],
70
+ "destructive-outline": [
71
+ "btn-destructive-outline",
72
+ "focus-ring-error-outline"
69
73
  ]
70
74
  },
71
75
  size: {
@@ -1576,13 +1580,13 @@ var inputShellVariants = cva13(
1576
1580
  }
1577
1581
  },
1578
1582
  defaultVariants: {
1579
- size: "lg",
1583
+ size: "md",
1580
1584
  status: "default"
1581
1585
  }
1582
1586
  }
1583
1587
  );
1584
1588
  var InputShell = React21.forwardRef(
1585
- ({ size, status, disabled, className, ...rest }, ref) => {
1589
+ ({ size = "md", status, disabled, className, ...rest }, ref) => {
1586
1590
  return /* @__PURE__ */ jsx23(
1587
1591
  "div",
1588
1592
  {
@@ -1685,7 +1689,7 @@ var Autocomplete = React23.forwardRef((props, forwardedRef) => {
1685
1689
  hint,
1686
1690
  hideHint,
1687
1691
  status = "default",
1688
- size = "lg",
1692
+ size = "md",
1689
1693
  disabled,
1690
1694
  className,
1691
1695
  leadingIcon,
@@ -1956,7 +1960,7 @@ import { cva as cva15 } from "class-variance-authority";
1956
1960
  import { ChevronDownIcon as ChevronDownIcon2 } from "@bubo-squared/icons";
1957
1961
  import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
1958
1962
  var selectTriggerVariants = cva15(
1959
- "group flex w-full items-center justify-between rounded-4 border bg-(--background-primary) p-2 text-left transition-colors cursor-pointer focus-ring-primary focus:border-(--border-brand) hover:bg-(--background-primary-hover) disabled:bg-(--background-primary) disabled:border-(--border-secondary-disabled) disabled:text-primary-disabled disabled:cursor-default",
1963
+ "group flex w-full items-center justify-between rounded-4 border bg-(--background-primary) p-2 text-left transition-[background-color] cursor-pointer hover:bg-(--background-primary-hover) disabled:bg-(--background-primary-disabled) disabled:text-primary-disabled disabled:cursor-default",
1960
1964
  {
1961
1965
  variants: {
1962
1966
  size: {
@@ -1966,13 +1970,13 @@ var selectTriggerVariants = cva15(
1966
1970
  xl: "h-14"
1967
1971
  },
1968
1972
  status: {
1969
- default: "border-(--border-secondary)",
1970
- success: "border-(--border-success)",
1971
- error: "border-(--border-error)"
1973
+ default: "input-default",
1974
+ success: "input-success",
1975
+ error: "input-error"
1972
1976
  }
1973
1977
  },
1974
1978
  defaultVariants: {
1975
- size: "lg",
1979
+ size: "md",
1976
1980
  status: "default"
1977
1981
  }
1978
1982
  }
@@ -1994,7 +1998,7 @@ var textVariants = cva15("truncate", {
1994
1998
  }
1995
1999
  },
1996
2000
  defaultVariants: {
1997
- size: "lg",
2001
+ size: "md",
1998
2002
  hasValue: false
1999
2003
  }
2000
2004
  });
@@ -2012,7 +2016,7 @@ var selectIconVariants = cva15("flex items-center justify-center shrink-0", {
2012
2016
  }
2013
2017
  },
2014
2018
  defaultVariants: {
2015
- size: "lg",
2019
+ size: "md",
2016
2020
  disabled: false
2017
2021
  }
2018
2022
  });
@@ -2036,7 +2040,7 @@ var Select = React24.forwardRef((props, forwardedRef) => {
2036
2040
  hideHint = false,
2037
2041
  name,
2038
2042
  placeholder = "Placeholder text",
2039
- size = "lg",
2043
+ size = "md",
2040
2044
  status = "default",
2041
2045
  disabled,
2042
2046
  options,
@@ -2108,6 +2112,7 @@ var Select = React24.forwardRef((props, forwardedRef) => {
2108
2112
  type: "button",
2109
2113
  "aria-haspopup": "listbox",
2110
2114
  "aria-expanded": isOpen,
2115
+ "aria-disabled": disabled || void 0,
2111
2116
  disabled,
2112
2117
  className: cn(
2113
2118
  selectTriggerVariants({ size, status }),
@@ -2201,7 +2206,7 @@ var passwordTextVariants = cva16("truncate", {
2201
2206
  }
2202
2207
  },
2203
2208
  defaultVariants: {
2204
- size: "lg",
2209
+ size: "md",
2205
2210
  disabled: false
2206
2211
  }
2207
2212
  });
@@ -2249,7 +2254,7 @@ var PasswordInput = React25.forwardRef((props, forwardedRef) => {
2249
2254
  hint,
2250
2255
  hideHint,
2251
2256
  placeholder = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
2252
- size = "lg",
2257
+ size = "md",
2253
2258
  status = "default",
2254
2259
  variant = "icon",
2255
2260
  disabled,
@@ -2757,7 +2762,7 @@ var inputTextVariants2 = cva18("", {
2757
2762
  }
2758
2763
  },
2759
2764
  defaultVariants: {
2760
- size: "lg"
2765
+ size: "md"
2761
2766
  }
2762
2767
  });
2763
2768
  var dropdownWidthVariants = cva18("", {
@@ -2770,7 +2775,7 @@ var dropdownWidthVariants = cva18("", {
2770
2775
  }
2771
2776
  },
2772
2777
  defaultVariants: {
2773
- size: "lg"
2778
+ size: "md"
2774
2779
  }
2775
2780
  });
2776
2781
  var wrapperStatusClass = {
@@ -2790,12 +2795,12 @@ var countryOptionVariants = cva18(
2790
2795
  }
2791
2796
  },
2792
2797
  defaultVariants: {
2793
- size: "lg"
2798
+ size: "md"
2794
2799
  }
2795
2800
  }
2796
2801
  );
2797
2802
  var PhoneInput = React31.forwardRef(
2798
- (props, ref) => {
2803
+ (props, forwardedRef) => {
2799
2804
  const {
2800
2805
  className,
2801
2806
  onChange,
@@ -2804,11 +2809,16 @@ var PhoneInput = React31.forwardRef(
2804
2809
  hint,
2805
2810
  hideHint,
2806
2811
  placeholder,
2807
- size = "lg",
2812
+ size = "md",
2808
2813
  disabled = false,
2809
2814
  status = "default",
2810
2815
  ...rest
2811
2816
  } = props;
2817
+ const wrapperRef = React31.useRef(null);
2818
+ const focusNumberInput = React31.useCallback(() => {
2819
+ const el = wrapperRef.current?.querySelector("input");
2820
+ el?.focus();
2821
+ }, []);
2812
2822
  return /* @__PURE__ */ jsx33(
2813
2823
  Field,
2814
2824
  {
@@ -2818,16 +2828,29 @@ var PhoneInput = React31.forwardRef(
2818
2828
  status,
2819
2829
  disabled,
2820
2830
  className,
2821
- children: /* @__PURE__ */ jsx33("div", { className: cn("w-full", wrapperStatusClass[status]), children: /* @__PURE__ */ jsx33(
2831
+ children: /* @__PURE__ */ jsx33("div", { ref: wrapperRef, className: cn("w-full", wrapperStatusClass[status]), children: /* @__PURE__ */ jsx33(
2822
2832
  RPNInput.default,
2823
2833
  {
2824
- ref,
2834
+ ref: forwardedRef,
2825
2835
  className: cn(
2826
2836
  sizeBase({ size }),
2827
2837
  inputTextVariants2({ size, disabled })
2828
2838
  ),
2829
2839
  flagComponent: FlagComponent,
2830
- countrySelectComponent: (countrySelectProps) => /* @__PURE__ */ jsx33(CountrySelect, { ...countrySelectProps, size }),
2840
+ countrySelectComponent: (countrySelectProps) => /* @__PURE__ */ jsx33(
2841
+ CountrySelect,
2842
+ {
2843
+ ...countrySelectProps,
2844
+ size,
2845
+ onAfterSelect: () => {
2846
+ requestAnimationFrame(() => {
2847
+ requestAnimationFrame(() => {
2848
+ focusNumberInput();
2849
+ });
2850
+ });
2851
+ }
2852
+ }
2853
+ ),
2831
2854
  inputComponent: InputComponent,
2832
2855
  smartCaret: false,
2833
2856
  value: value || void 0,
@@ -2862,7 +2885,8 @@ var CountrySelect = ({
2862
2885
  value: selectedCountry,
2863
2886
  options: countryList,
2864
2887
  onChange,
2865
- size = "lg"
2888
+ size = "md",
2889
+ onAfterSelect
2866
2890
  }) => {
2867
2891
  const scrollAreaRef = React31.useRef(null);
2868
2892
  const [searchValue, setSearchValue] = React31.useState("");
@@ -2946,7 +2970,10 @@ var CountrySelect = ({
2946
2970
  countryName: label,
2947
2971
  selectedCountry,
2948
2972
  onChange,
2949
- onSelectComplete: () => setIsOpen(false),
2973
+ onSelectComplete: () => {
2974
+ setIsOpen(false);
2975
+ onAfterSelect?.();
2976
+ },
2950
2977
  size
2951
2978
  },
2952
2979
  value
@@ -2967,7 +2994,7 @@ var CountrySelectOption = (props) => {
2967
2994
  selectedCountry,
2968
2995
  onChange,
2969
2996
  onSelectComplete,
2970
- size = "lg"
2997
+ size = "md"
2971
2998
  } = props;
2972
2999
  const handleSelect = () => {
2973
3000
  onChange(country);
@@ -3130,7 +3157,7 @@ var searchTextVariants = cva19("truncate", {
3130
3157
  }
3131
3158
  },
3132
3159
  defaultVariants: {
3133
- size: "lg"
3160
+ size: "md"
3134
3161
  }
3135
3162
  });
3136
3163
  var iconWrapperVariants3 = cva19("flex items-center justify-center shrink-0 text-(--icon-primary)", {
@@ -3146,13 +3173,13 @@ var iconWrapperVariants3 = cva19("flex items-center justify-center shrink-0 text
3146
3173
  }
3147
3174
  },
3148
3175
  defaultVariants: {
3149
- size: "lg"
3176
+ size: "md"
3150
3177
  }
3151
3178
  });
3152
3179
  var SearchInput = React33.forwardRef((props, forwardedRef) => {
3153
3180
  const {
3154
3181
  placeholder = "Search...",
3155
- size = "lg",
3182
+ size = "md",
3156
3183
  disabled,
3157
3184
  className,
3158
3185
  leadingIcon,
@@ -3213,10 +3240,21 @@ SearchInput.displayName = "SearchInput";
3213
3240
  import * as React35 from "react";
3214
3241
 
3215
3242
  // src/components/Feedback/Tooltip.tsx
3216
- import "react";
3243
+ import * as React34 from "react";
3217
3244
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
3218
3245
  import { jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
3219
3246
  var TooltipArrow = TooltipPrimitive.Arrow;
3247
+ var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
3248
+ var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
3249
+ var canAcceptRef = (child) => {
3250
+ const type = child.type;
3251
+ if (typeof child.type === "string") return true;
3252
+ if (type?.$$typeof === REACT_FORWARD_REF_TYPE) return true;
3253
+ if (type?.$$typeof === REACT_MEMO_TYPE && type.type?.$$typeof === REACT_FORWARD_REF_TYPE) {
3254
+ return true;
3255
+ }
3256
+ return false;
3257
+ };
3220
3258
  var mapPlacementToSideAndAlign = (placement) => {
3221
3259
  switch (placement) {
3222
3260
  case "top":
@@ -3263,6 +3301,7 @@ var Tooltip = (props) => {
3263
3301
  children,
3264
3302
  delayDuration = 200
3265
3303
  } = props;
3304
+ const trigger = React34.isValidElement(children) && canAcceptRef(children) ? children : /* @__PURE__ */ jsx36("span", { className: "inline-flex", tabIndex: 0, children });
3266
3305
  const hasStrapline = typeof strapline === "string" ? strapline.trim() !== "" : strapline != null;
3267
3306
  const hasDescription = typeof description === "string" ? description.trim() !== "" : description != null;
3268
3307
  const { side, align } = mapPlacementToSideAndAlign(placement);
@@ -3277,7 +3316,7 @@ var Tooltip = (props) => {
3277
3316
  disableHoverableContent,
3278
3317
  delayDuration,
3279
3318
  children: [
3280
- /* @__PURE__ */ jsx36(TooltipPrimitive.Trigger, { asChild: true, children }),
3319
+ /* @__PURE__ */ jsx36(TooltipPrimitive.Trigger, { asChild: true, children: trigger }),
3281
3320
  /* @__PURE__ */ jsx36(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs24(
3282
3321
  TooltipPrimitive.Content,
3283
3322
  {
@@ -3536,15 +3575,27 @@ var Slider = React35.forwardRef((props, forwardedRef) => {
3536
3575
  }
3537
3576
  return rounded.toFixed(2);
3538
3577
  };
3539
- const formatDisplayValue = (val) => {
3578
+ const formatFallbackText = (val) => {
3540
3579
  const value2 = val ?? min;
3541
- if (tooltipFormatter) return tooltipFormatter(value2);
3542
3580
  if (showPercentage) {
3543
3581
  const percent = valueToPercent(value2);
3544
3582
  return `${formatNumber(percent)}%`;
3545
3583
  }
3546
3584
  return formatNumber(value2);
3547
3585
  };
3586
+ const formatDisplayNode = (val) => {
3587
+ const value2 = val ?? min;
3588
+ if (tooltipFormatter) return tooltipFormatter(value2);
3589
+ return formatFallbackText(value2);
3590
+ };
3591
+ const formatAriaValueText = (val) => {
3592
+ const fallback = formatFallbackText(val);
3593
+ if (!tooltipFormatter) return fallback;
3594
+ const node = tooltipFormatter(val ?? min);
3595
+ if (typeof node === "string") return node;
3596
+ if (typeof node === "number") return String(node);
3597
+ return fallback;
3598
+ };
3548
3599
  const formatNumericLabel = () => {
3549
3600
  if (isRange && secondary !== void 0) {
3550
3601
  if (!tooltipFormatter && showPercentage && display === "numeric") {
@@ -3552,14 +3603,18 @@ var Slider = React35.forwardRef((props, forwardedRef) => {
3552
3603
  const second = formatNumber(valueToPercent(secondary));
3553
3604
  return `${first} - ${second}`;
3554
3605
  }
3555
- return `${formatDisplayValue(primary)} - ${formatDisplayValue(secondary)}`;
3606
+ return /* @__PURE__ */ jsxs25(Fragment2, { children: [
3607
+ formatDisplayNode(primary),
3608
+ " - ",
3609
+ formatDisplayNode(secondary)
3610
+ ] });
3556
3611
  }
3557
- return formatDisplayValue(primary);
3612
+ return formatDisplayNode(primary);
3558
3613
  };
3559
3614
  const trackHeight = 32;
3560
3615
  const thumbWidth = 18;
3561
3616
  const thumbRadius = thumbWidth / 2;
3562
- const renderHandle = (index, percent, ariaValueText) => {
3617
+ const renderHandle = (index, percent, tooltipContent, ariaValueText) => {
3563
3618
  const val = index === 0 ? primary : secondary;
3564
3619
  const isDragging = draggingThumbIndex === index;
3565
3620
  const isTooltipVisible = showTooltip && (hoveredThumbIndex === index || draggingThumbIndex === index || focusedThumbIndex === index);
@@ -3612,7 +3667,7 @@ var Slider = React35.forwardRef((props, forwardedRef) => {
3612
3667
  return /* @__PURE__ */ jsx37(
3613
3668
  Tooltip,
3614
3669
  {
3615
- title: ariaValueText,
3670
+ title: tooltipContent,
3616
3671
  placement: tooltipPlacement === "top" ? "top" : "bottom",
3617
3672
  offset: 8,
3618
3673
  open: isTooltipVisible,
@@ -3674,8 +3729,18 @@ var Slider = React35.forwardRef((props, forwardedRef) => {
3674
3729
  }
3675
3730
  }
3676
3731
  ),
3677
- renderHandle(0, primaryPercent, formatDisplayValue(primary)),
3678
- isRange && secondary !== void 0 && renderHandle(1, secondaryPercent, formatDisplayValue(secondary))
3732
+ renderHandle(
3733
+ 0,
3734
+ primaryPercent,
3735
+ formatDisplayNode(primary),
3736
+ formatAriaValueText(primary)
3737
+ ),
3738
+ isRange && secondary !== void 0 && renderHandle(
3739
+ 1,
3740
+ secondaryPercent,
3741
+ formatDisplayNode(secondary),
3742
+ formatAriaValueText(secondary)
3743
+ )
3679
3744
  ]
3680
3745
  }
3681
3746
  ) }),
@@ -3893,7 +3958,7 @@ var inputTextVariants3 = cva20("truncate", {
3893
3958
  }
3894
3959
  },
3895
3960
  defaultVariants: {
3896
- size: "lg"
3961
+ size: "md"
3897
3962
  }
3898
3963
  });
3899
3964
  var iconWrapperVariants4 = cva20(
@@ -3911,7 +3976,7 @@ var iconWrapperVariants4 = cva20(
3911
3976
  }
3912
3977
  },
3913
3978
  defaultVariants: {
3914
- size: "lg"
3979
+ size: "md"
3915
3980
  }
3916
3981
  }
3917
3982
  );
@@ -3921,7 +3986,7 @@ var TextInput = React37.forwardRef((props, forwardedRef) => {
3921
3986
  hint,
3922
3987
  hideHint,
3923
3988
  placeholder = "Placeholder text",
3924
- size = "lg",
3989
+ size = "md",
3925
3990
  status = "default",
3926
3991
  disabled = false,
3927
3992
  className,
@@ -4123,7 +4188,7 @@ var WebsiteInput = React39.forwardRef((props, forwardedRef) => {
4123
4188
  hierarchy = "leading",
4124
4189
  protocolLabel = "http://",
4125
4190
  icon,
4126
- size = "lg",
4191
+ size = "md",
4127
4192
  disabled,
4128
4193
  className,
4129
4194
  ...rest