diff --git a/.circleci/config.yml b/.circleci/config.yml index 12f6b95609..bac6ed16be 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -137,7 +137,7 @@ jobs: - store_test_results: { path: ./reports } - store_artifacts: { path: ./reports } - test-react-16: &test-react + test-react-18: &test-react docker: *docker-node-browsers-image resource_class: xlarge environment: @@ -177,7 +177,7 @@ jobs: - store_test_results: { path: ./reports } - store_artifacts: { path: ./reports } - test-iso-react-16: &test-iso + test-iso-react-18: &test-iso docker: *docker-node-image environment: JUNIT_REPORT_PATH: reports @@ -228,14 +228,14 @@ workflows: requires: [compile] - test-node-libs: requires: [compile] - - test-react-16: + - test-react-18: requires: [compile] - - test-iso-react-16: + - test-iso-react-18: requires: [compile] - deploy-preview: requires: [dist] - deploy-npm: - requires: [dist, lint, test-node-libs, test-react-16, test-iso-react-16] + requires: [dist, lint, test-node-libs, test-react-18, test-iso-react-18] filters: branches: only: diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index 7ac0a4fba9..281576385a 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -7,9 +7,9 @@ about: Something not working as expected? #### Environment -- __Package version(s)__: -- __Operating System__: -- __Browser name and version__: +- **Package version(s)**: +- **Operating System**: +- **Browser name and version**: #### Code Sandbox diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md index 794ee48ede..6aa71e271e 100644 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -7,8 +7,8 @@ about: Propose a new feature or suggest an idea #### Environment -- __Package version(s)__: -- __Browser and OS versions__: +- **Package version(s)**: +- **Browser and OS versions**: #### Feature request diff --git a/.github/ISSUE_TEMPLATE/Support_question.md b/.github/ISSUE_TEMPLATE/Support_question.md index 1818fd3a80..f2062aae5b 100644 --- a/.github/ISSUE_TEMPLATE/Support_question.md +++ b/.github/ISSUE_TEMPLATE/Support_question.md @@ -7,8 +7,8 @@ about: Need help with Blueprint? #### Environment -- __Package version(s)__: -- __Browser and OS versions__: +- **Package version(s)**: +- **Browser and OS versions**: #### Question diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5c54ee8c87..8be00a4f71 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,8 +2,8 @@ #### Checklist -- [ ] Includes tests -- [ ] Update documentation +- [ ] Includes tests +- [ ] Update documentation diff --git a/.stylelintrc b/.stylelintrc index 294c5664c1..f4ed341223 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -12,7 +12,7 @@ "color-function-notation": "legacy", "declaration-empty-line-before": null, "no-invalid-position-at-import-rule": [true, { - "ignoreAtRules": ["use", "forward"] + "ignoreAtRules": ["use"] }], "scss/media-feature-value-dollar-variable": null, "selector-max-universal": 1 diff --git a/.yarn/patches/react-day-picker-npm-7.4.9-8853eff118.patch b/.yarn/patches/react-day-picker-npm-7.4.9-8853eff118.patch new file mode 100644 index 0000000000..a40ffecda0 --- /dev/null +++ b/.yarn/patches/react-day-picker-npm-7.4.9-8853eff118.patch @@ -0,0 +1,31 @@ +diff --git a/types/Props.d.ts b/types/Props.d.ts +index f8fcd45ab3048d9b34709eba1797597ac2facdec..3afa05a42f485ff23899f20df2ff9d85bf588eed 100644 +--- a/types/Props.d.ts ++++ b/types/Props.d.ts +@@ -44,7 +44,7 @@ export interface DayPickerProps { + captionElement?: + | React.ReactElement> + | React.ComponentClass +- | React.SFC; ++ | React.FC; + className?: string; + classNames?: ClassNames; + containerProps?: React.DetailedHTMLProps< +@@ -69,7 +69,7 @@ export interface DayPickerProps { + navbarElement?: + | React.ReactElement> + | React.ComponentClass +- | React.SFC; ++ | React.FC; + numberOfMonths?: number; + onBlur?: (e: React.FocusEvent) => void; + onCaptionClick?: (month: Date, e: React.MouseEvent) => void; +@@ -142,7 +142,7 @@ export interface DayPickerProps { + weekdayElement?: + | React.ReactElement> + | React.ComponentClass +- | React.SFC; ++ | React.FC; + weekdaysLong?: string[]; + weekdaysShort?: string[]; + tabIndex?: number; diff --git a/CHANGELOG.md b/CHANGELOG.md index b0467a9cb3..cfaf526b4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,7 @@ -Changelog ---------- +# Changelog Changelogs for `@blueprintjs/*` packages currently live in the project's Github wiki: -- [5.x Changelog](https://github.com/palantir/blueprint/wiki/5.x-Changelog) -- [4.x Changelog](https://github.com/palantir/blueprint/wiki/4.x-Changelog) -- [3.x Changelog](https://github.com/palantir/blueprint/wiki/3.x-Changelog) +- [5.x Changelog](https://github.com/palantir/blueprint/wiki/5.x-Changelog) +- [4.x Changelog](https://github.com/palantir/blueprint/wiki/4.x-Changelog) +- [3.x Changelog](https://github.com/palantir/blueprint/wiki/3.x-Changelog) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83906ec998..147840f0d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,8 +36,8 @@ A typical contributor workflow looks like this: 1. Create a new feature branch. We like to use a format like `[your-initials]/[short-name]`: for example, `bd/refactor-buttons`. -1. Run development build tasks - follow the ["Developing libraries" steps in the README](https://github.com/palantir/blueprint/blob/develop/README.md#developing-libraries). -1. Visit http://localhost:9000 in your web browser to see the interactive docs web app. +2. Run development build tasks - follow the ["Developing libraries" steps in the README](https://github.com/palantir/blueprint/blob/develop/README.md#developing-libraries). +3. Visit http://localhost:9000 in your web browser to see the interactive docs web app. 4. Write some code. :hammer: **Refer to the wiki in this repo for detailed instructions on:** - [Development practices](https://github.com/palantir/blueprint/wiki/Development-practices) - [Coding guidelines](https://github.com/palantir/blueprint/wiki/Coding-guidelines) @@ -45,26 +45,15 @@ A typical contributor workflow looks like this: 5. Ensure your code **compiles properly** and is **tested**, **linted**, and **formatted**. - Run `yarn compile` at the repo root to build all libraries. - Run `yarn bundle` at the repo root to build the Blueprint documentation and other bundles. - - Add unit tests as necessary when fixing bugs or adding features; run them with `yarn test` - in the relevant package directory. - - Linting is best handled by your editor for real-time feedback (see - [Editor integration](https://github.com/palantir/blueprint/wiki/Editor-integration)). Run - `yarn lint` to be 100% safe. + - Add unit tests as necessary when fixing bugs or adding features; run them with `yarn test` in the relevant package directory. + - Linting is best handled by your editor for real-time feedback (see [Editor integration](https://github.com/palantir/blueprint/wiki/Editor-integration)). Run `yarn lint` to be 100% safe. - TypeScript lint errors can often be automatically fixed by ESLint. Run lint fixes with `yarn lint-fix`. - - Code formatting is enforced using [Prettier](https://prettier.io/). These errors can be fixed in your editor - through the Prettier extension (make sure you have set up the editor integrations linked above). - __Formatting checks will not run__ during the `yarn lint` package script. - Instead, when using the CLI or in a CI environment, you should run the `yarn format` script to fix all - formatting issues across the Blueprint monorepo. -1. Submit a Pull Request on GitHub and fill out the template. - - ⚠️ __DO NOT enable CircleCI for your fork of Blueprint.__ When you open a PR, your branch will be checked out - and built in palantir's CI pipeline automatically. There is no need to enable the CI build for your fork's - pipeline. If you do, this may cause problems in the CI build. - - If you have already opened a PR where CircleCI built the code in your own personal or organization pipeline, - you will likely have to disable the project from building at app.circleci.com/settings/project/github/\/website - and open a new PR. -1. Team members will review your code and merge it after approvals. + - Code formatting is enforced using [Prettier](https://prettier.io/). These errors can be fixed in your editor through the Prettier extension (make sure you have set up the editor integrations linked above). **Formatting checks will not run** during the `yarn lint` package script. Instead, when using the CLI or in a CI environment you should run the `yarn format` script to fix all formatting issues across the Blueprint monorepo. +6. Submit a Pull Request on GitHub and fill out the template. + - ⚠️ **DO NOT enable CircleCI for your fork of Blueprint.** When you open a PR, your branch will be checked out and built in palantir's CI pipeline automatically. There is no need to enable the CI build for your fork's pipeline. If you do, this may cause problems in the CI build. + - If you have already opened a PR where CircleCI built the code in your own personal or organization pipeline, you will likely have to disable the project from building at app.circleci.com/settings/project/github/\/website and open a new PR. +7. Team members will review your code and merge it after approvals. - You may be asked to make modifications to code style or to fix bugs you may have not noticed. - Please respond to comments in a timely fashion (even if to tell us you need more time). - _Do not_ amend commits and `push --force` as they break the PR history. Please add more commits; we squash each PR to a single commit on merge. -1. Hooray, you contributed! :tophat: +8. Hooray, you contributed! :tophat: diff --git a/README.md b/README.md index 48d2519d8a..c240042371 100644 --- a/README.md +++ b/README.md @@ -84,15 +84,15 @@ First, ensure you have `nvm` ([Node Version Manager](https://github.com/nvm-sh/n After cloning this repo, run: 1. `nvm use` to use the supported Node version for Blueprint development. -1. `corepack enable` to activate [Yarn](https://yarnpkg.com/getting-started) as the Node package manager. -1. `yarn` to install all dependencies for the monorepo. - 1. If seeing an error like "Error when performing the request ...", you may be using a VPN that needs to be disabled to install the dependencies. -1. If running on Windows: +2. `corepack enable` to activate [Yarn](https://yarnpkg.com/getting-started) as the Node package manager. +3. `yarn` to install all dependencies for the monorepo. + 1. If seeing an error like "Error when performing the request ...", you may be using a VPN that needs to be disabled to install the dependencies. +4. If running on Windows: 1. `npm install -g windows-build-tools` to install build tools globally - 1. Ensure `bash` is your configured script-shell by running:
+ 2. Ensure `bash` is your configured script-shell by running:
`npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"` -1. `yarn verify` to ensure you have all the build tooling working properly. - 1. There may currently be some errors when running this step, even though everything is set up properly, see https://github.com/palantir/blueprint/issues/6926 for more info. +5. `yarn verify` to ensure you have all the build tooling working properly. + 1. There may currently be some errors when running this step, even though everything is set up properly, see https://github.com/palantir/blueprint/issues/6926 for more info. ### Incorporating upstream changes @@ -101,47 +101,33 @@ If you were previously in a working state and have just pulled new code from `de - If there were package dependency changes, run `yarn` at the root. - This command is very quick if there are no new things to install. - Run `yarn compile` to get the latest built versions of the library packages in this repo. - - This command is quicker than `yarn verify` since it doesn't build the application packages (`docs-app`, - `landing-app`, etc.) or run tests + - This command is quicker than `yarn verify` since it doesn't build the application packages (`docs-app`,`landing-app`, etc.) or run tests ### Developing libraries There are a few ways to run development scripts, here they are listed from simplest to more advanced usage: -- Run `yarn dev` from the root directory to watch changes across all packages and run the docs application with - webpack-dev-server. +- Run `yarn dev` from the root directory to watch changes across all packages and run the docs application with webpack-dev-server. - Alternately, most libraries have a dev script to run the docs app _and_ watch changes to only that package: - `yarn dev:core` - `yarn dev:docs` - `yarn dev:datetime` - `yarn dev:select` - `yarn dev:table` -- Lastly, if you want to control exactly which dev scripts are run and view the console output in the cleanest way, - we recommend opening separate terminal windows or splits and running local package dev tasks in each one. This is - the recommended workflow for frequent contributors and advanced developers. For example, to test changes in the core - and icons packages, you would run the following in separate terminals: +- Lastly, if you want to control exactly which dev scripts are run and view the console output in the cleanest way, we recommend opening separate terminal windows or splits and running local package dev tasks in each one. This is the recommended workflow for frequent contributors and advanced developers. For example, to test changes in the core and icons packages, you would run the following in separate terminals: - `cd packages/core && yarn dev` - `cd packages/icons && yarn dev` - `cd packages/docs-app && yarn dev` ### Updating documentation -Much of Blueprint's documentation lives inside source code as JSDoc comments in `.tsx` files and KSS markup in `.scss` -files. This documentation is extracted and converted into static JSON data using -[documentalist](https://github.com/palantir/documentalist/). - -If you are updating documentation sources (_not_ the docs UI code which lives in `packages/docs-app` or the docs theme -in `packages/docs-theme`), you'll need to run `yarn compile` from `packages/docs-data` to see changes reflected in the -application. For simplicity, an alias script `yarn docs-data` exists in the root to minimize directory hopping. +Much of Blueprint's documentation lives inside source code as JSDoc comments in `.tsx` files and KSS markup in `.scss` files. This documentation is extracted and converted into static JSON data using [documentalist](https://github.com/palantir/documentalist/). If you are updating documentation sources (_not_ the docs UI code which lives in `packages/docs-app` or the docs theme in `packages/docs-theme`), you'll need to run `yarn compile` from `packages/docs-data` to see changes reflected in the application. For simplicity, an alias script `yarn docs-data` exists in the root to minimize directory hopping. ### Updating icons -The [One-time setup](#one-time-setup) and [Incorporating upstream changes](#incorporating-upstream-changes) steps should -produce the generated source code in this repo used to build the icons documentation. This is sufficient for most -development workflows. +The [One-time setup](#one-time-setup) and [Incorporating upstream changes](#incorporating-upstream-changes) steps should produce the generated source code in this repo used to build the icons documentation. This is sufficient for most development workflows. -If you are updating icons or adding new ones, you'll need to run `yarn compile` in `packages/icons` to see those changes -reflected before running any of the dev scripts. +If you are updating icons or adding new ones, you'll need to run `yarn compile` in `packages/icons` to see those changes reflected before running any of the dev scripts. ## License diff --git a/package.json b/package.json index 485cadc333..ea0fcb4d88 100644 --- a/package.json +++ b/package.json @@ -34,15 +34,15 @@ "verify": "npm-run-all -s compile dist -p test lint format-check" }, "dependencies": { - "@lerna-lite/cli": "^3.2.1", - "@lerna-lite/version": "^3.2.1", + "@lerna-lite/cli": "^3.11.0", + "@lerna-lite/version": "^3.11.0", "@types/chai": "~4.3.11", "@types/enzyme": "~3.10.18", "@types/enzyme-adapter-react-16": "~1.0.9", "@types/mocha": "~10.0.6", "@types/node": "~20.11.6", - "@types/react": "~16.14.55", - "@types/react-dom": "~16.9.24", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "@types/react-transition-group": "~4.4.10", "@types/sinon": "~17.0.3", "@types/yargs": "~17.0.32", @@ -65,7 +65,7 @@ "yarn-deduplicate": "^6.0.2" }, "resolutions": { - "@types/react": "16.14.55" + "@types/react": "18.3.12" }, "engines": { "node": ">=20.11" diff --git a/packages/core/changelog/@unreleased/pr-7137.v2.yml b/packages/core/changelog/@unreleased/pr-7137.v2.yml new file mode 100644 index 0000000000..5ddd8f0717 --- /dev/null +++ b/packages/core/changelog/@unreleased/pr-7137.v2.yml @@ -0,0 +1,5 @@ +type: improvement +improvement: + description: Update React version check in Portal component to support React 18 and newer versions. + links: + - https://github.com/palantir/blueprint/pull/7137 diff --git a/packages/core/package.json b/packages/core/package.json index e3e03f7684..970d1f8628 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@blueprintjs/core", - "version": "5.16.2", + "version": "5.16.4", "description": "Core styles & components", "main": "lib/cjs/index.js", "module": "lib/esm/index.js", @@ -75,16 +75,16 @@ "@blueprintjs/node-build-scripts": "workspace:^", "@blueprintjs/test-commons": "workspace:^", "@testing-library/dom": "^10.4.0", - "@testing-library/react": "^12.1.5", + "@testing-library/react": "^16.1.0", "@testing-library/user-event": "^13.5.0", "@types/use-sync-external-store": "0.0.6", "enzyme": "^3.11.0", "karma": "^6.4.2", "mocha": "^10.2.0", "npm-run-all": "^4.1.5", - "react": "^16.14.0", - "react-dom": "^16.14.0", - "react-test-renderer": "^16.14.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-test-renderer": "^18.3.1", "typescript": "~5.3.3", "webpack-cli": "^5.1.4" }, diff --git a/packages/core/src/_dark-theme.scss b/packages/core/src/_dark-theme.scss index a68c7cb973..11d15b3149 100644 --- a/packages/core/src/_dark-theme.scss +++ b/packages/core/src/_dark-theme.scss @@ -1,6 +1,5 @@ // Copyright 2021 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "common/variables" as *; .#{$ns}-dark { // this tells the browser to use a dark theme UI, which is most useful for enabling diff --git a/packages/core/src/_reset.scss b/packages/core/src/_reset.scss index 196e84dfe1..b5cb3c51b6 100644 --- a/packages/core/src/_reset.scss +++ b/packages/core/src/_reset.scss @@ -1,9 +1,8 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "common/variables" as *; -@use "common/color-aliases" as *; -@use "common/mixins" as *; +@import "common/variables"; +@import "common/mixins"; // Apply a natural box layout model to all elements, but allow components to change as necessary html { diff --git a/packages/core/src/_typography.scss b/packages/core/src/_typography.scss index 7030553668..4557b1d2c2 100644 --- a/packages/core/src/_typography.scss +++ b/packages/core/src/_typography.scss @@ -1,14 +1,11 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "common/variables" as *; -@use "common/variables-extended" as *; -@use "common/color-aliases" as *; -@use "common/mixins" as *; -@use "common/typography-colors" as *; -@use "components/icon/icon" as *; -@use "components/html-table/html-table" as *; +@import "common/variables"; +@import "common/variables-extended"; +@import "common/mixins"; +@import "common/typography-colors"; +@import "components/icon/icon"; @include pt-typography-colors(); /* diff --git a/packages/core/src/accessibility/_focus-states.scss b/packages/core/src/accessibility/_focus-states.scss index 9092f0f26d..e9383ab3a6 100644 --- a/packages/core/src/accessibility/_focus-states.scss +++ b/packages/core/src/accessibility/_focus-states.scss @@ -1,7 +1,5 @@ // Copyright 2016 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../common/variables" as *; -@use "../common/mixins" as *; :focus { @include focus-outline(); diff --git a/packages/core/src/blueprint.scss b/packages/core/src/blueprint.scss index 8affcd0006..497440e8ff 100644 --- a/packages/core/src/blueprint.scss +++ b/packages/core/src/blueprint.scss @@ -6,8 +6,13 @@ Licensed under the Apache License, Version 2.0. */ // Import files in the same order that they are documented in the docs -@forward "reset"; -@forward "typography"; -@forward "accessibility/focus-states"; -@forward "dark-theme"; -@forward "components/index"; +@import "@blueprintjs/colors/lib/scss/colors"; +@import "common/variables"; +@import "common/variables-extended"; +@import "common/mixins"; + +@import "reset"; +@import "typography"; +@import "accessibility/focus-states"; +@import "dark-theme"; +@import "components/index"; diff --git a/packages/core/src/common/_color-aliases.scss b/packages/core/src/common/_color-aliases.scss index 05ba6de177..427cadcc33 100644 --- a/packages/core/src/common/_color-aliases.scss +++ b/packages/core/src/common/_color-aliases.scss @@ -9,7 +9,6 @@ // - A limited subset of Sass syntax is supported. All syntax inluded here must be able to get parsed by the // `generate-css-variables` script in @blueprintjs/node-build-scripts. For example, "sass:math" is unsupported. // ---------------------------------------------------------------------------- -@use "@blueprintjs/colors/lib/scss/colors" as *; $pt-intent-primary: $blue3 !default; $pt-intent-success: $green3 !default; diff --git a/packages/core/src/common/_flex.scss b/packages/core/src/common/_flex.scss index 5ca8fa57fc..46bf5ace1f 100644 --- a/packages/core/src/common/_flex.scss +++ b/packages/core/src/common/_flex.scss @@ -1,6 +1,5 @@ // Copyright 2018 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "variables" as *; // this element becomes a flex container in the given direction. // supply `$margin` to put space between each child. diff --git a/packages/core/src/common/_mixins.scss b/packages/core/src/common/_mixins.scss index d7323eff49..e12f5415a5 100644 --- a/packages/core/src/common/_mixins.scss +++ b/packages/core/src/common/_mixins.scss @@ -2,10 +2,8 @@ // Licensed under the Apache License, Version 2.0. @use "sass:math"; -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "color-aliases" as *; -@use "variables" as *; -@use "flex" as *; +@import "@blueprintjs/colors/lib/scss/colors"; +@import "flex"; $pt-intent-colors: ( "primary": $pt-intent-primary, diff --git a/packages/core/src/common/_react-transition.scss b/packages/core/src/common/_react-transition.scss index 0b0415db30..67bd5b7dfe 100644 --- a/packages/core/src/common/_react-transition.scss +++ b/packages/core/src/common/_react-transition.scss @@ -1,8 +1,6 @@ // Copyright 2016 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "variables" as *; - /* A mixin to generate the classes for a React CSSTransition which animates any number of CSS properties at once. diff --git a/packages/core/src/common/_typography-colors.scss b/packages/core/src/common/_typography-colors.scss index 455476c1d9..ab584742f3 100644 --- a/packages/core/src/common/_typography-colors.scss +++ b/packages/core/src/common/_typography-colors.scss @@ -1,11 +1,9 @@ // Copyright 2022 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "variables" as *; -@use "variables-extended" as *; -@use "color-aliases" as *; -@use "mixins" as *; +@import "variables"; +@import "variables-extended"; +@import "mixins"; @mixin pt-typography-colors() { // N.B. we can't declare any global colors here because this mixin is @included at diff --git a/packages/core/src/common/_variables-extended.scss b/packages/core/src/common/_variables-extended.scss index 6e0d962a2c..6a49cd2a19 100644 --- a/packages/core/src/common/_variables-extended.scss +++ b/packages/core/src/common/_variables-extended.scss @@ -1,7 +1,7 @@ // Copyright 2022 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "variables" as *; +@import "variables"; // ---------------------------------------------------------------------------- // This file contains additional common variables which we do not want to export in public API via variables.scss, diff --git a/packages/core/src/common/_variables.scss b/packages/core/src/common/_variables.scss index 51998a0ff3..b7472c94a1 100644 --- a/packages/core/src/common/_variables.scss +++ b/packages/core/src/common/_variables.scss @@ -1,8 +1,8 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "color-aliases" as *; +@import "color-aliases"; +@import "mixins"; // ---------------------------------------------------------------------------- // This file is part of the public Sass API of @blueprintjs/core. diff --git a/packages/core/src/common/boundary.ts b/packages/core/src/common/boundary.ts index 3718ea8ef7..b842fa9230 100644 --- a/packages/core/src/common/boundary.ts +++ b/packages/core/src/common/boundary.ts @@ -17,7 +17,7 @@ /** Boundary of a one-dimensional interval. */ export const Boundary = { START: "start" as const, - // tslint:disable-next-line:object-literal-sort-keys + /* eslint-disable-next-line sort-keys */ END: "end" as const, }; // eslint-disable-next-line @typescript-eslint/no-redeclare diff --git a/packages/core/src/common/elevation.ts b/packages/core/src/common/elevation.ts index 1dcc474825..584989b1fe 100644 --- a/packages/core/src/common/elevation.ts +++ b/packages/core/src/common/elevation.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -// tslint:disable:object-literal-sort-keys +/* eslint-disable sort-keys */ export const Elevation = { ZERO: 0 as const, ONE: 1 as const, diff --git a/packages/core/src/common/intent.ts b/packages/core/src/common/intent.ts index f7375e9753..85bd05e425 100644 --- a/packages/core/src/common/intent.ts +++ b/packages/core/src/common/intent.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -// tslint:disable:object-literal-sort-keys +/* eslint-disable sort-keys */ /** * The four basic intents. diff --git a/packages/core/src/common/keyCodes.ts b/packages/core/src/common/keyCodes.ts index 2540b1a2ff..7275503a0d 100644 --- a/packages/core/src/common/keyCodes.ts +++ b/packages/core/src/common/keyCodes.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -// tslint:disable object-literal-sort-keys +/* eslint-disable sort-keys */ /** @deprecated use named keys instead of key codes */ export const KeyCodes = { diff --git a/packages/core/src/common/utils/domUtils.ts b/packages/core/src/common/utils/domUtils.ts index e153317f45..6cdfae3113 100644 --- a/packages/core/src/common/utils/domUtils.ts +++ b/packages/core/src/common/utils/domUtils.ts @@ -158,3 +158,34 @@ export function clickElementOnKeyPress(keys: string[]) { } }; } + +/** + * Selector for all possible focusable items. + * + * Derived from this SO question: {@link https://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus} + * + * Note: Order may not be correct if children elements use tabindex values > 0. + */ +const SELECTOR_FOCUSABLE = [ + 'a[href]:not([tabindex="-1"])', + 'button:not([disabled]):not([tabindex="-1"])', + 'details:not([tabindex="-1"])', + 'input:not([disabled]):not([tabindex="-1"])', + 'select:not([disabled]):not([tabindex="-1"])', + 'textarea:not([disabled]):not([tabindex="-1"])', + '[tabindex]:not([tabindex="-1"])', +].join(","); + +/** + * Gets all focusable elements within the given element. + * + * Selector derived from this SO question: {@link https://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus} + * + * Note: Order may not be correct if children elements use tabindex values > 0. + * + * @param {HTMLElement} element - The element to search within. + * @returns {HTMLElement[]} An array of focusable elements. + */ +export function getFocusableElements(element: HTMLElement): HTMLElement[] { + return Array.from(element.querySelectorAll(SELECTOR_FOCUSABLE)); +} diff --git a/packages/core/src/common/utils/index.ts b/packages/core/src/common/utils/index.ts index b936abd470..52bac16aca 100644 --- a/packages/core/src/common/utils/index.ts +++ b/packages/core/src/common/utils/index.ts @@ -20,6 +20,7 @@ export { elementIsOrContains, elementIsTextInput, getActiveElement, + getFocusableElements, throttle, throttleEvent, throttleReactEventCallback, diff --git a/packages/core/src/common/utils/reactUtils.ts b/packages/core/src/common/utils/reactUtils.ts index 661686da38..f587fb783e 100644 --- a/packages/core/src/common/utils/reactUtils.ts +++ b/packages/core/src/common/utils/reactUtils.ts @@ -92,12 +92,12 @@ export function isReactElement(child: React.ReactNode): child is React. ); } -function isReactFragment(child: React.ReactNode): child is React.ReactFragment { +function isReactFragment(child: React.ReactNode): child is Iterable { // bit hacky, but generally works return typeof (child as any).type === "symbol"; } -function isReactNodeArray(child: React.ReactNode): child is React.ReactNodeArray { +function isReactNodeArray(child: React.ReactNode): child is React.ReactNode[] { return Array.isArray(child); } @@ -124,6 +124,7 @@ export function isElementOfType

( ); } -export function isReact18(): boolean { - return React.version.startsWith("18"); +export function isReact18OrHigher(): boolean { + const majorVersion = parseInt(React.version.split(".")[0], 10); + return majorVersion >= 18; } diff --git a/packages/core/src/components/_index.scss b/packages/core/src/components/_index.scss index 406860ca7d..368d842ef9 100644 --- a/packages/core/src/components/_index.scss +++ b/packages/core/src/components/_index.scss @@ -1,49 +1,49 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@forward "alert/alert"; -@forward "breadcrumbs/breadcrumbs"; -@forward "button/button"; -@forward "button/button-group"; -@forward "callout/callout"; -@forward "card/card"; -@forward "card-list/card-list"; -@forward "collapse/collapse"; -@forward "context-menu/context-menu"; -@forward "control-card/control-card"; -@forward "divider/divider"; -@forward "dialog/dialog"; -@forward "dialog/dialog-body"; -@forward "dialog/dialog-footer"; -@forward "dialog/multistep-dialog"; -@forward "drawer/drawer"; -@forward "editable-text/editable-text"; -@forward "entity-title/entity-title"; -@forward "forms/index"; -@forward "html-select/html-select"; -@forward "html-table/html-table"; -@forward "hotkeys/hotkeys"; -@forward "icon/icon"; -@forward "menu/menu"; -@forward "navbar/navbar"; -@forward "non-ideal-state/non-ideal-state"; -@forward "overflow-list/overflow-list"; -@forward "overlay/overlay"; -@forward "panel-stack/panel-stack"; -@forward "panel-stack2/panel-stack2"; -@forward "popover/popover"; -@forward "portal/portal"; -@forward "progress-bar/progress-bar"; -@forward "section/section"; -@forward "segmented-control/segmented-control"; -@forward "skeleton/skeleton"; -@forward "slider/slider"; -@forward "spinner/spinner"; -@forward "tabs/tabs"; -@forward "tag/tag"; -@forward "tag/compound-tag"; -@forward "tag-input/tag-input"; -@forward "tag-input/resizable-input"; -@forward "toast/toast"; -@forward "tooltip/tooltip"; -@forward "tree/tree"; +@import "alert/alert"; +@import "breadcrumbs/breadcrumbs"; +@import "button/button"; +@import "button/button-group"; +@import "callout/callout"; +@import "card/card"; +@import "card-list/card-list"; +@import "collapse/collapse"; +@import "context-menu/context-menu"; +@import "control-card/control-card"; +@import "divider/divider"; +@import "dialog/dialog"; +@import "dialog/dialog-body"; +@import "dialog/dialog-footer"; +@import "dialog/multistep-dialog"; +@import "drawer/drawer"; +@import "editable-text/editable-text"; +@import "entity-title/entity-title"; +@import "forms/index"; +@import "html-select/html-select"; +@import "html-table/html-table"; +@import "hotkeys/hotkeys"; +@import "icon/icon"; +@import "menu/menu"; +@import "navbar/navbar"; +@import "non-ideal-state/non-ideal-state"; +@import "overflow-list/overflow-list"; +@import "overlay/overlay"; +@import "panel-stack/panel-stack"; +@import "panel-stack2/panel-stack2"; +@import "popover/popover"; +@import "portal/portal"; +@import "progress-bar/progress-bar"; +@import "section/section"; +@import "segmented-control/segmented-control"; +@import "skeleton/skeleton"; +@import "slider/slider"; +@import "spinner/spinner"; +@import "tabs/tabs"; +@import "tag/tag"; +@import "tag/compound-tag"; +@import "tag-input/tag-input"; +@import "tag-input/resizable-input"; +@import "toast/toast"; +@import "tooltip/tooltip"; +@import "tree/tree"; diff --git a/packages/core/src/components/alert/_alert.scss b/packages/core/src/components/alert/_alert.scss index f29152365b..18a294d7da 100644 --- a/packages/core/src/components/alert/_alert.scss +++ b/packages/core/src/components/alert/_alert.scss @@ -1,7 +1,7 @@ // Copyright 2016 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/variables" as *; +@import "../../common/variables"; .#{$ns}-alert { max-width: $pt-grid-size * 40; diff --git a/packages/core/src/components/alert/alert.md b/packages/core/src/components/alert/alert.md index fc7a31bc8c..8db2f33001 100644 --- a/packages/core/src/components/alert/alert.md +++ b/packages/core/src/components/alert/alert.md @@ -1,8 +1,8 @@ @# Alert -__Alerts__ notify users of important information and force them to acknowledge the alert content before continuing. +**Alerts** notify users of important information and force them to acknowledge the alert content before continuing. -Although similar to [__Dialog__](#core/components/dialog), an alert is more restrictive and should only be used for +Although similar to [**Dialog**](#core/components/dialog), an alert is more restrictive and should only be used for important information. By default, the user can only exit the alert by clicking one of the confirmation buttons; clicking the overlay or pressing the `esc` key will not close the alert. These interactions can be enabled via props. @@ -10,7 +10,7 @@ clicking the overlay or pressing the `esc` key will not close the alert. These i @## Props interface -__Alert__ only supports controlled usage through the `isOpen` prop. Use the `onConfirm` and `onCancel` props to respond +**Alert** only supports controlled usage through the `isOpen` prop. Use the `onConfirm` and `onCancel` props to respond to those interactions separately, or use `onClose` to handle both at the same time. @interface AlertProps diff --git a/packages/core/src/components/alert/alert.tsx b/packages/core/src/components/alert/alert.tsx index 84d21563df..15a3cf9fa9 100644 --- a/packages/core/src/components/alert/alert.tsx +++ b/packages/core/src/components/alert/alert.tsx @@ -1,5 +1,5 @@ /* - * Copyright 2015 Palantir Technologies, Inc. All rights reserved. + * Copyright 2025 Palantir Technologies, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,13 @@ import classNames from "classnames"; import * as React from "react"; -import { - AbstractPureComponent, - Classes, - DISPLAYNAME_PREFIX, - type Intent, - type MaybeElement, - type Props, -} from "../../common"; +import { Classes, DISPLAYNAME_PREFIX, type Intent, type MaybeElement, type Props } from "../../common"; import { ALERT_WARN_CANCEL_ESCAPE_KEY, ALERT_WARN_CANCEL_OUTSIDE_CLICK, ALERT_WARN_CANCEL_PROPS, } from "../../common/errors"; +import { useValidateProps } from "../../hooks/useValidateProps"; import { Button } from "../button/buttons"; import { Dialog } from "../dialog/dialog"; import { Icon, type IconName } from "../icon/icon"; @@ -122,21 +116,21 @@ export interface AlertProps extends OverlayLifecycleProps, Props { * * If any of the `cancel` props are defined, then either `onCancel` or `onClose` must be defined. */ - onCancel?(evt?: React.SyntheticEvent): void; + onCancel?: (event?: React.SyntheticEvent) => void; /** * Handler invoked when the confirm button is clicked. Alerts can be **confirmed** in the following ways: * - clicking the confirm button * - focusing on the confirm button and pressing `enter` or `space` */ - onConfirm?(evt?: React.SyntheticEvent): void; + onConfirm?: (event?: React.SyntheticEvent) => void; /** * Handler invoked when the Alert is confirmed or canceled; see `onConfirm` and `onCancel` for more details. * First argument is `true` if confirmed, `false` otherwise. * This is an alternative to defining separate `onConfirm` and `onCancel` handlers. */ - onClose?(confirmed: boolean, evt?: React.SyntheticEvent): void; + onClose?: (confirmed: boolean, event?: React.SyntheticEvent) => void; } /** @@ -144,75 +138,76 @@ export interface AlertProps extends OverlayLifecycleProps, Props { * * @see https://blueprintjs.com/docs/#core/components/alert */ -export class Alert extends AbstractPureComponent { - public static defaultProps: AlertProps = { - canEscapeKeyCancel: false, - canOutsideClickCancel: false, - confirmButtonText: "OK", - isOpen: false, - loading: false, - }; - - public static displayName = `${DISPLAYNAME_PREFIX}.Alert`; - - public render() { - const { - canEscapeKeyCancel, - canOutsideClickCancel, - children, - className, - icon, - intent, - loading, - cancelButtonText, - confirmButtonText, - onClose, - ...overlayProps - } = this.props; - return ( -

-
- -
{children}
-
-
-
-
- ); - } - - protected validateProps(props: AlertProps) { - if (props.onClose == null && (props.cancelButtonText == null) !== (props.onCancel == null)) { +export const Alert: React.FC = props => { + const { + cancelButtonText, + canEscapeKeyCancel = false, + canOutsideClickCancel = false, + children, + className, + confirmButtonText = "OK", + icon, + intent, + isOpen = false, + loading = false, + onCancel, + onClose, + onConfirm, + ...overlayProps + } = props; + + useValidateProps(() => { + if (onClose == null && (cancelButtonText == null) !== (onCancel == null)) { console.warn(ALERT_WARN_CANCEL_PROPS); } - const hasCancelHandler = props.onCancel != null || props.onClose != null; - if (props.canEscapeKeyCancel && !hasCancelHandler) { + const hasCancelHandler = onCancel != null || onClose != null; + if (canEscapeKeyCancel && !hasCancelHandler) { console.warn(ALERT_WARN_CANCEL_ESCAPE_KEY); } - if (props.canOutsideClickCancel && !hasCancelHandler) { + if (canOutsideClickCancel && !hasCancelHandler) { console.warn(ALERT_WARN_CANCEL_OUTSIDE_CLICK); } - } - - private handleCancel = (evt?: React.SyntheticEvent) => this.internalHandleCallbacks(false, evt); - - private handleConfirm = (evt: React.SyntheticEvent) => this.internalHandleCallbacks(true, evt); - - private internalHandleCallbacks(confirmed: boolean, evt?: React.SyntheticEvent) { - const { onCancel, onClose, onConfirm } = this.props; - (confirmed ? onConfirm : onCancel)?.(evt); - onClose?.(confirmed, evt); - } -} + }, [canEscapeKeyCancel, canOutsideClickCancel, cancelButtonText, onCancel, onClose]); + + const internalHandleCallbacks = React.useCallback( + (confirmed: boolean, event?: React.SyntheticEvent) => { + (confirmed ? onConfirm : onCancel)?.(event); + onClose?.(confirmed, event); + }, + [onCancel, onClose, onConfirm], + ); + + const handleCancel = React.useCallback( + (event?: React.SyntheticEvent) => internalHandleCallbacks(false, event), + [internalHandleCallbacks], + ); + + const handleConfirm = React.useCallback( + (event: React.SyntheticEvent) => internalHandleCallbacks(true, event), + [internalHandleCallbacks], + ); + + return ( + +
+ +
{children}
+
+
+
+
+ ); +}; + +Alert.displayName = `${DISPLAYNAME_PREFIX}.Alert`; diff --git a/packages/core/src/components/breadcrumbs/_breadcrumbs.scss b/packages/core/src/components/breadcrumbs/_breadcrumbs.scss index 0ece8e2ac9..30c0fa1403 100644 --- a/packages/core/src/components/breadcrumbs/_breadcrumbs.scss +++ b/packages/core/src/components/breadcrumbs/_breadcrumbs.scss @@ -1,10 +1,8 @@ // Copyright 2016 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "@blueprintjs/icons/lib/scss/variables" as *; -@use "../../common/variables" as *; -@use "../../common/color-aliases" as *; +@import "@blueprintjs/icons/lib/scss/variables"; +@import "../../common/variables"; /* Breadcrumbs diff --git a/packages/core/src/components/button/_button-group.scss b/packages/core/src/components/button/_button-group.scss index 555767f7bb..dd8b44b803 100644 --- a/packages/core/src/components/button/_button-group.scss +++ b/packages/core/src/components/button/_button-group.scss @@ -1,9 +1,9 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/variables" as *; -@use "../forms/common" as *; -@use "./common" as *; +@import "../../common/variables"; +@import "../forms/common"; +@import "./common"; /* Button groups diff --git a/packages/core/src/components/button/_button.scss b/packages/core/src/components/button/_button.scss index 00feee80b8..7633946f44 100644 --- a/packages/core/src/components/button/_button.scss +++ b/packages/core/src/components/button/_button.scss @@ -1,13 +1,9 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "../../common/color-aliases" as *; -@use "../../common/variables" as *; -@use "../../common/variables-extended" as *; -@use "./common" as *; -@use "../icon/icon-mixins" as *; -@use "../progress-bar/common" as *; +@import "../../common/variables"; +@import "../../common/variables-extended"; +@import "./common"; /* Button diff --git a/packages/core/src/components/button/_common.scss b/packages/core/src/components/button/_common.scss index aaf69ec35c..669625fe3e 100644 --- a/packages/core/src/components/button/_common.scss +++ b/packages/core/src/components/button/_common.scss @@ -1,13 +1,10 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "../../common/color-aliases" as *; -@use "../../common/flex" as *; -@use "../../common/mixins" as *; -@use "../../common/variables" as *; -@use "../../common/variables-extended" as *; -@use "../progress-bar/common" as *; +@import "../../common/mixins"; +@import "../../common/variables"; +@import "../../common/variables-extended"; +@import "../progress-bar/common"; $button-border-width: 1px !default; $button-padding: ($pt-grid-size * 0.5) $pt-grid-size !default; diff --git a/packages/core/src/components/callout/_callout.scss b/packages/core/src/components/callout/_callout.scss index d6b955f95c..d1c21bc50e 100644 --- a/packages/core/src/components/callout/_callout.scss +++ b/packages/core/src/components/callout/_callout.scss @@ -1,12 +1,7 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "../../common/color-aliases" as *; -@use "../../common/variables" as *; -@use "../../common/variables-extended" as *; -@use "../../common/mixins" as *; -@use "../icon/icon-mixins" as *; +@import "../../common/variables-extended"; /* Callout diff --git a/packages/core/src/components/card-list/card-list.scss b/packages/core/src/components/card-list/card-list.scss index 5bb232b502..eb6cf5dad8 100644 --- a/packages/core/src/components/card-list/card-list.scss +++ b/packages/core/src/components/card-list/card-list.scss @@ -1,10 +1,7 @@ // Copyright 2023 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "../../common/color-aliases" as *; -@use "../../common/variables" as *; -@use "../card/card-variables" as *; +@import "../card/card-variables"; .#{$ns}-card-list { overflow: auto; diff --git a/packages/core/src/components/card-list/cardList.tsx b/packages/core/src/components/card-list/cardList.tsx index 2f4ac71a97..6c0c1631af 100644 --- a/packages/core/src/components/card-list/cardList.tsx +++ b/packages/core/src/components/card-list/cardList.tsx @@ -45,7 +45,7 @@ export interface CardListProps extends Props, HTMLDivProps, React.RefAttributes< } export const CardList: React.FC = React.forwardRef((props, ref) => { - const { bordered, className, children, compact, ...htmlProps } = props; + const { bordered = true, className, children, compact = false, ...htmlProps } = props; const classes = classNames(className, Classes.CARD_LIST, { [Classes.CARD_LIST_BORDERED]: bordered, @@ -58,8 +58,4 @@ export const CardList: React.FC = React.forwardRef((props, ref) = ); }); -CardList.defaultProps = { - bordered: true, - compact: false, -}; CardList.displayName = `${DISPLAYNAME_PREFIX}.CardList`; diff --git a/packages/core/src/components/card/_card-variables.scss b/packages/core/src/components/card/_card-variables.scss index 5693188763..a4653e32d3 100644 --- a/packages/core/src/components/card/_card-variables.scss +++ b/packages/core/src/components/card/_card-variables.scss @@ -1,10 +1,7 @@ // Copyright 2023 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "../../common/color-aliases" as *; -@use "../../common/variables" as *; -@use "../../common/variables-extended" as *; +@import "../../common/variables-extended"; $card-padding: $pt-grid-size * 2 !default; $card-padding-compact: $pt-grid-size * 1.5 !default; diff --git a/packages/core/src/components/card/_card.scss b/packages/core/src/components/card/_card.scss index efd43de8da..2653b8962b 100644 --- a/packages/core/src/components/card/_card.scss +++ b/packages/core/src/components/card/_card.scss @@ -1,10 +1,7 @@ // Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "../../common/variables" as *; -@use "../../common/variables-extended" as *; -@use "./card-variables" as *; +@import "./card-variables"; /* Cards diff --git a/packages/core/src/components/card/card.tsx b/packages/core/src/components/card/card.tsx index 632d8eaa29..7872922a95 100644 --- a/packages/core/src/components/card/card.tsx +++ b/packages/core/src/components/card/card.tsx @@ -68,7 +68,7 @@ export interface CardProps extends Props, HTMLDivProps, React.RefAttributes = React.forwardRef((props, ref) => { - const { className, elevation, interactive, selected, compact, ...htmlProps } = props; + const { className, elevation = Elevation.ZERO, interactive = false, selected, compact, ...htmlProps } = props; const classes = classNames(className, Classes.CARD, Classes.elevationClass(elevation!), { [Classes.INTERACTIVE]: interactive, [Classes.COMPACT]: compact, @@ -76,8 +76,4 @@ export const Card: React.FC = React.forwardRef((props, ref) => { }); return
; }); -Card.defaultProps = { - elevation: Elevation.ZERO, - interactive: false, -}; Card.displayName = `${DISPLAYNAME_PREFIX}.Card`; diff --git a/packages/core/src/components/collapse/_collapse.scss b/packages/core/src/components/collapse/_collapse.scss index 9e7c1eda57..39726d7a3f 100644 --- a/packages/core/src/components/collapse/_collapse.scss +++ b/packages/core/src/components/collapse/_collapse.scss @@ -1,7 +1,7 @@ // Copyright 2016 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/variables" as *; +@import "../../common/variables"; $collapse-transition: ($pt-transition-duration * 2) $pt-transition-ease !default; diff --git a/packages/core/src/components/context-menu/_context-menu.scss b/packages/core/src/components/context-menu/_context-menu.scss index 7721e83040..265c4fca3a 100644 --- a/packages/core/src/components/context-menu/_context-menu.scss +++ b/packages/core/src/components/context-menu/_context-menu.scss @@ -1,7 +1,7 @@ // Copyright 2021 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/variables" as *; +@import "../../common/variables"; .#{$ns}-context-menu-virtual-target { position: fixed; diff --git a/packages/core/src/components/context-menu/contextMenu.tsx b/packages/core/src/components/context-menu/contextMenu.tsx index d9d364a2ff..354fe92e29 100644 --- a/packages/core/src/components/context-menu/contextMenu.tsx +++ b/packages/core/src/components/context-menu/contextMenu.tsx @@ -241,7 +241,7 @@ export const ContextMenu: React.FC = React.forwardRef {maybePopover} - {React.createElement>( + {React.createElement & React.ClassAttributes>( tagName, { className: containerClassName, diff --git a/packages/core/src/components/context-menu/contextMenuSingleton.tsx b/packages/core/src/components/context-menu/contextMenuSingleton.tsx index fa250a2503..620473acfd 100644 --- a/packages/core/src/components/context-menu/contextMenuSingleton.tsx +++ b/packages/core/src/components/context-menu/contextMenuSingleton.tsx @@ -50,7 +50,11 @@ export function showContextMenu( ) { const { container = document.body, + // TODO(React 18): Replace deprecated ReactDOM methods. See: https://github.com/palantir/blueprint/issues/7165 + // eslint-disable-next-line deprecation/deprecation domRenderer = ReactDOM.render, + // TODO(React 18): Replace deprecated ReactDOM methods. See: https://github.com/palantir/blueprint/issues/7165 + // eslint-disable-next-line deprecation/deprecation domUnmounter = ReactDOM.unmountComponentAtNode, } = options; @@ -65,6 +69,8 @@ export function showContextMenu( domUnmounter(contextMenuElement); } + // TODO(React 18): Replace deprecated ReactDOM methods. See: https://github.com/palantir/blueprint/issues/7165 + // eslint-disable-next-line deprecation/deprecation domRenderer( @@ -81,6 +87,8 @@ export function showContextMenu( * @see https://blueprintjs.com/docs/#core/components/context-menu-popover.imperative-api */ export function hideContextMenu(options: DOMMountOptions = {}) { + // TODO(React 18): Replace deprecated ReactDOM methods. See: https://github.com/palantir/blueprint/issues/7165 + // eslint-disable-next-line deprecation/deprecation const { domUnmounter = ReactDOM.unmountComponentAtNode } = options; if (contextMenuElement !== undefined) { diff --git a/packages/core/src/components/control-card/_control-card.scss b/packages/core/src/components/control-card/_control-card.scss index fad2094b5e..2b74c42bdd 100644 --- a/packages/core/src/components/control-card/_control-card.scss +++ b/packages/core/src/components/control-card/_control-card.scss @@ -1,8 +1,7 @@ // Copyright 2023 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/variables" as *; -@use "../card/card-variables" as *; +@import "../card/card-variables"; // use an extra selector to increase specificity .#{$ns}-card.#{$ns}-control-card { diff --git a/packages/core/src/components/control-card/checkboxCard.tsx b/packages/core/src/components/control-card/checkboxCard.tsx index a08099300c..b3219e748f 100644 --- a/packages/core/src/components/control-card/checkboxCard.tsx +++ b/packages/core/src/components/control-card/checkboxCard.tsx @@ -17,7 +17,7 @@ import classNames from "classnames"; import * as React from "react"; -import { Classes } from "../../common"; +import { Alignment, Classes } from "../../common"; import { DISPLAYNAME_PREFIX } from "../../common/props"; import { ControlCard, type ControlCardProps } from "./controlCard"; @@ -30,10 +30,15 @@ export type CheckboxCardProps = Omit; * @see https://blueprintjs.com/docs/#core/components/control-card.checkbox-card */ export const CheckboxCard: React.FC = React.forwardRef((props, ref) => { - const className = classNames(props.className, Classes.CHECKBOX_CONTROL_CARD); - return ; + const { alignIndicator = Alignment.LEFT, className, ...rest } = props; + return ( + + ); }); -CheckboxCard.defaultProps = { - alignIndicator: "left", -}; CheckboxCard.displayName = `${DISPLAYNAME_PREFIX}.CheckboxCard`; diff --git a/packages/core/src/components/control-card/controlCard.tsx b/packages/core/src/components/control-card/controlCard.tsx index 6d51e0b7b3..a2f19d3025 100644 --- a/packages/core/src/components/control-card/controlCard.tsx +++ b/packages/core/src/components/control-card/controlCard.tsx @@ -17,7 +17,7 @@ import classNames from "classnames"; import * as React from "react"; -import { Classes } from "../../common"; +import { Alignment, Classes } from "../../common"; import { DISPLAYNAME_PREFIX, type HTMLInputProps } from "../../common/props"; import { Card, type CardProps } from "../card/card"; import type { CheckedControlProps, ControlProps } from "../forms/controlProps"; @@ -71,7 +71,7 @@ export interface ControlCardProps extends SupportedCardProps, SupportedControlPr */ export const ControlCard: React.FC = React.forwardRef((props, ref) => { const { - alignIndicator, + alignIndicator = Alignment.RIGHT, checked: _checked, children, className, @@ -82,7 +82,7 @@ export const ControlCard: React.FC = React.forwardRef((props, inputRef, label, onChange: _onChange, - showAsSelectedWhenChecked, + showAsSelectedWhenChecked = true, value, ...cardProps } = props; @@ -120,8 +120,4 @@ export const ControlCard: React.FC = React.forwardRef((props, ); }); -ControlCard.defaultProps = { - alignIndicator: "right", - showAsSelectedWhenChecked: true, -}; ControlCard.displayName = `${DISPLAYNAME_PREFIX}.ControlCard`; diff --git a/packages/core/src/components/dialog/_dialog-body.scss b/packages/core/src/components/dialog/_dialog-body.scss index 1cce21a45d..8fff971000 100644 --- a/packages/core/src/components/dialog/_dialog-body.scss +++ b/packages/core/src/components/dialog/_dialog-body.scss @@ -1,9 +1,6 @@ // Copyright 2023 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/variables" as *; -@use "dialog" as *; - .#{$ns}-dialog-body { flex: 1 1 auto; // We'd like to use padding instead of margin here to be consistent with the -dialog-body-scroll-container class, diff --git a/packages/core/src/components/dialog/_dialog-footer.scss b/packages/core/src/components/dialog/_dialog-footer.scss index e0787cbcbc..add233f15d 100644 --- a/packages/core/src/components/dialog/_dialog-footer.scss +++ b/packages/core/src/components/dialog/_dialog-footer.scss @@ -1,11 +1,6 @@ // Copyright 2023 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "../../common/color-aliases" as *; -@use "../../common/variables" as *; -@use "dialog" as *; - .#{$ns}-dialog-footer { flex: 0 0 auto; // We'd like to use padding instead of margin here to be consistent with the -dialog-footer-fixed class, diff --git a/packages/core/src/components/dialog/_dialog.scss b/packages/core/src/components/dialog/_dialog.scss index e97247d4a5..88431ef8c7 100644 --- a/packages/core/src/components/dialog/_dialog.scss +++ b/packages/core/src/components/dialog/_dialog.scss @@ -2,12 +2,10 @@ // Licensed under the Apache License, Version 2.0. @use "sass:math"; -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "@blueprintjs/icons/lib/scss/variables" as *; -@use "../../common/color-aliases" as *; -@use "../../common/mixins" as *; -@use "../../common/react-transition" as *; -@use "../../common/variables" as *; +@import "@blueprintjs/icons/lib/scss/variables"; +@import "../../common/mixins"; +@import "../../common/react-transition"; +@import "../../common/variables"; /* Dialog diff --git a/packages/core/src/components/dialog/_multistep-dialog.scss b/packages/core/src/components/dialog/_multistep-dialog.scss index 3af08c086b..bf092a7135 100644 --- a/packages/core/src/components/dialog/_multistep-dialog.scss +++ b/packages/core/src/components/dialog/_multistep-dialog.scss @@ -1,14 +1,12 @@ // Copyright 2020 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "@blueprintjs/icons/lib/scss/variables" as *; -@use "../../common/color-aliases" as *; -@use "../../common/mixins" as *; -@use "../../common/react-transition" as *; -@use "../../common/variables" as *; -@use "dialog" as *; +@import "@blueprintjs/icons/lib/scss/variables"; +@import "../../common/mixins"; +@import "../../common/react-transition"; +@import "../../common/variables"; +$dialog-border-radius: $pt-border-radius * 2 !default; $step-radius: $pt-border-radius * 2 !default; .#{$ns}-multistep-dialog-panels { diff --git a/packages/core/src/components/dialog/dialog.md b/packages/core/src/components/dialog/dialog.md index 5387241cd2..767e26c30c 100644 --- a/packages/core/src/components/dialog/dialog.md +++ b/packages/core/src/components/dialog/dialog.md @@ -16,7 +16,7 @@ We use the term "dialog" in Blueprint to avoid confusion with the adjective. Blueprint provides two types of dialogs: 1. Standard dialog: show single view using the `` component -1. Multi-step dialog: show multiple sequential views using the `` component. +2. Multi-step dialog: show multiple sequential views using the `` component. @## Dialog diff --git a/packages/core/src/components/dialog/dialog.tsx b/packages/core/src/components/dialog/dialog.tsx index 7d5212806c..d401a1cfdf 100644 --- a/packages/core/src/components/dialog/dialog.tsx +++ b/packages/core/src/components/dialog/dialog.tsx @@ -33,7 +33,7 @@ import { Button } from "../button/buttons"; import { H6 } from "../html/html"; import { Icon } from "../icon/icon"; import type { BackdropProps, OverlayableProps } from "../overlay/overlayProps"; -import { Overlay2 } from "../overlay2/overlay2"; +import { Overlay2, OVERLAY2_DEFAULT_PROPS } from "../overlay2/overlay2"; export interface DialogProps extends OverlayableProps, BackdropProps, Props { /** Dialog contents. */ @@ -146,7 +146,7 @@ export class Dialog extends AbstractPureComponent {
{ - public static defaultProps: DialogBodyProps = { - useOverflowScrollContainer: true, - }; +export const DialogBody: React.FC = props => { + const { children, className, useOverflowScrollContainer, ...htmlProps } = props; + return ( +
+ {children} +
+ ); +}; - public render() { - return ( -
- {this.props.children} -
- ); - } -} +DialogBody.displayName = `${DISPLAYNAME_PREFIX}.DialogBody`; diff --git a/packages/core/src/components/dialog/dialogFooter.tsx b/packages/core/src/components/dialog/dialogFooter.tsx index f68ac34374..488d96ee9a 100644 --- a/packages/core/src/components/dialog/dialogFooter.tsx +++ b/packages/core/src/components/dialog/dialogFooter.tsx @@ -17,16 +17,16 @@ import classNames from "classnames"; import * as React from "react"; -import { AbstractPureComponent, Classes } from "../../common"; -import type { Props } from "../../common/props"; - -export interface DialogFooterProps extends Props { - /** Child contents are rendered on the left side of the footer. */ - children?: React.ReactNode; +import { Classes, DISPLAYNAME_PREFIX } from "../../common"; +import type { HTMLDivProps, Props } from "../../common/props"; +export interface DialogFooterProps extends Props, HTMLDivProps { /** Dialog actions (typically buttons) are rendered on the right side of the footer. */ actions?: React.ReactNode; + /** Child contents are rendered on the left side of the footer. */ + children?: React.ReactNode; + /** * Use a "minimal" appearance for the footer, simply applying an HTML role and * some visual padding. This is useful for small dialogs, and should not be used @@ -52,35 +52,19 @@ export interface DialogFooterProps extends Props { * * @see https://blueprintjs.com/docs/#core/components/dialog.dialog-footer-props */ -export class DialogFooter extends AbstractPureComponent { - public static defaultProps: DialogFooterProps = { - minimal: false, - }; - - public render() { - return ( -
- {this.renderMainSection()} - {this.maybeRenderActionsSection()} -
- ); - } +export const DialogFooter: React.FC = props => { + const { actions, children, className, minimal = false, ...htmlProps } = props; + return ( +
+
{children}
+ {actions != null &&
{actions}
} +
+ ); +}; - /** Render the main footer section (left aligned). */ - private renderMainSection() { - return
{this.props.children}
; - } - - /** Optionally render the footer actions (right aligned). */ - private maybeRenderActionsSection() { - const { actions } = this.props; - if (actions == null) { - return undefined; - } - return
{actions}
; - } -} +DialogFooter.displayName = `${DISPLAYNAME_PREFIX}.DialogFooter`; diff --git a/packages/core/src/components/dialog/dialogStep.tsx b/packages/core/src/components/dialog/dialogStep.tsx index e5987144fe..91eb90d69e 100644 --- a/packages/core/src/components/dialog/dialogStep.tsx +++ b/packages/core/src/components/dialog/dialogStep.tsx @@ -17,7 +17,7 @@ import classNames from "classnames"; import * as React from "react"; -import { AbstractPureComponent, Classes } from "../../common"; +import { Classes } from "../../common"; import { DISPLAYNAME_PREFIX, type HTMLDivProps, type Props } from "../../common/props"; import type { DialogStepButtonProps } from "./dialogStepButton"; @@ -56,22 +56,21 @@ export interface DialogStepProps extends Props, Omit { - public static displayName = `${DISPLAYNAME_PREFIX}.DialogStep`; +export const DialogStep: React.FC = props => { + const { className, id, title, ...htmlProps } = props; - // this component is never rendered directly; see MultistepDialog#renderDialogStepPanel() - /* istanbul ignore next */ - public render() { - const { className } = this.props; - return ( -
-
-
- ); - } -} + // this component is never rendered directly; see MultistepDialog#renderDialogStep() + return ( +
+
+
+ ); +}; + +DialogStep.displayName = `${DISPLAYNAME_PREFIX}.DialogStep`; diff --git a/packages/core/src/components/divider/_divider.scss b/packages/core/src/components/divider/_divider.scss index 84e5f4f542..618fec9ba4 100644 --- a/packages/core/src/components/divider/_divider.scss +++ b/packages/core/src/components/divider/_divider.scss @@ -1,8 +1,7 @@ // Copyright 2018 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/color-aliases" as *; -@use "../../common/variables" as *; +@import "../../common/variables"; $divider-margin: $pt-grid-size * 0.5 !default; diff --git a/packages/core/src/components/drawer/_drawer.scss b/packages/core/src/components/drawer/_drawer.scss index 5f4ad48539..acc9a1cfd5 100644 --- a/packages/core/src/components/drawer/_drawer.scss +++ b/packages/core/src/components/drawer/_drawer.scss @@ -1,12 +1,10 @@ // Copyright 2018 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "@blueprintjs/colors/lib/scss/colors" as *; -@use "@blueprintjs/icons/lib/scss/variables" as *; -@use "../../common/color-aliases" as *; -@use "../../common/mixins" as *; -@use "../../common/react-transition" as *; -@use "../../common/variables" as *; +@import "@blueprintjs/icons/lib/scss/variables"; +@import "../../common/mixins"; +@import "../../common/react-transition"; +@import "../../common/variables"; $drawer-margin: ($pt-grid-size * 3) 0 !default; $drawer-padding: $pt-grid-size * 2 !default; diff --git a/packages/core/src/components/editable-text/_editable-text.scss b/packages/core/src/components/editable-text/_editable-text.scss index bf7de2b6f5..37d2e1dcf1 100644 --- a/packages/core/src/components/editable-text/_editable-text.scss +++ b/packages/core/src/components/editable-text/_editable-text.scss @@ -1,10 +1,8 @@ // Copyright 2016 Palantir Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. -@use "../../common/color-aliases" as *; -@use "../../common/mixins" as *; -@use "../../common/variables" as *; -@use "../forms/common" as *; +@import "../../common/variables"; +@import "../forms/common"; .#{$ns}-editable-text { cursor: text; diff --git a/packages/core/src/components/editable-text/editable-text.md b/packages/core/src/components/editable-text/editable-text.md index 1f593bd14f..6421790468 100644 --- a/packages/core/src/components/editable-text/editable-text.md +++ b/packages/core/src/components/editable-text/editable-text.md @@ -1,6 +1,6 @@ @# Editable text -__EditableText__ is an interactive component which appears as normal UI text. It transforms into an interactive +**EditableText** is an interactive component which appears as normal UI text. It transforms into an interactive text input field when a user hovers and/or focuses on it. The text input inherits all font styling from its ancestors, making for a seamless transition between reading and @@ -8,8 +8,8 @@ editing text. You might use this component for inline renaming, or for an [editable multiline description](#core/components/editable-text.multiline-mode). -You should not use __EditableText__ when a more static, always-editable -[__InputGroup__](#core/components/input-group) or [__TextArea__](#core/components/text-area) +You should not use **EditableText** when a more static, always-editable +[**InputGroup**](#core/components/input-group) or [**TextArea**](#core/components/text-area) component would suffice. @reactExample EditableTextExample @@ -23,10 +23,9 @@ you should center the component via flexbox or with `position` and `transform: t
- @## Multiline mode -By default, __EditableText__ supports _exactly one line of text_ and will grow or shrink horizontally based on the +By default, **EditableText** supports _exactly one line of text_ and will grow or shrink horizontally based on the length of text. You may enable the `multiline` prop to use a `