@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,92 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.shared-common", "title": "Shared Utility Class Maps", "category": "types" } */
|
|
2
|
+
// -- Gap classes (mirrors SPACING_SIZES from @pithyjs/design-system) -----------
|
|
3
|
+
export const GAP_CLASS = {
|
|
4
|
+
'0': 'u-gap-0',
|
|
5
|
+
xs: 'u-gap-xs',
|
|
6
|
+
sm: 'u-gap-sm',
|
|
7
|
+
md: 'u-gap-md',
|
|
8
|
+
lg: 'u-gap-lg',
|
|
9
|
+
xl: 'u-gap-xl',
|
|
10
|
+
};
|
|
11
|
+
// -- Row-gap classes --------------------------------------------------------
|
|
12
|
+
export const ROW_GAP_CLASS = {
|
|
13
|
+
'0': 'u-row-gap-0',
|
|
14
|
+
xs: 'u-row-gap-xs',
|
|
15
|
+
sm: 'u-row-gap-sm',
|
|
16
|
+
md: 'u-row-gap-md',
|
|
17
|
+
lg: 'u-row-gap-lg',
|
|
18
|
+
xl: 'u-row-gap-xl',
|
|
19
|
+
};
|
|
20
|
+
// -- Col-gap classes --------------------------------------------------------
|
|
21
|
+
export const COL_GAP_CLASS = {
|
|
22
|
+
'0': 'u-col-gap-0',
|
|
23
|
+
xs: 'u-col-gap-xs',
|
|
24
|
+
sm: 'u-col-gap-sm',
|
|
25
|
+
md: 'u-col-gap-md',
|
|
26
|
+
lg: 'u-col-gap-lg',
|
|
27
|
+
xl: 'u-col-gap-xl',
|
|
28
|
+
};
|
|
29
|
+
// -- Align-items classes (mirrors $_align-items-values in layout SCSS) --------
|
|
30
|
+
const ALIGN_ITEMS = ['start', 'center', 'end', 'stretch', 'baseline'];
|
|
31
|
+
export const ALIGN_CLASS = {
|
|
32
|
+
start: 'u-items-start',
|
|
33
|
+
center: 'u-items-center',
|
|
34
|
+
end: 'u-items-end',
|
|
35
|
+
stretch: 'u-items-stretch',
|
|
36
|
+
baseline: 'u-items-baseline',
|
|
37
|
+
};
|
|
38
|
+
// -- Justify-content classes ------------------------------------------------
|
|
39
|
+
const JUSTIFY_ITEMS = [
|
|
40
|
+
'start',
|
|
41
|
+
'end',
|
|
42
|
+
'center',
|
|
43
|
+
'between',
|
|
44
|
+
'around',
|
|
45
|
+
'evenly',
|
|
46
|
+
];
|
|
47
|
+
export const JUSTIFY_CLASS = {
|
|
48
|
+
start: 'u-justify-start',
|
|
49
|
+
end: 'u-justify-end',
|
|
50
|
+
center: 'u-justify-center',
|
|
51
|
+
between: 'u-justify-between',
|
|
52
|
+
around: 'u-justify-around',
|
|
53
|
+
evenly: 'u-justify-evenly',
|
|
54
|
+
};
|
|
55
|
+
// -- Vertical padding classes (PageSection) --------------------------------------
|
|
56
|
+
export const PY_CLASS = {
|
|
57
|
+
'0': 'u-py-0',
|
|
58
|
+
xs: 'u-py-xs',
|
|
59
|
+
sm: 'u-py-sm',
|
|
60
|
+
md: 'u-py-md',
|
|
61
|
+
lg: 'u-py-lg',
|
|
62
|
+
xl: 'u-py-xl',
|
|
63
|
+
};
|
|
64
|
+
// -- PageSection semantic tags ---------------------------------------------------
|
|
65
|
+
export const SECTION_TAGS = [
|
|
66
|
+
'section',
|
|
67
|
+
'article',
|
|
68
|
+
'aside',
|
|
69
|
+
'header',
|
|
70
|
+
'footer',
|
|
71
|
+
'main',
|
|
72
|
+
];
|
|
73
|
+
// -- Control-size classes (Button, Input, Select, etc.) -----------------------
|
|
74
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-common","name":"CONTROL_CLASS","stability":"stable","signature":"Record<ControlSize, string>"} */
|
|
75
|
+
export const CONTROL_CLASS = {
|
|
76
|
+
sm: 'u-control-sm',
|
|
77
|
+
md: 'u-control-md',
|
|
78
|
+
lg: 'u-control-lg',
|
|
79
|
+
};
|
|
80
|
+
// -- CSS length validation ----------------------------------------------------
|
|
81
|
+
/** Matches a numeric CSS length value (e.g. "250px", "15rem", "50%"). */
|
|
82
|
+
export const CSS_LENGTH_PATTERN = /^\d+(\.\d+)?(px|rem|em|%|ch|vw|vh|vmin|vmax|svw|svh|dvw|dvh|cqi|cqb)$/;
|
|
83
|
+
// Per-prefix counters so components don't collide and each namespace can be
|
|
84
|
+
// reset independently between SSR requests.
|
|
85
|
+
const uidCounters = new Map();
|
|
86
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-common","name":"nextUid","stability":"internal","signature":"(prefix: string) => string"} */
|
|
87
|
+
export function nextUid(prefix) {
|
|
88
|
+
const n = (uidCounters.get(prefix) ?? 0) + 1;
|
|
89
|
+
uidCounters.set(prefix, n);
|
|
90
|
+
return `${prefix}-${n}`;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/shared/common.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAc/G,iFAAiF;AAEjF,MAAM,CAAC,MAAM,SAAS,GAAgC;IACpD,GAAG,EAAE,SAAS;IACd,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,UAAU;IACd,EAAE,EAAE,UAAU;CACf,CAAC;AAEF,8EAA8E;AAE9E,MAAM,CAAC,MAAM,aAAa,GAAgC;IACxD,GAAG,EAAE,aAAa;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;CACnB,CAAC;AAEF,8EAA8E;AAE9E,MAAM,CAAC,MAAM,aAAa,GAAgC;IACxD,GAAG,EAAE,aAAa;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;CACnB,CAAC;AAEF,gFAAgF;AAEhF,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAG/E,MAAM,CAAC,MAAM,WAAW,GAA+B;IACrD,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,gBAAgB;IACxB,GAAG,EAAE,aAAa;IAClB,OAAO,EAAE,iBAAiB;IAC1B,QAAQ,EAAE,kBAAkB;CAC7B,CAAC;AAEF,8EAA8E;AAE9E,MAAM,aAAa,GAAG;IACpB,OAAO;IACP,KAAK;IACL,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,QAAQ;CACA,CAAC;AAGX,MAAM,CAAC,MAAM,aAAa,GAAmC;IAC3D,KAAK,EAAE,iBAAiB;IACxB,GAAG,EAAE,eAAe;IACpB,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,kBAAkB;IAC1B,MAAM,EAAE,kBAAkB;CAC3B,CAAC;AAEF,mFAAmF;AAEnF,MAAM,CAAC,MAAM,QAAQ,GAAgC;IACnD,GAAG,EAAE,QAAQ;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;CACd,CAAC;AAEF,mFAAmF;AAEnF,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS;IACT,SAAS;IACT,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,MAAM;CACE,CAAC;AAGX,gFAAgF;AAEhF,8IAA8I;AAC9I,MAAM,CAAC,MAAM,aAAa,GAAgC;IACxD,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;IAClB,EAAE,EAAE,cAAc;CACnB,CAAC;AAEF,gFAAgF;AAEhF,yEAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAC7B,uEAAuE,CAAC;AAE1E,4EAA4E;AAC5E,4CAA4C;AAC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE9C,yIAAyI;AACzI,MAAM,UAAU,OAAO,CAAC,MAAc;IACpC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7C,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3B,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.entrance-config", "title": "Section Entrance Animation Config", "category": "runtime" } */
|
|
2
|
+
/**
|
|
3
|
+
* Global entrance animation configuration for section templates.
|
|
4
|
+
*
|
|
5
|
+
* Controls whether and how sections animate when they scroll into view.
|
|
6
|
+
* Set once at app init (typically from pithy.config.ts) — sections read
|
|
7
|
+
* the config at mount time.
|
|
8
|
+
*
|
|
9
|
+
* Presets:
|
|
10
|
+
* - "none" — no entrance animations (accessibility-first, performance-focused)
|
|
11
|
+
* - "subtle" — fade only, no translate, fast duration
|
|
12
|
+
* - "standard" — fade + slide up, moderate duration (default)
|
|
13
|
+
* - "expressive" — fade + slide + stagger + scale, deliberate duration (premium)
|
|
14
|
+
*/
|
|
15
|
+
/** @codexApi {"parent":"pithy.ui-kit.entrance-config","name":"EntrancePreset","stability":"stable","signature":"type EntrancePreset"} */
|
|
16
|
+
export type EntrancePreset = 'none' | 'subtle' | 'standard' | 'expressive';
|
|
17
|
+
/** @codexApi {"parent":"pithy.ui-kit.entrance-config","name":"EntranceConfig","stability":"stable","signature":"interface EntranceConfig"} */
|
|
18
|
+
export interface EntranceConfig {
|
|
19
|
+
/** Animation preset (default: "standard") */
|
|
20
|
+
preset: EntrancePreset;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Set the global entrance animation config.
|
|
24
|
+
*
|
|
25
|
+
* Applies a `data-entrance` attribute on `<html>` so both CSS and
|
|
26
|
+
* `getEntranceConfig()` can read it. Typically you don't call this
|
|
27
|
+
* directly — set `entrance.preset` in `pithy.config.ts` and the
|
|
28
|
+
* framework applies it during bootstrap.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { setEntranceConfig } from "@pithyjs/ui-kit";
|
|
33
|
+
* setEntranceConfig({ preset: "expressive" });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
/** @codexApi {"parent":"pithy.ui-kit.entrance-config","name":"setEntranceConfig","stability":"stable","signature":"(config: Partial<EntranceConfig>) => void"} */
|
|
37
|
+
export declare function setEntranceConfig(config: Partial<EntranceConfig>): void;
|
|
38
|
+
/**
|
|
39
|
+
* Get the current entrance animation config.
|
|
40
|
+
*
|
|
41
|
+
* Reads `data-entrance` from `<html>` — set either by `pithy.config.ts`
|
|
42
|
+
* via bootstrap or manually via `setEntranceConfig()`.
|
|
43
|
+
*/
|
|
44
|
+
/** @codexApi {"parent":"pithy.ui-kit.entrance-config","name":"getEntranceConfig","stability":"stable","signature":"() => EntranceConfig"} */
|
|
45
|
+
export declare function getEntranceConfig(): EntranceConfig;
|
|
46
|
+
//# sourceMappingURL=entrance-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrance-config.d.ts","sourceRoot":"","sources":["../../src/shared/entrance-config.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAE3H;;;;;;;;;;;;GAYG;AAEH,yIAAyI;AACzI,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,CAAC;AAE3E,8IAA8I;AAC9I,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,MAAM,EAAE,cAAc,CAAC;CACxB;AAaD;;;;;;;;;;;;;GAaG;AACH,kKAAkK;AAClK,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAgBvE;AAED;;;;;GAKG;AACH,6IAA6I;AAC7I,wBAAgB,iBAAiB,IAAI,cAAc,CAQlD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.entrance-config", "title": "Section Entrance Animation Config", "category": "runtime" } */
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Internals
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
const VALID_PRESETS = [
|
|
6
|
+
'none',
|
|
7
|
+
'subtle',
|
|
8
|
+
'standard',
|
|
9
|
+
'expressive',
|
|
10
|
+
];
|
|
11
|
+
/**
|
|
12
|
+
* Set the global entrance animation config.
|
|
13
|
+
*
|
|
14
|
+
* Applies a `data-entrance` attribute on `<html>` so both CSS and
|
|
15
|
+
* `getEntranceConfig()` can read it. Typically you don't call this
|
|
16
|
+
* directly — set `entrance.preset` in `pithy.config.ts` and the
|
|
17
|
+
* framework applies it during bootstrap.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { setEntranceConfig } from "@pithyjs/ui-kit";
|
|
22
|
+
* setEntranceConfig({ preset: "expressive" });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/** @codexApi {"parent":"pithy.ui-kit.entrance-config","name":"setEntranceConfig","stability":"stable","signature":"(config: Partial<EntranceConfig>) => void"} */
|
|
26
|
+
export function setEntranceConfig(config) {
|
|
27
|
+
const preset = config.preset ?? 'standard';
|
|
28
|
+
if (import.meta.env?.DEV && !VALID_PRESETS.includes(preset)) {
|
|
29
|
+
console.warn(`[setEntranceConfig] Invalid preset: "${preset}". Expected one of: ${VALID_PRESETS.join(', ')}. Falling back to "standard".`);
|
|
30
|
+
}
|
|
31
|
+
const validated = VALID_PRESETS.includes(preset) ? preset : 'standard';
|
|
32
|
+
// data-entrance on <html> is the single source of truth — read by
|
|
33
|
+
// getEntranceConfig() and by CSS selectors like [data-entrance="expressive"]
|
|
34
|
+
if (typeof document !== 'undefined') {
|
|
35
|
+
document.documentElement.setAttribute('data-entrance', validated);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the current entrance animation config.
|
|
40
|
+
*
|
|
41
|
+
* Reads `data-entrance` from `<html>` — set either by `pithy.config.ts`
|
|
42
|
+
* via bootstrap or manually via `setEntranceConfig()`.
|
|
43
|
+
*/
|
|
44
|
+
/** @codexApi {"parent":"pithy.ui-kit.entrance-config","name":"getEntranceConfig","stability":"stable","signature":"() => EntranceConfig"} */
|
|
45
|
+
export function getEntranceConfig() {
|
|
46
|
+
if (typeof document !== 'undefined') {
|
|
47
|
+
const attr = document.documentElement.getAttribute('data-entrance');
|
|
48
|
+
if (attr && VALID_PRESETS.includes(attr)) {
|
|
49
|
+
return { preset: attr };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { preset: 'standard' };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=entrance-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrance-config.js","sourceRoot":"","sources":["../../src/shared/entrance-config.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAyB3H,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,aAAa,GAA8B;IAC/C,MAAM;IACN,QAAQ;IACR,UAAU;IACV,YAAY;CACb,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,kKAAkK;AAClK,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,UAAU,CAAC;IAE3C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5D,OAAO,CAAC,IAAI,CACV,wCAAwC,MAAM,uBAAuB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAC7H,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC;IAEvE,kEAAkE;IAClE,6EAA6E;IAC7E,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,6IAA6I;AAC7I,MAAM,UAAU,iBAAiB;IAC/B,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QACpE,IAAI,IAAI,IAAI,aAAa,CAAC,QAAQ,CAAC,IAAsB,CAAC,EAAE,CAAC;YAC3D,OAAO,EAAE,MAAM,EAAE,IAAsB,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.focusable", "title": "Focusable Element Selector", "category": "types" } */
|
|
2
|
+
/** CSS selector matching interactive, non-disabled focusable elements. */
|
|
3
|
+
/** @codexApi {"parent":"pithy.ui-kit.focusable","name":"FOCUSABLE_SELECTOR","stability":"stable","signature":"string"} */
|
|
4
|
+
export declare const FOCUSABLE_SELECTOR: string;
|
|
5
|
+
/** Returns the first focusable descendant of `container`, or `null`. */
|
|
6
|
+
/** @codexApi {"parent":"pithy.ui-kit.focusable","name":"getFirstFocusable","stability":"stable","signature":"(container: HTMLElement) => HTMLElement | null"} */
|
|
7
|
+
export declare function getFirstFocusable(container: HTMLElement): HTMLElement | null;
|
|
8
|
+
//# sourceMappingURL=focusable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focusable.d.ts","sourceRoot":"","sources":["../../src/shared/focusable.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAE5G,0EAA0E;AAC1E,0HAA0H;AAC1H,eAAO,MAAM,kBAAkB,QAOnB,CAAC;AAEb,wEAAwE;AACxE,iKAAiK;AACjK,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAE5E"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.focusable", "title": "Focusable Element Selector", "category": "types" } */
|
|
2
|
+
/** CSS selector matching interactive, non-disabled focusable elements. */
|
|
3
|
+
/** @codexApi {"parent":"pithy.ui-kit.focusable","name":"FOCUSABLE_SELECTOR","stability":"stable","signature":"string"} */
|
|
4
|
+
export const FOCUSABLE_SELECTOR = [
|
|
5
|
+
'a[href]:not([tabindex="-1"]):not([aria-disabled="true"])',
|
|
6
|
+
'button:not([disabled]):not([tabindex="-1"]):not([aria-disabled="true"])',
|
|
7
|
+
'input:not([disabled]):not([tabindex="-1"])',
|
|
8
|
+
'select:not([disabled]):not([tabindex="-1"])',
|
|
9
|
+
'textarea:not([disabled]):not([tabindex="-1"])',
|
|
10
|
+
'[tabindex]:not([tabindex="-1"]):not([aria-disabled="true"])',
|
|
11
|
+
].join(', ');
|
|
12
|
+
/** Returns the first focusable descendant of `container`, or `null`. */
|
|
13
|
+
/** @codexApi {"parent":"pithy.ui-kit.focusable","name":"getFirstFocusable","stability":"stable","signature":"(container: HTMLElement) => HTMLElement | null"} */
|
|
14
|
+
export function getFirstFocusable(container) {
|
|
15
|
+
return container.querySelector(FOCUSABLE_SELECTOR);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=focusable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focusable.js","sourceRoot":"","sources":["../../src/shared/focusable.ts"],"names":[],"mappings":"AAAA,4GAA4G;AAE5G,0EAA0E;AAC1E,0HAA0H;AAC1H,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,0DAA0D;IAC1D,yEAAyE;IACzE,4CAA4C;IAC5C,6CAA6C;IAC7C,+CAA+C;IAC/C,6DAA6D;CAC9D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,wEAAwE;AACxE,iKAAiK;AACjK,MAAM,UAAU,iBAAiB,CAAC,SAAsB;IACtD,OAAO,SAAS,CAAC,aAAa,CAAc,kBAAkB,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.shared-form-elements", "title": "Shared Form Element Factories", "category": "types" } */
|
|
2
|
+
/**
|
|
3
|
+
* Shared DOM factory functions for form control atoms.
|
|
4
|
+
* Eliminates boilerplate for helper text, error messages, state icons,
|
|
5
|
+
* and the wrapper-container pattern used by every form atom.
|
|
6
|
+
*/
|
|
7
|
+
import type { ReactiveText } from './clickable';
|
|
8
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"createHelperElement","stability":"stable","signature":"(id: string, text: string | null | undefined) => HTMLSpanElement | undefined"} */
|
|
9
|
+
/**
|
|
10
|
+
* Create a `<span class="ui-form-helper">` for sub-label hints.
|
|
11
|
+
* Returns `undefined` when `text` is nullish so callers can use a simple
|
|
12
|
+
* conditional without extra branching.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createHelperElement(id: string, text: string | null | undefined): HTMLSpanElement | undefined;
|
|
15
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"createErrorElement","stability":"stable","signature":"(id: string, errorMessage: ReactiveText | null | undefined) => HTMLSpanElement | undefined"} */
|
|
16
|
+
/**
|
|
17
|
+
* Create a `<span class="ui-form-error" role="alert">` for validation errors.
|
|
18
|
+
* Hidden by default — `applyFormState` toggles visibility reactively.
|
|
19
|
+
* Returns `undefined` when `errorMessage` is nullish.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createErrorElement(id: string, errorMessage: ReactiveText | null | undefined): HTMLSpanElement | undefined;
|
|
22
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"createStateIcon","stability":"stable","signature":"(className?: string) => HTMLSpanElement"} */
|
|
23
|
+
/**
|
|
24
|
+
* Create the state-icon `<span>` used by `applyFormState` to render
|
|
25
|
+
* success-checkmark / error-alert indicators.
|
|
26
|
+
*
|
|
27
|
+
* **Appended controls** (Input, Textarea, Select): pass a `className`
|
|
28
|
+
* (e.g. `"ui-input-state-icon"`) — the element starts hidden and is shown
|
|
29
|
+
* by `applyFormState` when an error or success state is active.
|
|
30
|
+
*
|
|
31
|
+
* **Detached controls** (Checkbox, Radio, Toggle): omit `className` — the
|
|
32
|
+
* element satisfies `applyFormState`'s contract without ever being shown
|
|
33
|
+
* (the custom box / circle / track already conveys state via color).
|
|
34
|
+
*/
|
|
35
|
+
export declare function createStateIcon(className?: string): HTMLSpanElement;
|
|
36
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"wrapFormControl","stability":"stable","signature":"(wrapper: HTMLElement, opts: { helperEl?: HTMLSpanElement; errorMsgEl?: HTMLSpanElement; containerClass?: string }) => { root: HTMLElement; needsContainer: boolean }"} */
|
|
37
|
+
/**
|
|
38
|
+
* When helper text or an error message element exists, wrap the control
|
|
39
|
+
* `wrapper` in a container `<div>` so the sub-text sits in normal document
|
|
40
|
+
* flow below the control. When neither is present, returns `wrapper` as-is.
|
|
41
|
+
*
|
|
42
|
+
* @param wrapper The component's main wrapper element
|
|
43
|
+
* @param opts.helperEl Helper text `<span>` (from `createHelperElement`)
|
|
44
|
+
* @param opts.errorMsgEl Error message `<span>` (from `createErrorElement`)
|
|
45
|
+
* @param opts.containerClass Optional CSS class for the container div
|
|
46
|
+
* (e.g. `"ui-checkbox-field"`, `"ui-select-wrapper"`). Omit for a plain `<div>`.
|
|
47
|
+
* @returns `{ root, needsContainer }` — `root` is the element to return as `el`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function wrapFormControl(wrapper: HTMLElement, opts: {
|
|
50
|
+
helperEl?: HTMLSpanElement;
|
|
51
|
+
errorMsgEl?: HTMLSpanElement;
|
|
52
|
+
containerClass?: string;
|
|
53
|
+
}): {
|
|
54
|
+
root: HTMLElement;
|
|
55
|
+
needsContainer: boolean;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=form-elements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-elements.d.ts","sourceRoot":"","sources":["../../src/shared/form-elements.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAE1H;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,4MAA4M;AAC5M;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,eAAe,GAAG,SAAS,CAQ7B;AAMD,yNAAyN;AACzN;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,MAAM,EACV,YAAY,EAAE,YAAY,GAAG,IAAI,GAAG,SAAS,GAC5C,eAAe,GAAG,SAAS,CAS7B;AAMD,mKAAmK;AACnK;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,eAAe,CAMnE;AAMD,iSAAiS;AACjS;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE;IACJ,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,CAahD"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.shared-form-elements", "title": "Shared Form Element Factories", "category": "types" } */
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Helper text
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"createHelperElement","stability":"stable","signature":"(id: string, text: string | null | undefined) => HTMLSpanElement | undefined"} */
|
|
6
|
+
/**
|
|
7
|
+
* Create a `<span class="ui-form-helper">` for sub-label hints.
|
|
8
|
+
* Returns `undefined` when `text` is nullish so callers can use a simple
|
|
9
|
+
* conditional without extra branching.
|
|
10
|
+
*/
|
|
11
|
+
export function createHelperElement(id, text) {
|
|
12
|
+
if (text == null)
|
|
13
|
+
return undefined;
|
|
14
|
+
const el = document.createElement('span');
|
|
15
|
+
el.classList.add('ui-form-helper');
|
|
16
|
+
el.id = id;
|
|
17
|
+
el.textContent = text;
|
|
18
|
+
return el;
|
|
19
|
+
}
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Error message
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"createErrorElement","stability":"stable","signature":"(id: string, errorMessage: ReactiveText | null | undefined) => HTMLSpanElement | undefined"} */
|
|
24
|
+
/**
|
|
25
|
+
* Create a `<span class="ui-form-error" role="alert">` for validation errors.
|
|
26
|
+
* Hidden by default — `applyFormState` toggles visibility reactively.
|
|
27
|
+
* Returns `undefined` when `errorMessage` is nullish.
|
|
28
|
+
*/
|
|
29
|
+
export function createErrorElement(id, errorMessage) {
|
|
30
|
+
if (errorMessage == null)
|
|
31
|
+
return undefined;
|
|
32
|
+
const el = document.createElement('span');
|
|
33
|
+
el.classList.add('ui-form-error');
|
|
34
|
+
el.id = id;
|
|
35
|
+
el.setAttribute('role', 'alert');
|
|
36
|
+
el.hidden = true;
|
|
37
|
+
return el;
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// State icon
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"createStateIcon","stability":"stable","signature":"(className?: string) => HTMLSpanElement"} */
|
|
43
|
+
/**
|
|
44
|
+
* Create the state-icon `<span>` used by `applyFormState` to render
|
|
45
|
+
* success-checkmark / error-alert indicators.
|
|
46
|
+
*
|
|
47
|
+
* **Appended controls** (Input, Textarea, Select): pass a `className`
|
|
48
|
+
* (e.g. `"ui-input-state-icon"`) — the element starts hidden and is shown
|
|
49
|
+
* by `applyFormState` when an error or success state is active.
|
|
50
|
+
*
|
|
51
|
+
* **Detached controls** (Checkbox, Radio, Toggle): omit `className` — the
|
|
52
|
+
* element satisfies `applyFormState`'s contract without ever being shown
|
|
53
|
+
* (the custom box / circle / track already conveys state via color).
|
|
54
|
+
*/
|
|
55
|
+
export function createStateIcon(className) {
|
|
56
|
+
const el = document.createElement('span');
|
|
57
|
+
if (className)
|
|
58
|
+
el.classList.add(className);
|
|
59
|
+
el.setAttribute('aria-hidden', 'true');
|
|
60
|
+
if (className)
|
|
61
|
+
el.hidden = true;
|
|
62
|
+
return el;
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Wrapper container
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-elements","name":"wrapFormControl","stability":"stable","signature":"(wrapper: HTMLElement, opts: { helperEl?: HTMLSpanElement; errorMsgEl?: HTMLSpanElement; containerClass?: string }) => { root: HTMLElement; needsContainer: boolean }"} */
|
|
68
|
+
/**
|
|
69
|
+
* When helper text or an error message element exists, wrap the control
|
|
70
|
+
* `wrapper` in a container `<div>` so the sub-text sits in normal document
|
|
71
|
+
* flow below the control. When neither is present, returns `wrapper` as-is.
|
|
72
|
+
*
|
|
73
|
+
* @param wrapper The component's main wrapper element
|
|
74
|
+
* @param opts.helperEl Helper text `<span>` (from `createHelperElement`)
|
|
75
|
+
* @param opts.errorMsgEl Error message `<span>` (from `createErrorElement`)
|
|
76
|
+
* @param opts.containerClass Optional CSS class for the container div
|
|
77
|
+
* (e.g. `"ui-checkbox-field"`, `"ui-select-wrapper"`). Omit for a plain `<div>`.
|
|
78
|
+
* @returns `{ root, needsContainer }` — `root` is the element to return as `el`.
|
|
79
|
+
*/
|
|
80
|
+
export function wrapFormControl(wrapper, opts) {
|
|
81
|
+
const { helperEl, errorMsgEl, containerClass } = opts;
|
|
82
|
+
const needsContainer = !!(helperEl || errorMsgEl);
|
|
83
|
+
if (!needsContainer)
|
|
84
|
+
return { root: wrapper, needsContainer: false };
|
|
85
|
+
const container = document.createElement('div');
|
|
86
|
+
if (containerClass)
|
|
87
|
+
container.classList.add(containerClass);
|
|
88
|
+
container.appendChild(wrapper);
|
|
89
|
+
if (helperEl)
|
|
90
|
+
container.appendChild(helperEl);
|
|
91
|
+
if (errorMsgEl)
|
|
92
|
+
container.appendChild(errorMsgEl);
|
|
93
|
+
return { root: container, needsContainer: true };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=form-elements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-elements.js","sourceRoot":"","sources":["../../src/shared/form-elements.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAU1H,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,4MAA4M;AAC5M;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,EAAU,EACV,IAA+B;IAE/B,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IAEnC,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACnC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;IACX,EAAE,CAAC,WAAW,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,yNAAyN;AACzN;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,EAAU,EACV,YAA6C;IAE7C,IAAI,YAAY,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IAE3C,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;IACX,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC;IACjB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,mKAAmK;AACnK;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,SAAkB;IAChD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,SAAS;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3C,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,SAAS;QAAE,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,iSAAiS;AACjS;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAoB,EACpB,IAIC;IAED,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IACtD,MAAM,cAAc,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC;IAElD,IAAI,CAAC,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;IAErE,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,cAAc;QAAE,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5D,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC/B,IAAI,QAAQ;QAAE,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,UAAU;QAAE,SAAS,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAElD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.shared-form-state", "title": "Shared Form State Logic", "category": "types" } */
|
|
2
|
+
export interface FormStateElements {
|
|
3
|
+
/** The element that receives data-error, data-success, and the shake animation class */
|
|
4
|
+
wrapper: HTMLElement;
|
|
5
|
+
/** The element that receives aria-invalid, aria-describedby (input or trigger) */
|
|
6
|
+
control: HTMLElement;
|
|
7
|
+
/** State icon container (success checkmark / error alert) */
|
|
8
|
+
stateIconEl: HTMLElement;
|
|
9
|
+
/** Helper text element (optional) */
|
|
10
|
+
helperEl?: HTMLSpanElement;
|
|
11
|
+
/** Error message element (optional) */
|
|
12
|
+
errorMsgEl?: HTMLSpanElement;
|
|
13
|
+
}
|
|
14
|
+
export interface FormStateReaders {
|
|
15
|
+
readError: () => boolean | undefined;
|
|
16
|
+
readErrorMessage: () => string | undefined;
|
|
17
|
+
readSuccess: () => boolean | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface FormStateIds {
|
|
20
|
+
helperId: string;
|
|
21
|
+
errorMsgId: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FormStateConfig {
|
|
24
|
+
/** CSS class for the shake animation (e.g. "ui-input-shake" or "ui-select-shake") */
|
|
25
|
+
shakeClass: string;
|
|
26
|
+
/** CSS class prefix for state icons (e.g. "ui-input-state-icon" or "ui-select-state-icon") */
|
|
27
|
+
iconPrefix: string;
|
|
28
|
+
}
|
|
29
|
+
export interface FormStateTracker {
|
|
30
|
+
prevError: boolean;
|
|
31
|
+
prevSuccess: boolean;
|
|
32
|
+
firstRun: boolean;
|
|
33
|
+
shakeEndHandler: EventListener | undefined;
|
|
34
|
+
popEndHandler: EventListener | undefined;
|
|
35
|
+
}
|
|
36
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-state","name":"createFormStateTracker","stability":"internal","signature":"() => FormStateTracker"} */
|
|
37
|
+
export declare function createFormStateTracker(): FormStateTracker;
|
|
38
|
+
/**
|
|
39
|
+
* Apply error/success state, state icon, shake/pop animations, and
|
|
40
|
+
* error/helper text visibility. Call this inside `applyState()` or an effect.
|
|
41
|
+
*
|
|
42
|
+
* @returns void — mutates DOM elements in place
|
|
43
|
+
*/
|
|
44
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-state","name":"applyFormState","stability":"internal","signature":"(els, readers, ids, config, tracker) => void"} */
|
|
45
|
+
export declare function applyFormState(els: FormStateElements, readers: FormStateReaders, ids: FormStateIds, config: FormStateConfig, tracker: FormStateTracker): void;
|
|
46
|
+
/**
|
|
47
|
+
* Clean up animation event listeners tracked by a FormStateTracker.
|
|
48
|
+
* Call this in the component's `destroy()` function.
|
|
49
|
+
*/
|
|
50
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-state","name":"cleanupFormState","stability":"internal","signature":"(wrapper, stateIconEl, tracker) => void"} */
|
|
51
|
+
export declare function cleanupFormState(wrapper: HTMLElement, stateIconEl: HTMLElement, tracker: FormStateTracker): void;
|
|
52
|
+
//# sourceMappingURL=form-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-state.d.ts","sourceRoot":"","sources":["../../src/shared/form-state.ts"],"names":[],"mappings":"AAAA,iHAAiH;AAcjH,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,OAAO,EAAE,WAAW,CAAC;IACrB,kFAAkF;IAClF,OAAO,EAAE,WAAW,CAAC;IACrB,6DAA6D;IAC7D,WAAW,EAAE,WAAW,CAAC;IACzB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,uCAAuC;IACvC,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,OAAO,GAAG,SAAS,CAAC;IACrC,gBAAgB,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC3C,WAAW,EAAE,MAAM,OAAO,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,qFAAqF;IACrF,UAAU,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3C,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;CAC1C;AAMD,wJAAwJ;AACxJ,wBAAgB,sBAAsB,IAAI,gBAAgB,CAQzD;AAED;;;;;GAKG;AACH,sKAAsK;AACtK,wBAAgB,cAAc,CAC5B,GAAG,EAAE,iBAAiB,EACtB,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAoHN;AAED;;;GAGG;AACH,mKAAmK;AACnK,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAON"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/** @codex { "id": "pithy.ui-kit.shared-form-state", "title": "Shared Form State Logic", "category": "types" } */
|
|
2
|
+
/**
|
|
3
|
+
* Shared state application logic for form control atoms (Input, Select, Textarea).
|
|
4
|
+
* Handles error shake, success pop, state icon switching, error/helper text swap,
|
|
5
|
+
* and dynamic aria-describedby — eliminating duplication across form atoms.
|
|
6
|
+
*/
|
|
7
|
+
import { CHECK_ICON, ALERT_ICON } from './icons';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Factory
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-state","name":"createFormStateTracker","stability":"internal","signature":"() => FormStateTracker"} */
|
|
12
|
+
export function createFormStateTracker() {
|
|
13
|
+
return {
|
|
14
|
+
prevError: false,
|
|
15
|
+
prevSuccess: false,
|
|
16
|
+
firstRun: true,
|
|
17
|
+
shakeEndHandler: undefined,
|
|
18
|
+
popEndHandler: undefined,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Apply error/success state, state icon, shake/pop animations, and
|
|
23
|
+
* error/helper text visibility. Call this inside `applyState()` or an effect.
|
|
24
|
+
*
|
|
25
|
+
* @returns void — mutates DOM elements in place
|
|
26
|
+
*/
|
|
27
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-state","name":"applyFormState","stability":"internal","signature":"(els, readers, ids, config, tracker) => void"} */
|
|
28
|
+
export function applyFormState(els, readers, ids, config, tracker) {
|
|
29
|
+
const { wrapper, control, stateIconEl, helperEl, errorMsgEl } = els;
|
|
30
|
+
const { readError, readErrorMessage, readSuccess } = readers;
|
|
31
|
+
const { helperId, errorMsgId } = ids;
|
|
32
|
+
const { shakeClass, iconPrefix } = config;
|
|
33
|
+
// -- Error state -----------------------------------------------------------
|
|
34
|
+
const isError = readError();
|
|
35
|
+
if (isError) {
|
|
36
|
+
control.setAttribute('aria-invalid', 'true');
|
|
37
|
+
wrapper.setAttribute('data-error', '');
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
control.removeAttribute('aria-invalid');
|
|
41
|
+
wrapper.removeAttribute('data-error');
|
|
42
|
+
}
|
|
43
|
+
// -- Error message + helper text swap --------------------------------------
|
|
44
|
+
const errorMsg = readErrorMessage();
|
|
45
|
+
const msg = errorMsgEl ? errorMsg : undefined;
|
|
46
|
+
// -- Dev warning: error=true without errorMessage --------------------------
|
|
47
|
+
// Fire on every false→true error transition (not just firstRun) so the
|
|
48
|
+
// warning catches the common case where error starts false and becomes
|
|
49
|
+
// true after validation.
|
|
50
|
+
if (import.meta.env?.DEV &&
|
|
51
|
+
isError &&
|
|
52
|
+
!errorMsg &&
|
|
53
|
+
(!tracker.prevError || tracker.firstRun)) {
|
|
54
|
+
console.warn(`[PithyJS] ⚠️ Form control has error=true but no errorMessage. ` +
|
|
55
|
+
`Screen readers will announce "invalid" with no context. ` +
|
|
56
|
+
`Provide an errorMessage for accessible error identification (WCAG 3.3.1).`);
|
|
57
|
+
}
|
|
58
|
+
const showError = !!isError && !!msg && !!errorMsgEl;
|
|
59
|
+
if (errorMsgEl) {
|
|
60
|
+
errorMsgEl.textContent = showError ? msg : '';
|
|
61
|
+
errorMsgEl.hidden = !showError;
|
|
62
|
+
if (helperEl) {
|
|
63
|
+
helperEl.hidden = showError;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// -- Dynamic aria-describedby — only reference visible content -------------
|
|
67
|
+
{
|
|
68
|
+
const descIds = [];
|
|
69
|
+
if (errorMsgEl && showError)
|
|
70
|
+
descIds.push(errorMsgId);
|
|
71
|
+
if (helperEl && !showError)
|
|
72
|
+
descIds.push(helperId);
|
|
73
|
+
if (descIds.length > 0) {
|
|
74
|
+
control.setAttribute('aria-describedby', descIds.join(' '));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
control.removeAttribute('aria-describedby');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// -- Error shake — only on false→true transition, skip first run -----------
|
|
81
|
+
if (isError && !tracker.prevError && !tracker.firstRun) {
|
|
82
|
+
if (tracker.shakeEndHandler) {
|
|
83
|
+
wrapper.removeEventListener('animationend', tracker.shakeEndHandler);
|
|
84
|
+
}
|
|
85
|
+
wrapper.classList.add(shakeClass);
|
|
86
|
+
tracker.shakeEndHandler = () => {
|
|
87
|
+
wrapper.classList.remove(shakeClass);
|
|
88
|
+
wrapper.removeEventListener('animationend', tracker.shakeEndHandler);
|
|
89
|
+
tracker.shakeEndHandler = undefined;
|
|
90
|
+
};
|
|
91
|
+
wrapper.addEventListener('animationend', tracker.shakeEndHandler);
|
|
92
|
+
}
|
|
93
|
+
tracker.prevError = !!isError;
|
|
94
|
+
// -- Success state ---------------------------------------------------------
|
|
95
|
+
const isSuccess = readSuccess();
|
|
96
|
+
if (isSuccess) {
|
|
97
|
+
wrapper.setAttribute('data-success', '');
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
wrapper.removeAttribute('data-success');
|
|
101
|
+
}
|
|
102
|
+
// -- State icon ------------------------------------------------------------
|
|
103
|
+
const errorIconClass = `${iconPrefix}-error`;
|
|
104
|
+
const successIconClass = `${iconPrefix}-success`;
|
|
105
|
+
const popClass = `${iconPrefix}-pop`;
|
|
106
|
+
if (isError) {
|
|
107
|
+
stateIconEl.innerHTML = ALERT_ICON;
|
|
108
|
+
stateIconEl.classList.add(errorIconClass);
|
|
109
|
+
stateIconEl.classList.remove(successIconClass);
|
|
110
|
+
stateIconEl.hidden = false;
|
|
111
|
+
}
|
|
112
|
+
else if (isSuccess) {
|
|
113
|
+
stateIconEl.innerHTML = CHECK_ICON;
|
|
114
|
+
stateIconEl.classList.add(successIconClass);
|
|
115
|
+
stateIconEl.classList.remove(errorIconClass);
|
|
116
|
+
stateIconEl.hidden = false;
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
stateIconEl.hidden = true;
|
|
120
|
+
stateIconEl.innerHTML = '';
|
|
121
|
+
stateIconEl.classList.remove(errorIconClass, successIconClass, popClass);
|
|
122
|
+
}
|
|
123
|
+
// -- Success pop — only on false→true transition, skip first run -----------
|
|
124
|
+
if (isSuccess && !isError && !tracker.prevSuccess && !tracker.firstRun) {
|
|
125
|
+
if (tracker.popEndHandler) {
|
|
126
|
+
stateIconEl.removeEventListener('animationend', tracker.popEndHandler);
|
|
127
|
+
}
|
|
128
|
+
stateIconEl.classList.add(popClass);
|
|
129
|
+
tracker.popEndHandler = () => {
|
|
130
|
+
stateIconEl.classList.remove(popClass);
|
|
131
|
+
stateIconEl.removeEventListener('animationend', tracker.popEndHandler);
|
|
132
|
+
tracker.popEndHandler = undefined;
|
|
133
|
+
};
|
|
134
|
+
stateIconEl.addEventListener('animationend', tracker.popEndHandler);
|
|
135
|
+
}
|
|
136
|
+
tracker.prevSuccess = !!isSuccess;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Clean up animation event listeners tracked by a FormStateTracker.
|
|
140
|
+
* Call this in the component's `destroy()` function.
|
|
141
|
+
*/
|
|
142
|
+
/** @codexApi {"parent":"pithy.ui-kit.shared-form-state","name":"cleanupFormState","stability":"internal","signature":"(wrapper, stateIconEl, tracker) => void"} */
|
|
143
|
+
export function cleanupFormState(wrapper, stateIconEl, tracker) {
|
|
144
|
+
if (tracker.shakeEndHandler) {
|
|
145
|
+
wrapper.removeEventListener('animationend', tracker.shakeEndHandler);
|
|
146
|
+
}
|
|
147
|
+
if (tracker.popEndHandler) {
|
|
148
|
+
stateIconEl.removeEventListener('animationend', tracker.popEndHandler);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=form-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-state.js","sourceRoot":"","sources":["../../src/shared/form-state.ts"],"names":[],"mappings":"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"}
|