-
Notifications
You must be signed in to change notification settings - Fork 1
Price and Address generic components proposal #384
base: main
Are you sure you want to change the base?
Conversation
|
@ttsahi we need to derive the locale for |
| 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 { | ||
| money: Money; | ||
| locale?: string; // For formatting - defaults to 'en-US' | ||
| precision?: number; // Decimal places - default 2 |
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 default should be per locale, in Intl when not passing it, it is locale based
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.
That's the default, we get the locale & currency information from essentials
| } | ||
|
|
||
| function formatAmount(amount: number, precision: number = 2): string { | ||
| return amount.toFixed(precision); |
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.
you should not use precision this way, use minimumFractionDigits and maximumSignificantDigits instead, and don't default to 2 but leave undefined so by default it is based on locale
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.
Fixed
| // Address.Formatted Component Props | ||
| interface AddressFormattedProps { | ||
| children?: AsChildChildren<{ | ||
| formattedAddress: 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.
when using asChild with render props (function) also return the original address object, this way Event.Address can render formatted address by default but also allow the user to use render props with the address object instead (like parts in intl)
I would even call it parts
🎯 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-reactfor centralized currency/locale managementIntl.NumberFormatfor proper locale-aware number formattingAddress Component Integration
@fragaria/address-formatterfor 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.