From 1b6392defce5870f8445005261dad3415e68c964 Mon Sep 17 00:00:00 2001 From: Florian Scholdei Date: Tue, 8 Oct 2019 16:42:08 +0200 Subject: [PATCH] Switch from ReactJSS to styled-components in ui-components --- .../src/main/js/ProtocolInformation.js | 37 ++-- scm-ui/ui-components/src/BranchSelector.js | 80 +++------ scm-ui/ui-components/src/Breadcrumb.js | 57 +++--- scm-ui/ui-components/src/CardColumn.js | 131 ++++++-------- scm-ui/ui-components/src/CardColumnGroup.js | 51 +++--- scm-ui/ui-components/src/DateFromNow.js | 24 ++- scm-ui/ui-components/src/Help.js | 31 ++-- scm-ui/ui-components/src/HelpIcon.js | 17 +- scm-ui/ui-components/src/Loading.js | 60 ++----- scm-ui/ui-components/src/MarkdownView.js | 50 +++--- .../ui-components/src/OverviewPageActions.js | 20 +-- scm-ui/ui-components/src/buttons/Button.js | 5 +- .../ui-components/src/buttons/CreateButton.js | 28 ++- scm-ui/ui-components/src/forms/FilterInput.js | 29 +-- scm-ui/ui-components/src/forms/TagGroup.js | 20 +-- scm-ui/ui-components/src/layout/Page.js | 42 ++--- scm-ui/ui-components/src/repos/DiffFile.js | 169 +++++++++--------- .../src/repos/changesets/ChangesetRow.js | 127 ++++++------- scm-ui/ui-webapp/src/style/scm.scss | 10 +- 19 files changed, 422 insertions(+), 566 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/js/ProtocolInformation.js b/scm-plugins/scm-git-plugin/src/main/js/ProtocolInformation.js index eb5396caad..12662d857e 100644 --- a/scm-plugins/scm-git-plugin/src/main/js/ProtocolInformation.js +++ b/scm-plugins/scm-git-plugin/src/main/js/ProtocolInformation.js @@ -1,10 +1,9 @@ //@flow import React from "react"; -import { ButtonAddons, Button } from "@scm-manager/ui-components"; -import type { Repository } from "@scm-manager/ui-types"; -import CloneInformation from "./CloneInformation"; -import type { Link } from "@scm-manager/ui-types"; import styled from "styled-components"; +import type { Repository, Link } from "@scm-manager/ui-types"; +import { ButtonAddons, Button } from "@scm-manager/ui-components"; +import CloneInformation from "./CloneInformation"; const Wrapper = styled.div` position: relative; @@ -18,7 +17,7 @@ const Switcher = styled(ButtonAddons)` type Props = { repository: Repository -} +}; type State = { selected?: Link @@ -39,8 +38,7 @@ function selectHttpOrFirst(repository: Repository) { return undefined; } -class ProtocolInformation extends React.Component { - +export default class ProtocolInformation extends React.Component { constructor(props: Props) { super(props); this.state = { @@ -60,12 +58,12 @@ class ProtocolInformation extends React.Component { let color = null; const { selected } = this.state; - if ( selected && protocol.name === selected.name ) { + if (selected && protocol.name === selected.name) { color = "link is-selected"; } return ( - ); @@ -80,25 +78,24 @@ class ProtocolInformation extends React.Component { } if (protocols.length === 1) { - return ; + return ( + + ); } const { selected } = this.state; let cloneInformation = null; if (selected) { - cloneInformation = ; + cloneInformation = ( + + ); } return ( - - - {protocols.map(this.renderProtocolButton)} - - { cloneInformation } - + + {protocols.map(this.renderProtocolButton)} + {cloneInformation} + ); } - } - -export default ProtocolInformation; diff --git a/scm-ui/ui-components/src/BranchSelector.js b/scm-ui/ui-components/src/BranchSelector.js index f86019e399..3d748850da 100644 --- a/scm-ui/ui-components/src/BranchSelector.js +++ b/scm-ui/ui-components/src/BranchSelector.js @@ -1,41 +1,34 @@ -// @flow - +//@flow import React from "react"; -import type { Branch } from "@scm-manager/ui-types"; -import injectSheet from "react-jss"; import classNames from "classnames"; +import styled from "styled-components"; +import type { Branch } from "@scm-manager/ui-types"; import DropDown from "./forms/DropDown"; -const styles = { - zeroflex: { - flexBasis: "inherit", - flexGrow: 0 - }, - minWidthOfControl: { - minWidth: "10rem" - }, - labelSizing: { - fontSize: "1rem !important" - }, - noBottomMargin: { - marginBottom: "0 !important" - } -}; - type Props = { - branches: Branch[], // TODO: Use generics? + branches: Branch[], selected: (branch?: Branch) => void, selectedBranch?: string, label: string, - disabled?: boolean, - - // context props - classes: Object + disabled?: boolean }; type State = { selectedBranch?: Branch }; -class BranchSelector extends React.Component { +const ZeroflexFieldLabel = styled.label` + flex-basis: inherit; + flex-grow: 0; +`; + +const MinWidthControl = styled.div` + min-width: 10rem; +`; + +const NoBottomMarginField = styled.div` + margin-bottom: 0 !important; +`; + +export default class BranchSelector extends React.Component { constructor(props: Props) { super(props); this.state = {}; @@ -52,32 +45,19 @@ class BranchSelector extends React.Component { } render() { - const { branches, classes, label, disabled } = this.props; + const { branches, label, disabled } = this.props; if (branches) { return ( -
-
+ - -
+
{label}
+
-
-
+ + b.name)} @@ -89,8 +69,8 @@ class BranchSelector extends React.Component { : "" } /> -
-
+ +
); @@ -113,5 +93,3 @@ class BranchSelector extends React.Component { this.setState({ selectedBranch: branch }); }; } - -export default injectSheet(styles)(BranchSelector); diff --git a/scm-ui/ui-components/src/Breadcrumb.js b/scm-ui/ui-components/src/Breadcrumb.js index 74996accc0..524230a0a4 100644 --- a/scm-ui/ui-components/src/Breadcrumb.js +++ b/scm-ui/ui-components/src/Breadcrumb.js @@ -2,8 +2,8 @@ import React from "react"; import { Link } from "react-router-dom"; import { translate } from "react-i18next"; -import injectSheet from "react-jss"; import classNames from "classnames"; +import styled from "styled-components"; import { binder, ExtensionPoint } from "@scm-manager/ui-extensions"; import type { Branch, Repository } from "@scm-manager/ui-types"; import Icon from "./Icon"; @@ -18,29 +18,21 @@ type Props = { baseUrl: string, // Context props - classes: any, t: string => string }; -const styles = { - noMargin: { - margin: "0" - }, - flexRow: { - display: "flex", - flexDirection: "row" - }, - flexStart: { - flex: "1" - }, - homeIcon: { - lineHeight: "1.5rem" - }, - buttonGroup: { - alignSelf: "center", - paddingRight: "1rem" - } -}; +const FlexStartNav = styled.nav` + flex: 1; +`; + +const HomeIcon = styled(Icon)` + line-height: 1.5rem; +`; + +const ActionWrapper = styled.div` + align-self: center; + padding-right: 1rem; +`; class Breadcrumb extends React.Component { renderPath() { @@ -79,25 +71,20 @@ class Breadcrumb extends React.Component { revision, path, repository, - classes, t } = this.props; return ( <> -
- + {binder.hasExtension("repos.sources.actionbar") && ( -
+ { }} renderAll={true} /> -
+ )}
-
+
); } } -export default translate("commons")(injectSheet(styles)(Breadcrumb)); +export default translate("commons")(Breadcrumb); diff --git a/scm-ui/ui-components/src/CardColumn.js b/scm-ui/ui-components/src/CardColumn.js index 5340d88a35..865c337881 100644 --- a/scm-ui/ui-components/src/CardColumn.js +++ b/scm-ui/ui-components/src/CardColumn.js @@ -1,45 +1,9 @@ //@flow import * as React from "react"; -import injectSheet from "react-jss"; import classNames from "classnames"; - +import styled from "styled-components"; import { Link } from "react-router-dom"; -const styles = { - inner: { - position: "relative", - pointerEvents: "none", - zIndex: 1 - }, - innerLink: { - pointerEvents: "all" - }, - centerImage: { - marginTop: "0.8em", - marginLeft: "1em !important" - }, - flexFullHeight: { - display: "flex", - flexDirection: "column", - justifyContent: "space-around", - alignSelf: "stretch" - }, - footer: { - display: "flex", - paddingBottom: "1rem", - }, - topPart: { - display: "flex" - }, - contentRight: { - marginLeft: "auto" - }, - contentLeft: { - marginBottom: "0 !important", - overflow: "hidden" - } -}; - type Props = { title: string, description: string, @@ -49,19 +13,54 @@ type Props = { footerRight: React.Node, link?: string, action?: () => void, - className?: string, - - // context props - classes: any + className?: string }; -class CardColumn extends React.Component { +const NoEventWrapper = styled.article` + pointer-events: none; + z-index: 1; +`; + +const AvatarWrapper = styled.figure` + margin-top: 0.8em; + margin-left: 1em !important; +`; + +const FlexFullHeight = styled.div` + flex-direction: column; + justify-content: space-around; + align-self: stretch; +`; + +const FooterWrapper = styled.div` + padding-bottom: 1rem; +`; + +const ContentLeft = styled.div` + margin-bottom: 0 !important; + overflow: hidden; +`; + +const ContentRight = styled.div` + margin-left: auto; +`; + +export default class CardColumn extends React.Component { createLink = () => { const { link, action } = this.props; if (link) { return ; } else if (action) { - return {e.preventDefault(); action();}} href="#" />; + return ( + { + e.preventDefault(); + action(); + }} + href="#" + /> + ); } return null; }; @@ -74,49 +73,37 @@ class CardColumn extends React.Component { contentRight, footerLeft, footerRight, - classes, className } = this.props; const link = this.createLink(); return ( <> {link} -
-
- {avatar} -
-
+ {avatar} + -
-
+
+

{title}

{description}

-
-
- {contentRight && contentRight} -
+ + {contentRight && contentRight}
-
-
{footerLeft}
-
{footerRight}
+ +
{footerLeft}
+
+ {footerRight}
-
-
+ + + ); } } - -export default injectSheet(styles)(CardColumn); diff --git a/scm-ui/ui-components/src/CardColumnGroup.js b/scm-ui/ui-components/src/CardColumnGroup.js index b72bd97dd7..ddecfd1c11 100644 --- a/scm-ui/ui-components/src/CardColumnGroup.js +++ b/scm-ui/ui-components/src/CardColumnGroup.js @@ -1,37 +1,26 @@ //@flow import * as React from "react"; -import injectSheet from "react-jss"; import classNames from "classnames"; - -const styles = { - pointer: { - cursor: "pointer", - fontSize: "1.5rem" - }, - repoGroup: { - marginBottom: "1em" - }, - wrapper: { - padding: "0 0.75rem" - }, - clearfix: { - clear: "both" - } -}; +import styled from "styled-components"; type Props = { name: string, - elements: React.Node[], - - // context props - classes: any + elements: React.Node[] }; type State = { collapsed: boolean }; -class CardColumnGroup extends React.Component { +const Container = styled.div` + margin-bottom: 1em; +`; + +const Wrapper = styled.div` + padding: 0 0.75rem; +`; + +export default class CardColumnGroup extends React.Component { constructor(props: Props) { super(props); this.state = { @@ -58,7 +47,7 @@ class CardColumnGroup extends React.Component { }; render() { - const { name, elements, classes } = this.props; + const { name, elements } = this.props; const { collapsed } = this.state; const icon = collapsed ? "fa-angle-right" : "fa-angle-down"; @@ -84,20 +73,20 @@ class CardColumnGroup extends React.Component { }); } return ( -
+

- + {name}


-
+ {content} -
-
-
+ +
); } } - -export default injectSheet(styles)(CardColumnGroup); diff --git a/scm-ui/ui-components/src/DateFromNow.js b/scm-ui/ui-components/src/DateFromNow.js index 3c14f02d0c..0407cfc32e 100644 --- a/scm-ui/ui-components/src/DateFromNow.js +++ b/scm-ui/ui-components/src/DateFromNow.js @@ -2,39 +2,35 @@ import React from "react"; import moment from "moment"; import { translate } from "react-i18next"; -import injectSheet from "react-jss"; +import styled from "styled-components"; // fix german locale // https://momentjscom.readthedocs.io/en/latest/moment/00-use-it/07-browserify/ import "moment/locale/de"; -const styles = { - date: { - borderBottom: "1px dotted rgba(219, 219, 219)", - cursor: "help" - } -}; - type Props = { date?: string, // context props - classes: any, i18n: any }; -class DateFromNow extends React.Component { +const Date = styled.time` + border-bottom: 1px dotted rgba(219, 219, 219); + cursor: help; +`; +class DateFromNow extends React.Component { render() { - const { i18n, date, classes } = this.props; + const { i18n, date } = this.props; if (date) { const dateWithLocale = moment(date).locale(i18n.language); return ( - + ); } @@ -42,4 +38,4 @@ class DateFromNow extends React.Component { } } -export default injectSheet(styles)(translate()(DateFromNow)); +export default translate()(DateFromNow); diff --git a/scm-ui/ui-components/src/Help.js b/scm-ui/ui-components/src/Help.js index 6b632810e9..e7a73900ea 100644 --- a/scm-ui/ui-components/src/Help.js +++ b/scm-ui/ui-components/src/Help.js @@ -1,36 +1,27 @@ //@flow import React from "react"; -import injectSheet from "react-jss"; import classNames from "classnames"; +import styled from "styled-components"; import Tooltip from "./Tooltip"; import HelpIcon from "./HelpIcon"; -const styles = { - tooltip: { - display: "inline-block", - paddingLeft: "3px", - position: "absolute" - } -}; - type Props = { message: string, - className?: string, - classes: any + className?: string }; -class Help extends React.Component { +const HelpTooltip = styled(Tooltip)` + position: absolute; + padding-left: 3px; +`; + +export default class Help extends React.Component { render() { - const { message, className, classes } = this.props; + const { message, className } = this.props; return ( - + - + ); } } - -export default injectSheet(styles)(Help); diff --git a/scm-ui/ui-components/src/HelpIcon.js b/scm-ui/ui-components/src/HelpIcon.js index c73417bb27..3e265a0446 100644 --- a/scm-ui/ui-components/src/HelpIcon.js +++ b/scm-ui/ui-components/src/HelpIcon.js @@ -1,25 +1,16 @@ //@flow import React from "react"; -import injectSheet from "react-jss"; import Icon from "./Icon"; type Props = { - classes: any + className?: string }; -const styles = { - textinfo: { - color: "#98d8f3 !important" - } -}; - -class HelpIcon extends React.Component { +export default class HelpIcon extends React.Component { render() { - const { classes } = this.props; + const { className } = this.props; return ( - + ); } } - -export default injectSheet(styles)(HelpIcon); diff --git a/scm-ui/ui-components/src/Loading.js b/scm-ui/ui-components/src/Loading.js index 6b4817131f..2ead83c153 100644 --- a/scm-ui/ui-components/src/Loading.js +++ b/scm-ui/ui-components/src/Loading.js @@ -1,57 +1,35 @@ //@flow - import React from "react"; import { translate } from "react-i18next"; -import injectSheet from "react-jss"; +import styled from "styled-components"; import Image from "./Image"; -const styles = { - minHeightContainer: { - minHeight: "256px" - }, - wrapper: { - position: "relative" - }, - loading: { - width: "128px", - height: "128px", - - position: "absolute", - top: "50%", - left: "50%", - - margin: "64px 0 0 -64px" - }, - image: { - width: "128px", - height: "128px" - } -}; - type Props = { t: string => string, - message?: string, - classes: any + message?: string }; +const Wrapper = styled.div` + align-items: center; + justify-content: center; + min-height: 256px; +`; + +const FixedSizedImage = styled(Image)` + width: 128px; + height: 128px; +`; + class Loading extends React.Component { render() { - const { message, t, classes } = this.props; + const { message, t } = this.props; return ( -
-
-
- {t("loading.alt")} -

{message}

-
-
-
+ + +

{message}

+
); } } -export default injectSheet(styles)(translate("commons")(Loading)); +export default translate("commons")(Loading); diff --git a/scm-ui/ui-components/src/MarkdownView.js b/scm-ui/ui-components/src/MarkdownView.js index 6176601d68..1d7416a74c 100644 --- a/scm-ui/ui-components/src/MarkdownView.js +++ b/scm-ui/ui-components/src/MarkdownView.js @@ -1,8 +1,8 @@ //@flow import React from "react"; import { withRouter } from "react-router-dom"; -import injectSheet from "react-jss"; import Markdown from "react-markdown/with-html"; +import styled from "styled-components"; import { binder } from "@scm-manager/ui-extensions"; import SyntaxHighlighter from "./SyntaxHighlighter"; import MarkdownHeadingRenderer from "./MarkdownHeadingRenderer"; @@ -14,32 +14,29 @@ type Props = { enableAnchorHeadings: boolean, // context props - classes: any, location: any }; -const styles = { - markdown: { - "& > .content": { - "& > h1, h2, h3, h4, h5, h6": { - margin: "0.5rem 0", - fontSize: "0.9rem" - }, - "& > h1": { - fontWeight: "700" - }, - "& > h2": { - fontWeight: "600" - }, - "& > h3, h4, h5, h6": { - fontWeight: "500" - }, - "& strong": { - fontWeight: "500" - } +const MarkdownWrapper = styled.div` + > .content: { + > h1, h2, h3, h4, h5, h6: { + margin: 0.5rem 0; + font-size: 0.9rem; + } + > h1: { + font-weight: 700; + } + > h2: { + font-weight: 600; + } + > h3, h4, h5, h6: { + font-weight: 500; + } + & strong: { + font-weight: 500; } } -}; +`; class MarkdownView extends React.Component { static defaultProps = { @@ -72,8 +69,7 @@ class MarkdownView extends React.Component { content, renderers, renderContext, - enableAnchorHeadings, - classes + enableAnchorHeadings } = this.props; const rendererFactory = binder.getExtension("markdown-renderer-factory"); @@ -96,7 +92,7 @@ class MarkdownView extends React.Component { } return ( -
(this.contentRef = el)}> + (this.contentRef = el)}> { source={content} renderers={rendererList} /> -
+ ); } } -export default injectSheet(styles)(withRouter(MarkdownView)); +export default withRouter(MarkdownView); diff --git a/scm-ui/ui-components/src/OverviewPageActions.js b/scm-ui/ui-components/src/OverviewPageActions.js index 84d0713752..999297d0c3 100644 --- a/scm-ui/ui-components/src/OverviewPageActions.js +++ b/scm-ui/ui-components/src/OverviewPageActions.js @@ -1,11 +1,10 @@ -// @flow +//@flow import React from "react"; import type { History } from "history"; import { withRouter } from "react-router-dom"; import classNames from "classnames"; -import injectSheet from "react-jss"; -import { FilterInput } from "./forms"; import { Button, urls } from "./index"; +import { FilterInput } from "./forms"; type Props = { showCreateButton: boolean, @@ -13,19 +12,10 @@ type Props = { label?: string, // context props - classes: Object, history: History, location: any }; -const styles = { - button: { - float: "right", - marginTop: "1.25rem", - marginLeft: "1.25rem" - } -}; - class OverviewPageActions extends React.Component { render() { const { history, location, link } = this.props; @@ -43,10 +33,10 @@ class OverviewPageActions extends React.Component { } renderCreateButton() { - const { showCreateButton, classes, link, label } = this.props; + const { showCreateButton, link, label } = this.props; if (showCreateButton) { return ( -
+
); @@ -55,4 +45,4 @@ class OverviewPageActions extends React.Component { } } -export default injectSheet(styles)(withRouter(OverviewPageActions)); +export default withRouter(OverviewPageActions); diff --git a/scm-ui/ui-components/src/buttons/Button.js b/scm-ui/ui-components/src/buttons/Button.js index d2c782d12d..23aa2e9a83 100644 --- a/scm-ui/ui-components/src/buttons/Button.js +++ b/scm-ui/ui-components/src/buttons/Button.js @@ -14,10 +14,7 @@ export type ButtonProps = { icon?: string, fullWidth?: boolean, reducedMobile?: boolean, - children?: React.Node, - - // context props - classes: any + children?: React.Node }; type Props = ButtonProps & { diff --git a/scm-ui/ui-components/src/buttons/CreateButton.js b/scm-ui/ui-components/src/buttons/CreateButton.js index 155669754c..8eef654f13 100644 --- a/scm-ui/ui-components/src/buttons/CreateButton.js +++ b/scm-ui/ui-components/src/buttons/CreateButton.js @@ -1,28 +1,20 @@ //@flow import React from "react"; -import injectSheet from "react-jss"; -import { type ButtonProps } from "./Button"; -import classNames from "classnames"; -import Button from "./Button"; +import styled from "styled-components"; +import Button, { type ButtonProps } from "./Button"; -const styles = { - spacing: { - marginTop: "2em", - border: "2px solid #e9f7fd", - padding: "1em 1em" - } - -}; +const Wrapper = styled.div` + margin-top: 2em; + padding: 1em 1em; + border: 2px solid #e9f7fd; +`; -class CreateButton extends React.Component { +export default class CreateButton extends React.Component { render() { - const { classes } = this.props; return ( -
+
+ ); } } - -export default injectSheet(styles)(CreateButton); diff --git a/scm-ui/ui-components/src/forms/FilterInput.js b/scm-ui/ui-components/src/forms/FilterInput.js index dc97b4856e..b430516abb 100644 --- a/scm-ui/ui-components/src/forms/FilterInput.js +++ b/scm-ui/ui-components/src/forms/FilterInput.js @@ -1,15 +1,13 @@ //@flow import React from "react"; -import injectSheet from "react-jss"; -import classNames from "classnames"; import { translate } from "react-i18next"; +import styled from "styled-components"; type Props = { filter: string => void, value?: string, // context props - classes: Object, t: string => string }; @@ -17,15 +15,9 @@ type State = { value: string }; -const styles = { - inputField: { - float: "right", - marginTop: "1.25rem" - }, - inputHeight: { - height: "2.5rem" - } -}; +const FixedHeightInput = styled.input` + height: 2.5rem; +`; class FilterInput extends React.Component { constructor(props) { @@ -43,15 +35,12 @@ class FilterInput extends React.Component { }; render() { - const { classes, t } = this.props; + const { t } = this.props; return ( -
+
- { } } -export default injectSheet(styles)(translate("commons")(FilterInput)); +export default translate("commons")(FilterInput); diff --git a/scm-ui/ui-components/src/forms/TagGroup.js b/scm-ui/ui-components/src/forms/TagGroup.js index ff72753b02..77d8090c49 100644 --- a/scm-ui/ui-components/src/forms/TagGroup.js +++ b/scm-ui/ui-components/src/forms/TagGroup.js @@ -1,6 +1,5 @@ //@flow import * as React from "react"; -import injectSheet from "react-jss"; import type { DisplayedUser } from "@scm-manager/ui-types"; import { Help, Tag } from "../index"; @@ -8,24 +7,15 @@ type Props = { items: DisplayedUser[], label: string, helpText?: string, - onRemove: (DisplayedUser[]) => void, - - // context props - classes: Object + onRemove: (DisplayedUser[]) => void }; -const styles = { - help: { - position: "relative" - } -}; - -class TagGroup extends React.Component { +export default class TagGroup extends React.Component { render() { - const { items, label, helpText, classes } = this.props; + const { items, label, helpText } = this.props; let help = null; if (helpText) { - help = ; + help = ; } return (
@@ -62,5 +52,3 @@ class TagGroup extends React.Component { this.props.onRemove(newItems); }; } - -export default injectSheet(styles)(TagGroup); diff --git a/scm-ui/ui-components/src/layout/Page.js b/scm-ui/ui-components/src/layout/Page.js index 622c4b429c..8d4f0241f1 100644 --- a/scm-ui/ui-components/src/layout/Page.js +++ b/scm-ui/ui-components/src/layout/Page.js @@ -1,7 +1,7 @@ //@flow import * as React from "react"; -import injectSheet from "react-jss"; import classNames from "classnames"; +import styled from "styled-components"; import Loading from "./../Loading"; import ErrorNotification from "./../ErrorNotification"; import Title from "./Title"; @@ -15,20 +15,20 @@ type Props = { loading?: boolean, error?: Error, showContentOnError?: boolean, - children: React.Node, - - // context props - classes: Object + children: React.Node }; -const styles = { - actions: { - display: "flex", - justifyContent: "flex-end" +const PageActionContainer = styled.div` + justify-content: flex-end; + align-items: center; + + // every child except first + > * ~ * { + margin-left: 1.25rem; } -}; +`; -class Page extends React.Component { +export default class Page extends React.Component { render() { const { error } = this.props; return ( @@ -45,12 +45,14 @@ class Page extends React.Component { } isPageAction(node: any) { - return node.displayName === PageActions.displayName - || (node.type && node.type.displayName === PageActions.displayName); + return ( + node.displayName === PageActions.displayName || + (node.type && node.type.displayName === PageActions.displayName) + ); } renderPageHeader() { - const { error, title, subtitle, children, classes } = this.props; + const { error, title, subtitle, children } = this.props; let pageActions = null; let pageActionsExists = false; @@ -58,14 +60,16 @@ class Page extends React.Component { if (child && !error) { if (this.isPageAction(child)) { pageActions = ( -
{child} -
+ ); pageActionsExists = true; } @@ -110,5 +114,3 @@ class Page extends React.Component { return content; } } - -export default injectSheet(styles)(Page); diff --git a/scm-ui/ui-components/src/repos/DiffFile.js b/scm-ui/ui-components/src/repos/DiffFile.js index 24009353af..7b0b40932e 100644 --- a/scm-ui/ui-components/src/repos/DiffFile.js +++ b/scm-ui/ui-components/src/repos/DiffFile.js @@ -1,5 +1,8 @@ //@flow import React from "react"; +import { translate } from "react-i18next"; +import classNames from "classnames"; +import styled from "styled-components"; import { Change, Diff as DiffComponent, @@ -8,71 +11,14 @@ import { getChangeKey, Hunk } from "react-diff-view"; -import injectSheets from "react-jss"; -import classNames from "classnames"; -import { translate } from "react-i18next"; import { Button, ButtonGroup } from "../buttons"; import Tag from "../Tag"; -const styles = { - panel: { - fontSize: "1rem" - }, - /* breaks into a second row - when buttons and title become too long */ - level: { - flexWrap: "wrap" - }, - titleHeader: { - display: "flex", - maxWidth: "100%", - cursor: "pointer" - }, - title: { - marginLeft: ".25rem", - fontSize: "1rem" - }, - /* align child to right */ - buttonHeader: { - display: "flex", - marginLeft: "auto" - }, - hunkDivider: { - margin: ".5rem 0" - }, - changeType: { - marginLeft: ".75rem" - }, - diff: { - /* column sizing */ - "& > colgroup .diff-gutter-col": { - width: "3.25rem" - }, - /* prevent following content from moving down */ - "& > .diff-gutter:empty:hover::after": { - fontSize: "0.7rem" - }, - /* smaller font size for code */ - "& .diff-line": { - fontSize: "0.75rem" - }, - /* comment padding for sideBySide view */ - "&.split .diff-widget-content .is-indented-line": { - paddingLeft: "3.25rem" - }, - /* comment padding for combined view */ - "&.unified .diff-widget-content .is-indented-line": { - paddingLeft: "6.5rem" - } - } -}; - type Props = DiffObjectProps & { file: File, collapsible: true, // context props - classes: any, t: string => string }; @@ -81,6 +27,64 @@ type State = { sideBySide: boolean }; +const DiffFilePanel = styled.div` + ${props => + props.file && + props.file.isBinary && { + borderBottom: "none" + }}; +`; + +const FlexWrapLevel = styled.div` + /* breaks into a second row + when buttons and title become too long */ + flex-wrap: wrap; +`; + +const FullWidthTitleHeader = styled.div` + max-width: 100%; +`; + +const TitleWrapper = styled.span` + margin-left: 0.25rem; +`; + +const ButtonWrapper = styled.div` + /* align child to right */ + margin-left: auto; +`; + +const HunkDivider = styled.hr` + margin: 0.5rem 0; +`; + +const ChangeTypeTag = styled(Tag)` + marginleft: ".75rem"; +`; + +const ModifiedDiffComponent = styled(DiffComponent)` + /* column sizing */ + > colgroup .diff-gutter-col: { + width: 3.25rem; + } + /* prevent following content from moving down */ + > .diff-gutter:empty:hover::after: { + font-size: 0.7rem; + } + /* smaller font size for code */ + & .diff-line: { + font-size: 0.75rem; + } + /* comment padding for sidebyside view */ + &.split .diff-widget-content .is-indented-line: { + padding-left: 3.25rem; + } + /* comment padding for combined view */ + &.unified .diff-widget-content .is-indented-line: { + padding-left: 6.5rem; + } +`; + class DiffFile extends React.Component { constructor(props: Props) { super(props); @@ -111,9 +115,8 @@ class DiffFile extends React.Component { }; createHunkHeader = (hunk: Hunk, i: number) => { - const { classes } = this.props; if (i > 0) { - return
; + return ; } return null; }; @@ -199,7 +202,7 @@ class DiffFile extends React.Component { }; renderChangeTag = (file: any) => { - const { t, classes } = this.props; + const { t } = this.props; if (!file.type) { return; } @@ -216,12 +219,8 @@ class DiffFile extends React.Component { : "info is-outlined"; return ( - @@ -234,7 +233,6 @@ class DiffFile extends React.Component { fileControlFactory, fileAnnotationFactory, collapsible, - classes, t } = this.props; const { collapsed, sideBySide } = this.state; @@ -250,12 +248,9 @@ class DiffFile extends React.Component { body = (
{fileAnnotations} - + {file.hunks.map(this.renderHunk)} - +
); } @@ -265,23 +260,27 @@ class DiffFile extends React.Component { ? fileControlFactory(file, this.setCollapse) : null; return ( -
+
-
-
+ {collapseIcon} - {this.renderFileTitle(file)} - + {this.renderChangeTag(file)} -
-
+ + {fileControls} -
-
+ +
{body} -
+ ); } } -export default injectSheets(styles)(translate("repos")(DiffFile)); +export default translate("repos")(DiffFile); diff --git a/scm-ui/ui-components/src/repos/changesets/ChangesetRow.js b/scm-ui/ui-components/src/repos/changesets/ChangesetRow.js index 311716ba06..61678c8447 100644 --- a/scm-ui/ui-components/src/repos/changesets/ChangesetRow.js +++ b/scm-ui/ui-components/src/repos/changesets/ChangesetRow.js @@ -1,60 +1,63 @@ //@flow import React from "react"; -import type { Changeset, Repository } from "@scm-manager/ui-types"; - -import classNames from "classnames"; import { Interpolate, translate } from "react-i18next"; -import ChangesetId from "./ChangesetId"; -import injectSheet from "react-jss"; -import { DateFromNow } from "../.."; -import ChangesetAuthor from "./ChangesetAuthor"; -import { parseDescription } from "./changesets"; -import { AvatarWrapper, AvatarImage } from "../../avatar"; +import classNames from "classnames"; +import styled from "styled-components"; import { ExtensionPoint } from "@scm-manager/ui-extensions"; +import type { Changeset, Repository } from "@scm-manager/ui-types"; +import DateFromNow from "../../DateFromNow"; +import { AvatarWrapper, AvatarImage } from "../../avatar"; +import { parseDescription } from "./changesets"; +import ChangesetId from "./ChangesetId"; +import ChangesetAuthor from "./ChangesetAuthor"; import ChangesetTags from "./ChangesetTags"; import ChangesetButtonGroup from "./ChangesetButtonGroup"; -const styles = { - changeset: { - // & references parent rule - // have a look at https://cssinjs.org/jss-plugin-nested?v=v10.0.0-alpha.9 - "& + &": { - borderTop: "1px solid rgba(219, 219, 219, 0.5)", - marginTop: "1rem", - paddingTop: "1rem" - } - }, - avatarFigure: { - marginTop: ".5rem", - marginRight: ".5rem" - }, - avatarImage: { - height: "35px", - width: "35px" - }, - metadata: { - marginLeft: 0 - }, - authorMargin: { - marginTop: "0.5rem" - }, - isVcentered: { - alignSelf: "center" - }, - flexVcenter: { - display: "flex", - alignItems: "center", - justifyContent: "flex-end" - } -}; - type Props = { repository: Repository, changeset: Changeset, - t: any, - classes: any + + // context props + t: string => string }; +const Wrapper = styled.div` + // & references parent rule + // have a look at https://cssinjs.org/jss-plugin-nested?v=v10.0.0-alpha.9 + & + &: { + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid rgba(219, 219, 219, 0.5); + } +`; + +const AvatarFigure = styled.figure` + margin-top: 0.5rem; + margin-right: 0.5rem; +`; + +const FixedSizedAvatar = styled.div` + width: 35px; + height: 35px; +`; + +const Metadata = styled.div` + margin-left: 0; +`; + +const AuthorWrapper = styled.p` + margin-top: 0.5rem; +`; + +const VCenteredColumn = styled.div` + align-self: center; +`; + +const VCenteredChildColumn = styled.div` + align-items: center; + justify-content: flex-end; +`; + class ChangesetRow extends React.Component { createChangesetId = (changeset: Changeset) => { const { repository } = this.props; @@ -62,28 +65,26 @@ class ChangesetRow extends React.Component { }; render() { - const { repository, changeset, classes } = this.props; + const { repository, changeset } = this.props; const description = parseDescription(changeset.description); const changesetId = this.createChangesetId(changeset); const dateFromNow = ; return ( -
+
-
-
+ + -
-
+ +
-
+

{ time={dateFromNow} />

-

+ -

-

+ +
-
+ -
+
-
+ { props={{ repository, changeset }} renderAll={true} /> -
+
-
+ ); } } -export default injectSheet(styles)(translate("repos")(ChangesetRow)); +export default translate("repos")(ChangesetRow); diff --git a/scm-ui/ui-webapp/src/style/scm.scss b/scm-ui/ui-webapp/src/style/scm.scss index fcbbb436a4..20e3c47ad7 100644 --- a/scm-ui/ui-webapp/src/style/scm.scss +++ b/scm-ui/ui-webapp/src/style/scm.scss @@ -5,6 +5,7 @@ $turquoise: #00d1df; $blue: #33b2e8; $cyan: $blue; $green: #00c79b; +$blue-light: #98d8f3; .is-ellipsis-overflow { overflow: hidden; @@ -145,6 +146,10 @@ $danger-25: scale-color($danger, $lightness: 75%); color: #ffb600 !important; } +.has-text-blue-light { + color: $blue-light !important; +} + // border and background colors .has-background-dark-75 { background-color: $dark-75; @@ -213,6 +218,9 @@ $danger-25: scale-color($danger, $lightness: 75%); .has-background-warning-invert { background-color: $warning-invert; } +.has-background-blue-light { + background-color: $blue-light; +} // tags .tag:not(body) { @@ -589,7 +597,7 @@ form .field:not(.is-grouped) { .input, .textarea { /*background-color: whitesmoke;*/ - border-color: #98d8f3; + border-color: $blue-light; box-shadow: none; }