Improve docs readability: example panels, heading scale, text measure

- Example demos use bg-surface and join their code panel into one card
- Larger h1/h2/h3 in .prose and a ~70-character measure for running text
This commit is contained in:
codecalm
2026-08-12 01:53:42 +02:00
parent 4948c03c34
commit 0dd000fb25
4 changed files with 60 additions and 9 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@tabler/docs": patch
---
Updated docs readability: white example panels joined with their code, larger headings, and a narrower text measure.
+42
View File
@@ -1570,6 +1570,48 @@ svg.DocSearch-Hit-Select-Icon {
width: 15rem;
}
/* Running text keeps a comfortable measure of about 70 characters; demos, code
and tables stay full width. Direct children only, so markup inside demos is
left alone. Geist's `0` is much wider than its average glyph, so 61ch reads
as roughly 70 characters, not 61. */
.prose > p,
.prose > ul,
.prose > ol,
.prose > dl,
.prose > blockquote,
.prose > h2,
.prose > h3,
.prose > h4 {
max-width: 61ch;
}
/* Docs pages need more heading contrast than the dashboard scale gives: there,
h3 matches the body size and only differs in weight. */
.docs-page-header h1 {
font-size: 1.875rem;
line-height: 1.2;
}
.prose > h2 {
font-size: 1.375rem;
line-height: 1.3;
}
.prose > h3 {
font-size: 1.125rem;
}
/* The code panel is flush with the demo above it. It carries the lower half of
the shared outline: in dark mode the code background matches the page, so
without a border the card would have no bottom edge. */
.example-code .shiki {
margin-bottom: 0;
border: 1px solid var(--tblr-border-color);
border-block-start: 0;
border-start-start-radius: 0;
border-start-end-radius: 0;
}
.DocSearch-Button {
width: 100%;
box-shadow: 0 0 0 1px var(--tblr-border-color);
+11 -7
View File
@@ -5,11 +5,11 @@ import { beautifyHtml, highlightCode, removeHref } from '@shared/lib/code-exampl
/**
* Demo area background:
* - surface-secondary — muted solid surface (default)
* - surface — theme-aware white, one step above the page background (default)
* - surface-secondary — muted solid surface, same tone as the page background
* - transparent — checkerboard pattern, for components with their own background
* - primary — theme-aware white (bg-surface)
*/
type ExampleBackground = 'surface-secondary' | 'transparent' | 'primary'
type ExampleBackground = 'surface' | 'surface-secondary' | 'transparent'
interface Props {
/** raw HTML of the example; when absent — the slot is rendered */
@@ -29,12 +29,12 @@ interface Props {
codeOnly?: boolean
}
const { html: htmlProp, code, raw, overflow = 'auto', background = 'surface-secondary', class: className, height, column, centered, vertical, columnFullWidth, hideCode, codeOnly } = Astro.props
const { html: htmlProp, code, raw, overflow = 'auto', background = 'surface', class: className, height, column, centered, vertical, columnFullWidth, hideCode, codeOnly } = Astro.props
const backgroundClasses: Record<ExampleBackground, string> = {
'surface': 'bg-surface',
'surface-secondary': 'bg-surface-secondary',
'transparent': 'bg-pattern-rectangles',
'primary': 'bg-surface',
}
// Strip empty lines from the example HTML.
@@ -45,7 +45,11 @@ let html = (htmlProp ?? (await Astro.slots.render('default'))).replace(/^\s*[\r\
// code in the panel looks like hand-written HTML.
html = html.replace(/<(path|circle|line|polyline|polygon|rect|ellipse)([^>]*?)\s*><\/\1>/g, '<$1$2 />').replace(/&#39;/g, "'")
const exampleClasses = ['example fs-base border rounded my-5', !raw && 'd-flex flex-wrap justify-content-center', `overflow-${overflow}`, 'position-relative', backgroundClasses[background], className]
// The demo and its code panel sit flush against each other so they read as one
// card; a demo without code keeps all four corners and its own bottom margin.
const joined = !hideCode && !codeOnly
const exampleClasses = ['example fs-base border mt-5', joined ? 'rounded-top border-bottom-0 mb-0' : 'rounded mb-5', !raw && 'd-flex flex-wrap justify-content-center', `overflow-${overflow}`, 'position-relative', backgroundClasses[background], className]
const innerClasses = ['p-6 w-full', column && 'd-flex gap-3 flex-column', !column && centered && `d-flex flex-fill flex-wrap gap-2 justify-content-center${vertical ? ' align-items-center flex-column' : ' justify-content-center'}`, columnFullWidth && 'd-flex flex-fill flex-column gap-2']
@@ -68,7 +72,7 @@ const highlighted = hideCode ? '' : await highlightCode(beautifyHtml(code ?? htm
{
!hideCode && (
<div class="position-relative">
<div class:list={['position-relative', joined && 'example-code mb-5']}>
<a class="btn btn-icon btn-dark position-absolute m-2 top-0 end-0 z-3" data-clipboard-text={code ?? html}>
<Icon name="clipboard" />
<Icon name="check" class="d-none" />
+2 -2
View File
@@ -347,7 +347,7 @@ const relatedPages = await Promise.all(
data-bs-smooth-scroll="true"
tabindex="0"
>
<div class="d-flex">
<div class="d-flex docs-page-header">
<h1>
{title}
</h1>
@@ -361,7 +361,7 @@ const relatedPages = await Promise.all(
}
</div>
<p class="text-secondary fs-3 lh-3">{summary}</p>
<p class="text-secondary fs-2 lh-3">{summary}</p>
{/* Page must supply headings with ids (MDX does this by default). */}
<slot />