UNPKG

optimizely-oui

Version:

Optimizely's Component Library.

119 lines (108 loc) 3.96 kB
import classNames from "classnames"; import { cloneDeep } from "lodash"; import PropTypes from "prop-types"; import React from "react"; import Icon from "react-oui-icons"; import ReactDiffViewer from "react-diff-viewer"; import { brandBlueDark } from "../../tokens/forimport/index.es"; /** * * @param {Object} props - Properties passed to component * @returns {ReactElement} */ export const CodeDiff = ({ borderLocation, className, header, newValue, oldValue, testSection, ...props }) => { let before = cloneDeep(oldValue); let after = cloneDeep(newValue); // Attempt to stringify, since non-strings will // throw an error in ReactDiffViewer anyways if ([before, after].some(val => typeof val !== "string")) { before = JSON.stringify(before, null, 2); after = JSON.stringify(after, null, 2); } return ( <div className={classNames("oui-codediff", { "border--top": borderLocation.includes("top"), "border--right": borderLocation.includes("right"), "border--bottom": borderLocation.includes("bottom"), "border--left": borderLocation.includes("left"), }, className)} data-test-section={testSection} > {header && ( <div className="background--grey-25 border--bottom color--base soft--sides soft-half--ends"> {header} </div> )} <ReactDiffViewer {...props} codeFoldMessageRenderer={() => ( // eslint-disable-line react/jsx-no-bind <div className="flex" style={{ marginTop: 3 }}> {/* TODO(AXIOM-139) Use "Arrow Ns" icon when available */} <Icon name="ellipsis" fill={brandBlueDark} /> </div> )} oldValue={before} newValue={after} /** * BEGIN: TODO(AXIOM-138) Ensure styling is correct and remove * remaining default declarations mentioned below */ // See https://github.com/praneshr/react-diff-viewer/tree/v3.0.0#overriding-styles // for more info on styling options styles={{ line: { wordBreak: "break-word", }, codeFoldGutter: { backgroundColor: "#f1f8ff", // Sames as variables.light.codeFoldBackground }, }} /** * END: TODO(AXIOM-138) Ensure styling is correct and * remove remaining default declarations above */ /> </div> ); }; CodeDiff.propTypes = { /** Where borders should be added. Defaults to borders on every side (OUI) */ borderLocation: PropTypes.arrayOf(PropTypes.oneOf(["top", "right", "bottom", "left"])), /** CSS class names. */ className: PropTypes.string, /** * Differential title that spans all columns. * If not provided, no header will be shown (OUI) */ header: PropTypes.node, /** * New value. If of type "object", will be * formatted with JSON.stringify (ReactDiffViewer) */ newValue: PropTypes.any.isRequired, /** Show and hide line numbers (ReactDiffViewer) */ oldValue: PropTypes.any.isRequired, /** Value used for testing via data-test-section attribute (OUI) */ testSection: PropTypes.string, /** * Get info on the core component (ReactDiffViewer) * props at https://github.com/praneshr/react-diff-viewer/tree/v3.0.0#props */ }; CodeDiff.defaultProps = { borderLocation: ["top", "right", "bottom", "left"], compareMethod: "diffWords", header: "", testSection: "", }; export default CodeDiff;