AkiraAkira.dev
4 min read

What's new in Akira UI 3.2.0

A time picker and a date and time picker for forms, plus charts and stat cards that show the exact figure, with percentages in your locale.

also in FR PT

I released 3.2.0 of Akira UI, a React component library built on shadcn primitives. Besides the usual buttons, dialogs and tables, it ships app shells, ready-made blocks, translated labels and an Inertia adapter.

This release is mostly about two kinds of screen: forms that need a time, and dashboards that need numbers. It’s a minor release, so coming from 3.1.0 you only need to bump the version. The screenshots below are the examples from ui.akira-io.com rendered with 3.2.0, with the data table example cut down to a single row.

Picking a time, or a date and a time

A TimePicker for a pickup slot, open on 14:00 with the minutes in steps of 15

The library had a DatePicker but nothing for picking a time. TimePicker fills that gap. In this example a warehouse takes pickups between 08:00 and 18:00, one slot every 15 minutes:

<TimePicker
    value={pickup}
    onChange={setPickup}
    minuteStep={15}
    minTime="08:00"
    maxTime="18:00"
/>

You can type the hours and minutes into the field or pick them from the columns, and the value comes back as a plain HH:mm string. If you leave out hourCycle, the picker asks Intl.DateTimeFormat for the hour cycle of the date locale set on UiLocaleProvider, so a Portuguese app gets a 24-hour clock and an American one gets AM and PM.

A DateTimePicker with the September calendar, weekends disabled, next to the hour and minute columns

When the form needs a moment rather than a time of day, DateTimePicker puts the calendar and the same columns side by side and returns a Date. Here the maintenance window can only start on a weekday in September, in steps of 30 minutes:

<DateTimePicker
    value={start}
    onChange={setStart}
    minDate={opensAt}
    maxDate={closesAt}
    disabledDays={isWeekend}
    minuteStep={30}
/>

minDate and maxDate bound the time as well as the day: on the first or last allowed day, the columns stop at that bound’s time. Both pickers ship their labels in Portuguese, Spanish and French.

Exact figures in charts

A bar chart of a net balance with zero in the middle, losses in red and a tooltip showing €25,296

A net balance that is positive one month and negative the next is easier to read with zero in the middle, a line through it, and the losses in another colour:

<BarChart
    data={balanceByMonth}
    series={['balance']}
    xKey="month"
    yDomain="symmetric"
    referenceLines={[{ y: 0 }]}
    colorBy={(datum) =>
        Number(datum.balance) < 0 ? 'var(--destructive)' : 'var(--chart-1)'
    }
    yFormat={{ style: 'currency', currency: 'EUR', notation: 'compact' }}
/>

yDomain="symmetric" takes the largest absolute value, rounds it up and mirrors it, so the April peak of 25,296 gives an axis from -30,000 to 30,000. The red comes from colorBy, which takes either a function of the row or 'category' to give each row its own palette colour.

The axis stays compact, counting in steps of €10K, but the tooltip now shows the exact value by default: €25,296 for April. For rankings there’s variant="lollipop", and valueLabels prints the value on each mark. Line charts also take yScale="log", and an area chart can fade with fill="gradient".

A total split into parts

A StatBreakdownCard showing $66.0k collected, split into card, bank transfer and wallet with their shares

StatBreakdownCard puts the total on the left and, on the right, a bar with one segment per part and a legend underneath. Each segment can take focus and shows its label, share and exact value in a tooltip. CompositionBar is the same bar and legend without the card, for when you already have a card of your own.

The shares these components format, and the trend on StatCard, now follow a locale set on the provider. Without it they stay in en-US:

<UiLocaleProvider labels={ptLabels} dateLocale={pt} locale="pt-PT">
    <App />
</UiLocaleProvider>

The 62.4% above becomes 62,4% in pt-PT. A malformed tag such as pt_PT falls back to en-US instead of throwing.

The data table total

A data table footer reading Page 1 of 1, 1 record

The total under the data table now picks singular or plural from the count with Intl.PluralRules. A table with one row says “1 record” instead of “1 records”, and the Portuguese and French labels follow the same rule.

Smaller changes

In closing

With 3.2.0, a form can ask for a time without a custom input, and a dashboard can show the exact figure behind every bar. You can try each component on ui.akira-io.com. The full list of changes is in the release notes, and the package is on npm.

Search the dev log

Search posts, tags, ideas…