# Framework integration A4ui ships **SolidJS** components. There are two ways to use it, depending on your stack: | Your stack | How | Notes | | -------------------------------------------------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | **Vite + Solid** | Native components | The default. Everything works. | | **SolidStart** (SSR) | Native components | Server-rendered via the `solid` export condition; a few client-only backdrops (see [SSR](#server-side-rendering-ssr)). | | **Astro** | Native components as Solid islands | Via `@astrojs/solid-js`. | | **React / Next.js**, **Vue**, **Svelte**, **plain HTML** | [**Web Components**](#web-components-react-nextjs-vue-vanilla) | Solid components can't run inside React/Vue directly — use the framework‑agnostic custom elements. | > **Honest heads‑up:** a Solid component (` ) ``` --- ## SolidStart Same install and Tailwind preset as above. Import the stylesheet once in your root layout (`src/root.tsx` or `app.tsx`): ```tsx import '@a4ui/core/styles.css' ``` Then use the components anywhere. The design tokens and layout render on the server fine; interactive/portalled components hydrate on the client. ### Server-side rendering (SSR) A4ui ships a **`solid` export condition** pointing at its source, so Solid's compiler (SolidStart, or any `vite-plugin-solid` app) compiles the components for **both server and client** — the components **render on the server**, then hydrate. (Non-Solid tooling falls back to the precompiled `import`/`default` browser build.) Importing the package on the server is safe: `theme`, `effects` and motion **don't touch the DOM at module load**. - Most components SSR fine — Kobalte is SSR-safe, and anything using `onMount`, `IntersectionObserver`, `matchMedia`, or rAF simply runs after hydration. - A few are inherently **client-only** — the starfield/scenery backdrops (`SpaceBackground`, `ThemedScenery`, `SnowScenery`, `ChristmasBackground`) build their DOM imperatively. Wrap those with SolidStart's `clientOnly`: ```tsx import { clientOnly } from '@solidjs/start' const SpaceBackground = clientOnly(() => import('@a4ui/core').then((m) => ({ default: m.SpaceBackground }))) ``` --- ## Astro Add the Solid integration and Tailwind: ```bash npm i @a4ui/core solid-js npx astro add solid tailwind ``` Register the preset in `tailwind.config.mjs`: ```js import a4ui from '@a4ui/core/preset' export default { presets: [a4ui], content: ['./src/**/*.{astro,ts,tsx,mdx}', './node_modules/@a4ui/core/dist/**/*.js'], } ``` Import the stylesheet in your layout's frontmatter (or a global CSS entry): ```astro --- import '@a4ui/core/styles.css' --- ``` Write a small Solid component and drop it into `.astro` as an island. Use `client:only="solid-js"` for interactive components (Kobalte behavior needs the client): ```tsx // src/components/SaveButton.tsx import { Button } from '@a4ui/core' export default () => ``` ```astro --- import SaveButton from '../components/SaveButton.tsx' --- ``` Static, non‑interactive components (`Badge`, `Card`, `Stat`) can use `client:load` or render at build time. --- ## Web Components (React, Next.js, Vue, vanilla) For any non‑Solid framework, A4ui ships a **self‑contained Web Components bundle** — Solid is compiled in, so there's no Solid toolchain to set up. A curated set of presentational components is registered as custom elements. ```bash npm i @a4ui/core ``` ```js import '@a4ui/core/elements' // registers , , … (side effect) import '@a4ui/core/elements.css' // precompiled styles (no Tailwind needed) ``` Or straight from a CDN in plain HTML: ```html ``` ### Available elements `a4-button` · `a4-badge` · `a4-alert` · `a4-spinner` · `a4-avatar` · `a4-progress` · `a4-meter` · `a4-ring-progress` · `a4-stat` · `a4-kbd` · `a4-separator` · `a4-rating` · `a4-countdown` · `a4-clock` · `a4-condition-scale` · `a4-announcement-bar` Props map to attributes (kebab‑case, coerced by type). Text goes in a `label` attribute (or between the tags). `a4-alert` uses `heading` (not `title`, which collides with the native HTML attribute). `a4-rating` emits a `change` event with the new value in `event.detail`. > Rich, interactive, or portalled components (Modal, Combobox, DataGrid, Drawer, …) are **not** wrapped as elements — for those, use the native Solid components in a Solid app. ### React / Next.js Custom elements work in JSX; register them once (e.g. in a client component or `_app`): ```tsx 'use client' import '@a4ui/core/elements' import '@a4ui/core/elements.css' export function Toolbar() { const ref = useRef(null) useEffect(() => { const el = ref.current const onChange = (e: Event) => console.log('rating', (e as CustomEvent).detail) el?.addEventListener('change', onChange) return () => el?.removeEventListener('change', onChange) }, []) return (
{/* @ts-expect-error — custom element */} {/* @ts-expect-error — custom element */}
) } ``` In **Next.js**, the import must run in a Client Component (`'use client'`) because it registers browser custom elements. ### Vue Tell Vue which tags are custom elements (`vite.config`: `vueCompilerOptions.isCustomElement = tag => tag.startsWith('a4-')`), import the bundle once, then use the tags in templates. Attributes and `@change` work as usual. ### Vanilla / any framework Include the two files (script + CSS) and write the tags. That's it.