;
+};
diff --git a/packages/storybook/src/nimble/button/button-sections.ts b/packages/storybook/src/nimble/button/button-sections.ts
new file mode 100644
index 0000000000..0f030949cf
--- /dev/null
+++ b/packages/storybook/src/nimble/button/button-sections.ts
@@ -0,0 +1,18 @@
+export const buttonSections = {
+ overview: { id: 'overview', title: 'Overview', level: 2 },
+ buttonAnatomy: { id: 'button-anatomy', title: 'Button Anatomy', level: 3 },
+ implementationApi: { id: 'implementation-api', title: 'Implementation & API', level: 2 },
+ usage: { id: 'usage', title: 'Usage', level: 2 },
+ whenToUse: { id: 'when-to-use', title: 'When to Use', level: 3 },
+ appearanceStyling: { id: 'appearance-styling', title: 'Appearance & Styling', level: 2 },
+ appearances: { id: 'appearances', title: 'Appearances', level: 3 },
+ appearanceVariants: { id: 'appearance-variants', title: 'Appearance Variants', level: 3 },
+ sizing: { id: 'sizing', title: 'Sizing', level: 3 },
+ spacingWithOtherComponents: { id: 'spacing-with-other-components', title: 'Spacing with Other Components', level: 3 },
+ buttonGuidelines: { id: 'button-guidelines', title: 'Button Guidelines', level: 2 },
+ accessibility: { id: 'accessibility', title: 'Accessibility', level: 2 },
+ accessibleIconButtons: { id: 'accessible-icon-buttons', title: 'Accessible Icon Buttons', level: 3 },
+ keyboardUsage: { id: 'keyboard-usage', title: 'Keyboard Usage', level: 3 },
+ alternativesRelated: { id: 'alternatives-related', title: 'Alternatives & Related', level: 2 },
+ alternativesToConsider: { id: 'alternatives-to-consider', title: 'Alternatives to Consider', level: 3 }
+} as const;
diff --git a/packages/storybook/src/nimble/button/button.mdx b/packages/storybook/src/nimble/button/button.mdx
index c4f83de384..e9287642e7 100644
--- a/packages/storybook/src/nimble/button/button.mdx
+++ b/packages/storybook/src/nimble/button/button.mdx
@@ -1,46 +1,189 @@
import { Canvas, Meta, Controls, Title } from '@storybook/addon-docs/blocks';
import ContentHiddenDocs from '../patterns/button/content-hidden-docs.mdx';
import ButtonStylingDocs from '../patterns/button/button-styling-docs.mdx';
+import { buttonSections as sections } from './button-sections';
import ComponentApisLink from '../../docs/component-apis-link.mdx';
import { buttonTag } from '@ni/nimble-components/dist/esm/button';
import { anchorButtonTag } from '@ni/nimble-components/dist/esm/anchor-button';
+import { NimbleButton } from '@ni/nimble-react/button';
import * as buttonStories from './button.stories';
-import { Tag } from '../../utilities/story-layout';
+import { ButtonAnatomy } from './button-anatomy';
+import {
+ Do,
+ Dont,
+ StoryAnatomy,
+ StoryApi,
+ StoryGuidance,
+ StoryGuidanceGrid,
+ StoryPage,
+ StoryPreview,
+ StorySection,
+ StorySubsection,
+ Tag
+} from '../../utilities/story-layout';
-
-
-Per [W3C](https://www.w3.org/WAI/ARIA/apg/patterns/button/) - A button is a
-widget that enables users to trigger an action or event, such as submitting a
-form, opening a dialog, canceling an action, or performing a delete operation.
-
-Consider if you want a button that triggers
-navigation to a URL.
-
-
-
-## API
-
-
-
-
-
-## Styling
-
-
-
-### Sizing
-
-Nimble Buttons are currently always 32px tall. Designs exist for other sizes; if
-you need these in an application, please comment on
-[Configurable height for nimble controls (#610)](https://github.com/ni/nimble/issues/610).
-
-{/* ## Usage */}
-
-{/* ## Examples */}
-
-## Accessibility
-
-
-
-{/* ## Resources */}
+
+
+
+
+
+ Per [W3C](https://www.w3.org/WAI/ARIA/apg/patterns/button/), a
+ button is a widget that enables users to trigger an action or event,
+ such as submitting a form, opening a dialog, canceling an action, or
+ performing a delete operation.
+
+
+
+ Consider if you want a button that
+ triggers navigation to a URL.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Primary Actions: Use buttons for primary actions
+ that users need to take, such as submitting a form, saving changes,
+ or proceeding to the next step.
+
+
+
+ Call to Action (CTA): Buttons are ideal for CTAs
+ that encourage users to take a specific action, like "Sign Up,"
+ "Buy Now," or "Learn More."
+
+
+
+
+
+
+ Standard styling options for the button control are found below, in
+ order of usage from least to most prominent. Consider the indented
+ context before employing an appearance variant.
+
+
+
+
+
+ Nimble Buttons are currently always 32px tall. Designs exist for
+ other sizes; if you need these in an application, please comment on
+ [Configurable height for nimble controls (#610)](https://github.com/ni/nimble/issues/610).
+
+
+
+
+ Use consistent spacing between elements to keep layouts clean and
+ organized. Adequate padding around components prevents visual
+ clutter and helps users focus on key information. Use responsive
+ spacing when layouts change across screen sizes.
+
+
+
+
+
+
+
+ Cancel
+ Save
+
+ }
+ >
+ Use one visually prominent action per section and pair it with
+ less prominent actions when users need a clear hierarchy.
+
+
+ Save
+ Submit
+
+ }
+ >
+ Do not use multiple visually prominent buttons together when
+ one action should take priority.
+
+
+ Save Changes
+
+ }
+ >
+ Use concise labels that describe the action the button performs.
+
+
+ Click Here
+
+ }
+ >
+ Avoid vague labels that do not tell users what will happen when
+ the button is activated.
+
+
+
+
+
+
+
+
+
+
+
+ Buttons must remain keyboard accessible so users can move focus
+ to them and activate them with standard keyboard controls.
+
+
+
+
+
+
+
+
+ Consider if you need a button that
+ triggers navigation to a URL.
+
+
+
+
diff --git a/packages/storybook/src/nimble/button/button.stories.ts b/packages/storybook/src/nimble/button/button.stories.ts
index b3205047af..5b44b051de 100644
--- a/packages/storybook/src/nimble/button/button.stories.ts
+++ b/packages/storybook/src/nimble/button/button.stories.ts
@@ -39,6 +39,9 @@ const metadata: Meta = {
parameters: {
actions: {
handles: ['click']
+ },
+ docs: {
+ toc: { disable: true }
}
},
argTypes: {
diff --git a/packages/storybook/src/nimble/button/images/button-anatomy.svg b/packages/storybook/src/nimble/button/images/button-anatomy.svg
new file mode 100644
index 0000000000..976d29419a
--- /dev/null
+++ b/packages/storybook/src/nimble/button/images/button-anatomy.svg
@@ -0,0 +1,64 @@
+
diff --git a/packages/storybook/src/nimble/dialog/dialog.mdx b/packages/storybook/src/nimble/dialog/dialog.mdx
index 4e7292b100..d0e12ded4b 100644
--- a/packages/storybook/src/nimble/dialog/dialog.mdx
+++ b/packages/storybook/src/nimble/dialog/dialog.mdx
@@ -80,7 +80,7 @@ MyDialogOwner.razor
MyDialogOwner.razor.cs
-```cs
+```text
private DialogData _model = new();
private NimbleDialog! _dialog;
diff --git a/packages/storybook/src/nimble/patterns/button/button-styling-docs.mdx b/packages/storybook/src/nimble/patterns/button/button-styling-docs.mdx
index d4430055ef..3ca7470d3a 100644
--- a/packages/storybook/src/nimble/patterns/button/button-styling-docs.mdx
+++ b/packages/storybook/src/nimble/patterns/button/button-styling-docs.mdx
@@ -1,112 +1,117 @@
import { NimbleIconKey } from '@ni/nimble-react/icons/key';
-import { Frame, Container, Column, Do, Dont, Divider } from '../../../utilities/story-layout';
+import { StoryShowcase, StorySubsection } from '../../../utilities/story-layout';
+import { buttonSections } from '../../button/button-sections';
-### Appearances
+
-These are the standard styling options for the button. Each should be considered
-for use before employing an appearance variant.
+These are the standard styling options for the button, ordered from least to
+most visually prominent. Consider each option before employing an appearance
+variant.
#### Ghost Button
-
-
-
+
+
+
-
-
-
-
-
Ghost is the default appearance and should be the first considered for use.
-
- Use as the default and standard option to create a clean airy and open UI
- feel. Ghost buttons fit comfortably in tight spaces and help control the
- visual density of the UI.
-
-
- Be careful when using that the surrounding context does not cause this
- button to be confused for emphasized body text, tabs or a standalone links.
-
-
Use in combination with a primary outline or primary block buttons to create a hierarchy of importance. There is no primary ghost button.
-
-
-
-
+
+
+
+
When to Use
+
+
Ghost is the default appearance and should be the first considered for use.
+
+ Use as the default and standard option to create a clean airy and open UI
+ feel. Ghost buttons fit comfortably in tight spaces and help control the
+ visual density of the UI.
+
+
+ Be careful when using that the surrounding context does not cause this
+ button to be confused for emphasized body text, tabs or a standalone links.
+
+
Use in combination with a primary outline or primary block buttons to create a hierarchy of importance. There is no primary ghost button.
+
+
+
#### Outline Button
-
-
-
+
+
+
-
-
-
-
- Outline is the secondary style and should be considered for
- use when ghost button is not sufficient.
-
-
- Use as an alternative standard button when a ghost button is
- not suitable. Use like a ghost button to create a clean,
- light and airy feel.
-
-
- The outline button is more visually direct about the
- control's functionality than a ghost button.
-
-
- Use in combination with ghost buttons (but not block
- buttons) to create hierarchy.
-
-
-
-
-
+
+
+
+
When to Use
+
+
+ Outline is the secondary style and should be considered for
+ use when ghost button is not sufficient.
+
+
+ Use as an alternative standard button when a ghost button is
+ not suitable. Use like a ghost button to create a clean,
+ light and airy feel.
+
+
+ The outline button is more visually direct about the
+ control's functionality than a ghost button.
+
+
+ Use in combination with ghost buttons (but not block
+ buttons) to create hierarchy.
+
+
+
+
#### Block Button
-
-
-
+
+
+
-
-
-
-
- Block is the tertiary style used for creating the most eye
- catching and functionally direct button. Use in areas where
- controls are not often present or obvious, or when lots of
- busy information can cause an important control to be
- overlooked.
-
-
- Use as a standard button when the most visible solution is
- required. Use as an alternative to overly subtle button
- solutions when it is important to emphasize an action and
- the functionality of the control.
-
-
- Use in combination with ghost buttons (but not outline
- buttons) to create hierarchy.
-
-
-
-
-
-
-### Appearance Variants
+
+
+
+
When to Use
+
+
+ Block is the tertiary style used for creating the most eye
+ catching and functionally direct button. Use in areas where
+ controls are not often present or obvious, or when lots of
+ busy information can cause an important control to be overlooked.
+
+
+ Use as a standard button when the most visible solution is
+ required. Use as an alternative to overly subtle button
+ solutions when it is important to emphasize an action and
+ the functionality of the control.
+
+
+ Use in combination with ghost buttons (but not outline
+ buttons) to create hierarchy.
+
+
+
+
+
+
+
+
Button appearance variants are mainly used when a button needs be distinguished
for one of the following reasons:
@@ -119,78 +124,81 @@ There are two available values for `appearance-variant`: `primary` and `accent`.
#### Accent Button
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
When to Use
+
+
Use only 1 accent button in a section. It should be used when
trying to achieve the most prominent eye-catching approach.
Consider the contextual implications of using a green colored
button in relation to its name or metaphor. Remember that color
has accessibility constraints and the color alone should not be
relied on.
-
-
- Use in situations that lack color and enthusiasm to help support
- the brand.
-
- Use in combination with ghost buttons to create hierarchy.
-
+
+
Use in situations that lack color and enthusiasm to help support the brand.
+
Use in combination with ghost buttons to create hierarchy.
+
Do not use an outline button with a block button to create
hierarchy.
-
-
-
-
+
Use only 1 primary button in a section. It should be used when
there is a conflict with color and its context.
-
- Use in combination with ghost buttons to create hierarchy.
-
+
+
Use in combination with ghost buttons to create hierarchy.
+
Do not use an outline button with a block button to create
hierarchy.
-
-
-
-
+
+
+
+
#### Examples
To see more examples of appearance variant button hierarchy, see the Figma docs
for
[Primary and Standard Actions](https://www.figma.com/file/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?type=design&node-id=1604-74603&mode=design&t=SQ3lyK83VHBUaOkg-0).
+
+
diff --git a/packages/storybook/src/nimble/select/select.mdx b/packages/storybook/src/nimble/select/select.mdx
index 0d5f0b8c13..dd998e8ca9 100644
--- a/packages/storybook/src/nimble/select/select.mdx
+++ b/packages/storybook/src/nimble/select/select.mdx
@@ -13,11 +13,42 @@ import { comboboxTag } from '@ni/nimble-components/dist/esm/combobox';
import { listOptionTag } from '@ni/nimble-components/dist/esm/list-option';
import { listOptionGroupTag } from '@ni/nimble-components/dist/esm/list-option-group';
import { radioTag } from '@ni/nimble-components/dist/esm/radio';
-import { Tag } from '../../utilities/story-layout';
+import {
+ StoryApi,
+ StoryPage,
+ StoryPreview,
+ StorySection,
+ StorySubsection,
+ Tag
+} from '../../utilities/story-layout';
+
+export const sections = {
+ overview: { id: 'overview', title: 'Overview', level: 2 },
+ implementationApi: { id: 'implementation-api', title: 'Implementation & API', level: 2 },
+ api: { id: 'api', title: 'API', level: 3 },
+ listOption: { id: 'list-option', title: 'List Option', level: 3 },
+ listOptionGroup: { id: 'list-option-group', title: 'List Option Group', level: 3 },
+ styling: { id: 'styling', title: 'Styling', level: 2 },
+ examples: { id: 'examples', title: 'Examples', level: 2 },
+ placeholder: { id: 'placeholder', title: 'Placeholder', level: 3 },
+ dynamicOptions: { id: 'dynamic-options', title: 'Dynamic options', level: 3 }
+};
+
+
The Select control allows users to choose from a list of options displayed in a
dropdown menu.
@@ -25,15 +56,21 @@ Use when you need to present a small set of options.
Use if users should be able to enter a custom value
in addition to selecting from the list.
+
-
+
+
+
+
-## API
+
+
+
-### List Option
+
@@ -48,22 +85,31 @@ on the Select control. Without this, the Select may display unexpected behavior
(like reverting to the placeholder value when updating the list of filtered
options).
-### List Option Group
+
+
+
-## Styling
+
+
+
+
+
+
By default, the select control resizes to the selected option size. In most
layouts, give the select a specific `width` to align with other items. Ensure
the control is wide enough so labels do not wrap.
+
+
{/* ## Usage */}
-## Examples
+
-### Placeholder
+
To display placeholder text within the select you must provide an option that
has the `disabled`, `selected` and `hidden` attributes set. This option will not
@@ -81,9 +127,12 @@ the end of the prompt.
placeholder as `disabled` and `hidden` and ensure that it is the first option
in the list. See [#2783](https://github.com/ni/nimble/issues/2783) for more detail.*
-
+
+
+
+
-### Dynamic options
+
There are scenarios that require not all possible options to be available
initially, such as when the set of all options is too large to be loaded at
@@ -125,6 +174,11 @@ group should be displayed, and all options within the group should be displayed
as well. If the group label does not match the filter text, then options within
the group should only be displayed if they match the filter text.
+
+
+
+
+
{/* ## Accessibility */}
{/* ## Resources */}
diff --git a/packages/storybook/src/nimble/select/select.stories.ts b/packages/storybook/src/nimble/select/select.stories.ts
index 4bbcfcd39f..9f6d92b124 100644
--- a/packages/storybook/src/nimble/select/select.stories.ts
+++ b/packages/storybook/src/nimble/select/select.stories.ts
@@ -138,6 +138,11 @@ When the \`loading-visible\` attribute is set, a loading spinner will be display
const metadata: Meta = {
title: 'Components/Select',
+ parameters: {
+ docs: {
+ toc: { disable: true }
+ }
+ },
render: createUserSelectedThemeStory(html`
${disableStorybookZoomTransform}
<${selectTag}
diff --git a/packages/storybook/src/nimble/table/table.mdx b/packages/storybook/src/nimble/table/table.mdx
index 84bd087fae..d2e6cb3a29 100644
--- a/packages/storybook/src/nimble/table/table.mdx
+++ b/packages/storybook/src/nimble/table/table.mdx
@@ -70,7 +70,7 @@ MyComponent.razor
MyComponent.razor.cs
-```cs
+```text
...
private NimbleTable? _table;
private IEnumerable TableData { get; set; } = Enumerable.Empty();
diff --git a/packages/storybook/src/ok/ts/icon-dynamic/ts-icon-dynamic.mdx b/packages/storybook/src/ok/ts/icon-dynamic/ts-icon-dynamic.mdx
index 85512f456c..f99bd9c176 100644
--- a/packages/storybook/src/ok/ts/icon-dynamic/ts-icon-dynamic.mdx
+++ b/packages/storybook/src/ok/ts/icon-dynamic/ts-icon-dynamic.mdx
@@ -41,7 +41,7 @@ customElements
Register once after first render using the `OkTsIconDynamic.RegisterIconDynamicAsync` helper:
-```cs
+```text
@inject IJSRuntime JSRuntime
protected override async Task OnAfterRenderAsync(bool firstRender)
diff --git a/packages/storybook/src/utilities/story-layout.tsx b/packages/storybook/src/utilities/story-layout.tsx
index 4ae12100fa..67e4cee478 100644
--- a/packages/storybook/src/utilities/story-layout.tsx
+++ b/packages/storybook/src/utilities/story-layout.tsx
@@ -1,7 +1,45 @@
import React, { type ReactNode } from 'react';
import { NimbleIconCheck } from '@ni/nimble-react/icons/check';
-import { NimbleThemeProvider } from '@ni/nimble-react/theme-provider';
-import { NimbleIconExclamationMark } from '@ni/nimble-react/icons/exclamation-mark';
+import { NimbleThemeProvider, type ThemeProvider } from '@ni/nimble-react/theme-provider';
+import { NimbleIconXmark } from '@ni/nimble-react/icons/xmark';
+import {
+ applicationBackgroundColor,
+ bodyEmphasizedFont,
+ bodyEmphasizedFontColor,
+ bodyDisabledFontColor,
+ bodyFontColor,
+ bodyPlus1FontFamily,
+ bodyPlus1FontSize,
+ bodyPlus1FontWeight,
+ bodyPlus1EmphasizedFontWeight,
+ bodyPlus1EmphasizedFont,
+ bodyPlus1Font,
+ bodyPlus1FontColor,
+ buttonAccentBlockFontColor,
+ buttonLabelFont,
+ buttonLabelFontWeight,
+ cardBorderColor,
+ dialogLargeWidth,
+ dividerBackgroundColor,
+ dividerWidth,
+ elevation1BoxShadow,
+ failColor,
+ largePadding,
+ linkProminentFontColor,
+ mediumPadding,
+ passColor,
+ smallPadding,
+ standardPadding,
+ subtitlePlus1FontColor,
+ tableRowBorderColor,
+ tooltipCaptionFont,
+ titlePlus1FontColor,
+ titlePlus2FontColor,
+ headlinePlus1FontColor,
+ iconColor,
+} from '@ni/nimble-components/dist/esm/theme-provider/design-tokens';
+import { tokenNames } from '@ni/nimble-components/dist/esm/theme-provider/design-token-names';
+import { tokenValues } from '@ni/nimble-components/dist/esm/theme-provider/design-token-values';
export const css = (strings: TemplateStringsArray, ...values: unknown[]): React.JSX.Element =>