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
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@

- [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).
- [add] `gap{size}`, `gapx{size}`, and `gapy{size}` on the padding scale, with `*-mm` / `*-ml` / `*-mxl` variants. Use with `flex` or `grid`.
- [breaking] `grid` is a 12-column CSS Grid. A `col` without a width class spans the full row, `w-1/12` to `w-11/12` set how many columns it spans, `ml-1/12` to `ml-11/12` set where it starts, and `grid--gut{size}` sets `column-gap`. `col--auto` is removed, and other left and right margins on a grid `col` are ignored.
- [add] `examples/jit` — a sample app that generates only the utilities used in its markup (no reset or component preflight). On-demand builds can also emit off-scale transforms (`rotate*`, `scale*`); pixel utilities stay on the documented scale.
- [add] `aspect-{ratio}` / `aspect-auto`, `object-{contain,cover,fill,none,scale-down}`, `flex--space-around-main` / `flex--space-evenly-main`, and transform utilities (`rotate{deg}`, `scale{percent}`).
- [breaking] `txt-break-word` uses `overflow-wrap: anywhere`, so words break only when they would overflow, instead of `word-break: break-all`.
- [add] `animation-shimmer`, `visible-on-parent-hover`, `bg-canvas`, and `bg-canvas--dark`.
- [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
27 changes: 25 additions & 2 deletions MIGRATION_GUIDES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

Version 2.0.0 rebuilds Assembly with [UnoCSS](https://unocss.dev/) while keeping the existing class names and `buildUserAssets` API.

You do not need to change class names in markup. Continue to use `assembly.css` / `assembly.js`, or keep calling `Assembly.buildUserAssets`.
Most markup works unchanged. Continue to use `assembly.css` / `assembly.js`, or keep calling `Assembly.buildUserAssets`. Check grids and `txt-break-word` for the changes below.

What can change:

- The contents of `assembly.css` are generated by UnoCSS, so whitespace, comments, rule order, and source maps may differ from 1.x. Selectors and declarations for public classes stay the same.
- The contents of `assembly.css` are generated by UnoCSS, so whitespace, comments, rule order, and source maps may differ from 1.x. Selectors and declarations for public classes stay the same, except for the grid and `txt-break-word`.
- Layout-scale media variants (`px12-mm`, `w-1/2-ml`, and so on) now use the same custom media queries you pass to `buildUserAssets`, instead of the hardcoded default breakpoints.
- `@mapbox/assembly` now depends on `@unocss/core` (used when creating custom builds) and requires Node.js 24+.

Expand All @@ -27,6 +27,29 @@ export default defineConfig({

The generated CSS still uses Assembly's CSS variables and custom media queries, so it needs a PostCSS step with `postcss-custom-properties` and `postcss-custom-media`. See [`presetAssembly` in the README](README.md#presetassemblyoptions) for the config.

### `grid` is CSS Grid

`grid` is now a 12-column CSS Grid instead of a flexbox row. `grid`, `col`, `w-1/12` to `w-11/12`, and `grid--gut{size}` keep their names. Check grids that rely on flexbox behavior:

- `col--auto` is removed. For columns that share the remaining space, use `flex` with `flex-child-grow` on the children.
- A `col` without a width class spans the full row instead of sizing to its content. For content-sized columns, use `flex`.
- `flex-child-*` classes have no effect on a `col`.
- Left and right margin classes on a `col` are ignored. `ml-1/12` to `ml-11/12` still offset a `col`, and need a `w-*` fraction class next to them. `mr-1/12` to `mr-11/12` have no grid equivalent.
- Give every direct child of `grid` the `col` class, including children that only have a `w-*` fraction class.
- `grid--gut{size}` sets `column-gap` instead of a negative margin on `grid` and padding on `col`. Add `gapy{size}` for space between rows.

### `txt-break-word`

`txt-break-word` uses `overflow-wrap: anywhere` instead of `word-break: break-all`, so words break only when they would overflow their container.

### New utilities

These are additive with 1.x class names:

- `gap12` / `gapx12` / `gapy12` (padding scale) for `flex` and `grid` spacing.
- `aspect-16/9`, `object-cover`, `flex--space-evenly-main`, `rotate90`, `scale50`.
- `animation-shimmer`, `visible-on-parent-hover`, `bg-canvas`, `bg-canvas--dark`.

## 1.0.0+

Version 1.0.0 of Assembly introduces breaking changes – learn how to resolve them with this handy guide.
Expand Down
2 changes: 1 addition & 1 deletion docs/.vitepress/theme/IconGrid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { data as icons } from './icons.data.js';
<div
v-for="icon in icons"
:key="icon"
class="w-1/4 w-1/6-ml w-1/12-mxl mb12 py12 px3 flex flex--column flex--center-cross"
class="col w-1/4 w-1/6-ml w-1/12-mxl mb12 py12 px3 flex flex--column flex--center-cross"
>
<svg class="icon h18 w18">
<use :xlink:href="`#icon-${icon}`" />
Expand Down
15 changes: 1 addition & 14 deletions docs/.vitepress/theme/Layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,6 @@ function nestedWrapClass(parent, level) {
return parent.isDoc && level === 0 ? 'block mt6' : 'inline-block block-mm';
}

function useProse() {
const current = normalized(route.path);
return (
current !== '/' &&
current !== '/catalog' &&
!current.startsWith('/examples') &&
!current.startsWith('/documentation')
);
}

onMounted(() => {
updateHash();
window.addEventListener('hashchange', updateHash);
Expand Down Expand Up @@ -173,10 +163,7 @@ onUnmounted(() => {
</div>
</div>
</div>
<div
class="ml180-mm mx-auto px24 w-auto wmax1200-mm px60-mm mb60 mt24"
:class="{ prose: useProse() }"
>
<div class="ml180-mm mx-auto px24 w-auto wmax1200-mm px60-mm mb60 mt24">
<Content />
</div>
</div>
Expand Down
20 changes: 20 additions & 0 deletions docs/.vitepress/theme/LayoutScales.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ const classSets = [
classPatterns: ['px{n}', 'py{n}', 'pl{n}', 'pt{n}', 'pr{n}', 'pb{n}'],
scale: scales.padding
},
{
name: 'Gaps',
classPatterns: ['gap{n}', 'gapx{n}', 'gapy{n}'],
scale: scales.gap
},
{
name: 'Aspect ratios',
classPatterns: ['aspect-{ratio}'],
scale: scales.aspectRatio
},
{
name: 'Rotations',
classPatterns: ['rotate{n}'],
scale: scales.rotate
},
{
name: 'Scales',
classPatterns: ['scale{n}'],
scale: scales.scale
},
{
name: 'Widths',
classPatterns: ['w{n}'],
Expand Down
27 changes: 4 additions & 23 deletions docs/.vitepress/theme/catalog/Grids.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const sizeCombos = [
['-1/6', '-1/6', '-2/3'],
['-1/12', '-1/6', '-3/4']
];
const offsetCombos = sizeCombos.filter(combo => combo.length === 2);
</script>

<template>
Expand Down Expand Up @@ -47,32 +48,12 @@ const sizeCombos = [
Grid with left offset
</h3>
<div
v-for="(combo, index) in sizeCombos"
v-for="([offset, width], index) in offsetCombos"
:key="`ml-${index}`"
class="txt-s grid mb18"
>
<div
v-for="(cell, cellIndex) in combo"
:key="cellIndex"
:class="`col ${cellIndex === 1 ? 'ml' : 'w'}${cell}`"
>
<div v-if="cellIndex !== 1" class="border px3 py3">w{{ cell }}</div>
</div>
</div>
<h3 class="mb12 mt60 txt-m txt-bold color-darken50 txt-uppercase txt-s">
Grid with right offset
</h3>
<div
v-for="(combo, index) in sizeCombos"
:key="`mr-${index}`"
class="txt-s grid mb18"
>
<div
v-for="(cell, cellIndex) in combo"
:key="cellIndex"
:class="`col ${cellIndex === 1 ? 'mr' : 'w'}${cell}`"
>
<div v-if="cellIndex !== 1" class="border px3 py3">w{{ cell }}</div>
<div :class="`col ml${offset} w${width}`">
<div class="border px3 py3">ml{{ offset }} w{{ width }}</div>
</div>
</div>
<h3 class="mb12 mt60 txt-m txt-bold color-darken50 txt-uppercase txt-s">
Expand Down
4 changes: 4 additions & 0 deletions docs/.vitepress/theme/site-nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ const nav = [
'Positioning',
'Margins',
'Padding',
'Gap',
'Sizing',
'Flexbox',
'Aspect ratio',
'Object fit',
'Transforms',
'Layout utils'
]),
docSection('Theming', [
Expand Down
14 changes: 14 additions & 0 deletions docs/documentation/animations.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ Transition and reaction animations. By default, these run once for 1.5 seconds.
<div class="bg-blue inline-block mr18 w60 h60 round animation-shake animation--infinite"></div>
```

```selectors
.animation-shimmer
```

Sweep a highlight across an element to show it is loading or updating. Works on any background color except white. Runs infinitely for 1.5 seconds per sweep; use the speed and delay modifiers below to change it.

```example
<div class="bg-gray-lighter round h36 mb12 animation-shimmer"></div>
<div class="bg-green round h36 mb12 animation-shimmer"></div>
<div class="bg-gray-dark round px12 py12">
<div class="bg-lighten10 round h36 animation-shimmer"></div>
</div>
```

```selectors
.animation--speed-025
.animation--speed-05
Expand Down
Loading
Loading