@techsio/ui-kit 0.53.0 → 0.54.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/atoms/numeric-input.js +86 -31
- package/dist/molecules/quantity-field.js +162 -0
- package/dist/src/atoms/numeric-input.d.ts +5 -5
- package/dist/src/atoms/numeric-input.d.ts.map +1 -1
- package/dist/src/molecules/quantity-field.d.ts +30 -0
- package/dist/src/molecules/quantity-field.d.ts.map +1 -0
- package/dist/src/templates/numeric-input.d.ts +1 -1
- package/dist/stories/atoms/numeric-input.stories.d.ts +4 -0
- package/dist/stories/atoms/numeric-input.stories.d.ts.map +1 -1
- package/dist/stories/changelog/changelog.stories.d.ts.map +1 -1
- package/dist/stories/molecules/form-numeric-input.stories.d.ts +1 -0
- package/dist/stories/molecules/form-numeric-input.stories.d.ts.map +1 -1
- package/dist/stories/molecules/quantity-field.stories.d.ts +16 -0
- package/dist/stories/molecules/quantity-field.stories.d.ts.map +1 -0
- package/dist/test/numeric-input.spec.d.ts +2 -0
- package/dist/test/numeric-input.spec.d.ts.map +1 -0
- package/dist/test/quantity-field.spec.d.ts +2 -0
- package/dist/test/quantity-field.spec.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/tokens/components/components.css +1 -0
- package/src/tokens/components/molecules/_quantity-field.css +17 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { normalizeProps, useMachine } from "@zag-js/react";
|
|
3
|
-
import { createContext, useContext, useId } from "react";
|
|
3
|
+
import { createContext, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef } from "react";
|
|
4
4
|
import { tv } from "../utils.js";
|
|
5
5
|
import { Button } from "./button.js";
|
|
6
6
|
import { Input } from "./input.js";
|
|
@@ -81,65 +81,76 @@ const numericInputVariants = tv({
|
|
|
81
81
|
size: "md"
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
|
+
const triggerIconSizes = {
|
|
85
|
+
sm: "xs",
|
|
86
|
+
md: "sm",
|
|
87
|
+
lg: "md"
|
|
88
|
+
};
|
|
84
89
|
const NumericInputContext = /*#__PURE__*/ createContext(null);
|
|
85
90
|
function useNumericInputContext() {
|
|
86
91
|
const context = useContext(NumericInputContext);
|
|
87
92
|
if (!context) throw new Error("NumericInput components must be used within NumericInput.Root");
|
|
88
93
|
return context;
|
|
89
94
|
}
|
|
90
|
-
function NumericInput({ id,
|
|
95
|
+
function NumericInput({ id, size, value, defaultValue, onChange, dir = "ltr", describedBy, precision, children, ref, className, locale = "cs-CZ", ...props }) {
|
|
91
96
|
const generatedId = useId();
|
|
92
|
-
const
|
|
97
|
+
const [machineProps, elementProps] = __rspack_external__zag_js_number_input_f1a1f439.splitProps(props);
|
|
98
|
+
const { formatOptions, invalid, disabled = false, required = false, step = 1, allowMouseWheel = true, clampValueOnBlur = true, spinOnPress = true, focusInputOnChange = true } = machineProps;
|
|
93
99
|
const resolvedFormatOptions = precision ? {
|
|
94
100
|
...formatOptions ?? {},
|
|
95
101
|
maximumFractionDigits: precision
|
|
96
102
|
} : formatOptions;
|
|
97
103
|
const formatValue = (inputValue)=>{
|
|
98
|
-
if (!resolvedFormatOptions) return String(inputValue);
|
|
104
|
+
if ("string" == typeof inputValue || !resolvedFormatOptions) return String(inputValue);
|
|
99
105
|
return new Intl.NumberFormat(locale, resolvedFormatOptions).format(inputValue);
|
|
100
106
|
};
|
|
101
|
-
const stringValue = void 0 !== value ? formatValue(value) : void 0;
|
|
102
|
-
const stringDefaultValue = void 0 !== defaultValue ? formatValue(defaultValue) : void 0;
|
|
103
107
|
const service = useMachine(__rspack_external__zag_js_number_input_f1a1f439.machine, {
|
|
104
|
-
|
|
105
|
-
ids: id ? {
|
|
106
|
-
input: id
|
|
107
|
-
} : void 0,
|
|
108
|
-
min,
|
|
109
|
-
max,
|
|
110
|
-
step,
|
|
111
|
-
name,
|
|
108
|
+
...machineProps,
|
|
112
109
|
disabled,
|
|
113
|
-
locale,
|
|
114
110
|
required,
|
|
115
|
-
|
|
116
|
-
readOnly,
|
|
117
|
-
inputMode,
|
|
118
|
-
dir,
|
|
119
|
-
invalid,
|
|
120
|
-
value: stringValue,
|
|
121
|
-
defaultValue: stringDefaultValue,
|
|
111
|
+
step,
|
|
122
112
|
allowMouseWheel,
|
|
123
|
-
allowOverflow,
|
|
124
113
|
clampValueOnBlur,
|
|
125
114
|
spinOnPress,
|
|
115
|
+
focusInputOnChange,
|
|
116
|
+
id: id || generatedId,
|
|
117
|
+
ids: id ? {
|
|
118
|
+
...machineProps.ids,
|
|
119
|
+
input: id
|
|
120
|
+
} : machineProps.ids,
|
|
121
|
+
dir,
|
|
122
|
+
locale,
|
|
123
|
+
value: void 0 !== value ? formatValue(value) : void 0,
|
|
124
|
+
defaultValue: void 0 !== defaultValue ? formatValue(defaultValue) : void 0,
|
|
126
125
|
formatOptions: resolvedFormatOptions,
|
|
127
126
|
onValueChange: (details)=>{
|
|
128
127
|
onChange?.(details.valueAsNumber);
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
machineProps.onValueChange?.(details);
|
|
129
|
+
}
|
|
131
130
|
});
|
|
132
131
|
const api = __rspack_external__zag_js_number_input_f1a1f439.connect(service, normalizeProps);
|
|
132
|
+
useEffect(()=>{
|
|
133
|
+
const inputId = api.getInputProps().id;
|
|
134
|
+
const input = inputId ? service.scope.getById(inputId) : null;
|
|
135
|
+
if (input && input === service.scope.getActiveElement() && !api.focused) service.send({
|
|
136
|
+
type: "INPUT.FOCUS"
|
|
137
|
+
});
|
|
138
|
+
}, [
|
|
139
|
+
api,
|
|
140
|
+
service
|
|
141
|
+
]);
|
|
133
142
|
const styles = numericInputVariants({
|
|
134
143
|
size
|
|
135
144
|
});
|
|
145
|
+
const inputDisabled = api.getInputProps().disabled;
|
|
136
146
|
return /*#__PURE__*/ jsx(NumericInputContext.Provider, {
|
|
137
147
|
value: {
|
|
138
148
|
api,
|
|
139
149
|
size,
|
|
140
150
|
styles,
|
|
141
151
|
invalid,
|
|
142
|
-
describedBy
|
|
152
|
+
describedBy,
|
|
153
|
+
controlledValue: "string" == typeof value ? value : void 0
|
|
143
154
|
},
|
|
144
155
|
children: /*#__PURE__*/ jsx("div", {
|
|
145
156
|
className: styles.root({
|
|
@@ -147,7 +158,11 @@ function NumericInput({ id, name, size, disabled = false, required = false, patt
|
|
|
147
158
|
}),
|
|
148
159
|
ref: ref,
|
|
149
160
|
...api.getRootProps(),
|
|
150
|
-
...
|
|
161
|
+
...elementProps,
|
|
162
|
+
onWheelCapture: (event)=>{
|
|
163
|
+
if (inputDisabled || machineProps.readOnly) event.stopPropagation();
|
|
164
|
+
elementProps.onWheelCapture?.(event);
|
|
165
|
+
},
|
|
151
166
|
children: children
|
|
152
167
|
})
|
|
153
168
|
});
|
|
@@ -166,13 +181,53 @@ NumericInput.Control = function({ children, ref, className, ...props }) {
|
|
|
166
181
|
});
|
|
167
182
|
};
|
|
168
183
|
NumericInput.Input = function({ ref, className, ...props }) {
|
|
169
|
-
const { api, styles, describedBy } = useNumericInputContext();
|
|
184
|
+
const { api, styles, describedBy, controlledValue } = useNumericInputContext();
|
|
185
|
+
const inputRef = useRef(null);
|
|
186
|
+
const mergedRef = useMemo(()=>(node)=>{
|
|
187
|
+
inputRef.current = node;
|
|
188
|
+
const cleanup = "function" == typeof ref ? ref(node) : void 0;
|
|
189
|
+
if (ref && "function" != typeof ref) ref.current = node;
|
|
190
|
+
return ()=>{
|
|
191
|
+
inputRef.current = null;
|
|
192
|
+
if ("function" == typeof cleanup) cleanup();
|
|
193
|
+
else if ("function" == typeof ref) ref(null);
|
|
194
|
+
else if (ref) ref.current = null;
|
|
195
|
+
};
|
|
196
|
+
}, [
|
|
197
|
+
ref
|
|
198
|
+
]);
|
|
199
|
+
useLayoutEffect(()=>{
|
|
200
|
+
if (void 0 === controlledValue) return;
|
|
201
|
+
const view = inputRef.current?.ownerDocument.defaultView;
|
|
202
|
+
if (!view) return;
|
|
203
|
+
let cancelled = false;
|
|
204
|
+
let frame;
|
|
205
|
+
queueMicrotask(()=>{
|
|
206
|
+
if (cancelled) return;
|
|
207
|
+
frame = view.requestAnimationFrame(()=>{
|
|
208
|
+
const input = inputRef.current;
|
|
209
|
+
if (!input || input.value === controlledValue) return;
|
|
210
|
+
const start = input.selectionStart;
|
|
211
|
+
const end = input.selectionEnd;
|
|
212
|
+
const direction = input.selectionDirection;
|
|
213
|
+
input.value = controlledValue;
|
|
214
|
+
if (input.ownerDocument.activeElement === input && null !== start && null !== end) input.setSelectionRange(Math.min(start, controlledValue.length), Math.min(end, controlledValue.length), direction ?? void 0);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
return ()=>{
|
|
218
|
+
cancelled = true;
|
|
219
|
+
if (void 0 !== frame) view.cancelAnimationFrame(frame);
|
|
220
|
+
};
|
|
221
|
+
}, [
|
|
222
|
+
api,
|
|
223
|
+
controlledValue
|
|
224
|
+
]);
|
|
170
225
|
const ariaDescribedBy = [
|
|
171
226
|
props["aria-describedby"],
|
|
172
227
|
describedBy
|
|
173
228
|
].filter(Boolean).join(" ") || void 0;
|
|
174
229
|
return /*#__PURE__*/ jsx(Input, {
|
|
175
|
-
ref: ref,
|
|
230
|
+
ref: void 0 === controlledValue ? ref : mergedRef,
|
|
176
231
|
...api.getInputProps(),
|
|
177
232
|
...props,
|
|
178
233
|
"aria-describedby": ariaDescribedBy,
|
|
@@ -183,7 +238,7 @@ NumericInput.Input = function({ ref, className, ...props }) {
|
|
|
183
238
|
};
|
|
184
239
|
NumericInput.IncrementTrigger = function({ variant = "primary", theme = "borderless", icon = "token-icon-numeric-input-increment", iconPosition = "left", iconSize, uppercase, block, isLoading, loadingText, ref, className, children, ...props }) {
|
|
185
240
|
const { api, styles, size } = useNumericInputContext();
|
|
186
|
-
const resolvedIconSize = iconSize ??
|
|
241
|
+
const resolvedIconSize = iconSize ?? triggerIconSizes[size ?? "md"];
|
|
187
242
|
return /*#__PURE__*/ jsx(Button, {
|
|
188
243
|
block: block,
|
|
189
244
|
className: styles.trigger({
|
|
@@ -206,7 +261,7 @@ NumericInput.IncrementTrigger = function({ variant = "primary", theme = "borderl
|
|
|
206
261
|
};
|
|
207
262
|
NumericInput.DecrementTrigger = function({ variant = "primary", theme = "borderless", icon = "token-icon-numeric-input-decrement", iconPosition = "left", iconSize, uppercase, block, isLoading, loadingText, ref, className, children, ...props }) {
|
|
208
263
|
const { api, styles, size } = useNumericInputContext();
|
|
209
|
-
const resolvedIconSize = iconSize ??
|
|
264
|
+
const resolvedIconSize = iconSize ?? triggerIconSizes[size ?? "md"];
|
|
210
265
|
return /*#__PURE__*/ jsx(Button, {
|
|
211
266
|
block: block,
|
|
212
267
|
className: styles.trigger({
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useId } from "react";
|
|
3
|
+
import { Label } from "../atoms/label.js";
|
|
4
|
+
import { NumericInput } from "../atoms/numeric-input.js";
|
|
5
|
+
import { StatusText } from "../atoms/status-text.js";
|
|
6
|
+
import { tv } from "../utils.js";
|
|
7
|
+
const descriptionSeparator = /\s+/;
|
|
8
|
+
const quantityFieldVariants = tv({
|
|
9
|
+
slots: {
|
|
10
|
+
root: "flex min-w-0 flex-col gap-quantity-field",
|
|
11
|
+
control: "flex min-w-0 flex-wrap items-center gap-quantity-field-control",
|
|
12
|
+
numeric: "min-w-quantity-field-control-min-width flex-1",
|
|
13
|
+
input: "min-w-0",
|
|
14
|
+
unit: "min-w-0 max-w-full break-words text-quantity-field-unit-fg",
|
|
15
|
+
message: "text-quantity-field-message-fg",
|
|
16
|
+
label: ""
|
|
17
|
+
},
|
|
18
|
+
variants: {
|
|
19
|
+
size: {
|
|
20
|
+
sm: {
|
|
21
|
+
unit: "text-quantity-field-unit-sm"
|
|
22
|
+
},
|
|
23
|
+
md: {
|
|
24
|
+
unit: "text-quantity-field-unit-md"
|
|
25
|
+
},
|
|
26
|
+
lg: {
|
|
27
|
+
unit: "text-quantity-field-unit-lg"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
hideLabel: {
|
|
31
|
+
true: {
|
|
32
|
+
label: "sr-only"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
defaultVariants: {
|
|
37
|
+
size: "md",
|
|
38
|
+
hideLabel: false
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
function hasContent(content) {
|
|
42
|
+
return null != content && false !== content && "" !== content;
|
|
43
|
+
}
|
|
44
|
+
function QuantityField({ id, label, unitLabel, value, onValueChange, onValueCommit, helperText, error, hideLabel = false, pending = false, pendingLabel, disabled = false, readOnly = false, required, describedBy, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, autoFocus, size = "md", formatOptions, ref, className, ...props }) {
|
|
45
|
+
const generatedId = useId();
|
|
46
|
+
const inputId = id ?? generatedId;
|
|
47
|
+
const unitId = `${inputId}-unit`;
|
|
48
|
+
const helperId = `${inputId}-helper`;
|
|
49
|
+
const errorId = `${inputId}-error`;
|
|
50
|
+
const pendingId = `${inputId}-pending`;
|
|
51
|
+
const hasError = hasContent(error);
|
|
52
|
+
const hasHelper = hasContent(helperText);
|
|
53
|
+
const blocked = pending || disabled || readOnly;
|
|
54
|
+
const mergedDescribedBy = [
|
|
55
|
+
describedBy,
|
|
56
|
+
ariaDescribedBy,
|
|
57
|
+
unitId,
|
|
58
|
+
hasHelper ? helperId : void 0,
|
|
59
|
+
hasError ? errorId : void 0,
|
|
60
|
+
pending ? pendingId : void 0
|
|
61
|
+
].filter(Boolean).flatMap((description)=>description?.split(descriptionSeparator) ?? []).filter(Boolean);
|
|
62
|
+
const inputDescribedBy = [
|
|
63
|
+
...new Set(mergedDescribedBy)
|
|
64
|
+
].join(" ");
|
|
65
|
+
const styles = quantityFieldVariants({
|
|
66
|
+
size,
|
|
67
|
+
hideLabel
|
|
68
|
+
});
|
|
69
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
70
|
+
className: styles.root({
|
|
71
|
+
className
|
|
72
|
+
}),
|
|
73
|
+
"data-pending": pending || void 0,
|
|
74
|
+
"data-validation": hasError ? "error" : void 0,
|
|
75
|
+
children: [
|
|
76
|
+
/*#__PURE__*/ jsx(Label, {
|
|
77
|
+
className: styles.label(),
|
|
78
|
+
disabled: disabled || pending,
|
|
79
|
+
htmlFor: inputId,
|
|
80
|
+
required: required,
|
|
81
|
+
size: size,
|
|
82
|
+
children: label
|
|
83
|
+
}),
|
|
84
|
+
/*#__PURE__*/ jsxs("div", {
|
|
85
|
+
"aria-busy": pending || void 0,
|
|
86
|
+
className: styles.control(),
|
|
87
|
+
children: [
|
|
88
|
+
/*#__PURE__*/ jsx(NumericInput, {
|
|
89
|
+
...props,
|
|
90
|
+
allowOverflow: false,
|
|
91
|
+
clampValueOnBlur: false,
|
|
92
|
+
className: styles.numeric(),
|
|
93
|
+
describedBy: inputDescribedBy,
|
|
94
|
+
disabled: disabled || pending,
|
|
95
|
+
formatOptions: formatOptions ?? {
|
|
96
|
+
useGrouping: false,
|
|
97
|
+
maximumFractionDigits: 20
|
|
98
|
+
},
|
|
99
|
+
id: inputId,
|
|
100
|
+
invalid: hasError,
|
|
101
|
+
onValueChange: (details)=>{
|
|
102
|
+
if (!blocked) onValueChange(details);
|
|
103
|
+
},
|
|
104
|
+
onValueCommit: (details)=>{
|
|
105
|
+
if (!blocked) onValueCommit?.(details);
|
|
106
|
+
},
|
|
107
|
+
readOnly: readOnly,
|
|
108
|
+
required: required,
|
|
109
|
+
size: size,
|
|
110
|
+
value: value,
|
|
111
|
+
children: /*#__PURE__*/ jsxs(NumericInput.Control, {
|
|
112
|
+
className: styles.numeric(),
|
|
113
|
+
"data-validation": hasError ? "error" : void 0,
|
|
114
|
+
children: [
|
|
115
|
+
/*#__PURE__*/ jsx(NumericInput.Input, {
|
|
116
|
+
"aria-label": ariaLabel,
|
|
117
|
+
"aria-labelledby": ariaLabelledBy,
|
|
118
|
+
autoFocus: autoFocus,
|
|
119
|
+
className: styles.input(),
|
|
120
|
+
ref: ref
|
|
121
|
+
}),
|
|
122
|
+
/*#__PURE__*/ jsxs(NumericInput.TriggerContainer, {
|
|
123
|
+
children: [
|
|
124
|
+
/*#__PURE__*/ jsx(NumericInput.IncrementTrigger, {}),
|
|
125
|
+
/*#__PURE__*/ jsx(NumericInput.DecrementTrigger, {})
|
|
126
|
+
]
|
|
127
|
+
})
|
|
128
|
+
]
|
|
129
|
+
})
|
|
130
|
+
}),
|
|
131
|
+
/*#__PURE__*/ jsx("span", {
|
|
132
|
+
className: styles.unit(),
|
|
133
|
+
id: unitId,
|
|
134
|
+
children: unitLabel
|
|
135
|
+
})
|
|
136
|
+
]
|
|
137
|
+
}),
|
|
138
|
+
hasHelper && /*#__PURE__*/ jsx(StatusText, {
|
|
139
|
+
className: styles.message(),
|
|
140
|
+
id: helperId,
|
|
141
|
+
size: size,
|
|
142
|
+
children: helperText
|
|
143
|
+
}),
|
|
144
|
+
hasError && /*#__PURE__*/ jsx(StatusText, {
|
|
145
|
+
id: errorId,
|
|
146
|
+
size: size,
|
|
147
|
+
status: "error",
|
|
148
|
+
children: error
|
|
149
|
+
}),
|
|
150
|
+
pending && /*#__PURE__*/ jsx(StatusText, {
|
|
151
|
+
"aria-atomic": "true",
|
|
152
|
+
"aria-live": "polite",
|
|
153
|
+
className: styles.message(),
|
|
154
|
+
id: pendingId,
|
|
155
|
+
role: "status",
|
|
156
|
+
size: size,
|
|
157
|
+
children: pendingLabel
|
|
158
|
+
})
|
|
159
|
+
]
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
export { QuantityField };
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* NumericInput — @techsio/ui-kit atom.
|
|
3
3
|
*
|
|
4
4
|
* @component NumericInput
|
|
5
|
-
* @componentVersion v1.0
|
|
5
|
+
* @componentVersion v1.1.0
|
|
6
6
|
* @skill numeric-input-usage
|
|
7
7
|
* @changelog libs/ui/stories/changelog/changelog.stories.tsx
|
|
8
8
|
*
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import * as numberInput from "@zag-js/number-input";
|
|
13
13
|
import { type ComponentPropsWithoutRef, type ReactNode, type Ref } from "react";
|
|
14
14
|
import type { IconType } from "./icon.js";
|
|
15
|
-
export type NumericInputProps = Omit<numberInput.Props, "value" | "defaultValue" | "id"> & Omit<ComponentPropsWithoutRef<"div">, "onChange" | "children"> & {
|
|
15
|
+
export type NumericInputProps = Omit<numberInput.Props, "value" | "defaultValue" | "id"> & Omit<ComponentPropsWithoutRef<"div">, "onChange" | "children" | "defaultValue"> & {
|
|
16
16
|
size?: "sm" | "md" | "lg";
|
|
17
|
-
value?: number;
|
|
18
|
-
defaultValue?: number;
|
|
17
|
+
value?: number | string;
|
|
18
|
+
defaultValue?: number | string;
|
|
19
19
|
onChange?: (value: number) => void;
|
|
20
20
|
precision?: number;
|
|
21
21
|
children?: ReactNode;
|
|
@@ -24,7 +24,7 @@ export type NumericInputProps = Omit<numberInput.Props, "value" | "defaultValue"
|
|
|
24
24
|
id?: string;
|
|
25
25
|
locale?: string;
|
|
26
26
|
};
|
|
27
|
-
export declare function NumericInput({ id,
|
|
27
|
+
export declare function NumericInput({ id, size, value, defaultValue, onChange, dir, describedBy, precision, children, ref, className, locale, ...props }: NumericInputProps): import("react/jsx-runtime").JSX.Element;
|
|
28
28
|
export declare namespace NumericInput {
|
|
29
29
|
var Control: ({ children, ref, className, ...props }: NumericInputControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
30
|
var Input: ({ ref, className, ...props }: NumericInputInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numeric-input.d.ts","sourceRoot":"","sources":["../../../src/atoms/numeric-input.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,WAAW,MAAM,sBAAsB,CAAA;AAEnD,OAAO,EACL,KAAK,wBAAwB,EAE7B,KAAK,SAAS,EACd,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"numeric-input.d.ts","sourceRoot":"","sources":["../../../src/atoms/numeric-input.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QuantityField — @techsio/ui-kit molecule.
|
|
3
|
+
*
|
|
4
|
+
* @component QuantityField
|
|
5
|
+
* @componentVersion v1.0.0
|
|
6
|
+
* @skill quantity-field-usage
|
|
7
|
+
* @changelog libs/ui/stories/changelog/changelog.stories.tsx
|
|
8
|
+
*/
|
|
9
|
+
import { type ReactNode, type Ref } from "react";
|
|
10
|
+
import { type NumericInputProps } from "../atoms/numeric-input.js";
|
|
11
|
+
type QuantityFieldPendingProps = {
|
|
12
|
+
pending: true;
|
|
13
|
+
pendingLabel: string;
|
|
14
|
+
} | {
|
|
15
|
+
pending?: false;
|
|
16
|
+
pendingLabel?: string;
|
|
17
|
+
};
|
|
18
|
+
export type QuantityFieldProps = Omit<NumericInputProps, "children" | "value" | "defaultValue" | "onChange" | "ref" | "invalid" | "allowOverflow" | "clampValueOnBlur" | "precision" | "ids"> & QuantityFieldPendingProps & {
|
|
19
|
+
label: ReactNode;
|
|
20
|
+
unitLabel: string;
|
|
21
|
+
value: string;
|
|
22
|
+
onValueChange: NonNullable<NumericInputProps["onValueChange"]>;
|
|
23
|
+
helperText?: ReactNode;
|
|
24
|
+
error?: ReactNode;
|
|
25
|
+
hideLabel?: boolean;
|
|
26
|
+
ref?: Ref<HTMLInputElement>;
|
|
27
|
+
};
|
|
28
|
+
export declare function QuantityField({ id, label, unitLabel, value, onValueChange, onValueCommit, helperText, error, hideLabel, pending, pendingLabel, disabled, readOnly, required, describedBy, "aria-describedby": ariaDescribedBy, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, autoFocus, size, formatOptions, ref, className, ...props }: QuantityFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=quantity-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantity-field.d.ts","sourceRoot":"","sources":["../../../src/molecules/quantity-field.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,EAAS,MAAM,OAAO,CAAA;AAEvD,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AA2B7E,KAAK,yBAAyB,GAC1B;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9C,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,iBAAiB,EACf,UAAU,GACV,OAAO,GACP,cAAc,GACd,UAAU,GACV,KAAK,GACL,SAAS,GACT,eAAe,GACf,kBAAkB,GAClB,WAAW,GACX,KAAK,CACR,GACC,yBAAyB,GAAG;IAC1B,KAAK,EAAE,SAAS,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,WAAW,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAA;IAC9D,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAA;CAC5B,CAAA;AAWH,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,KAAK,EACL,SAAS,EACT,KAAK,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,KAAK,EACL,SAAiB,EACjB,OAAe,EACf,YAAY,EACZ,QAAgB,EAChB,QAAgB,EAChB,QAAQ,EACR,WAAW,EACX,kBAAkB,EAAE,eAAe,EACnC,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,SAAS,EACT,IAAW,EACX,aAAa,EACb,GAAG,EACH,SAAS,EACT,GAAG,KAAK,EACT,EAAE,kBAAkB,2CAkHpB"}
|
|
@@ -20,4 +20,8 @@ export declare const WithPrecision: Story;
|
|
|
20
20
|
export declare const CustomLayoutHorizontal: Story;
|
|
21
21
|
export declare const Disabled: Story;
|
|
22
22
|
export declare const CustomButtonProps: Story;
|
|
23
|
+
export declare const ControlledDraft: Story;
|
|
24
|
+
export declare const CallbackCompatibility: Story;
|
|
25
|
+
export declare const UncontrolledDefaults: Story;
|
|
26
|
+
export declare const ExplicitUndefinedDefaults: Story;
|
|
23
27
|
//# sourceMappingURL=numeric-input.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numeric-input.stories.d.ts","sourceRoot":"","sources":["../../../stories/atoms/numeric-input.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"numeric-input.stories.d.ts","sourceRoot":"","sources":["../../../stories/atoms/numeric-input.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAMtD,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AAQpF,KAAK,cAAc,GAAG,iBAAiB,GAAG;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CAanC,CAAA;AAED,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAA;AAErC,eAAO,MAAM,UAAU,EAAE,KAyExB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAyBvB,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAmDtB,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KA4B7B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAgC1B,CAAA;AAED,eAAO,MAAM,MAAM,EAAE,KAgCpB,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAkC1B,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,KAgC3B,CAAA;AAED,eAAO,MAAM,sBAAsB,EAAE,KAyBpC,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAiBtB,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,KA+C/B,CAAA;AAGD,eAAO,MAAM,eAAe,EAAE,KAuC7B,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,KA0EnC,CAAA;AAED,eAAO,MAAM,oBAAoB,EAAE,KA0ClC,CAAA;AAGD,eAAO,MAAM,yBAAyB,EAAE,KA6BvC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changelog.stories.d.ts","sourceRoot":"","sources":["../../../stories/changelog/changelog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"changelog.stories.d.ts","sourceRoot":"","sources":["../../../stories/changelog/changelog.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AA4StD,iBAAS,SAAS,4CAUjB;AAED,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,SAAS,CAKhC,CAAA;AAED,eAAe,IAAI,CAAA;AAEnB,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,OAAO,SAAS,CAAM,CAAA"}
|
|
@@ -14,4 +14,5 @@ export declare const WithScrubber: Story;
|
|
|
14
14
|
export declare const AllSizes: Story;
|
|
15
15
|
export declare const WithPrecision: Story;
|
|
16
16
|
export declare const ComplexDemo: Story;
|
|
17
|
+
export declare const ControlledDraft: Story;
|
|
17
18
|
//# sourceMappingURL=form-numeric-input.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-numeric-input.stories.d.ts","sourceRoot":"","sources":["../../../stories/molecules/form-numeric-input.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"form-numeric-input.stories.d.ts","sourceRoot":"","sources":["../../../stories/molecules/form-numeric-input.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAKtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAEzE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CA6HvC,CAAA;AAED,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAG9C,eAAO,MAAM,UAAU,EAAE,KAmBxB,CAAA;AAGD,eAAO,MAAM,SAAS,EAAE,KA6BvB,CAAA;AAGD,eAAO,MAAM,gBAAgB,EAAE,KA8F9B,CAAA;AAGD,eAAO,MAAM,QAAQ,EAAE,KA2BtB,CAAA;AAGD,eAAO,MAAM,QAAQ,EAAE,KAsBtB,CAAA;AAGD,eAAO,MAAM,gBAAgB,EAAE,KAgC9B,CAAA;AAGD,eAAO,MAAM,eAAe,EAAE,KAuB7B,CAAA;AAGD,eAAO,MAAM,YAAY,EAAE,KA4B1B,CAAA;AAGD,eAAO,MAAM,QAAQ,EAAE,KAsEtB,CAAA;AAGD,eAAO,MAAM,aAAa,EAAE,KA4B3B,CAAA;AAGD,eAAO,MAAM,WAAW,EAAE,KAuDzB,CAAA;AAOD,eAAO,MAAM,eAAe,EAAE,KAiE7B,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { QuantityField } from "../../src/molecules/quantity-field.js";
|
|
3
|
+
declare const meta: Meta<typeof QuantityField>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof QuantityField>;
|
|
6
|
+
export declare const Playground: Story;
|
|
7
|
+
export declare const Sizes: Story;
|
|
8
|
+
export declare const States: Story;
|
|
9
|
+
export declare const RejectedUpdate: Story;
|
|
10
|
+
export declare const DecimalQuantity: Story;
|
|
11
|
+
export declare const Bounds: Story;
|
|
12
|
+
export declare const CompactLongUnit: Story;
|
|
13
|
+
export declare const PendingAndReadOnly: Story;
|
|
14
|
+
export declare const InputAttributes: Story;
|
|
15
|
+
export declare const FormIdentity: Story;
|
|
16
|
+
//# sourceMappingURL=quantity-field.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantity-field.stories.d.ts","sourceRoot":"","sources":["../../../stories/molecules/quantity-field.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAKtD,OAAO,EACN,aAAa,EAEb,MAAM,oCAAoC,CAAA;AAI3C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CA+CpC,CAAA;AACD,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,aAAa,CAAC,CAAA;AAgB3C,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAA;AAED,eAAO,MAAM,KAAK,EAAE,KAYnB,CAAA;AAED,eAAO,MAAM,MAAM,EAAE,KA2BpB,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAiD5B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KAe7B,CAAA;AAED,eAAO,MAAM,MAAM,EAAE,KAiBpB,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KAmB7B,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,KAuDhC,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KA0B7B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAgD1B,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numeric-input.spec.d.ts","sourceRoot":"","sources":["../../test/numeric-input.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantity-field.spec.d.ts","sourceRoot":"","sources":["../../test/quantity-field.spec.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
@import "./molecules/_pagination.css";
|
|
35
35
|
@import "./molecules/_popover.css";
|
|
36
36
|
@import "./molecules/_price-block.css";
|
|
37
|
+
@import "./molecules/_quantity-field.css";
|
|
37
38
|
@import "./molecules/_radio-card.css";
|
|
38
39
|
@import "./molecules/_radio-group.css";
|
|
39
40
|
@import "./molecules/_menu.css";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
@theme static {
|
|
2
|
+
/* Reference layer */
|
|
3
|
+
--color-quantity-field-unit: var(--color-fg-primary);
|
|
4
|
+
--color-quantity-field-message: var(--color-fg-primary);
|
|
5
|
+
|
|
6
|
+
/* Derived foreground */
|
|
7
|
+
--color-quantity-field-unit-fg: var(--color-quantity-field-unit);
|
|
8
|
+
--color-quantity-field-message-fg: var(--color-quantity-field-message);
|
|
9
|
+
|
|
10
|
+
/* Layout and typography follow the existing form controls. */
|
|
11
|
+
--gap-quantity-field: var(--spacing-form-field);
|
|
12
|
+
--gap-quantity-field-control: var(--spacing-150);
|
|
13
|
+
--spacing-quantity-field-control-min-width: var(--spacing-950);
|
|
14
|
+
--text-quantity-field-unit-sm: var(--text-sm);
|
|
15
|
+
--text-quantity-field-unit-md: var(--text-md);
|
|
16
|
+
--text-quantity-field-unit-lg: var(--text-lg);
|
|
17
|
+
}
|