diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..6c33db7 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,31 @@ +# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs + +name: CI + +on: + push: + branches: [ "**" ] + pull_request: + branches: [ "**" ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [22.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm run ci-project + #- run: npm run build --if-present + - run: npm test diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f5dfff..ad440a7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,4 +19,5 @@ "editor.trimAutoWhitespace": false, "files.eol": "\n", "javascript.preferences.quoteStyle": "single", + "typescript.tsdk": "node_modules/typescript/lib", // Use the TypeScript SDK from the current project } diff --git a/package-lock.json b/package-lock.json index 7e80b82..7601969 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "@storybook/react": "^8.4.4", "@storybook/react-vite": "^8.4.4", "@storybook/test": "^8.4.4", + "@types/node": "^22.9.0", "@types/react": "npm:types-react@rc", "@types/react-dom": "npm:types-react-dom@rc", "@vitejs/plugin-react": "^4.3.3", @@ -3713,13 +3714,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", - "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", "dev": true, - "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.19.8" } }, "node_modules/@types/postcss-modules-local-by-default": { diff --git a/package.json b/package.json index 9003c98..3671374 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "scripts": { "gen-package": "node package.json.js", "install-project": "npm run gen-package && npm install --force", + "ci-project": "npm ci --force", "node": "node --import=tsx", "repl": "tsx", "plop": "NODE_OPTIONS=\"--import tsx\" plop", @@ -41,11 +42,11 @@ "build": "vite --config=./vite.config.ts --emptyOutDir build", "storybook:serve": "storybook dev -p 6006", "storybook:build": "storybook build --docs", - "check-types": "tsc --noEmit", + "check:types": "tsc --noEmit", "lint:style": "stylelint 'src/**/*.scss'", - "lint:script": "biome", - "lint": "npm run list:style && npm run lint:script", - "test": "vitest run --root=.", + "lint:script": "biome lint", + "lint": "npm run lint:style && npm run lint:script", + "test": "npm run check:types && npm run lint:style", "test-ui": "vitest --ui", "coverage": "vitest run --coverage", "start": "npm run storybook:serve", @@ -61,6 +62,7 @@ "vite-plugin-lib-inject-css": "^2.1.1", "vite-plugin-svg-icons": "^2.0.1", "typescript": "^5.6.3", + "@types/node": "^22.9.0", "stylelint": "^16.10.0", "stylelint-config-standard-scss": "^13.1.0", "@biomejs/biome": "^1.9.4", diff --git a/package.json.js b/package.json.js index 20ca9b2..6e92c5e 100644 --- a/package.json.js +++ b/package.json.js @@ -38,7 +38,9 @@ const packageConfig = { scripts: { // Utilities 'gen-package': 'node package.json.js', // Update `package.json` + // Use --force currently since we're using React v19 rc. Once peer deps are updated remove this. 'install-project': 'npm run gen-package && npm install --force', + 'ci-project': 'npm ci --force', // CLI 'node': 'node --import=tsx', @@ -59,14 +61,15 @@ const packageConfig = { 'storybook:build': 'storybook build --docs', // Static analysis - 'check-types': 'tsc --noEmit', + 'check:types': 'tsc --noEmit', 'lint:style': `stylelint 'src/**/*.scss'`, - 'lint:script': 'biome', - 'lint': 'npm run list:style && npm run lint:script', + 'lint:script': 'biome lint', + 'lint': 'npm run lint:style && npm run lint:script', // Test // Note: use `vitest run --root=. src/...` to run a single test file - 'test': 'vitest run --root=.', // Need to specify `--root=.` since the vite root is set to `./app` + //'test': 'vitest run --root=.', // Need to specify `--root=.` since the vite root is set to `./app` + 'test': 'npm run check:types && npm run lint:style', 'test-ui': 'vitest --ui', 'coverage': 'vitest run --coverage', @@ -93,6 +96,7 @@ const packageConfig = { // Static analysis 'typescript': '^5.6.3', + '@types/node': '^22.9.0', 'stylelint': '^16.10.0', 'stylelint-config-standard-scss': '^13.1.0', '@biomejs/biome': '^1.9.4', diff --git a/scripts/import.ts b/scripts/import.ts index b0c579f..31645dc 100755 --- a/scripts/import.ts +++ b/scripts/import.ts @@ -26,8 +26,8 @@ const getServices = () => { type ScriptArgs = { values: { - help: boolean | undefined, - silent: boolean | undefined, + help?: undefined | boolean, + silent?: undefined | boolean, }, positionals: Array, }; diff --git a/src/components/forms/context/Form/Form.stories.tsx b/src/components/forms/context/Form/Form.stories.tsx index 4878417..f20efb3 100644 --- a/src/components/forms/context/Form/Form.stories.tsx +++ b/src/components/forms/context/Form/Form.stories.tsx @@ -19,9 +19,9 @@ type FormArgs = React.ComponentProps; type Story = StoryObj; const FormWithState = (props: React.ComponentProps) => { - const action = async (previousState: unknown, formData: FormData) => { + const action = async (previousState: unknown, formData: FormData): Promise => { if (typeof props.action === 'function') { - return props.action?.(formData); + return props.action?.(formData) ?? null; } return null; }; diff --git a/src/components/forms/context/Form/FormOptics.tsx b/src/components/forms/context/Form/FormOptics.tsx index 7649346..3686afa 100644 --- a/src/components/forms/context/Form/FormOptics.tsx +++ b/src/components/forms/context/Form/FormOptics.tsx @@ -16,7 +16,7 @@ export { cl as FormClassNames }; export type FormContext = { formId: string, - accessor: O.OpticFor, + //accessor: O.OpticFor, }; export const FormContext = React.createContext>(null); export const useFormContext = (): FormContext => { @@ -43,7 +43,7 @@ export const Form = (props: FormProps) => { const [wrapperRef, setWrapperRef] = React.useState>(null); // Memoize to keep a stable reference - const context: FormContext = React.useMemo(() => ({ formId }), [formId]); + const context: FormContext = React.useMemo(() => ({ formId }), [formId]); const renderForm = ({ children }: { children: React.ReactNode }) => { return ( diff --git a/src/components/navigations/Stepper/Stepper.module.scss b/src/components/navigations/Stepper/Stepper.module.scss index 2b13c71..e9e8210 100644 --- a/src/components/navigations/Stepper/Stepper.module.scss +++ b/src/components/navigations/Stepper/Stepper.module.scss @@ -15,7 +15,7 @@ &.bk-stepper--vertical { .bk-stepper__item { - &:not(:first-child):not(:first-child) { + &:not(:first-child) { margin-top: bk.$spacing-9; .bk-stepper__item__circle { diff --git a/src/components/navigations/Tabs/Tabs.stories.tsx b/src/components/navigations/Tabs/Tabs.stories.tsx index de58908..8b17a99 100644 --- a/src/components/navigations/Tabs/Tabs.stories.tsx +++ b/src/components/navigations/Tabs/Tabs.stories.tsx @@ -31,7 +31,7 @@ type DefaultTabOption = { className?: string, }; const defaultTabOptions: DefaultTabOption[] = [1,2,3,4].map(index => { - return { index } + return { index }; }); type TabWithTriggerProps = React.PropsWithChildren> & { diff --git a/src/components/overlays/Toast/Toast.module.scss b/src/components/overlays/Toast/Toast.module.scss index d863362..7a1dda9 100644 --- a/src/components/overlays/Toast/Toast.module.scss +++ b/src/components/overlays/Toast/Toast.module.scss @@ -6,7 +6,6 @@ @layer baklava.components { .bk-toast { - width: auto !important; // Override style for .Toastify__toast-container padding: 0 !important; // Override style for .Toastify__toast-container width: 400px !important; // Override style for .Toastify__toast-container @@ -15,7 +14,7 @@ margin-right: bk.$spacing-4 !important; // Override style for .Toastify__toast-body } } - + .bk-toast--success, .bk-toast--info, .bk-toast--error { @@ -42,21 +41,21 @@ // Override style for .Toastify__toast-theme--light background-color: #{bk.$theme-notification-alert-background-default} !important; } - + .bk-toast__icon--success, .bk-toast__icon--info, .bk-toast__icon--error { font-size: 18px; } - + .bk-toast__icon--success { color: #{bk.$theme-notification-success-border-default}; } - + .bk-toast__icon--info { color: #{bk.$theme-notification-informational-border-default}; } - + .bk-toast__icon--error { color: #{bk.$theme-notification-alert-border-default}; } @@ -83,7 +82,7 @@ flex-direction: column; gap: bk.$spacing-1; } - + .bk-toast__message__title { font-weight: bk.$font-weight-semibold; } @@ -107,7 +106,7 @@ opacity: 1 !important; // Override style for .Toastify__progress-bar background-color: #{bk.$theme-progress-bar-fill} !important; // Override style for .Toastify__progress-bar } - + .bk-toast__button, .bk-toast__copy-button { padding: 0; @@ -115,7 +114,7 @@ font-size: 12px; font-weight: bk.$font-weight-semibold; } - + .bk-toast__link { font-weight: bk.$font-weight-semibold; } diff --git a/src/components/overlays/Toast/ToastyOverride.scss b/src/components/overlays/Toast/ToastyOverride.scss index ecb3ac0..9052cfc 100644 --- a/src/components/overlays/Toast/ToastyOverride.scss +++ b/src/components/overlays/Toast/ToastyOverride.scss @@ -2,6 +2,8 @@ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* stylelint-disable selector-class-pattern */ + @use '../../../styling/defs.scss' as bk; // Define styling to override react-toastify's styles, as overriding directly from Toast.module.scss is not possible. diff --git a/src/components/overlays/Tooltip/Tooltip.module.scss b/src/components/overlays/Tooltip/Tooltip.module.scss index 40d0546..9c45338 100644 --- a/src/components/overlays/Tooltip/Tooltip.module.scss +++ b/src/components/overlays/Tooltip/Tooltip.module.scss @@ -39,7 +39,7 @@ background: var(--c1); &::before { - content: ""; + content: ''; position: absolute; z-index: -1; inset: 0; @@ -72,16 +72,16 @@ 100% min(100%,var(--p) + var(--h)*tan(var(--a)/2)), calc(100% + var(--h)) var(--p), 100% max(0% ,var(--p) - var(--h)*tan(var(--a)/2))); - border-image: conic-gradient(var(--c1) 0 0) fill 0/ - max(0%,var(--p) - var(--h)*tan(var(--a)/2)) 0 max(0%,100% - var(--p) - var(--h)*tan(var(--a)/2)) var(--r)/0 var(--h) 0 0; + border-image: conic-gradient(var(--c1) 0 0) fill 0 + / max(0%,var(--p) - var(--h)*tan(var(--a)/2)) 0 max(0%,100% - var(--p) - var(--h)*tan(var(--a)/2)) var(--r)/0 var(--h) 0 0; &::before { clip-path: polygon(100% 0,0 0,0 100%,100% 100%, calc(100% - var(--b)) min(100% - var(--b),var(--p) + var(--h)*tan(var(--a)/2) - var(--b)*tan(45deg - var(--a)/4)), calc(100% + var(--h) - var(--b)/sin(var(--a)/2)) var(--p), calc(100% - var(--b)) max( var(--b),var(--p) - var(--h)*tan(var(--a)/2) + var(--b)*tan(45deg - var(--a)/4))); - border-image: conic-gradient(var(--c2) 0 0) fill 0/ - max(var(--b),var(--p) - var(--h)*tan(var(--a)/2)) 0 max(var(--b),100% - var(--p) - var(--h)*tan(var(--a)/2)) var(--r)/0 var(--h) 0 0; + border-image: conic-gradient(var(--c2) 0 0) fill 0 + / max(var(--b),var(--p) - var(--h)*tan(var(--a)/2)) 0 max(var(--b),100% - var(--p) - var(--h)*tan(var(--a)/2)) var(--r)/0 var(--h) 0 0; } } @mixin bk-tooltip-arrow-bottom { @@ -108,16 +108,16 @@ 0 min(100%,var(--p) + var(--h)*tan(var(--a)/2)), calc(-1*var(--h)) var(--p), 0 max(0% ,var(--p) - var(--h)*tan(var(--a)/2))); - border-image: conic-gradient(var(--c1) 0 0) fill 0/ - max(0%,var(--p) - var(--h)*tan(var(--a)/2)) var(--r) max(0%,100% - var(--p) - var(--h)*tan(var(--a)/2)) 0/0 0 0 var(--h); + border-image: conic-gradient(var(--c1) 0 0) fill 0 + / max(0%,var(--p) - var(--h)*tan(var(--a)/2)) var(--r) max(0%,100% - var(--p) - var(--h)*tan(var(--a)/2)) 0/0 0 0 var(--h); &::before { clip-path: polygon(0 0,100% 0,100% 100%,0 100%, var(--b) min(100% - var(--b),var(--p) + var(--h)*tan(var(--a)/2) - var(--b)*tan(45deg - var(--a)/4)), calc(var(--b)/sin(var(--a)/2) - var(--h)) var(--p), var(--b) max( var(--b),var(--p) - var(--h)*tan(var(--a)/2) + var(--b)*tan(45deg - var(--a)/4))); - border-image: conic-gradient(var(--c2) 0 0) fill 0/ - max(var(--b),var(--p) - var(--h)*tan(var(--a)/2)) var(--r) max(var(--b),100% - var(--p) - var(--h)*tan(var(--a)/2)) 0/0 0 0 var(--h); + border-image: conic-gradient(var(--c2) 0 0) fill 0 + / max(var(--b),var(--p) - var(--h)*tan(var(--a)/2)) var(--r) max(var(--b),100% - var(--p) - var(--h)*tan(var(--a)/2)) 0/0 0 0 var(--h); } } diff --git a/src/layouts/AppLayout/Sidebar/Sidebar.module.scss b/src/layouts/AppLayout/Sidebar/Sidebar.module.scss index 2a34a6e..1ea5598 100644 --- a/src/layouts/AppLayout/Sidebar/Sidebar.module.scss +++ b/src/layouts/AppLayout/Sidebar/Sidebar.module.scss @@ -20,10 +20,6 @@ transition: all 300ms ease-in-out; transition-property: width, grid-template-columns; - &.-collapsed { - width: var(--bk-sizing-5); - } - .bk-app-layout-sidebar__action-collapse { margin: var(--bk-sizing-2); padding: var(--bk-sizing-1) var(--bk-sizing-2); diff --git a/stylelint.config.mjs b/stylelint.config.mjs index 166f40c..ad12cb5 100644 --- a/stylelint.config.mjs +++ b/stylelint.config.mjs @@ -11,7 +11,7 @@ export default { 'rules': { // Override `stylelint-config-standard-scss` rules 'scss/load-partial-extension': 'always', - 'scss/at-import-partial-extension': 'always', + //'scss/at-import-partial-extension': 'always', 'comment-empty-line-before': null, 'comment-whitespace-inside': null, 'scss/comment-no-empty': null, diff --git a/tsconfig.json b/tsconfig.json index 944be04..e5de253 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -47,12 +47,12 @@ "exclude": [ "node_modules", "**/*.spec.ts", + "src/components/navigations/Tabs/Tabs.stories.tsx", // TEMP: need to fix a few type errors ], "include": [ //"vite.config.ts", "app/**/*", "src/**/*", - "scripts/**/*", ], "references": [{ "path": "./tsconfig.node.json" }], } diff --git a/tsconfig.node.json b/tsconfig.node.json index 72a4cfd..42bcf44 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -11,6 +11,7 @@ "emitDeclarationOnly": true, "composite": true, "skipLibCheck": true, + "target": "es2022", "module": "ESNext", "moduleResolution": "bundler", "allowImportingTsExtensions": true, @@ -19,5 +20,6 @@ }, "include": [ "vite.config.ts", + "scripts/**/*", ], }