@tooark/react
v1.4.0
Published
Tooark React — typed wrappers for ark-* components for React 18 and 19
Readme
@tooark/react
Typed React wrappers for the Tooark Web Components: camelCase props, custom events as handlers, JSX typings for every ark-* tag. React 18 and 19.
🌍 Languages:
English (this file) ·
Português
📑 Contents
- Overview
- Installation
- Configuration
- Components
- Usage examples
- Dependencies
- Contributing
- Help & Security
- Support
- License
📖 Overview
The @tooark/react package provides:
- one component per element (41 wrappers:
ArkAlert,ArkAvatar,ArkBadge,ArkButton,ArkCalendar,ArkCard, …) with typed props that extend theArk*StyleOptionsfrom@tooark/core; - camelCase props map to attributes; booleans are passed as present/absent; object props (
events,rows,options, andlocaleJsononArkCalendar/ArkDatepicker) are serialized or assigned as properties for you (on the other wrapperslocaleJsonis a JSON string); - custom events become handlers receiving the
CustomEvent(onChange,onClose,onSelect, …) or, on the calendar, datepicker, clock, carousel and scheduler, itsdetail; native events (onClick,onInput) work as usual, andArkButtonPropsextendsReact.HTMLAttributes<HTMLElement>, soonClick,onFocus,id,style, … are typed (adisabledorloadingbutton never firesonClick); - the elements register themselves on first render (
ensureTooarkComponentsRegistered), browser only, so SSR frameworks are fine; IntrinsicElementstypings for everyark-*tag, for the side packages or when you prefer the raw element;toast,showToast,dismissToastre-exported from@tooark/core.
🔧 Installation
pnpm add @tooark/react @tooark/web-components@tooark/react already depends on @tooark/web-components, @tooark/core and @tooark/tokens, but pnpm does not expose transitive dependencies to your app, and the stylesheet import below comes from @tooark/web-components: install it directly. toast is re-exported by @tooark/react.
Peer dependencies: react and react-dom ≥ 18.
⚙️ Configuration
Import the stylesheet once, in main.tsx or your root layout; nothing else to configure (the wrappers register the elements themselves):
import "@tooark/web-components/styles.css";📦 Components
One wrapper per element, named after it: ark-button → ArkButton, ark-kv-editor → ArkKvEditor, ark-command-palette → ArkCommandPalette + ArkCommandItem. Each exports its props type (ArkButtonProps, …).
- Props: the element's attributes in camelCase (
iconOnly,stepMinutes,localeJson),className, plus the element's JS properties where they matter (events,rows,options,sizes,colors, andvalueFieldonArkKvEditor, which must be a stable function:useCallback). - Events:
on<Event>for the custom events, receiving theCustomEvent(onChangeonArkSelect/ArkKvEditor,onCloseonArkDialog/ArkDrawer,onSelectonArkMenu/ArkCommandPalette, …);onChangeonArkCalendar/ArkDatepicker/ArkClock,onSlideChangeonArkCarouselandonEventClick/onSlotClick/onViewChange/onRangeChangeonArkSchedulerreceive thedetailitself. Native events bubble from the inner control (onInputonArkInput: readevent.target.value). - State: attributes like
openare the source of truth (ArkDialog open={bool}+onClose), so controlled rendering works and the exit still animates. - Ref: every wrapper forwards
refto itsark-*element (React 18 and 19), typed as the element class from@tooark/web-components, so its methods and properties are typed. Object and callback refs both work (including React 19 callback refs that return a cleanup), and the wrapper's own events and properties keep working.
import { ArkButton, ArkDialog } from "@tooark/react";
import React, { useRef } from "react";
export function Shortcuts() {
const dialog = useRef<React.ComponentRef<typeof ArkDialog>>(null); // the <ark-dialog> element
return (
<>
<ArkButton onClick={() => dialog.current?.show()}>Keyboard shortcuts</ArkButton>
<ArkDialog ref={dialog} label="Keyboard shortcuts">
<p>Ctrl+K opens the command palette.</p>
</ArkDialog>
</>
);
}Full attribute reference, theming guide and E2E hooks: https://github.com/Tooark/web-components#readme · live examples with interaction tests: Storybook.
📝 Usage examples
A form with a confirmation dialog and a toast
import { ArkButton, ArkDialog, ArkInput, ArkSelect, ArkToaster, toast } from "@tooark/react";
import { type FormEvent, useState } from "react";
const ROLES = [
{ value: "dev", label: "Developer" },
{ value: "ops", label: "Operations" },
];
export function ProfileForm() {
const [name, setName] = useState("");
const [role, setRole] = useState("dev");
const [confirming, setConfirming] = useState(false);
function submit(event: FormEvent) {
event.preventDefault();
setConfirming(true);
}
function publish() {
setConfirming(false);
toast.success("Profile published", { description: `Welcome, ${name}.` });
}
return (
<form onSubmit={submit}>
<ArkInput label="Name" value={name} required onInput={(e) => setName((e.target as HTMLInputElement).value)} />
<ArkSelect label="Role" options={ROLES} value={role} onChange={(e) => setRole(e.detail.value)} />
<ArkButton type="submit" intent="primary">
Save
</ArkButton>
<ArkDialog label="Publish changes?" open={confirming} onClose={() => setConfirming(false)}>
<p>Your profile will be visible to the whole team.</p>
<div slot="footer">
<ArkButton variant="ghost" onClick={() => setConfirming(false)}>
Cancel
</ArkButton>
<ArkButton intent="primary" onClick={publish}>
Publish
</ArkButton>
</div>
</ArkDialog>
<ArkToaster position="bottom-right" />
</form>
);
}A raw element from a side package
import { registerTooarkChart } from "@tooark/chart";
import { useEffect, useRef } from "react";
export function Sales({ option }: { option: object }) {
const ref = useRef<HTMLElement & { option: object }>(null);
useEffect(() => {
registerTooarkChart();
if (ref.current) ref.current.option = option; // JS property, not an attribute
}, [option]);
return <ark-chart ref={ref} height="320px" />; // typed by @tooark/react's IntrinsicElements
}📋 Dependencies
Installed automatically unless marked as peer; peer dependencies are yours to install (the ranges are what the package declares).
| Package | Version | Description |
| -------------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------- |
| @tooark/core | ^1.4.0 | Types, i18n, toast/announce services, motion and overlay helpers |
| @tooark/web-components | ^1.4.0 | The ark-* Custom Elements and their stylesheet |
| react | >=18 (peer) | React 18 or 19 |
| react-dom | >=18 (peer) | React DOM renderer |
🪪 Contributing
Contributions are welcome! Open issues and pull requests in the Tooark/web-components repository; CONTRIBUTING.md covers the workflow, the commit convention and the checklist. @tooark/react is released in lockstep with every other @tooark/* package.
🆘 Help & Security
- ❓ Questions, bugs, feature ideas — see SUPPORT.md for the right channel
- 🔒 Security vulnerabilities — do not open a public issue; follow SECURITY.md
💖 Support
If this project helps your workflow, consider supporting its development:
Every contribution helps keep the project maintained and improving. Thank you! 🙏
📄 License
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
