v1.3.0¶
使用するvisual-parts-sdkをv1.3.0にアップデートしました。( プロジェクトの情報を取得するAPI が追加されました。これを使ってプロジェクトのUUIDを得ることで、intdash APIを使用してプロジェクトに紐づくリソースを参照することができます。)
複数の依存パッケージを更新しました。
上記パッケージの更新に伴い、webpack、Jestのメジャーバージョンを更新し、一部の設定ファイル、ソースコードを変更しました。詳細については後述の移行手順をご確認ください。
ビジュアルパーツをサーバーにをデプロイするときのNginxの設定を更新しました(デベロッパーガイドの記述のみの更新です)。
v1.2.0からv1.3.0への移行手順¶
data-viz-create-visual-parts-react v1.2.0を使用して作成したワークスペースは、以下の操作を行うことで、v1.3.0を使用して作成したワークスペースと同じ状態にすることができます。
注釈
この移行手順を実行しなくても、v1.2.0以下で作成したビジュアルパーツは継続して使用することが可能です。
作成済みのワークスペースをv1.3.0に合わせたい場合のみ、この以降手順を実行してください。
ワークスペース直下の
package.json
を以下のように更新することで、@data-viz-create-visual-parts-sdkを含む依存パッケージを更新します。package.json
diff --git a/package.json b/package.json index 3205f8e..8ace43a 100644 --- a/package.json +++ b/package.json @@ -58,105 +58,98 @@ "test:watch": "jest --watchAll", "type-watch": "tsc -p . --noEmit --incremental -w" }, - "resolutions": { - "@types/estree": "0.0.50", - "@types/react": "17.0.33", - "@types/react-dom": "17.0.10" - }, "dependencies": { - "@aptpod/data-viz-visual-parts-sdk": "^1.2.0", + "@aptpod/data-viz-visual-parts-sdk": "^1.3.0", "binary-search-bounds": "^2.0.5", "chart.js": "^2.9.4", - "core-js": "3.10.2", - "d3": "^6.6.2", - "react": "17.0.2", + "core-js": "3.26.1", + "d3": "^6.7.0", + "react": "^18.2.0", "react-chartjs-2": "^2.11.2", - "react-dom": "17.0.2", + "react-dom": "^18.2.0", "reboot.css": "1.0.4", - "styled-components": "^5.2.3", + "styled-components": "^5.3.6", "zod": "^1.11.17" }, "devDependencies": { - "@axe-core/react": "4.3.1", - "@babel/core": "7.13.16", - "@babel/eslint-parser": "^7.13.14", - "@babel/eslint-plugin": "^7.13.16", - "@storybook/addon-actions": "6.4.9", - "@storybook/addons": "6.4.9", - "@storybook/core": "^6.4.9", - "@storybook/react": "6.4.9", + "@axe-core/react": "4.5.1", + "@babel/core": "7.20.2", + "@babel/eslint-parser": "^7.19.1", + "@babel/eslint-plugin": "^7.19.1", + "@storybook/addon-actions": "^6.5.13", + "@storybook/addon-essentials": "^6.5.13", + "@storybook/addons": "^6.5.13", + "@storybook/builder-webpack5": "^6.5.13", + "@storybook/core": "^6.5.13", + "@storybook/manager-webpack5": "^6.5.13", + "@storybook/react": "^6.5.13", "@testing-library/react-hooks": "5.1.3", - "@types/babel__core": "7.1.16", + "@types/babel__core": "7.1.20", "@types/browserslist": "4.8.0", "@types/caniuse-lite": "1.0.1", - "@types/chart.js": "^2.9.34", + "@types/chart.js": "^2.9.37", "@types/core-js": "2.5.5", - "@types/d3": "^6.7.5", - "@types/eslint": "7.2.14", - "@types/file-loader": "4.2.1", - "@types/mini-css-extract-plugin": "1.4.3", - "@types/optimize-css-assets-webpack-plugin": "5.0.4", - "@types/prettier": "2.4.1", + "@types/d3": "^7.4.0", + "@types/eslint": "7.29.0", + "@types/file-loader": "^5.0.1", + "@types/jest": "^29.2.3", + "@types/mini-css-extract-plugin": "2.5.0", + "@types/optimize-css-assets-webpack-plugin": "5.0.5", + "@types/prettier": "2.7.1", "@types/progress-bar-webpack-plugin": "2.1.2", - "@types/prop-types": "15.7.4", - "@types/react": "17.0.33", - "@types/react-dom": "17.0.10", - "@types/react-test-renderer": "17.0.1", - "@types/styled-components": "^5.1.15", - "@types/stylelint": "9.10.1", + "@types/prop-types": "15.7.5", + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.9", + "@types/react-test-renderer": "^18.0.0", + "@types/styled-components": "^5.1.26", + "@types/stylelint": "13.13.3", "@types/terser-webpack-plugin": "5.0.4", "@types/testing-library__react-hooks": "3.4.1", - "@types/webpack": "5.28.0", - "@types/webpack-bundle-analyzer": "3.9.4", - "@types/webpack-dev-server": "^3.11.6", + "@types/webpack": "^5.28.0", + "@types/webpack-bundle-analyzer": "^4.6.0", + "@types/webpack-dev-server": "^4.7.2", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", "@typescript-eslint/typescript-estree": "^4.33.0", "babel-eslint": "10.1.0", - "babel-loader": "8.2.3", - "browserslist": "4.17.6", - "caniuse-lite": "1.0.30001271", + "babel-loader": "^9.1.0", + "browserslist": "4.21.4", "cross-env": "^7.0.3", - "css-loader": "5.2.7", - "del-cli": "^3.0.1", - "eslint": "7.24.0", + "css-loader": "^6.7.2", + "del-cli": "^5.0.0", + "eslint": "7.32.0", "eslint-config-prettier": "^7.2.0", "eslint-import-resolver-webpack": "^0.13.2", - "eslint-plugin-compat": "^3.9.0", + "eslint-plugin-compat": "^3.13.0", "eslint-plugin-flowtype": "^5.10.0", - "eslint-plugin-flowtype-errors": "^4.4.0", - "eslint-plugin-import": "^2.22.1", + "eslint-plugin-flowtype-errors": "^4.5.0", + "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^24.7.0", - "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-prettier": "^3.4.1", - "eslint-plugin-react": "^7.23.2", - "eslint-plugin-react-hooks": "^4.2.0", + "eslint-plugin-react": "^7.31.10", + "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-unicorn": "^24.0.0", - "file-loader": "6.2.0", - "html-loader": "2.1.2", + "file-loader": "^6.2.0", + "html-loader": "^4.2.0", "husky": "^4.3.6", - "image-webpack-loader": "7.0.1", - "jest": "26.6.3", + "image-webpack-loader": "^8.1.0", + "jest": "^29.3.1", "lint-staged": "^10.5.4", - "mini-css-extract-plugin": "1.5.1", + "mini-css-extract-plugin": "^2.6.1", "npm-run-all": "4.1.5", - "optimize-css-assets-webpack-plugin": "5.0.8", - "prettier": "2.2.1", + "optimize-css-assets-webpack-plugin": "^6.0.1", + "prettier": "2.7.1", "progress-bar-webpack-plugin": "2.1.0", - "prop-types": "15.7.2", + "prop-types": "15.8.1", "react-storybook-addon-props-combinations": "1.1.0", - "react-test-renderer": "17.0.2", - "reg-keygen-git-hash-plugin": "0.10.17", - "reg-notify-gitlab-plugin": "0.10.17", - "reg-notify-slack-plugin": "0.10.17", - "reg-publish-s3-plugin": "0.10.17", - "reg-suit": "0.10.17", - "regenerator-runtime": "0.13.9", - "sort-package-json": "1.49.0", - "source-map-loader": "^1.1.3", + "react-test-renderer": "18.2.0", + "regenerator-runtime": "0.13.10", + "sort-package-json": "2.1.0", + "source-map-loader": "^4.0.1", "storycap": "3.0.4", - "style-loader": "2.0.0", - "stylelint": "13.12.0", + "style-loader": "^3.3.1", + "stylelint": "13.13.1", "stylelint-a11y": "^1.2.3", "stylelint-config-prettier": "^8.0.2", "stylelint-config-property-sort-order-smacss": "^7.1.0", @@ -164,16 +157,16 @@ "stylelint-config-styled-components": "^0.1.1", "stylelint-no-unsupported-browser-features": "^4.1.4", "stylelint-processor-styled-components": "^1.10.0", - "terser-webpack-plugin": "4.2.3", - "ts-jest": "26.4.4", - "ts-loader": "8.1.0", - "typescript": "^4.5.2", + "terser-webpack-plugin": "^5.3.6", + "ts-jest": "^29.0.3", + "ts-loader": "9.4.1", + "typescript": "^4.9.3", "url-loader": "4.1.1", "utility-types": "^3.10.0", - "webpack": "4.46.0", - "webpack-bundle-analyzer": "4.4.2", - "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.2" + "webpack": "^5.75.0", + "webpack-bundle-analyzer": "4.7.0", + "webpack-cli": "^4.10.0", + "webpack-dev-server": "^4.11.1" }, "engines": { "node": ">=10.23.0"
上記のパッチを適用後、以下のコマンドを実行してパッケージをインストールしてください。
$ npm i
ワークスペース直下にあるwebpackの設定ファイルを以下のように更新します。
webpack.dev.js
diff --git a/webpack.dev.js b/webpack.dev.js index 55f3444..d3d5214 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -24,10 +24,6 @@ module.exports = { 'storybook/src': path.join(__dirname, '.storybook/src'), }, }, - node: { - fs: 'empty', - Buffer: false, - }, module: { rules: [ // js(x) or ts(x) @@ -118,11 +114,13 @@ module.exports = { }, ], devServer: { - writeToDisk: true, - contentBase: path.join(__dirname, 'debug'), + devMiddleware: { + writeToDisk: true, + }, + static: { + directory: path.join(__dirname, 'debug'), + }, port: 8080, compress: true, - // dissable live reloading. - inline: false, }, }
webpack.prod.js
diff --git a/webpack.prod.js b/webpack.prod.js index be7c2e5..93ca950 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -2,9 +2,8 @@ const path = require('path') const webpack = require('webpack') const TerserPlugin = require('terser-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') -const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') - .BundleAnalyzerPlugin +const BundleAnalyzerPlugin = + require('webpack-bundle-analyzer').BundleAnalyzerPlugin const ProgressBarPlugin = require('progress-bar-webpack-plugin') /** @@ -23,6 +22,9 @@ module.exports = { path: path.join(__dirname, 'build'), filename: '[name].js', chunkFilename: '[name].[chunkhash].js', + // 空文字列で固定化。 + // Visual Parts SDK から取得する baseURLを使用してリソースURLを絶対パスに変換するため。 + publicPath: '', }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], @@ -35,10 +37,6 @@ module.exports = { 'scheduler/tracing': 'scheduler/tracing-profiling', }, }, - node: { - fs: 'empty', - Buffer: false, - }, module: { rules: [ // ts or tsx @@ -97,7 +95,6 @@ module.exports = { minimizer: [ // 圧縮 new TerserPlugin({ - cache: false, parallel: true, terserOptions: { output: { @@ -114,7 +111,6 @@ module.exports = { banner: () => LICENSE_TEXT, }, }), - new OptimizeCSSAssetsPlugin({}), ], }, plugins: [ @@ -133,7 +129,7 @@ module.exports = { analyzerMode: 'static', }) : undefined, - ].filter((v) => v), + ].filter(Boolean), performance: { hints: 'warning', },
Storybookの設定ファイルを以下のように更新します。
.storybook/main.js
diff --git a/.storybook/main.js b/.storybook/main.js index 4c1d1f0..bab6727 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,69 +1,31 @@ const path = require('path') -const webpack = require('webpack') module.exports = { stories: ['../src/**/*.stories.tsx'], - addons: ['@storybook/addon-actions/register', 'storycap/register'], - webpackFinal: async (config /*, { configType } */) => { + addons: ['@storybook/addon-essentials'], + framework: '@storybook/react', + core: { + builder: 'webpack5', + }, + typescript: { + check: false, + reactDocgen: false, + }, + reactOptions: { + fastRefresh: true, + }, + webpackFinal: async (config) => { config.node = { - fs: 'empty', __dirname: true, __filename: true, } - config.resolve = { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - alias: { - src: path.join(__dirname, '../src'), - 'storybook/src': path.join(__dirname, './src'), - }, + config.resolve.alias = { + ...config.resolve.alias, + src: path.join(__dirname, '../src'), + 'storybook/src': path.join(__dirname, './src'), } - config.module.rules = config.module.rules - // Remove default CSS loader - .filter((rule) => !rule.test.toString().includes('.css')) - .reduce((acc, rule) => [...acc, rule], [ - // add CSS Modules loader - { - test: /\.css$/, - exclude: /reboot\.css$/, - use: [ - 'style-loader', - { - loader: 'dts-css-modules-loader', - options: { - namedExport: true, - }, - }, - { - loader: 'css-loader', - options: { - sourceMap: true, - modules: { - mode: 'local', - localIdentName: '[folder]__[local]__[hash:base64:5]', - }, - importLoaders: 1, - }, - }, - 'postcss-loader', - ], - }, - // add reboot.css loader - { - test: /reboot\.css$/, - use: ['style-loader', 'css-loader'], - }, - ]) - - config.plugins.push( - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify('development'), - __DEVELOPMENT__: true, - __DEVTOOLS__: true, - }), - ) - return config }, }
.storybook/preview.js
diff --git a/.storybook/preview.js b/.storybook/preview.js index f827a52..157ee35 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,22 +1,12 @@ import 'reboot.css' import React from 'react' import { addDecorator } from '@storybook/react' -import { setDefaults } from 'react-storybook-addon-props-combinations' import { withScreenshot } from 'storycap' -import { FONT_FAMILIES, FONT_LOADER_SPECS } from './src/constant/font' -import { FontStyle } from './src/components/font-style' -import { FontProvider } from './src/components/font-provider' -import { StyledGlobal } from './src/style' - -setDefaults({ - showSource: true, - style: { - padding: '20px', - margin: '10px', - border: '1px solid #dfe2e5', - }, -}) +import { FONT_FAMILIES, FONT_LOADER_SPECS } from 'storybook/src/constant/font' +import { FontStyle } from 'storybook/src/components/font-style' +import { FontProvider } from 'storybook/src/components/font-provider' +import { StyledGlobal } from 'storybook/src/style' addDecorator(withScreenshot) addDecorator((storyFn) => (
ワークスペース直下にあるJestの設定ファイルを以下のように更新します。
jest.config.js
diff --git a/jest.config.js b/jest.config.js index 8b27711..bb48485 100644 --- a/jest.config.js +++ b/jest.config.js @@ -56,11 +56,7 @@ module.exports = { // globalTeardown: null, // A set of global variables that need to be available in all test environments - globals: { - 'ts-jest': { - tsConfig: 'tsconfig.json', - }, - }, + // globals: {} // An array of directory names to be searched recursively up from the requiring module's location // moduleDirectories: [ @@ -159,7 +155,12 @@ module.exports = { // A map from regular expressions to paths to transformers transform: { - '^.+\\.(ts|tsx)$': 'ts-jest', + '^.+\\.(ts|tsx)$': [ + 'ts-jest', + { + tsConfig: 'tsconfig.json', + }, + ], }, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation @@ -178,4 +179,6 @@ module.exports = { // Whether to use watchman for file crawling // watchman: true, + + preset: 'ts-jest', }
React関連のファイルを以下のように更新します。
注釈
これらはReactをv18にアップデートしたことによる更新です。
.storybook/src/components/font-provider/component.tsx
diff --git a/.storybook/src/components/font-provider/component.tsx b/.storybook/src/components/font-provider/component.tsx index 67b88a8..7cab59e 100644 --- a/.storybook/src/components/font-provider/component.tsx +++ b/.storybook/src/components/font-provider/component.tsx @@ -3,9 +3,12 @@ import { FontFamilies } from '@aptpod/data-viz-visual-parts-sdk' import { Context } from './context' -export const FontProvider: React.FC<{ fontFamilies: FontFamilies }> = ( - props, -) => { +type Props = { + fontFamilies: FontFamilies + children: React.ReactNode +} + +export const FontProvider: React.FC<Props> = (props) => { return ( <Context.Provider value={props.fontFamilies}> {props.children}
src/utils/components/transform/scale/component.tsx
diff --git a/src/utils/components/transform/scale/component.tsx b/src/utils/components/transform/scale/component.tsx index 97d64d6..334057b 100644 --- a/src/utils/components/transform/scale/component.tsx +++ b/src/utils/components/transform/scale/component.tsx @@ -8,6 +8,7 @@ type Props = { originalHeight: number width: number height: number + children: React.ReactNode } export const Scale: FC<Props> = memo((props) => {
以下4つのファイルでは、react-dom v18へのマイグレーションのために同じ修正を行います。
src/entrypoint/samples/horizontal-bars/index.tsx
diff --git a/src/entrypoint/samples/horizontal-bars/index.tsx b/src/entrypoint/samples/horizontal-bars/index.tsx index 40e40c9..f4720b3 100644 --- a/src/entrypoint/samples/horizontal-bars/index.tsx +++ b/src/entrypoint/samples/horizontal-bars/index.tsx @@ -5,7 +5,7 @@ import { ExposerEvent, } from '@aptpod/data-viz-visual-parts-sdk' import React from 'react' -import { render, unmountComponentAtNode } from 'react-dom' +import { createRoot, Root } from 'react-dom/client' // Shadow DOM に適用するStyle import { StyledShadowStyle } from '../../../styles/shadow' @@ -45,13 +45,15 @@ const metadata: Metadata = { * Renderer クラスを継承したPluginRendererを定義します。 */ class PluginRenderer extends Renderer { + private root: Root | undefined + /** * 描画を実行します。 1回だけコールします。 * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。 */ - // eslint-disable-next-line class-methods-use-this render(el: HTMLElement, comm: ExposerEvent) { - render( + this.root = createRoot(el) + this.root.render( <StyleSheetManagerWrapper> {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */} <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}> @@ -61,16 +63,16 @@ class PluginRenderer extends Renderer { </> </ReactProfilerWrapper> </StyleSheetManagerWrapper>, - el, ) } /** - * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 - * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。 + * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 + * + * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。 */ - // eslint-disable-next-line class-methods-use-this - dispose(el: HTMLElement) { - unmountComponentAtNode(el) + dispose(_el: HTMLElement) { + this.root?.unmount() + this.root = undefined } }
src/entrypoint/samples/line-graph/index.tsx
diff --git a/src/entrypoint/samples/line-graph/index.tsx b/src/entrypoint/samples/line-graph/index.tsx index 19e9605..e850fdf 100644 --- a/src/entrypoint/samples/line-graph/index.tsx +++ b/src/entrypoint/samples/line-graph/index.tsx @@ -5,7 +5,7 @@ import { ExposerEvent, } from '@aptpod/data-viz-visual-parts-sdk' import React from 'react' -import { render, unmountComponentAtNode } from 'react-dom' +import { createRoot, Root } from 'react-dom/client' // Shadow DOM に適用するStyle import { StyledShadowStyle } from '../../../styles/shadow' @@ -44,13 +44,15 @@ const metadata: Metadata = { * Renderer クラスを継承したPluginRendererを定義します。 */ class PluginRenderer extends Renderer { + private root: Root | undefined + /** * 描画を実行します。 1回だけコールします。 * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。 */ - // eslint-disable-next-line class-methods-use-this render(el: HTMLElement, comm: ExposerEvent) { - render( + this.root = createRoot(el) + this.root.render( <StyleSheetManagerWrapper> {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */} <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}> @@ -60,16 +62,16 @@ class PluginRenderer extends Renderer { </> </ReactProfilerWrapper> </StyleSheetManagerWrapper>, - el, ) } /** - * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 - * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。 + * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 + * + * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。 */ - // eslint-disable-next-line class-methods-use-this - dispose(el: HTMLElement) { - unmountComponentAtNode(el) + dispose(_el: HTMLElement) { + this.root?.unmount() + this.root = undefined } }
src/entrypoint/samples/sensor-value/index.tsx
diff --git a/src/entrypoint/samples/sensor-value/index.tsx b/src/entrypoint/samples/sensor-value/index.tsx index 1054a2e..6fbcc0a 100644 --- a/src/entrypoint/samples/sensor-value/index.tsx +++ b/src/entrypoint/samples/sensor-value/index.tsx @@ -5,7 +5,7 @@ import { ExposerEvent, } from '@aptpod/data-viz-visual-parts-sdk' import React from 'react' -import { render, unmountComponentAtNode } from 'react-dom' +import { createRoot, Root } from 'react-dom/client' // Shadow DOM に適用するStyle import { StyledShadowStyle } from '../../../styles/shadow' @@ -43,14 +43,15 @@ const metadata: Metadata = { * Renderer クラスを継承したPluginRendererを定義します。 */ class PluginRenderer extends Renderer { + private root: Root | undefined + /** * 描画を実行します。 1回だけコールします。 * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。 */ - // eslint-disable-next-line class-methods-use-this render(el: HTMLElement, comm: ExposerEvent) { - // Reactを使用した描画 - render( + this.root = createRoot(el) + this.root.render( <StyleSheetManagerWrapper> {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */} <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}> @@ -60,16 +61,16 @@ class PluginRenderer extends Renderer { </> </ReactProfilerWrapper> </StyleSheetManagerWrapper>, - el, ) } /** - * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 - * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。 + * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 + * + * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。 */ - // eslint-disable-next-line class-methods-use-this - dispose(el: HTMLElement) { - unmountComponentAtNode(el) + dispose(_el: HTMLElement) { + this.root?.unmount() + this.root = undefined } }
src/entrypoint/samples/time-series-text/index.tsx
diff --git a/src/entrypoint/samples/time-series-text/index.tsx b/src/entrypoint/samples/time-series-text/index.tsx index fbe5d50..ffe9d20 100644 --- a/src/entrypoint/samples/time-series-text/index.tsx +++ b/src/entrypoint/samples/time-series-text/index.tsx @@ -5,7 +5,7 @@ import { ExposerEvent, } from '@aptpod/data-viz-visual-parts-sdk' import React from 'react' -import { render, unmountComponentAtNode } from 'react-dom' +import { createRoot, Root } from 'react-dom/client' // Shadow DOM に適用するStyle import { StyledShadowStyle } from '../../../styles/shadow' @@ -44,13 +44,15 @@ const metadata: Metadata = { * Renderer クラスを継承したPluginRendererを定義します。 */ class PluginRenderer extends Renderer { + private root: Root | undefined + /** * 描画を実行します。 1回だけコールします。 * 状態を変更する場合は、 ExposerEvent のイベントを利用し、 element のDOMを再描画します。 */ - // eslint-disable-next-line class-methods-use-this render(el: HTMLElement, comm: ExposerEvent) { - render( + this.root = createRoot(el) + this.root.render( <StyleSheetManagerWrapper> {/* comm.renderingProfile は Data Visualizer v3.3.0 以降で利用可能です。 */} <ReactProfilerWrapper onProfile={comm.renderingProfile?.emit}> @@ -60,16 +62,16 @@ class PluginRenderer extends Renderer { </> </ReactProfilerWrapper> </StyleSheetManagerWrapper>, - el, ) } /** - * element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 - * HTMLElement は、 render メソッドに引数として渡された HTMLElement (コンテナ)と同じです。 + * render メソッドで指定した element に紐づく子要素のDOMや子要素のイベントハンドラを解放します。 + * + * ※ 引数の _el は React v18 に更新したことで、引数 el は使用しなくなりましたが、互換性を維持するため引数の定義は現状維持となっています。 */ - // eslint-disable-next-line class-methods-use-this - dispose(el: HTMLElement) { - unmountComponentAtNode(el) + dispose(_el: HTMLElement) { + this.root?.unmount() + this.root = undefined } }