@facter/ds-core 1.34.0 → 1.35.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
@@ -63,7 +63,7 @@ function cn(...inputs) {
63
63
  return tailwindMerge.twMerge(clsx.clsx(inputs));
64
64
  }
65
65
  var buttonVariants = classVarianceAuthority.cva(
66
- "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",
66
+ "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-70",
67
67
  {
68
68
  variants: {
69
69
  variant: {
@@ -3073,6 +3073,163 @@ var toast = Object.assign(
3073
3073
  promise: (promise, options) => sonner.toast.promise(promise, options)
3074
3074
  }
3075
3075
  );
3076
+ var NumberStepper = React10__namespace.forwardRef(
3077
+ ({
3078
+ value = 1,
3079
+ onChange,
3080
+ onBlur,
3081
+ min = 0,
3082
+ max,
3083
+ step = 0.5,
3084
+ defaultValue,
3085
+ label,
3086
+ required,
3087
+ disabled,
3088
+ error,
3089
+ labelSuffix,
3090
+ className,
3091
+ name
3092
+ }, ref) => {
3093
+ const inputRef = React10__namespace.useRef(null);
3094
+ const [displayValue, setDisplayValue] = React10__namespace.useState(String(value));
3095
+ const [isFocused, setIsFocused] = React10__namespace.useState(false);
3096
+ React10__namespace.useImperativeHandle(ref, () => inputRef.current, []);
3097
+ React10__namespace.useEffect(() => {
3098
+ if (!isFocused) {
3099
+ setDisplayValue(String(value));
3100
+ }
3101
+ }, [value, isFocused]);
3102
+ const canDecrement = value - step >= min;
3103
+ const canIncrement = max === void 0 || value + step <= max;
3104
+ const handleDecrement = React10__namespace.useCallback(() => {
3105
+ if (!canDecrement || disabled) return;
3106
+ const newValue = Math.round((value - step) * 1e3) / 1e3;
3107
+ onChange?.(newValue);
3108
+ }, [value, step, min, disabled, onChange, canDecrement]);
3109
+ const handleIncrement = React10__namespace.useCallback(() => {
3110
+ if (!canIncrement || disabled) return;
3111
+ const newValue = Math.round((value + step) * 1e3) / 1e3;
3112
+ onChange?.(newValue);
3113
+ }, [value, step, max, disabled, onChange, canIncrement]);
3114
+ const handleInputChange = React10__namespace.useCallback(
3115
+ (e) => {
3116
+ const raw = e.target.value;
3117
+ setDisplayValue(raw);
3118
+ if (raw === "" || raw === "-" || raw === ".") return;
3119
+ const parsed = parseFloat(raw);
3120
+ if (isNaN(parsed)) return;
3121
+ onChange?.(parsed);
3122
+ },
3123
+ [onChange]
3124
+ );
3125
+ const handleInputFocus = React10__namespace.useCallback(() => {
3126
+ setIsFocused(true);
3127
+ }, []);
3128
+ const handleInputBlur = React10__namespace.useCallback(() => {
3129
+ setIsFocused(false);
3130
+ const parsed = parseFloat(displayValue);
3131
+ if (isNaN(parsed) || displayValue === "") {
3132
+ const resetValue = defaultValue ?? min;
3133
+ setDisplayValue(String(resetValue));
3134
+ if (value !== resetValue) onChange?.(resetValue);
3135
+ onBlur?.();
3136
+ return;
3137
+ }
3138
+ let clamped = parsed;
3139
+ if (clamped < min) clamped = min;
3140
+ if (max !== void 0 && clamped > max) clamped = max;
3141
+ setDisplayValue(String(clamped));
3142
+ if (clamped !== value) onChange?.(clamped);
3143
+ onBlur?.();
3144
+ }, [displayValue, value, min, max, onChange, onBlur]);
3145
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", className), children: [
3146
+ /* @__PURE__ */ jsxRuntime.jsxs(
3147
+ "div",
3148
+ {
3149
+ className: cn(
3150
+ "flex items-center h-12 rounded-md border-2 transition-colors overflow-hidden bg-background",
3151
+ error ? "border-red-500 focus-within:border-red-600" : "border-border focus-within:border-primary",
3152
+ disabled && "opacity-50 cursor-not-allowed"
3153
+ ),
3154
+ children: [
3155
+ /* @__PURE__ */ jsxRuntime.jsx(
3156
+ "button",
3157
+ {
3158
+ type: "button",
3159
+ tabIndex: -1,
3160
+ onClick: handleDecrement,
3161
+ disabled: disabled || !canDecrement,
3162
+ className: cn(
3163
+ "flex items-center justify-center w-11 h-full transition-colors select-none shrink-0",
3164
+ "text-muted-foreground hover:text-foreground hover:bg-muted",
3165
+ "disabled:opacity-30 disabled:hover:bg-transparent disabled:hover:text-muted-foreground disabled:cursor-not-allowed"
3166
+ ),
3167
+ "aria-label": "Diminuir",
3168
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) })
3169
+ }
3170
+ ),
3171
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border shrink-0" }),
3172
+ /* @__PURE__ */ jsxRuntime.jsx(
3173
+ "input",
3174
+ {
3175
+ ref: inputRef,
3176
+ name,
3177
+ type: "text",
3178
+ inputMode: "decimal",
3179
+ value: displayValue,
3180
+ onChange: handleInputChange,
3181
+ onFocus: handleInputFocus,
3182
+ onBlur: handleInputBlur,
3183
+ disabled,
3184
+ className: cn(
3185
+ "flex-1 min-w-0 h-full text-center text-sm font-medium bg-transparent outline-none",
3186
+ "disabled:cursor-not-allowed",
3187
+ label ? "pt-1" : ""
3188
+ )
3189
+ }
3190
+ ),
3191
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-6 bg-border shrink-0" }),
3192
+ /* @__PURE__ */ jsxRuntime.jsx(
3193
+ "button",
3194
+ {
3195
+ type: "button",
3196
+ tabIndex: -1,
3197
+ onClick: handleIncrement,
3198
+ disabled: disabled || !canIncrement,
3199
+ className: cn(
3200
+ "flex items-center justify-center w-11 h-full transition-colors select-none shrink-0",
3201
+ "text-muted-foreground hover:text-foreground hover:bg-muted",
3202
+ "disabled:opacity-30 disabled:hover:bg-transparent disabled:hover:text-muted-foreground disabled:cursor-not-allowed"
3203
+ ),
3204
+ "aria-label": "Aumentar",
3205
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
3206
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
3207
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
3208
+ ] })
3209
+ }
3210
+ )
3211
+ ]
3212
+ }
3213
+ ),
3214
+ label && /* @__PURE__ */ jsxRuntime.jsxs(
3215
+ "label",
3216
+ {
3217
+ className: cn(
3218
+ "absolute left-3 top-[-6px] text-xs font-medium bg-background px-1 cursor-pointer inline-flex items-center gap-1",
3219
+ error ? "text-red-500" : "text-foreground"
3220
+ ),
3221
+ onClick: () => inputRef.current?.focus(),
3222
+ children: [
3223
+ label,
3224
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-0.5", children: "*" }),
3225
+ labelSuffix
3226
+ ]
3227
+ }
3228
+ )
3229
+ ] });
3230
+ }
3231
+ );
3232
+ NumberStepper.displayName = "NumberStepper";
3076
3233
  var switchVariants = classVarianceAuthority.cva(
3077
3234
  [
3078
3235
  "peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent",
@@ -3884,7 +4041,9 @@ function SelectDropdown({
3884
4041
  collisionPadding: 16,
3885
4042
  className: "p-0 overflow-hidden flex flex-col",
3886
4043
  style: {
3887
- width: "var(--radix-popover-trigger-width)",
4044
+ minWidth: "var(--radix-popover-trigger-width)",
4045
+ width: "fit-content",
4046
+ maxWidth: "var(--radix-popover-content-available-width, 100%)",
3888
4047
  maxHeight: "min(340px, var(--radix-popover-content-available-height, 340px))"
3889
4048
  },
3890
4049
  onOpenAutoFocus: (e) => {
@@ -4227,7 +4386,9 @@ function MultiSelectDropdown({
4227
4386
  collisionPadding: 16,
4228
4387
  className: "p-0 overflow-hidden flex flex-col",
4229
4388
  style: {
4230
- width: "var(--radix-popover-trigger-width)",
4389
+ minWidth: "var(--radix-popover-trigger-width)",
4390
+ width: "fit-content",
4391
+ maxWidth: "var(--radix-popover-content-available-width, 100%)",
4231
4392
  maxHeight: "min(340px, var(--radix-popover-content-available-height, 340px))"
4232
4393
  },
4233
4394
  onOpenAutoFocus: (e) => {
@@ -4593,6 +4754,55 @@ function FormRadioGroup({
4593
4754
  ) });
4594
4755
  }
4595
4756
  FormRadioGroup.displayName = "Form.RadioGroup";
4757
+ function FormNumberStepper({
4758
+ name,
4759
+ label,
4760
+ description,
4761
+ tooltip,
4762
+ required,
4763
+ disabled,
4764
+ className,
4765
+ min = 0,
4766
+ max,
4767
+ step = 0.5,
4768
+ defaultValue,
4769
+ hideError = false
4770
+ }) {
4771
+ const form = reactHookForm.useFormContext();
4772
+ const fieldState = form.getFieldState(name, form.formState);
4773
+ const error = fieldState.error?.message;
4774
+ return /* @__PURE__ */ jsxRuntime.jsx(FormFieldProvider, { name, children: /* @__PURE__ */ jsxRuntime.jsx(
4775
+ reactHookForm.Controller,
4776
+ {
4777
+ control: form.control,
4778
+ name,
4779
+ render: ({ field }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-1", className), children: [
4780
+ /* @__PURE__ */ jsxRuntime.jsx(
4781
+ NumberStepper,
4782
+ {
4783
+ ref: field.ref,
4784
+ name: field.name,
4785
+ value: typeof field.value === "number" ? field.value : 0,
4786
+ onChange: field.onChange,
4787
+ onBlur: field.onBlur,
4788
+ min,
4789
+ max,
4790
+ step,
4791
+ defaultValue,
4792
+ label,
4793
+ required,
4794
+ disabled,
4795
+ error: !!error,
4796
+ labelSuffix: tooltip ? /* @__PURE__ */ jsxRuntime.jsx(FieldTooltipIcon, { tooltip }) : void 0
4797
+ }
4798
+ ),
4799
+ description && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground px-1", children: description }),
4800
+ !hideError && error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-red-500 px-1", children: error })
4801
+ ] })
4802
+ }
4803
+ ) });
4804
+ }
4805
+ FormNumberStepper.displayName = "Form.NumberStepper";
4596
4806
  function FormRoot({
4597
4807
  form,
4598
4808
  onSubmit,
@@ -4621,6 +4831,7 @@ var Form = Object.assign(FormRoot, {
4621
4831
  Checkbox: FormCheckbox,
4622
4832
  Switch: FormSwitch,
4623
4833
  RadioGroup: FormRadioGroup,
4834
+ NumberStepper: FormNumberStepper,
4624
4835
  // Partes auxiliares
4625
4836
  Label: FormLabel,
4626
4837
  Description: FormDescription,
@@ -9092,6 +9303,8 @@ exports.FormFieldProvider = FormFieldProvider;
9092
9303
  exports.FormFieldWrapper = FormFieldWrapper;
9093
9304
  exports.FormInput = FormInput;
9094
9305
  exports.FormLabel = FormLabel;
9306
+ exports.FormMultiSelect = FormMultiSelect;
9307
+ exports.FormNumberStepper = FormNumberStepper;
9095
9308
  exports.FormRadioGroup = FormRadioGroup;
9096
9309
  exports.FormSelect = FormSelect;
9097
9310
  exports.FormSwitch = FormSwitch;
@@ -9125,6 +9338,7 @@ exports.Navbar = Navbar;
9125
9338
  exports.NavbarCompanyProfile = NavbarCompanyProfile;
9126
9339
  exports.NavbarNotification = NavbarNotification;
9127
9340
  exports.NavbarUserMenu = NavbarUserMenu;
9341
+ exports.NumberStepper = NumberStepper;
9128
9342
  exports.PageHeader = PageHeader;
9129
9343
  exports.Popover = Popover;
9130
9344
  exports.PopoverContent = PopoverContent;