Skip to content

Commit ab44661

Browse files
authored
Merge pull request #1 from duenyang/feature/react
feat(react): 支持在React中调用update
2 parents b95b016 + 732d34d commit ab44661

File tree

7 files changed

+47
-121
lines changed

7 files changed

+47
-121
lines changed

package-lock.json

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"site:intranet": "cd site && vite build --mode intranet",
1515
"site:preview": "cd site && vite build --mode preview && cd ../_site && cp index.html 404.html",
1616
"prebuild": "rimraf es/* lib/* dist/* esm/*",
17-
"build": "cross-env NODE_ENV=production rollup -c script/rollup.config.js",
17+
"build": "npm run generate:entry && cross-env NODE_ENV=production rollup -c script/rollup.config.js",
1818
"build:tsc": "run-p build:tsc-*",
1919
"build:tsc-lib": "tsc --emitDeclarationOnly -d -p ./tsconfig.build.json --outDir lib/",
2020
"build:tsc-esm": "tsc --emitDeclarationOnly -d -p ./tsconfig.build.json --outDir esm/",
@@ -71,7 +71,7 @@
7171
"lodash": "~4.17.15",
7272
"omi-transition": "^0.1.11",
7373
"tailwind-merge": "^2.2.1",
74-
"tdesign-icons-web-components": "^0.1.5"
74+
"tdesign-icons-web-components": "^0.2.0"
7575
},
7676
"devDependencies": {
7777
"@babel/core": "^7.24.7",

script/generate-entry.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const components = fs.readdirSync(componentsPath).filter((name) => {
1616
return false;
1717
});
1818

19-
const code = components.reduce((pre, next) => `${pre}export * from './${next}';\n`, '');
19+
const code = components.reduce((pre, next) => `${pre}export * from './${next.replace(/\.ts/, '')}';\n`, '');
2020

2121
fs.writeFileSync(path.resolve(componentsPath, 'index.ts'), code, {
2222
encoding: 'utf-8',

site/docs/getting-started.md

+13-4
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,31 @@ export default defineConfig({
6969

7070
```javascript
7171
import { renderReact } from 'tdesign-web-components';
72+
import type { ExtendedElement } from 'tdesign-web-components';
7273
```
7374

7475
在React项目中使用
7576

7677
```javascript
7778
const App: React.FC = () => {
7879
const ref = React.useRef<HTMLDivElement>(null);
80+
const tdComponent = React.useRef<ExtendedElement>();
81+
82+
const changeTheme = () => {
83+
if(!tdComponent.current) return;
84+
tdComponent.current.props.theme = 'danger';
85+
tdComponent.current.update(); // 调用update更新对应的组件
86+
}
87+
7988
React.useEffect(() => {
80-
if (ref.current) {
81-
renderReact(<t-button>BUTTON</t-button>, ref.current)
82-
}
89+
tdComponent.current = renderReact(<t-button theme={'primary'}>BUTTON</t-button>, ref.current);
8390
}, [])
8491

8592

8693
return (
87-
<div ref={ref}></div>
94+
<div ref={ref}>
95+
<button onClick={changeTheme}>点击我切换主题</button>
96+
</div>
8897
)
8998
}
9099
```

site/index.html

-102
Original file line numberDiff line numberDiff line change
@@ -13,108 +13,6 @@
1313
</head>
1414
<body>
1515
<div id="app"></div>
16-
<script>
17-
// 主题方案采用css变量,此处先注释
18-
// document.addEventListener('DOMContentLoaded', function () {
19-
// try {
20-
// if (
21-
// localStorage.theme === "dark" ||
22-
// (!("theme" in localStorage) &&
23-
// window.matchMedia("(prefers-color-scheme: dark)").matches)
24-
// ) {
25-
// walkDOMAndToggleDark(document.body, false)
26-
// document.documentElement.classList.add("dark");
27-
// } else {
28-
// walkDOMAndToggleDark(document.body, true)
29-
// document.documentElement.classList.remove("dark");
30-
// }
31-
// } catch (_) { }
32-
// })
33-
34-
35-
// function toggleNodeDark(node, isDark) {
36-
// if (
37-
// node instanceof HTMLElement &&
38-
// node.tagName.toLowerCase().indexOf("-") !== -1
39-
// ) {
40-
// if (isDark) {
41-
// node.classList.remove("dark");
42-
// } else {
43-
// node.classList.add("dark");
44-
// }
45-
46-
// }
47-
// }
48-
49-
// function walkDOMAndToggleDark(rootNode, isDark) {
50-
// if (isDark) {
51-
// document.documentElement.classList.remove("dark");
52-
// } else {
53-
// document.documentElement.classList.add("dark");
54-
// }
55-
// const treeWalker = document.createTreeWalker(
56-
// rootNode,
57-
// NodeFilter.SHOW_ELEMENT,
58-
// null,
59-
// false
60-
// );
61-
62-
// while (treeWalker.nextNode()) {
63-
// const node = treeWalker.currentNode;
64-
// toggleNodeDark(node, isDark);
65-
66-
// // Check if the node has a shadow root
67-
// if (node.shadowRoot) {
68-
// walkDOMAndToggleDark(node.shadowRoot, isDark);
69-
// }
70-
71-
// // Check if the node has assigned nodes (for slots)
72-
// if (node.assignedNodes) {
73-
// node.assignedNodes().forEach((assignedNode) => {
74-
// if (assignedNode.nodeType === Node.ELEMENT_NODE) {
75-
// walkDOMAndToggleDark(assignedNode, isDark);
76-
// }
77-
// });
78-
// }
79-
// }
80-
// }
81-
82-
// function toggleDark() {
83-
// if (document.documentElement.classList.contains("dark")) {
84-
// localStorage.theme = "light";
85-
// walkDOMAndToggleDark(document.body, true)
86-
// document.documentElement.classList.remove("dark");
87-
// } else {
88-
// localStorage.theme = "dark";
89-
// walkDOMAndToggleDark(document.body, false)
90-
// document.documentElement.classList.add("dark");
91-
// }
92-
// }
93-
94-
// function setDarkMode() {
95-
// localStorage.theme = "dark";
96-
// walkDOMAndToggleDark(document.body, false)
97-
// document.documentElement.classList.add("dark");
98-
// }
99-
100-
// function setLightMode() {
101-
// localStorage.theme = "light";
102-
// walkDOMAndToggleDark(document.body, true)
103-
// document.documentElement.classList.remove("dark");
104-
// }
105-
106-
// function refreshDark() {
107-
// if (document.documentElement.classList.contains("dark")) {
108-
// walkDOMAndToggleDark(document.body, false)
109-
// } else {
110-
// walkDOMAndToggleDark(document.body, true)
111-
// }
112-
// }
113-
114-
// window.addEventListener('load', function() {
115-
// refreshDark()
116-
// })
117-
</script>
11816
<script type="module" src="/main.tsx"></script>
11917
</body>
12018
</html>

src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export * from './popup';
2828
export * from './progress';
2929
export * from './radio';
3030
export * from './range-input';
31-
export * from './react.ts';
31+
export * from './react';
3232
export * from './select';
3333
export * from './select-input';
3434
export * from './skeleton';

src/react.ts

+22-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,27 @@
22
* 在React环境中使用的兼容方法
33
*/
44

5-
import { render } from 'omi';
5+
import { Component, render } from 'omi';
6+
7+
export type ExtendedElement = (HTMLElement | SVGAElement | HTMLInputElement) & {
8+
receiveProps: Function;
9+
update: Function;
10+
queuedUpdate: Function;
11+
store?: unknown;
12+
className?: string;
13+
props: Record<string, unknown>;
14+
splitText?: Function;
15+
prevProps?: Record<string, unknown> & {
16+
ref?:
17+
| {
18+
current?: unknown;
19+
}
20+
| Function;
21+
};
22+
attributes: NamedNodeMap;
23+
_component?: Component;
24+
_listeners: Record<string, Function>;
25+
} & Record<string, unknown>;
626

727
const convertReactToOmi = (r: any): Omi.ComponentChild => {
828
if (!r) return r;
@@ -49,8 +69,7 @@ const convertReactToOmi = (r: any): Omi.ComponentChild => {
4969
* @param reactVNode react的vnode结构
5070
* @param root 需要挂载的html
5171
*/
52-
const renderReact = <T = any>(reactVNode: T, root: HTMLElement) => {
72+
const renderReact = <T = any>(reactVNode: T, root: HTMLElement): ExtendedElement =>
5373
render(convertReactToOmi(reactVNode), root);
54-
};
5574

5675
export { renderReact, convertReactToOmi };

0 commit comments

Comments
 (0)