From b00716aab24baefdac05a5b5bf1115679928b3fb Mon Sep 17 00:00:00 2001 From: Dmytro Kirpa Date: Tue, 14 Apr 2026 17:02:45 +0200 Subject: [PATCH 01/12] feat(react-headless-components-preview): add more components and their stories --- .../react-headless-components-preview.api.md | 617 +++++++++++++++++- .../library/package.json | 25 +- .../library/src/Avatar.ts | 2 + .../library/src/Badge.ts | 2 + .../library/src/Breadcrumb.ts | 22 + .../library/src/Checkbox.ts | 2 + .../library/src/Field.ts | 2 + .../library/src/Input.ts | 2 + .../library/src/Link.ts | 2 + .../library/src/ProgressBar.ts | 2 + .../library/src/RadioGroup.ts | 16 + .../library/src/Rating.ts | 16 + .../library/src/SearchBox.ts | 2 + .../library/src/Select.ts | 2 + .../library/src/Skeleton.ts | 16 + .../library/src/Slider.ts | 2 + .../library/src/SpinButton.ts | 2 + .../library/src/Spinner.ts | 2 + .../library/src/Switch.ts | 2 + .../library/src/TabList.ts | 10 + .../library/src/Textarea.ts | 2 + .../components/Accordion/Accordion.types.ts | 13 +- .../AccordionItem/AccordionItem.types.ts | 13 +- .../AccordionItem/useAccordionItem.ts | 11 +- .../src/components/Accordion/useAccordion.ts | 11 +- .../src/components/Avatar/Avatar.test.tsx | 16 + .../library/src/components/Avatar/Avatar.tsx | 19 + .../src/components/Avatar/Avatar.types.ts | 16 + .../Avatar/__snapshots__/Avatar.test.tsx.snap | 14 + .../library/src/components/Avatar/index.ts | 4 + .../src/components/Avatar/renderAvatar.tsx | 6 + .../src/components/Avatar/useAvatar.ts | 16 + .../src/components/Badge/Badge.test.tsx | 16 + .../library/src/components/Badge/Badge.tsx | 19 + .../src/components/Badge/Badge.types.ts | 16 + .../Badge/__snapshots__/Badge.test.tsx.snap | 9 + .../library/src/components/Badge/index.ts | 4 + .../src/components/Badge/renderBadge.tsx | 6 + .../library/src/components/Badge/useBadge.ts | 16 + .../components/Breadcrumb/Breadcrumb.test.tsx | 16 + .../src/components/Breadcrumb/Breadcrumb.tsx | 20 + .../components/Breadcrumb/Breadcrumb.types.ts | 26 + .../BreadcrumbButton/BreadcrumbButton.tsx | 20 + .../BreadcrumbButton.types.ts | 27 + .../Breadcrumb/BreadcrumbButton/index.ts | 4 + .../renderBreadcrumbButton.ts | 12 + .../BreadcrumbButton/useBreadcrumbButton.ts | 25 + .../BreadcrumbDivider/BreadcrumbDivider.tsx | 19 + .../BreadcrumbDivider.types.ts | 20 + .../Breadcrumb/BreadcrumbDivider/index.ts | 4 + .../renderBreadcrumbDivider.ts | 6 + .../BreadcrumbDivider/useBreadcrumbDivider.ts | 19 + .../BreadcrumbItem/BreadcrumbItem.tsx | 19 + .../BreadcrumbItem/BreadcrumbItem.types.ts | 20 + .../Breadcrumb/BreadcrumbItem/index.ts | 4 + .../BreadcrumbItem/renderBreadcrumbItem.ts | 6 + .../BreadcrumbItem/useBreadcrumbItem.ts | 16 + .../__snapshots__/Breadcrumb.test.tsx.snap | 15 + .../src/components/Breadcrumb/index.ts | 13 + .../Breadcrumb/renderBreadcrumb.tsx | 6 + .../components/Breadcrumb/useBreadcrumb.ts | 33 + .../src/components/Button/Button.types.ts | 19 +- .../src/components/Button/useButton.ts | 13 +- .../src/components/Checkbox/Checkbox.test.tsx | 17 + .../src/components/Checkbox/Checkbox.tsx | 18 + .../src/components/Checkbox/Checkbox.types.ts | 17 + .../__snapshots__/Checkbox.test.tsx.snap | 21 + .../library/src/components/Checkbox/index.ts | 4 + .../components/Checkbox/renderCheckbox.tsx | 6 + .../src/components/Checkbox/useCheckbox.ts | 20 + .../src/components/Divider/Divider.types.ts | 9 +- .../src/components/Divider/useDivider.ts | 9 +- .../src/components/Field/Field.test.tsx | 16 + .../library/src/components/Field/Field.tsx | 20 + .../src/components/Field/Field.types.ts | 26 + .../Field/__snapshots__/Field.test.tsx.snap | 9 + .../library/src/components/Field/index.ts | 4 + .../src/components/Field/renderField.tsx | 6 + .../library/src/components/Field/useField.ts | 16 + .../components/Field/useFieldContextValues.ts | 10 + .../src/components/Input/Input.test.tsx | 17 + .../library/src/components/Input/Input.tsx | 18 + .../src/components/Input/Input.types.ts | 16 + .../Input/__snapshots__/Input.test.tsx.snap | 13 + .../library/src/components/Input/index.ts | 4 + .../src/components/Input/renderInput.tsx | 6 + .../library/src/components/Input/useInput.ts | 16 + .../library/src/components/Label/Label.tsx | 18 + .../src/components/Label/Label.types.ts | 16 + .../library/src/components/Label/index.ts | 4 + .../src/components/Label/renderLabel.ts | 6 + .../library/src/components/Label/useLabel.ts | 16 + .../library/src/components/Link/Link.test.tsx | 16 + .../library/src/components/Link/Link.tsx | 19 + .../library/src/components/Link/Link.types.ts | 28 + .../Link/__snapshots__/Link.test.tsx.snap | 11 + .../library/src/components/Link/index.ts | 4 + .../src/components/Link/renderLink.tsx | 6 + .../library/src/components/Link/useLink.ts | 22 + .../ProgressBar/ProgressBar.test.tsx | 16 + .../components/ProgressBar/ProgressBar.tsx | 18 + .../ProgressBar/ProgressBar.types.ts | 17 + .../__snapshots__/ProgressBar.test.tsx.snap | 11 + .../src/components/ProgressBar/index.ts | 4 + .../ProgressBar/renderProgressBar.tsx | 9 + .../components/ProgressBar/useProgressBar.ts | 30 + .../src/components/RadioGroup/Radio/Radio.tsx | 17 + .../RadioGroup/Radio/Radio.types.ts | 16 + .../src/components/RadioGroup/Radio/index.ts | 4 + .../RadioGroup/Radio/renderRadio.tsx | 6 + .../components/RadioGroup/Radio/useRadio.ts | 16 + .../components/RadioGroup/RadioGroup.test.tsx | 16 + .../src/components/RadioGroup/RadioGroup.tsx | 21 + .../components/RadioGroup/RadioGroup.types.ts | 26 + .../__snapshots__/RadioGroup.test.tsx.snap | 11 + .../src/components/RadioGroup/index.ts | 7 + .../RadioGroup/renderRadioGroup.tsx | 6 + .../components/RadioGroup/useRadioGroup.ts | 16 + .../RadioGroup/useRadioGroupContextValues.ts | 8 + .../src/components/Rating/Rating.test.tsx | 25 + .../library/src/components/Rating/Rating.tsx | 21 + .../src/components/Rating/Rating.types.ts | 26 + .../Rating/RatingItem/RatingItem.tsx | 17 + .../Rating/RatingItem/RatingItem.types.ts | 20 + .../src/components/Rating/RatingItem/index.ts | 4 + .../Rating/RatingItem/renderRatingItem.tsx | 6 + .../Rating/RatingItem/useRatingItem.ts | 16 + .../Rating/__snapshots__/Rating.test.tsx.snap | 76 +++ .../library/src/components/Rating/index.ts | 7 + .../src/components/Rating/renderRating.tsx | 6 + .../src/components/Rating/useRating.tsx | 16 + .../Rating/useRatingContextValues.ts | 6 + .../src/components/SearchBox/Search.types.ts | 20 + .../components/SearchBox/SearchBox.test.tsx | 17 + .../src/components/SearchBox/SearchBox.tsx | 19 + .../__snapshots__/SearchBox.test.tsx.snap | 21 + .../library/src/components/SearchBox/index.ts | 4 + .../components/SearchBox/renderSearchBox.tsx | 6 + .../src/components/SearchBox/useSearchBox.ts | 16 + .../src/components/Select/Select.test.tsx | 23 + .../library/src/components/Select/Select.tsx | 19 + .../src/components/Select/Select.types.ts | 13 + .../Select/__snapshots__/Select.test.tsx.snap | 26 + .../library/src/components/Select/index.ts | 4 + .../src/components/Select/renderSelect.tsx | 6 + .../src/components/Select/useSelect.ts | 19 + .../src/components/Skeleton/Skeleton.test.tsx | 16 + .../src/components/Skeleton/Skeleton.tsx | 18 + .../src/components/Skeleton/Skeleton.types.ts | 26 + .../Skeleton/SkeletonItem/SkeletonItem.tsx | 17 + .../SkeletonItem/SkeletonItem.types.ts | 20 + .../components/Skeleton/SkeletonItem/index.ts | 4 + .../SkeletonItem/renderSkeletonItem.tsx | 6 + .../Skeleton/SkeletonItem/useSkeletonItem.ts | 16 + .../__snapshots__/Skeleton.test.tsx.snap | 12 + .../library/src/components/Skeleton/index.ts | 7 + .../components/Skeleton/renderSkeleton.tsx | 6 + .../src/components/Skeleton/useSkeleton.ts | 23 + .../src/components/Slider/Slider.test.tsx | 17 + .../library/src/components/Slider/Slider.tsx | 18 + .../src/components/Slider/Slider.types.ts | 16 + .../Slider/__snapshots__/Slider.test.tsx.snap | 17 + .../library/src/components/Slider/index.ts | 4 + .../src/components/Slider/renderSlider.tsx | 6 + .../src/components/Slider/useSlider.ts | 16 + .../components/SpinButton/SpinButton.test.tsx | 17 + .../src/components/SpinButton/SpinButton.tsx | 18 + .../components/SpinButton/SpinButton.types.ts | 20 + .../__snapshots__/SpinButton.test.tsx.snap | 27 + .../src/components/SpinButton/index.ts | 4 + .../SpinButton/renderSpinButton.tsx | 6 + .../components/SpinButton/useSpinButton.ts | 16 + .../src/components/Spinner/Spinner.test.tsx | 16 + .../src/components/Spinner/Spinner.tsx | 18 + .../src/components/Spinner/Spinner.types.ts | 16 + .../__snapshots__/Spinner.test.tsx.snap | 13 + .../library/src/components/Spinner/index.ts | 4 + .../src/components/Spinner/renderSpinner.tsx | 6 + .../src/components/Spinner/useSpinner.ts | 16 + .../src/components/Switch/Switch.test.tsx | 17 + .../library/src/components/Switch/Switch.tsx | 18 + .../src/components/Switch/Switch.types.ts | 16 + .../Switch/__snapshots__/Switch.test.tsx.snap | 22 + .../library/src/components/Switch/index.ts | 4 + .../src/components/Switch/renderSwitch.tsx | 6 + .../src/components/Switch/useSwitch.ts | 16 + .../src/components/TabList/Tab/Tab.tsx | 18 + .../src/components/TabList/Tab/Tab.types.ts | 13 + .../src/components/TabList/Tab/index.ts | 4 + .../src/components/TabList/Tab/renderTab.tsx | 6 + .../src/components/TabList/Tab/useTab.ts | 23 + .../src/components/TabList/TabList.test.tsx | 16 + .../src/components/TabList/TabList.tsx | 20 + .../src/components/TabList/TabList.types.ts | 30 + .../__snapshots__/TabList.test.tsx.snap | 13 + .../library/src/components/TabList/index.ts | 7 + .../src/components/TabList/renderTabList.tsx | 6 + .../src/components/TabList/useTabList.ts | 20 + .../TabList/useTabListContextValues.ts | 9 + .../src/components/Textarea/Textarea.test.tsx | 17 + .../src/components/Textarea/Textarea.tsx | 18 + .../src/components/Textarea/Textarea.types.ts | 20 + .../__snapshots__/Textarea.test.tsx.snap | 11 + .../library/src/components/Textarea/index.ts | 4 + .../components/Textarea/renderTextarea.tsx | 6 + .../src/components/Textarea/useTextarea.ts | 16 + .../library/src/index.ts | 107 +++ .../AccordionCollapsible.stories.tsx | 13 +- .../Accordion/AccordionDefault.stories.tsx | 10 +- .../src/Avatar/AvatarDefault.stories.tsx | 21 + .../stories/src/Avatar/AvatarDescription.md | 3 + .../stories/src/Avatar/index.stories.tsx | 17 + .../src/Badge/BadgeDefault.stories.tsx | 22 + .../stories/src/Badge/BadgeDescription.md | 3 + .../stories/src/Badge/index.stories.tsx | 17 + .../Breadcrumb/BreadcrumbDefault.stories.tsx | 40 ++ .../src/Breadcrumb/BreadcrumbDescription.md | 3 + .../stories/src/Breadcrumb/index.stories.tsx | 23 + .../src/Button/ButtonDefault.stories.tsx | 2 +- .../src/Checkbox/CheckboxDefault.stories.tsx | 16 + .../src/Checkbox/CheckboxDescription.md | 0 .../stories/src/Checkbox/index.stories.tsx | 17 + .../src/Field/FieldDefault.stories.tsx | 45 ++ .../stories/src/Field/FieldDescription.md | 3 + .../stories/src/Field/index.stories.tsx | 17 + .../src/Input/InputDefault.stories.tsx | 20 + .../stories/src/Input/InputDescription.md | 3 + .../stories/src/Input/index.stories.tsx | 17 + .../stories/src/Link/LinkDefault.stories.tsx | 29 + .../stories/src/Link/LinkDescription.md | 3 + .../stories/src/Link/index.stories.tsx | 17 + .../ProgressBarDefault.stories.tsx | 12 + .../src/ProgressBar/ProgressBarDescription.md | 5 + .../stories/src/ProgressBar/index.stories.tsx | 17 + .../RadioGroup/RadioGroupDefault.stories.tsx | 34 + .../src/RadioGroup/RadioGroupDescription.md | 3 + .../stories/src/RadioGroup/index.stories.tsx | 18 + .../src/Rating/RatingDefault.stories.tsx | 35 + .../stories/src/Rating/RatingDescription.md | 3 + .../stories/src/Rating/index.stories.tsx | 18 + .../SearchBox/SearchBoxDefault.stories.tsx | 14 + .../src/SearchBox/SearchBoxDescription.md | 3 + .../stories/src/SearchBox/index.stories.tsx | 17 + .../src/Select/SelectDefault.stories.tsx | 26 + .../stories/src/Select/SelectDescription.md | 3 + .../stories/src/Select/index.stories.tsx | 17 + .../src/Skeleton/SkeletonDefault.stories.tsx | 17 + .../src/Skeleton/SkeletonDescription.md | 3 + .../stories/src/Skeleton/index.stories.tsx | 18 + .../src/Slider/SliderDefault.stories.tsx | 23 + .../stories/src/Slider/SliderDescription.md | 3 + .../stories/src/Slider/index.stories.tsx | 17 + .../SpinButton/SpinButtonDefault.stories.tsx | 31 + .../src/SpinButton/SpinButtonDescription.md | 3 + .../stories/src/SpinButton/index.stories.tsx | 17 + .../src/Spinner/SpinnerDefault.stories.tsx | 12 + .../stories/src/Spinner/SpinnerDescription.md | 3 + .../src/Spinner/SpinnerLabels.stories.tsx | 14 + .../stories/src/Spinner/index.stories.tsx | 18 + .../src/Switch/SwitchDefault.stories.tsx | 19 + .../stories/src/Switch/SwitchDescription.md | 3 + .../stories/src/Switch/index.stories.tsx | 17 + .../src/TabList/TabListDefault.stories.tsx | 33 + .../stories/src/TabList/TabListDescription.md | 3 + .../stories/src/TabList/index.stories.tsx | 17 + .../src/Textarea/TextareaDefault.stories.tsx | 24 + .../src/Textarea/TextareaDescription.md | 3 + .../stories/src/Textarea/index.stories.tsx | 17 + .../react-tabs/library/etc/react-tabs.api.md | 6 + .../react-tabs/library/src/index.ts | 2 +- 270 files changed, 4384 insertions(+), 45 deletions(-) create mode 100644 packages/react-components/react-headless-components-preview/library/src/Avatar.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Badge.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Breadcrumb.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Checkbox.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Field.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Input.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Link.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/ProgressBar.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/RadioGroup.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Rating.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/SearchBox.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Select.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Skeleton.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Slider.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/SpinButton.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Spinner.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Switch.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/TabList.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/Textarea.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Avatar/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Avatar/renderAvatar.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Avatar/useAvatar.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Badge/__snapshots__/Badge.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Badge/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Badge/renderBadge.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Badge/useBadge.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/renderBreadcrumbButton.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/useBreadcrumbButton.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/renderBreadcrumbDivider.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/useBreadcrumbDivider.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/renderBreadcrumbItem.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/useBreadcrumbItem.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/renderBreadcrumb.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/useBreadcrumb.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Checkbox/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Checkbox/renderCheckbox.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Checkbox/useCheckbox.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/Field.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/Field.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/Field.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/__snapshots__/Field.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/renderField.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/useField.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Field/useFieldContextValues.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Input/Input.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Input/Input.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Input/Input.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Input/__snapshots__/Input.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Input/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Input/renderInput.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Input/useInput.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Label/Label.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Label/Label.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Label/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Label/renderLabel.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Label/useLabel.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Link/Link.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Link/Link.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Link/Link.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Link/__snapshots__/Link.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Link/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Link/renderLink.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Link/useLink.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/__snapshots__/ProgressBar.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/renderProgressBar.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/useProgressBar.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/renderRadio.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/useRadio.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/renderRadioGroup.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroup.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroupContextValues.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/renderRatingItem.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/useRatingItem.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/__snapshots__/Rating.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/renderRating.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/useRating.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Rating/useRatingContextValues.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SearchBox/Search.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SearchBox/__snapshots__/SearchBox.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SearchBox/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SearchBox/renderSearchBox.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SearchBox/useSearchBox.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Select/Select.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Select/Select.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Select/Select.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Select/__snapshots__/Select.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Select/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Select/renderSelect.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Select/useSelect.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/renderSkeletonItem.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/useSkeletonItem.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/__snapshots__/Skeleton.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/renderSkeleton.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Skeleton/useSkeleton.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Slider/__snapshots__/Slider.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Slider/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Slider/renderSlider.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Slider/useSlider.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SpinButton/__snapshots__/SpinButton.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SpinButton/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SpinButton/renderSpinButton.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/SpinButton/useSpinButton.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Spinner/__snapshots__/Spinner.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Spinner/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Spinner/renderSpinner.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Spinner/useSpinner.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Switch/__snapshots__/Switch.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Switch/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Switch/renderSwitch.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Switch/useSwitch.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/renderTab.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/useTab.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/__snapshots__/TabList.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/renderTabList.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabList.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabListContextValues.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Textarea/Textarea.test.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Textarea/Textarea.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Textarea/Textarea.types.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Textarea/__snapshots__/Textarea.test.tsx.snap create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Textarea/index.ts create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Textarea/renderTextarea.tsx create mode 100644 packages/react-components/react-headless-components-preview/library/src/components/Textarea/useTextarea.ts create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Avatar/AvatarDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Avatar/AvatarDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Avatar/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Badge/BadgeDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Badge/BadgeDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Badge/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Breadcrumb/BreadcrumbDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Breadcrumb/BreadcrumbDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Breadcrumb/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Checkbox/CheckboxDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Checkbox/CheckboxDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Checkbox/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Field/FieldDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Field/FieldDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Field/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Input/InputDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Input/InputDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Input/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Link/LinkDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Link/LinkDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Link/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/ProgressBar/ProgressBarDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/ProgressBar/ProgressBarDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/ProgressBar/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/RadioGroup/RadioGroupDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/RadioGroup/RadioGroupDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/RadioGroup/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Rating/RatingDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Rating/RatingDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Rating/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/SearchBox/SearchBoxDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/SearchBox/SearchBoxDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/SearchBox/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Select/SelectDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Select/SelectDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Select/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Skeleton/SkeletonDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Skeleton/SkeletonDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Skeleton/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Slider/SliderDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Slider/SliderDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Slider/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/SpinButton/SpinButtonDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/SpinButton/SpinButtonDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/SpinButton/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Spinner/SpinnerDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Spinner/SpinnerDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Spinner/SpinnerLabels.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Spinner/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Switch/SwitchDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Switch/SwitchDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Switch/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/TabList/TabListDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/TabList/TabListDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/TabList/index.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Textarea/TextareaDefault.stories.tsx create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Textarea/TextareaDescription.md create mode 100644 packages/react-components/react-headless-components-preview/stories/src/Textarea/index.stories.tsx diff --git a/packages/react-components/react-headless-components-preview/library/etc/react-headless-components-preview.api.md b/packages/react-components/react-headless-components-preview/library/etc/react-headless-components-preview.api.md index b20d9b2f1f00a..29ceea052fd09 100644 --- a/packages/react-components/react-headless-components-preview/library/etc/react-headless-components-preview.api.md +++ b/packages/react-components/react-headless-components-preview/library/etc/react-headless-components-preview.api.md @@ -20,16 +20,101 @@ import type { AccordionPanelBaseProps } from '@fluentui/react-accordion'; import type { AccordionPanelBaseState } from '@fluentui/react-accordion'; import type { AccordionPanelSlots as AccordionPanelSlots_2 } from '@fluentui/react-accordion'; import type { AccordionSlots as AccordionSlots_2 } from '@fluentui/react-accordion'; +import type { AvatarBaseProps } from '@fluentui/react-avatar'; +import { AvatarBaseState } from '@fluentui/react-avatar'; +import type { BadgeBaseProps } from '@fluentui/react-badge'; +import { BadgeBaseState } from '@fluentui/react-badge'; +import type { BreadcrumbBaseProps } from '@fluentui/react-breadcrumb'; +import { BreadcrumbBaseState } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbButtonBaseProps } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbButtonBaseState } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbButtonSlots as BreadcrumbButtonSlots_2 } from '@fluentui/react-breadcrumb'; +import { BreadcrumbContextValues as BreadcrumbContextValues_2 } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbDividerBaseProps } from '@fluentui/react-breadcrumb'; +import { BreadcrumbDividerBaseState } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbDividerSlots as BreadcrumbDividerSlots_2 } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbItemBaseProps } from '@fluentui/react-breadcrumb'; +import { BreadcrumbItemBaseState } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbItemSlots as BreadcrumbItemSlots_2 } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbSlots as BreadcrumbSlots_2 } from '@fluentui/react-breadcrumb'; import type { ButtonBaseProps } from '@fluentui/react-button'; import { ButtonBaseState } from '@fluentui/react-button'; import type { ButtonSlots as ButtonSlots_2 } from '@fluentui/react-button'; +import type { CheckboxBaseProps } from '@fluentui/react-checkbox'; +import { CheckboxBaseState } from '@fluentui/react-checkbox'; +import type { CheckboxSlots as CheckboxSlots_2 } from '@fluentui/react-checkbox'; +import { ComponentProps } from '@fluentui/react-utilities'; import { ContextSelector } from '@fluentui/react-context-selector'; import type { DividerBaseProps } from '@fluentui/react-divider'; import { DividerBaseState } from '@fluentui/react-divider'; import type { DividerSlots as DividerSlots_2 } from '@fluentui/react-divider'; +import type { FieldBaseProps } from '@fluentui/react-field'; +import { FieldBaseState } from '@fluentui/react-field'; +import { FieldContextValues } from '@fluentui/react-field'; +import type { FieldSlots as FieldSlots_2 } from '@fluentui/react-field'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { InputBaseProps } from '@fluentui/react-input'; +import { InputBaseState } from '@fluentui/react-input'; +import type { InputSlots as InputSlots_2 } from '@fluentui/react-input'; import { JSXElement } from '@fluentui/react-utilities'; -import type * as React_2 from 'react'; +import type { LinkBaseProps } from '@fluentui/react-link'; +import { LinkBaseState } from '@fluentui/react-link'; +import type { LinkSlots as LinkSlots_2 } from '@fluentui/react-link'; +import type { ProgressBarBaseProps } from '@fluentui/react-progress'; +import type { ProgressBarBaseState } from '@fluentui/react-progress'; +import type { ProgressBarSlots as ProgressBarSlots_2 } from '@fluentui/react-progress'; +import type { RadioBaseProps } from '@fluentui/react-radio'; +import { RadioBaseState } from '@fluentui/react-radio'; +import type { RadioGroupBaseProps } from '@fluentui/react-radio'; +import { RadioGroupBaseState } from '@fluentui/react-radio'; +import { RadioGroupContextValues } from '@fluentui/react-radio'; +import type { RadioGroupSlots as RadioGroupSlots_2 } from '@fluentui/react-radio'; +import { RadioOnChangeData } from '@fluentui/react-radio'; +import { RadioSlots as RadioSlots_2 } from '@fluentui/react-radio'; +import type { RatingBaseProps } from '@fluentui/react-rating'; +import { RatingBaseState } from '@fluentui/react-rating'; +import { RatingContextValues } from '@fluentui/react-rating'; +import type { RatingItemBaseProps } from '@fluentui/react-rating'; +import { RatingItemBaseState } from '@fluentui/react-rating'; +import { RatingItemSlots as RatingItemSlots_2 } from '@fluentui/react-rating'; +import type { RatingSlots as RatingSlots_2 } from '@fluentui/react-rating'; +import * as React_2 from 'react'; +import type { SearchBoxBaseProps } from '@fluentui/react-search'; +import { SearchBoxBaseState } from '@fluentui/react-search'; +import type { SearchBoxSlots as SearchBoxSlots_2 } from '@fluentui/react-search'; +import type { SelectBaseProps } from '@fluentui/react-select'; +import { SelectBaseState } from '@fluentui/react-select'; +import type { SelectSlots as SelectSlots_2 } from '@fluentui/react-select'; +import { SkeletonBaseProps } from '@fluentui/react-skeleton'; +import { SkeletonBaseState } from '@fluentui/react-skeleton'; +import { SkeletonContextValues } from '@fluentui/react-skeleton'; +import { SkeletonItemBaseProps } from '@fluentui/react-skeleton'; +import { SkeletonItemBaseState } from '@fluentui/react-skeleton'; +import type { SkeletonItemSlots as SkeletonItemSlots_2 } from '@fluentui/react-skeleton'; +import type { SkeletonSlots as SkeletonSlots_2 } from '@fluentui/react-skeleton'; +import type { SliderBaseProps } from '@fluentui/react-slider'; +import { SliderBaseState } from '@fluentui/react-slider'; +import type { SliderSlots as SliderSlots_2 } from '@fluentui/react-slider'; +import type { SpinButtonBaseProps } from '@fluentui/react-spinbutton'; +import { SpinButtonBaseState } from '@fluentui/react-spinbutton'; +import type { SpinButtonSlots as SpinButtonSlots_2 } from '@fluentui/react-spinbutton'; +import type { SpinnerBaseProps } from '@fluentui/react-spinner'; +import { SpinnerBaseState } from '@fluentui/react-spinner'; +import type { SpinnerSlots as SpinnerSlots_2 } from '@fluentui/react-spinner'; +import type { SwitchBaseProps } from '@fluentui/react-switch'; +import { SwitchBaseState } from '@fluentui/react-switch'; +import type { SwitchSlots as SwitchSlots_2 } from '@fluentui/react-switch'; +import type { TabBaseProps } from '@fluentui/react-tabs'; +import { TabBaseState } from '@fluentui/react-tabs'; +import type { TabListBaseProps } from '@fluentui/react-tabs'; +import { TabListBaseState } from '@fluentui/react-tabs'; +import { TabListContextValues } from '@fluentui/react-tabs'; +import type { TabListSlots as TabListSlots_2 } from '@fluentui/react-tabs'; +import { TabSlots } from '@fluentui/react-tabs'; +import { TabValue } from '@fluentui/react-tabs'; +import type { TextareaBaseProps } from '@fluentui/react-textarea'; +import { TextareaBaseState } from '@fluentui/react-textarea'; +import type { TextareaSlots as TextareaSlots_2 } from '@fluentui/react-textarea'; // @public export const Accordion: ForwardRefComponent; @@ -59,7 +144,12 @@ export type AccordionItemProps = AccordionItemProps_2; export type AccordionItemSlots = AccordionItemSlots_2; // @public (undocumented) -export type AccordionItemState = AccordionItemState_2; +export type AccordionItemState = AccordionItemState_2 & { + root: { + 'data-disabled'?: string; + 'data-open'?: string; + }; +}; // @public export const AccordionPanel: ForwardRefComponent; @@ -80,7 +170,85 @@ export type AccordionProps = AccordionBaseProps; export type AccordionSlots = AccordionSlots_2; // @public (undocumented) -export type AccordionState = AccordionBaseState; +export type AccordionState = AccordionBaseState & { + root: { + 'data-collapsible'?: string; + 'data-multiple'?: string; + }; +}; + +// @public +export const Avatar: ForwardRefComponent; + +// @public +export type AvatarProps = AvatarBaseProps; + +// @public +export type AvatarState = AvatarBaseState; + +// @public +export const Badge: ForwardRefComponent; + +// @public +export type BadgeProps = BadgeBaseProps; + +// @public +export type BadgeState = BadgeBaseState; + +// @public +export const Breadcrumb: ForwardRefComponent; + +// @public +export const BreadcrumbButton: ForwardRefComponent; + +// @public +export type BreadcrumbButtonProps = BreadcrumbButtonBaseProps; + +// @public +export type BreadcrumbButtonSlots = BreadcrumbButtonSlots_2; + +// @public +export type BreadcrumbButtonState = BreadcrumbButtonBaseState & { + root: { + 'data-current'?: string; + }; +}; + +// @public +export type BreadcrumbContextValues = BreadcrumbContextValues_2; + +// @public +export const BreadcrumbDivider: ForwardRefComponent; + +// @public +export type BreadcrumbDividerProps = BreadcrumbDividerBaseProps; + +// @public +export type BreadcrumbDividerSlots = BreadcrumbDividerSlots_2; + +// @public +export type BreadcrumbDividerState = BreadcrumbDividerBaseState; + +// @public +export const BreadcrumbItem: ForwardRefComponent; + +// @public +export type BreadcrumbItemProps = BreadcrumbItemBaseProps; + +// @public +export type BreadcrumbItemSlots = BreadcrumbItemSlots_2; + +// @public +export type BreadcrumbItemState = BreadcrumbItemBaseState; + +// @public +export type BreadcrumbProps = BreadcrumbBaseProps; + +// @public +export type BreadcrumbSlots = BreadcrumbSlots_2; + +// @public +export type BreadcrumbState = BreadcrumbBaseState; // @public export const Button: ForwardRefComponent; @@ -92,7 +260,25 @@ export type ButtonProps = ButtonBaseProps; export type ButtonSlots = ButtonSlots_2; // @public -export type ButtonState = ButtonBaseState; +export type ButtonState = ButtonBaseState & { + root: { + 'data-disabled'?: string; + 'data-disabled-focusable'?: string; + 'data-icon-only'?: string; + }; +}; + +// @public +export const Checkbox: ForwardRefComponent; + +// @public +export type CheckboxProps = CheckboxBaseProps; + +// @public (undocumented) +export type CheckboxSlots = CheckboxSlots_2; + +// @public +export type CheckboxState = CheckboxBaseState; // @public export const Divider: ForwardRefComponent; @@ -104,7 +290,123 @@ export type DividerProps = DividerBaseProps; export type DividerSlots = DividerSlots_2; // @public (undocumented) -export type DividerState = DividerBaseState; +export type DividerState = DividerBaseState & { + root: { + 'data-orientation'?: 'vertical' | 'horizontal'; + }; +}; + +// @public +export const Field: ForwardRefComponent; + +// @public +export type FieldProps = FieldBaseProps; + +// @public +export type FieldSlots = FieldSlots_2; + +// @public +export type FieldState = FieldBaseState; + +// @public +export const Input: ForwardRefComponent; + +// @public +export type InputProps = InputBaseProps; + +// @public +export type InputSlots = InputSlots_2; + +// @public +export type InputState = InputBaseState; + +// @public +export const Link: ForwardRefComponent; + +// @public +export type LinkProps = LinkBaseProps; + +// @public +export type LinkSlots = LinkSlots_2; + +// @public +export type LinkState = LinkBaseState & { + root: { + 'data-disabled'?: string; + 'data-disabled-focusable'?: string; + }; +}; + +// @public +export const ProgressBar: ForwardRefComponent; + +// @public +export type ProgressBarProps = ProgressBarBaseProps; + +// @public (undocumented) +export type ProgressBarSlots = ProgressBarSlots_2; + +// @public +export type ProgressBarState = ProgressBarBaseState; + +// @public +export const Radio: React_2.ForwardRefExoticComponent, "input">, "onChange" | "size"> & { + value?: string; + labelPosition?: "after" | "below"; + disabled?: boolean; + onChange?: (ev: React_2.ChangeEvent, data: RadioOnChangeData) => void; +} & React_2.RefAttributes>; + +// @public +export const RadioGroup: ForwardRefComponent; + +// @public +export type RadioGroupProps = RadioGroupBaseProps; + +// @public +export type RadioGroupSlots = RadioGroupSlots_2; + +// @public +export type RadioGroupState = RadioGroupBaseState; + +// @public +export type RadioProps = RadioBaseProps; + +// @public +export type RadioSlots = RadioSlots_2; + +// @public +export type RadioState = RadioBaseState; + +// @public +export const Rating: ForwardRefComponent; + +// @public +export const RatingItem: React_2.ForwardRefExoticComponent, "root"> & Omit<{ + as?: "span" | undefined; +} & Omit, HTMLSpanElement>, "children"> & { + children?: any; +}, "ref"> & { + value?: number; +} & React_2.RefAttributes>; + +// @public +export type RatingItemProps = RatingItemBaseProps; + +// @public +export type RatingItemSlots = RatingItemSlots_2; + +// @public +export type RatingItemState = RatingItemBaseState; + +// @public +export type RatingProps = RatingBaseProps; + +// @public +export type RatingSlots = RatingSlots_2; + +// @public +export type RatingState = RatingBaseState; // @public export const renderAccordion: (state: AccordionBaseState, contextValues: AccordionContextValues_2) => JSXElement; @@ -118,12 +420,233 @@ export const renderAccordionItem: (state: AccordionItemState_2, contextValues: A // @public export const renderAccordionPanel: (state: AccordionPanelState) => JSXElement; +// @public +export const renderAvatar: (state: AvatarBaseState) => JSXElement; + +// @public +export const renderBadge: (state: BadgeBaseState) => JSXElement; + +// @public +export const renderBreadcrumb: (state: BreadcrumbBaseState, contextValues: BreadcrumbContextValues_2) => JSXElement; + +// @public +export const renderBreadcrumbButton: (state: BreadcrumbButtonState) => JSXElement; + +// @public +export const renderBreadcrumbDivider: (state: BreadcrumbDividerBaseState) => JSXElement; + +// @public +export const renderBreadcrumbItem: (state: BreadcrumbItemBaseState) => JSXElement; + // @public export const renderButton: (state: ButtonBaseState) => JSXElement; +// @public +export const renderCheckbox: (state: CheckboxBaseState) => JSXElement; + // @public export const renderDivider: (state: DividerBaseState) => JSXElement; +// @public +export const renderField: (state: FieldBaseState, contextValues: FieldContextValues) => JSXElement; + +// @public +export const renderInput: (state: InputBaseState) => JSXElement; + +// @public +export const renderLink: (state: LinkBaseState) => JSXElement; + +// @public +export const renderProgressBar: (state: ProgressBarState) => JSXElement; + +// @public +export const renderRadio: (state: RadioBaseState) => JSXElement; + +// @public +export const renderRadioGroup: (state: RadioGroupBaseState, contextValues: RadioGroupContextValues) => JSXElement; + +// @public +export const renderRating: (state: RatingBaseState, contextValues: RatingContextValues) => JSXElement; + +// @public +export const renderRatingItem: (state: RatingItemBaseState) => JSXElement; + +// @public +export const renderSearchBox: (state: SearchBoxBaseState) => JSXElement; + +// @public +export const renderSelect: (state: SelectBaseState) => JSXElement; + +// @public +export const renderSkeleton: (state: SkeletonBaseState, contextValues: SkeletonContextValues) => JSXElement; + +// @public +export const renderSkeletonItem: (state: SkeletonItemBaseState) => JSXElement; + +// @public +export const renderSlider: (state: SliderBaseState) => JSXElement; + +// @public +export const renderSpinButton: (state: SpinButtonBaseState) => JSXElement; + +// @public +export const renderSpinner: (state: SpinnerBaseState) => JSXElement; + +// @public +export const renderSwitch: (state: SwitchBaseState) => JSXElement; + +// @public +export const renderTab: (state: TabBaseState) => JSXElement; + +// @public +export const renderTabList: (state: TabListBaseState, contextValues: TabListContextValues) => JSXElement; + +// @public +export const renderTextarea: (state: TextareaBaseState) => JSXElement; + +// @public +export const SearchBox: ForwardRefComponent; + +// @public +export type SearchBoxProps = SearchBoxBaseProps; + +// @public +export type SearchBoxSlots = SearchBoxSlots_2; + +// @public +export type SearchBoxState = SearchBoxBaseState; + +// @public +export const Select: ForwardRefComponent; + +// @public +export type SelectProps = SelectBaseProps; + +// @public (undocumented) +export type SelectSlots = SelectSlots_2; + +// @public +export type SelectState = SelectBaseState; + +// @public +export const Skeleton: React_2.ForwardRefExoticComponent>; + +// @public +export const SkeletonItem: React_2.ForwardRefExoticComponent>; + +// @public +export type SkeletonItemProps = SkeletonItemBaseProps; + +// @public +export type SkeletonItemSlots = SkeletonItemSlots_2; + +// @public +export type SkeletonItemState = SkeletonItemBaseState; + +// @public +export type SkeletonProps = SkeletonBaseProps; + +// @public +export type SkeletonSlots = SkeletonSlots_2; + +// @public +export type SkeletonState = SkeletonBaseState; + +// @public +export const Slider: ForwardRefComponent; + +// @public +export type SliderProps = SliderBaseProps; + +// @public +export type SliderSlots = SliderSlots_2; + +// @public +export type SliderState = SliderBaseState; + +// @public +export const SpinButton: ForwardRefComponent; + +// @public +export type SpinButtonProps = SpinButtonBaseProps; + +// @public +export type SpinButtonSlots = SpinButtonSlots_2; + +// @public +export type SpinButtonState = SpinButtonBaseState; + +// @public +export const Spinner: ForwardRefComponent; + +// @public +export type SpinnerProps = SpinnerBaseProps; + +// @public +export type SpinnerSlots = SpinnerSlots_2; + +// @public +export type SpinnerState = SpinnerBaseState; + +// @public +export const Switch: ForwardRefComponent; + +// @public +export type SwitchProps = SwitchBaseProps; + +// @public +export type SwitchSlots = SwitchSlots_2; + +// @public +export type SwitchState = SwitchBaseState; + +// @public +export const Tab: ForwardRefComponent; + +// @public +export const TabList: ForwardRefComponent; + +// @public +export type TabListProps = TabListBaseProps; + +// @public +export type TabListSlots = TabListSlots_2; + +// @public +export type TabListState = TabListBaseState & { + root: { + focusgroup?: string; + }; +}; + +// @public (undocumented) +export type TabProps = TabBaseProps; + +export { TabSlots } + +// @public (undocumented) +export type TabState = TabBaseState & { + root: { + focusgroupstart?: string; + 'data-icon-only'?: ''; + 'data-selected'?: ''; + }; +}; + +export { TabValue } + +// @public +export const Textarea: ForwardRefComponent; + +// @public +export type TextareaProps = TextareaBaseProps; + +// @public +export type TextareaSlots = TextareaSlots_2; + +// @public +export type TextareaState = TextareaBaseState; + // @public export const useAccordion: (props: AccordionProps, ref: React_2.Ref) => AccordionState; @@ -142,12 +665,96 @@ export const useAccordionItem: (props: AccordionItemProps, ref: React_2.Ref) => AccordionPanelState; +// @public +export const useAvatar: (props: AvatarProps, ref: React_2.Ref) => AvatarState; + +// @public +export const useBadge: (props: BadgeProps, ref: React_2.Ref) => BadgeState; + +// @public +export const useBreadcrumb: (props: BreadcrumbProps, ref: React_2.Ref) => BreadcrumbState; + +// @public +export const useBreadcrumbButton: (props: BreadcrumbButtonProps, ref: React_2.Ref) => BreadcrumbButtonState; + +// @public +export const useBreadcrumbContext: () => BreadcrumbContextValues_2; + +// @public +export const useBreadcrumbContextValues: (state: BreadcrumbState) => BreadcrumbContextValues; + +// @public +export const useBreadcrumbDivider: (props: BreadcrumbDividerProps, ref: React_2.Ref) => BreadcrumbDividerState; + +// @public +export const useBreadcrumbItem: (props: BreadcrumbItemProps, ref: React_2.Ref) => BreadcrumbItemState; + // @public export const useButton: (props: ButtonProps, ref: React_2.Ref) => ButtonState; +// @public +export const useCheckbox: (props: CheckboxProps, ref: React_2.Ref) => CheckboxState; + // @public export const useDivider: (props: DividerProps, ref: React_2.Ref) => DividerState; +// @public +export const useField: (props: FieldProps, ref: React_2.Ref) => FieldState; + +// @public +export const useInput: (props: InputProps, ref: React_2.Ref) => InputState; + +// @public +export const useLink: (props: LinkProps, ref: React_2.Ref) => LinkState; + +// @public +export const useProgressBar: (props: ProgressBarProps, ref: React_2.Ref) => ProgressBarState; + +// @public +export const useRadio: (props: RadioProps, ref: React_2.Ref) => RadioState; + +// @public +export const useRadioGroup: (props: RadioGroupProps, ref: React_2.Ref) => RadioGroupState; + +// @public +export const useRating: (props: RatingProps, ref: React_2.Ref) => RatingState; + +// @public +export const useRatingItem: (props: RatingItemProps, ref: React_2.Ref) => RatingItemState; + +// @public +export const useSearchBox: (props: SearchBoxProps, ref: React_2.Ref) => SearchBoxState; + +// @public +export const useSelect: (props: SelectProps, ref: React_2.Ref) => SelectState; + +// @public +export const useSkeleton: (props: SkeletonProps, ref: React_2.Ref) => SkeletonState; + +// @public +export const useSkeletonItem: (props: SkeletonItemProps, ref: React_2.Ref) => SkeletonItemState; + +// @public +export const useSlider: (props: SliderProps, ref: React_2.Ref) => SliderState; + +// @public +export const useSpinButton: (props: SpinButtonProps, ref: React_2.Ref) => SpinButtonState; + +// @public +export const useSpinner: (props: SpinnerProps, ref: React_2.Ref) => SpinnerState; + +// @public +export const useSwitch: (props: SwitchProps, ref: React_2.Ref) => SwitchState; + +// @public +export const useTab: (props: TabProps, ref: React_2.Ref) => TabState; + +// @public +export const useTabList: (props: TabListProps, ref: React_2.Ref) => TabListState; + +// @public +export const useTextarea: (props: TextareaProps, ref: React_2.Ref) => TextareaState; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/react-components/react-headless-components-preview/library/package.json b/packages/react-components/react-headless-components-preview/library/package.json index 5de707fdcb733..c0c8e93077262 100644 --- a/packages/react-components/react-headless-components-preview/library/package.json +++ b/packages/react-components/react-headless-components-preview/library/package.json @@ -20,10 +20,33 @@ "license": "MIT", "dependencies": { "@fluentui/react-accordion": "^9.10.0", + "@fluentui/react-avatar": "^9.10.4", + "@fluentui/react-badge": "^9.5.1", "@fluentui/react-button": "^9.9.0", + "@fluentui/react-breadcrumb": "^9.4.0", + "@fluentui/react-checkbox": "^9.5.17", + "@fluentui/react-dialog": "^9.17.3", "@fluentui/react-divider": "^9.7.0", - "@fluentui/react-jsx-runtime": "^9.4.1", + "@fluentui/react-field": "^9.4.16", + "@fluentui/react-image": "^9.4.0", + "@fluentui/react-input": "^9.8.0", + "@fluentui/react-label": "^9.3.15", + "@fluentui/react-link": "^9.8.0", + "@fluentui/react-persona": "^9.7.1", + "@fluentui/react-progress": "^9.4.17", + "@fluentui/react-radio": "^9.6.0", + "@fluentui/react-rating": "^9.4.0", + "@fluentui/react-search": "^9.4.0", + "@fluentui/react-select": "^9.4.16", "@fluentui/react-shared-contexts": "^9.26.2", + "@fluentui/react-skeleton": "^9.7.0", + "@fluentui/react-slider": "^9.6.0", + "@fluentui/react-spinbutton": "^9.6.0", + "@fluentui/react-spinner": "^9.8.0", + "@fluentui/react-switch": "^9.7.0", + "@fluentui/react-tabs": "^9.11.2", + "@fluentui/react-tags": "^9.7.19", + "@fluentui/react-textarea": "^9.7.0", "@fluentui/react-utilities": "^9.26.2", "@swc/helpers": "^0.5.1" }, diff --git a/packages/react-components/react-headless-components-preview/library/src/Avatar.ts b/packages/react-components/react-headless-components-preview/library/src/Avatar.ts new file mode 100644 index 0000000000000..b18247893808b --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Avatar.ts @@ -0,0 +1,2 @@ +export { Avatar, renderAvatar, useAvatar } from './components/Avatar/index'; +export type { AvatarSlots, AvatarProps, AvatarState } from './components/Avatar/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Badge.ts b/packages/react-components/react-headless-components-preview/library/src/Badge.ts new file mode 100644 index 0000000000000..13eee87fab714 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Badge.ts @@ -0,0 +1,2 @@ +export { Badge, renderBadge, useBadge } from './components/Badge/index'; +export type { BadgeProps, BadgeState } from './components/Badge/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Breadcrumb.ts b/packages/react-components/react-headless-components-preview/library/src/Breadcrumb.ts new file mode 100644 index 0000000000000..85cce42643f7c --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Breadcrumb.ts @@ -0,0 +1,22 @@ +export { + Breadcrumb, + renderBreadcrumb, + useBreadcrumb, + useBreadcrumbContext, + useBreadcrumbContextValues, +} from './components/Breadcrumb'; +export type { + BreadcrumbSlots, + BreadcrumbProps, + BreadcrumbState, + BreadcrumbContextValues, +} from './components/Breadcrumb'; + +export { BreadcrumbDivider, renderBreadcrumbDivider, useBreadcrumbDivider } from './components/Breadcrumb'; +export type { BreadcrumbDividerSlots, BreadcrumbDividerProps, BreadcrumbDividerState } from './components/Breadcrumb'; + +export { BreadcrumbItem, renderBreadcrumbItem, useBreadcrumbItem } from './components/Breadcrumb'; +export type { BreadcrumbItemSlots, BreadcrumbItemProps, BreadcrumbItemState } from './components/Breadcrumb'; + +export { BreadcrumbButton, renderBreadcrumbButton, useBreadcrumbButton } from './components/Breadcrumb'; +export type { BreadcrumbButtonSlots, BreadcrumbButtonProps, BreadcrumbButtonState } from './components/Breadcrumb'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Checkbox.ts b/packages/react-components/react-headless-components-preview/library/src/Checkbox.ts new file mode 100644 index 0000000000000..a6fe15d94c5fc --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Checkbox.ts @@ -0,0 +1,2 @@ +export { Checkbox, renderCheckbox, useCheckbox } from './components/Checkbox/index'; +export type { CheckboxSlots, CheckboxProps, CheckboxState } from './components/Checkbox/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Field.ts b/packages/react-components/react-headless-components-preview/library/src/Field.ts new file mode 100644 index 0000000000000..86afafa149ff1 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Field.ts @@ -0,0 +1,2 @@ +export { Field, renderField, useField } from './components/Field/index'; +export type { FieldSlots, FieldProps, FieldState } from './components/Field/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Input.ts b/packages/react-components/react-headless-components-preview/library/src/Input.ts new file mode 100644 index 0000000000000..89764f4bc2620 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Input.ts @@ -0,0 +1,2 @@ +export { Input, renderInput, useInput } from './components/Input/index'; +export type { InputSlots, InputProps, InputState } from './components/Input/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Link.ts b/packages/react-components/react-headless-components-preview/library/src/Link.ts new file mode 100644 index 0000000000000..5a1056fe6576d --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Link.ts @@ -0,0 +1,2 @@ +export { Link, renderLink, useLink } from './components/Link/index'; +export type { LinkSlots, LinkProps, LinkState } from './components/Link/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/ProgressBar.ts b/packages/react-components/react-headless-components-preview/library/src/ProgressBar.ts new file mode 100644 index 0000000000000..43a14f1ad2f57 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/ProgressBar.ts @@ -0,0 +1,2 @@ +export { ProgressBar, renderProgressBar, useProgressBar } from './components/ProgressBar/index'; +export type { ProgressBarSlots, ProgressBarProps, ProgressBarState } from './components/ProgressBar/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/RadioGroup.ts b/packages/react-components/react-headless-components-preview/library/src/RadioGroup.ts new file mode 100644 index 0000000000000..6c3ea10ba1e14 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/RadioGroup.ts @@ -0,0 +1,16 @@ +export { + Radio, + renderRadio, + useRadio, + RadioGroup, + renderRadioGroup, + useRadioGroup, +} from './components/RadioGroup/index'; +export type { + RadioSlots, + RadioProps, + RadioState, + RadioGroupSlots, + RadioGroupProps, + RadioGroupState, +} from './components/RadioGroup/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Rating.ts b/packages/react-components/react-headless-components-preview/library/src/Rating.ts new file mode 100644 index 0000000000000..658430ad97cc2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Rating.ts @@ -0,0 +1,16 @@ +export { + RatingItem, + renderRatingItem, + useRatingItem, + Rating, + renderRating, + useRating, +} from './components/Rating/index'; +export type { + RatingItemSlots, + RatingItemProps, + RatingItemState, + RatingSlots, + RatingProps, + RatingState, +} from './components/Rating/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/SearchBox.ts b/packages/react-components/react-headless-components-preview/library/src/SearchBox.ts new file mode 100644 index 0000000000000..6a8dbcf6c258a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/SearchBox.ts @@ -0,0 +1,2 @@ +export { SearchBox, renderSearchBox, useSearchBox } from './components/SearchBox/index'; +export type { SearchBoxSlots, SearchBoxProps, SearchBoxState } from './components/SearchBox/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Select.ts b/packages/react-components/react-headless-components-preview/library/src/Select.ts new file mode 100644 index 0000000000000..77a248d43add6 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Select.ts @@ -0,0 +1,2 @@ +export { Select, renderSelect, useSelect } from './components/Select/index'; +export type { SelectSlots, SelectProps, SelectState } from './components/Select/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Skeleton.ts b/packages/react-components/react-headless-components-preview/library/src/Skeleton.ts new file mode 100644 index 0000000000000..c29e0a37c8fdd --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Skeleton.ts @@ -0,0 +1,16 @@ +export { + SkeletonItem, + renderSkeletonItem, + useSkeletonItem, + Skeleton, + renderSkeleton, + useSkeleton, +} from './components/Skeleton/index'; +export type { + SkeletonItemSlots, + SkeletonItemProps, + SkeletonItemState, + SkeletonSlots, + SkeletonProps, + SkeletonState, +} from './components/Skeleton/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Slider.ts b/packages/react-components/react-headless-components-preview/library/src/Slider.ts new file mode 100644 index 0000000000000..c82dca29698d3 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Slider.ts @@ -0,0 +1,2 @@ +export { Slider, renderSlider, useSlider } from './components/Slider/index'; +export type { SliderSlots, SliderProps, SliderState } from './components/Slider/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/SpinButton.ts b/packages/react-components/react-headless-components-preview/library/src/SpinButton.ts new file mode 100644 index 0000000000000..5166e6c1f4fe4 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/SpinButton.ts @@ -0,0 +1,2 @@ +export { SpinButton, renderSpinButton, useSpinButton } from './components/SpinButton/index'; +export type { SpinButtonSlots, SpinButtonProps, SpinButtonState } from './components/SpinButton/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Spinner.ts b/packages/react-components/react-headless-components-preview/library/src/Spinner.ts new file mode 100644 index 0000000000000..eaf7c7c0d9554 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Spinner.ts @@ -0,0 +1,2 @@ +export { Spinner, renderSpinner, useSpinner } from './components/Spinner/index'; +export type { SpinnerSlots, SpinnerProps, SpinnerState } from './components/Spinner/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Switch.ts b/packages/react-components/react-headless-components-preview/library/src/Switch.ts new file mode 100644 index 0000000000000..23349fb31f717 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Switch.ts @@ -0,0 +1,2 @@ +export { Switch, renderSwitch, useSwitch } from './components/Switch/index'; +export type { SwitchSlots, SwitchProps, SwitchState } from './components/Switch/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/TabList.ts b/packages/react-components/react-headless-components-preview/library/src/TabList.ts new file mode 100644 index 0000000000000..e8339b88f812b --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/TabList.ts @@ -0,0 +1,10 @@ +export { Tab, renderTab, useTab, TabList, renderTabList, useTabList } from './components/TabList/index'; +export type { + TabSlots, + TabValue, + TabProps, + TabState, + TabListSlots, + TabListProps, + TabListState, +} from './components/TabList/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/Textarea.ts b/packages/react-components/react-headless-components-preview/library/src/Textarea.ts new file mode 100644 index 0000000000000..e1ee150910003 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/Textarea.ts @@ -0,0 +1,2 @@ +export { Textarea, renderTextarea, useTextarea } from './components/Textarea/index'; +export type { TextareaSlots, TextareaProps, TextareaState } from './components/Textarea/index'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/Accordion.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/Accordion.types.ts index f70377ba16201..39f3108e03562 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/Accordion.types.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/Accordion.types.ts @@ -9,6 +9,17 @@ export type AccordionSlots = AccordionBaseSlots; export type AccordionProps = AccordionBaseProps; -export type AccordionState = AccordionBaseState; +export type AccordionState = AccordionBaseState & { + root: { + /** + * Data attribute set to indicate whether the accordion allows multiple items to be expanded at once. + */ + 'data-collapsible'?: string; + /** + * Data attribute set to indicate whether the accordion allows multiple items to be expanded at once. + */ + 'data-multiple'?: string; + }; +}; export type AccordionContextValues = AccordionBaseContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/AccordionItem.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/AccordionItem.types.ts index a5b064e93f589..d898c1a990177 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/AccordionItem.types.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/AccordionItem.types.ts @@ -9,6 +9,17 @@ export type AccordionItemSlots = AccordionItemBaseSlots; export type AccordionItemProps = AccordionItemBaseProps; -export type AccordionItemState = AccordionItemBaseState; +export type AccordionItemState = AccordionItemBaseState & { + root: { + /** + * Data attribute set to indicate whether the accordion item is disabled. + */ + 'data-disabled'?: string; + /** + * Data attribute set to indicate whether the accordion item is open. + */ + 'data-open'?: string; + }; +}; export type AccordionItemContextValues = AccordionItemBaseContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/useAccordionItem.ts b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/useAccordionItem.ts index 58010b1a5b490..87a9efbaf680e 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/useAccordionItem.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/AccordionItem/useAccordionItem.ts @@ -15,12 +15,13 @@ import { stringifyDataAttribute } from '../../../utils'; * The returned state can be modified with hooks before being passed to `renderAccordionItem`. */ export const useAccordionItem = (props: AccordionItemProps, ref: React.Ref): AccordionItemState => { - const state = useAccordionItem_unstable(props, ref); + 'use no memo'; - Object.assign(state.root, { - 'data-disabled': stringifyDataAttribute(state.disabled), - 'data-open': stringifyDataAttribute(state.open), - }); + const state: AccordionItemState = useAccordionItem_unstable(props, ref); + + // Set data attributes for open and disabled states to simplify styling of these states. + state.root['data-disabled'] = stringifyDataAttribute(state.disabled); + state.root['data-open'] = stringifyDataAttribute(state.open); return state; }; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/useAccordion.ts b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/useAccordion.ts index 8c734230b7f00..1421e18fc8047 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Accordion/useAccordion.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Accordion/useAccordion.ts @@ -15,12 +15,13 @@ import { stringifyDataAttribute } from '../../utils'; * The returned state can be modified with hooks before being passed to `renderAccordion`. */ export const useAccordion = (props: AccordionProps, ref: React.Ref): AccordionState => { - const state = useAccordionBase_unstable(props, ref); + 'use no memo'; - Object.assign(state.root, { - 'data-collapsible': stringifyDataAttribute(state.collapsible), - 'data-multiple': stringifyDataAttribute(state.multiple), - }); + const state: AccordionState = useAccordionBase_unstable(props, ref); + + // Set data attributes for collapsible and multiple states to simplify styling of these states. + state.root['data-collapsible'] = stringifyDataAttribute(state.collapsible); + state.root['data-multiple'] = stringifyDataAttribute(state.multiple); return state; }; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.test.tsx new file mode 100644 index 0000000000000..54e859ee79c46 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Avatar } from './Avatar'; + +describe('Avatar', () => { + isConformant({ + Component: Avatar, + displayName: 'Avatar', + }); + + it('renders a default state', () => { + const result = render(Default Avatar); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.tsx new file mode 100644 index 0000000000000..2441a688f8349 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.tsx @@ -0,0 +1,19 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { AvatarProps } from './Avatar.types'; +import { useAvatar } from './useAvatar'; +import { renderAvatar } from './renderAvatar'; + +/** + * An avatar component that displays an image or icon. + */ +export const Avatar: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useAvatar(props, ref); + + return renderAvatar(state); +}); + +Avatar.displayName = 'Avatar'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.types.ts new file mode 100644 index 0000000000000..111fcac1500c2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/Avatar.types.ts @@ -0,0 +1,16 @@ +import type { AvatarSlots as AvatarBaseSlots, AvatarBaseProps, AvatarBaseState } from '@fluentui/react-avatar'; + +/** + * Avatar component slots + */ +export type AvatarSlots = AvatarBaseSlots; + +/** + * Avatar component props + */ +export type AvatarProps = AvatarBaseProps; + +/** + * Avatar component state + */ +export type AvatarState = AvatarBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap new file mode 100644 index 0000000000000..9479c09c08c0a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Avatar renders a default state 1`] = ` +
+ + +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Avatar/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/index.ts new file mode 100644 index 0000000000000..58da5abff54df --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/index.ts @@ -0,0 +1,4 @@ +export { Avatar } from './Avatar'; +export { renderAvatar } from './renderAvatar'; +export { useAvatar } from './useAvatar'; +export type { AvatarSlots, AvatarProps, AvatarState } from './Avatar.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Avatar/renderAvatar.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/renderAvatar.tsx new file mode 100644 index 0000000000000..a7dbd90ee6bce --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/renderAvatar.tsx @@ -0,0 +1,6 @@ +import { renderAvatar_unstable } from '@fluentui/react-avatar'; + +/** + * Renders the final JSX of the Avatar component, given the state. + */ +export const renderAvatar = renderAvatar_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Avatar/useAvatar.ts b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/useAvatar.ts new file mode 100644 index 0000000000000..dc195103a6840 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Avatar/useAvatar.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useAvatarBase_unstable } from '@fluentui/react-avatar'; + +import type { AvatarProps, AvatarState } from './Avatar.types'; + +/** + * Returns the state for an Avatar component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderAvatar`. + */ +export const useAvatar = (props: AvatarProps, ref: React.Ref): AvatarState => { + const state: AvatarState = useAvatarBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.test.tsx new file mode 100644 index 0000000000000..627d61ea614ee --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Badge } from './Badge'; + +describe('Badge', () => { + isConformant({ + Component: Badge, + displayName: 'Badge', + }); + + it('renders a default state', () => { + const result = render(Default Badge); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.tsx new file mode 100644 index 0000000000000..88d9da04d8ef2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.tsx @@ -0,0 +1,19 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { BadgeProps } from './Badge.types'; +import { useBadge } from './useBadge'; +import { renderBadge } from './renderBadge'; + +/** + * A badge component for displaying counts or labels. + */ +export const Badge: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useBadge(props, ref); + + return renderBadge(state); +}); + +Badge.displayName = 'Badge'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.types.ts new file mode 100644 index 0000000000000..0af66ce6986ec --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Badge/Badge.types.ts @@ -0,0 +1,16 @@ +import type { BadgeSlots as BadgeBaseSlots, BadgeBaseProps, BadgeBaseState } from '@fluentui/react-badge'; + +/** + * Badge component slots + */ +export type BadgeSlots = BadgeBaseSlots; + +/** + * Badge component props + */ +export type BadgeProps = BadgeBaseProps; + +/** + * Badge component state + */ +export type BadgeState = BadgeBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Badge/__snapshots__/Badge.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Badge/__snapshots__/Badge.test.tsx.snap new file mode 100644 index 0000000000000..10b637a8b5e69 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Badge/__snapshots__/Badge.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Badge renders a default state 1`] = ` +
+
+ Default Badge +
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Badge/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Badge/index.ts new file mode 100644 index 0000000000000..1f2787bfe1772 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Badge/index.ts @@ -0,0 +1,4 @@ +export { Badge } from './Badge'; +export { renderBadge } from './renderBadge'; +export { useBadge } from './useBadge'; +export type { BadgeSlots, BadgeProps, BadgeState } from './Badge.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Badge/renderBadge.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Badge/renderBadge.tsx new file mode 100644 index 0000000000000..e47c727459cce --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Badge/renderBadge.tsx @@ -0,0 +1,6 @@ +import { renderBadge_unstable } from '@fluentui/react-badge'; + +/** + * Renders the final JSX of the Badge component, given the state. + */ +export const renderBadge = renderBadge_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Badge/useBadge.ts b/packages/react-components/react-headless-components-preview/library/src/components/Badge/useBadge.ts new file mode 100644 index 0000000000000..f75b5b88918e1 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Badge/useBadge.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useBadgeBase_unstable } from '@fluentui/react-badge'; + +import type { BadgeProps, BadgeState } from './Badge.types'; + +/** + * Returns the state for a Badge component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderBadge`. + */ +export const useBadge = (props: BadgeProps, ref: React.Ref): BadgeState => { + const state: BadgeState = useBadgeBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.test.tsx new file mode 100644 index 0000000000000..1aba84097bdf4 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Breadcrumb } from './Breadcrumb'; + +describe('Breadcrumb', () => { + isConformant({ + Component: Breadcrumb, + displayName: 'Breadcrumb', + }); + + it('renders a default state', () => { + const result = render(Default Breadcrumb); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.tsx new file mode 100644 index 0000000000000..2faaf67edce84 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.tsx @@ -0,0 +1,20 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { BreadcrumbProps } from './Breadcrumb.types'; +import { useBreadcrumb, useBreadcrumbContextValues } from './useBreadcrumb'; +import { renderBreadcrumb } from './renderBreadcrumb'; + +/** + * A breadcrumb component for displaying navigation hierarchy. + */ +export const Breadcrumb: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useBreadcrumb(props, ref); + const contextValues = useBreadcrumbContextValues(state); + + return renderBreadcrumb(state, contextValues); +}); + +Breadcrumb.displayName = 'Breadcrumb'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.types.ts new file mode 100644 index 0000000000000..15e237ade2150 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/Breadcrumb.types.ts @@ -0,0 +1,26 @@ +import type { + BreadcrumbSlots as BreadcrumbBaseSlots, + BreadcrumbBaseProps, + BreadcrumbBaseState, + BreadcrumbContextValues as BreadcrumbBaseContextValues, +} from '@fluentui/react-breadcrumb'; + +/** + * Breadcrumb component slots + */ +export type BreadcrumbSlots = BreadcrumbBaseSlots; + +/** + * Breadcrumb component props + */ +export type BreadcrumbProps = BreadcrumbBaseProps; + +/** + * Breadcrumb component state + */ +export type BreadcrumbState = BreadcrumbBaseState; + +/** + * Context values provided by Breadcrumb to its sub-components. + */ +export type BreadcrumbContextValues = BreadcrumbBaseContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.tsx new file mode 100644 index 0000000000000..b14ce4082efb0 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.tsx @@ -0,0 +1,20 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { BreadcrumbButtonProps } from './BreadcrumbButton.types'; +import { useBreadcrumbButton } from './useBreadcrumbButton'; +import { renderBreadcrumbButton } from './renderBreadcrumbButton'; + +/** + * An interactive button representing a navigation step in a breadcrumb trail. + * Set the `current` prop to mark the active page. + */ +export const BreadcrumbButton: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useBreadcrumbButton(props, ref); + + return renderBreadcrumbButton(state); +}); + +BreadcrumbButton.displayName = 'BreadcrumbButton'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.types.ts new file mode 100644 index 0000000000000..dd3cb0093b542 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/BreadcrumbButton.types.ts @@ -0,0 +1,27 @@ +import type { + BreadcrumbButtonSlots as BreadcrumbButtonBaseSlots, + BreadcrumbButtonBaseProps, + BreadcrumbButtonBaseState, +} from '@fluentui/react-breadcrumb'; + +/** + * BreadcrumbButton component slots + */ +export type BreadcrumbButtonSlots = BreadcrumbButtonBaseSlots; + +/** + * BreadcrumbButton component props + */ +export type BreadcrumbButtonProps = BreadcrumbButtonBaseProps; + +/** + * BreadcrumbButton component state + */ +export type BreadcrumbButtonState = BreadcrumbButtonBaseState & { + root: { + /** + * Data attribute set to indicate that this button represents the current page in the breadcrumb. + */ + 'data-current'?: string; + }; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/index.ts new file mode 100644 index 0000000000000..2e5582099aa1a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/index.ts @@ -0,0 +1,4 @@ +export { BreadcrumbButton } from './BreadcrumbButton'; +export { renderBreadcrumbButton } from './renderBreadcrumbButton'; +export { useBreadcrumbButton } from './useBreadcrumbButton'; +export type { BreadcrumbButtonSlots, BreadcrumbButtonProps, BreadcrumbButtonState } from './BreadcrumbButton.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/renderBreadcrumbButton.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/renderBreadcrumbButton.ts new file mode 100644 index 0000000000000..a709686a8d220 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/renderBreadcrumbButton.ts @@ -0,0 +1,12 @@ +import { renderBreadcrumbButton_unstable } from '@fluentui/react-breadcrumb'; +import type { BreadcrumbButtonBaseState } from '@fluentui/react-breadcrumb'; +import type { JSXElement } from '@fluentui/react-utilities'; + +import type { BreadcrumbButtonState } from './BreadcrumbButton.types'; + +/** + * Renders the final JSX of the BreadcrumbButton component, given the state. + */ +export const renderBreadcrumbButton = (state: BreadcrumbButtonState): JSXElement => { + return renderBreadcrumbButton_unstable(state as BreadcrumbButtonBaseState); +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/useBreadcrumbButton.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/useBreadcrumbButton.ts new file mode 100644 index 0000000000000..d260c4ac69228 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbButton/useBreadcrumbButton.ts @@ -0,0 +1,25 @@ +'use client'; + +import type * as React from 'react'; +import { useBreadcrumbButtonBase_unstable } from '@fluentui/react-breadcrumb'; + +import type { BreadcrumbButtonProps, BreadcrumbButtonState } from './BreadcrumbButton.types'; +import { stringifyDataAttribute } from '../../../utils'; + +/** + * Returns the state for a BreadcrumbButton component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderBreadcrumbButton`. + */ +export const useBreadcrumbButton = ( + props: BreadcrumbButtonProps, + ref: React.Ref, +): BreadcrumbButtonState => { + 'use no memo'; + + const state: BreadcrumbButtonState = useBreadcrumbButtonBase_unstable(props, ref); + + // Set data attribute for current state to simplify styling of the active breadcrumb item. + state.root['data-current'] = stringifyDataAttribute(state.current); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.tsx new file mode 100644 index 0000000000000..db73976b7e775 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.tsx @@ -0,0 +1,19 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { BreadcrumbDividerProps } from './BreadcrumbDivider.types'; +import { useBreadcrumbDivider } from './useBreadcrumbDivider'; +import { renderBreadcrumbDivider } from './renderBreadcrumbDivider'; + +/** + * A visual separator between breadcrumb items. + */ +export const BreadcrumbDivider: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useBreadcrumbDivider(props, ref); + + return renderBreadcrumbDivider(state); +}); + +BreadcrumbDivider.displayName = 'BreadcrumbDivider'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.types.ts new file mode 100644 index 0000000000000..ceb907e7ad0ca --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/BreadcrumbDivider.types.ts @@ -0,0 +1,20 @@ +import type { + BreadcrumbDividerSlots as BreadcrumbDividerBaseSlots, + BreadcrumbDividerBaseProps, + BreadcrumbDividerBaseState, +} from '@fluentui/react-breadcrumb'; + +/** + * BreadcrumbDivider component slots + */ +export type BreadcrumbDividerSlots = BreadcrumbDividerBaseSlots; + +/** + * BreadcrumbDivider component props + */ +export type BreadcrumbDividerProps = BreadcrumbDividerBaseProps; + +/** + * BreadcrumbDivider component state + */ +export type BreadcrumbDividerState = BreadcrumbDividerBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/index.ts new file mode 100644 index 0000000000000..9a24109e5a136 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/index.ts @@ -0,0 +1,4 @@ +export { BreadcrumbDivider } from './BreadcrumbDivider'; +export { renderBreadcrumbDivider } from './renderBreadcrumbDivider'; +export { useBreadcrumbDivider } from './useBreadcrumbDivider'; +export type { BreadcrumbDividerSlots, BreadcrumbDividerProps, BreadcrumbDividerState } from './BreadcrumbDivider.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/renderBreadcrumbDivider.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/renderBreadcrumbDivider.ts new file mode 100644 index 0000000000000..b6fc2aca033e2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/renderBreadcrumbDivider.ts @@ -0,0 +1,6 @@ +import { renderBreadcrumbDivider_unstable } from '@fluentui/react-breadcrumb'; + +/** + * Renders the final JSX of the BreadcrumbDivider component, given the state. + */ +export const renderBreadcrumbDivider = renderBreadcrumbDivider_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/useBreadcrumbDivider.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/useBreadcrumbDivider.ts new file mode 100644 index 0000000000000..fcbc02361f132 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbDivider/useBreadcrumbDivider.ts @@ -0,0 +1,19 @@ +'use client'; + +import type * as React from 'react'; +import { useBreadcrumbDividerBase_unstable } from '@fluentui/react-breadcrumb'; + +import type { BreadcrumbDividerProps, BreadcrumbDividerState } from './BreadcrumbDivider.types'; + +/** + * Returns the state for a BreadcrumbDivider component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderBreadcrumbDivider`. + */ +export const useBreadcrumbDivider = ( + props: BreadcrumbDividerProps, + ref: React.Ref, +): BreadcrumbDividerState => { + const state: BreadcrumbDividerState = useBreadcrumbDividerBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.tsx new file mode 100644 index 0000000000000..395346e93cd84 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.tsx @@ -0,0 +1,19 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { BreadcrumbItemProps } from './BreadcrumbItem.types'; +import { useBreadcrumbItem } from './useBreadcrumbItem'; +import { renderBreadcrumbItem } from './renderBreadcrumbItem'; + +/** + * A list item that wraps a breadcrumb entry, such as a BreadcrumbButton or plain text. + */ +export const BreadcrumbItem: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useBreadcrumbItem(props, ref); + + return renderBreadcrumbItem(state); +}); + +BreadcrumbItem.displayName = 'BreadcrumbItem'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.types.ts new file mode 100644 index 0000000000000..51f6d92f49b09 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/BreadcrumbItem.types.ts @@ -0,0 +1,20 @@ +import type { + BreadcrumbItemSlots as BreadcrumbItemBaseSlots, + BreadcrumbItemBaseProps, + BreadcrumbItemBaseState, +} from '@fluentui/react-breadcrumb'; + +/** + * BreadcrumbItem component slots + */ +export type BreadcrumbItemSlots = BreadcrumbItemBaseSlots; + +/** + * BreadcrumbItem component props + */ +export type BreadcrumbItemProps = BreadcrumbItemBaseProps; + +/** + * BreadcrumbItem component state + */ +export type BreadcrumbItemState = BreadcrumbItemBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/index.ts new file mode 100644 index 0000000000000..58d83098be85a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/index.ts @@ -0,0 +1,4 @@ +export { BreadcrumbItem } from './BreadcrumbItem'; +export { renderBreadcrumbItem } from './renderBreadcrumbItem'; +export { useBreadcrumbItem } from './useBreadcrumbItem'; +export type { BreadcrumbItemSlots, BreadcrumbItemProps, BreadcrumbItemState } from './BreadcrumbItem.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/renderBreadcrumbItem.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/renderBreadcrumbItem.ts new file mode 100644 index 0000000000000..d0178cf53a6f4 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/renderBreadcrumbItem.ts @@ -0,0 +1,6 @@ +import { renderBreadcrumbItem_unstable } from '@fluentui/react-breadcrumb'; + +/** + * Renders the final JSX of the BreadcrumbItem component, given the state. + */ +export const renderBreadcrumbItem = renderBreadcrumbItem_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/useBreadcrumbItem.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/useBreadcrumbItem.ts new file mode 100644 index 0000000000000..b8b353f6fc75c --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/BreadcrumbItem/useBreadcrumbItem.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useBreadcrumbItemBase_unstable } from '@fluentui/react-breadcrumb'; + +import type { BreadcrumbItemProps, BreadcrumbItemState } from './BreadcrumbItem.types'; + +/** + * Returns the state for a BreadcrumbItem component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderBreadcrumbItem`. + */ +export const useBreadcrumbItem = (props: BreadcrumbItemProps, ref: React.Ref): BreadcrumbItemState => { + const state: BreadcrumbItemState = useBreadcrumbItemBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap new file mode 100644 index 0000000000000..979051771d343 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/__snapshots__/Breadcrumb.test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Breadcrumb renders a default state 1`] = ` +
+ +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/index.ts new file mode 100644 index 0000000000000..23c1c9f1e956b --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/index.ts @@ -0,0 +1,13 @@ +export { Breadcrumb } from './Breadcrumb'; +export { renderBreadcrumb } from './renderBreadcrumb'; +export { useBreadcrumb, useBreadcrumbContext, useBreadcrumbContextValues } from './useBreadcrumb'; +export type { BreadcrumbSlots, BreadcrumbProps, BreadcrumbState, BreadcrumbContextValues } from './Breadcrumb.types'; + +export { BreadcrumbDivider, renderBreadcrumbDivider, useBreadcrumbDivider } from './BreadcrumbDivider'; +export type { BreadcrumbDividerSlots, BreadcrumbDividerProps, BreadcrumbDividerState } from './BreadcrumbDivider'; + +export { BreadcrumbItem, renderBreadcrumbItem, useBreadcrumbItem } from './BreadcrumbItem'; +export type { BreadcrumbItemSlots, BreadcrumbItemProps, BreadcrumbItemState } from './BreadcrumbItem'; + +export { BreadcrumbButton, renderBreadcrumbButton, useBreadcrumbButton } from './BreadcrumbButton'; +export type { BreadcrumbButtonSlots, BreadcrumbButtonProps, BreadcrumbButtonState } from './BreadcrumbButton'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/renderBreadcrumb.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/renderBreadcrumb.tsx new file mode 100644 index 0000000000000..21372820fb7a9 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/renderBreadcrumb.tsx @@ -0,0 +1,6 @@ +import { renderBreadcrumb_unstable } from '@fluentui/react-breadcrumb'; + +/** + * Renders the final JSX of the Breadcrumb component, given the state and context values. + */ +export const renderBreadcrumb = renderBreadcrumb_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/useBreadcrumb.ts b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/useBreadcrumb.ts new file mode 100644 index 0000000000000..64dd5eede1e7e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Breadcrumb/useBreadcrumb.ts @@ -0,0 +1,33 @@ +'use client'; + +import type * as React from 'react'; +import { + useBreadcrumbBase_unstable, + useBreadcrumbContext_unstable, + useBreadcrumbContextValues_unstable, +} from '@fluentui/react-breadcrumb'; + +import type { BreadcrumbProps, BreadcrumbState, BreadcrumbContextValues } from './Breadcrumb.types'; + +/** + * Returns the state for a Breadcrumb component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderBreadcrumb`. + */ +export const useBreadcrumb = (props: BreadcrumbProps, ref: React.Ref): BreadcrumbState => { + const state: BreadcrumbState = useBreadcrumbBase_unstable(props, ref); + + return state; +}; + +/** + * Returns the context values provided by the nearest Breadcrumb, enabling child components to + * read breadcrumb-level state such as the current size. + */ +export const useBreadcrumbContext = useBreadcrumbContext_unstable; + +/** + * Maps Breadcrumb state to the context values passed down to child components. + */ +export const useBreadcrumbContextValues = useBreadcrumbContextValues_unstable as ( + state: BreadcrumbState, +) => BreadcrumbContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Button/Button.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Button/Button.types.ts index 81bbfb69d11b5..6080ab66927fa 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Button/Button.types.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Button/Button.types.ts @@ -13,4 +13,21 @@ export type ButtonProps = ButtonBaseProps; /** * Button component state */ -export type ButtonState = ButtonBaseState; +export type ButtonState = ButtonBaseState & { + root: { + /** + * Data attribute set when the button is disabled. + */ + 'data-disabled'?: string; + + /** + * Data attribute set when the button is disabled but still focusable. + */ + 'data-disabled-focusable'?: string; + + /** + * Data attribute set when the button renders only an icon. + */ + 'data-icon-only'?: string; + }; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Button/useButton.ts b/packages/react-components/react-headless-components-preview/library/src/components/Button/useButton.ts index 8fa1537184d18..e3619da1d76e9 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Button/useButton.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Button/useButton.ts @@ -11,13 +11,14 @@ import { stringifyDataAttribute } from '../../utils'; * The returned state can be modified with hooks before being passed to `renderButton`. */ export const useButton = (props: ButtonProps, ref: React.Ref): ButtonState => { - const state = useButtonBase_unstable(props, ref); + 'use no memo'; - Object.assign(state.root, { - 'data-disabled': stringifyDataAttribute(state.disabled), - 'data-disabled-focusable': stringifyDataAttribute(state.disabledFocusable), - 'data-icon-only': stringifyDataAttribute(state.iconOnly), - }); + const state: ButtonState = useButtonBase_unstable(props, ref); + + // Set data attributes for disabled, disabledFocusable, and iconOnly states to simplify styling of these states. + state.root['data-disabled'] = stringifyDataAttribute(state.disabled); + state.root['data-disabled-focusable'] = stringifyDataAttribute(state.disabledFocusable); + state.root['data-icon-only'] = stringifyDataAttribute(state.iconOnly); return state; }; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.test.tsx new file mode 100644 index 0000000000000..c14ae51aaf3f9 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Checkbox } from './Checkbox'; + +describe('Checkbox', () => { + isConformant({ + Component: Checkbox, + displayName: 'Checkbox', + primarySlot: 'input', + }); + + it('renders a default state', () => { + const result = render(); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.tsx new file mode 100644 index 0000000000000..05f551879b70e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import { useCheckbox } from './useCheckbox'; +import { renderCheckbox } from './renderCheckbox'; +import type { CheckboxProps } from './Checkbox.types'; + +/** + * Checkbox component - TODO: add more docs + */ +export const Checkbox: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useCheckbox(props, ref); + + return renderCheckbox(state); +}); + +Checkbox.displayName = 'Checkbox'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.types.ts new file mode 100644 index 0000000000000..7949e91cb1a2f --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/Checkbox.types.ts @@ -0,0 +1,17 @@ +import type { + CheckboxSlots as CheckboxBaseSlots, + CheckboxBaseState, + CheckboxBaseProps, +} from '@fluentui/react-checkbox'; + +export type CheckboxSlots = CheckboxBaseSlots; + +/** + * Checkbox Props + */ +export type CheckboxProps = CheckboxBaseProps; + +/** + * State used in rendering Checkbox + */ +export type CheckboxState = CheckboxBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap new file mode 100644 index 0000000000000..0136fbf2944e1 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Checkbox renders a default state 1`] = ` +
+ + + +`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/index.ts new file mode 100644 index 0000000000000..6c2ba7bed9e16 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/index.ts @@ -0,0 +1,4 @@ +export { Checkbox } from './Checkbox'; +export type { CheckboxSlots, CheckboxProps, CheckboxState } from './Checkbox.types'; +export { renderCheckbox } from './renderCheckbox'; +export { useCheckbox } from './useCheckbox'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/renderCheckbox.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/renderCheckbox.tsx new file mode 100644 index 0000000000000..b24c9b2ed209d --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/renderCheckbox.tsx @@ -0,0 +1,6 @@ +import { renderCheckbox_unstable } from '@fluentui/react-checkbox'; + +/** + * Render the final JSX of Checkbox + */ +export const renderCheckbox = renderCheckbox_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/useCheckbox.ts b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/useCheckbox.ts new file mode 100644 index 0000000000000..763cb243f071e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Checkbox/useCheckbox.ts @@ -0,0 +1,20 @@ +'use client'; + +import type * as React from 'react'; +import { useCheckboxBase_unstable } from '@fluentui/react-checkbox'; +import type { CheckboxProps, CheckboxState } from './Checkbox.types'; + +/** + * Create the state required to render Checkbox. + * + * The returned state can be modified with hooks, + * before being passed to renderCheckbox_unstable. + * + * @param props - props from this instance of Checkbox + * @param ref - reference to root HTMLInputElement of Checkbox + */ +export const useCheckbox = (props: CheckboxProps, ref: React.Ref): CheckboxState => { + const state = useCheckboxBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Divider/Divider.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Divider/Divider.types.ts index c228163738bb6..3947f556a0c38 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Divider/Divider.types.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Divider/Divider.types.ts @@ -4,4 +4,11 @@ export type DividerSlots = DividerBaseSlots; export type DividerProps = DividerBaseProps; -export type DividerState = DividerBaseState; +export type DividerState = DividerBaseState & { + root: { + /** + * Data attribute set to indicate the orientation of the divider. + */ + 'data-orientation'?: 'vertical' | 'horizontal'; + }; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Divider/useDivider.ts b/packages/react-components/react-headless-components-preview/library/src/components/Divider/useDivider.ts index b0f17acfcabae..f312873e608eb 100644 --- a/packages/react-components/react-headless-components-preview/library/src/components/Divider/useDivider.ts +++ b/packages/react-components/react-headless-components-preview/library/src/components/Divider/useDivider.ts @@ -10,11 +10,12 @@ import type { DividerProps, DividerState } from './Divider.types'; * The returned state can be modified with hooks before being passed to `renderDivider`. */ export const useDivider = (props: DividerProps, ref: React.Ref): DividerState => { - const state = useDividerBase_unstable(props, ref); + 'use no memo'; - Object.assign(state.root, { - 'data-orientation': props.vertical ? 'vertical' : 'horizontal', - }); + const state: DividerState = useDividerBase_unstable(props, ref); + + // Set data attribute for orientation to simplify styling of vertical vs horizontal dividers. + state.root['data-orientation'] = props.vertical ? 'vertical' : 'horizontal'; return state; }; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.test.tsx new file mode 100644 index 0000000000000..adc9e439cd6e4 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Field } from './Field'; + +describe('Field', () => { + isConformant({ + Component: Field, + displayName: 'Field', + }); + + it('renders a default state', () => { + const result = render(Default Field); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.tsx new file mode 100644 index 0000000000000..c3250989039c7 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.tsx @@ -0,0 +1,20 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { FieldProps } from './Field.types'; +import { useField } from './useField'; +import { renderField } from './renderField'; +import { useFieldContextValues } from './useFieldContextValues'; + +/** + * A field component for form input grouping. + */ +export const Field: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useField(props, ref); + const contextValues = useFieldContextValues(state); + + return renderField(state, contextValues); +}); + +Field.displayName = 'Field'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.types.ts new file mode 100644 index 0000000000000..9029f52bd2027 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/Field.types.ts @@ -0,0 +1,26 @@ +import type { + FieldSlots as FieldBaseSlots, + FieldBaseProps, + FieldBaseState, + FieldContextValues as FieldContextValuesBase, +} from '@fluentui/react-field'; + +/** + * Field component slots + */ +export type FieldSlots = FieldBaseSlots; + +/** + * Field component props + */ +export type FieldProps = FieldBaseProps; + +/** + * Field component state + */ +export type FieldState = FieldBaseState; + +/** + * Field component context values + */ +export type FieldContextValues = FieldContextValuesBase; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/__snapshots__/Field.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Field/__snapshots__/Field.test.tsx.snap new file mode 100644 index 0000000000000..e3a492ee2e792 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/__snapshots__/Field.test.tsx.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Field renders a default state 1`] = ` +
+
+ Default Field +
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Field/index.ts new file mode 100644 index 0000000000000..7d165fd1d0e39 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/index.ts @@ -0,0 +1,4 @@ +export { Field } from './Field'; +export { renderField } from './renderField'; +export { useField } from './useField'; +export type { FieldSlots, FieldProps, FieldState } from './Field.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/renderField.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Field/renderField.tsx new file mode 100644 index 0000000000000..5223ac169fe8e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/renderField.tsx @@ -0,0 +1,6 @@ +import { renderField_unstable } from '@fluentui/react-field'; + +/** + * Renders the final JSX of the Field component, given the state. + */ +export const renderField = renderField_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/useField.ts b/packages/react-components/react-headless-components-preview/library/src/components/Field/useField.ts new file mode 100644 index 0000000000000..a9055a776bc69 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/useField.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useFieldBase_unstable } from '@fluentui/react-field'; + +import type { FieldProps, FieldState } from './Field.types'; + +/** + * Returns the state for a Field component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderField`. + */ +export const useField = (props: FieldProps, ref: React.Ref): FieldState => { + const state: FieldState = useFieldBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Field/useFieldContextValues.ts b/packages/react-components/react-headless-components-preview/library/src/components/Field/useFieldContextValues.ts new file mode 100644 index 0000000000000..e942fb9ba3fea --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Field/useFieldContextValues.ts @@ -0,0 +1,10 @@ +'use client'; + +import { useFieldContextValues_unstable } from '@fluentui/react-field'; + +import type { FieldState, FieldContextValues } from './Field.types'; + +/** + * Returns the context values for a Field component, given its state. + */ +export const useFieldContextValues = useFieldContextValues_unstable as (state: FieldState) => FieldContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.test.tsx new file mode 100644 index 0000000000000..d5c854df462f4 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Input } from './Input'; + +describe('Input', () => { + isConformant({ + Component: Input, + displayName: 'Input', + primarySlot: 'input', + }); + + it('renders a default state', () => { + const result = render(); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.tsx new file mode 100644 index 0000000000000..8f0a0618c4da8 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { InputProps } from './Input.types'; +import { useInput } from './useInput'; +import { renderInput } from './renderInput'; + +/** + * An input component for text and other input types. + */ +export const Input: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useInput(props, ref); + + return renderInput(state); +}); + +Input.displayName = 'Input'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.types.ts new file mode 100644 index 0000000000000..df52e15c4ebba --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Input/Input.types.ts @@ -0,0 +1,16 @@ +import type { InputSlots as InputBaseSlots, InputBaseProps, InputBaseState } from '@fluentui/react-input'; + +/** + * Input component slots + */ +export type InputSlots = InputBaseSlots; + +/** + * Input component props + */ +export type InputProps = InputBaseProps; + +/** + * Input component state + */ +export type InputState = InputBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Input/__snapshots__/Input.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Input/__snapshots__/Input.test.tsx.snap new file mode 100644 index 0000000000000..5f85e777f9eab --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Input/__snapshots__/Input.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Input renders a default state 1`] = ` +
+ + + +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Input/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Input/index.ts new file mode 100644 index 0000000000000..5c7dc655e38a7 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Input/index.ts @@ -0,0 +1,4 @@ +export { Input } from './Input'; +export { renderInput } from './renderInput'; +export { useInput } from './useInput'; +export type { InputSlots, InputProps, InputState } from './Input.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Input/renderInput.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Input/renderInput.tsx new file mode 100644 index 0000000000000..7e1891f1a33a9 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Input/renderInput.tsx @@ -0,0 +1,6 @@ +import { renderInput_unstable } from '@fluentui/react-input'; + +/** + * Renders the final JSX of the Input component, given the state. + */ +export const renderInput = renderInput_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Input/useInput.ts b/packages/react-components/react-headless-components-preview/library/src/components/Input/useInput.ts new file mode 100644 index 0000000000000..ae0a49a55cdb8 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Input/useInput.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useInputBase_unstable } from '@fluentui/react-input'; + +import type { InputProps, InputState } from './Input.types'; + +/** + * Returns the state for an Input component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderInput`. + */ +export const useInput = (props: InputProps, ref: React.Ref): InputState => { + const state: InputState = useInputBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Label/Label.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Label/Label.tsx new file mode 100644 index 0000000000000..68baf453df1a2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Label/Label.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { LabelProps } from './Label.types'; +import { useLabel } from './useLabel'; +import { renderLabel } from './renderLabel'; + +/** + * A label component that associates text with form elements. + */ +export const Label: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useLabel(props, ref); + + return renderLabel(state); +}); + +Label.displayName = 'Label'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Label/Label.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Label/Label.types.ts new file mode 100644 index 0000000000000..0ec9aab0af7db --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Label/Label.types.ts @@ -0,0 +1,16 @@ +import type { LabelSlots as LabelBaseSlots, LabelBaseProps, LabelBaseState } from '@fluentui/react-label'; + +/** + * Label component slots + */ +export type LabelSlots = LabelBaseSlots; + +/** + * Label component props + */ +export type LabelProps = LabelBaseProps; + +/** + * Label component state + */ +export type LabelState = LabelBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Label/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Label/index.ts new file mode 100644 index 0000000000000..6679803721ab1 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Label/index.ts @@ -0,0 +1,4 @@ +export { Label } from './Label'; +export { renderLabel } from './renderLabel'; +export { useLabel } from './useLabel'; +export type { LabelSlots, LabelProps, LabelState } from './Label.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Label/renderLabel.ts b/packages/react-components/react-headless-components-preview/library/src/components/Label/renderLabel.ts new file mode 100644 index 0000000000000..ae856b597bfd4 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Label/renderLabel.ts @@ -0,0 +1,6 @@ +import { renderLabel_unstable } from '@fluentui/react-label'; + +/** + * Renders the final JSX of the Label component, given the state. + */ +export const renderLabel = renderLabel_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Label/useLabel.ts b/packages/react-components/react-headless-components-preview/library/src/components/Label/useLabel.ts new file mode 100644 index 0000000000000..47b55ff940b64 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Label/useLabel.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useLabelBase_unstable } from '@fluentui/react-label'; + +import type { LabelProps, LabelState } from './Label.types'; + +/** + * Returns the state for a Label component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderLabel`. + */ +export const useLabel = (props: LabelProps, ref: React.Ref): LabelState => { + const state = useLabelBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.test.tsx new file mode 100644 index 0000000000000..0b6c863dae928 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Link } from './Link'; + +describe('Link', () => { + isConformant({ + Component: Link, + displayName: 'Link', + }); + + it('renders a default state', () => { + const result = render(Default Link); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.tsx new file mode 100644 index 0000000000000..b72231440020c --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.tsx @@ -0,0 +1,19 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { LinkProps } from './Link.types'; +import { useLink } from './useLink'; +import { renderLink } from './renderLink'; + +/** + * A link component for navigation. + */ +export const Link: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useLink(props, ref); + + return renderLink(state); +}); + +Link.displayName = 'Link'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.types.ts new file mode 100644 index 0000000000000..9b88ec57c8035 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Link/Link.types.ts @@ -0,0 +1,28 @@ +import type { LinkSlots as LinkBaseSlots, LinkBaseProps, LinkBaseState } from '@fluentui/react-link'; + +/** + * Link component slots + */ +export type LinkSlots = LinkBaseSlots; + +/** + * Link component props + */ +export type LinkProps = LinkBaseProps; + +/** + * Link component state + */ +export type LinkState = LinkBaseState & { + root: { + /** + * Data attribute set when the link is disabled. + */ + 'data-disabled'?: string; + + /** + * Data attribute set when the link is disabled but still focusable. + */ + 'data-disabled-focusable'?: string; + }; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Link/__snapshots__/Link.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Link/__snapshots__/Link.test.tsx.snap new file mode 100644 index 0000000000000..eb7dd312cc1cf --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Link/__snapshots__/Link.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Link renders a default state 1`] = ` +
+ +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Link/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Link/index.ts new file mode 100644 index 0000000000000..f27464593eec2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Link/index.ts @@ -0,0 +1,4 @@ +export { Link } from './Link'; +export { renderLink } from './renderLink'; +export { useLink } from './useLink'; +export type { LinkSlots, LinkProps, LinkState } from './Link.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Link/renderLink.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Link/renderLink.tsx new file mode 100644 index 0000000000000..0fda28a3a1366 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Link/renderLink.tsx @@ -0,0 +1,6 @@ +import { renderLink_unstable } from '@fluentui/react-link'; + +/** + * Renders the final JSX of the Link component, given the state. + */ +export const renderLink = renderLink_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Link/useLink.ts b/packages/react-components/react-headless-components-preview/library/src/components/Link/useLink.ts new file mode 100644 index 0000000000000..e2bff81db26b9 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Link/useLink.ts @@ -0,0 +1,22 @@ +'use client'; + +import type * as React from 'react'; +import { useLinkBase_unstable } from '@fluentui/react-link'; + +import type { LinkProps, LinkState } from './Link.types'; +import { stringifyDataAttribute } from '../../utils'; + +/** + * Returns the state for a Link component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderLink`. + */ +export const useLink = (props: LinkProps, ref: React.Ref): LinkState => { + 'use no memo'; + + const state: LinkState = useLinkBase_unstable(props, ref); + + state.root['data-disabled'] = stringifyDataAttribute(state.disabled); + state.root['data-disabled-focusable'] = stringifyDataAttribute(state.disabledFocusable); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.test.tsx new file mode 100644 index 0000000000000..c87ce6f9c0a25 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { ProgressBar } from './ProgressBar'; + +describe('ProgressBar', () => { + isConformant({ + Component: ProgressBar, + displayName: 'ProgressBar', + }); + + it('renders a default state', () => { + const result = render(Default ProgressBar); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.tsx b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.tsx new file mode 100644 index 0000000000000..17c00f567e1db --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import { useProgressBar } from './useProgressBar'; +import { renderProgressBar } from './renderProgressBar'; +import type { ProgressBarProps } from './ProgressBar.types'; + +/** + * ProgressBar component - TODO: add more docs + */ +export const ProgressBar: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useProgressBar(props, ref); + + return renderProgressBar(state); +}); + +ProgressBar.displayName = 'ProgressBar'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.types.ts new file mode 100644 index 0000000000000..00d2f37d74e24 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/ProgressBar.types.ts @@ -0,0 +1,17 @@ +import type { + ProgressBarSlots as ProgressBarBaseSlots, + ProgressBarBaseProps, + ProgressBarBaseState, +} from '@fluentui/react-progress'; + +export type ProgressBarSlots = ProgressBarBaseSlots; + +/** + * ProgressBar Props + */ +export type ProgressBarProps = ProgressBarBaseProps; + +/** + * State used in rendering ProgressBar + */ +export type ProgressBarState = ProgressBarBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/__snapshots__/ProgressBar.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/__snapshots__/ProgressBar.test.tsx.snap new file mode 100644 index 0000000000000..3bbfb2fd545e2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/__snapshots__/ProgressBar.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`ProgressBar renders a default state 1`] = ` +
+
+
+
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/index.ts new file mode 100644 index 0000000000000..7c8181a5c39c7 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/index.ts @@ -0,0 +1,4 @@ +export { ProgressBar } from './ProgressBar'; +export type { ProgressBarSlots, ProgressBarProps, ProgressBarState } from './ProgressBar.types'; +export { renderProgressBar } from './renderProgressBar'; +export { useProgressBar } from './useProgressBar'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/renderProgressBar.tsx b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/renderProgressBar.tsx new file mode 100644 index 0000000000000..905b5243737ce --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/renderProgressBar.tsx @@ -0,0 +1,9 @@ +import { renderProgressBar_unstable } from '@fluentui/react-progress'; +import type { JSXElement } from '@fluentui/react-utilities'; + +import type { ProgressBarState } from './ProgressBar.types'; + +/** + * Render the final JSX of ProgressBar + */ +export const renderProgressBar = renderProgressBar_unstable as (state: ProgressBarState) => JSXElement; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/useProgressBar.ts b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/useProgressBar.ts new file mode 100644 index 0000000000000..a348500951a4e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/ProgressBar/useProgressBar.ts @@ -0,0 +1,30 @@ +'use client'; + +import type * as React from 'react'; +import { useProgressBarBase_unstable } from '@fluentui/react-progress'; + +import type { ProgressBarProps, ProgressBarState } from './ProgressBar.types'; + +/** + * Create the state required to render ProgressBar. + * + * The returned state can be modified with hooks, + * before being passed to renderProgressBar_unstable. + * + * @param props - props from this instance of ProgressBar + * @param ref - reference to root HTMLDivElement of ProgressBar + */ +export const useProgressBar = (props: ProgressBarProps, ref: React.Ref): ProgressBarState => { + 'use no memo'; + + const state = useProgressBarBase_unstable(props, ref); + + if (state.bar && state.value !== undefined) { + state.bar.style = { + width: Math.min(100, Math.max(0, (state.value / state.max) * 100)) + '%', + ...state.bar.style, + }; + } + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.tsx b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.tsx new file mode 100644 index 0000000000000..37c67fff8d9a2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.tsx @@ -0,0 +1,17 @@ +'use client'; + +import * as React from 'react'; +import type { RadioProps } from './Radio.types'; +import { useRadio } from './useRadio'; +import { renderRadio } from './renderRadio'; + +/** + * A Radio component for use inside a RadioGroup. + */ +export const Radio = React.forwardRef((props, ref) => { + const state = useRadio(props, ref); + + return renderRadio(state); +}); + +Radio.displayName = 'Radio'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.types.ts new file mode 100644 index 0000000000000..d5579e786d60c --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/Radio.types.ts @@ -0,0 +1,16 @@ +import type { RadioSlots as RadioBaseSlots, RadioBaseProps, RadioBaseState } from '@fluentui/react-radio'; + +/** + * Radio component slots + */ +export type RadioSlots = RadioBaseSlots; + +/** + * Radio component props + */ +export type RadioProps = RadioBaseProps; + +/** + * Radio component state + */ +export type RadioState = RadioBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/index.ts new file mode 100644 index 0000000000000..d5771a3974c95 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/index.ts @@ -0,0 +1,4 @@ +export { Radio } from './Radio'; +export { renderRadio } from './renderRadio'; +export { useRadio } from './useRadio'; +export type { RadioSlots, RadioProps, RadioState } from './Radio.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/renderRadio.tsx b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/renderRadio.tsx new file mode 100644 index 0000000000000..755b32abbb7d6 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/renderRadio.tsx @@ -0,0 +1,6 @@ +import { renderRadio_unstable } from '@fluentui/react-radio'; + +/** + * Renders the final JSX of the Radio component, given the state. + */ +export const renderRadio = renderRadio_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/useRadio.ts b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/useRadio.ts new file mode 100644 index 0000000000000..435c095b9877a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/Radio/useRadio.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useRadioBase_unstable } from '@fluentui/react-radio'; + +import type { RadioProps, RadioState } from './Radio.types'; + +/** + * Returns the state for a Radio component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderRadio`. + */ +export const useRadio = (props: RadioProps, ref: React.Ref): RadioState => { + const state = useRadioBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.test.tsx new file mode 100644 index 0000000000000..45c77eda0791d --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { RadioGroup } from './RadioGroup'; + +describe('RadioGroup', () => { + isConformant({ + Component: RadioGroup, + displayName: 'RadioGroup', + }); + + it('renders a default state', () => { + const result = render(Default RadioGroup); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.tsx b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.tsx new file mode 100644 index 0000000000000..18ee525fb7c58 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.tsx @@ -0,0 +1,21 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { RadioGroupProps } from './RadioGroup.types'; + +import { useRadioGroup } from './useRadioGroup'; +import { renderRadioGroup } from './renderRadioGroup'; +import { useRadioGroupContextValues } from './useRadioGroupContextValues'; + +/** + * A radio group component for selecting one option. + */ +export const RadioGroup: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useRadioGroup(props, ref); + const contextValues = useRadioGroupContextValues(state); + + return renderRadioGroup(state, contextValues); +}); + +RadioGroup.displayName = 'RadioGroup'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.types.ts new file mode 100644 index 0000000000000..23d7cb05ab802 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/RadioGroup.types.ts @@ -0,0 +1,26 @@ +import type { + RadioGroupSlots as RadioGroupBaseSlots, + RadioGroupBaseProps, + RadioGroupBaseState, + RadioGroupContextValues as RadioGroupContextValuesBase, +} from '@fluentui/react-radio'; + +/** + * RadioGroup component slots + */ +export type RadioGroupSlots = RadioGroupBaseSlots; + +/** + * RadioGroup component props + */ +export type RadioGroupProps = RadioGroupBaseProps; + +/** + * RadioGroup component state + */ +export type RadioGroupState = RadioGroupBaseState; + +/** + * RadioGroup component context values + */ +export type RadioGroupContextValues = RadioGroupContextValuesBase; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap new file mode 100644 index 0000000000000..af96da1fab1c2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`RadioGroup renders a default state 1`] = ` +
+
+ Default RadioGroup +
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/index.ts new file mode 100644 index 0000000000000..0227525cd8440 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/index.ts @@ -0,0 +1,7 @@ +export { RadioGroup } from './RadioGroup'; +export { renderRadioGroup } from './renderRadioGroup'; +export { useRadioGroup } from './useRadioGroup'; +export type { RadioGroupSlots, RadioGroupProps, RadioGroupState } from './RadioGroup.types'; + +export { Radio, renderRadio, useRadio } from './Radio'; +export type { RadioSlots, RadioProps, RadioState } from './Radio'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/renderRadioGroup.tsx b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/renderRadioGroup.tsx new file mode 100644 index 0000000000000..9a8edbf465385 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/renderRadioGroup.tsx @@ -0,0 +1,6 @@ +import { renderRadioGroup_unstable } from '@fluentui/react-radio'; + +/** + * Renders the final JSX of the RadioGroup component, given the state. + */ +export const renderRadioGroup = renderRadioGroup_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroup.ts b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroup.ts new file mode 100644 index 0000000000000..343a57345f9dc --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroup.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useRadioGroupBase_unstable } from '@fluentui/react-radio'; + +import type { RadioGroupProps, RadioGroupState } from './RadioGroup.types'; + +/** + * Returns the state for a RadioGroup component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderRadioGroup`. + */ +export const useRadioGroup = (props: RadioGroupProps, ref: React.Ref): RadioGroupState => { + const state = useRadioGroupBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroupContextValues.ts b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroupContextValues.ts new file mode 100644 index 0000000000000..a35741e42159e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/RadioGroup/useRadioGroupContextValues.ts @@ -0,0 +1,8 @@ +'use client'; + +import { useRadioGroupContextValues as useRadioGroupContextValues_unstable } from '@fluentui/react-radio'; +import type { RadioGroupContextValues, RadioGroupState } from './RadioGroup.types'; + +export const useRadioGroupContextValues = useRadioGroupContextValues_unstable as ( + state: RadioGroupState, +) => RadioGroupContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.test.tsx new file mode 100644 index 0000000000000..a366cae60698e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.test.tsx @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Rating } from './Rating'; +import { RatingItem } from './RatingItem'; + +describe('Rating', () => { + isConformant({ + Component: Rating, + displayName: 'Rating', + }); + + it('renders a default state', () => { + const result = render( + + + + + + + , + ); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.tsx new file mode 100644 index 0000000000000..b6acc6635bcb6 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.tsx @@ -0,0 +1,21 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { RatingProps } from './Rating.types'; +import { useRating } from './useRating'; +import { renderRating } from './renderRating'; +import { useRatingContextValues } from './useRatingContextValues'; + +/** + * A rating component for displaying star ratings. + */ +export const Rating: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useRating(props, ref); + const contextValues = useRatingContextValues(state); + + return renderRating(state, contextValues); +}); + +Rating.displayName = 'Rating'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.types.ts new file mode 100644 index 0000000000000..b5c63ce69007e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/Rating.types.ts @@ -0,0 +1,26 @@ +import type { + RatingSlots as RatingBaseSlots, + RatingBaseProps, + RatingBaseState, + RatingContextValues as RatingContextValuesBase, +} from '@fluentui/react-rating'; + +/** + * Rating component slots + */ +export type RatingSlots = RatingBaseSlots; + +/** + * Rating component props + */ +export type RatingProps = RatingBaseProps; + +/** + * Rating component state + */ +export type RatingState = RatingBaseState; + +/** + * Rating component context values + */ +export type RatingContextValues = RatingContextValuesBase; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.tsx new file mode 100644 index 0000000000000..68326ed9ecb1a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.tsx @@ -0,0 +1,17 @@ +'use client'; + +import * as React from 'react'; +import type { RatingItemProps } from './RatingItem.types'; +import { useRatingItem } from './useRatingItem'; +import { renderRatingItem } from './renderRatingItem'; + +/** + * A RatingItem component representing a single star/icon within a Rating. + */ +export const RatingItem = React.forwardRef((props, ref) => { + const state = useRatingItem(props, ref); + + return renderRatingItem(state); +}); + +RatingItem.displayName = 'RatingItem'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.types.ts new file mode 100644 index 0000000000000..3aeb2841ee465 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/RatingItem.types.ts @@ -0,0 +1,20 @@ +import type { + RatingItemSlots as RatingItemBaseSlots, + RatingItemBaseProps, + RatingItemBaseState, +} from '@fluentui/react-rating'; + +/** + * RatingItem component slots + */ +export type RatingItemSlots = RatingItemBaseSlots; + +/** + * RatingItem component props + */ +export type RatingItemProps = RatingItemBaseProps; + +/** + * RatingItem component state + */ +export type RatingItemState = RatingItemBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/index.ts new file mode 100644 index 0000000000000..871ca14f654d4 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/index.ts @@ -0,0 +1,4 @@ +export { RatingItem } from './RatingItem'; +export { renderRatingItem } from './renderRatingItem'; +export { useRatingItem } from './useRatingItem'; +export type { RatingItemSlots, RatingItemProps, RatingItemState } from './RatingItem.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/renderRatingItem.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/renderRatingItem.tsx new file mode 100644 index 0000000000000..c85d3c3fabc25 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/renderRatingItem.tsx @@ -0,0 +1,6 @@ +import { renderRatingItem_unstable } from '@fluentui/react-rating'; + +/** + * Renders the final JSX of the RatingItem component, given the state. + */ +export const renderRatingItem = renderRatingItem_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/useRatingItem.ts b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/useRatingItem.ts new file mode 100644 index 0000000000000..9e0d12e28a357 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/RatingItem/useRatingItem.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useRatingItemBase_unstable } from '@fluentui/react-rating'; + +import type { RatingItemProps, RatingItemState } from './RatingItem.types'; + +/** + * Returns the state for a RatingItem component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderRatingItem`. + */ +export const useRatingItem = (props: RatingItemProps, ref: React.Ref): RatingItemState => { + const state = useRatingItemBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/__snapshots__/Rating.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Rating/__snapshots__/Rating.test.tsx.snap new file mode 100644 index 0000000000000..4e197c2192903 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/__snapshots__/Rating.test.tsx.snap @@ -0,0 +1,76 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Rating renders a default state 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + +
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Rating/index.ts new file mode 100644 index 0000000000000..d4b1d142dde41 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/index.ts @@ -0,0 +1,7 @@ +export { RatingItem, renderRatingItem, useRatingItem } from './RatingItem'; +export type { RatingItemSlots, RatingItemProps, RatingItemState } from './RatingItem/RatingItem.types'; + +export { Rating } from './Rating'; +export { renderRating } from './renderRating'; +export { useRating } from './useRating'; +export type { RatingSlots, RatingProps, RatingState } from './Rating.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/renderRating.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Rating/renderRating.tsx new file mode 100644 index 0000000000000..6fdd0e4ba9bf8 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/renderRating.tsx @@ -0,0 +1,6 @@ +import { renderRating_unstable } from '@fluentui/react-rating'; + +/** + * Renders the final JSX of the Rating component, given the state. + */ +export const renderRating = renderRating_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/useRating.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Rating/useRating.tsx new file mode 100644 index 0000000000000..dc4efb6bf5358 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/useRating.tsx @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useRatingBase_unstable } from '@fluentui/react-rating'; + +import type { RatingProps, RatingState } from './Rating.types'; + +/** + * Returns the state for a Rating component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderRating`. + */ +export const useRating = (props: RatingProps, ref: React.Ref): RatingState => { + const state = useRatingBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Rating/useRatingContextValues.ts b/packages/react-components/react-headless-components-preview/library/src/components/Rating/useRatingContextValues.ts new file mode 100644 index 0000000000000..e571d10ec4b37 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Rating/useRatingContextValues.ts @@ -0,0 +1,6 @@ +'use client'; + +import { useRatingContextValues as useFieldContextValuesBase_unstable } from '@fluentui/react-rating'; +import type { RatingContextValues, RatingState } from './Rating.types'; + +export const useRatingContextValues = useFieldContextValuesBase_unstable as (state: RatingState) => RatingContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/Search.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/Search.types.ts new file mode 100644 index 0000000000000..022cdba5df70c --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/Search.types.ts @@ -0,0 +1,20 @@ +import type { + SearchBoxSlots as SearchBoxBaseSlots, + SearchBoxBaseProps, + SearchBoxBaseState, +} from '@fluentui/react-search'; + +/** + * Search component slots + */ +export type SearchBoxSlots = SearchBoxBaseSlots; + +/** + * Search component props + */ +export type SearchBoxProps = SearchBoxBaseProps; + +/** + * Search component state + */ +export type SearchBoxState = SearchBoxBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.test.tsx new file mode 100644 index 0000000000000..3279fadbc2f63 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { SearchBox } from './SearchBox'; + +describe('SearchBox', () => { + isConformant({ + Component: SearchBox, + displayName: 'SearchBox', + primarySlot: 'input', + }); + + it('renders a default state', () => { + const result = render(); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.tsx b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.tsx new file mode 100644 index 0000000000000..611daf7f7a3ee --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/SearchBox.tsx @@ -0,0 +1,19 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import type { SearchBoxProps } from './Search.types'; +import { useSearchBox } from './useSearchBox'; +import { renderSearchBox } from './renderSearchBox'; + +/** + * A search box component for search input. + */ +export const SearchBox: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useSearchBox(props, ref); + + return renderSearchBox(state); +}); + +SearchBox.displayName = 'SearchBox'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/__snapshots__/SearchBox.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/__snapshots__/SearchBox.test.tsx.snap new file mode 100644 index 0000000000000..905db02c7f017 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/__snapshots__/SearchBox.test.tsx.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`SearchBox renders a default state 1`] = ` +
+ + + + + + + +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/index.ts new file mode 100644 index 0000000000000..dde1ce3b058d2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/index.ts @@ -0,0 +1,4 @@ +export { SearchBox } from './SearchBox'; +export { renderSearchBox } from './renderSearchBox'; +export { useSearchBox as useSearchBox } from './useSearchBox'; +export type { SearchBoxSlots, SearchBoxProps, SearchBoxState } from './Search.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/renderSearchBox.tsx b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/renderSearchBox.tsx new file mode 100644 index 0000000000000..6c17d54d4a6dd --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/renderSearchBox.tsx @@ -0,0 +1,6 @@ +import { renderSearchBox_unstable } from '@fluentui/react-search'; + +/** + * Renders the final JSX of the SearchBox component, given the state. + */ +export const renderSearchBox = renderSearchBox_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/useSearchBox.ts b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/useSearchBox.ts new file mode 100644 index 0000000000000..ab2d7f0d3cb32 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SearchBox/useSearchBox.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useSearchBoxBase_unstable } from '@fluentui/react-search'; + +import type { SearchBoxProps, SearchBoxState } from './Search.types'; + +/** + * Returns the state for a SearchBox component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderSearchBox`. + */ +export const useSearchBox = (props: SearchBoxProps, ref: React.Ref): SearchBoxState => { + const state = useSearchBoxBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.test.tsx new file mode 100644 index 0000000000000..65190bd001839 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.test.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Select } from './Select'; + +describe('Select', () => { + isConformant({ + Component: Select, + displayName: 'Select', + primarySlot: 'select', + }); + + it('renders a default state', () => { + const result = render( + , + ); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.tsx new file mode 100644 index 0000000000000..ba45cf76cd4d6 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.tsx @@ -0,0 +1,19 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; + +import { useSelect } from './useSelect'; +import { renderSelect } from './renderSelect'; +import type { SelectProps } from './Select.types'; + +/** + * Select component - TODO: add more docs + */ +export const Select: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useSelect(props, ref); + + return renderSelect(state); +}); + +Select.displayName = 'Select'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.types.ts new file mode 100644 index 0000000000000..aba4dcfb0c44b --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Select/Select.types.ts @@ -0,0 +1,13 @@ +import type { SelectSlots as SelectBaseSlots, SelectBaseProps, SelectBaseState } from '@fluentui/react-select'; + +export type SelectSlots = SelectBaseSlots; + +/** + * Select Props + */ +export type SelectProps = SelectBaseProps; + +/** + * State used in rendering Select + */ +export type SelectState = SelectBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Select/__snapshots__/Select.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Select/__snapshots__/Select.test.tsx.snap new file mode 100644 index 0000000000000..dd664b6f54287 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Select/__snapshots__/Select.test.tsx.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Select renders a default state 1`] = ` +
+ + + + +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Select/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Select/index.ts new file mode 100644 index 0000000000000..b82efc3cd2c4d --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Select/index.ts @@ -0,0 +1,4 @@ +export { Select } from './Select'; +export type { SelectSlots, SelectProps, SelectState } from './Select.types'; +export { renderSelect } from './renderSelect'; +export { useSelect } from './useSelect'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Select/renderSelect.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Select/renderSelect.tsx new file mode 100644 index 0000000000000..b6de75286f3ec --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Select/renderSelect.tsx @@ -0,0 +1,6 @@ +import { renderSelect_unstable } from '@fluentui/react-select'; + +/** + * Render the final JSX of Select + */ +export const renderSelect = renderSelect_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Select/useSelect.ts b/packages/react-components/react-headless-components-preview/library/src/components/Select/useSelect.ts new file mode 100644 index 0000000000000..ef2b6ee61943d --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Select/useSelect.ts @@ -0,0 +1,19 @@ +'use client'; + +import type * as React from 'react'; +import { useSelectBase_unstable } from '@fluentui/react-select'; +import type { SelectProps, SelectState } from './Select.types'; + +/** + * Create the state required to render Select. + * + * The returned state can be modified with hooks, + * before being passed to renderSelect. + * + * @param props - props from this instance of Select + * @param ref - reference to root HTMLSelectElement + */ +export const useSelect = (props: SelectProps, ref: React.Ref): SelectState => { + const state = useSelectBase_unstable(props, ref); + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.test.tsx new file mode 100644 index 0000000000000..94367cf910172 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Skeleton } from './Skeleton'; + +describe('Skeleton', () => { + isConformant({ + Component: Skeleton, + displayName: 'Skeleton', + }); + + it('renders a default state', () => { + const result = render(Default Skeleton); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.tsx new file mode 100644 index 0000000000000..fbbb2ee923f2a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { SkeletonProps } from './Skeleton.types'; +import { useSkeleton, useSkeletonContextValues } from './useSkeleton'; +import { renderSkeleton } from './renderSkeleton'; + +/** + * A skeleton component for loading placeholders. + */ +export const Skeleton = React.forwardRef((props, ref) => { + const state = useSkeleton(props, ref); + const contextValues = useSkeletonContextValues(state); + + return renderSkeleton(state, contextValues); +}); + +Skeleton.displayName = 'Skeleton'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.types.ts new file mode 100644 index 0000000000000..df885847b1ba7 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/Skeleton.types.ts @@ -0,0 +1,26 @@ +import type { + SkeletonSlots as SkeletonBaseSlots, + SkeletonBaseProps, + SkeletonBaseState, + SkeletonContextValues as SkeletonContextValuesBase, +} from '@fluentui/react-skeleton'; + +/** + * Skeleton component slots + */ +export type SkeletonSlots = SkeletonBaseSlots; + +/** + * Skeleton component props + */ +export type SkeletonProps = SkeletonBaseProps; + +/** + * Skeleton component state + */ +export type SkeletonState = SkeletonBaseState; + +/** + * Skeleton component context values + */ +export type SkeletonContextValues = SkeletonContextValuesBase; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.tsx new file mode 100644 index 0000000000000..33aef85417544 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.tsx @@ -0,0 +1,17 @@ +'use client'; + +import * as React from 'react'; +import type { SkeletonItemProps } from './SkeletonItem.types'; +import { useSkeletonItem } from './useSkeletonItem'; +import { renderSkeletonItem } from './renderSkeletonItem'; + +/** + * A SkeletonItem component for loading placeholders. + */ +export const SkeletonItem = React.forwardRef((props, ref) => { + const state = useSkeletonItem(props, ref); + + return renderSkeletonItem(state); +}); + +SkeletonItem.displayName = 'SkeletonItem'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.types.ts new file mode 100644 index 0000000000000..cf31015dff683 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/SkeletonItem.types.ts @@ -0,0 +1,20 @@ +import type { + SkeletonItemSlots as SkeletonItemBaseSlots, + SkeletonItemBaseProps, + SkeletonItemBaseState, +} from '@fluentui/react-skeleton'; + +/** + * SkeletonItem component slots + */ +export type SkeletonItemSlots = SkeletonItemBaseSlots; + +/** + * SkeletonItem component props + */ +export type SkeletonItemProps = SkeletonItemBaseProps; + +/** + * SkeletonItem component state + */ +export type SkeletonItemState = SkeletonItemBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/index.ts new file mode 100644 index 0000000000000..c1f1988e3a8aa --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/index.ts @@ -0,0 +1,4 @@ +export { SkeletonItem } from './SkeletonItem'; +export { renderSkeletonItem } from './renderSkeletonItem'; +export { useSkeletonItem } from './useSkeletonItem'; +export type { SkeletonItemSlots, SkeletonItemProps, SkeletonItemState } from './SkeletonItem.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/renderSkeletonItem.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/renderSkeletonItem.tsx new file mode 100644 index 0000000000000..f99403783efd2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/renderSkeletonItem.tsx @@ -0,0 +1,6 @@ +import { renderSkeletonItem_unstable } from '@fluentui/react-skeleton'; + +/** + * Renders the final JSX of the SkeletonItem component, given the state. + */ +export const renderSkeletonItem = renderSkeletonItem_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/useSkeletonItem.ts b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/useSkeletonItem.ts new file mode 100644 index 0000000000000..28822bc8af645 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/SkeletonItem/useSkeletonItem.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useSkeletonItemBase_unstable } from '@fluentui/react-skeleton'; + +import type { SkeletonItemProps, SkeletonItemState } from './SkeletonItem.types'; + +/** + * Returns the state for a SkeletonItem component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderSkeletonItem`. + */ +export const useSkeletonItem = (props: SkeletonItemProps, ref: React.Ref): SkeletonItemState => { + const state = useSkeletonItemBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/__snapshots__/Skeleton.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/__snapshots__/Skeleton.test.tsx.snap new file mode 100644 index 0000000000000..7f291387bf40e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/__snapshots__/Skeleton.test.tsx.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Skeleton renders a default state 1`] = ` +
+
+ Default Skeleton +
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/index.ts new file mode 100644 index 0000000000000..93eb84a1fa39d --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/index.ts @@ -0,0 +1,7 @@ +export { SkeletonItem, renderSkeletonItem, useSkeletonItem } from './SkeletonItem'; +export type { SkeletonItemSlots, SkeletonItemProps, SkeletonItemState } from './SkeletonItem/SkeletonItem.types'; + +export { Skeleton } from './Skeleton'; +export { renderSkeleton } from './renderSkeleton'; +export { useSkeleton } from './useSkeleton'; +export type { SkeletonSlots, SkeletonProps, SkeletonState } from './Skeleton.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/renderSkeleton.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/renderSkeleton.tsx new file mode 100644 index 0000000000000..2bc31745425dc --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/renderSkeleton.tsx @@ -0,0 +1,6 @@ +import { renderSkeleton_unstable } from '@fluentui/react-skeleton'; + +/** + * Renders the final JSX of the Skeleton component, given the state. + */ +export const renderSkeleton = renderSkeleton_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/useSkeleton.ts b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/useSkeleton.ts new file mode 100644 index 0000000000000..332f9df9c5b70 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Skeleton/useSkeleton.ts @@ -0,0 +1,23 @@ +'use client'; + +import type * as React from 'react'; +import { + useSkeletonBase_unstable, + useSkeletonContextValues as useSkeletonContextValues_unstable, +} from '@fluentui/react-skeleton'; + +import type { SkeletonProps, SkeletonState, SkeletonContextValues } from './Skeleton.types'; + +/** + * Returns the state for a Skeleton component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderSkeleton`. + */ +export const useSkeleton = (props: SkeletonProps, ref: React.Ref): SkeletonState => { + const state = useSkeletonBase_unstable(props, ref); + + return state; +}; + +export const useSkeletonContextValues = useSkeletonContextValues_unstable as ( + state: SkeletonState, +) => SkeletonContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.test.tsx new file mode 100644 index 0000000000000..5ff9f889c2644 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Slider } from './Slider'; + +describe('Slider', () => { + isConformant({ + Component: Slider, + displayName: 'Slider', + primarySlot: 'input', + }); + + it('renders a default state', () => { + const result = render(); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.tsx new file mode 100644 index 0000000000000..9f937ac1dc517 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { SliderProps } from './Slider.types'; +import { useSlider } from './useSlider'; +import { renderSlider } from './renderSlider'; + +/** + * A slider component for selecting a value in a range. + */ +export const Slider: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useSlider(props, ref); + + return renderSlider(state); +}); + +Slider.displayName = 'Slider'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.types.ts new file mode 100644 index 0000000000000..391b954a17a5a --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Slider/Slider.types.ts @@ -0,0 +1,16 @@ +import type { SliderSlots as SliderBaseSlots, SliderBaseProps, SliderBaseState } from '@fluentui/react-slider'; + +/** + * Slider component slots + */ +export type SliderSlots = SliderBaseSlots; + +/** + * Slider component props + */ +export type SliderProps = SliderBaseProps; + +/** + * Slider component state + */ +export type SliderState = SliderBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Slider/__snapshots__/Slider.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Slider/__snapshots__/Slider.test.tsx.snap new file mode 100644 index 0000000000000..05d5680073ae9 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Slider/__snapshots__/Slider.test.tsx.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Slider renders a default state 1`] = ` +
+
+ +
+
+
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Slider/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Slider/index.ts new file mode 100644 index 0000000000000..679a67e73c73f --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Slider/index.ts @@ -0,0 +1,4 @@ +export { Slider } from './Slider'; +export { renderSlider } from './renderSlider'; +export { useSlider } from './useSlider'; +export type { SliderSlots, SliderProps, SliderState } from './Slider.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Slider/renderSlider.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Slider/renderSlider.tsx new file mode 100644 index 0000000000000..93f9cf3a20971 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Slider/renderSlider.tsx @@ -0,0 +1,6 @@ +import { renderSlider_unstable } from '@fluentui/react-slider'; + +/** + * Renders the final JSX of the Slider component, given the state. + */ +export const renderSlider = renderSlider_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Slider/useSlider.ts b/packages/react-components/react-headless-components-preview/library/src/components/Slider/useSlider.ts new file mode 100644 index 0000000000000..1cf65696b6f86 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Slider/useSlider.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useSliderBase_unstable } from '@fluentui/react-slider'; + +import type { SliderProps, SliderState } from './Slider.types'; + +/** + * Returns the state for a Slider component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderSlider`. + */ +export const useSlider = (props: SliderProps, ref: React.Ref): SliderState => { + const state: SliderState = useSliderBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.test.tsx new file mode 100644 index 0000000000000..9450dd45e65b6 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { SpinButton } from './SpinButton'; + +describe('SpinButton', () => { + isConformant({ + Component: SpinButton, + displayName: 'SpinButton', + primarySlot: 'input', + }); + + it('renders a default state', () => { + const result = render(); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.tsx b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.tsx new file mode 100644 index 0000000000000..47b9c280b601c --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { SpinButtonProps } from './SpinButton.types'; +import { useSpinButton } from './useSpinButton'; +import { renderSpinButton } from './renderSpinButton'; + +/** + * A spin button component for incrementing/decrementing values. + */ +export const SpinButton: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useSpinButton(props, ref); + + return renderSpinButton(state); +}); + +SpinButton.displayName = 'SpinButton'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.types.ts new file mode 100644 index 0000000000000..867729c22bcea --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/SpinButton.types.ts @@ -0,0 +1,20 @@ +import type { + SpinButtonSlots as SpinButtonBaseSlots, + SpinButtonBaseProps, + SpinButtonBaseState, +} from '@fluentui/react-spinbutton'; + +/** + * SpinButton component slots + */ +export type SpinButtonSlots = SpinButtonBaseSlots; + +/** + * SpinButton component props + */ +export type SpinButtonProps = SpinButtonBaseProps; + +/** + * SpinButton component state + */ +export type SpinButtonState = SpinButtonBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/__snapshots__/SpinButton.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/__snapshots__/SpinButton.test.tsx.snap new file mode 100644 index 0000000000000..3e69578070e58 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/__snapshots__/SpinButton.test.tsx.snap @@ -0,0 +1,27 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`SpinButton renders a default state 1`] = ` +
+ + +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/index.ts new file mode 100644 index 0000000000000..c6acde55db924 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/index.ts @@ -0,0 +1,4 @@ +export { SpinButton } from './SpinButton'; +export { renderSpinButton } from './renderSpinButton'; +export { useSpinButton } from './useSpinButton'; +export type { SpinButtonSlots, SpinButtonProps, SpinButtonState } from './SpinButton.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/renderSpinButton.tsx b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/renderSpinButton.tsx new file mode 100644 index 0000000000000..e20dc034670f9 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/renderSpinButton.tsx @@ -0,0 +1,6 @@ +import { renderSpinButton_unstable } from '@fluentui/react-spinbutton'; + +/** + * Renders the final JSX of the SpinButton component, given the state. + */ +export const renderSpinButton = renderSpinButton_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/useSpinButton.ts b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/useSpinButton.ts new file mode 100644 index 0000000000000..0f21e15cd0ad3 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/SpinButton/useSpinButton.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useSpinButtonBase_unstable } from '@fluentui/react-spinbutton'; + +import type { SpinButtonProps, SpinButtonState } from './SpinButton.types'; + +/** + * Returns the state for a SpinButton component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderSpinButton`. + */ +export const useSpinButton = (props: SpinButtonProps, ref: React.Ref): SpinButtonState => { + const state = useSpinButtonBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.test.tsx new file mode 100644 index 0000000000000..c46fcc68f92a6 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Spinner } from './Spinner'; + +describe('Spinner', () => { + isConformant({ + Component: Spinner, + displayName: 'Spinner', + }); + + it('renders a default state', () => { + const result = render(Default Spinner); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.tsx new file mode 100644 index 0000000000000..1d44449ade26e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { SpinnerProps } from './Spinner.types'; +import { useSpinner } from './useSpinner'; +import { renderSpinner } from './renderSpinner'; + +/** + * A spinner component for loading indicators. + */ +export const Spinner: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useSpinner(props, ref); + + return renderSpinner(state); +}); + +Spinner.displayName = 'Spinner'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.types.ts new file mode 100644 index 0000000000000..4b944d1af5aa3 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/Spinner.types.ts @@ -0,0 +1,16 @@ +import type { SpinnerSlots as SpinnerBaseSlots, SpinnerBaseProps, SpinnerBaseState } from '@fluentui/react-spinner'; + +/** + * Spinner component slots + */ +export type SpinnerSlots = SpinnerBaseSlots; + +/** + * Spinner component props + */ +export type SpinnerProps = SpinnerBaseProps; + +/** + * Spinner component state + */ +export type SpinnerState = SpinnerBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Spinner/__snapshots__/Spinner.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/__snapshots__/Spinner.test.tsx.snap new file mode 100644 index 0000000000000..667f48655c194 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/__snapshots__/Spinner.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Spinner renders a default state 1`] = ` +
+
+ + + +
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Spinner/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/index.ts new file mode 100644 index 0000000000000..7c45ff5910c02 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/index.ts @@ -0,0 +1,4 @@ +export { Spinner } from './Spinner'; +export { renderSpinner } from './renderSpinner'; +export { useSpinner } from './useSpinner'; +export type { SpinnerSlots, SpinnerProps, SpinnerState } from './Spinner.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Spinner/renderSpinner.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/renderSpinner.tsx new file mode 100644 index 0000000000000..d0a7b1ecf8615 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/renderSpinner.tsx @@ -0,0 +1,6 @@ +import { renderSpinner_unstable } from '@fluentui/react-spinner'; + +/** + * Renders the final JSX of the Spinner component, given the state. + */ +export const renderSpinner = renderSpinner_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Spinner/useSpinner.ts b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/useSpinner.ts new file mode 100644 index 0000000000000..0b73fbba6f053 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Spinner/useSpinner.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useSpinnerBase_unstable } from '@fluentui/react-spinner'; + +import type { SpinnerProps, SpinnerState } from './Spinner.types'; + +/** + * Returns the state for a Spinner component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderSpinner`. + */ +export const useSpinner = (props: SpinnerProps, ref: React.Ref): SpinnerState => { + const state: SpinnerState = useSpinnerBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.test.tsx new file mode 100644 index 0000000000000..6da4ccb3e7fbc --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Switch } from './Switch'; + +describe('Switch', () => { + isConformant({ + Component: Switch, + displayName: 'Switch', + primarySlot: 'input', + }); + + it('renders a default state', () => { + const result = render(); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.tsx new file mode 100644 index 0000000000000..4bf8930f48ee9 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { SwitchProps } from './Switch.types'; +import { useSwitch } from './useSwitch'; +import { renderSwitch } from './renderSwitch'; + +/** + * A switch component for toggling values. + */ +export const Switch: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useSwitch(props, ref); + + return renderSwitch(state); +}); + +Switch.displayName = 'Switch'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.types.ts new file mode 100644 index 0000000000000..78fb5f1dd534e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Switch/Switch.types.ts @@ -0,0 +1,16 @@ +import type { SwitchSlots as SwitchBaseSlots, SwitchBaseProps, SwitchBaseState } from '@fluentui/react-switch'; + +/** + * Switch component slots + */ +export type SwitchSlots = SwitchBaseSlots; + +/** + * Switch component props + */ +export type SwitchProps = SwitchBaseProps; + +/** + * Switch component state + */ +export type SwitchState = SwitchBaseState; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Switch/__snapshots__/Switch.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/Switch/__snapshots__/Switch.test.tsx.snap new file mode 100644 index 0000000000000..067dff41a4347 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Switch/__snapshots__/Switch.test.tsx.snap @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`Switch renders a default state 1`] = ` +
+
+ + +
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Switch/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/Switch/index.ts new file mode 100644 index 0000000000000..5204770be9dd6 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Switch/index.ts @@ -0,0 +1,4 @@ +export { Switch } from './Switch'; +export { renderSwitch } from './renderSwitch'; +export { useSwitch } from './useSwitch'; +export type { SwitchSlots, SwitchProps, SwitchState } from './Switch.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Switch/renderSwitch.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Switch/renderSwitch.tsx new file mode 100644 index 0000000000000..9fd8c9e984fa8 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Switch/renderSwitch.tsx @@ -0,0 +1,6 @@ +import { renderSwitch_unstable } from '@fluentui/react-switch'; + +/** + * Renders the final JSX of the Switch component, given the state. + */ +export const renderSwitch = renderSwitch_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Switch/useSwitch.ts b/packages/react-components/react-headless-components-preview/library/src/components/Switch/useSwitch.ts new file mode 100644 index 0000000000000..35f3c2d88e0fe --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Switch/useSwitch.ts @@ -0,0 +1,16 @@ +'use client'; + +import type * as React from 'react'; +import { useSwitchBase_unstable } from '@fluentui/react-switch'; + +import type { SwitchProps, SwitchState } from './Switch.types'; + +/** + * Returns the state for a Switch component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderSwitch`. + */ +export const useSwitch = (props: SwitchProps, ref: React.Ref): SwitchState => { + const state = useSwitchBase_unstable(props, ref); + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.tsx b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.tsx new file mode 100644 index 0000000000000..fa044bbfff0b2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.tsx @@ -0,0 +1,18 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { TabProps } from './Tab.types'; +import { useTab } from './useTab'; +import { renderTab } from './renderTab'; + +/** + * A tab component for organizing content. + */ +export const Tab: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useTab(props, ref); + + return renderTab(state); +}); + +Tab.displayName = 'Tab'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.types.ts new file mode 100644 index 0000000000000..9816ddaef0eb2 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/Tab.types.ts @@ -0,0 +1,13 @@ +export type { TabSlots, TabValue } from '@fluentui/react-tabs'; + +import type { TabBaseProps, TabBaseState } from '@fluentui/react-tabs'; + +export type TabProps = TabBaseProps; + +export type TabState = TabBaseState & { + root: { + focusgroupstart?: string; + 'data-icon-only'?: ''; + 'data-selected'?: ''; + }; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/index.ts new file mode 100644 index 0000000000000..08ead275c3335 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/index.ts @@ -0,0 +1,4 @@ +export type { TabSlots, TabValue, TabProps, TabState } from './Tab.types'; +export { Tab } from './Tab'; +export { renderTab } from './renderTab'; +export { useTab } from './useTab'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/renderTab.tsx b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/renderTab.tsx new file mode 100644 index 0000000000000..68322a8d4542e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/renderTab.tsx @@ -0,0 +1,6 @@ +import { renderTab_unstable } from '@fluentui/react-tabs'; + +/** + * Renders the final JSX of the Tab component, given the state. + */ +export const renderTab = renderTab_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/useTab.ts b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/useTab.ts new file mode 100644 index 0000000000000..c4e7928a5c6de --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/Tab/useTab.ts @@ -0,0 +1,23 @@ +'use client'; + +import type * as React from 'react'; +import { useTabBase_unstable } from '@fluentui/react-tabs'; + +import type { TabProps, TabState } from './Tab.types'; + +/** + * Returns the state for a Tab component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderTab`. + */ +export const useTab = (props: TabProps, ref: React.Ref): TabState => { + 'use no memo'; + + const state: TabState = useTabBase_unstable(props, ref); + + state.root.focusgroupstart = state.selected ? '' : undefined; + + state.root['data-icon-only'] = state.iconOnly ? '' : undefined; + state.root['data-selected'] = state.selected ? '' : undefined; + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.test.tsx new file mode 100644 index 0000000000000..9499f39dafe66 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.test.tsx @@ -0,0 +1,16 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { TabList } from './TabList'; + +describe('TabList', () => { + isConformant({ + Component: TabList, + displayName: 'TabList', + }); + + it('renders a default state', () => { + const result = render(Default TabList); + expect(result.container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.tsx b/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.tsx new file mode 100644 index 0000000000000..d5fbd91a6b810 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.tsx @@ -0,0 +1,20 @@ +'use client'; + +import * as React from 'react'; +import type { ForwardRefComponent } from '@fluentui/react-utilities'; +import type { TabListProps } from './TabList.types'; +import { useTabList } from './useTabList'; +import { useTabListContextValues } from './useTabListContextValues'; +import { renderTabList } from './renderTabList'; + +/** + * A tab list component for organizing content. + */ +export const TabList: ForwardRefComponent = React.forwardRef((props, ref) => { + const state = useTabList(props, ref); + const contextValues = useTabListContextValues(state); + + return renderTabList(state, contextValues); +}); + +TabList.displayName = 'TabList'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.types.ts b/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.types.ts new file mode 100644 index 0000000000000..b4a0669346574 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/TabList.types.ts @@ -0,0 +1,30 @@ +import type { + TabListSlots as TabListBaseSlots, + TabListBaseProps, + TabListBaseState, + TabListContextValues as TabListContextValuesBase, +} from '@fluentui/react-tabs'; + +/** + * TabList component slots + */ +export type TabListSlots = TabListBaseSlots; + +/** + * TabList component props + */ +export type TabListProps = TabListBaseProps; + +/** + * TabList component state + */ +export type TabListState = TabListBaseState & { + root: { + focusgroup?: string; + }; +}; + +/** + * TabList component context values + */ +export type TabListContextValues = TabListContextValuesBase; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/__snapshots__/TabList.test.tsx.snap b/packages/react-components/react-headless-components-preview/library/src/components/TabList/__snapshots__/TabList.test.tsx.snap new file mode 100644 index 0000000000000..40421d18e351e --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/__snapshots__/TabList.test.tsx.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`TabList renders a default state 1`] = ` +
+
+ Default TabList +
+
+`; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/index.ts b/packages/react-components/react-headless-components-preview/library/src/components/TabList/index.ts new file mode 100644 index 0000000000000..6b35fd5593fd0 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/index.ts @@ -0,0 +1,7 @@ +export type { TabProps, TabValue, TabSlots, TabState } from './Tab'; +export { Tab, renderTab, useTab } from './Tab'; + +export { TabList } from './TabList'; +export { renderTabList } from './renderTabList'; +export { useTabList } from './useTabList'; +export type { TabListSlots, TabListProps, TabListState } from './TabList.types'; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/renderTabList.tsx b/packages/react-components/react-headless-components-preview/library/src/components/TabList/renderTabList.tsx new file mode 100644 index 0000000000000..9d601f590a86d --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/renderTabList.tsx @@ -0,0 +1,6 @@ +import { renderTabList_unstable } from '@fluentui/react-tabs'; + +/** + * Renders the final JSX of the TabList component, given the state. + */ +export const renderTabList = renderTabList_unstable; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabList.ts b/packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabList.ts new file mode 100644 index 0000000000000..4292c014feb8b --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabList.ts @@ -0,0 +1,20 @@ +'use client'; + +import type * as React from 'react'; +import { useTabListBase_unstable } from '@fluentui/react-tabs'; + +import type { TabListProps, TabListState } from './TabList.types'; + +/** + * Returns the state for a TabList component, given its props and ref. + * The returned state can be modified with hooks before being passed to `renderTabList`. + */ +export const useTabList = (props: TabListProps, ref: React.Ref): TabListState => { + 'use no memo'; + + const state: TabListState = useTabListBase_unstable(props, ref); + + state.root.focusgroup = state.vertical ? 'tablist block wrap no-memory' : 'tablist inline wrap no-memory'; + + return state; +}; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabListContextValues.ts b/packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabListContextValues.ts new file mode 100644 index 0000000000000..f896b23be18a8 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/TabList/useTabListContextValues.ts @@ -0,0 +1,9 @@ +'use client'; + +import { useTabListContextValues_unstable } from '@fluentui/react-tabs'; + +import type { TabListContextValues, TabListState } from './TabList.types'; + +export const useTabListContextValues = useTabListContextValues_unstable as ( + state: TabListState, +) => TabListContextValues; diff --git a/packages/react-components/react-headless-components-preview/library/src/components/Textarea/Textarea.test.tsx b/packages/react-components/react-headless-components-preview/library/src/components/Textarea/Textarea.test.tsx new file mode 100644 index 0000000000000..14a1e30613199 --- /dev/null +++ b/packages/react-components/react-headless-components-preview/library/src/components/Textarea/Textarea.test.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { isConformant } from '../../testing/isConformant'; +import { Textarea } from './Textarea'; + +describe('Textarea', () => { + isConformant({ + Component: Textarea, + displayName: 'Textarea', + primarySlot: 'textarea', + }); + + it('renders a default state', () => { + const result = render(