packages/components — measured against 0.2.321.
We are adopting the library across six stx apps and inventoried what we hand-roll. Most of it maps cleanly onto the 102 shipped components. Three do not, and in each case the library already ships the pieces, which is what makes the absence feel like a gap rather than a wishlist.
1. DateRangePicker — the strongest case
Calendar ships, but it is single-date only. Its props are value, minDate, maxDate, disabledDates, locale, firstDayOfWeek, showToday, highlightToday — there is no range mode, no start/end pair, and no presets.
So every app that needs "last 7 days / last 30 days / custom range" builds it. We now have four near-identical copies, hand-ported between repos:
analyticshq/resources/components/DateRangePicker.stx 16 buttons, 5 selects, 1 dialog
loghq/resources/components/DateRangePicker.stx 15 buttons, 4 selects, 1 dialog
bughq/resources/components/DateRangePicker.stx 14 buttons, 4 selects, 1 dialog
status/resources/components/DateRangePicker.stx 12 buttons, 4 selects, 1 dialogFour copies of the same bugs, fixed four times. It is the single largest piece of duplicated UI we have.
A shipped version composes entirely from things you already have — Popover for the panel, Calendar for the grid, Button for the presets — so the ask is mostly a range selection mode on Calendar plus a preset list. Something like:
<DateRangePicker
:start="from" :end="to"
:presets="[7, 30, 90]"
@change="apply($event)"
/>If a full DateRangePicker is too opinionated, Calendar gaining a range mode would be most of the value — the preset row is a Button loop any app can write.
2. ThemeToggle
Hand-rolled in four of our six apps (analyticshq, bughq, loghq, status). Sidebar already has followSystemAppearance and a theme prop, so the library clearly has a theme concept — there is just no standalone control to drive it.
Every implementation is the same three states (light / dark / system), the same localStorage persistence, and the same pre-paint flash problem to avoid. That last part is the reason it belongs in the library: getting it wrong means a flash of the wrong theme on every load, and it is not obvious which order the class and the stored value have to be applied in.
3. EmptyState
29 files across all six apps render a hand-built empty state — icon, heading, one line of explanation, optional action button. Card and Button exist; the composition does not.
status 14 · bughq 4 · loghq 4 · reportshq 3 · analyticshq 2 · commshq 2Low complexity, high repetition — the kind of thing that ends up subtly inconsistent across an app suite precisely because it is easy enough that everyone writes their own.
<EmptyState icon="inbox" title="No monitors yet" description="Add one to start checking uptime.">
<Button variant="primary">Add monitor</Button>
</EmptyState>Deliberately not asking for charts
We also hand-roll BarChart, LineChart, DonutChart, FunnelChart, HeatmapChart and TableChart. Those are compiled to web components and shipped in our own packages on purpose, so they are a product decision rather than a library gap. Noting it only so the absence is not read as an oversight — Heatmap shipping while the rest do not is a slightly odd shape, but we are not asking you to close it.
Priority, if only one gets built
DateRangePicker (or range mode on Calendar). It is the only one of the three where the absence has already cost us four maintained copies, and it is the one an app cannot reasonably get right by composing what exists today.