{
  "name": "frameworks/react",
  "title": "React",
  "description": "Tips for using eurodata-ui in your React app.",
  "docs": "https://test-apps.eurodata.de/a/eurodata-ui/docs/frameworks/react/",
  "sections": [
    {
      "heading": "React",
      "markdown": ""
    },
    {
      "heading": "Installation",
      "markdown": "Add the package to your React app:\n\n```bash\npnpm add @eurodata/eurodata-ui\n```\n\nThen import the stylesheet **once** in your app's entry file (`main.tsx`, `index.tsx`, …):\n\n```ts\n// src/main.tsx\nimport '@eurodata/eurodata-ui/dist/styles/eurodata.css';\n```\n\nHow you import and use the components themselves depends on your React version. Jump to the section that matches your project:\n\n-   **React 19 and above** — use components natively. See [Using with React 19 and Above](https://test-apps.eurodata.de/a/eurodata-ui/docs/frameworks/react/#using-with-react-19-and-above).\n-   **React 18 and below** — use the bundled React wrappers. See [Using with React 18 and Below](https://test-apps.eurodata.de/a/eurodata-ui/docs/frameworks/react/#using-with-react-18-and-below)."
    },
    {
      "heading": "Using with React 19 and Above",
      "markdown": "React 19+ [supports custom elements](https://react.dev/blog/2024/04/25/react-19#support-for-custom-elements) natively, so you can use eurodata-ui components just like any other HTML element — no wrappers needed.\n\nEach component you want to use needs to be imported **once per app**, next to the stylesheet in your entry file:\n\n```ts\n// src/main.tsx\nimport '@eurodata/eurodata-ui/dist/styles/eurodata.css';\nimport '@eurodata/eurodata-ui/dist/components/button/button.js';\n```\n\nAfter that, the custom element is registered globally and you can use it from anywhere in your app:\n\n```jsx\nexport default function App() {\n  return <ed-button variant=\"brand\">Button</ed-button>;\n}\n```\n\nAs the list of components grows, you may want to keep your entry file tidy by collecting all eurodata-ui imports in a dedicated file:\n\n```ts\n// src/eurodata-ui.ts\nimport '@eurodata/eurodata-ui/dist/styles/eurodata.css';\nimport '@eurodata/eurodata-ui/dist/components/button/button.js';\nimport '@eurodata/eurodata-ui/dist/components/input/input.js';\n// …add more components here as you adopt them\n```\n\nThen import that file once from your entry:\n\n```ts\n// src/main.tsx\nimport './eurodata-ui';\n```\n\n### TypeScript\n\nYou can add type safety using the types file included with eurodata-ui.\n\n```\nnode_modules/@eurodata/eurodata-ui/dist/custom-elements-jsx.d.ts\n```\n\nThis gives you inline documentation, autocomplete, and type-safe validation for every component. Add the types to your project by updating your `tsconfig.json` file.\n\n```json\n{\n  \"compilerOptions\": {\n    \"types\": [\"@eurodata/eurodata-ui/dist/custom-elements-jsx.d.ts\"]\n  }\n}\n```\n\n### Event Handling\n\nMany eurodata-ui components emit [native events](https://developer.mozilla.org/en-US/docs/Web/API/Event). For example, the [input component](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/input) emits the `input` event when it receives input. In React, you can listen for the event using `onInput`.\n\nHere's how you can bind the input's value to a state variable.\n\n```jsx\nimport { useState } from 'react';\n\nfunction MyComponent() {\n  const [value, setValue] = useState('');\n\n  return <ed-input value={value} onInput={event => setValue(event.target.value)} />;\n}\n\nexport default MyComponent;\n```\n\nIf you're using TypeScript, `event.target` will be a reference to the underlying custom element. You can strongly type the event target as shown below.\n\n```tsx\nimport { useState } from 'react';\nimport type EdInputElement from '@eurodata/eurodata-ui/dist/components/input/input.js';\n\nfunction MyComponent() {\n  const [value, setValue] = useState('');\n\n  return <ed-input value={value} onInput={event => setValue((event.target as EdInputElement).value)} />;\n}\n\nexport default MyComponent;\n```\n\neurodata-ui also emits its own custom events such as `ed-show`, `ed-hide`, and `ed-alert-dialog-confirm`. React 19 lets you bind these directly with a JSX prop following the lowercase `on<event-name>` convention — for example, the `ed-alert-dialog-confirm` event maps to the `oned-alert-dialog-confirm` prop:\n\n```tsx\nfunction MyComponent({ onConfirm, onCancel }: { onConfirm: () => void; onCancel: () => void }) {\n  return (\n    <ed-alert-dialog\n      type=\"warning\"\n      label=\"Delete user?\"\n      oned-alert-dialog-confirm={onConfirm}\n      oned-alert-dialog-cancel={onCancel}\n    >\n      This action is permanent.\n    </ed-alert-dialog>\n  );\n}\n```\n\nEvery eurodata-ui custom event has a corresponding `oned-*` prop typed in `custom-elements-jsx.d.ts`, so once you've completed the [TypeScript setup](https://test-apps.eurodata.de/a/eurodata-ui/docs/frameworks/react/#typescript) above you'll get autocomplete and type checking for them."
    },
    {
      "heading": "Using with React 18 and Below",
      "markdown": "React 18 and below have [limited support](https://custom-elements-everywhere.com/#react) for custom elements. For these versions, eurodata-ui ships React wrappers for every component, built with [`@lit/react`](https://lit.dev/docs/frameworks/react/). Wrappers are regular React components — fully typed out of the box, so no JSX type setup is needed.\n\n### Using a Wrapper\n\nImport the `<EdButton>` React component instead of the raw `<ed-button>` custom element:\n\n```jsx\nimport EdButton from '@eurodata/eurodata-ui/dist/react/button/index.js';\n\nconst MyComponent = () => <EdButton variant=\"brand\">Click me</EdButton>;\n\nexport default MyComponent;\n```\n\nUnlike the raw custom elements, wrappers are imported **per file** — wherever you render the component, just like any other React component. The wrapper takes care of registering the underlying custom element on first import, so you don't need a separate side-effect import.\n\nYou can find the React import path for each component in the _Importing_ section of its documentation.\n\nA barrel re-export of every wrapper is also available at `@eurodata/eurodata-ui/dist/react`:\n\n```jsx\nimport { EdButton, EdInput } from '@eurodata/eurodata-ui/dist/react';\n```\n\nThis is convenient for quick scripts and prototypes, but it **disables tree-shaking** — the barrel pulls in every component the library ships, regardless of how many you actually use. Prefer the per-component import path for production apps.\n\n### Event Handling with Wrappers\n\n```jsx\nimport { useState } from 'react';\nimport EdInput from '@eurodata/eurodata-ui/dist/react/input/index.js';\n\nfunction MyComponent() {\n  const [value, setValue] = useState('');\n\n  return <EdInput value={value} onInput={event => setValue(event.target.value)} />;\n}\n\nexport default MyComponent;\n```\n\nFor TypeScript, you can strongly type the event target:\n\n```tsx\nimport { useState } from 'react';\nimport EdInput from '@eurodata/eurodata-ui/dist/react/input/index.js';\nimport type EdInputElement from '@eurodata/eurodata-ui/dist/components/input/input.js';\n\nfunction MyComponent() {\n  const [value, setValue] = useState('');\n\n  return <EdInput value={value} onInput={event => setValue((event.target as EdInputElement).value)} />;\n}\n\nexport default MyComponent;\n```\n\nCustom events emitted by eurodata-ui components (e.g. `ed-show`, `ed-hide`, `ed-alert-dialog-confirm`) are exposed as **camelCased React props** on the wrapper — `ed-show` becomes `onEdShow`, `ed-alert-dialog-confirm` becomes `onEdAlertDialogConfirm`, and so on. Each event is typed using the event types re-exported from `@eurodata/eurodata-ui/dist/events/events.js`:\n\n```tsx\nimport EdDrawer from '@eurodata/eurodata-ui/dist/react/drawer/index.js';\nimport type { EdShowEvent } from '@eurodata/eurodata-ui/dist/events/events.js';\n\nfunction MyComponent() {\n  const handleShow = (event: EdShowEvent) => {\n    // …\n  };\n\n  return <EdDrawer onEdShow={handleShow} label=\"My drawer\">…</EdDrawer>;\n}\n```\n\nLifecycle handlers such as `onEdShow` and `onEdHide` fire only for the component they're set on — these events don't bubble (see [Event bubbling](https://test-apps.eurodata.de/a/eurodata-ui/docs/usage/#bubbling)). An `onEdHide` on a dialog is therefore **not** triggered when a nested `EdSelect` closes its menu, so you can wire it directly to close the dialog."
    }
  ]
}
