Skip to content

Latest commit

 

History

History
1436 lines (1116 loc) · 55.3 KB

File metadata and controls

1436 lines (1116 loc) · 55.3 KB

@jasonrundell/topiary

4.1.0

Minor Changes

  • #158 2b8f867 Thanks @jasonrundell! - Close the component-contract gaps an external audit found while evaluating a migration onto Topiary (jasonrundell/react-mega-menu, Phase 0 of docs/refactor/topiary-migration.md in that repo). Seven fixes, all additive or corrective:

    • className/style now merge instead of replacing. Every exported component built its own class (Row, Grid, and Blockquote also an inline style) and then spread ...props after it, so a caller's own className/style silently discarded the component's built-in styling instead of appending to it. src/lib/mergeProps.ts is the one place this is now implemented, used by every component that spreads props.
    • A zIndex token category (base/overlay/nav/modal) for stacking a fixed nav bar and its dropdown above page content.
    • color.surfaceAlt, a hover/alt-surface colour token, wired into Link's and the secondary Button variant's :hover state, and checked by the contrast suite like every other rendered pairing (primary/surfaceAlt for Link's hover text, text/surfaceAlt for the secondary Button's). arcade's surfaceAlt is lightened from #fef3c7 to #fff9e3 to clear AA (primary/surfaceAlt was 4.39:1, under the 4.5:1 floor); every other theme already passed.
    • A real contrast floor on the border/surface pair (WCAG 1.4.11's 3:1, up from a minRatio of 1 that let any two distinct colours pass). hangar's and cascade's color.border are darkened just enough to clear it; broadsheet and arcade were already well clear.
    • media, breakpoints, THEME_NAMES, DEFAULT_THEME, and the ThemeName type are now exported from the package's public entry. media gives vanilla-extract-flavoured (min-width: ...) strings; breakpoints gives the same values as bare literals ({ sm: '30rem', md: '48rem', lg: '64rem' }) for a consumer doing its own JS-side responsive math — a consumer can align its build-time responsive styles or theme switcher with Topiary's without guessing at values only visible as compiled CSS custom properties.
    • Component prop types extend the matching React.ComponentPropsWithRef. id, className, aria-*, data-*, and ref already forwarded to the underlying DOM element at runtime; the types now say so, for every component that spreads props (not just Link/Heading/Button).
    • An optional children slot on Link and Button, alongside the existing label. label always renders first; children, when given, follows it in the same element — for a trailing icon or anything else a single string can't express.

4.0.1

Patch Changes

  • #146 113367f Thanks @jasonrundell! - Point package.json's repository, bugs, and homepage fields at jasonrundell/topiary instead of the pre-rename jasonrundell/dropship.

    The GitHub repository itself was renamed after the rebrand landed, but this metadata — along with a handful of links in the landing page, Storybook, and issue templates that pointed at the old Storybook deployment URL — was left pointing at the old name. GitHub redirects the old URLs, so nothing was broken, but the published package should point at its actual home.

4.0.0

Major Changes

  • #136 408b387 Thanks @jasonrundell! - Remove Button's backgroundColor prop.

    It applied the value as an inline style, which is the one place a colour can outrank the theme. A button given backgroundColor="#6200ea" kept that colour through every design change, so the component looked re-themeable and was not — exactly the failure theme-agnostic.test.ts exists to prevent everywhere else.

    primary and size remain. Both select between values the active theme supplies, which is the distinction that matters: a variant is a choice within the system, a literal colour is an escape from it.

    Migration. Restyle through the custom properties instead, which reach every component rather than one button and survive a rebuild:

    [data-theme='mine'] {
      --topiary-color-primary: #0f766e;
      --topiary-color-onPrimary: #ffffff;
    }

    For a genuine one-off, the escape hatch is still there — it is just yours to write, and it no longer sits in the public API advertising itself as the supported route.

  • #136 408b387 Thanks @jasonrundell! - Require React 19, replace Pigment CSS with vanilla-extract, and fix package resolution.

    Breaking changes

    • react and react-dom peer dependencies are now ^19.0.0. Projects on React 18 should stay on the 3.x line.
    • @pigment-css/react is no longer required alongside this package. Topiary now has no runtime dependencies at all — remove it from your dependencies if you installed it only for Topiary.

    Fixes

    • The CommonJS entry point was a .js file inside a "type": "module" package, so Node parsed it as ESM. It is now dist/index.cjs, and require('@jasonrundell/topiary') works.
    • The types export condition was ordered last and resolved as ESM types under require, so types only worked via dynamic import. Type conditions are now split per entry, with dist/index.d.cts emitted for CommonJS.
    • yaml was a runtime dependency that no source file imported. Removed.
    • Storybook demo assets from public/ were being copied into the published package. They no longer are.

    Improvements

    • Design tokens now compile to CSS custom properties with stable names (--topiary-color-primary, --topiary-size-large, and so on). Overriding one in your own stylesheet restyles every component that uses it, with no rebuild. See the README for the naming scheme.
    • The ES bundle is 6.7 kB, down from 26.5 kB.
  • #144 f38fb4c Thanks @jasonrundell! - Rename Dropship to Topiary.

    The old name said nothing true about the library; the new one is the thesis in a word. Topiary is one living structure clipped into unrelated shapes — which is exactly what the library does: the same markup renders as four deliberately unrelated designs, with nothing changing but a token file. The name also keeps faith with the project's CSS Zen Garden lineage. It comes with a mascot: a topiary peacock, drawn once and rendered in all four themes, because the logo should have to prove the claim too.

    Breaking changes

    • The package is now @jasonrundell/topiary. Update your dependency and imports:

      - npm install @jasonrundell/dropship
      + npm install @jasonrundell/topiary
      - import '@jasonrundell/dropship/style.css'
      - import { Card, Button } from '@jasonrundell/dropship'
      + import '@jasonrundell/topiary/style.css'
      + import { Card, Button } from '@jasonrundell/topiary'
    • The CSS custom property prefix — the public theming API — is now --topiary-* instead of --dropship-*. Every property keeps its name after the prefix, so the migration is a find-and-replace:

      [data-theme='mine'] {
      -  --dropship-color-primary: #0f766e;
      +  --topiary-color-primary: #0f766e;
      }

    Theme names (hangar, broadsheet, arcade, cascade), component names, props, and data-theme/data-part attributes are all unchanged.

  • #136 408b387 Thanks @jasonrundell! - Rebuild the token layer as a themeable contract, and ship four themes.

    Topiary now works the way CSS Zen Garden did: tokens drive form, components drive function. The same markup renders in deliberately unrelated ways depending only on which theme is active.

    Four themes

    Theme Character
    hangar Default. Instrumentation: monospaced headings, sharp corners, hairlines
    broadsheet Editorial print: serif, ink on paper, rules instead of boxes, no shadows
    arcade Neo-brutalist: heavy outlines, hard offset shadows, saturated colour
    cascade Soft: generous rounding, blurred elevation, almost no visible borders

    No two designs share a typeface. Each supplies its own body, heading, and monospace face — Hangar sets headings in a monospace, Broadsheet in a serif, Arcade in a heavy grotesque, Cascade in a geometric sans — and a test asserts all three roles are distinct across all four. Typography is the loudest signal a design gives off, so two designs sharing a heading face read as variants of one another however far apart their colour and geometry are.

    Switch with a single attribute — no rebuild, no JavaScript, and it cascades, so a theme can be scoped to any subtree:

    <body data-theme="arcade">
      <aside data-theme="broadsheet">…this subtree only…</aside>
    </body>

    A much larger token contract. The previous set covered colours, sizes, and font families. It now also covers radius, borderWidth, borderStyle, shadow, fontWeight, lineHeight, letterSpacing, duration, and easing. Those structural axes are what let themes look unrelated rather than merely recoloured — a palette swap alone only ever produces the same design in different colours.

    Breaking changes

    • Token custom properties have been renamed and restructured. --topiary-size-* and --topiary-padding-* are replaced by --topiary-space-*; --topiary-heading-* is replaced by --topiary-fontSize-*. Anything overriding the old names needs updating.
    • The Tokens default export and fontFamilyToCss are no longer exported from the package. Token access is via CSS custom properties, or vars from the theme module.
    • src/lib/common.tokens.json is replaced by per-theme documents under src/tokens/.

    Other changes

    • Row gains a gap prop; Grid's columnGap and rowGap now fall back to the theme's space scale instead of collapsing to zero.
    • Components gained real focus-visible rings, transitions, and disabled styling, all token-driven.
    • Headings no longer overflow narrow containers.

Minor Changes

  • #136 408b387 Thanks @jasonrundell! - Themes can now control layout, and adds Card.

    Tokens previously drove appearance only. They now also drive placement. Components with internal structure render their children into named grid areas, and the theme supplies the grid-template-areas string that arranges them — the direct equivalent of the stable element IDs CSS Zen Garden relied on. The component guarantees the slots exist; the theme decides where they go.

    New: Card, the first component with internal structure. It exposes four slots — media, title, body, actions — and each shipped theme arranges them differently from identical props:

    Theme Arrangement
    hangar Media pinned left in a fixed column
    broadsheet Full-bleed media above a single column of text
    arcade Media pushed right, text leading
    cascade Media above, title and actions sharing a row

    New tokens: --topiary-layout-cardAreas and --topiary-layout-cardColumns. Layout tokens are necessarily per-component, since the area names belong to a specific component's slots. DTCG has no layout primitive, so these carry a non-standard $type.

    New: data-part hooks. Every Card slot carries a stable data-part attribute (card, card-media, card-title, card-body, card-actions) as a public hook for a theme that needs to reach past the tokens with its own CSS. Renaming one is a breaking change.

    A token deliberately cannot change DOM order, so visual order and reading order stay coupled and a theme cannot make the tab order disagree with what is on screen. A test asserts it.

Patch Changes

  • #136 408b387 Thanks @jasonrundell! - Every shipped design now meets WCAG AA, enforced by the test suite.

    Adds a contrast check over every colour pairing the components actually put on screen — text on backgrounds, labels on fills, focus rings on surfaces — for all four designs. A design whose colours fail cannot be released.

    It found four real failures the moment it ran, none of which were visible by eye:

    Design Pairing Was Now
    Arcade primary on page 4.47:1 4.72:1
    Cascade onAccent on accent 3.74:1 4.63:1
    Cascade success on page 3.60:1 4.68:1
    Cascade warning on page 3.04:1 4.69:1

    Those token values have been darkened to clear the threshold.

    Two component changes came out of the same work:

    • Link no longer changes colour on hover. Switching to accent made accent a text colour, which would have forced every design's accent to be readable as body copy — impossible for Arcade's yellow. Hover now only thickens the underline, leaving accent free to be a fill.
    • Blockquote's rule now uses primary rather than accent, for the same reason: a fill colour cannot be guaranteed visible as a line.

    Card fix: a card with no media no longer applies the templated layout. It was reserving an empty media column and crushing the text beside it, which was obvious the moment three text-only cards were put in a row.

  • #136 408b387 Thanks @jasonrundell! - Describe the package as what it is.

    The npm description read "Get a React project up and running really fast with Topiary" — a generic speed pitch that says nothing true about this package and nothing that distinguishes it. It is now:

    A token-driven React component library: the same markup renders as four deliberately unrelated designs.

    This is the same correction already made to the README and the Storybook welcome page, applied to the one surface a potential user actually sees first.

Formerly published as @jasonrundell/dropship (3.x and earlier); entries below the rename keep the historical name.

Releases from v3.4.0 onward are generated by Changesets. Earlier entries below were generated by auto.

v3.3.1 (Fri Jan 24 2025)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v3.3.0 (Fri Jan 17 2025)

🚀 Enhancement

Authors: 1


v3.2.0 (Thu Jan 16 2025)

🚀 Enhancement

Authors: 1


v3.1.0 (Wed Dec 11 2024)

🚀 Enhancement

Authors: 1


v3.0.1 (Wed Dec 11 2024)

🐛 Bug Fix

Authors: 1


v3.0.0 (Wed Dec 11 2024)

💥 Breaking Change

Authors: 1


v2.9.3 (Fri Nov 08 2024)

🐛 Bug Fix

Authors: 1


v2.9.2 (Tue Nov 05 2024)

🐛 Bug Fix

Authors: 1


v2.9.1 (Tue Nov 05 2024)

🐛 Bug Fix

Authors: 1


v2.9.0 (Tue Oct 29 2024)

🚀 Enhancement

Authors: 1


v2.7.0 (Mon Oct 28 2024)

🚀 Enhancement

Authors: 1


v2.6.3 (Tue Oct 22 2024)

⚠️ Pushed to main

  • Update README.md with installation instructions and links (@jasonrundell)

Authors: 1


v2.6.2 (Tue Oct 22 2024)

⚠️ Pushed to main

Authors: 1


v2.6.1 (Tue Oct 22 2024)

⚠️ Pushed to main

Authors: 1


v2.3.0 (Tue Oct 22 2024)

🚀 Enhancement

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.3.0 (Tue Oct 22 2024)

🚀 Enhancement

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.3.0 (Tue Oct 22 2024)

🚀 Enhancement

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.3.0 (Tue Oct 22 2024)

🚀 Enhancement

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.3.0 (Tue Oct 22 2024)

🚀 Enhancement

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Sep 27 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Mon Jul 29 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Jul 26 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Jul 26 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Jul 26 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Jul 26 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Jul 26 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Jul 26 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.3 (Fri Jul 26 2024)

⚠️ Pushed to main

🔩 Dependency Updates

Authors: 2


v2.2.2 (Thu Oct 19 2023)

🐛 Bug Fix

Authors: 1


v2.2.1 (Thu Oct 19 2023)

🐛 Bug Fix

Authors: 1


v2.2.0 (Mon Oct 02 2023)

🚀 Enhancement

Authors: 1


v2.1.0 (Fri Sep 29 2023)

🚀 Enhancement

Authors: 1


v2.0.2 (Thu Sep 28 2023)

🐛 Bug Fix

Authors: 1


v2.0.1 (Wed Sep 27 2023)

🐛 Bug Fix

Authors: 1


v2.0.0 (Wed Sep 27 2023)

💥 Breaking Change

🚀 Enhancement

🔩 Dependency Updates

Authors: 2