@red-hat-developer-hub/backstage-plugin-global-floating-action-button 0.0.1 → 0.0.2

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,12 @@
1
1
  # @red-hat-developer-hub/backstage-plugin-global-floating-action-button
2
2
 
3
+ ## 0.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 37af2c4: align page-end floating action buttons to the right page when expanded
8
+ - 09dfb9d: Updated dependency `@mui/styles` to `5.16.13`.
9
+
3
10
  ## 0.0.1
4
11
 
5
12
  ### Patch Changes
package/README.md CHANGED
@@ -22,7 +22,10 @@ This plugin has been added to the example app in this workspace, meaning it can
22
22
 
23
23
  ```tsx title="packages/app/src/components/Root/Root.tsx"
24
24
  /* highlight-add-next-line */
25
- import { GlobalFloatingButton } from '@red-hat-developer-hub/backstage-plugin-global-floating-action-button';
25
+ import {
26
+ GlobalFloatingButton,
27
+ Slot,
28
+ } from '@red-hat-developer-hub/backstage-plugin-global-floating-action-button';
26
29
 
27
30
  export const Root = ({ children }: PropsWithChildren<{}>) => (
28
31
  <SidebarPage>
@@ -37,11 +40,11 @@ This plugin has been added to the example app in this workspace, meaning it can
37
40
  to: '/create',
38
41
  },
39
42
  {
43
+ slot: Slot.BOTTOM_CENTER,
40
44
  icon: <LibraryBooks />,
41
45
  label: 'Docs',
42
46
  toolTip: 'Docs',
43
47
  to: '/docs',
44
- position: 'bottom-center',
45
48
  },
46
49
  ]}
47
50
  />
@@ -33,7 +33,7 @@ const FAB = ({
33
33
  ...external ? { href: actionButton.to } : {}
34
34
  },
35
35
  actionButton.icon && /* @__PURE__ */ React.createElement(FabIcon, { icon: actionButton.icon }),
36
- (actionButton.showLabel || !actionButton.icon) && /* @__PURE__ */ React.createElement(Typography, { sx: { ml: 1 } }, actionButton.label)
36
+ (actionButton.showLabel || !actionButton.icon) && /* @__PURE__ */ React.createElement(Typography, { sx: actionButton.icon ? { ml: 1 } : {} }, actionButton.label)
37
37
  ))
38
38
  );
39
39
  };
@@ -1 +1 @@
1
- {"version":3,"file":"FAB.esm.js","sources":["../../src/components/FAB.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 * as React from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport Fab from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { FabIcon } from './FabIcon';\nimport { FloatingActionButton, Slot } from '../types';\n\nexport const FAB = ({\n actionButton,\n size,\n}: {\n actionButton: FloatingActionButton;\n size?: 'small' | 'medium' | 'large';\n}) => {\n const navigate = useNavigate();\n const isExternalUri = (uri: string) => /^([a-z+.-]+):/.test(uri);\n const external = isExternalUri(actionButton.to!);\n const newWindow = external && !!/^https?:/.exec(actionButton.to!);\n const navigateTo = () =>\n actionButton.to && !external ? navigate(actionButton.to) : '';\n return (\n <Tooltip\n title={actionButton.toolTip}\n placement={Slot.PAGE_END ? 'left' : 'right'}\n >\n <div>\n <Fab\n {...(newWindow ? { target: '_blank', rel: 'noopener' } : {})}\n variant={\n actionButton.showLabel || !actionButton.icon\n ? 'extended'\n : 'circular'\n }\n size={size || actionButton.size || 'medium'}\n color={actionButton.color || 'default'}\n aria-label={actionButton.label}\n onClick={actionButton.onClick || navigateTo}\n {...(external ? { href: actionButton.to } : {})}\n >\n {actionButton.icon && <FabIcon icon={actionButton.icon} />}\n {(actionButton.showLabel || !actionButton.icon) && (\n <Typography sx={{ ml: 1 }}>{actionButton.label}</Typography>\n )}\n </Fab>\n </div>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAwBO,MAAM,MAAM,CAAC;AAAA,EAClB,YAAA;AAAA,EACA;AACF,CAGM,KAAA;AACJ,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAA,MAAM,aAAgB,GAAA,CAAC,GAAgB,KAAA,eAAA,CAAgB,KAAK,GAAG,CAAA;AAC/D,EAAM,MAAA,QAAA,GAAW,aAAc,CAAA,YAAA,CAAa,EAAG,CAAA;AAC/C,EAAA,MAAM,YAAY,QAAY,IAAA,CAAC,CAAC,UAAW,CAAA,IAAA,CAAK,aAAa,EAAG,CAAA;AAChE,EAAM,MAAA,UAAA,GAAa,MACjB,YAAa,CAAA,EAAA,IAAM,CAAC,QAAW,GAAA,QAAA,CAAS,YAAa,CAAA,EAAE,CAAI,GAAA,EAAA;AAC7D,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,OAAO,YAAa,CAAA,OAAA;AAAA,MACpB,SAAA,EAAW,IAAK,CAAA,QAAA,GAAW,MAAS,GAAA;AAAA,KAAA;AAAA,wCAEnC,KACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACE,GAAI,YAAY,EAAE,MAAA,EAAQ,UAAU,GAAK,EAAA,UAAA,KAAe,EAAC;AAAA,QAC1D,SACE,YAAa,CAAA,SAAA,IAAa,CAAC,YAAA,CAAa,OACpC,UACA,GAAA,UAAA;AAAA,QAEN,IAAA,EAAM,IAAQ,IAAA,YAAA,CAAa,IAAQ,IAAA,QAAA;AAAA,QACnC,KAAA,EAAO,aAAa,KAAS,IAAA,SAAA;AAAA,QAC7B,cAAY,YAAa,CAAA,KAAA;AAAA,QACzB,OAAA,EAAS,aAAa,OAAW,IAAA,UAAA;AAAA,QAChC,GAAI,QAAW,GAAA,EAAE,MAAM,YAAa,CAAA,EAAA,KAAO;AAAC,OAAA;AAAA,MAE5C,aAAa,IAAQ,oBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,IAAA,EAAM,aAAa,IAAM,EAAA,CAAA;AAAA,MAAA,CACtD,YAAa,CAAA,SAAA,IAAa,CAAC,YAAA,CAAa,IACxC,qBAAA,KAAA,CAAA,aAAA,CAAC,UAAW,EAAA,EAAA,EAAA,EAAI,EAAE,EAAA,EAAI,CAAE,EAAA,EAAA,EAAI,aAAa,KAAM;AAAA,KAGrD;AAAA,GACF;AAEJ;;;;"}
1
+ {"version":3,"file":"FAB.esm.js","sources":["../../src/components/FAB.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 * as React from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport Fab from '@mui/material/Fab';\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { FabIcon } from './FabIcon';\nimport { FloatingActionButton, Slot } from '../types';\n\nexport const FAB = ({\n actionButton,\n size,\n}: {\n actionButton: FloatingActionButton;\n size?: 'small' | 'medium' | 'large';\n}) => {\n const navigate = useNavigate();\n const isExternalUri = (uri: string) => /^([a-z+.-]+):/.test(uri);\n const external = isExternalUri(actionButton.to!);\n const newWindow = external && !!/^https?:/.exec(actionButton.to!);\n const navigateTo = () =>\n actionButton.to && !external ? navigate(actionButton.to) : '';\n return (\n <Tooltip\n title={actionButton.toolTip}\n placement={Slot.PAGE_END ? 'left' : 'right'}\n >\n <div>\n <Fab\n {...(newWindow ? { target: '_blank', rel: 'noopener' } : {})}\n variant={\n actionButton.showLabel || !actionButton.icon\n ? 'extended'\n : 'circular'\n }\n size={size || actionButton.size || 'medium'}\n color={actionButton.color || 'default'}\n aria-label={actionButton.label}\n onClick={actionButton.onClick || navigateTo}\n {...(external ? { href: actionButton.to } : {})}\n >\n {actionButton.icon && <FabIcon icon={actionButton.icon} />}\n {(actionButton.showLabel || !actionButton.icon) && (\n <Typography sx={actionButton.icon ? { ml: 1 } : {}}>\n {actionButton.label}\n </Typography>\n )}\n </Fab>\n </div>\n </Tooltip>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AAwBO,MAAM,MAAM,CAAC;AAAA,EAClB,YAAA;AAAA,EACA;AACF,CAGM,KAAA;AACJ,EAAA,MAAM,WAAW,WAAY,EAAA;AAC7B,EAAA,MAAM,aAAgB,GAAA,CAAC,GAAgB,KAAA,eAAA,CAAgB,KAAK,GAAG,CAAA;AAC/D,EAAM,MAAA,QAAA,GAAW,aAAc,CAAA,YAAA,CAAa,EAAG,CAAA;AAC/C,EAAA,MAAM,YAAY,QAAY,IAAA,CAAC,CAAC,UAAW,CAAA,IAAA,CAAK,aAAa,EAAG,CAAA;AAChE,EAAM,MAAA,UAAA,GAAa,MACjB,YAAa,CAAA,EAAA,IAAM,CAAC,QAAW,GAAA,QAAA,CAAS,YAAa,CAAA,EAAE,CAAI,GAAA,EAAA;AAC7D,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,OAAO,YAAa,CAAA,OAAA;AAAA,MACpB,SAAA,EAAW,IAAK,CAAA,QAAA,GAAW,MAAS,GAAA;AAAA,KAAA;AAAA,wCAEnC,KACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACE,GAAI,YAAY,EAAE,MAAA,EAAQ,UAAU,GAAK,EAAA,UAAA,KAAe,EAAC;AAAA,QAC1D,SACE,YAAa,CAAA,SAAA,IAAa,CAAC,YAAA,CAAa,OACpC,UACA,GAAA,UAAA;AAAA,QAEN,IAAA,EAAM,IAAQ,IAAA,YAAA,CAAa,IAAQ,IAAA,QAAA;AAAA,QACnC,KAAA,EAAO,aAAa,KAAS,IAAA,SAAA;AAAA,QAC7B,cAAY,YAAa,CAAA,KAAA;AAAA,QACzB,OAAA,EAAS,aAAa,OAAW,IAAA,UAAA;AAAA,QAChC,GAAI,QAAW,GAAA,EAAE,MAAM,YAAa,CAAA,EAAA,KAAO;AAAC,OAAA;AAAA,MAE5C,aAAa,IAAQ,oBAAA,KAAA,CAAA,aAAA,CAAC,OAAQ,EAAA,EAAA,IAAA,EAAM,aAAa,IAAM,EAAA,CAAA;AAAA,MAAA,CACtD,aAAa,SAAa,IAAA,CAAC,YAAa,CAAA,IAAA,yCACvC,UAAW,EAAA,EAAA,EAAA,EAAI,YAAa,CAAA,IAAA,GAAO,EAAE,EAAI,EAAA,CAAA,KAAM,EAAC,EAAA,EAC9C,aAAa,KAChB;AAAA,KAGN;AAAA,GACF;AAEJ;;;;"}
@@ -16,16 +16,18 @@ const useStyles = makeStyles((theme) => ({
16
16
  },
17
17
  "page-end": {
18
18
  bottom: theme.spacing(4),
19
- right: theme.spacing(4)
19
+ right: theme.spacing(4),
20
+ alignItems: "end"
20
21
  },
21
22
  "bottom-center": {
22
23
  bottom: theme.spacing(4),
23
- left: "50%"
24
+ left: "50%",
25
+ alignItems: "center"
24
26
  }
25
27
  }));
26
28
  const FloatingButton = ({
27
29
  floatingButtons,
28
- position
30
+ slot
29
31
  }) => {
30
32
  const { pathname } = useLocation();
31
33
  const subMenuRef = React.useRef(null);
@@ -53,9 +55,9 @@ const FloatingButton = ({
53
55
  return /* @__PURE__ */ React.createElement(
54
56
  "div",
55
57
  {
56
- className: classnames(fabButton.button, fabButton[position]),
58
+ className: classnames(fabButton.button, fabButton[slot]),
57
59
  style: {
58
- flexDirection: subMenuDirection || "column-reverse"
60
+ flexDirection: subMenuDirection
59
61
  },
60
62
  id: "floating-button",
61
63
  "data-testId": "floating-button",
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingButton.esm.js","sources":["../../src/components/FloatingButton.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport classnames from 'classnames';\n\nimport { makeStyles } from '@mui/styles';\nimport { FABWithSubmenu } from './FABWithSubmenu';\nimport { FAB } from './FAB';\nimport { FlexDirection, FloatingActionButton, Slot } from '../types';\nimport { filterAndSortButtons } from '../utils';\n\nconst useStyles = makeStyles(theme => ({\n button: {\n zIndex: 200,\n display: 'flex',\n position: 'fixed',\n maxWidth: '150px',\n gap: '10px',\n },\n 'page-end': {\n bottom: theme.spacing(4),\n right: theme.spacing(4),\n },\n 'bottom-center': {\n bottom: theme.spacing(4),\n left: '50%',\n },\n}));\n\nexport const FloatingButton = ({\n floatingButtons,\n position,\n}: {\n floatingButtons: FloatingActionButton[];\n position: Slot;\n}) => {\n const { pathname } = useLocation();\n const subMenuRef = React.useRef<HTMLDivElement>(null);\n const [subMenuDirection, setSubMenuDirection] =\n React.useState<FlexDirection>('column');\n const fabButton = useStyles();\n\n React.useEffect(() => {\n const floatingButtonElement = document.getElementById('floating-button');\n const screenHeight = window.innerHeight;\n if (floatingButtonElement) {\n const { top } = floatingButtonElement?.getBoundingClientRect();\n if (top < screenHeight / 2) {\n setSubMenuDirection('column');\n } else {\n setSubMenuDirection('column-reverse');\n }\n }\n }, [pathname]);\n\n const fabs = React.useMemo(\n () => filterAndSortButtons(floatingButtons, pathname),\n [floatingButtons, pathname],\n );\n\n if (fabs?.length === 0) {\n return null;\n }\n return (\n <div\n className={classnames(fabButton.button, fabButton[position])}\n style={{\n flexDirection: subMenuDirection || 'column-reverse',\n }}\n id=\"floating-button\"\n data-testId=\"floating-button\"\n ref={subMenuRef}\n >\n {fabs.length > 1 ? (\n <FABWithSubmenu fabs={fabs} ref={subMenuRef.current} />\n ) : (\n <FAB actionButton={fabs[0]} />\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA0BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA,GAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,OAAA;AAAA,IACV,QAAU,EAAA,OAAA;AAAA,IACV,GAAK,EAAA;AAAA,GACP;AAAA,EACA,UAAY,EAAA;AAAA,IACV,MAAA,EAAQ,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACvB,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,CAAC;AAAA,GACxB;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,MAAA,EAAQ,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACvB,IAAM,EAAA;AAAA;AAEV,CAAE,CAAA,CAAA;AAEK,MAAM,iBAAiB,CAAC;AAAA,EAC7B,eAAA;AAAA,EACA;AACF,CAGM,KAAA;AACJ,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,WAAY,EAAA;AACjC,EAAM,MAAA,UAAA,GAAa,KAAM,CAAA,MAAA,CAAuB,IAAI,CAAA;AACpD,EAAA,MAAM,CAAC,gBAAkB,EAAA,mBAAmB,CAC1C,GAAA,KAAA,CAAM,SAAwB,QAAQ,CAAA;AACxC,EAAA,MAAM,YAAY,SAAU,EAAA;AAE5B,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAM,MAAA,qBAAA,GAAwB,QAAS,CAAA,cAAA,CAAe,iBAAiB,CAAA;AACvE,IAAA,MAAM,eAAe,MAAO,CAAA,WAAA;AAC5B,IAAA,IAAI,qBAAuB,EAAA;AACzB,MAAA,MAAM,EAAE,GAAA,EAAQ,GAAA,qBAAA,EAAuB,qBAAsB,EAAA;AAC7D,MAAI,IAAA,GAAA,GAAM,eAAe,CAAG,EAAA;AAC1B,QAAA,mBAAA,CAAoB,QAAQ,CAAA;AAAA,OACvB,MAAA;AACL,QAAA,mBAAA,CAAoB,gBAAgB,CAAA;AAAA;AACtC;AACF,GACF,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,OAAO,KAAM,CAAA,OAAA;AAAA,IACjB,MAAM,oBAAqB,CAAA,eAAA,EAAiB,QAAQ,CAAA;AAAA,IACpD,CAAC,iBAAiB,QAAQ;AAAA,GAC5B;AAEA,EAAI,IAAA,IAAA,EAAM,WAAW,CAAG,EAAA;AACtB,IAAO,OAAA,IAAA;AAAA;AAET,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAW,UAAW,CAAA,SAAA,CAAU,MAAQ,EAAA,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,MAC3D,KAAO,EAAA;AAAA,QACL,eAAe,gBAAoB,IAAA;AAAA,OACrC;AAAA,MACA,EAAG,EAAA,iBAAA;AAAA,MACH,aAAY,EAAA,iBAAA;AAAA,MACZ,GAAK,EAAA;AAAA,KAAA;AAAA,IAEJ,IAAK,CAAA,MAAA,GAAS,CACb,mBAAA,KAAA,CAAA,aAAA,CAAC,kBAAe,IAAY,EAAA,GAAA,EAAK,UAAW,CAAA,OAAA,EAAS,oBAEpD,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,YAAc,EAAA,IAAA,CAAK,CAAC,CAAG,EAAA;AAAA,GAEhC;AAEJ;;;;"}
1
+ {"version":3,"file":"FloatingButton.esm.js","sources":["../../src/components/FloatingButton.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 * as React from 'react';\nimport { useLocation } from 'react-router-dom';\nimport classnames from 'classnames';\n\nimport { makeStyles } from '@mui/styles';\nimport { FABWithSubmenu } from './FABWithSubmenu';\nimport { FAB } from './FAB';\nimport { FloatingActionButton, Slot } from '../types';\nimport { filterAndSortButtons } from '../utils';\n\nconst useStyles = makeStyles(theme => ({\n button: {\n zIndex: 200,\n display: 'flex',\n position: 'fixed',\n maxWidth: '150px',\n gap: '10px',\n },\n 'page-end': {\n bottom: theme.spacing(4),\n right: theme.spacing(4),\n alignItems: 'end',\n },\n 'bottom-center': {\n bottom: theme.spacing(4),\n left: '50%',\n alignItems: 'center',\n },\n}));\n\nexport const FloatingButton = ({\n floatingButtons,\n slot,\n}: {\n floatingButtons: FloatingActionButton[];\n slot: Slot;\n}) => {\n const { pathname } = useLocation();\n const subMenuRef = React.useRef<HTMLDivElement>(null);\n const [subMenuDirection, setSubMenuDirection] = React.useState<\n 'column' | 'column-reverse'\n >('column');\n const fabButton = useStyles();\n\n React.useEffect(() => {\n const floatingButtonElement = document.getElementById('floating-button');\n const screenHeight = window.innerHeight;\n if (floatingButtonElement) {\n const { top } = floatingButtonElement?.getBoundingClientRect();\n if (top < screenHeight / 2) {\n setSubMenuDirection('column');\n } else {\n setSubMenuDirection('column-reverse');\n }\n }\n }, [pathname]);\n\n const fabs = React.useMemo(\n () => filterAndSortButtons(floatingButtons, pathname),\n [floatingButtons, pathname],\n );\n\n if (fabs?.length === 0) {\n return null;\n }\n return (\n <div\n className={classnames(fabButton.button, fabButton[slot])}\n style={{\n flexDirection: subMenuDirection,\n }}\n id=\"floating-button\"\n data-testId=\"floating-button\"\n ref={subMenuRef}\n >\n {fabs.length > 1 ? (\n <FABWithSubmenu fabs={fabs} ref={subMenuRef.current} />\n ) : (\n <FAB actionButton={fabs[0]} />\n )}\n </div>\n );\n};\n"],"names":[],"mappings":";;;;;;;;AA0BA,MAAM,SAAA,GAAY,WAAW,CAAU,KAAA,MAAA;AAAA,EACrC,MAAQ,EAAA;AAAA,IACN,MAAQ,EAAA,GAAA;AAAA,IACR,OAAS,EAAA,MAAA;AAAA,IACT,QAAU,EAAA,OAAA;AAAA,IACV,QAAU,EAAA,OAAA;AAAA,IACV,GAAK,EAAA;AAAA,GACP;AAAA,EACA,UAAY,EAAA;AAAA,IACV,MAAA,EAAQ,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACvB,KAAA,EAAO,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACtB,UAAY,EAAA;AAAA,GACd;AAAA,EACA,eAAiB,EAAA;AAAA,IACf,MAAA,EAAQ,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,IACvB,IAAM,EAAA,KAAA;AAAA,IACN,UAAY,EAAA;AAAA;AAEhB,CAAE,CAAA,CAAA;AAEK,MAAM,iBAAiB,CAAC;AAAA,EAC7B,eAAA;AAAA,EACA;AACF,CAGM,KAAA;AACJ,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,WAAY,EAAA;AACjC,EAAM,MAAA,UAAA,GAAa,KAAM,CAAA,MAAA,CAAuB,IAAI,CAAA;AACpD,EAAA,MAAM,CAAC,gBAAkB,EAAA,mBAAmB,CAAI,GAAA,KAAA,CAAM,SAEpD,QAAQ,CAAA;AACV,EAAA,MAAM,YAAY,SAAU,EAAA;AAE5B,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAM,MAAA,qBAAA,GAAwB,QAAS,CAAA,cAAA,CAAe,iBAAiB,CAAA;AACvE,IAAA,MAAM,eAAe,MAAO,CAAA,WAAA;AAC5B,IAAA,IAAI,qBAAuB,EAAA;AACzB,MAAA,MAAM,EAAE,GAAA,EAAQ,GAAA,qBAAA,EAAuB,qBAAsB,EAAA;AAC7D,MAAI,IAAA,GAAA,GAAM,eAAe,CAAG,EAAA;AAC1B,QAAA,mBAAA,CAAoB,QAAQ,CAAA;AAAA,OACvB,MAAA;AACL,QAAA,mBAAA,CAAoB,gBAAgB,CAAA;AAAA;AACtC;AACF,GACF,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,OAAO,KAAM,CAAA,OAAA;AAAA,IACjB,MAAM,oBAAqB,CAAA,eAAA,EAAiB,QAAQ,CAAA;AAAA,IACpD,CAAC,iBAAiB,QAAQ;AAAA,GAC5B;AAEA,EAAI,IAAA,IAAA,EAAM,WAAW,CAAG,EAAA;AACtB,IAAO,OAAA,IAAA;AAAA;AAET,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAW,UAAW,CAAA,SAAA,CAAU,MAAQ,EAAA,SAAA,CAAU,IAAI,CAAC,CAAA;AAAA,MACvD,KAAO,EAAA;AAAA,QACL,aAAe,EAAA;AAAA,OACjB;AAAA,MACA,EAAG,EAAA,iBAAA;AAAA,MACH,aAAY,EAAA,iBAAA;AAAA,MACZ,GAAK,EAAA;AAAA,KAAA;AAAA,IAEJ,IAAK,CAAA,MAAA,GAAS,CACb,mBAAA,KAAA,CAAA,aAAA,CAAC,kBAAe,IAAY,EAAA,GAAA,EAAK,UAAW,CAAA,OAAA,EAAS,oBAEpD,KAAA,CAAA,aAAA,CAAA,GAAA,EAAA,EAAI,YAAc,EAAA,IAAA,CAAK,CAAC,CAAG,EAAA;AAAA,GAEhC;AAEJ;;;;"}
@@ -6,7 +6,14 @@ const GlobalFloatingActionButton = ({
6
6
  floatingButtons
7
7
  }) => {
8
8
  const floatingButtonMap = evaluateFloatingButtonsWithPositions(floatingButtons);
9
- return /* @__PURE__ */ React.createElement(React.Fragment, null, floatingButtonMap.map((fb) => /* @__PURE__ */ React.createElement(FloatingButton, { position: fb.slot, floatingButtons: fb.actions })));
9
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, floatingButtonMap.map((fb) => /* @__PURE__ */ React.createElement(
10
+ FloatingButton,
11
+ {
12
+ key: fb.slot,
13
+ slot: fb.slot,
14
+ floatingButtons: fb.actions
15
+ }
16
+ )));
10
17
  };
11
18
 
12
19
  export { GlobalFloatingActionButton };
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalFloatingActionButton.esm.js","sources":["../../src/components/GlobalFloatingActionButton.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 * as React from 'react';\nimport { FloatingActionButton } from '../types';\nimport { evaluateFloatingButtonsWithPositions } from '../utils';\nimport { FloatingButton } from './FloatingButton';\n\nexport const GlobalFloatingActionButton = ({\n floatingButtons,\n}: {\n floatingButtons: FloatingActionButton[];\n}) => {\n const floatingButtonMap =\n evaluateFloatingButtonsWithPositions(floatingButtons);\n\n return (\n <>\n {floatingButtonMap.map(fb => (\n <FloatingButton position={fb.slot} floatingButtons={fb.actions} />\n ))}\n </>\n );\n};\n"],"names":[],"mappings":";;;;AAoBO,MAAM,6BAA6B,CAAC;AAAA,EACzC;AACF,CAEM,KAAA;AACJ,EAAM,MAAA,iBAAA,GACJ,qCAAqC,eAAe,CAAA;AAEtD,EAAA,uBAEK,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EAAA,iBAAA,CAAkB,GAAI,CAAA,CAAA,EAAA,qBACpB,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA,EAAe,QAAU,EAAA,EAAA,CAAG,IAAM,EAAA,eAAA,EAAiB,EAAG,CAAA,OAAA,EAAS,CACjE,CACH,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"GlobalFloatingActionButton.esm.js","sources":["../../src/components/GlobalFloatingActionButton.tsx"],"sourcesContent":["/*\n * Copyright 2025 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 * as React from 'react';\nimport { FloatingActionButton } from '../types';\nimport { evaluateFloatingButtonsWithPositions } from '../utils';\nimport { FloatingButton } from './FloatingButton';\n\nexport const GlobalFloatingActionButton = ({\n floatingButtons,\n}: {\n floatingButtons: FloatingActionButton[];\n}) => {\n const floatingButtonMap =\n evaluateFloatingButtonsWithPositions(floatingButtons);\n\n return (\n <>\n {floatingButtonMap.map(fb => (\n <FloatingButton\n key={fb.slot}\n slot={fb.slot}\n floatingButtons={fb.actions}\n />\n ))}\n </>\n );\n};\n"],"names":[],"mappings":";;;;AAoBO,MAAM,6BAA6B,CAAC;AAAA,EACzC;AACF,CAEM,KAAA;AACJ,EAAM,MAAA,iBAAA,GACJ,qCAAqC,eAAe,CAAA;AAEtD,EACE,uBAAA,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACG,iBAAkB,CAAA,GAAA,CAAI,CACrB,EAAA,qBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,cAAA;AAAA,IAAA;AAAA,MACC,KAAK,EAAG,CAAA,IAAA;AAAA,MACR,MAAM,EAAG,CAAA,IAAA;AAAA,MACT,iBAAiB,EAAG,CAAA;AAAA;AAAA,GAEvB,CACH,CAAA;AAEJ;;;;"}
package/dist/index.d.ts CHANGED
@@ -3,8 +3,9 @@ import * as react from 'react';
3
3
  import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
4
4
 
5
5
  /**
6
- * @public
7
6
  * Slot
7
+ *
8
+ * @public
8
9
  */
9
10
  declare enum Slot {
10
11
  /**
@@ -17,28 +18,16 @@ declare enum Slot {
17
18
  BOTTOM_CENTER = "bottom-center"
18
19
  }
19
20
  /**
20
- * @public
21
- * Floating Action Button With Positions
22
- */
23
- type FloatingActionButtonWithPositions = Array<{
24
- slot: Slot;
25
- actions: FloatingActionButton[];
26
- }>;
27
- /**
28
- * @public
29
- * Flex Direction
30
- */
31
- type FlexDirection = 'row' | 'row-reverse' | 'column' | 'column-reverse';
32
- /**
33
- * @public
34
21
  * Floating Action Button
22
+ *
23
+ * @public
35
24
  */
36
25
  type FloatingActionButton = {
26
+ slot?: Slot;
37
27
  label: string;
38
28
  showLabel?: boolean;
39
29
  icon?: string | React.ReactElement;
40
30
  size?: 'small' | 'medium' | 'large';
41
- position?: Slot | string;
42
31
  color?: 'default' | 'error' | 'info' | 'inherit' | 'primary' | 'secondary' | 'success' | 'warning';
43
32
  onClick?: React.MouseEventHandler;
44
33
  to?: string;
@@ -47,18 +36,29 @@ type FloatingActionButton = {
47
36
  visibleOnPaths?: string[];
48
37
  excludeOnPaths?: string[];
49
38
  };
50
-
51
39
  /**
40
+ * Floating Action Button With Positions
41
+ *
52
42
  * @public
43
+ */
44
+ type FloatingActionButtonWithPositions = Array<{
45
+ slot: Slot;
46
+ actions: FloatingActionButton[];
47
+ }>;
48
+
49
+ /**
53
50
  * Global Floating Action Button Plugin
51
+ *
52
+ * @public
54
53
  */
55
54
  declare const globalFloatingActionButtonPlugin: _backstage_core_plugin_api.BackstagePlugin<{}, {}, {}>;
56
55
  /**
57
- * @public
58
56
  * Global Floating Action Button
57
+ *
58
+ * @public
59
59
  */
60
60
  declare const GlobalFloatingActionButton: ({ floatingButtons, }: {
61
61
  floatingButtons: FloatingActionButton[];
62
62
  }) => react.JSX.Element;
63
63
 
64
- export { type FlexDirection, type FloatingActionButton, type FloatingActionButtonWithPositions, GlobalFloatingActionButton, Slot, globalFloatingActionButtonPlugin };
64
+ export { type FloatingActionButton, type FloatingActionButtonWithPositions, GlobalFloatingActionButton, Slot, globalFloatingActionButtonPlugin };
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2025 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 {\n createComponentExtension,\n createPlugin,\n} from '@backstage/core-plugin-api';\n\n/**\n * @public\n * Global Floating Action Button Plugin\n */\nexport const globalFloatingActionButtonPlugin = createPlugin({\n id: 'global-floating-action-button',\n});\n\n/**\n * @public\n * Global Floating Action Button\n */\nexport const GlobalFloatingActionButton =\n globalFloatingActionButtonPlugin.provide(\n createComponentExtension({\n name: 'GlobalFloatingActionButton',\n component: {\n lazy: () =>\n import('./components/GlobalFloatingActionButton').then(\n m => m.GlobalFloatingActionButton,\n ),\n },\n }),\n );\n"],"names":[],"mappings":";;AAwBO,MAAM,mCAAmC,YAAa,CAAA;AAAA,EAC3D,EAAI,EAAA;AACN,CAAC;AAMM,MAAM,6BACX,gCAAiC,CAAA,OAAA;AAAA,EAC/B,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,4BAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,gDAAyC,CAAE,CAAA,IAAA;AAAA,QAChD,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;;;;"}
1
+ {"version":3,"file":"plugin.esm.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright 2025 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 {\n createComponentExtension,\n createPlugin,\n} from '@backstage/core-plugin-api';\n\n/**\n * Global Floating Action Button Plugin\n *\n * @public\n */\nexport const globalFloatingActionButtonPlugin = createPlugin({\n id: 'global-floating-action-button',\n});\n\n/**\n * Global Floating Action Button\n *\n * @public\n */\nexport const GlobalFloatingActionButton =\n globalFloatingActionButtonPlugin.provide(\n createComponentExtension({\n name: 'GlobalFloatingActionButton',\n component: {\n lazy: () =>\n import('./components/GlobalFloatingActionButton').then(\n m => m.GlobalFloatingActionButton,\n ),\n },\n }),\n );\n"],"names":[],"mappings":";;AAyBO,MAAM,mCAAmC,YAAa,CAAA;AAAA,EAC3D,EAAI,EAAA;AACN,CAAC;AAOM,MAAM,6BACX,gCAAiC,CAAA,OAAA;AAAA,EAC/B,wBAAyB,CAAA;AAAA,IACvB,IAAM,EAAA,4BAAA;AAAA,IACN,SAAW,EAAA;AAAA,MACT,IAAM,EAAA,MACJ,OAAO,gDAAyC,CAAE,CAAA,IAAA;AAAA,QAChD,OAAK,CAAE,CAAA;AAAA;AACT;AACJ,GACD;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"sourcesContent":["/*\n * Copyright 2025 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\n/**\n * @public\n * Slot\n */\n\nexport enum Slot {\n /**\n * Positions the floating action button in the bottom-right corner of the page\n */\n PAGE_END = 'page-end',\n /**\n * Positions the floating action button at the bottom center of the page\n */\n BOTTOM_CENTER = 'bottom-center',\n}\n\n/**\n * @public\n * Floating Action Button With Positions\n */\n\nexport type FloatingActionButtonWithPositions = Array<{\n slot: Slot;\n actions: FloatingActionButton[];\n}>;\n\n/**\n * @public\n * Flex Direction\n */\n\nexport type FlexDirection = 'row' | 'row-reverse' | 'column' | 'column-reverse';\n\n/**\n * @public\n * Floating Action Button\n */\nexport type FloatingActionButton = {\n label: string;\n showLabel?: boolean;\n icon?: string | React.ReactElement;\n size?: 'small' | 'medium' | 'large';\n position?: Slot | string;\n color?:\n | 'default'\n | 'error'\n | 'info'\n | 'inherit'\n | 'primary'\n | 'secondary'\n | 'success'\n | 'warning';\n onClick?: React.MouseEventHandler;\n to?: string;\n toolTip?: string;\n priority?: number;\n visibleOnPaths?: string[];\n excludeOnPaths?: string[];\n};\n"],"names":["Slot"],"mappings":"AAqBY,IAAA,IAAA,qBAAAA,KAAL,KAAA;AAIL,EAAAA,MAAA,UAAW,CAAA,GAAA,UAAA;AAIX,EAAAA,MAAA,eAAgB,CAAA,GAAA,eAAA;AARN,EAAAA,OAAAA,KAAAA;AAAA,CAAA,EAAA,IAAA,IAAA,EAAA;;;;"}
1
+ {"version":3,"file":"types.esm.js","sources":["../src/types.ts"],"sourcesContent":["/*\n * Copyright 2025 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\n/**\n * Slot\n *\n * @public\n */\nexport enum Slot {\n /**\n * Positions the floating action button in the bottom-right corner of the page\n */\n PAGE_END = 'page-end',\n /**\n * Positions the floating action button at the bottom center of the page\n */\n BOTTOM_CENTER = 'bottom-center',\n}\n\n/**\n * Floating Action Button\n *\n * @public\n */\nexport type FloatingActionButton = {\n slot?: Slot;\n label: string;\n showLabel?: boolean;\n icon?: string | React.ReactElement;\n size?: 'small' | 'medium' | 'large';\n color?:\n | 'default'\n | 'error'\n | 'info'\n | 'inherit'\n | 'primary'\n | 'secondary'\n | 'success'\n | 'warning';\n onClick?: React.MouseEventHandler;\n to?: string;\n toolTip?: string;\n priority?: number;\n visibleOnPaths?: string[];\n excludeOnPaths?: string[];\n};\n\n/**\n * Floating Action Button With Positions\n *\n * @public\n */\nexport type FloatingActionButtonWithPositions = Array<{\n slot: Slot;\n actions: FloatingActionButton[];\n}>;\n"],"names":["Slot"],"mappings":"AAqBY,IAAA,IAAA,qBAAAA,KAAL,KAAA;AAIL,EAAAA,MAAA,UAAW,CAAA,GAAA,UAAA;AAIX,EAAAA,MAAA,eAAgB,CAAA,GAAA,eAAA;AARN,EAAAA,OAAAA,KAAAA;AAAA,CAAA,EAAA,IAAA,IAAA,EAAA;;;;"}
package/dist/utils.esm.js CHANGED
@@ -2,13 +2,13 @@ import { Slot } from './types.esm.js';
2
2
 
3
3
  const evaluateFloatingButtonsWithPositions = (floatingButtons) => floatingButtons.reduce(
4
4
  (acc, fb) => {
5
- const position = !fb?.position || !(fb.position in Slot) ? Slot.PAGE_END : Slot[fb.position];
6
- const slotWithActions = acc.find((a) => a.slot === position);
5
+ const slot = fb.slot ?? Slot.PAGE_END;
6
+ const slotWithActions = acc.find((a) => a.slot === slot);
7
7
  if (slotWithActions) {
8
8
  slotWithActions.actions.push(fb);
9
9
  } else {
10
10
  acc.push({
11
- slot: position,
11
+ slot,
12
12
  actions: [fb]
13
13
  });
14
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.esm.js","sources":["../src/utils.ts"],"sourcesContent":["/*\n * Copyright 2025 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 {\n FloatingActionButton,\n FloatingActionButtonWithPositions,\n Slot,\n} from './types';\n\nexport const evaluateFloatingButtonsWithPositions = (\n floatingButtons: FloatingActionButton[],\n): FloatingActionButtonWithPositions =>\n floatingButtons.reduce(\n (acc: FloatingActionButtonWithPositions, fb: FloatingActionButton) => {\n const position: Slot =\n !fb?.position || !(fb.position in Slot)\n ? Slot.PAGE_END\n : Slot[fb.position as keyof typeof Slot];\n const slotWithActions = acc.find(a => a.slot === position);\n if (slotWithActions) {\n slotWithActions.actions.push(fb);\n } else {\n acc.push({\n slot: position,\n actions: [fb],\n });\n }\n return acc;\n },\n [],\n );\n\nexport const sortButtonsWithPriority = (\n floatingButtons: FloatingActionButton[],\n) => {\n const buttons = [...floatingButtons];\n return buttons.sort((fb1, fb2) => {\n if ((fb2.priority || 0) > (fb1.priority || 0)) {\n return 1;\n }\n if ((fb2.priority || 0) < (fb1.priority || 0)) {\n return -1;\n }\n return 0;\n });\n};\n\nexport const filterAndSortButtons = (\n floatingButtons: FloatingActionButton[],\n pathname: string,\n) => {\n const filteredButtons = floatingButtons.filter(fb => {\n if (fb.excludeOnPaths?.includes(pathname)) {\n return false;\n }\n if (fb.visibleOnPaths && fb.visibleOnPaths.length > 0) {\n if (fb.visibleOnPaths?.includes(pathname)) {\n return true;\n }\n return false;\n }\n return true;\n });\n const sortedButtons = sortButtonsWithPriority(filteredButtons);\n return sortedButtons;\n};\n"],"names":[],"mappings":";;AAqBa,MAAA,oCAAA,GAAuC,CAClD,eAAA,KAEA,eAAgB,CAAA,MAAA;AAAA,EACd,CAAC,KAAwC,EAA6B,KAAA;AACpE,IAAA,MAAM,QACJ,GAAA,CAAC,EAAI,EAAA,QAAA,IAAY,EAAE,EAAA,CAAG,QAAY,IAAA,IAAA,CAAA,GAC9B,IAAK,CAAA,QAAA,GACL,IAAK,CAAA,EAAA,CAAG,QAA6B,CAAA;AAC3C,IAAA,MAAM,kBAAkB,GAAI,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,QAAQ,CAAA;AACzD,IAAA,IAAI,eAAiB,EAAA;AACnB,MAAgB,eAAA,CAAA,OAAA,CAAQ,KAAK,EAAE,CAAA;AAAA,KAC1B,MAAA;AACL,MAAA,GAAA,CAAI,IAAK,CAAA;AAAA,QACP,IAAM,EAAA,QAAA;AAAA,QACN,OAAA,EAAS,CAAC,EAAE;AAAA,OACb,CAAA;AAAA;AAEH,IAAO,OAAA,GAAA;AAAA,GACT;AAAA,EACA;AACF;AAEW,MAAA,uBAAA,GAA0B,CACrC,eACG,KAAA;AACH,EAAM,MAAA,OAAA,GAAU,CAAC,GAAG,eAAe,CAAA;AACnC,EAAA,OAAO,OAAQ,CAAA,IAAA,CAAK,CAAC,GAAA,EAAK,GAAQ,KAAA;AAChC,IAAA,IAAA,CAAK,GAAI,CAAA,QAAA,IAAY,CAAM,KAAA,GAAA,CAAI,YAAY,CAAI,CAAA,EAAA;AAC7C,MAAO,OAAA,CAAA;AAAA;AAET,IAAA,IAAA,CAAK,GAAI,CAAA,QAAA,IAAY,CAAM,KAAA,GAAA,CAAI,YAAY,CAAI,CAAA,EAAA;AAC7C,MAAO,OAAA,CAAA,CAAA;AAAA;AAET,IAAO,OAAA,CAAA;AAAA,GACR,CAAA;AACH;AAEa,MAAA,oBAAA,GAAuB,CAClC,eAAA,EACA,QACG,KAAA;AACH,EAAM,MAAA,eAAA,GAAkB,eAAgB,CAAA,MAAA,CAAO,CAAM,EAAA,KAAA;AACnD,IAAA,IAAI,EAAG,CAAA,cAAA,EAAgB,QAAS,CAAA,QAAQ,CAAG,EAAA;AACzC,MAAO,OAAA,KAAA;AAAA;AAET,IAAA,IAAI,EAAG,CAAA,cAAA,IAAkB,EAAG,CAAA,cAAA,CAAe,SAAS,CAAG,EAAA;AACrD,MAAA,IAAI,EAAG,CAAA,cAAA,EAAgB,QAAS,CAAA,QAAQ,CAAG,EAAA;AACzC,QAAO,OAAA,IAAA;AAAA;AAET,MAAO,OAAA,KAAA;AAAA;AAET,IAAO,OAAA,IAAA;AAAA,GACR,CAAA;AACD,EAAM,MAAA,aAAA,GAAgB,wBAAwB,eAAe,CAAA;AAC7D,EAAO,OAAA,aAAA;AACT;;;;"}
1
+ {"version":3,"file":"utils.esm.js","sources":["../src/utils.ts"],"sourcesContent":["/*\n * Copyright 2025 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 {\n FloatingActionButton,\n FloatingActionButtonWithPositions,\n Slot,\n} from './types';\n\nexport const evaluateFloatingButtonsWithPositions = (\n floatingButtons: FloatingActionButton[],\n): FloatingActionButtonWithPositions =>\n floatingButtons.reduce(\n (acc: FloatingActionButtonWithPositions, fb: FloatingActionButton) => {\n const slot = fb.slot ?? Slot.PAGE_END;\n const slotWithActions = acc.find(a => a.slot === slot);\n if (slotWithActions) {\n slotWithActions.actions.push(fb);\n } else {\n acc.push({\n slot,\n actions: [fb],\n });\n }\n return acc;\n },\n [],\n );\n\nexport const sortButtonsWithPriority = (\n floatingButtons: FloatingActionButton[],\n) => {\n const buttons = [...floatingButtons];\n return buttons.sort((fb1, fb2) => {\n if ((fb2.priority || 0) > (fb1.priority || 0)) {\n return 1;\n }\n if ((fb2.priority || 0) < (fb1.priority || 0)) {\n return -1;\n }\n return 0;\n });\n};\n\nexport const filterAndSortButtons = (\n floatingButtons: FloatingActionButton[],\n pathname: string,\n) => {\n const filteredButtons = floatingButtons.filter(fb => {\n if (fb.excludeOnPaths?.includes(pathname)) {\n return false;\n }\n if (fb.visibleOnPaths && fb.visibleOnPaths.length > 0) {\n if (fb.visibleOnPaths?.includes(pathname)) {\n return true;\n }\n return false;\n }\n return true;\n });\n const sortedButtons = sortButtonsWithPriority(filteredButtons);\n return sortedButtons;\n};\n"],"names":[],"mappings":";;AAqBa,MAAA,oCAAA,GAAuC,CAClD,eAAA,KAEA,eAAgB,CAAA,MAAA;AAAA,EACd,CAAC,KAAwC,EAA6B,KAAA;AACpE,IAAM,MAAA,IAAA,GAAO,EAAG,CAAA,IAAA,IAAQ,IAAK,CAAA,QAAA;AAC7B,IAAA,MAAM,kBAAkB,GAAI,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,SAAS,IAAI,CAAA;AACrD,IAAA,IAAI,eAAiB,EAAA;AACnB,MAAgB,eAAA,CAAA,OAAA,CAAQ,KAAK,EAAE,CAAA;AAAA,KAC1B,MAAA;AACL,MAAA,GAAA,CAAI,IAAK,CAAA;AAAA,QACP,IAAA;AAAA,QACA,OAAA,EAAS,CAAC,EAAE;AAAA,OACb,CAAA;AAAA;AAEH,IAAO,OAAA,GAAA;AAAA,GACT;AAAA,EACA;AACF;AAEW,MAAA,uBAAA,GAA0B,CACrC,eACG,KAAA;AACH,EAAM,MAAA,OAAA,GAAU,CAAC,GAAG,eAAe,CAAA;AACnC,EAAA,OAAO,OAAQ,CAAA,IAAA,CAAK,CAAC,GAAA,EAAK,GAAQ,KAAA;AAChC,IAAA,IAAA,CAAK,GAAI,CAAA,QAAA,IAAY,CAAM,KAAA,GAAA,CAAI,YAAY,CAAI,CAAA,EAAA;AAC7C,MAAO,OAAA,CAAA;AAAA;AAET,IAAA,IAAA,CAAK,GAAI,CAAA,QAAA,IAAY,CAAM,KAAA,GAAA,CAAI,YAAY,CAAI,CAAA,EAAA;AAC7C,MAAO,OAAA,CAAA,CAAA;AAAA;AAET,IAAO,OAAA,CAAA;AAAA,GACR,CAAA;AACH;AAEa,MAAA,oBAAA,GAAuB,CAClC,eAAA,EACA,QACG,KAAA;AACH,EAAM,MAAA,eAAA,GAAkB,eAAgB,CAAA,MAAA,CAAO,CAAM,EAAA,KAAA;AACnD,IAAA,IAAI,EAAG,CAAA,cAAA,EAAgB,QAAS,CAAA,QAAQ,CAAG,EAAA;AACzC,MAAO,OAAA,KAAA;AAAA;AAET,IAAA,IAAI,EAAG,CAAA,cAAA,IAAkB,EAAG,CAAA,cAAA,CAAe,SAAS,CAAG,EAAA;AACrD,MAAA,IAAI,EAAG,CAAA,cAAA,EAAgB,QAAS,CAAA,QAAQ,CAAG,EAAA;AACzC,QAAO,OAAA,IAAA;AAAA;AAET,MAAO,OAAA,KAAA;AAAA;AAET,IAAO,OAAA,IAAA;AAAA,GACR,CAAA;AACD,EAAM,MAAA,aAAA,GAAgB,wBAAwB,eAAe,CAAA;AAC7D,EAAO,OAAA,aAAA;AACT;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@red-hat-developer-hub/backstage-plugin-global-floating-action-button",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -38,7 +38,7 @@
38
38
  "@backstage/theme": "^0.6.0",
39
39
  "@mui/icons-material": "^5.15.17",
40
40
  "@mui/material": "^5.15.17",
41
- "@mui/styles": "5.16.7",
41
+ "@mui/styles": "5.16.13",
42
42
  "classnames": "^2.5.1",
43
43
  "react-use": "^17.2.4"
44
44
  },