diff --git a/packages/duoyun-ui/docs/en/01-guide/60-integrate.md b/packages/duoyun-ui/docs/en/01-guide/60-integrate.md
index 6b6648fc..0dd09ba6 100644
--- a/packages/duoyun-ui/docs/en/01-guide/60-integrate.md
+++ b/packages/duoyun-ui/docs/en/01-guide/60-integrate.md
@@ -6,12 +6,81 @@ However, there is no [type hint](https://code.visualstudio.com/docs/editor/intel
## React
> [!NOTE]
-> Only the experimental version of React supports custom elements. Use `npm install react@experimental react-dom@experimental` to install the experimental version of React.
+> Only the React 19 supports custom elements. Use `npm install react@canary react-dom@canary` to install the React 19.
Use DuoyunUI like any other React component library:
+### Use React Component in ``
+
+`` only supports rendering `TemplateResult`:
+
+```ts
+const routes = {
+ about: {
+ pattern: '/about',
+ title: `About`,
+ getContent(_, ele) {
+ return html``;
+ },
+ },
+} satisfies RoutesObject;
+```
+
+To render the React component, need to manually mount it onto the ``:
+
+```ts
+function renderReactNode(ele: any, node: ReactNode) {
+ ele.react?.unmount();
+ ele.react = createRoot(ele);
+ ele.react.render(node);
+}
+
+const routes = {
+ about: {
+ pattern: '/about',
+ title: `About`,
+ getContent(_, ele) {
+ renderReactNode(ele, );
+ },
+ },
+} satisfies RoutesObject;
+```
+
+### Using the React component as Property
+
+Some elements support custom rendering content, such as the `header` of ``:
+
+```ts
+function Page() {
+ return No.`}>;
+}
+```
+
+If want to render the React component, need to first mount it to the `HTMLElement`, which can be achieved through custom Hooks:
+
+```tsx
+function useReactNode(node: ReactNode) {
+ const ref = useRef<{ root: Root; container: HTMLElement }>();
+ useEffect(() => () => ref.current?.root.unmount(), []);
+ if (ref.current) {
+ ref.current.root.render(node);
+ return ref.current.container;
+ }
+ const container = document.createElement('div');
+ container.style.display = 'contents';
+ const root = createRoot(container);
+ ref.current = { root, container };
+ root.render(node);
+ return container;
+}
+
+function Page() {
+ return No>)}>;
+}
+```
+
## Vue
DuoyunUI also exports Vue components, which are used the same as React. The only difference is that the path is changed from `react` to `vue`,
@@ -33,7 +102,7 @@ In the Vue project, it also supports directly writing custom elements, but [dist
DuoyunUI does not re-export as a Svelte component, and you can use the custom element directly:
-
+
> [!NOTE]
> Use the `Sveltekit`, please make sure the `Svelte` is installed as a `dependencies` instead of `DevDependenCies`, otherwise the type cannot be import successfully;
diff --git a/packages/duoyun-ui/docs/zh/01-guide/60-integrate.md b/packages/duoyun-ui/docs/zh/01-guide/60-integrate.md
index 53f2c7d5..33a7d46e 100644
--- a/packages/duoyun-ui/docs/zh/01-guide/60-integrate.md
+++ b/packages/duoyun-ui/docs/zh/01-guide/60-integrate.md
@@ -6,12 +6,81 @@
## React
> [!NOTE]
-> React 的实验版才支持自定义元素,使用 `npm install react@experimental react-dom@experimental` 安装 React 实验版。
+> React 19 才支持自定义元素,当前使用 `npm install react@canary react-dom@canary` 安装 React 19。
跟使用其他 React 组件库一样使用 DuoyunUI:
+### 在 `` 中使用 React 组件
+
+`` 只支持渲染 `TemplateResult`:
+
+```ts
+const routes = {
+ about: {
+ pattern: '/about',
+ title: `About`,
+ getContent(_, ele) {
+ return html``;
+ },
+ },
+} satisfies RoutesObject;
+```
+
+要渲染 React 组件需要手动挂载到 `` 上:
+
+```ts
+function renderReactNode(ele: any, node: ReactNode) {
+ ele.react?.unmount();
+ ele.react = createRoot(ele);
+ ele.react.render(node);
+}
+
+const routes = {
+ about: {
+ pattern: '/about',
+ title: `About`,
+ getContent(_, ele) {
+ renderReactNode(ele, );
+ },
+ },
+} satisfies RoutesObject;
+```
+
+### 在 Property 上使用 React 组件
+
+一些元素支持自定义渲染内容,例如 `` 的 `header`:
+
+```ts
+function Page() {
+ return No.`}>;
+}
+```
+
+如果要渲染 React 组件,则需要先渲染到 `HTMLElement` 上,可以通过自定义 Hooks 实现:
+
+```tsx
+function useReactNode(node: ReactNode) {
+ const ref = useRef<{ root: Root; container: HTMLElement }>();
+ useEffect(() => () => ref.current?.root.unmount(), []);
+ if (ref.current) {
+ ref.current.root.render(node);
+ return ref.current.container;
+ }
+ const container = document.createElement('div');
+ container.style.display = 'contents';
+ const root = createRoot(container);
+ ref.current = { root, container };
+ root.render(node);
+ return container;
+}
+
+function Page() {
+ return No>)}>;
+}
+```
+
## Vue
DuoyunUI 也导出了 Vue 组件,使用和 React 一样,唯一的区别是路径将 `react` 改成 `vue`,
@@ -33,7 +102,7 @@ DuoyunUI 也导出了 Vue 组件,使用和 React 一样,唯一的区别是
DuoyunUI 没有重导出为 Svelte 组件,直接使用自定义元素即可:
-
+
> [!NOTE]
> 使用 `SvelteKit` 请确保 `svelte` 安装成 `dependencies` 而非 `devDependencies`,否则类型不能成功导入;
diff --git a/packages/duoyun-ui/src/elements/card.ts b/packages/duoyun-ui/src/elements/card.ts
index 8fe869eb..1293d5b6 100644
--- a/packages/duoyun-ui/src/elements/card.ts
+++ b/packages/duoyun-ui/src/elements/card.ts
@@ -71,7 +71,8 @@ const style = createCSSSheet(css`
.actions:where(:hover, [data-active], :state(active)) {
background-color: ${theme.hoverBackgroundColor};
}
- slot[name='body']::slotted(*) {
+ slot[name='body']::slotted(*),
+ slot:not([name])::slotted(*) {
hyphens: auto;
margin-block-end: 0em !important;
}
diff --git a/packages/duoyun-ui/src/elements/paragraph.ts b/packages/duoyun-ui/src/elements/paragraph.ts
index a46a4c78..81bf0534 100644
--- a/packages/duoyun-ui/src/elements/paragraph.ts
+++ b/packages/duoyun-ui/src/elements/paragraph.ts
@@ -13,38 +13,31 @@ const style = createCSSSheet(css`
:where(dy-paragraph):where(:lang(zh), :lang(ja), :lang(kr)) {
line-height: 1.7;
}
- :where(gem-link, dy-link):where(:not([hidden])) {
- display: inline-block;
- color: ${theme.primaryColor};
- text-decoration: underline;
- }
- :where(gem-link, dy-link):where(:lang(zh), :lang(ja), :lang(kr)) {
- text-underline-offset: 0.125em;
- }
- ul,
- ol {
- margin-block: 0 1em;
- padding: 0;
- list-style-position: inside;
- }
- li {
- padding-inline-start: 0.5em;
- }
- code,
- kbd {
- font-family: ${theme.codeFont};
- margin-inline: 0.2em;
- padding: 0.15em 0.4em 0.1em;
- font-size: 0.9em;
- border: 1px solid ${theme.borderColor};
- border-radius: ${theme.smallRound};
- }
- code {
- background: ${theme.hoverBackgroundColor};
- }
- kbd {
- background: ${theme.lightBackgroundColor};
- border-bottom-width: 2px;
+ :where(dy-paragraph) {
+ :where(gem-link, dy-link):where(:not([hidden])) {
+ display: inline-block;
+ color: ${theme.primaryColor};
+ text-decoration: underline;
+ }
+ :where(gem-link, dy-link):where(:lang(zh), :lang(ja), :lang(kr)) {
+ text-underline-offset: 0.125em;
+ }
+ code,
+ kbd {
+ font-family: ${theme.codeFont};
+ margin-inline: 0.2em;
+ padding: 0.15em 0.4em 0.1em;
+ font-size: 0.9em;
+ border: 1px solid ${theme.borderColor};
+ border-radius: ${theme.smallRound};
+ }
+ code {
+ background: ${theme.hoverBackgroundColor};
+ }
+ kbd {
+ background: ${theme.lightBackgroundColor};
+ border-bottom-width: 2px;
+ }
}
`);
diff --git a/packages/gem-examples/src/console/index.ts b/packages/gem-examples/src/console/index.ts
index 07ec9574..f94cc9f6 100644
--- a/packages/gem-examples/src/console/index.ts
+++ b/packages/gem-examples/src/console/index.ts
@@ -7,6 +7,8 @@ import { type ContextMenus, type Routes, type UserInfo, type NavItems } from 'du
import 'duoyun-ui/patterns/console';
import 'duoyun-ui/elements/badge';
import 'duoyun-ui/elements/code-block';
+import 'duoyun-ui/elements/paragraph';
+import 'duoyun-ui/elements/card';
import 'duoyun-ui/helper/error';
@@ -57,7 +59,13 @@ const routes = {
about: {
pattern: '/about',
title: `About`,
- content: html`About`,
+ content: html`
+
+
+ Elit aute excepteur dolore occaecat esse F aliqua mollit duis culpa aliqua adipisicing culpa.
+
+
+ `,
},
} satisfies Routes;