@backstage/core-components 0.14.9-next.1 → 0.14.10-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @backstage/core-components
2
2
 
3
+ ## 0.14.10-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 678971a: Move the `Link` component to the `RoutedTabs` instead of the `HeaderTabs` component
8
+ - Updated dependencies
9
+ - @backstage/config@1.2.0
10
+ - @backstage/core-plugin-api@1.9.3
11
+ - @backstage/errors@1.2.4
12
+ - @backstage/theme@0.5.6
13
+ - @backstage/version-bridge@1.0.8
14
+
15
+ ## 0.14.9
16
+
17
+ ### Patch Changes
18
+
19
+ - d4ffdbb: Fixed bug where `<Select>` component with empty string as placeholder gave an error
20
+ - 99d672d: Modified the `Select` component to take in a `data-testid` parameter ensuring backwards compatibility with default value corresponding to previously hardcoded `data-testid` of "select".
21
+ - Updated dependencies
22
+ - @backstage/config@1.2.0
23
+ - @backstage/core-plugin-api@1.9.3
24
+ - @backstage/errors@1.2.4
25
+ - @backstage/theme@0.5.6
26
+ - @backstage/version-bridge@1.0.8
27
+
3
28
  ## 0.14.9-next.1
4
29
 
5
30
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/core-components__alpha",
3
- "version": "0.14.9-next.1",
3
+ "version": "0.14.10-next.0",
4
4
  "main": "../dist/alpha.esm.js",
5
5
  "module": "../dist/alpha.esm.js",
6
6
  "types": "../dist/alpha.d.ts"
@@ -1,8 +1,9 @@
1
1
  import React__default, { useMemo } from 'react';
2
2
  import { Helmet } from 'react-helmet';
3
- import { useNavigate, useParams, useRoutes, matchRoutes } from 'react-router-dom';
3
+ import { useParams, useRoutes, matchRoutes } from 'react-router-dom';
4
4
  import { Content } from '../../layout/Content/Content.esm.js';
5
5
  import { HeaderTabs } from '../../layout/HeaderTabs/HeaderTabs.esm.js';
6
+ import { Link } from '../Link/Link.esm.js';
6
7
 
7
8
  function useSelectedSubRoute(subRoutes) {
8
9
  const params = useParams();
@@ -32,30 +33,26 @@ function useSelectedSubRoute(subRoutes) {
32
33
  }
33
34
  function RoutedTabs(props) {
34
35
  const { routes } = props;
35
- const navigate = useNavigate();
36
36
  const { index, route, element } = useSelectedSubRoute(routes);
37
37
  const headerTabs = useMemo(
38
- () => routes.map((t) => ({
39
- id: t.path,
40
- label: t.title,
41
- tabProps: t.tabProps
42
- })),
38
+ () => routes.map((t) => {
39
+ const { path, title, tabProps } = t;
40
+ let to = path;
41
+ to = to.replace(/\/\*$/, "");
42
+ to = to.replace(/^\//, "");
43
+ return {
44
+ id: path,
45
+ label: title,
46
+ tabProps: {
47
+ component: Link,
48
+ to,
49
+ ...tabProps
50
+ }
51
+ };
52
+ }),
43
53
  [routes]
44
54
  );
45
- const onTabChange = (tabIndex) => {
46
- let { path } = routes[tabIndex];
47
- path = path.replace(/\/\*$/, "");
48
- path = path.replace(/^\//, "");
49
- navigate(path);
50
- };
51
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
52
- HeaderTabs,
53
- {
54
- tabs: headerTabs,
55
- selectedIndex: index,
56
- onChange: onTabChange
57
- }
58
- ), /* @__PURE__ */ React__default.createElement(Content, null, /* @__PURE__ */ React__default.createElement(Helmet, { title: route?.title }), element));
55
+ return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(HeaderTabs, { tabs: headerTabs, selectedIndex: index }), /* @__PURE__ */ React__default.createElement(Content, null, /* @__PURE__ */ React__default.createElement(Helmet, { title: route?.title }), element));
59
56
  }
60
57
 
61
58
  export { RoutedTabs, useSelectedSubRoute };
@@ -1 +1 @@
1
- {"version":3,"file":"RoutedTabs.esm.js","sources":["../../../src/components/TabbedLayout/RoutedTabs.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useMemo } from 'react';\nimport { Helmet } from 'react-helmet';\nimport {\n matchRoutes,\n useNavigate,\n useParams,\n useRoutes,\n} from 'react-router-dom';\nimport { Content } from '../../layout/Content';\nimport { HeaderTabs } from '../../layout/HeaderTabs';\nimport { SubRoute } from './types';\n\nexport function useSelectedSubRoute(subRoutes: SubRoute[]): {\n index: number;\n route?: SubRoute;\n element?: JSX.Element;\n} {\n const params = useParams();\n\n const routes = subRoutes.map(({ path, children }) => ({\n caseSensitive: false,\n path: `${path}/*`,\n element: children,\n }));\n\n // TODO: remove once react-router updated\n const sortedRoutes = routes.sort((a, b) =>\n // remove \"/*\" symbols from path end before comparing\n b.path.replace(/\\/\\*$/, '').localeCompare(a.path.replace(/\\/\\*$/, '')),\n );\n\n const element = useRoutes(sortedRoutes) ?? subRoutes[0]?.children;\n\n // TODO(Rugvip): Once we only support v6 stable we can always prefix\n // This avoids having a double / prefix for react-router v6 beta, which in turn breaks\n // the tab highlighting when using relative paths for the tabs.\n let currentRoute = params['*'] ?? '';\n if (!currentRoute.startsWith('/')) {\n currentRoute = `/${currentRoute}`;\n }\n\n const [matchedRoute] = matchRoutes(sortedRoutes, currentRoute) ?? [];\n const foundIndex = matchedRoute\n ? subRoutes.findIndex(t => `${t.path}/*` === matchedRoute.route.path)\n : 0;\n\n return {\n index: foundIndex === -1 ? 0 : foundIndex,\n element,\n route: subRoutes[foundIndex] ?? subRoutes[0],\n };\n}\n\nexport function RoutedTabs(props: { routes: SubRoute[] }) {\n const { routes } = props;\n const navigate = useNavigate();\n const { index, route, element } = useSelectedSubRoute(routes);\n const headerTabs = useMemo(\n () =>\n routes.map(t => ({\n id: t.path,\n label: t.title,\n tabProps: t.tabProps,\n })),\n [routes],\n );\n\n const onTabChange = (tabIndex: number) => {\n let { path } = routes[tabIndex];\n // Remove trailing /*\n path = path.replace(/\\/\\*$/, '');\n // And remove leading / for relative navigation\n path = path.replace(/^\\//, '');\n // Note! route resolves relative to the position in the React tree,\n // not relative to current location\n navigate(path);\n };\n return (\n <>\n <HeaderTabs\n tabs={headerTabs}\n selectedIndex={index}\n onChange={onTabChange}\n />\n <Content>\n <Helmet title={route?.title} />\n {element}\n </Content>\n </>\n );\n}\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"RoutedTabs.esm.js","sources":["../../../src/components/TabbedLayout/RoutedTabs.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { useMemo } from 'react';\nimport { Helmet } from 'react-helmet';\nimport { matchRoutes, useParams, useRoutes } from 'react-router-dom';\nimport { Content } from '../../layout/Content';\nimport { HeaderTabs } from '../../layout/HeaderTabs';\nimport { SubRoute } from './types';\nimport { Link } from '../Link';\n\nexport function useSelectedSubRoute(subRoutes: SubRoute[]): {\n index: number;\n route?: SubRoute;\n element?: JSX.Element;\n} {\n const params = useParams();\n\n const routes = subRoutes.map(({ path, children }) => ({\n caseSensitive: false,\n path: `${path}/*`,\n element: children,\n }));\n\n // TODO: remove once react-router updated\n const sortedRoutes = routes.sort((a, b) =>\n // remove \"/*\" symbols from path end before comparing\n b.path.replace(/\\/\\*$/, '').localeCompare(a.path.replace(/\\/\\*$/, '')),\n );\n\n const element = useRoutes(sortedRoutes) ?? subRoutes[0]?.children;\n\n // TODO(Rugvip): Once we only support v6 stable we can always prefix\n // This avoids having a double / prefix for react-router v6 beta, which in turn breaks\n // the tab highlighting when using relative paths for the tabs.\n let currentRoute = params['*'] ?? '';\n if (!currentRoute.startsWith('/')) {\n currentRoute = `/${currentRoute}`;\n }\n\n const [matchedRoute] = matchRoutes(sortedRoutes, currentRoute) ?? [];\n const foundIndex = matchedRoute\n ? subRoutes.findIndex(t => `${t.path}/*` === matchedRoute.route.path)\n : 0;\n\n return {\n index: foundIndex === -1 ? 0 : foundIndex,\n element,\n route: subRoutes[foundIndex] ?? subRoutes[0],\n };\n}\n\nexport function RoutedTabs(props: { routes: SubRoute[] }) {\n const { routes } = props;\n\n const { index, route, element } = useSelectedSubRoute(routes);\n const headerTabs = useMemo(\n () =>\n routes.map(t => {\n const { path, title, tabProps } = t;\n let to = path;\n // Remove trailing /*\n to = to.replace(/\\/\\*$/, '');\n // And remove leading / for relative navigation\n to = to.replace(/^\\//, '');\n return {\n id: path,\n label: title,\n tabProps: {\n component: Link,\n to,\n ...tabProps,\n },\n };\n }),\n [routes],\n );\n\n return (\n <>\n <HeaderTabs tabs={headerTabs} selectedIndex={index} />\n <Content>\n <Helmet title={route?.title} />\n {element}\n </Content>\n </>\n );\n}\n"],"names":["React"],"mappings":"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"}
@@ -3,7 +3,6 @@ import { makeStyles } from '@material-ui/core/styles';
3
3
  import TabUI from '@material-ui/core/Tab';
4
4
  import Tabs from '@material-ui/core/Tabs';
5
5
  import React__default, { useState, useCallback, useEffect } from 'react';
6
- import { Link } from '../../components/Link/Link.esm.js';
7
6
 
8
7
  const useStyles = makeStyles(
9
8
  (theme) => ({
@@ -50,9 +49,6 @@ function HeaderTabs(props) {
50
49
  setSelectedTab(selectedIndex);
51
50
  }
52
51
  }, [selectedIndex]);
53
- function removeLeadingSlash(path) {
54
- return path.replace(/^\//, "");
55
- }
56
52
  return /* @__PURE__ */ React__default.createElement(Box, { className: styles.tabsWrapper }, /* @__PURE__ */ React__default.createElement(
57
53
  Tabs,
58
54
  {
@@ -70,8 +66,6 @@ function HeaderTabs(props) {
70
66
  "data-testid": `header-tab-${index}`,
71
67
  label: tab.label,
72
68
  key: tab.id,
73
- component: Link,
74
- to: removeLeadingSlash(tab.id),
75
69
  value: index,
76
70
  className: styles.defaultTab,
77
71
  classes: { selected: styles.selected, root: styles.tabRoot },
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderTabs.esm.js","sources":["../../../src/layout/HeaderTabs/HeaderTabs.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport TabUI, { TabProps } from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport React, { useCallback, useEffect, useState } from 'react';\nimport { Link } from '../../components/Link';\n\n// TODO(blam): Remove this implementation when the Tabs are ready\n// This is just a temporary solution to implementing tabs for now\n\n/** @public */\nexport type HeaderTabsClassKey =\n | 'tabsWrapper'\n | 'defaultTab'\n | 'selected'\n | 'tabRoot';\n\nconst useStyles = makeStyles(\n theme => ({\n tabsWrapper: {\n gridArea: 'pageSubheader',\n backgroundColor: theme.palette.background.paper,\n paddingLeft: theme.spacing(3),\n minWidth: 0,\n },\n defaultTab: {\n ...theme.typography.caption,\n padding: theme.spacing(3, 3),\n textTransform: 'uppercase',\n fontWeight: theme.typography.fontWeightBold,\n color: theme.palette.text.secondary,\n },\n selected: {\n color: theme.palette.text.primary,\n },\n tabRoot: {\n '&:hover': {\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n },\n },\n }),\n { name: 'BackstageHeaderTabs' },\n);\n\nexport type Tab = {\n id: string;\n label: string;\n tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>;\n};\n\ntype HeaderTabsProps = {\n tabs: Tab[];\n onChange?: (index: number) => void;\n selectedIndex?: number;\n};\n\n/**\n * Horizontal Tabs component\n *\n * @public\n *\n */\nexport function HeaderTabs(props: HeaderTabsProps) {\n const { tabs, onChange, selectedIndex } = props;\n const [selectedTab, setSelectedTab] = useState<number>(selectedIndex ?? 0);\n const styles = useStyles();\n\n const handleChange = useCallback(\n (_: React.ChangeEvent<{}>, index: number) => {\n if (selectedIndex === undefined) {\n setSelectedTab(index);\n }\n if (onChange) onChange(index);\n },\n [selectedIndex, onChange],\n );\n\n useEffect(() => {\n if (selectedIndex !== undefined) {\n setSelectedTab(selectedIndex);\n }\n }, [selectedIndex]);\n function removeLeadingSlash(path: string) {\n return path.replace(/^\\//, '');\n }\n return (\n <Box className={styles.tabsWrapper}>\n <Tabs\n indicatorColor=\"primary\"\n textColor=\"inherit\"\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label=\"tabs\"\n onChange={handleChange}\n value={selectedTab}\n >\n {tabs.map((tab, index) => (\n <TabUI\n data-testid={`header-tab-${index}`}\n label={tab.label}\n key={tab.id}\n component={Link}\n to={removeLeadingSlash(tab.id)}\n value={index}\n className={styles.defaultTab}\n classes={{ selected: styles.selected, root: styles.tabRoot }}\n {...tab.tabProps}\n />\n ))}\n </Tabs>\n </Box>\n );\n}\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"HeaderTabs.esm.js","sources":["../../../src/layout/HeaderTabs/HeaderTabs.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport TabUI, { TabProps } from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport React, { useCallback, useEffect, useState } from 'react';\n\n// TODO(blam): Remove this implementation when the Tabs are ready\n// This is just a temporary solution to implementing tabs for now\n\n/** @public */\nexport type HeaderTabsClassKey =\n | 'tabsWrapper'\n | 'defaultTab'\n | 'selected'\n | 'tabRoot';\n\nconst useStyles = makeStyles(\n theme => ({\n tabsWrapper: {\n gridArea: 'pageSubheader',\n backgroundColor: theme.palette.background.paper,\n paddingLeft: theme.spacing(3),\n minWidth: 0,\n },\n defaultTab: {\n ...theme.typography.caption,\n padding: theme.spacing(3, 3),\n textTransform: 'uppercase',\n fontWeight: theme.typography.fontWeightBold,\n color: theme.palette.text.secondary,\n },\n selected: {\n color: theme.palette.text.primary,\n },\n tabRoot: {\n '&:hover': {\n backgroundColor: theme.palette.background.default,\n color: theme.palette.text.primary,\n },\n },\n }),\n { name: 'BackstageHeaderTabs' },\n);\n\nexport type Tab = {\n id: string;\n label: string;\n tabProps?: TabProps<React.ElementType, { component?: React.ElementType }>;\n};\n\ntype HeaderTabsProps = {\n tabs: Tab[];\n onChange?: (index: number) => void;\n selectedIndex?: number;\n};\n\n/**\n * Horizontal Tabs component\n *\n * @public\n *\n */\nexport function HeaderTabs(props: HeaderTabsProps) {\n const { tabs, onChange, selectedIndex } = props;\n const [selectedTab, setSelectedTab] = useState<number>(selectedIndex ?? 0);\n const styles = useStyles();\n\n const handleChange = useCallback(\n (_: React.ChangeEvent<{}>, index: number) => {\n if (selectedIndex === undefined) {\n setSelectedTab(index);\n }\n if (onChange) onChange(index);\n },\n [selectedIndex, onChange],\n );\n\n useEffect(() => {\n if (selectedIndex !== undefined) {\n setSelectedTab(selectedIndex);\n }\n }, [selectedIndex]);\n\n return (\n <Box className={styles.tabsWrapper}>\n <Tabs\n indicatorColor=\"primary\"\n textColor=\"inherit\"\n variant=\"scrollable\"\n scrollButtons=\"auto\"\n aria-label=\"tabs\"\n onChange={handleChange}\n value={selectedTab}\n >\n {tabs.map((tab, index) => (\n <TabUI\n data-testid={`header-tab-${index}`}\n label={tab.label}\n key={tab.id}\n value={index}\n className={styles.defaultTab}\n classes={{ selected: styles.selected, root: styles.tabRoot }}\n {...tab.tabProps}\n />\n ))}\n </Tabs>\n </Box>\n );\n}\n"],"names":["React"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/core-components",
3
3
  "description": "Core components used by Backstage plugins and apps",
4
- "version": "0.14.9-next.1",
4
+ "version": "0.14.10-next.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -94,10 +94,10 @@
94
94
  "zod": "^3.22.4"
95
95
  },
96
96
  "devDependencies": {
97
- "@backstage/app-defaults": "^1.5.8-next.2",
98
- "@backstage/cli": "^0.26.11-next.1",
99
- "@backstage/core-app-api": "^1.13.1-next.1",
100
- "@backstage/test-utils": "^1.5.8-next.1",
97
+ "@backstage/app-defaults": "^1.5.9-next.0",
98
+ "@backstage/cli": "^0.27.0-next.0",
99
+ "@backstage/core-app-api": "^1.14.1-next.0",
100
+ "@backstage/test-utils": "^1.5.9-next.0",
101
101
  "@testing-library/dom": "^10.0.0",
102
102
  "@testing-library/jest-dom": "^6.0.0",
103
103
  "@testing-library/react": "^15.0.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/core-components__testutils",
3
- "version": "0.14.9-next.1",
3
+ "version": "0.14.10-next.0",
4
4
  "main": "../dist/testUtils.esm.js",
5
5
  "module": "../dist/testUtils.esm.js",
6
6
  "types": "../dist/testUtils.d.ts"