# gnome-ui complete documentation > Consolidated, LLM-friendly documentation for gnome-ui. Generated from the repository's authoritative Markdown sources; do not edit this file directly. Use public imports from the documented npm packages. Roadmap items are not released APIs. For a compact index, use https://gnome-ui.org/llms.txt. --- Source: README.md # gnome-ui A React component library that faithfully implements the [GNOME Human Interface Guidelines](https://developer.gnome.org/hig/), built on top of the [Adwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/) design language. [![npm](https://img.shields.io/npm/v/@gnome-ui/react)](https://www.npmjs.com/package/@gnome-ui/react) [![CI](https://github.com/eljijuna/gnome-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/eljijuna/gnome-ui/actions/workflows/ci.yml) [![Docs](https://img.shields.io/badge/gnome--ui-docs-3584e4)](https://gnome-ui.org/) [![Storybook](https://img.shields.io/badge/Storybook-live-ff4785?logo=storybook&logoColor=white)](https://gnome-ui.org/react/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/ElJijuna/gnome-ui/blob/main/LICENSE) Read the guides, architecture, design guidelines, roadmap, and changelog at **[gnome-ui.org](https://gnome-ui.org/)** — and browse every component live, with real interactive previews, in each package's own Storybook (linked throughout, and per-row in the tables below). ## Packages | Package | Description | Version | |---------|-------------|---------| | [`@gnome-ui/core`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/core) | Framework-agnostic design tokens (CSS custom properties) | [![npm](https://img.shields.io/npm/v/@gnome-ui/core)](https://www.npmjs.com/package/@gnome-ui/core) | | [`@gnome-ui/icons`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/icons) | Framework-agnostic Adwaita symbolic icon definitions (SVG path data) | [![npm](https://img.shields.io/npm/v/@gnome-ui/icons)](https://www.npmjs.com/package/@gnome-ui/icons) | | [`@gnome-ui/react`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/react) | React component library | [![npm](https://img.shields.io/npm/v/@gnome-ui/react)](https://www.npmjs.com/package/@gnome-ui/react) | | [`@gnome-ui/layout`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/layout) | Full-page application shell and dashboard components | [![npm](https://img.shields.io/npm/v/@gnome-ui/layout)](https://www.npmjs.com/package/@gnome-ui/layout) | | [`@gnome-ui/platform`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/platform) | TypeScript bridge to GNOME host APIs (GSettings, portals, notifications…) | [![npm](https://img.shields.io/npm/v/@gnome-ui/platform)](https://www.npmjs.com/package/@gnome-ui/platform) | | [`@gnome-ui/hooks`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/hooks) | React hooks that surface `@gnome-ui/platform` APIs as idiomatic React state | [![npm](https://img.shields.io/npm/v/@gnome-ui/hooks)](https://www.npmjs.com/package/@gnome-ui/hooks) | | [`@gnome-ui/charts`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/charts) | Data visualisation components (Line, Bar, Area) styled with Adwaita tokens | [![npm](https://img.shields.io/npm/v/@gnome-ui/charts)](https://www.npmjs.com/package/@gnome-ui/charts) | | [`@gnome-ui/react-native`](https://github.com/ElJijuna/gnome-ui/tree/main/packages/react-native) | React Native components for iOS/Android/GNOME-mobile | [![npm](https://img.shields.io/npm/v/@gnome-ui/react-native)](https://www.npmjs.com/package/@gnome-ui/react-native) | ## Quick start ```bash npm install @gnome-ui/react ``` ```tsx import { Button } from "@gnome-ui/react"; import "@gnome-ui/react/styles"; export default function App() { return ( ); } ``` ### Locale & number formatting Wrap your app in `GnomeProvider` to share locale, text direction, and default `Intl` options across `@gnome-ui/react`, `@gnome-ui/layout`, and `@gnome-ui/charts`. ```tsx import { GnomeProvider } from "@gnome-ui/react"; ``` Compact notation renders values like `1K`; standard notation renders values like `1,000`. > **Tokens only** (framework-agnostic): > ```bash > npm install @gnome-ui/core > ``` > ```css > @import "@gnome-ui/core/styles"; > ``` ## Components Live examples and documentation: **[Storybook →](https://gnome-ui.org/react/)** AI assistants and coding agents can use [`llms.txt`](https://gnome-ui.org/llms.txt) for a compact documentation index or [`llms-full.txt`](https://gnome-ui.org/llms-full.txt) for complete context. The **React Native** and **Web Components** columns show each component's port status in [`@gnome-ui/react-native`](https://github.com/ElJijuna/gnome-ui/blob/main/packages/react-native/ROADMAP.md) and [`@gnome-ui/web-components`](https://github.com/ElJijuna/gnome-ui/blob/main/packages/web-components/ROADMAP.md): ✅ shipped · 🚧 in progress · ⬜ planned · 🚫 not planned · — not tracked there (see that package's own `ROADMAP.md` for why — usually a domain-specific or React-only component with no cross-platform target). Generated by [`scripts/generate-component-tables.mjs`](https://github.com/ElJijuna/gnome-ui/blob/main/scripts/generate-component-tables.mjs) from those two files — edit them, not this table, then run `npm run tables:generate`. | Component | Description | React Native | Web Components | Story | |-----------|-------------|:------------:|:---------------:|-------| | `AboutDialog` | Standard app info dialog with details, credits, and legal tabs. Mirrors `AdwAboutDialog`. | 🚫 | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-aboutdialog--docs) | | `ActionRow` | Standard settings row with title, optional subtitle, leading icon, and trailing widget. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-actionrow--docs) | | `AffectedPackage` | | — | — | [Docs](https://gnome-ui.org/react/) | | `AnimatedIcon` | Plays the CSS animation embedded in an `animated` icon from [`@gnome-ui/icons`](https://www.npmjs.com/package/@gnome-ui/icons) — `Syncing`, `Recording`, `Downloading`, `Connecting`. Rendered through plain `Icon` instead, these show a static frame; `AnimatedIcon` is what turns the animation on. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-animatedicon--docs) | | `Avatar` | Circular avatar following the Adwaita `AdwAvatar` pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-avatar--docs) | | `AvatarGroup` | Stack of avatars with overflow indicator. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-avatargroup--docs) | | `AvatarRotator` | Single avatar surface that crossfades through multiple image sources. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-avatarrotator--docs) | | `Badge` | Counter or status indicator, optionally overlaid on another element. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-badge--docs) | | `Banner` | Persistent message strip displayed at the top of a view. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-banner--docs) | | `Bin` | Single-child container with no visual styling. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-bin--docs) | | `Blockquote` | Styled pull-quote with semantic `
` markup. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-blockquote--docs) | | `BottomSheet` | Slide-up panel that overlays content from the bottom edge. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-bottomsheet--docs) | | `BoxedList` | Rounded bordered list — the most common container pattern in GNOME settings and detail views. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-boxedlist--docs) | | `BreakpointBin` | Container that fires layout changes when **its own width** crosses defined thresholds — the CSS container-query equivalent of `AdwBreakpointBin` (libadwaita 1.9 / GNOME 50). | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/adaptive-breakpointbin--docs) | | `Button` | Button component following the [GNOME Human Interface Guidelines](https://developer.gnome.org/hig/patterns/controls/buttons.html). | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-button--docs) | | `ButtonContent` | Icon + label layout helper for buttons that contain both an icon and text. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-buttoncontent--docs) | | `ButtonRow` | Full-width activatable row styled as a button inside a `BoxedList`. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-buttonrow--docs) | | `Calendar` | Month-grid date display with full keyboard navigation — mirrors [`GtkCalendar`](https://gnome.pages.gitlab.gnome.org/gtk/gtk4/class.Calendar.html). Usable standalone (settings, forms) or as the panel inside a `DatePicker`. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-calendar--docs) | | `CalendarRange` | Start/end date-range selection driving the same grid engine as `Calendar` — roving `tabindex`, month/year drill-down, `min`/`max`, week numbers, localisation. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-calendarrange--docs) | | `Callout` | Inline, dismissible admonition box for contextual help text within forms and cards. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-callout--docs) | | `Card` | Card component following the [GNOME HIG containers](https://developer.gnome.org/hig/patterns/containers.html) and the Adwaita `.card` style class. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-card--docs) | | `Carousel` | Swipeable content carousel. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-carousel--docs) | | `Checkbox` | Checkbox for multi-selection, following the GNOME HIG and Adwaita style. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-checkbox--docs) | | `CheckRow` | Activatable row with an integrated checkbox. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-checkrow--docs) | | `Chip` | Compact pill-shaped label for tags, filters, and selection states. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-chip--docs) | | `ChoiceCardGroup` | Card-based single-choice selector — large selectable cards instead of radio buttons. | ⬜ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-choicecardgroup--docs) | | `Clamp` | Constrains its child to a maximum width while allowing it to shrink freely on narrow screens — mirroring the Adwaita `AdwClamp` widget. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/adaptive-clamp--docs) | | `CoachMark` | Onboarding **feature-discovery** pattern: spotlight a UI element and anchor a callout bubble (title, description, actions) beside it to teach a user one feature. Compose several with `CoachMarkTour`, or drive a single mark with `open`. | ✅ | — | [Docs](https://gnome-ui.org/react/) | | `CodeBlock` | Static monospace code/config snippet display with optional line numbers and a trailing `CopyButton`. | ⬜ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-codeblock--docs) | | `ColorPicker` | Color palette picker following the Adwaita `GtkColorButton` + swatch pattern. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-colorpicker--docs) | | `ColumnView` | Multi-column sortable data table styled with Adwaita design tokens. | 🚫 | — | [Docs](https://gnome-ui.org/react/?path=/docs/data-display-columnview--docs) | | `ComboRow` | Settings row with an inline combo selector at the trailing edge. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-comborow--docs) | | `ContributionGraph` | A responsive activity heatmap calendar styled with Adwaita design tokens. Colour intensity represents activity count per day. | 🚫 | — | [Docs](https://gnome-ui.org/react/?path=/docs/data-display-contributiongraph--docs) | | `CopyButton` | Icon button that copies a value to the clipboard, swapping to a checkmark and a "Copied!" tooltip as confirmation. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-copybutton--docs) | | `CopyField` | Read-only `TextField` with a built-in trailing `CopyButton`, for displaying copyable values (API keys, tokens, IDs) outside the `CveIdentifier`/`CweIdentifier`-style specialised components. | ⬜ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-copyfield--docs) | | `CountDownTimer` | Displays a countdown timer showing the remaining time until a specified end date. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-countdowntimer--docs) | | `CveIdentifier` | Monospace CVE identifier for vulnerability tables, findings, and report references. | — | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-cveidentifier--docs) | | `CvssScore` | Compact CVSS score display for vulnerability tables, finding summaries, and CVE detail surfaces. | — | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-cvssscore--docs) | | `CvssVector` | | — | — | [Docs](https://gnome-ui.org/react/) | | `CweIdentifier` | | — | — | [Docs](https://gnome-ui.org/react/) | | `DatePicker` | A [`Popover`](../Popover)-anchored [`Calendar`](../Calendar) behind an entry-styled trigger — mirrors the `GtkCalendar` + `GtkPopover` composition GNOME apps use for date entry. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-datepicker--docs) | | `DateRangePicker` | A [`Popover`](../Popover)-anchored [`CalendarRange`](../CalendarRange) behind an entry-styled trigger — the range counterpart of `DatePicker`, and the same `GtkCalendar` + `GtkPopover` composition GNOME apps use for date entry. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-daterangepicker--docs) | | `Dialog` | Blocking modal dialog — two modes in one component. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-dialog--docs) | | `Divider` | Horizontal rule with an optional centred label — common auth/login-form pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-divider--docs) | | `Drawer` | Slide-over panel for supplementary React content. Use `side` to open from the left or right, `size` for classic or wide widths, and pass the body through `children` or the `content` prop. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-drawer--docs) | | `Dropdown` | Expandable option list following the Adwaita combo-row / drop-down style. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-dropdown--docs) | | `EmojiPicker` | Searchable emoji grid in a `Popover`. Mirrors `GtkEmojiChooser`. | ⬜ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-emojipicker--docs) | | `EntryRow` | Row with an inline text entry field. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-entryrow--docs) | | `Expander` | Standalone disclosure triangle + collapsible content — mirrors `GtkExpander`. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-expander--docs) | | `ExpanderRow` | Collapsible `ActionRow` that reveals nested rows on activation. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-expanderrow--docs) | | `FieldGroup` | Generic form-field grouping with a shared label, help text, and error message, for arbitrary fields outside a `BoxedList`. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-fieldgroup--docs) | | `FileDropZone` | Drag-and-drop file upload target with hover/active states, falling back to a `GtkFileDialog`-style click-to-browse trigger. | ⬜ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-filedropzone--docs) | | `FileTypeIcon` | Small icon — optionally a thumbnail — resolved from a file's MIME type or name extension. Useful for file-manager-style listings. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-filetypeicon--docs) | | `FilterableMultiSelectDropdown` | `MultiSelectDropdown` plus a filter field for narrowing long option lists. | — | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-filterablemultiselectdropdown--docs) | | `FontPicker` | Button that opens a family/size/weight chooser. Mirrors `GtkFontDialogButton`: the trigger itself previews the current selection rendered in that font. | ⬜ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-fontpicker--docs) | | `Footer` | Bottom bar with leading/trailing slots and optional center content. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-footer--docs) | | `Frame` | Simple bordered surface with `border-radius` but no background fill. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-frame--docs) | | `HeaderBar` | Title bar with centered title and leading/trailing action slots. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-headerbar--docs) | | `Highlight` | Wraps every occurrence of `query` within `text` in a `` element. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-highlight--docs) | | `Icon` | Renders an [`@gnome-ui/icons`](https://www.npmjs.com/package/@gnome-ui/icons) definition as an inline SVG. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-icon--docs) | | `IconButton` | Icon-only action button composed from `Button`, `Icon`, and optionally `Tooltip`. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-iconbutton--docs) | | `InlineViewSwitcher` | Compact inline view switcher for placing inside content areas, cards, or toolbars. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-inlineviewswitcher--docs) | | `Kbd` | Standalone single key-cap for inline instructional text. | 🚫 | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-kbd--docs) | | `LevelBar` | Discrete level indicator with colour-coded low/high offset zones — mirrors `GtkLevelBar`. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-levelbar--docs) | | `Link` | Inline hyperlink following GNOME HIG. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-link--docs) | | `LinkedGroup` | Renders children as a single visually-connected unit with no gap and merged borders. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-linkedgroup--docs) | | `Modal` | | — | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-modal--docs) | | `MultiSelectDropdown` | Checkbox-list variant of `Dropdown` for selecting multiple values from a single trigger. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-multiselectdropdown--docs) | | `NavigationSplitView` | Two-pane sidebar + content layout that collapses to a single navigable pane on narrow screens (≤ 400 px), mirroring `AdwNavigationSplitView`. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/adaptive-navigationsplitview--docs) | | `NavigationView` | Single-pane push/pop navigation stack. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-navigationview--docs) | | `OtpInput` | Segmented PIN/verification-code input — one cell per digit, with auto-advance on typing, backspace-to-previous-cell, and paste support. | ⬜ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-otpinput--docs) | | `Overlay` | Standalone backdrop/scrim layer with a fade transition and click-to-dismiss — the shared building block behind `Modal`, `Dialog`, and `BottomSheet`'s backdrops, extracted for building custom overlay UI. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-overlay--docs) | | `OverlaySplitView` | Sidebar + content layout where the sidebar becomes a slide-over **overlay** on narrow screens (≤ 400 px), mirroring `AdwOverlaySplitView`. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/adaptive-overlaysplitview--docs) | | `PasswordEntryRow` | Password entry row with a built-in reveal/conceal toggle. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-passwordentryrow--docs) | | `PasswordField` | Single-line password input with a peek toggle that reveals the value as plain text. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-passwordfield--docs) | | `PathBar` | Breadcrumb path bar for navigating a hierarchical location. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-pathbar--docs) | | `Popover` | Floating panel anchored to a trigger element, following the Adwaita `GtkPopover` pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-popover--docs) | | `Portal` | Reusable `createPortal` wrapper — SSR-safe (renders `children` inline when `document` is unavailable) with optional mount-target support. | 🚫 | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-portal--docs) | | `PreferencesDialog` | Multi-page settings dialog using `PreferencesPage` tabs. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-preferencesdialog--docs) | | `PreferencesGroup` | Titled section that wraps a `BoxedList` with an optional description. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-preferencesgroup--docs) | | `PreferencesPage` | Scrollable page composed of `PreferencesGroup` sections. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-preferencespage--docs) | | `ProgressBar` | Determinate and indeterminate progress bar following the Adwaita style. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-progressbar--docs) | | `RadioButton` | Single-selection radio button following the GNOME HIG and Adwaita style. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-radiobutton--docs) | | `RangeSlider` | Dual-thumb slider for selecting a min/max range, following the Adwaita `GtkScale` pattern used by `Slider`. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-rangeslider--docs) | | `RatingStars` | Star rating display and input. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-ratingstars--docs) | | `ScrollToTop` | Fixed-position button that scrolls the page to the top on click, following the GNOME Human Interface Guidelines. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-scrolltotop--docs) | | `SearchBar` | Collapsible search bar following the Adwaita `AdwSearchBar` pattern. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-searchbar--docs) | | `SecurityMetric` | | — | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-securitymetric--docs) | | `SegmentedBar` | Horizontal bar split into proportional segments, one per category. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-segmentedbar--docs) | | `Separator` | Thin dividing line that separates groups of content. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-separator--docs) | | `SeverityBadge` | Pill-shaped label for vulnerability severities in security reports, CVE tables, dashboards, and scanner results. | — | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-severitybadge--docs) | | `ShortcutLabel` | Read-only display of a keyboard shortcut with per-key key-cap styling. | 🚫 | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-shortcutlabel--docs) | | `ShortcutsDialog` | Modal dialog listing keyboard shortcuts grouped in sections, with integrated search. | 🚫 | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-shortcutsdialog--docs) | | `Sidebar` | Lateral navigation panel following the Adwaita `.navigation-sidebar` pattern. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-sidebar--docs) | | `Skeleton` | Content-shaped loading placeholder for skeleton screens. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-skeleton--docs) | | `Slider` | Draggable range control following the Adwaita `GtkScale` pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-slider--docs) | | `SpinButton` | Numeric input with − and + buttons following the Adwaita `GtkSpinButton` style. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-spinbutton--docs) | | `Spinner` | Indeterminate loading indicator following the Adwaita spinner style. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-spinner--docs) | | `SpinRow` | Settings row with an integrated spin button for numeric values. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-spinrow--docs) | | `SplitButton` | Primary action button with an attached dropdown arrow. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-splitbutton--docs) | | `StatusBadge` | Pill-shaped text label for entity status. Use for human-readable state labels like `published`, `beta`, or `new` — not for numeric counts (use `Badge` for those). | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-statusbadge--docs) | | `StatusPage` | Empty-state and status page following the Adwaita `AdwStatusPage` pattern. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-statuspage--docs) | | `StepIndicator` | Numbered "Step X of Y" progress indicator for onboarding/wizard flows. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-stepindicator--docs) | | `Switch` | On/off toggle following the Adwaita switch style. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-switch--docs) | | `SwitchRow` | Activatable row with an integrated switch. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-switchrow--docs) | | `Tabs` | Tab-based navigation following the Adwaita `AdwTabBar` pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-tabs--docs) | | `TagInput` | Type-to-add multi-value input rendering entries as removable `Chip`s in a `WrapBox`. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-taginput--docs) | | `TerminalView` | Scrollable terminal-style output area styled after GNOME Terminal. Intended for displaying logs, command output, or read-only text content. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-terminalview--docs) | | `Text` | Typography component mirroring all [Adwaita text style classes](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/style-classes.html). | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-text--docs) | | `TextField` | Single-line text input with label, helper text, and error state. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-textfield--docs) | | `TextTruncate` | Single/multi-line text truncation with an automatic tooltip revealing the full content on overflow — mirrors `GtkLabel`'s `ellipsize` property. | ⬜ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-texttruncate--docs) | | `Timeline` | Ordered sequence of events connected by a visual timeline. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-timeline--docs) | | `TimePicker` | Hour/minute selection built from paired [`SpinButton`](../SpinButton)s inside a [`Popover`](../Popover), behind an entry-styled trigger — mirrors the `GtkSpinButton` + `GtkPopover` composition GNOME apps use for time entry, with 12- and 24-hour support. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-timepicker--docs) | | `Toast` | Non-blocking temporary notification following the Adwaita `AdwToast` pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-toast--docs) | | `ToggleGroup` | Mutually-exclusive group of toggle buttons for in-place option selection. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-togglegroup--docs) | | `Toolbar` | Horizontal action bar following the libadwaita `.toolbar` pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-spacer--docs) | | `ToolbarView` | Layout container that attaches bars at the top and/or bottom while scrolling only the middle content. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-toolbarview--docs) | | `Tooltip` | Informational floating label following the GNOME HIG tooltip pattern. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-tooltip--docs) | | `ViewSwitcher` | Segmented control for switching between major views, mirroring the Adwaita `AdwViewSwitcher`. | ✅ | ✅ | [Docs](https://gnome-ui.org/react/?path=/docs/components-viewswitcher--docs) | | `ViewSwitcherBar` | Bottom navigation bar for `ViewSwitcher` items on narrow screens (≤ 550 px), mirroring `AdwViewSwitcherBar`. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/adaptive-viewswitcherbar--docs) | | `ViewSwitcherSidebar` | Sidebar-style view switcher for apps with many top-level views or when the sidebar layout fits better than a header-bar `ViewSwitcher`. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-viewswitchersidebar--docs) | | `VisuallyHidden` | Reusable "sr-only" utility — visually hides content while keeping it in the accessibility tree, so screen readers still announce it. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-visuallyhidden--docs) | | `VulnerabilityFinding` | | — | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-vulnerabilityfinding--docs) | | `VulnerabilitySummary` | | — | — | [Docs](https://gnome-ui.org/react/) | | `WidgetManager` | Card that manages a controlled collection of "widgets" picked from a `catalog`, each rendering its own content via `render()`. The header's edit button toggles a dashed "add widget" trigger that opens a catalog picker — `Modal`, `BottomSheet`, or `Drawer`, chosen with `pickerSurface`. Adding and removing is staged inside the picker and only applied through `onChange` when the user confirms; canceling discards the staging. Widgets can only be removed through the picker, not inline in the card. | ✅ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-widgetmanager--docs) | | `WindowTitle` | Two-line title + subtitle widget for use inside a `HeaderBar`. | ⬜ | — | [Docs](https://gnome-ui.org/react/?path=/docs/components-windowtitle--docs) | | `WrapBox` | Flexible wrapping layout container. | ✅ | ⬜ | [Docs](https://gnome-ui.org/react/?path=/docs/components-wrapbox--docs) | ### Layout shells & dashboard (`@gnome-ui/layout`) Live examples and documentation: **[Storybook →](https://gnome-ui.org/layout/)** | Component | Description | Story | |-----------|-------------|-------| | `ActivityFeed` | Chronological list of recent events with relative timestamps, optional icons, skeleton loading state, and a "Show more" affordance. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-activityfeed--docs) | | `AdaptiveLayout` | Full-page adaptive shell that switches navigation automatically based on viewport width. Use the **viewport toolbar** to preview each breakpoint: | [Docs](https://gnome-ui.org/layout/?path=/docs/adaptive-adaptivelayout--docs) | | `AppHeader` | GNOME application header with named shell slots. | [Docs](https://gnome-ui.org/layout/) | | `ApplicationCard` | App detail header with avatar, name, badge, description, stat row, and actions. Designed for the MyApps `AppDetail` view — use `EntityCard` for list rows. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-applicationcard--docs) | | `Banner` | Persistent in-app message strip shown at the top of a view, following GNOME HIG banner guidelines. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-banner--docs) | | `ChartCard` | | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-chartcard--docs) | | `CounterCard` | Metric card with an animated numeric counter. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-countercard--docs) | | `DashboardGrid` | Responsive 12-column grid container for dashboard widgets and panels. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-dashboardgrid--docs) | | `EmptyState` | Centered empty-state illustration for views with no data. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-emptystate--docs) | | `EntityCard` | Avatar/icon + title + meta card. Covers both compact grid cards (Following screen) and full-width list rows (MyApps screen) via additive optional props. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-entitycard--docs) | | `ErrorState` | Error state with four presets that set a default icon and title. All defaults can be overridden via `icon` and `title` props. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-errorstate--docs) | | `FileManager` | GNOME Files (Nautilus)–style file browser assembled from **`@gnome-ui/layout`** and **`@gnome-ui/react`** components. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-filemanager--docs) | | `IconBadge` | Rounded-square tinted icon container. Accepts the seven gnome-ui named colors or any hex value (`#rgb` / `#rrggbb`). In both cases the background is rendered at 15% opacity via `color-mix`. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-iconbadge--docs) | | `Layout` | Full-page application shell from **`@gnome-ui/layout`** that composes four named zones following the GNOME Human Interface Guidelines. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-layout--docs) | | `LoadingStatus` | Visually hidden live region announcing a skeleton loading state to screen readers. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-loadingstatus--docs) | | `MasonryGrid` | Masonry layout that distributes variable-height items across columns using a **shortest-column-first** algorithm — each new item is placed in the column with the least accumulated height, minimising gaps. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-masonrygrid--docs) | | `PageContent` | Page content container with GNOME spacing and optional width clamping. | [Docs](https://gnome-ui.org/layout/) | | `PanelCard` | Card with a structured **header / body / footer** layout and built-in collapse/expand behaviour. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-panelcard--docs) | | `ProfileCard` | Dashboard card for displaying a user profile — avatar, name, handle, optional status dot, optional stats row, and an optional decorative background chart. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-profilecard--docs) | | `ProgressCard` | Resource usage card with a labeled progress bar. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-progresscard--docs) | | `QuickActions` | Grid of shortcut action buttons for dashboards, file managers, and control panels. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-quickactions--docs) | | `ResizablePanel` | Two or more panels separated by a draggable divider, based on the `GtkPaned` pattern. Foundational for user-resizable master-detail layouts (code editors, file explorers, analytics dashboards). | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-resizablepanel--docs) | | `SectionHeader` | Title row for dashboard sections with optional subtitle and trailing action slot. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-sectionheader--docs) | | `Settings` | GNOME Settings–style preferences app assembled from **`@gnome-ui/layout`** and **`@gnome-ui/react`**. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-settings--docs) | | `SidebarShell` | Full-height GNOME sidebar with fixed header/footer and scrollable navigation area. | [Docs](https://gnome-ui.org/layout/) | | `SidebarTrigger` | Header button that opens overlay sidebars on narrow screens and toggles rail collapse on wider screens. | [Docs](https://gnome-ui.org/layout/) | | `SplitLayout` | List/master + detail shell following the Adwaita `AdwNavigationSplitView` pattern, with a `HeaderBar` for each pane — the way real Adwaita apps (Settings, Files, Contacts) actually look, rather than the bare pane-toggle mechanics of `@gnome-ui/react`'s `NavigationSplitView` that this composes. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-splitlayout--docs) | | `StatCard` | Metric card for dashboards with optional unit, trend indicator, icon, background chart, and loading state. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-statcard--docs) | | `StatusBar` | Compact footer/status bar for application shells. | [Docs](https://gnome-ui.org/layout/) | | `StatusIndicator` | Status dot for communicating the health of a service, connection, or resource. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-statusindicator--docs) | | `StickyToc` | Sticky table-of-contents side rail with scroll-spy: the link for the section currently nearest the top of the viewport is highlighted automatically as the user scrolls. For long docs/settings pages. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-stickytoc--docs) | | `TeamCard` | Group identity card: avatar group, team name, and member count. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-teamcard--docs) | | `Toast` | In-app notifications following the GNOME Human Interface Guidelines. | [Docs](https://gnome-ui.org/layout/) | | `UserCard` | User identity panel for popovers, sidebar footers, and profile pages. | [Docs](https://gnome-ui.org/layout/?path=/docs/layout-usercard--docs) | ### Data visualization (`@gnome-ui/charts`) Live examples and documentation: **[Storybook →](https://gnome-ui.org/charts/)** | Component | Description | Story | |-----------|-------------|-------| | `AreaChart` | Area chart built on Recharts with GNOME design tokens, supporting stacked areas and gradient fills. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-areachart--docs) | | `BarChart` | Bar chart built on Recharts with GNOME design tokens for grouped comparisons across categories. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-barchart--docs) | | `BoxPlot` | Box-and-whisker plot built with plain HTML/CSS — no Recharts (it has no native box-plot primitive). Shows the distribution of one or more groups: median, interquartile range (Q1–Q3), whiskers extending to the most extreme non-outlier value, and outliers beyond 1.5×IQR. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-boxplot--docs) | | `BulletChart` | Bullet graph (Stephen Few) built with plain SVG-free HTML — no Recharts. Shows a performance measure against a target and qualitative ranges in a single compact horizontal track, for KPI rows in tables and dashboards where `GaugeChart` takes too much vertical space. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-bulletchart--docs) | | `CloudChart` | Word/tag cloud that scales each term's font size proportionally to its numeric value. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-cloudchart--docs) | | `ComposedChart` | Mixed chart combining bars, lines, and areas on shared axes. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-composedchart--docs) | | `FunnelChart` | Funnel visualization for conversion rates and sales pipelines. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-funnelchart--docs) | | `GaugeChart` | Single-value speedometer gauge built on Recharts. Renders a semicircular arc between `min` and `max`, with the current value shown as a label at its center — for KPI dashboards, alongside `StatCard` from `@gnome-ui/layout`. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-gaugechart--docs) | | `Heatmap` | Generic matrix heatmap built in pure CSS/SVG (no Recharts dependency) — for correlation matrices, density grids, or any row × column value grid. For a calendar-shaped activity heatmap, use `ContributionGraph` from `@gnome-ui/react` instead. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-heatmap--docs) | | `LineChart` | Line chart built on Recharts with GNOME design tokens for axes, grid, and tooltips. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-linechart--docs) | | `PieChart` | Pie and donut chart built on Recharts for part-to-whole comparisons. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-piechart--docs) | | `RadarChart` | Radar (spider) chart built on Recharts for comparing multiple attributes across one or more subjects. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-radarchart--docs) | | `RadialBarChart` | Radial bar chart built on Recharts. Each data item renders as a circular arc, useful for showing multiple metrics as circular progress rings. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-radialbarchart--docs) | | `SankeyChart` | Flow diagram built on Recharts. Renders named nodes as columns of rectangles connected by curved, proportionally-sized links — for multi-stage funnels, user journeys, or any flow between categories. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-sankeychart--docs) | | `ScatterChart` | Scatter and bubble chart for visualizing correlation between two numeric variables. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-scatterchart--docs) | | `TreeMap` | Tree map built on Recharts. Displays hierarchical data as nested rectangles; area is proportional to each item's value. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-treemap--docs) | | `WaterfallChart` | Floating-bar chart built on Recharts for the cumulative effect of a sequence of increases and decreases — revenue bridges, budget breakdowns, cohort attrition. Each bar starts where the previous one ended; mark `isTotal` on start/end/subtotal bars to anchor them to zero instead. | [Docs](https://gnome-ui.org/charts/?path=/docs/charts-waterfallchart--docs) | See [ROADMAP.md](https://github.com/ElJijuna/gnome-ui/blob/main/ROADMAP.md) for the full list of planned components. ## Development ### Prerequisites - Node.js 22+ - npm 10+ ### Setup ```bash git clone https://github.com/your-org/gnome-react.git cd gnome-react npm install ``` ### Commands | Command | Description | |---------|-------------| | `npm run build` | Build all packages | | `npm run storybook` | Start Storybook dev server at `localhost:6006` | | `npm run build-storybook` | Build Storybook for production | | `npm run typecheck` | Type-check all packages | | `npm run lint` | Lint all packages | ### Project structure ``` gnome-ui/ ├── packages/ │ ├── core/ # @gnome-ui/core — CSS design tokens │ ├── icons/ # @gnome-ui/icons — Adwaita icon definitions (SVG path data) │ ├── react/ # @gnome-ui/react — React components │ ├── layout/ # @gnome-ui/layout — Application shell & dashboard components │ ├── platform/ # @gnome-ui/platform — GNOME host bridge (GSettings, portals…) │ ├── hooks/ # @gnome-ui/hooks — React hooks for platform APIs │ └── charts/ # @gnome-ui/charts — Adwaita-styled chart components ├── GNOME_GUIDELINES.md ├── ROADMAP.md └── turbo.json ``` ## Contributing Read [CONTRIBUTING.md](https://github.com/ElJijuna/gnome-ui/blob/main/CONTRIBUTING.md) before opening a pull request. This project uses [Conventional Commits](https://www.conventionalcommits.org/). Your commit messages determine the next version automatically via semantic-release: | Prefix | Release | |--------|---------| | `feat:` | minor | | `fix:`, `perf:`, `refactor:` | patch | | `feat!:` or `BREAKING CHANGE:` | major | | `chore:`, `docs:`, `test:` | no release | ## License [MIT](https://github.com/ElJijuna/gnome-ui/blob/main/LICENSE) © el_jijuna --- Source: COMPONENT_INDEX.md # Component Index Snapshot: 2026-06-30. Scope: `@gnome-ui/react`, `@gnome-ui/layout`, `@gnome-ui/charts`. ## Inventory | Package | Public component dirs | Root index | Package subpath exports | Notes | |---------|-----------------------|------------|--------------------------|-------| | `@gnome-ui/react` | 84 | 84 | 84 component paths + 2 provider internals | Full root export parity. Added missing `ScrollToTop` subpath export. | | `@gnome-ui/layout` | 28 | 28 | 28 | Added `ChartCard`; added missing `LoadingStatus` subpath export. | | `@gnome-ui/charts` | 14 | 14 | 14 | Added missing `ComposedChart`, `FunnelChart`, `ScatterChart` subpath exports. | Coverage/doc shape: | Artifact | Count | |----------|-------| | Component `index.ts` files | 126 | | Component READMEs | 123 | | Component stories | 124 | | Component tests | 101 | ## `@gnome-ui/react` Foundation: - Controls: `Button`, `IconButton`, `SplitButton`, `ButtonContent`, `Switch`, `Checkbox`, `RadioButton`, `TextField`, `SpinButton`, `Slider`, `Dropdown`, `SearchBar`, `Link`, `ToggleGroup`, `InlineViewSwitcher`, `PathBar`, `ScrollToTop`. - Display: `Text`, `Icon`, `Avatar`, `AvatarGroup`, `AvatarRotator`, `Badge`, `StatusBadge`, `Blockquote`, `Spinner`, `ProgressBar`, `SegmentedBar`, `Skeleton`, `CountDownTimer`, `StatusPage`, `Separator`, `Chip`, `ShortcutLabel`, `WindowTitle`, `Timeline`, `ContributionGraph`, `TerminalView`. - Layout/containers: `Box`, `Card`, `Frame`, `Bin`, `HeaderBar`, `Toolbar`, `Spacer`, `ToolbarView`, `LinkedGroup`, `Sidebar`, `SidebarSection`, `SidebarItem`, `BoxedList`, `ActionRow`, `ButtonRow`, `ExpanderRow`, `SwitchRow`, `CheckRow`, `ComboRow`, `EntryRow`, `PasswordEntryRow`, `SpinRow`, `WrapBox`, `TabBar`, `TabItem`, `TabPanel`, `ViewSwitcher`, `ViewSwitcherItem`, `ViewSwitcherBar`, `ViewSwitcherSidebar`, `ViewSwitcherSidebarItem`, `Carousel`, `ShortcutsDialog`. - Overlays: `Toast`, `Toaster`, `Dialog`, `Modal`, `BottomSheet`, `Drawer`, `Tooltip`, `Popover`, `Banner`, `AboutDialog`. - Preferences: `PreferencesGroup`, `PreferencesPage`, `PreferencesDialog`. - Adaptive: `useBreakpoint`, `Clamp`, `BreakpointBin`, `NavigationView`, `NavigationPage`, `NavigationSplitView`, `OverlaySplitView`. - Provider: `GnomeProvider`, `useLocale`, `useDir`, `useColorScheme`, `useResolvedColorScheme`, `useAccentColor`, `useNumberFormatter`, `useDateTimeFormatter`. Assessment: - Strong GNOME/libadwaita coverage. Most widget-gallery patterns already exist. - Main risk now: API bloat without composition guidance. New low-level widgets should be rare. - More useful next layer: app workflow components, data density, empty/loading/error consistency. ## `@gnome-ui/layout` Application shell: - `Layout`, `AppHeader`, `PageContent`, `SidebarShell`, `SidebarTrigger`, `StatusBar`, `AdaptiveLayout`. Dashboard/application composition: - `DashboardGrid`, `MasonryGrid`, `PanelCard`, `SectionHeader`, `ActivityFeed`, `QuickActions`, `StatCard`, `CounterCard`, `ProgressCard`, `ChartCard`, `StatusIndicator`, `LoadingStatus`. Entity/state cards: - `ApplicationCard`, `EntityCard`, `UserCard`, `ProfileCard`, `IconBadge`, `EmptyState`, `ErrorState`, `Banner`, `Toast`. Assessment: - Package duplicates some `react` primitives by intention (`Banner`, `Toast`, state components) but naming can confuse consumers. - Best future work: higher-level shells where app teams otherwise hand-roll layout glue. - Avoid moving data table here while `ColumnView` exists in `react`; build wrappers only when async/stateful needs justify it. ## `@gnome-ui/charts` General charts: - `LineChart`, `AreaChart`, `BarChart`, `ComposedChart`, `PieChart`, `RadarChart`, `RadialBarChart`, `TreeMap`, `CloudChart`, `ScatterChart`, `FunnelChart`. Compact charts: - `SparkLineChart`, `SparkAreaChart`, `SparkBarChart`. Utilities: - `GNOME_CHART_PALETTE`, `ChartLegendPosition`. Assessment: - Chart type coverage is broad enough for dashboards. - Biggest missing piece is not more chart shapes; it is shared chart scaffolding: headers, summaries, loading/error/empty, accessibility, export actions. - `ContributionGraph` currently lives in `react` as pure SVG/data display; keep it there unless chart package becomes umbrella for all visualizations. ## Recommended New Components Priority 1: | Component | Package | Why useful | Shape | |-----------|---------|------------|-------| | `ChartCard` | `@gnome-ui/layout` | Done. Every dashboard chart needs same shell: title, subtitle, metric, actions, loading, empty, error. Prevents repeated `Card` + `SectionHeader` + chart glue. | `title`, `subtitle`, `value`, `trend`, `actions`, `loading`, `error`, `empty`, `children`. | | `MetricGrid` | `@gnome-ui/layout` | Common pattern: 2-6 `StatCard`/`CounterCard` blocks with responsive columns. Thin wrapper over `DashboardGrid`, but names intent. | `items`, `columns`, `loading`, `renderItem`. | | `ResourceMeter` | `@gnome-ui/react` | `ProgressBar` + threshold label/status appears in CPU/memory/storage/settings. Smaller primitive than `ProgressCard`. | `value`, `max`, `label`, `format`, `thresholds`, `variant`. | | `FilterBar` | `@gnome-ui/react` | Search + chips + dropdown filters + clear action is common across lists/tables. Current pieces exist, composition repeats. | `query`, `filters`, `activeFilters`, `onClear`, slots. | | `PageHeader` | `@gnome-ui/layout` | App pages need consistent title/subtitle/actions above content; `AppHeader` is shell-level. | `title`, `subtitle`, `breadcrumbs`, `actions`, `metadata`. | Priority 2: | Component | Package | Why useful | Shape | |-----------|---------|------------|-------| | `DataState` | `@gnome-ui/react` | Standardizes loading/empty/error/success branching around content. Reduces repeated conditional UI. | `loading`, `error`, `empty`, `skeleton`, `children`. | | `SelectionToolbar` | `@gnome-ui/react` | Lists/tables need bulk actions once items selected. GNOME apps use contextual bars often. | `selectedCount`, `actions`, `onClear`. | | `DateRangePicker` | `@gnome-ui/react` | Charts/filtering need time ranges. Current controls lack date/range primitive. | `value`, `onChange`, `presets`, `locale`. | | `Pagination` | `@gnome-ui/react` | `ColumnView`/cards need page controls when virtualization not desired. | `page`, `pageCount`, `onPageChange`, `totalItems`. | | `DetailsList` | `@gnome-ui/react` | Read-only key/value metadata is common; `ActionRow variant="property"` helps but verbose. | `items`, `columns`, `copyable`, `orientation`. | Priority 3: | Component | Package | Why useful | Shape | |-----------|---------|------------|-------| | `ResizablePanel` | `@gnome-ui/layout` | Existing layout roadmap item; useful for editors/file managers/analytics. | `direction`, `defaultSizes`, `minSizes`, children. | | `CommandPalette` | `@gnome-ui/layout` | Existing roadmap item; app-level nav/action search. High utility but bigger API. | `open`, `items`, `groups`, `onSelect`, `shortcut`. | | `NotificationCenter` | `@gnome-ui/layout` | Complements `Toast`; useful for persistent notifications/history. | `items`, `groups`, `onDismiss`, `actions`. | | `KpiChartCard` | `@gnome-ui/layout` | Opinionated combo: metric + spark chart + trend. Very dashboard-useful, but can be built after `ChartCard`. | `metric`, `trend`, `spark`, `period`. | | `ExportMenu` | `@gnome-ui/react` | Charts/tables commonly expose CSV/PNG/copy actions. Generic menu avoids per-chart duplication. | `items`, `formats`, `onExport`. | ## Do Not Add Yet - New primitive chart types before `ChartCard`/data-state exists. Current chart coverage already broad. - More row variants unless direct libadwaita/HIG pattern exists. `ActionRow` + slots covers many. - Another `DataTable` in `layout`; `ColumnView` exists in `react`. If async table needed, make `DataView` wrapper using `ColumnView`. - Separate `DrawerPanel`; `Drawer`, `BottomSheet`, `OverlaySplitView` already cover most overlay panel needs. Add only if common filter/detail drawer API emerges. ## Implementation Rules For Next Components - Package boundary: `react` = primitives, `layout` = app/workflow composition, `charts` = visualization primitives/utilities. - Export parity: every public component needs root export, per-component `index.ts`, package subpath export, README, story, focused test. - Accessibility: named controls, keyboard path, ARIA only where semantic HTML is insufficient. - Intl: numbers/dates use `GnomeProvider` formatter hooks unless component receives explicit formatter. - Motion: all transitions respect `prefers-reduced-motion`. - Dependencies: avoid new runtime deps unless domain logic is hard and proven lib exists. --- Source: GNOME_GUIDELINES.md # GNOME Design System — Guidelines Reference for building components that follow the [GNOME Human Interface Guidelines (HIG)](https://developer.gnome.org/hig/) and the [Adwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/css-variables.html) design language. --- ## 1. Design Principles 1. **Clarity** — Interfaces should be easy to understand at a glance. 2. **Consistency** — Use system patterns. Users learn the UI once; it must behave the same everywhere. 3. **Efficiency** — Minimize steps to complete tasks. 4. **Forgiveness** — Prefer reversible actions. Confirm destructive ones. 5. **Accessibility** — Use relative font sizes, sufficient contrast, and keyboard navigation. --- ## 2. Color All colors are exposed as CSS custom properties via `tokens.css`. ### Palette | Name | Shade 1 (lightest) | Shade 3 (base) | Shade 5 (darkest) | |----------|--------------------|-----------------|-------------------| | Blue | `#99c1f1` | `#3584e4` | `#1a5fb4` | | Green | `#8ff0a4` | `#33d17a` | `#26a269` | | Yellow | `#f9f06b` | `#f6d32d` | `#e5a50a` | | Orange | `#ffbe6f` | `#ff7800` | `#c64600` | | Red | `#f66151` | `#e01b24` | `#a51d2d` | | Purple | `#dc8add` | `#9141ac` | `#63452c` | ### Semantic Tokens | Token | Purpose | |------------------------------|---------------------------------------------| | `--gnome-accent-color` | Interactive elements (links, focus rings) | | `--gnome-accent-bg-color` | Suggested action button background | | `--gnome-destructive-bg-color` | Destructive action button background | | `--gnome-success-bg-color` | Positive feedback / success state | | `--gnome-warning-bg-color` | Cautionary state | | `--gnome-error-bg-color` | Error state | ### Rules - **Never hard-code colors**. Always reference design tokens. - Default accent color is **blue** (`--gnome-blue-3: #3584e4`). Users/distributions may override it. - Always support **dark mode** via `@media (prefers-color-scheme: dark)` or a `.dark` data attribute. - Minimum contrast ratio: **4.5:1** for text (WCAG AA). --- ## 3. Typography Font family: **Adwaita Sans** (falls back to Cantarell → Inter → system-ui). ```css font-family: var(--gnome-font-family); ``` ### Scale | Token | Size (rem) | Use case | |--------------------------------|------------|-----------------------| | `--gnome-font-size-caption` | 0.75rem | Labels, captions | | `--gnome-font-size-body` | 1rem | Body text (base) | | `--gnome-font-size-title-4` | 1.125rem | Small headings | | `--gnome-font-size-title-3` | 1.25rem | Section headings | | `--gnome-font-size-title-2` | 1.5rem | Page headings | | `--gnome-font-size-title-1` | 1.875rem | Modal/dialog titles | | `--gnome-font-size-large-title`| 2.25rem | Hero / welcome screens| ### Rules - **Always use `rem`/`em`**, never `px` for font sizes — respects user accessibility settings. - **Minimize font variants** — stick to normal (400) and semibold (600). - Use **Header Capitalization** for button labels and headings (e.g. "Save Document"). - Use proper Unicode: `"` `"` (U+201C/201D), `…` (U+2026), `–` (U+2013). --- ## 4. Spacing 6 px base grid. All spacing tokens are multiples of 6 px. | Token | Value | Use case | |--------------------|-------|---------------------------------------------| | `--gnome-space-1` | 6px | Icon-label gap, tight inline spacing | | `--gnome-space-2` | 12px | Label-to-component gap, button padding | | `--gnome-space-3` | 18px | Group separation (vertical) | | `--gnome-space-4` | 24px | Section padding | | `--gnome-space-5` | 36px | Dialog / page padding | | `--gnome-space-6` | 48px | Large layout gaps | --- ## 5. Border Radius | Token | Value | Use case | |------------------------|----------|-----------------------------------| | `--gnome-radius-sm` | 4px | Small inline elements | | `--gnome-radius-md` | 8px | **Default** (buttons, inputs…) | | `--gnome-radius-lg` | 12px | Cards, popovers, dialogs | | `--gnome-radius-xl` | 15px | Windows | | `--gnome-radius-pill` | 9999px | Pill buttons, circular buttons | --- ## 6. Shadows | Token | Use case | |----------------------|--------------------------------| | `--gnome-shadow-sm` | Subtle elevation (buttons) | | `--gnome-shadow-md` | Popovers, dropdowns | | `--gnome-shadow-lg` | Dialogs, floating windows | --- ## 7. Transitions | Token | Value | |---------------------------|--------| | `--gnome-duration-fast` | 100ms | | `--gnome-duration-normal` | 200ms | | `--gnome-duration-slow` | 400ms | | `--gnome-easing-default` | `cubic-bezier(0.25, 0.46, 0.45, 0.94)` | Use `fast` for hover/active state changes. Use `normal` for appearing/disappearing elements. --- ## 8. Component Patterns ### 8.1 Buttons | Variant | When to use | |---------------|-----------------------------------------------------------| | `default` | Standard actions with no particular priority | | `suggested` | The single primary / affirmative action in a view | | `flat` | Actions inside header bars, toolbars, or dense UIs | | `destructive` | Irreversible or dangerous actions (Delete, Format…) | **Rules:** - Use at most **one `suggested` button** per window/view. - Use at most **one `destructive` button** per dialog. - Labels must be **imperative verbs** with Header Capitalization. - Avoid mixing icon + label on buttons outside header bars. - Place **affirmative actions on the right**, cancel on the left (dialogs). ### 8.2 Forms & Inputs - Group related controls with clear labels above or to the left. - Use `12px` horizontal gap between label and its input. - Show validation feedback inline, immediately after the control. ### 8.3 Dialogs - Keep dialogs focused on a **single task**. - Include a title, optional body text, and a button row. - Button order: **[Cancel] [Destructive] [Suggested]** (left → right). - Do not open dialogs from dialogs. ### 8.4 Header Bars - Use `flat` buttons in header bars. - Keep the title centered and concise. - Place primary navigation controls (back, menu) on the left; secondary actions on the right. --- ## 9. Accessibility - All interactive elements must be **keyboard navigable** (Tab, Enter, Space, Escape). - Provide `aria-label` for icon-only buttons. - Focus ring must be clearly visible (`--gnome-focus-ring-width: 3px`). - Do not rely on color alone to convey meaning. - Test with a screen reader (Orca on GNOME) and the `@storybook/addon-a11y` panel. --- ## 10. Dark Mode Components must respond to `@media (prefers-color-scheme: dark)` automatically via the tokens defined in `tokens.css`. No additional logic needed in component code — simply reference CSS custom properties. ```css /* ✅ correct — adapts automatically */ color: var(--gnome-window-fg-color); /* ❌ wrong — breaks dark mode */ color: rgba(0, 0, 0, 0.8); ``` --- ## 11. File & Component Conventions ``` src/ components/ ComponentName/ ComponentName.tsx # Component implementation ComponentName.module.css # Scoped styles (CSS Modules) ComponentName.stories.tsx # Storybook stories index.ts # Re-exports styles/ tokens.css # All design tokens (single source of truth) index.ts # Library public API ``` - One component per directory. - CSS Modules for all component styles — no global class names. - All design values (color, spacing, radius…) **must** come from `tokens.css` variables. - Props interface must be exported and documented with JSDoc. - Every component must have a Storybook story with `autodocs` tag. --- Source: ARCHITECTURE.md # Architecture — @gnome-ui This document describes the package dependency graph and the role of each workspace in the monorepo. ## Package dependency graph ```mermaid graph TD GNOME["🖥️ GNOME / GJS runtime\nGSettings · Gio · Gtk · Notifications\nXDG Portals · GDK Clipboard"] subgraph "gnome-ui monorepo" CORE["@gnome-ui/core\nDesign tokens · CSS variables\n(Adwaita colours, radii, typography)"] ICONS["@gnome-ui/icons\nSVG icon components"] PLATFORM["@gnome-ui/platform\nTypeScript API layer\nsettings · notifications · fileChooser\ncolorScheme · window · portals · clipboard"] HOOKS["@gnome-ui/hooks\nReact hooks\nuseSettings · useNotification · useColorScheme\nuseFileChooser · useClipboard · useWindowState"] REACT["@gnome-ui/react\nUI components\n(Button, Dialog, Sidebar, …)"] CHARTS["@gnome-ui/charts\nChart components\n(AreaChart, BarChart, LineChart)"] WEB_COMPONENTS["@gnome-ui/web-components\nNative Custom Elements\n(Dialog, Toast, Popover)"] end APP["Your App (React, HTML, or htmx)"] GNOME -->|WebKit bridge / XDG Portals| PLATFORM PLATFORM --> HOOKS CORE --> REACT CORE --> CHARTS CORE --> HOOKS CORE --> WEB_COMPONENTS ICONS --> REACT REACT --> APP CHARTS --> APP HOOKS --> APP WEB_COMPONENTS --> APP ``` ## Package roles | Package | Role | React? | GNOME runtime? | |---------|------|--------|----------------| | `@gnome-ui/core` | Design tokens, CSS custom properties | No | No | | `@gnome-ui/icons` | SVG icon components | Yes | No | | `@gnome-ui/platform` | Low-level TypeScript bridge to GNOME APIs | No | Yes | | `@gnome-ui/hooks` | React hooks that surface `platform` APIs | Yes | Via platform | | `@gnome-ui/react` | Full Adwaita UI component library | Yes | No | | `@gnome-ui/charts` | Recharts-based chart components styled with Adwaita tokens | Yes | No | | `@gnome-ui/web-components` | Native, light-DOM Custom Elements for framework-agnostic apps | No | No | ## Communication model `@gnome-ui/platform` communicates with the GNOME host process through one of two mechanisms, resolved at runtime: ``` ┌─────────────────────────────────────────────────┐ │ React App (WebKitGTK WebView or browser) │ │ │ │ @gnome-ui/platform │ │ │ │ │ ├─ WebKit bridge ──► window.webkit │ │ │ (GJS host) .messageHandlers.* │ │ │ │ │ └─ XDG Portals ──► org.freedesktop.* │ │ (Flatpak / via postMessage / │ │ browser) fetch proxy │ └─────────────────────────────────────────────────┘ ``` When neither bridge is available (unit tests, standard browsers) every call falls back to a no-op stub so the application renders without crashing. ## Build order ``` @gnome-ui/core → @gnome-ui/platform → @gnome-ui/hooks → @gnome-ui/icons → @gnome-ui/react → @gnome-ui/charts → @gnome-ui/web-components ``` `@gnome-ui/hooks` depends on both `@gnome-ui/platform` (runtime) and `@gnome-ui/core` (tokens for any bundled UI). --- Source: packages/core/README.md # @gnome-ui/core

gnome-ui

Framework-agnostic CSS design tokens for the GNOME UI design system, based on the [GNOME Human Interface Guidelines](https://developer.gnome.org/hig/) and the [Adwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/css-variables.html) design language. [![npm](https://img.shields.io/npm/v/@gnome-ui/core)](https://www.npmjs.com/package/@gnome-ui/core) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE) ## Installation ```bash npm install @gnome-ui/core ``` ## Usage Import the tokens once at the root of your app: ```css @import "@gnome-ui/core/styles"; ``` ```js import "@gnome-ui/core/styles"; ``` All tokens are then available as CSS custom properties: ```css .my-button { background-color: var(--gnome-accent-bg-color); color: var(--gnome-accent-fg-color); border-radius: var(--gnome-radius-md); font-family: var(--gnome-font-family); padding: var(--gnome-space-1) var(--gnome-space-2); } ``` Dark mode is handled automatically via `@media (prefers-color-scheme: dark)`. ## Token reference ### Colors | Token | Light | Dark | |-------|-------|------| | `--gnome-accent-color` | `#3584e4` | `#78aeed` | | `--gnome-accent-bg-color` | `#3584e4` | `#3584e4` | | `--gnome-accent-fg-color` | `#ffffff` | `#ffffff` | | `--gnome-destructive-bg-color` | `#e01b24` | `#e01b24` | | `--gnome-destructive-fg-color` | `#ffffff` | `#ffffff` | | `--gnome-success-bg-color` | `#2ec27e` | `#2ec27e` | | `--gnome-warning-bg-color` | `#f6d32d` | `#f6d32d` | | `--gnome-window-bg-color` | `#fafafa` | `#242424` | | `--gnome-window-fg-color` | `rgba(0,0,0,.8)` | `rgba(255,255,255,.87)` | | `--gnome-card-bg-color` | `#ffffff` | `#383838` | | `--gnome-headerbar-bg-color` | `#ebebeb` | `#303030` | ### Spacing (6 px grid) | Token | Value | |-------|-------| | `--gnome-space-1` | `6px` | | `--gnome-space-2` | `12px` | | `--gnome-space-3` | `18px` | | `--gnome-space-4` | `24px` | | `--gnome-space-5` | `36px` | | `--gnome-space-6` | `48px` | ### Border radius | Token | Value | Use | |-------|-------|-----| | `--gnome-radius-sm` | `4px` | Small elements | | `--gnome-radius-md` | `8px` | Default (buttons, inputs) | | `--gnome-radius-lg` | `12px` | Cards, popovers | | `--gnome-radius-xl` | `15px` | Windows | | `--gnome-radius-pill` | `9999px` | Pill/circular buttons | ### Typography | Token | Value | |-------|-------| | `--gnome-font-family` | `"Adwaita Sans", Cantarell, "Inter", system-ui, sans-serif` | | `--gnome-font-size-large-title` | `2.25rem` | | `--gnome-font-size-title-1` | `1.875rem` | | `--gnome-font-size-title-2` | `1.5rem` | | `--gnome-font-size-title-3` | `1.25rem` | | `--gnome-font-size-title-4` | `1.125rem` | | `--gnome-font-size-body` | `1rem` | | `--gnome-font-size-caption` | `0.75rem` | | `--gnome-font-weight-normal` | `400` | | `--gnome-font-weight-semibold` | `600` | | `--gnome-font-weight-bold` | `700` | ### Focus ring | Token | Value | |-------|-------| | `--gnome-focus-ring-color` | `var(--gnome-accent-color)` | | `--gnome-focus-ring-width` | `3px` | | `--gnome-focus-ring-offset` | `2px` | ### Motion | Token | Value | |-------|-------| | `--gnome-duration-fast` | `100ms` | | `--gnome-duration-normal` | `200ms` | | `--gnome-duration-slow` | `400ms` | | `--gnome-easing-default` | `cubic-bezier(0.25, 0.46, 0.45, 0.94)` | | `--gnome-easing-spring` | `cubic-bezier(0.34, 1.56, 0.64, 1)` | ### Shadows | Token | Use | |-------|-----| | `--gnome-shadow-sm` | Subtle card/button shadow | | `--gnome-shadow-md` | Popovers, dropdowns | | `--gnome-shadow-lg` | Dialogs, modals | ### Layout | Token | Value | Use | |-------|-------|-----| | `--gnome-layout-sidebar-min-width` | `180px` | Minimum GNOME sidebar width | | `--gnome-layout-sidebar-default-width` | `240px` | Default standalone sidebar width | | `--gnome-layout-sidebar-max-width` | `280px` | Maximum GNOME sidebar width | | `--gnome-layout-sidebar-width` | `clamp(180px, 25%, 280px)` | Standard in-flow sidebar width | | `--gnome-layout-sidebar-overlay-width` | `clamp(180px, 75%, 280px)` | Overlay sidebar width on narrow screens | | `--gnome-layout-sidebar-rail-width` | `56px` | Collapsed icon-only sidebar rail | | `--gnome-layout-breakpoint-narrow` | `400px` | Split-view collapse threshold | | `--gnome-layout-breakpoint-medium` | `550px` | Bottom-navigation / compact shell threshold | | `--gnome-layout-breakpoint-wide` | `860px` | Nested-layout outer-pane threshold | | `--gnome-layout-content-padding` | `var(--gnome-space-4)` | Default page content padding | | `--gnome-layout-content-padding-compact` | `var(--gnome-space-2)` | Compact page content padding | | `--gnome-layout-content-padding-spacious` | `var(--gnome-space-5)` | Spacious page content padding | The breakpoint tokens document the shared GNOME thresholds. CSS media queries still use literal pixel values because custom properties are not valid in standard `@media` conditions. ### Misc | Token | Value | |-------|-------| | `--gnome-opacity-disabled` | `0.5` | ## License [MIT](../../LICENSE) --- Source: packages/icons/README.md # @gnome-ui/icons

gnome-ui

Framework-agnostic icon definitions for the [gnome-ui](https://github.com/ElJijuna/gnome-ui) design system. Each icon is a plain JavaScript object (`IconDefinition`) containing SVG path data — no DOM, no React, no styles. UI framework adapters consume this shape to render inline SVGs. The `Icon` React adapter also accepts icons from [`simple-icons`](https://simpleicons.org/) directly, without any conversion. [![npm](https://img.shields.io/npm/v/@gnome-ui/icons)](https://www.npmjs.com/package/@gnome-ui/icons) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE) ## Installation ```bash npm install @gnome-ui/icons ``` ## Tree-shaking This package is fully tree-shakeable. Importing a single icon only pulls that icon's module into your bundle — not the entire registry. ```ts // Only `Add` and `Search` are included in the final bundle import { Add, Search } from "@gnome-ui/icons"; ``` Each icon is also available as a direct sub-path import for bundlers that prefer explicit paths: ```ts import { Add } from "@gnome-ui/icons/icons"; import { GitHub } from "@gnome-ui/icons/third-party"; ``` ## Usage ### With `@gnome-ui/react` ```tsx import { Icon } from "@gnome-ui/react"; import { Search, Settings, GoHome } from "@gnome-ui/icons"; ``` ### With `simple-icons` The `Icon` component accepts any `simple-icons` icon directly — no adapter or conversion needed. `simple-icons` is not a dependency of this package; install it separately in your project. ```tsx import { Icon } from "@gnome-ui/react"; import { siGithub, siNpm } from "simple-icons"; ``` You can also pass a plain `{ path }` object for any single-path SVG icon: ```tsx import { Icon } from "@gnome-ui/react"; // Custom viewBox (defaults to "0 0 24 24"): ``` ### Framework-agnostic (raw SVG) ```ts import { Search } from "@gnome-ui/icons"; import type { IconDefinition } from "@gnome-ui/icons"; function renderIcon(icon: IconDefinition, size = 16) { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("viewBox", icon.viewBox); svg.setAttribute("width", String(size)); svg.setAttribute("height", String(size)); svg.setAttribute("fill", "currentColor"); for (const path of icon.paths) { const el = document.createElementNS("http://www.w3.org/2000/svg", "path"); el.setAttribute("d", path.d); if (path.fillRule) el.setAttribute("fill-rule", path.fillRule); if (path.clipRule) el.setAttribute("clip-rule", path.clipRule); svg.appendChild(el); } return svg; } ``` ### Animated icons A handful of icons carry a small CSS animation instead of (or in addition to) static path data — `animated: true`, with the SVG markup in `svg` instead of `paths`. This mirrors GTK 4.22's `GtkSvg`: trusted, package-authored SVG (not arbitrary user content) that can include `