@pithyjs/ui-kit 0.1.0-beta.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/LICENSE +21 -0
- package/dist/animation/animate-in.d.ts +35 -0
- package/dist/animation/animate-in.d.ts.map +1 -0
- package/dist/animation/animate-in.js +71 -0
- package/dist/animation/animate-in.js.map +1 -0
- package/dist/atoms/actions/_icon-control.scss +53 -0
- package/dist/atoms/actions/button/Button.d.ts +93 -0
- package/dist/atoms/actions/button/Button.d.ts.map +1 -0
- package/dist/atoms/actions/button/Button.js +332 -0
- package/dist/atoms/actions/button/Button.js.map +1 -0
- package/dist/atoms/actions/button/button.scss +342 -0
- package/dist/atoms/actions/icon-button/IconButton.d.ts +47 -0
- package/dist/atoms/actions/icon-button/IconButton.d.ts.map +1 -0
- package/dist/atoms/actions/icon-button/IconButton.js +81 -0
- package/dist/atoms/actions/icon-button/IconButton.js.map +1 -0
- package/dist/atoms/actions/icon-button/icon-button.scss +20 -0
- package/dist/atoms/actions/icon-group/IconGroup.d.ts +60 -0
- package/dist/atoms/actions/icon-group/IconGroup.d.ts.map +1 -0
- package/dist/atoms/actions/icon-group/IconGroup.js +191 -0
- package/dist/atoms/actions/icon-group/IconGroup.js.map +1 -0
- package/dist/atoms/actions/icon-group/icon-group.scss +36 -0
- package/dist/atoms/actions/segmented-control/SegmentedControl.d.ts +49 -0
- package/dist/atoms/actions/segmented-control/SegmentedControl.d.ts.map +1 -0
- package/dist/atoms/actions/segmented-control/SegmentedControl.js +107 -0
- package/dist/atoms/actions/segmented-control/SegmentedControl.js.map +1 -0
- package/dist/atoms/actions/segmented-control/segmented-control.scss +90 -0
- package/dist/atoms/content/_mixins.scss +79 -0
- package/dist/atoms/content/action-tile/ActionTile.d.ts +27 -0
- package/dist/atoms/content/action-tile/ActionTile.d.ts.map +1 -0
- package/dist/atoms/content/action-tile/ActionTile.js +98 -0
- package/dist/atoms/content/action-tile/ActionTile.js.map +1 -0
- package/dist/atoms/content/action-tile/action-tile.scss +150 -0
- package/dist/atoms/content/badge/Badge.d.ts +57 -0
- package/dist/atoms/content/badge/Badge.d.ts.map +1 -0
- package/dist/atoms/content/badge/Badge.js +177 -0
- package/dist/atoms/content/badge/Badge.js.map +1 -0
- package/dist/atoms/content/badge/badge.scss +198 -0
- package/dist/atoms/content/heading/Heading.d.ts +53 -0
- package/dist/atoms/content/heading/Heading.d.ts.map +1 -0
- package/dist/atoms/content/heading/Heading.js +142 -0
- package/dist/atoms/content/heading/Heading.js.map +1 -0
- package/dist/atoms/content/heading/heading.scss +43 -0
- package/dist/atoms/content/icon/Icon.d.ts +68 -0
- package/dist/atoms/content/icon/Icon.d.ts.map +1 -0
- package/dist/atoms/content/icon/Icon.js +137 -0
- package/dist/atoms/content/icon/Icon.js.map +1 -0
- package/dist/atoms/content/icon/icon.scss +66 -0
- package/dist/atoms/content/icon/resolveIconSvg.d.ts +21 -0
- package/dist/atoms/content/icon/resolveIconSvg.d.ts.map +1 -0
- package/dist/atoms/content/icon/resolveIconSvg.js +73 -0
- package/dist/atoms/content/icon/resolveIconSvg.js.map +1 -0
- package/dist/atoms/content/image/Image.d.ts +81 -0
- package/dist/atoms/content/image/Image.d.ts.map +1 -0
- package/dist/atoms/content/image/Image.js +293 -0
- package/dist/atoms/content/image/Image.js.map +1 -0
- package/dist/atoms/content/image/image.scss +77 -0
- package/dist/atoms/content/text/Text.d.ts +58 -0
- package/dist/atoms/content/text/Text.d.ts.map +1 -0
- package/dist/atoms/content/text/Text.js +158 -0
- package/dist/atoms/content/text/Text.js.map +1 -0
- package/dist/atoms/content/text/text.scss +98 -0
- package/dist/atoms/content/tile/Tile.d.ts +66 -0
- package/dist/atoms/content/tile/Tile.d.ts.map +1 -0
- package/dist/atoms/content/tile/Tile.js +125 -0
- package/dist/atoms/content/tile/Tile.js.map +1 -0
- package/dist/atoms/content/tile/tile.scss +122 -0
- package/dist/atoms/feedback/tooltip/Tooltip.d.ts +44 -0
- package/dist/atoms/feedback/tooltip/Tooltip.d.ts.map +1 -0
- package/dist/atoms/feedback/tooltip/Tooltip.js +121 -0
- package/dist/atoms/feedback/tooltip/Tooltip.js.map +1 -0
- package/dist/atoms/feedback/tooltip/tooltip.scss +96 -0
- package/dist/atoms/forms/checkbox/Checkbox.d.ts +49 -0
- package/dist/atoms/forms/checkbox/Checkbox.d.ts.map +1 -0
- package/dist/atoms/forms/checkbox/Checkbox.js +269 -0
- package/dist/atoms/forms/checkbox/Checkbox.js.map +1 -0
- package/dist/atoms/forms/checkbox/CheckboxGroup.d.ts +50 -0
- package/dist/atoms/forms/checkbox/CheckboxGroup.d.ts.map +1 -0
- package/dist/atoms/forms/checkbox/CheckboxGroup.js +132 -0
- package/dist/atoms/forms/checkbox/CheckboxGroup.js.map +1 -0
- package/dist/atoms/forms/checkbox/checkbox.scss +506 -0
- package/dist/atoms/forms/file-picker/FilePicker.d.ts +23 -0
- package/dist/atoms/forms/file-picker/FilePicker.d.ts.map +1 -0
- package/dist/atoms/forms/file-picker/FilePicker.js +103 -0
- package/dist/atoms/forms/file-picker/FilePicker.js.map +1 -0
- package/dist/atoms/forms/file-picker/file-picker.scss +84 -0
- package/dist/atoms/forms/form-field/FormField.d.ts +39 -0
- package/dist/atoms/forms/form-field/FormField.d.ts.map +1 -0
- package/dist/atoms/forms/form-field/FormField.js +139 -0
- package/dist/atoms/forms/form-field/FormField.js.map +1 -0
- package/dist/atoms/forms/form-field/form-field.scss +46 -0
- package/dist/atoms/forms/input/Input.d.ts +81 -0
- package/dist/atoms/forms/input/Input.d.ts.map +1 -0
- package/dist/atoms/forms/input/Input.js +417 -0
- package/dist/atoms/forms/input/Input.js.map +1 -0
- package/dist/atoms/forms/input/input.scss +547 -0
- package/dist/atoms/forms/radio/Radio.d.ts +54 -0
- package/dist/atoms/forms/radio/Radio.d.ts.map +1 -0
- package/dist/atoms/forms/radio/Radio.js +278 -0
- package/dist/atoms/forms/radio/Radio.js.map +1 -0
- package/dist/atoms/forms/radio/RadioGroup.d.ts +54 -0
- package/dist/atoms/forms/radio/RadioGroup.d.ts.map +1 -0
- package/dist/atoms/forms/radio/RadioGroup.js +137 -0
- package/dist/atoms/forms/radio/RadioGroup.js.map +1 -0
- package/dist/atoms/forms/radio/radio.scss +459 -0
- package/dist/atoms/forms/select/Select.d.ts +57 -0
- package/dist/atoms/forms/select/Select.d.ts.map +1 -0
- package/dist/atoms/forms/select/Select.js +457 -0
- package/dist/atoms/forms/select/Select.js.map +1 -0
- package/dist/atoms/forms/select/select-dropdown.d.ts +49 -0
- package/dist/atoms/forms/select/select-dropdown.d.ts.map +1 -0
- package/dist/atoms/forms/select/select-dropdown.js +305 -0
- package/dist/atoms/forms/select/select-dropdown.js.map +1 -0
- package/dist/atoms/forms/select/select-keyboard.d.ts +14 -0
- package/dist/atoms/forms/select/select-keyboard.d.ts.map +1 -0
- package/dist/atoms/forms/select/select-keyboard.js +182 -0
- package/dist/atoms/forms/select/select-keyboard.js.map +1 -0
- package/dist/atoms/forms/select/select.scss +630 -0
- package/dist/atoms/forms/textarea/Textarea.d.ts +69 -0
- package/dist/atoms/forms/textarea/Textarea.d.ts.map +1 -0
- package/dist/atoms/forms/textarea/Textarea.js +394 -0
- package/dist/atoms/forms/textarea/Textarea.js.map +1 -0
- package/dist/atoms/forms/textarea/textarea.scss +486 -0
- package/dist/atoms/forms/toggle/Toggle.d.ts +47 -0
- package/dist/atoms/forms/toggle/Toggle.d.ts.map +1 -0
- package/dist/atoms/forms/toggle/Toggle.js +243 -0
- package/dist/atoms/forms/toggle/Toggle.js.map +1 -0
- package/dist/atoms/forms/toggle/toggle.scss +561 -0
- package/dist/compiler.d.ts +7 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +18 -0
- package/dist/compiler.js.map +1 -0
- package/dist/icons/index.d.ts +14 -0
- package/dist/icons/index.d.ts.map +1 -0
- package/dist/icons/index.js +14 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/icons/registry.d.ts +65 -0
- package/dist/icons/registry.d.ts.map +1 -0
- package/dist/icons/registry.js +126 -0
- package/dist/icons/registry.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/Grid.d.ts +78 -0
- package/dist/layout/Grid.d.ts.map +1 -0
- package/dist/layout/Grid.js +272 -0
- package/dist/layout/Grid.js.map +1 -0
- package/dist/layout/GridItem.d.ts +52 -0
- package/dist/layout/GridItem.d.ts.map +1 -0
- package/dist/layout/GridItem.js +99 -0
- package/dist/layout/GridItem.js.map +1 -0
- package/dist/layout/PageSection.d.ts +43 -0
- package/dist/layout/PageSection.d.ts.map +1 -0
- package/dist/layout/PageSection.js +75 -0
- package/dist/layout/PageSection.js.map +1 -0
- package/dist/layout/SmartContainer.d.ts +66 -0
- package/dist/layout/SmartContainer.d.ts.map +1 -0
- package/dist/layout/SmartContainer.js +194 -0
- package/dist/layout/SmartContainer.js.map +1 -0
- package/dist/layout/Stack.d.ts +65 -0
- package/dist/layout/Stack.d.ts.map +1 -0
- package/dist/layout/Stack.js +114 -0
- package/dist/layout/Stack.js.map +1 -0
- package/dist/organisms/content/Card.d.ts +93 -0
- package/dist/organisms/content/Card.d.ts.map +1 -0
- package/dist/organisms/content/Card.js +353 -0
- package/dist/organisms/content/Card.js.map +1 -0
- package/dist/organisms/content/_card-horizontal.scss +88 -0
- package/dist/organisms/content/_card-link.scss +49 -0
- package/dist/organisms/content/_card-overlay.scss +91 -0
- package/dist/organisms/content/_card-root.scss +99 -0
- package/dist/organisms/content/_card-slots.scss +143 -0
- package/dist/organisms/content/_card-states.scss +166 -0
- package/dist/organisms/content/_card-tokens.scss +22 -0
- package/dist/organisms/content/_card-variants.scss +31 -0
- package/dist/organisms/content/card.scss +15 -0
- package/dist/organisms/feedback/Modal.d.ts +39 -0
- package/dist/organisms/feedback/Modal.d.ts.map +1 -0
- package/dist/organisms/feedback/Modal.js +120 -0
- package/dist/organisms/feedback/Modal.js.map +1 -0
- package/dist/organisms/feedback/Popover.d.ts +30 -0
- package/dist/organisms/feedback/Popover.d.ts.map +1 -0
- package/dist/organisms/feedback/Popover.js +151 -0
- package/dist/organisms/feedback/Popover.js.map +1 -0
- package/dist/organisms/feedback/modal.scss +66 -0
- package/dist/organisms/feedback/popover.scss +27 -0
- package/dist/organisms/forms/DynamicForm.d.ts +118 -0
- package/dist/organisms/forms/DynamicForm.d.ts.map +1 -0
- package/dist/organisms/forms/DynamicForm.js +546 -0
- package/dist/organisms/forms/DynamicForm.js.map +1 -0
- package/dist/organisms/forms/Form.d.ts +62 -0
- package/dist/organisms/forms/Form.d.ts.map +1 -0
- package/dist/organisms/forms/Form.js +131 -0
- package/dist/organisms/forms/Form.js.map +1 -0
- package/dist/organisms/forms/dynamic-form.scss +91 -0
- package/dist/organisms/forms/form-helpers.d.ts +21 -0
- package/dist/organisms/forms/form-helpers.d.ts.map +1 -0
- package/dist/organisms/forms/form-helpers.js +57 -0
- package/dist/organisms/forms/form-helpers.js.map +1 -0
- package/dist/organisms/forms/form-state.d.ts +66 -0
- package/dist/organisms/forms/form-state.d.ts.map +1 -0
- package/dist/organisms/forms/form-state.js +156 -0
- package/dist/organisms/forms/form-state.js.map +1 -0
- package/dist/organisms/forms/form.scss +23 -0
- package/dist/organisms/forms/validation.d.ts +32 -0
- package/dist/organisms/forms/validation.d.ts.map +1 -0
- package/dist/organisms/forms/validation.js +118 -0
- package/dist/organisms/forms/validation.js.map +1 -0
- package/dist/organisms/navigation/Navbar.d.ts +66 -0
- package/dist/organisms/navigation/Navbar.d.ts.map +1 -0
- package/dist/organisms/navigation/Navbar.js +881 -0
- package/dist/organisms/navigation/Navbar.js.map +1 -0
- package/dist/organisms/navigation/_navbar-announcement.scss +62 -0
- package/dist/organisms/navigation/_navbar-brand.scss +69 -0
- package/dist/organisms/navigation/_navbar-container.scss +37 -0
- package/dist/organisms/navigation/_navbar-desktop.scss +116 -0
- package/dist/organisms/navigation/_navbar-drawer.scss +97 -0
- package/dist/organisms/navigation/_navbar-links.scss +143 -0
- package/dist/organisms/navigation/_navbar-menu.scss +193 -0
- package/dist/organisms/navigation/_navbar-root.scss +107 -0
- package/dist/organisms/navigation/_navbar-search.scss +83 -0
- package/dist/organisms/navigation/_navbar-toggle.scss +91 -0
- package/dist/organisms/navigation/_navbar-tokens.scss +15 -0
- package/dist/organisms/navigation/navbar.scss +17 -0
- package/dist/registry/categories.d.ts +6 -0
- package/dist/registry/categories.d.ts.map +1 -0
- package/dist/registry/categories.js +13 -0
- package/dist/registry/categories.js.map +1 -0
- package/dist/registry/components.d.ts +5 -0
- package/dist/registry/components.d.ts.map +1 -0
- package/dist/registry/components.js +95 -0
- package/dist/registry/components.js.map +1 -0
- package/dist/registry/index.d.ts +59 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +79 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/levels.d.ts +6 -0
- package/dist/registry/levels.d.ts.map +1 -0
- package/dist/registry/levels.js +9 -0
- package/dist/registry/levels.js.map +1 -0
- package/dist/registry/registry-meta-types.d.ts +67 -0
- package/dist/registry/registry-meta-types.d.ts.map +1 -0
- package/dist/registry/registry-meta-types.js +6 -0
- package/dist/registry/registry-meta-types.js.map +1 -0
- package/dist/registry/registry-meta.d.ts +5 -0
- package/dist/registry/registry-meta.d.ts.map +1 -0
- package/dist/registry/registry-meta.js +731 -0
- package/dist/registry/registry-meta.js.map +1 -0
- package/dist/registry/renderer.d.ts +69 -0
- package/dist/registry/renderer.d.ts.map +1 -0
- package/dist/registry/renderer.js +311 -0
- package/dist/registry/renderer.js.map +1 -0
- package/dist/sections/_section-base.scss +204 -0
- package/dist/sections/contact/ContactSection.d.ts +55 -0
- package/dist/sections/contact/ContactSection.d.ts.map +1 -0
- package/dist/sections/contact/ContactSection.js +142 -0
- package/dist/sections/contact/ContactSection.js.map +1 -0
- package/dist/sections/contact/contact-section.scss +142 -0
- package/dist/sections/cta/CTASection.d.ts +52 -0
- package/dist/sections/cta/CTASection.d.ts.map +1 -0
- package/dist/sections/cta/CTASection.js +130 -0
- package/dist/sections/cta/CTASection.js.map +1 -0
- package/dist/sections/cta/cta-section.scss +131 -0
- package/dist/sections/entrance.d.ts +29 -0
- package/dist/sections/entrance.d.ts.map +1 -0
- package/dist/sections/entrance.js +69 -0
- package/dist/sections/entrance.js.map +1 -0
- package/dist/sections/features/FeaturesSection.d.ts +54 -0
- package/dist/sections/features/FeaturesSection.d.ts.map +1 -0
- package/dist/sections/features/FeaturesSection.js +139 -0
- package/dist/sections/features/FeaturesSection.js.map +1 -0
- package/dist/sections/features/features-section.scss +140 -0
- package/dist/sections/footer/FooterSection.d.ts +53 -0
- package/dist/sections/footer/FooterSection.d.ts.map +1 -0
- package/dist/sections/footer/FooterSection.js +147 -0
- package/dist/sections/footer/FooterSection.js.map +1 -0
- package/dist/sections/footer/footer-section.scss +131 -0
- package/dist/sections/hero/HeroSection.d.ts +66 -0
- package/dist/sections/hero/HeroSection.d.ts.map +1 -0
- package/dist/sections/hero/HeroSection.js +156 -0
- package/dist/sections/hero/HeroSection.js.map +1 -0
- package/dist/sections/hero/hero-section.scss +211 -0
- package/dist/shared/_form-animations.scss +283 -0
- package/dist/shared/_media-fit.scss +63 -0
- package/dist/shared/_mixins.scss +69 -0
- package/dist/shared/_tokens.scss +116 -0
- package/dist/shared/badge.d.ts +15 -0
- package/dist/shared/badge.d.ts.map +1 -0
- package/dist/shared/badge.js +15 -0
- package/dist/shared/badge.js.map +1 -0
- package/dist/shared/button.d.ts +22 -0
- package/dist/shared/button.d.ts.map +1 -0
- package/dist/shared/button.js +22 -0
- package/dist/shared/button.js.map +1 -0
- package/dist/shared/card.d.ts +21 -0
- package/dist/shared/card.d.ts.map +1 -0
- package/dist/shared/card.js +38 -0
- package/dist/shared/card.js.map +1 -0
- package/dist/shared/checkbox.d.ts +10 -0
- package/dist/shared/checkbox.d.ts.map +1 -0
- package/dist/shared/checkbox.js +28 -0
- package/dist/shared/checkbox.js.map +1 -0
- package/dist/shared/clickable.d.ts +34 -0
- package/dist/shared/clickable.d.ts.map +1 -0
- package/dist/shared/clickable.js +54 -0
- package/dist/shared/clickable.js.map +1 -0
- package/dist/shared/common.d.ts +31 -0
- package/dist/shared/common.d.ts.map +1 -0
- package/dist/shared/common.js +92 -0
- package/dist/shared/common.js.map +1 -0
- package/dist/shared/entrance-config.d.ts +46 -0
- package/dist/shared/entrance-config.d.ts.map +1 -0
- package/dist/shared/entrance-config.js +54 -0
- package/dist/shared/entrance-config.js.map +1 -0
- package/dist/shared/focusable.d.ts +8 -0
- package/dist/shared/focusable.d.ts.map +1 -0
- package/dist/shared/focusable.js +17 -0
- package/dist/shared/focusable.js.map +1 -0
- package/dist/shared/form-elements.d.ts +57 -0
- package/dist/shared/form-elements.d.ts.map +1 -0
- package/dist/shared/form-elements.js +95 -0
- package/dist/shared/form-elements.js.map +1 -0
- package/dist/shared/form-state.d.ts +52 -0
- package/dist/shared/form-state.d.ts.map +1 -0
- package/dist/shared/form-state.js +151 -0
- package/dist/shared/form-state.js.map +1 -0
- package/dist/shared/grid.d.ts +21 -0
- package/dist/shared/grid.d.ts.map +1 -0
- package/dist/shared/grid.js +187 -0
- package/dist/shared/grid.js.map +1 -0
- package/dist/shared/icon-slot.d.ts +22 -0
- package/dist/shared/icon-slot.d.ts.map +1 -0
- package/dist/shared/icon-slot.js +38 -0
- package/dist/shared/icon-slot.js.map +1 -0
- package/dist/shared/icon.d.ts +17 -0
- package/dist/shared/icon.d.ts.map +1 -0
- package/dist/shared/icon.js +18 -0
- package/dist/shared/icon.js.map +1 -0
- package/dist/shared/icons.d.ts +19 -0
- package/dist/shared/icons.d.ts.map +1 -0
- package/dist/shared/icons.js +22 -0
- package/dist/shared/icons.js.map +1 -0
- package/dist/shared/image.d.ts +35 -0
- package/dist/shared/image.d.ts.map +1 -0
- package/dist/shared/image.js +46 -0
- package/dist/shared/image.js.map +1 -0
- package/dist/shared/input.d.ts +12 -0
- package/dist/shared/input.d.ts.map +1 -0
- package/dist/shared/input.js +29 -0
- package/dist/shared/input.js.map +1 -0
- package/dist/shared/radio.d.ts +10 -0
- package/dist/shared/radio.d.ts.map +1 -0
- package/dist/shared/radio.js +29 -0
- package/dist/shared/radio.js.map +1 -0
- package/dist/shared/reconcile-list.d.ts +37 -0
- package/dist/shared/reconcile-list.d.ts.map +1 -0
- package/dist/shared/reconcile-list.js +95 -0
- package/dist/shared/reconcile-list.js.map +1 -0
- package/dist/shared/section.d.ts +23 -0
- package/dist/shared/section.d.ts.map +1 -0
- package/dist/shared/section.js +65 -0
- package/dist/shared/section.js.map +1 -0
- package/dist/shared/segmented.d.ts +17 -0
- package/dist/shared/segmented.d.ts.map +1 -0
- package/dist/shared/segmented.js +53 -0
- package/dist/shared/segmented.js.map +1 -0
- package/dist/shared/select.d.ts +18 -0
- package/dist/shared/select.d.ts.map +1 -0
- package/dist/shared/select.js +14 -0
- package/dist/shared/select.js.map +1 -0
- package/dist/shared/slots.d.ts +11 -0
- package/dist/shared/slots.d.ts.map +1 -0
- package/dist/shared/slots.js +33 -0
- package/dist/shared/slots.js.map +1 -0
- package/dist/shared/smart-container.d.ts +19 -0
- package/dist/shared/smart-container.d.ts.map +1 -0
- package/dist/shared/smart-container.js +29 -0
- package/dist/shared/smart-container.js.map +1 -0
- package/dist/shared/text.d.ts +29 -0
- package/dist/shared/text.d.ts.map +1 -0
- package/dist/shared/text.js +72 -0
- package/dist/shared/text.js.map +1 -0
- package/dist/shared/textarea.d.ts +6 -0
- package/dist/shared/textarea.d.ts.map +1 -0
- package/dist/shared/textarea.js +18 -0
- package/dist/shared/textarea.js.map +1 -0
- package/dist/shared/toggle.d.ts +6 -0
- package/dist/shared/toggle.d.ts.map +1 -0
- package/dist/shared/toggle.js +19 -0
- package/dist/shared/toggle.js.map +1 -0
- package/dist/shared/types.d.ts +41 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +20 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/structural/ErrorBoundary.d.ts +18 -0
- package/dist/structural/ErrorBoundary.d.ts.map +1 -0
- package/dist/structural/ErrorBoundary.js +119 -0
- package/dist/structural/ErrorBoundary.js.map +1 -0
- package/dist/structural/For.d.ts +37 -0
- package/dist/structural/For.d.ts.map +1 -0
- package/dist/structural/For.js +129 -0
- package/dist/structural/For.js.map +1 -0
- package/dist/structural/Lazy.d.ts +43 -0
- package/dist/structural/Lazy.d.ts.map +1 -0
- package/dist/structural/Lazy.js +47 -0
- package/dist/structural/Lazy.js.map +1 -0
- package/dist/structural/NavLink.d.ts +45 -0
- package/dist/structural/NavLink.d.ts.map +1 -0
- package/dist/structural/NavLink.js +37 -0
- package/dist/structural/NavLink.js.map +1 -0
- package/dist/structural/Show.d.ts +35 -0
- package/dist/structural/Show.d.ts.map +1 -0
- package/dist/structural/Show.js +34 -0
- package/dist/structural/Show.js.map +1 -0
- package/dist/structural/nav-link.scss +54 -0
- package/dist/styles/index.scss +58 -0
- package/package.json +64 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/// Icon component styles
|
|
2
|
+
/// Accessible inline icon wrapper sized by design-system iconography tokens.
|
|
3
|
+
/// Uses currentColor inheritance — zero raw values.
|
|
4
|
+
///
|
|
5
|
+
/// @group atoms/content
|
|
6
|
+
|
|
7
|
+
@use '@pithyjs/design-system/iconography/_generated/tokens' as icon-tokens;
|
|
8
|
+
@use '../mixins' as content;
|
|
9
|
+
|
|
10
|
+
// ============================================
|
|
11
|
+
// Base wrapper — inline icon container
|
|
12
|
+
// ============================================
|
|
13
|
+
|
|
14
|
+
.ui-icon {
|
|
15
|
+
// Inline-flex keeps icon inline with text while centering SVG content
|
|
16
|
+
display: inline-flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
// Shrink-to-fit — default md size (overridden by u-icon-* utilities)
|
|
20
|
+
inline-size: icon-tokens.icon-size-var(md);
|
|
21
|
+
block-size: icon-tokens.icon-size-var(md);
|
|
22
|
+
// Inherit parent text color by default
|
|
23
|
+
color: currentColor;
|
|
24
|
+
// Ensure SVG children fill the container
|
|
25
|
+
line-height: 0;
|
|
26
|
+
// Clip overflow — fixed-size box should not leak content beyond its bounds
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
// Prevent icon from shrinking in flex layouts
|
|
29
|
+
flex-shrink: 0;
|
|
30
|
+
// Optical alignment with adjacent text
|
|
31
|
+
vertical-align: middle;
|
|
32
|
+
|
|
33
|
+
// SVG children should fill the icon container.
|
|
34
|
+
// No fill/stroke override — SVGs control their own rendering:
|
|
35
|
+
// Solid icons: use fill="currentColor" (or inherit from parent color)
|
|
36
|
+
// Outline icons: use fill="none" stroke="currentColor"
|
|
37
|
+
// This avoids CSS fill overriding SVG presentation attributes.
|
|
38
|
+
> svg {
|
|
39
|
+
inline-size: 100%;
|
|
40
|
+
block-size: 100%;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ============================================
|
|
45
|
+
// Size variants (from --icon-size-* tokens)
|
|
46
|
+
// ============================================
|
|
47
|
+
|
|
48
|
+
@each $level, $_value in icon-tokens.$size-tokens {
|
|
49
|
+
.u-icon-#{$level} {
|
|
50
|
+
inline-size: icon-tokens.icon-size-var($level);
|
|
51
|
+
block-size: icon-tokens.icon-size-var($level);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ============================================
|
|
56
|
+
// Color scheme (maps data-color to --color-* tokens)
|
|
57
|
+
// ============================================
|
|
58
|
+
|
|
59
|
+
@include content.color-scheme('.ui-icon');
|
|
60
|
+
|
|
61
|
+
// ============================================
|
|
62
|
+
// High Contrast (forced-colors + increased contrast)
|
|
63
|
+
// ============================================
|
|
64
|
+
|
|
65
|
+
@include content.forced-colors('.ui-icon');
|
|
66
|
+
@include content.high-contrast('.ui-icon');
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @codex
|
|
2
|
+
{
|
|
3
|
+
"id": "pithy.ui-kit.icon-resolve",
|
|
4
|
+
"title": "Icon Sprite SVG Resolution",
|
|
5
|
+
"category": "runtime"
|
|
6
|
+
}
|
|
7
|
+
*/
|
|
8
|
+
export interface ResolvedIcon {
|
|
9
|
+
/** The SVG element to append */
|
|
10
|
+
svg: SVGSVGElement;
|
|
11
|
+
/** Whether this is a missing-icon placeholder */
|
|
12
|
+
missing: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Try to resolve `name` from the icon sprite registry.
|
|
16
|
+
*
|
|
17
|
+
* @returns A resolved icon with `svg` and `missing` flag, or `null` if no name was provided.
|
|
18
|
+
*/
|
|
19
|
+
/** @codexApi {"parent":"pithy.ui-kit.icon-resolve","name":"resolveIconSvg","stability":"stable","signature":"(name: string | undefined) => ResolvedIcon | null"} */
|
|
20
|
+
export declare function resolveIconSvg(name: string | undefined): ResolvedIcon | null;
|
|
21
|
+
//# sourceMappingURL=resolveIconSvg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveIconSvg.d.ts","sourceRoot":"","sources":["../../../../src/atoms/content/icon/resolveIconSvg.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAiBF,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,GAAG,EAAE,aAAa,CAAC;IACnB,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,oKAAoK;AACpK,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,IAAI,CA2B5E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** @codex
|
|
2
|
+
{
|
|
3
|
+
"id": "pithy.ui-kit.icon-resolve",
|
|
4
|
+
"title": "Icon Sprite SVG Resolution",
|
|
5
|
+
"category": "runtime"
|
|
6
|
+
}
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Resolve an icon name to an SVG element from the sprite registry.
|
|
10
|
+
*
|
|
11
|
+
* Returns a ready-to-append `<svg>` element:
|
|
12
|
+
* - Found → `<svg><use href="sprite#name"/></svg>`
|
|
13
|
+
* - Not found → placeholder (dashed circle + "?") with DEV warning
|
|
14
|
+
* - No name → `null`
|
|
15
|
+
*/
|
|
16
|
+
// Relative import to avoid self-referencing package alias (@pithyjs/ui-kit/icons).
|
|
17
|
+
// Maps to: packages/ui-kit/src/icons/index.ts
|
|
18
|
+
import { lookupIcon } from '../../../icons';
|
|
19
|
+
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
20
|
+
/**
|
|
21
|
+
* Try to resolve `name` from the icon sprite registry.
|
|
22
|
+
*
|
|
23
|
+
* @returns A resolved icon with `svg` and `missing` flag, or `null` if no name was provided.
|
|
24
|
+
*/
|
|
25
|
+
/** @codexApi {"parent":"pithy.ui-kit.icon-resolve","name":"resolveIconSvg","stability":"stable","signature":"(name: string | undefined) => ResolvedIcon | null"} */
|
|
26
|
+
export function resolveIconSvg(name) {
|
|
27
|
+
const trimmed = name?.trim();
|
|
28
|
+
if (!trimmed)
|
|
29
|
+
return null;
|
|
30
|
+
const result = lookupIcon(trimmed);
|
|
31
|
+
if (result) {
|
|
32
|
+
const svg = document.createElementNS(SVG_NS, 'svg');
|
|
33
|
+
svg.setAttribute('aria-hidden', 'true');
|
|
34
|
+
if (result.viewBox) {
|
|
35
|
+
svg.setAttribute('viewBox', result.viewBox);
|
|
36
|
+
}
|
|
37
|
+
const use = document.createElementNS(SVG_NS, 'use');
|
|
38
|
+
use.setAttribute('href', result.href);
|
|
39
|
+
svg.appendChild(use);
|
|
40
|
+
return { svg, missing: false };
|
|
41
|
+
}
|
|
42
|
+
// Missing icon — placeholder: dashed circle + "?"
|
|
43
|
+
if (import.meta.env?.DEV) {
|
|
44
|
+
console.warn(`[<Icon>] name="${name}" not found in icon registry and no children provided. ` +
|
|
45
|
+
`Either register a sprite with registerIconSprite() or pass inline SVG as children.`);
|
|
46
|
+
}
|
|
47
|
+
return { svg: createMissingIconSvg(), missing: true };
|
|
48
|
+
}
|
|
49
|
+
function createMissingIconSvg() {
|
|
50
|
+
const svg = document.createElementNS(SVG_NS, 'svg');
|
|
51
|
+
svg.setAttribute('aria-hidden', 'true');
|
|
52
|
+
svg.setAttribute('viewBox', '0 0 24 24');
|
|
53
|
+
svg.setAttribute('fill', 'none');
|
|
54
|
+
svg.setAttribute('stroke', 'currentColor');
|
|
55
|
+
svg.setAttribute('stroke-width', '1.5');
|
|
56
|
+
const circle = document.createElementNS(SVG_NS, 'circle');
|
|
57
|
+
circle.setAttribute('cx', '12');
|
|
58
|
+
circle.setAttribute('cy', '12');
|
|
59
|
+
circle.setAttribute('r', '10');
|
|
60
|
+
circle.setAttribute('stroke-dasharray', '4 3');
|
|
61
|
+
svg.appendChild(circle);
|
|
62
|
+
const text = document.createElementNS(SVG_NS, 'text');
|
|
63
|
+
text.setAttribute('x', '12');
|
|
64
|
+
text.setAttribute('y', '16');
|
|
65
|
+
text.setAttribute('text-anchor', 'middle');
|
|
66
|
+
text.setAttribute('fill', 'currentColor');
|
|
67
|
+
text.setAttribute('stroke', 'none');
|
|
68
|
+
text.setAttribute('font-size', '12');
|
|
69
|
+
text.textContent = '?';
|
|
70
|
+
svg.appendChild(text);
|
|
71
|
+
return svg;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=resolveIconSvg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveIconSvg.js","sourceRoot":"","sources":["../../../../src/atoms/content/icon/resolveIconSvg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** @codex
|
|
2
|
+
{
|
|
3
|
+
"id": "pithy.ui-kit.image",
|
|
4
|
+
"title": "<Image> Content Component",
|
|
5
|
+
"category": "feature"
|
|
6
|
+
}
|
|
7
|
+
*/
|
|
8
|
+
import type { ReactiveText } from '../../../shared/clickable';
|
|
9
|
+
import { type ImageFit, type ImageLoading, type ImageDecoding, type ImageFetchPriority, type ImageSizing } from '../../../shared/image';
|
|
10
|
+
import { type RadiusLevel } from '@pithyjs/design-system/radius';
|
|
11
|
+
/** @codexApi {"parent":"pithy.ui-kit.image","name":"ImageSource","stability":"stable","signature":"interface ImageSource"} */
|
|
12
|
+
/**
|
|
13
|
+
* A single `<source>` entry for `<picture>` multi-format rendering.
|
|
14
|
+
* Each source must have at least one of `src` or `srcset`.
|
|
15
|
+
*
|
|
16
|
+
* Note: the root-level `ImageProps.src` is always required for the fallback
|
|
17
|
+
* `<img>` element. These sources only add `<source>` alternatives inside
|
|
18
|
+
* `<picture>` — they do not replace the root `src`.
|
|
19
|
+
*/
|
|
20
|
+
export interface ImageSource {
|
|
21
|
+
/** Image URL — required if `srcset` is not provided */
|
|
22
|
+
src?: string;
|
|
23
|
+
/** MIME type (e.g. "image/avif", "image/webp") */
|
|
24
|
+
type?: string;
|
|
25
|
+
/** Media condition (e.g. "(min-width: 768px)") */
|
|
26
|
+
media?: string;
|
|
27
|
+
/** Srcset descriptor (e.g. "img.avif 1x, img.avif 2x" or "img-400.avif 400w") */
|
|
28
|
+
srcset?: string;
|
|
29
|
+
}
|
|
30
|
+
/** @codexApi {"parent":"pithy.ui-kit.image","name":"ImageProps","stability":"stable","signature":"interface ImageProps"} */
|
|
31
|
+
export interface ImageProps {
|
|
32
|
+
/** Image source URL — static string or signal/computed accessor. Required. */
|
|
33
|
+
src: ReactiveText;
|
|
34
|
+
/** Alt text for accessibility — static or signal. REQUIRED. Use "" only for purely decorative images. */
|
|
35
|
+
alt: ReactiveText;
|
|
36
|
+
/** Intrinsic width in pixels — prevents layout shift (CLS) */
|
|
37
|
+
width?: number;
|
|
38
|
+
/** Intrinsic height in pixels — prevents layout shift (CLS) */
|
|
39
|
+
height?: number;
|
|
40
|
+
/** Loading strategy (default: "lazy") */
|
|
41
|
+
loading?: ImageLoading;
|
|
42
|
+
/** Decoding strategy (default: "async") */
|
|
43
|
+
decoding?: ImageDecoding;
|
|
44
|
+
/** Fetch priority hint — use "high" for LCP images (default: "auto") */
|
|
45
|
+
fetchPriority?: ImageFetchPriority;
|
|
46
|
+
/** Aspect ratio — preset string ("16/9") or custom CSS value ("4 / 3") */
|
|
47
|
+
aspectRatio?: string;
|
|
48
|
+
/** Object-fit — how the image fills its container (default: "cover") */
|
|
49
|
+
fit?: ImageFit;
|
|
50
|
+
/** Width behaviour — "auto" (intrinsic, capped at 100%) or "fill" (100% of container). Default: "auto". */
|
|
51
|
+
sizing?: ImageSizing;
|
|
52
|
+
/** Responsive sizes attribute (e.g. "(max-width: 600px) 100vw, 50vw") */
|
|
53
|
+
sizes?: string;
|
|
54
|
+
/** Srcset for responsive resolution switching (e.g. "img-400.jpg 400w, img-800.jpg 800w") */
|
|
55
|
+
srcset?: string;
|
|
56
|
+
/** Additional <source> elements for <picture> — enables AVIF/WebP with fallback */
|
|
57
|
+
sources?: ImageSource[];
|
|
58
|
+
/** Border radius — design system RadiusLevel or true for "md" (default: none) */
|
|
59
|
+
rounded?: boolean | RadiusLevel;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Accessible, optimized image component.
|
|
63
|
+
*
|
|
64
|
+
* Mobile-first with lazy loading and async decoding by default.
|
|
65
|
+
* Enforces `alt` text for accessibility. Use `width`/`height` to eliminate
|
|
66
|
+
* layout shift (CLS = 0). Supports `<picture>` with multiple `<source>`
|
|
67
|
+
* elements for format negotiation (AVIF, WebP, fallback).
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```html
|
|
71
|
+
* <Image src="'/photo.jpg'" alt="'A sunset'" width="800" height="600" />
|
|
72
|
+
* <Image src="'/hero.jpg'" alt="'Hero'" aspectRatio="'16/9'" fit="'cover'" loading="'eager'" fetchPriority="'high'" />
|
|
73
|
+
* <Image src="'/avatar.jpg'" alt="'User'" width="100" height="100" rounded="'xl'" />
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
/** @codexApi {"parent":"pithy.ui-kit.image","name":"Image","stability":"stable","signature":"(props: ImageProps) => { el: HTMLElement | DocumentFragment; destroy: () => void }"} */
|
|
77
|
+
export declare function Image(props: ImageProps): {
|
|
78
|
+
el: HTMLElement | DocumentFragment;
|
|
79
|
+
destroy: () => void;
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=Image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Image.d.ts","sourceRoot":"","sources":["../../../../src/atoms/content/image/Image.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAKF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAOL,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAIhF,8HAA8H;AAC9H;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,4HAA4H;AAC5H,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,GAAG,EAAE,YAAY,CAAC;IAClB,yGAAyG;IACzG,GAAG,EAAE,YAAY,CAAC;IAClB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,wEAAwE;IACxE,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,2GAA2G;IAC3G,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;CACjC;AAED;;;;;;;;;;;;;;GAcG;AACH,qLAAqL;AACrL,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG;IACxC,EAAE,EAAE,WAAW,GAAG,gBAAgB,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAkVA"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/** @codex
|
|
2
|
+
{
|
|
3
|
+
"id": "pithy.ui-kit.image",
|
|
4
|
+
"title": "<Image> Content Component",
|
|
5
|
+
"category": "feature"
|
|
6
|
+
}
|
|
7
|
+
*/
|
|
8
|
+
import { renderChildren } from '@pithyjs/core';
|
|
9
|
+
import { captureSlot } from '../../../shared/slots';
|
|
10
|
+
import { effect } from '@pithyjs/signals';
|
|
11
|
+
import { IMAGE_FIT_VALUES, IMAGE_LOADING_VALUES, IMAGE_DECODING_VALUES, IMAGE_FETCH_PRIORITY_VALUES, IMAGE_SIZING_VALUES, ASPECT_RATIO_PRESETS, } from '../../../shared/image';
|
|
12
|
+
import { RADIUS_LEVELS } from '@pithyjs/design-system/radius';
|
|
13
|
+
/**
|
|
14
|
+
* Accessible, optimized image component.
|
|
15
|
+
*
|
|
16
|
+
* Mobile-first with lazy loading and async decoding by default.
|
|
17
|
+
* Enforces `alt` text for accessibility. Use `width`/`height` to eliminate
|
|
18
|
+
* layout shift (CLS = 0). Supports `<picture>` with multiple `<source>`
|
|
19
|
+
* elements for format negotiation (AVIF, WebP, fallback).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```html
|
|
23
|
+
* <Image src="'/photo.jpg'" alt="'A sunset'" width="800" height="600" />
|
|
24
|
+
* <Image src="'/hero.jpg'" alt="'Hero'" aspectRatio="'16/9'" fit="'cover'" loading="'eager'" fetchPriority="'high'" />
|
|
25
|
+
* <Image src="'/avatar.jpg'" alt="'User'" width="100" height="100" rounded="'xl'" />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
/** @codexApi {"parent":"pithy.ui-kit.image","name":"Image","stability":"stable","signature":"(props: ImageProps) => { el: HTMLElement | DocumentFragment; destroy: () => void }"} */
|
|
29
|
+
export function Image(props) {
|
|
30
|
+
const { src: srcProp, alt: altProp, width, height, loading: rawLoading = 'lazy', decoding: rawDecoding = 'async', fetchPriority: rawFetchPriority = 'auto', aspectRatio: rawAspectRatio, fit: rawFit = 'cover', sizing: rawSizing = 'auto', sizes, srcset, sources, rounded, } = props;
|
|
31
|
+
const isSrcFn = typeof srcProp === 'function';
|
|
32
|
+
const isAltFn = typeof altProp === 'function';
|
|
33
|
+
const readSrc = () => isSrcFn
|
|
34
|
+
? srcProp()
|
|
35
|
+
: srcProp;
|
|
36
|
+
const readAlt = () => isAltFn
|
|
37
|
+
? altProp()
|
|
38
|
+
: altProp;
|
|
39
|
+
const staticSrc = isSrcFn ? undefined : readSrc();
|
|
40
|
+
const staticAlt = isAltFn ? undefined : readAlt();
|
|
41
|
+
// -- Validation -----------------------------------------------------------
|
|
42
|
+
const hasSrc = typeof staticSrc === 'string' && staticSrc.trim().length > 0;
|
|
43
|
+
// Whitespace-only alt is treated as missing (warned in DEV); intentionally
|
|
44
|
+
// empty alt ("") is allowed and marks the image as decorative.
|
|
45
|
+
const isValidAlt = (v) => typeof v === 'string' && (v === '' || v.trim().length > 0);
|
|
46
|
+
const hasAlt = isValidAlt(staticAlt);
|
|
47
|
+
const validLoading = IMAGE_LOADING_VALUES.includes(rawLoading);
|
|
48
|
+
const validDecoding = IMAGE_DECODING_VALUES.includes(rawDecoding);
|
|
49
|
+
const validFetchPriority = IMAGE_FETCH_PRIORITY_VALUES.includes(rawFetchPriority);
|
|
50
|
+
const validFit = IMAGE_FIT_VALUES.includes(rawFit);
|
|
51
|
+
const sizing = IMAGE_SIZING_VALUES.includes(rawSizing)
|
|
52
|
+
? rawSizing
|
|
53
|
+
: 'auto';
|
|
54
|
+
// Sanitize width/height: must be finite positive integers (at least 1px)
|
|
55
|
+
const validWidth = width != null && Number.isFinite(width) && width > 0
|
|
56
|
+
? Math.max(1, Math.round(width))
|
|
57
|
+
: undefined;
|
|
58
|
+
const validHeight = height != null && Number.isFinite(height) && height > 0
|
|
59
|
+
? Math.max(1, Math.round(height))
|
|
60
|
+
: undefined;
|
|
61
|
+
// Validate rounded prop
|
|
62
|
+
const validRounded = rounded === true
|
|
63
|
+
? 'md'
|
|
64
|
+
: typeof rounded === 'string' &&
|
|
65
|
+
RADIUS_LEVELS.includes(rounded)
|
|
66
|
+
? rounded
|
|
67
|
+
: undefined;
|
|
68
|
+
if (import.meta.env?.DEV) {
|
|
69
|
+
if (!isSrcFn && !hasSrc) {
|
|
70
|
+
console.warn(`[<Image>] Missing or empty "src" prop. An image source is required.`);
|
|
71
|
+
}
|
|
72
|
+
if (!isAltFn && !hasAlt) {
|
|
73
|
+
console.warn(`[<Image>] Missing "alt" prop. All images MUST have alt text for accessibility. Use alt="" only for purely decorative images.`);
|
|
74
|
+
}
|
|
75
|
+
if (!validLoading) {
|
|
76
|
+
const valid = IMAGE_LOADING_VALUES.join(', ');
|
|
77
|
+
console.warn(`[<Image>] Invalid loading: "${rawLoading}". Expected one of: ${valid}. Falling back to "lazy".`);
|
|
78
|
+
}
|
|
79
|
+
if (!validDecoding) {
|
|
80
|
+
const valid = IMAGE_DECODING_VALUES.join(', ');
|
|
81
|
+
console.warn(`[<Image>] Invalid decoding: "${rawDecoding}". Expected one of: ${valid}. Falling back to "async".`);
|
|
82
|
+
}
|
|
83
|
+
if (!validFetchPriority) {
|
|
84
|
+
const valid = IMAGE_FETCH_PRIORITY_VALUES.join(', ');
|
|
85
|
+
console.warn(`[<Image>] Invalid fetchPriority: "${rawFetchPriority}". Expected one of: ${valid}. Falling back to "auto".`);
|
|
86
|
+
}
|
|
87
|
+
if (!validFit) {
|
|
88
|
+
const valid = IMAGE_FIT_VALUES.join(', ');
|
|
89
|
+
console.warn(`[<Image>] Invalid fit: "${rawFit}". Expected one of: ${valid}. Falling back to "cover".`);
|
|
90
|
+
}
|
|
91
|
+
if (rawLoading === 'lazy' && rawFetchPriority === 'high') {
|
|
92
|
+
console.warn(`[<Image>] loading="lazy" with fetchPriority="high" is contradictory. For LCP images, use loading="eager" with fetchPriority="high".`);
|
|
93
|
+
}
|
|
94
|
+
if (width == null || height == null) {
|
|
95
|
+
console.warn(`[<Image>] Missing width/height. Provide both to prevent layout shift (CLS). The browser needs intrinsic dimensions to reserve space before the image loads.`);
|
|
96
|
+
}
|
|
97
|
+
if (width != null && (!Number.isFinite(width) || width <= 0)) {
|
|
98
|
+
console.warn(`[<Image>] Invalid width: ${width}. Expected a finite positive number. Ignoring.`);
|
|
99
|
+
}
|
|
100
|
+
if (height != null && (!Number.isFinite(height) || height <= 0)) {
|
|
101
|
+
console.warn(`[<Image>] Invalid height: ${height}. Expected a finite positive number. Ignoring.`);
|
|
102
|
+
}
|
|
103
|
+
if (rounded != null &&
|
|
104
|
+
rounded !== true &&
|
|
105
|
+
rounded !== false &&
|
|
106
|
+
!validRounded) {
|
|
107
|
+
const valid = RADIUS_LEVELS.join(', ');
|
|
108
|
+
console.warn(`[<Image>] Invalid rounded: "${rounded}". Expected true or one of: ${valid}. Ignoring.`);
|
|
109
|
+
}
|
|
110
|
+
if (sources != null && !Array.isArray(sources)) {
|
|
111
|
+
console.warn(`[<Image>] Invalid "sources" prop: expected an array of ImageSource objects. Falling back to plain <img>.`);
|
|
112
|
+
}
|
|
113
|
+
if (Array.isArray(sources) &&
|
|
114
|
+
sources.some(s => s == null ||
|
|
115
|
+
typeof s !== 'object' ||
|
|
116
|
+
((typeof s.src !== 'string' || s.src.trim().length === 0) &&
|
|
117
|
+
(typeof s.srcset !== 'string' || s.srcset.trim().length === 0)))) {
|
|
118
|
+
console.warn(`[<Image>] Some entries in "sources" are invalid: each source must be an object with a non-empty "src" or "srcset" string.`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const loading = validLoading ? rawLoading : 'lazy';
|
|
122
|
+
const decoding = validDecoding ? rawDecoding : 'async';
|
|
123
|
+
const fetchPriority = validFetchPriority ? rawFetchPriority : 'auto';
|
|
124
|
+
const fit = validFit ? rawFit : 'cover';
|
|
125
|
+
// Resolve aspect ratio (preset or custom CSS value)
|
|
126
|
+
const aspectRatio = rawAspectRatio
|
|
127
|
+
? ASPECT_RATIO_PRESETS[rawAspectRatio] || rawAspectRatio
|
|
128
|
+
: undefined;
|
|
129
|
+
// -- Determine rendering mode: <picture> or plain <img> -------------------
|
|
130
|
+
const usePicture = Array.isArray(sources) && sources.length > 0;
|
|
131
|
+
// -- Build wrapper element ------------------------------------------------
|
|
132
|
+
const el = document.createElement('div');
|
|
133
|
+
el.classList.add('ui-image');
|
|
134
|
+
if (sizing === 'fill') {
|
|
135
|
+
el.dataset.sizing = 'fill';
|
|
136
|
+
}
|
|
137
|
+
// Aspect ratio container
|
|
138
|
+
if (aspectRatio) {
|
|
139
|
+
el.style.aspectRatio = aspectRatio;
|
|
140
|
+
el.classList.add('ui-image-aspect-ratio');
|
|
141
|
+
}
|
|
142
|
+
// Rounded corners — maps to design system u-radius-* utilities
|
|
143
|
+
if (validRounded) {
|
|
144
|
+
el.classList.add(`u-radius-${validRounded}`);
|
|
145
|
+
}
|
|
146
|
+
// Width/height on wrapper to reserve space (CLS prevention)
|
|
147
|
+
if (validWidth != null && !aspectRatio) {
|
|
148
|
+
el.style.maxInlineSize = `${validWidth}px`;
|
|
149
|
+
}
|
|
150
|
+
// -- Build image content or empty placeholder -----------------------------
|
|
151
|
+
// Applied separately so buildImageContent doesn't subscribe its caller to alt.
|
|
152
|
+
const applyAlt = (target, value) => {
|
|
153
|
+
if (isValidAlt(value)) {
|
|
154
|
+
target.alt = value;
|
|
155
|
+
if (value === '')
|
|
156
|
+
target.setAttribute('role', 'none');
|
|
157
|
+
else
|
|
158
|
+
target.removeAttribute('role');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
target.removeAttribute('alt');
|
|
162
|
+
target.removeAttribute('role');
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const buildImageContent = (src) => {
|
|
166
|
+
const newImg = document.createElement('img');
|
|
167
|
+
newImg.classList.add('ui-image-img');
|
|
168
|
+
newImg.src = src;
|
|
169
|
+
newImg.loading = loading;
|
|
170
|
+
newImg.decoding = decoding;
|
|
171
|
+
if (fetchPriority !== 'auto') {
|
|
172
|
+
newImg.setAttribute('fetchpriority', fetchPriority);
|
|
173
|
+
}
|
|
174
|
+
if (validWidth != null)
|
|
175
|
+
newImg.width = validWidth;
|
|
176
|
+
if (validHeight != null)
|
|
177
|
+
newImg.height = validHeight;
|
|
178
|
+
if (fit)
|
|
179
|
+
newImg.style.objectFit = fit;
|
|
180
|
+
if (typeof sizes === 'string') {
|
|
181
|
+
const trimmedSizes = sizes.trim();
|
|
182
|
+
if (trimmedSizes.length > 0)
|
|
183
|
+
newImg.sizes = trimmedSizes;
|
|
184
|
+
}
|
|
185
|
+
if (typeof srcset === 'string') {
|
|
186
|
+
const trimmedSrcset = srcset.trim();
|
|
187
|
+
if (trimmedSrcset.length > 0)
|
|
188
|
+
newImg.srcset = trimmedSrcset;
|
|
189
|
+
}
|
|
190
|
+
const pictureSources = usePicture ? sources : [];
|
|
191
|
+
if (pictureSources.length === 0)
|
|
192
|
+
return { root: newImg, img: newImg };
|
|
193
|
+
const picture = document.createElement('picture');
|
|
194
|
+
picture.classList.add('ui-image-picture');
|
|
195
|
+
for (const source of pictureSources) {
|
|
196
|
+
const trimmedSrc = typeof source?.src === 'string' ? source.src.trim() : '';
|
|
197
|
+
const trimmedSrcset = typeof source?.srcset === 'string' ? source.srcset.trim() : '';
|
|
198
|
+
if (source == null ||
|
|
199
|
+
typeof source !== 'object' ||
|
|
200
|
+
(!trimmedSrc && !trimmedSrcset)) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const sourceEl = document.createElement('source');
|
|
204
|
+
sourceEl.srcset = trimmedSrcset || trimmedSrc;
|
|
205
|
+
if (typeof source.type === 'string') {
|
|
206
|
+
const trimmedType = source.type.trim();
|
|
207
|
+
if (trimmedType)
|
|
208
|
+
sourceEl.type = trimmedType;
|
|
209
|
+
}
|
|
210
|
+
if (typeof source.media === 'string') {
|
|
211
|
+
const trimmedMedia = source.media.trim();
|
|
212
|
+
if (trimmedMedia)
|
|
213
|
+
sourceEl.media = trimmedMedia;
|
|
214
|
+
}
|
|
215
|
+
if (typeof sizes === 'string') {
|
|
216
|
+
const trimmedSizes = sizes.trim();
|
|
217
|
+
if (trimmedSizes.length > 0)
|
|
218
|
+
sourceEl.sizes = trimmedSizes;
|
|
219
|
+
}
|
|
220
|
+
picture.appendChild(sourceEl);
|
|
221
|
+
}
|
|
222
|
+
if (picture.childElementCount === 0)
|
|
223
|
+
return { root: newImg, img: newImg };
|
|
224
|
+
picture.appendChild(newImg);
|
|
225
|
+
return { root: picture, img: newImg };
|
|
226
|
+
};
|
|
227
|
+
let img;
|
|
228
|
+
let contentRoot;
|
|
229
|
+
if (hasSrc) {
|
|
230
|
+
const built = buildImageContent(staticSrc.trim());
|
|
231
|
+
contentRoot = built.root;
|
|
232
|
+
img = built.img;
|
|
233
|
+
if (!isAltFn)
|
|
234
|
+
applyAlt(img, staticAlt);
|
|
235
|
+
el.appendChild(contentRoot);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// No valid src — render an empty placeholder to avoid a spurious
|
|
239
|
+
// network request (setting img.src="" resolves to the document URL).
|
|
240
|
+
el.classList.add('ui-image-empty');
|
|
241
|
+
}
|
|
242
|
+
// Content projection (for overlay content like captions). Anchored after the
|
|
243
|
+
// image so reactive remounts can insertBefore() to preserve DOM order.
|
|
244
|
+
const { el: childFragment, destroy } = renderChildren();
|
|
245
|
+
captureSlot(el, 'default');
|
|
246
|
+
const childAnchor = document.createComment('');
|
|
247
|
+
el.appendChild(childAnchor);
|
|
248
|
+
el.appendChild(childFragment);
|
|
249
|
+
// Reactive src — handles empty ↔ non-empty transitions by mounting/unmounting
|
|
250
|
+
// the <img>/<picture>. Static-string src never changes, so we skip the effect.
|
|
251
|
+
const cleanupSrcEffect = isSrcFn
|
|
252
|
+
? effect(() => {
|
|
253
|
+
const next = readSrc();
|
|
254
|
+
const trimmed = typeof next === 'string' ? next.trim() : '';
|
|
255
|
+
if (trimmed.length > 0) {
|
|
256
|
+
if (img) {
|
|
257
|
+
img.src = trimmed;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
const built = buildImageContent(trimmed);
|
|
261
|
+
contentRoot = built.root;
|
|
262
|
+
img = built.img;
|
|
263
|
+
applyAlt(img, isAltFn ? readAlt() : staticAlt);
|
|
264
|
+
el.classList.remove('ui-image-empty');
|
|
265
|
+
el.insertBefore(contentRoot, childAnchor);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else if (contentRoot) {
|
|
269
|
+
contentRoot.remove();
|
|
270
|
+
contentRoot = undefined;
|
|
271
|
+
img = undefined;
|
|
272
|
+
el.classList.add('ui-image-empty');
|
|
273
|
+
}
|
|
274
|
+
})
|
|
275
|
+
: undefined;
|
|
276
|
+
const cleanupAltEffect = isAltFn
|
|
277
|
+
? effect(() => {
|
|
278
|
+
const next = readAlt();
|
|
279
|
+
if (img)
|
|
280
|
+
applyAlt(img, next);
|
|
281
|
+
})
|
|
282
|
+
: undefined;
|
|
283
|
+
return {
|
|
284
|
+
el,
|
|
285
|
+
destroy: () => {
|
|
286
|
+
cleanupSrcEffect?.();
|
|
287
|
+
cleanupAltEffect?.();
|
|
288
|
+
destroy();
|
|
289
|
+
el.replaceChildren();
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=Image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Image.js","sourceRoot":"","sources":["../../../../src/atoms/content/image/Image.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/// Image component styles
|
|
2
|
+
/// Optimized, accessible image rendering with CLS prevention.
|
|
3
|
+
/// Uses design system tokens -- zero raw values.
|
|
4
|
+
///
|
|
5
|
+
/// @group atoms/content
|
|
6
|
+
|
|
7
|
+
@use '@pithyjs/design-system/a11y/styles/mixins' as a11y;
|
|
8
|
+
|
|
9
|
+
// ============================================
|
|
10
|
+
// Base wrapper — reserves space, prevents CLS
|
|
11
|
+
// ============================================
|
|
12
|
+
|
|
13
|
+
.ui-image {
|
|
14
|
+
// Block element by default for layout control
|
|
15
|
+
display: block;
|
|
16
|
+
position: relative;
|
|
17
|
+
// Prevent overflow from rounded corners or aspect ratio
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
// Logical max-width: never exceed container
|
|
20
|
+
max-inline-size: 100%;
|
|
21
|
+
// Intrinsic sizing: shrink-to-fit by default
|
|
22
|
+
inline-size: fit-content;
|
|
23
|
+
|
|
24
|
+
&[data-sizing='fill'] {
|
|
25
|
+
inline-size: 100%;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ============================================
|
|
30
|
+
// <img> element — fills the container
|
|
31
|
+
// ============================================
|
|
32
|
+
|
|
33
|
+
.ui-image-img {
|
|
34
|
+
// Fill the wrapper completely
|
|
35
|
+
display: block;
|
|
36
|
+
inline-size: 100%;
|
|
37
|
+
block-size: 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// When aspect ratio is set on the wrapper, img fills it
|
|
41
|
+
.ui-image-aspect-ratio .ui-image-img {
|
|
42
|
+
// Ensure image fills the entire aspect ratio box
|
|
43
|
+
object-fit: cover;
|
|
44
|
+
block-size: 100%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ============================================
|
|
48
|
+
// <picture> element — transparent wrapper
|
|
49
|
+
// ============================================
|
|
50
|
+
|
|
51
|
+
.ui-image-picture {
|
|
52
|
+
display: contents;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ============================================
|
|
56
|
+
// High Contrast (forced-colors)
|
|
57
|
+
// ============================================
|
|
58
|
+
|
|
59
|
+
@include a11y.forced-colors {
|
|
60
|
+
// In high contrast mode, ensure images remain visible.
|
|
61
|
+
// Add a thin border so users know an image is present.
|
|
62
|
+
.ui-image {
|
|
63
|
+
border: var(--border-width-hairline) solid CanvasText;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ============================================
|
|
68
|
+
// Reduced motion — pause CSS animations on images
|
|
69
|
+
// ============================================
|
|
70
|
+
|
|
71
|
+
@include a11y.motion-reduced {
|
|
72
|
+
.ui-image-img {
|
|
73
|
+
// Pause any CSS animations applied to the <img> when reduced motion is requested
|
|
74
|
+
// Note: this does not stop GIF/APNG playback; it only affects CSS-driven animations
|
|
75
|
+
animation-play-state: paused;
|
|
76
|
+
}
|
|
77
|
+
}
|