@primitiv-ui/react 0.1.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/README.md +79 -0
- package/package.json +59 -0
- package/src/AccessibleIcon/AccessibleIcon.tsx +40 -0
- package/src/AccessibleIcon/README.md +42 -0
- package/src/AccessibleIcon/__tests__/AccessibleIcon.test.tsx +47 -0
- package/src/AccessibleIcon/index.ts +2 -0
- package/src/AccessibleIcon/types.ts +8 -0
- package/src/Accordion/Accordion.tsx +412 -0
- package/src/Accordion/AccordionContext.ts +12 -0
- package/src/Accordion/README.md +202 -0
- package/src/Accordion/__tests__/Accordion.asChild.test.tsx +237 -0
- package/src/Accordion/__tests__/Accordion.basic-rendering.test.tsx +333 -0
- package/src/Accordion/__tests__/Accordion.controlled-state.test.tsx +175 -0
- package/src/Accordion/__tests__/Accordion.data-attributes.test.tsx +272 -0
- package/src/Accordion/__tests__/Accordion.disabled-items.test.tsx +311 -0
- package/src/Accordion/__tests__/Accordion.error-handling.test.tsx +119 -0
- package/src/Accordion/__tests__/Accordion.forceMount.test.tsx +119 -0
- package/src/Accordion/__tests__/Accordion.keyboard-interaction.test.tsx +736 -0
- package/src/Accordion/__tests__/Accordion.mouse-interaction.test.tsx +212 -0
- package/src/Accordion/__tests__/Accordion.multiple-mode.test.tsx +90 -0
- package/src/Accordion/__tests__/Accordion.reading-direction.test.tsx +139 -0
- package/src/Accordion/__tests__/Accordion.uncontrolled-state.test.tsx +154 -0
- package/src/Accordion/hooks/index.ts +6 -0
- package/src/Accordion/hooks/useAccordionContext.ts +1 -0
- package/src/Accordion/hooks/useAccordionHeaderContext.ts +10 -0
- package/src/Accordion/hooks/useAccordionItem.ts +22 -0
- package/src/Accordion/hooks/useAccordionItemContext.ts +1 -0
- package/src/Accordion/hooks/useAccordionRoot.ts +151 -0
- package/src/Accordion/hooks/useAccordionTrigger.ts +90 -0
- package/src/Accordion/index.ts +1 -0
- package/src/Accordion/types.ts +81 -0
- package/src/Alert/Alert.tsx +43 -0
- package/src/Alert/README.md +54 -0
- package/src/Alert/__tests__/Alert.test.tsx +28 -0
- package/src/Alert/index.ts +2 -0
- package/src/Alert/types.ts +5 -0
- package/src/Avatar/Avatar.tsx +149 -0
- package/src/Avatar/AvatarContext.ts +20 -0
- package/src/Avatar/README.md +116 -0
- package/src/Avatar/__tests__/Avatar.asChild.test.tsx +53 -0
- package/src/Avatar/__tests__/Avatar.basic-rendering.test.tsx +14 -0
- package/src/Avatar/__tests__/Avatar.error-handling.test.tsx +30 -0
- package/src/Avatar/__tests__/Avatar.fallback.test.tsx +75 -0
- package/src/Avatar/__tests__/Avatar.image-loading.test.tsx +81 -0
- package/src/Avatar/hooks/index.ts +2 -0
- package/src/Avatar/hooks/useAvatarContext.ts +1 -0
- package/src/Avatar/hooks/useAvatarImage.ts +40 -0
- package/src/Avatar/index.ts +3 -0
- package/src/Avatar/types.ts +44 -0
- package/src/Breadcrumb/Breadcrumb.tsx +234 -0
- package/src/Breadcrumb/README.md +111 -0
- package/src/Breadcrumb/__tests__/Breadcrumb.asChild.test.tsx +33 -0
- package/src/Breadcrumb/__tests__/Breadcrumb.basic-rendering.test.tsx +132 -0
- package/src/Breadcrumb/index.ts +2 -0
- package/src/Breadcrumb/types.ts +22 -0
- package/src/Button/Button.tsx +95 -0
- package/src/Button/README.md +112 -0
- package/src/Button/__tests__/Button.asChild.test.tsx +91 -0
- package/src/Button/__tests__/Button.basic-rendering.test.tsx +126 -0
- package/src/Button/__tests__/Button.contract.test.tsx +72 -0
- package/src/Button/__tests__/Button.disabled.test.tsx +52 -0
- package/src/Button/__tests__/Button.icon-usage.test.tsx +57 -0
- package/src/Button/__tests__/Button.keyboard-interaction.test.tsx +70 -0
- package/src/Button/index.ts +2 -0
- package/src/Button/types.ts +8 -0
- package/src/Carousel/Carousel.tsx +708 -0
- package/src/Carousel/CarouselContext.ts +11 -0
- package/src/Carousel/README.md +848 -0
- package/src/Carousel/__tests__/Carousel.asChild.test.tsx +178 -0
- package/src/Carousel/__tests__/Carousel.auto-play.test.tsx +617 -0
- package/src/Carousel/__tests__/Carousel.basic-rendering.test.tsx +569 -0
- package/src/Carousel/__tests__/Carousel.controlled-state.test.tsx +137 -0
- package/src/Carousel/__tests__/Carousel.error-handling.test.tsx +81 -0
- package/src/Carousel/__tests__/Carousel.ids.test.tsx +111 -0
- package/src/Carousel/__tests__/Carousel.imperative-api.test.tsx +213 -0
- package/src/Carousel/__tests__/Carousel.indicators.test.tsx +560 -0
- package/src/Carousel/__tests__/Carousel.intersection-observer.test.tsx +276 -0
- package/src/Carousel/__tests__/Carousel.keyboard-navigation.test.tsx +158 -0
- package/src/Carousel/__tests__/Carousel.play-pause.test.tsx +232 -0
- package/src/Carousel/__tests__/Carousel.prev-next.test.tsx +68 -0
- package/src/Carousel/__tests__/Carousel.reduced-motion.test.tsx +49 -0
- package/src/Carousel/__tests__/Carousel.refresh-progress.test.tsx +87 -0
- package/src/Carousel/__tests__/Carousel.scroll-snap-change.test.tsx +179 -0
- package/src/Carousel/__tests__/Carousel.scroll-sync.test.tsx +109 -0
- package/src/Carousel/__tests__/Carousel.slides-per-move.test.tsx +151 -0
- package/src/Carousel/__tests__/Carousel.slides-per-page.test.tsx +183 -0
- package/src/Carousel/__tests__/Carousel.touch-interaction.test.tsx +96 -0
- package/src/Carousel/__tests__/Carousel.transition-modes.test.tsx +70 -0
- package/src/Carousel/__tests__/Carousel.translations.test.tsx +157 -0
- package/src/Carousel/__tests__/Carousel.uncontrolled-state.test.tsx +146 -0
- package/src/Carousel/hooks/index.ts +4 -0
- package/src/Carousel/hooks/useCarouselContext.ts +13 -0
- package/src/Carousel/hooks/useCarouselRoot.ts +450 -0
- package/src/Carousel/hooks/useCarouselSlide.ts +45 -0
- package/src/Carousel/hooks/useCarouselViewport.ts +290 -0
- package/src/Carousel/index.ts +3 -0
- package/src/Carousel/types.ts +400 -0
- package/src/Checkbox/Checkbox.tsx +228 -0
- package/src/Checkbox/CheckboxContext.ts +12 -0
- package/src/Checkbox/README.md +156 -0
- package/src/Checkbox/__tests__/Checkbox.asChild.test.tsx +69 -0
- package/src/Checkbox/__tests__/Checkbox.basic-rendering.test.tsx +41 -0
- package/src/Checkbox/__tests__/Checkbox.controlled-state.test.tsx +82 -0
- package/src/Checkbox/__tests__/Checkbox.disabled.test.tsx +15 -0
- package/src/Checkbox/__tests__/Checkbox.indeterminate.test.tsx +82 -0
- package/src/Checkbox/__tests__/Checkbox.indicator.test.tsx +117 -0
- package/src/Checkbox/__tests__/Checkbox.uncontrolled-state.test.tsx +89 -0
- package/src/Checkbox/hooks/index.ts +2 -0
- package/src/Checkbox/hooks/useCheckboxContext.ts +1 -0
- package/src/Checkbox/hooks/useCheckboxRoot.ts +32 -0
- package/src/Checkbox/index.ts +1 -0
- package/src/Checkbox/types.ts +33 -0
- package/src/CheckboxCard/CheckboxCard.tsx +208 -0
- package/src/CheckboxCard/CheckboxCardContext.ts +12 -0
- package/src/CheckboxCard/README.md +114 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.asChild.test.tsx +54 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.basic-rendering.test.tsx +58 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.controlled-state.test.tsx +77 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.disabled.test.tsx +55 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.error-handling.test.tsx +20 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.indeterminate.test.tsx +60 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.indicator.test.tsx +136 -0
- package/src/CheckboxCard/__tests__/CheckboxCard.uncontrolled-state.test.tsx +73 -0
- package/src/CheckboxCard/hooks/index.ts +2 -0
- package/src/CheckboxCard/hooks/useCheckboxCardContext.ts +1 -0
- package/src/CheckboxCard/hooks/useCheckboxCardRoot.ts +30 -0
- package/src/CheckboxCard/index.ts +3 -0
- package/src/CheckboxCard/types.ts +33 -0
- package/src/Collapsible/Collapsible.tsx +316 -0
- package/src/Collapsible/CollapsibleContext.ts +7 -0
- package/src/Collapsible/README.md +174 -0
- package/src/Collapsible/__tests__/Collapsible.asChild.test.tsx +240 -0
- package/src/Collapsible/__tests__/Collapsible.basic-rendering.test.tsx +118 -0
- package/src/Collapsible/__tests__/Collapsible.controlled-state.test.tsx +134 -0
- package/src/Collapsible/__tests__/Collapsible.disabled.test.tsx +132 -0
- package/src/Collapsible/__tests__/Collapsible.error-handling.test.tsx +40 -0
- package/src/Collapsible/__tests__/Collapsible.forceMount.test.tsx +111 -0
- package/src/Collapsible/__tests__/Collapsible.triggerIcon.test.tsx +93 -0
- package/src/Collapsible/__tests__/Collapsible.uncontrolled-state.test.tsx +125 -0
- package/src/Collapsible/hooks/index.ts +2 -0
- package/src/Collapsible/hooks/useCollapsibleRoot.ts +34 -0
- package/src/Collapsible/hooks/useCollapsibleTrigger.ts +49 -0
- package/src/Collapsible/index.ts +1 -0
- package/src/Collapsible/types.ts +48 -0
- package/src/ContextMenu/ContextMenu.tsx +1004 -0
- package/src/ContextMenu/ContextMenuContentContext.ts +15 -0
- package/src/ContextMenu/ContextMenuContext.ts +21 -0
- package/src/ContextMenu/ContextMenuGroupContext.ts +8 -0
- package/src/ContextMenu/ContextMenuItemIndicatorContext.ts +8 -0
- package/src/ContextMenu/ContextMenuRadioGroupContext.ts +9 -0
- package/src/ContextMenu/ContextMenuSubContext.ts +15 -0
- package/src/ContextMenu/README.md +275 -0
- package/src/ContextMenu/__tests__/ContextMenu.asChild.test.tsx +186 -0
- package/src/ContextMenu/__tests__/ContextMenu.basic-rendering.test.tsx +39 -0
- package/src/ContextMenu/__tests__/ContextMenu.checkbox-item.test.tsx +145 -0
- package/src/ContextMenu/__tests__/ContextMenu.error-handling.test.tsx +113 -0
- package/src/ContextMenu/__tests__/ContextMenu.group-label.test.tsx +48 -0
- package/src/ContextMenu/__tests__/ContextMenu.item-indicator.test.tsx +88 -0
- package/src/ContextMenu/__tests__/ContextMenu.item.test.tsx +106 -0
- package/src/ContextMenu/__tests__/ContextMenu.keyboard-interaction.test.tsx +172 -0
- package/src/ContextMenu/__tests__/ContextMenu.mouse-interaction.test.tsx +227 -0
- package/src/ContextMenu/__tests__/ContextMenu.radio-item.test.tsx +127 -0
- package/src/ContextMenu/__tests__/ContextMenu.reading-direction.test.tsx +152 -0
- package/src/ContextMenu/__tests__/ContextMenu.separator.test.tsx +47 -0
- package/src/ContextMenu/__tests__/ContextMenu.state-modes.test.tsx +119 -0
- package/src/ContextMenu/__tests__/ContextMenu.sub.test.tsx +262 -0
- package/src/ContextMenu/__tests__/ContextMenu.typeahead.test.tsx +89 -0
- package/src/ContextMenu/constants.ts +4 -0
- package/src/ContextMenu/index.ts +1 -0
- package/src/ContextMenu/types.ts +199 -0
- package/src/DirectionProvider/DirectionContext.ts +21 -0
- package/src/DirectionProvider/DirectionProvider.tsx +31 -0
- package/src/DirectionProvider/README.md +62 -0
- package/src/DirectionProvider/__tests__/DirectionProvider.test.tsx +29 -0
- package/src/DirectionProvider/index.ts +3 -0
- package/src/DirectionProvider/types.ts +10 -0
- package/src/Divider/Divider.tsx +57 -0
- package/src/Divider/README.md +57 -0
- package/src/Divider/__tests__/Divider.test.tsx +41 -0
- package/src/Divider/index.ts +1 -0
- package/src/Divider/types.ts +5 -0
- package/src/Dropdown/Dropdown.tsx +842 -0
- package/src/Dropdown/DropdownContentContext.ts +15 -0
- package/src/Dropdown/DropdownContext.ts +17 -0
- package/src/Dropdown/DropdownGroupContext.ts +8 -0
- package/src/Dropdown/DropdownItemIndicatorContext.ts +13 -0
- package/src/Dropdown/DropdownRadioGroupContext.ts +9 -0
- package/src/Dropdown/DropdownSubContext.ts +15 -0
- package/src/Dropdown/README.md +284 -0
- package/src/Dropdown/__tests__/Dropdown.asChild.test.tsx +286 -0
- package/src/Dropdown/__tests__/Dropdown.basic-rendering.test.tsx +43 -0
- package/src/Dropdown/__tests__/Dropdown.checkbox-item.test.tsx +121 -0
- package/src/Dropdown/__tests__/Dropdown.disabled.test.tsx +143 -0
- package/src/Dropdown/__tests__/Dropdown.error-handling.test.tsx +85 -0
- package/src/Dropdown/__tests__/Dropdown.group-label.test.tsx +68 -0
- package/src/Dropdown/__tests__/Dropdown.item-indicator.test.tsx +260 -0
- package/src/Dropdown/__tests__/Dropdown.item.test.tsx +72 -0
- package/src/Dropdown/__tests__/Dropdown.keyboard-edge-cases.test.tsx +77 -0
- package/src/Dropdown/__tests__/Dropdown.keyboard-interaction.test.tsx +310 -0
- package/src/Dropdown/__tests__/Dropdown.mouse-interaction.test.tsx +347 -0
- package/src/Dropdown/__tests__/Dropdown.radio-item.test.tsx +134 -0
- package/src/Dropdown/__tests__/Dropdown.reading-direction.test.tsx +153 -0
- package/src/Dropdown/__tests__/Dropdown.separator.test.tsx +46 -0
- package/src/Dropdown/__tests__/Dropdown.state-modes.test.tsx +100 -0
- package/src/Dropdown/__tests__/Dropdown.sub.test.tsx +185 -0
- package/src/Dropdown/__tests__/Dropdown.trigger.test.tsx +110 -0
- package/src/Dropdown/__tests__/Dropdown.typeahead.test.tsx +133 -0
- package/src/Dropdown/constants.ts +4 -0
- package/src/Dropdown/hooks/index.ts +9 -0
- package/src/Dropdown/hooks/useCloseSiblingSub.ts +13 -0
- package/src/Dropdown/hooks/useDropdownContent.ts +162 -0
- package/src/Dropdown/hooks/useDropdownContext.ts +1 -0
- package/src/Dropdown/hooks/useDropdownGroup.ts +18 -0
- package/src/Dropdown/hooks/useDropdownItem.ts +49 -0
- package/src/Dropdown/hooks/useDropdownLabel.ts +15 -0
- package/src/Dropdown/hooks/useDropdownRoot.ts +57 -0
- package/src/Dropdown/hooks/useDropdownSubContext.ts +1 -0
- package/src/Dropdown/hooks/useDropdownTrigger.ts +31 -0
- package/src/Dropdown/index.ts +1 -0
- package/src/Dropdown/types.ts +200 -0
- package/src/EmptyState/EmptyState.tsx +245 -0
- package/src/EmptyState/README.md +129 -0
- package/src/EmptyState/__tests__/EmptyState.Actions.test.tsx +32 -0
- package/src/EmptyState/__tests__/EmptyState.Description.test.tsx +30 -0
- package/src/EmptyState/__tests__/EmptyState.Media.test.tsx +34 -0
- package/src/EmptyState/__tests__/EmptyState.Root.test.tsx +28 -0
- package/src/EmptyState/__tests__/EmptyState.Title.test.tsx +26 -0
- package/src/EmptyState/index.ts +2 -0
- package/src/EmptyState/types.ts +21 -0
- package/src/Field/Field.tsx +239 -0
- package/src/Field/FieldContext.ts +22 -0
- package/src/Field/README.md +167 -0
- package/src/Field/__tests__/Field.asChild.test.tsx +83 -0
- package/src/Field/__tests__/Field.basic-rendering.test.tsx +104 -0
- package/src/Field/__tests__/Field.state-cascade.test.tsx +75 -0
- package/src/Field/hooks/index.ts +2 -0
- package/src/Field/hooks/useFieldContext.ts +1 -0
- package/src/Field/hooks/useFieldProps.ts +57 -0
- package/src/Field/index.ts +2 -0
- package/src/Field/types.ts +33 -0
- package/src/Fieldset/Fieldset.tsx +104 -0
- package/src/Fieldset/README.md +74 -0
- package/src/Fieldset/__tests__/Fieldset.basic-rendering.test.tsx +81 -0
- package/src/Fieldset/__tests__/Fieldset.disabled.test.tsx +41 -0
- package/src/Fieldset/index.ts +2 -0
- package/src/Fieldset/types.ts +5 -0
- package/src/Input/Input.tsx +120 -0
- package/src/Input/README.md +180 -0
- package/src/Input/__tests__/Input.asChild.test.tsx +85 -0
- package/src/Input/__tests__/Input.basic-rendering.test.tsx +118 -0
- package/src/Input/__tests__/Input.disabled.test.tsx +49 -0
- package/src/Input/__tests__/Input.field-integration.test.tsx +148 -0
- package/src/Input/index.ts +2 -0
- package/src/Input/types.ts +7 -0
- package/src/InputGroup/InputGroup.tsx +228 -0
- package/src/InputGroup/README.md +178 -0
- package/src/InputGroup/__tests__/InputGroup.asChild.test.tsx +109 -0
- package/src/InputGroup/__tests__/InputGroup.basic-rendering.test.tsx +106 -0
- package/src/InputGroup/index.ts +2 -0
- package/src/InputGroup/types.ts +13 -0
- package/src/MillerColumns/MillerColumns.tsx +329 -0
- package/src/MillerColumns/MillerColumnsContext.ts +25 -0
- package/src/MillerColumns/README.md +278 -0
- package/src/MillerColumns/__tests__/MillerColumns.aria.test.tsx +82 -0
- package/src/MillerColumns/__tests__/MillerColumns.asChild.test.tsx +106 -0
- package/src/MillerColumns/__tests__/MillerColumns.auto-scroll.test.tsx +68 -0
- package/src/MillerColumns/__tests__/MillerColumns.basic-rendering.test.tsx +52 -0
- package/src/MillerColumns/__tests__/MillerColumns.column-projection.test.tsx +161 -0
- package/src/MillerColumns/__tests__/MillerColumns.controlled-state.test.tsx +90 -0
- package/src/MillerColumns/__tests__/MillerColumns.data-attributes.test.tsx +77 -0
- package/src/MillerColumns/__tests__/MillerColumns.disabled-items.test.tsx +65 -0
- package/src/MillerColumns/__tests__/MillerColumns.error-handling.test.tsx +57 -0
- package/src/MillerColumns/__tests__/MillerColumns.fixtures.ts +15 -0
- package/src/MillerColumns/__tests__/MillerColumns.item-indicator.test.tsx +57 -0
- package/src/MillerColumns/__tests__/MillerColumns.keyboard-interaction.test.tsx +181 -0
- package/src/MillerColumns/__tests__/MillerColumns.preview-panel.test.tsx +47 -0
- package/src/MillerColumns/__tests__/MillerColumns.resize.test.tsx +137 -0
- package/src/MillerColumns/__tests__/MillerColumns.roving-tabindex.test.tsx +91 -0
- package/src/MillerColumns/__tests__/MillerColumns.selection.test.tsx +54 -0
- package/src/MillerColumns/__tests__/MillerColumns.uncontrolled-state.test.tsx +70 -0
- package/src/MillerColumns/hooks/index.ts +7 -0
- package/src/MillerColumns/hooks/useMillerColumnsColumn.ts +23 -0
- package/src/MillerColumns/hooks/useMillerColumnsColumnContext.ts +1 -0
- package/src/MillerColumns/hooks/useMillerColumnsContext.ts +1 -0
- package/src/MillerColumns/hooks/useMillerColumnsItem.ts +157 -0
- package/src/MillerColumns/hooks/useMillerColumnsItemContext.ts +1 -0
- package/src/MillerColumns/hooks/useMillerColumnsResizeHandle.ts +76 -0
- package/src/MillerColumns/hooks/useMillerColumnsRoot.ts +0 -0
- package/src/MillerColumns/index.ts +3 -0
- package/src/MillerColumns/types.ts +93 -0
- package/src/MillerColumns/useMillerColumnsSelection.ts +31 -0
- package/src/MillerColumns/utils.ts +75 -0
- package/src/Modal/Modal.tsx +474 -0
- package/src/Modal/ModalContext.ts +13 -0
- package/src/Modal/README.md +207 -0
- package/src/Modal/__tests__/Modal.accessibility.test.tsx +167 -0
- package/src/Modal/__tests__/Modal.asChild.test.tsx +162 -0
- package/src/Modal/__tests__/Modal.click-outside.test.tsx +115 -0
- package/src/Modal/__tests__/Modal.content.test.tsx +193 -0
- package/src/Modal/__tests__/Modal.controlled-state.test.tsx +120 -0
- package/src/Modal/__tests__/Modal.error-handling.test.tsx +30 -0
- package/src/Modal/__tests__/Modal.escape-hatches.test.tsx +99 -0
- package/src/Modal/__tests__/Modal.imperative-api.test.tsx +119 -0
- package/src/Modal/__tests__/Modal.nested.test.tsx +106 -0
- package/src/Modal/__tests__/Modal.overlay.test.tsx +99 -0
- package/src/Modal/__tests__/Modal.portal.test.tsx +90 -0
- package/src/Modal/__tests__/Modal.presence.test.tsx +111 -0
- package/src/Modal/__tests__/Modal.trigger.test.tsx +70 -0
- package/src/Modal/__tests__/Modal.uncontrolled-state.test.tsx +72 -0
- package/src/Modal/__tests__/dialog-polyfill.ts +40 -0
- package/src/Modal/hooks/index.ts +4 -0
- package/src/Modal/hooks/useModalContent.ts +62 -0
- package/src/Modal/hooks/useModalContext.ts +1 -0
- package/src/Modal/hooks/useModalRoot.ts +81 -0
- package/src/Modal/hooks/useModalTrigger.ts +25 -0
- package/src/Modal/index.ts +3 -0
- package/src/Modal/types.ts +76 -0
- package/src/Portal/Portal.tsx +28 -0
- package/src/Portal/README.md +70 -0
- package/src/Portal/__tests__/Portal.basic-rendering.test.tsx +17 -0
- package/src/Portal/index.ts +2 -0
- package/src/Portal/types.ts +6 -0
- package/src/Progress/Progress.tsx +178 -0
- package/src/Progress/ProgressContext.ts +15 -0
- package/src/Progress/README.md +112 -0
- package/src/Progress/__tests__/Progress.asChild.test.tsx +37 -0
- package/src/Progress/__tests__/Progress.basic-rendering.test.tsx +65 -0
- package/src/Progress/__tests__/Progress.error-handling.test.tsx +40 -0
- package/src/Progress/__tests__/Progress.fixtures.ts +7 -0
- package/src/Progress/__tests__/Progress.value.test.tsx +83 -0
- package/src/Progress/hooks/index.ts +2 -0
- package/src/Progress/hooks/useProgressContext.ts +1 -0
- package/src/Progress/hooks/useProgressRoot.ts +45 -0
- package/src/Progress/index.ts +3 -0
- package/src/Progress/types.ts +43 -0
- package/src/RadioCard/README.md +133 -0
- package/src/RadioCard/RadioCard.tsx +334 -0
- package/src/RadioCard/RadioCardContext.ts +23 -0
- package/src/RadioCard/RadioCardItemContext.ts +10 -0
- package/src/RadioCard/__tests__/RadioCard.asChild.test.tsx +76 -0
- package/src/RadioCard/__tests__/RadioCard.basic-rendering.test.tsx +87 -0
- package/src/RadioCard/__tests__/RadioCard.controlled-state.test.tsx +107 -0
- package/src/RadioCard/__tests__/RadioCard.disabled-items.test.tsx +61 -0
- package/src/RadioCard/__tests__/RadioCard.error-handling.test.tsx +35 -0
- package/src/RadioCard/__tests__/RadioCard.indicator.test.tsx +119 -0
- package/src/RadioCard/__tests__/RadioCard.keyboard-interaction.test.tsx +158 -0
- package/src/RadioCard/__tests__/RadioCard.orientation.test.tsx +90 -0
- package/src/RadioCard/__tests__/RadioCard.reading-direction.test.tsx +65 -0
- package/src/RadioCard/__tests__/RadioCard.uncontrolled-state.test.tsx +108 -0
- package/src/RadioCard/hooks/index.ts +3 -0
- package/src/RadioCard/hooks/useRadioCardContext.ts +1 -0
- package/src/RadioCard/hooks/useRadioCardItemContext.ts +1 -0
- package/src/RadioCard/hooks/useRadioCardRoot.ts +77 -0
- package/src/RadioCard/index.ts +4 -0
- package/src/RadioCard/types.ts +51 -0
- package/src/RadioGroup/README.md +185 -0
- package/src/RadioGroup/RadioGroup.tsx +353 -0
- package/src/RadioGroup/RadioGroupContext.ts +23 -0
- package/src/RadioGroup/RadioGroupItemContext.ts +10 -0
- package/src/RadioGroup/__tests__/RadioGroup.asChild.test.tsx +105 -0
- package/src/RadioGroup/__tests__/RadioGroup.basic-rendering.test.tsx +72 -0
- package/src/RadioGroup/__tests__/RadioGroup.controlled-state.test.tsx +109 -0
- package/src/RadioGroup/__tests__/RadioGroup.disabled-keydown-guards.test.tsx +68 -0
- package/src/RadioGroup/__tests__/RadioGroup.disabled.test.tsx +79 -0
- package/src/RadioGroup/__tests__/RadioGroup.error-handling.test.tsx +33 -0
- package/src/RadioGroup/__tests__/RadioGroup.indicator.test.tsx +85 -0
- package/src/RadioGroup/__tests__/RadioGroup.keyboard-interaction.test.tsx +135 -0
- package/src/RadioGroup/__tests__/RadioGroup.orientation.test.tsx +90 -0
- package/src/RadioGroup/__tests__/RadioGroup.reading-direction.test.tsx +65 -0
- package/src/RadioGroup/__tests__/RadioGroup.ref-forwarding.test.tsx +45 -0
- package/src/RadioGroup/__tests__/RadioGroup.roving-tabindex.test.tsx +105 -0
- package/src/RadioGroup/__tests__/RadioGroup.uncontrolled-state.test.tsx +96 -0
- package/src/RadioGroup/hooks/index.ts +3 -0
- package/src/RadioGroup/hooks/useRadioGroupContext.ts +1 -0
- package/src/RadioGroup/hooks/useRadioGroupItemContext.ts +1 -0
- package/src/RadioGroup/hooks/useRadioGroupRoot.ts +87 -0
- package/src/RadioGroup/index.ts +1 -0
- package/src/RadioGroup/types.ts +51 -0
- package/src/Select/README.md +203 -0
- package/src/Select/Select.tsx +204 -0
- package/src/Select/__tests__/Select.asChild.test.tsx +36 -0
- package/src/Select/__tests__/Select.basic-rendering.test.tsx +17 -0
- package/src/Select/__tests__/Select.controlled-state.test.tsx +69 -0
- package/src/Select/__tests__/Select.data-attributes.test.tsx +29 -0
- package/src/Select/__tests__/Select.field-integration.test.tsx +150 -0
- package/src/Select/__tests__/Select.group.test.tsx +42 -0
- package/src/Select/__tests__/Select.placeholder.test.tsx +32 -0
- package/src/Select/index.ts +2 -0
- package/src/Select/types.ts +89 -0
- package/src/SkipNav/README.md +87 -0
- package/src/SkipNav/SkipNav.tsx +116 -0
- package/src/SkipNav/__tests__/SkipNav.basic-rendering.test.tsx +23 -0
- package/src/SkipNav/__tests__/SkipNav.ids.test.tsx +19 -0
- package/src/SkipNav/index.ts +1 -0
- package/src/SkipNav/types.ts +26 -0
- package/src/Slider/README.md +215 -0
- package/src/Slider/Slider.tsx +308 -0
- package/src/Slider/SliderContext.ts +24 -0
- package/src/Slider/__tests__/Slider.asChild.test.tsx +119 -0
- package/src/Slider/__tests__/Slider.basic-rendering.test.tsx +157 -0
- package/src/Slider/__tests__/Slider.controlled-state.test.tsx +78 -0
- package/src/Slider/__tests__/Slider.disabled.test.tsx +82 -0
- package/src/Slider/__tests__/Slider.error-handling.test.tsx +45 -0
- package/src/Slider/__tests__/Slider.fixtures.ts +53 -0
- package/src/Slider/__tests__/Slider.form.test.tsx +67 -0
- package/src/Slider/__tests__/Slider.inverted.test.tsx +112 -0
- package/src/Slider/__tests__/Slider.keyboard-interaction.test.tsx +118 -0
- package/src/Slider/__tests__/Slider.multiple-thumbs.test.tsx +84 -0
- package/src/Slider/__tests__/Slider.orientation.test.tsx +101 -0
- package/src/Slider/__tests__/Slider.pointer-interaction.test.tsx +205 -0
- package/src/Slider/__tests__/Slider.reading-direction.test.tsx +99 -0
- package/src/Slider/__tests__/Slider.uncontrolled-state.test.tsx +69 -0
- package/src/Slider/__tests__/Slider.value-commit.test.tsx +103 -0
- package/src/Slider/hooks/index.ts +3 -0
- package/src/Slider/hooks/useSliderContext.ts +1 -0
- package/src/Slider/hooks/useSliderRoot.ts +197 -0
- package/src/Slider/hooks/useSliderThumb.ts +77 -0
- package/src/Slider/index.ts +3 -0
- package/src/Slider/types.ts +48 -0
- package/src/Slider/utils.ts +155 -0
- package/src/Slot/Slot.tsx +158 -0
- package/src/Slot/__tests__/Slot.test.tsx +163 -0
- package/src/Slot/__tests__/composeEventHandlers.test.ts +74 -0
- package/src/Slot/composeEventHandlers.ts +38 -0
- package/src/Slot/index.ts +3 -0
- package/src/Slot/types.ts +5 -0
- package/src/Status/README.md +50 -0
- package/src/Status/Status.tsx +44 -0
- package/src/Status/__tests__/Status.test.tsx +28 -0
- package/src/Status/index.ts +2 -0
- package/src/Status/types.ts +5 -0
- package/src/Switch/README.md +121 -0
- package/src/Switch/Switch.tsx +167 -0
- package/src/Switch/SwitchContext.ts +10 -0
- package/src/Switch/__tests__/Switch.asChild.test.tsx +56 -0
- package/src/Switch/__tests__/Switch.basic-rendering.test.tsx +76 -0
- package/src/Switch/__tests__/Switch.contract.test.tsx +109 -0
- package/src/Switch/__tests__/Switch.controlled-state.test.tsx +79 -0
- package/src/Switch/__tests__/Switch.disabled.test.tsx +60 -0
- package/src/Switch/__tests__/Switch.error-handling.test.tsx +20 -0
- package/src/Switch/__tests__/Switch.keyboard-interaction.test.tsx +56 -0
- package/src/Switch/__tests__/Switch.thumb.test.tsx +84 -0
- package/src/Switch/__tests__/Switch.uncontrolled-state.test.tsx +83 -0
- package/src/Switch/hooks/index.ts +2 -0
- package/src/Switch/hooks/useSwitchContext.ts +1 -0
- package/src/Switch/hooks/useSwitchRoot.ts +28 -0
- package/src/Switch/index.ts +3 -0
- package/src/Switch/types.ts +37 -0
- package/src/Table/README.md +205 -0
- package/src/Table/Table.tsx +380 -0
- package/src/Table/__tests__/Table.Body.test.tsx +61 -0
- package/src/Table/__tests__/Table.Caption.test.tsx +70 -0
- package/src/Table/__tests__/Table.Cell.test.tsx +73 -0
- package/src/Table/__tests__/Table.Footer.test.tsx +61 -0
- package/src/Table/__tests__/Table.Head.test.tsx +61 -0
- package/src/Table/__tests__/Table.Header.test.tsx +73 -0
- package/src/Table/__tests__/Table.Root.test.tsx +49 -0
- package/src/Table/__tests__/Table.Row.test.tsx +67 -0
- package/src/Table/__tests__/Table.ScrollArea.test.tsx +83 -0
- package/src/Table/index.ts +1 -0
- package/src/Table/types.ts +63 -0
- package/src/Tabs/README.md +110 -0
- package/src/Tabs/Tabs.tsx +434 -0
- package/src/Tabs/TabsContext.ts +13 -0
- package/src/Tabs/__tests__/Tabs.activation-mode.test.tsx +114 -0
- package/src/Tabs/__tests__/Tabs.asChild.test.tsx +91 -0
- package/src/Tabs/__tests__/Tabs.basic-rendering.test.tsx +483 -0
- package/src/Tabs/__tests__/Tabs.change-event-callbacks.test.tsx +133 -0
- package/src/Tabs/__tests__/Tabs.controlled-state.test.tsx +152 -0
- package/src/Tabs/__tests__/Tabs.disabled-tabs.test.tsx +203 -0
- package/src/Tabs/__tests__/Tabs.error-handling.test.tsx +82 -0
- package/src/Tabs/__tests__/Tabs.fixtures.ts +171 -0
- package/src/Tabs/__tests__/Tabs.imperative-api.test.tsx +118 -0
- package/src/Tabs/__tests__/Tabs.keyboard-interaction.test.tsx +192 -0
- package/src/Tabs/__tests__/Tabs.lazy-mount.test.tsx +61 -0
- package/src/Tabs/__tests__/Tabs.mouse-interaction.test.tsx +216 -0
- package/src/Tabs/__tests__/Tabs.reading-direction.test.tsx +58 -0
- package/src/Tabs/__tests__/Tabs.uncontrolled-state.test.tsx +197 -0
- package/src/Tabs/hooks/index.ts +4 -0
- package/src/Tabs/hooks/useTabsContent.ts +27 -0
- package/src/Tabs/hooks/useTabsContext.ts +1 -0
- package/src/Tabs/hooks/useTabsRoot.ts +148 -0
- package/src/Tabs/hooks/useTabsTrigger.ts +111 -0
- package/src/Tabs/index.ts +3 -0
- package/src/Tabs/types.ts +99 -0
- package/src/Tabs/utils.ts +8 -0
- package/src/Textarea/README.md +98 -0
- package/src/Textarea/Textarea.tsx +93 -0
- package/src/Textarea/__tests__/Textarea.asChild.test.tsx +85 -0
- package/src/Textarea/__tests__/Textarea.basic-rendering.test.tsx +107 -0
- package/src/Textarea/__tests__/Textarea.disabled.test.tsx +49 -0
- package/src/Textarea/__tests__/Textarea.field-integration.test.tsx +134 -0
- package/src/Textarea/index.ts +2 -0
- package/src/Textarea/types.ts +7 -0
- package/src/Toggle/README.md +97 -0
- package/src/Toggle/Toggle.tsx +81 -0
- package/src/Toggle/__tests__/Toggle.asChild.test.tsx +42 -0
- package/src/Toggle/__tests__/Toggle.basic-rendering.test.tsx +28 -0
- package/src/Toggle/__tests__/Toggle.controlled-state.test.tsx +60 -0
- package/src/Toggle/__tests__/Toggle.disabled.test.tsx +34 -0
- package/src/Toggle/__tests__/Toggle.keyboard-interaction.test.tsx +42 -0
- package/src/Toggle/__tests__/Toggle.uncontrolled-state.test.tsx +40 -0
- package/src/Toggle/index.ts +2 -0
- package/src/Toggle/types.ts +23 -0
- package/src/ToggleGroup/README.md +137 -0
- package/src/ToggleGroup/ToggleGroup.tsx +298 -0
- package/src/ToggleGroup/ToggleGroupContext.ts +9 -0
- package/src/ToggleGroup/__tests__/ToggleGroup.asChild.test.tsx +65 -0
- package/src/ToggleGroup/__tests__/ToggleGroup.basic-rendering.test.tsx +50 -0
- package/src/ToggleGroup/__tests__/ToggleGroup.disabled.test.tsx +54 -0
- package/src/ToggleGroup/__tests__/ToggleGroup.keyboard-interaction.test.tsx +151 -0
- package/src/ToggleGroup/__tests__/ToggleGroup.multiple-mode.test.tsx +144 -0
- package/src/ToggleGroup/__tests__/ToggleGroup.reading-direction.test.tsx +28 -0
- package/src/ToggleGroup/__tests__/ToggleGroup.single-mode.test.tsx +139 -0
- package/src/ToggleGroup/hooks/index.ts +2 -0
- package/src/ToggleGroup/hooks/useToggleGroupContext.ts +1 -0
- package/src/ToggleGroup/hooks/useToggleGroupRoot.ts +110 -0
- package/src/ToggleGroup/index.ts +2 -0
- package/src/ToggleGroup/types.ts +72 -0
- package/src/Tooltip/README.md +214 -0
- package/src/Tooltip/Tooltip.tsx +260 -0
- package/src/Tooltip/TooltipContext.ts +20 -0
- package/src/Tooltip/__tests__/Tooltip.asChild.test.tsx +77 -0
- package/src/Tooltip/__tests__/Tooltip.basic-rendering.test.tsx +180 -0
- package/src/Tooltip/__tests__/Tooltip.controlled-state.test.tsx +128 -0
- package/src/Tooltip/__tests__/Tooltip.escape-hatches.test.tsx +73 -0
- package/src/Tooltip/__tests__/Tooltip.focus-interaction.test.tsx +88 -0
- package/src/Tooltip/__tests__/Tooltip.hover-interaction.test.tsx +179 -0
- package/src/Tooltip/__tests__/Tooltip.keyboard-interaction.test.tsx +85 -0
- package/src/Tooltip/__tests__/Tooltip.uncontrolled-state.test.tsx +67 -0
- package/src/Tooltip/hooks/index.ts +4 -0
- package/src/Tooltip/hooks/useTooltipContent.ts +53 -0
- package/src/Tooltip/hooks/useTooltipProvider.ts +41 -0
- package/src/Tooltip/hooks/useTooltipRoot.ts +106 -0
- package/src/Tooltip/hooks/useTooltipTrigger.ts +44 -0
- package/src/Tooltip/index.ts +1 -0
- package/src/Tooltip/types.ts +64 -0
- package/src/Tree/README.md +339 -0
- package/src/Tree/Tree.tsx +571 -0
- package/src/Tree/TreeContext.ts +24 -0
- package/src/Tree/__tests__/Tree.aria.test.tsx +53 -0
- package/src/Tree/__tests__/Tree.asChild.test.tsx +134 -0
- package/src/Tree/__tests__/Tree.basic-rendering.test.tsx +111 -0
- package/src/Tree/__tests__/Tree.branch-behaviour.test.tsx +87 -0
- package/src/Tree/__tests__/Tree.controlled-expansion.test.tsx +92 -0
- package/src/Tree/__tests__/Tree.data-attributes.test.tsx +88 -0
- package/src/Tree/__tests__/Tree.disabled-items.test.tsx +196 -0
- package/src/Tree/__tests__/Tree.error-handling.test.tsx +71 -0
- package/src/Tree/__tests__/Tree.forceMount.test.tsx +72 -0
- package/src/Tree/__tests__/Tree.keyboard-interaction.test.tsx +150 -0
- package/src/Tree/__tests__/Tree.multiple-selection.test.tsx +151 -0
- package/src/Tree/__tests__/Tree.range-selection.test.tsx +200 -0
- package/src/Tree/__tests__/Tree.recursion-depth.test.tsx +73 -0
- package/src/Tree/__tests__/Tree.roving-tabindex.test.tsx +117 -0
- package/src/Tree/__tests__/Tree.selection-path.test.tsx +404 -0
- package/src/Tree/__tests__/Tree.single-selection.test.tsx +108 -0
- package/src/Tree/__tests__/Tree.uncontrolled-expansion.test.tsx +69 -0
- package/src/Tree/hooks/index.ts +3 -0
- package/src/Tree/hooks/useTreeItemKeyboard.ts +86 -0
- package/src/Tree/hooks/useTreePath.ts +68 -0
- package/src/Tree/hooks/useTreeRoot.ts +279 -0
- package/src/Tree/index.ts +3 -0
- package/src/Tree/types.ts +224 -0
- package/src/Tree/utils.ts +59 -0
- package/src/VisuallyHidden/README.md +58 -0
- package/src/VisuallyHidden/VisuallyHidden.tsx +67 -0
- package/src/VisuallyHidden/__tests__/VisuallyHidden.test.tsx +59 -0
- package/src/VisuallyHidden/index.ts +2 -0
- package/src/VisuallyHidden/types.ts +5 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useCollection.ts +74 -0
- package/src/hooks/useControllableState.ts +81 -0
- package/src/hooks/useRovingTabindex.ts +178 -0
- package/src/index.ts +38 -0
- package/src/test/intersectionObserverPolyfill.ts +83 -0
- package/src/test/popoverPolyfill.ts +86 -0
- package/src/test/scrollPolyfill.ts +23 -0
- package/src/types.ts +13 -0
- package/src/utils/__tests__/createStrictContext.test.tsx +69 -0
- package/src/utils/__tests__/deriveId.test.ts +28 -0
- package/src/utils/__tests__/getKeyToActionMap.test.ts +106 -0
- package/src/utils/createStrictContext.ts +49 -0
- package/src/utils/deriveId.ts +31 -0
- package/src/utils/getKeyToActionMap.ts +95 -0
- package/src/utils/index.ts +3 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Table
|
|
2
|
+
|
|
3
|
+
A compound component wrapping standard HTML table elements. Follows the
|
|
4
|
+
[WAI-ARIA table pattern](https://www.w3.org/WAI/ARIA/apg/patterns/table/)
|
|
5
|
+
with zero styles shipped.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Table } from "@primitiv-ui/react";
|
|
9
|
+
|
|
10
|
+
<Table.ScrollArea>
|
|
11
|
+
<Table.Root>
|
|
12
|
+
<Table.Caption>Team members</Table.Caption>
|
|
13
|
+
<Table.Head>
|
|
14
|
+
<Table.Row>
|
|
15
|
+
<Table.Header scope="col">Name</Table.Header>
|
|
16
|
+
<Table.Header scope="col">Role</Table.Header>
|
|
17
|
+
<Table.Header scope="col">Location</Table.Header>
|
|
18
|
+
</Table.Row>
|
|
19
|
+
</Table.Head>
|
|
20
|
+
<Table.Body>
|
|
21
|
+
<Table.Row>
|
|
22
|
+
<Table.Cell>Alice</Table.Cell>
|
|
23
|
+
<Table.Cell>Engineer</Table.Cell>
|
|
24
|
+
<Table.Cell>London</Table.Cell>
|
|
25
|
+
</Table.Row>
|
|
26
|
+
<Table.Row>
|
|
27
|
+
<Table.Cell>Bob</Table.Cell>
|
|
28
|
+
<Table.Cell>Designer</Table.Cell>
|
|
29
|
+
<Table.Cell>Berlin</Table.Cell>
|
|
30
|
+
</Table.Row>
|
|
31
|
+
</Table.Body>
|
|
32
|
+
<Table.Footer>
|
|
33
|
+
<Table.Row>
|
|
34
|
+
<Table.Cell colSpan={3}>2 team members</Table.Cell>
|
|
35
|
+
</Table.Row>
|
|
36
|
+
</Table.Footer>
|
|
37
|
+
</Table.Root>
|
|
38
|
+
</Table.ScrollArea>;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Sub-components
|
|
42
|
+
|
|
43
|
+
| Export | Renders | Notes |
|
|
44
|
+
| ------------------ | ----------- | ------------------------------------------------------------------------------------------- |
|
|
45
|
+
| `Table.Root` | `<table>` | Implicit `role="table"`. Accepts all `TableHTMLAttributes`. |
|
|
46
|
+
| `Table.Head` | `<thead>` | Groups header rows. Browsers may repeat on printed pages. |
|
|
47
|
+
| `Table.Body` | `<tbody>` | Groups data rows. Multiple `<tbody>` elements are valid. |
|
|
48
|
+
| `Table.Footer` | `<tfoot>` | Groups footer/summary rows. Browsers may repeat on printed pages. |
|
|
49
|
+
| `Table.Row` | `<tr>` | Individual row. May contain `Table.Header` or `Table.Cell` children. |
|
|
50
|
+
| `Table.Header` | `<th>` | Header cell. Set `scope` for accessibility — see [Accessible headers](#accessible-headers). |
|
|
51
|
+
| `Table.Cell` | `<td>` | Data cell. Accepts `colSpan` and `rowSpan`. |
|
|
52
|
+
| `Table.ScrollArea` | `<div>` | Horizontal-scroll wrapper — see [Responsive scrolling](#responsive-scrolling). |
|
|
53
|
+
| `Table.Caption` | `<caption>` | Visible table label — see [Caption](#caption). |
|
|
54
|
+
|
|
55
|
+
## Accessible headers
|
|
56
|
+
|
|
57
|
+
The `scope` attribute on `Table.Header` tells assistive technology which data
|
|
58
|
+
cells a header describes. Always set it — without `scope`, screen readers may
|
|
59
|
+
struggle to announce the correct header for each cell.
|
|
60
|
+
|
|
61
|
+
| Value | Associates header with |
|
|
62
|
+
| ------------ | ---------------------------------------------------- |
|
|
63
|
+
| `"col"` | All cells in the same column |
|
|
64
|
+
| `"row"` | All cells in the same row |
|
|
65
|
+
| `"colgroup"` | All cells in the column group spanned by this header |
|
|
66
|
+
| `"rowgroup"` | All cells in the row group spanned by this header |
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<Table.Head>
|
|
70
|
+
<Table.Row>
|
|
71
|
+
<Table.Header scope="col">Name</Table.Header>
|
|
72
|
+
<Table.Header scope="col">Role</Table.Header>
|
|
73
|
+
</Table.Row>
|
|
74
|
+
</Table.Head>
|
|
75
|
+
<Table.Body>
|
|
76
|
+
<Table.Row>
|
|
77
|
+
{/* Row header for each data row */}
|
|
78
|
+
<Table.Header scope="row">Alice</Table.Header>
|
|
79
|
+
<Table.Cell>Engineer</Table.Cell>
|
|
80
|
+
</Table.Row>
|
|
81
|
+
</Table.Body>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Caption
|
|
85
|
+
|
|
86
|
+
A `Table.Caption` is the preferred way to give a table an accessible name.
|
|
87
|
+
The browser programmatically associates `<caption>` with the `<table>`, so
|
|
88
|
+
assistive technology announces it when the user enters the table — no
|
|
89
|
+
`aria-label` on `Table.Root` is needed.
|
|
90
|
+
|
|
91
|
+
**`captionSide` prop.** Controls whether the caption appears above or below
|
|
92
|
+
the table via the CSS `caption-side` property. Defaults to `"bottom"`.
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
{
|
|
96
|
+
/* Caption below table (default) */
|
|
97
|
+
}
|
|
98
|
+
<Table.Root>
|
|
99
|
+
<Table.Caption>Q1 sales by region</Table.Caption>…
|
|
100
|
+
</Table.Root>;
|
|
101
|
+
|
|
102
|
+
{
|
|
103
|
+
/* Caption above table */
|
|
104
|
+
}
|
|
105
|
+
<Table.Root>
|
|
106
|
+
<Table.Caption captionSide="top">Q1 sales by region</Table.Caption>…
|
|
107
|
+
</Table.Root>;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
When a visible caption is not desirable, use `aria-label` directly on
|
|
111
|
+
`Table.Root` instead:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
<Table.Root aria-label="Q1 sales by region">…</Table.Root>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Responsive scrolling
|
|
118
|
+
|
|
119
|
+
Wrap `Table.Root` in `Table.ScrollArea` to allow horizontal scrolling on
|
|
120
|
+
narrow viewports instead of overflowing or compressing columns.
|
|
121
|
+
|
|
122
|
+
`Table.ScrollArea` applies `display: block`, `overflow-x: auto`, and
|
|
123
|
+
`max-width: 100%` as inline styles.
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
<Table.ScrollArea>
|
|
127
|
+
<Table.Root>…</Table.Root>
|
|
128
|
+
</Table.ScrollArea>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Any `style` properties you pass are merged with (and take priority over) the
|
|
132
|
+
base scroll styles, so you can layer additional styles freely:
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
<Table.ScrollArea style={{ borderRadius: "8px" }}>
|
|
136
|
+
<Table.Root>…</Table.Root>
|
|
137
|
+
</Table.ScrollArea>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Multiple `<tbody>` groups
|
|
141
|
+
|
|
142
|
+
Multiple `Table.Body` elements are valid HTML and useful for visually
|
|
143
|
+
separating logical row groups within a single table:
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
<Table.Root>
|
|
147
|
+
<Table.Head>…</Table.Head>
|
|
148
|
+
<Table.Body>
|
|
149
|
+
{/* Group 1 */}
|
|
150
|
+
<Table.Row>…</Table.Row>
|
|
151
|
+
</Table.Body>
|
|
152
|
+
<Table.Body>
|
|
153
|
+
{/* Group 2 */}
|
|
154
|
+
<Table.Row>…</Table.Row>
|
|
155
|
+
</Table.Body>
|
|
156
|
+
</Table.Root>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Spanning cells
|
|
160
|
+
|
|
161
|
+
`Table.Cell` and `Table.Header` accept `colSpan` and `rowSpan`:
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
<Table.Row>
|
|
165
|
+
<Table.Cell colSpan={3}>Spans three columns</Table.Cell>
|
|
166
|
+
</Table.Row>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Styling hooks
|
|
170
|
+
|
|
171
|
+
`Table` is a static layout component — it emits no `data-state` or
|
|
172
|
+
`data-orientation` attributes. Style it via element or attribute selectors
|
|
173
|
+
with whatever system you use:
|
|
174
|
+
|
|
175
|
+
```css
|
|
176
|
+
table {
|
|
177
|
+
border-collapse: collapse;
|
|
178
|
+
width: 100%;
|
|
179
|
+
}
|
|
180
|
+
th,
|
|
181
|
+
td {
|
|
182
|
+
padding: 0.5rem 1rem;
|
|
183
|
+
text-align: left;
|
|
184
|
+
}
|
|
185
|
+
thead {
|
|
186
|
+
background: #f9fafb;
|
|
187
|
+
}
|
|
188
|
+
tfoot {
|
|
189
|
+
font-weight: bold;
|
|
190
|
+
}
|
|
191
|
+
tr:nth-child(even) td {
|
|
192
|
+
background: #f3f4f6;
|
|
193
|
+
}
|
|
194
|
+
[scope="col"] {
|
|
195
|
+
font-weight: 600;
|
|
196
|
+
}
|
|
197
|
+
caption {
|
|
198
|
+
font-size: 0.875rem;
|
|
199
|
+
color: #6b7280;
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
[Back to @primitiv-ui/react](../../README.md)
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TableBodyProps,
|
|
3
|
+
TableCaptionProps,
|
|
4
|
+
TableCellProps,
|
|
5
|
+
TableFooterProps,
|
|
6
|
+
TableHeaderProps,
|
|
7
|
+
TableHeadProps,
|
|
8
|
+
TableRootProps,
|
|
9
|
+
TableRowProps,
|
|
10
|
+
TableScrollAreaProps,
|
|
11
|
+
} from "./types";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The root of a Table widget — renders a plain `<table>` element and passes
|
|
15
|
+
* all `TableHTMLAttributes` through to the DOM.
|
|
16
|
+
*
|
|
17
|
+
* The `<table>` element carries an implicit `role="table"` in the accessibility
|
|
18
|
+
* tree. Assistive technology will announce it as a table and report the number
|
|
19
|
+
* of rows and columns to the user.
|
|
20
|
+
*
|
|
21
|
+
* Always pair column headers (`Table.Header`) with the correct
|
|
22
|
+
* {@link TableHeaderProps.scope | `scope`} attribute so screen readers can
|
|
23
|
+
* associate data cells with their headers.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <Table.Root>
|
|
28
|
+
* <Table.Head>
|
|
29
|
+
* <Table.Row>
|
|
30
|
+
* <Table.Header scope="col">Name</Table.Header>
|
|
31
|
+
* <Table.Header scope="col">Role</Table.Header>
|
|
32
|
+
* </Table.Row>
|
|
33
|
+
* </Table.Head>
|
|
34
|
+
* <Table.Body>
|
|
35
|
+
* <Table.Row>
|
|
36
|
+
* <Table.Cell>Alice</Table.Cell>
|
|
37
|
+
* <Table.Cell>Engineer</Table.Cell>
|
|
38
|
+
* </Table.Row>
|
|
39
|
+
* </Table.Body>
|
|
40
|
+
* </Table.Root>
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
function Table({ children, ...rest }: TableRootProps) {
|
|
44
|
+
return <table {...rest}>{children}</table>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Table.displayName = "Table";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Groups header rows inside a `<thead>` element.
|
|
51
|
+
*
|
|
52
|
+
* Browsers and assistive technology treat rows inside `<thead>` as column
|
|
53
|
+
* headers. When a table is printed across multiple pages, the browser may
|
|
54
|
+
* repeat the `<thead>` content at the top of each page.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```tsx
|
|
58
|
+
* <Table.Head>
|
|
59
|
+
* <Table.Row>
|
|
60
|
+
* <Table.Header scope="col">Name</Table.Header>
|
|
61
|
+
* <Table.Header scope="col">Email</Table.Header>
|
|
62
|
+
* </Table.Row>
|
|
63
|
+
* </Table.Head>
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
function TableHead({ children, ...rest }: TableHeadProps) {
|
|
67
|
+
return <thead {...rest}>{children}</thead>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
TableHead.displayName = "TableHead";
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Groups data rows inside a `<tbody>` element.
|
|
74
|
+
*
|
|
75
|
+
* Using `<tbody>` explicitly improves accessibility and allows browsers to
|
|
76
|
+
* scroll the body independently of a fixed header. Multiple `<tbody>` elements
|
|
77
|
+
* are valid and useful for visually separating logical row groups within a
|
|
78
|
+
* single table.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <Table.Body>
|
|
83
|
+
* <Table.Row>
|
|
84
|
+
* <Table.Cell>Alice</Table.Cell>
|
|
85
|
+
* <Table.Cell>alice@example.com</Table.Cell>
|
|
86
|
+
* </Table.Row>
|
|
87
|
+
* </Table.Body>
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
function TableBody({ children, ...rest }: TableBodyProps) {
|
|
91
|
+
return <tbody {...rest}>{children}</tbody>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
TableBody.displayName = "TableBody";
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Groups footer rows inside a `<tfoot>` element.
|
|
98
|
+
*
|
|
99
|
+
* Typically used for summary rows — totals, averages, counts. When a table is
|
|
100
|
+
* printed across multiple pages some browsers repeat the `<tfoot>` content at
|
|
101
|
+
* the bottom of each page.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```tsx
|
|
105
|
+
* <Table.Footer>
|
|
106
|
+
* <Table.Row>
|
|
107
|
+
* <Table.Cell>Total</Table.Cell>
|
|
108
|
+
* <Table.Cell>£1,200</Table.Cell>
|
|
109
|
+
* </Table.Row>
|
|
110
|
+
* </Table.Footer>
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
function TableFooter({ children, ...rest }: TableFooterProps) {
|
|
114
|
+
return <tfoot {...rest}>{children}</tfoot>;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
TableFooter.displayName = "TableFooter";
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* An individual table row — renders a `<tr>` element.
|
|
121
|
+
*
|
|
122
|
+
* May contain `Table.Header` (`<th>`) or `Table.Cell` (`<td>`) children, or a
|
|
123
|
+
* mix of both when the row contains both header and data cells (e.g. the first
|
|
124
|
+
* column of each row is a row header).
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```tsx
|
|
128
|
+
* <Table.Row>
|
|
129
|
+
* <Table.Header scope="row">Alice</Table.Header>
|
|
130
|
+
* <Table.Cell>Engineer</Table.Cell>
|
|
131
|
+
* <Table.Cell>London</Table.Cell>
|
|
132
|
+
* </Table.Row>
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
function TableRow({ children, ...rest }: TableRowProps) {
|
|
136
|
+
return <tr {...rest}>{children}</tr>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
TableRow.displayName = "TableRow";
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A header cell — renders a `<th>` element with an implicit
|
|
143
|
+
* `role="columnheader"` or `role="rowheader"` depending on context.
|
|
144
|
+
*
|
|
145
|
+
* **`scope` prop.** The `scope` attribute is the primary accessibility
|
|
146
|
+
* contract for table headers. Set it so assistive technology knows which data
|
|
147
|
+
* cells this header describes:
|
|
148
|
+
*
|
|
149
|
+
* | Value | Associates header with |
|
|
150
|
+
* | ----- | ---------------------- |
|
|
151
|
+
* | `"col"` | All cells in the same column |
|
|
152
|
+
* | `"row"` | All cells in the same row |
|
|
153
|
+
* | `"colgroup"` | All cells in the column group spanned by this header |
|
|
154
|
+
* | `"rowgroup"` | All cells in the row group spanned by this header |
|
|
155
|
+
*
|
|
156
|
+
* All `ThHTMLAttributes` (including `colSpan`, `rowSpan`, `abbr`) pass
|
|
157
|
+
* through to the DOM.
|
|
158
|
+
*
|
|
159
|
+
* @example Column header
|
|
160
|
+
* ```tsx
|
|
161
|
+
* <Table.Header scope="col">Name</Table.Header>
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* @example Row header
|
|
165
|
+
* ```tsx
|
|
166
|
+
* <Table.Header scope="row">Alice</Table.Header>
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
function TableHeader({ children, ...rest }: TableHeaderProps) {
|
|
170
|
+
return <th {...rest}>{children}</th>;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
TableHeader.displayName = "TableHeader";
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* A data cell — renders a `<td>` element.
|
|
177
|
+
*
|
|
178
|
+
* All `TdHTMLAttributes` pass through to the DOM, including `colSpan` and
|
|
179
|
+
* `rowSpan` for spanning multiple columns or rows.
|
|
180
|
+
*
|
|
181
|
+
* @example Basic cell
|
|
182
|
+
* ```tsx
|
|
183
|
+
* <Table.Cell>alice@example.com</Table.Cell>
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @example Spanning two columns
|
|
187
|
+
* ```tsx
|
|
188
|
+
* <Table.Cell colSpan={2}>Full-width note</Table.Cell>
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
function TableCell({ children, ...rest }: TableCellProps) {
|
|
192
|
+
return <td {...rest}>{children}</td>;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
TableCell.displayName = "TableCell";
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* A horizontal-scroll wrapper for tables wider than their container.
|
|
199
|
+
*
|
|
200
|
+
* Renders a `<div>` with `display: block`, `overflow-x: auto`, and
|
|
201
|
+
* `max-width: 100%` applied as inline styles, then wraps a `Table.Root`
|
|
202
|
+
* inside it. Use this when your table has many columns and you want it to
|
|
203
|
+
* scroll horizontally on narrow viewports instead of overflowing or
|
|
204
|
+
* compressing.
|
|
205
|
+
*
|
|
206
|
+
* **Custom styles.** Any `style` properties you pass are merged with (and take priority
|
|
207
|
+
* over) the base scroll styles, so you can layer additional styles freely without
|
|
208
|
+
* repeating the scroll declarations:
|
|
209
|
+
*
|
|
210
|
+
* ```tsx
|
|
211
|
+
* <Table.ScrollArea style={{ borderRadius: "8px" }}>
|
|
212
|
+
* …
|
|
213
|
+
* </Table.ScrollArea>
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```tsx
|
|
218
|
+
* <Table.ScrollArea>
|
|
219
|
+
* <Table.Root>
|
|
220
|
+
* …
|
|
221
|
+
* </Table.Root>
|
|
222
|
+
* </Table.ScrollArea>
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
function TableScrollArea({ children, style, ...rest }: TableScrollAreaProps) {
|
|
226
|
+
return (
|
|
227
|
+
<div
|
|
228
|
+
style={{
|
|
229
|
+
display: "block",
|
|
230
|
+
overflowX: "auto",
|
|
231
|
+
maxWidth: "100%",
|
|
232
|
+
...style,
|
|
233
|
+
}}
|
|
234
|
+
{...rest}
|
|
235
|
+
>
|
|
236
|
+
{children}
|
|
237
|
+
</div>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
TableScrollArea.displayName = "TableScrollArea";
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* A visible caption for the table — renders a `<caption>` element.
|
|
245
|
+
*
|
|
246
|
+
* A visible `<caption>` is the preferred way to label a table for
|
|
247
|
+
* accessibility. It is programmatically associated with the `<table>` element
|
|
248
|
+
* by the browser, so assistive technology announces it when the user enters
|
|
249
|
+
* the table — no `aria-label` or `aria-labelledby` on the table itself is
|
|
250
|
+
* needed.
|
|
251
|
+
*
|
|
252
|
+
* **`captionSide` prop.** Controls whether the caption appears above or below
|
|
253
|
+
* the table via the CSS `caption-side` property. Defaults to `"bottom"`.
|
|
254
|
+
*
|
|
255
|
+
* | Value | Position |
|
|
256
|
+
* | ----- | -------- |
|
|
257
|
+
* | `"bottom"` (default) | Below the table |
|
|
258
|
+
* | `"top"` | Above the table |
|
|
259
|
+
*
|
|
260
|
+
* @example Default (caption below table)
|
|
261
|
+
* ```tsx
|
|
262
|
+
* <Table.Root>
|
|
263
|
+
* <Table.Caption>Q1 sales figures by region</Table.Caption>
|
|
264
|
+
* …
|
|
265
|
+
* </Table.Root>
|
|
266
|
+
* ```
|
|
267
|
+
*
|
|
268
|
+
* @example Caption above table
|
|
269
|
+
* ```tsx
|
|
270
|
+
* <Table.Root>
|
|
271
|
+
* <Table.Caption captionSide="top">Q1 sales figures by region</Table.Caption>
|
|
272
|
+
* …
|
|
273
|
+
* </Table.Root>
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
function TableCaption({
|
|
277
|
+
children,
|
|
278
|
+
captionSide = "bottom",
|
|
279
|
+
...rest
|
|
280
|
+
}: TableCaptionProps) {
|
|
281
|
+
return (
|
|
282
|
+
<caption style={{ captionSide }} {...rest}>
|
|
283
|
+
{children}
|
|
284
|
+
</caption>
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
TableCaption.displayName = "TableCaption";
|
|
289
|
+
|
|
290
|
+
type TableCompound = typeof Table & {
|
|
291
|
+
Root: typeof Table;
|
|
292
|
+
Head: typeof TableHead;
|
|
293
|
+
Body: typeof TableBody;
|
|
294
|
+
Footer: typeof TableFooter;
|
|
295
|
+
Row: typeof TableRow;
|
|
296
|
+
Header: typeof TableHeader;
|
|
297
|
+
Cell: typeof TableCell;
|
|
298
|
+
ScrollArea: typeof TableScrollArea;
|
|
299
|
+
Caption: typeof TableCaption;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const TableCompound: TableCompound = Object.assign(Table, {
|
|
303
|
+
Root: Table,
|
|
304
|
+
Head: TableHead,
|
|
305
|
+
Body: TableBody,
|
|
306
|
+
Footer: TableFooter,
|
|
307
|
+
Row: TableRow,
|
|
308
|
+
Header: TableHeader,
|
|
309
|
+
Cell: TableCell,
|
|
310
|
+
ScrollArea: TableScrollArea,
|
|
311
|
+
Caption: TableCaption,
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Headless, accessible **Table** — a compound component wrapping standard
|
|
316
|
+
* HTML table elements with zero styles.
|
|
317
|
+
*
|
|
318
|
+
* `Table` is both callable (it's an alias of {@link Table | `Table.Root`})
|
|
319
|
+
* and carries its sub-components as static properties. Prefer the namespaced
|
|
320
|
+
* form in application code for readability:
|
|
321
|
+
*
|
|
322
|
+
* - {@link Table | `Table.Root`} — `<table>`, implicit `role="table"`.
|
|
323
|
+
* - {@link TableHead | `Table.Head`} — `<thead>`, groups header rows.
|
|
324
|
+
* - {@link TableBody | `Table.Body`} — `<tbody>`, groups data rows.
|
|
325
|
+
* - {@link TableFooter | `Table.Footer`} — `<tfoot>`, groups footer/summary rows.
|
|
326
|
+
* - {@link TableRow | `Table.Row`} — `<tr>`, individual row.
|
|
327
|
+
* - {@link TableHeader | `Table.Header`} — `<th>`, header cell; use `scope` for accessibility.
|
|
328
|
+
* - {@link TableCell | `Table.Cell`} — `<td>`, data cell.
|
|
329
|
+
* - {@link TableScrollArea | `Table.ScrollArea`} — horizontal-scroll wrapper for wide tables.
|
|
330
|
+
* - {@link TableCaption | `Table.Caption`} — `<caption>`, visible accessible table label.
|
|
331
|
+
*
|
|
332
|
+
* @example Minimal usage
|
|
333
|
+
* ```tsx
|
|
334
|
+
* import { Table } from "@primitiv-ui/react";
|
|
335
|
+
*
|
|
336
|
+
* export function Demo() {
|
|
337
|
+
* return (
|
|
338
|
+
* <Table.Root>
|
|
339
|
+
* <Table.Caption>Team members</Table.Caption>
|
|
340
|
+
* <Table.Head>
|
|
341
|
+
* <Table.Row>
|
|
342
|
+
* <Table.Header scope="col">Name</Table.Header>
|
|
343
|
+
* <Table.Header scope="col">Role</Table.Header>
|
|
344
|
+
* </Table.Row>
|
|
345
|
+
* </Table.Head>
|
|
346
|
+
* <Table.Body>
|
|
347
|
+
* <Table.Row>
|
|
348
|
+
* <Table.Cell>Alice</Table.Cell>
|
|
349
|
+
* <Table.Cell>Engineer</Table.Cell>
|
|
350
|
+
* </Table.Row>
|
|
351
|
+
* </Table.Body>
|
|
352
|
+
* </Table.Root>
|
|
353
|
+
* );
|
|
354
|
+
* }
|
|
355
|
+
* ```
|
|
356
|
+
*
|
|
357
|
+
* @example Responsive — horizontal scroll on narrow viewports
|
|
358
|
+
* ```tsx
|
|
359
|
+
* <Table.ScrollArea>
|
|
360
|
+
* <Table.Root>…</Table.Root>
|
|
361
|
+
* </Table.ScrollArea>
|
|
362
|
+
* ```
|
|
363
|
+
*
|
|
364
|
+
* @example Styling with any system
|
|
365
|
+
* Because no styles ship with the component, target the rendered elements
|
|
366
|
+
* with whatever system you use (CSS, Tailwind, design tokens, etc.):
|
|
367
|
+
*
|
|
368
|
+
* ```css
|
|
369
|
+
* table { border-collapse: collapse; width: 100%; }
|
|
370
|
+
* th, td { padding: 0.5rem 1rem; border: 1px solid #e5e7eb; }
|
|
371
|
+
* thead { background: #f9fafb; }
|
|
372
|
+
* ```
|
|
373
|
+
*
|
|
374
|
+
* @see {@link TableHeader} for the `scope` attribute and its accessibility contract.
|
|
375
|
+
* @see {@link TableCaption} for caption placement and why it beats `aria-label`.
|
|
376
|
+
* @see {@link TableScrollArea} for the horizontal-scroll style caveat.
|
|
377
|
+
*/
|
|
378
|
+
TableCompound.displayName = "Table";
|
|
379
|
+
|
|
380
|
+
export { TableCompound as Table };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Table } from "..";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
|
|
4
|
+
describe("Table.Body rendering", () => {
|
|
5
|
+
it("should render tbody element", () => {
|
|
6
|
+
// Arrange
|
|
7
|
+
render(
|
|
8
|
+
<table>
|
|
9
|
+
<Table.Body />
|
|
10
|
+
</table>,
|
|
11
|
+
);
|
|
12
|
+
const tbody = screen.getByRole("rowgroup");
|
|
13
|
+
|
|
14
|
+
// Assert
|
|
15
|
+
expect(tbody).toBeVisible();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should render children correctly", () => {
|
|
19
|
+
// Arrange
|
|
20
|
+
render(
|
|
21
|
+
<table>
|
|
22
|
+
<Table.Body>
|
|
23
|
+
<tr>
|
|
24
|
+
<td>Example text</td>
|
|
25
|
+
</tr>
|
|
26
|
+
</Table.Body>
|
|
27
|
+
</table>,
|
|
28
|
+
);
|
|
29
|
+
const childElement = screen.getByText(/Example text/i);
|
|
30
|
+
|
|
31
|
+
// Assert
|
|
32
|
+
expect(childElement).toBeVisible();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should add className to tbody element", () => {
|
|
36
|
+
// Arrange
|
|
37
|
+
const testClass = "test-class";
|
|
38
|
+
render(
|
|
39
|
+
<table>
|
|
40
|
+
<Table.Body className={testClass} />
|
|
41
|
+
</table>,
|
|
42
|
+
);
|
|
43
|
+
const tbody = screen.getByRole("rowgroup");
|
|
44
|
+
|
|
45
|
+
// Assert
|
|
46
|
+
expect(tbody).toHaveClass(testClass);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("should apply correct HTML attributes to tbody element", () => {
|
|
50
|
+
// Arrange
|
|
51
|
+
render(
|
|
52
|
+
<table>
|
|
53
|
+
<Table.Body id="test" />
|
|
54
|
+
</table>,
|
|
55
|
+
);
|
|
56
|
+
const tbody = screen.getByRole("rowgroup");
|
|
57
|
+
|
|
58
|
+
// Assert
|
|
59
|
+
expect(tbody).toHaveAttribute("id", "test");
|
|
60
|
+
});
|
|
61
|
+
});
|