Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- [breaking] Rebuild Assembly's CSS pipeline on [UnoCSS](https://unocss.dev/). Class names and `buildUserAssets` stay compatible; the generated stylesheet's formatting, comments, and source maps may differ. Node.js 24+ is required.
- [add] Export `presetAssembly()` for on-demand UnoCSS builds that keep Assembly class names. Pass `{ safelist: true }` only when you want the full prebuilt utility set.
- [add] `examples/jit` — a sample app that generates only the utilities used in its markup (no reset or component preflight).
- [style change] Toggle groups are restyled as segmented controls. `toggle` is now 24px tall.
- [add] `toggle--l` (36px).
- [internal] Assembly utilities are UnoCSS rules in `src/preset/`. Reset and component CSS live in `src/preset/base.css`. The package build is `src/build-*.js`. The documentation site is VitePress under `docs/`.

## 1.16.0
Expand Down
47 changes: 36 additions & 11 deletions docs/.vitepress/theme/catalog/Toggles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@ const colors = [null].concat(formColors.filter(color => !isLight(color)));
const lightenColors = formColors.filter(isLight);
const animals = ['cow', 'horse', 'pig'];

function toggleClass(color, activeColor) {
function toggleClass(color, activeColor, size) {
return [
'toggle',
color ? `toggle--${color}` : '',
activeColor ? `toggle--active-${activeColor}` : ''
activeColor ? `toggle--active-${activeColor}` : '',
size ? `toggle--${size}` : ''
]
.filter(Boolean)
.join(' ');
}

function groupClass(small) {
return small ? 'mb12 mr12 toggle-group toggle-group--s txt-s' : 'mb12 mr12 toggle-group';
}
const groupClass = 'mb12 mr12 toggle-group';

function groupName(prefix, color, extra) {
return `${prefix}-${color || 'default'}-${extra || 'on'}`;
Expand All @@ -41,7 +40,7 @@ function groupName(prefix, color, extra) {
<div
v-for="color in colors"
:key="`a-${active}-${color}`"
:class="groupClass(false)"
:class="groupClass"
>
<label v-for="(label, index) in animals" :key="label" class="toggle-container">
<input
Expand All @@ -57,7 +56,7 @@ function groupName(prefix, color, extra) {
</div>
<div class="mb12 txt-bold color-darken50 txt-uppercase txt-s">Disabled</div>
<div class="mb24">
<div v-for="color in colors" :key="`d-${color}`" :class="groupClass(false)">
<div v-for="color in colors" :key="`d-${color}`" :class="groupClass">
<label v-for="(label, index) in animals" :key="label" class="toggle-container">
<input
disabled
Expand All @@ -69,24 +68,50 @@ function groupName(prefix, color, extra) {
<div :class="toggleClass(color)">{{ label }}</div>
</label>
</div>
<div :class="groupClass">
<label v-for="(label, index) in animals" :key="label" class="toggle-container">
<input
disabled
:name="groupName('disabled', 'active', 'blue')"
:value="label"
:checked="index === 1"
type="radio"
/>
<div :class="toggleClass(null, 'blue')">{{ label }}</div>
</label>
</div>
</div>
<div class="mb12 txt-bold color-darken50 txt-uppercase txt-s">Small</div>
<div class="mb24">
<div v-for="color in colors" :key="`s-${color}`" :class="groupClass(true)">
<div v-for="color in colors" :key="`s-${color}`" :class="groupClass">
<label v-for="(label, index) in animals" :key="label" class="toggle-container">
<input
:name="groupName('small', color)"
:value="label"
:checked="index === 1"
type="radio"
/>
<div :class="toggleClass(color)">{{ label }}</div>
<div :class="toggleClass(color, null, 's')">{{ label }}</div>
</label>
</div>
</div>
<div class="mb12 txt-bold color-darken50 txt-uppercase txt-s">Large</div>
<div class="mb24">
<div v-for="color in colors" :key="`lg-${color}`" :class="groupClass">
<label v-for="(label, index) in animals" :key="label" class="toggle-container">
<input
:name="groupName('large', color)"
:value="label"
:checked="index === 1"
type="radio"
/>
<div :class="toggleClass(color, null, 'l')">{{ label }}</div>
</label>
</div>
</div>
<div class="mb12 txt-bold color-darken50 txt-uppercase txt-s">Light variations</div>
<div class="bg-gray round px12 py12 mt12">
<div v-for="color in lightenColors" :key="`l-${color}`" :class="groupClass(false)">
<div v-for="color in lightenColors" :key="`l-${color}`" :class="groupClass">
<label v-for="(label, index) in animals" :key="label" class="toggle-container">
<input
:name="groupName('light', color)"
Expand All @@ -102,7 +127,7 @@ function groupName(prefix, color, extra) {
Disabled and light
</div>
<div class="bg-gray round px12 py12 mt12">
<div v-for="color in lightenColors" :key="`ld-${color}`" :class="groupClass(false)">
<div v-for="color in lightenColors" :key="`ld-${color}`" :class="groupClass">
<label v-for="(label, index) in animals" :key="label" class="toggle-container">
<input
disabled
Expand Down
18 changes: 14 additions & 4 deletions docs/documentation/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,9 @@ The toggle group component styles a set of `<input type=radio'>` elements. The m
.toggle
```

Style a toggle group.
Style a toggle group. Toggles within a group share an equal width, set by the widest toggle.
Change the inactive toggle text color and the active toggle background color with a `toggle--{color}` modifier (`*-dark` colors are not available).
Change the active label color with a `toggle--active-{color}` modifier (`*-dark` colors are not available).
Change the border radiuses of toggle groups inside small text with `toggle-group--s` on the `toggle-container` element.

```example
<div class='toggle-group mr18'>
Expand All @@ -413,12 +412,13 @@ Change the border radiuses of toggle groups inside small text with `toggle-group

```selectors
.toggle--s
.toggle--l
```

Make a toggle small.
Change the toggle height. `toggle--s` is 18px tall, the default `toggle` is 24px to match `input--s`, and `toggle--l` is 36px to match `input`.

```example
<div class='toggle-group'>
<div class='toggle-group mr18'>
<label class='toggle-container'>
<input checked name='toggle-small' type='radio' />
<div class='toggle toggle--s'>mouse</div>
Expand All @@ -428,6 +428,16 @@ Make a toggle small.
<div class='toggle toggle--s'>cricket</div>
</label>
</div>
<div class='toggle-group'>
<label class='toggle-container'>
<input checked name='toggle-large' type='radio' />
<div class='toggle toggle--l'>horse</div>
</label>
<label class='toggle-container'>
<input name='toggle-large' type='radio' />
<div class='toggle toggle--l'>ox</div>
</label>
</div>
```

```selectors
Expand Down
4 changes: 1 addition & 3 deletions src/preset/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -800,17 +800,15 @@ input:checked + .switch {
background-color: var(--gray);
}
input:checked + .toggle {
background: var(--gray);
background: var(--gray-deep);
color: var(--white);
}
input:disabled + .toggle {
pointer-events: none;
color: var(--darken25);
border-color: var(--transparent);
}
input:checked:disabled + .toggle {
background-color: var(--disabled25);
color: var(--darken25);
}
body,
input,
Expand Down
20 changes: 19 additions & 1 deletion src/preset/colors.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,30 @@ function colorRules(config) {
[s => s, { color: `var(--${color})` }],
[s => `input:checked + ${s}`, { background: `var(--${color})` }]
]);
if (color === 'white' || color.startsWith('lighten')) {
append(`toggle--${color}`, [
[
s => `.toggle-group:has(${s})`,
{ 'background-color': 'var(--lighten10)' }
],
[s => `input:checked + ${s}`, { color: 'var(--gray-dark)' }],
// `.toggle` outranks the checked color above for checked + disabled.
[s => `input:disabled + .toggle${s}`, { color: 'var(--lighten25)' }]
]);
} else if (color.startsWith('darken')) {
append(`toggle--${color}`, [
[
s => `.toggle-group:has(${s})`,
{ 'background-color': 'var(--darken5)' }
]
]);
}
});

colorsFor(resolved, 'toggleActive').forEach(color => {
if (isNotAccessibleForForms(color)) return;
append(`toggle--active-${color}`, [
[s => `input:checked + ${s}`, { color: `var(--${color})` }]
[s => `input:checked:enabled + ${s}`, { color: `var(--${color})` }]
]);
});

Expand Down
36 changes: 28 additions & 8 deletions src/preset/utilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,28 @@ const UTILITY_RULES = [
['switch--l', { width: '40px', height: '24px', top: '0' }],
[
'toggle-group',
{ display: 'inline-flex', 'text-align': 'center', 'border-radius': '18px' }
{
display: 'inline-grid',
'grid-auto-flow': 'column',
'grid-auto-columns': '1fr',
'background-color': 'var(--gray-faint)',
'border-radius': 'var(--border-radius)'
}
],
['toggle-container', { 'max-width': '100%' }],
[
'toggle',
{
'flex-shrink': '0',
display: 'flex',
'align-items': 'center',
'justify-content': 'center',
height: '24px',
padding: '0 18px',
cursor: 'pointer',
color: 'var(--gray)',
color: 'var(--gray-deep)',
'font-size': 'var(--font-size-s)',
padding: '3px 18px',
'border-radius': '15px',
'line-height': 'var(--line-height-s)',
'white-space': 'nowrap',
'border-radius': 'var(--border-radius)',
'background-color': 'var(--transparent)',
transition:
'color var(--transition),\n background-color var(--transition)'
Expand All @@ -169,9 +179,19 @@ const UTILITY_RULES = [
[
'toggle--s',
{
height: '18px',
padding: '0 12px',
'font-size': 'var(--font-size-xs)',
'line-height': 'var(--line-height-s)',
padding: '0 12px'
'line-height': 'var(--line-height-xs)'
}
],
[
'toggle--l',
{
height: '36px',
padding: '0 24px',
'font-size': 'var(--font-size-m)',
'line-height': 'var(--line-height-m)'
}
],
['txt-mono', { 'font-family': 'var(--font-stack-mono)', 'font-size': '90%' }],
Expand Down
Loading
Loading