@pixelated-tech/components 3.2.14 → 3.3.1
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/README.COMPONENTS.md +520 -31
- package/README.md +163 -49
- package/dist/components/cms/cloudinary.image.js +1 -0
- package/dist/components/cms/wordpress.components.js +1 -0
- package/dist/components/general/sidepanel.js +1 -1
- package/dist/components/general/tab.css +105 -0
- package/dist/components/general/tab.js +26 -0
- package/dist/components/menu/menu-accordion.css +10 -0
- package/dist/components/menu/menu-accordion.js +2 -1
- package/dist/components/menu/menu-simple.css +0 -7
- package/dist/components/seo/metadata.components.js +0 -19
- package/dist/components/seo/metadata.functions.js +111 -0
- package/dist/components/seo/schema-blogposting.functions.js +42 -0
- package/dist/components/seo/schema-blogposting.js +0 -46
- package/dist/components/seo/sitemap.js +1 -1
- package/dist/components/shoppingcart/shoppingcart.components.js +4 -4
- package/dist/components/sitebuilder/config/CompoundFontSelector.css +25 -0
- package/dist/components/sitebuilder/config/CompoundFontSelector.js +41 -0
- package/dist/components/sitebuilder/config/ConfigBuilder.css +277 -0
- package/dist/components/sitebuilder/config/ConfigBuilder.js +380 -0
- package/dist/components/sitebuilder/config/ConfigEngine.js +82 -0
- package/dist/components/sitebuilder/config/FontSelector.css +82 -0
- package/dist/components/sitebuilder/config/FontSelector.js +115 -0
- package/dist/components/sitebuilder/config/google-fonts.js +112 -0
- package/dist/components/{pagebuilder → sitebuilder}/form/form.css +55 -34
- package/dist/components/sitebuilder/form/formbuilder.js +107 -0
- package/dist/components/sitebuilder/form/formcomponents.js +380 -0
- package/dist/components/sitebuilder/form/formengine.js +82 -0
- package/dist/components/{pagebuilder/form/form.js → sitebuilder/form/formextractor.js} +10 -211
- package/dist/components/sitebuilder/form/formutils.js +206 -0
- package/dist/components/sitebuilder/form/formvalidator.js +123 -0
- package/dist/components/{pagebuilder → sitebuilder/page}/components/ComponentPropertiesForm.js +1 -1
- package/dist/components/{pagebuilder → sitebuilder/page}/components/PageBuilderUI.js +2 -2
- package/dist/components/{pagebuilder → sitebuilder/page}/components/PageEngine.js +1 -1
- package/dist/components/sitebuilder/page/documentation/api-examples/save-route-example.js +37 -0
- package/dist/components/{pagebuilder → sitebuilder/page}/lib/componentMap.js +3 -3
- package/dist/components/{pagebuilder → sitebuilder/page}/lib/componentMetadata.js +2 -2
- package/dist/components/{pagebuilder → sitebuilder/page}/lib/pageStorageContentful.js +2 -2
- package/dist/components/sitebuilder/page/lib/pageStorageTypes.js +1 -0
- package/dist/components/structured/markdown.js +1 -0
- package/dist/components/structured/recipe.js +1 -0
- package/dist/components/structured/timeline.js +1 -0
- package/dist/css/pixelated.global.css +0 -35
- package/dist/css/pixelated.grid.scss +4 -0
- package/dist/css/pixelated.visualdesign.scss +88 -0
- package/dist/data/form.json +18 -18
- package/dist/data/routes.json +32 -1
- package/dist/data/shipping.to.json +9 -9
- package/dist/data/siteinfo-form.json +200 -0
- package/dist/data/visualdesignform.json +244 -0
- package/dist/index.js +33 -21
- package/dist/index.server.js +24 -17
- package/dist/types/components/cms/cloudinary.image.d.ts.map +1 -1
- package/dist/types/components/cms/wordpress.components.d.ts.map +1 -1
- package/dist/types/components/general/semantic.d.ts +3 -3
- package/dist/types/components/general/tab.d.ts +18 -0
- package/dist/types/components/general/tab.d.ts.map +1 -0
- package/dist/types/components/menu/menu-accordion.d.ts.map +1 -1
- package/dist/types/components/seo/metadata.components.d.ts +0 -17
- package/dist/types/components/seo/metadata.components.d.ts.map +1 -1
- package/dist/types/components/seo/{metadata.d.ts → metadata.functions.d.ts} +15 -1
- package/dist/types/components/seo/metadata.functions.d.ts.map +1 -0
- package/dist/types/components/seo/schema-blogposting.d.ts +1 -25
- package/dist/types/components/seo/schema-blogposting.d.ts.map +1 -1
- package/dist/types/components/seo/schema-blogposting.functions.d.ts +26 -0
- package/dist/types/components/seo/schema-blogposting.functions.d.ts.map +1 -0
- package/dist/types/components/seo/sitemap.d.ts.map +1 -1
- package/dist/types/components/shoppingcart/shoppingcart.components.d.ts +1 -1
- package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts +23 -0
- package/dist/types/components/sitebuilder/config/CompoundFontSelector.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts +354 -0
- package/dist/types/components/sitebuilder/config/ConfigBuilder.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/config/ConfigEngine.d.ts +10 -0
- package/dist/types/components/sitebuilder/config/ConfigEngine.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/config/FontSelector.d.ts +27 -0
- package/dist/types/components/sitebuilder/config/FontSelector.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/config/google-fonts.d.ts +41 -0
- package/dist/types/components/sitebuilder/config/google-fonts.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/form/formbuilder.d.ts +11 -0
- package/dist/types/components/sitebuilder/form/formbuilder.d.ts.map +1 -0
- package/dist/types/components/{pagebuilder → sitebuilder}/form/formcomponents.d.ts +15 -17
- package/dist/types/components/sitebuilder/form/formcomponents.d.ts.map +1 -0
- package/dist/types/components/{pagebuilder/form/form.submit.d.ts → sitebuilder/form/formemailer.d.ts} +1 -1
- package/dist/types/components/sitebuilder/form/formemailer.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/form/formengine.d.ts +14 -0
- package/dist/types/components/sitebuilder/form/formengine.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/form/formextractor.d.ts +25 -0
- package/dist/types/components/sitebuilder/form/formextractor.d.ts.map +1 -0
- package/dist/types/components/{pagebuilder/form/formvalidations.d.ts → sitebuilder/form/formfieldvalidations.d.ts} +1 -1
- package/dist/types/components/sitebuilder/form/formfieldvalidations.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/form/formtypes.d.ts +66 -0
- package/dist/types/components/sitebuilder/form/formtypes.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/form/formutils.d.ts +20 -0
- package/dist/types/components/sitebuilder/form/formutils.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/form/formvalidator.d.ts +20 -0
- package/dist/types/components/sitebuilder/form/formvalidator.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/components/ComponentPropertiesForm.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/components/ComponentSelector.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/components/ComponentTree.d.ts.map +1 -0
- package/dist/types/components/{pagebuilder → sitebuilder/page}/components/PageBuilderUI.d.ts +1 -1
- package/dist/types/components/sitebuilder/page/components/PageBuilderUI.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/components/PageEngine.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/components/SaveLoadSection.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/documentation/api-examples/save-route-example.d.ts +6 -0
- package/dist/types/components/sitebuilder/page/documentation/api-examples/save-route-example.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/lib/componentGeneration.d.ts.map +1 -0
- package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/componentMap.d.ts +3 -3
- package/dist/types/components/sitebuilder/page/lib/componentMap.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/lib/componentMetadata.d.ts.map +1 -0
- package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/pageStorageContentful.d.ts +1 -1
- package/dist/types/components/sitebuilder/page/lib/pageStorageContentful.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/lib/pageStorageLocal.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/lib/pageStorageTypes.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/lib/propTypeIntrospection.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/lib/types.d.ts.map +1 -0
- package/dist/types/components/sitebuilder/page/lib/usePageBuilder.d.ts.map +1 -0
- package/dist/types/components/structured/markdown.d.ts.map +1 -1
- package/dist/types/components/structured/recipe.d.ts.map +1 -1
- package/dist/types/components/structured/timeline.d.ts.map +1 -1
- package/dist/types/index.d.ts +33 -20
- package/dist/types/index.server.d.ts +23 -16
- package/dist/types/stories/general/tab.stories.d.ts +45 -0
- package/dist/types/stories/general/tab.stories.d.ts.map +1 -0
- package/dist/types/stories/seo/seo.metadata.stories.d.ts +1 -1
- package/dist/types/stories/seo/seo.metadata.stories.d.ts.map +1 -1
- package/dist/types/stories/sitebuilder/compoundfontselector.stories.d.ts +51 -0
- package/dist/types/stories/sitebuilder/compoundfontselector.stories.d.ts.map +1 -0
- package/dist/types/stories/sitebuilder/configbuilder.stories.d.ts +103 -0
- package/dist/types/stories/sitebuilder/configbuilder.stories.d.ts.map +1 -0
- package/dist/types/stories/{pagebuilder → sitebuilder}/form-builder.stories.d.ts +1 -1
- package/dist/types/stories/sitebuilder/form-builder.stories.d.ts.map +1 -0
- package/dist/types/stories/{pagebuilder → sitebuilder}/form-engine.stories.d.ts +1 -1
- package/dist/types/stories/sitebuilder/form-engine.stories.d.ts.map +1 -0
- package/dist/types/stories/{pagebuilder → sitebuilder}/form-extractor.stories.d.ts +1 -1
- package/dist/types/stories/sitebuilder/form-extractor.stories.d.ts.map +1 -0
- package/dist/types/stories/{pagebuilder → sitebuilder}/pagebuilder.stories.d.ts +1 -1
- package/dist/types/stories/{pagebuilder → sitebuilder}/pagebuilder.stories.d.ts.map +1 -1
- package/dist/types/stories/{pagebuilder → sitebuilder}/pagebuilder.usageguide.stories.d.ts +1 -1
- package/dist/types/stories/{pagebuilder → sitebuilder}/pagebuilder.usageguide.stories.d.ts.map +1 -1
- package/dist/types/stories/{pagebuilder → sitebuilder}/pageengine.stories.d.ts +1 -1
- package/dist/types/stories/{pagebuilder → sitebuilder}/pageengine.stories.d.ts.map +1 -1
- package/dist/types/tests/compoundfontselector.test.d.ts +2 -0
- package/dist/types/tests/compoundfontselector.test.d.ts.map +1 -0
- package/dist/types/tests/configbuilder.test.d.ts +2 -0
- package/dist/types/tests/configbuilder.test.d.ts.map +1 -0
- package/dist/types/tests/configengine.test.d.ts +2 -0
- package/dist/types/tests/configengine.test.d.ts.map +1 -0
- package/dist/types/tests/fontselector.test.d.ts +2 -0
- package/dist/types/tests/fontselector.test.d.ts.map +1 -0
- package/dist/types/tests/tab.test.d.ts +2 -0
- package/dist/types/tests/tab.test.d.ts.map +1 -0
- package/package.json +15 -12
- package/dist/components/pagebuilder/form/formcomponents.js +0 -359
- package/dist/components/seo/metadata.js +0 -108
- package/dist/types/components/pagebuilder/components/ComponentPropertiesForm.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/components/ComponentSelector.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/components/ComponentTree.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/components/PageBuilderUI.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/components/PageEngine.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/components/SaveLoadSection.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/form/form.d.ts +0 -46
- package/dist/types/components/pagebuilder/form/form.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/form/form.submit.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/form/formcomponents.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/form/formvalidations.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/componentGeneration.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/componentMap.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/componentMetadata.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/pageStorageContentful.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/pageStorageLocal.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/pageStorageTypes.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/propTypeIntrospection.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/types.d.ts.map +0 -1
- package/dist/types/components/pagebuilder/lib/usePageBuilder.d.ts.map +0 -1
- package/dist/types/components/seo/metadata.d.ts.map +0 -1
- package/dist/types/stories/pagebuilder/form-builder.stories.d.ts.map +0 -1
- package/dist/types/stories/pagebuilder/form-engine.stories.d.ts.map +0 -1
- package/dist/types/stories/pagebuilder/form-extractor.stories.d.ts.map +0 -1
- /package/dist/components/{pagebuilder/form/form.submit.js → sitebuilder/form/formemailer.js} +0 -0
- /package/dist/components/{pagebuilder/form/formvalidations.js → sitebuilder/form/formfieldvalidations.js} +0 -0
- /package/dist/components/{pagebuilder/lib/pageStorageTypes.js → sitebuilder/form/formtypes.js} +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/components/ComponentSelector.js +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/components/ComponentTree.js +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/components/SaveLoadSection.js +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/components/pagebuilder.scss +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/lib/componentGeneration.js +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/lib/pageStorageLocal.js +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/lib/propTypeIntrospection.js +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/lib/types.js +0 -0
- /package/dist/components/{pagebuilder → sitebuilder/page}/lib/usePageBuilder.js +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/components/ComponentPropertiesForm.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/components/ComponentSelector.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/components/ComponentTree.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/components/PageEngine.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/components/SaveLoadSection.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/componentGeneration.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/componentMetadata.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/pageStorageLocal.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/pageStorageTypes.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/propTypeIntrospection.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/types.d.ts +0 -0
- /package/dist/types/components/{pagebuilder → sitebuilder/page}/lib/usePageBuilder.d.ts +0 -0
package/README.COMPONENTS.md
CHANGED
|
@@ -2,15 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
This guide provides detailed API documentation and usage examples for all Pixelated Components.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## � Reference Implementation
|
|
6
|
+
|
|
7
|
+
For a complete working example of Pixelated Components in action, check out the [pixelated-admin](https://github.com/brianwhaley/pixelated-admin) project. This admin interface demonstrates real-world usage of all components with:
|
|
8
|
+
|
|
9
|
+
- **Component Integration**: Live examples of component combinations
|
|
10
|
+
- **Configuration Management**: Dynamic site configuration with ConfigBuilder
|
|
11
|
+
- **Page Building**: Visual page construction workflows
|
|
12
|
+
- **Authentication**: Secure admin access patterns
|
|
13
|
+
- **Production Setup**: HTTPS, optimization, and deployment configurations
|
|
14
|
+
|
|
15
|
+
## �📋 Table of Contents
|
|
6
16
|
|
|
7
17
|
### General Components
|
|
8
18
|
- [Accordion](#accordion)
|
|
9
19
|
- [Callout](#callout)
|
|
20
|
+
- [CSS](#css)
|
|
10
21
|
- [Loading](#loading)
|
|
22
|
+
- [MicroInteractions](#microinteractions)
|
|
11
23
|
- [Modal](#modal)
|
|
24
|
+
- [Semantic](#semantic)
|
|
12
25
|
- [SidePanel](#sidepanel)
|
|
13
26
|
- [SmartImage](#smartimage)
|
|
27
|
+
- [Tab](#tab)
|
|
14
28
|
- [Table](#table)
|
|
15
29
|
|
|
16
30
|
### CMS Integration
|
|
@@ -34,6 +48,7 @@ This guide provides detailed API documentation and usage examples for all Pixela
|
|
|
34
48
|
- [ComponentPropertiesForm](#componentpropertiesform)
|
|
35
49
|
- [ComponentSelector](#componentselector)
|
|
36
50
|
- [ComponentTree](#componenttree)
|
|
51
|
+
- [ConfigBuilder](#configbuilder)
|
|
37
52
|
- [PageBuilderUI](#pagebuilderui)
|
|
38
53
|
- [PageEngine](#pageengine)
|
|
39
54
|
- [SaveLoadSection](#saveloadsection)
|
|
@@ -310,6 +325,76 @@ import { SmartImage } from '@pixelated-tech/components';
|
|
|
310
325
|
| `width` | `number` | - | Image width |
|
|
311
326
|
| `height` | `number` | - | Image height |
|
|
312
327
|
|
|
328
|
+
### CSS
|
|
329
|
+
|
|
330
|
+
Utility functions for CSS optimization and loading.
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
import { deferAllCSS, preloadAllCSS } from '@pixelated-tech/components';
|
|
334
|
+
|
|
335
|
+
// Defer CSS loading for better performance
|
|
336
|
+
deferAllCSS();
|
|
337
|
+
|
|
338
|
+
// Preload all CSS files
|
|
339
|
+
preloadAllCSS();
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
#### Functions
|
|
343
|
+
- **`deferAllCSS()`**: Defers loading of all CSS stylesheets for improved page load performance
|
|
344
|
+
- **`preloadAllCSS()`**: Preloads all CSS files with high priority
|
|
345
|
+
|
|
346
|
+
### MicroInteractions
|
|
347
|
+
|
|
348
|
+
Component for adding subtle CSS animations and interactions to page elements.
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
import { MicroInteractions } from '@pixelated-tech/components';
|
|
352
|
+
|
|
353
|
+
<MicroInteractions
|
|
354
|
+
buttonring={true}
|
|
355
|
+
cartpulse={true}
|
|
356
|
+
formglow={true}
|
|
357
|
+
imgscale={true}
|
|
358
|
+
scrollfadeElements=".fade-on-scroll"
|
|
359
|
+
/>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
#### Props
|
|
363
|
+
| Prop | Type | Default | Description |
|
|
364
|
+
|------|------|---------|-------------|
|
|
365
|
+
| `buttonring` | `boolean` | - | Add ring animation to buttons |
|
|
366
|
+
| `cartpulse` | `boolean` | - | Pulse animation for cart elements |
|
|
367
|
+
| `formglow` | `boolean` | - | Glow effect for form inputs |
|
|
368
|
+
| `grayscalehover` | `boolean` | - | Grayscale to color transition on hover |
|
|
369
|
+
| `imgscale` | `boolean` | - | Scale animation for images |
|
|
370
|
+
| `imgtwist` | `boolean` | - | Twist animation for images |
|
|
371
|
+
| `imghue` | `boolean` | - | Hue rotation for images |
|
|
372
|
+
| `simplemenubutton` | `boolean` | - | Animation for simple menu buttons |
|
|
373
|
+
| `scrollfadeElements` | `string` | - | CSS selector for elements to fade on scroll |
|
|
374
|
+
|
|
375
|
+
### Semantic
|
|
376
|
+
|
|
377
|
+
Semantic HTML layout components for structured content.
|
|
378
|
+
|
|
379
|
+
```tsx
|
|
380
|
+
import { PageSection, PageTitleHeader, GridContainer } from '@pixelated-tech/components';
|
|
381
|
+
|
|
382
|
+
<PageSection layoutType="grid" autoFlow="row">
|
|
383
|
+
<PageTitleHeader title="Welcome" />
|
|
384
|
+
<GridContainer columns={3} gap="1rem">
|
|
385
|
+
<div>Content 1</div>
|
|
386
|
+
<div>Content 2</div>
|
|
387
|
+
<div>Content 3</div>
|
|
388
|
+
</GridContainer>
|
|
389
|
+
</PageSection>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
#### Components
|
|
393
|
+
- **`PageSection`**: Semantic section with configurable layout
|
|
394
|
+
- **`PageTitleHeader`**: H1 title with optional link
|
|
395
|
+
- **`GridContainer`**: CSS Grid container with responsive columns
|
|
396
|
+
- **`FlexContainer`**: Flexbox container with alignment options
|
|
397
|
+
|
|
313
398
|
---
|
|
314
399
|
|
|
315
400
|
## CMS Integration
|
|
@@ -554,7 +639,7 @@ const reviews = [
|
|
|
554
639
|
|
|
555
640
|
### Forms
|
|
556
641
|
|
|
557
|
-
Dynamic form builder that generates forms from JSON configuration.
|
|
642
|
+
Dynamic form builder that generates forms from JSON configuration with comprehensive validation and event handling.
|
|
558
643
|
|
|
559
644
|
#### FormEngine
|
|
560
645
|
|
|
@@ -566,21 +651,39 @@ import { FormEngine } from '@pixelated-tech/components';
|
|
|
566
651
|
const formConfig = {
|
|
567
652
|
fields: [
|
|
568
653
|
{
|
|
569
|
-
|
|
654
|
+
component: 'FormInput',
|
|
570
655
|
props: {
|
|
656
|
+
type: 'text',
|
|
657
|
+
id: 'email',
|
|
571
658
|
name: 'email',
|
|
572
659
|
label: 'Email Address',
|
|
573
660
|
placeholder: 'Enter your email',
|
|
574
|
-
required:
|
|
661
|
+
required: 'required',
|
|
662
|
+
validate: 'email'
|
|
575
663
|
}
|
|
576
664
|
},
|
|
577
665
|
{
|
|
578
|
-
|
|
666
|
+
component: 'FormTextarea',
|
|
579
667
|
props: {
|
|
668
|
+
id: 'message',
|
|
580
669
|
name: 'message',
|
|
581
670
|
label: 'Message',
|
|
582
671
|
placeholder: 'Enter your message',
|
|
583
|
-
rows: 4
|
|
672
|
+
rows: '4',
|
|
673
|
+
required: 'required'
|
|
674
|
+
}
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
component: 'FormSelect',
|
|
678
|
+
props: {
|
|
679
|
+
id: 'category',
|
|
680
|
+
name: 'category',
|
|
681
|
+
label: 'Category',
|
|
682
|
+
options: [
|
|
683
|
+
{ text: 'General', value: 'general' },
|
|
684
|
+
{ text: 'Support', value: 'support' },
|
|
685
|
+
{ text: 'Sales', value: 'sales' }
|
|
686
|
+
]
|
|
584
687
|
}
|
|
585
688
|
}
|
|
586
689
|
]
|
|
@@ -595,36 +698,171 @@ const formConfig = {
|
|
|
595
698
|
|
|
596
699
|
#### Form Components
|
|
597
700
|
|
|
598
|
-
Individual form field components
|
|
701
|
+
Individual form field components with unified event handling and validation.
|
|
702
|
+
|
|
703
|
+
##### FormInput
|
|
704
|
+
Text input field with validation and accessibility features.
|
|
599
705
|
|
|
600
706
|
```tsx
|
|
601
|
-
import
|
|
707
|
+
import { FormInput } from '@pixelated-tech/components';
|
|
708
|
+
|
|
709
|
+
<FormInput
|
|
710
|
+
type="email"
|
|
711
|
+
id="email"
|
|
712
|
+
name="email"
|
|
713
|
+
label="Email Address"
|
|
714
|
+
placeholder="Enter your email"
|
|
715
|
+
required="required"
|
|
716
|
+
validate="email"
|
|
717
|
+
display="vertical"
|
|
718
|
+
/>
|
|
719
|
+
```
|
|
602
720
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
721
|
+
**Props:**
|
|
722
|
+
- `type`: Input type (text, email, password, etc.)
|
|
723
|
+
- `id`: Unique identifier
|
|
724
|
+
- `name`: Form field name
|
|
725
|
+
- `label`: Display label
|
|
726
|
+
- `placeholder`: Input placeholder text
|
|
727
|
+
- `required`: Makes field required
|
|
728
|
+
- `validate`: Validation rule name
|
|
729
|
+
- `display`: Layout mode (vertical/horizontal)
|
|
730
|
+
|
|
731
|
+
##### FormTextarea
|
|
732
|
+
Multi-line text input with validation.
|
|
733
|
+
|
|
734
|
+
```tsx
|
|
735
|
+
import { FormTextarea } from '@pixelated-tech/components';
|
|
736
|
+
|
|
737
|
+
<FormTextarea
|
|
738
|
+
id="description"
|
|
739
|
+
name="description"
|
|
740
|
+
label="Description"
|
|
741
|
+
placeholder="Enter description"
|
|
742
|
+
rows="4"
|
|
743
|
+
required="required"
|
|
744
|
+
display="vertical"
|
|
745
|
+
/>
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
##### FormSelect
|
|
749
|
+
Dropdown selection with option validation.
|
|
750
|
+
|
|
751
|
+
```tsx
|
|
752
|
+
import { FormSelect } from '@pixelated-tech/components';
|
|
753
|
+
|
|
754
|
+
<FormSelect
|
|
755
|
+
id="category"
|
|
756
|
+
name="category"
|
|
757
|
+
label="Category"
|
|
758
|
+
options={[
|
|
759
|
+
{ text: 'Option 1', value: 'opt1' },
|
|
760
|
+
{ text: 'Option 2', value: 'opt2' }
|
|
761
|
+
]}
|
|
762
|
+
required="required"
|
|
763
|
+
/>
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
##### FormRadio
|
|
767
|
+
Radio button group with validation.
|
|
768
|
+
|
|
769
|
+
```tsx
|
|
770
|
+
import { FormRadio } from '@pixelated-tech/components';
|
|
771
|
+
|
|
772
|
+
<FormRadio
|
|
773
|
+
id="choice"
|
|
774
|
+
name="choice"
|
|
775
|
+
label="Choose an option"
|
|
776
|
+
options={[
|
|
777
|
+
{ text: 'Option A', value: 'a' },
|
|
778
|
+
{ text: 'Option B', value: 'b' }
|
|
779
|
+
]}
|
|
780
|
+
required="required"
|
|
781
|
+
/>
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
##### FormCheckbox
|
|
785
|
+
Checkbox group with validation.
|
|
786
|
+
|
|
787
|
+
```tsx
|
|
788
|
+
import { FormCheckbox } from '@pixelated-tech/components';
|
|
789
|
+
|
|
790
|
+
<FormCheckbox
|
|
791
|
+
id="preferences"
|
|
792
|
+
name="preferences"
|
|
793
|
+
label="Preferences"
|
|
794
|
+
options={[
|
|
795
|
+
{ text: 'Email updates', value: 'email' },
|
|
796
|
+
{ text: 'SMS updates', value: 'sms' }
|
|
797
|
+
]}
|
|
798
|
+
/>
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
##### FormButton
|
|
802
|
+
Action button for form submission.
|
|
803
|
+
|
|
804
|
+
```tsx
|
|
805
|
+
import { FormButton } from '@pixelated-tech/components';
|
|
806
|
+
|
|
807
|
+
<FormButton
|
|
808
|
+
type="submit"
|
|
809
|
+
id="submit-btn"
|
|
810
|
+
text="Submit Form"
|
|
811
|
+
onClick={handleSubmit}
|
|
812
|
+
/>
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
##### FormTooltip
|
|
816
|
+
Unified tooltip and validation message component with mouseover behavior and conditional styling.
|
|
817
|
+
|
|
818
|
+
```tsx
|
|
819
|
+
import { FormTooltip } from '@pixelated-tech/components';
|
|
820
|
+
|
|
821
|
+
// Tooltip mode - displays information with black ⓘ icon
|
|
822
|
+
<FormTooltip
|
|
823
|
+
mode="tooltip"
|
|
824
|
+
text={['This field is required', 'Please enter a valid email address']}
|
|
825
|
+
/>
|
|
826
|
+
|
|
827
|
+
// Validation mode - displays errors with red ❌ icon
|
|
828
|
+
<FormTooltip
|
|
829
|
+
mode="validate"
|
|
830
|
+
text={['Email format is invalid', 'Please check your input']}
|
|
831
|
+
/>
|
|
626
832
|
```
|
|
627
833
|
|
|
834
|
+
**Props:**
|
|
835
|
+
- `mode`: Display mode ('tooltip' for info, 'validate' for errors)
|
|
836
|
+
- `text`: Array of strings to display (always use array format)
|
|
837
|
+
|
|
838
|
+
**Features:**
|
|
839
|
+
- **Conditional Icons**: ⓘ (black) for tooltips, ❌ (red) for validation errors
|
|
840
|
+
- **Mouseover Behavior**: Shows/hides content on hover for both modes
|
|
841
|
+
- **Unified Styling**: Consistent appearance with mode-based color variations
|
|
842
|
+
- **Array-Based Text**: Always accepts text as string array for consistency
|
|
843
|
+
|
|
844
|
+
#### Form Validation
|
|
845
|
+
|
|
846
|
+
Built-in validation rules available via the `validate` prop:
|
|
847
|
+
|
|
848
|
+
- `email`: Email format validation
|
|
849
|
+
- `url`: URL format validation
|
|
850
|
+
- `phone`: Phone number format
|
|
851
|
+
- `zipcode`: US zip code validation
|
|
852
|
+
- `required`: Required field validation
|
|
853
|
+
- Custom validation functions can be added to `formvalidations.tsx`
|
|
854
|
+
|
|
855
|
+
#### Recent Improvements
|
|
856
|
+
|
|
857
|
+
**Version 3.2.14+** includes major refactoring for better performance and maintainability:
|
|
858
|
+
|
|
859
|
+
- **FormTooltip Unification**: Merged FormTooltip and FormValidate into single component with mode-based rendering
|
|
860
|
+
- **Unified Event Handling**: All form components now use consistent `onChange` and `onInput` handlers for better test compatibility
|
|
861
|
+
- **Performance Optimization**: Replaced inefficient `JSON.parse/stringify` with direct object destructuring
|
|
862
|
+
- **Code Deduplication**: Custom `useFormComponent` hook eliminates repetitive validation logic
|
|
863
|
+
- **Circular Reference Prevention**: Fixed memory leaks in option generation for radio/checkbox components
|
|
864
|
+
- **Enhanced Test Coverage**: 2,244 tests passing across 67 test files with comprehensive form component coverage
|
|
865
|
+
|
|
628
866
|
### Menu
|
|
629
867
|
|
|
630
868
|
Navigation components with multiple interaction patterns.
|
|
@@ -691,6 +929,29 @@ const menuItems = [
|
|
|
691
929
|
<MenuExpando menuItems={menuItems} />
|
|
692
930
|
```
|
|
693
931
|
|
|
932
|
+
### Tab
|
|
933
|
+
|
|
934
|
+
Configurable tab component with multiple orientations and content areas.
|
|
935
|
+
|
|
936
|
+
```tsx
|
|
937
|
+
import { Tab } from '@pixelated-tech/components';
|
|
938
|
+
|
|
939
|
+
const tabs = [
|
|
940
|
+
{ id: 'tab1', label: 'Tab 1', content: <div>Content for Tab 1</div> },
|
|
941
|
+
{ id: 'tab2', label: 'Tab 2', content: <div>Content for Tab 2</div> },
|
|
942
|
+
{ id: 'tab3', label: 'Tab 3', content: <div>Content for Tab 3</div> },
|
|
943
|
+
];
|
|
944
|
+
|
|
945
|
+
<Tab tabs={tabs} orientation="top" defaultActiveTab="tab1" />
|
|
946
|
+
```
|
|
947
|
+
|
|
948
|
+
#### Props
|
|
949
|
+
|
|
950
|
+
- `tabs`: Array of tab objects with `id`, `label`, and `content`
|
|
951
|
+
- `orientation`: 'top' | 'bottom' | 'left' | 'right' (default: 'top')
|
|
952
|
+
- `defaultActiveTab`: ID of the initially active tab
|
|
953
|
+
- `onTabChange`: Callback function called when tab changes
|
|
954
|
+
|
|
694
955
|
### Tables
|
|
695
956
|
|
|
696
957
|
Data display component with sorting and image support.
|
|
@@ -874,6 +1135,234 @@ import { SaveLoadSection } from '@pixelated-tech/components';
|
|
|
874
1135
|
| `onLoad` | `function` | - | Load handler |
|
|
875
1136
|
| `onNew` | `function` | - | New page handler |
|
|
876
1137
|
|
|
1138
|
+
### ConfigBuilder
|
|
1139
|
+
|
|
1140
|
+
Tabbed interface for managing site metadata and routes configuration.
|
|
1141
|
+
|
|
1142
|
+
```tsx
|
|
1143
|
+
import { ConfigBuilder } from '@pixelated-tech/components';
|
|
1144
|
+
|
|
1145
|
+
<ConfigBuilder
|
|
1146
|
+
initialConfig={{
|
|
1147
|
+
siteInfo: { name: 'My Site', description: 'Site description' },
|
|
1148
|
+
routes: [
|
|
1149
|
+
{ path: '/home', component: 'Home', title: 'Home Page' }
|
|
1150
|
+
]
|
|
1151
|
+
}}
|
|
1152
|
+
onSave={(config) => console.log('Config saved:', config)}
|
|
1153
|
+
/>
|
|
1154
|
+
```
|
|
1155
|
+
|
|
1156
|
+
#### Props
|
|
1157
|
+
| Prop | Type | Default | Description |
|
|
1158
|
+
|------|------|---------|-------------|
|
|
1159
|
+
| `initialConfig` | `SiteConfig` | - | Initial site configuration |
|
|
1160
|
+
| `onSave` | `function` | - | Configuration save handler |
|
|
1161
|
+
|
|
1162
|
+
#### SiteConfig Type
|
|
1163
|
+
```tsx
|
|
1164
|
+
interface SiteConfig {
|
|
1165
|
+
siteInfo: {
|
|
1166
|
+
name: string;
|
|
1167
|
+
author: string;
|
|
1168
|
+
description: string;
|
|
1169
|
+
url: string;
|
|
1170
|
+
email: string;
|
|
1171
|
+
favicon: string;
|
|
1172
|
+
favicon_sizes: string;
|
|
1173
|
+
favicon_type: string;
|
|
1174
|
+
theme_color: string;
|
|
1175
|
+
background_color: string;
|
|
1176
|
+
default_locale: string;
|
|
1177
|
+
display: string;
|
|
1178
|
+
image?: string;
|
|
1179
|
+
image_height?: string;
|
|
1180
|
+
image_width?: string;
|
|
1181
|
+
telephone?: string;
|
|
1182
|
+
address?: {
|
|
1183
|
+
streetAddress: string;
|
|
1184
|
+
addressLocality: string;
|
|
1185
|
+
addressRegion: string;
|
|
1186
|
+
postalCode: string;
|
|
1187
|
+
addressCountry: string;
|
|
1188
|
+
};
|
|
1189
|
+
priceRange?: string;
|
|
1190
|
+
sameAs?: string[];
|
|
1191
|
+
keywords?: string;
|
|
1192
|
+
};
|
|
1193
|
+
routes: Array<{
|
|
1194
|
+
path: string;
|
|
1195
|
+
component: string;
|
|
1196
|
+
title?: string;
|
|
1197
|
+
description?: string;
|
|
1198
|
+
}>;
|
|
1199
|
+
visualdesign?: {
|
|
1200
|
+
'primary-color': string;
|
|
1201
|
+
'secondary-color': string;
|
|
1202
|
+
'accent1-color': string;
|
|
1203
|
+
'accent2-color': string;
|
|
1204
|
+
'bg-color': string;
|
|
1205
|
+
'text-color': string;
|
|
1206
|
+
'header-font-primary': string;
|
|
1207
|
+
'header-font-fallback': string;
|
|
1208
|
+
'header-font-generic': string;
|
|
1209
|
+
'body-font-primary': string;
|
|
1210
|
+
'body-font-fallback': string;
|
|
1211
|
+
'body-font-generic': string;
|
|
1212
|
+
'font-size1-min': string;
|
|
1213
|
+
'font-size1-max': string;
|
|
1214
|
+
'font-size2-min': string;
|
|
1215
|
+
'font-size2-max': string;
|
|
1216
|
+
'font-size3-min': string;
|
|
1217
|
+
'font-size3-max': string;
|
|
1218
|
+
'font-size4-min': string;
|
|
1219
|
+
'font-size4-max': string;
|
|
1220
|
+
'font-size5-min': string;
|
|
1221
|
+
'font-size5-max': string;
|
|
1222
|
+
'font-size6-min': string;
|
|
1223
|
+
'font-size6-max': string;
|
|
1224
|
+
'font-min-screen': string;
|
|
1225
|
+
'font-max-screen': string;
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
```
|
|
1229
|
+
|
|
1230
|
+
#### Features
|
|
1231
|
+
- **Tabbed Interface**: Organized into "Site Info", "Routes", and "Visual Design" tabs
|
|
1232
|
+
- **Comprehensive Site Info Management**: Edit all standard site metadata fields including PWA settings, contact info, and address
|
|
1233
|
+
- **Route Management**: Add, edit, and remove page routes with component mapping
|
|
1234
|
+
- **Visual Design Configuration**: Manage design tokens like colors, fonts, and spacing through a form-based interface
|
|
1235
|
+
- **Real-time Preview**: JSON preview of current configuration
|
|
1236
|
+
- **Save Functionality**: Callback-based configuration persistence with form validation enforcement
|
|
1237
|
+
- **Form Validation**: Required field validation for essential site information with visual feedback
|
|
1238
|
+
|
|
1239
|
+
#### Validation Behavior
|
|
1240
|
+
|
|
1241
|
+
The "Save Config" button enforces form validation before allowing configuration saves:
|
|
1242
|
+
|
|
1243
|
+
- **Required Fields**: Site name, author, description, URL, and email are mandatory
|
|
1244
|
+
- **Visual Feedback**: Invalid fields show validation errors with ❌ indicators
|
|
1245
|
+
- **Save Prevention**: Save action is blocked until all required validations pass
|
|
1246
|
+
- **Real-time Validation**: Form validates as you type with immediate feedback
|
|
1247
|
+
|
|
1248
|
+
#### Visual Design Tab
|
|
1249
|
+
|
|
1250
|
+
The Visual Design tab provides a form-based interface for configuring visual design tokens. These tokens are stored in the `visualdesign` object of the site configuration and can be used to maintain consistent theming across your application.
|
|
1251
|
+
|
|
1252
|
+
**Supported Design Tokens:**
|
|
1253
|
+
- **Colors**: Primary, secondary, accent, text, and background colors
|
|
1254
|
+
- **Typography**: Header and body fonts with primary Google Fonts, web-safe fallbacks, and generic family fallbacks
|
|
1255
|
+
- **Layout**: Border radius, box shadows, transition durations
|
|
1256
|
+
|
|
1257
|
+
**Usage in Components:**
|
|
1258
|
+
```tsx
|
|
1259
|
+
// Access visual design tokens from config
|
|
1260
|
+
const config = useConfig();
|
|
1261
|
+
const primaryColor = config.visualdesign?.['primary-color'] || '#369';
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
### FontSelector
|
|
1265
|
+
|
|
1266
|
+
Autocomplete input component for selecting fonts with support for Google Fonts, web-safe fonts, and generic font families.
|
|
1267
|
+
|
|
1268
|
+
```tsx
|
|
1269
|
+
import { FontSelector } from '@pixelated-tech/components';
|
|
1270
|
+
|
|
1271
|
+
<FontSelector
|
|
1272
|
+
id="header-font-primary"
|
|
1273
|
+
name="header-font-primary"
|
|
1274
|
+
label="Header Font (Google Fonts)"
|
|
1275
|
+
fontType="google"
|
|
1276
|
+
value="Montserrat"
|
|
1277
|
+
onChange={(font) => console.log('Selected font:', font)}
|
|
1278
|
+
/>
|
|
1279
|
+
```
|
|
1280
|
+
|
|
1281
|
+
#### Props
|
|
1282
|
+
| Prop | Type | Default | Description |
|
|
1283
|
+
|------|------|---------|-------------|
|
|
1284
|
+
| `id` | `string` | - | Unique identifier for the input |
|
|
1285
|
+
| `name` | `string` | - | Name attribute for form submission |
|
|
1286
|
+
| `label` | `string` | - | Display label for the input |
|
|
1287
|
+
| `fontType` | `'google' \| 'websafe' \| 'generic'` | - | Type of fonts to show in autocomplete |
|
|
1288
|
+
| `value` | `string` | `''` | Current selected font value |
|
|
1289
|
+
| `onChange` | `function` | - | Callback when font selection changes |
|
|
1290
|
+
| `required` | `boolean` | `false` | Whether the field is required |
|
|
1291
|
+
| `placeholder` | `string` | - | Placeholder text (auto-generated based on fontType) |
|
|
1292
|
+
|
|
1293
|
+
#### Font Types
|
|
1294
|
+
|
|
1295
|
+
- **`google`**: Shows Google Fonts with live preview links
|
|
1296
|
+
- **`websafe`**: Shows common web-safe fonts (Arial, Helvetica, etc.)
|
|
1297
|
+
- **`generic`**: Shows CSS generic font families (serif, sans-serif, etc.)
|
|
1298
|
+
|
|
1299
|
+
#### Features
|
|
1300
|
+
|
|
1301
|
+
- **Autocomplete**: Intelligent font suggestions as you type
|
|
1302
|
+
- **Google Fonts Integration**: Direct links to Google Fonts preview pages
|
|
1303
|
+
- **Web-safe Fallbacks**: Ensures font availability across devices
|
|
1304
|
+
- **Generic Families**: CSS generic font family support
|
|
1305
|
+
- **Accessibility**: Proper labeling and keyboard navigation
|
|
1306
|
+
|
|
1307
|
+
### ConfigEngine
|
|
1308
|
+
|
|
1309
|
+
Components for rendering visual design styles and Google Fonts imports from configuration data.
|
|
1310
|
+
|
|
1311
|
+
#### VisualDesignStyles
|
|
1312
|
+
|
|
1313
|
+
Renders CSS custom properties from visual design configuration tokens.
|
|
1314
|
+
|
|
1315
|
+
```tsx
|
|
1316
|
+
import { VisualDesignStyles } from '@pixelated-tech/components';
|
|
1317
|
+
|
|
1318
|
+
<VisualDesignStyles visualdesign={{
|
|
1319
|
+
'primary-color': '#007bff',
|
|
1320
|
+
'header-font-primary': 'Montserrat',
|
|
1321
|
+
'header-font-fallback': 'Arial',
|
|
1322
|
+
'header-font-generic': 'sans-serif',
|
|
1323
|
+
'font-size1-min': '14px',
|
|
1324
|
+
'font-size1-max': '18px'
|
|
1325
|
+
}} />
|
|
1326
|
+
```
|
|
1327
|
+
|
|
1328
|
+
**Generated CSS:**
|
|
1329
|
+
```css
|
|
1330
|
+
:root {
|
|
1331
|
+
--primary-color: #007bff;
|
|
1332
|
+
--header-font-family: "Montserrat", "Arial", "sans-serif";
|
|
1333
|
+
--font-size1: clamp(var(--font-size1-min), calc(var(--font-size1-min) + ((var(--font-size1-max) - var(--font-size1-min)) * ((100vw - var(--font-min-screen)) / (var(--font-max-screen) - var(--font-min-screen))))), var(--font-size1-max));
|
|
1334
|
+
}
|
|
1335
|
+
h1 { font-size: var(--font-size1); }
|
|
1336
|
+
```
|
|
1337
|
+
|
|
1338
|
+
#### GoogleFontsImports
|
|
1339
|
+
|
|
1340
|
+
Automatically generates Google Fonts link tags for fonts specified in visual design configuration.
|
|
1341
|
+
|
|
1342
|
+
```tsx
|
|
1343
|
+
import { GoogleFontsImports } from '@pixelated-tech/components';
|
|
1344
|
+
|
|
1345
|
+
<GoogleFontsImports visualdesign={{
|
|
1346
|
+
'header-font-primary': 'Montserrat',
|
|
1347
|
+
'body-font-primary': 'Open Sans'
|
|
1348
|
+
}} />
|
|
1349
|
+
```
|
|
1350
|
+
|
|
1351
|
+
**Generated HTML:**
|
|
1352
|
+
```html
|
|
1353
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
1354
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
1355
|
+
<link href="https://fonts.googleapis.com/css2?family=Montserrat|Open+Sans&display=swap" rel="stylesheet">
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
#### Features
|
|
1359
|
+
|
|
1360
|
+
- **Font Stack Generation**: Automatically builds CSS font-family stacks from 3-field font configuration
|
|
1361
|
+
- **Responsive Typography**: Generates fluid font sizes using CSS clamp() for responsive design
|
|
1362
|
+
- **Google Fonts Integration**: Automatically imports only the Google Fonts used in the design
|
|
1363
|
+
- **Web-safe Font Filtering**: Excludes web-safe fonts from Google Fonts imports to reduce loading
|
|
1364
|
+
- **Server-safe**: Both components are safe to use in server components and API routes
|
|
1365
|
+
|
|
877
1366
|
---
|
|
878
1367
|
|
|
879
1368
|
## SEO & Schema
|