@mohasinac/appkit 3.0.2 → 3.0.4
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/filters/filter-load-options.js +11 -1
- package/dist/_internal/client/features/layout/filterNavItems.js +0 -1
- package/dist/_internal/client/features/layout/index.js +0 -1
- package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +0 -1
- package/dist/_internal/client/features/maintenance/views/ServerErrorDetailView.js +0 -1
- package/dist/_internal/server/features/checkout/actions.js +9 -9
- package/dist/_internal/server/jobs/core/cleanupRtdbEvents.js +1 -1
- package/dist/_internal/shared/listing-types/action-tracker.js +1 -1
- package/dist/client/api/ApiError.d.ts +10 -4
- package/dist/client/api/surface-error.js +0 -1
- package/dist/client.d.ts +4 -0
- package/dist/client.js +2 -0
- package/dist/core/hooks/useSyncManager.js +4 -4
- package/dist/features/_guide-cls.d.ts +1 -1
- package/dist/features/_guide-cls.js +1 -1
- package/dist/features/about/components/AboutView.js +1 -4
- package/dist/features/about/components/FAQPageView.js +1 -1
- package/dist/features/about/components/FeesView.js +1 -1
- package/dist/features/about/components/HelpPageView.js +1 -1
- package/dist/features/about/components/HowOrdersWorkView.js +1 -1
- package/dist/features/about/components/PublicProfileView.js +6 -6
- package/dist/features/about/components/TrackOrderView.js +1 -1
- package/dist/features/account/components/AddressBook.js +1 -1
- package/dist/features/account/components/AddressForm.js +10 -2
- package/dist/features/account/components/AddressesIndexListing.js +1 -1
- package/dist/features/account/components/BuyerAccountGuideView.js +1 -1
- package/dist/features/account/components/BuyerAuctionsGuideView.js +1 -1
- package/dist/features/account/components/BuyerOrdersGuideView.js +1 -1
- package/dist/features/account/components/BuyerShoppingGuideView.js +1 -1
- package/dist/features/account/components/ChatWindow.js +1 -1
- package/dist/features/account/components/MessagesView.js +1 -1
- package/dist/features/account/components/NotificationBell.js +25 -10
- package/dist/features/account/components/NotificationPreferencesPanel.js +2 -2
- package/dist/features/account/components/UserOffersPanel.js +1 -0
- package/dist/features/account/components/UserSidebar.js +1 -6
- package/dist/features/account/components/UserSupportView.js +1 -1
- package/dist/features/admin/components/AdminAnalyticsGuideView.js +2 -2
- package/dist/features/admin/components/AdminBlogEditorView.js +1 -1
- package/dist/features/admin/components/AdminBundlesView.js +1 -1
- package/dist/features/admin/components/AdminCarouselEditorView.js +1 -1
- package/dist/features/admin/components/AdminCatalogGuideView.js +2 -2
- package/dist/features/admin/components/AdminContentGuideView.js +2 -2
- package/dist/features/admin/components/AdminEmployeeEditorView.js +2 -2
- package/dist/features/admin/components/AdminGuideHubView.js +1 -5
- package/dist/features/admin/components/AdminMediaView.js +1 -1
- package/dist/features/admin/components/AdminNavigationView.js +1 -1
- package/dist/features/admin/components/AdminOrdersGuideView.js +3 -3
- package/dist/features/admin/components/AdminPayoutsView.js +1 -4
- package/dist/features/admin/components/AdminSidebar.js +1 -6
- package/dist/features/admin/components/AdminSiteConfigGuideView.js +1 -1
- package/dist/features/admin/components/AdminSiteSettingsView.js +9 -1
- package/dist/features/admin/components/AdminStoreEditorView.js +1 -1
- package/dist/features/admin/components/AdminStoresGuideView.js +2 -2
- package/dist/features/admin/components/AdminSupportTicketDetailView.js +7 -7
- package/dist/features/admin/components/AdminTeamGuideView.js +2 -2
- package/dist/features/admin/components/AdminTrustGuideView.js +3 -3
- package/dist/features/admin/components/AdminUsersGuideView.js +3 -3
- package/dist/features/admin/components/DashboardStats.js +6 -5
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/components/analytics/AdminAnalyticsCharts.js +4 -6
- package/dist/features/admin/components/analytics/AdminStatCard.js +4 -3
- package/dist/features/admin/components/analytics/AdminTopProductsTable.js +1 -1
- package/dist/features/auctions/components/AuctionBidsTable.js +1 -1
- package/dist/features/auctions/components/AuctionDetailPageView.js +1 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +3 -3
- package/dist/features/auth/components/ForgotPasswordView.js +19 -8
- package/dist/features/auth/components/LoginForm.js +10 -2
- package/dist/features/auth/components/RegisterForm.js +10 -2
- package/dist/features/auth/components/ResetPasswordView.js +19 -8
- package/dist/features/auth/components/SocialAuthButtons.js +1 -1
- package/dist/features/before-after/components/BeforeAfterSlider.js +1 -1
- package/dist/features/blog/api/[slug]/route.js +1 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +1 -1
- package/dist/features/blog/components/BlogListView.js +1 -1
- package/dist/features/blog/components/BlogPostView.js +1 -1
- package/dist/features/blog/schemas/index.d.ts +2 -2
- package/dist/features/cart/components/CartDrawer.js +2 -2
- package/dist/features/cart/components/CartView.js +1 -1
- package/dist/features/cart/components/CheckoutView.js +1 -1
- package/dist/features/categories/components/BrandDetailPageView.js +2 -1
- package/dist/features/categories/components/BundleDetailView.js +1 -1
- package/dist/features/categories/components/BundleItemsPicker.js +1 -1
- package/dist/features/categories/components/CategoryBundlesListing.js +3 -1
- package/dist/features/categories/components/CategoryDetailPageView.js +1 -1
- package/dist/features/categories/components/CategoryGrid.js +2 -1
- package/dist/features/categories/components/CategoryTableColumns.js +5 -2
- package/dist/features/categories/components/CategoryTree.js +3 -2
- package/dist/features/categories/components/ConcernCard.js +1 -1
- package/dist/features/categories/schemas/index.d.ts +2 -2
- package/dist/features/checkout/components/CheckoutStepper.js +1 -1
- package/dist/features/collections/components/CollectionCard.js +1 -1
- package/dist/features/contact/components/ContactPageView.js +27 -27
- package/dist/features/contact/email.d.ts +1 -0
- package/dist/features/contact/email.js +17 -5
- package/dist/features/copilot/components/AdminCopilotView.js +3 -3
- package/dist/features/email/primitives.d.ts +4 -0
- package/dist/features/email/primitives.js +4 -0
- package/dist/features/events/components/EventCard.js +2 -2
- package/dist/features/events/components/EventOfferCard.js +1 -1
- package/dist/features/events/components/EventRaffleEntryForm.js +1 -1
- package/dist/features/events/components/EventRaffleWinnerView.js +2 -2
- package/dist/features/events/components/EventSaleBanner.js +0 -1
- package/dist/features/events/schemas/index.d.ts +2 -2
- package/dist/features/faq/components/ContactCTA.js +1 -1
- package/dist/features/faq/components/FAQAccordion.js +2 -2
- package/dist/features/faq/components/FAQCategorySidebar.js +2 -2
- package/dist/features/faq/components/FAQHelpfulButtons.js +2 -2
- package/dist/features/faq/components/RelatedFAQs.js +1 -1
- package/dist/features/faq/schemas/index.d.ts +2 -2
- package/dist/features/filters/AsyncFacetSection.js +3 -3
- package/dist/features/filters/FilterFacetSection.js +6 -6
- package/dist/features/filters/RangeFilter.js +2 -2
- package/dist/features/filters/SwitchFilter.js +1 -1
- package/dist/features/forms/Checkbox.js +1 -1
- package/dist/features/forms/Slider.js +7 -2
- package/dist/features/forms/utils.d.ts +2 -2
- package/dist/features/forms/utils.js +2 -2
- package/dist/features/history/hooks/useHistory.js +1 -1
- package/dist/features/homepage/components/AdSlot.js +3 -3
- package/dist/features/homepage/components/AdvertisementBanner.js +5 -4
- package/dist/features/homepage/components/BeforeAfterCard.js +9 -1
- package/dist/features/homepage/components/CharacterHotspot.js +42 -49
- package/dist/features/homepage/components/CharacterHotspotForm.js +18 -20
- package/dist/features/homepage/components/CollectionCardsSection.js +2 -2
- package/dist/features/homepage/components/CustomCardsSection.js +3 -6
- package/dist/features/homepage/components/CustomerReviewsSection.js +1 -1
- package/dist/features/homepage/components/FAQSection.js +2 -2
- package/dist/features/homepage/components/FeaturedResultsSection.js +1 -1
- package/dist/features/homepage/components/GoogleReviewsSection.js +4 -4
- package/dist/features/homepage/components/HeroBanner.js +12 -63
- package/dist/features/homepage/components/HeroCarousel.js +6 -6
- package/dist/features/homepage/components/HeroSection.js +1 -1
- package/dist/features/homepage/components/HowItWorksInfoView.js +1 -1
- package/dist/features/homepage/components/HowItWorksSection.js +5 -3
- package/dist/features/homepage/components/NewsletterBanner.js +3 -7
- package/dist/features/homepage/components/PromoGrid.js +2 -26
- package/dist/features/homepage/components/SectionCarousel.js +1 -1
- package/dist/features/homepage/components/SecurityHighlightsSection.js +6 -3
- package/dist/features/homepage/components/ShopByCategorySection.js +3 -3
- package/dist/features/homepage/components/SiteFeaturesSection.js +1 -1
- package/dist/features/homepage/components/SocialPostCard.js +2 -3
- package/dist/features/homepage/components/StatsCounterSection.js +6 -3
- package/dist/features/homepage/components/TestimonialsCarousel.js +2 -25
- package/dist/features/homepage/components/TrustBadges.js +1 -9
- package/dist/features/homepage/components/TrustFeaturesSection.js +6 -3
- package/dist/features/homepage/components/TrustIndicatorsSection.js +1 -1
- package/dist/features/homepage/components/WelcomeSection.js +2 -2
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +1 -1
- package/dist/features/homepage/lib/franchise-colors.d.ts +7 -0
- package/dist/features/homepage/lib/franchise-colors.js +7 -0
- package/dist/features/homepage/lib/live-stats.js +5 -5
- package/dist/features/layout/AppLayoutShell.js +7 -9
- package/dist/features/layout/BottomNavbar.js +1 -2
- package/dist/features/messages/hooks/useConversation.js +2 -1
- package/dist/features/messages/hooks/useConversations.js +1 -0
- package/dist/features/orders/components/OrdersList.js +1 -1
- package/dist/features/orders/components/RefundHistoryTable.d.ts +6 -0
- package/dist/features/orders/components/RefundHistoryTable.js +3 -2
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +2 -2
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +2 -1
- package/dist/features/products/components/CompareOverlay.js +11 -8
- package/dist/features/products/components/CustomSectionTabContent.js +1 -1
- package/dist/features/products/components/FeatureBadge.js +11 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -2
- package/dist/features/products/components/MarketplaceBundleCard.js +1 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +2 -2
- package/dist/features/products/components/PrizeDrawItemsEditor.js +1 -1
- package/dist/features/products/components/PrizeDrawsIndexListing.js +1 -1
- package/dist/features/products/components/ProductCardMetadataSection.js +0 -1
- package/dist/features/products/components/ProductDetailPageView.js +1 -1
- package/dist/features/products/components/ProductFeatureBadges.js +1 -1
- package/dist/features/products/components/ProductGalleryClient.js +1 -1
- package/dist/features/products/components/ProductGrid.js +7 -7
- package/dist/features/products/components/ShareButton.js +1 -1
- package/dist/features/products/components/ShowGroupSection.js +7 -5
- package/dist/features/products/components/SublistingCarouselSection.js +2 -2
- package/dist/features/products/schemas/index.d.ts +2 -2
- package/dist/features/promotions/components/CouponCard.js +2 -2
- package/dist/features/promotions/schemas/index.d.ts +2 -2
- package/dist/features/reviews/components/ReviewDetailShell.js +3 -3
- package/dist/features/reviews/components/ReviewModal.js +2 -4
- package/dist/features/reviews/components/ReviewSummary.js +3 -2
- package/dist/features/reviews/components/ReviewsList.js +1 -1
- package/dist/features/scams/actions/scam-actions.js +1 -1
- package/dist/features/scams/components/ScamProfileView.js +1 -1
- package/dist/features/search/components/Search.js +2 -2
- package/dist/features/search/components/SearchFiltersRow.js +1 -1
- package/dist/features/search/schemas/index.d.ts +1 -1
- package/dist/features/seller/components/PhysicalLocationModal.js +2 -3
- package/dist/features/seller/components/SellerAddressesView.js +2 -1
- package/dist/features/seller/components/SellerAnalyticsAlertsView.js +1 -1
- package/dist/features/seller/components/SellerBidsView.js +1 -1
- package/dist/features/seller/components/SellerCouponEditorView.js +1 -1
- package/dist/features/seller/components/SellerGoogleReviewsView.js +1 -1
- package/dist/features/seller/components/SellerLiveView.js +1 -1
- package/dist/features/seller/components/SellerOffersPanel.js +1 -0
- package/dist/features/seller/components/SellerOrdersView.js +1 -1
- package/dist/features/seller/components/SellerPayoutMethodsView.js +8 -2
- package/dist/features/seller/components/SellerPayoutRequestView.js +1 -1
- package/dist/features/seller/components/SellerPayoutSettingsView.js +1 -1
- package/dist/features/seller/components/SellerProductShell.js +2 -2
- package/dist/features/seller/components/SellerProductsCards.js +1 -1
- package/dist/features/seller/components/SellerProductsView.js +1 -1
- package/dist/features/seller/components/SellerReviewsView.js +2 -1
- package/dist/features/seller/components/SellerShippingConfigsView.js +9 -3
- package/dist/features/seller/components/SellerShippingView.js +1 -1
- package/dist/features/seller/components/SellerSidebar.js +3 -8
- package/dist/features/seller/components/SellerStoreCategoriesView.js +11 -3
- package/dist/features/seller/components/SellerTemplatesView.js +8 -2
- package/dist/features/seller/components/analytics/SellerRevenueChart.js +1 -1
- package/dist/features/seller/components/analytics/SellerTopProducts.js +1 -1
- package/dist/features/seller/schemas/index.d.ts +2 -2
- package/dist/features/shell/FormShell.js +2 -2
- package/dist/features/shell/QuickFormDrawer.js +1 -1
- package/dist/features/site-settings/components/NavPermissionsManager.js +1 -1
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +1 -1
- package/dist/features/stores/components/StoreGuideHubView.js +2 -9
- package/dist/features/stores/components/StoreHeader.js +1 -1
- package/dist/features/stores/components/StoreListingsGuideView.js +4 -4
- package/dist/features/stores/components/StoreOrdersGuideView.js +2 -2
- package/dist/features/stores/components/StoresIndexListing.js +1 -1
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +2 -2
- package/dist/features/wishlist/components/WishlistPage.js +1 -1
- package/dist/features/wishlist/components/WishlistToggleButton.js +3 -3
- package/dist/features/wishlist/hooks/useWishlistCount.js +1 -1
- package/dist/http/ApiClient.d.ts +1 -0
- package/dist/http/ApiClient.js +20 -0
- package/dist/monitoring/error-tracking.d.ts +0 -3
- package/dist/monitoring/error-tracking.js +1 -1
- package/dist/monitoring/server-logger.js +3 -3
- package/dist/next/components/GlobalError.js +1 -1
- package/dist/react/ErrorBoundary.js +1 -1
- package/dist/styles.css +45 -7
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-light.js +3 -0
- package/dist/tokens/tokens.css +43 -6
- package/dist/ui/components/Anchor.d.ts +8 -1
- package/dist/ui/components/Anchor.js +16 -2
- package/dist/ui/components/Button.d.ts +5 -2
- package/dist/ui/components/Button.js +5 -2
- package/dist/ui/components/Details.d.ts +33 -2
- package/dist/ui/components/Details.js +73 -4
- package/dist/ui/components/Div.d.ts +3 -0
- package/dist/ui/components/Div.js +12 -1
- package/dist/ui/components/DynamicBgDiv.d.ts +13 -0
- package/dist/ui/components/DynamicBgDiv.js +18 -0
- package/dist/ui/components/Form.d.ts +3 -19
- package/dist/ui/components/Form.js +8 -1
- package/dist/ui/components/Layout.d.ts +12 -1
- package/dist/ui/components/Layout.js +9 -1
- package/dist/ui/components/Progress.d.ts +1 -1
- package/dist/ui/components/Progress.js +1 -0
- package/dist/ui/components/Progress.style.css +1 -0
- package/dist/ui/components/ProgressBarFill.d.ts +6 -0
- package/dist/ui/components/ProgressBarFill.js +11 -0
- package/dist/ui/components/Semantic.d.ts +26 -7
- package/dist/ui/components/Semantic.js +33 -8
- package/dist/ui/components/TextLink.d.ts +36 -1
- package/dist/ui/components/TextLink.js +30 -2
- package/dist/ui/components/Typography.d.ts +26 -6
- package/dist/ui/components/Typography.js +37 -13
- package/dist/ui/components/VacationBanner.js +0 -1
- package/dist/ui/components/surface-tokens.d.ts +12 -2
- package/dist/ui/components/surface-tokens.js +19 -1
- package/dist/ui/rich-text/RichText.js +1 -1
- package/dist/validation/schemas.d.ts +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { Button, Div, Input, Row, Span, Stack, Text } from "../../ui";
|
|
5
5
|
import { cn } from "./filterUtils";
|
|
6
|
-
const CLS_BADGE_COUNT = "inline-flex items-center justify-center w-5 h-5 rounded-full bg-success-surface dark:bg-success-surface text-success dark:text-success ring-1 ring-
|
|
6
|
+
const CLS_BADGE_COUNT = "inline-flex items-center justify-center w-5 h-5 rounded-full bg-success-surface dark:bg-success-surface text-success dark:text-success ring-1 ring-success/20";
|
|
7
7
|
const CLS_CLEAR_ICON = "inline-flex items-center justify-center w-5 h-5 p-0 text-zinc-500 dark:text-zinc-400 hover:text-error dark:hover:text-error hover:bg-zinc-100 dark:hover:bg-slate-700 transition-colors rounded-full";
|
|
8
8
|
/**
|
|
9
9
|
* AsyncFacetSection — collapsible filter section that loads options from the API
|
|
@@ -62,6 +62,6 @@ export function AsyncFacetSection({ title, selected, onChange, loadOptions, sele
|
|
|
62
62
|
.slice(0, 3);
|
|
63
63
|
return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: () => setCollapsed((c) => !c), variant: "ghost", size: "sm", className: "flex-1 justify-between text-sm font-semibold text-zinc-900 dark:text-zinc-50 py-1 hover:opacity-80 transition-opacity", "aria-expanded": !collapsed, children: [_jsxs(Row, { as: Span, gap: "xs", children: [title, hasValue && (_jsx(Span, { size: "xs", className: CLS_BADGE_COUNT, children: selected.length }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", collapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: CLS_CLEAR_ICON, "aria-label": "Clear filter", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), collapsed && hasValue && (_jsxs(Row, { wrap: true, gap: "xs", className: "mt-2", children: [selectedLabels.map((label) => (_jsx(Span, { layout: "inline-flex", size: "xs", border: "default", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", children: label }, label))), selected.length > 3 && (_jsxs(Span, { layout: "inline-flex", size: "xs", rounded: "full", padding: "pill-xs", color: "faint", children: ["+", selected.length - 3, " more"] }))] })), _jsx(Div, { className: "mt-2", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: query, onChange: (e) => handleQueryChange(e.target.value), className: "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20" }) }), !collapsed && (_jsxs(Stack, { className: "mt-3", gap: "xs", children: [options.map((opt) => {
|
|
64
64
|
const isSelected = selected.includes(opt.value);
|
|
65
|
-
return (_jsxs(Row, { gap: "2.5", className: "cursor-pointer group", padding: "y-2xs", children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(opt.value), "aria-label": opt.label, className: "flex-shrink-0 w-4 h-4 rounded border-zinc-300 dark:border-slate-600 cursor-pointer text-primary-600 dark:text-secondary-500" }), _jsx(Span, { size: "sm", className: "flex-1 group-hover:text-
|
|
66
|
-
}), options.length === 0 && !loading && (_jsx(Text, { paddingY: "2xs", color: "faint", size: "xs", children: "No results" })), loading && (_jsx(Text, { paddingY: "2xs", className: "animate-pulse", color: "faint", size: "xs", children: "Loading\u2026" })), hasMore && !loading && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", textSize: "xs", textColor: "faint", className: "w-full text-left hover:text-
|
|
65
|
+
return (_jsxs(Row, { gap: "2.5", className: "cursor-pointer group", padding: "y-2xs", children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(opt.value), "aria-label": opt.label, className: "flex-shrink-0 w-4 h-4 rounded border-zinc-300 dark:border-slate-600 cursor-pointer text-primary-600 dark:text-secondary-500" }), _jsx(Span, { size: "sm", className: "flex-1 group-hover:text-[var(--appkit-color-text)] transition-colors truncate", color: "muted", children: opt.label }), opt.count !== undefined && (_jsx(Span, { size: "xs", className: "tabular-nums flex-shrink-0", color: "faint", children: opt.count }))] }, opt.value));
|
|
66
|
+
}), options.length === 0 && !loading && (_jsx(Text, { paddingY: "2xs", color: "faint", size: "xs", children: "No results" })), loading && (_jsx(Text, { paddingY: "2xs", className: "animate-pulse", color: "faint", size: "xs", children: "Loading\u2026" })), hasMore && !loading && (_jsx(Button, { type: "button", variant: "ghost", size: "sm", textSize: "xs", textColor: "faint", className: "w-full text-left hover:text-[var(--appkit-color-text)] py-[0.25rem]", onClick: () => void load(query, page + 1), children: "Load more\u2026" }))] }))] }));
|
|
67
67
|
}
|
|
@@ -9,7 +9,7 @@ const __O = {
|
|
|
9
9
|
const CLS_OPTION_SELECTED = "border-success bg-success-surface text-success dark:border-success/60 dark:bg-success-surface dark:text-success";
|
|
10
10
|
const CLS_OPTION_DOT = "inline-flex h-4 w-4 items-center justify-center rounded-full bg-success-surface text-[10px] text-white";
|
|
11
11
|
const CLS_CLEAR_BTN = "w-full py-1 text-xs text-zinc-400 transition-colors hover:text-error";
|
|
12
|
-
const CLS_BADGE_COUNT = "inline-flex items-center justify-center w-5 h-5 rounded-full bg-success-surface dark:bg-success-surface text-success dark:text-success ring-1 ring-
|
|
12
|
+
const CLS_BADGE_COUNT = "inline-flex items-center justify-center w-5 h-5 rounded-full bg-success-surface dark:bg-success-surface text-success dark:text-success ring-1 ring-success/20";
|
|
13
13
|
const CLS_CLEAR_ICON = "inline-flex items-center justify-center w-5 h-5 p-0 text-zinc-500 dark:text-zinc-400 hover:text-error dark:hover:text-error hover:bg-zinc-100 dark:hover:bg-slate-700 transition-colors rounded-full";
|
|
14
14
|
/**
|
|
15
15
|
* FilterFacetSection — collapsible checkbox/radio filter section.
|
|
@@ -71,12 +71,12 @@ export function FilterFacetSection({ title, options, selected, onChange, selecti
|
|
|
71
71
|
? CLS_OPTION_SELECTED
|
|
72
72
|
: "border-zinc-200 bg-white text-zinc-700 hover:border-zinc-400 dark:border-slate-700 dark:bg-slate-900 dark:text-zinc-200 dark:hover:border-slate-500"), children: [title, hasValue && (_jsx(Span, { weight: "bold", className: CLS_OPTION_DOT, children: selected.length })), _jsx("svg", { className: cn("h-3.5 w-3.5 text-zinc-400 transition-transform", dropdownOpen ? "rotate-180" : ""), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), dropdownOpen && (_jsxs(Div, { className: "absolute left-0 top-full z-[var(--appkit-z-dropdown,50)] mt-1 min-w-[180px] max-w-[260px]", surface: "default", rounded: "xl", shadow: "lg", border: "default", children: [searchable && (_jsx(Div, { border: "subtle", className: "border-b", padding: "xs", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: search, onChange: (e) => handleSearch(e.target.value), className: "w-full rounded-md border border-zinc-200 bg-white px-2 py-1 text-xs text-zinc-900 focus:outline-none dark:border-slate-700 dark:bg-slate-800/60 dark:text-zinc-100" }) })), _jsxs(Div, { className: `max-h-56 ${__O.yAuto}`, padding: "y-2xs", children: [filtered.map((option) => {
|
|
73
73
|
const isSelected = selected.includes(option.value);
|
|
74
|
-
return (_jsxs(Row, { gap: "xs", className: "cursor-pointer py-
|
|
75
|
-
}), filtered.length === 0 && (_jsx(Text, { paddingY: "xs",
|
|
74
|
+
return (_jsxs(Row, { gap: "xs", className: "cursor-pointer py-[0.375rem] hover:bg-[var(--appkit-color-bg)] mx-1", padding: "x-sm", rounded: "lg", onClick: () => toggle(option.value), children: [_jsx("input", { type: selectionMode === "single" ? "radio" : "checkbox", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: "h-3.5 w-3.5 flex-shrink-0 cursor-pointer rounded border-zinc-300 text-primary-600 dark:border-slate-600 dark:text-secondary-500" }), _jsx(Span, { size: "xs", className: "flex-1 truncate", color: "muted", children: option.label }), option.count !== undefined && (_jsx(Span, { className: "flex-shrink-0 text-[10px] tabular-nums", color: "faint", children: option.count }))] }, option.value));
|
|
75
|
+
}), filtered.length === 0 && (_jsx(Text, { paddingY: "xs", paddingX: "x-sm", color: "faint", size: "xs", children: "No results" }))] }), hasValue && (_jsx(Div, { border: "subtle", className: "border-t p-[0.25rem]", children: _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: CLS_CLEAR_BTN, onClick: () => { onChange([]); onClear?.(); setDropdownOpen(false); }, children: "Clear" }) }))] }))] }));
|
|
76
76
|
}
|
|
77
77
|
// ── Accordion variant (default) ─────────────────────────────────────────
|
|
78
|
-
return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: handleToggle, variant: "ghost", size: "sm", className: "flex-1 justify-between text-
|
|
78
|
+
return (_jsxs(Div, { className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "xs", children: [_jsxs(Button, { type: "button", onClick: handleToggle, variant: "ghost", size: "sm", className: "flex-1 justify-[space-between] text-[0.875rem] font-[600] text-[var(--appkit-color-text)] py-[0.25rem] hover:opacity-80 transition-opacity", "aria-expanded": !isCollapsed, children: [_jsxs(Row, { as: Span, gap: "xs", children: [title, hasValue && (_jsx(Span, { size: "xs", className: CLS_BADGE_COUNT, children: selected.length }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", isCollapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: CLS_CLEAR_ICON, "aria-label": "Clear filter", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), isCollapsed && hasValue && (_jsxs(Row, { wrap: true, gap: "xs", className: "mt-2", children: [selectedLabels.map((label) => (_jsx(Span, { layout: "inline-flex", size: "xs", className: "border border-[var(--appkit-color-border)]", rounded: "full", padding: "pill-xs", surface: "subtle", color: "muted", children: label }, label))), selected.length > 3 && (_jsxs(Span, { layout: "inline-flex", size: "xs", rounded: "full", padding: "pill-xs", color: "faint", children: ["+", selected.length - 3, " more"] }))] })), searchable && (_jsx(Div, { className: "mt-2", children: _jsx(Input, { type: "search", placeholder: "Search\u2026", value: search, onChange: (e) => handleSearch(e.target.value), className: "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20" }) })), !isCollapsed && (_jsxs(Stack, { className: "mt-3", gap: "xs", children: [filtered.map((option) => {
|
|
79
79
|
const isSelected = selected.includes(option.value);
|
|
80
|
-
return (_jsxs(Row, { gap: "2.5", className: "cursor-pointer group", padding: "y-2xs", children: [selectionMode === "single" ? (_jsx("input", { type: "radio", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded-full text-primary-600 dark:text-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })) : (_jsx("input", { type: "checkbox", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded text-primary-600 dark:text-secondary-500 checked:bg-primary-600 dark:checked:bg-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })), _jsx(Span, { size: "sm", className: "flex-1 group-hover:text-
|
|
81
|
-
}), filtered.length === 0 && (_jsx(Text, {
|
|
80
|
+
return (_jsxs(Row, { gap: "2.5", className: "cursor-pointer group", padding: "y-2xs", children: [selectionMode === "single" ? (_jsx("input", { type: "radio", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded-full text-primary-600 dark:text-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })) : (_jsx("input", { type: "checkbox", checked: isSelected, onChange: () => toggle(option.value), "aria-label": option.label, className: cn("flex-shrink-0 border-zinc-300 dark:border-slate-600 cursor-pointer", "w-4 h-4 rounded text-primary-600 dark:text-secondary-500 checked:bg-primary-600 dark:checked:bg-secondary-500", "focus:ring-primary-500/30 dark:focus:ring-secondary-400/30") })), _jsx(Span, { size: "sm", className: "flex-1 group-hover:text-[var(--appkit-color-text)] transition-colors truncate", color: "muted", children: option.label }), option.count !== undefined && (_jsx(Span, { size: "xs", className: "tabular-nums flex-shrink-0", color: "faint", children: option.count }))] }, option.value));
|
|
81
|
+
}), filtered.length === 0 && (_jsx(Text, { paddingY: "2xs", color: "faint", size: "xs", children: "No results" }))] }))] }));
|
|
82
82
|
}
|
|
@@ -3,7 +3,7 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Button, Div, Input, Row, Slider, Span, Stack, Text } from "../../ui";
|
|
5
5
|
import { cn } from "./filterUtils";
|
|
6
|
-
const CLS_BADGE_COUNT = "inline-flex items-center justify-center w-5 h-5 rounded-full bg-success-surface dark:bg-success-surface text-success dark:text-success ring-1 ring-
|
|
6
|
+
const CLS_BADGE_COUNT = "inline-flex items-center justify-center w-5 h-5 rounded-full bg-success-surface dark:bg-success-surface text-success dark:text-success ring-1 ring-success/20";
|
|
7
7
|
const CLS_CLEAR_BTN = "inline-flex items-center justify-center w-5 h-5 text-zinc-500 dark:text-zinc-400 hover:text-error dark:hover:text-error rounded-full transition-colors";
|
|
8
8
|
function DualSlider({ minValue, maxValue, onMinChange, onMaxChange, minBound, maxBound, step = 1, prefix = "", }) {
|
|
9
9
|
const minNum = Math.max(minBound, Math.min(parseFloat(minValue) || minBound, maxBound));
|
|
@@ -26,5 +26,5 @@ export function RangeFilter({ title, minLabel, maxLabel, minValue, maxValue, onM
|
|
|
26
26
|
maxBound !== undefined;
|
|
27
27
|
const hasValue = !!(minValue || maxValue);
|
|
28
28
|
const inputClass = "w-full rounded-md border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-2.5 py-1.5 text-xs text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20";
|
|
29
|
-
return (_jsxs(Div, { role: "group", "aria-labelledby": `rf-${title}`, className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { align: "center", gap: "sm", children: [_jsxs(Button, { type: "button", id: `rf-${title}`, onClick: handleToggle, variant: "ghost", size: "sm", className: "flex-1 justify-between text-
|
|
29
|
+
return (_jsxs(Div, { role: "group", "aria-labelledby": `rf-${title}`, className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { align: "center", gap: "sm", children: [_jsxs(Button, { type: "button", id: `rf-${title}`, onClick: handleToggle, variant: "ghost", size: "sm", className: "flex-1 justify-[space-between] text-[0.875rem] font-[600] text-[var(--appkit-color-text)] py-[0.25rem] hover:opacity-80 transition-opacity", "aria-expanded": !isCollapsed, children: [_jsxs(Span, { layout: "flex", gap: "md", children: [title, hasValue && (_jsx(Span, { size: "xs", className: CLS_BADGE_COUNT, children: "1" }))] }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", isCollapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), onClear && hasValue && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: CLS_CLEAR_BTN, "aria-label": "Clear", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), !isCollapsed && (_jsxs(Stack, { gap: "3", className: "mt-3", children: [canShowSlider && (_jsx(DualSlider, { minValue: minValue, maxValue: maxValue, onMinChange: onMinChange, onMaxChange: onMaxChange, minBound: minBound, maxBound: maxBound, step: step, prefix: prefix })), _jsxs(Row, { align: "end", gap: "sm", children: [_jsxs(Div, { className: "flex-1 min-w-0", children: [minLabel && (_jsx(Text, { className: "mb-1", color: "muted", size: "xs", children: minLabel })), _jsxs(Div, { className: "relative", children: [prefix && (_jsx(Span, { size: "xs", className: "absolute left-2 top-1/2 -translate-y-1/2 pointer-events-none", color: "faint", children: prefix })), _jsx(Input, { type: type, value: minValue, onChange: (e) => onMinChange(e.target.value), placeholder: minPlaceholder ?? (type === "date" ? "From" : "Min"), className: cn(inputClass, prefix ? "pl-5" : "") })] })] }), _jsx(Span, { size: "xs", className: "flex-shrink-0 pb-[0.375rem]", color: "faint", children: "-" }), _jsxs(Div, { className: "flex-1 min-w-0", children: [maxLabel && (_jsx(Text, { className: "mb-1", color: "muted", size: "xs", children: maxLabel })), _jsxs(Div, { className: "relative", children: [prefix && (_jsx(Span, { size: "xs", className: "absolute left-2 top-1/2 -translate-y-1/2 pointer-events-none", color: "faint", children: prefix })), _jsx(Input, { type: type, value: maxValue, onChange: (e) => onMaxChange(e.target.value), placeholder: maxPlaceholder ?? (type === "date" ? "To" : "Max"), className: cn(inputClass, prefix ? "pl-5" : "") })] })] })] })] }))] }));
|
|
30
30
|
}
|
|
@@ -14,5 +14,5 @@ export function SwitchFilter({ title, label, checked, onChange, defaultCollapsed
|
|
|
14
14
|
else
|
|
15
15
|
setInternalCollapsed((c) => !c);
|
|
16
16
|
};
|
|
17
|
-
return (_jsxs(Div, { role: "group", "aria-labelledby": `sf-${title}`, className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "sm", children: [_jsxs(Button, { type: "button", id: `sf-${title}`, onClick: handleToggle, variant: "ghost", size: "sm", className: "flex-1 justify-between text-
|
|
17
|
+
return (_jsxs(Div, { role: "group", "aria-labelledby": `sf-${title}`, className: cn("p-4 border-b border-zinc-200 dark:border-slate-700 last:border-b-0", className), children: [_jsxs(Row, { gap: "sm", children: [_jsxs(Button, { type: "button", id: `sf-${title}`, onClick: handleToggle, variant: "ghost", size: "sm", className: "flex-1 justify-[space-between] text-[0.875rem] font-[600] text-[var(--appkit-color-text)] py-[0.25rem] hover:opacity-80 transition-opacity", "aria-expanded": !isCollapsed, children: [_jsx(Text, { size: "sm", weight: "semibold", color: "primary", children: title }), _jsx("svg", { className: cn("w-4 h-4 text-zinc-500 dark:text-zinc-400 transition-transform duration-200", isCollapsed ? "" : "rotate-180"), fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19 9l-7 7-7-7" }) })] }), checked && onClear && (_jsx(Button, { type: "button", onClick: onClear, variant: "ghost", size: "sm", className: CLS_CLEAR_BTN, "aria-label": "Clear", children: _jsx("svg", { className: "w-3 h-3", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) }))] }), !isCollapsed && (_jsxs(Row, { className: "mt-3", align: "center", justify: "between", gap: "3", children: [_jsx(Span, { size: "sm", color: "muted", children: label }), _jsx(Toggle, { checked: checked, onChange: onChange, size: "sm" })] }))] }));
|
|
18
18
|
}
|
|
@@ -12,5 +12,5 @@ export function Checkbox({ label, suffix, error, indeterminate, className = "",
|
|
|
12
12
|
}, [indeterminate]);
|
|
13
13
|
return (_jsxs(Div, { className: "w-full", children: [_jsxs("label", { className: "flex flex-row items-center gap-3 cursor-pointer group", children: [_jsxs(Row, { className: "relative flex-shrink-0", align: "center", justify: "center", children: [_jsx("input", { ref: inputRef, type: "checkbox", checked: checked, className: cn("peer w-5 h-5 rounded-md border-2 cursor-pointer", "transition-all duration-200 appearance-none", error
|
|
14
14
|
? "border-error dark:border-error"
|
|
15
|
-
: "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { layout: "flex", gap: "md", size: "sm", className: "group-hover:text-
|
|
15
|
+
: "border-zinc-300 dark:border-slate-600", "checked:bg-primary-600 checked:border-primary-600", "dark:checked:bg-secondary-500 dark:checked:border-secondary-500", "hover:border-primary-400 dark:hover:border-secondary-400", "focus:outline-none focus:ring-2 focus:ring-primary-500/30 focus:ring-offset-1", "dark:focus:ring-secondary-400/30 dark:focus:ring-offset-slate-900", "disabled:opacity-50 disabled:cursor-not-allowed", className), ...props }), _jsx("svg", { className: "absolute w-3 h-3 text-white pointer-events-none opacity-0 peer-checked:opacity-100 transition-opacity duration-150", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: indeterminate ? (_jsx("line", { x1: "2", y1: "6", x2: "10", y2: "6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })) : (_jsx("path", { d: "M2 6L5 9L10 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })) })] }), (label || suffix) && (_jsxs(Span, { layout: "flex", gap: "md", size: "sm", className: "group-hover:text-[var(--appkit-color-text)] transition-colors", color: "muted", children: [label, suffix] }))] }), error && (_jsx(Text, { className: cn(ERROR_BASE, "mt-1.5"), role: "alert", children: error }))] }));
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React from "react";
|
|
3
|
+
import React, { useRef, useEffect } from "react";
|
|
4
4
|
import { Div, Row, Span, Text } from "../../ui";
|
|
5
5
|
import { cn, LABEL_BASE, ERROR_BASE } from "./utils";
|
|
6
6
|
/**
|
|
@@ -11,6 +11,11 @@ export function Slider({ value: controlledValue, defaultValue = 0, min = 0, max
|
|
|
11
11
|
const value = controlledValue !== undefined ? controlledValue : internalValue;
|
|
12
12
|
const sliderId = id ?? React.useId();
|
|
13
13
|
const pct = ((value - min) / (max - min)) * 100;
|
|
14
|
+
const fillRef = useRef(null);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (fillRef.current)
|
|
17
|
+
fillRef.current.style.width = `${pct}%`;
|
|
18
|
+
}, [pct]);
|
|
14
19
|
const handleChange = (e) => {
|
|
15
20
|
const newVal = Number(e.target.value);
|
|
16
21
|
if (controlledValue === undefined)
|
|
@@ -18,5 +23,5 @@ export function Slider({ value: controlledValue, defaultValue = 0, min = 0, max
|
|
|
18
23
|
onChange?.(newVal);
|
|
19
24
|
};
|
|
20
25
|
const displayValue = formatValue ? formatValue(value) : String(value);
|
|
21
|
-
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { size: "sm", weight: "semibold", className: "tabular-nums", color: "primary", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Row, { className: "absolute inset-y-0 w-full", align: "center", children: _jsx(Div, { className: "w-full h-1.5", surface: "subtle", rounded: "full", children: _jsx(
|
|
26
|
+
return (_jsxs(Div, { className: cn("w-full space-y-2", className), children: [(label || showValue) && (_jsxs(Row, { justify: "between", children: [label && (_jsx("label", { htmlFor: sliderId, className: LABEL_BASE, children: label })), showValue && (_jsx(Span, { size: "sm", weight: "semibold", className: "tabular-nums", color: "primary", children: displayValue }))] })), _jsxs(Row, { className: "relative h-5", children: [_jsx(Row, { className: "absolute inset-y-0 w-full", align: "center", children: _jsx(Div, { className: "w-full h-1.5", surface: "subtle", rounded: "full", children: _jsx("div", { ref: fillRef, className: "h-full bg-primary-500 dark:bg-secondary-500 transition-all rounded-full" }) }) }), _jsx("input", { type: "range", id: sliderId, min: min, max: max, step: step, value: value, disabled: disabled, onChange: handleChange, className: cn("relative w-full appearance-none bg-transparent cursor-pointer", "focus:outline-none", "[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4", "[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white", "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-500 dark:[&::-webkit-slider-thumb]:border-secondary-500", "[&::-webkit-slider-thumb]:shadow-sm", "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4", "[&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white", "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary-500 dark:[&::-moz-range-thumb]:border-secondary-500", disabled && "opacity-50 cursor-not-allowed") })] }), _jsxs(Row, { color: "muted", textSize: "xs", justify: "between", children: [_jsx(Span, { children: formatValue ? formatValue(min) : min }), _jsx(Span, { children: formatValue ? formatValue(max) : max })] }), error && (_jsx(Text, { className: ERROR_BASE, role: "alert", children: error }))] }));
|
|
22
27
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/** Simple class-name concatenation utility. */
|
|
2
2
|
export declare function cn(...classes: (string | undefined | null | false)[]): string;
|
|
3
3
|
export declare const INPUT_BASE = "rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3.5 py-2.5 text-sm text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20 focus:border-primary-500 dark:focus:border-secondary-400 focus:outline-none transition-colors duration-150 placeholder:text-zinc-400 dark:placeholder:text-zinc-500";
|
|
4
|
-
export declare const INPUT_ERROR = "border-
|
|
5
|
-
export declare const INPUT_SUCCESS = "border-
|
|
4
|
+
export declare const INPUT_ERROR = "border-error focus:ring-error/20 focus:border-error bg-error-surface/30";
|
|
5
|
+
export declare const INPUT_SUCCESS = "border-success focus:ring-success/20 focus:border-success";
|
|
6
6
|
export declare const INPUT_DISABLED = "bg-zinc-50 dark:bg-slate-800/30 text-zinc-400 dark:text-zinc-400 cursor-not-allowed opacity-60";
|
|
7
7
|
export declare const INPUT_WITH_ICON = "pl-10";
|
|
8
8
|
export declare const LABEL_BASE = "block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5";
|
|
@@ -4,8 +4,8 @@ export function cn(...classes) {
|
|
|
4
4
|
}
|
|
5
5
|
// --- Shared style constants ---------------------------------------------------
|
|
6
6
|
export const INPUT_BASE = "rounded-lg border border-zinc-200 dark:border-slate-700 bg-white dark:bg-slate-800/60 px-3.5 py-2.5 text-sm text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-primary-500/20 dark:focus:ring-secondary-400/20 focus:border-primary-500 dark:focus:border-secondary-400 focus:outline-none transition-colors duration-150 placeholder:text-zinc-400 dark:placeholder:text-zinc-500";
|
|
7
|
-
export const INPUT_ERROR = "border-
|
|
8
|
-
export const INPUT_SUCCESS = "border-
|
|
7
|
+
export const INPUT_ERROR = "border-error focus:ring-error/20 focus:border-error bg-error-surface/30";
|
|
8
|
+
export const INPUT_SUCCESS = "border-success focus:ring-success/20 focus:border-success";
|
|
9
9
|
export const INPUT_DISABLED = "bg-zinc-50 dark:bg-slate-800/30 text-zinc-400 dark:text-zinc-400 cursor-not-allowed opacity-60";
|
|
10
10
|
export const INPUT_WITH_ICON = "pl-10";
|
|
11
11
|
export const LABEL_BASE = "block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1.5";
|
|
@@ -19,11 +19,11 @@ function AdsenseAd({ config }) {
|
|
|
19
19
|
// AdSense not loaded yet — no-op
|
|
20
20
|
}
|
|
21
21
|
}, []);
|
|
22
|
-
return (_jsx(Div, { ref: ref, children: _jsx("ins", { className: "adsbygoogle
|
|
22
|
+
return (_jsx(Div, { ref: ref, children: _jsx("ins", { className: "adsbygoogle block", "data-ad-client": config.adsenseClient ?? "", "data-ad-slot": config.adsenseSlot ?? "", "data-ad-format": config.adsenseFormat ?? "auto", "data-full-width-responsive": "true" }) }));
|
|
23
23
|
}
|
|
24
24
|
function ThirdPartyAd({ config }) {
|
|
25
25
|
if (config.thirdPartyUrl) {
|
|
26
|
-
return (_jsx("iframe", { src: config.thirdPartyUrl, width: config.thirdPartyWidth ?? "100%", height: config.thirdPartyHeight ?? "90", scrolling: "no", frameBorder: "0", title: "Advertisement",
|
|
26
|
+
return (_jsx("iframe", { src: config.thirdPartyUrl, width: config.thirdPartyWidth ?? "100%", height: config.thirdPartyHeight ?? "90", scrolling: "no", frameBorder: "0", title: "Advertisement", className: "border-0 overflow-hidden", loading: "lazy" }));
|
|
27
27
|
}
|
|
28
28
|
return null;
|
|
29
29
|
}
|
|
@@ -31,7 +31,7 @@ function ManualAdBanner({ ad }) {
|
|
|
31
31
|
const { creative } = ad;
|
|
32
32
|
if (!creative)
|
|
33
33
|
return null;
|
|
34
|
-
return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs(Div, { className: "flex-1 min-w-0", children: [creative.title ? (_jsx(Text, { className: "truncate", color: "primary", size: "sm", weight: "semibold", children: creative.title })) : null, creative.body ? (_jsx(Text, { className: "truncate", color: "muted", size: "xs", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx(Span, { color: "inverse", size: "xs", weight: "semibold", className: "flex-shrink-0 bg-primary py-
|
|
34
|
+
return (_jsxs("a", { href: creative.ctaHref || "#", target: creative.ctaHref ? "_blank" : undefined, rel: "noopener noreferrer", className: "flex items-center gap-3 w-full overflow-hidden rounded-lg bg-zinc-100 dark:bg-zinc-800 px-4 py-3 hover:bg-zinc-200 dark:hover:bg-zinc-700 transition-colors no-underline", children: [creative.imageUrl ? (_jsx("img", { src: creative.imageUrl, alt: creative.title || "Advertisement", className: "h-14 w-14 rounded object-cover flex-shrink-0", loading: "lazy" })) : null, _jsxs(Div, { className: "flex-1 min-w-0", children: [creative.title ? (_jsx(Text, { className: "truncate", color: "primary", size: "sm", weight: "semibold", children: creative.title })) : null, creative.body ? (_jsx(Text, { className: "truncate", color: "muted", size: "xs", children: creative.body })) : null] }), creative.ctaLabel ? (_jsx(Span, { color: "inverse", size: "xs", weight: "semibold", className: "flex-shrink-0 bg-primary py-[0.375rem]", rounded: "md", padding: "x-sm", children: creative.ctaLabel })) : null] }));
|
|
35
35
|
}
|
|
36
36
|
// ---------------------------------------------------------------------------
|
|
37
37
|
// Primary component
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CARD_ASPECT_BANNER, GRID_COLS_2_MD } from "../../../_internal/shared/styles/grid";
|
|
3
3
|
import { Button, Div, Grid, Heading, Row, Scrim, Section, Span, Stack, Text } from "../../../ui";
|
|
4
|
+
import { DynamicBgDiv } from "../../../ui/components/DynamicBgDiv";
|
|
4
5
|
import { MediaImage } from "../../media/MediaImage";
|
|
5
6
|
import { ArrowRight, Sparkles } from "lucide-react";
|
|
6
7
|
const __P = {
|
|
@@ -22,13 +23,13 @@ export function AdvertisementBanner({ title, subtitle, ctaLabel = "Shop now", on
|
|
|
22
23
|
}
|
|
23
24
|
// -- Split layout: when a backgroundImage is provided --
|
|
24
25
|
if (backgroundImage) {
|
|
25
|
-
return (_jsx(Section, { className: `${__P.p8} ${wrapClass} ${className}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsx(Div, { className: `relative ${__O.hidden} bg-
|
|
26
|
+
return (_jsx(Section, { className: `${__P.p8} ${wrapClass} ${className}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsx(Div, { className: `relative ${__O.hidden} bg-neutral-900`, rounded: "2xl", shadow: "xl", children: _jsxs(Grid, { className: `${GRID_COLS_2_MD} min-h-[clamp(300px,40vh,420px)]`, children: [_jsxs(Div, { className: `relative ${CARD_ASPECT_BANNER} order-last md:order-first min-h-0 min-h-[clamp(300px,40vh,420px)]`, children: [_jsx(MediaImage, { src: backgroundImage, alt: title, size: "banner", priority: true }), _jsx(Scrim, { direction: "right-to-left", intensity: "medium", className: "hidden md:block absolute inset-y-0 right-0 w-24" })] }), _jsxs(Stack, { justify: "center", className: "relative", paddingX: "x-xl", padding: "y-2xl", children: [_jsx(Div, { className: "absolute top-0 right-0 w-32 h-32 opacity-10 pointer-events-none bg-[radial-gradient(circle,_white_1px,_transparent_1px)] bg-[length:12px_12px]", "aria-hidden": true }), tagLabel && (_jsxs(Span, { layout: "inline-flex", gap: "xs", color: "inverse", size: "xs", weight: "semibold", className: "self-start bg-[rgba(255,255,255,0.1)] /80 tracking-widest mb-5 backdrop-blur-sm", rounded: "full", padding: "pill-md", transform: "uppercase", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { color: "inverse", level: 2, variant: "none", className: "font-extrabold mb-4 leading-tight", mdSize: "4xl", lgSize: "5xl", size: "3xl", children: title }), subtitle && (_jsx(Text, { color: "inverse", variant: "none", className: "/75 mb-8 leading-relaxed", mdSize: "lg", size: "base", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { gap: "md", variant: "secondary", size: "lg", onClick: onCtaClick, className: "self-start bg-[var(--appkit-color-surface)] text-[var(--appkit-color-text)] hover:bg-neutral-100 dark:bg-neutral-100 dark:text-[var(--appkit-color-text)] dark:hover:bg-neutral-200 font-[600]", shadow: "lg", children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] })] }) }) }) }));
|
|
26
27
|
}
|
|
27
28
|
// -- Full-width gradient layout --
|
|
28
|
-
return (_jsx(Section, { className: `${__P.p8} ${wrapClass} ${className}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsxs(
|
|
29
|
-
"relative overflow-hidden rounded-2xl",
|
|
29
|
+
return (_jsx(Section, { className: `${__P.p8} ${wrapClass} ${className}`, children: _jsx(Div, { className: CLS_CONTAINER, children: _jsxs(DynamicBgDiv, { color: backgroundColor, className: [
|
|
30
|
+
"flex items-center relative overflow-hidden rounded-2xl",
|
|
30
31
|
compact
|
|
31
32
|
? "h-[clamp(112px,16vh,160px)]"
|
|
32
33
|
: "min-h-[clamp(240px,34vh,360px)]",
|
|
33
|
-
].join(" "),
|
|
34
|
+
].join(" "), children: [!backgroundColor && (_jsx(Div, { className: CLS_GRADIENT_BG, "aria-hidden": true })), _jsxs(Div, { className: `absolute inset-0 ${__O.hidden}`, "aria-hidden": true, children: [_jsx(Div, { className: "absolute -top-16 -left-16 w-64 h-64 bg-primary/20 blur-3xl animate-pulse", rounded: "full" }), _jsx(Div, { className: "absolute -bottom-16 right-0 w-80 h-80 bg-cobalt/20 blur-3xl animate-pulse", rounded: "full" })] }), compact ? (_jsxs(Row, { justify: "between", className: "relative z-10 w-full", gap: "md", padding: "inlineLg", children: [_jsxs(Span, { layout: "inline-flex", gap: "md", children: [_jsx(Sparkles, { className: "w-4 h-4 text-white/80" }), _jsx(Span, { color: "inverse", size: "sm", weight: "semibold", children: title })] }), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "sm", onClick: onCtaClick, className: CLS_CTA_BTN_SM, children: [ctaLabel, _jsx(ArrowRight, { className: "w-3.5 h-3.5" })] }))] })) : (_jsxs(Div, { className: "relative z-10 w-full max-w-4xl mx-auto md:py-[4rem] text-center", paddingY: "y-3xl", paddingX: "x-lg", children: [tagLabel && (_jsxs(Span, { layout: "inline-flex", gap: "xs", color: "inverse", size: "xs", weight: "semibold", className: "bg-[rgba(255,255,255,0.15)] /90 tracking-widest mb-5 backdrop-blur-sm", shadow: "sm", rounded: "full", padding: "pill-lg", transform: "uppercase", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), tagLabel] })), _jsx(Heading, { color: "inverse", level: 2, variant: "none", className: "font-extrabold mb-4 leading-tight", mdSize: "5xl", lgSize: "6xl", size: "3xl", shadow: "lg", children: title }), subtitle && (_jsx(Text, { color: "inverse", variant: "none", className: "mb-10 max-w-2xl mx-auto", mdSize: "xl", size: "base", children: subtitle })), ctaLabel && onCtaClick && (_jsxs(Button, { variant: "secondary", size: "lg", onClick: onCtaClick, className: CLS_CTA_BTN_LG, children: [ctaLabel, _jsx(ArrowRight, { className: "w-4 h-4" })] }))] }))] }) }) }));
|
|
34
35
|
}
|
|
@@ -11,6 +11,8 @@ const __O = {
|
|
|
11
11
|
};
|
|
12
12
|
export function BeforeAfterCard({ item, beforeLabel = "Before", afterLabel = "After", }) {
|
|
13
13
|
const containerRef = useRef(null);
|
|
14
|
+
const beforeClipRef = useRef(null);
|
|
15
|
+
const dividerRef = useRef(null);
|
|
14
16
|
const [position, setPosition] = useState(50);
|
|
15
17
|
const [dragging, setDragging] = useState(false);
|
|
16
18
|
const updatePosition = useCallback((clientX) => {
|
|
@@ -22,6 +24,12 @@ export function BeforeAfterCard({ item, beforeLabel = "Before", afterLabel = "Af
|
|
|
22
24
|
const pct = Math.max(0, Math.min(100, (x / rect.width) * 100));
|
|
23
25
|
setPosition(pct);
|
|
24
26
|
}, []);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (beforeClipRef.current)
|
|
29
|
+
beforeClipRef.current.style.width = `${position}%`;
|
|
30
|
+
if (dividerRef.current)
|
|
31
|
+
dividerRef.current.style.left = `${position}%`;
|
|
32
|
+
}, [position]);
|
|
25
33
|
useEffect(() => {
|
|
26
34
|
if (!dragging)
|
|
27
35
|
return;
|
|
@@ -55,5 +63,5 @@ export function BeforeAfterCard({ item, beforeLabel = "Before", afterLabel = "Af
|
|
|
55
63
|
setPosition((p) => Math.max(0, p - 2));
|
|
56
64
|
if (e.key === "ArrowRight")
|
|
57
65
|
setPosition((p) => Math.min(100, p + 2));
|
|
58
|
-
}, children: [_jsx(Image, { src: item.afterImage, alt: afterLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }), _jsx(
|
|
66
|
+
}, children: [_jsx(Image, { src: item.afterImage, alt: afterLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }), _jsx("div", { ref: beforeClipRef, className: "absolute inset-0 overflow-hidden", children: _jsx(Image, { src: item.beforeImage, alt: beforeLabel, fill: true, sizes: "(max-width: 640px) 100vw, 50vw", className: "object-cover" }) }), _jsx("div", { ref: dividerRef, className: "absolute top-0 bottom-0 z-10 w-0.5 bg-[var(--appkit-color-surface)] shadow-md", children: _jsx(Row, { className: "absolute top-1/2 left-1/2 h-8 w-8 -translate-x-1/2 -translate-y-1/2 bg-card", align: "center", justify: "center", rounded: "full", shadow: "lg", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 8L1 5M4 8L1 11M4 8H12M12 8L15 5M12 8L15 11", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }) }), _jsx(Span, { surface: "overlay-sm", color: "inverse", size: "xs", weight: "medium", className: "absolute top-3 left-3 z-10", padding: "pill-sm", rounded: "full", children: beforeLabel }), _jsx(Span, { surface: "overlay-sm", color: "inverse", size: "xs", weight: "medium", className: "absolute top-3 right-3 z-10", padding: "pill-sm", rounded: "full", children: afterLabel })] }), _jsx(Div, { className: `${__P.p4}`, children: _jsx(Text, { className: "text-foreground", size: "sm", weight: "medium", children: item.caption }) })] }));
|
|
59
67
|
}
|
|
@@ -15,6 +15,14 @@ const __O = {
|
|
|
15
15
|
const FALLBACK_IMAGE = "/animevssuperhero.jpg";
|
|
16
16
|
const FALLBACK_IMAGE_ALT = "DC, Marvel and Anime characters";
|
|
17
17
|
const FONT_BANGERS = "var(--font-bangers, Bangers, cursive)";
|
|
18
|
+
/* -- Franchise brand colour references — hex lives in tokens.css (exempt) -- */
|
|
19
|
+
const BRAND_MARVEL = "var(--brand-marvel)";
|
|
20
|
+
const BRAND_DC = "var(--brand-dc)";
|
|
21
|
+
const BRAND_DC_ALT = "var(--brand-dc-alt)";
|
|
22
|
+
const BRAND_ANIME_YELLOW = "var(--brand-anime-yellow)";
|
|
23
|
+
const BRAND_ANIME_YELLOW_TEXT = "var(--brand-anime-yellow-text)";
|
|
24
|
+
const BRAND_NARUTO = "var(--brand-naruto)";
|
|
25
|
+
const BRAND_HOTSPOT_OVERLAY = "var(--brand-hotspot-overlay)";
|
|
18
26
|
const DEFAULT_HOTSPOTS = [
|
|
19
27
|
{
|
|
20
28
|
id: "spiderman",
|
|
@@ -24,7 +32,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
24
32
|
href: "/franchise/marvel",
|
|
25
33
|
xPct: 8,
|
|
26
34
|
yPct: 22,
|
|
27
|
-
accent:
|
|
35
|
+
accent: BRAND_MARVEL,
|
|
28
36
|
badge: "MARVEL",
|
|
29
37
|
buyText: "Get Spider-Man Figures",
|
|
30
38
|
},
|
|
@@ -36,7 +44,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
36
44
|
href: "/franchise/marvel",
|
|
37
45
|
xPct: 18,
|
|
38
46
|
yPct: 58,
|
|
39
|
-
accent:
|
|
47
|
+
accent: BRAND_MARVEL,
|
|
40
48
|
badge: "MARVEL",
|
|
41
49
|
buyText: "Get Iron Man Figures",
|
|
42
50
|
},
|
|
@@ -48,7 +56,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
48
56
|
href: "/franchise/dc-comics",
|
|
49
57
|
xPct: 28,
|
|
50
58
|
yPct: 18,
|
|
51
|
-
accent:
|
|
59
|
+
accent: BRAND_DC,
|
|
52
60
|
badge: "DC",
|
|
53
61
|
buyText: "Get Robin Figures",
|
|
54
62
|
},
|
|
@@ -60,7 +68,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
60
68
|
href: "/franchise/dc-comics",
|
|
61
69
|
xPct: 36,
|
|
62
70
|
yPct: 42,
|
|
63
|
-
accent:
|
|
71
|
+
accent: BRAND_DC,
|
|
64
72
|
badge: "DC",
|
|
65
73
|
buyText: "Get Batman Figures",
|
|
66
74
|
},
|
|
@@ -72,7 +80,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
72
80
|
href: "/franchise/marvel",
|
|
73
81
|
xPct: 12,
|
|
74
82
|
yPct: 76,
|
|
75
|
-
accent:
|
|
83
|
+
accent: BRAND_DC_ALT,
|
|
76
84
|
badge: "MARVEL",
|
|
77
85
|
buyText: "Get Cap Figures",
|
|
78
86
|
},
|
|
@@ -84,7 +92,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
84
92
|
href: "/franchise/dc-comics",
|
|
85
93
|
xPct: 44,
|
|
86
94
|
yPct: 68,
|
|
87
|
-
accent:
|
|
95
|
+
accent: BRAND_DC_ALT,
|
|
88
96
|
badge: "DC",
|
|
89
97
|
buyText: "Get Superman Figures",
|
|
90
98
|
},
|
|
@@ -96,7 +104,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
96
104
|
href: "/franchise/dragon-ball",
|
|
97
105
|
xPct: 51,
|
|
98
106
|
yPct: 36,
|
|
99
|
-
accent:
|
|
107
|
+
accent: BRAND_ANIME_YELLOW,
|
|
100
108
|
badge: "ANIME",
|
|
101
109
|
buyText: "Get Goku Figures",
|
|
102
110
|
},
|
|
@@ -108,7 +116,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
108
116
|
href: "/franchise/naruto",
|
|
109
117
|
xPct: 57,
|
|
110
118
|
yPct: 78,
|
|
111
|
-
accent:
|
|
119
|
+
accent: BRAND_NARUTO,
|
|
112
120
|
badge: "ANIME",
|
|
113
121
|
buyText: "Get Naruto Figures",
|
|
114
122
|
},
|
|
@@ -120,7 +128,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
120
128
|
href: "/franchise/bleach",
|
|
121
129
|
xPct: 70,
|
|
122
130
|
yPct: 20,
|
|
123
|
-
accent:
|
|
131
|
+
accent: BRAND_DC,
|
|
124
132
|
badge: "ANIME",
|
|
125
133
|
buyText: "Get Ichigo Figures",
|
|
126
134
|
},
|
|
@@ -132,7 +140,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
132
140
|
href: "/franchise/one-piece",
|
|
133
141
|
xPct: 80,
|
|
134
142
|
yPct: 50,
|
|
135
|
-
accent:
|
|
143
|
+
accent: BRAND_ANIME_YELLOW,
|
|
136
144
|
badge: "ANIME",
|
|
137
145
|
buyText: "Get Luffy Figures",
|
|
138
146
|
},
|
|
@@ -144,7 +152,7 @@ const DEFAULT_HOTSPOTS = [
|
|
|
144
152
|
href: "/franchise/one-punch-man",
|
|
145
153
|
xPct: 91,
|
|
146
154
|
yPct: 50,
|
|
147
|
-
accent:
|
|
155
|
+
accent: BRAND_ANIME_YELLOW,
|
|
148
156
|
badge: "ANIME",
|
|
149
157
|
buyText: "Get Saitama Figures",
|
|
150
158
|
},
|
|
@@ -158,40 +166,25 @@ export function CharacterHotspot({ config, defaultHotspots = DEFAULT_HOTSPOTS, u
|
|
|
158
166
|
return (_jsx(CharacterHotspotInner, { panoramicImage: panoramicImage, panoramicAlt: panoramicAlt, hotspots: hotspots, universeLinks: universeLinks ?? DEFAULT_UNIVERSE_LINKS, shopAllHref: shopAllHref, heading: heading, subheading: subheading }));
|
|
159
167
|
}
|
|
160
168
|
const DEFAULT_UNIVERSE_LINKS = [
|
|
161
|
-
{ label: "MARVEL", href: "/franchise/marvel", color:
|
|
162
|
-
{
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
label: "DRAGON BALL",
|
|
170
|
-
href: "/franchise/dragon-ball",
|
|
171
|
-
color: "#FFE500",
|
|
172
|
-
icon: "✦",
|
|
173
|
-
},
|
|
174
|
-
{ label: "NARUTO", href: "/franchise/naruto", color: "#FF6B00", icon: "🍃" },
|
|
175
|
-
{
|
|
176
|
-
label: "ONE PIECE",
|
|
177
|
-
href: "/franchise/one-piece",
|
|
178
|
-
color: "#FFE500",
|
|
179
|
-
icon: "⚓",
|
|
180
|
-
},
|
|
181
|
-
{ label: "BLEACH", href: "/franchise/bleach", color: "#4A90D9", icon: "⚔" },
|
|
169
|
+
{ label: "MARVEL", href: "/franchise/marvel", color: BRAND_MARVEL, icon: "⚡" },
|
|
170
|
+
{ label: "DC COMICS", href: "/franchise/dc-comics", color: BRAND_DC, icon: "🦇" },
|
|
171
|
+
{ label: "DRAGON BALL", href: "/franchise/dragon-ball", color: BRAND_ANIME_YELLOW, icon: "✦" },
|
|
172
|
+
{ label: "NARUTO", href: "/franchise/naruto", color: BRAND_NARUTO, icon: "🍃" },
|
|
173
|
+
{ label: "ONE PIECE", href: "/franchise/one-piece", color: BRAND_ANIME_YELLOW, icon: "⚓" },
|
|
174
|
+
{ label: "BLEACH", href: "/franchise/bleach", color: BRAND_DC, icon: "⚔" },
|
|
182
175
|
];
|
|
183
176
|
function HotspotHeaderOverlay({ heading, subheading, shopAllHref, }) {
|
|
184
177
|
return (_jsx(Div, { className: "absolute top-0 left-0 right-0 z-10 pointer-events-none", style: {
|
|
185
178
|
background: "linear-gradient(to bottom, rgba(10,10,18,0.88) 0%, rgba(10,10,18,0.40) 50%, transparent 100%)",
|
|
186
|
-
}, children: _jsxs(Row, { wrap: true, align: "start", justify: "between", gap: "sm", className: "pointer-events-auto mx-auto max-w-7xl
|
|
179
|
+
}, children: _jsxs(Row, { wrap: true, align: "start", justify: "between", gap: "sm", className: "pointer-events-auto mx-auto max-w-7xl gap-y-3", paddingX: "x-md", paddingY: "t-md-b-lg", children: [_jsxs(Div, { children: [_jsx(Text, { className: "mb-1 font-black uppercase tracking-[0.2em]", size: "xs", style: { color: "var(--color-red)" }, children: "Explore the Universe" }), _jsx(Heading, { level: 2, style: {
|
|
187
180
|
fontFamily: FONT_BANGERS,
|
|
188
181
|
fontSize: "clamp(1.8rem, 4.5vw, 3rem)",
|
|
189
182
|
letterSpacing: "0.07em",
|
|
190
|
-
color: "
|
|
183
|
+
color: "white",
|
|
191
184
|
lineHeight: 1,
|
|
192
185
|
}, children: heading }), subheading ? (_jsx(Text, { className: "mt-2 max-w-md", size: "sm", weight: "medium", style: { color: "var(--dark-section-muted)" }, children: subheading })) : (_jsxs(Text, { className: "mt-2 max-w-md", size: "sm", weight: "medium", style: { color: "var(--dark-section-muted)" }, children: ["& beyond \u2014 tap the", " ", _jsx(Span, { layout: "inline-flex-center", rounded: "full", weight: "light", style: {
|
|
193
186
|
background: "rgba(255,255,255,0.92)",
|
|
194
|
-
color: "
|
|
187
|
+
color: "var(--appkit-color-text)",
|
|
195
188
|
width: 18,
|
|
196
189
|
height: 18,
|
|
197
190
|
border: "1.5px solid rgba(0,0,0,0.18)",
|
|
@@ -203,7 +196,7 @@ function HotspotHeaderOverlay({ heading, subheading, shopAllHref, }) {
|
|
|
203
196
|
fontFamily: FONT_BANGERS,
|
|
204
197
|
letterSpacing: "0.1em",
|
|
205
198
|
background: "var(--color-red)",
|
|
206
|
-
color: "
|
|
199
|
+
color: "white",
|
|
207
200
|
border: "3px solid var(--border-ink)",
|
|
208
201
|
boxShadow: "4px 4px 0px var(--border-ink)",
|
|
209
202
|
}, children: "SHOP ALL \u2192" })] }) }));
|
|
@@ -214,7 +207,7 @@ function HotspotImageLayer({ panoramicImage, panoramicAlt, }) {
|
|
|
214
207
|
} }), _jsx(Div, { className: "absolute inset-0", style: {
|
|
215
208
|
background: "linear-gradient(to bottom, rgba(10,10,18,0.25) 0%, transparent 40%, rgba(10,10,18,0.65) 100%)",
|
|
216
209
|
} }), _jsx(Div, { className: "absolute bottom-0 left-0 right-0 h-16 pointer-events-none", style: {
|
|
217
|
-
background:
|
|
210
|
+
background: `linear-gradient(to bottom, transparent, ${BRAND_HOTSPOT_OVERLAY})`,
|
|
218
211
|
} })] }));
|
|
219
212
|
}
|
|
220
213
|
function HotspotPin({ hotspot, isActive, isMobile, toggle, onClose, }) {
|
|
@@ -239,7 +232,7 @@ function HotspotPin({ hotspot, isActive, isMobile, toggle, onClose, }) {
|
|
|
239
232
|
padding: 0,
|
|
240
233
|
transition: "transform 0.2s ease, opacity 0.2s ease",
|
|
241
234
|
transform: isActive ? "scale(1.2) rotate(45deg)" : "scale(1)",
|
|
242
|
-
color: isMobile ? "
|
|
235
|
+
color: isMobile ? "white" : isActive ? "white" : "var(--appkit-color-text)",
|
|
243
236
|
fontSize: isMobile ? 18 : 22,
|
|
244
237
|
fontWeight: 200,
|
|
245
238
|
lineHeight: 1,
|
|
@@ -256,11 +249,11 @@ function HotspotPin({ hotspot, isActive, isMobile, toggle, onClose, }) {
|
|
|
256
249
|
overflow: "hidden",
|
|
257
250
|
zIndex: 40,
|
|
258
251
|
animation: "fadeInUp 0.2s ease both",
|
|
259
|
-
}, children: [_jsx(Div, { style: { height: 4, background: hotspot.accent } }), _jsxs(Div, { paddingX: "x-5", padding: "y-md", children: [_jsx(Text, { className: "text-[10px] uppercase tracking-[0.18em] mb-1", weight: "bold", style: { color: hotspot.accent ===
|
|
252
|
+
}, children: [_jsx(Div, { style: { height: 4, background: hotspot.accent } }), _jsxs(Div, { paddingX: "x-5", padding: "y-md", children: [_jsx(Text, { className: "text-[10px] uppercase tracking-[0.18em] mb-1", weight: "bold", style: { color: hotspot.accent === BRAND_ANIME_YELLOW ? BRAND_ANIME_YELLOW_TEXT : hotspot.accent }, children: hotspot.universe }), _jsx(Heading, { level: 3, className: "font-black leading-tight mb-3", style: { fontFamily: FONT_BANGERS, fontSize: "1.45rem", letterSpacing: "0.06em", color: "var(--appkit-color-text)" }, children: hotspot.name }), _jsx(Text, { className: "leading-relaxed mb-4", size: "xs", style: { color: "var(--appkit-color-slate-700)" }, children: hotspot.description }), _jsxs(Link, { href: hotspot.href, onClick: onClose, className: "flex items-center justify-between px-4 py-2.5 text-sm font-black uppercase transition-opacity hover:opacity-85", style: {
|
|
260
253
|
fontFamily: FONT_BANGERS,
|
|
261
254
|
letterSpacing: "0.1em",
|
|
262
255
|
background: hotspot.accent,
|
|
263
|
-
color: hotspot.accent ===
|
|
256
|
+
color: hotspot.accent === BRAND_ANIME_YELLOW ? "black" : "white",
|
|
264
257
|
borderRadius: 2,
|
|
265
258
|
}, children: [hotspot.buyText, _jsx(Span, { "aria-hidden": "true", children: "\u2192" })] })] })] }))] }));
|
|
266
259
|
}
|
|
@@ -272,14 +265,14 @@ function MobileHotspotSheet({ active, onClose, }) {
|
|
|
272
265
|
borderTopRightRadius: 16,
|
|
273
266
|
overflow: "hidden",
|
|
274
267
|
animation: "fadeInUp 0.22s ease both",
|
|
275
|
-
}, children: [_jsx(Row, { paddingY: "b-2xs", padding: "t-sm", justify: "center", children: _jsx(Div, { style: { width: 40, height: 4, borderRadius: 2, background: "
|
|
268
|
+
}, children: [_jsx(Row, { paddingY: "b-2xs", padding: "t-sm", justify: "center", children: _jsx(Div, { style: { width: 40, height: 4, borderRadius: 2, background: "var(--appkit-color-zinc-300)" } }) }), _jsx(Div, { style: { height: 4, background: active.accent } }), _jsxs(Div, { padding: "t-md", style: { paddingInline: "1.25rem", paddingBottom: "2.5rem" }, children: [_jsx(Text, { className: "text-[10px] uppercase tracking-[0.18em] mb-1", weight: "bold", style: { color: active.accent === BRAND_ANIME_YELLOW ? BRAND_ANIME_YELLOW_TEXT : active.accent }, children: active.universe }), _jsx(Heading, { level: 3, className: "font-black leading-tight mb-2", style: { fontFamily: FONT_BANGERS, fontSize: "clamp(1.5rem, 6vw, 2rem)", letterSpacing: "0.06em", color: "var(--appkit-color-text)" }, children: active.name }), _jsx(Text, { className: "leading-relaxed mb-5", size: "sm", style: { color: "var(--appkit-color-slate-700)" }, children: active.description }), _jsxs(Row, { gap: "3", children: [_jsxs(Link, { href: active.href, onClick: onClose, className: "flex-1 flex items-center justify-between px-4 py-3 font-black uppercase", style: {
|
|
276
269
|
fontFamily: FONT_BANGERS,
|
|
277
270
|
letterSpacing: "0.1em",
|
|
278
271
|
fontSize: "0.9rem",
|
|
279
272
|
background: active.accent,
|
|
280
|
-
color: active.accent ===
|
|
273
|
+
color: active.accent === BRAND_ANIME_YELLOW ? "black" : "white",
|
|
281
274
|
borderRadius: 4,
|
|
282
|
-
}, children: [active.buyText, _jsx(Span, { "aria-hidden": "true", children: "\u2192" })] }), _jsx(Button, { type: "button", variant: "outline", onClick: onClose, paddingX: "lg", textSize: "sm", rounded: "default", className: "py-
|
|
275
|
+
}, children: [active.buyText, _jsx(Span, { "aria-hidden": "true", children: "\u2192" })] }), _jsx(Button, { type: "button", variant: "outline", onClick: onClose, paddingX: "lg", textSize: "sm", rounded: "default", className: "py-[0.75rem] font-[700]", style: { background: "var(--appkit-color-slate-100)", color: "var(--appkit-color-slate-600)" }, children: "Close" })] })] })] }) }));
|
|
283
276
|
}
|
|
284
277
|
function UniverseBrowseRow({ universeLinks, }) {
|
|
285
278
|
return (_jsx(Div, { gap: "3", className: `mx-auto max-w-7xl ${GRID_COLS_6_LG}`, paddingY: "y-lg", paddingX: "x-md", style: { borderTop: "1px solid rgba(255,255,255,0.08)" }, children: universeLinks.map(({ label, href, color, icon }) => (_jsxs(Link, { href: href, className: "group flex items-center gap-2.5 px-3 py-2.5 rounded-sm transition-all hover:-translate-y-0.5", style: {
|
|
@@ -292,7 +285,7 @@ function UniverseBrowseRow({ universeLinks, }) {
|
|
|
292
285
|
}, onMouseLeave: (e) => {
|
|
293
286
|
e.currentTarget.style.borderColor = "rgba(255,255,255,0.08)";
|
|
294
287
|
e.currentTarget.style.background = "rgba(255,255,255,0.04)";
|
|
295
|
-
}, children: [_jsx(Span, { size: "base", "aria-hidden": "true", className: "select-none", children: icon }), _jsx(Span, { size: "xs", className: "font-black uppercase tracking-wide", style: { fontFamily: FONT_BANGERS, letterSpacing: "0.1em", color: "
|
|
288
|
+
}, children: [_jsx(Span, { size: "base", "aria-hidden": "true", className: "select-none", children: icon }), _jsx(Span, { size: "xs", className: "font-black uppercase tracking-wide", style: { fontFamily: FONT_BANGERS, letterSpacing: "0.1em", color: "var(--appkit-color-slate-200)" }, children: label }), _jsx(Span, { size: "xs", className: "ml-auto", style: { color: "var(--appkit-color-slate-600)", transition: "color 0.15s" }, children: "\u2192" })] }, label))) }));
|
|
296
289
|
}
|
|
297
290
|
function CharacterHotspotInner({ panoramicImage, panoramicAlt, hotspots, universeLinks, shopAllHref, heading, subheading, }) {
|
|
298
291
|
const [activeId, setActiveId] = useState(null);
|
|
@@ -324,13 +317,13 @@ function CharacterHotspotInner({ panoramicImage, panoramicAlt, hotspots, univers
|
|
|
324
317
|
borderTop: "3px solid var(--dark-section-bg)",
|
|
325
318
|
borderBottom: "3px solid var(--dark-section-bg)",
|
|
326
319
|
overflow: "hidden",
|
|
327
|
-
}, children: [_jsxs(Div, { ref: containerRef, className: "relative w-full", style: { aspectRatio: "16/9", minHeight: "420px" }, children: [_jsx(HotspotHeaderOverlay, { heading: heading, subheading: subheading, shopAllHref: shopAllHref }), _jsx(HotspotImageLayer, { panoramicImage: panoramicImage, panoramicAlt: panoramicAlt }), _jsx(Div, { className: "hidden sm:flex absolute left-0 right-0 justify-around items-start pointer-events-none", style: { top: "clamp(120px, 18vh, 165px)", zIndex: 5 }, children: [
|
|
328
|
-
{ label: "MARVEL", color:
|
|
329
|
-
{ label: "DC COMICS", color:
|
|
330
|
-
{ label: "ANIME", color:
|
|
320
|
+
}, children: [_jsxs(Div, { ref: containerRef, className: "relative w-full", style: { aspectRatio: "16/9", minHeight: "420px" }, children: [_jsx(HotspotHeaderOverlay, { heading: heading, subheading: subheading, shopAllHref: shopAllHref }), _jsx(HotspotImageLayer, { panoramicImage: panoramicImage, panoramicAlt: panoramicAlt }), _jsx(Div, { className: "hidden sm:flex absolute left-0 right-0 justify-[space-around] items-[flex-start] pointer-events-none", style: { top: "clamp(120px, 18vh, 165px)", zIndex: 5 }, children: [
|
|
321
|
+
{ label: "MARVEL", color: BRAND_MARVEL },
|
|
322
|
+
{ label: "DC COMICS", color: BRAND_DC },
|
|
323
|
+
{ label: "ANIME", color: BRAND_ANIME_YELLOW },
|
|
331
324
|
].map(({ label, color }) => (_jsxs(Stack, { align: "center", children: [_jsx(Span, { className: "text-[10px] font-black uppercase tracking-[0.18em]", smSize: "xs", rounded: "sm", padding: "pill-md", style: {
|
|
332
325
|
background: color,
|
|
333
|
-
color: color ===
|
|
326
|
+
color: color === BRAND_ANIME_YELLOW ? "black" : "white",
|
|
334
327
|
boxShadow: "2px 2px 0px rgba(0,0,0,0.6)",
|
|
335
328
|
fontFamily: FONT_BANGERS,
|
|
336
329
|
letterSpacing: "0.16em",
|