Deleted file with button component, remove all component button from all dependent files

This commit is contained in:
Maximus 2022-08-02 15:58:24 +03:00
parent 14d78e63d3
commit a0518a50c5
14 changed files with 12 additions and 428 deletions

View File

@ -4,7 +4,6 @@ import React, { Fragment } from "react";
import _ModalTitle from "./_ModalTitle";
import _ModalFooter from "./_ModalFooter";
import classNames from "classnames";
import _ModalCloseButton from "./_ModalCloseButton";
type Props = {
children: React.ReactNode;
@ -57,6 +56,5 @@ function Modal ({
Modal.Header = _ModalTitle;
Modal.Footer = _ModalFooter;
Modal.CloseButton = _ModalCloseButton;
export default Modal;

View File

@ -1,24 +0,0 @@
import React from "react";
import Button from "components/controls/Button";
import { ReactComponent as SVGTimesIcon } from "assets/svg/times.svg";
type Props = {
onClose: VoidFunction,
};
export default function _ModalCloseButton({onClose}: Props) {
return (
<div className="absolute right-4 top-4">
<Button
htmlType="button"
iconed="only"
className="w-10 h-10"
variant="gray"
type="text"
onClick={onClose}
>
<SVGTimesIcon className="w-full h-full stroke-current" />
</Button>
</div>
);
}

View File

@ -1,239 +0,0 @@
import classNames from 'classnames';
import {
StyleColorVariants,
StyleColorVariantsMap,
StyleType,
} from 'core/_variants';
import React from 'react';
type Props = {
href?: string;
variant?: StyleColorVariants;
type?: StyleType;
iconed?: boolean | "only";
glowing?: boolean;
disabled?: boolean;
onClick?: (event: React.MouseEvent) => void;
children?: React.ReactNode;
className?: string | undefined;
rel?: string | undefined;
htmlType?: 'button' | 'submit' | 'reset' | undefined;
};
const buttonBgVariants: StyleColorVariantsMap<string> = {
gray: 'bg-gray-500',
blue: 'bg-blue-500',
emerald: 'bg-emerald-600',
pink: 'bg-pink-500',
purple: 'bg-purple-500',
red: 'bg-red-500',
sky: 'bg-sky-500',
yellow: 'bg-yellow-500',
"dark-coral": "bg-dark-coral-500",
};
const buttonBgDisabledVariants: StyleColorVariantsMap<string> = {
gray: 'bg-gray-200',
blue: 'bg-blue-100/10',
emerald: 'bg-emerald-200/50',
pink: 'bg-pink-200/50',
purple: 'bg-purple-200/50',
red: 'bg-red-200/50',
sky: 'bg-sky-200/50',
yellow: 'bg-yellow-200/50',
"dark-coral": "bg-dark-coral-200/50",
};
const buttonBgDisabledHoverVariants: StyleColorVariantsMap<string> = {
gray: 'hover:bg-gray-500/50',
blue: 'hover:bg-blue-100/10',
emerald: 'hover:bg-emerald-500/50',
pink: 'hover:bg-pink-500/50',
purple: 'hover:bg-purple-500/50',
red: 'hover:bg-red-500/50',
sky: 'hover:bg-sky-500/50',
yellow: 'hover:bg-yellow-500/50',
"dark-coral": "hover:bg-dark-coral-500/50",
};
const buttonHoverBgVariants: StyleColorVariantsMap<string> = {
gray: 'hover:bg-gray-600',
blue: 'hover:bg-blue-400',
emerald: 'hover:bg-emerald-600',
pink: 'hover:bg-pink-600',
purple: 'hover:bg-purple-600',
red: 'hover:bg-red-600',
sky: 'hover:bg-sky-600',
yellow: 'hover:bg-yellow-600',
"dark-coral": "hover:bg-dark-coral-600",
};
const buttonBorderVariants: StyleColorVariantsMap<string> = {
gray: 'border-gray-500',
blue: 'border-blue-500',
emerald: 'border-emerald-700',
pink: 'border-pink-300',
purple: 'border-purple-300',
red: 'border-red-300',
sky: 'border-sky-300',
yellow: 'border-yellow-300',
"dark-coral": "border-dark-coral-500",
};
const buttonBorderHoverVariants: StyleColorVariantsMap<string> = {
gray: 'hover:border-gray-500',
blue: 'hover:border-blue-400',
emerald: 'hover:border-emerald-900',
pink: 'hover:border-pink-400',
purple: 'hover:border-purple-400',
red: 'hover:border-red-500',
sky: 'hover:border-sky-400',
yellow: 'hover:border-yellow-400',
"dark-coral": "hover:border-dark-coral-400",
};
const buttonTextVariants: StyleColorVariantsMap<string> = {
gray: 'text-white',
blue: 'text-white',
emerald: 'text-emerald-300',
pink: 'text-white',
purple: 'text-white',
red: 'text-white',
sky: 'text-white',
yellow: 'text-white',
"dark-coral": "text-white",
};
const buttonTextHoverVariants: StyleColorVariantsMap<string> = {
blue: 'hover:text-white',
emerald: 'hover:text-emerald-900',
gray: 'hover:text-white',
pink: 'hover:text-white',
purple: 'hover:text-white',
red: 'hover:text-white',
sky: 'hover:text-white',
yellow: 'hover:text-white',
"dark-coral": 'hover:text-white',
}
const buttonTextMutedVariants: StyleColorVariantsMap<string> = {
gray: 'text-gray-500',
blue: 'text-gray-50',
emerald: 'text-gray-50',
pink: 'text-gray-50',
purple: 'text-gray-50',
red: 'text-gray-50',
sky: 'text-gray-50',
yellow: 'text-gray-50',
"dark-coral": "text-gray-500",
};
const buttonGlowVariants: StyleColorVariantsMap<string> = {
gray: 'shadow-gray-300/50',
blue: 'shadow-blue-500/50',
emerald: 'shadow-blue-700/50',
pink: 'shadow-blue-300/50',
purple: 'shadow-blue-300/50',
red: 'shadow-blue-300/50',
sky: 'shadow-blue-300/50',
yellow: 'shadow-blue-300/50',
"dark-coral": "shadow-dark-coral-300/50",
};
const buttonHoverGlowVariants: StyleColorVariantsMap<string> = {
gray: 'hover:shadow-gray-300/50',
blue: 'hover:shadow-blue-400/50',
emerald: 'hover:shadow-blue-300/50',
pink: 'hover:shadow-blue-300/50',
purple: 'hover:shadow-blue-300/50',
red: 'hover:shadow-blue-300/50',
sky: 'hover:shadow-blue-300/50',
yellow: 'hover:shadow-blue-300/50',
"dark-coral": "hover:shadow-dark-coral-300/50",
};
const isURL = (str: string) =>
/^(?:\w+:)?\/\/([^\s.]+\.\S{2}|localhost[:?\d]*)\S*$/.test(str);
const isInternalURL = (str: string) => /^\/(\S*\/)*\S*\/?$/.test(str);
/**
* Common button component
* @param {string|undefined} href New location link
* @param {boolean} iconed Flag to process component with icon. Default: `false`
* @param {StyleGlobalVariants|undefined} variant Button variant.
* Default: `base`
* @param {StyleType} type Button type.
* Default: `fill`
* @param {boolean|undefined} glowing Enables glowing shadow around
* button element. Default `false`
* @param {boolean|undefined} disabled Shows button element as
* disabled item
* @return {JSX.Element}
*/
const Button = ({
href,
iconed,
variant = 'gray',
type = 'fill',
glowing = false,
disabled,
onClick: onPress,
children,
className,
rel,
htmlType,
}: Props) =>{
const isExternal = isURL(href ?? '');
const isInternal = isInternalURL(href ?? '');
const As = isExternal || isInternal ? 'a' : 'button';
return (
<As
rel={rel}
href={href}
type={htmlType}
onClick={!disabled ? onPress : undefined}
className={classNames([
'text-center',
'rounded-lg font-semibold',
'transition-[box-shadow,background-color,color,border-color]',
'border',
{
'px-2 py-2': iconed === "only",
'py-3 pl-2 pr-5': iconed && iconed !== "only",
'py-3 px-8': !iconed,
'!cursor-default': disabled,
},
{
'shadow-lg': !disabled && glowing && type !== 'text',
'hover:shadow-lg': !disabled && glowing,
// Text variants
[`${buttonTextVariants[variant]}`]: !disabled,
[`${buttonTextHoverVariants[variant]}`]: !disabled && type === "outline",
// Background variants
[`${buttonBgVariants[variant]}`]: !disabled && type === 'fill',
[`${buttonHoverBgVariants[variant]}`]: !disabled,
// Glowing variants
[`${buttonGlowVariants[variant]}`]:
!disabled && glowing === true && type !== 'text',
[`${buttonHoverGlowVariants[variant]}`]: glowing,
// Disabled variants
[`${buttonTextMutedVariants[variant]}`]: disabled,
[`${buttonBgDisabledVariants[variant]}`]: disabled && type === 'fill',
[`${buttonBgDisabledHoverVariants[variant]}`]: disabled,
// Border variants
[`${buttonBorderVariants[variant]}`]: type !== 'text',
'!border-transparent': disabled || type === 'text',
},
buttonBorderHoverVariants[variant],
className,
])}
>
{children}
</As>
);
};
export default Button;

View File

@ -1,6 +1,5 @@
import { Combobox } from "@headlessui/react";
import { useState } from "react";
import { ReactComponent as SVGDropdownIcon } from "assets/svg/dropdown.svg";
import classNames from "classnames";
type OptionPropsArg = {
@ -50,10 +49,6 @@ export default function Combox<T = any>({
/>
<Combobox.Button className="absolute inset-y-0 right-0 p-2.5 flex items-center w-10 hover:bg-blue-500
border-l-2 border-blue-900/50 transition-colors">
<SVGDropdownIcon
className="w-full h-full fill-white"
aria-hidden="true"
/>
</Combobox.Button>
</div>
<Combobox.Options
@ -77,7 +72,7 @@ export default function Combox<T = any>({
}
value={valueMaper ? valueMaper(option) : option}
>
{(stats) => itemBuilder(stats, option)}
</Combobox.Option>
))
)}

View File

@ -11,11 +11,9 @@ import { useTranslation } from "react-i18next";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import Button from "components/controls/Button";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGBackIcon } from "assets/svg/backstab.svg";
/* -------------------------------------------------------------------------- */
/* Component */
/* -------------------------------------------------------------------------- */
@ -36,20 +34,6 @@ export default function GlobalControls() {
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Button
type="fill"
variant="blue"
onClick={() => navigate(-1)}
className="font-bold"
iconed
>
<div className="flex items-center space-x-3">
<div className="flex-none w-6 h-6">
<SVGBackIcon className="w-full h-full stroke-current opacity-60"/>
</div>
<div className="flex-1">{t('back')}</div>
</div>
</Button>
</Transition>
</>
);

View File

@ -8,17 +8,11 @@ import { useNavigate } from "react-router-dom";
/* -------------------------------------------------------------------------- */
import ContextMenu from "components/containers/contextmenu/ContextMenu";
import Logotype from "components/Logotype";
import Button from "components/controls/Button";
import Avatar from "components/containers/Avatar";
import ContextMenuAction from "components/containers/contextmenu/ContextMenuAction";
/* -------------------------------------------------------------------------- */
/* SVG */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGSearchIcon } from "assets/svg/search.svg";
import { ReactComponent as SVGBellIcon } from "assets/svg/bell.svg";
import { ReactComponent as SVGCogIcon } from "assets/svg/cog.svg";
import { ReactComponent as SVGUserAddIcon } from "assets/svg/user-add.svg";
import { ReactComponent as SVGExitIcon } from "assets/svg/exit.svg";
/* -------------------------------------------------------------------------- */
/* Hooks */
/* -------------------------------------------------------------------------- */
@ -66,12 +60,7 @@ export default function Header({title}: Props) {
<Logotype name={title} />
</div>
<div className="flex-none flex items-center space-x-3">
<Button iconed="only" className="w-10 h-10" variant="blue" type="text" onClick={showSearchbar}>
<SVGSearchIcon className="w-full h-full stroke-current" />
</Button>
<Button iconed="only" className="w-10 h-10" variant="blue" type="text">
<SVGBellIcon className="w-full h-full stroke-current" />
</Button>
<ContextMenu
button={<Avatar className="p-2" />}
className="absolute w-full min-h-14 sm:w-80 -bottom-3
@ -100,9 +89,7 @@ export default function Header({title}: Props) {
disabled={isLoading}
className="group w-full py-2 -mx-4 px-4 hover:bg-gray-200/20 rounded-md hover:text-blue-400 transition-colors"
caption="Account settings"
icon={
<SVGCogIcon className="w-6 h-6 stroke-gray-200/30 group-hover:stroke-current" />
}
/>
<ContextMenuAction
action={() => {
@ -111,17 +98,13 @@ export default function Header({title}: Props) {
disabled={isLoading}
className="group w-full py-2 -mx-4 px-4 hover:bg-gray-200/20 rounded-md hover:text-blue-400 transition-colors"
caption={t("account.connect")}
icon={
<SVGUserAddIcon className="w-6 h-6 stroke-gray-200/30 group-hover:stroke-current" />
}
/>
<ContextMenuAction
action={signOut}
className="group w-full py-2 -mx-4 px-4 hover:bg-gray-200/20 rounded-md transition-colors"
caption={t('logOut')}
icon={
<SVGExitIcon className="w-6 h-6 stroke-gray-200/30 group-hover:stroke-current" />
}
/>
</ContextMenu>
</div>

View File

@ -48,7 +48,6 @@ export default function LanguageSelector({ isShown, onClose }: Props) {
return (
<Modal isOpen={isShown} onClose={onClose} className="max-w-lg">
<Modal.CloseButton onClose={onClose} />
<Modal.Header>{t("selectLanguage")}</Modal.Header>
<Combox
options={Object.keys(languages)}

View File

@ -1,7 +1,6 @@
/* -------------------------------------------------------------------------- */
/* Libraries */
/* -------------------------------------------------------------------------- */
import Button from "components/controls/Button";
import StandalonePage from "components/StandalonePage";
import React from "react";
@ -14,13 +13,6 @@ export default function AuthFailure() {
<div className="flex flex-col items-center justify-center h-full space-y-4">
<div className="text-3xl font-bold text-gray-200">You have to be authorized</div>
<div className="text-2xl text-gray-400">to access techpal dashboard</div>
<Button
variant="red"
type="fill"
href={process.env.REACT_APP_OPENID_PROVIDER_URL}
>
Войти
</Button>
</div>
</StandalonePage>
);

View File

@ -15,7 +15,6 @@ import AvailabilityIndicator from "components/indicators/AvailabilityIndicator";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGArrowRightShortIcon } from "assets/svg/arrow-right-short.svg";
/* -------------------------------------------------------------------------- */
/* Dashboard page */
/* -------------------------------------------------------------------------- */
@ -25,7 +24,7 @@ import { useServicesViewModel } from "services/controller/servicesViewModel";
import CircleLoader from "components/CircleLoader";
import _ from "lodash";
import { useUIStore } from "ui/data/uiSlice";
import Button from "components/controls/Button";
import { useNavigate } from "react-router-dom";
import { useSubscriptionsStore } from "subscriptions/data/subscriptionsSlice";
import { useSubscriptionsViewModel } from "subscriptions/controller/subscriptionsViewModel";
@ -64,13 +63,7 @@ export default function Dashboard() {
</HexagonOutlined>
</div>
<div className="flex-grow">
<Button
variant="emerald"
type="outline"
onClick={() => navigate("/services")}
>
Connect service
</Button>
</div>
</div>
<div className="pl-20 opacity-40">
@ -84,7 +77,7 @@ export default function Dashboard() {
className="font-semibold inline-flex items-center space-x-2 hover:space-x-3"
>
<span className="transition-all">connect</span>
<SVGArrowRightShortIcon className="w-3 h-3 fill-white transition-all" />
</TextAction>
</div>
</Card>
@ -128,7 +121,6 @@ export default function Dashboard() {
<div className="text-right">
<TextAction className="font-semibold inline-flex items-center space-x-2 hover:space-x-3">
<span className="transition-all">open</span>
<SVGArrowRightShortIcon className="w-3 h-3 fill-white transition-all" />
</TextAction>
</div>
</Card>
@ -175,7 +167,6 @@ export default function Dashboard() {
className="font-semibold inline-flex items-center space-x-2 hover:space-x-3"
>
<span className="transition-all">open</span>
<SVGArrowRightShortIcon className="w-3 h-3 fill-white transition-all" />
</TextAction>
</div>
</Card>

View File

@ -9,7 +9,6 @@ import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
/* -------------------------------------------------------------------------- */
/* Components */
import Button from "components/controls/Button";
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* Misc */
@ -17,7 +16,6 @@ import Button from "components/controls/Button";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGBackIcon } from "assets/svg/backstab.svg";
/* -------------------------------------------------------------------------- */
/* Account information management page */
/* -------------------------------------------------------------------------- */
@ -33,23 +31,7 @@ const NoMatch = (): JSX.Element => {
<div className="font-bold text-6xl text-gray-500">404</div>
<div className="font-bold text-3xl mb-10">Page Not Found</div>
<div className="font-thin text-xl mb-10">{t('serv.noSuchPath')}</div>
<Button
iconed={true}
htmlType="button"
variant="blue"
onClick={() =>
navigate("/", {
replace: true,
})
}
>
<div className="flex items-center space-x-3">
<div className="flex-none w-6 h-6">
<SVGBackIcon className="w-full h-full stroke-current opacity-60" />
</div>
<div className="flex-1">{t("serv.goHome")}</div>
</div>
</Button>
</div>
);
};

View File

@ -6,12 +6,9 @@ import Modal from "components/containers/modal/Modal";
/* -------------------------------------------------------------------------- */
/* Icons/SVG */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGSearchIcon } from "assets/svg/search.svg";
import { ReactComponent as SVGTimesIcon } from "assets/svg/times.svg";
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
import Button from "components/controls/Button";
/* -------------------------------------------------------------------------- */
/* Hooks */
/* -------------------------------------------------------------------------- */
@ -36,28 +33,7 @@ export default function GlobalSearchbar() {
<Combobox value="" onChange={() => {}}>
<div className="flex space-x-2 -mt-3 -mx-5 items-center">
<div className="flex-none basis-5">
<SVGSearchIcon className="w-full h-full stroke-current" />
</div>
<div className="flex-grow">
<Combobox.Input
onChange={(event) => {}}
placeholder={t('search.label')}
className="bg-transparent
focus:outline-none
px-4 py-2 w-full"
/>
</div>
<div className="flex-none">
<Button
htmlType="button"
iconed="only"
className="w-10 h-10"
variant="blue"
type="text"
onClick={hideSearchbar}
>
<SVGTimesIcon className="w-full h-full stroke-current" />
</Button>
</div>
</div>
<Combobox.Options>

View File

@ -12,12 +12,10 @@ import { useEmailDataViewModel } from "../controller/emailDataViewModel";
/* Components */
/* -------------------------------------------------------------------------- */
import Modal from "components/containers/modal/Modal";
import Button from "components/controls/Button";
import InputField from "components/controls/InputField";
/* -------------------------------------------------------------------------- */
/* Icons */
/* -------------------------------------------------------------------------- */
import { ReactComponent as SVGCircleProgressIcon } from "assets/svg/circle-progress.svg";
import { useTranslation } from "react-i18next";
/* -------------------------------------------------------------------------- */
/* Component */
@ -60,7 +58,6 @@ export default function EmailEditor({ isShown, onClose: extOnClose }: Props) {
return (
<Modal isOpen={isShown} onClose={onClose} className="max-w-lg">
<form onSubmit={onSubmitHandler}>
<Modal.CloseButton onClose={onClose} />
<Modal.Header>{t("account.mail")}</Modal.Header>
<InputField
name="email"
@ -71,27 +68,7 @@ export default function EmailEditor({ isShown, onClose: extOnClose }: Props) {
autoComplete="off"
/>
<Modal.Footer className="flex justify-between">
<Button type="text" variant="red" onClick={onClose}>
{t("cancel")}
</Button>
<Button
disabled={!isValid || isSubmiting}
htmlType="submit"
type="fill"
variant="blue"
glowing={true}
className="relative"
>
<span className={classNames({ "opacity-0": isSubmiting })}>
{t("save")}
</span>
<SVGCircleProgressIcon
className={classNames(
"absolute top-1/2 left-1/2 trasnform -translate-x-1/2 -translate-y-1/2 w-8 h-8 stroke-current",
{ "opacity-0": !isSubmiting }
)}
/>
</Button>
</Modal.Footer>
</form>
</Modal>

View File

@ -3,7 +3,6 @@ import Modal from "components/containers/modal/Modal";
import { Formik } from "formik";
import { useTranslation } from "react-i18next";
import InputField from "components/controls/InputField";
import Button from "components/controls/Button";
type Props = {
isShown: boolean;
@ -28,7 +27,6 @@ export default function PasswordConfirmation({
return (
<Modal isOpen={isShown} onClose={onClose} className="max-w-lg">
<Modal.CloseButton onClose={onClose} />
<Modal.Header>{t("dialogues.confirmAction.title")}</Modal.Header>
<Formik
initialValues={{
@ -59,7 +57,6 @@ export default function PasswordConfirmation({
{t("dialogues.confirmAction.description")}
</div>
<Modal.Footer className="text-center">
<Button type="outline" htmlType="submit" variant="red">{t('dialogues.confirmAction.confirm')}</Button>
</Modal.Footer>
</form>
)}

View File

@ -1,10 +1,8 @@
import React from "react";
import Modal from "components/containers/modal/Modal";
import Button from "components/controls/Button";
import InputField from "components/controls/InputField";
import { useUserStore } from "../data/userSlice";
import { ReactComponent as SVGCircleProgressIcon } from "assets/svg/circle-progress.svg";
import classNames from "classnames";
import { useTranslation } from "react-i18next";
import { Formik } from "formik";
@ -38,7 +36,6 @@ export default function PersonalInfomrationEditor({
return (
<Modal isOpen={isShown} onClose={onClose} className="max-w-lg">
<Modal.CloseButton onClose={onClose} />
<Modal.Header>{t("account.info")}</Modal.Header>
<Formik
initialValues={{
@ -97,31 +94,7 @@ export default function PersonalInfomrationEditor({
touched={formik.touched.lastname}
/>
<Modal.Footer className="flex justify-between">
<Button type="text" variant="red" onClick={onClose}>
{t("cancel")}
</Button>
<Button
disabled={
!formik.isValid || formik.isSubmitting || !formik.touched
}
htmlType="submit"
type="fill"
variant="blue"
glowing={true}
className="relative"
>
<span
className={classNames({ "opacity-0": formik.isSubmitting })}
>
{t("save")}
</span>
<SVGCircleProgressIcon
className={classNames(
"absolute top-1/2 left-1/2 trasnform -translate-x-1/2 -translate-y-1/2 w-8 h-8 stroke-current",
{ "opacity-0": !formik.isSubmitting }
)}
/>
</Button>
</Modal.Footer>
</form>
)}