@simpleapps-com/augur-web 2026.11.2 → 2026.11.3

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 (167) hide show
  1. package/EXPORTS.md +1 -1
  2. package/README.md +7 -2
  3. package/dist/add-to-cart-button.cjs +3 -2
  4. package/dist/add-to-cart-button.cjs.map +1 -1
  5. package/dist/add-to-cart-button.js +2 -1
  6. package/dist/add-to-cart-button.js.map +1 -1
  7. package/dist/bin-scan.d.ts +23 -0
  8. package/dist/bin-scan.d.ts.map +1 -0
  9. package/dist/button.d.ts +1 -1
  10. package/dist/{chunk-32XB3REY.cjs → chunk-6SSR5Z6X.cjs} +8 -5
  11. package/dist/chunk-6SSR5Z6X.cjs.map +1 -0
  12. package/dist/{chunk-RCUKSVMF.js → chunk-6USFUHWW.js} +9 -14
  13. package/dist/chunk-6USFUHWW.js.map +1 -0
  14. package/dist/{chunk-WJUDOEVB.cjs → chunk-7RDA26CL.cjs} +7 -7
  15. package/dist/{chunk-WJUDOEVB.cjs.map → chunk-7RDA26CL.cjs.map} +1 -1
  16. package/dist/{chunk-UMNTUD2P.js → chunk-AC3OCGDU.js} +6 -8
  17. package/dist/chunk-AC3OCGDU.js.map +1 -0
  18. package/dist/{chunk-MOC5N2N4.js → chunk-BSRLAXZ2.js} +9 -6
  19. package/dist/chunk-BSRLAXZ2.js.map +1 -0
  20. package/dist/{chunk-UB7HYAAC.js → chunk-EBCKH6JE.js} +6 -3
  21. package/dist/chunk-EBCKH6JE.js.map +1 -0
  22. package/dist/{chunk-WFMP6TZN.js → chunk-I6LMIYVF.js} +3 -3
  23. package/dist/{chunk-RGJT67PN.js → chunk-IDCDOE2L.js} +6 -3
  24. package/dist/chunk-IDCDOE2L.js.map +1 -0
  25. package/dist/{chunk-MXSQYVCK.js → chunk-IXQFZJSN.js} +7 -3
  26. package/dist/chunk-IXQFZJSN.js.map +1 -0
  27. package/dist/{chunk-76RSVRGB.cjs → chunk-KVJQIZSM.cjs} +10 -15
  28. package/dist/chunk-KVJQIZSM.cjs.map +1 -0
  29. package/dist/{chunk-TFP5RICB.cjs → chunk-L7JN7ED7.cjs} +37 -37
  30. package/dist/chunk-L7JN7ED7.cjs.map +1 -0
  31. package/dist/{chunk-JXW4XE2P.cjs → chunk-N57EZBPE.cjs} +10 -7
  32. package/dist/chunk-N57EZBPE.cjs.map +1 -0
  33. package/dist/chunk-NBXA42AW.cjs +534 -0
  34. package/dist/chunk-NBXA42AW.cjs.map +1 -0
  35. package/dist/chunk-NSMOT7GD.js +534 -0
  36. package/dist/chunk-NSMOT7GD.js.map +1 -0
  37. package/dist/{chunk-BXMTQGKV.cjs → chunk-OJS2B6U2.cjs} +7 -3
  38. package/dist/chunk-OJS2B6U2.cjs.map +1 -0
  39. package/dist/{chunk-5VMEEKZ5.cjs → chunk-SJGSBMMN.cjs} +7 -9
  40. package/dist/chunk-SJGSBMMN.cjs.map +1 -0
  41. package/dist/{chunk-C6K7FZNX.js → chunk-TEDFINZP.js} +2 -2
  42. package/dist/{chunk-DMWSWL4B.cjs → chunk-VCFKYOVH.cjs} +3 -3
  43. package/dist/{chunk-DMWSWL4B.cjs.map → chunk-VCFKYOVH.cjs.map} +1 -1
  44. package/dist/{chunk-Z57QBVUC.cjs → chunk-VXVOYZBN.cjs} +8 -5
  45. package/dist/chunk-VXVOYZBN.cjs.map +1 -0
  46. package/dist/{chunk-KVHOMD4T.js → chunk-YJDVFOVR.js} +40 -40
  47. package/dist/chunk-YJDVFOVR.js.map +1 -0
  48. package/dist/command.cjs +3 -3
  49. package/dist/command.cjs.map +1 -1
  50. package/dist/command.d.ts.map +1 -1
  51. package/dist/command.js +2 -2
  52. package/dist/command.js.map +1 -1
  53. package/dist/confirm-dialog.cjs +3 -2
  54. package/dist/confirm-dialog.cjs.map +1 -1
  55. package/dist/confirm-dialog.js +2 -1
  56. package/dist/confirm-dialog.js.map +1 -1
  57. package/dist/data-table.cjs +65 -46
  58. package/dist/data-table.cjs.map +1 -1
  59. package/dist/data-table.d.ts.map +1 -1
  60. package/dist/data-table.js +59 -40
  61. package/dist/data-table.js.map +1 -1
  62. package/dist/detail-panel.cjs +71 -63
  63. package/dist/detail-panel.cjs.map +1 -1
  64. package/dist/detail-panel.d.ts.map +1 -1
  65. package/dist/detail-panel.js +70 -62
  66. package/dist/detail-panel.js.map +1 -1
  67. package/dist/dropdown-menu.cjs +3 -2
  68. package/dist/dropdown-menu.cjs.map +1 -1
  69. package/dist/dropdown-menu.d.ts.map +1 -1
  70. package/dist/dropdown-menu.js +2 -1
  71. package/dist/financing-widget.cjs +4 -1
  72. package/dist/financing-widget.cjs.map +1 -1
  73. package/dist/financing-widget.d.ts.map +1 -1
  74. package/dist/financing-widget.js +4 -1
  75. package/dist/financing-widget.js.map +1 -1
  76. package/dist/form-field.cjs +3 -2
  77. package/dist/form-field.cjs.map +1 -1
  78. package/dist/form-field.d.ts.map +1 -1
  79. package/dist/form-field.js +2 -1
  80. package/dist/form-input.cjs +4 -3
  81. package/dist/form-input.cjs.map +1 -1
  82. package/dist/form-input.d.ts.map +1 -1
  83. package/dist/form-input.js +3 -2
  84. package/dist/form-select.cjs +5 -4
  85. package/dist/form-select.cjs.map +1 -1
  86. package/dist/form-select.js +4 -3
  87. package/dist/form-textarea.cjs +4 -3
  88. package/dist/form-textarea.cjs.map +1 -1
  89. package/dist/form-textarea.d.ts.map +1 -1
  90. package/dist/form-textarea.js +3 -2
  91. package/dist/gtm.cjs +3 -3
  92. package/dist/gtm.js +2 -2
  93. package/dist/pagination.cjs +3 -3
  94. package/dist/pagination.d.ts +1 -1
  95. package/dist/pagination.d.ts.map +1 -1
  96. package/dist/pagination.js +2 -2
  97. package/dist/payment-modal.cjs +52 -34
  98. package/dist/payment-modal.cjs.map +1 -1
  99. package/dist/payment-modal.d.ts +4 -4
  100. package/dist/payment-modal.d.ts.map +1 -1
  101. package/dist/payment-modal.js +52 -34
  102. package/dist/payment-modal.js.map +1 -1
  103. package/dist/popover.cjs +4 -4
  104. package/dist/popover.cjs.map +1 -1
  105. package/dist/popover.js +3 -3
  106. package/dist/popover.js.map +1 -1
  107. package/dist/price.cjs +2 -2
  108. package/dist/price.js +1 -1
  109. package/dist/provider.cjs +3 -3
  110. package/dist/provider.js +2 -2
  111. package/dist/quantity-input.cjs +125 -111
  112. package/dist/quantity-input.cjs.map +1 -1
  113. package/dist/quantity-input.d.ts +16 -5
  114. package/dist/quantity-input.d.ts.map +1 -1
  115. package/dist/quantity-input.js +127 -113
  116. package/dist/quantity-input.js.map +1 -1
  117. package/dist/resource-tabs.cjs +10 -5
  118. package/dist/resource-tabs.cjs.map +1 -1
  119. package/dist/resource-tabs.d.ts +1 -1
  120. package/dist/resource-tabs.d.ts.map +1 -1
  121. package/dist/resource-tabs.js +10 -5
  122. package/dist/resource-tabs.js.map +1 -1
  123. package/dist/rules.d.ts +315 -17
  124. package/dist/rules.d.ts.map +1 -1
  125. package/dist/select.cjs +3 -2
  126. package/dist/select.cjs.map +1 -1
  127. package/dist/select.d.ts.map +1 -1
  128. package/dist/select.js +2 -1
  129. package/dist/separator.cjs +8 -9
  130. package/dist/separator.cjs.map +1 -1
  131. package/dist/separator.d.ts.map +1 -1
  132. package/dist/separator.js +7 -8
  133. package/dist/separator.js.map +1 -1
  134. package/dist/session-replay.cjs +2 -2
  135. package/dist/session-replay.js +1 -1
  136. package/dist/spinner.cjs +3 -2
  137. package/dist/spinner.cjs.map +1 -1
  138. package/dist/spinner.d.ts +1 -1
  139. package/dist/spinner.d.ts.map +1 -1
  140. package/dist/spinner.js +2 -1
  141. package/dist/stock-label.cjs +28 -33
  142. package/dist/stock-label.cjs.map +1 -1
  143. package/dist/stock-label.d.ts.map +1 -1
  144. package/dist/stock-label.js +30 -35
  145. package/dist/stock-label.js.map +1 -1
  146. package/llms.txt +3 -2
  147. package/package.json +3 -1
  148. package/dist/chunk-32XB3REY.cjs.map +0 -1
  149. package/dist/chunk-5VMEEKZ5.cjs.map +0 -1
  150. package/dist/chunk-76RSVRGB.cjs.map +0 -1
  151. package/dist/chunk-BXMTQGKV.cjs.map +0 -1
  152. package/dist/chunk-IO77MGHW.js +0 -220
  153. package/dist/chunk-IO77MGHW.js.map +0 -1
  154. package/dist/chunk-JXW4XE2P.cjs.map +0 -1
  155. package/dist/chunk-KVHOMD4T.js.map +0 -1
  156. package/dist/chunk-MOC5N2N4.js.map +0 -1
  157. package/dist/chunk-MXSQYVCK.js.map +0 -1
  158. package/dist/chunk-QKWXJM4Q.cjs +0 -220
  159. package/dist/chunk-QKWXJM4Q.cjs.map +0 -1
  160. package/dist/chunk-RCUKSVMF.js.map +0 -1
  161. package/dist/chunk-RGJT67PN.js.map +0 -1
  162. package/dist/chunk-TFP5RICB.cjs.map +0 -1
  163. package/dist/chunk-UB7HYAAC.js.map +0 -1
  164. package/dist/chunk-UMNTUD2P.js.map +0 -1
  165. package/dist/chunk-Z57QBVUC.cjs.map +0 -1
  166. /package/dist/{chunk-WFMP6TZN.js.map → chunk-I6LMIYVF.js.map} +0 -0
  167. /package/dist/{chunk-C6K7FZNX.js.map → chunk-TEDFINZP.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/quantity-input.cjs","../src/quantity-input.tsx"],"names":[],"mappings":"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","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/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\";\nimport {\n clampQuantity,\n cleanQtyFrom,\n decreaseDisabled,\n increaseDisabled,\n keyAllowed,\n stepDown,\n stepUp,\n} from \"./rules\";\n\nexport interface QuantityInputProps {\n /** Current quantity value (controlled). */\n value: number;\n /** Called with the new quantity after validation and rounding. */\n onChange: (value: number) => void;\n /** Minimum allowed quantity. Default: `0`. */\n min?: number;\n /** Maximum allowed quantity. */\n max?: number;\n /** Increment/decrement step size. Values are rounded up to the nearest step. Default: `1`. */\n step?: number;\n /** Number of decimal places to display. Default: `0`. */\n decimals?: number;\n /** Show +/- stepper buttons. Default: `true`. */\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\n/**\n * The quantity a typed string commits to: `min` when blank, else the number (or `min` when it\n * is not one) rounded up to the step, clamped to [min, max] and to `decimals` places.\n */\nfunction committedQuantity(\n raw: string,\n min: number,\n max: number | undefined,\n step: number,\n decimals: number,\n): number {\n if (raw.trim() === \"\") return min;\n\n let parsed = parseFloat(raw);\n if (isNaN(parsed)) parsed = min;\n\n // roundToStep stays here: Math.ceil over fractional quantities has no lsc form.\n parsed = clampQuantity(roundToStep(parsed, step), min, max);\n\n return parseFloat(parsed.toFixed(decimals));\n}\n\n/**\n * Numeric input with optional +/- stepper buttons for cart quantities.\n *\n * @example\n * ```tsx\n * <QuantityInput value={qty} onChange={setQty} min={1} step={1} />\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(() => value.toFixed(decimals));\n\n React.useEffect(() => {\n setQtyStr(value.toFixed(decimals));\n }, [value, decimals]);\n\n const commit = React.useCallback(\n (raw: string) => {\n const quantity = committedQuantity(raw, min, max, step, decimals);\n setQtyStr(quantity.toFixed(decimals));\n onChange(quantity);\n },\n [min, max, step, decimals, onChange],\n );\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n commit(qtyStr);\n return;\n }\n if (!keyAllowed(e.key, decimals, qtyStr.includes(\".\"))) e.preventDefault();\n },\n [decimals, qtyStr, commit],\n );\n\n const handleChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setQtyStr(cleanQtyFrom(e.target.value, decimals > 0, false, 0));\n },\n [decimals],\n );\n\n const handleBlur = React.useCallback(() => {\n commit(qtyStr);\n }, [commit, qtyStr]);\n\n const handleDecrement = React.useCallback(() => {\n onChange(stepDown(value, step, min));\n }, [value, step, min, onChange]);\n\n const handleIncrement = React.useCallback(() => {\n onChange(stepUp(value, step, max));\n }, [value, step, max, onChange]);\n\n const minDisabled = decreaseDisabled(disabled, value, min);\n const maxDisabled = increaseDisabled(disabled, value, max);\n\n return (\n <div className={cn(\"bg-background inline-flex items-center rounded-md border\", className)}>\n {showStepper && (\n <button\n type=\"button\"\n aria-label=\"Decrease quantity\"\n disabled={minDisabled}\n onClick={handleDecrement}\n className={cn(\n \"hover:bg-accent flex h-10 w-10 items-center justify-center 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 bg-transparent text-center 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 \"hover:bg-accent flex h-10 w-10 items-center justify-center 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"]}
1
+ {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/quantity-input.cjs","../src/quantity-input.tsx"],"names":[],"mappings":"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","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/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 { pow10, signedFixedText } from \"@atlas/utils/fixed\";\nimport { LuMinus, LuPlus } from \"react-icons/lu\";\nimport {\n cleanQtyFrom,\n commitUnits,\n decreaseDisabled,\n increaseDisabled,\n inputModeOf,\n keyActionOf,\n slotsWhen,\n stepDown,\n stepUp,\n} from \"./rules\";\n\n/**\n * The `<input>` attributes the component owns. A site can't pass them: `min`, `max` and `step`\n * are its numeric props, and the rest drive commit on blur and Enter.\n */\ntype OwnInputAttribute =\n | \"value\"\n | \"onChange\"\n | \"type\"\n | \"inputMode\"\n | \"disabled\"\n | \"onKeyDown\"\n | \"onBlur\"\n | \"className\"\n | \"min\"\n | \"max\"\n | \"step\";\n\n/**\n * Every other `<input>` attribute (`id`, `name`, `aria-label`, `aria-labelledby`,\n * `aria-describedby`, `autoComplete`, `data-*`, …) goes onto the field, so a site can name it.\n */\nexport interface QuantityInputProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n OwnInputAttribute\n> {\n /** Current quantity value (controlled). */\n value: number;\n /** Called with the new quantity after validation and rounding. */\n onChange: (value: number) => void;\n /** Minimum allowed quantity, at the field's `decimals`. Default: `0`. */\n min?: number;\n /** Maximum allowed quantity, at the field's `decimals`. */\n max?: number;\n /** Increment/decrement step, at the field's `decimals`. Values round up to it. Default: `1`. */\n step?: number;\n /** Number of decimal places to display. Default: `0`. */\n decimals?: number;\n /** Show +/- stepper buttons. Default: `true`. */\n showStepper?: boolean;\n disabled?: boolean;\n /** Classes for the wrapper. */\n className?: string;\n inputClassName?: string;\n buttonClassName?: string;\n}\n\n/**\n * The field's state and handlers. Every decision is a proved rule (`./rules`, utils `fixed`);\n * this only holds React state, converts the props to integer units of 10^-decimals\n * (`Math.round`) and acts on what the rules return.\n */\nfunction useQuantityInput(props: QuantityInputProps) {\n const {\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 ...rest\n } = props;\n const scale = pow10(decimals);\n const shown = signedFixedText(Math.round(value * scale), decimals);\n const [text, setText] = React.useState(shown);\n\n React.useEffect(() => {\n setText(shown);\n }, [shown]);\n\n const commit = React.useCallback(\n (raw: string) => {\n const units = commitUnits(\n raw,\n Math.round(min * scale),\n max === undefined ? undefined : Math.round(max * scale),\n Math.round(step * scale),\n decimals,\n );\n setText(signedFixedText(units, decimals));\n onChange(units / scale);\n },\n [min, max, step, decimals, scale, onChange],\n );\n\n const onKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n const action = keyActionOf(e.key, decimals, text);\n if (action === \"commit\") commit(text);\n else if (action === \"block\") e.preventDefault();\n },\n [decimals, text, commit],\n );\n\n const onTextChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setText(cleanQtyFrom(e.target.value, decimals > 0, false, 0));\n },\n [decimals],\n );\n\n const onBlur = React.useCallback(() => {\n commit(text);\n }, [commit, text]);\n\n const onDecrease = React.useCallback(() => {\n onChange(stepDown(value, step, min));\n }, [value, step, min, onChange]);\n\n const onIncrease = React.useCallback(() => {\n onChange(stepUp(value, step, max));\n }, [value, step, max, onChange]);\n\n return {\n rest,\n text,\n disabled,\n inputMode: inputModeOf(decimals),\n steppers: slotsWhen(showStepper),\n decreaseOff: decreaseDisabled(disabled, value, min),\n increaseOff: increaseDisabled(disabled, value, max),\n onKeyDown,\n onTextChange,\n onBlur,\n onDecrease,\n onIncrease,\n className: cn(\"bg-background inline-flex items-center rounded-md border\", className),\n inputClassName: cn(\"h-10 w-16 bg-transparent text-center focus:outline-none\", inputClassName),\n buttonClassName: cn(\n \"hover:bg-accent flex h-10 w-10 items-center justify-center disabled:opacity-50\",\n buttonClassName,\n ),\n };\n}\n\n/**\n * Numeric input with optional +/- stepper buttons for cart quantities.\n *\n * @example\n * ```tsx\n * <label htmlFor=\"qty\">Quantity</label>\n * <QuantityInput id=\"qty\" value={qty} onChange={setQty} min={1} step={1} />\n * ```\n */\nconst QuantityInput = React.memo(\n React.forwardRef<HTMLInputElement, QuantityInputProps>((props, ref) => {\n const q = useQuantityInput(props);\n return (\n <div className={q.className}>\n {q.steppers.map((slot) => (\n <button\n key={slot}\n type=\"button\"\n aria-label=\"Decrease quantity\"\n disabled={q.decreaseOff}\n onClick={q.onDecrease}\n className={q.buttonClassName}\n >\n <LuMinus />\n </button>\n ))}\n <input\n {...q.rest}\n ref={ref}\n type=\"text\"\n inputMode={q.inputMode}\n value={q.text}\n disabled={q.disabled}\n onKeyDown={q.onKeyDown}\n onChange={q.onTextChange}\n onBlur={q.onBlur}\n className={q.inputClassName}\n />\n {q.steppers.map((slot) => (\n <button\n key={slot}\n type=\"button\"\n aria-label=\"Increase quantity\"\n disabled={q.increaseOff}\n onClick={q.onIncrease}\n className={q.buttonClassName}\n >\n <LuPlus />\n </button>\n ))}\n </div>\n );\n }),\n);\nQuantityInput.displayName = \"QuantityInput\";\n\nexport { QuantityInput };\n"]}
@@ -1,20 +1,30 @@
1
1
  import * as React from "react";
2
- export interface QuantityInputProps {
2
+ /**
3
+ * The `<input>` attributes the component owns. A site can't pass them: `min`, `max` and `step`
4
+ * are its numeric props, and the rest drive commit on blur and Enter.
5
+ */
6
+ type OwnInputAttribute = "value" | "onChange" | "type" | "inputMode" | "disabled" | "onKeyDown" | "onBlur" | "className" | "min" | "max" | "step";
7
+ /**
8
+ * Every other `<input>` attribute (`id`, `name`, `aria-label`, `aria-labelledby`,
9
+ * `aria-describedby`, `autoComplete`, `data-*`, …) goes onto the field, so a site can name it.
10
+ */
11
+ export interface QuantityInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, OwnInputAttribute> {
3
12
  /** Current quantity value (controlled). */
4
13
  value: number;
5
14
  /** Called with the new quantity after validation and rounding. */
6
15
  onChange: (value: number) => void;
7
- /** Minimum allowed quantity. Default: `0`. */
16
+ /** Minimum allowed quantity, at the field's `decimals`. Default: `0`. */
8
17
  min?: number;
9
- /** Maximum allowed quantity. */
18
+ /** Maximum allowed quantity, at the field's `decimals`. */
10
19
  max?: number;
11
- /** Increment/decrement step size. Values are rounded up to the nearest step. Default: `1`. */
20
+ /** Increment/decrement step, at the field's `decimals`. Values round up to it. Default: `1`. */
12
21
  step?: number;
13
22
  /** Number of decimal places to display. Default: `0`. */
14
23
  decimals?: number;
15
24
  /** Show +/- stepper buttons. Default: `true`. */
16
25
  showStepper?: boolean;
17
26
  disabled?: boolean;
27
+ /** Classes for the wrapper. */
18
28
  className?: string;
19
29
  inputClassName?: string;
20
30
  buttonClassName?: string;
@@ -24,7 +34,8 @@ export interface QuantityInputProps {
24
34
  *
25
35
  * @example
26
36
  * ```tsx
27
- * <QuantityInput value={qty} onChange={setQty} min={1} step={1} />
37
+ * <label htmlFor="qty">Quantity</label>
38
+ * <QuantityInput id="qty" value={qty} onChange={setQty} min={1} step={1} />
28
39
  * ```
29
40
  */
30
41
  declare const QuantityInput: React.NamedExoticComponent<QuantityInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -1 +1 @@
1
- {"version":3,"file":"quantity-input.d.ts","sourceRoot":"","sources":["../src/quantity-input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8FAA8F;IAC9F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA6BD;;;;;;;GAOG;AACH,QAAA,MAAM,aAAa,wFAkHlB,CAAC;AAGF,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"quantity-input.d.ts","sourceRoot":"","sources":["../src/quantity-input.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B;;;GAGG;AACH,KAAK,iBAAiB,GAClB,OAAO,GACP,UAAU,GACV,MAAM,GACN,WAAW,GACX,UAAU,GACV,WAAW,GACX,QAAQ,GACR,WAAW,GACX,KAAK,GACL,KAAK,GACL,MAAM,CAAC;AAEX;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAC9C,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAC3C,iBAAiB,CAClB;IACC,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gGAAgG;IAChG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA+FD;;;;;;;;GAQG;AACH,QAAA,MAAM,aAAa,wFA4ClB,CAAC;AAGF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -1,134 +1,148 @@
1
1
  "use client";
2
2
  "use client";
3
3
  import {
4
- clampQuantity,
5
4
  cleanQtyFrom,
5
+ commitUnits,
6
6
  decreaseDisabled,
7
7
  increaseDisabled,
8
- keyAllowed,
8
+ inputModeOf,
9
+ keyActionOf,
10
+ pow10,
11
+ signedFixedText,
12
+ slotsWhen,
9
13
  stepDown,
10
14
  stepUp
11
- } from "./chunk-IO77MGHW.js";
15
+ } from "./chunk-NSMOT7GD.js";
12
16
 
13
17
  // src/quantity-input.tsx
14
18
  import * as React from "react";
15
19
  import { cn } from "@simpleapps-com/augur-utils/web";
16
20
  import { LuMinus, LuPlus } from "react-icons/lu";
17
21
  import { jsx, jsxs } from "react/jsx-runtime";
18
- function roundToStep(value, step) {
19
- if (step <= 1) return value;
20
- return Math.ceil(value / step) * step;
21
- }
22
- function committedQuantity(raw, min, max, step, decimals) {
23
- if (raw.trim() === "") return min;
24
- let parsed = parseFloat(raw);
25
- if (isNaN(parsed)) parsed = min;
26
- parsed = clampQuantity(roundToStep(parsed, step), min, max);
27
- return parseFloat(parsed.toFixed(decimals));
22
+ function useQuantityInput(props) {
23
+ const {
24
+ value,
25
+ onChange,
26
+ min = 0,
27
+ max,
28
+ step = 1,
29
+ decimals = 0,
30
+ showStepper = true,
31
+ disabled = false,
32
+ className,
33
+ inputClassName,
34
+ buttonClassName,
35
+ ...rest
36
+ } = props;
37
+ const scale = pow10(decimals);
38
+ const shown = signedFixedText(Math.round(value * scale), decimals);
39
+ const [text, setText] = React.useState(shown);
40
+ React.useEffect(() => {
41
+ setText(shown);
42
+ }, [shown]);
43
+ const commit = React.useCallback(
44
+ (raw) => {
45
+ const units = commitUnits(
46
+ raw,
47
+ Math.round(min * scale),
48
+ max === void 0 ? void 0 : Math.round(max * scale),
49
+ Math.round(step * scale),
50
+ decimals
51
+ );
52
+ setText(signedFixedText(units, decimals));
53
+ onChange(units / scale);
54
+ },
55
+ [min, max, step, decimals, scale, onChange]
56
+ );
57
+ const onKeyDown = React.useCallback(
58
+ (e) => {
59
+ const action = keyActionOf(e.key, decimals, text);
60
+ if (action === "commit") commit(text);
61
+ else if (action === "block") e.preventDefault();
62
+ },
63
+ [decimals, text, commit]
64
+ );
65
+ const onTextChange = React.useCallback(
66
+ (e) => {
67
+ setText(cleanQtyFrom(e.target.value, decimals > 0, false, 0));
68
+ },
69
+ [decimals]
70
+ );
71
+ const onBlur = React.useCallback(() => {
72
+ commit(text);
73
+ }, [commit, text]);
74
+ const onDecrease = React.useCallback(() => {
75
+ onChange(stepDown(value, step, min));
76
+ }, [value, step, min, onChange]);
77
+ const onIncrease = React.useCallback(() => {
78
+ onChange(stepUp(value, step, max));
79
+ }, [value, step, max, onChange]);
80
+ return {
81
+ rest,
82
+ text,
83
+ disabled,
84
+ inputMode: inputModeOf(decimals),
85
+ steppers: slotsWhen(showStepper),
86
+ decreaseOff: decreaseDisabled(disabled, value, min),
87
+ increaseOff: increaseDisabled(disabled, value, max),
88
+ onKeyDown,
89
+ onTextChange,
90
+ onBlur,
91
+ onDecrease,
92
+ onIncrease,
93
+ className: cn("bg-background inline-flex items-center rounded-md border", className),
94
+ inputClassName: cn("h-10 w-16 bg-transparent text-center focus:outline-none", inputClassName),
95
+ buttonClassName: cn(
96
+ "hover:bg-accent flex h-10 w-10 items-center justify-center disabled:opacity-50",
97
+ buttonClassName
98
+ )
99
+ };
28
100
  }
29
101
  var QuantityInput = React.memo(
30
- React.forwardRef(
31
- ({
32
- value,
33
- onChange,
34
- min = 0,
35
- max,
36
- step = 1,
37
- decimals = 0,
38
- showStepper = true,
39
- disabled = false,
40
- className,
41
- inputClassName,
42
- buttonClassName
43
- }, ref) => {
44
- const [qtyStr, setQtyStr] = React.useState(() => value.toFixed(decimals));
45
- React.useEffect(() => {
46
- setQtyStr(value.toFixed(decimals));
47
- }, [value, decimals]);
48
- const commit = React.useCallback(
49
- (raw) => {
50
- const quantity = committedQuantity(raw, min, max, step, decimals);
51
- setQtyStr(quantity.toFixed(decimals));
52
- onChange(quantity);
102
+ React.forwardRef((props, ref) => {
103
+ const q = useQuantityInput(props);
104
+ return /* @__PURE__ */ jsxs("div", { className: q.className, children: [
105
+ q.steppers.map((slot) => /* @__PURE__ */ jsx(
106
+ "button",
107
+ {
108
+ type: "button",
109
+ "aria-label": "Decrease quantity",
110
+ disabled: q.decreaseOff,
111
+ onClick: q.onDecrease,
112
+ className: q.buttonClassName,
113
+ children: /* @__PURE__ */ jsx(LuMinus, {})
53
114
  },
54
- [min, max, step, decimals, onChange]
55
- );
56
- const handleKeyDown = React.useCallback(
57
- (e) => {
58
- if (e.key === "Enter") {
59
- commit(qtyStr);
60
- return;
61
- }
62
- if (!keyAllowed(e.key, decimals, qtyStr.includes("."))) e.preventDefault();
63
- },
64
- [decimals, qtyStr, commit]
65
- );
66
- const handleChange = React.useCallback(
67
- (e) => {
68
- setQtyStr(cleanQtyFrom(e.target.value, decimals > 0, false, 0));
115
+ slot
116
+ )),
117
+ /* @__PURE__ */ jsx(
118
+ "input",
119
+ {
120
+ ...q.rest,
121
+ ref,
122
+ type: "text",
123
+ inputMode: q.inputMode,
124
+ value: q.text,
125
+ disabled: q.disabled,
126
+ onKeyDown: q.onKeyDown,
127
+ onChange: q.onTextChange,
128
+ onBlur: q.onBlur,
129
+ className: q.inputClassName
130
+ }
131
+ ),
132
+ q.steppers.map((slot) => /* @__PURE__ */ jsx(
133
+ "button",
134
+ {
135
+ type: "button",
136
+ "aria-label": "Increase quantity",
137
+ disabled: q.increaseOff,
138
+ onClick: q.onIncrease,
139
+ className: q.buttonClassName,
140
+ children: /* @__PURE__ */ jsx(LuPlus, {})
69
141
  },
70
- [decimals]
71
- );
72
- const handleBlur = React.useCallback(() => {
73
- commit(qtyStr);
74
- }, [commit, qtyStr]);
75
- const handleDecrement = React.useCallback(() => {
76
- onChange(stepDown(value, step, min));
77
- }, [value, step, min, onChange]);
78
- const handleIncrement = React.useCallback(() => {
79
- onChange(stepUp(value, step, max));
80
- }, [value, step, max, onChange]);
81
- const minDisabled = decreaseDisabled(disabled, value, min);
82
- const maxDisabled = increaseDisabled(disabled, value, max);
83
- return /* @__PURE__ */ jsxs("div", { className: cn("bg-background inline-flex items-center rounded-md border", className), children: [
84
- showStepper && /* @__PURE__ */ jsx(
85
- "button",
86
- {
87
- type: "button",
88
- "aria-label": "Decrease quantity",
89
- disabled: minDisabled,
90
- onClick: handleDecrement,
91
- className: cn(
92
- "hover:bg-accent flex h-10 w-10 items-center justify-center disabled:opacity-50",
93
- buttonClassName
94
- ),
95
- children: /* @__PURE__ */ jsx(LuMinus, {})
96
- }
97
- ),
98
- /* @__PURE__ */ jsx(
99
- "input",
100
- {
101
- ref,
102
- type: "text",
103
- inputMode: decimals > 0 ? "decimal" : "numeric",
104
- value: qtyStr,
105
- disabled,
106
- onKeyDown: handleKeyDown,
107
- onChange: handleChange,
108
- onBlur: handleBlur,
109
- className: cn(
110
- "h-10 w-16 bg-transparent text-center focus:outline-none",
111
- inputClassName
112
- )
113
- }
114
- ),
115
- showStepper && /* @__PURE__ */ jsx(
116
- "button",
117
- {
118
- type: "button",
119
- "aria-label": "Increase quantity",
120
- disabled: maxDisabled,
121
- onClick: handleIncrement,
122
- className: cn(
123
- "hover:bg-accent flex h-10 w-10 items-center justify-center disabled:opacity-50",
124
- buttonClassName
125
- ),
126
- children: /* @__PURE__ */ jsx(LuPlus, {})
127
- }
128
- )
129
- ] });
130
- }
131
- )
142
+ slot
143
+ ))
144
+ ] });
145
+ })
132
146
  );
133
147
  QuantityInput.displayName = "QuantityInput";
134
148
  export {
@@ -1 +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\";\nimport {\n clampQuantity,\n cleanQtyFrom,\n decreaseDisabled,\n increaseDisabled,\n keyAllowed,\n stepDown,\n stepUp,\n} from \"./rules\";\n\nexport interface QuantityInputProps {\n /** Current quantity value (controlled). */\n value: number;\n /** Called with the new quantity after validation and rounding. */\n onChange: (value: number) => void;\n /** Minimum allowed quantity. Default: `0`. */\n min?: number;\n /** Maximum allowed quantity. */\n max?: number;\n /** Increment/decrement step size. Values are rounded up to the nearest step. Default: `1`. */\n step?: number;\n /** Number of decimal places to display. Default: `0`. */\n decimals?: number;\n /** Show +/- stepper buttons. Default: `true`. */\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\n/**\n * The quantity a typed string commits to: `min` when blank, else the number (or `min` when it\n * is not one) rounded up to the step, clamped to [min, max] and to `decimals` places.\n */\nfunction committedQuantity(\n raw: string,\n min: number,\n max: number | undefined,\n step: number,\n decimals: number,\n): number {\n if (raw.trim() === \"\") return min;\n\n let parsed = parseFloat(raw);\n if (isNaN(parsed)) parsed = min;\n\n // roundToStep stays here: Math.ceil over fractional quantities has no lsc form.\n parsed = clampQuantity(roundToStep(parsed, step), min, max);\n\n return parseFloat(parsed.toFixed(decimals));\n}\n\n/**\n * Numeric input with optional +/- stepper buttons for cart quantities.\n *\n * @example\n * ```tsx\n * <QuantityInput value={qty} onChange={setQty} min={1} step={1} />\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(() => value.toFixed(decimals));\n\n React.useEffect(() => {\n setQtyStr(value.toFixed(decimals));\n }, [value, decimals]);\n\n const commit = React.useCallback(\n (raw: string) => {\n const quantity = committedQuantity(raw, min, max, step, decimals);\n setQtyStr(quantity.toFixed(decimals));\n onChange(quantity);\n },\n [min, max, step, decimals, onChange],\n );\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n commit(qtyStr);\n return;\n }\n if (!keyAllowed(e.key, decimals, qtyStr.includes(\".\"))) e.preventDefault();\n },\n [decimals, qtyStr, commit],\n );\n\n const handleChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setQtyStr(cleanQtyFrom(e.target.value, decimals > 0, false, 0));\n },\n [decimals],\n );\n\n const handleBlur = React.useCallback(() => {\n commit(qtyStr);\n }, [commit, qtyStr]);\n\n const handleDecrement = React.useCallback(() => {\n onChange(stepDown(value, step, min));\n }, [value, step, min, onChange]);\n\n const handleIncrement = React.useCallback(() => {\n onChange(stepUp(value, step, max));\n }, [value, step, max, onChange]);\n\n const minDisabled = decreaseDisabled(disabled, value, min);\n const maxDisabled = increaseDisabled(disabled, value, max);\n\n return (\n <div className={cn(\"bg-background inline-flex items-center rounded-md border\", className)}>\n {showStepper && (\n <button\n type=\"button\"\n aria-label=\"Decrease quantity\"\n disabled={minDisabled}\n onClick={handleDecrement}\n className={cn(\n \"hover:bg-accent flex h-10 w-10 items-center justify-center 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 bg-transparent text-center 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 \"hover:bg-accent flex h-10 w-10 items-center justify-center 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":[]}
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 { pow10, signedFixedText } from \"@atlas/utils/fixed\";\nimport { LuMinus, LuPlus } from \"react-icons/lu\";\nimport {\n cleanQtyFrom,\n commitUnits,\n decreaseDisabled,\n increaseDisabled,\n inputModeOf,\n keyActionOf,\n slotsWhen,\n stepDown,\n stepUp,\n} from \"./rules\";\n\n/**\n * The `<input>` attributes the component owns. A site can't pass them: `min`, `max` and `step`\n * are its numeric props, and the rest drive commit on blur and Enter.\n */\ntype OwnInputAttribute =\n | \"value\"\n | \"onChange\"\n | \"type\"\n | \"inputMode\"\n | \"disabled\"\n | \"onKeyDown\"\n | \"onBlur\"\n | \"className\"\n | \"min\"\n | \"max\"\n | \"step\";\n\n/**\n * Every other `<input>` attribute (`id`, `name`, `aria-label`, `aria-labelledby`,\n * `aria-describedby`, `autoComplete`, `data-*`, …) goes onto the field, so a site can name it.\n */\nexport interface QuantityInputProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n OwnInputAttribute\n> {\n /** Current quantity value (controlled). */\n value: number;\n /** Called with the new quantity after validation and rounding. */\n onChange: (value: number) => void;\n /** Minimum allowed quantity, at the field's `decimals`. Default: `0`. */\n min?: number;\n /** Maximum allowed quantity, at the field's `decimals`. */\n max?: number;\n /** Increment/decrement step, at the field's `decimals`. Values round up to it. Default: `1`. */\n step?: number;\n /** Number of decimal places to display. Default: `0`. */\n decimals?: number;\n /** Show +/- stepper buttons. Default: `true`. */\n showStepper?: boolean;\n disabled?: boolean;\n /** Classes for the wrapper. */\n className?: string;\n inputClassName?: string;\n buttonClassName?: string;\n}\n\n/**\n * The field's state and handlers. Every decision is a proved rule (`./rules`, utils `fixed`);\n * this only holds React state, converts the props to integer units of 10^-decimals\n * (`Math.round`) and acts on what the rules return.\n */\nfunction useQuantityInput(props: QuantityInputProps) {\n const {\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 ...rest\n } = props;\n const scale = pow10(decimals);\n const shown = signedFixedText(Math.round(value * scale), decimals);\n const [text, setText] = React.useState(shown);\n\n React.useEffect(() => {\n setText(shown);\n }, [shown]);\n\n const commit = React.useCallback(\n (raw: string) => {\n const units = commitUnits(\n raw,\n Math.round(min * scale),\n max === undefined ? undefined : Math.round(max * scale),\n Math.round(step * scale),\n decimals,\n );\n setText(signedFixedText(units, decimals));\n onChange(units / scale);\n },\n [min, max, step, decimals, scale, onChange],\n );\n\n const onKeyDown = React.useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n const action = keyActionOf(e.key, decimals, text);\n if (action === \"commit\") commit(text);\n else if (action === \"block\") e.preventDefault();\n },\n [decimals, text, commit],\n );\n\n const onTextChange = React.useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setText(cleanQtyFrom(e.target.value, decimals > 0, false, 0));\n },\n [decimals],\n );\n\n const onBlur = React.useCallback(() => {\n commit(text);\n }, [commit, text]);\n\n const onDecrease = React.useCallback(() => {\n onChange(stepDown(value, step, min));\n }, [value, step, min, onChange]);\n\n const onIncrease = React.useCallback(() => {\n onChange(stepUp(value, step, max));\n }, [value, step, max, onChange]);\n\n return {\n rest,\n text,\n disabled,\n inputMode: inputModeOf(decimals),\n steppers: slotsWhen(showStepper),\n decreaseOff: decreaseDisabled(disabled, value, min),\n increaseOff: increaseDisabled(disabled, value, max),\n onKeyDown,\n onTextChange,\n onBlur,\n onDecrease,\n onIncrease,\n className: cn(\"bg-background inline-flex items-center rounded-md border\", className),\n inputClassName: cn(\"h-10 w-16 bg-transparent text-center focus:outline-none\", inputClassName),\n buttonClassName: cn(\n \"hover:bg-accent flex h-10 w-10 items-center justify-center disabled:opacity-50\",\n buttonClassName,\n ),\n };\n}\n\n/**\n * Numeric input with optional +/- stepper buttons for cart quantities.\n *\n * @example\n * ```tsx\n * <label htmlFor=\"qty\">Quantity</label>\n * <QuantityInput id=\"qty\" value={qty} onChange={setQty} min={1} step={1} />\n * ```\n */\nconst QuantityInput = React.memo(\n React.forwardRef<HTMLInputElement, QuantityInputProps>((props, ref) => {\n const q = useQuantityInput(props);\n return (\n <div className={q.className}>\n {q.steppers.map((slot) => (\n <button\n key={slot}\n type=\"button\"\n aria-label=\"Decrease quantity\"\n disabled={q.decreaseOff}\n onClick={q.onDecrease}\n className={q.buttonClassName}\n >\n <LuMinus />\n </button>\n ))}\n <input\n {...q.rest}\n ref={ref}\n type=\"text\"\n inputMode={q.inputMode}\n value={q.text}\n disabled={q.disabled}\n onKeyDown={q.onKeyDown}\n onChange={q.onTextChange}\n onBlur={q.onBlur}\n className={q.inputClassName}\n />\n {q.steppers.map((slot) => (\n <button\n key={slot}\n type=\"button\"\n aria-label=\"Increase quantity\"\n disabled={q.increaseOff}\n onClick={q.onIncrease}\n className={q.buttonClassName}\n >\n <LuPlus />\n </button>\n ))}\n </div>\n );\n }),\n);\nQuantityInput.displayName = \"QuantityInput\";\n\nexport { QuantityInput };\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }"use client";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
2
  "use client";
3
3
 
4
4
 
@@ -7,17 +7,22 @@
7
7
 
8
8
  var _chunkUFL6PVLIcjs = require('./chunk-UFL6PVLI.cjs');
9
9
 
10
+
11
+ var _chunkNBXA42AWcjs = require('./chunk-NBXA42AW.cjs');
12
+
10
13
  // src/resource-tabs.tsx
11
14
  require('react');
12
15
  var _web = require('@simpleapps-com/augur-utils/web');
13
16
  var _jsxruntime = require('react/jsx-runtime');
14
17
  function ResourceTabs({ tabs, defaultTab, className }) {
15
- if (tabs.length === 0) return null;
16
- const resolvedDefault = _nullishCoalesce(defaultTab, () => ( tabs[0].value));
17
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkUFL6PVLIcjs.Tabs, { defaultValue: resolvedDefault, className: _web.cn.call(void 0, className), children: [
18
+ const view = _chunkNBXA42AWcjs.tabsViewOf.call(void 0,
19
+ defaultTab,
20
+ tabs.map((tab) => tab.value)
21
+ );
22
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: view.shown.map((slot) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkUFL6PVLIcjs.Tabs, { defaultValue: view.defaultTab, className: _web.cn.call(void 0, className), children: [
18
23
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUFL6PVLIcjs.TabsList, { children: tabs.map((tab) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUFL6PVLIcjs.TabsTrigger, { value: tab.value, disabled: tab.disabled, children: tab.label }, tab.value)) }),
19
24
  tabs.map((tab) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUFL6PVLIcjs.TabsContent, { value: tab.value, children: tab.content }, tab.value))
20
- ] });
25
+ ] }, slot)) });
21
26
  }
22
27
  ResourceTabs.displayName = "ResourceTabs";
23
28
 
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/resource-tabs.cjs","../src/resource-tabs.tsx"],"names":[],"mappings":"AAAA,yLAAY;AACZ,YAAY;AACZ;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACNA,iBAAuB;AACvB,sDAAmB;AAmCf,+CAAA;AANJ,SAAS,YAAA,CAAa,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,CAAA,EAAsB;AACxE,EAAA,GAAA,CAAI,IAAA,CAAK,OAAA,IAAW,CAAA,EAAG,OAAO,IAAA;AAE9B,EAAA,MAAM,gBAAA,mBAAkB,UAAA,UAAc,IAAA,CAAK,CAAC,CAAA,CAAG,OAAA;AAE/C,EAAA,uBACE,8BAAA,sBAAC,EAAA,EAAK,YAAA,EAAc,eAAA,EAAiB,SAAA,EAAW,qBAAA,SAAY,CAAA,EAC1D,QAAA,EAAA;AAAA,oBAAA,6BAAA,0BAAC,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAA,mBACT,6BAAA,6BAAC,EAAA,EAA4B,KAAA,EAAO,GAAA,CAAI,KAAA,EAAO,QAAA,EAAU,GAAA,CAAI,QAAA,EAC1D,QAAA,EAAA,GAAA,CAAI,MAAA,CAAA,EADW,GAAA,CAAI,KAEtB,CACD,EAAA,CACH,CAAA;AAAA,IACC,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAA,mBACT,6BAAA,6BAAC,EAAA,EAA4B,KAAA,EAAO,GAAA,CAAI,KAAA,EACrC,QAAA,EAAA,GAAA,CAAI,QAAA,CAAA,EADW,GAAA,CAAI,KAEtB,CACD;AAAA,EAAA,EAAA,CACH,CAAA;AAEJ;AACA,YAAA,CAAa,YAAA,EAAc,cAAA;ADjC3B;AACE;AACF,oCAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/resource-tabs.cjs","sourcesContent":[null,"/** Sub-resource tab layout composing Tabs. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"./tabs\";\n\nexport interface TabDef {\n value: string;\n label: string;\n content: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface ResourceTabsProps {\n tabs: TabDef[];\n defaultTab?: string;\n className?: string;\n}\n\n/**\n * Standardized sub-resource tab layout for detail pages.\n *\n * @example\n * ```tsx\n * <ResourceTabs\n * tabs={[\n * { value: \"attributes\", label: \"Attributes\", content: <AttributesList /> },\n * { value: \"items\", label: \"Items\", content: <ItemsList /> },\n * ]}\n * />\n * ```\n */\nfunction ResourceTabs({ tabs, defaultTab, className }: ResourceTabsProps) {\n if (tabs.length === 0) return null;\n\n const resolvedDefault = defaultTab ?? tabs[0]!.value;\n\n return (\n <Tabs defaultValue={resolvedDefault} className={cn(className)}>\n <TabsList>\n {tabs.map((tab) => (\n <TabsTrigger key={tab.value} value={tab.value} disabled={tab.disabled}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {tabs.map((tab) => (\n <TabsContent key={tab.value} value={tab.value}>\n {tab.content}\n </TabsContent>\n ))}\n </Tabs>\n );\n}\nResourceTabs.displayName = \"ResourceTabs\";\n\nexport { ResourceTabs };\n"]}
1
+ {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/resource-tabs.cjs","../src/resource-tabs.tsx"],"names":[],"mappings":"AAAA,qFAAY;AACZ,YAAY;AACZ;AACE;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACTA,iBAAuB;AACvB,sDAAmB;AAqCf,+CAAA;AAPJ,SAAS,YAAA,CAAa,EAAE,IAAA,EAAM,UAAA,EAAY,UAAU,CAAA,EAAsB;AACxE,EAAA,MAAM,KAAA,EAAO,0CAAA;AAAA,IACX,UAAA;AAAA,IACA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAA,GAAQ,GAAA,CAAI,KAAK;AAAA,EAC7B,CAAA;AAEA,EAAA,uBACE,6BAAA,oBAAA,EAAA,EACG,QAAA,EAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAA,mBACf,8BAAA,sBAAC,EAAA,EAAgB,YAAA,EAAc,IAAA,CAAK,UAAA,EAAY,SAAA,EAAW,qBAAA,SAAY,CAAA,EACrE,QAAA,EAAA;AAAA,oBAAA,6BAAA,0BAAC,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAA,mBACT,6BAAA,6BAAC,EAAA,EAA4B,KAAA,EAAO,GAAA,CAAI,KAAA,EAAO,QAAA,EAAU,GAAA,CAAI,QAAA,EAC1D,QAAA,EAAA,GAAA,CAAI,MAAA,CAAA,EADW,GAAA,CAAI,KAEtB,CACD,EAAA,CACH,CAAA;AAAA,IACC,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,EAAA,mBACT,6BAAA,6BAAC,EAAA,EAA4B,KAAA,EAAO,GAAA,CAAI,KAAA,EACrC,QAAA,EAAA,GAAA,CAAI,QAAA,CAAA,EADW,GAAA,CAAI,KAEtB,CACD;AAAA,EAAA,EAAA,CAAA,EAZQ,IAaX,CACD,EAAA,CACH,CAAA;AAEJ;AACA,YAAA,CAAa,YAAA,EAAc,cAAA;ADlC3B;AACE;AACF,oCAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/resource-tabs.cjs","sourcesContent":[null,"/** Sub-resource tab layout composing Tabs. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"./tabs\";\nimport { tabsViewOf } from \"./rules\";\n\nexport interface TabDef {\n value: string;\n label: string;\n content: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface ResourceTabsProps {\n tabs: TabDef[];\n defaultTab?: string;\n className?: string;\n}\n\n/**\n * Standardized sub-resource tab layout for detail pages.\n *\n * @example\n * ```tsx\n * <ResourceTabs\n * tabs={[\n * { value: \"attributes\", label: \"Attributes\", content: <AttributesList /> },\n * { value: \"items\", label: \"Items\", content: <ItemsList /> },\n * ]}\n * />\n * ```\n */\nfunction ResourceTabs({ tabs, defaultTab, className }: ResourceTabsProps) {\n const view = tabsViewOf(\n defaultTab,\n tabs.map((tab) => tab.value),\n );\n\n return (\n <>\n {view.shown.map((slot) => (\n <Tabs key={slot} defaultValue={view.defaultTab} className={cn(className)}>\n <TabsList>\n {tabs.map((tab) => (\n <TabsTrigger key={tab.value} value={tab.value} disabled={tab.disabled}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {tabs.map((tab) => (\n <TabsContent key={tab.value} value={tab.value}>\n {tab.content}\n </TabsContent>\n ))}\n </Tabs>\n ))}\n </>\n );\n}\nResourceTabs.displayName = \"ResourceTabs\";\n\nexport { ResourceTabs };\n"]}
@@ -23,7 +23,7 @@ export interface ResourceTabsProps {
23
23
  * />
24
24
  * ```
25
25
  */
26
- declare function ResourceTabs({ tabs, defaultTab, className }: ResourceTabsProps): React.JSX.Element | null;
26
+ declare function ResourceTabs({ tabs, defaultTab, className }: ResourceTabsProps): React.JSX.Element;
27
27
  declare namespace ResourceTabs {
28
28
  var displayName: string;
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resource-tabs.d.ts","sourceRoot":"","sources":["../src/resource-tabs.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,iBAAS,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,iBAAiB,4BAqBvE;kBArBQ,YAAY;;;AAwBrB,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"resource-tabs.d.ts","sourceRoot":"","sources":["../src/resource-tabs.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,iBAAS,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,iBAAiB,qBA0BvE;kBA1BQ,YAAY;;;AA6BrB,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -6,18 +6,23 @@ import {
6
6
  TabsList,
7
7
  TabsTrigger
8
8
  } from "./chunk-KHIHHL3A.js";
9
+ import {
10
+ tabsViewOf
11
+ } from "./chunk-NSMOT7GD.js";
9
12
 
10
13
  // src/resource-tabs.tsx
11
14
  import "react";
12
15
  import { cn } from "@simpleapps-com/augur-utils/web";
13
- import { jsx, jsxs } from "react/jsx-runtime";
16
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
17
  function ResourceTabs({ tabs, defaultTab, className }) {
15
- if (tabs.length === 0) return null;
16
- const resolvedDefault = defaultTab ?? tabs[0].value;
17
- return /* @__PURE__ */ jsxs(Tabs, { defaultValue: resolvedDefault, className: cn(className), children: [
18
+ const view = tabsViewOf(
19
+ defaultTab,
20
+ tabs.map((tab) => tab.value)
21
+ );
22
+ return /* @__PURE__ */ jsx(Fragment, { children: view.shown.map((slot) => /* @__PURE__ */ jsxs(Tabs, { defaultValue: view.defaultTab, className: cn(className), children: [
18
23
  /* @__PURE__ */ jsx(TabsList, { children: tabs.map((tab) => /* @__PURE__ */ jsx(TabsTrigger, { value: tab.value, disabled: tab.disabled, children: tab.label }, tab.value)) }),
19
24
  tabs.map((tab) => /* @__PURE__ */ jsx(TabsContent, { value: tab.value, children: tab.content }, tab.value))
20
- ] });
25
+ ] }, slot)) });
21
26
  }
22
27
  ResourceTabs.displayName = "ResourceTabs";
23
28
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resource-tabs.tsx"],"sourcesContent":["/** Sub-resource tab layout composing Tabs. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"./tabs\";\n\nexport interface TabDef {\n value: string;\n label: string;\n content: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface ResourceTabsProps {\n tabs: TabDef[];\n defaultTab?: string;\n className?: string;\n}\n\n/**\n * Standardized sub-resource tab layout for detail pages.\n *\n * @example\n * ```tsx\n * <ResourceTabs\n * tabs={[\n * { value: \"attributes\", label: \"Attributes\", content: <AttributesList /> },\n * { value: \"items\", label: \"Items\", content: <ItemsList /> },\n * ]}\n * />\n * ```\n */\nfunction ResourceTabs({ tabs, defaultTab, className }: ResourceTabsProps) {\n if (tabs.length === 0) return null;\n\n const resolvedDefault = defaultTab ?? tabs[0]!.value;\n\n return (\n <Tabs defaultValue={resolvedDefault} className={cn(className)}>\n <TabsList>\n {tabs.map((tab) => (\n <TabsTrigger key={tab.value} value={tab.value} disabled={tab.disabled}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {tabs.map((tab) => (\n <TabsContent key={tab.value} value={tab.value}>\n {tab.content}\n </TabsContent>\n ))}\n </Tabs>\n );\n}\nResourceTabs.displayName = \"ResourceTabs\";\n\nexport { ResourceTabs };\n"],"mappings":";;;;;;;;;;AAGA,OAAuB;AACvB,SAAS,UAAU;AAmCf,SAGM,KAHN;AANJ,SAAS,aAAa,EAAE,MAAM,YAAY,UAAU,GAAsB;AACxE,MAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,QAAM,kBAAkB,cAAc,KAAK,CAAC,EAAG;AAE/C,SACE,qBAAC,QAAK,cAAc,iBAAiB,WAAW,GAAG,SAAS,GAC1D;AAAA,wBAAC,YACE,eAAK,IAAI,CAAC,QACT,oBAAC,eAA4B,OAAO,IAAI,OAAO,UAAU,IAAI,UAC1D,cAAI,SADW,IAAI,KAEtB,CACD,GACH;AAAA,IACC,KAAK,IAAI,CAAC,QACT,oBAAC,eAA4B,OAAO,IAAI,OACrC,cAAI,WADW,IAAI,KAEtB,CACD;AAAA,KACH;AAEJ;AACA,aAAa,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/resource-tabs.tsx"],"sourcesContent":["/** Sub-resource tab layout composing Tabs. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"./tabs\";\nimport { tabsViewOf } from \"./rules\";\n\nexport interface TabDef {\n value: string;\n label: string;\n content: React.ReactNode;\n disabled?: boolean;\n}\n\nexport interface ResourceTabsProps {\n tabs: TabDef[];\n defaultTab?: string;\n className?: string;\n}\n\n/**\n * Standardized sub-resource tab layout for detail pages.\n *\n * @example\n * ```tsx\n * <ResourceTabs\n * tabs={[\n * { value: \"attributes\", label: \"Attributes\", content: <AttributesList /> },\n * { value: \"items\", label: \"Items\", content: <ItemsList /> },\n * ]}\n * />\n * ```\n */\nfunction ResourceTabs({ tabs, defaultTab, className }: ResourceTabsProps) {\n const view = tabsViewOf(\n defaultTab,\n tabs.map((tab) => tab.value),\n );\n\n return (\n <>\n {view.shown.map((slot) => (\n <Tabs key={slot} defaultValue={view.defaultTab} className={cn(className)}>\n <TabsList>\n {tabs.map((tab) => (\n <TabsTrigger key={tab.value} value={tab.value} disabled={tab.disabled}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {tabs.map((tab) => (\n <TabsContent key={tab.value} value={tab.value}>\n {tab.content}\n </TabsContent>\n ))}\n </Tabs>\n ))}\n </>\n );\n}\nResourceTabs.displayName = \"ResourceTabs\";\n\nexport { ResourceTabs };\n"],"mappings":";;;;;;;;;;;;;AAGA,OAAuB;AACvB,SAAS,UAAU;AAqCf,mBAKU,KAHN,YAFJ;AAPJ,SAAS,aAAa,EAAE,MAAM,YAAY,UAAU,GAAsB;AACxE,QAAM,OAAO;AAAA,IACX;AAAA,IACA,KAAK,IAAI,CAAC,QAAQ,IAAI,KAAK;AAAA,EAC7B;AAEA,SACE,gCACG,eAAK,MAAM,IAAI,CAAC,SACf,qBAAC,QAAgB,cAAc,KAAK,YAAY,WAAW,GAAG,SAAS,GACrE;AAAA,wBAAC,YACE,eAAK,IAAI,CAAC,QACT,oBAAC,eAA4B,OAAO,IAAI,OAAO,UAAU,IAAI,UAC1D,cAAI,SADW,IAAI,KAEtB,CACD,GACH;AAAA,IACC,KAAK,IAAI,CAAC,QACT,oBAAC,eAA4B,OAAO,IAAI,OACrC,cAAI,WADW,IAAI,KAEtB,CACD;AAAA,OAZQ,IAaX,CACD,GACH;AAEJ;AACA,aAAa,cAAc;","names":[]}