@backstage/core-components 0.18.0 → 0.18.2-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @backstage/core-components
2
2
 
3
+ ## 0.18.2-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - d493126: Swap base token for semantic token in ItemCardHeader to ensure readability in light mode.
8
+ - 6981ae6: Fixed DependencyGraph `svg` size not adapting to the container size
9
+ - Updated dependencies
10
+ - @backstage/config@1.3.3
11
+ - @backstage/core-plugin-api@1.11.0
12
+ - @backstage/errors@1.2.7
13
+ - @backstage/theme@0.6.8
14
+ - @backstage/version-bridge@1.0.11
15
+
3
16
  ## 0.18.0
4
17
 
5
18
  ### Minor Changes
@@ -1,5 +1,8 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
2
  import { useState, useRef, useMemo, useCallback, useEffect } from 'react';
3
+ import useMeasure from 'react-use/esm/useMeasure';
4
+ import classNames from 'classnames';
5
+ import { once } from 'lodash';
3
6
  import * as d3Zoom from 'd3-zoom';
4
7
  import * as d3Selection from 'd3-selection';
5
8
  import useTheme from '@material-ui/core/styles/useTheme';
@@ -19,11 +22,18 @@ import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
19
22
  import { coreComponentsTranslationRef } from '../../translation.esm.js';
20
23
 
21
24
  const useStyles = makeStyles((theme) => ({
25
+ fullscreenButton: {
26
+ position: "absolute",
27
+ right: 0
28
+ },
22
29
  root: {
23
30
  overflow: "hidden",
24
31
  minHeight: "100%",
25
32
  minWidth: "100%"
26
33
  },
34
+ fixedHeight: {
35
+ height: "100%"
36
+ },
27
37
  fullscreen: {
28
38
  backgroundColor: theme.palette.background.paper
29
39
  }
@@ -76,13 +86,15 @@ function DependencyGraph(props) {
76
86
  const [graphEdges, setGraphEdges] = useState([]);
77
87
  const maxWidth = Math.max(graphWidth, containerWidth);
78
88
  const maxHeight = Math.max(graphHeight, containerHeight);
79
- const minHeight = Math.min(graphHeight, containerHeight);
80
- const scalableHeight = fit === "grow" ? maxHeight : minHeight;
89
+ const [_measureRef] = useMeasure();
90
+ const measureRef = once(_measureRef);
91
+ const scalableHeight = fit === "grow" ? maxHeight : containerHeight;
81
92
  const containerRef = useMemo(
82
93
  () => debounce((root) => {
83
94
  if (!root) {
84
95
  return;
85
96
  }
97
+ measureRef(root);
86
98
  const node = root.querySelector(
87
99
  `svg#${DEPENDENCY_GRAPH_SVG}`
88
100
  );
@@ -125,7 +137,7 @@ function DependencyGraph(props) {
125
137
  setContainerHeight(newContainerHeight);
126
138
  }
127
139
  }, 100),
128
- [containerHeight, containerWidth, maxWidth, maxHeight, zoom]
140
+ [measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom]
129
141
  );
130
142
  const setNodesAndEdges = useCallback(() => {
131
143
  const currentGraphNodes = graph.current.nodes();
@@ -211,109 +223,128 @@ function DependencyGraph(props) {
211
223
  setNodesAndEdges,
212
224
  updateGraph
213
225
  ]);
214
- function setNode(id, node) {
215
- graph.current.setNode(id, node);
216
- updateGraph();
217
- return graph.current;
218
- }
219
- function setEdge(id, edge) {
220
- graph.current.setEdge(id, edge);
221
- updateGraph();
222
- return graph.current;
223
- }
224
- return /* @__PURE__ */ jsx("div", { ref: containerRef, className: styles.root, children: /* @__PURE__ */ jsxs(
225
- FullScreen,
226
+ const setNode = useCallback(
227
+ (id, node) => {
228
+ graph.current.setNode(id, node);
229
+ updateGraph();
230
+ return graph.current;
231
+ },
232
+ [updateGraph]
233
+ );
234
+ const setEdge = useCallback(
235
+ (id, edge) => {
236
+ graph.current.setEdge(id, edge);
237
+ updateGraph();
238
+ return graph.current;
239
+ },
240
+ [updateGraph]
241
+ );
242
+ return /* @__PURE__ */ jsx(
243
+ "div",
226
244
  {
227
- handle: fullScreenHandle,
228
- className: fullScreenHandle.active ? styles.fullscreen : styles.root,
229
- children: [
230
- allowFullscreen && /* @__PURE__ */ jsx(Tooltip, { title: t("dependencyGraph.fullscreenTooltip"), children: /* @__PURE__ */ jsx(
231
- IconButton,
232
- {
233
- style: { float: "right" },
234
- onClick: fullScreenHandle.active ? fullScreenHandle.exit : fullScreenHandle.enter,
235
- children: fullScreenHandle.active ? /* @__PURE__ */ jsx(FullscreenExitIcon, {}) : /* @__PURE__ */ jsx(FullscreenIcon, {})
236
- }
237
- ) }),
238
- /* @__PURE__ */ jsxs(
239
- "svg",
240
- {
241
- ...svgProps,
242
- width: "100%",
243
- height: scalableHeight,
244
- viewBox: `0 0 ${maxWidth} ${maxHeight}`,
245
- id: DEPENDENCY_GRAPH_SVG,
246
- children: [
247
- /* @__PURE__ */ jsxs("defs", { children: [
248
- /* @__PURE__ */ jsx(
249
- "marker",
250
- {
251
- id: ARROW_MARKER_ID,
252
- viewBox: "0 0 24 24",
253
- markerWidth: "14",
254
- markerHeight: "14",
255
- refX: "16",
256
- refY: "12",
257
- orient: "auto",
258
- markerUnits: "strokeWidth",
259
- children: /* @__PURE__ */ jsx(
260
- "path",
245
+ ref: containerRef,
246
+ className: classNames(
247
+ styles.root,
248
+ fit === "contain" && styles.fixedHeight
249
+ ),
250
+ children: /* @__PURE__ */ jsxs(
251
+ FullScreen,
252
+ {
253
+ handle: fullScreenHandle,
254
+ className: classNames(
255
+ fullScreenHandle.active ? styles.fullscreen : styles.root,
256
+ fit === "contain" && styles.fixedHeight
257
+ ),
258
+ children: [
259
+ allowFullscreen && /* @__PURE__ */ jsx(Tooltip, { title: t("dependencyGraph.fullscreenTooltip"), children: /* @__PURE__ */ jsx(
260
+ IconButton,
261
+ {
262
+ className: styles.fullscreenButton,
263
+ onClick: fullScreenHandle.active ? fullScreenHandle.exit : fullScreenHandle.enter,
264
+ children: fullScreenHandle.active ? /* @__PURE__ */ jsx(FullscreenExitIcon, {}) : /* @__PURE__ */ jsx(FullscreenIcon, {})
265
+ }
266
+ ) }),
267
+ /* @__PURE__ */ jsxs(
268
+ "svg",
269
+ {
270
+ ...svgProps,
271
+ width: "100%",
272
+ height: scalableHeight,
273
+ viewBox: `0 0 ${maxWidth} ${maxHeight}`,
274
+ id: DEPENDENCY_GRAPH_SVG,
275
+ children: [
276
+ /* @__PURE__ */ jsxs("defs", { children: [
277
+ /* @__PURE__ */ jsx(
278
+ "marker",
261
279
  {
262
- fill: theme.palette.textSubtle,
263
- d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"
280
+ id: ARROW_MARKER_ID,
281
+ viewBox: "0 0 24 24",
282
+ markerWidth: "14",
283
+ markerHeight: "14",
284
+ refX: "16",
285
+ refY: "12",
286
+ orient: "auto",
287
+ markerUnits: "strokeWidth",
288
+ children: /* @__PURE__ */ jsx(
289
+ "path",
290
+ {
291
+ fill: theme.palette.textSubtle,
292
+ d: "M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"
293
+ }
294
+ )
264
295
  }
265
- )
266
- }
267
- ),
268
- defs
269
- ] }),
270
- /* @__PURE__ */ jsx("g", { id: WORKSPACE_ID, children: /* @__PURE__ */ jsxs(
271
- "svg",
272
- {
273
- width: graphWidth,
274
- height: graphHeight,
275
- y: maxHeight / 2 - graphHeight / 2,
276
- x: maxWidth / 2 - graphWidth / 2,
277
- viewBox: `0 0 ${graphWidth} ${graphHeight}`,
278
- children: [
279
- graphEdges.map((e) => {
280
- const edge = graph.current.edge(e);
281
- if (!edge) return null;
282
- return /* @__PURE__ */ jsx(
283
- Edge,
284
- {
285
- id: e,
286
- setEdge,
287
- render: renderLabel,
288
- edge,
289
- curve,
290
- showArrowHeads
291
- },
292
- `${e.v}-${e.w}`
293
- );
294
- }),
295
- graphNodes.map((id) => {
296
- const node = graph.current.node(id);
297
- if (!node) return null;
298
- return /* @__PURE__ */ jsx(
299
- Node,
300
- {
301
- setNode,
302
- render: renderNode,
303
- node
304
- },
305
- id
306
- );
307
- })
308
- ]
309
- }
310
- ) })
311
- ]
312
- }
313
- )
314
- ]
296
+ ),
297
+ defs
298
+ ] }),
299
+ /* @__PURE__ */ jsx("g", { id: WORKSPACE_ID, children: /* @__PURE__ */ jsxs(
300
+ "svg",
301
+ {
302
+ width: graphWidth,
303
+ height: graphHeight,
304
+ y: maxHeight / 2 - graphHeight / 2,
305
+ x: maxWidth / 2 - graphWidth / 2,
306
+ viewBox: `0 0 ${graphWidth} ${graphHeight}`,
307
+ children: [
308
+ graphEdges.map((e) => {
309
+ const edge = graph.current.edge(e);
310
+ if (!edge) return null;
311
+ return /* @__PURE__ */ jsx(
312
+ Edge,
313
+ {
314
+ id: e,
315
+ setEdge,
316
+ render: renderLabel,
317
+ edge,
318
+ curve,
319
+ showArrowHeads
320
+ },
321
+ `${e.v}-${e.w}`
322
+ );
323
+ }),
324
+ graphNodes.map((id) => {
325
+ const node = graph.current.node(id);
326
+ if (!node) return null;
327
+ return /* @__PURE__ */ jsx(
328
+ Node,
329
+ {
330
+ setNode,
331
+ render: renderNode,
332
+ node
333
+ },
334
+ id
335
+ );
336
+ })
337
+ ]
338
+ }
339
+ ) })
340
+ ]
341
+ }
342
+ )
343
+ ]
344
+ }
345
+ )
315
346
  }
316
- ) });
347
+ );
317
348
  }
318
349
 
319
350
  export { DependencyGraph };
@@ -1 +1 @@
1
- {"version":3,"file":"DependencyGraph.esm.js","sources":["../../../src/components/DependencyGraph/DependencyGraph.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 SVGProps,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport * as d3Zoom from 'd3-zoom';\nimport * as d3Selection from 'd3-selection';\nimport useTheme from '@material-ui/core/styles/useTheme';\nimport dagre from '@dagrejs/dagre';\nimport debounce from 'lodash/debounce';\nimport { DependencyGraphTypes as Types } from './types';\nimport { Node } from './Node';\nimport { Edge, GraphEdge } from './Edge';\nimport { ARROW_MARKER_ID } from './constants';\nimport IconButton from '@material-ui/core/IconButton';\nimport FullscreenIcon from '@material-ui/icons/Fullscreen';\nimport FullscreenExitIcon from '@material-ui/icons/FullscreenExit';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { coreComponentsTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n root: {\n overflow: 'hidden',\n minHeight: '100%',\n minWidth: '100%',\n },\n fullscreen: {\n backgroundColor: theme.palette.background.paper,\n },\n}));\n\n/**\n * Properties of {@link DependencyGraph}\n *\n * @public\n * @remarks\n * `<NodeData>` and `<EdgeData>` are useful when rendering custom or edge labels\n */\nexport interface DependencyGraphProps<NodeData, EdgeData>\n extends SVGProps<SVGSVGElement> {\n /**\n * Edges of graph\n */\n edges: Types.DependencyEdge<EdgeData>[];\n /**\n * Nodes of Graph\n */\n nodes: Types.DependencyNode<NodeData>[];\n /**\n * Graph {@link DependencyGraphTypes.Direction | direction}\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Direction.TOP_BOTTOM`\n */\n direction?: Types.Direction;\n /**\n * Node {@link DependencyGraphTypes.Alignment | alignment}\n */\n align?: Types.Alignment;\n /**\n * Margin between nodes on each rank\n *\n * @remarks\n *\n * Default: 50\n */\n nodeMargin?: number;\n /**\n * Margin between edges\n *\n * @remarks\n *\n * Default: 10\n */\n edgeMargin?: number;\n /**\n * Margin between each rank\n *\n * @remarks\n *\n * Default: 50\n */\n rankMargin?: number;\n /**\n * Margin on left and right of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingX?: number;\n /**\n * Margin on top and bottom of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingY?: number;\n /**\n * Heuristic used to find set of edges that will make graph acyclic\n */\n acyclicer?: 'greedy';\n /**\n * {@link DependencyGraphTypes.Ranker | Algorithm} used to rank nodes\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Ranker.NETWORK_SIMPLEX`\n */\n ranker?: Types.Ranker;\n /**\n * {@link DependencyGraphTypes.LabelPosition | Position} of label in relation to edge\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelPosition?: Types.LabelPosition;\n /**\n * How much to move label away from edge\n *\n * @remarks\n *\n * Applies only when {@link DependencyGraphProps.labelPosition} is `DependencyGraphTypes.LabelPosition.LEFT` or\n * `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelOffset?: number;\n /**\n * Minimum number of ranks to keep between connected nodes\n */\n edgeRanks?: number;\n /**\n * Weight applied to edges in graph\n */\n edgeWeight?: number;\n /**\n * Custom node rendering component\n */\n renderNode?: Types.RenderNodeFunction<NodeData>;\n /**\n * Custom label rendering component\n */\n renderLabel?: Types.RenderLabelFunction<EdgeData>;\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs | Defs} shared by rendered SVG to be used by\n * {@link DependencyGraphProps.renderNode} and/or {@link DependencyGraphProps.renderLabel}\n */\n defs?: JSX.Element | JSX.Element[];\n /**\n * Controls zoom behavior of graph\n *\n * @remarks\n *\n * Default: `enabled`\n */\n zoom?: 'enabled' | 'disabled' | 'enable-on-click';\n /**\n * A factory for curve generators addressing both lines and areas.\n *\n * @remarks\n *\n * Default: 'curveMonotoneX'\n */\n curve?: 'curveStepBefore' | 'curveMonotoneX';\n /**\n * Controls if the arrow heads should be rendered or not.\n *\n * Default: false\n */\n showArrowHeads?: boolean;\n /**\n * Controls if the graph should be contained or grow\n *\n * @remarks\n *\n * Default: 'grow'\n */\n fit?: 'grow' | 'contain';\n /**\n * Controls if user can toggle fullscreen mode\n *\n * @remarks\n *\n * Default: true\n */\n allowFullscreen?: boolean;\n}\n\nconst WORKSPACE_ID = 'workspace';\nconst DEPENDENCY_GRAPH_SVG = 'dependency-graph';\n\n/**\n * Graph component used to visualize relations between entities\n *\n * @public\n */\nexport function DependencyGraph<NodeData, EdgeData>(\n props: DependencyGraphProps<NodeData, EdgeData>,\n) {\n const {\n edges,\n nodes,\n renderNode,\n direction = Types.Direction.TOP_BOTTOM,\n align,\n nodeMargin = 50,\n edgeMargin = 10,\n rankMargin = 50,\n paddingX = 0,\n paddingY = 0,\n acyclicer,\n ranker = Types.Ranker.NETWORK_SIMPLEX,\n labelPosition = Types.LabelPosition.RIGHT,\n labelOffset = 10,\n edgeRanks = 1,\n edgeWeight = 1,\n renderLabel,\n defs,\n zoom = 'enabled',\n curve = 'curveMonotoneX',\n showArrowHeads = false,\n fit = 'grow',\n allowFullscreen = true,\n ...svgProps\n } = props;\n const theme = useTheme();\n const [containerWidth, setContainerWidth] = useState<number>(100);\n const [containerHeight, setContainerHeight] = useState<number>(100);\n const fullScreenHandle = useFullScreenHandle();\n const styles = useStyles();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const graph = useRef<dagre.graphlib.Graph<Types.DependencyNode<NodeData>>>(\n new dagre.graphlib.Graph(),\n );\n const [graphWidth, setGraphWidth] = useState<number>(\n graph.current.graph()?.width || 0,\n );\n const [graphHeight, setGraphHeight] = useState<number>(\n graph.current.graph()?.height || 0,\n );\n const [graphNodes, setGraphNodes] = useState<string[]>([]);\n const [graphEdges, setGraphEdges] = useState<dagre.Edge[]>([]);\n\n const maxWidth = Math.max(graphWidth, containerWidth);\n const maxHeight = Math.max(graphHeight, containerHeight);\n const minHeight = Math.min(graphHeight, containerHeight);\n\n const scalableHeight = fit === 'grow' ? maxHeight : minHeight;\n\n const containerRef = useMemo(\n () =>\n debounce((root: HTMLDivElement) => {\n if (!root) {\n return;\n }\n // Set up zooming + panning\n const node: SVGSVGElement = root.querySelector(\n `svg#${DEPENDENCY_GRAPH_SVG}`,\n ) as SVGSVGElement;\n if (!node) {\n return;\n }\n const container = d3Selection.select<SVGSVGElement, null>(node);\n const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));\n\n function enableZoom() {\n container.call(\n d3Zoom\n .zoom<SVGSVGElement, null>()\n .scaleExtent([1, Infinity])\n .on('zoom', event => {\n event.transform.x = Math.min(\n 0,\n Math.max(\n event.transform.x,\n maxWidth - maxWidth * event.transform.k,\n ),\n );\n event.transform.y = Math.min(\n 0,\n Math.max(\n event.transform.y,\n maxHeight - maxHeight * event.transform.k,\n ),\n );\n workspace.attr('transform', event.transform);\n }),\n );\n }\n\n if (zoom === 'enabled') {\n enableZoom();\n } else if (zoom === 'enable-on-click') {\n container.on('click', () => enableZoom());\n }\n\n const { width: newContainerWidth, height: newContainerHeight } =\n root.getBoundingClientRect();\n if (containerWidth !== newContainerWidth) {\n setContainerWidth(newContainerWidth);\n }\n if (containerHeight !== newContainerHeight) {\n setContainerHeight(newContainerHeight);\n }\n }, 100),\n [containerHeight, containerWidth, maxWidth, maxHeight, zoom],\n );\n\n const setNodesAndEdges = useCallback(() => {\n // Cleaning up lingering nodes and edges\n const currentGraphNodes = graph.current.nodes();\n const currentGraphEdges = graph.current.edges();\n\n currentGraphNodes.forEach(nodeId => {\n const remainingNode = nodes.some(node => node.id === nodeId);\n if (!remainingNode) {\n graph.current.removeNode(nodeId);\n }\n });\n\n currentGraphEdges.forEach(e => {\n const remainingEdge = edges.some(\n edge => edge.from === e.v && edge.to === e.w,\n );\n if (!remainingEdge) {\n graph.current.removeEdge(e.v, e.w);\n }\n });\n\n // Adding/updating nodes and edges\n nodes.forEach(node => {\n const existingNode = graph.current\n .nodes()\n .find(nodeId => node.id === nodeId);\n\n if (existingNode && graph.current.node(existingNode)) {\n const { width, height, x, y } = graph.current.node(existingNode);\n graph.current.setNode(existingNode, { ...node, width, height, x, y });\n } else {\n graph.current.setNode(node.id, { ...node, width: 0, height: 0 });\n }\n });\n\n edges.forEach(e => {\n graph.current.setEdge(e.from, e.to, {\n ...e,\n label: e.label,\n width: 0,\n height: 0,\n labelpos: labelPosition,\n labeloffset: labelOffset,\n weight: edgeWeight,\n minlen: edgeRanks,\n });\n });\n }, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);\n\n const updateGraph = useMemo(\n () =>\n debounce(\n () => {\n dagre.layout(graph.current);\n const { height, width } = graph.current.graph();\n const newHeight = Math.max(0, height || 0);\n const newWidth = Math.max(0, width || 0);\n setGraphWidth(newWidth);\n setGraphHeight(newHeight);\n\n setGraphNodes(graph.current.nodes());\n setGraphEdges(graph.current.edges());\n },\n 250,\n { leading: true },\n ),\n [],\n );\n\n useEffect(() => {\n graph.current.setGraph({\n rankdir: direction,\n align,\n nodesep: nodeMargin,\n edgesep: edgeMargin,\n ranksep: rankMargin,\n marginx: paddingX,\n marginy: paddingY,\n acyclicer,\n ranker,\n });\n\n setNodesAndEdges();\n updateGraph();\n\n return updateGraph.cancel;\n }, [\n acyclicer,\n align,\n direction,\n edgeMargin,\n paddingX,\n paddingY,\n nodeMargin,\n rankMargin,\n ranker,\n setNodesAndEdges,\n updateGraph,\n ]);\n\n function setNode(id: string, node: Types.DependencyNode<NodeData>) {\n graph.current.setNode(id, node);\n updateGraph();\n return graph.current;\n }\n\n function setEdge(id: dagre.Edge, edge: Types.DependencyEdge<EdgeData>) {\n graph.current.setEdge(id, edge);\n updateGraph();\n return graph.current;\n }\n\n return (\n <div ref={containerRef} className={styles.root}>\n <FullScreen\n handle={fullScreenHandle}\n className={fullScreenHandle.active ? styles.fullscreen : styles.root}\n >\n {allowFullscreen && (\n <Tooltip title={t('dependencyGraph.fullscreenTooltip')}>\n <IconButton\n style={{ float: 'right' }}\n onClick={\n fullScreenHandle.active\n ? fullScreenHandle.exit\n : fullScreenHandle.enter\n }\n >\n {fullScreenHandle.active ? (\n <FullscreenExitIcon />\n ) : (\n <FullscreenIcon />\n )}\n </IconButton>\n </Tooltip>\n )}\n\n <svg\n {...svgProps}\n width=\"100%\"\n height={scalableHeight}\n viewBox={`0 0 ${maxWidth} ${maxHeight}`}\n id={DEPENDENCY_GRAPH_SVG}\n >\n <defs>\n <marker\n id={ARROW_MARKER_ID}\n viewBox=\"0 0 24 24\"\n markerWidth=\"14\"\n markerHeight=\"14\"\n refX=\"16\"\n refY=\"12\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path\n fill={theme.palette.textSubtle}\n d=\"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"\n />\n </marker>\n {defs}\n </defs>\n <g id={WORKSPACE_ID}>\n <svg\n width={graphWidth}\n height={graphHeight}\n y={maxHeight / 2 - graphHeight / 2}\n x={maxWidth / 2 - graphWidth / 2}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n >\n {graphEdges.map(e => {\n const edge = graph.current.edge(e) as GraphEdge<EdgeData>;\n if (!edge) return null;\n return (\n <Edge\n key={`${e.v}-${e.w}`}\n id={e}\n setEdge={setEdge}\n render={renderLabel}\n edge={edge}\n curve={curve}\n showArrowHeads={showArrowHeads}\n />\n );\n })}\n {graphNodes.map((id: string) => {\n const node = graph.current.node(id);\n if (!node) return null;\n return (\n <Node\n key={id}\n setNode={setNode}\n render={renderNode}\n node={node}\n />\n );\n })}\n </svg>\n </g>\n </svg>\n </FullScreen>\n </div>\n );\n}\n"],"names":["Types"],"mappings":"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"}
1
+ {"version":3,"file":"DependencyGraph.esm.js","sources":["../../../src/components/DependencyGraph/DependencyGraph.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 SVGProps,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport useMeasure from 'react-use/esm/useMeasure';\nimport classNames from 'classnames';\nimport { once } from 'lodash';\nimport * as d3Zoom from 'd3-zoom';\nimport * as d3Selection from 'd3-selection';\nimport useTheme from '@material-ui/core/styles/useTheme';\nimport dagre from '@dagrejs/dagre';\nimport debounce from 'lodash/debounce';\nimport { DependencyGraphTypes as Types } from './types';\nimport { Node } from './Node';\nimport { Edge, GraphEdge } from './Edge';\nimport { ARROW_MARKER_ID } from './constants';\nimport IconButton from '@material-ui/core/IconButton';\nimport FullscreenIcon from '@material-ui/icons/Fullscreen';\nimport FullscreenExitIcon from '@material-ui/icons/FullscreenExit';\nimport { FullScreen, useFullScreenHandle } from 'react-full-screen';\nimport { makeStyles, Theme } from '@material-ui/core/styles';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\nimport { coreComponentsTranslationRef } from '../../translation';\n\nconst useStyles = makeStyles((theme: Theme) => ({\n fullscreenButton: {\n position: 'absolute',\n right: 0,\n },\n root: {\n overflow: 'hidden',\n minHeight: '100%',\n minWidth: '100%',\n },\n fixedHeight: {\n height: '100%',\n },\n fullscreen: {\n backgroundColor: theme.palette.background.paper,\n },\n}));\n\n/**\n * Properties of {@link DependencyGraph}\n *\n * @public\n * @remarks\n * `<NodeData>` and `<EdgeData>` are useful when rendering custom or edge labels\n */\nexport interface DependencyGraphProps<NodeData, EdgeData>\n extends SVGProps<SVGSVGElement> {\n /**\n * Edges of graph\n */\n edges: Types.DependencyEdge<EdgeData>[];\n /**\n * Nodes of Graph\n */\n nodes: Types.DependencyNode<NodeData>[];\n /**\n * Graph {@link DependencyGraphTypes.Direction | direction}\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Direction.TOP_BOTTOM`\n */\n direction?: Types.Direction;\n /**\n * Node {@link DependencyGraphTypes.Alignment | alignment}\n */\n align?: Types.Alignment;\n /**\n * Margin between nodes on each rank\n *\n * @remarks\n *\n * Default: 50\n */\n nodeMargin?: number;\n /**\n * Margin between edges\n *\n * @remarks\n *\n * Default: 10\n */\n edgeMargin?: number;\n /**\n * Margin between each rank\n *\n * @remarks\n *\n * Default: 50\n */\n rankMargin?: number;\n /**\n * Margin on left and right of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingX?: number;\n /**\n * Margin on top and bottom of whole graph\n *\n * @remarks\n *\n * Default: 0\n */\n paddingY?: number;\n /**\n * Heuristic used to find set of edges that will make graph acyclic\n */\n acyclicer?: 'greedy';\n /**\n * {@link DependencyGraphTypes.Ranker | Algorithm} used to rank nodes\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.Ranker.NETWORK_SIMPLEX`\n */\n ranker?: Types.Ranker;\n /**\n * {@link DependencyGraphTypes.LabelPosition | Position} of label in relation to edge\n *\n * @remarks\n *\n * Default: `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelPosition?: Types.LabelPosition;\n /**\n * How much to move label away from edge\n *\n * @remarks\n *\n * Applies only when {@link DependencyGraphProps.labelPosition} is `DependencyGraphTypes.LabelPosition.LEFT` or\n * `DependencyGraphTypes.LabelPosition.RIGHT`\n */\n labelOffset?: number;\n /**\n * Minimum number of ranks to keep between connected nodes\n */\n edgeRanks?: number;\n /**\n * Weight applied to edges in graph\n */\n edgeWeight?: number;\n /**\n * Custom node rendering component\n */\n renderNode?: Types.RenderNodeFunction<NodeData>;\n /**\n * Custom label rendering component\n */\n renderLabel?: Types.RenderLabelFunction<EdgeData>;\n /**\n * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs | Defs} shared by rendered SVG to be used by\n * {@link DependencyGraphProps.renderNode} and/or {@link DependencyGraphProps.renderLabel}\n */\n defs?: JSX.Element | JSX.Element[];\n /**\n * Controls zoom behavior of graph\n *\n * @remarks\n *\n * Default: `enabled`\n */\n zoom?: 'enabled' | 'disabled' | 'enable-on-click';\n /**\n * A factory for curve generators addressing both lines and areas.\n *\n * @remarks\n *\n * Default: 'curveMonotoneX'\n */\n curve?: 'curveStepBefore' | 'curveMonotoneX';\n /**\n * Controls if the arrow heads should be rendered or not.\n *\n * Default: false\n */\n showArrowHeads?: boolean;\n /**\n * Controls if the graph should be contained or grow\n *\n * @remarks\n *\n * Default: 'grow'\n */\n fit?: 'grow' | 'contain';\n /**\n * Controls if user can toggle fullscreen mode\n *\n * @remarks\n *\n * Default: true\n */\n allowFullscreen?: boolean;\n}\n\nconst WORKSPACE_ID = 'workspace';\nconst DEPENDENCY_GRAPH_SVG = 'dependency-graph';\n\n/**\n * Graph component used to visualize relations between entities\n *\n * @public\n */\nexport function DependencyGraph<NodeData, EdgeData>(\n props: DependencyGraphProps<NodeData, EdgeData>,\n) {\n const {\n edges,\n nodes,\n renderNode,\n direction = Types.Direction.TOP_BOTTOM,\n align,\n nodeMargin = 50,\n edgeMargin = 10,\n rankMargin = 50,\n paddingX = 0,\n paddingY = 0,\n acyclicer,\n ranker = Types.Ranker.NETWORK_SIMPLEX,\n labelPosition = Types.LabelPosition.RIGHT,\n labelOffset = 10,\n edgeRanks = 1,\n edgeWeight = 1,\n renderLabel,\n defs,\n zoom = 'enabled',\n curve = 'curveMonotoneX',\n showArrowHeads = false,\n fit = 'grow',\n allowFullscreen = true,\n ...svgProps\n } = props;\n const theme = useTheme();\n const [containerWidth, setContainerWidth] = useState<number>(100);\n const [containerHeight, setContainerHeight] = useState<number>(100);\n const fullScreenHandle = useFullScreenHandle();\n const styles = useStyles();\n const { t } = useTranslationRef(coreComponentsTranslationRef);\n\n const graph = useRef<dagre.graphlib.Graph<Types.DependencyNode<NodeData>>>(\n new dagre.graphlib.Graph(),\n );\n const [graphWidth, setGraphWidth] = useState<number>(\n graph.current.graph()?.width || 0,\n );\n const [graphHeight, setGraphHeight] = useState<number>(\n graph.current.graph()?.height || 0,\n );\n const [graphNodes, setGraphNodes] = useState<string[]>([]);\n const [graphEdges, setGraphEdges] = useState<dagre.Edge[]>([]);\n\n const maxWidth = Math.max(graphWidth, containerWidth);\n const maxHeight = Math.max(graphHeight, containerHeight);\n\n const [_measureRef] = useMeasure();\n const measureRef = once(_measureRef);\n\n const scalableHeight = fit === 'grow' ? maxHeight : containerHeight;\n\n const containerRef = useMemo(\n () =>\n debounce((root: HTMLDivElement) => {\n if (!root) {\n return;\n }\n measureRef(root);\n\n // Set up zooming + panning\n const node: SVGSVGElement = root.querySelector(\n `svg#${DEPENDENCY_GRAPH_SVG}`,\n ) as SVGSVGElement;\n if (!node) {\n return;\n }\n const container = d3Selection.select<SVGSVGElement, null>(node);\n const workspace = d3Selection.select(node.getElementById(WORKSPACE_ID));\n\n function enableZoom() {\n container.call(\n d3Zoom\n .zoom<SVGSVGElement, null>()\n .scaleExtent([1, Infinity])\n .on('zoom', event => {\n event.transform.x = Math.min(\n 0,\n Math.max(\n event.transform.x,\n maxWidth - maxWidth * event.transform.k,\n ),\n );\n event.transform.y = Math.min(\n 0,\n Math.max(\n event.transform.y,\n maxHeight - maxHeight * event.transform.k,\n ),\n );\n workspace.attr('transform', event.transform);\n }),\n );\n }\n\n if (zoom === 'enabled') {\n enableZoom();\n } else if (zoom === 'enable-on-click') {\n container.on('click', () => enableZoom());\n }\n\n const { width: newContainerWidth, height: newContainerHeight } =\n root.getBoundingClientRect();\n if (containerWidth !== newContainerWidth) {\n setContainerWidth(newContainerWidth);\n }\n if (containerHeight !== newContainerHeight) {\n setContainerHeight(newContainerHeight);\n }\n }, 100),\n [measureRef, containerHeight, containerWidth, maxWidth, maxHeight, zoom],\n );\n\n const setNodesAndEdges = useCallback(() => {\n // Cleaning up lingering nodes and edges\n const currentGraphNodes = graph.current.nodes();\n const currentGraphEdges = graph.current.edges();\n\n currentGraphNodes.forEach(nodeId => {\n const remainingNode = nodes.some(node => node.id === nodeId);\n if (!remainingNode) {\n graph.current.removeNode(nodeId);\n }\n });\n\n currentGraphEdges.forEach(e => {\n const remainingEdge = edges.some(\n edge => edge.from === e.v && edge.to === e.w,\n );\n if (!remainingEdge) {\n graph.current.removeEdge(e.v, e.w);\n }\n });\n\n // Adding/updating nodes and edges\n nodes.forEach(node => {\n const existingNode = graph.current\n .nodes()\n .find(nodeId => node.id === nodeId);\n\n if (existingNode && graph.current.node(existingNode)) {\n const { width, height, x, y } = graph.current.node(existingNode);\n graph.current.setNode(existingNode, { ...node, width, height, x, y });\n } else {\n graph.current.setNode(node.id, { ...node, width: 0, height: 0 });\n }\n });\n\n edges.forEach(e => {\n graph.current.setEdge(e.from, e.to, {\n ...e,\n label: e.label,\n width: 0,\n height: 0,\n labelpos: labelPosition,\n labeloffset: labelOffset,\n weight: edgeWeight,\n minlen: edgeRanks,\n });\n });\n }, [edges, nodes, labelPosition, labelOffset, edgeWeight, edgeRanks]);\n\n const updateGraph = useMemo(\n () =>\n debounce(\n () => {\n dagre.layout(graph.current);\n const { height, width } = graph.current.graph();\n const newHeight = Math.max(0, height || 0);\n const newWidth = Math.max(0, width || 0);\n setGraphWidth(newWidth);\n setGraphHeight(newHeight);\n\n setGraphNodes(graph.current.nodes());\n setGraphEdges(graph.current.edges());\n },\n 250,\n { leading: true },\n ),\n [],\n );\n\n useEffect(() => {\n graph.current.setGraph({\n rankdir: direction,\n align,\n nodesep: nodeMargin,\n edgesep: edgeMargin,\n ranksep: rankMargin,\n marginx: paddingX,\n marginy: paddingY,\n acyclicer,\n ranker,\n });\n\n setNodesAndEdges();\n updateGraph();\n\n return updateGraph.cancel;\n }, [\n acyclicer,\n align,\n direction,\n edgeMargin,\n paddingX,\n paddingY,\n nodeMargin,\n rankMargin,\n ranker,\n setNodesAndEdges,\n updateGraph,\n ]);\n\n const setNode = useCallback(\n (id: string, node: Types.DependencyNode<NodeData>) => {\n graph.current.setNode(id, node);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n const setEdge = useCallback(\n (id: dagre.Edge, edge: Types.DependencyEdge<EdgeData>) => {\n graph.current.setEdge(id, edge);\n updateGraph();\n return graph.current;\n },\n [updateGraph],\n );\n\n return (\n <div\n ref={containerRef}\n className={classNames(\n styles.root,\n fit === 'contain' && styles.fixedHeight,\n )}\n >\n <FullScreen\n handle={fullScreenHandle}\n className={classNames(\n fullScreenHandle.active ? styles.fullscreen : styles.root,\n fit === 'contain' && styles.fixedHeight,\n )}\n >\n {allowFullscreen && (\n <Tooltip title={t('dependencyGraph.fullscreenTooltip')}>\n <IconButton\n className={styles.fullscreenButton}\n onClick={\n fullScreenHandle.active\n ? fullScreenHandle.exit\n : fullScreenHandle.enter\n }\n >\n {fullScreenHandle.active ? (\n <FullscreenExitIcon />\n ) : (\n <FullscreenIcon />\n )}\n </IconButton>\n </Tooltip>\n )}\n\n <svg\n {...svgProps}\n width=\"100%\"\n height={scalableHeight}\n viewBox={`0 0 ${maxWidth} ${maxHeight}`}\n id={DEPENDENCY_GRAPH_SVG}\n >\n <defs>\n <marker\n id={ARROW_MARKER_ID}\n viewBox=\"0 0 24 24\"\n markerWidth=\"14\"\n markerHeight=\"14\"\n refX=\"16\"\n refY=\"12\"\n orient=\"auto\"\n markerUnits=\"strokeWidth\"\n >\n <path\n fill={theme.palette.textSubtle}\n d=\"M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\"\n />\n </marker>\n {defs}\n </defs>\n <g id={WORKSPACE_ID}>\n <svg\n width={graphWidth}\n height={graphHeight}\n y={maxHeight / 2 - graphHeight / 2}\n x={maxWidth / 2 - graphWidth / 2}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n >\n {graphEdges.map(e => {\n const edge = graph.current.edge(e) as GraphEdge<EdgeData>;\n if (!edge) return null;\n return (\n <Edge\n key={`${e.v}-${e.w}`}\n id={e}\n setEdge={setEdge}\n render={renderLabel}\n edge={edge}\n curve={curve}\n showArrowHeads={showArrowHeads}\n />\n );\n })}\n {graphNodes.map((id: string) => {\n const node = graph.current.node(id);\n if (!node) return null;\n return (\n <Node\n key={id}\n setNode={setNode}\n render={renderNode}\n node={node}\n />\n );\n })}\n </svg>\n </g>\n </svg>\n </FullScreen>\n </div>\n );\n}\n"],"names":["Types"],"mappings":"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"}
@@ -5,7 +5,7 @@ import Typography from '@material-ui/core/Typography';
5
5
 
6
6
  const styles = (theme) => createStyles({
7
7
  root: {
8
- color: theme.palette.common.white,
8
+ color: theme.palette.text.primary,
9
9
  padding: theme.spacing(2, 2, 3),
10
10
  backgroundImage: theme.getPageTheme({ themeId: "card" }).backgroundImage,
11
11
  backgroundPosition: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"ItemCardHeader.esm.js","sources":["../../../src/layout/ItemCard/ItemCardHeader.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 Box from '@material-ui/core/Box';\nimport {\n createStyles,\n makeStyles,\n Theme,\n WithStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { ReactNode } from 'react';\n\n/** @public */\nexport type ItemCardHeaderClassKey = 'root';\n\nconst styles = (theme: Theme) =>\n createStyles({\n root: {\n color: theme.palette.common.white,\n padding: theme.spacing(2, 2, 3),\n backgroundImage: theme.getPageTheme({ themeId: 'card' }).backgroundImage,\n backgroundPosition: 0,\n backgroundSize: 'inherit',\n },\n });\n\nconst useStyles = makeStyles(styles, { name: 'BackstageItemCardHeader' });\n\n/** @public */\nexport type ItemCardHeaderProps = Partial<WithStyles<typeof styles>> & {\n /**\n * A large title to show in the header, providing the main heading.\n *\n * Use this if you want to have the default styling and placement of a title.\n */\n title?: ReactNode;\n /**\n * A slightly smaller title to show in the header, providing additional\n * details.\n *\n * Use this if you want to have the default styling and placement of a\n * subtitle.\n */\n subtitle?: ReactNode;\n /**\n * Custom children to draw in the header.\n *\n * If the title and/or subtitle were specified, the children are drawn below\n * those.\n */\n children?: ReactNode;\n};\n\n/**\n * A simple card header, rendering a default look for \"item cards\" - cards that\n * are arranged in a grid for users to select among several options.\n *\n * @remarks\n * This component expects to be placed within a Material UI `<CardMedia>`.\n *\n * Styles for the header can be overridden using the `classes` prop, e.g.:\n *\n * `<ItemCardHeader title=\"Hello\" classes={{ root: myClassName }} />`\n *\n * @public\n */\nexport function ItemCardHeader(props: ItemCardHeaderProps) {\n const { title, subtitle, children } = props;\n const classes = useStyles(props);\n return (\n <Box className={classes.root}>\n {subtitle && (\n <Typography variant=\"subtitle2\" component=\"h3\">\n {subtitle}\n </Typography>\n )}\n {title && (\n <Typography variant=\"h6\" component=\"h4\">\n {title}\n </Typography>\n )}\n {children}\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;AA6BA,MAAM,MAAA,GAAS,CAAC,KAAA,KACd,YAAA,CAAa;AAAA,EACX,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,IAC5B,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,IAC9B,iBAAiB,KAAA,CAAM,YAAA,CAAa,EAAE,OAAA,EAAS,MAAA,EAAQ,CAAA,CAAE,eAAA;AAAA,IACzD,kBAAA,EAAoB,CAAA;AAAA,IACpB,cAAA,EAAgB;AAAA;AAEpB,CAAC,CAAA;AAEH,MAAM,YAAY,UAAA,CAAW,MAAA,EAAQ,EAAE,IAAA,EAAM,2BAA2B,CAAA;AAwCjE,SAAS,eAAe,KAAA,EAA4B;AACzD,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAU,QAAA,EAAS,GAAI,KAAA;AACtC,EAAA,MAAM,OAAA,GAAU,UAAU,KAAK,CAAA;AAC/B,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,IAAA,EACrB,QAAA,EAAA;AAAA,IAAA,QAAA,wBACE,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EAAY,SAAA,EAAU,MACvC,QAAA,EAAA,QAAA,EACH,CAAA;AAAA,IAED,yBACC,GAAA,CAAC,UAAA,EAAA,EAAW,SAAQ,IAAA,EAAK,SAAA,EAAU,MAChC,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,IAED;AAAA,GAAA,EACH,CAAA;AAEJ;;;;"}
1
+ {"version":3,"file":"ItemCardHeader.esm.js","sources":["../../../src/layout/ItemCard/ItemCardHeader.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 Box from '@material-ui/core/Box';\nimport {\n createStyles,\n makeStyles,\n Theme,\n WithStyles,\n} from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport { ReactNode } from 'react';\n\n/** @public */\nexport type ItemCardHeaderClassKey = 'root';\n\nconst styles = (theme: Theme) =>\n createStyles({\n root: {\n color: theme.palette.text.primary,\n padding: theme.spacing(2, 2, 3),\n backgroundImage: theme.getPageTheme({ themeId: 'card' }).backgroundImage,\n backgroundPosition: 0,\n backgroundSize: 'inherit',\n },\n });\n\nconst useStyles = makeStyles(styles, { name: 'BackstageItemCardHeader' });\n\n/** @public */\nexport type ItemCardHeaderProps = Partial<WithStyles<typeof styles>> & {\n /**\n * A large title to show in the header, providing the main heading.\n *\n * Use this if you want to have the default styling and placement of a title.\n */\n title?: ReactNode;\n /**\n * A slightly smaller title to show in the header, providing additional\n * details.\n *\n * Use this if you want to have the default styling and placement of a\n * subtitle.\n */\n subtitle?: ReactNode;\n /**\n * Custom children to draw in the header.\n *\n * If the title and/or subtitle were specified, the children are drawn below\n * those.\n */\n children?: ReactNode;\n};\n\n/**\n * A simple card header, rendering a default look for \"item cards\" - cards that\n * are arranged in a grid for users to select among several options.\n *\n * @remarks\n * This component expects to be placed within a Material UI `<CardMedia>`.\n *\n * Styles for the header can be overridden using the `classes` prop, e.g.:\n *\n * `<ItemCardHeader title=\"Hello\" classes={{ root: myClassName }} />`\n *\n * @public\n */\nexport function ItemCardHeader(props: ItemCardHeaderProps) {\n const { title, subtitle, children } = props;\n const classes = useStyles(props);\n return (\n <Box className={classes.root}>\n {subtitle && (\n <Typography variant=\"subtitle2\" component=\"h3\">\n {subtitle}\n </Typography>\n )}\n {title && (\n <Typography variant=\"h6\" component=\"h4\">\n {title}\n </Typography>\n )}\n {children}\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;AA6BA,MAAM,MAAA,GAAS,CAAC,KAAA,KACd,YAAA,CAAa;AAAA,EACX,IAAA,EAAM;AAAA,IACJ,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,OAAA;AAAA,IAC1B,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,IAC9B,iBAAiB,KAAA,CAAM,YAAA,CAAa,EAAE,OAAA,EAAS,MAAA,EAAQ,CAAA,CAAE,eAAA;AAAA,IACzD,kBAAA,EAAoB,CAAA;AAAA,IACpB,cAAA,EAAgB;AAAA;AAEpB,CAAC,CAAA;AAEH,MAAM,YAAY,UAAA,CAAW,MAAA,EAAQ,EAAE,IAAA,EAAM,2BAA2B,CAAA;AAwCjE,SAAS,eAAe,KAAA,EAA4B;AACzD,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAU,QAAA,EAAS,GAAI,KAAA;AACtC,EAAA,MAAM,OAAA,GAAU,UAAU,KAAK,CAAA;AAC/B,EAAA,uBACE,IAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAW,OAAA,CAAQ,IAAA,EACrB,QAAA,EAAA;AAAA,IAAA,QAAA,wBACE,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EAAY,SAAA,EAAU,MACvC,QAAA,EAAA,QAAA,EACH,CAAA;AAAA,IAED,yBACC,GAAA,CAAC,UAAA,EAAA,EAAW,SAAQ,IAAA,EAAK,SAAA,EAAU,MAChC,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,IAED;AAAA,GAAA,EACH,CAAA;AAEJ;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/core-components",
3
- "version": "0.18.0",
3
+ "version": "0.18.2-next.0",
4
4
  "description": "Core components used by Backstage plugins and apps",
5
5
  "backstage": {
6
6
  "role": "web-library"
@@ -66,11 +66,11 @@
66
66
  "test": "backstage-cli package test"
67
67
  },
68
68
  "dependencies": {
69
- "@backstage/config": "^1.3.3",
70
- "@backstage/core-plugin-api": "^1.11.0",
71
- "@backstage/errors": "^1.2.7",
72
- "@backstage/theme": "^0.6.8",
73
- "@backstage/version-bridge": "^1.0.11",
69
+ "@backstage/config": "1.3.3",
70
+ "@backstage/core-plugin-api": "1.11.0",
71
+ "@backstage/errors": "1.2.7",
72
+ "@backstage/theme": "0.6.8",
73
+ "@backstage/version-bridge": "1.0.11",
74
74
  "@dagrejs/dagre": "^1.1.4",
75
75
  "@date-io/core": "^1.3.13",
76
76
  "@material-table/core": "^3.1.0",
@@ -107,10 +107,10 @@
107
107
  "zod": "^3.22.4"
108
108
  },
109
109
  "devDependencies": {
110
- "@backstage/app-defaults": "^1.7.0",
111
- "@backstage/cli": "^0.34.2",
112
- "@backstage/core-app-api": "^1.19.0",
113
- "@backstage/test-utils": "^1.7.11",
110
+ "@backstage/app-defaults": "1.7.1-next.0",
111
+ "@backstage/cli": "0.34.4-next.0",
112
+ "@backstage/core-app-api": "1.19.0",
113
+ "@backstage/test-utils": "1.7.11",
114
114
  "@testing-library/dom": "^10.0.0",
115
115
  "@testing-library/jest-dom": "^6.0.0",
116
116
  "@testing-library/user-event": "^14.0.0",