@mohasinac/appkit 3.6.4 → 3.7.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.
- package/dist/_internal/client/features/layout/DashboardLayoutClient.d.ts +17 -3
- package/dist/_internal/client/features/layout/DashboardLayoutClient.js +7 -2
- package/dist/_internal/client/features/tour/TourProvider.d.ts +5 -2
- package/dist/_internal/client/features/tour/TourProvider.js +125 -12
- package/dist/_internal/client/theme/ThemeProvider.js +1 -1
- package/dist/_internal/server/features/faqs/og.js +5 -1
- package/dist/_internal/server/features/reviews/og.js +5 -1
- package/dist/_internal/server/features/seo/manifest.js +2 -1
- package/dist/_internal/server/features/seo/og.js +7 -1
- package/dist/_internal/server/features/tester/visibility.d.ts +13 -0
- package/dist/_internal/server/features/tester/visibility.js +28 -0
- package/dist/_internal/server/functions/scheduled.d.ts +2 -1
- package/dist/_internal/server/functions/scheduled.js +9 -1
- package/dist/_internal/server/jobs/core/jobRunners.js +5 -0
- package/dist/_internal/server/jobs/core/resetOtpVerification.d.ts +17 -0
- package/dist/_internal/server/jobs/core/resetOtpVerification.js +88 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.d.ts +6 -0
- package/dist/_internal/server/jobs/core/testerSandboxCleanup.js +35 -0
- package/dist/_internal/server/jobs/handlers/_helpers.d.ts +6 -0
- package/dist/_internal/server/jobs/handlers/_helpers.js +12 -0
- package/dist/_internal/server/jobs/handlers/index.d.ts +1 -0
- package/dist/_internal/server/jobs/handlers/index.js +2 -0
- package/dist/_internal/server/jobs/handlers/messages.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/messages.js +2 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.d.ts +2 -0
- package/dist/_internal/server/jobs/handlers/testerSandboxCleanup.js +2 -0
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +48 -0
- package/dist/_internal/shared/tokens/index.d.ts +12 -12
- package/dist/client.d.ts +15 -3
- package/dist/client.js +10 -2
- package/dist/constants/api-endpoints.d.ts +36 -12
- package/dist/constants/api-endpoints.js +16 -8
- package/dist/constants/field-names.d.ts +9 -0
- package/dist/constants/field-names.js +12 -0
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.js +1 -1
- package/dist/features/account/components/LinkedAccountsSection.d.ts +11 -0
- package/dist/features/account/components/LinkedAccountsSection.js +11 -0
- package/dist/features/account/components/UserSidebar.d.ts +3 -1
- package/dist/features/account/components/UserSidebar.js +11 -15
- package/dist/features/account/hooks/useCollapsedSections.d.ts +20 -0
- package/dist/features/account/hooks/useCollapsedSections.js +63 -0
- package/dist/features/account/hooks/useProfile.d.ts +8 -0
- package/dist/features/account/index.d.ts +1 -0
- package/dist/features/account/index.js +1 -0
- package/dist/features/admin/components/AdminAddressEditorView.js +2 -2
- package/dist/features/admin/components/AdminCarouselView.js +2 -2
- package/dist/features/admin/components/AdminCategoryEditorView.js +2 -2
- package/dist/features/admin/components/AdminProductEditorView.js +5 -2
- package/dist/features/admin/components/AdminSectionsView.js +3 -18
- package/dist/features/admin/components/AdminSidebar.js +10 -8
- package/dist/features/admin/components/AdminSiteSettingsView.js +133 -127
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.d.ts +9 -0
- package/dist/features/admin/components/AdminTesterChecklistItemEditorView.js +129 -0
- package/dist/features/admin/components/AdminTesterChecklistView.d.ts +6 -0
- package/dist/features/admin/components/AdminTesterChecklistView.js +93 -0
- package/dist/features/admin/components/AdminUserEditorView.d.ts +3 -1
- package/dist/features/admin/components/AdminUserEditorView.js +7 -1
- package/dist/features/admin/components/AdminUsersView.js +1 -1
- package/dist/features/admin/components/DataListingView.js +2 -2
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.d.ts +8 -0
- package/dist/features/admin/components/analytics/AdminPageViewsReportView.js +41 -0
- package/dist/features/admin/components/index.d.ts +6 -0
- package/dist/features/admin/components/index.js +3 -0
- package/dist/features/admin/schemas/firestore.d.ts +0 -7
- package/dist/features/admin/schemas/firestore.js +6 -6
- package/dist/features/analytics/components/PageViewTracker.d.ts +12 -0
- package/dist/features/analytics/components/PageViewTracker.js +22 -0
- package/dist/features/analytics/repository/page-views.repository.d.ts +32 -0
- package/dist/features/analytics/repository/page-views.repository.js +43 -0
- package/dist/features/analytics/types.d.ts +6 -0
- package/dist/features/analytics/types.js +13 -0
- package/dist/features/auth/components/SocialAuthButtons.js +1 -1
- package/dist/features/auth/hooks/useAuth.d.ts +12 -0
- package/dist/features/auth/hooks/useAuth.js +109 -0
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/schemas/firestore.d.ts +17 -1
- package/dist/features/auth/schemas/firestore.js +2 -0
- package/dist/features/blog/components/BlogIndexListing.js +2 -2
- package/dist/features/blog/schemas/firestore.d.ts +4 -0
- package/dist/features/cart/actions/cart-actions.js +20 -2
- package/dist/features/categories/components/CategoriesIndexListing.js +2 -2
- package/dist/features/categories/components/CategoryBundlesListing.js +2 -2
- package/dist/features/categories/components/CategoryDetailPageView.js +3 -1
- package/dist/features/categories/components/CategoryProductsListing.js +2 -2
- package/dist/features/categories/schemas/firestore.d.ts +4 -0
- package/dist/features/classified/components/ClassifiedIndexListing.js +2 -2
- package/dist/features/digital-codes/components/DigitalCodesIndexListing.js +2 -2
- package/dist/features/email/primitives.d.ts +2 -2
- package/dist/features/email/primitives.js +2 -2
- package/dist/features/events/components/EventsIndexListing.js +2 -2
- package/dist/features/events/schemas/firestore.d.ts +4 -0
- package/dist/features/layout/BackToTop.d.ts +6 -1
- package/dist/features/layout/BackToTop.js +31 -6
- package/dist/features/live/components/LiveItemsIndexListing.js +2 -2
- package/dist/features/media/MediaVideo.js +5 -1
- package/dist/features/pre-orders/components/PreOrdersIndexListing.js +2 -2
- package/dist/features/products/components/AuctionsIndexListing.js +2 -2
- package/dist/features/products/components/PrizeDrawsIndexListing.js +2 -2
- package/dist/features/products/components/ProductsIndexListing.js +2 -2
- package/dist/features/products/constants/action-defs.d.ts +2 -0
- package/dist/features/products/constants/action-defs.js +2 -0
- package/dist/features/products/schemas/firestore.d.ts +4 -0
- package/dist/features/promotions/components/CouponsIndexListing.js +2 -2
- package/dist/features/reviews/components/ReviewsIndexListing.js +2 -2
- package/dist/features/seller/actions/seller-actions.js +11 -6
- package/dist/features/seller/components/SellerAddressesView.js +2 -2
- package/dist/features/seller/components/SellerBidsView.js +2 -2
- package/dist/features/seller/components/SellerOrdersView.js +2 -2
- package/dist/features/seller/components/SellerProductsView.js +2 -2
- package/dist/features/seller/components/SellerSidebar.d.ts +3 -1
- package/dist/features/seller/components/SellerSidebar.js +11 -10
- package/dist/features/seller/components/SellerStoreCategoriesView.js +2 -2
- package/dist/features/seller/components/SellerTemplatesView.js +2 -2
- package/dist/features/shell/StepForm.js +4 -4
- package/dist/features/stores/actions/store-query-actions.d.ts +5 -4
- package/dist/features/stores/actions/store-query-actions.js +11 -8
- package/dist/features/stores/components/StoreAuctionsListing.js +2 -2
- package/dist/features/stores/components/StoreClassifiedsListing.js +2 -2
- package/dist/features/stores/components/StoreDigitalCodesListing.js +2 -2
- package/dist/features/stores/components/StoreLiveItemsListing.js +2 -2
- package/dist/features/stores/components/StorePreOrdersListing.js +2 -2
- package/dist/features/stores/components/StoreProductsListing.js +2 -2
- package/dist/features/stores/components/StoreReviewsListing.js +2 -2
- package/dist/features/stores/components/StoresIndexListing.js +2 -2
- package/dist/features/stores/schemas/firestore.d.ts +4 -0
- package/dist/features/tester/actions/checklist-item-actions.d.ts +69 -0
- package/dist/features/tester/actions/checklist-item-actions.js +42 -0
- package/dist/features/tester/actions/index.d.ts +1 -0
- package/dist/features/tester/actions/index.js +1 -0
- package/dist/features/tester/components/AdminTesterFeedbackIssuesView.d.ts +2 -0
- package/dist/features/tester/components/AdminTesterFeedbackIssuesView.js +22 -0
- package/dist/features/tester/components/AdminTesterFeedbackListView.d.ts +3 -0
- package/dist/features/tester/components/AdminTesterFeedbackListView.js +100 -0
- package/dist/features/tester/components/AdminTesterFeedbackReportView.d.ts +2 -0
- package/dist/features/tester/components/AdminTesterFeedbackReportView.js +30 -0
- package/dist/features/tester/components/AdminTesterFeedbackView.d.ts +2 -0
- package/dist/features/tester/components/AdminTesterFeedbackView.js +9 -0
- package/dist/features/tester/components/TesterChecklistStepRow.d.ts +18 -0
- package/dist/features/tester/components/TesterChecklistStepRow.js +29 -0
- package/dist/features/tester/components/TesterFeedbackChart.d.ts +14 -0
- package/dist/features/tester/components/TesterFeedbackChart.js +18 -0
- package/dist/features/tester/components/TesterHubView.d.ts +5 -0
- package/dist/features/tester/components/TesterHubView.js +71 -0
- package/dist/features/tester/components/index.d.ts +11 -0
- package/dist/features/tester/components/index.js +7 -0
- package/dist/features/tester/index.d.ts +2 -0
- package/dist/features/tester/index.js +2 -0
- package/dist/features/tester/repository/index.d.ts +2 -0
- package/dist/features/tester/repository/index.js +2 -0
- package/dist/features/tester/repository/tester-checklist-item.repository.d.ts +13 -0
- package/dist/features/tester/repository/tester-checklist-item.repository.js +55 -0
- package/dist/features/tester/repository/tester-checklist-response.repository.d.ts +42 -0
- package/dist/features/tester/repository/tester-checklist-response.repository.js +98 -0
- package/dist/features/tester/schemas/firestore.d.ts +85 -0
- package/dist/features/tester/schemas/firestore.js +93 -0
- package/dist/features/tester/schemas/index.d.ts +1 -0
- package/dist/features/tester/schemas/index.js +1 -0
- package/dist/features/tester/seed-data/blog-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/blog-tester-seed-data.js +40 -0
- package/dist/features/tester/seed-data/categories-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/categories-tester-seed-data.js +177 -0
- package/dist/features/tester/seed-data/events-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/events-tester-seed-data.js +50 -0
- package/dist/features/tester/seed-data/index.d.ts +6 -0
- package/dist/features/tester/seed-data/index.js +6 -0
- package/dist/features/tester/seed-data/products-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/products-tester-seed-data.js +151 -0
- package/dist/features/tester/seed-data/stores-tester-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/stores-tester-seed-data.js +40 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.d.ts +2 -0
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +248 -0
- package/dist/features/tester/seed-data/tester-ttl.d.ts +4 -0
- package/dist/features/tester/seed-data/tester-ttl.js +6 -0
- package/dist/features/tester/server.d.ts +9 -0
- package/dist/features/tester/server.js +8 -0
- package/dist/index.d.ts +28 -2
- package/dist/index.js +51 -1
- package/dist/next/api/api-response.js +5 -1
- package/dist/next/api/routeHandler.js +10 -1
- package/dist/next/middleware/chain.js +1 -1
- package/dist/next/routing/route-map.d.ts +6 -7
- package/dist/next/routing/route-map.js +3 -7
- package/dist/providers/payment-manual/index.d.ts +2 -2
- package/dist/providers/payment-manual/index.js +2 -2
- package/dist/react/contexts/SessionContext.d.ts +4 -0
- package/dist/react/contexts/SessionContext.js +4 -0
- package/dist/repositories/index.d.ts +4 -0
- package/dist/repositories/index.js +3 -0
- package/dist/security/pii-encrypt.js +12 -2
- package/dist/seed/addresses-seed-data.js +1 -1
- package/dist/seed/bids-seed-data.js +1 -1
- package/dist/seed/blog-posts-seed-data.js +1 -1
- package/dist/seed/carousel-slides-seed-data.js +22 -16
- package/dist/seed/carousels-seed-data.js +1 -1
- package/dist/seed/cart-seed-data.js +1 -1
- package/dist/seed/categories-seed-data.js +1 -1
- package/dist/seed/claimed-coupons-seed-data.js +1 -1
- package/dist/seed/conversations-seed-data.js +1 -1
- package/dist/seed/coupon-usage-seed-data.js +1 -1
- package/dist/seed/coupons-seed-data.js +1 -1
- package/dist/seed/events-seed-data.js +1 -1
- package/dist/seed/faq-seed-data.js +119 -3
- package/dist/seed/grouped-listings-seed-data.d.ts +2 -0
- package/dist/seed/grouped-listings-seed-data.js +1 -1
- package/dist/seed/history-seed-data.js +1 -1
- package/dist/seed/homepage-sections-seed-data.js +1 -1
- package/dist/seed/index.d.ts +2 -2
- package/dist/seed/index.js +7 -3
- package/dist/seed/lottery-entries-seed-data.js +1 -1
- package/dist/seed/manifest.d.ts +4 -3
- package/dist/seed/manifest.js +13 -6
- package/dist/seed/notifications-seed-data.js +1 -1
- package/dist/seed/offers-seed-data.js +1 -1
- package/dist/seed/orders-seed-data.js +1 -1
- package/dist/seed/payouts-seed-data.js +1 -1
- package/dist/seed/products-art-seed-data.js +1 -1
- package/dist/seed/products-auctions-seed-data.js +1 -1
- package/dist/seed/products-classifieds-seed-data.js +1 -1
- package/dist/seed/products-digital-codes-seed-data.js +1 -1
- package/dist/seed/products-live-items-seed-data.js +1 -1
- package/dist/seed/products-preorders-seed-data.d.ts +2 -0
- package/dist/seed/products-preorders-seed-data.js +1 -1
- package/dist/seed/products-prize-draws-seed-data.js +1 -1
- package/dist/seed/products-standard-seed-data.js +1 -1
- package/dist/seed/products-stickers-seed-data.js +1 -1
- package/dist/seed/reviews-seed-data.js +1 -1
- package/dist/seed/scammers-seed-data.js +1 -1
- package/dist/seed/sessions-seed-data.js +1 -1
- package/dist/seed/site-settings-seed-data.js +22 -16
- package/dist/seed/store-addresses-seed-data.js +1 -1
- package/dist/seed/store-extensions-seed-data.js +1 -1
- package/dist/seed/stores-seed-data.js +1 -1
- package/dist/seed/support-tickets-seed-data.js +1 -1
- package/dist/seed/tester-checklist-seed-data.d.ts +2 -0
- package/dist/seed/tester-checklist-seed-data.js +248 -0
- package/dist/seed/users-seed-data.js +1 -1
- package/dist/seed/wishlists-seed-data.js +1 -1
- package/dist/server.d.ts +7 -2
- package/dist/server.js +19 -12
- package/dist/styles.css +163 -147
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/color-pairs.d.ts +46 -0
- package/dist/tokens/color-pairs.js +93 -0
- package/dist/tokens/index.d.ts +60 -60
- package/dist/tokens/index.js +30 -30
- package/dist/tokens/themes/cobalt-night.d.ts +3 -2
- package/dist/tokens/themes/cobalt-night.js +3 -2
- package/dist/tokens/themes/default-dark.d.ts +4 -1
- package/dist/tokens/themes/default-dark.js +44 -41
- package/dist/tokens/themes/default-light.d.ts +5 -1
- package/dist/tokens/themes/default-light.js +39 -35
- package/dist/tokens/themes/sunset.js +4 -4
- package/dist/tokens/tokens.css +110 -104
- package/dist/ui/components/CollapsibleSection.d.ts +15 -0
- package/dist/ui/components/CollapsibleSection.js +13 -0
- package/dist/ui/components/ListingToolbar.js +2 -1
- package/dist/ui/components/Semantic.style.css +3 -3
- package/dist/ui/components/SideDrawer.style.css +19 -19
- package/dist/ui/components/Slider.js +1 -1
- package/dist/ui/components/StickyToolbar.d.ts +36 -7
- package/dist/ui/components/StickyToolbar.js +63 -5
- package/dist/ui/components/Tabs.js +17 -1
- package/dist/ui/components/Tabs.style.css +10 -0
- package/dist/ui/components/Typography.js +7 -0
- package/dist/ui/components/surface-tokens.d.ts +0 -7
- package/dist/ui/components/surface-tokens.js +7 -0
- package/dist/ui/index.d.ts +6 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/rich-text/RichText.style.css +20 -20
- package/dist/utils/id-generators.d.ts +13 -0
- package/dist/utils/id-generators.js +17 -0
- package/package.json +1 -1
- package/scripts/seed-cli-loader.mjs +15 -0
- package/scripts/seed-cli.mjs +71 -17
|
@@ -1,15 +1,24 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
2
|
/**
|
|
3
3
|
* StickyToolbar — primitive for the recurrent translucent sticky bar pattern
|
|
4
4
|
* (`sticky top-[calc(var(--header-height,0px)+var(--appkit-navbar-height,2.5rem))]
|
|
5
5
|
* z-10 ... backdrop-blur-sm border-b ...`) used by search-results pages,
|
|
6
|
-
* leaderboards, etc.
|
|
6
|
+
* leaderboards, sticky pagination rows, etc.
|
|
7
7
|
*
|
|
8
8
|
* The header offset is sourced from `--header-height`, which the global
|
|
9
9
|
* AppLayoutShell sets at runtime. Consumer code never authors the offset
|
|
10
10
|
* manually — only `audit-sticky-offsets` allowlisted files may.
|
|
11
|
+
*
|
|
12
|
+
* Dismiss/hide: pass `dismissible` (with a stable `id`) to let the user
|
|
13
|
+
* collapse the bar to a thin re-expand strip for the rest of the browser
|
|
14
|
+
* session — a viewport-annoyance-avoidance toggle, not a durable
|
|
15
|
+
* preference, so it resets on reload rather than persisting forever. This
|
|
16
|
+
* is what closes the mobile-overlap complaint the sticky toolbar pattern
|
|
17
|
+
* caused across listing pages: at narrow widths, any sticky bar competing
|
|
18
|
+
* with page content for vertical space needs a way out that doesn't require
|
|
19
|
+
* scrolling past it.
|
|
11
20
|
*/
|
|
12
|
-
export type StickyToolbarOffset = "header" | "header+nav" | number;
|
|
21
|
+
export type StickyToolbarOffset = "header" | "header+nav" | "header+pagination" | "header+bulk-actions" | number;
|
|
13
22
|
export type StickyToolbarTone = "default" | "muted" | "translucent" | "inverse";
|
|
14
23
|
export type StickyToolbarPadding = "none" | "sm" | "md" | "lg" | "toolbar";
|
|
15
24
|
export interface StickyToolbarProps {
|
|
@@ -20,11 +29,31 @@ export interface StickyToolbarProps {
|
|
|
20
29
|
tone?: StickyToolbarTone;
|
|
21
30
|
/** Show a bottom border. Default `true`. */
|
|
22
31
|
border?: boolean;
|
|
23
|
-
/** Padding preset. Default `"toolbar"`. */
|
|
32
|
+
/** Padding preset. Default `"toolbar"`. Use `"none"` + `className` for a responsive/custom padding a preset can't express. */
|
|
24
33
|
padding?: StickyToolbarPadding;
|
|
25
|
-
/**
|
|
26
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Stacking layer. Default `"above-content"` (z-10). Use `"above-toolbar"`
|
|
36
|
+
* (z-20) for a bar that must stack above another StickyToolbar beneath it
|
|
37
|
+
* — the common case being a bulk-action bar or primary filter toolbar
|
|
38
|
+
* sitting above a secondary sticky pagination row.
|
|
39
|
+
*/
|
|
40
|
+
z?: "below-modal" | "above-content" | "above-toolbar";
|
|
27
41
|
/** Accessible role override. */
|
|
28
42
|
role?: string;
|
|
43
|
+
/** Extra classes appended after the primitive's own — the escape hatch for another primitive (e.g. ListingToolbar) built on top of this one. */
|
|
44
|
+
className?: string;
|
|
45
|
+
/** Forwarded to the root element — for `data-testid` and similar test/analytics hooks. */
|
|
46
|
+
dataTestId?: string;
|
|
47
|
+
/**
|
|
48
|
+
* When true, renders a collapse/expand control. Requires `id` — the
|
|
49
|
+
* collapsed state is stored in `sessionStorage` keyed by it, so distinct
|
|
50
|
+
* toolbars on the same page (or the same toolbar across route changes
|
|
51
|
+
* within a session) don't clobber each other.
|
|
52
|
+
*/
|
|
53
|
+
dismissible?: boolean;
|
|
54
|
+
/** Required when `dismissible` is true — see above. */
|
|
55
|
+
id?: string;
|
|
56
|
+
/** Accessible label for the collapse/expand button. Default "Toolbar". */
|
|
57
|
+
label?: string;
|
|
29
58
|
}
|
|
30
|
-
export declare function StickyToolbar({ children, offset, tone, border, padding, z, role, }: StickyToolbarProps): import("react").JSX.Element;
|
|
59
|
+
export declare function StickyToolbar({ children, offset, tone, border, padding, z, role, className, dataTestId, dismissible, id, label, }: StickyToolbarProps): import("react").JSX.Element;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { normalizeError } from "../../errors/normalize";
|
|
2
5
|
const TONE_CLS = {
|
|
3
6
|
default: "bg-[var(--appkit-color-surface)]",
|
|
4
7
|
muted: "bg-[var(--appkit-color-bg)]",
|
|
@@ -19,19 +22,74 @@ function resolveOffsetClass(offset) {
|
|
|
19
22
|
if (offset === "header+nav") {
|
|
20
23
|
return "top-[calc(var(--header-height,0px)+var(--appkit-navbar-height,2.5rem))]";
|
|
21
24
|
}
|
|
25
|
+
if (offset === "header+pagination") {
|
|
26
|
+
// Matches the sticky pagination-row offset repeated verbatim across
|
|
27
|
+
// every DataListingView-style index listing (44px = the fixed toolbar
|
|
28
|
+
// row height above it) — consolidated here instead of copy-pasted.
|
|
29
|
+
return "top-[calc(var(--header-height,0px)+44px)]";
|
|
30
|
+
}
|
|
31
|
+
if (offset === "header+bulk-actions") {
|
|
32
|
+
// Matches the sticky bulk-action-bar offset that stacks below both the
|
|
33
|
+
// filter toolbar (44px) and the pagination row above it (88px total).
|
|
34
|
+
return "top-[calc(var(--header-height,0px)+88px)]";
|
|
35
|
+
}
|
|
22
36
|
// Numeric offsets are applied via inline style instead (see below) —
|
|
23
37
|
// Tailwind's static scanner can never see a dynamically-interpolated
|
|
24
38
|
// `top-[${offset}px]` arbitrary value, so no CSS rule would ever be
|
|
25
39
|
// generated for it in the compiled stylesheet.
|
|
26
40
|
return "";
|
|
27
41
|
}
|
|
28
|
-
|
|
42
|
+
const STORAGE_PREFIX = "appkit:sticky-toolbar-collapsed:";
|
|
43
|
+
function readCollapsed(id) {
|
|
44
|
+
if (typeof window === "undefined")
|
|
45
|
+
return false;
|
|
46
|
+
try {
|
|
47
|
+
return window.sessionStorage.getItem(STORAGE_PREFIX + id) === "1";
|
|
48
|
+
}
|
|
49
|
+
catch (_err) {
|
|
50
|
+
void normalizeError(_err);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function writeCollapsed(id, value) {
|
|
55
|
+
try {
|
|
56
|
+
if (value)
|
|
57
|
+
window.sessionStorage.setItem(STORAGE_PREFIX + id, "1");
|
|
58
|
+
else
|
|
59
|
+
window.sessionStorage.removeItem(STORAGE_PREFIX + id);
|
|
60
|
+
}
|
|
61
|
+
catch (_err) {
|
|
62
|
+
void normalizeError(_err);
|
|
63
|
+
// sessionStorage unavailable (private browsing, etc.) — collapse still
|
|
64
|
+
// works for the current render, just doesn't survive a re-mount.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export function StickyToolbar({ children, offset = "header", tone = "translucent", border = true, padding = "toolbar", z = "above-content", role, className, dataTestId, dismissible = false, id, label = "Toolbar", }) {
|
|
68
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (dismissible && id)
|
|
71
|
+
setCollapsed(readCollapsed(id));
|
|
72
|
+
}, [dismissible, id]);
|
|
29
73
|
const offsetCls = resolveOffsetClass(offset);
|
|
30
74
|
const offsetStyle = typeof offset === "number" ? { top: `${offset}px` } : undefined;
|
|
31
75
|
const borderCls = border ? "border-b border-[var(--appkit-color-border)]" : "";
|
|
32
|
-
const zCls = z === "above-content" ? "z-10" : "z-[5]";
|
|
33
|
-
|
|
76
|
+
const zCls = z === "above-toolbar" ? "z-20" : z === "above-content" ? "z-10" : "z-[5]";
|
|
77
|
+
const toggle = () => {
|
|
78
|
+
const next = !collapsed;
|
|
79
|
+
setCollapsed(next);
|
|
80
|
+
if (id)
|
|
81
|
+
writeCollapsed(id, next);
|
|
82
|
+
};
|
|
83
|
+
if (dismissible && id && collapsed) {
|
|
84
|
+
return (_jsx("div", { "data-testid": dataTestId, style: offsetStyle, className: `sticky ${offsetCls} ${zCls} ${TONE_CLS[tone]} ${borderCls} flex justify-center`, children: _jsxs("button", { type: "button", onClick: toggle, "aria-label": `Show ${label}`, "aria-expanded": false, className: "px-4 py-0.5 text-[length:var(--appkit-text-xs)] text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text)]", children: ["\u2304 Show ", label] }) }));
|
|
85
|
+
}
|
|
86
|
+
return (_jsxs("div", { role: role, "data-testid": dataTestId, style: offsetStyle,
|
|
34
87
|
// for the translucent sticky-toolbar pattern. The header offset is
|
|
35
88
|
// sourced from --header-height (set by AppLayoutShell at runtime).
|
|
36
|
-
|
|
89
|
+
// `relative` only when dismissible — the absolutely-positioned toggle
|
|
90
|
+
// button anchors to it without disturbing the existing internal
|
|
91
|
+
// layout of `children` (each of the 27+ migrated call sites has its
|
|
92
|
+
// own Row/Div structure; a flex wrapper here would double-nest and
|
|
93
|
+
// risk breaking their centering).
|
|
94
|
+
className: `sticky ${offsetCls} ${zCls} ${TONE_CLS[tone]} ${borderCls} ${PADDING_CLS[padding]} ${dismissible ? "relative pr-8" : ""} ${className ?? ""}`, children: [children, dismissible && id && (_jsx("button", { type: "button", onClick: toggle, "aria-label": `Hide ${label}`, "aria-expanded": true, className: "absolute right-1.5 top-1/2 -translate-y-1/2 px-1.5 py-1 text-[var(--appkit-color-text-muted)] hover:text-[var(--appkit-color-text)]", children: "\u2303" }))] }));
|
|
37
95
|
}
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import { createContext, useContext, useMemo, useState } from "react";
|
|
3
|
+
import React, { createContext, useContext, useMemo, useState } from "react";
|
|
4
|
+
import { Select } from "./Select";
|
|
4
5
|
const UI_TABS = {
|
|
5
6
|
list: "appkit-tabs-list",
|
|
7
|
+
listDropdown: "appkit-tabs-list--dropdown",
|
|
6
8
|
trigger: "appkit-tabs-trigger",
|
|
7
9
|
content: "appkit-tabs-content",
|
|
8
10
|
};
|
|
11
|
+
/** Past this many items, TabsList renders a <Select> dropdown instead of a
|
|
12
|
+
* horizontal row — a scrollable row of 6+ tabs is unreadable/unreachable on
|
|
13
|
+
* mobile widths. */
|
|
14
|
+
const TABS_DROPDOWN_THRESHOLD = 5;
|
|
9
15
|
const TabsContext = createContext({
|
|
10
16
|
active: "",
|
|
11
17
|
setActive: () => { },
|
|
@@ -25,6 +31,16 @@ export function Tabs({ defaultValue = "", value, onChange, className = "", child
|
|
|
25
31
|
return (_jsx(TabsContext.Provider, { value: contextValue, children: _jsx("div", { className: className, "data-section": "tabs-div-614", children: children }) }));
|
|
26
32
|
}
|
|
27
33
|
export function TabsList({ className = "", children }) {
|
|
34
|
+
const { active, setActive } = useContext(TabsContext);
|
|
35
|
+
const items = React.Children.toArray(children).filter((child) => React.isValidElement(child));
|
|
36
|
+
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
|
+
}));
|
|
42
|
+
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
|
+
}
|
|
28
44
|
return (_jsx("div", { role: "tablist", className: [UI_TABS.list, className].filter(Boolean).join(" "), "data-section": "tabs-div-615", children: children }));
|
|
29
45
|
}
|
|
30
46
|
export function TabsTrigger({ value, disabled, className = "", children, }) {
|
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
scrollbar-width: thin;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/* Past TABS_DROPDOWN_THRESHOLD triggers, TabsList renders a <Select bare>
|
|
18
|
+
instead of the flex row above — override the row-specific layout rules
|
|
19
|
+
that don't apply to a native <select>. */
|
|
20
|
+
.appkit-tabs-list--dropdown {
|
|
21
|
+
display: block;
|
|
22
|
+
overflow: visible;
|
|
23
|
+
border-bottom: none;
|
|
24
|
+
max-width: 20rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
.appkit-tabs-trigger {
|
|
18
28
|
margin-bottom: -1px;
|
|
19
29
|
border-bottom: 2px solid transparent;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { ROUNDED_MAP, PADDING_MAP, X_ONLY_MAP } from "./surface-tokens";
|
|
4
|
+
import { getSurfaceTextClass } from "../../tokens/color-pairs";
|
|
4
5
|
const TYPOGRAPHY = {
|
|
5
6
|
headingLevel: {
|
|
6
7
|
1: "appkit-heading--h1",
|
|
@@ -356,6 +357,11 @@ const SPAN_SHADOW_MAP = {
|
|
|
356
357
|
};
|
|
357
358
|
export const Span = React.forwardRef(function Span({ variant = "inherit", color, size, smSize, mdSize, lgSize, xlSize, weight, transform, truncate, numeric, italic, family, align, gradient, rounded, padding, surface, border, layout, gap, shadow, className = "", children, ...props }, ref) {
|
|
358
359
|
const resolvedColor = color ?? variant;
|
|
360
|
+
// Colors as a function (appkit/src/tokens/color-pairs.ts): only fall back to
|
|
361
|
+
// the surface's paired default text color when the consumer hasn't already
|
|
362
|
+
// requested one explicitly (resolvedColor === "inherit", i.e. neither
|
|
363
|
+
// `color` nor `variant` was passed) — never fights an explicit choice.
|
|
364
|
+
const surfaceTextFallback = surface && resolvedColor === "inherit" ? getSurfaceTextClass(surface) : "";
|
|
359
365
|
const classes = [
|
|
360
366
|
"appkit-span",
|
|
361
367
|
size ? TYPOGRAPHY.textSize[size] : "",
|
|
@@ -365,6 +371,7 @@ export const Span = React.forwardRef(function Span({ variant = "inherit", color,
|
|
|
365
371
|
responsiveSizeClass("xl:", xlSize),
|
|
366
372
|
weight ? TYPOGRAPHY.textWeight[weight] : "",
|
|
367
373
|
TYPOGRAPHY.colorVariant[resolvedColor],
|
|
374
|
+
surfaceTextFallback,
|
|
368
375
|
...shapingClasses({ transform, truncate, numeric, italic, family, align, gradient }),
|
|
369
376
|
rounded ? SPAN_ROUNDED_MAP[rounded] : "",
|
|
370
377
|
padding ? SPAN_PADDING_MAP[padding] : "",
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Surface & layout tokens — shared prop maps for all layout primitives.
|
|
3
|
-
*
|
|
4
|
-
* These maps power the Bootstrap/MUI-style props (`surface`, `padding`,
|
|
5
|
-
* `rounded`, `border`, `shadow`) on Stack, Row, Grid, Container, Section,
|
|
6
|
-
* Article, Main, Aside, Div, BlockHeader, and BlockFooter.
|
|
7
|
-
*/
|
|
8
1
|
export declare const SURFACE_MAP: {
|
|
9
2
|
readonly none: "";
|
|
10
3
|
readonly default: "bg-[var(--appkit-color-surface)]";
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* `rounded`, `border`, `shadow`) on Stack, Row, Grid, Container, Section,
|
|
6
6
|
* Article, Main, Aside, Div, BlockHeader, and BlockFooter.
|
|
7
7
|
*/
|
|
8
|
+
import { getSurfaceTextClass } from "../../tokens/color-pairs";
|
|
8
9
|
export const SURFACE_MAP = {
|
|
9
10
|
none: "",
|
|
10
11
|
default: "bg-[var(--appkit-color-surface)]",
|
|
@@ -270,6 +271,12 @@ const OVERFLOW_MAP = {
|
|
|
270
271
|
export function buildSurfaceClasses(props) {
|
|
271
272
|
return [
|
|
272
273
|
props.surface ? SURFACE_MAP[props.surface] : "",
|
|
274
|
+
// Colors as a function, not a convention (appkit/src/tokens/color-pairs.ts):
|
|
275
|
+
// every `surface` gets a readable default text color from here, resolved
|
|
276
|
+
// via getSurfaceTextClass — never picked independently. A child element's
|
|
277
|
+
// own explicit text color class still wins (normal CSS specificity), so
|
|
278
|
+
// this only fills in a floor, it never overrides an intentional choice.
|
|
279
|
+
props.surface ? getSurfaceTextClass(props.surface) : "",
|
|
273
280
|
props.padding ? PADDING_MAP[props.padding] : "",
|
|
274
281
|
props.paddingX ? X_ONLY_MAP[props.paddingX] : "",
|
|
275
282
|
props.paddingY ? Y_ONLY_MAP[props.paddingY] : "",
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -222,3 +222,9 @@ export { Scrim } from "./components/Scrim";
|
|
|
222
222
|
export type { ScrimProps, ScrimDirection, ScrimIntensity } from "./components/Scrim";
|
|
223
223
|
export { Kbd } from "./components/Kbd";
|
|
224
224
|
export type { KbdProps, KbdSize, KbdTone } from "./components/Kbd";
|
|
225
|
+
export { StickyToolbar } from "./components/StickyToolbar";
|
|
226
|
+
export type { StickyToolbarProps, StickyToolbarOffset, StickyToolbarTone, StickyToolbarPadding, } from "./components/StickyToolbar";
|
|
227
|
+
export { Show, Hide } from "./components/Responsive";
|
|
228
|
+
export type { ShowProps, HideProps } from "./components/Responsive";
|
|
229
|
+
export { CollapsibleSection } from "./components/CollapsibleSection";
|
|
230
|
+
export type { CollapsibleSectionProps } from "./components/CollapsibleSection";
|
package/dist/ui/index.js
CHANGED
|
@@ -116,3 +116,6 @@ export { HorizontalRule } from "./components/HorizontalRule";
|
|
|
116
116
|
export { Anchor } from "./components/Anchor";
|
|
117
117
|
export { Scrim } from "./components/Scrim";
|
|
118
118
|
export { Kbd } from "./components/Kbd";
|
|
119
|
+
export { StickyToolbar } from "./components/StickyToolbar";
|
|
120
|
+
export { Show, Hide } from "./components/Responsive";
|
|
121
|
+
export { CollapsibleSection } from "./components/CollapsibleSection";
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
border-radius: 0.25rem;
|
|
57
57
|
font-size: 0.875em;
|
|
58
58
|
font-weight: 500;
|
|
59
|
-
background-color:
|
|
60
|
-
color:
|
|
61
|
-
border: 1px solid
|
|
59
|
+
background-color: color-mix(in srgb, var(--appkit-color-primary) 8%, transparent);
|
|
60
|
+
color: var(--appkit-color-primary-700);
|
|
61
|
+
border: 1px solid color-mix(in srgb, var(--appkit-color-primary) 18%, transparent);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
.dark .appkit-rich-text :not(pre) > code {
|
|
65
65
|
background-color: rgba(51, 65, 85, 0.6); /* slate-700/60 */
|
|
66
|
-
color:
|
|
66
|
+
color: var(--appkit-color-secondary-400);
|
|
67
67
|
border-color: rgba(71, 85, 105, 0.5);
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -86,31 +86,31 @@
|
|
|
86
86
|
|
|
87
87
|
/* --- Blockquote ----------------------------------------------------------- */
|
|
88
88
|
.appkit-rich-text blockquote {
|
|
89
|
-
border-left: 3px solid
|
|
89
|
+
border-left: 3px solid var(--appkit-color-primary);
|
|
90
90
|
padding: 0.5rem 1rem;
|
|
91
91
|
margin: 1.25rem 0;
|
|
92
92
|
border-radius: 0 0.375rem 0.375rem 0;
|
|
93
|
-
background-color:
|
|
93
|
+
background-color: color-mix(in srgb, var(--appkit-color-primary) 6%, transparent);
|
|
94
94
|
color: var(--appkit-color-zinc-700);
|
|
95
95
|
font-style: italic;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
.dark .appkit-rich-text blockquote {
|
|
99
|
-
border-left-color:
|
|
100
|
-
background-color:
|
|
99
|
+
border-left-color: var(--appkit-color-secondary-400);
|
|
100
|
+
background-color: color-mix(in srgb, var(--appkit-color-secondary) 6%, transparent);
|
|
101
101
|
color: var(--appkit-color-text-faint);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/* --- Mark / Highlight ----------------------------------------------------- */
|
|
105
105
|
.appkit-rich-text mark {
|
|
106
|
-
background-color:
|
|
106
|
+
background-color: color-mix(in srgb, var(--appkit-color-secondary) 25%, transparent);
|
|
107
107
|
color: inherit;
|
|
108
108
|
border-radius: 0.125rem;
|
|
109
109
|
padding: 0 0.1em;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
.dark .appkit-rich-text mark {
|
|
113
|
-
background-color:
|
|
113
|
+
background-color: color-mix(in srgb, var(--appkit-color-secondary) 35%, transparent);
|
|
114
114
|
color: var(--appkit-color-zinc-100);
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -128,26 +128,26 @@
|
|
|
128
128
|
|
|
129
129
|
/* --- Links ---------------------------------------------------------------- */
|
|
130
130
|
.appkit-rich-text a {
|
|
131
|
-
color:
|
|
131
|
+
color: var(--appkit-color-primary-600);
|
|
132
132
|
text-decoration: underline;
|
|
133
|
-
text-decoration-color:
|
|
133
|
+
text-decoration-color: color-mix(in srgb, var(--appkit-color-primary-600) 60%, transparent);
|
|
134
134
|
text-underline-offset: 2px;
|
|
135
135
|
transition: color 150ms, text-decoration-color 150ms;
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
.appkit-rich-text a:hover {
|
|
139
|
-
color:
|
|
140
|
-
text-decoration-color:
|
|
139
|
+
color: var(--appkit-color-primary-700);
|
|
140
|
+
text-decoration-color: color-mix(in srgb, var(--appkit-color-primary-700) 70%, transparent);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
.dark .appkit-rich-text a {
|
|
144
|
-
color:
|
|
145
|
-
text-decoration-color:
|
|
144
|
+
color: var(--appkit-color-secondary-400);
|
|
145
|
+
text-decoration-color: color-mix(in srgb, var(--appkit-color-secondary-400) 60%, transparent);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
.dark .appkit-rich-text a:hover {
|
|
149
|
-
color:
|
|
150
|
-
text-decoration-color:
|
|
149
|
+
color: var(--appkit-color-secondary-300);
|
|
150
|
+
text-decoration-color: color-mix(in srgb, var(--appkit-color-secondary-300) 60%, transparent);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/* --- Tables --------------------------------------------------------------- */
|
|
@@ -274,11 +274,11 @@
|
|
|
274
274
|
.appkit-rich-text ins {
|
|
275
275
|
text-decoration: underline;
|
|
276
276
|
text-decoration-style: wavy;
|
|
277
|
-
text-decoration-color:
|
|
277
|
+
text-decoration-color: var(--appkit-color-primary);
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
.dark .appkit-rich-text ins {
|
|
281
|
-
text-decoration-color:
|
|
281
|
+
text-decoration-color: var(--appkit-color-secondary-400);
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
.appkit-rich-text del {
|
|
@@ -65,6 +65,13 @@ export interface GenerateFAQIdInput {
|
|
|
65
65
|
customId?: string;
|
|
66
66
|
}
|
|
67
67
|
export declare function generateFAQId(input: GenerateFAQIdInput): string;
|
|
68
|
+
export interface GenerateChecklistItemIdInput {
|
|
69
|
+
groupKey: string;
|
|
70
|
+
pageKey: string;
|
|
71
|
+
label: string;
|
|
72
|
+
customId?: string;
|
|
73
|
+
}
|
|
74
|
+
export declare function generateChecklistItemId(input: GenerateChecklistItemIdInput): string;
|
|
68
75
|
export declare function generateCouponId(code: string, customId?: string): string;
|
|
69
76
|
export interface GenerateCarouselIdInput {
|
|
70
77
|
title: string;
|
|
@@ -266,6 +273,12 @@ export type MediaFilenameContext = ({
|
|
|
266
273
|
buyerName: string;
|
|
267
274
|
ext?: string;
|
|
268
275
|
date?: Date;
|
|
276
|
+
} | {
|
|
277
|
+
type: "tester-screenshot";
|
|
278
|
+
testerName: string;
|
|
279
|
+
checklistItemId: string;
|
|
280
|
+
ext?: string;
|
|
281
|
+
date?: Date;
|
|
269
282
|
};
|
|
270
283
|
export declare function generateMediaFilename(ctx: MediaFilenameContext): string;
|
|
271
284
|
export declare function validateMediaFilename(filename: string): boolean;
|
|
@@ -77,6 +77,12 @@ export function generateFAQId(input) {
|
|
|
77
77
|
const questionSlug = slugify(input.question).substring(0, 50).replace(/-+$/, "");
|
|
78
78
|
return `faq-${slugify(input.category)}-${questionSlug}`;
|
|
79
79
|
}
|
|
80
|
+
export function generateChecklistItemId(input) {
|
|
81
|
+
if (input.customId?.trim())
|
|
82
|
+
return input.customId.trim();
|
|
83
|
+
const labelSlug = slugify(input.label).substring(0, 40).replace(/-+$/, "");
|
|
84
|
+
return `checklist-${slugify(input.groupKey)}-${slugify(input.pageKey)}-${labelSlug}`;
|
|
85
|
+
}
|
|
80
86
|
// ─── Coupon ───────────────────────────────────────────────────────────────────
|
|
81
87
|
export function generateCouponId(code, customId) {
|
|
82
88
|
if (customId?.trim())
|
|
@@ -425,6 +431,16 @@ export function generateMediaFilename(ctx) {
|
|
|
425
431
|
const name = ctx.buyerName.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").slice(0, 20);
|
|
426
432
|
return `payment-proof-${ctx.orderId}-${name}-${y}${m}${day}.${ext}`;
|
|
427
433
|
}
|
|
434
|
+
case "tester-screenshot": {
|
|
435
|
+
const d = ctx.date ?? new Date();
|
|
436
|
+
const y = d.getFullYear();
|
|
437
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
438
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
439
|
+
const ext = ctx.ext ?? "jpg";
|
|
440
|
+
const name = ctx.testerName.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").slice(0, 20);
|
|
441
|
+
const item = ctx.checklistItemId.toLowerCase().replace(/[^a-z0-9-]/g, "").slice(0, 40);
|
|
442
|
+
return `tester-screenshot-${item}-${name}-${y}${m}${day}.${ext}`;
|
|
443
|
+
}
|
|
428
444
|
}
|
|
429
445
|
}
|
|
430
446
|
/**
|
|
@@ -475,6 +491,7 @@ const MEDIA_FILENAME_PATTERNS = [
|
|
|
475
491
|
{ context: "shipping-proof", pattern: new RegExp(`^shipping-proof-${SLUG_PART}-${DATE_PART}\\.${EXT_PART}$`) },
|
|
476
492
|
{ context: "refund-proof", pattern: new RegExp(`^refund-proof-${SLUG_PART}-${SLUG_PART}-${DATE_PART}\\.${EXT_PART}$`) },
|
|
477
493
|
{ context: "payment-proof", pattern: new RegExp(`^payment-proof-${SLUG_PART}-${SLUG_PART}-${DATE_PART}\\.${EXT_PART}$`) },
|
|
494
|
+
{ context: "tester-screenshot", pattern: new RegExp(`^tester-screenshot-${SLUG_PART}-${SLUG_PART}-${DATE_PART}\\.${EXT_PART}$`) },
|
|
478
495
|
];
|
|
479
496
|
export function validateMediaFilename(filename) {
|
|
480
497
|
if (!filename || filename.length > 256)
|
package/package.json
CHANGED
|
@@ -11,6 +11,18 @@
|
|
|
11
11
|
// `import "./foo.css"` side-effect statements that Node ESM can't load.
|
|
12
12
|
const STUB_EXTENSIONS = [".css", ".scss", ".sass", ".png", ".jpg", ".jpeg", ".svg", ".webp", ".gif"];
|
|
13
13
|
|
|
14
|
+
// server-only / client-only are Next.js-specific sentinel packages — their
|
|
15
|
+
// entire module body unconditionally throws, because their whole purpose is
|
|
16
|
+
// a Next.js-compiler-time + Next.js-runtime guard against importing a
|
|
17
|
+
// server-only (or client-only) module from the wrong side of the boundary.
|
|
18
|
+
// A raw Node script (this CLI) is neither a Next.js Server Component nor a
|
|
19
|
+
// Client Component, so the guard is meaningless here — the main
|
|
20
|
+
// @mohasinac/appkit barrel transitively reaches a module (e.g.
|
|
21
|
+
// features/contact/email.tsx) that imports "server-only" at the top level,
|
|
22
|
+
// which crashes the whole CLI on load. Stub both to a no-op module. Found
|
|
23
|
+
// 2026-08-17 debugging the CLI seed tool being unable to import appkit at all.
|
|
24
|
+
const SENTINEL_SPECIFIERS = new Set(["server-only", "client-only"]);
|
|
25
|
+
|
|
14
26
|
export async function load(url, context, nextLoad) {
|
|
15
27
|
if (STUB_EXTENSIONS.some((ext) => url.endsWith(ext))) {
|
|
16
28
|
return { format: "module", shortCircuit: true, source: "export default undefined;" };
|
|
@@ -19,6 +31,9 @@ export async function load(url, context, nextLoad) {
|
|
|
19
31
|
}
|
|
20
32
|
|
|
21
33
|
export async function resolve(specifier, context, nextResolve) {
|
|
34
|
+
if (SENTINEL_SPECIFIERS.has(specifier)) {
|
|
35
|
+
return { url: `data:text/javascript,export default undefined;`, shortCircuit: true };
|
|
36
|
+
}
|
|
22
37
|
try {
|
|
23
38
|
return await nextResolve(specifier, context);
|
|
24
39
|
} catch (err) {
|