@backstage/core-components 0.18.14-next.1 → 0.18.14

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,31 @@
1
1
  # @backstage/core-components
2
2
 
3
+ ## 0.18.14
4
+
5
+ ### Patch Changes
6
+
7
+ - b80a9f3: Added an `onCopyLog` prop to the `LogViewer` component that renders a copy button in the toolbar, allowing users to copy all log content to the clipboard.
8
+ - 736d84e: Use locale-insensitive Unicode casing for consistent string handling across environments.
9
+ - a15bac8: Added an optional `variant` prop to `CopyTextButton` to allow configuring its visual style (`primary`, `secondary`, or `tertiary`).
10
+ - c0ebaa7: chore(deps): bump `js-yaml` from 4.3.1 to 4.3.2
11
+ - bfb6497: Fixed `CopyTextButton` showing its tooltip on hover/focus instead of only after the user clicks to copy the text.
12
+ - 279fdf6: Declared the DOM Testing Library dependency required by React Testing Library.
13
+ - f2b5407: Updated dependency `react-idle-timer` to `5.7.3`.
14
+ - d9a949e: Added support for rendering custom link elements inside `HeaderIconLinkRow`.
15
+ - Updated dependencies
16
+ - @backstage/ui@0.18.0
17
+ - @backstage/config@1.3.9
18
+ - @backstage/core-plugin-api@1.12.10
19
+
20
+ ## 0.18.14-next.2
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies
25
+ - @backstage/config@1.3.9-next.0
26
+ - @backstage/ui@0.18.0-next.2
27
+ - @backstage/core-plugin-api@1.12.10-next.1
28
+
3
29
  ## 0.18.14-next.1
4
30
 
5
31
  ### Patch Changes
@@ -13,7 +13,8 @@ function CopyTextButton(props) {
13
13
  text,
14
14
  tooltipDelay = 1e3,
15
15
  tooltipText = t("copyTextButton.tooltipText"),
16
- "aria-label": ariaLabel = "Copy text"
16
+ "aria-label": ariaLabel = "Copy text",
17
+ variant
17
18
  } = props;
18
19
  const errorApi = useApi(errorApiRef);
19
20
  const [open, setOpen] = useState(false);
@@ -41,17 +42,27 @@ function CopyTextButton(props) {
41
42
  }
42
43
  };
43
44
  }, []);
44
- return /* @__PURE__ */ jsxs(TooltipTrigger, { isOpen: open, onOpenChange: setOpen, children: [
45
- /* @__PURE__ */ jsx(
46
- ButtonIcon,
47
- {
48
- icon: /* @__PURE__ */ jsx(CopyIcon, {}),
49
- onPress: handleCopyClick,
50
- "aria-label": ariaLabel
51
- }
52
- ),
53
- /* @__PURE__ */ jsx(Tooltip, { children: tooltipText })
54
- ] });
45
+ return /* @__PURE__ */ jsxs(
46
+ TooltipTrigger,
47
+ {
48
+ isOpen: open,
49
+ onOpenChange: (isOpen) => {
50
+ if (!isOpen) setOpen(false);
51
+ },
52
+ children: [
53
+ /* @__PURE__ */ jsx(
54
+ ButtonIcon,
55
+ {
56
+ icon: /* @__PURE__ */ jsx(CopyIcon, {}),
57
+ onPress: handleCopyClick,
58
+ "aria-label": ariaLabel,
59
+ variant
60
+ }
61
+ ),
62
+ /* @__PURE__ */ jsx(Tooltip, { children: tooltipText })
63
+ ]
64
+ }
65
+ );
55
66
  }
56
67
 
57
68
  export { CopyTextButton };
@@ -1 +1 @@
1
- {"version":3,"file":"CopyTextButton.esm.js","sources":["../../../src/components/CopyTextButton/CopyTextButton.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 */\n\nimport { errorApiRef, useApi } from '@backstage/core-plugin-api';\nimport { ButtonIcon, Tooltip, TooltipTrigger } from '@backstage/ui';\nimport CopyIcon from '@material-ui/icons/FileCopy';\nimport { useEffect, useRef, useState } from 'react';\nimport useCopyToClipboard from 'react-use/esm/useCopyToClipboard';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Properties for {@link CopyTextButton}\n *\n * @public\n */\nexport interface CopyTextButtonProps {\n /**\n * The text to be copied\n */\n text: string;\n /**\n * Number of milliseconds that the tooltip is shown\n *\n * @remarks\n *\n * Default: 1000\n */\n tooltipDelay?: number;\n /**\n * Text to show in the tooltip when user has clicked the button\n *\n * @remarks\n *\n * Default: \"Text copied to clipboard\"\n */\n tooltipText?: string;\n\n /**\n * Text to use as aria-label prop on the button\n *\n * @remarks\n *\n * Default: \"Copy text\"\n */\n 'aria-label'?: string;\n}\n\n/**\n * Copy text button with visual feedback\n *\n * @public\n * @remarks\n *\n * Visual feedback takes form of:\n * - a hover color\n * - click ripple\n * - Tooltip shown when user has clicked\n *\n * @example\n *\n * ```\n * <CopyTextButton\n * text=\"My text that I want to be copied to the clipboard\"\n * arial-label=\"Accessible label for this button\" />\n * ```\n */\nexport function CopyTextButton(props: CopyTextButtonProps) {\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const {\n text,\n tooltipDelay = 1000,\n tooltipText = t('copyTextButton.tooltipText'),\n 'aria-label': ariaLabel = 'Copy text',\n } = props;\n const errorApi = useApi(errorApiRef);\n const [open, setOpen] = useState(false);\n const [{ error }, copyToClipboard] = useCopyToClipboard();\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (error) {\n errorApi.post(error);\n }\n }, [error, errorApi]);\n\n const handleCopyClick = () => {\n // Clear any existing timeout to reset the timer on repeated clicks\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n setOpen(true);\n copyToClipboard(text);\n\n // Set new timeout to close tooltip\n timeoutRef.current = setTimeout(() => {\n setOpen(false);\n }, tooltipDelay);\n };\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return (\n <TooltipTrigger isOpen={open} onOpenChange={setOpen}>\n <ButtonIcon\n icon={<CopyIcon />}\n onPress={handleCopyClick}\n aria-label={ariaLabel}\n />\n <Tooltip>{tooltipText}</Tooltip>\n </TooltipTrigger>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AAgFO,SAAS,eAAe,KAAA,EAA4B;AACzD,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,4BAA4B,CAAA;AAC5D,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,YAAA,GAAe,GAAA;AAAA,IACf,WAAA,GAAc,EAAE,4BAA4B,CAAA;AAAA,IAC5C,cAAc,SAAA,GAAY;AAAA,GAC5B,GAAI,KAAA;AACJ,EAAA,MAAM,QAAA,GAAW,OAAO,WAAW,CAAA;AACnC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,CAAC,EAAE,KAAA,EAAM,EAAG,eAAe,IAAI,kBAAA,EAAmB;AACxD,EAAA,MAAM,UAAA,GAAa,OAA6C,IAAI,CAAA;AAEpE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,IACrB;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,QAAQ,CAAC,CAAA;AAEpB,EAAA,MAAM,kBAAkB,MAAM;AAE5B,IAAA,IAAI,WAAW,OAAA,EAAS;AACtB,MAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAAA,IACjC;AAEA,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,eAAA,CAAgB,IAAI,CAAA;AAGpB,IAAA,UAAA,CAAW,OAAA,GAAU,WAAW,MAAM;AACpC,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,GAAG,YAAY,CAAA;AAAA,EACjB,CAAA;AAGA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,WAAW,OAAA,EAAS;AACtB,QAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAAA,MACjC;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,uBACE,IAAA,CAAC,cAAA,EAAA,EAAe,MAAA,EAAQ,IAAA,EAAM,cAAc,OAAA,EAC1C,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,IAAA,sBAAO,QAAA,EAAA,EAAS,CAAA;AAAA,QAChB,OAAA,EAAS,eAAA;AAAA,QACT,YAAA,EAAY;AAAA;AAAA,KACd;AAAA,oBACA,GAAA,CAAC,WAAS,QAAA,EAAA,WAAA,EAAY;AAAA,GAAA,EACxB,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"CopyTextButton.esm.js","sources":["../../../src/components/CopyTextButton/CopyTextButton.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 */\n\nimport { errorApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n ButtonIcon,\n ButtonIconProps,\n Tooltip,\n TooltipTrigger,\n} from '@backstage/ui';\nimport CopyIcon from '@material-ui/icons/FileCopy';\nimport { useEffect, useRef, useState } from 'react';\nimport useCopyToClipboard from 'react-use/esm/useCopyToClipboard';\nimport { coreComponentsTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/**\n * Properties for {@link CopyTextButton}\n *\n * @public\n */\nexport interface CopyTextButtonProps {\n /**\n * The text to be copied\n */\n text: string;\n /**\n * Number of milliseconds that the tooltip is shown\n *\n * @remarks\n *\n * Default: 1000\n */\n tooltipDelay?: number;\n /**\n * Text to show in the tooltip when user has clicked the button\n *\n * @remarks\n *\n * Default: \"Text copied to clipboard\"\n */\n tooltipText?: string;\n\n /**\n * Text to use as aria-label prop on the button\n *\n * @remarks\n *\n * Default: \"Copy text\"\n */\n 'aria-label'?: string;\n\n /**\n * The visual variant of the button\n *\n * @remarks\n *\n * Default: \"primary\"\n */\n variant?: ButtonIconProps['variant'];\n}\n\n/**\n * Copy text button with visual feedback\n *\n * @public\n * @remarks\n *\n * Visual feedback takes form of:\n * - a hover color\n * - click ripple\n * - Tooltip shown when user has clicked\n *\n * @example\n *\n * ```\n * <CopyTextButton\n * text=\"My text that I want to be copied to the clipboard\"\n * arial-label=\"Accessible label for this button\" />\n * ```\n */\nexport function CopyTextButton(props: CopyTextButtonProps) {\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n const {\n text,\n tooltipDelay = 1000,\n tooltipText = t('copyTextButton.tooltipText'),\n 'aria-label': ariaLabel = 'Copy text',\n variant,\n } = props;\n const errorApi = useApi(errorApiRef);\n const [open, setOpen] = useState(false);\n const [{ error }, copyToClipboard] = useCopyToClipboard();\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (error) {\n errorApi.post(error);\n }\n }, [error, errorApi]);\n\n const handleCopyClick = () => {\n // Clear any existing timeout to reset the timer on repeated clicks\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n\n setOpen(true);\n copyToClipboard(text);\n\n // Set new timeout to close tooltip\n timeoutRef.current = setTimeout(() => {\n setOpen(false);\n }, tooltipDelay);\n };\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n return (\n <TooltipTrigger\n isOpen={open}\n onOpenChange={isOpen => {\n if (!isOpen) setOpen(false);\n }}\n >\n <ButtonIcon\n icon={<CopyIcon />}\n onPress={handleCopyClick}\n aria-label={ariaLabel}\n variant={variant}\n />\n <Tooltip>{tooltipText}</Tooltip>\n </TooltipTrigger>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;AA8FO,SAAS,eAAe,KAAA,EAA4B;AACzD,EAAA,MAAM,EAAE,CAAA,EAAE,GAAI,iBAAA,CAAkB,4BAA4B,CAAA;AAC5D,EAAA,MAAM;AAAA,IACJ,IAAA;AAAA,IACA,YAAA,GAAe,GAAA;AAAA,IACf,WAAA,GAAc,EAAE,4BAA4B,CAAA;AAAA,IAC5C,cAAc,SAAA,GAAY,WAAA;AAAA,IAC1B;AAAA,GACF,GAAI,KAAA;AACJ,EAAA,MAAM,QAAA,GAAW,OAAO,WAAW,CAAA;AACnC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,KAAK,CAAA;AACtC,EAAA,MAAM,CAAC,EAAE,KAAA,EAAM,EAAG,eAAe,IAAI,kBAAA,EAAmB;AACxD,EAAA,MAAM,UAAA,GAAa,OAA6C,IAAI,CAAA;AAEpE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AAAA,IACrB;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,EAAO,QAAQ,CAAC,CAAA;AAEpB,EAAA,MAAM,kBAAkB,MAAM;AAE5B,IAAA,IAAI,WAAW,OAAA,EAAS;AACtB,MAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAAA,IACjC;AAEA,IAAA,OAAA,CAAQ,IAAI,CAAA;AACZ,IAAA,eAAA,CAAgB,IAAI,CAAA;AAGpB,IAAA,UAAA,CAAW,OAAA,GAAU,WAAW,MAAM;AACpC,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,GAAG,YAAY,CAAA;AAAA,EACjB,CAAA;AAGA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,WAAW,OAAA,EAAS;AACtB,QAAA,YAAA,CAAa,WAAW,OAAO,CAAA;AAAA,MACjC;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,uBACE,IAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,MAAA,EAAQ,IAAA;AAAA,MACR,cAAc,CAAA,MAAA,KAAU;AACtB,QAAA,IAAI,CAAC,MAAA,EAAQ,OAAA,CAAQ,KAAK,CAAA;AAAA,MAC5B,CAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,IAAA,sBAAO,QAAA,EAAA,EAAS,CAAA;AAAA,YAChB,OAAA,EAAS,eAAA;AAAA,YACT,YAAA,EAAY,SAAA;AAAA,YACZ;AAAA;AAAA,SACF;AAAA,wBACA,GAAA,CAAC,WAAS,QAAA,EAAA,WAAA,EAAY;AAAA;AAAA;AAAA,GACxB;AAEJ;;;;"}
@@ -1,4 +1,4 @@
1
- import { jsx } from 'react/jsx-runtime';
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { makeStyles } from '@material-ui/core/styles';
3
3
  import { IconLinkVertical } from './IconLinkVertical.esm.js';
4
4
 
@@ -16,9 +16,12 @@ const useStyles = makeStyles(
16
16
  { name: "BackstageHeaderIconLinkRow" }
17
17
  );
18
18
  function HeaderIconLinkRow(props) {
19
- const { links } = props;
19
+ const { links, children } = props;
20
20
  const classes = useStyles();
21
- return /* @__PURE__ */ jsx("nav", { className: classes.links, children: links.map((link, index) => /* @__PURE__ */ jsx(IconLinkVertical, { ...link }, index + 1)) });
21
+ return /* @__PURE__ */ jsxs("nav", { className: classes.links, children: [
22
+ links.map((link, index) => /* @__PURE__ */ jsx(IconLinkVertical, { ...link }, index + 1)),
23
+ children
24
+ ] });
22
25
  }
23
26
 
24
27
  export { HeaderIconLinkRow };
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderIconLinkRow.esm.js","sources":["../../../src/components/HeaderIconLinkRow/HeaderIconLinkRow.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 { makeStyles } from '@material-ui/core/styles';\nimport { IconLinkVertical, IconLinkVerticalProps } from './IconLinkVertical';\n\n/** @public */\nexport type HeaderIconLinkRowClassKey = 'links';\n\nconst useStyles = makeStyles(\n theme => ({\n links: {\n margin: theme.spacing(2, 0),\n display: 'grid',\n gridAutoFlow: 'column',\n gridAutoColumns: 'min-content',\n gridGap: theme.spacing(3),\n wordBreak: 'keep-all',\n },\n }),\n { name: 'BackstageHeaderIconLinkRow' },\n);\n\ntype Props = {\n links: IconLinkVerticalProps[];\n};\n\n/**\n * HTML nav tag with links mapped inside\n *\n * @public\n *\n */\nexport function HeaderIconLinkRow(props: Props) {\n const { links } = props;\n const classes = useStyles();\n return (\n <nav className={classes.links}>\n {links.map((link, index) => (\n <IconLinkVertical key={index + 1} {...link} />\n ))}\n </nav>\n );\n}\n"],"names":[],"mappings":";;;;AAqBA,MAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAA,KAAA,MAAU;AAAA,IACR,KAAA,EAAO;AAAA,MACL,MAAA,EAAQ,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAA;AAAA,MAC1B,OAAA,EAAS,MAAA;AAAA,MACT,YAAA,EAAc,QAAA;AAAA,MACd,eAAA,EAAiB,aAAA;AAAA,MACjB,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,MACxB,SAAA,EAAW;AAAA;AACb,GACF,CAAA;AAAA,EACA,EAAE,MAAM,4BAAA;AACV,CAAA;AAYO,SAAS,kBAAkB,KAAA,EAAc;AAC9C,EAAA,MAAM,EAAE,OAAM,GAAI,KAAA;AAClB,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,2BACG,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,KAAA,EACrB,gBAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,yBACf,gBAAA,EAAA,EAAkC,GAAG,QAAf,KAAA,GAAQ,CAAa,CAC7C,CAAA,EACH,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"HeaderIconLinkRow.esm.js","sources":["../../../src/components/HeaderIconLinkRow/HeaderIconLinkRow.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 { makeStyles } from '@material-ui/core/styles';\nimport { ReactNode } from 'react';\nimport { IconLinkVertical, IconLinkVerticalProps } from './IconLinkVertical';\n\n/** @public */\nexport type HeaderIconLinkRowClassKey = 'links';\n\nconst useStyles = makeStyles(\n theme => ({\n links: {\n margin: theme.spacing(2, 0),\n display: 'grid',\n gridAutoFlow: 'column',\n gridAutoColumns: 'min-content',\n gridGap: theme.spacing(3),\n wordBreak: 'keep-all',\n },\n }),\n { name: 'BackstageHeaderIconLinkRow' },\n);\n\ntype Props = {\n links: IconLinkVerticalProps[];\n children?: ReactNode;\n};\n\n/**\n * HTML nav tag with links and optional custom link elements inside\n *\n * @public\n *\n */\nexport function HeaderIconLinkRow(props: Props) {\n const { links, children } = props;\n const classes = useStyles();\n return (\n <nav className={classes.links}>\n {links.map((link, index) => (\n <IconLinkVertical key={index + 1} {...link} />\n ))}\n {children}\n </nav>\n );\n}\n"],"names":[],"mappings":";;;;AAsBA,MAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAA,KAAA,MAAU;AAAA,IACR,KAAA,EAAO;AAAA,MACL,MAAA,EAAQ,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,CAAC,CAAA;AAAA,MAC1B,OAAA,EAAS,MAAA;AAAA,MACT,YAAA,EAAc,QAAA;AAAA,MACd,eAAA,EAAiB,aAAA;AAAA,MACjB,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,MACxB,SAAA,EAAW;AAAA;AACb,GACF,CAAA;AAAA,EACA,EAAE,MAAM,4BAAA;AACV,CAAA;AAaO,SAAS,kBAAkB,KAAA,EAAc;AAC9C,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAS,GAAI,KAAA;AAC5B,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,KAAA,EACrB,QAAA,EAAA;AAAA,IAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,qBAChB,GAAA,CAAC,oBAAkC,GAAG,IAAA,EAAA,EAAf,KAAA,GAAQ,CAAa,CAC7C,CAAA;AAAA,IACA;AAAA,GAAA,EACH,CAAA;AAEJ;;;;"}
@@ -40,7 +40,7 @@ class AnsiLine {
40
40
  constructor(lineNumber = 1, chunks = []) {
41
41
  this.lineNumber = lineNumber;
42
42
  this.chunks = chunks;
43
- this.text = chunks.map((c) => c.text).join("").toLocaleLowerCase("en-US");
43
+ this.text = chunks.map((c) => c.text).join("").toLowerCase();
44
44
  }
45
45
  lastChunk() {
46
46
  return this.chunks[this.chunks.length - 1];
@@ -48,7 +48,7 @@ class AnsiLine {
48
48
  replaceLastChunk(newChunks) {
49
49
  if (newChunks) {
50
50
  this.chunks.splice(this.chunks.length - 1, 1, ...newChunks);
51
- this.text = this.chunks.map((c) => c.text).join("").toLocaleLowerCase("en-US");
51
+ this.text = this.chunks.map((c) => c.text).join("").toLowerCase();
52
52
  }
53
53
  }
54
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AnsiProcessor.esm.js","sources":["../../../src/components/LogViewer/AnsiProcessor.ts"],"sourcesContent":["/*\n * Copyright 2021 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 */\n\nimport ansiRegexMaker from 'ansi-regex';\n\nconst ansiRegex = ansiRegexMaker();\nconst newlineRegex = /\\n\\r?/g;\n\n// A mapping of how each escape code changes the modifiers\nconst codeModifiers = Object.fromEntries(\n Object.entries({\n 1: m => ({ ...m, bold: true }),\n 3: m => ({ ...m, italic: true }),\n 4: m => ({ ...m, underline: true }),\n 22: ({ bold: _, ...m }) => m,\n 23: ({ italic: _, ...m }) => m,\n 24: ({ underline: _, ...m }) => m,\n 30: m => ({ ...m, foreground: 'black' }),\n 31: m => ({ ...m, foreground: 'red' }),\n 32: m => ({ ...m, foreground: 'green' }),\n 33: m => ({ ...m, foreground: 'yellow' }),\n 34: m => ({ ...m, foreground: 'blue' }),\n 35: m => ({ ...m, foreground: 'magenta' }),\n 36: m => ({ ...m, foreground: 'cyan' }),\n 37: m => ({ ...m, foreground: 'white' }),\n 39: ({ foreground: _, ...m }) => m,\n 90: m => ({ ...m, foreground: 'grey' }),\n 40: m => ({ ...m, background: 'black' }),\n 41: m => ({ ...m, background: 'red' }),\n 42: m => ({ ...m, background: 'green' }),\n 43: m => ({ ...m, background: 'yellow' }),\n 44: m => ({ ...m, background: 'blue' }),\n 45: m => ({ ...m, background: 'magenta' }),\n 46: m => ({ ...m, background: 'cyan' }),\n 47: m => ({ ...m, background: 'white' }),\n 49: ({ background: _, ...m }) => m,\n } as Record<string, (m: ChunkModifiers) => ChunkModifiers>).map(\n ([code, modifier]) => [`\\x1b[${code}m`, modifier],\n ),\n);\n\nexport type AnsiColor =\n | 'black'\n | 'red'\n | 'green'\n | 'yellow'\n | 'blue'\n | 'magenta'\n | 'cyan'\n | 'white'\n | 'grey';\n\nexport interface ChunkModifiers {\n foreground?: AnsiColor;\n background?: AnsiColor;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n}\n\nexport interface AnsiChunk {\n text: string;\n modifiers: ChunkModifiers;\n}\n\nexport class AnsiLine {\n text: string;\n readonly lineNumber: number;\n readonly chunks: AnsiChunk[];\n\n constructor(lineNumber: number = 1, chunks: AnsiChunk[] = []) {\n this.lineNumber = lineNumber;\n this.chunks = chunks;\n this.text = chunks\n .map(c => c.text)\n .join('')\n .toLocaleLowerCase('en-US');\n }\n\n lastChunk(): AnsiChunk | undefined {\n return this.chunks[this.chunks.length - 1];\n }\n\n replaceLastChunk(newChunks?: AnsiChunk[]) {\n if (newChunks) {\n this.chunks.splice(this.chunks.length - 1, 1, ...newChunks);\n this.text = this.chunks\n .map(c => c.text)\n .join('')\n .toLocaleLowerCase('en-US');\n }\n }\n}\n\nexport class AnsiProcessor {\n private text: string = '';\n private lines: AnsiLine[] = [];\n\n /**\n * Processes a chunk of text while keeping internal state that optimizes\n * subsequent processing that appends to the text.\n */\n process(text: string): AnsiLine[] {\n if (this.text === text) {\n return this.lines;\n }\n\n if (this.text && text.startsWith(this.text)) {\n const lastLineIndex = this.lines.length > 0 ? this.lines.length - 1 : 0;\n const lastLine = this.lines[lastLineIndex] ?? new AnsiLine();\n const lastChunk = lastLine.lastChunk();\n\n const newLines = this.processLines(\n (lastChunk?.text ?? '') + text.slice(this.text.length),\n lastChunk?.modifiers,\n lastLine?.lineNumber,\n );\n lastLine.replaceLastChunk(newLines[0]?.chunks);\n\n this.lines[lastLineIndex] = lastLine;\n this.lines = this.lines.concat(newLines.slice(1));\n } else {\n this.lines = this.processLines(text);\n }\n this.text = text;\n\n return this.lines;\n }\n\n // Split a chunk of text up into lines and process each line individually\n private processLines = (\n text: string,\n modifiers: ChunkModifiers = {},\n startingLineNumber: number = 1,\n ): AnsiLine[] => {\n const lines: AnsiLine[] = [];\n\n let currentModifiers = modifiers;\n let currentLineNumber = startingLineNumber;\n\n let prevIndex = 0;\n newlineRegex.lastIndex = 0;\n for (;;) {\n const match = newlineRegex.exec(text);\n if (!match) {\n const chunks = this.processText(\n text.slice(prevIndex),\n currentModifiers,\n );\n lines.push(new AnsiLine(currentLineNumber, chunks));\n return lines;\n }\n\n const line = text.slice(prevIndex, match.index);\n prevIndex = match.index + match[0].length;\n\n const chunks = this.processText(line, currentModifiers);\n lines.push(new AnsiLine(currentLineNumber, chunks));\n\n // Modifiers that are active in the last chunk are carried over to the next line\n currentModifiers =\n chunks[chunks.length - 1].modifiers ?? currentModifiers;\n currentLineNumber += 1;\n }\n };\n\n // Processing of a one individual text chunk\n private processText = (\n fullText: string,\n modifiers: ChunkModifiers,\n ): AnsiChunk[] => {\n const chunks: AnsiChunk[] = [];\n\n let currentModifiers = modifiers;\n\n let prevIndex = 0;\n ansiRegex.lastIndex = 0;\n for (;;) {\n const match = ansiRegex.exec(fullText);\n if (!match) {\n chunks.push({\n text: fullText.slice(prevIndex),\n modifiers: currentModifiers,\n });\n return chunks;\n }\n\n const text = fullText.slice(prevIndex, match.index);\n chunks.push({ text, modifiers: currentModifiers });\n\n // For every escape code that we encounter we keep track of where the\n // next chunk of text starts, and what modifiers it has\n prevIndex = match.index + match[0].length;\n currentModifiers = this.processCode(match[0], currentModifiers);\n }\n };\n\n private processCode = (\n code: string,\n modifiers: ChunkModifiers,\n ): ChunkModifiers => {\n return codeModifiers[code]?.(modifiers) ?? modifiers;\n };\n}\n"],"names":["chunks"],"mappings":"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"}
1
+ {"version":3,"file":"AnsiProcessor.esm.js","sources":["../../../src/components/LogViewer/AnsiProcessor.ts"],"sourcesContent":["/*\n * Copyright 2021 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 */\n\nimport ansiRegexMaker from 'ansi-regex';\n\nconst ansiRegex = ansiRegexMaker();\nconst newlineRegex = /\\n\\r?/g;\n\n// A mapping of how each escape code changes the modifiers\nconst codeModifiers = Object.fromEntries(\n Object.entries({\n 1: m => ({ ...m, bold: true }),\n 3: m => ({ ...m, italic: true }),\n 4: m => ({ ...m, underline: true }),\n 22: ({ bold: _, ...m }) => m,\n 23: ({ italic: _, ...m }) => m,\n 24: ({ underline: _, ...m }) => m,\n 30: m => ({ ...m, foreground: 'black' }),\n 31: m => ({ ...m, foreground: 'red' }),\n 32: m => ({ ...m, foreground: 'green' }),\n 33: m => ({ ...m, foreground: 'yellow' }),\n 34: m => ({ ...m, foreground: 'blue' }),\n 35: m => ({ ...m, foreground: 'magenta' }),\n 36: m => ({ ...m, foreground: 'cyan' }),\n 37: m => ({ ...m, foreground: 'white' }),\n 39: ({ foreground: _, ...m }) => m,\n 90: m => ({ ...m, foreground: 'grey' }),\n 40: m => ({ ...m, background: 'black' }),\n 41: m => ({ ...m, background: 'red' }),\n 42: m => ({ ...m, background: 'green' }),\n 43: m => ({ ...m, background: 'yellow' }),\n 44: m => ({ ...m, background: 'blue' }),\n 45: m => ({ ...m, background: 'magenta' }),\n 46: m => ({ ...m, background: 'cyan' }),\n 47: m => ({ ...m, background: 'white' }),\n 49: ({ background: _, ...m }) => m,\n } as Record<string, (m: ChunkModifiers) => ChunkModifiers>).map(\n ([code, modifier]) => [`\\x1b[${code}m`, modifier],\n ),\n);\n\nexport type AnsiColor =\n | 'black'\n | 'red'\n | 'green'\n | 'yellow'\n | 'blue'\n | 'magenta'\n | 'cyan'\n | 'white'\n | 'grey';\n\nexport interface ChunkModifiers {\n foreground?: AnsiColor;\n background?: AnsiColor;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n}\n\nexport interface AnsiChunk {\n text: string;\n modifiers: ChunkModifiers;\n}\n\nexport class AnsiLine {\n text: string;\n readonly lineNumber: number;\n readonly chunks: AnsiChunk[];\n\n constructor(lineNumber: number = 1, chunks: AnsiChunk[] = []) {\n this.lineNumber = lineNumber;\n this.chunks = chunks;\n this.text = chunks\n .map(c => c.text)\n .join('')\n .toLowerCase();\n }\n\n lastChunk(): AnsiChunk | undefined {\n return this.chunks[this.chunks.length - 1];\n }\n\n replaceLastChunk(newChunks?: AnsiChunk[]) {\n if (newChunks) {\n this.chunks.splice(this.chunks.length - 1, 1, ...newChunks);\n this.text = this.chunks\n .map(c => c.text)\n .join('')\n .toLowerCase();\n }\n }\n}\n\nexport class AnsiProcessor {\n private text: string = '';\n private lines: AnsiLine[] = [];\n\n /**\n * Processes a chunk of text while keeping internal state that optimizes\n * subsequent processing that appends to the text.\n */\n process(text: string): AnsiLine[] {\n if (this.text === text) {\n return this.lines;\n }\n\n if (this.text && text.startsWith(this.text)) {\n const lastLineIndex = this.lines.length > 0 ? this.lines.length - 1 : 0;\n const lastLine = this.lines[lastLineIndex] ?? new AnsiLine();\n const lastChunk = lastLine.lastChunk();\n\n const newLines = this.processLines(\n (lastChunk?.text ?? '') + text.slice(this.text.length),\n lastChunk?.modifiers,\n lastLine?.lineNumber,\n );\n lastLine.replaceLastChunk(newLines[0]?.chunks);\n\n this.lines[lastLineIndex] = lastLine;\n this.lines = this.lines.concat(newLines.slice(1));\n } else {\n this.lines = this.processLines(text);\n }\n this.text = text;\n\n return this.lines;\n }\n\n // Split a chunk of text up into lines and process each line individually\n private processLines = (\n text: string,\n modifiers: ChunkModifiers = {},\n startingLineNumber: number = 1,\n ): AnsiLine[] => {\n const lines: AnsiLine[] = [];\n\n let currentModifiers = modifiers;\n let currentLineNumber = startingLineNumber;\n\n let prevIndex = 0;\n newlineRegex.lastIndex = 0;\n for (;;) {\n const match = newlineRegex.exec(text);\n if (!match) {\n const chunks = this.processText(\n text.slice(prevIndex),\n currentModifiers,\n );\n lines.push(new AnsiLine(currentLineNumber, chunks));\n return lines;\n }\n\n const line = text.slice(prevIndex, match.index);\n prevIndex = match.index + match[0].length;\n\n const chunks = this.processText(line, currentModifiers);\n lines.push(new AnsiLine(currentLineNumber, chunks));\n\n // Modifiers that are active in the last chunk are carried over to the next line\n currentModifiers =\n chunks[chunks.length - 1].modifiers ?? currentModifiers;\n currentLineNumber += 1;\n }\n };\n\n // Processing of a one individual text chunk\n private processText = (\n fullText: string,\n modifiers: ChunkModifiers,\n ): AnsiChunk[] => {\n const chunks: AnsiChunk[] = [];\n\n let currentModifiers = modifiers;\n\n let prevIndex = 0;\n ansiRegex.lastIndex = 0;\n for (;;) {\n const match = ansiRegex.exec(fullText);\n if (!match) {\n chunks.push({\n text: fullText.slice(prevIndex),\n modifiers: currentModifiers,\n });\n return chunks;\n }\n\n const text = fullText.slice(prevIndex, match.index);\n chunks.push({ text, modifiers: currentModifiers });\n\n // For every escape code that we encounter we keep track of where the\n // next chunk of text starts, and what modifiers it has\n prevIndex = match.index + match[0].length;\n currentModifiers = this.processCode(match[0], currentModifiers);\n }\n };\n\n private processCode = (\n code: string,\n modifiers: ChunkModifiers,\n ): ChunkModifiers => {\n return codeModifiers[code]?.(modifiers) ?? modifiers;\n };\n}\n"],"names":["chunks"],"mappings":"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"}
@@ -32,7 +32,7 @@ function applySearchFilter(lines, searchText) {
32
32
  }
33
33
  function useLogViewerSearch(lines) {
34
34
  const [searchInput, setSearchInput] = useState("");
35
- const searchText = searchInput.toLocaleLowerCase("en-US");
35
+ const searchText = searchInput.toLowerCase();
36
36
  const [resultIndex, setResultIndex] = useState(0);
37
37
  const [shouldFilter, toggleShouldFilter] = useToggle(false);
38
38
  const filter = useMemo(
@@ -1 +1 @@
1
- {"version":3,"file":"useLogViewerSearch.esm.js","sources":["../../../src/components/LogViewer/useLogViewerSearch.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 */\n\nimport { useMemo, useState } from 'react';\nimport { useToggle } from '@react-hookz/web';\nimport { AnsiLine } from './AnsiProcessor';\n\nexport function applySearchFilter(lines: AnsiLine[], searchText: string) {\n if (!searchText) {\n return { lines };\n }\n\n const matchingLines = [];\n const searchResults = [];\n for (const line of lines) {\n if (line.text.includes(searchText)) {\n matchingLines.push(line);\n\n let offset = 0;\n let lineResultIndex = 0;\n for (;;) {\n const start = line.text.indexOf(searchText, offset);\n if (start === -1) {\n break;\n }\n searchResults.push({\n lineNumber: line.lineNumber,\n lineIndex: lineResultIndex++,\n });\n offset = start + searchText.length;\n }\n }\n }\n\n return {\n lines: matchingLines,\n results: searchResults,\n };\n}\n\nexport interface LogViewerSearch {\n lines: AnsiLine[];\n\n searchText: string;\n searchInput: string;\n setSearchInput: (searchInput: string) => void;\n\n shouldFilter: boolean;\n toggleShouldFilter: () => void;\n\n resultCount: number | undefined;\n resultIndex: number | undefined;\n resultIndexStep: (decrement?: boolean) => void;\n\n resultLine: number | undefined;\n resultLineIndex: number | undefined;\n}\n\nexport function useLogViewerSearch(lines: AnsiLine[]): LogViewerSearch {\n const [searchInput, setSearchInput] = useState('');\n const searchText = searchInput.toLocaleLowerCase('en-US');\n\n const [resultIndex, setResultIndex] = useState<number>(0);\n\n const [shouldFilter, toggleShouldFilter] = useToggle(false);\n\n const filter = useMemo(\n () => applySearchFilter(lines, searchText),\n [lines, searchText],\n );\n\n const searchResult = filter.results\n ? filter.results[Math.min(resultIndex, filter.results.length - 1)]\n : undefined;\n const resultCount = filter.results?.length;\n\n const resultIndexStep = (decrement?: boolean) => {\n if (decrement) {\n if (resultCount !== undefined) {\n const next = Math.min(resultIndex - 1, resultCount - 2);\n setResultIndex(next < 0 ? resultCount - 1 : next);\n }\n } else {\n if (resultCount !== undefined) {\n const next = resultIndex + 1;\n setResultIndex(next >= resultCount ? 0 : next);\n }\n }\n };\n\n return {\n lines: shouldFilter ? filter.lines : lines,\n searchText,\n searchInput,\n setSearchInput,\n shouldFilter,\n toggleShouldFilter,\n resultCount,\n resultIndex,\n resultIndexStep,\n resultLine: searchResult?.lineNumber,\n resultLineIndex: searchResult?.lineIndex,\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useLogViewerSearch.esm.js","sources":["../../../src/components/LogViewer/useLogViewerSearch.tsx"],"sourcesContent":["/*\n * Copyright 2021 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 */\n\nimport { useMemo, useState } from 'react';\nimport { useToggle } from '@react-hookz/web';\nimport { AnsiLine } from './AnsiProcessor';\n\nexport function applySearchFilter(lines: AnsiLine[], searchText: string) {\n if (!searchText) {\n return { lines };\n }\n\n const matchingLines = [];\n const searchResults = [];\n for (const line of lines) {\n if (line.text.includes(searchText)) {\n matchingLines.push(line);\n\n let offset = 0;\n let lineResultIndex = 0;\n for (;;) {\n const start = line.text.indexOf(searchText, offset);\n if (start === -1) {\n break;\n }\n searchResults.push({\n lineNumber: line.lineNumber,\n lineIndex: lineResultIndex++,\n });\n offset = start + searchText.length;\n }\n }\n }\n\n return {\n lines: matchingLines,\n results: searchResults,\n };\n}\n\nexport interface LogViewerSearch {\n lines: AnsiLine[];\n\n searchText: string;\n searchInput: string;\n setSearchInput: (searchInput: string) => void;\n\n shouldFilter: boolean;\n toggleShouldFilter: () => void;\n\n resultCount: number | undefined;\n resultIndex: number | undefined;\n resultIndexStep: (decrement?: boolean) => void;\n\n resultLine: number | undefined;\n resultLineIndex: number | undefined;\n}\n\nexport function useLogViewerSearch(lines: AnsiLine[]): LogViewerSearch {\n const [searchInput, setSearchInput] = useState('');\n const searchText = searchInput.toLowerCase();\n\n const [resultIndex, setResultIndex] = useState<number>(0);\n\n const [shouldFilter, toggleShouldFilter] = useToggle(false);\n\n const filter = useMemo(\n () => applySearchFilter(lines, searchText),\n [lines, searchText],\n );\n\n const searchResult = filter.results\n ? filter.results[Math.min(resultIndex, filter.results.length - 1)]\n : undefined;\n const resultCount = filter.results?.length;\n\n const resultIndexStep = (decrement?: boolean) => {\n if (decrement) {\n if (resultCount !== undefined) {\n const next = Math.min(resultIndex - 1, resultCount - 2);\n setResultIndex(next < 0 ? resultCount - 1 : next);\n }\n } else {\n if (resultCount !== undefined) {\n const next = resultIndex + 1;\n setResultIndex(next >= resultCount ? 0 : next);\n }\n }\n };\n\n return {\n lines: shouldFilter ? filter.lines : lines,\n searchText,\n searchInput,\n setSearchInput,\n shouldFilter,\n toggleShouldFilter,\n resultCount,\n resultIndex,\n resultIndexStep,\n resultLine: searchResult?.lineNumber,\n resultLineIndex: searchResult?.lineIndex,\n };\n}\n"],"names":[],"mappings":"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"}
@@ -54,7 +54,7 @@ const flatten = (text, child) => {
54
54
  const headingRenderer = ({ level, children }) => {
55
55
  const childrenArray = Children.toArray(children);
56
56
  const text = childrenArray.reduce(flatten, "");
57
- const slug = text.toLocaleLowerCase("en-US").replace(/\W/g, "-");
57
+ const slug = text.toLowerCase().replace(/\W/g, "-");
58
58
  return createElement(`h${level}`, { id: slug }, children);
59
59
  };
60
60
  const components = {
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownContent.esm.js","sources":["../../../src/components/MarkdownContent/MarkdownContent.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 */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport ReactMarkdown, { Options } from 'react-markdown';\nimport gfm from 'remark-gfm';\nimport { Children, createElement } from 'react';\nimport { CodeSnippet } from '../CodeSnippet';\nimport { HeadingProps } from 'react-markdown/lib/ast-to-react';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize';\nimport type { PluggableList } from 'react-markdown/lib/react-markdown';\nimport { Link } from '../Link';\n\nexport type MarkdownContentClassKey = 'markdown';\n\nconst useStyles = makeStyles(\n theme => ({\n markdown: {\n '& table': {\n borderCollapse: 'collapse',\n border: `1px solid ${theme.palette.border}`,\n },\n '& th, & td': {\n border: `1px solid ${theme.palette.border}`,\n padding: theme.spacing(1),\n },\n '& td': {\n wordBreak: 'break-word',\n overflow: 'hidden',\n verticalAlign: 'middle',\n lineHeight: '1',\n margin: 0,\n padding: theme.spacing(3, 2, 3, 2.5),\n borderBottom: 0,\n },\n '& th': {\n backgroundColor: theme.palette.background.paper,\n },\n '& tr': {\n backgroundColor: theme.palette.background.paper,\n },\n '& tr:nth-child(odd)': {\n backgroundColor: theme.palette.background.default,\n },\n\n '& a': {\n color: theme.palette.link,\n },\n '& img': {\n maxWidth: '100%',\n },\n },\n }),\n { name: 'BackstageMarkdownContent' },\n);\n\ntype Props = {\n content: string;\n dialect?: 'gfm' | 'common-mark';\n linkTarget?: Options['linkTarget'];\n transformLinkUri?: (href: string) => string;\n transformImageUri?: (href: string) => string;\n className?: string;\n};\n\nconst flatten = (text: string, child: any): string => {\n if (!child) return text;\n\n return typeof child === 'string'\n ? text + child\n : Children.toArray(child.props.children).reduce(flatten, text);\n};\n\nconst headingRenderer = ({ level, children }: HeadingProps) => {\n const childrenArray = Children.toArray(children);\n const text = childrenArray.reduce(flatten, '');\n const slug = text.toLocaleLowerCase('en-US').replace(/\\W/g, '-');\n return createElement(`h${level}`, { id: slug }, children);\n};\n\nconst components: Options['components'] = {\n code: ({ inline, className, children, ...props }) => {\n const text = String(children).replace(/\\n+$/, '');\n const match = /language-(\\w+)/.exec(className || '');\n return !inline && match ? (\n <CodeSnippet language={match[1]} text={text} />\n ) : (\n <code className={className} {...props}>\n {children}\n </code>\n );\n },\n h1: headingRenderer,\n h2: headingRenderer,\n h3: headingRenderer,\n h4: headingRenderer,\n h5: headingRenderer,\n h6: headingRenderer,\n\n a: ({ href, children, title, target, rel }) =>\n href ? (\n <Link\n to={href}\n title={title}\n {...(target ? { target } : {})}\n {...(rel ? { rel } : {})}\n >\n {children}\n </Link>\n ) : (\n <>{children}</>\n ),\n};\n\nconst gfmRehypePlugins: PluggableList = [\n [\n rehypeRaw,\n {\n tagfilter: true,\n },\n ],\n [\n rehypeSanitize,\n {\n ...defaultSchema,\n attributes: {\n ...defaultSchema.attributes,\n code: [\n ...(defaultSchema.attributes?.code ?? []),\n // for syntax highlighting classes in code blocks\n // breaks the codesnippet component override above if omitted\n ['className'],\n ],\n },\n },\n ],\n];\n\n/**\n * Renders markdown with the default dialect {@link https://github.github.com/gfm/ | gfm - GitHub flavored Markdown} to backstage theme styled HTML.\n *\n * @remarks\n * If you just want to render to plain {@link https://commonmark.org/ | CommonMark}, set the dialect to `'common-mark'`\n */\nexport function MarkdownContent(props: Props) {\n const {\n content,\n dialect = 'gfm',\n linkTarget,\n transformLinkUri,\n transformImageUri,\n className,\n } = props;\n const classes = useStyles();\n return (\n <ReactMarkdown\n remarkPlugins={dialect === 'gfm' ? [gfm] : []}\n rehypePlugins={dialect === 'gfm' ? gfmRehypePlugins : []}\n className={`${classes.markdown} ${className ?? ''}`.trim()}\n children={content}\n components={components}\n linkTarget={linkTarget}\n transformLinkUri={transformLinkUri}\n transformImageUri={transformImageUri}\n />\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MarkdownContent.esm.js","sources":["../../../src/components/MarkdownContent/MarkdownContent.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 */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport ReactMarkdown, { Options } from 'react-markdown';\nimport gfm from 'remark-gfm';\nimport { Children, createElement } from 'react';\nimport { CodeSnippet } from '../CodeSnippet';\nimport { HeadingProps } from 'react-markdown/lib/ast-to-react';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize';\nimport type { PluggableList } from 'react-markdown/lib/react-markdown';\nimport { Link } from '../Link';\n\nexport type MarkdownContentClassKey = 'markdown';\n\nconst useStyles = makeStyles(\n theme => ({\n markdown: {\n '& table': {\n borderCollapse: 'collapse',\n border: `1px solid ${theme.palette.border}`,\n },\n '& th, & td': {\n border: `1px solid ${theme.palette.border}`,\n padding: theme.spacing(1),\n },\n '& td': {\n wordBreak: 'break-word',\n overflow: 'hidden',\n verticalAlign: 'middle',\n lineHeight: '1',\n margin: 0,\n padding: theme.spacing(3, 2, 3, 2.5),\n borderBottom: 0,\n },\n '& th': {\n backgroundColor: theme.palette.background.paper,\n },\n '& tr': {\n backgroundColor: theme.palette.background.paper,\n },\n '& tr:nth-child(odd)': {\n backgroundColor: theme.palette.background.default,\n },\n\n '& a': {\n color: theme.palette.link,\n },\n '& img': {\n maxWidth: '100%',\n },\n },\n }),\n { name: 'BackstageMarkdownContent' },\n);\n\ntype Props = {\n content: string;\n dialect?: 'gfm' | 'common-mark';\n linkTarget?: Options['linkTarget'];\n transformLinkUri?: (href: string) => string;\n transformImageUri?: (href: string) => string;\n className?: string;\n};\n\nconst flatten = (text: string, child: any): string => {\n if (!child) return text;\n\n return typeof child === 'string'\n ? text + child\n : Children.toArray(child.props.children).reduce(flatten, text);\n};\n\nconst headingRenderer = ({ level, children }: HeadingProps) => {\n const childrenArray = Children.toArray(children);\n const text = childrenArray.reduce(flatten, '');\n const slug = text.toLowerCase().replace(/\\W/g, '-');\n return createElement(`h${level}`, { id: slug }, children);\n};\n\nconst components: Options['components'] = {\n code: ({ inline, className, children, ...props }) => {\n const text = String(children).replace(/\\n+$/, '');\n const match = /language-(\\w+)/.exec(className || '');\n return !inline && match ? (\n <CodeSnippet language={match[1]} text={text} />\n ) : (\n <code className={className} {...props}>\n {children}\n </code>\n );\n },\n h1: headingRenderer,\n h2: headingRenderer,\n h3: headingRenderer,\n h4: headingRenderer,\n h5: headingRenderer,\n h6: headingRenderer,\n\n a: ({ href, children, title, target, rel }) =>\n href ? (\n <Link\n to={href}\n title={title}\n {...(target ? { target } : {})}\n {...(rel ? { rel } : {})}\n >\n {children}\n </Link>\n ) : (\n <>{children}</>\n ),\n};\n\nconst gfmRehypePlugins: PluggableList = [\n [\n rehypeRaw,\n {\n tagfilter: true,\n },\n ],\n [\n rehypeSanitize,\n {\n ...defaultSchema,\n attributes: {\n ...defaultSchema.attributes,\n code: [\n ...(defaultSchema.attributes?.code ?? []),\n // for syntax highlighting classes in code blocks\n // breaks the codesnippet component override above if omitted\n ['className'],\n ],\n },\n },\n ],\n];\n\n/**\n * Renders markdown with the default dialect {@link https://github.github.com/gfm/ | gfm - GitHub flavored Markdown} to backstage theme styled HTML.\n *\n * @remarks\n * If you just want to render to plain {@link https://commonmark.org/ | CommonMark}, set the dialect to `'common-mark'`\n */\nexport function MarkdownContent(props: Props) {\n const {\n content,\n dialect = 'gfm',\n linkTarget,\n transformLinkUri,\n transformImageUri,\n className,\n } = props;\n const classes = useStyles();\n return (\n <ReactMarkdown\n remarkPlugins={dialect === 'gfm' ? [gfm] : []}\n rehypePlugins={dialect === 'gfm' ? gfmRehypePlugins : []}\n className={`${classes.markdown} ${className ?? ''}`.trim()}\n children={content}\n components={components}\n linkTarget={linkTarget}\n transformLinkUri={transformLinkUri}\n transformImageUri={transformImageUri}\n />\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AA6BA,MAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CAAA,KAAA,MAAU;AAAA,IACR,QAAA,EAAU;AAAA,MACR,SAAA,EAAW;AAAA,QACT,cAAA,EAAgB,UAAA;AAAA,QAChB,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA;AAAA,OAC3C;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,CAAA;AAAA,QACzC,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC;AAAA,OAC1B;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,SAAA,EAAW,YAAA;AAAA,QACX,QAAA,EAAU,QAAA;AAAA,QACV,aAAA,EAAe,QAAA;AAAA,QACf,UAAA,EAAY,GAAA;AAAA,QACZ,MAAA,EAAQ,CAAA;AAAA,QACR,SAAS,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,CAAA,EAAG,GAAG,GAAG,CAAA;AAAA,QACnC,YAAA,EAAc;AAAA,OAChB;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA,OAC5C;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA,OAC5C;AAAA,MACA,qBAAA,EAAuB;AAAA,QACrB,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAAA,OAC5C;AAAA,MAEA,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,MAAM,OAAA,CAAQ;AAAA,OACvB;AAAA,MACA,OAAA,EAAS;AAAA,QACP,QAAA,EAAU;AAAA;AACZ;AACF,GACF,CAAA;AAAA,EACA,EAAE,MAAM,0BAAA;AACV,CAAA;AAWA,MAAM,OAAA,GAAU,CAAC,IAAA,EAAc,KAAA,KAAuB;AACpD,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AAEnB,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GACpB,IAAA,GAAO,KAAA,GACP,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,KAAA,CAAM,QAAQ,CAAA,CAAE,MAAA,CAAO,SAAS,IAAI,CAAA;AACjE,CAAA;AAEA,MAAM,eAAA,GAAkB,CAAC,EAAE,KAAA,EAAO,UAAS,KAAoB;AAC7D,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AAC/C,EAAA,MAAM,IAAA,GAAO,aAAA,CAAc,MAAA,CAAO,OAAA,EAAS,EAAE,CAAA;AAC7C,EAAA,MAAM,OAAO,IAAA,CAAK,WAAA,EAAY,CAAE,OAAA,CAAQ,OAAO,GAAG,CAAA;AAClD,EAAA,OAAO,aAAA,CAAc,IAAI,KAAK,CAAA,CAAA,EAAI,EAAE,EAAA,EAAI,IAAA,IAAQ,QAAQ,CAAA;AAC1D,CAAA;AAEA,MAAM,UAAA,GAAoC;AAAA,EACxC,IAAA,EAAM,CAAC,EAAE,MAAA,EAAQ,WAAW,QAAA,EAAU,GAAG,OAAM,KAAM;AACnD,IAAA,MAAM,OAAO,MAAA,CAAO,QAAQ,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAChD,IAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,SAAA,IAAa,EAAE,CAAA;AACnD,IAAA,OAAO,CAAC,MAAA,IAAU,KAAA,mBAChB,GAAA,CAAC,WAAA,EAAA,EAAY,UAAU,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,EAAY,oBAE7C,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAuB,GAAG,OAC7B,QAAA,EACH,CAAA;AAAA,EAEJ,CAAA;AAAA,EACA,EAAA,EAAI,eAAA;AAAA,EACJ,EAAA,EAAI,eAAA;AAAA,EACJ,EAAA,EAAI,eAAA;AAAA,EACJ,EAAA,EAAI,eAAA;AAAA,EACJ,EAAA,EAAI,eAAA;AAAA,EACJ,EAAA,EAAI,eAAA;AAAA,EAEJ,CAAA,EAAG,CAAC,EAAE,IAAA,EAAM,UAAU,KAAA,EAAO,MAAA,EAAQ,GAAA,EAAI,KACvC,IAAA,mBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,EAAA,EAAI,IAAA;AAAA,MACJ,KAAA;AAAA,MACC,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW,EAAC;AAAA,MAC3B,GAAI,GAAA,GAAM,EAAE,GAAA,KAAQ,EAAC;AAAA,MAErB;AAAA;AAAA,GACH,mCAEG,QAAA,EAAS;AAElB,CAAA;AAEA,MAAM,gBAAA,GAAkC;AAAA,EACtC;AAAA,IACE,SAAA;AAAA,IACA;AAAA,MACE,SAAA,EAAW;AAAA;AACb,GACF;AAAA,EACA;AAAA,IACE,cAAA;AAAA,IACA;AAAA,MACE,GAAG,aAAA;AAAA,MACH,UAAA,EAAY;AAAA,QACV,GAAG,aAAA,CAAc,UAAA;AAAA,QACjB,IAAA,EAAM;AAAA,UACJ,GAAI,aAAA,CAAc,UAAA,EAAY,IAAA,IAAQ,EAAC;AAAA;AAAA;AAAA,UAGvC,CAAC,WAAW;AAAA;AACd;AACF;AACF;AAEJ,CAAA;AAQO,SAAS,gBAAgB,KAAA,EAAc;AAC5C,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,OAAA,GAAU,KAAA;AAAA,IACV,UAAA;AAAA,IACA,gBAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACF,GAAI,KAAA;AACJ,EAAA,MAAM,UAAU,SAAA,EAAU;AAC1B,EAAA,uBACE,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,eAAe,OAAA,KAAY,KAAA,GAAQ,CAAC,GAAG,IAAI,EAAC;AAAA,MAC5C,aAAA,EAAe,OAAA,KAAY,KAAA,GAAQ,gBAAA,GAAmB,EAAC;AAAA,MACvD,SAAA,EAAW,GAAG,OAAA,CAAQ,QAAQ,IAAI,SAAA,IAAa,EAAE,GAAG,IAAA,EAAK;AAAA,MACzD,QAAA,EAAU,OAAA;AAAA,MACV,UAAA;AAAA,MACA,UAAA;AAAA,MACA,gBAAA;AAAA,MACA;AAAA;AAAA,GACF;AAEJ;;;;"}
@@ -89,7 +89,7 @@ const useStyles = makeStyles(
89
89
  { name: "BackstageWarningPanel" }
90
90
  );
91
91
  const capitalize = (s) => {
92
- return s.charAt(0).toLocaleUpperCase("en-US") + s.slice(1);
92
+ return s.charAt(0).toUpperCase() + s.slice(1);
93
93
  };
94
94
  function WarningPanel(props) {
95
95
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"WarningPanel.esm.js","sources":["../../../src/components/WarningPanel/WarningPanel.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 */\n\nimport { makeStyles, darken, lighten, Theme } from '@material-ui/core/styles';\nimport Accordion from '@material-ui/core/Accordion';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport ErrorOutline from '@material-ui/icons/ErrorOutline';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport { ReactNode } from 'react';\nimport { MarkdownContent } from '../MarkdownContent';\n\nconst getWarningTextColor = (\n severity: NonNullable<WarningProps['severity']>,\n theme: Theme,\n) => {\n const getColor = theme.palette.type === 'light' ? darken : lighten;\n return getColor(theme.palette[severity].light, 0.6);\n};\n\nconst getWarningBackgroundColor = (\n severity: NonNullable<WarningProps['severity']>,\n theme: Theme,\n) => {\n const getBackgroundColor = theme.palette.type === 'light' ? lighten : darken;\n return getBackgroundColor(theme.palette[severity].light, 0.9);\n};\n\nconst useErrorOutlineStyles = makeStyles(theme => ({\n root: {\n marginRight: theme.spacing(1),\n fill: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n },\n}));\n\nconst ErrorOutlineStyled = ({ severity }: Pick<WarningProps, 'severity'>) => {\n const classes = useErrorOutlineStyles({ severity });\n return <ErrorOutline classes={classes} />;\n};\nconst ExpandMoreIconStyled = ({ severity }: Pick<WarningProps, 'severity'>) => {\n const classes = useErrorOutlineStyles({ severity });\n return <ExpandMoreIcon classes={classes} />;\n};\n\nexport type WarningPanelClassKey =\n | 'panel'\n | 'summary'\n | 'summaryText'\n | 'message'\n | 'details';\n\nconst useStyles = makeStyles(\n theme => ({\n panel: {\n backgroundColor: ({ severity }: WarningProps) =>\n getWarningBackgroundColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n color: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n verticalAlign: 'middle',\n },\n summary: {\n display: 'flex',\n flexDirection: 'row',\n },\n summaryText: {\n color: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n fontWeight: theme.typography.fontWeightBold,\n },\n markdownContent: {\n wordBreak: 'break-word',\n '& p': {\n display: 'inline',\n },\n },\n message: {\n width: '100%',\n display: 'block',\n color: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n backgroundColor: ({ severity }: WarningProps) =>\n getWarningBackgroundColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n },\n details: {\n width: '100%',\n display: 'block',\n color: theme.palette.textContrast,\n backgroundColor: theme.palette.background.default,\n border: `1px solid ${theme.palette.border}`,\n padding: theme.spacing(2.0),\n fontFamily: 'sans-serif',\n },\n }),\n { name: 'BackstageWarningPanel' },\n);\n\nexport type WarningProps = {\n title?: string;\n severity?: 'warning' | 'error' | 'info';\n titleFormat?: string;\n message?: ReactNode;\n defaultExpanded?: boolean;\n children?: ReactNode;\n};\n\nconst capitalize = (s: string) => {\n return s.charAt(0).toLocaleUpperCase('en-US') + s.slice(1);\n};\n\n/**\n * Show a user friendly error message to a user similar to\n * ErrorPanel except that the warning panel only shows the warning message to\n * the user.\n *\n * @param severity - Ability to change the severity of the alert. Default value\n * \"warning\"\n * @param title - A title for the warning. If not supplied, \"Warning\" will be\n * used.\n * @param message - Optional more detailed user-friendly message elaborating on\n * the cause of the error.\n * @param children - Objects to provide context, such as a stack trace or detailed\n * error reporting. Will be available inside an unfolded accordion.\n */\nexport function WarningPanel(props: WarningProps) {\n const {\n severity = 'warning',\n title,\n titleFormat,\n message,\n children,\n defaultExpanded,\n } = props;\n const classes = useStyles({ severity });\n\n // If no severity or title provided, the heading will read simply \"Warning\"\n const subTitle = capitalize(severity) + (title ? `: ${title}` : '');\n\n return (\n <Accordion\n defaultExpanded={defaultExpanded ?? false}\n className={classes.panel}\n role=\"alert\"\n >\n <AccordionSummary\n expandIcon={<ExpandMoreIconStyled severity={severity} />}\n className={classes.summary}\n >\n <ErrorOutlineStyled severity={severity} />\n <Typography className={classes.summaryText} variant=\"subtitle1\">\n {titleFormat === 'markdown' ? (\n <MarkdownContent\n content={subTitle}\n className={classes.markdownContent}\n />\n ) : (\n subTitle\n )}\n </Typography>\n </AccordionSummary>\n {(message || children) && (\n <AccordionDetails>\n <Grid container>\n {message && (\n <Grid item xs={12}>\n <Typography className={classes.message} variant=\"body1\">\n {message}\n </Typography>\n </Grid>\n )}\n {children && (\n <Grid item xs={12} className={classes.details}>\n {children}\n </Grid>\n )}\n </Grid>\n </AccordionDetails>\n )}\n </Accordion>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"WarningPanel.esm.js","sources":["../../../src/components/WarningPanel/WarningPanel.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 */\n\nimport { makeStyles, darken, lighten, Theme } from '@material-ui/core/styles';\nimport Accordion from '@material-ui/core/Accordion';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport ErrorOutline from '@material-ui/icons/ErrorOutline';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport { ReactNode } from 'react';\nimport { MarkdownContent } from '../MarkdownContent';\n\nconst getWarningTextColor = (\n severity: NonNullable<WarningProps['severity']>,\n theme: Theme,\n) => {\n const getColor = theme.palette.type === 'light' ? darken : lighten;\n return getColor(theme.palette[severity].light, 0.6);\n};\n\nconst getWarningBackgroundColor = (\n severity: NonNullable<WarningProps['severity']>,\n theme: Theme,\n) => {\n const getBackgroundColor = theme.palette.type === 'light' ? lighten : darken;\n return getBackgroundColor(theme.palette[severity].light, 0.9);\n};\n\nconst useErrorOutlineStyles = makeStyles(theme => ({\n root: {\n marginRight: theme.spacing(1),\n fill: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n },\n}));\n\nconst ErrorOutlineStyled = ({ severity }: Pick<WarningProps, 'severity'>) => {\n const classes = useErrorOutlineStyles({ severity });\n return <ErrorOutline classes={classes} />;\n};\nconst ExpandMoreIconStyled = ({ severity }: Pick<WarningProps, 'severity'>) => {\n const classes = useErrorOutlineStyles({ severity });\n return <ExpandMoreIcon classes={classes} />;\n};\n\nexport type WarningPanelClassKey =\n | 'panel'\n | 'summary'\n | 'summaryText'\n | 'message'\n | 'details';\n\nconst useStyles = makeStyles(\n theme => ({\n panel: {\n backgroundColor: ({ severity }: WarningProps) =>\n getWarningBackgroundColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n color: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n verticalAlign: 'middle',\n },\n summary: {\n display: 'flex',\n flexDirection: 'row',\n },\n summaryText: {\n color: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n fontWeight: theme.typography.fontWeightBold,\n },\n markdownContent: {\n wordBreak: 'break-word',\n '& p': {\n display: 'inline',\n },\n },\n message: {\n width: '100%',\n display: 'block',\n color: ({ severity }: WarningProps) =>\n getWarningTextColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n backgroundColor: ({ severity }: WarningProps) =>\n getWarningBackgroundColor(\n severity as NonNullable<WarningProps['severity']>,\n theme,\n ),\n },\n details: {\n width: '100%',\n display: 'block',\n color: theme.palette.textContrast,\n backgroundColor: theme.palette.background.default,\n border: `1px solid ${theme.palette.border}`,\n padding: theme.spacing(2.0),\n fontFamily: 'sans-serif',\n },\n }),\n { name: 'BackstageWarningPanel' },\n);\n\nexport type WarningProps = {\n title?: string;\n severity?: 'warning' | 'error' | 'info';\n titleFormat?: string;\n message?: ReactNode;\n defaultExpanded?: boolean;\n children?: ReactNode;\n};\n\nconst capitalize = (s: string) => {\n return s.charAt(0).toUpperCase() + s.slice(1);\n};\n\n/**\n * Show a user friendly error message to a user similar to\n * ErrorPanel except that the warning panel only shows the warning message to\n * the user.\n *\n * @param severity - Ability to change the severity of the alert. Default value\n * \"warning\"\n * @param title - A title for the warning. If not supplied, \"Warning\" will be\n * used.\n * @param message - Optional more detailed user-friendly message elaborating on\n * the cause of the error.\n * @param children - Objects to provide context, such as a stack trace or detailed\n * error reporting. Will be available inside an unfolded accordion.\n */\nexport function WarningPanel(props: WarningProps) {\n const {\n severity = 'warning',\n title,\n titleFormat,\n message,\n children,\n defaultExpanded,\n } = props;\n const classes = useStyles({ severity });\n\n // If no severity or title provided, the heading will read simply \"Warning\"\n const subTitle = capitalize(severity) + (title ? `: ${title}` : '');\n\n return (\n <Accordion\n defaultExpanded={defaultExpanded ?? false}\n className={classes.panel}\n role=\"alert\"\n >\n <AccordionSummary\n expandIcon={<ExpandMoreIconStyled severity={severity} />}\n className={classes.summary}\n >\n <ErrorOutlineStyled severity={severity} />\n <Typography className={classes.summaryText} variant=\"subtitle1\">\n {titleFormat === 'markdown' ? (\n <MarkdownContent\n content={subTitle}\n className={classes.markdownContent}\n />\n ) : (\n subTitle\n )}\n </Typography>\n </AccordionSummary>\n {(message || children) && (\n <AccordionDetails>\n <Grid container>\n {message && (\n <Grid item xs={12}>\n <Typography className={classes.message} variant=\"body1\">\n {message}\n </Typography>\n </Grid>\n )}\n {children && (\n <Grid item xs={12} className={classes.details}>\n {children}\n </Grid>\n )}\n </Grid>\n </AccordionDetails>\n )}\n </Accordion>\n );\n}\n"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ import { CSSProperties, ElementType, ReactNode, SVGProps, PropsWithChildren, Com
4
4
  import { ButtonProps as ButtonProps$1 } from '@material-ui/core/Button';
5
5
  import { LinkProps as LinkProps$1 } from '@material-ui/core/Link';
6
6
  import { LinkProps as LinkProps$2, NavLinkProps } from 'react-router-dom';
7
+ import { ButtonIconProps } from '@backstage/ui';
7
8
  import IconButton from '@material-ui/core/IconButton';
8
9
  import CSS from 'csstype';
9
10
  import { Options } from 'react-markdown';
@@ -279,6 +280,14 @@ interface CopyTextButtonProps {
279
280
  * Default: "Copy text"
280
281
  */
281
282
  'aria-label'?: string;
283
+ /**
284
+ * The visual variant of the button
285
+ *
286
+ * @remarks
287
+ *
288
+ * Default: "primary"
289
+ */
290
+ variant?: ButtonIconProps['variant'];
282
291
  }
283
292
  /**
284
293
  * Copy text button with visual feedback
@@ -875,9 +884,10 @@ declare function IconLinkVertical({ color, disabled, href, icon, label, onClick,
875
884
  type HeaderIconLinkRowClassKey = 'links';
876
885
  type Props$d = {
877
886
  links: IconLinkVerticalProps[];
887
+ children?: ReactNode;
878
888
  };
879
889
  /**
880
- * HTML nav tag with links mapped inside
890
+ * HTML nav tag with links and optional custom link elements inside
881
891
  *
882
892
  * @public
883
893
  *
@@ -196,8 +196,8 @@ const WorkaroundNavLink = forwardRef(function WorkaroundNavLinkWithRef({
196
196
  let { pathname: locationPathname } = useLocation();
197
197
  let { pathname: toPathname } = useResolvedPath(to);
198
198
  if (!caseSensitive) {
199
- locationPathname = locationPathname.toLocaleLowerCase("en-US");
200
- toPathname = toPathname.toLocaleLowerCase("en-US");
199
+ locationPathname = locationPathname.toLowerCase();
200
+ toPathname = toPathname.toLowerCase();
201
201
  }
202
202
  let isActive = locationPathname === toPathname;
203
203
  if (!isActive && !end) {
@@ -1 +1 @@
1
- {"version":3,"file":"Items.esm.js","sources":["../../../src/layout/Sidebar/Items.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 */\n\nimport {\n IconComponent,\n useAnalytics,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport Badge from '@material-ui/core/Badge';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles, styled, Theme } from '@material-ui/core/styles';\nimport {\n CreateCSSProperties,\n StyledComponentProps,\n} from '@material-ui/core/styles/withStyles';\nimport TextField from '@material-ui/core/TextField';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport ArrowDropDown from '@material-ui/icons/ArrowDropDown';\nimport ArrowDropUp from '@material-ui/icons/ArrowDropUp';\nimport ArrowRightIcon from '@material-ui/icons/ArrowRight';\nimport SearchIcon from '@material-ui/icons/Search';\nimport classnames from 'classnames';\nimport type { Location } from 'history';\n\nimport {\n ComponentProps,\n ComponentType,\n CSSProperties,\n forwardRef,\n KeyboardEventHandler,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useState,\n MouseEvent,\n ChangeEvent,\n ReactElement,\n createElement,\n} from 'react';\n\nimport {\n Link,\n NavLinkProps,\n resolvePath,\n useLocation,\n useResolvedPath,\n} from 'react-router-dom';\n\nimport {\n SidebarConfig,\n SidebarConfigContext,\n SidebarItemWithSubmenuContext,\n} from './config';\nimport DoubleArrowLeft from './icons/DoubleArrowLeft';\nimport DoubleArrowRight from './icons/DoubleArrowRight';\nimport { useSidebarOpenState } from './SidebarOpenStateContext';\nimport { SidebarSubmenu, SidebarSubmenuProps } from './SidebarSubmenu';\nimport { SidebarSubmenuItemProps } from './SidebarSubmenuItem';\nimport { isLocationMatch } from './utils';\nimport Button from '@material-ui/core/Button';\n\n/** @public */\nexport type SidebarItemClassKey =\n | 'root'\n | 'buttonItem'\n | 'closed'\n | 'open'\n | 'highlightable'\n | 'highlighted'\n | 'label'\n | 'iconContainer'\n | 'searchRoot'\n | 'searchField'\n | 'searchFieldHTMLInput'\n | 'searchContainer'\n | 'secondaryAction'\n | 'closedItemIcon'\n | 'submenuArrow'\n | 'expandButton'\n | 'arrows'\n | 'selected';\n\nconst makeSidebarStyles = (sidebarConfig: SidebarConfig) =>\n makeStyles(\n theme => ({\n root: {\n color: theme.palette.navigation.color,\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n height: 48,\n cursor: 'pointer',\n },\n buttonItem: {\n background: 'none',\n border: 'none',\n width: '100%',\n margin: 0,\n padding: 0,\n textAlign: 'inherit',\n font: 'inherit',\n textTransform: 'none',\n },\n itemIcon: {\n display: 'inline-flex',\n fontSize: theme.typography.fontSize,\n lineHeight: 0,\n '& svg': {\n width: '1.5em',\n height: '1.5em',\n fontSize: 'inherit',\n flexShrink: 0,\n },\n },\n closed: {\n width: sidebarConfig.drawerWidthClosed,\n justifyContent: 'center',\n },\n open: {\n [theme.breakpoints.up('sm')]: {\n width: sidebarConfig.drawerWidthOpen,\n },\n },\n highlightable: {\n '&:hover': {\n background:\n theme.palette.navigation.navItem?.hoverBackground ?? '#404040',\n },\n },\n highlighted: {\n background:\n theme.palette.navigation.navItem?.hoverBackground ?? '#404040',\n },\n label: {\n // XXX (@koroeskohr): I can't seem to achieve the desired font-weight from the designs\n fontWeight: 'bold',\n whiteSpace: 'nowrap',\n lineHeight: 'auto',\n flex: '3 1 auto',\n width: '110px',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n },\n iconContainer: {\n boxSizing: 'border-box',\n height: '100%',\n width: sidebarConfig.iconContainerWidth,\n marginRight: -theme.spacing(2),\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: '0',\n },\n searchRoot: {\n marginBottom: 12,\n },\n searchField: {\n color: '#b5b5b5',\n fontWeight: theme.typography.fontWeightBold,\n fontSize: theme.typography.fontSize,\n },\n searchFieldHTMLInput: {\n padding: theme.spacing(2, 0, 2),\n },\n searchContainer: {\n width: sidebarConfig.drawerWidthOpen - sidebarConfig.iconContainerWidth,\n },\n secondaryAction: {\n width: theme.spacing(6),\n textAlign: 'center',\n marginRight: theme.spacing(1),\n },\n closedItemIcon: {\n width: '100%',\n justifyContent: 'center',\n },\n submenuArrow: {\n display: 'flex',\n },\n expandButton: {\n background: 'none',\n border: 'none',\n color: theme.palette.navigation.color,\n width: '100%',\n cursor: 'pointer',\n position: 'relative',\n height: 48,\n },\n arrows: {\n position: 'absolute',\n right: 10,\n },\n selected: {\n '&$root': {\n borderLeft: `solid ${sidebarConfig.selectedIndicatorWidth}px ${theme.palette.navigation.indicator}`,\n color: theme.palette.navigation.selectedColor,\n },\n '&$closed': {\n width: sidebarConfig.drawerWidthClosed,\n },\n '& $closedItemIcon': {\n paddingRight: sidebarConfig.selectedIndicatorWidth,\n },\n '& $iconContainer': {\n marginLeft: -sidebarConfig.selectedIndicatorWidth,\n },\n },\n }),\n { name: 'BackstageSidebarItem' },\n );\n\n// This is a workaround for this issue https://github.com/mui/material-ui/issues/15511\n// The styling of the `selected` elements doesn't work as expected when using a prop callback.\n// Don't use this pattern unless needed\nfunction useMemoStyles(sidebarConfig: SidebarConfig) {\n const useStyles = useMemo(\n () => makeSidebarStyles(sidebarConfig),\n [sidebarConfig],\n );\n return useStyles();\n}\n\n/**\n * Evaluates the routes of the SubmenuItems & nested DropdownItems.\n * The reevaluation is only triggered, if the `locationPathname` changes, as `useElementFilter` uses memorization.\n *\n * @param submenu SidebarSubmenu component\n * @param location Location\n * @returns boolean\n */\nconst useLocationMatch = (\n submenu: ReactElement<SidebarSubmenuProps>,\n location: Location,\n): boolean =>\n useElementFilter(\n submenu.props.children,\n elements => {\n let active = false;\n elements\n .getElements()\n .forEach(\n ({\n props: { to, dropdownItems },\n }: {\n props: Partial<SidebarSubmenuItemProps>;\n }) => {\n if (!active) {\n if (dropdownItems?.length) {\n dropdownItems.forEach(\n ({ to: _to }) =>\n (active =\n active || isLocationMatch(location, resolvePath(_to))),\n );\n return;\n }\n if (to) {\n active = isLocationMatch(location, resolvePath(to));\n }\n }\n },\n );\n return active;\n },\n [location.pathname],\n );\n\ntype SidebarItemBaseProps = {\n icon: IconComponent;\n text?: string;\n hasNotifications?: boolean;\n hasSubmenu?: boolean;\n disableHighlight?: boolean;\n className?: string;\n noTrack?: boolean;\n onClick?: (ev: MouseEvent) => void;\n};\n\ntype SidebarItemButtonProps = SidebarItemBaseProps & {\n onClick: (ev: MouseEvent) => void;\n children?: ReactNode;\n};\n\ntype SidebarItemLinkProps = SidebarItemBaseProps & {\n to: string;\n onClick?: (ev: MouseEvent) => void;\n} & NavLinkProps;\n\ntype SidebarItemWithSubmenuProps = SidebarItemBaseProps & {\n to?: string;\n onClick?: (ev: MouseEvent) => void;\n children: ReactNode;\n};\n\n/**\n * SidebarItem with 'to' property will be a clickable link.\n * SidebarItem with 'onClick' property and without 'to' property will be a clickable button.\n * SidebarItem which wraps a SidebarSubmenu will be a clickable button which opens a submenu.\n */\ntype SidebarItemProps =\n | SidebarItemLinkProps\n | SidebarItemButtonProps\n | SidebarItemWithSubmenuProps;\n\nfunction isButtonItem(\n props: SidebarItemProps,\n): props is SidebarItemButtonProps {\n return (props as SidebarItemLinkProps).to === undefined;\n}\n\nconst sidebarSubmenuType = createElement(SidebarSubmenu).type;\n\n// TODO(Rugvip): Remove this once NavLink is updated in react-router-dom.\n// This is needed because react-router doesn't handle the path comparison\n// properly yet, matching for example /foobar with /foo.\nexport const WorkaroundNavLink = forwardRef<\n HTMLAnchorElement,\n NavLinkProps & {\n children?: ReactNode;\n activeStyle?: CSSProperties;\n activeClassName?: string;\n }\n>(function WorkaroundNavLinkWithRef(\n {\n to,\n end,\n style,\n className,\n activeStyle,\n caseSensitive,\n activeClassName = 'active',\n 'aria-current': ariaCurrentProp = 'page',\n ...rest\n },\n ref,\n) {\n let { pathname: locationPathname } = useLocation();\n let { pathname: toPathname } = useResolvedPath(to);\n\n if (!caseSensitive) {\n locationPathname = locationPathname.toLocaleLowerCase('en-US');\n toPathname = toPathname.toLocaleLowerCase('en-US');\n }\n\n let isActive = locationPathname === toPathname;\n if (!isActive && !end) {\n // This is the behavior that is different from the original NavLink\n isActive = locationPathname.startsWith(`${toPathname}/`);\n }\n\n const ariaCurrent = isActive ? ariaCurrentProp : undefined;\n\n return (\n <Link\n {...rest}\n to={to}\n ref={ref}\n aria-current={ariaCurrent}\n style={{ ...style, ...(isActive ? activeStyle : undefined) }}\n className={classnames([\n typeof className !== 'function' ? className : undefined,\n isActive ? activeClassName : undefined,\n ])}\n />\n );\n});\n\n/**\n * Common component used by SidebarItem & SidebarItemWithSubmenu\n */\nconst SidebarItemBase = forwardRef<\n any,\n SidebarItemProps & { children: ReactNode }\n>((props, ref) => {\n const {\n icon: Icon,\n text,\n hasNotifications = false,\n hasSubmenu = false,\n disableHighlight = false,\n onClick,\n noTrack,\n children,\n className,\n ...navLinkProps\n } = props;\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const classes = useMemoStyles(sidebarConfig);\n // XXX (@koroeskohr): unsure this is optimal. But I just really didn't want to have the item component\n // depend on the current location, and at least have it being optionally forced to selected.\n // Still waiting on a Q answered to fine tune the implementation\n const { isOpen } = useSidebarOpenState();\n\n const divStyle =\n !isOpen && hasSubmenu\n ? { display: 'flex', marginLeft: '20px' }\n : { lineHeight: '0' };\n\n const displayItemIcon = (\n <Box style={divStyle}>\n <Box component=\"span\" className={classes.itemIcon}>\n <Icon fontSize=\"inherit\" />\n </Box>\n {!isOpen && hasSubmenu ? <ArrowRightIcon fontSize=\"small\" /> : <></>}\n </Box>\n );\n\n const itemIcon = (\n <Badge\n color=\"secondary\"\n variant=\"dot\"\n overlap=\"circular\"\n invisible={!hasNotifications}\n className={classnames({ [classes.closedItemIcon]: !isOpen })}\n >\n {displayItemIcon}\n </Badge>\n );\n\n const openContent = (\n <>\n <Box data-testid=\"login-button\" className={classes.iconContainer}>\n {itemIcon}\n </Box>\n {text && (\n <Typography\n variant=\"subtitle2\"\n component=\"span\"\n className={classes.label}\n >\n {text}\n </Typography>\n )}\n <div className={classes.secondaryAction}>{children}</div>\n </>\n );\n\n const content = isOpen ? openContent : itemIcon;\n\n const childProps = {\n onClick,\n className: classnames(\n className,\n classes.root,\n isOpen ? classes.open : classes.closed,\n isButtonItem(props) && classes.buttonItem,\n { [classes.highlightable]: !disableHighlight },\n ),\n };\n\n const analyticsApi = useAnalytics();\n const { pathname: to } = useResolvedPath(\n !isButtonItem(props) && props.to ? props.to : '',\n );\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => {\n if (!noTrack) {\n const action = 'click';\n const subject = text ?? 'Sidebar Item';\n const options = to ? { attributes: { to } } : undefined;\n analyticsApi.captureEvent(action, subject, options);\n }\n onClick?.(event);\n },\n [analyticsApi, text, to, noTrack, onClick],\n );\n\n if (isButtonItem(props)) {\n return (\n <Button\n role=\"button\"\n aria-label={text}\n {...childProps}\n ref={ref}\n onClick={handleClick}\n >\n {content}\n </Button>\n );\n }\n\n return (\n <WorkaroundNavLink\n {...childProps}\n activeClassName={classes.selected}\n to={props.to ? props.to : ''}\n ref={ref}\n aria-label={text ? text : props.to}\n {...navLinkProps}\n onClick={handleClick}\n >\n {content}\n </WorkaroundNavLink>\n );\n});\n\nconst SidebarItemWithSubmenu = ({\n children,\n ...props\n}: SidebarItemBaseProps & {\n children: ReactElement<SidebarSubmenuProps>;\n}) => {\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const classes = useMemoStyles(sidebarConfig);\n const [isHoveredOn, setIsHoveredOn] = useState(false);\n const location = useLocation();\n const isActive = useLocationMatch(children, location);\n const isSmallScreen = useMediaQuery((theme: Theme) =>\n theme.breakpoints.down('sm'),\n );\n\n const handleMouseEnter = () => {\n setIsHoveredOn(true);\n };\n const handleMouseLeave = () => {\n setIsHoveredOn(false);\n };\n\n const arrowIcon = () => {\n if (isSmallScreen) {\n return isHoveredOn ? (\n <ArrowDropUp fontSize=\"small\" className={classes.submenuArrow} />\n ) : (\n <ArrowDropDown fontSize=\"small\" className={classes.submenuArrow} />\n );\n }\n return (\n !isHoveredOn && (\n <ArrowRightIcon fontSize=\"small\" className={classes.submenuArrow} />\n )\n );\n };\n\n return (\n <SidebarItemWithSubmenuContext.Provider\n value={{\n isHoveredOn,\n setIsHoveredOn,\n }}\n >\n <div\n data-testid=\"item-with-submenu\"\n onMouseLeave={handleMouseLeave}\n onTouchStart={isHoveredOn ? handleMouseLeave : handleMouseEnter}\n onMouseEnter={handleMouseEnter}\n className={classnames(isHoveredOn && classes.highlighted)}\n >\n <SidebarItemBase\n hasSubmenu\n className={isActive ? classes.selected : ''}\n {...props}\n >\n {arrowIcon()}\n </SidebarItemBase>\n {isHoveredOn && children}\n </div>\n </SidebarItemWithSubmenuContext.Provider>\n );\n};\n\n/**\n * Creates a `SidebarItem`\n *\n * @remarks\n * If children contain a `SidebarSubmenu` component the `SidebarItem` will have a expandable submenu\n */\nexport const SidebarItem = forwardRef<\n any,\n SidebarItemProps & { children: ReactNode }\n>((props, ref) => {\n // Filter children for SidebarSubmenu components\n const [submenu] = useElementFilter(props.children, elements =>\n // Directly comparing child.type with SidebarSubmenu will not work with in\n // combination with react-hot-loader\n //\n // https://github.com/gaearon/react-hot-loader/issues/304#issuecomment-456569720\n elements.getElements().filter(child => child.type === sidebarSubmenuType),\n );\n\n if (submenu) {\n return (\n <SidebarItemWithSubmenu {...props}>\n {submenu as ReactElement<SidebarSubmenuProps>}\n </SidebarItemWithSubmenu>\n );\n }\n\n return <SidebarItemBase {...props} ref={ref} />;\n}) as (props: SidebarItemProps) => JSX.Element;\n\ntype SidebarSearchFieldProps = {\n onSearch: (input: string) => void;\n to?: string;\n icon?: IconComponent;\n};\n\nexport function SidebarSearchField(props: SidebarSearchFieldProps) {\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const [input, setInput] = useState('');\n const classes = useMemoStyles(sidebarConfig);\n const Icon = props.icon ? props.icon : SearchIcon;\n\n const search = () => {\n props.onSearch(input);\n setInput('');\n };\n\n const handleEnter: KeyboardEventHandler = ev => {\n if (ev.key === 'Enter') {\n ev.preventDefault();\n search();\n }\n };\n\n const handleInput = (ev: ChangeEvent<HTMLInputElement>) => {\n setInput(ev.target.value);\n };\n\n const handleInputClick = (ev: MouseEvent<HTMLInputElement>) => {\n // Clicking into the search fields shouldn't navigate to the search page\n ev.preventDefault();\n ev.stopPropagation();\n };\n\n const handleItemClick = (ev: MouseEvent) => {\n // Clicking on the search icon while should execute a query with the current field content\n search();\n ev.preventDefault();\n };\n\n return (\n <Box className={classes.searchRoot}>\n <SidebarItem\n icon={Icon}\n to={props.to}\n onClick={handleItemClick}\n disableHighlight\n >\n <TextField\n placeholder=\"Search\"\n value={input}\n onClick={handleInputClick}\n onChange={handleInput}\n onKeyDown={handleEnter}\n className={classes.searchContainer}\n InputProps={{\n disableUnderline: true,\n className: classes.searchField,\n }}\n inputProps={{\n className: classes.searchFieldHTMLInput,\n }}\n />\n </SidebarItem>\n </Box>\n );\n}\n\nexport type SidebarSpaceClassKey = 'root';\n\nexport const SidebarSpace = styled('div')(\n {\n flex: 1,\n },\n { name: 'BackstageSidebarSpace' },\n) as ComponentType<ComponentProps<'div'> & StyledComponentProps<'root'>>;\n\nexport type SidebarSpacerClassKey = 'root';\n\nexport const SidebarSpacer = styled('div')(\n {\n height: 8,\n },\n { name: 'BackstageSidebarSpacer' },\n) as ComponentType<ComponentProps<'div'> & StyledComponentProps<'root'>>;\n\nexport type SidebarDividerClassKey = 'root';\n\nexport const SidebarDivider = styled('hr')(\n ({ theme }) => ({\n height: 1,\n width: '100%',\n background: '#383838',\n border: 'none',\n margin: theme.spacing(1.2, 0),\n }),\n { name: 'BackstageSidebarDivider' },\n) as ComponentType<ComponentProps<'hr'> & StyledComponentProps<'root'>>;\n\nconst styledScrollbar = (theme: Theme): CreateCSSProperties => ({\n overflowY: 'auto',\n '&::-webkit-scrollbar': {\n backgroundColor: theme.palette.background.default,\n width: '5px',\n borderRadius: '5px',\n },\n '&::-webkit-scrollbar-thumb': {\n backgroundColor: theme.palette.text.secondary,\n borderRadius: '5px',\n },\n});\n\nexport const SidebarScrollWrapper = styled('div')(({ theme }) => {\n const scrollbarStyles = styledScrollbar(theme);\n return {\n flex: '0 1 auto',\n overflowX: 'hidden',\n width: '100%',\n // Display at least one item in the container\n // Question: Can this be a config/theme variable - if so, which? :/\n minHeight: '48px',\n overflowY: 'hidden',\n '@media (hover: none)': scrollbarStyles,\n '&:hover': scrollbarStyles,\n };\n}) as ComponentType<ComponentProps<'div'> & StyledComponentProps<'root'>>;\n\n/**\n * A button which allows you to expand the sidebar when clicked.\n *\n * @remarks\n * Use optionally to replace sidebar's expand-on-hover feature with expand-on-click.\n *\n * If you are using this you might want to set the `disableExpandOnHover` of the `Sidebar` to `true`.\n *\n * @public\n */\nexport const SidebarExpandButton = () => {\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const classes = useMemoStyles(sidebarConfig);\n const { isOpen, setOpen } = useSidebarOpenState();\n const isSmallScreen = useMediaQuery<Theme>(\n theme => theme.breakpoints.down('md'),\n { noSsr: true },\n );\n\n if (isSmallScreen) {\n return null;\n }\n\n const handleClick = () => {\n setOpen(!isOpen);\n };\n\n return (\n <Button\n role=\"button\"\n onClick={handleClick}\n className={classes.expandButton}\n aria-label=\"Expand Sidebar\"\n data-testid=\"sidebar-expand-button\"\n >\n <Box className={classes.arrows}>\n {isOpen ? <DoubleArrowLeft /> : <DoubleArrowRight />}\n </Box>\n </Button>\n );\n};\n"],"names":["classnames","ArrowDropUp","ArrowDropDown","SearchIcon"],"mappings":"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"}
1
+ {"version":3,"file":"Items.esm.js","sources":["../../../src/layout/Sidebar/Items.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 */\n\nimport {\n IconComponent,\n useAnalytics,\n useElementFilter,\n} from '@backstage/core-plugin-api';\nimport Badge from '@material-ui/core/Badge';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles, styled, Theme } from '@material-ui/core/styles';\nimport {\n CreateCSSProperties,\n StyledComponentProps,\n} from '@material-ui/core/styles/withStyles';\nimport TextField from '@material-ui/core/TextField';\nimport Typography from '@material-ui/core/Typography';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport ArrowDropDown from '@material-ui/icons/ArrowDropDown';\nimport ArrowDropUp from '@material-ui/icons/ArrowDropUp';\nimport ArrowRightIcon from '@material-ui/icons/ArrowRight';\nimport SearchIcon from '@material-ui/icons/Search';\nimport classnames from 'classnames';\nimport type { Location } from 'history';\n\nimport {\n ComponentProps,\n ComponentType,\n CSSProperties,\n forwardRef,\n KeyboardEventHandler,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n useState,\n MouseEvent,\n ChangeEvent,\n ReactElement,\n createElement,\n} from 'react';\n\nimport {\n Link,\n NavLinkProps,\n resolvePath,\n useLocation,\n useResolvedPath,\n} from 'react-router-dom';\n\nimport {\n SidebarConfig,\n SidebarConfigContext,\n SidebarItemWithSubmenuContext,\n} from './config';\nimport DoubleArrowLeft from './icons/DoubleArrowLeft';\nimport DoubleArrowRight from './icons/DoubleArrowRight';\nimport { useSidebarOpenState } from './SidebarOpenStateContext';\nimport { SidebarSubmenu, SidebarSubmenuProps } from './SidebarSubmenu';\nimport { SidebarSubmenuItemProps } from './SidebarSubmenuItem';\nimport { isLocationMatch } from './utils';\nimport Button from '@material-ui/core/Button';\n\n/** @public */\nexport type SidebarItemClassKey =\n | 'root'\n | 'buttonItem'\n | 'closed'\n | 'open'\n | 'highlightable'\n | 'highlighted'\n | 'label'\n | 'iconContainer'\n | 'searchRoot'\n | 'searchField'\n | 'searchFieldHTMLInput'\n | 'searchContainer'\n | 'secondaryAction'\n | 'closedItemIcon'\n | 'submenuArrow'\n | 'expandButton'\n | 'arrows'\n | 'selected';\n\nconst makeSidebarStyles = (sidebarConfig: SidebarConfig) =>\n makeStyles(\n theme => ({\n root: {\n color: theme.palette.navigation.color,\n display: 'flex',\n flexFlow: 'row nowrap',\n alignItems: 'center',\n height: 48,\n cursor: 'pointer',\n },\n buttonItem: {\n background: 'none',\n border: 'none',\n width: '100%',\n margin: 0,\n padding: 0,\n textAlign: 'inherit',\n font: 'inherit',\n textTransform: 'none',\n },\n itemIcon: {\n display: 'inline-flex',\n fontSize: theme.typography.fontSize,\n lineHeight: 0,\n '& svg': {\n width: '1.5em',\n height: '1.5em',\n fontSize: 'inherit',\n flexShrink: 0,\n },\n },\n closed: {\n width: sidebarConfig.drawerWidthClosed,\n justifyContent: 'center',\n },\n open: {\n [theme.breakpoints.up('sm')]: {\n width: sidebarConfig.drawerWidthOpen,\n },\n },\n highlightable: {\n '&:hover': {\n background:\n theme.palette.navigation.navItem?.hoverBackground ?? '#404040',\n },\n },\n highlighted: {\n background:\n theme.palette.navigation.navItem?.hoverBackground ?? '#404040',\n },\n label: {\n // XXX (@koroeskohr): I can't seem to achieve the desired font-weight from the designs\n fontWeight: 'bold',\n whiteSpace: 'nowrap',\n lineHeight: 'auto',\n flex: '3 1 auto',\n width: '110px',\n overflow: 'hidden',\n 'text-overflow': 'ellipsis',\n },\n iconContainer: {\n boxSizing: 'border-box',\n height: '100%',\n width: sidebarConfig.iconContainerWidth,\n marginRight: -theme.spacing(2),\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n lineHeight: '0',\n },\n searchRoot: {\n marginBottom: 12,\n },\n searchField: {\n color: '#b5b5b5',\n fontWeight: theme.typography.fontWeightBold,\n fontSize: theme.typography.fontSize,\n },\n searchFieldHTMLInput: {\n padding: theme.spacing(2, 0, 2),\n },\n searchContainer: {\n width: sidebarConfig.drawerWidthOpen - sidebarConfig.iconContainerWidth,\n },\n secondaryAction: {\n width: theme.spacing(6),\n textAlign: 'center',\n marginRight: theme.spacing(1),\n },\n closedItemIcon: {\n width: '100%',\n justifyContent: 'center',\n },\n submenuArrow: {\n display: 'flex',\n },\n expandButton: {\n background: 'none',\n border: 'none',\n color: theme.palette.navigation.color,\n width: '100%',\n cursor: 'pointer',\n position: 'relative',\n height: 48,\n },\n arrows: {\n position: 'absolute',\n right: 10,\n },\n selected: {\n '&$root': {\n borderLeft: `solid ${sidebarConfig.selectedIndicatorWidth}px ${theme.palette.navigation.indicator}`,\n color: theme.palette.navigation.selectedColor,\n },\n '&$closed': {\n width: sidebarConfig.drawerWidthClosed,\n },\n '& $closedItemIcon': {\n paddingRight: sidebarConfig.selectedIndicatorWidth,\n },\n '& $iconContainer': {\n marginLeft: -sidebarConfig.selectedIndicatorWidth,\n },\n },\n }),\n { name: 'BackstageSidebarItem' },\n );\n\n// This is a workaround for this issue https://github.com/mui/material-ui/issues/15511\n// The styling of the `selected` elements doesn't work as expected when using a prop callback.\n// Don't use this pattern unless needed\nfunction useMemoStyles(sidebarConfig: SidebarConfig) {\n const useStyles = useMemo(\n () => makeSidebarStyles(sidebarConfig),\n [sidebarConfig],\n );\n return useStyles();\n}\n\n/**\n * Evaluates the routes of the SubmenuItems & nested DropdownItems.\n * The reevaluation is only triggered, if the `locationPathname` changes, as `useElementFilter` uses memorization.\n *\n * @param submenu SidebarSubmenu component\n * @param location Location\n * @returns boolean\n */\nconst useLocationMatch = (\n submenu: ReactElement<SidebarSubmenuProps>,\n location: Location,\n): boolean =>\n useElementFilter(\n submenu.props.children,\n elements => {\n let active = false;\n elements\n .getElements()\n .forEach(\n ({\n props: { to, dropdownItems },\n }: {\n props: Partial<SidebarSubmenuItemProps>;\n }) => {\n if (!active) {\n if (dropdownItems?.length) {\n dropdownItems.forEach(\n ({ to: _to }) =>\n (active =\n active || isLocationMatch(location, resolvePath(_to))),\n );\n return;\n }\n if (to) {\n active = isLocationMatch(location, resolvePath(to));\n }\n }\n },\n );\n return active;\n },\n [location.pathname],\n );\n\ntype SidebarItemBaseProps = {\n icon: IconComponent;\n text?: string;\n hasNotifications?: boolean;\n hasSubmenu?: boolean;\n disableHighlight?: boolean;\n className?: string;\n noTrack?: boolean;\n onClick?: (ev: MouseEvent) => void;\n};\n\ntype SidebarItemButtonProps = SidebarItemBaseProps & {\n onClick: (ev: MouseEvent) => void;\n children?: ReactNode;\n};\n\ntype SidebarItemLinkProps = SidebarItemBaseProps & {\n to: string;\n onClick?: (ev: MouseEvent) => void;\n} & NavLinkProps;\n\ntype SidebarItemWithSubmenuProps = SidebarItemBaseProps & {\n to?: string;\n onClick?: (ev: MouseEvent) => void;\n children: ReactNode;\n};\n\n/**\n * SidebarItem with 'to' property will be a clickable link.\n * SidebarItem with 'onClick' property and without 'to' property will be a clickable button.\n * SidebarItem which wraps a SidebarSubmenu will be a clickable button which opens a submenu.\n */\ntype SidebarItemProps =\n | SidebarItemLinkProps\n | SidebarItemButtonProps\n | SidebarItemWithSubmenuProps;\n\nfunction isButtonItem(\n props: SidebarItemProps,\n): props is SidebarItemButtonProps {\n return (props as SidebarItemLinkProps).to === undefined;\n}\n\nconst sidebarSubmenuType = createElement(SidebarSubmenu).type;\n\n// TODO(Rugvip): Remove this once NavLink is updated in react-router-dom.\n// This is needed because react-router doesn't handle the path comparison\n// properly yet, matching for example /foobar with /foo.\nexport const WorkaroundNavLink = forwardRef<\n HTMLAnchorElement,\n NavLinkProps & {\n children?: ReactNode;\n activeStyle?: CSSProperties;\n activeClassName?: string;\n }\n>(function WorkaroundNavLinkWithRef(\n {\n to,\n end,\n style,\n className,\n activeStyle,\n caseSensitive,\n activeClassName = 'active',\n 'aria-current': ariaCurrentProp = 'page',\n ...rest\n },\n ref,\n) {\n let { pathname: locationPathname } = useLocation();\n let { pathname: toPathname } = useResolvedPath(to);\n\n if (!caseSensitive) {\n locationPathname = locationPathname.toLowerCase();\n toPathname = toPathname.toLowerCase();\n }\n\n let isActive = locationPathname === toPathname;\n if (!isActive && !end) {\n // This is the behavior that is different from the original NavLink\n isActive = locationPathname.startsWith(`${toPathname}/`);\n }\n\n const ariaCurrent = isActive ? ariaCurrentProp : undefined;\n\n return (\n <Link\n {...rest}\n to={to}\n ref={ref}\n aria-current={ariaCurrent}\n style={{ ...style, ...(isActive ? activeStyle : undefined) }}\n className={classnames([\n typeof className !== 'function' ? className : undefined,\n isActive ? activeClassName : undefined,\n ])}\n />\n );\n});\n\n/**\n * Common component used by SidebarItem & SidebarItemWithSubmenu\n */\nconst SidebarItemBase = forwardRef<\n any,\n SidebarItemProps & { children: ReactNode }\n>((props, ref) => {\n const {\n icon: Icon,\n text,\n hasNotifications = false,\n hasSubmenu = false,\n disableHighlight = false,\n onClick,\n noTrack,\n children,\n className,\n ...navLinkProps\n } = props;\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const classes = useMemoStyles(sidebarConfig);\n // XXX (@koroeskohr): unsure this is optimal. But I just really didn't want to have the item component\n // depend on the current location, and at least have it being optionally forced to selected.\n // Still waiting on a Q answered to fine tune the implementation\n const { isOpen } = useSidebarOpenState();\n\n const divStyle =\n !isOpen && hasSubmenu\n ? { display: 'flex', marginLeft: '20px' }\n : { lineHeight: '0' };\n\n const displayItemIcon = (\n <Box style={divStyle}>\n <Box component=\"span\" className={classes.itemIcon}>\n <Icon fontSize=\"inherit\" />\n </Box>\n {!isOpen && hasSubmenu ? <ArrowRightIcon fontSize=\"small\" /> : <></>}\n </Box>\n );\n\n const itemIcon = (\n <Badge\n color=\"secondary\"\n variant=\"dot\"\n overlap=\"circular\"\n invisible={!hasNotifications}\n className={classnames({ [classes.closedItemIcon]: !isOpen })}\n >\n {displayItemIcon}\n </Badge>\n );\n\n const openContent = (\n <>\n <Box data-testid=\"login-button\" className={classes.iconContainer}>\n {itemIcon}\n </Box>\n {text && (\n <Typography\n variant=\"subtitle2\"\n component=\"span\"\n className={classes.label}\n >\n {text}\n </Typography>\n )}\n <div className={classes.secondaryAction}>{children}</div>\n </>\n );\n\n const content = isOpen ? openContent : itemIcon;\n\n const childProps = {\n onClick,\n className: classnames(\n className,\n classes.root,\n isOpen ? classes.open : classes.closed,\n isButtonItem(props) && classes.buttonItem,\n { [classes.highlightable]: !disableHighlight },\n ),\n };\n\n const analyticsApi = useAnalytics();\n const { pathname: to } = useResolvedPath(\n !isButtonItem(props) && props.to ? props.to : '',\n );\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLAnchorElement | HTMLButtonElement>) => {\n if (!noTrack) {\n const action = 'click';\n const subject = text ?? 'Sidebar Item';\n const options = to ? { attributes: { to } } : undefined;\n analyticsApi.captureEvent(action, subject, options);\n }\n onClick?.(event);\n },\n [analyticsApi, text, to, noTrack, onClick],\n );\n\n if (isButtonItem(props)) {\n return (\n <Button\n role=\"button\"\n aria-label={text}\n {...childProps}\n ref={ref}\n onClick={handleClick}\n >\n {content}\n </Button>\n );\n }\n\n return (\n <WorkaroundNavLink\n {...childProps}\n activeClassName={classes.selected}\n to={props.to ? props.to : ''}\n ref={ref}\n aria-label={text ? text : props.to}\n {...navLinkProps}\n onClick={handleClick}\n >\n {content}\n </WorkaroundNavLink>\n );\n});\n\nconst SidebarItemWithSubmenu = ({\n children,\n ...props\n}: SidebarItemBaseProps & {\n children: ReactElement<SidebarSubmenuProps>;\n}) => {\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const classes = useMemoStyles(sidebarConfig);\n const [isHoveredOn, setIsHoveredOn] = useState(false);\n const location = useLocation();\n const isActive = useLocationMatch(children, location);\n const isSmallScreen = useMediaQuery((theme: Theme) =>\n theme.breakpoints.down('sm'),\n );\n\n const handleMouseEnter = () => {\n setIsHoveredOn(true);\n };\n const handleMouseLeave = () => {\n setIsHoveredOn(false);\n };\n\n const arrowIcon = () => {\n if (isSmallScreen) {\n return isHoveredOn ? (\n <ArrowDropUp fontSize=\"small\" className={classes.submenuArrow} />\n ) : (\n <ArrowDropDown fontSize=\"small\" className={classes.submenuArrow} />\n );\n }\n return (\n !isHoveredOn && (\n <ArrowRightIcon fontSize=\"small\" className={classes.submenuArrow} />\n )\n );\n };\n\n return (\n <SidebarItemWithSubmenuContext.Provider\n value={{\n isHoveredOn,\n setIsHoveredOn,\n }}\n >\n <div\n data-testid=\"item-with-submenu\"\n onMouseLeave={handleMouseLeave}\n onTouchStart={isHoveredOn ? handleMouseLeave : handleMouseEnter}\n onMouseEnter={handleMouseEnter}\n className={classnames(isHoveredOn && classes.highlighted)}\n >\n <SidebarItemBase\n hasSubmenu\n className={isActive ? classes.selected : ''}\n {...props}\n >\n {arrowIcon()}\n </SidebarItemBase>\n {isHoveredOn && children}\n </div>\n </SidebarItemWithSubmenuContext.Provider>\n );\n};\n\n/**\n * Creates a `SidebarItem`\n *\n * @remarks\n * If children contain a `SidebarSubmenu` component the `SidebarItem` will have a expandable submenu\n */\nexport const SidebarItem = forwardRef<\n any,\n SidebarItemProps & { children: ReactNode }\n>((props, ref) => {\n // Filter children for SidebarSubmenu components\n const [submenu] = useElementFilter(props.children, elements =>\n // Directly comparing child.type with SidebarSubmenu will not work with in\n // combination with react-hot-loader\n //\n // https://github.com/gaearon/react-hot-loader/issues/304#issuecomment-456569720\n elements.getElements().filter(child => child.type === sidebarSubmenuType),\n );\n\n if (submenu) {\n return (\n <SidebarItemWithSubmenu {...props}>\n {submenu as ReactElement<SidebarSubmenuProps>}\n </SidebarItemWithSubmenu>\n );\n }\n\n return <SidebarItemBase {...props} ref={ref} />;\n}) as (props: SidebarItemProps) => JSX.Element;\n\ntype SidebarSearchFieldProps = {\n onSearch: (input: string) => void;\n to?: string;\n icon?: IconComponent;\n};\n\nexport function SidebarSearchField(props: SidebarSearchFieldProps) {\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const [input, setInput] = useState('');\n const classes = useMemoStyles(sidebarConfig);\n const Icon = props.icon ? props.icon : SearchIcon;\n\n const search = () => {\n props.onSearch(input);\n setInput('');\n };\n\n const handleEnter: KeyboardEventHandler = ev => {\n if (ev.key === 'Enter') {\n ev.preventDefault();\n search();\n }\n };\n\n const handleInput = (ev: ChangeEvent<HTMLInputElement>) => {\n setInput(ev.target.value);\n };\n\n const handleInputClick = (ev: MouseEvent<HTMLInputElement>) => {\n // Clicking into the search fields shouldn't navigate to the search page\n ev.preventDefault();\n ev.stopPropagation();\n };\n\n const handleItemClick = (ev: MouseEvent) => {\n // Clicking on the search icon while should execute a query with the current field content\n search();\n ev.preventDefault();\n };\n\n return (\n <Box className={classes.searchRoot}>\n <SidebarItem\n icon={Icon}\n to={props.to}\n onClick={handleItemClick}\n disableHighlight\n >\n <TextField\n placeholder=\"Search\"\n value={input}\n onClick={handleInputClick}\n onChange={handleInput}\n onKeyDown={handleEnter}\n className={classes.searchContainer}\n InputProps={{\n disableUnderline: true,\n className: classes.searchField,\n }}\n inputProps={{\n className: classes.searchFieldHTMLInput,\n }}\n />\n </SidebarItem>\n </Box>\n );\n}\n\nexport type SidebarSpaceClassKey = 'root';\n\nexport const SidebarSpace = styled('div')(\n {\n flex: 1,\n },\n { name: 'BackstageSidebarSpace' },\n) as ComponentType<ComponentProps<'div'> & StyledComponentProps<'root'>>;\n\nexport type SidebarSpacerClassKey = 'root';\n\nexport const SidebarSpacer = styled('div')(\n {\n height: 8,\n },\n { name: 'BackstageSidebarSpacer' },\n) as ComponentType<ComponentProps<'div'> & StyledComponentProps<'root'>>;\n\nexport type SidebarDividerClassKey = 'root';\n\nexport const SidebarDivider = styled('hr')(\n ({ theme }) => ({\n height: 1,\n width: '100%',\n background: '#383838',\n border: 'none',\n margin: theme.spacing(1.2, 0),\n }),\n { name: 'BackstageSidebarDivider' },\n) as ComponentType<ComponentProps<'hr'> & StyledComponentProps<'root'>>;\n\nconst styledScrollbar = (theme: Theme): CreateCSSProperties => ({\n overflowY: 'auto',\n '&::-webkit-scrollbar': {\n backgroundColor: theme.palette.background.default,\n width: '5px',\n borderRadius: '5px',\n },\n '&::-webkit-scrollbar-thumb': {\n backgroundColor: theme.palette.text.secondary,\n borderRadius: '5px',\n },\n});\n\nexport const SidebarScrollWrapper = styled('div')(({ theme }) => {\n const scrollbarStyles = styledScrollbar(theme);\n return {\n flex: '0 1 auto',\n overflowX: 'hidden',\n width: '100%',\n // Display at least one item in the container\n // Question: Can this be a config/theme variable - if so, which? :/\n minHeight: '48px',\n overflowY: 'hidden',\n '@media (hover: none)': scrollbarStyles,\n '&:hover': scrollbarStyles,\n };\n}) as ComponentType<ComponentProps<'div'> & StyledComponentProps<'root'>>;\n\n/**\n * A button which allows you to expand the sidebar when clicked.\n *\n * @remarks\n * Use optionally to replace sidebar's expand-on-hover feature with expand-on-click.\n *\n * If you are using this you might want to set the `disableExpandOnHover` of the `Sidebar` to `true`.\n *\n * @public\n */\nexport const SidebarExpandButton = () => {\n const { sidebarConfig } = useContext(SidebarConfigContext);\n const classes = useMemoStyles(sidebarConfig);\n const { isOpen, setOpen } = useSidebarOpenState();\n const isSmallScreen = useMediaQuery<Theme>(\n theme => theme.breakpoints.down('md'),\n { noSsr: true },\n );\n\n if (isSmallScreen) {\n return null;\n }\n\n const handleClick = () => {\n setOpen(!isOpen);\n };\n\n return (\n <Button\n role=\"button\"\n onClick={handleClick}\n className={classes.expandButton}\n aria-label=\"Expand Sidebar\"\n data-testid=\"sidebar-expand-button\"\n >\n <Box className={classes.arrows}>\n {isOpen ? <DoubleArrowLeft /> : <DoubleArrowRight />}\n </Box>\n </Button>\n );\n};\n"],"names":["classnames","ArrowDropUp","ArrowDropDown","SearchIcon"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/core-components",
3
- "version": "0.18.14-next.1",
3
+ "version": "0.18.14",
4
4
  "description": "Core components used by Backstage plugins and apps",
5
5
  "backstage": {
6
6
  "role": "web-library"
@@ -66,12 +66,12 @@
66
66
  "test": "backstage-cli package test"
67
67
  },
68
68
  "dependencies": {
69
- "@backstage/config": "1.3.8",
70
- "@backstage/core-plugin-api": "1.12.10-next.0",
71
- "@backstage/errors": "1.3.1",
72
- "@backstage/theme": "0.7.3",
73
- "@backstage/ui": "0.18.0-next.1",
74
- "@backstage/version-bridge": "1.0.12",
69
+ "@backstage/config": "^1.3.9",
70
+ "@backstage/core-plugin-api": "^1.12.10",
71
+ "@backstage/errors": "^1.3.1",
72
+ "@backstage/theme": "^0.7.3",
73
+ "@backstage/ui": "^0.18.0",
74
+ "@backstage/version-bridge": "^1.0.12",
75
75
  "@dagrejs/dagre": "^1.1.4",
76
76
  "@date-io/core": "^1.3.13",
77
77
  "@material-table/core": "^3.1.0",
@@ -88,7 +88,7 @@
88
88
  "d3-selection": "^3.0.0",
89
89
  "d3-shape": "^3.0.0",
90
90
  "d3-zoom": "^3.0.0",
91
- "js-yaml": "^4.3.0",
91
+ "js-yaml": "^4.3.2",
92
92
  "linkify-react": "4.3.2",
93
93
  "linkifyjs": "4.3.2",
94
94
  "lodash": "^4.17.21",
@@ -98,7 +98,7 @@
98
98
  "react-full-screen": "^1.1.1",
99
99
  "react-helmet": "6.1.0",
100
100
  "react-hook-form": "^7.12.2",
101
- "react-idle-timer": "5.7.2",
101
+ "react-idle-timer": "5.7.3",
102
102
  "react-markdown": "^8.0.0",
103
103
  "react-sparklines": "^1.7.0",
104
104
  "react-syntax-highlighter": "^15.4.5",
@@ -112,10 +112,10 @@
112
112
  "zod": "^3.25.76 || ^4.0.0"
113
113
  },
114
114
  "devDependencies": {
115
- "@backstage/app-defaults": "1.7.12-next.1",
116
- "@backstage/cli": "0.36.6-next.0",
117
- "@backstage/core-app-api": "1.20.5-next.1",
118
- "@backstage/test-utils": "1.7.22-next.1",
115
+ "@backstage/app-defaults": "^1.7.12",
116
+ "@backstage/cli": "^0.36.6",
117
+ "@backstage/core-app-api": "^1.20.5",
118
+ "@backstage/test-utils": "^1.7.22",
119
119
  "@testing-library/jest-dom": "^6.0.0",
120
120
  "@testing-library/user-event": "^14.0.0",
121
121
  "@types/ansi-regex": "^5.0.0",