@open-mercato/core 0.7.1-develop.7203.1.9396450b78 → 0.8.1-develop.7204.1.83330e271e
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/.turbo/turbo-build.log +1 -1
- package/build.mjs +11 -0
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +23 -0
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +2 -1
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +2 -1
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +2 -1
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/lib/detailHelpers.js +4 -0
- package/dist/modules/customers/lib/detailHelpers.js.map +2 -2
- package/dist/modules/customers/lib/todoCompatibility.js +5 -0
- package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
- package/dist/modules/design_system/backend/design-system/page.meta.js +3 -2
- package/dist/modules/design_system/backend/design-system/page.meta.js.map +2 -2
- package/dist/modules/design_system/gallery/assets/ai-prompt-image.png +0 -0
- package/dist/modules/design_system/gallery/assets/avatar-illustration.png +0 -0
- package/dist/modules/design_system/gallery/assets/avatar-memoji.png +0 -0
- package/dist/modules/design_system/gallery/assets/avatar-photo.png +0 -0
- package/dist/modules/design_system/gallery/assets/blog-photo-0.png +0 -0
- package/dist/modules/design_system/gallery/assets/contact-support-portrait.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-ada.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-avax.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-bnb.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-brand.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-btc.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-clock.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-crown.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-dot.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-eth.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-hbar.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-history.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-link.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-menu.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-metamask.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-more.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-phantom.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-rewards.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-sad-face.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-sol.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-star.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-status-cancelled.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-status-pending.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-status-success.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-status-warning.svg +3 -0
- package/dist/modules/design_system/gallery/assets/crypto-trx.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-usdc.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-usdt.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-walletconnect.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-wei.png +0 -0
- package/dist/modules/design_system/gallery/assets/crypto-xrp.png +0 -0
- package/dist/modules/design_system/gallery/assets/cryptocurrency-artwork.js +67 -0
- package/dist/modules/design_system/gallery/assets/cryptocurrency-artwork.js.map +7 -0
- package/dist/modules/design_system/gallery/assets/github-logo.png +0 -0
- package/dist/modules/design_system/gallery/assets/images.d.js +1 -0
- package/dist/modules/design_system/gallery/assets/images.d.js.map +7 -0
- package/dist/modules/design_system/gallery/assets/input-european-union.svg +18 -0
- package/dist/modules/design_system/gallery/assets/landing-teams-01.png +0 -0
- package/dist/modules/design_system/gallery/assets/marketing-artwork.js +83 -0
- package/dist/modules/design_system/gallery/assets/marketing-artwork.js.map +7 -0
- package/dist/modules/design_system/gallery/assets/menu-apex.svg +18 -0
- package/dist/modules/design_system/gallery/assets/menu-mastercard.svg +7 -0
- package/dist/modules/design_system/gallery/assets/menu-spotify.svg +4 -0
- package/dist/modules/design_system/gallery/assets/menu-united-states.svg +16 -0
- package/dist/modules/design_system/gallery/assets/select-google.png +0 -0
- package/dist/modules/design_system/gallery/assets/select-poland.png +0 -0
- package/dist/modules/design_system/gallery/assets/selection-artwork.js +5 -0
- package/dist/modules/design_system/gallery/assets/selection-artwork.js.map +7 -0
- package/dist/modules/design_system/gallery/assets/social-apple-filled.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-apple-stroke.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-dropbox-filled.svg +5 -0
- package/dist/modules/design_system/gallery/assets/social-dropbox-stroke.svg +5 -0
- package/dist/modules/design_system/gallery/assets/social-facebook-filled.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-facebook-stroke.svg +10 -0
- package/dist/modules/design_system/gallery/assets/social-github-filled.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-github-stroke.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-google-filled.svg +7 -0
- package/dist/modules/design_system/gallery/assets/social-google-stroke.svg +7 -0
- package/dist/modules/design_system/gallery/assets/social-linkedin-filled.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-linkedin-stroke.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-x-filled.svg +4 -0
- package/dist/modules/design_system/gallery/assets/social-x-stroke.svg +4 -0
- package/dist/modules/design_system/gallery/assets/style-studio-product.png +0 -0
- package/dist/modules/design_system/gallery/assets/upload-images.js +8 -0
- package/dist/modules/design_system/gallery/assets/upload-images.js.map +7 -0
- package/dist/modules/design_system/gallery/components/BrandStylePreview.js +74 -0
- package/dist/modules/design_system/gallery/components/BrandStylePreview.js.map +7 -0
- package/dist/modules/design_system/gallery/components/CodeSnippet.js +31 -31
- package/dist/modules/design_system/gallery/components/CodeSnippet.js.map +2 -2
- package/dist/modules/design_system/gallery/components/ColorPlayground.js +408 -0
- package/dist/modules/design_system/gallery/components/ColorPlayground.js.map +7 -0
- package/dist/modules/design_system/gallery/components/ColorStudioCompositions.js +166 -0
- package/dist/modules/design_system/gallery/components/ColorStudioCompositions.js.map +7 -0
- package/dist/modules/design_system/gallery/components/ColorStudioSpecimen.js +182 -0
- package/dist/modules/design_system/gallery/components/ColorStudioSpecimen.js.map +7 -0
- package/dist/modules/design_system/gallery/components/CompactEntrySpecimen.js +80 -0
- package/dist/modules/design_system/gallery/components/CompactEntrySpecimen.js.map +7 -0
- package/dist/modules/design_system/gallery/components/ComponentIndex.js +42 -0
- package/dist/modules/design_system/gallery/components/ComponentIndex.js.map +7 -0
- package/dist/modules/design_system/gallery/components/DesignSystemHome.js +69 -0
- package/dist/modules/design_system/gallery/components/DesignSystemHome.js.map +7 -0
- package/dist/modules/design_system/gallery/components/EntryCard.js +47 -41
- package/dist/modules/design_system/gallery/components/EntryCard.js.map +2 -2
- package/dist/modules/design_system/gallery/components/EntryHeader.js +68 -0
- package/dist/modules/design_system/gallery/components/EntryHeader.js.map +7 -0
- package/dist/modules/design_system/gallery/components/FamilyEntryPreview.js +19 -0
- package/dist/modules/design_system/gallery/components/FamilyEntryPreview.js.map +7 -0
- package/dist/modules/design_system/gallery/components/FoundationGuide.js +46 -0
- package/dist/modules/design_system/gallery/components/FoundationGuide.js.map +7 -0
- package/dist/modules/design_system/gallery/components/GalleryLink.js +21 -0
- package/dist/modules/design_system/gallery/components/GalleryLink.js.map +7 -0
- package/dist/modules/design_system/gallery/components/GalleryNavigation.js +82 -0
- package/dist/modules/design_system/gallery/components/GalleryNavigation.js.map +7 -0
- package/dist/modules/design_system/gallery/components/GalleryShell.js +147 -67
- package/dist/modules/design_system/gallery/components/GalleryShell.js.map +3 -3
- package/dist/modules/design_system/gallery/components/IconsBrowser.js +33 -0
- package/dist/modules/design_system/gallery/components/IconsBrowser.js.map +7 -0
- package/dist/modules/design_system/gallery/components/SourceLibrary.js +93 -0
- package/dist/modules/design_system/gallery/components/SourceLibrary.js.map +7 -0
- package/dist/modules/design_system/gallery/components/StyleAgents.js +139 -0
- package/dist/modules/design_system/gallery/components/StyleAgents.js.map +7 -0
- package/dist/modules/design_system/gallery/components/ThemeTokenReference.js +101 -0
- package/dist/modules/design_system/gallery/components/ThemeTokenReference.js.map +7 -0
- package/dist/modules/design_system/gallery/components/VariantPreview.js +2 -2
- package/dist/modules/design_system/gallery/components/VariantPreview.js.map +2 -2
- package/dist/modules/design_system/gallery/components/colorPreview.js +58 -0
- package/dist/modules/design_system/gallery/components/colorPreview.js.map +7 -0
- package/dist/modules/design_system/gallery/components/colorStudio.js +218 -0
- package/dist/modules/design_system/gallery/components/colorStudio.js.map +7 -0
- package/dist/modules/design_system/gallery/components/styleAgentBranding.js +46 -0
- package/dist/modules/design_system/gallery/components/styleAgentBranding.js.map +7 -0
- package/dist/modules/design_system/gallery/components/themeTokens.js +32 -0
- package/dist/modules/design_system/gallery/components/themeTokens.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/ai-product-code.generated.js +194 -0
- package/dist/modules/design_system/gallery/demos/ai-product-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/ai-product.js +423 -0
- package/dist/modules/design_system/gallery/demos/ai-product.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/buttons.js +289 -0
- package/dist/modules/design_system/gallery/demos/buttons.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/cryptocurrency.js +1708 -0
- package/dist/modules/design_system/gallery/demos/cryptocurrency.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/feeds-code.generated.js +92 -0
- package/dist/modules/design_system/gallery/demos/feeds-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/feeds.js +148 -0
- package/dist/modules/design_system/gallery/demos/feeds.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/file-upload.js +72 -0
- package/dist/modules/design_system/gallery/demos/file-upload.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/foundation-reference-data.js +4875 -0
- package/dist/modules/design_system/gallery/demos/foundation-reference-data.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/foundation-references.js +188 -0
- package/dist/modules/design_system/gallery/demos/foundation-references.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/key-components-code.generated.js +6 -0
- package/dist/modules/design_system/gallery/demos/key-components-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/key-components.js +127 -0
- package/dist/modules/design_system/gallery/demos/key-components.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/marketing-controls-code.generated.js +98 -0
- package/dist/modules/design_system/gallery/demos/marketing-controls-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/marketing-controls.js +134 -0
- package/dist/modules/design_system/gallery/demos/marketing-controls.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/marketing-widgets-code.generated.js +195 -0
- package/dist/modules/design_system/gallery/demos/marketing-widgets-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/marketing-widgets.js +586 -0
- package/dist/modules/design_system/gallery/demos/marketing-widgets.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/menu-fixtures.js +40 -0
- package/dist/modules/design_system/gallery/demos/menu-fixtures.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/menu-sources.js +295 -0
- package/dist/modules/design_system/gallery/demos/menu-sources.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/menus.js +150 -0
- package/dist/modules/design_system/gallery/demos/menus.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/rating-reviews.js +53 -0
- package/dist/modules/design_system/gallery/demos/rating-reviews.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/registered-icons.js +104 -0
- package/dist/modules/design_system/gallery/demos/registered-icons.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/selection-cards.js +99 -0
- package/dist/modules/design_system/gallery/demos/selection-cards.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/shell-code.generated.js +189 -0
- package/dist/modules/design_system/gallery/demos/shell-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/shell.js +330 -0
- package/dist/modules/design_system/gallery/demos/shell.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/source-artwork.js +120 -0
- package/dist/modules/design_system/gallery/demos/source-artwork.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/source-filters-code.generated.js +125 -0
- package/dist/modules/design_system/gallery/demos/source-filters-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/source-filters.js +185 -0
- package/dist/modules/design_system/gallery/demos/source-filters.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/source-icons.js +69 -0
- package/dist/modules/design_system/gallery/demos/source-icons.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/table-cells-code.generated.js +150 -0
- package/dist/modules/design_system/gallery/demos/table-cells-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/table-cells.js +181 -0
- package/dist/modules/design_system/gallery/demos/table-cells.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/text-inputs.js +113 -0
- package/dist/modules/design_system/gallery/demos/text-inputs.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/time-picker-code.generated.js +41 -0
- package/dist/modules/design_system/gallery/demos/time-picker-code.generated.js.map +7 -0
- package/dist/modules/design_system/gallery/demos/time-picker.js +41 -0
- package/dist/modules/design_system/gallery/demos/time-picker.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/banners.js +123 -60
- package/dist/modules/design_system/gallery/entries/banners.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/buttons-snippets.js +433 -0
- package/dist/modules/design_system/gallery/entries/buttons-snippets.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/buttons.js +127 -148
- package/dist/modules/design_system/gallery/entries/buttons.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/charts.js +532 -186
- package/dist/modules/design_system/gallery/entries/charts.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/dates.js +191 -3
- package/dist/modules/design_system/gallery/entries/dates.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/detail.js +118 -77
- package/dist/modules/design_system/gallery/entries/detail.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/display.js +1449 -240
- package/dist/modules/design_system/gallery/entries/display.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/feedback.js +1058 -132
- package/dist/modules/design_system/gallery/entries/feedback.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/filters.js +231 -103
- package/dist/modules/design_system/gallery/entries/filters.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/foundations.js +368 -57
- package/dist/modules/design_system/gallery/entries/foundations.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/icons.js +29 -91
- package/dist/modules/design_system/gallery/entries/icons.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/inputs-snippets.js +154 -0
- package/dist/modules/design_system/gallery/entries/inputs-snippets.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/inputs.js +2043 -306
- package/dist/modules/design_system/gallery/entries/inputs.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/library.js +20 -0
- package/dist/modules/design_system/gallery/entries/library.js.map +7 -0
- package/dist/modules/design_system/gallery/entries/messages.js +121 -103
- package/dist/modules/design_system/gallery/entries/messages.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/navigation.js +676 -103
- package/dist/modules/design_system/gallery/entries/navigation.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/notifications.js +131 -78
- package/dist/modules/design_system/gallery/entries/notifications.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/overlays.js +611 -203
- package/dist/modules/design_system/gallery/entries/overlays.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/scaffolding.js +1175 -120
- package/dist/modules/design_system/gallery/entries/scaffolding.js.map +2 -2
- package/dist/modules/design_system/gallery/entries/schedule.js +79 -54
- package/dist/modules/design_system/gallery/entries/schedule.js.map +2 -2
- package/dist/modules/design_system/gallery/presentation.js +108 -0
- package/dist/modules/design_system/gallery/presentation.js.map +7 -0
- package/dist/modules/design_system/gallery/registry.js +8 -5
- package/dist/modules/design_system/gallery/registry.js.map +2 -2
- package/dist/modules/design_system/gallery/source-library.generated.js +5 -0
- package/dist/modules/design_system/gallery/source-library.generated.js.map +7 -0
- package/dist/modules/design_system/i18n/de.json +7167 -0
- package/dist/modules/design_system/i18n/en.json +7167 -0
- package/dist/modules/design_system/i18n/es.json +7167 -0
- package/dist/modules/design_system/i18n/ko.json +7167 -0
- package/dist/modules/design_system/i18n/pl.json +7167 -0
- package/dist/modules/push_notifications/lib/queue.js +1 -31
- package/dist/modules/push_notifications/lib/queue.js.map +2 -2
- package/jest.config.cjs +1 -0
- package/jest.mocks/image.js +1 -0
- package/package.json +8 -8
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +50 -0
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +2 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +2 -1
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +2 -2
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +2 -1
- package/src/modules/customers/lib/detailHelpers.ts +4 -0
- package/src/modules/customers/lib/todoCompatibility.ts +10 -0
- package/src/modules/design_system/backend/design-system/page.meta.ts +3 -2
- package/src/modules/design_system/gallery/assets/README.md +30 -0
- package/src/modules/design_system/gallery/assets/ai-prompt-image.png +0 -0
- package/src/modules/design_system/gallery/assets/avatar-illustration.png +0 -0
- package/src/modules/design_system/gallery/assets/avatar-memoji.png +0 -0
- package/src/modules/design_system/gallery/assets/avatar-photo.png +0 -0
- package/src/modules/design_system/gallery/assets/blog-photo-0.png +0 -0
- package/src/modules/design_system/gallery/assets/contact-support-portrait.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-ada.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-avax.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-bnb.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-brand.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-btc.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-clock.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-crown.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-dot.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-eth.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-hbar.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-history.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-link.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-menu.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-metamask.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-more.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-phantom.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-rewards.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-sad-face.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-sol.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-star.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-status-cancelled.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-status-pending.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-status-success.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-status-warning.svg +3 -0
- package/src/modules/design_system/gallery/assets/crypto-trx.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-usdc.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-usdt.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-walletconnect.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-wei.png +0 -0
- package/src/modules/design_system/gallery/assets/crypto-xrp.png +0 -0
- package/src/modules/design_system/gallery/assets/cryptocurrency-artwork.ts +63 -0
- package/src/modules/design_system/gallery/assets/github-logo.png +0 -0
- package/src/modules/design_system/gallery/assets/images.d.ts +9 -0
- package/src/modules/design_system/gallery/assets/input-european-union.svg +18 -0
- package/src/modules/design_system/gallery/assets/landing-teams-01.png +0 -0
- package/src/modules/design_system/gallery/assets/marketing-artwork.ts +79 -0
- package/src/modules/design_system/gallery/assets/menu-apex.svg +18 -0
- package/src/modules/design_system/gallery/assets/menu-mastercard.svg +7 -0
- package/src/modules/design_system/gallery/assets/menu-spotify.svg +4 -0
- package/src/modules/design_system/gallery/assets/menu-united-states.svg +16 -0
- package/src/modules/design_system/gallery/assets/select-google.png +0 -0
- package/src/modules/design_system/gallery/assets/select-poland.png +0 -0
- package/src/modules/design_system/gallery/assets/selection-artwork.ts +1 -0
- package/src/modules/design_system/gallery/assets/social-apple-filled.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-apple-stroke.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-dropbox-filled.svg +5 -0
- package/src/modules/design_system/gallery/assets/social-dropbox-stroke.svg +5 -0
- package/src/modules/design_system/gallery/assets/social-facebook-filled.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-facebook-stroke.svg +10 -0
- package/src/modules/design_system/gallery/assets/social-github-filled.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-github-stroke.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-google-filled.svg +7 -0
- package/src/modules/design_system/gallery/assets/social-google-stroke.svg +7 -0
- package/src/modules/design_system/gallery/assets/social-linkedin-filled.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-linkedin-stroke.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-x-filled.svg +4 -0
- package/src/modules/design_system/gallery/assets/social-x-stroke.svg +4 -0
- package/src/modules/design_system/gallery/assets/style-studio-product.png +0 -0
- package/src/modules/design_system/gallery/assets/upload-images.ts +5 -0
- package/src/modules/design_system/gallery/components/BrandStylePreview.tsx +94 -0
- package/src/modules/design_system/gallery/components/CodeSnippet.tsx +34 -34
- package/src/modules/design_system/gallery/components/ColorPlayground.tsx +324 -0
- package/src/modules/design_system/gallery/components/ColorStudioCompositions.tsx +96 -0
- package/src/modules/design_system/gallery/components/ColorStudioSpecimen.tsx +164 -0
- package/src/modules/design_system/gallery/components/CompactEntrySpecimen.tsx +65 -0
- package/src/modules/design_system/gallery/components/ComponentIndex.tsx +47 -0
- package/src/modules/design_system/gallery/components/DesignSystemHome.tsx +66 -0
- package/src/modules/design_system/gallery/components/EntryCard.tsx +52 -37
- package/src/modules/design_system/gallery/components/EntryHeader.tsx +80 -0
- package/src/modules/design_system/gallery/components/FamilyEntryPreview.tsx +22 -0
- package/src/modules/design_system/gallery/components/FoundationGuide.tsx +43 -0
- package/src/modules/design_system/gallery/components/GalleryLink.tsx +19 -0
- package/src/modules/design_system/gallery/components/GalleryNavigation.tsx +86 -0
- package/src/modules/design_system/gallery/components/GalleryShell.tsx +149 -63
- package/src/modules/design_system/gallery/components/IconsBrowser.tsx +40 -0
- package/src/modules/design_system/gallery/components/SourceLibrary.tsx +90 -0
- package/src/modules/design_system/gallery/components/StyleAgents.tsx +115 -0
- package/src/modules/design_system/gallery/components/ThemeTokenReference.tsx +76 -0
- package/src/modules/design_system/gallery/components/VariantPreview.tsx +2 -2
- package/src/modules/design_system/gallery/components/colorPreview.ts +63 -0
- package/src/modules/design_system/gallery/components/colorStudio.ts +260 -0
- package/src/modules/design_system/gallery/components/styleAgentBranding.ts +42 -0
- package/src/modules/design_system/gallery/components/themeTokens.ts +26 -0
- package/src/modules/design_system/gallery/demos/ai-product-code.generated.ts +3 -0
- package/src/modules/design_system/gallery/demos/ai-product.tsx +188 -0
- package/src/modules/design_system/gallery/demos/buttons.tsx +331 -0
- package/src/modules/design_system/gallery/demos/cryptocurrency.tsx +1943 -0
- package/src/modules/design_system/gallery/demos/feeds-code.generated.ts +4 -0
- package/src/modules/design_system/gallery/demos/feeds.tsx +82 -0
- package/src/modules/design_system/gallery/demos/file-upload.tsx +61 -0
- package/src/modules/design_system/gallery/demos/foundation-reference-data.ts +4872 -0
- package/src/modules/design_system/gallery/demos/foundation-references.tsx +140 -0
- package/src/modules/design_system/gallery/demos/key-components-code.generated.ts +3 -0
- package/src/modules/design_system/gallery/demos/key-components.tsx +106 -0
- package/src/modules/design_system/gallery/demos/marketing-controls-code.generated.ts +3 -0
- package/src/modules/design_system/gallery/demos/marketing-controls.tsx +92 -0
- package/src/modules/design_system/gallery/demos/marketing-widgets-code.generated.ts +3 -0
- package/src/modules/design_system/gallery/demos/marketing-widgets.tsx +189 -0
- package/src/modules/design_system/gallery/demos/menu-fixtures.tsx +48 -0
- package/src/modules/design_system/gallery/demos/menu-sources.ts +5 -0
- package/src/modules/design_system/gallery/demos/menus.tsx +122 -0
- package/src/modules/design_system/gallery/demos/rating-reviews.tsx +44 -0
- package/src/modules/design_system/gallery/demos/registered-icons.tsx +117 -0
- package/src/modules/design_system/gallery/demos/selection-cards.tsx +97 -0
- package/src/modules/design_system/gallery/demos/shell-code.generated.ts +3 -0
- package/src/modules/design_system/gallery/demos/shell.tsx +183 -0
- package/src/modules/design_system/gallery/demos/source-artwork.tsx +88 -0
- package/src/modules/design_system/gallery/demos/source-filters-code.generated.ts +3 -0
- package/src/modules/design_system/gallery/demos/source-filters.tsx +119 -0
- package/src/modules/design_system/gallery/demos/source-icons.tsx +62 -0
- package/src/modules/design_system/gallery/demos/table-cells-code.generated.ts +3 -0
- package/src/modules/design_system/gallery/demos/table-cells.tsx +144 -0
- package/src/modules/design_system/gallery/demos/text-inputs.tsx +90 -0
- package/src/modules/design_system/gallery/demos/time-picker-code.generated.ts +5 -0
- package/src/modules/design_system/gallery/demos/time-picker.tsx +31 -0
- package/src/modules/design_system/gallery/entries/banners.tsx +143 -94
- package/src/modules/design_system/gallery/entries/buttons-snippets.ts +432 -0
- package/src/modules/design_system/gallery/entries/buttons.tsx +125 -196
- package/src/modules/design_system/gallery/entries/charts.tsx +545 -233
- package/src/modules/design_system/gallery/entries/dates.tsx +171 -3
- package/src/modules/design_system/gallery/entries/detail.tsx +142 -115
- package/src/modules/design_system/gallery/entries/display.tsx +1691 -319
- package/src/modules/design_system/gallery/entries/feedback.tsx +1082 -169
- package/src/modules/design_system/gallery/entries/filters.tsx +238 -143
- package/src/modules/design_system/gallery/entries/foundations.tsx +404 -61
- package/src/modules/design_system/gallery/entries/icons.tsx +31 -117
- package/src/modules/design_system/gallery/entries/inputs-snippets.ts +156 -0
- package/src/modules/design_system/gallery/entries/inputs.tsx +2146 -503
- package/src/modules/design_system/gallery/entries/library.tsx +16 -0
- package/src/modules/design_system/gallery/entries/messages.tsx +114 -106
- package/src/modules/design_system/gallery/entries/navigation.tsx +782 -192
- package/src/modules/design_system/gallery/entries/notifications.tsx +145 -120
- package/src/modules/design_system/gallery/entries/overlays.tsx +696 -280
- package/src/modules/design_system/gallery/entries/scaffolding.tsx +1192 -158
- package/src/modules/design_system/gallery/entries/schedule.tsx +72 -58
- package/src/modules/design_system/gallery/presentation.ts +106 -0
- package/src/modules/design_system/gallery/registry.ts +8 -6
- package/src/modules/design_system/gallery/source-library.generated.ts +2 -0
- package/src/modules/design_system/i18n/de.json +7112 -3
- package/src/modules/design_system/i18n/en.json +7112 -3
- package/src/modules/design_system/i18n/es.json +7112 -3
- package/src/modules/design_system/i18n/ko.json +7112 -3
- package/src/modules/design_system/i18n/pl.json +7112 -3
- package/src/modules/push_notifications/AGENTS.md +9 -5
- package/src/modules/push_notifications/lib/queue.ts +15 -44
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { MarketingControlDemo } from '../demos/marketing-controls'
|
|
2
|
+
import { marketingControlExampleCode } from '../demos/marketing-controls-code.generated'
|
|
3
|
+
import { FieldLabelExample, FormFieldLabelExample, HintTextExample } from '../demos/key-components'
|
|
1
4
|
import * as React from 'react'
|
|
2
5
|
import { Copy, Globe, Info, Link2, Send, User } from 'lucide-react'
|
|
6
|
+
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
3
7
|
import { Input } from '@open-mercato/ui/primitives/input'
|
|
4
8
|
import { Textarea } from '@open-mercato/ui/primitives/textarea'
|
|
5
9
|
import {
|
|
@@ -22,11 +26,13 @@ import { Radio, RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
|
22
26
|
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
23
27
|
import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
24
28
|
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
29
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
25
30
|
import { Slider } from '@open-mercato/ui/primitives/slider'
|
|
26
31
|
import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
27
32
|
import { SearchInput } from '@open-mercato/ui/primitives/search-input'
|
|
28
33
|
import { EmailInput } from '@open-mercato/ui/primitives/email-input'
|
|
29
34
|
import { PasswordInput } from '@open-mercato/ui/primitives/password-input'
|
|
35
|
+
import { PasswordStrength } from '@open-mercato/ui/primitives/password-strength'
|
|
30
36
|
import { WebsiteInput } from '@open-mercato/ui/primitives/website-input'
|
|
31
37
|
import { AmountInput, type AmountValue } from '@open-mercato/ui/primitives/amount-input'
|
|
32
38
|
import { CounterInput } from '@open-mercato/ui/primitives/counter-input'
|
|
@@ -38,9 +44,15 @@ import {
|
|
|
38
44
|
COLOR_PICKER_DEFAULT_SWATCHES,
|
|
39
45
|
} from '@open-mercato/ui/primitives/color-picker'
|
|
40
46
|
import { TagInput } from '@open-mercato/ui/primitives/tag-input'
|
|
41
|
-
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
47
|
+
import { RichEditor, RichEditorColorPalette, RICH_EDITOR_COLOR_PALETTE, type RichEditorToolbarDesign, type RichEditorVariant, type RichEditorColorKey } from '@open-mercato/ui/primitives/rich-editor'
|
|
42
48
|
import { IconButton } from '@open-mercato/ui/primitives/icon-button'
|
|
49
|
+
import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
50
|
+
import { FileUploadAreaDemo, FileUploadCardDemo, ImageUploadDemo } from '../demos/file-upload'
|
|
51
|
+
import { SelectionSourceCardsDemo, IntegrationSwitchDemo } from '../demos/selection-cards'
|
|
52
|
+
import { SelectSourceExample, SelectSourceMatrix, DropdownSourceExample } from '../demos/menus'
|
|
53
|
+
import { SourceTextInputMatrix, SourcePhoneExamples, SourceTextareaExamples } from '../demos/text-inputs'
|
|
43
54
|
import type { GalleryEntry } from '../types'
|
|
55
|
+
import { inputFieldCode, textareaFieldCode, phoneNumberFieldCode, selectFieldCode, dropdownCode, fieldLabelCode, fieldLabelInformationCode, fieldLabelActionCode, formFieldLabelCode, hintTextCode } from './inputs-snippets'
|
|
44
56
|
|
|
45
57
|
// Component titles and variant names are proper nouns from the codebase and
|
|
46
58
|
// are deliberately not translated. `code` MUST contain the entry's importPath
|
|
@@ -54,7 +66,8 @@ import type { GalleryEntry } from '../types'
|
|
|
54
66
|
// ---------------------------------------------------------------------------
|
|
55
67
|
|
|
56
68
|
function DemoSearchInput({ size }: { size?: 'sm' | 'default' | 'lg' }) {
|
|
57
|
-
const
|
|
69
|
+
const t = useT()
|
|
70
|
+
const [value, setValue] = React.useState(() => t('design_system.gallery.sampleCopy.openOrders'))
|
|
58
71
|
return (
|
|
59
72
|
<div className="w-72">
|
|
60
73
|
<SearchInput value={value} onChange={setValue} size={size} />
|
|
@@ -71,6 +84,103 @@ function DemoAmountInput({ showCurrency }: { showCurrency?: boolean }) {
|
|
|
71
84
|
)
|
|
72
85
|
}
|
|
73
86
|
|
|
87
|
+
const selectionCardClasses = 'relative w-full max-w-90 gap-3.5 rounded-xl border border-border bg-background p-4 shadow-xs transition-colors hover:border-transparent hover:bg-muted hover:shadow-none has-[[data-state=checked]]:border-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus has-[:disabled]:border-border has-[:disabled]:bg-background has-[:disabled]:shadow-none [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-xl [&_button]:relative [&_button]:z-10'
|
|
88
|
+
|
|
89
|
+
function SelectionCardsPreview({ control, disabled = false }: { control: 'checkbox' | 'radio' | 'switch'; disabled?: boolean }) {
|
|
90
|
+
const t = useT()
|
|
91
|
+
const choices = [
|
|
92
|
+
{ value: 'immediate', label: t('design_system.gallery.samples.selection.immediate'), description: t('design_system.gallery.samples.selection.immediateDescription') },
|
|
93
|
+
{ value: 'weekly', label: t('design_system.gallery.samples.selection.weekly'), description: t('design_system.gallery.samples.selection.weeklyDescription') },
|
|
94
|
+
]
|
|
95
|
+
const cards = choices.map((choice, index) => {
|
|
96
|
+
const fieldProps = {
|
|
97
|
+
label: choice.label,
|
|
98
|
+
description: choice.description,
|
|
99
|
+
sublabel: t('design_system.gallery.samples.selection.optional'),
|
|
100
|
+
badge: <Badge variant={disabled ? 'outline' : 'info'} size="sm" className={disabled ? 'text-text-disabled' : undefined}>{t('design_system.gallery.samples.selection.new')}</Badge>,
|
|
101
|
+
disabled,
|
|
102
|
+
className: 'mt-0',
|
|
103
|
+
containerClassName: selectionCardClasses,
|
|
104
|
+
}
|
|
105
|
+
if (control === 'radio') return <RadioField key={choice.value} value={choice.value} flip {...fieldProps} />
|
|
106
|
+
if (control === 'switch') return <SwitchField key={choice.value} defaultChecked={index === 0} {...fieldProps} />
|
|
107
|
+
return <CheckboxField key={choice.value} defaultChecked={index === 0} flip {...fieldProps} />
|
|
108
|
+
})
|
|
109
|
+
if (control === 'radio') {
|
|
110
|
+
return <RadioGroup defaultValue="immediate" aria-label={t('design_system.gallery.samples.selection.preferences')} className="grid w-full gap-4 sm:grid-cols-2">{cards}</RadioGroup>
|
|
111
|
+
}
|
|
112
|
+
return <div className="grid w-full gap-4 sm:grid-cols-2">{cards}</div>
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function FlippedRadioPreview() {
|
|
116
|
+
const t = useT()
|
|
117
|
+
return (
|
|
118
|
+
<RadioGroup defaultValue="immediate" aria-label={t('design_system.gallery.samples.selection.preferences')} className="w-72">
|
|
119
|
+
<RadioField value="immediate" flip label={t('design_system.gallery.samples.selection.immediate')} />
|
|
120
|
+
<RadioField value="weekly" flip label={t('design_system.gallery.samples.selection.weekly')} />
|
|
121
|
+
</RadioGroup>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function ReadOnlyInputPreview() {
|
|
126
|
+
const t = useT()
|
|
127
|
+
return (
|
|
128
|
+
<FormField
|
|
129
|
+
className="w-full max-w-sm"
|
|
130
|
+
label={t('design_system.gallery.samples.states.recordId')}
|
|
131
|
+
description={t('design_system.gallery.samples.states.readOnlyHint')}
|
|
132
|
+
>
|
|
133
|
+
<Input readOnly value="OM-2026-0042" />
|
|
134
|
+
</FormField>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function ReadOnlyTextareaPreview() {
|
|
139
|
+
const t = useT()
|
|
140
|
+
return (
|
|
141
|
+
<FormField
|
|
142
|
+
className="w-full max-w-sm"
|
|
143
|
+
label={t('design_system.gallery.samples.states.savedNote')}
|
|
144
|
+
description={t('design_system.gallery.samples.states.readOnlyHint')}
|
|
145
|
+
>
|
|
146
|
+
<Textarea readOnly value={t('design_system.gallery.samples.states.noteValue')} />
|
|
147
|
+
</FormField>
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function DisabledSearchInputPreview() {
|
|
152
|
+
const t = useT()
|
|
153
|
+
const [query, setQuery] = React.useState('OM-2026-0042')
|
|
154
|
+
return (
|
|
155
|
+
<FormField className="w-full max-w-sm" label={t('design_system.gallery.samples.states.search')} disabled>
|
|
156
|
+
<SearchInput value={query} onChange={setQuery} />
|
|
157
|
+
</FormField>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function InvalidPasswordInputPreview() {
|
|
162
|
+
const t = useT()
|
|
163
|
+
return (
|
|
164
|
+
<FormField
|
|
165
|
+
className="w-full max-w-sm"
|
|
166
|
+
label={t('design_system.gallery.samples.states.password')}
|
|
167
|
+
error={t('design_system.gallery.samples.states.passwordError')}
|
|
168
|
+
>
|
|
169
|
+
<PasswordInput defaultValue="short" autoComplete="off" />
|
|
170
|
+
</FormField>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function DisabledAmountInputPreview() {
|
|
175
|
+
const t = useT()
|
|
176
|
+
const [value, setValue] = React.useState<AmountValue>({ amount: '1250.00', currency: 'EUR' })
|
|
177
|
+
return (
|
|
178
|
+
<FormField className="w-full max-w-sm" label={t('design_system.gallery.samples.states.amount')} disabled>
|
|
179
|
+
<AmountInput value={value} onChange={setValue} />
|
|
180
|
+
</FormField>
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
74
184
|
function DemoCounterInput({
|
|
75
185
|
initial = 2,
|
|
76
186
|
step,
|
|
@@ -111,18 +221,25 @@ function DemoCardInput({ initial = '' }: { initial?: string }) {
|
|
|
111
221
|
function DemoColorPicker({
|
|
112
222
|
allowCustom,
|
|
113
223
|
swatches,
|
|
224
|
+
showOpacity = false,
|
|
114
225
|
}: {
|
|
115
226
|
allowCustom?: boolean
|
|
116
227
|
swatches?: readonly string[]
|
|
228
|
+
showOpacity?: boolean
|
|
117
229
|
}) {
|
|
230
|
+
const t = useT()
|
|
118
231
|
const [color, setColor] = React.useState('#6366F1')
|
|
232
|
+
const [opacity, setOpacity] = React.useState(75)
|
|
119
233
|
return (
|
|
120
234
|
<ColorPicker
|
|
121
235
|
value={color}
|
|
122
236
|
onChange={setColor}
|
|
123
237
|
allowCustom={allowCustom}
|
|
124
238
|
swatches={swatches}
|
|
125
|
-
|
|
239
|
+
showOpacity={showOpacity}
|
|
240
|
+
opacity={showOpacity ? opacity : 100}
|
|
241
|
+
onOpacityChange={showOpacity ? setOpacity : undefined}
|
|
242
|
+
aria-label={t('design_system.gallery.sampleCopy.pickColor')}
|
|
126
243
|
/>
|
|
127
244
|
)
|
|
128
245
|
}
|
|
@@ -144,17 +261,68 @@ function DemoTagInput({
|
|
|
144
261
|
)
|
|
145
262
|
}
|
|
146
263
|
|
|
147
|
-
function DemoRichEditor({ variant }: { variant
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
)
|
|
264
|
+
function DemoRichEditor({ variant = 'standard', toolbarDesign, disabled = false, counter = false }: { variant?: RichEditorVariant; toolbarDesign?: RichEditorToolbarDesign; disabled?: boolean; counter?: boolean }) {
|
|
265
|
+
const t = useT()
|
|
266
|
+
const [html, setHtml] = React.useState(() => '<p>' + t('design_system.gallery.samples.richEditor.initial') + '</p>')
|
|
267
|
+
const [feedback, setFeedback] = React.useState('')
|
|
268
|
+
const labels = {
|
|
269
|
+
bold: t('design_system.gallery.samples.richEditor.labels.bold'),
|
|
270
|
+
italic: t('design_system.gallery.samples.richEditor.labels.italic'),
|
|
271
|
+
underline: t('design_system.gallery.samples.richEditor.labels.underline'),
|
|
272
|
+
strikethrough: t('design_system.gallery.samples.richEditor.labels.strikethrough'),
|
|
273
|
+
unorderedList: t('design_system.gallery.samples.richEditor.labels.unorderedList'),
|
|
274
|
+
orderedList: t('design_system.gallery.samples.richEditor.labels.orderedList'),
|
|
275
|
+
checklist: t('design_system.gallery.samples.richEditor.labels.checklist'),
|
|
276
|
+
blockquote: t('design_system.gallery.samples.richEditor.labels.blockquote'),
|
|
277
|
+
code: t('design_system.gallery.samples.richEditor.labels.code'),
|
|
278
|
+
inlineCode: t('design_system.gallery.samples.richEditor.labels.inlineCode'),
|
|
279
|
+
codeBlock: t('design_system.gallery.samples.richEditor.labels.codeBlock'),
|
|
280
|
+
horizontalRule: t('design_system.gallery.samples.richEditor.labels.horizontalRule'),
|
|
281
|
+
image: t('design_system.gallery.samples.richEditor.labels.image'),
|
|
282
|
+
imageUrlPrompt: t('design_system.gallery.samples.richEditor.labels.imageUrlPrompt'),
|
|
283
|
+
table: t('design_system.gallery.samples.richEditor.labels.table'),
|
|
284
|
+
heading: t('design_system.gallery.samples.richEditor.labels.heading'),
|
|
285
|
+
heading1: t('design_system.gallery.samples.richEditor.labels.heading1'),
|
|
286
|
+
heading2: t('design_system.gallery.samples.richEditor.labels.heading2'),
|
|
287
|
+
heading3: t('design_system.gallery.samples.richEditor.labels.heading3'),
|
|
288
|
+
paragraph: t('design_system.gallery.samples.richEditor.labels.paragraph'),
|
|
289
|
+
link: t('design_system.gallery.samples.richEditor.labels.link'),
|
|
290
|
+
linkUrlPrompt: t('design_system.gallery.samples.richEditor.labels.linkUrlPrompt'),
|
|
291
|
+
color: t('design_system.gallery.samples.richEditor.labels.color'),
|
|
292
|
+
textColor: t('design_system.gallery.samples.richEditor.labels.textColor'),
|
|
293
|
+
fontSize: t('design_system.gallery.samples.richEditor.labels.fontSize'),
|
|
294
|
+
align: t('design_system.gallery.samples.richEditor.labels.align'),
|
|
295
|
+
alignLeft: t('design_system.gallery.samples.richEditor.labels.alignLeft'),
|
|
296
|
+
alignCenter: t('design_system.gallery.samples.richEditor.labels.alignCenter'),
|
|
297
|
+
alignRight: t('design_system.gallery.samples.richEditor.labels.alignRight'),
|
|
298
|
+
alignJustify: t('design_system.gallery.samples.richEditor.labels.alignJustify'),
|
|
299
|
+
comment: t('design_system.gallery.samples.richEditor.labels.comment'),
|
|
300
|
+
mention: t('design_system.gallery.samples.richEditor.labels.mention'),
|
|
301
|
+
more: t('design_system.gallery.samples.richEditor.labels.more'),
|
|
302
|
+
help: t('design_system.gallery.samples.richEditor.labels.help'),
|
|
303
|
+
fullscreen: t('design_system.gallery.samples.richEditor.labels.fullscreen'),
|
|
304
|
+
placeholder: t('design_system.gallery.samples.richEditor.labels.placeholder'),
|
|
305
|
+
colors: Object.fromEntries(Object.keys(RICH_EDITOR_COLOR_PALETTE).map(key => [key, t(`design_system.gallery.samples.richEditor.colors.${key}`)])) as Record<RichEditorColorKey, string>,
|
|
306
|
+
}
|
|
151
307
|
return (
|
|
152
|
-
<div className="w-full max-w-
|
|
153
|
-
<RichEditor value={html} onChange={setHtml} variant={variant}
|
|
308
|
+
<div className="flex min-w-0 w-full max-w-3xl flex-col gap-3">
|
|
309
|
+
<RichEditor value={html} onChange={setHtml} variant={variant} toolbarDesign={toolbarDesign} disabled={disabled} maxLength={counter ? 100 : undefined} labels={labels}
|
|
310
|
+
onComment={() => setFeedback(t('design_system.gallery.samples.richEditor.comment'))}
|
|
311
|
+
onMention={() => setFeedback(t('design_system.gallery.samples.richEditor.mention'))} />
|
|
312
|
+
{feedback && <output aria-live="polite" className="text-sm text-muted-foreground">{feedback}</output>}
|
|
154
313
|
</div>
|
|
155
314
|
)
|
|
156
315
|
}
|
|
157
316
|
|
|
317
|
+
function DemoRichEditorPalette() {
|
|
318
|
+
const t = useT()
|
|
319
|
+
const [value, setValue] = React.useState<RichEditorColorKey | null>('gray')
|
|
320
|
+
const labels = Object.fromEntries(Object.keys(RICH_EDITOR_COLOR_PALETTE).map(key => [key, t(`design_system.gallery.samples.richEditor.colors.${key}`)])) as Record<RichEditorColorKey, string>
|
|
321
|
+
return <div className="flex w-full max-w-sm flex-col gap-3"><RichEditorColorPalette value={value} onChange={setValue} labels={labels} />
|
|
322
|
+
<output aria-live="polite" className="text-sm text-muted-foreground">{value ? labels[value] : ''}</output>
|
|
323
|
+
</div>
|
|
324
|
+
}
|
|
325
|
+
|
|
158
326
|
// ---------------------------------------------------------------------------
|
|
159
327
|
// Entries
|
|
160
328
|
// ---------------------------------------------------------------------------
|
|
@@ -163,15 +331,13 @@ const inputEntry: GalleryEntry = {
|
|
|
163
331
|
id: 'input',
|
|
164
332
|
title: 'Input',
|
|
165
333
|
importPath: '@open-mercato/ui/primitives/input',
|
|
334
|
+
figmaNodeId: '266:5251',
|
|
335
|
+
usage: { do: ['Numeric sizes 32, 36 and 40 use the source 14/20 text, 20 px icons and asymmetric input padding. Named sizes preserve existing callers.', 'leading and trailing accept interactive controls; provide accessible labels and forward disabled to those controls. leftIcon/rightIcon remain decorative.', 'The source compositions cover all twelve Text Input types. Hover and focus are real browser states; the Date example uses the native date picker and locale formatting. Existing CardInput brand badges and phone parsing retain their runtime behavior.'] },
|
|
166
336
|
variants: [
|
|
167
337
|
{
|
|
168
338
|
id: 'default',
|
|
169
339
|
title: 'default',
|
|
170
|
-
render: () =>
|
|
171
|
-
<div className="w-72">
|
|
172
|
-
<Input placeholder="Product name" />
|
|
173
|
-
</div>
|
|
174
|
-
),
|
|
340
|
+
render: () => <InputInputsDefaultSample />,
|
|
175
341
|
code: `import { Input } from '@open-mercato/ui/primitives/input'
|
|
176
342
|
|
|
177
343
|
<Input placeholder="Product name" />`,
|
|
@@ -179,16 +345,7 @@ const inputEntry: GalleryEntry = {
|
|
|
179
345
|
{
|
|
180
346
|
id: 'icon-slots',
|
|
181
347
|
title: 'Icon slots',
|
|
182
|
-
render: () =>
|
|
183
|
-
<>
|
|
184
|
-
<div className="w-56">
|
|
185
|
-
<Input leftIcon={<User />} placeholder="Assignee" />
|
|
186
|
-
</div>
|
|
187
|
-
<div className="w-56">
|
|
188
|
-
<Input rightIcon={<Info />} placeholder="SKU" />
|
|
189
|
-
</div>
|
|
190
|
-
</>
|
|
191
|
-
),
|
|
348
|
+
render: () => <InputInputsIconSlotsSample />,
|
|
192
349
|
code: `import { Info, User } from 'lucide-react'
|
|
193
350
|
import { Input } from '@open-mercato/ui/primitives/input'
|
|
194
351
|
|
|
@@ -198,19 +355,7 @@ import { Input } from '@open-mercato/ui/primitives/input'
|
|
|
198
355
|
{
|
|
199
356
|
id: 'sizes',
|
|
200
357
|
title: 'Sizes',
|
|
201
|
-
render: () =>
|
|
202
|
-
<>
|
|
203
|
-
<div className="w-44">
|
|
204
|
-
<Input size="lg" placeholder="Large" />
|
|
205
|
-
</div>
|
|
206
|
-
<div className="w-44">
|
|
207
|
-
<Input size="default" placeholder="Default" />
|
|
208
|
-
</div>
|
|
209
|
-
<div className="w-44">
|
|
210
|
-
<Input size="sm" placeholder="Small" />
|
|
211
|
-
</div>
|
|
212
|
-
</>
|
|
213
|
-
),
|
|
358
|
+
render: () => <InputInputsSizesSample />,
|
|
214
359
|
code: `import { Input } from '@open-mercato/ui/primitives/input'
|
|
215
360
|
|
|
216
361
|
<Input size="lg" placeholder="Large" />
|
|
@@ -220,37 +365,43 @@ import { Input } from '@open-mercato/ui/primitives/input'
|
|
|
220
365
|
{
|
|
221
366
|
id: 'states',
|
|
222
367
|
title: 'States',
|
|
223
|
-
render: () =>
|
|
224
|
-
<>
|
|
225
|
-
<div className="w-56">
|
|
226
|
-
<Input aria-invalid defaultValue="not-a-number" />
|
|
227
|
-
</div>
|
|
228
|
-
<div className="w-56">
|
|
229
|
-
<Input disabled placeholder="Disabled" />
|
|
230
|
-
</div>
|
|
231
|
-
</>
|
|
232
|
-
),
|
|
368
|
+
render: () => <InputInputsStatesSample />,
|
|
233
369
|
code: `import { Input } from '@open-mercato/ui/primitives/input'
|
|
234
370
|
|
|
235
371
|
<Input aria-invalid defaultValue="not-a-number" />
|
|
236
372
|
<Input disabled placeholder="Disabled" />`,
|
|
237
373
|
},
|
|
374
|
+
{
|
|
375
|
+
id: 'read-only',
|
|
376
|
+
title: 'Read-only',
|
|
377
|
+
render: () => <ReadOnlyInputPreview />,
|
|
378
|
+
code: `import { Input } from '@open-mercato/ui/primitives/input'
|
|
379
|
+
import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
380
|
+
|
|
381
|
+
<FormField label="Record ID" description="Read-only content stays focusable and can be selected and copied.">
|
|
382
|
+
<Input readOnly value="OM-2026-0042" />
|
|
383
|
+
</FormField>`,
|
|
384
|
+
},
|
|
385
|
+
{ id: 'source-32', title: 'Source / all twelve types / 32 px', render: () => <SourceTextInputMatrix size={32} />, code: inputFieldCode({ inputProps: ' size={32}' }) },
|
|
386
|
+
{ id: 'source-36', title: 'Source / all twelve types / 36 px', render: () => <SourceTextInputMatrix size={36} />, code: inputFieldCode({ inputProps: ' size={36}' }) },
|
|
387
|
+
{ id: 'source-40', title: 'Source / all twelve types / 40 px', render: () => <SourceTextInputMatrix size={40} />, code: inputFieldCode({ inputProps: ' size={40}' }) },
|
|
388
|
+
{ id: 'source-placeholder', title: 'Source / placeholder', render: () => <SourceTextInputMatrix state="placeholder" />, code: inputFieldCode() },
|
|
389
|
+
{ id: 'source-error', title: 'Source / error', render: () => <SourceTextInputMatrix state="error" />, code: inputFieldCode({ inputProps: ' aria-invalid', fieldProps: ' error="Enter your full name"' }) },
|
|
390
|
+
{ id: 'source-disabled', title: 'Source / disabled', render: () => <SourceTextInputMatrix state="disabled" />, code: inputFieldCode({ inputProps: ' disabled', fieldProps: ' disabled' }) },
|
|
238
391
|
],
|
|
239
392
|
}
|
|
240
393
|
|
|
241
394
|
const textareaEntry: GalleryEntry = {
|
|
242
395
|
id: 'textarea',
|
|
243
396
|
title: 'Textarea',
|
|
397
|
+
figmaNodeId: '435:5725',
|
|
398
|
+
usage: { do: ['appearance=source adds the source 112 px minimum field, 12 px radius, 14/20 text and an interior character counter. The browser-native resize handle remains operable.', 'The default appearance and external counter retain their current layout. Set maxLength together with showCount and supply a visible field label.'] },
|
|
244
399
|
importPath: '@open-mercato/ui/primitives/textarea',
|
|
245
400
|
variants: [
|
|
246
401
|
{
|
|
247
402
|
id: 'default',
|
|
248
403
|
title: 'default',
|
|
249
|
-
render: () =>
|
|
250
|
-
<div className="w-80">
|
|
251
|
-
<Textarea placeholder="Internal note for the fulfillment team" />
|
|
252
|
-
</div>
|
|
253
|
-
),
|
|
404
|
+
render: () => <TextareaInputsDefaultSample />,
|
|
254
405
|
code: `import { Textarea } from '@open-mercato/ui/primitives/textarea'
|
|
255
406
|
|
|
256
407
|
<Textarea placeholder="Internal note for the fulfillment team" />`,
|
|
@@ -258,15 +409,7 @@ const textareaEntry: GalleryEntry = {
|
|
|
258
409
|
{
|
|
259
410
|
id: 'character-count',
|
|
260
411
|
title: 'Character counter',
|
|
261
|
-
render: () =>
|
|
262
|
-
<div className="w-80">
|
|
263
|
-
<Textarea
|
|
264
|
-
showCount
|
|
265
|
-
maxLength={200}
|
|
266
|
-
defaultValue="Customer prefers delivery after 4 PM."
|
|
267
|
-
/>
|
|
268
|
-
</div>
|
|
269
|
-
),
|
|
412
|
+
render: () => <TextareaInputsCharacterCountSample />,
|
|
270
413
|
code: `import { Textarea } from '@open-mercato/ui/primitives/textarea'
|
|
271
414
|
|
|
272
415
|
<Textarea showCount maxLength={200} defaultValue="Customer prefers delivery after 4 PM." />`,
|
|
@@ -274,183 +417,77 @@ const textareaEntry: GalleryEntry = {
|
|
|
274
417
|
{
|
|
275
418
|
id: 'states',
|
|
276
419
|
title: 'States',
|
|
277
|
-
render: () =>
|
|
278
|
-
<>
|
|
279
|
-
<div className="w-72">
|
|
280
|
-
<Textarea aria-invalid defaultValue="Too short" />
|
|
281
|
-
</div>
|
|
282
|
-
<div className="w-72">
|
|
283
|
-
<Textarea disabled placeholder="Disabled" />
|
|
284
|
-
</div>
|
|
285
|
-
</>
|
|
286
|
-
),
|
|
420
|
+
render: () => <TextareaInputsStatesSample />,
|
|
287
421
|
code: `import { Textarea } from '@open-mercato/ui/primitives/textarea'
|
|
288
422
|
|
|
289
423
|
<Textarea aria-invalid defaultValue="Too short" />
|
|
290
424
|
<Textarea disabled placeholder="Disabled" />`,
|
|
291
425
|
},
|
|
426
|
+
{
|
|
427
|
+
id: 'read-only',
|
|
428
|
+
title: 'Read-only',
|
|
429
|
+
render: () => <ReadOnlyTextareaPreview />,
|
|
430
|
+
code: `import { Textarea } from '@open-mercato/ui/primitives/textarea'
|
|
431
|
+
import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
432
|
+
|
|
433
|
+
<FormField label="Saved note" description="Read-only content stays focusable and can be selected and copied.">
|
|
434
|
+
<Textarea readOnly value="Customer requested delivery after 4 PM." />
|
|
435
|
+
</FormField>`,
|
|
436
|
+
},
|
|
437
|
+
{ id: 'source-states', title: 'Source / default, filled, error and disabled', render: () => <SourceTextareaExamples />, code: textareaFieldCode },
|
|
438
|
+
],
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const phoneNumberEntry: GalleryEntry = {
|
|
442
|
+
id: 'phone-number-field',
|
|
443
|
+
title: 'PhoneNumberField',
|
|
444
|
+
importPath: '@open-mercato/ui/backend/inputs/PhoneNumberField',
|
|
445
|
+
figmaNodeId: '313:10101',
|
|
446
|
+
usage: { do: ['Numeric sizes 32/36/40 add source geometry while the existing automatic height remains the default.', 'Choose a country or edit the national number to update the local value. Validation and optional duplicate lookup retain their existing contracts.', 'countries translates and limits picker choices; countryLabel names the picker and renderCountryIcon can supply actual country assets.'] },
|
|
447
|
+
variants: [
|
|
448
|
+
{ id: 'sizes', title: 'Source / 32, 36 and 40 px', render: () => <SourcePhoneExamples />, code: phoneNumberFieldCode() },
|
|
449
|
+
{ id: 'placeholder', title: 'Source / placeholder', render: () => <SourcePhoneExamples state="placeholder" />, code: phoneNumberFieldCode() },
|
|
450
|
+
{ id: 'validation', title: 'Source / validation', render: () => <SourcePhoneExamples state="error" />, code: phoneNumberFieldCode(' externalError="Enter a valid phone number"') },
|
|
451
|
+
{ id: 'disabled', title: 'Source / disabled', render: () => <SourcePhoneExamples state="disabled" />, code: phoneNumberFieldCode(' disabled') },
|
|
292
452
|
],
|
|
293
453
|
}
|
|
294
454
|
|
|
295
455
|
const selectEntry: GalleryEntry = {
|
|
296
456
|
id: 'select',
|
|
457
|
+
figmaNodeId: '270:1085',
|
|
297
458
|
title: 'Select',
|
|
298
459
|
importPath: '@open-mercato/ui/primitives/select',
|
|
460
|
+
usage: { do: [
|
|
461
|
+
'Six source leading types: Basic, Country, Avatar, Provider, Brand, and Company. The 32/36/40 numeric sizes use the measured source text, icons, padding and radii; named sizes retain their existing defaults.',
|
|
462
|
+
'SelectItem leading keeps the visual outside Radix ItemText. The trigger renders its selected visual explicitly, so a selection never duplicates the icon.',
|
|
463
|
+
'Use Dropdown for searchable choices. Select keeps Radix keyboard typeahead; search inputs must not be nested in a Select listbox.',
|
|
464
|
+
] },
|
|
299
465
|
variants: [
|
|
300
|
-
{
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
<SelectContent>
|
|
310
|
-
<SelectItem value="eur">Euro (EUR)</SelectItem>
|
|
311
|
-
<SelectItem value="pln">Polish Złoty (PLN)</SelectItem>
|
|
312
|
-
<SelectItem value="usd">US Dollar (USD)</SelectItem>
|
|
313
|
-
</SelectContent>
|
|
314
|
-
</Select>
|
|
315
|
-
</div>
|
|
316
|
-
),
|
|
317
|
-
code: `import {
|
|
318
|
-
Select,
|
|
319
|
-
SelectContent,
|
|
320
|
-
SelectItem,
|
|
321
|
-
SelectTrigger,
|
|
322
|
-
SelectValue,
|
|
323
|
-
} from '@open-mercato/ui/primitives/select'
|
|
324
|
-
|
|
325
|
-
<Select defaultValue="pln">
|
|
326
|
-
<SelectTrigger>
|
|
327
|
-
<SelectValue placeholder="Choose currency" />
|
|
328
|
-
</SelectTrigger>
|
|
329
|
-
<SelectContent>
|
|
330
|
-
<SelectItem value="eur">Euro (EUR)</SelectItem>
|
|
331
|
-
<SelectItem value="pln">Polish Złoty (PLN)</SelectItem>
|
|
332
|
-
<SelectItem value="usd">US Dollar (USD)</SelectItem>
|
|
333
|
-
</SelectContent>
|
|
334
|
-
</Select>`,
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
id: 'groups-leading',
|
|
338
|
-
title: 'Groups + leading slot',
|
|
339
|
-
render: () => (
|
|
340
|
-
<div className="w-56">
|
|
341
|
-
<Select>
|
|
342
|
-
<SelectTrigger>
|
|
343
|
-
<SelectTriggerLeading>
|
|
344
|
-
<Globe />
|
|
345
|
-
</SelectTriggerLeading>
|
|
346
|
-
<SelectValue placeholder="Sales channel" />
|
|
347
|
-
</SelectTrigger>
|
|
348
|
-
<SelectContent>
|
|
349
|
-
<SelectGroup>
|
|
350
|
-
<SelectLabel>Online</SelectLabel>
|
|
351
|
-
<SelectItem value="webstore">Webstore</SelectItem>
|
|
352
|
-
<SelectItem value="marketplace">Marketplace</SelectItem>
|
|
353
|
-
</SelectGroup>
|
|
354
|
-
<SelectSeparator />
|
|
355
|
-
<SelectGroup>
|
|
356
|
-
<SelectLabel>Offline</SelectLabel>
|
|
357
|
-
<SelectItem value="retail">Retail store</SelectItem>
|
|
358
|
-
</SelectGroup>
|
|
359
|
-
</SelectContent>
|
|
360
|
-
</Select>
|
|
361
|
-
</div>
|
|
362
|
-
),
|
|
363
|
-
code: `import { Globe } from 'lucide-react'
|
|
364
|
-
import {
|
|
365
|
-
Select,
|
|
366
|
-
SelectContent,
|
|
367
|
-
SelectGroup,
|
|
368
|
-
SelectItem,
|
|
369
|
-
SelectLabel,
|
|
370
|
-
SelectSeparator,
|
|
371
|
-
SelectTrigger,
|
|
372
|
-
SelectTriggerLeading,
|
|
373
|
-
SelectValue,
|
|
374
|
-
} from '@open-mercato/ui/primitives/select'
|
|
375
|
-
|
|
376
|
-
<Select>
|
|
377
|
-
<SelectTrigger>
|
|
378
|
-
<SelectTriggerLeading><Globe /></SelectTriggerLeading>
|
|
379
|
-
<SelectValue placeholder="Sales channel" />
|
|
380
|
-
</SelectTrigger>
|
|
381
|
-
<SelectContent>
|
|
382
|
-
<SelectGroup>
|
|
383
|
-
<SelectLabel>Online</SelectLabel>
|
|
384
|
-
<SelectItem value="webstore">Webstore</SelectItem>
|
|
385
|
-
<SelectItem value="marketplace">Marketplace</SelectItem>
|
|
386
|
-
</SelectGroup>
|
|
387
|
-
<SelectSeparator />
|
|
388
|
-
<SelectGroup>
|
|
389
|
-
<SelectLabel>Offline</SelectLabel>
|
|
390
|
-
<SelectItem value="retail">Retail store</SelectItem>
|
|
391
|
-
</SelectGroup>
|
|
392
|
-
</SelectContent>
|
|
393
|
-
</Select>`,
|
|
394
|
-
},
|
|
395
|
-
{
|
|
396
|
-
id: 'sizes',
|
|
397
|
-
title: 'Sizes',
|
|
398
|
-
render: () => (
|
|
399
|
-
<>
|
|
400
|
-
{(['lg', 'default', 'sm', 'xs'] as const).map((size) => (
|
|
401
|
-
<div key={size} className="w-40">
|
|
402
|
-
<Select defaultValue="active">
|
|
403
|
-
<SelectTrigger size={size}>
|
|
404
|
-
<SelectValue />
|
|
405
|
-
</SelectTrigger>
|
|
406
|
-
<SelectContent>
|
|
407
|
-
<SelectItem value="active">Active</SelectItem>
|
|
408
|
-
<SelectItem value="archived">Archived</SelectItem>
|
|
409
|
-
</SelectContent>
|
|
410
|
-
</Select>
|
|
411
|
-
</div>
|
|
412
|
-
))}
|
|
413
|
-
</>
|
|
414
|
-
),
|
|
415
|
-
code: `import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@open-mercato/ui/primitives/select'
|
|
416
|
-
|
|
417
|
-
<SelectTrigger size="lg" />
|
|
418
|
-
<SelectTrigger size="default" />
|
|
419
|
-
<SelectTrigger size="sm" />
|
|
420
|
-
<SelectTrigger size="xs" />`,
|
|
421
|
-
},
|
|
422
|
-
{
|
|
423
|
-
id: 'states',
|
|
424
|
-
title: 'States',
|
|
425
|
-
render: () => (
|
|
426
|
-
<>
|
|
427
|
-
<div className="w-48">
|
|
428
|
-
<Select>
|
|
429
|
-
<SelectTrigger aria-invalid="true">
|
|
430
|
-
<SelectValue placeholder="Required" />
|
|
431
|
-
</SelectTrigger>
|
|
432
|
-
<SelectContent>
|
|
433
|
-
<SelectItem value="a">Option A</SelectItem>
|
|
434
|
-
</SelectContent>
|
|
435
|
-
</Select>
|
|
436
|
-
</div>
|
|
437
|
-
<div className="w-48">
|
|
438
|
-
<Select>
|
|
439
|
-
<SelectTrigger disabled>
|
|
440
|
-
<SelectValue placeholder="Disabled" />
|
|
441
|
-
</SelectTrigger>
|
|
442
|
-
<SelectContent>
|
|
443
|
-
<SelectItem value="a">Option A</SelectItem>
|
|
444
|
-
</SelectContent>
|
|
445
|
-
</Select>
|
|
446
|
-
</div>
|
|
447
|
-
</>
|
|
448
|
-
),
|
|
449
|
-
code: `import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@open-mercato/ui/primitives/select'
|
|
466
|
+
{ id: 'default', title: 'Basic / 36 px', render: () => <div className="w-72 max-w-full"><SelectSourceExample kind="basic" /></div>, code: selectFieldCode() },
|
|
467
|
+
{ id: 'groups-leading', title: 'All six leading types / 36 px', render: () => <SelectSourceMatrix />, code: selectFieldCode({ leading: true }) },
|
|
468
|
+
{ id: 'sizes', title: 'All types / 32 px', render: () => <SelectSourceMatrix size={32} />, code: selectFieldCode({ size: 32, leading: true }) },
|
|
469
|
+
{ id: 'medium', title: 'All types / 40 px', render: () => <SelectSourceMatrix size={40} />, code: selectFieldCode({ size: 40, leading: true }) },
|
|
470
|
+
{ id: 'placeholder', title: 'All types / placeholders', render: () => <SelectSourceMatrix state="default" />, code: selectFieldCode({ leading: true, initialValue: '' }) },
|
|
471
|
+
{ id: 'states', title: 'All types / disabled', render: () => <SelectSourceMatrix state="disabled" />, code: selectFieldCode({ leading: true, selectProps: ' disabled', fieldProps: ' disabled' }) },
|
|
472
|
+
{ id: 'errors', title: 'All types / errors', render: () => <SelectSourceMatrix state="error" />, code: selectFieldCode({ leading: true, initialValue: '', fieldProps: ' error="Choose an office"' }) },
|
|
473
|
+
],
|
|
474
|
+
}
|
|
450
475
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
476
|
+
const dropdownEntry: GalleryEntry = {
|
|
477
|
+
id: 'dropdown',
|
|
478
|
+
figmaNodeId: '379:6629',
|
|
479
|
+
title: 'Dropdown',
|
|
480
|
+
importPath: '@open-mercato/ui/primitives/dropdown',
|
|
481
|
+
descriptionKey: 'design_system.entries.dropdown.description',
|
|
482
|
+
usage: { do: [
|
|
483
|
+
'A searchable, keyboard-operated picker built from Popover and cmdk. All six leading types use source assets and production components at 36 or 56 px.',
|
|
484
|
+
'Search, clear, choose with arrows and Enter, or dismiss with Escape. The selected value and footer action update local example state.',
|
|
485
|
+
'The saved checked state is separate from the active keyboard option. Footer buttons remain outside listbox options. Source Misc Items 414:8031 supplies search, action and caption layouts.',
|
|
486
|
+
] },
|
|
487
|
+
variants: [
|
|
488
|
+
{ id: 'small', title: 'All six types / 36 px', render: () => <DropdownSourceExample />, code: dropdownCode() },
|
|
489
|
+
{ id: 'large', title: 'All six types / 56 px', render: () => <DropdownSourceExample size={56} />, code: dropdownCode({ size: 56 }) },
|
|
490
|
+
{ id: 'empty', title: 'No results / clear to recover', render: () => <DropdownSourceExample empty />, code: dropdownCode({ initialQuery: 'zzzz' }) },
|
|
454
491
|
],
|
|
455
492
|
}
|
|
456
493
|
|
|
@@ -462,20 +499,7 @@ const compactSelectEntry: GalleryEntry = {
|
|
|
462
499
|
{
|
|
463
500
|
id: 'trigger-label',
|
|
464
501
|
title: 'With trigger label',
|
|
465
|
-
render: () =>
|
|
466
|
-
<div className="w-44">
|
|
467
|
-
<Select defaultValue="newest">
|
|
468
|
-
<CompactSelectTrigger triggerLabel="Sort:">
|
|
469
|
-
<SelectValue />
|
|
470
|
-
</CompactSelectTrigger>
|
|
471
|
-
<SelectContent>
|
|
472
|
-
<SelectItem value="newest">Newest</SelectItem>
|
|
473
|
-
<SelectItem value="oldest">Oldest</SelectItem>
|
|
474
|
-
<SelectItem value="value">Highest value</SelectItem>
|
|
475
|
-
</SelectContent>
|
|
476
|
-
</Select>
|
|
477
|
-
</div>
|
|
478
|
-
),
|
|
502
|
+
render: () => <CompactSelectInputsTriggerLabelSample />,
|
|
479
503
|
code: `import {
|
|
480
504
|
CompactSelectTrigger,
|
|
481
505
|
Select,
|
|
@@ -498,19 +522,7 @@ const compactSelectEntry: GalleryEntry = {
|
|
|
498
522
|
{
|
|
499
523
|
id: 'plain',
|
|
500
524
|
title: 'Without label',
|
|
501
|
-
render: () =>
|
|
502
|
-
<div className="w-36">
|
|
503
|
-
<Select defaultValue="table">
|
|
504
|
-
<CompactSelectTrigger>
|
|
505
|
-
<SelectValue />
|
|
506
|
-
</CompactSelectTrigger>
|
|
507
|
-
<SelectContent>
|
|
508
|
-
<SelectItem value="table">Table</SelectItem>
|
|
509
|
-
<SelectItem value="board">Board</SelectItem>
|
|
510
|
-
</SelectContent>
|
|
511
|
-
</Select>
|
|
512
|
-
</div>
|
|
513
|
-
),
|
|
525
|
+
render: () => <CompactSelectInputsPlainSample />,
|
|
514
526
|
code: `import {
|
|
515
527
|
CompactSelectTrigger,
|
|
516
528
|
Select,
|
|
@@ -540,20 +552,7 @@ const inlineSelectEntry: GalleryEntry = {
|
|
|
540
552
|
{
|
|
541
553
|
id: 'default',
|
|
542
554
|
title: 'default (border on hover)',
|
|
543
|
-
render: () =>
|
|
544
|
-
<div className="w-40">
|
|
545
|
-
<Select defaultValue="high">
|
|
546
|
-
<InlineSelectTrigger>
|
|
547
|
-
<SelectValue />
|
|
548
|
-
</InlineSelectTrigger>
|
|
549
|
-
<SelectContent>
|
|
550
|
-
<SelectItem value="low">Low</SelectItem>
|
|
551
|
-
<SelectItem value="medium">Medium</SelectItem>
|
|
552
|
-
<SelectItem value="high">High</SelectItem>
|
|
553
|
-
</SelectContent>
|
|
554
|
-
</Select>
|
|
555
|
-
</div>
|
|
556
|
-
),
|
|
555
|
+
render: () => <InlineSelectInputsDefaultSample />,
|
|
557
556
|
code: `import {
|
|
558
557
|
InlineSelectTrigger,
|
|
559
558
|
Select,
|
|
@@ -576,19 +575,7 @@ const inlineSelectEntry: GalleryEntry = {
|
|
|
576
575
|
{
|
|
577
576
|
id: 'invisible',
|
|
578
577
|
title: 'Invisible until focus',
|
|
579
|
-
render: () =>
|
|
580
|
-
<div className="w-40">
|
|
581
|
-
<Select defaultValue="draft">
|
|
582
|
-
<InlineSelectTrigger showBorderOnHover={false}>
|
|
583
|
-
<SelectValue />
|
|
584
|
-
</InlineSelectTrigger>
|
|
585
|
-
<SelectContent>
|
|
586
|
-
<SelectItem value="draft">Draft</SelectItem>
|
|
587
|
-
<SelectItem value="published">Published</SelectItem>
|
|
588
|
-
</SelectContent>
|
|
589
|
-
</Select>
|
|
590
|
-
</div>
|
|
591
|
-
),
|
|
578
|
+
render: () => <InlineSelectInputsInvisibleSample />,
|
|
592
579
|
code: `import {
|
|
593
580
|
InlineSelectTrigger,
|
|
594
581
|
Select,
|
|
@@ -612,11 +599,7 @@ const inlineInputEntry: GalleryEntry = {
|
|
|
612
599
|
{
|
|
613
600
|
id: 'default',
|
|
614
601
|
title: 'default (border on hover)',
|
|
615
|
-
render: () =>
|
|
616
|
-
<div className="w-56">
|
|
617
|
-
<InlineInput defaultValue="Aurora desk lamp" aria-label="Product name" />
|
|
618
|
-
</div>
|
|
619
|
-
),
|
|
602
|
+
render: () => <InlineInputInputsDefaultSample />,
|
|
620
603
|
code: `import { InlineInput } from '@open-mercato/ui/primitives/inline-input'
|
|
621
604
|
|
|
622
605
|
<InlineInput defaultValue="Aurora desk lamp" aria-label="Product name" onBlur={save} />`,
|
|
@@ -648,13 +631,7 @@ const checkboxEntry: GalleryEntry = {
|
|
|
648
631
|
{
|
|
649
632
|
id: 'states',
|
|
650
633
|
title: 'States',
|
|
651
|
-
render: () =>
|
|
652
|
-
<>
|
|
653
|
-
<Checkbox aria-label="Unchecked" />
|
|
654
|
-
<Checkbox defaultChecked aria-label="Checked" />
|
|
655
|
-
<Checkbox checked="indeterminate" aria-label="Indeterminate" />
|
|
656
|
-
</>
|
|
657
|
-
),
|
|
634
|
+
render: () => <CheckboxInputsStatesSample />,
|
|
658
635
|
code: `import { Checkbox } from '@open-mercato/ui/primitives/checkbox'
|
|
659
636
|
|
|
660
637
|
<Checkbox />
|
|
@@ -664,12 +641,7 @@ const checkboxEntry: GalleryEntry = {
|
|
|
664
641
|
{
|
|
665
642
|
id: 'sizes',
|
|
666
643
|
title: 'Sizes',
|
|
667
|
-
render: () =>
|
|
668
|
-
<>
|
|
669
|
-
<Checkbox size="sm" defaultChecked aria-label="Small" />
|
|
670
|
-
<Checkbox size="md" defaultChecked aria-label="Medium" />
|
|
671
|
-
</>
|
|
672
|
-
),
|
|
644
|
+
render: () => <CheckboxInputsSizesSample />,
|
|
673
645
|
code: `import { Checkbox } from '@open-mercato/ui/primitives/checkbox'
|
|
674
646
|
|
|
675
647
|
<Checkbox size="sm" defaultChecked />
|
|
@@ -678,12 +650,7 @@ const checkboxEntry: GalleryEntry = {
|
|
|
678
650
|
{
|
|
679
651
|
id: 'disabled',
|
|
680
652
|
title: 'Disabled',
|
|
681
|
-
render: () =>
|
|
682
|
-
<>
|
|
683
|
-
<Checkbox disabled aria-label="Disabled" />
|
|
684
|
-
<Checkbox disabled defaultChecked aria-label="Disabled checked" />
|
|
685
|
-
</>
|
|
686
|
-
),
|
|
653
|
+
render: () => <CheckboxInputsDisabledSample />,
|
|
687
654
|
code: `import { Checkbox } from '@open-mercato/ui/primitives/checkbox'
|
|
688
655
|
|
|
689
656
|
<Checkbox disabled />
|
|
@@ -696,13 +663,12 @@ const checkboxFieldEntry: GalleryEntry = {
|
|
|
696
663
|
id: 'checkbox-field',
|
|
697
664
|
title: 'CheckboxField',
|
|
698
665
|
importPath: '@open-mercato/ui/primitives/checkbox-field',
|
|
666
|
+
figmaNodeId: '231:4897',
|
|
699
667
|
variants: [
|
|
700
668
|
{
|
|
701
669
|
id: 'default',
|
|
702
670
|
title: 'default',
|
|
703
|
-
render: () =>
|
|
704
|
-
<CheckboxField label="Email notifications" defaultChecked />
|
|
705
|
-
),
|
|
671
|
+
render: () => <CheckboxFieldInputsDefaultSample />,
|
|
706
672
|
code: `import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
707
673
|
|
|
708
674
|
<CheckboxField label="Email notifications" defaultChecked />`,
|
|
@@ -710,15 +676,7 @@ const checkboxFieldEntry: GalleryEntry = {
|
|
|
710
676
|
{
|
|
711
677
|
id: 'with-description',
|
|
712
678
|
title: 'With sublabel + description',
|
|
713
|
-
render: () =>
|
|
714
|
-
<div className="w-80">
|
|
715
|
-
<CheckboxField
|
|
716
|
-
label="Auto-archive"
|
|
717
|
-
sublabel="(recommended)"
|
|
718
|
-
description="Closed conversations move to the archive after 30 days."
|
|
719
|
-
/>
|
|
720
|
-
</div>
|
|
721
|
-
),
|
|
679
|
+
render: () => <CheckboxFieldInputsWithDescriptionSample />,
|
|
722
680
|
code: `import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
723
681
|
|
|
724
682
|
<CheckboxField
|
|
@@ -730,57 +688,239 @@ const checkboxFieldEntry: GalleryEntry = {
|
|
|
730
688
|
{
|
|
731
689
|
id: 'flip',
|
|
732
690
|
title: 'Flipped (checkbox right)',
|
|
733
|
-
render: () =>
|
|
734
|
-
<div className="w-72">
|
|
735
|
-
<CheckboxField flip label="Include shipping costs" defaultChecked />
|
|
736
|
-
</div>
|
|
737
|
-
),
|
|
691
|
+
render: () => <CheckboxFieldInputsFlipSample />,
|
|
738
692
|
code: `import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
739
693
|
|
|
740
694
|
<CheckboxField flip label="Include shipping costs" defaultChecked />`,
|
|
741
695
|
},
|
|
742
|
-
],
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
const radioEntry: GalleryEntry = {
|
|
746
|
-
id: 'radio',
|
|
747
|
-
title: 'Radio',
|
|
748
|
-
importPath: '@open-mercato/ui/primitives/radio',
|
|
749
|
-
keywords: ['radiobutton', 'radio button', 'option group'],
|
|
750
|
-
variants: [
|
|
751
696
|
{
|
|
752
|
-
id: '
|
|
753
|
-
title: '
|
|
754
|
-
render: () =>
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
697
|
+
id: 'cards',
|
|
698
|
+
title: 'Card / default, selected and hover',
|
|
699
|
+
render: () => <SelectionCardsPreview control="checkbox" />,
|
|
700
|
+
code: `import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
701
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
702
|
+
|
|
703
|
+
const cardClassName = 'relative w-full max-w-90 gap-3.5 rounded-xl border border-border bg-background p-4 shadow-xs transition-colors hover:border-transparent hover:bg-muted hover:shadow-none has-[[data-state=checked]]:border-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus has-[:disabled]:border-border has-[:disabled]:bg-background has-[:disabled]:shadow-none [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-xl [&_button]:relative [&_button]:z-10'
|
|
704
|
+
|
|
705
|
+
<div className="grid w-full gap-4 sm:grid-cols-2">
|
|
706
|
+
<CheckboxField flip defaultChecked
|
|
707
|
+
label="Immediate updates"
|
|
708
|
+
sublabel="(Optional)"
|
|
709
|
+
description="Receive an update when an order changes."
|
|
710
|
+
badge={<Badge variant="info" size="sm">New</Badge>}
|
|
711
|
+
className="mt-0"
|
|
712
|
+
containerClassName={cardClassName}
|
|
713
|
+
/>
|
|
714
|
+
<CheckboxField flip
|
|
715
|
+
label="Weekly summary"
|
|
716
|
+
sublabel="(Optional)"
|
|
717
|
+
description="Receive one summary every Monday."
|
|
718
|
+
badge={<Badge variant="info" size="sm">New</Badge>}
|
|
719
|
+
className="mt-0"
|
|
720
|
+
containerClassName={cardClassName}
|
|
721
|
+
/>
|
|
722
|
+
</div>`,
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
id: 'cards-disabled',
|
|
726
|
+
title: 'Card / disabled',
|
|
727
|
+
render: () => <SelectionCardsPreview control="checkbox" disabled />,
|
|
728
|
+
code: `import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
729
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
730
|
+
|
|
731
|
+
const cardClassName = 'relative w-full max-w-90 gap-3.5 rounded-xl border border-border bg-background p-4 shadow-xs transition-colors hover:border-transparent hover:bg-muted hover:shadow-none has-[[data-state=checked]]:border-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus has-[:disabled]:border-border has-[:disabled]:bg-background has-[:disabled]:shadow-none [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-xl [&_button]:relative [&_button]:z-10'
|
|
732
|
+
|
|
733
|
+
<div className="grid w-full gap-4 sm:grid-cols-2">
|
|
734
|
+
<CheckboxField flip defaultChecked disabled
|
|
735
|
+
label="Immediate updates"
|
|
736
|
+
sublabel="(Optional)"
|
|
737
|
+
description="Receive an update when an order changes."
|
|
738
|
+
badge={<Badge variant="outline" size="sm" className="text-text-disabled">New</Badge>}
|
|
739
|
+
className="mt-0"
|
|
740
|
+
containerClassName={cardClassName}
|
|
741
|
+
/>
|
|
742
|
+
<CheckboxField flip disabled
|
|
743
|
+
label="Weekly summary"
|
|
744
|
+
sublabel="(Optional)"
|
|
745
|
+
description="Receive one summary every Monday."
|
|
746
|
+
badge={<Badge variant="outline" size="sm" className="text-text-disabled">New</Badge>}
|
|
747
|
+
className="mt-0"
|
|
748
|
+
containerClassName={cardClassName}
|
|
749
|
+
/>
|
|
750
|
+
</div>`,
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
id: 'source-cards-icon',
|
|
754
|
+
title: 'icon cards / default, active, disabled and live hover',
|
|
755
|
+
render: () => <SelectionSourceCardsDemo control="checkbox" kind="icon" />,
|
|
756
|
+
code: `import * as React from 'react'
|
|
757
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
758
|
+
import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
759
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
762
760
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
761
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
762
|
+
const [checked, setChecked] = React.useState(false)
|
|
763
|
+
const label = 'Label'
|
|
764
|
+
return (
|
|
765
|
+
|
|
766
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
767
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
768
|
+
<CheckboxField flip checked={checked} onCheckedChange={value => setChecked(value === true)} disabled={disabled}
|
|
769
|
+
label={label}
|
|
770
|
+
sublabel="(Sublabel)"
|
|
771
|
+
description="Insert the checkbox description here."
|
|
772
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
773
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
774
|
+
/>
|
|
775
|
+
</div>
|
|
776
|
+
|
|
777
|
+
)
|
|
778
|
+
}`,
|
|
768
779
|
},
|
|
769
780
|
{
|
|
770
|
-
id: '
|
|
771
|
-
title: '
|
|
772
|
-
render: () =>
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
code: `import { Radio, RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
781
|
+
id: 'source-cards-avatar',
|
|
782
|
+
title: 'avatar cards / default, active, disabled and live hover',
|
|
783
|
+
render: () => <SelectionSourceCardsDemo control="checkbox" kind="avatar" />,
|
|
784
|
+
code: `import * as React from 'react'
|
|
785
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
786
|
+
import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
787
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
788
|
+
import { Avatar } from '@open-mercato/ui/primitives/avatar'
|
|
779
789
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
790
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
791
|
+
const [checked, setChecked] = React.useState(false)
|
|
792
|
+
const label = 'Label'
|
|
793
|
+
return (
|
|
794
|
+
|
|
795
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
796
|
+
<Avatar label={label} size={40} src={imageUrl} aria-hidden="true" />
|
|
797
|
+
<CheckboxField flip checked={checked} onCheckedChange={value => setChecked(value === true)} disabled={disabled}
|
|
798
|
+
label={label}
|
|
799
|
+
sublabel="(Sublabel)"
|
|
800
|
+
description="Insert the checkbox description here."
|
|
801
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
802
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
803
|
+
/>
|
|
804
|
+
</div>
|
|
805
|
+
|
|
806
|
+
)
|
|
807
|
+
}`,
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
id: 'source-cards-provider',
|
|
811
|
+
title: 'provider cards / default, active, disabled and live hover',
|
|
812
|
+
render: () => <SelectionSourceCardsDemo control="checkbox" kind="provider" />,
|
|
813
|
+
code: `import * as React from 'react'
|
|
814
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
815
|
+
import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
816
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
817
|
+
|
|
818
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
819
|
+
const [checked, setChecked] = React.useState(false)
|
|
820
|
+
const label = 'Label'
|
|
821
|
+
return (
|
|
822
|
+
|
|
823
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
824
|
+
<img src={imageUrl} alt="" className="h-6 w-8 shrink-0 object-contain" />
|
|
825
|
+
<CheckboxField flip checked={checked} onCheckedChange={value => setChecked(value === true)} disabled={disabled}
|
|
826
|
+
label={label}
|
|
827
|
+
sublabel="(Sublabel)"
|
|
828
|
+
description="Insert the checkbox description here."
|
|
829
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
830
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
831
|
+
/>
|
|
832
|
+
</div>
|
|
833
|
+
|
|
834
|
+
)
|
|
835
|
+
}`,
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
id: 'source-cards-brand',
|
|
839
|
+
title: 'brand cards / default, active, disabled and live hover',
|
|
840
|
+
render: () => <SelectionSourceCardsDemo control="checkbox" kind="brand" />,
|
|
841
|
+
code: `import * as React from 'react'
|
|
842
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
843
|
+
import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
844
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
845
|
+
|
|
846
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
847
|
+
const [checked, setChecked] = React.useState(false)
|
|
848
|
+
const label = 'Label'
|
|
849
|
+
return (
|
|
850
|
+
|
|
851
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
852
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
853
|
+
<CheckboxField flip checked={checked} onCheckedChange={value => setChecked(value === true)} disabled={disabled}
|
|
854
|
+
label={label}
|
|
855
|
+
sublabel="(Sublabel)"
|
|
856
|
+
description="Insert the checkbox description here."
|
|
857
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
858
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
859
|
+
/>
|
|
860
|
+
</div>
|
|
861
|
+
|
|
862
|
+
)
|
|
863
|
+
}`,
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
id: 'source-cards-company',
|
|
867
|
+
title: 'company cards / default, active, disabled and live hover',
|
|
868
|
+
render: () => <SelectionSourceCardsDemo control="checkbox" kind="company" />,
|
|
869
|
+
code: `import * as React from 'react'
|
|
870
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
871
|
+
import { CheckboxField } from '@open-mercato/ui/primitives/checkbox-field'
|
|
872
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
873
|
+
|
|
874
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
875
|
+
const [checked, setChecked] = React.useState(false)
|
|
876
|
+
const label = 'Label'
|
|
877
|
+
return (
|
|
878
|
+
|
|
879
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
880
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
881
|
+
<CheckboxField flip checked={checked} onCheckedChange={value => setChecked(value === true)} disabled={disabled}
|
|
882
|
+
label={label}
|
|
883
|
+
sublabel="(Sublabel)"
|
|
884
|
+
description="Insert the checkbox description here."
|
|
885
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
886
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
887
|
+
/>
|
|
888
|
+
</div>
|
|
889
|
+
|
|
890
|
+
)
|
|
891
|
+
}`,
|
|
892
|
+
},
|
|
893
|
+
],
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
const radioEntry: GalleryEntry = {
|
|
897
|
+
id: 'radio',
|
|
898
|
+
title: 'Radio',
|
|
899
|
+
importPath: '@open-mercato/ui/primitives/radio',
|
|
900
|
+
keywords: ['radiobutton', 'radio button', 'option group'],
|
|
901
|
+
variants: [
|
|
902
|
+
{
|
|
903
|
+
id: 'group',
|
|
904
|
+
title: 'RadioGroup',
|
|
905
|
+
render: () => <RadioInputsGroupSample />,
|
|
906
|
+
code: `import { Radio, RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
907
|
+
|
|
908
|
+
<RadioGroup defaultValue="card" aria-label="Payment method">
|
|
909
|
+
<Radio value="card" aria-label="Card" />
|
|
910
|
+
<Radio value="transfer" aria-label="Bank transfer" />
|
|
911
|
+
<Radio value="cash" aria-label="Cash" />
|
|
912
|
+
</RadioGroup>`,
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
id: 'disabled',
|
|
916
|
+
title: 'Disabled',
|
|
917
|
+
render: () => <RadioInputsDisabledSample />,
|
|
918
|
+
code: `import { Radio, RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
919
|
+
|
|
920
|
+
<RadioGroup defaultValue="a" disabled>
|
|
921
|
+
<Radio value="a" />
|
|
922
|
+
<Radio value="b" />
|
|
923
|
+
</RadioGroup>`,
|
|
784
924
|
},
|
|
785
925
|
],
|
|
786
926
|
}
|
|
@@ -790,16 +930,24 @@ const radioFieldEntry: GalleryEntry = {
|
|
|
790
930
|
id: 'radio-field',
|
|
791
931
|
title: 'RadioField',
|
|
792
932
|
importPath: '@open-mercato/ui/primitives/radio-field',
|
|
933
|
+
figmaNodeId: '515:4282',
|
|
793
934
|
variants: [
|
|
935
|
+
{
|
|
936
|
+
id: 'flip',
|
|
937
|
+
title: 'Flipped (radio right)',
|
|
938
|
+
render: () => <FlippedRadioPreview />,
|
|
939
|
+
code: `import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
940
|
+
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
941
|
+
|
|
942
|
+
<RadioGroup defaultValue="immediate" aria-label="Notification preferences" className="w-72">
|
|
943
|
+
<RadioField value="immediate" flip label="Immediate updates" />
|
|
944
|
+
<RadioField value="weekly" flip label="Weekly summary" />
|
|
945
|
+
</RadioGroup>`,
|
|
946
|
+
},
|
|
794
947
|
{
|
|
795
948
|
id: 'default',
|
|
796
949
|
title: 'default',
|
|
797
|
-
render: () =>
|
|
798
|
-
<RadioGroup defaultValue="standard" aria-label="Shipping speed">
|
|
799
|
-
<RadioField value="standard" label="Standard" />
|
|
800
|
-
<RadioField value="express" label="Express" />
|
|
801
|
-
</RadioGroup>
|
|
802
|
-
),
|
|
950
|
+
render: () => <RadioFieldInputsDefaultSample />,
|
|
803
951
|
code: `import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
804
952
|
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
805
953
|
|
|
@@ -811,22 +959,7 @@ import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
|
811
959
|
{
|
|
812
960
|
id: 'with-description',
|
|
813
961
|
title: 'With description',
|
|
814
|
-
render: () =>
|
|
815
|
-
<div className="w-80">
|
|
816
|
-
<RadioGroup defaultValue="invoice" aria-label="Billing">
|
|
817
|
-
<RadioField
|
|
818
|
-
value="invoice"
|
|
819
|
-
label="Invoice"
|
|
820
|
-
description="Pay within 14 days of delivery."
|
|
821
|
-
/>
|
|
822
|
-
<RadioField
|
|
823
|
-
value="prepaid"
|
|
824
|
-
label="Prepaid"
|
|
825
|
-
description="Order ships after payment clears."
|
|
826
|
-
/>
|
|
827
|
-
</RadioGroup>
|
|
828
|
-
</div>
|
|
829
|
-
),
|
|
962
|
+
render: () => <RadioFieldInputsWithDescriptionSample />,
|
|
830
963
|
code: `import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
831
964
|
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
832
965
|
|
|
@@ -835,6 +968,210 @@ import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
|
835
968
|
<RadioField value="prepaid" label="Prepaid" description="Order ships after payment clears." />
|
|
836
969
|
</RadioGroup>`,
|
|
837
970
|
},
|
|
971
|
+
{
|
|
972
|
+
id: 'cards',
|
|
973
|
+
title: 'Card / default, selected and hover',
|
|
974
|
+
render: () => <SelectionCardsPreview control="radio" />,
|
|
975
|
+
code: `import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
976
|
+
import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
977
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
978
|
+
|
|
979
|
+
const cardClassName = 'relative w-full max-w-90 gap-3.5 rounded-xl border border-border bg-background p-4 shadow-xs transition-colors hover:border-transparent hover:bg-muted hover:shadow-none has-[[data-state=checked]]:border-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus has-[:disabled]:border-border has-[:disabled]:bg-background has-[:disabled]:shadow-none [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-xl [&_button]:relative [&_button]:z-10'
|
|
980
|
+
|
|
981
|
+
<RadioGroup defaultValue="immediate" aria-label="Notification preferences" className="grid w-full gap-4 sm:grid-cols-2">
|
|
982
|
+
<RadioField flip value="immediate"
|
|
983
|
+
label="Immediate updates"
|
|
984
|
+
sublabel="(Optional)"
|
|
985
|
+
description="Receive an update when an order changes."
|
|
986
|
+
badge={<Badge variant="info" size="sm">New</Badge>}
|
|
987
|
+
className="mt-0"
|
|
988
|
+
containerClassName={cardClassName}
|
|
989
|
+
/>
|
|
990
|
+
<RadioField flip value="weekly"
|
|
991
|
+
label="Weekly summary"
|
|
992
|
+
sublabel="(Optional)"
|
|
993
|
+
description="Receive one summary every Monday."
|
|
994
|
+
badge={<Badge variant="info" size="sm">New</Badge>}
|
|
995
|
+
className="mt-0"
|
|
996
|
+
containerClassName={cardClassName}
|
|
997
|
+
/>
|
|
998
|
+
</RadioGroup>`,
|
|
999
|
+
},
|
|
1000
|
+
{
|
|
1001
|
+
id: 'cards-disabled',
|
|
1002
|
+
title: 'Card / disabled',
|
|
1003
|
+
render: () => <SelectionCardsPreview control="radio" disabled />,
|
|
1004
|
+
code: `import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
1005
|
+
import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
1006
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1007
|
+
|
|
1008
|
+
const cardClassName = 'relative w-full max-w-90 gap-3.5 rounded-xl border border-border bg-background p-4 shadow-xs transition-colors hover:border-transparent hover:bg-muted hover:shadow-none has-[[data-state=checked]]:border-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus has-[:disabled]:border-border has-[:disabled]:bg-background has-[:disabled]:shadow-none [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-xl [&_button]:relative [&_button]:z-10'
|
|
1009
|
+
|
|
1010
|
+
<RadioGroup defaultValue="immediate" aria-label="Notification preferences" className="grid w-full gap-4 sm:grid-cols-2">
|
|
1011
|
+
<RadioField flip value="immediate" disabled
|
|
1012
|
+
label="Immediate updates"
|
|
1013
|
+
sublabel="(Optional)"
|
|
1014
|
+
description="Receive an update when an order changes."
|
|
1015
|
+
badge={<Badge variant="outline" size="sm" className="text-text-disabled">New</Badge>}
|
|
1016
|
+
className="mt-0"
|
|
1017
|
+
containerClassName={cardClassName}
|
|
1018
|
+
/>
|
|
1019
|
+
<RadioField flip value="weekly" disabled
|
|
1020
|
+
label="Weekly summary"
|
|
1021
|
+
sublabel="(Optional)"
|
|
1022
|
+
description="Receive one summary every Monday."
|
|
1023
|
+
badge={<Badge variant="outline" size="sm" className="text-text-disabled">New</Badge>}
|
|
1024
|
+
className="mt-0"
|
|
1025
|
+
containerClassName={cardClassName}
|
|
1026
|
+
/>
|
|
1027
|
+
</RadioGroup>`,
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
id: 'source-cards-icon',
|
|
1031
|
+
title: 'icon cards / default, active, disabled and live hover',
|
|
1032
|
+
render: () => <SelectionSourceCardsDemo control="radio" kind="icon" />,
|
|
1033
|
+
code: `import * as React from 'react'
|
|
1034
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1035
|
+
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
1036
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1037
|
+
import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
1038
|
+
|
|
1039
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1040
|
+
const [value, setValue] = React.useState('selected')
|
|
1041
|
+
const label = 'Label'
|
|
1042
|
+
return (
|
|
1043
|
+
<RadioGroup value={value} onValueChange={setValue} aria-label={label}>
|
|
1044
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1045
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
1046
|
+
<RadioField value="selected" flip disabled={disabled}
|
|
1047
|
+
label={label}
|
|
1048
|
+
sublabel="(Sublabel)"
|
|
1049
|
+
description="Insert the checkbox description here."
|
|
1050
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1051
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1052
|
+
/>
|
|
1053
|
+
</div>
|
|
1054
|
+
</RadioGroup>
|
|
1055
|
+
)
|
|
1056
|
+
}`,
|
|
1057
|
+
},
|
|
1058
|
+
{
|
|
1059
|
+
id: 'source-cards-avatar',
|
|
1060
|
+
title: 'avatar cards / default, active, disabled and live hover',
|
|
1061
|
+
render: () => <SelectionSourceCardsDemo control="radio" kind="avatar" />,
|
|
1062
|
+
code: `import * as React from 'react'
|
|
1063
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1064
|
+
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
1065
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1066
|
+
import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
1067
|
+
import { Avatar } from '@open-mercato/ui/primitives/avatar'
|
|
1068
|
+
|
|
1069
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1070
|
+
const [value, setValue] = React.useState('selected')
|
|
1071
|
+
const label = 'Label'
|
|
1072
|
+
return (
|
|
1073
|
+
<RadioGroup value={value} onValueChange={setValue} aria-label={label}>
|
|
1074
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1075
|
+
<Avatar label={label} size={40} src={imageUrl} aria-hidden="true" />
|
|
1076
|
+
<RadioField value="selected" flip disabled={disabled}
|
|
1077
|
+
label={label}
|
|
1078
|
+
sublabel="(Sublabel)"
|
|
1079
|
+
description="Insert the checkbox description here."
|
|
1080
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1081
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1082
|
+
/>
|
|
1083
|
+
</div>
|
|
1084
|
+
</RadioGroup>
|
|
1085
|
+
)
|
|
1086
|
+
}`,
|
|
1087
|
+
},
|
|
1088
|
+
{
|
|
1089
|
+
id: 'source-cards-provider',
|
|
1090
|
+
title: 'provider cards / default, active, disabled and live hover',
|
|
1091
|
+
render: () => <SelectionSourceCardsDemo control="radio" kind="provider" />,
|
|
1092
|
+
code: `import * as React from 'react'
|
|
1093
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1094
|
+
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
1095
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1096
|
+
import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
1097
|
+
|
|
1098
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1099
|
+
const [value, setValue] = React.useState('selected')
|
|
1100
|
+
const label = 'Label'
|
|
1101
|
+
return (
|
|
1102
|
+
<RadioGroup value={value} onValueChange={setValue} aria-label={label}>
|
|
1103
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1104
|
+
<img src={imageUrl} alt="" className="h-6 w-8 shrink-0 object-contain" />
|
|
1105
|
+
<RadioField value="selected" flip disabled={disabled}
|
|
1106
|
+
label={label}
|
|
1107
|
+
sublabel="(Sublabel)"
|
|
1108
|
+
description="Insert the checkbox description here."
|
|
1109
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1110
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1111
|
+
/>
|
|
1112
|
+
</div>
|
|
1113
|
+
</RadioGroup>
|
|
1114
|
+
)
|
|
1115
|
+
}`,
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
id: 'source-cards-brand',
|
|
1119
|
+
title: 'brand cards / default, active, disabled and live hover',
|
|
1120
|
+
render: () => <SelectionSourceCardsDemo control="radio" kind="brand" />,
|
|
1121
|
+
code: `import * as React from 'react'
|
|
1122
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1123
|
+
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
1124
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1125
|
+
import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
1126
|
+
|
|
1127
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1128
|
+
const [value, setValue] = React.useState('selected')
|
|
1129
|
+
const label = 'Label'
|
|
1130
|
+
return (
|
|
1131
|
+
<RadioGroup value={value} onValueChange={setValue} aria-label={label}>
|
|
1132
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1133
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
1134
|
+
<RadioField value="selected" flip disabled={disabled}
|
|
1135
|
+
label={label}
|
|
1136
|
+
sublabel="(Sublabel)"
|
|
1137
|
+
description="Insert the checkbox description here."
|
|
1138
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1139
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1140
|
+
/>
|
|
1141
|
+
</div>
|
|
1142
|
+
</RadioGroup>
|
|
1143
|
+
)
|
|
1144
|
+
}`,
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
id: 'source-cards-company',
|
|
1148
|
+
title: 'company cards / default, active, disabled and live hover',
|
|
1149
|
+
render: () => <SelectionSourceCardsDemo control="radio" kind="company" />,
|
|
1150
|
+
code: `import * as React from 'react'
|
|
1151
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1152
|
+
import { RadioField } from '@open-mercato/ui/primitives/radio-field'
|
|
1153
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1154
|
+
import { RadioGroup } from '@open-mercato/ui/primitives/radio'
|
|
1155
|
+
|
|
1156
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1157
|
+
const [value, setValue] = React.useState('selected')
|
|
1158
|
+
const label = 'Label'
|
|
1159
|
+
return (
|
|
1160
|
+
<RadioGroup value={value} onValueChange={setValue} aria-label={label}>
|
|
1161
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1162
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
1163
|
+
<RadioField value="selected" flip disabled={disabled}
|
|
1164
|
+
label={label}
|
|
1165
|
+
sublabel="(Sublabel)"
|
|
1166
|
+
description="Insert the checkbox description here."
|
|
1167
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1168
|
+
className="mt-0 disabled:opacity-100 disabled:data-[state=checked]:bg-bg-disabled disabled:data-[state=checked]:border-border-disabled disabled:data-[state=checked]:text-background" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1169
|
+
/>
|
|
1170
|
+
</div>
|
|
1171
|
+
</RadioGroup>
|
|
1172
|
+
)
|
|
1173
|
+
}`,
|
|
1174
|
+
},
|
|
838
1175
|
],
|
|
839
1176
|
}
|
|
840
1177
|
|
|
@@ -846,12 +1183,7 @@ const switchEntry: GalleryEntry = {
|
|
|
846
1183
|
{
|
|
847
1184
|
id: 'states',
|
|
848
1185
|
title: 'States',
|
|
849
|
-
render: () =>
|
|
850
|
-
<>
|
|
851
|
-
<Switch aria-label="Off" />
|
|
852
|
-
<Switch defaultChecked aria-label="On" />
|
|
853
|
-
</>
|
|
854
|
-
),
|
|
1186
|
+
render: () => <SwitchInputsStatesSample />,
|
|
855
1187
|
code: `import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
856
1188
|
|
|
857
1189
|
<Switch />
|
|
@@ -860,12 +1192,7 @@ const switchEntry: GalleryEntry = {
|
|
|
860
1192
|
{
|
|
861
1193
|
id: 'disabled',
|
|
862
1194
|
title: 'Disabled',
|
|
863
|
-
render: () =>
|
|
864
|
-
<>
|
|
865
|
-
<Switch disabled aria-label="Disabled off" />
|
|
866
|
-
<Switch disabled defaultChecked aria-label="Disabled on" />
|
|
867
|
-
</>
|
|
868
|
-
),
|
|
1195
|
+
render: () => <SwitchInputsDisabledSample />,
|
|
869
1196
|
code: `import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
870
1197
|
|
|
871
1198
|
<Switch disabled />
|
|
@@ -878,15 +1205,12 @@ const switchFieldEntry: GalleryEntry = {
|
|
|
878
1205
|
id: 'switch-field',
|
|
879
1206
|
title: 'SwitchField',
|
|
880
1207
|
importPath: '@open-mercato/ui/primitives/switch-field',
|
|
1208
|
+
figmaNodeId: '385:4580',
|
|
881
1209
|
variants: [
|
|
882
1210
|
{
|
|
883
1211
|
id: 'default',
|
|
884
1212
|
title: 'default (switch right)',
|
|
885
|
-
render: () =>
|
|
886
|
-
<div className="w-72">
|
|
887
|
-
<SwitchField label="Two-factor authentication" defaultChecked />
|
|
888
|
-
</div>
|
|
889
|
-
),
|
|
1213
|
+
render: () => <SwitchFieldInputsDefaultSample />,
|
|
890
1214
|
code: `import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
891
1215
|
|
|
892
1216
|
<SwitchField label="Two-factor authentication" defaultChecked />`,
|
|
@@ -894,14 +1218,7 @@ const switchFieldEntry: GalleryEntry = {
|
|
|
894
1218
|
{
|
|
895
1219
|
id: 'with-description',
|
|
896
1220
|
title: 'With description',
|
|
897
|
-
render: () =>
|
|
898
|
-
<div className="w-80">
|
|
899
|
-
<SwitchField
|
|
900
|
-
label="Low-stock alerts"
|
|
901
|
-
description="Notify purchasing when stock drops below the reorder point."
|
|
902
|
-
/>
|
|
903
|
-
</div>
|
|
904
|
-
),
|
|
1221
|
+
render: () => <SwitchFieldInputsWithDescriptionSample />,
|
|
905
1222
|
code: `import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
906
1223
|
|
|
907
1224
|
<SwitchField
|
|
@@ -912,31 +1229,420 @@ const switchFieldEntry: GalleryEntry = {
|
|
|
912
1229
|
{
|
|
913
1230
|
id: 'flip',
|
|
914
1231
|
title: 'Flipped (switch left)',
|
|
915
|
-
render: () =>
|
|
916
|
-
<div className="w-72">
|
|
917
|
-
<SwitchField flip label="Sync inventory nightly" defaultChecked />
|
|
918
|
-
</div>
|
|
919
|
-
),
|
|
1232
|
+
render: () => <SwitchFieldInputsFlipSample />,
|
|
920
1233
|
code: `import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
921
1234
|
|
|
922
1235
|
<SwitchField flip label="Sync inventory nightly" defaultChecked />`,
|
|
923
1236
|
},
|
|
1237
|
+
{
|
|
1238
|
+
id: 'cards',
|
|
1239
|
+
title: 'Card / default, selected and hover',
|
|
1240
|
+
render: () => <SelectionCardsPreview control="switch" />,
|
|
1241
|
+
code: `import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1242
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1243
|
+
|
|
1244
|
+
const cardClassName = 'relative w-full max-w-90 gap-3.5 rounded-xl border border-border bg-background p-4 shadow-xs transition-colors hover:border-transparent hover:bg-muted hover:shadow-none has-[[data-state=checked]]:border-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus has-[:disabled]:border-border has-[:disabled]:bg-background has-[:disabled]:shadow-none [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-xl [&_button]:relative [&_button]:z-10'
|
|
1245
|
+
|
|
1246
|
+
<div className="grid w-full gap-4 sm:grid-cols-2">
|
|
1247
|
+
<SwitchField defaultChecked
|
|
1248
|
+
label="Immediate updates"
|
|
1249
|
+
sublabel="(Optional)"
|
|
1250
|
+
description="Receive an update when an order changes."
|
|
1251
|
+
badge={<Badge variant="info" size="sm">New</Badge>}
|
|
1252
|
+
className="mt-0"
|
|
1253
|
+
containerClassName={cardClassName}
|
|
1254
|
+
/>
|
|
1255
|
+
<SwitchField
|
|
1256
|
+
label="Weekly summary"
|
|
1257
|
+
sublabel="(Optional)"
|
|
1258
|
+
description="Receive one summary every Monday."
|
|
1259
|
+
badge={<Badge variant="info" size="sm">New</Badge>}
|
|
1260
|
+
className="mt-0"
|
|
1261
|
+
containerClassName={cardClassName}
|
|
1262
|
+
/>
|
|
1263
|
+
</div>`,
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
id: 'cards-disabled',
|
|
1267
|
+
title: 'Card / disabled',
|
|
1268
|
+
render: () => <SelectionCardsPreview control="switch" disabled />,
|
|
1269
|
+
code: `import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1270
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1271
|
+
|
|
1272
|
+
const cardClassName = 'relative w-full max-w-90 gap-3.5 rounded-xl border border-border bg-background p-4 shadow-xs transition-colors hover:border-transparent hover:bg-muted hover:shadow-none has-[[data-state=checked]]:border-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus has-[:disabled]:border-border has-[:disabled]:bg-background has-[:disabled]:shadow-none [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-xl [&_button]:relative [&_button]:z-10'
|
|
1273
|
+
|
|
1274
|
+
<div className="grid w-full gap-4 sm:grid-cols-2">
|
|
1275
|
+
<SwitchField defaultChecked disabled
|
|
1276
|
+
label="Immediate updates"
|
|
1277
|
+
sublabel="(Optional)"
|
|
1278
|
+
description="Receive an update when an order changes."
|
|
1279
|
+
badge={<Badge variant="outline" size="sm" className="text-text-disabled">New</Badge>}
|
|
1280
|
+
className="mt-0"
|
|
1281
|
+
containerClassName={cardClassName}
|
|
1282
|
+
/>
|
|
1283
|
+
<SwitchField disabled
|
|
1284
|
+
label="Weekly summary"
|
|
1285
|
+
sublabel="(Optional)"
|
|
1286
|
+
description="Receive one summary every Monday."
|
|
1287
|
+
badge={<Badge variant="outline" size="sm" className="text-text-disabled">New</Badge>}
|
|
1288
|
+
className="mt-0"
|
|
1289
|
+
containerClassName={cardClassName}
|
|
1290
|
+
/>
|
|
1291
|
+
</div>`,
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
id: 'source-cards-icon',
|
|
1295
|
+
title: 'icon cards / default, active, disabled and live hover',
|
|
1296
|
+
render: () => <SelectionSourceCardsDemo control="switch" kind="icon" />,
|
|
1297
|
+
code: `import * as React from 'react'
|
|
1298
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1299
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1300
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1301
|
+
|
|
1302
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1303
|
+
const [checked, setChecked] = React.useState(false)
|
|
1304
|
+
const label = 'Label'
|
|
1305
|
+
return (
|
|
1306
|
+
|
|
1307
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1308
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
1309
|
+
<SwitchField checked={checked} onCheckedChange={setChecked} disabled={disabled}
|
|
1310
|
+
label={label}
|
|
1311
|
+
sublabel="(Sublabel)"
|
|
1312
|
+
description="Insert the checkbox description here."
|
|
1313
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1314
|
+
className="mt-0" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1315
|
+
/>
|
|
1316
|
+
</div>
|
|
1317
|
+
|
|
1318
|
+
)
|
|
1319
|
+
}`,
|
|
1320
|
+
},
|
|
1321
|
+
{
|
|
1322
|
+
id: 'source-cards-avatar',
|
|
1323
|
+
title: 'avatar cards / default, active, disabled and live hover',
|
|
1324
|
+
render: () => <SelectionSourceCardsDemo control="switch" kind="avatar" />,
|
|
1325
|
+
code: `import * as React from 'react'
|
|
1326
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1327
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1328
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1329
|
+
import { Avatar } from '@open-mercato/ui/primitives/avatar'
|
|
1330
|
+
|
|
1331
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1332
|
+
const [checked, setChecked] = React.useState(false)
|
|
1333
|
+
const label = 'Label'
|
|
1334
|
+
return (
|
|
1335
|
+
|
|
1336
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1337
|
+
<Avatar label={label} size={40} src={imageUrl} aria-hidden="true" />
|
|
1338
|
+
<SwitchField checked={checked} onCheckedChange={setChecked} disabled={disabled}
|
|
1339
|
+
label={label}
|
|
1340
|
+
sublabel="(Sublabel)"
|
|
1341
|
+
description="Insert the checkbox description here."
|
|
1342
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1343
|
+
className="mt-0" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1344
|
+
/>
|
|
1345
|
+
</div>
|
|
1346
|
+
|
|
1347
|
+
)
|
|
1348
|
+
}`,
|
|
1349
|
+
},
|
|
1350
|
+
{
|
|
1351
|
+
id: 'source-cards-provider',
|
|
1352
|
+
title: 'provider cards / default, active, disabled and live hover',
|
|
1353
|
+
render: () => <SelectionSourceCardsDemo control="switch" kind="provider" />,
|
|
1354
|
+
code: `import * as React from 'react'
|
|
1355
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1356
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1357
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1358
|
+
|
|
1359
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1360
|
+
const [checked, setChecked] = React.useState(false)
|
|
1361
|
+
const label = 'Label'
|
|
1362
|
+
return (
|
|
1363
|
+
|
|
1364
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1365
|
+
<img src={imageUrl} alt="" className="h-6 w-8 shrink-0 object-contain" />
|
|
1366
|
+
<SwitchField checked={checked} onCheckedChange={setChecked} disabled={disabled}
|
|
1367
|
+
label={label}
|
|
1368
|
+
sublabel="(Sublabel)"
|
|
1369
|
+
description="Insert the checkbox description here."
|
|
1370
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1371
|
+
className="mt-0" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1372
|
+
/>
|
|
1373
|
+
</div>
|
|
1374
|
+
|
|
1375
|
+
)
|
|
1376
|
+
}`,
|
|
1377
|
+
},
|
|
1378
|
+
{
|
|
1379
|
+
id: 'source-cards-brand',
|
|
1380
|
+
title: 'brand cards / default, active, disabled and live hover',
|
|
1381
|
+
render: () => <SelectionSourceCardsDemo control="switch" kind="brand" />,
|
|
1382
|
+
code: `import * as React from 'react'
|
|
1383
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1384
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1385
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1386
|
+
|
|
1387
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1388
|
+
const [checked, setChecked] = React.useState(false)
|
|
1389
|
+
const label = 'Label'
|
|
1390
|
+
return (
|
|
1391
|
+
|
|
1392
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1393
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
1394
|
+
<SwitchField checked={checked} onCheckedChange={setChecked} disabled={disabled}
|
|
1395
|
+
label={label}
|
|
1396
|
+
sublabel="(Sublabel)"
|
|
1397
|
+
description="Insert the checkbox description here."
|
|
1398
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1399
|
+
className="mt-0" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1400
|
+
/>
|
|
1401
|
+
</div>
|
|
1402
|
+
|
|
1403
|
+
)
|
|
1404
|
+
}`,
|
|
1405
|
+
},
|
|
1406
|
+
{
|
|
1407
|
+
id: 'source-cards-company',
|
|
1408
|
+
title: 'company cards / default, active, disabled and live hover',
|
|
1409
|
+
render: () => <SelectionSourceCardsDemo control="switch" kind="company" />,
|
|
1410
|
+
code: `import * as React from 'react'
|
|
1411
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1412
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1413
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1414
|
+
|
|
1415
|
+
function SelectionCardExample({ imageUrl, disabled = false }: { imageUrl: string; disabled?: boolean }) {
|
|
1416
|
+
const [checked, setChecked] = React.useState(false)
|
|
1417
|
+
const label = 'Label'
|
|
1418
|
+
return (
|
|
1419
|
+
|
|
1420
|
+
<div className={cn('relative flex w-90 max-w-full items-start gap-3.5 rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs transition-colors hover:bg-muted hover:shadow-none has-[[data-state=checked]]:ring-accent-indigo has-[[data-state=checked]]:shadow-none has-[:focus-visible]:shadow-focus [&_label]:after:absolute [&_label]:after:inset-0 [&_label]:after:rounded-selection-card [&_button]:relative [&_button]:z-10', disabled && 'shadow-none hover:bg-background has-[[data-state=checked]]:ring-border')}>
|
|
1421
|
+
<img src={imageUrl} alt="" className="size-10 shrink-0 object-contain" />
|
|
1422
|
+
<SwitchField checked={checked} onCheckedChange={setChecked} disabled={disabled}
|
|
1423
|
+
label={label}
|
|
1424
|
+
sublabel="(Sublabel)"
|
|
1425
|
+
description="Insert the checkbox description here."
|
|
1426
|
+
badge={<Badge size={16} appearance={disabled ? 'stroke' : 'light'} tone={disabled ? 'neutral' : 'info'}>New</Badge>}
|
|
1427
|
+
className="mt-0" containerClassName="min-w-0 flex-1 gap-3.5"
|
|
1428
|
+
/>
|
|
1429
|
+
</div>
|
|
1430
|
+
|
|
1431
|
+
)
|
|
1432
|
+
}`,
|
|
1433
|
+
},
|
|
1434
|
+
{
|
|
1435
|
+
id: 'integration-horizontal-card',
|
|
1436
|
+
title: 'Integration / horizontal / card',
|
|
1437
|
+
render: () => <IntegrationSwitchDemo alignment="horizontal" appearance="card" />,
|
|
1438
|
+
code: `import * as React from 'react'
|
|
1439
|
+
import { Settings } from 'lucide-react'
|
|
1440
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1441
|
+
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
1442
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1443
|
+
import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
1444
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1445
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
1446
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@open-mercato/ui/primitives/dialog'
|
|
1447
|
+
|
|
1448
|
+
function IntegrationExample({ brandUrl, alignment, appearance }: { brandUrl: string; alignment: 'horizontal' | 'vertical'; appearance: 'card' | 'list' }) {
|
|
1449
|
+
const t = useT()
|
|
1450
|
+
const id = React.useId()
|
|
1451
|
+
const [checked, setChecked] = React.useState(false)
|
|
1452
|
+
const [open, setOpen] = React.useState(false)
|
|
1453
|
+
const horizontal = alignment === 'horizontal'
|
|
1454
|
+
const card = appearance === 'card'
|
|
1455
|
+
return (
|
|
1456
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
1457
|
+
<div data-slot="integration-switch" data-alignment={alignment} data-appearance={appearance} className={cn('relative flex max-w-full gap-3.5', horizontal ? 'w-154 flex-wrap items-center sm:flex-nowrap' : 'w-95 flex-col items-start', card && 'rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs')}>
|
|
1458
|
+
<img src={brandUrl} alt="" className={cn('shrink-0', card ? 'size-10' : 'size-12')} />
|
|
1459
|
+
<div className={cn('flex min-w-0 flex-col gap-1', horizontal && 'min-w-40 flex-1')}>
|
|
1460
|
+
<div className="flex flex-wrap items-center gap-1.5">
|
|
1461
|
+
<span id={id} className={cn('font-medium text-foreground', card ? 'text-sm leading-5' : 'text-base leading-6')}>Microsoft Office 365</span>
|
|
1462
|
+
<Badge size={16} appearance="light" tone="info">New</Badge>
|
|
1463
|
+
</div>
|
|
1464
|
+
<p className={cn('text-muted-foreground', card ? 'text-xs leading-4' : 'text-sm leading-5')}>Seamless collaboration and document management.</p>
|
|
1465
|
+
</div>
|
|
1466
|
+
<Button asChild variant="outline" size="default" className={horizontal ? undefined : 'w-full'}><DialogTrigger><Settings aria-hidden="true" />Manage</DialogTrigger></Button>
|
|
1467
|
+
<Switch aria-labelledby={id} checked={checked} onCheckedChange={setChecked} className={horizontal ? undefined : card ? 'absolute top-5 right-5' : 'absolute top-3 right-3'} />
|
|
1468
|
+
</div>
|
|
1469
|
+
<DialogContent onKeyDownCapture={event => { if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) { event.preventDefault(); setOpen(false) } }}>
|
|
1470
|
+
<DialogHeader><DialogTitle>Microsoft Office 365 settings</DialogTitle><DialogDescription>Seamless collaboration and document management.</DialogDescription></DialogHeader>
|
|
1471
|
+
<SwitchField label="Enable integration" checked={checked} onCheckedChange={setChecked} />
|
|
1472
|
+
<DialogFooter><Button variant="outline" onClick={() => setOpen(false)}>{t('common.close')}</Button></DialogFooter>
|
|
1473
|
+
</DialogContent>
|
|
1474
|
+
</Dialog>
|
|
1475
|
+
)
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
<IntegrationExample brandUrl={brandUrl} alignment="horizontal" appearance="card" />`,
|
|
1479
|
+
},
|
|
1480
|
+
{
|
|
1481
|
+
id: 'integration-horizontal-list',
|
|
1482
|
+
title: 'Integration / horizontal / list',
|
|
1483
|
+
render: () => <IntegrationSwitchDemo alignment="horizontal" appearance="list" />,
|
|
1484
|
+
code: `import * as React from 'react'
|
|
1485
|
+
import { Settings } from 'lucide-react'
|
|
1486
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1487
|
+
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
1488
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1489
|
+
import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
1490
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1491
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
1492
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@open-mercato/ui/primitives/dialog'
|
|
1493
|
+
|
|
1494
|
+
function IntegrationExample({ brandUrl, alignment, appearance }: { brandUrl: string; alignment: 'horizontal' | 'vertical'; appearance: 'card' | 'list' }) {
|
|
1495
|
+
const t = useT()
|
|
1496
|
+
const id = React.useId()
|
|
1497
|
+
const [checked, setChecked] = React.useState(false)
|
|
1498
|
+
const [open, setOpen] = React.useState(false)
|
|
1499
|
+
const horizontal = alignment === 'horizontal'
|
|
1500
|
+
const card = appearance === 'card'
|
|
1501
|
+
return (
|
|
1502
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
1503
|
+
<div data-slot="integration-switch" data-alignment={alignment} data-appearance={appearance} className={cn('relative flex max-w-full gap-3.5', horizontal ? 'w-154 flex-wrap items-center sm:flex-nowrap' : 'w-95 flex-col items-start', card && 'rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs')}>
|
|
1504
|
+
<img src={brandUrl} alt="" className={cn('shrink-0', card ? 'size-10' : 'size-12')} />
|
|
1505
|
+
<div className={cn('flex min-w-0 flex-col gap-1', horizontal && 'min-w-40 flex-1')}>
|
|
1506
|
+
<div className="flex flex-wrap items-center gap-1.5">
|
|
1507
|
+
<span id={id} className={cn('font-medium text-foreground', card ? 'text-sm leading-5' : 'text-base leading-6')}>Microsoft Office 365</span>
|
|
1508
|
+
<Badge size={16} appearance="light" tone="info">New</Badge>
|
|
1509
|
+
</div>
|
|
1510
|
+
<p className={cn('text-muted-foreground', card ? 'text-xs leading-4' : 'text-sm leading-5')}>Seamless collaboration and document management.</p>
|
|
1511
|
+
</div>
|
|
1512
|
+
<Button asChild variant="outline" size="default" className={horizontal ? undefined : 'w-full'}><DialogTrigger><Settings aria-hidden="true" />Manage</DialogTrigger></Button>
|
|
1513
|
+
<Switch aria-labelledby={id} checked={checked} onCheckedChange={setChecked} className={horizontal ? undefined : card ? 'absolute top-5 right-5' : 'absolute top-3 right-3'} />
|
|
1514
|
+
</div>
|
|
1515
|
+
<DialogContent onKeyDownCapture={event => { if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) { event.preventDefault(); setOpen(false) } }}>
|
|
1516
|
+
<DialogHeader><DialogTitle>Microsoft Office 365 settings</DialogTitle><DialogDescription>Seamless collaboration and document management.</DialogDescription></DialogHeader>
|
|
1517
|
+
<SwitchField label="Enable integration" checked={checked} onCheckedChange={setChecked} />
|
|
1518
|
+
<DialogFooter><Button variant="outline" onClick={() => setOpen(false)}>{t('common.close')}</Button></DialogFooter>
|
|
1519
|
+
</DialogContent>
|
|
1520
|
+
</Dialog>
|
|
1521
|
+
)
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
<IntegrationExample brandUrl={brandUrl} alignment="horizontal" appearance="list" />`,
|
|
1525
|
+
},
|
|
1526
|
+
{
|
|
1527
|
+
id: 'integration-vertical-card',
|
|
1528
|
+
title: 'Integration / vertical / card',
|
|
1529
|
+
render: () => <IntegrationSwitchDemo alignment="vertical" appearance="card" />,
|
|
1530
|
+
code: `import * as React from 'react'
|
|
1531
|
+
import { Settings } from 'lucide-react'
|
|
1532
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1533
|
+
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
1534
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1535
|
+
import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
1536
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1537
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
1538
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@open-mercato/ui/primitives/dialog'
|
|
1539
|
+
|
|
1540
|
+
function IntegrationExample({ brandUrl, alignment, appearance }: { brandUrl: string; alignment: 'horizontal' | 'vertical'; appearance: 'card' | 'list' }) {
|
|
1541
|
+
const t = useT()
|
|
1542
|
+
const id = React.useId()
|
|
1543
|
+
const [checked, setChecked] = React.useState(false)
|
|
1544
|
+
const [open, setOpen] = React.useState(false)
|
|
1545
|
+
const horizontal = alignment === 'horizontal'
|
|
1546
|
+
const card = appearance === 'card'
|
|
1547
|
+
return (
|
|
1548
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
1549
|
+
<div data-slot="integration-switch" data-alignment={alignment} data-appearance={appearance} className={cn('relative flex max-w-full gap-3.5', horizontal ? 'w-154 flex-wrap items-center sm:flex-nowrap' : 'w-95 flex-col items-start', card && 'rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs')}>
|
|
1550
|
+
<img src={brandUrl} alt="" className={cn('shrink-0', card ? 'size-10' : 'size-12')} />
|
|
1551
|
+
<div className={cn('flex min-w-0 flex-col gap-1', horizontal && 'min-w-40 flex-1')}>
|
|
1552
|
+
<div className="flex flex-wrap items-center gap-1.5">
|
|
1553
|
+
<span id={id} className={cn('font-medium text-foreground', card ? 'text-sm leading-5' : 'text-base leading-6')}>Microsoft Office 365</span>
|
|
1554
|
+
<Badge size={16} appearance="light" tone="info">New</Badge>
|
|
1555
|
+
</div>
|
|
1556
|
+
<p className={cn('text-muted-foreground', card ? 'text-xs leading-4' : 'text-sm leading-5')}>Seamless collaboration and document management.</p>
|
|
1557
|
+
</div>
|
|
1558
|
+
<Button asChild variant="outline" size="default" className={horizontal ? undefined : 'w-full'}><DialogTrigger><Settings aria-hidden="true" />Manage</DialogTrigger></Button>
|
|
1559
|
+
<Switch aria-labelledby={id} checked={checked} onCheckedChange={setChecked} className={horizontal ? undefined : card ? 'absolute top-5 right-5' : 'absolute top-3 right-3'} />
|
|
1560
|
+
</div>
|
|
1561
|
+
<DialogContent onKeyDownCapture={event => { if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) { event.preventDefault(); setOpen(false) } }}>
|
|
1562
|
+
<DialogHeader><DialogTitle>Microsoft Office 365 settings</DialogTitle><DialogDescription>Seamless collaboration and document management.</DialogDescription></DialogHeader>
|
|
1563
|
+
<SwitchField label="Enable integration" checked={checked} onCheckedChange={setChecked} />
|
|
1564
|
+
<DialogFooter><Button variant="outline" onClick={() => setOpen(false)}>{t('common.close')}</Button></DialogFooter>
|
|
1565
|
+
</DialogContent>
|
|
1566
|
+
</Dialog>
|
|
1567
|
+
)
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
<IntegrationExample brandUrl={brandUrl} alignment="vertical" appearance="card" />`,
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
id: 'integration-vertical-list',
|
|
1574
|
+
title: 'Integration / vertical / list',
|
|
1575
|
+
render: () => <IntegrationSwitchDemo alignment="vertical" appearance="list" />,
|
|
1576
|
+
code: `import * as React from 'react'
|
|
1577
|
+
import { Settings } from 'lucide-react'
|
|
1578
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
1579
|
+
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
1580
|
+
import { SwitchField } from '@open-mercato/ui/primitives/switch-field'
|
|
1581
|
+
import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
1582
|
+
import { Badge } from '@open-mercato/ui/primitives/badge'
|
|
1583
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
1584
|
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@open-mercato/ui/primitives/dialog'
|
|
1585
|
+
|
|
1586
|
+
function IntegrationExample({ brandUrl, alignment, appearance }: { brandUrl: string; alignment: 'horizontal' | 'vertical'; appearance: 'card' | 'list' }) {
|
|
1587
|
+
const t = useT()
|
|
1588
|
+
const id = React.useId()
|
|
1589
|
+
const [checked, setChecked] = React.useState(false)
|
|
1590
|
+
const [open, setOpen] = React.useState(false)
|
|
1591
|
+
const horizontal = alignment === 'horizontal'
|
|
1592
|
+
const card = appearance === 'card'
|
|
1593
|
+
return (
|
|
1594
|
+
<Dialog open={open} onOpenChange={setOpen}>
|
|
1595
|
+
<div data-slot="integration-switch" data-alignment={alignment} data-appearance={appearance} className={cn('relative flex max-w-full gap-3.5', horizontal ? 'w-154 flex-wrap items-center sm:flex-nowrap' : 'w-95 flex-col items-start', card && 'rounded-selection-card bg-background p-4 ring-1 ring-inset ring-border shadow-xs')}>
|
|
1596
|
+
<img src={brandUrl} alt="" className={cn('shrink-0', card ? 'size-10' : 'size-12')} />
|
|
1597
|
+
<div className={cn('flex min-w-0 flex-col gap-1', horizontal && 'min-w-40 flex-1')}>
|
|
1598
|
+
<div className="flex flex-wrap items-center gap-1.5">
|
|
1599
|
+
<span id={id} className={cn('font-medium text-foreground', card ? 'text-sm leading-5' : 'text-base leading-6')}>Microsoft Office 365</span>
|
|
1600
|
+
<Badge size={16} appearance="light" tone="info">New</Badge>
|
|
1601
|
+
</div>
|
|
1602
|
+
<p className={cn('text-muted-foreground', card ? 'text-xs leading-4' : 'text-sm leading-5')}>Seamless collaboration and document management.</p>
|
|
1603
|
+
</div>
|
|
1604
|
+
<Button asChild variant="outline" size="default" className={horizontal ? undefined : 'w-full'}><DialogTrigger><Settings aria-hidden="true" />Manage</DialogTrigger></Button>
|
|
1605
|
+
<Switch aria-labelledby={id} checked={checked} onCheckedChange={setChecked} className={horizontal ? undefined : card ? 'absolute top-5 right-5' : 'absolute top-3 right-3'} />
|
|
1606
|
+
</div>
|
|
1607
|
+
<DialogContent onKeyDownCapture={event => { if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) { event.preventDefault(); setOpen(false) } }}>
|
|
1608
|
+
<DialogHeader><DialogTitle>Microsoft Office 365 settings</DialogTitle><DialogDescription>Seamless collaboration and document management.</DialogDescription></DialogHeader>
|
|
1609
|
+
<SwitchField label="Enable integration" checked={checked} onCheckedChange={setChecked} />
|
|
1610
|
+
<DialogFooter><Button variant="outline" onClick={() => setOpen(false)}>{t('common.close')}</Button></DialogFooter>
|
|
1611
|
+
</DialogContent>
|
|
1612
|
+
</Dialog>
|
|
1613
|
+
)
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
<IntegrationExample brandUrl={brandUrl} alignment="vertical" appearance="list" />`,
|
|
1617
|
+
},
|
|
924
1618
|
],
|
|
925
1619
|
}
|
|
926
1620
|
|
|
1621
|
+
function SliderValueDemo({ initialValues }: { initialValues: number[] }) {
|
|
1622
|
+
const t = useT()
|
|
1623
|
+
const id = React.useId()
|
|
1624
|
+
const [values, setValues] = React.useState(initialValues)
|
|
1625
|
+
const range = values.length === 2
|
|
1626
|
+
return <div className="flex w-72 max-w-full flex-col gap-1">
|
|
1627
|
+
<div className="flex items-center justify-between gap-2 text-xs">
|
|
1628
|
+
<span id={id}>{t(range ? 'design_system.gallery.examples.controls.range' : 'design_system.gallery.examples.controls.value')}</span>
|
|
1629
|
+
<output className="text-muted-foreground">{values.join(' – ')}</output>
|
|
1630
|
+
</div>
|
|
1631
|
+
<Slider value={values} onValueChange={setValues} min={0} max={100} className="h-4" aria-labelledby={id}
|
|
1632
|
+
thumbLabels={range ? [t('design_system.gallery.examples.controls.lower'), t('design_system.gallery.examples.controls.upper')] : undefined} />
|
|
1633
|
+
</div>
|
|
1634
|
+
}
|
|
1635
|
+
|
|
927
1636
|
const sliderEntry: GalleryEntry = {
|
|
928
1637
|
id: 'slider',
|
|
1638
|
+
figmaNodeId: '2617:1169',
|
|
929
1639
|
title: 'Slider',
|
|
930
1640
|
importPath: '@open-mercato/ui/primitives/slider',
|
|
931
1641
|
variants: [
|
|
932
1642
|
{
|
|
933
1643
|
id: 'single',
|
|
934
1644
|
title: 'Single value',
|
|
935
|
-
render: () =>
|
|
936
|
-
<div className="w-72">
|
|
937
|
-
<Slider defaultValue={[40]} min={0} max={100} step={5} aria-label="Discount" />
|
|
938
|
-
</div>
|
|
939
|
-
),
|
|
1645
|
+
render: () => <SliderInputsSingleSample />,
|
|
940
1646
|
code: `import { Slider } from '@open-mercato/ui/primitives/slider'
|
|
941
1647
|
|
|
942
1648
|
<Slider defaultValue={[40]} min={0} max={100} step={5} aria-label="Discount" />`,
|
|
@@ -944,11 +1650,7 @@ const sliderEntry: GalleryEntry = {
|
|
|
944
1650
|
{
|
|
945
1651
|
id: 'range',
|
|
946
1652
|
title: 'Range (two thumbs)',
|
|
947
|
-
render: () =>
|
|
948
|
-
<div className="w-72">
|
|
949
|
-
<Slider defaultValue={[20, 60]} min={0} max={100} aria-label="Price range" />
|
|
950
|
-
</div>
|
|
951
|
-
),
|
|
1653
|
+
render: () => <SliderInputsRangeSample />,
|
|
952
1654
|
code: `import { Slider } from '@open-mercato/ui/primitives/slider'
|
|
953
1655
|
|
|
954
1656
|
<Slider defaultValue={[20, 60]} min={0} max={100} aria-label="Price range" />`,
|
|
@@ -956,16 +1658,58 @@ const sliderEntry: GalleryEntry = {
|
|
|
956
1658
|
{
|
|
957
1659
|
id: 'disabled',
|
|
958
1660
|
title: 'Disabled',
|
|
959
|
-
render: () =>
|
|
960
|
-
<div className="w-72">
|
|
961
|
-
<Slider defaultValue={[45]} disabled aria-label="Disabled slider" />
|
|
962
|
-
</div>
|
|
963
|
-
),
|
|
1661
|
+
render: () => <SliderInputsDisabledSample />,
|
|
964
1662
|
code: `import { Slider } from '@open-mercato/ui/primitives/slider'
|
|
965
1663
|
|
|
966
1664
|
<Slider defaultValue={[45]} disabled />`,
|
|
967
1665
|
},
|
|
968
|
-
|
|
1666
|
+
{
|
|
1667
|
+
id: 'source-values',
|
|
1668
|
+
title: 'Source values · 0 / 25 / 50 / 75 / 100',
|
|
1669
|
+
render: () => <div className="flex w-full flex-wrap gap-6">{[0, 25, 50, 75, 100].map(value => <SliderValueDemo key={value} initialValues={[value]} />)}</div>,
|
|
1670
|
+
code: `import * as React from 'react'
|
|
1671
|
+
import { Slider } from '@open-mercato/ui/primitives/slider'
|
|
1672
|
+
|
|
1673
|
+
function SliderValueDemo({ initialValues }: { initialValues: number[] }) {
|
|
1674
|
+
const id = React.useId()
|
|
1675
|
+
const [values, setValues] = React.useState(initialValues)
|
|
1676
|
+
const range = values.length === 2
|
|
1677
|
+
return <div className="flex w-72 max-w-full flex-col gap-1">
|
|
1678
|
+
<div className="flex items-center justify-between gap-2 text-xs">
|
|
1679
|
+
<span id={id}>{range ? 'Range' : 'Value'}</span>
|
|
1680
|
+
<output className="text-muted-foreground">{values.join(' – ')}</output>
|
|
1681
|
+
</div>
|
|
1682
|
+
<Slider value={values} onValueChange={setValues} min={0} max={100} className="h-4" aria-labelledby={id}
|
|
1683
|
+
thumbLabels={range ? ['Lower value', 'Upper value'] : undefined} />
|
|
1684
|
+
</div>
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
<div className="flex w-full flex-wrap gap-6">{[0, 25, 50, 75, 100].map(value => <SliderValueDemo key={value} initialValues={[value]} />)}</div>`,
|
|
1688
|
+
},
|
|
1689
|
+
{
|
|
1690
|
+
id: 'source-ranges',
|
|
1691
|
+
title: 'Source ranges · 11 pairs',
|
|
1692
|
+
render: () => <div className="flex w-full flex-wrap gap-6">{[[0, 0], [0, 25], [25, 50], [50, 75], [75, 100], [0, 50], [25, 75], [50, 100], [0, 75], [25, 100], [0, 100]].map(values => <SliderValueDemo key={values.join("-")} initialValues={values} />)}</div>,
|
|
1693
|
+
code: `import * as React from 'react'
|
|
1694
|
+
import { Slider } from '@open-mercato/ui/primitives/slider'
|
|
1695
|
+
|
|
1696
|
+
function SliderValueDemo({ initialValues }: { initialValues: number[] }) {
|
|
1697
|
+
const id = React.useId()
|
|
1698
|
+
const [values, setValues] = React.useState(initialValues)
|
|
1699
|
+
const range = values.length === 2
|
|
1700
|
+
return <div className="flex w-72 max-w-full flex-col gap-1">
|
|
1701
|
+
<div className="flex items-center justify-between gap-2 text-xs">
|
|
1702
|
+
<span id={id}>{range ? 'Range' : 'Value'}</span>
|
|
1703
|
+
<output className="text-muted-foreground">{values.join(' – ')}</output>
|
|
1704
|
+
</div>
|
|
1705
|
+
<Slider value={values} onValueChange={setValues} min={0} max={100} className="h-4" aria-labelledby={id}
|
|
1706
|
+
thumbLabels={range ? ['Lower value', 'Upper value'] : undefined} />
|
|
1707
|
+
</div>
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
<div className="flex w-full flex-wrap gap-6">{[[0, 0], [0, 25], [25, 50], [50, 75], [75, 100], [0, 50], [25, 75], [50, 100], [0, 75], [25, 100], [0, 100]].map(values => <SliderValueDemo key={values.join("-")} initialValues={values} />)}</div>`,
|
|
1711
|
+
},
|
|
1712
|
+
],
|
|
969
1713
|
}
|
|
970
1714
|
|
|
971
1715
|
const formFieldEntry: GalleryEntry = {
|
|
@@ -976,13 +1720,7 @@ const formFieldEntry: GalleryEntry = {
|
|
|
976
1720
|
{
|
|
977
1721
|
id: 'default',
|
|
978
1722
|
title: 'Label + description',
|
|
979
|
-
render: () =>
|
|
980
|
-
<div className="w-72">
|
|
981
|
-
<FormField label="Warehouse code" description="Short identifier used on labels.">
|
|
982
|
-
<Input placeholder="WAW-01" />
|
|
983
|
-
</FormField>
|
|
984
|
-
</div>
|
|
985
|
-
),
|
|
1723
|
+
render: () => <FormFieldInputsDefaultSample />,
|
|
986
1724
|
code: `import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
987
1725
|
import { Input } from '@open-mercato/ui/primitives/input'
|
|
988
1726
|
|
|
@@ -993,13 +1731,7 @@ import { Input } from '@open-mercato/ui/primitives/input'
|
|
|
993
1731
|
{
|
|
994
1732
|
id: 'required',
|
|
995
1733
|
title: 'Required',
|
|
996
|
-
render: () =>
|
|
997
|
-
<div className="w-72">
|
|
998
|
-
<FormField label="Company name" required>
|
|
999
|
-
<Input placeholder="Acme sp. z o.o." />
|
|
1000
|
-
</FormField>
|
|
1001
|
-
</div>
|
|
1002
|
-
),
|
|
1734
|
+
render: () => <FormFieldInputsRequiredSample />,
|
|
1003
1735
|
code: `import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
1004
1736
|
import { Input } from '@open-mercato/ui/primitives/input'
|
|
1005
1737
|
|
|
@@ -1010,13 +1742,7 @@ import { Input } from '@open-mercato/ui/primitives/input'
|
|
|
1010
1742
|
{
|
|
1011
1743
|
id: 'error',
|
|
1012
1744
|
title: 'Error',
|
|
1013
|
-
render: () =>
|
|
1014
|
-
<div className="w-72">
|
|
1015
|
-
<FormField label="VAT ID" error="VAT ID must have 10 digits.">
|
|
1016
|
-
<Input defaultValue="52601" />
|
|
1017
|
-
</FormField>
|
|
1018
|
-
</div>
|
|
1019
|
-
),
|
|
1745
|
+
render: () => <FormFieldInputsErrorSample />,
|
|
1020
1746
|
code: `import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
1021
1747
|
import { Input } from '@open-mercato/ui/primitives/input'
|
|
1022
1748
|
|
|
@@ -1027,13 +1753,7 @@ import { Input } from '@open-mercato/ui/primitives/input'
|
|
|
1027
1753
|
{
|
|
1028
1754
|
id: 'horizontal',
|
|
1029
1755
|
title: 'Horizontal',
|
|
1030
|
-
render: () =>
|
|
1031
|
-
<div className="w-72">
|
|
1032
|
-
<FormField label="Enable webhooks" orientation="horizontal">
|
|
1033
|
-
<Switch defaultChecked />
|
|
1034
|
-
</FormField>
|
|
1035
|
-
</div>
|
|
1036
|
-
),
|
|
1756
|
+
render: () => <FormFieldInputsHorizontalSample />,
|
|
1037
1757
|
code: `import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
1038
1758
|
import { Switch } from '@open-mercato/ui/primitives/switch'
|
|
1039
1759
|
|
|
@@ -1067,6 +1787,19 @@ const [query, setQuery] = React.useState('')
|
|
|
1067
1787
|
|
|
1068
1788
|
<SearchInput size="sm" value={query} onChange={setQuery} />`,
|
|
1069
1789
|
},
|
|
1790
|
+
{
|
|
1791
|
+
id: 'disabled',
|
|
1792
|
+
title: 'Disabled (clear action hidden)',
|
|
1793
|
+
render: () => <DisabledSearchInputPreview />,
|
|
1794
|
+
code: `import { SearchInput } from '@open-mercato/ui/primitives/search-input'
|
|
1795
|
+
import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
1796
|
+
|
|
1797
|
+
const [query, setQuery] = React.useState('OM-2026-0042')
|
|
1798
|
+
|
|
1799
|
+
<FormField label="Search orders" disabled>
|
|
1800
|
+
<SearchInput value={query} onChange={setQuery} />
|
|
1801
|
+
</FormField>`,
|
|
1802
|
+
},
|
|
1070
1803
|
],
|
|
1071
1804
|
}
|
|
1072
1805
|
|
|
@@ -1114,6 +1847,109 @@ const emailInputEntry: GalleryEntry = {
|
|
|
1114
1847
|
],
|
|
1115
1848
|
}
|
|
1116
1849
|
|
|
1850
|
+
function PasswordStrengthDemo({ initialValue = '', interactive = false }: { initialValue?: string; interactive?: boolean }) {
|
|
1851
|
+
const t = useT()
|
|
1852
|
+
const [password, setPassword] = React.useState(initialValue)
|
|
1853
|
+
const requirements = [
|
|
1854
|
+
{ id: 'uppercase', label: t('design_system.gallery.samples.passwordStrength.uppercase'), met: /[A-Z]/.test(password) },
|
|
1855
|
+
{ id: 'number', label: t('design_system.gallery.samples.passwordStrength.number'), met: /[0-9]/.test(password) },
|
|
1856
|
+
{ id: 'length', label: t('design_system.gallery.samples.passwordStrength.length'), met: password.length >= 8 },
|
|
1857
|
+
]
|
|
1858
|
+
const met = requirements.filter(requirement => requirement.met).length
|
|
1859
|
+
const strength = password.length === 0 ? 'empty' : met === 3 ? 'strong' : met === 2 ? 'moderate' : 'weak'
|
|
1860
|
+
return (
|
|
1861
|
+
<div className="w-75 max-w-full">
|
|
1862
|
+
{interactive ? <PasswordInput value={password} onChange={event => setPassword(event.target.value)} aria-label={t('design_system.gallery.samples.passwordStrength.password')} /> : null}
|
|
1863
|
+
<PasswordStrength strength={strength} requirements={requirements} />
|
|
1864
|
+
</div>
|
|
1865
|
+
)
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
const passwordStrengthEntry: GalleryEntry = {
|
|
1869
|
+
id: 'password-strength',
|
|
1870
|
+
title: 'PasswordStrength',
|
|
1871
|
+
importPath: '@open-mercato/ui/primitives/password-strength',
|
|
1872
|
+
figmaNodeId: '327:8202',
|
|
1873
|
+
usage: {
|
|
1874
|
+
do: ['Supply the evaluated strength and requirements from the policy that owns the form.', 'The interactive example demonstrates the three rules shown in Figma; the visual primitive does not define authentication policy.'],
|
|
1875
|
+
},
|
|
1876
|
+
variants: [
|
|
1877
|
+
{
|
|
1878
|
+
id: 'empty',
|
|
1879
|
+
title: 'empty',
|
|
1880
|
+
render: () => <PasswordStrengthDemo initialValue="" />,
|
|
1881
|
+
code: `import { PasswordStrength } from '@open-mercato/ui/primitives/password-strength'
|
|
1882
|
+
|
|
1883
|
+
|
|
1884
|
+
<PasswordStrength strength="empty" requirements={[
|
|
1885
|
+
{ id: 'uppercase', label: 'At least 1 uppercase', met: false },
|
|
1886
|
+
{ id: 'number', label: 'At least 1 number', met: false },
|
|
1887
|
+
{ id: 'length', label: 'At least 8 characters', met: false },
|
|
1888
|
+
]} />`,
|
|
1889
|
+
},
|
|
1890
|
+
{
|
|
1891
|
+
id: 'weak',
|
|
1892
|
+
title: 'weak',
|
|
1893
|
+
render: () => <PasswordStrengthDemo initialValue="A" />,
|
|
1894
|
+
code: `import { PasswordStrength } from '@open-mercato/ui/primitives/password-strength'
|
|
1895
|
+
|
|
1896
|
+
|
|
1897
|
+
<PasswordStrength strength="weak" requirements={[
|
|
1898
|
+
{ id: 'uppercase', label: 'At least 1 uppercase', met: true },
|
|
1899
|
+
{ id: 'number', label: 'At least 1 number', met: false },
|
|
1900
|
+
{ id: 'length', label: 'At least 8 characters', met: false },
|
|
1901
|
+
]} />`,
|
|
1902
|
+
},
|
|
1903
|
+
{
|
|
1904
|
+
id: 'moderate',
|
|
1905
|
+
title: 'moderate',
|
|
1906
|
+
render: () => <PasswordStrengthDemo initialValue="A1" />,
|
|
1907
|
+
code: `import { PasswordStrength } from '@open-mercato/ui/primitives/password-strength'
|
|
1908
|
+
|
|
1909
|
+
|
|
1910
|
+
<PasswordStrength strength="moderate" requirements={[
|
|
1911
|
+
{ id: 'uppercase', label: 'At least 1 uppercase', met: true },
|
|
1912
|
+
{ id: 'number', label: 'At least 1 number', met: true },
|
|
1913
|
+
{ id: 'length', label: 'At least 8 characters', met: false },
|
|
1914
|
+
]} />`,
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
id: 'strong',
|
|
1918
|
+
title: 'strong',
|
|
1919
|
+
render: () => <PasswordStrengthDemo initialValue="A1234567" />,
|
|
1920
|
+
code: `import { PasswordStrength } from '@open-mercato/ui/primitives/password-strength'
|
|
1921
|
+
|
|
1922
|
+
|
|
1923
|
+
<PasswordStrength strength="strong" requirements={[
|
|
1924
|
+
{ id: 'uppercase', label: 'At least 1 uppercase', met: true },
|
|
1925
|
+
{ id: 'number', label: 'At least 1 number', met: true },
|
|
1926
|
+
{ id: 'length', label: 'At least 8 characters', met: true },
|
|
1927
|
+
]} />`,
|
|
1928
|
+
},
|
|
1929
|
+
{
|
|
1930
|
+
id: 'interactive',
|
|
1931
|
+
title: 'interactive',
|
|
1932
|
+
render: () => <PasswordStrengthDemo interactive />,
|
|
1933
|
+
code: `import { PasswordStrength } from '@open-mercato/ui/primitives/password-strength'
|
|
1934
|
+
import { PasswordInput } from '@open-mercato/ui/primitives/password-input'
|
|
1935
|
+
|
|
1936
|
+
const [password, setPassword] = React.useState('')
|
|
1937
|
+
const requirements = [
|
|
1938
|
+
{ id: 'uppercase', label: 'At least 1 uppercase', met: /[A-Z]/.test(password) },
|
|
1939
|
+
{ id: 'number', label: 'At least 1 number', met: /[0-9]/.test(password) },
|
|
1940
|
+
{ id: 'length', label: 'At least 8 characters', met: password.length >= 8 },
|
|
1941
|
+
]
|
|
1942
|
+
const met = requirements.filter(requirement => requirement.met).length
|
|
1943
|
+
const strength = password.length === 0 ? 'empty' : met === 3 ? 'strong' : met === 2 ? 'moderate' : 'weak'
|
|
1944
|
+
|
|
1945
|
+
<div className="w-75 max-w-full">
|
|
1946
|
+
<PasswordInput value={password} onChange={event => setPassword(event.target.value)} aria-label="Password" />
|
|
1947
|
+
<PasswordStrength strength={strength} requirements={requirements} />
|
|
1948
|
+
</div>`,
|
|
1949
|
+
},
|
|
1950
|
+
],
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1117
1953
|
const passwordInputEntry: GalleryEntry = {
|
|
1118
1954
|
id: 'password-input',
|
|
1119
1955
|
title: 'PasswordInput',
|
|
@@ -1155,6 +1991,17 @@ const passwordInputEntry: GalleryEntry = {
|
|
|
1155
1991
|
|
|
1156
1992
|
<PasswordInput disabled />`,
|
|
1157
1993
|
},
|
|
1994
|
+
{
|
|
1995
|
+
id: 'invalid',
|
|
1996
|
+
title: 'Invalid (described error)',
|
|
1997
|
+
render: () => <InvalidPasswordInputPreview />,
|
|
1998
|
+
code: `import { PasswordInput } from '@open-mercato/ui/primitives/password-input'
|
|
1999
|
+
import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
2000
|
+
|
|
2001
|
+
<FormField label="Password" error="Use at least 12 characters.">
|
|
2002
|
+
<PasswordInput defaultValue="short" autoComplete="off" />
|
|
2003
|
+
</FormField>`,
|
|
2004
|
+
},
|
|
1158
2005
|
],
|
|
1159
2006
|
}
|
|
1160
2007
|
|
|
@@ -1225,6 +2072,19 @@ const [value, setValue] = React.useState<AmountValue>({ amount: '', currency: 'E
|
|
|
1225
2072
|
|
|
1226
2073
|
<AmountInput value={value} onChange={setValue} showCurrency={false} />`,
|
|
1227
2074
|
},
|
|
2075
|
+
{
|
|
2076
|
+
id: 'disabled',
|
|
2077
|
+
title: 'Disabled (amount and currency)',
|
|
2078
|
+
render: () => <DisabledAmountInputPreview />,
|
|
2079
|
+
code: `import { AmountInput, type AmountValue } from '@open-mercato/ui/primitives/amount-input'
|
|
2080
|
+
import { FormField } from '@open-mercato/ui/primitives/form-field'
|
|
2081
|
+
|
|
2082
|
+
const [value, setValue] = React.useState<AmountValue>({ amount: '1250.00', currency: 'EUR' })
|
|
2083
|
+
|
|
2084
|
+
<FormField label="Order total" disabled>
|
|
2085
|
+
<AmountInput value={value} onChange={setValue} />
|
|
2086
|
+
</FormField>`,
|
|
2087
|
+
},
|
|
1228
2088
|
],
|
|
1229
2089
|
}
|
|
1230
2090
|
|
|
@@ -1274,10 +2134,10 @@ const digitInputEntry: GalleryEntry = {
|
|
|
1274
2134
|
{
|
|
1275
2135
|
id: 'default',
|
|
1276
2136
|
title: 'default (6 cells)',
|
|
1277
|
-
render: () => <
|
|
2137
|
+
render: () => <DigitInputInputsDefaultSample />,
|
|
1278
2138
|
code: `import { DigitInput } from '@open-mercato/ui/primitives/digit-input'
|
|
1279
2139
|
|
|
1280
|
-
<DigitInput onComplete={(code) => verify(code)} />`,
|
|
2140
|
+
<DigitInput className="w-full gap-1 sm:w-auto sm:gap-2" cellClassName="min-w-0 w-8 flex-1 sm:w-14 sm:flex-none" onComplete={(code) => verify(code)} />`,
|
|
1281
2141
|
},
|
|
1282
2142
|
{
|
|
1283
2143
|
id: 'masked',
|
|
@@ -1290,12 +2150,7 @@ const digitInputEntry: GalleryEntry = {
|
|
|
1290
2150
|
{
|
|
1291
2151
|
id: 'states',
|
|
1292
2152
|
title: 'States',
|
|
1293
|
-
render: () =>
|
|
1294
|
-
<div className="flex flex-col gap-3">
|
|
1295
|
-
<DigitInput length={4} value="4921" aria-invalid aria-label="Invalid code" />
|
|
1296
|
-
<DigitInput length={4} disabled aria-label="Disabled code" />
|
|
1297
|
-
</div>
|
|
1298
|
-
),
|
|
2153
|
+
render: () => <DigitInputInputsStatesSample />,
|
|
1299
2154
|
code: `import { DigitInput } from '@open-mercato/ui/primitives/digit-input'
|
|
1300
2155
|
|
|
1301
2156
|
<DigitInput length={4} aria-invalid />
|
|
@@ -1338,20 +2193,7 @@ const buttonInputEntry: GalleryEntry = {
|
|
|
1338
2193
|
{
|
|
1339
2194
|
id: 'copy-link',
|
|
1340
2195
|
title: 'Copy link',
|
|
1341
|
-
render: () =>
|
|
1342
|
-
<div className="w-80">
|
|
1343
|
-
<ButtonInput
|
|
1344
|
-
readOnly
|
|
1345
|
-
defaultValue="https://app.example.com/i/8f2c"
|
|
1346
|
-
leftIcon={<Link2 />}
|
|
1347
|
-
trailingAction={
|
|
1348
|
-
<IconButton variant="ghost" aria-label="Copy link">
|
|
1349
|
-
<Copy />
|
|
1350
|
-
</IconButton>
|
|
1351
|
-
}
|
|
1352
|
-
/>
|
|
1353
|
-
</div>
|
|
1354
|
-
),
|
|
2196
|
+
render: () => <ButtonInputInputsCopyLinkSample />,
|
|
1355
2197
|
code: `import { Copy, Link2 } from 'lucide-react'
|
|
1356
2198
|
import { ButtonInput } from '@open-mercato/ui/primitives/button-input'
|
|
1357
2199
|
import { IconButton } from '@open-mercato/ui/primitives/icon-button'
|
|
@@ -1368,18 +2210,7 @@ import { IconButton } from '@open-mercato/ui/primitives/icon-button'
|
|
|
1368
2210
|
{
|
|
1369
2211
|
id: 'send',
|
|
1370
2212
|
title: 'Send action',
|
|
1371
|
-
render: () =>
|
|
1372
|
-
<div className="w-80">
|
|
1373
|
-
<ButtonInput
|
|
1374
|
-
placeholder="Invite by email"
|
|
1375
|
-
trailingAction={
|
|
1376
|
-
<IconButton variant="ghost" aria-label="Send invite">
|
|
1377
|
-
<Send />
|
|
1378
|
-
</IconButton>
|
|
1379
|
-
}
|
|
1380
|
-
/>
|
|
1381
|
-
</div>
|
|
1382
|
-
),
|
|
2213
|
+
render: () => <ButtonInputInputsSendSample />,
|
|
1383
2214
|
code: `import { Send } from 'lucide-react'
|
|
1384
2215
|
import { ButtonInput } from '@open-mercato/ui/primitives/button-input'
|
|
1385
2216
|
import { IconButton } from '@open-mercato/ui/primitives/icon-button'
|
|
@@ -1398,7 +2229,19 @@ const colorPickerEntry: GalleryEntry = {
|
|
|
1398
2229
|
id: 'color-picker',
|
|
1399
2230
|
title: 'ColorPicker',
|
|
1400
2231
|
importPath: '@open-mercato/ui/primitives/color-picker',
|
|
2232
|
+
figmaNodeId: '4415:53671',
|
|
1401
2233
|
variants: [
|
|
2234
|
+
{
|
|
2235
|
+
id: 'opacity',
|
|
2236
|
+
title: 'Opacity',
|
|
2237
|
+
render: () => <DemoColorPicker showOpacity />,
|
|
2238
|
+
code: `import { ColorPicker } from '@open-mercato/ui/primitives/color-picker'
|
|
2239
|
+
|
|
2240
|
+
const [color, setColor] = React.useState('#6366F1')
|
|
2241
|
+
const [opacity, setOpacity] = React.useState(75)
|
|
2242
|
+
|
|
2243
|
+
<ColorPicker value={color} onChange={setColor} showOpacity opacity={opacity} onOpacityChange={setOpacity} />`,
|
|
2244
|
+
},
|
|
1402
2245
|
{
|
|
1403
2246
|
id: 'default',
|
|
1404
2247
|
title: 'default',
|
|
@@ -1438,9 +2281,7 @@ const tagInputEntry: GalleryEntry = {
|
|
|
1438
2281
|
{
|
|
1439
2282
|
id: 'default',
|
|
1440
2283
|
title: 'default',
|
|
1441
|
-
render: () =>
|
|
1442
|
-
<DemoTagInput initial={['wholesale', 'priority', 'eu']} placeholder="Add tag" />
|
|
1443
|
-
),
|
|
2284
|
+
render: () => <TagInputInputsDefaultSample />,
|
|
1444
2285
|
code: `import { TagInput } from '@open-mercato/ui/primitives/tag-input'
|
|
1445
2286
|
|
|
1446
2287
|
const [tags, setTags] = React.useState<string[]>(['wholesale', 'priority', 'eu'])
|
|
@@ -1450,9 +2291,7 @@ const [tags, setTags] = React.useState<string[]>(['wholesale', 'priority', 'eu']
|
|
|
1450
2291
|
{
|
|
1451
2292
|
id: 'max-tags',
|
|
1452
2293
|
title: 'Max tags reached',
|
|
1453
|
-
render: () =>
|
|
1454
|
-
<DemoTagInput initial={['red', 'green', 'blue']} maxTags={3} placeholder="Add tag" />
|
|
1455
|
-
),
|
|
2294
|
+
render: () => <TagInputInputsMaxTagsSample />,
|
|
1456
2295
|
code: `import { TagInput } from '@open-mercato/ui/primitives/tag-input'
|
|
1457
2296
|
|
|
1458
2297
|
<TagInput value={tags} onChange={setTags} maxTags={3} />`,
|
|
@@ -1462,34 +2301,451 @@ const [tags, setTags] = React.useState<string[]>(['wholesale', 'priority', 'eu']
|
|
|
1462
2301
|
|
|
1463
2302
|
const richEditorEntry: GalleryEntry = {
|
|
1464
2303
|
id: 'rich-editor',
|
|
2304
|
+
figmaNodeId: '166926:17605',
|
|
1465
2305
|
title: 'RichEditor',
|
|
1466
2306
|
importPath: '@open-mercato/ui/primitives/rich-editor',
|
|
2307
|
+
docsAnchor: '#richeditor',
|
|
2308
|
+
usage: { do: [
|
|
2309
|
+
'toolbarDesign opts into source layouts 01–04 with 28 px controls, 20 px icons and 6 px item radii. Existing full, standard, basic and minimal presets retain their defaults.',
|
|
2310
|
+
'Every source layout includes a working More menu. Hidden commands remain available in that menu when the toolbar narrows.',
|
|
2311
|
+
'The 12-color palette already includes the source Color11 (white) and Color12 (black). Color choice changes editable content; stored HTML still passes through the existing sanitizer.',
|
|
2312
|
+
'The character counter updates while typing. onChange retains its blur contract; consumers supply translated labels and their own comment and mention workflows.',
|
|
2313
|
+
] },
|
|
2314
|
+
variants: [
|
|
2315
|
+
{ id: 'minimal', title: 'Preset / minimal', render: () => <DemoRichEditor variant="minimal" />, code: `import * as React from 'react'
|
|
2316
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2317
|
+
|
|
2318
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2319
|
+
<RichEditor value={html} onChange={setHtml} variant="minimal" />` },
|
|
2320
|
+
{ id: 'standard', title: 'Preset / standard', render: () => <DemoRichEditor variant="standard" />, code: `import * as React from 'react'
|
|
2321
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2322
|
+
|
|
2323
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2324
|
+
<RichEditor value={html} onChange={setHtml} variant="standard" />` },
|
|
2325
|
+
{ id: 'basic', title: 'Preset / basic', render: () => <DemoRichEditor variant="basic" />, code: `import * as React from 'react'
|
|
2326
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2327
|
+
|
|
2328
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2329
|
+
<RichEditor value={html} onChange={setHtml} variant="basic" />` },
|
|
2330
|
+
{ id: 'full', title: 'Preset / full', render: () => <DemoRichEditor variant="full" />, code: `import * as React from 'react'
|
|
2331
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2332
|
+
|
|
2333
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2334
|
+
<RichEditor value={html} onChange={setHtml} variant="full" />` },
|
|
2335
|
+
{ id: 'source-01', title: 'Source layout 01', render: () => <DemoRichEditor toolbarDesign="01" />, code: `import * as React from 'react'
|
|
2336
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2337
|
+
|
|
2338
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2339
|
+
<RichEditor value={html} onChange={setHtml} toolbarDesign="01" />` },
|
|
2340
|
+
{ id: 'source-02', title: 'Source layout 02', render: () => <DemoRichEditor toolbarDesign="02" />, code: `import * as React from 'react'
|
|
2341
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2342
|
+
|
|
2343
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2344
|
+
<RichEditor value={html} onChange={setHtml} toolbarDesign="02" />` },
|
|
2345
|
+
{ id: 'source-03', title: 'Source layout 03', render: () => <DemoRichEditor toolbarDesign="03" />, code: `import * as React from 'react'
|
|
2346
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2347
|
+
|
|
2348
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2349
|
+
<RichEditor value={html} onChange={setHtml} toolbarDesign="03" />` },
|
|
2350
|
+
{ id: 'source-04', title: 'Source layout 04', render: () => <DemoRichEditor toolbarDesign="04" />, code: `import * as React from 'react'
|
|
2351
|
+
import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2352
|
+
|
|
2353
|
+
const [html, setHtml] = React.useState('<p>Editable text</p>')
|
|
2354
|
+
<RichEditor value={html} onChange={setHtml} toolbarDesign="04" />` },
|
|
2355
|
+
{ id: 'disabled', title: 'Source layout / disabled', render: () => <DemoRichEditor toolbarDesign="01" disabled />, code: `import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2356
|
+
|
|
2357
|
+
<RichEditor value={html} onChange={setHtml} toolbarDesign="01" disabled />` },
|
|
2358
|
+
{ id: 'counter', title: 'Live character counter', render: () => <DemoRichEditor toolbarDesign="03" counter />, code: `import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2359
|
+
|
|
2360
|
+
<RichEditor value={html} onChange={setHtml} toolbarDesign="03" maxLength={100} />` },
|
|
2361
|
+
{ id: 'palette', title: 'All twelve source colors', render: () => <DemoRichEditorPalette />, code: `import * as React from 'react'
|
|
2362
|
+
import { RichEditorColorPalette, type RichEditorColorKey } from '@open-mercato/ui/primitives/rich-editor'
|
|
2363
|
+
|
|
2364
|
+
const [color, setColor] = React.useState<RichEditorColorKey | null>('gray')
|
|
2365
|
+
<RichEditorColorPalette value={color} onChange={setColor} />` },
|
|
2366
|
+
],
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
const fileUploadAreaEntry: GalleryEntry = {
|
|
2370
|
+
id: 'file-upload',
|
|
2371
|
+
title: 'FileUploadArea',
|
|
2372
|
+
importPath: '@open-mercato/ui/primitives/file-upload',
|
|
2373
|
+
figmaNodeId: '450:9413',
|
|
2374
|
+
docsAnchor: '#fileuploadarea',
|
|
2375
|
+
usage: { do: ['Default and hover are live states of the same drop target. Select or drop files to exercise the local demo queue.', 'Pass onFilesSelected and handle transfer separately. Demo progress is simulated locally; files never leave the browser.', 'Keep custom accept/maxSizeBytes and the description consistent.'] },
|
|
2376
|
+
variants: [
|
|
2377
|
+
{
|
|
2378
|
+
id: 'default', title: 'default',
|
|
2379
|
+
render: () => <FileUploadAreaDemo />,
|
|
2380
|
+
code: `import { FileUploadArea } from '@open-mercato/ui/primitives/file-upload'
|
|
2381
|
+
|
|
2382
|
+
<FileUploadArea onFilesSelected={handleFiles} onFilesRejected={handleRejections} />`,
|
|
2383
|
+
},
|
|
2384
|
+
{
|
|
2385
|
+
id: 'drag-and-drop', title: 'drag-and-drop',
|
|
2386
|
+
render: () => <FileUploadAreaDemo />,
|
|
2387
|
+
code: `import { FileUploadArea } from '@open-mercato/ui/primitives/file-upload'
|
|
2388
|
+
|
|
2389
|
+
<FileUploadArea onFilesSelected={handleFiles} onFilesRejected={handleRejections} />`,
|
|
2390
|
+
},
|
|
2391
|
+
{
|
|
2392
|
+
id: 'disabled', title: 'disabled',
|
|
2393
|
+
render: () => <FileUploadAreaDemo disabled />,
|
|
2394
|
+
code: `import { FileUploadArea } from '@open-mercato/ui/primitives/file-upload'
|
|
2395
|
+
|
|
2396
|
+
<FileUploadArea disabled onFilesSelected={handleFiles} onFilesRejected={handleRejections} />`,
|
|
2397
|
+
},
|
|
2398
|
+
],
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
const fileUploadCardEntry: GalleryEntry = {
|
|
2402
|
+
id: 'file-upload-card',
|
|
2403
|
+
title: 'FileUploadCard',
|
|
2404
|
+
importPath: '@open-mercato/ui/primitives/file-upload-card',
|
|
2405
|
+
figmaNodeId: '451:409',
|
|
2406
|
+
docsAnchor: '#fileuploadcard',
|
|
2407
|
+
usage: { do: ['Cancel/remove and retry are real callbacks. The error example retries using local simulated progress.', 'The caller owns transfer state, progress, and localized file-size text.'] },
|
|
2408
|
+
variants: [
|
|
2409
|
+
{
|
|
2410
|
+
id: 'uploading', title: 'uploading',
|
|
2411
|
+
render: () => <FileUploadCardDemo initialStatus="uploading" />,
|
|
2412
|
+
code: `import { FileUploadCard } from '@open-mercato/ui/primitives/file-upload-card'
|
|
2413
|
+
|
|
2414
|
+
<FileUploadCard fileName="my-cv.pdf" sizeLabel={sizeLabel} status="uploading" progress={progress} onRemove={removeFile} onRetry={retryFile} />`,
|
|
2415
|
+
},
|
|
2416
|
+
{
|
|
2417
|
+
id: 'success', title: 'success',
|
|
2418
|
+
render: () => <FileUploadCardDemo initialStatus="success" />,
|
|
2419
|
+
code: `import { FileUploadCard } from '@open-mercato/ui/primitives/file-upload-card'
|
|
2420
|
+
|
|
2421
|
+
<FileUploadCard fileName="my-cv.pdf" sizeLabel={sizeLabel} status="success" progress={progress} onRemove={removeFile} onRetry={retryFile} />`,
|
|
2422
|
+
},
|
|
2423
|
+
{
|
|
2424
|
+
id: 'error', title: 'error',
|
|
2425
|
+
render: () => <FileUploadCardDemo initialStatus="error" />,
|
|
2426
|
+
code: `import { FileUploadCard } from '@open-mercato/ui/primitives/file-upload-card'
|
|
2427
|
+
|
|
2428
|
+
<FileUploadCard fileName="my-cv.pdf" sizeLabel={sizeLabel} status="error" progress={progress} onRemove={removeFile} onRetry={retryFile} />`,
|
|
2429
|
+
},
|
|
2430
|
+
],
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
const fileFormatIconEntry: GalleryEntry = {
|
|
2434
|
+
id: 'file-format-icon',
|
|
2435
|
+
title: 'FileFormatIcon',
|
|
2436
|
+
importPath: '@open-mercato/ui/primitives/file-format-icon',
|
|
2437
|
+
figmaNodeId: '450:17234',
|
|
2438
|
+
docsAnchor: '#fileformaticon',
|
|
2439
|
+
usage: { do: ['Both sizes and all nine category colors come from Figma. Teal is the source name of the light-blue category.', 'The original Figma paper/fold artwork is bundled locally. Category-label foregrounds meet 4.5:1 contrast.'] },
|
|
2440
|
+
variants: [
|
|
2441
|
+
{
|
|
2442
|
+
id: 'red-default', title: 'red / 40px',
|
|
2443
|
+
render: () => <FileFormatIcon format="PDF" tone="red" size="default" />,
|
|
2444
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2445
|
+
|
|
2446
|
+
<FileFormatIcon format="PDF" tone="red" size="default" />`,
|
|
2447
|
+
},
|
|
2448
|
+
{
|
|
2449
|
+
id: 'orange-default', title: 'orange / 40px',
|
|
2450
|
+
render: () => <FileFormatIcon format="PDF" tone="orange" size="default" />,
|
|
2451
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2452
|
+
|
|
2453
|
+
<FileFormatIcon format="PDF" tone="orange" size="default" />`,
|
|
2454
|
+
},
|
|
2455
|
+
{
|
|
2456
|
+
id: 'yellow-default', title: 'yellow / 40px',
|
|
2457
|
+
render: () => <FileFormatIcon format="PDF" tone="yellow" size="default" />,
|
|
2458
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2459
|
+
|
|
2460
|
+
<FileFormatIcon format="PDF" tone="yellow" size="default" />`,
|
|
2461
|
+
},
|
|
2462
|
+
{
|
|
2463
|
+
id: 'green-default', title: 'green / 40px',
|
|
2464
|
+
render: () => <FileFormatIcon format="PDF" tone="green" size="default" />,
|
|
2465
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2466
|
+
|
|
2467
|
+
<FileFormatIcon format="PDF" tone="green" size="default" />`,
|
|
2468
|
+
},
|
|
2469
|
+
{
|
|
2470
|
+
id: 'teal-default', title: 'teal / 40px',
|
|
2471
|
+
render: () => <FileFormatIcon format="PDF" tone="teal" size="default" />,
|
|
2472
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2473
|
+
|
|
2474
|
+
<FileFormatIcon format="PDF" tone="teal" size="default" />`,
|
|
2475
|
+
},
|
|
2476
|
+
{
|
|
2477
|
+
id: 'blue-default', title: 'blue / 40px',
|
|
2478
|
+
render: () => <FileFormatIcon format="PDF" tone="blue" size="default" />,
|
|
2479
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2480
|
+
|
|
2481
|
+
<FileFormatIcon format="PDF" tone="blue" size="default" />`,
|
|
2482
|
+
},
|
|
2483
|
+
{
|
|
2484
|
+
id: 'purple-default', title: 'purple / 40px',
|
|
2485
|
+
render: () => <FileFormatIcon format="PDF" tone="purple" size="default" />,
|
|
2486
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2487
|
+
|
|
2488
|
+
<FileFormatIcon format="PDF" tone="purple" size="default" />`,
|
|
2489
|
+
},
|
|
2490
|
+
{
|
|
2491
|
+
id: 'pink-default', title: 'pink / 40px',
|
|
2492
|
+
render: () => <FileFormatIcon format="PDF" tone="pink" size="default" />,
|
|
2493
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2494
|
+
|
|
2495
|
+
<FileFormatIcon format="PDF" tone="pink" size="default" />`,
|
|
2496
|
+
},
|
|
2497
|
+
{
|
|
2498
|
+
id: 'gray-default', title: 'gray / 40px',
|
|
2499
|
+
render: () => <FileFormatIcon format="PDF" tone="gray" size="default" />,
|
|
2500
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2501
|
+
|
|
2502
|
+
<FileFormatIcon format="PDF" tone="gray" size="default" />`,
|
|
2503
|
+
},
|
|
2504
|
+
{
|
|
2505
|
+
id: 'red-sm', title: 'red / 32px',
|
|
2506
|
+
render: () => <FileFormatIcon format="PDF" tone="red" size="sm" />,
|
|
2507
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2508
|
+
|
|
2509
|
+
<FileFormatIcon format="PDF" tone="red" size="sm" />`,
|
|
2510
|
+
},
|
|
2511
|
+
{
|
|
2512
|
+
id: 'orange-sm', title: 'orange / 32px',
|
|
2513
|
+
render: () => <FileFormatIcon format="PDF" tone="orange" size="sm" />,
|
|
2514
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2515
|
+
|
|
2516
|
+
<FileFormatIcon format="PDF" tone="orange" size="sm" />`,
|
|
2517
|
+
},
|
|
2518
|
+
{
|
|
2519
|
+
id: 'yellow-sm', title: 'yellow / 32px',
|
|
2520
|
+
render: () => <FileFormatIcon format="PDF" tone="yellow" size="sm" />,
|
|
2521
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2522
|
+
|
|
2523
|
+
<FileFormatIcon format="PDF" tone="yellow" size="sm" />`,
|
|
2524
|
+
},
|
|
2525
|
+
{
|
|
2526
|
+
id: 'green-sm', title: 'green / 32px',
|
|
2527
|
+
render: () => <FileFormatIcon format="PDF" tone="green" size="sm" />,
|
|
2528
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2529
|
+
|
|
2530
|
+
<FileFormatIcon format="PDF" tone="green" size="sm" />`,
|
|
2531
|
+
},
|
|
2532
|
+
{
|
|
2533
|
+
id: 'teal-sm', title: 'teal / 32px',
|
|
2534
|
+
render: () => <FileFormatIcon format="PDF" tone="teal" size="sm" />,
|
|
2535
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2536
|
+
|
|
2537
|
+
<FileFormatIcon format="PDF" tone="teal" size="sm" />`,
|
|
2538
|
+
},
|
|
2539
|
+
{
|
|
2540
|
+
id: 'blue-sm', title: 'blue / 32px',
|
|
2541
|
+
render: () => <FileFormatIcon format="PDF" tone="blue" size="sm" />,
|
|
2542
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2543
|
+
|
|
2544
|
+
<FileFormatIcon format="PDF" tone="blue" size="sm" />`,
|
|
2545
|
+
},
|
|
2546
|
+
{
|
|
2547
|
+
id: 'purple-sm', title: 'purple / 32px',
|
|
2548
|
+
render: () => <FileFormatIcon format="PDF" tone="purple" size="sm" />,
|
|
2549
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2550
|
+
|
|
2551
|
+
<FileFormatIcon format="PDF" tone="purple" size="sm" />`,
|
|
2552
|
+
},
|
|
2553
|
+
{
|
|
2554
|
+
id: 'pink-sm', title: 'pink / 32px',
|
|
2555
|
+
render: () => <FileFormatIcon format="PDF" tone="pink" size="sm" />,
|
|
2556
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2557
|
+
|
|
2558
|
+
<FileFormatIcon format="PDF" tone="pink" size="sm" />`,
|
|
2559
|
+
},
|
|
2560
|
+
{
|
|
2561
|
+
id: 'gray-sm', title: 'gray / 32px',
|
|
2562
|
+
render: () => <FileFormatIcon format="PDF" tone="gray" size="sm" />,
|
|
2563
|
+
code: `import { FileFormatIcon } from '@open-mercato/ui/primitives/file-format-icon'
|
|
2564
|
+
|
|
2565
|
+
<FileFormatIcon format="PDF" tone="gray" size="sm" />`,
|
|
2566
|
+
},
|
|
2567
|
+
],
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
const imageUploadEntry: GalleryEntry = {
|
|
2571
|
+
id: 'image-upload',
|
|
2572
|
+
title: 'ImageUpload',
|
|
2573
|
+
importPath: '@open-mercato/ui/primitives/image-upload',
|
|
2574
|
+
figmaNodeId: '452:653',
|
|
2575
|
+
docsAnchor: '#imageupload',
|
|
2576
|
+
usage: { do: ['Figma calls the layout with text above actions Vertical; both source layouts place the avatar to the left.', 'New selections must decode as PNG/JPEG and meet the configured minimum dimensions (400×400 by default). The caller owns the preview URL and transfer.', 'Existing uploaded illustrations are exact source fixtures. Change and Remove update only local browser state.'] },
|
|
1467
2577
|
variants: [
|
|
1468
2578
|
{
|
|
1469
|
-
id: '
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
2579
|
+
id: 'avatar-vertical-empty', title: 'avatar / vertical / empty',
|
|
2580
|
+
render: () => <ImageUploadDemo kind="avatar" alignment="vertical" uploaded={false} />,
|
|
2581
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
2582
|
+
|
|
2583
|
+
<ImageUpload kind="avatar" alignment="vertical" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
2584
|
+
},
|
|
2585
|
+
{
|
|
2586
|
+
id: 'avatar-vertical-uploaded', title: 'avatar / vertical / uploaded',
|
|
2587
|
+
render: () => <ImageUploadDemo kind="avatar" alignment="vertical" uploaded={true} />,
|
|
2588
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
2589
|
+
|
|
2590
|
+
<ImageUpload kind="avatar" alignment="vertical" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
2591
|
+
},
|
|
2592
|
+
{
|
|
2593
|
+
id: 'avatar-horizontal-empty', title: 'avatar / horizontal / empty',
|
|
2594
|
+
render: () => <ImageUploadDemo kind="avatar" alignment="horizontal" uploaded={false} />,
|
|
2595
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
1473
2596
|
|
|
1474
|
-
|
|
2597
|
+
<ImageUpload kind="avatar" alignment="horizontal" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
2598
|
+
},
|
|
2599
|
+
{
|
|
2600
|
+
id: 'avatar-horizontal-uploaded', title: 'avatar / horizontal / uploaded',
|
|
2601
|
+
render: () => <ImageUploadDemo kind="avatar" alignment="horizontal" uploaded={true} />,
|
|
2602
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
2603
|
+
|
|
2604
|
+
<ImageUpload kind="avatar" alignment="horizontal" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
2605
|
+
},
|
|
2606
|
+
{
|
|
2607
|
+
id: 'company-vertical-empty', title: 'company / vertical / empty',
|
|
2608
|
+
render: () => <ImageUploadDemo kind="company" alignment="vertical" uploaded={false} />,
|
|
2609
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
1475
2610
|
|
|
1476
|
-
<
|
|
2611
|
+
<ImageUpload kind="company" alignment="vertical" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
1477
2612
|
},
|
|
1478
2613
|
{
|
|
1479
|
-
id: '
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
code: `import { RichEditor } from '@open-mercato/ui/primitives/rich-editor'
|
|
2614
|
+
id: 'company-vertical-uploaded', title: 'company / vertical / uploaded',
|
|
2615
|
+
render: () => <ImageUploadDemo kind="company" alignment="vertical" uploaded={true} />,
|
|
2616
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
1483
2617
|
|
|
1484
|
-
<
|
|
2618
|
+
<ImageUpload kind="company" alignment="vertical" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
2619
|
+
},
|
|
2620
|
+
{
|
|
2621
|
+
id: 'company-horizontal-empty', title: 'company / horizontal / empty',
|
|
2622
|
+
render: () => <ImageUploadDemo kind="company" alignment="horizontal" uploaded={false} />,
|
|
2623
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
2624
|
+
|
|
2625
|
+
<ImageUpload kind="company" alignment="horizontal" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
2626
|
+
},
|
|
2627
|
+
{
|
|
2628
|
+
id: 'company-horizontal-uploaded', title: 'company / horizontal / uploaded',
|
|
2629
|
+
render: () => <ImageUploadDemo kind="company" alignment="horizontal" uploaded={true} />,
|
|
2630
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
2631
|
+
|
|
2632
|
+
<ImageUpload kind="company" alignment="horizontal" src={previewUrl} alt={imageLabel} onChange={handleImageChange} />`,
|
|
2633
|
+
},
|
|
2634
|
+
{
|
|
2635
|
+
id: 'disabled', title: 'disabled',
|
|
2636
|
+
render: () => <ImageUploadDemo kind="avatar" alignment="vertical" uploaded disabled />,
|
|
2637
|
+
code: `import { ImageUpload } from '@open-mercato/ui/primitives/image-upload'
|
|
2638
|
+
|
|
2639
|
+
<ImageUpload disabled src={previewUrl} onChange={handleImageChange} />`,
|
|
1485
2640
|
},
|
|
1486
2641
|
],
|
|
1487
2642
|
}
|
|
1488
2643
|
|
|
2644
|
+
const labelEntry: GalleryEntry = {
|
|
2645
|
+
id: 'label', title: 'FieldLabel',
|
|
2646
|
+
importPath: '@open-mercato/ui/primitives/label',
|
|
2647
|
+
figmaNodeId: '266:2814',
|
|
2648
|
+
descriptionKey: 'design_system.entries.label.description',
|
|
2649
|
+
variants: [
|
|
2650
|
+
{ id: 'normal', title: 'normal', render: () => <FieldLabelExample />, code: fieldLabelCode(' sublabel="(optional)"') },
|
|
2651
|
+
{ id: 'disabled', title: 'disabled', render: () => <FieldLabelExample disabled />, code: fieldLabelCode(' disabled') },
|
|
2652
|
+
{ id: 'required', title: 'required', render: () => <FieldLabelExample kind="required" />, code: fieldLabelCode(' required') },
|
|
2653
|
+
{ id: 'optional', title: 'optional', render: () => <FieldLabelExample kind="optional" />, code: fieldLabelCode(' sublabel="(optional)"') },
|
|
2654
|
+
{ id: 'information', title: 'information', render: () => <FieldLabelExample kind="information" />, code: fieldLabelInformationCode },
|
|
2655
|
+
{ id: 'action', title: 'action', render: () => <FieldLabelExample kind="action" />, code: fieldLabelActionCode },
|
|
2656
|
+
{ id: 'form-field', title: 'form-field', render: () => <FormFieldLabelExample />, code: formFieldLabelCode },
|
|
2657
|
+
],
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
const hint_textEntry: GalleryEntry = {
|
|
2661
|
+
id: 'hint-text', title: 'HintText',
|
|
2662
|
+
importPath: '@open-mercato/ui/primitives/hint-text',
|
|
2663
|
+
figmaNodeId: '266:5284',
|
|
2664
|
+
descriptionKey: 'design_system.entries.hint-text.description',
|
|
2665
|
+
variants: [
|
|
2666
|
+
{ id: 'default', title: 'default', render: () => <HintTextExample />, code: hintTextCode() },
|
|
2667
|
+
{ id: 'error', title: 'error', render: () => <HintTextExample state="error" />, code: hintTextCode({ state: 'error' }) },
|
|
2668
|
+
{ id: 'disabled', title: 'disabled', render: () => <HintTextExample state="disabled" />, code: hintTextCode({ state: 'disabled' }) },
|
|
2669
|
+
{ id: 'text-only', title: 'text-only', render: () => <HintTextExample icon={false} />, code: hintTextCode({ icon: false }) },
|
|
2670
|
+
],
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
const marketingControlsEntry: GalleryEntry = {
|
|
2674
|
+
id: 'marketing-controls',
|
|
2675
|
+
title: 'Marketing Controls',
|
|
2676
|
+
importPath: '@open-mercato/ui/primitives/input',
|
|
2677
|
+
figmaNodeId: '6696:81119',
|
|
2678
|
+
variants: [
|
|
2679
|
+
{ id: 'product-image-1', title: 'product-image-1', render: () => <MarketingControlDemo kind="product-image" product={0} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={0} />') },
|
|
2680
|
+
{ id: 'product-image-2', title: 'product-image-2', render: () => <MarketingControlDemo kind="product-image" product={1} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={1} />') },
|
|
2681
|
+
{ id: 'product-image-3', title: 'product-image-3', render: () => <MarketingControlDemo kind="product-image" product={2} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={2} />') },
|
|
2682
|
+
{ id: 'product-image-4', title: 'product-image-4', render: () => <MarketingControlDemo kind="product-image" product={3} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={3} />') },
|
|
2683
|
+
{ id: 'product-image-5', title: 'product-image-5', render: () => <MarketingControlDemo kind="product-image" product={4} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={4} />') },
|
|
2684
|
+
{ id: 'product-image-6', title: 'product-image-6', render: () => <MarketingControlDemo kind="product-image" product={5} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={5} />') },
|
|
2685
|
+
{ id: 'product-image-7', title: 'product-image-7', render: () => <MarketingControlDemo kind="product-image" product={6} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={6} />') },
|
|
2686
|
+
{ id: 'product-image-8', title: 'product-image-8', render: () => <MarketingControlDemo kind="product-image" product={7} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={7} />') },
|
|
2687
|
+
{ id: 'product-image-9', title: 'product-image-9', render: () => <MarketingControlDemo kind="product-image" product={8} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={8} />') },
|
|
2688
|
+
{ id: 'product-image-10', title: 'product-image-10', render: () => <MarketingControlDemo kind="product-image" product={9} />, code: marketingControlExampleCode('<MarketingControlDemo kind="product-image" product={9} />') },
|
|
2689
|
+
{ id: 'step-item-default', title: 'step-item-default', render: () => <MarketingControlDemo kind="step-item" state="default" />, code: marketingControlExampleCode('<MarketingControlDemo kind="step-item" state="default" />') },
|
|
2690
|
+
{ id: 'step-item-active', title: 'step-item-active', render: () => <MarketingControlDemo kind="step-item" state="active" />, code: marketingControlExampleCode('<MarketingControlDemo kind="step-item" state="active" />') },
|
|
2691
|
+
{ id: 'step-item-complete', title: 'step-item-complete', render: () => <MarketingControlDemo kind="step-item" state="complete" />, code: marketingControlExampleCode('<MarketingControlDemo kind="step-item" state="complete" />') },
|
|
2692
|
+
{ id: 'select-default', title: 'select-default', render: () => <MarketingControlDemo kind="select" state="default" />, code: marketingControlExampleCode('<MarketingControlDemo kind="select" state="default" />') },
|
|
2693
|
+
{ id: 'select-hover', title: 'select-hover', render: () => <MarketingControlDemo kind="select" state="hover" />, code: marketingControlExampleCode('<MarketingControlDemo kind="select" state="hover" />') },
|
|
2694
|
+
{ id: 'select-active', title: 'select-active', render: () => <MarketingControlDemo kind="select" state="active" />, code: marketingControlExampleCode('<MarketingControlDemo kind="select" state="active" />') },
|
|
2695
|
+
{ id: 'select-filled', title: 'select-filled', render: () => <MarketingControlDemo kind="select" state="filled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="select" state="filled" />') },
|
|
2696
|
+
{ id: 'input-default-medium', title: 'input-default-medium', render: () => <MarketingControlDemo kind="input" state="default" size="medium" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="default" size="medium" />') },
|
|
2697
|
+
{ id: 'input-hover-medium', title: 'input-hover-medium', render: () => <MarketingControlDemo kind="input" state="hover" size="medium" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="hover" size="medium" />') },
|
|
2698
|
+
{ id: 'input-active-medium', title: 'input-active-medium', render: () => <MarketingControlDemo kind="input" state="active" size="medium" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="active" size="medium" />') },
|
|
2699
|
+
{ id: 'input-filled-medium', title: 'input-filled-medium', render: () => <MarketingControlDemo kind="input" state="filled" size="medium" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="filled" size="medium" />') },
|
|
2700
|
+
{ id: 'input-default-large', title: 'input-default-large', render: () => <MarketingControlDemo kind="input" state="default" size="large" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="default" size="large" />') },
|
|
2701
|
+
{ id: 'input-hover-large', title: 'input-hover-large', render: () => <MarketingControlDemo kind="input" state="hover" size="large" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="hover" size="large" />') },
|
|
2702
|
+
{ id: 'input-active-large', title: 'input-active-large', render: () => <MarketingControlDemo kind="input" state="active" size="large" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="active" size="large" />') },
|
|
2703
|
+
{ id: 'input-filled-large', title: 'input-filled-large', render: () => <MarketingControlDemo kind="input" state="filled" size="large" />, code: marketingControlExampleCode('<MarketingControlDemo kind="input" state="filled" size="large" />') },
|
|
2704
|
+
{ id: 'textarea-default', title: 'textarea-default', render: () => <MarketingControlDemo kind="textarea" state="default" />, code: marketingControlExampleCode('<MarketingControlDemo kind="textarea" state="default" />') },
|
|
2705
|
+
{ id: 'textarea-hover', title: 'textarea-hover', render: () => <MarketingControlDemo kind="textarea" state="hover" />, code: marketingControlExampleCode('<MarketingControlDemo kind="textarea" state="hover" />') },
|
|
2706
|
+
{ id: 'textarea-active', title: 'textarea-active', render: () => <MarketingControlDemo kind="textarea" state="active" />, code: marketingControlExampleCode('<MarketingControlDemo kind="textarea" state="active" />') },
|
|
2707
|
+
{ id: 'textarea-filled', title: 'textarea-filled', render: () => <MarketingControlDemo kind="textarea" state="filled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="textarea" state="filled" />') },
|
|
2708
|
+
{ id: 'amount-default', title: 'amount-default', render: () => <MarketingControlDemo kind="amount" state="default" />, code: marketingControlExampleCode('<MarketingControlDemo kind="amount" state="default" />') },
|
|
2709
|
+
{ id: 'amount-hover', title: 'amount-hover', render: () => <MarketingControlDemo kind="amount" state="hover" />, code: marketingControlExampleCode('<MarketingControlDemo kind="amount" state="hover" />') },
|
|
2710
|
+
{ id: 'amount-active', title: 'amount-active', render: () => <MarketingControlDemo kind="amount" state="active" />, code: marketingControlExampleCode('<MarketingControlDemo kind="amount" state="active" />') },
|
|
2711
|
+
{ id: 'amount-filled', title: 'amount-filled', render: () => <MarketingControlDemo kind="amount" state="filled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="amount" state="filled" />') },
|
|
2712
|
+
{ id: 'tab-menu-default', title: 'tab-menu-default', render: () => <MarketingControlDemo kind="tab-menu" state="default" />, code: marketingControlExampleCode('<MarketingControlDemo kind="tab-menu" state="default" />') },
|
|
2713
|
+
{ id: 'tab-menu-hover', title: 'tab-menu-hover', render: () => <MarketingControlDemo kind="tab-menu" state="hover" />, code: marketingControlExampleCode('<MarketingControlDemo kind="tab-menu" state="hover" />') },
|
|
2714
|
+
{ id: 'tab-menu-active', title: 'tab-menu-active', render: () => <MarketingControlDemo kind="tab-menu" state="active" />, code: marketingControlExampleCode('<MarketingControlDemo kind="tab-menu" state="active" />') },
|
|
2715
|
+
{ id: 'inline-input-placeholder', title: 'inline-input-placeholder', render: () => <MarketingControlDemo kind="inline-input" state="placeholder" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-input" state="placeholder" />') },
|
|
2716
|
+
{ id: 'inline-input-hover', title: 'inline-input-hover', render: () => <MarketingControlDemo kind="inline-input" state="hover" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-input" state="hover" />') },
|
|
2717
|
+
{ id: 'inline-input-focus', title: 'inline-input-focus', render: () => <MarketingControlDemo kind="inline-input" state="focus" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-input" state="focus" />') },
|
|
2718
|
+
{ id: 'inline-input-filled', title: 'inline-input-filled', render: () => <MarketingControlDemo kind="inline-input" state="filled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-input" state="filled" />') },
|
|
2719
|
+
{ id: 'inline-input-disabled', title: 'inline-input-disabled', render: () => <MarketingControlDemo kind="inline-input" state="disabled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-input" state="disabled" />') },
|
|
2720
|
+
{ id: 'inline-select-placeholder', title: 'inline-select-placeholder', render: () => <MarketingControlDemo kind="inline-select" state="placeholder" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-select" state="placeholder" />') },
|
|
2721
|
+
{ id: 'inline-select-hover', title: 'inline-select-hover', render: () => <MarketingControlDemo kind="inline-select" state="hover" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-select" state="hover" />') },
|
|
2722
|
+
{ id: 'inline-select-focus', title: 'inline-select-focus', render: () => <MarketingControlDemo kind="inline-select" state="focus" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-select" state="focus" />') },
|
|
2723
|
+
{ id: 'inline-select-filled', title: 'inline-select-filled', render: () => <MarketingControlDemo kind="inline-select" state="filled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-select" state="filled" />') },
|
|
2724
|
+
{ id: 'inline-select-disabled', title: 'inline-select-disabled', render: () => <MarketingControlDemo kind="inline-select" state="disabled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="inline-select" state="disabled" />') },
|
|
2725
|
+
{ id: 'chart-tooltip-right', title: 'chart-tooltip-right', render: () => <MarketingControlDemo kind="chart-tooltip" side="right" />, code: marketingControlExampleCode('<MarketingControlDemo kind="chart-tooltip" side="right" />') },
|
|
2726
|
+
{ id: 'chart-tooltip-left', title: 'chart-tooltip-left', render: () => <MarketingControlDemo kind="chart-tooltip" side="left" />, code: marketingControlExampleCode('<MarketingControlDemo kind="chart-tooltip" side="left" />') },
|
|
2727
|
+
{ id: 'chart-tooltip-bottom', title: 'chart-tooltip-bottom', render: () => <MarketingControlDemo kind="chart-tooltip" side="bottom" />, code: marketingControlExampleCode('<MarketingControlDemo kind="chart-tooltip" side="bottom" />') },
|
|
2728
|
+
{ id: 'chart-tooltip-top', title: 'chart-tooltip-top', render: () => <MarketingControlDemo kind="chart-tooltip" side="top" />, code: marketingControlExampleCode('<MarketingControlDemo kind="chart-tooltip" side="top" />') },
|
|
2729
|
+
{ id: 'selected-button-default', title: 'selected-button-default', render: () => <MarketingControlDemo kind="selected-button" state="default" />, code: marketingControlExampleCode('<MarketingControlDemo kind="selected-button" state="default" />') },
|
|
2730
|
+
{ id: 'selected-button-hover', title: 'selected-button-hover', render: () => <MarketingControlDemo kind="selected-button" state="hover" />, code: marketingControlExampleCode('<MarketingControlDemo kind="selected-button" state="hover" />') },
|
|
2731
|
+
{ id: 'selected-button-selected', title: 'selected-button-selected', render: () => <MarketingControlDemo kind="selected-button" state="selected" />, code: marketingControlExampleCode('<MarketingControlDemo kind="selected-button" state="selected" />') },
|
|
2732
|
+
{ id: 'selected-button-disabled', title: 'selected-button-disabled', render: () => <MarketingControlDemo kind="selected-button" state="disabled" />, code: marketingControlExampleCode('<MarketingControlDemo kind="selected-button" state="disabled" />') },
|
|
2733
|
+
],
|
|
2734
|
+
}
|
|
2735
|
+
|
|
1489
2736
|
export const entries: GalleryEntry[] = [
|
|
2737
|
+
marketingControlsEntry,
|
|
2738
|
+
labelEntry,
|
|
2739
|
+
hint_textEntry,
|
|
2740
|
+
fileUploadAreaEntry,
|
|
2741
|
+
fileUploadCardEntry,
|
|
2742
|
+
fileFormatIconEntry,
|
|
2743
|
+
imageUploadEntry,
|
|
1490
2744
|
inputEntry,
|
|
1491
2745
|
textareaEntry,
|
|
2746
|
+
phoneNumberEntry,
|
|
1492
2747
|
selectEntry,
|
|
2748
|
+
dropdownEntry,
|
|
1493
2749
|
compactSelectEntry,
|
|
1494
2750
|
inlineSelectEntry,
|
|
1495
2751
|
inlineInputEntry,
|
|
@@ -1504,6 +2760,7 @@ export const entries: GalleryEntry[] = [
|
|
|
1504
2760
|
searchInputEntry,
|
|
1505
2761
|
emailInputEntry,
|
|
1506
2762
|
passwordInputEntry,
|
|
2763
|
+
passwordStrengthEntry,
|
|
1507
2764
|
websiteInputEntry,
|
|
1508
2765
|
amountInputEntry,
|
|
1509
2766
|
counterInputEntry,
|
|
@@ -1514,3 +2771,389 @@ export const entries: GalleryEntry[] = [
|
|
|
1514
2771
|
tagInputEntry,
|
|
1515
2772
|
richEditorEntry,
|
|
1516
2773
|
]
|
|
2774
|
+
|
|
2775
|
+
function InputInputsDefaultSample() {
|
|
2776
|
+
const t = useT()
|
|
2777
|
+
return (<div className="w-72">
|
|
2778
|
+
<Input placeholder={t('design_system.gallery.samples.marketing.productName')} />
|
|
2779
|
+
</div>)
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2782
|
+
function InputInputsIconSlotsSample() {
|
|
2783
|
+
const t = useT()
|
|
2784
|
+
return (<>
|
|
2785
|
+
<div className="w-56">
|
|
2786
|
+
<Input leftIcon={<User />} placeholder={t('design_system.gallery.sampleCopy.assignee')} />
|
|
2787
|
+
</div>
|
|
2788
|
+
<div className="w-56">
|
|
2789
|
+
<Input rightIcon={<Info />} placeholder="SKU" />
|
|
2790
|
+
</div>
|
|
2791
|
+
</>)
|
|
2792
|
+
}
|
|
2793
|
+
|
|
2794
|
+
function InputInputsSizesSample() {
|
|
2795
|
+
const t = useT()
|
|
2796
|
+
return (<>
|
|
2797
|
+
<div className="w-44">
|
|
2798
|
+
<Input size="lg" placeholder={t('design_system.gallery.sampleCopy.large')} />
|
|
2799
|
+
</div>
|
|
2800
|
+
<div className="w-44">
|
|
2801
|
+
<Input size="default" placeholder={t('design_system.gallery.examples.aiProduct.default')} />
|
|
2802
|
+
</div>
|
|
2803
|
+
<div className="w-44">
|
|
2804
|
+
<Input size="sm" placeholder={t('design_system.gallery.sampleCopy.small')} />
|
|
2805
|
+
</div>
|
|
2806
|
+
</>)
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
function InputInputsStatesSample() {
|
|
2810
|
+
const t = useT()
|
|
2811
|
+
return (<>
|
|
2812
|
+
<div className="w-56">
|
|
2813
|
+
<Input aria-invalid defaultValue="not-a-number" />
|
|
2814
|
+
</div>
|
|
2815
|
+
<div className="w-56">
|
|
2816
|
+
<Input disabled placeholder={t('design_system.gallery.examples.keyComponents.disabled')} />
|
|
2817
|
+
</div>
|
|
2818
|
+
</>)
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
function TextareaInputsDefaultSample() {
|
|
2822
|
+
const t = useT()
|
|
2823
|
+
return (<div className="w-80">
|
|
2824
|
+
<Textarea placeholder={t('design_system.gallery.sampleCopy.internalNoteForTheFulfillmentTeam')} />
|
|
2825
|
+
</div>)
|
|
2826
|
+
}
|
|
2827
|
+
|
|
2828
|
+
function TextareaInputsStatesSample() {
|
|
2829
|
+
const t = useT()
|
|
2830
|
+
return (<>
|
|
2831
|
+
<div className="w-72">
|
|
2832
|
+
<Textarea aria-invalid defaultValue={t('design_system.gallery.sampleCopy.tooShort')} />
|
|
2833
|
+
</div>
|
|
2834
|
+
<div className="w-72">
|
|
2835
|
+
<Textarea disabled placeholder={t('design_system.gallery.examples.keyComponents.disabled')} />
|
|
2836
|
+
</div>
|
|
2837
|
+
</>)
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2840
|
+
function CompactSelectInputsTriggerLabelSample() {
|
|
2841
|
+
const t = useT()
|
|
2842
|
+
return (<div className="w-44">
|
|
2843
|
+
<Select defaultValue="newest">
|
|
2844
|
+
<CompactSelectTrigger triggerLabel="Sort:">
|
|
2845
|
+
<SelectValue />
|
|
2846
|
+
</CompactSelectTrigger>
|
|
2847
|
+
<SelectContent>
|
|
2848
|
+
<SelectItem value="newest">{t('design_system.gallery.sampleCopy.newest')}</SelectItem>
|
|
2849
|
+
<SelectItem value="oldest">{t('design_system.gallery.sampleCopy.oldest')}</SelectItem>
|
|
2850
|
+
<SelectItem value="value">{t('design_system.gallery.sampleCopy.highestValue')}</SelectItem>
|
|
2851
|
+
</SelectContent>
|
|
2852
|
+
</Select>
|
|
2853
|
+
</div>)
|
|
2854
|
+
}
|
|
2855
|
+
|
|
2856
|
+
function CompactSelectInputsPlainSample() {
|
|
2857
|
+
const t = useT()
|
|
2858
|
+
return (<div className="w-36">
|
|
2859
|
+
<Select defaultValue="table">
|
|
2860
|
+
<CompactSelectTrigger>
|
|
2861
|
+
<SelectValue />
|
|
2862
|
+
</CompactSelectTrigger>
|
|
2863
|
+
<SelectContent>
|
|
2864
|
+
<SelectItem value="table">{t('design_system.gallery.samples.richEditor.labels.table')}</SelectItem>
|
|
2865
|
+
<SelectItem value="board">{t('design_system.gallery.sampleCopy.board')}</SelectItem>
|
|
2866
|
+
</SelectContent>
|
|
2867
|
+
</Select>
|
|
2868
|
+
</div>)
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
function InlineSelectInputsDefaultSample() {
|
|
2872
|
+
const t = useT()
|
|
2873
|
+
return (<div className="w-40">
|
|
2874
|
+
<Select defaultValue="high">
|
|
2875
|
+
<InlineSelectTrigger>
|
|
2876
|
+
<SelectValue />
|
|
2877
|
+
</InlineSelectTrigger>
|
|
2878
|
+
<SelectContent>
|
|
2879
|
+
<SelectItem value="low">{t('design_system.gallery.samples.finance.low')}</SelectItem>
|
|
2880
|
+
<SelectItem value="medium">{t('design_system.gallery.examples.aiProduct.medium')}</SelectItem>
|
|
2881
|
+
<SelectItem value="high">{t('design_system.gallery.samples.finance.high')}</SelectItem>
|
|
2882
|
+
</SelectContent>
|
|
2883
|
+
</Select>
|
|
2884
|
+
</div>)
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
function InlineSelectInputsInvisibleSample() {
|
|
2888
|
+
const t = useT()
|
|
2889
|
+
return (<div className="w-40">
|
|
2890
|
+
<Select defaultValue="draft">
|
|
2891
|
+
<InlineSelectTrigger showBorderOnHover={false}>
|
|
2892
|
+
<SelectValue />
|
|
2893
|
+
</InlineSelectTrigger>
|
|
2894
|
+
<SelectContent>
|
|
2895
|
+
<SelectItem value="draft">{t('design_system.gallery.sampleCopy.draft')}</SelectItem>
|
|
2896
|
+
<SelectItem value="published">{t('design_system.gallery.sampleCopy.published')}</SelectItem>
|
|
2897
|
+
</SelectContent>
|
|
2898
|
+
</Select>
|
|
2899
|
+
</div>)
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
function InlineInputInputsDefaultSample() {
|
|
2903
|
+
const t = useT()
|
|
2904
|
+
return (<div className="w-56">
|
|
2905
|
+
<InlineInput defaultValue={t('design_system.gallery.sampleCopy.auroraDeskLamp')} aria-label={t('design_system.gallery.samples.marketing.productName')} />
|
|
2906
|
+
</div>)
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
function CheckboxInputsStatesSample() {
|
|
2910
|
+
const t = useT()
|
|
2911
|
+
return (<>
|
|
2912
|
+
<Checkbox aria-label={t('design_system.gallery.sampleCopy.unchecked')} />
|
|
2913
|
+
<Checkbox defaultChecked aria-label={t('design_system.gallery.sampleCopy.checked')} />
|
|
2914
|
+
<Checkbox checked="indeterminate" aria-label={t('design_system.gallery.sampleCopy.indeterminate')} />
|
|
2915
|
+
</>)
|
|
2916
|
+
}
|
|
2917
|
+
|
|
2918
|
+
function CheckboxInputsSizesSample() {
|
|
2919
|
+
const t = useT()
|
|
2920
|
+
return (<>
|
|
2921
|
+
<Checkbox size="sm" defaultChecked aria-label={t('design_system.gallery.sampleCopy.small')} />
|
|
2922
|
+
<Checkbox size="md" defaultChecked aria-label={t('design_system.gallery.examples.aiProduct.medium')} />
|
|
2923
|
+
</>)
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
function CheckboxInputsDisabledSample() {
|
|
2927
|
+
const t = useT()
|
|
2928
|
+
return (<>
|
|
2929
|
+
<Checkbox disabled aria-label={t('design_system.gallery.examples.keyComponents.disabled')} />
|
|
2930
|
+
<Checkbox disabled defaultChecked aria-label={t('design_system.gallery.sampleCopy.disabledChecked')} />
|
|
2931
|
+
</>)
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
function CheckboxFieldInputsDefaultSample() {
|
|
2935
|
+
const t = useT()
|
|
2936
|
+
return (<CheckboxField label={t('design_system.gallery.sampleCopy.emailNotifications')} defaultChecked />)
|
|
2937
|
+
}
|
|
2938
|
+
|
|
2939
|
+
function CheckboxFieldInputsWithDescriptionSample() {
|
|
2940
|
+
const t = useT()
|
|
2941
|
+
return (<div className="w-80">
|
|
2942
|
+
<CheckboxField
|
|
2943
|
+
label={t('design_system.gallery.sampleCopy.autoarchive')}
|
|
2944
|
+
sublabel="(recommended)"
|
|
2945
|
+
description={t('design_system.gallery.sampleCopy.closedConversationsMoveToTheArchiveAfter30Days')}
|
|
2946
|
+
/>
|
|
2947
|
+
</div>)
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
function CheckboxFieldInputsFlipSample() {
|
|
2951
|
+
const t = useT()
|
|
2952
|
+
return (<div className="w-72">
|
|
2953
|
+
<CheckboxField flip label={t('design_system.gallery.sampleCopy.includeShippingCosts')} defaultChecked />
|
|
2954
|
+
</div>)
|
|
2955
|
+
}
|
|
2956
|
+
|
|
2957
|
+
function RadioInputsGroupSample() {
|
|
2958
|
+
const t = useT()
|
|
2959
|
+
return (<RadioGroup defaultValue="card" className="flex-row gap-3" aria-label={t('design_system.gallery.samples.menu.kind.provider')}>
|
|
2960
|
+
<Radio value="card" aria-label={t('design_system.gallery.sampleCopy.card')} />
|
|
2961
|
+
<Radio value="transfer" aria-label={t('design_system.gallery.sampleCopy.bankTransfer')} />
|
|
2962
|
+
<Radio value="cash" aria-label={t('design_system.gallery.sampleCopy.cash')} />
|
|
2963
|
+
</RadioGroup>)
|
|
2964
|
+
}
|
|
2965
|
+
|
|
2966
|
+
function RadioInputsDisabledSample() {
|
|
2967
|
+
const t = useT()
|
|
2968
|
+
return (<RadioGroup defaultValue="a" disabled className="flex-row gap-3" aria-label={t('design_system.gallery.sampleCopy.disabledGroup')}>
|
|
2969
|
+
<Radio value="a" aria-label={t('design_system.gallery.sampleCopy.selectedDisabled')} />
|
|
2970
|
+
<Radio value="b" aria-label={t('design_system.gallery.sampleCopy.unselectedDisabled')} />
|
|
2971
|
+
</RadioGroup>)
|
|
2972
|
+
}
|
|
2973
|
+
|
|
2974
|
+
function RadioFieldInputsDefaultSample() {
|
|
2975
|
+
const t = useT()
|
|
2976
|
+
return (<RadioGroup defaultValue="standard" aria-label={t('design_system.gallery.sampleCopy.shippingSpeed')}>
|
|
2977
|
+
<RadioField value="standard" label={t('design_system.gallery.sampleCopy.standard')} />
|
|
2978
|
+
<RadioField value="express" label={t('design_system.gallery.sampleCopy.express')} />
|
|
2979
|
+
</RadioGroup>)
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
function RadioFieldInputsWithDescriptionSample() {
|
|
2983
|
+
const t = useT()
|
|
2984
|
+
return (<div className="w-80">
|
|
2985
|
+
<RadioGroup defaultValue="invoice" aria-label={t('design_system.gallery.samples.marketing.billing')}>
|
|
2986
|
+
<RadioField
|
|
2987
|
+
value="invoice"
|
|
2988
|
+
label={t('design_system.gallery.sampleCopy.invoice')}
|
|
2989
|
+
description={t('design_system.gallery.sampleCopy.payWithin14DaysOfDelivery')}
|
|
2990
|
+
/>
|
|
2991
|
+
<RadioField
|
|
2992
|
+
value="prepaid"
|
|
2993
|
+
label={t('design_system.gallery.sampleCopy.prepaid')}
|
|
2994
|
+
description={t('design_system.gallery.sampleCopy.orderShipsAfterPaymentClears')}
|
|
2995
|
+
/>
|
|
2996
|
+
</RadioGroup>
|
|
2997
|
+
</div>)
|
|
2998
|
+
}
|
|
2999
|
+
|
|
3000
|
+
function SwitchInputsStatesSample() {
|
|
3001
|
+
const t = useT()
|
|
3002
|
+
return (<>
|
|
3003
|
+
<Switch aria-label={t('design_system.gallery.sampleCopy.off')} />
|
|
3004
|
+
<Switch defaultChecked aria-label={t('design_system.gallery.sampleCopy.on')} />
|
|
3005
|
+
</>)
|
|
3006
|
+
}
|
|
3007
|
+
|
|
3008
|
+
function SwitchInputsDisabledSample() {
|
|
3009
|
+
const t = useT()
|
|
3010
|
+
return (<>
|
|
3011
|
+
<Switch disabled aria-label={t('design_system.gallery.sampleCopy.disabledOff')} />
|
|
3012
|
+
<Switch disabled defaultChecked aria-label={t('design_system.gallery.sampleCopy.disabledOn')} />
|
|
3013
|
+
</>)
|
|
3014
|
+
}
|
|
3015
|
+
|
|
3016
|
+
function SwitchFieldInputsDefaultSample() {
|
|
3017
|
+
const t = useT()
|
|
3018
|
+
return (<div className="w-72">
|
|
3019
|
+
<SwitchField label={t('design_system.gallery.sampleCopy.twofactorAuthentication')} defaultChecked />
|
|
3020
|
+
</div>)
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
function SwitchFieldInputsWithDescriptionSample() {
|
|
3024
|
+
const t = useT()
|
|
3025
|
+
return (<div className="w-80">
|
|
3026
|
+
<SwitchField
|
|
3027
|
+
label={t('design_system.gallery.sampleCopy.lowstockAlerts')}
|
|
3028
|
+
description={t('design_system.gallery.sampleCopy.notifyPurchasingWhenStockDropsBelowTheReorderPoint')}
|
|
3029
|
+
/>
|
|
3030
|
+
</div>)
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
function SwitchFieldInputsFlipSample() {
|
|
3034
|
+
const t = useT()
|
|
3035
|
+
return (<div className="w-72">
|
|
3036
|
+
<SwitchField flip label={t('design_system.gallery.sampleCopy.syncInventoryNightly')} defaultChecked />
|
|
3037
|
+
</div>)
|
|
3038
|
+
}
|
|
3039
|
+
|
|
3040
|
+
function SliderInputsSingleSample() {
|
|
3041
|
+
const t = useT()
|
|
3042
|
+
return (<div className="w-72">
|
|
3043
|
+
<Slider defaultValue={[40]} min={0} max={100} step={5} aria-label={t('design_system.gallery.sampleCopy.discount')} />
|
|
3044
|
+
</div>)
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
function SliderInputsRangeSample() {
|
|
3048
|
+
const t = useT()
|
|
3049
|
+
return (<div className="w-72">
|
|
3050
|
+
<Slider defaultValue={[20, 60]} min={0} max={100} aria-label={t('design_system.gallery.sampleCopy.priceRange')} />
|
|
3051
|
+
</div>)
|
|
3052
|
+
}
|
|
3053
|
+
|
|
3054
|
+
function SliderInputsDisabledSample() {
|
|
3055
|
+
const t = useT()
|
|
3056
|
+
return (<div className="w-72">
|
|
3057
|
+
<Slider defaultValue={[45]} disabled aria-label={t('design_system.gallery.sampleCopy.disabledSlider')} />
|
|
3058
|
+
</div>)
|
|
3059
|
+
}
|
|
3060
|
+
|
|
3061
|
+
function FormFieldInputsDefaultSample() {
|
|
3062
|
+
const t = useT()
|
|
3063
|
+
return (<div className="w-72">
|
|
3064
|
+
<FormField label={t('design_system.gallery.sampleCopy.warehouseCode')} description={t('design_system.gallery.sampleCopy.shortIdentifierUsedOnLabels')}>
|
|
3065
|
+
<Input placeholder="WAW-01" />
|
|
3066
|
+
</FormField>
|
|
3067
|
+
</div>)
|
|
3068
|
+
}
|
|
3069
|
+
|
|
3070
|
+
function FormFieldInputsRequiredSample() {
|
|
3071
|
+
const t = useT()
|
|
3072
|
+
return (<div className="w-72">
|
|
3073
|
+
<FormField label={t('design_system.gallery.sampleCopy.companyName')} required>
|
|
3074
|
+
<Input placeholder="Acme sp. z o.o." />
|
|
3075
|
+
</FormField>
|
|
3076
|
+
</div>)
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
function FormFieldInputsHorizontalSample() {
|
|
3080
|
+
const t = useT()
|
|
3081
|
+
return (<div className="w-72">
|
|
3082
|
+
<FormField label={t('design_system.gallery.sampleCopy.enableWebhooks')} orientation="horizontal">
|
|
3083
|
+
<Switch defaultChecked />
|
|
3084
|
+
</FormField>
|
|
3085
|
+
</div>)
|
|
3086
|
+
}
|
|
3087
|
+
|
|
3088
|
+
function DigitInputInputsDefaultSample() {
|
|
3089
|
+
const t = useT()
|
|
3090
|
+
return (<DigitInput aria-label={t('design_system.gallery.examples.aiProduct.verification')} className="w-full gap-1 sm:w-auto sm:gap-2" cellClassName="min-w-0 w-8 flex-1 sm:w-14 sm:flex-none" />)
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
function DigitInputInputsStatesSample() {
|
|
3094
|
+
const t = useT()
|
|
3095
|
+
return (<div className="flex flex-col gap-3">
|
|
3096
|
+
<DigitInput length={4} value="4921" aria-invalid aria-label={t('design_system.gallery.sampleCopy.invalidCode')} />
|
|
3097
|
+
<DigitInput length={4} disabled aria-label={t('design_system.gallery.sampleCopy.disabledCode')} />
|
|
3098
|
+
</div>)
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
function ButtonInputInputsCopyLinkSample() {
|
|
3102
|
+
const t = useT()
|
|
3103
|
+
return (<div className="w-80">
|
|
3104
|
+
<ButtonInput
|
|
3105
|
+
readOnly
|
|
3106
|
+
defaultValue="https://app.example.com/i/8f2c"
|
|
3107
|
+
leftIcon={<Link2 />}
|
|
3108
|
+
trailingAction={
|
|
3109
|
+
<IconButton variant="ghost" aria-label={t('design_system.gallery.sampleCopy.copyLink')}>
|
|
3110
|
+
<Copy />
|
|
3111
|
+
</IconButton>
|
|
3112
|
+
}
|
|
3113
|
+
/>
|
|
3114
|
+
</div>)
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
function ButtonInputInputsSendSample() {
|
|
3118
|
+
const t = useT()
|
|
3119
|
+
return (<div className="w-80">
|
|
3120
|
+
<ButtonInput
|
|
3121
|
+
placeholder={t('design_system.gallery.sampleCopy.inviteByEmail')}
|
|
3122
|
+
trailingAction={
|
|
3123
|
+
<IconButton variant="ghost" aria-label={t('design_system.gallery.sampleCopy.sendInvite')}>
|
|
3124
|
+
<Send />
|
|
3125
|
+
</IconButton>
|
|
3126
|
+
}
|
|
3127
|
+
/>
|
|
3128
|
+
</div>)
|
|
3129
|
+
}
|
|
3130
|
+
|
|
3131
|
+
function TagInputInputsDefaultSample() {
|
|
3132
|
+
const t = useT()
|
|
3133
|
+
return (<DemoTagInput initial={['wholesale', 'priority', 'eu']} placeholder={t('design_system.gallery.sampleCopy.addTag')} />)
|
|
3134
|
+
}
|
|
3135
|
+
|
|
3136
|
+
function TagInputInputsMaxTagsSample() {
|
|
3137
|
+
const t = useT()
|
|
3138
|
+
return (<DemoTagInput initial={['red', 'green', 'blue']} maxTags={3} placeholder={t('design_system.gallery.sampleCopy.addTag')} />)
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
function TextareaInputsCharacterCountSample() {
|
|
3142
|
+
const t = useT()
|
|
3143
|
+
return (<div className="w-80">
|
|
3144
|
+
<Textarea
|
|
3145
|
+
showCount
|
|
3146
|
+
maxLength={200}
|
|
3147
|
+
defaultValue={t('design_system.gallery.sampleCopy.customerPrefersDeliveryAfter4PM')}
|
|
3148
|
+
/>
|
|
3149
|
+
</div>)
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
function FormFieldInputsErrorSample() {
|
|
3153
|
+
const t = useT()
|
|
3154
|
+
return (<div className="w-72">
|
|
3155
|
+
<FormField label={t('design_system.gallery.sampleCopy.vatID')} error={t('design_system.gallery.sampleCopy.vatIDMustHave10Digits')}>
|
|
3156
|
+
<Input defaultValue="52601" />
|
|
3157
|
+
</FormField>
|
|
3158
|
+
</div>)
|
|
3159
|
+
}
|