-
Notifications
You must be signed in to change notification settings - Fork 0
Price and Address generic components proposal #384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@ttsahi we need to derive the locale for |
// Utility Functions | ||
// ========================================== | ||
|
||
function formatAddress(addressData: AddressData): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not taking into consideration the regional settings so it assumes en-US format,
// ========================================== | ||
|
||
function formatAddress(addressData: AddressData): string { | ||
if (addressData.formattedAddress) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even if you have formatted address it might be an issue if it was not fetched using the right locale
|
||
function formatPrice( | ||
money: Money, | ||
locale: string = 'en-US', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the locale should come from the site's regional settings
```tsx | ||
// Creating a new address form (starts empty) | ||
<Address.Root address={{ address: {}, countryList: countries }}> | ||
<Address.Form onAddressChange={setAddressData}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you discuss it with Wix Forms? do we have a use case of creating such form outside of forms?
|
||
--- | ||
|
||
### Address.FormCountrySelect |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure we should provided a headless component for this, unless we have something special with the list of countries, did we get an actual request for address form?
} | ||
>; | ||
asChild?: boolean; | ||
separator?: string; // Separator for single-line format - default ', ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be locale based, also we should probably support format options like short (shorthand country names and states), full, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you consider using any 3rd party library for this?
- [Price.Currency](#pricecurrency) | ||
- [Price.Symbol](#pricesymbol) | ||
- [Price.Formatted](#priceformatted) | ||
- [Price.CompareAt](#pricecompareat) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need all these components? these are all Stores related which are supposed to be something like
<Product.ComareAtPrice>
<Price.Formatted>
</Product.ComareAtPrice>
Also, for backward compatibility, we should have a default rendering of <Price.Formatted> in the stores price components in case they have no children/use asChild otherwise we need to provide a new set of product components because they are a defined API by now
range?: PriceRange; | ||
discount?: Discount; | ||
isOnSale?: boolean; | ||
locale?: string; // For formatting - defaults to 'en-US' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should come from regional settings if not provided
} | ||
|
||
interface Price { | ||
current: Money; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isnt this is too much stores related? is this a platformized object? with all these fields? I think that we should only stick to something that formats a Money object using regional settings and use it in components that renders money
🎯 Add Generic Price and Address Components
Overview
This PR introduces two new foundational components to the headless-components library: Price and Address. These components provide flexible, internationalized solutions for displaying monetary values and addresses across different contexts and locales.
🚀 What's New
💰 Price Component
A comprehensive price display system built with composable primitives following Radix UI architecture patterns.
Key Features:
Components:
Price.Root
- Context provider with currency service setupPrice.Amount
- Raw amount display without currency formattingPrice.Currency
- Currency symbol/code displayPrice.Formatted
- Fully formatted price with locale-aware formatting🏠 Address Component
An international address formatting system powered by @fragaria/address-formatter.
Key Features:
Components:
Address.Root
- Context provider for address dataAddress.Formatted
- Single formatted address stringAddress.Lines
- Array of address lines for custom layouts🎨 Component Architecture
Both components follow established patterns from the headless-components library:
✅ Compound Component Pattern - Composable sub-components
✅ Context-based Data Sharing - Efficient prop drilling elimination
✅ AsChild Support - Full custom rendering flexibility
✅ TypeScript Integration - Comprehensive type safety
✅ Test ID Standardization - Consistent testing approach
✅ Documentation Completeness - Full API documentation with examples
📝 Usage Examples
Basic Price Display
Custom Price Layout
International Address Display
Custom Address Layout
🛠️ Implementation Details
Price Component Integration
@wix/services-manager-react
for centralized currency/locale managementIntl.NumberFormat
for proper locale-aware number formattingAddress Component Integration
@fragaria/address-formatter
for international address standardsCode Quality
📋 Files Changed
Core Components
packages/headless-components/components/src/react/address.tsx
- Address component implementationpackages/headless-components/components/src/react/price.tsx
- Price component implementationpackages/headless-components/components/src/services/currency-service.ts
- Currency service for PriceDocumentation
docs/api/generic-components/ADDRESS_INTERFACE.md
- Complete Address API documentationdocs/api/generic-components/PRICE_INTERFACE.md
- Complete Price API documentationExamples
examples/astro-components-demo/src/components/AddressExamples.jsx
- Comprehensive Address usage examplesexamples/astro-components-demo/src/components/PriceExamples.jsx
- Comprehensive Price usage examples✅ Checklist
🎯 Impact
These components provide essential building blocks for e-commerce, booking, and other applications requiring price and address displays. They eliminate the need for custom formatting logic while ensuring international compatibility and accessibility.
This PR establishes the foundation for consistent price and address handling across all Wix headless components, with full internationalization support and flexible rendering options.