From 4229e2a11290ca1ac9acaa436aca733e2bdca52f Mon Sep 17 00:00:00 2001 From: Zohar Manor-Abel Date: Wed, 26 Aug 2026 10:24:04 +0100 Subject: [PATCH] Improve typography foundations docs and Storybook examples - Expand MUI Typography stories to cover the full DS Typography scale - Add variant guide, size ramp, and weight/line-height/letter-spacing token stories - Add truncation & overflow story with Tooltip pairing - Clean up colour/variant story organisation and descriptions - Update typography foundations docs --- .storybook/storybook.css | 16 ++ .../MUI/DataDisplay/Typography.stories.tsx | 214 ++++++++++++-- src/storybook/foundation/2. typography.mdx | 265 +++++++++++++++--- 3 files changed, 424 insertions(+), 71 deletions(-) diff --git a/.storybook/storybook.css b/.storybook/storybook.css index 03cbfd65..4e67f527 100644 --- a/.storybook/storybook.css +++ b/.storybook/storybook.css @@ -112,6 +112,22 @@ pre .language-shell:not(.MuiTypography-root) { max-width: 58ch; } +/* Typeface samples (Foundations/Typography) */ +.ds-docs h3.ds-type-sample-inter { + font-family: var(--ds-font-family-default) !important; +} +.ds-docs h3.ds-type-sample-outfit { + font-family: var(--ds-font-family-display) !important; +} +.ds-docs h3.ds-type-sample-mono { + font-family: var(--ds-font-family-mono) !important; +} +.ds-docs h3.ds-type-sample-inter, +.ds-docs h3.ds-type-sample-outfit, +.ds-docs h3.ds-type-sample-mono { + font-size: var(--ds-font-size-900) !important; +} + /* MDX Components */ .ds-docs code { diff --git a/src/components/MUI/DataDisplay/Typography.stories.tsx b/src/components/MUI/DataDisplay/Typography.stories.tsx index 6354ea4a..0e66fe4e 100644 --- a/src/components/MUI/DataDisplay/Typography.stories.tsx +++ b/src/components/MUI/DataDisplay/Typography.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { Box, Stack, Typography } from "../MuiWrapped"; +import { Box, Stack, Tooltip, Typography } from "../MuiWrapped"; import { colourSet } from "../../../utils/diamond"; import { TypographyProps } from "@mui/material/Typography"; import { muiDocsParameters } from "../../../../.storybook/muiDocsParameters"; @@ -50,6 +50,32 @@ const sizeRamp: { { px: 11, variants: ["overlineSmall"] }, ]; +const fontWeightScale: { token: string; label: string; value: string }[] = [ + { token: "--ds-font-weight-light", label: "Light", value: "300" }, + { token: "--ds-font-weight-regular", label: "Regular", value: "400" }, + { token: "--ds-font-weight-medium", label: "Medium", value: "500" }, + { token: "--ds-font-weight-semibold", label: "Semibold", value: "600" }, + { token: "--ds-font-weight-bold", label: "Bold", value: "700" }, +]; + +const lineHeightScale: { token: string; label: string; value: string }[] = [ + { token: "--ds-line-height-tight", label: "Tight", value: "1.1" }, + { token: "--ds-line-height-condensed", label: "Condensed", value: "1.2" }, + { token: "--ds-line-height-normal", label: "Normal", value: "1.4" }, + { token: "--ds-line-height-relaxed", label: "Relaxed", value: "1.5" }, +]; + +const letterSpacingScale: { token: string; label: string; value: string }[] = [ + { token: "--ds-letter-spacing-tight", label: "Tight", value: "-0.03em" }, + { + token: "--ds-letter-spacing-condensed", + label: "Condensed", + value: "-0.01em", + }, + { token: "--ds-letter-spacing-normal", label: "Normal", value: "0" }, + { token: "--ds-letter-spacing-wide", label: "Wide", value: "0.08em" }, +]; + type VariantGuideEntry = { variant: NonNullable; note: string | string[]; @@ -349,36 +375,6 @@ export const Basic: Story = { render: (args) => , }; -export const SizeRamp: Story = { - name: "Size ramp", - render: (args) => ( - - {sizeRamp.map(({ px, variants }) => ( - - - {px}px - - - {variants.map((variant) => ( - - {variant} - - ))} - - - ))} - - ), -}; - export const VariantGuide: Story = { name: "Variant guide", parameters: { @@ -427,6 +423,116 @@ export const VariantGuide: Story = { ), }; +export const SizeRamp: Story = { + name: "Size ramp", + render: (args) => ( + + {sizeRamp.map(({ px, variants }) => ( + + + {px}px + + + {variants.map((variant) => ( + + {variant} + + ))} + + + ))} + + ), +}; + +export const ScaleTokens: Story = { + name: "Weight, line height & letter spacing", + parameters: { + controls: { disable: true }, + docs: { + description: { + story: + "Weight, line height and letter spacing tokens underpin the typography variants above. Prefer the variants directly — these tokens are for building new variants or components.", + }, + }, + }, + render: (_args) => ( + + + + Font weight + + + {fontWeightScale.map(({ token, label, value }) => ( + + + {label} · {value} · {token} + + + The quick brown fox jumps over the lazy dog. + + + ))} + + + + + + Line height + + + {lineHeightScale.map(({ token, label, value }) => ( + + + {label} · {value} · {token} + + + The quick brown fox jumps over the lazy dog and again, the quick + brown fox jumps over the lazy dog. + + + ))} + + + + + + Letter spacing + + + {letterSpacingScale.map(({ token, label, value }) => ( + + + {label} · {value} · {token} + + + Diamond + + + ))} + + + + ), +}; + export const ColourGuide: Story = { name: "Colour guide", parameters: { @@ -563,3 +669,49 @@ Use this when the document outline calls for an \`h1\` but the design calls for ), }; + +const longValue = + "/dls/i15-1/data/2026/cm12345-1/processed/sample_0042_scan_00187.nxs"; + +export const TruncationAndOverflow: Story = { + name: "Truncation & overflow", + parameters: { + controls: { disable: true }, + docs: { + description: { + story: + "Use `noWrap` inside a width-constrained container to truncate long technical values with an ellipsis. Pair it with a `Tooltip` so the full value is still available on hover or focus.", + }, + }, + }, + render: (_args) => ( + + + + Without noWrap — wraps and can push the layout + + {longValue} + + + + + With noWrap — truncates to an ellipsis + + + {longValue} + + + + + + With noWrap + Tooltip — full value on hover/focus + + + + {longValue} + + + + + ), +}; diff --git a/src/storybook/foundation/2. typography.mdx b/src/storybook/foundation/2. typography.mdx index b368af97..9829a494 100644 --- a/src/storybook/foundation/2. typography.mdx +++ b/src/storybook/foundation/2. typography.mdx @@ -15,6 +15,13 @@ import { Meta } from "@storybook/blocks"; ## Typefaces + + + + + + + @@ -90,6 +97,11 @@ Use heading levels in order where possible. Avoid jumping directly from h1 to h4 ## Typography variants
Typeface
+ + + + + @@ -153,6 +165,10 @@ Diamond DS provides a shared typography scale that underpins all typography variants.
Group
+ + + + @@ -238,6 +254,174 @@ design system. Avoid applying arbitrary font sizes when an existing typography variant already communicates the correct hierarchy and meaning. +## Font weight scale + +
Token
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TokenWeightTypical use
+ --ds-font-weight-light + 300 + Not used by any variant. Reserve for deliberate light treatments in + large display type. +
+ --ds-font-weight-regular + 400Body copy, captions, meta text and mono values
+ --ds-font-weight-medium + 500 + h1/h2 and h1Display/ + h2Display +
+ --ds-font-weight-semibold + 600 + h3h6, h3Display/ + h4Display, subtitles, overlines and buttons +
+ --ds-font-weight-bold + 700 + Not used by any variant. Reserve for inline emphasis within body text + rather than a whole heading. +
+ +## Line height scale + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TokenValueTypical use
+ --ds-line-height-tight + 1.1Large display headings
+ --ds-line-height-condensed + 1.2Headings and utility text
+ --ds-line-height-normal + 1.4Captions and dense text
+ --ds-line-height-relaxed + 1.5Body copy and long-form reading
+ +## Letter spacing scale + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TokenValueTypical use
+ --ds-letter-spacing-tight + -0.03emLarge display headings
+ --ds-letter-spacing-condensed + -0.01emHeadings
+ --ds-letter-spacing-normal + 0Body and most UI text
+ --ds-letter-spacing-wide + 0.08emOverlines and uppercase labels
+ +Weight, line height and letter spacing tokens are primarily intended for +creating reusable components, defining typography variants, and establishing +consistent scale across the design system. + +Avoid applying arbitrary weights, line heights or letter spacing when an +existing typography variant already communicates the correct hierarchy and +meaning. + ## Display and heading variants Use display variants for large, high-level moments such as landing pages, @@ -264,44 +448,30 @@ standard heading hierarchy within operational interfaces. ## Choosing a typeface -

- Inter -

+

Inter

-Inter is the default interface typeface. +**Inter** is the default interface typeface. -Use Inter for: +Use for: - Navigation +- Body text - Buttons - Forms - Tables - Dialogues - Cards -- Body text - Labels - Status messages Inter should be the default choice unless there is a specific reason to use Outfit or IBM Plex Mono. -

- Outfit -

+

Outfit

-Outfit is used for display and high-level headings. +**Outfit** is used for display and high-level headings. -Use Outfit sparingly for: +Use sparingly for: - Product names - Major page titles @@ -310,34 +480,24 @@ Use Outfit sparingly for: Do not use Outfit for dense application UI, tables, forms, or technical values. -

- IBM Plex Mono -

+

IBM Plex Mono

-IBM Plex Mono is used for technical and aligned information. +**IBM Plex Mono** is used for technical and aligned information. -Use IBM Plex Mono for: +Use for: -- Beamline IDs -- Sample IDs -- Proposal IDs -- Timestamps - Code - Logs - Console output +- Timestamps +- Numeric values where alignment helps comparison +- IDs (proposals, samples, beamlines) - Numeric columns - Technical table values -- Numeric values where alignment helps comparison - File paths - API-like values -Do not use mono type for general UI text. It reduces readability when used too -widely. +Do not use mono type for general UI text. ## Technical values @@ -354,6 +514,28 @@ Use mono type where users need to inspect precise values: For tables with mixed content, use mono only for the technical cells rather than the whole table. +## Truncation and overflow + +Long technical values (paths, IDs, timestamps) can overflow a constrained +layout such as a table cell or a narrow panel. + +Use `noWrap` inside a width-constrained container to truncate the value to a +single line with an ellipsis, and pair it with a tooltip so the full value is +still available on hover or focus. + +```tsx + + + + /dls/i15-1/data/2026/cm12345-1/processed/sample_0042.nxs + + + +``` + +Don't truncate a value without also giving users a way to read it in full. +Prefer a tooltip, or reflow the layout so the value has room to wrap. + ## Numbers and units Keep numbers and units readable. @@ -464,8 +646,11 @@ Logs and console output should use mono type. ```tsx - [14:30:15] Starting data acquisition pipeline [14:30:18] Detector initialised - successfully [14:30:22] Scan started — energy 12.4 keV, exposure 0.5 s + [14:30:15] Starting data acquisition pipeline +
+ [14:30:18] Detector initialised successfully +
+ [14:30:22] Scan started — energy 12.4 keV, exposure 0.5 s
```