@snowcone-app/ui 0.1.43 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +18 -4
- package/package.json +9 -5
- package/src/components/CanvasIsolationBoundary.tsx +202 -0
- package/src/components/LoadingOverlayPrism.tsx +251 -0
- package/src/composed/AddToCart.tsx +229 -0
- package/src/composed/ArtAlignment.tsx +703 -0
- package/src/composed/ArtSelector.tsx +290 -0
- package/src/composed/ArtworkCustomizer.tsx +212 -0
- package/src/composed/CanvasEditor.tsx +79 -0
- package/src/composed/ColorPicker.tsx +111 -0
- package/src/composed/CurrentSelectionDisplay.tsx +86 -0
- package/src/composed/HeroProductImage.tsx +1071 -0
- package/src/composed/Lightbox.index.ts +2 -0
- package/src/composed/Lightbox.tsx +230 -0
- package/src/composed/PlacementClipShapeSelector.tsx +88 -0
- package/src/composed/PlacementTabs.tsx +179 -0
- package/src/composed/ProductCard.tsx +298 -0
- package/src/composed/ProductGallery.tsx +54 -0
- package/src/composed/ProductImage.tsx +129 -0
- package/src/composed/ProductList.tsx +147 -0
- package/src/composed/ProductOptions.tsx +305 -0
- package/src/composed/RealtimeMockup.tsx +121 -0
- package/src/composed/TileCount.tsx +348 -0
- package/src/composed/carousels/HeroCarousel.tsx +240 -0
- package/src/composed/carousels/MobileProductCarousel.tsx +1002 -0
- package/src/composed/carousels/index.ts +11 -0
- package/src/composed/carousels/types.ts +58 -0
- package/src/composed/grids/MasonryGrid.tsx +238 -0
- package/src/composed/grids/index.ts +9 -0
- package/src/composed/search/CurrentRefinements.tsx +80 -0
- package/src/composed/search/Filters.tsx +49 -0
- package/src/composed/search/FiltersButton.tsx +57 -0
- package/src/composed/search/FiltersDrawer.tsx +375 -0
- package/src/composed/search/ProductGrid.tsx +118 -0
- package/src/composed/search/ProductHit.tsx +56 -0
- package/src/composed/search/SearchBox.tsx +109 -0
- package/src/composed/search/SearchProvider.tsx +136 -0
- package/src/composed/search/facetConfig.ts +16 -0
- package/src/composed/search/index.ts +22 -0
- package/src/composed/search/meilisearchAdapter.ts +20 -0
- package/src/composed/search/types.ts +22 -0
- package/src/composed/zoom/EnhancedImageViewer.tsx +505 -0
- package/src/composed/zoom/ResponsiveZoom.tsx +134 -0
- package/src/composed/zoom/ZoomOverlay.tsx +194 -0
- package/src/composed/zoom/index.ts +12 -0
- package/src/composed/zoom/types.ts +12 -0
- package/src/design-system/ColorPalette.tsx +126 -0
- package/src/design-system/ColorSwatch.tsx +49 -0
- package/src/design-system/DesignSystemPage.tsx +130 -0
- package/src/design-system/ThemeSwitcher.tsx +181 -0
- package/src/design-system/TypographyScale.tsx +106 -0
- package/src/design-system/index.ts +5 -0
- package/src/ecommerce/stories/HeroProductImage.stories.tsx +66 -0
- package/src/ecommerce/stories/PDPHeroGallery.stories.tsx +105 -0
- package/src/ecommerce/stories/PDPInfoPanel.stories.tsx +472 -0
- package/src/ecommerce/stories/PDPLayout.stories.tsx +365 -0
- package/src/hooks/useBrand.ts +41 -0
- package/src/hooks/useCanvasContext.ts +127 -0
- package/src/hooks/useDeviceDetection.ts +64 -0
- package/src/hooks/useFocusTrap.ts +70 -0
- package/src/hooks/useImagePreloader.ts +268 -0
- package/src/hooks/useImageTransition.ts +608 -0
- package/src/hooks/usePlacementsProcessor.ts +74 -0
- package/src/hooks/useProductGallery.ts +193 -0
- package/src/hooks/useProductPage.ts +467 -0
- package/src/hooks/useRenderGuard.ts +96 -0
- package/src/hooks/useScrollDirection.ts +196 -0
- package/src/hooks/viewport/index.ts +25 -0
- package/src/hooks/viewport/useContainerWidth.ts +59 -0
- package/src/hooks/viewport/useMediaQuery.ts +52 -0
- package/src/hooks/viewport/useResponsiveImageCap.ts +149 -0
- package/src/hooks/viewport/useViewportDimensions.ts +135 -0
- package/src/hooks/viewport/useWideMonitorMode.ts +150 -0
- package/src/hooks/visibility/index.ts +15 -0
- package/src/hooks/visibility/observerPool.ts +150 -0
- package/src/index.ts +240 -0
- package/src/layouts/hero-zoom/HeroShrinkLayout.tsx +209 -0
- package/src/layouts/hero-zoom/HeroZoomLayout.tsx +351 -0
- package/src/layouts/hero-zoom/index.ts +30 -0
- package/src/layouts/hero-zoom/stories/HeroZoomLayout.stories.tsx +350 -0
- package/src/layouts/hero-zoom/types.ts +113 -0
- package/src/layouts/hero-zoom/useHeroZoomScales.ts +156 -0
- package/src/layouts/index.ts +9 -0
- package/src/layouts/pdp/EdgeBlurBox.tsx +210 -0
- package/src/layouts/pdp/ImageBlurExtension.tsx +215 -0
- package/src/layouts/pdp/ImageEdgeBlur.tsx +215 -0
- package/src/layouts/pdp/PDPLayout.tsx +246 -0
- package/src/layouts/pdp/SimpleImageBlur.tsx +140 -0
- package/src/layouts/pdp/index.ts +40 -0
- package/src/lib/env.ts +15 -0
- package/src/lib/locale.ts +167 -0
- package/src/lib/router.tsx +46 -0
- package/src/lib/utils.ts +6 -0
- package/src/lightbox/README.md +77 -0
- package/src/next/index.tsx +26 -0
- package/src/patterns/MockupPriorityProvider.tsx +1014 -0
- package/src/patterns/Product.tsx +850 -0
- package/src/patterns/ProductPageProvider.tsx +224 -0
- package/src/patterns/RealtimeProvider.tsx +1162 -0
- package/src/patterns/ShopProvider.tsx +603 -0
- package/src/personalization/PersonalizationBridge.tsx +235 -0
- package/src/personalization/PersonalizationContext.ts +29 -0
- package/src/personalization/PersonalizationInputs.tsx +110 -0
- package/src/personalization/PersonalizationProvider.tsx +407 -0
- package/src/personalization/canvas-stub.d.ts +22 -0
- package/src/personalization/index.ts +43 -0
- package/src/personalization/types.ts +48 -0
- package/src/personalization/usePersonalization.ts +32 -0
- package/src/personalization/usePersonalizationShimmer.ts +159 -0
- package/src/personalization/utils.ts +59 -0
- package/src/primitives/BrandLogo.tsx +65 -0
- package/src/primitives/BrandName.tsx +51 -0
- package/src/primitives/Button.tsx +123 -0
- package/src/primitives/ColorSwatch.tsx +221 -0
- package/src/primitives/DragHintAnimation.tsx +190 -0
- package/src/primitives/EdgeSwipeGuards.tsx +60 -0
- package/src/primitives/FloatingActionGroup.tsx +176 -0
- package/src/primitives/ProductPrice.tsx +171 -0
- package/src/primitives/ProgressiveBlur.tsx +295 -0
- package/src/primitives/ThemeToggle.tsx +125 -0
- package/src/primitives/__tests__/story-coverage.test.ts +98 -0
- package/src/primitives/accordion.tsx +280 -0
- package/src/primitives/badge.tsx +137 -0
- package/src/primitives/card.tsx +61 -0
- package/src/primitives/checkbox.tsx +56 -0
- package/src/primitives/collapsible.tsx +51 -0
- package/src/primitives/drawer.tsx +828 -0
- package/src/primitives/dropdown-menu.tsx +197 -0
- package/src/primitives/fieldset.tsx +73 -0
- package/src/primitives/index.ts +138 -0
- package/src/primitives/input.tsx +91 -0
- package/src/primitives/kbd.tsx +130 -0
- package/src/primitives/label.tsx +20 -0
- package/src/primitives/link.tsx +182 -0
- package/src/primitives/popover.tsx +80 -0
- package/src/primitives/radio-group.tsx +79 -0
- package/src/primitives/scroll-fade.tsx +159 -0
- package/src/primitives/select.tsx +170 -0
- package/src/primitives/separator.tsx +25 -0
- package/src/primitives/slider.tsx +221 -0
- package/src/primitives/spinner.tsx +72 -0
- package/src/primitives/stories/Accordion.stories.tsx +121 -0
- package/src/primitives/stories/Badge.stories.tsx +221 -0
- package/src/primitives/stories/Button.stories.tsx +185 -0
- package/src/primitives/stories/Card.stories.tsx +171 -0
- package/src/primitives/stories/Checkbox.stories.tsx +214 -0
- package/src/primitives/stories/Collapsible.stories.tsx +230 -0
- package/src/primitives/stories/Drawer.stories.tsx +378 -0
- package/src/primitives/stories/DropdownMenu.stories.tsx +182 -0
- package/src/primitives/stories/Fieldset.stories.tsx +212 -0
- package/src/primitives/stories/Input.stories.tsx +172 -0
- package/src/primitives/stories/Kbd.stories.tsx +183 -0
- package/src/primitives/stories/Label.stories.tsx +98 -0
- package/src/primitives/stories/Link.stories.tsx +260 -0
- package/src/primitives/stories/Popover.stories.tsx +178 -0
- package/src/primitives/stories/RadioGroup.stories.tsx +205 -0
- package/src/primitives/stories/Select.stories.tsx +222 -0
- package/src/primitives/stories/Separator.stories.tsx +134 -0
- package/src/primitives/stories/Slider.stories.tsx +203 -0
- package/src/primitives/stories/Spinner.stories.tsx +142 -0
- package/src/primitives/stories/Surface.stories.tsx +257 -0
- package/src/primitives/stories/Switch.stories.tsx +131 -0
- package/src/primitives/stories/Tabs.stories.tsx +275 -0
- package/src/primitives/stories/TextField.stories.tsx +139 -0
- package/src/primitives/stories/Textarea.stories.tsx +148 -0
- package/src/primitives/stories/Tooltip.stories.tsx +119 -0
- package/src/primitives/surface.tsx +86 -0
- package/src/primitives/switch.tsx +35 -0
- package/src/primitives/tabs.tsx +206 -0
- package/src/primitives/text-field.tsx +84 -0
- package/src/primitives/textarea.tsx +50 -0
- package/src/primitives/tooltip.tsx +58 -0
- package/src/services/CanvasExportService.ts +518 -0
- package/src/styles/base.css +380 -0
- package/src/styles/defaults.css +280 -0
- package/src/styles/globals.css +1242 -0
- package/src/styles/index.css +17 -0
- package/src/styles/ne-themes.css +4740 -0
- package/src/styles/tailwind.css +11 -0
- package/src/styles/tokens.css +117 -0
- package/src/styles/utilities.css +188 -0
- package/src/themes/apply-theme.ts +449 -0
- package/src/themes/getThemeStyles.ts +454 -0
- package/src/themes/index.ts +48 -0
- package/src/themes/oklch-theme.ts +283 -0
- package/src/themes/presets.ts +989 -0
- package/src/themes/types.ts +386 -0
- package/src/themes/useTheme.tsx +450 -0
- package/src/utils/dev-warnings.ts +161 -0
- package/src/utils/devWarnings.ts +153 -0
- package/dist/styles.css +0 -1
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Configuration Types
|
|
3
|
+
*
|
|
4
|
+
* This is the single source of truth for theme types.
|
|
5
|
+
* Both snowcone-canvas and next-ecommerce use these same types.
|
|
6
|
+
*
|
|
7
|
+
* OKLCH-BASED THEME SYSTEM:
|
|
8
|
+
* -------------------------
|
|
9
|
+
* Themes are defined with just a few parameters (hue, chroma, isDark) and
|
|
10
|
+
* all colors are generated algorithmically. This ensures:
|
|
11
|
+
* - Consistent foreground colors (no more accidentally tinted text)
|
|
12
|
+
* - Easy theme creation (just pick a hue)
|
|
13
|
+
* - Mathematically correct color relationships
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// OKLCH THEME CONFIGURATION (Modern approach)
|
|
18
|
+
// =============================================================================
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* OKLCH-based theme configuration
|
|
22
|
+
*
|
|
23
|
+
* Define themes with just hue + chroma, and all colors are generated automatically.
|
|
24
|
+
* This is the recommended way to create new themes.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* {
|
|
28
|
+
* name: 'Purple',
|
|
29
|
+
* hue: 270, // Purple hue (0-360)
|
|
30
|
+
* chroma: 0.18, // Saturation (0-0.4)
|
|
31
|
+
* isDark: false,
|
|
32
|
+
* radiusPreset: 'soft',
|
|
33
|
+
* }
|
|
34
|
+
*/
|
|
35
|
+
export interface OklchThemeConfig {
|
|
36
|
+
/** Theme name for display */
|
|
37
|
+
name: string;
|
|
38
|
+
|
|
39
|
+
/** Primary hue (0-360). Examples: 270=purple, 220=blue, 145=green, 30=orange, 350=pink */
|
|
40
|
+
hue: number;
|
|
41
|
+
|
|
42
|
+
/** Chroma/saturation (0-0.4). Higher = more vivid. Typical: 0.12-0.22 */
|
|
43
|
+
chroma?: number;
|
|
44
|
+
|
|
45
|
+
/** Whether this is a dark theme */
|
|
46
|
+
isDark: boolean;
|
|
47
|
+
|
|
48
|
+
/** Semantic radius preset */
|
|
49
|
+
radiusPreset?: RadiusPresetId;
|
|
50
|
+
|
|
51
|
+
/** Icon stroke width preset */
|
|
52
|
+
iconStrokeWidth?: 'thin' | 'normal' | 'thick' | 'extra-thick';
|
|
53
|
+
|
|
54
|
+
/** Font family preset */
|
|
55
|
+
fontFamily?: 'sans' | 'serif' | 'mono' | 'display' | 'handwriting' | 'mixed' |
|
|
56
|
+
'montserrat-combo' | 'playfair-combo' | 'helvetica-combo';
|
|
57
|
+
|
|
58
|
+
/** Advanced font pairing configuration */
|
|
59
|
+
fontPairing?: FontPairing;
|
|
60
|
+
|
|
61
|
+
/** Override the primary color lightness (0-1). Defaults to LIGHTNESS.light.primary (0.55) or LIGHTNESS.dark.primary (0.70). Use 0.0 for pure black, 1.0 for pure white. */
|
|
62
|
+
primaryLightness?: number;
|
|
63
|
+
|
|
64
|
+
/** Name of the light variant (for dark themes) */
|
|
65
|
+
lightVariant?: string;
|
|
66
|
+
|
|
67
|
+
/** Name of the dark variant (for light themes) */
|
|
68
|
+
darkVariant?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// =============================================================================
|
|
72
|
+
// LEGACY THEME CONFIGURATION (for backwards compatibility)
|
|
73
|
+
// =============================================================================
|
|
74
|
+
|
|
75
|
+
export interface ThemeConfig {
|
|
76
|
+
/** Theme name for display */
|
|
77
|
+
name?: string;
|
|
78
|
+
|
|
79
|
+
/** Page background color (hex) */
|
|
80
|
+
backgroundColor?: string;
|
|
81
|
+
|
|
82
|
+
/** Primary accent color (hex) - used for buttons, links, focus states */
|
|
83
|
+
primaryColor?: string;
|
|
84
|
+
|
|
85
|
+
/** Secondary accent color (hex) - optional, defaults to primaryColor */
|
|
86
|
+
secondaryColor?: string;
|
|
87
|
+
|
|
88
|
+
/** Main text color (hex) */
|
|
89
|
+
textColor?: string;
|
|
90
|
+
|
|
91
|
+
/** Vibrant color for icons (hex) - optional, defaults to primaryColor */
|
|
92
|
+
iconColor?: string;
|
|
93
|
+
|
|
94
|
+
/** Accent text for light backgrounds (e.g., product detail pages) */
|
|
95
|
+
accentTextLight?: string;
|
|
96
|
+
|
|
97
|
+
/** Accent text for dark backgrounds (e.g., overlays) */
|
|
98
|
+
accentTextDark?: string;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Border radius preset (legacy simple preset)
|
|
102
|
+
* @deprecated Use `radiusPreset` for semantic radius control
|
|
103
|
+
*/
|
|
104
|
+
borderRadius?: 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Semantic radius preset - defines the "shape personality" of the theme
|
|
108
|
+
* Controls border-radius for buttons, inputs, cards, modals, etc.
|
|
109
|
+
*/
|
|
110
|
+
radiusPreset?: RadiusPresetId | RadiusConfig;
|
|
111
|
+
|
|
112
|
+
/** Icon stroke width preset */
|
|
113
|
+
iconStrokeWidth?: 'thin' | 'normal' | 'thick' | 'extra-thick';
|
|
114
|
+
|
|
115
|
+
/** Whether this is a dark theme */
|
|
116
|
+
isDark?: boolean;
|
|
117
|
+
|
|
118
|
+
/** Name of the light variant of this theme (for dark themes) */
|
|
119
|
+
lightVariant?: string;
|
|
120
|
+
|
|
121
|
+
/** Name of the dark variant of this theme (for light themes) */
|
|
122
|
+
darkVariant?: string;
|
|
123
|
+
|
|
124
|
+
/** Font family preset */
|
|
125
|
+
fontFamily?:
|
|
126
|
+
| 'sans'
|
|
127
|
+
| 'serif'
|
|
128
|
+
| 'mono'
|
|
129
|
+
| 'display'
|
|
130
|
+
| 'handwriting'
|
|
131
|
+
| 'mixed'
|
|
132
|
+
| 'montserrat-combo'
|
|
133
|
+
| 'playfair-combo'
|
|
134
|
+
| 'helvetica-combo';
|
|
135
|
+
|
|
136
|
+
/** Advanced font pairing configuration */
|
|
137
|
+
fontPairing?: FontPairing;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Font Pairing Configuration
|
|
142
|
+
*
|
|
143
|
+
* Defines the complete typography system for a theme. Theme designers can
|
|
144
|
+
* customize fonts at multiple levels of granularity:
|
|
145
|
+
*
|
|
146
|
+
* 1. **Core fonts** (required): `headingFont` and `bodyFont`
|
|
147
|
+
* 2. **Semantic roles** (optional): Override specific UI contexts
|
|
148
|
+
* 3. **Weights** (optional): Fine-tune font weights per role
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* // Minimal configuration - uses defaults for semantic roles
|
|
152
|
+
* {
|
|
153
|
+
* id: 'classic-serif',
|
|
154
|
+
* headingFont: 'Playfair Display, serif',
|
|
155
|
+
* bodyFont: 'Open Sans, sans-serif',
|
|
156
|
+
* }
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* // Full customization - luxury brand with distinct fonts per role
|
|
160
|
+
* {
|
|
161
|
+
* id: 'luxury-retail',
|
|
162
|
+
* headingFont: 'Playfair Display, serif',
|
|
163
|
+
* bodyFont: 'Cormorant, serif',
|
|
164
|
+
* labelFont: 'Montserrat, sans-serif',
|
|
165
|
+
* buttonFont: 'Montserrat, sans-serif',
|
|
166
|
+
* captionFont: 'Open Sans, sans-serif',
|
|
167
|
+
* displayFont: 'Playfair Display, serif',
|
|
168
|
+
* weights: {
|
|
169
|
+
* headingWeight: '500',
|
|
170
|
+
* displayWeight: '700',
|
|
171
|
+
* },
|
|
172
|
+
* }
|
|
173
|
+
*/
|
|
174
|
+
export interface FontPairing {
|
|
175
|
+
/** Unique identifier for this font pairing */
|
|
176
|
+
id: string;
|
|
177
|
+
|
|
178
|
+
/** Font stack for headings (h1-h6, titles) */
|
|
179
|
+
headingFont: string;
|
|
180
|
+
|
|
181
|
+
/** Font stack for body text (paragraphs, default text) */
|
|
182
|
+
bodyFont: string;
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Semantic Font Roles
|
|
186
|
+
* Override specific UI contexts with custom fonts.
|
|
187
|
+
* If not specified, defaults to bodyFont or headingFont as appropriate.
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
/** Font for form labels and field names. Defaults to bodyFont. */
|
|
191
|
+
labelFont?: string;
|
|
192
|
+
|
|
193
|
+
/** Font for button text and CTAs. Defaults to bodyFont. */
|
|
194
|
+
buttonFont?: string;
|
|
195
|
+
|
|
196
|
+
/** Font for small text, descriptions, helper text. Defaults to bodyFont. */
|
|
197
|
+
captionFont?: string;
|
|
198
|
+
|
|
199
|
+
/** Font for hero text, prices, prominent numbers. Defaults to headingFont. */
|
|
200
|
+
displayFont?: string;
|
|
201
|
+
|
|
202
|
+
/** Font for emphasis, blockquotes, pullquotes. Defaults to headingFont. */
|
|
203
|
+
accentFont?: string;
|
|
204
|
+
|
|
205
|
+
/** Font weights per role */
|
|
206
|
+
weights?: FontWeights;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Font Weights Configuration
|
|
211
|
+
*
|
|
212
|
+
* Fine-tune font weights for different text roles.
|
|
213
|
+
* All values should be valid CSS font-weight values (100-900 or keywords).
|
|
214
|
+
*/
|
|
215
|
+
export interface FontWeights {
|
|
216
|
+
/** Weight for body text. Default: '400' */
|
|
217
|
+
bodyWeight?: string;
|
|
218
|
+
|
|
219
|
+
/** Weight for headings. Default: '600' */
|
|
220
|
+
headingWeight?: string;
|
|
221
|
+
|
|
222
|
+
/** Weight for button text. Default: '500' */
|
|
223
|
+
buttonWeight?: string;
|
|
224
|
+
|
|
225
|
+
/** Weight for form labels. Default: '500' */
|
|
226
|
+
labelWeight?: string;
|
|
227
|
+
|
|
228
|
+
/** Weight for captions and small text. Default: '400' */
|
|
229
|
+
captionWeight?: string;
|
|
230
|
+
|
|
231
|
+
/** Weight for display/hero text. Default: '700' */
|
|
232
|
+
displayWeight?: string;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Theme preset with required name */
|
|
236
|
+
export type ThemePreset = ThemeConfig & { name: string };
|
|
237
|
+
|
|
238
|
+
/* =============================================================================
|
|
239
|
+
* SEMANTIC RADIUS SYSTEM
|
|
240
|
+
* =============================================================================
|
|
241
|
+
* Defines how border-radius is applied to different component types.
|
|
242
|
+
* Themes can use a preset ID (string) or a full RadiusConfig object.
|
|
243
|
+
*
|
|
244
|
+
* Built-in presets: 'default' | 'sharp' | 'soft' | 'brutalist' | 'playful'
|
|
245
|
+
*/
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Radius size tokens that can be assigned to semantic roles
|
|
249
|
+
*
|
|
250
|
+
* Maps to CSS variables:
|
|
251
|
+
* - 'none' → 0
|
|
252
|
+
* - 'sm' → var(--radius-sm) = 2px
|
|
253
|
+
* - 'md' → var(--radius-md) = 4px
|
|
254
|
+
* - 'lg' → var(--radius-lg) = 6px
|
|
255
|
+
* - 'xl' → var(--radius-xl) = 8px
|
|
256
|
+
* - '2xl' → var(--radius-2xl) = 12px
|
|
257
|
+
* - '3xl' → var(--radius-3xl) = 20px
|
|
258
|
+
* - '4xl' → var(--radius-4xl) = 24px
|
|
259
|
+
* - 'full' → var(--radius-full) = 50% (pill shape)
|
|
260
|
+
*/
|
|
261
|
+
export type RadiusSize = 'none' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | 'full';
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Built-in radius preset identifiers
|
|
265
|
+
*
|
|
266
|
+
* Each preset defines a complete "shape personality":
|
|
267
|
+
* - **default**: Balanced, professional appearance
|
|
268
|
+
* - **sharp**: Technical, precise, minimal rounding
|
|
269
|
+
* - **soft**: Friendly, approachable, heavily rounded
|
|
270
|
+
* - **brutalist**: Raw, bold, no rounding at all
|
|
271
|
+
* - **playful**: Fun, casual, varied rounding
|
|
272
|
+
*/
|
|
273
|
+
export type RadiusPresetId = 'default' | 'sharp' | 'soft' | 'brutalist' | 'playful';
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Semantic Radius Configuration
|
|
277
|
+
*
|
|
278
|
+
* Defines border-radius for each component type. Theme designers can
|
|
279
|
+
* customize any role independently for fine-grained shape control.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* // Custom e-commerce theme with pill buttons but square cards
|
|
283
|
+
* {
|
|
284
|
+
* button: 'full', // Pill-shaped buttons (trendy)
|
|
285
|
+
* input: 'lg', // Rounded inputs
|
|
286
|
+
* card: 'sm', // Subtle card rounding
|
|
287
|
+
* modal: 'lg', // Friendly modals
|
|
288
|
+
* badge: 'full', // Classic pill badges
|
|
289
|
+
* avatar: 'full', // Circular avatars
|
|
290
|
+
* tooltip: 'md', // Subtle tooltip rounding
|
|
291
|
+
* image: 'lg', // Product image rounding
|
|
292
|
+
* }
|
|
293
|
+
*/
|
|
294
|
+
export interface RadiusConfig {
|
|
295
|
+
/** Buttons, chips, toggles, action elements */
|
|
296
|
+
button?: RadiusSize;
|
|
297
|
+
|
|
298
|
+
/** Text inputs, selects, textareas, form controls */
|
|
299
|
+
input?: RadiusSize;
|
|
300
|
+
|
|
301
|
+
/** Cards, panels, surfaces, containers */
|
|
302
|
+
card?: RadiusSize;
|
|
303
|
+
|
|
304
|
+
/** Modals, dialogs, sheets, drawers */
|
|
305
|
+
modal?: RadiusSize;
|
|
306
|
+
|
|
307
|
+
/** Badges, tags, status indicators, labels */
|
|
308
|
+
badge?: RadiusSize;
|
|
309
|
+
|
|
310
|
+
/** Avatars, profile images, user icons */
|
|
311
|
+
avatar?: RadiusSize;
|
|
312
|
+
|
|
313
|
+
/** Tooltips, popovers, dropdown menus */
|
|
314
|
+
tooltip?: RadiusSize;
|
|
315
|
+
|
|
316
|
+
/** Product images, thumbnails, media containers */
|
|
317
|
+
image?: RadiusSize;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Built-in radius presets
|
|
322
|
+
*
|
|
323
|
+
* These define complete "shape personalities" that can be applied
|
|
324
|
+
* with a single string identifier.
|
|
325
|
+
*/
|
|
326
|
+
export const RADIUS_PRESETS: Record<RadiusPresetId, Required<RadiusConfig>> = {
|
|
327
|
+
/** Balanced, professional - the safe default */
|
|
328
|
+
default: {
|
|
329
|
+
button: 'md',
|
|
330
|
+
input: 'md',
|
|
331
|
+
card: 'lg',
|
|
332
|
+
modal: 'xl',
|
|
333
|
+
badge: 'full',
|
|
334
|
+
avatar: 'full',
|
|
335
|
+
tooltip: 'lg', // Visible rounding for tooltips, popovers, dropdown menus
|
|
336
|
+
image: 'md',
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
/** Technical, precise - minimal rounding for professional tools */
|
|
340
|
+
sharp: {
|
|
341
|
+
button: 'sm',
|
|
342
|
+
input: 'sm',
|
|
343
|
+
card: 'sm',
|
|
344
|
+
modal: 'md',
|
|
345
|
+
badge: 'sm',
|
|
346
|
+
avatar: 'md',
|
|
347
|
+
tooltip: 'none',
|
|
348
|
+
image: 'sm',
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
/** Friendly, approachable - heavy rounding for consumer apps */
|
|
352
|
+
soft: {
|
|
353
|
+
button: 'full',
|
|
354
|
+
input: 'xl',
|
|
355
|
+
card: '2xl',
|
|
356
|
+
modal: '3xl',
|
|
357
|
+
badge: 'full',
|
|
358
|
+
avatar: 'full',
|
|
359
|
+
tooltip: 'lg',
|
|
360
|
+
image: 'xl',
|
|
361
|
+
},
|
|
362
|
+
|
|
363
|
+
/** Raw, bold - no rounding for maximum impact */
|
|
364
|
+
brutalist: {
|
|
365
|
+
button: 'none',
|
|
366
|
+
input: 'none',
|
|
367
|
+
card: 'none',
|
|
368
|
+
modal: 'none',
|
|
369
|
+
badge: 'none',
|
|
370
|
+
avatar: 'none',
|
|
371
|
+
tooltip: 'none',
|
|
372
|
+
image: 'none',
|
|
373
|
+
},
|
|
374
|
+
|
|
375
|
+
/** Fun, casual - varied rounding for personality */
|
|
376
|
+
playful: {
|
|
377
|
+
button: '2xl',
|
|
378
|
+
input: 'xl',
|
|
379
|
+
card: '3xl',
|
|
380
|
+
modal: '3xl',
|
|
381
|
+
badge: 'full',
|
|
382
|
+
avatar: 'full',
|
|
383
|
+
tooltip: 'xl',
|
|
384
|
+
image: '2xl',
|
|
385
|
+
},
|
|
386
|
+
};
|