@rufous/ui 0.3.62 → 0.3.64

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 (3) hide show
  1. package/dist/main.cjs +43 -14
  2. package/dist/main.js +43 -14
  3. package/package.json +1 -1
package/dist/main.cjs CHANGED
@@ -2762,28 +2762,55 @@ var TextField = (0, import_react11.forwardRef)(({
2762
2762
  className
2763
2763
  ].filter(Boolean).join(" ");
2764
2764
  const internalRef = import_react11.default.useRef(null);
2765
+ const numberMin = type === "number" ? slotProps?.input?.min ?? props.min : void 0;
2766
+ const numberMax = type === "number" ? slotProps?.input?.max ?? props.max : void 0;
2767
+ const setNativeValue = (val) => {
2768
+ if (!internalRef.current) return;
2769
+ const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
2770
+ setter?.call(internalRef.current, val);
2771
+ };
2772
+ const emitChange = (e, numericValue) => {
2773
+ const syntheticEvent = Object.assign({}, e, {
2774
+ target: Object.assign({}, e.target, { value: numericValue }),
2775
+ currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
2776
+ });
2777
+ onChange?.(syntheticEvent);
2778
+ };
2765
2779
  const handleChange = (e) => {
2766
2780
  if (type === "number") {
2767
- const raw = e.target.value;
2768
- const inputMax = slotProps?.input?.max ?? props.max;
2781
+ let raw = e.target.value;
2769
2782
  const inputMaxLength = slotProps?.input?.maxLength ?? props.maxLength;
2770
2783
  if (inputMaxLength != null) {
2771
2784
  const digits = raw.replace(/[^0-9]/g, "");
2772
2785
  if (digits.length > Number(inputMaxLength)) return;
2773
2786
  }
2774
- if (inputMax != null && raw !== "") {
2775
- if (Number(raw) > Number(inputMax)) return;
2787
+ if (numberMax != null && raw !== "" && Number(raw) > Number(numberMax)) {
2788
+ raw = String(numberMax);
2789
+ setNativeValue(raw);
2776
2790
  }
2777
- const numericValue = raw === "" ? "" : Number(raw);
2778
- const syntheticEvent = Object.assign({}, e, {
2779
- target: Object.assign({}, e.target, { value: numericValue }),
2780
- currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
2781
- });
2782
- onChange?.(syntheticEvent);
2791
+ emitChange(e, raw === "" ? "" : Number(raw));
2783
2792
  return;
2784
2793
  }
2785
2794
  onChange?.(e);
2786
2795
  };
2796
+ const handleBlur = (e) => {
2797
+ if (type === "number") {
2798
+ const raw = e.target.value;
2799
+ if (raw !== "") {
2800
+ const n = Number(raw);
2801
+ if (!isNaN(n)) {
2802
+ let clamped = n;
2803
+ if (numberMin != null && clamped < Number(numberMin)) clamped = Number(numberMin);
2804
+ if (numberMax != null && clamped > Number(numberMax)) clamped = Number(numberMax);
2805
+ if (clamped !== n) {
2806
+ setNativeValue(String(clamped));
2807
+ emitChange(e, clamped);
2808
+ }
2809
+ }
2810
+ }
2811
+ }
2812
+ onBlur?.(e);
2813
+ };
2787
2814
  const triggerChange = () => {
2788
2815
  if (internalRef.current) {
2789
2816
  const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
@@ -2798,9 +2825,10 @@ var TextField = (0, import_react11.forwardRef)(({
2798
2825
  const stepBy = (delta) => {
2799
2826
  if (!internalRef.current) return;
2800
2827
  const step = Number(stepProp ?? (numberVariant ? STEP_BY_VARIANT[numberVariant] : 1));
2801
- const newVal = (parseFloat(internalRef.current.value) || 0) + delta * step;
2802
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
2803
- nativeInputValueSetter?.call(internalRef.current, String(newVal));
2828
+ let newVal = (parseFloat(internalRef.current.value) || 0) + delta * step;
2829
+ if (numberMax != null && newVal > Number(numberMax)) newVal = Number(numberMax);
2830
+ if (numberMin != null && newVal < Number(numberMin)) newVal = Number(numberMin);
2831
+ setNativeValue(String(newVal));
2804
2832
  triggerChange();
2805
2833
  };
2806
2834
  const handleIncrement = (e) => {
@@ -2872,7 +2900,8 @@ var TextField = (0, import_react11.forwardRef)(({
2872
2900
  readOnly,
2873
2901
  ...slotProps?.input,
2874
2902
  ...props,
2875
- onChange: handleChange
2903
+ onChange: handleChange,
2904
+ onBlur: handleBlur
2876
2905
  }
2877
2906
  ), InputProps?.endAdornment && /* @__PURE__ */ import_react11.default.createElement("div", { className: "rf-text-field__adornment rf-text-field__adornment--end" }, InputProps.endAdornment), !isTextarea && type === "number" && !disabled && !readOnly && /* @__PURE__ */ import_react11.default.createElement("div", { className: "rf-text-field__number-controls" }, /* @__PURE__ */ import_react11.default.createElement("button", { type: "button", tabIndex: -1, onClick: handleIncrement, className: "rf-text-field__number-btn" }, /* @__PURE__ */ import_react11.default.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ import_react11.default.createElement("path", { d: "M4 0L8 5H0L4 0Z" }))), /* @__PURE__ */ import_react11.default.createElement("button", { type: "button", tabIndex: -1, onClick: handleDecrement, className: "rf-text-field__number-btn", style: { marginTop: 2 } }, /* @__PURE__ */ import_react11.default.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ import_react11.default.createElement("path", { d: "M4 5L0 0H8L4 5Z" })))), hasLabel && /* @__PURE__ */ import_react11.default.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, " ", required && /* @__PURE__ */ import_react11.default.createElement("span", { className: "rf-text-field__asterisk" }, "*")), variant === "outlined" && /* @__PURE__ */ import_react11.default.createElement("fieldset", { className: "rf-text-field__notch" }, hasLabel ? /* @__PURE__ */ import_react11.default.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ import_react11.default.createElement("span", null, label, " ", required ? "*" : "")) : /* @__PURE__ */ import_react11.default.createElement("legend", { className: "rf-text-field__legend--empty" }))), helperText && /* @__PURE__ */ import_react11.default.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
2878
2907
  });
package/dist/main.js CHANGED
@@ -2468,28 +2468,55 @@ var TextField = forwardRef6(({
2468
2468
  className
2469
2469
  ].filter(Boolean).join(" ");
2470
2470
  const internalRef = React143.useRef(null);
2471
+ const numberMin = type === "number" ? slotProps?.input?.min ?? props.min : void 0;
2472
+ const numberMax = type === "number" ? slotProps?.input?.max ?? props.max : void 0;
2473
+ const setNativeValue = (val) => {
2474
+ if (!internalRef.current) return;
2475
+ const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
2476
+ setter?.call(internalRef.current, val);
2477
+ };
2478
+ const emitChange = (e, numericValue) => {
2479
+ const syntheticEvent = Object.assign({}, e, {
2480
+ target: Object.assign({}, e.target, { value: numericValue }),
2481
+ currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
2482
+ });
2483
+ onChange?.(syntheticEvent);
2484
+ };
2471
2485
  const handleChange = (e) => {
2472
2486
  if (type === "number") {
2473
- const raw = e.target.value;
2474
- const inputMax = slotProps?.input?.max ?? props.max;
2487
+ let raw = e.target.value;
2475
2488
  const inputMaxLength = slotProps?.input?.maxLength ?? props.maxLength;
2476
2489
  if (inputMaxLength != null) {
2477
2490
  const digits = raw.replace(/[^0-9]/g, "");
2478
2491
  if (digits.length > Number(inputMaxLength)) return;
2479
2492
  }
2480
- if (inputMax != null && raw !== "") {
2481
- if (Number(raw) > Number(inputMax)) return;
2493
+ if (numberMax != null && raw !== "" && Number(raw) > Number(numberMax)) {
2494
+ raw = String(numberMax);
2495
+ setNativeValue(raw);
2482
2496
  }
2483
- const numericValue = raw === "" ? "" : Number(raw);
2484
- const syntheticEvent = Object.assign({}, e, {
2485
- target: Object.assign({}, e.target, { value: numericValue }),
2486
- currentTarget: Object.assign({}, e.currentTarget, { value: numericValue })
2487
- });
2488
- onChange?.(syntheticEvent);
2497
+ emitChange(e, raw === "" ? "" : Number(raw));
2489
2498
  return;
2490
2499
  }
2491
2500
  onChange?.(e);
2492
2501
  };
2502
+ const handleBlur = (e) => {
2503
+ if (type === "number") {
2504
+ const raw = e.target.value;
2505
+ if (raw !== "") {
2506
+ const n = Number(raw);
2507
+ if (!isNaN(n)) {
2508
+ let clamped = n;
2509
+ if (numberMin != null && clamped < Number(numberMin)) clamped = Number(numberMin);
2510
+ if (numberMax != null && clamped > Number(numberMax)) clamped = Number(numberMax);
2511
+ if (clamped !== n) {
2512
+ setNativeValue(String(clamped));
2513
+ emitChange(e, clamped);
2514
+ }
2515
+ }
2516
+ }
2517
+ }
2518
+ onBlur?.(e);
2519
+ };
2493
2520
  const triggerChange = () => {
2494
2521
  if (internalRef.current) {
2495
2522
  const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
@@ -2504,9 +2531,10 @@ var TextField = forwardRef6(({
2504
2531
  const stepBy = (delta) => {
2505
2532
  if (!internalRef.current) return;
2506
2533
  const step = Number(stepProp ?? (numberVariant ? STEP_BY_VARIANT[numberVariant] : 1));
2507
- const newVal = (parseFloat(internalRef.current.value) || 0) + delta * step;
2508
- const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
2509
- nativeInputValueSetter?.call(internalRef.current, String(newVal));
2534
+ let newVal = (parseFloat(internalRef.current.value) || 0) + delta * step;
2535
+ if (numberMax != null && newVal > Number(numberMax)) newVal = Number(numberMax);
2536
+ if (numberMin != null && newVal < Number(numberMin)) newVal = Number(numberMin);
2537
+ setNativeValue(String(newVal));
2510
2538
  triggerChange();
2511
2539
  };
2512
2540
  const handleIncrement = (e) => {
@@ -2578,7 +2606,8 @@ var TextField = forwardRef6(({
2578
2606
  readOnly,
2579
2607
  ...slotProps?.input,
2580
2608
  ...props,
2581
- onChange: handleChange
2609
+ onChange: handleChange,
2610
+ onBlur: handleBlur
2582
2611
  }
2583
2612
  ), InputProps?.endAdornment && /* @__PURE__ */ React143.createElement("div", { className: "rf-text-field__adornment rf-text-field__adornment--end" }, InputProps.endAdornment), !isTextarea && type === "number" && !disabled && !readOnly && /* @__PURE__ */ React143.createElement("div", { className: "rf-text-field__number-controls" }, /* @__PURE__ */ React143.createElement("button", { type: "button", tabIndex: -1, onClick: handleIncrement, className: "rf-text-field__number-btn" }, /* @__PURE__ */ React143.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ React143.createElement("path", { d: "M4 0L8 5H0L4 0Z" }))), /* @__PURE__ */ React143.createElement("button", { type: "button", tabIndex: -1, onClick: handleDecrement, className: "rf-text-field__number-btn", style: { marginTop: 2 } }, /* @__PURE__ */ React143.createElement("svg", { width: "8", height: "5", viewBox: "0 0 8 5", fill: "currentColor" }, /* @__PURE__ */ React143.createElement("path", { d: "M4 5L0 0H8L4 5Z" })))), hasLabel && /* @__PURE__ */ React143.createElement("label", { htmlFor: inputId, className: "rf-text-field__label" }, label, " ", required && /* @__PURE__ */ React143.createElement("span", { className: "rf-text-field__asterisk" }, "*")), variant === "outlined" && /* @__PURE__ */ React143.createElement("fieldset", { className: "rf-text-field__notch" }, hasLabel ? /* @__PURE__ */ React143.createElement("legend", { className: "rf-text-field__legend" }, /* @__PURE__ */ React143.createElement("span", null, label, " ", required ? "*" : "")) : /* @__PURE__ */ React143.createElement("legend", { className: "rf-text-field__legend--empty" }))), helperText && /* @__PURE__ */ React143.createElement("div", { className: "rf-text-field__helper-text" }, helperText));
2584
2613
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rufous/ui",
3
3
  "private": false,
4
- "version": "0.3.62",
4
+ "version": "0.3.64",
5
5
  "type": "module",
6
6
  "description": "Experimental: A lightweight React UI component library (Beta)",
7
7
  "style": "./dist/main.css",