v1.4.0¶
data-viz-visual-parts-sdkをv1.4.0にアップデートしました。 (Data Visualizerから取得するFont FamiliesのAPIにYotsuya Sans JPフォントを追加し、Axis ProNのフォントを非推奨に変更しました。)
サポートするNode.jsのバージョンを16.20.0以上にしました。
複数の依存パッケージを更新しました。
上記パッケージの更新に伴い、一部のソースコードを変更しました。
ビジュアルパーツのサンプルコードに含まれるextension.tsにおけるExtension型オブジェクトの解析方法を改善しました。
機能していないreboot.cssの定義を削除しました。
サーバー設定に関するデベロッパーガイドの記述を更新しました。
v.1.3.0からv1.4.0への移行手順¶
data-viz-create-visual-parts-react v1.3.0を使用して作成したワークスペースは、以下の操作を行うことで、v1.4.0を使用して作成したワークスペースと同じ状態にすることができます。
注釈
この移行手順を実行しなくても、v1.3.0以下で作成したビジュアルパーツは継続して使用することが可能です。
作成済みのワークスペースをv.1.4.0に合わせたい場合のみ、この以降手順を実行してください。
ワークスペース直下の
package.json
を以下のように更新します。package.json
diff --git a/package.json b/package.json index f93ee78..9900417 100644 --- a/package.json +++ b/package.json @@ -56,35 +56,37 @@ "test": "run-s test:watch", "test:once": "jest", "test:watch": "jest --watchAll", - "type-watch": "tsc -p . --noEmit --incremental -w" + "type-watch": "tsc -p . --noEmit --incremental -w", + "test:webpack-dev": "webpack --config webpack.dev.js" }, "dependencies": { - "@aptpod/data-viz-visual-parts-sdk": "^1.3.0", + "@aptpod/data-viz-visual-parts-sdk": "^1.4.0", "binary-search-bounds": "^2.0.5", - "chart.js": "^2.9.4", - "core-js": "3.26.1", + "chart.js": "^4.3.0", + "chartjs-adapter-date-fns": "^3.0.0", + "core-js": "3.31.0", "d3": "^6.7.0", + "date-fns": "^2.30.0", "react": "^18.2.0", - "react-chartjs-2": "^2.11.2", + "react-chartjs-2": "5.2.0", "react-dom": "^18.2.0", - "reboot.css": "1.0.4", - "styled-components": "^5.3.6", - "zod": "^1.11.17" + "styled-components": "^5.3.11", + "zod": "^3.21.4" }, "devDependencies": { - "@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", + "@axe-core/react": "4.7.3", + "@babel/core": "7.22.5", + "@babel/eslint-parser": "^7.22.5", + "@babel/eslint-plugin": "^7.22.5", + "@storybook/addon-actions": "^6.5.16", + "@storybook/addon-essentials": "^6.5.16", + "@storybook/addons": "^6.5.16", + "@storybook/builder-webpack5": "^6.5.16", + "@storybook/core": "^6.5.16", + "@storybook/manager-webpack5": "^6.5.16", + "@storybook/react": "^6.5.16", "@testing-library/react-hooks": "5.1.3", - "@types/babel__core": "7.1.20", + "@types/babel__core": "7.20.1", "@types/browserslist": "4.8.0", "@types/caniuse-lite": "1.0.1", "@types/chart.js": "^2.9.37", @@ -92,30 +94,29 @@ "@types/d3": "^7.4.0", "@types/eslint": "7.29.0", "@types/file-loader": "^5.0.1", - "@types/jest": "^29.2.3", + "@types/jest": "^29.5.2", "@types/mini-css-extract-plugin": "2.5.0", - "@types/optimize-css-assets-webpack-plugin": "5.0.5", - "@types/prettier": "2.7.1", + "@types/prettier": "2.7.3", "@types/progress-bar-webpack-plugin": "2.1.2", "@types/prop-types": "15.7.5", - "@types/react": "^18.0.25", - "@types/react-dom": "^18.0.9", + "@types/react": "^18.2.12", + "@types/react-dom": "^18.2.5", "@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": "^5.28.1", "@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", + "@typescript-eslint/eslint-plugin": "^5.59.11", + "@typescript-eslint/parser": "^5.59.11", + "@typescript-eslint/typescript-estree": "^5.59.11", "babel-eslint": "10.1.0", - "babel-loader": "^9.1.0", - "browserslist": "4.21.4", + "babel-loader": "^9.1.2", + "browserslist": "4.21.9", "cross-env": "^7.0.3", - "css-loader": "^6.7.2", + "css-loader": "^6.8.1", "del-cli": "^5.0.0", "eslint": "7.32.0", "eslint-config-prettier": "^7.2.0", @@ -123,32 +124,30 @@ "eslint-plugin-compat": "^3.13.0", "eslint-plugin-flowtype": "^5.10.0", "eslint-plugin-flowtype-errors": "^4.5.0", - "eslint-plugin-import": "^2.26.0", + "eslint-plugin-import": "^2.27.5", "eslint-plugin-jest": "^24.7.0", - "eslint-plugin-jsx-a11y": "^6.6.1", + "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-prettier": "^3.4.1", - "eslint-plugin-react": "^7.31.10", + "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-unicorn": "^24.0.0", "file-loader": "^6.2.0", "html-loader": "^4.2.0", "husky": "^4.3.6", "image-webpack-loader": "^8.1.0", - "jest": "^29.3.1", - "lint-staged": "^10.5.4", - "mini-css-extract-plugin": "^2.6.1", + "jest": "^29.5.0", + "lint-staged": "^13.2.2", + "mini-css-extract-plugin": "^2.7.6", "npm-run-all": "4.1.5", - "optimize-css-assets-webpack-plugin": "^6.0.1", - "prettier": "2.7.1", + "prettier": "2.8.8", "progress-bar-webpack-plugin": "2.1.0", "prop-types": "15.8.1", - "react-storybook-addon-props-combinations": "1.1.0", "react-test-renderer": "18.2.0", - "regenerator-runtime": "0.13.10", - "sort-package-json": "2.1.0", + "regenerator-runtime": "0.13.11", + "sort-package-json": "2.4.1", "source-map-loader": "^4.0.1", - "storycap": "3.0.4", - "style-loader": "^3.3.1", + "storycap": "4.1.2", + "style-loader": "^3.3.3", "stylelint": "13.13.1", "stylelint-a11y": "^1.2.3", "stylelint-config-prettier": "^8.0.2", @@ -157,18 +156,18 @@ "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": "^5.3.6", - "ts-jest": "^29.0.3", - "ts-loader": "9.4.1", - "typescript": "^4.9.3", + "terser-webpack-plugin": "^5.3.9", + "ts-jest": "^29.1.0", + "ts-loader": "9.4.3", + "typescript": "^5.1.3", "url-loader": "4.1.1", "utility-types": "^3.10.0", - "webpack": "^5.75.0", - "webpack-bundle-analyzer": "4.7.0", - "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.11.1" + "webpack": "^5.87.0", + "webpack-bundle-analyzer": "4.9.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1" }, "engines": { - "node": ">=10.23.0" + "node": ">=16.20.0" } }
上記のパッチを適用後、以下のコマンドを実行してパッケージをインストールし、
package-lock.json
を更新します。$ npm i
v1.4.0で追加されたYotsuyaSansJPのフォントファイルをワークスペースに追加します。
以下のコマンドを実行し、任意のディレクトリ名でv1.4.0のワークスペースを作成します。 (このワークスペースは、フォントのコピー元としてのみ使用します。)
$ npx @aptpod/data-viz-visual-parts-react -o <v1.4.0の任意のワークスペース名>
フォントファイルを既存のワークスペースにコピーします。
コピー元:
<v1.4.0の任意のワークスペース名>/.storybook/src/assets/font
コピー先:
<既存のワークスペース名>/.storybook/src/assets/font
これにより以下の3つのフォントが既存のワークスペースに追加されます。
YotsuyaSansJP-L.woff2
YotsuyaSansJP-M.woff2
YotsuyaSansJP-R.woff2
フォントを参照しているファイルを更新します。
.storybook/src/constant/font.ts
diff --git a/.storybook/src/constant/font.ts b/.storybook/src/constant/font.ts index 6feb998..8e7ad43 100644 --- a/.storybook/src/constant/font.ts +++ b/.storybook/src/constant/font.ts @@ -1,5 +1,8 @@ import { FontFamilies } from '@aptpod/data-viz-visual-parts-sdk' +import URL_YOTSUYA_SANS_JP_LIGHT from '../assets/font/YotsuyaSansJP-L.woff2' +import URL_YOTSUYA_SANS_JP_REGULER from '../assets/font/YotsuyaSansJP-R.woff2' +import URL_YOTSUYA_SANS_JP_MEDIUM from '../assets/font/YotsuyaSansJP-M.woff2' import URL_APT7SEG from '../assets/font/apt7seg-Regular.woff2' import URL_APT_Q_REGULAR from '../assets/font/aptQ-Regular.woff2' import URL_HOOG0553 from '../assets/font/HOOG0553.ttf' @@ -12,6 +15,9 @@ const URL_OXYGEN_MONO_REGULAR = 'https://fonts.googleapis.com/css2?family=Oxygen+Mono&display=swap' export const FONT_FAMILIES: FontFamilies = { + yotsuyaSansJPLight: 'yotsuyaSansJP-Light', + yotsuyaSansJPRegular: 'yotsuyaSansJP-Regular', + yotsuyaSansJPMedium: 'yotusyaSansJP-Medium', // style 指定時に font-weight: 100 を指定すること axisProNLight: 'sans-serif', // style 指定時に font-weight: 400 を指定すること @@ -46,6 +52,21 @@ export type FontLoaderSpecs = Record< > export const FONT_LOADER_SPECS: FontLoaderSpecs = { + yotsuyaSansJPLight: { + type: 'REQUIRE', + url: URL_YOTSUYA_SANS_JP_LIGHT, + fontFamily: FONT_FAMILIES.yotsuyaSansJPLight, + }, + yotsuyaSansJPRegular: { + type: 'REQUIRE', + url: URL_YOTSUYA_SANS_JP_REGULER, + fontFamily: FONT_FAMILIES.yotsuyaSansJPRegular, + }, + yotsuyaSansJPMedium: { + type: 'REQUIRE', + url: URL_YOTSUYA_SANS_JP_MEDIUM, + fontFamily: FONT_FAMILIES.yotsuyaSansJPMedium, + }, axisProNLight: { type: 'NO_LOAD', },
src/entrypoint/samples/horizontal-bars/selector.ts
diff --git a/src/entrypoint/samples/horizontal-bars/selector.ts b/src/entrypoint/samples/horizontal-bars/selector.ts index 76a6bdd..0a6eed2 100644 --- a/src/entrypoint/samples/horizontal-bars/selector.ts +++ b/src/entrypoint/samples/horizontal-bars/selector.ts @@ -55,10 +55,10 @@ export const useSelectProps = (params: { // メモ化のため、useMemoを使用します。 const propsFontFamilies = useMemo(() => { return { - name: fontFamilies.axisProNRegular, + name: fontFamilies.yotsuyaSansJPRegular, value: fontFamilies.apt7seg, } - }, [fontFamilies.axisProNRegular, fontFamilies.apt7seg]) + }, [fontFamilies.yotsuyaSansJPRegular, fontFamilies.apt7seg]) // selectNonNullablesのメモ化 const memoizedSelectNonNullables = useMemo(
src/entrypoint/samples/horizontal-bars/test.stories.tsx
diff --git a/src/entrypoint/samples/horizontal-bars/test.stories.tsx b/src/entrypoint/samples/horizontal-bars/test.stories.tsx index 0422eba..396f240 100644 --- a/src/entrypoint/samples/horizontal-bars/test.stories.tsx +++ b/src/entrypoint/samples/horizontal-bars/test.stories.tsx @@ -10,7 +10,7 @@ storiesOf(__dirname, module) * values 1個 */ .add('values_1item', () => { - const nameFontFamily = useFontFamily('axisProNRegular') + const nameFontFamily = useFontFamily('yotsuyaSansJPRegular') const valueFontFamily = useFontFamily('apt7seg') return ( @@ -30,7 +30,7 @@ storiesOf(__dirname, module) * values 1個, negative */ .add('values_1item_negative', () => { - const nameFontFamily = useFontFamily('axisProNRegular') + const nameFontFamily = useFontFamily('yotsuyaSansJPRegular') const valueFontFamily = useFontFamily('apt7seg') return ( @@ -50,7 +50,7 @@ storiesOf(__dirname, module) * values 1個, overflow */ .add('values_1item_overflow', () => { - const nameFontFamily = useFontFamily('axisProNRegular') + const nameFontFamily = useFontFamily('yotsuyaSansJPRegular') const valueFontFamily = useFontFamily('apt7seg') return ( @@ -70,7 +70,7 @@ storiesOf(__dirname, module) * values 3個、1アイテムのみセット */ .add('values_3items_empty_2items', () => { - const nameFontFamily = useFontFamily('axisProNRegular') + const nameFontFamily = useFontFamily('yotsuyaSansJPRegular') const valueFontFamily = useFontFamily('apt7seg') return ( @@ -94,7 +94,7 @@ storiesOf(__dirname, module) * values 3個、全アイテムをセット */ .add('values_3items', () => { - const nameFontFamily = useFontFamily('axisProNRegular') + const nameFontFamily = useFontFamily('yotsuyaSansJPRegular') const valueFontFamily = useFontFamily('apt7seg') return ( @@ -118,7 +118,7 @@ storiesOf(__dirname, module) * values 3個、全アイテムをセット、小さく表示 */ .add('values_3items_small', () => { - const nameFontFamily = useFontFamily('axisProNRegular') + const nameFontFamily = useFontFamily('yotsuyaSansJPRegular') const valueFontFamily = useFontFamily('apt7seg') return (
src/entrypoint/samples/horizontal-bars/constant.ts
diff --git a/src/entrypoint/samples/horizontal-bars/constant.ts b/src/entrypoint/samples/horizontal-bars/constant.ts index be4cb9e..615e581 100644 --- a/src/entrypoint/samples/horizontal-bars/constant.ts +++ b/src/entrypoint/samples/horizontal-bars/constant.ts @@ -17,6 +17,9 @@ export const INIT_VIEW_GRID: ViewGrid = { colSpan: 0, rowSpan: 0 } export const INIT_DATA_SPECS: DataSpecification[] = [] export const INIT_VALUES: Value[] = [] export const INIT_FONT_FAMILIES: FontFamilies = { + yotsuyaSansJPLight: '', + yotsuyaSansJPRegular: '', + yotsuyaSansJPMedium: '', axisProNLight: '', axisProNRegular: '', axisProNMedium: '',
依存パッケージ更新に伴い、
chart.js
、react-chartjs-2
を使用しているファイルを更新します。src/entrypoint/samples/line-graph/component.tsx
diff --git a/src/entrypoint/samples/line-graph/component.tsx b/src/entrypoint/samples/line-graph/component.tsx index a327c7b..60c4c3a 100644 --- a/src/entrypoint/samples/line-graph/component.tsx +++ b/src/entrypoint/samples/line-graph/component.tsx @@ -1,5 +1,14 @@ import React, { memo, useCallback, useMemo } from 'react' -import Chart from 'react-chartjs-2' +import { + ChartEvent, + Chart as ChartJS, + LegendElement, + LegendItem, + registerables, +} from 'chart.js' +import { Chart, ChartProps } from 'react-chartjs-2' +import 'chartjs-adapter-date-fns' +import { enUS } from 'date-fns/locale' type Props = { /** メモリのラベルを表示せずにビジュアルパーツのパネルにフィットするかを指定します */ @@ -42,6 +51,11 @@ type Props = { */ type PropsValue = Props['values'][0] +/** + * Chart.js に使用する機能を登録します。 + */ +ChartJS.register(...registerables) + export const LineGraph: React.VFC<Props> = memo((props) => { const { values, onLegendHiddenChange } = props @@ -66,16 +80,23 @@ export const LineGraph: React.VFC<Props> = memo((props) => { }, []) // props.valuesからChartに指定するDatasetsに変換します。 - const datasets = useMemo(() => props.values.map(convertToDataset), [ - props.values, - convertToDataset, - ]) + const datasets = useMemo( + () => props.values.map(convertToDataset), + [props.values, convertToDataset], + ) // 凡例をクリックしたときのイベントハンドラを定義します。 - const onLegendClick = useCallback( - (_: any, legend: { datasetIndex: number; hidden: boolean }) => { - const value = values[legend.datasetIndex] - onLegendHiddenChange({ valueID: value.id, hidden: legend.hidden }) + const onLegendClick: ( + e: ChartEvent, + legendItem: LegendItem, + legend: LegendElement<any>, + ) => void = useCallback( + (_event, legendItem, _legend) => { + const value = values[legendItem.datasetIndex ?? 0] + onLegendHiddenChange({ + valueID: value.id, + hidden: legendItem.hidden ?? false, + }) }, [values, onLegendHiddenChange], ) @@ -84,8 +105,8 @@ export const LineGraph: React.VFC<Props> = memo((props) => { const data = useMemo(() => ({ datasets }), [datasets]) // Chartに指定するOptionsに変換します。 - const options = useMemo( - () => ({ + const options: ChartProps['options'] = useMemo(() => { + const nextOptions: ChartProps['options'] = { maintainAspectRatio: false, responsive: false, animation: { @@ -107,34 +128,41 @@ export const LineGraph: React.VFC<Props> = memo((props) => { }, }, scales: { - xAxes: [ - { - type: 'time', - display: !props.contentFit, - ticks: { - // Chartで指定する時間はミリ秒のため、UNIX Timestampからミリ秒の単位に変換します。 - min: props.time.start * 1000, - // Chartで指定する時間はミリ秒のため、UNIX Timestampからミリ秒の単位に変換します。 - max: props.time.end * 1000, + x: { + type: 'time', + display: !props.contentFit, + // Chartで指定する時間はミリ秒のため、UNIX Timestampからミリ秒の単位に変換します。 + min: props.time.start * 1000, + // Chartで指定する時間はミリ秒のため、UNIX Timestampからミリ秒の単位に変換します。 + max: props.time.end * 1000, + time: { + unit: 'second', + displayFormats: { + second: 'HH:mm:ss', }, }, - ], - yAxes: [ - { - display: !props.contentFit, + adapters: { + date: { + locale: enUS, + }, }, - ], + }, + y: { + display: !props.contentFit, + }, }, hover: { mode: 'nearest' as const, intersect: false, }, - legend: { - onClick: onLegendClick, + plugins: { + legend: { + onClick: onLegendClick, + }, }, - }), - [onLegendClick, props.contentFit, props.time.end, props.time.start], - ) + } + return nextOptions + }, [onLegendClick, props.contentFit, props.time.end, props.time.start]) return ( <Chart
Extension型オブジェクトの解析に関連するファイルを更新します。
src/entrypoint/samples/horizontal-bars/extension.ts
diff --git a/src/entrypoint/samples/horizontal-bars/extension.ts b/src/entrypoint/samples/horizontal-bars/extension.ts index b5ef836..0cf4ce5 100644 --- a/src/entrypoint/samples/horizontal-bars/extension.ts +++ b/src/entrypoint/samples/horizontal-bars/extension.ts @@ -1,32 +1,30 @@ /** * Horizontal BarsビジュアルパーツはExtensionを使用しません */ -// import * as Z from 'zod' +import * as Z from 'zod' import { Metadata } from '@aptpod/data-viz-visual-parts-sdk' -// import { estimate, estimatePartialObject } from 'src/utils/zod' /** * Extension の型を定義 */ -export type Extension = {} +export type Extension = Z.infer<typeof schema> /** * Extension のDefault値を設定します。 */ -export const defaultExtension: Extension = {} +export const defaultExtension = {} /** * Extension のスキーマ定義します。 */ -export const schema = {} +export const schema = Z.object({}).catch(defaultExtension) /** * Extension の各フィールドをチェックします。 */ -export const parse = (_anyExtension: any): Extension => { - // const def = defaultExtension - // const ext = estimatePartialObject<Extension>(anyExtension) - return {} +export const parse = (anyExtension: any): Extension => { + return schema.parse(anyExtension) } -export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = [] +export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = + []
src/entrypoint/samples/line-graph/container.tsx
diff --git a/src/entrypoint/samples/line-graph/container.tsx b/src/entrypoint/samples/line-graph/container.tsx index 097ea9f..4a67696 100644 --- a/src/entrypoint/samples/line-graph/container.tsx +++ b/src/entrypoint/samples/line-graph/container.tsx @@ -31,7 +31,7 @@ export const LineGraphContainer: React.FC<Props> = memo((props) => { const [timeSelectedRange, setTimeSelectedRange] = useState( INIT_TIME_SELECTED_RANGE, ) - const [extension, setExtension] = useState(defaultExtension) + const [extension, setExtension] = useState<Extension>(defaultExtension) const [dataSpecs, setDataSpecs] = useState(INIT_DATA_SPECS) const [values, setValues] = useState(INIT_VALUES)
src/entrypoint/samples/line-graph/extension.ts
diff --git a/src/entrypoint/samples/line-graph/extension.ts b/src/entrypoint/samples/line-graph/extension.ts index 0c7fd35..2a309ac 100644 --- a/src/entrypoint/samples/line-graph/extension.ts +++ b/src/entrypoint/samples/line-graph/extension.ts @@ -1,43 +1,34 @@ import * as Z from 'zod' import { Metadata } from '@aptpod/data-viz-visual-parts-sdk' -import { estimate, estimatePartialObject } from 'src/utils/zod' /** * Extension の型を定義 */ -export type Extension = { - hiddenIDs: string[] -} +export type Extension = Z.infer<typeof schema> /** * Extension のDefault値を設定します。 */ -export const defaultExtension: Extension = { - hiddenIDs: [], -} +export const defaultExtension = { + hiddenIDs: [] as string[], +} as const /** * Extension のスキーマ定義します。 */ -export const schema = { - hiddenIDs: Z.array(Z.string()), -} +export const schema = Z.object({ + hiddenIDs: Z.array(Z.string()).catch(defaultExtension.hiddenIDs), +}).catch(defaultExtension) /** * Extension の各フィールドをチェックします。 */ export const parse = (anyExtension: any): Extension => { - const def = defaultExtension - const ext = estimatePartialObject<Extension>(anyExtension) - - const hiddenIDs = estimate(schema.hiddenIDs, ext.hiddenIDs, def.hiddenIDs) - - return { - hiddenIDs, - } + return schema.parse(anyExtension) } /** * Data VisualizerのPanel Optionに表示する入力項目を定義します。 */ -export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = [] +export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = + []
src/entrypoint/samples/sensor-value/container.tsx
diff --git a/src/entrypoint/samples/sensor-value/container.tsx b/src/entrypoint/samples/sensor-value/container.tsx index fd52844..44b8136 100644 --- a/src/entrypoint/samples/sensor-value/container.tsx +++ b/src/entrypoint/samples/sensor-value/container.tsx @@ -2,7 +2,11 @@ import React, { memo, useEffect, useMemo, useState } from 'react' import { ExposerEvent } from '@aptpod/data-viz-visual-parts-sdk' import { SensorValue } from './component' -import { parse as parseExtension, defaultExtension } from './extension' +import { + parse as parseExtension, + defaultExtension, + Extension, +} from './extension' import { shouldDisplayedSmall, toDisplayedText } from './utils' import { canDisplayNumber } from 'src/utils/validator' @@ -17,9 +21,15 @@ export const SensorValueContainer: React.FC<Props> = memo((props) => { // SensorValue を表示するためのStateを定義します。 const [small, setSmall] = useState(false) const [baseURL, setBaseURL] = useState('') - const [description, setDescription] = useState(defaultExtension.description) - const [bgColor, setBgColor] = useState(defaultExtension.bgColor) - const [factor, setFactor] = useState(defaultExtension.factor) + const [description, setDescription] = useState<Extension['description']>( + defaultExtension.description, + ) + const [bgColor, setBgColor] = useState<Extension['bgColor']>( + defaultExtension.bgColor, + ) + const [factor, setFactor] = useState<Extension['factor']>( + defaultExtension.factor, + ) const [decimalDigits, setDecimalDigits] = useState(0) const [curValue, setCurValue] = useState<any>('') const [valueFontFamily, setValueFontFamily] = useState('')
src/entrypoint/samples/sensor-value/extension.ts
diff --git a/src/entrypoint/samples/sensor-value/extension.ts b/src/entrypoint/samples/sensor-value/extension.ts index dd8e6bf..00e78d6 100644 --- a/src/entrypoint/samples/sensor-value/extension.ts +++ b/src/entrypoint/samples/sensor-value/extension.ts @@ -1,6 +1,5 @@ import * as Z from 'zod' import { Metadata } from '@aptpod/data-viz-visual-parts-sdk' -import { estimate, estimatePartialObject } from 'src/utils/zod' // 使用するカラーを定義します。 export const BG_COLOR_TRANSPARENT = 'transparent' @@ -11,85 +10,70 @@ export const BG_COLOR_BLUE = 'blue' /** * Extension の型を定義 */ -export type Extension = { - description: string - bgColor: string - factor: number -} +export type Extension = Z.infer<typeof schema> /** * Extension のDefault値を設定します。 */ -export const defaultExtension: Extension = { +export const defaultExtension = { description: 'no settings', bgColor: BG_COLOR_TRANSPARENT, factor: 1, -} +} as const /** * Extension のスキーマ定義します。 */ -export const schema = { - description: Z.string(), +export const schema = Z.object({ + description: Z.string().catch(defaultExtension.description), bgColor: Z.union([ Z.literal(BG_COLOR_TRANSPARENT), Z.literal(BG_COLOR_RED), Z.literal(BG_COLOR_GREEN), Z.literal(BG_COLOR_BLUE), - ]), - factor: Z.number(), -} + ]).catch(defaultExtension.bgColor), + factor: Z.number().catch(defaultExtension.factor), +}).catch(defaultExtension) /** * Extension の各フィールドをチェックします。 */ export const parse = (anyExtension: any): Extension => { - const def = defaultExtension - const ext = estimatePartialObject<Extension>(anyExtension) - - // eslint-disable-next-line prettier/prettier - const description = estimate(schema.description, ext.description, def.description) - const bgColor = estimate(schema.bgColor, ext.bgColor, def.bgColor) - const factor = estimate(schema.factor, ext.factor, def.factor) - - return { - description, - bgColor, - factor, - } + return schema.parse(anyExtension) } /** * Data VisualizerのPanel Optionに表示する入力項目を定義します。 */ -export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = [ - { - id: 'InputText', - key: 'description', - label: 'Description', - option: { placeholder: 'description' }, - }, - { - id: 'Select', - key: 'bgColor', - label: 'Background Color', - option: { - options: [ - { value: BG_COLOR_TRANSPARENT, text: 'transparent' }, - { value: BG_COLOR_RED, text: 'red' }, - { value: BG_COLOR_GREEN, text: 'green' }, - { value: BG_COLOR_BLUE, text: 'blue' }, - ], +export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = + [ + { + id: 'InputText', + key: 'description', + label: 'Description', + option: { placeholder: 'description' }, + }, + { + id: 'Select', + key: 'bgColor', + label: 'Background Color', + option: { + options: [ + { value: BG_COLOR_TRANSPARENT, text: 'transparent' }, + { value: BG_COLOR_RED, text: 'red' }, + { value: BG_COLOR_GREEN, text: 'green' }, + { value: BG_COLOR_BLUE, text: 'blue' }, + ], + }, }, - }, - { - id: 'InputNumber', - key: 'factor', - label: 'Factor', - option: { - placeholder: 'factor', - min: -Infinity, - max: Infinity, + { + id: 'InputNumber', + key: 'factor', + label: 'Factor', + option: { + placeholder: 'factor', + min: -Infinity, + max: Infinity, + }, }, - }, -] + ]
src/entrypoint/samples/time-series-text/extension.ts
diff --git a/src/entrypoint/samples/time-series-text/extension.ts b/src/entrypoint/samples/time-series-text/extension.ts index 7f3e315..d15ad0b 100644 --- a/src/entrypoint/samples/time-series-text/extension.ts +++ b/src/entrypoint/samples/time-series-text/extension.ts @@ -1,32 +1,30 @@ /** * TimeSeriesTextビジュアルパーツはExtensionを使用しません */ -// import * as Z from 'zod' +import * as Z from 'zod' import { Metadata } from '@aptpod/data-viz-visual-parts-sdk' -// import { estimate, estimatePartialObject } from 'src/utils/zod' /** * Extension の型を定義 */ -export type Extension = {} +export type Extension = Z.infer<typeof schema> /** * Extension のDefault値を設定します。 */ -export const defaultExtension: Extension = {} +export const defaultExtension = {} as const /** * Extension のスキーマ定義します。 */ -export const schema = {} +export const schema = Z.object({}).catch(defaultExtension) /** * Extension の各フィールドをチェックします。 */ -export const parse = (_anyExtension: any): Extension => { - // const def = defaultExtension - // const ext = estimatePartialObject<Extension>(anyExtension) - return {} +export const parse = (anyExtension: any): Extension => { + return schema.parse(anyExtension) } -export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = [] +export const EXTENSION_CONFIGS: Metadata['panelOptionConfig']['extensionConfigs'] = + []
src/utils/zod.ts
diff --git a/src/utils/zod.ts b/src/utils/zod.ts deleted file mode 100644 index ebc6569..0000000 --- a/src/utils/zod.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as Z from 'zod' - -export const estimate = <T extends any>( - z: Z.ZodTypeAny, - target: T | undefined, - default_: T, -): T => { - return (z.check(target) ? target : default_) as T -} - -export const estimatePartialObject = <T extends {}>( - target: any, -): Partial<T> => { - return estimate(Z.object({}).nonstrict(), target, {}) -}
reboot.css
の削除に伴い、関連するファイルを更新します。.storybook/preview.js
diff --git a/.storybook/preview.js b/.storybook/preview.js index 157ee35..275d8e2 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,4 +1,3 @@ -import 'reboot.css' import React from 'react' import { addDecorator } from '@storybook/react' import { withScreenshot } from 'storycap'
src/styles/shadow.ts
diff --git a/src/styles/shadow.ts b/src/styles/shadow.ts index c313864..af86ec5 100644 --- a/src/styles/shadow.ts +++ b/src/styles/shadow.ts @@ -1,9 +1,7 @@ import { createGlobalStyle } from 'styled-components' -import reboot from 'reboot.css' import { custom } from './custom-shadow' export const StyledShadowStyle = createGlobalStyle` - ${reboot} ${custom} `
webpack.dev.js
diff --git a/webpack.dev.js b/webpack.dev.js index d3d5214..fa9ad1e 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -63,10 +63,6 @@ module.exports = { }, ], }, - { - test: /reboot\.css$/, - use: [MiniCssExtractPlugin.loader, 'css-loader'], - }, // images { test: /\.((svg|png|jpg|jpeg|webp)$)/,
webpack.prod.js
diff --git a/webpack.prod.js b/webpack.prod.js index 93ca950..98757a0 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -58,10 +58,6 @@ module.exports = { include: /node_modules/, type: 'javascript/auto', }, - { - test: /reboot\.css$/, - use: [MiniCssExtractPlugin.loader, 'css-loader'], - }, // font { test: /\.((otf|ttf|woff|woff2)$)/,