From 8334bd0847504e702c9ccf5e2c927b98fc4c410f Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Wed, 8 Jan 2025 17:21:07 +0800 Subject: [PATCH] Add orientation prop --- docs/reference/generated/separator.json | 5 ++ .../demos/hero/css-modules/index.tsx | 2 +- .../separator/demos/hero/tailwind/index.tsx | 2 +- .../react/src/separator/Separator.test.tsx | 9 ++++ packages/react/src/separator/Separator.tsx | 52 ++++++++++++++----- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/docs/reference/generated/separator.json b/docs/reference/generated/separator.json index fade8f11aa..626fa8915c 100644 --- a/docs/reference/generated/separator.json +++ b/docs/reference/generated/separator.json @@ -2,6 +2,11 @@ "name": "Separator", "description": "A separator element accessible to screen readers.\nRenders a `
` element.", "props": { + "orientation": { + "type": "'horizontal' | 'vertical'", + "default": "'horizontal'", + "description": "The component orientation." + }, "className": { "type": "string | (state) => string", "description": "CSS class applied to the element, or a function that\nreturns a class based on the component’s state." diff --git a/docs/src/app/(public)/(content)/react/components/separator/demos/hero/css-modules/index.tsx b/docs/src/app/(public)/(content)/react/components/separator/demos/hero/css-modules/index.tsx index 024ebb4266..b9cfbd2710 100644 --- a/docs/src/app/(public)/(content)/react/components/separator/demos/hero/css-modules/index.tsx +++ b/docs/src/app/(public)/(content)/react/components/separator/demos/hero/css-modules/index.tsx @@ -18,7 +18,7 @@ export default function ExampleSeparator() { Support - + Log in diff --git a/docs/src/app/(public)/(content)/react/components/separator/demos/hero/tailwind/index.tsx b/docs/src/app/(public)/(content)/react/components/separator/demos/hero/tailwind/index.tsx index 325ff5d36c..89268dd5c0 100644 --- a/docs/src/app/(public)/(content)/react/components/separator/demos/hero/tailwind/index.tsx +++ b/docs/src/app/(public)/(content)/react/components/separator/demos/hero/tailwind/index.tsx @@ -29,7 +29,7 @@ export default function ExampleSeparator() { Support - + ', () => { const { getByRole } = await render(); expect(getByRole('separator')).toBeVisible(); }); + + describe('prop: orientation', () => { + ['horizontal', 'vertical'].forEach((orientation) => { + it(orientation, async () => { + const { getByRole } = await render(); + expect(getByRole('separator')).to.have.attribute('aria-orientation', orientation); + }); + }); + }); }); diff --git a/packages/react/src/separator/Separator.tsx b/packages/react/src/separator/Separator.tsx index 9c6c3f9115..624e6ac000 100644 --- a/packages/react/src/separator/Separator.tsx +++ b/packages/react/src/separator/Separator.tsx @@ -2,10 +2,9 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import type { BaseUIComponentProps } from '../utils/types'; +import { mergeReactProps } from '../utils/mergeReactProps'; import { useComponentRenderer } from '../utils/useComponentRenderer'; -const EMPTY_OBJECT = {}; - /** * A separator element accessible to screen readers. * Renders a `
` element. @@ -16,12 +15,23 @@ const Separator = React.forwardRef(function SeparatorComponent( props: Separator.Props, forwardedRef: React.ForwardedRef, ) { - const { className, render, ...other } = props; + const { className, render, orientation = 'horizontal', ...other } = props; + + const state: Separator.State = React.useMemo(() => ({ orientation }), [orientation]); + + const getSeparatorProps = React.useCallback( + (externalProps = {}) => + mergeReactProps(externalProps, { + 'aria-orientation': orientation, + }), + [orientation], + ); const { renderElement } = useComponentRenderer({ + propGetter: getSeparatorProps, render: render ?? 'div', className, - state: EMPTY_OBJECT, + state, extraProps: { role: 'separator', ...other }, ref: forwardedRef, }); @@ -29,6 +39,27 @@ const Separator = React.forwardRef(function SeparatorComponent( return renderElement(); }); +type Orientation = 'horizontal' | 'vertical'; + +namespace Separator { + export interface Props extends BaseUIComponentProps<'div', State> { + /** + * The component orientation. + * @default 'horizontal' + */ + orientation?: Orientation; + } + + export interface State { + /** + * The component orientation. + */ + orientation: Orientation; + } +} + +export { Separator }; + Separator.propTypes /* remove-proptypes */ = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ @@ -43,6 +74,11 @@ Separator.propTypes /* remove-proptypes */ = { * returns a class based on the component’s state. */ className: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), + /** + * The component orientation. + * @default 'horizontal' + */ + orientation: PropTypes.oneOf(['horizontal', 'vertical']), /** * Allows you to replace the component’s HTML element * with a different tag, or compose it with another component. @@ -51,11 +87,3 @@ Separator.propTypes /* remove-proptypes */ = { */ render: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), } as any; - -namespace Separator { - export interface Props extends BaseUIComponentProps<'div', State> {} - - export interface State {} -} - -export { Separator };