@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,353 @@
|
|
|
1
|
+
/** @codex
|
|
2
|
+
{
|
|
3
|
+
"id": "pithy.ui-kit.card",
|
|
4
|
+
"title": "<Card> Organism",
|
|
5
|
+
"category": "feature",
|
|
6
|
+
"risk": "medium"
|
|
7
|
+
}
|
|
8
|
+
*/
|
|
9
|
+
import { captureChildren } from '@pithyjs/core';
|
|
10
|
+
import { effect } from '@pithyjs/signals';
|
|
11
|
+
import { isSafeHref, sanitizeHref } from '@pithyjs/shared';
|
|
12
|
+
import { cleanupRouterDirectives } from '@pithyjs/router';
|
|
13
|
+
import { captureSlot, extractSlot } from '../../shared/slots';
|
|
14
|
+
import { generateSectionHeadingId, validateEnum } from '../../shared/section';
|
|
15
|
+
import { ORIENTATIONS } from '../../shared/types';
|
|
16
|
+
import { CARD_VARIANTS, CARD_PADDINGS, CARD_RADII, CARD_MEDIA_ASPECTS, } from '../../shared/card';
|
|
17
|
+
// -- Helpers ------------------------------------------------------------------
|
|
18
|
+
function firstHeadingIn(root) {
|
|
19
|
+
if (!root)
|
|
20
|
+
return null;
|
|
21
|
+
return root.querySelector('h1, h2, h3, h4, h5, h6');
|
|
22
|
+
}
|
|
23
|
+
function wrapSlot(name, className, tag, fragment) {
|
|
24
|
+
if (!fragment)
|
|
25
|
+
return null;
|
|
26
|
+
// If the user projected a single element whose tag already matches our
|
|
27
|
+
// target (e.g. `<footer data-slot="footer">`), reuse it instead of
|
|
28
|
+
// wrapping — otherwise the flex container would wrap a block child and
|
|
29
|
+
// lose all layout. `<template data-slot="...">` always falls through to
|
|
30
|
+
// the wrapper since extractSlot unpacks its content, and a mismatched
|
|
31
|
+
// tag (e.g. `<div data-slot="footer">`) is wrapped so the semantic tag
|
|
32
|
+
// we advertise is preserved.
|
|
33
|
+
const only = fragment.children.length === 1 && fragment.childNodes.length === 1
|
|
34
|
+
? fragment.firstElementChild
|
|
35
|
+
: null;
|
|
36
|
+
if (only && only.tagName.toLowerCase() === tag) {
|
|
37
|
+
only.classList.add(className);
|
|
38
|
+
captureSlot(only, name);
|
|
39
|
+
return only;
|
|
40
|
+
}
|
|
41
|
+
const wrapper = document.createElement(tag);
|
|
42
|
+
wrapper.classList.add(className);
|
|
43
|
+
captureSlot(wrapper, name);
|
|
44
|
+
wrapper.appendChild(fragment);
|
|
45
|
+
return wrapper;
|
|
46
|
+
}
|
|
47
|
+
// -- Component ----------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Content container with named slots (`media`, `header`, default = body,
|
|
50
|
+
* `footer`), five variants, orientation, and a pseudo-link pattern that
|
|
51
|
+
* lets the whole card act as a navigation target without sacrificing
|
|
52
|
+
* interactive children.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```html
|
|
56
|
+
* <Card variant="'elevated'" clickable="true" href="'/post/hello'">
|
|
57
|
+
* <img data-slot="media" src="/hero.jpg" alt="">
|
|
58
|
+
* <header data-slot="header">
|
|
59
|
+
* <Heading level="3">Hello world</Heading>
|
|
60
|
+
* </header>
|
|
61
|
+
* <Text>A short excerpt…</Text>
|
|
62
|
+
* <footer data-slot="footer">
|
|
63
|
+
* <Text color="'text-muted'" size="'sm'">3 min read</Text>
|
|
64
|
+
* </footer>
|
|
65
|
+
* </Card>
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
/** @codexApi {"parent":"pithy.ui-kit.card","name":"Card","stability":"stable","signature":"(props?: CardProps) => { el: HTMLElement; destroy: () => void }"} */
|
|
69
|
+
export function Card(props = {}) {
|
|
70
|
+
const { variant: rawVariant = 'default', padding: rawPadding = 'md', radius: rawRadius = 'md', orientation: rawOrientation = 'vertical', mediaOverlay = false, clickable = false, href, linkLabel: rawLinkLabel, disabled = false, selected = false, eyebrow, ariaLabel: rawAriaLabel, ariaLabelledBy: rawAriaLabelledBy, id, } = props;
|
|
71
|
+
// Whitespace-only labels would set an effectively empty accessible name
|
|
72
|
+
// and silently bypass the heading fallback. Trim once and treat empty
|
|
73
|
+
// strings as absent — same pattern as <Button>.
|
|
74
|
+
const ariaLabel = rawAriaLabel?.trim() || undefined;
|
|
75
|
+
const linkLabel = rawLinkLabel?.trim() || undefined;
|
|
76
|
+
const ariaLabelledBy = rawAriaLabelledBy?.trim() || undefined;
|
|
77
|
+
if (import.meta.env?.DEV) {
|
|
78
|
+
if (rawAriaLabel != null && !ariaLabel) {
|
|
79
|
+
console.warn('[<Card>] `ariaLabel` was empty or whitespace-only; falling back to heading / ariaLabelledBy / linkLabel.');
|
|
80
|
+
}
|
|
81
|
+
if (rawLinkLabel != null && !linkLabel) {
|
|
82
|
+
console.warn('[<Card>] `linkLabel` was empty or whitespace-only; falling back to heading / ariaLabelledBy / ariaLabel.');
|
|
83
|
+
}
|
|
84
|
+
if (rawAriaLabelledBy != null && !ariaLabelledBy) {
|
|
85
|
+
console.warn('[<Card>] `ariaLabelledBy` was whitespace-only; falling back to heading / ariaLabel / linkLabel.');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Destructure defaults first so undefined props skip validateEnum's warning path.
|
|
89
|
+
const variant = validateEnum('Card', 'variant', rawVariant, CARD_VARIANTS, 'default');
|
|
90
|
+
const padding = validateEnum('Card', 'padding', rawPadding, CARD_PADDINGS, 'md');
|
|
91
|
+
const radius = validateEnum('Card', 'radius', rawRadius, CARD_RADII, 'md');
|
|
92
|
+
const orientation = validateEnum('Card', 'orientation', rawOrientation, ORIENTATIONS, 'vertical');
|
|
93
|
+
// Horizontal thumbnails need a predictable aspect ratio or lists get janky.
|
|
94
|
+
const resolvedMediaAspect = props.mediaAspect &&
|
|
95
|
+
CARD_MEDIA_ASPECTS.includes(props.mediaAspect)
|
|
96
|
+
? props.mediaAspect
|
|
97
|
+
: orientation === 'horizontal'
|
|
98
|
+
? '16/9'
|
|
99
|
+
: undefined;
|
|
100
|
+
if (import.meta.env?.DEV) {
|
|
101
|
+
if (clickable && !href) {
|
|
102
|
+
console.warn('[<Card>] `clickable` requires `href`. The card will render without the stretched link overlay.');
|
|
103
|
+
}
|
|
104
|
+
if (!clickable && href) {
|
|
105
|
+
console.warn("[<Card>] `href` is ignored when `clickable` is false. Set `clickable='true'` to activate the link overlay.");
|
|
106
|
+
}
|
|
107
|
+
if (props.mediaAspect &&
|
|
108
|
+
!CARD_MEDIA_ASPECTS.includes(props.mediaAspect)) {
|
|
109
|
+
console.warn(`[<Card>] Invalid mediaAspect: "${props.mediaAspect}". Expected one of: ${CARD_MEDIA_ASPECTS.join(', ')}.`);
|
|
110
|
+
}
|
|
111
|
+
// Runtime guard for the site builder's untyped prop bag — TS consumers
|
|
112
|
+
// can't reach this, but JSON-driven rendering can.
|
|
113
|
+
if (typeof props.onClick === 'function') {
|
|
114
|
+
console.warn("[<Card>] `onClick` is not supported in V0.1. Use `clickable='true'` + `href` for navigation, or nest a <Button onClick=...> inside the footer slot. A first-class onClick card lands in V0.2.");
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Sanitize before both validating and assigning so the rendered URL is
|
|
118
|
+
// exactly what isSafeHref() checked — control-char / whitespace bypass
|
|
119
|
+
// surfaces disappear.
|
|
120
|
+
const normalizedHref = typeof href === 'string' ? sanitizeHref(href) : '';
|
|
121
|
+
const safeHref = clickable && normalizedHref && isSafeHref(normalizedHref)
|
|
122
|
+
? normalizedHref
|
|
123
|
+
: null;
|
|
124
|
+
if (import.meta.env?.DEV && clickable && href && !safeHref) {
|
|
125
|
+
if (!normalizedHref) {
|
|
126
|
+
console.warn(`[<Card>] \`href\` was empty or whitespace-only after sanitization; the card will not be clickable.`);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.warn(`[<Card>] Unsafe href rejected: "${normalizedHref}". Only http(s), mailto, tel, fragment-only (#...), query-only (?...), and relative URLs (/..., ./..., ../...) are allowed.`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const disposers = [];
|
|
133
|
+
// Capture projected children before any inner components render — mirrors
|
|
134
|
+
// the Navbar/section-template pattern. Named nodes are re-homed into slot
|
|
135
|
+
// wrappers below; anything left in the fragment becomes the default body.
|
|
136
|
+
const { el: childFragment, destroy: destroyChildren } = captureChildren();
|
|
137
|
+
disposers.push(destroyChildren);
|
|
138
|
+
const article = document.createElement('article');
|
|
139
|
+
article.classList.add('ui-card');
|
|
140
|
+
article.dataset.variant = variant;
|
|
141
|
+
article.dataset.padding = padding;
|
|
142
|
+
article.dataset.radius = radius;
|
|
143
|
+
article.dataset.orientation = orientation;
|
|
144
|
+
if (clickable && safeHref)
|
|
145
|
+
article.dataset.clickable = 'true';
|
|
146
|
+
if (mediaOverlay)
|
|
147
|
+
article.dataset.mediaOverlay = 'true';
|
|
148
|
+
if (id)
|
|
149
|
+
article.id = id;
|
|
150
|
+
// Reactive `selected` + `disabled`: follow Button's pattern — accept a
|
|
151
|
+
// boolean or a `() => boolean` getter. A function triggers an effect;
|
|
152
|
+
// a literal bakes in once.
|
|
153
|
+
const readDisabled = () => typeof disabled === 'function' ? disabled() : disabled;
|
|
154
|
+
const readSelected = () => typeof selected === 'function' ? selected() : selected;
|
|
155
|
+
const isReactive = typeof disabled === 'function' || typeof selected === 'function';
|
|
156
|
+
const applyState = () => {
|
|
157
|
+
const isDisabled = readDisabled();
|
|
158
|
+
const isSelected = readSelected();
|
|
159
|
+
if (isDisabled) {
|
|
160
|
+
article.dataset.disabled = 'true';
|
|
161
|
+
article.setAttribute('aria-disabled', 'true');
|
|
162
|
+
// `inert` blocks focus, clicks, and AT on every descendant.
|
|
163
|
+
article.setAttribute('inert', '');
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
delete article.dataset.disabled;
|
|
167
|
+
article.removeAttribute('aria-disabled');
|
|
168
|
+
article.removeAttribute('inert');
|
|
169
|
+
}
|
|
170
|
+
if (isSelected) {
|
|
171
|
+
article.dataset.selected = 'true';
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
delete article.dataset.selected;
|
|
175
|
+
}
|
|
176
|
+
// aria-current only has meaning in a navigation context, which disabled
|
|
177
|
+
// removes — keep the existing (non-reactive) gate on clickable && safeHref.
|
|
178
|
+
if (isSelected && clickable && safeHref && !isDisabled) {
|
|
179
|
+
article.setAttribute('aria-current', 'true');
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
article.removeAttribute('aria-current');
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
if (isReactive) {
|
|
186
|
+
disposers.push(effect(applyState));
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
applyState();
|
|
190
|
+
}
|
|
191
|
+
// An element can't @container-query itself, so layout lives on a child.
|
|
192
|
+
// See card.scss for the chrome/query-container split.
|
|
193
|
+
const layout = document.createElement('div');
|
|
194
|
+
layout.classList.add('ui-card-layout');
|
|
195
|
+
captureSlot(layout, 'default');
|
|
196
|
+
article.appendChild(layout);
|
|
197
|
+
// Slots — order is significant: media comes first so it can bleed when
|
|
198
|
+
// padding=none, then header/body/footer.
|
|
199
|
+
const mediaFragment = extractSlot(childFragment, 'media');
|
|
200
|
+
const mediaWrapper = wrapSlot('media', 'ui-card-media', 'div', mediaFragment);
|
|
201
|
+
if (mediaWrapper && resolvedMediaAspect) {
|
|
202
|
+
mediaWrapper.dataset.aspect = resolvedMediaAspect;
|
|
203
|
+
}
|
|
204
|
+
if (mediaWrapper)
|
|
205
|
+
layout.appendChild(mediaWrapper);
|
|
206
|
+
const headerFragment = extractSlot(childFragment, 'header');
|
|
207
|
+
let headerWrapper = wrapSlot('header', 'ui-card-header', 'header', headerFragment);
|
|
208
|
+
// If no header slot was projected, create one so the eyebrow has a home.
|
|
209
|
+
// Mirrors the Hero / CTA section eyebrow pattern.
|
|
210
|
+
if (typeof eyebrow === 'string' && eyebrow.trim().length > 0) {
|
|
211
|
+
const eyebrowEl = document.createElement('span');
|
|
212
|
+
eyebrowEl.classList.add('ui-card-eyebrow');
|
|
213
|
+
eyebrowEl.textContent = eyebrow.trim();
|
|
214
|
+
if (!headerWrapper) {
|
|
215
|
+
headerWrapper = document.createElement('header');
|
|
216
|
+
headerWrapper.classList.add('ui-card-header');
|
|
217
|
+
captureSlot(headerWrapper, 'header');
|
|
218
|
+
}
|
|
219
|
+
headerWrapper.prepend(eyebrowEl);
|
|
220
|
+
}
|
|
221
|
+
if (headerWrapper)
|
|
222
|
+
layout.appendChild(headerWrapper);
|
|
223
|
+
// Extract footer BEFORE the body collapse — otherwise the body scoop below
|
|
224
|
+
// would swallow footer nodes along with the default content.
|
|
225
|
+
const footerFragment = extractSlot(childFragment, 'footer');
|
|
226
|
+
const footerWrapper = wrapSlot('footer', 'ui-card-footer', 'footer', footerFragment);
|
|
227
|
+
// Skip the wrapper when empty so media+footer-only cards don't carry a
|
|
228
|
+
// vestigial element.
|
|
229
|
+
const remainingHasContent = childFragment.childNodes.length > 0 &&
|
|
230
|
+
Array.from(childFragment.childNodes).some(n => n.nodeType !== Node.TEXT_NODE || (n.textContent ?? '').trim().length > 0);
|
|
231
|
+
if (remainingHasContent) {
|
|
232
|
+
const body = document.createElement('div');
|
|
233
|
+
body.classList.add('ui-card-body');
|
|
234
|
+
body.appendChild(childFragment);
|
|
235
|
+
layout.appendChild(body);
|
|
236
|
+
}
|
|
237
|
+
if (footerWrapper)
|
|
238
|
+
layout.appendChild(footerWrapper);
|
|
239
|
+
// Overlay mode collapses header/body/footer into one caption group so
|
|
240
|
+
// the scrim, inverse text, and block-end anchoring share a positioning
|
|
241
|
+
// context. Media stays at z-index 0.
|
|
242
|
+
if (mediaOverlay) {
|
|
243
|
+
const caption = document.createElement('div');
|
|
244
|
+
caption.classList.add('ui-card-caption');
|
|
245
|
+
const nodesToMove = Array.from(layout.children).filter(c => c.classList.contains('ui-card-header') ||
|
|
246
|
+
c.classList.contains('ui-card-body') ||
|
|
247
|
+
c.classList.contains('ui-card-footer'));
|
|
248
|
+
for (const node of nodesToMove)
|
|
249
|
+
caption.appendChild(node);
|
|
250
|
+
// Only add the caption if it actually has content — an image-only card
|
|
251
|
+
// with `mediaOverlay` is still a valid configuration.
|
|
252
|
+
if (caption.children.length > 0)
|
|
253
|
+
layout.appendChild(caption);
|
|
254
|
+
}
|
|
255
|
+
// Accessible name fallback chain:
|
|
256
|
+
// ariaLabelledBy > clickable heading (auto-id) > heading (auto-id)
|
|
257
|
+
// > ariaLabel > linkLabel > DEV warning
|
|
258
|
+
// Non-clickable cards with headings also get aria-labelledby so screen
|
|
259
|
+
// readers announce "article, <heading text>" instead of bare "article".
|
|
260
|
+
const heading = firstHeadingIn(headerWrapper);
|
|
261
|
+
if (ariaLabelledBy) {
|
|
262
|
+
article.setAttribute('aria-labelledby', ariaLabelledBy);
|
|
263
|
+
}
|
|
264
|
+
else if (clickable && safeHref) {
|
|
265
|
+
if (heading) {
|
|
266
|
+
if (!heading.id)
|
|
267
|
+
heading.id = generateSectionHeadingId('card', id);
|
|
268
|
+
article.setAttribute('aria-labelledby', heading.id);
|
|
269
|
+
}
|
|
270
|
+
else if (ariaLabel) {
|
|
271
|
+
article.setAttribute('aria-label', ariaLabel);
|
|
272
|
+
}
|
|
273
|
+
else if (linkLabel) {
|
|
274
|
+
article.setAttribute('aria-label', linkLabel);
|
|
275
|
+
}
|
|
276
|
+
else if (import.meta.env?.DEV) {
|
|
277
|
+
console.warn('[<Card>] Clickable card has no accessible name. Add a heading in the header slot, or pass `ariaLabel` / `ariaLabelledBy`.');
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else if (heading) {
|
|
281
|
+
if (!heading.id)
|
|
282
|
+
heading.id = generateSectionHeadingId('card', id);
|
|
283
|
+
article.setAttribute('aria-labelledby', heading.id);
|
|
284
|
+
}
|
|
285
|
+
else if (ariaLabel) {
|
|
286
|
+
article.setAttribute('aria-label', ariaLabel);
|
|
287
|
+
}
|
|
288
|
+
// Pseudo-link overlay — absolute anchor at z-index 1 covers the card for
|
|
289
|
+
// hit-testing. Interactive descendants (buttons/inner links) are raised
|
|
290
|
+
// above it via a :is() rule in card.scss so they stay clickable.
|
|
291
|
+
if (clickable && safeHref) {
|
|
292
|
+
const overlay = document.createElement('a');
|
|
293
|
+
overlay.classList.add('ui-card-link');
|
|
294
|
+
overlay.href = safeHref;
|
|
295
|
+
overlay.setAttribute('data-router-link', '');
|
|
296
|
+
overlay.setAttribute('data-prefetch', 'none');
|
|
297
|
+
disposers.push(() => cleanupRouterDirectives(overlay));
|
|
298
|
+
if (linkLabel) {
|
|
299
|
+
overlay.setAttribute('aria-label', linkLabel);
|
|
300
|
+
}
|
|
301
|
+
else if (ariaLabelledBy) {
|
|
302
|
+
// Honour the explicit override — keeps article + overlay names in sync.
|
|
303
|
+
overlay.setAttribute('aria-labelledby', ariaLabelledBy);
|
|
304
|
+
}
|
|
305
|
+
else if (heading) {
|
|
306
|
+
// Reference the heading id so the link name stays in sync with reactive
|
|
307
|
+
// heading text — snapshotting textContent would freeze a stale name.
|
|
308
|
+
if (!heading.id)
|
|
309
|
+
heading.id = generateSectionHeadingId('card', id);
|
|
310
|
+
overlay.setAttribute('aria-labelledby', heading.id);
|
|
311
|
+
}
|
|
312
|
+
else if (ariaLabel) {
|
|
313
|
+
overlay.setAttribute('aria-label', ariaLabel);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
// Last-resort visually-hidden label so the link always has an
|
|
317
|
+
// accessible name even when heading and labels are absent.
|
|
318
|
+
const sr = document.createElement('span');
|
|
319
|
+
sr.classList.add('ui-card-link-label');
|
|
320
|
+
sr.textContent = 'Open';
|
|
321
|
+
overlay.appendChild(sr);
|
|
322
|
+
}
|
|
323
|
+
article.appendChild(overlay);
|
|
324
|
+
}
|
|
325
|
+
// Interactive-by-content: a non-clickable card that contains a focusable
|
|
326
|
+
// descendant (button, inner link, form control) still participates in the
|
|
327
|
+
// hover/focus-within lift. Tagged at mount so the SCSS can rely on a plain
|
|
328
|
+
// attribute selector rather than `:has()` inside `:where()` (which has
|
|
329
|
+
// uneven browser behaviour today).
|
|
330
|
+
if (!article.dataset.clickable) {
|
|
331
|
+
const focusable = article.querySelector('a, button, input, select, textarea, [role="button"], [tabindex]:not([tabindex="-1"])');
|
|
332
|
+
if (focusable)
|
|
333
|
+
article.dataset.interactive = 'true';
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
el: article,
|
|
337
|
+
destroy: () => {
|
|
338
|
+
for (const dispose of disposers) {
|
|
339
|
+
try {
|
|
340
|
+
dispose();
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
if (import.meta.env?.DEV) {
|
|
344
|
+
console.error('[<Card>] disposer threw:', err);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
disposers.length = 0;
|
|
349
|
+
article.replaceChildren();
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=Card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.js","sourceRoot":"","sources":["../../../src/organisms/content/Card.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/// Card horizontal orientation — @container upgrade
|
|
2
|
+
/// @group organisms/content
|
|
3
|
+
|
|
4
|
+
@use 'card-tokens' as tokens;
|
|
5
|
+
|
|
6
|
+
// ============================================
|
|
7
|
+
// Horizontal orientation — mobile-first @container upgrade
|
|
8
|
+
// ============================================
|
|
9
|
+
//
|
|
10
|
+
// Below $card-horizontal-min the layout stays vertical (base rules win).
|
|
11
|
+
// At or above the threshold, horizontal cards switch the layout element
|
|
12
|
+
// to a 2-column grid: media spans the full block-size on the inline-start,
|
|
13
|
+
// header/body/footer stack on the inline-end.
|
|
14
|
+
|
|
15
|
+
@container (min-inline-size: #{tokens.$card-horizontal-min}) {
|
|
16
|
+
.ui-card[data-orientation='horizontal'] > .ui-card-layout {
|
|
17
|
+
display: grid;
|
|
18
|
+
grid-template-columns:
|
|
19
|
+
clamp(
|
|
20
|
+
#{tokens.$card-media-min},
|
|
21
|
+
#{tokens.$card-media-preferred},
|
|
22
|
+
#{tokens.$card-media-max}
|
|
23
|
+
)
|
|
24
|
+
1fr;
|
|
25
|
+
// Explicit 3-row track: header (auto) | body (1fr fills extra space) |
|
|
26
|
+
// footer (auto, pinned at the bottom by the track order alone). This
|
|
27
|
+
// produces the editorial layout: header+body hug the block-start while
|
|
28
|
+
// footer always sits flush to the card's block-end, no matter how tall
|
|
29
|
+
// the media side is.
|
|
30
|
+
grid-template-rows: auto 1fr auto;
|
|
31
|
+
column-gap: var(--space-md); // media ↔ body: Friends
|
|
32
|
+
row-gap: 0;
|
|
33
|
+
align-items: stretch;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.ui-card[data-orientation='horizontal'] > .ui-card-layout > .ui-card-media {
|
|
37
|
+
grid-column: 1;
|
|
38
|
+
grid-row: 1 / -1;
|
|
39
|
+
// Media fills the grid cell edge-to-edge. Any aspect-ratio set on the
|
|
40
|
+
// media slot loses meaning here because the cell's block-size is driven
|
|
41
|
+
// by the layout; the inner img/video relies on object-fit: cover (from
|
|
42
|
+
// base .ui-card-media rules) to crop gracefully.
|
|
43
|
+
aspect-ratio: auto;
|
|
44
|
+
inline-size: auto;
|
|
45
|
+
block-size: auto;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.ui-card[data-orientation='horizontal'] > .ui-card-layout > .ui-card-header {
|
|
49
|
+
grid-column: 2;
|
|
50
|
+
grid-row: 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.ui-card[data-orientation='horizontal'] > .ui-card-layout > .ui-card-body {
|
|
54
|
+
grid-column: 2;
|
|
55
|
+
grid-row: 2;
|
|
56
|
+
// Content hugs the block-start of the 1fr track instead of centre-
|
|
57
|
+
// stretching across the extra space.
|
|
58
|
+
align-self: start;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.ui-card[data-orientation='horizontal'] > .ui-card-layout > .ui-card-footer {
|
|
62
|
+
grid-column: 2;
|
|
63
|
+
grid-row: 3;
|
|
64
|
+
// Row 3 is auto-sized and placed after the 1fr row → footer naturally
|
|
65
|
+
// pins to the block-end. The base `margin-block-start: auto` rule is a
|
|
66
|
+
// no-op in grid context and doesn't interfere here.
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Padded horizontal: media kisses the leading + block edges.
|
|
70
|
+
.ui-card[data-orientation='horizontal']:not([data-padding='none'])
|
|
71
|
+
> .ui-card-layout
|
|
72
|
+
> .ui-card-media {
|
|
73
|
+
margin-block: calc(-1 * var(--_card-padding));
|
|
74
|
+
margin-inline-start: calc(-1 * var(--_card-padding));
|
|
75
|
+
border-start-start-radius: inherit;
|
|
76
|
+
border-end-start-radius: inherit;
|
|
77
|
+
border-start-end-radius: 0;
|
|
78
|
+
border-end-end-radius: 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Zero-padding horizontal: only the trailing corners need squaring.
|
|
82
|
+
.ui-card[data-orientation='horizontal'][data-padding='none']
|
|
83
|
+
> .ui-card-layout
|
|
84
|
+
> .ui-card-media {
|
|
85
|
+
border-start-end-radius: 0;
|
|
86
|
+
border-end-end-radius: 0;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/// Card pseudo-link overlay + focus ring
|
|
2
|
+
/// @group organisms/content
|
|
3
|
+
|
|
4
|
+
@use '@pithyjs/design-system/a11y/styles/mixins' as a11y;
|
|
5
|
+
|
|
6
|
+
// ============================================
|
|
7
|
+
// Pseudo-link overlay (clickable cards)
|
|
8
|
+
// ============================================
|
|
9
|
+
|
|
10
|
+
.ui-card-link {
|
|
11
|
+
position: absolute;
|
|
12
|
+
inset: 0;
|
|
13
|
+
z-index: 1;
|
|
14
|
+
border-radius: inherit;
|
|
15
|
+
color: inherit;
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
// The link itself carries no visible chrome — the card is the affordance.
|
|
18
|
+
-webkit-tap-highlight-color: transparent;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Interactive descendants inside a clickable card rise above the overlay
|
|
22
|
+
// anchor so they still receive their own clicks (buttons, tag chips,
|
|
23
|
+
// inline links inside the body slot).
|
|
24
|
+
.ui-card[data-clickable='true']
|
|
25
|
+
.ui-card-layout
|
|
26
|
+
:is(
|
|
27
|
+
a:not(.ui-card-link),
|
|
28
|
+
button,
|
|
29
|
+
[role='button'],
|
|
30
|
+
input,
|
|
31
|
+
select,
|
|
32
|
+
textarea,
|
|
33
|
+
[tabindex]:not([tabindex='-1'])
|
|
34
|
+
) {
|
|
35
|
+
position: relative;
|
|
36
|
+
z-index: 2;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.ui-card-link-label {
|
|
40
|
+
// Visually-hidden but kept in the a11y tree.
|
|
41
|
+
@include a11y.visually-hidden;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Card-wide focus ring: when the stretched link takes keyboard focus, the
|
|
45
|
+
// whole article paints the focus ring — the card *is* the focus indicator.
|
|
46
|
+
// Disabled cards are inert (no focus possible), but guard defensively.
|
|
47
|
+
.ui-card:not([data-disabled='true']):has(.ui-card-link:focus-visible) {
|
|
48
|
+
@include a11y.focus-ring;
|
|
49
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/// Card full-bleed media overlay mode
|
|
2
|
+
/// @group organisms/content
|
|
3
|
+
|
|
4
|
+
// ============================================
|
|
5
|
+
// Full-bleed media overlay mode
|
|
6
|
+
// ============================================
|
|
7
|
+
//
|
|
8
|
+
// Flipped topology: media fills the card (ignoring `padding`) and the
|
|
9
|
+
// header/body/footer collapse into a single `.ui-card-caption` group that
|
|
10
|
+
// rides a gradient scrim at the block-end. Uses CSS Grid with a single
|
|
11
|
+
// named area so media + caption stack in the same cell — caption pins to
|
|
12
|
+
// block-end, media fills. Text color flips to `--color-text-inverse`
|
|
13
|
+
// (always readable on the dark scrim regardless of theme).
|
|
14
|
+
|
|
15
|
+
.ui-card[data-media-overlay='true'] > .ui-card-layout {
|
|
16
|
+
display: grid;
|
|
17
|
+
grid-template-areas: 'stack';
|
|
18
|
+
padding: 0;
|
|
19
|
+
gap: 0;
|
|
20
|
+
// Overlay cards are media-first — block-size is dictated by the media's
|
|
21
|
+
// aspect ratio. The caption lives on top.
|
|
22
|
+
min-block-size: 100%;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ui-card[data-media-overlay='true'] > .ui-card-layout > .ui-card-media {
|
|
26
|
+
grid-area: stack;
|
|
27
|
+
z-index: 0;
|
|
28
|
+
inline-size: 100%;
|
|
29
|
+
block-size: 100%;
|
|
30
|
+
// Cancel the vertical-mode negative-inset margins — they're irrelevant
|
|
31
|
+
// now that media spans the whole card via grid-area.
|
|
32
|
+
margin: 0;
|
|
33
|
+
// Inherit the card's radius so corners stay rounded.
|
|
34
|
+
border-radius: inherit;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ui-card[data-media-overlay='true'] > .ui-card-layout > .ui-card-caption {
|
|
38
|
+
grid-area: stack;
|
|
39
|
+
align-self: end;
|
|
40
|
+
z-index: 1;
|
|
41
|
+
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
gap: var(--space-xs);
|
|
45
|
+
padding: var(--_card-padding);
|
|
46
|
+
color: var(--color-text-inverse);
|
|
47
|
+
|
|
48
|
+
// Scrim — fades from transparent at the top to a dark `--color-overlay`
|
|
49
|
+
// tint at the block-end so the caption stays readable over any image.
|
|
50
|
+
// `--color-overlay` is a design-system token that's always dark, by design.
|
|
51
|
+
background: linear-gradient(
|
|
52
|
+
to top,
|
|
53
|
+
color-mix(in oklch, var(--color-overlay) 82%, transparent) 0%,
|
|
54
|
+
color-mix(in oklch, var(--color-overlay) 50%, transparent) 45%,
|
|
55
|
+
transparent 100%
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// Inherit the card's radius on the block-end corners only.
|
|
59
|
+
border-end-start-radius: inherit;
|
|
60
|
+
border-end-end-radius: inherit;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Inside a caption, the heading, body, and eyebrow all inherit the inverse
|
|
64
|
+
// color. Eyebrow keeps a slight tint drop so it reads as secondary.
|
|
65
|
+
.ui-card[data-media-overlay='true']
|
|
66
|
+
.ui-card-caption
|
|
67
|
+
:is(h1, h2, h3, h4, h5, h6),
|
|
68
|
+
.ui-card[data-media-overlay='true'] .ui-card-caption .ui-card-body,
|
|
69
|
+
.ui-card[data-media-overlay='true'] .ui-card-caption .ui-card-body .ui-text,
|
|
70
|
+
.ui-card[data-media-overlay='true'] .ui-card-caption .ui-text {
|
|
71
|
+
color: var(--color-text-inverse);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.ui-card[data-media-overlay='true'] .ui-card-caption .ui-card-eyebrow {
|
|
75
|
+
color: var(--color-text-inverse);
|
|
76
|
+
opacity: 0.9;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Muted text becomes less translucent against the scrim — fully opaque
|
|
80
|
+
// inverse color reads better than a muted variant would.
|
|
81
|
+
.ui-card[data-media-overlay='true'] .ui-card-caption [data-color='text-muted'] {
|
|
82
|
+
color: var(--color-text-inverse);
|
|
83
|
+
opacity: 0.8;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Footer's auto margin-block-start makes sense inside a flex column card,
|
|
87
|
+
// but inside the compact caption stack we want tight rhythm.
|
|
88
|
+
.ui-card[data-media-overlay='true'] .ui-card-caption > .ui-card-footer {
|
|
89
|
+
margin-block-start: 0;
|
|
90
|
+
padding-block-start: 0;
|
|
91
|
+
}
|