From d3e04a1dcd3a72e64ee337258fe34f4c937313fd Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Wed, 12 Aug 2026 16:19:51 +1000 Subject: [PATCH] Update Playground toolbars and alignment --- .../docs/src/components/playground/editor.tsx | 7 +- .../playground/icon-toggle-button-group.tsx | 96 +++++++++---------- .../playground/pane-toolbar.browser.test.ts | 81 ++++++++++++++++ .../components/playground/pane-toolbar.tsx | 20 ++++ .../components/playground/preview-toolbar.tsx | 5 +- 5 files changed, 154 insertions(+), 55 deletions(-) create mode 100644 apps/docs/src/components/playground/pane-toolbar.browser.test.ts create mode 100644 apps/docs/src/components/playground/pane-toolbar.tsx diff --git a/apps/docs/src/components/playground/editor.tsx b/apps/docs/src/components/playground/editor.tsx index 58adae09..6f571459 100644 --- a/apps/docs/src/components/playground/editor.tsx +++ b/apps/docs/src/components/playground/editor.tsx @@ -10,6 +10,7 @@ import { runFormatDocument, } from '../../lib/playground-format'; import { EditorSkeleton } from './editor-skeleton'; +import { PlaygroundPaneToolbar } from './pane-toolbar.js'; type PlaygroundEditorProps = { defaultValue: string; @@ -48,16 +49,16 @@ export default function PlaygroundEditor({ return (
-
+ -
+
( - options: ReadonlyArray<{ value: Value }>, - onChange: (value: Value) => void, -) { - return (selection: Selection) => { - if (selection === 'all') return; - - const selectedKey = selection.values().next().value; - const selectedOption = options.find((option) => option.value === selectedKey); - if (!selectedOption) return; - - onChange(selectedOption.value); - }; -} - type IconToggleItem = { icon: IconName; label: string; @@ -41,6 +19,20 @@ type IconToggleButtonGroupProps = { value: Value | null; }; +type TextToggleItem = { + label: string; + value: Value; +}; + +type TextToggleButtonGroupProps = { + label: string; + onChange: (value: Value) => void; + options: ReadonlyArray>; + value: Value; +}; + +const GROUP_CLASS_NAME = 'flex items-center gap-2 bg-fd-secondary p-0.5'; + /** A round icon-only pill group, for choices with well-known glyphs such as light/dark/system. */ export function IconToggleButtonGroup({ label, @@ -61,15 +53,10 @@ export function IconToggleButtonGroup({ {options.map(({ icon, label: optionLabel, value: optionValue }) => ( { - return cx( - 'flex size-8 items-center justify-center', - PILL_CLASS_NAME, - isSelected && PILL_SELECTED_CLASS_NAME, - ); - }} + className={button({ appearance: 'subtle', size: 'small', tone: 'neutral' })} id={optionValue} key={optionValue} + render={renderToggleButton} > @@ -78,18 +65,6 @@ export function IconToggleButtonGroup({ ); } -type TextToggleItem = { - label: string; - value: Value; -}; - -type TextToggleButtonGroupProps = { - label: string; - onChange: (value: Value) => void; - options: ReadonlyArray>; - value: Value; -}; - /** * A round pill group with visible text labels, for choices without an established glyph, such as * a named theme identity. Matches `IconToggleButtonGroup` in height, radius, and focus treatment. @@ -112,15 +87,10 @@ export function TextToggleButtonGroup({ > {options.map(({ label: optionLabel, value: optionValue }) => ( { - return cx( - 'flex h-8 items-center justify-center whitespace-nowrap px-3 font-medium text-xs', - PILL_CLASS_NAME, - isSelected && PILL_SELECTED_CLASS_NAME, - ); - }} + className={button({ appearance: 'subtle', size: 'small', tone: 'neutral' })} id={optionValue} key={optionValue} + render={renderToggleButton} > {optionLabel} @@ -128,3 +98,29 @@ export function TextToggleButtonGroup({ ); } + +type RenderToggleButton = ComponentProps['render']; + +/** + * Renders the toggle's `