@mohasinac/appkit 4.26.0 → 4.28.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/lottery/LotteryAdminEditView.d.ts +16 -16
- package/dist/_internal/client/features/lottery/LotteryAdminEditView.js +29 -6
- package/dist/_internal/client/features/lottery/LotteryListView.js +13 -1
- package/dist/_internal/server/features/bundles/data.d.ts +19 -0
- package/dist/_internal/server/features/bundles/data.js +32 -0
- package/dist/_internal/server/features/bundles/index.d.ts +1 -1
- package/dist/_internal/server/features/bundles/index.js +1 -1
- package/dist/_internal/server/features/checkout/actions.js +6 -4
- package/dist/_internal/server/features/classified/metadata.js +3 -1
- package/dist/_internal/server/features/digital-code/metadata.js +3 -1
- package/dist/_internal/server/features/live/metadata.js +3 -1
- package/dist/_internal/server/features/refunds/actions.js +3 -2
- package/dist/_internal/server/features/reviews/actions.js +3 -2
- package/dist/_internal/server/features/seo/sitemap.js +189 -40
- package/dist/_internal/server/jobs/core/listingProcessor.d.ts +0 -1
- package/dist/_internal/server/jobs/core/listingProcessor.js +19 -1
- package/dist/_internal/shared/actions/action-registry.js +14 -0
- package/dist/_internal/shared/checkout/order-math.d.ts +25 -3
- package/dist/_internal/shared/features/checkout/config.d.ts +3 -3
- package/dist/_internal/shared/features/checkout/config.js +6 -3
- package/dist/client.d.ts +32 -2
- package/dist/client.js +37 -2
- package/dist/constants/api-endpoints.d.ts +21 -3
- package/dist/constants/api-endpoints.js +14 -1
- package/dist/constants/field-names.d.ts +2 -2
- package/dist/constants/field-names.js +2 -2
- package/dist/core/newsletter.repository.js +14 -1
- package/dist/features/about/components/FAQPageView.js +1 -1
- package/dist/features/about/components/FeesView.js +1 -1
- package/dist/features/account/components/AddressForm.d.ts +2 -0
- package/dist/features/account/components/AddressForm.js +5 -1
- package/dist/features/account/components/UserBidsView.js +1 -1
- package/dist/features/account/components/UserSidebar.js +1 -1
- package/dist/features/account/components/UserSupportView.js +24 -2
- package/dist/features/account/hooks/useAddresses.d.ts +29 -1
- package/dist/features/account/hooks/useAddresses.js +4 -1
- package/dist/features/account/hooks/useProfile.d.ts +1 -1
- package/dist/features/account/hooks/useProfile.js +1 -1
- package/dist/features/addresses/repository/addresses.repository.d.ts +13 -0
- package/dist/features/addresses/repository/addresses.repository.js +19 -0
- package/dist/features/admin/actions/chat-actions.js +5 -1
- package/dist/features/admin/components/AdminAdsView.js +1 -1
- package/dist/features/admin/components/AdminBidsView.js +6 -1
- package/dist/features/admin/components/AdminCarouselGroupEditorView.d.ts +9 -1
- package/dist/features/admin/components/AdminCarouselGroupEditorView.js +42 -10
- package/dist/features/admin/components/AdminCarouselView.js +1 -1
- package/dist/features/admin/components/AdminFeatureEditorView.js +1 -1
- package/dist/features/admin/components/AdminGroupedListingsView.js +14 -2
- package/dist/features/admin/components/AdminSidebar.js +1 -1
- package/dist/features/admin/components/AdminViewCards.js +2 -2
- package/dist/features/admin/components/DataTable.js +2 -2
- package/dist/features/admin/schemas/firestore.js +9 -3
- package/dist/features/auctions/actions/bid-actions.js +45 -4
- package/dist/features/auctions/components/AuctionBottomActions.d.ts +21 -6
- package/dist/features/auctions/components/AuctionBottomActions.js +42 -11
- package/dist/features/auctions/components/AuctionDetailPageView.d.ts +8 -3
- package/dist/features/auctions/components/AuctionDetailPageView.js +2 -2
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +4 -5
- package/dist/features/auctions/components/PlaceBidFormClient.d.ts +27 -2
- package/dist/features/auctions/components/PlaceBidFormClient.js +42 -20
- package/dist/features/auth/components/SocialAuthButtons.js +1 -1
- package/dist/features/auth/hooks/useAuth.d.ts +23 -1
- package/dist/features/auth/hooks/useAuth.js +27 -1
- package/dist/features/auth/permissions/constants.d.ts +1 -1
- package/dist/features/auth/permissions/constants.js +3 -0
- package/dist/features/auth/repository/session.repository.d.ts +16 -1
- package/dist/features/auth/repository/session.repository.js +23 -0
- package/dist/features/auth/repository/user.repository.js +13 -2
- package/dist/features/blog/components/BlogListView.js +2 -2
- package/dist/features/cart/components/CartPriceBreakdown.d.ts +11 -1
- package/dist/features/cart/components/CartPriceBreakdown.js +3 -3
- package/dist/features/cart/components/StoreAddonsPicker.d.ts +9 -0
- package/dist/features/cart/components/StoreAddonsPicker.js +15 -5
- package/dist/features/cart/components/index.d.ts +1 -1
- package/dist/features/cart/components/index.js +1 -1
- package/dist/features/cart/hooks/useGuestCartMerge.d.ts +8 -1
- package/dist/features/cart/hooks/useGuestCartMerge.js +2 -1
- package/dist/features/cart/utils/line-total.d.ts +25 -0
- package/dist/features/cart/utils/line-total.js +26 -0
- package/dist/features/catalogue/repository/catalogue.repository.d.ts +12 -0
- package/dist/features/catalogue/repository/catalogue.repository.js +15 -0
- package/dist/features/categories/components/CategoryTree.js +2 -2
- package/dist/features/contact/components/ContactForm.js +1 -1
- package/dist/features/copilot/hooks/useCopilotFeedback.d.ts +1 -1
- package/dist/features/copilot/hooks/useCopilotFeedback.js +1 -1
- package/dist/features/events/components/AdminEventEditorView.js +16 -9
- package/dist/features/events/components/AdminEventEntriesView.js +7 -13
- package/dist/features/events/components/EventRafflesSection.js +14 -2
- package/dist/features/events/components/EventStatusBadge.js +1 -1
- package/dist/features/events/components/event-entry-detail-fields.d.ts +24 -0
- package/dist/features/events/components/event-entry-detail-fields.js +13 -0
- package/dist/features/faq/components/ContactCTA.js +1 -1
- package/dist/features/faq/components/FAQHelpfulButtons.js +2 -2
- package/dist/features/faq/repository/faqs.repository.d.ts +16 -1
- package/dist/features/faq/repository/faqs.repository.js +64 -54
- package/dist/features/faq/schemas/firestore.d.ts +3 -2
- package/dist/features/faq/schemas/firestore.js +2 -2
- package/dist/features/faq/schemas/index.d.ts +3 -3
- package/dist/features/faq/schemas/index.js +1 -1
- package/dist/features/filters/FilterFacetSection.js +2 -2
- package/dist/features/forms/Toggle.js +1 -1
- package/dist/features/grouped/components/GroupedListingEditorView.d.ts +18 -0
- package/dist/features/grouped/components/GroupedListingEditorView.js +192 -0
- package/dist/features/homepage/components/AdvertisementBanner.js +2 -2
- package/dist/features/homepage/components/BrandsSection.js +1 -1
- package/dist/features/homepage/components/CTABannerSection.js +1 -1
- package/dist/features/homepage/components/HomepageCustomerReviewsSection.js +1 -1
- package/dist/features/homepage/components/HomepageSectionBoundary.d.ts +39 -0
- package/dist/features/homepage/components/HomepageSectionBoundary.js +49 -0
- package/dist/features/homepage/components/ShopByCategorySection.js +1 -1
- package/dist/features/homepage/components/WelcomeSection.js +1 -1
- package/dist/features/homepage/lib/section-renderer.js +2 -1
- package/dist/features/layout/AppLayoutShell.js +5 -5
- package/dist/features/layout/BottomActions.js +5 -5
- package/dist/features/layout/BottomSheet.js +1 -1
- package/dist/features/layout/MainNavbar.js +1 -1
- package/dist/features/layout/NavbarLayout.js +1 -1
- package/dist/features/layout/TitleBarLayout.js +3 -3
- package/dist/features/layout/hooks/useFormBottomActions.d.ts +11 -1
- package/dist/features/layout/hooks/useFormBottomActions.js +16 -2
- package/dist/features/lottery/schemas/config-write.d.ts +141 -0
- package/dist/features/lottery/schemas/config-write.js +139 -0
- package/dist/features/media/MediaPickerModal.js +3 -1
- package/dist/features/media/MediaVideo.js +4 -2
- package/dist/features/media/components/MediaSlider.js +1 -1
- package/dist/features/orders/components/OrdersList.js +2 -2
- package/dist/features/payments/repository/payout.repository.d.ts +11 -1
- package/dist/features/payments/repository/payout.repository.js +14 -6
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +3 -2
- package/dist/features/pre-orders/components/PreOrderBadge.js +1 -1
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +1 -1
- package/dist/features/products/columns/productTableColumns.js +3 -3
- package/dist/features/products/components/CompareOverlay.js +1 -1
- package/dist/features/products/components/PrizeDrawDetailPageView.js +1 -1
- package/dist/features/products/components/PrizeDrawEntryActions.js +2 -2
- package/dist/features/products/components/PrizeDrawsSection.js +5 -1
- package/dist/features/products/components/ProductDetailActions.js +11 -7
- package/dist/features/products/components/ProductDetailPageView.js +3 -3
- package/dist/features/products/components/ProductFeatureBadges.js +2 -2
- package/dist/features/products/components/ProductFeaturesSelector.js +1 -1
- package/dist/features/products/components/ProductFilters.js +15 -8
- package/dist/features/products/components/ProductGrid.js +8 -17
- package/dist/features/products/components/ProductTabs.js +7 -4
- package/dist/features/products/components/ProductTabsShell.js +2 -7
- package/dist/features/products/constants/action-defs.d.ts +21 -4
- package/dist/features/products/constants/action-defs.js +7 -3
- package/dist/features/products/hooks/useRelatedProducts.js +2 -1
- package/dist/features/products/repository/products.repository.d.ts +1 -1
- package/dist/features/products/repository/products.repository.js +27 -13
- package/dist/features/products/schemas/firestore.d.ts +3 -2
- package/dist/features/products/schemas/firestore.js +1 -1
- package/dist/features/reviews/actions/review-actions.d.ts +8 -1
- package/dist/features/reviews/actions/review-actions.js +14 -3
- package/dist/features/reviews/components/ReviewDetailShell.js +10 -4
- package/dist/features/reviews/components/ReviewModal.js +1 -1
- package/dist/features/reviews/repository/reviews.repository.d.ts +25 -1
- package/dist/features/reviews/repository/reviews.repository.js +53 -13
- package/dist/features/reviews/schemas/firestore.d.ts +6 -0
- package/dist/features/scams/components/ScamRegistryView.js +2 -2
- package/dist/features/search/components/Search.js +3 -3
- package/dist/features/search/components/SearchResultsSection.js +1 -1
- package/dist/features/seller/components/SellerAddressesView.js +3 -1
- package/dist/features/seller/components/SellerBidsView.js +6 -1
- package/dist/features/seller/components/SellerSidebar.js +1 -1
- package/dist/features/shell/SectionForm.d.ts +21 -1
- package/dist/features/shell/SectionForm.js +15 -3
- package/dist/features/shell/build-sections.js +10 -1
- package/dist/features/shell/field-ui-meta.d.ts +21 -0
- package/dist/features/shipments/components/AdminShipmentLotItemsView.js +23 -6
- package/dist/features/site-settings/components/ActionPermissionsManager.js +1 -1
- package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +21 -4
- package/dist/features/store-extensions/repository/store-extensions.repositories.js +24 -4
- package/dist/features/store-extensions/schemas/shipping-config-form.js +13 -0
- package/dist/features/store-extensions/schemas/store-category-form.js +1 -1
- package/dist/features/stores/actions/store-query-actions.js +25 -1
- package/dist/features/stores/components/InteractiveStoreCard.js +1 -1
- package/dist/features/stores/components/StoreHeader.js +1 -1
- package/dist/features/stores/components/StoreNavTabs.js +20 -8
- package/dist/features/support/repository/support.repository.d.ts +12 -0
- package/dist/features/support/repository/support.repository.js +15 -0
- package/dist/features/support/schemas/ticket-create-form.d.ts +33 -0
- package/dist/features/support/schemas/ticket-create-form.js +82 -0
- package/dist/features/tester/seed-data/products-tester-seed-data.js +108 -2
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +235 -13
- package/dist/features/wishlist/components/WishlistHeartButton.d.ts +55 -0
- package/dist/features/wishlist/components/WishlistHeartButton.js +52 -0
- package/dist/features/wishlist/components/index.d.ts +2 -1
- package/dist/features/wishlist/components/index.js +1 -1
- package/dist/index.d.ts +10 -3
- package/dist/index.js +19 -4
- package/dist/monitoring/error-tracking.js +39 -5
- package/dist/monitoring/server-logger.js +70 -32
- package/dist/next/components/ErrorView.js +1 -1
- package/dist/next/routing/route-map.d.ts +39 -7
- package/dist/next/routing/route-map.js +34 -4
- package/dist/providers/db-firebase/base.repository.d.ts +30 -0
- package/dist/providers/db-firebase/base.repository.js +56 -9
- package/dist/react/ErrorBoundary.js +9 -1
- package/dist/react/contexts/SessionContext.js +6 -2
- package/dist/react/hooks/useAuthGate.d.ts +22 -0
- package/dist/react/hooks/useAuthGate.js +86 -7
- package/dist/schemas/registry.d.ts +3 -3
- package/dist/security/index.d.ts +1 -1
- package/dist/security/index.js +1 -1
- package/dist/security/pii-encrypt.d.ts +13 -5
- package/dist/security/pii-encrypt.js +132 -6
- package/dist/security/pii-schemas.d.ts +20 -4
- package/dist/security/pii-schemas.js +23 -5
- package/dist/seed/_helpers/product-search-txt.d.ts +18 -0
- package/dist/seed/_helpers/product-search-txt.js +33 -0
- package/dist/seed/faq-seed-data.d.ts +16 -0
- package/dist/seed/faq-seed-data.js +22 -1
- package/dist/seed/products-art-seed-data.js +49 -7
- package/dist/seed/products-auctions-seed-data.js +12 -4
- package/dist/seed/products-classifieds-seed-data.d.ts +5 -0
- package/dist/seed/products-classifieds-seed-data.js +65 -9
- package/dist/seed/products-digital-codes-seed-data.d.ts +5 -0
- package/dist/seed/products-digital-codes-seed-data.js +65 -9
- package/dist/seed/products-live-items-seed-data.d.ts +5 -0
- package/dist/seed/products-live-items-seed-data.js +33 -5
- package/dist/seed/products-preorders-seed-data.d.ts +1 -1
- package/dist/seed/products-preorders-seed-data.js +6 -2
- package/dist/seed/products-prize-draws-seed-data.d.ts +5 -0
- package/dist/seed/products-prize-draws-seed-data.js +57 -8
- package/dist/seed/products-standard-seed-data.js +6 -2
- package/dist/seed/products-stickers-seed-data.js +49 -7
- package/dist/seed/site-settings-seed-data.js +5 -3
- package/dist/seo/json-ld.d.ts +44 -2
- package/dist/seo/json-ld.js +57 -11
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/styles.css +368 -90
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.js +1 -1
- package/dist/tokens/themes/default-dark.js +6 -0
- package/dist/tokens/themes/default-light.js +5 -0
- package/dist/tokens/tokens.css +84 -0
- package/dist/ui/DataTable.js +1 -1
- package/dist/ui/DataTable.style.css +3 -3
- package/dist/ui/components/BulkActionBar.style.css +1 -3
- package/dist/ui/components/Button.js +15 -6
- package/dist/ui/components/Dropdown.style.css +1 -4
- package/dist/ui/components/FilterChipGroup.js +1 -1
- package/dist/ui/components/FilterDrawer.style.css +1 -1
- package/dist/ui/components/Icon.d.ts +53 -0
- package/dist/ui/components/Icon.js +41 -0
- package/dist/ui/components/IconButton.d.ts +13 -0
- package/dist/ui/components/IconButton.js +13 -0
- package/dist/ui/components/IconButton.style.css +18 -10
- package/dist/ui/components/ListingLayout.style.css +2 -10
- package/dist/ui/components/ListingToolbar.js +6 -6
- package/dist/ui/components/Modal.js +1 -1
- package/dist/ui/components/PaginatedSelect.style.css +3 -3
- package/dist/ui/components/Pagination.style.css +1 -6
- package/dist/ui/components/RichTextEditor.js +1 -1
- package/dist/ui/components/RowActionMenu.style.css +1 -1
- package/dist/ui/components/SideDrawer.style.css +1 -1
- package/dist/ui/components/Slider.js +1 -1
- package/dist/ui/components/TabBarShell.d.ts +78 -0
- package/dist/ui/components/TabBarShell.js +95 -0
- package/dist/ui/components/Tabs.js +12 -8
- package/dist/ui/components/Tabs.style.css +249 -41
- package/dist/ui/components/ViewToggle.style.css +1 -5
- package/dist/ui/components/tabs-overflow.d.ts +17 -0
- package/dist/ui/components/tabs-overflow.js +142 -0
- package/dist/ui/icons/icon-registry.d.ts +38 -0
- package/dist/ui/icons/icon-registry.js +37 -0
- package/dist/ui/index.d.ts +6 -0
- package/dist/ui/index.js +3 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/media-url.d.ts +27 -4
- package/dist/utils/media-url.js +37 -6
- package/dist/utils/search-txt.d.ts +71 -0
- package/dist/utils/search-txt.js +118 -0
- package/package.json +1 -1
package/dist/tokens/index.d.ts
CHANGED
|
@@ -268,7 +268,7 @@ export declare const LAYOUT: {
|
|
|
268
268
|
readonly navbarBg: "bg-[color-mix(in_srgb,var(--appkit-color-bg)_90%,transparent)] backdrop-blur-md border-b border-[var(--appkit-color-border)]";
|
|
269
269
|
readonly sidebarBg: "bg-[var(--appkit-color-surface)] border-l border-[var(--appkit-color-border-subtle)]";
|
|
270
270
|
readonly bottomNavBg: "bg-[color-mix(in_srgb,var(--appkit-color-bg)_90%,transparent)] backdrop-blur-md border-t border-[var(--appkit-color-border)]";
|
|
271
|
-
readonly footerBg: "
|
|
271
|
+
readonly footerBg: " bg-[var(--appkit-color-surface)] border-t border-[var(--appkit-color-border-subtle)]";
|
|
272
272
|
readonly fullScreen: "min-h-screen";
|
|
273
273
|
readonly flexCenter: "flex items-center justify-center";
|
|
274
274
|
readonly centerText: "text-center";
|
package/dist/tokens/index.js
CHANGED
|
@@ -205,7 +205,7 @@ export const LAYOUT = {
|
|
|
205
205
|
navbarBg: "bg-[color-mix(in_srgb,var(--appkit-color-bg)_90%,transparent)] backdrop-blur-md border-b border-[var(--appkit-color-border)]",
|
|
206
206
|
sidebarBg: "bg-[var(--appkit-color-surface)] border-l border-[var(--appkit-color-border-subtle)]",
|
|
207
207
|
bottomNavBg: "bg-[color-mix(in_srgb,var(--appkit-color-bg)_90%,transparent)] backdrop-blur-md border-t border-[var(--appkit-color-border)]",
|
|
208
|
-
footerBg: "
|
|
208
|
+
footerBg: " bg-[var(--appkit-color-surface)] border-t border-[var(--appkit-color-border-subtle)]",
|
|
209
209
|
fullScreen: "min-h-screen",
|
|
210
210
|
flexCenter: "flex items-center justify-center",
|
|
211
211
|
centerText: "text-center",
|
|
@@ -43,6 +43,12 @@ export const DEFAULT_DARK_THEME = {
|
|
|
43
43
|
"appkit-color-surface": "#0f172a",
|
|
44
44
|
"appkit-color-surface-elevated": "rgba(15, 23, 42, 0.9)",
|
|
45
45
|
"appkit-color-surface-input": "rgba(30, 41, 59, 0.6)",
|
|
46
|
+
// Theme-inverting interactive fills. Must stay byte-identical to the
|
|
47
|
+
// [data-theme="default-dark"] block in tokens.css — audit-theme-drift
|
|
48
|
+
// compares them.
|
|
49
|
+
"appkit-color-surface-hover": "rgba(148, 163, 184, 0.12)",
|
|
50
|
+
"appkit-color-surface-raised": "rgba(30, 41, 59, 0.7)",
|
|
51
|
+
"appkit-color-primary-surface": "rgba(239, 68, 68, 0.16)",
|
|
46
52
|
"appkit-color-border": "#334155",
|
|
47
53
|
"appkit-color-border-subtle": "rgba(30, 41, 59, 0.6)",
|
|
48
54
|
"appkit-color-text": "#fafafa",
|
|
@@ -46,6 +46,11 @@ export const DEFAULT_LIGHT_THEME = {
|
|
|
46
46
|
"appkit-color-surface": "#ffffff",
|
|
47
47
|
"appkit-color-surface-elevated": "#ffffff",
|
|
48
48
|
"appkit-color-surface-input": "#ffffff",
|
|
49
|
+
// Theme-inverting interactive fills. Must stay byte-identical to the
|
|
50
|
+
// matching :root block in tokens.css — audit-theme-drift compares them.
|
|
51
|
+
"appkit-color-surface-hover": "#f4f4f5",
|
|
52
|
+
"appkit-color-surface-raised": "#fafafa",
|
|
53
|
+
"appkit-color-primary-surface": "#f0fdfa",
|
|
49
54
|
"appkit-color-border": "#e4e4e7",
|
|
50
55
|
"appkit-color-border-subtle": "#f4f4f5",
|
|
51
56
|
"appkit-color-text": "#18181b",
|
package/dist/tokens/tokens.css
CHANGED
|
@@ -262,6 +262,27 @@
|
|
|
262
262
|
--appkit-color-surface-elevated: #ffffff;
|
|
263
263
|
--appkit-color-surface-input: #ffffff;
|
|
264
264
|
|
|
265
|
+
/* --- Interactive surfaces ------------------------------------------------
|
|
266
|
+
* `-hover` is the neutral chrome hover fill; `-raised` is a resting panel one
|
|
267
|
+
* step off the page surface; `primary-surface` is the brand-tinted hover.
|
|
268
|
+
*
|
|
269
|
+
* All three INVERT with the theme, and that is the whole point. A hardcoded
|
|
270
|
+
* a hardcoded `zinc-50` hover fill is near-white in every theme, and sits under
|
|
271
|
+
* `dark:hover:text-*` white ink and is unreadable; `--appkit-color-zinc-*`
|
|
272
|
+
* are declared once under :root and never inverted either. `surface-elevated`
|
|
273
|
+
* is not a substitute — it EQUALS `surface` in default-light and sunset, so a
|
|
274
|
+
* hover built on it does nothing at all in a light theme.
|
|
275
|
+
*
|
|
276
|
+
* `surface-hover` and `surface-raised` were referenced by 10 call sites for a
|
|
277
|
+
* long time while being declared nowhere, so they computed to nothing.
|
|
278
|
+
* NB: never write a closing curly brace in a comment in this file —
|
|
279
|
+
* audit-theme-drift matches each block non-greedily and a brace truncates it.
|
|
280
|
+
*/
|
|
281
|
+
--appkit-color-surface-hover: #f4f4f5;
|
|
282
|
+
--appkit-color-surface-raised: #fafafa;
|
|
283
|
+
--appkit-color-primary-surface: #f0fdfa;
|
|
284
|
+
|
|
285
|
+
|
|
265
286
|
--appkit-color-border: #e4e4e7; /* zinc-200 */
|
|
266
287
|
--appkit-color-border-subtle: #f4f4f5; /* zinc-100 */
|
|
267
288
|
|
|
@@ -383,6 +404,27 @@
|
|
|
383
404
|
--appkit-color-surface-elevated: rgba(15, 23, 42, 0.9);
|
|
384
405
|
--appkit-color-surface-input: rgba(30, 41, 59, 0.6); /* slate-800/60 */
|
|
385
406
|
|
|
407
|
+
/* --- Interactive surfaces ------------------------------------------------
|
|
408
|
+
* `-hover` is the neutral chrome hover fill; `-raised` is a resting panel one
|
|
409
|
+
* step off the page surface; `primary-surface` is the brand-tinted hover.
|
|
410
|
+
*
|
|
411
|
+
* All three INVERT with the theme, and that is the whole point. A hardcoded
|
|
412
|
+
* a hardcoded `zinc-50` hover fill is near-white in every theme, and sits under
|
|
413
|
+
* `dark:hover:text-*` white ink and is unreadable; `--appkit-color-zinc-*`
|
|
414
|
+
* are declared once under :root and never inverted either. `surface-elevated`
|
|
415
|
+
* is not a substitute — it EQUALS `surface` in default-light and sunset, so a
|
|
416
|
+
* hover built on it does nothing at all in a light theme.
|
|
417
|
+
*
|
|
418
|
+
* `surface-hover` and `surface-raised` were referenced by 10 call sites for a
|
|
419
|
+
* long time while being declared nowhere, so they computed to nothing.
|
|
420
|
+
* NB: never write a closing curly brace in a comment in this file —
|
|
421
|
+
* audit-theme-drift matches each block non-greedily and a brace truncates it.
|
|
422
|
+
*/
|
|
423
|
+
--appkit-color-surface-hover: rgba(148, 163, 184, 0.12);
|
|
424
|
+
--appkit-color-surface-raised: rgba(30, 41, 59, 0.7);
|
|
425
|
+
--appkit-color-primary-surface: rgba(239, 68, 68, 0.16);
|
|
426
|
+
|
|
427
|
+
|
|
386
428
|
--appkit-color-border: #334155; /* slate-700 */
|
|
387
429
|
--appkit-color-border-subtle: rgba(30, 41, 59, 0.6); /* slate-800/60 */
|
|
388
430
|
|
|
@@ -479,6 +521,27 @@
|
|
|
479
521
|
--appkit-color-surface-elevated: rgba(21, 54, 180, 0.9);
|
|
480
522
|
--appkit-color-surface-input: rgba(24, 49, 142, 0.6);
|
|
481
523
|
|
|
524
|
+
/* --- Interactive surfaces ------------------------------------------------
|
|
525
|
+
* `-hover` is the neutral chrome hover fill; `-raised` is a resting panel one
|
|
526
|
+
* step off the page surface; `primary-surface` is the brand-tinted hover.
|
|
527
|
+
*
|
|
528
|
+
* All three INVERT with the theme, and that is the whole point. A hardcoded
|
|
529
|
+
* a hardcoded `zinc-50` hover fill is near-white in every theme, and sits under
|
|
530
|
+
* `dark:hover:text-*` white ink and is unreadable; `--appkit-color-zinc-*`
|
|
531
|
+
* are declared once under :root and never inverted either. `surface-elevated`
|
|
532
|
+
* is not a substitute — it EQUALS `surface` in default-light and sunset, so a
|
|
533
|
+
* hover built on it does nothing at all in a light theme.
|
|
534
|
+
*
|
|
535
|
+
* `surface-hover` and `surface-raised` were referenced by 10 call sites for a
|
|
536
|
+
* long time while being declared nowhere, so they computed to nothing.
|
|
537
|
+
* NB: never write a closing curly brace in a comment in this file —
|
|
538
|
+
* audit-theme-drift matches each block non-greedily and a brace truncates it.
|
|
539
|
+
*/
|
|
540
|
+
--appkit-color-surface-hover: rgba(137, 185, 255, 0.14);
|
|
541
|
+
--appkit-color-surface-raised: rgba(24, 49, 142, 0.7);
|
|
542
|
+
--appkit-color-primary-surface: rgba(89, 146, 255, 0.18);
|
|
543
|
+
|
|
544
|
+
|
|
482
545
|
--appkit-color-border: #1343de; /* primary-700 */
|
|
483
546
|
--appkit-color-border-subtle: rgba(24, 49, 142, 0.6);
|
|
484
547
|
|
|
@@ -518,6 +581,27 @@
|
|
|
518
581
|
--appkit-color-surface-elevated: #ffffff;
|
|
519
582
|
--appkit-color-surface-input: #fffbeb; /* amber-50 */
|
|
520
583
|
|
|
584
|
+
/* --- Interactive surfaces ------------------------------------------------
|
|
585
|
+
* `-hover` is the neutral chrome hover fill; `-raised` is a resting panel one
|
|
586
|
+
* step off the page surface; `primary-surface` is the brand-tinted hover.
|
|
587
|
+
*
|
|
588
|
+
* All three INVERT with the theme, and that is the whole point. A hardcoded
|
|
589
|
+
* a hardcoded `zinc-50` hover fill is near-white in every theme, and sits under
|
|
590
|
+
* `dark:hover:text-*` white ink and is unreadable; `--appkit-color-zinc-*`
|
|
591
|
+
* are declared once under :root and never inverted either. `surface-elevated`
|
|
592
|
+
* is not a substitute — it EQUALS `surface` in default-light and sunset, so a
|
|
593
|
+
* hover built on it does nothing at all in a light theme.
|
|
594
|
+
*
|
|
595
|
+
* `surface-hover` and `surface-raised` were referenced by 10 call sites for a
|
|
596
|
+
* long time while being declared nowhere, so they computed to nothing.
|
|
597
|
+
* NB: never write a closing curly brace in a comment in this file —
|
|
598
|
+
* audit-theme-drift matches each block non-greedily and a brace truncates it.
|
|
599
|
+
*/
|
|
600
|
+
--appkit-color-surface-hover: #ffedd5;
|
|
601
|
+
--appkit-color-surface-raised: #fff7ed;
|
|
602
|
+
--appkit-color-primary-surface: #fef3c7;
|
|
603
|
+
|
|
604
|
+
|
|
521
605
|
--appkit-color-border: #fed7aa; /* orange-200 */
|
|
522
606
|
--appkit-color-border-subtle: #ffedd5; /* orange-100 */
|
|
523
607
|
|
package/dist/ui/DataTable.js
CHANGED
|
@@ -158,5 +158,5 @@ function SelectableCard({ id, selectable, selected, onToggle, children, listMode
|
|
|
158
158
|
selected
|
|
159
159
|
? "border-2 border-primary bg-primary"
|
|
160
160
|
: "border-2 border-zinc-500 dark:border-slate-400 bg-transparent group-hover:border-primary",
|
|
161
|
-
].join(" "), checked: selected, onChange: (e) => onToggle(id, e.target.checked), "aria-label": "Select item" }), selected && (_jsx("svg", { className: "absolute inset-0 m-auto
|
|
161
|
+
].join(" "), checked: selected, onChange: (e) => onToggle(id, e.target.checked), "aria-label": "Select item" }), selected && (_jsx("svg", { className: "absolute inset-0 m-auto h-3 w-3 text-white pointer-events-none", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 3, d: "M5 13l4 4L19 7" }) }))] }) }) }), selected && (_jsx(Div, { className: "absolute inset-0 z-[var(--appkit-z-raised)] ring-2 ring-primary ring-offset-0 pointer-events-none", rounded: "xl", "aria-hidden": "true" })), children] }));
|
|
162
162
|
}
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
.appkit-data-table__th--sortable:hover {
|
|
66
|
-
background: var(--appkit-color-
|
|
66
|
+
background: var(--appkit-color-surface-hover);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
:is(.dark) .appkit-data-table__th--sortable:hover {
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
.appkit-data-table__row--clickable:hover {
|
|
98
|
-
background: var(--appkit-color-
|
|
98
|
+
background: var(--appkit-color-surface-hover);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
:is(.dark) .appkit-data-table__row--clickable:hover {
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
.appkit-data-table__view-btn:hover {
|
|
163
|
-
background: var(--appkit-color-
|
|
163
|
+
background: var(--appkit-color-surface-hover);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
:is(.dark) .appkit-data-table__view-btn:hover {
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
transition: background-color 0.15s ease;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
.appkit-bulk-bar__picker-trigger:hover { background: var(--appkit-color-
|
|
79
|
+
.appkit-bulk-bar__picker-trigger:hover { background: var(--appkit-color-surface-hover); }
|
|
80
80
|
.appkit-bulk-bar__picker-trigger--danger { color: var(--appkit-color-rose-700); }
|
|
81
81
|
|
|
82
82
|
.appkit-bulk-bar__picker-icon {
|
|
@@ -182,8 +182,6 @@
|
|
|
182
182
|
background: rgba(30, 41, 59, 0.6);
|
|
183
183
|
color: var(--appkit-color-text);
|
|
184
184
|
}
|
|
185
|
-
|
|
186
|
-
.dark .appkit-bulk-bar__picker-trigger:hover { background: rgba(51, 65, 85, 0.6); }
|
|
187
185
|
.dark .appkit-bulk-bar__picker-trigger--danger { color: var(--appkit-color-rose-300); }
|
|
188
186
|
|
|
189
187
|
.dark .appkit-bulk-bar__dropdown {
|
|
@@ -7,7 +7,7 @@ import { Loader2 } from "lucide-react";
|
|
|
7
7
|
import { surfaceError } from "../../client/api/surface-error";
|
|
8
8
|
import { useToastSafe } from "./Toast";
|
|
9
9
|
import { SHADOW_MAP } from "./surface-tokens";
|
|
10
|
-
import { resolveIcon } from "../icons/icon-registry";
|
|
10
|
+
import { resolveIcon, ICON_SIZE } from "../icons/icon-registry";
|
|
11
11
|
function spawnRipple(host, clientX, clientY) {
|
|
12
12
|
const rect = host.getBoundingClientRect();
|
|
13
13
|
const size = Math.max(rect.width, rect.height);
|
|
@@ -117,11 +117,20 @@ const BUTTON_JUSTIFY_MAP = {
|
|
|
117
117
|
* `aria-hidden` because the label (or `ariaLabel`) already names the action;
|
|
118
118
|
* announcing the glyph as well would read it twice.
|
|
119
119
|
*/
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Icon size follows the BUTTON's size. It used to be hardcoded `h-4 w-4` for
|
|
122
|
+
* every size, so a `lg` button carried the same 16px glyph as an `sm` one.
|
|
123
|
+
*/
|
|
124
|
+
const ACTION_ICON_SIZE = {
|
|
125
|
+
sm: "sm",
|
|
126
|
+
md: "md",
|
|
127
|
+
lg: "lg",
|
|
128
|
+
};
|
|
129
|
+
function ActionIcon({ action, size, }) {
|
|
130
|
+
const Glyph = resolveIcon(action?.iconKey);
|
|
131
|
+
if (!Glyph)
|
|
123
132
|
return null;
|
|
124
|
-
return _jsx(
|
|
133
|
+
return (_jsx(Glyph, { className: `${ICON_SIZE[ACTION_ICON_SIZE[size]]} shrink-0`, "aria-hidden": "true" }));
|
|
125
134
|
}
|
|
126
135
|
// Map ActionKind → Button variant (caller can override via explicit variant prop)
|
|
127
136
|
const ACTION_KIND_VARIANT = {
|
|
@@ -151,7 +160,7 @@ export function Button({ variant, size = "md", className = "", isLoading = false
|
|
|
151
160
|
* label. If the caller passed children they have composed their own content,
|
|
152
161
|
* and injecting a glyph into it would be a surprise.
|
|
153
162
|
*/
|
|
154
|
-
const actionIcon = children === undefined && action?.iconKey ? _jsx(ActionIcon, { action: action }) : null;
|
|
163
|
+
const actionIcon = children === undefined && action?.iconKey ? _jsx(ActionIcon, { action: action, size: size }) : null;
|
|
155
164
|
const resolvedChildren = children ??
|
|
156
165
|
(action ? (actionIcon ? (_jsxs(_Fragment, { children: [actionIcon, action.label] })) : (action.label)) : undefined);
|
|
157
166
|
const resolvedAriaLabel = props["aria-label"] ?? (action ? (action.ariaLabel ?? action.label) : undefined);
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
color: var(--appkit-color-zinc-700);
|
|
67
67
|
}
|
|
68
68
|
.appkit-dropdown__composed-item:hover {
|
|
69
|
-
background: var(--appkit-color-
|
|
69
|
+
background: var(--appkit-color-surface-hover);
|
|
70
70
|
}
|
|
71
71
|
.appkit-dropdown__composed-item:disabled {
|
|
72
72
|
opacity: 0.5;
|
|
@@ -102,9 +102,6 @@
|
|
|
102
102
|
.dark .appkit-dropdown__composed-item {
|
|
103
103
|
color: var(--appkit-color-text);
|
|
104
104
|
}
|
|
105
|
-
.dark .appkit-dropdown__composed-item:hover {
|
|
106
|
-
background: var(--appkit-color-slate-800);
|
|
107
|
-
}
|
|
108
105
|
.dark .appkit-dropdown__separator {
|
|
109
106
|
border-color: var(--appkit-color-border);
|
|
110
107
|
}
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Div } from "./Div";
|
|
4
4
|
import { Text } from "./Typography";
|
|
5
5
|
const ACTIVE_CLS = "bg-[var(--appkit-color-primary)] text-white border-[var(--appkit-color-primary)]";
|
|
6
|
-
const INACTIVE_CLS = "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-
|
|
6
|
+
const INACTIVE_CLS = "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-surface-hover";
|
|
7
7
|
const CHIP_BASE_CLS = "rounded-full px-3 py-1 text-xs font-medium border transition-colors";
|
|
8
8
|
const LABEL_CLS = "text-xs font-semibold uppercase tracking-widest text-[var(--appkit-color-text-muted)]";
|
|
9
9
|
// `opacity-70` rather than a fixed colour so the count stays legible against
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ICONS, ICON_SIZE, type IconKey, type IconSizeKey } from "../icons/icon-registry";
|
|
3
|
+
/**
|
|
4
|
+
* Ink colour. Deliberately a small enum of THEME-INVERTING tokens rather than
|
|
5
|
+
* open className — a glyph that does not follow the theme is the same defect as
|
|
6
|
+
* a hardcoded `zinc-50` hover background, one property over.
|
|
7
|
+
*/
|
|
8
|
+
declare const TONES: {
|
|
9
|
+
readonly current: "";
|
|
10
|
+
readonly default: "text-[var(--appkit-color-text)]";
|
|
11
|
+
readonly muted: "text-[var(--appkit-color-text-muted)]";
|
|
12
|
+
readonly faint: "text-[var(--appkit-color-text-faint)]";
|
|
13
|
+
readonly primary: "text-primary";
|
|
14
|
+
readonly success: "text-success";
|
|
15
|
+
readonly warning: "text-warning";
|
|
16
|
+
readonly error: "text-error";
|
|
17
|
+
readonly info: "text-info";
|
|
18
|
+
/** White ink, for a glyph on a solid brand/status fill or a dark scrim. */
|
|
19
|
+
readonly "on-solid": "text-white";
|
|
20
|
+
};
|
|
21
|
+
export type IconTone = keyof typeof TONES;
|
|
22
|
+
export interface IconProps extends Omit<React.SVGProps<SVGSVGElement>, "ref" | "name"> {
|
|
23
|
+
/** Registry key — a typo is a compile error, not a silent blank. */
|
|
24
|
+
name: IconKey;
|
|
25
|
+
/** Role-based size. See ICON_SIZE for which to pick. */
|
|
26
|
+
size?: IconSizeKey;
|
|
27
|
+
tone?: IconTone;
|
|
28
|
+
/**
|
|
29
|
+
* Filled rather than outlined — the wishlist heart's "saved" state, a
|
|
30
|
+
* rating star, etc. Lucide glyphs are stroked outlines by default.
|
|
31
|
+
*/
|
|
32
|
+
filled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Give the glyph an accessible name. OMIT for decorative icons that sit
|
|
35
|
+
* beside a visible text label — the default is `aria-hidden`, because a
|
|
36
|
+
* screen reader announcing "heart, Add to wishlist" is worse than silence.
|
|
37
|
+
*/
|
|
38
|
+
label?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The single way to render an icon.
|
|
42
|
+
*
|
|
43
|
+
* 105 files imported `lucide-react` directly and each picked its own size, so
|
|
44
|
+
* "an icon" was whatever that file happened to choose. `icon-registry.ts` was
|
|
45
|
+
* built to be the indirection and had no consumer; this is it.
|
|
46
|
+
*
|
|
47
|
+
* Safe in a Server Component: `lucide-react` is plain CJS with no `"use client"`
|
|
48
|
+
* banner, and this file adds no hooks. Do NOT add state here without also
|
|
49
|
+
* checking every RSC call site (Root Cause #76).
|
|
50
|
+
*/
|
|
51
|
+
export declare function Icon({ name, size, tone, filled, label, className, ...rest }: IconProps): React.JSX.Element | null;
|
|
52
|
+
export { ICONS, ICON_SIZE };
|
|
53
|
+
export type { IconKey, IconSizeKey };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { twMerge } from "tailwind-merge";
|
|
3
|
+
import { ICONS, ICON_SIZE, resolveIcon, } from "../icons/icon-registry";
|
|
4
|
+
/**
|
|
5
|
+
* Ink colour. Deliberately a small enum of THEME-INVERTING tokens rather than
|
|
6
|
+
* open className — a glyph that does not follow the theme is the same defect as
|
|
7
|
+
* a hardcoded `zinc-50` hover background, one property over.
|
|
8
|
+
*/
|
|
9
|
+
const TONES = {
|
|
10
|
+
current: "",
|
|
11
|
+
default: "text-[var(--appkit-color-text)]",
|
|
12
|
+
muted: "text-[var(--appkit-color-text-muted)]",
|
|
13
|
+
faint: "text-[var(--appkit-color-text-faint)]",
|
|
14
|
+
primary: "text-primary",
|
|
15
|
+
success: "text-success",
|
|
16
|
+
warning: "text-warning",
|
|
17
|
+
error: "text-error",
|
|
18
|
+
info: "text-info",
|
|
19
|
+
/** White ink, for a glyph on a solid brand/status fill or a dark scrim. */
|
|
20
|
+
"on-solid": "text-white",
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The single way to render an icon.
|
|
24
|
+
*
|
|
25
|
+
* 105 files imported `lucide-react` directly and each picked its own size, so
|
|
26
|
+
* "an icon" was whatever that file happened to choose. `icon-registry.ts` was
|
|
27
|
+
* built to be the indirection and had no consumer; this is it.
|
|
28
|
+
*
|
|
29
|
+
* Safe in a Server Component: `lucide-react` is plain CJS with no `"use client"`
|
|
30
|
+
* banner, and this file adds no hooks. Do NOT add state here without also
|
|
31
|
+
* checking every RSC call site (Root Cause #76).
|
|
32
|
+
*/
|
|
33
|
+
export function Icon({ name, size = "md", tone = "current", filled = false, label, className = "", ...rest }) {
|
|
34
|
+
const Glyph = resolveIcon(name);
|
|
35
|
+
// `resolveIcon` returns undefined for an unknown key on purpose — render
|
|
36
|
+
// nothing and leave the label intact rather than drawing a broken-image box.
|
|
37
|
+
if (!Glyph)
|
|
38
|
+
return null;
|
|
39
|
+
return (_jsx(Glyph, { className: twMerge(ICON_SIZE[size], TONES[tone], "shrink-0", className), fill: filled ? "currentColor" : "none", "aria-hidden": label ? undefined : true, "aria-label": label, role: label ? "img" : undefined, ...rest }));
|
|
40
|
+
}
|
|
41
|
+
export { ICONS, ICON_SIZE };
|
|
@@ -3,8 +3,21 @@ import { type RoundedKey } from "./surface-tokens";
|
|
|
3
3
|
declare const SIZES: {
|
|
4
4
|
readonly sm: "appkit-icon-button--sm";
|
|
5
5
|
readonly md: "appkit-icon-button--md";
|
|
6
|
+
/** 44px — minimum comfortable tap target. See the CSS for when to use it. */
|
|
7
|
+
readonly touch: "appkit-icon-button--touch";
|
|
6
8
|
readonly lg: "appkit-icon-button--lg";
|
|
7
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* The glyph size each box wants. Callers should let the button decide rather
|
|
12
|
+
* than passing a size to the icon by hand — a mismatched pair (a 14px glyph in
|
|
13
|
+
* a 44px box) is the whole "the icon is very small" report.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ICON_BUTTON_ICON_SIZE: {
|
|
16
|
+
readonly sm: "sm";
|
|
17
|
+
readonly md: "md";
|
|
18
|
+
readonly touch: "lg";
|
|
19
|
+
readonly lg: "lg";
|
|
20
|
+
};
|
|
8
21
|
declare const VARIANTS: {
|
|
9
22
|
readonly ghost: "appkit-icon-button--ghost";
|
|
10
23
|
readonly outline: "appkit-icon-button--outline";
|
|
@@ -5,8 +5,21 @@ const BASE = "appkit-icon-button";
|
|
|
5
5
|
const SIZES = {
|
|
6
6
|
sm: "appkit-icon-button--sm",
|
|
7
7
|
md: "appkit-icon-button--md",
|
|
8
|
+
/** 44px — minimum comfortable tap target. See the CSS for when to use it. */
|
|
9
|
+
touch: "appkit-icon-button--touch",
|
|
8
10
|
lg: "appkit-icon-button--lg",
|
|
9
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* The glyph size each box wants. Callers should let the button decide rather
|
|
14
|
+
* than passing a size to the icon by hand — a mismatched pair (a 14px glyph in
|
|
15
|
+
* a 44px box) is the whole "the icon is very small" report.
|
|
16
|
+
*/
|
|
17
|
+
export const ICON_BUTTON_ICON_SIZE = {
|
|
18
|
+
sm: "sm",
|
|
19
|
+
md: "md",
|
|
20
|
+
touch: "lg",
|
|
21
|
+
lg: "lg",
|
|
22
|
+
};
|
|
10
23
|
const VARIANTS = {
|
|
11
24
|
ghost: "appkit-icon-button--ghost",
|
|
12
25
|
outline: "appkit-icon-button--outline",
|
|
@@ -36,23 +36,35 @@
|
|
|
36
36
|
border-radius: 0.75rem;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/* 44px — the minimum comfortable tap target. For a control that is the ONLY
|
|
40
|
+
* affordance in its area and has no text label to widen it: a product card's
|
|
41
|
+
* wishlist heart, a media overlay control. Sits between --md and --lg because
|
|
42
|
+
* those are round numbers, not accessibility thresholds.
|
|
43
|
+
*
|
|
44
|
+
* Use IconButton, not Button, for these: `.appkit-button--sm` sets
|
|
45
|
+
* `min-height: 36px`, and under `important: true` a caller's `h-8` (2rem)
|
|
46
|
+
* loses to it — which is how the card heart rendered as a 32x36 ellipse under
|
|
47
|
+
* `rounded-full`. These boxes set `width`+`height` with no min, so they are
|
|
48
|
+
* true squares. */
|
|
49
|
+
.appkit-icon-button--touch {
|
|
50
|
+
width: 2.75rem;
|
|
51
|
+
height: 2.75rem;
|
|
52
|
+
border-radius: 0.75rem;
|
|
53
|
+
}
|
|
54
|
+
|
|
39
55
|
.appkit-icon-button--ghost {
|
|
40
56
|
background: transparent;
|
|
41
57
|
color: var(--appkit-color-zinc-600);
|
|
42
58
|
}
|
|
43
59
|
|
|
44
60
|
.appkit-icon-button--ghost:hover:not(:disabled) {
|
|
45
|
-
background: var(--appkit-color-
|
|
61
|
+
background: var(--appkit-color-surface-hover);
|
|
46
62
|
}
|
|
47
63
|
|
|
48
64
|
.dark .appkit-icon-button--ghost {
|
|
49
65
|
color: var(--appkit-color-text-faint);
|
|
50
66
|
}
|
|
51
67
|
|
|
52
|
-
.dark .appkit-icon-button--ghost:hover:not(:disabled) {
|
|
53
|
-
background: var(--appkit-color-zinc-800);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
68
|
.appkit-icon-button--outline {
|
|
57
69
|
border-color: var(--appkit-color-border);
|
|
58
70
|
background: var(--appkit-color-surface);
|
|
@@ -60,7 +72,7 @@
|
|
|
60
72
|
}
|
|
61
73
|
|
|
62
74
|
.appkit-icon-button--outline:hover:not(:disabled) {
|
|
63
|
-
background: var(--appkit-color-
|
|
75
|
+
background: var(--appkit-color-surface-hover);
|
|
64
76
|
}
|
|
65
77
|
|
|
66
78
|
.dark .appkit-icon-button--outline {
|
|
@@ -69,10 +81,6 @@
|
|
|
69
81
|
color: var(--appkit-color-zinc-300);
|
|
70
82
|
}
|
|
71
83
|
|
|
72
|
-
.dark .appkit-icon-button--outline:hover:not(:disabled) {
|
|
73
|
-
background: var(--appkit-color-slate-800);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
84
|
.appkit-icon-button--primary {
|
|
77
85
|
background: var(--appkit-color-secondary-600);
|
|
78
86
|
color: var(--appkit-color-text-on-primary);
|
|
@@ -184,7 +184,7 @@
|
|
|
184
184
|
|
|
185
185
|
.appkit-listing-layout__filter-btn:hover {
|
|
186
186
|
border-color: var(--appkit-color-zinc-300);
|
|
187
|
-
background: var(--appkit-color-
|
|
187
|
+
background: var(--appkit-color-surface-hover);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
.appkit-listing-layout__filter-btn--active {
|
|
@@ -197,10 +197,6 @@
|
|
|
197
197
|
border-color: var(--appkit-color-slate-800);
|
|
198
198
|
color: var(--appkit-color-slate-300);
|
|
199
199
|
}
|
|
200
|
-
.dark .appkit-listing-layout__filter-btn:hover {
|
|
201
|
-
border-color: var(--appkit-color-slate-700);
|
|
202
|
-
background: rgba(30, 41, 59, 0.6);
|
|
203
|
-
}
|
|
204
200
|
|
|
205
201
|
/* -- Filter badge ------------------------------------ */
|
|
206
202
|
|
|
@@ -494,9 +490,5 @@
|
|
|
494
490
|
}
|
|
495
491
|
|
|
496
492
|
.appkit-listing-layout__close-btn:hover {
|
|
497
|
-
background: var(--appkit-color-
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
.dark .appkit-listing-layout__close-btn:hover {
|
|
501
|
-
background: var(--appkit-color-slate-800);
|
|
493
|
+
background: var(--appkit-color-surface-hover);
|
|
502
494
|
}
|
|
@@ -6,8 +6,8 @@ import { SortDropdown } from "./SortDropdown";
|
|
|
6
6
|
import { Div } from "./Div";
|
|
7
7
|
import { Span } from "./Typography";
|
|
8
8
|
import { StickyToolbar } from "./StickyToolbar";
|
|
9
|
-
const CLS_CLEAR_LINK = "text-xs
|
|
10
|
-
const CLS_CLEAR_ICON_BTN = "flex shrink-0 items-center justify-center rounded-lg border border-[var(--appkit-color-border)] p-1.5 sm:p-2 text-[var(--appkit-color-text-muted)] hover:bg-
|
|
9
|
+
const CLS_CLEAR_LINK = "text-xs hover:text-error text-[var(--appkit-color-text-muted)] transition-colors";
|
|
10
|
+
const CLS_CLEAR_ICON_BTN = "flex shrink-0 items-center justify-center rounded-lg border border-[var(--appkit-color-border)] p-1.5 sm:p-2 text-[var(--appkit-color-text-muted)] hover:bg-surface-hover hover:text-error dark:hover:text-error transition-colors";
|
|
11
11
|
const DEFAULT_LABELS = {
|
|
12
12
|
search: "Search",
|
|
13
13
|
filters: "Filters",
|
|
@@ -23,7 +23,7 @@ const DEFAULT_LABELS = {
|
|
|
23
23
|
};
|
|
24
24
|
const VIEW_BTN_BASE = "p-1.5 sm:p-2 transition-colors";
|
|
25
25
|
const VIEW_BTN_ACTIVE = "bg-[var(--appkit-color-primary)] text-white";
|
|
26
|
-
const VIEW_BTN_INACTIVE = "text-[var(--appkit-color-text-muted)] hover:bg-
|
|
26
|
+
const VIEW_BTN_INACTIVE = "text-[var(--appkit-color-text-muted)] hover:bg-surface-hover text-[var(--appkit-color-text-muted)]";
|
|
27
27
|
export function ListingToolbar({ filterCount = 0, onFiltersClick, searchValue = "", searchPlaceholder = "Search…", onSearchChange, onSearchCommit, onSearchKeyDown, sortValue, sortOptions, onSortChange, view = "grid", onViewChange, hideViewToggle = false, showTableView = false, onResetAll, hasActiveState = false, bulkMode = false, bulkSelectedCount = 0, bulkTotalCount = 0, onBulkSelectAll, onBulkClear, toggles, extra, labels, className = "", dismissible = true, toolbarId, collapseLabel = "Toolbar", }) {
|
|
28
28
|
const l = { ...DEFAULT_LABELS, ...labels };
|
|
29
29
|
const pathname = usePathname();
|
|
@@ -37,9 +37,9 @@ export function ListingToolbar({ filterCount = 0, onFiltersClick, searchValue =
|
|
|
37
37
|
}
|
|
38
38
|
};
|
|
39
39
|
const allSelected = bulkTotalCount > 0 && bulkSelectedCount === bulkTotalCount;
|
|
40
|
-
return (_jsx(StickyToolbar, { dataTestId: "listing-toolbar", offset: "header", tone: "translucent", border: true, padding: "none", z: "above-toolbar", className: `py-3 px-3 sm:py-3.5 sm:px-4 shadow-sm ${className}`, dismissible: dismissible, id: resolvedToolbarId, label: collapseLabel, children: _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center gap-2.5 sm:gap-3", children: [bulkMode ? (_jsxs("div", { className: "flex flex-1 items-center gap-2", children: [_jsxs("button", { type: "button", onClick: onBulkSelectAll, className: "flex items-center gap-1.5 rounded-lg border border-[var(--appkit-color-border)] px-3 py-1.5 text-sm font-medium text-[var(--appkit-color-text-muted)] hover:bg-
|
|
40
|
+
return (_jsx(StickyToolbar, { dataTestId: "listing-toolbar", offset: "header", tone: "translucent", border: true, padding: "none", z: "above-toolbar", className: `py-3 px-3 sm:py-3.5 sm:px-4 shadow-sm ${className}`, dismissible: dismissible, id: resolvedToolbarId, label: collapseLabel, children: _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center gap-2.5 sm:gap-3", children: [bulkMode ? (_jsxs("div", { className: "flex flex-1 items-center gap-2", children: [_jsxs("button", { type: "button", onClick: onBulkSelectAll, className: "flex items-center gap-1.5 rounded-lg border border-[var(--appkit-color-border)] px-3 py-1.5 text-sm font-medium text-[var(--appkit-color-text-muted)] hover:bg-surface-hover transition-colors", children: [allSelected
|
|
41
41
|
? _jsx(CheckSquare, { className: "h-4 w-4 text-[var(--appkit-color-primary)]" })
|
|
42
|
-
: _jsx(Square, { className: "h-4 w-4" }), allSelected ? l.deselectAll : l.selectAll(bulkTotalCount)] }), _jsx(Span, { size: "sm", color: "muted", children: l.selected(bulkSelectedCount) }), _jsx("button", { type: "button", onClick: onBulkClear, className: CLS_CLEAR_LINK, children: l.clearSelection })] })) : onSearchChange ? (_jsxs("div", { className: "flex flex-1 items-center overflow-hidden rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] min-w-0", children: [_jsx("input", { type: "text", value: searchValue, onChange: (e) => onSearchChange(e.target.value), onKeyDown: handleKeyDown, placeholder: searchPlaceholder, className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-zinc-400 outline-none" }), _jsx("button", { type: "button", onClick: onSearchCommit, className: "flex shrink-0 items-center justify-center px-2.5 py-2 text-zinc-400 hover:text-[var(--appkit-color-primary)] transition-colors", "aria-label": l.search, children: _jsx(Search, { className: "h-4 w-4" }) })] })) : null, _jsxs("div", { className: "flex flex-wrap items-center gap-1.5 sm:gap-2 sm:shrink-0", children: [onFiltersClick && (_jsxs("button", { type: "button", onClick: onFiltersClick, className: "relative flex shrink-0 items-center gap-1.5 rounded-lg border border-[var(--appkit-color-border)] px-2.5 py-1.5 sm:px-3.5 sm:py-2 text-sm font-medium text-[var(--appkit-color-text-muted)] hover:bg-
|
|
42
|
+
: _jsx(Square, { className: "h-4 w-4" }), allSelected ? l.deselectAll : l.selectAll(bulkTotalCount)] }), _jsx(Span, { size: "sm", color: "muted", children: l.selected(bulkSelectedCount) }), _jsx("button", { type: "button", onClick: onBulkClear, className: CLS_CLEAR_LINK, children: l.clearSelection })] })) : onSearchChange ? (_jsxs("div", { className: "flex flex-1 items-center overflow-hidden rounded-lg border border-[var(--appkit-color-border)] bg-[var(--appkit-color-surface)] min-w-0", children: [_jsx("input", { type: "text", value: searchValue, onChange: (e) => onSearchChange(e.target.value), onKeyDown: handleKeyDown, placeholder: searchPlaceholder, className: "min-w-0 flex-1 bg-transparent px-3 py-2 text-sm text-[var(--appkit-color-text)] placeholder-zinc-400 outline-none" }), _jsx("button", { type: "button", onClick: onSearchCommit, className: "flex shrink-0 items-center justify-center px-2.5 py-2 text-zinc-400 hover:text-[var(--appkit-color-primary)] transition-colors", "aria-label": l.search, children: _jsx(Search, { className: "h-4 w-4" }) })] })) : null, _jsxs("div", { className: "flex flex-wrap items-center gap-1.5 sm:gap-2 sm:shrink-0", children: [onFiltersClick && (_jsxs("button", { type: "button", onClick: onFiltersClick, className: "relative flex shrink-0 items-center gap-1.5 rounded-lg border border-[var(--appkit-color-border)] px-2.5 py-1.5 sm:px-3.5 sm:py-2 text-sm font-medium text-[var(--appkit-color-text-muted)] hover:bg-surface-hover transition-colors", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), _jsx("span", { className: "hidden sm:inline", children: l.filters }), filterCount > 0 && (_jsx(Span, { weight: "bold", className: "absolute -top-1.5 -right-1.5 flex h-4 w-4 items-center justify-center rounded-full bg-[var(--appkit-color-primary)] text-[10px] text-white", children: filterCount }))] })), sortOptions && sortValue !== undefined && onSortChange && (_jsxs(Div, { className: "flex items-center gap-1.5 text-[var(--appkit-color-text-muted)]", children: [_jsx(Span, { size: "xs", className: "hidden md:inline whitespace-nowrap", children: l.sort }), _jsx(SortDropdown, { value: sortValue, onChange: onSortChange, options: sortOptions })] })), !hideViewToggle && onViewChange && (_jsxs("div", { className: "flex items-center rounded-lg border border-[var(--appkit-color-border)] overflow-hidden", children: [_jsx("button", { type: "button", onClick: () => onViewChange("grid"), "aria-label": l.gridView, className: `${VIEW_BTN_BASE} ${view === "grid" ? VIEW_BTN_ACTIVE : VIEW_BTN_INACTIVE}`, children: _jsx(LayoutGrid, { className: "h-4 w-4" }) }), _jsx("button", { type: "button", onClick: () => onViewChange("list"), "aria-label": l.listView, className: `${VIEW_BTN_BASE} ${view === "list" ? VIEW_BTN_ACTIVE : VIEW_BTN_INACTIVE}`, children: _jsx(List, { className: "h-4 w-4" }) }), showTableView && (_jsx("button", { type: "button", onClick: () => onViewChange("table"), "aria-label": l.tableView, className: `${VIEW_BTN_BASE} ${view === "table" ? VIEW_BTN_ACTIVE : VIEW_BTN_INACTIVE}`, children: _jsx(Table2, { className: "h-4 w-4" }) }))] })), onResetAll && hasActiveState && (_jsx("button", { type: "button", onClick: onResetAll, "aria-label": l.resetAll, title: l.resetAll, className: CLS_CLEAR_ICON_BTN, children: _jsx(RotateCcw, { className: "h-4 w-4" }) })), toggles && toggles.length > 0 && (_jsx("div", { className: "flex items-center gap-1", children: toggles.map((t) => (_jsx("button", { type: "button", role: "switch", "aria-checked": t.active, onClick: () => t.onChange(!t.active), className: `rounded-full border px-2.5 py-1 text-xs font-medium transition-colors whitespace-nowrap ${t.active
|
|
43
43
|
? "border-transparent bg-[var(--appkit-color-primary)] text-white"
|
|
44
|
-
: "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-
|
|
44
|
+
: "border-[var(--appkit-color-border)] text-[var(--appkit-color-text-muted)] hover:bg-surface-hover"}`, children: t.label }, t.label))) })), extra] })] }) }));
|
|
45
45
|
}
|
|
@@ -76,7 +76,7 @@ export function Modal({ isOpen, open, onClose, title, children, size = "md", sho
|
|
|
76
76
|
}
|
|
77
77
|
export function ModalFooter({ children, className = "", }) {
|
|
78
78
|
return (_jsx("div", { className: [
|
|
79
|
-
"flex items-center justify-end gap-3 border-t
|
|
79
|
+
"flex items-center justify-end gap-3 border-t px-6 py-4 border-[var(--appkit-color-border-subtle)]",
|
|
80
80
|
className,
|
|
81
81
|
]
|
|
82
82
|
.filter(Boolean)
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
.appkit-ps__chip-remove:hover {
|
|
50
50
|
color: var(--appkit-color-text);
|
|
51
|
-
background-color: var(--appkit-color-
|
|
51
|
+
background-color: var(--appkit-color-surface-hover);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
:is(.dark) .appkit-ps__chip-remove:hover {
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
.appkit-ps__option:hover {
|
|
170
|
-
background-color: var(--appkit-color-
|
|
170
|
+
background-color: var(--appkit-color-surface-hover);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
:is(.dark) .appkit-ps__option:hover {
|
|
@@ -254,7 +254,7 @@
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
.appkit-ps__create-btn:hover {
|
|
257
|
-
background-color: var(--appkit-color-
|
|
257
|
+
background-color: var(--appkit-color-surface-hover);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
:is(.dark) .appkit-ps__create-btn:hover {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
.appkit-pagination__button--default:hover {
|
|
25
|
-
background: var(--appkit-color-
|
|
25
|
+
background: var(--appkit-color-surface-hover);
|
|
26
26
|
border-color: var(--appkit-color-zinc-300);
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -55,11 +55,6 @@
|
|
|
55
55
|
color: var(--appkit-color-slate-300);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
.dark .appkit-pagination__button--default:hover {
|
|
59
|
-
background: var(--appkit-color-slate-800);
|
|
60
|
-
border-color: var(--appkit-color-slate-600);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
58
|
.dark .appkit-pagination__button--active {
|
|
64
59
|
background: var(--appkit-color-primary);
|
|
65
60
|
border-color: var(--appkit-color-primary);
|