sveltelean
Versionv0.2.0 GitHub

When plain HTML is enough

A native dialog, a popover, a disclosure, a checkbox, a switch, a radio group and a button are platform elements. If an application has its own design system, its own CSS conventions and no need for a written contract, it can write the markup and stop there; the behavior is the same, because the behavior is the browser's either way.

settings.svelte
<!-- Plain HTML. No package, no attribute from Svelte Lean. -->
<button type="button" commandfor="settings" command="show-modal">Settings</button>

<dialog id="settings" aria-labelledby="settings-title">
	<h2 id="settings-title">Settings</h2>
	<button type="button" commandfor="settings" command="close">Close</button>
</dialog>

The native-only fixture proves the point from the other side: with the stylesheet and the plugin installed, the production build of button, dialog and popover markup emits a Svelte Lean chunk of 0 B. Nothing was there to remove.

What the package adds for Tier 0

settings.svelte
<!-- The same dialog with the protocol attributes: hooks for the stylesheet and for
     development validation. The behavior is still the browser's. -->
<button type="button" data-slean="button" commandfor="settings" command="show-modal">Settings</button>

<dialog id="settings" data-slean="dialog" aria-labelledby="settings-title">
	<h2 id="settings-title" data-slean-part="title">Settings</h2>
	<button type="button" data-slean="button" commandfor="settings" command="close">Close</button>
</dialog>
  • A contract: the semantics, parts, keyboard, focus, disabled state, RTL, ARIA relationships, SSR and JS-disabled behavior of the element, and the test cases that cover them (dialog).
  • A stylesheet per primitive, built on tokens, with dark mode, forced colors, reduced motion and coarse-pointer sizes handled once (Styling).
  • Browser support knowledge: which platform feature each path depends on, its Baseline status and the documented fallback (Browser support).
  • Development validation of the markup, reported in the browser console with the trigger value concerned, where a relationship is missing.
  • Shared design tokens and the same protocol across every primitive and the table.
  • Types for the options a primitive accepts.

None of these is JavaScript in the production bundle. The data-slean attributes are hooks for the stylesheet and the validation, and the markup is valid without them.

What the package adds for Tier 1

Plain HTML has no accessible tabs interaction and no keyboard model for a menu. For those the package adds what the platform lacks and nothing more:

  • Keyboard behavior: arrow keys, Home and End, activation modes, disabled skipping, RTL, typeahead, Escape and focus return, tested in a browser.
  • ARIA coordination: aria-selected, the roving tabindex, hidden, aria-checked, written to the DOM on every change.
  • A shared runtime: one listener per event type for every instance on the page, measured at 1521 B brotli for tabs and 1932 B brotli for menu, each including the kernel.
  • Build-time discovery, so the registration module is added for the markup that uses it.
  • Cancelable events with a small detail, so the application can veto a change.

The rule

If the browser owns the behavior, Svelte Lean owns nothing, and the documentation shows the plain markup first. The package's value for a native primitive is the contract, the styles and the knowledge around the element, offered as an option; its value for a behavior is the tested interaction the platform does not provide. Both are honest about which is which.