@mohasinac/appkit 4.23.0 → 4.24.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.
Files changed (47) hide show
  1. package/dist/_internal/server/features/bundles/actions.js +7 -0
  2. package/dist/_internal/server/features/checkout/actions.js +24 -16
  3. package/dist/_internal/shared/actions/action-registry.js +41 -0
  4. package/dist/_internal/shared/checkout/order-math.d.ts +23 -5
  5. package/dist/_internal/shared/checkout/order-math.js +29 -6
  6. package/dist/_internal/shared/checkout/rules/_limits.d.ts +12 -2
  7. package/dist/_internal/shared/checkout/rules/_limits.js +12 -2
  8. package/dist/_internal/shared/features/cart/config.d.ts +2 -1
  9. package/dist/_internal/shared/features/cart/config.js +2 -1
  10. package/dist/_internal/shared/features/cart/schema.d.ts +6 -6
  11. package/dist/_internal/shared/features/notifications/action-url.d.ts +47 -0
  12. package/dist/_internal/shared/features/notifications/action-url.js +111 -0
  13. package/dist/constants/notification-types.d.ts +38 -10
  14. package/dist/constants/notification-types.js +39 -28
  15. package/dist/features/account/types/index.d.ts +1 -10
  16. package/dist/features/admin/actions/notification-actions.d.ts +12 -0
  17. package/dist/features/admin/actions/notification-actions.js +149 -4
  18. package/dist/features/admin/schemas/firestore.d.ts +14 -3
  19. package/dist/features/admin/schemas/firestore.js +79 -0
  20. package/dist/features/cart/actions/cart-actions.d.ts +16 -0
  21. package/dist/features/cart/actions/cart-actions.js +26 -12
  22. package/dist/features/cart/components/CartDrawer.js +2 -1
  23. package/dist/features/cart/schemas/firestore.d.ts +132 -8
  24. package/dist/features/cart/schemas/firestore.js +22 -0
  25. package/dist/features/email/index.d.ts +1 -1
  26. package/dist/features/email/index.js +5 -1
  27. package/dist/features/email/notification-templates.d.ts +35 -0
  28. package/dist/features/email/notification-templates.js +96 -0
  29. package/dist/features/orders/schemas/index.d.ts +2 -2
  30. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +30 -0
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.js +3 -1
  33. package/dist/schemas/registry.d.ts +2 -2
  34. package/dist/seed/factories/notification.factory.d.ts +2 -1
  35. package/dist/server-entry.d.ts +1 -0
  36. package/dist/server-entry.js +5 -0
  37. package/dist/server.d.ts +5 -1
  38. package/dist/server.js +10 -1
  39. package/dist/styles.css +58 -1
  40. package/dist/tailwind-utilities.css +1 -1
  41. package/dist/ui/components/QuantityStepper.d.ts +38 -0
  42. package/dist/ui/components/QuantityStepper.js +20 -0
  43. package/dist/ui/components/QuantityStepper.style.css +56 -0
  44. package/dist/ui/components/index.style.css +1 -0
  45. package/dist/ui/index.d.ts +2 -0
  46. package/dist/ui/index.js +1 -0
  47. package/package.json +1 -1
@@ -0,0 +1,38 @@
1
+ /**
2
+ * QuantityStepper — the canonical −/+ quantity control.
3
+ *
4
+ * There was no primitive for this; the pattern was hand-rolled inside
5
+ * `CartItemRow` and the grouped-cart-line work needed three more copies, which
6
+ * is the Rule of Three. Every consumer now shares one set of tokens, one
7
+ * clamping rule and one a11y contract.
8
+ *
9
+ * Deliberately NOT built on `<input type="number">`:
10
+ * - it would trip `audit-raw-form-input` (Rule #9), and
11
+ * - a free-text numeric field needs its own parse/clamp/validation story on
12
+ * every call site. Two buttons cannot produce an out-of-range value.
13
+ * If typed entry is ever genuinely wanted, it belongs in a `<Form>` with a
14
+ * `<FieldInput type="number">`, not here.
15
+ *
16
+ * `min` is the meaningful variant between the two line kinds:
17
+ * - `min={1}` — a normal quantity; you remove the line to get rid of it.
18
+ * - `min={0}` — a member inside a group line, where 0 legitimately means
19
+ * "drop this member from my selection".
20
+ */
21
+ import React from "react";
22
+ export interface QuantityStepperProps {
23
+ value: number;
24
+ onChange: (next: number) => void;
25
+ /** Lowest reachable value. See the note above on 0 vs 1. Default 1. */
26
+ min?: number;
27
+ /** Highest reachable value — pass the stock ceiling. Omit for unbounded. */
28
+ max?: number;
29
+ disabled?: boolean;
30
+ /** Dims and blocks interaction while a mutation is in flight. */
31
+ isBusy?: boolean;
32
+ size?: "sm" | "md";
33
+ /** Describes WHAT is being counted, e.g. `Quantity for Dragoon F`. */
34
+ ariaLabel?: string;
35
+ decrementLabel?: string;
36
+ incrementLabel?: string;
37
+ }
38
+ export declare function QuantityStepper({ value, onChange, min, max, disabled, isBusy, size, ariaLabel, decrementLabel, incrementLabel, }: QuantityStepperProps): React.JSX.Element;
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button } from "./Button";
4
+ import { Row } from "./Layout";
5
+ import { Span } from "./Typography";
6
+ export function QuantityStepper({ value, onChange, min = 1, max, disabled = false, isBusy = false, size = "sm", ariaLabel, decrementLabel = "Decrease quantity", incrementLabel = "Increase quantity", }) {
7
+ const canDecrement = !disabled && value > min;
8
+ const canIncrement = !disabled && (max === undefined || value < max);
9
+ // Clamp here rather than trusting the caller: every consumer would otherwise
10
+ // re-derive the same two bounds checks in its own handler.
11
+ const step = (delta) => {
12
+ const next = value + delta;
13
+ if (next < min)
14
+ return;
15
+ if (max !== undefined && next > max)
16
+ return;
17
+ onChange(next);
18
+ };
19
+ return (_jsxs(Row, { gap: "sm", align: "center", role: "group", "aria-label": ariaLabel, className: `appkit-qty-stepper appkit-qty-stepper--${size}${isBusy ? " appkit-qty-stepper--busy" : ""}`, children: [_jsx(Button, { type: "button", variant: "outline", size: "sm", rounded: "full", onClick: () => step(-1), disabled: !canDecrement, "aria-label": decrementLabel, className: "appkit-qty-stepper__btn", children: "\u2212" }), _jsx(Span, { "aria-live": "polite", className: "appkit-qty-stepper__value", children: value }), _jsx(Button, { type: "button", variant: "outline", size: "sm", rounded: "full", onClick: () => step(1), disabled: !canIncrement, "aria-label": incrementLabel, className: "appkit-qty-stepper__btn", children: "+" })] }));
20
+ }
@@ -0,0 +1,56 @@
1
+ /* QuantityStepper — the −/+ quantity control.
2
+ *
3
+ * All tokens live here rather than on the call site's className. The one
4
+ * hand-rolled copy this replaced carried `border-neutral-200` (a raw palette
5
+ * class, not a semantic token) plus an arbitrary `text-[length:...]`, and
6
+ * copying it to three new call sites would have multiplied that by four. */
7
+
8
+ .appkit-qty-stepper {
9
+ display: inline-flex;
10
+ align-items: center;
11
+ gap: var(--appkit-space-2);
12
+ }
13
+
14
+ .appkit-qty-stepper__value {
15
+ display: inline-block;
16
+ text-align: center;
17
+ font-variant-numeric: tabular-nums;
18
+ color: var(--appkit-color-text);
19
+ }
20
+
21
+ /* Fixed min-width so the row doesn't reflow as the number crosses 9 -> 10. */
22
+ .appkit-qty-stepper--sm .appkit-qty-stepper__value {
23
+ min-width: 1.5rem;
24
+ font-size: var(--appkit-text-sm);
25
+ }
26
+ .appkit-qty-stepper--md .appkit-qty-stepper__value {
27
+ min-width: 2rem;
28
+ font-size: var(--appkit-text-base);
29
+ }
30
+
31
+ .appkit-qty-stepper__btn {
32
+ justify-content: center;
33
+ border: 1px solid var(--appkit-color-border);
34
+ line-height: 1;
35
+ }
36
+
37
+ .appkit-qty-stepper--sm .appkit-qty-stepper__btn {
38
+ height: 1.75rem;
39
+ width: 1.75rem;
40
+ font-size: var(--appkit-text-sm);
41
+ }
42
+ .appkit-qty-stepper--md .appkit-qty-stepper__btn {
43
+ height: 2.25rem;
44
+ width: 2.25rem;
45
+ font-size: var(--appkit-text-base);
46
+ }
47
+
48
+ .appkit-qty-stepper__btn:disabled {
49
+ opacity: 0.4;
50
+ cursor: not-allowed;
51
+ }
52
+
53
+ .appkit-qty-stepper--busy {
54
+ opacity: 0.6;
55
+ pointer-events: none;
56
+ }
@@ -45,6 +45,7 @@
45
45
  @import "./Card.style.css";
46
46
  @import "./Avatar.style.css";
47
47
  @import "./Toggle.style.css";
48
+ @import "./QuantityStepper.style.css";
48
49
  @import "./Checkbox.style.css";
49
50
  @import "./EmptyState.style.css";
50
51
  @import "./SkipToMain.style.css";
@@ -89,6 +89,8 @@ export type { RadioGroupProps, RadioOption, RadioItemProps } from "./components/
89
89
  export { RadioGroup, RadioItem } from "./components/Radio";
90
90
  export type { ToggleProps } from "./components/Toggle";
91
91
  export { Toggle } from "./components/Toggle";
92
+ export type { QuantityStepperProps } from "./components/QuantityStepper";
93
+ export { QuantityStepper } from "./components/QuantityStepper";
92
94
  export type { ToastVariant, ToastPosition, ToastProviderProps, } from "./components/Toast";
93
95
  export { ToastProvider, useToast } from "./components/Toast";
94
96
  export type { StarRatingProps } from "./components/StarRating";
package/dist/ui/index.js CHANGED
@@ -47,6 +47,7 @@ export { Slider } from "./components/Slider";
47
47
  export { Checkbox } from "./components/Checkbox";
48
48
  export { RadioGroup, RadioItem } from "./components/Radio";
49
49
  export { Toggle } from "./components/Toggle";
50
+ export { QuantityStepper } from "./components/QuantityStepper";
50
51
  export { ToastProvider, useToast } from "./components/Toast";
51
52
  export { StarRating } from "./components/StarRating";
52
53
  export { Breadcrumb } from "./components/Breadcrumb";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "4.23.0",
3
+ "version": "4.24.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"