npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@takeoff-ui/react-spar

v0.1.2

Published

React-first Takeoff wrappers built on top of @turkish-technology/spar.

Readme

@takeoff-ui/react-spar

Current-phase React package for Takeoff components backed by @turkish-technology/spar. Components ship as compound surfaces: state lives on the root and structure lives in named subcomponents.

The public API uses React primitive vocabulary for Accordion state (value, defaultValue, onValueChange, item value) while preserving visual Takeoff vocabulary (type, mode, size) and translating framework mechanics into React conventions (default* props, on* callbacks, and compound children instead of Web Component slots).

Current Surface

The package currently exports:

  • Accordion
  • Button
  • Drawer
  • Tooltip
  • TakeoffSparProvider
  • customization and theme types from the package root

See the docs site for components queued next. Additional wrappers are added only after their component contract is source-backed and any upstream Spar behavior gaps are resolved.

Reference

  • Spar documentation: https://spar.app.turkishtechlab.com/
  • Spar Accordion reference: https://spar.app.turkishtechlab.com/docs/Components/Accordion

Install

@takeoff-ui/react-spar currently targets React 19.x only.

@takeoff-design/tokens is a peer dependency — install it alongside @takeoff-ui/react-spar. Keeping tokens out of dependencies ensures a single tokens copy in your tree and lets you upgrade tokens independently of this wrapper.

pnpm add @takeoff-ui/react-spar @takeoff-design/tokens

@turkish-technology/spar is still a regular dependency of @takeoff-ui/react-spar and is installed automatically. Add it to your own package.json only if your app imports from it directly (for example, when using Spar primitives that react-spar does not re-export).

@takeoff-ui/react-spar does not bundle component CSS. Import the token stylesheet once at the app shell or entrypoint:

import '@takeoff-design/tokens/css/default/theme.css';

Usage

import '@takeoff-design/tokens/css/default/theme.css';
import { Accordion, TakeoffSparProvider } from '@takeoff-ui/react-spar';

export function Example() {
  return (
    <TakeoffSparProvider>
      <Accordion defaultValue="baggage">
        <Accordion.Item value="baggage">
          <Accordion.Header>
            <Accordion.Trigger>Baggage allowance</Accordion.Trigger>
          </Accordion.Header>
          <Accordion.Content>
            Review your cabin and checked baggage limits before your trip.
          </Accordion.Content>
        </Accordion.Item>

        <Accordion.Item value="changes">
          <Accordion.Header>
            <Accordion.Trigger>Flight changes</Accordion.Trigger>
          </Accordion.Header>
          <Accordion.Content>
            Change rules depend on the fare family selected during booking.
          </Accordion.Content>
        </Accordion.Item>
      </Accordion>
    </TakeoffSparProvider>
  );
}

TakeoffSparProvider accepts colorMode ('light' | 'dark', default 'light'), an optional locale string, and an optional components customization map. The provider renders a display: contents wrapper that writes data-theme from colorMode and lang from locale.

Accordion

<Accordion multiple defaultValue={['one']}>
  <Accordion.Item value="one">
    <Accordion.Header>
      <Accordion.Trigger>
        FAQ
        <Accordion.Indicator />
      </Accordion.Trigger>
    </Accordion.Header>
    <Accordion.Content>Answer content</Accordion.Content>
  </Accordion.Item>
</Accordion>
  • Root behavior props: value, defaultValue, multiple, onValueChange, collapsible, disabled, orientation.
  • Root visual props: type, mode, size.
  • Trigger leading content: startContent prop on Accordion.Trigger.
  • Item props: required value, optional disabled.
  • Public parts: Accordion.Item, Accordion.Header, Accordion.Trigger, Accordion.Indicator, Accordion.Content.
  • The disclosure indicator is opt-in: drop <Accordion.Indicator /> into the trigger to render the default chevron, override its children to swap glyphs, or omit it to ship a trigger without a visual affordance. Placement (left vs right of the title) follows where you put it inside the trigger.
  • Web Component shortcuts such as item-level active, header, and custom DOM active-index events are intentionally not part of the React surface; use root state props and compound children instead.

Customization

Every public component part exposes the same customization layers:

  • className: appended to the canonical root slot class.
  • classNames: per-slot extra classes, concatenated with canonical tk-* classes.
  • slotProps: per-slot HTML attributes, shallow-merged below canonical wrapper attributes.
  • provider components: global defaults, classes, and slot props keyed by component name.

Canonical tk-* classes and data-slot attributes are always preserved.

Theme-level Defaults

<TakeoffSparProvider
  components={{
    Accordion: {
      defaultProps: { size: 'large' },
      className: 'travel-faq',
    },
    AccordionTrigger: {
      slotProps: { root: { 'aria-describedby': 'faq-trigger-hint' } },
    },
  }}
>
  {children}
</TakeoffSparProvider>

Instance props override provider defaults. Instance classNames and slotProps override provider entries for the same slot, while canonical wrapper attributes remain in place.

Per-instance Classes

<Accordion.Item value="faq" classNames={{ root: 'faq-item' }}>
  <Accordion.Header>
    <Accordion.Trigger classNames={{ root: 'faq-trigger' }}>
      FAQ
    </Accordion.Trigger>
  </Accordion.Header>
  <Accordion.Content>Answer text</Accordion.Content>
</Accordion.Item>

Per-instance Slot Props

<Accordion.Item
  value="faq"
  slotProps={{
    root: { 'aria-describedby': 'faq-note' },
  }}
>
  <Accordion.Header>
    <Accordion.Trigger>FAQ</Accordion.Trigger>
  </Accordion.Header>
  <Accordion.Content>Answer text</Accordion.Content>
</Accordion.Item>

Custom Indicator

<Accordion>
  <Accordion.Item value="faq">
    <Accordion.Header>
      <Accordion.Trigger>
        FAQ
        <Accordion.Indicator>
          {({ isOpen }) => (isOpen ? <span>-</span> : <span>+</span>)}
        </Accordion.Indicator>
      </Accordion.Trigger>
    </Accordion.Header>
    <Accordion.Content>Answer text</Accordion.Content>
  </Accordion.Item>
</Accordion>

Custom arrow content is rendered inside the canonical .tk-accordion-item-arrow owner node so recipes keep their stable selector.

Accordion.Indicator is opt-in — omit it to render a trigger without a disclosure affordance. Its owner node carries the canonical .tk-accordion-item-indicator class so recipes keep a stable selector.