diff --git a/change/@ni-nimble-components-1996d396-34af-4f72-95dd-d141df4ad7e4.json b/change/@ni-nimble-components-1996d396-34af-4f72-95dd-d141df4ad7e4.json
new file mode 100644
index 0000000000..000b12a582
--- /dev/null
+++ b/change/@ni-nimble-components-1996d396-34af-4f72-95dd-d141df4ad7e4.json
@@ -0,0 +1,7 @@
+{
+ "type": "minor",
+ "comment": "Add design tokens for additional spinner sizes, and update docs.",
+ "packageName": "@ni/nimble-components",
+ "email": "20709258+msmithNI@users.noreply.github.com",
+ "dependentChangeType": "patch"
+}
diff --git a/packages/nimble-components/src/spinner/styles.ts b/packages/nimble-components/src/spinner/styles.ts
index d217bf4a7d..9990d07435 100644
--- a/packages/nimble-components/src/spinner/styles.ts
+++ b/packages/nimble-components/src/spinner/styles.ts
@@ -5,6 +5,7 @@ import {
Black91,
White
} from '@ni/nimble-tokens/dist/styledictionary/js/tokens';
+import { spinnerSmallHeight } from '../theme-provider/design-tokens';
import { Theme } from '../theme-provider/types';
import { themeBehavior } from '../utilities/style/theme';
@@ -12,8 +13,8 @@ export const styles = css`
${display('inline-flex')}
:host {
- width: 16px;
- height: 16px;
+ height: ${spinnerSmallHeight};
+ aspect-ratio: 1 / 1;
}
div.container {
diff --git a/packages/nimble-components/src/spinner/tests/spinner-matrix.stories.ts b/packages/nimble-components/src/spinner/tests/spinner-matrix.stories.ts
index 71c0e30a33..14c95bfe39 100644
--- a/packages/nimble-components/src/spinner/tests/spinner-matrix.stories.ts
+++ b/packages/nimble-components/src/spinner/tests/spinner-matrix.stories.ts
@@ -9,7 +9,11 @@ import {
createMatrixThemeStory,
createStory
} from '../../utilities/tests/storybook';
-import { bodyFontColor } from '../../theme-provider/design-tokens';
+import {
+ bodyFontColor,
+ spinnerLargeHeight,
+ spinnerMediumHeight
+} from '../../theme-provider/design-tokens';
import { hiddenWrapper } from '../../utilities/tests/hidden';
import '../../all-components';
@@ -28,8 +32,9 @@ const metadata: Meta = {
export default metadata;
const sizeStates = [
- ['16x16', 'width: 16px; height: 16px'],
- ['32x32', 'width: 32px; height: 32px']
+ ['Small (16x16)', ''],
+ ['Medium (32x32)', `height: var(${spinnerMediumHeight.cssCustomProperty})`],
+ ['Large (64x64)', `height: var(${spinnerLargeHeight.cssCustomProperty})`]
];
type SizeState = typeof sizeStates[number];
diff --git a/packages/nimble-components/src/spinner/tests/spinner.stories.ts b/packages/nimble-components/src/spinner/tests/spinner.stories.ts
index 97bde923bd..c82d14af1a 100644
--- a/packages/nimble-components/src/spinner/tests/spinner.stories.ts
+++ b/packages/nimble-components/src/spinner/tests/spinner.stories.ts
@@ -3,12 +3,31 @@ import type { Meta, StoryObj } from '@storybook/html';
import { withXD } from 'storybook-addon-xd-designs';
import { createUserSelectedThemeStory } from '../../utilities/tests/storybook';
import '../../all-components';
+import {
+ spinnerLargeHeight,
+ spinnerMediumHeight
+} from '../../theme-provider/design-tokens';
+import {
+ scssPropertyFromTokenName,
+ scssPropertySetterMarkdown,
+ tokenNames
+} from '../../theme-provider/design-token-names';
-const overviewText = 'The `nimble-spinner` is an animating indicator that can be placed in a particular region of a page to represent loading progress, or an ongoing operation, of an indeterminate / unknown duration.'
- + '
The default spinner size is 16x16. Other sizes can be set via width/height CSS styles on the component, and it will scale appropriately.
'
- + 'Other sizes suggested by the Nimble designers: 32x32, 48x48, 64x64, 96x96, 128x128.
';
+const spinnerSize = {
+ small: null,
+ medium: `height: var(${spinnerMediumHeight.cssCustomProperty});`,
+ large: `height: var(${spinnerLargeHeight.cssCustomProperty});`
+} as const;
-const metadata: Meta = {
+interface SpinnerArgs {
+ size: keyof typeof spinnerSize;
+}
+
+const overviewText = 'The `nimble-spinner` is an animating indicator that can be placed in a particular region of a page to represent '
+ + 'loading progress, or an ongoing operation, of an indeterminate / unknown duration.
'
+ + 'See the `size` argument details for information on customizing the spinner size.
';
+
+const metadata: Meta = {
title: 'Spinner',
decorators: [withXD],
parameters: {
@@ -22,15 +41,53 @@ const metadata: Meta = {
'https://xd.adobe.com/view/33ffad4a-eb2c-4241-b8c5-ebfff1faf6f6-66ac/screen/dece308f-79e7-48ec-ab41-011f3376b49b/specs/'
}
},
- argTypes: {},
+ argTypes: {
+ size: {
+ description:
+ 'Size of the spinner component.Usage details
To customize its size, set its CSS '
+ + 'height to a design token, and its width will automatically match its height:
'
+ + `- For Small (16x16): ${scssPropertySetterMarkdown(
+ tokenNames.spinnerSmallHeight,
+ 'height'
+ )}
`
+ + `- For Medium (32x32): ${scssPropertySetterMarkdown(
+ tokenNames.spinnerMediumHeight,
+ 'height'
+ )}
`
+ + `- For Large (64x64): ${scssPropertySetterMarkdown(
+ tokenNames.spinnerLargeHeight,
+ 'height'
+ )}
`,
+ options: Object.keys(spinnerSize),
+ table: { defaultValue: { summary: 'Small (16x16)' } },
+ control: {
+ type: 'radio',
+ labels: {
+ small: `Small - 16x16 (default) - ${scssPropertyFromTokenName(
+ tokenNames.spinnerSmallHeight
+ )}`,
+ medium: `Medium - 32x32 - ${scssPropertyFromTokenName(
+ tokenNames.spinnerMediumHeight
+ )}`,
+ large: `Large - 64x64 - ${scssPropertyFromTokenName(
+ tokenNames.spinnerLargeHeight
+ )}`
+ }
+ }
+ }
+ },
// prettier-ignore
render: createUserSelectedThemeStory(html`
-
+
`),
- args: {}
+ args: {
+ size: 'small'
+ }
};
export default metadata;
-export const spinner: StoryObj = {};
+export const spinner: StoryObj = {};
diff --git a/packages/nimble-components/src/theme-provider/design-token-comments.ts b/packages/nimble-components/src/theme-provider/design-token-comments.ts
index a24bced8ee..40667edcc6 100644
--- a/packages/nimble-components/src/theme-provider/design-token-comments.ts
+++ b/packages/nimble-components/src/theme-provider/design-token-comments.ts
@@ -40,6 +40,9 @@ export const comments: { readonly [key in TokenName]: string | null } = {
iconSize: 'Standard layout height for all icons',
groupHeaderTextTransform: 'CSS text-transform string to use for headers',
drawerWidth: 'TODO: delete when able',
+ spinnerSmallHeight: 'Small height (16px) for a spinner component',
+ spinnerMediumHeight: 'Medium height (32px) for a spinner component',
+ spinnerLargeHeight: 'Large height (64px) for a spinner component',
smallDelay:
'Elements with small transition areas, such as icons and selection controls, have short durations.',
mediumDelay:
diff --git a/packages/nimble-components/src/theme-provider/design-token-names.ts b/packages/nimble-components/src/theme-provider/design-token-names.ts
index 4751bc0969..e78f583d5a 100644
--- a/packages/nimble-components/src/theme-provider/design-token-names.ts
+++ b/packages/nimble-components/src/theme-provider/design-token-names.ts
@@ -36,6 +36,9 @@ export const tokenNames: { readonly [key in TokenName]: string } = {
iconSize: 'icon-size',
groupHeaderTextTransform: 'group-header-text-transform',
drawerWidth: 'drawer-width',
+ spinnerSmallHeight: 'spinner-small-height',
+ spinnerMediumHeight: 'spinner-medium-height',
+ spinnerLargeHeight: 'spinner-large-height',
smallDelay: 'small-delay',
mediumDelay: 'medium-delay',
largeDelay: 'large-delay',
@@ -213,6 +216,10 @@ const prefix = 'ni-nimble';
export const styleNameFromTokenName = (tokenName: string): string => `${prefix}-${tokenName}`;
export const cssPropertyFromTokenName = (tokenName: string): string => `--${prefix}-${tokenName}`;
export const scssPropertyFromTokenName = (tokenName: string): string => `$${prefix}-${tokenName}`;
+export const scssPropertySetterMarkdown = (
+ tokenName: string,
+ cssProperty: string
+): string => `\`${cssProperty}: $${prefix}-${tokenName};\``;
export const scssInternalPropertyFromTokenName = (tokenName: string): string => `$${prefix}-internal-${tokenName}`;
export const scssInternalPropertySetterMarkdown = (
tokenName: string,
diff --git a/packages/nimble-components/src/theme-provider/design-tokens.ts b/packages/nimble-components/src/theme-provider/design-tokens.ts
index b403cf7a96..386641fd34 100644
--- a/packages/nimble-components/src/theme-provider/design-tokens.ts
+++ b/packages/nimble-components/src/theme-provider/design-tokens.ts
@@ -214,6 +214,16 @@ export const drawerWidth = DesignToken.create(
styleNameFromTokenName(tokenNames.drawerWidth)
).withDefault('784px');
+export const spinnerSmallHeight = DesignToken.create(
+ styleNameFromTokenName(tokenNames.spinnerSmallHeight)
+).withDefault('16px');
+export const spinnerMediumHeight = DesignToken.create(
+ styleNameFromTokenName(tokenNames.spinnerMediumHeight)
+).withDefault('32px');
+export const spinnerLargeHeight = DesignToken.create(
+ styleNameFromTokenName(tokenNames.spinnerLargeHeight)
+).withDefault('64px');
+
// Drop Shadow Tokens
export const elevation1BoxShadow = DesignToken.create(
styleNameFromTokenName(tokenNames.elevation1BoxShadow)