diff --git a/.changeset/wicked-dancers-end.md b/.changeset/wicked-dancers-end.md
new file mode 100644
index 00000000000..1efa6fe3c9b
--- /dev/null
+++ b/.changeset/wicked-dancers-end.md
@@ -0,0 +1,18 @@
+---
+'braid-design-system': minor
+---
+
+---
+updated:
+ - MenuRenderer
+---
+
+**MenuRenderer:** Add `small` size.
+
+Introduce a new `small` size for the `MenuRenderer` component.
+This is available via the `size` prop, which supports the existing `standard` (default) and `small`.
+
+**EXAMPLE USAGE:**
+```jsx
+
+```
diff --git a/packages/braid-design-system/src/lib/components/MenuItem/MenuItem.screenshots.tsx b/packages/braid-design-system/src/lib/components/MenuItem/MenuItem.screenshots.tsx
index 467f40407e1..c1bafd4f1de 100644
--- a/packages/braid-design-system/src/lib/components/MenuItem/MenuItem.screenshots.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuItem/MenuItem.screenshots.tsx
@@ -14,6 +14,7 @@ import { Menu } from '../MenuRenderer/MenuRenderer';
const defaultProps = {
offsetSpace: 'none',
align: 'left',
+ size: 'standard',
width: 'content',
highlightIndex: -1,
open: true,
diff --git a/packages/braid-design-system/src/lib/components/MenuItem/useMenuItem.tsx b/packages/braid-design-system/src/lib/components/MenuItem/useMenuItem.tsx
index 3bfb8e1ae77..3805c994ff7 100644
--- a/packages/braid-design-system/src/lib/components/MenuItem/useMenuItem.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuItem/useMenuItem.tsx
@@ -11,7 +11,6 @@ import React, {
import type { BadgeProps } from '../Badge/Badge';
import { type BoxProps, Box } from '../Box/Box';
import { Text } from '../Text/Text';
-import { touchableText } from '../../css/typography.css';
import { normalizeKey } from '../private/normalizeKey';
import { MenuRendererItemContext } from '../MenuRenderer/MenuRendererItemContext';
import { type Action, actionTypes } from '../MenuRenderer/MenuRenderer.actions';
@@ -25,6 +24,7 @@ import { MenuRendererContext } from '../MenuRenderer/MenuRendererContext';
import { useBraidTheme } from '../BraidProvider/BraidThemeContext';
import { iconSlotSpace } from '../private/iconSlotSpace';
import { badgeSlotSpace } from '../private/badgeSlotSpace';
+import { virtualTouchable } from '../private/touchable/virtualTouchable.css';
const {
MENU_ITEM_UP,
@@ -37,8 +37,6 @@ const {
MENU_ITEM_HOVER,
} = actionTypes;
-const menuItemChildrenSize = 'standard';
-
type MenuItemTone = 'critical' | undefined;
export interface UseMenuItemProps {
@@ -58,10 +56,11 @@ export function useMenuItem({
id,
...restProps
}: UseMenuItemProps) {
+ const menuRendererContext = useContext(MenuRendererContext);
const menuRendererItemContext = useContext(MenuRendererItemContext);
assert(
- menuRendererItemContext !== null,
+ menuRendererContext !== null && menuRendererItemContext !== null,
`${displayName} must be rendered as an immediate child of a menu. See the documentation for correct usage: https://seek-oss.github.io/braid-design-system/components/MenuItem`,
);
@@ -69,6 +68,7 @@ export function useMenuItem({
throw new Error(`${displayName} element rendered outside menu context`);
}
+ const { size } = menuRendererContext;
const { isHighlighted, index, dispatch, focusTrigger } =
menuRendererItemContext;
const menuItemRef = useRef(null);
@@ -155,11 +155,14 @@ export function useMenuItem({
background: isHighlighted ? hoverBackground : undefined,
className: [
styles.menuItem,
- touchableText[menuItemChildrenSize],
+ size === 'small' ? virtualTouchable : undefined,
atoms({
- display: 'block',
+ display: 'flex',
+ alignItems: 'center',
width: 'full',
- paddingX: 'small',
+ paddingX: size === 'standard' ? 'small' : 'small', // todo - with 'small' size - small or xsmall?
+ paddingY: size === 'standard' ? undefined : 'xsmall',
+ height: size === 'standard' ? 'touchable' : undefined,
cursor: 'pointer',
textAlign: 'left',
outline: 'none',
@@ -201,23 +204,24 @@ function MenuItemChildren({
);
let leftSlot: ReactNode = null;
+ const { size, reserveIconSpace } = menuRendererContext;
- if (!formElement) {
- if (icon) {
- leftSlot = (
-
- {icon}
-
- );
- } else if (menuRendererContext.reserveIconSpace) {
- leftSlot = (
-
- );
- }
+ // Todo - fix alignment issue. When reserveIconSpace is true, text is not aligned between items with and without icons
+
+ if (!formElement && (icon || reserveIconSpace)) {
+ leftSlot = (
+
+ {icon || (
+
+
+
+ )}
+
+ );
}
return (
@@ -234,8 +238,7 @@ function MenuItemChildren({
) : null}
diff --git a/packages/braid-design-system/src/lib/components/MenuItemCheckbox/MenuItemCheckbox.screenshots.tsx b/packages/braid-design-system/src/lib/components/MenuItemCheckbox/MenuItemCheckbox.screenshots.tsx
index dd16b6cd5d1..dedd0cd2058 100644
--- a/packages/braid-design-system/src/lib/components/MenuItemCheckbox/MenuItemCheckbox.screenshots.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuItemCheckbox/MenuItemCheckbox.screenshots.tsx
@@ -6,6 +6,7 @@ import { Menu } from '../MenuRenderer/MenuRenderer';
const defaultProps = {
offsetSpace: 'none',
align: 'left',
+ size: 'standard',
width: 'content',
highlightIndex: -1,
open: true,
diff --git a/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.screenshots.tsx b/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.screenshots.tsx
index b6a7f88fc1d..09958a36faf 100644
--- a/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.screenshots.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.screenshots.tsx
@@ -6,6 +6,7 @@ import { Menu } from '../MenuRenderer/MenuRenderer';
const defaultProps = {
offsetSpace: 'none',
align: 'left',
+ size: 'standard',
width: 'content',
highlightIndex: -1,
open: true,
diff --git a/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.tsx b/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.tsx
index 275cedc1b43..bd1683bd282 100644
--- a/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuItemDivider/MenuItemDivider.tsx
@@ -3,6 +3,7 @@ import React, { useContext } from 'react';
import { Box } from '../Box/Box';
import { Divider } from '../Divider/Divider';
import { MenuRendererContext } from '../MenuRenderer/MenuRendererContext';
+import { menuYPadding } from '../MenuRenderer/MenuRenderer.css';
export const MenuItemDivider = () => {
assert(
@@ -11,7 +12,7 @@ export const MenuItemDivider = () => {
);
return (
-
+
);
diff --git a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.css.ts b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.css.ts
index d9dd10770f5..5176d72e584 100644
--- a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.css.ts
+++ b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.css.ts
@@ -7,6 +7,8 @@ import {
import { calc } from '@vanilla-extract/css-utils';
import { vars } from '../../themes/vars.css';
+export const menuYPadding = 'xxsmall';
+
export const backdrop = style({
width: '100vw',
height: '100vh',
@@ -48,5 +50,8 @@ export const width = styleVariants({ small, medium, large }, (w) => [
]);
export const menuHeightLimit = style({
- maxHeight: calc(vars.touchableSize).multiply(9.5).toString(),
+ maxHeight: calc(vars.touchableSize)
+ .multiply(9.5)
+ .add(calc(vars.space[menuYPadding]).multiply(2))
+ .toString(),
});
diff --git a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.docs.tsx b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.docs.tsx
index 8a45b76dcfc..b207984c8e8 100644
--- a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.docs.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.docs.tsx
@@ -173,6 +173,62 @@ const docs: ComponentDocs = {
,
),
},
+ {
+ label: 'Sizes',
+ description: (
+
+ You can customise the size of the menu via the size{' '}
+ prop, which accepts either standard or{' '}
+ small. When using a small trigger
+ element, it is recommended to use the small size for
+ menu.
+
+ ),
+ Example: () =>
+ source(
+
+
+ (
+
+
+ Standard trigger{' '}
+
+
+
+ )}
+ >
+
+ Link
+
+
+
+ (
+
+
+ Small trigger{' '}
+
+
+
+ )}
+ >
+
+ Link
+
+
+ ,
+ ),
+ },
{
label: 'Width',
description: (
diff --git a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.screenshots.tsx b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.screenshots.tsx
index 8220212bd79..10eda9ca281 100644
--- a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.screenshots.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.screenshots.tsx
@@ -18,6 +18,7 @@ import { calc } from '@vanilla-extract/css-utils';
const defaultProps = {
offsetSpace: 'none',
align: 'left',
+ size: 'standard',
width: 'content',
highlightIndex: -1,
open: true,
diff --git a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.tsx b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.tsx
index 17adb7412be..828408195bb 100644
--- a/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.tsx
+++ b/packages/braid-design-system/src/lib/components/MenuRenderer/MenuRenderer.tsx
@@ -26,6 +26,7 @@ import buildDataAttributes, {
import * as styles from './MenuRenderer.css';
import { BraidPortal } from '../BraidPortal/BraidPortal';
import { assignInlineVars } from '@vanilla-extract/dynamic';
+import type { MenuSize } from './MenuRendererTypes';
interface TriggerProps {
'aria-haspopup': boolean;
@@ -51,6 +52,7 @@ export interface MenuRendererProps {
trigger: (props: TriggerProps, state: TriggerState) => ReactNode;
align?: 'left' | 'right';
offsetSpace?: ResponsiveSpace;
+ size?: MenuSize;
width?: keyof typeof styles.width | 'content';
placement?: 'top' | 'bottom';
onOpen?: () => void;
@@ -118,6 +120,7 @@ export const MenuRenderer = ({
onOpen,
onClose,
trigger,
+ size = 'standard',
width = 'content',
align = 'left',
offsetSpace = 'none',
@@ -344,6 +347,7 @@ export const MenuRenderer = ({