@eona-x/ui-toolkit-react
v0.9.2
Published
React port of the EONA-X design system, generated from the eona-ui-toolkit Yew crate.
Readme
@eona-x/ui-toolkit-react
React components for the EONA-X design system. This package is generated. The source
of truth is the Yew crate in this repository (src/): each component here was produced by
rendering the Rust component with Yew's own server renderer and splicing the props back
into the resulting markup, so the React and Yew renders are the same HTML by construction.
Generated from src_hash 6b5e166285546e8f773e7e24b49871d2b541213a89ce5a23b7ce030199f90c36.
Documentation
- Getting started — install, a first component, a static site, theming
- Components — every component, rendered live, with its call
Do not edit
Every file under src/ is overwritten by the next cargo xtask bridgegen, and cargo xtask check
re-runs the generator and diffs the result, so a hand edit is reported rather than
surviving quietly; CI runs it on every push.
To change a component, change the Rust component it came from — the file:line is
in the header of every generated file — and regenerate.
Install
npm install @eona-x/ui-toolkit-reactreact >= 19 is a peer dependency: NavDropdown renders inert
(src/molecules/nav_dropdown.rs:29), which React only added to its DOM attribute types
in 19.
The markup carries the design system's class names; @eona-x/ui-toolkit-css, installed with this
package at the same version, styles them. Import it once, and render the components inside
an element with the class eona-ui — every rule in it is scoped under that class, so it
neither resets nor displaces the rest of the page. Its own README lists the entry points,
including the opt-in page.css for an app that is an EONA-X page.
import '@eona-x/ui-toolkit-css';
import { Button } from '@eona-x/ui-toolkit-react';
export default function Page() {
return (
<div className="eona-ui">
<Button label="Get started" href="/docs" />
</div>
);
}One component needs a file this package does not carry: SiteHeader hardcodes
logo/logo-transparent.svg (src/organisms/site_header.rs:101,105) and must find it at
that path relative to the page, or it renders a broken image where the EONA-X mark goes.
RuleListItem needs an ancestor rather than an asset: every rule that styles it is
scoped under .rules-list, so render it inside a <ul className="rules-list">.
Server components
Every component is presentational and holds no state, so none of them carries a
client-component directive — the string does not occur anywhere in the package — and all
of them render inside a React Server Component. The
toolkit's stateful ontology browser is not here to port: it lives in eona-vocabulary-ui,
which owns it outright. Anything browser-only belongs in a hand-written client component.
SSR output is equivalent, not byte-identical
The elements, attributes and class names match the Yew render. The serialisation does not, in four measured ways, none of which changes what a browser shows. Do not write a snapshot test that diffs this package's SSR bytes against the Yew portal's:
- Trailing
;instyle. Yew emits the author's string verbatim (style="position:relative;",src/molecules/nav_dropdown.rs:24); React serialises a style object and writes no trailing semicolon. - Whitespace in
style. React normalisesbackground : #ffftobackground:#fff. - Whitespace in
class. Yew'sClassescollapses runs of whitespace; React does not, so a prop containing a newline reaches the class attribute intact (src/atoms/code_block.rs:38interpolateslanguage). - React's own additions. React 19 hoists a
<link rel="preload" as="image">for every<img src>it renders, and omitssrc=""entirely (with a warning) where Yew emits it.
Components (41)
AccordionItem—src/molecules/accordion_item.rs:17BadgeNum—src/atoms/badge_num.rs:11BgCheckItem—src/molecules/bg_check_item.rs:16Button—src/atoms/button.rs:30Callout—src/molecules/callout.rs:13CaseCard—src/molecules/case_card.rs:15CodeBlock—src/atoms/code_block.rs:27DatasetCard—src/molecules/dataset_card.rs:57DeclCard—src/molecules/decl_card.rs:17EvolutionBadge—src/atoms/evolution_badge.rs:23Hero—src/organisms/hero.rs:35HeroFilter—src/organisms/hero_filter.rs:34LogoDownloadCard—src/molecules/logo_download_card.rs:22MainNav—src/organisms/main_nav.rs:26MemberCard—src/molecules/member_card.rs:11MemberFilterCard—src/molecules/member_filter_card.rs:18MetricTile—src/molecules/metric_tile.rs:28Modal—src/molecules/modal.rs:28MvoCard—src/molecules/mvo_card.rs:11NavDropdown—src/molecules/nav_dropdown.rs:22NewsCard—src/molecules/news_card.rs:16OntoAnnotation—src/molecules/annotation.rs:38OntoBadge—src/atoms/onto_badge.rs:66PaletteGroup—src/molecules/palette_group.rs:43PersonalityCard—src/molecules/personality_card.rs:11Pill—src/atoms/pill.rs:28PillButton—src/atoms/pill_button.rs:37PillarCard—src/molecules/pillar_card.rs:13PropsTable—src/molecules/props_table.rs:40RefCard—src/molecules/ref_card.rs:14RuleListItem—src/molecules/rule_list_item.rs:28ScoreDonut—src/molecules/score_donut.rs:29SectionHead—src/molecules/section_head.rs:15ShapeCard—src/molecules/shape_card.rs:12SimpleFooter—src/organisms/simple_footer.rs:13SiteHeader—src/organisms/site_header.rs:96Swatch—src/molecules/swatch.rs:44TagLabel—src/atoms/tag_label.rs:27TextField—src/molecules/text_field.rs:22TypeScaleRow—src/molecules/type_scale_row.rs:14UsageExample—src/molecules/usage_example.rs:24
Out of scope (4)
Recorded here because a component that is missing on purpose and one that is missing by accident look identical from the outside.
- crate showcase page (1): DemoPage
- zero-prop demo section (3): ComponentsGallery, IntegrationSection, OntologySection
