diff --git a/packages/@react-spectrum/s2/src/ActionButton.tsx b/packages/@react-spectrum/s2/src/ActionButton.tsx index 970dd19c044..b480f818f81 100644 --- a/packages/@react-spectrum/s2/src/ActionButton.tsx +++ b/packages/@react-spectrum/s2/src/ActionButton.tsx @@ -280,7 +280,7 @@ export const btnStyles = style< }, '--iconWidth': { type: 'width', - value: fontRelative(20) + value: '1lh' }, '--badgePosition': { type: 'width', @@ -306,15 +306,6 @@ export const btnStyles = style< getAllowedOverrides() ); -// Matching icon sizes. TBD. -const avatarSize: Record, number> = { - XS: 14, - S: 16, - M: 20, - L: 22, - XL: 26 -} as const; - interface ActionButtonContextProps extends Partial { holdAffordance?: boolean; } @@ -402,7 +393,7 @@ export const ActionButton = forwardRef(function ActionButton( { render: centerBaseline({slot: 'icon', styles: style({gridArea: 'icon'})}), styles: style({ - size: fontRelative(20), + size: '1lh', marginStart: '--iconMargin', visibility: { isProgressVisible: 'hidden' @@ -413,7 +404,7 @@ export const ActionButton = forwardRef(function ActionButton( [ AvatarContext, { - size: avatarSize[size], + size: '1lh', styles: style({ marginStart: '--iconMargin', gridArea: 'icon' diff --git a/packages/@react-spectrum/s2/src/Avatar.tsx b/packages/@react-spectrum/s2/src/Avatar.tsx index 20c8347a5ba..9cbb8f625bb 100644 --- a/packages/@react-spectrum/s2/src/Avatar.tsx +++ b/packages/@react-spectrum/s2/src/Avatar.tsx @@ -38,7 +38,23 @@ export interface AvatarProps extends UnsafeStyles, DOMProps, SlotProps { * * @default 24 */ - size?: 16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 56 | 64 | 80 | 96 | 112 | (number & {}); + size?: + | 16 + | 20 + | 24 + | 28 + | 32 + | 36 + | 40 + | 44 + | 48 + | 56 + | 64 + | 80 + | 96 + | 112 + | (number & {}) + | `${number}lh`; /** Whether the avatar is over a color background. */ isOverBackground?: boolean; } @@ -59,7 +75,9 @@ const imageStyles = style( outlineColor: '--s2-container-bg', outlineWidth: { default: 1, - isLarge: 2 + isLarge: 2, + // if bigger than 64px, use 2px outline, otherwise use 1px outline + isLH: 'min(2px, max(1px, calc((((1lh / 64) - 1px) * 9999) + 1px)))' } }, getAllowedOverrides({width: false}) @@ -90,8 +108,16 @@ export const Avatar = forwardRef(function Avatar( const domProps = filterDOMProps(otherProps); // In the docs build, we need to be able to simulate font scaling. - let remSize = isDocsEnv() ? `calc(${size / 16} * var(--rem, 1rem))` : `${size / 16}rem`; - let isLarge = size >= 64; + let remSize; + let isLarge = false; + let isLH = false; + if (typeof size === 'string') { + remSize = size; + isLH = size.endsWith('lh'); + } else { + remSize = isDocsEnv() ? `calc(${size / 16} * var(--rem, 1rem))` : `${size / 16}rem`; + isLarge = size >= 64; + } return ( ); diff --git a/packages/@react-spectrum/s2/src/Badge.tsx b/packages/@react-spectrum/s2/src/Badge.tsx index 9bdb65e0b14..dd7038fa1d4 100644 --- a/packages/@react-spectrum/s2/src/Badge.tsx +++ b/packages/@react-spectrum/s2/src/Badge.tsx @@ -15,8 +15,8 @@ import {centerBaseline} from './CenterBaseline'; import {ContextValue, Provider, SlotProps} from 'react-aria-components/slots'; import {control, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'}; import {filterDOMProps} from 'react-aria/filterDOMProps'; -import {fontRelative, lightDark, style} from '../style' with {type: 'macro'}; import {IconContext} from './Icon'; +import {lightDark, style} from '../style' with {type: 'macro'}; import {TextContext as RACTextContext} from 'react-aria-components/Text'; import React, {createContext, forwardRef, ReactNode} from 'react'; import {SkeletonWrapper} from './Skeleton'; @@ -234,7 +234,7 @@ export const Badge = forwardRef(function Badge(props: BadgeProps, ref: DOMRef diff --git a/packages/@react-spectrum/s2/src/Button.tsx b/packages/@react-spectrum/s2/src/Button.tsx index 061a671d755..ccf7d7eaf93 100644 --- a/packages/@react-spectrum/s2/src/Button.tsx +++ b/packages/@react-spectrum/s2/src/Button.tsx @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import {baseColor, focusRing, fontRelative, lightDark, style} from '../style' with {type: 'macro'}; +import {baseColor, focusRing, lightDark, style} from '../style' with {type: 'macro'}; import { ButtonRenderProps, Button as RACButton, @@ -478,7 +478,7 @@ export const Button = forwardRef(function Button( { render: centerBaseline({slot: 'icon', styles: style({order: 0})}), styles: style({ - size: fontRelative(20), + size: '1lh', marginStart: '--iconMargin', flexShrink: 0, visibility: { @@ -593,7 +593,7 @@ export const LinkButton = forwardRef(function LinkButton( { render: centerBaseline({slot: 'icon', styles: style({order: 0})}), styles: style({ - size: fontRelative(20), + size: '1lh', marginStart: '--iconMargin', flexShrink: 0 }) diff --git a/packages/@react-spectrum/s2/src/DragPreview.tsx b/packages/@react-spectrum/s2/src/DragPreview.tsx index 1836f505404..8544bf7488b 100644 --- a/packages/@react-spectrum/s2/src/DragPreview.tsx +++ b/packages/@react-spectrum/s2/src/DragPreview.tsx @@ -10,7 +10,7 @@ * governing permissions and limitations under the License. */ -import {baseColor, fontRelative, style} from '../style' with {type: 'macro'}; +import {baseColor, style} from '../style' with {type: 'macro'}; import {centerBaseline} from './CenterBaseline'; import {controlFont} from './style-utils' with {type: 'macro'}; import {DEFAULT_SLOT, Provider} from 'react-aria-components/slots'; @@ -63,7 +63,7 @@ export let iconCenterWrapper = style({ export let icon = style({ display: 'block', - size: fontRelative(20), + size: '1lh', marginEnd: 'text-to-visual', '--iconPrimary': { type: 'fill', diff --git a/packages/@react-spectrum/s2/src/Field.tsx b/packages/@react-spectrum/s2/src/Field.tsx index 5709090d61f..221be8f67b1 100644 --- a/packages/@react-spectrum/s2/src/Field.tsx +++ b/packages/@react-spectrum/s2/src/Field.tsx @@ -294,7 +294,7 @@ export const FieldGroup = forwardRef(function FieldGroup( IconContext, { styles: style({ - size: fontRelative(20), + size: '1lh', '--iconPrimary': {type: 'fill', value: 'currentColor'} }) } @@ -490,7 +490,7 @@ export function FieldErrorIcon(props: {isDisabled?: boolean}): ReactNode { }) }), styles: style({ - size: fontRelative(20), + size: '1lh', marginStart: 'text-to-visual', marginEnd: fontRelative(-2), flexShrink: 0 diff --git a/packages/@react-spectrum/s2/src/ListView.tsx b/packages/@react-spectrum/s2/src/ListView.tsx index 41d69a077b5..bf0851803e9 100644 --- a/packages/@react-spectrum/s2/src/ListView.tsx +++ b/packages/@react-spectrum/s2/src/ListView.tsx @@ -12,15 +12,7 @@ import {ActionButtonGroupContext} from './ActionButtonGroup'; import {ActionMenuContext} from './ActionMenu'; -import { - baseColor, - color, - colorMix, - focusRing, - fontRelative, - space, - style -} from '../style' with {type: 'macro'}; +import {baseColor, color, colorMix, focusRing, space, style} from '../style' with {type: 'macro'}; import {centerBaseline} from './CenterBaseline'; import {Checkbox} from './Checkbox'; import {CheckboxContext} from 'react-aria-components/Checkbox'; @@ -235,7 +227,7 @@ const listView = style { IconContext, { render: centerBaseline({slot: 'icon', styles: treeIcon}), - styles: style({size: fontRelative(20), flexShrink: 0}) + styles: style({size: '1lh', flexShrink: 0}) } ], [ActionButtonGroupContext, {styles: treeActions, isDisabled, size: 'S'}], @@ -697,7 +697,7 @@ export const SideNavItemLink = (props: SideNavItemLinkProps): ReactNode => { IconContext, { render: centerBaseline({slot: 'icon', styles: treeIcon}), - styles: style({size: fontRelative(20), flexShrink: 0}) + styles: style({size: '1lh', flexShrink: 0}) } ] ]}> diff --git a/packages/@react-spectrum/s2/src/TagGroup.tsx b/packages/@react-spectrum/s2/src/TagGroup.tsx index c7a1f3f1e39..0f208512198 100644 --- a/packages/@react-spectrum/s2/src/TagGroup.tsx +++ b/packages/@react-spectrum/s2/src/TagGroup.tsx @@ -23,7 +23,7 @@ import { TagRenderProps } from 'react-aria-components/TagGroup'; import {AvatarContext} from './Avatar'; -import {baseColor, focusRing, fontRelative, lightDark, style} from '../style' with {type: 'macro'}; +import {baseColor, focusRing, lightDark, style} from '../style' with {type: 'macro'}; import {CenterBaseline, centerBaseline} from './CenterBaseline'; import {ClearButton} from './ClearButton'; import {CollectionBuilder} from 'react-aria/CollectionBuilder'; @@ -630,7 +630,7 @@ function TagWrapper({children, isDisabled, allowsRemoving, isInRealDOM, isEmphas { render: centerBaseline({slot: 'icon', styles: style({order: 0})}), styles: style({ - size: fontRelative(20), + size: '1lh', marginStart: '--iconMargin', flexShrink: 0 }) @@ -647,7 +647,7 @@ function TagWrapper({children, isDisabled, allowsRemoving, isInRealDOM, isEmphas ImageContext, { styles: style({ - size: fontRelative(20), + size: '1lh', flexShrink: 0, order: 0, aspectRatio: 'square', diff --git a/packages/@react-spectrum/s2/src/ToggleButton.tsx b/packages/@react-spectrum/s2/src/ToggleButton.tsx index cb8b897f33e..fa163d02b44 100644 --- a/packages/@react-spectrum/s2/src/ToggleButton.tsx +++ b/packages/@react-spectrum/s2/src/ToggleButton.tsx @@ -16,7 +16,6 @@ import {ContextValue, Provider, useSlottedContext} from 'react-aria-components/s import CornerTriangle from '../ui-icons/CornerTriangle'; import {createContext, forwardRef, ReactNode} from 'react'; import {FocusableRef, FocusableRefValue, GlobalDOMAttributes} from '@react-types/shared'; -import {fontRelative, space, style} from '../style' with {type: 'macro'}; import {IconContext} from './Icon'; import {pressScale} from './pressScale'; import { @@ -24,6 +23,7 @@ import { ToggleButtonProps as RACToggleButtonProps } from 'react-aria-components/ToggleButton'; import {SkeletonContext} from './Skeleton'; +import {space, style} from '../style' with {type: 'macro'}; import {StyleProps} from './style-utils'; import {Text, TextContext} from './Content'; import {ToggleButtonGroupContext} from './ToggleButtonGroup'; @@ -126,7 +126,7 @@ export const ToggleButton = forwardRef(function ToggleButton( IconContext, { render: centerBaseline({slot: 'icon', styles: style({order: 0})}), - styles: style({size: fontRelative(20), marginStart: '--iconMargin', flexShrink: 0}) + styles: style({size: '1lh', marginStart: '--iconMargin', flexShrink: 0}) } ] ]}> diff --git a/packages/@react-spectrum/s2/src/TreeView.tsx b/packages/@react-spectrum/s2/src/TreeView.tsx index 4573d2d5331..24f582dd7f2 100644 --- a/packages/@react-spectrum/s2/src/TreeView.tsx +++ b/packages/@react-spectrum/s2/src/TreeView.tsx @@ -12,14 +12,7 @@ import {ActionButtonGroupContext} from './ActionButtonGroup'; import {ActionMenuContext} from './ActionMenu'; -import { - baseColor, - color, - colorMix, - focusRing, - fontRelative, - style -} from '../style' with {type: 'macro'}; +import {baseColor, color, colorMix, focusRing, style} from '../style' with {type: 'macro'}; import {Button, ButtonContext} from 'react-aria-components/Button'; import {centerBaseline} from './CenterBaseline'; import {Checkbox} from './Checkbox'; @@ -703,7 +696,7 @@ export const TreeViewItemContent = (props: TreeViewItemContentProps): ReactNode IconContext, { render: centerBaseline({slot: 'icon', styles: treeIcon}), - styles: style({size: fontRelative(20), flexShrink: 0}) + styles: style({size: '1lh', flexShrink: 0}) } ], [ActionButtonGroupContext, {styles: treeActions, isDisabled}], diff --git a/packages/@react-spectrum/s2/stories/Avatar.stories.tsx b/packages/@react-spectrum/s2/stories/Avatar.stories.tsx index 550531d7867..444df15b025 100644 --- a/packages/@react-spectrum/s2/stories/Avatar.stories.tsx +++ b/packages/@react-spectrum/s2/stories/Avatar.stories.tsx @@ -40,3 +40,32 @@ type Story = StoryObj; export const Example: Story = { render: args => }; + +export const ExtremelyLargeHeader: Story = { + render: args => ( +
+
+ + Person +
+
+ + Person +
+
+ ), + argTypes: { + size: {control: false} + } +}; diff --git a/packages/@react-spectrum/s2/style/index.ts b/packages/@react-spectrum/s2/style/index.ts index 02d768a2a05..2685ce16742 100644 --- a/packages/@react-spectrum/s2/style/index.ts +++ b/packages/@react-spectrum/s2/style/index.ts @@ -149,9 +149,9 @@ export interface IconStyle { const iconSizes = { XS: 14, S: 16, - M: 20, - L: 22, - XL: 26 + M: 18, + L: 20, + XL: 22 } as const; /** diff --git a/packages/@react-spectrum/s2/style/style-macro.ts b/packages/@react-spectrum/s2/style/style-macro.ts index f2373f1bae2..e7f3900c0ad 100644 --- a/packages/@react-spectrum/s2/style/style-macro.ts +++ b/packages/@react-spectrum/s2/style/style-macro.ts @@ -119,7 +119,9 @@ export type LengthPercentageUnit = | 'cqw' | 'cqh' | 'cqmin' - | 'cqmax'; + | 'cqmax' + | 'lh' + | 'rlh'; export type LengthPercentage = `${number}${LengthPercentageUnit}`; export class PercentageProperty @@ -133,7 +135,7 @@ export class PercentageProperty toCSSValue(value: T | LengthPercentage): PropertyValueDefinition { if ( typeof value === 'string' && - /^-?\d+(?:\.\d+)?(%|vw|svw|dvw|vh|svh|dvh|vmin|svmin|dvmin|vmax|svmax|dvmax|cqw|cqh|cqmin|cqmax)$/.test( + /^-?\d+(?:\.\d+)?(%|vw|svw|dvw|vh|svh|dvh|vmin|svmin|dvmin|vmax|svmax|dvmax|cqw|cqh|cqmin|cqmax|lh|rlh)$/.test( value ) ) {