@simpleapps-com/augur-web 1.0.4 → 1.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.
@@ -0,0 +1,168 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }"use client";
2
+ "use client";
3
+
4
+ // src/quantity-input.tsx
5
+ var _react = require('react'); var React = _interopRequireWildcard(_react);
6
+ var _web = require('@simpleapps-com/augur-utils/web');
7
+ var _lu = require('react-icons/lu');
8
+ var _jsxruntime = require('react/jsx-runtime');
9
+ function roundToStep(value, step) {
10
+ if (step <= 1) return value;
11
+ return Math.ceil(value / step) * step;
12
+ }
13
+ var QuantityInput = React.memo(
14
+ React.forwardRef(
15
+ ({
16
+ value,
17
+ onChange,
18
+ min = 0,
19
+ max,
20
+ step = 1,
21
+ decimals = 0,
22
+ showStepper = true,
23
+ disabled = false,
24
+ className,
25
+ inputClassName,
26
+ buttonClassName
27
+ }, ref) => {
28
+ const [qtyStr, setQtyStr] = React.useState(
29
+ () => value.toFixed(decimals)
30
+ );
31
+ React.useEffect(() => {
32
+ setQtyStr(value.toFixed(decimals));
33
+ }, [value, decimals]);
34
+ const commit = React.useCallback(
35
+ (raw) => {
36
+ if (raw.trim() === "") {
37
+ setQtyStr(min.toFixed(decimals));
38
+ onChange(min);
39
+ return;
40
+ }
41
+ let parsed = parseFloat(raw);
42
+ if (isNaN(parsed)) parsed = min;
43
+ parsed = roundToStep(parsed, step);
44
+ if (parsed < min) parsed = min;
45
+ if (max !== void 0 && parsed > max) parsed = max;
46
+ const rounded = parseFloat(parsed.toFixed(decimals));
47
+ setQtyStr(rounded.toFixed(decimals));
48
+ onChange(rounded);
49
+ },
50
+ [min, max, step, decimals, onChange]
51
+ );
52
+ const handleKeyDown = React.useCallback(
53
+ (e) => {
54
+ const allowed = [
55
+ "Backspace",
56
+ "Delete",
57
+ "ArrowLeft",
58
+ "ArrowRight",
59
+ "Tab",
60
+ "Enter"
61
+ ];
62
+ if (allowed.includes(e.key)) {
63
+ if (e.key === "Enter") {
64
+ commit(qtyStr);
65
+ }
66
+ return;
67
+ }
68
+ if (decimals > 0 && e.key === "." && !qtyStr.includes(".")) {
69
+ return;
70
+ }
71
+ if (e.key >= "0" && e.key <= "9") {
72
+ return;
73
+ }
74
+ e.preventDefault();
75
+ },
76
+ [decimals, qtyStr, commit]
77
+ );
78
+ const handleChange = React.useCallback(
79
+ (e) => {
80
+ const pattern = decimals > 0 ? /[^0-9.]/g : /[^0-9]/g;
81
+ let cleaned = e.target.value.replace(pattern, "");
82
+ if (decimals > 0) {
83
+ const parts = cleaned.split(".");
84
+ if (parts.length > 2) {
85
+ cleaned = parts[0] + "." + parts.slice(1).join("");
86
+ }
87
+ }
88
+ setQtyStr(cleaned);
89
+ },
90
+ [decimals]
91
+ );
92
+ const handleBlur = React.useCallback(() => {
93
+ commit(qtyStr);
94
+ }, [commit, qtyStr]);
95
+ const handleDecrement = React.useCallback(() => {
96
+ const next = Math.max(value - step, min);
97
+ onChange(next);
98
+ }, [value, step, min, onChange]);
99
+ const handleIncrement = React.useCallback(() => {
100
+ const next = value + step;
101
+ onChange(max !== void 0 ? Math.min(next, max) : next);
102
+ }, [value, step, max, onChange]);
103
+ const minDisabled = disabled || value <= min;
104
+ const maxDisabled = disabled || max !== void 0 && value >= max;
105
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
106
+ "div",
107
+ {
108
+ className: _web.cn.call(void 0,
109
+ "inline-flex items-center border rounded-md bg-background",
110
+ className
111
+ ),
112
+ children: [
113
+ showStepper && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
114
+ "button",
115
+ {
116
+ type: "button",
117
+ "aria-label": "Decrease quantity",
118
+ disabled: minDisabled,
119
+ onClick: handleDecrement,
120
+ className: _web.cn.call(void 0,
121
+ "h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50",
122
+ buttonClassName
123
+ ),
124
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lu.LuMinus, {})
125
+ }
126
+ ),
127
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
128
+ "input",
129
+ {
130
+ ref,
131
+ type: "text",
132
+ inputMode: decimals > 0 ? "decimal" : "numeric",
133
+ value: qtyStr,
134
+ disabled,
135
+ onKeyDown: handleKeyDown,
136
+ onChange: handleChange,
137
+ onBlur: handleBlur,
138
+ className: _web.cn.call(void 0,
139
+ "h-10 w-16 text-center bg-transparent focus:outline-none",
140
+ inputClassName
141
+ )
142
+ }
143
+ ),
144
+ showStepper && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
145
+ "button",
146
+ {
147
+ type: "button",
148
+ "aria-label": "Increase quantity",
149
+ disabled: maxDisabled,
150
+ onClick: handleIncrement,
151
+ className: _web.cn.call(void 0,
152
+ "h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50",
153
+ buttonClassName
154
+ ),
155
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lu.LuPlus, {})
156
+ }
157
+ )
158
+ ]
159
+ }
160
+ );
161
+ }
162
+ )
163
+ );
164
+ QuantityInput.displayName = "QuantityInput";
165
+
166
+
167
+ exports.QuantityInput = QuantityInput;
168
+ //# sourceMappingURL=quantity-input.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/quantity-input.cjs","../src/quantity-input.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/quantity-input.cjs","sourcesContent":[null,"\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { LuMinus, LuPlus } from \"react-icons/lu\";\n\nexport interface QuantityInputProps {\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n decimals?: number;\n showStepper?: boolean;\n disabled?: boolean;\n className?: string;\n inputClassName?: string;\n buttonClassName?: string;\n}\n\nfunction roundToStep(value: number, step: number): number {\n if (step <= 1) return value;\n return Math.ceil(value / step) * step;\n}\n\nconst QuantityInput = React.memo(\n React.forwardRef<HTMLInputElement, QuantityInputProps>(\n (\n {\n value,\n onChange,\n min = 0,\n max,\n step = 1,\n decimals = 0,\n showStepper = true,\n disabled = false,\n className,\n inputClassName,\n buttonClassName,\n },\n ref,\n ) => {\n const [qtyStr, setQtyStr] = React.useState(() =>\n value.toFixed(decimals),\n );\n\n React.useEffect(() => {\n setQtyStr(value.toFixed(decimals));\n }, [value, decimals]);\n\n const commit = React.useCallback(\n (raw: string) => {\n if (raw.trim() === \"\") {\n setQtyStr(min.toFixed(decimals));\n onChange(min);\n return;\n }\n\n let parsed = parseFloat(raw);\n if (isNaN(parsed)) parsed = min;\n\n parsed = roundToStep(parsed, step);\n if (parsed < min) parsed = min;\n if (max !== undefined && parsed > max) parsed = max;\n\n const rounded = parseFloat(parsed.toFixed(decimals));\n setQtyStr(rounded.toFixed(decimals));\n onChange(rounded);\n },\n [min, max, step, decimals, onChange],\n );\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n const allowed = [\n \"Backspace\",\n \"Delete\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Tab\",\n \"Enter\",\n ];\n if (allowed.includes(e.key)) {\n if (e.key === \"Enter\") {\n commit(qtyStr);\n }\n return;\n }\n\n if (decimals > 0 && e.key === \".\" && !qtyStr.includes(\".\")) {\n return;\n }\n\n if (e.key >= \"0\" && e.key <= \"9\") {\n return;\n }\n\n e.preventDefault();\n },\n [decimals, qtyStr, commit],\n );\n\n const handleChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const pattern = decimals > 0 ? /[^0-9.]/g : /[^0-9]/g;\n let cleaned = e.target.value.replace(pattern, \"\");\n if (decimals > 0) {\n const parts = cleaned.split(\".\");\n if (parts.length > 2) {\n cleaned = parts[0] + \".\" + parts.slice(1).join(\"\");\n }\n }\n setQtyStr(cleaned);\n },\n [decimals],\n );\n\n const handleBlur = React.useCallback(() => {\n commit(qtyStr);\n }, [commit, qtyStr]);\n\n const handleDecrement = React.useCallback(() => {\n const next = Math.max(value - step, min);\n onChange(next);\n }, [value, step, min, onChange]);\n\n const handleIncrement = React.useCallback(() => {\n const next = value + step;\n onChange(max !== undefined ? Math.min(next, max) : next);\n }, [value, step, max, onChange]);\n\n const minDisabled = disabled || value <= min;\n const maxDisabled = disabled || (max !== undefined && value >= max);\n\n return (\n <div\n className={cn(\n \"inline-flex items-center border rounded-md bg-background\",\n className,\n )}\n >\n {showStepper && (\n <button\n type=\"button\"\n aria-label=\"Decrease quantity\"\n disabled={minDisabled}\n onClick={handleDecrement}\n className={cn(\n \"h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50\",\n buttonClassName,\n )}\n >\n <LuMinus />\n </button>\n )}\n <input\n ref={ref}\n type=\"text\"\n inputMode={decimals > 0 ? \"decimal\" : \"numeric\"}\n value={qtyStr}\n disabled={disabled}\n onKeyDown={handleKeyDown}\n onChange={handleChange}\n onBlur={handleBlur}\n className={cn(\n \"h-10 w-16 text-center bg-transparent focus:outline-none\",\n inputClassName,\n )}\n />\n {showStepper && (\n <button\n type=\"button\"\n aria-label=\"Increase quantity\"\n disabled={maxDisabled}\n onClick={handleIncrement}\n className={cn(\n \"h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50\",\n buttonClassName,\n )}\n >\n <LuPlus />\n </button>\n )}\n </div>\n );\n },\n ),\n);\nQuantityInput.displayName = \"QuantityInput\";\n\nexport { QuantityInput };\n"]}
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+
3
+ interface QuantityInputProps {
4
+ value: number;
5
+ onChange: (value: number) => void;
6
+ min?: number;
7
+ max?: number;
8
+ step?: number;
9
+ decimals?: number;
10
+ showStepper?: boolean;
11
+ disabled?: boolean;
12
+ className?: string;
13
+ inputClassName?: string;
14
+ buttonClassName?: string;
15
+ }
16
+ declare const QuantityInput: React.NamedExoticComponent<QuantityInputProps & React.RefAttributes<HTMLInputElement>>;
17
+
18
+ export { QuantityInput, type QuantityInputProps };
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+
3
+ interface QuantityInputProps {
4
+ value: number;
5
+ onChange: (value: number) => void;
6
+ min?: number;
7
+ max?: number;
8
+ step?: number;
9
+ decimals?: number;
10
+ showStepper?: boolean;
11
+ disabled?: boolean;
12
+ className?: string;
13
+ inputClassName?: string;
14
+ buttonClassName?: string;
15
+ }
16
+ declare const QuantityInput: React.NamedExoticComponent<QuantityInputProps & React.RefAttributes<HTMLInputElement>>;
17
+
18
+ export { QuantityInput, type QuantityInputProps };
@@ -0,0 +1,168 @@
1
+ "use client";
2
+ "use client";
3
+
4
+ // src/quantity-input.tsx
5
+ import * as React from "react";
6
+ import { cn } from "@simpleapps-com/augur-utils/web";
7
+ import { LuMinus, LuPlus } from "react-icons/lu";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ function roundToStep(value, step) {
10
+ if (step <= 1) return value;
11
+ return Math.ceil(value / step) * step;
12
+ }
13
+ var QuantityInput = React.memo(
14
+ React.forwardRef(
15
+ ({
16
+ value,
17
+ onChange,
18
+ min = 0,
19
+ max,
20
+ step = 1,
21
+ decimals = 0,
22
+ showStepper = true,
23
+ disabled = false,
24
+ className,
25
+ inputClassName,
26
+ buttonClassName
27
+ }, ref) => {
28
+ const [qtyStr, setQtyStr] = React.useState(
29
+ () => value.toFixed(decimals)
30
+ );
31
+ React.useEffect(() => {
32
+ setQtyStr(value.toFixed(decimals));
33
+ }, [value, decimals]);
34
+ const commit = React.useCallback(
35
+ (raw) => {
36
+ if (raw.trim() === "") {
37
+ setQtyStr(min.toFixed(decimals));
38
+ onChange(min);
39
+ return;
40
+ }
41
+ let parsed = parseFloat(raw);
42
+ if (isNaN(parsed)) parsed = min;
43
+ parsed = roundToStep(parsed, step);
44
+ if (parsed < min) parsed = min;
45
+ if (max !== void 0 && parsed > max) parsed = max;
46
+ const rounded = parseFloat(parsed.toFixed(decimals));
47
+ setQtyStr(rounded.toFixed(decimals));
48
+ onChange(rounded);
49
+ },
50
+ [min, max, step, decimals, onChange]
51
+ );
52
+ const handleKeyDown = React.useCallback(
53
+ (e) => {
54
+ const allowed = [
55
+ "Backspace",
56
+ "Delete",
57
+ "ArrowLeft",
58
+ "ArrowRight",
59
+ "Tab",
60
+ "Enter"
61
+ ];
62
+ if (allowed.includes(e.key)) {
63
+ if (e.key === "Enter") {
64
+ commit(qtyStr);
65
+ }
66
+ return;
67
+ }
68
+ if (decimals > 0 && e.key === "." && !qtyStr.includes(".")) {
69
+ return;
70
+ }
71
+ if (e.key >= "0" && e.key <= "9") {
72
+ return;
73
+ }
74
+ e.preventDefault();
75
+ },
76
+ [decimals, qtyStr, commit]
77
+ );
78
+ const handleChange = React.useCallback(
79
+ (e) => {
80
+ const pattern = decimals > 0 ? /[^0-9.]/g : /[^0-9]/g;
81
+ let cleaned = e.target.value.replace(pattern, "");
82
+ if (decimals > 0) {
83
+ const parts = cleaned.split(".");
84
+ if (parts.length > 2) {
85
+ cleaned = parts[0] + "." + parts.slice(1).join("");
86
+ }
87
+ }
88
+ setQtyStr(cleaned);
89
+ },
90
+ [decimals]
91
+ );
92
+ const handleBlur = React.useCallback(() => {
93
+ commit(qtyStr);
94
+ }, [commit, qtyStr]);
95
+ const handleDecrement = React.useCallback(() => {
96
+ const next = Math.max(value - step, min);
97
+ onChange(next);
98
+ }, [value, step, min, onChange]);
99
+ const handleIncrement = React.useCallback(() => {
100
+ const next = value + step;
101
+ onChange(max !== void 0 ? Math.min(next, max) : next);
102
+ }, [value, step, max, onChange]);
103
+ const minDisabled = disabled || value <= min;
104
+ const maxDisabled = disabled || max !== void 0 && value >= max;
105
+ return /* @__PURE__ */ jsxs(
106
+ "div",
107
+ {
108
+ className: cn(
109
+ "inline-flex items-center border rounded-md bg-background",
110
+ className
111
+ ),
112
+ children: [
113
+ showStepper && /* @__PURE__ */ jsx(
114
+ "button",
115
+ {
116
+ type: "button",
117
+ "aria-label": "Decrease quantity",
118
+ disabled: minDisabled,
119
+ onClick: handleDecrement,
120
+ className: cn(
121
+ "h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50",
122
+ buttonClassName
123
+ ),
124
+ children: /* @__PURE__ */ jsx(LuMinus, {})
125
+ }
126
+ ),
127
+ /* @__PURE__ */ jsx(
128
+ "input",
129
+ {
130
+ ref,
131
+ type: "text",
132
+ inputMode: decimals > 0 ? "decimal" : "numeric",
133
+ value: qtyStr,
134
+ disabled,
135
+ onKeyDown: handleKeyDown,
136
+ onChange: handleChange,
137
+ onBlur: handleBlur,
138
+ className: cn(
139
+ "h-10 w-16 text-center bg-transparent focus:outline-none",
140
+ inputClassName
141
+ )
142
+ }
143
+ ),
144
+ showStepper && /* @__PURE__ */ jsx(
145
+ "button",
146
+ {
147
+ type: "button",
148
+ "aria-label": "Increase quantity",
149
+ disabled: maxDisabled,
150
+ onClick: handleIncrement,
151
+ className: cn(
152
+ "h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50",
153
+ buttonClassName
154
+ ),
155
+ children: /* @__PURE__ */ jsx(LuPlus, {})
156
+ }
157
+ )
158
+ ]
159
+ }
160
+ );
161
+ }
162
+ )
163
+ );
164
+ QuantityInput.displayName = "QuantityInput";
165
+ export {
166
+ QuantityInput
167
+ };
168
+ //# sourceMappingURL=quantity-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/quantity-input.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { LuMinus, LuPlus } from \"react-icons/lu\";\n\nexport interface QuantityInputProps {\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n decimals?: number;\n showStepper?: boolean;\n disabled?: boolean;\n className?: string;\n inputClassName?: string;\n buttonClassName?: string;\n}\n\nfunction roundToStep(value: number, step: number): number {\n if (step <= 1) return value;\n return Math.ceil(value / step) * step;\n}\n\nconst QuantityInput = React.memo(\n React.forwardRef<HTMLInputElement, QuantityInputProps>(\n (\n {\n value,\n onChange,\n min = 0,\n max,\n step = 1,\n decimals = 0,\n showStepper = true,\n disabled = false,\n className,\n inputClassName,\n buttonClassName,\n },\n ref,\n ) => {\n const [qtyStr, setQtyStr] = React.useState(() =>\n value.toFixed(decimals),\n );\n\n React.useEffect(() => {\n setQtyStr(value.toFixed(decimals));\n }, [value, decimals]);\n\n const commit = React.useCallback(\n (raw: string) => {\n if (raw.trim() === \"\") {\n setQtyStr(min.toFixed(decimals));\n onChange(min);\n return;\n }\n\n let parsed = parseFloat(raw);\n if (isNaN(parsed)) parsed = min;\n\n parsed = roundToStep(parsed, step);\n if (parsed < min) parsed = min;\n if (max !== undefined && parsed > max) parsed = max;\n\n const rounded = parseFloat(parsed.toFixed(decimals));\n setQtyStr(rounded.toFixed(decimals));\n onChange(rounded);\n },\n [min, max, step, decimals, onChange],\n );\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n const allowed = [\n \"Backspace\",\n \"Delete\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Tab\",\n \"Enter\",\n ];\n if (allowed.includes(e.key)) {\n if (e.key === \"Enter\") {\n commit(qtyStr);\n }\n return;\n }\n\n if (decimals > 0 && e.key === \".\" && !qtyStr.includes(\".\")) {\n return;\n }\n\n if (e.key >= \"0\" && e.key <= \"9\") {\n return;\n }\n\n e.preventDefault();\n },\n [decimals, qtyStr, commit],\n );\n\n const handleChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const pattern = decimals > 0 ? /[^0-9.]/g : /[^0-9]/g;\n let cleaned = e.target.value.replace(pattern, \"\");\n if (decimals > 0) {\n const parts = cleaned.split(\".\");\n if (parts.length > 2) {\n cleaned = parts[0] + \".\" + parts.slice(1).join(\"\");\n }\n }\n setQtyStr(cleaned);\n },\n [decimals],\n );\n\n const handleBlur = React.useCallback(() => {\n commit(qtyStr);\n }, [commit, qtyStr]);\n\n const handleDecrement = React.useCallback(() => {\n const next = Math.max(value - step, min);\n onChange(next);\n }, [value, step, min, onChange]);\n\n const handleIncrement = React.useCallback(() => {\n const next = value + step;\n onChange(max !== undefined ? Math.min(next, max) : next);\n }, [value, step, max, onChange]);\n\n const minDisabled = disabled || value <= min;\n const maxDisabled = disabled || (max !== undefined && value >= max);\n\n return (\n <div\n className={cn(\n \"inline-flex items-center border rounded-md bg-background\",\n className,\n )}\n >\n {showStepper && (\n <button\n type=\"button\"\n aria-label=\"Decrease quantity\"\n disabled={minDisabled}\n onClick={handleDecrement}\n className={cn(\n \"h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50\",\n buttonClassName,\n )}\n >\n <LuMinus />\n </button>\n )}\n <input\n ref={ref}\n type=\"text\"\n inputMode={decimals > 0 ? \"decimal\" : \"numeric\"}\n value={qtyStr}\n disabled={disabled}\n onKeyDown={handleKeyDown}\n onChange={handleChange}\n onBlur={handleBlur}\n className={cn(\n \"h-10 w-16 text-center bg-transparent focus:outline-none\",\n inputClassName,\n )}\n />\n {showStepper && (\n <button\n type=\"button\"\n aria-label=\"Increase quantity\"\n disabled={maxDisabled}\n onClick={handleIncrement}\n className={cn(\n \"h-10 w-10 flex items-center justify-center hover:bg-accent disabled:opacity-50\",\n buttonClassName,\n )}\n >\n <LuPlus />\n </button>\n )}\n </div>\n );\n },\n ),\n);\nQuantityInput.displayName = \"QuantityInput\";\n\nexport { QuantityInput };\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simpleapps-com/augur-web",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Shared React UI components for Augur ecommerce sites (Radix + Tailwind)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -170,6 +170,11 @@
170
170
  "import": "./dist/mdx-components.js",
171
171
  "require": "./dist/mdx-components.cjs"
172
172
  },
173
+ "./quantity-input": {
174
+ "types": "./dist/quantity-input.d.ts",
175
+ "import": "./dist/quantity-input.js",
176
+ "require": "./dist/quantity-input.cjs"
177
+ },
173
178
  "./session-replay": {
174
179
  "types": "./dist/session-replay.d.ts",
175
180
  "import": "./dist/session-replay.js",
@@ -181,7 +186,7 @@
181
186
  "dist"
182
187
  ],
183
188
  "dependencies": {
184
- "@simpleapps-com/augur-utils": "1.0.4"
189
+ "@simpleapps-com/augur-utils": "1.0.6"
185
190
  },
186
191
  "peerDependencies": {
187
192
  "@radix-ui/react-accordion": "^1.2.0",