@nexus-cross/design-system 2.0.5 → 2.0.6

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.
@@ -1769,13 +1769,14 @@ Number input with two variants: basic (chevron arrows) and bind (+/- buttons). S
1769
1769
 
1770
1770
  WHEN TO USE:
1771
1771
  • Any numeric field — quantity, score, age, count
1772
- Currency with thousand separators PriceInput instead
1772
+ Need thousand separators? Set separator={true}
1773
+ • Currency UX (prefix $, balance, maxBalance, click-to-fill balance) → PriceInput instead
1773
1774
  • Date / time → DatePicker instead
1774
1775
 
1775
1776
  ANTI-PATTERNS:
1776
1777
  ✗ <TextInput type="number"> → <NumberInput> (loses keyboard ↑↓, step, accelerated long-press, max click)
1777
1778
  ✗ Custom +/- buttons + <input> → variant="bind" (or numberInputBind for external)
1778
- ✗ Manual thousand separators for currencyPriceInput
1779
+ ✗ Manual thousand separator string formattinguse separator={true}
1779
1780
  ✗ Inline unit text inside label/description → use prefixIcon/suffixIcon (e.g. suffixIcon="%")
1780
1781
 
1781
1782
  | Prop | Type | Default | Description |
@@ -1797,6 +1798,7 @@ ANTI-PATTERNS:
1797
1798
  | `disabled` | `boolean` | - | Disabled |
1798
1799
  | `readOnly` | `boolean` | - | Read-only (includes hiding buttons) |
1799
1800
  | `placeholder` | `string` | - | Placeholder (default: "0") |
1801
+ | `separator` | `boolean` | `false` | Display thousand-separator commas (e.g. 1,000). onValueChange still receives raw number without commas. Decimal part is not separated (1,234.567). |
1800
1802
  | `name` | `string` | - | Form field name |
1801
1803
  | `id` | `string` | - | Element ID |
1802
1804
  | `autoFocus` | `boolean` | - | Auto focus |
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ // src/utils/numberFormat.ts
4
+ function formatWithComma(value) {
5
+ if (!value) return value;
6
+ const [intPart, decPart] = value.split(".");
7
+ const formatted = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
8
+ return decPart !== void 0 ? `${formatted}.${decPart}` : formatted;
9
+ }
10
+ function stripComma(value) {
11
+ return value.replace(/,/g, "");
12
+ }
13
+
14
+ exports.formatWithComma = formatWithComma;
15
+ exports.stripComma = stripComma;
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var chunk3BMVYJCA_js = require('./chunk-3BMVYJCA.js');
3
4
  var chunkCZC76ZD5_js = require('./chunk-CZC76ZD5.js');
4
5
  var React = require('react');
5
6
  var classVarianceAuthority = require('class-variance-authority');
@@ -128,6 +129,7 @@ var NumberInput = React__namespace.forwardRef(
128
129
  readOnly,
129
130
  onValueChange,
130
131
  placeholder,
132
+ separator = false,
131
133
  ...props
132
134
  }, ref) => {
133
135
  const inputRef = React__namespace.useRef(null);
@@ -160,12 +162,24 @@ var NumberInput = React__namespace.forwardRef(
160
162
  );
161
163
  const handleInputChange = React__namespace.useCallback(
162
164
  (e) => {
163
- const raw = e.target.value;
165
+ const rawInput = e.target.value;
166
+ const raw = separator ? chunk3BMVYJCA_js.stripComma(rawInput) : rawInput;
164
167
  const regex = digit > 0 ? /^-?\d*\.?\d*$/ : /^-?\d*$/;
165
168
  if (!regex.test(raw)) return;
166
169
  setInternalValue(raw);
170
+ if (separator && inputRef.current) {
171
+ const cursorPos = e.target.selectionStart ?? 0;
172
+ const commasBefore = (rawInput.slice(0, cursorPos).match(/,/g) || []).length;
173
+ const formatted = chunk3BMVYJCA_js.formatWithComma(raw);
174
+ const el = inputRef.current;
175
+ requestAnimationFrame(() => {
176
+ const commasAfter = (formatted.slice(0, cursorPos).match(/,/g) || []).length;
177
+ const newPos = cursorPos + (commasAfter - commasBefore);
178
+ el.setSelectionRange(newPos, newPos);
179
+ });
180
+ }
167
181
  },
168
- [digit]
182
+ [digit, separator]
169
183
  );
170
184
  const handleBlur = React__namespace.useCallback(() => {
171
185
  commitValue(internalValue);
@@ -318,7 +332,7 @@ var NumberInput = React__namespace.forwardRef(
318
332
  inputMode: "decimal",
319
333
  role: "spinbutton",
320
334
  className: chunkCZC76ZD5_js.cn("nexus-number-input__field", inputClassName),
321
- value: internalValue,
335
+ value: separator ? chunk3BMVYJCA_js.formatWithComma(internalValue) : internalValue,
322
336
  disabled,
323
337
  readOnly,
324
338
  placeholder: placeholder ?? "0",
@@ -1,3 +1,4 @@
1
+ import { stripComma, formatWithComma } from './chunk-KHCPES3K.mjs';
1
2
  import { cn } from './chunk-MCKOWMLS.mjs';
2
3
  import * as React from 'react';
3
4
  import { cva } from 'class-variance-authority';
@@ -106,6 +107,7 @@ var NumberInput = React.forwardRef(
106
107
  readOnly,
107
108
  onValueChange,
108
109
  placeholder,
110
+ separator = false,
109
111
  ...props
110
112
  }, ref) => {
111
113
  const inputRef = React.useRef(null);
@@ -138,12 +140,24 @@ var NumberInput = React.forwardRef(
138
140
  );
139
141
  const handleInputChange = React.useCallback(
140
142
  (e) => {
141
- const raw = e.target.value;
143
+ const rawInput = e.target.value;
144
+ const raw = separator ? stripComma(rawInput) : rawInput;
142
145
  const regex = digit > 0 ? /^-?\d*\.?\d*$/ : /^-?\d*$/;
143
146
  if (!regex.test(raw)) return;
144
147
  setInternalValue(raw);
148
+ if (separator && inputRef.current) {
149
+ const cursorPos = e.target.selectionStart ?? 0;
150
+ const commasBefore = (rawInput.slice(0, cursorPos).match(/,/g) || []).length;
151
+ const formatted = formatWithComma(raw);
152
+ const el = inputRef.current;
153
+ requestAnimationFrame(() => {
154
+ const commasAfter = (formatted.slice(0, cursorPos).match(/,/g) || []).length;
155
+ const newPos = cursorPos + (commasAfter - commasBefore);
156
+ el.setSelectionRange(newPos, newPos);
157
+ });
158
+ }
145
159
  },
146
- [digit]
160
+ [digit, separator]
147
161
  );
148
162
  const handleBlur = React.useCallback(() => {
149
163
  commitValue(internalValue);
@@ -296,7 +310,7 @@ var NumberInput = React.forwardRef(
296
310
  inputMode: "decimal",
297
311
  role: "spinbutton",
298
312
  className: cn("nexus-number-input__field", inputClassName),
299
- value: internalValue,
313
+ value: separator ? formatWithComma(internalValue) : internalValue,
300
314
  disabled,
301
315
  readOnly,
302
316
  placeholder: placeholder ?? "0",
@@ -0,0 +1,12 @@
1
+ // src/utils/numberFormat.ts
2
+ function formatWithComma(value) {
3
+ if (!value) return value;
4
+ const [intPart, decPart] = value.split(".");
5
+ const formatted = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
6
+ return decPart !== void 0 ? `${formatted}.${decPart}` : formatted;
7
+ }
8
+ function stripComma(value) {
9
+ return value.replace(/,/g, "");
10
+ }
11
+
12
+ export { formatWithComma, stripComma };
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var chunk3BMVYJCA_js = require('./chunk-3BMVYJCA.js');
3
4
  var chunkCZC76ZD5_js = require('./chunk-CZC76ZD5.js');
4
5
  var React = require('react');
5
6
  var classVarianceAuthority = require('class-variance-authority');
@@ -25,15 +26,6 @@ function _interopNamespace(e) {
25
26
 
26
27
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
27
28
 
28
- function formatWithComma(value) {
29
- if (!value) return value;
30
- const [intPart, decPart] = value.split(".");
31
- const formatted = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
32
- return decPart !== void 0 ? `${formatted}.${decPart}` : formatted;
33
- }
34
- function stripComma(value) {
35
- return value.replace(/,/g, "");
36
- }
37
29
  var priceInputVariants = classVarianceAuthority.cva("nexus-price-input", {
38
30
  variants: {
39
31
  size: {
@@ -98,14 +90,14 @@ var PriceInput = React__namespace.forwardRef(
98
90
  const handleChange = React__namespace.useCallback(
99
91
  (e) => {
100
92
  const rawInput = e.target.value;
101
- const raw = separator ? stripComma(rawInput) : rawInput;
93
+ const raw = separator ? chunk3BMVYJCA_js.stripComma(rawInput) : rawInput;
102
94
  if (!isControlled) setInternalValue(raw);
103
95
  onValueChange?.(raw);
104
96
  onChange?.(e);
105
97
  if (separator && inputRef.current) {
106
98
  const cursorPos = e.target.selectionStart ?? 0;
107
99
  const commasBefore = (rawInput.slice(0, cursorPos).match(/,/g) || []).length;
108
- const formatted = formatWithComma(raw);
100
+ const formatted = chunk3BMVYJCA_js.formatWithComma(raw);
109
101
  const el = inputRef.current;
110
102
  requestAnimationFrame(() => {
111
103
  el.value = formatted;
@@ -162,7 +154,7 @@ var PriceInput = React__namespace.forwardRef(
162
154
  disabled,
163
155
  "aria-invalid": hasError || void 0,
164
156
  "aria-describedby": description ? `${inputId}-desc` : void 0,
165
- value: isControlled ? separator ? formatWithComma(String(controlledValue)) : controlledValue : void 0,
157
+ value: isControlled ? separator ? chunk3BMVYJCA_js.formatWithComma(String(controlledValue)) : controlledValue : void 0,
166
158
  defaultValue: !isControlled ? void 0 : void 0,
167
159
  onChange: handleChange,
168
160
  inputMode: "decimal",
@@ -1,17 +1,9 @@
1
+ import { stripComma, formatWithComma } from './chunk-KHCPES3K.mjs';
1
2
  import { cn } from './chunk-MCKOWMLS.mjs';
2
3
  import * as React from 'react';
3
4
  import { cva } from 'class-variance-authority';
4
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
6
 
6
- function formatWithComma(value) {
7
- if (!value) return value;
8
- const [intPart, decPart] = value.split(".");
9
- const formatted = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
10
- return decPart !== void 0 ? `${formatted}.${decPart}` : formatted;
11
- }
12
- function stripComma(value) {
13
- return value.replace(/,/g, "");
14
- }
15
7
  var priceInputVariants = cva("nexus-price-input", {
16
8
  variants: {
17
9
  size: {
@@ -43,6 +43,14 @@ interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputEleme
43
43
  containerClassName?: string;
44
44
  /** <input> element 자체에 적용 (font-size 같은 텍스트 스타일 오버라이드 시). */
45
45
  inputClassName?: string;
46
+ /**
47
+ * 천단위 콤마 구분자를 화면에 표시.
48
+ * - `false` (default): `1000` 그대로 표시
49
+ * - `true`: 화면엔 `1,000` 으로 표시하되, `onValueChange` 로는 콤마 없는 raw 숫자 (1000) 가 전달됨
50
+ *
51
+ * 소수점은 콤마가 들어가지 않는다 (`1234.567` → `1,234.567`).
52
+ */
53
+ separator?: boolean;
46
54
  }
47
55
  declare function numberInputBind(ref: React.RefObject<NumberInputRef | null>, direction: 'increment' | 'decrement'): {
48
56
  onPointerDown: (e: React.PointerEvent) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"NumberInput.d.ts","sourceRoot":"","sources":["../../src/components/NumberInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,QAAA,MAAM,mBAAmB;;;8EAcvB,CAAC;AAqDH,UAAU,cAAc;IACtB,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,cAAc,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,UAAU,gBACR,SAAQ,IAAI,CACR,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,MAAM,GAAG,UAAU,GAAG,OAAO,CAC9B,EACD,YAAY,CAAC,OAAO,mBAAmB,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACpD;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAcD,iBAAS,eAAe,CACtB,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAC3C,SAAS,EAAE,WAAW,GAAG,WAAW;uBAGf,KAAK,CAAC,YAAY;;;EAOxC;AAED,QAAA,MAAM,WAAW,yFA+ThB,CAAC;AAIF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"NumberInput.d.ts","sourceRoot":"","sources":["../../src/components/NumberInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,mBAAmB;;;8EAcvB,CAAC;AAqDH,UAAU,cAAc;IACtB,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,cAAc,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAChD,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,UAAU,gBACR,SAAQ,IAAI,CACR,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,MAAM,GAAG,UAAU,GAAG,OAAO,CAC9B,EACD,YAAY,CAAC,OAAO,mBAAmB,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B;;;OAGG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACpD;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAcD,iBAAS,eAAe,CACtB,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAC3C,SAAS,EAAE,WAAW,GAAG,WAAW;uBAGf,KAAK,CAAC,YAAY;;;EAOxC;AAED,QAAA,MAAM,WAAW,yFAkVhB,CAAC;AAIF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC;AAC7D,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"PriceInput.d.ts","sourceRoot":"","sources":["../../src/components/PriceInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAclE,QAAA,MAAM,kBAAkB;;;8EAatB,CAAC;AAEH,UAAU,eACR,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC,EACtG,YAAY,CAAC,OAAO,kBAAkB,CAAC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gGAAgG;IAChG,MAAM,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC;IACnC,sEAAsE;IACtE,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,iHAAiH;IACjH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2GAA2G;IAC3G,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,iCAAiC;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,yFAAyF;IACzF,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,QAAA,MAAM,UAAU,0FAqMf,CAAC;AAIF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"PriceInput.d.ts","sourceRoot":"","sources":["../../src/components/PriceInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,kBAAkB;;;8EAatB,CAAC;AAEH,UAAU,eACR,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAAC,EACtG,YAAY,CAAC,OAAO,kBAAkB,CAAC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gGAAgG;IAChG,MAAM,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC;IACnC,sEAAsE;IACtE,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2GAA2G;IAC3G,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,iHAAiH;IACjH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2GAA2G;IAC3G,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,iCAAiC;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,yFAAyF;IACzF,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,QAAA,MAAM,UAAU,0FAqMf,CAAC;AAIF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -41,8 +41,9 @@ var chunkJ5ZKGPBY_js = require('./chunks/chunk-J5ZKGPBY.js');
41
41
  var chunkX2SHTVZQ_js = require('./chunks/chunk-X2SHTVZQ.js');
42
42
  var chunkBBLBTOP4_js = require('./chunks/chunk-BBLBTOP4.js');
43
43
  var chunkXGIJZ3NZ_js = require('./chunks/chunk-XGIJZ3NZ.js');
44
- var chunk2BINGHGR_js = require('./chunks/chunk-2BINGHGR.js');
45
- var chunk4ENXP7WH_js = require('./chunks/chunk-4ENXP7WH.js');
44
+ var chunkEBMOQIY5_js = require('./chunks/chunk-EBMOQIY5.js');
45
+ var chunkL7SGGDY3_js = require('./chunks/chunk-L7SGGDY3.js');
46
+ require('./chunks/chunk-3BMVYJCA.js');
46
47
  var chunkMA2VCCIY_js = require('./chunks/chunk-MA2VCCIY.js');
47
48
  var chunkR744EATX_js = require('./chunks/chunk-R744EATX.js');
48
49
  var chunkF24AY3HI_js = require('./chunks/chunk-F24AY3HI.js');
@@ -766,23 +767,23 @@ Object.defineProperty(exports, "textAreaVariants", {
766
767
  });
767
768
  Object.defineProperty(exports, "NumberInput", {
768
769
  enumerable: true,
769
- get: function () { return chunk2BINGHGR_js.NumberInput; }
770
+ get: function () { return chunkEBMOQIY5_js.NumberInput; }
770
771
  });
771
772
  Object.defineProperty(exports, "numberInputBind", {
772
773
  enumerable: true,
773
- get: function () { return chunk2BINGHGR_js.numberInputBind; }
774
+ get: function () { return chunkEBMOQIY5_js.numberInputBind; }
774
775
  });
775
776
  Object.defineProperty(exports, "numberInputVariants", {
776
777
  enumerable: true,
777
- get: function () { return chunk2BINGHGR_js.numberInputVariants; }
778
+ get: function () { return chunkEBMOQIY5_js.numberInputVariants; }
778
779
  });
779
780
  Object.defineProperty(exports, "PriceInput", {
780
781
  enumerable: true,
781
- get: function () { return chunk4ENXP7WH_js.PriceInput; }
782
+ get: function () { return chunkL7SGGDY3_js.PriceInput; }
782
783
  });
783
784
  Object.defineProperty(exports, "priceInputVariants", {
784
785
  enumerable: true,
785
- get: function () { return chunk4ENXP7WH_js.priceInputVariants; }
786
+ get: function () { return chunkL7SGGDY3_js.priceInputVariants; }
786
787
  });
787
788
  Object.defineProperty(exports, "Avatar", {
788
789
  enumerable: true,
package/dist/index.mjs CHANGED
@@ -39,8 +39,9 @@ export { CheckBox, checkBoxVariants } from './chunks/chunk-MRRKW5QN.mjs';
39
39
  export { Switch, switchVariants } from './chunks/chunk-ADO7PDLY.mjs';
40
40
  export { TextInput, textInputVariants } from './chunks/chunk-UKRU46PH.mjs';
41
41
  export { TextArea, textAreaVariants } from './chunks/chunk-ZU4AWAFT.mjs';
42
- export { NumberInput, numberInputBind, numberInputVariants } from './chunks/chunk-RL5UAEGQ.mjs';
43
- export { PriceInput, priceInputVariants } from './chunks/chunk-WGGBE4ZD.mjs';
42
+ export { NumberInput, numberInputBind, numberInputVariants } from './chunks/chunk-FMUWSORG.mjs';
43
+ export { PriceInput, priceInputVariants } from './chunks/chunk-QBMDWUQU.mjs';
44
+ import './chunks/chunk-KHCPES3K.mjs';
44
45
  export { Avatar, avatarVariants } from './chunks/chunk-YLO4UKSC.mjs';
45
46
  export { ModalContainer_default as ModalContainer, ModalPortalTarget_default as ModalPortalTarget, ModalTemplate_default as ModalTemplate, checkModal, closeModal, getModalDefaultOption, openModal as modal, openModal, resetModal } from './chunks/chunk-7WWQ5DS3.mjs';
46
47
  export { useDraggableBottomSheet } from './chunks/chunk-WBCXHGRL.mjs';
@@ -1,19 +1,20 @@
1
1
  'use strict';
2
2
 
3
- var chunk2BINGHGR_js = require('./chunks/chunk-2BINGHGR.js');
3
+ var chunkEBMOQIY5_js = require('./chunks/chunk-EBMOQIY5.js');
4
+ require('./chunks/chunk-3BMVYJCA.js');
4
5
  require('./chunks/chunk-CZC76ZD5.js');
5
6
 
6
7
 
7
8
 
8
9
  Object.defineProperty(exports, "NumberInput", {
9
10
  enumerable: true,
10
- get: function () { return chunk2BINGHGR_js.NumberInput; }
11
+ get: function () { return chunkEBMOQIY5_js.NumberInput; }
11
12
  });
12
13
  Object.defineProperty(exports, "numberInputBind", {
13
14
  enumerable: true,
14
- get: function () { return chunk2BINGHGR_js.numberInputBind; }
15
+ get: function () { return chunkEBMOQIY5_js.numberInputBind; }
15
16
  });
16
17
  Object.defineProperty(exports, "numberInputVariants", {
17
18
  enumerable: true,
18
- get: function () { return chunk2BINGHGR_js.numberInputVariants; }
19
+ get: function () { return chunkEBMOQIY5_js.numberInputVariants; }
19
20
  });
@@ -1,2 +1,3 @@
1
- export { NumberInput, numberInputBind, numberInputVariants } from './chunks/chunk-RL5UAEGQ.mjs';
1
+ export { NumberInput, numberInputBind, numberInputVariants } from './chunks/chunk-FMUWSORG.mjs';
2
+ import './chunks/chunk-KHCPES3K.mjs';
2
3
  import './chunks/chunk-MCKOWMLS.mjs';
@@ -1,15 +1,16 @@
1
1
  'use strict';
2
2
 
3
- var chunk4ENXP7WH_js = require('./chunks/chunk-4ENXP7WH.js');
3
+ var chunkL7SGGDY3_js = require('./chunks/chunk-L7SGGDY3.js');
4
+ require('./chunks/chunk-3BMVYJCA.js');
4
5
  require('./chunks/chunk-CZC76ZD5.js');
5
6
 
6
7
 
7
8
 
8
9
  Object.defineProperty(exports, "PriceInput", {
9
10
  enumerable: true,
10
- get: function () { return chunk4ENXP7WH_js.PriceInput; }
11
+ get: function () { return chunkL7SGGDY3_js.PriceInput; }
11
12
  });
12
13
  Object.defineProperty(exports, "priceInputVariants", {
13
14
  enumerable: true,
14
- get: function () { return chunk4ENXP7WH_js.priceInputVariants; }
15
+ get: function () { return chunkL7SGGDY3_js.priceInputVariants; }
15
16
  });
@@ -1,2 +1,3 @@
1
- export { PriceInput, priceInputVariants } from './chunks/chunk-WGGBE4ZD.mjs';
1
+ export { PriceInput, priceInputVariants } from './chunks/chunk-QBMDWUQU.mjs';
2
+ import './chunks/chunk-KHCPES3K.mjs';
2
3
  import './chunks/chunk-MCKOWMLS.mjs';
@@ -2101,6 +2101,11 @@
2101
2101
  "type": "string",
2102
2102
  "description": "Placeholder (default: \"0\")"
2103
2103
  },
2104
+ "separator": {
2105
+ "type": "boolean",
2106
+ "default": false,
2107
+ "description": "Display thousand-separator commas (e.g. 1,000). onValueChange still receives raw number without commas. Decimal part is not separated (1,234.567)."
2108
+ },
2104
2109
  "name": {
2105
2110
  "type": "string",
2106
2111
  "description": "Form field name"
@@ -2128,7 +2133,7 @@
2128
2133
  }
2129
2134
  },
2130
2135
  "additionalProperties": false,
2131
- "description": "Number input with two variants: basic (chevron arrows) and bind (+/- buttons). Supports label, description, max display (click to fill), accelerated increment on long press. numberInputBind(ref, direction) binds acceleration to external buttons.\n\nWHEN TO USE:\n • Any numeric field — quantity, score, age, count\n • Currency with thousand separators → PriceInput instead\n • Date / time → DatePicker instead\n\nANTI-PATTERNS:\n ✗ <TextInput type=\"number\"> → <NumberInput> (loses keyboard ↑↓, step, accelerated long-press, max click)\n ✗ Custom +/- buttons + <input> → variant=\"bind\" (or numberInputBind for external)\n ✗ Manual thousand separators for currencyPriceInput\n ✗ Inline unit text inside label/description → use prefixIcon/suffixIcon (e.g. suffixIcon=\"%\")"
2136
+ "description": "Number input with two variants: basic (chevron arrows) and bind (+/- buttons). Supports label, description, max display (click to fill), accelerated increment on long press. numberInputBind(ref, direction) binds acceleration to external buttons.\n\nWHEN TO USE:\n • Any numeric field — quantity, score, age, count\n • Need thousand separators? Set separator={true}\n • Currency UX (prefix $, balance, maxBalance, click-to-fill balance) → PriceInput instead\n • Date / time → DatePicker instead\n\nANTI-PATTERNS:\n ✗ <TextInput type=\"number\"> → <NumberInput> (loses keyboard ↑↓, step, accelerated long-press, max click)\n ✗ Custom +/- buttons + <input> → variant=\"bind\" (or numberInputBind for external)\n ✗ Manual thousand separator string formattinguse separator={true}\n ✗ Inline unit text inside label/description → use prefixIcon/suffixIcon (e.g. suffixIcon=\"%\")"
2132
2137
  }
2133
2138
  },
2134
2139
  "$schema": "http://json-schema.org/draft-07/schema#"
@@ -17,6 +17,7 @@ export declare const numberInputPropsSchema: z.ZodObject<{
17
17
  disabled: z.ZodOptional<z.ZodBoolean>;
18
18
  readOnly: z.ZodOptional<z.ZodBoolean>;
19
19
  placeholder: z.ZodOptional<z.ZodString>;
20
+ separator: z.ZodDefault<z.ZodBoolean>;
20
21
  name: z.ZodOptional<z.ZodString>;
21
22
  id: z.ZodOptional<z.ZodString>;
22
23
  autoFocus: z.ZodOptional<z.ZodBoolean>;
@@ -25,6 +26,7 @@ export declare const numberInputPropsSchema: z.ZodObject<{
25
26
  onFocus: z.ZodOptional<z.ZodAny>;
26
27
  className: z.ZodOptional<z.ZodString>;
27
28
  }, "strip", z.ZodTypeAny, {
29
+ separator: boolean;
28
30
  size: "xl" | "lg" | "md";
29
31
  variant: "basic" | "bind";
30
32
  step: number;
@@ -55,6 +57,7 @@ export declare const numberInputPropsSchema: z.ZodObject<{
55
57
  id?: string | undefined;
56
58
  error?: boolean | undefined;
57
59
  label?: string | undefined;
60
+ separator?: boolean | undefined;
58
61
  description?: string | undefined;
59
62
  value?: string | number | undefined;
60
63
  size?: "xl" | "lg" | "md" | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/schemas/number-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0EhC,CAAC"}
1
+ {"version":3,"file":"number-input.d.ts","sourceRoot":"","sources":["../../src/schemas/number-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiFhC,CAAC"}
@@ -87,6 +87,11 @@
87
87
  "type": "string",
88
88
  "description": "Placeholder (default: \"0\")"
89
89
  },
90
+ "separator": {
91
+ "type": "boolean",
92
+ "default": false,
93
+ "description": "Display thousand-separator commas (e.g. 1,000). onValueChange still receives raw number without commas. Decimal part is not separated (1,234.567)."
94
+ },
90
95
  "name": {
91
96
  "type": "string",
92
97
  "description": "Form field name"
@@ -114,7 +119,7 @@
114
119
  }
115
120
  },
116
121
  "additionalProperties": false,
117
- "description": "Number input with two variants: basic (chevron arrows) and bind (+/- buttons). Supports label, description, max display (click to fill), accelerated increment on long press. numberInputBind(ref, direction) binds acceleration to external buttons.\n\nWHEN TO USE:\n • Any numeric field — quantity, score, age, count\n • Currency with thousand separators → PriceInput instead\n • Date / time → DatePicker instead\n\nANTI-PATTERNS:\n ✗ <TextInput type=\"number\"> → <NumberInput> (loses keyboard ↑↓, step, accelerated long-press, max click)\n ✗ Custom +/- buttons + <input> → variant=\"bind\" (or numberInputBind for external)\n ✗ Manual thousand separators for currencyPriceInput\n ✗ Inline unit text inside label/description → use prefixIcon/suffixIcon (e.g. suffixIcon=\"%\")"
122
+ "description": "Number input with two variants: basic (chevron arrows) and bind (+/- buttons). Supports label, description, max display (click to fill), accelerated increment on long press. numberInputBind(ref, direction) binds acceleration to external buttons.\n\nWHEN TO USE:\n • Any numeric field — quantity, score, age, count\n • Need thousand separators? Set separator={true}\n • Currency UX (prefix $, balance, maxBalance, click-to-fill balance) → PriceInput instead\n • Date / time → DatePicker instead\n\nANTI-PATTERNS:\n ✗ <TextInput type=\"number\"> → <NumberInput> (loses keyboard ↑↓, step, accelerated long-press, max click)\n ✗ Custom +/- buttons + <input> → variant=\"bind\" (or numberInputBind for external)\n ✗ Manual thousand separator string formattinguse separator={true}\n ✗ Inline unit text inside label/description → use prefixIcon/suffixIcon (e.g. suffixIcon=\"%\")"
118
123
  }
119
124
  },
120
125
  "$schema": "http://json-schema.org/draft-07/schema#"
package/dist/schemas.js CHANGED
@@ -1186,6 +1186,9 @@ var numberInputPropsSchema = zod.z.object({
1186
1186
  disabled: zod.z.boolean().optional().describe("Disabled"),
1187
1187
  readOnly: zod.z.boolean().optional().describe("Read-only (includes hiding buttons)"),
1188
1188
  placeholder: zod.z.string().optional().describe('Placeholder (default: "0")'),
1189
+ separator: zod.z.boolean().default(false).describe(
1190
+ "Display thousand-separator commas (e.g. 1,000). onValueChange still receives raw number without commas. Decimal part is not separated (1,234.567)."
1191
+ ),
1189
1192
  name: zod.z.string().optional().describe("Form field name"),
1190
1193
  id: zod.z.string().optional().describe("Element ID"),
1191
1194
  autoFocus: zod.z.boolean().optional().describe("Auto focus"),
@@ -1198,13 +1201,14 @@ var numberInputPropsSchema = zod.z.object({
1198
1201
 
1199
1202
  WHEN TO USE:
1200
1203
  \u2022 Any numeric field \u2014 quantity, score, age, count
1201
- \u2022 Currency with thousand separators \u2192 PriceInput instead
1204
+ \u2022 Need thousand separators? Set separator={true}
1205
+ \u2022 Currency UX (prefix $, balance, maxBalance, click-to-fill balance) \u2192 PriceInput instead
1202
1206
  \u2022 Date / time \u2192 DatePicker instead
1203
1207
 
1204
1208
  ANTI-PATTERNS:
1205
1209
  \u2717 <TextInput type="number"> \u2192 <NumberInput> (loses keyboard \u2191\u2193, step, accelerated long-press, max click)
1206
1210
  \u2717 Custom +/- buttons + <input> \u2192 variant="bind" (or numberInputBind for external)
1207
- \u2717 Manual thousand separators for currency \u2192 PriceInput
1211
+ \u2717 Manual thousand separator string formatting \u2192 use separator={true}
1208
1212
  \u2717 Inline unit text inside label/description \u2192 use prefixIcon/suffixIcon (e.g. suffixIcon="%")`
1209
1213
  );
1210
1214
  var priceInputPropsSchema = zod.z.object({
package/dist/schemas.mjs CHANGED
@@ -1184,6 +1184,9 @@ var numberInputPropsSchema = z.object({
1184
1184
  disabled: z.boolean().optional().describe("Disabled"),
1185
1185
  readOnly: z.boolean().optional().describe("Read-only (includes hiding buttons)"),
1186
1186
  placeholder: z.string().optional().describe('Placeholder (default: "0")'),
1187
+ separator: z.boolean().default(false).describe(
1188
+ "Display thousand-separator commas (e.g. 1,000). onValueChange still receives raw number without commas. Decimal part is not separated (1,234.567)."
1189
+ ),
1187
1190
  name: z.string().optional().describe("Form field name"),
1188
1191
  id: z.string().optional().describe("Element ID"),
1189
1192
  autoFocus: z.boolean().optional().describe("Auto focus"),
@@ -1196,13 +1199,14 @@ var numberInputPropsSchema = z.object({
1196
1199
 
1197
1200
  WHEN TO USE:
1198
1201
  \u2022 Any numeric field \u2014 quantity, score, age, count
1199
- \u2022 Currency with thousand separators \u2192 PriceInput instead
1202
+ \u2022 Need thousand separators? Set separator={true}
1203
+ \u2022 Currency UX (prefix $, balance, maxBalance, click-to-fill balance) \u2192 PriceInput instead
1200
1204
  \u2022 Date / time \u2192 DatePicker instead
1201
1205
 
1202
1206
  ANTI-PATTERNS:
1203
1207
  \u2717 <TextInput type="number"> \u2192 <NumberInput> (loses keyboard \u2191\u2193, step, accelerated long-press, max click)
1204
1208
  \u2717 Custom +/- buttons + <input> \u2192 variant="bind" (or numberInputBind for external)
1205
- \u2717 Manual thousand separators for currency \u2192 PriceInput
1209
+ \u2717 Manual thousand separator string formatting \u2192 use separator={true}
1206
1210
  \u2717 Inline unit text inside label/description \u2192 use prefixIcon/suffixIcon (e.g. suffixIcon="%")`
1207
1211
  );
1208
1212
  var priceInputPropsSchema = z.object({
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Company CSS — Tailwind v4 (@theme + .dark)
3
3
  * 자동 생성: scripts/generate-css.js
4
- * 생성일: 2026-05-14T03:22:06.241Z
4
+ * 생성일: 2026-05-21T07:29:09.566Z
5
5
  *
6
6
  * @theme: Tailwind 유틸리티 클래스 자동 생성
7
7
  * :root: 순수 CSS 변수 (var()로 직접 사용)
@@ -2,7 +2,7 @@
2
2
  * Company CSS — 순수 CSS 변수 (:root + .dark)
3
3
  * Tailwind 없이 var(--*) 로 사용 가능
4
4
  * 자동 생성: scripts/generate-css.js
5
- * 생성일: 2026-05-14T03:22:06.246Z
5
+ * 생성일: 2026-05-21T07:29:09.570Z
6
6
  */
7
7
 
8
8
  :root {
@@ -2,7 +2,7 @@
2
2
  * Gamehub Domain CSS — 순수 CSS 변수
3
3
  * Tailwind 없이 var(--*) 로 사용 가능
4
4
  * 자동 생성: scripts/generate-css.js
5
- * 생성일: 2026-05-14T03:22:06.251Z
5
+ * 생성일: 2026-05-21T07:29:09.575Z
6
6
  */
7
7
 
8
8
  :root {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Gamehub Domain CSS — Tailwind v4 (@theme + .gamehub)
3
3
  * 자동 생성: scripts/generate-css.js
4
- * 생성일: 2026-05-14T03:22:06.250Z
4
+ * 생성일: 2026-05-21T07:29:09.575Z
5
5
  */
6
6
 
7
7
  @theme {
@@ -2,7 +2,7 @@
2
2
  * Prediction Domain CSS — 순수 CSS 변수
3
3
  * Tailwind 없이 var(--*) 로 사용 가능
4
4
  * 자동 생성: scripts/generate-css.js
5
- * 생성일: 2026-05-14T03:22:06.253Z
5
+ * 생성일: 2026-05-21T07:29:09.576Z
6
6
  */
7
7
 
8
8
  :root {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Prediction Domain CSS — Tailwind v4 (@theme + .prediction)
3
3
  * 자동 생성: scripts/generate-css.js
4
- * 생성일: 2026-05-14T03:22:06.252Z
4
+ * 생성일: 2026-05-21T07:29:09.576Z
5
5
  */
6
6
 
7
7
  @theme {
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 천단위 콤마(,) 포맷 / 언포맷 유틸.
3
+ *
4
+ * NumberInput, PriceInput 등 숫자 입력 컴포넌트에서 `separator` 옵션이 켜졌을 때 공통으로 사용한다.
5
+ *
6
+ * - `formatWithComma('1234567.89') → '1,234,567.89'` (소수부는 콤마 미적용)
7
+ * - `formatWithComma('-1234') → '-1,234'`
8
+ * - `stripComma('1,234,567') → '1234567'`
9
+ *
10
+ * `value` 가 `string` 타입인 것은 입력 도중 사용자가 타이핑하는 부분 문자열
11
+ * (예: '-', '12.', '0.0') 을 손상 없이 유지하기 위함이다.
12
+ */
13
+ export declare function formatWithComma(value: string): string;
14
+ export declare function stripComma(value: string): string;
15
+ //# sourceMappingURL=numberFormat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numberFormat.d.ts","sourceRoot":"","sources":["../../src/utils/numberFormat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexus-cross/design-system",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "NEXUS Design System UI Components",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -361,8 +361,8 @@
361
361
  "sonner": "^2.0.7",
362
362
  "vaul": "^1.1.2",
363
363
  "zod": "^3.25.76",
364
- "@nexus-cross/tokens": "2.0.5",
365
- "@nexus-cross/tokens-domains": "2.0.5"
364
+ "@nexus-cross/tokens": "2.0.6",
365
+ "@nexus-cross/tokens-domains": "2.0.6"
366
366
  },
367
367
  "devDependencies": {
368
368
  "@testing-library/jest-dom": "^6.9.1",