Skip to content

v0.3.0

Choose a tag to compare

@benface benface released this 19 Sep 23:30
· 21 commits to main since this release
86e172d

Components

  • @monowind/ui. A menu (with submenus), a dialog, a popover, and a tooltip, each a Zag.js state machine wired to the engine. Zag runs the roles and states, the keyboard, typeahead, focus trapping and restore, and dismissal; the engine places each floating part against its trigger in cells, in the top layer, above everything and outside any scroller it opened from. Headless: mark the parts with data-part and mount on their root (menu(root, { id })), then style the parts with Tailwind and monowind classes. positioning.placement takes Zag's placements (bottom-start, top, right-end, …) and flips when the part would overflow the host; positioning.gutter and positioning.offset count cells, and a margin utility on the positioner does the same (mt-1 under a trigger is a gap, -mt-1 on a submenu levels its first item with the item that opened it).
  • React, Vue, and Svelte. @monowind/ui-react (useMenu, useDialog, usePopover, useTooltip), @monowind/ui-vue (composables), and @monowind/ui-svelte (runes) fold Zag's adapter in, one function per component with the same props everywhere. They need React 18, Vue 3.5, or Svelte 5.20 and up. Examples for all three, plus a Vue example app, and the playground sample now opens a menu and a dialog.
  • Surfaces. A popover or dialog takes the theme's text and background colors, as the browser gives it the canvas's. bg-clear on a menu's or popover's content sees through to whatever sits behind the host.

Top layer

  • Popovers and modal dialogs paint last. An open [popover] or modal <dialog> is laid out as a fixed box of the host and painted above everything, outside its ancestors' clips, scrolling, and transforms, in the order they opened. ::backdrop is drawn beneath it: backdrop:bg-black/50 dims the page, backdrop:backdrop-blur-sm blurs it. A fixed box paints and hit-tests from the host's origin too, where it used to vanish inside a scroller.
  • Under a modal dialog the page is blocked, grid included, so grid mode falls back to the dialog's own pointer and selection.
  • Exits. A popover's exit through transition-discrete plays to the end before it leaves the top layer.

Anchor positioning

  • position-area. An out-of-flow box with a position-area is placed in a cell of its anchor's 3×3 grid and aligned toward it; anchors are named by anchor-name, or implied by a popover's invoker (popovertarget, commandfor). position-try-fallbacks flips the box where it would overflow, and its margins flip with it as in CSS; anchor-center centers on the anchor; position-anchor reads normal, auto, none, and match-parent. The area taken is written as data-mw-area, and a box follows its anchor through scrolling.

Theming

  • Derived tokens. --mw-fg and --mw-bg now derive from the host's own color and background-color (a transparent host reads the background behind it, the canvas past the page), so text-* and bg-* on <mono-wind> drive the focus invert and everything that reads the tokens. A change to an ancestor's class or style, or to the color scheme, applies at once. Migration: the built-in themes set color and background-color instead of the two tokens; a stylesheet still declaring --mw-fg/--mw-bg keeps its values.

Engine

  • align-middle on inline boxes lands the line's text on the box's middle row, where it used to behave as top.
  • Painting over glyphs. A glyph painted over another keeps only the fill beneath it: a heading stuck over an italic run no longer turns italic, and a plain run over colored or underlined text stays plain.
  • Box model. A box sized below its borders and padding (Tailwind's <hr>: height: 0 plus a border) keeps its border row, in block and flex layout alike.
  • Aligned lines. A button or other inline box on a centered or right-aligned line sits where the line's text is.
  • Focus and pointer. A menu, listbox, tree, or grid container leaves the focus invert to its items; a press over a focusable target focuses it; a grid drag can start from a menu's border cell; summary and [contenteditable] count as interactive.
  • Locks in a cascade layer. The companion's engine rules moved into @layer theme, so a ! utility (bg-red-500!, w-40!, text-2xl!) or an unlayered !important rule no longer paints the element's own box over the grid or pushes it off its cells; the value still reaches the grid's paint. pointer-events-auto! keeps working as the hit-target escape hatch.
  • Attributes. The host follows the attributes that render (class, style, HTML rendering attributes, ARIA states, data-*) instead of every attribute. Migration: observedAttributes is gone from registerLeafRenderer; the host follows every attribute of a leaf, so drop the field.

Full changelog: v0.2.14...v0.3.0