From 6da57ffb0efeaeb40741b5dbf9dbb3d79eba7af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20S=C3=A1ros?= Date: Wed, 24 Jun 2026 15:15:29 +0200 Subject: [PATCH] feat(many): support current spacing tokens in the margin prop for v2 components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface the current (era-3) spacing tokens (general.*, gap.*, padding.card.* dot-paths) on the `margin` prop of v2 components. View v2 already resolved them at runtime, but the `Spacing` type and component docs only advertised the older token eras. - emotion: add CurrentSpacingValues dot-path literals to the Spacing union and mark the legacy (era-1) and phased-out (era-2) unions as @deprecated - v2 components: sync the margin JSDoc across all v2 components to point at the spacing guide and use a current-token example - docs: re-add the Layout Spacing guide as a v11.7+ version-gated page, following the theme-overrides version-banner pattern; convert legacy margin values in v2 README examples to the current general.* tokens (value-preserving mapping) - tests: cover era-3 dot-path resolution in calcSpacingFromShorthand and add View v2 integration tests; add regression-test examples 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/guides/layout-spacing.md | 95 +++++++++++++++++++ .../src/styleUtils/ThemeablePropValues.ts | 45 ++++++++- .../calcSpacingFromShorthand.test.tsx | 66 +++++++++++++ packages/ui-alerts/src/Alert/v2/README.md | 22 ++--- packages/ui-alerts/src/Alert/v2/props.ts | 6 +- packages/ui-avatar/src/Avatar/v2/props.ts | 2 +- packages/ui-badge/src/Badge/v2/README.md | 34 +++---- packages/ui-badge/src/Badge/v2/props.ts | 6 +- .../ui-billboard/src/Billboard/v2/README.md | 4 +- .../ui-billboard/src/Billboard/v2/props.ts | 6 +- .../ui-breadcrumb/src/Breadcrumb/v2/README.md | 4 +- .../ui-breadcrumb/src/Breadcrumb/v2/props.ts | 6 +- .../ui-buttons/src/BaseButton/v2/README.md | 2 +- .../ui-buttons/src/BaseButton/v2/props.ts | 6 +- packages/ui-buttons/src/Button/v2/README.md | 48 +++++----- packages/ui-buttons/src/Button/v2/props.ts | 6 +- .../ui-buttons/src/CloseButton/v2/README.md | 2 +- .../ui-buttons/src/CloseButton/v2/props.ts | 6 +- .../src/CondensedButton/v2/props.ts | 6 +- .../ui-buttons/src/IconButton/v2/README.md | 16 ++-- .../ui-buttons/src/IconButton/v2/props.ts | 6 +- packages/ui-byline/src/Byline/v2/README.md | 4 +- packages/ui-byline/src/Byline/v2/props.ts | 6 +- .../src/ColorIndicator/v2/README.md | 24 ++--- .../src/ColorPicker/v2/README.md | 4 +- .../src/DrawerLayout/v2/README.md | 16 ++-- .../ui-drilldown/src/Drilldown/v2/README.md | 4 +- .../ui-editable/src/InPlaceEdit/v2/README.md | 2 +- .../ui-file-drop/src/FileDrop/v2/README.md | 8 +- .../ui-file-drop/src/FileDrop/v2/props.ts | 6 +- packages/ui-flex/src/Flex/v2/README.md | 30 +++--- packages/ui-flex/src/Flex/v2/props.ts | 6 +- .../src/FormFieldLayout/v2/props.ts | 2 +- packages/ui-heading/src/Heading/v2/README.md | 6 +- packages/ui-heading/src/Heading/v2/props.ts | 6 +- packages/ui-img/src/Img/v2/README.md | 16 ++-- packages/ui-img/src/Img/v2/props.ts | 6 +- packages/ui-link/src/Link/v2/README.md | 6 +- packages/ui-link/src/Link/v2/props.ts | 2 +- packages/ui-list/src/InlineList/v2/README.md | 14 +-- packages/ui-list/src/InlineList/v2/props.ts | 6 +- packages/ui-list/src/List/v2/README.md | 18 ++-- packages/ui-list/src/List/v2/props.ts | 6 +- packages/ui-modal/src/Modal/v2/README.md | 26 ++--- .../ui-navigation/src/AppNav/v2/README.md | 2 +- packages/ui-navigation/src/AppNav/v2/props.ts | 6 +- packages/ui-overlays/src/Mask/v2/README.md | 2 +- .../ui-pagination/src/Pagination/v2/README.md | 18 ++-- .../ui-pagination/src/Pagination/v2/props.ts | 6 +- packages/ui-pill/src/Pill/v2/README.md | 10 +- packages/ui-pill/src/Pill/v2/props.ts | 6 +- packages/ui-popover/src/Popover/v2/README.md | 14 +-- .../ui-progress/src/ProgressBar/v2/README.md | 18 ++-- .../ui-progress/src/ProgressBar/v2/props.ts | 6 +- .../src/ProgressCircle/v2/README.md | 16 ++-- .../src/ProgressCircle/v2/props.ts | 6 +- .../src/RadioInput/v2/README.md | 4 +- .../src/RangeInput/v2/README.md | 2 +- packages/ui-rating/src/Rating/v2/README.md | 6 +- packages/ui-rating/src/Rating/v2/props.ts | 6 +- packages/ui-select/src/Select/v2/README.md | 4 +- .../src/SourceCodeEditor/v2/README.md | 12 +-- packages/ui-spinner/src/Spinner/v2/props.ts | 2 +- packages/ui-table/src/Table/v2/README.md | 22 ++--- packages/ui-table/src/Table/v2/props.ts | 6 +- packages/ui-tabs/src/Tabs/v2/README.md | 16 ++-- packages/ui-tabs/src/Tabs/v2/props.ts | 6 +- packages/ui-tag/src/Tag/v2/README.md | 12 +-- packages/ui-tag/src/Tag/v2/props.ts | 6 +- .../ui-text-area/src/TextArea/v2/README.md | 2 +- .../ui-text-input/src/TextInput/v2/README.md | 18 ++-- packages/ui-text/src/Text/v2/README.md | 2 +- .../src/ToggleDetails/v2/README.md | 4 +- .../ui-top-nav-bar/src/TopNavBar/v2/README.md | 52 +++++----- .../src/TreeBrowser/v2/README.md | 12 +-- packages/ui-view/src/ContextView/v2/README.md | 8 +- .../ui-view/src/View/__tests__/View.test.tsx | 39 ++++++++ packages/ui-view/src/View/v2/README.md | 84 ++++++++-------- packages/ui-view/src/View/v2/props.ts | 2 +- regression-test/src/app/view/page.tsx | 21 ++++ 80 files changed, 670 insertions(+), 406 deletions(-) create mode 100644 docs/guides/layout-spacing.md diff --git a/docs/guides/layout-spacing.md b/docs/guides/layout-spacing.md new file mode 100644 index 0000000000..146ef5d6fe --- /dev/null +++ b/docs/guides/layout-spacing.md @@ -0,0 +1,95 @@ +--- +title: Layout Spacing +category: Guides +order: 7 +relevantForAI: true +--- + +## Layout Spacing + +```js +--- +type: embed +--- + + The spacing tokens documented on this page (such as general.spaceMd) require v11.7+ components and are applied through the margin and padding props. If you are viewing the v11.6 version, switch to v11.7 to see the examples working correctly. + +``` + +Our design system provides a set of spacing tokens for consistent layouts and components. The current tokens are organized into a general t-shirt scale plus a handful of semantic tokens. Some tokens share a value but carry different meaning — prefer the semantically correct token for the context (e.g. use `gap.buttons` for spacing between buttons). + +The `margin` and `padding` props on InstUI components accept these tokens via **dot-path notation** (for example `margin="general.spaceMd"` or `padding="padding.card.lg"`), and support the familiar CSS-like 1–4 value shorthand. + +## Tokens + +### General scale + +| Key | Value | Value in pixels | +| ----------------- | -------- | --------------- | +| general.spaceNone | 0rem | 0px | +| general.space2xs | 0.125rem | 2px | +| general.spaceXs | 0.25rem | 4px | +| general.spaceSm | 0.5rem | 8px | +| general.spaceMd | 0.75rem | 12px | +| general.spaceLg | 1rem | 16px | +| general.spaceXl | 1.5rem | 24px | +| general.space2xl | 2rem | 32px | + +### Semantic tokens + +| Key | Value | Value in pixels | +| ----------------------------- | ------- | --------------- | +| gap.sections | 3rem | 48px | +| gap.buttons | 0.75rem | 12px | +| gap.cards.sm | 0.75rem | 12px | +| gap.cards.md | 1rem | 16px | +| gap.cards.lg | 1.5rem | 24px | +| gap.cards.nestedContainers.sm | 0.5rem | 8px | +| gap.cards.nestedContainers.md | 0.75rem | 12px | +| gap.cards.nestedContainers.lg | 1rem | 16px | +| gap.inputs.horizontal | 0.75rem | 12px | +| gap.inputs.vertical | 1rem | 16px | +| padding.card.sm | 0.5rem | 8px | +| padding.card.md | 0.75rem | 12px | +| padding.card.lg | 1rem | 16px | + +## Applying spacing + +### Using the `margin` prop + +Most components support a `margin` prop that works like the CSS `margin` property. Pass a single token or use the 1–4 value shorthand to fine-tune individual edges. + +```js +--- +type: example +--- + + + + +``` + +### Using the `padding` prop + +Components that render their own surface accept a `padding` prop, which resolves the same tokens. Semantic `padding.card.*` tokens are a good fit for card-like containers. + +```js +--- +type: example +--- + + This container uses padding.card.lg. + +``` + +## Deprecated tokens + +For compatibility reasons we still resolve two earlier generations of spacing tokens at runtime, but they should **not** be used when creating new layouts — prefer the current tokens above. + +### Phased-out tokens + +The flat `space0`–`space60` scale and the flat semantic tokens (`sections`, `buttons`, `paddingCardLarge`, `selects`, `tags`, etc.) were an interim set and have been superseded by the current general scale and dot-path semantic tokens. + +### Legacy tokens + +The original legacy keywords (`xxxSmall`, `small`, `medium`, `large`, `xxLarge`, etc.) remain so old layouts don't break when updating InstUI. diff --git a/packages/emotion/src/styleUtils/ThemeablePropValues.ts b/packages/emotion/src/styleUtils/ThemeablePropValues.ts index f2ba3287c8..f8c490b2d6 100644 --- a/packages/emotion/src/styleUtils/ThemeablePropValues.ts +++ b/packages/emotion/src/styleUtils/ThemeablePropValues.ts @@ -90,7 +90,18 @@ const ThemeablePropValues = { // SPACING type OldSpacingKeys = keyof typeof ThemeablePropValues.SPACING +/** + * @deprecated Era-1 (legacy) spacing keywords. Still resolved at runtime, but + * prefer the current `CurrentSpacingValues` dot-path tokens (e.g. `general.spaceMd`). + * See https://instructure.design/layout-spacing. + */ type OldSpacingValues = (typeof ThemeablePropValues.SPACING)[OldSpacingKeys] +/** + * @deprecated Era-2 spacing tokens (the `space0`–`space60` and flat semantic set) + * have been phased out. Still resolved at runtime, but prefer the current + * `CurrentSpacingValues` dot-path tokens (e.g. `general.spaceMd`, `gap.cards.md`). + * See https://instructure.design/layout-spacing. + */ type NewSpacingValues = | 'space0' | 'space2' @@ -120,7 +131,38 @@ type NewSpacingValues = | 'tags' | 'statusIndicators' | 'dataPoints' -type SpacingValues = OldSpacingValues | NewSpacingValues +/** + * Current (era-3) spacing tokens. Referenced via dot-path notation and resolved + * against the new theme's `sharedTokens.spacing` map (see + * `@instructure/ui-themes` `newThemeTokens`). These are the recommended values + * for the `margin`/`padding` props. See https://instructure.design/layout-spacing. + */ +type CurrentSpacingValues = + // general t-shirt scale + | 'general.spaceNone' + | 'general.space2xs' + | 'general.spaceXs' + | 'general.spaceSm' + | 'general.spaceMd' + | 'general.spaceLg' + | 'general.spaceXl' + | 'general.space2xl' + // semantic gap tokens + | 'gap.sections' + | 'gap.buttons' + | 'gap.cards.sm' + | 'gap.cards.md' + | 'gap.cards.lg' + | 'gap.cards.nestedContainers.sm' + | 'gap.cards.nestedContainers.md' + | 'gap.cards.nestedContainers.lg' + | 'gap.inputs.horizontal' + | 'gap.inputs.vertical' + // semantic padding tokens + | 'padding.card.sm' + | 'padding.card.md' + | 'padding.card.lg' +type SpacingValues = CurrentSpacingValues | OldSpacingValues | NewSpacingValues // adding `(string & {})` allows to use any string while still allowing specific string values to be suggested by IDEs type Spacing = SpacingValues | (string & {}) @@ -152,6 +194,7 @@ export default ThemeablePropValues export { ThemeablePropValues } export type { SpacingValues, + CurrentSpacingValues, Spacing, Shadow, Stacking, diff --git a/packages/emotion/src/styleUtils/__tests__/calcSpacingFromShorthand.test.tsx b/packages/emotion/src/styleUtils/__tests__/calcSpacingFromShorthand.test.tsx index ecd4649885..80599a8626 100644 --- a/packages/emotion/src/styleUtils/__tests__/calcSpacingFromShorthand.test.tsx +++ b/packages/emotion/src/styleUtils/__tests__/calcSpacingFromShorthand.test.tsx @@ -239,4 +239,70 @@ describe('calcSpacingFromShorthand', () => { consoleWarnSpy.mockRestore() }) }) + + // Era-3 (current) tokens are referenced via dot-path notation and resolved + // against the new theme's nested `sharedTokens.spacing` map. This block mirrors + // that shape to verify the real consumer syntax (e.g. `margin="general.spaceMd"`). + describe('era-3 (current) spacing tokens', () => { + const eraThreeMap = { + general: { + spaceNone: '0rem', + space2xs: '0.125rem', + spaceXs: '0.25rem', + spaceSm: '0.5rem', + spaceMd: '0.75rem', + spaceLg: '1rem', + spaceXl: '1.5rem', + space2xl: '2rem' + }, + gap: { + sections: '3rem', + buttons: '0.75rem', + cards: { + sm: '0.75rem', + md: '1rem', + lg: '1.5rem', + nestedContainers: { sm: '0.5rem', md: '0.75rem', lg: '1rem' } + }, + inputs: { horizontal: '0.75rem', vertical: '1rem' } + }, + padding: { + card: { sm: '0.5rem', md: '0.75rem', lg: '1rem' } + } + } + + it('resolves a general scale token', () => { + expect(calcSpacingFromShorthand('general.spaceMd', eraThreeMap)).toBe('0.75rem') + }) + + it('resolves general.spaceNone', () => { + expect(calcSpacingFromShorthand('general.spaceNone', eraThreeMap)).toBe('0rem') + }) + + it('resolves a deeply nested semantic gap token', () => { + expect( + calcSpacingFromShorthand('gap.cards.nestedContainers.md', eraThreeMap) + ).toBe('0.75rem') + }) + + it('resolves a semantic padding token', () => { + expect(calcSpacingFromShorthand('padding.card.lg', eraThreeMap)).toBe('1rem') + }) + + it('handles CSS-like shorthand mixing the general scale with auto', () => { + const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + + expect( + calcSpacingFromShorthand('general.spaceLg auto general.spaceXl', eraThreeMap) + ).toBe('1rem auto 1.5rem') + + consoleWarnSpy.mockRestore() + }) + + it('mixes semantic gap and padding tokens', () => { + expect( + calcSpacingFromShorthand('gap.cards.sm padding.card.md', eraThreeMap) + ).toBe('0.75rem 0.75rem') + }) + }) }) diff --git a/packages/ui-alerts/src/Alert/v2/README.md b/packages/ui-alerts/src/Alert/v2/README.md index f802e616e1..69d8aa9e23 100644 --- a/packages/ui-alerts/src/Alert/v2/README.md +++ b/packages/ui-alerts/src/Alert/v2/README.md @@ -24,7 +24,7 @@ type: example @@ -33,7 +33,7 @@ type: example Sample info text. I will fade out if you close me. @@ -41,7 +41,7 @@ type: example Sample error text that continues for a while @@ -51,7 +51,7 @@ type: example Sample warning text. This alert is not dismissible and cannot be closed. @@ -67,7 +67,7 @@ type: example --- @@ -119,14 +119,14 @@ const Example = () => { {alerts.map((alert) => { return ( - + closeAlert(alert.key)} liveRegion={() => document.getElementById('flash-messages')} liveRegionPoliteness={alert.politeness} - margin="small 0" + margin="general.spaceMd 0" > This is {alert.politeness === 'polite' ? 'a' : 'an'}{' '} {alert.politeness} {alert.variant} alert @@ -164,7 +164,7 @@ const Example = () => { return (
- {lorem.paragraph()} @@ -212,7 +212,7 @@ type: example padding="small medium" borderWidth="small" borderRadius="small" - margin="x-small 0" + margin="general.spaceSm 0" > {lorem.paragraph()} diff --git a/packages/ui-alerts/src/Alert/v2/props.ts b/packages/ui-alerts/src/Alert/v2/props.ts index 33a1966d06..fce9f0fe81 100644 --- a/packages/ui-alerts/src/Alert/v2/props.ts +++ b/packages/ui-alerts/src/Alert/v2/props.ts @@ -79,9 +79,9 @@ type AlertOwnProps = { */ timeout?: number /** - * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`, - * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via - * familiar CSS-like shorthand. For example: `margin="small auto large"`. + * Valid values are `0`, `none`, `auto`, and Spacing token values, + * see https://instructure.design/layout-spacing. Apply these values via + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing /** diff --git a/packages/ui-avatar/src/Avatar/v2/props.ts b/packages/ui-avatar/src/Avatar/v2/props.ts index 40fa9986bf..ce3665719f 100644 --- a/packages/ui-avatar/src/Avatar/v2/props.ts +++ b/packages/ui-avatar/src/Avatar/v2/props.ts @@ -81,7 +81,7 @@ type AvatarOwnProps = { /** * Valid values are `0`, `none`, `auto`, and Spacing token values, * see https://instructure.design/layout-spacing. Apply these values via - * familiar CSS-like shorthand. For example, `margin="small auto large"`. + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing /** diff --git a/packages/ui-badge/src/Badge/v2/README.md b/packages/ui-badge/src/Badge/v2/README.md index 01618bcbf1..627f98baa2 100644 --- a/packages/ui-badge/src/Badge/v2/README.md +++ b/packages/ui-badge/src/Badge/v2/README.md @@ -16,7 +16,7 @@ type: example @@ -59,7 +59,7 @@ Use the `countUntil` prop to set a limit for the count. The default for `formatO type: example ---
- + @@ -80,7 +80,7 @@ type: example ---
- + - + - + - + ( const Example = () => (
- - + + - + - + - + - + @@ -169,7 +169,7 @@ const Example = () => ( ( @@ -196,7 +196,7 @@ const Example = () => ( ( ( } diff --git a/packages/ui-billboard/src/Billboard/v2/props.ts b/packages/ui-billboard/src/Billboard/v2/props.ts index 085b147a46..7b8bd2cbe4 100644 --- a/packages/ui-billboard/src/Billboard/v2/props.ts +++ b/packages/ui-billboard/src/Billboard/v2/props.ts @@ -90,9 +90,9 @@ type BillboardOwnProps = { */ readOnly?: boolean /** - * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`, - * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via - * familiar CSS-like shorthand. For example: `margin="small auto large"`. + * Valid values are `0`, `none`, `auto`, and Spacing token values, + * see https://instructure.design/layout-spacing. Apply these values via + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing } diff --git a/packages/ui-breadcrumb/src/Breadcrumb/v2/README.md b/packages/ui-breadcrumb/src/Breadcrumb/v2/README.md index 4428e9209a..57117dcaed 100644 --- a/packages/ui-breadcrumb/src/Breadcrumb/v2/README.md +++ b/packages/ui-breadcrumb/src/Breadcrumb/v2/README.md @@ -52,7 +52,7 @@ Change the `size` prop to control the font-size of the breadcrumbs (default is ` type: example ---
- + English 204 Rabbit Is Rich - + English 204 + Click me ``` diff --git a/packages/ui-buttons/src/BaseButton/v2/props.ts b/packages/ui-buttons/src/BaseButton/v2/props.ts index 02f0ec5508..a9299186dc 100644 --- a/packages/ui-buttons/src/BaseButton/v2/props.ts +++ b/packages/ui-buttons/src/BaseButton/v2/props.ts @@ -120,9 +120,9 @@ type BaseButtonOwnProps = { isCondensed?: boolean /** - * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`, - * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via - * familiar CSS-like shorthand. For example: `margin="small auto large"`. + * Valid values are `0`, `none`, `auto`, and Spacing token values, + * see https://instructure.design/layout-spacing. Apply these values via + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing diff --git a/packages/ui-buttons/src/Button/v2/README.md b/packages/ui-buttons/src/Button/v2/README.md index b6d886f41a..e6bff47106 100644 --- a/packages/ui-buttons/src/Button/v2/README.md +++ b/packages/ui-buttons/src/Button/v2/README.md @@ -20,12 +20,12 @@ The `color` prop will change the Button's color scheme. type: example --- - - - - - - + + + + + + ``` @@ -38,7 +38,7 @@ The `primary-inverse` color is designed for use on colored backgrounds. It provi type: example --- - + ``` @@ -51,12 +51,12 @@ There is a specific need for `AI buttons`, which has an icon and gradient colors type: example --- - - - - - - + + + + + + ``` @@ -69,9 +69,9 @@ To specify the Button `size`, set the size prop to `small`, `medium` (default) o type: example --- - - - + + + ``` @@ -82,8 +82,8 @@ There are also two condensed size variants for compact layouts: `condensedSmall` type: example --- - - + + ``` @@ -109,7 +109,7 @@ type: example @@ -146,7 +146,7 @@ type: example @@ -178,7 +178,7 @@ type: example @@ -202,7 +202,7 @@ Use backgroundless buttons when there is a need to deemphasize the button. Be su type: example --- - + ``` @@ -261,7 +261,7 @@ type: example onChange={this.toggleWithBackground} /> - + - + - diff --git a/packages/ui-drawer-layout/src/DrawerLayout/v2/README.md b/packages/ui-drawer-layout/src/DrawerLayout/v2/README.md index a3a6ebb9b4..0dfefc9ba6 100644 --- a/packages/ui-drawer-layout/src/DrawerLayout/v2/README.md +++ b/packages/ui-drawer-layout/src/DrawerLayout/v2/README.md @@ -41,7 +41,7 @@ type: example as="div" maxWidth="16rem" textAlign="center" - margin="large auto" + margin="general.space2xl auto" padding="small" > - + Hello from start tray with a small amount of placeholder content @@ -64,7 +64,7 @@ type: example
``` @@ -131,7 +131,7 @@ type: example console.log(`Files accepted ${files.map((f) => f.name).join(',')}`) }} renderLabel={ - + Drag and Drop or Click to Browser your Computer @@ -140,7 +140,7 @@ type: example } width="18rem" height="16rem" - margin="x-small" + margin="general.spaceSm" /> ``` diff --git a/packages/ui-file-drop/src/FileDrop/v2/props.ts b/packages/ui-file-drop/src/FileDrop/v2/props.ts index 8e9e9633ee..d6ddb281f9 100644 --- a/packages/ui-file-drop/src/FileDrop/v2/props.ts +++ b/packages/ui-file-drop/src/FileDrop/v2/props.ts @@ -141,9 +141,9 @@ type FileDropOwnProps = { */ minWidth?: string | number /** - * Valid values are 0, none, auto, xxx-small, xx-small, x-small, small, - * medium, large, x-large, xx-large. Apply these values via familiar - * CSS-like shorthand. For example: margin="small auto large". + * Valid values are `0`, `none`, `auto`, and Spacing token values, + * see https://instructure.design/layout-spacing. Apply these values via + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing /** diff --git a/packages/ui-flex/src/Flex/v2/README.md b/packages/ui-flex/src/Flex/v2/README.md index aefa6d084d..cebbe33c0a 100644 --- a/packages/ui-flex/src/Flex/v2/README.md +++ b/packages/ui-flex/src/Flex/v2/README.md @@ -19,19 +19,19 @@ Flex defaults to a `direction` of `row`, creating a horizontal layout. Change `d type: example ---
- + One Two Three Four - + One Two Three Four - + One Two Three @@ -55,19 +55,19 @@ Flex items will have no gap by default. You can set the gap between Flex.Items b type: example ---
- + One Two Three Four - + One Two Three Four - + One Two Three @@ -89,25 +89,25 @@ You can also set the gap between rows and columns by using the `gap` property. M type: example ---
- + One Two Three Four - + One Two Three Four - + One Two Three Four - + One Two Three @@ -238,7 +238,7 @@ Use the `justifyItems` property to change the justification of Flex.Items. type: example ---
- + @@ -250,7 +250,7 @@ type: example - + @@ -316,7 +316,7 @@ type: example Lorem ipsum dolor sit amet consectetur dolor sit - { - + @@ -375,7 +375,7 @@ const Example = () => { withBorder={false} renderIcon={} screenReaderLabel="Print This Image" - margin="0 x-small 0 0" + margin="0 general.spaceSm 0 0" /> { withBorder={false} renderIcon={} screenReaderLabel="Download This Image" - margin="0 x-small 0 0" + margin="0 general.spaceSm 0 0" /> { } + renderTrigger={} isShowingContent={isShowingContent} onShowContent={() => { setIsShowingContent(true) @@ -221,10 +221,10 @@ const Example = () => { shouldContainFocus={false} shouldFocusContentOnTriggerBlur={false} > - +
-
@@ -320,7 +320,7 @@ const Example = () => { return ( - + { ))} - + { return ( @@ -34,7 +34,7 @@ type: example screenReaderLabel="Loading completion" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" renderValue={({ valueNow, valueMax }) => { return ( @@ -50,7 +50,7 @@ type: example screenReaderLabel="Loading completion" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" renderValue={({ valueNow, valueMax }) => { return ( @@ -124,7 +124,7 @@ type: example meterColor="info" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" renderValue={({ valueNow, valueMax }) => { return ( @@ -141,7 +141,7 @@ type: example meterColor="success" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" renderValue={({ valueNow, valueMax }) => { return ( @@ -158,7 +158,7 @@ type: example meterColor="alert" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" renderValue={({ valueNow, valueMax }) => { return ( @@ -175,7 +175,7 @@ type: example meterColor="warning" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" renderValue={({ valueNow, valueMax }) => { return ( @@ -192,7 +192,7 @@ type: example meterColor="danger" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" renderValue={({ valueNow, valueMax }) => { return ( @@ -326,7 +326,7 @@ const Example = () => { as="div" background="primary" padding="medium" - margin="0 0 large 0" + margin="0 0 general.space2xl 0" > Settings} diff --git a/packages/ui-progress/src/ProgressBar/v2/props.ts b/packages/ui-progress/src/ProgressBar/v2/props.ts index 5435e01a47..230f5173e1 100644 --- a/packages/ui-progress/src/ProgressBar/v2/props.ts +++ b/packages/ui-progress/src/ProgressBar/v2/props.ts @@ -95,9 +95,9 @@ type ProgressBarOwnProps = { shouldAnimate?: boolean /** - * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`, - * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via - * familiar CSS-like shorthand. For example: `margin="small auto large"`. + * Valid values are `0`, `none`, `auto`, and Spacing token values, + * see https://instructure.design/layout-spacing. Apply these values via + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing diff --git a/packages/ui-progress/src/ProgressCircle/v2/README.md b/packages/ui-progress/src/ProgressCircle/v2/README.md index a03a8a8c0d..2c5142dae4 100644 --- a/packages/ui-progress/src/ProgressCircle/v2/README.md +++ b/packages/ui-progress/src/ProgressCircle/v2/README.md @@ -17,7 +17,7 @@ type: example screenReaderLabel="Loading completion" valueNow={40} valueMax={60} - margin="0 small 0 0" + margin="0 general.spaceMd 0 0" shouldAnimateOnMount /> @@ -33,7 +33,7 @@ type: example screenReaderLabel="Loading completion" valueNow={40} valueMax={60} - margin="0 small 0 0" + margin="0 general.spaceMd 0 0" shouldAnimateOnMount animationDelay={4000} formatScreenReaderValue={function ({ valueNow, valueMax }) { @@ -114,35 +114,35 @@ type: example meterColor="info" valueNow={40} valueMax={60} - margin="0 0 small" + margin="0 0 general.spaceMd" />
``` diff --git a/packages/ui-progress/src/ProgressCircle/v2/props.ts b/packages/ui-progress/src/ProgressCircle/v2/props.ts index a4df44aa93..b53022e004 100644 --- a/packages/ui-progress/src/ProgressCircle/v2/props.ts +++ b/packages/ui-progress/src/ProgressCircle/v2/props.ts @@ -82,9 +82,9 @@ type ProgressCircleOwnProps = { | ((values: Values) => ProgressCircleMeterColor) | ProgressCircleMeterColor /** - * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`, - * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via - * familiar CSS-like shorthand. For example: `margin="small auto large"`. + * Valid values are `0`, `none`, `auto`, and Spacing token values, + * see https://instructure.design/layout-spacing. Apply these values via + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing /** diff --git a/packages/ui-radio-input/src/RadioInput/v2/README.md b/packages/ui-radio-input/src/RadioInput/v2/README.md index f44b8a5a89..bf762c09d8 100644 --- a/packages/ui-radio-input/src/RadioInput/v2/README.md +++ b/packages/ui-radio-input/src/RadioInput/v2/README.md @@ -13,7 +13,7 @@ type: example --- - + - + { /> - + diff --git a/packages/ui-rating/src/Rating/v2/README.md b/packages/ui-rating/src/Rating/v2/README.md index f52dd4190f..17cfab7f2c 100644 --- a/packages/ui-rating/src/Rating/v2/README.md +++ b/packages/ui-rating/src/Rating/v2/README.md @@ -65,7 +65,7 @@ type: example iconCount={5} valueNow={3.76} valueMax={5} - margin="small"/> + margin="general.spaceMd"/> 4/5 @@ -74,7 +74,7 @@ type: example iconCount={5} valueNow={30} valueMax={100} - margin="small" + margin="general.spaceMd" /> 2/5 @@ -86,7 +86,7 @@ type: example iconCount={5} valueNow={8} valueMax={8} - margin="small"/> + margin="general.spaceMd"/> 5/5 diff --git a/packages/ui-rating/src/Rating/v2/props.ts b/packages/ui-rating/src/Rating/v2/props.ts index 9b05a2cf96..be6ed04cec 100644 --- a/packages/ui-rating/src/Rating/v2/props.ts +++ b/packages/ui-rating/src/Rating/v2/props.ts @@ -59,9 +59,9 @@ type RatingOwnProps = { */ animateFill?: boolean /** - * Valid values are `0`, `none`, `auto`, `xxx-small`, `xx-small`, `x-small`, - * `small`, `medium`, `large`, `x-large`, `xx-large`. Apply these values via - * familiar CSS-like shorthand. For example: `margin="small auto large"`. + * Valid values are `0`, `none`, `auto`, and Spacing token values, + * see https://instructure.design/layout-spacing. Apply these values via + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing } diff --git a/packages/ui-select/src/Select/v2/README.md b/packages/ui-select/src/Select/v2/README.md index 78992236fe..ec5ac742b3 100644 --- a/packages/ui-select/src/Select/v2/README.md +++ b/packages/ui-select/src/Select/v2/README.md @@ -713,7 +713,7 @@ const GroupSelectExample = ({ options }) => { type="notification" variant={variant} standalone - margin="0 x-small xxx-small 0" + margin="0 general.spaceSm general.space2xs 0" /> {text} @@ -764,7 +764,7 @@ const GroupSelectExample = ({ options }) => { : 'primary' } standalone - margin="0 0 xxx-small 0" + margin="0 0 general.space2xs 0" /> } inputRef={(el) => { diff --git a/packages/ui-source-code-editor/src/SourceCodeEditor/v2/README.md b/packages/ui-source-code-editor/src/SourceCodeEditor/v2/README.md index cff4ebc4f4..7d565ae6ff 100644 --- a/packages/ui-source-code-editor/src/SourceCodeEditor/v2/README.md +++ b/packages/ui-source-code-editor/src/SourceCodeEditor/v2/README.md @@ -323,7 +323,7 @@ type: example return ( - + {Object.keys(settings).map((prop) => ( - + {[ 'lineNumbers', @@ -488,7 +488,7 @@ type: example return ( - + - + - + + - +
Contact person
@@ -404,10 +404,10 @@ class PlaygroundExample extends React.Component { } return ( - + + Example Settings )} @@ -479,7 +479,7 @@ class PlaygroundExample extends React.Component { - + - - + + {this.state.breadcrumbs[this.state.breadcrumbs.length - 1]} @@ -540,7 +540,7 @@ class PlaygroundExample extends React.Component { padding="small medium medium" > {Array.from(Array(5)).map((_i, idx) => ( - + {this.fillerText} ))} @@ -1094,7 +1094,7 @@ Use the brand logo over the primary brand color. type: example ---
- + {() => ( - + {() => ( - + {() => ( - + {() => ( - + {() => ( - + {() => ( - + {() => ( - + {() => ( - + {() => ( - + {() => ( - + {() => ( - +
- + Page Content @@ -1974,7 +1974,7 @@ type: example ---
- + {() => ( Contact information

{lorem.sentence()}

- + - +
Contact person
@@ -2115,7 +2115,7 @@ class InPlaceDialogExample extends React.Component { render() { return ( - + {({ currentLayout }) => ( - + { return ( <> - + 1) { return
{props.name} - +
} @@ -387,7 +387,7 @@ const Example = () => { screenReaderLabel="Cancel" onClick={(e) => handleExpandToggle(e, false)} onKeyDown={(e) => handleKeyPress(e, false)} - margin="0 0 0 small" + margin="0 0 0 general.spaceMd" > @@ -395,7 +395,7 @@ const Example = () => { screenReaderLabel="Add new group" onClick={(e) => handleExpandToggle(e, false)} onKeyDown={(e) => handleKeyPress(e, false)} - margin="0 0 0 small" + margin="0 0 0 general.spaceMd" > @@ -480,7 +480,7 @@ const Example = () => { return ( <> - + @@ -633,7 +633,7 @@ const Example = () => { return ( <> - + Hello World @@ -32,7 +32,7 @@ type: example Some informational text that is helpful This ContextView uses the inverse background and medium padding. Its width prop is set to `30rem`, which causes long strings like this to wrap. It also has top margin to separate it from the ContextViews above it. diff --git a/packages/ui-view/src/View/__tests__/View.test.tsx b/packages/ui-view/src/View/__tests__/View.test.tsx index 7cb967b878..ae49c53023 100644 --- a/packages/ui-view/src/View/__tests__/View.test.tsx +++ b/packages/ui-view/src/View/__tests__/View.test.tsx @@ -233,6 +233,45 @@ describe('', () => { expect(newStyles.maxWidth).toEqual('200px') }) + it('should resolve current (era-3) spacing tokens for the margin prop', () => { + const { container } = render( + +

View Content

+
+ ) + + const view = container.querySelector("span[class$='-view']") + const styles = getComputedStyle(view!) + + // general.spaceMd resolves to 0.75rem (12px) + expect(styles.marginTop).toEqual('0.75rem') + expect(styles.marginRight).toEqual('0.75rem') + expect(styles.marginBottom).toEqual('0.75rem') + expect(styles.marginLeft).toEqual('0.75rem') + + // a known token should not emit the "not found in theme" warning + expect(consoleWarningMock).not.toHaveBeenCalledWith( + expect.stringContaining('not found in theme') + ) + }) + + it('should resolve era-3 tokens via CSS-like shorthand for the margin prop', () => { + const { container } = render( + +

View Content

+
+ ) + + const view = container.querySelector("span[class$='-view']") + const styles = getComputedStyle(view!) + + // 3-value shorthand: top | left+right | bottom + expect(styles.marginTop).toEqual('1rem') // general.spaceLg + expect(styles.marginRight).toEqual('auto') + expect(styles.marginBottom).toEqual('1.5rem') // general.spaceXl + expect(styles.marginLeft).toEqual('auto') + }) + it('should meet a11y standards', async () => { const { container } = render(View Content) diff --git a/packages/ui-view/src/View/v2/README.md b/packages/ui-view/src/View/v2/README.md index 31e3fe54fd..523dea6e9e 100644 --- a/packages/ui-view/src/View/v2/README.md +++ b/packages/ui-view/src/View/v2/README.md @@ -20,7 +20,7 @@ type: example --- @@ -52,7 +52,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="primary" > @@ -62,7 +62,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="secondary" > @@ -72,7 +72,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="primary-inverse" > @@ -82,7 +82,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="brand" > @@ -92,7 +92,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="alert" > @@ -102,7 +102,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="success" > @@ -112,7 +112,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="danger" > @@ -122,7 +122,7 @@ type: example as="div" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="warning" > @@ -144,7 +144,7 @@ type: example as="span" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="large" background="primary" shadow="resting" @@ -155,7 +155,7 @@ type: example as="span" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="large" background="primary" shadow="above" @@ -166,7 +166,7 @@ type: example as="span" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="large" background="primary" shadow="topmost" @@ -191,7 +191,7 @@ type: example as="span" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="primary" borderWidth="small" @@ -202,7 +202,7 @@ type: example as="span" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="primary" borderWidth="medium" @@ -213,7 +213,7 @@ type: example as="span" display="inline-block" maxWidth="10rem" - margin="small" + margin="general.spaceMd" padding="small" background="primary" borderWidth="large none" @@ -222,7 +222,7 @@ type: example { as="div" background="primary" padding="small" - margin="0 0 small" + margin="0 0 general.spaceMd" borderWidth="small" > { borderRadius = { { { display="inline-block" height="100px" width="100px" - margin="small" + margin="general.spaceMd" background="primary" borderRadius="circle" borderWidth="small" @@ -583,7 +583,7 @@ const FocusedExample = () => { > { { { as="div" height="7rem" width="20rem" - margin="medium none x-large" + margin="general.spaceXl none general.space2xl" overflowY={overflowY} overflowX={overflowX} withVisualDebug @@ -736,7 +736,7 @@ type: example > @@ -744,7 +744,7 @@ type: example @@ -772,7 +772,7 @@ type: example > @@ -799,7 +799,7 @@ type: example display="inline-block" withVisualDebug textAlign="end" - margin="large auto" + margin="general.space2xl auto" padding="0 small 0 0" > diff --git a/packages/ui-view/src/View/v2/props.ts b/packages/ui-view/src/View/v2/props.ts index c14df20c36..919dffee51 100644 --- a/packages/ui-view/src/View/v2/props.ts +++ b/packages/ui-view/src/View/v2/props.ts @@ -163,7 +163,7 @@ type ViewOwnProps = { /** * Valid values are `0`, `none`, `auto`, and Spacing token values, * see https://instructure.design/layout-spacing. Apply these values via - * familiar CSS-like shorthand. For example, `margin="small auto large"`. + * familiar CSS-like shorthand. For example, `margin="general.spaceMd auto"`. */ margin?: Spacing /** diff --git a/regression-test/src/app/view/page.tsx b/regression-test/src/app/view/page.tsx index 8fb11fe12d..00c245d64f 100644 --- a/regression-test/src/app/view/page.tsx +++ b/regression-test/src/app/view/page.tsx @@ -271,6 +271,27 @@ export default function ViewPage() {
Paragraph-like content
+ + {/* Current (era-3) spacing tokens via dot-path notation */} +
+ + margin="general.spaceMd" + + + margin="general.spaceLg auto general.spaceXl" + + + margin="gap.cards.md" + + + margin="padding.card.lg" + +
) }