Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardise icon slot spacing #1638

Merged
merged 9 commits into from
Oct 29, 2024
22 changes: 22 additions & 0 deletions .changeset/bright-peas-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
'braid-design-system': patch
---

---
updated:
- AccordionItem
- Button
- ButtonLink
- FieldMessage
- Heading
- MenuItem
- MenuItemCheckbox
- Notice
- Rating
- Tab
- Text
---

Standardise icon slot spacing

Normalise the space between the `icon` slot and component content across the system.
13 changes: 13 additions & 0 deletions .changeset/chatty-yaks-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'braid-design-system': patch
---

---
updated:
- Rating
---

**Rating:** Simplify internal layout

Simplify the internal HTML and layout of the `Rating` component.
This change should not affect the appearance or behavior of the component.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import buildDataAttributes, {
type DataAttributeMap,
} from '../private/buildDataAttributes';
import { badgeSlotSpace } from '../private/badgeSlotSpace';
import * as styles from './AccordionItem.css';

const itemSpaceForSize = {
Expand Down Expand Up @@ -145,7 +146,7 @@ export const AccordionItem = ({
<Column>
<Text size={size} weight={weight} tone={tone} icon={icon}>
{badge ? (
<Box component="span" paddingRight="xsmall">
<Box component="span" paddingRight={badgeSlotSpace}>
{label}
</Box>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,6 @@ export const ButtonText = ({
{icon && iconPosition === 'leading' ? (
<AvoidWidowIcon
iconPosition={iconPosition}
space="xsmall"
className={
shouldReducePaddingX || bleed
? null
Expand All @@ -401,7 +400,6 @@ export const ButtonText = ({
{!loading && icon && iconPosition === 'trailing' ? (
<AvoidWidowIcon
iconPosition={iconPosition}
space="xsmall"
className={
shouldReducePaddingX || bleed
? null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import { atoms } from '../../css/atoms/atoms';
import { iconSize } from '../../hooks/useIcon';
import * as styles from './useMenuItem.css';
import { MenuRendererContext } from '../MenuRenderer/MenuRendererContext';
import { useBraidTheme } from '../BraidProvider/BraidThemeContext';
import { iconSlotSpace } from '../private/iconSlotSpace';
import { badgeSlotSpace } from '../private/badgeSlotSpace';

const {
MENU_ITEM_UP,
Expand All @@ -35,7 +38,6 @@ const {
} = actionTypes;

const menuItemChildrenSize = 'standard';
const menuItemPaddingSize = 'small';

type MenuItemTone = 'critical' | undefined;

Expand Down Expand Up @@ -157,7 +159,7 @@ export function useMenuItem<MenuItemElement extends HTMLElement>({
atoms({
display: 'block',
width: 'full',
paddingX: menuItemPaddingSize,
paddingX: 'small',
cursor: 'pointer',
textAlign: 'left',
outline: 'none',
Expand All @@ -183,6 +185,9 @@ function MenuItemChildren({
formElement = false,
}: MenuItemChildrenProps) {
const menuRendererContext = useContext(MenuRendererContext);
const legacy = useBraidTheme().legacy;
const iconSpace = legacy ? 'small' : iconSlotSpace;
const badgeSpace = legacy ? 'small' : badgeSlotSpace;

assert(
menuRendererContext !== null,
Expand Down Expand Up @@ -220,7 +225,7 @@ function MenuItemChildren({
{leftSlot ? (
<Box
component="span"
paddingRight={menuItemPaddingSize}
paddingRight={iconSpace}
flexShrink={0}
minWidth={0}
>
Expand All @@ -240,7 +245,7 @@ function MenuItemChildren({
{badge ? (
<Box
component="span"
paddingLeft={menuItemPaddingSize}
paddingLeft={badgeSpace}
flexShrink={0}
minWidth={0}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Box } from '../Box/Box';
import { IconTick } from '../icons/IconTick/IconTick';
import type { MenuItemProps } from '../MenuItem/MenuItem';
import { useMenuItem } from '../MenuItem/useMenuItem';
import { iconSlotSpace } from '../private/iconSlotSpace';
import { useBraidTheme } from '../BraidProvider/BraidThemeContext';

import * as styles from './MenuItemCheckbox.css';

Expand All @@ -26,6 +28,8 @@ export const MenuItemCheckbox = ({
data,
id,
});
const legacy = useBraidTheme().legacy;
const iconSpace = legacy ? 'xsmall' : iconSlotSpace;

return (
<Box
Expand All @@ -43,7 +47,7 @@ export const MenuItemCheckbox = ({
boxShadow="borderField"
position="relative"
background={{ lightMode: 'surface' }}
marginRight="xsmall"
marginRight={iconSpace}
flexShrink={0}
className={styles.checkboxSize}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DefaultTextPropsProvider } from '../private/defaultTextProps';
import buildDataAttributes, {
type DataAttributeMap,
} from '../private/buildDataAttributes';
import { iconSlotSpace } from '../private/iconSlotSpace';

type Tone = 'promote' | 'info' | 'positive' | 'critical';

Expand Down Expand Up @@ -40,7 +41,7 @@ export const Notice = ({
{...buildDataAttributes({ data, validateRestProps: restProps })}
>
<DefaultTextPropsProvider tone={tone}>
<Columns space="xsmall">
<Columns space={iconSlotSpace}>
<Column width="content">
<Text>
<Icon />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ export const darkModeStarColor = style(
}),
);

export const starSpacing = style({
paddingRight: '1px',
});

export const textSpacing = style({
paddingLeft: '0.4em',
export const inlineFlex = style({
display: 'inline-flex',
gap: '1px',
});
64 changes: 29 additions & 35 deletions packages/braid-design-system/src/lib/components/Rating/Rating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import React from 'react';
import assert from 'assert';
import dedent from 'dedent';
import { useBackground } from '../Box/BackgroundContext';
import useIcon, { type UseIconProps } from '../../hooks/useIcon';
import type { UseIconProps } from '../../hooks/useIcon';
import { Box } from '../Box/Box';
import { type TextProps, Text } from '../Text/Text';
import { IconStarSvg as IconStarEmptySvg } from '../icons/IconStar/IconStarSvg';
import { IconStarHalfSvg } from '../icons/IconStar/IconStarHalfSvg';
import { IconContainer } from '../icons/IconContainer';
import { IconStarActiveSvg as IconStarFullSvg } from '../icons/IconStar/IconStarActiveSvg';
import { iconSlotSpace } from '../private/iconSlotSpace';
import * as styles from './Rating.css';

const getPercent = (rating: number, position: number) =>
Expand All @@ -18,10 +20,6 @@ type RatingStar = {
} & UseIconProps;
const RatingStar = ({ percent, ...restProps }: RatingStar) => {
const currentBg = useBackground();
const {
svgProps: { className, ...svgProps },
} = useIcon(restProps);

let component = IconStarEmptySvg;

if (percent >= 25 && percent < 75) {
Expand All @@ -33,21 +31,27 @@ const RatingStar = ({ percent, ...restProps }: RatingStar) => {
}

return (
<Box
component={component}
{...svgProps}
className={[
className,
{
[styles.lightModeStarColor]:
currentBg.lightMode === 'body' || currentBg.lightMode === 'surface',
},
{
[styles.darkModeStarColor]:
currentBg.darkMode === 'body' || currentBg.darkMode === 'surface',
},
]}
/>
<IconContainer {...restProps}>
{({ className, ...svgProps }) => (
<Box
component={component}
{...svgProps}
className={[
className,
{
[styles.lightModeStarColor]:
currentBg.lightMode === 'body' ||
currentBg.lightMode === 'surface',
},
{
[styles.darkModeStarColor]:
currentBg.darkMode === 'body' ||
currentBg.darkMode === 'surface',
},
]}
/>
)}
</IconContainer>
);
};

Expand Down Expand Up @@ -102,32 +106,22 @@ export const Rating = ({
return (
<Text size={size} data={data} weight={weight}>
<Box
display="inlineBlock"
component="span"
className={styles.inlineFlex}
aria-label={
ariaLabel || `${rating.toFixed(1)} out of ${ratingArr.length}`
}
>
{variant === 'minimal' ? (
<Box display="inlineBlock" aria-hidden={true}>
<RatingStar percent={100} />
</Box>
<RatingStar percent={100} />
) : (
ratingArr.map((_, position) => (
<Box
key={position}
display="inlineBlock"
aria-hidden={true}
className={{
[styles.starSpacing]: position !== ratingArr.length - 1,
}}
>
<RatingStar percent={getPercent(rating, position)} />
</Box>
<RatingStar key={position} percent={getPercent(rating, position)} />
))
)}
</Box>
{variant !== 'starsOnly' && (
<Box component="span" className={styles.textSpacing} aria-hidden={true}>
<Box component="span" paddingLeft={iconSlotSpace} aria-hidden={true}>
{rating.toFixed(1)}
</Box>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { useResponsiveValue } from '../useResponsiveValue/useResponsiveValue';
import { smoothScroll, smoothScrollIntoView } from '../private/smoothScroll';
import { useSpace } from '../useSpace/useSpace';
import type { BraidTokens } from '../../themes/tokenType';
import { badgeSlotSpace } from '../private/badgeSlotSpace';
import * as styles from './Tabs.css';

export interface TabProps {
Expand Down Expand Up @@ -294,7 +295,7 @@ export const Tab = ({
</Box>

{badge ? (
<Box component="span" paddingLeft="xsmall">
<Box component="span" paddingLeft={badgeSlotSpace}>
{cloneElement(badge, { bleedY: true })}
</Box>
) : null}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import type { Space } from '../../../css/atoms/atoms';
import { type BoxProps, Box } from '../../Box/Box';
import { iconSlotSpace } from '../iconSlotSpace';

import * as styles from './AvoidWidowIcon.css';

Expand All @@ -12,13 +13,12 @@ interface Props extends Pick<BoxProps, 'children' | 'className'> {
export const AvoidWidowIcon = ({
children,
iconPosition,
space = 'xxsmall',
className,
}: Props) => (
<Box
component="span"
paddingRight={iconPosition === 'leading' ? space : undefined}
paddingLeft={iconPosition === 'trailing' ? space : undefined}
paddingRight={iconPosition === 'leading' ? iconSlotSpace : undefined}
paddingLeft={iconPosition === 'trailing' ? iconSlotSpace : undefined}
className={[styles.nowrap, className]}
aria-hidden
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
StyledInput,
} from './StyledInput';
import { virtualTouchable } from '../touchable/virtualTouchable.css';
import { badgeSlotSpace } from '../badgeSlotSpace';
import * as styles from './InlineField.css';

interface InlineFieldBaseProps {
Expand Down Expand Up @@ -130,7 +131,7 @@ export const InlineField = forwardRef<
size={size}
>
{badge ? (
<Box component="span" paddingRight="xsmall">
<Box component="span" paddingRight={badgeSlotSpace}>
{label}
</Box>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { MaxLines } from '../MaxLines/MaxLines';
import type { UseIconProps } from '../../../hooks/useIcon';
import { alignToFlexAlign } from '../../../utils/align';
import { descenderCropFixForWebkitBox } from '../MaxLines/MaxLines.css';
import { iconSlotSpace } from '../iconSlotSpace';

export interface TypographyProps extends Pick<BoxProps, 'id' | 'component'> {
children?: ReactNode;
Expand Down Expand Up @@ -59,7 +60,7 @@ export const Typography = ({
<Box
component="span"
display="block"
paddingRight="xsmall"
paddingRight={iconSlotSpace}
flexGrow={0}
flexShrink={0}
minWidth={0}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const badgeSlotSpace = 'xsmall';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const iconSlotSpace = 'xxsmall';