Skip to content

Releases: losol/ratio-ui

@eventuras/ratio-ui@2.16.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 21:04
Immutable release. Only release title and notes can be modified.

Minor Changes

  • 1fbf082: Two-tone (split) chips: <Chip split> renders a segmented key/value pill —
    <Chip.Key> (darker, meta voice built in) + <Chip.Value> (lighter,
    semibold, family-neutral) sharing one border and radius. Segment colors read
    from new --chip-key-bg/-fg and --chip-value-bg/-fg tokens, so scopes
    re-skin them like any chip (colored keys, square corners) without extra
    variants.

  • 477960f: Make Footer composable with a set of building blocks.

    New compound subcomponents let you assemble editorial or compact footers from
    parts instead of hand-writing markup:

    • Footer.Brand — logo + wordmark + a serif mission line
    • Footer.LinkColumn + Footer.Link — titled link stacks; a link can carry a
      tag badge or an external arrow, and takes an as prop for router links
    • Footer.Publisher — the imprint block (reuses the Publisher shape)
    • Footer.Newsletter — frames a label/hint around your own signup form
    • Footer.Social + Footer.Social.Item — a row of round icon links
    • Footer.BottomBar — the thin copyright/legal row, with an optional top rule

    Everything is token-driven; a dark footer now re-scopes the text and border
    tokens so blocks stay legible on the deep surface without hardcoded colours.
    Footer and Footer.Classic are unchanged, so existing footers keep working.

  • 442bbc7: Two small primitives for editorial outlines (className-free consumers):

    • Text gains family ('sans' | 'serif' | 'mono', from the theme's font
      tokens) and transform ('none' | 'uppercase' — uppercase bundles a modest
      letter-spacing). Together with size="xs" + variant="subtle" this is the
      small meta/caption voice (type labels, counts) previously only reachable via
      className. Text prop types are now exported from core/Text.
    • Stack gains rail — a --border-1 hairline down the left edge with a
      matching inset, marking children as one level deeper in a hierarchy
      (outlines, threads, tree levels). Vertical stacks only.
    • Stack align accepts 'baseline' — for horizontal stacks pairing text at
      different sizes (a title and its caption), so baselines line up instead of
      boxes.

@eventuras/markdown@0.14.0

Choose a tag to compare

@github-actions github-actions released this 27 Jul 21:04
Immutable release. Only release title and notes can be modified.

Minor Changes

  • ce9a5a7: Add a codeBlock component slot to MarkdownContent — the opt-in seam for
    syntax highlighting. Pass @eventuras/ratio-ui-shiki's CodeBlock and fenced
    code blocks highlight (theme-aware, client-side); by default nothing changes
    and no highlighter code is bundled. The slot receives the exact props the
    built-in CodeBlock rendering uses (MarkdownCodeBlockProps, exported), so
    CodeBlock-compatible components are drop-ins that match the default
    appearance. Inline code and unknown-language fallback are unaffected.

@eventuras/ratio-ui@2.15.0

Choose a tag to compare

@github-actions github-actions released this 22 Jul 08:27
Immutable release. Only release title and notes can be modified.

Minor Changes

  • 68a188a: Heading now forwards standard DOM and ARIA attributes to the rendered
    element.

    id, style, role, aria-*, event handlers and the other HTML heading
    attributes now reach the element, so anchor targets like
    <Heading as="h2" id={slug}> work without wrapping the heading in an
    id-bearing element. Spacing props are still compiled to utility classes, and
    className/testId keep their explicit meaning — spacing keys never leak onto
    the DOM (they are split out with extractSpacingProps).

  • 71c0a89: Add InlineCode and Divider core components.

    • InlineCode renders a <code> pill styled with the shared --code-* tokens,
      so inline snippets match CodeBlock and stay legible in every theme.
    • Divider renders a token-driven thematic break (--border-2) rather than a
      fixed grey rule.

    Both ship their own theme-aware CSS that travels with the component import, so
    they work regardless of which CSS entrypoint the app uses.

  • 937f5c4: Behavior change: global.css no longer hides the page until a theme is set.

    The light theme is fully defined on bare :root, so a page with no data-theme
    is already correctly styled. The previous html { opacity: 0 } guard hid it
    anyway until a theme attribute appeared — which meant any consumer who never set
    data-theme got a permanently blank white page, with no error. For a design
    system that is the worst possible first-run experience.

    The visibility guard is now opt-in and forgiving:

    html[data-theme-loading]:not([data-theme]):not([data-color-scheme]) {
      opacity: 0;
    }
    • Import the CSS and render — the page is visible in the light theme. No
      attribute required.
    • Set data-theme for another palette; it can be set late without the page
      ever going blank.
    • Resolving the theme in JS after first paint and want no flash? Set
      data-theme in a blocking <head> script (correct first paint), or add
      data-theme-loading to <html> and set data-theme once resolved.

    Migration. If you already set data-theme in a blocking <head> script,
    nothing changes. If you relied on the default opacity: 0 to mask a
    JS-resolved theme applied after paint, add data-theme-loading to <html> to
    keep the same hide-until-resolved behavior.

  • 80cbd81: Add slugify and getTextContent utilities (@eventuras/ratio-ui/utils).

    • slugify is the single source of truth for heading anchor ids — the same
      GitHub-flavoured slug used both to id a heading and to build the table of
      contents that links to it, so the two never drift.
    • getTextContent flattens a React node tree to plain text, e.g. for slugging
      a heading whose children mix strings and inline elements.

    Together with the existing TableOfContents component and TocHeading type,
    these let a consumer render an anchored, scroll-spied TOC without re-inventing
    the slug convention.

@eventuras/markdown@0.13.0

Choose a tag to compare

@github-actions github-actions released this 22 Jul 08:26
Immutable release. Only release title and notes can be modified.

Minor Changes

  • 71c0a89: Fix dark mode. Code blocks, inline code, blockquotes and rules were rendered
    with hardcoded light Tailwind greys and turned near-invisible under
    data-theme="dark". Rendering now delegates to ratio-ui's theme-aware
    components, so no hardcoded colours remain in the component map:

    • fenced code blocks → CodeBlock
    • inline code → InlineCode
    • blockquotes → Blockquote
    • thematic breaks → Divider

    Requires @eventuras/ratio-ui ^2.15.0 (peer range raised from ^2.13.0) for
    the new InlineCode and Divider primitives.

  • 80cbd81: Add extractHeadings(markdown), which pulls the h2/h3 headings out of raw
    markdown as a TocHeading[] for an "on this page" table of contents. Ids are
    produced with ratio-ui's slugify, so they match the anchors a heading
    renderer puts on the page; fenced code blocks are skipped and link/emphasis
    syntax is stripped from the visible text. Pairs with
    @eventuras/ratio-ui/core/TableOfContents.

  • f8207a1: Move the markdown engine into runtime dependencies, and name its component type.

    • react-markdown, rehype-raw, rehype-sanitize and remark-gfm move from
      peer to regular dependencies. They are internal implementation — the component
      builds its own render pipeline and shares no instance across the package
      boundary — so consumers no longer have to install them by hand. Only react,
      react-dom and @eventuras/ratio-ui, which genuinely need one shared copy,
      remain peers.
    • New exported type MarkdownComponents for customComponents. It is
      react-markdown's Components (plus custom element names from remark plugins),
      aliased so consumers import it from this package instead of reaching into
      react-markdown, and so the name survives a future change of renderer.

@eventuras/ratio-ui@2.14.0

Choose a tag to compare

@github-actions github-actions released this 21 Jul 18:23
Immutable release. Only release title and notes can be modified.

Minor Changes

  • 69c337d: CodeBlock: inline annotations.

    annotations renders notes directly beneath the line they refer to — validation
    output, review comments, explanations:

    <CodeBlock
      code={source}
      annotations={[
        {
          line: 8,
          severity: "error",
          code: "circular-ref",
          path: "Event.prerequisite.ref",
          message: "An event cannot be its own prerequisite.",
        },
      ]}
    />

    Each note takes a severity (error | warning | info | success, tinted with the
    matching semantic tokens so it follows light/dark), an optional machine-readable
    code shown as a pill, and an optional path for where it points. message is
    a React node rather than an HTML string, so this stays injection-safe like the
    rest of CodeBlock.

    Unlike a hover tooltip the notes stay put: long messages get room to wrap, the
    whole set is scannable at a glance, and the text lives in the document — so
    keyboard and screen-reader users reach it, and a screenshot captures it.

    Companion packages that wrap the core CodeBlock (e.g.
    @eventuras/ratio-ui-shiki) pick this up without any change of their own.

  • c4a6a95: CommandPalette: injection-safe result highlighting (description + highlights), descriptionHtml deprecated.

    CommandPaletteItem now takes a plain-text description plus optional
    highlights[start, end) character ranges the component wraps in <mark>
    itself. No HTML is injected, so search-result excerpts from untrusted content
    are safe by default:

    { id, title, description: 'Streaming logs and audit trails', highlights: [[0, 9]] }

    Out-of-bounds ranges are clamped and overlapping ones skipped, so a provider
    can hand over raw match offsets without pre-validating them.

    • descriptionHtml is deprecated — it injects raw HTML via
      dangerouslySetInnerHTML and is an XSS vector for untrusted values. It still
      renders (trusted/pre-sanitized content only) but is ignored when
      description is set, and will be removed in the next major. Migrate excerpt
      highlighting from an HTML string to description + highlights.

    This takes raw HTML off CommandPalette's default render path — the library's
    only remaining dangerouslySetInnerHTML is now the opt-in, deprecated
    descriptionHtml fallback.

Patch Changes

  • ceaeb95: NavTree: content items require a stable id, and content is detected by key presence.

    • NavTreeContentItem now requires id: string. With no href or string
      title to key on, an index-based fallback would remount the (often stateful)
      content — e.g. a SearchField filtering its own group loses focus — when
      siblings are filtered or reordered.
    • Content vs. link rows are distinguished by 'content' in node rather than a
      truthiness check, so a content value of 0/''/null is no longer misread
      as a link row.

ratio-ui-shiki v0.1.0

Choose a tag to compare

@github-actions github-actions released this 21 Jul 18:23
Immutable release. Only release title and notes can be modified.

What's Changed

  • Commandpalette safe highlights by @losolio in #68
  • feat: add @eventuras/ratio-ui-shiki (alpha) — Shiki highlighting for CodeBlock by @losolio in #71
  • feat(ratio-ui-shiki): add useShikiHighlighter hook by @losolio in #72
  • CodeBlock: Use fine-grained shiki/core for minimal bundles by @losolio in #74
  • CodeBlock: Add inline annotations by @losolio in #76
  • feat: move datatable from eventuras by @losolio in #77
  • datatable: Make publishable and wire up npm release by @losolio in #79
  • feat(markdown): add @eventuras/markdown by @losolio in #80
  • chore: version packages by @github-actions[bot] in #69

Full Changelog: https://github.com/losol/ratio-ui/compare/@eventuras/ratio-ui@2.13.0...@eventuras/ratio-ui-shiki@0.1.0

@eventuras/markdown@0.12.0

Choose a tag to compare

@github-actions github-actions released this 21 Jul 18:23
Immutable release. Only release title and notes can be modified.

Minor Changes

  • 2f52323: Moved into losol/ratio-ui. The package now lives beside the design system
    it renders with, and is released from this repository.

    • Relicensed from MIT to MPL-2.0, matching the rest of the Ratio UI family.
    • Renumbered onto a 0.x line. The package was never published to npm — its
      old version tracked the eventuras monorepo rather than this package's own
      API — so 9.0.6 became 0.11.6, each former major bump becoming a minor one.
    • The @eventuras/ratio-ui peer range tightens from >=1 to ^2.13.0. The old
      range accepted a v1 design system against components written for v2.
    • Shared config now comes from this repository's @ratio-ui/* packages
      (typescript, vite and eslint config) instead of the @eventuras/* ones.
    • test runs vitest run rather than watch mode, and the package is registered
      as a vitest project at the repo root so its jsdom environment and setup files
      apply — without that, its tests would silently skip locally and fail in CI.
    • Fixed: extending the sanitize schema dropped the default attributes for
      any tag the extension also named. Both mergeSanitizeSchemas and
      MarkdownContent's own merge used a shallow spread, so extending a with a
      single attribute discarded the rest of GitHub's allowlist for a — including
      href, silently breaking every link. Attribute lists are now concatenated
      per tag and de-duplicated.
    • Documentation fix: the README claimed data: URLs were blocked outright. They
      are blocked in links but allowed for images, per GitHub's default schema.

Versions before the move were renumbered. This package was developed in
the eventuras monorepo and never published to npm, so its version tracked
that repository rather than this package's own API. On moving here it was
renumbered onto a 0.x line: each former major bump became a minor bump
(the breaking slot in 0.x), so 9.0.6 became 0.11.6. The entries below
keep their original text — only the version headings changed.

@eventuras/datatable@0.6.0

Choose a tag to compare

@github-actions github-actions released this 21 Jul 18:23
Immutable release. Only release title and notes can be modified.

Minor Changes

  • fe53b07: Publishable from this repository, and fixed for Node consumers.

    • Added "type": "module". The build emits ESM, but without this Node read
      dist/index.js as CommonJS and threw Cannot use import statement outside a module the moment anyone imported the package.
    • Breaking: @eventuras/ratio-ui moved from dependencies to
      peerDependencies (^2.13.0), matching the other Ratio UI companion
      packages. As a regular dependency it resolved to a pinned copy at publish
      time, so consumers ended up with a second ratio-ui beside their own —
      duplicated styles and two module instances. Install @eventuras/ratio-ui
      alongside this package.
    • Ships a LICENSE (MPL-2.0), a README and a description; the published
      package carried none of them.

Patch Changes

  • 5b5777c: Moved into losol/ratio-ui. The package consumes @eventuras/ratio-ui from the
    workspace again rather than from npm — which supersedes the note on 0.5.29, where
    that entry described the arrangement while datatable still lived in
    losol/eventuras. It no longer depends on @eventuras/ratio-ui-next at all.

    Alongside the move:

    • Column headers declare scope="col", so screen readers announce them as
      column headers while navigating the grid.
    • The client-side page-size effect now re-runs when pageSize or
      clientsidePagination change, instead of only on mount — page size no longer
      goes stale when those props change.

@eventuras/ratio-ui@2.13.0

Choose a tag to compare

@github-actions github-actions released this 16 Jul 00:04
Immutable release. Only release title and notes can be modified.

Minor Changes

  • fdee141: NavTree: defaultOpen on branches and defaultExpandedDepth on the tree.

    • { title: 'Resources', defaultOpen: true, … } — one branch starts expanded
      without containing the current page.
    • defaultExpandedDepth={1} — every top-level branch starts expanded
      (Infinity opens everything).

    Both share the active branch's semantics: the user's toggle wins until
    currentPath changes, then the defaults re-assert — and the chevron's first
    click now collapses a branch that's open via a default (the toggle shares the
    derived base).

    NavTreeItem is now a union (NavTreeLinkItem | NavTreeContentItem):
    regular rows keep a required title — the accessible name — while content
    items may omit it, so no more placeholder title: "". Mixing content with
    row props (href, icon, children, …) is now a type error instead of
    being silently ignored.

    The LinkComponent prop type now declares everything NavTree actually passes
    (style for the depth indent, aria-current, rail aria-label/title) —
    adapters that only forward className silently lose the indent and the
    active/rail semantics, so spread the rest: ({ href, ...rest }) => <Link to={href} {...rest} />.

@eventuras/ratio-ui@2.12.0

Choose a tag to compare

@github-actions github-actions released this 15 Jul 01:42
Immutable release. Only release title and notes can be modified.

Minor Changes

  • e7246c5: Navbar — composition parts for app headers.

    The navbar can now be assembled from parts (existing Brand/Content are
    untouched):

    • Navbar.Search — a growing, width-capped zone for a search control.
      It's a slot: drop a SearchField in from the call site (core/ can't
      depend on forms/).

    • Navbar.Links + Navbar.Link — horizontal pill links with icon,
      isCurrent (tinted pill + aria-current="page"), and LinkComponent
      injection for SPA routers.

    • Navbar.Actions — the right-hand cluster (bell, theme, user menu).

    • Navbar.Spacer — flexible gap.

    • Navbar.Row — stack rows for the editorial 2-row layout, with
      variants utility (slim tinted strip), brand, and nav. Rows are
      separated by background tone, never borders.

    Root gains elevated — elevation instead of lines, per the design
    ("baren står på en subtil skygge"): card background and a soft shadow, never
    borders. Centered it's a floating card (rounded from md, full-bleed below);
    with fluid (full-width row for admin consoles) it's a flat app header.

    Drawer gains a side prop ('left' | 'right' | 'top' | 'bottom',
    default right) — nav sheets from the left, action sheets from the bottom
    (rounded lip, content-sized up to 85vh), notification trays from the top. Its
    close affordance is now a round ghost ActionButton instead of a full
    secondary Button pill.

    Navbar.Toggle + Navbar.Collapse own the mobile pattern: a round
    burger button that morphs into an X in place, and a disclosure panel folding
    out under the bar — aria-expanded/aria-controls and panel ids wired
    automatically (no state at the call site). Pairs are linked by
    controls/id (default 'menu'), so a navbar can host several independent
    panels — e.g. a search toggle and a burger — with one open at a time. Panels
    unmount when closed. Navbar is now a Client Component ('use client').

    The stories use staged collapse (search needs lg, links md) so nothing
    wraps awkwardly at mid widths.

    <Navbar sticky elevated fluid>
      <Navbar.Brand>…logo…</Navbar.Brand>
      <Navbar.Links>
        <Navbar.Link href="/" isCurrent>Dashboard</Navbar.Link>
      </Navbar.Links>
      <Navbar.Search><SearchField size="sm"  /></Navbar.Search>
      <Navbar.Spacer />
      <Navbar.Actions>…bell, user menu…</Navbar.Actions>
    </Navbar>
  • b2998e4: NavTree: horizontal orientation, accent active marker, and a content slot.

    • orientation="horizontal" — the top-level items as a tab row with an
      accent underline on the active item (the navbar nav-row form, per the
      design's navbar spec). Groups flatten and nesting isn't rendered.
    • Visual change: the vertical active row now uses the accent (Ochre)
      tint with a 3px accent bar — the same "current" marker as Menu — replacing
      the primary tint.
    • NavTreeItem.content — render arbitrary JSX as an item (no row
      chrome), e.g. a compact SearchField living inside a group and filtering
      its siblings. Composed from the call site; NavTree stays in core.
      Hidden in iconOnly and horizontal modes.
  • 58bc0cd: SearchField & ActionButton — sizes, a real clear button, round variant, and React Aria alignment.

    SearchField:

    • size'sm' | 'md' | 'lg' (default md); sm is the compact
      variant for sidebars and toolbars (the "Filter types…" pattern).
    • The clear button now actually renders — the docs always claimed one, but
      React Aria only wires a clear button when the field contains a button. It's
      an ActionButton round hooked up automatically through React Aria's
      ButtonContext, shown only while the field has content (Escape still clears).
    • More React Aria surface: onClear, name, autoFocus, plus testId.
    • Visual change: md/lg now match Button's heights (~38px/~50px) instead
      of the chunky p-4 + border-2 form default, so a SearchField sits level
      with buttons in the same toolbar row.
    • New FilterNavigation story shows the sidebar pattern: a small SearchField
      live-filtering a NavTree.

    ActionButton:

    • Rebuilt on React Aria's Button — unified press handling and RAC
      context participation (which is what powers the SearchField clear button).
      onPress and isDisabled are available; onClick/disabled keep working.
    • round — fully circular chrome for burger/bell buttons and clear-X
      affordances.
    • The subtle look is now the default (card-toned chrome); the former
      transparent default is available as variant="ghost", and the subtle
      variant name is gone (beta). Token-scoped consumers (Console, CodeBlock)
      re-skin via --action-button-* and are unaffected.
    • Fixed: icon + plain-text buttons lost their horizontal padding. The
      CSS-based icon-only check (:only-child) doesn't see text nodes, so
      <Pause /> Pause was treated as icon-only and rendered flush. Icon-only
      detection is now element-based; icon-only buttons still stay square.
    • Now a Client Component ('use client'), as required by React Aria.

    Also exports Bell, Pause, and Play icons, and the ActionButton stories are consolidated to five scriptorium-themed examples.

  • 5d57df5: SearchField shortcut + a generic useKeyboardShortcut hook.

    New in hooks/: useKeyboardShortcut(combo, handler, options) — parses a
    'mod+k'-style combo (mod = ⌘ on Apple platforms, Ctrl elsewhere), binds a
    global listener, keeps the handler in a ref, SSR-safe. Ships with
    shortcutLabel(combo) (platform-correct ⌘K / Ctrl+K text for Kbd
    hints) and isApplePlatform(). Reusable for command palettes, dialogs, and
    anything shortcut-shaped.

    SearchField gains shortcut as the first consumer: the combo focuses
    the field from anywhere, and a Kbd hint with the platform-correct label
    shows inside the field while it's empty and unfocused.

Patch Changes

  • bd4435e: SearchField: remove the double clear button. WebKit renders a native
    cancel button on input[type=search] next to SearchField's own clear
    ActionButton; the native one is now suppressed.