Add a design system for Claude Design, generated from garage_ui
Tokens come out of garage_ui/tool/export_design_tokens_test.dart, the components are CSS on top of them, and the cards cover foundations, components and whole hub and Arcs & Angles screens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013F4NWNvYcdeSgqbWMT1VQ7
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
572c09039f
commit
b5e5ed5b75
@@ -0,0 +1,94 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Button groups</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-block { padding: 0 var(--gap-xs); }
|
||||
.ds-half + .ds-half { margin-top: var(--gap-lg); }
|
||||
.ds-block > .caption { padding-bottom: var(--gap-xs); }
|
||||
.ds-half { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-xl); }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Button groups</div>
|
||||
<div class="subtitle">Controls joined into one. Only the outer corners round.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-half">
|
||||
<div class="ds-block">
|
||||
<div class="caption">Button welded to a field</div>
|
||||
<div class="btn-group span">
|
||||
<label class="field grow"><input value="gk_live_4f8a2c91" aria-label="Client ID"></label>
|
||||
<button class="btn secondary icon-only" aria-label="Copy"><svg class="icon" viewBox="0 0 24 24"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-block">
|
||||
<div class="caption">Segmented choice</div>
|
||||
<div class="btn-group fill">
|
||||
<button class="btn secondary">Off</button>
|
||||
<button class="btn primary">Optional</button>
|
||||
<button class="btn secondary">Required</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-half">
|
||||
<div class="ds-block">
|
||||
<div class="caption">Vertical, with a group nested in it</div>
|
||||
<div class="btn-group vertical span">
|
||||
<label class="field"><input placeholder="Email" aria-label="Email"></label>
|
||||
<div class="btn-group span">
|
||||
<label class="field grow"><input placeholder="Password" type="password" aria-label="Password"></label>
|
||||
<button class="btn outline icon-only" aria-label="Show password"><svg class="icon" viewBox="0 0 24 24"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" /><circle cx="12" cy="12" r="3" /></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-block">
|
||||
<div class="caption">Toolbar toggles - primary on, outline off</div>
|
||||
<div class="chrome-bar">
|
||||
<button class="btn primary icon-only" aria-label="Bold"><svg class="icon" viewBox="0 0 24 24"><path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" /></svg></button>
|
||||
<button class="btn outline icon-only" aria-label="Italic"><svg class="icon" viewBox="0 0 24 24"><line x1="19" x2="10" y1="4" y2="4" /><line x1="14" x2="5" y1="20" y2="20" /><line x1="15" x2="9" y1="4" y2="20" /></svg></button>
|
||||
<button class="btn outline icon-only" aria-label="Underline"><svg class="icon" viewBox="0 0 24 24"><path d="M6 4v6a6 6 0 0 0 12 0V4" /><line x1="4" x2="20" y1="20" y2="20" /></svg></button>
|
||||
<span class="vr"></span>
|
||||
<div class="btn-group">
|
||||
<button class="btn primary icon-only" aria-label="Align left"><svg class="icon" viewBox="0 0 24 24"><path d="M21 5H3" /><path d="M15 12H3" /><path d="M17 19H3" /></svg></button>
|
||||
<button class="btn outline icon-only" aria-label="Align centre"><svg class="icon" viewBox="0 0 24 24"><path d="M21 5H3" /><path d="M17 12H7" /><path d="M19 19H5" /></svg></button>
|
||||
<button class="btn outline icon-only" aria-label="Align right"><svg class="icon" viewBox="0 0 24 24"><path d="M21 5H3" /><path d="M21 12H9" /><path d="M21 19H7" /></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>A field with its one action welded on: a spanning group, the field grows, then a secondary IconButton.</li>
|
||||
<li>Groups nest. A corner only rounds where both groups agree it's an outer one.</li>
|
||||
<li>A segmented choice: fill the group, chosen one primary, the rest secondary, labels centred.</li>
|
||||
<li>Editor toolbar toggles: primary when on, outline when off.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Leave a segmented control shrunk to its labels. It should span its field.</li>
|
||||
<li>Mix the primary-on toggle pattern and Toggle on the same surface.</li>
|
||||
<li>Use a secondary off state unless its a master switch whose off state matters.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,130 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Buttons</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap-sm); padding: 0 var(--gap-xs); }
|
||||
.ds-block + .ds-block { margin-top: var(--gap-lg); }
|
||||
.ds-block > .caption { padding: 0 var(--gap-xs) var(--gap-xs); }
|
||||
|
||||
.ds-table { width: 100%; border-collapse: collapse; }
|
||||
.ds-table td { padding: var(--gap-xs) var(--gap-xs); border-top: var(--control-border-width) solid var(--divider); vertical-align: middle; }
|
||||
.ds-table tr:first-child td { border-top: 0; }
|
||||
.ds-table td:first-child { width: 30%; }
|
||||
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Buttons</div>
|
||||
<div class="subtitle">Pick the variant, then stop. The theme does the rest.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-block">
|
||||
<div class="caption">Variants</div>
|
||||
<div class="ds-row">
|
||||
<button class="btn primary">Save</button>
|
||||
<button class="btn secondary">Duplicate</button>
|
||||
<button class="btn outline">Cancel</button>
|
||||
<button class="btn ghost">Settings</button>
|
||||
<button class="btn ghost-destructive">Remove</button>
|
||||
<button class="btn destructive">Delete</button>
|
||||
<button class="btn link">Learn more</button>
|
||||
<button class="btn text">Forgot password?</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-block">
|
||||
<div class="caption">With a leading icon</div>
|
||||
<div class="ds-row">
|
||||
<button class="btn primary"><svg class="icon" viewBox="0 0 24 24"><path d="M5 12h14" /><path d="M12 5v14" /></svg>New product</button>
|
||||
<button class="btn outline"><svg class="icon" viewBox="0 0 24 24"><path d="M12 15V3" /><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><path d="m7 10 5 5 5-5" /></svg>Export</button>
|
||||
<button class="btn ghost"><svg class="icon" viewBox="0 0 24 24"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /><circle cx="12" cy="12" r="3" /></svg>Settings</button>
|
||||
<button class="btn ghost-destructive"><svg class="icon" viewBox="0 0 24 24"><path d="M10 11v6" /><path d="M14 11v6" /><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" /><path d="M3 6h18" /><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" /></svg>Revoke</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-block">
|
||||
<div class="caption">Icon only - IconButton, never a Button with just an icon in it</div>
|
||||
<div class="ds-row">
|
||||
<button class="btn primary icon-only" aria-label="Add"><svg class="icon" viewBox="0 0 24 24"><path d="M5 12h14" /><path d="M12 5v14" /></svg></button>
|
||||
<button class="btn secondary icon-only" aria-label="Copy"><svg class="icon" viewBox="0 0 24 24"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg></button>
|
||||
<button class="btn outline icon-only" aria-label="Refresh"><svg class="icon" viewBox="0 0 24 24"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" /><path d="M21 3v5h-5" /><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" /><path d="M8 16H3v5" /></svg></button>
|
||||
<button class="btn ghost icon-only" aria-label="Edit"><svg class="icon" viewBox="0 0 24 24"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" /><path d="m15 5 4 4" /></svg></button>
|
||||
<button class="btn ghost-destructive icon-only" aria-label="Delete"><svg class="icon" viewBox="0 0 24 24"><path d="M10 11v6" /><path d="M14 11v6" /><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" /><path d="M3 6h18" /><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" /></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-block">
|
||||
<div class="caption">Disabled</div>
|
||||
<div class="ds-row">
|
||||
<button class="btn primary" disabled>Save</button>
|
||||
<button class="btn secondary" disabled>Duplicate</button>
|
||||
<button class="btn outline" disabled>Cancel</button>
|
||||
<button class="btn ghost" disabled>Settings</button>
|
||||
<button class="btn ghost-destructive" disabled>Remove</button>
|
||||
<button class="btn destructive" disabled>Delete</button>
|
||||
<button class="btn link" disabled>Learn more</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-block">
|
||||
<div class="caption">Hovered</div>
|
||||
<div class="ds-row">
|
||||
<button class="btn primary is-hovered">Save</button>
|
||||
<button class="btn secondary is-hovered">Duplicate</button>
|
||||
<button class="btn outline is-hovered">Cancel</button>
|
||||
<button class="btn ghost is-hovered">Settings</button>
|
||||
<button class="btn ghost-destructive is-hovered">Remove</button>
|
||||
<button class="btn destructive is-hovered">Delete</button>
|
||||
<button class="btn link is-hovered">Learn more</button>
|
||||
<button class="btn text is-hovered">Forgot password?</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Variants mean something</div>
|
||||
</div>
|
||||
|
||||
<table class="ds-table">
|
||||
<tr><td><button class="btn primary">Primary</button></td><td>The one action, or the thing thats on or chosen. One per view, ideally.</td></tr>
|
||||
<tr><td><button class="btn secondary">Secondary</button></td><td>A neutral filled control. A resting toggle, a button welded to a field, the selected nav item.</td></tr>
|
||||
<tr><td><button class="btn outline">Outline</button></td><td>A normal action that isnt the main one. Cancel, Retry, Previous and Next.</td></tr>
|
||||
<tr><td><button class="btn ghost">Ghost</button></td><td>Chrome, toolbars, nav items, row actions. Anything that shouldnt compete.</td></tr>
|
||||
<tr><td><button class="btn destructive">Destructive</button></td><td>The confirm button of a destructive dialog.</td></tr>
|
||||
<tr><td><button class="btn ghost-destructive">Ghost destructive</button></td><td>A destructive trigger that isnt a filled slab. Remove, Revoke, Delete in a row.</td></tr>
|
||||
<tr><td><button class="btn link">Link</button> <button class="btn text">Text</button></td><td>Inline, in running copy.</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Dialogs: Cancel is outline, confirm is primary or destructive.</li>
|
||||
<li>Retry after an error, and an empty state's call to action: outline.</li>
|
||||
<li>Panel header actions: a ghost IconButton, each in a Tooltip.</li>
|
||||
<li>An action in a settings row: ghost. In a property row: secondary.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Bold a button label, or colour its text or icon by hand.</li>
|
||||
<li>Hand-colour a ghost button red. Thats what ghost destructive is for.</li>
|
||||
<li>Set an alignment unless the button is stretched wider than its label.</li>
|
||||
<li>Force a compact density on a button to make it fit.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,66 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Dialogs</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-stage { display: flex; flex-direction: column; align-items: center; gap: var(--gap-xl); padding: var(--gap-xxl) var(--container-padding); border-radius: var(--radius-xl); }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dialogs</div>
|
||||
<div class="subtitle">A small confirm, over a dimmed page.</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-backdrop ds-stage">
|
||||
<div class="dialog" role="alertdialog" aria-labelledby="d1-title">
|
||||
<div class="body">
|
||||
<div class="title" id="d1-title">Delete this product?</div>
|
||||
<div class="content">People who already bought it keep their licence. It cant be sold again.</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="btn outline">Cancel</button>
|
||||
<button class="btn destructive">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog" role="alertdialog" aria-labelledby="d2-title">
|
||||
<div class="body">
|
||||
<div class="title" id="d2-title">Publish changes?</div>
|
||||
<div class="content">The new price goes live at checkout straight away.</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<button class="btn outline">Cancel</button>
|
||||
<button class="btn primary">Publish</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>showDialog with an AlertDialog: a title, a line of content and its actions.</li>
|
||||
<li>Cancel is outline. Confirm is primary, or destructive when it removes something.</li>
|
||||
<li>Bigger jobs, like settings or export, go in a pane overlay instead.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Constrain the dialog's width. It caps itself at the dialog max width.</li>
|
||||
<li>Build the action row by hand. The dialog draws its own band.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,110 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Feedback</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-row { display: flex; flex-wrap: wrap; gap: var(--gap-md); padding: 0 var(--gap-xs); align-items: flex-start; }
|
||||
.ds-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--gap-xl); padding: 0 var(--gap-xs); }
|
||||
.ds-cell { display: flex; flex-direction: column; gap: var(--gap-xs); }
|
||||
.ds-state { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--gap-sm); padding: var(--gap-xxl) var(--gap-md); }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Feedback</div>
|
||||
<div class="subtitle">Toasts, and the three states a page can be in.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-row">
|
||||
<div class="toast" role="status">
|
||||
<div class="body">
|
||||
<div class="badge"><svg class="icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><path d="M12 16v-4" /><path d="M12 8h.01" /></svg></div>
|
||||
<div class="text">
|
||||
<div class="title">Link copied</div>
|
||||
<div class="subtitle">Paste it anywhere a buyer can reach.</div>
|
||||
</div>
|
||||
<button class="btn outline icon-only" aria-label="Close"><svg class="icon" viewBox="0 0 24 24"><path d="M18 6 6 18" /><path d="m6 6 12 12" /></svg></button>
|
||||
</div>
|
||||
<div class="drain"><span style="width: 80%"></span></div>
|
||||
</div>
|
||||
<div class="toast success" role="status">
|
||||
<div class="body">
|
||||
<div class="badge"><svg class="icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><path d="m9 12 2 2 4-4" /></svg></div>
|
||||
<div class="text">
|
||||
<div class="title">Saved</div>
|
||||
<div class="subtitle">Your changes are live.</div>
|
||||
</div>
|
||||
<button class="btn outline icon-only" aria-label="Close"><svg class="icon" viewBox="0 0 24 24"><path d="M18 6 6 18" /><path d="m6 6 12 12" /></svg></button>
|
||||
</div>
|
||||
<div class="drain"><span style="width: 45%"></span></div>
|
||||
</div>
|
||||
<div class="toast error" role="alert">
|
||||
<div class="body">
|
||||
<div class="badge"><svg class="icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><line x1="12" x2="12" y1="8" y2="12" /><line x1="12" x2="12.01" y1="16" y2="16" /></svg></div>
|
||||
<div class="text">
|
||||
<div class="title">Couldnt save</div>
|
||||
<div class="subtitle">Check your connection and try again.</div>
|
||||
</div>
|
||||
<button class="btn outline icon-only" aria-label="Close"><svg class="icon" viewBox="0 0 24 24"><path d="M18 6 6 18" /><path d="m6 6 12 12" /></svg></button>
|
||||
</div>
|
||||
<div class="drain"><span style="width: 20%"></span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Loading, empty, error</div>
|
||||
<div class="subtitle">The plainest thing that works.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-grid">
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Loading</div>
|
||||
<div class="ds-state outlined">
|
||||
<div class="spinner" role="progressbar" aria-label="Loading"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Empty</div>
|
||||
<div class="ds-state outlined">
|
||||
<div class="text-xs muted">No coupons yet.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Error</div>
|
||||
<div class="ds-state outlined">
|
||||
<div class="text-xs muted">Couldnt load orders.</div>
|
||||
<button class="btn outline">Retry</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>showAppToast with a title, a subtitle and a severity: info, success or error. The severity colours the drain bar, nothing else.</li>
|
||||
<li>Loading is a spinner. Empty is one muted line. Error is the message muted and an outline Retry.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Use skeletons or shimmer.</li>
|
||||
<li>Hand-build a toast out of a card and some padding.</li>
|
||||
<li>Hand-build a warning box. A page that wants more is asking for a new garage_ui component.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,73 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Menus and tooltips</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--gap-xl); padding: 0 var(--gap-xs); align-items: start; }
|
||||
.ds-cell { display: flex; flex-direction: column; align-items: flex-start; gap: var(--gap-xs); }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Menus and tooltips</div>
|
||||
<div class="subtitle">Floating surfaces. Flat, no shadow.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-grid">
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Menu</div>
|
||||
<div class="popover" role="menu">
|
||||
<div class="menu-label">Edit</div>
|
||||
<div class="menu-item" role="menuitem"><svg class="icon" viewBox="0 0 24 24"><circle cx="6" cy="6" r="3" /><path d="M8.12 8.12 12 12" /><path d="M20 4 8.12 15.88" /><circle cx="6" cy="18" r="3" /><path d="M14.8 14.8 20 20" /></svg>Cut<span class="shortcut">⌘ + X</span></div>
|
||||
<div class="menu-item is-hovered" role="menuitem"><svg class="icon" viewBox="0 0 24 24"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>Copy<span class="shortcut">⌘ + C</span></div>
|
||||
<div class="menu-item" role="menuitem"><svg class="icon" viewBox="0 0 24 24"><path d="M11 14h10" /><path d="M16 4h2a2 2 0 0 1 2 2v1.344" /><path d="m17 18 4-4-4-4" /><path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113" /><rect x="8" y="2" width="8" height="4" rx="1" /></svg>Paste<span class="shortcut">⌘ + V</span></div>
|
||||
<div class="menu-divider"></div>
|
||||
<div class="menu-item" role="menuitem"><svg class="icon" viewBox="0 0 24 24"><path d="M10 11v6" /><path d="M14 11v6" /><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" /><path d="M3 6h18" /><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" /></svg>Delete</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Context menu</div>
|
||||
<div class="popover" role="menu">
|
||||
<div class="menu-item" role="menuitem"><svg class="icon" viewBox="0 0 24 24"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" /><path d="M3 3v5h5" /></svg>Reset to Default</div>
|
||||
<div class="menu-item" role="menuitem"><svg class="icon" viewBox="0 0 24 24"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>Copy</div>
|
||||
<div class="menu-item disabled" aria-disabled="true" role="menuitem"><svg class="icon" viewBox="0 0 24 24"><path d="M11 14h10" /><path d="M16 4h2a2 2 0 0 1 2 2v1.344" /><path d="m17 18 4-4-4-4" /><path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 1.793-1.113" /><rect x="8" y="2" width="8" height="4" rx="1" /></svg>Paste</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Tooltip</div>
|
||||
<button class="btn ghost icon-only" aria-label="Copy"><svg class="icon" viewBox="0 0 24 24"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg></button>
|
||||
<span class="tooltip" role="tooltip">Copy client ID</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>MenuButton rows, with MenuLabel and MenuDivider to group them.</li>
|
||||
<li>showContextMenu for right-click. Property rows get Reset, Copy and Paste, greyed when theres nothing to do.</li>
|
||||
<li>A tooltip on every icon-only button, with plain text in it.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Hand-build a popover out of a container with a fill, border and radius.</li>
|
||||
<li>Colour tooltip text, or pad the tooltip yourself.</li>
|
||||
<li>Add a shadow to a menu. Surfaces are separated by their border and fill.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,94 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Properties section</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Properties section</div>
|
||||
<div class="subtitle">A boxed card of label and value rows.</div>
|
||||
</div>
|
||||
|
||||
<div class="properties-section">
|
||||
<div class="header" role="button" aria-expanded="true">
|
||||
<svg class="icon chevron" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6" /></svg>
|
||||
<span>Subscription</span>
|
||||
<span class="trailing muted">Active</span>
|
||||
</div>
|
||||
|
||||
<div class="rows">
|
||||
<div class="property-row">
|
||||
<div class="label">Plan</div>
|
||||
<div class="value"><label class="field secondary readonly"><input value="Pro, monthly" readonly disabled aria-label="Plan"></label></div>
|
||||
</div>
|
||||
|
||||
<div class="property-row">
|
||||
<div class="label">Seats<span class="subtitle">People who can sign in</span></div>
|
||||
<div class="value"><label class="field secondary error"><input value="0" aria-label="Seats"></label></div>
|
||||
<div class="error">Needs at least one seat</div>
|
||||
</div>
|
||||
|
||||
<div class="property-row">
|
||||
<div class="label">Billing</div>
|
||||
<div class="value">
|
||||
<div class="select secondary" role="button">
|
||||
<span>Monthly</span>
|
||||
<svg class="icon chevron" viewBox="0 0 24 24"><path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="description">Switching takes effect from the next invoice, not this one.</div>
|
||||
</div>
|
||||
|
||||
<div class="property-row">
|
||||
<div class="label">Invoices</div>
|
||||
<div class="value"><button class="btn secondary">Open billing portal</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="btn ghost">Reset</button>
|
||||
<button class="btn ghost-destructive">Cancel plan</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">The value slot is never bare text</div>
|
||||
<div class="subtitle">A read-only value is a secondary field, read only and disabled.</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Beside real fields, bare text reads as a caption and the column goes ragged.</li>
|
||||
<li>A button in the value slot sits left and keeps its own width. It doesnt stretch.</li>
|
||||
<li>A refused value says why in the row's error, under it. Copy about the setting goes in the description box.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Inspectors, account and security pages, and lists of records, one section per record.</li>
|
||||
<li>A status or count in the header's trailing slot. It stays visible when collapsed.</li>
|
||||
<li>What the section can do, in the actions band under the rows.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Use outline fields or ghost selects in here. Controls in a section are secondary.</li>
|
||||
<li>Put live data in the subtitle. No counts, dates, names or statuses.</li>
|
||||
<li>Add gaps between sections. Each one carries its own margin.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,84 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Select</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--gap-xl); padding: 0 var(--gap-xs); align-items: start; }
|
||||
.ds-cell { display: flex; flex-direction: column; align-items: flex-start; gap: var(--gap-xs); min-width: 0; }
|
||||
.ds-open { display: flex; flex-direction: column; gap: var(--gap-xs); align-items: flex-start; padding: var(--gap-lg) var(--gap-xs) 0; }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Select</div>
|
||||
<div class="subtitle">One value from a list, in a popup.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-grid">
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Outline - the default</div>
|
||||
<div class="select" role="button">
|
||||
<span>Engineering</span>
|
||||
<svg class="icon chevron" viewBox="0 0 24 24"><path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Secondary - in a property row</div>
|
||||
<div class="select secondary" role="button">
|
||||
<span>Monthly</span>
|
||||
<svg class="icon chevron" viewBox="0 0 24 24"><path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Ghost - in a settings row</div>
|
||||
<div class="select ghost" role="button">
|
||||
<span>All regions</span>
|
||||
<svg class="icon chevron" viewBox="0 0 24 24"><path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-open">
|
||||
<div class="caption">Open</div>
|
||||
<div class="select" role="button">
|
||||
<span>Engineering</span>
|
||||
<svg class="icon chevron" viewBox="0 0 24 24"><path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" /></svg>
|
||||
</div>
|
||||
<div class="select-popup" role="listbox">
|
||||
<div class="option" role="option">Design</div>
|
||||
<div class="option selected" role="option" aria-selected="true">Engineering<svg class="icon" viewBox="0 0 24 24"><path d="M20 6 9 17l-5-5" /></svg></div>
|
||||
<div class="option is-hovered" role="option">Finance</div>
|
||||
<div class="option" role="option">Support</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Outline by default, beside other outline fields.</li>
|
||||
<li>Secondary in a property row. The row forces it anyway.</li>
|
||||
<li>Ghost in a settings row, or where it reports a value rather than offering a control.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Give a toolbar select a literal width.</li>
|
||||
<li>Put a ghost select inside a properties section.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,59 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Selection controls</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap-xl); padding: 0 var(--gap-xs); }
|
||||
.ds-cell { display: flex; flex-direction: column; gap: var(--gap-md); }
|
||||
.ds-cell > .caption { margin-bottom: calc(var(--gap-xs) - var(--gap-md)); }
|
||||
.ds-pair { display: inline-flex; align-items: center; gap: var(--gap-sm); }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Selection controls</div>
|
||||
<div class="subtitle">On or off. Checkbox or Switch, one per surface.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-grid">
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Checkbox</div>
|
||||
<label class="ds-pair"><span class="checkbox" role="checkbox" aria-checked="false"></span>Snap to grid</label>
|
||||
<label class="ds-pair"><span class="checkbox checked" role="checkbox" aria-checked="true"></span>Show labels</label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Switch</div>
|
||||
<label class="ds-pair"><span class="switch" role="switch" aria-checked="false"></span>Email receipts</label>
|
||||
<label class="ds-pair"><span class="switch on" role="switch" aria-checked="true"></span>Active</label>
|
||||
<label class="ds-pair muted"><span class="switch disabled" role="switch" aria-checked="false" aria-disabled="true"></span>Managed by your organisation</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Checkbox in dense editor panels. Arcs and Angles uses it throughout.</li>
|
||||
<li>Switch in rows on a product page. The hub uses it in settings rows.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Mix checkboxes and switches on one surface.</li>
|
||||
<li>Recolour the track, thumb or tick. The accent is primary.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,74 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Settings list</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Product</div>
|
||||
<div class="subtitle">What people see at checkout</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-list">
|
||||
<div class="settings-row">
|
||||
<div class="label">Name<span class="tag">Required</span><span class="subtitle">Shown on receipts</span></div>
|
||||
<div class="field-slot"><label class="field"><input value="Pro plan" aria-label="Name"></label></div>
|
||||
</div>
|
||||
|
||||
<div class="settings-row">
|
||||
<div class="label">Billing<span class="subtitle">How often it charges</span></div>
|
||||
<div class="field-slot">
|
||||
<div class="select ghost" role="button">
|
||||
<span>Monthly</span>
|
||||
<svg class="icon chevron" viewBox="0 0 24 24"><path d="m7 15 5 5 5-5" /><path d="m7 9 5-5 5 5" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-row">
|
||||
<div class="label">Checkout link</div>
|
||||
<div class="field-slot">
|
||||
<button class="btn ghost"><svg class="icon" viewBox="0 0 24 24"><rect width="14" height="14" x="8" y="8" rx="2" ry="2" /><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" /></svg>Copy link</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-row">
|
||||
<div class="label">Price<span class="tag">Required</span></div>
|
||||
<div class="field-slot"><label class="field error"><input value="0.00" aria-label="Price"><span class="unit">GBP</span></label></div>
|
||||
<div class="error">A paid product needs a price above zero</div>
|
||||
<div class="description">Buyers see this converted to their own currency at checkout.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Forms on the page ground: products, coupons, clients.</li>
|
||||
<li>Selects, buttons and icon buttons are ghost. Text fields are outline, read-only ones too.</li>
|
||||
<li>"Required" goes in the row's action slot, beside the label.</li>
|
||||
<li>Why a value was refused goes in the row's error slot, under the row.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Use secondary fields here. With no card behind them, filled controls float.</li>
|
||||
<li>Stretch a select or a button to a column. They keep their own width - only a text field fills its slot.</li>
|
||||
<li>Write a sentence in the subtitle. That goes in the description.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,98 @@
|
||||
<!-- @dsCard group="Components" -->
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Text fields</title>
|
||||
<link rel="stylesheet" href="../components.css">
|
||||
<style>
|
||||
.ds { padding: 0 var(--container-padding) var(--container-padding); }
|
||||
.ds-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--gap-lg) var(--gap-xl); padding: 0 var(--gap-xs); }
|
||||
.ds-cell { display: flex; flex-direction: column; gap: var(--gap-xs); min-width: 0; }
|
||||
.ds-rules { margin: 0; padding: 0 var(--gap-xs) 0 var(--gap-xl); display: flex; flex-direction: column; gap: var(--gap-xxs); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="ds">
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Text fields</div>
|
||||
<div class="subtitle">Outline for free text, secondary for values.</div>
|
||||
</div>
|
||||
|
||||
<div class="ds-grid">
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Outline - the default</div>
|
||||
<label class="field stretch"><input placeholder="Product name" aria-label="Product name"></label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Outline, filled in</div>
|
||||
<label class="field stretch"><input value="Pro plan" aria-label="Product name"></label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">With a leading icon</div>
|
||||
<label class="field stretch">
|
||||
<svg class="icon" viewBox="0 0 24 24"><path d="m21 21-4.34-4.34" /><circle cx="11" cy="11" r="8" /></svg>
|
||||
<input placeholder="Search" aria-label="Search">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Secondary</div>
|
||||
<label class="field secondary stretch"><input value="1280" aria-label="Width"></label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Read only</div>
|
||||
<label class="field secondary readonly stretch"><input value="prod_8f2k1c" readonly disabled aria-label="Product ID"></label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Numeric, centred, with a unit</div>
|
||||
<label class="field secondary center stretch">
|
||||
<input value="24" aria-label="Stroke width">
|
||||
<span class="unit">px</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Error - the outline reddens, never the fill</div>
|
||||
<label class="field error stretch"><input value="pro plan!" aria-label="Slug"></label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Outline, hovered</div>
|
||||
<label class="field stretch is-hovered"><input value="Pro plan" aria-label="Product name"></label>
|
||||
</div>
|
||||
|
||||
<div class="ds-cell">
|
||||
<div class="caption">Read only, monospace - ids and skus</div>
|
||||
<label class="field secondary readonly mono stretch"><input value="usr_8f2c41d9a7" readonly disabled aria-label="User ID"></label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Use it for</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Outline for free text: names, search, a composer, a form.</li>
|
||||
<li>Secondary for numeric property values and read-only values.</li>
|
||||
<li>Inside a property row the field is forced to secondary. You dont pick.</li>
|
||||
<li>A read-only value is a read-only, disabled field. Never bare text.</li>
|
||||
</ul>
|
||||
|
||||
<div class="sub-heading">
|
||||
<div class="title">Dont</div>
|
||||
</div>
|
||||
<ul class="ds-rules">
|
||||
<li>Hand-roll a red line under a field. Use the row's error slot.</li>
|
||||
<li>Put a secondary field in a settings list, or an outline one in a properties section.</li>
|
||||
<li>Colour or size the icon. The field does it.</li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user