@mohasinac/appkit 4.11.1 → 4.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 (212) hide show
  1. package/dist/_internal/server/features/checkout/actions.d.ts +4 -0
  2. package/dist/_internal/server/features/checkout/actions.js +138 -27
  3. package/dist/_internal/server/features/checkout/data.d.ts +10 -0
  4. package/dist/_internal/server/features/checkout/locked-lines.d.ts +30 -0
  5. package/dist/_internal/server/features/checkout/locked-lines.js +116 -0
  6. package/dist/_internal/server/features/orders/adapters.js +7 -0
  7. package/dist/_internal/server/features/products/data.d.ts +12 -3
  8. package/dist/_internal/server/features/products/data.js +55 -4
  9. package/dist/_internal/server/features/products/index.d.ts +2 -1
  10. package/dist/_internal/server/features/products/index.js +2 -1
  11. package/dist/_internal/server/features/products/list-public.d.ts +130 -0
  12. package/dist/_internal/server/features/products/list-public.js +375 -0
  13. package/dist/_internal/server/features/reviews/data.d.ts +1 -1
  14. package/dist/_internal/server/features/reviews/data.js +3 -2
  15. package/dist/_internal/server/features/tester/visibility.js +3 -3
  16. package/dist/_internal/server/jobs/core/auctionSettlement.js +89 -16
  17. package/dist/_internal/server/jobs/core/offerExpiry.js +116 -4
  18. package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +1 -1
  19. package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +4 -1
  20. package/dist/_internal/server/jobs/core/testerSandboxRefresh.js +2 -0
  21. package/dist/_internal/server/jobs/handlers/_helpers.js +4 -1
  22. package/dist/_internal/server/jobs/handlers/messages.d.ts +5 -0
  23. package/dist/_internal/server/jobs/handlers/messages.js +5 -0
  24. package/dist/_internal/shared/checkout/lanes.d.ts +41 -0
  25. package/dist/_internal/shared/checkout/lanes.js +106 -0
  26. package/dist/_internal/shared/checkout/order-math.d.ts +19 -0
  27. package/dist/_internal/shared/checkout/order-math.js +30 -6
  28. package/dist/_internal/shared/features/promotions/schema.d.ts +0 -16
  29. package/dist/_internal/shared/features/promotions/schema.js +0 -2
  30. package/dist/_internal/shared/features/reviews/config.d.ts +8 -1
  31. package/dist/_internal/shared/features/reviews/config.js +8 -1
  32. package/dist/_internal/shared/listing-types/_registry.d.ts +88 -1
  33. package/dist/_internal/shared/listing-types/_registry.js +63 -1
  34. package/dist/_internal/shared/listing-types/art/config.d.ts +59 -0
  35. package/dist/_internal/shared/listing-types/art/config.js +12 -0
  36. package/dist/_internal/shared/listing-types/auction/config.d.ts +53 -0
  37. package/dist/_internal/shared/listing-types/auction/config.js +17 -0
  38. package/dist/_internal/shared/listing-types/classified/config.d.ts +59 -0
  39. package/dist/_internal/shared/listing-types/classified/config.js +14 -0
  40. package/dist/_internal/shared/listing-types/digital-code/config.d.ts +59 -0
  41. package/dist/_internal/shared/listing-types/digital-code/config.js +12 -0
  42. package/dist/_internal/shared/listing-types/feature-flags.d.ts +1 -0
  43. package/dist/_internal/shared/listing-types/feature-flags.js +24 -10
  44. package/dist/_internal/shared/listing-types/live/config.d.ts +59 -0
  45. package/dist/_internal/shared/listing-types/live/config.js +14 -0
  46. package/dist/_internal/shared/listing-types/pre-order/config.d.ts +110 -0
  47. package/dist/_internal/shared/listing-types/pre-order/config.js +14 -0
  48. package/dist/_internal/shared/listing-types/prize-draw/config.d.ts +44 -0
  49. package/dist/_internal/shared/listing-types/prize-draw/config.js +10 -0
  50. package/dist/_internal/shared/listing-types/standard/config.d.ts +59 -0
  51. package/dist/_internal/shared/listing-types/standard/config.js +9 -0
  52. package/dist/_internal/shared/listing-types/stickers/config.d.ts +59 -0
  53. package/dist/_internal/shared/listing-types/stickers/config.js +12 -0
  54. package/dist/client.d.ts +7 -2
  55. package/dist/client.js +8 -2
  56. package/dist/constants/field-names.d.ts +12 -0
  57. package/dist/constants/field-names.js +12 -0
  58. package/dist/constants/table-keys.d.ts +2 -0
  59. package/dist/constants/table-keys.js +2 -0
  60. package/dist/features/account/components/NotificationBell.js +1 -0
  61. package/dist/features/account/components/UserOffersPanel.js +8 -1
  62. package/dist/features/account/components/UserOrdersView.js +27 -5
  63. package/dist/features/admin/actions/notification-actions.js +1 -1
  64. package/dist/features/admin/components/AdminAddressesView.js +3 -1
  65. package/dist/features/admin/components/AdminCouponEditorView.js +1 -4
  66. package/dist/features/admin/components/AdminPaymentMethodsView.js +3 -1
  67. package/dist/features/admin/components/AdminProductsView.js +34 -18
  68. package/dist/features/admin/constants/filter-tabs.d.ts +26 -9
  69. package/dist/features/admin/constants/filter-tabs.js +22 -9
  70. package/dist/features/admin/schemas/firestore.d.ts +2 -1
  71. package/dist/features/admin/schemas/firestore.js +1 -0
  72. package/dist/features/auctions/actions/bid-actions.d.ts +11 -1
  73. package/dist/features/auctions/actions/bid-actions.js +29 -15
  74. package/dist/features/auctions/components/AuctionBidsTable.js +6 -2
  75. package/dist/features/auctions/components/AuctionBottomActions.js +1 -0
  76. package/dist/features/auctions/components/AuctionDetailPageView.js +13 -11
  77. package/dist/features/auctions/components/AuctionsListView.js +12 -53
  78. package/dist/features/auctions/components/PlaceBidFormClient.js +10 -1
  79. package/dist/features/auctions/repository/bid.repository.d.ts +15 -0
  80. package/dist/features/auctions/repository/bid.repository.js +19 -0
  81. package/dist/features/auctions/schemas/firestore.d.ts +11 -1
  82. package/dist/features/auctions/schemas/firestore.js +1 -0
  83. package/dist/features/cart/actions/cart-actions.d.ts +11 -0
  84. package/dist/features/cart/actions/cart-actions.js +24 -0
  85. package/dist/features/cart/repository/cart.repository.d.ts +24 -1
  86. package/dist/features/cart/repository/cart.repository.js +71 -6
  87. package/dist/features/cart/schemas/firestore.d.ts +23 -4
  88. package/dist/features/categories/components/BrandDetailTabs.js +31 -11
  89. package/dist/features/categories/components/CategoryDetailTabs.js +27 -7
  90. package/dist/features/categories/components/CategoryProductsListing.d.ts +9 -1
  91. package/dist/features/categories/components/CategoryProductsListing.js +5 -2
  92. package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -1
  93. package/dist/features/contact/email.js +56 -1
  94. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +17 -16
  95. package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
  96. package/dist/features/homepage/components/SectionCarousel.js +1 -1
  97. package/dist/features/homepage/components/ShopByCategorySection.js +1 -1
  98. package/dist/features/layout/AppLayoutShell.js +9 -2
  99. package/dist/features/layout/BottomActions.js +26 -3
  100. package/dist/features/layout/BottomActionsContext.d.ts +14 -0
  101. package/dist/features/layout/BottomActionsContext.js +13 -1
  102. package/dist/features/layout/hooks/useBottomActions.d.ts +6 -1
  103. package/dist/features/layout/hooks/useBottomActions.js +4 -1
  104. package/dist/features/layout/index.d.ts +1 -1
  105. package/dist/features/live/components/LiveItemDetailPageView.js +7 -6
  106. package/dist/features/orders/repository/orders.repository.d.ts +4 -15
  107. package/dist/features/orders/repository/orders.repository.js +4 -27
  108. package/dist/features/orders/types/index.d.ts +16 -0
  109. package/dist/features/orders/utils/order-splitter.js +14 -2
  110. package/dist/features/pre-orders/components/PreOrderBottomActions.d.ts +1 -1
  111. package/dist/features/pre-orders/components/PreOrderBottomActions.js +3 -19
  112. package/dist/features/pre-orders/components/PreOrdersListView.js +11 -39
  113. package/dist/features/products/components/ArtStickersListView.js +10 -49
  114. package/dist/features/products/components/AuctionsIndexListing.js +1 -2
  115. package/dist/features/products/components/ListingBottomActions.d.ts +28 -0
  116. package/dist/features/products/components/ListingBottomActions.js +25 -0
  117. package/dist/features/products/components/PrizeDrawBottomActions.d.ts +1 -1
  118. package/dist/features/products/components/PrizeDrawBottomActions.js +3 -21
  119. package/dist/features/products/components/ProductDetailActions.js +4 -0
  120. package/dist/features/products/components/ProductDetailPageView.js +7 -7
  121. package/dist/features/products/components/ProductsIndexPageView.js +9 -62
  122. package/dist/features/products/constants/listing-tabs.d.ts +43 -198
  123. package/dist/features/products/constants/listing-tabs.js +71 -58
  124. package/dist/features/products/constants/sieve.d.ts +104 -1
  125. package/dist/features/products/constants/sieve.js +27 -7
  126. package/dist/features/products/repository/products.repository.d.ts +45 -1
  127. package/dist/features/products/repository/products.repository.js +67 -8
  128. package/dist/features/products/utils/listing-badge-variant.d.ts +20 -1
  129. package/dist/features/products/utils/listing-badge-variant.js +26 -1
  130. package/dist/features/products/utils/listing-type.d.ts +24 -0
  131. package/dist/features/products/utils/listing-type.js +48 -0
  132. package/dist/features/promotions/actions/coupon-actions.d.ts +7 -0
  133. package/dist/features/promotions/actions/coupon-actions.js +12 -1
  134. package/dist/features/promotions/actions/coupon-stacking.d.ts +24 -0
  135. package/dist/features/promotions/actions/coupon-stacking.js +21 -0
  136. package/dist/features/promotions/actions/index.d.ts +1 -0
  137. package/dist/features/promotions/actions/index.js +1 -0
  138. package/dist/features/promotions/actions/seller-coupon-actions.d.ts +0 -1
  139. package/dist/features/promotions/actions/seller-coupon-actions.js +0 -1
  140. package/dist/features/promotions/components/CouponHelpDetails.d.ts +20 -0
  141. package/dist/features/promotions/components/CouponHelpDetails.js +17 -0
  142. package/dist/features/promotions/components/CouponsIndexListing.js +2 -1
  143. package/dist/features/promotions/components/index.d.ts +2 -0
  144. package/dist/features/promotions/components/index.js +1 -0
  145. package/dist/features/promotions/constants/coupon-help.d.ts +27 -0
  146. package/dist/features/promotions/constants/coupon-help.js +42 -0
  147. package/dist/features/promotions/repository/coupons.repository.d.ts +10 -1
  148. package/dist/features/promotions/repository/coupons.repository.js +22 -8
  149. package/dist/features/promotions/schemas/firestore.d.ts +0 -1
  150. package/dist/features/promotions/schemas/firestore.js +1 -1
  151. package/dist/features/promotions/schemas/index.d.ts +0 -20
  152. package/dist/features/promotions/schemas/index.js +0 -1
  153. package/dist/features/reviews/actions/review-actions.js +5 -1
  154. package/dist/features/reviews/components/ReviewDetailPageView.js +2 -1
  155. package/dist/features/reviews/components/ReviewFilters.d.ts +7 -1
  156. package/dist/features/reviews/components/ReviewFilters.js +4 -3
  157. package/dist/features/reviews/components/ReviewsIndexListing.d.ts +6 -0
  158. package/dist/features/reviews/components/ReviewsIndexListing.js +9 -109
  159. package/dist/features/reviews/components/ReviewsListingPanel.d.ts +41 -0
  160. package/dist/features/reviews/components/ReviewsListingPanel.js +226 -0
  161. package/dist/features/reviews/components/index.d.ts +2 -0
  162. package/dist/features/reviews/components/index.js +1 -0
  163. package/dist/features/reviews/hooks/useReviews.d.ts +8 -0
  164. package/dist/features/reviews/hooks/useReviews.js +14 -6
  165. package/dist/features/reviews/repository/reviews.repository.d.ts +29 -1
  166. package/dist/features/reviews/repository/reviews.repository.js +77 -41
  167. package/dist/features/reviews/types/index.d.ts +8 -1
  168. package/dist/features/seller/actions/offer-actions.d.ts +6 -0
  169. package/dist/features/seller/actions/offer-actions.js +8 -9
  170. package/dist/features/seller/components/SellerOffersView.d.ts +6 -1
  171. package/dist/features/seller/components/SellerOffersView.js +59 -8
  172. package/dist/features/seller/components/SellerProductsCards.js +2 -2
  173. package/dist/features/seller/components/SellerProductsView.js +21 -18
  174. package/dist/features/seller/repository/offer.repository.d.ts +18 -2
  175. package/dist/features/seller/repository/offer.repository.js +38 -2
  176. package/dist/features/seller/schemas/firestore.d.ts +7 -2
  177. package/dist/features/seller/schemas/firestore.js +3 -0
  178. package/dist/features/seller/schemas/offer-forms.d.ts +12 -0
  179. package/dist/features/seller/schemas/offer-forms.js +28 -0
  180. package/dist/features/stores/actions/store-query-actions.js +1 -1
  181. package/dist/features/stores/components/StoreAuctionsListing.js +5 -11
  182. package/dist/features/stores/components/StorePreOrdersListing.js +6 -11
  183. package/dist/features/stores/components/StoreReviewsListing.d.ts +4 -0
  184. package/dist/features/stores/components/StoreReviewsListing.js +7 -108
  185. package/dist/features/stores/schemas/index.d.ts +2 -2
  186. package/dist/features/tester/seed-data/coupons-tester-seed-data.js +3 -3
  187. package/dist/features/tester/seed-data/index.d.ts +1 -0
  188. package/dist/features/tester/seed-data/index.js +1 -0
  189. package/dist/features/tester/seed-data/offers-tester-seed-data.d.ts +2 -0
  190. package/dist/features/tester/seed-data/offers-tester-seed-data.js +61 -0
  191. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +337 -1
  192. package/dist/index.d.ts +11 -4
  193. package/dist/index.js +15 -3
  194. package/dist/react/hooks/useListingTypeFlags.d.ts +12 -19
  195. package/dist/react/hooks/useListingTypeFlags.js +4 -9
  196. package/dist/schemas/registry.d.ts +0 -12
  197. package/dist/seed/claimed-coupons-seed-data.js +3 -3
  198. package/dist/seed/coupons-seed-data.js +29 -10
  199. package/dist/seed/faq-seed-data.js +2 -2
  200. package/dist/seed/manifest.js +2 -2
  201. package/dist/server-entry.d.ts +1 -0
  202. package/dist/server-entry.js +1 -0
  203. package/dist/server.d.ts +1 -0
  204. package/dist/server.js +3 -0
  205. package/dist/styles.css +44 -39
  206. package/dist/tailwind-utilities.css +1 -1
  207. package/dist/ui/components/FilterChipGroup.d.ts +21 -3
  208. package/dist/ui/components/FilterChipGroup.js +33 -4
  209. package/dist/ui/components/HorizontalScroller.d.ts +1 -2
  210. package/dist/ui/components/HorizontalScroller.js +9 -5
  211. package/dist/ui/components/HorizontalScroller.style.css +43 -38
  212. package/package.json +1 -1
@@ -28,13 +28,31 @@ export interface FilterChipGroupProps {
28
28
  label: string;
29
29
  /** Tab definitions. Pass a constant from `appkit/src/features/admin/constants/filter-tabs.ts`. */
30
30
  tabs: readonly FilterChipGroupTab[];
31
- /** Current filter value (empty string = "All" selected). */
31
+ /**
32
+ * Current filter value. Single-select: one id, or `""` for "All".
33
+ * Multi-select (`multiple`): a pipe-joined set of ids (`"auction|art"`),
34
+ * `""` when nothing is ticked.
35
+ */
32
36
  value: string;
33
- /** Called with the new filter value (`""` when `All` is picked). */
37
+ /**
38
+ * Called with the new filter value. Single-select passes the picked id
39
+ * (`""` when `All` is picked); multi-select passes the whole pipe-joined
40
+ * set after toggling the clicked chip.
41
+ */
34
42
  onChange: (value: string) => void;
35
43
  /** Sentinel id treated as "no filter" — defaults to `"All"`. */
36
44
  allId?: string;
45
+ /**
46
+ * Checkbox semantics: several chips can be active at once and the value is
47
+ * a pipe-joined OR-group — the exact shape sievejs parses as a same-field OR
48
+ * and the Firebase adapter upgrades to a `.where(…, "in", …)` query.
49
+ *
50
+ * "Nothing ticked" already means "everything", so the `allId` sentinel chip
51
+ * is not rendered in this mode — it would be a second way to express the
52
+ * same state that every caller would have to remember to clear.
53
+ */
54
+ multiple?: boolean;
37
55
  /** Optional className spread onto the outer wrapper. */
38
56
  className?: string;
39
57
  }
40
- export declare function FilterChipGroup({ label, tabs, value, onChange, allId, className, }: FilterChipGroupProps): React.JSX.Element;
58
+ export declare function FilterChipGroup({ label, tabs, value, onChange, allId, multiple, className, }: FilterChipGroupProps): React.JSX.Element;
@@ -6,10 +6,39 @@ const ACTIVE_CLS = "bg-[var(--appkit-color-primary)] text-white border-[var(--ap
6
6
  const INACTIVE_CLS = "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-zinc-50 hover:bg-[var(--appkit-color-surface-elevated)]";
7
7
  const CHIP_BASE_CLS = "rounded-full px-3 py-1 text-xs font-medium border transition-colors";
8
8
  const LABEL_CLS = "text-xs font-semibold uppercase tracking-widest text-[var(--appkit-color-text-muted)]";
9
- export function FilterChipGroup({ label, tabs, value, onChange, allId = "All", className, }) {
9
+ /** Split a pipe-joined multi-select value into its ids. */
10
+ function parseMulti(value) {
11
+ return value ? value.split("|").filter(Boolean) : [];
12
+ }
13
+ export function FilterChipGroup({ label, tabs, value, onChange, allId = "All", multiple = false, className, }) {
14
+ const selected = new Set(multiple ? parseMulti(value) : []);
10
15
  const current = value || allId;
11
- return (_jsxs(Div, { className: `space-y-2 ${className ?? ""}`.trim(), children: [_jsx(Text, { as: "p", className: LABEL_CLS, children: label }), _jsx(Div, { className: "flex flex-wrap gap-2", children: tabs.map((tab) => {
12
- const isActive = current === tab.id;
13
- return (_jsx("button", { type: "button", "aria-pressed": isActive, onClick: () => onChange(tab.id === allId ? "" : tab.id), className: `${CHIP_BASE_CLS} ${isActive ? ACTIVE_CLS : INACTIVE_CLS}`, children: tab.label }, tab.id));
16
+ // In multi-select the "All" sentinel is redundant with an empty selection
17
+ // see the `multiple` prop docs.
18
+ const visibleTabs = multiple ? tabs.filter((t) => t.id !== allId) : tabs;
19
+ const handleClick = (tabId) => {
20
+ if (!multiple) {
21
+ onChange(tabId === allId ? "" : tabId);
22
+ return;
23
+ }
24
+ // Rebuild in the source array's order, not click order, so the same
25
+ // selection always serialises to the same string — a value that varied by
26
+ // click order would be a different React Query key for identical results.
27
+ const next = new Set(selected);
28
+ if (next.has(tabId))
29
+ next.delete(tabId);
30
+ else
31
+ next.add(tabId);
32
+ onChange(visibleTabs
33
+ .map((t) => t.id)
34
+ .filter((id) => next.has(id))
35
+ .join("|"));
36
+ };
37
+ return (_jsxs(Div, { className: `space-y-2 ${className ?? ""}`.trim(), children: [_jsx(Text, { as: "p", className: LABEL_CLS, children: label }), _jsx(Div, { className: "flex flex-wrap gap-2", role: multiple ? "group" : undefined, "aria-label": multiple ? label : undefined, children: visibleTabs.map((tab) => {
38
+ const isActive = multiple ? selected.has(tab.id) : current === tab.id;
39
+ return (_jsx("button", { type: "button",
40
+ // Checkboxes report checked state, not pressed state — a screen
41
+ // reader announcing "pressed" for a filter that stays on is wrong.
42
+ role: multiple ? "checkbox" : undefined, "aria-checked": multiple ? isActive : undefined, "aria-pressed": multiple ? undefined : isActive, onClick: () => handleClick(tab.id), className: `${CHIP_BASE_CLS} ${isActive ? ACTIVE_CLS : INACTIVE_CLS}`, children: tab.label }, tab.id));
14
43
  }) })] }));
15
44
  }
@@ -22,7 +22,6 @@ export interface HorizontalScrollerProps<T = unknown> {
22
22
  */
23
23
  arrowStyle?: "circle" | "full-height";
24
24
  showScrollbar?: boolean;
25
- showFadeEdges?: boolean;
26
25
  scrollContainerRef?: RefObject<HTMLDivElement | null>;
27
26
  onScroll?: () => void;
28
27
  items?: T[];
@@ -38,4 +37,4 @@ export interface HorizontalScrollerProps<T = unknown> {
38
37
  /** When the scroller reaches the last item, snap instantly back to the first instead of stopping. */
39
38
  loop?: boolean;
40
39
  }
41
- export declare function HorizontalScroller<T = unknown>({ children, className, gap, snapToItems, showArrows, arrowSize, arrowStyle, showScrollbar, showFadeEdges, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows, autoScroll, autoScrollInterval, minItemWidth, pauseOnHover, itemClassName, loop, }: HorizontalScrollerProps<T>): import("react").JSX.Element;
40
+ export declare function HorizontalScroller<T = unknown>({ children, className, gap, snapToItems, showArrows, arrowSize, arrowStyle, showScrollbar, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows, autoScroll, autoScrollInterval, minItemWidth, pauseOnHover, itemClassName, loop, }: HorizontalScrollerProps<T>): import("react").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useRef, useState, useEffect, useCallback, } from "react";
4
4
  import { ChevronLeft, ChevronRight } from "lucide-react";
5
5
  const BREAKPOINTS = [
@@ -21,7 +21,7 @@ function resolvePerView(perView, containerWidth) {
21
21
  }
22
22
  return 1;
23
23
  }
24
- export function HorizontalScroller({ children, className = "", gap = 16, snapToItems, showArrows, arrowSize = "md", arrowStyle = "circle", showScrollbar, showFadeEdges, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows = 1, autoScroll, autoScrollInterval = 3500, minItemWidth, pauseOnHover = false, itemClassName = "", loop = false, }) {
24
+ export function HorizontalScroller({ children, className = "", gap = 16, snapToItems, showArrows, arrowSize = "md", arrowStyle = "circle", showScrollbar, scrollContainerRef: externalRef, onScroll, items, renderItem, keyExtractor, perView, rows = 1, autoScroll, autoScrollInterval = 3500, minItemWidth, pauseOnHover = false, itemClassName = "", loop = false, }) {
25
25
  const [itemWidth, setItemWidth] = useState(undefined);
26
26
  const [colCount, setColCount] = useState(typeof perView === "number" ? perView : 3);
27
27
  const [isPaused, setIsPaused] = useState(false);
@@ -200,11 +200,15 @@ export function HorizontalScroller({ children, className = "", gap = 16, snapToI
200
200
  const prevDisabled = !loop && atStart;
201
201
  const nextDisabled = !loop && atEnd;
202
202
  const arrowsHidden = !loop && atStart && atEnd; // no scrollable overflow
203
- return (_jsxs("div", { className: ["appkit-hscroller appkit-hscroller--with-arrows", className]
203
+ return (_jsxs("div", { className: [
204
+ "appkit-hscroller appkit-hscroller--with-arrows",
205
+ `appkit-hscroller--arrow-${arrowSize}`,
206
+ className,
207
+ ]
204
208
  .filter(Boolean)
205
- .join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-511", children: [showFadeEdges && (_jsxs(_Fragment, { children: [_jsx("div", { className: "appkit-hscroller__fade appkit-hscroller__fade--left" }), _jsx("div", { className: "appkit-hscroller__fade appkit-hscroller__fade--right" })] })), !arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(-1), "aria-label": "Previous", "aria-disabled": prevDisabled || undefined, disabled: prevDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--prev appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronLeft, { className: "w-4 h-4" }) })), _jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px`, paddingLeft: 36, paddingRight: 36 }, "data-section": "horizontalscroller-div-512", children: content }), !arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(1), "aria-label": "Next", "aria-disabled": nextDisabled || undefined, disabled: nextDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--next appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronRight, { className: "w-4 h-4" }) }))] }));
209
+ .join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-511", children: [!arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(-1), "aria-label": "Previous", "aria-disabled": prevDisabled || undefined, disabled: prevDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--prev appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronLeft, { className: "w-4 h-4" }) })), _jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px` }, "data-section": "horizontalscroller-div-512", children: content }), !arrowsHidden && (_jsx("button", { type: "button", onClick: () => scrollBy(1), "aria-label": "Next", "aria-disabled": nextDisabled || undefined, disabled: nextDisabled, className: `appkit-hscroller__arrow appkit-hscroller__arrow--next appkit-hscroller__arrow--${arrowSize} ${arrowStyle === "full-height" ? "appkit-hscroller__arrow--full-height" : ""}`, children: _jsx(ChevronRight, { className: "w-4 h-4" }) }))] }));
206
210
  }
207
- return (_jsxs("div", { className: ["appkit-hscroller", className].filter(Boolean).join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-513", children: [showFadeEdges && (_jsxs(_Fragment, { children: [_jsx("div", { className: "appkit-hscroller__fade appkit-hscroller__fade--left" }), _jsx("div", { className: "appkit-hscroller__fade appkit-hscroller__fade--right" })] })), _jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px` }, "data-section": "horizontalscroller-div-514", children: content })] }));
211
+ return (_jsx("div", { className: ["appkit-hscroller", className].filter(Boolean).join(" "), tabIndex: 0, onKeyDown: handleKeyDown, ...interactionHandlers, "data-section": "horizontalscroller-div-513", children: _jsx("div", { ref: containerRef, onScroll: combinedOnScroll, className: scrollerCls(snapToItems, showScrollbar), style: { gap: `${gap}px` }, "data-section": "horizontalscroller-div-514", children: content }) }));
208
212
  }
209
213
  function scrollerCls(snapToItems, showScrollbar) {
210
214
  return [
@@ -50,9 +50,38 @@
50
50
 
51
51
  /* -- Arrows ------------------------------------------ */
52
52
 
53
- .appkit-hscroller--with-arrows .appkit-hscroller__track {
54
- padding-left: 36px;
55
- padding-right: 36px;
53
+ /* Component-local custom properties — never added to tokens.css, so
54
+ * audit-theme-drift.mjs's stray-key check can't fire on them. Default
55
+ * gutter is 0 so the no-arrows variant is untouched. --arrow-size defaults
56
+ * to the old hardcoded 36px ("md") and is overridden by the
57
+ * --arrow-{sm,md,lg} modifiers below. */
58
+ .appkit-hscroller {
59
+ --appkit-hscroller-arrow-size: 2.25rem;
60
+ --appkit-hscroller-gutter: 0px;
61
+ }
62
+
63
+ .appkit-hscroller--arrow-sm { --appkit-hscroller-arrow-size: 1.75rem; }
64
+ .appkit-hscroller--arrow-md { --appkit-hscroller-arrow-size: 2.25rem; }
65
+ .appkit-hscroller--arrow-lg { --appkit-hscroller-arrow-size: 2.75rem; }
66
+
67
+ /* Arrows only render at sm+ — below that, touch users swipe and reserving
68
+ * gutter space would eat into an already-narrow single-column card. Gutter
69
+ * lives on the WRAPPER (padding box), not the scrollable track, so items
70
+ * are clipped at the gutter's inner edge instead of scrolling underneath
71
+ * an absolutely-positioned arrow. */
72
+ .appkit-hscroller__arrow {
73
+ display: none;
74
+ }
75
+
76
+ @media (min-width: 640px) {
77
+ .appkit-hscroller--with-arrows {
78
+ --appkit-hscroller-gutter: calc(var(--appkit-hscroller-arrow-size) + var(--appkit-space-2));
79
+ padding-left: var(--appkit-hscroller-gutter);
80
+ padding-right: var(--appkit-hscroller-gutter);
81
+ }
82
+ .appkit-hscroller--with-arrows .appkit-hscroller__arrow {
83
+ display: flex;
84
+ }
56
85
  }
57
86
 
58
87
  .appkit-hscroller__arrow {
@@ -60,11 +89,12 @@
60
89
  top: 50%;
61
90
  transform: translateY(-50%);
62
91
  z-index: 20;
92
+ width: var(--appkit-hscroller-arrow-size);
93
+ height: var(--appkit-hscroller-arrow-size);
63
94
  border-radius: 9999px;
64
95
  background: rgba(255, 255, 255, 0.9);
65
96
  border: 1px solid var(--appkit-color-border);
66
97
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
67
- display: flex;
68
98
  align-items: center;
69
99
  justify-content: center;
70
100
  transition: background 150ms;
@@ -80,18 +110,20 @@
80
110
  pointer-events: none;
81
111
  }
82
112
 
83
- .appkit-hscroller__arrow--prev { left: 0; }
84
- .appkit-hscroller__arrow--next { right: 0; }
113
+ /* Centered within the gutter (gutter = arrow size + space-2 breathing room). */
114
+ .appkit-hscroller__arrow--prev { left: calc((var(--appkit-hscroller-gutter) - var(--appkit-hscroller-arrow-size)) / 2); }
115
+ .appkit-hscroller__arrow--next { right: calc((var(--appkit-hscroller-gutter) - var(--appkit-hscroller-arrow-size)) / 2); }
85
116
 
86
- .appkit-hscroller__arrow--sm { width: 1.75rem; height: 1.75rem; font-size: 0.875rem; }
87
- .appkit-hscroller__arrow--md { width: 2.25rem; height: 2.25rem; font-size: 1rem; }
88
- .appkit-hscroller__arrow--lg { width: 2.75rem; height: 2.75rem; font-size: 1.125rem; }
117
+ .appkit-hscroller__arrow--sm { font-size: 0.875rem; }
118
+ .appkit-hscroller__arrow--md { font-size: 1rem; }
119
+ .appkit-hscroller__arrow--lg { font-size: 1.125rem; }
89
120
 
90
121
  /* Full-height variant — a thin sliver spanning the whole track height
91
122
  * instead of a small centered circle, so a double-row grid of cards has a
92
123
  * much taller, easier-to-hit click target on either side. Width still comes
93
- * from the --sm/--md/--lg size classes above; this only overrides the
94
- * vertical sizing/position and squares off the rounding on the outer edge. */
124
+ * from --appkit-hscroller-arrow-size via the --sm/--md/--lg modifiers above;
125
+ * this only overrides the vertical sizing/position and squares off the
126
+ * rounding on the outer edge. */
95
127
  .appkit-hscroller__arrow--full-height {
96
128
  top: 0;
97
129
  height: 100%;
@@ -119,30 +151,3 @@
119
151
  background: var(--appkit-color-slate-700);
120
152
  }
121
153
 
122
- /* -- Fade edges -------------------------------------- */
123
-
124
- .appkit-hscroller__fade {
125
- position: absolute;
126
- top: 0;
127
- bottom: 0;
128
- width: 2rem;
129
- z-index: var(--appkit-z-raised);
130
- pointer-events: none;
131
- }
132
-
133
- .appkit-hscroller__fade--left {
134
- left: 0;
135
- background: linear-gradient(to right, var(--appkit-color-surface), transparent);
136
- }
137
-
138
- .appkit-hscroller__fade--right {
139
- right: 0;
140
- background: linear-gradient(to left, var(--appkit-color-surface), transparent);
141
- }
142
-
143
- .dark .appkit-hscroller__fade--left {
144
- background: linear-gradient(to right, var(--appkit-color-surface), transparent);
145
- }
146
- .dark .appkit-hscroller__fade--right {
147
- background: linear-gradient(to left, var(--appkit-color-surface), transparent);
148
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "4.11.1",
3
+ "version": "4.11.3",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"