From 7805d16b34c4d662806f412d41a855146e76f24c Mon Sep 17 00:00:00 2001 From: Alex Sanders Date: Tue, 13 Aug 2024 14:06:46 +0100 Subject: [PATCH] Aligns values of `rem*` exports from `source` (#1643) align values of `rem*` exports from source Brings `remSize`, `remIconSize`, `remHeight` and `remWidth` into line with `remSpace`, by changing their values from numbers (of rems) to strings with `rem` units. --- .changeset/friendly-parrots-relax.md | 7 +++- .changeset/purple-bags-sell.md | 42 +++++++++++++++++++ .../expanding-wrapper/styles.ts | 8 ++-- .../src/react-components/file-input/styles.ts | 6 +-- .../source/src/foundations/size/size.ts | 26 ++++-------- .../source/src/foundations/space/space.ts | 34 +++++++-------- .../source/src/foundations/tokens.test.ts | 30 ++++++------- .../foundations/utils/convert-value.test.ts | 10 ++--- .../src/foundations/utils/convert-value.ts | 13 ++++-- .../react-components/user-feedback/styles.ts | 8 ++-- 10 files changed, 113 insertions(+), 71 deletions(-) create mode 100644 .changeset/purple-bags-sell.md diff --git a/.changeset/friendly-parrots-relax.md b/.changeset/friendly-parrots-relax.md index b7af3cb2d..5a83f9e30 100644 --- a/.changeset/friendly-parrots-relax.md +++ b/.changeset/friendly-parrots-relax.md @@ -2,5 +2,8 @@ '@guardian/source': major --- -- Applies consistent spacing around checkboxes and radio buttons by removing conditional styles and using padding to ensure minimum height of 44px. The external padding is now consistent regardless of the presence of a label and / or supporting text, and removes any inconsistency when these elements are stacked vertically. -- Checkboxes and radio buttons are now aligned with the first line of text when labels wrap on to multiple lines. +Applies consistent spacing around checkboxes and radio buttons by removing conditional styles and using padding to ensure minimum height of 44px. + +The external padding is now consistent regardless of the presence of a label and / or supporting text, and removes any inconsistency when these elements are stacked vertically. + +Checkboxes and radio buttons are also now aligned with the first line of text when labels wrap on to multiple lines. diff --git a/.changeset/purple-bags-sell.md b/.changeset/purple-bags-sell.md new file mode 100644 index 000000000..d8fcf0a0d --- /dev/null +++ b/.changeset/purple-bags-sell.md @@ -0,0 +1,42 @@ +--- +'@guardian/source-development-kitchen': major +'@guardian/source': major +--- + +Brings `remSize`, `remIconSize`, `remHeight` and `remWidth` into line with `remSpace`, by changing their values from numbers (of rems) to strings with `rem` units. + +_The sizes haven't changed, only the way they are exported._ + +### Before + +```js +const style = ` + bottom: ${remHeight.ctaSmall}rem; +`; +``` + +### After + +```js +const style = ` + bottom: ${remHeight.ctaSmall}; +`; +``` + +If you have been performing calculations with the old number values in JS, you can use the [CSS `calc` function](https://developer.mozilla.org/en-US/docs/Web/CSS/calc) instead: + +### Before + +```js +const style = ` + bottom: -${remHeight.ctaSmall / 2}rem; +`; +``` + +### After + +```js +const style = ` + bottom: calc(-${remHeight.ctaSmall} / 2); +`; +``` diff --git a/libs/@guardian/source-development-kitchen/src/react-components/expanding-wrapper/styles.ts b/libs/@guardian/source-development-kitchen/src/react-components/expanding-wrapper/styles.ts index ccad265fd..c2807522e 100644 --- a/libs/@guardian/source-development-kitchen/src/react-components/expanding-wrapper/styles.ts +++ b/libs/@guardian/source-development-kitchen/src/react-components/expanding-wrapper/styles.ts @@ -79,16 +79,16 @@ export const showHideLabelStyles = css` box-sizing: border-box; cursor: pointer; position: absolute; - bottom: -${remHeight.ctaSmall / 2}rem; - border-radius: ${remHeight.ctaSmall}rem; + bottom: calc(-${remHeight.ctaSmall} / 2); + border-radius: ${remHeight.ctaSmall}; padding: 0 ${remSpace[4]}; padding-bottom: 2px; border: 1px solid ${themeColour('--expandBackground')}; text-decoration: none; background: ${themeColour('--expandBackground')}; color: ${themeColour('--expandText')}; - height: ${remHeight.ctaSmall}rem; - min-height: ${remHeight.ctaSmall}rem; + height: ${remHeight.ctaSmall}; + min-height: ${remHeight.ctaSmall}; margin-left: ${remSpace[2]}; &:hover { diff --git a/libs/@guardian/source-development-kitchen/src/react-components/file-input/styles.ts b/libs/@guardian/source-development-kitchen/src/react-components/file-input/styles.ts index fd0f7ee51..6241a18b5 100644 --- a/libs/@guardian/source-development-kitchen/src/react-components/file-input/styles.ts +++ b/libs/@guardian/source-development-kitchen/src/react-components/file-input/styles.ts @@ -81,9 +81,9 @@ export const customUpload = ( text-decoration: none; white-space: nowrap; margin: ${remSpace[2]} ${remSpace[2]} ${remSpace[2]} 0; - height: ${remHeight.ctaXsmall}rem; - min-height: ${remHeight.ctaXsmall}rem; - border-radius: ${remHeight.ctaMedium}rem; + height: ${remHeight.ctaXsmall}; + min-height: ${remHeight.ctaXsmall}; + border-radius: ${remHeight.ctaMedium}; color: ${fileInput.primary}; border: ${hasError ? `2px solid ${fileInput.error}` diff --git a/libs/@guardian/source/src/foundations/size/size.ts b/libs/@guardian/source/src/foundations/size/size.ts index 7b9340ccf..ef2553182 100644 --- a/libs/@guardian/source/src/foundations/size/size.ts +++ b/libs/@guardian/source/src/foundations/size/size.ts @@ -18,16 +18,12 @@ export const size = { * [Design System](https://theguardian.design/2a1e5182b/p/24a3ec-size/t/329aef) * * May be used for call to action buttons and user input fields. - * - ** `remSize.medium` -> 2.75rem - ** `remSize.small` -> 2.25rem - ** `remSize.xsmall` -> 1.5rem */ -const remSize: { [K in keyof typeof size]: number } = { +const remSize = { xsmall: pxToRem(size.xsmall), small: pxToRem(size.small), medium: pxToRem(size.medium), -}; +} as const; /* We attempt to use these values for icons within Source components. @@ -41,11 +37,11 @@ export const iconSize = { medium: pxStringToNumber(tokens.icon.medium), } as const; -const remIconSize: { [K in keyof typeof iconSize]: number } = { +const remIconSize = { xsmall: pxToRem(iconSize.xsmall), small: pxToRem(iconSize.small), medium: pxToRem(iconSize.medium), -}; +} as const; /** * [Storybook](https://guardian.github.io/storybooks/?path=/docs/source_foundations-size--page#tokens) • @@ -71,7 +67,7 @@ export const height = { iconMedium: iconSize.medium, iconSmall: iconSize.small, iconXsmall: iconSize.xsmall, -}; +} as const; /** * [Storybook](https://guardian.github.io/storybooks/?path=/docs/source_foundations-size--page#tokens) • @@ -97,7 +93,7 @@ export const remHeight = { iconMedium: remIconSize.medium, iconSmall: remIconSize.small, iconXsmall: remIconSize.xsmall, -}; +} as const; /** * [Storybook](https://guardian.github.io/storybooks/?path=/docs/source_foundations-size--page#tokens) • @@ -108,9 +104,6 @@ export const remHeight = { ** `width.ctaMedium`: medium height call to action buttons and links ** `width.ctaSmall`: small height call to action buttons and links ** `width.ctaXsmall`: xsmall height call to action buttons and links - ** `width.inputMedium`: text input fields, radio and checkbox labels - ** `width.inputXsmall`: checkables such as checkboxes or radio buttons - ** `width.inputMedium` ** `width.inputXsmall`: checkables such as checkboxes or radio buttons ** `width.iconMedium` ** `width.iconSmall` @@ -124,7 +117,7 @@ export const width = { iconMedium: iconSize.medium, iconSmall: iconSize.small, iconXsmall: iconSize.xsmall, -}; +} as const; /** * [Storybook](https://guardian.github.io/storybooks/?path=/docs/source_foundations-size--page#tokens) • @@ -135,9 +128,6 @@ export const width = { ** `remWidth.ctaMedium`: medium height call to action buttons and links ** `remWidth.ctaSmall`: small height call to action buttons and links ** `remWidth.ctaXsmall`: xsmall height call to action buttons and links - ** `remWidth.inputMedium`: text input fields, radio and checkbox labels - ** `remWidth.inputXsmall`: checkables such as checkboxes or radio buttons - ** `remWidth.inputMedium` ** `remWidth.inputXsmall`: checkables such as checkboxes or radio buttons ** `remWidth.iconMedium` ** `remWidth.iconSmall` @@ -151,4 +141,4 @@ export const remWidth = { iconMedium: remIconSize.medium, iconSmall: remIconSize.small, iconXsmall: remIconSize.xsmall, -}; +} as const; diff --git a/libs/@guardian/source/src/foundations/space/space.ts b/libs/@guardian/source/src/foundations/space/space.ts index 6d3e56b4f..c7e04671b 100644 --- a/libs/@guardian/source/src/foundations/space/space.ts +++ b/libs/@guardian/source/src/foundations/space/space.ts @@ -26,20 +26,20 @@ export const space = { 24: pxStringToNumber(tokens[24]), } as const; -export const remSpace: { [K in keyof typeof space]: string } = { - 0: `${pxToRem(space[0])}rem`, - 1: `${pxToRem(space[1])}rem`, - 2: `${pxToRem(space[2])}rem`, - 3: `${pxToRem(space[3])}rem`, - 4: `${pxToRem(space[4])}rem`, - 5: `${pxToRem(space[5])}rem`, - 6: `${pxToRem(space[6])}rem`, - 8: `${pxToRem(space[8])}rem`, - 9: `${pxToRem(space[9])}rem`, - 10: `${pxToRem(space[10])}rem`, - 12: `${pxToRem(space[12])}rem`, - 14: `${pxToRem(space[14])}rem`, - 16: `${pxToRem(space[16])}rem`, - 18: `${pxToRem(space[18])}rem`, - 24: `${pxToRem(space[24])}rem`, -}; +export const remSpace = { + 0: pxToRem(space[0]), + 1: pxToRem(space[1]), + 2: pxToRem(space[2]), + 3: pxToRem(space[3]), + 4: pxToRem(space[4]), + 5: pxToRem(space[5]), + 6: pxToRem(space[6]), + 8: pxToRem(space[8]), + 9: pxToRem(space[9]), + 10: pxToRem(space[10]), + 12: pxToRem(space[12]), + 14: pxToRem(space[14]), + 16: pxToRem(space[16]), + 18: pxToRem(space[18]), + 24: pxToRem(space[24]), +} as const; diff --git a/libs/@guardian/source/src/foundations/tokens.test.ts b/libs/@guardian/source/src/foundations/tokens.test.ts index 416bd5fc0..fa8e98d86 100644 --- a/libs/@guardian/source/src/foundations/tokens.test.ts +++ b/libs/@guardian/source/src/foundations/tokens.test.ts @@ -196,14 +196,14 @@ describe('Size tokens', () => { inputMedium: 44, }); expect(remHeight).toEqual({ - ctaXsmall: 1.5, - ctaSmall: 2.25, - ctaMedium: 2.75, - iconXsmall: 1.25, - iconSmall: 1.625, - iconMedium: 1.875, - inputXsmall: 1.5, - inputMedium: 2.75, + ctaXsmall: '1.5rem', + ctaSmall: '2.25rem', + ctaMedium: '2.75rem', + iconXsmall: '1.25rem', + iconSmall: '1.625rem', + iconMedium: '1.875rem', + inputXsmall: '1.5rem', + inputMedium: '2.75rem', }); expect(width).toEqual({ ctaXsmall: 24, @@ -215,13 +215,13 @@ describe('Size tokens', () => { inputXsmall: 24, }); expect(remWidth).toEqual({ - ctaXsmall: 1.5, - ctaSmall: 2.25, - ctaMedium: 2.75, - iconXsmall: 1.25, - iconSmall: 1.625, - iconMedium: 1.875, - inputXsmall: 1.5, + ctaXsmall: '1.5rem', + ctaSmall: '2.25rem', + ctaMedium: '2.75rem', + iconXsmall: '1.25rem', + iconSmall: '1.625rem', + iconMedium: '1.875rem', + inputXsmall: '1.5rem', }); }); }); diff --git a/libs/@guardian/source/src/foundations/utils/convert-value.test.ts b/libs/@guardian/source/src/foundations/utils/convert-value.test.ts index b5c59ce0b..42f17c393 100644 --- a/libs/@guardian/source/src/foundations/utils/convert-value.test.ts +++ b/libs/@guardian/source/src/foundations/utils/convert-value.test.ts @@ -6,10 +6,10 @@ import { } from './convert-value'; describe('pxToRem', () => { - it('should calculate a rem equivalent of a pixel value', () => { + it('should calculate a value with a rem unit from a pixel value', () => { const value = 17; const result = pxToRem(value); - expect(result).toBe(1.0625); + expect(result).toBe('1.0625rem'); }); }); @@ -23,11 +23,11 @@ describe('pxStringToNumber', () => { }); describe('pxStringToRem', () => { - it('should convert a value with a px unit to rem equivalent', () => { + it('should convert a value with a px unit to a value with a rem unit', () => { const value = '20px'; const result = pxStringToRem(value); - expect(result).toBe(1.25); - expect(typeof result).toBe('number'); + expect(result).toBe('1.25rem'); + expect(typeof result).toBe('string'); }); }); diff --git a/libs/@guardian/source/src/foundations/utils/convert-value.ts b/libs/@guardian/source/src/foundations/utils/convert-value.ts index ecd6cba83..4ec2f9576 100644 --- a/libs/@guardian/source/src/foundations/utils/convert-value.ts +++ b/libs/@guardian/source/src/foundations/utils/convert-value.ts @@ -1,9 +1,16 @@ +export type RemString = `${N}rem`; +export type PxString = `${N}px`; + export const rootPixelFontSize = 16; -export const pxToRem = (px: number): number => px / rootPixelFontSize; -export const pxStringToRem = (px: `${number}px`): number => +export const pxToRem = (px: number): RemString => + `${px / rootPixelFontSize}rem`; + +export const pxStringToRem = (px: PxString): RemString => pxToRem(pxStringToNumber(px)); -export const pxStringToNumber = (px: `${N}px`): N => + +export const pxStringToNumber = (px: PxString): N => Number(px.slice(0, -2)) as N; + export const fontArrayToString = (fonts: readonly string[]): string => fonts.map((name) => (name.includes(' ') ? `"${name}"` : name)).join(', '); diff --git a/libs/@guardian/source/src/react-components/user-feedback/styles.ts b/libs/@guardian/source/src/react-components/user-feedback/styles.ts index 0fa79f539..e246e538d 100644 --- a/libs/@guardian/source/src/react-components/user-feedback/styles.ts +++ b/libs/@guardian/source/src/react-components/user-feedback/styles.ts @@ -24,16 +24,16 @@ const inlineMessage = css` const inlineMessageSmall = css` ${textSans14}; svg { - width: ${remWidth.iconSmall}rem; - height: ${remHeight.iconSmall}rem; + width: ${remWidth.iconSmall}; + height: ${remHeight.iconSmall}; } `; const inlineMessageMedium = css` ${textSans17}; svg { - width: ${remWidth.iconMedium}rem; - height: ${remHeight.iconMedium}rem; + width: ${remWidth.iconMedium}; + height: ${remHeight.iconMedium}; } `;