JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 241
  • Score
    100M100P100Q94888F
  • License MIT

React 19 components for the DGA (Digital Government Authority) design system , accessible, RTL-native, dark-mode ready.

Package Exports

  • @dev-dga/react

Readme

@dev-dga/react

React 19 components for the DGA (Digital Government Authority) design system , Saudi Arabia's national reference for government digital platforms.

Accessible (WCAG 2.2 AA), RTL-native, dark-mode ready, themable. Ships no CSS , pair with @dev-dga/css.

Install

npm install @dev-dga/react @dev-dga/css

Requires react@^19 and react-dom@^19 (peer dependencies).

Usage

import '@dev-dga/css'; // required , components ship no styles
import { DgaProvider, Button, Input, Select, SelectItem, Switch } from '@dev-dga/react';

export default function App() {
  return (
    <DgaProvider>
      <Input label="Email" type="email" helperText="We'll never share it." />
      <Select label="Country" placeholder="Choose…">
        <SelectItem value="sa">Saudi Arabia</SelectItem>
        <SelectItem value="ae">United Arab Emirates</SelectItem>
      </Select>
      <Switch label="Subscribe to the newsletter" />
      <Button>Submit</Button>
    </DgaProvider>
  );
}

For RTL, dark mode, or a brand color, configure the provider:

<DgaProvider dir="rtl" mode="dark" theme={{ primary: 'lavender' }}>
  {/* … */}
</DgaProvider>

Server Components / Next.js App Router

The package entry ships 'use client', so the whole component surface is a client boundary and slots into a React Server Component tree the usual way:

  • App Router: wrap DgaProvider once in a 'use client' module and render that from your server layout.tsx; use components inside your client components as normal. Importing anything from @dev-dga/react into a Server Component establishes the client boundary automatically — the package entry carries 'use client'.
  • Vite / CRA / any client-rendered React 19 app: nothing special — just put DgaProvider at the root.

Because the entry is a single client boundary, even purely-presentational components (Card, Divider) render as client components when imported from @dev-dga/react — the right trade-off for an all-client library (most of the surface needs hooks/context), and what makes a one-line barrel import work in RSC. This is by design, not a limitation to route around.

Visual components support asChild so you can render them as your router's Link (Next.js, React Router, TanStack Router, …) without invalid <button><a> nesting:

<Button asChild>
  <Link href="/about">About</Link>
</Button>

Build your own field

useFieldA11y + FieldMessage are public , the same primitives every shipped form control uses. Build a custom field (date picker, file upload, combobox) with the library's a11y wiring, helper/error precedence, and dev-time warnings:

import { useFieldA11y, FieldMessage } from '@dev-dga/react';

function MyField({ label, helperText, error, errorMessage, ...rest }) {
  const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } =
    useFieldA11y({ name: 'MyField', label, error, errorMessage, helperText });
  return (
    <div className="ddga-field">
      {label && <label htmlFor={fieldId}>{label}</label>}
      <input {...controlProps} {...rest} />
      {hasErrorMessage && (
        <FieldMessage id={errorId} variant="error">
          {errorMessage}
        </FieldMessage>
      )}
      {hasHelper && (
        <FieldMessage id={helperId} variant="helper">
          {helperText}
        </FieldMessage>
      )}
    </div>
  );
}

Components

Form: Button · Input · Textarea · NumberInput · InputOTP (OTP/PIN) · SearchBox · TagInput (token/chip) · Checkbox · RadioGroup + Radio · Switch · Select + SelectItem · Combobox + ComboboxItem (+ ComboboxGroup · ComboboxSeparator) · DatePicker (Hijri toggle) · Slider (single/range) · Rating (half-star) · FileUpload · Toggle + ToggleGroup (+ ToggleGroupItem)

Display: Card (+ CardImage/CardHeader/CardTitle/CardDescription/CardContent/CardFooter) · Table (+ TableHeader/TableBody/TableFooter/TableRow/TableHead/TableCell/TableCaption) · List (+ ListItem/ListItemIcon/ListItemContent/ListItemAction) · Quote (+ QuoteContent/QuoteCaption/QuoteAuthor/QuoteSource) · Badge · Divider · Avatar (+ AvatarImage/AvatarFallback/AvatarGroup) · DescriptionList (+ DescriptionItem/DescriptionTerm/DescriptionDetails) · Stat + StatGroup (KPI tiles) · Timeline (+ TimelineItem/TimelineMarker/TimelineContent/TimelineTitle/TimelineDescription/TimelineTime) · EmptyState (+ EmptyStateMedia/EmptyStateTitle/EmptyStateDescription/EmptyStateActions)

Feedback / overlay: Tooltip · Alert · Modal · Toast (imperative API) · Drawer (off-canvas, 4 sides) · DropdownMenu (compound w/ CheckboxItem, RadioGroup, Sub) · Popover (generic floating panel) · Command + CommandDialog (⌘K palette)

Navigation: Tabs · Breadcrumb · Pagination · Accordion · Steps · Sidebar (app-shell, collapsible) · Menubar (File/Edit/View app-bar) · Link (styled <a>, external)

Layout: ScrollArea · Collapsible (+ CollapsibleTrigger/CollapsibleContent)

Status: Spinner · Skeleton · Progress + CircularProgress

Primitives: DgaProvider · useDga · useDir · useFieldA11y · FieldMessage · cn

Theming types: DgaTheme · PaletteName · ThemeColor

Docs

Live Storybook · Source

License

MIT