إنتقل إلى المحتوى الرئيسي

React

The system's components as React components: @arabesquelabs/design-system/react (dist/react/, from react/src/). They write the same markup the specs describe, so dist/arabesque.css styles them, and they use the same helpers (js/) for what they do. The CSS stays the system; React is one way to write its markup. hunt and any page without React use the classes and the helpers directly, as before.

See them working, in English and Arabic, light and dark, on the example pages (in a checkout, npm run serve, then /examples/). The studio homepage template is built from them: templates/react/home.tsx.

Use it​

React 19 or later. Link the CSS and fonts as for any page (README, "Use it in a project"), serve dist/icons.svg from the same origin as the page (an SVG <use> can't reach across origins), then:

TSX
import { ArabesqueProvider, Button, Field, Input, SiteHeader, useToast } from "@arabesquelabs/design-system/react";

export function App() {
return (
<ArabesqueProvider lang="en" sprite="/dist/icons.svg">
<SiteHeader links={[{ label: "The idea", href: "#idea" }]} />
<Field label="Full name" hint="As it is on your passport">
<Input autoComplete="name" />
</Field>
<Button variant="primary">Save changes</Button>
</ArabesqueProvider>
);
}

ArabesqueProvider says, once, what every component needs to know about the page. Without one, the components take the language of <html lang> in the browser; on the server there's no <html> to read, so a page rendered there in Arabic needs the provider.

SettingWhatDefault
langThe page's language: the components' own words (Menu, Clear search, Retry…) and how they write numbers"en"
numeralsIn Arabic, Western ("latn") or Arabic-Indic ("arab") digits"latn"
spriteThe icon sprite's URL"/dist/icons.svg"
labelsYour own words for any built-in labelthe language's

For Arabic, set lang="ar" dir="rtl" on <html> as well, and <ArabesqueProvider lang="ar">: the components' labels, digits, date picker and construction figure follow it. A part of a page in the other language takes its own provider and its own lang and dir, as the examples do.

What there is​

One module per spec, named after it:

ModuleComponentsSpec
buttonButton (variant, size, icon, iconEnd, label, busy; an <a> with href), ButtonGroup (label, vertical)Button
link, languageTextLink (arrow, external, muted), LanguageLinkText link, Language link
field, rangeField, Input (icon, number), Range, Select, Textarea, Affix, AffixText, Fieldset, ErrorMessage, HintField
choiceCheckbox (indeterminate), Radio, Switch, ChoicesCheckbox, radio and switch
segmentedSegmented (radios), SegmentedButtons (pressed buttons)Segmented control
character-count, date-input, date-pickerCharacterCount, DateInput, DatePicker, DateExampleCharacter count, Date input, Date picker
formsErrorSummary, Search, SummaryList, ConfirmationError summary, Search, Summary list, Confirmation
disclosure, card, table, steps, task-listDisclosure, Card (footer, ribbon), Panel, Stat, Table, Steps, TaskListDisclosure, Card, Table, Steps, Task list
badge, tintBadge, Tag, Highlight, Avatar (size, square), AvatarStackBadge and tag, Tints
page-head, nav, site-header, sidebar, footer, breadcrumbsPageHead, Tabs, SectionNav, SiteHeader (language, sticky, skipTo), ThemeToggle, Shell, Footer, Breadcrumbs, BackLinkPage head, Tabs, Site header, Sidebar, Footer, Breadcrumbs
notice, phase-banner, toast, dialog, menu, tooltipNotice (onDismiss; its kind's word as the title by default), SideEffect, PhaseBanner, useToast, Dialog, Menu, useTooltipsNotice, Phase banner, Toast, Dialog, Menu, Tooltip
empty-state, progress, save-state, bulk-bar, kbdEmptyState, Spinner (the star; label when nothing beside it says what's happening), Skeleton, Progress, SaveState, RollbackNote, Stale, StaleNote, BulkBar, Kbd, ShortcutsEmpty state, Loading, Pending changes, Bulk bar, Keys
pagination, stepper, status, rating, popoverPagination (page, pages, href, onNavigate), pageRange, Stepper (steps, current, href), Status (tone, live, dotOnly), Timeline, List, Rating, RatingValue, Popover (label, icon, title)Pagination, Stepper, Status, Timeline, List, Rating, Popover
chartChartFigure, ColumnChart, SplitBar, BulletChartCharts
brand, pattern, construction, iconMark, ArabesqueMark, Star, Wordmark, Lockup (stacked, product, name, mark), Pattern (full, quiet), Hero, HeroCaption, ConstructionFigure, IconBrand, Pattern, Construction figure, Icon
layoutPage, Section (heading, lede), Stack, Cluster, Grid, Split, VisuallyHidden, SkipLinkLayout

Every prop is typed (dist/react/*.d.ts), with what it's for.

How they work​

  • Same markup. A component writes what its spec's Anatomy shows, with the same classes and ARIA. If the two ever differ, the spec is right.
  • The helpers do the behaviour. Tabs, menus, the site header's menu, dialogs, the date picker, the character count, tooltips, chart keys and the pattern are wired by the helpers in js/, from an effect. They're imported from js/ where they are (never bundled in), so the date picker and validation still find the sprite at ../dist/icons.svg.
  • Ids are made for you. A field's id, its hint's and its error's are made with useId and joined up (aria-describedby, aria-invalid), so they can't disagree. Give an id when something outside needs it: an error summary's link, say.
  • Server rendering works: nothing touches document until an effect. The homepage template is rendered on the server, and wired in the page by the helpers alone (see its script).
  • Focus. Dialog returns focus to returnFocusTo when it closes, or to what had focus when it opened. Pass returnFocusTo: Safari doesn't focus a button when it's clicked.

Change them​

Each component is in react/src/<spec>.tsx. Then:

Terminal
npm install
npm run build:react # dist/react, the examples, and the homepage template; type-checked
npm test # includes tests/react.test.js
node scripts/check-page.mjs # every example page in Chrome, with axe, light and dark
  • A component changes with its CSS and its spec, in the same change. tests/react.test.js fails if a CSS component has no React component writing it, if the mark or the icons drift from assets/ and icons/, or if the English and Arabic labels have different keys.
  • An example is a function in examples/src/demos.tsx, written in English, with each sentence through t(). Its Arabic comes from the site's Arabic catalogue (showcase-ar.js), or examples/src/ar.ts for a new sentence; the build fails on a sentence with no Arabic. Each demo is shown twice on its page, in English and in Arabic, so it mustn't give fixed ids to its elements: let the components make them, or use useId.
  • The homepage is templates/react/home.tsx: its words, in English and Arabic, are in copy. The build writes templates/home.html and templates/ar/home.html from it; don't edit those.

dist/react/, examples/ and the template's HTML are committed, as dist/ is: the site serves the repository as it is. CI rebuilds them and fails if they differ.