diff --git a/.github/workflows/node-version-test.yml b/.github/workflows/node-version-test.yml index 3d7415c9e..83d61adc2 100644 --- a/.github/workflows/node-version-test.yml +++ b/.github/workflows/node-version-test.yml @@ -6,13 +6,17 @@ on: pull_request: branches: - main + +env: + NX_DAEMON: false + jobs: test: runs-on: ubuntu-latest strategy: matrix: - node-versions: [20.x,22.x] + node-version: [20.x, 22.x] steps: - uses: actions/checkout@v4 @@ -20,15 +24,15 @@ jobs: uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - + - name: Install pnpm - run: npm install -g pnpm - + run: npm install -g pnpm@10.33.3 + - name: Install dependencies run: pnpm install --frozen-lockfile - + - name: Run component tests run: npx nx run-many -t test:noninteractive --all --skip-nx-cache - + - name: Build all projects - run: npx nx run-many -t build --all --exclude storybook-composition docs + run: npx nx run-many -t build --all --exclude=storybook-composition,docs diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..6aa994103 --- /dev/null +++ b/.npmrc @@ -0,0 +1,7 @@ +strict-dep-builds=false +only-built-dependencies[]=cypress +only-built-dependencies[]=@swc/core +only-built-dependencies[]=core-js +only-built-dependencies[]=esbuild +only-built-dependencies[]=nx +only-built-dependencies[]=unrs-resolver diff --git a/apps/developer-manual/package.json b/apps/developer-manual/package.json index 98f440b15..379c2a823 100644 --- a/apps/developer-manual/package.json +++ b/apps/developer-manual/package.json @@ -16,22 +16,12 @@ "dependencies": { "@docusaurus/core": "^3.10.1", "@docusaurus/preset-classic": "^3.10.1", - "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.1", "@mdx-js/react": "^3.1.1", "@mui/icons-material": "^9.0.1", "@mui/material": "^9.0.1", "clsx": "^2.1.1", - "mobx": "^6.15.2", - "mobx-react": "^9.2.1", - "prism-react-renderer": "^2.4.1", "react": "^19.2.6", - "react-dom": "^19.2.6", - "react-redux": "^9.2.0", - "redux": "^5.0.1" - }, - "devDependencies": { - "@docusaurus/module-type-aliases": "^3.10.1" + "react-dom": "^19.2.6" }, "browserslist": { "production": [ diff --git a/apps/developer-manual/vite.config.ts b/apps/developer-manual/vite.config.ts index 19f199c44..4226c70c5 100644 --- a/apps/developer-manual/vite.config.ts +++ b/apps/developer-manual/vite.config.ts @@ -1,31 +1,33 @@ /// import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; -export default defineConfig(() => ({ - root: __dirname, - cacheDir: '../../node_modules/.vite/apps/developer-manual', - server: { - port: 4200, - host: 'localhost', - }, - preview: { - port: 4200, - host: 'localhost', - }, - plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], - // Uncomment this if you are using workers. - // worker: { - // plugins: [ nxViteTsPaths() ], - // }, - build: { - outDir: '../../dist/apps/developer-manual', - emptyOutDir: true, - reportCompressedSize: true, - commonjsOptions: { - transformMixedEsModules: true, +export default defineConfig(async () => { + const react = (await import('@vitejs/plugin-react')).default; + return { + root: __dirname, + cacheDir: '../../node_modules/.vite/apps/developer-manual', + server: { + port: 4200, + host: 'localhost', }, - }, -})); + preview: { + port: 4200, + host: 'localhost', + }, + plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + build: { + outDir: '../../dist/apps/developer-manual', + emptyOutDir: true, + reportCompressedSize: true, + commonjsOptions: { + transformMixedEsModules: true, + }, + }, + }; +}); diff --git a/apps/storybook-composition/.storybook/main.ts b/apps/storybook-composition/.storybook/main.ts index e24d57fe7..e7cc82474 100644 --- a/apps/storybook-composition/.storybook/main.ts +++ b/apps/storybook-composition/.storybook/main.ts @@ -1,16 +1,10 @@ -import { dirname, join } from 'node:path'; import type { StorybookConfig } from '@storybook/react-vite'; -function getAbsolutePath(value: string): string { - return dirname(require.resolve(join(value, 'package.json'))); -} - const config: StorybookConfig = { stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'], - addons: [], framework: { - name: getAbsolutePath('@storybook/react-vite'), + name: "@storybook/react-vite", options: { builder: { viteConfigPath: 'vite.config.ts', @@ -61,7 +55,3 @@ const config: StorybookConfig = { }; export default config; - -// To customize your Vite configuration you can use the viteFinal field. -// Check https://storybook.js.org/docs/react/builders/vite#configuration -// and https://nx.dev/recipes/storybook/custom-builder-configs diff --git a/apps/storybook-composition/.storybook/manager.js b/apps/storybook-composition/.storybook/manager.js index 5d76b72f9..c81264170 100644 --- a/apps/storybook-composition/.storybook/manager.js +++ b/apps/storybook-composition/.storybook/manager.js @@ -1,6 +1,6 @@ -import { addons } from "@storybook/addons"; +import { addons } from "storybook/manager-api"; import wheregroupTheme from "./wheregroupTheme"; addons.setConfig({ - theme: wheregroupTheme, + theme: wheregroupTheme, }); diff --git a/apps/storybook-composition/.storybook/preview.ts b/apps/storybook-composition/.storybook/preview.ts index 9a4023267..a03e9a491 100644 --- a/apps/storybook-composition/.storybook/preview.ts +++ b/apps/storybook-composition/.storybook/preview.ts @@ -1,27 +1,32 @@ import './style.css'; -export const parameters = { - docs: { - inlineStories: false, +const preview = { + parameters: { + layout: 'fullscreen', + docs: { + story: { + iframeHeight: 500, + }, + }, + actions: { argTypesRegex: '^on[A-Z].*' }, }, - actions: { argTypesRegex: '^on[A-Z].*' }, - -}; - -export const globalTypes = { - theme: { - name: 'Theme', - title: 'Theme', - description: 'Theme for your components', - defaultValue: 'light', - toolbar: { - icon: 'paintbrush', - dynamicTitle: true, - items: [ - { value: 'light', left: '☀️', title: 'Light mode' }, - { value: 'dark', left: '🌙', title: 'Dark mode' }, - ], + globalTypes: { + theme: { + name: 'Theme', + title: 'Theme', + description: 'Theme for your components', + defaultValue: 'light', + toolbar: { + icon: 'paintbrush', + dynamicTitle: true, + items: [ + { value: 'light', left: '☀️', title: 'Light mode' }, + { value: 'dark', left: '🌙', title: 'Dark mode' }, + ], + }, }, }, + tags: ['autodocs'], }; -export const tags = ['autodocs']; + +export default preview; diff --git a/apps/storybook-composition/.storybook/style.css b/apps/storybook-composition/.storybook/style.css index 3d64be89a..bf3e6d78a 100644 --- a/apps/storybook-composition/.storybook/style.css +++ b/apps/storybook-composition/.storybook/style.css @@ -1,20 +1,12 @@ -.docs-story > div:first-child{ - z-index:0; +.sb-story { + min-height: 500px; + position: relative; } -.docs-story > div > div:first-child, .innerZoomElementWrapper, .innerZoomElementWrapper > div:first-child, .innerZoomElementWrapper > div:first-child > div:first-child{ - - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.docs-story > div > div:first-child{ - height: initial; -} - -.innerZoomElementWrapper > div > div > div:first-child{ - height: 100% !important; +.sb-story > div { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; } diff --git a/apps/storybook-composition/tsconfig.json b/apps/storybook-composition/tsconfig.json index 3ba3ccf56..4b1e247d5 100644 --- a/apps/storybook-composition/tsconfig.json +++ b/apps/storybook-composition/tsconfig.json @@ -12,6 +12,9 @@ "references": [ { "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.storybook.json" } ], "extends": "../../tsconfig.base.json" diff --git a/apps/storybook-composition/tsconfig.storybook.json b/apps/storybook-composition/tsconfig.storybook.json new file mode 100644 index 000000000..0439de486 --- /dev/null +++ b/apps/storybook-composition/tsconfig.storybook.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": false, + "noEmit": true + }, + "include": [".storybook/**/*"] +} diff --git a/apps/storybook-composition/vite.config.ts b/apps/storybook-composition/vite.config.ts index 66bd22883..2ff29b5c9 100644 --- a/apps/storybook-composition/vite.config.ts +++ b/apps/storybook-composition/vite.config.ts @@ -1,31 +1,33 @@ /// import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; -export default defineConfig(() => ({ - root: __dirname, - cacheDir: '../../node_modules/.vite/apps/storybook-composition', - server: { - port: 4200, - host: 'localhost', - }, - preview: { - port: 4200, - host: 'localhost', - }, - plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], - // Uncomment this if you are using workers. - // worker: { - // plugins: [ nxViteTsPaths() ], - // }, - build: { - outDir: '../../dist/apps/storybook-composition', - emptyOutDir: true, - reportCompressedSize: true, - commonjsOptions: { - transformMixedEsModules: true, +export default defineConfig(async () => { + const react = (await import('@vitejs/plugin-react')).default; + return { + root: __dirname, + cacheDir: '../../node_modules/.vite/apps/storybook-composition', + server: { + port: 4200, + host: 'localhost', }, - }, -})); + preview: { + port: 4200, + host: 'localhost', + }, + plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + build: { + outDir: '../../dist/apps/storybook-composition', + emptyOutDir: true, + reportCompressedSize: true, + commonjsOptions: { + transformMixedEsModules: true, + }, + }, + }; +}); diff --git a/apps/template/package.json b/apps/template/package.json index 31962c369..7a3d4b494 100644 --- a/apps/template/package.json +++ b/apps/template/package.json @@ -9,21 +9,23 @@ "preview": "vite preview" }, "dependencies": { - "@mapcomponents/react-maplibre": "^1.8.10", - "react": "^19.2.4", - "react-dom": "^19.2.4" + "@mapcomponents/react-maplibre": "workspace:*" }, + "peerDependencies": { + "react": "^19.2.6", + "react-dom": "^19.2.6" + }, "devDependencies": { - "@eslint/js": "^9.34.0", + "@eslint/js": "^10.0.1", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.2.0", - "eslint": "^9.34.0", - "eslint-plugin-react-hooks": "^7.0.1", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.3.0", + "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.2", - "globals": "^16.2.0", + "globals": "^17.6.0", "typescript": "^6.0.3", - "typescript-eslint": "^8.33.0", - "vite": "^7.1.4" + "typescript-eslint": "^8.59.2", + "vite": "^8.0.11" } } diff --git a/apps/template/tsconfig.app.json b/apps/template/tsconfig.app.json index 7a17e30aa..753622700 100644 --- a/apps/template/tsconfig.app.json +++ b/apps/template/tsconfig.app.json @@ -19,5 +19,10 @@ "src/**/*.spec.jsx", "src/**/*.test.jsx" ], - "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"], + "references": [ + { + "path": "../../packages/react-maplibre/tsconfig.lib.json" + } + ] } diff --git a/apps/template/vite.config.ts b/apps/template/vite.config.ts index b0cbf4575..35bbb1fe2 100644 --- a/apps/template/vite.config.ts +++ b/apps/template/vite.config.ts @@ -1,31 +1,33 @@ /// import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; -export default defineConfig(() => ({ - root: __dirname, - cacheDir: '../../node_modules/.vite/apps/template', - server: { - port: 4200, - host: 'localhost', - }, - preview: { - port: 4200, - host: 'localhost', - }, - plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], - // Uncomment this if you are using workers. - // worker: { - // plugins: [ nxViteTsPaths() ], - // }, - build: { - outDir: '../../dist/apps/template', - emptyOutDir: true, - reportCompressedSize: true, - commonjsOptions: { - transformMixedEsModules: true, +export default defineConfig(async () => { + const react = (await import('@vitejs/plugin-react')).default; + return { + root: __dirname, + cacheDir: '../../node_modules/.vite/apps/template', + server: { + port: 4200, + host: 'localhost', }, - }, -})); + preview: { + port: 4200, + host: 'localhost', + }, + plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])], + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + build: { + outDir: '../../dist/apps/template', + emptyOutDir: true, + reportCompressedSize: true, + commonjsOptions: { + transformMixedEsModules: true, + }, + }, + }; +}); diff --git a/eslint.config.mjs b/eslint.config.mjs index 876c473f2..0edde0941 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -47,8 +47,7 @@ export default [ 'eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended', - 'prettier', - 'plugin:storybook/recommended' + 'prettier' ), { plugins: { @@ -67,7 +66,7 @@ export default [ }, settings: { react: { - version: 'detect', + version: '19', }, }, rules: { diff --git a/nx.json b/nx.json index a5fb62f70..c3166cf32 100644 --- a/nx.json +++ b/nx.json @@ -113,5 +113,6 @@ "unitTestRunner": "none" } } - } + }, + "analytics": false } diff --git a/package.json b/package.json index 70c612702..9977f907e 100644 --- a/package.json +++ b/package.json @@ -1,87 +1,84 @@ { - "name": "mapcomponents", - "version": "0.0.8", - "license": "MIT", - "private": true, - "scripts": { - "prettier:check": "prettier --check .", - "migrate-changelog": "ts-node ./scripts/migrate_changelog.ts" - }, - "dependencies": { - "@babel/plugin-transform-typescript": "^7.28.0", - "@cypress/react": "^9.0.1", - "@eslint/eslintrc": "^3.3.1", - "@storybook/addon-docs": "^9.1.20", - "@typescript-eslint/eslint-plugin": "^8.42.0", - "@typescript-eslint/parser": "^8.42.0", - "babel-plugin-inline-react-svg": "^2.0.2", - "babel-plugin-styled-components": "^2.1.4", - "globals": "^16.3.0", - "react": "^19.1.0", - "react-dom": "^19.1.0" - }, - "devDependencies": { - "@babel/core": "^7.28.3", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "@babel/preset-react": "^7.27.1", - "@cypress/webpack-dev-server": "^4.1.1", - "@eslint/js": "^9.34.0", - "@nrwl/vite": "^19.8.4", - "@nx/cypress": "^21.5.1", - "@nx/eslint": "21.2.2", - "@nx/eslint-plugin": "21.2.2", - "@nx/js": "21.3.10", - "@nx/react": "21.2.2", - "@nx/storybook": "21.2.2", - "@nx/vite": "21.3.10", - "@nx/web": "21.3.10", - "@nx/workspace": "^21.4.1", - "@storybook/addon-docs": "^9.1.20", - "@storybook/addon-links": "^9.1.20", - "@storybook/addons": "^7.6.17", - "@storybook/react": "^9.1.20", - "@storybook/react-vite": "9.1.20", - "@storybook/testing-react": "^2.0.1", - "@swc-node/register": "~1.10.10", - "@swc/cli": "~0.7.8", - "@swc/core": "~1.12.14", - "@swc/helpers": "~0.5.17", - "@testing-library/dom": "^10.4.1", - "@testing-library/react": "^16.3.0", - "@types/node": "^24.3.1", - "@types/react": "^19.1.12", - "@types/react-dom": "^19.1.9", - "@vitejs/plugin-react": "^4.7.0", - "@vitest/ui": "^3.2.4", - "ajv": "^8.17.1", - "node-fetch": "^3.3.2", - "glob": "^11.0.3", - "cypress": "^14.5.4", - "eslint": "^9.34.0", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-cypress": "^5.1.1", - "eslint-plugin-import": "2.32.0", - "eslint-plugin-jsx-a11y": "6.10.2", - "eslint-plugin-react": "7.37.5", - "eslint-plugin-react-hooks": "5.2.0", - "eslint-plugin-storybook": "^9.1.4", - "html-webpack-plugin": "^5.6.4", - "jiti": "2.4.2", - "jsdom": "~26.1.0", - "nx": "21.3.10", - "prettier": "^3.6.2", - "storybook": "9.1.20", - "syncpack": "^13.0.4", - "ts-node": "10.9.2", - "tslib": "^2.8.1", - "typescript": "~6.0.3", - "typescript-eslint": "^8.42.0", - "vite": "^7.1.4", - "vite-plugin-dts": "~4.5.4", - "vitest": "^3.2.4" - }, - "workspaces": [ - "apps/**", - "packages/**" - ] + "name": "mapcomponents", + "version": "0.0.8", + "license": "MIT", + "private": true, + "scripts": { + "prettier:check": "prettier --check .", + "migrate-changelog": "ts-node ./scripts/migrate_changelog.ts" + }, + "dependencies": { + "@babel/plugin-transform-typescript": "^7.28.6", + "@cypress/react": "^9.0.2", + "@eslint/eslintrc": "^3.3.5", + "@typescript-eslint/eslint-plugin": "^8.59.2", + "@typescript-eslint/parser": "^8.59.2", + "babel-plugin-inline-react-svg": "^2.0.2", + "babel-plugin-styled-components": "^2.1.4", + "globals": "^17.6.0", + "react": "^19.2.6", + "react-dom": "^19.2.6" + }, + "devDependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", + "@babel/preset-react": "^7.28.5", + "@cypress/webpack-dev-server": "^5.6.0", + "@eslint/js": "^10.0.1", + "@nrwl/vite": "^19.8.4", + "@nx/cypress": "^22.7.1", + "@nx/eslint": "^22.7.1", + "@nx/eslint-plugin": "22.7.1", + "@nx/js": "22.7.1", + "@nx/react": "22.7.1", + "@nx/storybook": "22.7.1", + "@nx/vite": "22.7.1", + "@nx/web": "^22.7.1", + "@nx/workspace": "^22.7.1", + "@storybook/addon-docs": "^10.3.6", + "@storybook/addon-links": "^10.3.6", + "@storybook/react": "^10.3.6", + "@storybook/react-vite": "10.3.6", + "@swc-node/register": "~1.11.1", + "@swc/cli": "~0.8.1", + "@swc/core": "~1.15.33", + "@swc/helpers": "~0.5.21", + "@testing-library/dom": "^10.4.1", + "@testing-library/react": "^16.3.2", + "@types/node": "^25.6.2", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "@vitest/ui": "^4.1.5", + "ajv": "^8.20.0", + "cypress": "^15.14.2", + "eslint": "^10.3.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-cypress": "^6.4.1", + "eslint-plugin-import": "2.32.0", + "eslint-plugin-jsx-a11y": "6.10.2", + "eslint-plugin-react": "7.37.5", + "eslint-plugin-react-hooks": "7.1.1", + "eslint-plugin-storybook": "^10.3.6", + "glob": "^13.0.6", + "html-webpack-plugin": "^5.6.7", + "jiti": "2.7.0", + "jsdom": "~29.1.1", + "node-fetch": "^3.3.2", + "nx": "22.7.1", + "prettier": "^3.8.3", + "storybook": "10.3.6", + "syncpack": "^15.0.0", + "ts-node": "10.9.2", + "tslib": "^2.8.1", + "typescript": "~6.0.3", + "typescript-eslint": "^8.59.2", + "vite": "^8.0.11", + "vite-plugin-dts": "~5.0.0", + "vitest": "^4.1.5" + }, + "workspaces": [ + "apps/**", + "packages/**" + ] } diff --git a/packages/deck-gl/.storybook/main.ts b/packages/deck-gl/.storybook/main.ts index eb367a0cf..2f10fa512 100644 --- a/packages/deck-gl/.storybook/main.ts +++ b/packages/deck-gl/.storybook/main.ts @@ -1,11 +1,11 @@ -import { dirname, join } from "node:path"; import type { StorybookConfig } from '@storybook/react-vite'; + const config: StorybookConfig = { stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'], - addons: [getAbsolutePath("@storybook/addon-docs")], + addons: ["@storybook/addon-docs"], framework: { - name: getAbsolutePath("@storybook/react-vite"), + name: "@storybook/react-vite", options: { builder: { viteConfigPath: 'vite.config.ts', @@ -18,6 +18,7 @@ const config: StorybookConfig = { check: false, reactDocgen: 'react-docgen-typescript', reactDocgenTypescriptOptions: { + tsconfigPath: "./tsconfig.lib.json", shouldExtractLiteralValuesFromEnum: true, propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), }, @@ -26,11 +27,3 @@ const config: StorybookConfig = { }; export default config; - -// To customize your Vite configuration you can use the viteFinal field. -// Check https://storybook.js.org/docs/react/builders/vite#configuration -// and https://nx.dev/recipes/storybook/custom-builder-configs - -function getAbsolutePath(value: string): any { - return dirname(require.resolve(join(value, "package.json"))); -} diff --git a/packages/deck-gl/.storybook/manager.js b/packages/deck-gl/.storybook/manager.js index 5d76b72f9..9d82fd5aa 100644 --- a/packages/deck-gl/.storybook/manager.js +++ b/packages/deck-gl/.storybook/manager.js @@ -1,4 +1,4 @@ -import { addons } from "@storybook/addons"; +import { addons } from "storybook/manager-api"; import wheregroupTheme from "./wheregroupTheme"; addons.setConfig({ diff --git a/packages/deck-gl/.storybook/preview.ts b/packages/deck-gl/.storybook/preview.ts index 9a4023267..a03e9a491 100644 --- a/packages/deck-gl/.storybook/preview.ts +++ b/packages/deck-gl/.storybook/preview.ts @@ -1,27 +1,32 @@ import './style.css'; -export const parameters = { - docs: { - inlineStories: false, +const preview = { + parameters: { + layout: 'fullscreen', + docs: { + story: { + iframeHeight: 500, + }, + }, + actions: { argTypesRegex: '^on[A-Z].*' }, }, - actions: { argTypesRegex: '^on[A-Z].*' }, - -}; - -export const globalTypes = { - theme: { - name: 'Theme', - title: 'Theme', - description: 'Theme for your components', - defaultValue: 'light', - toolbar: { - icon: 'paintbrush', - dynamicTitle: true, - items: [ - { value: 'light', left: '☀️', title: 'Light mode' }, - { value: 'dark', left: '🌙', title: 'Dark mode' }, - ], + globalTypes: { + theme: { + name: 'Theme', + title: 'Theme', + description: 'Theme for your components', + defaultValue: 'light', + toolbar: { + icon: 'paintbrush', + dynamicTitle: true, + items: [ + { value: 'light', left: '☀️', title: 'Light mode' }, + { value: 'dark', left: '🌙', title: 'Dark mode' }, + ], + }, }, }, + tags: ['autodocs'], }; -export const tags = ['autodocs']; + +export default preview; diff --git a/packages/deck-gl/.storybook/style.css b/packages/deck-gl/.storybook/style.css index 3d64be89a..424ddd02a 100644 --- a/packages/deck-gl/.storybook/style.css +++ b/packages/deck-gl/.storybook/style.css @@ -1,20 +1,13 @@ -.docs-story > div:first-child{ - z-index:0; -} - -.docs-story > div > div:first-child, .innerZoomElementWrapper, .innerZoomElementWrapper > div:first-child, .innerZoomElementWrapper > div:first-child > div:first-child{ - - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.docs-story > div > div:first-child{ - height: initial; -} - -.innerZoomElementWrapper > div > div > div:first-child{ - height: 100% !important; +.sb-story { + min-height: 500px; + position: relative; +} + +.sb-story > div { + height: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; } diff --git a/packages/deck-gl/cypress.config.ts b/packages/deck-gl/cypress.config.ts index 7ce11e562..0c2f2862b 100644 --- a/packages/deck-gl/cypress.config.ts +++ b/packages/deck-gl/cypress.config.ts @@ -1,9 +1,31 @@ import { nxComponentTestingPreset } from '@nx/react/plugins/component-testing'; import { defineConfig } from 'cypress'; +const preset = nxComponentTestingPreset(__filename, { + bundler: 'vite', + buildTarget: 'deck-gl:build', +}); + export default defineConfig({ - component: nxComponentTestingPreset(__filename, { - bundler: 'vite', - buildTarget: 'deck-gl:build', - }), + component: { + ...preset, + setupNodeEvents(on) { + on('before:browser:launch', (browser, launchOptions) => { + if (browser.family === 'chromium') { + launchOptions.args.push('--use-gl=angle'); + launchOptions.args.push('--use-angle=swiftshader'); + launchOptions.args.push('--ignore-gpu-blocklist'); + launchOptions.args.push('--disable-gpu-sandbox'); + launchOptions.args.push('--enable-webgl'); + } + if (browser.name === 'electron') { + launchOptions.preferences.webPreferences = { + ...launchOptions.preferences.webPreferences, + webgl: true, + }; + } + return launchOptions; + }); + }, + }, }); diff --git a/packages/deck-gl/cypress/support/component.ts b/packages/deck-gl/cypress/support/component.ts index e0b6dd407..ebf9cf4ea 100644 --- a/packages/deck-gl/cypress/support/component.ts +++ b/packages/deck-gl/cypress/support/component.ts @@ -17,6 +17,17 @@ import { mount } from 'cypress/react'; // Import commands.ts using ES2015 syntax: import './commands'; +// Ignore WebGL context creation errors (e.g. in headless/CI environments) +Cypress.on('uncaught:exception', (err) => { + if ( + err.message.includes('Failed to initialize WebGL') || + err.message.includes('webglcontextcreationerror') + ) { + return false; + } + return true; +}); + // add component testing only related command here, such as mount declare global { // eslint-disable-next-line @typescript-eslint/no-namespace diff --git a/packages/deck-gl/package.json b/packages/deck-gl/package.json index 4776c31a3..f62930f0b 100644 --- a/packages/deck-gl/package.json +++ b/packages/deck-gl/package.json @@ -12,20 +12,19 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@mui/icons-material": "^7.3.2", - "@mui/system": "^7.3.2", - "@mui/material": "^7.3.2", - "@storybook/react": "^9.1.20", - "uuid": "^11.1.0" + "@mui/icons-material": "^9.0.1", + "@mui/material": "^9.0.1", + "react": "^19.2.6", + "react-dom": "^19.2.6" }, "peerDependencies": { - "@deck.gl/aggregation-layers": "^9.2.6", - "@deck.gl/core": "^9.2.6", - "@deck.gl/geo-layers": "^9.2.6", - "@deck.gl/mapbox": "^9.2.6", - "@deck.gl/mesh-layers": "^9.2.6", + "@deck.gl/aggregation-layers": "^9.3.2", + "@deck.gl/core": "^9.3.2", + "@deck.gl/geo-layers": "^9.3.2", + "@deck.gl/mapbox": "^9.3.2", + "@deck.gl/mesh-layers": "^9.3.2", "@mapcomponents/react-maplibre": "workspace:*", - "maplibre-gl": "^5.16.0" + "maplibre-gl": "^5.24.0" }, "devDependencies": { "@types/geojson": "^7946.0.16" diff --git a/packages/deck-gl/src/decorators/style.css b/packages/deck-gl/src/decorators/style.css index c03007552..f0c7bd57e 100644 --- a/packages/deck-gl/src/decorators/style.css +++ b/packages/deck-gl/src/decorators/style.css @@ -1,19 +1,24 @@ +html, +body, +#storybook-root, +#root { + height: 100%; + margin: 0; + padding: 0; +} + #root { background-color: #000; position: absolute; - min-height: 400px; top: 0; bottom: 0; left: 0; right: 0; } -.docs-story { - min-height: 400px; - display: flex; - align-items: stretch; -} -.docs-story > div:first-child { - width: 100%; + +#storybook-root > div, +#root > div { + height: 100%; } .App { @@ -23,6 +28,15 @@ bottom: 0; left: 0; } + +.fullscreen_map { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + .fullscreen_map .mapContainer { position: absolute; top: 0; diff --git a/packages/deck-gl/tsconfig.json b/packages/deck-gl/tsconfig.json index 83dcfe0ed..c5fadbd78 100644 --- a/packages/deck-gl/tsconfig.json +++ b/packages/deck-gl/tsconfig.json @@ -6,6 +6,9 @@ }, { "path": "./cypress/tsconfig.json" + }, + { + "path": "./tsconfig.storybook.json" } ], "extends": "../../tsconfig.base.json" diff --git a/packages/deck-gl/tsconfig.lib.json b/packages/deck-gl/tsconfig.lib.json index d3f39a24a..e6e23d67e 100644 --- a/packages/deck-gl/tsconfig.lib.json +++ b/packages/deck-gl/tsconfig.lib.json @@ -31,5 +31,10 @@ "**/*.cy.js", "**/*.cy.tsx", "**/*.cy.jsx" + ], + "references": [ + { + "path": "../react-maplibre/tsconfig.lib.json" + } ] } diff --git a/packages/deck-gl/tsconfig.storybook.json b/packages/deck-gl/tsconfig.storybook.json new file mode 100644 index 000000000..0439de486 --- /dev/null +++ b/packages/deck-gl/tsconfig.storybook.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": false, + "noEmit": true + }, + "include": [".storybook/**/*"] +} diff --git a/packages/deck-gl/vite.config.ts b/packages/deck-gl/vite.config.ts index a05cfa610..116880997 100644 --- a/packages/deck-gl/vite.config.ts +++ b/packages/deck-gl/vite.config.ts @@ -1,71 +1,73 @@ /// import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; import dts from 'vite-plugin-dts'; import * as path from 'path'; import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; -export default defineConfig(() => ({ - root: __dirname, - cacheDir: '../../node_modules/.vite/packages/deck-gl', - resolve: { - dedupe: [ - 'react', - 'react-dom', - '@mui/material', - '@mui/system', - '@emotion/react', - '@emotion/styled', - ], - }, - plugins: [ - react(), - nxViteTsPaths(), - nxCopyAssetsPlugin(['*.md']), - dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') }), - ], - // Uncomment this if you are using workers. - // worker: { - // plugins: [ nxViteTsPaths() ], - // }, - // Configuration for building your library. - // See: https://vitejs.dev/guide/build.html#library-mode - build: { - outDir: 'dist', - emptyOutDir: true, - reportCompressedSize: true, - commonjsOptions: { - transformMixedEsModules: true, - }, - lib: { - // Could also be a dictionary or array of multiple entry points. - entry: 'src/index.ts', - name: '@mapcomponents/deck-gl', - fileName: 'index', - // Change this to the formats you want to support. - // Don't forget to update your package.json as well. - formats: ['es' as const, 'cjs' as const], - }, - rollupOptions: { - // External packages that should not be bundled into your library. - external: [ +export default defineConfig(async () => { + const react = (await import('@vitejs/plugin-react')).default; + return { + root: __dirname, + cacheDir: '../../node_modules/.vite/packages/deck-gl', + resolve: { + dedupe: [ 'react', 'react-dom', - 'react/jsx-runtime', - '@mapcomponents/react-maplibre', - 'maplibre-gl', - '@deck.gl/aggregation-layers', - '@deck.gl/core', - '@deck.gl/geo-layers', - '@deck.gl/mapbox', - '@deck.gl/mesh-layers', '@mui/material', '@mui/system', - '@mui/icons-material', '@emotion/react', '@emotion/styled', ], }, - }, -})); + plugins: [ + react(), + nxViteTsPaths(), + nxCopyAssetsPlugin(['*.md']), + dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') }), + ], + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + // Configuration for building your library. + // See: https://vitejs.dev/guide/build.html#library-mode + build: { + outDir: 'dist', + emptyOutDir: true, + reportCompressedSize: true, + commonjsOptions: { + transformMixedEsModules: true, + }, + lib: { + // Could also be a dictionary or array of multiple entry points. + entry: 'src/index.ts', + name: '@mapcomponents/deck-gl', + fileName: 'index', + // Change this to the formats you want to support. + // Don't forget to update your package.json as well. + formats: ['es' as const, 'cjs' as const], + }, + rollupOptions: { + // External packages that should not be bundled into your library. + external: [ + 'react', + 'react-dom', + 'react/jsx-runtime', + '@mapcomponents/react-maplibre', + 'maplibre-gl', + '@deck.gl/aggregation-layers', + '@deck.gl/core', + '@deck.gl/geo-layers', + '@deck.gl/mapbox', + '@deck.gl/mesh-layers', + '@mui/material', + '@mui/system', + '@mui/icons-material', + '@emotion/react', + '@emotion/styled', + ], + }, + }, + }; +}); diff --git a/packages/ra-geospatial/.storybook/main.ts b/packages/ra-geospatial/.storybook/main.ts index 5412392a1..2f10fa512 100644 --- a/packages/ra-geospatial/.storybook/main.ts +++ b/packages/ra-geospatial/.storybook/main.ts @@ -1,10 +1,11 @@ -import { dirname, join } from 'node:path'; import type { StorybookConfig } from '@storybook/react-vite'; + const config: StorybookConfig = { stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'], + addons: ["@storybook/addon-docs"], framework: { - name: getAbsolutePath("@storybook/react-vite"), + name: "@storybook/react-vite", options: { builder: { viteConfigPath: 'vite.config.ts', @@ -12,14 +13,17 @@ const config: StorybookConfig = { }, }, staticDirs: ['../public'], -}; -export default config; + typescript: { + check: false, + reactDocgen: 'react-docgen-typescript', + reactDocgenTypescriptOptions: { + tsconfigPath: "./tsconfig.lib.json", + shouldExtractLiteralValuesFromEnum: true, + propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), + }, + }, -// To customize your Vite configuration you can use the viteFinal field. -// Check https://storybook.js.org/docs/react/builders/vite#configuration -// and https://nx.dev/recipes/storybook/custom-builder-configs +}; -function getAbsolutePath(value: string): any { - return dirname(require.resolve(join(value, "package.json"))); -} +export default config; diff --git a/packages/ra-geospatial/.storybook/manager.js b/packages/ra-geospatial/.storybook/manager.js index 5d76b72f9..c81264170 100644 --- a/packages/ra-geospatial/.storybook/manager.js +++ b/packages/ra-geospatial/.storybook/manager.js @@ -1,6 +1,6 @@ -import { addons } from "@storybook/addons"; +import { addons } from "storybook/manager-api"; import wheregroupTheme from "./wheregroupTheme"; addons.setConfig({ - theme: wheregroupTheme, + theme: wheregroupTheme, }); diff --git a/packages/ra-geospatial/.storybook/preview.ts b/packages/ra-geospatial/.storybook/preview.ts index 9a4023267..a03e9a491 100644 --- a/packages/ra-geospatial/.storybook/preview.ts +++ b/packages/ra-geospatial/.storybook/preview.ts @@ -1,27 +1,32 @@ import './style.css'; -export const parameters = { - docs: { - inlineStories: false, +const preview = { + parameters: { + layout: 'fullscreen', + docs: { + story: { + iframeHeight: 500, + }, + }, + actions: { argTypesRegex: '^on[A-Z].*' }, }, - actions: { argTypesRegex: '^on[A-Z].*' }, - -}; - -export const globalTypes = { - theme: { - name: 'Theme', - title: 'Theme', - description: 'Theme for your components', - defaultValue: 'light', - toolbar: { - icon: 'paintbrush', - dynamicTitle: true, - items: [ - { value: 'light', left: '☀️', title: 'Light mode' }, - { value: 'dark', left: '🌙', title: 'Dark mode' }, - ], + globalTypes: { + theme: { + name: 'Theme', + title: 'Theme', + description: 'Theme for your components', + defaultValue: 'light', + toolbar: { + icon: 'paintbrush', + dynamicTitle: true, + items: [ + { value: 'light', left: '☀️', title: 'Light mode' }, + { value: 'dark', left: '🌙', title: 'Dark mode' }, + ], + }, }, }, + tags: ['autodocs'], }; -export const tags = ['autodocs']; + +export default preview; diff --git a/packages/ra-geospatial/.storybook/style.css b/packages/ra-geospatial/.storybook/style.css index 3d64be89a..424ddd02a 100644 --- a/packages/ra-geospatial/.storybook/style.css +++ b/packages/ra-geospatial/.storybook/style.css @@ -1,20 +1,13 @@ -.docs-story > div:first-child{ - z-index:0; -} - -.docs-story > div > div:first-child, .innerZoomElementWrapper, .innerZoomElementWrapper > div:first-child, .innerZoomElementWrapper > div:first-child > div:first-child{ - - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.docs-story > div > div:first-child{ - height: initial; -} - -.innerZoomElementWrapper > div > div > div:first-child{ - height: 100% !important; +.sb-story { + min-height: 500px; + position: relative; +} + +.sb-story > div { + height: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; } diff --git a/packages/ra-geospatial/package.json b/packages/ra-geospatial/package.json index bd79bebb2..58a0e90b0 100644 --- a/packages/ra-geospatial/package.json +++ b/packages/ra-geospatial/package.json @@ -10,16 +10,16 @@ "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", "@mapcomponents/react-maplibre": "workspace:*", - "@mui/icons-material": "^7.3.2", - "@mui/material": "^7.3.2", - "@turf/helpers": "^7.3.4", - "@turf/turf": "^7.3.4", + "@mui/icons-material": "^7.3.11", + "@mui/material": "^7.3.11", + "@turf/helpers": "^7.3.5", + "@turf/turf": "^7.3.5", "@types/geojson": "^7946.0.16", - "lodash": "^4.17.21", - "maplibre-gl": "^5.16.0", - "ra-data-fakerest": "^5.11.0", - "react-admin": "^5.11.0", - "react-router-dom": "^7.8.2", + "lodash": "^4.18.1", + "maplibre-gl": "^5.24.0", + "ra-data-fakerest": "^5.14.6", + "react-admin": "^5.14.6", + "react-router-dom": "^7.15.0", "wellknown": "^0.5.0" } } diff --git a/packages/ra-geospatial/src/layout/GisLayout.jsx b/packages/ra-geospatial/src/layout/GisLayout.jsx index 963a1117b..a0f9f6517 100644 --- a/packages/ra-geospatial/src/layout/GisLayout.jsx +++ b/packages/ra-geospatial/src/layout/GisLayout.jsx @@ -1,51 +1,10 @@ import * as React from 'react'; import { useState } from 'react'; -import { Box, IconButton, styled } from '@mui/material'; +import { Box, IconButton } from '@mui/material'; import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; import { AppBar, Menu, Sidebar, useSidebarState } from 'react-admin'; -const Root = styled('div')(() => ({ - display: 'flex', - flexDirection: 'column', - zIndex: 1, - minHeight: '100%', - position: 'relative', - backgroundColor: 'transparent', - pointerEvents: 'none', -})); - -const AppFrame = styled('div')(() => ({ - display: 'flex', - flexDirection: 'column', -})); - -const ContentWithSidebar = styled('main')(() => ({ - display: 'flex', - flexGrow: 1, - marginTop: '3em', -})); - -const Content = styled('div')(() => ({ - display: 'flex', - flexDirection: 'row', - justifyContent: 'center', - maxHeight: '50vh', - position: 'fixed', - bottom: '0', - width: '100%', - backgroundColor: '#fafafa', - overflow: 'auto', - pointerEvents: 'all', - boxShadow: '0px 0px 8px rgba(0,0,0,0.2)', -})); - -const ContentWrapper = styled(Box)(() => ({ - maxWidth: '600px', - width: '100%', - height: '100%', -})); - const GisLayout = ({ children, title }) => { const [open] = useSidebarState(); const [contentOpen, setContentOpen] = useState(true); @@ -54,10 +13,31 @@ const GisLayout = ({ children, title }) => { setContentOpen(true); }, [children]); return ( - - + + - + { > - { {contentOpen ? : } - {children} - - - - + + {children} + + + + + ); }; diff --git a/packages/ra-geospatial/tsconfig.json b/packages/ra-geospatial/tsconfig.json index 04c22900d..92c2a0575 100644 --- a/packages/ra-geospatial/tsconfig.json +++ b/packages/ra-geospatial/tsconfig.json @@ -3,6 +3,9 @@ "references": [ { "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.storybook.json" } ], "extends": "../../tsconfig.base.json" diff --git a/packages/ra-geospatial/tsconfig.lib.json b/packages/ra-geospatial/tsconfig.lib.json index 1e1a1a749..4abd2b286 100644 --- a/packages/ra-geospatial/tsconfig.lib.json +++ b/packages/ra-geospatial/tsconfig.lib.json @@ -25,5 +25,10 @@ "**/*.stories.jsx", "**/*.stories.tsx" ], - "include": ["src/**/*", "../react-maplibre/src/**/*"] + "include": ["src/**/*", "../react-maplibre/src/**/*"], + "references": [ + { + "path": "../react-maplibre/tsconfig.lib.json" + } + ] } diff --git a/packages/ra-geospatial/tsconfig.storybook.json b/packages/ra-geospatial/tsconfig.storybook.json new file mode 100644 index 000000000..0439de486 --- /dev/null +++ b/packages/ra-geospatial/tsconfig.storybook.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": false, + "noEmit": true + }, + "include": [".storybook/**/*"] +} diff --git a/packages/ra-geospatial/vite.config.ts b/packages/ra-geospatial/vite.config.ts index 915606c99..687da7d32 100644 --- a/packages/ra-geospatial/vite.config.ts +++ b/packages/ra-geospatial/vite.config.ts @@ -1,58 +1,60 @@ /// import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; import dts from 'vite-plugin-dts'; import * as path from 'path'; import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'; -export default defineConfig(() => ({ - root: __dirname, - cacheDir: '../../node_modules/.vite/packages/ra-geospatial', - plugins: [ - react(), - nxViteTsPaths(), - nxCopyAssetsPlugin(['*.md']), - dts({ - entryRoot: 'src', - tsconfigPath: path.join(__dirname, 'tsconfig.lib.json'), - pathsToAliases: false, - }), - ], - // Uncomment this if you are using workers. - // worker: { - // plugins: [ nxViteTsPaths() ], - // }, - // Configuration for building your library. - // See: https://vitejs.dev/guide/build.html#library-mode - build: { - outDir: 'dist', - emptyOutDir: true, - reportCompressedSize: true, - commonjsOptions: { - transformMixedEsModules: true, - }, - lib: { - // Could also be a dictionary or array of multiple entry points. - entry: 'src/index.ts', - name: '@mapcomponents/ra-geospatial', - fileName: 'index', - // Change this to the formats you want to support. - // Don't forget to update your package.json as well. - formats: ['es' as const, 'cjs' as const], - }, - sourcemap: true, - rollupOptions: { - // External packages that should not be bundled into your library. - external: [ - 'react', - 'react-dom', - 'd3', - 'sql.js', - /* ...Object.keys(pkg.dependencies), +export default defineConfig(async () => { + const react = (await import('@vitejs/plugin-react')).default; + return { + root: __dirname, + cacheDir: '../../node_modules/.vite/packages/ra-geospatial', + plugins: [ + react(), + nxViteTsPaths(), + nxCopyAssetsPlugin(['*.md']), + dts({ + entryRoot: 'src', + tsconfigPath: path.join(__dirname, 'tsconfig.lib.json'), + pathsToAliases: false, + }), + ], + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + // Configuration for building your library. + // See: https://vitejs.dev/guide/build.html#library-mode + build: { + outDir: 'dist', + emptyOutDir: true, + reportCompressedSize: true, + commonjsOptions: { + transformMixedEsModules: true, + }, + lib: { + // Could also be a dictionary or array of multiple entry points. + entry: 'src/index.ts', + name: '@mapcomponents/ra-geospatial', + fileName: 'index', + // Change this to the formats you want to support. + // Don't forget to update your package.json as well. + formats: ['es' as const, 'cjs' as const], + }, + sourcemap: true, + rollupOptions: { + // External packages that should not be bundled into your library. + external: [ + 'react', + 'react-dom', + 'd3', + 'sql.js', + /* ...Object.keys(pkg.dependencies), ...Object.keys(pkg.devDependencies),*/ - ], - input: [path.join(__dirname, 'src/index.ts')], + ], + input: [path.join(__dirname, 'src/index.ts')], + }, }, - }, -})); + }; +}); diff --git a/packages/react-maplibre/.storybook/main.ts b/packages/react-maplibre/.storybook/main.ts index eb367a0cf..2f10fa512 100644 --- a/packages/react-maplibre/.storybook/main.ts +++ b/packages/react-maplibre/.storybook/main.ts @@ -1,11 +1,11 @@ -import { dirname, join } from "node:path"; import type { StorybookConfig } from '@storybook/react-vite'; + const config: StorybookConfig = { stories: ['../src/**/*.@(mdx|stories.@(js|jsx|ts|tsx))'], - addons: [getAbsolutePath("@storybook/addon-docs")], + addons: ["@storybook/addon-docs"], framework: { - name: getAbsolutePath("@storybook/react-vite"), + name: "@storybook/react-vite", options: { builder: { viteConfigPath: 'vite.config.ts', @@ -18,6 +18,7 @@ const config: StorybookConfig = { check: false, reactDocgen: 'react-docgen-typescript', reactDocgenTypescriptOptions: { + tsconfigPath: "./tsconfig.lib.json", shouldExtractLiteralValuesFromEnum: true, propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), }, @@ -26,11 +27,3 @@ const config: StorybookConfig = { }; export default config; - -// To customize your Vite configuration you can use the viteFinal field. -// Check https://storybook.js.org/docs/react/builders/vite#configuration -// and https://nx.dev/recipes/storybook/custom-builder-configs - -function getAbsolutePath(value: string): any { - return dirname(require.resolve(join(value, "package.json"))); -} diff --git a/packages/react-maplibre/.storybook/manager.js b/packages/react-maplibre/.storybook/manager.js index 5d76b72f9..c81264170 100644 --- a/packages/react-maplibre/.storybook/manager.js +++ b/packages/react-maplibre/.storybook/manager.js @@ -1,6 +1,6 @@ -import { addons } from "@storybook/addons"; +import { addons } from "storybook/manager-api"; import wheregroupTheme from "./wheregroupTheme"; addons.setConfig({ - theme: wheregroupTheme, + theme: wheregroupTheme, }); diff --git a/packages/react-maplibre/.storybook/preview.ts b/packages/react-maplibre/.storybook/preview.ts index 9a4023267..a03e9a491 100644 --- a/packages/react-maplibre/.storybook/preview.ts +++ b/packages/react-maplibre/.storybook/preview.ts @@ -1,27 +1,32 @@ import './style.css'; -export const parameters = { - docs: { - inlineStories: false, +const preview = { + parameters: { + layout: 'fullscreen', + docs: { + story: { + iframeHeight: 500, + }, + }, + actions: { argTypesRegex: '^on[A-Z].*' }, }, - actions: { argTypesRegex: '^on[A-Z].*' }, - -}; - -export const globalTypes = { - theme: { - name: 'Theme', - title: 'Theme', - description: 'Theme for your components', - defaultValue: 'light', - toolbar: { - icon: 'paintbrush', - dynamicTitle: true, - items: [ - { value: 'light', left: '☀️', title: 'Light mode' }, - { value: 'dark', left: '🌙', title: 'Dark mode' }, - ], + globalTypes: { + theme: { + name: 'Theme', + title: 'Theme', + description: 'Theme for your components', + defaultValue: 'light', + toolbar: { + icon: 'paintbrush', + dynamicTitle: true, + items: [ + { value: 'light', left: '☀️', title: 'Light mode' }, + { value: 'dark', left: '🌙', title: 'Dark mode' }, + ], + }, }, }, + tags: ['autodocs'], }; -export const tags = ['autodocs']; + +export default preview; diff --git a/packages/react-maplibre/.storybook/style.css b/packages/react-maplibre/.storybook/style.css index 3d64be89a..424ddd02a 100644 --- a/packages/react-maplibre/.storybook/style.css +++ b/packages/react-maplibre/.storybook/style.css @@ -1,20 +1,13 @@ -.docs-story > div:first-child{ - z-index:0; -} - -.docs-story > div > div:first-child, .innerZoomElementWrapper, .innerZoomElementWrapper > div:first-child, .innerZoomElementWrapper > div:first-child > div:first-child{ - - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} - -.docs-story > div > div:first-child{ - height: initial; -} - -.innerZoomElementWrapper > div > div > div:first-child{ - height: 100% !important; +.sb-story { + min-height: 500px; + position: relative; +} + +.sb-story > div { + height: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; } diff --git a/packages/react-maplibre/cypress.config.ts b/packages/react-maplibre/cypress.config.ts index 355174fe2..4531242a0 100644 --- a/packages/react-maplibre/cypress.config.ts +++ b/packages/react-maplibre/cypress.config.ts @@ -1,9 +1,31 @@ import { nxComponentTestingPreset } from '@nx/react/plugins/component-testing'; import { defineConfig } from 'cypress'; +const preset = nxComponentTestingPreset(__filename, { + bundler: 'vite', + buildTarget: 'react-maplibre:build', +}); + export default defineConfig({ - component: nxComponentTestingPreset(__filename, { - bundler: 'vite', - buildTarget: 'react-maplibre:build', - }), + component: { + ...preset, + setupNodeEvents(on) { + on('before:browser:launch', (browser, launchOptions) => { + if (browser.family === 'chromium') { + launchOptions.args.push('--use-gl=angle'); + launchOptions.args.push('--use-angle=swiftshader'); + launchOptions.args.push('--ignore-gpu-blocklist'); + launchOptions.args.push('--disable-gpu-sandbox'); + launchOptions.args.push('--enable-webgl'); + } + if (browser.name === 'electron') { + launchOptions.preferences.webPreferences = { + ...launchOptions.preferences.webPreferences, + webgl: true, + }; + } + return launchOptions; + }); + }, + }, }); diff --git a/packages/react-maplibre/cypress/support/component.ts b/packages/react-maplibre/cypress/support/component.ts index e0b6dd407..ebf9cf4ea 100644 --- a/packages/react-maplibre/cypress/support/component.ts +++ b/packages/react-maplibre/cypress/support/component.ts @@ -17,6 +17,17 @@ import { mount } from 'cypress/react'; // Import commands.ts using ES2015 syntax: import './commands'; +// Ignore WebGL context creation errors (e.g. in headless/CI environments) +Cypress.on('uncaught:exception', (err) => { + if ( + err.message.includes('Failed to initialize WebGL') || + err.message.includes('webglcontextcreationerror') + ) { + return false; + } + return true; +}); + // add component testing only related command here, such as mount declare global { // eslint-disable-next-line @typescript-eslint/no-namespace diff --git a/packages/react-maplibre/package.json b/packages/react-maplibre/package.json index a6afe25b5..1150f8b4c 100644 --- a/packages/react-maplibre/package.json +++ b/packages/react-maplibre/package.json @@ -21,38 +21,38 @@ "@emotion/css": "^11.13.5", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@mapbox/mapbox-gl-draw": "1.4.3", + "@mapbox/mapbox-gl-draw": "1.5.1", "@mapbox/mapbox-gl-sync-move": "^0.3.1", - "@mui/icons-material": "^7.3.2", - "@mui/material": "^7.3.2", - "@mui/system": "^7.3.2", - "@reduxjs/toolkit": "^2.9.0", + "@mui/icons-material": "^9.0.1", + "@mui/material": "^9.0.1", + "@mui/system": "^9.0.1", + "@reduxjs/toolkit": "^2.11.2", + "@storybook/react": "^10.3.6", "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.8.0", + "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "@tmcw/togeojson": "^7.1.2", - "@turf/helpers": "^7.3.4", - "@turf/turf": "^7.3.4", + "@turf/helpers": "^7.3.5", + "@turf/turf": "^7.3.5", "@types/d3": "^7.4.3", "@types/geojson": "^7946.0.16", "@types/react-color": "^3.0.13", "@types/topojson-client": "^3.1.5", "@types/topojson-specification": "^1.0.5", - "@xmldom/xmldom": "^0.9.8", - "camelcase": "^8.0.0", + "@xmldom/xmldom": "^0.9.10", + "camelcase": "^9.0.0", "csv2geojson": "^5.1.2", "d3": "^7.9.0", - "jspdf": "^3.0.2", - "osm2geojson-lite": "^1.1.2", + "jspdf": "^4.2.1", + "maplibre-gl": "^5.24.0", + "osm2geojson-lite": "^2.0.1", "pako": "^2.1.0", "react-color": "^2.19.3", "react-moveable": "^0.56.0", "react-redux": "^9.2.0", "redux": "^5.0.1", - "redux-thunk": "^3.1.0", "topojson-client": "^3.1.0", - "uuid": "^11.1.0", - "maplibre-gl": "^5.16.0", + "uuid": "^14.0.0", "wms-capabilities": "^0.6.0" }, "peerDependencies": { @@ -60,50 +60,26 @@ "react-dom": "^19.1.0" }, "devDependencies": { - "@testing-library/react": "^16.3.0", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "@types/chai": "^5.2.2", - "@types/elasticlunr": "^0.9.9", - "@types/enzyme": "^3.10.19", - "@types/expect": "^24.3.2", - "@types/jest": "^30.0.0", + "@testing-library/react": "^16.3.2", + "@types/chai": "^5.2.3", "@types/mapbox__mapbox-gl-draw": "^1.4.9", - "@types/mapbox__point-geometry": "^0.1.4", - "@types/mapbox__vector-tile": "^2.0.0", - "@types/mocha": "^10.0.10", "@types/pako": "^2.0.4", - "@types/react": "^19.1.12", - "@types/react-dom": "^19.1.9", - "@types/sql.js": "^1.4.9", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.42.0", - "@typescript-eslint/parser": "^8.42.0", - "babel-jest": "^30.1.2", - "babel-loader": "^10.0.0", - "babel-plugin-inline-react-svg": "^2.0.2", - "babel-plugin-styled-components": "^2.1.4", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@types/sql.js": "^1.4.11", + "babel-jest": "^30.4.1", "babel-preset-react-app": "^10.1.0", - "chai": "^6.0.1", - "elasticlunr": "^0.9.5", - "eslint-plugin-storybook": "^9.1.20", - "jest": "30.0.5", - "jest-circus": "30.0.5", - "jest-environment-jsdom": "^30.1.2", - "jest-enzyme": "^7.1.2", - "jest-resolve": "30.0.5", + "chai": "^6.2.2", + "jest": "30.4.0", + "jest-environment-jsdom": "^30.4.1", "jest-watch-typeahead": "3.0.1", - "mocha": "^11.7.2", - "path-browserify": "^1.0.1", - "postcss": "^8.5.6", + "react": "^19.2.6", "react-app-polyfill": "^3.0.0", "react-dev-utils": "^12.0.1", + "react-dom": "^19.2.6", "react-draggable": "^4.5.0", - "react-i18next": "^15.7.3", - "showdown": "^2.1.0", - "sql.js": "^1.13.0", - "ts-jest": "^29.4.1", - "ts-loader": "^9.5.4" + "react-i18next": "^17.0.7", + "sql.js": "^1.14.1" }, "jest": { "roots": [ @@ -131,7 +107,7 @@ "^.+\\.svg$": "/config/jest/fileTransform.js" }, "transformIgnorePatterns": [ - "[/\\\\]node_modules[/\\\\](?!three/examples/jsm/|kdbush/|geokdbush/|tinyqueue/|\\.pnpm/).+\\.(js|jsx|mjs|cjs|ts|tsx)$", + "[/\\\\]node_modules[/\\\\](?!three/examples/jsm/|kdbush/|geokdbush/|tinyqueue/|uuid/|nanoid/|osm2geojson-lite/|@mapbox/mapbox-gl-draw/|@mapbox/point-geometry/|\\.pnpm/).+\\.(js|jsx|mjs|cjs|ts|tsx)$", "^.+\\.module\\.(css|sass|scss)$" ], "modulePaths": [], diff --git a/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.cy.tsx b/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.cy.tsx index fc0fe584a..e5b03b901 100644 --- a/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.cy.tsx +++ b/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.cy.tsx @@ -1,10 +1,9 @@ -import React from 'react'; -import { composeStories } from '@storybook/testing-react'; +import { composeStories } from '@storybook/react'; import { mount } from '@cypress/react'; import * as stories from './MapLibreMap.stories'; import { expect } from 'chai'; -const { ExampleConfig }: any = composeStories(stories); +const { ExampleConfig }: any = composeStories(stories as any); describe('MlTerrainLayer Tests', () => { it('Should display Maplibre map with osm bright style', () => { diff --git a/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.stories.tsx b/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.stories.tsx index b13c38fd3..54ed26804 100644 --- a/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.stories.tsx +++ b/packages/react-maplibre/src/components/MapLibreMap/MapLibreMap.stories.tsx @@ -6,9 +6,10 @@ import TopToolbar from '../../ui_components/TopToolbar'; import sample_geojson_1 from '../MlGeoJsonLayer/assets/sample_1.json'; import { FeatureCollection } from 'geojson'; import themeDecorator from '../../decorators/ThemeDecorator'; -import { StoryFn } from '@storybook/react-vite'; +// eslint-disable-next-line storybook/no-renderer-packages +import { StoryFn, type Meta } from '@storybook/react'; -const storyoptions = { +const storyoptions: Meta = { title: 'Core/MapLibreMap', component: MapLibreMap, argTypes: { diff --git a/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.TOFIXcy.tsx b/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.TOFIXcy.tsx index 428381b71..c8696f8ce 100644 --- a/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.TOFIXcy.tsx +++ b/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.TOFIXcy.tsx @@ -1,10 +1,8 @@ -import { composeStories } from '@storybook/testing-react'; +import { composeStories } from '@storybook/react'; import { mount } from '@cypress/react'; import * as stories from './MlCreatePdfForm.stories'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-expect-error -const { ExampleConfig }: any = composeStories(stories); +const { ExampleConfig }: any = composeStories(stories as any); describe('MlCreatePdfForm Tests', () => { it('Should generate and download a PDF export of the current map preview', function () { diff --git a/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.stories.tsx b/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.stories.tsx index 438c5c839..8441691dc 100644 --- a/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.stories.tsx +++ b/packages/react-maplibre/src/components/MlCreatePdfForm/MlCreatePdfForm.stories.tsx @@ -10,6 +10,8 @@ import Sidebar from '../../ui_components/Sidebar'; import './lib/preview.css'; import mapContextDecorator from '../../decorators/MapContextDecorator'; import Draggable from 'react-draggable'; +// eslint-disable-next-line storybook/no-renderer-packages +import type { Meta } from '@storybook/react'; const PaperComponent = (props: object) => { const nodeRef = React.useRef(null); @@ -55,7 +57,7 @@ const MlDialog = ({ ); }; -const storyoptions = { +const storyoptions: Meta = { title: 'MapComponents/MlCreatePdfForm', component: MlCreatePdfForm, argTypes: {}, diff --git a/packages/react-maplibre/src/components/MlFeatureEditor/MlFeatureEditor.stories.tsx b/packages/react-maplibre/src/components/MlFeatureEditor/MlFeatureEditor.stories.tsx index 6858a74ea..041e036ac 100644 --- a/packages/react-maplibre/src/components/MlFeatureEditor/MlFeatureEditor.stories.tsx +++ b/packages/react-maplibre/src/components/MlFeatureEditor/MlFeatureEditor.stories.tsx @@ -100,7 +100,11 @@ const catalogueTemplate: any = () => { - + {(configTitles as { [key: string]: any })[selectedMode]}