@scm-manager/ui-components 4.0.0-REACT19-20250910-124634 → 4.0.0-REACT19-20250913-143258

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scm-manager/ui-components",
3
- "version": "4.0.0-REACT19-20250910-124634",
3
+ "version": "4.0.0-REACT19-20250913-143258",
4
4
  "description": "UI Components for SCM-Manager and its plugins",
5
5
  "main": "src/index.ts",
6
6
  "files": [
@@ -37,10 +37,10 @@
37
37
  "@scm-manager/jest-preset": "^2.15.0-alpha1",
38
38
  "@scm-manager/prettier-config": "^2.12.0",
39
39
  "@scm-manager/tsconfig": "^2.13.0",
40
- "@scm-manager/ui-shortcuts": "4.0.0-REACT19-20250910-124634",
41
- "@scm-manager/ui-syntaxhighlighting": "4.0.0-REACT19-20250910-124634",
42
- "@scm-manager/ui-text": "4.0.0-REACT19-20250910-124634",
43
- "@scm-manager/ui-types": "4.0.0-REACT19-20250910-124634",
40
+ "@scm-manager/ui-shortcuts": "4.0.0-REACT19-20250913-143258",
41
+ "@scm-manager/ui-syntaxhighlighting": "4.0.0-REACT19-20250913-143258",
42
+ "@scm-manager/ui-text": "4.0.0-REACT19-20250913-143258",
43
+ "@scm-manager/ui-types": "4.0.0-REACT19-20250913-143258",
44
44
  "@storybook/addon-actions": "^9.0.8",
45
45
  "@storybook/addon-docs": "^9.1.5",
46
46
  "@storybook/addon-essentials": "^9.0.0-alpha.12",
@@ -67,12 +67,12 @@
67
67
  "storybook-addon-themes": "^6.1.0"
68
68
  },
69
69
  "dependencies": {
70
- "@scm-manager/ui-api": "4.0.0-REACT19-20250910-124634",
71
- "@scm-manager/ui-buttons": "4.0.0-REACT19-20250910-124634",
72
- "@scm-manager/ui-core": "4.0.0-REACT19-20250910-124634",
73
- "@scm-manager/ui-extensions": "4.0.0-REACT19-20250910-124634",
74
- "@scm-manager/ui-layout": "4.0.0-REACT19-20250910-124634",
75
- "@scm-manager/ui-overlays": "4.0.0-REACT19-20250910-124634",
70
+ "@scm-manager/ui-api": "4.0.0-REACT19-20250913-143258",
71
+ "@scm-manager/ui-buttons": "4.0.0-REACT19-20250913-143258",
72
+ "@scm-manager/ui-core": "4.0.0-REACT19-20250913-143258",
73
+ "@scm-manager/ui-extensions": "4.0.0-REACT19-20250913-143258",
74
+ "@scm-manager/ui-layout": "4.0.0-REACT19-20250913-143258",
75
+ "@scm-manager/ui-overlays": "4.0.0-REACT19-20250913-143258",
76
76
  "deepmerge": "^4.2.2",
77
77
  "hast-util-sanitize": "^3.0.2",
78
78
  "react-diff-view": "^2.4.10",
package/src/Image.tsx CHANGED
@@ -22,6 +22,7 @@ type Props = {
22
22
  alt: string;
23
23
  title?: string;
24
24
  className?: string;
25
+ crossOrigin?: "anonymous" | "";
25
26
  };
26
27
 
27
28
  /**
@@ -37,8 +38,8 @@ class Image extends React.Component<Props> {
37
38
  };
38
39
 
39
40
  render() {
40
- const { alt, title, className } = this.props;
41
- return <img className={className} src={this.createImageSrc()} alt={alt} title={title} />;
41
+ const { alt, title, className, crossOrigin } = this.props;
42
+ return <img className={className} src={this.createImageSrc()} alt={alt} title={title} crossOrigin={crossOrigin} />;
42
43
  }
43
44
  }
44
45
 
@@ -1825,18 +1825,20 @@ exports[`Storyshots Footer Full 1`] = `
1825
1825
  className="has-text-weight-bold mb-2"
1826
1826
  >
1827
1827
  <div
1828
+ className="is-flex"
1828
1829
  data-testid="trillian-mcmillian"
1829
1830
  >
1830
- <span
1831
- className="Footer__AvatarContainer-sc-k70cxq-1 kckyuz image is-rounded"
1832
- >
1831
+ <div>
1833
1832
  <img
1834
1833
  alt="trillian"
1835
- className="is-rounded Footer__VCenteredAvatar-sc-k70cxq-0 bGojWR"
1834
+ className="is-rounded Footer__VCenteredAvatar-sc-k70cxq-0 gNPbnb"
1835
+ crossOrigin="anonymous"
1836
1836
  src="test-file-stub"
1837
1837
  />
1838
- </span>
1839
- Trillian McMillian
1838
+ </div>
1839
+ <div>
1840
+ Trillian McMillian
1841
+ </div>
1840
1842
  </div>
1841
1843
  </h2>
1842
1844
  <ul
@@ -2031,18 +2033,20 @@ exports[`Storyshots Footer With Avatar 1`] = `
2031
2033
  className="has-text-weight-bold mb-2"
2032
2034
  >
2033
2035
  <div
2036
+ className="is-flex"
2034
2037
  data-testid="trillian-mcmillian"
2035
2038
  >
2036
- <span
2037
- className="Footer__AvatarContainer-sc-k70cxq-1 kckyuz image is-rounded"
2038
- >
2039
+ <div>
2039
2040
  <img
2040
2041
  alt="trillian"
2041
- className="is-rounded Footer__VCenteredAvatar-sc-k70cxq-0 bGojWR"
2042
+ className="is-rounded Footer__VCenteredAvatar-sc-k70cxq-0 gNPbnb"
2043
+ crossOrigin="anonymous"
2042
2044
  src="test-file-stub"
2043
2045
  />
2044
- </span>
2045
- Trillian McMillian
2046
+ </div>
2047
+ <div>
2048
+ Trillian McMillian
2049
+ </div>
2046
2050
  </div>
2047
2051
  </h2>
2048
2052
  <ul
@@ -20073,6 +20077,7 @@ exports[`Storyshots Repositories/Annotate With Avatars 1`] = `
20073
20077
  <img
20074
20078
  alt="Arthur Dent"
20075
20079
  className="has-rounded-border AuthorImage-sc-ygvjd8-0 dTapGF"
20080
+ crossOrigin="anonymous"
20076
20081
  src="https://robohash.org/arthur.dent@hitchhiker.com.png"
20077
20082
  />
20078
20083
  Arthur Dent
@@ -20135,6 +20140,7 @@ exports[`Storyshots Repositories/Annotate With Avatars 1`] = `
20135
20140
  <img
20136
20141
  alt="Tricia Marie McMillan"
20137
20142
  className="has-rounded-border AuthorImage-sc-ygvjd8-0 dTapGF"
20143
+ crossOrigin="anonymous"
20138
20144
  src="https://robohash.org/trillian@hitchhiker.com.png"
20139
20145
  />
20140
20146
  Tricia Marie McMillan
@@ -20197,6 +20203,7 @@ exports[`Storyshots Repositories/Annotate With Avatars 1`] = `
20197
20203
  <img
20198
20204
  alt="Arthur Dent"
20199
20205
  className="has-rounded-border AuthorImage-sc-ygvjd8-0 dTapGF"
20206
+ crossOrigin="anonymous"
20200
20207
  src="https://robohash.org/arthur.dent@hitchhiker.com.png"
20201
20208
  />
20202
20209
  Arthur Dent
@@ -20241,6 +20248,7 @@ exports[`Storyshots Repositories/Annotate With Avatars 1`] = `
20241
20248
  <img
20242
20249
  alt="Ford Prefect"
20243
20250
  className="has-rounded-border AuthorImage-sc-ygvjd8-0 dTapGF"
20251
+ crossOrigin="anonymous"
20244
20252
  src="https://robohash.org/ford.prefect@hitchhiker.com.png"
20245
20253
  />
20246
20254
  Ford Prefect
@@ -20285,6 +20293,7 @@ exports[`Storyshots Repositories/Annotate With Avatars 1`] = `
20285
20293
  <img
20286
20294
  alt="Arthur Dent"
20287
20295
  className="has-rounded-border AuthorImage-sc-ygvjd8-0 dTapGF"
20296
+ crossOrigin="anonymous"
20288
20297
  src="https://robohash.org/arthur.dent@hitchhiker.com.png"
20289
20298
  />
20290
20299
  Arthur Dent
@@ -20367,11 +20376,12 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
20367
20376
  className="media-left mt-2 mr-2"
20368
20377
  >
20369
20378
  <div
20370
- className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 cDjLjl image"
20379
+ className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 gwbxYG image"
20371
20380
  >
20372
20381
  <img
20373
20382
  alt="SCM Administrator"
20374
20383
  className="has-rounded-border"
20384
+ crossOrigin="anonymous"
20375
20385
  src="https://robohash.org/scm-admin@scm-manager.org"
20376
20386
  />
20377
20387
  </div>
@@ -20425,6 +20435,7 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
20425
20435
  <img
20426
20436
  alt="Ford Prefect"
20427
20437
  className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
20438
+ crossOrigin="anonymous"
20428
20439
  src="https://robohash.org/ford.prefect@hitchhiker.com"
20429
20440
  />
20430
20441
  </a>
@@ -20435,6 +20446,7 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
20435
20446
  <img
20436
20447
  alt="Zaphod Beeblebrox"
20437
20448
  className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
20449
+ crossOrigin="anonymous"
20438
20450
  src="https://robohash.org/zaphod.beeblebrox@hitchhiker.cm"
20439
20451
  />
20440
20452
  </a>
@@ -20445,6 +20457,7 @@ exports[`Storyshots Repositories/Changesets Co-Authors with avatar 1`] = `
20445
20457
  <img
20446
20458
  alt="Tricia Marie McMillan"
20447
20459
  className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
20460
+ crossOrigin="anonymous"
20448
20461
  src="https://robohash.org/trillian@hitchhiker.cm"
20449
20462
  />
20450
20463
  </a>
@@ -20541,11 +20554,12 @@ exports[`Storyshots Repositories/Changesets Commiter and Co-Authors with avatar
20541
20554
  className="media-left mt-2 mr-2"
20542
20555
  >
20543
20556
  <div
20544
- className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 cDjLjl image"
20557
+ className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 gwbxYG image"
20545
20558
  >
20546
20559
  <img
20547
20560
  alt="SCM Administrator"
20548
20561
  className="has-rounded-border"
20562
+ crossOrigin="anonymous"
20549
20563
  src="https://robohash.org/scm-admin@scm-manager.org"
20550
20564
  />
20551
20565
  </div>
@@ -20594,6 +20608,7 @@ exports[`Storyshots Repositories/Changesets Commiter and Co-Authors with avatar
20594
20608
  <img
20595
20609
  alt="Zaphod Beeblebrox"
20596
20610
  className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
20611
+ crossOrigin="anonymous"
20597
20612
  src="https://robohash.org/zaphod.beeblebrox@hitchhiker.cm"
20598
20613
  />
20599
20614
  </a>
@@ -20609,6 +20624,7 @@ exports[`Storyshots Repositories/Changesets Commiter and Co-Authors with avatar
20609
20624
  <img
20610
20625
  alt="Ford Prefect"
20611
20626
  className="ContributorAvatar-sc-1yz8zn-0 lhgGHS"
20627
+ crossOrigin="anonymous"
20612
20628
  src="https://robohash.org/ford.prefect@hitchhiker.com"
20613
20629
  />
20614
20630
  </a>
@@ -21613,11 +21629,12 @@ exports[`Storyshots Repositories/Changesets With avatar 1`] = `
21613
21629
  className="media-left mt-2 mr-2"
21614
21630
  >
21615
21631
  <div
21616
- className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 cDjLjl image"
21632
+ className="SingleChangeset__FixedSizedAvatar-sc-ytpqp9-0 gwbxYG image"
21617
21633
  >
21618
21634
  <img
21619
21635
  alt="SCM Administrator"
21620
21636
  className="has-rounded-border"
21637
+ crossOrigin="anonymous"
21621
21638
  src="test-file-stub"
21622
21639
  />
21623
21640
  </div>
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  import React, { FC } from "react";
18
- import Image from "../Image";
18
+ import { Image } from "@scm-manager/ui-core";
19
19
  import { EXTENSION_POINT, Person } from "./Avatar";
20
20
  import { useBinder } from "@scm-manager/ui-extensions";
21
21
 
@@ -36,7 +36,7 @@ const AvatarImage: FC<Props> = ({ person, representation = "rounded-border", cla
36
36
  classes += " " + className;
37
37
  }
38
38
 
39
- return <Image className={classes} src={avatar} alt={person.name} />;
39
+ return <Image className={classes} src={avatar} alt={person.name} crossOrigin="anonymous" />;
40
40
  }
41
41
 
42
42
  return null;
@@ -51,23 +51,19 @@ type TitleWithAvatarProps = {
51
51
  };
52
52
 
53
53
  const VCenteredAvatar = styled(AvatarImage)`
54
- vertical-align: middle;
55
- `;
56
-
57
- const AvatarContainer = styled.span`
58
- float: left;
54
+ width: 1rem !important;
55
+ height: 1rem !important;
59
56
  margin-right: 0.3em;
60
57
  padding-top: 0.2em;
61
- width: 1em;
62
- height: 1em;
58
+ border-radius: 100%;
63
59
  `;
64
60
 
65
61
  const TitleWithAvatar: FC<TitleWithAvatarProps> = ({ me }) => (
66
- <div {...createAttributesForTesting(me.displayName)}>
67
- <AvatarContainer className="image is-rounded">
62
+ <div {...createAttributesForTesting(me.displayName)} className="is-flex">
63
+ <div>
68
64
  <VCenteredAvatar person={me} representation="rounded" />
69
- </AvatarContainer>
70
- {me.displayName}
65
+ </div>
66
+ <div>{me.displayName}</div>
71
67
  </div>
72
68
  );
73
69
 
@@ -14,9 +14,9 @@
14
14
  * along with this program. If not, see https://www.gnu.org/licenses/.
15
15
  */
16
16
 
17
- import { ReactNode } from "react";
17
+ import { FC, PropsWithChildren, ReactNode } from "react";
18
18
  import { DefaultCollapsed } from "./defaultCollapsed";
19
- import { Change, Hunk, FileDiff as File } from "@scm-manager/ui-types";
19
+ import { Change, Hunk, FileDiff as File, FileChangeType } from "@scm-manager/ui-types";
20
20
 
21
21
  export type ChangeEvent = {
22
22
  change: Change;
@@ -31,6 +31,20 @@ export type AnnotationFactoryContext = BaseContext;
31
31
 
32
32
  export type FileAnnotationFactory = (file: File) => ReactNode[];
33
33
 
34
+ export type FileTreeNodeWrapper = FC<
35
+ PropsWithChildren & {
36
+ name: string;
37
+ path: string;
38
+ changeType?: FileChangeType;
39
+ iconName: string;
40
+ iconColor: string;
41
+ isFile: boolean;
42
+ originalIcon: ReactNode;
43
+ originalLabel: ReactNode;
44
+ isCurrentFile: boolean;
45
+ }
46
+ >;
47
+
34
48
  // key = change id, value = react component
35
49
  export type AnnotationFactory = (context: AnnotationFactoryContext) => {
36
50
  [key: string]: any;
@@ -57,11 +57,11 @@ const ContributorWithAvatar: FC<PersonAvatarProps> = ({ person, avatar }) => {
57
57
  if (person.mail) {
58
58
  return (
59
59
  <a href={"mailto:" + person.mail} title={t("changeset.contributors.mailto") + " " + person.mail}>
60
- <ContributorAvatar src={avatar} alt={person.name} />
60
+ <ContributorAvatar src={avatar} alt={person.name} crossOrigin="anonymous" />
61
61
  </a>
62
62
  );
63
63
  }
64
- return <ContributorAvatar src={avatar} alt={person.name} title={person.name} />;
64
+ return <ContributorAvatar src={avatar} alt={person.name} title={person.name} crossOrigin="anonymous" />;
65
65
  };
66
66
 
67
67
  export const SingleContributor: FC<PersonProps> = ({ person, className, displayTextOnly }) => {
@@ -30,7 +30,7 @@ const Contributor: FC<{ person: Person }> = ({ person }) => {
30
30
  if (avatar) {
31
31
  prefix = (
32
32
  <>
33
- <ContributorAvatar src={avatar} alt={person.name} />{" "}
33
+ <ContributorAvatar src={avatar} alt={person.name} crossOrigin="anonymous" />{" "}
34
34
  </>
35
35
  );
36
36
  }
@@ -37,6 +37,7 @@ type Props = {
37
37
  const FixedSizedAvatar = styled.div`
38
38
  width: 35px;
39
39
  height: 35px;
40
+ overflow: hidden;
40
41
  `;
41
42
 
42
43
  const FullWidthDiv = styled.div`
@@ -18,12 +18,19 @@ import React, { FC } from "react";
18
18
  import { Link } from "react-router-dom";
19
19
  import { useTranslation } from "react-i18next";
20
20
  import classNames from "classnames";
21
- import { FileTree } from "@scm-manager/ui-types";
21
+ import { FileChangeType, FileTree } from "@scm-manager/ui-types";
22
22
  import { FileDiffContent, StackedSpan, StyledIcon } from "./styledElements";
23
+ import { FileTreeNodeWrapper } from "../DiffTypes";
23
24
 
24
- type Props = { tree: FileTree; currentFile: string; setCurrentFile: (path: string) => void; gap?: number };
25
+ type Props = {
26
+ tree: FileTree;
27
+ currentFile: string;
28
+ setCurrentFile: (path: string) => void;
29
+ gap?: number;
30
+ FileTreeNodeWrapper?: FileTreeNodeWrapper;
31
+ };
25
32
 
26
- const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15 }) => {
33
+ const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15, FileTreeNodeWrapper }) => {
27
34
  return (
28
35
  <FileDiffContent gap={gap}>
29
36
  {Object.keys(tree.children).map((key) => (
@@ -33,6 +40,7 @@ const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15 }
33
40
  parentPath=""
34
41
  currentFile={currentFile}
35
42
  setCurrentFile={setCurrentFile}
43
+ FileTreeNodeWrapper={FileTreeNodeWrapper}
36
44
  />
37
45
  ))}
38
46
  </FileDiffContent>
@@ -41,9 +49,13 @@ const DiffFileTree: FC<Props> = ({ tree, currentFile, setCurrentFile, gap = 15 }
41
49
 
42
50
  export default DiffFileTree;
43
51
 
44
- type ChangeType = "add" | "modify" | "delete" | "rename" | "copy";
45
-
46
- type NodeProps = { node: FileTree; parentPath: string; currentFile: string; setCurrentFile: (path: string) => void };
52
+ type NodeProps = {
53
+ node: FileTree;
54
+ parentPath: string;
55
+ currentFile: string;
56
+ setCurrentFile: (path: string) => void;
57
+ FileTreeNodeWrapper?: FileTreeNodeWrapper;
58
+ };
47
59
 
48
60
  const addPath = (parentPath: string, path: string) => {
49
61
  if ("" === parentPath) {
@@ -52,16 +64,31 @@ const addPath = (parentPath: string, path: string) => {
52
64
  return parentPath + "/" + path;
53
65
  };
54
66
 
55
- const TreeNode: FC<NodeProps> = ({ node, parentPath, currentFile, setCurrentFile }) => {
67
+ const TreeNode: FC<NodeProps> = ({ node, parentPath, currentFile, setCurrentFile, FileTreeNodeWrapper }) => {
56
68
  const [t] = useTranslation("repos");
57
69
 
70
+ FileTreeNodeWrapper = FileTreeNodeWrapper || (({ children }) => <>{children}</>);
71
+
72
+ const label = <div className="ml-1">{node.nodeName}</div>;
73
+ const icon = <StyledIcon alt={t("diff.showContent")}>folder</StyledIcon>;
58
74
  return (
59
75
  <li>
60
76
  {Object.keys(node.children).length > 0 ? (
61
77
  <ul className="py-1 pl-3">
62
78
  <li className="is-flex has-text-grey">
63
- <StyledIcon alt={t("diff.showContent")}>folder</StyledIcon>
64
- <div className="ml-1">{node.nodeName}</div>
79
+ <FileTreeNodeWrapper
80
+ path={addPath(parentPath, node.nodeName)}
81
+ isFile={false}
82
+ isCurrentFile={false}
83
+ name={node.nodeName}
84
+ iconName={"folder"}
85
+ iconColor={"grey"}
86
+ originalIcon={icon}
87
+ originalLabel={label}
88
+ >
89
+ {icon}
90
+ {label}
91
+ </FileTreeNodeWrapper>
65
92
  </li>
66
93
  {Object.keys(node.children).map((key) => (
67
94
  <TreeNode
@@ -70,23 +97,25 @@ const TreeNode: FC<NodeProps> = ({ node, parentPath, currentFile, setCurrentFile
70
97
  parentPath={addPath(parentPath, node.nodeName)}
71
98
  currentFile={currentFile}
72
99
  setCurrentFile={setCurrentFile}
100
+ FileTreeNodeWrapper={FileTreeNodeWrapper}
73
101
  />
74
102
  ))}
75
103
  </ul>
76
104
  ) : (
77
105
  <TreeFile
78
- changeType={node.changeType.toLowerCase() as ChangeType}
106
+ changeType={node.changeType.toLowerCase() as FileChangeType}
79
107
  path={node.nodeName}
80
108
  parentPath={parentPath}
81
109
  currentFile={currentFile}
82
110
  setCurrentFile={setCurrentFile}
111
+ FileTreeNodeWrapper={FileTreeNodeWrapper}
83
112
  />
84
113
  )}
85
114
  </li>
86
115
  );
87
116
  };
88
117
 
89
- const getColor = (changeType: ChangeType) => {
118
+ const getColor = (changeType: FileChangeType) => {
90
119
  switch (changeType) {
91
120
  case "add":
92
121
  return "success";
@@ -99,7 +128,7 @@ const getColor = (changeType: ChangeType) => {
99
128
  }
100
129
  };
101
130
 
102
- const getIcon = (changeType: ChangeType) => {
131
+ const getIcon = (changeType: FileChangeType) => {
103
132
  switch (changeType) {
104
133
  case "add":
105
134
  case "copy":
@@ -113,14 +142,22 @@ const getIcon = (changeType: ChangeType) => {
113
142
  };
114
143
 
115
144
  type FileProps = {
116
- changeType: ChangeType;
145
+ changeType: FileChangeType;
117
146
  path: string;
118
147
  parentPath: string;
119
148
  currentFile: string;
120
149
  setCurrentFile: (path: string) => void;
150
+ FileTreeNodeWrapper: FileTreeNodeWrapper;
121
151
  };
122
152
 
123
- const TreeFile: FC<FileProps> = ({ changeType, path, parentPath, currentFile, setCurrentFile }) => {
153
+ const TreeFile: FC<FileProps> = ({
154
+ changeType,
155
+ path,
156
+ parentPath,
157
+ currentFile,
158
+ setCurrentFile,
159
+ FileTreeNodeWrapper,
160
+ }) => {
124
161
  const [t] = useTranslation("repos");
125
162
  const completePath = addPath(parentPath, path);
126
163
 
@@ -128,35 +165,50 @@ const TreeFile: FC<FileProps> = ({ changeType, path, parentPath, currentFile, se
128
165
  return currentFile === completePath;
129
166
  };
130
167
 
168
+ const iconName = getIcon(changeType);
169
+
170
+ const icon = (
171
+ <StackedSpan className="fa-stack">
172
+ <StyledIcon
173
+ className={classNames("fa-stack-2x", `has-text-${getColor(changeType)}`)}
174
+ key={completePath + "file"}
175
+ type="fas"
176
+ alt={t("diff.showContent")}
177
+ >
178
+ file
179
+ </StyledIcon>
180
+ <StyledIcon
181
+ className={classNames("fa-stack-1x", "is-relative", "has-text-secondary-least")}
182
+ issmaller={iconName === "circle" ? "true" : "false"}
183
+ key={changeType}
184
+ alt={t(`diff.changes.${changeType}`)}
185
+ >
186
+ {iconName}
187
+ </StyledIcon>
188
+ </StackedSpan>
189
+ );
190
+ const label = <div className={classNames("ml-1", isCurrentFile() ? "has-text-weight-bold" : "")}>{path}</div>;
191
+
131
192
  return (
132
193
  <Link
133
194
  className="is-flex py-1 pl-3 has-cursor-pointer"
134
195
  onClick={() => setCurrentFile(completePath)}
135
196
  to={`#diff-${encodeURIComponent(completePath)}`}
136
197
  >
137
- <StackedSpan className="fa-stack">
138
- <StyledIcon
139
- className={classNames("fa-stack-2x", `has-text-${getColor(changeType)}`)}
140
- key={completePath + "file"}
141
- type={isCurrentFile() ? "fas" : "far"}
142
- alt={t("diff.showContent")}
143
- >
144
- file
145
- </StyledIcon>
146
- <StyledIcon
147
- className={classNames(
148
- "fa-stack-1x",
149
- "is-relative",
150
- isCurrentFile() ? "has-text-secondary-least" : `has-text-${getColor(changeType)}`
151
- )}
152
- issmaller={getIcon(changeType) === "circle" ? "true" : "false"}
153
- key={changeType}
154
- alt={t(`diff.changes.${changeType}`)}
155
- >
156
- {getIcon(changeType)}
157
- </StyledIcon>
158
- </StackedSpan>
159
- <div className="ml-1">{path}</div>
198
+ <FileTreeNodeWrapper
199
+ name={path}
200
+ path={completePath}
201
+ changeType={changeType}
202
+ isFile={true}
203
+ iconName={iconName}
204
+ iconColor={getColor(changeType)}
205
+ originalIcon={icon}
206
+ originalLabel={label}
207
+ isCurrentFile={isCurrentFile()}
208
+ >
209
+ {icon}
210
+ {label}
211
+ </FileTreeNodeWrapper>
160
212
  </Link>
161
213
  );
162
214
  };