AkiraAkira.dev
5 min de leitura

O que traz a Akira UI 3.1.0

Etiquetas em espanhol e em português europeu, badges na sidebar, coluna de ações fixa e a correção dos filtros de tabela no Inertia 3.

também em EN FR

Boa parte da 3.1.0 da Akira UI é para aplicações cuja interface não está em inglês. Há um pacote de etiquetas novo em espanhol, o português passou a ser português europeu do princípio ao fim, e o menu do utilizador na sidebar deixou de mostrar “Settings” e “Log out” numa interface em português.

Para quem não conhece, a Akira UI é uma biblioteca de componentes React construída sobre os primitivos do shadcn. Além de botões, diálogos e tabelas, traz shells de aplicação (sidebar, cabeçalho, menu do utilizador), blocos prontos, etiquetas por língua e um adaptador para Inertia. A 3.1.0 é uma minor sem breaking changes, por isso quem está na 3.0.0 só tem de subir a versão. Saiu agora para que a 1.0.0 do Nos-Ferry/support pudesse depender de uma versão publicada e não do branch main-dist.

Etiquetas em espanhol e em português europeu

O pacote espanhol tem a mesma forma do francês e está escrito em espanhol de Espanha:

import { UiLocaleProvider } from '@akira-io/ui';
import { esLabels } from '@akira-io/ui/locales/es';

<UiLocaleProvider labels={esLabels}>
    <App />
</UiLocaleProvider>;

O português, esse, andava inconsistente. Misturava grafias anteriores ao acordo, como “Seleccione”, com formas brasileiras e do acordo, como “Selecione” e “navegador”. Como o pacote se destina a Portugal e a Cabo Verde, todas as strings seguem agora uma só grafia europeia, a anterior ao acordo (“Seleccione”, “actual”, “acção”), e há um teste que rejeita as formas brasileiras e as do acordo.

O provider também chega agora a mais sítios. O EmptyState, o DangerZone, os formulários em overlay e o editor vão buscar-lhe as etiquetas, e o mesmo acontece com o texto para leitores de ecrã dos primitivos do shadcn: o “Close” do Dialog e do Sheet, o “Go to previous page” da Pagination, o “Toggle Sidebar”, o “Previous slide”. Até aqui, quem usava leitor de ecrã numa aplicação com ptLabels continuava a ouvir esses textos em inglês. Um teste de cobertura compara agora cada pacote com o português, chave a chave, para que uma etiqueta acrescentada a um não fique a faltar noutro.

A sidebar

Um item de navegação aceita agora badge e badgeLabel. O caso típico é uma fila de reembolsos, em que quem a gere quer ver quantos estão à espera sem abrir a página:

const mainNavItems: NavItem[] = [
    { title: 'Dashboard', href: '/dashboard', icon: LayoutGrid },
    {
        title: 'Refunds',
        href: '/refunds',
        icon: Receipt,
        badge: openRefundsCount,
        badgeLabel: `${openRefundsCount} refunds awaiting review`,
    },
];

O NavMain mostra o número encostado à direita da linha. Zero, um valor vazio ou um booleano não mostram nada, e assim uma fila sem pendentes deixa a linha limpa. De 1 a 99 aparece o número, acima disso aparece 99+. Com a sidebar reduzida aos ícones, o badge passa a ser um ponto sobre o ícone e o valor exato vai para o tooltip. O badgeLabel existe por causa dos leitores de ecrã: um “7” sozinho não diz o que está a contar, por isso a etiqueta torna-se o nome acessível da linha e o número em si fica escondido das tecnologias de apoio.

O AppSidebarHeader ganhou um slot actions, que aparece no extremo direito a seguir ao botão de pesquisa e serve para um sino de notificações ou um menu do utilizador. O adaptador de Inertia também o encaminha:

<AppSidebarHeader
    breadcrumbs={breadcrumbs}
    linkComponent={Link}
    onSearchClick={openCommandMenu}
    actions={<NotificationBell />}
/>

Quanto ao menu do utilizador, as entradas vêm agora do locale provider. Quando uma aplicação precisa de outro texto, o userMenuLabels do AppSidebar sobrepõe-se ao provider.

Três correções

A mais grave partia os filtros de tabela no Inertia 3. O hook dos filtros passava only: current.only em todas as visitas, mesmo sem only definido. O Inertia 3 lê visit.only.length, e um undefined explícito sobrepunha-se ao valor por omissão do router, de modo que a visita rebentava antes de sair qualquer pedido. A correção cabe numa linha:

// src/inertia-table-filters.ts
router.visit(current.url, {
    data: toQuery({ ...current.filters, ...changes }),
    ...(current.only ? { only: current.only } : {}),
    // …
});

A segunda era o DatePicker com dois contentores: o popover e, lá dentro, o calendário com anel e sombra próprios. A variante nested-surface existe para tirar essa segunda superfície, mas reconhecia o pai pelo data-slot, e renomear um componente com slotName substitui o data-slot. O popover do DatePicker chama-se calendar-popover, e o ConfirmDialog, o FormDialog e mais alguns perdiam o reset pelo mesmo motivo. Os cards e os conteúdos de overlay escrevem agora um atributo data-surface à parte, e é esse que a variante procura:

/* theme.css */
@custom-variant nested-surface (
    &:is(
        [data-surface]:not([data-inset]) *,
        [data-slot='sidebar'] *,
        [data-slot='data-table'] *
    )
);

O painel do floating sheet também recebeu o atributo. Um teste abre cada superfície marcada com um card lá dentro, e basta tirar o atributo a uma delas para esse teste falhar.

A terceira vê-se no macOS. O overscroll elástico mostra o fundo do elemento html, que ninguém pintava, e aparecia uma faixa de outra cor por cima da sidebar inset. O novo root-background.css, importado pelo theme.css, resolve isso:

:root {
    background-color: var(--background);
}

:root:has([data-slot='sidebar-wrapper'] [data-variant='inset']) {
    background-color: var(--sidebar);
}

Tabelas e campos de detalhe

A última coluna da data table, onde fica o menu da linha, mantém-se fixa quando a tabela faz scroll na horizontal. Num ecrã estreito, o menu fica à mão sem ir até ao fim da linha, e a sombra sobre as colunas escondidas só aparece quando há de facto alguma coisa por trás.

No bloco info field, um valor comprido, como um endereço de email, podia empurrar o botão de copiar para fora de uma coluna estreita. O botão passou para junto da etiqueta e o valor é cortado com reticências. Para manter o layout antigo, há copyPlacement="value".

Para terminar

Numa aplicação em português ou espanhol, é com esta versão que deixa de aparecer texto em inglês pelo meio. A lista completa está nas notas da release, o pacote está no npm e a documentação está na pasta docs do repositório.

Pesquisar no Dev Log

Pesquisar artigos, etiquetas, ideias…