diff --git a/src/components/Accordion/README.md b/src/components/Accordion/README.md
index 3711f94..d110204 100644
--- a/src/components/Accordion/README.md
+++ b/src/components/Accordion/README.md
@@ -38,15 +38,27 @@ import { MdFavorite } from 'react-icons/md';
```
+### Accordion with a right-aligned button header
+
+```jsx
+import { BBBAccordion } from 'bbb-ui-components-react';
+import { MdEdit } from 'react-icons/md';
+
+} buttonHeaderPosition="right">
+
Content for the accordion.
+
+```
+
## Props
-| Property | Type | Default | Description |
-| ------------------ | -------------------------------------- | ----------- | ------------------------------------------------------------------------------ |
-| `title` | `string` | | The text to be displayed in the accordion header. |
-| `tooltipLabel` | `string` | `null` | An optional label for the tooltip that appears on hover. |
-| `tooltipPlacement` | `import('@tippyjs/react').Placement` | `'bottom'` | The placement of the tooltip. |
-| `ariaLabel` | `string` | | The accessible name for the expand button. |
-| `ariaLabelledBy` | `string` | | The ID of the element that labels the expand button. |
-| `ariaDescribedBy` | `string` | | The ID of the element that describes the expand button. |
-| `buttonHeader` | `React.ReactNode` | `null` | Optional content to be rendered inside the button header. |
-| `children` | `React.ReactNode` | | The content to be displayed when the accordion is expanded. |
+| Property | Type | Default | Description |
+| ----------------------- | -------------------------------------- | ----------- | ------------------------------------------------------------------------------ |
+| `title` | `string` | | The text to be displayed in the accordion header. |
+| `tooltipLabel` | `string` | `null` | An optional label for the tooltip that appears on hover. |
+| `tooltipPlacement` | `import('@tippyjs/react').Placement` | `'bottom'` | The placement of the tooltip. |
+| `ariaLabel` | `string` | | The accessible name for the expand button. |
+| `ariaLabelledBy` | `string` | | The ID of the element that labels the expand button. |
+| `ariaDescribedBy` | `string` | | The ID of the element that describes the expand button. |
+| `buttonHeader` | `React.ReactNode` | `null` | Optional content to be rendered inside the button header. |
+| `buttonHeaderPosition` | `'left' \| 'right'` | `'left'` | Position of `buttonHeader` within the header row. |
+| `children` | `React.ReactNode` | | The content to be displayed when the accordion is expanded. |
diff --git a/src/components/Accordion/component.stories.tsx b/src/components/Accordion/component.stories.tsx
index 7b54464..7a05344 100644
--- a/src/components/Accordion/component.stories.tsx
+++ b/src/components/Accordion/component.stories.tsx
@@ -1,7 +1,14 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import BBBAccordion from './component';
-import { TOOLTIP_PLACEMENT_VALUES, DEFAULT_TOOLTIP_PLACEMENT } from './constants';
+import {
+ TOOLTIP_PLACEMENT_VALUES,
+ DEFAULT_TOOLTIP_PLACEMENT,
+ BUTTON_HEADER_POSITIONS,
+ BUTTON_HEADER_POSITION_VALUES,
+ DEFAULT_BUTTON_HEADER_POSITION,
+} from './constants';
+import { MdEdit } from 'react-icons/md';
import Typography from '../Typography/component';
const meta = {
@@ -44,6 +51,14 @@ const meta = {
control: false,
description: 'Optional React node rendered inside the button header.',
},
+ buttonHeaderPosition: {
+ control: 'select',
+ options: BUTTON_HEADER_POSITION_VALUES,
+ description: 'Position of `buttonHeader` within the header row.',
+ table: {
+ defaultValue: { summary: `${DEFAULT_BUTTON_HEADER_POSITION}` },
+ },
+ },
children: {
control: false,
description: 'Content shown when the accordion is expanded.',
@@ -79,3 +94,17 @@ export const WithTooltip: Story = {
),
},
};
+
+/** Shows `buttonHeaderPosition="right"` pushing the button header to the far edge of the header row. */
+export const WithRightAlignedButtonHeader: Story = {
+ args: {
+ title: 'Right-aligned Button Header',
+ buttonHeader: ,
+ buttonHeaderPosition: BUTTON_HEADER_POSITIONS.RIGHT,
+ children: (
+
+ Accordion content goes here.
+
+ ),
+ },
+};
diff --git a/src/components/Accordion/component.tsx b/src/components/Accordion/component.tsx
index 5fc0753..9524240 100644
--- a/src/components/Accordion/component.tsx
+++ b/src/components/Accordion/component.tsx
@@ -4,7 +4,7 @@ import * as Styled from './styles';
import { MdExpandMore } from 'react-icons/md';
import Tippy from '@tippyjs/react';
import 'tippy.js/dist/tippy.css';
-import { DEFAULT_TOOLTIP_PLACEMENT } from './constants';
+import { DEFAULT_TOOLTIP_PLACEMENT, DEFAULT_BUTTON_HEADER_POSITION } from './constants';
/**
* A customizable Accordion component that allows expanding and collapsing content.
@@ -21,6 +21,7 @@ function Accordion({
ariaLabelledBy,
ariaDescribedBy,
buttonHeader = null,
+ buttonHeaderPosition = DEFAULT_BUTTON_HEADER_POSITION,
children,
}: AccordionProps): JSX.Element {
const [isExpanded, setIsExpanded] = useState(false);
@@ -38,7 +39,9 @@ function Accordion({
{title}
- {buttonHeader}
+
+ {buttonHeader}
+
);
diff --git a/src/components/Accordion/constants.ts b/src/components/Accordion/constants.ts
index 79011e3..6dff066 100644
--- a/src/components/Accordion/constants.ts
+++ b/src/components/Accordion/constants.ts
@@ -7,8 +7,18 @@ const TOOLTIP_PLACEMENTS = {
const TOOLTIP_PLACEMENT_VALUES = Object.values(TOOLTIP_PLACEMENTS);
const DEFAULT_TOOLTIP_PLACEMENT = TOOLTIP_PLACEMENTS.TOP;
+const BUTTON_HEADER_POSITIONS = {
+ LEFT: 'left',
+ RIGHT: 'right',
+} as const;
+const BUTTON_HEADER_POSITION_VALUES = Object.values(BUTTON_HEADER_POSITIONS);
+const DEFAULT_BUTTON_HEADER_POSITION = BUTTON_HEADER_POSITIONS.LEFT;
+
export {
TOOLTIP_PLACEMENTS,
TOOLTIP_PLACEMENT_VALUES,
DEFAULT_TOOLTIP_PLACEMENT,
+ BUTTON_HEADER_POSITIONS,
+ BUTTON_HEADER_POSITION_VALUES,
+ DEFAULT_BUTTON_HEADER_POSITION,
}
\ No newline at end of file
diff --git a/src/components/Accordion/styles.ts b/src/components/Accordion/styles.ts
index 721cbb7..0850835 100644
--- a/src/components/Accordion/styles.ts
+++ b/src/components/Accordion/styles.ts
@@ -2,7 +2,7 @@ import styled from 'styled-components';
import { colorBackgroundLight, colorBrand1, colorTextDefault, colorWhite } from '../../stylesheets/palette';
import { fontSizeDefault } from '../../stylesheets/typography';
import { borderRadiusDefault, spacingMedium, spacingSmall } from '../../stylesheets/sizing';
-import { StyledAccordionContent, StyledExpandIcon } from './types';
+import { StyledAccordionContent, StyledExpandIcon, StyledButtonHeaderWrapper } from './types';
export const ExpandButton = styled.button`
display: flex;
@@ -51,6 +51,12 @@ export const ExpandIcon = styled.div`
}
`;
+export const ButtonHeaderWrapper = styled.span`
+ display: flex;
+ align-items: center;
+ margin-left: ${({ $position }) => ($position === 'right' ? 'auto' : '0')};
+`;
+
export const TitleText = styled.span`
font-size: ${fontSizeDefault};
font-weight: 400;
diff --git a/src/components/Accordion/types.ts b/src/components/Accordion/types.ts
index 87b09e4..2e61837 100644
--- a/src/components/Accordion/types.ts
+++ b/src/components/Accordion/types.ts
@@ -1,4 +1,4 @@
-import { TOOLTIP_PLACEMENT_VALUES } from './constants';
+import { TOOLTIP_PLACEMENT_VALUES, BUTTON_HEADER_POSITION_VALUES } from './constants';
import * as React from 'react';
export interface StyledExpandIcon {
@@ -10,7 +10,12 @@ export interface StyledAccordionContent {
$scrollHeight: number;
}
+export interface StyledButtonHeaderWrapper {
+ $position: ButtonHeaderPositionType;
+}
+
type TooltipPlacementType = typeof TOOLTIP_PLACEMENT_VALUES[number];
+type ButtonHeaderPositionType = typeof BUTTON_HEADER_POSITION_VALUES[number];
export interface AccordionProps {
/** The text to be displayed in the accordion header. */
@@ -34,6 +39,9 @@ export interface AccordionProps {
/** Optional React node rendered inside the button header, alongside the title. @default null */
buttonHeader?: React.ReactNode;
+ /** Position of `buttonHeader` within the header row. @default 'left' */
+ buttonHeaderPosition?: ButtonHeaderPositionType;
+
/** Content shown when the accordion is expanded. */
children?: React.ReactNode;
};