@mohasinac/appkit 4.62.0 → 4.62.1

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 (204) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/server/features/checkout/actions.d.ts +80 -0
  3. package/dist/_internal/server/features/checkout/actions.js +542 -26
  4. package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
  5. package/dist/_internal/server/features/invoicing/allocate.js +162 -0
  6. package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
  7. package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
  8. package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
  9. package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
  10. package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
  11. package/dist/_internal/server/features/invoicing/issue.js +202 -0
  12. package/dist/_internal/server/features/orders/actions.d.ts +8 -1
  13. package/dist/_internal/server/features/orders/actions.js +81 -8
  14. package/dist/_internal/server/features/orders/adapters.js +33 -0
  15. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
  16. package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
  17. package/dist/_internal/server/features/points/award.js +46 -4
  18. package/dist/_internal/server/features/refunds/actions.js +26 -0
  19. package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
  20. package/dist/_internal/server/features/shipping/courier-block.js +239 -0
  21. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  22. package/dist/_internal/server/features/site-settings/adapters.js +15 -0
  23. package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
  24. package/dist/_internal/server/features/stores/adapters.js +51 -0
  25. package/dist/_internal/server/functions/scheduled.js +38 -1
  26. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +9 -2
  27. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
  28. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
  29. package/dist/_internal/server/jobs/core/index.d.ts +2 -1
  30. package/dist/_internal/server/jobs/core/index.js +2 -1
  31. package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
  32. package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
  33. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
  34. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +62 -0
  35. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
  36. package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
  37. package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
  38. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +10 -2
  39. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
  40. package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
  41. package/dist/_internal/shared/actions/action-registry.js +28 -0
  42. package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
  43. package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
  44. package/dist/_internal/shared/checkout/order-math.d.ts +145 -0
  45. package/dist/_internal/shared/checkout/order-math.js +173 -0
  46. package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
  47. package/dist/_internal/shared/checkout/refundable-base.js +13 -1
  48. package/dist/_internal/shared/checkout/split.d.ts +87 -0
  49. package/dist/_internal/shared/checkout/split.js +100 -0
  50. package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
  51. package/dist/_internal/shared/content/disclaimers.js +217 -0
  52. package/dist/_internal/shared/content/published-values.d.ts +88 -0
  53. package/dist/_internal/shared/content/published-values.js +198 -0
  54. package/dist/_internal/shared/features/admin/integrations.d.ts +109 -0
  55. package/dist/_internal/shared/features/admin/integrations.js +253 -0
  56. package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
  57. package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
  58. package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
  59. package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
  60. package/dist/_internal/shared/features/points/accepts.d.ts +36 -0
  61. package/dist/_internal/shared/features/points/accepts.js +43 -0
  62. package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
  63. package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
  64. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  65. package/dist/_internal/shared/fees/calculator.d.ts +33 -1
  66. package/dist/_internal/shared/fees/calculator.js +32 -2
  67. package/dist/client.d.ts +11 -0
  68. package/dist/client.js +30 -0
  69. package/dist/constants/api-endpoints.d.ts +42 -0
  70. package/dist/constants/api-endpoints.js +14 -0
  71. package/dist/constants/field-names.d.ts +1 -0
  72. package/dist/constants/field-names.js +5 -0
  73. package/dist/contracts/index.d.ts +1 -1
  74. package/dist/contracts/shipping.d.ts +45 -0
  75. package/dist/contracts/shipping.js +15 -0
  76. package/dist/features/about/components/AboutView.js +1 -1
  77. package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
  78. package/dist/features/account/components/UserOrdersView.js +19 -33
  79. package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
  80. package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
  81. package/dist/features/admin/components/AdminInvoicingView.js +65 -0
  82. package/dist/features/admin/components/AdminOrderEditorView.d.ts +18 -1
  83. package/dist/features/admin/components/AdminOrderEditorView.js +11 -2
  84. package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
  85. package/dist/features/admin/components/AdminOrdersView.js +67 -5
  86. package/dist/features/admin/components/OwnerQuickActions.js +24 -2
  87. package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
  88. package/dist/features/admin/constants/filter-tabs.js +6 -0
  89. package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
  90. package/dist/features/admin/hooks/useAdminListingData.js +16 -0
  91. package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
  92. package/dist/features/admin/schemas/firestore.d.ts +30 -0
  93. package/dist/features/admin/schemas/firestore.js +5 -0
  94. package/dist/features/audit-log/schemas/firestore.d.ts +30 -0
  95. package/dist/features/audit-log/schemas/firestore.js +15 -0
  96. package/dist/features/auth/permissions/constants.js +13 -0
  97. package/dist/features/cart/components/CartPriceBreakdown.d.ts +13 -0
  98. package/dist/features/cart/components/CartPriceBreakdown.js +6 -2
  99. package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
  100. package/dist/features/cart/components/PointsTenderPicker.js +15 -0
  101. package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
  102. package/dist/features/cart/components/index.d.ts +2 -0
  103. package/dist/features/cart/components/index.js +1 -0
  104. package/dist/features/cart/repository/cart.repository.d.ts +19 -0
  105. package/dist/features/cart/repository/cart.repository.js +27 -0
  106. package/dist/features/cart/schemas/firestore.d.ts +92 -0
  107. package/dist/features/contact/email.d.ts +27 -10
  108. package/dist/features/contact/email.js +20 -3
  109. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +38 -0
  110. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +80 -0
  111. package/dist/features/dispute-reasons/schemas/firestore.d.ts +64 -0
  112. package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
  113. package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
  114. package/dist/features/faq/components/FAQAccordion.js +29 -4
  115. package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
  116. package/dist/features/invoicing/schemas/firestore.js +45 -0
  117. package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
  118. package/dist/features/invoicing/utils/financial-year.js +53 -0
  119. package/dist/features/jobs/actions/enqueue-job.js +18 -1
  120. package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
  121. package/dist/features/jobs/repository/jobs.repository.js +84 -1
  122. package/dist/features/jobs/schemas/firestore.d.ts +80 -0
  123. package/dist/features/jobs/schemas/firestore.js +37 -0
  124. package/dist/features/lottery/schemas/zod.d.ts +6 -6
  125. package/dist/features/media/MediaImage.js +22 -1
  126. package/dist/features/media/upload/ImageUpload.js +1 -1
  127. package/dist/features/obligations/constants/policies.js +24 -1
  128. package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
  129. package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
  130. package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
  131. package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
  132. package/dist/features/orders/components/RaiseDisputeForm.js +111 -0
  133. package/dist/features/orders/components/RefundRequestView.js +19 -1
  134. package/dist/features/orders/components/index.d.ts +4 -0
  135. package/dist/features/orders/components/index.js +2 -0
  136. package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
  137. package/dist/features/orders/constants/order-lane-tabs.js +88 -0
  138. package/dist/features/orders/repository/orders.repository.d.ts +57 -0
  139. package/dist/features/orders/repository/orders.repository.js +145 -0
  140. package/dist/features/orders/schemas/firestore.d.ts +196 -1
  141. package/dist/features/orders/schemas/index.d.ts +54 -6
  142. package/dist/features/orders/schemas/index.js +12 -0
  143. package/dist/features/orders/types/index.d.ts +26 -0
  144. package/dist/features/orders/utils/courier-block.d.ts +25 -0
  145. package/dist/features/orders/utils/courier-block.js +23 -0
  146. package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
  147. package/dist/features/payment-cases/schemas/firestore.js +1 -0
  148. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
  149. package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
  150. package/dist/features/products/components/ProductDetailPageView.js +2 -2
  151. package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
  152. package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
  153. package/dist/features/promotions/actions/coupon-stacking.js +21 -2
  154. package/dist/features/promotions/components/CouponCard.js +13 -0
  155. package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
  156. package/dist/features/promotions/constants/coupon-help.js +9 -1
  157. package/dist/features/promotions/schemas/firestore.d.ts +24 -0
  158. package/dist/features/promotions/schemas/firestore.js +4 -0
  159. package/dist/features/promotions/types/index.d.ts +19 -1
  160. package/dist/features/scams/components/ScamProfileView.js +2 -2
  161. package/dist/features/scams/components/ScamRegistryView.js +2 -2
  162. package/dist/features/search/action-index/tab-entries.js +1 -1
  163. package/dist/features/seller/actions/seller-actions.js +33 -3
  164. package/dist/features/seller/components/SellerOrdersView.js +129 -27
  165. package/dist/features/seller/hooks/useSellerListingData.js +25 -0
  166. package/dist/features/shipments/schemas/validation.d.ts +4 -4
  167. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +43 -0
  168. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +90 -0
  169. package/dist/features/shipping-boxes/schemas/firestore.d.ts +82 -0
  170. package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
  171. package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
  172. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
  173. package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
  174. package/dist/features/stores/schemas/firestore.d.ts +71 -0
  175. package/dist/features/stores/types/index.d.ts +19 -0
  176. package/dist/features/support/schemas/index.d.ts +6 -6
  177. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  178. package/dist/index.d.ts +6 -1
  179. package/dist/index.js +14 -1
  180. package/dist/next/routing/route-map.d.ts +20 -0
  181. package/dist/next/routing/route-map.js +10 -0
  182. package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
  183. package/dist/providers/shipping-shiprocket/index.js +84 -1
  184. package/dist/schemas/registry.d.ts +47 -18
  185. package/dist/schemas/sieve.d.ts +2 -2
  186. package/dist/server-entry.d.ts +2 -2
  187. package/dist/server-entry.js +8 -1
  188. package/dist/server.d.ts +10 -1
  189. package/dist/server.js +39 -1
  190. package/dist/styles.css +64 -80
  191. package/dist/tailwind-utilities.css +1 -1
  192. package/dist/tokens/themes/default-dark.js +1 -0
  193. package/dist/tokens/themes/default-light.js +1 -0
  194. package/dist/tokens/themes/required.d.ts +1 -1
  195. package/dist/tokens/themes/required.js +1 -0
  196. package/dist/tokens/tokens.css +15 -0
  197. package/dist/ui/components/Disclaimer.d.ts +19 -0
  198. package/dist/ui/components/Disclaimer.js +74 -0
  199. package/dist/ui/components/tabs-overflow.js +64 -11
  200. package/dist/ui/index.d.ts +2 -0
  201. package/dist/ui/index.js +6 -0
  202. package/dist/ui/rich-text/RichText.style.css +48 -79
  203. package/package.json +1 -1
  204. package/scripts/seed-cli.mjs +1831 -1822
@@ -54,6 +54,7 @@ export const DEFAULT_DARK_THEME = {
54
54
  "appkit-color-text": "#fafafa",
55
55
  "appkit-color-text-muted": "#b4b4bd",
56
56
  "appkit-color-text-faint": "#8b8b94",
57
+ "appkit-color-link": "#22d3ee",
57
58
  "appkit-color-success": "#34d399",
58
59
  "appkit-color-success-surface": "rgba(6, 78, 59, 0.25)",
59
60
  "appkit-color-warning": "#fbbf24",
@@ -57,6 +57,7 @@ export const DEFAULT_LIGHT_THEME = {
57
57
  "appkit-color-text-muted": "#5b5b63",
58
58
  "appkit-color-text-faint": "#6f6f78",
59
59
  "appkit-color-text-on-primary": "#ffffff",
60
+ "appkit-color-link": "#0f766e",
60
61
  "appkit-color-success": "#15803d",
61
62
  "appkit-color-success-surface": "#f0fdf4",
62
63
  "appkit-color-warning": "#b45309",
@@ -10,6 +10,6 @@ import type { GradientKey } from "./types";
10
10
  * unknown keys are rejected; missing keys fall back to the active mode's
11
11
  * default theme value (so a theme can override only a subset).
12
12
  */
13
- export declare const REQUIRED_THEME_TOKENS: readonly ["appkit-color-primary", "appkit-color-primary-50", "appkit-color-primary-100", "appkit-color-primary-200", "appkit-color-primary-300", "appkit-color-primary-400", "appkit-color-primary-500", "appkit-color-primary-600", "appkit-color-primary-700", "appkit-color-primary-800", "appkit-color-primary-900", "appkit-color-primary-950", "appkit-color-secondary", "appkit-color-secondary-50", "appkit-color-secondary-100", "appkit-color-secondary-200", "appkit-color-secondary-300", "appkit-color-secondary-400", "appkit-color-secondary-500", "appkit-color-secondary-600", "appkit-color-secondary-700", "appkit-color-secondary-800", "appkit-color-secondary-900", "appkit-color-secondary-950", "appkit-color-bg", "appkit-color-surface", "appkit-color-surface-elevated", "appkit-color-surface-input", "appkit-color-border", "appkit-color-border-subtle", "appkit-color-text", "appkit-color-text-muted", "appkit-color-text-faint", "appkit-color-text-on-primary", "appkit-color-success", "appkit-color-success-surface", "appkit-color-warning", "appkit-color-warning-surface", "appkit-color-error", "appkit-color-error-surface", "appkit-color-info", "appkit-color-info-surface", "appkit-color-focus-ring", "appkit-shadow-glow", "appkit-shadow-glow-pink", "appkit-font-display", "appkit-font-sans", "appkit-font-editorial", "appkit-font-mono", "appkit-space-0-5", "appkit-space-1", "appkit-space-1-5", "appkit-space-2", "appkit-space-2-5", "appkit-space-3", "appkit-space-3-5", "appkit-space-4", "appkit-space-5", "appkit-space-6", "appkit-space-8", "appkit-space-10", "appkit-space-12", "appkit-space-14", "appkit-space-16", "appkit-space-18", "appkit-space-20", "appkit-space-24", "appkit-text-2xs", "appkit-text-xs", "appkit-text-sm", "appkit-text-base", "appkit-text-lg", "appkit-text-xl", "appkit-text-2xl", "appkit-text-3xl", "appkit-text-4xl", "appkit-text-5xl"];
13
+ export declare const REQUIRED_THEME_TOKENS: readonly ["appkit-color-primary", "appkit-color-primary-50", "appkit-color-primary-100", "appkit-color-primary-200", "appkit-color-primary-300", "appkit-color-primary-400", "appkit-color-primary-500", "appkit-color-primary-600", "appkit-color-primary-700", "appkit-color-primary-800", "appkit-color-primary-900", "appkit-color-primary-950", "appkit-color-secondary", "appkit-color-secondary-50", "appkit-color-secondary-100", "appkit-color-secondary-200", "appkit-color-secondary-300", "appkit-color-secondary-400", "appkit-color-secondary-500", "appkit-color-secondary-600", "appkit-color-secondary-700", "appkit-color-secondary-800", "appkit-color-secondary-900", "appkit-color-secondary-950", "appkit-color-bg", "appkit-color-surface", "appkit-color-surface-elevated", "appkit-color-surface-input", "appkit-color-border", "appkit-color-border-subtle", "appkit-color-text", "appkit-color-text-muted", "appkit-color-text-faint", "appkit-color-text-on-primary", "appkit-color-link", "appkit-color-success", "appkit-color-success-surface", "appkit-color-warning", "appkit-color-warning-surface", "appkit-color-error", "appkit-color-error-surface", "appkit-color-info", "appkit-color-info-surface", "appkit-color-focus-ring", "appkit-shadow-glow", "appkit-shadow-glow-pink", "appkit-font-display", "appkit-font-sans", "appkit-font-editorial", "appkit-font-mono", "appkit-space-0-5", "appkit-space-1", "appkit-space-1-5", "appkit-space-2", "appkit-space-2-5", "appkit-space-3", "appkit-space-3-5", "appkit-space-4", "appkit-space-5", "appkit-space-6", "appkit-space-8", "appkit-space-10", "appkit-space-12", "appkit-space-14", "appkit-space-16", "appkit-space-18", "appkit-space-20", "appkit-space-24", "appkit-text-2xs", "appkit-text-xs", "appkit-text-sm", "appkit-text-base", "appkit-text-lg", "appkit-text-xl", "appkit-text-2xl", "appkit-text-3xl", "appkit-text-4xl", "appkit-text-5xl"];
14
14
  export type RequiredThemeToken = (typeof REQUIRED_THEME_TOKENS)[number];
15
15
  export declare const REQUIRED_GRADIENT_KEYS: readonly GradientKey[];
@@ -47,6 +47,7 @@ export const REQUIRED_THEME_TOKENS = [
47
47
  "appkit-color-text-muted",
48
48
  "appkit-color-text-faint",
49
49
  "appkit-color-text-on-primary",
50
+ "appkit-color-link",
50
51
  // Status
51
52
  "appkit-color-success",
52
53
  "appkit-color-success-surface",
@@ -302,6 +302,15 @@
302
302
  --appkit-color-text-on-primary: #ffffff;
303
303
  --appkit-color-text-on-dark: #ffffff;
304
304
 
305
+ /* Link ink for long-form prose. A SEPARATE token because the right link
306
+ * colour is not the same ramp in every theme: default-light wants primary
307
+ * (teal), default-dark wants secondary (cyan) because its primary is a RED
308
+ * that reads as danger, and cobalt-night's primary IS blue. Binding prose
309
+ * links to `primary-600` instead would be #dc2626 on the dark theme.
310
+ * primary-700, not -600: #0d9488 is only 3.59:1 on --appkit-color-bg and
311
+ * fails AA for normal text; #0f766e is 5.24:1. */
312
+ --appkit-color-link: #0f766e; /* primary-700 — 5.24:1 on --appkit-color-bg */
313
+
305
314
  --appkit-color-success: #15803d; /* green-700 — 4.5:1 AA against success-surface, distinct from the new teal primary */
306
315
  --appkit-color-success-surface: #f0fdf4; /* green-50 */
307
316
  --appkit-color-warning: #b45309; /* amber-700 — 4.5:1 AA against warning-surface */
@@ -500,6 +509,8 @@
500
509
  --appkit-color-text-muted: #b4b4bd; /* lightened from zinc-400 #a1a1aa — ~9:1 on the dark page */
501
510
  --appkit-color-text-faint: #8b8b94; /* lightened from zinc-500 #71717a, which was ~3:1 and read as barely present */
502
511
 
512
+ --appkit-color-link: #22d3ee; /* secondary-400 — 11.16:1 on --appkit-color-bg. NOT primary: this theme's primary is crimson */
513
+
503
514
  --appkit-color-success: #34d399; /* emerald-400 */
504
515
  --appkit-color-success-surface: rgba(6, 78, 59, 0.25);
505
516
  --appkit-color-warning: #fbbf24; /* amber-400 */
@@ -620,6 +631,8 @@
620
631
  --appkit-color-text-muted: #bcd4ff; /* primary-200 */
621
632
  --appkit-color-text-faint: #8eb9ff; /* primary-300 */
622
633
 
634
+ --appkit-color-link: #5992ff; /* primary-500 — 5.17:1 on --appkit-color-bg */
635
+
623
636
  --appkit-color-success: #4ade80;
624
637
  --appkit-color-success-surface: rgba(20, 83, 45, 0.3);
625
638
  --appkit-color-warning: #fbbf24;
@@ -652,6 +665,8 @@
652
665
  --appkit-color-surface-elevated: #ffffff;
653
666
  --appkit-color-surface-input: #fffbeb; /* amber-50 */
654
667
 
668
+ --appkit-color-link: #b45309; /* amber-700 — 4.73:1 on --appkit-color-bg; primary-600 #d97706 is only 3.0:1 */
669
+
655
670
  /* --- Interactive surfaces ------------------------------------------------
656
671
  * `-hover` is the neutral chrome hover fill; `-raised` is a resting panel one
657
672
  * step off the page surface; `primary-surface` is the brand-tinted hover.
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { type DisclaimerId } from "../../_internal/shared/content/disclaimers";
3
+ import { type PublishedValues } from "../../_internal/shared/content/published-values";
4
+ export interface DisclaimerProps {
5
+ id: DisclaimerId;
6
+ /** Override the money figures with the admin's current configuration. */
7
+ publishedValues?: PublishedValues;
8
+ /**
9
+ * Render without the surrounding box — for a disclaimer that sits inside a
10
+ * card that already has chrome.
11
+ *
12
+ * 🛑 Does NOT make it smaller or quieter. A `warning`-tone entry keeps its
13
+ * tone inline, because the entries marked `warning` are the ones where
14
+ * ignoring the text has a consequence the reader cannot undo.
15
+ */
16
+ inline?: boolean;
17
+ className?: string;
18
+ }
19
+ export declare function Disclaimer({ id, publishedValues, inline, className, }: DisclaimerProps): React.JSX.Element | null;
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { Div, Stack, Text } from "../index.js";
4
+ import { DISCLAIMERS, } from "../../_internal/shared/content/disclaimers.js";
5
+ import { resolvePublishedCopy, resolvePublishedValues, } from "../../_internal/shared/content/published-values.js";
6
+ /**
7
+ * The one way to render a disclaimer (Phase 12).
8
+ *
9
+ * ## 🛑 `id` only — there is no `text` prop, deliberately
10
+ *
11
+ * A `text` escape hatch would make this a styled box, and then the legally
12
+ * material disclaimers would be written at their call sites again, drift, and
13
+ * end up weakest exactly where they matter most. That is the failure this
14
+ * registry exists to close. If a surface needs a disclaimer that does not
15
+ * exist, the fix is a new registry entry — which is also what gets it
16
+ * reviewed.
17
+ *
18
+ * ## Tokens resolve here
19
+ *
20
+ * The protection entry quotes `{{saleProtectionMaxValue}}` and the claim
21
+ * windows, so the published limits come from the constants that ENFORCE them
22
+ * (Phase 9's mechanism). A change to `SALE_PROTECTION_MAX_VALUE` updates the
23
+ * terms rather than contradicting them.
24
+ *
25
+ * Code-derived values are the default; a caller with settings in hand passes
26
+ * better ones for the money figures.
27
+ *
28
+ * ## Safe in a Server Component
29
+ *
30
+ * No hooks, no state, and the registry is a plain object — so this renders on
31
+ * either side of the boundary. Do not add state here without checking every
32
+ * RSC call site (Root Cause #76).
33
+ */
34
+ const CODE_DERIVED_VALUES = resolvePublishedValues();
35
+ /**
36
+ * Renders `**bold**` and nothing else.
37
+ *
38
+ * 🛑 A deliberately tiny subset, not a markdown renderer. The emphasis is
39
+ * load-bearing in exactly the places it is used — "**not insurance**" in the
40
+ * protection entry, "**under review**" versus "**verified**" in the scam
41
+ * registry — and those are the phrases a reader skims past without it.
42
+ *
43
+ * 🛑 And it returns ELEMENTS, never HTML. The bodies are our own constants so
44
+ * injection is not the risk; the risk is that a `dangerouslySetInnerHTML`
45
+ * here would invite someone to pass admin-editable text through it later,
46
+ * which is how a disclaimer box becomes a stored-XSS surface.
47
+ */
48
+ function renderEmphasis(text) {
49
+ return text.split(/(\*\*[^*]+\*\*)/g).map((part, i) => part.startsWith("**") && part.endsWith("**") && part.length > 4 ? (_jsx(Text, { as: "span", weight: "semibold", children: part.slice(2, -2) }, i)) : (_jsx(React.Fragment, { children: part }, i)));
50
+ }
51
+ export function Disclaimer({ id, publishedValues = CODE_DERIVED_VALUES, inline = false, className = "", }) {
52
+ const entry = DISCLAIMERS[id];
53
+ /*
54
+ * A `Record<DisclaimerId, …>` means this cannot happen through the type, but
55
+ * an `as DisclaimerId` cast at a call site could — and rendering nothing is
56
+ * the wrong failure here. A missing disclaimer is invisible, which is the
57
+ * whole problem; so it renders nothing only when the registry genuinely has
58
+ * no entry, and the audit is what catches that case before it ships.
59
+ */
60
+ if (!entry)
61
+ return null;
62
+ const body = resolvePublishedCopy(entry.body, publishedValues);
63
+ const content = (_jsxs(Stack, { gap: "xs", children: [entry.heading && (_jsx(Text, { size: "xs", weight: "semibold", transform: "uppercase", color: "muted", children: entry.heading })), _jsx(Text, { size: "xs", color: "muted", className: "leading-relaxed", children: renderEmphasis(body) })] }));
64
+ if (inline)
65
+ return _jsx(Div, { className: className, children: content });
66
+ /*
67
+ * 🛑 `surface` + the matching ink, never a status background with literal
68
+ * white text. `-surface` is a near-white tint in light themes and a dark
69
+ * tint in dark ones, so a fixed `text-white` is invisible in exactly one
70
+ * theme — Root Cause #67, which shipped 26 invisible surfaces that way.
71
+ * `Text color="muted"` above pairs correctly with both.
72
+ */
73
+ return (_jsx(Div, { surface: entry.tone === "warning" ? "warning-surface" : "muted", rounded: "lg", padding: "sm", className: className, children: content }));
74
+ }
@@ -20,9 +20,16 @@
20
20
  */
21
21
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
22
22
  /**
23
- * Slack used by the hysteresis rule below, in px. Matches
24
- * 2 x --appkit-tabs-arrow-size (2rem) — the width the two in-flow arrows
25
- * reclaim from the list when they unmount.
23
+ * Slack used by the hysteresis rule below, in px. Nominally
24
+ * 2 x --appkit-tabs-arrow-size (2rem), the width of the two in-flow arrows.
25
+ *
26
+ * 🛑 It is a SAFETY MARGIN, not a measurement, and the distinction is what
27
+ * this file got wrong badly enough to crash production. The arrows are not
28
+ * the only thing `data-arrows="true"` changes — it also hides the list's
29
+ * scrollbar — so the real width reclaimed on unmount is this number minus the
30
+ * platform scrollbar, and on a machine with overlay scrollbars it is this
31
+ * number exactly. The rule below is written to be stable for every value in
32
+ * that range rather than assuming one of them.
26
33
  */
27
34
  const ARROW_SLACK_PX = 64;
28
35
  /** Sub-pixel tolerance: scrollWidth/clientWidth can differ by <1px at some zooms. */
@@ -51,19 +58,65 @@ export function useTabsOverflow(listRef, activeKey) {
51
58
  const overflow = el.scrollWidth - el.clientWidth;
52
59
  const previous = stateRef.current.hasArrows;
53
60
  /*
54
- * 🛑 HYSTERESIS — do not collapse this to a single threshold.
61
+ * 🛑 HYSTERESIS — do not collapse this to a single threshold, and do not
62
+ * "tidy" the negative one below back to a positive number.
55
63
  *
56
64
  * The arrows are IN-FLOW, so mounting them shrinks the list's clientWidth
57
- * by ~ARROW_SLACK_PX, which INCREASES the measured overflow. With one
58
- * threshold a strip 10px wider than its container oscillates forever:
59
- * hidden -> overflow 10 -> show -> overflow 74 -> still overflowing
60
- * -> ... -> hide -> overflow -54 -> hide -> widen -> overflow 10 -> show
65
+ * and INCREASES the measured overflow. With one threshold a strip 10px
66
+ * wider than its container oscillates forever.
67
+ *
68
+ * ## 🛑 THE PREVIOUS RULE WAS `overflow > ARROW_SLACK_PX` AND IT CRASHED
69
+ * ## EVERY STORE PAGE IN PRODUCTION WITH React #185 (max update depth).
61
70
  *
62
- * Once the arrows are up they may only come down if the content would
71
+ * Its stability proof — "they may only come down if the content would
63
72
  * STILL fit after reclaiming their width, which by construction leaves
64
- * overflow <= 0 afterwards. That makes the rule provably stable.
73
+ * overflow <= 0" — rests on mounting the arrows changing the measured
74
+ * overflow by EXACTLY `ARROW_SLACK_PX`. That is true of the arrows alone
75
+ * and FALSE of the net effect, because of a rule 100 lines away in
76
+ * `Tabs.style.css`:
77
+ *
78
+ * .appkit-tabs-shell[data-arrows="true"] .appkit-tabs-list {
79
+ * scrollbar-width: none;
80
+ * }
81
+ * …__arrow is 2rem; …-list::-webkit-scrollbar { display: none }
82
+ *
83
+ * The same `data-arrows="true"` that mounts the arrows also HIDES the
84
+ * scrollbar, handing the list back ~15px of clientWidth. So the net
85
+ * reclaimed width is ~49px, not 64 — and for any strip overflowing by
86
+ * 2..15px the two thresholds each imply the other:
87
+ *
88
+ * hidden, overflow 10 -> 10 > 1 -> SHOW
89
+ * shown, overflow 59 -> 59 > 64? -> no -> HIDE
90
+ * hidden, overflow 10 -> …forever
91
+ *
92
+ * `useLayoutEffect` below runs on every render by design, so the loop is
93
+ * unbounded and React tears the tree down. The `sameState` guard cannot
94
+ * help: the state genuinely differs each pass.
95
+ *
96
+ * ## The rule now, stable for ANY reclaimed width
97
+ *
98
+ * Let r = whatever mounting the arrows adds to `overflow` (unknown, and
99
+ * provably NOT a constant — it depends on CSS this file cannot see, the
100
+ * platform's scrollbar width, and whether the user has overlay
101
+ * scrollbars). All we know is 0 <= r.
102
+ *
103
+ * show: hidden AND overflow > EPSILON
104
+ * hide: shown AND overflow <= -ARROW_SLACK_PX
105
+ *
106
+ * After SHOWING: overflow' = overflow + r > EPSILON >= -ARROW_SLACK_PX,
107
+ * so the hide test cannot fire. No loop.
108
+ * After HIDING: overflow' = overflow - r <= -ARROW_SLACK_PX <= EPSILON,
109
+ * so the show test cannot fire. No loop.
110
+ *
111
+ * Stable for every r >= 0, which is the point: the previous rule was
112
+ * stable only for one exact value of r that nothing enforced.
113
+ *
114
+ * The cost is deliberate conservatism — once up, the arrows stay up until
115
+ * the strip has a full ARROW_SLACK_PX of genuine slack. An arrow that
116
+ * lingers on a strip that just fits is a cosmetic blemish; the thing it
117
+ * replaces is a white screen.
65
118
  */
66
- const hasArrows = previous ? overflow > ARROW_SLACK_PX : overflow > EPSILON;
119
+ const hasArrows = previous ? overflow > -ARROW_SLACK_PX : overflow > EPSILON;
67
120
  const max = el.scrollWidth - el.clientWidth;
68
121
  // Math.abs: scrollLeft is negative (or inverted) in RTL depending on engine.
69
122
  const position = Math.abs(el.scrollLeft);
@@ -16,6 +16,8 @@ export type { SectionProps, SectionBackgroundConfig, ArticleProps, MainProps, As
16
16
  export { Section, sectionBackgroundStyle, Article, Main, Aside, Nav, BlockHeader, BlockFooter, Ul, Ol, Li, Table, Thead, Tbody, Tr, Th, Td, Code, Pre, Blockquote, Figure, Figcaption, Dl, Dt, Dd, } from "./components/Semantic";
17
17
  export type { DivProps } from "./components/Div";
18
18
  export { Div } from "./components/Div";
19
+ export { Disclaimer } from "./components/Disclaimer";
20
+ export type { DisclaimerProps } from "./components/Disclaimer";
19
21
  export type { SpecTableProps, SpecTableRow } from "./components/SpecTable";
20
22
  export { SpecTable } from "./components/SpecTable";
21
23
  export type { ColorVariant } from "./components/Typography";
package/dist/ui/index.js CHANGED
@@ -30,6 +30,12 @@ export { FormErrorSummary } from "./forms/index.js";
30
30
  export { buildColumns, createColumnBuilder, renderBoolean, renderCurrency, renderCurrencyCompact, renderCount, renderNullable, renderRating, getStatusTone, getResourceIcon, } from "./columns/index.js";
31
31
  export { Section, sectionBackgroundStyle, Article, Main, Aside, Nav, BlockHeader, BlockFooter, Ul, Ol, Li, Table, Thead, Tbody, Tr, Th, Td, Code, Pre, Blockquote, Figure, Figcaption, Dl, Dt, Dd, } from "./components/Semantic.js";
32
32
  export { Div } from "./components/Div.js";
33
+ /*
34
+ * Phase 12 — the one way to render a disclaimer. `id` only: there is no `text`
35
+ * prop, because an escape hatch would make it a styled box and the legally
36
+ * material disclaimers would be written at their call sites again.
37
+ */
38
+ export { Disclaimer } from "./components/Disclaimer.js";
33
39
  export { SpecTable } from "./components/SpecTable.js";
34
40
  export { Heading, Text, Label, Caption, Span } from "./components/Typography.js";
35
41
  // --- Filter chip group (SB10-C completion, S8 2026-05-13) --------------------
@@ -43,77 +43,42 @@
43
43
 
44
44
 
45
45
  /* --------------------------------------------------------------------------
46
- * THE PROSE PALETTE — rebound to appkit theme tokens.
46
+ * THE PROSE PALETTE LIVES IN THE CONSUMER, NOT HERE.
47
47
  *
48
- * 🛑 `dark:prose-invert` CANNOT COMPILE IN THIS PROJECT. Do not "fix" dark-mode
49
- * rich text by adding it to a call site, and do not add
50
- * `@source inline("dark:prose-invert")` to globals.css.
51
- *
52
- * Every `proseClass` string in appkit carries `dark:prose-invert` and NONE of
53
- * them has ever generated a rule, because:
54
- * - the consumer build excludes appkit from scanning
55
- * (`src/app/globals.css` → `@source not "../../appkit"`), and
56
- * - `appkit/tailwind.config.js` does not load `@tailwindcss/typography`,
57
- * so appkit's own `dist/tailwind-utilities.css` cannot emit it either.
58
- *
59
- * So `--tw-prose-invert-*` is DEFINED and never switched on. Every rich-text
60
- * surface on the site — product and auction descriptions, blog posts, policy
61
- * pages, FAQ answers, category `contentBody`, pre-orders, classifieds, digital
62
- * codes, live items, prize draws, events — rendered the light-theme palette in
63
- * every theme: body at gray-700 and links at gray-900, i.e. near-black on a
64
- * dark page. The links were effectively invisible.
48
+ * 🛑 Do NOT reinstate a `:root .prose { --tw-prose-*: ... !important }` block
49
+ * in this file. One lived here for months and it NEVER APPLIED.
65
50
  *
66
- * It was not merely unstyled, it was OVERRIDING: `important: true` in
67
- * `tailwind.config.js` emits `.prose :where(a) { color: var(--tw-prose-links)
68
- * !important }`, which beat the themed `.dark .appkit-rich-text a` rule further
69
- * down this file. All that theme-aware CSS was dead on arrival.
51
+ * The typography plugin emits `.prose { --tw-prose-*: <tailwind gray> }`, and
52
+ * the consumer's `important: true` makes each of those `!important` inside
53
+ * `@layer utilities`. The block here was unlayered, and justified itself with
54
+ * "`:root .prose` is (0,2,0) against `.prose`'s (0,1,0), so specificity
55
+ * decides and the outcome does not depend on bundle order."
70
56
  *
71
- * Rebinding the VARIABLES fixes it at the only point both problems meet: every
72
- * prose rule reads `var(--tw-prose-*)`, so one block re-themes body, links,
73
- * headings, bold, lists, quotes, captions, code and tables at once — in both
74
- * built-in themes AND in any admin-authored custom theme, which `prose-invert`
75
- * could never have done (its palette is hardcoded Tailwind grays).
57
+ * Specificity is never consulted. For the IMPORTANT tier, cascade-layer order
58
+ * is REVERSED and unlayered sorts LOWEST, so a layered `!important` beats an
59
+ * unlayered one at any specificity (Root Cause #106, measured in a browser).
60
+ * The plugin's hardcoded light-mode grays therefore won in every theme —
61
+ * links at gray-900, i.e. near-black on the near-black dark page, and
62
+ * black-instead-of-teal in light. The fix was invisible to every gate because
63
+ * the CSS was present and correct-looking in `dist/styles.css`; only a
64
+ * rendered page shows it losing.
76
65
  *
77
- * 🛑 The specificity is deliberate and must not be lowered. `.prose` declares
78
- * these variables with `!important`, so an equal-importance override is decided
79
- * by EMISSION ORDER between two separate stylesheets — the non-deterministic
80
- * trap of Root Cause #79. `:root .prose` is (0,2,0) against `.prose`'s (0,1,0),
81
- * so specificity decides and the outcome does not depend on bundle order. The
82
- * dark block at (0,3,0) also outranks `.dark .prose-invert` (0,2,0), so this
83
- * stays correct even if someone later makes `prose-invert` compile.
66
+ * Owner is now `tailwind.config.js` → `theme.extend.typography`, which makes
67
+ * the plugin emit the appkit tokens in the first place so there is exactly
68
+ * one declaration and no contest. Each binds to an `--appkit-color-*` that is
69
+ * redefined per theme, so prose re-themes for the built-in themes and for any
70
+ * admin-authored one.
84
71
  *
85
- * Not scoped to `.appkit-rich-text` on purpose: `PolicyPageView` and the scams
86
- * FAQ page apply `prose` to a bare `<div>` and had the identical defect.
72
+ * 🛑 `dark:prose-invert` CANNOT COMPILE IN THIS PROJECT. Do not "fix" dark
73
+ * rich text by adding it to a call site, and do not add
74
+ * `@source inline("dark:prose-invert")` to globals.css. Every `proseClass`
75
+ * string in appkit carries it and none has ever generated a rule, because the
76
+ * consumer build excludes appkit from scanning (`src/app/globals.css` →
77
+ * `@source not "../../appkit"`) and `appkit/tailwind.config.js` does not load
78
+ * `@tailwindcss/typography`, so appkit's own `dist/tailwind-utilities.css`
79
+ * cannot emit it either. It is moot now regardless: the tokens above invert on
80
+ * their own, which `prose-invert` could never do with its hardcoded grays.
87
81
  * -------------------------------------------------------------------------- */
88
- :root .prose {
89
- --tw-prose-body: var(--appkit-color-text-muted) !important;
90
- --tw-prose-headings: var(--appkit-color-text) !important;
91
- --tw-prose-lead: var(--appkit-color-text-muted) !important;
92
- --tw-prose-links: var(--appkit-color-primary-600) !important;
93
- --tw-prose-bold: var(--appkit-color-text) !important;
94
- --tw-prose-counters: var(--appkit-color-text-faint) !important;
95
- --tw-prose-bullets: var(--appkit-color-text-faint) !important;
96
- --tw-prose-hr: var(--appkit-color-border) !important;
97
- --tw-prose-quotes: var(--appkit-color-text) !important;
98
- --tw-prose-quote-borders: var(--appkit-color-primary) !important;
99
- --tw-prose-captions: var(--appkit-color-text-faint) !important;
100
- --tw-prose-kbd: var(--appkit-color-text) !important;
101
- --tw-prose-kbd-shadows: 24 24 27 !important;
102
- --tw-prose-code: var(--appkit-color-text) !important;
103
- --tw-prose-pre-code: var(--appkit-color-slate-200) !important;
104
- --tw-prose-pre-bg: var(--appkit-color-slate-800) !important;
105
- --tw-prose-th-borders: var(--appkit-color-border) !important;
106
- --tw-prose-td-borders: var(--appkit-color-border) !important;
107
- }
108
-
109
- /* Only the values that are genuinely theme-specific. Everything above already
110
- * inverts, because `--appkit-color-text`/`-text-muted`/`-border` are redefined
111
- * per theme in tokens.css — which is the whole point of binding to them. */
112
- :root.dark .prose {
113
- --tw-prose-links: var(--appkit-color-secondary-400) !important;
114
- --tw-prose-kbd-shadows: 250 250 250 !important;
115
- --tw-prose-pre-bg: var(--appkit-color-surface) !important;
116
- }
117
82
 
118
83
  /* --------------------------------------------------------------------------
119
84
  * Base wrapper. All selectors are scoped to .appkit-rich-text so they
@@ -200,27 +165,31 @@
200
165
  }
201
166
 
202
167
  /* --- Links ---------------------------------------------------------------- */
168
+ /* No `.dark` variant, deliberately: `--appkit-color-link` is redefined per
169
+ * theme, so one rule covers every theme including admin-authored ones. The two
170
+ * `.dark .appkit-rich-text a` rules that used to sit here were also dead —
171
+ * non-important against the plugin's `.prose :where(a){color:…!important}`.
172
+ *
173
+ * Decoration binds to `currentColor` rather than naming the token a second
174
+ * time. That matters beyond brevity: the colour here IS still overridden by
175
+ * the plugin on any element that also carries `.prose`, so a hardcoded
176
+ * decoration colour could disagree with the ink actually rendered. With
177
+ * `currentColor` the underline follows whatever won. */
203
178
  .appkit-rich-text a {
204
- color: var(--appkit-color-primary-600);
179
+ color: var(--appkit-color-link);
205
180
  text-decoration: underline;
206
- text-decoration-color: color-mix(in srgb, var(--appkit-color-primary-600) 60%, transparent);
181
+ text-decoration-color: color-mix(in srgb, currentColor 60%, transparent);
207
182
  text-underline-offset: 2px;
208
183
  transition: color 150ms, text-decoration-color 150ms;
209
184
  }
210
185
 
186
+ /* Hover moves the link toward the page's own text colour, which darkens it in
187
+ * a light theme and lightens it in a dark one — so this needs no per-theme
188
+ * pair either. The plugin sets no `a:hover`, so unlike the resting colour
189
+ * above this rule is genuinely the one in effect. */
211
190
  .appkit-rich-text a:hover {
212
- color: var(--appkit-color-primary-700);
213
- text-decoration-color: color-mix(in srgb, var(--appkit-color-primary-700) 70%, transparent);
214
- }
215
-
216
- .dark .appkit-rich-text a {
217
- color: var(--appkit-color-secondary-400);
218
- text-decoration-color: color-mix(in srgb, var(--appkit-color-secondary-400) 60%, transparent);
219
- }
220
-
221
- .dark .appkit-rich-text a:hover {
222
- color: var(--appkit-color-secondary-300);
223
- text-decoration-color: color-mix(in srgb, var(--appkit-color-secondary-300) 60%, transparent);
191
+ color: color-mix(in srgb, var(--appkit-color-link) 80%, var(--appkit-color-text));
192
+ text-decoration-color: currentColor;
224
193
  }
225
194
 
226
195
  /* --- Tables --------------------------------------------------------------- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "4.62.0",
3
+ "version": "4.62.1",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"