diff --git a/.changeset/bitter-pants-watch.md b/.changeset/bitter-pants-watch.md deleted file mode 100644 index 3accf45826..0000000000 --- a/.changeset/bitter-pants-watch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': minor ---- - -We are updating the default size of the Button component in Canon to be small instead of medium. diff --git a/.changeset/brave-facts-pay.md b/.changeset/brave-facts-pay.md deleted file mode 100644 index 1f8e9663bf..0000000000 --- a/.changeset/brave-facts-pay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch ---- - -Migrate actions to new format diff --git a/.changeset/chatty-clowns-dream.md b/.changeset/chatty-clowns-dream.md deleted file mode 100644 index d601f7a40d..0000000000 --- a/.changeset/chatty-clowns-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -table actions header support i18n diff --git a/.changeset/chubby-dots-kiss.md b/.changeset/chubby-dots-kiss.md new file mode 100644 index 0000000000..7a28467725 --- /dev/null +++ b/.changeset/chubby-dots-kiss.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Fixed an issue causing TechDocs to not properly handle initial redirect. diff --git a/.changeset/clear-bananas-end.md b/.changeset/clear-bananas-end.md new file mode 100644 index 0000000000..50e722544c --- /dev/null +++ b/.changeset/clear-bananas-end.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-graph': patch +--- + +Catalog graph plugin support i18n diff --git a/.changeset/cold-meals-like.md b/.changeset/cold-meals-like.md deleted file mode 100644 index 7feb978337..0000000000 --- a/.changeset/cold-meals-like.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-client': patch ---- - -Fixed `CatalogClient` error responses for `refreshEntity` and `addLocation`. diff --git a/.changeset/create-app-1748956288.md b/.changeset/create-app-1748956288.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1748956288.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/create-app-1749565617.md b/.changeset/create-app-1749565617.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1749565617.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/create-app-1749636320.md b/.changeset/create-app-1749636320.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1749636320.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/cuddly-camels-lose.md b/.changeset/cuddly-camels-lose.md deleted file mode 100644 index 23162bfdc5..0000000000 --- a/.changeset/cuddly-camels-lose.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': patch ---- - -Migrate to new action format diff --git a/.changeset/curly-zoos-thank.md b/.changeset/curly-zoos-thank.md new file mode 100644 index 0000000000..ec55b2abb9 --- /dev/null +++ b/.changeset/curly-zoos-thank.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +We are consolidating all css files into a single styles.css in Canon. diff --git a/.changeset/curvy-peaches-relate.md b/.changeset/curvy-peaches-relate.md deleted file mode 100644 index 9fafc77abb..0000000000 --- a/.changeset/curvy-peaches-relate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-azure': patch ---- - -Migrating `azure` actions to using the new `zod` schema format diff --git a/.changeset/curvy-words-create.md b/.changeset/curvy-words-create.md deleted file mode 100644 index b180705ebe..0000000000 --- a/.changeset/curvy-words-create.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': minor ---- - -Internal update to promote the modular CLI entrypoint to stable. diff --git a/.changeset/cyan-islands-swim.md b/.changeset/cyan-islands-swim.md new file mode 100644 index 0000000000..396cc6fc68 --- /dev/null +++ b/.changeset/cyan-islands-swim.md @@ -0,0 +1,14 @@ +--- +'@backstage/plugin-catalog-backend': major +'@backstage/create-app': patch +--- + +**BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed. + +The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly. +If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential +search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)). + +Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead. + +This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider. diff --git a/.changeset/dark-cougars-go.md b/.changeset/dark-cougars-go.md new file mode 100644 index 0000000000..f835dd2658 --- /dev/null +++ b/.changeset/dark-cougars-go.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +Add new SearchField component in Canon diff --git a/.changeset/deep-aliens-camp.md b/.changeset/deep-aliens-camp.md deleted file mode 100644 index ca5c3d8ed4..0000000000 --- a/.changeset/deep-aliens-camp.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-events-backend-module-kafka': minor ---- - -Adds a new module `kafka` for plugin-events-backend - -The module introduces the `KafkaConsumerClient` which creates a Kafka client used to establish consumer connections. It also provides the `KafkaConsumingEventPublisher`, a consumer that subscribes to configured Kafka topics and publishes received messages to the Event Service. diff --git a/.changeset/deep-moments-love.md b/.changeset/deep-moments-love.md deleted file mode 100644 index 89b3174275..0000000000 --- a/.changeset/deep-moments-love.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements. diff --git a/.changeset/dry-hornets-stop.md b/.changeset/dry-hornets-stop.md new file mode 100644 index 0000000000..4979d463a8 --- /dev/null +++ b/.changeset/dry-hornets-stop.md @@ -0,0 +1,6 @@ +--- +'@backstage/config-loader': patch +'@backstage/config': patch +--- + +Loosen the requirements for a key to be considered valid config. diff --git a/.changeset/dull-buttons-press.md b/.changeset/dull-buttons-press.md deleted file mode 100644 index 1c8f8fc13c..0000000000 --- a/.changeset/dull-buttons-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch ---- - -Migrate `bitbucket-cloud` to new actions format diff --git a/.changeset/dull-cars-shout.md b/.changeset/dull-cars-shout.md deleted file mode 100644 index be213a167c..0000000000 --- a/.changeset/dull-cars-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': patch ---- - -Migrate to using new actions diff --git a/.changeset/eight-pigs-post.md b/.changeset/eight-pigs-post.md deleted file mode 100644 index 8e50cc7707..0000000000 --- a/.changeset/eight-pigs-post.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': minor ---- - -We set the default size for IconButton in Canon to be small instead of medium. diff --git a/.changeset/eight-planets-see.md b/.changeset/eight-planets-see.md deleted file mode 100644 index 20adcac7ef..0000000000 --- a/.changeset/eight-planets-see.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -render details for composite property schemas diff --git a/.changeset/eighty-showers-hide.md b/.changeset/eighty-showers-hide.md deleted file mode 100644 index 0871fea4bb..0000000000 --- a/.changeset/eighty-showers-hide.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-scaffolder-node-test-utils': minor ---- - -**BREAKING CHANGES** - -Because of the removal of the `logStream` property to the `ActionsContext` this has been removed from the `createMockActionContext` method. - -You can remove this as it's no longer supported in the scaffolder actions. diff --git a/.changeset/eleven-foxes-mix.md b/.changeset/eleven-foxes-mix.md deleted file mode 100644 index 965be5435e..0000000000 --- a/.changeset/eleven-foxes-mix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': minor ---- - -Enhanced error handling in the auditor service factory to pass errors as objects. Aligned WinstonRootAuditorService with the default service factory's error handling. diff --git a/.changeset/empty-mugs-agree.md b/.changeset/empty-mugs-agree.md new file mode 100644 index 0000000000..80dd35b8cf --- /dev/null +++ b/.changeset/empty-mugs-agree.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Filter MultiEntityPicker options based on rendered option value diff --git a/.changeset/empty-poets-give.md b/.changeset/empty-poets-give.md new file mode 100644 index 0000000000..2eb63c2ed5 --- /dev/null +++ b/.changeset/empty-poets-give.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +Add new `RadioGroup` + `Radio` component to Canon diff --git a/.changeset/evil-cooks-watch.md b/.changeset/evil-cooks-watch.md deleted file mode 100644 index 0982f24634..0000000000 --- a/.changeset/evil-cooks-watch.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@backstage/plugin-catalog-unprocessed-entities': patch -'@backstage/plugin-app-visualizer': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-catalog-graph': patch -'@backstage/plugin-notifications': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-devtools': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-catalog': patch -'@backstage/plugin-signals': patch -'@backstage/plugin-search': patch -'@backstage/plugin-home': patch -'@backstage/plugin-app': patch -'@backstage/plugin-org': patch ---- - -Added the `info.packageJson` option to the plugin instance for the new frontend system. diff --git a/.changeset/fair-doors-bathe.md b/.changeset/fair-doors-bathe.md deleted file mode 100644 index bbb5f238ee..0000000000 --- a/.changeset/fair-doors-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Fixed a bug where linting would fail with the generated clients when defining top-level `enum` schema values. diff --git a/.changeset/famous-streets-stay.md b/.changeset/famous-streets-stay.md deleted file mode 100644 index d517b889c5..0000000000 --- a/.changeset/famous-streets-stay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-node': patch ---- - -Use `LoggerService` instead of `Logger`. This is a non-breaking change, as the `LoggerService` is a subset of the `Logger` interface. diff --git a/.changeset/fancy-nails-call.md b/.changeset/fancy-nails-call.md new file mode 100644 index 0000000000..556b358dfa --- /dev/null +++ b/.changeset/fancy-nails-call.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch +--- + +Fixed bug in `IncrementalIngestionEngine` by adding `burstLength` check when a burst completes diff --git a/.changeset/few-streets-accept.md b/.changeset/few-streets-accept.md deleted file mode 100644 index 4b82cc03e4..0000000000 --- a/.changeset/few-streets-accept.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch ---- - -Migrate the actions to the new format diff --git a/.changeset/fix-cli-config-docs-feedback.md b/.changeset/fix-cli-config-docs-feedback.md deleted file mode 100644 index 1e7298bafa..0000000000 --- a/.changeset/fix-cli-config-docs-feedback.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added user feedback when opening config docs in browser. The command now clearly indicates what it's doing and provides fallback instructions if the browser fails to open. diff --git a/.changeset/fluffy-bobcats-tell.md b/.changeset/fluffy-bobcats-tell.md deleted file mode 100644 index 41ed20a7ae..0000000000 --- a/.changeset/fluffy-bobcats-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/eslint-plugin': patch ---- - -Fix custom rules package scanning performance. diff --git a/.changeset/forty-seas-worry.md b/.changeset/forty-seas-worry.md deleted file mode 100644 index a88c15df53..0000000000 --- a/.changeset/forty-seas-worry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Fix styling for the title4 prop on the Heading component in Canon. diff --git a/.changeset/fresh-brooms-follow.md b/.changeset/fresh-brooms-follow.md deleted file mode 100644 index f2858779bf..0000000000 --- a/.changeset/fresh-brooms-follow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The `BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE` flag has been removed. Existing users are encouraged to switch to `EXPERIMENTAL_RSPACK` instead. diff --git a/.changeset/fresh-otters-say.md b/.changeset/fresh-otters-say.md deleted file mode 100644 index ed91c9fb8d..0000000000 --- a/.changeset/fresh-otters-say.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Migrating to latest action format diff --git a/.changeset/gentle-llamas-press.md b/.changeset/gentle-llamas-press.md new file mode 100644 index 0000000000..9c922d396f --- /dev/null +++ b/.changeset/gentle-llamas-press.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-defaults': patch +'@backstage/backend-test-utils': minor +--- + +Add a standard `toString` on credentials objects diff --git a/.changeset/good-paths-act.md b/.changeset/good-paths-act.md deleted file mode 100644 index dc33b43766..0000000000 --- a/.changeset/good-paths-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Fix an issue where errors were not printed to console when running `backstage-repo-tools schema openapi generate` without the `--watch` flag. diff --git a/.changeset/green-schools-live.md b/.changeset/green-schools-live.md deleted file mode 100644 index 9863021a28..0000000000 --- a/.changeset/green-schools-live.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-yeoman': patch ---- - -Migrate to new actions format diff --git a/.changeset/grumpy-dryers-act.md b/.changeset/grumpy-dryers-act.md deleted file mode 100644 index caaeac5fa8..0000000000 --- a/.changeset/grumpy-dryers-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': patch ---- - -Add missing highlight language for the `package-docs` command. diff --git a/.changeset/honest-moles-bet.md b/.changeset/honest-moles-bet.md deleted file mode 100644 index 22e0cb4533..0000000000 --- a/.changeset/honest-moles-bet.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch -'@backstage/plugin-scaffolder-node': patch ---- - -Update pull request creation filter to include .gitignore files in the created pull request diff --git a/.changeset/itchy-mirrors-juggle.md b/.changeset/itchy-mirrors-juggle.md deleted file mode 100644 index 6fd7c7543a..0000000000 --- a/.changeset/itchy-mirrors-juggle.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-notifications': patch -'@backstage/plugin-scaffolder': patch ---- - -Remove React import form notification and scaffolder plugin diff --git a/.changeset/khaki-horses-chew.md b/.changeset/khaki-horses-chew.md deleted file mode 100644 index b9f5dfda5e..0000000000 --- a/.changeset/khaki-horses-chew.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-techdocs': patch ---- - -Improved Keyboard accessibility in techdocs. diff --git a/.changeset/khaki-swans-invite.md b/.changeset/khaki-swans-invite.md deleted file mode 100644 index 4e768a1978..0000000000 --- a/.changeset/khaki-swans-invite.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-notifications-backend-module-email': patch -'@backstage/plugin-notifications-backend': patch ---- - -Internal changes to switch to the non-alpha `catalogServiceRef` diff --git a/.changeset/kind-houses-feel.md b/.changeset/kind-houses-feel.md deleted file mode 100644 index a4b3ac0d14..0000000000 --- a/.changeset/kind-houses-feel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Added a render prop to the Button component in Canon to use it as a link. diff --git a/.changeset/large-baboons-prove.md b/.changeset/large-baboons-prove.md deleted file mode 100644 index 072d57de4c..0000000000 --- a/.changeset/large-baboons-prove.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-catalog': minor ---- - -Add support to customize the about card icon links via `EntityIconLinkBlueprint` and provide a default catalog view catalog source, launch scaffolder template and read techdocs docs icon links extensions. - -**BREAKING ALPHA** - -The `Scaffolder` launch template and `TechDocs` read documentation icons have been extracted from the default `Catalog` about card links and are now provided respectively by the `Scaffolder` and `TechDocs` plugins in the new frontend system. It means that they will not be available unless you install the `TechDocs` and `Scaffolder` plugins. Also If you are using translation for these icon link titles other than the default, you should now translate them using the scaffolder translation reference or the TechDocs translation reference (the translation keys are still the same, `aboutCard.viewTechdocs` and `aboutCard.launchTemplate`). diff --git a/.changeset/late-buttons-strive.md b/.changeset/late-buttons-strive.md deleted file mode 100644 index 23e1045ba0..0000000000 --- a/.changeset/late-buttons-strive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Org plugin support i18n diff --git a/.changeset/lazy-rice-dream.md b/.changeset/lazy-rice-dream.md deleted file mode 100644 index fe91f85b2e..0000000000 --- a/.changeset/lazy-rice-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gerrit': patch ---- - -Migrating to use new format for actions diff --git a/.changeset/long-suits-obey.md b/.changeset/long-suits-obey.md deleted file mode 100644 index 996bba6026..0000000000 --- a/.changeset/long-suits-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-user-settings': patch ---- - -Add some translation to user-setting plugin diff --git a/.changeset/loose-ants-learn.md b/.changeset/loose-ants-learn.md deleted file mode 100644 index 29f357966c..0000000000 --- a/.changeset/loose-ants-learn.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor ---- - -**New Frontend System Only:** -The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. diff --git a/.changeset/major-heads-scream.md b/.changeset/major-heads-scream.md deleted file mode 100644 index 24caa6e4bb..0000000000 --- a/.changeset/major-heads-scream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': minor ---- - -**BREAKING CHANGE**: User and Group discovery will default to ingesting all users in sub groups that belong to the specified root group in config. Disable by setting `restrictUsersToGroup: true` in app-config under your module settings. diff --git a/.changeset/mean-lemons-dream.md b/.changeset/mean-lemons-dream.md new file mode 100644 index 0000000000..fdf7f29017 --- /dev/null +++ b/.changeset/mean-lemons-dream.md @@ -0,0 +1,5 @@ +--- +'@backstage/repo-tools': minor +--- + +Clear output directory before running `package-docs` and skip all internal packages. diff --git a/.changeset/mean-tigers-rush.md b/.changeset/mean-tigers-rush.md deleted file mode 100644 index e15b01cedc..0000000000 --- a/.changeset/mean-tigers-rush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Switched to using the `ModuleFederationPlugin` from `@module-federation/enhanced/rspack` for Rspack, rather than the built-in one. diff --git a/.changeset/mighty-windows-boil.md b/.changeset/mighty-windows-boil.md deleted file mode 100644 index 52eb024db1..0000000000 --- a/.changeset/mighty-windows-boil.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-sentry': patch ---- - -Migrate to new actions format diff --git a/.changeset/mira-flygande-spoons.md b/.changeset/mira-flygande-spoons.md deleted file mode 100644 index c4c50f117a..0000000000 --- a/.changeset/mira-flygande-spoons.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -You can now specify an optional value when applying the `HAS_LABEL` permission rule, similar to the `HAS_ANNOTATION` permission rule. diff --git a/.changeset/new-beers-sell.md b/.changeset/new-beers-sell.md deleted file mode 100644 index fd7407007d..0000000000 --- a/.changeset/new-beers-sell.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-notifications': patch -'@backstage/plugin-notifications-backend': patch -'@backstage/plugin-notifications-common': patch -'@backstage/plugin-notifications': patch ---- - -Adds ability for user to turn on/off notifications for specific topics within an origin. diff --git a/.changeset/odd-clubs-teach.md b/.changeset/odd-clubs-teach.md new file mode 100644 index 0000000000..79b91ad2fb --- /dev/null +++ b/.changeset/odd-clubs-teach.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-dynamic-feature-service': patch +--- + +Fix wrong imports which lead to module initialization failures when enabling dynamic plugins. diff --git a/.changeset/olive-buses-serve.md b/.changeset/olive-buses-serve.md deleted file mode 100644 index d4e1798360..0000000000 --- a/.changeset/olive-buses-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-techdocs': patch ---- - -Exports the default document collator for use in document transformation during search indexing. diff --git a/.changeset/open-bottles-attack.md b/.changeset/open-bottles-attack.md deleted file mode 100644 index e57607b55c..0000000000 --- a/.changeset/open-bottles-attack.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-notifications': patch ---- - -Removed `octokit` dependency as it was not being used diff --git a/.changeset/open-eyes-learn.md b/.changeset/open-eyes-learn.md deleted file mode 100644 index 3a0299aafb..0000000000 --- a/.changeset/open-eyes-learn.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -'@backstage/plugin-catalog-react': minor ---- - -Introduces a new `EntityIconLinkBlueprint` that customizes the `About` card icon links on the `Catalog` entity page. - -The blueprint currently accepts a `useProps` hook as `param` and this function returns the following props that will be passed to the icon link component: - -| Name | Description | Type | Default Value | -| ---------- | --------------------------------------------------- | ------------- | ------------- | -| `icon` | The icon to display. | `JSX.Element` | N/A | -| `label` | The label for the element. | `string` | N/A | -| `title` | The title for the element. | `string` | N/A | -| `disabled` | Whether the element is disabled. | `boolean` | `false` | -| `href` | The URL to navigate to when the element is clicked. | `string` | N/A | -| `onClick` | A function to call when the element is clicked. | `() => void` | N/A | - -Here is an usage example: - -```tsx -import { EntityIconLinkBlueprint } from '@backstage/plugin-catalog-react/alpha'; -//... - -EntityIconLinkBlueprint.make({ - name: 'my-icon-link', - params: { - useProps() { - const { t } = useTranslationRef(myIconLinkTranslationRef); - return { - label: t('myIconLink.label'), - icon: , - href: '/my-plugin', - }; - }, - }, -}); -``` - -Additionally, the `app-config.yaml` file allows you to override some of the default icon link parameters, including `label` and `title` values. Here's how to set them: - -```yaml -app: - extensions: - - entity-icon-link:my-plugin/my-icon-link: - config: - label: 'My Custom Icon Link label' -``` - -Finally, you can disable all links if you want to hide the About card header completely (useful, for example, when links are displayed on separate cards). The header is hidden when no icon links extensions are enabled. diff --git a/.changeset/orange-masks-decide.md b/.changeset/orange-masks-decide.md deleted file mode 100644 index 0ddb7a7e48..0000000000 --- a/.changeset/orange-masks-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-rails': patch ---- - -Migrate to new actions format diff --git a/.changeset/petite-candies-tan.md b/.changeset/petite-candies-tan.md deleted file mode 100644 index 6ec5c9c813..0000000000 --- a/.changeset/petite-candies-tan.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -Added a new optional `info` option to `createFrontendPlugin` that lets you provide a loaders for different sources of metadata information about the plugin. - -There are two available loaders. The first one is `info.packageJson`, which can be used to point to a `package.json` file for the plugin. This is recommended for any plugin that is defined within its own package, especially all plugins that are published to a package registry. Typical usage looks like this: - -```ts -export default createFrontendPlugin({ - pluginId: '...', - info: { - packageJson: () => import('../package.json'), - }, -}); -``` - -The second loader is `info.manifest`, which can be used to point to an opaque plugin manifest. This **MUST ONLY** be used by plugins that are intended for use within a single organization. Plugins that are published to an open package registry should **NOT** use this loader. The loader is useful for adding additional internal metadata associated with the plugin, and it is up to the Backstage app to decide how these manifests are parsed and used. The default manifest parser in an app created with `createApp` from `@backstage/frontend-defaults` is able to parse the default `catalog-info.yaml` format and built-in fields such as `spec.owner`. - -Typical usage looks like this: - -```ts -export default createFrontendPlugin({ - pluginId: '...', - info: { - manifest: () => import('../catalog-info.yaml'), - }, -}); -``` diff --git a/.changeset/petite-paths-remain.md b/.changeset/petite-paths-remain.md new file mode 100644 index 0000000000..a2bef50c80 --- /dev/null +++ b/.changeset/petite-paths-remain.md @@ -0,0 +1,7 @@ +--- +'@backstage/plugin-scaffolder-node-test-utils': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-scaffolder-node': patch +--- + +An internal refactor which adds additional types to experimental checkpoints diff --git a/.changeset/pre.json b/.changeset/pre.json index ca3ec8d340..c491678398 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -2,298 +2,232 @@ "mode": "pre", "tag": "next", "initialVersions": { - "example-app": "0.2.109", - "@backstage/app-defaults": "1.6.2", - "example-app-next": "0.0.23", - "app-next-example-plugin": "0.0.23", - "example-backend": "0.0.38", - "@backstage/backend-app-api": "1.2.3", - "@backstage/backend-defaults": "0.10.0", + "example-app": "0.2.110", + "@backstage/app-defaults": "1.6.3", + "example-app-next": "0.0.24", + "app-next-example-plugin": "0.0.24", + "example-backend": "0.0.39", + "@backstage/backend-app-api": "1.2.4", + "@backstage/backend-defaults": "0.11.0", "@backstage/backend-dev-utils": "0.1.5", - "@backstage/backend-dynamic-feature-service": "0.7.0", - "@backstage/backend-openapi-utils": "0.5.3", - "@backstage/backend-plugin-api": "1.3.1", - "@backstage/backend-test-utils": "1.5.0", - "@backstage/canon": "0.4.0", - "@backstage/catalog-client": "1.10.0", + "@backstage/backend-dynamic-feature-service": "0.7.1", + "@backstage/backend-openapi-utils": "0.5.4", + "@backstage/backend-plugin-api": "1.4.0", + "@backstage/backend-test-utils": "1.6.0", + "@backstage/canon": "0.5.0", + "@backstage/catalog-client": "1.10.1", "@backstage/catalog-model": "1.7.4", - "@backstage/cli": "0.32.1", + "@backstage/cli": "0.33.0", "@backstage/cli-common": "0.1.15", "@backstage/cli-node": "0.2.13", "@backstage/codemods": "0.1.52", "@backstage/config": "1.3.2", "@backstage/config-loader": "1.10.1", - "@backstage/core-app-api": "1.17.0", - "@backstage/core-compat-api": "0.4.2", - "@backstage/core-components": "0.17.2", - "@backstage/core-plugin-api": "1.10.7", - "@backstage/create-app": "0.6.2", - "@backstage/dev-utils": "1.1.10", - "e2e-test": "0.2.28", + "@backstage/core-app-api": "1.17.1", + "@backstage/core-compat-api": "0.4.3", + "@backstage/core-components": "0.17.3", + "@backstage/core-plugin-api": "1.10.8", + "@backstage/create-app": "0.7.0", + "@backstage/dev-utils": "1.1.11", + "e2e-test": "0.2.29", "@backstage/e2e-test-utils": "0.1.1", "@backstage/errors": "1.2.7", - "@backstage/eslint-plugin": "0.1.10", - "@backstage/frontend-app-api": "0.11.2", - "@backstage/frontend-defaults": "0.2.2", - "@backstage/frontend-dynamic-feature-loader": "0.1.1", - "@internal/frontend": "0.0.9", - "@backstage/frontend-plugin-api": "0.10.2", - "@backstage/frontend-test-utils": "0.3.2", + "@backstage/eslint-plugin": "0.1.11", + "@backstage/frontend-app-api": "0.11.3", + "@backstage/frontend-defaults": "0.2.3", + "@backstage/frontend-dynamic-feature-loader": "0.1.2", + "@internal/frontend": "0.0.10", + "@backstage/frontend-plugin-api": "0.10.3", + "@backstage/frontend-test-utils": "0.3.3", "@backstage/integration": "1.17.0", "@backstage/integration-aws-node": "0.1.16", - "@backstage/integration-react": "1.2.7", + "@backstage/integration-react": "1.2.8", "@internal/opaque": "0.0.1", "@backstage/release-manifests": "0.0.13", - "@backstage/repo-tools": "0.13.3", - "@internal/scaffolder": "0.0.9", - "@techdocs/cli": "1.9.3", - "techdocs-cli-embedded-app": "0.2.108", - "@backstage/test-utils": "1.7.8", + "@backstage/repo-tools": "0.14.0", + "@internal/scaffolder": "0.0.10", + "@techdocs/cli": "1.9.4", + "techdocs-cli-embedded-app": "0.2.109", + "@backstage/test-utils": "1.7.9", "@backstage/theme": "0.6.6", "@backstage/types": "1.2.1", "@backstage/version-bridge": "1.0.11", - "yarn-plugin-backstage": "0.0.5", - "@backstage/plugin-api-docs": "0.12.7", + "yarn-plugin-backstage": "0.0.6", + "@backstage/plugin-api-docs": "0.12.8", "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.10", - "@backstage/plugin-app": "0.1.9", - "@backstage/plugin-app-backend": "0.5.2", - "@backstage/plugin-app-node": "0.1.33", - "@backstage/plugin-app-visualizer": "0.1.19", - "@backstage/plugin-auth-backend": "0.25.0", - "@backstage/plugin-auth-backend-module-atlassian-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-auth0-provider": "0.2.3", - "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.8", - "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.2.3", - "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-github-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-gitlab-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-google-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-guest-provider": "0.2.8", - "@backstage/plugin-auth-backend-module-microsoft-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-oauth2-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.8", - "@backstage/plugin-auth-backend-module-oidc-provider": "0.4.3", - "@backstage/plugin-auth-backend-module-okta-provider": "0.2.3", - "@backstage/plugin-auth-backend-module-onelogin-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-pinniped-provider": "0.3.3", - "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.5.3", - "@backstage/plugin-auth-node": "0.6.3", - "@backstage/plugin-auth-react": "0.1.15", + "@backstage/plugin-app": "0.1.10", + "@backstage/plugin-app-backend": "0.5.3", + "@backstage/plugin-app-node": "0.1.34", + "@backstage/plugin-app-visualizer": "0.1.20", + "@backstage/plugin-auth-backend": "0.25.1", + "@backstage/plugin-auth-backend-module-atlassian-provider": "0.4.4", + "@backstage/plugin-auth-backend-module-auth0-provider": "0.2.4", + "@backstage/plugin-auth-backend-module-aws-alb-provider": "0.4.4", + "@backstage/plugin-auth-backend-module-azure-easyauth-provider": "0.2.9", + "@backstage/plugin-auth-backend-module-bitbucket-provider": "0.3.4", + "@backstage/plugin-auth-backend-module-bitbucket-server-provider": "0.2.4", + "@backstage/plugin-auth-backend-module-cloudflare-access-provider": "0.4.4", + "@backstage/plugin-auth-backend-module-gcp-iap-provider": "0.4.4", + "@backstage/plugin-auth-backend-module-github-provider": "0.3.4", + "@backstage/plugin-auth-backend-module-gitlab-provider": "0.3.4", + "@backstage/plugin-auth-backend-module-google-provider": "0.3.4", + "@backstage/plugin-auth-backend-module-guest-provider": "0.2.9", + "@backstage/plugin-auth-backend-module-microsoft-provider": "0.3.4", + "@backstage/plugin-auth-backend-module-oauth2-provider": "0.4.4", + "@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "0.2.9", + "@backstage/plugin-auth-backend-module-oidc-provider": "0.4.4", + "@backstage/plugin-auth-backend-module-okta-provider": "0.2.4", + "@backstage/plugin-auth-backend-module-onelogin-provider": "0.3.4", + "@backstage/plugin-auth-backend-module-pinniped-provider": "0.3.4", + "@backstage/plugin-auth-backend-module-vmware-cloud-provider": "0.5.4", + "@backstage/plugin-auth-node": "0.6.4", + "@backstage/plugin-auth-react": "0.1.16", "@backstage/plugin-bitbucket-cloud-common": "0.3.0", - "@backstage/plugin-catalog": "1.30.0", - "@backstage/plugin-catalog-backend": "2.0.0", - "@backstage/plugin-catalog-backend-module-aws": "0.4.11", - "@backstage/plugin-catalog-backend-module-azure": "0.3.5", - "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.5.2", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.4.8", - "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.4.1", - "@backstage/plugin-catalog-backend-module-gcp": "0.3.8", - "@backstage/plugin-catalog-backend-module-gerrit": "0.3.2", - "@backstage/plugin-catalog-backend-module-gitea": "0.1.0", - "@backstage/plugin-catalog-backend-module-github": "0.9.0", - "@backstage/plugin-catalog-backend-module-github-org": "0.3.10", - "@backstage/plugin-catalog-backend-module-gitlab": "0.6.6", - "@backstage/plugin-catalog-backend-module-gitlab-org": "0.2.9", - "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.7.0", - "@backstage/plugin-catalog-backend-module-ldap": "0.11.5", - "@backstage/plugin-catalog-backend-module-logs": "0.1.10", - "@backstage/plugin-catalog-backend-module-msgraph": "0.7.0", - "@backstage/plugin-catalog-backend-module-openapi": "0.2.10", - "@backstage/plugin-catalog-backend-module-puppetdb": "0.2.10", - "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.8", - "@backstage/plugin-catalog-backend-module-unprocessed": "0.6.0", + "@backstage/plugin-catalog": "1.31.0", + "@backstage/plugin-catalog-backend": "2.1.0", + "@backstage/plugin-catalog-backend-module-aws": "0.4.12", + "@backstage/plugin-catalog-backend-module-azure": "0.3.6", + "@backstage/plugin-catalog-backend-module-backstage-openapi": "0.5.3", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.5.0", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.5.0", + "@backstage/plugin-catalog-backend-module-gcp": "0.3.9", + "@backstage/plugin-catalog-backend-module-gerrit": "0.3.3", + "@backstage/plugin-catalog-backend-module-gitea": "0.1.1", + "@backstage/plugin-catalog-backend-module-github": "0.10.0", + "@backstage/plugin-catalog-backend-module-github-org": "0.3.11", + "@backstage/plugin-catalog-backend-module-gitlab": "0.7.0", + "@backstage/plugin-catalog-backend-module-gitlab-org": "0.2.10", + "@backstage/plugin-catalog-backend-module-incremental-ingestion": "0.7.1", + "@backstage/plugin-catalog-backend-module-ldap": "0.11.6", + "@backstage/plugin-catalog-backend-module-logs": "0.1.11", + "@backstage/plugin-catalog-backend-module-msgraph": "0.7.1", + "@backstage/plugin-catalog-backend-module-openapi": "0.2.11", + "@backstage/plugin-catalog-backend-module-puppetdb": "0.2.11", + "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.9", + "@backstage/plugin-catalog-backend-module-unprocessed": "0.6.1", "@backstage/plugin-catalog-common": "1.1.4", - "@backstage/plugin-catalog-graph": "0.4.19", - "@backstage/plugin-catalog-import": "0.13.0", - "@backstage/plugin-catalog-node": "1.17.0", - "@backstage/plugin-catalog-react": "1.18.0", - "@backstage/plugin-catalog-unprocessed-entities": "0.2.17", + "@backstage/plugin-catalog-graph": "0.4.20", + "@backstage/plugin-catalog-import": "0.13.1", + "@backstage/plugin-catalog-node": "1.17.1", + "@backstage/plugin-catalog-react": "1.19.0", + "@backstage/plugin-catalog-unprocessed-entities": "0.2.18", "@backstage/plugin-catalog-unprocessed-entities-common": "0.0.8", - "@backstage/plugin-config-schema": "0.1.68", - "@backstage/plugin-devtools": "0.1.27", - "@backstage/plugin-devtools-backend": "0.5.5", + "@backstage/plugin-config-schema": "0.1.69", + "@backstage/plugin-devtools": "0.1.28", + "@backstage/plugin-devtools-backend": "0.5.6", "@backstage/plugin-devtools-common": "0.1.16", - "@backstage/plugin-events-backend": "0.5.2", - "@backstage/plugin-events-backend-module-aws-sqs": "0.4.11", - "@backstage/plugin-events-backend-module-azure": "0.2.20", - "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.20", - "@backstage/plugin-events-backend-module-bitbucket-server": "0.1.1", - "@backstage/plugin-events-backend-module-gerrit": "0.2.20", - "@backstage/plugin-events-backend-module-github": "0.4.0", - "@backstage/plugin-events-backend-module-gitlab": "0.3.1", - "@backstage/plugin-events-backend-module-google-pubsub": "0.1.0", - "@backstage/plugin-events-backend-test-utils": "0.1.44", - "@backstage/plugin-events-node": "0.4.11", - "@internal/plugin-todo-list": "1.0.39", - "@internal/plugin-todo-list-backend": "1.0.39", + "@backstage/plugin-events-backend": "0.5.3", + "@backstage/plugin-events-backend-module-aws-sqs": "0.4.12", + "@backstage/plugin-events-backend-module-azure": "0.2.21", + "@backstage/plugin-events-backend-module-bitbucket-cloud": "0.2.21", + "@backstage/plugin-events-backend-module-bitbucket-server": "0.1.2", + "@backstage/plugin-events-backend-module-gerrit": "0.2.21", + "@backstage/plugin-events-backend-module-github": "0.4.1", + "@backstage/plugin-events-backend-module-gitlab": "0.3.2", + "@backstage/plugin-events-backend-module-google-pubsub": "0.1.1", + "@backstage/plugin-events-backend-module-kafka": "0.1.0", + "@backstage/plugin-events-backend-test-utils": "0.1.45", + "@backstage/plugin-events-node": "0.4.12", + "@internal/plugin-todo-list": "1.0.40", + "@internal/plugin-todo-list-backend": "1.0.40", "@internal/plugin-todo-list-common": "1.0.25", - "@backstage/plugin-gateway-backend": "1.0.1", - "@backstage/plugin-home": "0.8.8", - "@backstage/plugin-home-react": "0.1.26", - "@backstage/plugin-kubernetes": "0.12.7", - "@backstage/plugin-kubernetes-backend": "0.19.6", - "@backstage/plugin-kubernetes-cluster": "0.0.25", + "@backstage/plugin-gateway-backend": "1.0.2", + "@backstage/plugin-home": "0.8.9", + "@backstage/plugin-home-react": "0.1.27", + "@backstage/plugin-kubernetes": "0.12.8", + "@backstage/plugin-kubernetes-backend": "0.19.7", + "@backstage/plugin-kubernetes-cluster": "0.0.26", "@backstage/plugin-kubernetes-common": "0.9.5", - "@backstage/plugin-kubernetes-node": "0.3.0", - "@backstage/plugin-kubernetes-react": "0.5.7", - "@backstage/plugin-notifications": "0.5.5", - "@backstage/plugin-notifications-backend": "0.5.6", - "@backstage/plugin-notifications-backend-module-email": "0.3.9", - "@backstage/plugin-notifications-backend-module-slack": "0.1.1", - "@backstage/plugin-notifications-common": "0.0.8", - "@backstage/plugin-notifications-node": "0.2.15", - "@backstage/plugin-org": "0.6.39", - "@backstage/plugin-org-react": "0.1.38", - "@backstage/plugin-permission-backend": "0.7.0", - "@backstage/plugin-permission-backend-module-allow-all-policy": "0.2.8", + "@backstage/plugin-kubernetes-node": "0.3.1", + "@backstage/plugin-kubernetes-react": "0.5.8", + "@backstage/plugin-mcp-actions-backend": "0.1.0", + "@backstage/plugin-notifications": "0.5.6", + "@backstage/plugin-notifications-backend": "0.5.7", + "@backstage/plugin-notifications-backend-module-email": "0.3.10", + "@backstage/plugin-notifications-backend-module-slack": "0.1.2", + "@backstage/plugin-notifications-common": "0.0.9", + "@backstage/plugin-notifications-node": "0.2.16", + "@backstage/plugin-org": "0.6.40", + "@backstage/plugin-org-react": "0.1.39", + "@backstage/plugin-permission-backend": "0.7.1", + "@backstage/plugin-permission-backend-module-allow-all-policy": "0.2.9", "@backstage/plugin-permission-common": "0.9.0", - "@backstage/plugin-permission-node": "0.10.0", - "@backstage/plugin-permission-react": "0.4.34", - "@backstage/plugin-proxy-backend": "0.6.2", - "@backstage/plugin-proxy-node": "0.1.4", - "@backstage/plugin-scaffolder": "1.31.0", - "@backstage/plugin-scaffolder-backend": "1.33.0", - "@backstage/plugin-scaffolder-backend-module-azure": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.10", - "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.3.9", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.3.10", - "@backstage/plugin-scaffolder-backend-module-gcp": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-gitea": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-github": "0.7.1", - "@backstage/plugin-scaffolder-backend-module-gitlab": "0.9.1", - "@backstage/plugin-scaffolder-backend-module-notifications": "0.1.10", - "@backstage/plugin-scaffolder-backend-module-rails": "0.5.9", - "@backstage/plugin-scaffolder-backend-module-sentry": "0.2.9", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.4.10", + "@backstage/plugin-permission-node": "0.10.1", + "@backstage/plugin-permission-react": "0.4.35", + "@backstage/plugin-proxy-backend": "0.6.3", + "@backstage/plugin-proxy-node": "0.1.5", + "@backstage/plugin-scaffolder": "1.32.0", + "@backstage/plugin-scaffolder-backend": "2.0.0", + "@backstage/plugin-scaffolder-backend-module-azure": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.11", + "@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-confluence-to-markdown": "0.3.10", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.3.11", + "@backstage/plugin-scaffolder-backend-module-gcp": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-gitea": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-github": "0.8.0", + "@backstage/plugin-scaffolder-backend-module-gitlab": "0.9.2", + "@backstage/plugin-scaffolder-backend-module-notifications": "0.1.11", + "@backstage/plugin-scaffolder-backend-module-rails": "0.5.10", + "@backstage/plugin-scaffolder-backend-module-sentry": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.4.11", "@backstage/plugin-scaffolder-common": "1.5.11", - "@backstage/plugin-scaffolder-node": "0.8.2", - "@backstage/plugin-scaffolder-node-test-utils": "0.2.2", - "@backstage/plugin-scaffolder-react": "1.16.0", - "@backstage/plugin-search": "1.4.26", - "@backstage/plugin-search-backend": "2.0.2", - "@backstage/plugin-search-backend-module-catalog": "0.3.4", - "@backstage/plugin-search-backend-module-elasticsearch": "1.7.2", - "@backstage/plugin-search-backend-module-explore": "0.3.2", - "@backstage/plugin-search-backend-module-pg": "0.5.44", - "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.3.9", - "@backstage/plugin-search-backend-module-techdocs": "0.4.2", - "@backstage/plugin-search-backend-node": "1.3.11", + "@backstage/plugin-scaffolder-node": "0.9.0", + "@backstage/plugin-scaffolder-node-test-utils": "0.3.0", + "@backstage/plugin-scaffolder-react": "1.17.0", + "@backstage/plugin-search": "1.4.27", + "@backstage/plugin-search-backend": "2.0.3", + "@backstage/plugin-search-backend-module-catalog": "0.3.5", + "@backstage/plugin-search-backend-module-elasticsearch": "1.7.3", + "@backstage/plugin-search-backend-module-explore": "0.3.3", + "@backstage/plugin-search-backend-module-pg": "0.5.45", + "@backstage/plugin-search-backend-module-stack-overflow-collator": "0.3.10", + "@backstage/plugin-search-backend-module-techdocs": "0.4.3", + "@backstage/plugin-search-backend-node": "1.3.12", "@backstage/plugin-search-common": "1.2.18", - "@backstage/plugin-search-react": "1.9.0", - "@backstage/plugin-signals": "0.0.19", - "@backstage/plugin-signals-backend": "0.3.4", - "@backstage/plugin-signals-node": "0.1.20", - "@backstage/plugin-signals-react": "0.0.13", - "@backstage/plugin-techdocs": "1.12.6", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.48", - "@backstage/plugin-techdocs-backend": "2.0.2", - "@backstage/plugin-techdocs-common": "0.1.0", - "@backstage/plugin-techdocs-module-addons-contrib": "1.1.24", - "@backstage/plugin-techdocs-node": "1.13.3", - "@backstage/plugin-techdocs-react": "1.2.17", - "@backstage/plugin-user-settings": "0.8.22", - "@backstage/plugin-user-settings-backend": "0.3.2", - "@backstage/plugin-user-settings-common": "0.0.1", - "@backstage/plugin-events-backend-module-kafka": "0.0.0" + "@backstage/plugin-search-react": "1.9.1", + "@backstage/plugin-signals": "0.0.20", + "@backstage/plugin-signals-backend": "0.3.5", + "@backstage/plugin-signals-node": "0.1.21", + "@backstage/plugin-signals-react": "0.0.14", + "@backstage/plugin-techdocs": "1.13.0", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.49", + "@backstage/plugin-techdocs-backend": "2.0.3", + "@backstage/plugin-techdocs-common": "0.1.1", + "@backstage/plugin-techdocs-module-addons-contrib": "1.1.25", + "@backstage/plugin-techdocs-node": "1.13.4", + "@backstage/plugin-techdocs-react": "1.3.0", + "@backstage/plugin-user-settings": "0.8.23", + "@backstage/plugin-user-settings-backend": "0.3.3", + "@backstage/plugin-user-settings-common": "0.0.1" }, "changesets": [ - "bitter-pants-watch", - "brave-facts-pay", - "chatty-clowns-dream", - "cold-meals-like", - "create-app-1748956288", - "create-app-1749565617", - "create-app-1749636320", - "cuddly-camels-lose", - "curvy-peaches-relate", - "curvy-words-create", - "deep-aliens-camp", - "deep-moments-love", - "dull-buttons-press", - "dull-cars-shout", - "eight-pigs-post", - "eight-planets-see", - "eighty-showers-hide", - "eleven-foxes-mix", - "evil-cooks-watch", - "fair-doors-bathe", - "famous-streets-stay", - "few-streets-accept", - "fix-cli-config-docs-feedback", - "fluffy-bobcats-tell", - "forty-seas-worry", - "fresh-brooms-follow", - "fresh-otters-say", - "good-paths-act", - "green-schools-live", - "grumpy-dryers-act", - "honest-moles-bet", - "itchy-mirrors-juggle", - "khaki-horses-chew", - "khaki-swans-invite", - "kind-houses-feel", - "large-baboons-prove", - "late-buttons-strive", - "lazy-rice-dream", - "long-suits-obey", - "loose-ants-learn", - "major-heads-scream", - "mean-tigers-rush", - "mighty-windows-boil", - "mira-flygande-spoons", - "new-beers-sell", - "olive-buses-serve", - "open-bottles-attack", - "open-eyes-learn", - "orange-masks-decide", - "petite-candies-tan", - "puny-pillows-wave", - "purple-times-deny", - "rare-rules-move", - "red-vans-march", - "ripe-squids-sink", - "rotten-dragons-guess", - "salty-worlds-float", - "scaffolder-breakages-1", - "scaffolder-breakages-2", - "scaffolder-breakages-3", - "scaffolder-breakages-4", - "scaffolder-breakages-5", - "scaffolder-breakages-6", - "scaffolder-deprecations-1", - "seven-beans-appear", - "shiny-bags-bet", - "six-mangos-yell", - "slimy-cups-shake", - "slow-impalas-wear", - "small-dots-march", - "smooth-eels-think", - "some-llamas-go", - "spicy-rivers-notice", - "spotty-cases-show", - "strong-trams-joke", - "stupid-flies-speak", - "stupid-goats-teach", - "stupid-pens-serve", - "sweet-ducks-wait", - "sweet-squids-dig", - "swift-brooms-bet", - "tender-trees-open", - "tender-wolves-lie", - "three-boats-sort", - "tough-heads-knock", - "true-tools-play", - "twelve-zoos-learn", - "warm-hornets-unite", - "warm-taxes-show", - "wet-bars-report", - "wet-bars-reporting", - "yummy-donuts-peel" + "chubby-dots-kiss", + "clear-bananas-end", + "curly-zoos-thank", + "cyan-islands-swim", + "dark-cougars-go", + "empty-mugs-agree", + "empty-poets-give", + "gentle-llamas-press", + "mean-lemons-dream", + "petite-paths-remain", + "public-nails-melt", + "red-trams-join", + "rich-eagles-rule", + "shaggy-cobras-rhyme", + "sharp-stars-report", + "silent-vans-tie", + "six-dots-agree", + "sixty-ties-matter", + "social-insects-cheat", + "stupid-donuts-sit", + "three-shoes-behave", + "tired-bats-attend", + "wicked-socks-share", + "wise-frogs-talk", + "yummy-pugs-battle" ] } diff --git a/.changeset/public-nails-melt.md b/.changeset/public-nails-melt.md new file mode 100644 index 0000000000..1529ee94d0 --- /dev/null +++ b/.changeset/public-nails-melt.md @@ -0,0 +1,13 @@ +--- +'@backstage/canon': minor +--- + +**BREAKING CHANGES** + +We’re updating our Button component to provide better support for button links. + +- We’re introducing a new `ButtonLink` component, which replaces the previous render prop pattern. +- To maintain naming consistency across components, `IconButton` is being renamed to `ButtonIcon`. +- Additionally, the render prop will be removed from all button-related components. + +These changes aim to simplify usage and improve clarity in our component API. diff --git a/.changeset/puny-pillows-wave.md b/.changeset/puny-pillows-wave.md deleted file mode 100644 index 813e603007..0000000000 --- a/.changeset/puny-pillows-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-plugin-api': patch ---- - -Added a new `useAppNode` hook, which can be used to get a reference to the `AppNode` from by the closest `ExtensionBoundary`. diff --git a/.changeset/purple-times-deny.md b/.changeset/purple-times-deny.md deleted file mode 100644 index 7cf4d2c3c3..0000000000 --- a/.changeset/purple-times-deny.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Added appropriate message when global templating function metadata is absent. diff --git a/.changeset/rare-rules-move.md b/.changeset/rare-rules-move.md deleted file mode 100644 index 6abc778941..0000000000 --- a/.changeset/rare-rules-move.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -**New Frontend System Only:** -The `Scaffolder` plugin is now responsible for providing an entity icon link extension to launch templates from the catalog entity page. diff --git a/.changeset/red-trams-join.md b/.changeset/red-trams-join.md new file mode 100644 index 0000000000..3ee245e2a8 --- /dev/null +++ b/.changeset/red-trams-join.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-notifications-backend': patch +--- + +Fix `addTopic` migration when `user_settings` present diff --git a/.changeset/red-vans-march.md b/.changeset/red-vans-march.md deleted file mode 100644 index a168e89884..0000000000 --- a/.changeset/red-vans-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitea': patch ---- - -Migrate to new actions format diff --git a/.changeset/rich-eagles-rule.md b/.changeset/rich-eagles-rule.md new file mode 100644 index 0000000000..100ccafb77 --- /dev/null +++ b/.changeset/rich-eagles-rule.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-mcp-actions-backend': patch +--- + +Fixed the example in the README for generating a static token by adding a subject field diff --git a/.changeset/ripe-squids-sink.md b/.changeset/ripe-squids-sink.md deleted file mode 100644 index 27d5d043b6..0000000000 --- a/.changeset/ripe-squids-sink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The experimental `FORCE_REACT_DEVELOPMENT` flag has been removed. diff --git a/.changeset/rotten-dragons-guess.md b/.changeset/rotten-dragons-guess.md deleted file mode 100644 index c35de83f6e..0000000000 --- a/.changeset/rotten-dragons-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-app-api': patch ---- - -Fixed a bug where occasionally the initialization order of multiple modules consuming a single extension point could happen in the wrong order. diff --git a/.changeset/salty-worlds-float.md b/.changeset/salty-worlds-float.md deleted file mode 100644 index a21d0b2e7c..0000000000 --- a/.changeset/salty-worlds-float.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': minor ---- - -Add .cache directory to shipped gitignore. diff --git a/.changeset/scaffolder-breakages-1.md b/.changeset/scaffolder-breakages-1.md deleted file mode 100644 index 53a7ba9d6a..0000000000 --- a/.changeset/scaffolder-breakages-1.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': major ---- - -**BREAKING CHANGES** - -Removal of deprecated re-exports from module packages. - -The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: - -- `createPublishAzureAction` should be imported from `@backstage/plugin-scaffolder-backend-module-azure` instead. - -- `createPublishBitbucketCloudAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead. - -- `createPublishBitbucketServerAction` and `createPublishBitbucketServerPullRequestAction` can be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead. - -- `createPublishBitbucketAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket` instead. - -- `createPublishGerritAction` and `createPublishGerritReviewAction` can be imported from `@backstage/plugin-scaffolder-backend-module-gerrit` instead. - -- `createGithubActionsDispatchAction`, `createGithubDeployKeyAction`, `createGithubEnvironmentAction`, `createGithubIssuesLabelAction`, `CreateGithubPullRequestActionOptions`, `createGithubRepoCreateAction`, `createGithubRepoPushAction`, `createGithubWebhookAction`, and `createPublishGithubAction` can be imported from `@backstage/plugin-scaffolder-backend-module-github` instead. - -- `createPublishGitlabAction` should be imported from `@backstage/plugin-scaffolder-backend-module-gitlab` instead. - -- `ActionContext`. `createTemplateAction`, `executeShellCommand`, `ExecuteShellCommandOptions`, `fetchContents`, `TaskSecrets`, and `TemplateAction` should be imported from `@backstage/plugin-scaffolder-node` instead. - -- `ScaffolderEntitiesProcessor` should be imported from `@backstage/plugin-catalog-backend-module-scaffolder-entity-model` instead. diff --git a/.changeset/scaffolder-breakages-2.md b/.changeset/scaffolder-breakages-2.md deleted file mode 100644 index 77ffe5fc42..0000000000 --- a/.changeset/scaffolder-breakages-2.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': major ---- - -**BREAKING ALPHA**: The `/alpha` export no longer exports the plugin. Please use `import('@backstage/plugin-scaffolder-backend')` instead as this has been removed. - -**BREAKING CHANGES**: The old `createRouter` function which was used in the old backend system has been removed along with the `RouterOptions` type. diff --git a/.changeset/scaffolder-breakages-3.md b/.changeset/scaffolder-breakages-3.md deleted file mode 100644 index f6dca6416f..0000000000 --- a/.changeset/scaffolder-breakages-3.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': major ---- - -**BREAKING CHANGES** - -The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: - -- `SerializedTask`, `SerializedTaskEvent`, `TaskBroker`, `TaskBrokerDispatchOptions`, `TaskBrokerDispatchResult`, `TaskCompletionState`, `TaskContext`, `TaskEventType`, `TaskStatus`, `TemplateFilter`, and `TemplateGlobal` should be imported from `@backstage/plugin-scaffolder-node` instead. - -- The deprecated `copyWithoutRender` option has been removed from `fetch:template` action. You should rename the option to `copyWithoutTemplating` instead. diff --git a/.changeset/scaffolder-breakages-4.md b/.changeset/scaffolder-breakages-4.md deleted file mode 100644 index e9f0c81256..0000000000 --- a/.changeset/scaffolder-breakages-4.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -'@backstage/plugin-scaffolder-node': minor ---- - -**BREAKING CHANGES** - -The legacy methods to define `createTemplateActions` have been replaced with the new native `zod` approaches for defining input and output schemas. - -You can migrate actions that look like the following with the below examples: - -```ts -// really old legacy json schema -createTemplateAction<{ repoUrl: string }, { repoOutput: string }>({ - id: 'test', - schema: { - input: { - type: 'object' - required: ['repoUrl'] - properties: { - repoUrl: { - type: 'string', - description: 'repository url description' - } - } - } - } -}); - -// old zod method -createTemplateAction({ - id: 'test' - schema: { - input: { - repoUrl: z.string({ description: 'repository url description' }) - } - } -}) - -// new method: -createTemplateAction({ - id: 'test', - schema: { - input: { - repoUrl: z => z.string({ description: 'repository url description' }) - } - } -}) - -// or for more complex zod types like unions -createTemplateAction({ - id: 'test', - schema: { - input: z => z.object({ - repoUrl: z.string({ description: 'repository url description' }) - }) - } -}) -``` - -This breaking change also means that `logStream` has been removed entirely from `ActionsContext`, and that the `logger` is now just a `LoggerService` implementation instead. There is no replacement for the `logStream`, if you wish to still keep using a `logStream` we recommend that you create your own stream that writes to `ctx.logger` instead. diff --git a/.changeset/scaffolder-breakages-5.md b/.changeset/scaffolder-breakages-5.md deleted file mode 100644 index 8047ec3dc3..0000000000 --- a/.changeset/scaffolder-breakages-5.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-github': minor ---- - -**BREAKING CHANGES** - -The `createGithubEnvironmentAction` action no longer requires an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. - -Unless you're providing your own override action to the default, this should be a non-breaking change. - -You can migrate using the following if you're getting typescript errors: - -```ts -import { catalogServiceRef } from '@backstage/plugin-catalog-node'; -import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; - -export const myModule = createBackendModule({ - pluginId: 'scaffolder', - moduleId: 'test', - register({ registerInit }) { - registerInit({ - deps: { - scaffolder: scaffolderActionsExtensionPoint, - catalog: catalogServiceRef, - }, - async init({ scaffolder, catalog }) { - scaffolder.addActions( - createGithubEnvironmentAction({ - catalog, - }), - ); - }, - }); - }, -}); -``` diff --git a/.changeset/scaffolder-breakages-6.md b/.changeset/scaffolder-breakages-6.md deleted file mode 100644 index 74ff76c27d..0000000000 --- a/.changeset/scaffolder-breakages-6.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': major ---- - -**BREAKING CHANGES** - -- The `createBuiltinActions` method has been removed, as this should no longer be needed with the new backend system route, and was only useful when passing the default list of actions again in the old backend system. You should be able to rely on the default behaviour of the new backend system which is to merge the actions. - -- The `createCatalogRegisterAction` and `createFetchCatalogEntityAction` actions no longer require an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. - -Unless you're providing your own override action to the default, this should be a non-breaking change. - -You can migrate using the following if you're getting typescript errors: - -```ts -import { catalogServiceRef } from '@backstage/plugin-catalog-node'; -import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; - -export const myModule = createBackendModule({ - pluginId: 'scaffolder', - moduleId: 'test', - register({ registerInit }) { - registerInit({ - deps: { - scaffolder: scaffolderActionsExtensionPoint, - catalog: catalogServiceRef, - }, - async init({ scaffolder, catalog }) { - scaffolder.addActions( - createCatalogRegisterAction({ - catalog, - }), - createFetchCatalogEntityAction({ - catalog, - integrations, - }), - ); - }, - }); - }, -}); -``` diff --git a/.changeset/scaffolder-deprecations-1.md b/.changeset/scaffolder-deprecations-1.md deleted file mode 100644 index 7d87013536..0000000000 --- a/.changeset/scaffolder-deprecations-1.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -**DEPRECATIONS** - -The following types and implementations have been deprecated, either because they're no longer relevant, or because upcoming changes to the `scaffolder-backend` after `2.0.0` will influence the changes to these API surfaces. - -- `CreateWorkerOptions` -- `DatabaseTaskStore` -- `DatabaseTaskStoreOptions` -- `TaskManager` -- `TaskStoreCreateTaskOptions` -- `TaskStoreCreateTaskResult` -- `TaskStoreEmitOptions` -- `TaskStoreListEventsOptions` -- `TaskStoreRecoverTaskOptions` -- `TaskStoreShutDownTaskOptions` - -There is no current path off deprecation, these types are going to be removed and rethought with a better way to define workers in the new backend system. diff --git a/.changeset/seven-beans-appear.md b/.changeset/seven-beans-appear.md deleted file mode 100644 index 82fe9f9889..0000000000 --- a/.changeset/seven-beans-appear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -Implement retry for GitLab API calls to handle rate limiting diff --git a/.changeset/shaggy-cobras-rhyme.md b/.changeset/shaggy-cobras-rhyme.md new file mode 100644 index 0000000000..d8adefd112 --- /dev/null +++ b/.changeset/shaggy-cobras-rhyme.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +We are transforming how we structure our class names and data attributes definitions for all components. They are now all set in the same place. diff --git a/.changeset/sharp-stars-report.md b/.changeset/sharp-stars-report.md new file mode 100644 index 0000000000..c37e0e39ea --- /dev/null +++ b/.changeset/sharp-stars-report.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Replaced deprecated uses of `@backstage/backend-common` with the equivalents in `@backstage/backend-defaults` and `@backstage/backend-plugin-api`. diff --git a/.changeset/shiny-bags-bet.md b/.changeset/shiny-bags-bet.md deleted file mode 100644 index 0d9f2c0f30..0000000000 --- a/.changeset/shiny-bags-bet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket': patch ---- - -Migrating `bitbucket` actions to use the new `zod` format diff --git a/.changeset/silent-vans-tie.md b/.changeset/silent-vans-tie.md new file mode 100644 index 0000000000..b81564be7e --- /dev/null +++ b/.changeset/silent-vans-tie.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +Added placeholder prop to TextField component. diff --git a/.changeset/six-dots-agree.md b/.changeset/six-dots-agree.md new file mode 100644 index 0000000000..97f9b3017f --- /dev/null +++ b/.changeset/six-dots-agree.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-defaults': patch +'@backstage/integration': patch +--- + +UrlReader: Fix handling of access tokens for GitLab readURL requests diff --git a/.changeset/six-mangos-yell.md b/.changeset/six-mangos-yell.md deleted file mode 100644 index 65ddae86f8..0000000000 --- a/.changeset/six-mangos-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/repo-tools': minor ---- - -Add support for caching the per-package output from the `package-docs` command. diff --git a/.changeset/sweet-squids-dig.md b/.changeset/sixty-ties-matter.md similarity index 58% rename from .changeset/sweet-squids-dig.md rename to .changeset/sixty-ties-matter.md index 78a388ec52..3be0bb08a8 100644 --- a/.changeset/sweet-squids-dig.md +++ b/.changeset/sixty-ties-matter.md @@ -2,4 +2,4 @@ '@backstage/plugin-scaffolder-backend-module-cookiecutter': patch --- -Migrate using new actions format +Fixing the typescript issue with using `z.unknown()` diff --git a/.changeset/slimy-cups-shake.md b/.changeset/slimy-cups-shake.md deleted file mode 100644 index 164b741499..0000000000 --- a/.changeset/slimy-cups-shake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-import': patch ---- - -Catalog import plugin full support i18n diff --git a/.changeset/slow-impalas-wear.md b/.changeset/slow-impalas-wear.md deleted file mode 100644 index b5151a6ed4..0000000000 --- a/.changeset/slow-impalas-wear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Only use the caching Jest module loader for frontend packages in order to avoid breaking real ESM module imports. diff --git a/.changeset/small-dots-march.md b/.changeset/small-dots-march.md deleted file mode 100644 index 0796ef68bb..0000000000 --- a/.changeset/small-dots-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-gitlab': patch ---- - -Support merge request labels in publish:gitlab:merge-request diff --git a/.changeset/smooth-eels-think.md b/.changeset/smooth-eels-think.md deleted file mode 100644 index c5e2fe0c85..0000000000 --- a/.changeset/smooth-eels-think.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor -'@backstage/plugin-techdocs-react': minor -'@backstage/plugin-catalog': minor -'@backstage/plugin-techdocs-common': patch ---- - -Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. diff --git a/.changeset/social-insects-cheat.md b/.changeset/social-insects-cheat.md new file mode 100644 index 0000000000..494cba15e7 --- /dev/null +++ b/.changeset/social-insects-cheat.md @@ -0,0 +1,21 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +Added support for file deletion to `publish:github:pull-request` action. + +Example usage: + +```diff + - action: publish:github:pull-request + id: clean-up-pr + input: + description: This is the description ++ filesToDelete: ++ - outdated/changelog.md ++ - sample-file.txt + owner: owner + repo: repo + title: Title Goes Here + +``` diff --git a/.changeset/some-llamas-go.md b/.changeset/some-llamas-go.md deleted file mode 100644 index d07b6a6c75..0000000000 --- a/.changeset/some-llamas-go.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-bitbucket-cloud': minor ---- - -**BREAKING**: `BitbucketCloudEntityProvider` now accepts a `CatalogService` instead of a `CatalogApi`. diff --git a/.changeset/spicy-rivers-notice.md b/.changeset/spicy-rivers-notice.md deleted file mode 100644 index 941f2d257d..0000000000 --- a/.changeset/spicy-rivers-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Fixed the `WelcomeTitle` to properly default to the previous value of `inherit` diff --git a/.changeset/spotty-cases-show.md b/.changeset/spotty-cases-show.md deleted file mode 100644 index 3e9a607733..0000000000 --- a/.changeset/spotty-cases-show.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-defaults': patch ---- - -Forwarded the new `pluginInfoResolver` option for `createApp`. diff --git a/.changeset/strong-trams-joke.md b/.changeset/strong-trams-joke.md deleted file mode 100644 index 8b6a831d7d..0000000000 --- a/.changeset/strong-trams-joke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updating the scaffolder action boilerplate to use new `zod` schema diff --git a/.changeset/stupid-donuts-sit.md b/.changeset/stupid-donuts-sit.md new file mode 100644 index 0000000000..e829d49843 --- /dev/null +++ b/.changeset/stupid-donuts-sit.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-import': patch +--- + +Fixed bug with error message since ResponseError is now thrown from CatalogClient diff --git a/.changeset/stupid-flies-speak.md b/.changeset/stupid-flies-speak.md deleted file mode 100644 index 5156a5b8b6..0000000000 --- a/.changeset/stupid-flies-speak.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/frontend-app-api': patch ---- - -Implemented support for the `plugin.info()` method in specialized apps with a default resolved for `package.json` and `catalog-info.yaml`. The default resolution logic can be overridden via the `pluginInfoResolver` option to `createSpecializedApp`, and plugin-specific overrides can be applied via the new `app.pluginOverrides` key in static configuration. diff --git a/.changeset/stupid-goats-teach.md b/.changeset/stupid-goats-teach.md deleted file mode 100644 index f90d9373e7..0000000000 --- a/.changeset/stupid-goats-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Added `backstage.pluginId` field in `package.json` to all default plugin package templates for the `new` command. diff --git a/.changeset/stupid-pens-serve.md b/.changeset/stupid-pens-serve.md deleted file mode 100644 index f7fe733254..0000000000 --- a/.changeset/stupid-pens-serve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Internal refactor to combine alpha `build` and `start` modules. diff --git a/.changeset/sweet-ducks-wait.md b/.changeset/sweet-ducks-wait.md deleted file mode 100644 index 4792fafe84..0000000000 --- a/.changeset/sweet-ducks-wait.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': minor ---- - -Added mock implementations for `ActionsService` and `ActionsRegistryService` diff --git a/.changeset/swift-brooms-bet.md b/.changeset/swift-brooms-bet.md deleted file mode 100644 index 818284fda9..0000000000 --- a/.changeset/swift-brooms-bet.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Enable usage of secrets within 'each' step of software templates. For example, you can now structure your `each` step like this: - -``` -each: - [ - { name: "Service1", token: "${{ secrets.token1 }}" }, - { name: "Service2", token: "${{ secrets.token2 }}" }, - ] -``` diff --git a/.changeset/tender-trees-open.md b/.changeset/tender-trees-open.md deleted file mode 100644 index c54fd6574f..0000000000 --- a/.changeset/tender-trees-open.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Add tests for Scaffolder diff --git a/.changeset/tender-wolves-lie.md b/.changeset/tender-wolves-lie.md deleted file mode 100644 index d5c77b44a9..0000000000 --- a/.changeset/tender-wolves-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-test-utils': patch ---- - -Make the `user` credentials mock behave more like production diff --git a/.changeset/three-boats-sort.md b/.changeset/three-boats-sort.md deleted file mode 100644 index 180a4e236c..0000000000 --- a/.changeset/three-boats-sort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -fix: merge eslint reports when using json format diff --git a/.changeset/three-shoes-behave.md b/.changeset/three-shoes-behave.md new file mode 100644 index 0000000000..51205ffa21 --- /dev/null +++ b/.changeset/three-shoes-behave.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +adding export for ButtonLink so it's importable diff --git a/.changeset/tired-bats-attend.md b/.changeset/tired-bats-attend.md new file mode 100644 index 0000000000..cfe01f14fe --- /dev/null +++ b/.changeset/tired-bats-attend.md @@ -0,0 +1,5 @@ +--- +'@backstage/integration-react': patch +--- + +Separated gitlab `write_repository` and `api` scope to pass checks in `RefreshingAuthSessionManager` diff --git a/.changeset/tough-heads-knock.md b/.changeset/tough-heads-knock.md deleted file mode 100644 index da2e2c1163..0000000000 --- a/.changeset/tough-heads-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Update `refresh_state_references.id` to be a big int diff --git a/.changeset/true-tools-play.md b/.changeset/true-tools-play.md deleted file mode 100644 index 4d1ae4d4e8..0000000000 --- a/.changeset/true-tools-play.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch ---- - -Fix `bitbucketCloudBranchRestrictions` API calls to accept null to prevent 400 errors for some branch restriction kinds defined. diff --git a/.changeset/twelve-zoos-learn.md b/.changeset/twelve-zoos-learn.md deleted file mode 100644 index c1c553cb70..0000000000 --- a/.changeset/twelve-zoos-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Fix an issue where some commands were not usable because of missing dist files diff --git a/.changeset/warm-hornets-unite.md b/.changeset/warm-hornets-unite.md deleted file mode 100644 index 65a56233cb..0000000000 --- a/.changeset/warm-hornets-unite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-react': patch ---- - -SearchBar clear button support i18n diff --git a/.changeset/warm-taxes-show.md b/.changeset/warm-taxes-show.md deleted file mode 100644 index edebd0048e..0000000000 --- a/.changeset/warm-taxes-show.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': minor ---- - -Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using instead of just . diff --git a/.changeset/wet-bars-report.md b/.changeset/wet-bars-report.md deleted file mode 100644 index d556f6cc61..0000000000 --- a/.changeset/wet-bars-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -Added `coreServices.actionsRegistry` and `coreServices.actions` to allow registration of distributed actions from plugins, and the ability to invoke these actions diff --git a/.changeset/wet-bars-reporting.md b/.changeset/wet-bars-reporting.md deleted file mode 100644 index 7dc66cb280..0000000000 --- a/.changeset/wet-bars-reporting.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-defaults': patch ---- - -Added some default implementations for the `ActionsService` and `ActionsRegistryService` that allow registration of actions for a particular plugin. diff --git a/.changeset/wicked-socks-share.md b/.changeset/wicked-socks-share.md new file mode 100644 index 0000000000..d3e1275732 --- /dev/null +++ b/.changeset/wicked-socks-share.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-search-backend': patch +--- + +Error messages should not contain backend SQL query strings in the API response, this change will ensure that messages are logged and empty response is returned to the user diff --git a/.changeset/wise-frogs-talk.md b/.changeset/wise-frogs-talk.md new file mode 100644 index 0000000000..6a25abc246 --- /dev/null +++ b/.changeset/wise-frogs-talk.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-defaults': patch +'@backstage/integration': patch +--- + +Fixed bug where the GitLab user token and GitLab integration token were being merged together diff --git a/.changeset/yummy-donuts-peel.md b/.changeset/yummy-donuts-peel.md deleted file mode 100644 index 6c66573025..0000000000 --- a/.changeset/yummy-donuts-peel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/canon': patch ---- - -Remove leftover console.log from Container component. diff --git a/.changeset/yummy-pugs-battle.md b/.changeset/yummy-pugs-battle.md new file mode 100644 index 0000000000..a17b934deb --- /dev/null +++ b/.changeset/yummy-pugs-battle.md @@ -0,0 +1,5 @@ +--- +'@backstage/theme': patch +--- + +Update uncomfortably bright color in recently visited and top visited home page cards diff --git a/.eslintrc.js b/.eslintrc.js index 409b820783..54f9e69576 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -18,8 +18,26 @@ var path = require('path'); module.exports = { root: true, - plugins: ['@spotify', 'notice', 'react', 'testing-library'], + plugins: ['@spotify', 'notice', 'react', 'testing-library', '@backstage'], rules: { + '@backstage/no-mixed-plugin-imports': [ + 'error', + { + // TODO: Fix these either by right role or by moving things to new packages + excludedTargetPackages: [ + '@backstage/plugin-catalog', + '@backstage/plugin-techdocs', + '@backstage/plugin-app', + '@backstage/plugin-catalog-backend', + '@backstage/test-utils', + '@backstage/plugin-auth-backend', + '@backstage/plugin-permission-backend', + '@backstage/plugin-kubernetes-backend', + '@backstage/config-loader', + '@backstage/plugin-app-backend' + ], + } + ], 'react/react-in-jsx-scope': 'off', 'notice/notice': [ 'error', diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 77faa9354f..4716f1363f 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -35,6 +35,11 @@ rangeStrategy: 'replace', matchSourceUrls: ['https://github.com/gregberge/svgr{/,}**'], }, + { + groupName: 'Module-federation monorepo packages', + rangeStrategy: 'replace', + matchSourceUrls: ['https://github.com/module-federation/core{/,}**'], + }, // We update yarn packages manually as it's gzip'd and we don't want to pollute the repository too much. { matchSourceUrls: ['https://github.com/yarnpkg/berry'], diff --git a/.github/vale/config/vocabularies/Backstage/accept.txt b/.github/vale/config/vocabularies/Backstage/accept.txt index 36f9335b1f..92c7a293f5 100644 --- a/.github/vale/config/vocabularies/Backstage/accept.txt +++ b/.github/vale/config/vocabularies/Backstage/accept.txt @@ -433,6 +433,7 @@ statefulsets stdout storable storages +Streamable stringified stringify subcommand diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index e1547801ef..9c97c62d16 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -52,17 +52,17 @@ jobs: working-directory: ./example-app - name: Login to GitHub Container Registry - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - name: Build and push - uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0 + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: './example-app' file: ./example-app/packages/backend/Dockerfile diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index 67fcc5d709..a5e89d6103 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -321,12 +321,12 @@ jobs: name: storybook path: microsite/build/storybook - - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: stable-reference-beta path: microsite/build/api/stable/ - - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: next-reference-beta path: microsite/build/api/next/ diff --git a/.github/workflows/sync_code-formatting.yml b/.github/workflows/sync_code-formatting.yml index ee97f3fef3..18ec62c7bf 100644 --- a/.github/workflows/sync_code-formatting.yml +++ b/.github/workflows/sync_code-formatting.yml @@ -30,7 +30,7 @@ jobs: cache-prefix: ${{ runner.os }}-v${{ matrix.node-version }} - name: Run Prettier on ADOPTERS.md - uses: creyD/prettier_action@31355f8eef017f8aeba2e0bc09d8502b13dbbad1 # v4.3 + uses: creyD/prettier_action@8c18391fdc98ed0d884c6345f03975edac71b8f0 # v4.6 with: # Modifies commit only if prettier autofixed the ADOPTERS.md prettier_options: --config docs/prettier.config.js --write ADOPTERS.md diff --git a/.github/workflows/verify_microsite.yml b/.github/workflows/verify_microsite.yml index df68cff2cf..38900074d6 100644 --- a/.github/workflows/verify_microsite.yml +++ b/.github/workflows/verify_microsite.yml @@ -325,13 +325,13 @@ jobs: working-directory: microsite - name: download stable reference (beta) - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: stable-reference-beta path: api/stable/ - name: download next reference (beta) - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: name: next-reference-beta path: api/next/ diff --git a/.github/workflows/verify_storybook.yml b/.github/workflows/verify_storybook.yml index 3cc846a706..6c1ceb4c52 100644 --- a/.github/workflows/verify_storybook.yml +++ b/.github/workflows/verify_storybook.yml @@ -54,7 +54,7 @@ jobs: - run: yarn --cwd packages/canon build-storybook - - uses: chromaui/action@e8cc4c31775280b175a3c440076c00d19a9014d7 # v11 + - uses: chromaui/action@1cfa065cbdab28f6ca3afaeb3d761383076a35aa # v11 with: token: ${{ secrets.GITHUB_TOKEN }} # projectToken intentionally shared to allow collaborators to run Chromatic on forks diff --git a/app-config.yaml b/app-config.yaml index eaee401d09..910a3e4f99 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -36,6 +36,12 @@ backend: # keys: # - secret: ${BACKEND_SECRET} + # Used for testing rate limiting locally + # rateLimit: + # windowMs: 1m + # incomingRequestLimit: 1 + # ipAllowList: [] + auth: # TODO: once plugins have been migrated we can remove this, but right now it # is require for the backend-next to work in this repo @@ -132,7 +138,6 @@ integrations: secretAccessKey: ${AWS_SECRET_ACCESS_KEY} catalog: - useUrlReadersSearch: true import: entityFilename: catalog-info.yaml pullRequestBranchName: backstage-integration diff --git a/canon-docs/next.config.mjs b/canon-docs/next.config.mjs index ca221d9a8c..8e6ed8fdc0 100644 --- a/canon-docs/next.config.mjs +++ b/canon-docs/next.config.mjs @@ -8,6 +8,11 @@ const nextConfig = { images: { unoptimized: true, }, + typescript: { + // Ignore TypeScript errors during build - safe for React 18/19 compatibility issues + // These are type-level conflicts that don't affect runtime behavior + ignoreBuildErrors: true, + }, }; const withMDX = createMDX({}); diff --git a/canon-docs/package.json b/canon-docs/package.json index 5a4affc45b..dba4abb78f 100644 --- a/canon-docs/package.json +++ b/canon-docs/package.json @@ -8,19 +8,25 @@ "lint": "next lint", "start": "npm run build:css && next dev" }, + "resolutions": { + "@types/react": "19.1.8", + "@types/react-dom": "19.1.6" + }, "dependencies": { "@codemirror/lang-sass": "^6.0.2", "@lezer/highlight": "^1.2.1", "@mdx-js/loader": "^3.1.0", "@mdx-js/react": "^3.1.0", - "@next/mdx": "^15.1.4", + "@next/mdx": "15.3.4", "@storybook/react": "^8.6.8", "@uiw/codemirror-themes": "^4.23.7", "@uiw/react-codemirror": "^4.23.7", + "html-react-parser": "^5.2.5", "motion": "^12.4.1", - "next": "14.2.26", - "react": "^18.0.2", - "react-dom": "^18.0.2", + "next": "15.3.4", + "next-mdx-remote-client": "^2.1.2", + "react": "19.1.0", + "react-dom": "19.1.0", "react-frame-component": "^5.2.7", "shiki": "^1.26.1", "storybook": "^8.6.8" @@ -28,10 +34,10 @@ "devDependencies": { "@types/mdx": "^2.0.13", "@types/node": "^20", - "@types/react": "^18.0.0", - "@types/react-dom": "^18.0.0", + "@types/react": "19.1.8", + "@types/react-dom": "19.1.6", "eslint": "^8", - "eslint-config-next": "14.2.23", + "eslint-config-next": "15.3.4", "lightningcss": "^1.28.2", "typescript": "^5" } diff --git a/canon-docs/public/header.png b/canon-docs/public/header.png index 507bd05ca7..8d11151a3e 100644 Binary files a/canon-docs/public/header.png and b/canon-docs/public/header.png differ diff --git a/canon-docs/public/styles.css b/canon-docs/public/styles.css new file mode 100644 index 0000000000..8a837749b5 --- /dev/null +++ b/canon-docs/public/styles.css @@ -0,0 +1,2 @@ +/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */ +@layer base{*,:before,:after{box-sizing:border-box}html{-webkit-text-size-adjust:100%;tab-size:4;font-family:system-ui,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;line-height:1.15}body{margin:0}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{border-color:currentColor}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:100%;line-height:1.15}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}}.cu-p{padding:var(--p)}.cu-p-0\.5{padding:var(--canon-space-0_5)}.cu-p-1{padding:var(--canon-space-1)}.cu-p-1\.5{padding:var(--canon-space-1_5)}.cu-p-2{padding:var(--canon-space-2)}.cu-p-3{padding:var(--canon-space-3)}.cu-p-4{padding:var(--canon-space-4)}.cu-p-5{padding:var(--canon-space-5)}.cu-p-6{padding:var(--canon-space-6)}.cu-p-7{padding:var(--canon-space-7)}.cu-p-8{padding:var(--canon-space-8)}.cu-p-9{padding:var(--canon-space-9)}.cu-p-10{padding:var(--canon-space-10)}.cu-p-11{padding:var(--canon-space-11)}.cu-p-12{padding:var(--canon-space-12)}.cu-p-13{padding:var(--canon-space-13)}.cu-p-14{padding:var(--canon-space-14)}@media (width>=640px){.xs\:cu-p{padding:var(--p-xs)}.xs\:cu-p-0\.5{padding:var(--canon-space-0_5)}.xs\:cu-p-1{padding:var(--canon-space-1)}.xs\:cu-p-1\.5{padding:var(--canon-space-1_5)}.xs\:cu-p-2{padding:var(--canon-space-2)}.xs\:cu-p-3{padding:var(--canon-space-3)}.xs\:cu-p-4{padding:var(--canon-space-4)}.xs\:cu-p-5{padding:var(--canon-space-5)}.xs\:cu-p-6{padding:var(--canon-space-6)}.xs\:cu-p-7{padding:var(--canon-space-7)}.xs\:cu-p-8{padding:var(--canon-space-8)}.xs\:cu-p-9{padding:var(--canon-space-9)}.xs\:cu-p-10{padding:var(--canon-space-10)}.xs\:cu-p-11{padding:var(--canon-space-11)}.xs\:cu-p-12{padding:var(--canon-space-12)}.xs\:cu-p-13{padding:var(--canon-space-13)}.xs\:cu-p-14{padding:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-p{padding:var(--p-sm)}.sm\:cu-p-0\.5{padding:var(--canon-space-0_5)}.sm\:cu-p-1{padding:var(--canon-space-1)}.sm\:cu-p-1\.5{padding:var(--canon-space-1_5)}.sm\:cu-p-2{padding:var(--canon-space-2)}.sm\:cu-p-3{padding:var(--canon-space-3)}.sm\:cu-p-4{padding:var(--canon-space-4)}.sm\:cu-p-5{padding:var(--canon-space-5)}.sm\:cu-p-6{padding:var(--canon-space-6)}.sm\:cu-p-7{padding:var(--canon-space-7)}.sm\:cu-p-8{padding:var(--canon-space-8)}.sm\:cu-p-9{padding:var(--canon-space-9)}.sm\:cu-p-10{padding:var(--canon-space-10)}.sm\:cu-p-11{padding:var(--canon-space-11)}.sm\:cu-p-12{padding:var(--canon-space-12)}.sm\:cu-p-13{padding:var(--canon-space-13)}.sm\:cu-p-14{padding:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-p{padding:var(--p-md)}.md\:cu-p-0\.5{padding:var(--canon-space-0_5)}.md\:cu-p-1{padding:var(--canon-space-1)}.md\:cu-p-1\.5{padding:var(--canon-space-1_5)}.md\:cu-p-2{padding:var(--canon-space-2)}.md\:cu-p-3{padding:var(--canon-space-3)}.md\:cu-p-4{padding:var(--canon-space-4)}.md\:cu-p-5{padding:var(--canon-space-5)}.md\:cu-p-6{padding:var(--canon-space-6)}.md\:cu-p-7{padding:var(--canon-space-7)}.md\:cu-p-8{padding:var(--canon-space-8)}.md\:cu-p-9{padding:var(--canon-space-9)}.md\:cu-p-10{padding:var(--canon-space-10)}.md\:cu-p-11{padding:var(--canon-space-11)}.md\:cu-p-12{padding:var(--canon-space-12)}.md\:cu-p-13{padding:var(--canon-space-13)}.md\:cu-p-14{padding:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-p{padding:var(--p-lg)}.lg\:cu-p-0\.5{padding:var(--canon-space-0_5)}.lg\:cu-p-1{padding:var(--canon-space-1)}.lg\:cu-p-1\.5{padding:var(--canon-space-1_5)}.lg\:cu-p-2{padding:var(--canon-space-2)}.lg\:cu-p-3{padding:var(--canon-space-3)}.lg\:cu-p-4{padding:var(--canon-space-4)}.lg\:cu-p-5{padding:var(--canon-space-5)}.lg\:cu-p-6{padding:var(--canon-space-6)}.lg\:cu-p-7{padding:var(--canon-space-7)}.lg\:cu-p-8{padding:var(--canon-space-8)}.lg\:cu-p-9{padding:var(--canon-space-9)}.lg\:cu-p-10{padding:var(--canon-space-10)}.lg\:cu-p-11{padding:var(--canon-space-11)}.lg\:cu-p-12{padding:var(--canon-space-12)}.lg\:cu-p-13{padding:var(--canon-space-13)}.lg\:cu-p-14{padding:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-p{padding:var(--p-xl)}.xl\:cu-p-0\.5{padding:var(--canon-space-0_5)}.xl\:cu-p-1{padding:var(--canon-space-1)}.xl\:cu-p-1\.5{padding:var(--canon-space-1_5)}.xl\:cu-p-2{padding:var(--canon-space-2)}.xl\:cu-p-3{padding:var(--canon-space-3)}.xl\:cu-p-4{padding:var(--canon-space-4)}.xl\:cu-p-5{padding:var(--canon-space-5)}.xl\:cu-p-6{padding:var(--canon-space-6)}.xl\:cu-p-7{padding:var(--canon-space-7)}.xl\:cu-p-8{padding:var(--canon-space-8)}.xl\:cu-p-9{padding:var(--canon-space-9)}.xl\:cu-p-10{padding:var(--canon-space-10)}.xl\:cu-p-11{padding:var(--canon-space-11)}.xl\:cu-p-12{padding:var(--canon-space-12)}.xl\:cu-p-13{padding:var(--canon-space-13)}.xl\:cu-p-14{padding:var(--canon-space-14)}}.cu-pl{padding-left:var(--pl)}.cu-pl-0\.5{padding-left:var(--canon-space-0_5)}.cu-pl-1{padding-left:var(--canon-space-1)}.cu-pl-1\.5{padding-left:var(--canon-space-1_5)}.cu-pl-2{padding-left:var(--canon-space-2)}.cu-pl-3{padding-left:var(--canon-space-3)}.cu-pl-4{padding-left:var(--canon-space-4)}.cu-pl-5{padding-left:var(--canon-space-5)}.cu-pl-6{padding-left:var(--canon-space-6)}.cu-pl-7{padding-left:var(--canon-space-7)}.cu-pl-8{padding-left:var(--canon-space-8)}.cu-pl-9{padding-left:var(--canon-space-9)}.cu-pl-10{padding-left:var(--canon-space-10)}.cu-pl-11{padding-left:var(--canon-space-11)}.cu-pl-12{padding-left:var(--canon-space-12)}.cu-pl-13{padding-left:var(--canon-space-13)}.cu-pl-14{padding-left:var(--canon-space-14)}@media (width>=640px){.xs\:cu-pl{padding-left:var(--pl-xs)}.xs\:cu-pl-0\.5{padding-left:var(--canon-space-0_5)}.xs\:cu-pl-1{padding-left:var(--canon-space-1)}.xs\:cu-pl-1\.5{padding-left:var(--canon-space-1_5)}.xs\:cu-pl-2{padding-left:var(--canon-space-2)}.xs\:cu-pl-3{padding-left:var(--canon-space-3)}.xs\:cu-pl-4{padding-left:var(--canon-space-4)}.xs\:cu-pl-5{padding-left:var(--canon-space-5)}.xs\:cu-pl-6{padding-left:var(--canon-space-6)}.xs\:cu-pl-7{padding-left:var(--canon-space-7)}.xs\:cu-pl-8{padding-left:var(--canon-space-8)}.xs\:cu-pl-9{padding-left:var(--canon-space-9)}.xs\:cu-pl-10{padding-left:var(--canon-space-10)}.xs\:cu-pl-11{padding-left:var(--canon-space-11)}.xs\:cu-pl-12{padding-left:var(--canon-space-12)}.xs\:cu-pl-13{padding-left:var(--canon-space-13)}.xs\:cu-pl-14{padding-left:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-pl{padding-left:var(--pl-sm)}.sm\:cu-pl-0\.5{padding-left:var(--canon-space-0_5)}.sm\:cu-pl-1{padding-left:var(--canon-space-1)}.sm\:cu-pl-1\.5{padding-left:var(--canon-space-1_5)}.sm\:cu-pl-2{padding-left:var(--canon-space-2)}.sm\:cu-pl-3{padding-left:var(--canon-space-3)}.sm\:cu-pl-4{padding-left:var(--canon-space-4)}.sm\:cu-pl-5{padding-left:var(--canon-space-5)}.sm\:cu-pl-6{padding-left:var(--canon-space-6)}.sm\:cu-pl-7{padding-left:var(--canon-space-7)}.sm\:cu-pl-8{padding-left:var(--canon-space-8)}.sm\:cu-pl-9{padding-left:var(--canon-space-9)}.sm\:cu-pl-10{padding-left:var(--canon-space-10)}.sm\:cu-pl-11{padding-left:var(--canon-space-11)}.sm\:cu-pl-12{padding-left:var(--canon-space-12)}.sm\:cu-pl-13{padding-left:var(--canon-space-13)}.sm\:cu-pl-14{padding-left:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-pl{padding-left:var(--pl-md)}.md\:cu-pl-0\.5{padding-left:var(--canon-space-0_5)}.md\:cu-pl-1{padding-left:var(--canon-space-1)}.md\:cu-pl-1\.5{padding-left:var(--canon-space-1_5)}.md\:cu-pl-2{padding-left:var(--canon-space-2)}.md\:cu-pl-3{padding-left:var(--canon-space-3)}.md\:cu-pl-4{padding-left:var(--canon-space-4)}.md\:cu-pl-5{padding-left:var(--canon-space-5)}.md\:cu-pl-6{padding-left:var(--canon-space-6)}.md\:cu-pl-7{padding-left:var(--canon-space-7)}.md\:cu-pl-8{padding-left:var(--canon-space-8)}.md\:cu-pl-9{padding-left:var(--canon-space-9)}.md\:cu-pl-10{padding-left:var(--canon-space-10)}.md\:cu-pl-11{padding-left:var(--canon-space-11)}.md\:cu-pl-12{padding-left:var(--canon-space-12)}.md\:cu-pl-13{padding-left:var(--canon-space-13)}.md\:cu-pl-14{padding-left:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-pl{padding-left:var(--pl-lg)}.lg\:cu-pl-0\.5{padding-left:var(--canon-space-0_5)}.lg\:cu-pl-1{padding-left:var(--canon-space-1)}.lg\:cu-pl-1\.5{padding-left:var(--canon-space-1_5)}.lg\:cu-pl-2{padding-left:var(--canon-space-2)}.lg\:cu-pl-3{padding-left:var(--canon-space-3)}.lg\:cu-pl-4{padding-left:var(--canon-space-4)}.lg\:cu-pl-5{padding-left:var(--canon-space-5)}.lg\:cu-pl-6{padding-left:var(--canon-space-6)}.lg\:cu-pl-7{padding-left:var(--canon-space-7)}.lg\:cu-pl-8{padding-left:var(--canon-space-8)}.lg\:cu-pl-9{padding-left:var(--canon-space-9)}.lg\:cu-pl-10{padding-left:var(--canon-space-10)}.lg\:cu-pl-11{padding-left:var(--canon-space-11)}.lg\:cu-pl-12{padding-left:var(--canon-space-12)}.lg\:cu-pl-13{padding-left:var(--canon-space-13)}.lg\:cu-pl-14{padding-left:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-pl{padding-left:var(--pl-xl)}.xl\:cu-pl-0\.5{padding-left:var(--canon-space-0_5)}.xl\:cu-pl-1{padding-left:var(--canon-space-1)}.xl\:cu-pl-1\.5{padding-left:var(--canon-space-1_5)}.xl\:cu-pl-2{padding-left:var(--canon-space-2)}.xl\:cu-pl-3{padding-left:var(--canon-space-3)}.xl\:cu-pl-4{padding-left:var(--canon-space-4)}.xl\:cu-pl-5{padding-left:var(--canon-space-5)}.xl\:cu-pl-6{padding-left:var(--canon-space-6)}.xl\:cu-pl-7{padding-left:var(--canon-space-7)}.xl\:cu-pl-8{padding-left:var(--canon-space-8)}.xl\:cu-pl-9{padding-left:var(--canon-space-9)}.xl\:cu-pl-10{padding-left:var(--canon-space-10)}.xl\:cu-pl-11{padding-left:var(--canon-space-11)}.xl\:cu-pl-12{padding-left:var(--canon-space-12)}.xl\:cu-pl-13{padding-left:var(--canon-space-13)}.xl\:cu-pl-14{padding-left:var(--canon-space-14)}}.cu-pr{padding-right:var(--pr)}.cu-pr-0\.5{padding-right:var(--canon-space-0_5)}.cu-pr-1{padding-right:var(--canon-space-1)}.cu-pr-1\.5{padding-right:var(--canon-space-1_5)}.cu-pr-2{padding-right:var(--canon-space-2)}.cu-pr-3{padding-right:var(--canon-space-3)}.cu-pr-4{padding-right:var(--canon-space-4)}.cu-pr-5{padding-right:var(--canon-space-5)}.cu-pr-6{padding-right:var(--canon-space-6)}.cu-pr-7{padding-right:var(--canon-space-7)}.cu-pr-8{padding-right:var(--canon-space-8)}.cu-pr-9{padding-right:var(--canon-space-9)}.cu-pr-10{padding-right:var(--canon-space-10)}.cu-pr-11{padding-right:var(--canon-space-11)}.cu-pr-12{padding-right:var(--canon-space-12)}.cu-pr-13{padding-right:var(--canon-space-13)}.cu-pr-14{padding-right:var(--canon-space-14)}@media (width>=640px){.xs\:cu-pr{padding-right:var(--pr-xs)}.xs\:cu-pr-0\.5{padding-right:var(--canon-space-0_5)}.xs\:cu-pr-1{padding-right:var(--canon-space-1)}.xs\:cu-pr-1\.5{padding-right:var(--canon-space-1_5)}.xs\:cu-pr-2{padding-right:var(--canon-space-2)}.xs\:cu-pr-3{padding-right:var(--canon-space-3)}.xs\:cu-pr-4{padding-right:var(--canon-space-4)}.xs\:cu-pr-5{padding-right:var(--canon-space-5)}.xs\:cu-pr-6{padding-right:var(--canon-space-6)}.xs\:cu-pr-7{padding-right:var(--canon-space-7)}.xs\:cu-pr-8{padding-right:var(--canon-space-8)}.xs\:cu-pr-9{padding-right:var(--canon-space-9)}.xs\:cu-pr-10{padding-right:var(--canon-space-10)}.xs\:cu-pr-11{padding-right:var(--canon-space-11)}.xs\:cu-pr-12{padding-right:var(--canon-space-12)}.xs\:cu-pr-13{padding-right:var(--canon-space-13)}.xs\:cu-pr-14{padding-right:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-pr{padding-right:var(--pr-sm)}.sm\:cu-pr-0\.5{padding-right:var(--canon-space-0_5)}.sm\:cu-pr-1{padding-right:var(--canon-space-1)}.sm\:cu-pr-1\.5{padding-right:var(--canon-space-1_5)}.sm\:cu-pr-2{padding-right:var(--canon-space-2)}.sm\:cu-pr-3{padding-right:var(--canon-space-3)}.sm\:cu-pr-4{padding-right:var(--canon-space-4)}.sm\:cu-pr-5{padding-right:var(--canon-space-5)}.sm\:cu-pr-6{padding-right:var(--canon-space-6)}.sm\:cu-pr-7{padding-right:var(--canon-space-7)}.sm\:cu-pr-8{padding-right:var(--canon-space-8)}.sm\:cu-pr-9{padding-right:var(--canon-space-9)}.sm\:cu-pr-10{padding-right:var(--canon-space-10)}.sm\:cu-pr-11{padding-right:var(--canon-space-11)}.sm\:cu-pr-12{padding-right:var(--canon-space-12)}.sm\:cu-pr-13{padding-right:var(--canon-space-13)}.sm\:cu-pr-14{padding-right:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-pr{padding-right:var(--pr-md)}.md\:cu-pr-0\.5{padding-right:var(--canon-space-0_5)}.md\:cu-pr-1{padding-right:var(--canon-space-1)}.md\:cu-pr-1\.5{padding-right:var(--canon-space-1_5)}.md\:cu-pr-2{padding-right:var(--canon-space-2)}.md\:cu-pr-3{padding-right:var(--canon-space-3)}.md\:cu-pr-4{padding-right:var(--canon-space-4)}.md\:cu-pr-5{padding-right:var(--canon-space-5)}.md\:cu-pr-6{padding-right:var(--canon-space-6)}.md\:cu-pr-7{padding-right:var(--canon-space-7)}.md\:cu-pr-8{padding-right:var(--canon-space-8)}.md\:cu-pr-9{padding-right:var(--canon-space-9)}.md\:cu-pr-10{padding-right:var(--canon-space-10)}.md\:cu-pr-11{padding-right:var(--canon-space-11)}.md\:cu-pr-12{padding-right:var(--canon-space-12)}.md\:cu-pr-13{padding-right:var(--canon-space-13)}.md\:cu-pr-14{padding-right:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-pr{padding-right:var(--pr-lg)}.lg\:cu-pr-0\.5{padding-right:var(--canon-space-0_5)}.lg\:cu-pr-1{padding-right:var(--canon-space-1)}.lg\:cu-pr-1\.5{padding-right:var(--canon-space-1_5)}.lg\:cu-pr-2{padding-right:var(--canon-space-2)}.lg\:cu-pr-3{padding-right:var(--canon-space-3)}.lg\:cu-pr-4{padding-right:var(--canon-space-4)}.lg\:cu-pr-5{padding-right:var(--canon-space-5)}.lg\:cu-pr-6{padding-right:var(--canon-space-6)}.lg\:cu-pr-7{padding-right:var(--canon-space-7)}.lg\:cu-pr-8{padding-right:var(--canon-space-8)}.lg\:cu-pr-9{padding-right:var(--canon-space-9)}.lg\:cu-pr-10{padding-right:var(--canon-space-10)}.lg\:cu-pr-11{padding-right:var(--canon-space-11)}.lg\:cu-pr-12{padding-right:var(--canon-space-12)}.lg\:cu-pr-13{padding-right:var(--canon-space-13)}.lg\:cu-pr-14{padding-right:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-pr{padding-right:var(--pr-xl)}.xl\:cu-pr-0\.5{padding-right:var(--canon-space-0_5)}.xl\:cu-pr-1{padding-right:var(--canon-space-1)}.xl\:cu-pr-1\.5{padding-right:var(--canon-space-1_5)}.xl\:cu-pr-2{padding-right:var(--canon-space-2)}.xl\:cu-pr-3{padding-right:var(--canon-space-3)}.xl\:cu-pr-4{padding-right:var(--canon-space-4)}.xl\:cu-pr-5{padding-right:var(--canon-space-5)}.xl\:cu-pr-6{padding-right:var(--canon-space-6)}.xl\:cu-pr-7{padding-right:var(--canon-space-7)}.xl\:cu-pr-8{padding-right:var(--canon-space-8)}.xl\:cu-pr-9{padding-right:var(--canon-space-9)}.xl\:cu-pr-10{padding-right:var(--canon-space-10)}.xl\:cu-pr-11{padding-right:var(--canon-space-11)}.xl\:cu-pr-12{padding-right:var(--canon-space-12)}.xl\:cu-pr-13{padding-right:var(--canon-space-13)}.xl\:cu-pr-14{padding-right:var(--canon-space-14)}}.cu-pt{padding-top:var(--pt)}.cu-pt-0\.5{padding-top:var(--canon-space-0_5)}.cu-pt-1{padding-top:var(--canon-space-1)}.cu-pt-1\.5{padding-top:var(--canon-space-1_5)}.cu-pt-2{padding-top:var(--canon-space-2)}.cu-pt-3{padding-top:var(--canon-space-3)}.cu-pt-4{padding-top:var(--canon-space-4)}.cu-pt-5{padding-top:var(--canon-space-5)}.cu-pt-6{padding-top:var(--canon-space-6)}.cu-pt-7{padding-top:var(--canon-space-7)}.cu-pt-8{padding-top:var(--canon-space-8)}.cu-pt-9{padding-top:var(--canon-space-9)}.cu-pt-10{padding-top:var(--canon-space-10)}.cu-pt-11{padding-top:var(--canon-space-11)}.cu-pt-12{padding-top:var(--canon-space-12)}.cu-pt-13{padding-top:var(--canon-space-13)}.cu-pt-14{padding-top:var(--canon-space-14)}@media (width>=640px){.xs\:cu-pt{padding-top:var(--pt-xs)}.xs\:cu-pt-0\.5{padding-top:var(--canon-space-0_5)}.xs\:cu-pt-1{padding-top:var(--canon-space-1)}.xs\:cu-pt-1\.5{padding-top:var(--canon-space-1_5)}.xs\:cu-pt-2{padding-top:var(--canon-space-2)}.xs\:cu-pt-3{padding-top:var(--canon-space-3)}.xs\:cu-pt-4{padding-top:var(--canon-space-4)}.xs\:cu-pt-5{padding-top:var(--canon-space-5)}.xs\:cu-pt-6{padding-top:var(--canon-space-6)}.xs\:cu-pt-7{padding-top:var(--canon-space-7)}.xs\:cu-pt-8{padding-top:var(--canon-space-8)}.xs\:cu-pt-9{padding-top:var(--canon-space-9)}.xs\:cu-pt-10{padding-top:var(--canon-space-10)}.xs\:cu-pt-11{padding-top:var(--canon-space-11)}.xs\:cu-pt-12{padding-top:var(--canon-space-12)}.xs\:cu-pt-13{padding-top:var(--canon-space-13)}.xs\:cu-pt-14{padding-top:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-pt{padding-top:var(--pt-sm)}.sm\:cu-pt-0\.5{padding-top:var(--canon-space-0_5)}.sm\:cu-pt-1{padding-top:var(--canon-space-1)}.sm\:cu-pt-1\.5{padding-top:var(--canon-space-1_5)}.sm\:cu-pt-2{padding-top:var(--canon-space-2)}.sm\:cu-pt-3{padding-top:var(--canon-space-3)}.sm\:cu-pt-4{padding-top:var(--canon-space-4)}.sm\:cu-pt-5{padding-top:var(--canon-space-5)}.sm\:cu-pt-6{padding-top:var(--canon-space-6)}.sm\:cu-pt-7{padding-top:var(--canon-space-7)}.sm\:cu-pt-8{padding-top:var(--canon-space-8)}.sm\:cu-pt-9{padding-top:var(--canon-space-9)}.sm\:cu-pt-10{padding-top:var(--canon-space-10)}.sm\:cu-pt-11{padding-top:var(--canon-space-11)}.sm\:cu-pt-12{padding-top:var(--canon-space-12)}.sm\:cu-pt-13{padding-top:var(--canon-space-13)}.sm\:cu-pt-14{padding-top:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-pt{padding-top:var(--pt-md)}.md\:cu-pt-0\.5{padding-top:var(--canon-space-0_5)}.md\:cu-pt-1{padding-top:var(--canon-space-1)}.md\:cu-pt-1\.5{padding-top:var(--canon-space-1_5)}.md\:cu-pt-2{padding-top:var(--canon-space-2)}.md\:cu-pt-3{padding-top:var(--canon-space-3)}.md\:cu-pt-4{padding-top:var(--canon-space-4)}.md\:cu-pt-5{padding-top:var(--canon-space-5)}.md\:cu-pt-6{padding-top:var(--canon-space-6)}.md\:cu-pt-7{padding-top:var(--canon-space-7)}.md\:cu-pt-8{padding-top:var(--canon-space-8)}.md\:cu-pt-9{padding-top:var(--canon-space-9)}.md\:cu-pt-10{padding-top:var(--canon-space-10)}.md\:cu-pt-11{padding-top:var(--canon-space-11)}.md\:cu-pt-12{padding-top:var(--canon-space-12)}.md\:cu-pt-13{padding-top:var(--canon-space-13)}.md\:cu-pt-14{padding-top:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-pt{padding-top:var(--pt-lg)}.lg\:cu-pt-0\.5{padding-top:var(--canon-space-0_5)}.lg\:cu-pt-1{padding-top:var(--canon-space-1)}.lg\:cu-pt-1\.5{padding-top:var(--canon-space-1_5)}.lg\:cu-pt-2{padding-top:var(--canon-space-2)}.lg\:cu-pt-3{padding-top:var(--canon-space-3)}.lg\:cu-pt-4{padding-top:var(--canon-space-4)}.lg\:cu-pt-5{padding-top:var(--canon-space-5)}.lg\:cu-pt-6{padding-top:var(--canon-space-6)}.lg\:cu-pt-7{padding-top:var(--canon-space-7)}.lg\:cu-pt-8{padding-top:var(--canon-space-8)}.lg\:cu-pt-9{padding-top:var(--canon-space-9)}.lg\:cu-pt-10{padding-top:var(--canon-space-10)}.lg\:cu-pt-11{padding-top:var(--canon-space-11)}.lg\:cu-pt-12{padding-top:var(--canon-space-12)}.lg\:cu-pt-13{padding-top:var(--canon-space-13)}.lg\:cu-pt-14{padding-top:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-pt{padding-top:var(--pt-xl)}.xl\:cu-pt-0\.5{padding-top:var(--canon-space-0_5)}.xl\:cu-pt-1{padding-top:var(--canon-space-1)}.xl\:cu-pt-1\.5{padding-top:var(--canon-space-1_5)}.xl\:cu-pt-2{padding-top:var(--canon-space-2)}.xl\:cu-pt-3{padding-top:var(--canon-space-3)}.xl\:cu-pt-4{padding-top:var(--canon-space-4)}.xl\:cu-pt-5{padding-top:var(--canon-space-5)}.xl\:cu-pt-6{padding-top:var(--canon-space-6)}.xl\:cu-pt-7{padding-top:var(--canon-space-7)}.xl\:cu-pt-8{padding-top:var(--canon-space-8)}.xl\:cu-pt-9{padding-top:var(--canon-space-9)}.xl\:cu-pt-10{padding-top:var(--canon-space-10)}.xl\:cu-pt-11{padding-top:var(--canon-space-11)}.xl\:cu-pt-12{padding-top:var(--canon-space-12)}.xl\:cu-pt-13{padding-top:var(--canon-space-13)}.xl\:cu-pt-14{padding-top:var(--canon-space-14)}}.cu-pb{padding-bottom:var(--pb)}.cu-pb-0\.5{padding-bottom:var(--canon-space-0_5)}.cu-pb-1{padding-bottom:var(--canon-space-1)}.cu-pb-1\.5{padding-bottom:var(--canon-space-1_5)}.cu-pb-2{padding-bottom:var(--canon-space-2)}.cu-pb-3{padding-bottom:var(--canon-space-3)}.cu-pb-4{padding-bottom:var(--canon-space-4)}.cu-pb-5{padding-bottom:var(--canon-space-5)}.cu-pb-6{padding-bottom:var(--canon-space-6)}.cu-pb-7{padding-bottom:var(--canon-space-7)}.cu-pb-8{padding-bottom:var(--canon-space-8)}.cu-pb-9{padding-bottom:var(--canon-space-9)}.cu-pb-10{padding-bottom:var(--canon-space-10)}.cu-pb-11{padding-bottom:var(--canon-space-11)}.cu-pb-12{padding-bottom:var(--canon-space-12)}.cu-pb-13{padding-bottom:var(--canon-space-13)}.cu-pb-14{padding-bottom:var(--canon-space-14)}@media (width>=640px){.xs\:cu-pb{padding-bottom:var(--pb-xs)}.xs\:cu-pb-0\.5{padding-bottom:var(--canon-space-0_5)}.xs\:cu-pb-1{padding-bottom:var(--canon-space-1)}.xs\:cu-pb-1\.5{padding-bottom:var(--canon-space-1_5)}.xs\:cu-pb-2{padding-bottom:var(--canon-space-2)}.xs\:cu-pb-3{padding-bottom:var(--canon-space-3)}.xs\:cu-pb-4{padding-bottom:var(--canon-space-4)}.xs\:cu-pb-5{padding-bottom:var(--canon-space-5)}.xs\:cu-pb-6{padding-bottom:var(--canon-space-6)}.xs\:cu-pb-7{padding-bottom:var(--canon-space-7)}.xs\:cu-pb-8{padding-bottom:var(--canon-space-8)}.xs\:cu-pb-9{padding-bottom:var(--canon-space-9)}.xs\:cu-pb-10{padding-bottom:var(--canon-space-10)}.xs\:cu-pb-11{padding-bottom:var(--canon-space-11)}.xs\:cu-pb-12{padding-bottom:var(--canon-space-12)}.xs\:cu-pb-13{padding-bottom:var(--canon-space-13)}.xs\:cu-pb-14{padding-bottom:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-pb{padding-bottom:var(--pb-sm)}.sm\:cu-pb-0\.5{padding-bottom:var(--canon-space-0_5)}.sm\:cu-pb-1{padding-bottom:var(--canon-space-1)}.sm\:cu-pb-1\.5{padding-bottom:var(--canon-space-1_5)}.sm\:cu-pb-2{padding-bottom:var(--canon-space-2)}.sm\:cu-pb-3{padding-bottom:var(--canon-space-3)}.sm\:cu-pb-4{padding-bottom:var(--canon-space-4)}.sm\:cu-pb-5{padding-bottom:var(--canon-space-5)}.sm\:cu-pb-6{padding-bottom:var(--canon-space-6)}.sm\:cu-pb-7{padding-bottom:var(--canon-space-7)}.sm\:cu-pb-8{padding-bottom:var(--canon-space-8)}.sm\:cu-pb-9{padding-bottom:var(--canon-space-9)}.sm\:cu-pb-10{padding-bottom:var(--canon-space-10)}.sm\:cu-pb-11{padding-bottom:var(--canon-space-11)}.sm\:cu-pb-12{padding-bottom:var(--canon-space-12)}.sm\:cu-pb-13{padding-bottom:var(--canon-space-13)}.sm\:cu-pb-14{padding-bottom:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-pb{padding-bottom:var(--pb-md)}.md\:cu-pb-0\.5{padding-bottom:var(--canon-space-0_5)}.md\:cu-pb-1{padding-bottom:var(--canon-space-1)}.md\:cu-pb-1\.5{padding-bottom:var(--canon-space-1_5)}.md\:cu-pb-2{padding-bottom:var(--canon-space-2)}.md\:cu-pb-3{padding-bottom:var(--canon-space-3)}.md\:cu-pb-4{padding-bottom:var(--canon-space-4)}.md\:cu-pb-5{padding-bottom:var(--canon-space-5)}.md\:cu-pb-6{padding-bottom:var(--canon-space-6)}.md\:cu-pb-7{padding-bottom:var(--canon-space-7)}.md\:cu-pb-8{padding-bottom:var(--canon-space-8)}.md\:cu-pb-9{padding-bottom:var(--canon-space-9)}.md\:cu-pb-10{padding-bottom:var(--canon-space-10)}.md\:cu-pb-11{padding-bottom:var(--canon-space-11)}.md\:cu-pb-12{padding-bottom:var(--canon-space-12)}.md\:cu-pb-13{padding-bottom:var(--canon-space-13)}.md\:cu-pb-14{padding-bottom:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-pb{padding-bottom:var(--pb-lg)}.lg\:cu-pb-0\.5{padding-bottom:var(--canon-space-0_5)}.lg\:cu-pb-1{padding-bottom:var(--canon-space-1)}.lg\:cu-pb-1\.5{padding-bottom:var(--canon-space-1_5)}.lg\:cu-pb-2{padding-bottom:var(--canon-space-2)}.lg\:cu-pb-3{padding-bottom:var(--canon-space-3)}.lg\:cu-pb-4{padding-bottom:var(--canon-space-4)}.lg\:cu-pb-5{padding-bottom:var(--canon-space-5)}.lg\:cu-pb-6{padding-bottom:var(--canon-space-6)}.lg\:cu-pb-7{padding-bottom:var(--canon-space-7)}.lg\:cu-pb-8{padding-bottom:var(--canon-space-8)}.lg\:cu-pb-9{padding-bottom:var(--canon-space-9)}.lg\:cu-pb-10{padding-bottom:var(--canon-space-10)}.lg\:cu-pb-11{padding-bottom:var(--canon-space-11)}.lg\:cu-pb-12{padding-bottom:var(--canon-space-12)}.lg\:cu-pb-13{padding-bottom:var(--canon-space-13)}.lg\:cu-pb-14{padding-bottom:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-pb{padding-bottom:var(--pb-xl)}.xl\:cu-pb-0\.5{padding-bottom:var(--canon-space-0_5)}.xl\:cu-pb-1{padding-bottom:var(--canon-space-1)}.xl\:cu-pb-1\.5{padding-bottom:var(--canon-space-1_5)}.xl\:cu-pb-2{padding-bottom:var(--canon-space-2)}.xl\:cu-pb-3{padding-bottom:var(--canon-space-3)}.xl\:cu-pb-4{padding-bottom:var(--canon-space-4)}.xl\:cu-pb-5{padding-bottom:var(--canon-space-5)}.xl\:cu-pb-6{padding-bottom:var(--canon-space-6)}.xl\:cu-pb-7{padding-bottom:var(--canon-space-7)}.xl\:cu-pb-8{padding-bottom:var(--canon-space-8)}.xl\:cu-pb-9{padding-bottom:var(--canon-space-9)}.xl\:cu-pb-10{padding-bottom:var(--canon-space-10)}.xl\:cu-pb-11{padding-bottom:var(--canon-space-11)}.xl\:cu-pb-12{padding-bottom:var(--canon-space-12)}.xl\:cu-pb-13{padding-bottom:var(--canon-space-13)}.xl\:cu-pb-14{padding-bottom:var(--canon-space-14)}}.cu-py{padding-top:var(--py);padding-bottom:var(--py)}.cu-py-0\.5{padding-top:var(--canon-space-0_5);padding-bottom:var(--canon-space-0_5)}.cu-py-1{padding-top:var(--canon-space-1);padding-bottom:var(--canon-space-1)}.cu-py-1\.5{padding-top:var(--canon-space-1_5);padding-bottom:var(--canon-space-1_5)}.cu-py-2{padding-top:var(--canon-space-2);padding-bottom:var(--canon-space-2)}.cu-py-3{padding-top:var(--canon-space-3);padding-bottom:var(--canon-space-3)}.cu-py-4{padding-top:var(--canon-space-4);padding-bottom:var(--canon-space-4)}.cu-py-5{padding-top:var(--canon-space-5);padding-bottom:var(--canon-space-5)}.cu-py-6{padding-top:var(--canon-space-6);padding-bottom:var(--canon-space-6)}.cu-py-7{padding-top:var(--canon-space-7);padding-bottom:var(--canon-space-7)}.cu-py-8{padding-top:var(--canon-space-8);padding-bottom:var(--canon-space-8)}.cu-py-9{padding-top:var(--canon-space-9);padding-bottom:var(--canon-space-9)}.cu-py-10{padding-top:var(--canon-space-10);padding-bottom:var(--canon-space-10)}.cu-py-11{padding-top:var(--canon-space-11);padding-bottom:var(--canon-space-11)}.cu-py-12{padding-top:var(--canon-space-12);padding-bottom:var(--canon-space-12)}.cu-py-13{padding-top:var(--canon-space-13);padding-bottom:var(--canon-space-13)}.cu-py-14{padding-top:var(--canon-space-14);padding-bottom:var(--canon-space-14)}@media (width>=640px){.xs\:cu-py{padding-top:var(--py-xs);padding-bottom:var(--py-xs)}.xs\:cu-py-0\.5{padding-top:var(--canon-space-0_5);padding-bottom:var(--canon-space-0_5)}.xs\:cu-py-1{padding-top:var(--canon-space-1);padding-bottom:var(--canon-space-1)}.xs\:cu-py-1\.5{padding-top:var(--canon-space-1_5);padding-bottom:var(--canon-space-1_5)}.xs\:cu-py-2{padding-top:var(--canon-space-2);padding-bottom:var(--canon-space-2)}.xs\:cu-py-3{padding-top:var(--canon-space-3);padding-bottom:var(--canon-space-3)}.xs\:cu-py-4{padding-top:var(--canon-space-4);padding-bottom:var(--canon-space-4)}.xs\:cu-py-5{padding-top:var(--canon-space-5);padding-bottom:var(--canon-space-5)}.xs\:cu-py-6{padding-top:var(--canon-space-6);padding-bottom:var(--canon-space-6)}.xs\:cu-py-7{padding-top:var(--canon-space-7);padding-bottom:var(--canon-space-7)}.xs\:cu-py-8{padding-top:var(--canon-space-8);padding-bottom:var(--canon-space-8)}.xs\:cu-py-9{padding-top:var(--canon-space-9);padding-bottom:var(--canon-space-9)}.xs\:cu-py-10{padding-top:var(--canon-space-10);padding-bottom:var(--canon-space-10)}.xs\:cu-py-11{padding-top:var(--canon-space-11);padding-bottom:var(--canon-space-11)}.xs\:cu-py-12{padding-top:var(--canon-space-12);padding-bottom:var(--canon-space-12)}.xs\:cu-py-13{padding-top:var(--canon-space-13);padding-bottom:var(--canon-space-13)}.xs\:cu-py-14{padding-top:var(--canon-space-14);padding-bottom:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-py{padding-top:var(--py-sm);padding-bottom:var(--py-sm)}.sm\:cu-py-0\.5{padding-top:var(--canon-space-0_5);padding-bottom:var(--canon-space-0_5)}.sm\:cu-py-1{padding-top:var(--canon-space-1);padding-bottom:var(--canon-space-1)}.sm\:cu-py-1\.5{padding-top:var(--canon-space-1_5);padding-bottom:var(--canon-space-1_5)}.sm\:cu-py-2{padding-top:var(--canon-space-2);padding-bottom:var(--canon-space-2)}.sm\:cu-py-3{padding-top:var(--canon-space-3);padding-bottom:var(--canon-space-3)}.sm\:cu-py-4{padding-top:var(--canon-space-4);padding-bottom:var(--canon-space-4)}.sm\:cu-py-5{padding-top:var(--canon-space-5);padding-bottom:var(--canon-space-5)}.sm\:cu-py-6{padding-top:var(--canon-space-6);padding-bottom:var(--canon-space-6)}.sm\:cu-py-7{padding-top:var(--canon-space-7);padding-bottom:var(--canon-space-7)}.sm\:cu-py-8{padding-top:var(--canon-space-8);padding-bottom:var(--canon-space-8)}.sm\:cu-py-9{padding-top:var(--canon-space-9);padding-bottom:var(--canon-space-9)}.sm\:cu-py-10{padding-top:var(--canon-space-10);padding-bottom:var(--canon-space-10)}.sm\:cu-py-11{padding-top:var(--canon-space-11);padding-bottom:var(--canon-space-11)}.sm\:cu-py-12{padding-top:var(--canon-space-12);padding-bottom:var(--canon-space-12)}.sm\:cu-py-13{padding-top:var(--canon-space-13);padding-bottom:var(--canon-space-13)}.sm\:cu-py-14{padding-top:var(--canon-space-14);padding-bottom:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-py{padding-top:var(--py-md);padding-bottom:var(--py-md)}.md\:cu-py-0\.5{padding-top:var(--canon-space-0_5);padding-bottom:var(--canon-space-0_5)}.md\:cu-py-1{padding-top:var(--canon-space-1);padding-bottom:var(--canon-space-1)}.md\:cu-py-1\.5{padding-top:var(--canon-space-1_5);padding-bottom:var(--canon-space-1_5)}.md\:cu-py-2{padding-top:var(--canon-space-2);padding-bottom:var(--canon-space-2)}.md\:cu-py-3{padding-top:var(--canon-space-3);padding-bottom:var(--canon-space-3)}.md\:cu-py-4{padding-top:var(--canon-space-4);padding-bottom:var(--canon-space-4)}.md\:cu-py-5{padding-top:var(--canon-space-5);padding-bottom:var(--canon-space-5)}.md\:cu-py-6{padding-top:var(--canon-space-6);padding-bottom:var(--canon-space-6)}.md\:cu-py-7{padding-top:var(--canon-space-7);padding-bottom:var(--canon-space-7)}.md\:cu-py-8{padding-top:var(--canon-space-8);padding-bottom:var(--canon-space-8)}.md\:cu-py-9{padding-top:var(--canon-space-9);padding-bottom:var(--canon-space-9)}.md\:cu-py-10{padding-top:var(--canon-space-10);padding-bottom:var(--canon-space-10)}.md\:cu-py-11{padding-top:var(--canon-space-11);padding-bottom:var(--canon-space-11)}.md\:cu-py-12{padding-top:var(--canon-space-12);padding-bottom:var(--canon-space-12)}.md\:cu-py-13{padding-top:var(--canon-space-13);padding-bottom:var(--canon-space-13)}.md\:cu-py-14{padding-top:var(--canon-space-14);padding-bottom:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-py{padding-top:var(--py-lg);padding-bottom:var(--py-lg)}.lg\:cu-py-0\.5{padding-top:var(--canon-space-0_5);padding-bottom:var(--canon-space-0_5)}.lg\:cu-py-1{padding-top:var(--canon-space-1);padding-bottom:var(--canon-space-1)}.lg\:cu-py-1\.5{padding-top:var(--canon-space-1_5);padding-bottom:var(--canon-space-1_5)}.lg\:cu-py-2{padding-top:var(--canon-space-2);padding-bottom:var(--canon-space-2)}.lg\:cu-py-3{padding-top:var(--canon-space-3);padding-bottom:var(--canon-space-3)}.lg\:cu-py-4{padding-top:var(--canon-space-4);padding-bottom:var(--canon-space-4)}.lg\:cu-py-5{padding-top:var(--canon-space-5);padding-bottom:var(--canon-space-5)}.lg\:cu-py-6{padding-top:var(--canon-space-6);padding-bottom:var(--canon-space-6)}.lg\:cu-py-7{padding-top:var(--canon-space-7);padding-bottom:var(--canon-space-7)}.lg\:cu-py-8{padding-top:var(--canon-space-8);padding-bottom:var(--canon-space-8)}.lg\:cu-py-9{padding-top:var(--canon-space-9);padding-bottom:var(--canon-space-9)}.lg\:cu-py-10{padding-top:var(--canon-space-10);padding-bottom:var(--canon-space-10)}.lg\:cu-py-11{padding-top:var(--canon-space-11);padding-bottom:var(--canon-space-11)}.lg\:cu-py-12{padding-top:var(--canon-space-12);padding-bottom:var(--canon-space-12)}.lg\:cu-py-13{padding-top:var(--canon-space-13);padding-bottom:var(--canon-space-13)}.lg\:cu-py-14{padding-top:var(--canon-space-14);padding-bottom:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-py{padding-top:var(--py-xl);padding-bottom:var(--py-xl)}.xl\:cu-py-0\.5{padding-top:var(--canon-space-0_5);padding-bottom:var(--canon-space-0_5)}.xl\:cu-py-1{padding-top:var(--canon-space-1);padding-bottom:var(--canon-space-1)}.xl\:cu-py-1\.5{padding-top:var(--canon-space-1_5);padding-bottom:var(--canon-space-1_5)}.xl\:cu-py-2{padding-top:var(--canon-space-2);padding-bottom:var(--canon-space-2)}.xl\:cu-py-3{padding-top:var(--canon-space-3);padding-bottom:var(--canon-space-3)}.xl\:cu-py-4{padding-top:var(--canon-space-4);padding-bottom:var(--canon-space-4)}.xl\:cu-py-5{padding-top:var(--canon-space-5);padding-bottom:var(--canon-space-5)}.xl\:cu-py-6{padding-top:var(--canon-space-6);padding-bottom:var(--canon-space-6)}.xl\:cu-py-7{padding-top:var(--canon-space-7);padding-bottom:var(--canon-space-7)}.xl\:cu-py-8{padding-top:var(--canon-space-8);padding-bottom:var(--canon-space-8)}.xl\:cu-py-9{padding-top:var(--canon-space-9);padding-bottom:var(--canon-space-9)}.xl\:cu-py-10{padding-top:var(--canon-space-10);padding-bottom:var(--canon-space-10)}.xl\:cu-py-11{padding-top:var(--canon-space-11);padding-bottom:var(--canon-space-11)}.xl\:cu-py-12{padding-top:var(--canon-space-12);padding-bottom:var(--canon-space-12)}.xl\:cu-py-13{padding-top:var(--canon-space-13);padding-bottom:var(--canon-space-13)}.xl\:cu-py-14{padding-top:var(--canon-space-14);padding-bottom:var(--canon-space-14)}}.cu-px{padding-left:var(--px);padding-right:var(--px)}.cu-px-0\.5{padding-left:var(--canon-space-0_5);padding-right:var(--canon-space-0_5)}.cu-px-1{padding-left:var(--canon-space-1);padding-right:var(--canon-space-1)}.cu-px-1\.5{padding-left:var(--canon-space-1_5);padding-right:var(--canon-space-1_5)}.cu-px-2{padding-left:var(--canon-space-2);padding-right:var(--canon-space-2)}.cu-px-3{padding-left:var(--canon-space-3);padding-right:var(--canon-space-3)}.cu-px-4{padding-left:var(--canon-space-4);padding-right:var(--canon-space-4)}.cu-px-5{padding-left:var(--canon-space-5);padding-right:var(--canon-space-5)}.cu-px-6{padding-left:var(--canon-space-6);padding-right:var(--canon-space-6)}.cu-px-7{padding-left:var(--canon-space-7);padding-right:var(--canon-space-7)}.cu-px-8{padding-left:var(--canon-space-8);padding-right:var(--canon-space-8)}.cu-px-9{padding-left:var(--canon-space-9);padding-right:var(--canon-space-9)}.cu-px-10{padding-left:var(--canon-space-10);padding-right:var(--canon-space-10)}.cu-px-11{padding-left:var(--canon-space-11);padding-right:var(--canon-space-11)}.cu-px-12{padding-left:var(--canon-space-12);padding-right:var(--canon-space-12)}.cu-px-13{padding-left:var(--canon-space-13);padding-right:var(--canon-space-13)}.cu-px-14{padding-left:var(--canon-space-14);padding-right:var(--canon-space-14)}@media (width>=640px){.xs\:cu-px{padding-left:var(--px-xs);padding-right:var(--px-xs)}.xs\:cu-px-0\.5{padding-left:var(--canon-space-0_5);padding-right:var(--canon-space-0_5)}.xs\:cu-px-1{padding-left:var(--canon-space-1);padding-right:var(--canon-space-1)}.xs\:cu-px-1\.5{padding-left:var(--canon-space-1_5);padding-right:var(--canon-space-1_5)}.xs\:cu-px-2{padding-left:var(--canon-space-2);padding-right:var(--canon-space-2)}.xs\:cu-px-3{padding-left:var(--canon-space-3);padding-right:var(--canon-space-3)}.xs\:cu-px-4{padding-left:var(--canon-space-4);padding-right:var(--canon-space-4)}.xs\:cu-px-5{padding-left:var(--canon-space-5);padding-right:var(--canon-space-5)}.xs\:cu-px-6{padding-left:var(--canon-space-6);padding-right:var(--canon-space-6)}.xs\:cu-px-7{padding-left:var(--canon-space-7);padding-right:var(--canon-space-7)}.xs\:cu-px-8{padding-left:var(--canon-space-8);padding-right:var(--canon-space-8)}.xs\:cu-px-9{padding-left:var(--canon-space-9);padding-right:var(--canon-space-9)}.xs\:cu-px-10{padding-left:var(--canon-space-10);padding-right:var(--canon-space-10)}.xs\:cu-px-11{padding-left:var(--canon-space-11);padding-right:var(--canon-space-11)}.xs\:cu-px-12{padding-left:var(--canon-space-12);padding-right:var(--canon-space-12)}.xs\:cu-px-13{padding-left:var(--canon-space-13);padding-right:var(--canon-space-13)}.xs\:cu-px-14{padding-left:var(--canon-space-14);padding-right:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-px{padding-left:var(--px-sm);padding-right:var(--px-sm)}.sm\:cu-px-0\.5{padding-left:var(--canon-space-0_5);padding-right:var(--canon-space-0_5)}.sm\:cu-px-1{padding-left:var(--canon-space-1);padding-right:var(--canon-space-1)}.sm\:cu-px-1\.5{padding-left:var(--canon-space-1_5);padding-right:var(--canon-space-1_5)}.sm\:cu-px-2{padding-left:var(--canon-space-2);padding-right:var(--canon-space-2)}.sm\:cu-px-3{padding-left:var(--canon-space-3);padding-right:var(--canon-space-3)}.sm\:cu-px-4{padding-left:var(--canon-space-4);padding-right:var(--canon-space-4)}.sm\:cu-px-5{padding-left:var(--canon-space-5);padding-right:var(--canon-space-5)}.sm\:cu-px-6{padding-left:var(--canon-space-6);padding-right:var(--canon-space-6)}.sm\:cu-px-7{padding-left:var(--canon-space-7);padding-right:var(--canon-space-7)}.sm\:cu-px-8{padding-left:var(--canon-space-8);padding-right:var(--canon-space-8)}.sm\:cu-px-9{padding-left:var(--canon-space-9);padding-right:var(--canon-space-9)}.sm\:cu-px-10{padding-left:var(--canon-space-10);padding-right:var(--canon-space-10)}.sm\:cu-px-11{padding-left:var(--canon-space-11);padding-right:var(--canon-space-11)}.sm\:cu-px-12{padding-left:var(--canon-space-12);padding-right:var(--canon-space-12)}.sm\:cu-px-13{padding-left:var(--canon-space-13);padding-right:var(--canon-space-13)}.sm\:cu-px-14{padding-left:var(--canon-space-14);padding-right:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-px{padding-left:var(--px-md);padding-right:var(--px-md)}.md\:cu-px-0\.5{padding-left:var(--canon-space-0_5);padding-right:var(--canon-space-0_5)}.md\:cu-px-1{padding-left:var(--canon-space-1);padding-right:var(--canon-space-1)}.md\:cu-px-1\.5{padding-left:var(--canon-space-1_5);padding-right:var(--canon-space-1_5)}.md\:cu-px-2{padding-left:var(--canon-space-2);padding-right:var(--canon-space-2)}.md\:cu-px-3{padding-left:var(--canon-space-3);padding-right:var(--canon-space-3)}.md\:cu-px-4{padding-left:var(--canon-space-4);padding-right:var(--canon-space-4)}.md\:cu-px-5{padding-left:var(--canon-space-5);padding-right:var(--canon-space-5)}.md\:cu-px-6{padding-left:var(--canon-space-6);padding-right:var(--canon-space-6)}.md\:cu-px-7{padding-left:var(--canon-space-7);padding-right:var(--canon-space-7)}.md\:cu-px-8{padding-left:var(--canon-space-8);padding-right:var(--canon-space-8)}.md\:cu-px-9{padding-left:var(--canon-space-9);padding-right:var(--canon-space-9)}.md\:cu-px-10{padding-left:var(--canon-space-10);padding-right:var(--canon-space-10)}.md\:cu-px-11{padding-left:var(--canon-space-11);padding-right:var(--canon-space-11)}.md\:cu-px-12{padding-left:var(--canon-space-12);padding-right:var(--canon-space-12)}.md\:cu-px-13{padding-left:var(--canon-space-13);padding-right:var(--canon-space-13)}.md\:cu-px-14{padding-left:var(--canon-space-14);padding-right:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-px{padding-left:var(--px-lg);padding-right:var(--px-lg)}.lg\:cu-px-0\.5{padding-left:var(--canon-space-0_5);padding-right:var(--canon-space-0_5)}.lg\:cu-px-1{padding-left:var(--canon-space-1);padding-right:var(--canon-space-1)}.lg\:cu-px-1\.5{padding-left:var(--canon-space-1_5);padding-right:var(--canon-space-1_5)}.lg\:cu-px-2{padding-left:var(--canon-space-2);padding-right:var(--canon-space-2)}.lg\:cu-px-3{padding-left:var(--canon-space-3);padding-right:var(--canon-space-3)}.lg\:cu-px-4{padding-left:var(--canon-space-4);padding-right:var(--canon-space-4)}.lg\:cu-px-5{padding-left:var(--canon-space-5);padding-right:var(--canon-space-5)}.lg\:cu-px-6{padding-left:var(--canon-space-6);padding-right:var(--canon-space-6)}.lg\:cu-px-7{padding-left:var(--canon-space-7);padding-right:var(--canon-space-7)}.lg\:cu-px-8{padding-left:var(--canon-space-8);padding-right:var(--canon-space-8)}.lg\:cu-px-9{padding-left:var(--canon-space-9);padding-right:var(--canon-space-9)}.lg\:cu-px-10{padding-left:var(--canon-space-10);padding-right:var(--canon-space-10)}.lg\:cu-px-11{padding-left:var(--canon-space-11);padding-right:var(--canon-space-11)}.lg\:cu-px-12{padding-left:var(--canon-space-12);padding-right:var(--canon-space-12)}.lg\:cu-px-13{padding-left:var(--canon-space-13);padding-right:var(--canon-space-13)}.lg\:cu-px-14{padding-left:var(--canon-space-14);padding-right:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-px{padding-left:var(--px-xl);padding-right:var(--px-xl)}.xl\:cu-px-0\.5{padding-left:var(--canon-space-0_5);padding-right:var(--canon-space-0_5)}.xl\:cu-px-1{padding-left:var(--canon-space-1);padding-right:var(--canon-space-1)}.xl\:cu-px-1\.5{padding-left:var(--canon-space-1_5);padding-right:var(--canon-space-1_5)}.xl\:cu-px-2{padding-left:var(--canon-space-2);padding-right:var(--canon-space-2)}.xl\:cu-px-3{padding-left:var(--canon-space-3);padding-right:var(--canon-space-3)}.xl\:cu-px-4{padding-left:var(--canon-space-4);padding-right:var(--canon-space-4)}.xl\:cu-px-5{padding-left:var(--canon-space-5);padding-right:var(--canon-space-5)}.xl\:cu-px-6{padding-left:var(--canon-space-6);padding-right:var(--canon-space-6)}.xl\:cu-px-7{padding-left:var(--canon-space-7);padding-right:var(--canon-space-7)}.xl\:cu-px-8{padding-left:var(--canon-space-8);padding-right:var(--canon-space-8)}.xl\:cu-px-9{padding-left:var(--canon-space-9);padding-right:var(--canon-space-9)}.xl\:cu-px-10{padding-left:var(--canon-space-10);padding-right:var(--canon-space-10)}.xl\:cu-px-11{padding-left:var(--canon-space-11);padding-right:var(--canon-space-11)}.xl\:cu-px-12{padding-left:var(--canon-space-12);padding-right:var(--canon-space-12)}.xl\:cu-px-13{padding-left:var(--canon-space-13);padding-right:var(--canon-space-13)}.xl\:cu-px-14{padding-left:var(--canon-space-14);padding-right:var(--canon-space-14)}}.cu-m{margin:var(--m)}.cu-m-0\.5{margin:var(--canon-space-0_5)}.cu-m-1{margin:var(--canon-space-1)}.cu-m-1\.5{margin:var(--canon-space-1_5)}.cu-m-2{margin:var(--canon-space-2)}.cu-m-3{margin:var(--canon-space-3)}.cu-m-4{margin:var(--canon-space-4)}.cu-m-5{margin:var(--canon-space-5)}.cu-m-6{margin:var(--canon-space-6)}.cu-m-7{margin:var(--canon-space-7)}.cu-m-8{margin:var(--canon-space-8)}.cu-m-9{margin:var(--canon-space-9)}.cu-m-10{margin:var(--canon-space-10)}.cu-m-11{margin:var(--canon-space-11)}.cu-m-12{margin:var(--canon-space-12)}.cu-m-13{margin:var(--canon-space-13)}.cu-m-14{margin:var(--canon-space-14)}@media (width>=640px){.xs\:cu-m{margin:var(--p-xs)}.xs\:cu-m-0\.5{margin:var(--canon-space-0_5)}.xs\:cu-m-1{margin:var(--canon-space-1)}.xs\:cu-m-1\.5{margin:var(--canon-space-1_5)}.xs\:cu-m-2{margin:var(--canon-space-2)}.xs\:cu-m-3{margin:var(--canon-space-3)}.xs\:cu-m-4{margin:var(--canon-space-4)}.xs\:cu-m-5{margin:var(--canon-space-5)}.xs\:cu-m-6{margin:var(--canon-space-6)}.xs\:cu-m-7{margin:var(--canon-space-7)}.xs\:cu-m-8{margin:var(--canon-space-8)}.xs\:cu-m-9{margin:var(--canon-space-9)}.xs\:cu-m-10{margin:var(--canon-space-10)}.xs\:cu-m-11{margin:var(--canon-space-11)}.xs\:cu-m-12{margin:var(--canon-space-12)}.xs\:cu-m-13{margin:var(--canon-space-13)}.xs\:cu-m-14{margin:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-m{margin:var(--p-sm)}.sm\:cu-m-0\.5{margin:var(--canon-space-0_5)}.sm\:cu-m-1{margin:var(--canon-space-1)}.sm\:cu-m-1\.5{margin:var(--canon-space-1_5)}.sm\:cu-m-2{margin:var(--canon-space-2)}.sm\:cu-m-3{margin:var(--canon-space-3)}.sm\:cu-m-4{margin:var(--canon-space-4)}.sm\:cu-m-5{margin:var(--canon-space-5)}.sm\:cu-m-6{margin:var(--canon-space-6)}.sm\:cu-m-7{margin:var(--canon-space-7)}.sm\:cu-m-8{margin:var(--canon-space-8)}.sm\:cu-m-9{margin:var(--canon-space-9)}.sm\:cu-m-10{margin:var(--canon-space-10)}.sm\:cu-m-11{margin:var(--canon-space-11)}.sm\:cu-m-12{margin:var(--canon-space-12)}.sm\:cu-m-13{margin:var(--canon-space-13)}.sm\:cu-m-14{margin:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-m{margin:var(--p-md)}.md\:cu-m-0\.5{margin:var(--canon-space-0_5)}.md\:cu-m-1{margin:var(--canon-space-1)}.md\:cu-m-1\.5{margin:var(--canon-space-1_5)}.md\:cu-m-2{margin:var(--canon-space-2)}.md\:cu-m-3{margin:var(--canon-space-3)}.md\:cu-m-4{margin:var(--canon-space-4)}.md\:cu-m-5{margin:var(--canon-space-5)}.md\:cu-m-6{margin:var(--canon-space-6)}.md\:cu-m-7{margin:var(--canon-space-7)}.md\:cu-m-8{margin:var(--canon-space-8)}.md\:cu-m-9{margin:var(--canon-space-9)}.md\:cu-m-10{margin:var(--canon-space-10)}.md\:cu-m-11{margin:var(--canon-space-11)}.md\:cu-m-12{margin:var(--canon-space-12)}.md\:cu-m-13{margin:var(--canon-space-13)}.md\:cu-m-14{margin:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-m{margin:var(--p-lg)}.lg\:cu-m-0\.5{margin:var(--canon-space-0_5)}.lg\:cu-m-1{margin:var(--canon-space-1)}.lg\:cu-m-1\.5{margin:var(--canon-space-1_5)}.lg\:cu-m-2{margin:var(--canon-space-2)}.lg\:cu-m-3{margin:var(--canon-space-3)}.lg\:cu-m-4{margin:var(--canon-space-4)}.lg\:cu-m-5{margin:var(--canon-space-5)}.lg\:cu-m-6{margin:var(--canon-space-6)}.lg\:cu-m-7{margin:var(--canon-space-7)}.lg\:cu-m-8{margin:var(--canon-space-8)}.lg\:cu-m-9{margin:var(--canon-space-9)}.lg\:cu-m-10{margin:var(--canon-space-10)}.lg\:cu-m-11{margin:var(--canon-space-11)}.lg\:cu-m-12{margin:var(--canon-space-12)}.lg\:cu-m-13{margin:var(--canon-space-13)}.lg\:cu-m-14{margin:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-m{margin:var(--p-xl)}.xl\:cu-m-0\.5{margin:var(--canon-space-0_5)}.xl\:cu-m-1{margin:var(--canon-space-1)}.xl\:cu-m-1\.5{margin:var(--canon-space-1_5)}.xl\:cu-m-2{margin:var(--canon-space-2)}.xl\:cu-m-3{margin:var(--canon-space-3)}.xl\:cu-m-4{margin:var(--canon-space-4)}.xl\:cu-m-5{margin:var(--canon-space-5)}.xl\:cu-m-6{margin:var(--canon-space-6)}.xl\:cu-m-7{margin:var(--canon-space-7)}.xl\:cu-m-8{margin:var(--canon-space-8)}.xl\:cu-m-9{margin:var(--canon-space-9)}.xl\:cu-m-10{margin:var(--canon-space-10)}.xl\:cu-m-11{margin:var(--canon-space-11)}.xl\:cu-m-12{margin:var(--canon-space-12)}.xl\:cu-m-13{margin:var(--canon-space-13)}.xl\:cu-m-14{margin:var(--canon-space-14)}}.cu-ml{margin-left:var(--ml)}.cu-ml-0\.5{margin-left:var(--canon-space-0_5)}.cu-ml-1{margin-left:var(--canon-space-1)}.cu-ml-1\.5{margin-left:var(--canon-space-1_5)}.cu-ml-2{margin-left:var(--canon-space-2)}.cu-ml-3{margin-left:var(--canon-space-3)}.cu-ml-4{margin-left:var(--canon-space-4)}.cu-ml-5{margin-left:var(--canon-space-5)}.cu-ml-6{margin-left:var(--canon-space-6)}.cu-ml-7{margin-left:var(--canon-space-7)}.cu-ml-8{margin-left:var(--canon-space-8)}.cu-ml-9{margin-left:var(--canon-space-9)}.cu-ml-10{margin-left:var(--canon-space-10)}.cu-ml-11{margin-left:var(--canon-space-11)}.cu-ml-12{margin-left:var(--canon-space-12)}.cu-ml-13{margin-left:var(--canon-space-13)}.cu-ml-14{margin-left:var(--canon-space-14)}@media (width>=640px){.xs\:cu-ml{margin-left:var(--pl-xs)}.xs\:cu-ml-0\.5{margin-left:var(--canon-space-0_5)}.xs\:cu-ml-1{margin-left:var(--canon-space-1)}.xs\:cu-ml-1\.5{margin-left:var(--canon-space-1_5)}.xs\:cu-ml-2{margin-left:var(--canon-space-2)}.xs\:cu-ml-3{margin-left:var(--canon-space-3)}.xs\:cu-ml-4{margin-left:var(--canon-space-4)}.xs\:cu-ml-5{margin-left:var(--canon-space-5)}.xs\:cu-ml-6{margin-left:var(--canon-space-6)}.xs\:cu-ml-7{margin-left:var(--canon-space-7)}.xs\:cu-ml-8{margin-left:var(--canon-space-8)}.xs\:cu-ml-9{margin-left:var(--canon-space-9)}.xs\:cu-ml-10{margin-left:var(--canon-space-10)}.xs\:cu-ml-11{margin-left:var(--canon-space-11)}.xs\:cu-ml-12{margin-left:var(--canon-space-12)}.xs\:cu-ml-13{margin-left:var(--canon-space-13)}.xs\:cu-ml-14{margin-left:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-ml{margin-left:var(--pl-sm)}.sm\:cu-ml-0\.5{margin-left:var(--canon-space-0_5)}.sm\:cu-ml-1{margin-left:var(--canon-space-1)}.sm\:cu-ml-1\.5{margin-left:var(--canon-space-1_5)}.sm\:cu-ml-2{margin-left:var(--canon-space-2)}.sm\:cu-ml-3{margin-left:var(--canon-space-3)}.sm\:cu-ml-4{margin-left:var(--canon-space-4)}.sm\:cu-ml-5{margin-left:var(--canon-space-5)}.sm\:cu-ml-6{margin-left:var(--canon-space-6)}.sm\:cu-ml-7{margin-left:var(--canon-space-7)}.sm\:cu-ml-8{margin-left:var(--canon-space-8)}.sm\:cu-ml-9{margin-left:var(--canon-space-9)}.sm\:cu-ml-10{margin-left:var(--canon-space-10)}.sm\:cu-ml-11{margin-left:var(--canon-space-11)}.sm\:cu-ml-12{margin-left:var(--canon-space-12)}.sm\:cu-ml-13{margin-left:var(--canon-space-13)}.sm\:cu-ml-14{margin-left:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-ml{margin-left:var(--pl-md)}.md\:cu-ml-0\.5{margin-left:var(--canon-space-0_5)}.md\:cu-ml-1{margin-left:var(--canon-space-1)}.md\:cu-ml-1\.5{margin-left:var(--canon-space-1_5)}.md\:cu-ml-2{margin-left:var(--canon-space-2)}.md\:cu-ml-3{margin-left:var(--canon-space-3)}.md\:cu-ml-4{margin-left:var(--canon-space-4)}.md\:cu-ml-5{margin-left:var(--canon-space-5)}.md\:cu-ml-6{margin-left:var(--canon-space-6)}.md\:cu-ml-7{margin-left:var(--canon-space-7)}.md\:cu-ml-8{margin-left:var(--canon-space-8)}.md\:cu-ml-9{margin-left:var(--canon-space-9)}.md\:cu-ml-10{margin-left:var(--canon-space-10)}.md\:cu-ml-11{margin-left:var(--canon-space-11)}.md\:cu-ml-12{margin-left:var(--canon-space-12)}.md\:cu-ml-13{margin-left:var(--canon-space-13)}.md\:cu-ml-14{margin-left:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-ml{margin-left:var(--pl-lg)}.lg\:cu-ml-0\.5{margin-left:var(--canon-space-0_5)}.lg\:cu-ml-1{margin-left:var(--canon-space-1)}.lg\:cu-ml-1\.5{margin-left:var(--canon-space-1_5)}.lg\:cu-ml-2{margin-left:var(--canon-space-2)}.lg\:cu-ml-3{margin-left:var(--canon-space-3)}.lg\:cu-ml-4{margin-left:var(--canon-space-4)}.lg\:cu-ml-5{margin-left:var(--canon-space-5)}.lg\:cu-ml-6{margin-left:var(--canon-space-6)}.lg\:cu-ml-7{margin-left:var(--canon-space-7)}.lg\:cu-ml-8{margin-left:var(--canon-space-8)}.lg\:cu-ml-9{margin-left:var(--canon-space-9)}.lg\:cu-ml-10{margin-left:var(--canon-space-10)}.lg\:cu-ml-11{margin-left:var(--canon-space-11)}.lg\:cu-ml-12{margin-left:var(--canon-space-12)}.lg\:cu-ml-13{margin-left:var(--canon-space-13)}.lg\:cu-ml-14{margin-left:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-ml{margin-left:var(--pl-xl)}.xl\:cu-ml-0\.5{margin-left:var(--canon-space-0_5)}.xl\:cu-ml-1{margin-left:var(--canon-space-1)}.xl\:cu-ml-1\.5{margin-left:var(--canon-space-1_5)}.xl\:cu-ml-2{margin-left:var(--canon-space-2)}.xl\:cu-ml-3{margin-left:var(--canon-space-3)}.xl\:cu-ml-4{margin-left:var(--canon-space-4)}.xl\:cu-ml-5{margin-left:var(--canon-space-5)}.xl\:cu-ml-6{margin-left:var(--canon-space-6)}.xl\:cu-ml-7{margin-left:var(--canon-space-7)}.xl\:cu-ml-8{margin-left:var(--canon-space-8)}.xl\:cu-ml-9{margin-left:var(--canon-space-9)}.xl\:cu-ml-10{margin-left:var(--canon-space-10)}.xl\:cu-ml-11{margin-left:var(--canon-space-11)}.xl\:cu-ml-12{margin-left:var(--canon-space-12)}.xl\:cu-ml-13{margin-left:var(--canon-space-13)}.xl\:cu-ml-14{margin-left:var(--canon-space-14)}}.cu-mr{margin-right:var(--mr)}.cu-mr-0\.5{margin-right:var(--canon-space-0_5)}.cu-mr-1{margin-right:var(--canon-space-1)}.cu-mr-1\.5{margin-right:var(--canon-space-1_5)}.cu-mr-2{margin-right:var(--canon-space-2)}.cu-mr-3{margin-right:var(--canon-space-3)}.cu-mr-4{margin-right:var(--canon-space-4)}.cu-mr-5{margin-right:var(--canon-space-5)}.cu-mr-6{margin-right:var(--canon-space-6)}.cu-mr-7{margin-right:var(--canon-space-7)}.cu-mr-8{margin-right:var(--canon-space-8)}.cu-mr-9{margin-right:var(--canon-space-9)}.cu-mr-10{margin-right:var(--canon-space-10)}.cu-mr-11{margin-right:var(--canon-space-11)}.cu-mr-12{margin-right:var(--canon-space-12)}.cu-mr-13{margin-right:var(--canon-space-13)}.cu-mr-14{margin-right:var(--canon-space-14)}@media (width>=640px){.xs\:cu-mr{margin-right:var(--pr-xs)}.xs\:cu-mr-0\.5{margin-right:var(--canon-space-0_5)}.xs\:cu-mr-1{margin-right:var(--canon-space-1)}.xs\:cu-mr-1\.5{margin-right:var(--canon-space-1_5)}.xs\:cu-mr-2{margin-right:var(--canon-space-2)}.xs\:cu-mr-3{margin-right:var(--canon-space-3)}.xs\:cu-mr-4{margin-right:var(--canon-space-4)}.xs\:cu-mr-5{margin-right:var(--canon-space-5)}.xs\:cu-mr-6{margin-right:var(--canon-space-6)}.xs\:cu-mr-7{margin-right:var(--canon-space-7)}.xs\:cu-mr-8{margin-right:var(--canon-space-8)}.xs\:cu-mr-9{margin-right:var(--canon-space-9)}.xs\:cu-mr-10{margin-right:var(--canon-space-10)}.xs\:cu-mr-11{margin-right:var(--canon-space-11)}.xs\:cu-mr-12{margin-right:var(--canon-space-12)}.xs\:cu-mr-13{margin-right:var(--canon-space-13)}.xs\:cu-mr-14{margin-right:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-mr{margin-right:var(--pr-sm)}.sm\:cu-mr-0\.5{margin-right:var(--canon-space-0_5)}.sm\:cu-mr-1{margin-right:var(--canon-space-1)}.sm\:cu-mr-1\.5{margin-right:var(--canon-space-1_5)}.sm\:cu-mr-2{margin-right:var(--canon-space-2)}.sm\:cu-mr-3{margin-right:var(--canon-space-3)}.sm\:cu-mr-4{margin-right:var(--canon-space-4)}.sm\:cu-mr-5{margin-right:var(--canon-space-5)}.sm\:cu-mr-6{margin-right:var(--canon-space-6)}.sm\:cu-mr-7{margin-right:var(--canon-space-7)}.sm\:cu-mr-8{margin-right:var(--canon-space-8)}.sm\:cu-mr-9{margin-right:var(--canon-space-9)}.sm\:cu-mr-10{margin-right:var(--canon-space-10)}.sm\:cu-mr-11{margin-right:var(--canon-space-11)}.sm\:cu-mr-12{margin-right:var(--canon-space-12)}.sm\:cu-mr-13{margin-right:var(--canon-space-13)}.sm\:cu-mr-14{margin-right:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-mr{margin-right:var(--pr-md)}.md\:cu-mr-0\.5{margin-right:var(--canon-space-0_5)}.md\:cu-mr-1{margin-right:var(--canon-space-1)}.md\:cu-mr-1\.5{margin-right:var(--canon-space-1_5)}.md\:cu-mr-2{margin-right:var(--canon-space-2)}.md\:cu-mr-3{margin-right:var(--canon-space-3)}.md\:cu-mr-4{margin-right:var(--canon-space-4)}.md\:cu-mr-5{margin-right:var(--canon-space-5)}.md\:cu-mr-6{margin-right:var(--canon-space-6)}.md\:cu-mr-7{margin-right:var(--canon-space-7)}.md\:cu-mr-8{margin-right:var(--canon-space-8)}.md\:cu-mr-9{margin-right:var(--canon-space-9)}.md\:cu-mr-10{margin-right:var(--canon-space-10)}.md\:cu-mr-11{margin-right:var(--canon-space-11)}.md\:cu-mr-12{margin-right:var(--canon-space-12)}.md\:cu-mr-13{margin-right:var(--canon-space-13)}.md\:cu-mr-14{margin-right:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-mr{margin-right:var(--pr-lg)}.lg\:cu-mr-0\.5{margin-right:var(--canon-space-0_5)}.lg\:cu-mr-1{margin-right:var(--canon-space-1)}.lg\:cu-mr-1\.5{margin-right:var(--canon-space-1_5)}.lg\:cu-mr-2{margin-right:var(--canon-space-2)}.lg\:cu-mr-3{margin-right:var(--canon-space-3)}.lg\:cu-mr-4{margin-right:var(--canon-space-4)}.lg\:cu-mr-5{margin-right:var(--canon-space-5)}.lg\:cu-mr-6{margin-right:var(--canon-space-6)}.lg\:cu-mr-7{margin-right:var(--canon-space-7)}.lg\:cu-mr-8{margin-right:var(--canon-space-8)}.lg\:cu-mr-9{margin-right:var(--canon-space-9)}.lg\:cu-mr-10{margin-right:var(--canon-space-10)}.lg\:cu-mr-11{margin-right:var(--canon-space-11)}.lg\:cu-mr-12{margin-right:var(--canon-space-12)}.lg\:cu-mr-13{margin-right:var(--canon-space-13)}.lg\:cu-mr-14{margin-right:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-mr{margin-right:var(--pr-xl)}.xl\:cu-mr-0\.5{margin-right:var(--canon-space-0_5)}.xl\:cu-mr-1{margin-right:var(--canon-space-1)}.xl\:cu-mr-1\.5{margin-right:var(--canon-space-1_5)}.xl\:cu-mr-2{margin-right:var(--canon-space-2)}.xl\:cu-mr-3{margin-right:var(--canon-space-3)}.xl\:cu-mr-4{margin-right:var(--canon-space-4)}.xl\:cu-mr-5{margin-right:var(--canon-space-5)}.xl\:cu-mr-6{margin-right:var(--canon-space-6)}.xl\:cu-mr-7{margin-right:var(--canon-space-7)}.xl\:cu-mr-8{margin-right:var(--canon-space-8)}.xl\:cu-mr-9{margin-right:var(--canon-space-9)}.xl\:cu-mr-10{margin-right:var(--canon-space-10)}.xl\:cu-mr-11{margin-right:var(--canon-space-11)}.xl\:cu-mr-12{margin-right:var(--canon-space-12)}.xl\:cu-mr-13{margin-right:var(--canon-space-13)}.xl\:cu-mr-14{margin-right:var(--canon-space-14)}}.cu-mt{margin-top:var(--mt)}.cu-mt-0\.5{margin-top:var(--canon-space-0_5)}.cu-mt-1{margin-top:var(--canon-space-1)}.cu-mt-1\.5{margin-top:var(--canon-space-1_5)}.cu-mt-2{margin-top:var(--canon-space-2)}.cu-mt-3{margin-top:var(--canon-space-3)}.cu-mt-4{margin-top:var(--canon-space-4)}.cu-mt-5{margin-top:var(--canon-space-5)}.cu-mt-6{margin-top:var(--canon-space-6)}.cu-mt-7{margin-top:var(--canon-space-7)}.cu-mt-8{margin-top:var(--canon-space-8)}.cu-mt-9{margin-top:var(--canon-space-9)}.cu-mt-10{margin-top:var(--canon-space-10)}.cu-mt-11{margin-top:var(--canon-space-11)}.cu-mt-12{margin-top:var(--canon-space-12)}.cu-mt-13{margin-top:var(--canon-space-13)}.cu-mt-14{margin-top:var(--canon-space-14)}@media (width>=640px){.xs\:cu-mt{margin-top:var(--pt-xs)}.xs\:cu-mt-0\.5{margin-top:var(--canon-space-0_5)}.xs\:cu-mt-1{margin-top:var(--canon-space-1)}.xs\:cu-mt-1\.5{margin-top:var(--canon-space-1_5)}.xs\:cu-mt-2{margin-top:var(--canon-space-2)}.xs\:cu-mt-3{margin-top:var(--canon-space-3)}.xs\:cu-mt-4{margin-top:var(--canon-space-4)}.xs\:cu-mt-5{margin-top:var(--canon-space-5)}.xs\:cu-mt-6{margin-top:var(--canon-space-6)}.xs\:cu-mt-7{margin-top:var(--canon-space-7)}.xs\:cu-mt-8{margin-top:var(--canon-space-8)}.xs\:cu-mt-9{margin-top:var(--canon-space-9)}.xs\:cu-mt-10{margin-top:var(--canon-space-10)}.xs\:cu-mt-11{margin-top:var(--canon-space-11)}.xs\:cu-mt-12{margin-top:var(--canon-space-12)}.xs\:cu-mt-13{margin-top:var(--canon-space-13)}.xs\:cu-mt-14{margin-top:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-mt{margin-top:var(--pt-sm)}.sm\:cu-mt-0\.5{margin-top:var(--canon-space-0_5)}.sm\:cu-mt-1{margin-top:var(--canon-space-1)}.sm\:cu-mt-1\.5{margin-top:var(--canon-space-1_5)}.sm\:cu-mt-2{margin-top:var(--canon-space-2)}.sm\:cu-mt-3{margin-top:var(--canon-space-3)}.sm\:cu-mt-4{margin-top:var(--canon-space-4)}.sm\:cu-mt-5{margin-top:var(--canon-space-5)}.sm\:cu-mt-6{margin-top:var(--canon-space-6)}.sm\:cu-mt-7{margin-top:var(--canon-space-7)}.sm\:cu-mt-8{margin-top:var(--canon-space-8)}.sm\:cu-mt-9{margin-top:var(--canon-space-9)}.sm\:cu-mt-10{margin-top:var(--canon-space-10)}.sm\:cu-mt-11{margin-top:var(--canon-space-11)}.sm\:cu-mt-12{margin-top:var(--canon-space-12)}.sm\:cu-mt-13{margin-top:var(--canon-space-13)}.sm\:cu-mt-14{margin-top:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-mt{margin-top:var(--pt-md)}.md\:cu-mt-0\.5{margin-top:var(--canon-space-0_5)}.md\:cu-mt-1{margin-top:var(--canon-space-1)}.md\:cu-mt-1\.5{margin-top:var(--canon-space-1_5)}.md\:cu-mt-2{margin-top:var(--canon-space-2)}.md\:cu-mt-3{margin-top:var(--canon-space-3)}.md\:cu-mt-4{margin-top:var(--canon-space-4)}.md\:cu-mt-5{margin-top:var(--canon-space-5)}.md\:cu-mt-6{margin-top:var(--canon-space-6)}.md\:cu-mt-7{margin-top:var(--canon-space-7)}.md\:cu-mt-8{margin-top:var(--canon-space-8)}.md\:cu-mt-9{margin-top:var(--canon-space-9)}.md\:cu-mt-10{margin-top:var(--canon-space-10)}.md\:cu-mt-11{margin-top:var(--canon-space-11)}.md\:cu-mt-12{margin-top:var(--canon-space-12)}.md\:cu-mt-13{margin-top:var(--canon-space-13)}.md\:cu-mt-14{margin-top:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-mt{margin-top:var(--pt-lg)}.lg\:cu-mt-0\.5{margin-top:var(--canon-space-0_5)}.lg\:cu-mt-1{margin-top:var(--canon-space-1)}.lg\:cu-mt-1\.5{margin-top:var(--canon-space-1_5)}.lg\:cu-mt-2{margin-top:var(--canon-space-2)}.lg\:cu-mt-3{margin-top:var(--canon-space-3)}.lg\:cu-mt-4{margin-top:var(--canon-space-4)}.lg\:cu-mt-5{margin-top:var(--canon-space-5)}.lg\:cu-mt-6{margin-top:var(--canon-space-6)}.lg\:cu-mt-7{margin-top:var(--canon-space-7)}.lg\:cu-mt-8{margin-top:var(--canon-space-8)}.lg\:cu-mt-9{margin-top:var(--canon-space-9)}.lg\:cu-mt-10{margin-top:var(--canon-space-10)}.lg\:cu-mt-11{margin-top:var(--canon-space-11)}.lg\:cu-mt-12{margin-top:var(--canon-space-12)}.lg\:cu-mt-13{margin-top:var(--canon-space-13)}.lg\:cu-mt-14{margin-top:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-mt{margin-top:var(--pt-xl)}.xl\:cu-mt-0\.5{margin-top:var(--canon-space-0_5)}.xl\:cu-mt-1{margin-top:var(--canon-space-1)}.xl\:cu-mt-1\.5{margin-top:var(--canon-space-1_5)}.xl\:cu-mt-2{margin-top:var(--canon-space-2)}.xl\:cu-mt-3{margin-top:var(--canon-space-3)}.xl\:cu-mt-4{margin-top:var(--canon-space-4)}.xl\:cu-mt-5{margin-top:var(--canon-space-5)}.xl\:cu-mt-6{margin-top:var(--canon-space-6)}.xl\:cu-mt-7{margin-top:var(--canon-space-7)}.xl\:cu-mt-8{margin-top:var(--canon-space-8)}.xl\:cu-mt-9{margin-top:var(--canon-space-9)}.xl\:cu-mt-10{margin-top:var(--canon-space-10)}.xl\:cu-mt-11{margin-top:var(--canon-space-11)}.xl\:cu-mt-12{margin-top:var(--canon-space-12)}.xl\:cu-mt-13{margin-top:var(--canon-space-13)}.xl\:cu-mt-14{margin-top:var(--canon-space-14)}}.cu-mb{margin-bottom:var(--mb)}.cu-mb-0\.5{margin-bottom:var(--canon-space-0_5)}.cu-mb-1{margin-bottom:var(--canon-space-1)}.cu-mb-1\.5{margin-bottom:var(--canon-space-1_5)}.cu-mb-2{margin-bottom:var(--canon-space-2)}.cu-mb-3{margin-bottom:var(--canon-space-3)}.cu-mb-4{margin-bottom:var(--canon-space-4)}.cu-mb-5{margin-bottom:var(--canon-space-5)}.cu-mb-6{margin-bottom:var(--canon-space-6)}.cu-mb-7{margin-bottom:var(--canon-space-7)}.cu-mb-8{margin-bottom:var(--canon-space-8)}.cu-mb-9{margin-bottom:var(--canon-space-9)}.cu-mb-10{margin-bottom:var(--canon-space-10)}.cu-mb-11{margin-bottom:var(--canon-space-11)}.cu-mb-12{margin-bottom:var(--canon-space-12)}.cu-mb-13{margin-bottom:var(--canon-space-13)}.cu-mb-14{margin-bottom:var(--canon-space-14)}@media (width>=640px){.xs\:cu-mb{margin-bottom:var(--pb-xs)}.xs\:cu-mb-0\.5{margin-bottom:var(--canon-space-0_5)}.xs\:cu-mb-1{margin-bottom:var(--canon-space-1)}.xs\:cu-mb-1\.5{margin-bottom:var(--canon-space-1_5)}.xs\:cu-mb-2{margin-bottom:var(--canon-space-2)}.xs\:cu-mb-3{margin-bottom:var(--canon-space-3)}.xs\:cu-mb-4{margin-bottom:var(--canon-space-4)}.xs\:cu-mb-5{margin-bottom:var(--canon-space-5)}.xs\:cu-mb-6{margin-bottom:var(--canon-space-6)}.xs\:cu-mb-7{margin-bottom:var(--canon-space-7)}.xs\:cu-mb-8{margin-bottom:var(--canon-space-8)}.xs\:cu-mb-9{margin-bottom:var(--canon-space-9)}.xs\:cu-mb-10{margin-bottom:var(--canon-space-10)}.xs\:cu-mb-11{margin-bottom:var(--canon-space-11)}.xs\:cu-mb-12{margin-bottom:var(--canon-space-12)}.xs\:cu-mb-13{margin-bottom:var(--canon-space-13)}.xs\:cu-mb-14{margin-bottom:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-mb{margin-bottom:var(--pb-sm)}.sm\:cu-mb-0\.5{margin-bottom:var(--canon-space-0_5)}.sm\:cu-mb-1{margin-bottom:var(--canon-space-1)}.sm\:cu-mb-1\.5{margin-bottom:var(--canon-space-1_5)}.sm\:cu-mb-2{margin-bottom:var(--canon-space-2)}.sm\:cu-mb-3{margin-bottom:var(--canon-space-3)}.sm\:cu-mb-4{margin-bottom:var(--canon-space-4)}.sm\:cu-mb-5{margin-bottom:var(--canon-space-5)}.sm\:cu-mb-6{margin-bottom:var(--canon-space-6)}.sm\:cu-mb-7{margin-bottom:var(--canon-space-7)}.sm\:cu-mb-8{margin-bottom:var(--canon-space-8)}.sm\:cu-mb-9{margin-bottom:var(--canon-space-9)}.sm\:cu-mb-10{margin-bottom:var(--canon-space-10)}.sm\:cu-mb-11{margin-bottom:var(--canon-space-11)}.sm\:cu-mb-12{margin-bottom:var(--canon-space-12)}.sm\:cu-mb-13{margin-bottom:var(--canon-space-13)}.sm\:cu-mb-14{margin-bottom:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-mb{margin-bottom:var(--pb-md)}.md\:cu-mb-0\.5{margin-bottom:var(--canon-space-0_5)}.md\:cu-mb-1{margin-bottom:var(--canon-space-1)}.md\:cu-mb-1\.5{margin-bottom:var(--canon-space-1_5)}.md\:cu-mb-2{margin-bottom:var(--canon-space-2)}.md\:cu-mb-3{margin-bottom:var(--canon-space-3)}.md\:cu-mb-4{margin-bottom:var(--canon-space-4)}.md\:cu-mb-5{margin-bottom:var(--canon-space-5)}.md\:cu-mb-6{margin-bottom:var(--canon-space-6)}.md\:cu-mb-7{margin-bottom:var(--canon-space-7)}.md\:cu-mb-8{margin-bottom:var(--canon-space-8)}.md\:cu-mb-9{margin-bottom:var(--canon-space-9)}.md\:cu-mb-10{margin-bottom:var(--canon-space-10)}.md\:cu-mb-11{margin-bottom:var(--canon-space-11)}.md\:cu-mb-12{margin-bottom:var(--canon-space-12)}.md\:cu-mb-13{margin-bottom:var(--canon-space-13)}.md\:cu-mb-14{margin-bottom:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-mb{margin-bottom:var(--pb-lg)}.lg\:cu-mb-0\.5{margin-bottom:var(--canon-space-0_5)}.lg\:cu-mb-1{margin-bottom:var(--canon-space-1)}.lg\:cu-mb-1\.5{margin-bottom:var(--canon-space-1_5)}.lg\:cu-mb-2{margin-bottom:var(--canon-space-2)}.lg\:cu-mb-3{margin-bottom:var(--canon-space-3)}.lg\:cu-mb-4{margin-bottom:var(--canon-space-4)}.lg\:cu-mb-5{margin-bottom:var(--canon-space-5)}.lg\:cu-mb-6{margin-bottom:var(--canon-space-6)}.lg\:cu-mb-7{margin-bottom:var(--canon-space-7)}.lg\:cu-mb-8{margin-bottom:var(--canon-space-8)}.lg\:cu-mb-9{margin-bottom:var(--canon-space-9)}.lg\:cu-mb-10{margin-bottom:var(--canon-space-10)}.lg\:cu-mb-11{margin-bottom:var(--canon-space-11)}.lg\:cu-mb-12{margin-bottom:var(--canon-space-12)}.lg\:cu-mb-13{margin-bottom:var(--canon-space-13)}.lg\:cu-mb-14{margin-bottom:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-mb{margin-bottom:var(--pb-xl)}.xl\:cu-mb-0\.5{margin-bottom:var(--canon-space-0_5)}.xl\:cu-mb-1{margin-bottom:var(--canon-space-1)}.xl\:cu-mb-1\.5{margin-bottom:var(--canon-space-1_5)}.xl\:cu-mb-2{margin-bottom:var(--canon-space-2)}.xl\:cu-mb-3{margin-bottom:var(--canon-space-3)}.xl\:cu-mb-4{margin-bottom:var(--canon-space-4)}.xl\:cu-mb-5{margin-bottom:var(--canon-space-5)}.xl\:cu-mb-6{margin-bottom:var(--canon-space-6)}.xl\:cu-mb-7{margin-bottom:var(--canon-space-7)}.xl\:cu-mb-8{margin-bottom:var(--canon-space-8)}.xl\:cu-mb-9{margin-bottom:var(--canon-space-9)}.xl\:cu-mb-10{margin-bottom:var(--canon-space-10)}.xl\:cu-mb-11{margin-bottom:var(--canon-space-11)}.xl\:cu-mb-12{margin-bottom:var(--canon-space-12)}.xl\:cu-mb-13{margin-bottom:var(--canon-space-13)}.xl\:cu-mb-14{margin-bottom:var(--canon-space-14)}}.cu-my{margin-top:var(--my);margin-bottom:var(--my)}.cu-my-0\.5{margin-top:var(--canon-space-0_5);margin-bottom:var(--canon-space-0_5)}.cu-my-1{margin-top:var(--canon-space-1);margin-bottom:var(--canon-space-1)}.cu-my-1\.5{margin-top:var(--canon-space-1_5);margin-bottom:var(--canon-space-1_5)}.cu-my-2{margin-top:var(--canon-space-2);margin-bottom:var(--canon-space-2)}.cu-my-3{margin-top:var(--canon-space-3);margin-bottom:var(--canon-space-3)}.cu-my-4{margin-top:var(--canon-space-4);margin-bottom:var(--canon-space-4)}.cu-my-5{margin-top:var(--canon-space-5);margin-bottom:var(--canon-space-5)}.cu-my-6{margin-top:var(--canon-space-6);margin-bottom:var(--canon-space-6)}.cu-my-7{margin-top:var(--canon-space-7);margin-bottom:var(--canon-space-7)}.cu-my-8{margin-top:var(--canon-space-8);margin-bottom:var(--canon-space-8)}.cu-my-9{margin-top:var(--canon-space-9);margin-bottom:var(--canon-space-9)}.cu-my-10{margin-top:var(--canon-space-10);margin-bottom:var(--canon-space-10)}.cu-my-11{margin-top:var(--canon-space-11);margin-bottom:var(--canon-space-11)}.cu-my-12{margin-top:var(--canon-space-12);margin-bottom:var(--canon-space-12)}.cu-my-13{margin-top:var(--canon-space-13);margin-bottom:var(--canon-space-13)}.cu-my-14{margin-top:var(--canon-space-14);margin-bottom:var(--canon-space-14)}@media (width>=640px){.xs\:cu-my{margin-top:var(--py-xs);margin-bottom:var(--py-xs)}.xs\:cu-my-0\.5{margin-top:var(--canon-space-0_5);margin-bottom:var(--canon-space-0_5)}.xs\:cu-my-1{margin-top:var(--canon-space-1);margin-bottom:var(--canon-space-1)}.xs\:cu-my-1\.5{margin-top:var(--canon-space-1_5);margin-bottom:var(--canon-space-1_5)}.xs\:cu-my-2{margin-top:var(--canon-space-2);margin-bottom:var(--canon-space-2)}.xs\:cu-my-3{margin-top:var(--canon-space-3);margin-bottom:var(--canon-space-3)}.xs\:cu-my-4{margin-top:var(--canon-space-4);margin-bottom:var(--canon-space-4)}.xs\:cu-my-5{margin-top:var(--canon-space-5);margin-bottom:var(--canon-space-5)}.xs\:cu-my-6{margin-top:var(--canon-space-6);margin-bottom:var(--canon-space-6)}.xs\:cu-my-7{margin-top:var(--canon-space-7);margin-bottom:var(--canon-space-7)}.xs\:cu-my-8{margin-top:var(--canon-space-8);margin-bottom:var(--canon-space-8)}.xs\:cu-my-9{margin-top:var(--canon-space-9);margin-bottom:var(--canon-space-9)}.xs\:cu-my-10{margin-top:var(--canon-space-10);margin-bottom:var(--canon-space-10)}.xs\:cu-my-11{margin-top:var(--canon-space-11);margin-bottom:var(--canon-space-11)}.xs\:cu-my-12{margin-top:var(--canon-space-12);margin-bottom:var(--canon-space-12)}.xs\:cu-my-13{margin-top:var(--canon-space-13);margin-bottom:var(--canon-space-13)}.xs\:cu-my-14{margin-top:var(--canon-space-14);margin-bottom:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-my{margin-top:var(--py-sm);margin-bottom:var(--py-sm)}.sm\:cu-my-0\.5{margin-top:var(--canon-space-0_5);margin-bottom:var(--canon-space-0_5)}.sm\:cu-my-1{margin-top:var(--canon-space-1);margin-bottom:var(--canon-space-1)}.sm\:cu-my-1\.5{margin-top:var(--canon-space-1_5);margin-bottom:var(--canon-space-1_5)}.sm\:cu-my-2{margin-top:var(--canon-space-2);margin-bottom:var(--canon-space-2)}.sm\:cu-my-3{margin-top:var(--canon-space-3);margin-bottom:var(--canon-space-3)}.sm\:cu-my-4{margin-top:var(--canon-space-4);margin-bottom:var(--canon-space-4)}.sm\:cu-my-5{margin-top:var(--canon-space-5);margin-bottom:var(--canon-space-5)}.sm\:cu-my-6{margin-top:var(--canon-space-6);margin-bottom:var(--canon-space-6)}.sm\:cu-my-7{margin-top:var(--canon-space-7);margin-bottom:var(--canon-space-7)}.sm\:cu-my-8{margin-top:var(--canon-space-8);margin-bottom:var(--canon-space-8)}.sm\:cu-my-9{margin-top:var(--canon-space-9);margin-bottom:var(--canon-space-9)}.sm\:cu-my-10{margin-top:var(--canon-space-10);margin-bottom:var(--canon-space-10)}.sm\:cu-my-11{margin-top:var(--canon-space-11);margin-bottom:var(--canon-space-11)}.sm\:cu-my-12{margin-top:var(--canon-space-12);margin-bottom:var(--canon-space-12)}.sm\:cu-my-13{margin-top:var(--canon-space-13);margin-bottom:var(--canon-space-13)}.sm\:cu-my-14{margin-top:var(--canon-space-14);margin-bottom:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-my{margin-top:var(--py-md);margin-bottom:var(--py-md)}.md\:cu-my-0\.5{margin-top:var(--canon-space-0_5);margin-bottom:var(--canon-space-0_5)}.md\:cu-my-1{margin-top:var(--canon-space-1);margin-bottom:var(--canon-space-1)}.md\:cu-my-1\.5{margin-top:var(--canon-space-1_5);margin-bottom:var(--canon-space-1_5)}.md\:cu-my-2{margin-top:var(--canon-space-2);margin-bottom:var(--canon-space-2)}.md\:cu-my-3{margin-top:var(--canon-space-3);margin-bottom:var(--canon-space-3)}.md\:cu-my-4{margin-top:var(--canon-space-4);margin-bottom:var(--canon-space-4)}.md\:cu-my-5{margin-top:var(--canon-space-5);margin-bottom:var(--canon-space-5)}.md\:cu-my-6{margin-top:var(--canon-space-6);margin-bottom:var(--canon-space-6)}.md\:cu-my-7{margin-top:var(--canon-space-7);margin-bottom:var(--canon-space-7)}.md\:cu-my-8{margin-top:var(--canon-space-8);margin-bottom:var(--canon-space-8)}.md\:cu-my-9{margin-top:var(--canon-space-9);margin-bottom:var(--canon-space-9)}.md\:cu-my-10{margin-top:var(--canon-space-10);margin-bottom:var(--canon-space-10)}.md\:cu-my-11{margin-top:var(--canon-space-11);margin-bottom:var(--canon-space-11)}.md\:cu-my-12{margin-top:var(--canon-space-12);margin-bottom:var(--canon-space-12)}.md\:cu-my-13{margin-top:var(--canon-space-13);margin-bottom:var(--canon-space-13)}.md\:cu-my-14{margin-top:var(--canon-space-14);margin-bottom:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-my{margin-top:var(--py-lg);margin-bottom:var(--py-lg)}.lg\:cu-my-0\.5{margin-top:var(--canon-space-0_5);margin-bottom:var(--canon-space-0_5)}.lg\:cu-my-1{margin-top:var(--canon-space-1);margin-bottom:var(--canon-space-1)}.lg\:cu-my-1\.5{margin-top:var(--canon-space-1_5);margin-bottom:var(--canon-space-1_5)}.lg\:cu-my-2{margin-top:var(--canon-space-2);margin-bottom:var(--canon-space-2)}.lg\:cu-my-3{margin-top:var(--canon-space-3);margin-bottom:var(--canon-space-3)}.lg\:cu-my-4{margin-top:var(--canon-space-4);margin-bottom:var(--canon-space-4)}.lg\:cu-my-5{margin-top:var(--canon-space-5);margin-bottom:var(--canon-space-5)}.lg\:cu-my-6{margin-top:var(--canon-space-6);margin-bottom:var(--canon-space-6)}.lg\:cu-my-7{margin-top:var(--canon-space-7);margin-bottom:var(--canon-space-7)}.lg\:cu-my-8{margin-top:var(--canon-space-8);margin-bottom:var(--canon-space-8)}.lg\:cu-my-9{margin-top:var(--canon-space-9);margin-bottom:var(--canon-space-9)}.lg\:cu-my-10{margin-top:var(--canon-space-10);margin-bottom:var(--canon-space-10)}.lg\:cu-my-11{margin-top:var(--canon-space-11);margin-bottom:var(--canon-space-11)}.lg\:cu-my-12{margin-top:var(--canon-space-12);margin-bottom:var(--canon-space-12)}.lg\:cu-my-13{margin-top:var(--canon-space-13);margin-bottom:var(--canon-space-13)}.lg\:cu-my-14{margin-top:var(--canon-space-14);margin-bottom:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-my{margin-top:var(--py-xl);margin-bottom:var(--py-xl)}.xl\:cu-my-0\.5{margin-top:var(--canon-space-0_5);margin-bottom:var(--canon-space-0_5)}.xl\:cu-my-1{margin-top:var(--canon-space-1);margin-bottom:var(--canon-space-1)}.xl\:cu-my-1\.5{margin-top:var(--canon-space-1_5);margin-bottom:var(--canon-space-1_5)}.xl\:cu-my-2{margin-top:var(--canon-space-2);margin-bottom:var(--canon-space-2)}.xl\:cu-my-3{margin-top:var(--canon-space-3);margin-bottom:var(--canon-space-3)}.xl\:cu-my-4{margin-top:var(--canon-space-4);margin-bottom:var(--canon-space-4)}.xl\:cu-my-5{margin-top:var(--canon-space-5);margin-bottom:var(--canon-space-5)}.xl\:cu-my-6{margin-top:var(--canon-space-6);margin-bottom:var(--canon-space-6)}.xl\:cu-my-7{margin-top:var(--canon-space-7);margin-bottom:var(--canon-space-7)}.xl\:cu-my-8{margin-top:var(--canon-space-8);margin-bottom:var(--canon-space-8)}.xl\:cu-my-9{margin-top:var(--canon-space-9);margin-bottom:var(--canon-space-9)}.xl\:cu-my-10{margin-top:var(--canon-space-10);margin-bottom:var(--canon-space-10)}.xl\:cu-my-11{margin-top:var(--canon-space-11);margin-bottom:var(--canon-space-11)}.xl\:cu-my-12{margin-top:var(--canon-space-12);margin-bottom:var(--canon-space-12)}.xl\:cu-my-13{margin-top:var(--canon-space-13);margin-bottom:var(--canon-space-13)}.xl\:cu-my-14{margin-top:var(--canon-space-14);margin-bottom:var(--canon-space-14)}}.cu-mx{margin-left:var(--mx);margin-right:var(--mx)}.cu-mx-0\.5{margin-left:var(--canon-space-0_5);margin-right:var(--canon-space-0_5)}.cu-mx-1{margin-left:var(--canon-space-1);margin-right:var(--canon-space-1)}.cu-mx-1\.5{margin-left:var(--canon-space-1_5);margin-right:var(--canon-space-1_5)}.cu-mx-2{margin-left:var(--canon-space-2);margin-right:var(--canon-space-2)}.cu-mx-3{margin-left:var(--canon-space-3);margin-right:var(--canon-space-3)}.cu-mx-4{margin-left:var(--canon-space-4);margin-right:var(--canon-space-4)}.cu-mx-5{margin-left:var(--canon-space-5);margin-right:var(--canon-space-5)}.cu-mx-6{margin-left:var(--canon-space-6);margin-right:var(--canon-space-6)}.cu-mx-7{margin-left:var(--canon-space-7);margin-right:var(--canon-space-7)}.cu-mx-8{margin-left:var(--canon-space-8);margin-right:var(--canon-space-8)}.cu-mx-9{margin-left:var(--canon-space-9);margin-right:var(--canon-space-9)}.cu-mx-10{margin-left:var(--canon-space-10);margin-right:var(--canon-space-10)}.cu-mx-11{margin-left:var(--canon-space-11);margin-right:var(--canon-space-11)}.cu-mx-12{margin-left:var(--canon-space-12);margin-right:var(--canon-space-12)}.cu-mx-13{margin-left:var(--canon-space-13);margin-right:var(--canon-space-13)}.cu-mx-14{margin-left:var(--canon-space-14);margin-right:var(--canon-space-14)}@media (width>=640px){.xs\:cu-mx{margin-left:var(--px-xs);margin-right:var(--px-xs)}.xs\:cu-mx-0\.5{margin-left:var(--canon-space-0_5);margin-right:var(--canon-space-0_5)}.xs\:cu-mx-1{margin-left:var(--canon-space-1);margin-right:var(--canon-space-1)}.xs\:cu-mx-1\.5{margin-left:var(--canon-space-1_5);margin-right:var(--canon-space-1_5)}.xs\:cu-mx-2{margin-left:var(--canon-space-2);margin-right:var(--canon-space-2)}.xs\:cu-mx-3{margin-left:var(--canon-space-3);margin-right:var(--canon-space-3)}.xs\:cu-mx-4{margin-left:var(--canon-space-4);margin-right:var(--canon-space-4)}.xs\:cu-mx-5{margin-left:var(--canon-space-5);margin-right:var(--canon-space-5)}.xs\:cu-mx-6{margin-left:var(--canon-space-6);margin-right:var(--canon-space-6)}.xs\:cu-mx-7{margin-left:var(--canon-space-7);margin-right:var(--canon-space-7)}.xs\:cu-mx-8{margin-left:var(--canon-space-8);margin-right:var(--canon-space-8)}.xs\:cu-mx-9{margin-left:var(--canon-space-9);margin-right:var(--canon-space-9)}.xs\:cu-mx-10{margin-left:var(--canon-space-10);margin-right:var(--canon-space-10)}.xs\:cu-mx-11{margin-left:var(--canon-space-11);margin-right:var(--canon-space-11)}.xs\:cu-mx-12{margin-left:var(--canon-space-12);margin-right:var(--canon-space-12)}.xs\:cu-mx-13{margin-left:var(--canon-space-13);margin-right:var(--canon-space-13)}.xs\:cu-mx-14{margin-left:var(--canon-space-14);margin-right:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-mx{margin-left:var(--px-sm);margin-right:var(--px-sm)}.sm\:cu-mx-0\.5{margin-left:var(--canon-space-0_5);margin-right:var(--canon-space-0_5)}.sm\:cu-mx-1{margin-left:var(--canon-space-1);margin-right:var(--canon-space-1)}.sm\:cu-mx-1\.5{margin-left:var(--canon-space-1_5);margin-right:var(--canon-space-1_5)}.sm\:cu-mx-2{margin-left:var(--canon-space-2);margin-right:var(--canon-space-2)}.sm\:cu-mx-3{margin-left:var(--canon-space-3);margin-right:var(--canon-space-3)}.sm\:cu-mx-4{margin-left:var(--canon-space-4);margin-right:var(--canon-space-4)}.sm\:cu-mx-5{margin-left:var(--canon-space-5);margin-right:var(--canon-space-5)}.sm\:cu-mx-6{margin-left:var(--canon-space-6);margin-right:var(--canon-space-6)}.sm\:cu-mx-7{margin-left:var(--canon-space-7);margin-right:var(--canon-space-7)}.sm\:cu-mx-8{margin-left:var(--canon-space-8);margin-right:var(--canon-space-8)}.sm\:cu-mx-9{margin-left:var(--canon-space-9);margin-right:var(--canon-space-9)}.sm\:cu-mx-10{margin-left:var(--canon-space-10);margin-right:var(--canon-space-10)}.sm\:cu-mx-11{margin-left:var(--canon-space-11);margin-right:var(--canon-space-11)}.sm\:cu-mx-12{margin-left:var(--canon-space-12);margin-right:var(--canon-space-12)}.sm\:cu-mx-13{margin-left:var(--canon-space-13);margin-right:var(--canon-space-13)}.sm\:cu-mx-14{margin-left:var(--canon-space-14);margin-right:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-mx{margin-left:var(--px-md);margin-right:var(--px-md)}.md\:cu-mx-0\.5{margin-left:var(--canon-space-0_5);margin-right:var(--canon-space-0_5)}.md\:cu-mx-1{margin-left:var(--canon-space-1);margin-right:var(--canon-space-1)}.md\:cu-mx-1\.5{margin-left:var(--canon-space-1_5);margin-right:var(--canon-space-1_5)}.md\:cu-mx-2{margin-left:var(--canon-space-2);margin-right:var(--canon-space-2)}.md\:cu-mx-3{margin-left:var(--canon-space-3);margin-right:var(--canon-space-3)}.md\:cu-mx-4{margin-left:var(--canon-space-4);margin-right:var(--canon-space-4)}.md\:cu-mx-5{margin-left:var(--canon-space-5);margin-right:var(--canon-space-5)}.md\:cu-mx-6{margin-left:var(--canon-space-6);margin-right:var(--canon-space-6)}.md\:cu-mx-7{margin-left:var(--canon-space-7);margin-right:var(--canon-space-7)}.md\:cu-mx-8{margin-left:var(--canon-space-8);margin-right:var(--canon-space-8)}.md\:cu-mx-9{margin-left:var(--canon-space-9);margin-right:var(--canon-space-9)}.md\:cu-mx-10{margin-left:var(--canon-space-10);margin-right:var(--canon-space-10)}.md\:cu-mx-11{margin-left:var(--canon-space-11);margin-right:var(--canon-space-11)}.md\:cu-mx-12{margin-left:var(--canon-space-12);margin-right:var(--canon-space-12)}.md\:cu-mx-13{margin-left:var(--canon-space-13);margin-right:var(--canon-space-13)}.md\:cu-mx-14{margin-left:var(--canon-space-14);margin-right:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-mx{margin-left:var(--px-lg);margin-right:var(--px-lg)}.lg\:cu-mx-0\.5{margin-left:var(--canon-space-0_5);margin-right:var(--canon-space-0_5)}.lg\:cu-mx-1{margin-left:var(--canon-space-1);margin-right:var(--canon-space-1)}.lg\:cu-mx-1\.5{margin-left:var(--canon-space-1_5);margin-right:var(--canon-space-1_5)}.lg\:cu-mx-2{margin-left:var(--canon-space-2);margin-right:var(--canon-space-2)}.lg\:cu-mx-3{margin-left:var(--canon-space-3);margin-right:var(--canon-space-3)}.lg\:cu-mx-4{margin-left:var(--canon-space-4);margin-right:var(--canon-space-4)}.lg\:cu-mx-5{margin-left:var(--canon-space-5);margin-right:var(--canon-space-5)}.lg\:cu-mx-6{margin-left:var(--canon-space-6);margin-right:var(--canon-space-6)}.lg\:cu-mx-7{margin-left:var(--canon-space-7);margin-right:var(--canon-space-7)}.lg\:cu-mx-8{margin-left:var(--canon-space-8);margin-right:var(--canon-space-8)}.lg\:cu-mx-9{margin-left:var(--canon-space-9);margin-right:var(--canon-space-9)}.lg\:cu-mx-10{margin-left:var(--canon-space-10);margin-right:var(--canon-space-10)}.lg\:cu-mx-11{margin-left:var(--canon-space-11);margin-right:var(--canon-space-11)}.lg\:cu-mx-12{margin-left:var(--canon-space-12);margin-right:var(--canon-space-12)}.lg\:cu-mx-13{margin-left:var(--canon-space-13);margin-right:var(--canon-space-13)}.lg\:cu-mx-14{margin-left:var(--canon-space-14);margin-right:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-mx{margin-left:var(--px-xl);margin-right:var(--px-xl)}.xl\:cu-mx-0\.5{margin-left:var(--canon-space-0_5);margin-right:var(--canon-space-0_5)}.xl\:cu-mx-1{margin-left:var(--canon-space-1);margin-right:var(--canon-space-1)}.xl\:cu-mx-1\.5{margin-left:var(--canon-space-1_5);margin-right:var(--canon-space-1_5)}.xl\:cu-mx-2{margin-left:var(--canon-space-2);margin-right:var(--canon-space-2)}.xl\:cu-mx-3{margin-left:var(--canon-space-3);margin-right:var(--canon-space-3)}.xl\:cu-mx-4{margin-left:var(--canon-space-4);margin-right:var(--canon-space-4)}.xl\:cu-mx-5{margin-left:var(--canon-space-5);margin-right:var(--canon-space-5)}.xl\:cu-mx-6{margin-left:var(--canon-space-6);margin-right:var(--canon-space-6)}.xl\:cu-mx-7{margin-left:var(--canon-space-7);margin-right:var(--canon-space-7)}.xl\:cu-mx-8{margin-left:var(--canon-space-8);margin-right:var(--canon-space-8)}.xl\:cu-mx-9{margin-left:var(--canon-space-9);margin-right:var(--canon-space-9)}.xl\:cu-mx-10{margin-left:var(--canon-space-10);margin-right:var(--canon-space-10)}.xl\:cu-mx-11{margin-left:var(--canon-space-11);margin-right:var(--canon-space-11)}.xl\:cu-mx-12{margin-left:var(--canon-space-12);margin-right:var(--canon-space-12)}.xl\:cu-mx-13{margin-left:var(--canon-space-13);margin-right:var(--canon-space-13)}.xl\:cu-mx-14{margin-left:var(--canon-space-14);margin-right:var(--canon-space-14)}}.cu-display-none{display:none}.cu-display-inline{display:inline}.cu-display-inline-block{display:inline-block}.cu-display-block{display:block}@media (width>=640px){.xs\:cu-display-none{display:none}.xs\:cu-display-inline{display:inline}.xs\:cu-display-inline-block{display:inline-block}.xs\:cu-display-block{display:block}}@media (width>=768px){.sm\:cu-display-none{display:none}.sm\:cu-display-inline{display:inline}.sm\:cu-display-inline-block{display:inline-block}.sm\:cu-display-block{display:block}}@media (width>=1024px){.md\:cu-display-none{display:none}.md\:cu-display-inline{display:inline}.md\:cu-display-inline-block{display:inline-block}.md\:cu-display-block{display:block}}@media (width>=1280px){.lg\:cu-display-none{display:none}.lg\:cu-display-inline{display:inline}.lg\:cu-display-inline-block{display:inline-block}.lg\:cu-display-block{display:block}}@media (width>=1536px){.xl\:cu-display-none{display:none}.xl\:cu-display-inline{display:inline}.xl\:cu-display-inline-block{display:inline-block}.xl\:cu-display-block{display:block}}.cu-w{width:var(--width)}.cu-min-w{min-width:var(--min-width)}.cu-max-w{max-width:var(--max-width)}@media (width>=640px){.xs\:cu-w{width:var(--width)}.xs\:cu-min-w{min-width:var(--min-width)}.xs\:cu-max-w{max-width:var(--max-width)}}@media (width>=768px){.sm\:cu-w{width:var(--width)}.sm\:cu-min-w{min-width:var(--min-width)}.sm\:cu-max-w{max-width:var(--max-width)}}@media (width>=1024px){.md\:cu-w{width:var(--width)}.md\:cu-min-w{min-width:var(--min-width)}.md\:cu-max-w{max-width:var(--max-width)}}@media (width>=1280px){.lg\:cu-w{width:var(--width)}.lg\:cu-min-w{min-width:var(--min-width)}.lg\:cu-max-w{max-width:var(--max-width)}}@media (width>=1536px){.xl\:cu-w{width:var(--width)}.xl\:cu-min-w{min-width:var(--min-width)}.xl\:cu-max-w{max-width:var(--max-width)}}.cu-h{height:var(--height)}.cu-min-h{min-height:var(--min-height)}.cu-max-h{max-height:var(--max-height)}@media (width>=640px){.xs\:cu-h{height:var(--height)}.xs\:cu-min-h{min-height:var(--min-height)}.xs\:cu-max-h{max-height:var(--max-height)}}@media (width>=768px){.sm\:cu-h{height:var(--height)}.sm\:cu-min-h{min-height:var(--min-height)}.sm\:cu-max-h{max-height:var(--max-height)}}@media (width>=1024px){.md\:cu-h{height:var(--height)}.md\:cu-min-h{min-height:var(--min-height)}.md\:cu-max-h{max-height:var(--max-height)}}@media (width>=1280px){.lg\:cu-h{height:var(--height)}.lg\:cu-min-h{min-height:var(--min-height)}.lg\:cu-max-h{max-height:var(--max-height)}}@media (width>=1536px){.xl\:cu-h{height:var(--height)}.xl\:cu-min-h{min-height:var(--min-height)}.xl\:cu-max-h{max-height:var(--max-height)}}.cu-position-absolute{position:absolute}.cu-position-fixed{position:fixed}.cu-position-sticky{position:sticky}.cu-position-relative{position:relative}.cu-position-static{position:static}@media (width>=640px){.xs\:cu-position-absolute{position:absolute}.xs\:cu-position-fixed{position:fixed}.xs\:cu-position-sticky{position:sticky}.xs\:cu-position-relative{position:relative}.xs\:cu-position-static{position:static}}@media (width>=768px){.sm\:cu-position-absolute{position:absolute}.sm\:cu-position-fixed{position:fixed}.sm\:cu-position-sticky{position:sticky}.sm\:cu-position-relative{position:relative}.sm\:cu-position-static{position:static}}@media (width>=1024px){.md\:cu-position-absolute{position:absolute}.md\:cu-position-fixed{position:fixed}.md\:cu-position-sticky{position:sticky}.md\:cu-position-relative{position:relative}.md\:cu-position-static{position:static}}@media (width>=1280px){.lg\:cu-position-absolute{position:absolute}.lg\:cu-position-fixed{position:fixed}.lg\:cu-position-sticky{position:sticky}.lg\:cu-position-relative{position:relative}.lg\:cu-position-static{position:static}}@media (width>=1536px){.xl\:cu-position-absolute{position:absolute}.xl\:cu-position-fixed{position:fixed}.xl\:cu-position-sticky{position:sticky}.xl\:cu-position-relative{position:relative}.xl\:cu-position-static{position:static}}.cu-columns-1{grid-template-columns:repeat(1,minmax(0,1fr))}.cu-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}.cu-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cu-columns-4{grid-template-columns:repeat(4,minmax(0,1fr))}.cu-columns-5{grid-template-columns:repeat(5,minmax(0,1fr))}.cu-columns-6{grid-template-columns:repeat(6,minmax(0,1fr))}.cu-columns-7{grid-template-columns:repeat(7,minmax(0,1fr))}.cu-columns-8{grid-template-columns:repeat(8,minmax(0,1fr))}.cu-columns-9{grid-template-columns:repeat(9,minmax(0,1fr))}.cu-columns-10{grid-template-columns:repeat(10,minmax(0,1fr))}.cu-columns-11{grid-template-columns:repeat(11,minmax(0,1fr))}.cu-columns-12{grid-template-columns:repeat(12,minmax(0,1fr))}.cu-columns-auto{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}.cu-col-span-1{grid-column:span 1/span 1}.cu-col-span-2{grid-column:span 2/span 2}.cu-col-span-3{grid-column:span 3/span 3}.cu-col-span-4{grid-column:span 4/span 4}.cu-col-span-5{grid-column:span 5/span 5}.cu-col-span-6{grid-column:span 6/span 6}.cu-col-span-7{grid-column:span 7/span 7}.cu-col-span-8{grid-column:span 8/span 8}.cu-col-span-9{grid-column:span 9/span 9}.cu-col-span-10{grid-column:span 10/span 10}.cu-col-span-11{grid-column:span 11/span 11}.cu-col-span-12{grid-column:span 12/span 12}.cu-col-span-auto{grid-column:span auto/span auto}.cu-col-start-1{grid-column-start:1}.cu-col-start-2{grid-column-start:2}.cu-col-start-3{grid-column-start:3}.cu-col-start-4{grid-column-start:4}.cu-col-start-5{grid-column-start:5}.cu-col-start-6{grid-column-start:6}.cu-col-start-7{grid-column-start:7}.cu-col-start-8{grid-column-start:8}.cu-col-start-9{grid-column-start:9}.cu-col-start-10{grid-column-start:10}.cu-col-start-11{grid-column-start:11}.cu-col-start-12{grid-column-start:12}.cu-col-start-13{grid-column-start:13}.cu-col-start-auto{grid-column-start:auto}.cu-col-end-1{grid-column-end:1}.cu-col-end-2{grid-column-end:2}.cu-col-end-3{grid-column-end:3}.cu-col-end-4{grid-column-end:4}.cu-col-end-5{grid-column-end:5}.cu-col-end-6{grid-column-end:6}.cu-col-end-7{grid-column-end:7}.cu-col-end-8{grid-column-end:8}.cu-col-end-9{grid-column-end:9}.cu-col-end-10{grid-column-end:10}.cu-col-end-11{grid-column-end:11}.cu-col-end-12{grid-column-end:12}.cu-col-end-13{grid-column-end:13}.cu-col-end-auto{grid-column-end:auto}.cu-row-span-1{grid-row:span 1/span 1}.cu-row-span-2{grid-row:span 2/span 2}.cu-row-span-3{grid-row:span 3/span 3}.cu-row-span-4{grid-row:span 4/span 4}.cu-row-span-5{grid-row:span 5/span 5}.cu-row-span-6{grid-row:span 6/span 6}.cu-row-span-7{grid-row:span 7/span 7}.cu-row-span-8{grid-row:span 8/span 8}.cu-row-span-9{grid-row:span 9/span 9}.cu-row-span-10{grid-row:span 10/span 10}.cu-row-span-11{grid-row:span 11/span 11}.cu-row-span-12{grid-row:span 12/span 12}.cu-row-span-auto{grid-row:span auto/span auto}@media (width>=640px){.xs\:cu-columns-1{grid-template-columns:repeat(1,minmax(0,1fr))}.xs\:cu-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xs\:cu-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xs\:cu-columns-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xs\:cu-columns-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xs\:cu-columns-6{grid-template-columns:repeat(6,minmax(0,1fr))}.xs\:cu-columns-7{grid-template-columns:repeat(7,minmax(0,1fr))}.xs\:cu-columns-8{grid-template-columns:repeat(8,minmax(0,1fr))}.xs\:cu-columns-9{grid-template-columns:repeat(9,minmax(0,1fr))}.xs\:cu-columns-10{grid-template-columns:repeat(10,minmax(0,1fr))}.xs\:cu-columns-11{grid-template-columns:repeat(11,minmax(0,1fr))}.xs\:cu-columns-12{grid-template-columns:repeat(12,minmax(0,1fr))}.xs\:cu-columns-auto{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}.xs\:cu-col-span-1{grid-column:span 1/span 1}.xs\:cu-col-span-2{grid-column:span 2/span 2}.xs\:cu-col-span-3{grid-column:span 3/span 3}.xs\:cu-col-span-4{grid-column:span 4/span 4}.xs\:cu-col-span-5{grid-column:span 5/span 5}.xs\:cu-col-span-6{grid-column:span 6/span 6}.xs\:cu-col-span-7{grid-column:span 7/span 7}.xs\:cu-col-span-8{grid-column:span 8/span 8}.xs\:cu-col-span-9{grid-column:span 9/span 9}.xs\:cu-col-span-10{grid-column:span 10/span 10}.xs\:cu-col-span-11{grid-column:span 11/span 11}.xs\:cu-col-span-12{grid-column:span 12/span 12}.xs\:cu-col-span-auto{grid-column:span auto/span auto}.xs\:cu-col-start-1{grid-column-start:1}.xs\:cu-col-start-2{grid-column-start:2}.xs\:cu-col-start-3{grid-column-start:3}.xs\:cu-col-start-4{grid-column-start:4}.xs\:cu-col-start-5{grid-column-start:5}.xs\:cu-col-start-6{grid-column-start:6}.xs\:cu-col-start-7{grid-column-start:7}.xs\:cu-col-start-8{grid-column-start:8}.xs\:cu-col-start-9{grid-column-start:9}.xs\:cu-col-start-10{grid-column-start:10}.xs\:cu-col-start-11{grid-column-start:11}.xs\:cu-col-start-12{grid-column-start:12}.xs\:cu-col-start-13{grid-column-start:13}.xs\:cu-col-start-auto{grid-column-start:auto}.xs\:cu-col-end-1{grid-column-end:1}.xs\:cu-col-end-2{grid-column-end:2}.xs\:cu-col-end-3{grid-column-end:3}.xs\:cu-col-end-4{grid-column-end:4}.xs\:cu-col-end-5{grid-column-end:5}.xs\:cu-col-end-6{grid-column-end:6}.xs\:cu-col-end-7{grid-column-end:7}.xs\:cu-col-end-8{grid-column-end:8}.xs\:cu-col-end-9{grid-column-end:9}.xs\:cu-col-end-10{grid-column-end:10}.xs\:cu-col-end-11{grid-column-end:11}.xs\:cu-col-end-12{grid-column-end:12}.xs\:cu-col-end-13{grid-column-end:13}.xs\:cu-col-end-auto{grid-column-end:auto}.xs\:cu-row-span-1{grid-row:span 1/span 1}.xs\:cu-row-span-2{grid-row:span 2/span 2}.xs\:cu-row-span-3{grid-row:span 3/span 3}.xs\:cu-row-span-4{grid-row:span 4/span 4}.xs\:cu-row-span-5{grid-row:span 5/span 5}.xs\:cu-row-span-6{grid-row:span 6/span 6}.xs\:cu-row-span-7{grid-row:span 7/span 7}.xs\:cu-row-span-8{grid-row:span 8/span 8}.xs\:cu-row-span-9{grid-row:span 9/span 9}.xs\:cu-row-span-10{grid-row:span 10/span 10}.xs\:cu-row-span-11{grid-row:span 11/span 11}.xs\:cu-row-span-12{grid-row:span 12/span 12}.xs\:cu-row-span-auto{grid-row:span auto/span auto}}@media (width>=768px){.sm\:cu-columns-1{grid-template-columns:repeat(1,minmax(0,1fr))}.sm\:cu-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:cu-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:cu-columns-4{grid-template-columns:repeat(4,minmax(0,1fr))}.sm\:cu-columns-5{grid-template-columns:repeat(5,minmax(0,1fr))}.sm\:cu-columns-6{grid-template-columns:repeat(6,minmax(0,1fr))}.sm\:cu-columns-7{grid-template-columns:repeat(7,minmax(0,1fr))}.sm\:cu-columns-8{grid-template-columns:repeat(8,minmax(0,1fr))}.sm\:cu-columns-9{grid-template-columns:repeat(9,minmax(0,1fr))}.sm\:cu-columns-10{grid-template-columns:repeat(10,minmax(0,1fr))}.sm\:cu-columns-11{grid-template-columns:repeat(11,minmax(0,1fr))}.sm\:cu-columns-12{grid-template-columns:repeat(12,minmax(0,1fr))}.sm\:cu-columns-auto{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}.sm\:cu-col-span-1{grid-column:span 1/span 1}.sm\:cu-col-span-2{grid-column:span 2/span 2}.sm\:cu-col-span-3{grid-column:span 3/span 3}.sm\:cu-col-span-4{grid-column:span 4/span 4}.sm\:cu-col-span-5{grid-column:span 5/span 5}.sm\:cu-col-span-6{grid-column:span 6/span 6}.sm\:cu-col-span-7{grid-column:span 7/span 7}.sm\:cu-col-span-8{grid-column:span 8/span 8}.sm\:cu-col-span-9{grid-column:span 9/span 9}.sm\:cu-col-span-10{grid-column:span 10/span 10}.sm\:cu-col-span-11{grid-column:span 11/span 11}.sm\:cu-col-span-12{grid-column:span 12/span 12}.sm\:cu-col-span-auto{grid-column:span auto/span auto}.sm\:cu-col-start-1{grid-column-start:1}.sm\:cu-col-start-2{grid-column-start:2}.sm\:cu-col-start-3{grid-column-start:3}.sm\:cu-col-start-4{grid-column-start:4}.sm\:cu-col-start-5{grid-column-start:5}.sm\:cu-col-start-6{grid-column-start:6}.sm\:cu-col-start-7{grid-column-start:7}.sm\:cu-col-start-8{grid-column-start:8}.sm\:cu-col-start-9{grid-column-start:9}.sm\:cu-col-start-10{grid-column-start:10}.sm\:cu-col-start-11{grid-column-start:11}.sm\:cu-col-start-12{grid-column-start:12}.sm\:cu-col-start-13{grid-column-start:13}.sm\:cu-col-start-auto{grid-column-start:auto}.sm\:cu-col-end-1{grid-column-end:1}.sm\:cu-col-end-2{grid-column-end:2}.sm\:cu-col-end-3{grid-column-end:3}.sm\:cu-col-end-4{grid-column-end:4}.sm\:cu-col-end-5{grid-column-end:5}.sm\:cu-col-end-6{grid-column-end:6}.sm\:cu-col-end-7{grid-column-end:7}.sm\:cu-col-end-8{grid-column-end:8}.sm\:cu-col-end-9{grid-column-end:9}.sm\:cu-col-end-10{grid-column-end:10}.sm\:cu-col-end-11{grid-column-end:11}.sm\:cu-col-end-12{grid-column-end:12}.sm\:cu-col-end-13{grid-column-end:13}.sm\:cu-col-end-auto{grid-column-end:auto}.sm\:cu-row-span-1{grid-row:span 1/span 1}.sm\:cu-row-span-2{grid-row:span 2/span 2}.sm\:cu-row-span-3{grid-row:span 3/span 3}.sm\:cu-row-span-4{grid-row:span 4/span 4}.sm\:cu-row-span-5{grid-row:span 5/span 5}.sm\:cu-row-span-6{grid-row:span 6/span 6}.sm\:cu-row-span-7{grid-row:span 7/span 7}.sm\:cu-row-span-8{grid-row:span 8/span 8}.sm\:cu-row-span-9{grid-row:span 9/span 9}.sm\:cu-row-span-10{grid-row:span 10/span 10}.sm\:cu-row-span-11{grid-row:span 11/span 11}.sm\:cu-row-span-12{grid-row:span 12/span 12}.sm\:cu-row-span-auto{grid-row:span auto/span auto}}@media (width>=1024px){.md\:cu-columns-1{grid-template-columns:repeat(1,minmax(0,1fr))}.md\:cu-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:cu-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:cu-columns-4{grid-template-columns:repeat(4,minmax(0,1fr))}.md\:cu-columns-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:cu-columns-6{grid-template-columns:repeat(6,minmax(0,1fr))}.md\:cu-columns-7{grid-template-columns:repeat(7,minmax(0,1fr))}.md\:cu-columns-8{grid-template-columns:repeat(8,minmax(0,1fr))}.md\:cu-columns-9{grid-template-columns:repeat(9,minmax(0,1fr))}.md\:cu-columns-10{grid-template-columns:repeat(10,minmax(0,1fr))}.md\:cu-columns-11{grid-template-columns:repeat(11,minmax(0,1fr))}.md\:cu-columns-12{grid-template-columns:repeat(12,minmax(0,1fr))}.md\:cu-columns-auto{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}.md\:cu-col-span-1{grid-column:span 1/span 1}.md\:cu-col-span-2{grid-column:span 2/span 2}.md\:cu-col-span-3{grid-column:span 3/span 3}.md\:cu-col-span-4{grid-column:span 4/span 4}.md\:cu-col-span-5{grid-column:span 5/span 5}.md\:cu-col-span-6{grid-column:span 6/span 6}.md\:cu-col-span-7{grid-column:span 7/span 7}.md\:cu-col-span-8{grid-column:span 8/span 8}.md\:cu-col-span-9{grid-column:span 9/span 9}.md\:cu-col-span-10{grid-column:span 10/span 10}.md\:cu-col-span-11{grid-column:span 11/span 11}.md\:cu-col-span-12{grid-column:span 12/span 12}.md\:cu-col-span-auto{grid-column:span auto/span auto}.md\:cu-col-start-1{grid-column-start:1}.md\:cu-col-start-2{grid-column-start:2}.md\:cu-col-start-3{grid-column-start:3}.md\:cu-col-start-4{grid-column-start:4}.md\:cu-col-start-5{grid-column-start:5}.md\:cu-col-start-6{grid-column-start:6}.md\:cu-col-start-7{grid-column-start:7}.md\:cu-col-start-8{grid-column-start:8}.md\:cu-col-start-9{grid-column-start:9}.md\:cu-col-start-10{grid-column-start:10}.md\:cu-col-start-11{grid-column-start:11}.md\:cu-col-start-12{grid-column-start:12}.md\:cu-col-start-13{grid-column-start:13}.md\:cu-col-start-auto{grid-column-start:auto}.md\:cu-col-end-1{grid-column-end:1}.md\:cu-col-end-2{grid-column-end:2}.md\:cu-col-end-3{grid-column-end:3}.md\:cu-col-end-4{grid-column-end:4}.md\:cu-col-end-5{grid-column-end:5}.md\:cu-col-end-6{grid-column-end:6}.md\:cu-col-end-7{grid-column-end:7}.md\:cu-col-end-8{grid-column-end:8}.md\:cu-col-end-9{grid-column-end:9}.md\:cu-col-end-10{grid-column-end:10}.md\:cu-col-end-11{grid-column-end:11}.md\:cu-col-end-12{grid-column-end:12}.md\:cu-col-end-13{grid-column-end:13}.md\:cu-col-end-auto{grid-column-end:auto}.md\:cu-row-span-1{grid-row:span 1/span 1}.md\:cu-row-span-2{grid-row:span 2/span 2}.md\:cu-row-span-3{grid-row:span 3/span 3}.md\:cu-row-span-4{grid-row:span 4/span 4}.md\:cu-row-span-5{grid-row:span 5/span 5}.md\:cu-row-span-6{grid-row:span 6/span 6}.md\:cu-row-span-7{grid-row:span 7/span 7}.md\:cu-row-span-8{grid-row:span 8/span 8}.md\:cu-row-span-9{grid-row:span 9/span 9}.md\:cu-row-span-10{grid-row:span 10/span 10}.md\:cu-row-span-11{grid-row:span 11/span 11}.md\:cu-row-span-12{grid-row:span 12/span 12}.md\:cu-row-span-auto{grid-row:span auto/span auto}}@media (width>=1280px){.lg\:cu-columns-1{grid-template-columns:repeat(1,minmax(0,1fr))}.lg\:cu-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:cu-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:cu-columns-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:cu-columns-5{grid-template-columns:repeat(5,minmax(0,1fr))}.lg\:cu-columns-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:cu-columns-7{grid-template-columns:repeat(7,minmax(0,1fr))}.lg\:cu-columns-8{grid-template-columns:repeat(8,minmax(0,1fr))}.lg\:cu-columns-9{grid-template-columns:repeat(9,minmax(0,1fr))}.lg\:cu-columns-10{grid-template-columns:repeat(10,minmax(0,1fr))}.lg\:cu-columns-11{grid-template-columns:repeat(11,minmax(0,1fr))}.lg\:cu-columns-12{grid-template-columns:repeat(12,minmax(0,1fr))}.lg\:cu-columns-auto{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}.lg\:cu-col-span-1{grid-column:span 1/span 1}.lg\:cu-col-span-2{grid-column:span 2/span 2}.lg\:cu-col-span-3{grid-column:span 3/span 3}.lg\:cu-col-span-4{grid-column:span 4/span 4}.lg\:cu-col-span-5{grid-column:span 5/span 5}.lg\:cu-col-span-6{grid-column:span 6/span 6}.lg\:cu-col-span-7{grid-column:span 7/span 7}.lg\:cu-col-span-8{grid-column:span 8/span 8}.lg\:cu-col-span-9{grid-column:span 9/span 9}.lg\:cu-col-span-10{grid-column:span 10/span 10}.lg\:cu-col-span-11{grid-column:span 11/span 11}.lg\:cu-col-span-12{grid-column:span 12/span 12}.lg\:cu-col-span-auto{grid-column:span auto/span auto}.lg\:cu-col-start-1{grid-column-start:1}.lg\:cu-col-start-2{grid-column-start:2}.lg\:cu-col-start-3{grid-column-start:3}.lg\:cu-col-start-4{grid-column-start:4}.lg\:cu-col-start-5{grid-column-start:5}.lg\:cu-col-start-6{grid-column-start:6}.lg\:cu-col-start-7{grid-column-start:7}.lg\:cu-col-start-8{grid-column-start:8}.lg\:cu-col-start-9{grid-column-start:9}.lg\:cu-col-start-10{grid-column-start:10}.lg\:cu-col-start-11{grid-column-start:11}.lg\:cu-col-start-12{grid-column-start:12}.lg\:cu-col-start-13{grid-column-start:13}.lg\:cu-col-start-auto{grid-column-start:auto}.lg\:cu-col-end-1{grid-column-end:1}.lg\:cu-col-end-2{grid-column-end:2}.lg\:cu-col-end-3{grid-column-end:3}.lg\:cu-col-end-4{grid-column-end:4}.lg\:cu-col-end-5{grid-column-end:5}.lg\:cu-col-end-6{grid-column-end:6}.lg\:cu-col-end-7{grid-column-end:7}.lg\:cu-col-end-8{grid-column-end:8}.lg\:cu-col-end-9{grid-column-end:9}.lg\:cu-col-end-10{grid-column-end:10}.lg\:cu-col-end-11{grid-column-end:11}.lg\:cu-col-end-12{grid-column-end:12}.lg\:cu-col-end-13{grid-column-end:13}.lg\:cu-col-end-auto{grid-column-end:auto}.lg\:cu-row-span-1{grid-row:span 1/span 1}.lg\:cu-row-span-2{grid-row:span 2/span 2}.lg\:cu-row-span-3{grid-row:span 3/span 3}.lg\:cu-row-span-4{grid-row:span 4/span 4}.lg\:cu-row-span-5{grid-row:span 5/span 5}.lg\:cu-row-span-6{grid-row:span 6/span 6}.lg\:cu-row-span-7{grid-row:span 7/span 7}.lg\:cu-row-span-8{grid-row:span 8/span 8}.lg\:cu-row-span-9{grid-row:span 9/span 9}.lg\:cu-row-span-10{grid-row:span 10/span 10}.lg\:cu-row-span-11{grid-row:span 11/span 11}.lg\:cu-row-span-12{grid-row:span 12/span 12}.lg\:cu-row-span-auto{grid-row:span auto/span auto}}@media (width>=1536px){.xl\:cu-columns-1{grid-template-columns:repeat(1,minmax(0,1fr))}.xl\:cu-columns-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:cu-columns-3{grid-template-columns:repeat(3,minmax(0,1fr))}.xl\:cu-columns-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:cu-columns-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:cu-columns-6{grid-template-columns:repeat(6,minmax(0,1fr))}.xl\:cu-columns-7{grid-template-columns:repeat(7,minmax(0,1fr))}.xl\:cu-columns-8{grid-template-columns:repeat(8,minmax(0,1fr))}.xl\:cu-columns-9{grid-template-columns:repeat(9,minmax(0,1fr))}.xl\:cu-columns-10{grid-template-columns:repeat(10,minmax(0,1fr))}.xl\:cu-columns-11{grid-template-columns:repeat(11,minmax(0,1fr))}.xl\:cu-columns-12{grid-template-columns:repeat(12,minmax(0,1fr))}.xl\:cu-columns-auto{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}.xl\:cu-col-span-1{grid-column:span 1/span 1}.xl\:cu-col-span-2{grid-column:span 2/span 2}.xl\:cu-col-span-3{grid-column:span 3/span 3}.xl\:cu-col-span-4{grid-column:span 4/span 4}.xl\:cu-col-span-5{grid-column:span 5/span 5}.xl\:cu-col-span-6{grid-column:span 6/span 6}.xl\:cu-col-span-7{grid-column:span 7/span 7}.xl\:cu-col-span-8{grid-column:span 8/span 8}.xl\:cu-col-span-9{grid-column:span 9/span 9}.xl\:cu-col-span-10{grid-column:span 10/span 10}.xl\:cu-col-span-11{grid-column:span 11/span 11}.xl\:cu-col-span-12{grid-column:span 12/span 12}.xl\:cu-col-span-auto{grid-column:span auto/span auto}.xl\:cu-col-start-1{grid-column-start:1}.xl\:cu-col-start-2{grid-column-start:2}.xl\:cu-col-start-3{grid-column-start:3}.xl\:cu-col-start-4{grid-column-start:4}.xl\:cu-col-start-5{grid-column-start:5}.xl\:cu-col-start-6{grid-column-start:6}.xl\:cu-col-start-7{grid-column-start:7}.xl\:cu-col-start-8{grid-column-start:8}.xl\:cu-col-start-9{grid-column-start:9}.xl\:cu-col-start-10{grid-column-start:10}.xl\:cu-col-start-11{grid-column-start:11}.xl\:cu-col-start-12{grid-column-start:12}.xl\:cu-col-start-13{grid-column-start:13}.xl\:cu-col-start-auto{grid-column-start:auto}.xl\:cu-col-end-1{grid-column-end:1}.xl\:cu-col-end-2{grid-column-end:2}.xl\:cu-col-end-3{grid-column-end:3}.xl\:cu-col-end-4{grid-column-end:4}.xl\:cu-col-end-5{grid-column-end:5}.xl\:cu-col-end-6{grid-column-end:6}.xl\:cu-col-end-7{grid-column-end:7}.xl\:cu-col-end-8{grid-column-end:8}.xl\:cu-col-end-9{grid-column-end:9}.xl\:cu-col-end-10{grid-column-end:10}.xl\:cu-col-end-11{grid-column-end:11}.xl\:cu-col-end-12{grid-column-end:12}.xl\:cu-col-end-13{grid-column-end:13}.xl\:cu-col-end-auto{grid-column-end:auto}.xl\:cu-row-span-1{grid-row:span 1/span 1}.xl\:cu-row-span-2{grid-row:span 2/span 2}.xl\:cu-row-span-3{grid-row:span 3/span 3}.xl\:cu-row-span-4{grid-row:span 4/span 4}.xl\:cu-row-span-5{grid-row:span 5/span 5}.xl\:cu-row-span-6{grid-row:span 6/span 6}.xl\:cu-row-span-7{grid-row:span 7/span 7}.xl\:cu-row-span-8{grid-row:span 8/span 8}.xl\:cu-row-span-9{grid-row:span 9/span 9}.xl\:cu-row-span-10{grid-row:span 10/span 10}.xl\:cu-row-span-11{grid-row:span 11/span 11}.xl\:cu-row-span-12{grid-row:span 12/span 12}.xl\:cu-row-span-auto{grid-row:span auto/span auto}}.cu-gap{gap:var(--gap)}.cu-gap-0\.5{gap:var(--canon-space-0_5)}.cu-gap-1{gap:var(--canon-space-1)}.cu-gap-1\.5{gap:var(--canon-space-1_5)}.cu-gap-2{gap:var(--canon-space-2)}.cu-gap-3{gap:var(--canon-space-3)}.cu-gap-4{gap:var(--canon-space-4)}.cu-gap-5{gap:var(--canon-space-5)}.cu-gap-6{gap:var(--canon-space-6)}.cu-gap-7{gap:var(--canon-space-7)}.cu-gap-8{gap:var(--canon-space-8)}.cu-gap-9{gap:var(--canon-space-9)}.cu-gap-10{gap:var(--canon-space-10)}.cu-gap-11{gap:var(--canon-space-11)}.cu-gap-12{gap:var(--canon-space-12)}.cu-gap-13{gap:var(--canon-space-13)}.cu-gap-14{gap:var(--canon-space-14)}@media (width>=640px){.xs\:cu-gap{gap:var(--gap-xs)}.xs\:cu-gap-0\.5{gap:var(--canon-space-0_5)}.xs\:cu-gap-1{gap:var(--canon-space-1)}.xs\:cu-gap-1\.5{gap:var(--canon-space-1_5)}.xs\:cu-gap-2{gap:var(--canon-space-2)}.xs\:cu-gap-3{gap:var(--canon-space-3)}.xs\:cu-gap-4{gap:var(--canon-space-4)}.xs\:cu-gap-5{gap:var(--canon-space-5)}.xs\:cu-gap-6{gap:var(--canon-space-6)}.xs\:cu-gap-7{gap:var(--canon-space-7)}.xs\:cu-gap-8{gap:var(--canon-space-8)}.xs\:cu-gap-9{gap:var(--canon-space-9)}.xs\:cu-gap-10{gap:var(--canon-space-10)}.xs\:cu-gap-11{gap:var(--canon-space-11)}.xs\:cu-gap-12{gap:var(--canon-space-12)}.xs\:cu-gap-13{gap:var(--canon-space-13)}.xs\:cu-gap-14{gap:var(--canon-space-14)}}@media (width>=768px){.sm\:cu-gap{gap:var(--gap-sm)}.sm\:cu-gap-0\.5{gap:var(--canon-space-0_5)}.sm\:cu-gap-1{gap:var(--canon-space-1)}.sm\:cu-gap-1\.5{gap:var(--canon-space-1_5)}.sm\:cu-gap-2{gap:var(--canon-space-2)}.sm\:cu-gap-3{gap:var(--canon-space-3)}.sm\:cu-gap-4{gap:var(--canon-space-4)}.sm\:cu-gap-5{gap:var(--canon-space-5)}.sm\:cu-gap-6{gap:var(--canon-space-6)}.sm\:cu-gap-7{gap:var(--canon-space-7)}.sm\:cu-gap-8{gap:var(--canon-space-8)}.sm\:cu-gap-9{gap:var(--canon-space-9)}.sm\:cu-gap-10{gap:var(--canon-space-10)}.sm\:cu-gap-11{gap:var(--canon-space-11)}.sm\:cu-gap-12{gap:var(--canon-space-12)}.sm\:cu-gap-13{gap:var(--canon-space-13)}.sm\:cu-gap-14{gap:var(--canon-space-14)}}@media (width>=1024px){.md\:cu-gap{gap:var(--gap-md)}.md\:cu-gap-0\.5{gap:var(--canon-space-0_5)}.md\:cu-gap-1{gap:var(--canon-space-1)}.md\:cu-gap-1\.5{gap:var(--canon-space-1_5)}.md\:cu-gap-2{gap:var(--canon-space-2)}.md\:cu-gap-3{gap:var(--canon-space-3)}.md\:cu-gap-4{gap:var(--canon-space-4)}.md\:cu-gap-5{gap:var(--canon-space-5)}.md\:cu-gap-6{gap:var(--canon-space-6)}.md\:cu-gap-7{gap:var(--canon-space-7)}.md\:cu-gap-8{gap:var(--canon-space-8)}.md\:cu-gap-9{gap:var(--canon-space-9)}.md\:cu-gap-10{gap:var(--canon-space-10)}.md\:cu-gap-11{gap:var(--canon-space-11)}.md\:cu-gap-12{gap:var(--canon-space-12)}.md\:cu-gap-13{gap:var(--canon-space-13)}.md\:cu-gap-14{gap:var(--canon-space-14)}}@media (width>=1280px){.lg\:cu-gap{gap:var(--gap-lg)}.lg\:cu-gap-0\.5{gap:var(--canon-space-0_5)}.lg\:cu-gap-1{gap:var(--canon-space-1)}.lg\:cu-gap-1\.5{gap:var(--canon-space-1_5)}.lg\:cu-gap-2{gap:var(--canon-space-2)}.lg\:cu-gap-3{gap:var(--canon-space-3)}.lg\:cu-gap-4{gap:var(--canon-space-4)}.lg\:cu-gap-5{gap:var(--canon-space-5)}.lg\:cu-gap-6{gap:var(--canon-space-6)}.lg\:cu-gap-7{gap:var(--canon-space-7)}.lg\:cu-gap-8{gap:var(--canon-space-8)}.lg\:cu-gap-9{gap:var(--canon-space-9)}.lg\:cu-gap-10{gap:var(--canon-space-10)}.lg\:cu-gap-11{gap:var(--canon-space-11)}.lg\:cu-gap-12{gap:var(--canon-space-12)}.lg\:cu-gap-13{gap:var(--canon-space-13)}.lg\:cu-gap-14{gap:var(--canon-space-14)}}@media (width>=1536px){.xl\:cu-gap{gap:var(--gap-xl)}.xl\:cu-gap-0\.5{gap:var(--canon-space-0_5)}.xl\:cu-gap-1{gap:var(--canon-space-1)}.xl\:cu-gap-1\.5{gap:var(--canon-space-1_5)}.xl\:cu-gap-2{gap:var(--canon-space-2)}.xl\:cu-gap-3{gap:var(--canon-space-3)}.xl\:cu-gap-4{gap:var(--canon-space-4)}.xl\:cu-gap-5{gap:var(--canon-space-5)}.xl\:cu-gap-6{gap:var(--canon-space-6)}.xl\:cu-gap-7{gap:var(--canon-space-7)}.xl\:cu-gap-8{gap:var(--canon-space-8)}.xl\:cu-gap-9{gap:var(--canon-space-9)}.xl\:cu-gap-10{gap:var(--canon-space-10)}.xl\:cu-gap-11{gap:var(--canon-space-11)}.xl\:cu-gap-12{gap:var(--canon-space-12)}.xl\:cu-gap-13{gap:var(--canon-space-13)}.xl\:cu-gap-14{gap:var(--canon-space-14)}}.cu-align-start{align-items:start}.cu-align-center{align-items:center}.cu-align-end{align-items:end}.cu-align-stretch{align-items:stretch}.cu-jc-start{justify-content:start}.cu-jc-center{justify-content:center}.cu-jc-end{justify-content:end}.cu-jc-between{justify-content:space-between}.cu-fd-row{flex-direction:row}.cu-fd-column{flex-direction:column}.cu-fd-row-reverse{flex-direction:row-reverse}.cu-fd-column-reverse{flex-direction:column-reverse}@media (width>=640px){.xs\:cu-align-start{align-items:start}.xs\:cu-align-center{align-items:center}.xs\:cu-align-end{align-items:end}.xs\:cu-align-stretch{align-items:stretch}.xs\:cu-jc-start{justify-content:start}.xs\:cu-jc-center{justify-content:center}.xs\:cu-jc-end{justify-content:end}.xs\:cu-jc-between{justify-content:space-between}.xs\:cu-fd-row{flex-direction:row}.xs\:cu-fd-column{flex-direction:column}.xs\:cu-fd-row-reverse{flex-direction:row-reverse}.xs\:cu-fd-column-reverse{flex-direction:column-reverse}}@media (width>=768px){.sm\:cu-align-start{align-items:start}.sm\:cu-align-center{align-items:center}.sm\:cu-align-end{align-items:end}.sm\:cu-align-stretch{align-items:stretch}.sm\:cu-jc-start{justify-content:start}.sm\:cu-jc-center{justify-content:center}.sm\:cu-jc-end{justify-content:end}.sm\:cu-jc-between{justify-content:space-between}.sm\:cu-fd-row{flex-direction:row}.sm\:cu-fd-column{flex-direction:column}.sm\:cu-fd-row-reverse{flex-direction:row-reverse}.sm\:cu-fd-column-reverse{flex-direction:column-reverse}}@media (width>=1024px){.md\:cu-align-start{align-items:start}.md\:cu-align-center{align-items:center}.md\:cu-align-end{align-items:end}.md\:cu-align-stretch{align-items:stretch}.md\:cu-jc-start{justify-content:start}.md\:cu-jc-center{justify-content:center}.md\:cu-jc-end{justify-content:end}.md\:cu-jc-between{justify-content:space-between}.md\:cu-fd-row{flex-direction:row}.md\:cu-fd-column{flex-direction:column}.md\:cu-fd-row-reverse{flex-direction:row-reverse}.md\:cu-fd-column-reverse{flex-direction:column-reverse}}@media (width>=1280px){.lg\:cu-align-start{align-items:start}.lg\:cu-align-center{align-items:center}.lg\:cu-align-end{align-items:end}.lg\:cu-align-stretch{align-items:stretch}.lg\:cu-jc-start{justify-content:start}.lg\:cu-jc-center{justify-content:center}.lg\:cu-jc-end{justify-content:end}.lg\:cu-jc-between{justify-content:space-between}.lg\:cu-fd-row{flex-direction:row}.lg\:cu-fd-column{flex-direction:column}.lg\:cu-fd-row-reverse{flex-direction:row-reverse}.lg\:cu-fd-column-reverse{flex-direction:column-reverse}}@media (width>=1536px){.xl\:cu-align-start{align-items:start}.xl\:cu-align-center{align-items:center}.xl\:cu-align-end{align-items:end}.xl\:cu-align-stretch{align-items:stretch}.xl\:cu-jc-start{justify-content:start}.xl\:cu-jc-center{justify-content:center}.xl\:cu-jc-end{justify-content:end}.xl\:cu-jc-between{justify-content:space-between}.xl\:cu-fd-row{flex-direction:row}.xl\:cu-fd-column{flex-direction:column}.xl\:cu-fd-row-reverse{flex-direction:row-reverse}.xl\:cu-fd-column-reverse{flex-direction:column-reverse}}:where(a){color:inherit;text-decoration:none}:root{--canon-font-regular:system-ui;--canon-font-monospace:ui-monospace,"Menlo","Monaco","Consolas","Liberation Mono","Courier New",monospace;--canon-font-weight-regular:400;--canon-font-weight-bold:600;--canon-font-size-1:.625rem;--canon-font-size-2:.75rem;--canon-font-size-3:.875rem;--canon-font-size-4:1rem;--canon-font-size-5:1.25rem;--canon-font-size-6:1.5rem;--canon-font-size-7:2rem;--canon-font-size-8:3rem;--canon-font-size-9:4rem;--canon-font-size-10:5.75rem;--canon-space:.25rem;--canon-space-0_5:calc(var(--canon-space)*.5);--canon-space-1:var(--canon-space);--canon-space-1_5:calc(var(--canon-space)*1.5);--canon-space-2:calc(var(--canon-space)*2);--canon-space-3:calc(var(--canon-space)*3);--canon-space-4:calc(var(--canon-space)*4);--canon-space-5:calc(var(--canon-space)*5);--canon-space-6:calc(var(--canon-space)*6);--canon-space-7:calc(var(--canon-space)*7);--canon-space-8:calc(var(--canon-space)*8);--canon-space-9:calc(var(--canon-space)*9);--canon-space-10:calc(var(--canon-space)*10);--canon-space-11:calc(var(--canon-space)*11);--canon-space-12:calc(var(--canon-space)*12);--canon-space-13:calc(var(--canon-space)*13);--canon-space-14:calc(var(--canon-space)*14);--canon-radius-1:calc(.125rem);--canon-radius-2:calc(.25rem);--canon-radius-3:calc(.5rem);--canon-radius-4:calc(.75rem);--canon-radius-5:calc(1rem);--canon-radius-6:calc(1.25rem);--canon-radius-full:9999px;--canon-black:#000;--canon-white:#fff;--canon-gray-1:#f8f8f8;--canon-gray-2:#ececec;--canon-gray-3:#d9d9d9;--canon-gray-4:#c1c1c1;--canon-gray-5:#9e9e9e;--canon-gray-6:#8c8c8c;--canon-gray-7:#757575;--canon-gray-8:#595959;--canon-bg:var(--canon-gray-1);--canon-bg-surface-1:var(--canon-white);--canon-bg-surface-2:var(--canon-gray-2);--canon-bg-solid:#1f5493;--canon-bg-solid-hover:#163a66;--canon-bg-solid-pressed:#0f2b4e;--canon-bg-solid-disabled:#ebebeb;--canon-bg-tint:transparent;--canon-bg-tint-hover:#1f549366;--canon-bg-tint-pressed:#1f549399;--canon-bg-tint-disabled:#ebebeb;--canon-bg-danger:#feebe7;--canon-bg-warning:#fff2b2;--canon-bg-success:#e6f6eb;--canon-fg-primary:var(--canon-black);--canon-fg-secondary:var(--canon-gray-7);--canon-fg-link:#1f5493;--canon-fg-link-hover:#1f2d5c;--canon-fg-disabled:#9e9e9e;--canon-fg-solid:var(--canon-white);--canon-fg-solid-disabled:#9c9c9c;--canon-fg-tint:#1f5493;--canon-fg-tint-disabled:var(--canon-gray-5);--canon-fg-danger:#e22b2b;--canon-fg-warning:#e36d05;--canon-fg-success:#1db954;--canon-border:#0000001a;--canon-border-hover:#0003;--canon-border-pressed:#0006;--canon-border-disabled:#0000001a;--canon-border-danger:#f87a7a;--canon-border-warning:#e36d05;--canon-border-success:#53db83;--canon-ring:#1f5493;--canon-scrollbar:#a0a0a03b;--canon-scrollbar-thumb:#a0a0a0}[data-theme=dark]{--canon-gray-1:#191919;--canon-gray-2:#242424;--canon-gray-3:#373737;--canon-gray-4:#464646;--canon-gray-5:#575757;--canon-gray-6:#7b7b7b;--canon-gray-7:#9e9e9e;--canon-gray-8:#b4b4b4;--canon-bg:var(--canon-black);--canon-bg-surface-1:var(--canon-gray-1);--canon-bg-surface-2:var(--canon-gray-2);--canon-bg-solid:#9cc9ff;--canon-bg-solid-hover:#83b9fd;--canon-bg-solid-pressed:#83b9fd;--canon-bg-solid-disabled:#222;--canon-bg-tint:transparent;--canon-bg-tint-hover:#9cc9ff1f;--canon-bg-tint-pressed:#9cc9ff29;--canon-bg-tint-disabled:transparent;--canon-bg-danger:#3b1219;--canon-bg-warning:#302008;--canon-bg-success:#132d21;--canon-fg-primary:var(--canon-white);--canon-fg-secondary:var(--canon-gray-7);--canon-fg-link:#9cc9ff;--canon-fg-link-hover:#7eb5f7;--canon-fg-disabled:var(--canon-gray-7);--canon-fg-solid:#101821;--canon-fg-solid-disabled:var(--canon-gray-5);--canon-fg-tint:#9cc9ff;--canon-fg-tint-disabled:var(--canon-gray-5);--canon-fg-danger:#e22b2b;--canon-fg-warning:#e36d05;--canon-fg-success:#1db954;--canon-border:#fff3;--canon-border-hover:#fff6;--canon-border-pressed:#ffffff80;--canon-border-disabled:#fff3;--canon-border-danger:#f87a7a;--canon-border-warning:#e36d05;--canon-border-success:#53db83;--canon-ring:#1f5493;--canon-scrollbar:#3636363a;--canon-scrollbar-thumb:#575757}.canon-AvatarRoot{vertical-align:middle;user-select:none;color:var(--canon-fg-primary);background-color:var(--canon-bg-surface-2);border-radius:100%;justify-content:center;align-items:center;width:2rem;height:2rem;font-size:1rem;font-weight:500;line-height:1;display:inline-flex;overflow:hidden}.canon-AvatarRoot[data-size=small]{width:1.5rem;height:1.5rem}.canon-AvatarRoot[data-size=medium]{width:2rem;height:2rem}.canon-AvatarRoot[data-size=large]{width:3rem;height:3rem}.canon-AvatarImage{object-fit:cover;width:100%;height:100%}.canon-AvatarFallback{width:100%;height:100%;font-size:var(--canon-font-size-3);font-weight:var(--canon-font-weight-regular);box-shadow:inset 0 0 0 1px var(--canon-border);border-radius:var(--canon-radius-full);justify-content:center;align-items:center;display:flex}.canon-Box{font-family:var(--canon-font-regular);font-weight:var(--canon-font-weight-regular);color:var(--canon-fg-primary)}.canon-Button{user-select:none;font-family:var(--canon-font-regular);font-weight:var(--canon-font-weight-bold);cursor:pointer;border-radius:var(--canon-radius-2);justify-content:center;align-items:center;gap:var(--canon-space-1_5);border:none;padding:0;display:inline-flex;&:disabled{cursor:not-allowed}}.canon-Button[data-variant=primary]{background-color:var(--canon-bg-solid);color:var(--canon-fg-solid);transition:background-color .15s,box-shadow .15s;&:hover{background-color:var(--canon-bg-solid-hover)}&:active{background-color:var(--canon-bg-solid-pressed)}&:focus-visible{outline:2px solid var(--canon-ring);outline-offset:2px}&:disabled{background-color:var(--canon-bg-solid-disabled);color:var(--canon-fg-solid-disabled)}}.canon-Button[data-variant=secondary]{background-color:var(--canon-bg-surface-1);box-shadow:inset 0 0 0 1px var(--canon-border);color:var(--canon-fg-primary);transition:box-shadow .15s;&:hover{box-shadow:inset 0 0 0 1px var(--canon-border-hover)}&:active{box-shadow:inset 0 0 0 1px var(--canon-border-pressed)}&:focus-visible{box-shadow:inset 0 0 0 2px var(--canon-ring);outline:none;transition:none}&:disabled{box-shadow:inset 0 0 0 1px var(--canon-border-disabled);color:var(--canon-fg-disabled)}}.canon-Button[data-size=medium]{font-size:var(--canon-font-size-4);padding:0 var(--canon-space-3);height:2.5rem}.canon-Button[data-size=small]{font-size:var(--canon-font-size-3);padding:0 var(--canon-space-2);height:2rem}.canon-Button[data-size=small] svg{width:1rem;height:1rem}.canon-Button[data-size=medium] svg{width:1.25rem;height:1.25rem}.canon-ButtonIcon{justify-content:center;align-items:center}.canon-ButtonIcon[data-size=small]{width:2rem;padding:0}.canon-ButtonIcon[data-size=medium]{width:2.5rem;padding:0}.canon-CheckboxRoot{width:1rem;height:1rem;box-shadow:inset 0 0 0 1px var(--canon-border);cursor:pointer;background-color:var(--canon-bg-surface-1);border:none;border-radius:2px;flex-shrink:0;justify-content:center;align-items:center;padding:0;transition:background-color .2s ease-in-out;display:flex}.canon-CheckboxRoot:focus-visible{outline:2px solid var(--canon-ring);outline-offset:2px;transition:none}.canon-CheckboxRoot[data-checked]{background-color:var(--canon-bg-solid);box-shadow:none;color:var(--canon-fg-solid)}.canon-CheckboxLabel{align-items:center;gap:var(--canon-space-2);font-size:var(--canon-font-size-3);font-family:var(--canon-font-regular);font-weight:var(--canon-font-weight-regular);color:var(--canon-fg-primary);user-select:none;flex-direction:row;display:flex;&:hover{& .canon-CheckboxRoot:not([data-checked]){box-shadow:inset 0 0 0 1px var(--canon-border-hover)}}}.canon-CheckboxIndicator{color:var(--canon-fg-solid);justify-content:center;align-items:center;display:flex}.canon-CollapsiblePanel{height:var(--collapsible-panel-height);transition:all .15s ease-out;display:flex;overflow:hidden;&[data-starting-style],&[data-ending-style]{height:0}}.canon-Container{max-width:120rem;padding-inline:var(--canon-space-4);margin-inline:auto;transition:padding .2s ease-in-out}@media (width>=640px){.canon-Container{padding-inline:var(--canon-space-8)}}@media (width>=1024px){.canon-Container{padding-inline:var(--canon-space-12)}}.canon-DataTableRoot{gap:var(--canon-space-3);flex-direction:column;display:flex}.canon-DataTablePagination{padding-top:var(--canon-space-5);justify-content:space-between;align-items:center;display:flex}.canon-DataTablePagination--left{justify-content:space-between;align-items:center;display:flex}.canon-DataTablePagination--right{justify-content:space-between;align-items:center;gap:var(--canon-space-2);display:flex}.canon-DataTablePagination--select{min-width:10.5rem}.canon-FieldError{color:var(--canon-fg-danger);font-size:var(--canon-font-size-2);font-weight:var(--canon-font-weight-regular);margin-top:var(--canon-space-2)}.canon-FieldLabelWrapper{margin-bottom:var(--canon-space-3);gap:var(--canon-space-1);flex-direction:column;display:flex}.canon-FieldLabel{color:var(--canon-fg-primary);cursor:pointer;font-weight:var(--canon-font-weight-regular);font-size:var(--canon-font-size-2);margin-right:auto}.canon-FieldSecondaryLabel{color:var(--canon-fg-secondary);font-weight:var(--canon-font-weight-regular);margin-left:var(--canon-space-1)}.canon-FieldDescription{font-weight:var(--canon-font-weight-regular);font-size:var(--canon-font-size-2);color:var(--canon-fg-secondary);margin:0}.canon-Flex{min-width:0;display:flex}.canon-Grid{display:grid}.canon-Heading{font-family:var(--canon-font-regular);color:var(--canon-fg-primary);margin:0;padding:0;line-height:100%}.canon-Heading[data-variant=display]{font-size:var(--canon-font-size-10);font-weight:var(--canon-font-weight-bold)}.canon-Heading[data-variant=title1]{font-size:var(--canon-font-size-9);font-weight:var(--canon-font-weight-bold)}.canon-Heading[data-variant=title2]{font-size:var(--canon-font-size-8);font-weight:var(--canon-font-weight-bold)}.canon-Heading[data-variant=title3]{font-size:var(--canon-font-size-7);font-weight:var(--canon-font-weight-bold)}.canon-Heading[data-variant=title4]{font-size:var(--canon-font-size-6);font-weight:var(--canon-font-weight-bold)}.canon-Heading[data-variant=title5]{font-size:var(--canon-font-size-5);font-weight:var(--canon-font-weight-bold)}.canon-Heading[data-color=primary]{color:var(--canon-fg-primary)}.canon-Heading[data-color=secondary]{color:var(--canon-fg-secondary)}.canon-Heading[data-truncate]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.canon-Icon{width:1rem;height:1rem}.canon-Link{font-family:var(--canon-font-regular);color:var(--canon-fg-link);cursor:pointer;margin:0;padding:0;text-decoration-line:none;&:hover{color:var(--canon-fg-link-hover);text-underline-offset:calc(.025em + 2px);text-decoration-line:underline;text-decoration-style:solid;text-decoration-thickness:min(2px,max(1px,.05em));text-decoration-color:color-mix(in srgb,var(--canon-fg-link-hover)30%,transparent)}}.canon-Link[data-variant=body]{font-size:var(--canon-font-size-3);line-height:140%}.canon-Link[data-variant=subtitle]{font-size:var(--canon-font-size-4);line-height:140%}.canon-Link[data-variant=caption]{font-size:var(--canon-font-size-2);line-height:140%}.canon-Link[data-variant=label]{font-size:var(--canon-font-size-1);line-height:140%}.canon-Link[data-weight=regular]{font-weight:var(--canon-font-weight-regular)}.canon-Link[data-weight=bold]{font-weight:var(--canon-font-weight-bold)}.canon-MenuPositioner{outline:0}.canon-MenuPopup{background-color:var(--canon-bg-surface-1);border:1px solid var(--canon-border);color:var(--canon-fg-primary);transform-origin:var(--transform-origin);max-width:min(var(--available-width),340px);max-height:min(var(--available-height),500px);padding-bottom:var(--canon-space-1);border-radius:.375rem;outline:none;flex-direction:column;transition:transform .15s,opacity .15s;display:flex;position:relative;overflow:auto;&[data-starting-style],&[data-ending-style]{opacity:0;transform:scale(.9)}}.canon-MenuItem{user-select:none;align-items:center;gap:var(--canon-space-2);height:32px;color:var(--canon-fg-primary);border-radius:var(--canon-radius-2);margin-inline:var(--canon-space-1);padding-inline:var(--canon-space-2);font-size:var(--canon-font-size-3);cursor:pointer;outline:0;flex-shrink:0;text-decoration:none;display:flex;&:first-child{margin-top:var(--canon-space-1)}&[data-highlighted]{background-color:var(--canon-gray-3)}}.canon-MenuSubmenuTrigger{user-select:none;justify-content:space-between;align-items:center;gap:var(--canon-space-2);height:32px;color:var(--canon-fg-primary);border-radius:var(--canon-radius-2);margin-inline:var(--canon-space-1);padding-inline:var(--canon-space-2);font-size:var(--canon-font-size-3);cursor:pointer;outline:0;flex-shrink:0;text-decoration:none;display:flex;& .canon-Icon{color:var(--canon-fg-secondary)}&:first-child{margin-top:var(--canon-space-1)}&[data-popup-open],&[data-highlighted]{background-color:var(--canon-gray-3);& .canon-Icon{color:var(--canon-fg-primary)}}}.canon-MenuSeparator{background-color:var(--color-gray-200);height:1px;margin:.375rem 1rem}.canon-SubmenuComboboxSearch{padding-inline:var(--canon-space-3);border:none;border-bottom:1px solid var(--canon-border);background-color:var(--canon-bg-surface-1);width:100%;height:32px;color:var(--canon-fg-primary);line-height:140%;font-size:var(--canon-font-size-3);z-index:1;outline:none;position:sticky;top:0;&::placeholder{color:var(--canon-fg-secondary)}&:disabled{opacity:.6;cursor:not-allowed}}.canon-SubmenuComboboxItems{padding-top:var(--canon-space-2);outline:none;flex-direction:column;display:flex;overflow-y:auto}.canon-SubmenuComboboxNoResults{padding-inline:var(--canon-space-3);padding-top:var(--canon-space-2);padding-bottom:var(--canon-space-4);color:var(--canon-fg-secondary);font-size:var(--canon-font-size-3)}.canon-SubmenuComboboxItem{user-select:none;justify-content:space-between;align-items:center;gap:var(--canon-space-2);height:32px;color:var(--canon-fg-primary);border-radius:var(--canon-radius-2);margin-inline:var(--canon-space-1);padding-inline:var(--canon-space-2);font-size:var(--canon-font-size-3);cursor:pointer;outline:0;flex-shrink:0;text-decoration:none;display:flex;&[data-highlighted]{background-color:var(--canon-gray-3)}&[data-disabled]{opacity:.5;cursor:not-allowed}}.canon-SubmenuComboboxItemCheckbox{width:16px;height:16px;color:var(--canon-fg-primary);border-radius:var(--canon-radius-2);border:1px solid var(--canon-border);background:var(--canon-bg-surface-1);flex-shrink:0;justify-content:center;align-items:center;display:flex}.canon-SubmenuComboboxItemLabel{text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.canon-RadioGroup{color:var(--canon-fg-primary);flex-direction:column;display:flex}.canon-RadioGroup[data-orientation=horizontal] .canon-RadioGroupContent{gap:var(--canon-space-4);flex-direction:row}.canon-RadioGroupContent{gap:var(--canon-space-2);flex-direction:column;display:flex}.canon-Radio{align-items:center;gap:var(--canon-space-2);font-size:var(--canon-font-size-2);color:var(--canon-fg-primary);forced-color-adjust:none;display:flex;position:relative;&:before{content:"";box-sizing:border-box;border:.125rem solid var(--canon-border);background:var(--canon-gray-1);border-radius:var(--canon-radius-full);width:1rem;height:1rem;transition:all .2s;display:block}&[data-pressed]:before{border-color:var(--canon-border)}&[data-selected]{&:before{border-color:var(--canon-bg-solid);border-width:.25rem}&[data-pressed]:before{border-color:var(--canon-bg-solid)}}&[data-focus-visible]:before{outline:2px solid var(--canon-ring);outline-offset:2px}&[data-disabled]{cursor:not-allowed;color:var(--canon-fg-disabled);&:before{border-color:var(--canon-border-disabled);background:var(--canon-bg-disabled)}&[data-selected]:before{border-color:var(--canon-border-disabled)}}&[data-invalid]:before,&[data-invalid][data-selected]:before{border-color:var(--canon-border-danger)}&[data-disabled][data-invalid]{color:var(--canon-fg-disabled);&:before{border-color:var(--canon-border-disabled);background:var(--canon-bg-disabled)}&[data-selected]:before{border-color:var(--canon-border-disabled)}}}.canon-TableRoot{caption-side:bottom;border-collapse:collapse;width:100%}.canon-TableHead{text-align:left;padding:var(--canon-space-3);font-size:var(--canon-font-size-3);color:var(--canon-fg-primary)}.canon-TableBody{color:var(--canon-fg-primary)}.canon-TableRow{border-bottom:1px solid var(--canon-border);transition:color .2s ease-in-out}.canon-TableBody .canon-TableRow:hover{background-color:var(--canon-gray-2)}.canon-TableCell{padding:var(--canon-space-3);font-size:var(--canon-font-size-3)}.canon-TableCellText,.canon-TableCellLink{gap:var(--canon-space-0_5);flex-direction:column;display:flex}.canon-TableCellProfile{gap:var(--canon-space-2);flex-direction:row;align-items:center;display:flex}.canon-TableCellProfileAvatar{vertical-align:middle;user-select:none;color:var(--canon-fg-primary);background-color:var(--canon-bg-surface-2);border-radius:100%;justify-content:center;align-items:center;width:1.25rem;height:1.25rem;font-size:1rem;font-weight:500;line-height:1;display:inline-flex;overflow:hidden}.canon-TableCellProfileAvatarImage{object-fit:cover;width:100%;height:100%}.canon-TableCellProfileAvatarFallback{width:100%;height:100%;font-size:var(--canon-font-size-2);font-weight:var(--canon-font-weight-regular);box-shadow:inset 0 0 0 1px var(--canon-border);border-radius:var(--canon-radius-full);justify-content:center;align-items:center;display:flex}.canon-TabsRoot{border:1px solid var(--color-gray-200);border-radius:.375rem}.canon-TabsList{z-index:0;display:flex;position:relative}.canon-TabsTab{appearance:none;color:var(--canon-fg-secondary);user-select:none;padding-inline:var(--canon-space-3);height:2rem;font-family:inherit;font-size:.875rem;font-weight:500;line-height:1.25rem;font-size:var(--canon-font-size-2);cursor:pointer;background:0 0;border:0;outline:0;justify-content:center;align-items:center;margin:0;padding-block:0;transition:color .2s ease-in-out;display:flex;&[data-selected]{color:var(--canon-fg-primary)}@media (hover:hover){&:hover{color:var(--canon-fg-primary)}}&:focus-visible{position:relative;&:before{content:"";outline:1px solid var(--canon-ring);outline-offset:-1px;border-radius:.25rem;position:absolute;inset:.25rem 0}}}.canon-TabsIndicator{z-index:-1;translate:var(--active-tab-left)-50%;width:var(--active-tab-width);background-color:var(--canon-bg-solid);height:1px;transition-property:translate,width;transition-duration:.2s;transition-timing-function:ease-in-out;position:absolute;bottom:0;left:0}.canon-TabsPanel{&[hidden]{display:none}}.canon-Text{font-family:var(--canon-font-regular);margin:0;padding:0}.canon-Text[data-variant=body]{font-size:var(--canon-font-size-3);line-height:140%}.canon-Text[data-variant=subtitle]{font-size:var(--canon-font-size-4);line-height:140%}.canon-Text[data-variant=caption]{font-size:var(--canon-font-size-2);line-height:140%}.canon-Text[data-variant=label]{font-size:var(--canon-font-size-1);line-height:140%}.canon-Text[data-weight=regular]{font-weight:var(--canon-font-weight-regular)}.canon-Text[data-weight=bold]{font-weight:var(--canon-font-weight-bold)}.canon-Text[data-color=primary]{color:var(--canon-fg-primary)}.canon-Text[data-color=secondary]{color:var(--canon-fg-secondary)}.canon-Text[data-color=danger]{color:var(--canon-fg-danger)}.canon-Text[data-color=warning]{color:var(--canon-fg-warning)}.canon-Text[data-color=success]{color:var(--canon-fg-success)}.canon-Text[data-truncate]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.canon-TextField{font-family:var(--canon-font-regular);flex-direction:column;width:100%;display:flex}.canon-InputWrapper{position:relative;&[data-size=small] .canon-Input{height:2rem}&[data-size=medium] .canon-Input{height:2.5rem}&[data-size=small] .canon-Input[data-icon]{padding-left:var(--canon-space-8)}&[data-size=medium] .canon-Input[data-icon]{padding-left:var(--canon-space-9)}}.canon-InputIcon{left:var(--canon-space-3);margin-right:var(--canon-space-1);color:var(--canon-fg-primary);flex-shrink:0;position:absolute;top:50%;transform:translateY(-50%);&[data-size=small],&[data-size=small] svg{width:1rem;height:1rem}&[data-size=medium],&[data-size=medium] svg{width:1.25rem;height:1.25rem}}.canon-Input{padding:0 var(--canon-space-3);border-radius:var(--canon-radius-3);border:1px solid var(--canon-border);background-color:var(--canon-bg-surface-1);font-size:var(--canon-font-size-3);font-family:var(--canon-font-regular);font-weight:var(--canon-font-weight-regular);color:var(--canon-fg-primary);width:100%;height:100%;cursor:inherit;align-items:center;transition:border-color .2s ease-in-out,outline-color .2s ease-in-out;display:flex;&::-webkit-search-cancel-button,&::-webkit-search-decoration{-webkit-appearance:none}&::placeholder{color:var(--canon-fg-secondary)}&[data-focused]{outline-color:var(--canon-border-pressed);outline-width:0}&[data-hovered]{border-color:var(--canon-border-hover)}&[data-focused]{border-color:var(--canon-border-pressed);outline-width:0}&[data-invalid]{border-color:var(--canon-fg-danger)}&[data-disabled]{opacity:.5;cursor:not-allowed;border:1px solid var(--canon-border-disabled)}}.canon-SearchField[data-empty] .canon-InputClear{display:none}.canon-InputClear{cursor:pointer;color:var(--canon-fg-secondary);background-color:#0000;border:none;justify-content:center;align-items:center;margin:0;padding:0;transition:color .2s ease-in-out;display:flex;position:absolute;top:0;bottom:0;right:0}.canon-InputClear:hover{color:var(--canon-fg-primary)}.canon-InputClear[data-size=small]{width:2rem;height:2rem}.canon-InputClear[data-size=medium]{width:2.5rem;height:2.5rem}.canon-InputClear svg{width:1rem;height:1rem}.canon-TooltipPopup{box-sizing:border-box;transform-origin:var(--transform-origin);background-color:canvas;background-color:var(--canon-bg-surface-1);color:var(--canon-fg-primary);outline:1px solid var(--canon-border);box-shadow:0 10px 15px -3px var(--canon-border),0 4px 6px -4px var(--canon-border);border-radius:.375rem;flex-direction:column;padding:.25rem .5rem;font-size:.875rem;line-height:1.25rem;transition:transform .15s,opacity .15s;display:flex;&[data-starting-style],&[data-ending-style]{opacity:0;transform:scale(.9)}&[data-instant]{transition-duration:0s}}.canon-TooltipArrow{display:flex;&[data-side=top]{bottom:-8px;rotate:180deg}&[data-side=bottom]{top:-8px;rotate:none}&[data-side=left]{right:-13px;rotate:90deg}&[data-side=right]{left:-13px;rotate:-90deg}}.canon-TooltipArrow-fill{fill:var(--canon-bg-surface-1)}.canon-TooltipArrow-outer-stroke{@media (prefers-color-scheme:light){fill:var(--canon-border)}}.canon-ScrollAreaRoot{box-sizing:border-box;width:24rem;max-width:calc(100vw - 8rem);height:8.5rem}.canon-ScrollAreaViewport{overscroll-behavior:contain;height:100%}.canon-ScrollAreaContent{padding-block:.75rem;flex-direction:column;gap:1rem;padding-left:1rem;padding-right:1.5rem;display:flex}.canon-ScrollAreaScrollbar{background-color:var(--canon-scrollbar);opacity:0;border-radius:.375rem;justify-content:center;width:.25rem;margin:.5rem;transition:opacity .15s .3s;display:flex;&[data-hovering],&[data-scrolling]{opacity:1;transition-duration:75ms;transition-delay:0s}&:before{content:"";width:1.25rem;height:100%;position:absolute}}.canon-ScrollAreaThumb{border-radius:inherit;background-color:var(--canon-scrollbar-thumb);width:100%}.canon-Select{font-family:var(--canon-font-regular);flex-direction:column;width:100%;display:flex}.canon-SelectLabel{font-size:var(--canon-font-size-2);font-weight:var(--canon-font-weight-regular);color:var(--canon-fg-primary);margin-bottom:var(--canon-space-1_5);cursor:pointer}.canon-SelectLabel[data-disabled]{cursor:default}.canon-SelectDescription{font-size:var(--canon-font-size-2);font-weight:var(--canon-font-weight-regular);color:var(--canon-fg-secondary);padding-top:var(--canon-space-1_5);margin:0}.canon-SelectError{font-size:var(--canon-font-size-2);font-weight:var(--canon-font-weight-regular);color:var(--canon-fg-danger);padding-top:var(--canon-space-1_5);margin:0}.canon-SelectTrigger{box-sizing:border-box;border-radius:var(--canon-radius-3);border:1px solid var(--canon-border);padding:0 var(--canon-space-4);background-color:var(--canon-bg-surface-1);font-size:var(--canon-font-size-3);font-family:var(--canon-font-regular);font-weight:var(--canon-font-weight-regular);color:var(--canon-fg-primary);cursor:pointer;justify-content:space-between;align-items:center;gap:var(--canon-space-2);width:100%;transition:border-color .2s ease-in-out,outline-color .2s ease-in-out;display:flex}.canon-SelectTrigger::placeholder{color:var(--canon-fg-secondary)}.canon-SelectTrigger:hover{border-color:var(--canon-border-hover)}.canon-SelectTrigger:focus-visible{border-color:var(--canon-border-pressed);outline:0}.canon-SelectTrigger[data-invalid]{border-color:var(--canon-fg-danger)}.canon-SelectTrigger[data-invalid]:hover,.canon-SelectTrigger[data-invalid]:focus-visible{border-width:2px}.canon-SelectTrigger[data-disabled]{cursor:not-allowed;border-color:var(--canon-border-disabled);color:var(--canon-fg-disabled)}.canon-SelectTrigger[data-size=small]{height:2rem}.canon-SelectTrigger[data-size=medium]{height:3rem}.canon-SelectIcon{margin-left:var(--canon-space-5);transition:transform .2s}.canon-SelectTrigger[data-popup-open] .canon-SelectIcon{transform:rotate(180deg)}.canon-SelectPopup{box-sizing:border-box;max-height:var(--available-height);background-color:var(--canon-bg-surface-1);border:1px solid var(--canon-border);border-radius:var(--canon-radius-3);padding-block:var(--canon-space-1);z-index:1;transform-origin:var(--transform-origin);outline:0;transition:transform .15s,opacity .15s;overflow-y:auto;box-shadow:0 4px 12px #0003}.canon-SelectPopup[data-starting-style],.canon-SelectPopup[data-ending-style]{opacity:0;transform:scale(.9)}.canon-SelectItem{width:var(--anchor-width);padding-block:var(--canon-space-2);padding-inline:var(--canon-space-4);color:var(--canon-fg-primary);border-radius:var(--canon-radius-3);cursor:pointer;user-select:none;font-size:var(--canon-font-size-3);align-items:center;gap:var(--canon-space-2);outline:none;grid-template-columns:1rem 1fr;grid-template-areas:"icon text";display:grid;position:relative}.canon-SelectItem[data-highlighted]{z-index:0;color:var(--canon-fg-primary);position:relative}.canon-SelectItem[data-highlighted]:before{content:"";z-index:-1;background-color:var(--canon-bg-tint-hover);border-radius:.25rem;position:absolute;inset-block:0;inset-inline:.25rem}.canon-SelectItem[data-disabled]{cursor:not-allowed;color:var(--canon-fg-disabled)}.canon-SelectItemIndicator{grid-area:icon;justify-content:center;align-items:center;display:flex}.canon-SelectItemText{flex:1;grid-area:text}.canon-SelectRequired{color:var(--canon-fg-secondary);font-size:var(--canon-font-size-2);font-weight:var(--canon-font-weight-regular);margin-left:var(--canon-space-1)}.canon-SelectIcon{justify-content:center;align-items:center;display:flex}.canon-SelectValue{text-overflow:ellipsis;white-space:nowrap;width:100%;overflow:hidden}.canon-Switch{align-items:center;gap:var(--canon-space-3);font-size:var(--canon-font-size-3);color:var(--canon-fg-primary);cursor:pointer;display:flex;position:relative;&[data-pressed] .canon-SwitchIndicator{&:before{background:var(--canon-fg-solid)}}&[data-selected]{& .canon-SwitchIndicator{background:var(--canon-bg-solid);&:before{background:var(--canon-fg-solid);transform:translate(100%)}}&[data-pressed]{& .indicator{background:var(--canon-gray-3)}}}&[data-focus-visible] .canon-SwitchIndicator{outline-offset:2px;outline:2px solid}}.canon-SwitchIndicator{background:var(--canon-gray-3);border:2px;border-radius:1.143rem;width:2rem;height:1.143rem;transition:all .2s;&:before{content:"";background:var(--canon-fg-solid);border-radius:16px;width:.857rem;height:.857rem;margin:.143rem;transition:all .2s;display:block}} \ No newline at end of file diff --git a/canon-docs/scripts/build-css.js b/canon-docs/scripts/build-css.js index dd9775150f..edd80add51 100644 --- a/canon-docs/scripts/build-css.js +++ b/canon-docs/scripts/build-css.js @@ -5,10 +5,8 @@ const { bundle } = require('lightningcss'); const source = '../../packages/canon/src/css'; const destination = '../public'; -const source1 = path.join(__dirname, `${source}/core.css`); -const destination1 = path.join(__dirname, `${destination}/core.css`); -const source2 = path.join(__dirname, `${source}/components.css`); -const destination2 = path.join(__dirname, `${destination}/components.css`); +const source1 = path.join(__dirname, `${source}/styles.css`); +const destination1 = path.join(__dirname, `${destination}/styles.css`); // Function to bundle and copy the CSS file const bundleAndCopyFile = async (source, destination) => { @@ -26,10 +24,7 @@ const bundleAndCopyFile = async (source, destination) => { }; // Initial bundle and copy -Promise.all([ - bundleAndCopyFile(source1, destination1), - bundleAndCopyFile(source2, destination2), -]) +Promise.all([bundleAndCopyFile(source1, destination1)]) .then(() => { // Add an empty line after all operations are complete - It looks better in the terminal :) console.log(''); diff --git a/canon-docs/src/app/(docs)/changelog/page.mdx b/canon-docs/src/app/(docs)/changelog/page.mdx new file mode 100644 index 0000000000..7cc0b2bf3e --- /dev/null +++ b/canon-docs/src/app/(docs)/changelog/page.mdx @@ -0,0 +1,13 @@ +import { Changelog } from '@/components/Changelog'; + +# Changelog + + + +## Version 0.1.0 + +We're excited to share the initial release of Canon 💚 In this first alpha version, +you'll find the foundation of our design system: a set of versatile layout components +and a handful of essential atomic elements to help you get started. While Canon is +still in its early stages, it's ready for exploration and we'd love for you to give +it a try and share your feedback. diff --git a/canon-docs/src/app/(docs)/components/[slug]/page.tsx b/canon-docs/src/app/(docs)/components/[slug]/page.tsx new file mode 100644 index 0000000000..d6f98c8f93 --- /dev/null +++ b/canon-docs/src/app/(docs)/components/[slug]/page.tsx @@ -0,0 +1,25 @@ +import { components, layoutComponents } from '@/utils/data'; + +export default async function Page({ + params, +}: { + params: Promise<{ slug: string }>; +}) { + const { slug } = await params; + + const { default: Component } = await import( + `@/content/components/${slug}.mdx` + ); + + return ; +} + +export function generateStaticParams() { + const list = [...components, ...layoutComponents]; + + return list.map(component => ({ + slug: component.slug, + })); +} + +export const dynamicParams = false; diff --git a/canon-docs/src/app/(docs)/components/avatar/page.mdx b/canon-docs/src/app/(docs)/components/avatar/page.mdx deleted file mode 100644 index b46caf8d62..0000000000 --- a/canon-docs/src/app/(docs)/components/avatar/page.mdx +++ /dev/null @@ -1,75 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { AvatarSnippet } from '@/snippets/stories-snippets'; -import { avatarPropDefs } from './props'; - -# Avatar - -An avatar component with a fallback for initials. - -} - code={``} -/> - - - - Usage - Theming - - - `} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-AvatarRoot` - - `canon-AvatarRoot[data-size='small']` - - `canon-AvatarRoot[data-size='medium']` - - `canon-AvatarRoot[data-size='large']` - - `canon-AvatarImage` - - `canon-AvatarFallback` - - - -## API reference - - - -## Examples - -### Sizes - -Avatar sizes can be set using the `size` prop. - -} - code={` - - - - `} -/> - -### Fallback - -If the image is not available, the avatar will show the initials of the name. - -} - code={``} -/> diff --git a/canon-docs/src/app/(docs)/components/avatar/props.ts b/canon-docs/src/app/(docs)/components/avatar/props.ts deleted file mode 100644 index e86c67a41e..0000000000 --- a/canon-docs/src/app/(docs)/components/avatar/props.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const avatarPropDefs: Record = { - src: { - type: 'string', - }, - name: { - type: 'string', - }, - size: { - type: 'enum', - values: ['small', 'medium', 'large'], - default: 'medium', - responsive: true, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/box/props.ts b/canon-docs/src/app/(docs)/components/box/props.ts deleted file mode 100644 index f3e38984dd..0000000000 --- a/canon-docs/src/app/(docs)/components/box/props.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - classNamePropDefs, - displayPropDefs, - heightPropDefs, - positionPropDefs, - stylePropDefs, - widthPropDefs, -} from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const boxPropDefs: Record = { - as: { - type: 'enum', - values: ['div', 'span'], - default: 'div', - responsive: true, - }, - ...widthPropDefs, - ...heightPropDefs, - ...positionPropDefs, - ...displayPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/button/page.mdx b/canon-docs/src/app/(docs)/components/button/page.mdx deleted file mode 100644 index 3554ee39f9..0000000000 --- a/canon-docs/src/app/(docs)/components/button/page.mdx +++ /dev/null @@ -1,150 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { ButtonSnippet } from '@/snippets/stories-snippets'; -import { buttonVariants } from '@/snippets/code-snippets'; -import { buttonPropDefs } from './props'; - -# Button - -A button component that can be used to trigger actions. - -} - code={` - - - -`} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - - -## Examples - -### Variants - -Here's a view when buttons have different variants. - -} - code={buttonVariants} -/> - -### Sizes - -Here's a view when buttons have different sizes. - -} - code={` - - -`} -/> - -### With Icons - -Here's a view when buttons have icons. - -} - code={` - - - -`} -/> - -### Full width - -Here's a view when buttons are full width. - -} - code={` - -`} -/> - -### Disabled - -Here's a view when buttons are disabled. - -} - code={``} -/> - -### As Link - -Here's a view when buttons are rendered as a link. - -} - code={``} -/> - -### Responsive - -Here's a view when buttons are responsive. - - - Responsive Button - `} -/> diff --git a/canon-docs/src/app/(docs)/components/button/props.ts b/canon-docs/src/app/(docs)/components/button/props.ts deleted file mode 100644 index 36b0f73066..0000000000 --- a/canon-docs/src/app/(docs)/components/button/props.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const buttonPropDefs: Record = { - variant: { - type: 'enum', - values: ['primary', 'secondary'], - default: 'primary', - responsive: true, - }, - size: { - type: 'enum', - values: ['small', 'medium'], - default: 'medium', - responsive: true, - }, - render: { - type: 'enum', - values: ['ReactNode'], - responsive: false, - default: ' - )} /> - - - It's the edge of the world and all of Western civilization - The sun may rise in the East, at least it settled in a final location - It's understood that Hollywood sells Californication - - -`} -/> - - - - Usage - Theming - - - - ( - - )} /> - Your content -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-CollapsibleRoot` - - `canon-CollapsibleTrigger` - - `canon-CollapsiblePanel` - - - -## API reference - -### Collapsible.Root - -Groups all parts of the collapsible. Renders a `
` element. - - - -### Collapsible.Trigger - -The trigger by default render a simple unstyled button. Because menus can be rendered in different ways, we recommend -using the `render` prop to render a custom trigger. - - - )} /> - - - It's the edge of the world and all of Western civilization - The sun may rise in the East, at least it settled in a final location - It's understood that Hollywood sells Californication - - -`} -/> diff --git a/canon-docs/src/app/(docs)/components/collapsible/props.ts b/canon-docs/src/app/(docs)/components/collapsible/props.ts deleted file mode 100644 index 02c62dc89e..0000000000 --- a/canon-docs/src/app/(docs)/components/collapsible/props.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - classNamePropDefs, - stylePropDefs, - renderPropDefs, -} from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const collapsibleRootPropDefs: Record = { - defaultOpen: { - type: 'boolean', - default: 'false', - }, - open: { - type: 'boolean', - }, - onOpenChange: { - type: 'enum', - values: ['(open) => void'], - }, - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const collapsibleTriggerPropDefs: Record = { - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const collapsiblePanelPropDefs: Record = { - hiddenUntilFound: { - type: 'boolean', - default: 'false', - }, - keepMounted: { - type: 'boolean', - default: 'false', - }, - ...renderPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/container/props.ts b/canon-docs/src/app/(docs)/components/container/props.ts deleted file mode 100644 index 4a3410ec12..0000000000 --- a/canon-docs/src/app/(docs)/components/container/props.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { - classNamePropDefs, - stylePropDefs, - gapPropDefs, -} from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const containerPropDefs: Record = { - ...gapPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/flex/page.mdx b/canon-docs/src/app/(docs)/components/flex/page.mdx deleted file mode 100644 index 8150f3e3c5..0000000000 --- a/canon-docs/src/app/(docs)/components/flex/page.mdx +++ /dev/null @@ -1,83 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { - flexFAQ1, - flexSimple, - flexResponsive, - flexAlign, -} from '@/snippets/code-snippets'; -import { Snippet } from '@/components/Snippet'; -import { FlexSnippet } from '@/snippets/stories-snippets'; -import { flexPropDefs } from './props'; -import { spacingPropDefs } from '../../../../utils/propDefs'; - -# Flex - -This is the flex container component. It will help to define the number of -columns that will be used in the grid. You can also define the gap between the -columns. All values are responsive. - -} - code={` - - - -`} -/> - - - - Usage - - - -`} - /> - - - -## API reference - - - -The grid component also accepts all the spacing props from the Box component. - - - -## Common questions - -### Can I stack horizontally? - -The Flex component only allows for stacking elements vertically. If you want -to create a column layout, please use the Grid component. - - - -## Examples - -### Simple - -A simple example of how to use the Flex component. - - - -### Responsive - -The Flex component also supports responsive values, making it easy to create -responsive designs. - - - -### Align - -The Flex component also supports responsive alignment, making it easy to -create responsive designs. - - diff --git a/canon-docs/src/app/(docs)/components/flex/props.ts b/canon-docs/src/app/(docs)/components/flex/props.ts deleted file mode 100644 index 2268a6909d..0000000000 --- a/canon-docs/src/app/(docs)/components/flex/props.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - PropDef, - childrenPropDefs, - classNamePropDefs, - stylePropDefs, -} from '../../../../utils/propDefs'; - -export const flexPropDefs: Record = { - align: { - type: 'enum', - values: ['start', 'center', 'end', 'baseline', 'stretch'], - responsive: true, - }, - direction: { - type: 'enum', - values: ['row', 'column', 'row-reverse', 'column-reverse'], - responsive: true, - }, - justify: { - type: 'enum', - values: ['start', 'center', 'end', 'between'], - responsive: true, - }, - ...childrenPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/grid/props.ts b/canon-docs/src/app/(docs)/components/grid/props.ts deleted file mode 100644 index a9e8717fa1..0000000000 --- a/canon-docs/src/app/(docs)/components/grid/props.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - PropDef, - childrenPropDefs, - classNamePropDefs, - stylePropDefs, -} from '../../../../utils/propDefs'; - -const columnsValues = [ - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - '10', - '11', - '12', -]; - -export const gridPropDefs: Record = { - columns: { - type: 'enum | string', - values: [...columnsValues, 'auto'], - responsive: true, - default: 'auto', - }, - ...childrenPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; - -export const gridItemPropDefs: Record = { - colSpan: { - type: 'enum | string', - values: [...columnsValues, 'full'], - responsive: true, - }, - rowSpan: { - type: 'enum | string', - values: [...columnsValues, 'full'], - responsive: true, - }, - start: { - type: 'enum | string', - values: [...columnsValues, 'auto'], - responsive: true, - }, - end: { - type: 'enum | string', - values: [...columnsValues, 'auto'], - responsive: true, - }, - ...childrenPropDefs, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/heading/page.mdx b/canon-docs/src/app/(docs)/components/heading/page.mdx deleted file mode 100644 index a5eb488411..0000000000 --- a/canon-docs/src/app/(docs)/components/heading/page.mdx +++ /dev/null @@ -1,102 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { HeadingSnippet } from '@/snippets/stories-snippets'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { headingPropDefs } from './props'; - -# Heading - -Headings are used to structure the content of your page. - -} - code={`Hello World!`} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - - -## Examples - -### All variants - -The `Heading` component has a `variant` prop that can be used to change the -appearance of the heading. - -} - code={` - Display - Title 1 - Title 2 - Title 3 - Title 4 - Title 5 -`} -/> - -### Truncate - -The `Heading` component has a `truncate` prop that can be used to truncate the -heading. - -} - code={` - A man looks at a painting in a museum and says, “Brothers and sisters I - have none, but that man's father is my father's son.” Who is - in the painting? - `} -/> - -### Custom render - -You can also use the `render` prop to render the heading as a different element. - -} - code={`}>Custom render`} -/> - -### Responsive - -You can also use the `variant` prop to change the appearance of the text based -on the screen size. - - - Responsive heading - `} -/> diff --git a/canon-docs/src/app/(docs)/components/heading/props.ts b/canon-docs/src/app/(docs)/components/heading/props.ts deleted file mode 100644 index 6d62d2dee1..0000000000 --- a/canon-docs/src/app/(docs)/components/heading/props.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const headingPropDefs: Record = { - variant: { - type: 'enum', - values: ['display', 'title1', 'title2', 'title3', 'title4', 'title5'], - responsive: true, - }, - children: { - type: 'enum', - values: ['ReactNode'], - responsive: false, - }, - truncate: { - type: 'boolean', - default: 'false', - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/icon-button/page.mdx b/canon-docs/src/app/(docs)/components/icon-button/page.mdx deleted file mode 100644 index 60530ec9ea..0000000000 --- a/canon-docs/src/app/(docs)/components/icon-button/page.mdx +++ /dev/null @@ -1,97 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { IconButtonSnippet } from '@/snippets/stories-snippets'; -import { iconButtonVariants } from '@/snippets/code-snippets'; -import { iconButtonPropDefs } from './props'; - -# Icon Button - -A button component with a single icon that can be used to trigger actions. - -} - code={` - - - `} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - - -## Examples - -### Variants - -Here's a view when buttons have different variants. - -} - code={iconButtonVariants} -/> - -### Sizes - -Here's a view when buttons have different sizes. - -} - code={` - - -`} -/> - -### Disabled - -Here's a view when buttons are disabled. - -} - code={``} -/> - -### Responsive - -Here's a view when buttons are responsive. - -`} -/> diff --git a/canon-docs/src/app/(docs)/components/icon-button/props.ts b/canon-docs/src/app/(docs)/components/icon-button/props.ts deleted file mode 100644 index bcb1580247..0000000000 --- a/canon-docs/src/app/(docs)/components/icon-button/props.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '../../../../utils/propDefs'; -import type { PropDef } from '../../../../utils/propDefs'; - -export const iconButtonPropDefs: Record = { - variant: { - type: 'enum', - values: ['primary', 'secondary'], - default: 'primary', - responsive: true, - }, - size: { - type: 'enum', - values: ['small', 'medium'], - default: 'medium', - responsive: true, - }, - icon: { type: 'enum', values: 'icon', responsive: false }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/icon/page.mdx b/canon-docs/src/app/(docs)/components/icon/page.mdx deleted file mode 100644 index 66be460d13..0000000000 --- a/canon-docs/src/app/(docs)/components/icon/page.mdx +++ /dev/null @@ -1,44 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { IconSnippet } from '@/snippets/stories-snippets'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { iconPropDefs } from './props'; - -# Icon - -Icons are used to represent an action or a state. - -} - code={``} -/> - - - - Usage - Theming - - - -`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - `} - /> - - - - -## API reference - - diff --git a/canon-docs/src/app/(docs)/components/link/page.mdx b/canon-docs/src/app/(docs)/components/link/page.mdx deleted file mode 100644 index 64a3261590..0000000000 --- a/canon-docs/src/app/(docs)/components/link/page.mdx +++ /dev/null @@ -1,84 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { - MenuSnippet, - ButtonSnippet, - LinkSnippet, -} from '@/snippets/stories-snippets'; -import { linkPropDefs } from './props'; - -# Link - -A link component that renders a `` element. - -} - code={`Sign up for Backstage`} -/> - - - - Usage - Theming - - - Sign up for Backstage`} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-Link` - - `canon-Link[data-variant='body']` - - `canon-Link[data-variant='subtitle']` - - `canon-Link[data-variant='caption']` - - `canon-Link[data-variant='label']` - - `canon-Link[data-weight='regular']` - - `canon-Link[data-weight='bold']` - - - -## API reference - - - -## Examples - -### Variants - -Here's a view when links have different variants. - -} - code={` - - - - - `} -/> - -### Weights - -Here's a view when links have different weights. - -} - code={` - - - `} -/> diff --git a/canon-docs/src/app/(docs)/components/link/props.ts b/canon-docs/src/app/(docs)/components/link/props.ts deleted file mode 100644 index 83507c5594..0000000000 --- a/canon-docs/src/app/(docs)/components/link/props.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; -import type { PropDef } from '@/utils/propDefs'; - -export const linkPropDefs: Record = { - to: { - type: 'string', - }, - variant: { - type: 'enum', - values: ['subtitle', 'body', 'caption', 'label'], - default: 'body', - responsive: true, - }, - weight: { - type: 'enum', - values: ['regular', 'bold'], - default: 'regular', - responsive: true, - }, - ...classNamePropDefs, - ...stylePropDefs, -}; diff --git a/canon-docs/src/app/(docs)/components/menu/page.mdx b/canon-docs/src/app/(docs)/components/menu/page.mdx deleted file mode 100644 index 524db26cd1..0000000000 --- a/canon-docs/src/app/(docs)/components/menu/page.mdx +++ /dev/null @@ -1,202 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { MenuSnippet } from '@/snippets/stories-snippets'; -import { BaseUI } from '@/components/HeadlessBanners/BaseUI'; -import { - menuRootPropDefs, - menuTriggerPropDefs, - menuPositionerPropDefs, - menuItemPropDefs, -} from './props'; - -# Menu - -A list of actions in a dropdown, enhanced with keyboard navigation. - -} - code={` - ( - - )} - /> - - - - Settings - Invite new members - Download app - Log out - - - - `} -/> - - - - Usage - Theming - - - - - - - - - - - - `} - /> - - - We recommend starting with our [global tokens](/theme/theming) to customize the library and align it with - your brand. For additional flexibility, you can use the provided class names for each element listed below. - - `canon-MenuTrigger` - - `canon-MenuBackdrop` - - `canon-MenuPositioner` - - `canon-MenuPopup` - - `canon-MenuArrow` - - `canon-MenuItem` - - `canon-MenuGroup` - - `canon-MenuGroupLabel` - - `canon-MenuRadioGroup` - - `canon-MenuRadioItem` - - `canon-MenuRadioItemIndicator` - - `canon-MenuCheckboxItem` - - `canon-MenuCheckboxItemIndicator` - - `canon-MenuSubmenuTrigger` - - `canon-MenuSeparator` - - - -## API reference - - - -### Menu.Root - -Groups all parts of the menu. Doesn't render its own HTML element. - - - -### Menu.Trigger - -The trigger by default render a simple unstyled button. Because menus can be rendered in different ways, we recommend -using the `render` prop to render a custom trigger. - - - )} - /> - - - - Settings - Invite new members - Download app - Log out - - - - `} -/> - -### Nested navigation - -You can nest menus to create a more complex navigation structure. - -} - code={` ( - - )} - /> - - - - Settings - Invite new members - Download app - Log out - - Submenu - - - - Submenu Item 1 - Submenu Item 2 - Submenu Item 3 - - - - - - - `} -/> diff --git a/canon-docs/src/app/(docs)/components/select/page.mdx b/canon-docs/src/app/(docs)/components/select/page.mdx deleted file mode 100644 index 4399f62235..0000000000 --- a/canon-docs/src/app/(docs)/components/select/page.mdx +++ /dev/null @@ -1,128 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { Tabs } from '@/components/Tabs'; -import { CodeBlock } from '@/components/CodeBlock'; -import { SelectSnippet } from '@/snippets/stories-snippets'; -import { selectPropDefs } from './props'; - -# Select - -A common form component for choosing a predefined value in a dropdown menu. - -} - code={``} -/> - -### Sizes - -Here's a view when the selects have different sizes. - -} - code={` - - `} -/> - -### Disabled - -Here's a view when the select is disabled. - -} - code={``; + +export const selectDefaultSnippet = ``; + +export const selectSizesSnippet = ` + +`; + +export const selectDisabledSnippet = ``; diff --git a/canon-docs/src/content/components/switch.mdx b/canon-docs/src/content/components/switch.mdx new file mode 100644 index 0000000000..068ec96217 --- /dev/null +++ b/canon-docs/src/content/components/switch.mdx @@ -0,0 +1,41 @@ +import { PropsTable } from '@/components/PropsTable'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { SwitchSnippet } from '@/snippets/stories-snippets'; +import { switchPropDefs, snippetUsage } from './switch.props'; +import { ComponentInfos } from '@/components/ComponentInfos'; + +# Switch + +A control that indicates whether a setting is on or off. + +} + code={``} +/> + + + +## API reference + + + +## Examples + +### Disabled + +A switch can be disabled using the `isDisabled` prop. + +} + code={``} +/> diff --git a/canon-docs/src/content/components/switch.props.ts b/canon-docs/src/content/components/switch.props.ts new file mode 100644 index 0000000000..ddbca4e049 --- /dev/null +++ b/canon-docs/src/content/components/switch.props.ts @@ -0,0 +1,71 @@ +import { classNamePropDefs, stylePropDefs } from '@/utils/propDefs'; +import type { PropDef } from '@/utils/propDefs'; + +export const switchPropDefs: Record = { + autoFocus: { + type: 'boolean', + }, + defaultSelected: { + type: 'boolean', + }, + ...classNamePropDefs, + isDisabled: { + type: 'boolean', + }, + isReadOnly: { + type: 'boolean', + }, + isSelected: { + type: 'boolean', + }, + label: { + type: 'string', + }, + name: { + type: 'string', + }, + onChange: { + type: 'enum', + values: ['(isSelected: boolean) => void'], + }, + onFocus: { + type: 'enum', + values: ['(e: FocusEvent) => void'], + }, + onBlur: { + type: 'enum', + values: ['(e: FocusEvent) => void'], + }, + onFocusChange: { + type: 'enum', + values: ['(isFocused: boolean) => void'], + }, + onKeyDown: { + type: 'enum', + values: ['(e: KeyboardEvent) => void'], + }, + onKeyUp: { + type: 'enum', + values: ['(e: KeyboardEvent) => void'], + }, + onHoverStart: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + }, + onHoverEnd: { + type: 'enum', + values: ['(e: HoverEvent) => void'], + }, + onHoverChange: { + type: 'enum', + values: ['(isHovered: boolean) => void'], + }, + ...stylePropDefs, + value: { + type: 'string', + }, +}; + +export const snippetUsage = `import { Switch } from '@backstage/canon'; + +`; diff --git a/canon-docs/src/app/(docs)/components/table/page.mdx b/canon-docs/src/content/components/table.mdx similarity index 100% rename from canon-docs/src/app/(docs)/components/table/page.mdx rename to canon-docs/src/content/components/table.mdx diff --git a/canon-docs/src/content/components/tabs.mdx b/canon-docs/src/content/components/tabs.mdx new file mode 100644 index 0000000000..85cfa34af2 --- /dev/null +++ b/canon-docs/src/content/components/tabs.mdx @@ -0,0 +1,61 @@ +import { PropsTable } from '@/components/PropsTable'; +import { TabsSnippet } from '@/snippets/stories-snippets'; +import { Snippet } from '@/components/Snippet'; +import { CodeBlock } from '@/components/CodeBlock'; +import { + tabsRootPropDefs, + tabsListPropDefs, + tabsTabPropDefs, + tabsPanelPropDefs, + tabsUsageSnippet, + tabsDefaultSnippet, +} from './tabs.props'; +import { ComponentInfos } from '@/components/ComponentInfos'; + +# Tabs + +A component for toggling between related panels on the same page. + +} + code={tabsDefaultSnippet} +/> + + + +## API reference + +### Tabs.Root + +Groups the tabs and the corresponding panels. Renders a `
` element. + + + +### Tabs.List + +Groups the individual tab buttons. Renders a `
` element. + + + +### Tabs.Tab + +An individual interactive tab button that toggles the corresponding panel. Renders a ` - - - -`; - -export const iconButtonVariants = ` - - - -`; - -export const flexFAQ1 = ` - Hello World - Hello World - Hello World -`; - -export const flexSimple = ` - Hello World - Hello World - Hello World -`; - -export const flexResponsive = ` - Hello World - Hello World - Hello World -`; - -export const flexAlign = ` - Hello World - Hello World - Hello World -`; diff --git a/canon-docs/src/snippets/stories-snippets.tsx b/canon-docs/src/snippets/stories-snippets.tsx index 64047ebde9..62b0a99232 100644 --- a/canon-docs/src/snippets/stories-snippets.tsx +++ b/canon-docs/src/snippets/stories-snippets.tsx @@ -3,11 +3,12 @@ import { composeStories } from '@storybook/react'; import * as BoxStories from '../../../packages/canon/src/components/Box/Box.stories'; import * as ButtonStories from '../../../packages/canon/src/components/Button/Button.stories'; +import * as ButtonIconStories from '../../../packages/canon/src/components/ButtonIcon/ButtonIcon.stories'; +import * as ButtonLinkStories from '../../../packages/canon/src/components/ButtonLink/ButtonLink.stories'; import * as CheckboxStories from '../../../packages/canon/src/components/Checkbox/Checkbox.stories'; import * as ContainerStories from '../../../packages/canon/src/components/Container/Container.stories'; import * as GridStories from '../../../packages/canon/src/components/Grid/Grid.stories'; import * as HeadingStories from '../../../packages/canon/src/components/Heading/Heading.stories'; -import * as IconButtonStories from '../../../packages/canon/src/components/IconButton/IconButton.stories'; import * as IconStories from '../../../packages/canon/src/components/Icon/Icon.stories'; import * as TextFieldStories from '../../../packages/canon/src/components/TextField/TextField.stories'; import * as TextStories from '../../../packages/canon/src/components/Text/Text.stories'; @@ -17,7 +18,10 @@ import * as MenuStories from '../../../packages/canon/src/components/Menu/Menu.s import * as LinkStories from '../../../packages/canon/src/components/Link/Link.stories'; import * as AvatarStories from '../../../packages/canon/src/components/Avatar/Avatar.stories'; import * as CollapsibleStories from '../../../packages/canon/src/components/Collapsible/Collapsible.stories'; +import * as RadioGroupStories from '../../../packages/canon/src/components/RadioGroup/RadioGroup.stories'; import * as TabsStories from '../../../packages/canon/src/components/Tabs/Tabs.stories'; +import * as SwitchStories from '../../../packages/canon/src/components/Switch/Switch.stories'; +import * as SearchFieldStories from '../../../packages/canon/src/components/SearchField/SearchField.stories'; export const BoxSnippet = ({ story }: { story: keyof typeof BoxStories }) => { const stories = composeStories(BoxStories); @@ -37,6 +41,28 @@ export const ButtonSnippet = ({ return StoryComponent ? : null; }; +export const ButtonIconSnippet = ({ + story, +}: { + story: keyof typeof ButtonIconStories; +}) => { + const stories = composeStories(ButtonIconStories); + const StoryComponent = stories[story as keyof typeof stories]; + + return StoryComponent ? : null; +}; + +export const ButtonLinkSnippet = ({ + story, +}: { + story: keyof typeof ButtonLinkStories; +}) => { + const stories = composeStories(ButtonLinkStories); + const StoryComponent = stories[story as keyof typeof stories]; + + return StoryComponent ? : null; +}; + export const CheckboxSnippet = ({ story, }: { @@ -95,17 +121,6 @@ export const HeadingSnippet = ({ return StoryComponent ? : null; }; -export const IconButtonSnippet = ({ - story, -}: { - story: keyof typeof IconButtonStories; -}) => { - const stories = composeStories(IconButtonStories); - const StoryComponent = stories[story as keyof typeof stories]; - - return StoryComponent ? : null; -}; - export const IconSnippet = ({ story }: { story: keyof typeof IconStories }) => { const stories = composeStories(IconStories); const StoryComponent = stories[story as keyof typeof stories]; @@ -173,3 +188,36 @@ export const TabsSnippet = ({ story }: { story: keyof typeof TabsStories }) => { return StoryComponent ? : null; }; + +export const SwitchSnippet = ({ + story, +}: { + story: keyof typeof SwitchStories; +}) => { + const stories = composeStories(SwitchStories); + const StoryComponent = stories[story as keyof typeof stories]; + + return StoryComponent ? : null; +}; + +export const RadioGroupSnippet = ({ + story, +}: { + story: keyof typeof RadioGroupStories; +}) => { + const stories = composeStories(RadioGroupStories); + const StoryComponent = stories[story as keyof typeof stories]; + + return StoryComponent ? : null; +}; + +export const SearchFieldSnippet = ({ + story, +}: { + story: keyof typeof SearchFieldStories; +}) => { + const stories = composeStories(SearchFieldStories); + const StoryComponent = stories[story as keyof typeof stories]; + + return StoryComponent ? : null; +}; diff --git a/canon-docs/src/utils/changelog.ts b/canon-docs/src/utils/changelog.ts new file mode 100644 index 0000000000..94317ab78b --- /dev/null +++ b/canon-docs/src/utils/changelog.ts @@ -0,0 +1,386 @@ +export type Component = + | 'avatar' + | 'box' + | 'button' + | 'heading' + | 'text' + | 'icon-button' + | 'icon' + | 'tabs' + | 'menu' + | 'textfield' + | 'datatable' + | 'select' + | 'collapsible' + | 'checkbox' + | 'container' + | 'link' + | 'tooltip' + | 'scrollarea' + | 'flex' + | 'switch'; + +export type Version = `${number}.${number}.${number}`; + +export interface ChangelogProps { + components: Component[]; + description: string; + version: Version; + platform: 'oss' | 'portal'; + prs: string[]; +} + +export const changelog: ChangelogProps[] = [ + { + components: ['switch'], + version: '0.5.0', + description: '✨ Add new `Switch` component', + platform: 'portal', + prs: ['30251'], + }, + { + components: ['tabs'], + version: '0.4.0', + description: '✨ Add new `Tabs` component', + platform: 'portal', + prs: ['29996'], + }, + { + components: ['text', 'heading'], + version: '0.4.0', + description: '✨ Add `truncate` prop to `Text` and `Heading`', + platform: 'portal', + prs: ['29988'], + }, + { + components: ['menu'], + version: '0.4.0', + description: '✨ Add combobox option to `Menu`', + platform: 'portal', + prs: ['29986'], + }, + { + components: ['textfield'], + version: '0.4.0', + description: '✨ Add icon prop on `TextField`', + platform: 'portal', + prs: ['29820'], + }, + { + components: ['button', 'icon-button'], + version: '0.4.0', + description: 'Improve icon props on `Button` and `IconButton`', + platform: 'portal', + prs: ['29667'], + }, + { + components: ['text', 'heading'], + version: '0.4.0', + description: + 'Improve the way we treat custom render on `Text` and `Heading`', + platform: 'portal', + prs: ['29989'], + }, + { + components: ['menu'], + version: '0.4.0', + description: 'Improve `Menu` styles', + platform: 'portal', + prs: ['29986'], + }, + { + components: ['textfield'], + version: '0.4.0', + description: 'Improve `TextField` styles', + platform: 'portal', + prs: ['29974'], + }, + { + components: ['textfield'], + version: '0.4.0', + description: 'Improve clear button on `TextField`', + platform: 'portal', + prs: ['29878'], + }, + { + components: ['flex'], + version: '0.4.0', + description: 'Fix spacing props on all layout components', + platform: 'portal', + prs: ['30013'], + }, + { + components: [], + version: '0.4.0', + description: 'Fix - Pin Base UI version', + platform: 'portal', + prs: ['29782'], + }, + { + components: ['select'], + version: '0.4.0', + description: 'Fix - Clicking `Select` label moves focus to trigger', + platform: 'portal', + prs: ['29755'], + }, + { + components: ['datatable'], + version: '0.4.0', + description: 'Fix `DataTable.Pagination` count issue', + platform: 'portal', + prs: ['29688'], + }, + { + components: ['datatable'], + version: '0.3.0', + description: 'Add `DataTable` component', + platform: 'portal', + prs: ['29484', '29603'], + }, + { + components: ['select'], + version: '0.3.0', + description: 'Add `Select` component', + platform: 'portal', + prs: ['29440'], + }, + { + components: ['avatar'], + version: '0.3.0', + description: 'Add `Avatar` component', + platform: 'portal', + prs: ['29594'], + }, + { + components: ['collapsible'], + version: '0.3.0', + description: 'Add `Collapsible` component', + platform: 'portal', + prs: ['29617'], + }, + { + components: ['textfield'], + version: '0.3.0', + description: 'Add `TextField` component instead of `Field` + `Input`', + platform: 'portal', + prs: ['29364'], + }, + { + components: ['datatable'], + version: '0.3.0', + description: 'Add `TableCellProfile`', + platform: 'portal', + prs: ['29600'], + }, + { + components: [], + version: '0.3.0', + description: 'Add breakpoint hooks - `up()` and `down()`', + platform: 'portal', + prs: ['29564'], + }, + { + components: [], + version: '0.3.0', + description: 'Add gray scale css tokens', + platform: 'portal', + prs: ['29543'], + }, + { + components: [], + version: '0.3.0', + description: + 'Update CSS styling API using `[data-___]` instead of class names for props', + platform: 'portal', + prs: ['29560'], + }, + { + components: ['checkbox'], + version: '0.3.0', + description: 'Update `Checkbox` dark mode', + platform: 'portal', + prs: ['29544'], + }, + { + components: ['container'], + version: '0.3.0', + description: 'Update `Container` styles', + platform: 'portal', + prs: ['29475'], + }, + { + components: ['menu'], + version: '0.3.0', + description: 'Update `Menu` styles', + platform: 'portal', + prs: ['29351'], + }, + { + components: ['select'], + version: '0.3.0', + description: 'Fix `Select` styles on small sizes + with long option names', + platform: 'portal', + prs: ['29545'], + }, + { + components: ['link'], + version: '0.3.0', + description: 'Fix render prop on `Link`', + platform: 'portal', + prs: ['29247'], + }, + { + components: ['textfield', 'select'], + version: '0.3.0', + description: 'Remove `Field` from `TextField` + `Select`', + platform: 'portal', + prs: ['29482'], + }, + { + components: ['text', 'heading'], + version: '0.3.0', + description: 'Update `textDecoration` to `none` on `Text` / `Heading`', + platform: 'portal', + prs: ['29357'], + }, + { + components: ['text', 'heading'], + version: '0.3.0', + description: 'Update `textDecoration` to `none` on `Text` / `Heading`', + platform: 'portal', + prs: ['29357'], + }, + { + components: [], + version: '0.3.0', + description: 'Docs - Use stories from Storybook for all examples in Nextjs', + platform: 'portal', + prs: ['29306'], + }, + { + components: [], + version: '0.3.0', + description: 'Docs - Add release page (this one 🤗)', + platform: 'portal', + prs: ['29461'], + }, + { + components: [], + version: '0.3.0', + description: 'Docs - Add docs for Menu, Link', + platform: 'portal', + prs: ['29576'], + }, + { + components: [], + version: '0.3.0', + description: 'Fix CSS watch mode', + platform: 'portal', + prs: ['29352'], + }, + { + components: ['menu'], + version: '0.2.0', + description: 'New `Menu` component', + platform: 'portal', + prs: ['29151'], + }, + { + components: ['icon-button'], + version: '0.2.0', + description: 'New `IconButton` component', + platform: 'portal', + prs: ['29239'], + }, + { + components: ['scrollarea'], + version: '0.2.0', + description: 'New `ScrollArea` component', + platform: 'portal', + prs: ['29240'], + }, + { + components: ['button', 'checkbox'], + version: '0.2.0', + description: 'Improve `Button` & `Checkbox` styles', + platform: 'portal', + prs: ['29127', '28789'], + }, + { + components: ['text'], + version: '0.2.0', + description: 'Improve `Text` styles', + platform: 'portal', + prs: ['29200'], + }, + { + components: ['icon'], + version: '0.2.0', + description: 'Renamed `CanonProvider` to `IconProvider`', + platform: 'portal', + prs: ['29002'], + }, + { + components: ['icon'], + version: '0.2.0', + description: 'Added about 40+ new icons', + platform: 'portal', + prs: ['29264'], + }, + { + components: [], + version: '0.2.0', + description: 'Simplified styling into a unique styles.css file', + platform: 'portal', + prs: ['29199'], + }, + { + components: [], + version: '0.2.0', + description: 'Added Canon styles to Backstage', + platform: 'portal', + prs: ['29137'], + }, + { + components: [], + version: '0.2.0', + description: 'Update global CSS tokens', + platform: 'portal', + prs: ['28804'], + }, + { + components: ['flex'], + version: '0.2.0', + description: 'Merge Stack + Inline into Flex', + platform: 'portal', + prs: ['28634'], + }, + { + components: ['button'], + version: '0.2.0', + description: 'Improve `Button` types', + platform: 'portal', + prs: ['29205'], + }, + { + components: [], + version: '0.2.0', + description: 'Move font weight and family back to each components', + platform: 'portal', + prs: ['28972'], + }, + { + components: [], + version: '0.2.0', + description: 'Fix custom values in spacing props', + platform: 'portal', + prs: ['28770'], + }, + { + components: [], + version: '0.2.0', + description: 'Multiple updates on the Canon Docs site', + platform: 'portal', + prs: ['28760'], + }, +]; diff --git a/canon-docs/src/utils/data.ts b/canon-docs/src/utils/data.ts index ba4fd5e432..c1997f5b1f 100644 --- a/canon-docs/src/utils/data.ts +++ b/canon-docs/src/utils/data.ts @@ -14,8 +14,8 @@ export const overview: Page[] = [ slug: 'about', }, { - title: 'Releases', - slug: 'releases', + title: 'Changelog', + slug: 'changelog', }, ]; @@ -76,6 +76,16 @@ export const components: Page[] = [ slug: 'button', status: 'alpha', }, + { + title: 'ButtonIcon', + slug: 'button-icon', + status: 'alpha', + }, + { + title: 'ButtonLink', + slug: 'button-link', + status: 'alpha', + }, { title: 'Checkbox', slug: 'checkbox', @@ -96,11 +106,6 @@ export const components: Page[] = [ slug: 'icon', status: 'alpha', }, - { - title: 'IconButton', - slug: 'icon-button', - status: 'alpha', - }, { title: 'Link', slug: 'link', @@ -111,11 +116,26 @@ export const components: Page[] = [ slug: 'menu', status: 'alpha', }, + { + title: 'RadioGroup', + slug: 'radio-group', + status: 'alpha', + }, + { + title: 'SearchField', + slug: 'search-field', + status: 'alpha', + }, { title: 'Select', slug: 'select', status: 'alpha', }, + { + title: 'Switch', + slug: 'switch', + status: 'alpha', + }, { title: 'Table', slug: 'table', diff --git a/canon-docs/tsconfig.json b/canon-docs/tsconfig.json index 2baa7cde8f..e1b3951aa8 100644 --- a/canon-docs/tsconfig.json +++ b/canon-docs/tsconfig.json @@ -3,7 +3,7 @@ "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, - "strict": true, + "strict": false, "noEmit": true, "esModuleInterop": true, "module": "esnext", @@ -12,6 +12,7 @@ "isolatedModules": true, "jsx": "preserve", "incremental": true, + "noImplicitAny": false, "plugins": [ { "name": "next" @@ -19,14 +20,16 @@ ], "paths": { "@/*": ["./src/*"] - } + }, + "target": "ES2017" }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", - "dist/types/**/*.ts" + "dist/types/**/*.ts", + "src/types/**/*.d.ts" ], "exclude": ["node_modules"] } diff --git a/canon-docs/yarn.lock b/canon-docs/yarn.lock index decb4e7efe..7cfd30ebfe 100644 --- a/canon-docs/yarn.lock +++ b/canon-docs/yarn.lock @@ -5,36 +5,52 @@ __metadata: version: 8 cacheKey: 10 -"@babel/runtime@npm:^7.18.6": - version: 7.26.10 - resolution: "@babel/runtime@npm:7.26.10" +"@babel/code-frame@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" dependencies: - regenerator-runtime: "npm:^0.14.0" - checksum: 10/9d7ff8e96abe3791047c1138789c742411e3ef19c4d7ca18ce916f83cec92c06ec5dc64401759f6dd1e377cf8a01bbd2c62e033eb7550f435cf6579768d0d4a5 + "@babel/helper-validator-identifier": "npm:^7.27.1" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10/721b8a6e360a1fa0f1c9fe7351ae6c874828e119183688b533c477aa378f1010f37cc9afbfc4722c686d1f5cdd00da02eab4ba7278a0c504fa0d7a321dcd4fdf + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 10/75041904d21bdc0cd3b07a8ac90b11d64cd3c881e89cb936fa80edd734bf23c35e6bd1312611e8574c4eab1f3af0f63e8a5894f4699e9cfdf70c06fcf4252320 + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.18.6": + version: 7.27.6 + resolution: "@babel/runtime@npm:7.27.6" + checksum: 10/cc957a12ba3781241b83d528eb69ddeb86ca5ac43179a825e83aa81263a6b3eb88c57bed8a937cdeacfc3192e07ec24c73acdfea4507d0c0428c8e23d6322bfe languageName: node linkType: hard "@codemirror/autocomplete@npm:^6.0.0": - version: 6.18.4 - resolution: "@codemirror/autocomplete@npm:6.18.4" + version: 6.18.6 + resolution: "@codemirror/autocomplete@npm:6.18.6" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.17.0" "@lezer/common": "npm:^1.0.0" - checksum: 10/7cd62db2ee87d6cb3936ced4f211bdcd9ce75515f64922119370c303a8bdbf5640e640a8d802c30d01cb55fb6c9b5299426ff799f04cff0bef8d0c3450fe2528 + checksum: 10/0574d96fd04ccf2d3b7ae3c4efe0a72f423fa81658876ec50865ce3371cea038aeddf026976ec0d0ccbee72ac66bdf7deec9106dee251ad49019ae7e1a871663 languageName: node linkType: hard "@codemirror/commands@npm:^6.0.0, @codemirror/commands@npm:^6.1.0": - version: 6.8.0 - resolution: "@codemirror/commands@npm:6.8.0" + version: 6.8.1 + resolution: "@codemirror/commands@npm:6.8.1" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.4.0" "@codemirror/view": "npm:^6.27.0" "@lezer/common": "npm:^1.1.0" - checksum: 10/0c7991736bc84d0a7f8e49c311c78a78def84fca36ff61c2f9887067e2c06b1b232711cb99282cd410527ddbe0671d2b9aff93e0848fa731a2014c3691c737ea + checksum: 10/72b6343777d4fe4af1bcc91331eb64705b33e871c9f8e2a0cd177269478a6f3282bf25aeaecdbb55fd5e031b67aabfede068e919fe69e473d07e5090dd76b381 languageName: node linkType: hard @@ -65,8 +81,8 @@ __metadata: linkType: hard "@codemirror/language@npm:^6.0.0": - version: 6.10.8 - resolution: "@codemirror/language@npm:6.10.8" + version: 6.11.1 + resolution: "@codemirror/language@npm:6.11.1" dependencies: "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.23.0" @@ -74,38 +90,38 @@ __metadata: "@lezer/highlight": "npm:^1.0.0" "@lezer/lr": "npm:^1.0.0" style-mod: "npm:^4.0.0" - checksum: 10/63b83b41d9f8475f757144cc204df08834bb14411c484aa265ffa3e93b7d8f696a21110df72101159a8675eda29018c6d08f864965bd4651b607a39f10ad32ed + checksum: 10/024969113d61ccb5d497b75a8a9875d43e1bfc8466de2819bb5db23f01b200937366800a812e8d33eb5e34e3a5d2aa22d0ff8205f34a5e8aeb4cd1d221bcaa78 languageName: node linkType: hard "@codemirror/lint@npm:^6.0.0": - version: 6.8.4 - resolution: "@codemirror/lint@npm:6.8.4" + version: 6.8.5 + resolution: "@codemirror/lint@npm:6.8.5" dependencies: "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.35.0" crelt: "npm:^1.0.5" - checksum: 10/401ead0591d88d31d1bf6527d4caba26e0deb7b49382dfbb8c712037d858047b0699fa2c15831a07db928194549eea9b942004fee42f334b34ff5973c7dbec58 + checksum: 10/9eddfea1dd0615431d57687c2a0d4de510d725aac6f6bbc2eba4bc934963371304dfa4c49398b3043372ef34cead3ebc0ec3f652632a87f5d8a458fa911a309a languageName: node linkType: hard "@codemirror/search@npm:^6.0.0": - version: 6.5.8 - resolution: "@codemirror/search@npm:6.5.8" + version: 6.5.11 + resolution: "@codemirror/search@npm:6.5.11" dependencies: "@codemirror/state": "npm:^6.0.0" "@codemirror/view": "npm:^6.0.0" crelt: "npm:^1.0.5" - checksum: 10/1389fa4e05da72b621ae10ff00d4ef0d23b08a3a7ac48f6e0b867429da7b80036bd7a6feef1a54f5b4c4af9fc4277f754a313a858fbfc12ccdfa48e9bf300cef + checksum: 10/d057f37cb369460b25625d7eb72f40636bf78ecd140608da53010cf3660f982a9e613826e38d85d87c9c2ff11e45c9482429987bfd4f29cbbd192f1ee3fd2695 languageName: node linkType: hard "@codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.1, @codemirror/state@npm:^6.4.0, @codemirror/state@npm:^6.5.0": - version: 6.5.1 - resolution: "@codemirror/state@npm:6.5.1" + version: 6.5.2 + resolution: "@codemirror/state@npm:6.5.2" dependencies: "@marijn/find-cluster-break": "npm:^1.0.0" - checksum: 10/117f21ba2ff5bc9f9b946ca9943279a29bb9461ec77fc2313cfd8908ed6eb7df2950d7c5b0ba0a0a23c3e0633c6bba56f8c105f97875665e0376a9e110d10a48 + checksum: 10/5ccd3acb0c0a5b88e83fb91be39099fceb9f44a5047cc41a75d53f160e736851f65c8de40950b90c6519e6d2828e12f468db0af658dde30e938896f1c39eec91 languageName: node linkType: hard @@ -122,199 +138,228 @@ __metadata: linkType: hard "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0, @codemirror/view@npm:^6.35.0": - version: 6.36.2 - resolution: "@codemirror/view@npm:6.36.2" + version: 6.37.1 + resolution: "@codemirror/view@npm:6.37.1" dependencies: "@codemirror/state": "npm:^6.5.0" + crelt: "npm:^1.0.6" style-mod: "npm:^4.1.0" w3c-keyname: "npm:^2.2.4" - checksum: 10/9ef7fcf4f9d9b6e66645ae65da1bf0c90e08f6ba786de0373b9f3644632066b91b8ea20faf67bb81eb9adf310ae76888cc7fd0901e2bb4821193f5427455c137 + checksum: 10/04594b0bad98036c57ef0fb962b0e09186de404e26f1068fd98191edae51f2c5b476938d42239c8c7f0b70deead837f925a9d671b7cc8f9f336bdbb01630bbf9 languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/aix-ppc64@npm:0.25.0" +"@emnapi/core@npm:^1.4.3": + version: 1.4.3 + resolution: "@emnapi/core@npm:1.4.3" + dependencies: + "@emnapi/wasi-threads": "npm:1.0.2" + tslib: "npm:^2.4.0" + checksum: 10/b511f66b897d2019835391544fdf11f4fa0ce06cc1181abfa17c7d4cf03aaaa4fc8a64fcd30bb3f901de488d0a6f370b53a8de2215a898f5a4ac98015265b3b7 + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.4.3": + version: 1.4.3 + resolution: "@emnapi/runtime@npm:1.4.3" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/4f90852a1a5912982cc4e176b6420556971bcf6a85ee23e379e2455066d616219751367dcf43e6a6eaf41ea7e95ba9dc830665a52b5d979dfe074237d19578f8 + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.0.2": + version: 1.0.2 + resolution: "@emnapi/wasi-threads@npm:1.0.2" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/e82941776665eb958c2084728191d6b15a94383449975c4621b67a1c8217e1c0ec11056a693906c76863cb96f782f8be500510ecec6874e3f5da35a8e7968cfd + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/aix-ppc64@npm:0.25.5" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/android-arm64@npm:0.25.0" +"@esbuild/android-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-arm64@npm:0.25.5" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/android-arm@npm:0.25.0" +"@esbuild/android-arm@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-arm@npm:0.25.5" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/android-x64@npm:0.25.0" +"@esbuild/android-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/android-x64@npm:0.25.5" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/darwin-arm64@npm:0.25.0" +"@esbuild/darwin-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/darwin-arm64@npm:0.25.5" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/darwin-x64@npm:0.25.0" +"@esbuild/darwin-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/darwin-x64@npm:0.25.5" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/freebsd-arm64@npm:0.25.0" +"@esbuild/freebsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/freebsd-arm64@npm:0.25.5" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/freebsd-x64@npm:0.25.0" +"@esbuild/freebsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/freebsd-x64@npm:0.25.5" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-arm64@npm:0.25.0" +"@esbuild/linux-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-arm64@npm:0.25.5" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-arm@npm:0.25.0" +"@esbuild/linux-arm@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-arm@npm:0.25.5" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-ia32@npm:0.25.0" +"@esbuild/linux-ia32@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-ia32@npm:0.25.5" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-loong64@npm:0.25.0" +"@esbuild/linux-loong64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-loong64@npm:0.25.5" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-mips64el@npm:0.25.0" +"@esbuild/linux-mips64el@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-mips64el@npm:0.25.5" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-ppc64@npm:0.25.0" +"@esbuild/linux-ppc64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-ppc64@npm:0.25.5" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-riscv64@npm:0.25.0" +"@esbuild/linux-riscv64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-riscv64@npm:0.25.5" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-s390x@npm:0.25.0" +"@esbuild/linux-s390x@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-s390x@npm:0.25.5" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/linux-x64@npm:0.25.0" +"@esbuild/linux-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/linux-x64@npm:0.25.5" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/netbsd-arm64@npm:0.25.0" +"@esbuild/netbsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/netbsd-arm64@npm:0.25.5" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/netbsd-x64@npm:0.25.0" +"@esbuild/netbsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/netbsd-x64@npm:0.25.5" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/openbsd-arm64@npm:0.25.0" +"@esbuild/openbsd-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/openbsd-arm64@npm:0.25.5" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/openbsd-x64@npm:0.25.0" +"@esbuild/openbsd-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/openbsd-x64@npm:0.25.5" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/sunos-x64@npm:0.25.0" +"@esbuild/sunos-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/sunos-x64@npm:0.25.5" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/win32-arm64@npm:0.25.0" +"@esbuild/win32-arm64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-arm64@npm:0.25.5" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/win32-ia32@npm:0.25.0" +"@esbuild/win32-ia32@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-ia32@npm:0.25.5" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.25.0": - version: 0.25.0 - resolution: "@esbuild/win32-x64@npm:0.25.0" +"@esbuild/win32-x64@npm:0.25.5": + version: 0.25.5 + resolution: "@esbuild/win32-x64@npm:0.25.5" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": - version: 4.4.1 - resolution: "@eslint-community/eslint-utils@npm:4.4.1" +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.7.0": + version: 4.7.0 + resolution: "@eslint-community/eslint-utils@npm:4.7.0" dependencies: eslint-visitor-keys: "npm:^3.4.3" peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - checksum: 10/ae92a11412674329b4bd38422518601ec9ceae28e251104d1cad83715da9d38e321f68c817c39b64e66d0af7d98df6f9a10ad2dc638911254b47fb8932df00ef + checksum: 10/43ed5d391526d9f5bbe452aef336389a473026fca92057cf97c576db11401ce9bcf8ef0bf72625bbaf6207ed8ba6bf0dcf4d7e809c24f08faa68a28533c491a7 languageName: node linkType: hard @@ -374,17 +419,192 @@ __metadata: languageName: node linkType: hard -"@isaacs/cliui@npm:^8.0.2": - version: 8.0.2 - resolution: "@isaacs/cliui@npm:8.0.2" +"@img/sharp-darwin-arm64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-darwin-arm64@npm:0.34.2" dependencies: - string-width: "npm:^5.1.2" - string-width-cjs: "npm:string-width@^4.2.0" - strip-ansi: "npm:^7.0.1" - strip-ansi-cjs: "npm:strip-ansi@^6.0.1" - wrap-ansi: "npm:^8.1.0" - wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" - checksum: 10/e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + "@img/sharp-libvips-darwin-arm64": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-darwin-arm64": + optional: true + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-darwin-x64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-darwin-x64@npm:0.34.2" + dependencies: + "@img/sharp-libvips-darwin-x64": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-darwin-x64": + optional: true + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-arm64@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-darwin-arm64@npm:1.1.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-libvips-darwin-x64@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-darwin-x64@npm:1.1.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm64@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-linux-arm64@npm:1.1.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-arm@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-linux-arm@npm:1.1.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-ppc64@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-linux-ppc64@npm:1.1.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-s390x@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-linux-s390x@npm:1.1.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linux-x64@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-linux-x64@npm:1.1.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-arm64@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.1.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-libvips-linuxmusl-x64@npm:1.1.0": + version: 1.1.0 + resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.1.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linux-arm64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-linux-arm64@npm:0.34.2" + dependencies: + "@img/sharp-libvips-linux-arm64": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-linux-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-arm@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-linux-arm@npm:0.34.2" + dependencies: + "@img/sharp-libvips-linux-arm": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-linux-arm": + optional: true + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-s390x@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-linux-s390x@npm:0.34.2" + dependencies: + "@img/sharp-libvips-linux-s390x": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-linux-s390x": + optional: true + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linux-x64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-linux-x64@npm:0.34.2" + dependencies: + "@img/sharp-libvips-linux-x64": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-linux-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-arm64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-linuxmusl-arm64@npm:0.34.2" + dependencies: + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-linuxmusl-x64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-linuxmusl-x64@npm:0.34.2" + dependencies: + "@img/sharp-libvips-linuxmusl-x64": "npm:1.1.0" + dependenciesMeta: + "@img/sharp-libvips-linuxmusl-x64": + optional: true + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@img/sharp-wasm32@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-wasm32@npm:0.34.2" + dependencies: + "@emnapi/runtime": "npm:^1.4.3" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@img/sharp-win32-arm64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-win32-arm64@npm:0.34.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@img/sharp-win32-ia32@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-win32-ia32@npm:0.34.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@img/sharp-win32-x64@npm:0.34.2": + version: 0.34.2 + resolution: "@img/sharp-win32-x64@npm:0.34.2" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -396,13 +616,13 @@ __metadata: linkType: hard "@lezer/css@npm:^1.1.7": - version: 1.1.9 - resolution: "@lezer/css@npm:1.1.9" + version: 1.2.1 + resolution: "@lezer/css@npm:1.2.1" dependencies: "@lezer/common": "npm:^1.2.0" "@lezer/highlight": "npm:^1.0.0" - "@lezer/lr": "npm:^1.0.0" - checksum: 10/bcc277bb6b806961ebfd03e98faf8e5870dd7da2eb565c43922ac378d926b49f479309b28cc824fd4e17baac2c8952966807d06fbe2a45d53e9a3f1518134729 + "@lezer/lr": "npm:^1.3.0" + checksum: 10/726ea0e0b4d10c0326cc62d562a63c0d74970dde2002fab8172681c63e3210ff39d0f629370ad498b70e503ab2e9f74dd342d7c9e402b98f315b556116c3551a languageName: node linkType: hard @@ -415,7 +635,7 @@ __metadata: languageName: node linkType: hard -"@lezer/lr@npm:^1.0.0": +"@lezer/lr@npm:^1.0.0, @lezer/lr@npm:^1.3.0": version: 1.4.2 resolution: "@lezer/lr@npm:1.4.2" dependencies: @@ -425,13 +645,13 @@ __metadata: linkType: hard "@lezer/sass@npm:^1.0.0": - version: 1.0.7 - resolution: "@lezer/sass@npm:1.0.7" + version: 1.1.0 + resolution: "@lezer/sass@npm:1.1.0" dependencies: "@lezer/common": "npm:^1.2.0" "@lezer/highlight": "npm:^1.0.0" "@lezer/lr": "npm:^1.0.0" - checksum: 10/a7531cbf0766d3875480c24ae8929dd56053d71f9eaef8815e6f468e2252e66e38236a3f89395463e4cee43230dc35351386bedc6138cf1a19a44a64ce58a372 + checksum: 10/2f42dfaf5a328d4626a0a8ff8cd5973b7f52e8112541281cf1cbb1970acdc52c7c9f55c71f635bcff75a6151a55f7653d277306a15494b23b652e87d16df9ce3 languageName: node linkType: hard @@ -457,7 +677,7 @@ __metadata: languageName: node linkType: hard -"@mdx-js/mdx@npm:^3.0.0": +"@mdx-js/mdx@npm:^3.0.0, @mdx-js/mdx@npm:^3.1.0": version: 3.1.0 resolution: "@mdx-js/mdx@npm:3.1.0" dependencies: @@ -501,25 +721,36 @@ __metadata: languageName: node linkType: hard -"@next/env@npm:14.2.26": - version: 14.2.26 - resolution: "@next/env@npm:14.2.26" - checksum: 10/0caa679cdf9367501daf1bff0e762b720613a3ee1689e5585bfb7c792fdd07c251bc1f7488919a296047eb1f2b82ceb13955b673143468cad338a87b7d98c196 - languageName: node - linkType: hard - -"@next/eslint-plugin-next@npm:14.2.23": - version: 14.2.23 - resolution: "@next/eslint-plugin-next@npm:14.2.23" +"@napi-rs/wasm-runtime@npm:^0.2.11": + version: 0.2.11 + resolution: "@napi-rs/wasm-runtime@npm:0.2.11" dependencies: - glob: "npm:10.3.10" - checksum: 10/e46513a7601bf682f1e60cc668188cf2c9f0471be73ffbbac69da240e9f91c6b9c3aad3e83a8da54c0ba8bce37cc6368bbafb04b74b385d5df0c36dde09a3217 + "@emnapi/core": "npm:^1.4.3" + "@emnapi/runtime": "npm:^1.4.3" + "@tybys/wasm-util": "npm:^0.9.0" + checksum: 10/e30fe3060474c5018e160231df0531d62b5e22f4736ecd49c04ca6cadacb2acf59b9205435794cd5b898e41e2e3ddb6523e93b97799bd1f4d0751557de6e38e4 languageName: node linkType: hard -"@next/mdx@npm:^15.1.4": - version: 15.1.6 - resolution: "@next/mdx@npm:15.1.6" +"@next/env@npm:15.3.4": + version: 15.3.4 + resolution: "@next/env@npm:15.3.4" + checksum: 10/40ea0bee2eca72dce6102d30ac50029309bf68a281585270e38f920ae47043f240352ad250058d462169a436dea3d8f78a935406ee61088bd4a614524b4a315b + languageName: node + linkType: hard + +"@next/eslint-plugin-next@npm:15.3.4": + version: 15.3.4 + resolution: "@next/eslint-plugin-next@npm:15.3.4" + dependencies: + fast-glob: "npm:3.3.1" + checksum: 10/8a473bd32a06f62c16f60f9c40b7b8149cf91170ce4c1546cda57e9c85ac8481c7ad3aa4a77e8c3c7000e80d3de809d2db7df6cb79e13fd258fff382729abf60 + languageName: node + linkType: hard + +"@next/mdx@npm:15.3.4": + version: 15.3.4 + resolution: "@next/mdx@npm:15.3.4" dependencies: source-map: "npm:^0.7.0" peerDependencies: @@ -530,69 +761,62 @@ __metadata: optional: true "@mdx-js/react": optional: true - checksum: 10/3b46e99934543df94bcb335dddab794db4fcaff09223343e9e00597d3df1e094f16dd619c433fb2fa7fff38c3da57b3118cbc010cdeb9790d0cf01e6c37016e8 + checksum: 10/07904beda049317e43857f9dfe659adb6e57c4417475de1d21a7605f8ace5d9aa992a06465d1a94fe4b62331901765b15659555e8aadedbd410f86df1bebd1bd languageName: node linkType: hard -"@next/swc-darwin-arm64@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-darwin-arm64@npm:14.2.26" +"@next/swc-darwin-arm64@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-darwin-arm64@npm:15.3.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@next/swc-darwin-x64@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-darwin-x64@npm:14.2.26" +"@next/swc-darwin-x64@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-darwin-x64@npm:15.3.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@next/swc-linux-arm64-gnu@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-arm64-gnu@npm:14.2.26" +"@next/swc-linux-arm64-gnu@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-linux-arm64-gnu@npm:15.3.4" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-arm64-musl@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-arm64-musl@npm:14.2.26" +"@next/swc-linux-arm64-musl@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-linux-arm64-musl@npm:15.3.4" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@next/swc-linux-x64-gnu@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-x64-gnu@npm:14.2.26" +"@next/swc-linux-x64-gnu@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-linux-x64-gnu@npm:15.3.4" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-x64-musl@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-linux-x64-musl@npm:14.2.26" +"@next/swc-linux-x64-musl@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-linux-x64-musl@npm:15.3.4" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@next/swc-win32-arm64-msvc@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-win32-arm64-msvc@npm:14.2.26" +"@next/swc-win32-arm64-msvc@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-win32-arm64-msvc@npm:15.3.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@next/swc-win32-ia32-msvc@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-win32-ia32-msvc@npm:14.2.26" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@next/swc-win32-x64-msvc@npm:14.2.26": - version: 14.2.26 - resolution: "@next/swc-win32-x64-msvc@npm:14.2.26" +"@next/swc-win32-x64-msvc@npm:15.3.4": + version: 15.3.4 + resolution: "@next/swc-win32-x64-msvc@npm:15.3.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -631,13 +855,6 @@ __metadata: languageName: node linkType: hard -"@pkgjs/parseargs@npm:^0.11.0": - version: 0.11.0 - resolution: "@pkgjs/parseargs@npm:0.11.0" - checksum: 10/115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff - languageName: node - linkType: hard - "@rtsao/scc@npm:^1.1.0": version: 1.1.0 resolution: "@rtsao/scc@npm:1.1.0" @@ -645,97 +862,97 @@ __metadata: languageName: node linkType: hard -"@rushstack/eslint-patch@npm:^1.3.3": - version: 1.10.5 - resolution: "@rushstack/eslint-patch@npm:1.10.5" - checksum: 10/769d130dfb088c21e7ce72b552ea58c0d6d790cfe9fcadc4cd66e1282a0213a2c6b570d679723e0d3792a6b6ebfcbdeb5e785261d196017840853b8a5c57dfea +"@rushstack/eslint-patch@npm:^1.10.3": + version: 1.11.0 + resolution: "@rushstack/eslint-patch@npm:1.11.0" + checksum: 10/9bb3eb4a48a9a55e31d302b8b99f405e0f3e436fc3cda8c869fdd3fefd3ac398f5a353cceaa6c8cc5e5baf03ccd88d7965fbd25eb111f1f334415f95fa0f996d languageName: node linkType: hard -"@shikijs/core@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/core@npm:1.26.1" +"@shikijs/core@npm:1.29.2": + version: 1.29.2 + resolution: "@shikijs/core@npm:1.29.2" dependencies: - "@shikijs/engine-javascript": "npm:1.26.1" - "@shikijs/engine-oniguruma": "npm:1.26.1" - "@shikijs/types": "npm:1.26.1" + "@shikijs/engine-javascript": "npm:1.29.2" + "@shikijs/engine-oniguruma": "npm:1.29.2" + "@shikijs/types": "npm:1.29.2" "@shikijs/vscode-textmate": "npm:^10.0.1" "@types/hast": "npm:^3.0.4" hast-util-to-html: "npm:^9.0.4" - checksum: 10/d70dd7e267da624bdc098f9f0295699d30d6bb0873a0c7f239f0664f253532af395208efe10cb0ad6f96b8c63fee439ce7ddbf5bd60b41149e2911fc3c55fc8f + checksum: 10/83dc5e86efc587d513268175ff43e8273567d2c6616d725bff15b08cf243d90f9371d6fa76ba49bb0e9823fc9947c8d8c650c81cfb19c3eb726178326f639a55 languageName: node linkType: hard -"@shikijs/engine-javascript@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/engine-javascript@npm:1.26.1" +"@shikijs/engine-javascript@npm:1.29.2": + version: 1.29.2 + resolution: "@shikijs/engine-javascript@npm:1.29.2" dependencies: - "@shikijs/types": "npm:1.26.1" + "@shikijs/types": "npm:1.29.2" "@shikijs/vscode-textmate": "npm:^10.0.1" - oniguruma-to-es: "npm:0.10.0" - checksum: 10/fd7dac25fe4310bcd055af5163044fa598a65ec54376938f2ee70b8ab864a4d2f4bba2e76353d739ffcf071ffbc57b16147f47e5c9f950bf82f826cf88d3dd85 + oniguruma-to-es: "npm:^2.2.0" + checksum: 10/b49461ff7152650ffdbd77332d1c70e24a2ff1abe869e1038694b410194c6403fe5e8fce104fdd305d10c18702a50c1edbdb87172aa09f11340bc1203ed38488 languageName: node linkType: hard -"@shikijs/engine-oniguruma@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/engine-oniguruma@npm:1.26.1" +"@shikijs/engine-oniguruma@npm:1.29.2": + version: 1.29.2 + resolution: "@shikijs/engine-oniguruma@npm:1.29.2" dependencies: - "@shikijs/types": "npm:1.26.1" + "@shikijs/types": "npm:1.29.2" "@shikijs/vscode-textmate": "npm:^10.0.1" - checksum: 10/17b3355fc226f58ef67d419c9e64a4dc99a63481c66f7ec55fdfb5035363605359414211e40ac8260db9c10c507e587dfac1061c0f57f111050e921e38cd58ef + checksum: 10/bb3e2c01da84d573251ebc289b1ecf815261024dea5bddb93ad56c3504a71cde3630db070be401ed3bbcd23a8a839ec78984a82317f9c9d0bba58daed935b781 languageName: node linkType: hard -"@shikijs/langs@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/langs@npm:1.26.1" +"@shikijs/langs@npm:1.29.2": + version: 1.29.2 + resolution: "@shikijs/langs@npm:1.29.2" dependencies: - "@shikijs/types": "npm:1.26.1" - checksum: 10/b3909ffa30a89aa81e21da3c0af9388dfadab4f5ce9ce6f5a1cc3f7728e46702c02720123bad49dcd3f02e823c0ce9d533534164b0feb57856d2f8ee9504bce2 + "@shikijs/types": "npm:1.29.2" + checksum: 10/01f62d31c653c718a992918357e54d2d312c8da407997565fc19056fbf47f0fadc0f9f4b5fe1e1ba7b7d08e3984fb1f962159503ef0edd81fab5ee8bfdbf9080 languageName: node linkType: hard -"@shikijs/themes@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/themes@npm:1.26.1" +"@shikijs/themes@npm:1.29.2": + version: 1.29.2 + resolution: "@shikijs/themes@npm:1.29.2" dependencies: - "@shikijs/types": "npm:1.26.1" - checksum: 10/5e2f5fe828f1b74dcc4027239768b3fe91567a5e07c3d014747627a7bd8a5ecf22460c59c20924172a96d99f4deed3e81e6f377e5f81239d6c6666d09e12fbd6 + "@shikijs/types": "npm:1.29.2" + checksum: 10/b81606dd882136e3fd751d0829133b5e66b10b8e32bd52ce16e7eac8755891c23e43f3ce06e65b97a75d2bc3b17e7fdb9115e9812679bb820ab163915868fd8b languageName: node linkType: hard -"@shikijs/types@npm:1.26.1": - version: 1.26.1 - resolution: "@shikijs/types@npm:1.26.1" +"@shikijs/types@npm:1.29.2": + version: 1.29.2 + resolution: "@shikijs/types@npm:1.29.2" dependencies: "@shikijs/vscode-textmate": "npm:^10.0.1" "@types/hast": "npm:^3.0.4" - checksum: 10/68ad9307424012cb833c02b7e0db4f0792d6ff9b633591318c76edb5a4ffb84da0de56dbe33b9b62ae810a878fdfd4f9ff6655a067997c664d9b0436266bcb16 + checksum: 10/579e64b6e8cb83023232b8060b08f51cff3909b199d0d1a0c58ed500c898dd34b74bf0457336fa2e6bee1005889e198d7d924347ad616eee30c6ae4c89a67ab8 languageName: node linkType: hard "@shikijs/vscode-textmate@npm:^10.0.1": - version: 10.0.1 - resolution: "@shikijs/vscode-textmate@npm:10.0.1" - checksum: 10/8bb005efbf472a9cac19bb5fb0bb1a2b612e128122e5a9d7b2bb2af674c29912db0e59c547ec458e5333f8f7ac7a8f054a24cb653f11dc20951e299933b416e4 + version: 10.0.2 + resolution: "@shikijs/vscode-textmate@npm:10.0.2" + checksum: 10/d924cba8a01cd9ca12f56ba097d628fdb81455abb85884c8d8a5ae85b628a37dd5907e7691019b97107bd6608c866adf91ba04a1c3bba391281c88e386c044ea languageName: node linkType: hard -"@storybook/components@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/components@npm:8.6.12" +"@storybook/components@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/components@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/ccc6af275bdfbc66de8afb272f59b2b4b6b76bb2961903335cb62e7defae4a2368bd8f5a2008f8598dd8417e5368d824bce836ca96c3c6ff659dbf2f081ec0dd + checksum: 10/d3647505510313aa3c32fd1f8f202eda723ad99bd353b20aa929c5ecab4edc3c86ad06d0eac02f3c6d948e88f13f65ca5fa35ef27c079ef1b92abe8692f23699 languageName: node linkType: hard -"@storybook/core@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/core@npm:8.6.12" +"@storybook/core@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/core@npm:8.6.14" dependencies: - "@storybook/theming": "npm:8.6.12" + "@storybook/theming": "npm:8.6.14" better-opn: "npm:^3.0.2" browser-assert: "npm:^1.2.1" esbuild: "npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0" @@ -751,7 +968,7 @@ __metadata: peerDependenciesMeta: prettier: optional: true - checksum: 10/78776f51b9eae00f9387421b33b646b1dc67ef833fd6272de03399daa7f0ffa248c65b5f24d5d2a9af923a029d06d84d5425e3455302ece542bf47c7a9ec0df6 + checksum: 10/8f8c811edd4ea8dcedcc63a79b3168dc83aa0401e3760990cb5995ea6beaac4026c6ccc1046182f41eed7c09333005f3348d8b42f89fc5dd5b2ce011a9d2a48f languageName: node linkType: hard @@ -762,92 +979,91 @@ __metadata: languageName: node linkType: hard -"@storybook/manager-api@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/manager-api@npm:8.6.12" +"@storybook/manager-api@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/manager-api@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/d1c44c6649a024c4007461c12a15337f5d13532dbaccc4c02f71bd99599fb973e2574eb8f1bc2d93e05da24e4ae43fa47ec637a7c4cccf5ffc67045cafbf087c + checksum: 10/4544b317050b81574f1cd6f911dcb99ee2adbd7190555209171a7dd2233cd331165fa11c16a5977ebe58eeaf26c86bbfcb23f701cfd79a10f0d034dae65197bd languageName: node linkType: hard -"@storybook/preview-api@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/preview-api@npm:8.6.12" +"@storybook/preview-api@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/preview-api@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/d24f11e4e54e9e51297b0f87e1d462b3f14a974b4681f31d93b62b0706ce5b5ed4ffaaac521ec049dcb0e08e7aa7590f2e039aee4bbe9f85033d69474d982f23 + checksum: 10/9b77288f2f627a7c70cfd3e88bdc4348c1425fab6b333ed77efb913e45881bcdf2ca67f1174e47fe978a7993c2a653fb8accf518ba51441cfb9450145101e9d8 languageName: node linkType: hard -"@storybook/react-dom-shim@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/react-dom-shim@npm:8.6.12" +"@storybook/react-dom-shim@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/react-dom-shim@npm:8.6.14" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 - checksum: 10/7677b4fae978209af239471f9eb609db4318815bd4249a0f48b9875482d9ae910b93fbe4db5d7f794ecc2a1249edf40da26af9de673c941c48fccc4007819c96 + storybook: ^8.6.14 + checksum: 10/d14d970b98dc8266d4df80225538fb537449c15877f0f54465dfe52242f0c3f041c975824cc2894f72a3a8023fdffa0a281d90325b95297858e3684913b3cc15 languageName: node linkType: hard "@storybook/react@npm:^8.6.8": - version: 8.6.12 - resolution: "@storybook/react@npm:8.6.12" + version: 8.6.14 + resolution: "@storybook/react@npm:8.6.14" dependencies: - "@storybook/components": "npm:8.6.12" + "@storybook/components": "npm:8.6.14" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:8.6.12" - "@storybook/preview-api": "npm:8.6.12" - "@storybook/react-dom-shim": "npm:8.6.12" - "@storybook/theming": "npm:8.6.12" + "@storybook/manager-api": "npm:8.6.14" + "@storybook/preview-api": "npm:8.6.14" + "@storybook/react-dom-shim": "npm:8.6.14" + "@storybook/theming": "npm:8.6.14" peerDependencies: - "@storybook/test": 8.6.12 + "@storybook/test": 8.6.14 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta - storybook: ^8.6.12 + storybook: ^8.6.14 typescript: ">= 4.2.x" peerDependenciesMeta: "@storybook/test": optional: true typescript: optional: true - checksum: 10/d8258c82743906f48a872a781f3e5a63e9ce3fda2ba3b911e959cf62ebda43989b23746257d97905addb7142ac7e53d0089dc178bcbeea48ed4d37d025dd047b + checksum: 10/a8710dcb80da9df4a78cfb3560a8c0c31c6f6c04902aa95446d4e40f6a9179770ead6f9a0a06fa44d00677cd1cd92eb60fdc57f433035ec722275847139671a4 languageName: node linkType: hard -"@storybook/theming@npm:8.6.12": - version: 8.6.12 - resolution: "@storybook/theming@npm:8.6.12" +"@storybook/theming@npm:8.6.14": + version: 8.6.14 + resolution: "@storybook/theming@npm:8.6.14" peerDependencies: storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 - checksum: 10/c811d9dbb9eaaa680b922111fca126a2985f2238dfb01c1cd23184323eea12899dc9f079063ac42c5e63b0c83de326bd9cc17241e4060ff04e860c57a55fb8b9 + checksum: 10/6936ea3348968fe598ad47421c11a78c6ee2ce62336ea1ce9cb8257e9faa2553d3ac3e443f8a36d35a41b0d60eb169231516649c710582ec68fdead4f23ffc0e languageName: node linkType: hard -"@swc/counter@npm:^0.1.3": +"@swc/counter@npm:0.1.3": version: 0.1.3 resolution: "@swc/counter@npm:0.1.3" checksum: 10/df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 languageName: node linkType: hard -"@swc/helpers@npm:0.5.5": - version: 0.5.5 - resolution: "@swc/helpers@npm:0.5.5" +"@swc/helpers@npm:0.5.15": + version: 0.5.15 + resolution: "@swc/helpers@npm:0.5.15" dependencies: - "@swc/counter": "npm:^0.1.3" - tslib: "npm:^2.4.0" - checksum: 10/1c5ef04f642542212df28c669438f3e0f459dcde7b448a5b1fcafb2e9e4f13e76d8428535a270e91ed123dd2a21189dbed34086b88a8cf68baf84984d6d0e39b + tslib: "npm:^2.8.0" + checksum: 10/e3f32c6deeecfb0fa3f22edff03a7b358e7ce16d27b0f1c8b5cdc3042c5c4ce4da6eac0b781ab7cc4f54696ece657467d56734fb26883439fb00017385364c4c languageName: node linkType: hard -"@types/acorn@npm:^4.0.0": - version: 4.0.6 - resolution: "@types/acorn@npm:4.0.6" +"@tybys/wasm-util@npm:^0.9.0": + version: 0.9.0 + resolution: "@tybys/wasm-util@npm:0.9.0" dependencies: - "@types/estree": "npm:*" - checksum: 10/e00671d5055d06b07feccb8c2841467a4bdd1ab95a29e191d51cacc08c496e1ba1f54edeefab274bb2ba51cb45b0aaaa662a63897650e9d02e9997ad82124ae4 + tslib: "npm:^2.4.0" + checksum: 10/aa58e64753a420ad1eefaf7bacef3dda61d74f9336925943d9244132d5b48d9242f734f1e707fd5ccfa6dd1d8ec8e6debc234b4dedb3a5b0d8486d1f373350b2 languageName: node linkType: hard @@ -870,9 +1086,9 @@ __metadata: linkType: hard "@types/estree@npm:*, @types/estree@npm:^1.0.0": - version: 1.0.6 - resolution: "@types/estree@npm:1.0.6" - checksum: 10/9d35d475095199c23e05b431bcdd1f6fec7380612aed068b14b2a08aa70494de8a9026765a5a91b1073f636fb0368f6d8973f518a31391d519e20c59388ed88d + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10/25a4c16a6752538ffde2826c2cc0c6491d90e69cd6187bef4a006dd2c3c45469f049e643d7e516c515f21484dc3d48fd5c870be158a5beb72f5baf3dc43e4099 languageName: node linkType: hard @@ -892,7 +1108,7 @@ __metadata: languageName: node linkType: hard -"@types/mdast@npm:^4.0.0": +"@types/mdast@npm:^4.0.0, @types/mdast@npm:^4.0.4": version: 4.0.4 resolution: "@types/mdast@npm:4.0.4" dependencies: @@ -909,44 +1125,36 @@ __metadata: linkType: hard "@types/ms@npm:*": - version: 0.7.34 - resolution: "@types/ms@npm:0.7.34" - checksum: 10/f38d36e7b6edecd9badc9cf50474159e9da5fa6965a75186cceaf883278611b9df6669dc3a3cc122b7938d317b68a9e3d573d316fcb35d1be47ec9e468c6bd8a + version: 2.1.0 + resolution: "@types/ms@npm:2.1.0" + checksum: 10/532d2ebb91937ccc4a89389715e5b47d4c66e708d15942fe6cc25add6dc37b2be058230a327dd50f43f89b8b6d5d52b74685a9e8f70516edfc9bdd6be910eff4 languageName: node linkType: hard "@types/node@npm:^20": - version: 20.17.30 - resolution: "@types/node@npm:20.17.30" + version: 20.19.0 + resolution: "@types/node@npm:20.19.0" dependencies: - undici-types: "npm:~6.19.2" - checksum: 10/69fd3b177417be77b459e8f1dd4e78c85c686167086920fbf35a9fda301709bbeee6a87ad2591fb1ddd96c65e725ec6bb527a06496626a1c94367d1361048f8d + undici-types: "npm:~6.21.0" + checksum: 10/76cc44487faa0bf5302c84e5317de4b9727ea4e4b86d59d18d25435f4ccd7e6c584614dea061256f24a097c25a1d82dac1cd134357b42ae28006ba113c97f490 languageName: node linkType: hard -"@types/prop-types@npm:*": - version: 15.7.14 - resolution: "@types/prop-types@npm:15.7.14" - checksum: 10/d0c5407b9ccc3dd5fae0ccf9b1007e7622ba5e6f1c18399b4f24dff33619d469da4b9fa918a374f19dc0d9fe6a013362aab0b844b606cfc10676efba3f5f736d - languageName: node - linkType: hard - -"@types/react-dom@npm:^18.0.0": - version: 18.3.7 - resolution: "@types/react-dom@npm:18.3.7" +"@types/react-dom@npm:19.1.6": + version: 19.1.6 + resolution: "@types/react-dom@npm:19.1.6" peerDependencies: - "@types/react": ^18.0.0 - checksum: 10/317569219366d487a3103ba1e5e47154e95a002915fdcf73a44162c48fe49c3a57fcf7f57fc6979e70d447112681e6b13c6c3c1df289db8b544df4aab2d318f3 + "@types/react": ^19.0.0 + checksum: 10/b5b20b7f0797f34c5a11915b74dcf8b3b7a9da9fea90279975ce6f150ca5d31bb069dbb0838638a5e9e168098aa4bb4a6f61d078efa1bbb55d7f0bdfe47bb142 languageName: node linkType: hard -"@types/react@npm:^18.0.0": - version: 18.3.21 - resolution: "@types/react@npm:18.3.21" +"@types/react@npm:19.1.8": + version: 19.1.8 + resolution: "@types/react@npm:19.1.8" dependencies: - "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/89adc2fe391fd63b620db0aaa10b2be89fad338039415fd748e60c962e47bf2b0f1897cb5226f181eda963f37a1c8ac1bf0b3b29a0e35313bacd0355e5d6c736 + checksum: 10/a3e6fe0f60f22828ef887f30993aa147b71532d7b1219dd00d246277eb7a9ca01ec533096237fa21ca1bccb3653373b4e8e59e5ae59f9c793058384bbc1f4d5c languageName: node linkType: hard @@ -965,120 +1173,144 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": - version: 8.19.1 - resolution: "@typescript-eslint/eslint-plugin@npm:8.19.1" + version: 8.34.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.34.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.19.1" - "@typescript-eslint/type-utils": "npm:8.19.1" - "@typescript-eslint/utils": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" + "@typescript-eslint/scope-manager": "npm:8.34.0" + "@typescript-eslint/type-utils": "npm:8.34.0" + "@typescript-eslint/utils": "npm:8.34.0" + "@typescript-eslint/visitor-keys": "npm:8.34.0" graphemer: "npm:^1.4.0" - ignore: "npm:^5.3.1" + ignore: "npm:^7.0.0" natural-compare: "npm:^1.4.0" - ts-api-utils: "npm:^2.0.0" + ts-api-utils: "npm:^2.1.0" peerDependencies: - "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + "@typescript-eslint/parser": ^8.34.0 eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/c9a6d3181ec01068075b85ad3ac454910b4452281d60c775cc7229827f6d6a076b7336f5f07a7ad89bf08b3224f6a49aa20342b9438702393bee0aa7315d23b2 + typescript: ">=4.8.4 <5.9.0" + checksum: 10/224f9e8a596e3c37fade2f2a1a9efce2fad652a768710693458e2b7c7f88c3a0e7bbbbc46d34d839c9373861fac542de6b9a7e132e36e2819b63840b9529e605 languageName: node linkType: hard "@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": - version: 8.19.1 - resolution: "@typescript-eslint/parser@npm:8.19.1" + version: 8.34.0 + resolution: "@typescript-eslint/parser@npm:8.34.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.19.1" - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/typescript-estree": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" + "@typescript-eslint/scope-manager": "npm:8.34.0" + "@typescript-eslint/types": "npm:8.34.0" + "@typescript-eslint/typescript-estree": "npm:8.34.0" + "@typescript-eslint/visitor-keys": "npm:8.34.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/da3db63ff655cf0fb91745ba8e52d853386f601cf6106d36f4541efcb9e2c6c3b82c6743b15680eff9eafeccaf31c9b26191a955e66ae19de9172f67335463ab + typescript: ">=4.8.4 <5.9.0" + checksum: 10/b4c03ff2f09fd800a8f28c24289d24e2f4bfb4745c122f5f496bf832b06f0f37b1ab31ce8d7590ff1f83253de3306d145ef7b3c7b853a4ae716cb7ff443d1c27 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/scope-manager@npm:8.19.1" +"@typescript-eslint/project-service@npm:8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/project-service@npm:8.34.0" dependencies: - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" - checksum: 10/6ffc78b15367f211eb6650459ca2bb6bfe4c1fa95a3474adc08ee9a20c250b2e0e02fd99be36bd3dad74967ecd9349e792b5d818d85735cba40f1b5c236074d1 - languageName: node - linkType: hard - -"@typescript-eslint/type-utils@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/type-utils@npm:8.19.1" - dependencies: - "@typescript-eslint/typescript-estree": "npm:8.19.1" - "@typescript-eslint/utils": "npm:8.19.1" + "@typescript-eslint/tsconfig-utils": "npm:^8.34.0" + "@typescript-eslint/types": "npm:^8.34.0" debug: "npm:^4.3.4" - ts-api-utils: "npm:^2.0.0" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10/04763896215c208c6b29e0b4f66ee0621878cd88fb6d9008c543db57f1d6b5d7fcc88f048c9a66ba2ed797f68e563c350e1b65403349ef75a4bc419072cef3c8 + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/scope-manager@npm:8.34.0" + dependencies: + "@typescript-eslint/types": "npm:8.34.0" + "@typescript-eslint/visitor-keys": "npm:8.34.0" + checksum: 10/fec7bb94fb3848bdf5ab9cfaf634e56aec3ed9bc4d546f65d83bb6511452e5a4b9eed5d09f54efceb9fa3b23a451d409735359237e8c0d51233d6537e5449fa7 + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.34.0, @typescript-eslint/tsconfig-utils@npm:^8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.34.0" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10/cbbca9526bd9c0309c77f9436f68c2c06712779a593a17757f1f7558ece27d9f40db2b37ebf12bd9e19cf227479083b7973c502436a0954a08406d8a598910ba + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/type-utils@npm:8.34.0" + dependencies: + "@typescript-eslint/typescript-estree": "npm:8.34.0" + "@typescript-eslint/utils": "npm:8.34.0" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^2.1.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/123ecda88b057d6a4b68226701f435661440a420fda88cba60b49d7fb3e4f49483164ff174f259e28c0beabb0ed04500462a20faefd78331ba202bf54b01e3ef + typescript: ">=4.8.4 <5.9.0" + checksum: 10/e7c565868b18d66ce5de016455c5ba2dc625a845e05ad563bfdf08b1753faa11d9aef22b9dc5071c57b6e73932748505715e7b47993757f1bc244d4d6f70d688 languageName: node linkType: hard -"@typescript-eslint/types@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/types@npm:8.19.1" - checksum: 10/5833a5f8fdac4a490dd3906a0243a0713fbf138fabb451870c70b0b089c539a9624b467b0913ddc0a225a8284342e7fd31cd506dec53c1a6d8f3c8c8902b9cae +"@typescript-eslint/types@npm:8.34.0, @typescript-eslint/types@npm:^8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/types@npm:8.34.0" + checksum: 10/da4dcee51e78139bdeb5832df836528c519a22c2e39b7737ae660afe024576030165424079f423a131ad56e2dca8f033943d6b48a54b4f4d296a6f7f83f5b494 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/typescript-estree@npm:8.19.1" +"@typescript-eslint/typescript-estree@npm:8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.34.0" dependencies: - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/visitor-keys": "npm:8.19.1" + "@typescript-eslint/project-service": "npm:8.34.0" + "@typescript-eslint/tsconfig-utils": "npm:8.34.0" + "@typescript-eslint/types": "npm:8.34.0" + "@typescript-eslint/visitor-keys": "npm:8.34.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" minimatch: "npm:^9.0.4" semver: "npm:^7.6.0" - ts-api-utils: "npm:^2.0.0" + ts-api-utils: "npm:^2.1.0" peerDependencies: - typescript: ">=4.8.4 <5.8.0" - checksum: 10/5de467452d5ef1a380d441b06cd0134652a0c98cdb4ce31b93eb589f7dc75ef60364d03fd80ca0a48d0c8b268f7258d4f6528b16fe1b89442d60a4bc960fe5f5 + typescript: ">=4.8.4 <5.9.0" + checksum: 10/26817d4c948253eb6a8f49fcd7a8f74c4ffeae7943aef9e1cb90d1b7adbc8e0f66605b0b318dc6eee3eda212882e278a300776b26fe4e2319712cd9822a3a4e4 languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/utils@npm:8.19.1" +"@typescript-eslint/utils@npm:8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/utils@npm:8.34.0" dependencies: - "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.19.1" - "@typescript-eslint/types": "npm:8.19.1" - "@typescript-eslint/typescript-estree": "npm:8.19.1" + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.34.0" + "@typescript-eslint/types": "npm:8.34.0" + "@typescript-eslint/typescript-estree": "npm:8.34.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.8.0" - checksum: 10/bb92116a53fe143ee87e830941afb21d4222a64ca3f2b6dac5c2d9984f981408e60e52b04c32d95208896075ac222fb4ee631c5b0c4826b87d4bd8091c421ab1 + typescript: ">=4.8.4 <5.9.0" + checksum: 10/c51d2015e8076dd2a9d8255746889130aaf298cf9ff8f73114dcf7148f34536d47d883880eec7e3d89ec3f746c2d3f2b749e8fef5e8ad9914132deb5c013efbd languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.19.1": - version: 8.19.1 - resolution: "@typescript-eslint/visitor-keys@npm:8.19.1" +"@typescript-eslint/visitor-keys@npm:8.34.0": + version: 8.34.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.34.0" dependencies: - "@typescript-eslint/types": "npm:8.19.1" + "@typescript-eslint/types": "npm:8.34.0" eslint-visitor-keys: "npm:^4.2.0" - checksum: 10/510eb196e7b7d59d3981d672a75454615159e931fe78e2a64b09607c3cfa45110709b0eb5ac3dd271d757a0d98cf4868ad2f45bf9193f96e9efec3efa92a19c1 + checksum: 10/8a591cb9f922b6fd92107ebdf255425cf7ecd56281d032d944fb38e6be319e6cca7dc49bab6ad1d46390d2ca023c3413c03775e638ec5fd70172150debf7636a languageName: node linkType: hard -"@uiw/codemirror-extensions-basic-setup@npm:4.23.7": - version: 4.23.7 - resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.23.7" +"@uiw/codemirror-extensions-basic-setup@npm:4.23.13": + version: 4.23.13 + resolution: "@uiw/codemirror-extensions-basic-setup@npm:4.23.13" dependencies: "@codemirror/autocomplete": "npm:^6.0.0" "@codemirror/commands": "npm:^6.0.0" @@ -1095,13 +1327,13 @@ __metadata: "@codemirror/search": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 10/7b8cbb9ccc931bc1a6909d009e653f78797e4b851aa9fb8e11f90ae1cea233e643a1951ad4ad9e10123ef166808acee1acff24732ea9fc15cd77164f6b179b91 + checksum: 10/35fd1894f9f7da8f94fa077a70821f92118597e2e2b12782b254b0844f06c1855508421c4cb47de7099a972ef706218c08203116aa93da4e8e1585c8d234015d languageName: node linkType: hard "@uiw/codemirror-themes@npm:^4.23.7": - version: 4.23.12 - resolution: "@uiw/codemirror-themes@npm:4.23.12" + version: 4.23.13 + resolution: "@uiw/codemirror-themes@npm:4.23.13" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" @@ -1110,19 +1342,19 @@ __metadata: "@codemirror/language": ">=6.0.0" "@codemirror/state": ">=6.0.0" "@codemirror/view": ">=6.0.0" - checksum: 10/472121efadf2b9eb110030f06d657cb9693861e1ca360c81c7b0d7aa4533e6e6791737dfd14bcbe496bcb818d33f4cf6a18caf504ec628807e273441f969ef83 + checksum: 10/8c168ed1aa6185c4cc92b66f873e38f6bb50778f1ccadcc99db04cbe97c928e7b924a2f41cb40c4b26328489038d986fe9360605e1668e6c0af2ba931b79523e languageName: node linkType: hard "@uiw/react-codemirror@npm:^4.23.7": - version: 4.23.7 - resolution: "@uiw/react-codemirror@npm:4.23.7" + version: 4.23.13 + resolution: "@uiw/react-codemirror@npm:4.23.13" dependencies: "@babel/runtime": "npm:^7.18.6" "@codemirror/commands": "npm:^6.1.0" "@codemirror/state": "npm:^6.1.1" "@codemirror/theme-one-dark": "npm:^6.0.0" - "@uiw/codemirror-extensions-basic-setup": "npm:4.23.7" + "@uiw/codemirror-extensions-basic-setup": "npm:4.23.13" codemirror: "npm:^6.0.0" peerDependencies: "@babel/runtime": ">=7.11.0" @@ -1132,14 +1364,135 @@ __metadata: codemirror: ">=6.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" - checksum: 10/dc6f1fd2f1863120e29ea331b2e279054bf508f00656d3fed97779f17818ae00b6cf9d74d3b0996800174d444b59702da74ca88c303db563daad85c0824fc952 + checksum: 10/51777d7eb313be0716d3597f829e6ee9982ab2dc3e36dc5219f25cdf680b82a6c0a0951d9adaca85b9c829da92f7971aa6e65bdd50e7610972d89463fe2587a1 languageName: node linkType: hard "@ungap/structured-clone@npm:^1.0.0, @ungap/structured-clone@npm:^1.2.0": - version: 1.2.1 - resolution: "@ungap/structured-clone@npm:1.2.1" - checksum: 10/6770f71e8183311b2871601ddb02d62a26373be7cf2950cb546a345a2305c75b502e36ce80166120aa2f5f1ea1562141684651ebbfcc711c58acd32035d3e545 + version: 1.3.0 + resolution: "@ungap/structured-clone@npm:1.3.0" + checksum: 10/80d6910946f2b1552a2406650051c91bbd1f24a6bf854354203d84fe2714b3e8ce4618f49cc3410494173a1c1e8e9777372fe68dce74bd45faf0a7a1a6ccf448 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-arm64@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.7.13" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-x64@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-darwin-x64@npm:1.7.13" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-freebsd-x64@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.7.13" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.7.13" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.7.13" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-gnu@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.7.13" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-musl@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.7.13" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.7.13" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.7.13" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-musl@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.7.13" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-s390x-gnu@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.7.13" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-gnu@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.7.13" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-musl@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.7.13" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-wasm32-wasi@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.7.13" + dependencies: + "@napi-rs/wasm-runtime": "npm:^0.2.11" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-arm64-msvc@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.7.13" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-ia32-msvc@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.7.13" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-x64-msvc@npm:1.7.13": + version: 1.7.13 + resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.7.13" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1153,11 +1506,11 @@ __metadata: linkType: hard "acorn@npm:^8.0.0, acorn@npm:^8.9.0": - version: 8.14.0 - resolution: "acorn@npm:8.14.0" + version: 8.15.0 + resolution: "acorn@npm:8.15.0" bin: acorn: bin/acorn - checksum: 10/6df29c35556782ca9e632db461a7f97947772c6c1d5438a81f0c873a3da3a792487e83e404d1c6c25f70513e91aa18745f6eafb1fcc3a43ecd1920b21dd173d2 + checksum: 10/77f2de5051a631cf1729c090e5759148459cdb76b5f5c70f890503d629cf5052357b0ce783c0f976dd8a93c5150f59f6d18df1def3f502396a20f81282482fa4 languageName: node linkType: hard @@ -1180,14 +1533,7 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^6.0.1": - version: 6.1.0 - resolution: "ansi-regex@npm:6.1.0" - checksum: 10/495834a53b0856c02acd40446f7130cb0f8284f4a39afdab20d5dc42b2e198b1196119fe887beed8f9055c4ff2055e3b2f6d4641d0be018cdfb64fedf6fc1aac - languageName: node - linkType: hard - -"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": +"ansi-styles@npm:^4.1.0": version: 4.3.0 resolution: "ansi-styles@npm:4.3.0" dependencies: @@ -1196,13 +1542,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^6.1.0": - version: 6.2.1 - resolution: "ansi-styles@npm:6.2.1" - checksum: 10/70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 - languageName: node - linkType: hard - "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -1228,16 +1567,18 @@ __metadata: linkType: hard "array-includes@npm:^3.1.6, array-includes@npm:^3.1.8": - version: 3.1.8 - resolution: "array-includes@npm:3.1.8" + version: 3.1.9 + resolution: "array-includes@npm:3.1.9" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.4" - is-string: "npm:^1.0.7" - checksum: 10/290b206c9451f181fb2b1f79a3bf1c0b66bb259791290ffbada760c79b284eef6f5ae2aeb4bcff450ebc9690edd25732c4c73a3c2b340fcc0f4563aed83bf488 + es-abstract: "npm:^1.24.0" + es-object-atoms: "npm:^1.1.1" + get-intrinsic: "npm:^1.3.0" + is-string: "npm:^1.1.1" + math-intrinsics: "npm:^1.1.0" + checksum: 10/8bfe9a58df74f326b4a76b04ee05c13d871759e888b4ee8f013145297cf5eb3c02cfa216067ebdaac5d74eb9763ac5cad77cdf2773b8ab475833701e032173aa languageName: node linkType: hard @@ -1256,16 +1597,17 @@ __metadata: linkType: hard "array.prototype.findlastindex@npm:^1.2.5": - version: 1.2.5 - resolution: "array.prototype.findlastindex@npm:1.2.5" + version: 1.2.6 + resolution: "array.prototype.findlastindex@npm:1.2.6" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-abstract: "npm:^1.23.2" + es-abstract: "npm:^1.23.9" es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" - es-shim-unscopables: "npm:^1.0.2" - checksum: 10/7c5c821f357cd53ab6cc305de8086430dd8d7a2485db87b13f843e868055e9582b1fd338f02338f67fc3a1603ceaf9610dd2a470b0b506f9d18934780f95b246 + es-object-atoms: "npm:^1.1.1" + es-shim-unscopables: "npm:^1.1.0" + checksum: 10/5ddb6420e820bef6ddfdcc08ce780d0fd5e627e97457919c27e32359916de5a11ce12f7c55073555e503856618eaaa70845d6ca11dcba724766f38eb1c22f7a2 languageName: node linkType: hard @@ -1346,6 +1688,13 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10/1a09379937d846f0ce7614e75071c12826945d4e417db634156bf0e4673c495989302f52186dfa9767a1d9181794554717badd193ca2bbab046ef1da741d8efd + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -1356,9 +1705,9 @@ __metadata: linkType: hard "axe-core@npm:^4.10.0": - version: 4.10.2 - resolution: "axe-core@npm:4.10.2" - checksum: 10/a69423b2ff16c15922c4ea7cf9cc5112728a2817bbe0f2cc212248d648885ffd1ba554e3a341dfc289cd9e67fc0d06f333b5c6837c5c38ca6652507381216fc1 + version: 4.10.3 + resolution: "axe-core@npm:4.10.3" + checksum: 10/9ff51ad0fd0fdec5c0247ea74e8ace5990b54c7f01f8fa3e5cd8ba98b0db24d8ebd7bab4a9bd4d75c28c4edcd1eac455b44c8c6c258c6a98f3d2f88bc60af4cc languageName: node linkType: hard @@ -1393,21 +1742,21 @@ __metadata: linkType: hard "brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" + version: 1.1.12 + resolution: "brace-expansion@npm:1.1.12" dependencies: balanced-match: "npm:^1.0.0" concat-map: "npm:0.0.1" - checksum: 10/faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + checksum: 10/12cb6d6310629e3048cadb003e1aca4d8c9bb5c67c3c321bafdd7e7a50155de081f78ea3e0ed92ecc75a9015e784f301efc8132383132f4f7904ad1ac529c562 languageName: node linkType: hard "brace-expansion@npm:^2.0.1": - version: 2.0.1 - resolution: "brace-expansion@npm:2.0.1" + version: 2.0.2 + resolution: "brace-expansion@npm:2.0.2" dependencies: balanced-match: "npm:^1.0.0" - checksum: 10/a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + checksum: 10/01dff195e3646bc4b0d27b63d9bab84d2ebc06121ff5013ad6e5356daa5a9d6b60fa26cf73c74797f2dc3fbec112af13578d51f75228c1112b26c790a87b0488 languageName: node linkType: hard @@ -1476,9 +1825,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001579": - version: 1.0.30001690 - resolution: "caniuse-lite@npm:1.0.30001690" - checksum: 10/9fb4659eb09a298601b9593739072c481e2f5cc524bd0530e5e0f002e66246da5e866669854dfc0d53195ee36b201dab02f7933a7cdf60ccba7adb2d4a304caf + version: 1.0.30001722 + resolution: "caniuse-lite@npm:1.0.30001722" + checksum: 10/60ad52c891221c894085d450c7308f94768702bed4f0b4b99199e3c3c5926b22d7c7c05f474fcdb484befbd43d1975f8529c8ad8f66770f5c32c5342716ecd0b languageName: node linkType: hard @@ -1490,21 +1839,23 @@ __metadata: "@lezer/highlight": "npm:^1.2.1" "@mdx-js/loader": "npm:^3.1.0" "@mdx-js/react": "npm:^3.1.0" - "@next/mdx": "npm:^15.1.4" + "@next/mdx": "npm:15.3.4" "@storybook/react": "npm:^8.6.8" "@types/mdx": "npm:^2.0.13" "@types/node": "npm:^20" - "@types/react": "npm:^18.0.0" - "@types/react-dom": "npm:^18.0.0" + "@types/react": "npm:19.1.8" + "@types/react-dom": "npm:19.1.6" "@uiw/codemirror-themes": "npm:^4.23.7" "@uiw/react-codemirror": "npm:^4.23.7" eslint: "npm:^8" - eslint-config-next: "npm:14.2.23" + eslint-config-next: "npm:15.3.4" + html-react-parser: "npm:^5.2.5" lightningcss: "npm:^1.28.2" motion: "npm:^12.4.1" - next: "npm:14.2.26" - react: "npm:^18.0.2" - react-dom: "npm:^18.0.2" + next: "npm:15.3.4" + next-mdx-remote-client: "npm:^2.1.2" + react: "npm:19.1.0" + react-dom: "npm:19.1.0" react-frame-component: "npm:^5.2.7" shiki: "npm:^1.26.1" storybook: "npm:^8.6.8" @@ -1595,13 +1946,33 @@ __metadata: languageName: node linkType: hard -"color-name@npm:~1.1.4": +"color-name@npm:^1.0.0, color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" checksum: 10/b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 languageName: node linkType: hard +"color-string@npm:^1.9.0": + version: 1.9.1 + resolution: "color-string@npm:1.9.1" + dependencies: + color-name: "npm:^1.0.0" + simple-swizzle: "npm:^0.2.2" + checksum: 10/72aa0b81ee71b3f4fb1ac9cd839cdbd7a011a7d318ef58e6cb13b3708dca75c7e45029697260488709f1b1c7ac4e35489a87e528156c1e365917d1c4ccb9b9cd + languageName: node + linkType: hard + +"color@npm:^4.2.3": + version: 4.2.3 + resolution: "color@npm:4.2.3" + dependencies: + color-convert: "npm:^2.0.1" + color-string: "npm:^1.9.0" + checksum: 10/b23f5e500a79ea22428db43d1a70642d983405c0dd1f95ef59dbdb9ba66afbb4773b334fa0b75bb10b0552fd7534c6b28d4db0a8b528f91975976e70973c0152 + languageName: node + linkType: hard + "comma-separated-tokens@npm:^2.0.0": version: 2.0.3 resolution: "comma-separated-tokens@npm:2.0.3" @@ -1616,14 +1987,14 @@ __metadata: languageName: node linkType: hard -"crelt@npm:^1.0.5": +"crelt@npm:^1.0.5, crelt@npm:^1.0.6": version: 1.0.6 resolution: "crelt@npm:1.0.6" checksum: 10/5ed326ca6bd243b1dba6b943f665b21c2c04be03271824bc48f20dba324b0f8233e221f8c67312526d24af2b1243c023dc05a41bd8bd05d1a479fd2c72fb39c3 languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": +"cross-spawn@npm:^7.0.2": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -1690,24 +2061,24 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.7": - version: 4.4.0 - resolution: "debug@npm:4.4.0" +"debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0": + version: 4.4.1 + resolution: "debug@npm:4.4.1" dependencies: ms: "npm:^2.1.3" peerDependenciesMeta: supports-color: optional: true - checksum: 10/1847944c2e3c2c732514b93d11886575625686056cd765336212dc15de2d2b29612b6cd80e1afba767bb8e1803b778caf9973e98169ef1a24a7a7009e1820367 + checksum: 10/8e2709b2144f03c7950f8804d01ccb3786373df01e406a0f66928e47001cf2d336cbed9ee137261d4f90d68d8679468c755e3548ed83ddacdc82b194d2468afe languageName: node linkType: hard "decode-named-character-reference@npm:^1.0.0": - version: 1.0.2 - resolution: "decode-named-character-reference@npm:1.0.2" + version: 1.1.0 + resolution: "decode-named-character-reference@npm:1.1.0" dependencies: character-entities: "npm:^2.0.0" - checksum: 10/f4c71d3b93105f20076052f9cb1523a22a9c796b8296cd35eef1ca54239c78d182c136a848b83ff8da2071e3ae2b1d300bf29d00650a6d6e675438cc31b11d78 + checksum: 10/102970fde2d011f307d3789776e68defd75ba4ade1a34951affd1fabb86cd32026fd809f2658c2b600d839a57b6b6a84e2b3a45166d38c8625d66ca11cd702b8 languageName: node linkType: hard @@ -1754,10 +2125,10 @@ __metadata: languageName: node linkType: hard -"detect-libc@npm:^2.0.3": - version: 2.0.3 - resolution: "detect-libc@npm:2.0.3" - checksum: 10/b4ea018d623e077bd395f168a9e81db77370dde36a5b01d067f2ad7989924a81d31cb547ff764acb2aa25d50bb7fdde0b0a93bec02212b0cb430621623246d39 +"detect-libc@npm:^2.0.3, detect-libc@npm:^2.0.4": + version: 2.0.4 + resolution: "detect-libc@npm:2.0.4" + checksum: 10/136e995f8c5ffbc515955b0175d441b967defd3d5f2268e89fa695e9c7170d8bed17993e31a34b04f0fad33d844a3a598e0fd519a8e9be3cad5f67662d96fee0 languageName: node linkType: hard @@ -1788,6 +2159,44 @@ __metadata: languageName: node linkType: hard +"dom-serializer@npm:^2.0.0": + version: 2.0.0 + resolution: "dom-serializer@npm:2.0.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.2" + entities: "npm:^4.2.0" + checksum: 10/e3bf9027a64450bca0a72297ecdc1e3abb7a2912268a9f3f5d33a2e29c1e2c3502c6e9f860fc6625940bfe0cfb57a44953262b9e94df76872fdfb8151097eeb3 + languageName: node + linkType: hard + +"domelementtype@npm:^2.3.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: 10/ee837a318ff702622f383409d1f5b25dd1024b692ef64d3096ff702e26339f8e345820f29a68bcdcea8cfee3531776b3382651232fbeae95612d6f0a75efb4f6 + languageName: node + linkType: hard + +"domhandler@npm:5.0.3, domhandler@npm:^5.0.2, domhandler@npm:^5.0.3": + version: 5.0.3 + resolution: "domhandler@npm:5.0.3" + dependencies: + domelementtype: "npm:^2.3.0" + checksum: 10/809b805a50a9c6884a29f38aec0a4e1b4537f40e1c861950ed47d10b049febe6b79ab72adaeeebb3cc8fc1cd33f34e97048a72a9265103426d93efafa78d3e96 + languageName: node + linkType: hard + +"domutils@npm:^3.2.1": + version: 3.2.2 + resolution: "domutils@npm:3.2.2" + dependencies: + dom-serializer: "npm:^2.0.0" + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + checksum: 10/2e08842151aa406f50fe5e6d494f4ec73c2373199fa00d1f77b56ec604e566b7f226312ae35ab8160bb7f27a27c7285d574c8044779053e499282ca9198be210 + languageName: node + linkType: hard + "dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1": version: 1.0.1 resolution: "dunder-proto@npm:1.0.1" @@ -1799,13 +2208,6 @@ __metadata: languageName: node linkType: hard -"eastasianwidth@npm:^0.2.0": - version: 0.2.0 - resolution: "eastasianwidth@npm:0.2.0" - checksum: 10/9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 - languageName: node - linkType: hard - "emoji-regex-xs@npm:^1.0.0": version: 1.0.0 resolution: "emoji-regex-xs@npm:1.0.0" @@ -1813,13 +2215,6 @@ __metadata: languageName: node linkType: hard -"emoji-regex@npm:^8.0.0": - version: 8.0.0 - resolution: "emoji-regex@npm:8.0.0" - checksum: 10/c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 - languageName: node - linkType: hard - "emoji-regex@npm:^9.2.2": version: 9.2.2 resolution: "emoji-regex@npm:9.2.2" @@ -1827,36 +2222,40 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.15.0": - version: 5.18.0 - resolution: "enhanced-resolve@npm:5.18.0" - dependencies: - graceful-fs: "npm:^4.2.4" - tapable: "npm:^2.2.0" - checksum: 10/e88463ef97b68d40d0da0cd0c572e23f43dba0be622d6d44eae5cafed05f0c5dac43e463a83a86c4f70186d029357f82b56d9e1e47e8fc91dce3d6602f8bd6ce +"entities@npm:^4.2.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 languageName: node linkType: hard -"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9": - version: 1.23.9 - resolution: "es-abstract@npm:1.23.9" +"entities@npm:^6.0.0": + version: 6.0.1 + resolution: "entities@npm:6.0.1" + checksum: 10/62af1307202884349d2867f0aac5c60d8b57102ea0b0e768b16246099512c28e239254ad772d6834e7e14cb1b6f153fc3d0c031934e3183b086c86d3838d874a + languageName: node + linkType: hard + +"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0": + version: 1.24.0 + resolution: "es-abstract@npm:1.24.0" dependencies: array-buffer-byte-length: "npm:^1.0.2" arraybuffer.prototype.slice: "npm:^1.0.4" available-typed-arrays: "npm:^1.0.7" call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.3" + call-bound: "npm:^1.0.4" data-view-buffer: "npm:^1.0.2" data-view-byte-length: "npm:^1.0.2" data-view-byte-offset: "npm:^1.0.1" es-define-property: "npm:^1.0.1" es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" + es-object-atoms: "npm:^1.1.1" es-set-tostringtag: "npm:^2.1.0" es-to-primitive: "npm:^1.3.0" function.prototype.name: "npm:^1.1.8" - get-intrinsic: "npm:^1.2.7" - get-proto: "npm:^1.0.0" + get-intrinsic: "npm:^1.3.0" + get-proto: "npm:^1.0.1" get-symbol-description: "npm:^1.1.0" globalthis: "npm:^1.0.4" gopd: "npm:^1.2.0" @@ -1868,21 +2267,24 @@ __metadata: is-array-buffer: "npm:^3.0.5" is-callable: "npm:^1.2.7" is-data-view: "npm:^1.0.2" + is-negative-zero: "npm:^2.0.3" is-regex: "npm:^1.2.1" + is-set: "npm:^2.0.3" is-shared-array-buffer: "npm:^1.0.4" is-string: "npm:^1.1.1" is-typed-array: "npm:^1.1.15" - is-weakref: "npm:^1.1.0" + is-weakref: "npm:^1.1.1" math-intrinsics: "npm:^1.1.0" - object-inspect: "npm:^1.13.3" + object-inspect: "npm:^1.13.4" object-keys: "npm:^1.1.1" object.assign: "npm:^4.1.7" own-keys: "npm:^1.0.1" - regexp.prototype.flags: "npm:^1.5.3" + regexp.prototype.flags: "npm:^1.5.4" safe-array-concat: "npm:^1.1.3" safe-push-apply: "npm:^1.0.0" safe-regex-test: "npm:^1.1.0" set-proto: "npm:^1.0.0" + stop-iteration-iterator: "npm:^1.1.0" string.prototype.trim: "npm:^1.2.10" string.prototype.trimend: "npm:^1.0.9" string.prototype.trimstart: "npm:^1.0.8" @@ -1891,8 +2293,8 @@ __metadata: typed-array-byte-offset: "npm:^1.0.4" typed-array-length: "npm:^1.0.7" unbox-primitive: "npm:^1.1.0" - which-typed-array: "npm:^1.1.18" - checksum: 10/31a321966d760d88fc2ed984104841b42f4f24fc322b246002b9be0af162e03803ee41fcc3cf8be89e07a27ba3033168f877dd983703cb81422ffe5322a27582 + which-typed-array: "npm:^1.1.19" + checksum: 10/64e07a886f7439cf5ccfc100f9716e6173e10af6071a50a5031afbdde474a3dbc9619d5965da54e55f8908746a9134a46be02af8c732d574b7b81ed3124e2daf languageName: node linkType: hard @@ -1955,12 +2357,12 @@ __metadata: languageName: node linkType: hard -"es-shim-unscopables@npm:^1.0.2": - version: 1.0.2 - resolution: "es-shim-unscopables@npm:1.0.2" +"es-shim-unscopables@npm:^1.0.2, es-shim-unscopables@npm:^1.1.0": + version: 1.1.0 + resolution: "es-shim-unscopables@npm:1.1.0" dependencies: - hasown: "npm:^2.0.0" - checksum: 10/6d3bf91f658a27cc7217cd32b407a0d714393a84d125ad576319b9e83a893bea165cf41270c29e9ceaa56d3cf41608945d7e2a2c31fd51c0009b0c31402b91c7 + hasown: "npm:^2.0.2" + checksum: 10/c351f586c30bbabc62355be49564b2435468b52c3532b8a1663672e3d10dc300197e69c247869dd173e56d86423ab95fc0c10b0939cdae597094e0fdca078cba languageName: node linkType: hard @@ -2011,34 +2413,34 @@ __metadata: linkType: hard "esbuild@npm:^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0": - version: 0.25.0 - resolution: "esbuild@npm:0.25.0" + version: 0.25.5 + resolution: "esbuild@npm:0.25.5" dependencies: - "@esbuild/aix-ppc64": "npm:0.25.0" - "@esbuild/android-arm": "npm:0.25.0" - "@esbuild/android-arm64": "npm:0.25.0" - "@esbuild/android-x64": "npm:0.25.0" - "@esbuild/darwin-arm64": "npm:0.25.0" - "@esbuild/darwin-x64": "npm:0.25.0" - "@esbuild/freebsd-arm64": "npm:0.25.0" - "@esbuild/freebsd-x64": "npm:0.25.0" - "@esbuild/linux-arm": "npm:0.25.0" - "@esbuild/linux-arm64": "npm:0.25.0" - "@esbuild/linux-ia32": "npm:0.25.0" - "@esbuild/linux-loong64": "npm:0.25.0" - "@esbuild/linux-mips64el": "npm:0.25.0" - "@esbuild/linux-ppc64": "npm:0.25.0" - "@esbuild/linux-riscv64": "npm:0.25.0" - "@esbuild/linux-s390x": "npm:0.25.0" - "@esbuild/linux-x64": "npm:0.25.0" - "@esbuild/netbsd-arm64": "npm:0.25.0" - "@esbuild/netbsd-x64": "npm:0.25.0" - "@esbuild/openbsd-arm64": "npm:0.25.0" - "@esbuild/openbsd-x64": "npm:0.25.0" - "@esbuild/sunos-x64": "npm:0.25.0" - "@esbuild/win32-arm64": "npm:0.25.0" - "@esbuild/win32-ia32": "npm:0.25.0" - "@esbuild/win32-x64": "npm:0.25.0" + "@esbuild/aix-ppc64": "npm:0.25.5" + "@esbuild/android-arm": "npm:0.25.5" + "@esbuild/android-arm64": "npm:0.25.5" + "@esbuild/android-x64": "npm:0.25.5" + "@esbuild/darwin-arm64": "npm:0.25.5" + "@esbuild/darwin-x64": "npm:0.25.5" + "@esbuild/freebsd-arm64": "npm:0.25.5" + "@esbuild/freebsd-x64": "npm:0.25.5" + "@esbuild/linux-arm": "npm:0.25.5" + "@esbuild/linux-arm64": "npm:0.25.5" + "@esbuild/linux-ia32": "npm:0.25.5" + "@esbuild/linux-loong64": "npm:0.25.5" + "@esbuild/linux-mips64el": "npm:0.25.5" + "@esbuild/linux-ppc64": "npm:0.25.5" + "@esbuild/linux-riscv64": "npm:0.25.5" + "@esbuild/linux-s390x": "npm:0.25.5" + "@esbuild/linux-x64": "npm:0.25.5" + "@esbuild/netbsd-arm64": "npm:0.25.5" + "@esbuild/netbsd-x64": "npm:0.25.5" + "@esbuild/openbsd-arm64": "npm:0.25.5" + "@esbuild/openbsd-x64": "npm:0.25.5" + "@esbuild/sunos-x64": "npm:0.25.5" + "@esbuild/win32-arm64": "npm:0.25.5" + "@esbuild/win32-ia32": "npm:0.25.5" + "@esbuild/win32-x64": "npm:0.25.5" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -2092,7 +2494,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/451daf6a442df29ec5d528587caa4ce783d41ff4acb93252da5a852b8d36c22e9f84d17f6721d4fbef9a1ba9855bc9fe1f167dd732c11665fe53032f2b89f114 + checksum: 10/0fa4c3b42c6ddf1a008e75a4bb3dcab08ce22ac0b31dd59dc01f7fe8e21380bfaec07a2fe3730a7cf430da5a30142d016714b358666325a4733547afa42be405 languageName: node linkType: hard @@ -2103,27 +2505,27 @@ __metadata: languageName: node linkType: hard -"eslint-config-next@npm:14.2.23": - version: 14.2.23 - resolution: "eslint-config-next@npm:14.2.23" +"eslint-config-next@npm:15.3.4": + version: 15.3.4 + resolution: "eslint-config-next@npm:15.3.4" dependencies: - "@next/eslint-plugin-next": "npm:14.2.23" - "@rushstack/eslint-patch": "npm:^1.3.3" + "@next/eslint-plugin-next": "npm:15.3.4" + "@rushstack/eslint-patch": "npm:^1.10.3" "@typescript-eslint/eslint-plugin": "npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0" "@typescript-eslint/parser": "npm:^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0" eslint-import-resolver-node: "npm:^0.3.6" eslint-import-resolver-typescript: "npm:^3.5.2" - eslint-plugin-import: "npm:^2.28.1" - eslint-plugin-jsx-a11y: "npm:^6.7.1" - eslint-plugin-react: "npm:^7.33.2" - eslint-plugin-react-hooks: "npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + eslint-plugin-import: "npm:^2.31.0" + eslint-plugin-jsx-a11y: "npm:^6.10.0" + eslint-plugin-react: "npm:^7.37.0" + eslint-plugin-react-hooks: "npm:^5.0.0" peerDependencies: - eslint: ^7.23.0 || ^8.0.0 + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 typescript: ">=3.3.1" peerDependenciesMeta: typescript: optional: true - checksum: 10/ee23822e91c155cb0531c786cf11573b8914bc7dfa3b506c45c1d13d4b0c1b515764bd2744daa9c36bddf3bb7cfff434fa6bd169540a2fb933a336df78e7d850 + checksum: 10/6c21254d3383b9158ff5f3b2881cc702bee3d2635b4326757965945691f6e65e25fdfef4f2964382fb4b2f52d9f03b929cb71d267709727df7365e7da80c8c3a languageName: node linkType: hard @@ -2139,17 +2541,16 @@ __metadata: linkType: hard "eslint-import-resolver-typescript@npm:^3.5.2": - version: 3.7.0 - resolution: "eslint-import-resolver-typescript@npm:3.7.0" + version: 3.10.1 + resolution: "eslint-import-resolver-typescript@npm:3.10.1" dependencies: "@nolyfill/is-core-module": "npm:1.0.39" - debug: "npm:^4.3.7" - enhanced-resolve: "npm:^5.15.0" - fast-glob: "npm:^3.3.2" - get-tsconfig: "npm:^4.7.5" - is-bun-module: "npm:^1.0.2" - is-glob: "npm:^4.0.3" - stable-hash: "npm:^0.0.4" + debug: "npm:^4.4.0" + get-tsconfig: "npm:^4.10.0" + is-bun-module: "npm:^2.0.0" + stable-hash: "npm:^0.0.5" + tinyglobby: "npm:^0.2.13" + unrs-resolver: "npm:^1.6.2" peerDependencies: eslint: "*" eslint-plugin-import: "*" @@ -2159,7 +2560,7 @@ __metadata: optional: true eslint-plugin-import-x: optional: true - checksum: 10/8158730c11e562c56ed9bf7236dc75bce35b6992dc32c39ac2f4177ab77fca97b95999850204a6458054243607b54aee88c028a61fed4184f24f425fa1afff01 + checksum: 10/b8d6a9b2045c70f043f722f78c9e65bc0283126f0ad92c8f07473f7647d77f7b1562f765a472f17e06b81897b407091c0ec9f2e4592b158c9fd92d0b0c33de89 languageName: node linkType: hard @@ -2175,7 +2576,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-import@npm:^2.28.1": +"eslint-plugin-import@npm:^2.31.0": version: 2.31.0 resolution: "eslint-plugin-import@npm:2.31.0" dependencies: @@ -2204,7 +2605,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.7.1": +"eslint-plugin-jsx-a11y@npm:^6.10.0": version: 6.10.2 resolution: "eslint-plugin-jsx-a11y@npm:6.10.2" dependencies: @@ -2229,18 +2630,18 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": - version: 5.0.0-canary-7118f5dd7-20230705 - resolution: "eslint-plugin-react-hooks@npm:5.0.0-canary-7118f5dd7-20230705" +"eslint-plugin-react-hooks@npm:^5.0.0": + version: 5.2.0 + resolution: "eslint-plugin-react-hooks@npm:5.2.0" peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 10/0e0e80c21552998b7af2b92a74aec5e862b33f6f16c3e1303d42b5821d68b7ba11c2037bd73e3581fc7d97d9a2e64dd19e202d47d6885f53e33aac87c048d641 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + checksum: 10/ebb79e9cf69ae06e3a7876536653c5e556b5fd8cd9dc49577f10a6e728360e7b6f5ce91f4339b33e93b26e3bb23805418f8b5e75db80baddd617b1dffe73bed1 languageName: node linkType: hard -"eslint-plugin-react@npm:^7.33.2": - version: 7.37.3 - resolution: "eslint-plugin-react@npm:7.37.3" +"eslint-plugin-react@npm:^7.37.0": + version: 7.37.5 + resolution: "eslint-plugin-react@npm:7.37.5" dependencies: array-includes: "npm:^3.1.8" array.prototype.findlast: "npm:^1.2.5" @@ -2252,7 +2653,7 @@ __metadata: hasown: "npm:^2.0.2" jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.8" + object.entries: "npm:^1.1.9" object.fromentries: "npm:^2.0.8" object.values: "npm:^1.2.1" prop-types: "npm:^15.8.1" @@ -2262,7 +2663,7 @@ __metadata: string.prototype.repeat: "npm:^1.0.0" peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - checksum: 10/30042b95c440a962157192f67369d8c9171f7c73e992695e5674c9d28c3cfe4098488eca86dfa7c433d4c8a91243cbafdc80c7e42d2c1720a427ddb36e65457e + checksum: 10/ee1bd4e0ec64f29109d5a625bb703d179c82e0159c86c3f1b52fc1209d2994625a137dae303c333fb308a2e38315e44066d5204998177e31974382f9fda25d5c languageName: node linkType: hard @@ -2284,9 +2685,9 @@ __metadata: linkType: hard "eslint-visitor-keys@npm:^4.2.0": - version: 4.2.0 - resolution: "eslint-visitor-keys@npm:4.2.0" - checksum: 10/9651b3356b01760e586b4c631c5268c0e1a85236e3292bf754f0472f465bf9a856c0ddc261fceace155334118c0151778effafbab981413dbf9288349343fa25 + version: 4.2.1 + resolution: "eslint-visitor-keys@npm:4.2.1" + checksum: 10/3ee00fc6a7002d4b0ffd9dc99e13a6a7882c557329e6c25ab254220d71e5c9c4f89dca4695352949ea678eb1f3ba912a18ef8aac0a7fe094196fd92f441bfce2 languageName: node linkType: hard @@ -2473,6 +2874,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:3.3.1": + version: 3.3.1 + resolution: "fast-glob@npm:3.3.1" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 10/51bcd15472879dfe51d4b01c5b70bbc7652724d39cdd082ba11276dbd7d84db0f6b33757e1938af8b2768a4bf485d9be0c89153beae24ee8331d6dcc7550379f + languageName: node + linkType: hard + "fast-glob@npm:^3.3.2": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" @@ -2501,11 +2915,23 @@ __metadata: linkType: hard "fastq@npm:^1.6.0": - version: 1.18.0 - resolution: "fastq@npm:1.18.0" + version: 1.19.1 + resolution: "fastq@npm:1.19.1" dependencies: reusify: "npm:^1.0.4" - checksum: 10/c5b501333dc8f5d188d828ea162aad03ff5a81aed185b6d4a5078aaeae0a42babc34296d7af13ebce86401cccd93c9b7b3cbf61280821c5f20af233378b42fbb + checksum: 10/75679dc226316341c4f2a6b618571f51eac96779906faecd8921b984e844d6ae42fabb2df69b1071327d398d5716693ea9c9c8941f64ac9e89ec2032ce59d730 + languageName: node + linkType: hard + +"fdir@npm:^6.4.4": + version: 6.4.6 + resolution: "fdir@npm:6.4.6" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10/c186ba387e7b75ccf874a098d9bc5fe0af0e9c52fc56f8eac8e80aa4edb65532684bf2bf769894ff90f53bf221d6136692052d31f07a9952807acae6cbe7ee50 languageName: node linkType: hard @@ -2549,9 +2975,9 @@ __metadata: linkType: hard "flatted@npm:^3.2.9": - version: 3.3.2 - resolution: "flatted@npm:3.3.2" - checksum: 10/ac3c159742e01d0e860a861164bcfd35bb567ccbebb8a0dd041e61cf3c64a435b917dd1e7ed1c380c2ebca85735fb16644485ec33665bc6aafc3b316aa1eed44 + version: 3.3.3 + resolution: "flatted@npm:3.3.3" + checksum: 10/8c96c02fbeadcf4e8ffd0fa24983241e27698b0781295622591fc13585e2f226609d95e422bcf2ef044146ffacb6b68b1f20871454eddf75ab3caa6ee5f4a1fe languageName: node linkType: hard @@ -2564,22 +2990,12 @@ __metadata: languageName: node linkType: hard -"foreground-child@npm:^3.1.0": - version: 3.3.0 - resolution: "foreground-child@npm:3.3.0" +"framer-motion@npm:^12.17.0": + version: 12.17.0 + resolution: "framer-motion@npm:12.17.0" dependencies: - cross-spawn: "npm:^7.0.0" - signal-exit: "npm:^4.0.1" - checksum: 10/e3a60480f3a09b12273ce2c5fcb9514d98dd0e528f58656a1b04680225f918d60a2f81f6a368f2f3b937fcee9cfc0cbf16f1ad9a0bc6a3a6e103a84c9a90087e - languageName: node - linkType: hard - -"framer-motion@npm:^12.5.0": - version: 12.5.0 - resolution: "framer-motion@npm:12.5.0" - dependencies: - motion-dom: "npm:^12.5.0" - motion-utils: "npm:^12.5.0" + motion-dom: "npm:^12.17.0" + motion-utils: "npm:^12.12.1" tslib: "npm:^2.4.0" peerDependencies: "@emotion/is-prop-valid": "*" @@ -2592,7 +3008,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 10/6659e0b704d3216dafdcb11175e3c5f55d536469ddd8ad62b37d00bc7e893d914989791c018cfdfa17b3142b655f0d85226adc94ed390c1524312c3653b8c75f + checksum: 10/803b57cb7ec7200938c9425392a66839c96bf5a800ff14b38d9e689a47341678c53ce54765f68f0a186cfad6c1270b2ad46a75aeff67b2a2e2f3b846852d792c languageName: node linkType: hard @@ -2670,12 +3086,12 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.7.5": - version: 4.8.1 - resolution: "get-tsconfig@npm:4.8.1" +"get-tsconfig@npm:^4.10.0": + version: 4.10.1 + resolution: "get-tsconfig@npm:4.10.1" dependencies: resolve-pkg-maps: "npm:^1.0.0" - checksum: 10/3fb5a8ad57b9633eaea085d81661e9e5c9f78b35d8f8689eaf8b8b45a2a3ebf3b3422266d4d7df765e308cc1e6231648d114803ab3d018332e29916f2c1de036 + checksum: 10/04d63f47fdecaefbd1f73ec02949be4ec4db7d6d9fbc8d4e81f9a4bb1c6f876e48943712f2f9236643d3e4d61d9a7b06da08564d08b034631ebe3f5605bef237 languageName: node linkType: hard @@ -2697,21 +3113,6 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.3.10": - version: 10.3.10 - resolution: "glob@npm:10.3.10" - dependencies: - foreground-child: "npm:^3.1.0" - jackspeak: "npm:^2.3.5" - minimatch: "npm:^9.0.1" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry: "npm:^1.10.1" - bin: - glob: dist/esm/bin.mjs - checksum: 10/38bdb2c9ce75eb5ed168f309d4ed05b0798f640b637034800a6bf306f39d35409bf278b0eaaffaec07591085d3acb7184a201eae791468f0f617771c2486a6a8 - languageName: node - linkType: hard - "glob@npm:^7.1.3": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -2752,13 +3153,6 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4": - version: 4.2.11 - resolution: "graceful-fs@npm:4.2.11" - checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 - languageName: node - linkType: hard - "graphemer@npm:^1.4.0": version: 1.4.0 resolution: "graphemer@npm:1.4.0" @@ -2814,7 +3208,7 @@ __metadata: languageName: node linkType: hard -"hasown@npm:^2.0.0, hasown@npm:^2.0.2": +"hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" dependencies: @@ -2824,8 +3218,8 @@ __metadata: linkType: hard "hast-util-to-estree@npm:^3.0.0": - version: 3.1.1 - resolution: "hast-util-to-estree@npm:3.1.1" + version: 3.1.3 + resolution: "hast-util-to-estree@npm:3.1.3" dependencies: "@types/estree": "npm:^1.0.0" "@types/estree-jsx": "npm:^1.0.0" @@ -2838,18 +3232,18 @@ __metadata: mdast-util-mdx-expression: "npm:^2.0.0" mdast-util-mdx-jsx: "npm:^3.0.0" mdast-util-mdxjs-esm: "npm:^2.0.0" - property-information: "npm:^6.0.0" + property-information: "npm:^7.0.0" space-separated-tokens: "npm:^2.0.0" - style-to-object: "npm:^1.0.0" + style-to-js: "npm:^1.0.0" unist-util-position: "npm:^5.0.0" zwitch: "npm:^2.0.0" - checksum: 10/f72b0d72d6f3e1d55a876e175716b78bf93b8246fac8dd6db6b46c03b0288d03f40644606f36c00e8f12829a6bef0e7a73b405825b651a94b41f0bc5b53b92b4 + checksum: 10/efe69c8af68f021d853e70916c6e940765be519aec8703765898c1c3814424b0470f70c0272cf4ac06dcaf6d6f3cc781ebf034701ed240a33ac691d1f5eaf65b languageName: node linkType: hard "hast-util-to-html@npm:^9.0.4": - version: 9.0.4 - resolution: "hast-util-to-html@npm:9.0.4" + version: 9.0.5 + resolution: "hast-util-to-html@npm:9.0.5" dependencies: "@types/hast": "npm:^3.0.0" "@types/unist": "npm:^3.0.0" @@ -2858,17 +3252,17 @@ __metadata: hast-util-whitespace: "npm:^3.0.0" html-void-elements: "npm:^3.0.0" mdast-util-to-hast: "npm:^13.0.0" - property-information: "npm:^6.0.0" + property-information: "npm:^7.0.0" space-separated-tokens: "npm:^2.0.0" stringify-entities: "npm:^4.0.0" zwitch: "npm:^2.0.4" - checksum: 10/a0b4ed9058e57fa2ca010d10c077fda78d2ab2af99f5bd09fe4b9948970025ac4a2a1a03ec7e2e0f3b0444066b1b35d602fa3e9fbd9b7fc9cdd35d0cafa909ca + checksum: 10/4278e5246f43adf7a30bf3b87db4a4e628b5362b8c149eb4360bf7e0f731f81fa31e4e844e8090d1dd5f739d0884678f8165b28f97c14139e4da4f945f9ff5f7 languageName: node linkType: hard "hast-util-to-jsx-runtime@npm:^2.0.0": - version: 2.3.2 - resolution: "hast-util-to-jsx-runtime@npm:2.3.2" + version: 2.3.6 + resolution: "hast-util-to-jsx-runtime@npm:2.3.6" dependencies: "@types/estree": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -2880,12 +3274,12 @@ __metadata: mdast-util-mdx-expression: "npm:^2.0.0" mdast-util-mdx-jsx: "npm:^3.0.0" mdast-util-mdxjs-esm: "npm:^2.0.0" - property-information: "npm:^6.0.0" + property-information: "npm:^7.0.0" space-separated-tokens: "npm:^2.0.0" - style-to-object: "npm:^1.0.0" + style-to-js: "npm:^1.0.0" unist-util-position: "npm:^5.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/3d72f83e2d8c29adc6576d2c6b41479902fd51fac8cfb2b67c35fd68fcb9c25c274699442e4dee901a7ab926a0ff6851713ed5d92448ac09ae0f10daf293476c + checksum: 10/111bd69f482952c7591cb4e1d3face25f1c18849b310a4d6cacc91e2d2cbc965d455fad35c059b8f0cfd762e933b826a7090b6f3098dece08307a6569de8f1d8 languageName: node linkType: hard @@ -2898,6 +3292,34 @@ __metadata: languageName: node linkType: hard +"html-dom-parser@npm:5.1.1": + version: 5.1.1 + resolution: "html-dom-parser@npm:5.1.1" + dependencies: + domhandler: "npm:5.0.3" + htmlparser2: "npm:10.0.0" + checksum: 10/85bbaa8699d40d54fd64f5472088199178a6c3dd6a907358ac476d9c511cb8ab10bff1469a785411e8b831a73ac08348392e56076eab6d100a3ec19dccc722ad + languageName: node + linkType: hard + +"html-react-parser@npm:^5.2.5": + version: 5.2.5 + resolution: "html-react-parser@npm:5.2.5" + dependencies: + domhandler: "npm:5.0.3" + html-dom-parser: "npm:5.1.1" + react-property: "npm:2.0.2" + style-to-js: "npm:1.1.16" + peerDependencies: + "@types/react": 0.14 || 15 || 16 || 17 || 18 || 19 + react: 0.14 || 15 || 16 || 17 || 18 || 19 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10/22852dc4826d3be9506e238e37a05c23b432675aac33f22bd5741caa195a32e99de99d2b99037fda532f198afbcdeacfc0b27627d6e529143a98c8f191e99c52 + languageName: node + linkType: hard + "html-void-elements@npm:^3.0.0": version: 3.0.0 resolution: "html-void-elements@npm:3.0.0" @@ -2905,20 +3327,39 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0, ignore@npm:^5.3.1": +"htmlparser2@npm:10.0.0": + version: 10.0.0 + resolution: "htmlparser2@npm:10.0.0" + dependencies: + domelementtype: "npm:^2.3.0" + domhandler: "npm:^5.0.3" + domutils: "npm:^3.2.1" + entities: "npm:^6.0.0" + checksum: 10/768870f0e020dca19dc45df206cb6ac466c5dba6566c8fca4ca880347eed409f9977028d08644ac516bca8628ac9c7ded5a3847dc3ee1c043f049abf9e817154 + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" checksum: 10/cceb6a457000f8f6a50e1196429750d782afce5680dd878aa4221bd79972d68b3a55b4b1458fc682be978f4d3c6a249046aa0880637367216444ab7b014cfc98 languageName: node linkType: hard +"ignore@npm:^7.0.0": + version: 7.0.5 + resolution: "ignore@npm:7.0.5" + checksum: 10/f134b96a4de0af419196f52c529d5c6120c4456ff8a6b5a14ceaaa399f883e15d58d2ce651c9b69b9388491d4669dda47285d307e827de9304a53a1824801bc6 + languageName: node + linkType: hard + "import-fresh@npm:^3.2.1": - version: 3.3.0 - resolution: "import-fresh@npm:3.3.0" + version: 3.3.1 + resolution: "import-fresh@npm:3.3.1" dependencies: parent-module: "npm:^1.0.0" resolve-from: "npm:^4.0.0" - checksum: 10/2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa + checksum: 10/a06b19461b4879cc654d46f8a6244eb55eb053437afd4cbb6613cad6be203811849ed3e4ea038783092879487299fda24af932b86bdfff67c9055ba3612b8c87 languageName: node linkType: hard @@ -3002,15 +3443,23 @@ __metadata: languageName: node linkType: hard +"is-arrayish@npm:^0.3.1": + version: 0.3.2 + resolution: "is-arrayish@npm:0.3.2" + checksum: 10/81a78d518ebd8b834523e25d102684ee0f7e98637136d3bdc93fd09636350fa06f1d8ca997ea28143d4d13cb1b69c0824f082db0ac13e1ab3311c10ffea60ade + languageName: node + linkType: hard + "is-async-function@npm:^2.0.0": - version: 2.1.0 - resolution: "is-async-function@npm:2.1.0" + version: 2.1.1 + resolution: "is-async-function@npm:2.1.1" dependencies: + async-function: "npm:^1.0.0" call-bound: "npm:^1.0.3" get-proto: "npm:^1.0.1" has-tostringtag: "npm:^1.0.2" safe-regex-test: "npm:^1.1.0" - checksum: 10/865f0e915b7d9aa5577327e7550bf77a4bb2b7bca497d32564e1d32dbe0ccb7eca1c9c56dd679b6dd2bd7feddb91574e773922276871a5958e53ae8473db4742 + checksum: 10/7c2ac7efdf671e03265e74a043bcb1c0a32e226bc2a42dfc5ec8644667df668bbe14b91c08e6c1414f392f8cf86cd1d489b3af97756e2c7a49dd1ba63fd40ca6 languageName: node linkType: hard @@ -3024,21 +3473,21 @@ __metadata: linkType: hard "is-boolean-object@npm:^1.2.1": - version: 1.2.1 - resolution: "is-boolean-object@npm:1.2.1" + version: 1.2.2 + resolution: "is-boolean-object@npm:1.2.2" dependencies: - call-bound: "npm:^1.0.2" + call-bound: "npm:^1.0.3" has-tostringtag: "npm:^1.0.2" - checksum: 10/5a15524635c9334ebbd668f20a6cbf023adceed5725ec96a50056d21ae65f52759d04a8fa7d7febf00ff3bc4e6d3837638eb84be572f287bcfd15f8b8facde43 + checksum: 10/051fa95fdb99d7fbf653165a7e6b2cba5d2eb62f7ffa81e793a790f3fb5366c91c1b7b6af6820aa2937dd86c73aa3ca9d9ca98f500988457b1c59692c52ba911 languageName: node linkType: hard -"is-bun-module@npm:^1.0.2": - version: 1.3.0 - resolution: "is-bun-module@npm:1.3.0" +"is-bun-module@npm:^2.0.0": + version: 2.0.0 + resolution: "is-bun-module@npm:2.0.0" dependencies: - semver: "npm:^7.6.3" - checksum: 10/b23d9ec7b4d4bfd89e4e72b5cd52e1bc153facad59fdd7394c656f8859a78740ef35996a2066240a32f39cc9a9da4b4eb69e68df3c71755a61ebbaf56d3daef0 + semver: "npm:^7.7.1" + checksum: 10/cded5a1a58368b847872d08617975d620ad94426d76a932f3e08d55b4574d199e0a62a4fb024fa2dc444200b71719eb0bffc5d3d1e1cc82e29b293bb8d66a990 languageName: node linkType: hard @@ -3111,13 +3560,6 @@ __metadata: languageName: node linkType: hard -"is-fullwidth-code-point@npm:^3.0.0": - version: 3.0.0 - resolution: "is-fullwidth-code-point@npm:3.0.0" - checksum: 10/44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 - languageName: node - linkType: hard - "is-generator-function@npm:^1.0.10, is-generator-function@npm:^1.0.7": version: 1.1.0 resolution: "is-generator-function@npm:1.1.0" @@ -3153,6 +3595,13 @@ __metadata: languageName: node linkType: hard +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: 10/8fe5cffd8d4fb2ec7b49d657e1691889778d037494c6f40f4d1a524cadd658b4b53ad7b6b73a59bcb4b143ae9a3d15829af864b2c0f9d65ac1e678c4c80f17e5 + languageName: node + linkType: hard + "is-number-object@npm:^1.1.1": version: 1.1.1 resolution: "is-number-object@npm:1.1.1" @@ -3212,7 +3661,7 @@ __metadata: languageName: node linkType: hard -"is-string@npm:^1.0.7, is-string@npm:^1.1.1": +"is-string@npm:^1.1.1": version: 1.1.1 resolution: "is-string@npm:1.1.1" dependencies: @@ -3249,12 +3698,12 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.0": - version: 1.1.0 - resolution: "is-weakref@npm:1.1.0" +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": + version: 1.1.1 + resolution: "is-weakref@npm:1.1.1" dependencies: - call-bound: "npm:^1.0.2" - checksum: 10/89e627cc1763ea110574bb408fcf060ede47e70437d9278858bc939e3b3f7e4b7c558610b733da5f2ad6084d9f12b9c714b011ccf3fa771ec87e221c22bed910 + call-bound: "npm:^1.0.3" + checksum: 10/543506fd8259038b371bb083aac25b16cb4fd8b12fc58053aa3d45ac28dfd001cd5c6dffbba7aeea4213c74732d46b6cb2cfb5b412eed11f2db524f3f97d09a0 languageName: node linkType: hard @@ -3305,20 +3754,7 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" - dependencies: - "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10/6e6490d676af8c94a7b5b29b8fd5629f21346911ebe2e32931c2a54210134408171c24cee1a109df2ec19894ad04a429402a8438cbf5cc2794585d35428ace76 - languageName: node - linkType: hard - -"js-tokens@npm:^3.0.0 || ^4.0.0": +"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" checksum: 10/af37d0d913fb56aec6dc0074c163cc71cd23c0b8aad5c2350747b6721d37ba118af35abdd8b33c47ec2800de07dedb16a527ca9c530ee004093e04958bd0cbf2 @@ -3422,91 +3858,91 @@ __metadata: languageName: node linkType: hard -"lightningcss-darwin-arm64@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-darwin-arm64@npm:1.29.3" +"lightningcss-darwin-arm64@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-darwin-arm64@npm:1.30.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lightningcss-darwin-x64@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-darwin-x64@npm:1.29.3" +"lightningcss-darwin-x64@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-darwin-x64@npm:1.30.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lightningcss-freebsd-x64@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-freebsd-x64@npm:1.29.3" +"lightningcss-freebsd-x64@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-freebsd-x64@npm:1.30.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lightningcss-linux-arm-gnueabihf@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-arm-gnueabihf@npm:1.29.3" +"lightningcss-linux-arm-gnueabihf@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.30.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"lightningcss-linux-arm64-gnu@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-arm64-gnu@npm:1.29.3" +"lightningcss-linux-arm64-gnu@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-arm64-gnu@npm:1.30.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-arm64-musl@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-arm64-musl@npm:1.29.3" +"lightningcss-linux-arm64-musl@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-arm64-musl@npm:1.30.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"lightningcss-linux-x64-gnu@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-x64-gnu@npm:1.29.3" +"lightningcss-linux-x64-gnu@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-x64-gnu@npm:1.30.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-x64-musl@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-linux-x64-musl@npm:1.29.3" +"lightningcss-linux-x64-musl@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-linux-x64-musl@npm:1.30.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"lightningcss-win32-arm64-msvc@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-win32-arm64-msvc@npm:1.29.3" +"lightningcss-win32-arm64-msvc@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-win32-arm64-msvc@npm:1.30.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"lightningcss-win32-x64-msvc@npm:1.29.3": - version: 1.29.3 - resolution: "lightningcss-win32-x64-msvc@npm:1.29.3" +"lightningcss-win32-x64-msvc@npm:1.30.1": + version: 1.30.1 + resolution: "lightningcss-win32-x64-msvc@npm:1.30.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "lightningcss@npm:^1.28.2": - version: 1.29.3 - resolution: "lightningcss@npm:1.29.3" + version: 1.30.1 + resolution: "lightningcss@npm:1.30.1" dependencies: detect-libc: "npm:^2.0.3" - lightningcss-darwin-arm64: "npm:1.29.3" - lightningcss-darwin-x64: "npm:1.29.3" - lightningcss-freebsd-x64: "npm:1.29.3" - lightningcss-linux-arm-gnueabihf: "npm:1.29.3" - lightningcss-linux-arm64-gnu: "npm:1.29.3" - lightningcss-linux-arm64-musl: "npm:1.29.3" - lightningcss-linux-x64-gnu: "npm:1.29.3" - lightningcss-linux-x64-musl: "npm:1.29.3" - lightningcss-win32-arm64-msvc: "npm:1.29.3" - lightningcss-win32-x64-msvc: "npm:1.29.3" + lightningcss-darwin-arm64: "npm:1.30.1" + lightningcss-darwin-x64: "npm:1.30.1" + lightningcss-freebsd-x64: "npm:1.30.1" + lightningcss-linux-arm-gnueabihf: "npm:1.30.1" + lightningcss-linux-arm64-gnu: "npm:1.30.1" + lightningcss-linux-arm64-musl: "npm:1.30.1" + lightningcss-linux-x64-gnu: "npm:1.30.1" + lightningcss-linux-x64-musl: "npm:1.30.1" + lightningcss-win32-arm64-msvc: "npm:1.30.1" + lightningcss-win32-x64-msvc: "npm:1.30.1" dependenciesMeta: lightningcss-darwin-arm64: optional: true @@ -3528,7 +3964,7 @@ __metadata: optional: true lightningcss-win32-x64-msvc: optional: true - checksum: 10/90933a666975f8e4f2b1bed1ec698a0072f96d2cd118e358932456a46105d62b72b701e4a5da5bd66f0b6e3beac2c65d0be2306acdf3f30603d86143502cce88 + checksum: 10/6c921135216cc498dfcb87e35dffe8432e99306cbd58009c598b1daf20c81cc14535abbd4c1066e5d1faf4080ed44a2995e8ecc343633db4897a2d041b76fb05 languageName: node linkType: hard @@ -3555,7 +3991,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -3566,13 +4002,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^10.2.0": - version: 10.4.3 - resolution: "lru-cache@npm:10.4.3" - checksum: 10/e6e90267360476720fa8e83cc168aa2bf0311f3f2eea20a6ba78b90a885ae72071d9db132f40fda4129c803e7dcec3a6b6a6fbb44ca90b081630b810b5d6a41a - languageName: node - linkType: hard - "markdown-extensions@npm:^2.0.0": version: 2.0.0 resolution: "markdown-extensions@npm:2.0.0" @@ -3622,8 +4051,8 @@ __metadata: linkType: hard "mdast-util-mdx-jsx@npm:^3.0.0": - version: 3.1.3 - resolution: "mdast-util-mdx-jsx@npm:3.1.3" + version: 3.2.0 + resolution: "mdast-util-mdx-jsx@npm:3.2.0" dependencies: "@types/estree-jsx": "npm:^1.0.0" "@types/hast": "npm:^3.0.0" @@ -3637,7 +4066,7 @@ __metadata: stringify-entities: "npm:^4.0.0" unist-util-stringify-position: "npm:^4.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/6c14f271f1380fd512038247f45887b7aa71bbf4acd8881651a317b61706b114f2582f62f7777d0eacd42c4a7b979802825c2a2fd8bb7c46a1ab931ccb1ddf3e + checksum: 10/62cd650a522e5d72ea6afd6d4a557fc86525b802d097a29a2fbe17d22e7b97c502a580611873e4d685777fe77c6ff8d39fb6e37d026b3acbc86c3b24927f4ad9 languageName: node linkType: hard @@ -3654,7 +4083,7 @@ __metadata: languageName: node linkType: hard -"mdast-util-mdxjs-esm@npm:^2.0.0": +"mdast-util-mdxjs-esm@npm:^2.0.0, mdast-util-mdxjs-esm@npm:^2.0.1": version: 2.0.1 resolution: "mdast-util-mdxjs-esm@npm:2.0.1" dependencies: @@ -3729,8 +4158,8 @@ __metadata: linkType: hard "micromark-core-commonmark@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-core-commonmark@npm:2.0.2" + version: 2.0.3 + resolution: "micromark-core-commonmark@npm:2.0.3" dependencies: decode-named-character-reference: "npm:^1.0.0" devlop: "npm:^1.0.0" @@ -3748,13 +4177,13 @@ __metadata: micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/eafa6b9cd6fd9f51efa7795824af9a765e24a4519855a5b6dfcb0f619a93d90599d39a261f626bfcc1dfa64f22430f7a677a83cb6ce4bd8e4eeabc892610c016 + checksum: 10/2b98b9eba1463850ebd8f338f966bd2113dafe764b490ebee3dccab3764d3c48b53fe67673297530e56bf54f58de27dfd1952ed79c5b4e32047cb7f29bd807f2 languageName: node linkType: hard "micromark-extension-mdx-expression@npm:^3.0.0": - version: 3.0.0 - resolution: "micromark-extension-mdx-expression@npm:3.0.0" + version: 3.0.1 + resolution: "micromark-extension-mdx-expression@npm:3.0.1" dependencies: "@types/estree": "npm:^1.0.0" devlop: "npm:^1.0.0" @@ -3764,15 +4193,14 @@ __metadata: micromark-util-events-to-acorn: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/a5592160319d4617362f6b72a6fc44b5570466afa07419d44bcfdd9398a77a5693d7c5f8da7b3ff4682edf6209d4781835f5d2e3166fdf6bba37db456fd2d091 + checksum: 10/a185e1787fe6d49d0e435690affd4b83ce319f88a08c57d2460d37d5c0a75ea64aa49a4a116b6d37f91389dc04351e1826aa834519a9f25fc31e1424962c6eb7 languageName: node linkType: hard "micromark-extension-mdx-jsx@npm:^3.0.0": - version: 3.0.1 - resolution: "micromark-extension-mdx-jsx@npm:3.0.1" + version: 3.0.2 + resolution: "micromark-extension-mdx-jsx@npm:3.0.2" dependencies: - "@types/acorn": "npm:^4.0.0" "@types/estree": "npm:^1.0.0" devlop: "npm:^1.0.0" estree-util-is-identifier-name: "npm:^3.0.0" @@ -3783,7 +4211,7 @@ __metadata: micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/2cc0277d91c3c85d52e88755d17d021b5eab6fa03a578a9965f9d3d2c184dbc1accce63e7f8437a092ceeb602840ef451d4dce6dc9e8c13df0bc76e741080a89 + checksum: 10/a85cdb7c972fbb2cc8f0a64adc808b2b62bc2d79dbdd31fcd3208ff15aafa0198b002022840b2c65b5bff6f2a8c2c4a59a32a89f3482e6e183114b476e98e25c languageName: node linkType: hard @@ -3853,8 +4281,8 @@ __metadata: linkType: hard "micromark-factory-mdx-expression@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-factory-mdx-expression@npm:2.0.2" + version: 2.0.3 + resolution: "micromark-factory-mdx-expression@npm:2.0.3" dependencies: "@types/estree": "npm:^1.0.0" devlop: "npm:^1.0.0" @@ -3865,7 +4293,7 @@ __metadata: micromark-util-types: "npm:^2.0.0" unist-util-position-from-estree: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/d5285fa98018f14a058c7cd4a961aacedd2d3c4f4fddd4c58c16f1e640d1284a8f581f4d00fa3e18c06ed302ce23bca23f6a01edd66064c23c9057e65385a62d + checksum: 10/afadae88a18f31afa564747101e076011c56457454b30294ae55aeea7efee8626ddc3bad0f0f43649008f89b8784782b5adec143fdf477fb352354d76f08db55 languageName: node linkType: hard @@ -3972,10 +4400,9 @@ __metadata: linkType: hard "micromark-util-events-to-acorn@npm:^2.0.0": - version: 2.0.2 - resolution: "micromark-util-events-to-acorn@npm:2.0.2" + version: 2.0.3 + resolution: "micromark-util-events-to-acorn@npm:2.0.3" dependencies: - "@types/acorn": "npm:^4.0.0" "@types/estree": "npm:^1.0.0" "@types/unist": "npm:^3.0.0" devlop: "npm:^1.0.0" @@ -3983,7 +4410,7 @@ __metadata: micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" vfile-message: "npm:^4.0.0" - checksum: 10/475367e716c4d24f2a57464a7f2c8aa507ae36c05b7767fd652895525f3f0a1179ea3219cabccc0f3038bb5e4f9cce5390d530dc56decaa5f1786bda42739810 + checksum: 10/0d87e49b897636dc0e84b4bd06b6fa9e6abcd40ab90c9431e36737c85c444d3db1e4f9b8f51433422b1bedc46f086890ce96671b5a795230c6b7b09cb53d9aba languageName: node linkType: hard @@ -4024,14 +4451,14 @@ __metadata: linkType: hard "micromark-util-subtokenize@npm:^2.0.0": - version: 2.0.3 - resolution: "micromark-util-subtokenize@npm:2.0.3" + version: 2.1.0 + resolution: "micromark-util-subtokenize@npm:2.1.0" dependencies: devlop: "npm:^1.0.0" micromark-util-chunked: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/57b26f129f46424a4670bb47c50f13c7309bb1bc557c02150a788d1634337c1bb25a3523af3d6dffc29aaec873b3bd88fd931bfff34e64284e6436e23873ca22 + checksum: 10/5f18c70cb952a414a4d161f5d6a5254d33c7dfcd56577e592ef2e172a0414058d3531a3554f43538f14e243592fffbc2e68ddaf6a41c54577b3ba7beb555d3dc languageName: node linkType: hard @@ -4043,15 +4470,15 @@ __metadata: linkType: hard "micromark-util-types@npm:^2.0.0": - version: 2.0.1 - resolution: "micromark-util-types@npm:2.0.1" - checksum: 10/69c5e18e6ba4e12473d6fe5f1a7cc113ac1d4bfc23c7ad57b16a5e4bfd09ef48b7c17a40c39d43996f2078ad898efd3f1945007c14f395abd55f2af03d413acd + version: 2.0.2 + resolution: "micromark-util-types@npm:2.0.2" + checksum: 10/a9eb067bd9384eab61942285d53738aa22f3fef4819eaf20249bec6ec13f1e4da2800230fd0ceb7e705108987aa9062fe3e9a8e5e48aa60180db80b9489dc3e2 languageName: node linkType: hard "micromark@npm:^4.0.0": - version: 4.0.1 - resolution: "micromark@npm:4.0.1" + version: 4.0.2 + resolution: "micromark@npm:4.0.2" dependencies: "@types/debug": "npm:^4.0.0" debug: "npm:^4.0.0" @@ -4070,11 +4497,11 @@ __metadata: micromark-util-subtokenize: "npm:^2.0.0" micromark-util-symbol: "npm:^2.0.0" micromark-util-types: "npm:^2.0.0" - checksum: 10/b948b1b239e589826bdaf2835daa9e88873e23d4b9148cd22109a86d4af55b96345cf9fc9059b6b19ae828f64d55e66f376ca3aeb4af3d2b0241560125f5dae6 + checksum: 10/1b85e49c8f71013df2d07a59e477deb72cd325d41cc15f35b2aa52b8b7a93fed45498ce3e18ed34464a9afa9ba8a9210b2509454b2a2d16ac06c7429f562bfac languageName: node linkType: hard -"micromatch@npm:^4.0.8": +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -4093,7 +4520,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1, minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.4": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -4109,34 +4536,27 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0": - version: 7.1.2 - resolution: "minipass@npm:7.1.2" - checksum: 10/c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 - languageName: node - linkType: hard - -"motion-dom@npm:^12.5.0": - version: 12.5.0 - resolution: "motion-dom@npm:12.5.0" +"motion-dom@npm:^12.17.0": + version: 12.17.0 + resolution: "motion-dom@npm:12.17.0" dependencies: - motion-utils: "npm:^12.5.0" - checksum: 10/289e3d5567053e9b84223df9b482bb9180732c0cb6276e7982a73ddad0f76e47f8e0f69e4cdf93d7a689ad021fce837fa8a19c8b61bf56d71bdfc0e590bc3e7e + motion-utils: "npm:^12.12.1" + checksum: 10/54b482d643ca12d895e8a0860809b2b53f2e7c2981d12f3d1230f5bd6154cb59df6ab81a690681df7a526da283aaf76acbf351b148e2b805ad5f8ce97156e061 languageName: node linkType: hard -"motion-utils@npm:^12.5.0": - version: 12.5.0 - resolution: "motion-utils@npm:12.5.0" - checksum: 10/f2d754a9e1c4cd829f0703ce47bbeb3e9967994a9cb35e759f34de16af6c520a4959b04ff6998211ca67dc7bfe0002d9b2465858167b1971b0403f63289f97fc +"motion-utils@npm:^12.12.1": + version: 12.12.1 + resolution: "motion-utils@npm:12.12.1" + checksum: 10/679503df10a1cd7ad58f9ed2f864acb5ecbadf380a668874f0cc6bdc1155278bac0cce73e3f703df19532f2bd922e3500fde179e8f76386e9651f8b1bd0cfe6d languageName: node linkType: hard "motion@npm:^12.4.1": - version: 12.5.0 - resolution: "motion@npm:12.5.0" + version: 12.17.0 + resolution: "motion@npm:12.17.0" dependencies: - framer-motion: "npm:^12.5.0" + framer-motion: "npm:^12.17.0" tslib: "npm:^2.4.0" peerDependencies: "@emotion/is-prop-valid": "*" @@ -4149,7 +4569,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 10/15910d37a14b91236c27c8cc6d12ae157cd1e6b55700fc58a0d271954236fae8e676b1ac9f705cb770c235892925fc6bbdb1f612dfb4018a5d4c0171964f5b3a + checksum: 10/4fde3c4f39fa872cb27a41ddf39dcf20a9a066428ce07cf7455e2a4779d916a47cb3141e8c4c970f9d7b8e8818b822f3eeb86761d61904a18383b82426f5f3ca languageName: node linkType: hard @@ -4161,11 +4581,20 @@ __metadata: linkType: hard "nanoid@npm:^3.3.6": - version: 3.3.8 - resolution: "nanoid@npm:3.3.8" + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" bin: nanoid: bin/nanoid.cjs - checksum: 10/2d1766606cf0d6f47b6f0fdab91761bb81609b2e3d367027aff45e6ee7006f660fb7e7781f4a34799fe6734f1268eeed2e37a5fdee809ade0c2d4eb11b0f9c40 + checksum: 10/73b5afe5975a307aaa3c95dfe3334c52cdf9ae71518176895229b8d65ab0d1c0417dd081426134eb7571c055720428ea5d57c645138161e7d10df80815527c48 + languageName: node + linkType: hard + +"napi-postinstall@npm:^0.2.2": + version: 0.2.4 + resolution: "napi-postinstall@npm:0.2.4" + bin: + napi-postinstall: lib/cli.js + checksum: 10/286785f884b872102fb284847ecc693101f70126b1fc7a97e19293929ce7f08802b41f89398015cce0797070ea3ce6871939a3c1e693c04cf594f7939dbe8cfb languageName: node linkType: hard @@ -4176,31 +4605,50 @@ __metadata: languageName: node linkType: hard -"next@npm:14.2.26": - version: 14.2.26 - resolution: "next@npm:14.2.26" +"next-mdx-remote-client@npm:^2.1.2": + version: 2.1.2 + resolution: "next-mdx-remote-client@npm:2.1.2" dependencies: - "@next/env": "npm:14.2.26" - "@next/swc-darwin-arm64": "npm:14.2.26" - "@next/swc-darwin-x64": "npm:14.2.26" - "@next/swc-linux-arm64-gnu": "npm:14.2.26" - "@next/swc-linux-arm64-musl": "npm:14.2.26" - "@next/swc-linux-x64-gnu": "npm:14.2.26" - "@next/swc-linux-x64-musl": "npm:14.2.26" - "@next/swc-win32-arm64-msvc": "npm:14.2.26" - "@next/swc-win32-ia32-msvc": "npm:14.2.26" - "@next/swc-win32-x64-msvc": "npm:14.2.26" - "@swc/helpers": "npm:0.5.5" + "@babel/code-frame": "npm:^7.27.1" + "@mdx-js/mdx": "npm:^3.1.0" + "@mdx-js/react": "npm:^3.1.0" + remark-mdx-remove-esm: "npm:^1.1.0" + serialize-error: "npm:^12.0.0" + vfile: "npm:^6.0.3" + vfile-matter: "npm:^5.0.1" + peerDependencies: + react: ^19.1.0 + react-dom: ^19.1.0 + checksum: 10/610e95bff6c1dcdb4d1fefc9333ac748f1899cbca1ea551e784cd1e8cfd077c14d6bb8ab27826886f354cc3b9cf700fe25810263f996c53f824a2cfdbc5a064f + languageName: node + linkType: hard + +"next@npm:15.3.4": + version: 15.3.4 + resolution: "next@npm:15.3.4" + dependencies: + "@next/env": "npm:15.3.4" + "@next/swc-darwin-arm64": "npm:15.3.4" + "@next/swc-darwin-x64": "npm:15.3.4" + "@next/swc-linux-arm64-gnu": "npm:15.3.4" + "@next/swc-linux-arm64-musl": "npm:15.3.4" + "@next/swc-linux-x64-gnu": "npm:15.3.4" + "@next/swc-linux-x64-musl": "npm:15.3.4" + "@next/swc-win32-arm64-msvc": "npm:15.3.4" + "@next/swc-win32-x64-msvc": "npm:15.3.4" + "@swc/counter": "npm:0.1.3" + "@swc/helpers": "npm:0.5.15" busboy: "npm:1.6.0" caniuse-lite: "npm:^1.0.30001579" - graceful-fs: "npm:^4.2.11" postcss: "npm:8.4.31" - styled-jsx: "npm:5.1.1" + sharp: "npm:^0.34.1" + styled-jsx: "npm:5.1.6" peerDependencies: "@opentelemetry/api": ^1.1.0 "@playwright/test": ^1.41.2 - react: ^18.2.0 - react-dom: ^18.2.0 + babel-plugin-react-compiler: "*" + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 sass: ^1.3.0 dependenciesMeta: "@next/swc-darwin-arm64": @@ -4217,20 +4665,22 @@ __metadata: optional: true "@next/swc-win32-arm64-msvc": optional: true - "@next/swc-win32-ia32-msvc": - optional: true "@next/swc-win32-x64-msvc": optional: true + sharp: + optional: true peerDependenciesMeta: "@opentelemetry/api": optional: true "@playwright/test": optional: true + babel-plugin-react-compiler: + optional: true sass: optional: true bin: next: dist/bin/next - checksum: 10/9bd8b2ef40076b251d036c6d3a3b435095ff941bab7166ebc3c75bd832c1812eb368f8dae1e56ef4bf600a81d0ad8190d778d610aa062ffa7c4c4f126cae7f13 + checksum: 10/bcc781ca5abba6a29408431f81b57598708871796fe4c70d1187cc92ca4905467a6a3cde32840cb7911099d54a93c1543c130e4dea2b59dbf9753f5850a8efdf languageName: node linkType: hard @@ -4241,10 +4691,10 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.3": - version: 1.13.3 - resolution: "object-inspect@npm:1.13.3" - checksum: 10/14cb973d8381c69e14d7f1c8c75044eb4caf04c6dabcf40ca5c2ce42dc2073ae0bb2a9939eeca142b0c05215afaa1cd5534adb7c8879c32cba2576e045ed8368 +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": + version: 1.13.4 + resolution: "object-inspect@npm:1.13.4" + checksum: 10/aa13b1190ad3e366f6c83ad8a16ed37a19ed57d267385aa4bfdccda833d7b90465c057ff6c55d035a6b2e52c1a2295582b294217a0a3a1ae7abdd6877ef781fb languageName: node linkType: hard @@ -4269,14 +4719,15 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.8": - version: 1.1.8 - resolution: "object.entries@npm:1.1.8" +"object.entries@npm:^1.1.9": + version: 1.1.9 + resolution: "object.entries@npm:1.1.9" dependencies: - call-bind: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" define-properties: "npm:^1.2.1" - es-object-atoms: "npm:^1.0.0" - checksum: 10/2301918fbd1ee697cf6ff7cd94f060c738c0a7d92b22fd24c7c250e9b593642c9707ad2c44d339303c1439c5967d8964251cdfc855f7f6ec55db2dd79e8dc2a7 + es-object-atoms: "npm:^1.1.1" + checksum: 10/24163ab1e1e013796693fc5f5d349e8b3ac0b6a34a7edb6c17d3dd45c6a8854145780c57d302a82512c1582f63720f4b4779d6c1cfba12cbb1420b978802d8a3 languageName: node linkType: hard @@ -4324,14 +4775,14 @@ __metadata: languageName: node linkType: hard -"oniguruma-to-es@npm:0.10.0": - version: 0.10.0 - resolution: "oniguruma-to-es@npm:0.10.0" +"oniguruma-to-es@npm:^2.2.0": + version: 2.3.0 + resolution: "oniguruma-to-es@npm:2.3.0" dependencies: emoji-regex-xs: "npm:^1.0.0" regex: "npm:^5.1.1" regex-recursion: "npm:^5.1.1" - checksum: 10/09756001a74218b26d18940bea3ebb00d1949aa7ac142def3a94a4d256371fea169f52088ea32a6a23ca21338be56427fd9f0264907cee663e7ab147152638f7 + checksum: 10/7ac89fe04791650c21a146e58c985de394597e0ab3eb7d7c46699d09f87d6aca63d9f2470f1473c5adfa16961c360df6858e6a24b2429ebd7c73620ca68aec98 languageName: node linkType: hard @@ -4441,17 +4892,7 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.1": - version: 1.11.1 - resolution: "path-scurry@npm:1.11.1" - dependencies: - lru-cache: "npm:^10.2.0" - minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: 10/5e8845c159261adda6f09814d7725683257fcc85a18f329880ab4d7cc1d12830967eae5d5894e453f341710d5484b8fdbbd4d75181b4d6e1eb2f4dc7aeadc434 - languageName: node - linkType: hard - -"picocolors@npm:^1.0.0": +"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 @@ -4465,10 +4906,17 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: 10/ce617b8da36797d09c0baacb96ca8a44460452c89362d7cb8f70ca46b4158ba8bc3606912de7c818eb4a939f7f9015cef3c766ec8a0c6bfc725fdc078e39c717 + languageName: node + linkType: hard + "possible-typed-array-names@npm:^1.0.0": - version: 1.0.0 - resolution: "possible-typed-array-names@npm:1.0.0" - checksum: 10/8ed3e96dfeea1c5880c1f4c9cb707e5fb26e8be22f14f82ef92df20fd2004e635c62ba47fbe8f2bb63bfd80dac1474be2fb39798da8c2feba2815435d1f749af + version: 1.1.0 + resolution: "possible-typed-array-names@npm:1.1.0" + checksum: 10/2f44137b8d3dd35f4a7ba7469eec1cd9cfbb46ec164b93a5bc1f4c3d68599c9910ee3b91da1d28b4560e9cc8414c3cd56fedc07259c67e52cc774476270d3302 languageName: node linkType: hard @@ -4508,10 +4956,10 @@ __metadata: languageName: node linkType: hard -"property-information@npm:^6.0.0": - version: 6.5.0 - resolution: "property-information@npm:6.5.0" - checksum: 10/fced94f3a09bf651ad1824d1bdc8980428e3e480e6d01e98df6babe2cc9d45a1c52eee9a7736d2006958f9b394eb5964dedd37e23038086ddc143fc2fd5e426c +"property-information@npm:^7.0.0": + version: 7.1.0 + resolution: "property-information@npm:7.1.0" + checksum: 10/896d38a52ad7170de73f832d277c69e76a9605d941ebb3f0d6e56271414a7fdf95ff6d2819e68036b8a0c7d2d4d88bf1d4a5765c032cb19c2343567ee3a14b15 languageName: node linkType: hard @@ -4529,15 +4977,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^18.0.2": - version: 18.3.1 - resolution: "react-dom@npm:18.3.1" +"react-dom@npm:19.1.0": + version: 19.1.0 + resolution: "react-dom@npm:19.1.0" dependencies: - loose-envify: "npm:^1.1.0" - scheduler: "npm:^0.23.2" + scheduler: "npm:^0.26.0" peerDependencies: - react: ^18.3.1 - checksum: 10/3f4b73a3aa083091173b29812b10394dd06f4ac06aff410b74702cfb3aa29d7b0ced208aab92d5272919b612e5cda21aeb1d54191848cf6e46e9e354f3541f81 + react: ^19.1.0 + checksum: 10/c5b58605862c7b0bb044416b01c73647bb8e89717fb5d7a2c279b11815fb7b49b619fe685c404e59f55eb52c66831236cc565c25ee1c2d042739f4a2cc538aa2 languageName: node linkType: hard @@ -4559,25 +5006,30 @@ __metadata: languageName: node linkType: hard -"react@npm:^18.0.2": - version: 18.3.1 - resolution: "react@npm:18.3.1" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10/261137d3f3993eaa2368a83110466fc0e558bc2c7f7ae7ca52d94f03aac945f45146bd85e5f481044db1758a1dbb57879e2fcdd33924e2dde1bdc550ce73f7bf +"react-property@npm:2.0.2": + version: 2.0.2 + resolution: "react-property@npm:2.0.2" + checksum: 10/3a4bc1951b2b7992cb8a2d3f12016dd0920d1c06eb58b456204a6ae1210401d62baece098d3200ed8a0513dde247a5d96ffdb24f354e32ce5a9b26fbd8552668 + languageName: node + linkType: hard + +"react@npm:19.1.0": + version: 19.1.0 + resolution: "react@npm:19.1.0" + checksum: 10/d0180689826fd9de87e839c365f6f361c561daea397d61d724687cae88f432a307d1c0f53a0ee95ddbe3352c10dac41d7ff1ad85530fb24951b27a39e5398db4 languageName: node linkType: hard "recast@npm:^0.23.5": - version: 0.23.9 - resolution: "recast@npm:0.23.9" + version: 0.23.11 + resolution: "recast@npm:0.23.11" dependencies: ast-types: "npm:^0.16.1" esprima: "npm:~4.0.0" source-map: "npm:~0.6.1" tiny-invariant: "npm:^1.3.3" tslib: "npm:^2.0.1" - checksum: 10/d60584be179d81a82fbe58b5bbe009aa42831ee114a21a3e3a22bda91334e0b8a1a4610dca8ecb7f9ea1426da4febc08134d3003085ad6ecee478d1808eb8796 + checksum: 10/a622b7848efe13a59a40c9a1a3a8178433eae1048780e04d7392406e2d67fc29e3efa84b3aa8cfda28fd58989f4b59fa968bed295b739987a666bd11cc57a5b2 languageName: node linkType: hard @@ -4645,13 +5097,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.14.0": - version: 0.14.1 - resolution: "regenerator-runtime@npm:0.14.1" - checksum: 10/5db3161abb311eef8c45bcf6565f4f378f785900ed3945acf740a9888c792f75b98ecb77f0775f3bf95502ff423529d23e94f41d80c8256e8fa05ed4b07cf471 - languageName: node - linkType: hard - "regex-recursion@npm:^5.1.1": version: 5.1.1 resolution: "regex-recursion@npm:5.1.1" @@ -4678,7 +5123,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.3": +"regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" dependencies: @@ -4703,6 +5148,19 @@ __metadata: languageName: node linkType: hard +"remark-mdx-remove-esm@npm:^1.1.0": + version: 1.2.0 + resolution: "remark-mdx-remove-esm@npm:1.2.0" + dependencies: + "@types/mdast": "npm:^4.0.4" + mdast-util-mdxjs-esm: "npm:^2.0.1" + unist-util-remove: "npm:^4.0.0" + peerDependencies: + unified: ^11 + checksum: 10/0a1155e08395ab73f877948455fc04d7457864f7556617efabecae7ea1b441cec2ca7ee9672e16a6cd56f2a16c57a4778f901e77d19052d1dd245de5bdf4618f + languageName: node + linkType: hard + "remark-mdx@npm:^3.0.0": version: 3.1.0 resolution: "remark-mdx@npm:3.1.0" @@ -4726,15 +5184,15 @@ __metadata: linkType: hard "remark-rehype@npm:^11.0.0": - version: 11.1.1 - resolution: "remark-rehype@npm:11.1.1" + version: 11.1.2 + resolution: "remark-rehype@npm:11.1.2" dependencies: "@types/hast": "npm:^3.0.0" "@types/mdast": "npm:^4.0.0" mdast-util-to-hast: "npm:^13.0.0" unified: "npm:^11.0.0" vfile: "npm:^6.0.0" - checksum: 10/39404bd19c57b2b69660be7e3d587ddb2240495845d42fad3bcc506c9c132d07abacb0a20182b73c530857b2da0c463ad5658382b448243ce432152ab49af08d + checksum: 10/b5374a0bf08398431c92740d0cd9b20aea9df44cee12326820ddcc1b7ee642706604006461ea9799554c347e7caf31e7432132a03b97c508e1f77d29c423bd86 languageName: node linkType: hard @@ -4805,9 +5263,9 @@ __metadata: linkType: hard "reusify@npm:^1.0.4": - version: 1.0.4 - resolution: "reusify@npm:1.0.4" - checksum: 10/14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + version: 1.1.0 + resolution: "reusify@npm:1.1.0" + checksum: 10/af47851b547e8a8dc89af144fceee17b80d5beaf5e6f57ed086432d79943434ff67ca526e92275be6f54b6189f6920a24eace75c2657eed32d02c400312b21ec languageName: node linkType: hard @@ -4865,12 +5323,10 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.23.2": - version: 0.23.2 - resolution: "scheduler@npm:0.23.2" - dependencies: - loose-envify: "npm:^1.1.0" - checksum: 10/e8d68b89d18d5b028223edf090092846868a765a591944760942b77ea1f69b17235f7e956696efbb62c8130ab90af7e0949bfb8eba7896335507317236966bc9 +"scheduler@npm:^0.26.0": + version: 0.26.0 + resolution: "scheduler@npm:0.26.0" + checksum: 10/1ecf2e5d7de1a7a132796834afe14a2d589ba7e437615bd8c06f3e0786a3ac3434655e67aac8755d9b14e05754c177e49c064261de2673aaa3c926bc98caa002 languageName: node linkType: hard @@ -4883,12 +5339,21 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.6.3": - version: 7.6.3 - resolution: "semver@npm:7.6.3" +"semver@npm:^7.6.0, semver@npm:^7.6.2, semver@npm:^7.7.1, semver@npm:^7.7.2": + version: 7.7.2 + resolution: "semver@npm:7.7.2" bin: semver: bin/semver.js - checksum: 10/36b1fbe1a2b6f873559cd57b238f1094a053dbfd997ceeb8757d79d1d2089c56d1321b9f1069ce263dc64cfa922fa1d2ad566b39426fe1ac6c723c1487589e10 + checksum: 10/7a24cffcaa13f53c09ce55e05efe25cd41328730b2308678624f8b9f5fc3093fc4d189f47950f0b811ff8f3c3039c24a2c36717ba7961615c682045bf03e1dda + languageName: node + linkType: hard + +"serialize-error@npm:^12.0.0": + version: 12.0.0 + resolution: "serialize-error@npm:12.0.0" + dependencies: + type-fest: "npm:^4.31.0" + checksum: 10/733ddb9a2bd86515d18ef43f6bcb1f55a9d9b900944420e5606725668e64b752e5da971071d8fe1562961a926796257d2edb9fad828ec90a35cc6c32a75449bb languageName: node linkType: hard @@ -4929,6 +5394,81 @@ __metadata: languageName: node linkType: hard +"sharp@npm:^0.34.1": + version: 0.34.2 + resolution: "sharp@npm:0.34.2" + dependencies: + "@img/sharp-darwin-arm64": "npm:0.34.2" + "@img/sharp-darwin-x64": "npm:0.34.2" + "@img/sharp-libvips-darwin-arm64": "npm:1.1.0" + "@img/sharp-libvips-darwin-x64": "npm:1.1.0" + "@img/sharp-libvips-linux-arm": "npm:1.1.0" + "@img/sharp-libvips-linux-arm64": "npm:1.1.0" + "@img/sharp-libvips-linux-ppc64": "npm:1.1.0" + "@img/sharp-libvips-linux-s390x": "npm:1.1.0" + "@img/sharp-libvips-linux-x64": "npm:1.1.0" + "@img/sharp-libvips-linuxmusl-arm64": "npm:1.1.0" + "@img/sharp-libvips-linuxmusl-x64": "npm:1.1.0" + "@img/sharp-linux-arm": "npm:0.34.2" + "@img/sharp-linux-arm64": "npm:0.34.2" + "@img/sharp-linux-s390x": "npm:0.34.2" + "@img/sharp-linux-x64": "npm:0.34.2" + "@img/sharp-linuxmusl-arm64": "npm:0.34.2" + "@img/sharp-linuxmusl-x64": "npm:0.34.2" + "@img/sharp-wasm32": "npm:0.34.2" + "@img/sharp-win32-arm64": "npm:0.34.2" + "@img/sharp-win32-ia32": "npm:0.34.2" + "@img/sharp-win32-x64": "npm:0.34.2" + color: "npm:^4.2.3" + detect-libc: "npm:^2.0.4" + semver: "npm:^7.7.2" + dependenciesMeta: + "@img/sharp-darwin-arm64": + optional: true + "@img/sharp-darwin-x64": + optional: true + "@img/sharp-libvips-darwin-arm64": + optional: true + "@img/sharp-libvips-darwin-x64": + optional: true + "@img/sharp-libvips-linux-arm": + optional: true + "@img/sharp-libvips-linux-arm64": + optional: true + "@img/sharp-libvips-linux-ppc64": + optional: true + "@img/sharp-libvips-linux-s390x": + optional: true + "@img/sharp-libvips-linux-x64": + optional: true + "@img/sharp-libvips-linuxmusl-arm64": + optional: true + "@img/sharp-libvips-linuxmusl-x64": + optional: true + "@img/sharp-linux-arm": + optional: true + "@img/sharp-linux-arm64": + optional: true + "@img/sharp-linux-s390x": + optional: true + "@img/sharp-linux-x64": + optional: true + "@img/sharp-linuxmusl-arm64": + optional: true + "@img/sharp-linuxmusl-x64": + optional: true + "@img/sharp-wasm32": + optional: true + "@img/sharp-win32-arm64": + optional: true + "@img/sharp-win32-ia32": + optional: true + "@img/sharp-win32-x64": + optional: true + checksum: 10/8c7a6f20d58849a6e33bc69c4525f471d57eb3dea0072331b55ab12bae4b8bd8b99b65264aeaec38e54d52d692db13e3261f6e7bc29430b39b507c409838cbb0 + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -4946,18 +5486,18 @@ __metadata: linkType: hard "shiki@npm:^1.26.1": - version: 1.26.1 - resolution: "shiki@npm:1.26.1" + version: 1.29.2 + resolution: "shiki@npm:1.29.2" dependencies: - "@shikijs/core": "npm:1.26.1" - "@shikijs/engine-javascript": "npm:1.26.1" - "@shikijs/engine-oniguruma": "npm:1.26.1" - "@shikijs/langs": "npm:1.26.1" - "@shikijs/themes": "npm:1.26.1" - "@shikijs/types": "npm:1.26.1" + "@shikijs/core": "npm:1.29.2" + "@shikijs/engine-javascript": "npm:1.29.2" + "@shikijs/engine-oniguruma": "npm:1.29.2" + "@shikijs/langs": "npm:1.29.2" + "@shikijs/themes": "npm:1.29.2" + "@shikijs/types": "npm:1.29.2" "@shikijs/vscode-textmate": "npm:^10.0.1" "@types/hast": "npm:^3.0.4" - checksum: 10/10b54241b2c58b0af228dbd00ebf2f7f820ec3527933c7fcbe7c1b634893fe003703f660cbf3ab4d0bdf61d2062590d3c7af5be57cd3192ebb4e5f2900d32f58 + checksum: 10/93de1ebc768ff497ba36720f3b385bff65a853248fdfc0afcb2aea81a43560b1bdc7db9e8417df11a87e106b0de0943989c6301daf62a43d09bd9ac7bc776bf3 languageName: node linkType: hard @@ -5009,10 +5549,12 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^4.0.1": - version: 4.1.0 - resolution: "signal-exit@npm:4.1.0" - checksum: 10/c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f +"simple-swizzle@npm:^0.2.2": + version: 0.2.2 + resolution: "simple-swizzle@npm:0.2.2" + dependencies: + is-arrayish: "npm:^0.3.1" + checksum: 10/c6dffff17aaa383dae7e5c056fbf10cf9855a9f79949f20ee225c04f06ddde56323600e0f3d6797e82d08d006e93761122527438ee9531620031c08c9e0d73cc languageName: node linkType: hard @@ -5044,18 +5586,28 @@ __metadata: languageName: node linkType: hard -"stable-hash@npm:^0.0.4": - version: 0.0.4 - resolution: "stable-hash@npm:0.0.4" - checksum: 10/21c039d21c1cb739cf8342561753a5e007cb95ea682ccd452e76310bbb9c6987a89de8eda023e320b019f3e4691aabda75079cdbb7dadf7ab9013e931f2f23cd +"stable-hash@npm:^0.0.5": + version: 0.0.5 + resolution: "stable-hash@npm:0.0.5" + checksum: 10/9222ea2c558e37c4a576cb4e406966b9e6aa05b93f5c4f09ef4aaabe3577439b9b8fbff407b16840b63e2ae83de74290c7b1c2da7360d571e480e46a4aec0a56 + languageName: node + linkType: hard + +"stop-iteration-iterator@npm:^1.1.0": + version: 1.1.0 + resolution: "stop-iteration-iterator@npm:1.1.0" + dependencies: + es-errors: "npm:^1.3.0" + internal-slot: "npm:^1.1.0" + checksum: 10/ff36c4db171ee76c936ccfe9541946b77017f12703d4c446652017356816862d3aa029a64e7d4c4ceb484e00ed4a81789333896390d808458638f3a216aa1f41 languageName: node linkType: hard "storybook@npm:^8.6.8": - version: 8.6.12 - resolution: "storybook@npm:8.6.12" + version: 8.6.14 + resolution: "storybook@npm:8.6.14" dependencies: - "@storybook/core": "npm:8.6.12" + "@storybook/core": "npm:8.6.14" peerDependencies: prettier: ^2 || ^3 peerDependenciesMeta: @@ -5065,7 +5617,7 @@ __metadata: getstorybook: ./bin/index.cjs sb: ./bin/index.cjs storybook: ./bin/index.cjs - checksum: 10/babd1d086eb02ba25ee659e02e619f7797a6b91028ad74d2da0ab77e72021cd5c2ac4f239668f15156aabf00bd97066a774370dceadf178b1e649bf971160a26 + checksum: 10/104932fe29ebf49bef24c90285741cec964d1c36b3f0b38da1dace31ac664be457f2a510e41ba69fe8aa0d90c20e3446fec27d1ced41e5eefb3a9ca713d99e79 languageName: node linkType: hard @@ -5076,28 +5628,6 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": - version: 4.2.3 - resolution: "string-width@npm:4.2.3" - dependencies: - emoji-regex: "npm:^8.0.0" - is-fullwidth-code-point: "npm:^3.0.0" - strip-ansi: "npm:^6.0.1" - checksum: 10/e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb - languageName: node - linkType: hard - -"string-width@npm:^5.0.1, string-width@npm:^5.1.2": - version: 5.1.2 - resolution: "string-width@npm:5.1.2" - dependencies: - eastasianwidth: "npm:^0.2.0" - emoji-regex: "npm:^9.2.2" - strip-ansi: "npm:^7.0.1" - checksum: 10/7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 - languageName: node - linkType: hard - "string.prototype.includes@npm:^2.0.1": version: 2.0.1 resolution: "string.prototype.includes@npm:2.0.1" @@ -5188,7 +5718,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": +"strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" dependencies: @@ -5197,15 +5727,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^7.0.1": - version: 7.1.0 - resolution: "strip-ansi@npm:7.1.0" - dependencies: - ansi-regex: "npm:^6.0.1" - checksum: 10/475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 - languageName: node - linkType: hard - "strip-bom@npm:^3.0.0": version: 3.0.0 resolution: "strip-bom@npm:3.0.0" @@ -5227,7 +5748,16 @@ __metadata: languageName: node linkType: hard -"style-to-object@npm:^1.0.0": +"style-to-js@npm:1.1.16, style-to-js@npm:^1.0.0": + version: 1.1.16 + resolution: "style-to-js@npm:1.1.16" + dependencies: + style-to-object: "npm:1.0.8" + checksum: 10/a876cc49a29ac90c7723b4d6f002ac6c1ac5ccc6b5bc963d9c607cfc74b15927b704c9324df6f824f576c65689fe4b4ff79caabcd44a13d8a02641f721f1b316 + languageName: node + linkType: hard + +"style-to-object@npm:1.0.8": version: 1.0.8 resolution: "style-to-object@npm:1.0.8" dependencies: @@ -5236,19 +5766,19 @@ __metadata: languageName: node linkType: hard -"styled-jsx@npm:5.1.1": - version: 5.1.1 - resolution: "styled-jsx@npm:5.1.1" +"styled-jsx@npm:5.1.6": + version: 5.1.6 + resolution: "styled-jsx@npm:5.1.6" dependencies: client-only: "npm:0.0.1" peerDependencies: - react: ">= 16.8.0 || 17.x.x || ^18.0.0-0" + react: ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" peerDependenciesMeta: "@babel/core": optional: true babel-plugin-macros: optional: true - checksum: 10/4f6a5d0010770fdeea1183d919d528fd46c484e23c0535ef3e1dd49488116f639c594f3bd4440e3bc8a8686c9f8d53c5761599870ff039ede11a5c3bfe08a4be + checksum: 10/ba01200e8227fe1441a719c2e7da96c8aa7ef61d14211d1500e1abce12efa118479bcb6e7e12beecb9e1db76432caad2f4e01bbc0c9be21c134b088a4ca5ffe0 languageName: node linkType: hard @@ -5268,13 +5798,6 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.2.0": - version: 2.2.1 - resolution: "tapable@npm:2.2.1" - checksum: 10/1769336dd21481ae6347611ca5fca47add0962fd8e80466515032125eca0084a4f0ede11e65341b9c0018ef4e1cf1ad820adbb0fba7cc99865c6005734000b0a - languageName: node - linkType: hard - "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -5289,6 +5812,16 @@ __metadata: languageName: node linkType: hard +"tinyglobby@npm:^0.2.13": + version: 0.2.14 + resolution: "tinyglobby@npm:0.2.14" + dependencies: + fdir: "npm:^6.4.4" + picomatch: "npm:^4.0.2" + checksum: 10/3d306d319718b7cc9d79fb3f29d8655237aa6a1f280860a217f93417039d0614891aee6fc47c5db315f4fcc6ac8d55eb8e23e2de73b2c51a431b42456d9e5764 + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -5312,12 +5845,12 @@ __metadata: languageName: node linkType: hard -"ts-api-utils@npm:^2.0.0": - version: 2.0.0 - resolution: "ts-api-utils@npm:2.0.0" +"ts-api-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "ts-api-utils@npm:2.1.0" peerDependencies: typescript: ">=4.8.4" - checksum: 10/485bdf8bbba98d58712243d958f4fd44742bbe49e559cd77882fb426d866eec6dd05c67ef91935dc4f8a3c776f235859735e1f05be399e4dc9e7ffd580120974 + checksum: 10/02e55b49d9617c6eebf8aadfa08d3ca03ca0cd2f0586ad34117fdfc7aa3cd25d95051843fde9df86665ad907f99baed179e7a117b11021417f379e4d2614eacd languageName: node linkType: hard @@ -5333,7 +5866,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.1, tslib@npm:^2.4.0": +"tslib@npm:^2.0.1, tslib@npm:^2.4.0, tslib@npm:^2.8.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7 @@ -5356,6 +5889,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.31.0": + version: 4.41.0 + resolution: "type-fest@npm:4.41.0" + checksum: 10/617ace794ac0893c2986912d28b3065ad1afb484cad59297835a0807dc63286c39e8675d65f7de08fafa339afcb8fe06a36e9a188b9857756ae1e92ee8bda212 + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-buffer@npm:1.0.3" @@ -5441,10 +5981,10 @@ __metadata: languageName: node linkType: hard -"undici-types@npm:~6.19.2": - version: 6.19.8 - resolution: "undici-types@npm:6.19.8" - checksum: 10/cf0b48ed4fc99baf56584afa91aaffa5010c268b8842f62e02f752df209e3dea138b372a60a963b3b2576ed932f32329ce7ddb9cb5f27a6c83040d8cd74b7a70 +"undici-types@npm:~6.21.0": + version: 6.21.0 + resolution: "undici-types@npm:6.21.0" + checksum: 10/ec8f41aa4359d50f9b59fa61fe3efce3477cc681908c8f84354d8567bb3701fafdddf36ef6bff307024d3feb42c837cf6f670314ba37fc8145e219560e473d14 languageName: node linkType: hard @@ -5490,6 +6030,17 @@ __metadata: languageName: node linkType: hard +"unist-util-remove@npm:^4.0.0": + version: 4.0.0 + resolution: "unist-util-remove@npm:4.0.0" + dependencies: + "@types/unist": "npm:^3.0.0" + unist-util-is: "npm:^6.0.0" + unist-util-visit-parents: "npm:^6.0.0" + checksum: 10/24a84224720f4c2d2ffce1d570c00b83ef545de80ec32a246698feff880446af6c410fc94deec4b4daafe09851d59f17cd1770e20f66d68092e3cd60c2147fb8 + languageName: node + linkType: hard + "unist-util-stringify-position@npm:^4.0.0": version: 4.0.0 resolution: "unist-util-stringify-position@npm:4.0.0" @@ -5520,6 +6071,67 @@ __metadata: languageName: node linkType: hard +"unrs-resolver@npm:^1.6.2": + version: 1.7.13 + resolution: "unrs-resolver@npm:1.7.13" + dependencies: + "@unrs/resolver-binding-darwin-arm64": "npm:1.7.13" + "@unrs/resolver-binding-darwin-x64": "npm:1.7.13" + "@unrs/resolver-binding-freebsd-x64": "npm:1.7.13" + "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.7.13" + "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.7.13" + "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.7.13" + "@unrs/resolver-binding-linux-arm64-musl": "npm:1.7.13" + "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.7.13" + "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.7.13" + "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.7.13" + "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.7.13" + "@unrs/resolver-binding-linux-x64-gnu": "npm:1.7.13" + "@unrs/resolver-binding-linux-x64-musl": "npm:1.7.13" + "@unrs/resolver-binding-wasm32-wasi": "npm:1.7.13" + "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.7.13" + "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.7.13" + "@unrs/resolver-binding-win32-x64-msvc": "npm:1.7.13" + napi-postinstall: "npm:^0.2.2" + dependenciesMeta: + "@unrs/resolver-binding-darwin-arm64": + optional: true + "@unrs/resolver-binding-darwin-x64": + optional: true + "@unrs/resolver-binding-freebsd-x64": + optional: true + "@unrs/resolver-binding-linux-arm-gnueabihf": + optional: true + "@unrs/resolver-binding-linux-arm-musleabihf": + optional: true + "@unrs/resolver-binding-linux-arm64-gnu": + optional: true + "@unrs/resolver-binding-linux-arm64-musl": + optional: true + "@unrs/resolver-binding-linux-ppc64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-musl": + optional: true + "@unrs/resolver-binding-linux-s390x-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-musl": + optional: true + "@unrs/resolver-binding-wasm32-wasi": + optional: true + "@unrs/resolver-binding-win32-arm64-msvc": + optional: true + "@unrs/resolver-binding-win32-ia32-msvc": + optional: true + "@unrs/resolver-binding-win32-x64-msvc": + optional: true + checksum: 10/362aa31e5cd635cf5955a7eb3fe58230a1a32bd5daba4c71e7620e0a0fcd35fffb926655e32d4834a82d48b676cf8a2208cf1de30e30b4bc85c2dc67fa60acb8 + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -5542,6 +6154,16 @@ __metadata: languageName: node linkType: hard +"vfile-matter@npm:^5.0.1": + version: 5.0.1 + resolution: "vfile-matter@npm:5.0.1" + dependencies: + vfile: "npm:^6.0.0" + yaml: "npm:^2.0.0" + checksum: 10/5eddf848617050df7b539b68c60f4850d4f87e848accb44eb541719cece48a170897fae759023d0f3a87bcfc65fc2183a9875f11c7b3dc9ceaab7b4d739f74d6 + languageName: node + linkType: hard + "vfile-message@npm:^4.0.0": version: 4.0.2 resolution: "vfile-message@npm:4.0.2" @@ -5552,7 +6174,7 @@ __metadata: languageName: node linkType: hard -"vfile@npm:^6.0.0": +"vfile@npm:^6.0.0, vfile@npm:^6.0.3": version: 6.0.3 resolution: "vfile@npm:6.0.3" dependencies: @@ -5615,7 +6237,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18, which-typed-array@npm:^1.1.2": +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19, which-typed-array@npm:^1.1.2": version: 1.1.19 resolution: "which-typed-array@npm:1.1.19" dependencies: @@ -5648,28 +6270,6 @@ __metadata: languageName: node linkType: hard -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version: 7.0.0 - resolution: "wrap-ansi@npm:7.0.0" - dependencies: - ansi-styles: "npm:^4.0.0" - string-width: "npm:^4.1.0" - strip-ansi: "npm:^6.0.0" - checksum: 10/cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 - languageName: node - linkType: hard - -"wrap-ansi@npm:^8.1.0": - version: 8.1.0 - resolution: "wrap-ansi@npm:8.1.0" - dependencies: - ansi-styles: "npm:^6.1.0" - string-width: "npm:^5.0.1" - strip-ansi: "npm:^7.0.1" - checksum: 10/7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf - languageName: node - linkType: hard - "wrappy@npm:1": version: 1.0.2 resolution: "wrappy@npm:1.0.2" @@ -5678,8 +6278,8 @@ __metadata: linkType: hard "ws@npm:^8.2.3": - version: 8.18.1 - resolution: "ws@npm:8.18.1" + version: 8.18.2 + resolution: "ws@npm:8.18.2" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -5688,7 +6288,16 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10/3f38e9594f2af5b6324138e86b74df7d77bbb8e310bf8188679dd80bac0d1f47e51536a1923ac3365f31f3d8b25ea0b03e4ade466aa8292a86cd5defca64b19b + checksum: 10/018e04ec95561d88248d53a2eaf094b4ae131e9b062f2679e6e8a62f04649bc543448f1e038125225ac6bbb25f54c1e65d7a2cc9dbc1e28b43e5e6b7162ad88e + languageName: node + linkType: hard + +"yaml@npm:^2.0.0": + version: 2.8.0 + resolution: "yaml@npm:2.8.0" + bin: + yaml: bin.mjs + checksum: 10/7d4bd9c10d0e467601f496193f2ac254140f8e36f96f5ff7f852b9ce37974168eb7354f4c36dc8837dde527a2043d004b6aff48818ec24a69ab2dd3c6b6c381c languageName: node linkType: hard diff --git a/docs/auth/autologout.md b/docs/auth/autologout.md index 1de0aabdb4..e2462522f4 100644 --- a/docs/auth/autologout.md +++ b/docs/auth/autologout.md @@ -68,7 +68,7 @@ These are the available settings: | Configuration Key | Component Property | Description | Allowed Values | Default Value | | ----------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | --------------------------- | | `auth.autologout.enabled` | `enabled` | Enable/disable the Auto Logout feature. | `true`/`false` | Default is enabled (`true`) | -| `auth.autologout.idleTimeoutMinutes` | `idleTimeoutMinutes` | Sets the idle time (in minutes) after which the user will be logged out. | `>= 0.5` minutes | `60` | +| `auth.autologout.idleTimeoutMinutes` | `idleTimeoutMinutes` | Sets the idle time (in minutes) after which the user will be logged out. | `>= 0.5` minutes | `0.5` | | `auth.autologout.promptBeforeIdleSeconds` | `promptBeforeIdleSeconds` | Determines the time (in seconds) prior to idle state when a prompt will appear. A value of 0 disables the prompt. This must be less than the value of `idleTimeoutMinutes`. | `>= 0` seconds | `10` | | `auth.autologout.useWorkerTimers` | `useWorkerTimers` | Enables or disables the use of Node's worker thread timers instead of main thread timers. This can be beneficial if the browser is terminating timers in inactive tabs, like those used by auto logout. In case of browser incompatibility, try setting this to false. | `true`/`false` | `true` | | `auth.autologout.logoutIfDisconnected` | `logoutIfDisconnected` | Enable/disable auto logout for disconnected users. Disconnected users are those who are logged in but do not have any active Backstage tabs open in their browsers. If enabled, such users will be automatically logged out after `idleTimeoutMinutes`. | `true`/`false` | `true` | diff --git a/docs/backend-system/core-services/actions-registry.md b/docs/backend-system/core-services/actions-registry.md new file mode 100644 index 0000000000..b1e8fe5f3d --- /dev/null +++ b/docs/backend-system/core-services/actions-registry.md @@ -0,0 +1,177 @@ +--- +id: actions-registry +title: Actions Registry (alpha) +sidebar_label: Actions Registry (alpha) +description: Documentation for the Actions Registry Service +--- + +## Overview + +The Actions Registry Service is a core service designed to provide a distributed registry for actions that can be executed within Backstage backend plugins. This service allows plugins to register reusable actions with well-defined schemas and execution logic, promoting consistency and reusability across the Backstage ecosystem. + +## Action Structure + +Each action registered with the service must conform to the `ActionsRegistryActionOptions` type, which includes: + +### Required Properties + +- **`name`:** A unique identifier for the action (string) +- **`title`:** A human-readable title for the action (string) +- **`description`:** A detailed description of what the action does (string) +- **`schema`:** Object containing input and output schema definitions + - **`input`:** Function that returns a Zod schema for validating input + - **`output`:** Function that returns a Zod schema for validating output +- **`action`:** The async function that executes the action logic + +### Optional Properties + +- **`attributes`:** Object containing behavioral flags: + - **`destructive`:** Boolean indicating if the action modifies or deletes data + - **`idempotent`:** Boolean indicating if running the action multiple times produces the same result + - **`readOnly`:** Boolean indicating if the action only reads data without modifications + +### Action Context + +When an action is executed, it receives a context object (`ActionsRegistryActionContext`) containing: + +- **`input`:** The validated input data matching the defined input schema +- **`logger`:** A LoggerService instance for logging within the action +- **`credentials`:** BackstageCredentials for authentication and authorization + +## Using the Service + +### Registering an Action + +Here's an example of how to register an action with the Actions Registry Service: + +```typescript +import { ActionsRegistryService } from '@backstage/backend-plugin-api'; + +export function registerMyActions(actionsRegistry: ActionsRegistryService) { + // Register a simple read-only action + actionsRegistry.register({ + name: 'fetch-user-info', + title: 'Fetch User Information', + description: 'Retrieves user information from the catalog', + schema: { + input: z => + z.object({ + userRef: z.string(), + includeGroups: z.boolean().optional(), + }), + output: z => + z.object({ + user: z.object({ + name: z.string(), + email: z.string(), + groups: z.array(z.string()).optional(), + }), + }), + }, + attributes: { + readOnly: true, + idempotent: true, + }, + action: async ({ input, logger, credentials }) => { + logger.info(`Fetching user info for ${input.userRef}`); + + // Perform the action logic here + const user = await fetchUserFromCatalog(input.userRef, credentials); + + return { + output: { + user: { + name: user.name, + email: user.email, + groups: input.includeGroups ? user.groups : undefined, + }, + }, + }; + }, + }); + + // Register a destructive action + actionsRegistry.register({ + name: 'delete-entity', + title: 'Delete Entity', + description: 'Removes an entity from the catalog', + schema: { + input: z => + z.object({ + entityRef: z.string(), + force: z.boolean().optional(), + }), + output: z => + z.object({ + deletedEntities: z.array(z.string()), + }), + }, + attributes: { + destructive: true, + idempotent: false, + }, + action: async ({ input, logger, credentials }) => { + logger.warn(`Deleting entity ${input.entityRef}`); + + // Perform the deletion logic here + const { deletedEntities } = await deleteEntityFromCatalog( + input.entityRef, + input.force, + credentials, + ); + + return { + output: deletedEntities, + }; + }, + }); +} +``` + +### Accessing the Service in a Plugin + +To use the Actions Registry Service in your plugin, access it through dependency injection: + +```typescript +import { + createBackendPlugin, + coreServices, +} from '@backstage/backend-plugin-api'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; + +export const myPlugin = createBackendPlugin({ + pluginId: 'my-plugin', + register(env) { + env.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + logger: coreServices.logger, + }, + async init({ actionsRegistry, logger }) { + logger.info('Registering actions...'); + registerMyActions(actionsRegistry); + logger.info('Actions registered successfully'); + }, + }); + }, +}); +``` + +## Best Practices + +### Naming Conventions + +- **Use kebab-case:** Action names should be in kebab-case (e.g., `fetch-user-info`, `create-repository`) +- **Be Descriptive:** Choose names that clearly describe what the action does +- **Avoid Redundancy:** Don't include plugin names in action names since the plugin context is separate +- **Use Verbs:** Start action names with verbs that describe the operation (e.g., `fetch`, `create`, `delete`, `update`) + +## Action Attributes Reference + +| Attribute | Type | Default | Description | +| ------------- | ------- | ------- | ------------------------------------------------------------------- | +| `destructive` | boolean | `true` | Indicates the action modifies or deletes data. Use with caution. | +| `idempotent` | boolean | `false` | Indicates the action can be run multiple times with the same result | +| `readOnly` | boolean | `false` | Indicates the action only reads data without making modifications | + +These attributes help consumers of actions understand their behavior and implement appropriate safeguards, retries, or optimizations based on the action's characteristics. diff --git a/docs/backend-system/core-services/actions.md b/docs/backend-system/core-services/actions.md new file mode 100644 index 0000000000..ddb28b4da7 --- /dev/null +++ b/docs/backend-system/core-services/actions.md @@ -0,0 +1,131 @@ +--- +id: actions +title: Actions (alpha) +sidebar_label: Actions (alpha) +description: Documentation for the Actions Service +--- + +## Overview + +The Actions Service is a core service that provides a standardized interface for discovering and executing registered actions within Backstage backend plugins. This service acts as the consumer-facing API for actions that have been registered through the Actions Registry Service, allowing plugins to list available actions and invoke them with proper authentication and input validation. + +## How it Works + +The Actions Service implements the `ActionsService` interface, which provides two primary methods: + +- **`list()`:** Retrieves all available actions with their complete metadata +- **`invoke()`:** Executes a specific action by ID with provided input data + +The service works in conjunction with the [Actions Registry Service](./actions-registry.md), where actions are registered by plugins and then made available for discovery and execution through this service. + +## Action Identification + +Actions are identified using a unique ID that follows a specific format: + +- All action IDs are prefixed with the plugin ID that registered them, following the pattern `pluginId:actionName` +- An action named `fetch-user-info` registered by the `catalog` plugin would have the ID `catalog:fetch-user-info` +- When using the `actionsRegistryServiceMock`, the plugin ID prefix will be `test:` + +This naming convention ensures that action names are globally unique across all plugins and provides clear ownership identification. + +## Configuration + +The Actions Service can be configured to control which plugins' actions are available: + +```yaml +backend: + actions: + pluginSources: + - catalog +``` + +## Using the Service + +### Listing Available Actions + +Here's an example of how to list all available actions: + +```typescript +import { ActionsService } from '@backstage/backend-plugin-api'; + +export async function listAvailableActions( + actionsService: ActionsService, + credentials: BackstageCredentials, +) { + try { + const { actions } = await actionsService.list({ credentials }); + + console.log(`Found ${actions.length} available actions:`); + + actions.forEach(action => { + console.log(`- ${action.id}: ${action.title}`); + console.log(` Description: ${action.description}`); + console.log(` Attributes: ${JSON.stringify(action.attributes)}`); + + if (action.schema.input) { + console.log( + ` Input Schema: ${JSON.stringify(action.schema.input, null, 2)}`, + ); + } + }); + + return actions; + } catch (error) { + console.error('Failed to list actions:', error); + throw error; + } +} +``` + +### Invoking an Action + +Here's an example of how to execute a specific action: + +```typescript +import { ActionsService } from '@backstage/backend-plugin-api'; + +export async function executeAction( + actionsService: ActionsService, + actionId: string, + input: JsonObject, + credentials: BackstageCredentials, +) { + try { + const { output } = await actionsService.invoke({ + id: actionId, + input, + credentials, + }); + + console.log(`Action ${actionId} executed successfully`); + console.log('Output:', JSON.stringify(output, null, 2)); + + return output; + } catch (error) { + console.error(`Failed to execute action ${actionId}:`, error); + throw error; + } +} + +// Example usage +async function fetchUserInfo( + actionsService: ActionsService, + credentials: BackstageCredentials, +) { + const output = await executeAction( + actionsService, + 'catalog:fetch-user-info', // Note: Action ID includes plugin prefix + { + userRef: 'user:default/john.doe', + includeGroups: true, + }, + credentials, + ); + + return output; +} +``` + +## Best Practices + +For comprehensive guidance on action design, naming conventions, and schema design, see the [Actions Registry Best Practices](./actions-registry.md#best-practices) documentation. diff --git a/docs/backend-system/core-services/http-router.md b/docs/backend-system/core-services/http-router.md index d7658d9a67..5e065152a0 100644 --- a/docs/backend-system/core-services/http-router.md +++ b/docs/backend-system/core-services/http-router.md @@ -68,6 +68,60 @@ For those routes you will also have to specify `allowLimitedAccess: true` when using the [`auth`](./auth.md) and [`httpAuth`](./http-auth.md) services to access the incoming credentials. +## Rate limiting + +Rate limiting allows you to limit the amount of requests users can send to you backend. +This is useful for blocking various network attacks, such as DDOS. + +To enable rate limiting, add the following to your config: + +```yaml +backend: + rateLimit: true +``` + +You can additionally configure the rate limiting parameters, also by plugin: + +```yaml +backend: + rateLimit: + global: true # Enables or disables rate limit for all plugins + window: 6s # Time window for rate limiting for single client + incomingRequestLimit: 100 # Number of requests to accept from one client during time window + ipAllowList: ['127.0.0.1'] # IPs to bypass rate limiting + skipSuccesfulRequests: false # Rate limit successful requests + skipFailedRequests: false # Rate limit failed requests + plugin: + # Plugin specific rate limiting + catalog: + window: 3s + incomingRequestLimit: 50 +``` + +By default, the rate limiting is per instance and the request counts are stored into memory. +If you want to share this information across all your backstage instances, you have to configure +the rate limiting store: + +```yaml +backend: + rateLimit: + global: true + store: + type: redis + connection: redis://127.0.0.1:16379 +``` + +If your instance is working behind a proxy, you have to configure the backend to trust the proxy +for the rate limiting being able to distinguish clients. + +```yaml +backend: + trustProxy: true +``` + +For more information about the trust proxy configuration and available options, +please refer to [express documentation](https://expressjs.com/en/guide/behind-proxies.html). + ## Configuring the service For more advanced customization, there are several APIs from the `@backstage/backend-defaults/httpRouter` package that allow you to customize the implementation of the config service. The default implementation uses all of the middleware exported from `@backstage/backend-defaults/httpRouter`, including `createLifecycleMiddleware`, `createAuthIntegrationRouter`, `createCredentialsBarrier` and `createCookieAuthRefreshMiddleware`. You can use these to create your own `httpRouter` service implementation, for example - here's how you would add a custom health check route to all plugins: @@ -78,6 +132,7 @@ import { createCookieAuthRefreshMiddleware, createCredentialsBarrier, createAuthIntegrationRouter, + createRateLimitMiddleware, } from '@backstage/backend-defaults/httpRouter'; import { createServiceFactory } from '@backstage/backend-plugin-api'; @@ -105,6 +160,11 @@ backend.add( }) { const router = PromiseRouter(); + // Optional rate limiting middleware + router.use( + createRateLimitMiddleware({ pluginId: plugin.getId(), config }), + ); + rootHttpRouter.use(`/api/${plugin.getId()}`, router); const credentialsBarrier = createCredentialsBarrier({ diff --git a/docs/backend-system/core-services/root-http-router.md b/docs/backend-system/core-services/root-http-router.md index 7a268e27fc..1e76fb1871 100644 --- a/docs/backend-system/core-services/root-http-router.md +++ b/docs/backend-system/core-services/root-http-router.md @@ -40,6 +40,10 @@ createBackendPlugin({ }); ``` +## Rate limiting + +Please refer to the [HTTP Router documentation](./http-router.md#rate-limiting). + ## Configuring the service ### Via `app-config.yaml` @@ -60,7 +64,7 @@ backend: # - A string in the format of '1d', '2 seconds' etc. as supported by the `ms` library. # - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'. # - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`. - serverShutdownTimeout: { seconds: 20 } + serverShutdownDelay: { seconds: 20 } ``` ### Via Code @@ -121,6 +125,11 @@ backend.add( app.use(middleware.cors()); app.use(middleware.compression()); + // Optional rate limiting middleware + app.use(middleware.rateLimit()); + // If you are using rate limiting behind a proxy, you should set the `trust proxy` setting to true + app.set('trust proxy', true); + app.use(healthRouter); // you can add you your own middleware in here @@ -161,3 +170,52 @@ backend.add( }), ); ``` + +## Defining Content Security Policy (CSP) Configuration + +Content Security Policy (CSP) is a crucial security feature that helps protect your Backstage instance from various attacks, particularly Cross-Site Scripting (XSS). Backstage provides a flexible way to configure CSP directives through your `app-config.yaml` file. + +### Basic Configuration + +CSP directives can be defined under the `backend.csp` section in your configuration: + +```yaml +backend: + csp: + default-src: ["'self'"] + script-src: ["'self'", "'unsafe-inline'", 'example.com'] + connect-src: ["'self'", 'http:', 'https:'] + img-src: ["'self'", 'data:', 'https://backstage.io'] + style-src: ["'self'", "'unsafe-inline'"] + frame-src: ['https://some-analytics-provider.com'] +``` + +### Available Directives + +You can configure any CSP directive supported by modern browsers. Common directives include: + +- `default-src`: The fallback for other CSP directives +- `script-src`: Controls which scripts can be executed +- `style-src`: Controls which styles can be applied +- `img-src`: Controls which images can be loaded +- `connect-src`: Controls which URLs can be loaded using fetch, WebSocket, etc. +- `frame-src`: Controls which URLs can be embedded in iframes +- `font-src`: Controls which fonts can be loaded +- `object-src`: Controls which URLs can be loaded as plugins +- `media-src`: Controls which media (audio, video) can be loaded +- `upgrade-insecure-requests`: Instructs browsers to upgrade HTTP to HTTPS + +### Special Values + +- Common special values within directive arrays: + - `self`: Allows content from the same origin + - `unsafe-inline`: Allows inline scripts/styles + - `unsafe-eval`: Allows dynamic code evaluation + - `none`: Blocks all content for that directive + - `data:`: Allows data: URIs (commonly used for images) + - `https:`: Allows any content over HTTPS + +For more information on available CSP options, refer to: + +- [MDN Content Security Policy documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) +- [Helmet Content Security Policy](https://helmetjs.github.io/#content-security-policy) diff --git a/docs/features/software-templates/writing-custom-actions.md b/docs/features/software-templates/writing-custom-actions.md index 26773c15c6..1a64406b04 100644 --- a/docs/features/software-templates/writing-custom-actions.md +++ b/docs/features/software-templates/writing-custom-actions.md @@ -12,7 +12,7 @@ by writing custom actions which can be used alongside our When adding custom actions, the actions array will **replace the built-in actions too**. Meaning, you will no longer be able to use them. -If you want to continue using the builtin actions, include them in the actions +If you want to continue using the builtin actions, include them in the `actions` array when registering your custom actions, as seen below. ::: @@ -52,19 +52,20 @@ its generated unit test. We will replace the existing placeholder code with our import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import fs from 'fs-extra'; -import { z } from 'zod'; +import { type z } from 'zod'; export const createNewFileAction = () => { return createTemplateAction({ id: 'acme:file:create', description: 'Create an Acme file.', schema: { - input: z.object({ - contents: z.string().describe('The contents of the file'), - filename: z - .string() - .describe('The filename of the file that will be created'), - }), + input: { + contents: z => z.string({ description: 'The contents of the file' }), + filename: z => + z.string({ + description: 'The filename of the file that will be created', + }), + }, }, async handler(ctx) { @@ -95,53 +96,11 @@ The `createTemplateAction` takes an object which specifies the following: function using `ctx.output` - `handler` - the actual code which is run as part of the action, with a context -You can also choose to define your custom action using JSON schema instead of `zod`: - -```ts title="With JSON Schema" -import { resolveSafeChildPath } from '@backstage/backend-plugin-api'; -import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; -import { writeFile } from 'fs'; - -export const createNewFileAction = () => { - return createTemplateAction<{ contents: string; filename: string }>({ - id: 'acme:file:create', - description: 'Create an Acme file.', - schema: { - input: { - required: ['contents', 'filename'], - type: 'object', - properties: { - contents: { - type: 'string', - title: 'Contents', - description: 'The contents of the file', - }, - filename: { - type: 'string', - title: 'Filename', - description: 'The filename of the file that will be created', - }, - }, - }, - }, - async handler(ctx) { - const { signal } = ctx; - await writeFile( - resolveSafeChildPath(ctx.workspacePath, ctx.input.filename), - ctx.input.contents, - { signal }, - _ => {}, - ); - }, - }); -}; -``` - ### Naming Conventions Try to keep names consistent for both your own custom actions, and any actions contributed to open source. We've found that a separation of `:` and using a verb as the last part of the name works well. -We follow `provider:entity:verb` or as close to this as possible for our built in actions. For example, +We follow `provider:entity:verb` or as close to this as possible for our built-in actions. For example, `github:actions:create` or `github:repo:create`. Also feel free to use your company name to namespace them if you prefer too, for example `acme:file:create` like above. @@ -151,14 +110,14 @@ and writing of template entity definitions. ### Adding a TemplateExample -A TemplateExample is a way to document different ways that your custom action can be used. Once added it will be visible +A TemplateExample is a way to document different ways that your custom action can be used. Once added, it will be visible in your Backstage instance under the [/create/actions](https://demo.backstage.io/create/actions) path. You can have multiple examples for one action that can demonstrate different combinations of inputs and how to use them. #### Define TemplateExamples Below is a sample TemplateExample that is used for `publish:github`. The source code is available -on [github](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts) +on [GitHub](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.ts) and preview on [demo.backstage.io/create/actions](https://demo.backstage.io/create/actions#publish-github) ```ts title="With JSON Schema" @@ -222,7 +181,7 @@ return createTemplateAction({ #### Test TemplateAction examples It is also possible to test your example TemplateActions. You can see a sample test -on [github](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts) +on [GitHub](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend-module-github/src/actions/github.examples.test.ts) ### The context object @@ -234,13 +193,12 @@ argument. It looks like the following: implement [idempotency of the actions](https://github.com/backstage/backstage/tree/master/beps/0004-scaffolder-task-idempotency) by not re-running the same function again if it was executed successfully on the previous run. -- `ctx.logger` - a Winston logger for additional logging inside your action -- `ctx.logStream` - a stream version of the logger if needed +- `ctx.logger` - a [LoggerService](../../backend-system/core-services/logger.md) instance for additional logging inside your action - `ctx.workspacePath` - a string of the working directory of the template run - `ctx.input` - an object which should match the `zod` or JSON schema provided in the `schema.input` part of the action definition - `ctx.output` - a function which you can call to set outputs that match the - JSON schema or `zod` in `schema.output` for ex. `ctx.output('downloadUrl', myDownloadUrl)` + `zod` schema in `schema.output` for ex. `ctx.output('downloadUrl', myDownloadUrl)` - `createTemporaryDirectory` a function to call to give you a temporary directory somewhere on the runner, so you can store some files there rather than polluting the `workspacePath` @@ -249,7 +207,7 @@ argument. It looks like the following: ## Registering Custom Actions -To register your new custom action in the Backend System you will need to create a backend module. Here is a very +To register your new custom action in the Backend System, you will need to create a backend module. Here is a very simplified example of how to do that: ```ts title="packages/backend/src/index.ts" @@ -327,8 +285,8 @@ const res = await ctx.checkpoint?.({ }); ``` -You have to define the unique key in scope of the scaffolder task for your checkpoint. During the execution task engine -will check if the checkpoint with such key was already executed or not, if yes, and the run was successful, the callback +You have to define the unique key in the scope of the scaffolder task for your checkpoint. During the execution task engine +will check if the checkpoint with such a key was already executed or not, if yes, and the run was successful, the callback will be skipped and instead the stored value will be returned. Whenever you change the return type of the checkpoint, we encourage you to change the ID. diff --git a/docs/integrations/bitbucketServer/discovery.md b/docs/integrations/bitbucketServer/discovery.md index 29c8d40338..350bc33aed 100644 --- a/docs/integrations/bitbucketServer/discovery.md +++ b/docs/integrations/bitbucketServer/discovery.md @@ -66,6 +66,7 @@ catalog: projectKey: '^apis-.*$' # optional; RegExp repoSlug: '^service-.*$' # optional; RegExp skipArchivedRepos: true # optional; boolean + validateLocationsExist: false # optional; boolean schedule: # same options as in SchedulerServiceTaskScheduleDefinition # supports cron, ISO duration, "human duration" as used in code frequency: { minutes: 30 } @@ -86,6 +87,10 @@ catalog: Regular expression used to filter results based on the repo slug. - **`skipArchivedRepos`** _(optional)_: Boolean flag to filter out archived repositories. +- **`validateLocationsExist`** _(optional)_: + Defaults to `false`. + Whether to validate locations that exist before emitting them. + This option avoids generating locations for catalog info files that do not exist in the source repository. - **`schedule`**: - **`frequency`**: How often you want the task to run. The system does its best to avoid overlapping invocations. diff --git a/docs/integrations/gitea/discovery.md b/docs/integrations/gitea/discovery.md index 6cae169b58..ce8ad9d360 100644 --- a/docs/integrations/gitea/discovery.md +++ b/docs/integrations/gitea/discovery.md @@ -30,7 +30,7 @@ backend.add(import('@backstage/plugin-catalog-backend-module-gitea')); ## Configuration -To use the discovery processor, you'll need a Gitea integration +To use the discovery provider, you'll need a Gitea integration [set up](locations.md). Then you can add any number of providers. ```yaml diff --git a/docs/notifications/index.md b/docs/notifications/index.md index 2af8879ac0..c31d2716e4 100644 --- a/docs/notifications/index.md +++ b/docs/notifications/index.md @@ -158,6 +158,21 @@ You can customize the origin names shown in the UI by passing an object where th Each notification processor will receive its own row in the settings page, where the user can enable or disable notifications from that processor. +### Automatic notification cleanup + +Notifications are deleted automatically after a certain period of time to prevent the database from growing indefinitely +and to keep the user interface clean. The default retention period is set to 1 year, meaning that notifications older +than that will be deleted automatically. + +The retention period can be configured by setting the `notifications.retention` in the `app-config.yaml` file. + +```yaml +notifications: + retention: 1y +``` + +If the retention is set to false, notifications will not be automatically deleted. + ## Additional info An example of a backend plugin sending notifications can be found in the [`@backstage/plugin-scaffolder-backend-module-notifications` package](https://github.com/backstage/backstage/tree/master/plugins/scaffolder-backend-module-notifications). diff --git a/docs/references/glossary.md b/docs/references/glossary.md index 273749323f..8d3c072685 100644 --- a/docs/references/glossary.md +++ b/docs/references/glossary.md @@ -10,7 +10,7 @@ A [token](#token) that gives access to perform actions on behalf of a user. It w ## Administrator -Someone responsible for installing and maintaining a Backstage [app](#app) for an organization. A [user role](#user-role). +Someone responsible for installing, configuring, and maintaining a Backstage [app](#app) for an organization. A [user role](#user-role). ## API (catalog plugin) @@ -20,6 +20,14 @@ An [entity](#entity) representing a schema that two [components](#component) use An installed instance of Backstage. An app can be local, intended for a single development group or individual developer, or organizational, for use by an entire enterprise. +## Authentication + +The process of verifying the identity of a user, system, or entity attempting to access a resource, system, or network. It answers the question: "Are you who you claim to be?" See [this Wikipedia article](https://en.wikipedia.org/wiki/Authentication) for more details. + +## Authorization + +The process of determining what an authenticated user or system is allowed to do within a system, application, or resource. It comes after authentication, and answers the question: "What are you allowed to access or do?" It involves assigning specific privileges or access rights or roles to the user. See [this Wikipedia article](https://en.wikipedia.org/wiki/Authorization) for more details. + ## Authorization Code A type of [OAuth flow](#oauth) used by confidential and public clients to get an [access token](#access-token). See [the OAuth docs](https://oauth.net/2/grant-types/authorization-code/) for more details. @@ -42,7 +50,7 @@ The actual framework that Backstage [plugins](#plugin) sit on. This spans both t ## Catalog -1. The core Backstage plugin that handle ingestion and display of your organizations software products. +1. The core Backstage plugin that handles ingestion and display of your organization's software products. 2. An organization's portfolio of software products managed in Backstage. @@ -50,16 +58,12 @@ The actual framework that Backstage [plugins](#plugin) sit on. This spans both t A set of technologies that "empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach." ([CNCF Cloud Native Definition v1.0](https://github.com/cncf/toc/blob/main/DEFINITION.md)). -## Cloud Native Computing Foundation +## Cloud Native Computing Foundation (AKA CNCF) A foundation dedicated to the promotion and advancement of [Cloud Native Computing](#Cloud-Native-Computing). The mission of the Cloud Native Computing Foundation (CNCF) is "to make cloud native computing ubiquitous" ([CNCF Charter](https://github.com/cncf/foundation/blob/main/charter.md)). CNCF is part of the [Linux Foundation](https://www.linuxfoundation.org/). -## CNCF - -Cloud Native Computing Foundation. - ## Code Grant [OAuth](#oauth) flow where the client receives an [authorization code](#code) that is passed to the backend to be exchanged for an [access token](#access-token) and possibly a [refresh token](#refresh-token). @@ -98,9 +102,9 @@ An executable or package file with all of the necessary information required to ## Developer -1. Someone who writes code and develops software. +1. A professional who designs, builds, tests, deploys, and maintains software applications and systems. Developers essentially turn ideas or requirements into functional digital products. -2. A [user role](#user-role) defined as someone who uses a Backstage [app](#app). Might or might not actually be a software developer. +2. A [user role](#user-role) defined as someone who creates, modifies, or uses a Backstage [app](#app). Might or might not actually be a software developer. ## Developer Portal @@ -108,15 +112,21 @@ A centralized system comprising a user interface and database used to facilitate ## Document (search plugin) -An abstract concept representing something that can be found by searching for it. A document can represent a software entity, a TechDocs page, etc. Documents are made up of metadata fields, at a minimum -- a title, text, and location (as in a URL). +1. A piece of information or data that is recorded on some medium for the purpose of storing and conveying information. + +2. An abstract concept representing something that can be found by searching for it. A document can represent a software entity, a TechDocs page, etc. Documents are made up of metadata fields, at a minimum -- a title, body (text), and location (as in a URL). ## Domain -An area that relates systems or entities to a business unit. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +1. A collection of systems that share terminology, domain models, metrics, KPIs, business purpose, or documentation; that is, it forms a bounded context. + +2. An area that relates systems or entities to a business unit. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Entity -What is cataloged in the Backstage Software Catalog. An entity is identified by a unique combination of [kind](#Kind), [namespace](#Namespace), and name. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +1. Something that exists as a separate and distinct unit. Its existence can be real or abstract, physical or conceptual, persistent or ephemeral. + +2. What is cataloged in the Backstage Software Catalog. An entity is identified by a unique combination of [kind](#Kind), [namespace](#Namespace), and name. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Evaluator @@ -124,11 +134,13 @@ Someone who assesses whether Backstage is a suitable solution for their organiza ## ID Token -A [JWT](#jwt) used to prove a user's identity, containing for example the user's email. Part of [OpenID Connect](#openid-connect). +A security token used in authentication processes, primarily defined by the [OpenID Connect (OIDC) standard](#openid-connect). Its main purpose is to prove that a user has been successfully authenticated by an identity provider. + +See [JSON Web Token](#json-web-token). ## Index (search plugin) -An index is a collection of [documents](#documents) of a given type. +A collection of [documents](#documents) of a given type. ## Indexer (search plugin) @@ -138,11 +150,9 @@ A write stream of [documents](#documents). Someone who develops one or more plugins that enable Backstage to interoperate with another software system. A [user role](#user-role). -## JWT +## JSON Web Token (AKA JWT) -JSON Web Token. - -A popular JSON based token format that is commonly encrypted and/or signed, see [the Wikipedia article](https://en.wikipedia.org/wiki/JSON_Web_Token) for more details. +A popular, compact, and self-contained open standard for securely transmitting information between parties as a JSON object. It is commonly used to verify a user's identity [authentication](#authentication) and permissions [authorization](#authorization). Each JWT consists of a header, payload, and digital signature separated by dots. While often encrypted, JWTs are always signed for integrity. This standard is a key component of [OpenID Connect](#openid-connect). For more details, see [the Wikipedia article](https://en.wikipedia.org/wiki/JSON_Web_Token). ## Kind @@ -158,7 +168,7 @@ A core Backstage plugin enabling a service owner-focused view of Kubernetes reso ## Local Package -One of the [packages](#package) within a [monorepo](#monorepo). These package may or may not also be published to a [package registry](#package-registry). +One of the [packages](#package) within a [monorepo](#monorepo). A package may or may not also be published to a [package registry](#package-registry). ## Monorepo @@ -172,11 +182,11 @@ An optional attribute that can be used to organize [entities](#entity). ## Objective -A high level goal of a [user role](#User-Role) interacting with Backstage. Some goals of the _administrator_ user role, for example, are to maintain an instance ("app") of Backstage; to add and update functionality via plugins; and to troubleshoot issues. +A high-level goal of a [user role](#User-Role) interacting with Backstage. Some goals of the _administrator_ user role, for example, are to maintain an instance ("app") of Backstage; to add and update functionality via plugins; and to troubleshoot issues. ## OAuth -Refers to: OAuth 2.0, a standard protocol for authorization. See [oauth.net/2/](https://oauth.net/2/). +Refers to: OAuth 2.0, a standard protocol and framework for granting third-party applications access to their data on other websites or services without sharing their passwords. See [oauth.net/2/](https://oauth.net/2/). ## Offline Access @@ -202,6 +212,10 @@ A service that hosts [packages](#package). The most prominent example is [NPM](h The declared role of a package, see [package roles](../tooling/cli/02-build-system.md#package-roles). +## Permission + +Specific rules or settings that define the level of access and types of actions that a user, group, or system process is allowed to perform on a particular resource. They are a core component of authorization that determine "what you can do" after you've been authenticated. Permissions are properties of objects or resources. Closely related to [Privilege](#privilege) (the terms are often used interchangeably). + ## Permission (core Backstage plugin) A core Backstage plugin and framework that allows restriction of actions to specific users. See [their docs](https://backstage.io/docs/permissions/overview) for more information. @@ -230,6 +244,10 @@ A specific response to a user's request to perform an action on a list of [resou A separate browser window opened on top of the previous one. +## Privilege + +Specific rules or settings that define what a user or process is allowed to do within the system, often relating to system-wide operations or capabilities. Privileges are properties of a subject, such as a user account or process, and represent a higher-level authority or right to perform certain security-critical functions. Closely related to [Permission](#permission) (the terms are often used interchangeably). + ## Procedure (use cases) A set of actions that accomplish a goal, usually as part of a [use case](#Use-Case). A procedure can be high-level, containing other procedures, or can be as simple as a single [task](#Task). @@ -240,9 +258,7 @@ An abstraction layer between a search engine and the [Backstage Search](#search) ## Refresh token -A special token that an [OAuth](#oauth) client can use to get a new [access token](#access-token) when the latter expires. - -https://oauth.net/2/refresh-tokens/ +A special token that an [OAuth](#oauth) client can use to get a new [access token](#access-token) when the latter expires. See [OAuth Refresh Tokens](https://oauth.net/2/refresh-tokens/) for details. ## Resource (catalog plugin) @@ -290,7 +306,7 @@ A "skeleton" software project created and managed in the Backstage Software Temp ## System (catalog plugin) -A system is a collection of [entities](#entity) that cooperate to perform a function. A system generally provides one or a few public APIs and consists of a handful of components, resources and private APIs. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. +A collection of [entities](#entity) that cooperate to perform a function. A system generally provides one or a few public APIs and consists of a handful of components, resources, and private or public APIs. See [the catalog docs](https://backstage.io/docs/features/software-catalog/system-model) for more information. ## Task (use cases) @@ -298,7 +314,7 @@ A low-level step-by-step [Procedure](#Procedure). ## TechDocs -A documentation solution that manages and generates a technical documentation from Markdown files stored with software component code. A core feature of Backstage. +A documentation solution that manages and generates technical documentation from Markdown files stored with software component code. A core feature of Backstage. ## Token @@ -306,8 +322,12 @@ A string containing information. ## Use Case -A purpose for which a [user role](#User-Role) interacts with Backstage. Related to [Objective](#objective): An objective is _what_ the user wants to do; a use case is _how_ the user does it. +A purpose for which a [user role](#User-Role) interacts with Backstage. Related to [Objective](#objective): An objective is _what_ the user wants to do, a use case is _how_ the user does it. + +## User + +Any consumer of Backstage or Backstage products/applications. Includes individuals like employees and contractors, as well as software that interacts with the backend through an API or acts as a proxy for a person by operating the user interface. ## User Role -A class of Backstage user for purposes of analyzing [use cases](#use-case). One of: evaluator; administrator; developer; integrator; and contributor. +A class of Backstage user for purposes of analyzing [use cases](#use-case). One of: [evaluator](#evaluator); [administrator](#administrator); [developer](#developer); [integrator](#integrator); and [contributor](#contributor). diff --git a/docs/releases/v1.40.0-changelog.md b/docs/releases/v1.40.0-changelog.md new file mode 100644 index 0000000000..e5b65ab8ed --- /dev/null +++ b/docs/releases/v1.40.0-changelog.md @@ -0,0 +1,2771 @@ +# Release v1.40.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.40.0](https://backstage.github.io/upgrade-helper/?to=1.40.0) + +## @backstage/plugin-scaffolder-backend@2.0.0 + +### Major Changes + +- 33394db: **BREAKING CHANGES** + + Removal of deprecated re-exports from module packages. + + The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: + + - `createPublishAzureAction` should be imported from `@backstage/plugin-scaffolder-backend-module-azure` instead. + + - `createPublishBitbucketCloudAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-cloud` instead. + + - `createPublishBitbucketServerAction` and `createPublishBitbucketServerPullRequestAction` can be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket-server` instead. + + - `createPublishBitbucketAction` should be imported from `@backstage/plugin-scaffolder-backend-module-bitbucket` instead. + + - `createPublishGerritAction` and `createPublishGerritReviewAction` can be imported from `@backstage/plugin-scaffolder-backend-module-gerrit` instead. + + - `createGithubActionsDispatchAction`, `createGithubDeployKeyAction`, `createGithubEnvironmentAction`, `createGithubIssuesLabelAction`, `CreateGithubPullRequestActionOptions`, `createGithubRepoCreateAction`, `createGithubRepoPushAction`, `createGithubWebhookAction`, and `createPublishGithubAction` can be imported from `@backstage/plugin-scaffolder-backend-module-github` instead. + + - `createPublishGitlabAction` should be imported from `@backstage/plugin-scaffolder-backend-module-gitlab` instead. + + - `ActionContext`. `createTemplateAction`, `executeShellCommand`, `ExecuteShellCommandOptions`, `fetchContents`, `TaskSecrets`, and `TemplateAction` should be imported from `@backstage/plugin-scaffolder-node` instead. + + - `ScaffolderEntitiesProcessor` should be imported from `@backstage/plugin-catalog-backend-module-scaffolder-entity-model` instead. + +- a8fcf04: **BREAKING ALPHA**: The `/alpha` export no longer exports the plugin. Please use `import('@backstage/plugin-scaffolder-backend')` instead as this has been removed. + + **BREAKING CHANGES**: The old `createRouter` function which was used in the old backend system has been removed along with the `RouterOptions` type. + +- 73b94d7: **BREAKING CHANGES** + + The following functions have been re-exported from the `scaffolder-backend` plugin for quite some time, and now it's time to clean them up. They've been moved as follows: + + - `SerializedTask`, `SerializedTaskEvent`, `TaskBroker`, `TaskBrokerDispatchOptions`, `TaskBrokerDispatchResult`, `TaskCompletionState`, `TaskContext`, `TaskEventType`, `TaskStatus`, `TemplateFilter`, and `TemplateGlobal` should be imported from `@backstage/plugin-scaffolder-node` instead. + + - The deprecated `copyWithoutRender` option has been removed from `fetch:template` action. You should rename the option to `copyWithoutTemplating` instead. + +- 5863b04: **BREAKING CHANGES** + + - The `createBuiltinActions` method has been removed, as this should no longer be needed with the new backend system route, and was only useful when passing the default list of actions again in the old backend system. You should be able to rely on the default behaviour of the new backend system which is to merge the actions. + + - The `createCatalogRegisterAction` and `createFetchCatalogEntityAction` actions no longer require an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. + + Unless you're providing your own override action to the default, this should be a non-breaking change. + + You can migrate using the following if you're getting typescript errors: + + ```ts + import { catalogServiceRef } from '@backstage/plugin-catalog-node'; + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + export const myModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'test', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + catalog: catalogServiceRef, + }, + async init({ scaffolder, catalog }) { + scaffolder.addActions( + createCatalogRegisterAction({ + catalog, + }), + createFetchCatalogEntityAction({ + catalog, + integrations, + }), + ); + }, + }); + }, + }); + ``` + +### Minor Changes + +- 73b94d7: **DEPRECATIONS** + + The following types and implementations have been deprecated, either because they're no longer relevant, or because upcoming changes to the `scaffolder-backend` after `2.0.0` will influence the changes to these API surfaces. + + - `CreateWorkerOptions` + - `DatabaseTaskStore` + - `DatabaseTaskStoreOptions` + - `TaskManager` + - `TaskStoreCreateTaskOptions` + - `TaskStoreCreateTaskResult` + - `TaskStoreEmitOptions` + - `TaskStoreListEventsOptions` + - `TaskStoreRecoverTaskOptions` + - `TaskStoreShutDownTaskOptions` + + There is no current path off deprecation, these types are going to be removed and rethought with a better way to define workers in the new backend system. + +### Patch Changes + +- 89a941d: Migrating to latest action format + +- 023629e: Enable usage of secrets within 'each' step of software templates. For example, you can now structure your `each` step like this: + + each: + [ + { name: "Service1", token: "${{ secrets.token1 }}" }, + { name: "Service2", token: "${{ secrets.token2 }}" }, + ] + +- e92e481: Add tests for Scaffolder + +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.10 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10 + - @backstage/plugin-scaffolder-backend-module-github@0.8.0 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.10 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/backend-defaults@0.11.0 + +### Minor Changes + +- 3ccb7fc: Enhanced error handling in the auditor service factory to pass errors as objects. Aligned WinstonRootAuditorService with the default service factory's error handling. + +### Patch Changes + +- 1220cf8: Added new rate limit middleware to allow rate limiting requests to the backend + + If you are using the `configure` callback of the root HTTP router service and do NOT call `applyDefaults()` inside it, please see [the relevant changes](https://github.com/backstage/backstage/pull/28708/files#diff-86ad1b6a694dd250823aee39d410428dd837c9d9a04ca8c33bd1081fbe3f22af) that were made, to see if you want to apply them as well to your custom configuration. + Rate limiting can be turned on by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + window: 6s + incomingRequestLimit: 100 + ``` + + Plugin specific rate limiting can be configured by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + global: false # This will disable the global rate limiting + plugin: + catalog: + window: 6s + incomingRequestLimit: 100 + ``` + +- c999c25: Added some default implementations for the experimental `ActionsService` and `ActionsRegistryService` under `/alpha` that allow registration of actions for a particular plugin. + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/backend-plugin-api@1.4.0 + +### Minor Changes + +- 664c07a: Added `actionsRegistry` and `actions` experimental services to `/alpha` to allow registration of distributed actions from plugins, and the ability to invoke these actions. You can use these services by including them like the following: + + ```ts + import { + actionsRegistryServiceRef, + actionsServiceRef, + } from '@backstage/backend-plugin-api/alpha'; + + createBackendPlugin({ + pluginId: 'test-plugin', + register({ registerInit }) { + registerInit({ + deps: { + actions: actionsServiceRef, + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actions, actionsRegistry }) { + actionsRegistry.register({ + ..., + }); + + await actions.invoke(...); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/backend-test-utils@1.6.0 + +### Minor Changes + +- 6dfb7be: Added `mockServices.permissions()` that can return actual results. +- c999c25: Added an `actionsRegistryServiceMock` and `actionsServiceMock` to `/alpha` export for the experimental services. + + This allows you to write tests for your actions by doing something similar to the following: + + ```ts + import { actionsRegistryServiceMock } from '@backstage/backend-test-utils/alpha'; + + const mockActionsRegistry = actionsRegistryServiceMock(); + const mockCatalog = catalogServiceMock({ + entities: [ + ... + ], + }); + + createGetCatalogEntityAction({ + catalog: mockCatalog, + actionsRegistry: mockActionsRegistry, + }); + + await expect( + mockActionsRegistry.invoke({ + id: 'test:get-catalog-entity', + input: { name: 'test' }, + }), + ).resolves.toEqual(...) + ``` + +### Patch Changes + +- 12c1fd4: Make the `user` credentials mock behave more like production +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/canon@0.5.0 + +### Minor Changes + +- 621fac9: We are updating the default size of the Button component in Canon to be small instead of medium. +- a842554: We set the default size for IconButton in Canon to be small instead of medium. +- 35fd51d: Move TextField component to use react Aria under the hood. Introducing a new FieldLabel component to help build custom fields. +- 78204a2: **Breaking** We are adding a new as prop on the Heading and Text component to make it easier to change the component tag. We are removing the render prop in favour of the as prop. +- c49e335: TextField in Canon now has multiple label sizes as well as the capacity to hide label and description but still make them available for screen readers. +- 24b45ef: Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using <Grid.Root /> instead of just . + +### Patch Changes + +- 44df879: Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements. +- ee6ffe6: Fix styling for the title4 prop on the Heading component in Canon. +- f2f814a: Added a render prop to the Button component in Canon to use it as a link. +- 98f02a6: Add new Switch component in Canon. +- c94f8e0: The filter input in menu comboboxes should now always use the full width of the menu it's in. +- 269316d: Remove leftover console.log from Container component. + +## @backstage/cli@0.33.0 + +### Minor Changes + +- eef0e83: Internal update to promote the modular CLI entrypoint to stable. + +### Patch Changes + +- d07fe35: Added user feedback when opening config docs in browser. The command now clearly indicates what it's doing and provides fallback instructions if the browser fails to open. +- ce70439: The `BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE` flag has been removed. Existing users are encouraged to switch to `EXPERIMENTAL_RSPACK` instead. +- 1d8f00b: Switched to using the `ModuleFederationPlugin` from `@module-federation/enhanced/rspack` for Rspack, rather than the built-in one. +- 2b9633f: The experimental `FORCE_REACT_DEVELOPMENT` flag has been removed. +- d8c4a54: Only use the caching Jest module loader for frontend packages in order to avoid breaking real ESM module imports. +- d6d63c7: Updating the scaffolder action boilerplate to use new `zod` schema +- e36e855: Added `backstage.pluginId` field in `package.json` to all default plugin package templates for the `new` command. +- 1bab255: Internal refactor to combine alpha `build` and `start` modules. +- 713e957: fix: merge eslint reports when using json format +- 8a0164c: Fix an issue where some commands were not usable because of missing dist files +- Updated dependencies + - @backstage/eslint-plugin@0.1.11 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/create-app@0.7.0 + +### Minor Changes + +- 30474c4: Add .cache directory to shipped gitignore. + +### Patch Changes + +- d57a6f7: Bumped create-app version. +- f628f44: Bumped create-app version. +- 9c9faf2: Bumped create-app version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/repo-tools@0.14.0 + +### Minor Changes + +- bf9a173: Add support for caching the per-package output from the `package-docs` command. + +### Patch Changes + +- 4bff5d0: Fixed a bug where linting would fail with the generated clients when defining top-level `enum` schema values. +- 2d20024: Fix an issue where errors were not printed to console when running `backstage-repo-tools schema openapi generate` without the `--watch` flag. +- e643ee4: Add missing highlight language for the `package-docs` command. +- c83cd8b: Fixed some circular or otherwise unclear imports +- a372bf1: Updated dependency `@electric-sql/pglite` to `^0.3.0`. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog@1.31.0 + +### Minor Changes + +- 406acb6: Add support to customize the about card icon links via `EntityIconLinkBlueprint` and provide a default catalog view catalog source, launch scaffolder template and read techdocs docs icon links extensions. + + **BREAKING ALPHA** + + The `Scaffolder` launch template and `TechDocs` read documentation icons have been extracted from the default `Catalog` about card links and are now provided respectively by the `Scaffolder` and `TechDocs` plugins in the new frontend system. It means that they will not be available unless you install the `TechDocs` and `Scaffolder` plugins. Also If you are using translation for these icon link titles other than the default, you should now translate them using the scaffolder translation reference or the TechDocs translation reference (the translation keys are still the same, `aboutCard.viewTechdocs` and `aboutCard.launchTemplate`). + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-catalog-backend@2.1.0 + +### Minor Changes + +- 2e7adf0: Implement the action `get-catalog-entity` with the `ActionsRegistry` + +### Patch Changes + +- 2cac8b0: You can now specify an optional value when applying the `HAS_LABEL` permission rule, similar to the `HAS_ANNOTATION` permission rule. +- c83cd8b: Fixed some circular or otherwise unclear imports +- 4654a78: Update `refresh_state_references.id` to be a big int +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.0 + +### Minor Changes + +- 8a150bf: **BREAKING**: `BitbucketCloudEntityProvider` now accepts a `CatalogService` instead of a `CatalogApi`. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.0 + +### Minor Changes + +- eb8b3aa: Add validateLocationsExist option to avoid generating locations for catalog-info.yaml files that do not exist in the source repository. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-github@0.10.0 + +### Minor Changes + +- 7c0dfb0: GitHub organization now matches in a case-insensitive manner when processing events. + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.0 + +### Minor Changes + +- 42bb3b8: **BREAKING CHANGE**: User and Group discovery will default to ingesting all users in sub groups that belong to the specified root group in config. Disable by setting `restrictUsersToGroup: true` in app-config under your module settings. + +### Patch Changes + +- 57a0bad: Implement retry for GitLab API calls to handle rate limiting +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-react@1.19.0 + +### Minor Changes + +- 406acb6: Introduces a new `EntityIconLinkBlueprint` that customizes the `About` card icon links on the `Catalog` entity page. + + The blueprint currently accepts a `useProps` hook as `param` and this function returns the following props that will be passed to the icon link component: + + | Name | Description | Type | Default Value | + | ---------- | --------------------------------------------------- | ------------- | ------------- | + | `icon` | The icon to display. | `JSX.Element` | N/A | + | `label` | The label for the element. | `string` | N/A | + | `title` | The title for the element. | `string` | N/A | + | `disabled` | Whether the element is disabled. | `boolean` | `false` | + | `href` | The URL to navigate to when the element is clicked. | `string` | N/A | + | `onClick` | A function to call when the element is clicked. | `() => void` | N/A | + + Here is an usage example: + + ```tsx + import { EntityIconLinkBlueprint } from '@backstage/plugin-catalog-react/alpha'; + //... + + EntityIconLinkBlueprint.make({ + name: 'my-icon-link', + params: { + useProps() { + const { t } = useTranslationRef(myIconLinkTranslationRef); + return { + label: t('myIconLink.label'), + icon: , + href: '/my-plugin', + }; + }, + }, + }); + ``` + + Additionally, the `app-config.yaml` file allows you to override some of the default icon link parameters, including `label` and `title` values. Here's how to set them: + + ```yaml + app: + extensions: + - entity-icon-link:my-plugin/my-icon-link: + config: + label: 'My Custom Icon Link label' + ``` + + Finally, you can disable all links if you want to hide the About card header completely (useful, for example, when links are displayed on separate cards). The header is hidden when no icon links extensions are enabled. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/frontend-test-utils@0.3.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-events-backend-module-kafka@0.1.0 + +### Minor Changes + +- b034b9d: Adds a new module `kafka` for plugin-events-backend + + The module introduces the `KafkaConsumerClient` which creates a Kafka client used to establish consumer connections. It also provides the `KafkaConsumingEventPublisher`, a consumer that subscribes to configured Kafka topics and publishes received messages to the Event Service. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-mcp-actions-backend@0.1.0 + +### Minor Changes + +- 4ed0fb6: Initial implementation of an `mcp-actions` backend + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder@1.32.0 + +### Minor Changes + +- 6c972fe: Added information about the `entityRef` and `taskId` to the analytics events whenever is possible. +- 3c59ece: **New Frontend System Only:** + The `Scaffolder` plugin is now responsible for providing an entity icon link extension to launch templates from the catalog entity page. + +### Patch Changes + +- d781b33: render details for composite property schemas +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- b00c160: Remove React import form notification and scaffolder plugin +- 95a1d72: Added appropriate message when global templating function metadata is absent. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.0 + +### Minor Changes + +- 5863b04: **BREAKING CHANGES** + + The `createGithubEnvironmentAction` action no longer requires an `AuthService`, and now accepts a `CatalogService` instead of `CatalogClient`. + + Unless you're providing your own override action to the default, this should be a non-breaking change. + + You can migrate using the following if you're getting typescript errors: + + ```ts + import { catalogServiceRef } from '@backstage/plugin-catalog-node'; + import { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha'; + + export const myModule = createBackendModule({ + pluginId: 'scaffolder', + moduleId: 'test', + register({ registerInit }) { + registerInit({ + deps: { + scaffolder: scaffolderActionsExtensionPoint, + catalog: catalogServiceRef, + }, + async init({ scaffolder, catalog }) { + scaffolder.addActions( + createGithubEnvironmentAction({ + catalog, + }), + ); + }, + }); + }, + }); + ``` + +### Patch Changes + +- 575c76b: Migrate to using new actions +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-node@0.9.0 + +### Minor Changes + +- 5863b04: **BREAKING CHANGES** + + The legacy methods to define `createTemplateActions` have been replaced with the new native `zod` approaches for defining input and output schemas. + + You can migrate actions that look like the following with the below examples: + + ```ts + // really old legacy json schema + createTemplateAction<{ repoUrl: string }, { repoOutput: string }>({ + id: 'test', + schema: { + input: { + type: 'object' + required: ['repoUrl'] + properties: { + repoUrl: { + type: 'string', + description: 'repository url description' + } + } + } + } + }); + + // old zod method + createTemplateAction({ + id: 'test' + schema: { + input: { + repoUrl: z.string({ description: 'repository url description' }) + } + } + }) + + // new method: + createTemplateAction({ + id: 'test', + schema: { + input: { + repoUrl: z => z.string({ description: 'repository url description' }) + } + } + }) + + // or for more complex zod types like unions + createTemplateAction({ + id: 'test', + schema: { + input: z => z.object({ + repoUrl: z.string({ description: 'repository url description' }) + }) + } + }) + ``` + + This breaking change also means that `logStream` has been removed entirely from `ActionsContext`, and that the `logger` is now just a `LoggerService` implementation instead. There is no replacement for the `logStream`, if you wish to still keep using a `logStream` we recommend that you create your own stream that writes to `ctx.logger` instead. + +### Patch Changes + +- e89d7b6: Use `LoggerService` instead of `Logger`. This is a non-breaking change, as the `LoggerService` is a subset of the `Logger` interface. +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.0 + +### Minor Changes + +- 3cea7ee: **BREAKING CHANGES** + + Because of the removal of the `logStream` property to the `ActionsContext` this has been removed from the `createMockActionContext` method. + + You can remove this as it's no longer supported in the scaffolder actions. + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-test-utils@1.6.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-react@1.17.0 + +### Minor Changes + +- 6c972fe: Added information about the `entityRef` and `taskId` to the analytics events whenever is possible. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-techdocs@1.13.0 + +### Minor Changes + +- 3c59ece: **New Frontend System Only:** + The `TechDocs` plugin is now responsible for providing an entity icon link extension to read documentation from the catalog entity page. +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/theme@0.6.6 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-techdocs-react@1.3.0 + +### Minor Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/version-bridge@1.0.11 + +## @backstage/app-defaults@1.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/backend-app-api@1.2.4 + +### Patch Changes + +- bb9a501: Fixed a bug where occasionally the initialization order of multiple modules consuming a single extension point could happen in the wrong order. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/backend-dynamic-feature-service@0.7.1 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/backend-openapi-utils@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/catalog-client@1.10.1 + +### Patch Changes + +- 22fad0d: Fixed `CatalogClient` error responses for `refreshEntity` and `addLocation`. +- Updated dependencies + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/core-app-api@1.17.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-compat-api@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.17.3 + +### Patch Changes + +- 6232160: table actions header support i18n +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-plugin-api@1.10.8 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- 0169b23: Internal tweak to avoid circular dependencies +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/dev-utils@1.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + +## @backstage/eslint-plugin@0.1.11 + +### Patch Changes + +- 098ef95: Fix custom rules package scanning performance. +- 063b2d3: Added new eslint rule to restrict mixed plugin imports. + + New rule `@backstage/no-mixed-plugin-imports` disallows mixed imports between plugins that are mixing + the backstage architecture. This rule forces that: + + - No imports from frontend plugins to backend plugins or other frontend plugins. + - No imports from backend plugins to frontend plugins or other backend plugins. + - No imports from common plugins to frontend or backend plugins. + + The current recommended configuration is giving a warning for mixed imports. This is to be changed in + the future to an error so please adjust your workspace accordingly. + +## @backstage/frontend-app-api@0.11.3 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies +- c38c9e8: Implemented support for the `plugin.info()` method in specialized apps with a default resolved for `package.json` and `catalog-info.yaml`. The default resolution logic can be overridden via the `pluginInfoResolver` option to `createSpecializedApp`, and plugin-specific overrides can be applied via the new `app.pluginOverrides` key in static configuration. +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-defaults@0.2.3 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.2.3 + +### Patch Changes + +- fa5650c: Forwarded the new `pluginInfoResolver` option for `createApp`. +- Updated dependencies + - @backstage/plugin-app@0.1.10 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/frontend-dynamic-feature-loader@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/config@1.3.2 + +## @backstage/frontend-plugin-api@0.10.3 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies + +- 9e3868f: Added a new optional `info` option to `createFrontendPlugin` that lets you provide a loaders for different sources of metadata information about the plugin. + + There are two available loaders. The first one is `info.packageJson`, which can be used to point to a `package.json` file for the plugin. This is recommended for any plugin that is defined within its own package, especially all plugins that are published to a package registry. Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + packageJson: () => import('../package.json'), + }, + }); + ``` + + The second loader is `info.manifest`, which can be used to point to an opaque plugin manifest. This **MUST ONLY** be used by plugins that are intended for use within a single organization. Plugins that are published to an open package registry should **NOT** use this loader. The loader is useful for adding additional internal metadata associated with the plugin, and it is up to the Backstage app to decide how these manifests are parsed and used. The default manifest parser in an app created with `createApp` from `@backstage/frontend-defaults` is able to parse the default `catalog-info.yaml` format and built-in fields such as `spec.owner`. + + Typical usage looks like this: + + ```ts + export default createFrontendPlugin({ + pluginId: '...', + info: { + manifest: () => import('../catalog-info.yaml'), + }, + }); + ``` + +- 6f48f71: Added a new `useAppNode` hook, which can be used to get a reference to the `AppNode` from by the closest `ExtensionBoundary`. + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.10 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/config@1.3.2 + - @backstage/test-utils@1.7.9 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/integration-react@1.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + +## @techdocs/cli@1.9.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/plugin-techdocs-node@1.13.4 + +## @backstage/test-utils@1.7.9 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-api-docs@0.12.8 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/plugin-catalog@1.31.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app@0.1.10 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/integration-react@1.2.8 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app-backend@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + +## @backstage/plugin-app-node@0.1.34 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config-loader@1.10.1 + +## @backstage/plugin-app-visualizer@0.1.20 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + +## @backstage/plugin-auth-backend@0.25.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-atlassian-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-auth0-provider@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-aws-alb-provider@0.4.4 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/plugin-auth-backend@0.25.1 + +## @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-bitbucket-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-bitbucket-server-provider@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-gcp-iap-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-github-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-gitlab-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-google-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-microsoft-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-oauth2-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + +## @backstage/plugin-auth-backend-module-oidc-provider@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-auth-backend@0.25.1 + +## @backstage/plugin-auth-backend-module-okta-provider@0.2.4 + +### Patch Changes + +- b25977f: Updated dependency `@davidzemon/passport-okta-oauth` to `^0.0.6`. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-onelogin-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-auth-backend-module-pinniped-provider@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-backend-module-vmware-cloud-provider@0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + +## @backstage/plugin-auth-node@0.6.4 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-auth-react@0.1.16 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-aws@0.4.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-azure@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-catalog-backend-module-gcp@0.3.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-catalog-backend-module-github@0.10.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.11.6 + +### Patch Changes + +- 087d51d: Export LDAP vendor types and instances for testing custom transformers + +- f07b0ad: Added the ability to configure disabling one side of the relations tree with LDAP. + + Groups have a `member` attribute and users have a `memberOf` attribute, however these can drift out of sync in some LDAP installations, leaving weird states in the Catalog as we collate these results together and deduplicate them. + + You can chose to optionally disable one side of these relationships, or even both by setting the respective mapping to `null` in your `app-config.yaml` for your groups and/or users: + + ```yaml + catalog: + providers: + ldapOrg: + default: + target: ldaps://ds.example.net + bind: + dn: uid=ldap-reader-user,ou=people,ou=example,dc=example,dc=net + secret: ${LDAP_SECRET} + users: + - dn: ou=people,ou=example,dc=example,dc=net + options: + filter: (uid=*) + map: + # this ensures that outgoing memberships from users is ignored + memberOf: null + groups: + - dn: ou=access,ou=groups,ou=example,dc=example,dc=net + options: + filter: (&(objectClass=some-group-class)(!(groupType=email))) + map: + description: l + set: + metadata.customField: 'hello' + map: + # this ensures that outgoing memberships from groups is ignored + members: null + ``` + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-logs@0.1.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-msgraph@0.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-puppetdb@0.2.11 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-unprocessed-entities-common@0.0.8 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-graph@0.4.20 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.1 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 5d7c539: Catalog import plugin full support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-node@1.17.1 + +### Patch Changes + +- 0169b23: Internal tweak to avoid circular dependencies +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.18 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + +## @backstage/plugin-config-schema@0.1.69 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-devtools@0.1.28 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-devtools-backend@0.5.6 + +### Patch Changes + +- 9a99735: Removed the usage of `permissionIntegrationRouter` in favor of using the new `coreServices.permissionsRegistry` +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-events-backend@0.5.3 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-aws-sqs@0.4.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-azure@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-bitbucket-cloud@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-bitbucket-server@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-gerrit@0.2.21 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-github@0.4.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-gitlab@0.3.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + +### Patch Changes + +- f983e99: Add an `EventConsumingGooglePubSubPublisher`, for pushing Backstage events to pubsub +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-backend-test-utils@0.1.45 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-events-node@0.4.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-gateway-backend@1.0.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-home@0.8.9 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 0ebad54: Fixed the `WelcomeTitle` to properly default to the previous value of `inherit` +- cef60db: Home plugin support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-home-react@0.1.27 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/theme@0.6.6 + +## @backstage/plugin-home-react@0.1.27 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- cef60db: Home plugin support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + +## @backstage/plugin-kubernetes@0.12.8 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 3ea5d1b: chore(deps): Update deprecated xterm to new package under @xterm +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/plugin-kubernetes-react@0.5.8 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-backend@0.19.7 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-node@0.3.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-kubernetes-cluster@0.0.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/plugin-kubernetes-react@0.5.8 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-node@0.3.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-kubernetes-react@0.5.8 + +### Patch Changes + +- 3ea5d1b: chore(deps): Update deprecated xterm to new package under @xterm +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-notifications@0.5.6 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- b00c160: Remove React import form notification and scaffolder plugin +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-notifications-backend@0.5.7 + +### Patch Changes + +- 41d4d6e: Notifications are now automatically deleted after 1 year by default. + + There is a new scheduled task that runs every 24 hours to delete notifications older than 1 year. + This can be configured by setting the `notifications.retention` in the `app-config.yaml` file. + + ```yaml + notifications: + retention: 1y + ``` + + If the retention is set to false, notifications will not be automatically deleted. + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. + +- ef9ab82: Notifications API will now return user as null always for broadcast notifications + +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-notifications-backend-module-email@0.3.10 + +### Patch Changes + +- 8a150bf: Internal changes to switch to the non-alpha `catalogServiceRef` +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications-backend-module-slack@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications-common@0.0.9 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- Updated dependencies + - @backstage/config@1.3.2 + +## @backstage/plugin-notifications-node@0.2.16 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-org@0.6.40 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- 4fe364f: Org plugin support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.3 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-org-react@0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/catalog-client@1.10.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + +## @backstage/plugin-permission-backend@0.7.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + +## @backstage/plugin-permission-node@0.10.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-permission-react@0.4.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/config@1.3.2 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-proxy-backend@0.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + - @backstage/plugin-proxy-node@0.1.5 + +## @backstage/plugin-proxy-node@0.1.5 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.10 + +### Patch Changes + +- e89d7b6: Migrating `azure` actions to using the new `zod` schema format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.11 + +### Patch Changes + +- 7f710d2: Migrating `bitbucket` actions to use the new `zod` format +- Updated dependencies + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.10 + +### Patch Changes + +- ca9fdc0: Migrate `bitbucket-cloud` to new actions format +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- 280611d: Fix `bitbucketCloudBranchRestrictions` API calls to accept null to prevent 400 errors for some branch restriction kinds defined. +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.0 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.10 + +### Patch Changes + +- d8169fc: Migrate the actions to the new format +- 9c8ff0c: Update pull request creation filter to include .gitignore files in the created pull request +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.10 + +### Patch Changes + +- 4a86bca: Migrate actions to new format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.11 + +### Patch Changes + +- 0b2bbf1: Migrate using new actions format +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.10 + +### Patch Changes + +- e24b29b: Migrating to use new format for actions +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.10 + +### Patch Changes + +- ed41017: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.2 + +### Patch Changes + +- 063b2d3: Fixed dependency to frontend package from tests +- a296637: Migrate to new action format +- 3d6493a: Support merge request labels in publish:gitlab:merge-request +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.11 + +### Patch Changes + +- 1fb5f06: Adds ability for user to turn on/off notifications for specific topics within an origin. +- 3f56115: Removed `octokit` dependency as it was not being used +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.10 + +### Patch Changes + +- a579693: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.10 + +### Patch Changes + +- 6c6fb4a: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.11 + +### Patch Changes + +- b392a34: Migrate to new actions format +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.3.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-search@1.4.27 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend@2.0.3 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-catalog@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-elasticsearch@1.7.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-explore@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-pg@0.5.45 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-stack-overflow-collator@0.3.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-techdocs@0.4.3 + +### Patch Changes + +- b47ec38: Exports the default document collator for use in document transformation during search indexing. +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-node@1.13.4 + +## @backstage/plugin-search-backend-node@1.3.12 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-react@1.9.1 + +### Patch Changes + +- 869fa46: SearchBar clear button support i18n +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-signals@0.0.20 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-signals-backend@0.3.5 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-signals-node@0.1.21 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-signals-react@0.0.14 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.49 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/integration-react@1.2.8 + - @backstage/core-app-api@1.17.1 + - @backstage/test-utils@1.7.9 + +## @backstage/plugin-techdocs-backend@2.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-client@1.10.1 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.3 + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-techdocs-node@1.13.4 + +## @backstage/plugin-techdocs-common@0.1.1 + +### Patch Changes + +- ec7b35d: Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into another entities TechDocs in conjunction with `backstage.io/techdocs-entity`. + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + +### Patch Changes + +- 9dde3ba: Improved Keyboard accessibility in techdocs. +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/integration-react@1.2.8 + - @backstage/integration@1.17.0 + +## @backstage/plugin-techdocs-node@1.13.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs-common@0.1.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-user-settings@0.8.23 + +### Patch Changes + +- 18c64e9: Added the `info.packageJson` option to the plugin instance for the new frontend system. +- ab6d3dd: Add some translation to user-setting plugin +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/errors@1.2.7 + - @backstage/theme@0.6.6 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.21 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.110 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-devtools@0.1.28 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + +## example-app-next@0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-app-visualizer@0.1.20 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-app@0.1.10 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/frontend-defaults@0.2.3 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + +## app-next-example-plugin@0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/frontend-plugin-api@0.10.3 + +## example-backend@0.0.39 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-backend@0.5.7 + - @backstage/plugin-scaffolder-backend-module-github@0.8.0 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-backend@2.0.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-devtools-backend@0.5.6 + - @backstage/plugin-mcp-actions-backend@0.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-search-backend@2.0.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-search-backend-module-techdocs@0.4.3 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.3 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + +## e2e-test@0.2.29 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.10 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/frontend-plugin-api@0.10.3 + +## techdocs-cli-embedded-app@0.2.109 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/test-utils@1.7.9 + - @backstage/theme@0.6.6 + +## yarn-plugin-backstage@0.0.6 + +### Patch Changes + +- a0f9e4e: added functionality so that adding or updating a backstage dependency to a package would maintain the "backstage:^" placeholder for the version. +- Updated dependencies + - @backstage/cli-common@0.1.15 + - @backstage/release-manifests@0.0.13 + +## @internal/plugin-todo-list@1.0.40 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + +## @internal/plugin-todo-list-backend@1.0.40 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 diff --git a/docs/releases/v1.40.0.md b/docs/releases/v1.40.0.md new file mode 100644 index 0000000000..b5ef87ffe1 --- /dev/null +++ b/docs/releases/v1.40.0.md @@ -0,0 +1,190 @@ +--- +id: v1.40.0 +title: v1.40.0 +description: Backstage Release v1.40.0 +--- + +These are the release notes for the v1.40.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### Scaffolder 2.0 Breaking Changes + +The deprecated legacy action formats have been removed and replaced with the new native `zod` formats. + +This also cleaned up some deprecated `logStream` and `WinstonLogger` usages in the old patterns. + +```ts +// really old legacy json schema +createTemplateAction<{ repoUrl: string }, { repoOutput: string }>({ + id: 'test', + schema: { + input: { + type: 'object' + required: ['repoUrl'] + properties: { + repoUrl: { + type: 'string', + description: 'repository url description' + } + } + } + } +}); + +// old zod method +createTemplateAction({ + id: 'test' + schema: { + input: { + repoUrl: z.string({ description: 'repository url description' }) + } + } +}) + +// new method: +createTemplateAction({ + id: 'test', + schema: { + input: { + repoUrl: z => z.string({ description: 'repository url description' }) + } + } +}) + +``` + +The `scaffolder-backend` plugin has been converted to being New Backend System only, which means a lot of the public API has been cleaned up. + +The `createRouter` and `createBuiltinActions` have been removed as they were only used in the legacy backend system. + +A lot of deprecated types which were re-exported in the `-backend` package from `-common` and `-node` have been removed, and can be fixed by importing them from the correct package. + +The deprecated `copyWithoutRender` option has been removed from `fetch:template` and should be renamed to `copyWithoutTemplating`. + +The re-exported action creators from the provider packages such as `createPublishAzureAction` and `createPublishGithubAction` should now be imported from the provider modules themselves. + +As always you can head over the latest changelogs for [`@backstage/plugin-scaffolder-backend`](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-backend/CHANGELOG.md) and [`@backstage/plugin-scaffolder-node`](https://github.com/backstage/backstage/blob/master/plugins/scaffolder-node/CHANGELOG.md) +for more detailed information. + +There’s also a number of new deprecation for types which are currently exported from `plugin-scaffolder-node`. We’re going to be looking at re-working the Scaffolder architecture in the future, so we’re going to be removing these types in a future version to iterate on the new API surfaces. Stay tuned for more updates! + +### Actions Registry + +We’ve added two new `alpha` services which can be used to define distributed Actions across Backstage. Plugins can use the `ActionsRegistry` to define actions that are automatically installed with their associated plugin. + +On top of this Actions Registry is a new `mcp-actions` backend plugin, which will surface these actions as tools as an MCP server. This can be used to expose plugin Actions with your favourite AI tools, such as Cursor, Claude or ChatGPT. + +You can find out more information about the `ActionsRegistry` and MCP integration in [this RFC](https://github.com/backstage/backstage/issues/30218). + +We’re actively working on this area, therefore it’s currently highly experimental and could be subject to breaking changes in future releases. However we’d really appreciate some feedback if you want to try and create some Actions for your plugins and surface them in an MCP server! + +In the next release we’ll be looking to integrate these Actions with the Scaffolder allowing you to call these actions from a template. + +### TechDocs deep linking + +Introduced `backstage.io/techdocs-entity-path` annotation which allows deep linking into other TechDocs in conjunction with `backstage.io/techdocs-entity`. + +Contributed by [@csuich2](https://github.com/csuich2) in [#29760](https://github.com/backstage/backstage/pull/29760) + +### Catalog modules Breaking Changes + +- `BitbucketCloudEntityProvider` now accepts a `CatalogService` instead of `CatalogApi` +- User and Group discovery for GitLab will default to ingesting all users in sub groups that belong to the specified root group in config. Disable by setting `restrictUsersToGroup: true` in app-config under your module settings. + +### New Module drop: `@backstage/plugin-events-backend-module-kafka` + +The module introduces the `KafkaConsumerClient` which creates a Kafka client used to establish consumer connections. It also provides the `KafkaConsumingEventPublisher`, a consumer that subscribes to configured Kafka topics and publishes received messages to the Backstage events service where Backstage plugins can access them. + +Contributed by [@Jonas-Beck](https://github.com/Jonas-Beck) in [#29315](https://github.com/backstage/backstage/pull/29315) + +### New lint rule added + +A new lint rule `@backstage/no-mixed-plugin-imports` was added to the defaults. This enforces rules that were always true but until now were implicit: that you should not import across frontend and backend package boundaries, isomorphic packages should not import non-isomorphic, etc. + +This rule is initially only set at a warning level, to give you some time to react. You may see warnings appear in your build output that were not there before - do pay attention to them, because they may expose some issues that you had not yet noticed. + +We intend to make this rule be at an error level in a future release. + +The rule has an option `excludedTargetPackages` that lets you opt out of enforcement in specific packages. You can put something like this in your root `.eslintrc.js`: + +```js +module.exports = { + root: true, + plugins: ['@spotify', 'react', 'testing-library', '@backstage'], + rules: { + '@backstage/no-mixed-plugin-imports': [ + 'error', // if you want to opt in to strict checks early + { + excludedTargetPackages: [ + '@internal/plugin-foo', + // ... +``` + +Contributed by [@drodil](https://github.com/drodil) in [#30227](https://github.com/backstage/backstage/pull/30227) + +### CLI: movement toward `rspack` + +The `BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE` flag has been removed entirely. If you were using this flag, we encourage you to switch to `EXPERIMENTAL_RSPACK` instead. In the near future, we hope to make `rspack` the default out of the box. + +While making these changes, the experimental `FORCE_REACT_DEVELOPMENT` flag was removed as well. + +### Backend rate limiting + +The backend system now has builtin support for rate limiting of incoming requests, both for your entire backends and on a per-plugin basis. It can use different backing stores for its state, and in-memory and redis is currently implemented out of the box. + +You can read more about this opt-in feature in [the documentation](https://backstage.io/docs/backend-system/core-services/http-router) for the HTTP router service. + +Contributed by [@drodil](https://github.com/drodil) in [#28708](https://github.com/backstage/backstage/pull/28708) + +### New Frontend System plugin info + +Plugins in the new frontend system can now expose rich, extensible metadata about themselves. This data is accessible at runtime inside your app. This is for example useful for adding contact and support information, and much more - and you can even overlay your own data on top of what is provided by open-source plugins. + +You can read more about this in the [frontend app](https://backstage.io/docs/frontend-system/architecture/app) and [plugin](https://backstage.io/docs/frontend-system/architecture/plugins) architecture documentation. + +### Notifications retention + +Notifications that are stored by the notifications backend plugin now have a default retention of one year before being deleted. This helps keep the storage size in check over time. You can override this using the `notifications.retention` duration setting in your app-config. + +Contributed by [@drodil](https://github.com/drodil) in [#30206](https://github.com/backstage/backstage/pull/30206) + +### Lots of i18n work + +A bunch of work was done to enable i18n (translations) in several plugins! This affected at least the following: + +- core components +- the org plugin +- the catalog import plugin +- the home plugin +- the search plugin +- the user settings plugin + +Contributed by [@mario-mui](https://github.com/mario-mui) + +### Canon steams ahead + +While it’s still early days, we still want to call out that the canon design system work steams ahead with various controls added and improvements made. Hang tight! + +## Security Fixes + +This release does not contain any security fixes. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/backstage-687207715902193673) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.40.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://info.backstage.spotify.com/newsletter_subscribe) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.41.0-next.0-changelog.md b/docs/releases/v1.41.0-next.0-changelog.md new file mode 100644 index 0000000000..9988f3005b --- /dev/null +++ b/docs/releases/v1.41.0-next.0-changelog.md @@ -0,0 +1,1497 @@ +# Release v1.41.0-next.0 + +Upgrade Helper: [https://backstage.github.io/upgrade-helper/?to=1.41.0-next.0](https://backstage.github.io/upgrade-helper/?to=1.41.0-next.0) + +## @backstage/plugin-catalog-backend@3.0.0-next.0 + +### Major Changes + +- 2339363: **BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed. + + The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly. + If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential + search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)). + + Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead. + + This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider. + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/backend-test-utils@1.7.0-next.0 + +### Minor Changes + +- ead925a: Add a standard `toString` on credentials objects + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/canon@0.6.0-next.0 + +### Minor Changes + +- 4c6d891: **BREAKING CHANGES** + + We’re updating our Button component to provide better support for button links. + + - We’re introducing a new `ButtonLink` component, which replaces the previous render prop pattern. + - To maintain naming consistency across components, `IconButton` is being renamed to `ButtonIcon`. + - Additionally, the render prop will be removed from all button-related components. + + These changes aim to simplify usage and improve clarity in our component API. + +### Patch Changes + +- 140f652: We are consolidating all css files into a single styles.css in Canon. +- 8154fb9: Add new SearchField component in Canon +- 6910892: Add new `RadioGroup` + `Radio` component to Canon +- a8a8514: We are transforming how we structure our class names and data attributes definitions for all components. They are now all set in the same place. +- 667b951: Added placeholder prop to TextField component. +- e71333a: adding export for ButtonLink so it's importable + +## @backstage/repo-tools@0.15.0-next.0 + +### Minor Changes + +- 1e7082e: Clear output directory before running `package-docs` and skip all internal packages. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @backstage/app-defaults@1.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/backend-defaults@0.11.1-next.0 + +### Patch Changes + +- ead925a: Add a standard `toString` on credentials objects +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## @backstage/backend-dynamic-feature-service@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/cli@0.33.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/eslint-plugin@0.1.11 + - @backstage/release-manifests@0.0.13 + - @backstage/types@1.2.1 + +## @backstage/core-compat-api@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/version-bridge@1.0.11 + +## @backstage/core-components@0.17.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/version-bridge@1.0.11 + +## @backstage/create-app@0.7.1-next.0 + +### Patch Changes + +- 2339363: **BREAKING:** The experimental `catalog.useUrlReadersSearch` configuration flag (introduced in v1.36) has been removed. + + The `UrlReaderProcessor` now always uses the `search` method of `UrlReaders`. Built-in `UrlReaderService` implementations have been updated accordingly. + If you use custom `UrlReaderService` implementations, you need to adapt their `search` method to correctly handle both specific URLs and potential + search patterns (see changes on built-in readers [in the original PR](https://github.com/backstage/backstage/pull/28379/files#diff-68b0452f173ee54bdd40f7b5e047a9cb8bb59200425622c212c217b76dac1d1b)). + + Previous behavior was to call the `search` method only if the parsed Git URL's filename contained a wildcard and use `readUrl` otherwise. Each `UrlReaderService` must implement this logic in the `search` method instead. + + This allows each `UrlReaderService` implementation to check whether it's a search URL (that contains a wildcard pattern) or not using logic that is specific to each provider. + +- Updated dependencies + - @backstage/cli-common@0.1.15 + +## @backstage/dev-utils@1.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + +## @backstage/frontend-app-api@0.11.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-defaults@0.2.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-defaults@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/frontend-dynamic-feature-loader@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/frontend-plugin-api@0.10.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/frontend-test-utils@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/config@1.3.2 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @backstage/integration@1.17.1-next.0 + +### Patch Changes + +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/integration-react@1.2.9-next.0 + +### Patch Changes + +- 998fd15: Separated gitlab `write_repository` and `api` scope to pass checks in `RefreshingAuthSessionManager` +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.8 + +## @techdocs/cli@1.9.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + +## @backstage/test-utils@1.7.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/theme@0.6.7-next.0 + +### Patch Changes + +- b68d269: Update uncomfortably bright color in recently visited and top visited home page cards + +## @backstage/plugin-api-docs@0.12.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app@0.1.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-app-visualizer@0.1.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-auth-react@0.1.17-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + +## @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + +## @backstage/plugin-catalog@1.31.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-catalog-backend-module-aws@0.4.13-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-catalog-backend-module-azure@0.3.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gerrit@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gitea@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github@0.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-github-org@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-github@0.10.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + +## @backstage/plugin-catalog-backend-module-gitlab@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-backend-module-gitlab-org@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend-module-gitlab@0.7.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-incremental-ingestion@0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-catalog-backend-module-logs@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + +## @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-model@1.7.4 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-graph@0.4.21-next.0 + +### Patch Changes + +- fe1a2f4: Catalog graph plugin support i18n +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-catalog-import@0.13.2-next.0 + +### Patch Changes + +- 406b8b8: Fixed bug with error message since ResponseError is now thrown from CatalogClient +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-catalog-react@1.19.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration-react@1.2.9-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/frontend-test-utils@0.3.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-config-schema@0.1.70-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-devtools@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-devtools-backend@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config-loader@1.10.1 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-devtools-common@0.1.16 + - @backstage/plugin-permission-common@0.9.0 + +## @backstage/plugin-events-backend-module-github@0.4.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + - @backstage/types@1.2.1 + +## @backstage/plugin-home@0.8.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-home-react@0.1.28-next.0 + +## @backstage/plugin-home-react@0.1.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-kubernetes@0.12.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-react@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-kubernetes-common@0.9.5 + - @backstage/plugin-kubernetes-react@0.5.9-next.0 + - @backstage/plugin-permission-react@0.4.35 + +## @backstage/plugin-kubernetes-react@0.5.9-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-kubernetes-common@0.9.5 + +## @backstage/plugin-mcp-actions-backend@0.1.1-next.0 + +### Patch Changes + +- 6bc0799: Fixed the example in the README for generating a static token by adding a subject field +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-client@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-notifications@0.5.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-notifications-backend@0.5.8-next.0 + +### Patch Changes + +- 9a5a73f: Fix `addTopic` migration when `user_settings` present +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-notifications-common@0.0.9 + - @backstage/plugin-signals-node@0.1.21 + +## @backstage/plugin-org@0.6.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-catalog-common@1.1.4 + +## @backstage/plugin-org-react@0.1.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + +## @backstage/plugin-scaffolder@1.32.1-next.0 + +### Patch Changes + +- 289e4a1: Filter MultiEntityPicker options based on rendered option value +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend@2.0.1-next.0 + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- fc70b43: Replaced deprecated uses of `@backstage/backend-common` with the equivalents in `@backstage/backend-defaults` and `@backstage/backend-plugin-api`. +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.0 + - @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-backend-module-azure@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.0 + - @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-bitbucket-cloud-common@0.3.1-next.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-confluence-to-markdown@0.3.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.3.13-next.0 + +### Patch Changes + +- cf9ba6f: Fixing the typescript issue with using `z.unknown()` +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gcp@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gerrit@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-gitea@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + +### Patch Changes + +- f36bcf9: Added support for file deletion to `publish:github:pull-request` action. + + Example usage: + + ```diff + - action: publish:github:pull-request + id: clean-up-pr + input: + description: This is the description + + filesToDelete: + + - outdated/changelog.md + + - sample-file.txt + owner: owner + repo: repo + title: Title Goes Here + + ``` + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-gitlab@0.9.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-notifications-node@0.2.16 + - @backstage/plugin-notifications-common@0.0.9 + +## @backstage/plugin-scaffolder-backend-module-rails@0.5.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-backend-module-sentry@0.2.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.4.12-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-node@0.9.1-next.0 + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-scaffolder-node-test-utils@0.3.1-next.0 + +### Patch Changes + +- dbde180: An internal refactor which adds additional types to experimental checkpoints +- Updated dependencies + - @backstage/backend-test-utils@1.7.0-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/types@1.2.1 + +## @backstage/plugin-scaffolder-react@1.17.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-scaffolder-common@1.5.11 + +## @backstage/plugin-search@1.4.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend@2.0.4-next.0 + +### Patch Changes + +- 69fb975: Error messages should not contain backend SQL query strings in the API response, this change will ensure that messages are logged and empty response is returned to the user +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-search-react@1.9.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-search-common@1.2.18 + +## @backstage/plugin-signals@0.0.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + +## @backstage/plugin-techdocs@1.13.2-next.0 + +### Patch Changes + +- 1debf7f: Fixed an issue causing TechDocs to not properly handle initial redirect. +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.51-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + +## @backstage/plugin-techdocs-backend@2.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-catalog-node@1.17.1 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + - @backstage/plugin-techdocs-node@1.13.5-next.0 + - @backstage/catalog-client@1.10.1 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## @backstage/plugin-techdocs-node@1.13.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/plugin-search-common@1.2.18 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-techdocs-react@1.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/version-bridge@1.0.11 + - @backstage/plugin-techdocs-common@0.1.1 + +## @backstage/plugin-user-settings@0.8.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/errors@1.2.7 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-react@0.0.14 + - @backstage/plugin-user-settings-common@0.0.1 + +## @backstage/plugin-user-settings-backend@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-signals-node@0.1.21 + - @backstage/plugin-user-settings-common@0.0.1 + +## example-app@0.2.111-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-devtools@0.1.29-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## example-app-next@0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-defaults@0.2.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-app-visualizer@0.1.21-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## app-next-example-plugin@0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## example-backend@0.0.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-backend@2.0.1-next.0 + - @backstage/plugin-notifications-backend@0.5.8-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + - @backstage/plugin-search-backend@2.0.4-next.0 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-devtools-backend@0.5.7-next.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.4-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-common@0.9.0 + +## e2e-test@0.2.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/create-app@0.7.1-next.0 + - @backstage/cli-common@0.1.15 + - @backstage/errors@1.2.7 + +## @internal/frontend@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/types@1.2.1 + - @backstage/version-bridge@1.0.11 + +## @internal/scaffolder@0.0.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## techdocs-cli-embedded-app@0.2.110-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/test-utils@1.7.10-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + +## @internal/plugin-todo-list@1.0.41-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-plugin-api@1.10.8 diff --git a/microsite/data/plugins/hetzner-cloud.yaml b/microsite/data/plugins/hetzner-cloud.yaml new file mode 100644 index 0000000000..6f1fbe3f25 --- /dev/null +++ b/microsite/data/plugins/hetzner-cloud.yaml @@ -0,0 +1,10 @@ +--- +title: Hetzner Cloud +author: Gluo NV +authorUrl: https://github.com/gluobe +category: Infrastructure +description: Integrate Hetzner Cloud resources into Backstage. +documentation: https://github.com/gluobe/hetzner-backstage-plugin/blob/main/README.md +iconUrl: https://avatars.githubusercontent.com/u/18439789?s=200&v=4 +npmPackageName: '@gluo-nv/backstage-plugin-hetzner' +addedDate: '2025-06-03' diff --git a/microsite/data/plugins/spacelift-io.yaml b/microsite/data/plugins/spacelift-io.yaml new file mode 100644 index 0000000000..fe9b48139f --- /dev/null +++ b/microsite/data/plugins/spacelift-io.yaml @@ -0,0 +1,10 @@ +--- +title: Spacelift.io +author: Spacelift.io +authorUrl: https://spacelift.io/ +category: Infrastructure +description: The Spacelift plugin allows you to manage your infrastructure directly from Backstage. Visualize your IaC stacks and trigger runs with ease. +documentation: https://docs.spacelift.io/integrations/external-integrations/backstage +iconUrl: https://avatars.githubusercontent.com/u/53318513?s=200&v=4 +npmPackageName: '@spacelift-io/backstage-integration-frontend' +addedDate: '2025-06-10' diff --git a/microsite/data/plugins/stackoverflow-teams.yaml b/microsite/data/plugins/stackoverflow-teams.yaml new file mode 100644 index 0000000000..cfe08757d3 --- /dev/null +++ b/microsite/data/plugins/stackoverflow-teams.yaml @@ -0,0 +1,10 @@ +--- +title: Stack Overflow for Teams +author: EstoesMoises +authorUrl: https://github.com/estoesmoises/ +category: Discovery +description: Provide seamless access to Stack Overflow Teams most relevant data, allowing you to display the top users, top tags, and top questions directly within Backstage. It also allows to securely create SO Teams questions from Backstage. +documentation: https://github.com/StackExchange/backstage-stackoverflow/blob/main/README.md +iconUrl: /img/stack-overflow-logo.svg +npmPackageName: 'backstage-plugin-stack-overflow-teams' +addedDate: '2025-06-10' diff --git a/microsite/docusaurus.config.ts b/microsite/docusaurus.config.ts index d71483ab8f..d7538cd12d 100644 --- a/microsite/docusaurus.config.ts +++ b/microsite/docusaurus.config.ts @@ -483,7 +483,7 @@ const config: Config = { copyright: `

Made with ❤️ at Spotify

`, }, algolia: { - apiKey: '1f0ba86672ccfc3576faa94583e5b318', + apiKey: '60d2643a9c6306463f15f8c3556e7f2e', // Owned by @Rugvip indexName: 'crawler_Backstage Docusaurus 2', appId: 'JCMFNHCHI8', searchParameters: {}, diff --git a/microsite/sidebars.ts b/microsite/sidebars.ts index 1f8d3defb7..eef7ef5ee9 100644 --- a/microsite/sidebars.ts +++ b/microsite/sidebars.ts @@ -330,7 +330,7 @@ export default { { type: 'category', label: 'Gitea', - items: ['integrations/gitea/locations'], + items: ['integrations/gitea/locations', 'integrations/gitea/discovery'], }, { type: 'category', @@ -462,6 +462,8 @@ export default { 'backend-system/core-services/token-manager', 'backend-system/core-services/url-reader', 'backend-system/core-services/user-info', + 'backend-system/core-services/actions-registry', + 'backend-system/core-services/actions', ], }, ], diff --git a/microsite/yarn.lock b/microsite/yarn.lock index e6454c4e82..40a000df33 100644 --- a/microsite/yarn.lock +++ b/microsite/yarn.lock @@ -4430,12 +4430,12 @@ __metadata: linkType: hard "brace-expansion@npm:^1.1.7": - version: 1.1.11 - resolution: "brace-expansion@npm:1.1.11" + version: 1.1.12 + resolution: "brace-expansion@npm:1.1.12" dependencies: balanced-match: "npm:^1.0.0" concat-map: "npm:0.0.1" - checksum: 10/faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + checksum: 10/12cb6d6310629e3048cadb003e1aca4d8c9bb5c67c3c321bafdd7e7a50155de081f78ea3e0ed92ecc75a9015e784f301efc8132383132f4f7904ad1ac529c562 languageName: node linkType: hard @@ -5942,11 +5942,11 @@ __metadata: linkType: hard "docusaurus-pushfeedback@npm:^1.0.0": - version: 1.0.3 - resolution: "docusaurus-pushfeedback@npm:1.0.3" + version: 1.0.5 + resolution: "docusaurus-pushfeedback@npm:1.0.5" peerDependencies: "@docusaurus/core": 3.x - checksum: 10/ee80ae0c1fc079b2c317cab86d83ba50cce18938a6ce0ac647aad25dc68fc0ad659e55c11e93d0e7c23270c503c3cb300111dfbdd04785ef7aaf6fb123b57eae + checksum: 10/5323af7f1c7b4590744ea9099cacb49087d98c48c11e2ed957ed744d6210a3d82fa0cc42ef0f011f25b0d08c2d0040065c8a2b641c7c9160532ceb51ad41475c languageName: node linkType: hard diff --git a/mkdocs.yml b/mkdocs.yml index 688ca1a078..eea5fc9c40 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -126,6 +126,9 @@ nav: - GitLab: - Locations: 'integrations/gitlab/locations.md' - Discovery: 'integrations/gitlab/discovery.md' + - Gitea: + - Locations: 'integrations/gitea/locations.md' + - Discovery: 'integrations/gitea/discovery.md' - Google GCS: - Locations: 'integrations/google-cloud-storage/locations.md' - LDAP: diff --git a/package.json b/package.json index fc773cb0d0..3a2ed93a88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.40.0-next.3", + "version": "1.41.0-next.0", "backstage": { "cli": { "new": { @@ -40,6 +40,7 @@ "postinstall": "husky || true", "lint": "backstage-cli repo lint --since origin/master", "lint:all": "backstage-cli repo lint", + "lint:circular-deps": "madge --circular .", "lint:docs": "node ./scripts/check-docs-quality", "lint:peer-deps": "backstage-repo-tools peer-deps", "lint:type-deps": "backstage-repo-tools type-deps", @@ -108,7 +109,8 @@ "csstype@npm:^3.0.2": "3.0.9", "csstype@npm:^3.1.2": "3.0.9", "csstype@npm:^3.1.3": "3.0.9", - "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch" + "jest-haste-map@^29.7.0": "patch:jest-haste-map@npm%3A29.7.0#./.yarn/patches/jest-haste-map-npm-29.7.0-e3be419eff.patch", + "GendocuPublicApis": "npm:gendocu-public-apis@^1.0.0" }, "dependencies": { "@backstage/errors": "workspace:^", @@ -122,6 +124,7 @@ "@backstage/codemods": "workspace:*", "@backstage/create-app": "workspace:*", "@backstage/e2e-test-utils": "workspace:*", + "@backstage/eslint-plugin": "workspace:*", "@backstage/repo-tools": "workspace:*", "@changesets/cli": "^2.14.0", "@octokit/rest": "^19.0.3", @@ -143,6 +146,7 @@ "fs-extra": "^11.2.0", "husky": "^9.0.0", "lint-staged": "^15.0.0", + "madge": "^8.0.0", "minimist": "^1.2.5", "node-gyp": "^10.0.0", "prettier": "^2.2.1", @@ -156,5 +160,22 @@ "packageManager": "yarn@4.8.1", "engines": { "node": "20 || 22" + }, + "madge": { + "fileExtensions": [ + "ts", + "tsx", + "js", + "jsx" + ], + "detectiveOptions": { + "ts": { + "skipTypeImports": true + }, + "tsx": { + "skipTypeImports": true + } + }, + "tsConfig": "./tsconfig.json" } } diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index d2689dc318..3319d20567 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,27 @@ # @backstage/app-defaults +## 1.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/theme@0.6.7-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/plugin-permission-react@0.4.35 + +## 1.6.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/core-plugin-api@1.10.8 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-permission-react@0.4.35 + ## 1.6.3-next.0 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 93baf003bf..8ddd62a6ba 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/app-defaults", - "version": "1.6.3-next.0", + "version": "1.6.4-next.0", "description": "Provides the default wiring of a Backstage App", "backstage": { "role": "web-library" diff --git a/packages/app-next-example-plugin/CHANGELOG.md b/packages/app-next-example-plugin/CHANGELOG.md index 7c8641ae87..f74cafd0bd 100644 --- a/packages/app-next-example-plugin/CHANGELOG.md +++ b/packages/app-next-example-plugin/CHANGELOG.md @@ -1,5 +1,21 @@ # app-next-example-plugin +## 0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + +## 0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.17.3 + - @backstage/frontend-plugin-api@0.10.3 + ## 0.0.24-next.1 ### Patch Changes diff --git a/packages/app-next-example-plugin/package.json b/packages/app-next-example-plugin/package.json index b6692df969..a63559a9f7 100644 --- a/packages/app-next-example-plugin/package.json +++ b/packages/app-next-example-plugin/package.json @@ -1,6 +1,6 @@ { "name": "app-next-example-plugin", - "version": "0.0.24-next.1", + "version": "0.0.25-next.0", "description": "Backstage internal example plugin", "backstage": { "role": "frontend-plugin", diff --git a/packages/app-next/CHANGELOG.md b/packages/app-next/CHANGELOG.md index 64f4c94f60..33e61bb967 100644 --- a/packages/app-next/CHANGELOG.md +++ b/packages/app-next/CHANGELOG.md @@ -1,5 +1,97 @@ # example-app-next +## 0.0.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-app@0.1.11-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.4-next.0 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/frontend-defaults@0.2.4-next.0 + - @backstage/frontend-plugin-api@0.10.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-app-visualizer@0.1.21-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## 0.0.24 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-app-visualizer@0.1.20 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-app@0.1.10 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-plugin-api@0.10.3 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/frontend-defaults@0.2.3 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-compat-api@0.4.3 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + ## 0.0.24-next.3 ### Patch Changes diff --git a/packages/app-next/package.json b/packages/app-next/package.json index eab318f7c1..ca5151a123 100644 --- a/packages/app-next/package.json +++ b/packages/app-next/package.json @@ -1,6 +1,6 @@ { "name": "example-app-next", - "version": "0.0.24-next.3", + "version": "0.0.25-next.0", "backstage": { "role": "frontend" }, diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index b71dba1a1c..87100e49ed 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,89 @@ # example-app +## 0.2.111-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.13.2-next.0 + - @backstage/plugin-catalog-graph@0.4.21-next.0 + - @backstage/canon@0.6.0-next.0 + - @backstage/plugin-scaffolder@1.32.1-next.0 + - @backstage/plugin-catalog-import@0.13.2-next.0 + - @backstage/integration-react@1.2.9-next.0 + - @backstage/theme@0.6.7-next.0 + - @backstage/cli@0.33.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.26-next.0 + - @backstage/plugin-catalog@1.31.1-next.0 + - @backstage/plugin-catalog-react@1.19.1-next.0 + - @backstage/app-defaults@1.6.4-next.0 + - @backstage/core-components@0.17.4-next.0 + - @backstage/plugin-home@0.8.10-next.0 + - @backstage/plugin-notifications@0.5.7-next.0 + - @backstage/plugin-scaffolder-react@1.17.1-next.0 + - @backstage/plugin-search-react@1.9.2-next.0 + - @backstage/plugin-signals@0.0.21-next.0 + - @backstage/plugin-techdocs-react@1.3.1-next.0 + - @backstage/plugin-user-settings@0.8.24-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.4-next.0 + - @backstage/plugin-api-docs@0.12.9-next.0 + - @backstage/plugin-auth-react@0.1.17-next.0 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-catalog-unprocessed-entities@0.2.19-next.0 + - @backstage/plugin-devtools@0.1.29-next.0 + - @backstage/plugin-kubernetes@0.12.9-next.0 + - @backstage/plugin-kubernetes-cluster@0.0.27-next.0 + - @backstage/plugin-org@0.6.41-next.0 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search@1.4.28-next.0 + - @backstage/plugin-search-common@1.2.18 + +## 0.2.110 + +### Patch Changes + +- Updated dependencies + - @backstage/canon@0.5.0 + - @backstage/core-components@0.17.3 + - @backstage/cli@0.33.0 + - @backstage/plugin-scaffolder-react@1.17.0 + - @backstage/plugin-scaffolder@1.32.0 + - @backstage/plugin-catalog-unprocessed-entities@0.2.18 + - @backstage/plugin-catalog-import@0.13.1 + - @backstage/plugin-catalog-graph@0.4.20 + - @backstage/plugin-notifications@0.5.6 + - @backstage/plugin-user-settings@0.8.23 + - @backstage/plugin-kubernetes@0.12.8 + - @backstage/plugin-api-docs@0.12.8 + - @backstage/plugin-devtools@0.1.28 + - @backstage/plugin-techdocs@1.13.0 + - @backstage/plugin-catalog@1.31.0 + - @backstage/plugin-signals@0.0.20 + - @backstage/plugin-search@1.4.27 + - @backstage/plugin-home@0.8.9 + - @backstage/plugin-org@0.6.40 + - @backstage/plugin-techdocs-module-addons-contrib@1.1.25 + - @backstage/core-plugin-api@1.10.8 + - @backstage/frontend-app-api@0.11.3 + - @backstage/plugin-catalog-react@1.19.0 + - @backstage/plugin-techdocs-react@1.3.0 + - @backstage/plugin-search-react@1.9.1 + - @backstage/app-defaults@1.6.3 + - @backstage/integration-react@1.2.8 + - @backstage/plugin-auth-react@0.1.16 + - @backstage/plugin-kubernetes-cluster@0.0.26 + - @backstage/catalog-model@1.7.4 + - @backstage/config@1.3.2 + - @backstage/core-app-api@1.17.1 + - @backstage/theme@0.6.6 + - @backstage/plugin-catalog-common@1.1.4 + - @backstage/plugin-permission-react@0.4.35 + - @backstage/plugin-search-common@1.2.18 + ## 0.2.110-next.3 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 43b3141754..7a79f0b445 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "example-app", - "version": "0.2.110-next.3", + "version": "0.2.111-next.0", "backstage": { "role": "frontend" }, diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 82bff8d26a..c590baad83 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/backend-app-api +## 1.2.4 + +### Patch Changes + +- bb9a501: Fixed a bug where occasionally the initialization order of multiple modules consuming a single extension point could happen in the wrong order. +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + ## 1.2.4-next.2 ### Patch Changes diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index 67222fc10a..12a7be3127 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-app-api", - "version": "1.2.4-next.2", + "version": "1.2.4", "description": "Core API used by Backstage backend apps", "backstage": { "role": "node-library" diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md index bf35f7b3ab..2e07955ed6 100644 --- a/packages/backend-defaults/CHANGELOG.md +++ b/packages/backend-defaults/CHANGELOG.md @@ -1,5 +1,75 @@ # @backstage/backend-defaults +## 0.11.1-next.0 + +### Patch Changes + +- ead925a: Add a standard `toString` on credentials objects +- e0189b8: UrlReader: Fix handling of access tokens for GitLab readURL requests +- d1e4a6d: Fixed bug where the GitLab user token and GitLab integration token were being merged together +- Updated dependencies + - @backstage/integration@1.17.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + +## 0.11.0 + +### Minor Changes + +- 3ccb7fc: Enhanced error handling in the auditor service factory to pass errors as objects. Aligned WinstonRootAuditorService with the default service factory's error handling. + +### Patch Changes + +- 1220cf8: Added new rate limit middleware to allow rate limiting requests to the backend + + If you are using the `configure` callback of the root HTTP router service and do NOT call `applyDefaults()` inside it, please see [the relevant changes](https://github.com/backstage/backstage/pull/28708/files#diff-86ad1b6a694dd250823aee39d410428dd837c9d9a04ca8c33bd1081fbe3f22af) that were made, to see if you want to apply them as well to your custom configuration. + Rate limiting can be turned on by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + window: 6s + incomingRequestLimit: 100 + ``` + + Plugin specific rate limiting can be configured by adding the following configuration to `app-config.yaml`: + + ```yaml + backend: + rateLimit: + global: false # This will disable the global rate limiting + plugin: + catalog: + window: 6s + incomingRequestLimit: 100 + ``` + +- c999c25: Added some default implementations for the experimental `ActionsService` and `ActionsRegistryService` under `/alpha` that allow registration of actions for a particular plugin. +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-dev-utils@0.1.5 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/integration@1.17.0 + - @backstage/integration-aws-node@0.1.16 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-node@0.10.1 + ## 0.11.0-next.2 ### Minor Changes diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index 1ef054a537..167a8935f9 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -790,6 +790,92 @@ export interface Config { headers?: { [name: string]: string }; }; + /** + * Rate limiting options. Defining this as `true` will enable rate limiting with default values. + */ + rateLimit?: + | true + | { + store?: + | { + type: 'redis'; + connection: string; + } + | { + type: 'memory'; + }; + /** + * Enable/disable global rate limiting. If this is disabled, plugin specific rate limiting must be + * used. + */ + global?: boolean; + /** + * Time frame in milliseconds or as human duration for which requests are checked/remembered. + * Defaults to one minute. + */ + window?: string | HumanDuration; + /** + * The maximum number of connections to allow during the `window` before rate limiting the client. + * Defaults to 5. + */ + incomingRequestLimit?: number; + /** + * Whether to pass requests in case of store failure. + * Defaults to false. + */ + passOnStoreError?: boolean; + /** + * List of allowed IP addresses that are not rate limited. + * Defaults to [127.0.0.1, 0:0:0:0:0:0:0:1, ::1]. + */ + ipAllowList?: string[]; + /** + * Skip rate limiting for requests that have been successful. + * Defaults to false. + */ + skipSuccessfulRequests?: boolean; + /** + * Skip rate limiting for requests that have failed. + * Defaults to false. + */ + skipFailedRequests?: boolean; + /** Plugin specific rate limiting configuration */ + plugin?: { + [pluginId: string]: { + /** + * Time frame in milliseconds or as human duration for which requests are checked/remembered. + * Defaults to one minute. + */ + window?: string | HumanDuration; + /** + * The maximum number of connections to allow during the `window` before rate limiting the client. + * Defaults to 5. + */ + incomingRequestLimit?: number; + /** + * Whether to pass requests in case of store failure. + * Defaults to false. + */ + passOnStoreError?: boolean; + /** + * List of allowed IP addresses that are not rate limited. + * Defaults to [127.0.0.1, 0:0:0:0:0:0:0:1, ::1]. + */ + ipAllowList?: string[]; + /** + * Skip rate limiting for requests that have been successful. + * Defaults to false. + */ + skipSuccessfulRequests?: boolean; + /** + * Skip rate limiting for requests that have failed. + * Defaults to false. + */ + skipFailedRequests?: boolean; + }; + }; + }; + /** * Configuration related to URL reading, used for example for reading catalog info * files, scaffolder templates, and techdocs content. diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 9ae78c119a..9a52bf8129 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-defaults", - "version": "0.11.0-next.2", + "version": "0.11.1-next.0", "description": "Backend defaults used by Backstage backend apps", "backstage": { "role": "node-library" @@ -20,8 +20,6 @@ "license": "Apache-2.0", "exports": { ".": "./src/index.ts", - "./actions": "./src/entrypoints/actions/index.ts", - "./actionsRegistry": "./src/entrypoints/actionsRegistry/index.ts", "./auditor": "./src/entrypoints/auditor/index.ts", "./auth": "./src/entrypoints/auth/index.ts", "./cache": "./src/entrypoints/cache/index.ts", @@ -41,18 +39,13 @@ "./scheduler": "./src/entrypoints/scheduler/index.ts", "./urlReader": "./src/entrypoints/urlReader/index.ts", "./userInfo": "./src/entrypoints/userInfo/index.ts", + "./alpha": "./src/alpha/index.ts", "./package.json": "./package.json" }, "main": "src/index.ts", "types": "src/index.ts", "typesVersions": { "*": { - "actions": [ - "src/entrypoints/actions/index.ts" - ], - "actionsRegistry": [ - "src/entrypoints/actionsRegistry/index.ts" - ], "auditor": [ "src/entrypoints/auditor/index.ts" ], @@ -110,6 +103,9 @@ "userInfo": [ "src/entrypoints/userInfo/index.ts" ], + "alpha": [ + "src/alpha/index.ts" + ], "package.json": [ "package.json" ] @@ -168,6 +164,7 @@ "cron": "^3.0.0", "express": "^4.17.1", "express-promise-router": "^4.1.0", + "express-rate-limit": "^7.5.0", "fs-extra": "^11.2.0", "git-url-parse": "^15.0.0", "helmet": "^6.0.0", @@ -187,6 +184,7 @@ "pg": "^8.11.3", "pg-connection-string": "^2.3.0", "pg-format": "^1.0.4", + "rate-limit-redis": "^4.2.0", "raw-body": "^2.4.1", "selfsigned": "^2.0.0", "tar": "^6.1.12", diff --git a/packages/backend-defaults/report-actions.api.md b/packages/backend-defaults/report-actions.api.md deleted file mode 100644 index 4c072af02a..0000000000 --- a/packages/backend-defaults/report-actions.api.md +++ /dev/null @@ -1,17 +0,0 @@ -## API Report File for "@backstage/backend-defaults" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { ActionsService } from '@backstage/backend-plugin-api'; -import { ServiceFactory } from '@backstage/backend-plugin-api'; - -// @public (undocumented) -export const actionsServiceFactory: ServiceFactory< - ActionsService, - 'plugin', - 'singleton' ->; - -// (No @packageDocumentation comment for this package) -``` diff --git a/packages/backend-defaults/report-actionsRegistry.api.md b/packages/backend-defaults/report-alpha.api.md similarity index 69% rename from packages/backend-defaults/report-actionsRegistry.api.md rename to packages/backend-defaults/report-alpha.api.md index d35bf4cef4..58277b5e1e 100644 --- a/packages/backend-defaults/report-actionsRegistry.api.md +++ b/packages/backend-defaults/report-alpha.api.md @@ -3,7 +3,8 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { ActionsRegistryService } from '@backstage/backend-plugin-api'; +import { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha'; +import { ActionsService } from '@backstage/backend-plugin-api/alpha'; import { ServiceFactory } from '@backstage/backend-plugin-api'; // @public (undocumented) @@ -13,5 +14,12 @@ export const actionsRegistryServiceFactory: ServiceFactory< 'singleton' >; +// @public (undocumented) +export const actionsServiceFactory: ServiceFactory< + ActionsService, + 'plugin', + 'singleton' +>; + // (No @packageDocumentation comment for this package) ``` diff --git a/packages/backend-defaults/report-rootHttpRouter.api.md b/packages/backend-defaults/report-rootHttpRouter.api.md index 826d592e8b..84424be39d 100644 --- a/packages/backend-defaults/report-rootHttpRouter.api.md +++ b/packages/backend-defaults/report-rootHttpRouter.api.md @@ -93,6 +93,7 @@ export class MiddlewareFactory { helmet(): RequestHandler; logging(): RequestHandler; notFound(): RequestHandler; + rateLimit(): RequestHandler; } // @public diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts index 032978c806..4b201fded3 100644 --- a/packages/backend-defaults/src/CreateBackend.ts +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -35,12 +35,12 @@ import { schedulerServiceFactory } from '@backstage/backend-defaults/scheduler'; import { urlReaderServiceFactory } from '@backstage/backend-defaults/urlReader'; import { userInfoServiceFactory } from '@backstage/backend-defaults/userInfo'; import { eventsServiceFactory } from '@backstage/plugin-events-node'; -import { actionsRegistryServiceFactory } from './entrypoints/actionsRegistry'; -import { actionsServiceFactory } from './entrypoints/actions'; - -export const defaultServiceFactories = [ +import { actionsRegistryServiceFactory, actionsServiceFactory, +} from '@backstage/backend-defaults/alpha'; + +export const defaultServiceFactories = [ auditorServiceFactory, authServiceFactory, cacheServiceFactory, @@ -61,6 +61,10 @@ export const defaultServiceFactories = [ userInfoServiceFactory, urlReaderServiceFactory, eventsServiceFactory, + + // alpha services + actionsRegistryServiceFactory, + actionsServiceFactory, ]; /** diff --git a/packages/backend-defaults/src/entrypoints/actions/DefaultActionsService.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/DefaultActionsService.ts similarity index 98% rename from packages/backend-defaults/src/entrypoints/actions/DefaultActionsService.ts rename to packages/backend-defaults/src/alpha/entrypoints/actions/DefaultActionsService.ts index 2421482f4c..d8847c2187 100644 --- a/packages/backend-defaults/src/entrypoints/actions/DefaultActionsService.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/actions/DefaultActionsService.ts @@ -14,8 +14,6 @@ * limitations under the License. */ import { - ActionsService, - ActionsServiceAction, AuthService, BackstageCredentials, DiscoveryService, @@ -24,6 +22,10 @@ import { } from '@backstage/backend-plugin-api'; import { ResponseError } from '@backstage/errors'; import { JsonObject } from '@backstage/types'; +import { + ActionsService, + ActionsServiceAction, +} from '@backstage/backend-plugin-api/alpha'; export class DefaultActionsService implements ActionsService { private constructor( diff --git a/packages/backend-defaults/src/entrypoints/actions/actionsServiceFactory.test.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.test.ts similarity index 93% rename from packages/backend-defaults/src/entrypoints/actions/actionsServiceFactory.test.ts rename to packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.test.ts index 7b7285c89a..af2fcb0c12 100644 --- a/packages/backend-defaults/src/entrypoints/actions/actionsServiceFactory.test.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.test.ts @@ -21,18 +21,20 @@ import { startTestBackend, } from '@backstage/backend-test-utils'; import { actionsRegistryServiceFactory } from '../actionsRegistry'; -import { httpRouterServiceFactory } from '../httpRouter'; +import { httpRouterServiceFactory } from '../../../entrypoints/httpRouter'; import { actionsServiceFactory } from './actionsServiceFactory'; import { setupServer } from 'msw/node'; import { rest } from 'msw'; import { - ActionsServiceAction, coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; import { json } from 'express'; import Router from 'express-promise-router'; import request from 'supertest'; +import { ActionsServiceAction } from '@backstage/backend-plugin-api/alpha'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; +import { actionsServiceRef } from '@backstage/backend-plugin-api/alpha'; const server = setupServer(); @@ -70,6 +72,11 @@ describe('actionsServiceFactory', () => { input: {}, output: {}, }, + attributes: { + destructive: false, + idempotent: false, + readOnly: false, + }, }; beforeEach(() => { @@ -196,7 +203,7 @@ describe('actionsServiceFactory', () => { pluginId: 'plugin-with-action', register({ registerInit }) { registerInit({ - deps: { actionsRegistry: coreServices.actionsRegistry }, + deps: { actionsRegistry: actionsRegistryServiceRef }, async init({ actionsRegistry }) { actionsRegistry.register({ name: 'with-validation', @@ -231,7 +238,7 @@ describe('actionsServiceFactory', () => { register({ registerInit }) { registerInit({ deps: { - actionsService: coreServices.actions, + actionsService: actionsServiceRef, router: coreServices.httpRouter, httpAuth: coreServices.httpAuth, }, @@ -306,6 +313,11 @@ describe('actionsServiceFactory', () => { type: 'object', }, }, + attributes: { + destructive: true, + idempotent: false, + readOnly: false, + }, title: 'Test', }, ], diff --git a/packages/backend-defaults/src/entrypoints/actions/actionsServiceFactory.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.ts similarity index 92% rename from packages/backend-defaults/src/entrypoints/actions/actionsServiceFactory.ts rename to packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.ts index 466cc02121..4325da7d13 100644 --- a/packages/backend-defaults/src/entrypoints/actions/actionsServiceFactory.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/actions/actionsServiceFactory.ts @@ -16,12 +16,13 @@ import { createServiceFactory } from '@backstage/backend-plugin-api'; import { coreServices } from '@backstage/backend-plugin-api'; import { DefaultActionsService } from './DefaultActionsService'; +import { actionsServiceRef } from '@backstage/backend-plugin-api/alpha'; /** * @public */ export const actionsServiceFactory = createServiceFactory({ - service: coreServices.actions, + service: actionsServiceRef, deps: { discovery: coreServices.discovery, config: coreServices.rootConfig, diff --git a/packages/backend-defaults/src/entrypoints/actions/index.ts b/packages/backend-defaults/src/alpha/entrypoints/actions/index.ts similarity index 100% rename from packages/backend-defaults/src/entrypoints/actions/index.ts rename to packages/backend-defaults/src/alpha/entrypoints/actions/index.ts diff --git a/packages/backend-defaults/src/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts similarity index 84% rename from packages/backend-defaults/src/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts rename to packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts index 17523a2ee5..2284935787 100644 --- a/packages/backend-defaults/src/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts @@ -15,8 +15,6 @@ */ import { - ActionsRegistryActionOptions, - ActionsRegistryService, AuthService, HttpAuthService, LoggerService, @@ -24,8 +22,12 @@ import { } from '@backstage/backend-plugin-api'; import PromiseRouter from 'express-promise-router'; import { Router, json } from 'express'; -import { z, ZodType } from 'zod'; +import { z, AnyZodObject } from 'zod'; import zodToJsonSchema from 'zod-to-json-schema'; +import { + ActionsRegistryActionOptions, + ActionsRegistryService, +} from '@backstage/backend-plugin-api/alpha'; import { ForwardedError, InputError, @@ -67,13 +69,20 @@ export class DefaultActionsRegistryService implements ActionsRegistryService { actions: Array.from(this.actions.entries()).map(([id, action]) => ({ id, ...action, + attributes: { + // Inspired by the @modelcontextprotocol/sdk defaults for the hints. + // https://github.com/modelcontextprotocol/typescript-sdk/blob/dd69efa1de8646bb6b195ff8d5f52e13739f4550/src/types.ts#L777-L812 + destructive: action.attributes?.destructive ?? true, + idempotent: action.attributes?.idempotent ?? false, + readOnly: action.attributes?.readOnly ?? false, + }, schema: { input: action.schema?.input ? zodToJsonSchema(action.schema.input(z)) - : zodToJsonSchema(z.any()), + : zodToJsonSchema(z.object({})), output: action.schema?.output ? zodToJsonSchema(action.schema.output(z)) - : zodToJsonSchema(z.any()), + : zodToJsonSchema(z.object({})), }, })), }); @@ -142,9 +151,10 @@ export class DefaultActionsRegistryService implements ActionsRegistryService { return router; } - register( - options: ActionsRegistryActionOptions, - ): void { + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >(options: ActionsRegistryActionOptions): void { const id = `${this.metadata.getId()}:${options.name}`; if (this.actions.has(id)) { diff --git a/packages/backend-defaults/src/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts similarity index 76% rename from packages/backend-defaults/src/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts rename to packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts index 5d47ff055d..79c103c284 100644 --- a/packages/backend-defaults/src/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.test.ts @@ -13,19 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { - coreServices, - createBackendPlugin, -} from '@backstage/backend-plugin-api'; +import { createBackendPlugin } from '@backstage/backend-plugin-api'; import { mockCredentials, mockServices, startTestBackend, } from '@backstage/backend-test-utils'; -import { httpRouterServiceFactory } from '../httpRouter'; +import { httpRouterServiceFactory } from '../../../entrypoints/httpRouter'; import request from 'supertest'; import { actionsRegistryServiceFactory } from './actionsRegistryServiceFactory'; import { InputError } from '@backstage/errors'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; describe('actionsRegistryServiceFactory', () => { const defaultServices = [ @@ -43,7 +41,7 @@ describe('actionsRegistryServiceFactory', () => { register(reg) { reg.registerInit({ deps: { - actionsRegistry: coreServices.actionsRegistry, + actionsRegistry: actionsRegistryServiceRef, }, async init({ actionsRegistry }) { actionsRegistry.register({ @@ -80,7 +78,7 @@ describe('actionsRegistryServiceFactory', () => { register(reg) { reg.registerInit({ deps: { - actionsRegistry: coreServices.actionsRegistry, + actionsRegistry: actionsRegistryServiceRef, }, async init({ actionsRegistry }) { actionsRegistry.register({ @@ -118,7 +116,7 @@ describe('actionsRegistryServiceFactory', () => { register(reg) { reg.registerInit({ deps: { - actionsRegistry: coreServices.actionsRegistry, + actionsRegistry: actionsRegistryServiceRef, }, async init({ actionsRegistry }) { actionsRegistry.register({ @@ -181,13 +179,13 @@ describe('actionsRegistryServiceFactory', () => { }); }); - it('should allow registering of actions with no schema', async () => { + it('should set default attributes', async () => { const pluginSubject = createBackendPlugin({ pluginId: 'my-plugin', register(reg) { reg.registerInit({ deps: { - actionsRegistry: coreServices.actionsRegistry, + actionsRegistry: actionsRegistryServiceRef, }, async init({ actionsRegistry }) { actionsRegistry.register({ @@ -195,9 +193,115 @@ describe('actionsRegistryServiceFactory', () => { title: 'Test', description: 'Test', schema: { + input: z => z.object({}), + output: z => z.object({}), + }, + action: async () => ({ output: { ok: true } }), + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server).get( + '/api/my-plugin/.backstage/actions/v1/actions', + ); + + expect(status).toBe(200); + + expect(body).toMatchObject({ + actions: [ + { + name: 'test', + attributes: { + destructive: true, + idempotent: false, + readOnly: false, + }, + }, + ], + }); + }); + + it('should allow setting attributes', async () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + attributes: { + destructive: false, + idempotent: true, + readOnly: true, + }, + schema: { + input: z => z.object({}), + output: z => z.object({}), + }, + action: async () => ({ output: { ok: true } }), + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginSubject, ...defaultServices], + }); + + const { body, status } = await request(server).get( + '/api/my-plugin/.backstage/actions/v1/actions', + ); + + expect(status).toBe(200); + + expect(body).toMatchObject({ + actions: [ + { + name: 'test', + title: 'Test', + description: 'Test', + attributes: { + destructive: false, + idempotent: true, + readOnly: true, + }, + }, + ], + }); + }); + + it('should forces registration of input and output schema as objects', async () => { + const pluginSubject = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + // @ts-expect-error - z.undefined is not a valid schema input: z => z.undefined(), + // @ts-expect-error - z.string is not a valid schema output: z => z.string(), }, + // @ts-expect-error - output is not a valid, needs to be an object action: async () => ({ output: 'ok' }), }); }, @@ -243,7 +347,7 @@ describe('actionsRegistryServiceFactory', () => { register(reg) { reg.registerInit({ deps: { - actionsRegistry: coreServices.actionsRegistry, + actionsRegistry: actionsRegistryServiceRef, }, async init({ actionsRegistry }) { actionsRegistry.register({ diff --git a/packages/backend-defaults/src/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts similarity index 92% rename from packages/backend-defaults/src/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts rename to packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts index 85515a6046..8c19b8148c 100644 --- a/packages/backend-defaults/src/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts +++ b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/actionsRegistryServiceFactory.ts @@ -19,12 +19,13 @@ import { createServiceFactory, } from '@backstage/backend-plugin-api'; import { DefaultActionsRegistryService } from './DefaultActionsRegistryService'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; /** * @public */ export const actionsRegistryServiceFactory = createServiceFactory({ - service: coreServices.actionsRegistry, + service: actionsRegistryServiceRef, deps: { metadata: coreServices.pluginMetadata, httpRouter: coreServices.httpRouter, diff --git a/packages/backend-defaults/src/entrypoints/actionsRegistry/index.ts b/packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/index.ts similarity index 100% rename from packages/backend-defaults/src/entrypoints/actionsRegistry/index.ts rename to packages/backend-defaults/src/alpha/entrypoints/actionsRegistry/index.ts diff --git a/packages/backend-defaults/src/alpha/index.ts b/packages/backend-defaults/src/alpha/index.ts new file mode 100644 index 0000000000..13bb439acd --- /dev/null +++ b/packages/backend-defaults/src/alpha/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { actionsRegistryServiceFactory } from './entrypoints/actionsRegistry'; +export { actionsServiceFactory } from './entrypoints/actions'; diff --git a/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts b/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts index 8454aa3ecc..fdc6e26c3a 100644 --- a/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts +++ b/packages/backend-defaults/src/entrypoints/auth/helpers.test.ts @@ -42,6 +42,23 @@ describe('credentials', () => { }, }); + expect( + createCredentialsWithUserPrincipal( + 'user:default/mock', + 'my-token', + undefined, + 'my-actor', + ), + ).toEqual({ + $$type: '@backstage/BackstageCredentials', + version: 'v1', + principal: { + type: 'user', + userEntityRef: 'user:default/mock', + actor: { type: 'service', subject: 'my-actor' }, + }, + }); + expect(createCredentialsWithNonePrincipal()).toEqual({ $$type: '@backstage/BackstageCredentials', version: 'v1', @@ -64,4 +81,63 @@ describe('credentials', () => { ), ).not.toMatch(/my-token/); }); + + it('should have a serializable form both as strings and as JSON', () => { + const simpleService = createCredentialsWithServicePrincipal('my-service'); + expect(String(simpleService)).toMatchInlineSnapshot( + `"backstageCredentials{servicePrincipal{my-service}}"`, + ); + expect(JSON.stringify(simpleService)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"service","subject":"my-service"}}"`, + ); + + const serviceWithAccessRestrictions = createCredentialsWithServicePrincipal( + 'my-service', + undefined, + { + permissionNames: ['perm'], + permissionAttributes: { + action: ['read'], + }, + }, + ); + expect(String(serviceWithAccessRestrictions)).toMatchInlineSnapshot( + `"backstageCredentials{servicePrincipal{my-service,accessRestrictions=cXWOJgUirHkHNZIowUi/YO5nwEwhTicC38iXi2XTYCk}}"`, + ); + expect(JSON.stringify(serviceWithAccessRestrictions)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"service","subject":"my-service","accessRestrictions":{"permissionNames":["perm"],"permissionAttributes":{"action":["read"]}}}}"`, + ); + + const simpleUser = createCredentialsWithUserPrincipal( + 'user:default/mock', + 'my-token', + ); + expect(String(simpleUser)).toMatchInlineSnapshot( + `"backstageCredentials{userPrincipal{user:default/mock}}"`, + ); + expect(JSON.stringify(simpleUser)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"user","userEntityRef":"user:default/mock"}}"`, + ); + + const userWithActor = createCredentialsWithUserPrincipal( + 'user:default/mock', + 'my-token', + undefined, + 'my-actor', + ); + expect(String(userWithActor)).toMatchInlineSnapshot( + `"backstageCredentials{userPrincipal{user:default/mock,actor={servicePrincipal{my-actor}}}}"`, + ); + expect(JSON.stringify(userWithActor)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"user","userEntityRef":"user:default/mock","actor":{"type":"service","subject":"my-actor"}}}"`, + ); + + const none = createCredentialsWithNonePrincipal(); + expect(String(none)).toMatchInlineSnapshot( + `"backstageCredentials{nonePrincipal}"`, + ); + expect(JSON.stringify(none)).toMatchInlineSnapshot( + `"{"$$type":"@backstage/BackstageCredentials","version":"v1","principal":{"type":"none"}}"`, + ); + }); }); diff --git a/packages/backend-defaults/src/entrypoints/auth/helpers.ts b/packages/backend-defaults/src/entrypoints/auth/helpers.ts index 58e2bcff74..02840112a9 100644 --- a/packages/backend-defaults/src/entrypoints/auth/helpers.ts +++ b/packages/backend-defaults/src/entrypoints/auth/helpers.ts @@ -22,29 +22,34 @@ import { BackstageUserPrincipal, } from '@backstage/backend-plugin-api'; import { InternalBackstageCredentials } from './types'; +import { createHash } from 'crypto'; export function createCredentialsWithServicePrincipal( sub: string, token?: string, accessRestrictions?: BackstagePrincipalAccessRestrictions, ): InternalBackstageCredentials { - return Object.defineProperty( - { - $$type: '@backstage/BackstageCredentials', - version: 'v1', - principal: { - type: 'service', - subject: sub, - accessRestrictions, - }, - }, - 'token', - { + const principal = createServicePrincipal(sub, accessRestrictions); + const result = { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + principal, + } as const; + Object.defineProperties(result, { + token: { enumerable: false, configurable: true, + writable: true, value: token, }, - ); + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `backstageCredentials{${principal}}`, + }, + }); + return result; } export function createCredentialsWithUserPrincipal( @@ -53,36 +58,49 @@ export function createCredentialsWithUserPrincipal( expiresAt?: Date, actor?: string, ): InternalBackstageCredentials { - return Object.defineProperty( - { - $$type: '@backstage/BackstageCredentials', - version: 'v1', - expiresAt, - principal: { - type: 'user', - userEntityRef: sub, - ...(actor && { - actor: { type: 'service', subject: actor }, - }), - }, - }, - 'token', - { + const principal = createUserPrincipal( + sub, + actor ? createServicePrincipal(actor) : undefined, + ); + const result = { + $$type: '@backstage/BackstageCredentials', + version: 'v1', + expiresAt, + principal, + } as const; + Object.defineProperties(result, { + token: { enumerable: false, configurable: true, + writable: true, value: token, }, - ); + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `backstageCredentials{${principal}}`, + }, + }); + return result; } export function createCredentialsWithNonePrincipal(): InternalBackstageCredentials { - return { + const principal = createNonePrincipal(); + const result = { $$type: '@backstage/BackstageCredentials', version: 'v1', - principal: { - type: 'none', + principal, + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `backstageCredentials{${principal}}`, }, - }; + }); + return result; } export function toInternalBackstageCredentials( @@ -106,3 +124,74 @@ export function toInternalBackstageCredentials( return internalCredentials; } + +function createServicePrincipal( + sub: string, + accessRestrictions?: BackstagePrincipalAccessRestrictions, +): BackstageServicePrincipal { + const result = { + type: 'service', + subject: sub, + accessRestrictions, + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => { + let parts = sub; + if (accessRestrictions) { + const hash = createHash('sha256') + .update(JSON.stringify(accessRestrictions)) + .digest('base64') + .replace(/=+$/, ''); + parts += `,accessRestrictions=${hash}`; + } + return `servicePrincipal{${parts}}`; + }, + }, + }); + return result; +} + +function createUserPrincipal( + userEntityRef: string, + actor?: BackstageServicePrincipal, +): BackstageUserPrincipal { + const result = { + type: 'user', + userEntityRef, + actor, + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => { + let parts = userEntityRef; + if (actor) { + parts += `,actor={${actor}}`; + } + return `userPrincipal{${parts}}`; + }, + }, + }); + return result; +} + +function createNonePrincipal(): BackstageNonePrincipal { + const result = { + type: 'none', + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => 'nonePrincipal', + }, + }); + return result; +} diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/http/createRateLimitMiddleware.ts b/packages/backend-defaults/src/entrypoints/httpRouter/http/createRateLimitMiddleware.ts new file mode 100644 index 0000000000..b139b212d2 --- /dev/null +++ b/packages/backend-defaults/src/entrypoints/httpRouter/http/createRateLimitMiddleware.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { NextFunction, Request, Response } from 'express'; +import { RateLimitStoreFactory } from '../../../lib/RateLimitStoreFactory.ts'; +import { Config } from '@backstage/config'; +import { rateLimitMiddleware } from '../../../lib/rateLimitMiddleware.ts'; + +export const createRateLimitMiddleware = (options: { + pluginId: string; + config: Config; +}) => { + const { pluginId, config } = options; + const configKey = `backend.rateLimit.plugin.${pluginId}`; + const enabled = config.has(configKey); + if (!enabled) { + return (_req: Request, _res: Response, next: NextFunction) => { + next(); + }; + } + + const rateLimitOptions = config.getConfig(configKey); + + return rateLimitMiddleware({ + store: RateLimitStoreFactory.create({ config, prefix: pluginId }), + config: rateLimitOptions, + }); +}; diff --git a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts index 1f2b989018..0fc70a07f0 100644 --- a/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/httpRouter/httpRouterServiceFactory.ts @@ -22,12 +22,13 @@ import { HttpRouterServiceAuthPolicy, } from '@backstage/backend-plugin-api'; import { - createLifecycleMiddleware, + createAuthIntegrationRouter, createCookieAuthRefreshMiddleware, createCredentialsBarrier, - createAuthIntegrationRouter, + createLifecycleMiddleware, } from './http'; import { MiddlewareFactory } from '../rootHttpRouter'; +import { createRateLimitMiddleware } from './http/createRateLimitMiddleware.ts'; /** * HTTP route registration for plugins. @@ -61,6 +62,8 @@ export const httpRouterServiceFactory = createServiceFactory({ }) { const router = PromiseRouter(); + router.use(createRateLimitMiddleware({ pluginId: plugin.getId(), config })); + rootHttpRouter.use(`/api/${plugin.getId()}`, router); const credentialsBarrier = createCredentialsBarrier({ diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts index 1ff9bd15d1..80a10fe0eb 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts @@ -15,15 +15,15 @@ */ import { - RootConfigService, LoggerService, + RootConfigService, } from '@backstage/backend-plugin-api'; import { - Request, - Response, ErrorRequestHandler, NextFunction, + Request, RequestHandler, + Response, } from 'express'; import cors from 'cors'; import helmet from 'helmet'; @@ -37,12 +37,14 @@ import { InputError, NotAllowedError, NotFoundError, + NotImplementedError, NotModifiedError, - ServiceUnavailableError, serializeError, + ServiceUnavailableError, } from '@backstage/errors'; -import { NotImplementedError } from '@backstage/errors'; import { applyInternalErrorFilter } from './applyInternalErrorFilter'; +import { RateLimitStoreFactory } from '../../../lib/RateLimitStoreFactory.ts'; +import { rateLimitMiddleware } from '../../../lib/rateLimitMiddleware.ts'; type LogMeta = { date: string; @@ -227,6 +229,47 @@ export class MiddlewareFactory { return cors(readCorsOptions(this.#config.getOptionalConfig('backend'))); } + /** + * Returns a middleware that implements rate limiting. + * + * @remarks + * + * Rate limiting is a common technique to prevent abuse of APIs. This middleware is + * configured using the config key `backend.rateLimit`. + * + * @returns An Express request handler + */ + rateLimit(): RequestHandler { + const enabled = this.#config.has('backend.rateLimit'); + if (!enabled) { + return (_req: Request, _res: Response, next: NextFunction) => { + next(); + }; + } + + const useDefaults = this.#config.getOptional('backend.rateLimit') === true; + const rateLimitOptions = useDefaults + ? undefined + : this.#config.getOptionalConfig('backend.rateLimit'); + + // Global rate limiting disabled + if ( + rateLimitOptions && + rateLimitOptions.getOptionalBoolean('global') === false + ) { + return (_req: Request, _res: Response, next: NextFunction) => { + next(); + }; + } + + return rateLimitMiddleware({ + store: useDefaults + ? undefined + : RateLimitStoreFactory.create({ config: this.#config }), + config: rateLimitOptions, + }); + } + /** * Express middleware to handle errors during request processing. * diff --git a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts index da7fcfe3f9..3b50515742 100644 --- a/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts +++ b/packages/backend-defaults/src/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.ts @@ -15,13 +15,13 @@ */ import { - RootConfigService, coreServices, createServiceFactory, LifecycleService, LoggerService, + RootConfigService, } from '@backstage/backend-plugin-api'; -import express, { RequestHandler, Express } from 'express'; +import express, { Express, RequestHandler } from 'express'; import type { Server } from 'node:http'; import { createHttpServer, @@ -121,6 +121,7 @@ const rootHttpRouterServiceFactoryWithOptions = ( app.use(middleware.cors()); app.use(middleware.compression()); app.use(middleware.logging()); + app.use(middleware.rateLimit()); app.use(healthRouter); app.use(routes); app.use(middleware.notFound()); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts index b7ccf165ad..337325f6f8 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.test.ts @@ -108,9 +108,6 @@ describe('GitlabUrlReader', () => { config: createConfig(), response: expect.objectContaining({ url: 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', - headers: expect.objectContaining({ - 'private-token': '', - }), }), }, { @@ -119,7 +116,7 @@ describe('GitlabUrlReader', () => { response: expect.objectContaining({ url: 'https://gitlab.example.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', headers: expect.objectContaining({ - 'private-token': '0123456789', + authorization: 'Bearer 0123456789', }), }), }, @@ -252,10 +249,10 @@ describe('GitlabUrlReader', () => { it('should return the file when using a user token', async () => { worker.use( rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -571,10 +568,10 @@ describe('GitlabUrlReader', () => { it('should return the file when using a user token', async () => { worker.use( rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -737,10 +734,10 @@ describe('GitlabUrlReader', () => { (_, res, ctx) => res(ctx.status(200), ctx.json({ id: 12345 })), ), rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -798,10 +795,10 @@ describe('GitlabUrlReader', () => { (_, res, ctx) => res(ctx.status(404)), ), rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); @@ -857,21 +854,19 @@ describe('GitlabUrlReader', () => { beforeEach(() => { worker.use( rest.get('*/api/v4/projects/group%2Fproject', (req, res, ctx) => { - // the private-token header must be included on API calls - if (req.headers.get('private-token') !== 'gl-dummy-token') { + if (req.headers.get('authorization') !== 'Bearer gl-dummy-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); }), rest.get('*/api/v4/projects/user%2Fproject', (req, res, ctx) => { - // the private-token header must be included on API calls - if (req.headers.get('private-token') !== 'gl-user-token') { + if (req.headers.get('authorization') !== 'Bearer gl-user-token') { return res( - ctx.status(403), - ctx.json({ message: 'Not Authorized' }), + ctx.status(401), + ctx.json({ message: '401 Unauthorized' }), ); } return res(ctx.status(200), ctx.json({ id: 12345 })); diff --git a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts index 3e5497a307..11746fef0d 100644 --- a/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts +++ b/packages/backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader.ts @@ -340,10 +340,7 @@ export class GitlabUrlReader implements UrlReaderService { ); } // Default to the old behavior of assuming the url is for a file - return getGitLabFileFetchUrl(target, { - ...this.integration.config, - ...(token && { token }), - }); + return getGitLabFileFetchUrl(target, this.integration.config, token); } // convert urls of the form: @@ -398,6 +395,12 @@ export class GitlabUrlReader implements UrlReaderService { ); const data = await result.json(); if (!result.ok) { + if (result.status === 401) { + throw new Error( + 'GitLab Error: 401 - Unauthorized. The access token used is either expired, or does not have permission to read the project', + ); + } + throw new Error(`Gitlab error: ${data.error}, ${data.error_description}`); } return Number(data.id); diff --git a/packages/backend-defaults/src/lib/RateLimitStoreFactory.test.ts b/packages/backend-defaults/src/lib/RateLimitStoreFactory.test.ts new file mode 100644 index 0000000000..684c204cb8 --- /dev/null +++ b/packages/backend-defaults/src/lib/RateLimitStoreFactory.test.ts @@ -0,0 +1,68 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { mockServices } from '@backstage/backend-test-utils'; +import { RateLimitStoreFactory } from './RateLimitStoreFactory.ts'; +import { RedisStore } from 'rate-limit-redis'; + +jest.mock('@keyv/redis', () => { + const Actual = jest.requireActual('@keyv/redis'); + return { + ...Actual, + __esModule: true, + default: jest.fn(() => { + return { + getClient: jest.fn(() => ({ + sendCommand: jest.fn().mockReturnValue('mock'), + })), + }; + }), + }; +}); + +describe('CacheRateLimitStoreFactory', () => { + afterEach(jest.clearAllMocks); + + it('should return undefined store with auto configuration if redis is not available', () => { + const config = mockServices.rootConfig({ + data: { + backend: { + rateLimit: { + store: undefined, + }, + }, + }, + }); + const store = RateLimitStoreFactory.create({ config }); + expect(store).toBeUndefined(); + }); + + it('should return redis store if configured explicitly', async () => { + const config = mockServices.rootConfig({ + data: { + backend: { + rateLimit: { + store: { + type: 'redis', + connection: 'redis://localhost:6379', + }, + }, + }, + }, + }); + const store = RateLimitStoreFactory.create({ config }); + expect(store).toBeInstanceOf(RedisStore); + }); +}); diff --git a/packages/backend-defaults/src/lib/RateLimitStoreFactory.ts b/packages/backend-defaults/src/lib/RateLimitStoreFactory.ts new file mode 100644 index 0000000000..9df6f03225 --- /dev/null +++ b/packages/backend-defaults/src/lib/RateLimitStoreFactory.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Config } from '@backstage/config'; +import type { Store } from 'express-rate-limit'; +import { RedisStore } from 'rate-limit-redis'; + +/** + * Creates a store for `express-rate-limit` based on the configuration. + * + * @internal + */ +export class RateLimitStoreFactory { + static create(options: { + config: Config; + prefix?: string; + }): Store | undefined { + const { config, prefix } = options; + const store = config.getOptionalConfig('backend.rateLimit.store'); + if (!store) { + return undefined; + } + const type = store.getString('type'); + switch (type) { + case 'redis': + return this.redis({ store, prefix }); + case 'memory': + default: + return undefined; + } + } + + private static redis(options: { store: Config; prefix?: string }): Store { + const { store, prefix } = options; + const connectionString = store.getString('connection'); + const KeyvRedis = require('@keyv/redis').default; + const keyv = new KeyvRedis(connectionString); + return new RedisStore({ + prefix, + sendCommand: async (...args: string[]) => { + const client = await keyv.getClient(); + return client.sendCommand(args); + }, + }); + } +} diff --git a/packages/backend-defaults/src/lib/rateLimitMiddleware.ts b/packages/backend-defaults/src/lib/rateLimitMiddleware.ts new file mode 100644 index 0000000000..57163b5908 --- /dev/null +++ b/packages/backend-defaults/src/lib/rateLimitMiddleware.ts @@ -0,0 +1,81 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { RequestHandler } from 'express'; +import { rateLimit, Store } from 'express-rate-limit'; +import { Config, readDurationFromConfig } from '@backstage/config'; +import { durationToMilliseconds } from '@backstage/types'; + +export const rateLimitMiddleware = (options: { + store?: Store; + config?: Config; +}): RequestHandler => { + const { store, config } = options; + let windowMs: number = 60000; + if (config && config.has('window')) { + const windowDuration = readDurationFromConfig(config, { + key: 'window', + }); + windowMs = durationToMilliseconds(windowDuration); + } + const limit = config?.getOptionalNumber('incomingRequestLimit'); + const ipAllowList = config?.getOptionalStringArray('ipAllowList') ?? [ + '127.0.0.1', + '0:0:0:0:0:0:0:1', + '::1', + ]; + const skipSuccessfulRequests = config?.getOptionalBoolean( + 'skipSuccessfulRequests', + ); + const skipFailedRequests = config?.getOptionalBoolean('skipFailedRequests'); + const passOnStoreError = config?.getOptionalBoolean('passOnStoreError'); + + return rateLimit({ + windowMs, + limit, + skipSuccessfulRequests, + message: { + error: { + name: 'Error', + message: `Too many requests, please try again later`, + }, + response: { + statusCode: 429, + }, + }, + statusCode: 429, + skipFailedRequests, + passOnStoreError: passOnStoreError, + keyGenerator(req, _res): string { + if (!req.ip) { + return req.socket.remoteAddress!; + } + return req.ip; + }, + skip: (req, _res) => { + return ( + Boolean(req.ip && ipAllowList.includes(req.ip)) || + Boolean( + req.socket.remoteAddress && + ipAllowList.includes(req.socket.remoteAddress), + ) + ); + }, + validate: { + trustProxy: false, + }, + store, + }); +}; diff --git a/packages/backend-dynamic-feature-service/CHANGELOG.md b/packages/backend-dynamic-feature-service/CHANGELOG.md index 9dd24cf091..344bbaaf9d 100644 --- a/packages/backend-dynamic-feature-service/CHANGELOG.md +++ b/packages/backend-dynamic-feature-service/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/backend-dynamic-feature-service +## 0.7.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-node@0.9.1-next.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/cli-node@0.2.13 + - @backstage/config-loader@1.10.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-search-common@1.2.18 + +## 0.7.1 + +### Patch Changes + +- c83cd8b: Fixed some circular or otherwise unclear imports +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-node@0.9.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/backend-openapi-utils@0.5.4 + - @backstage/cli-common@0.1.15 + - @backstage/cli-node@0.2.13 + - @backstage/config@1.3.2 + - @backstage/config-loader@1.10.1 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-app-node@0.1.34 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-search-common@1.2.18 + ## 0.7.1-next.2 ### Patch Changes diff --git a/packages/backend-dynamic-feature-service/package.json b/packages/backend-dynamic-feature-service/package.json index b5ddeca71d..926c3d21f5 100644 --- a/packages/backend-dynamic-feature-service/package.json +++ b/packages/backend-dynamic-feature-service/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-dynamic-feature-service", - "version": "0.7.1-next.2", + "version": "0.7.2-next.0", "description": "Backstage dynamic feature service", "backstage": { "role": "node-library" diff --git a/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts b/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts index 9f1ef68a77..cf48bcfc95 100644 --- a/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts +++ b/packages/backend-dynamic-feature-service/src/schema/openapi/generated/router.ts @@ -18,7 +18,7 @@ // * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. * // ****************************************************************** import { createValidatedOpenApiRouterFromGeneratedEndpointMap } from '@backstage/backend-openapi-utils'; -import { EndpointMap } from './'; +import { EndpointMap } from './apis'; export const spec = { openapi: '3.0.3', diff --git a/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts b/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts index f1a245b1ac..11c2838691 100644 --- a/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts +++ b/packages/backend-dynamic-feature-service/src/server/frontendRemotesServer.ts @@ -19,7 +19,7 @@ import { createServiceRef, } from '@backstage/backend-plugin-api'; import { createRouter } from './router'; -import { dynamicPluginsServiceRef } from '@backstage/backend-dynamic-feature-service'; +import { dynamicPluginsServiceRef } from '../manager'; import { spec } from '../schema/openapi'; import { ManifestFileName } from '@module-federation/sdk'; import { RemoteInfo } from '../schema/openapi/generated/models'; diff --git a/packages/backend-dynamic-feature-service/src/server/router.ts b/packages/backend-dynamic-feature-service/src/server/router.ts index 61c97797e7..7c533b6c58 100644 --- a/packages/backend-dynamic-feature-service/src/server/router.ts +++ b/packages/backend-dynamic-feature-service/src/server/router.ts @@ -20,7 +20,7 @@ import { } from '@backstage/backend-plugin-api'; import express from 'express'; import { createOpenApiRouter, spec } from '../schema/openapi'; -import { DynamicPluginProvider } from '@backstage/backend-dynamic-feature-service'; +import { DynamicPluginProvider } from '../manager'; import * as fs from 'fs'; import * as path from 'path'; import * as url from 'url'; diff --git a/packages/backend-openapi-utils/CHANGELOG.md b/packages/backend-openapi-utils/CHANGELOG.md index bfdc32df2e..1e1117b448 100644 --- a/packages/backend-openapi-utils/CHANGELOG.md +++ b/packages/backend-openapi-utils/CHANGELOG.md @@ -1,5 +1,14 @@ # @backstage/backend-openapi-utils +## 0.5.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@1.4.0 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + ## 0.5.4-next.1 ### Patch Changes diff --git a/packages/backend-openapi-utils/package.json b/packages/backend-openapi-utils/package.json index d4b17a4e61..5bacdc4709 100644 --- a/packages/backend-openapi-utils/package.json +++ b/packages/backend-openapi-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-openapi-utils", - "version": "0.5.4-next.1", + "version": "0.5.4", "description": "OpenAPI typescript support.", "backstage": { "role": "node-library" diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 3aea27d1de..c3f0dffa3e 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/backend-plugin-api +## 1.4.0 + +### Minor Changes + +- 664c07a: Added `actionsRegistry` and `actions` experimental services to `/alpha` to allow registration of distributed actions from plugins, and the ability to invoke these actions. You can use these services by including them like the following: + + ```ts + import { + actionsRegistryServiceRef, + actionsServiceRef, + } from '@backstage/backend-plugin-api/alpha'; + + createBackendPlugin({ + pluginId: 'test-plugin', + register({ registerInit }) { + registerInit({ + deps: { + actions: actionsServiceRef, + actionsRegistry: actionsRegistryServiceRef, + }, + async init({ actions, actionsRegistry }) { + actionsRegistry.register({ + ..., + }); + + await actions.invoke(...); + }, + }); + }, + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-auth-node@0.6.4 + - @backstage/cli-common@0.1.15 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + ## 1.4.0-next.1 ### Patch Changes diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 52c1c6a66a..61228fd228 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-plugin-api", - "version": "1.4.0-next.1", + "version": "1.4.0", "description": "Core API used by Backstage backend plugins", "backstage": { "role": "node-library" @@ -20,7 +20,7 @@ "license": "Apache-2.0", "exports": { ".": "./src/index.ts", - "./alpha": "./src/alpha.ts", + "./alpha": "./src/alpha/index.ts", "./testUtils": "./src/testUtils.ts", "./package.json": "./package.json" }, @@ -29,7 +29,7 @@ "typesVersions": { "*": { "alpha": [ - "src/alpha.ts" + "src/alpha/index.ts" ], "testUtils": [ "src/testUtils.ts" diff --git a/packages/backend-plugin-api/report-alpha.api.md b/packages/backend-plugin-api/report-alpha.api.md index d485e2132e..9be7a29ed5 100644 --- a/packages/backend-plugin-api/report-alpha.api.md +++ b/packages/backend-plugin-api/report-alpha.api.md @@ -3,7 +3,105 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { AnyZodObject } from 'zod'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { JSONSchema7 } from 'json-schema'; +import { JsonValue } from '@backstage/types'; +import { LoggerService } from '@backstage/backend-plugin-api'; import { ServiceRef } from '@backstage/backend-plugin-api'; +import { z } from 'zod'; + +// @alpha (undocumented) +export type ActionsRegistryActionContext = { + input: z.infer; + logger: LoggerService; + credentials: BackstageCredentials; +}; + +// @alpha (undocumented) +export type ActionsRegistryActionOptions< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, +> = { + name: string; + title: string; + description: string; + schema: { + input: (zod: typeof z) => TInputSchema; + output: (zod: typeof z) => TOutputSchema; + }; + attributes?: { + destructive?: boolean; + idempotent?: boolean; + readOnly?: boolean; + }; + action: (context: ActionsRegistryActionContext) => Promise< + z.infer extends void + ? void + : { + output: z.infer; + } + >; +}; + +// @alpha (undocumented) +export interface ActionsRegistryService { + // (undocumented) + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >( + options: ActionsRegistryActionOptions, + ): void; +} + +// @alpha +export const actionsRegistryServiceRef: ServiceRef< + ActionsRegistryService, + 'plugin', + 'singleton' +>; + +// @alpha (undocumented) +export interface ActionsService { + // (undocumented) + invoke(opts: { + id: string; + input?: JsonObject; + credentials: BackstageCredentials; + }): Promise<{ + output: JsonValue; + }>; + // (undocumented) + list: (opts: { credentials: BackstageCredentials }) => Promise<{ + actions: ActionsServiceAction[]; + }>; +} + +// @alpha (undocumented) +export type ActionsServiceAction = { + id: string; + name: string; + title: string; + description: string; + schema: { + input: JSONSchema7; + output: JSONSchema7; + }; + attributes: { + readOnly: boolean; + destructive: boolean; + idempotent: boolean; + }; +}; + +// @alpha +export const actionsServiceRef: ServiceRef< + ActionsService, + 'plugin', + 'singleton' +>; // @alpha (undocumented) export type BackendFeatureMeta = @@ -23,7 +121,7 @@ export interface InstanceMetadataService { getInstalledFeatures: () => BackendFeatureMeta[]; } -// @alpha +// @alpha (undocumented) export const instanceMetadataServiceRef: ServiceRef< InstanceMetadataService, 'plugin', diff --git a/packages/backend-plugin-api/report.api.md b/packages/backend-plugin-api/report.api.md index 68597dcbe1..52843dec96 100644 --- a/packages/backend-plugin-api/report.api.md +++ b/packages/backend-plugin-api/report.api.md @@ -12,7 +12,6 @@ import type { Handler } from 'express'; import { HumanDuration } from '@backstage/types'; import { isChildPath } from '@backstage/cli-common'; import { JsonObject } from '@backstage/types'; -import { JSONSchema7 } from 'json-schema'; import { JsonValue } from '@backstage/types'; import { Knex } from 'knex'; import { Permission } from '@backstage/plugin-permission-common'; @@ -26,72 +25,6 @@ import { QueryPermissionResponse } from '@backstage/plugin-permission-common'; import { Readable } from 'stream'; import type { Request as Request_2 } from 'express'; import type { Response as Response_2 } from 'express'; -import { z } from 'zod'; -import { ZodType } from 'zod'; - -// @public (undocumented) -export type ActionsRegistryActionContext = { - input: z.infer; - logger: LoggerService; - credentials: BackstageCredentials; -}; - -// @public (undocumented) -export type ActionsRegistryActionOptions< - TInputSchema extends ZodType, - TOutputSchema extends ZodType, -> = { - name: string; - title: string; - description: string; - schema: { - input: (zod: typeof z) => TInputSchema; - output: (zod: typeof z) => TOutputSchema; - }; - action: (context: ActionsRegistryActionContext) => Promise< - z.infer extends void - ? void - : { - output: z.infer; - } - >; -}; - -// @public (undocumented) -export interface ActionsRegistryService { - // (undocumented) - register( - options: ActionsRegistryActionOptions, - ): void; -} - -// @public (undocumented) -export interface ActionsService { - // (undocumented) - invoke(opts: { - id: string; - input?: JsonObject; - credentials: BackstageCredentials; - }): Promise<{ - output: JsonValue; - }>; - // (undocumented) - list: (opts: { credentials: BackstageCredentials }) => Promise<{ - actions: ActionsServiceAction[]; - }>; -} - -// @public (undocumented) -export type ActionsServiceAction = { - id: string; - name: string; - title: string; - description: string; - schema: { - input: JSONSchema7; - output: JSONSchema7; - }; -}; // @public export interface AuditorService { @@ -272,12 +205,6 @@ export type CacheServiceSetOptions = { // @public export namespace coreServices { const auth: ServiceRef; - const actions: ServiceRef; - const actionsRegistry: ServiceRef< - ActionsRegistryService, - 'plugin', - 'singleton' - >; const userInfo: ServiceRef; const cache: ServiceRef; const rootConfig: ServiceRef; diff --git a/packages/backend-plugin-api/src/alpha/ActionsRegistryService.ts b/packages/backend-plugin-api/src/alpha/ActionsRegistryService.ts new file mode 100644 index 0000000000..9a7820e354 --- /dev/null +++ b/packages/backend-plugin-api/src/alpha/ActionsRegistryService.ts @@ -0,0 +1,69 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { z, AnyZodObject } from 'zod'; +import { + LoggerService, + BackstageCredentials, +} from '@backstage/backend-plugin-api'; + +/** + * @alpha + */ +export type ActionsRegistryActionContext = { + input: z.infer; + logger: LoggerService; + credentials: BackstageCredentials; +}; + +/** + * @alpha + */ +export type ActionsRegistryActionOptions< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, +> = { + name: string; + title: string; + description: string; + schema: { + input: (zod: typeof z) => TInputSchema; + output: (zod: typeof z) => TOutputSchema; + }; + attributes?: { + destructive?: boolean; + idempotent?: boolean; + readOnly?: boolean; + }; + action: ( + context: ActionsRegistryActionContext, + ) => Promise< + z.infer extends void + ? void + : { output: z.infer } + >; +}; + +/** + * @alpha + */ +export interface ActionsRegistryService { + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >( + options: ActionsRegistryActionOptions, + ): void; +} diff --git a/packages/backend-plugin-api/src/alpha/ActionsService.ts b/packages/backend-plugin-api/src/alpha/ActionsService.ts new file mode 100644 index 0000000000..528b6cea67 --- /dev/null +++ b/packages/backend-plugin-api/src/alpha/ActionsService.ts @@ -0,0 +1,51 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { JsonObject, JsonValue } from '@backstage/types'; +import { JSONSchema7 } from 'json-schema'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; + +/** + * @alpha + */ +export type ActionsServiceAction = { + id: string; + name: string; + title: string; + description: string; + schema: { + input: JSONSchema7; + output: JSONSchema7; + }; + attributes: { + readOnly: boolean; + destructive: boolean; + idempotent: boolean; + }; +}; + +/** + * @alpha + */ +export interface ActionsService { + list: (opts: { + credentials: BackstageCredentials; + }) => Promise<{ actions: ActionsServiceAction[] }>; + invoke(opts: { + id: string; + input?: JsonObject; + credentials: BackstageCredentials; + }): Promise<{ output: JsonValue }>; +} diff --git a/packages/backend-plugin-api/src/services/definitions/InstanceMetadataService.ts b/packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts similarity index 100% rename from packages/backend-plugin-api/src/services/definitions/InstanceMetadataService.ts rename to packages/backend-plugin-api/src/alpha/InstanceMetadataService.ts diff --git a/packages/backend-plugin-api/src/alpha.ts b/packages/backend-plugin-api/src/alpha/index.ts similarity index 60% rename from packages/backend-plugin-api/src/alpha.ts rename to packages/backend-plugin-api/src/alpha/index.ts index 6e91e10671..5bb69eb4e2 100644 --- a/packages/backend-plugin-api/src/alpha.ts +++ b/packages/backend-plugin-api/src/alpha/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2023 The Backstage Authors + * Copyright 2025 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,20 +14,21 @@ * limitations under the License. */ -import { createServiceRef } from '@backstage/backend-plugin-api'; - -/** - * EXPERIMENTAL: Instance metadata service. - * - * @alpha - */ -export const instanceMetadataServiceRef = createServiceRef< - import('./services/definitions/InstanceMetadataService').InstanceMetadataService ->({ - id: 'core.instanceMetadata', -}); - export type { BackendFeatureMeta, InstanceMetadataService, -} from './services/definitions/InstanceMetadataService'; +} from './InstanceMetadataService'; + +export type { + ActionsRegistryService, + ActionsRegistryActionOptions, + ActionsRegistryActionContext, +} from './ActionsRegistryService'; + +export type { ActionsService, ActionsServiceAction } from './ActionsService'; + +export { + actionsRegistryServiceRef, + actionsServiceRef, + instanceMetadataServiceRef, +} from './refs'; diff --git a/packages/backend-plugin-api/src/alpha/refs.ts b/packages/backend-plugin-api/src/alpha/refs.ts new file mode 100644 index 0000000000..81996679f7 --- /dev/null +++ b/packages/backend-plugin-api/src/alpha/refs.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createServiceRef } from '@backstage/backend-plugin-api'; + +/** + * @alpha + */ +export const instanceMetadataServiceRef = createServiceRef< + import('./InstanceMetadataService').InstanceMetadataService +>({ + id: 'core.instanceMetadata', +}); + +/** + * Service for calling distributed actions + * + * See {@link ActionsService} + * and {@link https://backstage.io/docs/backend-system/core-services/actions | the service docs} + * for more information. + * + * @alpha + */ +export const actionsServiceRef = createServiceRef< + import('./ActionsService').ActionsService +>({ + id: 'alpha.core.actions', +}); + +/** + * Service for registering and managing distributed actions. + * + * See {@link ActionsRegistryService} + * and {@link https://backstage.io/docs/backend-system/core-services/actions-registry | the service docs} + * for more information. + * + * @alpha + */ +export const actionsRegistryServiceRef = createServiceRef< + import('./ActionsRegistryService').ActionsRegistryService +>({ + id: 'alpha.core.actionsRegistry', +}); diff --git a/packages/backend-plugin-api/src/services/definitions/ActionsRegistryService.ts b/packages/backend-plugin-api/src/services/definitions/ActionsRegistryService.ts index 3044c84ed8..6c0936f85c 100644 --- a/packages/backend-plugin-api/src/services/definitions/ActionsRegistryService.ts +++ b/packages/backend-plugin-api/src/services/definitions/ActionsRegistryService.ts @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { z, ZodType } from 'zod'; +import { z, AnyZodObject } from 'zod'; import { LoggerService } from './LoggerService'; import { BackstageCredentials } from './AuthService'; /** * @public */ -export type ActionsRegistryActionContext = { +export type ActionsRegistryActionContext = { input: z.infer; logger: LoggerService; credentials: BackstageCredentials; @@ -30,8 +30,8 @@ export type ActionsRegistryActionContext = { * @public */ export type ActionsRegistryActionOptions< - TInputSchema extends ZodType, - TOutputSchema extends ZodType, + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, > = { name: string; title: string; @@ -40,6 +40,11 @@ export type ActionsRegistryActionOptions< input: (zod: typeof z) => TInputSchema; output: (zod: typeof z) => TOutputSchema; }; + attributes?: { + destructive?: boolean; + idempotent?: boolean; + readOnly?: boolean; + }; action: ( context: ActionsRegistryActionContext, ) => Promise< @@ -53,7 +58,10 @@ export type ActionsRegistryActionOptions< * @public */ export interface ActionsRegistryService { - register( + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >( options: ActionsRegistryActionOptions, ): void; } diff --git a/packages/backend-plugin-api/src/services/definitions/ActionsService.ts b/packages/backend-plugin-api/src/services/definitions/ActionsService.ts index 69b13afaaa..d595008a42 100644 --- a/packages/backend-plugin-api/src/services/definitions/ActionsService.ts +++ b/packages/backend-plugin-api/src/services/definitions/ActionsService.ts @@ -29,6 +29,11 @@ export type ActionsServiceAction = { input: JSONSchema7; output: JSONSchema7; }; + attributes: { + readOnly: boolean; + destructive: boolean; + idempotent: boolean; + }; }; /** diff --git a/packages/backend-plugin-api/src/services/definitions/coreServices.ts b/packages/backend-plugin-api/src/services/definitions/coreServices.ts index c5282368ac..8c8c6c0f82 100644 --- a/packages/backend-plugin-api/src/services/definitions/coreServices.ts +++ b/packages/backend-plugin-api/src/services/definitions/coreServices.ts @@ -35,36 +35,6 @@ export namespace coreServices { id: 'core.auth', }); - /** - * Service for calling distributed actions - * - * See {@link ActionsService} - * and {@link https://backstage.io/docs/backend-system/core-services/actions | the service docs} - * for more information. - * - * @public - */ - export const actions = createServiceRef< - import('./ActionsService').ActionsService - >({ - id: 'core.actions', - }); - - /** - * Service for registering and managing distributed actions. - * - * See {@link ActionsRegistryService} - * and {@link https://backstage.io/docs/backend-system/core-services/actions-registry | the service docs} - * for more information. - * - * @public - */ - export const actionsRegistry = createServiceRef< - import('./ActionsRegistryService').ActionsRegistryService - >({ - id: 'core.actionsRegistry', - }); - /** * Authenticated user information retrieval. * diff --git a/packages/backend-plugin-api/src/services/definitions/index.ts b/packages/backend-plugin-api/src/services/definitions/index.ts index a01544b60f..c811a513a8 100644 --- a/packages/backend-plugin-api/src/services/definitions/index.ts +++ b/packages/backend-plugin-api/src/services/definitions/index.ts @@ -13,14 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -export type { - ActionsRegistryService, - ActionsRegistryActionOptions, - ActionsRegistryActionContext, -} from './ActionsRegistryService'; - -export type { ActionsService, ActionsServiceAction } from './ActionsService'; export type { AuditorService, AuditorServiceCreateEventOptions, diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 62aacfee99..9f4d75684f 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,70 @@ # @backstage/backend-test-utils +## 1.7.0-next.0 + +### Minor Changes + +- ead925a: Add a standard `toString` on credentials objects + +### Patch Changes + +- Updated dependencies + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/backend-app-api@1.2.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-events-node@0.4.12 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-permission-common@0.9.0 + +## 1.6.0 + +### Minor Changes + +- 6dfb7be: Added `mockServices.permissions()` that can return actual results. +- c999c25: Added an `actionsRegistryServiceMock` and `actionsServiceMock` to `/alpha` export for the experimental services. + + This allows you to write tests for your actions by doing something similar to the following: + + ```ts + import { actionsRegistryServiceMock } from '@backstage/backend-test-utils/alpha'; + + const mockActionsRegistry = actionsRegistryServiceMock(); + const mockCatalog = catalogServiceMock({ + entities: [ + ... + ], + }); + + createGetCatalogEntityAction({ + catalog: mockCatalog, + actionsRegistry: mockActionsRegistry, + }); + + await expect( + mockActionsRegistry.invoke({ + id: 'test:get-catalog-entity', + input: { name: 'test' }, + }), + ).resolves.toEqual(...) + ``` + +### Patch Changes + +- 12c1fd4: Make the `user` credentials mock behave more like production +- Updated dependencies + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/backend-app-api@1.2.4 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/config@1.3.2 + - @backstage/errors@1.2.7 + - @backstage/types@1.2.1 + - @backstage/plugin-events-node@0.4.12 + - @backstage/plugin-permission-common@0.9.0 + ## 1.6.0-next.2 ### Patch Changes diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 3783c943b6..eb0bc1da9a 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/backend-test-utils", - "version": "1.6.0-next.2", + "version": "1.7.0-next.0", "description": "Test helpers library for Backstage backends", "backstage": { "role": "node-library" @@ -21,7 +21,8 @@ "license": "Apache-2.0", "exports": { ".": "./src/index.ts", - "./package.json": "./package.json" + "./package.json": "./package.json", + "./alpha": "./src/alpha/index.ts" }, "main": "src/index.ts", "types": "src/index.ts", @@ -29,6 +30,9 @@ "*": { "package.json": [ "package.json" + ], + "alpha": [ + "src/alpha/index.ts" ] } }, @@ -52,6 +56,7 @@ "@backstage/errors": "workspace:^", "@backstage/plugin-auth-node": "workspace:^", "@backstage/plugin-events-node": "workspace:^", + "@backstage/plugin-permission-common": "workspace:^", "@backstage/types": "workspace:^", "@keyv/memcache": "^2.0.1", "@keyv/redis": "^4.0.1", @@ -72,7 +77,9 @@ "testcontainers": "^10.0.0", "textextensions": "^5.16.0", "uuid": "^11.0.0", - "yn": "^4.0.0" + "yn": "^4.0.0", + "zod": "^3.22.4", + "zod-to-json-schema": "^3.20.4" }, "devDependencies": { "@backstage/cli": "workspace:^", diff --git a/packages/backend-test-utils/report-alpha.api.md b/packages/backend-test-utils/report-alpha.api.md new file mode 100644 index 0000000000..ccbf96c0c7 --- /dev/null +++ b/packages/backend-test-utils/report-alpha.api.md @@ -0,0 +1,85 @@ +## API Report File for "@backstage/backend-test-utils" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ActionsRegistryActionOptions } from '@backstage/backend-plugin-api/alpha'; +import { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha'; +import { ActionsService } from '@backstage/backend-plugin-api/alpha'; +import { ActionsServiceAction } from '@backstage/backend-plugin-api/alpha'; +import { AnyZodObject } from 'zod'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; +import { JsonObject } from '@backstage/types'; +import { JsonValue } from '@backstage/types'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @alpha (undocumented) +export function actionsRegistryServiceMock(options?: { + logger: LoggerService; +}): MockActionsRegistry; + +// @alpha (undocumented) +export namespace actionsRegistryServiceMock { + const // (undocumented) + factory: () => ServiceFactory< + ActionsRegistryService, + 'plugin', + 'singleton' + >; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; +} + +// @alpha (undocumented) +export namespace actionsServiceMock { + const // (undocumented) + factory: () => ServiceFactory; + const // (undocumented) + mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; +} + +// @alpha +export class MockActionsRegistry + implements ActionsRegistryService, ActionsService +{ + // (undocumented) + readonly actions: Map>; + // (undocumented) + static create(opts: { logger: LoggerService }): MockActionsRegistry; + // (undocumented) + invoke(opts: { + id: string; + input?: JsonObject; + credentials?: BackstageCredentials; + }): Promise<{ + output: JsonValue; + }>; + // (undocumented) + list(): Promise<{ + actions: ActionsServiceAction[]; + }>; + // (undocumented) + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >(options: ActionsRegistryActionOptions): void; +} + +// @alpha (undocumented) +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/packages/backend-test-utils/report.api.md b/packages/backend-test-utils/report.api.md index 379a2a70ac..4853ca57c5 100644 --- a/packages/backend-test-utils/report.api.md +++ b/packages/backend-test-utils/report.api.md @@ -3,9 +3,8 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { ActionsRegistryService } from '@backstage/backend-plugin-api'; -import { ActionsService } from '@backstage/backend-plugin-api'; import { AuditorService } from '@backstage/backend-plugin-api'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { AuthService } from '@backstage/backend-plugin-api'; import { Backend } from '@backstage/backend-app-api'; import { BackendFeature } from '@backstage/backend-plugin-api'; @@ -163,28 +162,6 @@ export function mockErrorHandler(): ErrorRequestHandler< // @public export namespace mockServices { - // (undocumented) - export namespace actions { - const // (undocumented) - factory: () => ServiceFactory; - const // (undocumented) - mock: ( - partialImpl?: Partial | undefined, - ) => ServiceMock; - } - // (undocumented) - export namespace actionsRegistry { - const // (undocumented) - factory: () => ServiceFactory< - ActionsRegistryService, - 'plugin', - 'singleton' - >; - const // (undocumented) - mock: ( - partialImpl?: Partial | undefined, - ) => ServiceMock; - } // (undocumented) export namespace auditor { const // (undocumented) @@ -299,14 +276,17 @@ export namespace mockServices { partialImpl?: Partial | undefined, ) => ServiceMock; } + export function permissions(options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }): PermissionsService; // (undocumented) export namespace permissions { - const // (undocumented) - factory: () => ServiceFactory; - const // (undocumented) - mock: ( - partialImpl?: Partial | undefined, - ) => ServiceMock; + const factory: (options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }) => ServiceFactory; + const mock: ( + partialImpl?: Partial | undefined, + ) => ServiceMock; } // (undocumented) export namespace permissionsRegistry { diff --git a/packages/backend-test-utils/src/next/index.ts b/packages/backend-test-utils/src/alpha/index.ts similarity index 96% rename from packages/backend-test-utils/src/next/index.ts rename to packages/backend-test-utils/src/alpha/index.ts index 572fb3a9e7..d891744260 100644 --- a/packages/backend-test-utils/src/next/index.ts +++ b/packages/backend-test-utils/src/alpha/index.ts @@ -14,5 +14,4 @@ * limitations under the License. */ -export * from './wiring'; export * from './services'; diff --git a/packages/backend-test-utils/src/alpha/services/ActionsRegistryServiceMock.ts b/packages/backend-test-utils/src/alpha/services/ActionsRegistryServiceMock.ts new file mode 100644 index 0000000000..faf89b393a --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/ActionsRegistryServiceMock.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { mockServices } from '../../services'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { MockActionsRegistry } from './MockActionsRegistry'; +import { simpleMock } from './simpleMock'; +import { + ActionsRegistryService, + actionsRegistryServiceRef, +} from '@backstage/backend-plugin-api/alpha'; +import { actionsRegistryServiceFactory } from '@backstage/backend-defaults/alpha'; + +/** + * @alpha + */ +export function actionsRegistryServiceMock(options?: { + logger: LoggerService; +}): MockActionsRegistry { + return MockActionsRegistry.create({ + logger: options?.logger ?? mockServices.logger.mock(), + }); +} + +/** + * @alpha + */ +export namespace actionsRegistryServiceMock { + export const factory = () => actionsRegistryServiceFactory; + + export const mock = simpleMock( + actionsRegistryServiceRef, + () => ({ + register: jest.fn(), + }), + ); +} diff --git a/packages/backend-test-utils/src/alpha/services/ActionsServiceMock.ts b/packages/backend-test-utils/src/alpha/services/ActionsServiceMock.ts new file mode 100644 index 0000000000..63abff4c37 --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/ActionsServiceMock.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { simpleMock } from './simpleMock'; +import { + ActionsService, + actionsServiceRef, +} from '@backstage/backend-plugin-api/alpha'; +import { actionsServiceFactory } from '@backstage/backend-defaults/alpha'; + +/** + * @alpha + */ +export namespace actionsServiceMock { + export const factory = () => actionsServiceFactory; + + export const mock = simpleMock(actionsServiceRef, () => ({ + invoke: jest.fn(), + list: jest.fn(), + })); +} diff --git a/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.test.ts b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.test.ts new file mode 100644 index 0000000000..f604689c63 --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.test.ts @@ -0,0 +1,236 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + coreServices, + createBackendPlugin, +} from '@backstage/backend-plugin-api'; +import { startTestBackend } from '../../wiring'; +import { actionsRegistryServiceMock } from './ActionsRegistryServiceMock'; +import { mockCredentials } from '../../services'; +import { Router } from 'express'; +import supertest from 'supertest'; +import { + actionsRegistryServiceRef, + actionsServiceRef, +} from '@backstage/backend-plugin-api/alpha'; + +describe('MockActionsRegistry', () => { + it('should be able to register and invoke actions', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => + z.object({ + name: z.string(), + }), + output: z => + z.object({ + name: z.string(), + }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + const result = await registry.invoke({ + id: 'test:my-demo-action', + input: { name: 'test' }, + }); + + expect(result).toEqual({ output: { name: 'test' } }); + }); + + it('should throw an error when the input is invalid to the action', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + await expect( + registry.invoke({ id: 'test:my-demo-action', input: { name: 1 } }), + ).rejects.toThrow('Invalid input to action "test:my-demo-action"'); + }); + + it('should throw an error when the action is not found', async () => { + const registry = actionsRegistryServiceMock(); + + await expect(registry.invoke({ id: 'test' })).rejects.toThrow( + 'Action "test" not found, available actions: none', + ); + }); + + it('should throw an error when the action is not found with recommended actions', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + await expect(registry.invoke({ id: 'test' })).rejects.toThrow( + 'Action "test" not found, available actions: "test:my-demo-action"', + ); + }); + + it('should throw an error when the output is invalid', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.number() }), + output: z => z.object({ name: z.string() }), + }, + // @ts-expect-error - we want to test the error case + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + await expect( + registry.invoke({ id: 'test:my-demo-action', input: { name: 1 } }), + ).rejects.toThrow('Invalid output from action "test:my-demo-action"'); + }); + + it('should list the actions correctly', async () => { + const registry = actionsRegistryServiceMock(); + + registry.register({ + name: 'my-demo-action', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => ({ output: { name: input.name } }), + }); + + const result = await registry.list(); + + expect(result).toMatchObject({ + actions: [ + { + id: 'test:my-demo-action', + name: 'my-demo-action', + title: 'Test', + description: 'Test', + attributes: { + destructive: true, + idempotent: false, + readOnly: false, + }, + schema: { + input: { + type: 'object', + properties: { + name: { type: 'string' }, + }, + }, + output: { + type: 'object', + properties: { + name: { type: 'string' }, + }, + }, + }, + }, + ], + }); + }); + + describe('actionsRegistryServiceMock + mockService.actionsRegistry', () => { + it('should be able to register and invoke actions', async () => { + const pluginWithAction = createBackendPlugin({ + pluginId: 'my-plugin', + register(reg) { + reg.registerInit({ + deps: { actionsRegistry: actionsRegistryServiceRef }, + async init({ actionsRegistry }) { + actionsRegistry.register({ + name: 'test', + title: 'Test', + description: 'Test', + schema: { + input: z => z.object({ name: z.string() }), + output: z => z.object({ name: z.string() }), + }, + action: async ({ input }) => { + expect(input).toEqual({ name: 'test' }); + return { output: { name: input.name } }; + }, + }); + }, + }); + }, + }); + + const pluginToCallAction = createBackendPlugin({ + pluginId: 'my-plugin-to-call-action', + register(reg) { + reg.registerInit({ + deps: { + actions: actionsServiceRef, + router: coreServices.httpRouter, + }, + async init({ actions, router }) { + const testRouter = Router(); + router.use(testRouter); + + testRouter.post('/test', async (_, res) => { + const { output } = await actions.invoke({ + id: 'my-plugin:test', + input: { name: 'test' }, + credentials: mockCredentials.service(), + }); + + res.json(output); + }); + }, + }); + }, + }); + + const { server } = await startTestBackend({ + features: [pluginWithAction, pluginToCallAction], + }); + + const { body, status } = await supertest(server).post( + '/api/my-plugin-to-call-action/test', + ); + + expect(status).toBe(200); + expect(body).toEqual({ name: 'test' }); + }); + }); +}); diff --git a/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.ts b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.ts new file mode 100644 index 0000000000..49c80b7a3d --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/MockActionsRegistry.ts @@ -0,0 +1,168 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + BackstageCredentials, + LoggerService, +} from '@backstage/backend-plugin-api'; +import { ForwardedError, InputError, NotFoundError } from '@backstage/errors'; +import { JsonObject, JsonValue } from '@backstage/types'; +import { z, AnyZodObject } from 'zod'; +import zodToJsonSchema from 'zod-to-json-schema'; +import { mockCredentials } from '../../services'; +import { + ActionsRegistryActionOptions, + ActionsRegistryService, + ActionsService, + ActionsServiceAction, +} from '@backstage/backend-plugin-api/alpha'; + +/** + * A mock implementation of the ActionsRegistryService and ActionsService that can be used in tests. + * + * This is useful for testing actions that are registered with the ActionsRegistryService and ActionsService. + * + * The plugin ID is hardcoded to `testing` in the mock implementation. + * + * @example + * ```ts + * const actionsRegistry = mockServices.actionsRegistry(); + * + * actionsRegistry.register({ + * name: 'test', + * title: 'Test', + * description: 'Test', + * schema: { + * input: z.object({ name: z.string() }), + * output: z.object({ name: z.string() }), + * }, + * action: async ({ input }) => ({ output: { name: input.name } }), + * }); + * + * + * const result = await actionsRegistry.invoke({ + * id: 'testing:test', + * input: { name: 'test' }, + * }); + * + * expect(result).toEqual({ output: { name: 'test' } }); + * ``` + * + * @alpha + */ +export class MockActionsRegistry + implements ActionsRegistryService, ActionsService +{ + private constructor(private readonly logger: LoggerService) {} + + static create(opts: { logger: LoggerService }) { + return new MockActionsRegistry(opts.logger); + } + + readonly actions: Map> = + new Map(); + + async list(): Promise<{ actions: ActionsServiceAction[] }> { + return { + actions: Array.from(this.actions.entries()).map(([id, action]) => ({ + id, + name: action.name, + title: action.title, + description: action.description, + attributes: { + destructive: action.attributes?.destructive ?? true, + idempotent: action.attributes?.idempotent ?? false, + readOnly: action.attributes?.readOnly ?? false, + }, + schema: { + input: action.schema?.input + ? zodToJsonSchema(action.schema.input(z)) + : zodToJsonSchema(z.object({})), + output: action.schema?.output + ? zodToJsonSchema(action.schema.output(z)) + : zodToJsonSchema(z.object({})), + } as ActionsServiceAction['schema'], + })), + }; + } + + async invoke(opts: { + id: string; + input?: JsonObject; + credentials?: BackstageCredentials; + }): Promise<{ output: JsonValue }> { + const action = this.actions.get(opts.id); + + if (!action) { + const availableActionIds = Array.from(this.actions.keys()).join(', '); + throw new NotFoundError( + `Action "${opts.id}" not found, available actions: ${ + availableActionIds ? `"${availableActionIds}"` : 'none' + }`, + ); + } + + const input = action.schema?.input + ? action.schema.input(z).safeParse(opts.input) + : ({ success: true, data: undefined } as const); + + if (!input.success) { + throw new InputError(`Invalid input to action "${opts.id}"`, input.error); + } + + try { + const result = await action.action({ + input: input.data, + credentials: opts.credentials ?? mockCredentials.none(), + logger: this.logger, + }); + + const output = action.schema?.output + ? action.schema.output(z).safeParse(result?.output) + : ({ success: true, data: result?.output } as const); + + if (!output.success) { + throw new InputError( + `Invalid output from action "${opts.id}"`, + output.error, + ); + } + + return { output: output.data }; + } catch (error) { + throw new ForwardedError( + `Failed execution of action "${opts.id}"`, + error, + ); + } + } + + register< + TInputSchema extends AnyZodObject, + TOutputSchema extends AnyZodObject, + >(options: ActionsRegistryActionOptions): void { + // hardcode test: prefix similar to how the default actions registry does it + // and other places around the testing ecosystem: + // https://github.com/backstage/backstage/blob/a9219496d5c073aaa0b8caf32ece10455cf65e61/packages/backend-test-utils/src/next/services/mockServices.ts#L321 + // https://github.com/backstage/backstage/blob/861f162b4a39117b824669d67a951ed1db142e3d/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts#L99 + const id = `test:${options.name}`; + + if (this.actions.has(id)) { + throw new Error(`Action with id "${id}" is already registered`); + } + + this.actions.set(id, options); + } +} diff --git a/packages/backend-test-utils/src/alpha/services/index.ts b/packages/backend-test-utils/src/alpha/services/index.ts new file mode 100644 index 0000000000..ca9b3f23a0 --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { actionsRegistryServiceMock } from './ActionsRegistryServiceMock'; +export { MockActionsRegistry } from './MockActionsRegistry'; +export { actionsServiceMock } from './ActionsServiceMock'; +export { type ServiceMock } from './simpleMock'; diff --git a/packages/backend-test-utils/src/alpha/services/simpleMock.ts b/packages/backend-test-utils/src/alpha/services/simpleMock.ts new file mode 100644 index 0000000000..d07b143f7a --- /dev/null +++ b/packages/backend-test-utils/src/alpha/services/simpleMock.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createServiceFactory, + ServiceFactory, + ServiceRef, +} from '@backstage/backend-plugin-api'; + +/** @alpha */ +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + +/** @internal */ +export function simpleMock( + ref: ServiceRef, + mockFactory: () => jest.Mocked, +): (partialImpl?: Partial) => ServiceMock { + return partialImpl => { + const mock = mockFactory(); + if (partialImpl) { + for (const [key, impl] of Object.entries(partialImpl)) { + if (typeof impl === 'function') { + (mock as any)[key].mockImplementation(impl); + } else { + (mock as any)[key] = impl; + } + } + } + return Object.assign(mock, { + factory: createServiceFactory({ + service: ref, + deps: {}, + factory: () => mock, + }), + }) as ServiceMock; + }; +} diff --git a/packages/backend-test-utils/src/index.ts b/packages/backend-test-utils/src/index.ts index d8e0e2c4a6..7cc4546415 100644 --- a/packages/backend-test-utils/src/index.ts +++ b/packages/backend-test-utils/src/index.ts @@ -24,5 +24,6 @@ export * from './cache'; export * from './database'; export * from './msw'; export * from './filesystem'; -export * from './next'; +export * from './services'; +export * from './wiring'; export { mockErrorHandler } from './util'; diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.test.ts b/packages/backend-test-utils/src/services/MockAuthService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockAuthService.test.ts rename to packages/backend-test-utils/src/services/MockAuthService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockAuthService.ts b/packages/backend-test-utils/src/services/MockAuthService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockAuthService.ts rename to packages/backend-test-utils/src/services/MockAuthService.ts diff --git a/packages/backend-test-utils/src/next/services/MockEventsService.test.ts b/packages/backend-test-utils/src/services/MockEventsService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockEventsService.test.ts rename to packages/backend-test-utils/src/services/MockEventsService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockEventsService.ts b/packages/backend-test-utils/src/services/MockEventsService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockEventsService.ts rename to packages/backend-test-utils/src/services/MockEventsService.ts diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts b/packages/backend-test-utils/src/services/MockHttpAuthService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockHttpAuthService.test.ts rename to packages/backend-test-utils/src/services/MockHttpAuthService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockHttpAuthService.ts b/packages/backend-test-utils/src/services/MockHttpAuthService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockHttpAuthService.ts rename to packages/backend-test-utils/src/services/MockHttpAuthService.ts diff --git a/packages/backend-test-utils/src/services/MockPermissionsService.test.ts b/packages/backend-test-utils/src/services/MockPermissionsService.test.ts new file mode 100644 index 0000000000..eb98fe9457 --- /dev/null +++ b/packages/backend-test-utils/src/services/MockPermissionsService.test.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { MockPermissionsService } from './MockPermissionsService'; + +describe('MockPermissionsService', () => { + it('should return the correct result', async () => { + const permission = { + permission: { + name: 'test', + type: 'basic', + attributes: {}, + }, + } as const; + + const defaultService = new MockPermissionsService(); + const allowService = new MockPermissionsService({ + result: AuthorizeResult.ALLOW, + }); + const denyService = new MockPermissionsService({ + result: AuthorizeResult.DENY, + }); + + await expect(defaultService.authorize([permission])).resolves.toEqual([ + { + ...permission, + result: AuthorizeResult.ALLOW, + }, + ]); + await expect(allowService.authorize([permission])).resolves.toEqual([ + { + ...permission, + result: AuthorizeResult.ALLOW, + }, + ]); + await expect(denyService.authorize([permission])).resolves.toEqual([ + { + ...permission, + result: AuthorizeResult.DENY, + }, + ]); + }); +}); diff --git a/packages/backend-test-utils/src/services/MockPermissionsService.ts b/packages/backend-test-utils/src/services/MockPermissionsService.ts new file mode 100644 index 0000000000..3637c34554 --- /dev/null +++ b/packages/backend-test-utils/src/services/MockPermissionsService.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PermissionsService } from '@backstage/backend-plugin-api'; +import { + AuthorizePermissionRequest, + AuthorizePermissionResponse, + AuthorizeResult, + QueryPermissionRequest, + QueryPermissionResponse, +} from '@backstage/plugin-permission-common'; + +export class MockPermissionsService implements PermissionsService { + readonly #result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + + constructor(options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }) { + this.#result = options?.result ?? AuthorizeResult.ALLOW; + } + + async authorize( + requests: AuthorizePermissionRequest[], + ): Promise { + return requests.map(request => ({ + ...request, + result: this.#result, + })); + } + + async authorizeConditional( + requests: QueryPermissionRequest[], + ): Promise { + return requests.map(request => ({ + ...request, + result: this.#result, + })); + } +} diff --git a/packages/backend-test-utils/src/next/services/MockRootLoggerService.test.ts b/packages/backend-test-utils/src/services/MockRootLoggerService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockRootLoggerService.test.ts rename to packages/backend-test-utils/src/services/MockRootLoggerService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockRootLoggerService.ts b/packages/backend-test-utils/src/services/MockRootLoggerService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockRootLoggerService.ts rename to packages/backend-test-utils/src/services/MockRootLoggerService.ts diff --git a/packages/backend-test-utils/src/next/services/MockUserInfoService.test.ts b/packages/backend-test-utils/src/services/MockUserInfoService.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockUserInfoService.test.ts rename to packages/backend-test-utils/src/services/MockUserInfoService.test.ts diff --git a/packages/backend-test-utils/src/next/services/MockUserInfoService.ts b/packages/backend-test-utils/src/services/MockUserInfoService.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/MockUserInfoService.ts rename to packages/backend-test-utils/src/services/MockUserInfoService.ts diff --git a/packages/backend-test-utils/src/next/services/index.ts b/packages/backend-test-utils/src/services/index.ts similarity index 87% rename from packages/backend-test-utils/src/next/services/index.ts rename to packages/backend-test-utils/src/services/index.ts index 7c3949e207..73f179ca41 100644 --- a/packages/backend-test-utils/src/next/services/index.ts +++ b/packages/backend-test-utils/src/services/index.ts @@ -13,5 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { mockServices, type ServiceMock } from './mockServices'; +export { mockServices } from './mockServices'; export { mockCredentials } from './mockCredentials'; +export { type ServiceMock } from './simpleMock'; diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts b/packages/backend-test-utils/src/services/mockCredentials.test.ts similarity index 89% rename from packages/backend-test-utils/src/next/services/mockCredentials.test.ts rename to packages/backend-test-utils/src/services/mockCredentials.test.ts index 343d6d6d20..9248e3bde0 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.test.ts +++ b/packages/backend-test-utils/src/services/mockCredentials.test.ts @@ -170,4 +170,27 @@ describe('mockCredentials', () => { "Invalid user entity reference 'wrong', expected :/", ); }); + + it('should have a serializable form', () => { + expect(String(mockCredentials.service('my-service'))).toMatchInlineSnapshot( + `"mockCredentials{servicePrincipal{my-service}}"`, + ); + expect( + String(mockCredentials.user('user:default/mock')), + ).toMatchInlineSnapshot( + `"mockCredentials{userPrincipal{user:default/mock}}"`, + ); + expect( + String( + mockCredentials.user('user:default/mock', { + actor: { subject: 'my-actor' }, + }), + ), + ).toMatchInlineSnapshot( + `"mockCredentials{userPrincipal{user:default/mock,actor={my-actor}}}"`, + ); + expect(String(mockCredentials.none())).toMatchInlineSnapshot( + `"mockCredentials{nonePrincipal}"`, + ); + }); }); diff --git a/packages/backend-test-utils/src/next/services/mockCredentials.ts b/packages/backend-test-utils/src/services/mockCredentials.ts similarity index 87% rename from packages/backend-test-utils/src/next/services/mockCredentials.ts rename to packages/backend-test-utils/src/services/mockCredentials.ts index 617ffdb240..d749f7edb1 100644 --- a/packages/backend-test-utils/src/next/services/mockCredentials.ts +++ b/packages/backend-test-utils/src/services/mockCredentials.ts @@ -76,10 +76,19 @@ export namespace mockCredentials { * Creates a mocked credentials object for a unauthenticated principal. */ export function none(): BackstageCredentials { - return { + const result = { $$type: '@backstage/BackstageCredentials', principal: { type: 'none' }, - }; + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + writable: true, + value: () => `mockCredentials{nonePrincipal}`, + }, + }); + return result; } /** @@ -111,24 +120,32 @@ export namespace mockCredentials { options?: { actor?: { subject: string } }, ): BackstageCredentials { validateUserEntityRef(userEntityRef); - return Object.defineProperty( - { - $$type: '@backstage/BackstageCredentials', - principal: { - type: 'user', - userEntityRef, - ...(options?.actor && { - actor: { type: 'service', subject: options.actor.subject }, - }), - }, + const result = { + $$type: '@backstage/BackstageCredentials', + principal: { + type: 'user', + userEntityRef, + ...(options?.actor && { + actor: { type: 'service', subject: options.actor.subject } as const, + }), }, - 'token', - { + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + value: () => + `mockCredentials{userPrincipal{${userEntityRef}${ + options?.actor ? `,actor={${options.actor.subject}}` : '' + }}}`, + }, + token: { enumerable: false, configurable: true, value: user.token(), }, - ); + }); + return result; } /** @@ -231,14 +248,27 @@ export namespace mockCredentials { subject: string = DEFAULT_MOCK_SERVICE_SUBJECT, accessRestrictions?: BackstagePrincipalAccessRestrictions, ): BackstageCredentials { - return { + const result = { $$type: '@backstage/BackstageCredentials', principal: { type: 'service', subject, ...(accessRestrictions ? { accessRestrictions } : {}), }, - }; + } as const; + Object.defineProperties(result, { + toString: { + enumerable: false, + configurable: true, + value: () => + `mockCredentials{servicePrincipal{${subject}${ + accessRestrictions + ? `,accessRestrictions=${JSON.stringify(accessRestrictions)}` + : '' + }}}`, + }, + }); + return result; } /** diff --git a/packages/backend-test-utils/src/next/services/mockServices.test.ts b/packages/backend-test-utils/src/services/mockServices.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/services/mockServices.test.ts rename to packages/backend-test-utils/src/services/mockServices.test.ts diff --git a/packages/backend-test-utils/src/next/services/mockServices.ts b/packages/backend-test-utils/src/services/mockServices.ts similarity index 90% rename from packages/backend-test-utils/src/next/services/mockServices.ts rename to packages/backend-test-utils/src/services/mockServices.ts index 0c5b18bd1e..06bf8f9a29 100644 --- a/packages/backend-test-utils/src/next/services/mockServices.ts +++ b/packages/backend-test-utils/src/services/mockServices.ts @@ -36,6 +36,7 @@ import { DiscoveryService, HttpAuthService, LoggerService, + PermissionsService, RootConfigService, ServiceFactory, ServiceRef, @@ -45,6 +46,7 @@ import { } from '@backstage/backend-plugin-api'; import { ConfigReader } from '@backstage/config'; import { EventsService, eventsServiceRef } from '@backstage/plugin-events-node'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; import { JsonObject } from '@backstage/types'; import { Knex } from 'knex'; import { MockAuthService } from './MockAuthService'; @@ -53,8 +55,8 @@ import { MockRootLoggerService } from './MockRootLoggerService'; import { MockUserInfoService } from './MockUserInfoService'; import { mockCredentials } from './mockCredentials'; import { MockEventsService } from './MockEventsService'; -import { actionsServiceFactory } from '@backstage/backend-defaults/actions'; -import { actionsRegistryServiceFactory } from '@backstage/backend-defaults/actionsRegistry'; +import { MockPermissionsService } from './MockPermissionsService'; +import { simpleMock } from './simpleMock'; /** @internal */ function createLoggerMock() { @@ -91,43 +93,6 @@ function simpleFactoryWithOptions< ((...options: TOptions) => ServiceFactory); } -/** @public */ -export type ServiceMock = { - factory: ServiceFactory; -} & { - [Key in keyof TService]: TService[Key] extends ( - ...args: infer Args - ) => infer Return - ? TService[Key] & jest.MockInstance - : TService[Key]; -}; - -/** @internal */ -function simpleMock( - ref: ServiceRef, - mockFactory: () => jest.Mocked, -): (partialImpl?: Partial) => ServiceMock { - return partialImpl => { - const mock = mockFactory(); - if (partialImpl) { - for (const [key, impl] of Object.entries(partialImpl)) { - if (typeof impl === 'function') { - (mock as any)[key].mockImplementation(impl); - } else { - (mock as any)[key] = impl; - } - } - } - return Object.assign(mock, { - factory: createServiceFactory({ - service: ref, - deps: {}, - factory: () => mock, - }), - }) as ServiceMock; - }; -} - /** * Mock implementations of the core services, to be used in tests. * @@ -475,8 +440,37 @@ export namespace mockServices { ); } + /** + * Creates a functional mock implementation of the + * {@link @backstage/backend-plugin-api#PermissionsService}. + */ + export function permissions(options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }): PermissionsService { + return new MockPermissionsService(options); + } export namespace permissions { - export const factory = () => permissionsServiceFactory; + /** + * Creates a mock factory for the + * {@link @backstage/backend-plugin-api#coreServices.permissions}. Just + * returns the given `result` if you supply one. Otherwise, it returns the + * regular default permissions factory. + */ + export const factory = (options?: { + result: AuthorizeResult.ALLOW | AuthorizeResult.DENY; + }) => + options?.result + ? createServiceFactory({ + service: coreServices.permissions, + deps: {}, + factory: () => new MockPermissionsService(options), + }) + : permissionsServiceFactory; + /** + * Creates a mock of the + * {@link @backstage/backend-plugin-api#coreServices.permissions}, + * optionally with some given method implementations. + */ export const mock = simpleMock(coreServices.permissions, () => ({ authorize: jest.fn(), authorizeConditional: jest.fn(), @@ -520,20 +514,6 @@ export namespace mockServices { search: jest.fn(), })); } - export namespace actions { - export const factory = () => actionsServiceFactory; - export const mock = simpleMock(coreServices.actions, () => ({ - list: jest.fn(), - invoke: jest.fn(), - })); - } - - export namespace actionsRegistry { - export const factory = () => actionsRegistryServiceFactory; - export const mock = simpleMock(coreServices.actionsRegistry, () => ({ - register: jest.fn(), - })); - } /** * Creates a functional mock implementation of the diff --git a/packages/backend-test-utils/src/services/simpleMock.ts b/packages/backend-test-utils/src/services/simpleMock.ts new file mode 100644 index 0000000000..484969f235 --- /dev/null +++ b/packages/backend-test-utils/src/services/simpleMock.ts @@ -0,0 +1,57 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createServiceFactory, + ServiceFactory, + ServiceRef, +} from '@backstage/backend-plugin-api'; + +/** @public */ +export type ServiceMock = { + factory: ServiceFactory; +} & { + [Key in keyof TService]: TService[Key] extends ( + ...args: infer Args + ) => infer Return + ? TService[Key] & jest.MockInstance + : TService[Key]; +}; + +/** @internal */ +export function simpleMock( + ref: ServiceRef, + mockFactory: () => jest.Mocked, +): (partialImpl?: Partial) => ServiceMock { + return partialImpl => { + const mock = mockFactory(); + if (partialImpl) { + for (const [key, impl] of Object.entries(partialImpl)) { + if (typeof impl === 'function') { + (mock as any)[key].mockImplementation(impl); + } else { + (mock as any)[key] = impl; + } + } + } + return Object.assign(mock, { + factory: createServiceFactory({ + service: ref, + deps: {}, + factory: () => mock, + }), + }) as ServiceMock; + }; +} diff --git a/packages/backend-test-utils/src/util/errorHandler.ts b/packages/backend-test-utils/src/util/errorHandler.ts index f534823f50..79f4d8fd04 100644 --- a/packages/backend-test-utils/src/util/errorHandler.ts +++ b/packages/backend-test-utils/src/util/errorHandler.ts @@ -15,7 +15,7 @@ */ import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter'; -import { mockServices } from '../next'; +import { mockServices } from '../services'; /** * A mock for error handler middleware that can be used in router tests. diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts b/packages/backend-test-utils/src/wiring/ServiceFactoryTester.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.test.ts rename to packages/backend-test-utils/src/wiring/ServiceFactoryTester.test.ts diff --git a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts b/packages/backend-test-utils/src/wiring/ServiceFactoryTester.ts similarity index 97% rename from packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts rename to packages/backend-test-utils/src/wiring/ServiceFactoryTester.ts index 83a6a42307..2b49abc88f 100644 --- a/packages/backend-test-utils/src/next/wiring/ServiceFactoryTester.ts +++ b/packages/backend-test-utils/src/wiring/ServiceFactoryTester.ts @@ -20,7 +20,7 @@ import { defaultServiceFactories } from './TestBackend'; // This is a relative import in order to make sure that the implementation is duplicated // rather than leading to an import from @backstage/backend-app-api. // eslint-disable-next-line @backstage/no-relative-monorepo-imports -import { ServiceRegistry } from '../../../../backend-app-api/src/wiring/ServiceRegistry'; +import { ServiceRegistry } from '../../../backend-app-api/src/wiring/ServiceRegistry'; /** * Options for {@link ServiceFactoryTester}. diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/wiring/TestBackend.test.ts similarity index 100% rename from packages/backend-test-utils/src/next/wiring/TestBackend.test.ts rename to packages/backend-test-utils/src/wiring/TestBackend.test.ts diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/wiring/TestBackend.ts similarity index 97% rename from packages/backend-test-utils/src/next/wiring/TestBackend.ts rename to packages/backend-test-utils/src/wiring/TestBackend.ts index 20d02cf880..cdfa1fc695 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/wiring/TestBackend.ts @@ -31,7 +31,7 @@ import express from 'express'; import { InternalBackendFeature, InternalBackendRegistrations, -} from '../../../../backend-plugin-api/src/wiring/types'; +} from '../../../backend-plugin-api/src/wiring/types'; import { DefaultRootHttpRouter, ExtendedHttpServer, @@ -40,6 +40,10 @@ import { createHttpServer, } from '@backstage/backend-defaults/rootHttpRouter'; import { HostDiscovery } from '@backstage/backend-defaults/discovery'; +import { + actionsRegistryServiceMock, + actionsServiceMock, +} from '../alpha/services'; /** @public */ export interface TestBackendOptions { @@ -84,6 +88,10 @@ export const defaultServiceFactories = [ mockServices.userInfo.factory(), mockServices.urlReader.factory(), mockServices.events.factory(), + + // Alpha services + actionsRegistryServiceMock.factory(), + actionsServiceMock.factory(), ]; /** diff --git a/packages/backend-test-utils/src/next/wiring/index.ts b/packages/backend-test-utils/src/wiring/index.ts similarity index 100% rename from packages/backend-test-utils/src/next/wiring/index.ts rename to packages/backend-test-utils/src/wiring/index.ts diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index 9ed058ea7d..fe09ae31e6 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,85 @@ # example-backend +## 0.0.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@3.0.0-next.0 + - @backstage/backend-defaults@0.11.1-next.0 + - @backstage/plugin-scaffolder-backend@2.0.1-next.0 + - @backstage/plugin-notifications-backend@0.5.8-next.0 + - @backstage/plugin-mcp-actions-backend@0.1.1-next.0 + - @backstage/plugin-scaffolder-backend-module-github@0.8.1-next.0 + - @backstage/plugin-search-backend@2.0.4-next.0 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-devtools-backend@0.5.7-next.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.4-next.0 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-openapi@0.2.12-next.0 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-module-techdocs@0.4.4-next.0 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.12-next.0 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-common@0.9.0 + +## 0.0.39 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-notifications-backend@0.5.7 + - @backstage/plugin-scaffolder-backend-module-github@0.8.0 + - @backstage/backend-defaults@0.11.0 + - @backstage/plugin-scaffolder-backend@2.0.0 + - @backstage/plugin-catalog-backend@2.1.0 + - @backstage/plugin-devtools-backend@0.5.6 + - @backstage/plugin-mcp-actions-backend@0.1.0 + - @backstage/plugin-events-backend@0.5.3 + - @backstage/plugin-search-backend@2.0.3 + - @backstage/plugin-events-backend-module-google-pubsub@0.1.1 + - @backstage/plugin-scaffolder-backend-module-notifications@0.1.11 + - @backstage/plugin-auth-node@0.6.4 + - @backstage/plugin-search-backend-module-techdocs@0.4.3 + - @backstage/backend-plugin-api@1.4.0 + - @backstage/plugin-kubernetes-backend@0.19.7 + - @backstage/plugin-search-backend-module-catalog@0.3.5 + - @backstage/plugin-techdocs-backend@2.0.3 + - @backstage/catalog-model@1.7.4 + - @backstage/plugin-app-backend@0.5.3 + - @backstage/plugin-auth-backend@0.25.1 + - @backstage/plugin-auth-backend-module-github-provider@0.3.4 + - @backstage/plugin-auth-backend-module-guest-provider@0.2.9 + - @backstage/plugin-catalog-backend-module-backstage-openapi@0.5.3 + - @backstage/plugin-catalog-backend-module-openapi@0.2.11 + - @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.9 + - @backstage/plugin-catalog-backend-module-unprocessed@0.6.1 + - @backstage/plugin-permission-backend@0.7.1 + - @backstage/plugin-permission-backend-module-allow-all-policy@0.2.9 + - @backstage/plugin-permission-common@0.9.0 + - @backstage/plugin-permission-node@0.10.1 + - @backstage/plugin-proxy-backend@0.6.3 + - @backstage/plugin-search-backend-module-explore@0.3.3 + - @backstage/plugin-search-backend-node@1.3.12 + - @backstage/plugin-signals-backend@0.3.5 + ## 0.0.39-next.2 ### Patch Changes diff --git a/packages/backend/package.json b/packages/backend/package.json index 66cf7dccfc..e26dfc8e17 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.0.39-next.2", + "version": "0.0.40-next.0", "backstage": { "role": "backend" }, @@ -47,6 +47,7 @@ "@backstage/plugin-events-backend": "workspace:^", "@backstage/plugin-events-backend-module-google-pubsub": "workspace:^", "@backstage/plugin-kubernetes-backend": "workspace:^", + "@backstage/plugin-mcp-actions-backend": "workspace:^", "@backstage/plugin-notifications-backend": "workspace:^", "@backstage/plugin-permission-backend": "workspace:^", "@backstage/plugin-permission-backend-module-allow-all-policy": "workspace:^", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 23d814f1ae..f46e947b0d 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -62,4 +62,5 @@ backend.add(import('@backstage/plugin-notifications-backend')); backend.add(import('./instanceMetadata')); backend.add(import('@backstage/plugin-events-backend-module-google-pubsub')); +backend.add(import('@backstage/plugin-mcp-actions-backend')); backend.start(); diff --git a/packages/canon/.eslintrc.js b/packages/canon/.eslintrc.js index f7c0e8cbd1..9638ff6e45 100644 --- a/packages/canon/.eslintrc.js +++ b/packages/canon/.eslintrc.js @@ -3,6 +3,7 @@ module.exports = { extends: ['plugin:storybook/recommended'], rules: { 'react/forbid-elements': 'off', + '@backstage/no-mixed-plugin-imports': 'off' }, }; diff --git a/packages/canon/.storybook/main.ts b/packages/canon/.storybook/main.ts index e58c0f182f..3020ade96e 100644 --- a/packages/canon/.storybook/main.ts +++ b/packages/canon/.storybook/main.ts @@ -9,10 +9,7 @@ function getAbsolutePath(value: string): string { return dirname(require.resolve(join(value, 'package.json'))); } const config: StorybookConfig = { - stories: [ - '../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)', - '../src/stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', - ], + stories: ['../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)'], staticDirs: ['../static'], addons: [ getAbsolutePath('@storybook/addon-webpack5-compiler-swc'), diff --git a/packages/canon/CHANGELOG.md b/packages/canon/CHANGELOG.md index 519a21a72b..9daf374ba4 100644 --- a/packages/canon/CHANGELOG.md +++ b/packages/canon/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/canon +## 0.6.0-next.0 + +### Minor Changes + +- 4c6d891: **BREAKING CHANGES** + + We’re updating our Button component to provide better support for button links. + + - We’re introducing a new `ButtonLink` component, which replaces the previous render prop pattern. + - To maintain naming consistency across components, `IconButton` is being renamed to `ButtonIcon`. + - Additionally, the render prop will be removed from all button-related components. + + These changes aim to simplify usage and improve clarity in our component API. + +### Patch Changes + +- 140f652: We are consolidating all css files into a single styles.css in Canon. +- 8154fb9: Add new SearchField component in Canon +- 6910892: Add new `RadioGroup` + `Radio` component to Canon +- a8a8514: We are transforming how we structure our class names and data attributes definitions for all components. They are now all set in the same place. +- 667b951: Added placeholder prop to TextField component. +- e71333a: adding export for ButtonLink so it's importable + +## 0.5.0 + +### Minor Changes + +- 621fac9: We are updating the default size of the Button component in Canon to be small instead of medium. +- a842554: We set the default size for IconButton in Canon to be small instead of medium. +- 35fd51d: Move TextField component to use react Aria under the hood. Introducing a new FieldLabel component to help build custom fields. +- 78204a2: **Breaking** We are adding a new as prop on the Heading and Text component to make it easier to change the component tag. We are removing the render prop in favour of the as prop. +- c49e335: TextField in Canon now has multiple label sizes as well as the capacity to hide label and description but still make them available for screen readers. +- 24b45ef: Fixes spacing props on layout components and aligned on naming for the Grid component. You should now call the Grid root component using instead of just . + +### Patch Changes + +- 44df879: Add min-width: 0; by default on every Flex components in Canon to help support truncated texts inside flex elements. +- ee6ffe6: Fix styling for the title4 prop on the Heading component in Canon. +- f2f814a: Added a render prop to the Button component in Canon to use it as a link. +- 98f02a6: Add new Switch component in Canon. +- c94f8e0: The filter input in menu comboboxes should now always use the full width of the menu it's in. +- 269316d: Remove leftover console.log from Container component. + ## 0.5.0-next.2 ### Patch Changes diff --git a/packages/canon/css/avatar.css b/packages/canon/css/avatar.css deleted file mode 100644 index c1f4cca59e..0000000000 --- a/packages/canon/css/avatar.css +++ /dev/null @@ -1,49 +0,0 @@ -.canon-AvatarRoot { - vertical-align: middle; - user-select: none; - color: var(--canon-fg-primary); - background-color: var(--canon-bg-surface-2); - border-radius: 100%; - justify-content: center; - align-items: center; - width: 2rem; - height: 2rem; - font-size: 1rem; - font-weight: 500; - line-height: 1; - display: inline-flex; - overflow: hidden; -} - -.canon-AvatarRoot[data-size="small"] { - width: 1.5rem; - height: 1.5rem; -} - -.canon-AvatarRoot[data-size="medium"] { - width: 2rem; - height: 2rem; -} - -.canon-AvatarRoot[data-size="large"] { - width: 3rem; - height: 3rem; -} - -.canon-AvatarImage { - object-fit: cover; - width: 100%; - height: 100%; -} - -.canon-AvatarFallback { - width: 100%; - height: 100%; - font-size: var(--canon-font-size-3); - font-weight: var(--canon-font-weight-regular); - box-shadow: inset 0 0 0 1px var(--canon-border); - border-radius: var(--canon-radius-full); - justify-content: center; - align-items: center; - display: flex; -} diff --git a/packages/canon/css/box.css b/packages/canon/css/box.css deleted file mode 100644 index 7a01d5aa3a..0000000000 --- a/packages/canon/css/box.css +++ /dev/null @@ -1,5 +0,0 @@ -.canon-Box { - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); -} diff --git a/packages/canon/css/button.css b/packages/canon/css/button.css deleted file mode 100644 index 7aaad3ec48..0000000000 --- a/packages/canon/css/button.css +++ /dev/null @@ -1,89 +0,0 @@ -.canon-Button { - user-select: none; - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-bold); - cursor: pointer; - border-radius: var(--canon-radius-2); - justify-content: center; - align-items: center; - gap: var(--canon-space-1_5); - border: none; - padding: 0; - display: inline-flex; - - &:disabled { - cursor: not-allowed; - } -} - -.canon-Button[data-variant="primary"] { - background-color: var(--canon-bg-solid); - color: var(--canon-fg-solid); - transition: background-color .15s, box-shadow .15s; - - &:hover { - background-color: var(--canon-bg-solid-hover); - } - - &:active { - background-color: var(--canon-bg-solid-pressed); - } - - &:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - } - - &:disabled { - background-color: var(--canon-bg-solid-disabled); - color: var(--canon-fg-solid-disabled); - } -} - -.canon-Button[data-variant="secondary"] { - background-color: var(--canon-bg-surface-1); - box-shadow: inset 0 0 0 1px var(--canon-border); - color: var(--canon-fg-primary); - transition: box-shadow .15s; - - &:hover { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - - &:active { - box-shadow: inset 0 0 0 1px var(--canon-border-pressed); - } - - &:focus-visible { - box-shadow: inset 0 0 0 2px var(--canon-ring); - outline: none; - transition: none; - } - - &:disabled { - box-shadow: inset 0 0 0 1px var(--canon-border-disabled); - color: var(--canon-fg-disabled); - } -} - -.canon-Button[data-size="medium"] { - font-size: var(--canon-font-size-4); - padding: 0 var(--canon-space-3); - height: 40px; -} - -.canon-Button[data-size="small"] { - font-size: var(--canon-font-size-3); - padding: 0 var(--canon-space-2); - height: 32px; -} - -.canon-ButtonIcon[data-size="small"], .canon-ButtonIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-ButtonIcon[data-size="medium"], .canon-ButtonIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} diff --git a/packages/canon/css/checkbox.css b/packages/canon/css/checkbox.css deleted file mode 100644 index f8a2cc32d5..0000000000 --- a/packages/canon/css/checkbox.css +++ /dev/null @@ -1,52 +0,0 @@ -.canon-CheckboxRoot { - width: 1rem; - height: 1rem; - box-shadow: inset 0 0 0 1px var(--canon-border); - cursor: pointer; - background-color: var(--canon-bg-surface-1); - border: none; - border-radius: 2px; - flex-shrink: 0; - justify-content: center; - align-items: center; - padding: 0; - transition: background-color .2s ease-in-out; - display: flex; -} - -.canon-CheckboxRoot:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - transition: none; -} - -.canon-CheckboxRoot[data-checked] { - background-color: var(--canon-bg-solid); - box-shadow: none; - color: var(--canon-fg-solid); -} - -.canon-CheckboxLabel { - align-items: center; - gap: var(--canon-space-2); - font-size: var(--canon-font-size-3); - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - user-select: none; - flex-direction: row; - display: flex; - - &:hover { - & .canon-CheckboxRoot:not([data-checked]) { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - } -} - -.canon-CheckboxIndicator { - color: var(--canon-fg-solid); - justify-content: center; - align-items: center; - display: flex; -} diff --git a/packages/canon/css/collapsible.css b/packages/canon/css/collapsible.css deleted file mode 100644 index e5508f1ecb..0000000000 --- a/packages/canon/css/collapsible.css +++ /dev/null @@ -1,10 +0,0 @@ -.canon-CollapsiblePanel { - height: var(--collapsible-panel-height); - transition: all .15s ease-out; - display: flex; - overflow: hidden; - - &[data-starting-style], &[data-ending-style] { - height: 0; - } -} diff --git a/packages/canon/css/components.css b/packages/canon/css/components.css deleted file mode 100644 index bcdbb86235..0000000000 --- a/packages/canon/css/components.css +++ /dev/null @@ -1,1303 +0,0 @@ -.canon-AvatarRoot { - vertical-align: middle; - user-select: none; - color: var(--canon-fg-primary); - background-color: var(--canon-bg-surface-2); - border-radius: 100%; - justify-content: center; - align-items: center; - width: 2rem; - height: 2rem; - font-size: 1rem; - font-weight: 500; - line-height: 1; - display: inline-flex; - overflow: hidden; -} - -.canon-AvatarRoot[data-size="small"] { - width: 1.5rem; - height: 1.5rem; -} - -.canon-AvatarRoot[data-size="medium"] { - width: 2rem; - height: 2rem; -} - -.canon-AvatarRoot[data-size="large"] { - width: 3rem; - height: 3rem; -} - -.canon-AvatarImage { - object-fit: cover; - width: 100%; - height: 100%; -} - -.canon-AvatarFallback { - width: 100%; - height: 100%; - font-size: var(--canon-font-size-3); - font-weight: var(--canon-font-weight-regular); - box-shadow: inset 0 0 0 1px var(--canon-border); - border-radius: var(--canon-radius-full); - justify-content: center; - align-items: center; - display: flex; -} - -.canon-Box { - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); -} - -.canon-Button { - user-select: none; - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-bold); - cursor: pointer; - border-radius: var(--canon-radius-2); - justify-content: center; - align-items: center; - gap: var(--canon-space-1_5); - border: none; - padding: 0; - display: inline-flex; - - &:disabled { - cursor: not-allowed; - } -} - -.canon-Button[data-variant="primary"] { - background-color: var(--canon-bg-solid); - color: var(--canon-fg-solid); - transition: background-color .15s, box-shadow .15s; - - &:hover { - background-color: var(--canon-bg-solid-hover); - } - - &:active { - background-color: var(--canon-bg-solid-pressed); - } - - &:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - } - - &:disabled { - background-color: var(--canon-bg-solid-disabled); - color: var(--canon-fg-solid-disabled); - } -} - -.canon-Button[data-variant="secondary"] { - background-color: var(--canon-bg-surface-1); - box-shadow: inset 0 0 0 1px var(--canon-border); - color: var(--canon-fg-primary); - transition: box-shadow .15s; - - &:hover { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - - &:active { - box-shadow: inset 0 0 0 1px var(--canon-border-pressed); - } - - &:focus-visible { - box-shadow: inset 0 0 0 2px var(--canon-ring); - outline: none; - transition: none; - } - - &:disabled { - box-shadow: inset 0 0 0 1px var(--canon-border-disabled); - color: var(--canon-fg-disabled); - } -} - -.canon-Button[data-size="medium"] { - font-size: var(--canon-font-size-4); - padding: 0 var(--canon-space-3); - height: 40px; -} - -.canon-Button[data-size="small"] { - font-size: var(--canon-font-size-3); - padding: 0 var(--canon-space-2); - height: 32px; -} - -.canon-ButtonIcon[data-size="small"], .canon-ButtonIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-ButtonIcon[data-size="medium"], .canon-ButtonIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} - -.canon-CollapsiblePanel { - height: var(--collapsible-panel-height); - transition: all .15s ease-out; - display: flex; - overflow: hidden; - - &[data-starting-style], &[data-ending-style] { - height: 0; - } -} - -.canon-DataTableRoot { - gap: var(--canon-space-3); - flex-direction: column; - display: flex; -} - -.canon-DataTablePagination { - padding-top: var(--canon-space-5); - justify-content: space-between; - align-items: center; - display: flex; -} - -.canon-DataTablePagination--left { - justify-content: space-between; - align-items: center; - display: flex; -} - -.canon-DataTablePagination--right { - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - display: flex; -} - -.canon-DataTablePagination--select { - min-width: 10.5rem; -} - -.canon-Flex { - min-width: 0; - display: flex; -} - -.canon-Grid { - display: grid; -} - -.canon-Container { - max-width: 120rem; - padding-inline: var(--canon-space-4); - margin-inline: auto; - transition: padding .2s ease-in-out; -} - -@media (width >= 640px) { - .canon-Container { - padding-inline: var(--canon-space-8); - } -} - -@media (width >= 1024px) { - .canon-Container { - padding-inline: var(--canon-space-12); - } -} - -.canon-Icon { - width: 1rem; - height: 1rem; -} - -.canon-CheckboxRoot { - width: 1rem; - height: 1rem; - box-shadow: inset 0 0 0 1px var(--canon-border); - cursor: pointer; - background-color: var(--canon-bg-surface-1); - border: none; - border-radius: 2px; - flex-shrink: 0; - justify-content: center; - align-items: center; - padding: 0; - transition: background-color .2s ease-in-out; - display: flex; -} - -.canon-CheckboxRoot:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - transition: none; -} - -.canon-CheckboxRoot[data-checked] { - background-color: var(--canon-bg-solid); - box-shadow: none; - color: var(--canon-fg-solid); -} - -.canon-CheckboxLabel { - align-items: center; - gap: var(--canon-space-2); - font-size: var(--canon-font-size-3); - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - user-select: none; - flex-direction: row; - display: flex; - - &:hover { - & .canon-CheckboxRoot:not([data-checked]) { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - } -} - -.canon-CheckboxIndicator { - color: var(--canon-fg-solid); - justify-content: center; - align-items: center; - display: flex; -} - -.canon-TableRoot { - caption-side: bottom; - border-collapse: collapse; - width: 100%; -} - -.canon-TableHead { - text-align: left; - padding: var(--canon-space-3); - font-size: var(--canon-font-size-3); - color: var(--canon-fg-primary); -} - -.canon-TableBody { - color: var(--canon-fg-primary); -} - -.canon-TableRow { - border-bottom: 1px solid var(--canon-border); - transition: color .2s ease-in-out; -} - -.canon-TableBody .canon-TableRow:hover { - background-color: var(--canon-gray-2); -} - -.canon-TableCell { - padding: var(--canon-space-3); - font-size: var(--canon-font-size-3); -} - -.canon-TableCellText, .canon-TableCellLink { - gap: var(--canon-space-0_5); - flex-direction: column; - display: flex; -} - -.canon-TableCellProfile { - gap: var(--canon-space-2); - flex-direction: row; - align-items: center; - display: flex; -} - -.canon-TableCellProfileAvatar { - vertical-align: middle; - user-select: none; - color: var(--canon-fg-primary); - background-color: var(--canon-bg-surface-2); - border-radius: 100%; - justify-content: center; - align-items: center; - width: 1.25rem; - height: 1.25rem; - font-size: 1rem; - font-weight: 500; - line-height: 1; - display: inline-flex; - overflow: hidden; -} - -.canon-TableCellProfileAvatarImage { - object-fit: cover; - width: 100%; - height: 100%; -} - -.canon-TableCellProfileAvatarFallback { - width: 100%; - height: 100%; - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - box-shadow: inset 0 0 0 1px var(--canon-border); - border-radius: var(--canon-radius-full); - justify-content: center; - align-items: center; - display: flex; -} - -.canon-TabsRoot { - border: 1px solid var(--color-gray-200); - border-radius: .375rem; -} - -.canon-TabsList { - z-index: 0; - display: flex; - position: relative; -} - -.canon-TabsTab { - appearance: none; - color: var(--canon-fg-secondary); - user-select: none; - padding-inline: var(--canon-space-3); - height: 2rem; - font-family: inherit; - font-size: .875rem; - font-weight: 500; - line-height: 1.25rem; - font-size: var(--canon-font-size-2); - cursor: pointer; - background: none; - border: 0; - outline: 0; - justify-content: center; - align-items: center; - margin: 0; - padding-block: 0; - transition: color .2s ease-in-out; - display: flex; - - &[data-selected] { - color: var(--canon-fg-primary); - } - - @media (hover: hover) { - &:hover { - color: var(--canon-fg-primary); - } - } - - &:focus-visible { - position: relative; - - &:before { - content: ""; - outline: 1px solid var(--canon-ring); - outline-offset: -1px; - border-radius: .25rem; - position: absolute; - inset: .25rem 0; - } - } -} - -.canon-TabsIndicator { - z-index: -1; - translate: var(--active-tab-left) -50%; - width: var(--active-tab-width); - background-color: var(--canon-bg-solid); - height: 1px; - transition-property: translate, width; - transition-duration: .2s; - transition-timing-function: ease-in-out; - position: absolute; - bottom: 0; - left: 0; -} - -.canon-TabsPanel { - &[hidden] { - display: none; - } -} - -.canon-Text { - font-family: var(--canon-font-regular); - margin: 0; - padding: 0; -} - -.canon-Text[data-variant="body"] { - font-size: var(--canon-font-size-3); - line-height: 140%; -} - -.canon-Text[data-variant="subtitle"] { - font-size: var(--canon-font-size-4); - line-height: 140%; -} - -.canon-Text[data-variant="caption"] { - font-size: var(--canon-font-size-2); - line-height: 140%; -} - -.canon-Text[data-variant="label"] { - font-size: var(--canon-font-size-1); - line-height: 140%; -} - -.canon-Text[data-weight="regular"] { - font-weight: var(--canon-font-weight-regular); -} - -.canon-Text[data-weight="bold"] { - font-weight: var(--canon-font-weight-bold); -} - -.canon-Text[data-color="primary"] { - color: var(--canon-fg-primary); -} - -.canon-Text[data-color="secondary"] { - color: var(--canon-fg-secondary); -} - -.canon-Text[data-color="danger"] { - color: var(--canon-fg-danger); -} - -.canon-Text[data-color="warning"] { - color: var(--canon-fg-warning); -} - -.canon-Text[data-color="success"] { - color: var(--canon-fg-success); -} - -.canon-Text[data-truncate] { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} - -.canon-Heading { - font-family: var(--canon-font-regular); - color: var(--canon-fg-primary); - margin: 0; - padding: 0; - line-height: 100%; -} - -.canon-Heading[data-variant="display"] { - font-size: var(--canon-font-size-10); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title1"] { - font-size: var(--canon-font-size-9); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title2"] { - font-size: var(--canon-font-size-8); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title3"] { - font-size: var(--canon-font-size-7); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title4"] { - font-size: var(--canon-font-size-6); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title5"] { - font-size: var(--canon-font-size-5); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-color="primary"] { - color: var(--canon-fg-primary); -} - -.canon-Heading[data-color="secondary"] { - color: var(--canon-fg-secondary); -} - -.canon-Heading[data-truncate] { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} - -.canon-IconButton { - user-select: none; - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-bold); - cursor: pointer; - border-radius: var(--canon-radius-2); - justify-content: center; - align-items: center; - gap: var(--canon-space-1_5); - border: none; - padding: 0; - display: inline-flex; - - &:disabled { - cursor: not-allowed; - } -} - -.canon-IconButton[data-variant="primary"] { - background-color: var(--canon-bg-solid); - color: var(--canon-fg-solid); - transition: background-color .15s, box-shadow .15s; - - &:hover { - background-color: var(--canon-bg-solid-hover); - } - - &:active { - background-color: var(--canon-bg-solid-pressed); - } - - &:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - } - - &:disabled { - background-color: var(--canon-bg-solid-disabled); - color: var(--canon-fg-solid-disabled); - } -} - -.canon-IconButton[data-variant="secondary"] { - background-color: var(--canon-bg-surface-1); - box-shadow: inset 0 0 0 1px var(--canon-border); - color: var(--canon-fg-primary); - transition: box-shadow .15s; - - &:hover { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - - &:active { - box-shadow: inset 0 0 0 1px var(--canon-border-pressed); - } - - &:focus-visible { - box-shadow: inset 0 0 0 2px var(--canon-ring); - outline: none; - transition: none; - } - - &:disabled { - box-shadow: inset 0 0 0 1px var(--canon-border-disabled); - color: var(--canon-fg-disabled); - } -} - -.canon-IconButton[data-size="medium"] { - font-size: var(--canon-font-size-4); - width: 40px; - height: 40px; -} - -.canon-IconButton[data-size="small"] { - font-size: var(--canon-font-size-3); - width: 32px; - height: 32px; -} - -.canon-IconButtonIcon[data-size="small"], .canon-IconButtonIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-IconButtonIcon[data-size="medium"], .canon-IconButtonIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} - -.canon-TextField { - font-family: var(--canon-font-regular); - flex-direction: column; - width: 100%; - display: flex; -} - -.canon-TextFieldLabel { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - margin-bottom: var(--canon-space-1_5); - cursor: pointer; - margin-right: auto; -} - -.canon-TextFieldLabel[data-disabled] { - cursor: default; -} - -.canon-TextFieldDescription { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-secondary); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-TextFieldError { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-danger); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-TextFieldInputWrapper { - padding: 0 var(--canon-space-3); - border-radius: var(--canon-radius-3); - border: 1px solid var(--canon-border); - background-color: var(--canon-bg-surface-1); - align-items: center; - display: flex; -} - -.canon-TextFieldIcon { - margin-right: var(--canon-space-1); - color: var(--canon-fg-primary); - flex-shrink: 0; -} - -.canon-TextFieldIcon[data-size="small"], .canon-TextFieldIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-TextFieldIcon[data-size="medium"], .canon-TextFieldIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} - -.canon-TextFieldInput { - font-size: var(--canon-font-size-3); - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - width: 100%; - height: 100%; - cursor: inherit; - background: none; - border: none; - padding: 0; - transition: border-color .2s ease-in-out, outline-color .2s ease-in-out; -} - -.canon-TextFieldInput:not([data-filled]):has( + .canon-TextFieldClearButton) { - padding-right: 1.25rem; -} - -.canon-TextFieldInput[type="search"]::-webkit-search-cancel-button, .canon-TextFieldInput[type="search"]::-webkit-search-decoration { - appearance: none; -} - -.canon-TextFieldClearButton { - margin-left: var(--canon-space-1); - vertical-align: middle; - color: var(--canon-fg-primary); - background: none; - border: none; - padding: 0; - display: none; -} - -.canon-TextFieldInput[data-filled] + .canon-TextFieldClearButton { - display: inline-block; -} - -.canon-TextFieldClearButtonIcon { - display: block; -} - -.canon-TextFieldInput::placeholder { - color: var(--canon-fg-secondary); -} - -.canon-TextFieldInput[data-focused] { - outline-color: var(--canon-border-pressed); - outline-width: 0; -} - -.canon-TextFieldInputWrapper:has( > .canon-TextFieldInput:hover) { - border-color: var(--canon-border-hover); -} - -.canon-TextField[data-focused] .canon-TextFieldInputWrapper { - border-color: var(--canon-border-pressed); -} - -.canon-TextField[data-invalid] .canon-TextFieldInputWrapper { - border-color: var(--canon-fg-danger); -} - -.canon-TextField[data-disabled] .canon-TextFieldInputWrapper { - opacity: .5; - cursor: not-allowed; - border: 1px solid var(--canon-border-disabled); -} - -.canon-TextField[data-disabled] .canon-TextFieldClearButton { - cursor: inherit; -} - -.canon-TextFieldInputWrapper[data-size="small"] { - height: 2rem; -} - -.canon-TextFieldInputWrapper[data-size="medium"] { - height: 2.5rem; -} - -.canon-TextFieldRequired { - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - margin-left: var(--canon-space-1); -} - -.canon-MenuPositioner { - outline: 0; -} - -.canon-MenuPopup { - background-color: var(--canon-bg-surface-1); - border: 1px solid var(--canon-border); - color: var(--canon-fg-primary); - transform-origin: var(--transform-origin); - max-width: min(var(--available-width), 340px); - max-height: min(var(--available-height), 500px); - padding-bottom: var(--canon-space-1); - border-radius: .375rem; - outline: none; - flex-direction: column; - transition: transform .15s, opacity .15s; - display: flex; - position: relative; - overflow: auto; - - &[data-starting-style], &[data-ending-style] { - opacity: 0; - transform: scale(.9); - } -} - -.canon-MenuItem { - user-select: none; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - &:first-child { - margin-top: var(--canon-space-1); - } - - &[data-highlighted] { - background-color: var(--canon-gray-3); - } -} - -.canon-MenuSubmenuTrigger { - user-select: none; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - & .canon-Icon { - color: var(--canon-fg-secondary); - } - - &:first-child { - margin-top: var(--canon-space-1); - } - - &[data-popup-open], &[data-highlighted] { - background-color: var(--canon-gray-3); - - & .canon-Icon { - color: var(--canon-fg-primary); - } - } -} - -.canon-MenuSeparator { - background-color: var(--color-gray-200); - height: 1px; - margin: .375rem 1rem; -} - -.canon-SubmenuComboboxSearch { - padding-inline: var(--canon-space-3); - border: none; - border-bottom: 1px solid var(--canon-border); - background-color: var(--canon-bg-surface-1); - height: 32px; - color: var(--canon-fg-primary); - line-height: 140%; - font-size: var(--canon-font-size-3); - z-index: 1; - outline: none; - position: sticky; - top: 0; - - &::placeholder { - color: var(--canon-fg-secondary); - } - - &:disabled { - opacity: .6; - cursor: not-allowed; - } -} - -.canon-SubmenuComboboxItems { - padding-top: var(--canon-space-2); - outline: none; - flex-direction: column; - display: flex; - overflow-y: auto; -} - -.canon-SubmenuComboboxNoResults { - padding-inline: var(--canon-space-3); - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-4); - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-3); -} - -.canon-SubmenuComboboxItem { - user-select: none; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - &[data-highlighted] { - background-color: var(--canon-gray-3); - } - - &[data-disabled] { - opacity: .5; - cursor: not-allowed; - } -} - -.canon-SubmenuComboboxItemCheckbox { - width: 16px; - height: 16px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - border: 1px solid var(--canon-border); - background: var(--canon-bg-surface-1); - flex-shrink: 0; - justify-content: center; - align-items: center; - display: flex; -} - -.canon-SubmenuComboboxItemLabel { - text-overflow: ellipsis; - white-space: nowrap; - flex: 1; - overflow: hidden; -} - -.canon-Link { - font-family: var(--canon-font-regular); - color: var(--canon-fg-link); - cursor: pointer; - margin: 0; - padding: 0; - text-decoration-line: none; - - &:hover { - color: var(--canon-fg-link-hover); - text-underline-offset: calc(.025em + 2px); - text-decoration-line: underline; - text-decoration-style: solid; - text-decoration-thickness: min(2px, max(1px, .05em)); - text-decoration-color: color-mix(in srgb, var(--canon-fg-link-hover) 30%, transparent); - } -} - -.canon-Link[data-variant="body"] { - font-size: var(--canon-font-size-3); - line-height: 140%; -} - -.canon-Link[data-variant="subtitle"] { - font-size: var(--canon-font-size-4); - line-height: 140%; -} - -.canon-Link[data-variant="caption"] { - font-size: var(--canon-font-size-2); - line-height: 140%; -} - -.canon-Link[data-variant="label"] { - font-size: var(--canon-font-size-1); - line-height: 140%; -} - -.canon-Link[data-weight="regular"] { - font-weight: var(--canon-font-weight-regular); -} - -.canon-Link[data-weight="bold"] { - font-weight: var(--canon-font-weight-bold); -} - -.canon-TooltipPopup { - box-sizing: border-box; - transform-origin: var(--transform-origin); - background-color: canvas; - background-color: var(--canon-bg-surface-1); - color: var(--canon-fg-primary); - outline: 1px solid var(--canon-border); - box-shadow: 0 10px 15px -3px var(--canon-border), 0 4px 6px -4px var(--canon-border); - border-radius: .375rem; - flex-direction: column; - padding: .25rem .5rem; - font-size: .875rem; - line-height: 1.25rem; - transition: transform .15s, opacity .15s; - display: flex; - - &[data-starting-style], &[data-ending-style] { - opacity: 0; - transform: scale(.9); - } - - &[data-instant] { - transition-duration: 0s; - } -} - -.canon-TooltipArrow { - display: flex; - - &[data-side="top"] { - bottom: -8px; - rotate: 180deg; - } - - &[data-side="bottom"] { - top: -8px; - rotate: none; - } - - &[data-side="left"] { - right: -13px; - rotate: 90deg; - } - - &[data-side="right"] { - left: -13px; - rotate: -90deg; - } -} - -.canon-TooltipArrow-fill { - fill: var(--canon-bg-surface-1); -} - -.canon-TooltipArrow-outer-stroke { - @media (prefers-color-scheme: light) { - & { - fill: var(--canon-border); - } - } -} - -.canon-ScrollAreaRoot { - box-sizing: border-box; - width: 24rem; - max-width: calc(100vw - 8rem); - height: 8.5rem; -} - -.canon-ScrollAreaViewport { - overscroll-behavior: contain; - height: 100%; -} - -.canon-ScrollAreaContent { - padding-block: .75rem; - flex-direction: column; - gap: 1rem; - padding-left: 1rem; - padding-right: 1.5rem; - display: flex; -} - -.canon-ScrollAreaScrollbar { - background-color: var(--canon-scrollbar); - opacity: 0; - border-radius: .375rem; - justify-content: center; - width: .25rem; - margin: .5rem; - transition: opacity .15s .3s; - display: flex; - - &[data-hovering], &[data-scrolling] { - opacity: 1; - transition-duration: 75ms; - transition-delay: 0s; - } - - &:before { - content: ""; - width: 1.25rem; - height: 100%; - position: absolute; - } -} - -.canon-ScrollAreaThumb { - border-radius: inherit; - background-color: var(--canon-scrollbar-thumb); - width: 100%; -} - -.canon-Select { - font-family: var(--canon-font-regular); - flex-direction: column; - width: 100%; - display: flex; -} - -.canon-SelectLabel { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - margin-bottom: var(--canon-space-1_5); - cursor: pointer; -} - -.canon-SelectLabel[data-disabled] { - cursor: default; -} - -.canon-SelectDescription { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-secondary); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-SelectError { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-danger); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-SelectTrigger { - box-sizing: border-box; - border-radius: var(--canon-radius-3); - border: 1px solid var(--canon-border); - padding: 0 var(--canon-space-4); - background-color: var(--canon-bg-surface-1); - font-size: var(--canon-font-size-3); - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - cursor: pointer; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - width: 100%; - transition: border-color .2s ease-in-out, outline-color .2s ease-in-out; - display: flex; -} - -.canon-SelectTrigger::placeholder { - color: var(--canon-fg-secondary); -} - -.canon-SelectTrigger:hover { - border-color: var(--canon-border-hover); -} - -.canon-SelectTrigger:focus-visible { - border-color: var(--canon-border-pressed); - outline: 0; -} - -.canon-SelectTrigger[data-invalid] { - border-color: var(--canon-fg-danger); -} - -.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible { - border-width: 2px; -} - -.canon-SelectTrigger[data-disabled] { - cursor: not-allowed; - border-color: var(--canon-border-disabled); - color: var(--canon-fg-disabled); -} - -.canon-SelectTrigger[data-size="small"] { - height: 2rem; -} - -.canon-SelectTrigger[data-size="medium"] { - height: 3rem; -} - -.canon-SelectIcon { - margin-left: var(--canon-space-5); - transition: transform .2s; -} - -.canon-SelectTrigger[data-popup-open] .canon-SelectIcon { - transform: rotate(180deg); -} - -.canon-SelectPopup { - box-sizing: border-box; - max-height: var(--available-height); - background-color: var(--canon-bg-surface-1); - border: 1px solid var(--canon-border); - border-radius: var(--canon-radius-3); - padding-block: var(--canon-space-1); - z-index: 1; - transform-origin: var(--transform-origin); - outline: 0; - transition: transform .15s, opacity .15s; - overflow-y: auto; - box-shadow: 0 4px 12px #0003; -} - -.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] { - opacity: 0; - transform: scale(.9); -} - -.canon-SelectItem { - width: var(--anchor-width); - padding-block: var(--canon-space-2); - padding-inline: var(--canon-space-4); - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-3); - cursor: pointer; - user-select: none; - font-size: var(--canon-font-size-3); - align-items: center; - gap: var(--canon-space-2); - outline: none; - grid-template-columns: 1rem 1fr; - grid-template-areas: "icon text"; - display: grid; - position: relative; -} - -.canon-SelectItem[data-highlighted] { - z-index: 0; - color: var(--canon-fg-primary); - position: relative; -} - -.canon-SelectItem[data-highlighted]:before { - content: ""; - z-index: -1; - background-color: var(--canon-bg-tint-hover); - border-radius: .25rem; - position: absolute; - inset-block: 0; - inset-inline: .25rem; -} - -.canon-SelectItem[data-disabled] { - cursor: not-allowed; - color: var(--canon-fg-disabled); -} - -.canon-SelectItemIndicator { - grid-area: icon; - justify-content: center; - align-items: center; - display: flex; -} - -.canon-SelectItemText { - flex: 1; - grid-area: text; -} - -.canon-SelectRequired { - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - margin-left: var(--canon-space-1); -} - -.canon-SelectIcon { - justify-content: center; - align-items: center; - display: flex; -} - -.canon-SelectValue { - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; - overflow: hidden; -} diff --git a/packages/canon/css/container.css b/packages/canon/css/container.css deleted file mode 100644 index 47744cce1e..0000000000 --- a/packages/canon/css/container.css +++ /dev/null @@ -1,18 +0,0 @@ -.canon-Container { - max-width: 120rem; - padding-inline: var(--canon-space-4); - margin-inline: auto; - transition: padding .2s ease-in-out; -} - -@media (width >= 640px) { - .canon-Container { - padding-inline: var(--canon-space-8); - } -} - -@media (width >= 1024px) { - .canon-Container { - padding-inline: var(--canon-space-12); - } -} diff --git a/packages/canon/css/core.css b/packages/canon/css/core.css deleted file mode 100644 index ffdde83d72..0000000000 --- a/packages/canon/css/core.css +++ /dev/null @@ -1,9223 +0,0 @@ -/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */ -@layer base { - *, :before, :after { - box-sizing: border-box; - } - - html { - -webkit-text-size-adjust: 100%; - tab-size: 4; - font-family: system-ui, Segoe UI, Roboto, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; - line-height: 1.15; - } - - body { - margin: 0; - } - - b, strong { - font-weight: bolder; - } - - code, kbd, samp, pre { - font-family: ui-monospace, SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace; - font-size: 1em; - } - - small { - font-size: 80%; - } - - sub, sup { - vertical-align: baseline; - font-size: 75%; - line-height: 0; - position: relative; - } - - sub { - bottom: -.25em; - } - - sup { - top: -.5em; - } - - table { - border-color: currentColor; - } - - button, input, optgroup, select, textarea { - margin: 0; - font-family: inherit; - font-size: 100%; - line-height: 1.15; - } - - button, [type="button"], [type="reset"], [type="submit"] { - -webkit-appearance: button; - } - - legend { - padding: 0; - } - - progress { - vertical-align: baseline; - } - - ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { - height: auto; - } - - [type="search"] { - -webkit-appearance: textfield; - outline-offset: -2px; - } - - ::-webkit-search-decoration { - -webkit-appearance: none; - } - - ::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; - } - - summary { - display: list-item; - } -} - -.cu-p { - padding: var(--p); -} - -.cu-p-0\.5 { - padding: var(--canon-space-0_5); -} - -.cu-p-1 { - padding: var(--canon-space-1); -} - -.cu-p-1\.5 { - padding: var(--canon-space-1_5); -} - -.cu-p-2 { - padding: var(--canon-space-2); -} - -.cu-p-3 { - padding: var(--canon-space-3); -} - -.cu-p-4 { - padding: var(--canon-space-4); -} - -.cu-p-5 { - padding: var(--canon-space-5); -} - -.cu-p-6 { - padding: var(--canon-space-6); -} - -.cu-p-7 { - padding: var(--canon-space-7); -} - -.cu-p-8 { - padding: var(--canon-space-8); -} - -.cu-p-9 { - padding: var(--canon-space-9); -} - -.cu-p-10 { - padding: var(--canon-space-10); -} - -.cu-p-11 { - padding: var(--canon-space-11); -} - -.cu-p-12 { - padding: var(--canon-space-12); -} - -.cu-p-13 { - padding: var(--canon-space-13); -} - -.cu-p-14 { - padding: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-p { - padding: var(--p-xs); - } - - .xs\:cu-p-0\.5 { - padding: var(--canon-space-0_5); - } - - .xs\:cu-p-1 { - padding: var(--canon-space-1); - } - - .xs\:cu-p-1\.5 { - padding: var(--canon-space-1_5); - } - - .xs\:cu-p-2 { - padding: var(--canon-space-2); - } - - .xs\:cu-p-3 { - padding: var(--canon-space-3); - } - - .xs\:cu-p-4 { - padding: var(--canon-space-4); - } - - .xs\:cu-p-5 { - padding: var(--canon-space-5); - } - - .xs\:cu-p-6 { - padding: var(--canon-space-6); - } - - .xs\:cu-p-7 { - padding: var(--canon-space-7); - } - - .xs\:cu-p-8 { - padding: var(--canon-space-8); - } - - .xs\:cu-p-9 { - padding: var(--canon-space-9); - } - - .xs\:cu-p-10 { - padding: var(--canon-space-10); - } - - .xs\:cu-p-11 { - padding: var(--canon-space-11); - } - - .xs\:cu-p-12 { - padding: var(--canon-space-12); - } - - .xs\:cu-p-13 { - padding: var(--canon-space-13); - } - - .xs\:cu-p-14 { - padding: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-p { - padding: var(--p-sm); - } - - .sm\:cu-p-0\.5 { - padding: var(--canon-space-0_5); - } - - .sm\:cu-p-1 { - padding: var(--canon-space-1); - } - - .sm\:cu-p-1\.5 { - padding: var(--canon-space-1_5); - } - - .sm\:cu-p-2 { - padding: var(--canon-space-2); - } - - .sm\:cu-p-3 { - padding: var(--canon-space-3); - } - - .sm\:cu-p-4 { - padding: var(--canon-space-4); - } - - .sm\:cu-p-5 { - padding: var(--canon-space-5); - } - - .sm\:cu-p-6 { - padding: var(--canon-space-6); - } - - .sm\:cu-p-7 { - padding: var(--canon-space-7); - } - - .sm\:cu-p-8 { - padding: var(--canon-space-8); - } - - .sm\:cu-p-9 { - padding: var(--canon-space-9); - } - - .sm\:cu-p-10 { - padding: var(--canon-space-10); - } - - .sm\:cu-p-11 { - padding: var(--canon-space-11); - } - - .sm\:cu-p-12 { - padding: var(--canon-space-12); - } - - .sm\:cu-p-13 { - padding: var(--canon-space-13); - } - - .sm\:cu-p-14 { - padding: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-p { - padding: var(--p-md); - } - - .md\:cu-p-0\.5 { - padding: var(--canon-space-0_5); - } - - .md\:cu-p-1 { - padding: var(--canon-space-1); - } - - .md\:cu-p-1\.5 { - padding: var(--canon-space-1_5); - } - - .md\:cu-p-2 { - padding: var(--canon-space-2); - } - - .md\:cu-p-3 { - padding: var(--canon-space-3); - } - - .md\:cu-p-4 { - padding: var(--canon-space-4); - } - - .md\:cu-p-5 { - padding: var(--canon-space-5); - } - - .md\:cu-p-6 { - padding: var(--canon-space-6); - } - - .md\:cu-p-7 { - padding: var(--canon-space-7); - } - - .md\:cu-p-8 { - padding: var(--canon-space-8); - } - - .md\:cu-p-9 { - padding: var(--canon-space-9); - } - - .md\:cu-p-10 { - padding: var(--canon-space-10); - } - - .md\:cu-p-11 { - padding: var(--canon-space-11); - } - - .md\:cu-p-12 { - padding: var(--canon-space-12); - } - - .md\:cu-p-13 { - padding: var(--canon-space-13); - } - - .md\:cu-p-14 { - padding: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-p { - padding: var(--p-lg); - } - - .lg\:cu-p-0\.5 { - padding: var(--canon-space-0_5); - } - - .lg\:cu-p-1 { - padding: var(--canon-space-1); - } - - .lg\:cu-p-1\.5 { - padding: var(--canon-space-1_5); - } - - .lg\:cu-p-2 { - padding: var(--canon-space-2); - } - - .lg\:cu-p-3 { - padding: var(--canon-space-3); - } - - .lg\:cu-p-4 { - padding: var(--canon-space-4); - } - - .lg\:cu-p-5 { - padding: var(--canon-space-5); - } - - .lg\:cu-p-6 { - padding: var(--canon-space-6); - } - - .lg\:cu-p-7 { - padding: var(--canon-space-7); - } - - .lg\:cu-p-8 { - padding: var(--canon-space-8); - } - - .lg\:cu-p-9 { - padding: var(--canon-space-9); - } - - .lg\:cu-p-10 { - padding: var(--canon-space-10); - } - - .lg\:cu-p-11 { - padding: var(--canon-space-11); - } - - .lg\:cu-p-12 { - padding: var(--canon-space-12); - } - - .lg\:cu-p-13 { - padding: var(--canon-space-13); - } - - .lg\:cu-p-14 { - padding: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-p { - padding: var(--p-xl); - } - - .xl\:cu-p-0\.5 { - padding: var(--canon-space-0_5); - } - - .xl\:cu-p-1 { - padding: var(--canon-space-1); - } - - .xl\:cu-p-1\.5 { - padding: var(--canon-space-1_5); - } - - .xl\:cu-p-2 { - padding: var(--canon-space-2); - } - - .xl\:cu-p-3 { - padding: var(--canon-space-3); - } - - .xl\:cu-p-4 { - padding: var(--canon-space-4); - } - - .xl\:cu-p-5 { - padding: var(--canon-space-5); - } - - .xl\:cu-p-6 { - padding: var(--canon-space-6); - } - - .xl\:cu-p-7 { - padding: var(--canon-space-7); - } - - .xl\:cu-p-8 { - padding: var(--canon-space-8); - } - - .xl\:cu-p-9 { - padding: var(--canon-space-9); - } - - .xl\:cu-p-10 { - padding: var(--canon-space-10); - } - - .xl\:cu-p-11 { - padding: var(--canon-space-11); - } - - .xl\:cu-p-12 { - padding: var(--canon-space-12); - } - - .xl\:cu-p-13 { - padding: var(--canon-space-13); - } - - .xl\:cu-p-14 { - padding: var(--canon-space-14); - } -} - -.cu-pl { - padding-left: var(--pl); -} - -.cu-pl-0\.5 { - padding-left: var(--canon-space-0_5); -} - -.cu-pl-1 { - padding-left: var(--canon-space-1); -} - -.cu-pl-1\.5 { - padding-left: var(--canon-space-1_5); -} - -.cu-pl-2 { - padding-left: var(--canon-space-2); -} - -.cu-pl-3 { - padding-left: var(--canon-space-3); -} - -.cu-pl-4 { - padding-left: var(--canon-space-4); -} - -.cu-pl-5 { - padding-left: var(--canon-space-5); -} - -.cu-pl-6 { - padding-left: var(--canon-space-6); -} - -.cu-pl-7 { - padding-left: var(--canon-space-7); -} - -.cu-pl-8 { - padding-left: var(--canon-space-8); -} - -.cu-pl-9 { - padding-left: var(--canon-space-9); -} - -.cu-pl-10 { - padding-left: var(--canon-space-10); -} - -.cu-pl-11 { - padding-left: var(--canon-space-11); -} - -.cu-pl-12 { - padding-left: var(--canon-space-12); -} - -.cu-pl-13 { - padding-left: var(--canon-space-13); -} - -.cu-pl-14 { - padding-left: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-pl { - padding-left: var(--pl-xs); - } - - .xs\:cu-pl-0\.5 { - padding-left: var(--canon-space-0_5); - } - - .xs\:cu-pl-1 { - padding-left: var(--canon-space-1); - } - - .xs\:cu-pl-1\.5 { - padding-left: var(--canon-space-1_5); - } - - .xs\:cu-pl-2 { - padding-left: var(--canon-space-2); - } - - .xs\:cu-pl-3 { - padding-left: var(--canon-space-3); - } - - .xs\:cu-pl-4 { - padding-left: var(--canon-space-4); - } - - .xs\:cu-pl-5 { - padding-left: var(--canon-space-5); - } - - .xs\:cu-pl-6 { - padding-left: var(--canon-space-6); - } - - .xs\:cu-pl-7 { - padding-left: var(--canon-space-7); - } - - .xs\:cu-pl-8 { - padding-left: var(--canon-space-8); - } - - .xs\:cu-pl-9 { - padding-left: var(--canon-space-9); - } - - .xs\:cu-pl-10 { - padding-left: var(--canon-space-10); - } - - .xs\:cu-pl-11 { - padding-left: var(--canon-space-11); - } - - .xs\:cu-pl-12 { - padding-left: var(--canon-space-12); - } - - .xs\:cu-pl-13 { - padding-left: var(--canon-space-13); - } - - .xs\:cu-pl-14 { - padding-left: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-pl { - padding-left: var(--pl-sm); - } - - .sm\:cu-pl-0\.5 { - padding-left: var(--canon-space-0_5); - } - - .sm\:cu-pl-1 { - padding-left: var(--canon-space-1); - } - - .sm\:cu-pl-1\.5 { - padding-left: var(--canon-space-1_5); - } - - .sm\:cu-pl-2 { - padding-left: var(--canon-space-2); - } - - .sm\:cu-pl-3 { - padding-left: var(--canon-space-3); - } - - .sm\:cu-pl-4 { - padding-left: var(--canon-space-4); - } - - .sm\:cu-pl-5 { - padding-left: var(--canon-space-5); - } - - .sm\:cu-pl-6 { - padding-left: var(--canon-space-6); - } - - .sm\:cu-pl-7 { - padding-left: var(--canon-space-7); - } - - .sm\:cu-pl-8 { - padding-left: var(--canon-space-8); - } - - .sm\:cu-pl-9 { - padding-left: var(--canon-space-9); - } - - .sm\:cu-pl-10 { - padding-left: var(--canon-space-10); - } - - .sm\:cu-pl-11 { - padding-left: var(--canon-space-11); - } - - .sm\:cu-pl-12 { - padding-left: var(--canon-space-12); - } - - .sm\:cu-pl-13 { - padding-left: var(--canon-space-13); - } - - .sm\:cu-pl-14 { - padding-left: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-pl { - padding-left: var(--pl-md); - } - - .md\:cu-pl-0\.5 { - padding-left: var(--canon-space-0_5); - } - - .md\:cu-pl-1 { - padding-left: var(--canon-space-1); - } - - .md\:cu-pl-1\.5 { - padding-left: var(--canon-space-1_5); - } - - .md\:cu-pl-2 { - padding-left: var(--canon-space-2); - } - - .md\:cu-pl-3 { - padding-left: var(--canon-space-3); - } - - .md\:cu-pl-4 { - padding-left: var(--canon-space-4); - } - - .md\:cu-pl-5 { - padding-left: var(--canon-space-5); - } - - .md\:cu-pl-6 { - padding-left: var(--canon-space-6); - } - - .md\:cu-pl-7 { - padding-left: var(--canon-space-7); - } - - .md\:cu-pl-8 { - padding-left: var(--canon-space-8); - } - - .md\:cu-pl-9 { - padding-left: var(--canon-space-9); - } - - .md\:cu-pl-10 { - padding-left: var(--canon-space-10); - } - - .md\:cu-pl-11 { - padding-left: var(--canon-space-11); - } - - .md\:cu-pl-12 { - padding-left: var(--canon-space-12); - } - - .md\:cu-pl-13 { - padding-left: var(--canon-space-13); - } - - .md\:cu-pl-14 { - padding-left: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-pl { - padding-left: var(--pl-lg); - } - - .lg\:cu-pl-0\.5 { - padding-left: var(--canon-space-0_5); - } - - .lg\:cu-pl-1 { - padding-left: var(--canon-space-1); - } - - .lg\:cu-pl-1\.5 { - padding-left: var(--canon-space-1_5); - } - - .lg\:cu-pl-2 { - padding-left: var(--canon-space-2); - } - - .lg\:cu-pl-3 { - padding-left: var(--canon-space-3); - } - - .lg\:cu-pl-4 { - padding-left: var(--canon-space-4); - } - - .lg\:cu-pl-5 { - padding-left: var(--canon-space-5); - } - - .lg\:cu-pl-6 { - padding-left: var(--canon-space-6); - } - - .lg\:cu-pl-7 { - padding-left: var(--canon-space-7); - } - - .lg\:cu-pl-8 { - padding-left: var(--canon-space-8); - } - - .lg\:cu-pl-9 { - padding-left: var(--canon-space-9); - } - - .lg\:cu-pl-10 { - padding-left: var(--canon-space-10); - } - - .lg\:cu-pl-11 { - padding-left: var(--canon-space-11); - } - - .lg\:cu-pl-12 { - padding-left: var(--canon-space-12); - } - - .lg\:cu-pl-13 { - padding-left: var(--canon-space-13); - } - - .lg\:cu-pl-14 { - padding-left: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-pl { - padding-left: var(--pl-xl); - } - - .xl\:cu-pl-0\.5 { - padding-left: var(--canon-space-0_5); - } - - .xl\:cu-pl-1 { - padding-left: var(--canon-space-1); - } - - .xl\:cu-pl-1\.5 { - padding-left: var(--canon-space-1_5); - } - - .xl\:cu-pl-2 { - padding-left: var(--canon-space-2); - } - - .xl\:cu-pl-3 { - padding-left: var(--canon-space-3); - } - - .xl\:cu-pl-4 { - padding-left: var(--canon-space-4); - } - - .xl\:cu-pl-5 { - padding-left: var(--canon-space-5); - } - - .xl\:cu-pl-6 { - padding-left: var(--canon-space-6); - } - - .xl\:cu-pl-7 { - padding-left: var(--canon-space-7); - } - - .xl\:cu-pl-8 { - padding-left: var(--canon-space-8); - } - - .xl\:cu-pl-9 { - padding-left: var(--canon-space-9); - } - - .xl\:cu-pl-10 { - padding-left: var(--canon-space-10); - } - - .xl\:cu-pl-11 { - padding-left: var(--canon-space-11); - } - - .xl\:cu-pl-12 { - padding-left: var(--canon-space-12); - } - - .xl\:cu-pl-13 { - padding-left: var(--canon-space-13); - } - - .xl\:cu-pl-14 { - padding-left: var(--canon-space-14); - } -} - -.cu-pr { - padding-right: var(--pr); -} - -.cu-pr-0\.5 { - padding-right: var(--canon-space-0_5); -} - -.cu-pr-1 { - padding-right: var(--canon-space-1); -} - -.cu-pr-1\.5 { - padding-right: var(--canon-space-1_5); -} - -.cu-pr-2 { - padding-right: var(--canon-space-2); -} - -.cu-pr-3 { - padding-right: var(--canon-space-3); -} - -.cu-pr-4 { - padding-right: var(--canon-space-4); -} - -.cu-pr-5 { - padding-right: var(--canon-space-5); -} - -.cu-pr-6 { - padding-right: var(--canon-space-6); -} - -.cu-pr-7 { - padding-right: var(--canon-space-7); -} - -.cu-pr-8 { - padding-right: var(--canon-space-8); -} - -.cu-pr-9 { - padding-right: var(--canon-space-9); -} - -.cu-pr-10 { - padding-right: var(--canon-space-10); -} - -.cu-pr-11 { - padding-right: var(--canon-space-11); -} - -.cu-pr-12 { - padding-right: var(--canon-space-12); -} - -.cu-pr-13 { - padding-right: var(--canon-space-13); -} - -.cu-pr-14 { - padding-right: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-pr { - padding-right: var(--pr-xs); - } - - .xs\:cu-pr-0\.5 { - padding-right: var(--canon-space-0_5); - } - - .xs\:cu-pr-1 { - padding-right: var(--canon-space-1); - } - - .xs\:cu-pr-1\.5 { - padding-right: var(--canon-space-1_5); - } - - .xs\:cu-pr-2 { - padding-right: var(--canon-space-2); - } - - .xs\:cu-pr-3 { - padding-right: var(--canon-space-3); - } - - .xs\:cu-pr-4 { - padding-right: var(--canon-space-4); - } - - .xs\:cu-pr-5 { - padding-right: var(--canon-space-5); - } - - .xs\:cu-pr-6 { - padding-right: var(--canon-space-6); - } - - .xs\:cu-pr-7 { - padding-right: var(--canon-space-7); - } - - .xs\:cu-pr-8 { - padding-right: var(--canon-space-8); - } - - .xs\:cu-pr-9 { - padding-right: var(--canon-space-9); - } - - .xs\:cu-pr-10 { - padding-right: var(--canon-space-10); - } - - .xs\:cu-pr-11 { - padding-right: var(--canon-space-11); - } - - .xs\:cu-pr-12 { - padding-right: var(--canon-space-12); - } - - .xs\:cu-pr-13 { - padding-right: var(--canon-space-13); - } - - .xs\:cu-pr-14 { - padding-right: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-pr { - padding-right: var(--pr-sm); - } - - .sm\:cu-pr-0\.5 { - padding-right: var(--canon-space-0_5); - } - - .sm\:cu-pr-1 { - padding-right: var(--canon-space-1); - } - - .sm\:cu-pr-1\.5 { - padding-right: var(--canon-space-1_5); - } - - .sm\:cu-pr-2 { - padding-right: var(--canon-space-2); - } - - .sm\:cu-pr-3 { - padding-right: var(--canon-space-3); - } - - .sm\:cu-pr-4 { - padding-right: var(--canon-space-4); - } - - .sm\:cu-pr-5 { - padding-right: var(--canon-space-5); - } - - .sm\:cu-pr-6 { - padding-right: var(--canon-space-6); - } - - .sm\:cu-pr-7 { - padding-right: var(--canon-space-7); - } - - .sm\:cu-pr-8 { - padding-right: var(--canon-space-8); - } - - .sm\:cu-pr-9 { - padding-right: var(--canon-space-9); - } - - .sm\:cu-pr-10 { - padding-right: var(--canon-space-10); - } - - .sm\:cu-pr-11 { - padding-right: var(--canon-space-11); - } - - .sm\:cu-pr-12 { - padding-right: var(--canon-space-12); - } - - .sm\:cu-pr-13 { - padding-right: var(--canon-space-13); - } - - .sm\:cu-pr-14 { - padding-right: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-pr { - padding-right: var(--pr-md); - } - - .md\:cu-pr-0\.5 { - padding-right: var(--canon-space-0_5); - } - - .md\:cu-pr-1 { - padding-right: var(--canon-space-1); - } - - .md\:cu-pr-1\.5 { - padding-right: var(--canon-space-1_5); - } - - .md\:cu-pr-2 { - padding-right: var(--canon-space-2); - } - - .md\:cu-pr-3 { - padding-right: var(--canon-space-3); - } - - .md\:cu-pr-4 { - padding-right: var(--canon-space-4); - } - - .md\:cu-pr-5 { - padding-right: var(--canon-space-5); - } - - .md\:cu-pr-6 { - padding-right: var(--canon-space-6); - } - - .md\:cu-pr-7 { - padding-right: var(--canon-space-7); - } - - .md\:cu-pr-8 { - padding-right: var(--canon-space-8); - } - - .md\:cu-pr-9 { - padding-right: var(--canon-space-9); - } - - .md\:cu-pr-10 { - padding-right: var(--canon-space-10); - } - - .md\:cu-pr-11 { - padding-right: var(--canon-space-11); - } - - .md\:cu-pr-12 { - padding-right: var(--canon-space-12); - } - - .md\:cu-pr-13 { - padding-right: var(--canon-space-13); - } - - .md\:cu-pr-14 { - padding-right: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-pr { - padding-right: var(--pr-lg); - } - - .lg\:cu-pr-0\.5 { - padding-right: var(--canon-space-0_5); - } - - .lg\:cu-pr-1 { - padding-right: var(--canon-space-1); - } - - .lg\:cu-pr-1\.5 { - padding-right: var(--canon-space-1_5); - } - - .lg\:cu-pr-2 { - padding-right: var(--canon-space-2); - } - - .lg\:cu-pr-3 { - padding-right: var(--canon-space-3); - } - - .lg\:cu-pr-4 { - padding-right: var(--canon-space-4); - } - - .lg\:cu-pr-5 { - padding-right: var(--canon-space-5); - } - - .lg\:cu-pr-6 { - padding-right: var(--canon-space-6); - } - - .lg\:cu-pr-7 { - padding-right: var(--canon-space-7); - } - - .lg\:cu-pr-8 { - padding-right: var(--canon-space-8); - } - - .lg\:cu-pr-9 { - padding-right: var(--canon-space-9); - } - - .lg\:cu-pr-10 { - padding-right: var(--canon-space-10); - } - - .lg\:cu-pr-11 { - padding-right: var(--canon-space-11); - } - - .lg\:cu-pr-12 { - padding-right: var(--canon-space-12); - } - - .lg\:cu-pr-13 { - padding-right: var(--canon-space-13); - } - - .lg\:cu-pr-14 { - padding-right: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-pr { - padding-right: var(--pr-xl); - } - - .xl\:cu-pr-0\.5 { - padding-right: var(--canon-space-0_5); - } - - .xl\:cu-pr-1 { - padding-right: var(--canon-space-1); - } - - .xl\:cu-pr-1\.5 { - padding-right: var(--canon-space-1_5); - } - - .xl\:cu-pr-2 { - padding-right: var(--canon-space-2); - } - - .xl\:cu-pr-3 { - padding-right: var(--canon-space-3); - } - - .xl\:cu-pr-4 { - padding-right: var(--canon-space-4); - } - - .xl\:cu-pr-5 { - padding-right: var(--canon-space-5); - } - - .xl\:cu-pr-6 { - padding-right: var(--canon-space-6); - } - - .xl\:cu-pr-7 { - padding-right: var(--canon-space-7); - } - - .xl\:cu-pr-8 { - padding-right: var(--canon-space-8); - } - - .xl\:cu-pr-9 { - padding-right: var(--canon-space-9); - } - - .xl\:cu-pr-10 { - padding-right: var(--canon-space-10); - } - - .xl\:cu-pr-11 { - padding-right: var(--canon-space-11); - } - - .xl\:cu-pr-12 { - padding-right: var(--canon-space-12); - } - - .xl\:cu-pr-13 { - padding-right: var(--canon-space-13); - } - - .xl\:cu-pr-14 { - padding-right: var(--canon-space-14); - } -} - -.cu-pt { - padding-top: var(--pt); -} - -.cu-pt-0\.5 { - padding-top: var(--canon-space-0_5); -} - -.cu-pt-1 { - padding-top: var(--canon-space-1); -} - -.cu-pt-1\.5 { - padding-top: var(--canon-space-1_5); -} - -.cu-pt-2 { - padding-top: var(--canon-space-2); -} - -.cu-pt-3 { - padding-top: var(--canon-space-3); -} - -.cu-pt-4 { - padding-top: var(--canon-space-4); -} - -.cu-pt-5 { - padding-top: var(--canon-space-5); -} - -.cu-pt-6 { - padding-top: var(--canon-space-6); -} - -.cu-pt-7 { - padding-top: var(--canon-space-7); -} - -.cu-pt-8 { - padding-top: var(--canon-space-8); -} - -.cu-pt-9 { - padding-top: var(--canon-space-9); -} - -.cu-pt-10 { - padding-top: var(--canon-space-10); -} - -.cu-pt-11 { - padding-top: var(--canon-space-11); -} - -.cu-pt-12 { - padding-top: var(--canon-space-12); -} - -.cu-pt-13 { - padding-top: var(--canon-space-13); -} - -.cu-pt-14 { - padding-top: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-pt { - padding-top: var(--pt-xs); - } - - .xs\:cu-pt-0\.5 { - padding-top: var(--canon-space-0_5); - } - - .xs\:cu-pt-1 { - padding-top: var(--canon-space-1); - } - - .xs\:cu-pt-1\.5 { - padding-top: var(--canon-space-1_5); - } - - .xs\:cu-pt-2 { - padding-top: var(--canon-space-2); - } - - .xs\:cu-pt-3 { - padding-top: var(--canon-space-3); - } - - .xs\:cu-pt-4 { - padding-top: var(--canon-space-4); - } - - .xs\:cu-pt-5 { - padding-top: var(--canon-space-5); - } - - .xs\:cu-pt-6 { - padding-top: var(--canon-space-6); - } - - .xs\:cu-pt-7 { - padding-top: var(--canon-space-7); - } - - .xs\:cu-pt-8 { - padding-top: var(--canon-space-8); - } - - .xs\:cu-pt-9 { - padding-top: var(--canon-space-9); - } - - .xs\:cu-pt-10 { - padding-top: var(--canon-space-10); - } - - .xs\:cu-pt-11 { - padding-top: var(--canon-space-11); - } - - .xs\:cu-pt-12 { - padding-top: var(--canon-space-12); - } - - .xs\:cu-pt-13 { - padding-top: var(--canon-space-13); - } - - .xs\:cu-pt-14 { - padding-top: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-pt { - padding-top: var(--pt-sm); - } - - .sm\:cu-pt-0\.5 { - padding-top: var(--canon-space-0_5); - } - - .sm\:cu-pt-1 { - padding-top: var(--canon-space-1); - } - - .sm\:cu-pt-1\.5 { - padding-top: var(--canon-space-1_5); - } - - .sm\:cu-pt-2 { - padding-top: var(--canon-space-2); - } - - .sm\:cu-pt-3 { - padding-top: var(--canon-space-3); - } - - .sm\:cu-pt-4 { - padding-top: var(--canon-space-4); - } - - .sm\:cu-pt-5 { - padding-top: var(--canon-space-5); - } - - .sm\:cu-pt-6 { - padding-top: var(--canon-space-6); - } - - .sm\:cu-pt-7 { - padding-top: var(--canon-space-7); - } - - .sm\:cu-pt-8 { - padding-top: var(--canon-space-8); - } - - .sm\:cu-pt-9 { - padding-top: var(--canon-space-9); - } - - .sm\:cu-pt-10 { - padding-top: var(--canon-space-10); - } - - .sm\:cu-pt-11 { - padding-top: var(--canon-space-11); - } - - .sm\:cu-pt-12 { - padding-top: var(--canon-space-12); - } - - .sm\:cu-pt-13 { - padding-top: var(--canon-space-13); - } - - .sm\:cu-pt-14 { - padding-top: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-pt { - padding-top: var(--pt-md); - } - - .md\:cu-pt-0\.5 { - padding-top: var(--canon-space-0_5); - } - - .md\:cu-pt-1 { - padding-top: var(--canon-space-1); - } - - .md\:cu-pt-1\.5 { - padding-top: var(--canon-space-1_5); - } - - .md\:cu-pt-2 { - padding-top: var(--canon-space-2); - } - - .md\:cu-pt-3 { - padding-top: var(--canon-space-3); - } - - .md\:cu-pt-4 { - padding-top: var(--canon-space-4); - } - - .md\:cu-pt-5 { - padding-top: var(--canon-space-5); - } - - .md\:cu-pt-6 { - padding-top: var(--canon-space-6); - } - - .md\:cu-pt-7 { - padding-top: var(--canon-space-7); - } - - .md\:cu-pt-8 { - padding-top: var(--canon-space-8); - } - - .md\:cu-pt-9 { - padding-top: var(--canon-space-9); - } - - .md\:cu-pt-10 { - padding-top: var(--canon-space-10); - } - - .md\:cu-pt-11 { - padding-top: var(--canon-space-11); - } - - .md\:cu-pt-12 { - padding-top: var(--canon-space-12); - } - - .md\:cu-pt-13 { - padding-top: var(--canon-space-13); - } - - .md\:cu-pt-14 { - padding-top: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-pt { - padding-top: var(--pt-lg); - } - - .lg\:cu-pt-0\.5 { - padding-top: var(--canon-space-0_5); - } - - .lg\:cu-pt-1 { - padding-top: var(--canon-space-1); - } - - .lg\:cu-pt-1\.5 { - padding-top: var(--canon-space-1_5); - } - - .lg\:cu-pt-2 { - padding-top: var(--canon-space-2); - } - - .lg\:cu-pt-3 { - padding-top: var(--canon-space-3); - } - - .lg\:cu-pt-4 { - padding-top: var(--canon-space-4); - } - - .lg\:cu-pt-5 { - padding-top: var(--canon-space-5); - } - - .lg\:cu-pt-6 { - padding-top: var(--canon-space-6); - } - - .lg\:cu-pt-7 { - padding-top: var(--canon-space-7); - } - - .lg\:cu-pt-8 { - padding-top: var(--canon-space-8); - } - - .lg\:cu-pt-9 { - padding-top: var(--canon-space-9); - } - - .lg\:cu-pt-10 { - padding-top: var(--canon-space-10); - } - - .lg\:cu-pt-11 { - padding-top: var(--canon-space-11); - } - - .lg\:cu-pt-12 { - padding-top: var(--canon-space-12); - } - - .lg\:cu-pt-13 { - padding-top: var(--canon-space-13); - } - - .lg\:cu-pt-14 { - padding-top: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-pt { - padding-top: var(--pt-xl); - } - - .xl\:cu-pt-0\.5 { - padding-top: var(--canon-space-0_5); - } - - .xl\:cu-pt-1 { - padding-top: var(--canon-space-1); - } - - .xl\:cu-pt-1\.5 { - padding-top: var(--canon-space-1_5); - } - - .xl\:cu-pt-2 { - padding-top: var(--canon-space-2); - } - - .xl\:cu-pt-3 { - padding-top: var(--canon-space-3); - } - - .xl\:cu-pt-4 { - padding-top: var(--canon-space-4); - } - - .xl\:cu-pt-5 { - padding-top: var(--canon-space-5); - } - - .xl\:cu-pt-6 { - padding-top: var(--canon-space-6); - } - - .xl\:cu-pt-7 { - padding-top: var(--canon-space-7); - } - - .xl\:cu-pt-8 { - padding-top: var(--canon-space-8); - } - - .xl\:cu-pt-9 { - padding-top: var(--canon-space-9); - } - - .xl\:cu-pt-10 { - padding-top: var(--canon-space-10); - } - - .xl\:cu-pt-11 { - padding-top: var(--canon-space-11); - } - - .xl\:cu-pt-12 { - padding-top: var(--canon-space-12); - } - - .xl\:cu-pt-13 { - padding-top: var(--canon-space-13); - } - - .xl\:cu-pt-14 { - padding-top: var(--canon-space-14); - } -} - -.cu-pb { - padding-bottom: var(--pb); -} - -.cu-pb-0\.5 { - padding-bottom: var(--canon-space-0_5); -} - -.cu-pb-1 { - padding-bottom: var(--canon-space-1); -} - -.cu-pb-1\.5 { - padding-bottom: var(--canon-space-1_5); -} - -.cu-pb-2 { - padding-bottom: var(--canon-space-2); -} - -.cu-pb-3 { - padding-bottom: var(--canon-space-3); -} - -.cu-pb-4 { - padding-bottom: var(--canon-space-4); -} - -.cu-pb-5 { - padding-bottom: var(--canon-space-5); -} - -.cu-pb-6 { - padding-bottom: var(--canon-space-6); -} - -.cu-pb-7 { - padding-bottom: var(--canon-space-7); -} - -.cu-pb-8 { - padding-bottom: var(--canon-space-8); -} - -.cu-pb-9 { - padding-bottom: var(--canon-space-9); -} - -.cu-pb-10 { - padding-bottom: var(--canon-space-10); -} - -.cu-pb-11 { - padding-bottom: var(--canon-space-11); -} - -.cu-pb-12 { - padding-bottom: var(--canon-space-12); -} - -.cu-pb-13 { - padding-bottom: var(--canon-space-13); -} - -.cu-pb-14 { - padding-bottom: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-pb { - padding-bottom: var(--pb-xs); - } - - .xs\:cu-pb-0\.5 { - padding-bottom: var(--canon-space-0_5); - } - - .xs\:cu-pb-1 { - padding-bottom: var(--canon-space-1); - } - - .xs\:cu-pb-1\.5 { - padding-bottom: var(--canon-space-1_5); - } - - .xs\:cu-pb-2 { - padding-bottom: var(--canon-space-2); - } - - .xs\:cu-pb-3 { - padding-bottom: var(--canon-space-3); - } - - .xs\:cu-pb-4 { - padding-bottom: var(--canon-space-4); - } - - .xs\:cu-pb-5 { - padding-bottom: var(--canon-space-5); - } - - .xs\:cu-pb-6 { - padding-bottom: var(--canon-space-6); - } - - .xs\:cu-pb-7 { - padding-bottom: var(--canon-space-7); - } - - .xs\:cu-pb-8 { - padding-bottom: var(--canon-space-8); - } - - .xs\:cu-pb-9 { - padding-bottom: var(--canon-space-9); - } - - .xs\:cu-pb-10 { - padding-bottom: var(--canon-space-10); - } - - .xs\:cu-pb-11 { - padding-bottom: var(--canon-space-11); - } - - .xs\:cu-pb-12 { - padding-bottom: var(--canon-space-12); - } - - .xs\:cu-pb-13 { - padding-bottom: var(--canon-space-13); - } - - .xs\:cu-pb-14 { - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-pb { - padding-bottom: var(--pb-sm); - } - - .sm\:cu-pb-0\.5 { - padding-bottom: var(--canon-space-0_5); - } - - .sm\:cu-pb-1 { - padding-bottom: var(--canon-space-1); - } - - .sm\:cu-pb-1\.5 { - padding-bottom: var(--canon-space-1_5); - } - - .sm\:cu-pb-2 { - padding-bottom: var(--canon-space-2); - } - - .sm\:cu-pb-3 { - padding-bottom: var(--canon-space-3); - } - - .sm\:cu-pb-4 { - padding-bottom: var(--canon-space-4); - } - - .sm\:cu-pb-5 { - padding-bottom: var(--canon-space-5); - } - - .sm\:cu-pb-6 { - padding-bottom: var(--canon-space-6); - } - - .sm\:cu-pb-7 { - padding-bottom: var(--canon-space-7); - } - - .sm\:cu-pb-8 { - padding-bottom: var(--canon-space-8); - } - - .sm\:cu-pb-9 { - padding-bottom: var(--canon-space-9); - } - - .sm\:cu-pb-10 { - padding-bottom: var(--canon-space-10); - } - - .sm\:cu-pb-11 { - padding-bottom: var(--canon-space-11); - } - - .sm\:cu-pb-12 { - padding-bottom: var(--canon-space-12); - } - - .sm\:cu-pb-13 { - padding-bottom: var(--canon-space-13); - } - - .sm\:cu-pb-14 { - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-pb { - padding-bottom: var(--pb-md); - } - - .md\:cu-pb-0\.5 { - padding-bottom: var(--canon-space-0_5); - } - - .md\:cu-pb-1 { - padding-bottom: var(--canon-space-1); - } - - .md\:cu-pb-1\.5 { - padding-bottom: var(--canon-space-1_5); - } - - .md\:cu-pb-2 { - padding-bottom: var(--canon-space-2); - } - - .md\:cu-pb-3 { - padding-bottom: var(--canon-space-3); - } - - .md\:cu-pb-4 { - padding-bottom: var(--canon-space-4); - } - - .md\:cu-pb-5 { - padding-bottom: var(--canon-space-5); - } - - .md\:cu-pb-6 { - padding-bottom: var(--canon-space-6); - } - - .md\:cu-pb-7 { - padding-bottom: var(--canon-space-7); - } - - .md\:cu-pb-8 { - padding-bottom: var(--canon-space-8); - } - - .md\:cu-pb-9 { - padding-bottom: var(--canon-space-9); - } - - .md\:cu-pb-10 { - padding-bottom: var(--canon-space-10); - } - - .md\:cu-pb-11 { - padding-bottom: var(--canon-space-11); - } - - .md\:cu-pb-12 { - padding-bottom: var(--canon-space-12); - } - - .md\:cu-pb-13 { - padding-bottom: var(--canon-space-13); - } - - .md\:cu-pb-14 { - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-pb { - padding-bottom: var(--pb-lg); - } - - .lg\:cu-pb-0\.5 { - padding-bottom: var(--canon-space-0_5); - } - - .lg\:cu-pb-1 { - padding-bottom: var(--canon-space-1); - } - - .lg\:cu-pb-1\.5 { - padding-bottom: var(--canon-space-1_5); - } - - .lg\:cu-pb-2 { - padding-bottom: var(--canon-space-2); - } - - .lg\:cu-pb-3 { - padding-bottom: var(--canon-space-3); - } - - .lg\:cu-pb-4 { - padding-bottom: var(--canon-space-4); - } - - .lg\:cu-pb-5 { - padding-bottom: var(--canon-space-5); - } - - .lg\:cu-pb-6 { - padding-bottom: var(--canon-space-6); - } - - .lg\:cu-pb-7 { - padding-bottom: var(--canon-space-7); - } - - .lg\:cu-pb-8 { - padding-bottom: var(--canon-space-8); - } - - .lg\:cu-pb-9 { - padding-bottom: var(--canon-space-9); - } - - .lg\:cu-pb-10 { - padding-bottom: var(--canon-space-10); - } - - .lg\:cu-pb-11 { - padding-bottom: var(--canon-space-11); - } - - .lg\:cu-pb-12 { - padding-bottom: var(--canon-space-12); - } - - .lg\:cu-pb-13 { - padding-bottom: var(--canon-space-13); - } - - .lg\:cu-pb-14 { - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-pb { - padding-bottom: var(--pb-xl); - } - - .xl\:cu-pb-0\.5 { - padding-bottom: var(--canon-space-0_5); - } - - .xl\:cu-pb-1 { - padding-bottom: var(--canon-space-1); - } - - .xl\:cu-pb-1\.5 { - padding-bottom: var(--canon-space-1_5); - } - - .xl\:cu-pb-2 { - padding-bottom: var(--canon-space-2); - } - - .xl\:cu-pb-3 { - padding-bottom: var(--canon-space-3); - } - - .xl\:cu-pb-4 { - padding-bottom: var(--canon-space-4); - } - - .xl\:cu-pb-5 { - padding-bottom: var(--canon-space-5); - } - - .xl\:cu-pb-6 { - padding-bottom: var(--canon-space-6); - } - - .xl\:cu-pb-7 { - padding-bottom: var(--canon-space-7); - } - - .xl\:cu-pb-8 { - padding-bottom: var(--canon-space-8); - } - - .xl\:cu-pb-9 { - padding-bottom: var(--canon-space-9); - } - - .xl\:cu-pb-10 { - padding-bottom: var(--canon-space-10); - } - - .xl\:cu-pb-11 { - padding-bottom: var(--canon-space-11); - } - - .xl\:cu-pb-12 { - padding-bottom: var(--canon-space-12); - } - - .xl\:cu-pb-13 { - padding-bottom: var(--canon-space-13); - } - - .xl\:cu-pb-14 { - padding-bottom: var(--canon-space-14); - } -} - -.cu-py { - padding-top: var(--py); - padding-bottom: var(--py); -} - -.cu-py-0\.5 { - padding-top: var(--canon-space-0_5); - padding-bottom: var(--canon-space-0_5); -} - -.cu-py-1 { - padding-top: var(--canon-space-1); - padding-bottom: var(--canon-space-1); -} - -.cu-py-1\.5 { - padding-top: var(--canon-space-1_5); - padding-bottom: var(--canon-space-1_5); -} - -.cu-py-2 { - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-2); -} - -.cu-py-3 { - padding-top: var(--canon-space-3); - padding-bottom: var(--canon-space-3); -} - -.cu-py-4 { - padding-top: var(--canon-space-4); - padding-bottom: var(--canon-space-4); -} - -.cu-py-5 { - padding-top: var(--canon-space-5); - padding-bottom: var(--canon-space-5); -} - -.cu-py-6 { - padding-top: var(--canon-space-6); - padding-bottom: var(--canon-space-6); -} - -.cu-py-7 { - padding-top: var(--canon-space-7); - padding-bottom: var(--canon-space-7); -} - -.cu-py-8 { - padding-top: var(--canon-space-8); - padding-bottom: var(--canon-space-8); -} - -.cu-py-9 { - padding-top: var(--canon-space-9); - padding-bottom: var(--canon-space-9); -} - -.cu-py-10 { - padding-top: var(--canon-space-10); - padding-bottom: var(--canon-space-10); -} - -.cu-py-11 { - padding-top: var(--canon-space-11); - padding-bottom: var(--canon-space-11); -} - -.cu-py-12 { - padding-top: var(--canon-space-12); - padding-bottom: var(--canon-space-12); -} - -.cu-py-13 { - padding-top: var(--canon-space-13); - padding-bottom: var(--canon-space-13); -} - -.cu-py-14 { - padding-top: var(--canon-space-14); - padding-bottom: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-py { - padding-top: var(--py-xs); - padding-bottom: var(--py-xs); - } - - .xs\:cu-py-0\.5 { - padding-top: var(--canon-space-0_5); - padding-bottom: var(--canon-space-0_5); - } - - .xs\:cu-py-1 { - padding-top: var(--canon-space-1); - padding-bottom: var(--canon-space-1); - } - - .xs\:cu-py-1\.5 { - padding-top: var(--canon-space-1_5); - padding-bottom: var(--canon-space-1_5); - } - - .xs\:cu-py-2 { - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-2); - } - - .xs\:cu-py-3 { - padding-top: var(--canon-space-3); - padding-bottom: var(--canon-space-3); - } - - .xs\:cu-py-4 { - padding-top: var(--canon-space-4); - padding-bottom: var(--canon-space-4); - } - - .xs\:cu-py-5 { - padding-top: var(--canon-space-5); - padding-bottom: var(--canon-space-5); - } - - .xs\:cu-py-6 { - padding-top: var(--canon-space-6); - padding-bottom: var(--canon-space-6); - } - - .xs\:cu-py-7 { - padding-top: var(--canon-space-7); - padding-bottom: var(--canon-space-7); - } - - .xs\:cu-py-8 { - padding-top: var(--canon-space-8); - padding-bottom: var(--canon-space-8); - } - - .xs\:cu-py-9 { - padding-top: var(--canon-space-9); - padding-bottom: var(--canon-space-9); - } - - .xs\:cu-py-10 { - padding-top: var(--canon-space-10); - padding-bottom: var(--canon-space-10); - } - - .xs\:cu-py-11 { - padding-top: var(--canon-space-11); - padding-bottom: var(--canon-space-11); - } - - .xs\:cu-py-12 { - padding-top: var(--canon-space-12); - padding-bottom: var(--canon-space-12); - } - - .xs\:cu-py-13 { - padding-top: var(--canon-space-13); - padding-bottom: var(--canon-space-13); - } - - .xs\:cu-py-14 { - padding-top: var(--canon-space-14); - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-py { - padding-top: var(--py-sm); - padding-bottom: var(--py-sm); - } - - .sm\:cu-py-0\.5 { - padding-top: var(--canon-space-0_5); - padding-bottom: var(--canon-space-0_5); - } - - .sm\:cu-py-1 { - padding-top: var(--canon-space-1); - padding-bottom: var(--canon-space-1); - } - - .sm\:cu-py-1\.5 { - padding-top: var(--canon-space-1_5); - padding-bottom: var(--canon-space-1_5); - } - - .sm\:cu-py-2 { - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-2); - } - - .sm\:cu-py-3 { - padding-top: var(--canon-space-3); - padding-bottom: var(--canon-space-3); - } - - .sm\:cu-py-4 { - padding-top: var(--canon-space-4); - padding-bottom: var(--canon-space-4); - } - - .sm\:cu-py-5 { - padding-top: var(--canon-space-5); - padding-bottom: var(--canon-space-5); - } - - .sm\:cu-py-6 { - padding-top: var(--canon-space-6); - padding-bottom: var(--canon-space-6); - } - - .sm\:cu-py-7 { - padding-top: var(--canon-space-7); - padding-bottom: var(--canon-space-7); - } - - .sm\:cu-py-8 { - padding-top: var(--canon-space-8); - padding-bottom: var(--canon-space-8); - } - - .sm\:cu-py-9 { - padding-top: var(--canon-space-9); - padding-bottom: var(--canon-space-9); - } - - .sm\:cu-py-10 { - padding-top: var(--canon-space-10); - padding-bottom: var(--canon-space-10); - } - - .sm\:cu-py-11 { - padding-top: var(--canon-space-11); - padding-bottom: var(--canon-space-11); - } - - .sm\:cu-py-12 { - padding-top: var(--canon-space-12); - padding-bottom: var(--canon-space-12); - } - - .sm\:cu-py-13 { - padding-top: var(--canon-space-13); - padding-bottom: var(--canon-space-13); - } - - .sm\:cu-py-14 { - padding-top: var(--canon-space-14); - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-py { - padding-top: var(--py-md); - padding-bottom: var(--py-md); - } - - .md\:cu-py-0\.5 { - padding-top: var(--canon-space-0_5); - padding-bottom: var(--canon-space-0_5); - } - - .md\:cu-py-1 { - padding-top: var(--canon-space-1); - padding-bottom: var(--canon-space-1); - } - - .md\:cu-py-1\.5 { - padding-top: var(--canon-space-1_5); - padding-bottom: var(--canon-space-1_5); - } - - .md\:cu-py-2 { - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-2); - } - - .md\:cu-py-3 { - padding-top: var(--canon-space-3); - padding-bottom: var(--canon-space-3); - } - - .md\:cu-py-4 { - padding-top: var(--canon-space-4); - padding-bottom: var(--canon-space-4); - } - - .md\:cu-py-5 { - padding-top: var(--canon-space-5); - padding-bottom: var(--canon-space-5); - } - - .md\:cu-py-6 { - padding-top: var(--canon-space-6); - padding-bottom: var(--canon-space-6); - } - - .md\:cu-py-7 { - padding-top: var(--canon-space-7); - padding-bottom: var(--canon-space-7); - } - - .md\:cu-py-8 { - padding-top: var(--canon-space-8); - padding-bottom: var(--canon-space-8); - } - - .md\:cu-py-9 { - padding-top: var(--canon-space-9); - padding-bottom: var(--canon-space-9); - } - - .md\:cu-py-10 { - padding-top: var(--canon-space-10); - padding-bottom: var(--canon-space-10); - } - - .md\:cu-py-11 { - padding-top: var(--canon-space-11); - padding-bottom: var(--canon-space-11); - } - - .md\:cu-py-12 { - padding-top: var(--canon-space-12); - padding-bottom: var(--canon-space-12); - } - - .md\:cu-py-13 { - padding-top: var(--canon-space-13); - padding-bottom: var(--canon-space-13); - } - - .md\:cu-py-14 { - padding-top: var(--canon-space-14); - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-py { - padding-top: var(--py-lg); - padding-bottom: var(--py-lg); - } - - .lg\:cu-py-0\.5 { - padding-top: var(--canon-space-0_5); - padding-bottom: var(--canon-space-0_5); - } - - .lg\:cu-py-1 { - padding-top: var(--canon-space-1); - padding-bottom: var(--canon-space-1); - } - - .lg\:cu-py-1\.5 { - padding-top: var(--canon-space-1_5); - padding-bottom: var(--canon-space-1_5); - } - - .lg\:cu-py-2 { - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-2); - } - - .lg\:cu-py-3 { - padding-top: var(--canon-space-3); - padding-bottom: var(--canon-space-3); - } - - .lg\:cu-py-4 { - padding-top: var(--canon-space-4); - padding-bottom: var(--canon-space-4); - } - - .lg\:cu-py-5 { - padding-top: var(--canon-space-5); - padding-bottom: var(--canon-space-5); - } - - .lg\:cu-py-6 { - padding-top: var(--canon-space-6); - padding-bottom: var(--canon-space-6); - } - - .lg\:cu-py-7 { - padding-top: var(--canon-space-7); - padding-bottom: var(--canon-space-7); - } - - .lg\:cu-py-8 { - padding-top: var(--canon-space-8); - padding-bottom: var(--canon-space-8); - } - - .lg\:cu-py-9 { - padding-top: var(--canon-space-9); - padding-bottom: var(--canon-space-9); - } - - .lg\:cu-py-10 { - padding-top: var(--canon-space-10); - padding-bottom: var(--canon-space-10); - } - - .lg\:cu-py-11 { - padding-top: var(--canon-space-11); - padding-bottom: var(--canon-space-11); - } - - .lg\:cu-py-12 { - padding-top: var(--canon-space-12); - padding-bottom: var(--canon-space-12); - } - - .lg\:cu-py-13 { - padding-top: var(--canon-space-13); - padding-bottom: var(--canon-space-13); - } - - .lg\:cu-py-14 { - padding-top: var(--canon-space-14); - padding-bottom: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-py { - padding-top: var(--py-xl); - padding-bottom: var(--py-xl); - } - - .xl\:cu-py-0\.5 { - padding-top: var(--canon-space-0_5); - padding-bottom: var(--canon-space-0_5); - } - - .xl\:cu-py-1 { - padding-top: var(--canon-space-1); - padding-bottom: var(--canon-space-1); - } - - .xl\:cu-py-1\.5 { - padding-top: var(--canon-space-1_5); - padding-bottom: var(--canon-space-1_5); - } - - .xl\:cu-py-2 { - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-2); - } - - .xl\:cu-py-3 { - padding-top: var(--canon-space-3); - padding-bottom: var(--canon-space-3); - } - - .xl\:cu-py-4 { - padding-top: var(--canon-space-4); - padding-bottom: var(--canon-space-4); - } - - .xl\:cu-py-5 { - padding-top: var(--canon-space-5); - padding-bottom: var(--canon-space-5); - } - - .xl\:cu-py-6 { - padding-top: var(--canon-space-6); - padding-bottom: var(--canon-space-6); - } - - .xl\:cu-py-7 { - padding-top: var(--canon-space-7); - padding-bottom: var(--canon-space-7); - } - - .xl\:cu-py-8 { - padding-top: var(--canon-space-8); - padding-bottom: var(--canon-space-8); - } - - .xl\:cu-py-9 { - padding-top: var(--canon-space-9); - padding-bottom: var(--canon-space-9); - } - - .xl\:cu-py-10 { - padding-top: var(--canon-space-10); - padding-bottom: var(--canon-space-10); - } - - .xl\:cu-py-11 { - padding-top: var(--canon-space-11); - padding-bottom: var(--canon-space-11); - } - - .xl\:cu-py-12 { - padding-top: var(--canon-space-12); - padding-bottom: var(--canon-space-12); - } - - .xl\:cu-py-13 { - padding-top: var(--canon-space-13); - padding-bottom: var(--canon-space-13); - } - - .xl\:cu-py-14 { - padding-top: var(--canon-space-14); - padding-bottom: var(--canon-space-14); - } -} - -.cu-px { - padding-left: var(--px); - padding-right: var(--px); -} - -.cu-px-0\.5 { - padding-left: var(--canon-space-0_5); - padding-right: var(--canon-space-0_5); -} - -.cu-px-1 { - padding-left: var(--canon-space-1); - padding-right: var(--canon-space-1); -} - -.cu-px-1\.5 { - padding-left: var(--canon-space-1_5); - padding-right: var(--canon-space-1_5); -} - -.cu-px-2 { - padding-left: var(--canon-space-2); - padding-right: var(--canon-space-2); -} - -.cu-px-3 { - padding-left: var(--canon-space-3); - padding-right: var(--canon-space-3); -} - -.cu-px-4 { - padding-left: var(--canon-space-4); - padding-right: var(--canon-space-4); -} - -.cu-px-5 { - padding-left: var(--canon-space-5); - padding-right: var(--canon-space-5); -} - -.cu-px-6 { - padding-left: var(--canon-space-6); - padding-right: var(--canon-space-6); -} - -.cu-px-7 { - padding-left: var(--canon-space-7); - padding-right: var(--canon-space-7); -} - -.cu-px-8 { - padding-left: var(--canon-space-8); - padding-right: var(--canon-space-8); -} - -.cu-px-9 { - padding-left: var(--canon-space-9); - padding-right: var(--canon-space-9); -} - -.cu-px-10 { - padding-left: var(--canon-space-10); - padding-right: var(--canon-space-10); -} - -.cu-px-11 { - padding-left: var(--canon-space-11); - padding-right: var(--canon-space-11); -} - -.cu-px-12 { - padding-left: var(--canon-space-12); - padding-right: var(--canon-space-12); -} - -.cu-px-13 { - padding-left: var(--canon-space-13); - padding-right: var(--canon-space-13); -} - -.cu-px-14 { - padding-left: var(--canon-space-14); - padding-right: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-px { - padding-left: var(--px-xs); - padding-right: var(--px-xs); - } - - .xs\:cu-px-0\.5 { - padding-left: var(--canon-space-0_5); - padding-right: var(--canon-space-0_5); - } - - .xs\:cu-px-1 { - padding-left: var(--canon-space-1); - padding-right: var(--canon-space-1); - } - - .xs\:cu-px-1\.5 { - padding-left: var(--canon-space-1_5); - padding-right: var(--canon-space-1_5); - } - - .xs\:cu-px-2 { - padding-left: var(--canon-space-2); - padding-right: var(--canon-space-2); - } - - .xs\:cu-px-3 { - padding-left: var(--canon-space-3); - padding-right: var(--canon-space-3); - } - - .xs\:cu-px-4 { - padding-left: var(--canon-space-4); - padding-right: var(--canon-space-4); - } - - .xs\:cu-px-5 { - padding-left: var(--canon-space-5); - padding-right: var(--canon-space-5); - } - - .xs\:cu-px-6 { - padding-left: var(--canon-space-6); - padding-right: var(--canon-space-6); - } - - .xs\:cu-px-7 { - padding-left: var(--canon-space-7); - padding-right: var(--canon-space-7); - } - - .xs\:cu-px-8 { - padding-left: var(--canon-space-8); - padding-right: var(--canon-space-8); - } - - .xs\:cu-px-9 { - padding-left: var(--canon-space-9); - padding-right: var(--canon-space-9); - } - - .xs\:cu-px-10 { - padding-left: var(--canon-space-10); - padding-right: var(--canon-space-10); - } - - .xs\:cu-px-11 { - padding-left: var(--canon-space-11); - padding-right: var(--canon-space-11); - } - - .xs\:cu-px-12 { - padding-left: var(--canon-space-12); - padding-right: var(--canon-space-12); - } - - .xs\:cu-px-13 { - padding-left: var(--canon-space-13); - padding-right: var(--canon-space-13); - } - - .xs\:cu-px-14 { - padding-left: var(--canon-space-14); - padding-right: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-px { - padding-left: var(--px-sm); - padding-right: var(--px-sm); - } - - .sm\:cu-px-0\.5 { - padding-left: var(--canon-space-0_5); - padding-right: var(--canon-space-0_5); - } - - .sm\:cu-px-1 { - padding-left: var(--canon-space-1); - padding-right: var(--canon-space-1); - } - - .sm\:cu-px-1\.5 { - padding-left: var(--canon-space-1_5); - padding-right: var(--canon-space-1_5); - } - - .sm\:cu-px-2 { - padding-left: var(--canon-space-2); - padding-right: var(--canon-space-2); - } - - .sm\:cu-px-3 { - padding-left: var(--canon-space-3); - padding-right: var(--canon-space-3); - } - - .sm\:cu-px-4 { - padding-left: var(--canon-space-4); - padding-right: var(--canon-space-4); - } - - .sm\:cu-px-5 { - padding-left: var(--canon-space-5); - padding-right: var(--canon-space-5); - } - - .sm\:cu-px-6 { - padding-left: var(--canon-space-6); - padding-right: var(--canon-space-6); - } - - .sm\:cu-px-7 { - padding-left: var(--canon-space-7); - padding-right: var(--canon-space-7); - } - - .sm\:cu-px-8 { - padding-left: var(--canon-space-8); - padding-right: var(--canon-space-8); - } - - .sm\:cu-px-9 { - padding-left: var(--canon-space-9); - padding-right: var(--canon-space-9); - } - - .sm\:cu-px-10 { - padding-left: var(--canon-space-10); - padding-right: var(--canon-space-10); - } - - .sm\:cu-px-11 { - padding-left: var(--canon-space-11); - padding-right: var(--canon-space-11); - } - - .sm\:cu-px-12 { - padding-left: var(--canon-space-12); - padding-right: var(--canon-space-12); - } - - .sm\:cu-px-13 { - padding-left: var(--canon-space-13); - padding-right: var(--canon-space-13); - } - - .sm\:cu-px-14 { - padding-left: var(--canon-space-14); - padding-right: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-px { - padding-left: var(--px-md); - padding-right: var(--px-md); - } - - .md\:cu-px-0\.5 { - padding-left: var(--canon-space-0_5); - padding-right: var(--canon-space-0_5); - } - - .md\:cu-px-1 { - padding-left: var(--canon-space-1); - padding-right: var(--canon-space-1); - } - - .md\:cu-px-1\.5 { - padding-left: var(--canon-space-1_5); - padding-right: var(--canon-space-1_5); - } - - .md\:cu-px-2 { - padding-left: var(--canon-space-2); - padding-right: var(--canon-space-2); - } - - .md\:cu-px-3 { - padding-left: var(--canon-space-3); - padding-right: var(--canon-space-3); - } - - .md\:cu-px-4 { - padding-left: var(--canon-space-4); - padding-right: var(--canon-space-4); - } - - .md\:cu-px-5 { - padding-left: var(--canon-space-5); - padding-right: var(--canon-space-5); - } - - .md\:cu-px-6 { - padding-left: var(--canon-space-6); - padding-right: var(--canon-space-6); - } - - .md\:cu-px-7 { - padding-left: var(--canon-space-7); - padding-right: var(--canon-space-7); - } - - .md\:cu-px-8 { - padding-left: var(--canon-space-8); - padding-right: var(--canon-space-8); - } - - .md\:cu-px-9 { - padding-left: var(--canon-space-9); - padding-right: var(--canon-space-9); - } - - .md\:cu-px-10 { - padding-left: var(--canon-space-10); - padding-right: var(--canon-space-10); - } - - .md\:cu-px-11 { - padding-left: var(--canon-space-11); - padding-right: var(--canon-space-11); - } - - .md\:cu-px-12 { - padding-left: var(--canon-space-12); - padding-right: var(--canon-space-12); - } - - .md\:cu-px-13 { - padding-left: var(--canon-space-13); - padding-right: var(--canon-space-13); - } - - .md\:cu-px-14 { - padding-left: var(--canon-space-14); - padding-right: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-px { - padding-left: var(--px-lg); - padding-right: var(--px-lg); - } - - .lg\:cu-px-0\.5 { - padding-left: var(--canon-space-0_5); - padding-right: var(--canon-space-0_5); - } - - .lg\:cu-px-1 { - padding-left: var(--canon-space-1); - padding-right: var(--canon-space-1); - } - - .lg\:cu-px-1\.5 { - padding-left: var(--canon-space-1_5); - padding-right: var(--canon-space-1_5); - } - - .lg\:cu-px-2 { - padding-left: var(--canon-space-2); - padding-right: var(--canon-space-2); - } - - .lg\:cu-px-3 { - padding-left: var(--canon-space-3); - padding-right: var(--canon-space-3); - } - - .lg\:cu-px-4 { - padding-left: var(--canon-space-4); - padding-right: var(--canon-space-4); - } - - .lg\:cu-px-5 { - padding-left: var(--canon-space-5); - padding-right: var(--canon-space-5); - } - - .lg\:cu-px-6 { - padding-left: var(--canon-space-6); - padding-right: var(--canon-space-6); - } - - .lg\:cu-px-7 { - padding-left: var(--canon-space-7); - padding-right: var(--canon-space-7); - } - - .lg\:cu-px-8 { - padding-left: var(--canon-space-8); - padding-right: var(--canon-space-8); - } - - .lg\:cu-px-9 { - padding-left: var(--canon-space-9); - padding-right: var(--canon-space-9); - } - - .lg\:cu-px-10 { - padding-left: var(--canon-space-10); - padding-right: var(--canon-space-10); - } - - .lg\:cu-px-11 { - padding-left: var(--canon-space-11); - padding-right: var(--canon-space-11); - } - - .lg\:cu-px-12 { - padding-left: var(--canon-space-12); - padding-right: var(--canon-space-12); - } - - .lg\:cu-px-13 { - padding-left: var(--canon-space-13); - padding-right: var(--canon-space-13); - } - - .lg\:cu-px-14 { - padding-left: var(--canon-space-14); - padding-right: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-px { - padding-left: var(--px-xl); - padding-right: var(--px-xl); - } - - .xl\:cu-px-0\.5 { - padding-left: var(--canon-space-0_5); - padding-right: var(--canon-space-0_5); - } - - .xl\:cu-px-1 { - padding-left: var(--canon-space-1); - padding-right: var(--canon-space-1); - } - - .xl\:cu-px-1\.5 { - padding-left: var(--canon-space-1_5); - padding-right: var(--canon-space-1_5); - } - - .xl\:cu-px-2 { - padding-left: var(--canon-space-2); - padding-right: var(--canon-space-2); - } - - .xl\:cu-px-3 { - padding-left: var(--canon-space-3); - padding-right: var(--canon-space-3); - } - - .xl\:cu-px-4 { - padding-left: var(--canon-space-4); - padding-right: var(--canon-space-4); - } - - .xl\:cu-px-5 { - padding-left: var(--canon-space-5); - padding-right: var(--canon-space-5); - } - - .xl\:cu-px-6 { - padding-left: var(--canon-space-6); - padding-right: var(--canon-space-6); - } - - .xl\:cu-px-7 { - padding-left: var(--canon-space-7); - padding-right: var(--canon-space-7); - } - - .xl\:cu-px-8 { - padding-left: var(--canon-space-8); - padding-right: var(--canon-space-8); - } - - .xl\:cu-px-9 { - padding-left: var(--canon-space-9); - padding-right: var(--canon-space-9); - } - - .xl\:cu-px-10 { - padding-left: var(--canon-space-10); - padding-right: var(--canon-space-10); - } - - .xl\:cu-px-11 { - padding-left: var(--canon-space-11); - padding-right: var(--canon-space-11); - } - - .xl\:cu-px-12 { - padding-left: var(--canon-space-12); - padding-right: var(--canon-space-12); - } - - .xl\:cu-px-13 { - padding-left: var(--canon-space-13); - padding-right: var(--canon-space-13); - } - - .xl\:cu-px-14 { - padding-left: var(--canon-space-14); - padding-right: var(--canon-space-14); - } -} - -.cu-m { - margin: var(--m); -} - -.cu-m-0\.5 { - margin: var(--canon-space-0_5); -} - -.cu-m-1 { - margin: var(--canon-space-1); -} - -.cu-m-1\.5 { - margin: var(--canon-space-1_5); -} - -.cu-m-2 { - margin: var(--canon-space-2); -} - -.cu-m-3 { - margin: var(--canon-space-3); -} - -.cu-m-4 { - margin: var(--canon-space-4); -} - -.cu-m-5 { - margin: var(--canon-space-5); -} - -.cu-m-6 { - margin: var(--canon-space-6); -} - -.cu-m-7 { - margin: var(--canon-space-7); -} - -.cu-m-8 { - margin: var(--canon-space-8); -} - -.cu-m-9 { - margin: var(--canon-space-9); -} - -.cu-m-10 { - margin: var(--canon-space-10); -} - -.cu-m-11 { - margin: var(--canon-space-11); -} - -.cu-m-12 { - margin: var(--canon-space-12); -} - -.cu-m-13 { - margin: var(--canon-space-13); -} - -.cu-m-14 { - margin: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-m { - margin: var(--p-xs); - } - - .xs\:cu-m-0\.5 { - margin: var(--canon-space-0_5); - } - - .xs\:cu-m-1 { - margin: var(--canon-space-1); - } - - .xs\:cu-m-1\.5 { - margin: var(--canon-space-1_5); - } - - .xs\:cu-m-2 { - margin: var(--canon-space-2); - } - - .xs\:cu-m-3 { - margin: var(--canon-space-3); - } - - .xs\:cu-m-4 { - margin: var(--canon-space-4); - } - - .xs\:cu-m-5 { - margin: var(--canon-space-5); - } - - .xs\:cu-m-6 { - margin: var(--canon-space-6); - } - - .xs\:cu-m-7 { - margin: var(--canon-space-7); - } - - .xs\:cu-m-8 { - margin: var(--canon-space-8); - } - - .xs\:cu-m-9 { - margin: var(--canon-space-9); - } - - .xs\:cu-m-10 { - margin: var(--canon-space-10); - } - - .xs\:cu-m-11 { - margin: var(--canon-space-11); - } - - .xs\:cu-m-12 { - margin: var(--canon-space-12); - } - - .xs\:cu-m-13 { - margin: var(--canon-space-13); - } - - .xs\:cu-m-14 { - margin: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-m { - margin: var(--p-sm); - } - - .sm\:cu-m-0\.5 { - margin: var(--canon-space-0_5); - } - - .sm\:cu-m-1 { - margin: var(--canon-space-1); - } - - .sm\:cu-m-1\.5 { - margin: var(--canon-space-1_5); - } - - .sm\:cu-m-2 { - margin: var(--canon-space-2); - } - - .sm\:cu-m-3 { - margin: var(--canon-space-3); - } - - .sm\:cu-m-4 { - margin: var(--canon-space-4); - } - - .sm\:cu-m-5 { - margin: var(--canon-space-5); - } - - .sm\:cu-m-6 { - margin: var(--canon-space-6); - } - - .sm\:cu-m-7 { - margin: var(--canon-space-7); - } - - .sm\:cu-m-8 { - margin: var(--canon-space-8); - } - - .sm\:cu-m-9 { - margin: var(--canon-space-9); - } - - .sm\:cu-m-10 { - margin: var(--canon-space-10); - } - - .sm\:cu-m-11 { - margin: var(--canon-space-11); - } - - .sm\:cu-m-12 { - margin: var(--canon-space-12); - } - - .sm\:cu-m-13 { - margin: var(--canon-space-13); - } - - .sm\:cu-m-14 { - margin: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-m { - margin: var(--p-md); - } - - .md\:cu-m-0\.5 { - margin: var(--canon-space-0_5); - } - - .md\:cu-m-1 { - margin: var(--canon-space-1); - } - - .md\:cu-m-1\.5 { - margin: var(--canon-space-1_5); - } - - .md\:cu-m-2 { - margin: var(--canon-space-2); - } - - .md\:cu-m-3 { - margin: var(--canon-space-3); - } - - .md\:cu-m-4 { - margin: var(--canon-space-4); - } - - .md\:cu-m-5 { - margin: var(--canon-space-5); - } - - .md\:cu-m-6 { - margin: var(--canon-space-6); - } - - .md\:cu-m-7 { - margin: var(--canon-space-7); - } - - .md\:cu-m-8 { - margin: var(--canon-space-8); - } - - .md\:cu-m-9 { - margin: var(--canon-space-9); - } - - .md\:cu-m-10 { - margin: var(--canon-space-10); - } - - .md\:cu-m-11 { - margin: var(--canon-space-11); - } - - .md\:cu-m-12 { - margin: var(--canon-space-12); - } - - .md\:cu-m-13 { - margin: var(--canon-space-13); - } - - .md\:cu-m-14 { - margin: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-m { - margin: var(--p-lg); - } - - .lg\:cu-m-0\.5 { - margin: var(--canon-space-0_5); - } - - .lg\:cu-m-1 { - margin: var(--canon-space-1); - } - - .lg\:cu-m-1\.5 { - margin: var(--canon-space-1_5); - } - - .lg\:cu-m-2 { - margin: var(--canon-space-2); - } - - .lg\:cu-m-3 { - margin: var(--canon-space-3); - } - - .lg\:cu-m-4 { - margin: var(--canon-space-4); - } - - .lg\:cu-m-5 { - margin: var(--canon-space-5); - } - - .lg\:cu-m-6 { - margin: var(--canon-space-6); - } - - .lg\:cu-m-7 { - margin: var(--canon-space-7); - } - - .lg\:cu-m-8 { - margin: var(--canon-space-8); - } - - .lg\:cu-m-9 { - margin: var(--canon-space-9); - } - - .lg\:cu-m-10 { - margin: var(--canon-space-10); - } - - .lg\:cu-m-11 { - margin: var(--canon-space-11); - } - - .lg\:cu-m-12 { - margin: var(--canon-space-12); - } - - .lg\:cu-m-13 { - margin: var(--canon-space-13); - } - - .lg\:cu-m-14 { - margin: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-m { - margin: var(--p-xl); - } - - .xl\:cu-m-0\.5 { - margin: var(--canon-space-0_5); - } - - .xl\:cu-m-1 { - margin: var(--canon-space-1); - } - - .xl\:cu-m-1\.5 { - margin: var(--canon-space-1_5); - } - - .xl\:cu-m-2 { - margin: var(--canon-space-2); - } - - .xl\:cu-m-3 { - margin: var(--canon-space-3); - } - - .xl\:cu-m-4 { - margin: var(--canon-space-4); - } - - .xl\:cu-m-5 { - margin: var(--canon-space-5); - } - - .xl\:cu-m-6 { - margin: var(--canon-space-6); - } - - .xl\:cu-m-7 { - margin: var(--canon-space-7); - } - - .xl\:cu-m-8 { - margin: var(--canon-space-8); - } - - .xl\:cu-m-9 { - margin: var(--canon-space-9); - } - - .xl\:cu-m-10 { - margin: var(--canon-space-10); - } - - .xl\:cu-m-11 { - margin: var(--canon-space-11); - } - - .xl\:cu-m-12 { - margin: var(--canon-space-12); - } - - .xl\:cu-m-13 { - margin: var(--canon-space-13); - } - - .xl\:cu-m-14 { - margin: var(--canon-space-14); - } -} - -.cu-ml { - margin-left: var(--ml); -} - -.cu-ml-0\.5 { - margin-left: var(--canon-space-0_5); -} - -.cu-ml-1 { - margin-left: var(--canon-space-1); -} - -.cu-ml-1\.5 { - margin-left: var(--canon-space-1_5); -} - -.cu-ml-2 { - margin-left: var(--canon-space-2); -} - -.cu-ml-3 { - margin-left: var(--canon-space-3); -} - -.cu-ml-4 { - margin-left: var(--canon-space-4); -} - -.cu-ml-5 { - margin-left: var(--canon-space-5); -} - -.cu-ml-6 { - margin-left: var(--canon-space-6); -} - -.cu-ml-7 { - margin-left: var(--canon-space-7); -} - -.cu-ml-8 { - margin-left: var(--canon-space-8); -} - -.cu-ml-9 { - margin-left: var(--canon-space-9); -} - -.cu-ml-10 { - margin-left: var(--canon-space-10); -} - -.cu-ml-11 { - margin-left: var(--canon-space-11); -} - -.cu-ml-12 { - margin-left: var(--canon-space-12); -} - -.cu-ml-13 { - margin-left: var(--canon-space-13); -} - -.cu-ml-14 { - margin-left: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-ml { - margin-left: var(--pl-xs); - } - - .xs\:cu-ml-0\.5 { - margin-left: var(--canon-space-0_5); - } - - .xs\:cu-ml-1 { - margin-left: var(--canon-space-1); - } - - .xs\:cu-ml-1\.5 { - margin-left: var(--canon-space-1_5); - } - - .xs\:cu-ml-2 { - margin-left: var(--canon-space-2); - } - - .xs\:cu-ml-3 { - margin-left: var(--canon-space-3); - } - - .xs\:cu-ml-4 { - margin-left: var(--canon-space-4); - } - - .xs\:cu-ml-5 { - margin-left: var(--canon-space-5); - } - - .xs\:cu-ml-6 { - margin-left: var(--canon-space-6); - } - - .xs\:cu-ml-7 { - margin-left: var(--canon-space-7); - } - - .xs\:cu-ml-8 { - margin-left: var(--canon-space-8); - } - - .xs\:cu-ml-9 { - margin-left: var(--canon-space-9); - } - - .xs\:cu-ml-10 { - margin-left: var(--canon-space-10); - } - - .xs\:cu-ml-11 { - margin-left: var(--canon-space-11); - } - - .xs\:cu-ml-12 { - margin-left: var(--canon-space-12); - } - - .xs\:cu-ml-13 { - margin-left: var(--canon-space-13); - } - - .xs\:cu-ml-14 { - margin-left: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-ml { - margin-left: var(--pl-sm); - } - - .sm\:cu-ml-0\.5 { - margin-left: var(--canon-space-0_5); - } - - .sm\:cu-ml-1 { - margin-left: var(--canon-space-1); - } - - .sm\:cu-ml-1\.5 { - margin-left: var(--canon-space-1_5); - } - - .sm\:cu-ml-2 { - margin-left: var(--canon-space-2); - } - - .sm\:cu-ml-3 { - margin-left: var(--canon-space-3); - } - - .sm\:cu-ml-4 { - margin-left: var(--canon-space-4); - } - - .sm\:cu-ml-5 { - margin-left: var(--canon-space-5); - } - - .sm\:cu-ml-6 { - margin-left: var(--canon-space-6); - } - - .sm\:cu-ml-7 { - margin-left: var(--canon-space-7); - } - - .sm\:cu-ml-8 { - margin-left: var(--canon-space-8); - } - - .sm\:cu-ml-9 { - margin-left: var(--canon-space-9); - } - - .sm\:cu-ml-10 { - margin-left: var(--canon-space-10); - } - - .sm\:cu-ml-11 { - margin-left: var(--canon-space-11); - } - - .sm\:cu-ml-12 { - margin-left: var(--canon-space-12); - } - - .sm\:cu-ml-13 { - margin-left: var(--canon-space-13); - } - - .sm\:cu-ml-14 { - margin-left: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-ml { - margin-left: var(--pl-md); - } - - .md\:cu-ml-0\.5 { - margin-left: var(--canon-space-0_5); - } - - .md\:cu-ml-1 { - margin-left: var(--canon-space-1); - } - - .md\:cu-ml-1\.5 { - margin-left: var(--canon-space-1_5); - } - - .md\:cu-ml-2 { - margin-left: var(--canon-space-2); - } - - .md\:cu-ml-3 { - margin-left: var(--canon-space-3); - } - - .md\:cu-ml-4 { - margin-left: var(--canon-space-4); - } - - .md\:cu-ml-5 { - margin-left: var(--canon-space-5); - } - - .md\:cu-ml-6 { - margin-left: var(--canon-space-6); - } - - .md\:cu-ml-7 { - margin-left: var(--canon-space-7); - } - - .md\:cu-ml-8 { - margin-left: var(--canon-space-8); - } - - .md\:cu-ml-9 { - margin-left: var(--canon-space-9); - } - - .md\:cu-ml-10 { - margin-left: var(--canon-space-10); - } - - .md\:cu-ml-11 { - margin-left: var(--canon-space-11); - } - - .md\:cu-ml-12 { - margin-left: var(--canon-space-12); - } - - .md\:cu-ml-13 { - margin-left: var(--canon-space-13); - } - - .md\:cu-ml-14 { - margin-left: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-ml { - margin-left: var(--pl-lg); - } - - .lg\:cu-ml-0\.5 { - margin-left: var(--canon-space-0_5); - } - - .lg\:cu-ml-1 { - margin-left: var(--canon-space-1); - } - - .lg\:cu-ml-1\.5 { - margin-left: var(--canon-space-1_5); - } - - .lg\:cu-ml-2 { - margin-left: var(--canon-space-2); - } - - .lg\:cu-ml-3 { - margin-left: var(--canon-space-3); - } - - .lg\:cu-ml-4 { - margin-left: var(--canon-space-4); - } - - .lg\:cu-ml-5 { - margin-left: var(--canon-space-5); - } - - .lg\:cu-ml-6 { - margin-left: var(--canon-space-6); - } - - .lg\:cu-ml-7 { - margin-left: var(--canon-space-7); - } - - .lg\:cu-ml-8 { - margin-left: var(--canon-space-8); - } - - .lg\:cu-ml-9 { - margin-left: var(--canon-space-9); - } - - .lg\:cu-ml-10 { - margin-left: var(--canon-space-10); - } - - .lg\:cu-ml-11 { - margin-left: var(--canon-space-11); - } - - .lg\:cu-ml-12 { - margin-left: var(--canon-space-12); - } - - .lg\:cu-ml-13 { - margin-left: var(--canon-space-13); - } - - .lg\:cu-ml-14 { - margin-left: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-ml { - margin-left: var(--pl-xl); - } - - .xl\:cu-ml-0\.5 { - margin-left: var(--canon-space-0_5); - } - - .xl\:cu-ml-1 { - margin-left: var(--canon-space-1); - } - - .xl\:cu-ml-1\.5 { - margin-left: var(--canon-space-1_5); - } - - .xl\:cu-ml-2 { - margin-left: var(--canon-space-2); - } - - .xl\:cu-ml-3 { - margin-left: var(--canon-space-3); - } - - .xl\:cu-ml-4 { - margin-left: var(--canon-space-4); - } - - .xl\:cu-ml-5 { - margin-left: var(--canon-space-5); - } - - .xl\:cu-ml-6 { - margin-left: var(--canon-space-6); - } - - .xl\:cu-ml-7 { - margin-left: var(--canon-space-7); - } - - .xl\:cu-ml-8 { - margin-left: var(--canon-space-8); - } - - .xl\:cu-ml-9 { - margin-left: var(--canon-space-9); - } - - .xl\:cu-ml-10 { - margin-left: var(--canon-space-10); - } - - .xl\:cu-ml-11 { - margin-left: var(--canon-space-11); - } - - .xl\:cu-ml-12 { - margin-left: var(--canon-space-12); - } - - .xl\:cu-ml-13 { - margin-left: var(--canon-space-13); - } - - .xl\:cu-ml-14 { - margin-left: var(--canon-space-14); - } -} - -.cu-mr { - margin-right: var(--mr); -} - -.cu-mr-0\.5 { - margin-right: var(--canon-space-0_5); -} - -.cu-mr-1 { - margin-right: var(--canon-space-1); -} - -.cu-mr-1\.5 { - margin-right: var(--canon-space-1_5); -} - -.cu-mr-2 { - margin-right: var(--canon-space-2); -} - -.cu-mr-3 { - margin-right: var(--canon-space-3); -} - -.cu-mr-4 { - margin-right: var(--canon-space-4); -} - -.cu-mr-5 { - margin-right: var(--canon-space-5); -} - -.cu-mr-6 { - margin-right: var(--canon-space-6); -} - -.cu-mr-7 { - margin-right: var(--canon-space-7); -} - -.cu-mr-8 { - margin-right: var(--canon-space-8); -} - -.cu-mr-9 { - margin-right: var(--canon-space-9); -} - -.cu-mr-10 { - margin-right: var(--canon-space-10); -} - -.cu-mr-11 { - margin-right: var(--canon-space-11); -} - -.cu-mr-12 { - margin-right: var(--canon-space-12); -} - -.cu-mr-13 { - margin-right: var(--canon-space-13); -} - -.cu-mr-14 { - margin-right: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-mr { - margin-right: var(--pr-xs); - } - - .xs\:cu-mr-0\.5 { - margin-right: var(--canon-space-0_5); - } - - .xs\:cu-mr-1 { - margin-right: var(--canon-space-1); - } - - .xs\:cu-mr-1\.5 { - margin-right: var(--canon-space-1_5); - } - - .xs\:cu-mr-2 { - margin-right: var(--canon-space-2); - } - - .xs\:cu-mr-3 { - margin-right: var(--canon-space-3); - } - - .xs\:cu-mr-4 { - margin-right: var(--canon-space-4); - } - - .xs\:cu-mr-5 { - margin-right: var(--canon-space-5); - } - - .xs\:cu-mr-6 { - margin-right: var(--canon-space-6); - } - - .xs\:cu-mr-7 { - margin-right: var(--canon-space-7); - } - - .xs\:cu-mr-8 { - margin-right: var(--canon-space-8); - } - - .xs\:cu-mr-9 { - margin-right: var(--canon-space-9); - } - - .xs\:cu-mr-10 { - margin-right: var(--canon-space-10); - } - - .xs\:cu-mr-11 { - margin-right: var(--canon-space-11); - } - - .xs\:cu-mr-12 { - margin-right: var(--canon-space-12); - } - - .xs\:cu-mr-13 { - margin-right: var(--canon-space-13); - } - - .xs\:cu-mr-14 { - margin-right: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-mr { - margin-right: var(--pr-sm); - } - - .sm\:cu-mr-0\.5 { - margin-right: var(--canon-space-0_5); - } - - .sm\:cu-mr-1 { - margin-right: var(--canon-space-1); - } - - .sm\:cu-mr-1\.5 { - margin-right: var(--canon-space-1_5); - } - - .sm\:cu-mr-2 { - margin-right: var(--canon-space-2); - } - - .sm\:cu-mr-3 { - margin-right: var(--canon-space-3); - } - - .sm\:cu-mr-4 { - margin-right: var(--canon-space-4); - } - - .sm\:cu-mr-5 { - margin-right: var(--canon-space-5); - } - - .sm\:cu-mr-6 { - margin-right: var(--canon-space-6); - } - - .sm\:cu-mr-7 { - margin-right: var(--canon-space-7); - } - - .sm\:cu-mr-8 { - margin-right: var(--canon-space-8); - } - - .sm\:cu-mr-9 { - margin-right: var(--canon-space-9); - } - - .sm\:cu-mr-10 { - margin-right: var(--canon-space-10); - } - - .sm\:cu-mr-11 { - margin-right: var(--canon-space-11); - } - - .sm\:cu-mr-12 { - margin-right: var(--canon-space-12); - } - - .sm\:cu-mr-13 { - margin-right: var(--canon-space-13); - } - - .sm\:cu-mr-14 { - margin-right: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-mr { - margin-right: var(--pr-md); - } - - .md\:cu-mr-0\.5 { - margin-right: var(--canon-space-0_5); - } - - .md\:cu-mr-1 { - margin-right: var(--canon-space-1); - } - - .md\:cu-mr-1\.5 { - margin-right: var(--canon-space-1_5); - } - - .md\:cu-mr-2 { - margin-right: var(--canon-space-2); - } - - .md\:cu-mr-3 { - margin-right: var(--canon-space-3); - } - - .md\:cu-mr-4 { - margin-right: var(--canon-space-4); - } - - .md\:cu-mr-5 { - margin-right: var(--canon-space-5); - } - - .md\:cu-mr-6 { - margin-right: var(--canon-space-6); - } - - .md\:cu-mr-7 { - margin-right: var(--canon-space-7); - } - - .md\:cu-mr-8 { - margin-right: var(--canon-space-8); - } - - .md\:cu-mr-9 { - margin-right: var(--canon-space-9); - } - - .md\:cu-mr-10 { - margin-right: var(--canon-space-10); - } - - .md\:cu-mr-11 { - margin-right: var(--canon-space-11); - } - - .md\:cu-mr-12 { - margin-right: var(--canon-space-12); - } - - .md\:cu-mr-13 { - margin-right: var(--canon-space-13); - } - - .md\:cu-mr-14 { - margin-right: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-mr { - margin-right: var(--pr-lg); - } - - .lg\:cu-mr-0\.5 { - margin-right: var(--canon-space-0_5); - } - - .lg\:cu-mr-1 { - margin-right: var(--canon-space-1); - } - - .lg\:cu-mr-1\.5 { - margin-right: var(--canon-space-1_5); - } - - .lg\:cu-mr-2 { - margin-right: var(--canon-space-2); - } - - .lg\:cu-mr-3 { - margin-right: var(--canon-space-3); - } - - .lg\:cu-mr-4 { - margin-right: var(--canon-space-4); - } - - .lg\:cu-mr-5 { - margin-right: var(--canon-space-5); - } - - .lg\:cu-mr-6 { - margin-right: var(--canon-space-6); - } - - .lg\:cu-mr-7 { - margin-right: var(--canon-space-7); - } - - .lg\:cu-mr-8 { - margin-right: var(--canon-space-8); - } - - .lg\:cu-mr-9 { - margin-right: var(--canon-space-9); - } - - .lg\:cu-mr-10 { - margin-right: var(--canon-space-10); - } - - .lg\:cu-mr-11 { - margin-right: var(--canon-space-11); - } - - .lg\:cu-mr-12 { - margin-right: var(--canon-space-12); - } - - .lg\:cu-mr-13 { - margin-right: var(--canon-space-13); - } - - .lg\:cu-mr-14 { - margin-right: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-mr { - margin-right: var(--pr-xl); - } - - .xl\:cu-mr-0\.5 { - margin-right: var(--canon-space-0_5); - } - - .xl\:cu-mr-1 { - margin-right: var(--canon-space-1); - } - - .xl\:cu-mr-1\.5 { - margin-right: var(--canon-space-1_5); - } - - .xl\:cu-mr-2 { - margin-right: var(--canon-space-2); - } - - .xl\:cu-mr-3 { - margin-right: var(--canon-space-3); - } - - .xl\:cu-mr-4 { - margin-right: var(--canon-space-4); - } - - .xl\:cu-mr-5 { - margin-right: var(--canon-space-5); - } - - .xl\:cu-mr-6 { - margin-right: var(--canon-space-6); - } - - .xl\:cu-mr-7 { - margin-right: var(--canon-space-7); - } - - .xl\:cu-mr-8 { - margin-right: var(--canon-space-8); - } - - .xl\:cu-mr-9 { - margin-right: var(--canon-space-9); - } - - .xl\:cu-mr-10 { - margin-right: var(--canon-space-10); - } - - .xl\:cu-mr-11 { - margin-right: var(--canon-space-11); - } - - .xl\:cu-mr-12 { - margin-right: var(--canon-space-12); - } - - .xl\:cu-mr-13 { - margin-right: var(--canon-space-13); - } - - .xl\:cu-mr-14 { - margin-right: var(--canon-space-14); - } -} - -.cu-mt { - margin-top: var(--mt); -} - -.cu-mt-0\.5 { - margin-top: var(--canon-space-0_5); -} - -.cu-mt-1 { - margin-top: var(--canon-space-1); -} - -.cu-mt-1\.5 { - margin-top: var(--canon-space-1_5); -} - -.cu-mt-2 { - margin-top: var(--canon-space-2); -} - -.cu-mt-3 { - margin-top: var(--canon-space-3); -} - -.cu-mt-4 { - margin-top: var(--canon-space-4); -} - -.cu-mt-5 { - margin-top: var(--canon-space-5); -} - -.cu-mt-6 { - margin-top: var(--canon-space-6); -} - -.cu-mt-7 { - margin-top: var(--canon-space-7); -} - -.cu-mt-8 { - margin-top: var(--canon-space-8); -} - -.cu-mt-9 { - margin-top: var(--canon-space-9); -} - -.cu-mt-10 { - margin-top: var(--canon-space-10); -} - -.cu-mt-11 { - margin-top: var(--canon-space-11); -} - -.cu-mt-12 { - margin-top: var(--canon-space-12); -} - -.cu-mt-13 { - margin-top: var(--canon-space-13); -} - -.cu-mt-14 { - margin-top: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-mt { - margin-top: var(--pt-xs); - } - - .xs\:cu-mt-0\.5 { - margin-top: var(--canon-space-0_5); - } - - .xs\:cu-mt-1 { - margin-top: var(--canon-space-1); - } - - .xs\:cu-mt-1\.5 { - margin-top: var(--canon-space-1_5); - } - - .xs\:cu-mt-2 { - margin-top: var(--canon-space-2); - } - - .xs\:cu-mt-3 { - margin-top: var(--canon-space-3); - } - - .xs\:cu-mt-4 { - margin-top: var(--canon-space-4); - } - - .xs\:cu-mt-5 { - margin-top: var(--canon-space-5); - } - - .xs\:cu-mt-6 { - margin-top: var(--canon-space-6); - } - - .xs\:cu-mt-7 { - margin-top: var(--canon-space-7); - } - - .xs\:cu-mt-8 { - margin-top: var(--canon-space-8); - } - - .xs\:cu-mt-9 { - margin-top: var(--canon-space-9); - } - - .xs\:cu-mt-10 { - margin-top: var(--canon-space-10); - } - - .xs\:cu-mt-11 { - margin-top: var(--canon-space-11); - } - - .xs\:cu-mt-12 { - margin-top: var(--canon-space-12); - } - - .xs\:cu-mt-13 { - margin-top: var(--canon-space-13); - } - - .xs\:cu-mt-14 { - margin-top: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-mt { - margin-top: var(--pt-sm); - } - - .sm\:cu-mt-0\.5 { - margin-top: var(--canon-space-0_5); - } - - .sm\:cu-mt-1 { - margin-top: var(--canon-space-1); - } - - .sm\:cu-mt-1\.5 { - margin-top: var(--canon-space-1_5); - } - - .sm\:cu-mt-2 { - margin-top: var(--canon-space-2); - } - - .sm\:cu-mt-3 { - margin-top: var(--canon-space-3); - } - - .sm\:cu-mt-4 { - margin-top: var(--canon-space-4); - } - - .sm\:cu-mt-5 { - margin-top: var(--canon-space-5); - } - - .sm\:cu-mt-6 { - margin-top: var(--canon-space-6); - } - - .sm\:cu-mt-7 { - margin-top: var(--canon-space-7); - } - - .sm\:cu-mt-8 { - margin-top: var(--canon-space-8); - } - - .sm\:cu-mt-9 { - margin-top: var(--canon-space-9); - } - - .sm\:cu-mt-10 { - margin-top: var(--canon-space-10); - } - - .sm\:cu-mt-11 { - margin-top: var(--canon-space-11); - } - - .sm\:cu-mt-12 { - margin-top: var(--canon-space-12); - } - - .sm\:cu-mt-13 { - margin-top: var(--canon-space-13); - } - - .sm\:cu-mt-14 { - margin-top: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-mt { - margin-top: var(--pt-md); - } - - .md\:cu-mt-0\.5 { - margin-top: var(--canon-space-0_5); - } - - .md\:cu-mt-1 { - margin-top: var(--canon-space-1); - } - - .md\:cu-mt-1\.5 { - margin-top: var(--canon-space-1_5); - } - - .md\:cu-mt-2 { - margin-top: var(--canon-space-2); - } - - .md\:cu-mt-3 { - margin-top: var(--canon-space-3); - } - - .md\:cu-mt-4 { - margin-top: var(--canon-space-4); - } - - .md\:cu-mt-5 { - margin-top: var(--canon-space-5); - } - - .md\:cu-mt-6 { - margin-top: var(--canon-space-6); - } - - .md\:cu-mt-7 { - margin-top: var(--canon-space-7); - } - - .md\:cu-mt-8 { - margin-top: var(--canon-space-8); - } - - .md\:cu-mt-9 { - margin-top: var(--canon-space-9); - } - - .md\:cu-mt-10 { - margin-top: var(--canon-space-10); - } - - .md\:cu-mt-11 { - margin-top: var(--canon-space-11); - } - - .md\:cu-mt-12 { - margin-top: var(--canon-space-12); - } - - .md\:cu-mt-13 { - margin-top: var(--canon-space-13); - } - - .md\:cu-mt-14 { - margin-top: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-mt { - margin-top: var(--pt-lg); - } - - .lg\:cu-mt-0\.5 { - margin-top: var(--canon-space-0_5); - } - - .lg\:cu-mt-1 { - margin-top: var(--canon-space-1); - } - - .lg\:cu-mt-1\.5 { - margin-top: var(--canon-space-1_5); - } - - .lg\:cu-mt-2 { - margin-top: var(--canon-space-2); - } - - .lg\:cu-mt-3 { - margin-top: var(--canon-space-3); - } - - .lg\:cu-mt-4 { - margin-top: var(--canon-space-4); - } - - .lg\:cu-mt-5 { - margin-top: var(--canon-space-5); - } - - .lg\:cu-mt-6 { - margin-top: var(--canon-space-6); - } - - .lg\:cu-mt-7 { - margin-top: var(--canon-space-7); - } - - .lg\:cu-mt-8 { - margin-top: var(--canon-space-8); - } - - .lg\:cu-mt-9 { - margin-top: var(--canon-space-9); - } - - .lg\:cu-mt-10 { - margin-top: var(--canon-space-10); - } - - .lg\:cu-mt-11 { - margin-top: var(--canon-space-11); - } - - .lg\:cu-mt-12 { - margin-top: var(--canon-space-12); - } - - .lg\:cu-mt-13 { - margin-top: var(--canon-space-13); - } - - .lg\:cu-mt-14 { - margin-top: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-mt { - margin-top: var(--pt-xl); - } - - .xl\:cu-mt-0\.5 { - margin-top: var(--canon-space-0_5); - } - - .xl\:cu-mt-1 { - margin-top: var(--canon-space-1); - } - - .xl\:cu-mt-1\.5 { - margin-top: var(--canon-space-1_5); - } - - .xl\:cu-mt-2 { - margin-top: var(--canon-space-2); - } - - .xl\:cu-mt-3 { - margin-top: var(--canon-space-3); - } - - .xl\:cu-mt-4 { - margin-top: var(--canon-space-4); - } - - .xl\:cu-mt-5 { - margin-top: var(--canon-space-5); - } - - .xl\:cu-mt-6 { - margin-top: var(--canon-space-6); - } - - .xl\:cu-mt-7 { - margin-top: var(--canon-space-7); - } - - .xl\:cu-mt-8 { - margin-top: var(--canon-space-8); - } - - .xl\:cu-mt-9 { - margin-top: var(--canon-space-9); - } - - .xl\:cu-mt-10 { - margin-top: var(--canon-space-10); - } - - .xl\:cu-mt-11 { - margin-top: var(--canon-space-11); - } - - .xl\:cu-mt-12 { - margin-top: var(--canon-space-12); - } - - .xl\:cu-mt-13 { - margin-top: var(--canon-space-13); - } - - .xl\:cu-mt-14 { - margin-top: var(--canon-space-14); - } -} - -.cu-mb { - margin-bottom: var(--mb); -} - -.cu-mb-0\.5 { - margin-bottom: var(--canon-space-0_5); -} - -.cu-mb-1 { - margin-bottom: var(--canon-space-1); -} - -.cu-mb-1\.5 { - margin-bottom: var(--canon-space-1_5); -} - -.cu-mb-2 { - margin-bottom: var(--canon-space-2); -} - -.cu-mb-3 { - margin-bottom: var(--canon-space-3); -} - -.cu-mb-4 { - margin-bottom: var(--canon-space-4); -} - -.cu-mb-5 { - margin-bottom: var(--canon-space-5); -} - -.cu-mb-6 { - margin-bottom: var(--canon-space-6); -} - -.cu-mb-7 { - margin-bottom: var(--canon-space-7); -} - -.cu-mb-8 { - margin-bottom: var(--canon-space-8); -} - -.cu-mb-9 { - margin-bottom: var(--canon-space-9); -} - -.cu-mb-10 { - margin-bottom: var(--canon-space-10); -} - -.cu-mb-11 { - margin-bottom: var(--canon-space-11); -} - -.cu-mb-12 { - margin-bottom: var(--canon-space-12); -} - -.cu-mb-13 { - margin-bottom: var(--canon-space-13); -} - -.cu-mb-14 { - margin-bottom: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-mb { - margin-bottom: var(--pb-xs); - } - - .xs\:cu-mb-0\.5 { - margin-bottom: var(--canon-space-0_5); - } - - .xs\:cu-mb-1 { - margin-bottom: var(--canon-space-1); - } - - .xs\:cu-mb-1\.5 { - margin-bottom: var(--canon-space-1_5); - } - - .xs\:cu-mb-2 { - margin-bottom: var(--canon-space-2); - } - - .xs\:cu-mb-3 { - margin-bottom: var(--canon-space-3); - } - - .xs\:cu-mb-4 { - margin-bottom: var(--canon-space-4); - } - - .xs\:cu-mb-5 { - margin-bottom: var(--canon-space-5); - } - - .xs\:cu-mb-6 { - margin-bottom: var(--canon-space-6); - } - - .xs\:cu-mb-7 { - margin-bottom: var(--canon-space-7); - } - - .xs\:cu-mb-8 { - margin-bottom: var(--canon-space-8); - } - - .xs\:cu-mb-9 { - margin-bottom: var(--canon-space-9); - } - - .xs\:cu-mb-10 { - margin-bottom: var(--canon-space-10); - } - - .xs\:cu-mb-11 { - margin-bottom: var(--canon-space-11); - } - - .xs\:cu-mb-12 { - margin-bottom: var(--canon-space-12); - } - - .xs\:cu-mb-13 { - margin-bottom: var(--canon-space-13); - } - - .xs\:cu-mb-14 { - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-mb { - margin-bottom: var(--pb-sm); - } - - .sm\:cu-mb-0\.5 { - margin-bottom: var(--canon-space-0_5); - } - - .sm\:cu-mb-1 { - margin-bottom: var(--canon-space-1); - } - - .sm\:cu-mb-1\.5 { - margin-bottom: var(--canon-space-1_5); - } - - .sm\:cu-mb-2 { - margin-bottom: var(--canon-space-2); - } - - .sm\:cu-mb-3 { - margin-bottom: var(--canon-space-3); - } - - .sm\:cu-mb-4 { - margin-bottom: var(--canon-space-4); - } - - .sm\:cu-mb-5 { - margin-bottom: var(--canon-space-5); - } - - .sm\:cu-mb-6 { - margin-bottom: var(--canon-space-6); - } - - .sm\:cu-mb-7 { - margin-bottom: var(--canon-space-7); - } - - .sm\:cu-mb-8 { - margin-bottom: var(--canon-space-8); - } - - .sm\:cu-mb-9 { - margin-bottom: var(--canon-space-9); - } - - .sm\:cu-mb-10 { - margin-bottom: var(--canon-space-10); - } - - .sm\:cu-mb-11 { - margin-bottom: var(--canon-space-11); - } - - .sm\:cu-mb-12 { - margin-bottom: var(--canon-space-12); - } - - .sm\:cu-mb-13 { - margin-bottom: var(--canon-space-13); - } - - .sm\:cu-mb-14 { - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-mb { - margin-bottom: var(--pb-md); - } - - .md\:cu-mb-0\.5 { - margin-bottom: var(--canon-space-0_5); - } - - .md\:cu-mb-1 { - margin-bottom: var(--canon-space-1); - } - - .md\:cu-mb-1\.5 { - margin-bottom: var(--canon-space-1_5); - } - - .md\:cu-mb-2 { - margin-bottom: var(--canon-space-2); - } - - .md\:cu-mb-3 { - margin-bottom: var(--canon-space-3); - } - - .md\:cu-mb-4 { - margin-bottom: var(--canon-space-4); - } - - .md\:cu-mb-5 { - margin-bottom: var(--canon-space-5); - } - - .md\:cu-mb-6 { - margin-bottom: var(--canon-space-6); - } - - .md\:cu-mb-7 { - margin-bottom: var(--canon-space-7); - } - - .md\:cu-mb-8 { - margin-bottom: var(--canon-space-8); - } - - .md\:cu-mb-9 { - margin-bottom: var(--canon-space-9); - } - - .md\:cu-mb-10 { - margin-bottom: var(--canon-space-10); - } - - .md\:cu-mb-11 { - margin-bottom: var(--canon-space-11); - } - - .md\:cu-mb-12 { - margin-bottom: var(--canon-space-12); - } - - .md\:cu-mb-13 { - margin-bottom: var(--canon-space-13); - } - - .md\:cu-mb-14 { - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-mb { - margin-bottom: var(--pb-lg); - } - - .lg\:cu-mb-0\.5 { - margin-bottom: var(--canon-space-0_5); - } - - .lg\:cu-mb-1 { - margin-bottom: var(--canon-space-1); - } - - .lg\:cu-mb-1\.5 { - margin-bottom: var(--canon-space-1_5); - } - - .lg\:cu-mb-2 { - margin-bottom: var(--canon-space-2); - } - - .lg\:cu-mb-3 { - margin-bottom: var(--canon-space-3); - } - - .lg\:cu-mb-4 { - margin-bottom: var(--canon-space-4); - } - - .lg\:cu-mb-5 { - margin-bottom: var(--canon-space-5); - } - - .lg\:cu-mb-6 { - margin-bottom: var(--canon-space-6); - } - - .lg\:cu-mb-7 { - margin-bottom: var(--canon-space-7); - } - - .lg\:cu-mb-8 { - margin-bottom: var(--canon-space-8); - } - - .lg\:cu-mb-9 { - margin-bottom: var(--canon-space-9); - } - - .lg\:cu-mb-10 { - margin-bottom: var(--canon-space-10); - } - - .lg\:cu-mb-11 { - margin-bottom: var(--canon-space-11); - } - - .lg\:cu-mb-12 { - margin-bottom: var(--canon-space-12); - } - - .lg\:cu-mb-13 { - margin-bottom: var(--canon-space-13); - } - - .lg\:cu-mb-14 { - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-mb { - margin-bottom: var(--pb-xl); - } - - .xl\:cu-mb-0\.5 { - margin-bottom: var(--canon-space-0_5); - } - - .xl\:cu-mb-1 { - margin-bottom: var(--canon-space-1); - } - - .xl\:cu-mb-1\.5 { - margin-bottom: var(--canon-space-1_5); - } - - .xl\:cu-mb-2 { - margin-bottom: var(--canon-space-2); - } - - .xl\:cu-mb-3 { - margin-bottom: var(--canon-space-3); - } - - .xl\:cu-mb-4 { - margin-bottom: var(--canon-space-4); - } - - .xl\:cu-mb-5 { - margin-bottom: var(--canon-space-5); - } - - .xl\:cu-mb-6 { - margin-bottom: var(--canon-space-6); - } - - .xl\:cu-mb-7 { - margin-bottom: var(--canon-space-7); - } - - .xl\:cu-mb-8 { - margin-bottom: var(--canon-space-8); - } - - .xl\:cu-mb-9 { - margin-bottom: var(--canon-space-9); - } - - .xl\:cu-mb-10 { - margin-bottom: var(--canon-space-10); - } - - .xl\:cu-mb-11 { - margin-bottom: var(--canon-space-11); - } - - .xl\:cu-mb-12 { - margin-bottom: var(--canon-space-12); - } - - .xl\:cu-mb-13 { - margin-bottom: var(--canon-space-13); - } - - .xl\:cu-mb-14 { - margin-bottom: var(--canon-space-14); - } -} - -.cu-my { - margin-top: var(--my); - margin-bottom: var(--my); -} - -.cu-my-0\.5 { - margin-top: var(--canon-space-0_5); - margin-bottom: var(--canon-space-0_5); -} - -.cu-my-1 { - margin-top: var(--canon-space-1); - margin-bottom: var(--canon-space-1); -} - -.cu-my-1\.5 { - margin-top: var(--canon-space-1_5); - margin-bottom: var(--canon-space-1_5); -} - -.cu-my-2 { - margin-top: var(--canon-space-2); - margin-bottom: var(--canon-space-2); -} - -.cu-my-3 { - margin-top: var(--canon-space-3); - margin-bottom: var(--canon-space-3); -} - -.cu-my-4 { - margin-top: var(--canon-space-4); - margin-bottom: var(--canon-space-4); -} - -.cu-my-5 { - margin-top: var(--canon-space-5); - margin-bottom: var(--canon-space-5); -} - -.cu-my-6 { - margin-top: var(--canon-space-6); - margin-bottom: var(--canon-space-6); -} - -.cu-my-7 { - margin-top: var(--canon-space-7); - margin-bottom: var(--canon-space-7); -} - -.cu-my-8 { - margin-top: var(--canon-space-8); - margin-bottom: var(--canon-space-8); -} - -.cu-my-9 { - margin-top: var(--canon-space-9); - margin-bottom: var(--canon-space-9); -} - -.cu-my-10 { - margin-top: var(--canon-space-10); - margin-bottom: var(--canon-space-10); -} - -.cu-my-11 { - margin-top: var(--canon-space-11); - margin-bottom: var(--canon-space-11); -} - -.cu-my-12 { - margin-top: var(--canon-space-12); - margin-bottom: var(--canon-space-12); -} - -.cu-my-13 { - margin-top: var(--canon-space-13); - margin-bottom: var(--canon-space-13); -} - -.cu-my-14 { - margin-top: var(--canon-space-14); - margin-bottom: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-my { - margin-top: var(--py-xs); - margin-bottom: var(--py-xs); - } - - .xs\:cu-my-0\.5 { - margin-top: var(--canon-space-0_5); - margin-bottom: var(--canon-space-0_5); - } - - .xs\:cu-my-1 { - margin-top: var(--canon-space-1); - margin-bottom: var(--canon-space-1); - } - - .xs\:cu-my-1\.5 { - margin-top: var(--canon-space-1_5); - margin-bottom: var(--canon-space-1_5); - } - - .xs\:cu-my-2 { - margin-top: var(--canon-space-2); - margin-bottom: var(--canon-space-2); - } - - .xs\:cu-my-3 { - margin-top: var(--canon-space-3); - margin-bottom: var(--canon-space-3); - } - - .xs\:cu-my-4 { - margin-top: var(--canon-space-4); - margin-bottom: var(--canon-space-4); - } - - .xs\:cu-my-5 { - margin-top: var(--canon-space-5); - margin-bottom: var(--canon-space-5); - } - - .xs\:cu-my-6 { - margin-top: var(--canon-space-6); - margin-bottom: var(--canon-space-6); - } - - .xs\:cu-my-7 { - margin-top: var(--canon-space-7); - margin-bottom: var(--canon-space-7); - } - - .xs\:cu-my-8 { - margin-top: var(--canon-space-8); - margin-bottom: var(--canon-space-8); - } - - .xs\:cu-my-9 { - margin-top: var(--canon-space-9); - margin-bottom: var(--canon-space-9); - } - - .xs\:cu-my-10 { - margin-top: var(--canon-space-10); - margin-bottom: var(--canon-space-10); - } - - .xs\:cu-my-11 { - margin-top: var(--canon-space-11); - margin-bottom: var(--canon-space-11); - } - - .xs\:cu-my-12 { - margin-top: var(--canon-space-12); - margin-bottom: var(--canon-space-12); - } - - .xs\:cu-my-13 { - margin-top: var(--canon-space-13); - margin-bottom: var(--canon-space-13); - } - - .xs\:cu-my-14 { - margin-top: var(--canon-space-14); - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-my { - margin-top: var(--py-sm); - margin-bottom: var(--py-sm); - } - - .sm\:cu-my-0\.5 { - margin-top: var(--canon-space-0_5); - margin-bottom: var(--canon-space-0_5); - } - - .sm\:cu-my-1 { - margin-top: var(--canon-space-1); - margin-bottom: var(--canon-space-1); - } - - .sm\:cu-my-1\.5 { - margin-top: var(--canon-space-1_5); - margin-bottom: var(--canon-space-1_5); - } - - .sm\:cu-my-2 { - margin-top: var(--canon-space-2); - margin-bottom: var(--canon-space-2); - } - - .sm\:cu-my-3 { - margin-top: var(--canon-space-3); - margin-bottom: var(--canon-space-3); - } - - .sm\:cu-my-4 { - margin-top: var(--canon-space-4); - margin-bottom: var(--canon-space-4); - } - - .sm\:cu-my-5 { - margin-top: var(--canon-space-5); - margin-bottom: var(--canon-space-5); - } - - .sm\:cu-my-6 { - margin-top: var(--canon-space-6); - margin-bottom: var(--canon-space-6); - } - - .sm\:cu-my-7 { - margin-top: var(--canon-space-7); - margin-bottom: var(--canon-space-7); - } - - .sm\:cu-my-8 { - margin-top: var(--canon-space-8); - margin-bottom: var(--canon-space-8); - } - - .sm\:cu-my-9 { - margin-top: var(--canon-space-9); - margin-bottom: var(--canon-space-9); - } - - .sm\:cu-my-10 { - margin-top: var(--canon-space-10); - margin-bottom: var(--canon-space-10); - } - - .sm\:cu-my-11 { - margin-top: var(--canon-space-11); - margin-bottom: var(--canon-space-11); - } - - .sm\:cu-my-12 { - margin-top: var(--canon-space-12); - margin-bottom: var(--canon-space-12); - } - - .sm\:cu-my-13 { - margin-top: var(--canon-space-13); - margin-bottom: var(--canon-space-13); - } - - .sm\:cu-my-14 { - margin-top: var(--canon-space-14); - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-my { - margin-top: var(--py-md); - margin-bottom: var(--py-md); - } - - .md\:cu-my-0\.5 { - margin-top: var(--canon-space-0_5); - margin-bottom: var(--canon-space-0_5); - } - - .md\:cu-my-1 { - margin-top: var(--canon-space-1); - margin-bottom: var(--canon-space-1); - } - - .md\:cu-my-1\.5 { - margin-top: var(--canon-space-1_5); - margin-bottom: var(--canon-space-1_5); - } - - .md\:cu-my-2 { - margin-top: var(--canon-space-2); - margin-bottom: var(--canon-space-2); - } - - .md\:cu-my-3 { - margin-top: var(--canon-space-3); - margin-bottom: var(--canon-space-3); - } - - .md\:cu-my-4 { - margin-top: var(--canon-space-4); - margin-bottom: var(--canon-space-4); - } - - .md\:cu-my-5 { - margin-top: var(--canon-space-5); - margin-bottom: var(--canon-space-5); - } - - .md\:cu-my-6 { - margin-top: var(--canon-space-6); - margin-bottom: var(--canon-space-6); - } - - .md\:cu-my-7 { - margin-top: var(--canon-space-7); - margin-bottom: var(--canon-space-7); - } - - .md\:cu-my-8 { - margin-top: var(--canon-space-8); - margin-bottom: var(--canon-space-8); - } - - .md\:cu-my-9 { - margin-top: var(--canon-space-9); - margin-bottom: var(--canon-space-9); - } - - .md\:cu-my-10 { - margin-top: var(--canon-space-10); - margin-bottom: var(--canon-space-10); - } - - .md\:cu-my-11 { - margin-top: var(--canon-space-11); - margin-bottom: var(--canon-space-11); - } - - .md\:cu-my-12 { - margin-top: var(--canon-space-12); - margin-bottom: var(--canon-space-12); - } - - .md\:cu-my-13 { - margin-top: var(--canon-space-13); - margin-bottom: var(--canon-space-13); - } - - .md\:cu-my-14 { - margin-top: var(--canon-space-14); - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-my { - margin-top: var(--py-lg); - margin-bottom: var(--py-lg); - } - - .lg\:cu-my-0\.5 { - margin-top: var(--canon-space-0_5); - margin-bottom: var(--canon-space-0_5); - } - - .lg\:cu-my-1 { - margin-top: var(--canon-space-1); - margin-bottom: var(--canon-space-1); - } - - .lg\:cu-my-1\.5 { - margin-top: var(--canon-space-1_5); - margin-bottom: var(--canon-space-1_5); - } - - .lg\:cu-my-2 { - margin-top: var(--canon-space-2); - margin-bottom: var(--canon-space-2); - } - - .lg\:cu-my-3 { - margin-top: var(--canon-space-3); - margin-bottom: var(--canon-space-3); - } - - .lg\:cu-my-4 { - margin-top: var(--canon-space-4); - margin-bottom: var(--canon-space-4); - } - - .lg\:cu-my-5 { - margin-top: var(--canon-space-5); - margin-bottom: var(--canon-space-5); - } - - .lg\:cu-my-6 { - margin-top: var(--canon-space-6); - margin-bottom: var(--canon-space-6); - } - - .lg\:cu-my-7 { - margin-top: var(--canon-space-7); - margin-bottom: var(--canon-space-7); - } - - .lg\:cu-my-8 { - margin-top: var(--canon-space-8); - margin-bottom: var(--canon-space-8); - } - - .lg\:cu-my-9 { - margin-top: var(--canon-space-9); - margin-bottom: var(--canon-space-9); - } - - .lg\:cu-my-10 { - margin-top: var(--canon-space-10); - margin-bottom: var(--canon-space-10); - } - - .lg\:cu-my-11 { - margin-top: var(--canon-space-11); - margin-bottom: var(--canon-space-11); - } - - .lg\:cu-my-12 { - margin-top: var(--canon-space-12); - margin-bottom: var(--canon-space-12); - } - - .lg\:cu-my-13 { - margin-top: var(--canon-space-13); - margin-bottom: var(--canon-space-13); - } - - .lg\:cu-my-14 { - margin-top: var(--canon-space-14); - margin-bottom: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-my { - margin-top: var(--py-xl); - margin-bottom: var(--py-xl); - } - - .xl\:cu-my-0\.5 { - margin-top: var(--canon-space-0_5); - margin-bottom: var(--canon-space-0_5); - } - - .xl\:cu-my-1 { - margin-top: var(--canon-space-1); - margin-bottom: var(--canon-space-1); - } - - .xl\:cu-my-1\.5 { - margin-top: var(--canon-space-1_5); - margin-bottom: var(--canon-space-1_5); - } - - .xl\:cu-my-2 { - margin-top: var(--canon-space-2); - margin-bottom: var(--canon-space-2); - } - - .xl\:cu-my-3 { - margin-top: var(--canon-space-3); - margin-bottom: var(--canon-space-3); - } - - .xl\:cu-my-4 { - margin-top: var(--canon-space-4); - margin-bottom: var(--canon-space-4); - } - - .xl\:cu-my-5 { - margin-top: var(--canon-space-5); - margin-bottom: var(--canon-space-5); - } - - .xl\:cu-my-6 { - margin-top: var(--canon-space-6); - margin-bottom: var(--canon-space-6); - } - - .xl\:cu-my-7 { - margin-top: var(--canon-space-7); - margin-bottom: var(--canon-space-7); - } - - .xl\:cu-my-8 { - margin-top: var(--canon-space-8); - margin-bottom: var(--canon-space-8); - } - - .xl\:cu-my-9 { - margin-top: var(--canon-space-9); - margin-bottom: var(--canon-space-9); - } - - .xl\:cu-my-10 { - margin-top: var(--canon-space-10); - margin-bottom: var(--canon-space-10); - } - - .xl\:cu-my-11 { - margin-top: var(--canon-space-11); - margin-bottom: var(--canon-space-11); - } - - .xl\:cu-my-12 { - margin-top: var(--canon-space-12); - margin-bottom: var(--canon-space-12); - } - - .xl\:cu-my-13 { - margin-top: var(--canon-space-13); - margin-bottom: var(--canon-space-13); - } - - .xl\:cu-my-14 { - margin-top: var(--canon-space-14); - margin-bottom: var(--canon-space-14); - } -} - -.cu-mx { - margin-left: var(--mx); - margin-right: var(--mx); -} - -.cu-mx-0\.5 { - margin-left: var(--canon-space-0_5); - margin-right: var(--canon-space-0_5); -} - -.cu-mx-1 { - margin-left: var(--canon-space-1); - margin-right: var(--canon-space-1); -} - -.cu-mx-1\.5 { - margin-left: var(--canon-space-1_5); - margin-right: var(--canon-space-1_5); -} - -.cu-mx-2 { - margin-left: var(--canon-space-2); - margin-right: var(--canon-space-2); -} - -.cu-mx-3 { - margin-left: var(--canon-space-3); - margin-right: var(--canon-space-3); -} - -.cu-mx-4 { - margin-left: var(--canon-space-4); - margin-right: var(--canon-space-4); -} - -.cu-mx-5 { - margin-left: var(--canon-space-5); - margin-right: var(--canon-space-5); -} - -.cu-mx-6 { - margin-left: var(--canon-space-6); - margin-right: var(--canon-space-6); -} - -.cu-mx-7 { - margin-left: var(--canon-space-7); - margin-right: var(--canon-space-7); -} - -.cu-mx-8 { - margin-left: var(--canon-space-8); - margin-right: var(--canon-space-8); -} - -.cu-mx-9 { - margin-left: var(--canon-space-9); - margin-right: var(--canon-space-9); -} - -.cu-mx-10 { - margin-left: var(--canon-space-10); - margin-right: var(--canon-space-10); -} - -.cu-mx-11 { - margin-left: var(--canon-space-11); - margin-right: var(--canon-space-11); -} - -.cu-mx-12 { - margin-left: var(--canon-space-12); - margin-right: var(--canon-space-12); -} - -.cu-mx-13 { - margin-left: var(--canon-space-13); - margin-right: var(--canon-space-13); -} - -.cu-mx-14 { - margin-left: var(--canon-space-14); - margin-right: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-mx { - margin-left: var(--px-xs); - margin-right: var(--px-xs); - } - - .xs\:cu-mx-0\.5 { - margin-left: var(--canon-space-0_5); - margin-right: var(--canon-space-0_5); - } - - .xs\:cu-mx-1 { - margin-left: var(--canon-space-1); - margin-right: var(--canon-space-1); - } - - .xs\:cu-mx-1\.5 { - margin-left: var(--canon-space-1_5); - margin-right: var(--canon-space-1_5); - } - - .xs\:cu-mx-2 { - margin-left: var(--canon-space-2); - margin-right: var(--canon-space-2); - } - - .xs\:cu-mx-3 { - margin-left: var(--canon-space-3); - margin-right: var(--canon-space-3); - } - - .xs\:cu-mx-4 { - margin-left: var(--canon-space-4); - margin-right: var(--canon-space-4); - } - - .xs\:cu-mx-5 { - margin-left: var(--canon-space-5); - margin-right: var(--canon-space-5); - } - - .xs\:cu-mx-6 { - margin-left: var(--canon-space-6); - margin-right: var(--canon-space-6); - } - - .xs\:cu-mx-7 { - margin-left: var(--canon-space-7); - margin-right: var(--canon-space-7); - } - - .xs\:cu-mx-8 { - margin-left: var(--canon-space-8); - margin-right: var(--canon-space-8); - } - - .xs\:cu-mx-9 { - margin-left: var(--canon-space-9); - margin-right: var(--canon-space-9); - } - - .xs\:cu-mx-10 { - margin-left: var(--canon-space-10); - margin-right: var(--canon-space-10); - } - - .xs\:cu-mx-11 { - margin-left: var(--canon-space-11); - margin-right: var(--canon-space-11); - } - - .xs\:cu-mx-12 { - margin-left: var(--canon-space-12); - margin-right: var(--canon-space-12); - } - - .xs\:cu-mx-13 { - margin-left: var(--canon-space-13); - margin-right: var(--canon-space-13); - } - - .xs\:cu-mx-14 { - margin-left: var(--canon-space-14); - margin-right: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-mx { - margin-left: var(--px-sm); - margin-right: var(--px-sm); - } - - .sm\:cu-mx-0\.5 { - margin-left: var(--canon-space-0_5); - margin-right: var(--canon-space-0_5); - } - - .sm\:cu-mx-1 { - margin-left: var(--canon-space-1); - margin-right: var(--canon-space-1); - } - - .sm\:cu-mx-1\.5 { - margin-left: var(--canon-space-1_5); - margin-right: var(--canon-space-1_5); - } - - .sm\:cu-mx-2 { - margin-left: var(--canon-space-2); - margin-right: var(--canon-space-2); - } - - .sm\:cu-mx-3 { - margin-left: var(--canon-space-3); - margin-right: var(--canon-space-3); - } - - .sm\:cu-mx-4 { - margin-left: var(--canon-space-4); - margin-right: var(--canon-space-4); - } - - .sm\:cu-mx-5 { - margin-left: var(--canon-space-5); - margin-right: var(--canon-space-5); - } - - .sm\:cu-mx-6 { - margin-left: var(--canon-space-6); - margin-right: var(--canon-space-6); - } - - .sm\:cu-mx-7 { - margin-left: var(--canon-space-7); - margin-right: var(--canon-space-7); - } - - .sm\:cu-mx-8 { - margin-left: var(--canon-space-8); - margin-right: var(--canon-space-8); - } - - .sm\:cu-mx-9 { - margin-left: var(--canon-space-9); - margin-right: var(--canon-space-9); - } - - .sm\:cu-mx-10 { - margin-left: var(--canon-space-10); - margin-right: var(--canon-space-10); - } - - .sm\:cu-mx-11 { - margin-left: var(--canon-space-11); - margin-right: var(--canon-space-11); - } - - .sm\:cu-mx-12 { - margin-left: var(--canon-space-12); - margin-right: var(--canon-space-12); - } - - .sm\:cu-mx-13 { - margin-left: var(--canon-space-13); - margin-right: var(--canon-space-13); - } - - .sm\:cu-mx-14 { - margin-left: var(--canon-space-14); - margin-right: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-mx { - margin-left: var(--px-md); - margin-right: var(--px-md); - } - - .md\:cu-mx-0\.5 { - margin-left: var(--canon-space-0_5); - margin-right: var(--canon-space-0_5); - } - - .md\:cu-mx-1 { - margin-left: var(--canon-space-1); - margin-right: var(--canon-space-1); - } - - .md\:cu-mx-1\.5 { - margin-left: var(--canon-space-1_5); - margin-right: var(--canon-space-1_5); - } - - .md\:cu-mx-2 { - margin-left: var(--canon-space-2); - margin-right: var(--canon-space-2); - } - - .md\:cu-mx-3 { - margin-left: var(--canon-space-3); - margin-right: var(--canon-space-3); - } - - .md\:cu-mx-4 { - margin-left: var(--canon-space-4); - margin-right: var(--canon-space-4); - } - - .md\:cu-mx-5 { - margin-left: var(--canon-space-5); - margin-right: var(--canon-space-5); - } - - .md\:cu-mx-6 { - margin-left: var(--canon-space-6); - margin-right: var(--canon-space-6); - } - - .md\:cu-mx-7 { - margin-left: var(--canon-space-7); - margin-right: var(--canon-space-7); - } - - .md\:cu-mx-8 { - margin-left: var(--canon-space-8); - margin-right: var(--canon-space-8); - } - - .md\:cu-mx-9 { - margin-left: var(--canon-space-9); - margin-right: var(--canon-space-9); - } - - .md\:cu-mx-10 { - margin-left: var(--canon-space-10); - margin-right: var(--canon-space-10); - } - - .md\:cu-mx-11 { - margin-left: var(--canon-space-11); - margin-right: var(--canon-space-11); - } - - .md\:cu-mx-12 { - margin-left: var(--canon-space-12); - margin-right: var(--canon-space-12); - } - - .md\:cu-mx-13 { - margin-left: var(--canon-space-13); - margin-right: var(--canon-space-13); - } - - .md\:cu-mx-14 { - margin-left: var(--canon-space-14); - margin-right: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-mx { - margin-left: var(--px-lg); - margin-right: var(--px-lg); - } - - .lg\:cu-mx-0\.5 { - margin-left: var(--canon-space-0_5); - margin-right: var(--canon-space-0_5); - } - - .lg\:cu-mx-1 { - margin-left: var(--canon-space-1); - margin-right: var(--canon-space-1); - } - - .lg\:cu-mx-1\.5 { - margin-left: var(--canon-space-1_5); - margin-right: var(--canon-space-1_5); - } - - .lg\:cu-mx-2 { - margin-left: var(--canon-space-2); - margin-right: var(--canon-space-2); - } - - .lg\:cu-mx-3 { - margin-left: var(--canon-space-3); - margin-right: var(--canon-space-3); - } - - .lg\:cu-mx-4 { - margin-left: var(--canon-space-4); - margin-right: var(--canon-space-4); - } - - .lg\:cu-mx-5 { - margin-left: var(--canon-space-5); - margin-right: var(--canon-space-5); - } - - .lg\:cu-mx-6 { - margin-left: var(--canon-space-6); - margin-right: var(--canon-space-6); - } - - .lg\:cu-mx-7 { - margin-left: var(--canon-space-7); - margin-right: var(--canon-space-7); - } - - .lg\:cu-mx-8 { - margin-left: var(--canon-space-8); - margin-right: var(--canon-space-8); - } - - .lg\:cu-mx-9 { - margin-left: var(--canon-space-9); - margin-right: var(--canon-space-9); - } - - .lg\:cu-mx-10 { - margin-left: var(--canon-space-10); - margin-right: var(--canon-space-10); - } - - .lg\:cu-mx-11 { - margin-left: var(--canon-space-11); - margin-right: var(--canon-space-11); - } - - .lg\:cu-mx-12 { - margin-left: var(--canon-space-12); - margin-right: var(--canon-space-12); - } - - .lg\:cu-mx-13 { - margin-left: var(--canon-space-13); - margin-right: var(--canon-space-13); - } - - .lg\:cu-mx-14 { - margin-left: var(--canon-space-14); - margin-right: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-mx { - margin-left: var(--px-xl); - margin-right: var(--px-xl); - } - - .xl\:cu-mx-0\.5 { - margin-left: var(--canon-space-0_5); - margin-right: var(--canon-space-0_5); - } - - .xl\:cu-mx-1 { - margin-left: var(--canon-space-1); - margin-right: var(--canon-space-1); - } - - .xl\:cu-mx-1\.5 { - margin-left: var(--canon-space-1_5); - margin-right: var(--canon-space-1_5); - } - - .xl\:cu-mx-2 { - margin-left: var(--canon-space-2); - margin-right: var(--canon-space-2); - } - - .xl\:cu-mx-3 { - margin-left: var(--canon-space-3); - margin-right: var(--canon-space-3); - } - - .xl\:cu-mx-4 { - margin-left: var(--canon-space-4); - margin-right: var(--canon-space-4); - } - - .xl\:cu-mx-5 { - margin-left: var(--canon-space-5); - margin-right: var(--canon-space-5); - } - - .xl\:cu-mx-6 { - margin-left: var(--canon-space-6); - margin-right: var(--canon-space-6); - } - - .xl\:cu-mx-7 { - margin-left: var(--canon-space-7); - margin-right: var(--canon-space-7); - } - - .xl\:cu-mx-8 { - margin-left: var(--canon-space-8); - margin-right: var(--canon-space-8); - } - - .xl\:cu-mx-9 { - margin-left: var(--canon-space-9); - margin-right: var(--canon-space-9); - } - - .xl\:cu-mx-10 { - margin-left: var(--canon-space-10); - margin-right: var(--canon-space-10); - } - - .xl\:cu-mx-11 { - margin-left: var(--canon-space-11); - margin-right: var(--canon-space-11); - } - - .xl\:cu-mx-12 { - margin-left: var(--canon-space-12); - margin-right: var(--canon-space-12); - } - - .xl\:cu-mx-13 { - margin-left: var(--canon-space-13); - margin-right: var(--canon-space-13); - } - - .xl\:cu-mx-14 { - margin-left: var(--canon-space-14); - margin-right: var(--canon-space-14); - } -} - -.cu-display-none { - display: none; -} - -.cu-display-inline { - display: inline; -} - -.cu-display-inline-block { - display: inline-block; -} - -.cu-display-block { - display: block; -} - -@media (width >= 640px) { - .xs\:cu-display-none { - display: none; - } - - .xs\:cu-display-inline { - display: inline; - } - - .xs\:cu-display-inline-block { - display: inline-block; - } - - .xs\:cu-display-block { - display: block; - } -} - -@media (width >= 768px) { - .sm\:cu-display-none { - display: none; - } - - .sm\:cu-display-inline { - display: inline; - } - - .sm\:cu-display-inline-block { - display: inline-block; - } - - .sm\:cu-display-block { - display: block; - } -} - -@media (width >= 1024px) { - .md\:cu-display-none { - display: none; - } - - .md\:cu-display-inline { - display: inline; - } - - .md\:cu-display-inline-block { - display: inline-block; - } - - .md\:cu-display-block { - display: block; - } -} - -@media (width >= 1280px) { - .lg\:cu-display-none { - display: none; - } - - .lg\:cu-display-inline { - display: inline; - } - - .lg\:cu-display-inline-block { - display: inline-block; - } - - .lg\:cu-display-block { - display: block; - } -} - -@media (width >= 1536px) { - .xl\:cu-display-none { - display: none; - } - - .xl\:cu-display-inline { - display: inline; - } - - .xl\:cu-display-inline-block { - display: inline-block; - } - - .xl\:cu-display-block { - display: block; - } -} - -.cu-w { - width: var(--width); -} - -.cu-min-w { - min-width: var(--min-width); -} - -.cu-max-w { - max-width: var(--max-width); -} - -@media (width >= 640px) { - .xs\:cu-w { - width: var(--width); - } - - .xs\:cu-min-w { - min-width: var(--min-width); - } - - .xs\:cu-max-w { - max-width: var(--max-width); - } -} - -@media (width >= 768px) { - .sm\:cu-w { - width: var(--width); - } - - .sm\:cu-min-w { - min-width: var(--min-width); - } - - .sm\:cu-max-w { - max-width: var(--max-width); - } -} - -@media (width >= 1024px) { - .md\:cu-w { - width: var(--width); - } - - .md\:cu-min-w { - min-width: var(--min-width); - } - - .md\:cu-max-w { - max-width: var(--max-width); - } -} - -@media (width >= 1280px) { - .lg\:cu-w { - width: var(--width); - } - - .lg\:cu-min-w { - min-width: var(--min-width); - } - - .lg\:cu-max-w { - max-width: var(--max-width); - } -} - -@media (width >= 1536px) { - .xl\:cu-w { - width: var(--width); - } - - .xl\:cu-min-w { - min-width: var(--min-width); - } - - .xl\:cu-max-w { - max-width: var(--max-width); - } -} - -.cu-h { - height: var(--height); -} - -.cu-min-h { - min-height: var(--min-height); -} - -.cu-max-h { - max-height: var(--max-height); -} - -@media (width >= 640px) { - .xs\:cu-h { - height: var(--height); - } - - .xs\:cu-min-h { - min-height: var(--min-height); - } - - .xs\:cu-max-h { - max-height: var(--max-height); - } -} - -@media (width >= 768px) { - .sm\:cu-h { - height: var(--height); - } - - .sm\:cu-min-h { - min-height: var(--min-height); - } - - .sm\:cu-max-h { - max-height: var(--max-height); - } -} - -@media (width >= 1024px) { - .md\:cu-h { - height: var(--height); - } - - .md\:cu-min-h { - min-height: var(--min-height); - } - - .md\:cu-max-h { - max-height: var(--max-height); - } -} - -@media (width >= 1280px) { - .lg\:cu-h { - height: var(--height); - } - - .lg\:cu-min-h { - min-height: var(--min-height); - } - - .lg\:cu-max-h { - max-height: var(--max-height); - } -} - -@media (width >= 1536px) { - .xl\:cu-h { - height: var(--height); - } - - .xl\:cu-min-h { - min-height: var(--min-height); - } - - .xl\:cu-max-h { - max-height: var(--max-height); - } -} - -.cu-position-absolute { - position: absolute; -} - -.cu-position-fixed { - position: fixed; -} - -.cu-position-sticky { - position: sticky; -} - -.cu-position-relative { - position: relative; -} - -.cu-position-static { - position: static; -} - -@media (width >= 640px) { - .xs\:cu-position-absolute { - position: absolute; - } - - .xs\:cu-position-fixed { - position: fixed; - } - - .xs\:cu-position-sticky { - position: sticky; - } - - .xs\:cu-position-relative { - position: relative; - } - - .xs\:cu-position-static { - position: static; - } -} - -@media (width >= 768px) { - .sm\:cu-position-absolute { - position: absolute; - } - - .sm\:cu-position-fixed { - position: fixed; - } - - .sm\:cu-position-sticky { - position: sticky; - } - - .sm\:cu-position-relative { - position: relative; - } - - .sm\:cu-position-static { - position: static; - } -} - -@media (width >= 1024px) { - .md\:cu-position-absolute { - position: absolute; - } - - .md\:cu-position-fixed { - position: fixed; - } - - .md\:cu-position-sticky { - position: sticky; - } - - .md\:cu-position-relative { - position: relative; - } - - .md\:cu-position-static { - position: static; - } -} - -@media (width >= 1280px) { - .lg\:cu-position-absolute { - position: absolute; - } - - .lg\:cu-position-fixed { - position: fixed; - } - - .lg\:cu-position-sticky { - position: sticky; - } - - .lg\:cu-position-relative { - position: relative; - } - - .lg\:cu-position-static { - position: static; - } -} - -@media (width >= 1536px) { - .xl\:cu-position-absolute { - position: absolute; - } - - .xl\:cu-position-fixed { - position: fixed; - } - - .xl\:cu-position-sticky { - position: sticky; - } - - .xl\:cu-position-relative { - position: relative; - } - - .xl\:cu-position-static { - position: static; - } -} - -.cu-columns-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); -} - -.cu-columns-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.cu-columns-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); -} - -.cu-columns-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); -} - -.cu-columns-5 { - grid-template-columns: repeat(5, minmax(0, 1fr)); -} - -.cu-columns-6 { - grid-template-columns: repeat(6, minmax(0, 1fr)); -} - -.cu-columns-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); -} - -.cu-columns-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); -} - -.cu-columns-9 { - grid-template-columns: repeat(9, minmax(0, 1fr)); -} - -.cu-columns-10 { - grid-template-columns: repeat(10, minmax(0, 1fr)); -} - -.cu-columns-11 { - grid-template-columns: repeat(11, minmax(0, 1fr)); -} - -.cu-columns-12 { - grid-template-columns: repeat(12, minmax(0, 1fr)); -} - -.cu-columns-auto { - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); -} - -.cu-col-span-1 { - grid-column: span 1 / span 1; -} - -.cu-col-span-2 { - grid-column: span 2 / span 2; -} - -.cu-col-span-3 { - grid-column: span 3 / span 3; -} - -.cu-col-span-4 { - grid-column: span 4 / span 4; -} - -.cu-col-span-5 { - grid-column: span 5 / span 5; -} - -.cu-col-span-6 { - grid-column: span 6 / span 6; -} - -.cu-col-span-7 { - grid-column: span 7 / span 7; -} - -.cu-col-span-8 { - grid-column: span 8 / span 8; -} - -.cu-col-span-9 { - grid-column: span 9 / span 9; -} - -.cu-col-span-10 { - grid-column: span 10 / span 10; -} - -.cu-col-span-11 { - grid-column: span 11 / span 11; -} - -.cu-col-span-12 { - grid-column: span 12 / span 12; -} - -.cu-col-span-auto { - grid-column: span auto / span auto; -} - -.cu-col-start-1 { - grid-column-start: 1; -} - -.cu-col-start-2 { - grid-column-start: 2; -} - -.cu-col-start-3 { - grid-column-start: 3; -} - -.cu-col-start-4 { - grid-column-start: 4; -} - -.cu-col-start-5 { - grid-column-start: 5; -} - -.cu-col-start-6 { - grid-column-start: 6; -} - -.cu-col-start-7 { - grid-column-start: 7; -} - -.cu-col-start-8 { - grid-column-start: 8; -} - -.cu-col-start-9 { - grid-column-start: 9; -} - -.cu-col-start-10 { - grid-column-start: 10; -} - -.cu-col-start-11 { - grid-column-start: 11; -} - -.cu-col-start-12 { - grid-column-start: 12; -} - -.cu-col-start-13 { - grid-column-start: 13; -} - -.cu-col-start-auto { - grid-column-start: auto; -} - -.cu-col-end-1 { - grid-column-end: 1; -} - -.cu-col-end-2 { - grid-column-end: 2; -} - -.cu-col-end-3 { - grid-column-end: 3; -} - -.cu-col-end-4 { - grid-column-end: 4; -} - -.cu-col-end-5 { - grid-column-end: 5; -} - -.cu-col-end-6 { - grid-column-end: 6; -} - -.cu-col-end-7 { - grid-column-end: 7; -} - -.cu-col-end-8 { - grid-column-end: 8; -} - -.cu-col-end-9 { - grid-column-end: 9; -} - -.cu-col-end-10 { - grid-column-end: 10; -} - -.cu-col-end-11 { - grid-column-end: 11; -} - -.cu-col-end-12 { - grid-column-end: 12; -} - -.cu-col-end-13 { - grid-column-end: 13; -} - -.cu-col-end-auto { - grid-column-end: auto; -} - -.cu-row-span-1 { - grid-row: span 1 / span 1; -} - -.cu-row-span-2 { - grid-row: span 2 / span 2; -} - -.cu-row-span-3 { - grid-row: span 3 / span 3; -} - -.cu-row-span-4 { - grid-row: span 4 / span 4; -} - -.cu-row-span-5 { - grid-row: span 5 / span 5; -} - -.cu-row-span-6 { - grid-row: span 6 / span 6; -} - -.cu-row-span-7 { - grid-row: span 7 / span 7; -} - -.cu-row-span-8 { - grid-row: span 8 / span 8; -} - -.cu-row-span-9 { - grid-row: span 9 / span 9; -} - -.cu-row-span-10 { - grid-row: span 10 / span 10; -} - -.cu-row-span-11 { - grid-row: span 11 / span 11; -} - -.cu-row-span-12 { - grid-row: span 12 / span 12; -} - -.cu-row-span-auto { - grid-row: span auto / span auto; -} - -@media (width >= 640px) { - .xs\:cu-columns-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); - } - - .xs\:cu-columns-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .xs\:cu-columns-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .xs\:cu-columns-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .xs\:cu-columns-5 { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - - .xs\:cu-columns-6 { - grid-template-columns: repeat(6, minmax(0, 1fr)); - } - - .xs\:cu-columns-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); - } - - .xs\:cu-columns-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } - - .xs\:cu-columns-9 { - grid-template-columns: repeat(9, minmax(0, 1fr)); - } - - .xs\:cu-columns-10 { - grid-template-columns: repeat(10, minmax(0, 1fr)); - } - - .xs\:cu-columns-11 { - grid-template-columns: repeat(11, minmax(0, 1fr)); - } - - .xs\:cu-columns-12 { - grid-template-columns: repeat(12, minmax(0, 1fr)); - } - - .xs\:cu-columns-auto { - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); - } - - .xs\:cu-col-span-1 { - grid-column: span 1 / span 1; - } - - .xs\:cu-col-span-2 { - grid-column: span 2 / span 2; - } - - .xs\:cu-col-span-3 { - grid-column: span 3 / span 3; - } - - .xs\:cu-col-span-4 { - grid-column: span 4 / span 4; - } - - .xs\:cu-col-span-5 { - grid-column: span 5 / span 5; - } - - .xs\:cu-col-span-6 { - grid-column: span 6 / span 6; - } - - .xs\:cu-col-span-7 { - grid-column: span 7 / span 7; - } - - .xs\:cu-col-span-8 { - grid-column: span 8 / span 8; - } - - .xs\:cu-col-span-9 { - grid-column: span 9 / span 9; - } - - .xs\:cu-col-span-10 { - grid-column: span 10 / span 10; - } - - .xs\:cu-col-span-11 { - grid-column: span 11 / span 11; - } - - .xs\:cu-col-span-12 { - grid-column: span 12 / span 12; - } - - .xs\:cu-col-span-auto { - grid-column: span auto / span auto; - } - - .xs\:cu-col-start-1 { - grid-column-start: 1; - } - - .xs\:cu-col-start-2 { - grid-column-start: 2; - } - - .xs\:cu-col-start-3 { - grid-column-start: 3; - } - - .xs\:cu-col-start-4 { - grid-column-start: 4; - } - - .xs\:cu-col-start-5 { - grid-column-start: 5; - } - - .xs\:cu-col-start-6 { - grid-column-start: 6; - } - - .xs\:cu-col-start-7 { - grid-column-start: 7; - } - - .xs\:cu-col-start-8 { - grid-column-start: 8; - } - - .xs\:cu-col-start-9 { - grid-column-start: 9; - } - - .xs\:cu-col-start-10 { - grid-column-start: 10; - } - - .xs\:cu-col-start-11 { - grid-column-start: 11; - } - - .xs\:cu-col-start-12 { - grid-column-start: 12; - } - - .xs\:cu-col-start-13 { - grid-column-start: 13; - } - - .xs\:cu-col-start-auto { - grid-column-start: auto; - } - - .xs\:cu-col-end-1 { - grid-column-end: 1; - } - - .xs\:cu-col-end-2 { - grid-column-end: 2; - } - - .xs\:cu-col-end-3 { - grid-column-end: 3; - } - - .xs\:cu-col-end-4 { - grid-column-end: 4; - } - - .xs\:cu-col-end-5 { - grid-column-end: 5; - } - - .xs\:cu-col-end-6 { - grid-column-end: 6; - } - - .xs\:cu-col-end-7 { - grid-column-end: 7; - } - - .xs\:cu-col-end-8 { - grid-column-end: 8; - } - - .xs\:cu-col-end-9 { - grid-column-end: 9; - } - - .xs\:cu-col-end-10 { - grid-column-end: 10; - } - - .xs\:cu-col-end-11 { - grid-column-end: 11; - } - - .xs\:cu-col-end-12 { - grid-column-end: 12; - } - - .xs\:cu-col-end-13 { - grid-column-end: 13; - } - - .xs\:cu-col-end-auto { - grid-column-end: auto; - } - - .xs\:cu-row-span-1 { - grid-row: span 1 / span 1; - } - - .xs\:cu-row-span-2 { - grid-row: span 2 / span 2; - } - - .xs\:cu-row-span-3 { - grid-row: span 3 / span 3; - } - - .xs\:cu-row-span-4 { - grid-row: span 4 / span 4; - } - - .xs\:cu-row-span-5 { - grid-row: span 5 / span 5; - } - - .xs\:cu-row-span-6 { - grid-row: span 6 / span 6; - } - - .xs\:cu-row-span-7 { - grid-row: span 7 / span 7; - } - - .xs\:cu-row-span-8 { - grid-row: span 8 / span 8; - } - - .xs\:cu-row-span-9 { - grid-row: span 9 / span 9; - } - - .xs\:cu-row-span-10 { - grid-row: span 10 / span 10; - } - - .xs\:cu-row-span-11 { - grid-row: span 11 / span 11; - } - - .xs\:cu-row-span-12 { - grid-row: span 12 / span 12; - } - - .xs\:cu-row-span-auto { - grid-row: span auto / span auto; - } -} - -@media (width >= 768px) { - .sm\:cu-columns-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); - } - - .sm\:cu-columns-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .sm\:cu-columns-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .sm\:cu-columns-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .sm\:cu-columns-5 { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - - .sm\:cu-columns-6 { - grid-template-columns: repeat(6, minmax(0, 1fr)); - } - - .sm\:cu-columns-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); - } - - .sm\:cu-columns-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } - - .sm\:cu-columns-9 { - grid-template-columns: repeat(9, minmax(0, 1fr)); - } - - .sm\:cu-columns-10 { - grid-template-columns: repeat(10, minmax(0, 1fr)); - } - - .sm\:cu-columns-11 { - grid-template-columns: repeat(11, minmax(0, 1fr)); - } - - .sm\:cu-columns-12 { - grid-template-columns: repeat(12, minmax(0, 1fr)); - } - - .sm\:cu-columns-auto { - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); - } - - .sm\:cu-col-span-1 { - grid-column: span 1 / span 1; - } - - .sm\:cu-col-span-2 { - grid-column: span 2 / span 2; - } - - .sm\:cu-col-span-3 { - grid-column: span 3 / span 3; - } - - .sm\:cu-col-span-4 { - grid-column: span 4 / span 4; - } - - .sm\:cu-col-span-5 { - grid-column: span 5 / span 5; - } - - .sm\:cu-col-span-6 { - grid-column: span 6 / span 6; - } - - .sm\:cu-col-span-7 { - grid-column: span 7 / span 7; - } - - .sm\:cu-col-span-8 { - grid-column: span 8 / span 8; - } - - .sm\:cu-col-span-9 { - grid-column: span 9 / span 9; - } - - .sm\:cu-col-span-10 { - grid-column: span 10 / span 10; - } - - .sm\:cu-col-span-11 { - grid-column: span 11 / span 11; - } - - .sm\:cu-col-span-12 { - grid-column: span 12 / span 12; - } - - .sm\:cu-col-span-auto { - grid-column: span auto / span auto; - } - - .sm\:cu-col-start-1 { - grid-column-start: 1; - } - - .sm\:cu-col-start-2 { - grid-column-start: 2; - } - - .sm\:cu-col-start-3 { - grid-column-start: 3; - } - - .sm\:cu-col-start-4 { - grid-column-start: 4; - } - - .sm\:cu-col-start-5 { - grid-column-start: 5; - } - - .sm\:cu-col-start-6 { - grid-column-start: 6; - } - - .sm\:cu-col-start-7 { - grid-column-start: 7; - } - - .sm\:cu-col-start-8 { - grid-column-start: 8; - } - - .sm\:cu-col-start-9 { - grid-column-start: 9; - } - - .sm\:cu-col-start-10 { - grid-column-start: 10; - } - - .sm\:cu-col-start-11 { - grid-column-start: 11; - } - - .sm\:cu-col-start-12 { - grid-column-start: 12; - } - - .sm\:cu-col-start-13 { - grid-column-start: 13; - } - - .sm\:cu-col-start-auto { - grid-column-start: auto; - } - - .sm\:cu-col-end-1 { - grid-column-end: 1; - } - - .sm\:cu-col-end-2 { - grid-column-end: 2; - } - - .sm\:cu-col-end-3 { - grid-column-end: 3; - } - - .sm\:cu-col-end-4 { - grid-column-end: 4; - } - - .sm\:cu-col-end-5 { - grid-column-end: 5; - } - - .sm\:cu-col-end-6 { - grid-column-end: 6; - } - - .sm\:cu-col-end-7 { - grid-column-end: 7; - } - - .sm\:cu-col-end-8 { - grid-column-end: 8; - } - - .sm\:cu-col-end-9 { - grid-column-end: 9; - } - - .sm\:cu-col-end-10 { - grid-column-end: 10; - } - - .sm\:cu-col-end-11 { - grid-column-end: 11; - } - - .sm\:cu-col-end-12 { - grid-column-end: 12; - } - - .sm\:cu-col-end-13 { - grid-column-end: 13; - } - - .sm\:cu-col-end-auto { - grid-column-end: auto; - } - - .sm\:cu-row-span-1 { - grid-row: span 1 / span 1; - } - - .sm\:cu-row-span-2 { - grid-row: span 2 / span 2; - } - - .sm\:cu-row-span-3 { - grid-row: span 3 / span 3; - } - - .sm\:cu-row-span-4 { - grid-row: span 4 / span 4; - } - - .sm\:cu-row-span-5 { - grid-row: span 5 / span 5; - } - - .sm\:cu-row-span-6 { - grid-row: span 6 / span 6; - } - - .sm\:cu-row-span-7 { - grid-row: span 7 / span 7; - } - - .sm\:cu-row-span-8 { - grid-row: span 8 / span 8; - } - - .sm\:cu-row-span-9 { - grid-row: span 9 / span 9; - } - - .sm\:cu-row-span-10 { - grid-row: span 10 / span 10; - } - - .sm\:cu-row-span-11 { - grid-row: span 11 / span 11; - } - - .sm\:cu-row-span-12 { - grid-row: span 12 / span 12; - } - - .sm\:cu-row-span-auto { - grid-row: span auto / span auto; - } -} - -@media (width >= 1024px) { - .md\:cu-columns-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); - } - - .md\:cu-columns-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .md\:cu-columns-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .md\:cu-columns-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .md\:cu-columns-5 { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - - .md\:cu-columns-6 { - grid-template-columns: repeat(6, minmax(0, 1fr)); - } - - .md\:cu-columns-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); - } - - .md\:cu-columns-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } - - .md\:cu-columns-9 { - grid-template-columns: repeat(9, minmax(0, 1fr)); - } - - .md\:cu-columns-10 { - grid-template-columns: repeat(10, minmax(0, 1fr)); - } - - .md\:cu-columns-11 { - grid-template-columns: repeat(11, minmax(0, 1fr)); - } - - .md\:cu-columns-12 { - grid-template-columns: repeat(12, minmax(0, 1fr)); - } - - .md\:cu-columns-auto { - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); - } - - .md\:cu-col-span-1 { - grid-column: span 1 / span 1; - } - - .md\:cu-col-span-2 { - grid-column: span 2 / span 2; - } - - .md\:cu-col-span-3 { - grid-column: span 3 / span 3; - } - - .md\:cu-col-span-4 { - grid-column: span 4 / span 4; - } - - .md\:cu-col-span-5 { - grid-column: span 5 / span 5; - } - - .md\:cu-col-span-6 { - grid-column: span 6 / span 6; - } - - .md\:cu-col-span-7 { - grid-column: span 7 / span 7; - } - - .md\:cu-col-span-8 { - grid-column: span 8 / span 8; - } - - .md\:cu-col-span-9 { - grid-column: span 9 / span 9; - } - - .md\:cu-col-span-10 { - grid-column: span 10 / span 10; - } - - .md\:cu-col-span-11 { - grid-column: span 11 / span 11; - } - - .md\:cu-col-span-12 { - grid-column: span 12 / span 12; - } - - .md\:cu-col-span-auto { - grid-column: span auto / span auto; - } - - .md\:cu-col-start-1 { - grid-column-start: 1; - } - - .md\:cu-col-start-2 { - grid-column-start: 2; - } - - .md\:cu-col-start-3 { - grid-column-start: 3; - } - - .md\:cu-col-start-4 { - grid-column-start: 4; - } - - .md\:cu-col-start-5 { - grid-column-start: 5; - } - - .md\:cu-col-start-6 { - grid-column-start: 6; - } - - .md\:cu-col-start-7 { - grid-column-start: 7; - } - - .md\:cu-col-start-8 { - grid-column-start: 8; - } - - .md\:cu-col-start-9 { - grid-column-start: 9; - } - - .md\:cu-col-start-10 { - grid-column-start: 10; - } - - .md\:cu-col-start-11 { - grid-column-start: 11; - } - - .md\:cu-col-start-12 { - grid-column-start: 12; - } - - .md\:cu-col-start-13 { - grid-column-start: 13; - } - - .md\:cu-col-start-auto { - grid-column-start: auto; - } - - .md\:cu-col-end-1 { - grid-column-end: 1; - } - - .md\:cu-col-end-2 { - grid-column-end: 2; - } - - .md\:cu-col-end-3 { - grid-column-end: 3; - } - - .md\:cu-col-end-4 { - grid-column-end: 4; - } - - .md\:cu-col-end-5 { - grid-column-end: 5; - } - - .md\:cu-col-end-6 { - grid-column-end: 6; - } - - .md\:cu-col-end-7 { - grid-column-end: 7; - } - - .md\:cu-col-end-8 { - grid-column-end: 8; - } - - .md\:cu-col-end-9 { - grid-column-end: 9; - } - - .md\:cu-col-end-10 { - grid-column-end: 10; - } - - .md\:cu-col-end-11 { - grid-column-end: 11; - } - - .md\:cu-col-end-12 { - grid-column-end: 12; - } - - .md\:cu-col-end-13 { - grid-column-end: 13; - } - - .md\:cu-col-end-auto { - grid-column-end: auto; - } - - .md\:cu-row-span-1 { - grid-row: span 1 / span 1; - } - - .md\:cu-row-span-2 { - grid-row: span 2 / span 2; - } - - .md\:cu-row-span-3 { - grid-row: span 3 / span 3; - } - - .md\:cu-row-span-4 { - grid-row: span 4 / span 4; - } - - .md\:cu-row-span-5 { - grid-row: span 5 / span 5; - } - - .md\:cu-row-span-6 { - grid-row: span 6 / span 6; - } - - .md\:cu-row-span-7 { - grid-row: span 7 / span 7; - } - - .md\:cu-row-span-8 { - grid-row: span 8 / span 8; - } - - .md\:cu-row-span-9 { - grid-row: span 9 / span 9; - } - - .md\:cu-row-span-10 { - grid-row: span 10 / span 10; - } - - .md\:cu-row-span-11 { - grid-row: span 11 / span 11; - } - - .md\:cu-row-span-12 { - grid-row: span 12 / span 12; - } - - .md\:cu-row-span-auto { - grid-row: span auto / span auto; - } -} - -@media (width >= 1280px) { - .lg\:cu-columns-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); - } - - .lg\:cu-columns-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .lg\:cu-columns-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .lg\:cu-columns-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .lg\:cu-columns-5 { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - - .lg\:cu-columns-6 { - grid-template-columns: repeat(6, minmax(0, 1fr)); - } - - .lg\:cu-columns-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); - } - - .lg\:cu-columns-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } - - .lg\:cu-columns-9 { - grid-template-columns: repeat(9, minmax(0, 1fr)); - } - - .lg\:cu-columns-10 { - grid-template-columns: repeat(10, minmax(0, 1fr)); - } - - .lg\:cu-columns-11 { - grid-template-columns: repeat(11, minmax(0, 1fr)); - } - - .lg\:cu-columns-12 { - grid-template-columns: repeat(12, minmax(0, 1fr)); - } - - .lg\:cu-columns-auto { - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); - } - - .lg\:cu-col-span-1 { - grid-column: span 1 / span 1; - } - - .lg\:cu-col-span-2 { - grid-column: span 2 / span 2; - } - - .lg\:cu-col-span-3 { - grid-column: span 3 / span 3; - } - - .lg\:cu-col-span-4 { - grid-column: span 4 / span 4; - } - - .lg\:cu-col-span-5 { - grid-column: span 5 / span 5; - } - - .lg\:cu-col-span-6 { - grid-column: span 6 / span 6; - } - - .lg\:cu-col-span-7 { - grid-column: span 7 / span 7; - } - - .lg\:cu-col-span-8 { - grid-column: span 8 / span 8; - } - - .lg\:cu-col-span-9 { - grid-column: span 9 / span 9; - } - - .lg\:cu-col-span-10 { - grid-column: span 10 / span 10; - } - - .lg\:cu-col-span-11 { - grid-column: span 11 / span 11; - } - - .lg\:cu-col-span-12 { - grid-column: span 12 / span 12; - } - - .lg\:cu-col-span-auto { - grid-column: span auto / span auto; - } - - .lg\:cu-col-start-1 { - grid-column-start: 1; - } - - .lg\:cu-col-start-2 { - grid-column-start: 2; - } - - .lg\:cu-col-start-3 { - grid-column-start: 3; - } - - .lg\:cu-col-start-4 { - grid-column-start: 4; - } - - .lg\:cu-col-start-5 { - grid-column-start: 5; - } - - .lg\:cu-col-start-6 { - grid-column-start: 6; - } - - .lg\:cu-col-start-7 { - grid-column-start: 7; - } - - .lg\:cu-col-start-8 { - grid-column-start: 8; - } - - .lg\:cu-col-start-9 { - grid-column-start: 9; - } - - .lg\:cu-col-start-10 { - grid-column-start: 10; - } - - .lg\:cu-col-start-11 { - grid-column-start: 11; - } - - .lg\:cu-col-start-12 { - grid-column-start: 12; - } - - .lg\:cu-col-start-13 { - grid-column-start: 13; - } - - .lg\:cu-col-start-auto { - grid-column-start: auto; - } - - .lg\:cu-col-end-1 { - grid-column-end: 1; - } - - .lg\:cu-col-end-2 { - grid-column-end: 2; - } - - .lg\:cu-col-end-3 { - grid-column-end: 3; - } - - .lg\:cu-col-end-4 { - grid-column-end: 4; - } - - .lg\:cu-col-end-5 { - grid-column-end: 5; - } - - .lg\:cu-col-end-6 { - grid-column-end: 6; - } - - .lg\:cu-col-end-7 { - grid-column-end: 7; - } - - .lg\:cu-col-end-8 { - grid-column-end: 8; - } - - .lg\:cu-col-end-9 { - grid-column-end: 9; - } - - .lg\:cu-col-end-10 { - grid-column-end: 10; - } - - .lg\:cu-col-end-11 { - grid-column-end: 11; - } - - .lg\:cu-col-end-12 { - grid-column-end: 12; - } - - .lg\:cu-col-end-13 { - grid-column-end: 13; - } - - .lg\:cu-col-end-auto { - grid-column-end: auto; - } - - .lg\:cu-row-span-1 { - grid-row: span 1 / span 1; - } - - .lg\:cu-row-span-2 { - grid-row: span 2 / span 2; - } - - .lg\:cu-row-span-3 { - grid-row: span 3 / span 3; - } - - .lg\:cu-row-span-4 { - grid-row: span 4 / span 4; - } - - .lg\:cu-row-span-5 { - grid-row: span 5 / span 5; - } - - .lg\:cu-row-span-6 { - grid-row: span 6 / span 6; - } - - .lg\:cu-row-span-7 { - grid-row: span 7 / span 7; - } - - .lg\:cu-row-span-8 { - grid-row: span 8 / span 8; - } - - .lg\:cu-row-span-9 { - grid-row: span 9 / span 9; - } - - .lg\:cu-row-span-10 { - grid-row: span 10 / span 10; - } - - .lg\:cu-row-span-11 { - grid-row: span 11 / span 11; - } - - .lg\:cu-row-span-12 { - grid-row: span 12 / span 12; - } - - .lg\:cu-row-span-auto { - grid-row: span auto / span auto; - } -} - -@media (width >= 1536px) { - .xl\:cu-columns-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); - } - - .xl\:cu-columns-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .xl\:cu-columns-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); - } - - .xl\:cu-columns-4 { - grid-template-columns: repeat(4, minmax(0, 1fr)); - } - - .xl\:cu-columns-5 { - grid-template-columns: repeat(5, minmax(0, 1fr)); - } - - .xl\:cu-columns-6 { - grid-template-columns: repeat(6, minmax(0, 1fr)); - } - - .xl\:cu-columns-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); - } - - .xl\:cu-columns-8 { - grid-template-columns: repeat(8, minmax(0, 1fr)); - } - - .xl\:cu-columns-9 { - grid-template-columns: repeat(9, minmax(0, 1fr)); - } - - .xl\:cu-columns-10 { - grid-template-columns: repeat(10, minmax(0, 1fr)); - } - - .xl\:cu-columns-11 { - grid-template-columns: repeat(11, minmax(0, 1fr)); - } - - .xl\:cu-columns-12 { - grid-template-columns: repeat(12, minmax(0, 1fr)); - } - - .xl\:cu-columns-auto { - grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); - } - - .xl\:cu-col-span-1 { - grid-column: span 1 / span 1; - } - - .xl\:cu-col-span-2 { - grid-column: span 2 / span 2; - } - - .xl\:cu-col-span-3 { - grid-column: span 3 / span 3; - } - - .xl\:cu-col-span-4 { - grid-column: span 4 / span 4; - } - - .xl\:cu-col-span-5 { - grid-column: span 5 / span 5; - } - - .xl\:cu-col-span-6 { - grid-column: span 6 / span 6; - } - - .xl\:cu-col-span-7 { - grid-column: span 7 / span 7; - } - - .xl\:cu-col-span-8 { - grid-column: span 8 / span 8; - } - - .xl\:cu-col-span-9 { - grid-column: span 9 / span 9; - } - - .xl\:cu-col-span-10 { - grid-column: span 10 / span 10; - } - - .xl\:cu-col-span-11 { - grid-column: span 11 / span 11; - } - - .xl\:cu-col-span-12 { - grid-column: span 12 / span 12; - } - - .xl\:cu-col-span-auto { - grid-column: span auto / span auto; - } - - .xl\:cu-col-start-1 { - grid-column-start: 1; - } - - .xl\:cu-col-start-2 { - grid-column-start: 2; - } - - .xl\:cu-col-start-3 { - grid-column-start: 3; - } - - .xl\:cu-col-start-4 { - grid-column-start: 4; - } - - .xl\:cu-col-start-5 { - grid-column-start: 5; - } - - .xl\:cu-col-start-6 { - grid-column-start: 6; - } - - .xl\:cu-col-start-7 { - grid-column-start: 7; - } - - .xl\:cu-col-start-8 { - grid-column-start: 8; - } - - .xl\:cu-col-start-9 { - grid-column-start: 9; - } - - .xl\:cu-col-start-10 { - grid-column-start: 10; - } - - .xl\:cu-col-start-11 { - grid-column-start: 11; - } - - .xl\:cu-col-start-12 { - grid-column-start: 12; - } - - .xl\:cu-col-start-13 { - grid-column-start: 13; - } - - .xl\:cu-col-start-auto { - grid-column-start: auto; - } - - .xl\:cu-col-end-1 { - grid-column-end: 1; - } - - .xl\:cu-col-end-2 { - grid-column-end: 2; - } - - .xl\:cu-col-end-3 { - grid-column-end: 3; - } - - .xl\:cu-col-end-4 { - grid-column-end: 4; - } - - .xl\:cu-col-end-5 { - grid-column-end: 5; - } - - .xl\:cu-col-end-6 { - grid-column-end: 6; - } - - .xl\:cu-col-end-7 { - grid-column-end: 7; - } - - .xl\:cu-col-end-8 { - grid-column-end: 8; - } - - .xl\:cu-col-end-9 { - grid-column-end: 9; - } - - .xl\:cu-col-end-10 { - grid-column-end: 10; - } - - .xl\:cu-col-end-11 { - grid-column-end: 11; - } - - .xl\:cu-col-end-12 { - grid-column-end: 12; - } - - .xl\:cu-col-end-13 { - grid-column-end: 13; - } - - .xl\:cu-col-end-auto { - grid-column-end: auto; - } - - .xl\:cu-row-span-1 { - grid-row: span 1 / span 1; - } - - .xl\:cu-row-span-2 { - grid-row: span 2 / span 2; - } - - .xl\:cu-row-span-3 { - grid-row: span 3 / span 3; - } - - .xl\:cu-row-span-4 { - grid-row: span 4 / span 4; - } - - .xl\:cu-row-span-5 { - grid-row: span 5 / span 5; - } - - .xl\:cu-row-span-6 { - grid-row: span 6 / span 6; - } - - .xl\:cu-row-span-7 { - grid-row: span 7 / span 7; - } - - .xl\:cu-row-span-8 { - grid-row: span 8 / span 8; - } - - .xl\:cu-row-span-9 { - grid-row: span 9 / span 9; - } - - .xl\:cu-row-span-10 { - grid-row: span 10 / span 10; - } - - .xl\:cu-row-span-11 { - grid-row: span 11 / span 11; - } - - .xl\:cu-row-span-12 { - grid-row: span 12 / span 12; - } - - .xl\:cu-row-span-auto { - grid-row: span auto / span auto; - } -} - -.cu-gap { - gap: var(--gap); -} - -.cu-gap-0\.5 { - gap: var(--canon-space-0_5); -} - -.cu-gap-1 { - gap: var(--canon-space-1); -} - -.cu-gap-1\.5 { - gap: var(--canon-space-1_5); -} - -.cu-gap-2 { - gap: var(--canon-space-2); -} - -.cu-gap-3 { - gap: var(--canon-space-3); -} - -.cu-gap-4 { - gap: var(--canon-space-4); -} - -.cu-gap-5 { - gap: var(--canon-space-5); -} - -.cu-gap-6 { - gap: var(--canon-space-6); -} - -.cu-gap-7 { - gap: var(--canon-space-7); -} - -.cu-gap-8 { - gap: var(--canon-space-8); -} - -.cu-gap-9 { - gap: var(--canon-space-9); -} - -.cu-gap-10 { - gap: var(--canon-space-10); -} - -.cu-gap-11 { - gap: var(--canon-space-11); -} - -.cu-gap-12 { - gap: var(--canon-space-12); -} - -.cu-gap-13 { - gap: var(--canon-space-13); -} - -.cu-gap-14 { - gap: var(--canon-space-14); -} - -@media (width >= 640px) { - .xs\:cu-gap { - gap: var(--gap-xs); - } - - .xs\:cu-gap-0\.5 { - gap: var(--canon-space-0_5); - } - - .xs\:cu-gap-1 { - gap: var(--canon-space-1); - } - - .xs\:cu-gap-1\.5 { - gap: var(--canon-space-1_5); - } - - .xs\:cu-gap-2 { - gap: var(--canon-space-2); - } - - .xs\:cu-gap-3 { - gap: var(--canon-space-3); - } - - .xs\:cu-gap-4 { - gap: var(--canon-space-4); - } - - .xs\:cu-gap-5 { - gap: var(--canon-space-5); - } - - .xs\:cu-gap-6 { - gap: var(--canon-space-6); - } - - .xs\:cu-gap-7 { - gap: var(--canon-space-7); - } - - .xs\:cu-gap-8 { - gap: var(--canon-space-8); - } - - .xs\:cu-gap-9 { - gap: var(--canon-space-9); - } - - .xs\:cu-gap-10 { - gap: var(--canon-space-10); - } - - .xs\:cu-gap-11 { - gap: var(--canon-space-11); - } - - .xs\:cu-gap-12 { - gap: var(--canon-space-12); - } - - .xs\:cu-gap-13 { - gap: var(--canon-space-13); - } - - .xs\:cu-gap-14 { - gap: var(--canon-space-14); - } -} - -@media (width >= 768px) { - .sm\:cu-gap { - gap: var(--gap-sm); - } - - .sm\:cu-gap-0\.5 { - gap: var(--canon-space-0_5); - } - - .sm\:cu-gap-1 { - gap: var(--canon-space-1); - } - - .sm\:cu-gap-1\.5 { - gap: var(--canon-space-1_5); - } - - .sm\:cu-gap-2 { - gap: var(--canon-space-2); - } - - .sm\:cu-gap-3 { - gap: var(--canon-space-3); - } - - .sm\:cu-gap-4 { - gap: var(--canon-space-4); - } - - .sm\:cu-gap-5 { - gap: var(--canon-space-5); - } - - .sm\:cu-gap-6 { - gap: var(--canon-space-6); - } - - .sm\:cu-gap-7 { - gap: var(--canon-space-7); - } - - .sm\:cu-gap-8 { - gap: var(--canon-space-8); - } - - .sm\:cu-gap-9 { - gap: var(--canon-space-9); - } - - .sm\:cu-gap-10 { - gap: var(--canon-space-10); - } - - .sm\:cu-gap-11 { - gap: var(--canon-space-11); - } - - .sm\:cu-gap-12 { - gap: var(--canon-space-12); - } - - .sm\:cu-gap-13 { - gap: var(--canon-space-13); - } - - .sm\:cu-gap-14 { - gap: var(--canon-space-14); - } -} - -@media (width >= 1024px) { - .md\:cu-gap { - gap: var(--gap-md); - } - - .md\:cu-gap-0\.5 { - gap: var(--canon-space-0_5); - } - - .md\:cu-gap-1 { - gap: var(--canon-space-1); - } - - .md\:cu-gap-1\.5 { - gap: var(--canon-space-1_5); - } - - .md\:cu-gap-2 { - gap: var(--canon-space-2); - } - - .md\:cu-gap-3 { - gap: var(--canon-space-3); - } - - .md\:cu-gap-4 { - gap: var(--canon-space-4); - } - - .md\:cu-gap-5 { - gap: var(--canon-space-5); - } - - .md\:cu-gap-6 { - gap: var(--canon-space-6); - } - - .md\:cu-gap-7 { - gap: var(--canon-space-7); - } - - .md\:cu-gap-8 { - gap: var(--canon-space-8); - } - - .md\:cu-gap-9 { - gap: var(--canon-space-9); - } - - .md\:cu-gap-10 { - gap: var(--canon-space-10); - } - - .md\:cu-gap-11 { - gap: var(--canon-space-11); - } - - .md\:cu-gap-12 { - gap: var(--canon-space-12); - } - - .md\:cu-gap-13 { - gap: var(--canon-space-13); - } - - .md\:cu-gap-14 { - gap: var(--canon-space-14); - } -} - -@media (width >= 1280px) { - .lg\:cu-gap { - gap: var(--gap-lg); - } - - .lg\:cu-gap-0\.5 { - gap: var(--canon-space-0_5); - } - - .lg\:cu-gap-1 { - gap: var(--canon-space-1); - } - - .lg\:cu-gap-1\.5 { - gap: var(--canon-space-1_5); - } - - .lg\:cu-gap-2 { - gap: var(--canon-space-2); - } - - .lg\:cu-gap-3 { - gap: var(--canon-space-3); - } - - .lg\:cu-gap-4 { - gap: var(--canon-space-4); - } - - .lg\:cu-gap-5 { - gap: var(--canon-space-5); - } - - .lg\:cu-gap-6 { - gap: var(--canon-space-6); - } - - .lg\:cu-gap-7 { - gap: var(--canon-space-7); - } - - .lg\:cu-gap-8 { - gap: var(--canon-space-8); - } - - .lg\:cu-gap-9 { - gap: var(--canon-space-9); - } - - .lg\:cu-gap-10 { - gap: var(--canon-space-10); - } - - .lg\:cu-gap-11 { - gap: var(--canon-space-11); - } - - .lg\:cu-gap-12 { - gap: var(--canon-space-12); - } - - .lg\:cu-gap-13 { - gap: var(--canon-space-13); - } - - .lg\:cu-gap-14 { - gap: var(--canon-space-14); - } -} - -@media (width >= 1536px) { - .xl\:cu-gap { - gap: var(--gap-xl); - } - - .xl\:cu-gap-0\.5 { - gap: var(--canon-space-0_5); - } - - .xl\:cu-gap-1 { - gap: var(--canon-space-1); - } - - .xl\:cu-gap-1\.5 { - gap: var(--canon-space-1_5); - } - - .xl\:cu-gap-2 { - gap: var(--canon-space-2); - } - - .xl\:cu-gap-3 { - gap: var(--canon-space-3); - } - - .xl\:cu-gap-4 { - gap: var(--canon-space-4); - } - - .xl\:cu-gap-5 { - gap: var(--canon-space-5); - } - - .xl\:cu-gap-6 { - gap: var(--canon-space-6); - } - - .xl\:cu-gap-7 { - gap: var(--canon-space-7); - } - - .xl\:cu-gap-8 { - gap: var(--canon-space-8); - } - - .xl\:cu-gap-9 { - gap: var(--canon-space-9); - } - - .xl\:cu-gap-10 { - gap: var(--canon-space-10); - } - - .xl\:cu-gap-11 { - gap: var(--canon-space-11); - } - - .xl\:cu-gap-12 { - gap: var(--canon-space-12); - } - - .xl\:cu-gap-13 { - gap: var(--canon-space-13); - } - - .xl\:cu-gap-14 { - gap: var(--canon-space-14); - } -} - -.cu-align-start { - align-items: start; -} - -.cu-align-center { - align-items: center; -} - -.cu-align-end { - align-items: end; -} - -.cu-align-stretch { - align-items: stretch; -} - -.cu-jc-start { - justify-content: start; -} - -.cu-jc-center { - justify-content: center; -} - -.cu-jc-end { - justify-content: end; -} - -.cu-jc-between { - justify-content: space-between; -} - -.cu-fd-row { - flex-direction: row; -} - -.cu-fd-column { - flex-direction: column; -} - -.cu-fd-row-reverse { - flex-direction: row-reverse; -} - -.cu-fd-column-reverse { - flex-direction: column-reverse; -} - -@media (width >= 640px) { - .xs\:cu-align-start { - align-items: start; - } - - .xs\:cu-align-center { - align-items: center; - } - - .xs\:cu-align-end { - align-items: end; - } - - .xs\:cu-align-stretch { - align-items: stretch; - } - - .xs\:cu-jc-start { - justify-content: start; - } - - .xs\:cu-jc-center { - justify-content: center; - } - - .xs\:cu-jc-end { - justify-content: end; - } - - .xs\:cu-jc-between { - justify-content: space-between; - } - - .xs\:cu-fd-row { - flex-direction: row; - } - - .xs\:cu-fd-column { - flex-direction: column; - } - - .xs\:cu-fd-row-reverse { - flex-direction: row-reverse; - } - - .xs\:cu-fd-column-reverse { - flex-direction: column-reverse; - } -} - -@media (width >= 768px) { - .sm\:cu-align-start { - align-items: start; - } - - .sm\:cu-align-center { - align-items: center; - } - - .sm\:cu-align-end { - align-items: end; - } - - .sm\:cu-align-stretch { - align-items: stretch; - } - - .sm\:cu-jc-start { - justify-content: start; - } - - .sm\:cu-jc-center { - justify-content: center; - } - - .sm\:cu-jc-end { - justify-content: end; - } - - .sm\:cu-jc-between { - justify-content: space-between; - } - - .sm\:cu-fd-row { - flex-direction: row; - } - - .sm\:cu-fd-column { - flex-direction: column; - } - - .sm\:cu-fd-row-reverse { - flex-direction: row-reverse; - } - - .sm\:cu-fd-column-reverse { - flex-direction: column-reverse; - } -} - -@media (width >= 1024px) { - .md\:cu-align-start { - align-items: start; - } - - .md\:cu-align-center { - align-items: center; - } - - .md\:cu-align-end { - align-items: end; - } - - .md\:cu-align-stretch { - align-items: stretch; - } - - .md\:cu-jc-start { - justify-content: start; - } - - .md\:cu-jc-center { - justify-content: center; - } - - .md\:cu-jc-end { - justify-content: end; - } - - .md\:cu-jc-between { - justify-content: space-between; - } - - .md\:cu-fd-row { - flex-direction: row; - } - - .md\:cu-fd-column { - flex-direction: column; - } - - .md\:cu-fd-row-reverse { - flex-direction: row-reverse; - } - - .md\:cu-fd-column-reverse { - flex-direction: column-reverse; - } -} - -@media (width >= 1280px) { - .lg\:cu-align-start { - align-items: start; - } - - .lg\:cu-align-center { - align-items: center; - } - - .lg\:cu-align-end { - align-items: end; - } - - .lg\:cu-align-stretch { - align-items: stretch; - } - - .lg\:cu-jc-start { - justify-content: start; - } - - .lg\:cu-jc-center { - justify-content: center; - } - - .lg\:cu-jc-end { - justify-content: end; - } - - .lg\:cu-jc-between { - justify-content: space-between; - } - - .lg\:cu-fd-row { - flex-direction: row; - } - - .lg\:cu-fd-column { - flex-direction: column; - } - - .lg\:cu-fd-row-reverse { - flex-direction: row-reverse; - } - - .lg\:cu-fd-column-reverse { - flex-direction: column-reverse; - } -} - -@media (width >= 1536px) { - .xl\:cu-align-start { - align-items: start; - } - - .xl\:cu-align-center { - align-items: center; - } - - .xl\:cu-align-end { - align-items: end; - } - - .xl\:cu-align-stretch { - align-items: stretch; - } - - .xl\:cu-jc-start { - justify-content: start; - } - - .xl\:cu-jc-center { - justify-content: center; - } - - .xl\:cu-jc-end { - justify-content: end; - } - - .xl\:cu-jc-between { - justify-content: space-between; - } - - .xl\:cu-fd-row { - flex-direction: row; - } - - .xl\:cu-fd-column { - flex-direction: column; - } - - .xl\:cu-fd-row-reverse { - flex-direction: row-reverse; - } - - .xl\:cu-fd-column-reverse { - flex-direction: column-reverse; - } -} - -:where(a) { - color: inherit; - text-decoration: none; -} - -:root { - --canon-font-regular: system-ui; - --canon-font-monospace: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace; - --canon-font-weight-regular: 400; - --canon-font-weight-bold: 600; - --canon-font-size-1: .625rem; - --canon-font-size-2: .75rem; - --canon-font-size-3: .875rem; - --canon-font-size-4: 1rem; - --canon-font-size-5: 1.25rem; - --canon-font-size-6: 1.5rem; - --canon-font-size-7: 2rem; - --canon-font-size-8: 3rem; - --canon-font-size-9: 4rem; - --canon-font-size-10: 5.75rem; - --canon-space: .25rem; - --canon-space-0_5: calc(var(--canon-space) * .5); - --canon-space-1: var(--canon-space); - --canon-space-1_5: calc(var(--canon-space) * 1.5); - --canon-space-2: calc(var(--canon-space) * 2); - --canon-space-3: calc(var(--canon-space) * 3); - --canon-space-4: calc(var(--canon-space) * 4); - --canon-space-5: calc(var(--canon-space) * 5); - --canon-space-6: calc(var(--canon-space) * 6); - --canon-space-7: calc(var(--canon-space) * 7); - --canon-space-8: calc(var(--canon-space) * 8); - --canon-space-9: calc(var(--canon-space) * 9); - --canon-space-10: calc(var(--canon-space) * 10); - --canon-space-11: calc(var(--canon-space) * 11); - --canon-space-12: calc(var(--canon-space) * 12); - --canon-space-13: calc(var(--canon-space) * 13); - --canon-space-14: calc(var(--canon-space) * 14); - --canon-radius-1: calc(.125rem); - --canon-radius-2: calc(.25rem); - --canon-radius-3: calc(.5rem); - --canon-radius-4: calc(.75rem); - --canon-radius-5: calc(1rem); - --canon-radius-6: calc(1.25rem); - --canon-radius-full: 9999px; - --canon-black: #000; - --canon-white: #fff; - --canon-gray-1: #f8f8f8; - --canon-gray-2: #ececec; - --canon-gray-3: #d9d9d9; - --canon-gray-4: #c1c1c1; - --canon-gray-5: #9e9e9e; - --canon-gray-6: #8c8c8c; - --canon-gray-7: #757575; - --canon-gray-8: #595959; - --canon-bg: var(--canon-gray-1); - --canon-bg-surface-1: var(--canon-white); - --canon-bg-surface-2: var(--canon-gray-2); - --canon-bg-solid: #1f5493; - --canon-bg-solid-hover: #163a66; - --canon-bg-solid-pressed: #0f2b4e; - --canon-bg-solid-disabled: #ebebeb; - --canon-bg-tint: transparent; - --canon-bg-tint-hover: #1f549366; - --canon-bg-tint-pressed: #1f549399; - --canon-bg-tint-disabled: #ebebeb; - --canon-bg-danger: #feebe7; - --canon-bg-warning: #fff2b2; - --canon-bg-success: #e6f6eb; - --canon-fg-primary: var(--canon-black); - --canon-fg-secondary: var(--canon-gray-7); - --canon-fg-link: #1f5493; - --canon-fg-link-hover: #1f2d5c; - --canon-fg-disabled: #9e9e9e; - --canon-fg-solid: var(--canon-white); - --canon-fg-solid-disabled: #9c9c9c; - --canon-fg-tint: #1f5493; - --canon-fg-tint-disabled: var(--canon-gray-5); - --canon-fg-danger: #e22b2b; - --canon-fg-warning: #e36d05; - --canon-fg-success: #1db954; - --canon-border: #0000001a; - --canon-border-hover: #0003; - --canon-border-pressed: #0006; - --canon-border-disabled: #0000001a; - --canon-border-danger: #f87a7a; - --canon-border-warning: #e36d05; - --canon-border-success: #53db83; - --canon-ring: #1f5493; - --canon-scrollbar: #a0a0a03b; - --canon-scrollbar-thumb: #a0a0a0; -} - -[data-theme="dark"] { - --canon-gray-1: #191919; - --canon-gray-2: #242424; - --canon-gray-3: #373737; - --canon-gray-4: #464646; - --canon-gray-5: #575757; - --canon-gray-6: #7b7b7b; - --canon-gray-7: #9e9e9e; - --canon-gray-8: #b4b4b4; - --canon-bg: var(--canon-black); - --canon-bg-surface-1: var(--canon-gray-1); - --canon-bg-surface-2: var(--canon-gray-2); - --canon-bg-solid: #9cc9ff; - --canon-bg-solid-hover: #83b9fd; - --canon-bg-solid-pressed: #83b9fd; - --canon-bg-solid-disabled: #222; - --canon-bg-tint: transparent; - --canon-bg-tint-hover: #9cc9ff1f; - --canon-bg-tint-pressed: #9cc9ff29; - --canon-bg-tint-disabled: transparent; - --canon-bg-danger: #3b1219; - --canon-bg-warning: #302008; - --canon-bg-success: #132d21; - --canon-fg-primary: var(--canon-white); - --canon-fg-secondary: var(--canon-gray-7); - --canon-fg-link: #9cc9ff; - --canon-fg-link-hover: #7eb5f7; - --canon-fg-disabled: var(--canon-gray-7); - --canon-fg-solid: #101821; - --canon-fg-solid-disabled: var(--canon-gray-5); - --canon-fg-tint: #9cc9ff; - --canon-fg-tint-disabled: var(--canon-gray-5); - --canon-fg-danger: #e22b2b; - --canon-fg-warning: #e36d05; - --canon-fg-success: #1db954; - --canon-border: #fff3; - --canon-border-hover: #fff6; - --canon-border-pressed: #ffffff80; - --canon-border-disabled: #fff3; - --canon-border-danger: #f87a7a; - --canon-border-warning: #e36d05; - --canon-border-success: #53db83; - --canon-ring: #1f5493; - --canon-scrollbar: #3636363a; - --canon-scrollbar-thumb: #575757; -} diff --git a/packages/canon/css/datatable.css b/packages/canon/css/datatable.css deleted file mode 100644 index edef29f500..0000000000 --- a/packages/canon/css/datatable.css +++ /dev/null @@ -1,23 +0,0 @@ -.canon-DataTablePagination { - padding-top: var(--canon-space-5); - justify-content: space-between; - align-items: center; - display: flex; -} - -.canon-DataTablePagination--left { - justify-content: space-between; - align-items: center; - display: flex; -} - -.canon-DataTablePagination--right { - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - display: flex; -} - -.canon-DataTablePagination--select { - min-width: 10.5rem; -} diff --git a/packages/canon/css/flex.css b/packages/canon/css/flex.css deleted file mode 100644 index 5c6108eee7..0000000000 --- a/packages/canon/css/flex.css +++ /dev/null @@ -1,4 +0,0 @@ -.canon-Flex { - min-width: 0; - display: flex; -} diff --git a/packages/canon/css/grid.css b/packages/canon/css/grid.css deleted file mode 100644 index 0bb9267795..0000000000 --- a/packages/canon/css/grid.css +++ /dev/null @@ -1,3 +0,0 @@ -.canon-Grid { - display: grid; -} diff --git a/packages/canon/css/heading.css b/packages/canon/css/heading.css deleted file mode 100644 index e5645e14a9..0000000000 --- a/packages/canon/css/heading.css +++ /dev/null @@ -1,51 +0,0 @@ -.canon-Heading { - font-family: var(--canon-font-regular); - color: var(--canon-fg-primary); - margin: 0; - padding: 0; - line-height: 100%; -} - -.canon-Heading[data-variant="display"] { - font-size: var(--canon-font-size-10); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title1"] { - font-size: var(--canon-font-size-9); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title2"] { - font-size: var(--canon-font-size-8); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title3"] { - font-size: var(--canon-font-size-7); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title4"] { - font-size: var(--canon-font-size-6); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title5"] { - font-size: var(--canon-font-size-5); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-color="primary"] { - color: var(--canon-fg-primary); -} - -.canon-Heading[data-color="secondary"] { - color: var(--canon-fg-secondary); -} - -.canon-Heading[data-truncate] { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} diff --git a/packages/canon/css/icon.css b/packages/canon/css/icon.css deleted file mode 100644 index 35b453cb3f..0000000000 --- a/packages/canon/css/icon.css +++ /dev/null @@ -1,4 +0,0 @@ -.canon-Icon { - width: 1rem; - height: 1rem; -} diff --git a/packages/canon/css/iconbutton.css b/packages/canon/css/iconbutton.css deleted file mode 100644 index dc3f9d94c5..0000000000 --- a/packages/canon/css/iconbutton.css +++ /dev/null @@ -1,89 +0,0 @@ -.canon-IconButton { - user-select: none; - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-bold); - cursor: pointer; - border-radius: var(--canon-radius-2); - justify-content: center; - align-items: center; - gap: var(--canon-space-1_5); - border: none; - padding: 0; - display: inline-flex; - - &:disabled { - cursor: not-allowed; - } -} - -.canon-IconButton[data-variant="primary"] { - background-color: var(--canon-bg-solid); - color: var(--canon-fg-solid); - transition: background-color .15s, box-shadow .15s; - - &:hover { - background-color: var(--canon-bg-solid-hover); - } - - &:active { - background-color: var(--canon-bg-solid-pressed); - } - - &:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - } - - &:disabled { - background-color: var(--canon-bg-solid-disabled); - color: var(--canon-fg-solid-disabled); - } -} - -.canon-IconButton[data-variant="secondary"] { - background-color: var(--canon-bg-surface-1); - box-shadow: inset 0 0 0 1px var(--canon-border); - color: var(--canon-fg-primary); - transition: box-shadow .15s; - - &:hover { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - - &:active { - box-shadow: inset 0 0 0 1px var(--canon-border-pressed); - } - - &:focus-visible { - box-shadow: inset 0 0 0 2px var(--canon-ring); - outline: none; - transition: none; - } - - &:disabled { - box-shadow: inset 0 0 0 1px var(--canon-border-disabled); - color: var(--canon-fg-disabled); - } -} - -.canon-IconButton[data-size="medium"] { - font-size: var(--canon-font-size-4); - width: 40px; - height: 40px; -} - -.canon-IconButton[data-size="small"] { - font-size: var(--canon-font-size-3); - width: 32px; - height: 32px; -} - -.canon-IconButtonIcon[data-size="small"], .canon-IconButtonIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-IconButtonIcon[data-size="medium"], .canon-IconButtonIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} diff --git a/packages/canon/css/link.css b/packages/canon/css/link.css deleted file mode 100644 index 535beb3d9f..0000000000 --- a/packages/canon/css/link.css +++ /dev/null @@ -1,45 +0,0 @@ -.canon-Link { - font-family: var(--canon-font-regular); - color: var(--canon-fg-link); - cursor: pointer; - margin: 0; - padding: 0; - text-decoration-line: none; - - &:hover { - color: var(--canon-fg-link-hover); - text-underline-offset: calc(.025em + 2px); - text-decoration-line: underline; - text-decoration-style: solid; - text-decoration-thickness: min(2px, max(1px, .05em)); - text-decoration-color: color-mix(in srgb, var(--canon-fg-link-hover) 30%, transparent); - } -} - -.canon-Link[data-variant="body"] { - font-size: var(--canon-font-size-3); - line-height: 140%; -} - -.canon-Link[data-variant="subtitle"] { - font-size: var(--canon-font-size-4); - line-height: 140%; -} - -.canon-Link[data-variant="caption"] { - font-size: var(--canon-font-size-2); - line-height: 140%; -} - -.canon-Link[data-variant="label"] { - font-size: var(--canon-font-size-1); - line-height: 140%; -} - -.canon-Link[data-weight="regular"] { - font-weight: var(--canon-font-weight-regular); -} - -.canon-Link[data-weight="bold"] { - font-weight: var(--canon-font-weight-bold); -} diff --git a/packages/canon/css/menu.css b/packages/canon/css/menu.css deleted file mode 100644 index 4c9433275c..0000000000 --- a/packages/canon/css/menu.css +++ /dev/null @@ -1,177 +0,0 @@ -.canon-MenuPositioner { - outline: 0; -} - -.canon-MenuPopup { - background-color: var(--canon-bg-surface-1); - border: 1px solid var(--canon-border); - color: var(--canon-fg-primary); - transform-origin: var(--transform-origin); - max-width: min(var(--available-width), 340px); - max-height: min(var(--available-height), 500px); - padding-bottom: var(--canon-space-1); - border-radius: .375rem; - outline: none; - flex-direction: column; - transition: transform .15s, opacity .15s; - display: flex; - position: relative; - overflow: auto; - - &[data-starting-style], &[data-ending-style] { - opacity: 0; - transform: scale(.9); - } -} - -.canon-MenuItem { - user-select: none; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - &:first-child { - margin-top: var(--canon-space-1); - } - - &[data-highlighted] { - background-color: var(--canon-gray-3); - } -} - -.canon-MenuSubmenuTrigger { - user-select: none; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - & .canon-Icon { - color: var(--canon-fg-secondary); - } - - &:first-child { - margin-top: var(--canon-space-1); - } - - &[data-popup-open], &[data-highlighted] { - background-color: var(--canon-gray-3); - - & .canon-Icon { - color: var(--canon-fg-primary); - } - } -} - -.canon-MenuSeparator { - background-color: var(--color-gray-200); - height: 1px; - margin: .375rem 1rem; -} - -.canon-SubmenuComboboxSearch { - padding-inline: var(--canon-space-3); - border: none; - border-bottom: 1px solid var(--canon-border); - background-color: var(--canon-bg-surface-1); - height: 32px; - color: var(--canon-fg-primary); - line-height: 140%; - font-size: var(--canon-font-size-3); - z-index: 1; - outline: none; - position: sticky; - top: 0; - - &::placeholder { - color: var(--canon-fg-secondary); - } - - &:disabled { - opacity: .6; - cursor: not-allowed; - } -} - -.canon-SubmenuComboboxItems { - padding-top: var(--canon-space-2); - outline: none; - flex-direction: column; - display: flex; - overflow-y: auto; -} - -.canon-SubmenuComboboxNoResults { - padding-inline: var(--canon-space-3); - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-4); - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-3); -} - -.canon-SubmenuComboboxItem { - user-select: none; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - &[data-highlighted] { - background-color: var(--canon-gray-3); - } - - &[data-disabled] { - opacity: .5; - cursor: not-allowed; - } -} - -.canon-SubmenuComboboxItemCheckbox { - width: 16px; - height: 16px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - border: 1px solid var(--canon-border); - background: var(--canon-bg-surface-1); - flex-shrink: 0; - justify-content: center; - align-items: center; - display: flex; -} - -.canon-SubmenuComboboxItemLabel { - text-overflow: ellipsis; - white-space: nowrap; - flex: 1; - overflow: hidden; -} diff --git a/packages/canon/css/scrollarea.css b/packages/canon/css/scrollarea.css deleted file mode 100644 index d5809f2d88..0000000000 --- a/packages/canon/css/scrollarea.css +++ /dev/null @@ -1,50 +0,0 @@ -.canon-ScrollAreaRoot { - box-sizing: border-box; - width: 24rem; - max-width: calc(100vw - 8rem); - height: 8.5rem; -} - -.canon-ScrollAreaViewport { - overscroll-behavior: contain; - height: 100%; -} - -.canon-ScrollAreaContent { - padding-block: .75rem; - flex-direction: column; - gap: 1rem; - padding-left: 1rem; - padding-right: 1.5rem; - display: flex; -} - -.canon-ScrollAreaScrollbar { - background-color: var(--canon-scrollbar); - opacity: 0; - border-radius: .375rem; - justify-content: center; - width: .25rem; - margin: .5rem; - transition: opacity .15s .3s; - display: flex; - - &[data-hovering], &[data-scrolling] { - opacity: 1; - transition-duration: 75ms; - transition-delay: 0s; - } - - &:before { - content: ""; - width: 1.25rem; - height: 100%; - position: absolute; - } -} - -.canon-ScrollAreaThumb { - border-radius: inherit; - background-color: var(--canon-scrollbar-thumb); - width: 100%; -} diff --git a/packages/canon/css/select.css b/packages/canon/css/select.css deleted file mode 100644 index 1c23f39201..0000000000 --- a/packages/canon/css/select.css +++ /dev/null @@ -1,188 +0,0 @@ -.canon-Select { - font-family: var(--canon-font-regular); - flex-direction: column; - width: 100%; - display: flex; -} - -.canon-SelectLabel { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - margin-bottom: var(--canon-space-1_5); - cursor: pointer; -} - -.canon-SelectLabel[data-disabled] { - cursor: default; -} - -.canon-SelectDescription { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-secondary); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-SelectError { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-danger); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-SelectTrigger { - box-sizing: border-box; - border-radius: var(--canon-radius-3); - border: 1px solid var(--canon-border); - padding: 0 var(--canon-space-4); - background-color: var(--canon-bg-surface-1); - font-size: var(--canon-font-size-3); - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - cursor: pointer; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - width: 100%; - transition: border-color .2s ease-in-out, outline-color .2s ease-in-out; - display: flex; -} - -.canon-SelectTrigger::placeholder { - color: var(--canon-fg-secondary); -} - -.canon-SelectTrigger:hover { - border-color: var(--canon-border-hover); -} - -.canon-SelectTrigger:focus-visible { - border-color: var(--canon-border-pressed); - outline: 0; -} - -.canon-SelectTrigger[data-invalid] { - border-color: var(--canon-fg-danger); -} - -.canon-SelectTrigger[data-invalid]:hover, .canon-SelectTrigger[data-invalid]:focus-visible { - border-width: 2px; -} - -.canon-SelectTrigger[data-disabled] { - cursor: not-allowed; - border-color: var(--canon-border-disabled); - color: var(--canon-fg-disabled); -} - -.canon-SelectTrigger[data-size="small"] { - height: 2rem; -} - -.canon-SelectTrigger[data-size="medium"] { - height: 3rem; -} - -.canon-SelectIcon { - margin-left: var(--canon-space-5); - transition: transform .2s; -} - -.canon-SelectTrigger[data-popup-open] .canon-SelectIcon { - transform: rotate(180deg); -} - -.canon-SelectPopup { - box-sizing: border-box; - max-height: var(--available-height); - background-color: var(--canon-bg-surface-1); - border: 1px solid var(--canon-border); - border-radius: var(--canon-radius-3); - padding-block: var(--canon-space-1); - z-index: 1; - transform-origin: var(--transform-origin); - outline: 0; - transition: transform .15s, opacity .15s; - overflow-y: auto; - box-shadow: 0 4px 12px #0003; -} - -.canon-SelectPopup[data-starting-style], .canon-SelectPopup[data-ending-style] { - opacity: 0; - transform: scale(.9); -} - -.canon-SelectItem { - width: var(--anchor-width); - padding-block: var(--canon-space-2); - padding-inline: var(--canon-space-4); - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-3); - cursor: pointer; - user-select: none; - font-size: var(--canon-font-size-3); - align-items: center; - gap: var(--canon-space-2); - outline: none; - grid-template-columns: 1rem 1fr; - grid-template-areas: "icon text"; - display: grid; - position: relative; -} - -.canon-SelectItem[data-highlighted] { - z-index: 0; - color: var(--canon-fg-primary); - position: relative; -} - -.canon-SelectItem[data-highlighted]:before { - content: ""; - z-index: -1; - background-color: var(--canon-bg-tint-hover); - border-radius: .25rem; - position: absolute; - inset-block: 0; - inset-inline: .25rem; -} - -.canon-SelectItem[data-disabled] { - cursor: not-allowed; - color: var(--canon-fg-disabled); -} - -.canon-SelectItemIndicator { - grid-area: icon; - justify-content: center; - align-items: center; - display: flex; -} - -.canon-SelectItemText { - flex: 1; - grid-area: text; -} - -.canon-SelectRequired { - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - margin-left: var(--canon-space-1); -} - -.canon-SelectIcon { - justify-content: center; - align-items: center; - display: flex; -} - -.canon-SelectValue { - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; - overflow: hidden; -} diff --git a/packages/canon/css/styles.css b/packages/canon/css/styles.css index 43b1cfbc01..4fbd0cf035 100644 --- a/packages/canon/css/styles.css +++ b/packages/canon/css/styles.css @@ -9349,97 +9349,38 @@ .canon-Button[data-size="medium"] { font-size: var(--canon-font-size-4); padding: 0 var(--canon-space-3); - height: 40px; + height: 2.5rem; } .canon-Button[data-size="small"] { font-size: var(--canon-font-size-3); padding: 0 var(--canon-space-2); - height: 32px; + height: 2rem; } -.canon-ButtonIcon[data-size="small"], .canon-ButtonIcon[data-size="small"] svg { +.canon-Button[data-size="small"] svg { width: 1rem; height: 1rem; } -.canon-ButtonIcon[data-size="medium"], .canon-ButtonIcon[data-size="medium"] svg { +.canon-Button[data-size="medium"] svg { width: 1.25rem; height: 1.25rem; } -.canon-CollapsiblePanel { - height: var(--collapsible-panel-height); - transition: all .15s ease-out; - display: flex; - overflow: hidden; - - &[data-starting-style], &[data-ending-style] { - height: 0; - } -} - -.canon-DataTableRoot { - gap: var(--canon-space-3); - flex-direction: column; - display: flex; -} - -.canon-DataTablePagination { - padding-top: var(--canon-space-5); - justify-content: space-between; +.canon-ButtonIcon { + justify-content: center; align-items: center; - display: flex; } -.canon-DataTablePagination--left { - justify-content: space-between; - align-items: center; - display: flex; +.canon-ButtonIcon[data-size="small"] { + width: 2rem; + padding: 0; } -.canon-DataTablePagination--right { - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - display: flex; -} - -.canon-DataTablePagination--select { - min-width: 10.5rem; -} - -.canon-Flex { - min-width: 0; - display: flex; -} - -.canon-Grid { - display: grid; -} - -.canon-Container { - max-width: 120rem; - padding-inline: var(--canon-space-4); - margin-inline: auto; - transition: padding .2s ease-in-out; -} - -@media (width >= 640px) { - .canon-Container { - padding-inline: var(--canon-space-8); - } -} - -@media (width >= 1024px) { - .canon-Container { - padding-inline: var(--canon-space-12); - } -} - -.canon-Icon { - width: 1rem; - height: 1rem; +.canon-ButtonIcon[data-size="medium"] { + width: 2.5rem; + padding: 0; } .canon-CheckboxRoot { @@ -9495,6 +9436,482 @@ display: flex; } +.canon-CollapsiblePanel { + height: var(--collapsible-panel-height); + transition: all .15s ease-out; + display: flex; + overflow: hidden; + + &[data-starting-style], &[data-ending-style] { + height: 0; + } +} + +.canon-Container { + max-width: 120rem; + padding-inline: var(--canon-space-4); + margin-inline: auto; + transition: padding .2s ease-in-out; +} + +@media (width >= 640px) { + .canon-Container { + padding-inline: var(--canon-space-8); + } +} + +@media (width >= 1024px) { + .canon-Container { + padding-inline: var(--canon-space-12); + } +} + +.canon-DataTableRoot { + gap: var(--canon-space-3); + flex-direction: column; + display: flex; +} + +.canon-DataTablePagination { + padding-top: var(--canon-space-5); + justify-content: space-between; + align-items: center; + display: flex; +} + +.canon-DataTablePagination--left { + justify-content: space-between; + align-items: center; + display: flex; +} + +.canon-DataTablePagination--right { + justify-content: space-between; + align-items: center; + gap: var(--canon-space-2); + display: flex; +} + +.canon-DataTablePagination--select { + min-width: 10.5rem; +} + +.canon-FieldError { + color: var(--canon-fg-danger); + font-size: var(--canon-font-size-2); + font-weight: var(--canon-font-weight-regular); + margin-top: var(--canon-space-2); +} + +.canon-FieldLabelWrapper { + margin-bottom: var(--canon-space-3); + gap: var(--canon-space-1); + flex-direction: column; + display: flex; +} + +.canon-FieldLabel { + color: var(--canon-fg-primary); + cursor: pointer; + font-weight: var(--canon-font-weight-regular); + font-size: var(--canon-font-size-2); + margin-right: auto; +} + +.canon-FieldSecondaryLabel { + color: var(--canon-fg-secondary); + font-weight: var(--canon-font-weight-regular); + margin-left: var(--canon-space-1); +} + +.canon-FieldDescription { + font-weight: var(--canon-font-weight-regular); + font-size: var(--canon-font-size-2); + color: var(--canon-fg-secondary); + margin: 0; +} + +.canon-Flex { + min-width: 0; + display: flex; +} + +.canon-Grid { + display: grid; +} + +.canon-Heading { + font-family: var(--canon-font-regular); + color: var(--canon-fg-primary); + margin: 0; + padding: 0; + line-height: 100%; +} + +.canon-Heading[data-variant="display"] { + font-size: var(--canon-font-size-10); + font-weight: var(--canon-font-weight-bold); +} + +.canon-Heading[data-variant="title1"] { + font-size: var(--canon-font-size-9); + font-weight: var(--canon-font-weight-bold); +} + +.canon-Heading[data-variant="title2"] { + font-size: var(--canon-font-size-8); + font-weight: var(--canon-font-weight-bold); +} + +.canon-Heading[data-variant="title3"] { + font-size: var(--canon-font-size-7); + font-weight: var(--canon-font-weight-bold); +} + +.canon-Heading[data-variant="title4"] { + font-size: var(--canon-font-size-6); + font-weight: var(--canon-font-weight-bold); +} + +.canon-Heading[data-variant="title5"] { + font-size: var(--canon-font-size-5); + font-weight: var(--canon-font-weight-bold); +} + +.canon-Heading[data-color="primary"] { + color: var(--canon-fg-primary); +} + +.canon-Heading[data-color="secondary"] { + color: var(--canon-fg-secondary); +} + +.canon-Heading[data-truncate] { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.canon-Icon { + width: 1rem; + height: 1rem; +} + +.canon-Link { + font-family: var(--canon-font-regular); + color: var(--canon-fg-link); + cursor: pointer; + margin: 0; + padding: 0; + text-decoration-line: none; + + &:hover { + color: var(--canon-fg-link-hover); + text-underline-offset: calc(.025em + 2px); + text-decoration-line: underline; + text-decoration-style: solid; + text-decoration-thickness: min(2px, max(1px, .05em)); + text-decoration-color: color-mix(in srgb, var(--canon-fg-link-hover) 30%, transparent); + } +} + +.canon-Link[data-variant="body"] { + font-size: var(--canon-font-size-3); + line-height: 140%; +} + +.canon-Link[data-variant="subtitle"] { + font-size: var(--canon-font-size-4); + line-height: 140%; +} + +.canon-Link[data-variant="caption"] { + font-size: var(--canon-font-size-2); + line-height: 140%; +} + +.canon-Link[data-variant="label"] { + font-size: var(--canon-font-size-1); + line-height: 140%; +} + +.canon-Link[data-weight="regular"] { + font-weight: var(--canon-font-weight-regular); +} + +.canon-Link[data-weight="bold"] { + font-weight: var(--canon-font-weight-bold); +} + +.canon-MenuPositioner { + outline: 0; +} + +.canon-MenuPopup { + background-color: var(--canon-bg-surface-1); + border: 1px solid var(--canon-border); + color: var(--canon-fg-primary); + transform-origin: var(--transform-origin); + max-width: min(var(--available-width), 340px); + max-height: min(var(--available-height), 500px); + padding-bottom: var(--canon-space-1); + border-radius: .375rem; + outline: none; + flex-direction: column; + transition: transform .15s, opacity .15s; + display: flex; + position: relative; + overflow: auto; + + &[data-starting-style], &[data-ending-style] { + opacity: 0; + transform: scale(.9); + } +} + +.canon-MenuItem { + user-select: none; + align-items: center; + gap: var(--canon-space-2); + height: 32px; + color: var(--canon-fg-primary); + border-radius: var(--canon-radius-2); + margin-inline: var(--canon-space-1); + padding-inline: var(--canon-space-2); + font-size: var(--canon-font-size-3); + cursor: pointer; + outline: 0; + flex-shrink: 0; + text-decoration: none; + display: flex; + + &:first-child { + margin-top: var(--canon-space-1); + } + + &[data-highlighted] { + background-color: var(--canon-gray-3); + } +} + +.canon-MenuSubmenuTrigger { + user-select: none; + justify-content: space-between; + align-items: center; + gap: var(--canon-space-2); + height: 32px; + color: var(--canon-fg-primary); + border-radius: var(--canon-radius-2); + margin-inline: var(--canon-space-1); + padding-inline: var(--canon-space-2); + font-size: var(--canon-font-size-3); + cursor: pointer; + outline: 0; + flex-shrink: 0; + text-decoration: none; + display: flex; + + & .canon-Icon { + color: var(--canon-fg-secondary); + } + + &:first-child { + margin-top: var(--canon-space-1); + } + + &[data-popup-open], &[data-highlighted] { + background-color: var(--canon-gray-3); + + & .canon-Icon { + color: var(--canon-fg-primary); + } + } +} + +.canon-MenuSeparator { + background-color: var(--color-gray-200); + height: 1px; + margin: .375rem 1rem; +} + +.canon-SubmenuComboboxSearch { + padding-inline: var(--canon-space-3); + border: none; + border-bottom: 1px solid var(--canon-border); + background-color: var(--canon-bg-surface-1); + width: 100%; + height: 32px; + color: var(--canon-fg-primary); + line-height: 140%; + font-size: var(--canon-font-size-3); + z-index: 1; + outline: none; + position: sticky; + top: 0; + + &::placeholder { + color: var(--canon-fg-secondary); + } + + &:disabled { + opacity: .6; + cursor: not-allowed; + } +} + +.canon-SubmenuComboboxItems { + padding-top: var(--canon-space-2); + outline: none; + flex-direction: column; + display: flex; + overflow-y: auto; +} + +.canon-SubmenuComboboxNoResults { + padding-inline: var(--canon-space-3); + padding-top: var(--canon-space-2); + padding-bottom: var(--canon-space-4); + color: var(--canon-fg-secondary); + font-size: var(--canon-font-size-3); +} + +.canon-SubmenuComboboxItem { + user-select: none; + justify-content: space-between; + align-items: center; + gap: var(--canon-space-2); + height: 32px; + color: var(--canon-fg-primary); + border-radius: var(--canon-radius-2); + margin-inline: var(--canon-space-1); + padding-inline: var(--canon-space-2); + font-size: var(--canon-font-size-3); + cursor: pointer; + outline: 0; + flex-shrink: 0; + text-decoration: none; + display: flex; + + &[data-highlighted] { + background-color: var(--canon-gray-3); + } + + &[data-disabled] { + opacity: .5; + cursor: not-allowed; + } +} + +.canon-SubmenuComboboxItemCheckbox { + width: 16px; + height: 16px; + color: var(--canon-fg-primary); + border-radius: var(--canon-radius-2); + border: 1px solid var(--canon-border); + background: var(--canon-bg-surface-1); + flex-shrink: 0; + justify-content: center; + align-items: center; + display: flex; +} + +.canon-SubmenuComboboxItemLabel { + text-overflow: ellipsis; + white-space: nowrap; + flex: 1; + overflow: hidden; +} + +.canon-RadioGroup { + color: var(--canon-fg-primary); + flex-direction: column; + display: flex; +} + +.canon-RadioGroup[data-orientation="horizontal"] .canon-RadioGroupContent { + gap: var(--canon-space-4); + flex-direction: row; +} + +.canon-RadioGroupContent { + gap: var(--canon-space-2); + flex-direction: column; + display: flex; +} + +.canon-Radio { + align-items: center; + gap: var(--canon-space-2); + font-size: var(--canon-font-size-2); + color: var(--canon-fg-primary); + forced-color-adjust: none; + display: flex; + position: relative; + + &:before { + content: ""; + box-sizing: border-box; + border: .125rem solid var(--canon-border); + background: var(--canon-gray-1); + border-radius: var(--canon-radius-full); + width: 1rem; + height: 1rem; + transition: all .2s; + display: block; + } + + &[data-pressed]:before { + border-color: var(--canon-border); + } + + &[data-selected] { + &:before { + border-color: var(--canon-bg-solid); + border-width: .25rem; + } + + &[data-pressed]:before { + border-color: var(--canon-bg-solid); + } + } + + &[data-focus-visible]:before { + outline: 2px solid var(--canon-ring); + outline-offset: 2px; + } + + &[data-disabled] { + cursor: not-allowed; + color: var(--canon-fg-disabled); + + &:before { + border-color: var(--canon-border-disabled); + background: var(--canon-bg-disabled); + } + + &[data-selected]:before { + border-color: var(--canon-border-disabled); + } + } + + &[data-invalid]:before, &[data-invalid][data-selected]:before { + border-color: var(--canon-border-danger); + } + + &[data-disabled][data-invalid] { + color: var(--canon-fg-disabled); + + &:before { + border-color: var(--canon-border-disabled); + background: var(--canon-bg-disabled); + } + + &[data-selected]:before { + border-color: var(--canon-border-disabled); + } + } +} + .canon-TableRoot { caption-side: bottom; border-collapse: collapse; @@ -9711,148 +10128,6 @@ overflow: hidden; } -.canon-Heading { - font-family: var(--canon-font-regular); - color: var(--canon-fg-primary); - margin: 0; - padding: 0; - line-height: 100%; -} - -.canon-Heading[data-variant="display"] { - font-size: var(--canon-font-size-10); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title1"] { - font-size: var(--canon-font-size-9); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title2"] { - font-size: var(--canon-font-size-8); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title3"] { - font-size: var(--canon-font-size-7); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title4"] { - font-size: var(--canon-font-size-6); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-variant="title5"] { - font-size: var(--canon-font-size-5); - font-weight: var(--canon-font-weight-bold); -} - -.canon-Heading[data-color="primary"] { - color: var(--canon-fg-primary); -} - -.canon-Heading[data-color="secondary"] { - color: var(--canon-fg-secondary); -} - -.canon-Heading[data-truncate] { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} - -.canon-IconButton { - user-select: none; - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-bold); - cursor: pointer; - border-radius: var(--canon-radius-2); - justify-content: center; - align-items: center; - gap: var(--canon-space-1_5); - border: none; - padding: 0; - display: inline-flex; - - &:disabled { - cursor: not-allowed; - } -} - -.canon-IconButton[data-variant="primary"] { - background-color: var(--canon-bg-solid); - color: var(--canon-fg-solid); - transition: background-color .15s, box-shadow .15s; - - &:hover { - background-color: var(--canon-bg-solid-hover); - } - - &:active { - background-color: var(--canon-bg-solid-pressed); - } - - &:focus-visible { - outline: 2px solid var(--canon-ring); - outline-offset: 2px; - } - - &:disabled { - background-color: var(--canon-bg-solid-disabled); - color: var(--canon-fg-solid-disabled); - } -} - -.canon-IconButton[data-variant="secondary"] { - background-color: var(--canon-bg-surface-1); - box-shadow: inset 0 0 0 1px var(--canon-border); - color: var(--canon-fg-primary); - transition: box-shadow .15s; - - &:hover { - box-shadow: inset 0 0 0 1px var(--canon-border-hover); - } - - &:active { - box-shadow: inset 0 0 0 1px var(--canon-border-pressed); - } - - &:focus-visible { - box-shadow: inset 0 0 0 2px var(--canon-ring); - outline: none; - transition: none; - } - - &:disabled { - box-shadow: inset 0 0 0 1px var(--canon-border-disabled); - color: var(--canon-fg-disabled); - } -} - -.canon-IconButton[data-size="medium"] { - font-size: var(--canon-font-size-4); - width: 40px; - height: 40px; -} - -.canon-IconButton[data-size="small"] { - font-size: var(--canon-font-size-3); - width: 32px; - height: 32px; -} - -.canon-IconButtonIcon[data-size="small"], .canon-IconButtonIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-IconButtonIcon[data-size="medium"], .canon-IconButtonIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} - .canon-TextField { font-family: var(--canon-font-regular); flex-direction: column; @@ -9860,61 +10135,51 @@ display: flex; } -.canon-TextFieldLabel { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); +.canon-InputWrapper { + position: relative; + + &[data-size="small"] .canon-Input { + height: 2rem; + } + + &[data-size="medium"] .canon-Input { + height: 2.5rem; + } + + &[data-size="small"] .canon-Input[data-icon] { + padding-left: var(--canon-space-8); + } + + &[data-size="medium"] .canon-Input[data-icon] { + padding-left: var(--canon-space-9); + } +} + +.canon-InputIcon { + left: var(--canon-space-3); + margin-right: var(--canon-space-1); color: var(--canon-fg-primary); - margin-bottom: var(--canon-space-1_5); - cursor: pointer; - margin-right: auto; + flex-shrink: 0; + position: absolute; + top: 50%; + transform: translateY(-50%); + + &[data-size="small"], &[data-size="small"] svg { + width: 1rem; + height: 1rem; + } + + &[data-size="medium"], &[data-size="medium"] svg { + width: 1.25rem; + height: 1.25rem; + } } -.canon-TextFieldLabel[data-disabled] { - cursor: default; -} - -.canon-TextFieldDescription { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-secondary); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-TextFieldError { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-danger); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-TextFieldInputWrapper { +.canon-Input { padding: 0 var(--canon-space-3); border-radius: var(--canon-radius-3); border: 1px solid var(--canon-border); background-color: var(--canon-bg-surface-1); - align-items: center; - display: flex; -} - -.canon-TextFieldIcon { - margin-right: var(--canon-space-1); - color: var(--canon-fg-primary); - flex-shrink: 0; -} - -.canon-TextFieldIcon[data-size="small"], .canon-TextFieldIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-TextFieldIcon[data-size="medium"], .canon-TextFieldIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} - -.canon-TextFieldInput { font-size: var(--canon-font-size-3); font-family: var(--canon-font-regular); font-weight: var(--canon-font-weight-regular); @@ -9922,306 +10187,81 @@ width: 100%; height: 100%; cursor: inherit; - background: none; - border: none; - padding: 0; + align-items: center; transition: border-color .2s ease-in-out, outline-color .2s ease-in-out; -} - -.canon-TextFieldInput:not([data-filled]):has( + .canon-TextFieldClearButton) { - padding-right: 1.25rem; -} - -.canon-TextFieldInput[type="search"]::-webkit-search-cancel-button, .canon-TextFieldInput[type="search"]::-webkit-search-decoration { - appearance: none; -} - -.canon-TextFieldClearButton { - margin-left: var(--canon-space-1); - vertical-align: middle; - color: var(--canon-fg-primary); - background: none; - border: none; - padding: 0; - display: none; -} - -.canon-TextFieldInput[data-filled] + .canon-TextFieldClearButton { - display: inline-block; -} - -.canon-TextFieldClearButtonIcon { - display: block; -} - -.canon-TextFieldInput::placeholder { - color: var(--canon-fg-secondary); -} - -.canon-TextFieldInput[data-focused] { - outline-color: var(--canon-border-pressed); - outline-width: 0; -} - -.canon-TextFieldInputWrapper:has( > .canon-TextFieldInput:hover) { - border-color: var(--canon-border-hover); -} - -.canon-TextField[data-focused] .canon-TextFieldInputWrapper { - border-color: var(--canon-border-pressed); -} - -.canon-TextField[data-invalid] .canon-TextFieldInputWrapper { - border-color: var(--canon-fg-danger); -} - -.canon-TextField[data-disabled] .canon-TextFieldInputWrapper { - opacity: .5; - cursor: not-allowed; - border: 1px solid var(--canon-border-disabled); -} - -.canon-TextField[data-disabled] .canon-TextFieldClearButton { - cursor: inherit; -} - -.canon-TextFieldInputWrapper[data-size="small"] { - height: 2rem; -} - -.canon-TextFieldInputWrapper[data-size="medium"] { - height: 2.5rem; -} - -.canon-TextFieldRequired { - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - margin-left: var(--canon-space-1); -} - -.canon-MenuPositioner { - outline: 0; -} - -.canon-MenuPopup { - background-color: var(--canon-bg-surface-1); - border: 1px solid var(--canon-border); - color: var(--canon-fg-primary); - transform-origin: var(--transform-origin); - max-width: min(var(--available-width), 340px); - max-height: min(var(--available-height), 500px); - padding-bottom: var(--canon-space-1); - border-radius: .375rem; - outline: none; - flex-direction: column; - transition: transform .15s, opacity .15s; - display: flex; - position: relative; - overflow: auto; - - &[data-starting-style], &[data-ending-style] { - opacity: 0; - transform: scale(.9); - } -} - -.canon-MenuItem { - user-select: none; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; display: flex; - &:first-child { - margin-top: var(--canon-space-1); + &::-webkit-search-cancel-button, &::-webkit-search-decoration { + -webkit-appearance: none; } - &[data-highlighted] { - background-color: var(--canon-gray-3); - } -} - -.canon-MenuSubmenuTrigger { - user-select: none; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - & .canon-Icon { - color: var(--canon-fg-secondary); - } - - &:first-child { - margin-top: var(--canon-space-1); - } - - &[data-popup-open], &[data-highlighted] { - background-color: var(--canon-gray-3); - - & .canon-Icon { - color: var(--canon-fg-primary); - } - } -} - -.canon-MenuSeparator { - background-color: var(--color-gray-200); - height: 1px; - margin: .375rem 1rem; -} - -.canon-SubmenuComboboxSearch { - padding-inline: var(--canon-space-3); - border: none; - border-bottom: 1px solid var(--canon-border); - background-color: var(--canon-bg-surface-1); - height: 32px; - color: var(--canon-fg-primary); - line-height: 140%; - font-size: var(--canon-font-size-3); - z-index: 1; - outline: none; - position: sticky; - top: 0; - &::placeholder { color: var(--canon-fg-secondary); } - &:disabled { - opacity: .6; - cursor: not-allowed; + &[data-focused] { + outline-color: var(--canon-border-pressed); + outline-width: 0; } -} -.canon-SubmenuComboboxItems { - padding-top: var(--canon-space-2); - outline: none; - flex-direction: column; - display: flex; - overflow-y: auto; -} + &[data-hovered] { + border-color: var(--canon-border-hover); + } -.canon-SubmenuComboboxNoResults { - padding-inline: var(--canon-space-3); - padding-top: var(--canon-space-2); - padding-bottom: var(--canon-space-4); - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-3); -} + &[data-focused] { + border-color: var(--canon-border-pressed); + outline-width: 0; + } -.canon-SubmenuComboboxItem { - user-select: none; - justify-content: space-between; - align-items: center; - gap: var(--canon-space-2); - height: 32px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - margin-inline: var(--canon-space-1); - padding-inline: var(--canon-space-2); - font-size: var(--canon-font-size-3); - cursor: pointer; - outline: 0; - flex-shrink: 0; - text-decoration: none; - display: flex; - - &[data-highlighted] { - background-color: var(--canon-gray-3); + &[data-invalid] { + border-color: var(--canon-fg-danger); } &[data-disabled] { opacity: .5; cursor: not-allowed; + border: 1px solid var(--canon-border-disabled); } } -.canon-SubmenuComboboxItemCheckbox { - width: 16px; - height: 16px; - color: var(--canon-fg-primary); - border-radius: var(--canon-radius-2); - border: 1px solid var(--canon-border); - background: var(--canon-bg-surface-1); - flex-shrink: 0; +.canon-SearchField[data-empty] .canon-InputClear { + display: none; +} + +.canon-InputClear { + cursor: pointer; + color: var(--canon-fg-secondary); + background-color: #0000; + border: none; justify-content: center; align-items: center; - display: flex; -} - -.canon-SubmenuComboboxItemLabel { - text-overflow: ellipsis; - white-space: nowrap; - flex: 1; - overflow: hidden; -} - -.canon-Link { - font-family: var(--canon-font-regular); - color: var(--canon-fg-link); - cursor: pointer; margin: 0; padding: 0; - text-decoration-line: none; - - &:hover { - color: var(--canon-fg-link-hover); - text-underline-offset: calc(.025em + 2px); - text-decoration-line: underline; - text-decoration-style: solid; - text-decoration-thickness: min(2px, max(1px, .05em)); - text-decoration-color: color-mix(in srgb, var(--canon-fg-link-hover) 30%, transparent); - } + transition: color .2s ease-in-out; + display: flex; + position: absolute; + top: 0; + bottom: 0; + right: 0; } -.canon-Link[data-variant="body"] { - font-size: var(--canon-font-size-3); - line-height: 140%; +.canon-InputClear:hover { + color: var(--canon-fg-primary); } -.canon-Link[data-variant="subtitle"] { - font-size: var(--canon-font-size-4); - line-height: 140%; +.canon-InputClear[data-size="small"] { + width: 2rem; + height: 2rem; } -.canon-Link[data-variant="caption"] { - font-size: var(--canon-font-size-2); - line-height: 140%; +.canon-InputClear[data-size="medium"] { + width: 2.5rem; + height: 2.5rem; } -.canon-Link[data-variant="label"] { - font-size: var(--canon-font-size-1); - line-height: 140%; -} - -.canon-Link[data-weight="regular"] { - font-weight: var(--canon-font-weight-regular); -} - -.canon-Link[data-weight="bold"] { - font-weight: var(--canon-font-weight-bold); +.canon-InputClear svg { + width: 1rem; + height: 1rem; } .canon-TooltipPopup { @@ -10525,3 +10565,61 @@ width: 100%; overflow: hidden; } + +.canon-Switch { + align-items: center; + gap: var(--canon-space-3); + font-size: var(--canon-font-size-3); + color: var(--canon-fg-primary); + cursor: pointer; + display: flex; + position: relative; + + &[data-pressed] .canon-SwitchIndicator { + &:before { + background: var(--canon-fg-solid); + } + } + + &[data-selected] { + & .canon-SwitchIndicator { + background: var(--canon-bg-solid); + + &:before { + background: var(--canon-fg-solid); + transform: translateX(100%); + } + } + + &[data-pressed] { + & .indicator { + background: var(--canon-gray-3); + } + } + } + + &[data-focus-visible] .canon-SwitchIndicator { + outline-offset: 2px; + outline: 2px solid; + } +} + +.canon-SwitchIndicator { + background: var(--canon-gray-3); + border: 2px; + border-radius: 1.143rem; + width: 2rem; + height: 1.143rem; + transition: all .2s; + + &:before { + content: ""; + background: var(--canon-fg-solid); + border-radius: 16px; + width: .857rem; + height: .857rem; + margin: .143rem; + transition: all .2s; + display: block; + } +} diff --git a/packages/canon/css/table.css b/packages/canon/css/table.css deleted file mode 100644 index f14ee3759e..0000000000 --- a/packages/canon/css/table.css +++ /dev/null @@ -1,4 +0,0 @@ -.canon-TableCell { - padding: var(--canon-space-3); - font-size: var(--canon-font-size-3); -} diff --git a/packages/canon/css/tabs.css b/packages/canon/css/tabs.css deleted file mode 100644 index a9bf036c3e..0000000000 --- a/packages/canon/css/tabs.css +++ /dev/null @@ -1,76 +0,0 @@ -.canon-TabsRoot { - border: 1px solid var(--color-gray-200); - border-radius: .375rem; -} - -.canon-TabsList { - z-index: 0; - display: flex; - position: relative; -} - -.canon-TabsTab { - appearance: none; - color: var(--canon-fg-secondary); - user-select: none; - padding-inline: var(--canon-space-3); - height: 2rem; - font-family: inherit; - font-size: .875rem; - font-weight: 500; - line-height: 1.25rem; - font-size: var(--canon-font-size-2); - cursor: pointer; - background: none; - border: 0; - outline: 0; - justify-content: center; - align-items: center; - margin: 0; - padding-block: 0; - transition: color .2s ease-in-out; - display: flex; - - &[data-selected] { - color: var(--canon-fg-primary); - } - - @media (hover: hover) { - &:hover { - color: var(--canon-fg-primary); - } - } - - &:focus-visible { - position: relative; - - &:before { - content: ""; - outline: 1px solid var(--canon-ring); - outline-offset: -1px; - border-radius: .25rem; - position: absolute; - inset: .25rem 0; - } - } -} - -.canon-TabsIndicator { - z-index: -1; - translate: var(--active-tab-left) -50%; - width: var(--active-tab-width); - background-color: var(--canon-bg-solid); - height: 1px; - transition-property: translate, width; - transition-duration: .2s; - transition-timing-function: ease-in-out; - position: absolute; - bottom: 0; - left: 0; -} - -.canon-TabsPanel { - &[hidden] { - display: none; - } -} diff --git a/packages/canon/css/text.css b/packages/canon/css/text.css deleted file mode 100644 index c4f9671816..0000000000 --- a/packages/canon/css/text.css +++ /dev/null @@ -1,59 +0,0 @@ -.canon-Text { - font-family: var(--canon-font-regular); - margin: 0; - padding: 0; -} - -.canon-Text[data-variant="body"] { - font-size: var(--canon-font-size-3); - line-height: 140%; -} - -.canon-Text[data-variant="subtitle"] { - font-size: var(--canon-font-size-4); - line-height: 140%; -} - -.canon-Text[data-variant="caption"] { - font-size: var(--canon-font-size-2); - line-height: 140%; -} - -.canon-Text[data-variant="label"] { - font-size: var(--canon-font-size-1); - line-height: 140%; -} - -.canon-Text[data-weight="regular"] { - font-weight: var(--canon-font-weight-regular); -} - -.canon-Text[data-weight="bold"] { - font-weight: var(--canon-font-weight-bold); -} - -.canon-Text[data-color="primary"] { - color: var(--canon-fg-primary); -} - -.canon-Text[data-color="secondary"] { - color: var(--canon-fg-secondary); -} - -.canon-Text[data-color="danger"] { - color: var(--canon-fg-danger); -} - -.canon-Text[data-color="warning"] { - color: var(--canon-fg-warning); -} - -.canon-Text[data-color="success"] { - color: var(--canon-fg-success); -} - -.canon-Text[data-truncate] { - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; -} diff --git a/packages/canon/css/textfield.css b/packages/canon/css/textfield.css deleted file mode 100644 index c3c1a88ad6..0000000000 --- a/packages/canon/css/textfield.css +++ /dev/null @@ -1,146 +0,0 @@ -.canon-TextField { - font-family: var(--canon-font-regular); - flex-direction: column; - width: 100%; - display: flex; -} - -.canon-TextFieldLabel { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - margin-bottom: var(--canon-space-1_5); - cursor: pointer; - margin-right: auto; -} - -.canon-TextFieldLabel[data-disabled] { - cursor: default; -} - -.canon-TextFieldDescription { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-secondary); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-TextFieldError { - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-danger); - padding-top: var(--canon-space-1_5); - margin: 0; -} - -.canon-TextFieldInputWrapper { - padding: 0 var(--canon-space-3); - border-radius: var(--canon-radius-3); - border: 1px solid var(--canon-border); - background-color: var(--canon-bg-surface-1); - align-items: center; - display: flex; -} - -.canon-TextFieldIcon { - margin-right: var(--canon-space-1); - color: var(--canon-fg-primary); - flex-shrink: 0; -} - -.canon-TextFieldIcon[data-size="small"], .canon-TextFieldIcon[data-size="small"] svg { - width: 1rem; - height: 1rem; -} - -.canon-TextFieldIcon[data-size="medium"], .canon-TextFieldIcon[data-size="medium"] svg { - width: 1.25rem; - height: 1.25rem; -} - -.canon-TextFieldInput { - font-size: var(--canon-font-size-3); - font-family: var(--canon-font-regular); - font-weight: var(--canon-font-weight-regular); - color: var(--canon-fg-primary); - width: 100%; - height: 100%; - cursor: inherit; - background: none; - border: none; - padding: 0; - transition: border-color .2s ease-in-out, outline-color .2s ease-in-out; -} - -.canon-TextFieldInput:not([data-filled]):has( + .canon-TextFieldClearButton) { - padding-right: 1.25rem; -} - -.canon-TextFieldInput[type="search"]::-webkit-search-cancel-button, .canon-TextFieldInput[type="search"]::-webkit-search-decoration { - appearance: none; -} - -.canon-TextFieldClearButton { - margin-left: var(--canon-space-1); - vertical-align: middle; - color: var(--canon-fg-primary); - background: none; - border: none; - padding: 0; - display: none; -} - -.canon-TextFieldInput[data-filled] + .canon-TextFieldClearButton { - display: inline-block; -} - -.canon-TextFieldClearButtonIcon { - display: block; -} - -.canon-TextFieldInput::placeholder { - color: var(--canon-fg-secondary); -} - -.canon-TextFieldInput[data-focused] { - outline-color: var(--canon-border-pressed); - outline-width: 0; -} - -.canon-TextFieldInputWrapper:has( > .canon-TextFieldInput:hover) { - border-color: var(--canon-border-hover); -} - -.canon-TextField[data-focused] .canon-TextFieldInputWrapper { - border-color: var(--canon-border-pressed); -} - -.canon-TextField[data-invalid] .canon-TextFieldInputWrapper { - border-color: var(--canon-fg-danger); -} - -.canon-TextField[data-disabled] .canon-TextFieldInputWrapper { - opacity: .5; - cursor: not-allowed; - border: 1px solid var(--canon-border-disabled); -} - -.canon-TextField[data-disabled] .canon-TextFieldClearButton { - cursor: inherit; -} - -.canon-TextFieldInputWrapper[data-size="small"] { - height: 2rem; -} - -.canon-TextFieldInputWrapper[data-size="medium"] { - height: 2.5rem; -} - -.canon-TextFieldRequired { - color: var(--canon-fg-secondary); - font-size: var(--canon-font-size-2); - font-weight: var(--canon-font-weight-regular); - margin-left: var(--canon-space-1); -} diff --git a/packages/canon/css/tooltip.css b/packages/canon/css/tooltip.css deleted file mode 100644 index 05f2bab79f..0000000000 --- a/packages/canon/css/tooltip.css +++ /dev/null @@ -1,61 +0,0 @@ -.canon-TooltipPopup { - box-sizing: border-box; - transform-origin: var(--transform-origin); - background-color: canvas; - background-color: var(--canon-bg-surface-1); - color: var(--canon-fg-primary); - outline: 1px solid var(--canon-border); - box-shadow: 0 10px 15px -3px var(--canon-border), 0 4px 6px -4px var(--canon-border); - border-radius: .375rem; - flex-direction: column; - padding: .25rem .5rem; - font-size: .875rem; - line-height: 1.25rem; - transition: transform .15s, opacity .15s; - display: flex; - - &[data-starting-style], &[data-ending-style] { - opacity: 0; - transform: scale(.9); - } - - &[data-instant] { - transition-duration: 0s; - } -} - -.canon-TooltipArrow { - display: flex; - - &[data-side="top"] { - bottom: -8px; - rotate: 180deg; - } - - &[data-side="bottom"] { - top: -8px; - rotate: none; - } - - &[data-side="left"] { - right: -13px; - rotate: 90deg; - } - - &[data-side="right"] { - left: -13px; - rotate: -90deg; - } -} - -.canon-TooltipArrow-fill { - fill: var(--canon-bg-surface-1); -} - -.canon-TooltipArrow-outer-stroke { - @media (prefers-color-scheme: light) { - & { - fill: var(--canon-border); - } - } -} diff --git a/packages/canon/package.json b/packages/canon/package.json index e20572741e..eb6165aa8c 100644 --- a/packages/canon/package.json +++ b/packages/canon/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/canon", - "version": "0.5.0-next.2", + "version": "0.6.0-next.0", "backstage": { "role": "web-library" }, @@ -44,7 +44,8 @@ "@base-ui-components/react": "1.0.0-alpha.7", "@remixicon/react": "^4.6.0", "@tanstack/react-table": "^8.21.3", - "clsx": "^2.1.1" + "clsx": "^2.1.1", + "react-aria-components": "^1.10.1" }, "devDependencies": { "@backstage/cli": "workspace:^", diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index b6ce130ecc..372b82436b 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -5,26 +5,34 @@ ```ts import { Avatar as Avatar_2 } from '@base-ui-components/react/avatar'; import { Breakpoint as Breakpoint_2 } from '@backstage/canon'; +import { ButtonProps as ButtonProps_2 } from 'react-aria-components'; import { ChangeEvent } from 'react'; import { Collapsible as Collapsible_2 } from '@base-ui-components/react/collapsible'; import { ComponentProps } from 'react'; +import type { ComponentPropsWithRef } from 'react'; import { Context } from 'react'; import type { CSSProperties } from 'react'; +import type { ElementType } from 'react'; import { FC } from 'react'; import { FocusEvent as FocusEvent_2 } from 'react'; import { ForwardRefExoticComponent } from 'react'; import { HTMLAttributes } from 'react'; import { JSX as JSX_2 } from 'react/jsx-runtime'; +import { LinkProps as LinkProps_2 } from 'react-aria-components'; import { Menu as Menu_2 } from '@base-ui-components/react/menu'; -import type { MouseEventHandler } from 'react'; +import type { RadioGroupProps as RadioGroupProps_2 } from 'react-aria-components'; +import type { RadioProps as RadioProps_2 } from 'react-aria-components'; import { ReactElement } from 'react'; import { ReactNode } from 'react'; import { RefAttributes } from 'react'; import type { RemixiconComponentType } from '@remixicon/react'; import { ScrollArea as ScrollArea_2 } from '@base-ui-components/react/scroll-area'; +import type { SearchFieldProps as SearchFieldProps_2 } from 'react-aria-components'; +import type { SwitchProps as SwitchProps_2 } from 'react-aria-components'; import { Table as Table_2 } from '@tanstack/react-table'; import { Tabs as Tabs_2 } from '@base-ui-components/react/tabs'; import { TdHTMLAttributes } from 'react'; +import type { TextFieldProps as TextFieldProps_2 } from 'react-aria-components'; import { ThHTMLAttributes } from 'react'; import { Tooltip as Tooltip_2 } from '@base-ui-components/react/tooltip'; import type { useRender } from '@base-ui-components/react/use-render'; @@ -149,36 +157,64 @@ export const breakpoints: Breakpoint[]; // @public (undocumented) export const Button: ForwardRefExoticComponent< - Omit & RefAttributes + ButtonProps & RefAttributes >; // @public (undocumented) -export type ButtonOwnProps = GetPropDefTypes; - -// @public (undocumented) -export const buttonPropDefs: { - variant: { - type: 'enum'; - values: ('primary' | 'secondary')[]; - className: string; - default: 'primary'; - responsive: true; - }; - size: { - type: 'enum'; - values: ('small' | 'medium')[]; - className: string; - default: 'medium'; - responsive: true; - }; -}; +export const ButtonIcon: ForwardRefExoticComponent< + ButtonIconProps & RefAttributes +>; // @public -export interface ButtonProps extends useRender.ComponentProps<'button'> { +export interface ButtonIconProps extends ButtonProps_2 { + // (undocumented) + icon?: ReactElement; + // (undocumented) + size?: 'small' | 'medium' | Partial>; + // (undocumented) + variant?: + | 'primary' + | 'secondary' + | Partial>; +} + +// @public (undocumented) +export const ButtonLink: ForwardRefExoticComponent< + ButtonLinkProps & RefAttributes +>; + +// @public +export interface ButtonLinkProps extends LinkProps_2 { + // (undocumented) + children?: ReactNode; + // (undocumented) iconEnd?: ReactElement; + // (undocumented) iconStart?: ReactElement; - size?: ButtonOwnProps['size']; - variant?: ButtonOwnProps['variant']; + // (undocumented) + size?: 'small' | 'medium' | Partial>; + // (undocumented) + variant?: + | 'primary' + | 'secondary' + | Partial>; +} + +// @public +export interface ButtonProps extends ButtonProps_2 { + // (undocumented) + children?: ReactNode; + // (undocumented) + iconEnd?: ReactElement; + // (undocumented) + iconStart?: ReactElement; + // (undocumented) + size?: 'small' | 'medium' | Partial>; + // (undocumented) + variant?: + | 'primary' + | 'secondary' + | Partial>; } // @public (undocumented) @@ -210,6 +246,9 @@ export interface CheckboxProps { value?: string; } +// @public +export type ClassNamesMap = Record; + // @public export const Collapsible: { Root: ForwardRefExoticComponent< @@ -232,6 +271,253 @@ export const Collapsible: { // @public (undocumented) export type Columns = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 'auto'; +// @public +export type ComponentClassNames = + (typeof componentDefinitions)[T]['classNames']; + +// @public +export interface ComponentDefinition { + // (undocumented) + classNames: ClassNamesMap; + // (undocumented) + dataAttributes?: DataAttributesMap; +} + +// @public +export type ComponentDefinitionName = keyof typeof componentDefinitions; + +// @public +export const componentDefinitions: { + readonly Avatar: { + readonly classNames: { + readonly root: 'canon-AvatarRoot'; + readonly image: 'canon-AvatarImage'; + readonly fallback: 'canon-AvatarFallback'; + }; + readonly dataAttributes: { + readonly size: readonly ['small', 'medium', 'large']; + }; + }; + readonly Box: { + readonly classNames: { + readonly root: 'canon-Box'; + }; + }; + readonly Button: { + readonly classNames: { + readonly root: 'canon-Button'; + }; + readonly dataAttributes: { + readonly size: readonly ['small', 'medium', 'large']; + readonly variant: readonly ['primary', 'secondary', 'ghost']; + }; + }; + readonly ButtonIcon: { + readonly classNames: { + readonly root: 'canon-ButtonIcon'; + }; + }; + readonly ButtonLink: { + readonly classNames: { + readonly root: 'canon-ButtonLink'; + }; + }; + readonly Checkbox: { + readonly classNames: { + readonly root: 'canon-CheckboxRoot'; + readonly label: 'canon-CheckboxLabel'; + readonly indicator: 'canon-CheckboxIndicator'; + }; + readonly dataAttributes: { + readonly checked: readonly [true, false]; + }; + }; + readonly Collapsible: { + readonly classNames: { + readonly root: 'canon-CollapsibleRoot'; + readonly trigger: 'canon-CollapsibleTrigger'; + readonly panel: 'canon-CollapsiblePanel'; + }; + }; + readonly Container: { + readonly classNames: { + readonly root: 'canon-Container'; + }; + }; + readonly FieldLabel: { + readonly classNames: { + readonly root: 'canon-FieldLabelWrapper'; + readonly label: 'canon-FieldLabel'; + readonly secondaryLabel: 'canon-FieldSecondaryLabel'; + readonly description: 'canon-FieldDescription'; + }; + }; + readonly Flex: { + readonly classNames: { + readonly root: 'canon-Flex'; + }; + }; + readonly Grid: { + readonly classNames: { + readonly root: 'canon-Grid'; + readonly item: 'canon-GridItem'; + }; + }; + readonly Heading: { + readonly classNames: { + readonly root: 'canon-Heading'; + }; + readonly dataAttributes: { + readonly variant: readonly ['title1', 'title2', 'title3', 'subtitle']; + readonly color: readonly ['primary', 'secondary', 'muted']; + readonly truncate: readonly [true, false]; + }; + }; + readonly Icon: { + readonly classNames: { + readonly root: 'canon-Icon'; + }; + }; + readonly Link: { + readonly classNames: { + readonly root: 'canon-Link'; + }; + readonly dataAttributes: { + readonly variant: readonly ['subtitle', 'body', 'caption', 'label']; + readonly weight: readonly ['regular', 'bold']; + }; + }; + readonly Menu: { + readonly classNames: { + readonly trigger: 'canon-MenuTrigger'; + readonly backdrop: 'canon-MenuBackdrop'; + readonly positioner: 'canon-MenuPositioner'; + readonly popup: 'canon-MenuPopup'; + readonly arrow: 'canon-MenuArrow'; + readonly item: 'canon-MenuItem'; + readonly group: 'canon-MenuGroup'; + readonly groupLabel: 'canon-MenuGroupLabel'; + readonly radioGroup: 'canon-MenuRadioGroup'; + readonly radioItem: 'canon-MenuRadioItem'; + readonly radioItemIndicator: 'canon-MenuRadioItemIndicator'; + readonly checkboxItem: 'canon-MenuCheckboxItem'; + readonly checkboxItemIndicator: 'canon-MenuCheckboxItemIndicator'; + readonly submenuTrigger: 'canon-MenuSubmenuTrigger'; + readonly separator: 'canon-MenuSeparator'; + }; + }; + readonly RadioGroup: { + readonly classNames: { + readonly root: 'canon-RadioGroup'; + readonly content: 'canon-RadioGroupContent'; + readonly radio: 'canon-Radio'; + }; + }; + readonly ScrollArea: { + readonly classNames: { + readonly root: 'canon-ScrollAreaRoot'; + readonly viewport: 'canon-ScrollAreaViewport'; + readonly scrollbar: 'canon-ScrollAreaScrollbar'; + readonly thumb: 'canon-ScrollAreaThumb'; + }; + }; + readonly SearchField: { + readonly classNames: { + readonly root: 'canon-SearchField'; + readonly clear: 'canon-InputClear'; + }; + }; + readonly Select: { + readonly classNames: { + readonly root: 'canon-Select'; + readonly required: 'canon-SelectRequired'; + readonly trigger: 'canon-SelectTrigger'; + readonly value: 'canon-SelectValue'; + readonly icon: 'canon-SelectIcon'; + readonly popup: 'canon-SelectPopup'; + readonly item: 'canon-SelectItem'; + readonly itemIndicator: 'canon-SelectItemIndicator'; + readonly itemText: 'canon-SelectItemText'; + readonly description: 'canon-SelectDescription'; + readonly error: 'canon-SelectError'; + }; + readonly dataAttributes: { + readonly size: readonly ['small', 'medium']; + }; + }; + readonly Switch: { + readonly classNames: { + readonly root: 'canon-Switch'; + readonly indicator: 'canon-SwitchIndicator'; + }; + }; + readonly Table: { + readonly classNames: { + readonly root: 'canon-TableRoot'; + readonly header: 'canon-TableHeader'; + readonly body: 'canon-TableBody'; + readonly row: 'canon-TableRow'; + readonly head: 'canon-TableHead'; + readonly caption: 'canon-TableCaption'; + readonly cell: 'canon-TableCell'; + readonly cellText: 'canon-TableCellText'; + readonly cellLink: 'canon-TableCellLink'; + readonly cellProfile: 'canon-TableCellProfile'; + readonly cellProfileAvatar: 'canon-TableCellProfileAvatar'; + readonly cellProfileAvatarImage: 'canon-TableCellProfileAvatarImage'; + readonly cellProfileAvatarFallback: 'canon-TableCellProfileAvatarFallback'; + readonly cellProfileName: 'canon-TableCellProfileName'; + readonly cellProfileLink: 'canon-TableCellProfileLink'; + }; + }; + readonly Tabs: { + readonly classNames: { + readonly root: 'canon-TabsRoot'; + readonly list: 'canon-TabsList'; + readonly indicator: 'canon-TabsIndicator'; + readonly tab: 'canon-TabsTab'; + readonly panel: 'canon-TabsPanel'; + }; + }; + readonly Text: { + readonly classNames: { + readonly root: 'canon-Text'; + }; + readonly dataAttributes: { + readonly variant: readonly ['subtitle', 'body', 'caption', 'label']; + readonly weight: readonly ['regular', 'bold']; + readonly color: readonly [ + 'primary', + 'secondary', + 'danger', + 'warning', + 'success', + ]; + readonly truncate: readonly [true, false]; + }; + }; + readonly TextField: { + readonly classNames: { + readonly root: 'canon-TextField'; + readonly inputWrapper: 'canon-InputWrapper'; + readonly input: 'canon-Input'; + readonly inputIcon: 'canon-InputIcon'; + }; + readonly dataAttributes: { + readonly invalid: readonly [true, false]; + readonly disabled: readonly [true, false]; + }; + }; + readonly Tooltip: { + readonly classNames: { + readonly trigger: 'canon-TooltipTrigger'; + readonly positioner: 'canon-TooltipPositioner'; + readonly popup: 'canon-TooltipPopup'; + readonly arrow: 'canon-TooltipArrow'; + }; + }; +}; + // @public (undocumented) export const Container: ForwardRefExoticComponent< ContainerProps & RefAttributes @@ -259,6 +545,12 @@ export interface ContainerProps { style?: React.CSSProperties; } +// @public +export type DataAttributesMap = Record; + +// @public +export type DataAttributeValues = readonly (string | number | boolean)[]; + // @public export const DataTable: { Root: ( @@ -353,6 +645,20 @@ export type EnumPropDef = { required?: boolean; }; +// @public (undocumented) +export const FieldLabel: ForwardRefExoticComponent< + FieldLabelProps & RefAttributes +>; + +// @public (undocumented) +export interface FieldLabelProps { + description?: string | null; + htmlFor?: string; + id?: string; + label?: string | null; + secondaryLabel?: string | null; +} + // @public (undocumented) export const Flex: ForwardRefExoticComponent< FlexProps & RefAttributes @@ -611,25 +917,15 @@ export interface GridProps extends SpaceProps { } // @public (undocumented) -export const Heading: ForwardRefExoticComponent< - Omit & RefAttributes ->; +export const Heading: ( + props: HeadingProps & { + ref?: React.Ref; + }, +) => React.ReactElement | null; // @public (undocumented) -export interface HeadingProps - extends Omit, 'color'> { - // (undocumented) - className?: string; - // (undocumented) - color?: - | 'primary' - | 'secondary' - | Partial>; - // (undocumented) - style?: React.CSSProperties; - // (undocumented) - truncate?: boolean; - // (undocumented) +export type HeadingOwnProps = { + as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; variant?: | 'display' | 'title1' @@ -643,7 +939,18 @@ export interface HeadingProps 'display' | 'title1' | 'title2' | 'title3' | 'title4' | 'title5' > >; -} + color?: + | 'primary' + | 'secondary' + | Partial>; + truncate?: boolean; + className?: string; + style?: React.CSSProperties; +}; + +// @public (undocumented) +export type HeadingProps = HeadingOwnProps & + Omit, keyof HeadingOwnProps>; // @public (undocumented) export const heightPropDefs: { @@ -673,40 +980,6 @@ export type HeightProps = GetPropDefTypes; // @public (undocumented) export const Icon: (props: IconProps) => JSX_2.Element | null; -// @public (undocumented) -export const IconButton: ForwardRefExoticComponent< - IconButtonProps & RefAttributes ->; - -// @public (undocumented) -export type IconButtonOwnProps = GetPropDefTypes; - -// @public (undocumented) -export const iconButtonPropDefs: { - variant: { - type: 'enum'; - values: ('primary' | 'secondary')[]; - className: string; - default: 'primary'; - responsive: true; - }; - size: { - type: 'enum'; - values: ('small' | 'medium')[]; - className: string; - default: 'medium'; - responsive: true; - }; -}; - -// @public -export interface IconButtonProps - extends Omit, 'children'> { - icon: ReactElement; - size?: IconButtonOwnProps['size']; - variant?: IconButtonOwnProps['variant']; -} - // @public (undocumented) export const IconContext: Context; @@ -1018,6 +1291,27 @@ export type PositionProps = GetPropDefTypes; // @public (undocumented) export type PropDef = RegularPropDef | ResponsivePropDef; +// @public (undocumented) +export const Radio: ForwardRefExoticComponent< + RadioProps & RefAttributes +>; + +// @public (undocumented) +export const RadioGroup: ForwardRefExoticComponent< + RadioGroupProps & RefAttributes +>; + +// @public (undocumented) +export interface RadioGroupProps + extends Omit, + Omit { + // (undocumented) + children?: ReactNode; +} + +// @public (undocumented) +export interface RadioProps extends RadioProps_2 {} + // @public (undocumented) export type ReactNodePropDef = { type: 'ReactNode'; @@ -1064,6 +1358,20 @@ export const ScrollArea: { >; }; +// @public (undocumented) +export const SearchField: ForwardRefExoticComponent< + SearchFieldProps & RefAttributes +>; + +// @public (undocumented) +export interface SearchFieldProps + extends SearchFieldProps_2, + Omit { + icon?: ReactNode | false; + placeholder?: string; + size?: 'small' | 'medium' | Partial>; +} + // @public (undocumented) export const Select: ForwardRefExoticComponent< SelectProps & RefAttributes @@ -1159,6 +1467,16 @@ export type StylingPropDef = { parseValue?: (value: string) => string | undefined; }; +// @public (undocumented) +export const Switch: ForwardRefExoticComponent< + SwitchProps & RefAttributes +>; + +// @public (undocumented) +export interface SwitchProps extends SwitchProps_2 { + label?: string; +} + // @public export const Table: { Root: ForwardRefExoticComponent< @@ -1258,9 +1576,11 @@ export interface TabsRootWithoutOrientation > {} // @public (undocumented) -const Text_2: ForwardRefExoticComponent< - Omit & RefAttributes ->; +const Text_2: ( + props: TextProps & { + ref?: React.Ref; + }, +) => React.ReactElement | null; export { Text_2 as Text }; // @public (undocumented) @@ -1270,23 +1590,23 @@ export const TextField: ForwardRefExoticComponent< // @public (undocumented) export interface TextFieldProps - extends Omit, 'size'> { - className?: string; - description?: string; - error?: string | null; + extends TextFieldProps_2, + Omit { icon?: ReactNode; - label?: string; - name: string; - onClear?: MouseEventHandler; + placeholder?: string; size?: 'small' | 'medium' | Partial>; } // @public (undocumented) -export interface TextProps - extends Omit, 'color'> { - // (undocumented) - className?: string; - // (undocumented) +export type TextOwnProps = { + as?: 'p' | 'span' | 'label'; + variant?: + | 'subtitle' + | 'body' + | 'caption' + | 'label' + | Partial>; + weight?: 'regular' | 'bold' | Partial>; color?: | 'primary' | 'secondary' @@ -1299,20 +1619,14 @@ export interface TextProps 'primary' | 'secondary' | 'danger' | 'warning' | 'success' > >; - // (undocumented) - style?: CSSProperties; - // (undocumented) truncate?: boolean; - // (undocumented) - variant?: - | 'subtitle' - | 'body' - | 'caption' - | 'label' - | Partial>; - // (undocumented) - weight?: 'regular' | 'bold' | Partial>; -} + className?: string; + style?: React.CSSProperties; +}; + +// @public (undocumented) +export type TextProps = TextOwnProps & + Omit, keyof TextOwnProps>; // @public (undocumented) export const Tooltip: { diff --git a/packages/canon/scripts/build-css.mjs b/packages/canon/scripts/build-css.mjs index e76f5138ba..245b3cf282 100644 --- a/packages/canon/scripts/build-css.mjs +++ b/packages/canon/scripts/build-css.mjs @@ -17,89 +17,55 @@ /* eslint-disable no-restricted-imports */ import { transform, bundle } from 'lightningcss'; import fs from 'fs'; -import path from 'path'; import chalk from 'chalk'; -import { glob } from 'glob'; /* eslint-enable no-restricted-imports */ -// Check if core.css and components.css exist -const cssDir = 'src/css'; +const srcFile = 'src/css/styles.css'; const distDir = 'css'; -const componentsDir = 'src/components'; +const distFile = `${distDir}/styles.css`; -// Core files -const cssFiles = [ - { path: `${cssDir}/core.css`, newName: 'core.css' }, - { path: `${cssDir}/components.css`, newName: 'components.css' }, - { path: `${cssDir}/styles.css`, newName: 'styles.css' }, -]; - -// Components files -const componentsFiles = glob - .sync('**/*.css', { cwd: componentsDir }) - .map(file => { - const folderName = file.split('/')[0].toLocaleLowerCase('en-US'); - return { path: `${componentsDir}/${file}`, newName: `${folderName}.css` }; - }); - -// Combine core and components files -cssFiles.push(...componentsFiles); - -// Check if files exist -cssFiles.forEach(file => { - if (!fs.existsSync(file.path)) { - console.error(`${file.originalName} does not exist`); - process.exit(1); - } -}); +// Check if styles.css exists +if (!fs.existsSync(srcFile)) { + console.error(`${srcFile} does not exist`); + process.exit(1); +} // Ensure the dist/css directory exists if (!fs.existsSync(distDir)) { fs.mkdirSync(distDir, { recursive: true }); } -// Add watch mode support const args = process.argv.slice(2); const watchMode = args.includes('--watch'); async function buildCSS(logs = true) { - // Bundle and transform files - cssFiles.forEach(file => { - let { code: bundleCode } = bundle({ - filename: file.path, - }); + const css = fs.readFileSync(srcFile); - let { code } = transform({ - filename: `${distDir}/${file.newName}`, - code: bundleCode, - }); - - fs.writeFileSync(`${distDir}/${file.newName}`, code); - - if (logs) { - console.log(chalk.blue('CSS bundled: ') + file.newName); - } + let { code: bundleCode } = bundle({ + filename: srcFile, }); + const { code } = transform({ + filename: distFile, + code: bundleCode, + minify: false, + }); + fs.writeFileSync(distFile, code); if (logs) { - console.log(chalk.green('CSS files bundled successfully!')); + console.log(chalk.blue('CSS transformed and minified: ') + 'styles.css'); + console.log(chalk.green('CSS file built successfully!')); } } if (watchMode) { - // Watch both directories for changes - [cssDir, componentsDir].forEach(dir => { - fs.watch(dir, { recursive: true }, (eventType, filename) => { - if (filename?.endsWith('.css')) { - console.log( - chalk.yellow(`Changes detected in ${filename}, rebuilding...`), - ); - buildCSS(false).catch(console.error); - } - }); + fs.watch('src/css', { recursive: true }, (eventType, filename) => { + if (filename === 'styles.css') { + console.log( + chalk.yellow(`Changes detected in ${filename}, rebuilding...`), + ); + buildCSS(false).catch(console.error); + } }); - - // Initial build buildCSS().catch(console.error); console.log(chalk.yellow('Watching for CSS changes...')); } else { diff --git a/packages/canon/src/components/Avatar/Avatar.tsx b/packages/canon/src/components/Avatar/Avatar.tsx index 472bec39fb..4e899170de 100644 --- a/packages/canon/src/components/Avatar/Avatar.tsx +++ b/packages/canon/src/components/Avatar/Avatar.tsx @@ -18,28 +18,36 @@ import { forwardRef, ElementRef } from 'react'; import { Avatar as AvatarPrimitive } from '@base-ui-components/react/avatar'; import clsx from 'clsx'; import { AvatarProps } from './types'; +import { useStyles } from '../../hooks/useStyles'; /** @public */ export const Avatar = forwardRef< ElementRef, AvatarProps ->(({ className, src, name, size = 'medium', ...props }, ref) => ( - - - - {(name || '') - .split(' ') - .map(word => word[0]) - .join('') - .toLocaleUpperCase('en-US') - .slice(0, 2)} - - -)); +>((props, ref) => { + const { className, src, name, size = 'medium', ...rest } = props; + const { classNames } = useStyles('Avatar', { + size, + }); + + return ( + + + + {(name || '') + .split(' ') + .map(word => word[0]) + .join('') + .toLocaleUpperCase('en-US') + .slice(0, 2)} + + + ); +}); Avatar.displayName = AvatarPrimitive.Root.displayName; diff --git a/packages/canon/src/components/Box/Box.tsx b/packages/canon/src/components/Box/Box.tsx index 8718c77724..4273ee86f9 100644 --- a/packages/canon/src/components/Box/Box.tsx +++ b/packages/canon/src/components/Box/Box.tsx @@ -24,6 +24,7 @@ import { widthPropDefs } from '../../props/width.props'; import { heightPropDefs } from '../../props/height.props'; import { positionPropDefs } from '../../props/position.props'; import { displayPropDefs } from '../../props/display.props'; +import { useStyles } from '../../hooks/useStyles'; /** @public */ export const Box = forwardRef((props, ref) => { @@ -38,11 +39,12 @@ export const Box = forwardRef((props, ref) => { ...boxPropDefs, }; + const { classNames } = useStyles('Box'); const { className, style } = extractProps(props, propDefs); return createElement(props.as || 'div', { ref, - className: clsx('canon-Box', className), + className: clsx(classNames.root, className), style, children, }); diff --git a/packages/canon/src/components/Button/Button.stories.tsx b/packages/canon/src/components/Button/Button.stories.tsx index 2d79da7e29..e020ebb64d 100644 --- a/packages/canon/src/components/Button/Button.stories.tsx +++ b/packages/canon/src/components/Button/Button.stories.tsx @@ -18,7 +18,6 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Button } from './Button'; import { Flex } from '../Flex'; import { Text } from '../Text'; -import { ButtonProps } from './types'; import { Icon } from '../Icon'; const meta = { @@ -119,30 +118,18 @@ export const FullWidth: Story = { }; export const Disabled: Story = { - args: { - children: 'Button', - disabled: true, - }, - render: args => ( + render: () => ( - + ), }; -export const AsLink: Story = { - args: { - children: 'I am a link', - }, - render: args => ( - @@ -194,31 +179,27 @@ export const Playground: Story = { iconStart={} iconEnd={} style={{ width: '200px' }} - variant={variant as ButtonProps['variant']} - size={size as ButtonProps['size']} + variant={variant} + size={size} > Button - diff --git a/packages/canon/src/components/Button/Button.tsx b/packages/canon/src/components/Button/Button.tsx index 9775f3f629..40879e51ed 100644 --- a/packages/canon/src/components/Button/Button.tsx +++ b/packages/canon/src/components/Button/Button.tsx @@ -14,69 +14,43 @@ * limitations under the License. */ -import { forwardRef, useRef } from 'react'; import clsx from 'clsx'; -import { useResponsiveValue } from '../../hooks/useResponsiveValue'; -import { useRender } from '@base-ui-components/react/use-render'; - +import { forwardRef, Ref } from 'react'; +import { Button as RAButton } from 'react-aria-components'; import type { ButtonProps } from './types'; +import { useStyles } from '../../hooks/useStyles'; /** @public */ -export const Button = forwardRef( - (props: ButtonProps, ref) => { +export const Button = forwardRef( + (props: ButtonProps, ref: Ref) => { const { size = 'small', variant = 'primary', iconStart, iconEnd, children, - render = + {icon} + ); }, ); -export default IconButton; +ButtonIcon.displayName = 'ButtonIcon'; diff --git a/packages/canon/src/components/Button/index.tsx b/packages/canon/src/components/ButtonIcon/index.tsx similarity index 76% rename from packages/canon/src/components/Button/index.tsx rename to packages/canon/src/components/ButtonIcon/index.tsx index 9051f1145e..686fd844e8 100644 --- a/packages/canon/src/components/Button/index.tsx +++ b/packages/canon/src/components/ButtonIcon/index.tsx @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { Button } from './Button'; -export type { ButtonProps } from './types'; -export { buttonPropDefs } from './Button.props'; -export type { ButtonOwnProps } from './Button.props'; + +export * from './ButtonIcon'; +export * from './types'; diff --git a/packages/canon/src/components/ButtonIcon/styles.css b/packages/canon/src/components/ButtonIcon/styles.css new file mode 100644 index 0000000000..27c96e696e --- /dev/null +++ b/packages/canon/src/components/ButtonIcon/styles.css @@ -0,0 +1,30 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.canon-ButtonIcon { + align-items: center; + justify-content: center; +} + +.canon-ButtonIcon[data-size='small'] { + padding: 0; + width: 2rem; +} + +.canon-ButtonIcon[data-size='medium'] { + padding: 0; + width: 2.5rem; +} diff --git a/packages/canon/src/components/IconButton/types.ts b/packages/canon/src/components/ButtonIcon/types.ts similarity index 56% rename from packages/canon/src/components/IconButton/types.ts rename to packages/canon/src/components/ButtonIcon/types.ts index ece1950d1b..7f8b845de4 100644 --- a/packages/canon/src/components/IconButton/types.ts +++ b/packages/canon/src/components/ButtonIcon/types.ts @@ -14,30 +14,20 @@ * limitations under the License. */ -import type { IconButtonOwnProps } from './IconButton.props'; +import { Breakpoint } from '@backstage/canon'; import { ReactElement } from 'react'; +import { ButtonProps as RAButtonProps } from 'react-aria-components'; /** - * Properties for {@link IconButton} + * Properties for {@link ButtonIcon} * * @public */ -export interface IconButtonProps - extends Omit, 'children'> { - /** - * The size of the button - * @defaultValue 'medium' - */ - size?: IconButtonOwnProps['size']; - - /** - * The visual variant of the button - * @defaultValue 'primary' - */ - variant?: IconButtonOwnProps['variant']; - - /** - * Icon to display in the button - */ - icon: ReactElement; +export interface ButtonIconProps extends RAButtonProps { + size?: 'small' | 'medium' | Partial>; + variant?: + | 'primary' + | 'secondary' + | Partial>; + icon?: ReactElement; } diff --git a/packages/canon/src/components/ButtonLink/ButtonLink.stories.tsx b/packages/canon/src/components/ButtonLink/ButtonLink.stories.tsx new file mode 100644 index 0000000000..abf6e9d278 --- /dev/null +++ b/packages/canon/src/components/ButtonLink/ButtonLink.stories.tsx @@ -0,0 +1,212 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Meta, StoryObj } from '@storybook/react'; +import { ButtonLink } from './ButtonLink'; +import { Flex } from '../Flex'; +import { Text } from '../Text'; +import { Icon } from '../Icon'; + +const meta = { + title: 'Components/ButtonLink', + component: ButtonLink, + argTypes: { + size: { + control: 'select', + options: ['small', 'medium'], + }, + variant: { + control: 'select', + options: ['primary', 'secondary'], + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: 'Button', + }, +}; + +export const Variants: Story = { + render: () => ( + + } + variant="primary" + href="https://canon.backstage.io" + target="_blank" + > + Button + + } + variant="secondary" + href="https://canon.backstage.io" + target="_blank" + > + Button + + + ), +}; + +export const Sizes: Story = { + args: { + children: 'Button', + }, + render: () => ( + + }> + Small + + }> + Medium + + + ), +}; + +export const WithIcons: Story = { + args: { + children: 'Button', + }, + render: args => ( + + } /> + } /> + } + iconEnd={} + /> + + ), +}; + +export const FullWidth: Story = { + args: { + children: 'Button', + }, + render: args => ( + + } /> + } /> + } + iconEnd={} + /> + + ), +}; + +export const Disabled: Story = { + render: () => ( + + + Primary + + + Secondary + + + ), +}; + +export const Responsive: Story = { + args: { + children: 'Button', + variant: { + initial: 'primary', + sm: 'secondary', + }, + size: { + xs: 'small', + sm: 'medium', + }, + }, +}; + +const variants = ['primary', 'secondary'] as const; +const sizes = ['small', 'medium'] as const; + +export const Playground: Story = { + args: { + children: 'Button', + }, + render: () => ( + + {variants.map(variant => ( + + {variant} + {sizes.map(size => ( + + + Button + + } + variant={variant} + size={size} + > + Button + + } + variant={variant} + size={size} + > + Button + + } + iconEnd={} + style={{ width: '200px' }} + variant={variant} + size={size} + > + Button + + + Button + + } + variant={variant} + size={size} + isDisabled + > + Button + + } + variant={variant} + size={size} + isDisabled + > + Button + + + ))} + + ))} + + ), +}; diff --git a/packages/canon/src/components/ButtonLink/ButtonLink.tsx b/packages/canon/src/components/ButtonLink/ButtonLink.tsx new file mode 100644 index 0000000000..153643a530 --- /dev/null +++ b/packages/canon/src/components/ButtonLink/ButtonLink.tsx @@ -0,0 +1,58 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import clsx from 'clsx'; +import { forwardRef, Ref } from 'react'; +import { Link as RALink } from 'react-aria-components'; +import type { ButtonLinkProps } from './types'; +import { useStyles } from '../../hooks/useStyles'; + +/** @public */ +export const ButtonLink = forwardRef( + (props: ButtonLinkProps, ref: Ref) => { + const { + size = 'small', + variant = 'primary', + iconStart, + iconEnd, + children, + className, + ...rest + } = props; + + const { classNames, dataAttributes } = useStyles('Button', { + size, + variant, + }); + + const { classNames: classNamesButtonLink } = useStyles('ButtonLink'); + + return ( + + {iconStart} + {children} + {iconEnd} + + ); + }, +); + +ButtonLink.displayName = 'ButtonLink'; diff --git a/packages/canon/src/components/ButtonLink/index.ts b/packages/canon/src/components/ButtonLink/index.ts new file mode 100644 index 0000000000..bbfc696c67 --- /dev/null +++ b/packages/canon/src/components/ButtonLink/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './ButtonLink'; +export * from './types'; diff --git a/packages/canon/src/components/ButtonLink/types.ts b/packages/canon/src/components/ButtonLink/types.ts new file mode 100644 index 0000000000..f6524fbe62 --- /dev/null +++ b/packages/canon/src/components/ButtonLink/types.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Breakpoint } from '@backstage/canon'; +import { ReactElement, ReactNode } from 'react'; +import { LinkProps as RALinkProps } from 'react-aria-components'; + +/** + * Properties for {@link ButtonLink} + * + * @public + */ +export interface ButtonLinkProps extends RALinkProps { + size?: 'small' | 'medium' | Partial>; + variant?: + | 'primary' + | 'secondary' + | Partial>; + iconStart?: ReactElement; + iconEnd?: ReactElement; + children?: ReactNode; +} diff --git a/packages/canon/src/components/Checkbox/Checkbox.tsx b/packages/canon/src/components/Checkbox/Checkbox.tsx index 5bf6520891..aaa6fb105b 100644 --- a/packages/canon/src/components/Checkbox/Checkbox.tsx +++ b/packages/canon/src/components/Checkbox/Checkbox.tsx @@ -18,6 +18,7 @@ import { forwardRef } from 'react'; import { Checkbox as CheckboxPrimitive } from '@base-ui-components/react/checkbox'; import { Icon } from '@backstage/canon'; import type { CheckboxProps } from './types'; +import { useStyles } from '../../hooks/useStyles'; import clsx from 'clsx'; /** @public */ @@ -35,10 +36,12 @@ export const Checkbox = forwardRef( style, } = props; + const { classNames } = useStyles('Checkbox'); + const checkboxElement = ( ( value={value} style={style} > - + ); return label ? ( -
{`${fromCount} - ${toCount} of ${rowCount}`} - table?.previousPage()} - disabled={!table?.getCanPreviousPage()} + isDisabled={!table?.getCanPreviousPage()} icon={} /> - table?.nextPage()} - disabled={!table?.getCanNextPage()} + isDisabled={!table?.getCanNextPage()} icon={} />
diff --git a/packages/canon/src/components/FieldError/FieldError.stories.tsx b/packages/canon/src/components/FieldError/FieldError.stories.tsx new file mode 100644 index 0000000000..39714d16d2 --- /dev/null +++ b/packages/canon/src/components/FieldError/FieldError.stories.tsx @@ -0,0 +1,87 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Meta, StoryObj } from '@storybook/react'; +import { TextField, Input, Form } from 'react-aria-components'; +import { FieldError } from './FieldError'; + +const meta = { + title: 'Forms/FieldError', + component: FieldError, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +// Show error with server validation using Form component +export const WithServerValidation: Story = { + render: () => ( +
+ + + + +
+ ), +}; + +// Show error using children +export const WithCustomMessage: Story = { + render: () => ( + + + This is a custom error message. + + ), +}; + +// Show error with render prop function +export const WithRenderProp: Story = { + render: () => ( + 'This field is invalid'} + style={{ + display: 'flex', + flexDirection: 'column', + alignItems: 'flex-start', + }} + > + + + {({ validationErrors }) => + validationErrors.length > 0 ? validationErrors[0] : 'Field is invalid' + } + + + ), +}; diff --git a/packages/canon/src/components/FieldError/FieldError.styles.css b/packages/canon/src/components/FieldError/FieldError.styles.css new file mode 100644 index 0000000000..816eb3c35e --- /dev/null +++ b/packages/canon/src/components/FieldError/FieldError.styles.css @@ -0,0 +1,6 @@ +.canon-FieldError { + color: var(--canon-fg-danger); + font-size: var(--canon-font-size-2); + font-weight: var(--canon-font-weight-regular); + margin-top: var(--canon-space-2); +} diff --git a/packages/canon/src/components/Button/Button.props.ts b/packages/canon/src/components/FieldError/FieldError.tsx similarity index 51% rename from packages/canon/src/components/Button/Button.props.ts rename to packages/canon/src/components/FieldError/FieldError.tsx index e363360afa..b90d7b3bd3 100644 --- a/packages/canon/src/components/Button/Button.props.ts +++ b/packages/canon/src/components/FieldError/FieldError.tsx @@ -14,28 +14,26 @@ * limitations under the License. */ -import type { PropDef, GetPropDefTypes } from '../../props/prop-def'; +import { forwardRef } from 'react'; +import { + FieldError as AriaFieldError, + type FieldErrorProps, +} from 'react-aria-components'; +import clsx from 'clsx'; /** @public */ -export const buttonPropDefs = { - variant: { - type: 'enum', - values: ['primary', 'secondary'], - className: 'canon-Button--variant', - default: 'primary', - responsive: true, - }, - size: { - type: 'enum', - values: ['small', 'medium'], - className: 'canon-Button--size', - default: 'medium', - responsive: true, - }, -} satisfies { - variant: PropDef<'primary' | 'secondary'>; - size: PropDef<'small' | 'medium'>; -}; +export const FieldError = forwardRef( + (props: FieldErrorProps, ref) => { + const { className, ...rest } = props; -/** @public */ -export type ButtonOwnProps = GetPropDefTypes; + return ( + + ); + }, +); + +FieldError.displayName = 'FieldError'; diff --git a/packages/canon/src/components/FieldError/index.ts b/packages/canon/src/components/FieldError/index.ts new file mode 100644 index 0000000000..5b61f83ace --- /dev/null +++ b/packages/canon/src/components/FieldError/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './FieldError'; diff --git a/packages/canon/src/components/FieldLabel/FieldLabel.stories.tsx b/packages/canon/src/components/FieldLabel/FieldLabel.stories.tsx new file mode 100644 index 0000000000..a82639eca0 --- /dev/null +++ b/packages/canon/src/components/FieldLabel/FieldLabel.stories.tsx @@ -0,0 +1,65 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Meta, StoryObj } from '@storybook/react'; +import { FieldLabel } from './FieldLabel'; + +const meta = { + title: 'Forms/FieldLabel', + component: FieldLabel, + argTypes: { + label: { + control: 'text', + }, + secondaryLabel: { + control: 'text', + }, + description: { + control: 'text', + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + label: 'Label', + }, +}; + +export const WithSecondaryLabel: Story = { + args: { + ...Default.args, + secondaryLabel: 'Secondary Label', + }, +}; + +export const WithDescription: Story = { + args: { + ...Default.args, + description: 'Description', + }, +}; + +export const WithAllFields: Story = { + args: { + ...Default.args, + secondaryLabel: 'Secondary Label', + description: 'Description', + }, +}; diff --git a/packages/canon/src/components/FieldLabel/FieldLabel.styles.css b/packages/canon/src/components/FieldLabel/FieldLabel.styles.css new file mode 100644 index 0000000000..f668d2fd45 --- /dev/null +++ b/packages/canon/src/components/FieldLabel/FieldLabel.styles.css @@ -0,0 +1,27 @@ +.canon-FieldLabelWrapper { + display: flex; + flex-direction: column; + margin-bottom: var(--canon-space-3); + gap: var(--canon-space-1); +} + +.canon-FieldLabel { + color: var(--canon-fg-primary); + margin-right: auto; + cursor: pointer; + font-weight: var(--canon-font-weight-regular); + font-size: var(--canon-font-size-2); +} + +.canon-FieldSecondaryLabel { + color: var(--canon-fg-secondary); + font-weight: var(--canon-font-weight-regular); + margin-left: var(--canon-space-1); +} + +.canon-FieldDescription { + font-weight: var(--canon-font-weight-regular); + font-size: var(--canon-font-size-2); + color: var(--canon-fg-secondary); + margin: 0; +} diff --git a/packages/canon/src/components/FieldLabel/FieldLabel.tsx b/packages/canon/src/components/FieldLabel/FieldLabel.tsx new file mode 100644 index 0000000000..df0735389a --- /dev/null +++ b/packages/canon/src/components/FieldLabel/FieldLabel.tsx @@ -0,0 +1,50 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Label } from 'react-aria-components'; +import { forwardRef } from 'react'; +import type { FieldLabelProps } from './types'; +import { useStyles } from '../../hooks/useStyles'; + +/** @public */ +export const FieldLabel = forwardRef( + (props: FieldLabelProps, ref) => { + const { label, secondaryLabel, description, htmlFor, id, ...rest } = props; + + const { classNames } = useStyles('FieldLabel'); + + if (!label) return null; + + return ( +
+ {label && ( + + )} + {description && ( +
{description}
+ )} +
+ ); + }, +); + +FieldLabel.displayName = 'FieldLabel'; diff --git a/packages/canon/src/components/FieldLabel/index.ts b/packages/canon/src/components/FieldLabel/index.ts new file mode 100644 index 0000000000..b9cebb1bf7 --- /dev/null +++ b/packages/canon/src/components/FieldLabel/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './FieldLabel'; +export * from './types'; diff --git a/packages/canon/src/components/FieldLabel/types.ts b/packages/canon/src/components/FieldLabel/types.ts new file mode 100644 index 0000000000..dc4e444133 --- /dev/null +++ b/packages/canon/src/components/FieldLabel/types.ts @@ -0,0 +1,43 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @public */ +export interface FieldLabelProps { + /** + * The label of the text field + */ + label?: string | null; + + /** + * The secondary label of the text field + */ + secondaryLabel?: string | null; + + /** + * The description of the text field + */ + description?: string | null; + + /** + * The HTML for attribute of the text field + */ + htmlFor?: string; + + /** + * The id of the text field + */ + id?: string; +} diff --git a/packages/canon/src/components/Flex/Flex.tsx b/packages/canon/src/components/Flex/Flex.tsx index a53e0d28f4..ded4fffffa 100644 --- a/packages/canon/src/components/Flex/Flex.tsx +++ b/packages/canon/src/components/Flex/Flex.tsx @@ -21,6 +21,7 @@ import { flexPropDefs } from './Flex.props'; import { extractProps } from '../../utils/extractProps'; import { gapPropDefs } from '../../props/gap-props'; import { spacingPropDefs } from '../../props/spacing.props'; +import { useStyles } from '../../hooks/useStyles'; /** @public */ export const Flex = forwardRef((props, ref) => { @@ -30,11 +31,12 @@ export const Flex = forwardRef((props, ref) => { ...spacingPropDefs, }; + const { classNames } = useStyles('Flex'); const { className, style } = extractProps(props, propDefs); return createElement('div', { ref, - className: clsx('canon-Flex', className), + className: clsx(classNames.root, className), style, children: props.children, }); diff --git a/packages/canon/src/components/Grid/Grid.tsx b/packages/canon/src/components/Grid/Grid.tsx index 7bb5486a2d..27257c8972 100644 --- a/packages/canon/src/components/Grid/Grid.tsx +++ b/packages/canon/src/components/Grid/Grid.tsx @@ -21,6 +21,7 @@ import { gridItemPropDefs, gridPropDefs } from './Grid.props'; import clsx from 'clsx'; import type { GridItemProps, GridProps } from './types'; import { spacingPropDefs } from '../../props/spacing.props'; +import { useStyles } from '../../hooks/useStyles'; const GridRoot = forwardRef((props, ref) => { const propDefs = { @@ -29,11 +30,13 @@ const GridRoot = forwardRef((props, ref) => { ...spacingPropDefs, }; + const { classNames } = useStyles('Grid'); + const { className, style } = extractProps(props, propDefs); return createElement('div', { ref, - className: clsx('canon-Grid', className), + className: clsx(classNames.root, className), style, children: props.children, }); @@ -44,11 +47,12 @@ const GridItem = forwardRef((props, ref) => { ...gridItemPropDefs, }; + const { classNames } = useStyles('Grid'); const { className, style } = extractProps(props, propDefs); return createElement('div', { ref, - className: clsx('canon-GridItem', className), + className: clsx(classNames.item, className), style, children: props.children, }); diff --git a/packages/canon/src/components/Heading/Heading.stories.tsx b/packages/canon/src/components/Heading/Heading.stories.tsx index 956118ddeb..2e608c09a3 100644 --- a/packages/canon/src/components/Heading/Heading.stories.tsx +++ b/packages/canon/src/components/Heading/Heading.stories.tsx @@ -96,7 +96,7 @@ export const WrappedInLink: Story = { export const CustomRender: Story = { args: { ...Default.args, - render:

, + as: 'h4', }, }; diff --git a/packages/canon/src/components/Heading/Heading.tsx b/packages/canon/src/components/Heading/Heading.tsx index 6ea2fe006b..3d173e98ac 100644 --- a/packages/canon/src/components/Heading/Heading.tsx +++ b/packages/canon/src/components/Heading/Heading.tsx @@ -14,42 +14,50 @@ * limitations under the License. */ -import { forwardRef, useRef } from 'react'; +import { forwardRef } from 'react'; import clsx from 'clsx'; -import { useResponsiveValue } from '../../hooks/useResponsiveValue'; -import { useRender } from '@base-ui-components/react/use-render'; +import type { ElementType } from 'react'; import type { HeadingProps } from './types'; +import { useStyles } from '../../hooks/useStyles'; + +function HeadingComponent( + { + as, + variant = 'title1', + color = 'primary', + truncate, + className, + style, + ...restProps + }: HeadingProps, + ref: React.Ref, +) { + const Component = as || 'h1'; + + const { classNames, dataAttributes } = useStyles('Heading', { + variant, + color, + }); + + return ( + + ); +} + +HeadingComponent.displayName = 'Heading'; /** @public */ -export const Heading = forwardRef( - (props, ref) => { - const { - variant = 'title1', - color = 'primary', - truncate, - className, - render =

, - ...restProps - } = props; +export const Heading = forwardRef(HeadingComponent) as < + T extends ElementType = 'h1', +>( + props: HeadingProps & { ref?: React.Ref }, +) => React.ReactElement | null; - const responsiveVariant = useResponsiveValue(variant); - const responsiveColor = useResponsiveValue(color); - const internalRef = useRef(null); - - const { renderElement } = useRender({ - render, - props: { - className: clsx('canon-Heading', className), - ['data-variant']: responsiveVariant, - ['data-color']: responsiveColor, - ['data-truncate']: truncate, - ...restProps, - }, - refs: [ref, internalRef], - }); - - return renderElement(); - }, -); - -Heading.displayName = 'Heading'; +(Heading as any).displayName = 'Heading'; diff --git a/packages/canon/src/components/Heading/index.ts b/packages/canon/src/components/Heading/index.ts index 69b7c3c1a0..ca9845b122 100644 --- a/packages/canon/src/components/Heading/index.ts +++ b/packages/canon/src/components/Heading/index.ts @@ -14,5 +14,5 @@ * limitations under the License. */ -export { Heading } from './Heading'; -export type { HeadingProps } from './types'; +export * from './Heading'; +export * from './types'; diff --git a/packages/canon/src/components/Heading/types.ts b/packages/canon/src/components/Heading/types.ts index 7a94bdf2a4..f2317462c2 100644 --- a/packages/canon/src/components/Heading/types.ts +++ b/packages/canon/src/components/Heading/types.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { Breakpoint } from '../../types'; -import type { useRender } from '@base-ui-components/react/use-render'; +import type { ElementType, ComponentPropsWithRef } from 'react'; +import type { Breakpoint } from '../../types'; /** @public */ -export interface HeadingProps - extends Omit, 'color'> { +export type HeadingOwnProps = { + as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; variant?: | 'display' | 'title1' @@ -40,4 +40,8 @@ export interface HeadingProps truncate?: boolean; className?: string; style?: React.CSSProperties; -} +}; + +/** @public */ +export type HeadingProps = HeadingOwnProps & + Omit, keyof HeadingOwnProps>; diff --git a/packages/canon/src/components/Icon/Icon.tsx b/packages/canon/src/components/Icon/Icon.tsx index 8877420a84..85b476339d 100644 --- a/packages/canon/src/components/Icon/Icon.tsx +++ b/packages/canon/src/components/Icon/Icon.tsx @@ -18,6 +18,7 @@ import { ComponentType } from 'react'; import { useIcons } from './context'; import type { IconProps } from './types'; import clsx from 'clsx'; +import { useStyles } from '../../hooks/useStyles'; /** @public */ export const Icon = (props: IconProps) => { @@ -31,9 +32,11 @@ export const Icon = (props: IconProps) => { return null; } + const { classNames } = useStyles('Icon'); + return ( ((props, ref) => { ...restProps } = props; - const responsiveVariant = useResponsiveValue(variant); - const responsiveWeight = useResponsiveValue(weight); + const { classNames, dataAttributes } = useStyles('Link', { variant, weight }); const internalRef = useRef(null); const { renderElement } = useRender({ render, props: { - className: clsx('canon-Link', className), - ['data-variant']: responsiveVariant, - ['data-weight']: responsiveWeight, + className: clsx(classNames.root, className), + ...dataAttributes, ...restProps, }, refs: [ref, internalRef], diff --git a/packages/canon/src/components/Menu/Menu.styles.css b/packages/canon/src/components/Menu/Menu.styles.css index 07d257f57f..7ccaa7a634 100644 --- a/packages/canon/src/components/Menu/Menu.styles.css +++ b/packages/canon/src/components/Menu/Menu.styles.css @@ -93,6 +93,7 @@ .canon-SubmenuComboboxSearch { padding-inline: var(--canon-space-3); + width: 100%; height: 32px; border: none; border-bottom: 1px solid var(--canon-border); diff --git a/packages/canon/src/components/Menu/Menu.tsx b/packages/canon/src/components/Menu/Menu.tsx index 123b01b283..9c475fdf5f 100644 --- a/packages/canon/src/components/Menu/Menu.tsx +++ b/packages/canon/src/components/Menu/Menu.tsx @@ -20,190 +20,255 @@ import clsx from 'clsx'; import { MenuComponent } from './types'; import { Combobox } from './Combobox'; import { Icon } from '../Icon'; +import { useStyles } from '../../hooks/useStyles'; const MenuTrigger = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuTrigger.displayName = MenuPrimitive.Trigger.displayName; const MenuBackdrop = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuBackdrop.displayName = MenuPrimitive.Backdrop.displayName; const MenuPositioner = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuPositioner.displayName = MenuPrimitive.Positioner.displayName; const MenuPopup = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuPopup.displayName = MenuPrimitive.Popup.displayName; const MenuArrow = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuArrow.displayName = MenuPrimitive.Arrow.displayName; const MenuItem = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuItem.displayName = MenuPrimitive.Item.displayName; const MenuGroup = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuGroup.displayName = MenuPrimitive.Group.displayName; const MenuGroupLabel = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuGroupLabel.displayName = MenuPrimitive.GroupLabel.displayName; const MenuRadioGroup = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuRadioGroup.displayName = MenuPrimitive.RadioGroup.displayName; const MenuRadioItem = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuRadioItem.displayName = MenuPrimitive.RadioItem.displayName; const MenuRadioItemIndicator = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuRadioItemIndicator.displayName = MenuPrimitive.RadioItemIndicator.displayName; const MenuCheckboxItem = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuCheckboxItem.displayName = MenuPrimitive.CheckboxItem.displayName; const MenuCheckboxItemIndicator = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuCheckboxItemIndicator.displayName = MenuPrimitive.CheckboxItemIndicator.displayName; const MenuSubmenuTrigger = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - -
{children}
- -
-)); +>(({ className, children, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + +
{children}
+ +
+ ); +}); MenuSubmenuTrigger.displayName = MenuPrimitive.SubmenuTrigger.displayName; const MenuSeparator = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('Menu'); + + return ( + + ); +}); MenuSeparator.displayName = MenuPrimitive.Separator.displayName; /** @public */ diff --git a/packages/canon/src/components/RadioGroup/RadioGroup.stories.tsx b/packages/canon/src/components/RadioGroup/RadioGroup.stories.tsx new file mode 100644 index 0000000000..4f28e04bfc --- /dev/null +++ b/packages/canon/src/components/RadioGroup/RadioGroup.stories.tsx @@ -0,0 +1,147 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Meta, StoryObj } from '@storybook/react'; +import { RadioGroup, Radio } from './RadioGroup'; + +const meta = { + title: 'Forms/RadioGroup', + component: RadioGroup, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + label: 'What is your favorite pokemon?', + }, + render: args => ( + + Bulbasaur + Charmander + Squirtle + + ), +}; + +export const Horizontal: Story = { + args: { + ...Default.args, + orientation: 'horizontal', + }, + render: args => ( + + Bulbasaur + Charmander + Squirtle + + ), +}; + +export const Disabled: Story = { + args: { + ...Default.args, + isDisabled: true, + }, + render: args => ( + + Bulbasaur + Charmander + Squirtle + + ), +}; + +export const DisabledSingle: Story = { + args: { + ...Default.args, + }, + render: args => ( + + Bulbasaur + + Charmander + + Squirtle + + ), +}; + +export const DisabledAndSelected: Story = { + args: { + ...Default.args, + value: 'charmander', + }, + render: args => ( + + Bulbasaur + + Charmander + + Squirtle + + ), +}; + +export const Invalid: Story = { + args: { + ...Default.args, + name: 'pokemon', + isInvalid: true, + }, + render: args => ( + + Bulbasaur + + Charmander + + Squirtle + + ), +}; + +export const Validation: Story = { + args: { + ...Default.args, + name: 'pokemon', + defaultValue: 'charmander', + validationBehavior: 'aria', + validate: value => (value === 'charmander' ? 'Nice try!' : null), + }, + render: args => ( + + Bulbasaur + Charmander + Squirtle + + ), +}; + +export const ReadOnly: Story = { + args: { + ...Default.args, + isReadOnly: true, + defaultValue: 'charmander', + }, + render: args => ( + + Bulbasaur + Charmander + Squirtle + + ), +}; diff --git a/packages/canon/src/components/RadioGroup/RadioGroup.styles.css b/packages/canon/src/components/RadioGroup/RadioGroup.styles.css new file mode 100644 index 0000000000..a712f9031f --- /dev/null +++ b/packages/canon/src/components/RadioGroup/RadioGroup.styles.css @@ -0,0 +1,95 @@ +.canon-RadioGroup { + display: flex; + flex-direction: column; + color: var(--canon-fg-primary); +} + +.canon-RadioGroup[data-orientation='horizontal'] .canon-RadioGroupContent { + flex-direction: row; + gap: var(--canon-space-4); +} + +.canon-RadioGroupContent { + display: flex; + flex-direction: column; + gap: var(--canon-space-2); +} + +.canon-Radio { + display: flex; + /* This is needed so the HiddenInput is positioned correctly */ + position: relative; + align-items: center; + gap: var(--canon-space-2); + font-size: var(--canon-font-size-2); + color: var(--canon-fg-primary); + forced-color-adjust: none; + + &:before { + content: ''; + display: block; + width: 1rem; + height: 1rem; + box-sizing: border-box; + border: 0.125rem solid var(--canon-border); + background: var(--canon-gray-1); + border-radius: var(--canon-radius-full); + transition: all 200ms; + } + + &[data-pressed]:before { + border-color: var(--canon-border); + } + + &[data-selected] { + &:before { + border-color: var(--canon-bg-solid); + border-width: 0.25rem; + } + + &[data-pressed]:before { + border-color: var(--canon-bg-solid); + } + } + + &[data-focus-visible]:before { + outline: 2px solid var(--canon-ring); + outline-offset: 2px; + } + + &[data-disabled] { + cursor: not-allowed; + color: var(--canon-fg-disabled); + + &:before { + border-color: var(--canon-border-disabled); + background: var(--canon-bg-disabled); + } + + &[data-selected]:before { + border-color: var(--canon-border-disabled); + } + } + + &[data-invalid]:before { + border-color: var(--canon-border-danger); + } + + &[data-invalid][data-selected]:before { + border-color: var(--canon-border-danger); + } + + /* Ensure disabled state prevails over invalid state */ + &[data-disabled][data-invalid] { + color: var(--canon-fg-disabled); + + &:before { + border-color: var(--canon-border-disabled); + background: var(--canon-bg-disabled); + } + + &[data-selected]:before { + border-color: var(--canon-border-disabled); + } + } +} diff --git a/packages/canon/src/components/RadioGroup/RadioGroup.tsx b/packages/canon/src/components/RadioGroup/RadioGroup.tsx new file mode 100644 index 0000000000..4363477c1a --- /dev/null +++ b/packages/canon/src/components/RadioGroup/RadioGroup.tsx @@ -0,0 +1,95 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { forwardRef, useEffect } from 'react'; +import { + RadioGroup as AriaRadioGroup, + Radio as AriaRadio, +} from 'react-aria-components'; +import clsx from 'clsx'; +import { FieldLabel } from '../FieldLabel'; +import { FieldError } from '../FieldError'; +import { useStyles } from '../../hooks/useStyles'; + +import type { RadioGroupProps, RadioProps } from './types'; + +/** @public */ +export const RadioGroup = forwardRef( + (props, ref) => { + const { + className, + label, + secondaryLabel, + description, + isRequired, + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledBy, + children, + ...rest + } = props; + + const { classNames } = useStyles('RadioGroup'); + + useEffect(() => { + if (!label && !ariaLabel && !ariaLabelledBy) { + console.warn( + 'RadioGroup requires either a visible label, aria-label, or aria-labelledby for accessibility', + ); + } + }, [label, ariaLabel, ariaLabelledBy]); + + // If a secondary label is provided, use it. Otherwise, use 'Required' if the field is required. + const secondaryLabelText = + secondaryLabel || (isRequired ? 'Required' : null); + + return ( + + +
{children}
+ +
+ ); + }, +); + +RadioGroup.displayName = 'RadioGroup'; + +/** @public */ +export const Radio = forwardRef((props, ref) => { + const { className, ...rest } = props; + + const { classNames } = useStyles('RadioGroup'); + + return ( + + ); +}); + +RadioGroup.displayName = 'RadioGroup'; diff --git a/packages/canon/src/components/RadioGroup/index.ts b/packages/canon/src/components/RadioGroup/index.ts new file mode 100644 index 0000000000..fd9572f667 --- /dev/null +++ b/packages/canon/src/components/RadioGroup/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './RadioGroup'; +export * from './types'; diff --git a/packages/canon/src/components/RadioGroup/types.ts b/packages/canon/src/components/RadioGroup/types.ts new file mode 100644 index 0000000000..029ef4baf9 --- /dev/null +++ b/packages/canon/src/components/RadioGroup/types.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + RadioGroupProps as AriaRadioGroupProps, + RadioProps as AriaRadioProps, +} from 'react-aria-components'; +import type { FieldLabelProps } from '../FieldLabel/types'; +import { ReactNode } from 'react'; + +/** @public */ +export interface RadioGroupProps + extends Omit, + Omit { + children?: ReactNode; +} + +/** @public */ +export interface RadioProps extends AriaRadioProps {} diff --git a/packages/canon/src/components/ScrollArea/ScrollArea.tsx b/packages/canon/src/components/ScrollArea/ScrollArea.tsx index e96e76c29b..44722fbd12 100644 --- a/packages/canon/src/components/ScrollArea/ScrollArea.tsx +++ b/packages/canon/src/components/ScrollArea/ScrollArea.tsx @@ -17,53 +17,70 @@ import { forwardRef } from 'react'; import { ScrollArea as ScrollAreaPrimitive } from '@base-ui-components/react/scroll-area'; import clsx from 'clsx'; +import { useStyles } from '../../hooks/useStyles'; const ScrollAreaRoot = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('ScrollArea'); + + return ( + + ); +}); ScrollAreaRoot.displayName = ScrollAreaPrimitive.Root.displayName; const ScrollAreaViewport = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('ScrollArea'); + + return ( + + ); +}); ScrollAreaViewport.displayName = ScrollAreaPrimitive.Viewport.displayName; const ScrollAreaScrollbar = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('ScrollArea'); + + return ( + + ); +}); ScrollAreaScrollbar.displayName = ScrollAreaPrimitive.Scrollbar.displayName; const ScrollAreaThumb = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); +>(({ className, ...props }, ref) => { + const { classNames } = useStyles('ScrollArea'); + + return ( + + ); +}); ScrollAreaThumb.displayName = ScrollAreaPrimitive.Thumb.displayName; /** @public */ diff --git a/packages/canon/src/components/SearchField/SearchField.stories.tsx b/packages/canon/src/components/SearchField/SearchField.stories.tsx new file mode 100644 index 0000000000..5b267f585d --- /dev/null +++ b/packages/canon/src/components/SearchField/SearchField.stories.tsx @@ -0,0 +1,154 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Meta, StoryObj } from '@storybook/react'; +import { SearchField } from './SearchField'; +import { Form } from 'react-aria-components'; +import { Icon } from '../Icon'; +import { Flex } from '../Flex'; +import { FieldLabel } from '../FieldLabel'; + +const meta = { + title: 'Forms/SearchField', + component: SearchField, + argTypes: { + isRequired: { + control: 'boolean', + }, + icon: { + control: 'object', + }, + placeholder: { + control: 'text', + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + name: 'url', + style: { + maxWidth: '300px', + }, + }, +}; + +export const Sizes: Story = { + args: { + ...Default.args, + }, + render: args => ( + + + + + ), +}; + +export const DefaultValue: Story = { + args: { + ...Default.args, + defaultValue: 'https://example.com', + }, +}; + +export const WithLabel: Story = { + args: { + ...Default.args, + label: 'Label', + }, +}; + +export const WithDescription: Story = { + args: { + ...WithLabel.args, + description: 'Description', + }, +}; + +export const Required: Story = { + args: { + ...WithLabel.args, + isRequired: true, + }, +}; + +export const Disabled: Story = { + args: { + ...Default.args, + isDisabled: true, + }, +}; + +export const WithIcon: Story = { + args: { + ...Default.args, + }, + render: args => ( + } + /> + ), +}; + +export const DisabledWithIcon: Story = { + args: { + ...WithIcon.args, + isDisabled: true, + }, +}; + +export const ShowError: Story = { + args: { + ...WithLabel.args, + }, + render: args => ( +
+ + + ), +}; + +export const Validation: Story = { + args: { + ...WithLabel.args, + validate: value => (value === 'admin' ? 'Nice try!' : null), + }, +}; + +export const CustomField: Story = { + render: () => ( + <> + + + + ), +}; diff --git a/packages/canon/src/components/SearchField/SearchField.styles.css b/packages/canon/src/components/SearchField/SearchField.styles.css new file mode 100644 index 0000000000..70bd20e2ac --- /dev/null +++ b/packages/canon/src/components/SearchField/SearchField.styles.css @@ -0,0 +1,55 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.canon-SearchField[data-empty] .canon-InputClear { + display: none; +} + +.canon-InputClear { + position: absolute; + right: 0; + top: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; + background-color: transparent; + border: none; + padding: 0; + margin: 0; + cursor: pointer; + color: var(--canon-fg-secondary); + transition: color 0.2s ease-in-out; +} + +.canon-InputClear:hover { + color: var(--canon-fg-primary); +} + +.canon-InputClear[data-size='small'] { + width: 2rem; + height: 2rem; +} + +.canon-InputClear[data-size='medium'] { + width: 2.5rem; + height: 2.5rem; +} + +.canon-InputClear svg { + width: 1rem; + height: 1rem; +} diff --git a/packages/canon/src/components/SearchField/SearchField.tsx b/packages/canon/src/components/SearchField/SearchField.tsx new file mode 100644 index 0000000000..ff54439309 --- /dev/null +++ b/packages/canon/src/components/SearchField/SearchField.tsx @@ -0,0 +1,120 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { forwardRef, useEffect } from 'react'; +import { + Input, + SearchField as AriaSearchField, + Button, +} from 'react-aria-components'; +import clsx from 'clsx'; +import { FieldLabel } from '../FieldLabel'; +import { FieldError } from '../FieldError'; +import { RiSearch2Line, RiCloseCircleLine } from '@remixicon/react'; +import { useStyles } from '../../hooks/useStyles'; + +import type { SearchFieldProps } from './types'; + +/** @public */ +export const SearchField = forwardRef( + (props, ref) => { + const { + className, + icon, + size = 'small', + label, + secondaryLabel, + description, + isRequired, + placeholder = 'Search', + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledBy, + ...rest + } = props; + + useEffect(() => { + if (!label && !ariaLabel && !ariaLabelledBy) { + console.warn( + 'SearchField requires either a visible label, aria-label, or aria-labelledby for accessibility', + ); + } + }, [label, ariaLabel, ariaLabelledBy]); + + const { classNames: textFieldClassNames, dataAttributes } = useStyles( + 'TextField', + { + size, + }, + ); + + const { classNames: searchFieldClassNames } = useStyles('SearchField', { + size, + }); + + // If a secondary label is provided, use it. Otherwise, use 'Required' if the field is required. + const secondaryLabelText = + secondaryLabel || (isRequired ? 'Required' : null); + + return ( + + +
+ {icon !== false && ( + + )} + + +
+ +
+ ); + }, +); + +SearchField.displayName = 'searchField'; diff --git a/packages/canon/src/components/SearchField/index.ts b/packages/canon/src/components/SearchField/index.ts new file mode 100644 index 0000000000..288c3fe44a --- /dev/null +++ b/packages/canon/src/components/SearchField/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './SearchField'; +export * from './types'; diff --git a/packages/canon/src/components/SearchField/types.ts b/packages/canon/src/components/SearchField/types.ts new file mode 100644 index 0000000000..b561292684 --- /dev/null +++ b/packages/canon/src/components/SearchField/types.ts @@ -0,0 +1,41 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { SearchFieldProps as AriaSearchFieldProps } from 'react-aria-components'; +import { ReactNode } from 'react'; +import type { Breakpoint } from '../../types'; +import type { FieldLabelProps } from '../FieldLabel/types'; + +/** @public */ +export interface SearchFieldProps + extends AriaSearchFieldProps, + Omit { + /** + * An icon to render before the input + */ + icon?: ReactNode | false; + + /** + * The size of the text field + * @defaultValue 'medium' + */ + size?: 'small' | 'medium' | Partial>; + + /** + * The placeholder text for the input + */ + placeholder?: string; +} diff --git a/packages/canon/src/components/Select/Select.tsx b/packages/canon/src/components/Select/Select.tsx index 3f25ac26de..7bedc5e2a0 100644 --- a/packages/canon/src/components/Select/Select.tsx +++ b/packages/canon/src/components/Select/Select.tsx @@ -20,7 +20,7 @@ import { Icon } from '../Icon'; import clsx from 'clsx'; import './Select.styles.css'; import { SelectProps } from './types'; -import { useResponsiveValue } from '../../hooks/useResponsiveValue'; +import { useStyles } from '../../hooks/useStyles'; /** @public */ export const Select = forwardRef((props, ref) => { @@ -37,8 +37,9 @@ export const Select = forwardRef((props, ref) => { ...rest } = props; - // Get the responsive value for the variant - const responsiveSize = useResponsiveValue(size); + const { classNames, dataAttributes } = useStyles('Select', { + size, + }); // Generate unique IDs for accessibility const selectId = useId(); @@ -58,7 +59,7 @@ export const Select = forwardRef((props, ref) => { ); return ( -
+
{label && (