From 0ad7444fb1dc2cdb82830df4ef241d75a6bfd82d Mon Sep 17 00:00:00 2001 From: Vijay Aravamudhan Date: Fri, 15 Oct 2021 15:25:41 +0530 Subject: chore: move 'packages/ui' into 'src' (no longer an injected package) (#2077) --- package-lock.json | 20 +- package.json | 1 - packages/ui/.gitignore | 2 - packages/ui/package.json | 31 ---- packages/ui/src/badge/ProBadge.tsx | 63 ------- packages/ui/src/badge/index.tsx | 71 ------- packages/ui/src/headline/index.tsx | 70 ------- packages/ui/src/icon/index.tsx | 46 ----- packages/ui/src/index.ts | 6 - packages/ui/src/infobox/index.tsx | 205 --------------------- packages/ui/src/loader/index.tsx | 44 ----- packages/ui/src/typings/generic.ts | 11 -- packages/ui/tsconfig.json | 12 -- src/components/auth/SetupAssistant.js | 2 +- .../services/content/ConnectionLostBanner.js | 3 +- .../settings/account/AccountDashboard.js | 2 +- .../settings/recipes/RecipesDashboard.js | 3 +- src/components/ui/Modal/index.tsx | 4 +- src/components/ui/badge/ProBadge.tsx | 64 +++++++ src/components/ui/badge/index.tsx | 71 +++++++ src/components/ui/headline/index.tsx | 70 +++++++ src/components/ui/icon/index.tsx | 46 +++++ src/components/ui/infobox/index.tsx | 205 +++++++++++++++++++++ src/components/ui/loader/index.tsx | 44 +++++ src/components/ui/typings/generic.ts | 11 ++ src/features/nightlyBuilds/Component.js | 2 +- src/features/publishDebugInfo/Component.js | 3 +- src/features/quickSwitch/Component.js | 4 +- src/features/webControls/components/WebControls.js | 3 +- .../workspaces/components/WorkspaceDrawer.js | 4 +- .../components/WorkspaceSwitchingIndicator.js | 2 +- .../workspaces/components/WorkspacesDashboard.js | 3 +- 32 files changed, 542 insertions(+), 586 deletions(-) delete mode 100644 packages/ui/.gitignore delete mode 100644 packages/ui/package.json delete mode 100644 packages/ui/src/badge/ProBadge.tsx delete mode 100644 packages/ui/src/badge/index.tsx delete mode 100644 packages/ui/src/headline/index.tsx delete mode 100644 packages/ui/src/icon/index.tsx delete mode 100644 packages/ui/src/index.ts delete mode 100644 packages/ui/src/infobox/index.tsx delete mode 100644 packages/ui/src/loader/index.tsx delete mode 100644 packages/ui/src/typings/generic.ts delete mode 100644 packages/ui/tsconfig.json create mode 100644 src/components/ui/badge/ProBadge.tsx create mode 100644 src/components/ui/badge/index.tsx create mode 100644 src/components/ui/headline/index.tsx create mode 100644 src/components/ui/icon/index.tsx create mode 100644 src/components/ui/infobox/index.tsx create mode 100644 src/components/ui/loader/index.tsx create mode 100644 src/components/ui/typings/generic.ts diff --git a/package-lock.json b/package-lock.json index 6dc24c638..3b71bdba0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5299,14 +5299,6 @@ "color": "4.0.1" } }, - "@meetfranz/ui": { - "version": "file:packages/ui", - "requires": { - "@mdi/react": "1.5.0", - "@meetfranz/theme": "file:packages/theme", - "react-loader": "2.4.7" - } - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -16485,7 +16477,17 @@ "dev": true, "optional": true, "requires": { - "cli-truncate": "^1.1.0" + "cli-truncate": "^1.1.0", + "node-addon-api": "^1.6.3" + }, + "dependencies": { + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "optional": true + } } }, "iconv-lite": { diff --git a/package.json b/package.json index 1733c0e24..e7388eec9 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,6 @@ "@mdi/js": "6.2.95", "@meetfranz/forms": "file:packages/forms", "@meetfranz/theme": "file:packages/theme", - "@meetfranz/ui": "file:packages/ui", "@sentry/electron": "2.5.3", "auto-launch": "5.0.5", "btoa": "1.2.1", diff --git a/packages/ui/.gitignore b/packages/ui/.gitignore deleted file mode 100644 index d01826a6b..000000000 --- a/packages/ui/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -lib diff --git a/packages/ui/package.json b/packages/ui/package.json deleted file mode 100644 index 0de76a98b..000000000 --- a/packages/ui/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@meetfranz/ui", - "version": "1.1.0", - "description": "React UI components for Franz", - "main": "lib/index.js", - "scripts": { - "dev": "tsc -w", - "build": "tsc" - }, - "publishConfig": { - "access": "public" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/meetfranz/franz.git" - }, - "keywords": [ - "Franz", - "Forms", - "React", - "UI" - ], - "author": "Stefan Malzner ", - "license": "Apache-2.0", - "dependencies": { - "@mdi/react": "1.5.0", - "@meetfranz/theme": "file:../theme", - "react-loader": "2.4.7" - }, - "gitHead": "254da30f801169fac376bda1439b46cabbb491ad" -} diff --git a/packages/ui/src/badge/ProBadge.tsx b/packages/ui/src/badge/ProBadge.tsx deleted file mode 100644 index be7ed8e58..000000000 --- a/packages/ui/src/badge/ProBadge.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { mdiStar } from '@mdi/js'; -import classnames from 'classnames'; -import { Component } from 'react'; -import injectStyle from 'react-jss'; - -import { Badge, Icon } from '..'; -import { Theme } from '../../../theme'; -import { IWithStyle } from '../typings/generic'; - -interface IProps extends IWithStyle { - badgeClasses?: string; - iconClasses?: string; - inverted?: boolean; - className?: string; -} - -const styles = (theme: Theme) => ({ - badge: { - height: 'auto', - padding: [4, 6, 2, 7], - borderRadius: theme.borderRadiusSmall, - }, - invertedBadge: { - background: theme.styleTypes.primary.contrast, - color: theme.styleTypes.primary.accent, - }, - icon: { - fill: theme.styleTypes.primary.contrast, - }, - invertedIcon: { - fill: theme.styleTypes.primary.accent, - }, -}); - -class ProBadgeComponent extends Component { - render() { - const { classes, badgeClasses, iconClasses, inverted, className } = - this.props; - - return ( - - - - ); - } -} - -export const ProBadge = injectStyle(styles)(ProBadgeComponent); diff --git a/packages/ui/src/badge/index.tsx b/packages/ui/src/badge/index.tsx deleted file mode 100644 index a8f3ebcbf..000000000 --- a/packages/ui/src/badge/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import classnames from 'classnames'; -import { Component, ReactNode } from 'react'; -import injectStyle from 'react-jss'; - -import { Theme } from '../../../theme'; -import { IWithStyle } from '../typings/generic'; - -interface IProps extends IWithStyle { - type: string; - className?: string; - children: ReactNode; -} - -const badgeStyles = (theme: Theme) => { - const styles = {}; - Object.keys(theme.styleTypes).map(style => { - Object.assign(styles, { - [style]: { - background: theme.styleTypes[style].accent, - color: theme.styleTypes[style].contrast, - border: theme.styleTypes[style].border, - }, - }); - }); - - return styles; -}; - -const styles = (theme: Theme) => ({ - badge: { - display: 'inline-block', - padding: [3, 8, 4], - fontSize: theme.badgeFontSize, - borderRadius: theme.badgeBorderRadius, - margin: [0, 4], - - '&:first-child': { - marginLeft: 0, - }, - - '&:last-child': { - marginRight: 0, - }, - }, - ...badgeStyles(theme), -}); - -class BadgeComponent extends Component { - public static defaultProps = { - type: 'primary', - }; - - render() { - const { classes, children, type, className } = this.props; - - return ( -
- {children} -
- ); - } -} - -export const Badge = injectStyle(styles)(BadgeComponent); diff --git a/packages/ui/src/headline/index.tsx b/packages/ui/src/headline/index.tsx deleted file mode 100644 index b534a6298..000000000 --- a/packages/ui/src/headline/index.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import classnames from 'classnames'; -import { Component, createElement, ReactNode } from 'react'; -import injectStyle from 'react-jss'; - -import { Theme } from '../../../theme'; -import { IWithStyle, Omit } from '../typings/generic'; - -interface IProps extends IWithStyle { - level?: number; - className?: string; - children: string | ReactNode; - id?: string; -} - -const styles = (theme: Theme) => ({ - headline: { - fontWeight: 'lighter', - color: theme.colorText, - marginTop: 0, - marginBottom: 10, - textAlign: 'left', - }, - h1: { - fontSize: 30, - marginTop: 0, - }, - h2: { - fontSize: 20, - }, - h3: { - fontSize: 18, - }, - h4: { - fontSize: theme.uiFontSize, - }, -}); - -class HeadlineComponent extends Component { - render() { - const { classes, level, className, children, id } = this.props; - - return createElement( - `h${level}`, - { - id, - className: classnames({ - [classes.headline]: true, - [classes[level ? `h${level}` : 'h1']]: true, - [`${className}`]: className, - }), - 'data-type': 'franz-headline', - }, - children, - ); - } -} - -const Headline = injectStyle(styles)(HeadlineComponent); - -const createH = (level: number) => (props: Omit) => - ( - - {props.children} - - ); - -export const H1 = createH(1); -export const H2 = createH(2); -export const H3 = createH(3); -export const H4 = createH(4); diff --git a/packages/ui/src/icon/index.tsx b/packages/ui/src/icon/index.tsx deleted file mode 100644 index 9753b399c..000000000 --- a/packages/ui/src/icon/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import MdiIcon from '@mdi/react'; -import classnames from 'classnames'; -import { Component } from 'react'; -import injectStyle from 'react-jss'; - -import { Theme } from '../../../theme'; -import { IWithStyle } from '../typings/generic'; - -interface IProps extends IWithStyle { - icon: string; - size?: number; - className?: string; -} - -const styles = (theme: Theme) => ({ - icon: { - fill: theme.colorText, - }, -}); - -class IconComponent extends Component { - public static defaultProps = { - size: 1, - }; - - render() { - const { classes, icon, size, className } = this.props; - - if (!icon) { - console.warn('No Icon specified'); - } - - return ( - - ); - } -} - -export const Icon = injectStyle(styles)(IconComponent); diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts deleted file mode 100644 index bab3fc27b..000000000 --- a/packages/ui/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { Icon } from './icon'; -export { Infobox } from './infobox'; -export { H1, H2, H3, H4 } from './headline'; -export { Loader } from './loader'; -export { Badge } from './badge'; -export { ProBadge } from './badge/ProBadge'; diff --git a/packages/ui/src/infobox/index.tsx b/packages/ui/src/infobox/index.tsx deleted file mode 100644 index 7bad4a1f2..000000000 --- a/packages/ui/src/infobox/index.tsx +++ /dev/null @@ -1,205 +0,0 @@ -import { mdiClose } from '@mdi/js'; -import classnames from 'classnames'; -import { Component, ReactNode } from 'react'; -import injectStyle from 'react-jss'; - -import { Icon } from '..'; -import { Theme } from '../../../theme'; -import { IWithStyle } from '../typings/generic'; - -interface IProps extends IWithStyle { - icon?: string; - type?: string; - dismissable?: boolean; - onDismiss?: () => void; - onUnmount?: () => void; - ctaOnClick?: () => void; - ctaLabel?: string; - ctaLoading?: boolean; - children: ReactNode; - className: string; -} - -interface IState { - isDismissing: boolean; - dismissed: boolean; -} - -const buttonStyles = (theme: Theme) => { - const styles = {}; - Object.keys(theme.styleTypes).map(style => { - Object.assign(styles, { - [style]: { - background: theme.styleTypes[style].accent, - color: theme.styleTypes[style].contrast, - border: theme.styleTypes[style].border, - - '& svg': { - fill: theme.styleTypes[style].contrast, - }, - }, - }); - }); - - return styles; -}; - -const infoBoxTransition: string = 'none'; -const ctaTransition: string = 'none'; - -// TODO: Not sure why, but this location alone, the `dinwo` is not defined - and it throws an error thus aborting the startup sequence of ferdi -// if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) { -// infoBoxTransition = 'all 0.5s'; -// ctaTransition = 'opacity 0.3s'; -// } - -const styles = (theme: Theme) => ({ - wrapper: { - position: 'relative', - overflow: 'hidden', - height: 'auto', - marginBottom: 30, - }, - infobox: { - alignItems: 'center', - borderRadius: theme.borderRadiusSmall, - display: 'flex', - height: 'auto', - padding: '15px 20px', - top: 0, - transition: infoBoxTransition, - opacity: 1, - }, - dismissing: { - // position: 'absolute', - marginTop: -100, - opacity: 0, - }, - content: { - flex: 1, - }, - icon: { - marginRight: 10, - }, - close: { - color: (props: IProps) => - theme.styleTypes[props.type ? props.type : 'primary'].contrast, - marginRight: -5, - border: 0, - background: 'none', - }, - cta: { - borderColor: (props: IProps) => - theme.styleTypes[props.type ? props.type : 'primary'].contrast, - borderRadius: theme.borderRadiusSmall, - borderStyle: 'solid', - borderWidth: 1, - background: 'none', - color: (props: IProps) => - theme.styleTypes[props.type ? props.type : 'primary'].contrast, - marginLeft: 15, - padding: [4, 10], - fontSize: theme.uiFontSize, - transition: ctaTransition, - - '&:hover': { - opacity: 0.6, - }, - }, - ...buttonStyles(theme), -}); - -class InfoboxComponent extends Component { - public static defaultProps = { - type: 'primary', - dismissable: false, - ctaOnClick: () => {}, - onDismiss: () => {}, - ctaLabel: '', - ctaLoading: false, - }; - - state = { - isDismissing: false, - dismissed: false, - }; - - dismiss() { - const { onDismiss } = this.props; - - this.setState({ - isDismissing: true, - }); - - if (onDismiss) { - onDismiss(); - } - - setTimeout(() => { - this.setState({ - dismissed: true, - }); - }, 3000); - } - - componentWillUnmount(): void { - const { onUnmount } = this.props; - if (onUnmount) onUnmount(); - } - - render() { - const { - classes, - children, - icon, - type, - ctaLabel, - ctaOnClick, - dismissable, - className, - } = this.props; - - const { isDismissing, dismissed } = this.state; - - if (dismissed) { - return null; - } - - return ( -
-
- {icon && } -
{children}
- {ctaLabel && ( - - )} - {dismissable && ( - - )} -
-
- ); - } -} - -export const Infobox = injectStyle(styles)(InfoboxComponent); diff --git a/packages/ui/src/loader/index.tsx b/packages/ui/src/loader/index.tsx deleted file mode 100644 index 0607bd48b..000000000 --- a/packages/ui/src/loader/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import classnames from 'classnames'; -import { Component } from 'react'; -import injectStyle, { withTheme } from 'react-jss'; -import ReactLoader from 'react-loader'; - -import { IWithStyle } from '../typings/generic'; - -interface IProps extends IWithStyle { - className?: string; - color?: string; -} - -const styles = () => ({ - container: { - position: 'relative', - height: 60, - }, -}); - -class LoaderComponent extends Component { - render() { - const { classes, className, color, theme } = this.props; - - return ( -
- -
- ); - } -} - -export const Loader = injectStyle(styles)(withTheme(LoaderComponent)); diff --git a/packages/ui/src/typings/generic.ts b/packages/ui/src/typings/generic.ts deleted file mode 100644 index a2b9c041c..000000000 --- a/packages/ui/src/typings/generic.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Classes } from 'jss'; - -import { Theme } from '../../../theme'; - -export interface IWithStyle { - classes: Classes; - theme: Theme; -} - -export type Merge = Omit> & N; -export type Omit = Pick>; diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json deleted file mode 100644 index 015581136..000000000 --- a/packages/ui/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "lib", - "rootDir": "src" - }, - "references": [ - { - "path": "../theme" - } - ] -} diff --git a/src/components/auth/SetupAssistant.js b/src/components/auth/SetupAssistant.js index d0efd6361..d009a2878 100644 --- a/src/components/auth/SetupAssistant.js +++ b/src/components/auth/SetupAssistant.js @@ -6,7 +6,7 @@ import injectSheet from 'react-jss'; import classnames from 'classnames'; import { Input, Button } from '@meetfranz/forms'; -import { Badge } from '@meetfranz/ui'; +import { Badge } from '../ui/badge'; import Modal from '../ui/Modal'; import Infobox from '../ui/Infobox'; import Appear from '../ui/effects/Appear'; diff --git a/src/components/services/content/ConnectionLostBanner.js b/src/components/services/content/ConnectionLostBanner.js index 236d2739b..5111a081a 100644 --- a/src/components/services/content/ConnectionLostBanner.js +++ b/src/components/services/content/ConnectionLostBanner.js @@ -2,12 +2,11 @@ import { createRef, Component } from 'react'; import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; -import { Icon } from '@meetfranz/ui'; import { defineMessages, injectIntl } from 'react-intl'; import { mdiAlert } from '@mdi/js'; import { LIVE_API_FERDI_WEBSITE } from '../../../config'; -// import { Button } from '@meetfranz/forms'; +import { Icon } from '../../ui/icon'; const messages = defineMessages({ text: { diff --git a/src/components/settings/account/AccountDashboard.js b/src/components/settings/account/AccountDashboard.js index 686501267..6c489e64b 100644 --- a/src/components/settings/account/AccountDashboard.js +++ b/src/components/settings/account/AccountDashboard.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; import { defineMessages, injectIntl } from 'react-intl'; import ReactTooltip from 'react-tooltip'; -import { H1, H2 } from '@meetfranz/ui'; +import { H1, H2 } from '../../ui/headline'; import Loader from '../../ui/Loader'; import Button from '../../ui/Button'; diff --git a/src/components/settings/recipes/RecipesDashboard.js b/src/components/settings/recipes/RecipesDashboard.js index 0c521319a..8ab726eb3 100644 --- a/src/components/settings/recipes/RecipesDashboard.js +++ b/src/components/settings/recipes/RecipesDashboard.js @@ -6,7 +6,8 @@ import { Link } from 'react-router'; import { Button, Input } from '@meetfranz/forms'; import injectSheet from 'react-jss'; -import { H3, H2 } from '@meetfranz/ui'; + +import { H3, H2 } from '../../ui/headline'; import SearchInput from '../../ui/SearchInput'; import Infobox from '../../ui/Infobox'; import RecipeItem from './RecipeItem'; diff --git a/src/components/ui/Modal/index.tsx b/src/components/ui/Modal/index.tsx index 0bb0aaa61..f2f4461b8 100644 --- a/src/components/ui/Modal/index.tsx +++ b/src/components/ui/Modal/index.tsx @@ -2,9 +2,9 @@ import { Component, ReactChildren } from 'react'; import ReactModal from 'react-modal'; import classnames from 'classnames'; import injectCSS from 'react-jss'; -import { Icon } from '@meetfranz/ui'; - import { mdiClose } from '@mdi/js'; + +import { Icon } from '../icon'; import styles from './styles'; type Props = { diff --git a/src/components/ui/badge/ProBadge.tsx b/src/components/ui/badge/ProBadge.tsx new file mode 100644 index 000000000..cb6bc4c98 --- /dev/null +++ b/src/components/ui/badge/ProBadge.tsx @@ -0,0 +1,64 @@ +import { mdiStar } from '@mdi/js'; +import classnames from 'classnames'; +import { Component } from 'react'; +import injectStyle from 'react-jss'; + +import { Theme } from '@meetfranz/theme'; +import { Icon } from '../icon'; +import { Badge } from './index'; +import { IWithStyle } from '../typings/generic'; + +interface IProps extends IWithStyle { + badgeClasses?: string; + iconClasses?: string; + inverted?: boolean; + className?: string; +} + +const styles = (theme: Theme) => ({ + badge: { + height: 'auto', + padding: [4, 6, 2, 7], + borderRadius: theme.borderRadiusSmall, + }, + invertedBadge: { + background: theme.styleTypes.primary.contrast, + color: theme.styleTypes.primary.accent, + }, + icon: { + fill: theme.styleTypes.primary.contrast, + }, + invertedIcon: { + fill: theme.styleTypes.primary.accent, + }, +}); + +class ProBadgeComponent extends Component { + render() { + const { classes, badgeClasses, iconClasses, inverted, className } = + this.props; + + return ( + + + + ); + } +} + +export const ProBadge = injectStyle(styles)(ProBadgeComponent); diff --git a/src/components/ui/badge/index.tsx b/src/components/ui/badge/index.tsx new file mode 100644 index 000000000..6495036ff --- /dev/null +++ b/src/components/ui/badge/index.tsx @@ -0,0 +1,71 @@ +import classnames from 'classnames'; +import { Component, ReactNode } from 'react'; +import injectStyle from 'react-jss'; + +import { Theme } from '@meetfranz/theme'; +import { IWithStyle } from '../typings/generic'; + +interface IProps extends IWithStyle { + type: string; + className?: string; + children: ReactNode; +} + +const badgeStyles = (theme: Theme) => { + const styles = {}; + Object.keys(theme.styleTypes).map(style => { + Object.assign(styles, { + [style]: { + background: theme.styleTypes[style].accent, + color: theme.styleTypes[style].contrast, + border: theme.styleTypes[style].border, + }, + }); + }); + + return styles; +}; + +const styles = (theme: Theme) => ({ + badge: { + display: 'inline-block', + padding: [3, 8, 4], + fontSize: theme.badgeFontSize, + borderRadius: theme.badgeBorderRadius, + margin: [0, 4], + + '&:first-child': { + marginLeft: 0, + }, + + '&:last-child': { + marginRight: 0, + }, + }, + ...badgeStyles(theme), +}); + +class BadgeComponent extends Component { + public static defaultProps = { + type: 'primary', + }; + + render() { + const { classes, children, type, className } = this.props; + + return ( +
+ {children} +
+ ); + } +} + +export const Badge = injectStyle(styles)(BadgeComponent); diff --git a/src/components/ui/headline/index.tsx b/src/components/ui/headline/index.tsx new file mode 100644 index 000000000..3a3654f02 --- /dev/null +++ b/src/components/ui/headline/index.tsx @@ -0,0 +1,70 @@ +import classnames from 'classnames'; +import { Component, createElement, ReactNode } from 'react'; +import injectStyle from 'react-jss'; + +import { Theme } from '@meetfranz/theme'; +import { IWithStyle, Omit } from '../typings/generic'; + +interface IProps extends IWithStyle { + level?: number; + className?: string; + children: string | ReactNode; + id?: string; +} + +const styles = (theme: Theme) => ({ + headline: { + fontWeight: 'lighter', + color: theme.colorText, + marginTop: 0, + marginBottom: 10, + textAlign: 'left', + }, + h1: { + fontSize: 30, + marginTop: 0, + }, + h2: { + fontSize: 20, + }, + h3: { + fontSize: 18, + }, + h4: { + fontSize: theme.uiFontSize, + }, +}); + +class HeadlineComponent extends Component { + render() { + const { classes, level, className, children, id } = this.props; + + return createElement( + `h${level}`, + { + id, + className: classnames({ + [classes.headline]: true, + [classes[level ? `h${level}` : 'h1']]: true, + [`${className}`]: className, + }), + 'data-type': 'franz-headline', + }, + children, + ); + } +} + +const Headline = injectStyle(styles)(HeadlineComponent); + +const createH = (level: number) => (props: Omit) => + ( + + {props.children} + + ); + +export const H1 = createH(1); +export const H2 = createH(2); +export const H3 = createH(3); +export const H4 = createH(4); diff --git a/src/components/ui/icon/index.tsx b/src/components/ui/icon/index.tsx new file mode 100644 index 000000000..fdc48d14a --- /dev/null +++ b/src/components/ui/icon/index.tsx @@ -0,0 +1,46 @@ +import MdiIcon from '@mdi/react'; +import classnames from 'classnames'; +import { Component } from 'react'; +import injectStyle from 'react-jss'; + +import { Theme } from '@meetfranz/theme'; +import { IWithStyle } from '../typings/generic'; + +interface IProps extends IWithStyle { + icon: string; + size?: number; + className?: string; +} + +const styles = (theme: Theme) => ({ + icon: { + fill: theme.colorText, + }, +}); + +class IconComponent extends Component { + public static defaultProps = { + size: 1, + }; + + render() { + const { classes, icon, size, className } = this.props; + + if (!icon) { + console.warn('No Icon specified'); + } + + return ( + + ); + } +} + +export const Icon = injectStyle(styles)(IconComponent); diff --git a/src/components/ui/infobox/index.tsx b/src/components/ui/infobox/index.tsx new file mode 100644 index 000000000..e6be83556 --- /dev/null +++ b/src/components/ui/infobox/index.tsx @@ -0,0 +1,205 @@ +import { mdiClose } from '@mdi/js'; +import classnames from 'classnames'; +import { Component, ReactNode } from 'react'; +import injectStyle from 'react-jss'; + +import { Theme } from '@meetfranz/theme'; +import { Icon } from '../icon'; +import { IWithStyle } from '../typings/generic'; + +interface IProps extends IWithStyle { + icon?: string; + type?: string; + dismissable?: boolean; + onDismiss?: () => void; + onUnmount?: () => void; + ctaOnClick?: () => void; + ctaLabel?: string; + ctaLoading?: boolean; + children: ReactNode; + className: string; +} + +interface IState { + isDismissing: boolean; + dismissed: boolean; +} + +const buttonStyles = (theme: Theme) => { + const styles = {}; + Object.keys(theme.styleTypes).map(style => { + Object.assign(styles, { + [style]: { + background: theme.styleTypes[style].accent, + color: theme.styleTypes[style].contrast, + border: theme.styleTypes[style].border, + + '& svg': { + fill: theme.styleTypes[style].contrast, + }, + }, + }); + }); + + return styles; +}; + +const infoBoxTransition: string = 'none'; +const ctaTransition: string = 'none'; + +// TODO: Not sure why, but this location alone, the `dinwo` is not defined - and it throws an error thus aborting the startup sequence of ferdi +// if (window && window.matchMedia('(prefers-reduced-motion: no-preference)')) { +// infoBoxTransition = 'all 0.5s'; +// ctaTransition = 'opacity 0.3s'; +// } + +const styles = (theme: Theme) => ({ + wrapper: { + position: 'relative', + overflow: 'hidden', + height: 'auto', + marginBottom: 30, + }, + infobox: { + alignItems: 'center', + borderRadius: theme.borderRadiusSmall, + display: 'flex', + height: 'auto', + padding: '15px 20px', + top: 0, + transition: infoBoxTransition, + opacity: 1, + }, + dismissing: { + // position: 'absolute', + marginTop: -100, + opacity: 0, + }, + content: { + flex: 1, + }, + icon: { + marginRight: 10, + }, + close: { + color: (props: IProps) => + theme.styleTypes[props.type ? props.type : 'primary'].contrast, + marginRight: -5, + border: 0, + background: 'none', + }, + cta: { + borderColor: (props: IProps) => + theme.styleTypes[props.type ? props.type : 'primary'].contrast, + borderRadius: theme.borderRadiusSmall, + borderStyle: 'solid', + borderWidth: 1, + background: 'none', + color: (props: IProps) => + theme.styleTypes[props.type ? props.type : 'primary'].contrast, + marginLeft: 15, + padding: [4, 10], + fontSize: theme.uiFontSize, + transition: ctaTransition, + + '&:hover': { + opacity: 0.6, + }, + }, + ...buttonStyles(theme), +}); + +class InfoboxComponent extends Component { + public static defaultProps = { + type: 'primary', + dismissable: false, + ctaOnClick: () => {}, + onDismiss: () => {}, + ctaLabel: '', + ctaLoading: false, + }; + + state = { + isDismissing: false, + dismissed: false, + }; + + dismiss() { + const { onDismiss } = this.props; + + this.setState({ + isDismissing: true, + }); + + if (onDismiss) { + onDismiss(); + } + + setTimeout(() => { + this.setState({ + dismissed: true, + }); + }, 3000); + } + + componentWillUnmount(): void { + const { onUnmount } = this.props; + if (onUnmount) onUnmount(); + } + + render() { + const { + classes, + children, + icon, + type, + ctaLabel, + ctaOnClick, + dismissable, + className, + } = this.props; + + const { isDismissing, dismissed } = this.state; + + if (dismissed) { + return null; + } + + return ( +
+
+ {icon && } +
{children}
+ {ctaLabel && ( + + )} + {dismissable && ( + + )} +
+
+ ); + } +} + +export const Infobox = injectStyle(styles)(InfoboxComponent); diff --git a/src/components/ui/loader/index.tsx b/src/components/ui/loader/index.tsx new file mode 100644 index 000000000..0607bd48b --- /dev/null +++ b/src/components/ui/loader/index.tsx @@ -0,0 +1,44 @@ +import classnames from 'classnames'; +import { Component } from 'react'; +import injectStyle, { withTheme } from 'react-jss'; +import ReactLoader from 'react-loader'; + +import { IWithStyle } from '../typings/generic'; + +interface IProps extends IWithStyle { + className?: string; + color?: string; +} + +const styles = () => ({ + container: { + position: 'relative', + height: 60, + }, +}); + +class LoaderComponent extends Component { + render() { + const { classes, className, color, theme } = this.props; + + return ( +
+ +
+ ); + } +} + +export const Loader = injectStyle(styles)(withTheme(LoaderComponent)); diff --git a/src/components/ui/typings/generic.ts b/src/components/ui/typings/generic.ts new file mode 100644 index 000000000..ddce3f7c7 --- /dev/null +++ b/src/components/ui/typings/generic.ts @@ -0,0 +1,11 @@ +import { Classes } from 'jss'; + +import { Theme } from '@meetfranz/theme'; + +export interface IWithStyle { + classes: Classes; + theme: Theme; +} + +export type Merge = Omit> & N; +export type Omit = Pick>; diff --git a/src/features/nightlyBuilds/Component.js b/src/features/nightlyBuilds/Component.js index 98a7cb5a2..64f782c8f 100644 --- a/src/features/nightlyBuilds/Component.js +++ b/src/features/nightlyBuilds/Component.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { observer, inject } from 'mobx-react'; import injectSheet from 'react-jss'; import { defineMessages, injectIntl } from 'react-intl'; -import { H1 } from '@meetfranz/ui'; +import { H1 } from '../../components/ui/headline'; import Modal from '../../components/ui/Modal'; import Button from '../../components/ui/Button'; diff --git a/src/features/publishDebugInfo/Component.js b/src/features/publishDebugInfo/Component.js index d3751b63d..30bdc13b6 100644 --- a/src/features/publishDebugInfo/Component.js +++ b/src/features/publishDebugInfo/Component.js @@ -1,10 +1,11 @@ -import { H1 } from '@meetfranz/ui'; import { inject, observer } from 'mobx-react'; import PropTypes from 'prop-types'; import { Component } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; import injectSheet from 'react-jss'; import { state as ModalState } from './store'; + +import { H1 } from '../../components/ui/headline'; import { sendAuthRequest } from '../../api/utils/auth'; import Button from '../../components/ui/Button'; import Input from '../../components/ui/Input'; diff --git a/src/features/quickSwitch/Component.js b/src/features/quickSwitch/Component.js index 76b3c9b4b..ced047a93 100644 --- a/src/features/quickSwitch/Component.js +++ b/src/features/quickSwitch/Component.js @@ -6,9 +6,9 @@ import { reaction } from 'mobx'; import injectSheet from 'react-jss'; import { defineMessages, injectIntl } from 'react-intl'; import { Input } from '@meetfranz/forms'; -import { H1 } from '@meetfranz/ui'; - import { compact, invoke } from 'lodash'; + +import { H1 } from '../../components/ui/headline'; import Modal from '../../components/ui/Modal'; import { state as ModalState } from './store'; import ServicesStore from '../../stores/ServicesStore'; diff --git a/src/features/webControls/components/WebControls.js b/src/features/webControls/components/WebControls.js index 8261ede2b..5650d4cd1 100644 --- a/src/features/webControls/components/WebControls.js +++ b/src/features/webControls/components/WebControls.js @@ -2,7 +2,6 @@ import { createRef, Component } from 'react'; import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; -import { Icon } from '@meetfranz/ui'; import { defineMessages, injectIntl } from 'react-intl'; import { @@ -13,6 +12,8 @@ import { mdiEarth, } from '@mdi/js'; +import { Icon } from '../../../components/ui/icon'; + const messages = defineMessages({ goHome: { id: 'webControls.goHome', diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js index 54e74fdf5..590efacd0 100644 --- a/src/features/workspaces/components/WorkspaceDrawer.js +++ b/src/features/workspaces/components/WorkspaceDrawer.js @@ -3,10 +3,12 @@ import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; import { defineMessages, injectIntl } from 'react-intl'; -import { H1, Icon } from '@meetfranz/ui'; import ReactTooltip from 'react-tooltip'; import { mdiPlusBox, mdiCog } from '@mdi/js'; + +import { H1 } from '../../../components/ui/headline'; +import { Icon } from '../../../components/ui/icon'; import WorkspaceDrawerItem from './WorkspaceDrawerItem'; import { workspaceActions } from '../actions'; import { workspaceStore } from '../index'; diff --git a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js index 187b6a516..ff4e9475a 100644 --- a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js +++ b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js @@ -3,9 +3,9 @@ import PropTypes from 'prop-types'; import { observer } from 'mobx-react'; import injectSheet from 'react-jss'; import classnames from 'classnames'; -import { Loader } from '@meetfranz/ui'; import { defineMessages, injectIntl } from 'react-intl'; +import { Loader } from '../../../components/ui/loader/index'; import { workspaceStore } from '../index'; const messages = defineMessages({ diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 8ab9174d3..6e0d98ffb 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js @@ -3,9 +3,10 @@ import PropTypes from 'prop-types'; import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react'; import { defineMessages, injectIntl } from 'react-intl'; import injectSheet from 'react-jss'; -import { Infobox } from '@meetfranz/ui'; import { mdiCheckboxMarkedCircleOutline } from '@mdi/js'; + +import { Infobox } from '../../../components/ui/infobox/index'; import Loader from '../../../components/ui/Loader'; import WorkspaceItem from './WorkspaceItem'; import CreateWorkspaceForm from './CreateWorkspaceForm'; -- cgit v1.2.3-70-g09d2