Repository navigation
@codeatlasdev/ui@4.2.0
·
193 commits
to main
since this release
Minor Changes
- b65d56d: AI feedback loop. The
ca-ui-mcpserver has a newreport_issuetool: an agent that hits a library problem (bug, missing prop or component, migration gap, wrong docs) gets a sanitized issue draft (paths, foreign URLs, emails, IPs, tokens, env assignments and foreign package scopes are redacted, and the redactions are listed) with a prefilled link to the new "AI report" issue form and agh issue createcommand. It never posts.bunx @codeatlasdev/ui workaroundslists the// ca-ui-workaround(#<n>): <why>markers an agent left in your code and which issues are already closed (read-only, offline-safe, exit 0). - 81910d1: Avatar renders the photo as a real
<img>(no detachedImage()probe, so no double download) and passesloading,referrerpolicyandcrossoriginthrough, soloading="lazy"keeps a 200-row list from firing 200 requests andreferrerpolicy="no-referrer"works with CDNs that reject a cross-originReferer.fallbacknow also takes a snippet (an icon for groups, channels and bots), andonerrorfires when the image fails so you can refetch a signed URL. The fallback is always rendered beneath the image, so the box never changes size. Thedata-statusattribute on.ca-avataris gone. - 80c0336:
Cardhas apaddingprop ('none' | 'sm' | 'md' | 'lg', any CSS length, or a number of pixels) so a one-off density no longer needs an inner wrapper;flushstays as the alias of'none'. The docs now say that Card's content is already padded, and in development a[ca-ui]warning (card-double-padding) fires once when the first child adds its own padding on top of the card's (the 20px + 20px = 40px "oversized card"). - cd655bb: Chat primitives:
MessageBubble(direction, grouped tails, sender and avatar slot, quote, reactions, delivery ticks),ConversationItem(inbox row with unread, pinned, muted, typing, active),AudioPlayer(lazy src, waveform frompeaks, slider semantics, playback rate),MediaGrid(image, video and document tiles opening aLightboxgallery) andVirtualList(windowing plus load-older at the top that keeps the scroll position). Newchat,audioPlayer,mediaGridandvirtualListmessages in en and pt-BR. - 80c0336:
CopyButtontakesaria-labelfor the icon-only form (label=""), so each row of a list or table can announce its own name ("Copy client_id of Acme") instead of the same localized "Copy". The default stays the i18ncopyButton.label. The label is ignored whenlabelis visible, so the accessible name keeps containing the visible text. Remaining attributes (data-*,id,aria-describedby, …) are now forwarded to the underlying button. - 6e08799: Every numbered demo now has a reviewed
<Variant>.meta.jsonsidecar (summary,use,spec,tags,shape), soget_demo,search_demosand/api/v1/en/{e,p}/NNN.txtreturn what the demo shows, when to use it and a Spec list of its literal values (props, snippets, state, counts). The catalog check (manifest --check, run by every build) now fails on a demo without a sidecar, a sidecar without a demo, an unknown key, a badshape, or a spec line that quotes a token that is not in the demo source. Newcodeatlas-ui pick [ids...]opens the gallery, listens on127.0.0.1with a random per-run token and prints the ids you send with "Send to AI" (#005 #012). - d99cead:
codeatlas-ui initscaffolds SEO and PWA on SvelteKit (#205): prerenderedmanifest.webmanifest,robots.txtandsitemap.xmlroutes built with theseohelpers, a service worker (src/service-worker/index.tson$app/service-worker,$app/manifestand$app/envfor Kit 3;src/service-worker.tson$service-workerfor Kit 2) with a prerendered/offlinepage, and a default<Seo>with canonical and manifest link in the root layout. Existing files are never overwritten; after creating theminitreminds the app to setpaths.origin(otherwise Kit's prerender placeholder origin reaches the sitemap and canonical URLs), add the icons and excludesrc/service-workerfromtsconfig.jsonon Kit 3. - d99cead: New
InstallPrompt(#208): a dismissible banner that offers to install the app. On Chromium it keepsbeforeinstallprompt(no browser mini-infobar) and shows an Install button that opens the native dialog and reports the choice withonchoice; on iOS Safari and iPadOS, which have no install API, it shows the Share, Add to Home Screen steps. It renders nothing when the app already runs standalone, and stays hidden fordismissDays(default 14) after the user closes it. Strings are in theinstallPrompti18n group (en,pt-BR); theroot: Button onlysize budget rises by 240 B gzip because both catalogs ship with every root import. - 81910d1: Lightbox opens videos and galleries.
items({ type?: 'image' | 'video', src, alt?, caption?, meta?, poster?, download? }, exported asLightboxItem) plus a bindableindexadd previous/next buttons, ArrowLeft/ArrowRight and swipe (no wrap; the end buttons arearia-disabledso focus stays put), a counter, caption and sender/time line, video with controls (paused when you move on), and a Download button (ondownloador a plain<a download>).src/altstill work as a single-item shortcut. Newlightbox.previous,next,downloadandcounterlabels in en and pt-BR; the close button moved into a.ca-lightbox__toolsbar. - 3180023: Leading icon slot for
DropdownMenuItemandTabsTrigger, and a documented pattern for brand logos (#194).iconis a snippet rendered in a fixed 14px box with the standard gap andaria-hidden(the label stays the accessible name), so icon size and alignment no longer drift between menus.brandIconmarks the icon as a fixed-color brand mark: no highlighted, disabled, active or destructive color reaches it (trademark guidelines forbid recoloring). NewSchemeAssettakeslightanddarksnippets and shows the one for the kit's color scheme (.darkon<html>or adata-theme-scopeisland) with CSS only, so it is right in SSR and on first paint and apps no longer read the theme store for logo variants. New classes:.ca-dropdown-item__icon,.ca-tabs-trigger__icon,.ca-scheme-asset,.ca-scheme-asset__light,.ca-scheme-asset__dark. - 7a112eb: Navigation:
LoadingBoundarywraps<svelte:boundary pending>with a 200 ms delay and 500 ms minimum so a loading UI never flashes (default placeholder isSkeletonrows,aria-busy, named region).@codeatlasdev/ui/kitgainsNavigationProgress(top bar driven bynavigatingfrom$app/state) and thependingLink()attachment that setsdata-pendingon the link being navigated to. A test now proves AppShell stays mounted across 10 client-side navigations. - df50d86: New
RecordList,RecordRowandRecordCell: records as dense rows (identity, a few columns, a row menu) that re-flow to a compact two-line row on a phone. The list owns the flush container, the separators, onecolumnstemplate shared by the header and every row, the re-flow (a container query on the list's own width, 36rem), the 44px actions cell and anaria-hiddenheader whose labels become per-celldtwhen stacked. It replaces the hand-rolled flushCard+ grid +:globalrow CSS, and is much shorter on a phone thanTable responsive="cards". - d99cead:
<Seo>completes the social and language tags (#207):og.defaultImageis the site-wide card used when a page has noog.image(also feedstwitter:imageand thesummary_large_imagecard),twitter:titleandtwitter:descriptionmirror the page title and description, and the newlangprop setsog:localeand keeps<html lang>in sync on the client. - 81910d1:
skeletonprop onAvatar,KpiCard,TextField,Table,CardandGlassCard: the component keeps its real DOM, so the placeholder has exactly the loaded size (no layout shift). Content is laid out but hidden, the host paints the same shimmer as<Skeleton>, and it is announced witharia-busy="true"; a skeletonTextFieldis disabled and anAvatarmakes no image request. Reduced motion stops the sweep and forced colors draw an outline. New global[data-skeleton]rule andca-shimmerkeyframes inutilities.css. - f889334: Every backdrop blur now comes from one place. Components no longer declare
backdrop-filter: they setdata-ca-blur="<role>"(or are a.ca-surface) andstyles/surface.csspaints it from the tokens<html data-style>rewrites, so one attribute turns every blur off or down together. The look is unchanged (guarded by a computed-style test over 9 styles, light and dark).FloatingLayergains ablurprop (overlayortooltip).lint:tokensrejectsbackdrop-filteroutsidesurface.cssandmaterials.css. The MCP server gainslist_surfaces, generated from the[data-style]selectors inmaterials.css, anddist/surfaces.jsonships with the package. - 3180023:
TabsListhandles its own overflow (#190). It keeps the width of its tabs insideTabs(no more full-column pill on desktop), and when the tabs do not fit it scrolls sideways on its own with the scrollbar hidden and scroll snapping, instead of wrapping or widening the page on a phone. The selected tab is scrolled into view on mount and when it changes (only the strip scrolls, never the page). New optionalfadeprop masks the edge that still hides tabs, like theAppSettingsnav. The wrapperdivwithoverflow-x: autoand the:global(.ca-tabs-list) { width: max-content }workaround can be deleted.
Patch Changes
- 526fee2: A menu, Select list, popover or tooltip that is already open when a Dialog, Sheet or Drawer opens (a shortcut or an async action opening the modal over it) now moves into that modal and stays clickable and above it. Before, it stayed outside the modal, so it went inert and could not be used. When a modal closes before the popovers hosted in it, they are handed to the next modal or put back where they were declared instead of being removed with it. The layer stack and the stacking contract are covered by new tests and documented on the Dialog page (#225).
- 3afd417: Overlays return focus to the control that opened them on iPhone/iPad and Safari too. WebKit does not focus a tapped button (it focuses a focusable ancestor such as
<main tabindex="-1">, or nothing), so focus used to land there on close and VoiceOver users lost their place. CommandPalette: Mod+K focuses the search field on touch devices with a keyboard (covered by a test now). - c76c837: New guide
getting-started/migrate-react, readable offline through the MCPget_guide("migrate-react")and on the docs site: decision flow (incremental or rewrite), React hook to Svelte 5 rune map with the effect pitfalls, MUI / shadcn-Radix / Chakra to@codeatlasdev/uicomponent maps, layout templates, theme mapping, TanStack Table to@codeatlasdev/ui/table, and how to report a gap (report_issuekindmigration-gapplus aca-ui-workaroundmarker). A unit test fails when a component named in the maps stops being an export. - d99cead: The manifest
generateBrand/caBrandPluginwrite is installable:display: "standalone"(was"browser"),idandscopeset to"/", andtheme_color/background_colortaken from the theme's default scheme instead of always the light one (#206). The icon hash now includes the default scheme, so switching it renames the files. - 81910d1: Skeleton's shimmer is a translated
::afterband instead of an animatedbackground-position, so it no longer repaints on every frame. Reduced motion still gets a static, dimmed placeholder. - 9c9df3b:
@codeatlasdev/ui/viteis safe in the SSR graph: importingdesignStyle,mergeThemeorThemeOptionsfrom atheme.tsthathooks.server.tsshares no longer fails the SvelteKit server build withUNLOADABLE_DEPENDENCYon@resvg/resvg-js(#184). The native peers are loaded by name at run time andcaBrandPluginmarks themssr.external, so thessr.externalworkaround is no longer needed.runBrandandbrandUrlsare now exported from@codeatlasdev/ui/vite, as the 4.0.0 changelog announced (#185).
Install
bun add @codeatlasdev/ui@4.2.0Special thanks
To our main supporters and special contributors, Fábio Henrique Araújo (@FabioHAraujo) and Richardson Douglas (@Richards0nd). 💛