@mohasinac/appkit 3.9.1 → 4.0.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 (58) hide show
  1. package/dist/_internal/shared/actions/action-registry.js +8 -0
  2. package/dist/client.d.ts +2 -2
  3. package/dist/client.js +1 -4
  4. package/dist/constants/api-endpoints.d.ts +3 -0
  5. package/dist/constants/api-endpoints.js +1 -0
  6. package/dist/features/account/hooks/useDataViewMode.d.ts +17 -0
  7. package/dist/features/account/hooks/useDataViewMode.js +55 -0
  8. package/dist/features/account/hooks/useProfile.d.ts +2 -0
  9. package/dist/features/admin/components/AdminBundlesView.d.ts +3 -4
  10. package/dist/features/admin/components/AdminBundlesView.js +2 -2
  11. package/dist/features/admin/components/AdminCarouselView.js +1 -1
  12. package/dist/features/admin/components/AdminCategoriesView.d.ts +2 -6
  13. package/dist/features/admin/components/AdminCategoriesView.js +1 -1
  14. package/dist/features/admin/components/AdminFaqsView.d.ts +0 -2
  15. package/dist/features/admin/components/AdminPrizeDrawsView.js +1 -1
  16. package/dist/features/admin/components/DataListingView.d.ts +8 -2
  17. package/dist/features/admin/components/DataListingView.js +7 -3
  18. package/dist/features/admin/components/DataTable.d.ts +10 -2
  19. package/dist/features/admin/components/DataTable.js +4 -2
  20. package/dist/features/admin/hooks/useAdminListing.d.ts +2 -2
  21. package/dist/features/admin/hooks/useAdminListing.js +6 -1
  22. package/dist/features/categories/components/BrandDetailTabs.js +2 -12
  23. package/dist/features/categories/components/CategoryDetailTabs.js +2 -12
  24. package/dist/features/events/components/AdminEventsView.d.ts +1 -5
  25. package/dist/features/faq/components/FAQAccordion.js +3 -2
  26. package/dist/features/faq/components/RelatedFAQs.js +1 -1
  27. package/dist/features/homepage/components/FAQSection.js +3 -3
  28. package/dist/features/layout/FooterLayout.js +2 -2
  29. package/dist/features/lottery/schemas/zod.d.ts +4 -4
  30. package/dist/features/payments/schemas/firestore.d.ts +6 -0
  31. package/dist/features/payments/schemas/firestore.js +2 -0
  32. package/dist/features/seller/components/SellerBundlesView.d.ts +3 -4
  33. package/dist/features/seller/components/SellerBundlesView.js +2 -2
  34. package/dist/features/seller/components/SellerPayoutsView.d.ts +2 -5
  35. package/dist/features/seller/components/SellerPayoutsView.js +100 -21
  36. package/dist/features/seller/components/SellerPreOrdersView.js +1 -1
  37. package/dist/features/seller/components/SellerPrizeDrawsView.js +1 -1
  38. package/dist/features/seller/components/SellerProductsView.js +6 -2
  39. package/dist/features/shipments/components/AdminShipmentsView.d.ts +1 -5
  40. package/dist/index.d.ts +3 -5
  41. package/dist/index.js +3 -3
  42. package/dist/react/index.d.ts +0 -2
  43. package/dist/react/index.js +0 -2
  44. package/dist/seed/faq-seed-data.js +11 -11
  45. package/dist/seed/homepage-sections-seed-data.js +1 -1
  46. package/dist/styles.css +30 -99
  47. package/dist/tailwind-utilities.css +1 -1
  48. package/dist/ui/DataTable.js +1 -1
  49. package/dist/ui/DataTable.style.css +10 -0
  50. package/dist/ui/components/DetailPageTabs.d.ts +1 -1
  51. package/dist/ui/components/DetailPageTabs.js +6 -30
  52. package/dist/ui/components/Tabs.d.ts +9 -1
  53. package/dist/ui/components/Tabs.js +13 -8
  54. package/dist/ui/components/Tabs.style.css +19 -0
  55. package/dist/ui/components/index.style.css +0 -1
  56. package/dist/ui/index.d.ts +0 -2
  57. package/dist/ui/index.js +0 -1
  58. package/package.json +1 -1
@@ -123,7 +123,7 @@ pageSize: pageSizeProp, stickyHeader: stickyHeaderProp, striped: stripedProp, sh
123
123
  mobileCardRender &&
124
124
  renderCardGrid(activeViewMode), activeViewMode === "table" && mobileCardRender && (_jsx(Div, { className: "appkit-data-table__mobile-cards", children: paginatedData.map((item) => (_jsx(SelectableCard, { id: keyExtractor(item), selectable: selectable, selected: selectedIds.includes(keyExtractor(item)), onToggle: (id, checked) => onSelectionChange?.(checked
125
125
  ? [...selectedIds, id]
126
- : selectedIds.filter((s) => s !== id)), children: mobileCardRender(item) }, keyExtractor(item)))) })), activeViewMode === "table" && (_jsx(Div, { className: "appkit-data-table__wrapper", children: _jsx(Div, { className: `appkit-data-table__scroll ${stickyHeader ? "appkit-data-table__scroll--sticky" : ""}`, children: _jsxs("table", { className: "appkit-data-table__table", children: [_jsx("thead", { className: `appkit-data-table__thead ${stickyHeader ? "appkit-data-table__thead--sticky" : ""}`, children: _jsxs("tr", { children: [selectable && (_jsx("th", { scope: "col", className: "px-4 py-3 w-8", children: _jsx(Checkbox, { bare: true, className: CLS_CHECKBOX, "aria-label": "Select all on page", checked: paginatedData.length > 0 &&
126
+ : selectedIds.filter((s) => s !== id)), children: mobileCardRender(item) }, keyExtractor(item)))) })), activeViewMode === "table" && (_jsx(Div, { className: `appkit-data-table__wrapper ${mobileCardRender ? "appkit-data-table__wrapper--has-mobile-cards" : ""}`, children: _jsx(Div, { className: `appkit-data-table__scroll ${stickyHeader ? "appkit-data-table__scroll--sticky" : ""}`, children: _jsxs("table", { className: "appkit-data-table__table", children: [_jsx("thead", { className: `appkit-data-table__thead ${stickyHeader ? "appkit-data-table__thead--sticky" : ""}`, children: _jsxs("tr", { children: [selectable && (_jsx("th", { scope: "col", className: "px-4 py-3 w-8", children: _jsx(Checkbox, { bare: true, className: CLS_CHECKBOX, "aria-label": "Select all on page", checked: paginatedData.length > 0 &&
127
127
  paginatedData.every((item) => selectedIds.includes(keyExtractor(item))), onChange: (e) => {
128
128
  const pageIds = paginatedData.map(keyExtractor);
129
129
  onSelectionChange?.(e.target.checked
@@ -190,3 +190,13 @@
190
190
  display: none;
191
191
  }
192
192
  }
193
+
194
+ /* When mobileCardRender is supplied, the desktop table wrapper must hide
195
+ below the same breakpoint the mobile-cards block uses above — otherwise
196
+ both render simultaneously on small screens. Wrapper has no modifier
197
+ (and always renders) when mobileCardRender is absent. */
198
+ @media (max-width: 767px) {
199
+ .appkit-data-table__wrapper--has-mobile-cards {
200
+ display: none;
201
+ }
202
+ }
@@ -31,4 +31,4 @@ export interface DetailPageTabsProps {
31
31
  *
32
32
  * W1-14 — extracted 2026-05-23.
33
33
  */
34
- export declare function DetailPageTabs({ tabs, activeTab: activeTabProp, defaultTab, onTabChange, className, }: DetailPageTabsProps): React.JSX.Element;
34
+ export declare function DetailPageTabs({ tabs, activeTab, defaultTab, onTabChange, className, }: DetailPageTabsProps): React.JSX.Element;
@@ -1,11 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState } from "react";
4
3
  import { Div } from "./Div";
5
- import { Span } from "./Typography";
6
- const __O = {
7
- xAuto: "overflow-x-auto",
8
- };
4
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./Tabs";
9
5
  /**
10
6
  * `DetailPageTabs` — tab shell used by Product, Auction and Event detail
11
7
  * pages. Renders an accessible trigger strip + a single visible panel.
@@ -14,29 +10,9 @@ const __O = {
14
10
  *
15
11
  * W1-14 — extracted 2026-05-23.
16
12
  */
17
- export function DetailPageTabs({ tabs, activeTab: activeTabProp, defaultTab, onTabChange, className, }) {
18
- const [internalActive, setInternalActive] = useState(defaultTab ?? tabs[0]?.id ?? "");
19
- const activeTab = activeTabProp ?? internalActive;
20
- const active = tabs.find((t) => t.id === activeTab) ?? tabs[0];
21
- const handleChange = (id) => {
22
- if (activeTabProp === undefined)
23
- setInternalActive(id);
24
- onTabChange?.(id);
25
- };
26
- return (_jsxs(Div, { className: [
27
- "appkit-detail-tabs",
28
- "space-y-4",
29
- className,
30
- ]
31
- .filter(Boolean)
32
- .join(" "), children: [_jsx(Div, { role: "tablist", "aria-orientation": "horizontal", className: `flex gap-2 border-b border-[var(--appkit-color-border)] ${__O.xAuto}`, children: tabs.map((tab) => {
33
- const isActive = tab.id === active?.id;
34
- return (_jsxs("button", { type: "button", role: "tab", "aria-selected": isActive, "aria-controls": `detail-tab-panel-${tab.id}`, id: `detail-tab-trigger-${tab.id}`, disabled: tab.disabled, onClick: () => handleChange(tab.id), className: [
35
- "flex-shrink-0 px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors",
36
- isActive
37
- ? "border-[var(--appkit-color-primary)] text-[var(--appkit-color-text)]"
38
- : "border-transparent text-[var(--appkit-color-text-muted)] hover:text-zinc-700 hover:text-[var(--appkit-color-text-muted)]",
39
- tab.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer",
40
- ].join(" "), children: [tab.label, typeof tab.count === "number" ? (_jsx(Span, { size: "xs", className: "ml-2 inline-flex items-center justify-center rounded-full bg-[var(--appkit-color-surface)] px-2 py-0.5", children: tab.count })) : null] }, tab.id));
41
- }) }), active ? (_jsx(Div, { role: "tabpanel", id: `detail-tab-panel-${active.id}`, "aria-labelledby": `detail-tab-trigger-${active.id}`, children: active.content })) : null] }));
13
+ export function DetailPageTabs({ tabs, activeTab, defaultTab, onTabChange, className, }) {
14
+ return (_jsxs(Tabs, { value: activeTab, defaultValue: defaultTab ?? tabs[0]?.id ?? "", onChange: onTabChange, className: ["appkit-detail-tabs", "space-y-4", className].filter(Boolean).join(" "), children: [_jsx(TabsList, { children: tabs.map((tab) => {
15
+ const label = typeof tab.label === "string" ? tab.label : undefined;
16
+ return (_jsx(TabsTrigger, { value: tab.id, disabled: tab.disabled, badge: tab.count, label: label, children: tab.label }, tab.id));
17
+ }) }), tabs.map((tab) => (_jsx(TabsContent, { value: tab.id, children: _jsx(Div, { children: tab.content }) }, tab.id)))] }));
42
18
  }
@@ -15,6 +15,14 @@ export interface TabsTriggerProps {
15
15
  disabled?: boolean;
16
16
  className?: string;
17
17
  children?: React.ReactNode;
18
+ /** Optional count badge rendered as a small pill after the label. */
19
+ badge?: number;
20
+ /**
21
+ * Plain-text label to use for the collapsed mobile dropdown's option text
22
+ * when `children` isn't a plain string (e.g. it renders a badge pill).
23
+ * Falls back to `value` when omitted and `children` isn't a string.
24
+ */
25
+ label?: string;
18
26
  }
19
27
  export interface TabsContentProps {
20
28
  value: string;
@@ -23,6 +31,6 @@ export interface TabsContentProps {
23
31
  }
24
32
  export declare function Tabs({ defaultValue, value, onChange, className, children, }: TabsProps): React.JSX.Element;
25
33
  export declare function TabsList({ className, children }: TabsListProps): React.JSX.Element;
26
- export declare function TabsTrigger({ value, disabled, className, children, }: TabsTriggerProps): React.JSX.Element;
34
+ export declare function TabsTrigger({ value, disabled, className, children, badge, }: TabsTriggerProps): React.JSX.Element;
27
35
  export declare function TabsContent({ value, className, children, }: TabsContentProps): React.JSX.Element | null;
28
36
  export default Tabs;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import React, { createContext, useContext, useMemo, useState } from "react";
4
4
  import { Select } from "./Select";
5
5
  const UI_TABS = {
@@ -7,6 +7,7 @@ const UI_TABS = {
7
7
  listDropdown: "appkit-tabs-list--dropdown",
8
8
  trigger: "appkit-tabs-trigger",
9
9
  content: "appkit-tabs-content",
10
+ badge: "appkit-tabs-trigger__badge",
10
11
  };
11
12
  /** Past this many items, TabsList renders a <Select> dropdown instead of a
12
13
  * horizontal row — a scrollable row of 6+ tabs is unreadable/unreachable on
@@ -34,19 +35,23 @@ export function TabsList({ className = "", children }) {
34
35
  const { active, setActive } = useContext(TabsContext);
35
36
  const items = React.Children.toArray(children).filter((child) => React.isValidElement(child));
36
37
  if (items.length > TABS_DROPDOWN_THRESHOLD) {
37
- const options = items.map((item) => ({
38
- value: item.props.value,
39
- label: typeof item.props.children === "string" ? item.props.children : item.props.value,
40
- disabled: item.props.disabled,
41
- }));
38
+ const options = items.map((item) => {
39
+ const baseLabel = item.props.label ??
40
+ (typeof item.props.children === "string" ? item.props.children : item.props.value);
41
+ return {
42
+ value: item.props.value,
43
+ label: item.props.badge ? `${baseLabel} (${item.props.badge})` : baseLabel,
44
+ disabled: item.props.disabled,
45
+ };
46
+ });
42
47
  return (_jsx(Select, { bare: true, "aria-label": "Tabs", role: "tablist", options: options, value: active, onValueChange: setActive, className: [UI_TABS.list, UI_TABS.listDropdown, className].filter(Boolean).join(" ") }));
43
48
  }
44
49
  return (_jsx("div", { role: "tablist", className: [UI_TABS.list, className].filter(Boolean).join(" "), "data-section": "tabs-div-615", children: children }));
45
50
  }
46
- export function TabsTrigger({ value, disabled, className = "", children, }) {
51
+ export function TabsTrigger({ value, disabled, className = "", children, badge, }) {
47
52
  const { active, setActive } = useContext(TabsContext);
48
53
  const isActive = active === value;
49
- return (_jsx("button", { role: "tab", type: "button", disabled: disabled, "aria-selected": isActive, onClick: () => setActive(value), className: [UI_TABS.trigger, className].filter(Boolean).join(" "), children: children }));
54
+ return (_jsxs("button", { role: "tab", type: "button", disabled: disabled, "aria-selected": isActive, onClick: () => setActive(value), className: [UI_TABS.trigger, className].filter(Boolean).join(" "), children: [children, typeof badge === "number" && badge > 0 && (_jsx("span", { className: UI_TABS.badge, children: badge > 99 ? "99+" : badge }))] }));
50
55
  }
51
56
  export function TabsContent({ value, className = "", children, }) {
52
57
  const { active } = useContext(TabsContext);
@@ -49,6 +49,25 @@
49
49
  opacity: 0.5;
50
50
  }
51
51
 
52
+ .appkit-tabs-trigger__badge {
53
+ display: inline-flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ margin-left: 0.5rem;
57
+ padding: 0 0.4rem;
58
+ min-width: 1.25rem;
59
+ height: 1.25rem;
60
+ border-radius: 9999px;
61
+ font-size: 0.6875rem;
62
+ font-weight: 600;
63
+ background: var(--appkit-color-surface-elevated);
64
+ color: var(--appkit-color-text-muted);
65
+ }
66
+ .appkit-tabs-trigger[aria-selected="true"] .appkit-tabs-trigger__badge {
67
+ background: color-mix(in srgb, var(--appkit-color-primary) 15%, transparent);
68
+ color: var(--appkit-color-primary);
69
+ }
70
+
52
71
  .appkit-tabs-content {
53
72
  padding-top: 1rem;
54
73
  padding-bottom: 1rem;
@@ -22,7 +22,6 @@
22
22
  @import "./PriceDisplay.style.css";
23
23
  @import "./ItemRow.style.css";
24
24
  @import "./Tooltip.style.css";
25
- @import "./TabStrip.style.css";
26
25
  @import "./Layout.style.css";
27
26
  @import "./SortDropdown.style.css";
28
27
  @import "./TablePagination.style.css";
@@ -113,8 +113,6 @@ export type { ItemRowProps } from "./components/ItemRow";
113
113
  export { ItemRow } from "./components/ItemRow";
114
114
  export type { HorizontalScrollerProps, PerViewConfig, } from "./components/HorizontalScroller";
115
115
  export { HorizontalScroller } from "./components/HorizontalScroller";
116
- export type { TabStripProps, TabStripTab } from "./components/TabStrip";
117
- export { TabStrip } from "./components/TabStrip";
118
116
  export type { FormGridProps, FormFieldProps } from "./components/FormGrid";
119
117
  export { FormGrid, FormField as FormGridField } from "./components/FormGrid";
120
118
  export type { SettingsSectionProps, ToggleRowProps } from "./components/SettingsSection";
package/dist/ui/index.js CHANGED
@@ -59,7 +59,6 @@ export { SummaryCard } from "./components/SummaryCard";
59
59
  export { CountdownDisplay } from "./components/CountdownDisplay";
60
60
  export { ItemRow } from "./components/ItemRow";
61
61
  export { HorizontalScroller } from "./components/HorizontalScroller";
62
- export { TabStrip } from "./components/TabStrip";
63
62
  export { FormGrid, FormField as FormGridField } from "./components/FormGrid";
64
63
  export { SettingsSection, ToggleRow } from "./components/SettingsSection";
65
64
  export { DetailPageHero } from "./components/DetailPageHero";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "3.9.1",
3
+ "version": "4.0.0",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"