diff --git a/.gitignore b/.gitignore index bd7dfe99a..39a1d0053 100644 --- a/.gitignore +++ b/.gitignore @@ -19,8 +19,9 @@ packages/beeq/custom-elements.json packages/beeq/src/components/icon/svg/** packages/beeq/src/_storybook/CHANGELOG.md packages/beeq-angular/**/directives -packages/beeq-react/src/react-component-lib packages/beeq-react/src/components.ts +packages/beeq-react/ssr/components.ts +packages/beeq-react/ssr/components.server.ts packages/beeq-vue/src/vue-component-lib packages/beeq-vue/src/components.ts !.gitkeep diff --git a/nx.json b/nx.json index 869c6b8c4..7ab030b20 100644 --- a/nx.json +++ b/nx.json @@ -21,6 +21,9 @@ ] }, "targetDefaults": { + "prebuild": { + "cache": true + }, "build": { "dependsOn": ["^build"], "inputs": ["production", "^production"], diff --git a/package-lock.json b/package-lock.json index 24f379f85..f19f9fccf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,8 +56,8 @@ "@rollup/plugin-url": "8.0.2", "@schematics/angular": "18.2.7", "@stencil/angular-output-target": "0.8.4", - "@stencil/core": "4.20.0", - "@stencil/react-output-target": "0.5.3", + "@stencil/core": "4.22.1", + "@stencil/react-output-target": "0.7.1", "@stencil/sass": "3.0.12", "@stencil/vue-output-target": "0.8.9", "@storybook/addon-a11y": "8.3.5", @@ -83,7 +83,7 @@ "@types/jest": "29.5.13", "@types/mdx": "2.0.13", "@types/node": "22.7.4", - "@types/react": "18.3.4", + "@types/react": "18.3.11", "@types/react-dom": "18.3.0", "autoprefixer": "10.4.20", "babel-jest": "29.7.0", @@ -135,6 +135,7 @@ "tailwindcss-theme-swapper": "0.12.0", "ts-jest": "29.2.5", "ts-node": "10.9.2", + "tsx": "4.19.1", "typescript": "5.5.4", "typescript-eslint": "8.8.0", "vite": "5.4.8", @@ -8484,6 +8485,15 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@lit/react": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.6.tgz", + "integrity": "sha512-QIss8MPh6qUoFJmuaF4dSHts3qCsA36S3HcOLiNPShxhgYPr4XJRnCBKPipk85sR9xr6TQrOcDMfexwbNdJHYA==", + "license": "BSD-3-Clause", + "peerDependencies": { + "@types/react": "17 || 18" + } + }, "node_modules/@lit/reactive-element": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", @@ -12124,9 +12134,9 @@ } }, "node_modules/@stencil/core": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.20.0.tgz", - "integrity": "sha512-WPrTHFngvN081RY+dJPneKQLwnOFD60OMCOQGmmSHfCW0f4ujPMzzhwWU1gcSwXPWXz5O+8cBiiCaxAbJU7kAg==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.22.1.tgz", + "integrity": "sha512-/vaKFIK/BWpGVDTj3u6TE7Nc2SCqG1PmXPtg3mEpiJw1aJZFar/jrZzbvyBOVQ7TGpDdO1ne3esXAQndj73UTQ==", "license": "MIT", "bin": { "stencil": "bin/stencil" @@ -12137,13 +12147,23 @@ } }, "node_modules/@stencil/react-output-target": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.5.3.tgz", - "integrity": "sha512-68jwRp35CjAcwhTJ9yFD/3n+jrHOqvEH2jreVuPVvZK+4tkhPlYlwz0d1E1RlF3jyifUSfdkWUGgXIEy8Fo3yw==", - "dev": true, + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@stencil/react-output-target/-/react-output-target-0.7.1.tgz", + "integrity": "sha512-KSwX453qTEinzOPU0JrWTFDau7mP/UlaQSc79ADQExx3pct1y0BgfA/SIFLovzTwpSWM75gegd6eUtrX+RE1dA==", "license": "MIT", + "dependencies": { + "@lit/react": "^1.0.4", + "html-react-parser": "^5.1.10", + "react-dom": "^18.3.1", + "ts-morph": "^22.0.0" + }, "peerDependencies": { - "@stencil/core": ">=2.0.0 || >=3 || >= 4.0.0-beta.0 || >= 4.0.0" + "@stencil/core": ">=3 || >= 4.0.0-beta.0 || >= 4.0.0" + }, + "peerDependenciesMeta": { + "@stencil/core": { + "optional": false + } } }, "node_modules/@stencil/sass": { @@ -13553,6 +13573,42 @@ "node": ">=10.13.0" } }, + "node_modules/@ts-morph/common": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.23.0.tgz", + "integrity": "sha512-m7Lllj9n/S6sOkCkRftpM7L24uvmfXQFedlW/4hENcuJH1HHm9u5EgxZb9uVjQSCGrbBWBkOGgcTxNg36r6ywA==", + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.2", + "minimatch": "^9.0.3", + "mkdirp": "^3.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -14121,7 +14177,6 @@ "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "dev": true, "license": "MIT" }, "node_modules/@types/qs": { @@ -14139,10 +14194,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.4", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", - "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", - "dev": true, + "version": "18.3.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", + "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -17388,6 +17442,12 @@ "node": ">= 0.12.0" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "license": "MIT" + }, "node_modules/collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", @@ -19535,7 +19595,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", @@ -19550,7 +19609,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, "funding": [ { "type": "github", @@ -19577,7 +19635,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" @@ -19593,7 +19650,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", @@ -23240,6 +23296,35 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/html-dom-parser": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/html-dom-parser/-/html-dom-parser-5.0.10.tgz", + "integrity": "sha512-GwArYL3V3V8yU/mLKoFF7HlLBv80BZ2Ey1BzfVNRpAci0cEKhFHI/Qh8o8oyt3qlAMLlK250wsxLdYX4viedvg==", + "license": "MIT", + "dependencies": { + "domhandler": "5.0.3", + "htmlparser2": "9.1.0" + } + }, + "node_modules/html-dom-parser/node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -23277,6 +23362,27 @@ "dev": true, "license": "MIT" }, + "node_modules/html-react-parser": { + "version": "5.1.18", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.1.18.tgz", + "integrity": "sha512-65BwC0zzrdeW96jB2FRr5f1ovBhRMpLPJNvwkY5kA8Ay5xdL9t/RH2/uUTM7p+cl5iM88i6dDk4LXtfMnRmaJQ==", + "license": "MIT", + "dependencies": { + "domhandler": "5.0.3", + "html-dom-parser": "5.0.10", + "react-property": "2.0.2", + "style-to-js": "1.1.16" + }, + "peerDependencies": { + "@types/react": "0.14 || 15 || 16 || 17 || 18", + "react": "0.14 || 15 || 16 || 17 || 18" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/html-tags": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", @@ -23887,6 +23993,12 @@ "tslib": "^2.0.0" } }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", + "license": "MIT" + }, "node_modules/inquirer": { "version": "8.2.6", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", @@ -29397,7 +29509,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, "license": "MIT", "bin": { "mkdirp": "dist/cjs/src/bin.js" @@ -32159,6 +32270,12 @@ "node": ">=0.6.0" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "license": "MIT" + }, "node_modules/path-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", @@ -34870,6 +34987,12 @@ "dev": true, "license": "MIT" }, + "node_modules/react-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/react-property/-/react-property-2.0.2.tgz", + "integrity": "sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==", + "license": "MIT" + }, "node_modules/react-syntax-highlighter": { "version": "15.5.0", "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", @@ -39157,6 +39280,24 @@ "webpack": "^5.0.0" } }, + "node_modules/style-to-js": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", + "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.8" + } + }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, "node_modules/stylehacks": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", @@ -40772,6 +40913,16 @@ "node": ">=8" } }, + "node_modules/ts-morph": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-22.0.0.tgz", + "integrity": "sha512-M9MqFGZREyeb5fTl6gNHKZLqBQA0TjA1lea+CR48R8EBTDuWrNqW6ccC5QvjNR4s6wDumD3LTCjOFSp9iwlzaw==", + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.23.0", + "code-block-writer": "^13.0.1" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -40979,6 +41130,474 @@ "dev": true, "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.1.tgz", + "integrity": "sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.23.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, "node_modules/tuf-js": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", @@ -43335,7 +43954,7 @@ "dependencies": { "@floating-ui/core": "^1.6.3", "@floating-ui/dom": "^1.6.6", - "@stencil/core": "^4.19.2", + "@stencil/core": "^4.22.1", "cally": "^0.7.1" } }, @@ -43357,7 +43976,8 @@ "version": "1.7.0", "license": "Apache-2.0", "dependencies": { - "@beeq/core": "^1.7.0" + "@beeq/core": "^1.7.0", + "@stencil/react-output-target": "^0.7.1" }, "peerDependencies": { "react": ">=18.0.0", diff --git a/package.json b/package.json index d8aee699e..c281c2cec 100644 --- a/package.json +++ b/package.json @@ -78,8 +78,8 @@ "@rollup/plugin-url": "8.0.2", "@schematics/angular": "18.2.7", "@stencil/angular-output-target": "0.8.4", - "@stencil/core": "4.20.0", - "@stencil/react-output-target": "0.5.3", + "@stencil/core": "4.22.1", + "@stencil/react-output-target": "0.7.1", "@stencil/sass": "3.0.12", "@stencil/vue-output-target": "0.8.9", "@storybook/addon-a11y": "8.3.5", @@ -105,7 +105,7 @@ "@types/jest": "29.5.13", "@types/mdx": "2.0.13", "@types/node": "22.7.4", - "@types/react": "18.3.4", + "@types/react": "18.3.11", "@types/react-dom": "18.3.0", "autoprefixer": "10.4.20", "babel-jest": "29.7.0", @@ -157,6 +157,7 @@ "tailwindcss-theme-swapper": "0.12.0", "ts-jest": "29.2.5", "ts-node": "10.9.2", + "tsx": "4.19.1", "typescript": "5.5.4", "typescript-eslint": "8.8.0", "vite": "5.4.8", diff --git a/packages/beeq-angular/project.json b/packages/beeq-angular/project.json index 6fe53ea3b..b1b6a099a 100644 --- a/packages/beeq-angular/project.json +++ b/packages/beeq-angular/project.json @@ -7,6 +7,13 @@ "prefix": "beeq", "implicitDependencies": ["beeq"], "targets": { + "prebuild": { + "executor": "nx:run-commands", + "options": { + "commands": ["tsx packages/beeq-angular/scripts/fix-value-accessor-path.ts"] + }, + "dependsOn": [{ "dependencies": true, "target": "build" }] + }, "build": { "executor": "@nx/angular:package", "outputs": ["{workspaceRoot}/dist/beeq-angular"], @@ -22,7 +29,7 @@ } }, "defaultConfiguration": "production", - "dependsOn": [{ "dependencies": true, "target": "build" }] + "dependsOn": [{ "target": "prebuild" }] }, "lint": { "executor": "@nx/eslint:lint", diff --git a/packages/beeq-angular/scripts/fix-value-accessor-path.ts b/packages/beeq-angular/scripts/fix-value-accessor-path.ts new file mode 100644 index 000000000..ee72289fa --- /dev/null +++ b/packages/beeq-angular/scripts/fix-value-accessor-path.ts @@ -0,0 +1,94 @@ +import { resolve } from 'path'; +import { promises as fs } from 'fs'; + +['module', 'standalone'].forEach((type) => { + fixValueAccessorPath(type); +}); + +/** + * Fix the value accessor path by moving the file to the correct path + * + * @param {string} type - The type of the Angular project (module or standalone) + */ +async function fixValueAccessorPath(type: string): Promise { + const angularProjectPath = type === 'module' ? '.' : 'standalone'; + + // Define the folders and files paths + const basePath = resolve(__dirname, `../${angularProjectPath}/src/directives`).replace(/\\/g, '/'); + const wrongFolderPath = `${basePath}/value-accessor.ts`; + const backupFolderPath = `${basePath}/value-accessor`; + const sourceFilePath = `${basePath}/value-accessor/value-accessor.ts`; + const destinationFilePath = wrongFolderPath; + + // Check if the wrong file exists + if (await isDirectory(wrongFolderPath)) { + console.info(`Renaming wrong Value Accessor file for angular ${type} project...`); + await renameDirectory(wrongFolderPath, backupFolderPath); + } else { + console.info(`No changes required! Wrong folder does not exist for angular ${type} project`); + return; + } + + // Move the file to the correct path + if (await isDirectory(backupFolderPath)) { + console.info(`Moving wrong Value Accessor file for angular ${type} project to the correct path...`); + + try { + await moveFile(sourceFilePath, destinationFilePath); + await removeDirectory(backupFolderPath); + console.info(`File moved successfully for angular ${type} project to the correct path.`); + } catch (err) { + console.error(`Error moving the file for angular ${type} project`, err); + process.exit(1); // Exit the process with a failure code + } + } else { + console.warn(`No changes required! Source folder does not exist for angular ${type} project`); + } +} + +/** + * Check if a path exists and is a directory + * + * @param {string} path - The path to check + * @returns {Promise} + */ +async function isDirectory(path: string): Promise { + try { + const stat = await fs.stat(path); + return stat.isDirectory(); + } catch { + return false; + } +} + +/** + * Rename a directory + * + * @param {string} oldPath - The current path of the directory + * @param {string} newPath - The new path of the directory + * @returns {Promise} + */ +async function renameDirectory(oldPath: string, newPath: string): Promise { + await fs.rename(oldPath, newPath); +} + +/** + * Move a file + * + * @param {string} source - The source file path + * @param {string} destination - The destination file path + * @returns {Promise} + */ +async function moveFile(source: string, destination: string): Promise { + await fs.rename(source, destination); +} + +/** + * Remove a directory + * + * @param {string} path - The path of the directory to remove + * @returns {Promise} + */ +async function removeDirectory(path: string): Promise { + await fs.rmdir(path); +} diff --git a/packages/beeq-angular/standalone/src/index.ts b/packages/beeq-angular/standalone/src/index.ts index a92280940..b58b44670 100644 --- a/packages/beeq-angular/standalone/src/index.ts +++ b/packages/beeq-angular/standalone/src/index.ts @@ -1,5 +1,10 @@ /* -------------------------------------------------------------------------- */ /* DIRECTIVES */ /* -------------------------------------------------------------------------- */ -// @ts-ignore +export { BooleanValueAccessor } from './directives/boolean-value-accessor'; +export { NumericValueAccessor } from './directives/number-value-accessor'; +export { RadioValueAccessor } from './directives/radio-value-accessor'; +export { SelectValueAccessor } from './directives/select-value-accessor'; +export { TextValueAccessor } from './directives/text-value-accessor'; + export * from './directives/components'; diff --git a/packages/beeq-react/.babelrc b/packages/beeq-react/.babelrc index 4cb599268..1ea870ead 100644 --- a/packages/beeq-react/.babelrc +++ b/packages/beeq-react/.babelrc @@ -4,9 +4,9 @@ "@nx/react/babel", { "runtime": "automatic", - "useBuiltIns": "usage", - }, - ], + "useBuiltIns": "usage" + } + ] ], - "plugins": [], + "plugins": [] } diff --git a/packages/beeq-react/eslint.config.js b/packages/beeq-react/eslint.config.js index 0d42ac35f..f9fe6139d 100644 --- a/packages/beeq-react/eslint.config.js +++ b/packages/beeq-react/eslint.config.js @@ -27,7 +27,7 @@ module.exports = [ '@nx/dependency-checks': [ 'error', { - ignoredDependencies: ['@beeq/core', 'react', 'react-dom'], + ignoredDependencies: ['@beeq/core', '@stencil/react-output-target', 'react', 'react-dom'], }, ], }, diff --git a/packages/beeq-react/package.json b/packages/beeq-react/package.json index cab7a91a1..c096f25a1 100644 --- a/packages/beeq-react/package.json +++ b/packages/beeq-react/package.json @@ -7,7 +7,8 @@ "module": "./src/index.js", "types": "./src/index.d.ts", "dependencies": { - "@beeq/core": "^1.7.0" + "@beeq/core": "^1.7.0", + "@stencil/react-output-target": "^0.7.1" }, "peerDependencies": { "react": ">=18.0.0", diff --git a/packages/beeq-react/ssr/index.ts b/packages/beeq-react/ssr/index.ts new file mode 100644 index 000000000..4126aed6b --- /dev/null +++ b/packages/beeq-react/ssr/index.ts @@ -0,0 +1,3 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-nocheck +export * from './components'; diff --git a/packages/beeq-react/tsconfig.lib.json b/packages/beeq-react/tsconfig.lib.json index 34aa532d5..aacbef9cf 100644 --- a/packages/beeq-react/tsconfig.lib.json +++ b/packages/beeq-react/tsconfig.lib.json @@ -2,18 +2,20 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", - "types": ["node"] + "module": "esnext", + "moduleResolution": "bundler", + "types": ["node", "@nx/react/typings/cssmodule.d.ts", "@nx/react/typings/image.d.ts"] }, - "include": ["src"], + "include": ["src/index.ts", "ssr/index.ts"], "exclude": [ "jest.config.ts", - "**/*.spec.ts", - "**/*.test.ts", - "**/*.spec.tsx", - "**/*.test.tsx", - "**/*.spec.js", - "**/*.test.js", - "**/*.spec.jsx", - "**/*.test.jsx" + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/**/*.spec.tsx", + "src/**/*.test.tsx", + "src/**/*.spec.js", + "src/**/*.test.js", + "src/**/*.spec.jsx", + "src/**/*.test.jsx" ] } diff --git a/packages/beeq/.storybook/preview.ts b/packages/beeq/.storybook/preview.ts index 0bd06f146..306bc5554 100644 --- a/packages/beeq/.storybook/preview.ts +++ b/packages/beeq/.storybook/preview.ts @@ -1,3 +1,4 @@ +// eslint-disable no-unused-disable // eslint-disable-next-line import-x/no-unresolved import './assets/css/stories.css'; @@ -7,7 +8,8 @@ import type { Preview, WebComponentsRenderer } from '@storybook/web-components'; import { setCustomElementsManifest } from '@storybook/web-components'; import { createElement } from 'react'; -// @ts-expect-error: custom-elements is a generated file +/* eslint-disable @typescript-eslint/ban-ts-comment */ +// @ts-ignore: this is a custom element manifest generated by the build process // eslint-disable-next-line import-x/no-unresolved import customElements from '../custom-elements.json'; diff --git a/packages/beeq/eslint.config.js b/packages/beeq/eslint.config.js index 7636104ae..f80d50718 100644 --- a/packages/beeq/eslint.config.js +++ b/packages/beeq/eslint.config.js @@ -35,6 +35,9 @@ module.exports = [ }, }, }, + linterOptions: { + reportUnusedDisableDirectives: false, + }, settings: { react: { version: 'detect' }, }, diff --git a/packages/beeq/package.json b/packages/beeq/package.json index e24defd8e..bea826064 100644 --- a/packages/beeq/package.json +++ b/packages/beeq/package.json @@ -15,7 +15,7 @@ "dependencies": { "@floating-ui/core": "^1.6.3", "@floating-ui/dom": "^1.6.6", - "@stencil/core": "^4.19.2", + "@stencil/core": "^4.22.1", "cally": "^0.7.1" }, "repository": { diff --git a/packages/beeq/project.json b/packages/beeq/project.json index fe53258ec..80c29e210 100644 --- a/packages/beeq/project.json +++ b/packages/beeq/project.json @@ -72,7 +72,7 @@ "{projectRoot}/custom-elements.json", "{workspaceRoot}/packages/beeq-angular/src/directives", "{workspaceRoot}/packages/beeq-angular/standalone/src/directives", - "{workspaceRoot}/packages/beeq-react/src/react-component-lib", + "{workspaceRoot}/packages/beeq-react/src/components.ts", "{workspaceRoot}/packages/beeq-vue/src/components.ts", "{workspaceRoot}/packages/beeq-vue/src/vue-component-lib" ], diff --git a/packages/beeq/src/components.d.ts b/packages/beeq/src/components.d.ts index 20d1bd456..63c468de1 100644 --- a/packages/beeq/src/components.d.ts +++ b/packages/beeq/src/components.d.ts @@ -629,7 +629,7 @@ export namespace Components { /** * Icon name to load. Please check all available icons [here](https://phosphoricons.com/) */ - "name": string; + "name"?: string; /** * Set the size of the SVG */ @@ -2949,7 +2949,7 @@ declare namespace LocalJSX { /** * Icon name to load. Please check all available icons [here](https://phosphoricons.com/) */ - "name": string; + "name"?: string; /** * Callback handler to be called when the SVG has loaded */ diff --git a/packages/beeq/src/components/button/bq-button.tsx b/packages/beeq/src/components/button/bq-button.tsx index 5cfe18031..3c097420b 100644 --- a/packages/beeq/src/components/button/bq-button.tsx +++ b/packages/beeq/src/components/button/bq-button.tsx @@ -1,4 +1,4 @@ -import { Component, Element, Event, EventEmitter, h, Host, Prop, State, Watch } from '@stencil/core'; +import { AttachInternals, Component, Element, Event, EventEmitter, h, Host, Prop, State, Watch } from '@stencil/core'; import { BUTTON_APPEARANCE, @@ -24,7 +24,10 @@ import { hasSlotContent, isDefined, isNil, validatePropValue } from '../../share @Component({ tag: 'bq-button', styleUrl: './scss/bq-button.scss', - shadow: true, + formAssociated: true, + shadow: { + delegatesFocus: true, + }, }) export class BqButton { // Own Properties @@ -37,6 +40,7 @@ export class BqButton { // =================================== @Element() el!: HTMLBqButtonElement; + @AttachInternals() internals!: ElementInternals; // State() variables // Inlined decorator, alphabetical order @@ -149,26 +153,50 @@ export class BqButton { }; private handleClick = (ev: Event) => { - if (this.disabled || this.loading) { - ev.preventDefault(); - ev.stopPropagation(); + const { disabled, loading, bqClick, el } = this; + + if (disabled || loading) { + this.preventEvent(ev); return; } - if (this.type === 'submit' || this.type === 'reset') { - const wrapperForm = this.el.closest('form'); - if (!isNil(wrapperForm)) { - const btn = document.createElement('button'); - btn.type = this.type; - btn.hidden = true; - wrapperForm.append(btn); - - btn.click(); - btn.remove(); - } + const bqClickEvent = bqClick.emit(el); + if (bqClickEvent.defaultPrevented) { + this.preventEvent(ev); + return; } - this.bqClick.emit(this.el); + this.handleFormAction(); + }; + + private handleFormAction() { + const { + type, + internals: { form }, + } = this; + if (isNil(form)) return; + + const formAction = this.formActions(form)[type]; + if (isNil(formAction)) return; + + formAction(); + } + + private formActions = (form: HTMLFormElement) => ({ + submit: () => this.submitAssociatedForm(form), + reset: () => form.reset(), + }); + + private submitAssociatedForm = (form: HTMLFormElement) => { + if (typeof window === 'undefined' || isNil(form)) return; + + const btn = document.createElement('button'); + btn.type = this.type; + btn.hidden = true; + form.append(btn); + + btn.click(); + btn.remove(); }; private handleSlotChange = () => { @@ -176,6 +204,11 @@ export class BqButton { this.hasSuffix = hasSlotContent(this.suffixElem, 'suffix'); }; + private preventEvent(ev: Event) { + ev.preventDefault(); + ev.stopPropagation(); + } + // render() function // Always the last one in the class. // =================================== diff --git a/packages/beeq/src/components/date-picker/bq-date-picker.tsx b/packages/beeq/src/components/date-picker/bq-date-picker.tsx index 414232034..b515e34f6 100644 --- a/packages/beeq/src/components/date-picker/bq-date-picker.tsx +++ b/packages/beeq/src/components/date-picker/bq-date-picker.tsx @@ -249,6 +249,10 @@ export class BqDatePicker { this.handleValueChange(); } + componentWillLoad() { + this.handleValueChange(); + } + // Listeners // ============== diff --git a/packages/beeq/src/components/divider/bq-divider.tsx b/packages/beeq/src/components/divider/bq-divider.tsx index c7ce3499f..37d2de026 100644 --- a/packages/beeq/src/components/divider/bq-divider.tsx +++ b/packages/beeq/src/components/divider/bq-divider.tsx @@ -94,6 +94,10 @@ export class BqDivider { this.checkPropValues(); } + componentWillLoad() { + this.checkPropValues(); + } + componentDidLoad() { this.handleSlotChange(); } diff --git a/packages/beeq/src/components/icon/bq-icon.tsx b/packages/beeq/src/components/icon/bq-icon.tsx index 2df03f221..8393f02db 100644 --- a/packages/beeq/src/components/icon/bq-icon.tsx +++ b/packages/beeq/src/components/icon/bq-icon.tsx @@ -39,7 +39,7 @@ export class BqIcon { @Prop({ reflect: true }) color?: string; /** Icon name to load. Please check all available icons [here](https://phosphoricons.com/) */ - @Prop({ reflect: true }) name!: string; + @Prop({ reflect: true }) name?: string; /** Set the size of the SVG */ @Prop({ reflect: true }) size?: string | number = 24; @@ -97,10 +97,11 @@ export class BqIcon { // ===================================== connectedCallback() { - this.handlePropsChange(); + this.setupIconComponent(); + } - // !TO BE REMOVED: Delete this once the deprecated `weight` property is removed - if (!isNil(this.weight)) this.handleWeightChange(); + componentWillLoad() { + this.setupIconComponent(); } // Listeners @@ -118,6 +119,12 @@ export class BqIcon { // These methods cannot be called from the host element. // ======================================================= + private setupIconComponent = () => { + this.loadIcon(this.name); + // !TO BE REMOVED: Delete this once the deprecated `weight` property is removed + if (!isNil(this.weight)) this.handleWeightChange(); + }; + private getIconSource = (name: string) => { if (!this.name && !this.src) return; // Return the src if it is set diff --git a/packages/beeq/src/components/icon/helper/request.ts b/packages/beeq/src/components/icon/helper/request.ts index 93e0579eb..28587b6fa 100644 --- a/packages/beeq/src/components/icon/helper/request.ts +++ b/packages/beeq/src/components/icon/helper/request.ts @@ -5,9 +5,18 @@ import { isNil, isString } from '../../../shared/utils'; const requests = new Map>(); +export const iconContent = new Map(); +/** + * Fetches SVG content from a given URL and optionally sanitizes it. + * @param {string} url - The URL to fetch the SVG from. + * @param {boolean} sanitize - Whether to sanitize the SVG content. + * @returns {Promise} - A promise that resolves to the SVG content. + */ const fetchSvg = async (url: string, sanitize: boolean): Promise => { - if (typeof fetch === 'undefined' || typeof document === 'undefined') return; + if (isNil(url) || typeof fetch === 'undefined' || typeof window === 'undefined') { + return; + } if (requests.has(url)) return requests.get(url); @@ -19,23 +28,31 @@ const fetchSvg = async (url: string, sanitize: boolean): Promise => { return; } - let svgContent = (await response.text()) || ''; + let svgContent = await response.text(); - if (svgContent && sanitize !== false) svgContent = validateContent(svgContent); + if (sanitize !== false) { + svgContent = validateContent(svgContent); + } iconContent.set(url, svgContent); + return svgContent; } catch (error) { console.error(`[BqIcon] Failed to fetch SVG from ${url}:`, error); iconContent.set(url, ''); } }; -export const iconContent = new Map(); +/** + * Retrieves the SVG content for a given URL, fetching and caching it if necessary. + * @param {string} url - The URL to fetch the SVG from. + * @param {boolean} sanitize - Whether to sanitize the SVG content. + * @returns {Promise} - A promise that resolves to the SVG content. + */ +export const getSvgContent = async (url: string, sanitize: boolean): Promise => { + if (isNil(url)) return; -export const getSvgContent = async (url: string, sanitize: boolean) => { let req = requests.get(url); - // NOTE: if the request does not exists we will cache it if (isNil(req)) { req = fetchSvg(url, sanitize); requests.set(url, req); @@ -43,55 +60,55 @@ export const getSvgContent = async (url: string, sanitize: boolean) => { return req; }; +/** + * Validates and sanitizes the SVG content. + * @param {string} svgContent - The SVG content to validate. + * @returns {string} - The sanitized SVG content. + */ export const validateContent = (svgContent: string): string => { + if (typeof window === 'undefined' || isNil(svgContent)) return ''; + const svgTag = 'svg'; const iconCssClass = 'bq-icon__svg'; - const div = document.createElement('div'); div.innerHTML = svgContent; - for (let i = div.childNodes.length - 1; i >= 0; i--) { - if (div.childNodes[i].nodeName.toLowerCase() !== svgTag) { - div.removeChild(div.childNodes[i]); - } - } + const svgElm = div.querySelector(svgTag); - // must only have 1 root element - const svgElm = div.firstElementChild; - if (svgElm && svgElm.nodeName.toLowerCase() === svgTag) { - // keep other CSS classes (if there's any) and add the `bq-icon__svg` CSS class - const othersCssClasses = svgElm.getAttribute('class') || ''; - svgElm.setAttribute('class', `${othersCssClasses} ${iconCssClass}`.trim()); - // set the shadow DOM part for the SVG element + if (svgElm) { + const existingClasses = svgElm.getAttribute('class') || ''; + svgElm.setAttribute('class', `${existingClasses} ${iconCssClass}`.trim()); svgElm.setAttribute('part', svgTag); - - // remove height and width attribute, if for some reason they are still present in the SVG tag svgElm.removeAttribute('height'); svgElm.removeAttribute('width'); - // root element must be an svg - // lets double check we've got valid elements - // do not allow scripts - if (isValid(svgElm as HTMLElement)) return div.innerHTML; + if (isValid(svgElm)) { + return div.innerHTML; + } } return ''; }; -export const isValid = (elm: HTMLElement): boolean => { - if (elm.nodeType === Node.ELEMENT_NODE) { - if (elm.nodeName.toLowerCase() === 'script') return false; - - for (const attribute of Array.from(elm.attributes)) { - const value = attribute.value; - if (isString(value) && value.toLowerCase().startsWith('on')) { - return false; - } +/** + * Checks if an HTML element is valid (i.e., does not contain scripts or event handlers). + * @param {HTMLElement} elm - The element to check. + * @returns {boolean} - True if the element is valid, false otherwise. + */ +export const isValid = (elm: Element): boolean => { + if (!elm) return false; + if (elm.nodeType !== Node.ELEMENT_NODE) return false; + if (elm.nodeName.toLowerCase() === 'script') return false; + + for (const attribute of Array.from(elm.attributes)) { + if (isString(attribute.value) && attribute.value.toLowerCase().startsWith('on')) { + return false; } + } - for (const childNode of Array.from(elm.children) as HTMLElement[]) { - if (!isValid(childNode)) return false; - } + for (const childNode of Array.from(elm.children) as HTMLElement[]) { + if (!isValid(childNode)) return false; } + return true; }; diff --git a/packages/beeq/src/components/icon/readme.md b/packages/beeq/src/components/icon/readme.md index af648dee1..9857bef71 100644 --- a/packages/beeq/src/components/icon/readme.md +++ b/packages/beeq/src/components/icon/readme.md @@ -9,14 +9,14 @@ Icons are simplified images that graphically explain the meaning of an object on ## Properties -| Property | Attribute | Description | Type | Default | -| ------------------- | --------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------- | -| `color` | `color` | Set the stroke color of the SVG. The value should be a valid value of the palette color | `string` | `undefined` | -| `label` | `label` | Label for the icon, used for accessibility | `string` | `undefined` | -| `name` _(required)_ | `name` | Icon name to load. Please check all available icons [here](https://phosphoricons.com/) | `string` | `undefined` | -| `size` | `size` | Set the size of the SVG | `number \| string` | `24` | -| `src` | `src` | Set the source of the SVG. If the source is set, the name property will be ignored | `string` | `undefined` | -| `weight` | `weight` | **[DEPRECATED]** It set the icon weight/style

| `"bold" \| "duotone" \| "fill" \| "light" \| "regular" \| "thin"` | `undefined` | +| Property | Attribute | Description | Type | Default | +| -------- | --------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | ----------- | +| `color` | `color` | Set the stroke color of the SVG. The value should be a valid value of the palette color | `string` | `undefined` | +| `label` | `label` | Label for the icon, used for accessibility | `string` | `undefined` | +| `name` | `name` | Icon name to load. Please check all available icons [here](https://phosphoricons.com/) | `string` | `undefined` | +| `size` | `size` | Set the size of the SVG | `number \| string` | `24` | +| `src` | `src` | Set the source of the SVG. If the source is set, the name property will be ignored | `string` | `undefined` | +| `weight` | `weight` | **[DEPRECATED]** It set the icon weight/style

| `"bold" \| "duotone" \| "fill" \| "light" \| "regular" \| "thin"` | `undefined` | ## Events diff --git a/packages/beeq/src/components/input/_storybook/bq-input.stories.tsx b/packages/beeq/src/components/input/_storybook/bq-input.stories.tsx index 63001110c..d1a9d728e 100644 --- a/packages/beeq/src/components/input/_storybook/bq-input.stories.tsx +++ b/packages/beeq/src/components/input/_storybook/bq-input.stories.tsx @@ -123,19 +123,19 @@ const Template = (args: Args) => { ?disable-clear=${args['disable-clear']} ?disabled=${args.disabled} form=${ifDefined(args.form)} - inputmode=${args.inputmode} + inputmode=${ifDefined(args.inputmode)} max=${ifDefined(args.max)} maxlength=${ifDefined(args.maxlength)} min=${ifDefined(args.min)} minlength=${ifDefined(args.minlength)} name=${ifDefined(args.name)} pattern=${ifDefined(args.pattern)} - placeholder=${args.placeholder} + placeholder=${ifDefined(args.placeholder)} ?readonly=${args.readonly} ?required=${args.required} step=${ifDefined(args.step)} type=${ifDefined(args.type)} - validation-status=${args['validation-status']} + validation-status=${ifDefined(args['validation-status'])} value=${ifDefined(args.value)} @bqBlur=${args.bqBlur} @bqChange=${args.bqChange} @@ -283,7 +283,7 @@ export const WithForm: Story = {

Shipping Information

-
+
diff --git a/packages/beeq/src/components/notification/bq-notification.tsx b/packages/beeq/src/components/notification/bq-notification.tsx index 58e0d65f8..afe6dc174 100644 --- a/packages/beeq/src/components/notification/bq-notification.tsx +++ b/packages/beeq/src/components/notification/bq-notification.tsx @@ -50,7 +50,8 @@ export class BqNotification { @State() private hasContent = false; @State() private hasFooter = false; - @State() private notificationPortal = document.querySelector(`.${NOTIFICATION_PORTAL_SELECTOR}`); + @State() private notificationPortal = + typeof window !== 'undefined' ? document.querySelector(`.${NOTIFICATION_PORTAL_SELECTOR}`) : null; // Public Property API // ======================== @@ -126,7 +127,7 @@ export class BqNotification { connectedCallback() { const { notificationPortal } = this; - if (!notificationPortal) { + if (!notificationPortal && typeof window !== 'undefined') { this.notificationPortal = Object.assign(document.createElement('div'), { className: NOTIFICATION_PORTAL_SELECTOR, }); diff --git a/packages/beeq/src/components/select/bq-select.tsx b/packages/beeq/src/components/select/bq-select.tsx index 1e633e343..398ba5c3d 100644 --- a/packages/beeq/src/components/select/bq-select.tsx +++ b/packages/beeq/src/components/select/bq-select.tsx @@ -199,9 +199,11 @@ export class BqSelect { // ===================================== connectedCallback() { - if (this.multiple) { - this.value = Array.isArray(this.value) ? this.value : Array.from(JSON.parse(String(this.value))); - } + this.initMultipleValue(); + } + + componentWillLoad() { + this.initMultipleValue(); } componentDidLoad() { @@ -284,6 +286,12 @@ export class BqSelect { // These methods cannot be called from the host element. // ======================================================= + private initMultipleValue = () => { + if (!this.multiple) return; + + this.value = Array.isArray(this.value) ? this.value : Array.from(JSON.parse(String(this.value))); + }; + private handleBlur = () => { if (this.disabled) return; diff --git a/packages/beeq/src/components/side-menu/bq-side-menu.tsx b/packages/beeq/src/components/side-menu/bq-side-menu.tsx index 4d3ef4241..0f740da2b 100644 --- a/packages/beeq/src/components/side-menu/bq-side-menu.tsx +++ b/packages/beeq/src/components/side-menu/bq-side-menu.tsx @@ -1,4 +1,4 @@ -import { Component, Event, EventEmitter, h, Listen, Method, Prop, Watch } from '@stencil/core'; +import { Component, Event, EventEmitter, h, Listen, Method, Prop, State, Watch } from '@stencil/core'; import { TSideMenuAppearance, TSideMenuSize } from './bq-side-menu.types'; import { isHTMLElement } from '../../shared/utils'; @@ -25,7 +25,6 @@ export class BqSideMenu { private bodyCssCollapse = 'bq-body--side-menu__collapse'; private menuElem: HTMLElement; - private documentBody: HTMLBodyElement = document.querySelector('body'); // Reference to host HTML element // =================================== @@ -34,6 +33,8 @@ export class BqSideMenu { // Inlined decorator, alphabetical order // ======================================= + @State() private documentBody: HTMLBodyElement; + // Public Property API // ======================== @@ -70,6 +71,7 @@ export class BqSideMenu { // ===================================== componentDidLoad() { + this.documentBody = document.querySelector('body'); this.documentBody.classList.add(this.bodyCss); this.handleCollapse(); } diff --git a/packages/beeq/src/components/slider/bq-slider.tsx b/packages/beeq/src/components/slider/bq-slider.tsx index 1a7cc8e2e..6dbfe5421 100644 --- a/packages/beeq/src/components/slider/bq-slider.tsx +++ b/packages/beeq/src/components/slider/bq-slider.tsx @@ -142,9 +142,11 @@ export class BqSlider { // ===================================== connectedCallback() { - this.handleGapChange(this.gap); - this.setState(this.value); - this.handleStepPropChange(); + this.init(); + } + + componentWillLoad() { + this.init(); } componentDidLoad() { @@ -170,6 +172,12 @@ export class BqSlider { // These methods cannot be called from the host element. // ======================================================= + private init = () => { + this.handleGapChange(this.gap); + this.setState(this.value); + this.handleStepPropChange(); + }; + private runUpdates = () => { this.updateProgressTrack(); this.syncInputsValue(); diff --git a/packages/beeq/src/components/step-item/bq-step-item.tsx b/packages/beeq/src/components/step-item/bq-step-item.tsx index 447211e1e..bfea84791 100644 --- a/packages/beeq/src/components/step-item/bq-step-item.tsx +++ b/packages/beeq/src/components/step-item/bq-step-item.tsx @@ -65,6 +65,10 @@ export class BqStepItem { this.checkPropValues(); } + componentWillLoad() { + this.checkPropValues(); + } + componentDidLoad() { this.handleIconPrefix(); } diff --git a/packages/beeq/src/components/toast/bq-toast.tsx b/packages/beeq/src/components/toast/bq-toast.tsx index c3912d317..ba291e5b5 100644 --- a/packages/beeq/src/components/toast/bq-toast.tsx +++ b/packages/beeq/src/components/toast/bq-toast.tsx @@ -34,7 +34,8 @@ export class BqToast { // Inlined decorator, alphabetical order // ======================================= - @State() private toastPortal = document.querySelector(`.${TOAST_PORTAL_SELECTOR}`); + @State() private toastPortal = + typeof window !== 'undefined' ? document.querySelector(`.${TOAST_PORTAL_SELECTOR}`) : null; // Public Property API // ======================== @@ -107,7 +108,7 @@ export class BqToast { connectedCallback() { const { toastPortal } = this; - if (!toastPortal) { + if (!toastPortal && typeof window !== 'undefined') { this.toastPortal = Object.assign(document.createElement('div'), { className: TOAST_PORTAL_SELECTOR }); } } diff --git a/packages/beeq/src/shared/utils/assetsPath.ts b/packages/beeq/src/shared/utils/assetsPath.ts index 1fa43b0de..e51f19802 100644 --- a/packages/beeq/src/shared/utils/assetsPath.ts +++ b/packages/beeq/src/shared/utils/assetsPath.ts @@ -3,98 +3,71 @@ * https://github.com/shoelace-style/shoelace/blob/next/src/utilities/base-path.ts */ -/** - * Extend the Window interface to include the `bqSVGBasePath` property and prevent it from being modified. - * This is necessary to prevent the basePath from being modified by external scripts. - */ -declare global { - interface Window { - bqSVGBasePath: string; - } -} - -/** - * Define the `bqSVGBasePath` property on the global window object, but only when the window object is available. - */ -if (typeof window !== 'undefined') { - Object.defineProperty(window, 'bqSVGBasePath', { - configurable: true, - enumerable: false, - writable: true, - }); -} - +let basePath: string | undefined; const DATA_BEEQ_ATTRIBUTE = 'data-beeq'; const DEFAULT_SVG_PATH = 'svg'; -const scripts: HTMLScriptElement[] = - typeof document !== 'undefined' && document - ? ([...document.getElementsByTagName('script')] as HTMLScriptElement[]) - : []; /** - * Sets the `bqSVGBasePath` in the global window object, - * which is used to determine the SVG path in the BQIcon component. - * This method is the only way to update the base path. - * - * @param path - The new base path to set. + * Sets the base path for the assets. + * @param {string} path - The base path to set. */ export const setBasePath = (path: string): void => { - if (typeof window !== 'undefined') { - window.bqSVGBasePath = path; - } + basePath = path; }; /** - * Retrieves the `bqSVGBasePath`, optionally appending a subpath. - * - * @param subpath - The subpath to append to the base path. - * @returns The full base path including the subpath. + * Gets the base path for the assets. + * @param {string} subpath - An optional subpath to append to the base path. + * @returns {string} The base path of the assets. */ -export const getBasePath = (subpath = ''): string | undefined => { - if (typeof window === 'undefined') return undefined; +export const getBasePath = (subpath: string = ''): string => { + if (!basePath) { + const configScript = findConfigScript(); + const fallbackScript = configScript ? null : findFallbackScript(); - const { bqSVGBasePath } = window; - if (!bqSVGBasePath) { - initializeBasePath(); + const script = configScript || fallbackScript; + if (script) { + const path = configScript ? script.getAttribute(DATA_BEEQ_ATTRIBUTE) : getScriptPath(script); + setBasePath(`${path}/${DEFAULT_SVG_PATH}`); + } else { + // Fallback: use an environment variable (if set) or the default path + setBasePath(process.env.ASSETS_BASE_PATH || `./${DEFAULT_SVG_PATH}`); + } } - return formatBasePath(subpath); + // Return the base path without a trailing slash. If one exists, append the subpath separated by a slash. + const formattedSubpath = subpath ? `/${subpath.replace(/^\//, '')}` : ''; + return basePath.replace(/\/$/, '') + formattedSubpath; }; /** - * Initializes the `bqSVGBasePath` for the BEEQ assets by finding the appropriate script and setting the base path accordingly. - * 1. If a script with the attribute `data-beeq` exists, the base path will be set to the value of the `src` attribute. - * 2. If a script with the name `beeq.js` or `beeq.esm.js` exists, the base path will be set to the value of the `src` attribute. - * 3. If no scripts are found, the base path will be set to the default value `./svg`. + * Finds the configuration script element. + * @returns The configuration script element or null if not found. */ -const initializeBasePath = (): void => { - const configScript = findConfigScript(); - const fallbackScript = configScript ? null : findFallbackScript(); +const findConfigScript = (): HTMLScriptElement | null => { + if (typeof window === 'undefined') return null; - const script = configScript || fallbackScript; - if (script) { - const path = configScript ? script.getAttribute(DATA_BEEQ_ATTRIBUTE) : getScriptPath(script); - setBasePath(`${path}/${DEFAULT_SVG_PATH}`); - } else { - setBasePath(`./${DEFAULT_SVG_PATH}`); - } + return document.querySelector(`script[${DATA_BEEQ_ATTRIBUTE}]`); }; /** - * Formats the `bqSVGBasePath` without a trailing slash. - * If one exists, append the subpath separated by a slash. - * - * @param subpath - The subpath to append to the base path. - * @returns The formatted base path. + * Finds the fallback script element. + * @returns The fallback script element or null if not found. */ -const formatBasePath = (subpath: string): string => { - const formattedSubpath = subpath ? `/${subpath.replace(/^\//, '')}` : ''; - return window.bqSVGBasePath.replace(/\/$/, '') + formattedSubpath; -}; +const findFallbackScript = (): HTMLScriptElement | null => { + if (typeof window === 'undefined') return null; -const findConfigScript = (): HTMLScriptElement => scripts.find((script) => script.hasAttribute(DATA_BEEQ_ATTRIBUTE)); + return document.querySelector(`script[src*="beeq"]`); +}; -const findFallbackScript = (): HTMLScriptElement => scripts.find((script) => /beeq(\.esm)?\.js($|\?)/.test(script.src)); +/** + * Gets the path of a script element. + * @param {HTMLScriptElement} script - The script element. + * @returns The path of the script element. + */ +const getScriptPath = (script: HTMLScriptElement): string => { + if (typeof window === 'undefined') return ''; -const getScriptPath = (script: HTMLScriptElement): string => - script.getAttribute('src').split('/').slice(0, -1).join('/'); + const src = script.getAttribute('src'); + return src ? src.substring(0, src.lastIndexOf('/')) : ''; +}; diff --git a/packages/beeq/src/shared/utils/cssVariables.ts b/packages/beeq/src/shared/utils/cssVariables.ts index 603612111..f0381d56c 100644 --- a/packages/beeq/src/shared/utils/cssVariables.ts +++ b/packages/beeq/src/shared/utils/cssVariables.ts @@ -6,7 +6,9 @@ const CSSVALUEPREFIX = '--bq-'; * @param {string} colorName - Valid string value. * @return {string} The corresponding CSS custom property variable */ -export function getColorCSSVariable(colorName: string): string { +export function getColorCSSVariable(colorName: string): string | undefined { + if (typeof window === 'undefined') return undefined; + const token = `${CSSVALUEPREFIX}${colorName}`; const value = getComputedStyle(document.documentElement).getPropertyValue(token); if (!value) return undefined; diff --git a/packages/beeq/stencil.config.ts b/packages/beeq/stencil.config.ts index a21f48a40..fcea5ea73 100644 --- a/packages/beeq/stencil.config.ts +++ b/packages/beeq/stencil.config.ts @@ -82,9 +82,12 @@ export const config: Config = { customElementsDir, }), react({ - componentCorePackage, - proxiesFile: resolve(__dirname, '../beeq-react/src/components.ts').replace(/\\/g, '/'), - includeImportCustomElements: true, + outDir: resolve(__dirname, '../beeq-react/src/').replace(/\\/g, '/'), + customElementsDir, + }), + react({ + outDir: resolve(__dirname, '../beeq-react/ssr').replace(/\\/g, '/'), + hydrateModule: '@beeq/core/dist/hydrate', customElementsDir, }), vue({