Skip to content

Commit

Permalink
feat(react-tags): add styles for size (microsoft#28229)
Browse files Browse the repository at this point in the history
* WIP

* polish sizes and add examples

* HACK force tag on PR docsite

* make styles nicer

* stories

* reset

* group style

* update story description

* remove pr publish story hack
  • Loading branch information
YuanboXue-Amber authored Jun 20, 2023
1 parent 8189321 commit 81c9b35
Show file tree
Hide file tree
Showing 10 changed files with 525 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { useTagGroupContext_unstable } from '../../contexts/TagGroupContext';

const tagAvatarSizeMap = {
medium: 28,
small: 24,
'extra-small': 20,
small: 20,
'extra-small': 16,
} as const;

const tagAvatarShapeMap = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,172 +14,271 @@ export const tagClassNames: SlotClassNames<TagSlots> = {
};

/**
* Base styles shared by Tag/TagButton
* Inner horizontal space left and right of Tag
*/
export const useTagBaseStyles = makeStyles({
media: {
...shorthands.gridArea('media'),
alignSelf: 'center',
paddingLeft: tokens.spacingHorizontalXXS,
paddingRight: tokens.spacingHorizontalS,
},
icon: {
...shorthands.gridArea('media'),
display: 'flex',
alignSelf: 'center',
paddingLeft: '6px',
paddingRight: '2px',
},
primaryText: {
gridColumnStart: 'primary',
gridRowStart: 'primary',
gridRowEnd: 'secondary',
...typographyStyles.body1,
paddingLeft: tokens.spacingHorizontalXXS,
paddingRight: tokens.spacingHorizontalXXS,
whiteSpace: 'nowrap',
},
primaryTextWithSecondaryText: {
...shorthands.gridArea('primary'),
...typographyStyles.caption1,
},
secondaryText: {
...shorthands.gridArea('secondary'),
paddingLeft: tokens.spacingHorizontalXXS,
paddingRight: tokens.spacingHorizontalXXS,
...typographyStyles.caption2,
whiteSpace: 'nowrap',
},
});
const tagSpacingMedium = '7px';
const tagSpacingSmall = '5px';
const tagSpacingExtraSmall = '5px';

const mediumIconSize = '20px';
const smallIconSize = '16px';
const extraSmallIconSize = '12px';

const useRootStyles = makeStyles({
base: {
// TODO use makeResetStyle when styles are settled

export const useResetButtonStyles = makeStyles({
resetButton: {
color: 'inherit',
// reset default button style:
fontFamily: 'inherit',
lineHeight: 'normal',
...shorthands.overflow('visible'),
...shorthands.padding(0),
...shorthands.borderStyle('none'),
appearance: 'button',
textAlign: 'unset',
backgroundColor: 'transparent',
},
});

const useTagStyles = makeStyles({
root: {
// TODO use makeResetStyle when styles are settled
display: 'inline-grid',
alignItems: 'center',
gridTemplateRows: '1fr auto auto 1fr',
gridTemplateAreas: `
"media . dismissIcon"
"media primary dismissIcon"
"media secondary dismissIcon"
"media . dismissIcon"
`,

boxSizing: 'border-box',
height: '32px',
width: 'fit-content',
...shorthands.borderRadius(tokens.borderRadiusMedium),

backgroundColor: tokens.colorNeutralBackground3,
color: tokens.colorNeutralForeground2,
...shorthands.border(tokens.strokeWidthThin, 'solid', tokens.colorTransparentStroke),

':hover': {
cursor: 'pointer',
},
},

rounded: {
...shorthands.borderRadius(tokens.borderRadiusMedium),
...createCustomFocusIndicatorStyle(
{
...shorthands.borderRadius(tokens.borderRadiusMedium),
...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorStrokeFocus2),
},
{ enableOutline: true },
),

':hover': {
cursor: 'pointer',
},
},
rootCircular: {
circular: {
...shorthands.borderRadius(tokens.borderRadiusCircular),
...createCustomFocusIndicatorStyle({
...shorthands.borderRadius(tokens.borderRadiusCircular),
}),
...createCustomFocusIndicatorStyle(
{
...shorthands.borderRadius(tokens.borderRadiusCircular),
...shorthands.outline(tokens.strokeWidthThick, 'solid', tokens.colorStrokeFocus2),
},
{ enableOutline: true },
),
},

medium: {
height: '32px',
},
small: {
height: '24px',
},
'extra-small': {
height: '20px',
},
});
/**
* Styles for root slot when Tag is without leading media/icon
*/
const useRootWithoutMediaStyles = makeStyles({
medium: {
paddingLeft: tagSpacingMedium,
},
small: {
paddingLeft: tagSpacingSmall,
},
rootWithoutMedia: {
paddingLeft: tokens.spacingHorizontalS,
'extra-small': {
paddingLeft: tagSpacingExtraSmall,
},
rootWithoutDismiss: {
});
/**
* Styles for root slot when Tag is without dismiss icon
*/
const useRootWithoutDismissStyles = makeStyles({
medium: {
paddingRight: tagSpacingMedium,
},
small: {
paddingRight: tagSpacingSmall,
},
'extra-small': {
paddingRight: tagSpacingExtraSmall,
},
});

export const useIconStyles = makeStyles({
base: {
...shorthands.gridArea('media'),
display: 'flex',
},
medium: {
paddingLeft: tagSpacingMedium,
paddingRight: tokens.spacingHorizontalXS,
width: mediumIconSize,
fontSize: mediumIconSize,
},
small: {
paddingLeft: tagSpacingSmall,
paddingRight: tokens.spacingHorizontalXXS,
width: smallIconSize,
fontSize: smallIconSize,
},
'extra-small': {
paddingLeft: tagSpacingExtraSmall,
paddingRight: tokens.spacingHorizontalXXS,
width: extraSmallIconSize,
fontSize: extraSmallIconSize,
},
});

export const useMediaStyles = makeStyles({
base: {
...shorthands.gridArea('media'),
display: 'flex',
paddingLeft: '1px',
},
medium: {
paddingRight: tokens.spacingHorizontalS,
},
small: {
paddingRight: tokens.spacingHorizontalSNudge,
},
'extra-small': {
paddingRight: tokens.spacingHorizontalSNudge,
},
});

dismissIcon: {
const useDismissIconStyles = makeStyles({
base: {
...shorthands.gridArea('dismissIcon'),
display: 'flex',
alignItems: 'center',
fontSize: '20px',
paddingLeft: '2px',
paddingRight: '6px',
},
medium: {
paddingLeft: tokens.spacingHorizontalXS,
paddingRight: tagSpacingMedium,
fontSize: mediumIconSize,
},
small: {
paddingLeft: tokens.spacingHorizontalXXS,
paddingRight: tagSpacingSmall,
fontSize: smallIconSize,
},
'extra-small': {
paddingLeft: tokens.spacingHorizontalXXS,
paddingRight: tagSpacingExtraSmall,
fontSize: extraSmallIconSize,
},
});

export const usePrimaryTextStyles = makeStyles({
base: {
whiteSpace: 'nowrap',
paddingLeft: tokens.spacingHorizontalXXS,
paddingRight: tokens.spacingHorizontalXXS,
},

medium: {
...typographyStyles.body1,
},
small: {
...typographyStyles.caption1,
},
'extra-small': {
...typographyStyles.caption1,
},

// TODO add additional classes for fill/outline appearance, different sizes, and state
withoutSecondaryText: {
gridColumnStart: 'primary',
gridRowStart: 'primary',
gridRowEnd: 'secondary',
paddingBottom: tokens.spacingHorizontalXXS,
},
withSecondaryText: {
...shorthands.gridArea('primary'),
...typographyStyles.caption1,
marginTop: '-2px',
},
});

const useSmallTagStyles = makeStyles({
root: {
height: '24px',
export const useSecondaryTextStyles = makeStyles({
base: {
...shorthands.gridArea('secondary'),
paddingLeft: tokens.spacingHorizontalXXS,
paddingRight: tokens.spacingHorizontalXXS,
...typographyStyles.caption2,
whiteSpace: 'nowrap',
},
// TODO add additional styles for sizes
});

/**
* Apply styling to the Tag slots based on the state
*/
export const useTagStyles_unstable = (state: TagState): TagState => {
const baseStyles = useTagBaseStyles();
const resetButtonStyles = useResetButtonStyles();
const styles = useTagStyles();
const smallStyles = useSmallTagStyles();
const rootStyles = useRootStyles();
const rootWithoutMediaStyles = useRootWithoutMediaStyles();
const rootWithoutDismissStyles = useRootWithoutDismissStyles();

const iconStyles = useIconStyles();
const mediaStyles = useMediaStyles();
const dismissIconStyles = useDismissIconStyles();
const primaryTextStyles = usePrimaryTextStyles();
const secondaryTextStyles = useSecondaryTextStyles();

const { shape, size } = state;

state.root.className = mergeClasses(
tagClassNames.root,
resetButtonStyles.resetButton,

styles.root,
state.shape === 'circular' && styles.rootCircular,
!state.media && !state.icon && styles.rootWithoutMedia,
!state.dismissIcon && styles.rootWithoutDismiss,
rootStyles.base,
rootStyles[shape],
rootStyles[size],

state.size === 'small' && smallStyles.root,
!state.media && !state.icon && rootWithoutMediaStyles[size],
!state.dismissIcon && rootWithoutDismissStyles[size],

state.root.className,
);

if (state.media) {
state.media.className = mergeClasses(tagClassNames.media, baseStyles.media, state.media.className);
state.media.className = mergeClasses(
tagClassNames.media,
mediaStyles.base,
mediaStyles[size],
state.media.className,
);
}
if (state.icon) {
state.icon.className = mergeClasses(tagClassNames.icon, baseStyles.icon, state.icon.className);
state.icon.className = mergeClasses(tagClassNames.icon, iconStyles.base, iconStyles[size], state.icon.className);
}
if (state.primaryText) {
state.primaryText.className = mergeClasses(
tagClassNames.primaryText,
baseStyles.primaryText,
state.secondaryText && baseStyles.primaryTextWithSecondaryText,

primaryTextStyles.base,
primaryTextStyles[size],

state.secondaryText ? primaryTextStyles.withSecondaryText : primaryTextStyles.withoutSecondaryText,

state.primaryText.className,
);
}
if (state.secondaryText) {
state.secondaryText.className = mergeClasses(
tagClassNames.secondaryText,
baseStyles.secondaryText,
secondaryTextStyles.base,
state.secondaryText.className,
);
}
if (state.dismissIcon) {
state.dismissIcon.className = mergeClasses(
tagClassNames.dismissIcon,
styles.dismissIcon,
dismissIconStyles.base,
dismissIconStyles[size],
state.dismissIcon.className,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { useTagGroupContext_unstable } from '../../contexts/TagGroupContext';

const tagButtonAvatarSizeMap = {
medium: 28,
small: 24,
'extra-small': 20,
small: 20,
'extra-small': 16,
} as const;

const tagButtonAvatarShapeMap = {
Expand Down
Loading

0 comments on commit 81c9b35

Please sign in to comment.