@teambit/component.ui.component-compare.compare-aspects.compare-aspect-view 0.0.0-aceda4bd6dc966a1bd6ded58b3532380581cb4a5

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.
@@ -0,0 +1,97 @@
1
+ $editor-padding: 56px;
2
+
3
+ .componentCompareAspectViewContainer {
4
+ width: 100%;
5
+ height: 100%;
6
+ }
7
+ .componentCompareAspectDiffEditorContainer {
8
+ padding: 0px 8px;
9
+ display: flex;
10
+ flex-direction: column;
11
+ height: calc(100% - $editor-padding);
12
+ min-height: 0;
13
+ overflow-y: auto;
14
+ }
15
+
16
+ .name {
17
+ display: flex;
18
+ align-items: baseline;
19
+ padding: 8px;
20
+ }
21
+
22
+ .componentCompareAspectConfigDiff,
23
+ .componentCompareAspectCalculatedDiff {
24
+ display: flex;
25
+ flex: 1 0 auto;
26
+ padding: 0px 8px;
27
+ min-height: 0;
28
+ flex-direction: column;
29
+ }
30
+
31
+ .diffEditor {
32
+ width: 100%;
33
+ }
34
+
35
+ .diffWithActions {
36
+ position: relative;
37
+ width: 100%;
38
+ }
39
+
40
+ .copyActions {
41
+ position: absolute;
42
+ z-index: 1;
43
+ top: 8px;
44
+ right: 18px;
45
+ display: flex;
46
+ gap: 8px;
47
+ }
48
+
49
+ .loader {
50
+ display: flex;
51
+ align-items: center;
52
+ justify-items: center;
53
+ height: 100%;
54
+ width: 100%;
55
+ // Skeleton shimmer built from theme surfaces. It ran to a hard-coded #2b2b2b, which on a light page
56
+ // produced grey-on-grey bands.
57
+ color: var(--surface-neutral-color, #fff);
58
+ background-image: linear-gradient(
59
+ to right,
60
+ currentColor 0%,
61
+ var(--surface-neutral-hover-color, #f4f5f6) 30%,
62
+ var(--surface-neutral-hover-color, #f4f5f6) 50%,
63
+ currentColor 100%
64
+ );
65
+ > div {
66
+ background-image: linear-gradient(
67
+ to right,
68
+ currentColor 0%,
69
+ var(--surface-neutral-hover-color, #f4f5f6) 30%,
70
+ var(--surface-neutral-hover-color, #f4f5f6) 50%,
71
+ currentColor 100%
72
+ );
73
+ }
74
+ }
75
+
76
+ .copyButton {
77
+ cursor: pointer;
78
+ border: 0;
79
+ padding: 4px;
80
+ border-radius: 4px;
81
+ color: inherit;
82
+ background: var(--surface-color, #fff);
83
+ opacity: 0;
84
+
85
+ &.isLabelVisible {
86
+ opacity: 1;
87
+ }
88
+ }
89
+
90
+ .diffWithActions:hover .copyButton,
91
+ .copyButton:focus-visible {
92
+ opacity: 1;
93
+ }
94
+
95
+ .message {
96
+ left: 0;
97
+ }
@@ -0,0 +1,16 @@
1
+ import { unchangedContext } from './config-editor';
2
+
3
+ // Tests the decision only, without rendering: rendering needs `react-dom`, and this component's env can
4
+ // resolve a `react-dom` that does not match its `react`, which fails the suite before it runs.
5
+ jest.mock('@teambit/code.ui.diff-viewer', () => ({ DiffViewer: () => null }));
6
+
7
+ describe('unchangedContext', () => {
8
+ it('gives unlimited context when both sides are the same, so the diff is shown in full', () => {
9
+ const same = JSON.stringify({ policy: {} }, null, 2);
10
+ expect(unchangedContext(same, same)).toBe(Number.MAX_SAFE_INTEGER);
11
+ });
12
+
13
+ it('keeps the default context when the sides differ', () => {
14
+ expect(unchangedContext('{}', '{ "policy": {} }')).toBeUndefined();
15
+ });
16
+ });
@@ -0,0 +1,84 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ import React, { useMemo } from 'react';
3
+ import classNames from 'classnames';
4
+ import { H4 } from '@teambit/documenter.ui.heading';
5
+ import { BlockSkeleton } from '@teambit/base-ui.loaders.skeleton';
6
+ import { DiffViewer } from '@teambit/code.ui.diff-viewer';
7
+ import type { ComponentAspectData } from '@teambit/component.ui.component-compare.compare-aspects.models.component-compare-aspects-model';
8
+ import { ConfigDiffEditor, unchangedContext } from './config-editor';
9
+ import styles from './compare-aspect-view.module.scss';
10
+
11
+ export type CompareAspectViewProps = {
12
+ baseAspectData?: ComponentAspectData;
13
+ compareAspectData?: ComponentAspectData;
14
+ loading?: boolean;
15
+ name?: string;
16
+ } & HTMLAttributes<HTMLDivElement>;
17
+
18
+ export function CompareAspectView({
19
+ baseAspectData,
20
+ compareAspectData,
21
+ name,
22
+ loading,
23
+ className,
24
+ }: CompareAspectViewProps) {
25
+ const title = useMemo(() => name?.split('/').pop(), [name]);
26
+ const originalConfig = JSON.stringify(baseAspectData?.config, null, 2) || '';
27
+ const modifiedConfig = JSON.stringify(compareAspectData?.config, null, 2) || '';
28
+ const originalData = JSON.stringify(baseAspectData?.data, null, 2) || '';
29
+ const modifiedData = JSON.stringify(compareAspectData?.data, null, 2) || '';
30
+
31
+ return (
32
+ <div
33
+ key={`aspect-diff-editor-${title}`}
34
+ className={classNames(styles.componentCompareAspectViewContainer, className)}
35
+ >
36
+ <div className={styles.name}>
37
+ <H4 size="xs" className={styles.name}>
38
+ <span>{title}</span>
39
+ </H4>
40
+ </div>
41
+ <div className={styles.componentCompareAspectDiffEditorContainer}>
42
+ <div className={styles.componentCompareAspectConfigDiff}>
43
+ <H4 size="xxs" className={styles.name}>
44
+ <span>Config</span>
45
+ </H4>
46
+ {loading ? (
47
+ <AspectsCompareViewLoader />
48
+ ) : (
49
+ <ConfigDiffEditor
50
+ original={originalConfig}
51
+ modified={modifiedConfig}
52
+ name={`${title || 'aspect'} config`}
53
+ />
54
+ )}
55
+ </div>
56
+ <div className={styles.componentCompareAspectCalculatedDiff}>
57
+ <H4 size="xxs" className={styles.name}>
58
+ <span>Calculated Data</span>
59
+ </H4>
60
+ {loading ? (
61
+ <AspectsCompareViewLoader />
62
+ ) : (
63
+ <DiffViewer
64
+ className={styles.diffEditor}
65
+ fileName={`${title || 'aspect'}-data.json`}
66
+ oldContent={originalData}
67
+ newContent={modifiedData}
68
+ language="json"
69
+ defaultView="split"
70
+ showHeader={false}
71
+ collapsible={false}
72
+ maxHeight={420}
73
+ contextLines={unchangedContext(originalData, modifiedData)}
74
+ />
75
+ )}
76
+ </div>
77
+ </div>
78
+ </div>
79
+ );
80
+ }
81
+
82
+ function AspectsCompareViewLoader() {
83
+ return <BlockSkeleton className={styles.loader} lines={16} />;
84
+ }
@@ -0,0 +1,69 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ import React, { useState } from 'react';
3
+ import copy from 'copy-to-clipboard';
4
+ import classNames from 'classnames';
5
+ import { CopiedMessage } from '@teambit/documenter.ui.copied-message';
6
+ import { DiffViewer } from '@teambit/code.ui.diff-viewer';
7
+ import { Icon } from '@teambit/design.elements.icon';
8
+
9
+ import styles from './compare-aspect-view.module.scss';
10
+
11
+ export type ConfigDiffEditorProps = {
12
+ original?: string;
13
+ modified?: string;
14
+ name?: string;
15
+ } & HTMLAttributes<HTMLDivElement>;
16
+
17
+ export function ConfigDiffEditor({ original = '', modified = '', name = 'aspect config' }: ConfigDiffEditorProps) {
18
+ return (
19
+ <div className={styles.diffWithActions}>
20
+ <div className={styles.copyActions}>
21
+ {original && <CopyButton text={original} label="Copy base config" />}
22
+ {modified && <CopyButton text={modified} label="Copy changed config" />}
23
+ </div>
24
+ <DiffViewer
25
+ className={styles.diffEditor}
26
+ fileName={`${name}.json`}
27
+ oldContent={original}
28
+ newContent={modified}
29
+ language="json"
30
+ defaultView="split"
31
+ showHeader={false}
32
+ collapsible={false}
33
+ maxHeight={420}
34
+ contextLines={unchangedContext(original, modified)}
35
+ />
36
+ </div>
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Unlimited context when both sides are the same: an unchanged config has no change to collapse
42
+ * toward, so the default context would hide all of it behind a single "Expand N unchanged lines".
43
+ */
44
+ export function unchangedContext(original: string, modified: string): number | undefined {
45
+ return original === modified ? Number.MAX_SAFE_INTEGER : undefined;
46
+ }
47
+
48
+ function CopyButton({ text, label }: { text: string; label: string }) {
49
+ const [isCopied, setCopied] = useState(false);
50
+
51
+ const handleCopy = () => {
52
+ copy(text);
53
+ setCopied(true);
54
+ setTimeout(() => setCopied(false), 2000);
55
+ };
56
+
57
+ return (
58
+ <button
59
+ type="button"
60
+ aria-label={label}
61
+ title={label}
62
+ className={classNames(styles.copyButton, isCopied && styles.isLabelVisible)}
63
+ onClick={handleCopy}
64
+ >
65
+ <Icon className={styles.copyIcon} of="copy-cmp" />
66
+ <CopiedMessage className={styles.message} show={isCopied} />
67
+ </button>
68
+ );
69
+ }
@@ -0,0 +1,10 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ import React from 'react';
3
+ import type { ComponentAspectData } from '@teambit/component.ui.component-compare.compare-aspects.models.component-compare-aspects-model';
4
+ export type CompareAspectViewProps = {
5
+ baseAspectData?: ComponentAspectData;
6
+ compareAspectData?: ComponentAspectData;
7
+ loading?: boolean;
8
+ name?: string;
9
+ } & HTMLAttributes<HTMLDivElement>;
10
+ export declare function CompareAspectView({ baseAspectData, compareAspectData, name, loading, className, }: CompareAspectViewProps): React.JSX.Element;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.CompareAspectView = CompareAspectView;
40
+ const react_1 = __importStar(require("react"));
41
+ const classnames_1 = __importDefault(require("classnames"));
42
+ const documenter_ui_heading_1 = require("@teambit/documenter.ui.heading");
43
+ const base_ui_loaders_skeleton_1 = require("@teambit/base-ui.loaders.skeleton");
44
+ const code_ui_diff_viewer_1 = require("@teambit/code.ui.diff-viewer");
45
+ const config_editor_1 = require("./config-editor");
46
+ const compare_aspect_view_module_scss_1 = __importDefault(require("./compare-aspect-view.module.scss"));
47
+ function CompareAspectView({ baseAspectData, compareAspectData, name, loading, className, }) {
48
+ const title = (0, react_1.useMemo)(() => name === null || name === void 0 ? void 0 : name.split('/').pop(), [name]);
49
+ const originalConfig = JSON.stringify(baseAspectData === null || baseAspectData === void 0 ? void 0 : baseAspectData.config, null, 2) || '';
50
+ const modifiedConfig = JSON.stringify(compareAspectData === null || compareAspectData === void 0 ? void 0 : compareAspectData.config, null, 2) || '';
51
+ const originalData = JSON.stringify(baseAspectData === null || baseAspectData === void 0 ? void 0 : baseAspectData.data, null, 2) || '';
52
+ const modifiedData = JSON.stringify(compareAspectData === null || compareAspectData === void 0 ? void 0 : compareAspectData.data, null, 2) || '';
53
+ return (react_1.default.createElement("div", { key: `aspect-diff-editor-${title}`, className: (0, classnames_1.default)(compare_aspect_view_module_scss_1.default.componentCompareAspectViewContainer, className) },
54
+ react_1.default.createElement("div", { className: compare_aspect_view_module_scss_1.default.name },
55
+ react_1.default.createElement(documenter_ui_heading_1.H4, { size: "xs", className: compare_aspect_view_module_scss_1.default.name },
56
+ react_1.default.createElement("span", null, title))),
57
+ react_1.default.createElement("div", { className: compare_aspect_view_module_scss_1.default.componentCompareAspectDiffEditorContainer },
58
+ react_1.default.createElement("div", { className: compare_aspect_view_module_scss_1.default.componentCompareAspectConfigDiff },
59
+ react_1.default.createElement(documenter_ui_heading_1.H4, { size: "xxs", className: compare_aspect_view_module_scss_1.default.name },
60
+ react_1.default.createElement("span", null, "Config")),
61
+ loading ? (react_1.default.createElement(AspectsCompareViewLoader, null)) : (react_1.default.createElement(config_editor_1.ConfigDiffEditor, { original: originalConfig, modified: modifiedConfig, name: `${title || 'aspect'} config` }))),
62
+ react_1.default.createElement("div", { className: compare_aspect_view_module_scss_1.default.componentCompareAspectCalculatedDiff },
63
+ react_1.default.createElement(documenter_ui_heading_1.H4, { size: "xxs", className: compare_aspect_view_module_scss_1.default.name },
64
+ react_1.default.createElement("span", null, "Calculated Data")),
65
+ loading ? (react_1.default.createElement(AspectsCompareViewLoader, null)) : (react_1.default.createElement(code_ui_diff_viewer_1.DiffViewer, { className: compare_aspect_view_module_scss_1.default.diffEditor, fileName: `${title || 'aspect'}-data.json`, oldContent: originalData, newContent: modifiedData, language: "json", defaultView: "split", showHeader: false, collapsible: false, maxHeight: 420, contextLines: (0, config_editor_1.unchangedContext)(originalData, modifiedData) }))))));
66
+ }
67
+ function AspectsCompareViewLoader() {
68
+ return react_1.default.createElement(base_ui_loaders_skeleton_1.BlockSkeleton, { className: compare_aspect_view_module_scss_1.default.loader, lines: 16 });
69
+ }
70
+ //# sourceMappingURL=compare-aspect-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-aspect-view.js","sourceRoot":"","sources":["../compare-aspect-view.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ $editor-padding: 56px;
2
+
3
+ .componentCompareAspectViewContainer {
4
+ width: 100%;
5
+ height: 100%;
6
+ }
7
+ .componentCompareAspectDiffEditorContainer {
8
+ padding: 0px 8px;
9
+ display: flex;
10
+ flex-direction: column;
11
+ height: calc(100% - $editor-padding);
12
+ min-height: 0;
13
+ overflow-y: auto;
14
+ }
15
+
16
+ .name {
17
+ display: flex;
18
+ align-items: baseline;
19
+ padding: 8px;
20
+ }
21
+
22
+ .componentCompareAspectConfigDiff,
23
+ .componentCompareAspectCalculatedDiff {
24
+ display: flex;
25
+ flex: 1 0 auto;
26
+ padding: 0px 8px;
27
+ min-height: 0;
28
+ flex-direction: column;
29
+ }
30
+
31
+ .diffEditor {
32
+ width: 100%;
33
+ }
34
+
35
+ .diffWithActions {
36
+ position: relative;
37
+ width: 100%;
38
+ }
39
+
40
+ .copyActions {
41
+ position: absolute;
42
+ z-index: 1;
43
+ top: 8px;
44
+ right: 18px;
45
+ display: flex;
46
+ gap: 8px;
47
+ }
48
+
49
+ .loader {
50
+ display: flex;
51
+ align-items: center;
52
+ justify-items: center;
53
+ height: 100%;
54
+ width: 100%;
55
+ // Skeleton shimmer built from theme surfaces. It ran to a hard-coded #2b2b2b, which on a light page
56
+ // produced grey-on-grey bands.
57
+ color: var(--surface-neutral-color, #fff);
58
+ background-image: linear-gradient(
59
+ to right,
60
+ currentColor 0%,
61
+ var(--surface-neutral-hover-color, #f4f5f6) 30%,
62
+ var(--surface-neutral-hover-color, #f4f5f6) 50%,
63
+ currentColor 100%
64
+ );
65
+ > div {
66
+ background-image: linear-gradient(
67
+ to right,
68
+ currentColor 0%,
69
+ var(--surface-neutral-hover-color, #f4f5f6) 30%,
70
+ var(--surface-neutral-hover-color, #f4f5f6) 50%,
71
+ currentColor 100%
72
+ );
73
+ }
74
+ }
75
+
76
+ .copyButton {
77
+ cursor: pointer;
78
+ border: 0;
79
+ padding: 4px;
80
+ border-radius: 4px;
81
+ color: inherit;
82
+ background: var(--surface-color, #fff);
83
+ opacity: 0;
84
+
85
+ &.isLabelVisible {
86
+ opacity: 1;
87
+ }
88
+ }
89
+
90
+ .diffWithActions:hover .copyButton,
91
+ .copyButton:focus-visible {
92
+ opacity: 1;
93
+ }
94
+
95
+ .message {
96
+ left: 0;
97
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_editor_1 = require("./config-editor");
4
+ // Tests the decision only, without rendering: rendering needs `react-dom`, and this component's env can
5
+ // resolve a `react-dom` that does not match its `react`, which fails the suite before it runs.
6
+ jest.mock('@teambit/code.ui.diff-viewer', () => ({ DiffViewer: () => null }));
7
+ describe('unchangedContext', () => {
8
+ it('gives unlimited context when both sides are the same, so the diff is shown in full', () => {
9
+ const same = JSON.stringify({ policy: {} }, null, 2);
10
+ expect((0, config_editor_1.unchangedContext)(same, same)).toBe(Number.MAX_SAFE_INTEGER);
11
+ });
12
+ it('keeps the default context when the sides differ', () => {
13
+ expect((0, config_editor_1.unchangedContext)('{}', '{ "policy": {} }')).toBeUndefined();
14
+ });
15
+ });
16
+ //# sourceMappingURL=compare-aspect-view.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-aspect-view.spec.js","sourceRoot":"","sources":["../compare-aspect-view.spec.tsx"],"names":[],"mappings":";;AAAA,mDAAmD;AAEnD,wGAAwG;AACxG,+FAA+F;AAC/F,IAAI,CAAC,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAE9E,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oFAAoF,EAAE,GAAG,EAAE;QAC5F,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,IAAA,gCAAgB,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,IAAA,gCAAgB,EAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { HTMLAttributes } from 'react';
2
+ import React from 'react';
3
+ export type ConfigDiffEditorProps = {
4
+ original?: string;
5
+ modified?: string;
6
+ name?: string;
7
+ } & HTMLAttributes<HTMLDivElement>;
8
+ export declare function ConfigDiffEditor({ original, modified, name }: ConfigDiffEditorProps): React.JSX.Element;
9
+ /**
10
+ * Unlimited context when both sides are the same: an unchanged config has no change to collapse
11
+ * toward, so the default context would hide all of it behind a single "Expand N unchanged lines".
12
+ */
13
+ export declare function unchangedContext(original: string, modified: string): number | undefined;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ConfigDiffEditor = ConfigDiffEditor;
40
+ exports.unchangedContext = unchangedContext;
41
+ const react_1 = __importStar(require("react"));
42
+ const copy_to_clipboard_1 = __importDefault(require("copy-to-clipboard"));
43
+ const classnames_1 = __importDefault(require("classnames"));
44
+ const documenter_ui_copied_message_1 = require("@teambit/documenter.ui.copied-message");
45
+ const code_ui_diff_viewer_1 = require("@teambit/code.ui.diff-viewer");
46
+ const design_elements_icon_1 = require("@teambit/design.elements.icon");
47
+ const compare_aspect_view_module_scss_1 = __importDefault(require("./compare-aspect-view.module.scss"));
48
+ function ConfigDiffEditor({ original = '', modified = '', name = 'aspect config' }) {
49
+ return (react_1.default.createElement("div", { className: compare_aspect_view_module_scss_1.default.diffWithActions },
50
+ react_1.default.createElement("div", { className: compare_aspect_view_module_scss_1.default.copyActions },
51
+ original && react_1.default.createElement(CopyButton, { text: original, label: "Copy base config" }),
52
+ modified && react_1.default.createElement(CopyButton, { text: modified, label: "Copy changed config" })),
53
+ react_1.default.createElement(code_ui_diff_viewer_1.DiffViewer, { className: compare_aspect_view_module_scss_1.default.diffEditor, fileName: `${name}.json`, oldContent: original, newContent: modified, language: "json", defaultView: "split", showHeader: false, collapsible: false, maxHeight: 420, contextLines: unchangedContext(original, modified) })));
54
+ }
55
+ /**
56
+ * Unlimited context when both sides are the same: an unchanged config has no change to collapse
57
+ * toward, so the default context would hide all of it behind a single "Expand N unchanged lines".
58
+ */
59
+ function unchangedContext(original, modified) {
60
+ return original === modified ? Number.MAX_SAFE_INTEGER : undefined;
61
+ }
62
+ function CopyButton({ text, label }) {
63
+ const [isCopied, setCopied] = (0, react_1.useState)(false);
64
+ const handleCopy = () => {
65
+ (0, copy_to_clipboard_1.default)(text);
66
+ setCopied(true);
67
+ setTimeout(() => setCopied(false), 2000);
68
+ };
69
+ return (react_1.default.createElement("button", { type: "button", "aria-label": label, title: label, className: (0, classnames_1.default)(compare_aspect_view_module_scss_1.default.copyButton, isCopied && compare_aspect_view_module_scss_1.default.isLabelVisible), onClick: handleCopy },
70
+ react_1.default.createElement(design_elements_icon_1.Icon, { className: compare_aspect_view_module_scss_1.default.copyIcon, of: "copy-cmp" }),
71
+ react_1.default.createElement(documenter_ui_copied_message_1.CopiedMessage, { className: compare_aspect_view_module_scss_1.default.message, show: isCopied })));
72
+ }
73
+ //# sourceMappingURL=config-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-editor.js","sourceRoot":"","sources":["../config-editor.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBA,4CAqBC;AAMD,4CAEC;AA5CD,+CAAwC;AACxC,0EAAqC;AACrC,4DAAoC;AACpC,wFAAsE;AACtE,sEAA0D;AAC1D,wEAAqD;AAErD,wGAAuD;AAQvD,SAAgB,gBAAgB,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE,IAAI,GAAG,eAAe,EAAyB;IAC9G,OAAO,CACL,uCAAK,SAAS,EAAE,yCAAM,CAAC,eAAe;QACpC,uCAAK,SAAS,EAAE,yCAAM,CAAC,WAAW;YAC/B,QAAQ,IAAI,8BAAC,UAAU,IAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAC,kBAAkB,GAAG;YACnE,QAAQ,IAAI,8BAAC,UAAU,IAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAC,qBAAqB,GAAG,CACnE;QACN,8BAAC,gCAAU,IACT,SAAS,EAAE,yCAAM,CAAC,UAAU,EAC5B,QAAQ,EAAE,GAAG,IAAI,OAAO,EACxB,UAAU,EAAE,QAAQ,EACpB,UAAU,EAAE,QAAQ,EACpB,QAAQ,EAAC,MAAM,EACf,WAAW,EAAC,OAAO,EACnB,UAAU,EAAE,KAAK,EACjB,WAAW,EAAE,KAAK,EAClB,SAAS,EAAE,GAAG,EACd,YAAY,EAAE,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAClD,CACE,CACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,QAAgB,EAAE,QAAgB;IACjE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC;AAED,SAAS,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAmC;IAClE,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAE9C,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAA,2BAAI,EAAC,IAAI,CAAC,CAAC;QACX,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC;IAEF,OAAO,CACL,0CACE,IAAI,EAAC,QAAQ,gBACD,KAAK,EACjB,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,IAAA,oBAAU,EAAC,yCAAM,CAAC,UAAU,EAAE,QAAQ,IAAI,yCAAM,CAAC,cAAc,CAAC,EAC3E,OAAO,EAAE,UAAU;QAEnB,8BAAC,2BAAI,IAAC,SAAS,EAAE,yCAAM,CAAC,QAAQ,EAAE,EAAE,EAAC,UAAU,GAAG;QAClD,8BAAC,4CAAa,IAAC,SAAS,EAAE,yCAAM,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAI,CACrD,CACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export { CompareAspectView, CompareAspectViewProps } from './compare-aspect-view';
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CompareAspectView = void 0;
4
+ var compare_aspect_view_1 = require("./compare-aspect-view");
5
+ Object.defineProperty(exports, "CompareAspectView", { enumerable: true, get: function () { return compare_aspect_view_1.CompareAspectView; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,6DAAkF;AAAzE,wHAAA,iBAAiB,OAAA"}
@@ -0,0 +1,7 @@
1
+ ;
2
+ ;
3
+
4
+ export const compositions = [];
5
+ export const overview = [];
6
+
7
+ export const compositions_metadata = {"compositions":[]};
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { CompareAspectView, CompareAspectViewProps } from './compare-aspect-view';
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@teambit/component.ui.component-compare.compare-aspects.compare-aspect-view",
3
+ "version": "0.0.0-aceda4bd6dc966a1bd6ded58b3532380581cb4a5",
4
+ "homepage": "https://bit.cloud/teambit/component/ui/component-compare/compare-aspects/compare-aspect-view",
5
+ "main": "dist/index.js",
6
+ "componentId": {
7
+ "scope": "teambit.component",
8
+ "name": "ui/component-compare/compare-aspects/compare-aspect-view",
9
+ "version": "aceda4bd6dc966a1bd6ded58b3532380581cb4a5"
10
+ },
11
+ "dependencies": {
12
+ "classnames": "^2.5.1",
13
+ "copy-to-clipboard": "3.3.1",
14
+ "core-js": "^3.0.0",
15
+ "@teambit/base-ui.loaders.skeleton": "1.0.2",
16
+ "@teambit/code.ui.diff-viewer": "0.0.0-60f398af31ebe9621d00218f26b819b60c8686d8",
17
+ "@teambit/component.ui.component-compare.compare-aspects.models.component-compare-aspects-model": "0.0.12",
18
+ "@teambit/documenter.ui.heading": "4.1.8",
19
+ "@teambit/documenter.ui.copied-message": "4.1.8",
20
+ "@teambit/design.elements.icon": "1.0.24"
21
+ },
22
+ "devDependencies": {
23
+ "@types/classnames": "^2.3.4",
24
+ "@types/react": "^19.0.0",
25
+ "@types/mocha": "9.1.0",
26
+ "@types/node": "12.20.4",
27
+ "@types/react-dom": "^19.0.0",
28
+ "@types/jest": "^26.0.0",
29
+ "@babel/runtime": "7.20.0",
30
+ "@types/testing-library__jest-dom": "5.9.5"
31
+ },
32
+ "peerDependencies": {
33
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
34
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
35
+ },
36
+ "license": "Apache-2.0",
37
+ "optionalDependencies": {},
38
+ "peerDependenciesMeta": {},
39
+ "private": false,
40
+ "engines": {
41
+ "node": ">=12.22.0"
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/teambit/bit"
46
+ },
47
+ "keywords": [
48
+ "bit",
49
+ "components",
50
+ "collaboration",
51
+ "web",
52
+ "react",
53
+ "react-components",
54
+ "angular",
55
+ "angular-components"
56
+ ]
57
+ }
@@ -0,0 +1,29 @@
1
+ declare module '*.png' {
2
+ const value: any;
3
+ export = value;
4
+ }
5
+ declare module '*.svg' {
6
+ import type { FunctionComponent, SVGProps } from 'react';
7
+
8
+ export const ReactComponent: FunctionComponent<SVGProps<SVGSVGElement> & { title?: string }>;
9
+ const src: string;
10
+ export default src;
11
+ }
12
+
13
+ // @TODO Gilad
14
+ declare module '*.jpg' {
15
+ const value: any;
16
+ export = value;
17
+ }
18
+ declare module '*.jpeg' {
19
+ const value: any;
20
+ export = value;
21
+ }
22
+ declare module '*.gif' {
23
+ const value: any;
24
+ export = value;
25
+ }
26
+ declare module '*.bmp' {
27
+ const value: any;
28
+ export = value;
29
+ }
@@ -0,0 +1,42 @@
1
+ declare module '*.module.css' {
2
+ const classes: { readonly [key: string]: string };
3
+ export default classes;
4
+ }
5
+ declare module '*.module.scss' {
6
+ const classes: { readonly [key: string]: string };
7
+ export default classes;
8
+ }
9
+ declare module '*.module.sass' {
10
+ const classes: { readonly [key: string]: string };
11
+ export default classes;
12
+ }
13
+
14
+ declare module '*.module.less' {
15
+ const classes: { readonly [key: string]: string };
16
+ export default classes;
17
+ }
18
+
19
+ declare module '*.less' {
20
+ const classes: { readonly [key: string]: string };
21
+ export default classes;
22
+ }
23
+
24
+ declare module '*.css' {
25
+ const classes: { readonly [key: string]: string };
26
+ export default classes;
27
+ }
28
+
29
+ declare module '*.sass' {
30
+ const classes: { readonly [key: string]: string };
31
+ export default classes;
32
+ }
33
+
34
+ declare module '*.scss' {
35
+ const classes: { readonly [key: string]: string };
36
+ export default classes;
37
+ }
38
+
39
+ declare module '*.mdx' {
40
+ const component: any;
41
+ export default component;
42
+ }