refactor: replace ui components with plane ui components (#2626)

* refactor: replace button component with plane ui component and remove old button component

* refactor: replace dropdown component with plane ui component

* refactor: replace tooltip, input, textarea, spinner and loader component with plane ui component

* refactor: plane ui code refactor
This commit is contained in:
Anmol Singh Bhatia 2023-11-03 17:21:38 +05:30 committed by GitHub
parent 737fea28c6
commit f639e467f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 85 additions and 178 deletions

View File

@ -6,7 +6,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// components // components
import { CyclesBoard, CyclesList, CyclesListGanttChartView } from "components/cycles"; import { CyclesBoard, CyclesList, CyclesListGanttChartView } from "components/cycles";
// ui components // ui components
import { Loader } from "components/ui"; import { Loader } from "@plane/ui";
// types // types
import { TCycleLayout } from "types"; import { TCycleLayout } from "types";

View File

@ -3,7 +3,7 @@ import { Dialog, Transition } from "@headlessui/react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { AlertTriangle } from "lucide-react"; import { AlertTriangle } from "lucide-react";
// components // components
import { DangerButton, SecondaryButton } from "components/ui"; import { Button } from "@plane/ui";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// types // types
@ -101,10 +101,13 @@ export const CycleDeleteModal: React.FC<ICycleDelete> = observer((props) => {
</p> </p>
</span> </span>
<div className="flex justify-end gap-2"> <div className="flex justify-end gap-2">
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton> <Button variant="neutral-primary" size="sm" onClick={handleClose}>
<DangerButton onClick={formSubmit} loading={loader}> Cancel
</Button>
<Button variant="danger" size="sm" onClick={formSubmit}>
{loader ? "Deleting..." : "Delete Cycle"} {loader ? "Deleting..." : "Delete Cycle"}
</DangerButton> </Button>
</div> </div>
</div> </div>
</Dialog.Panel> </Dialog.Panel>

View File

@ -3,7 +3,7 @@ import { usePopper } from "react-popper";
import { Combobox } from "@headlessui/react"; import { Combobox } from "@headlessui/react";
import { Check, ChevronDown, Search, Triangle } from "lucide-react"; import { Check, ChevronDown, Search, Triangle } from "lucide-react";
// types // types
import { Tooltip } from "components/ui"; import { Tooltip } from "@plane/ui";
import { Placement } from "@popperjs/core"; import { Placement } from "@popperjs/core";
// constants // constants
import { IEstimatePoint } from "types"; import { IEstimatePoint } from "types";

View File

@ -8,9 +8,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// components // components
import { CreateUpdateProjectViewModal } from "components/views"; import { CreateUpdateProjectViewModal } from "components/views";
// components // components
import { Breadcrumbs, BreadcrumbItem } from "@plane/ui"; import { Breadcrumbs, BreadcrumbItem, Button } from "@plane/ui";
// ui
import { PrimaryButton } from "components/ui";
// helpers // helpers
import { truncateText } from "helpers/string.helper"; import { truncateText } from "helpers/string.helper";
@ -59,10 +57,14 @@ export const ProjectViewsHeader: React.FC = observer(() => {
</div> </div>
<div className="flex items-center gap-2 flex-shrink-0"> <div className="flex items-center gap-2 flex-shrink-0">
<div> <div>
<PrimaryButton type="button" className="flex items-center gap-2" onClick={() => setCreateViewModal(true)}> <Button
<Plus size={14} strokeWidth={2} /> variant="primary"
size="sm"
prependIcon={<Plus className="h-3.5 w-3.5 stroke-2" />}
onClick={() => setCreateViewModal(true)}
>
Create View Create View
</PrimaryButton> </Button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -7,7 +7,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// components // components
import { AppliedFiltersList } from "components/issues"; import { AppliedFiltersList } from "components/issues";
// ui // ui
import { PrimaryButton } from "components/ui"; import { Button } from "@plane/ui";
// helpers // helpers
import { areFiltersDifferent } from "helpers/filter.helper"; import { areFiltersDifferent } from "helpers/filter.helper";
// types // types
@ -102,9 +102,9 @@ export const ProjectViewAppliedFiltersRoot: React.FC = observer(() => {
states={projectStore.states?.[projectId?.toString() ?? ""]} states={projectStore.states?.[projectId?.toString() ?? ""]}
/> />
{storedFilters && viewDetails && areFiltersDifferent(storedFilters, viewDetails.query_data ?? {}) && ( {storedFilters && viewDetails && areFiltersDifferent(storedFilters, viewDetails.query_data ?? {}) && (
<PrimaryButton className="whitespace-nowrap" onClick={handleUpdateView}> <Button variant="primary" size="sm" onClick={handleUpdateView}>
Update view Update view
</PrimaryButton> </Button>
)} )}
</div> </div>
); );

View File

@ -4,7 +4,7 @@ import { Placement } from "@popperjs/core";
import { Combobox } from "@headlessui/react"; import { Combobox } from "@headlessui/react";
import { Check, ChevronDown, Search } from "lucide-react"; import { Check, ChevronDown, Search } from "lucide-react";
// ui // ui
import { Tooltip } from "components/ui"; import { Tooltip } from "@plane/ui";
// types // types
import { IIssueLabels } from "types"; import { IIssueLabels } from "types";

View File

@ -6,7 +6,7 @@ import { Disclosure, Transition } from "@headlessui/react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
// ui // ui
import { CustomMenu } from "components/ui"; import { CustomMenu } from "@plane/ui";
// icons // icons
import { ChevronDown, Component, Pencil, Plus, Trash2, X } from "lucide-react"; import { ChevronDown, Component, Pencil, Plus, Trash2, X } from "lucide-react";
// types // types

View File

@ -3,7 +3,7 @@ import React, { useRef, useState } from "react";
//hook //hook
import useOutsideClickDetector from "hooks/use-outside-click-detector"; import useOutsideClickDetector from "hooks/use-outside-click-detector";
// ui // ui
import { CustomMenu } from "components/ui"; import { CustomMenu } from "@plane/ui";
// types // types
import { IIssueLabels } from "types"; import { IIssueLabels } from "types";
//icons //icons

View File

@ -3,10 +3,8 @@ import { usePopper } from "react-popper";
import { Placement } from "@popperjs/core"; import { Placement } from "@popperjs/core";
import { Combobox } from "@headlessui/react"; import { Combobox } from "@headlessui/react";
import { Check, ChevronDown, Search, User2 } from "lucide-react"; import { Check, ChevronDown, Search, User2 } from "lucide-react";
// components
import { Tooltip } from "components/ui";
// ui // ui
import { Avatar, AvatarGroup } from "@plane/ui"; import { Avatar, AvatarGroup, Tooltip } from "@plane/ui";
// types // types
import { IUserLite } from "types"; import { IUserLite } from "types";

View File

@ -3,9 +3,7 @@ import { usePopper } from "react-popper";
import { Placement } from "@popperjs/core"; import { Placement } from "@popperjs/core";
import { Combobox } from "@headlessui/react"; import { Combobox } from "@headlessui/react";
import { Check, ChevronDown, Search } from "lucide-react"; import { Check, ChevronDown, Search } from "lucide-react";
import { PriorityIcon } from "@plane/ui"; import { PriorityIcon, Tooltip } from "@plane/ui";
// components
import { Tooltip } from "components/ui";
// helpers // helpers
import { capitalizeFirstLetter } from "helpers/string.helper"; import { capitalizeFirstLetter } from "helpers/string.helper";
// types // types

View File

@ -10,8 +10,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// ui // ui
import { CustomSelect } from "components/ui"; import { Button, CustomSelect, Input, TextArea } from "@plane/ui";
import { Button, Input, TextArea } from "@plane/ui";
// icons // icons
import { ChevronDown } from "lucide-react"; import { ChevronDown } from "lucide-react";
// types // types

View File

@ -11,8 +11,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// ui // ui
import { CustomSelect } from "components/ui"; import { Button, CustomSelect, Input, Tooltip } from "@plane/ui";
import { Button, Input, Tooltip } from "@plane/ui";
// types // types
import type { IState } from "types"; import type { IState } from "types";
// fetch-keys // fetch-keys

View File

@ -4,8 +4,7 @@ import { Placement } from "@popperjs/core";
import { Combobox } from "@headlessui/react"; import { Combobox } from "@headlessui/react";
import { Check, ChevronDown, Search } from "lucide-react"; import { Check, ChevronDown, Search } from "lucide-react";
// ui // ui
import { StateGroupIcon } from "@plane/ui"; import { StateGroupIcon, Tooltip } from "@plane/ui";
import { Tooltip } from "components/ui";
// types // types
import { IState } from "types"; import { IState } from "types";

View File

@ -1,36 +0,0 @@
// types
import { ButtonProps } from "./type";
export const DangerButton: React.FC<ButtonProps> = ({
children,
className = "",
onClick,
type = "button",
disabled = false,
loading = false,
size = "sm",
outline = false,
}) => (
<button
type={type}
className={`${className} border border-red-500 font-medium duration-300 ${
size === "sm"
? "rounded px-3 py-2 text-xs"
: size === "md"
? "rounded-md px-3.5 py-2 text-sm"
: "rounded-lg px-4 py-2 text-base"
} ${
disabled
? "cursor-not-allowed bg-opacity-70 border-opacity-70 hover:bg-opacity-70 hover:border-opacity-70"
: ""
} ${
outline
? "bg-transparent text-red-500 hover:bg-red-500 hover:text-white"
: "text-white bg-red-500 hover:border-opacity-90 hover:bg-opacity-90"
} ${loading ? "cursor-wait" : ""}`}
onClick={onClick}
disabled={disabled || loading}
>
{children}
</button>
);

View File

@ -1,3 +0,0 @@
export * from "./danger-button";
export * from "./primary-button";
export * from "./secondary-button";

View File

@ -1,32 +0,0 @@
// types
import { ButtonProps } from "./type";
export const PrimaryButton: React.FC<ButtonProps> = ({
children,
className = "",
onClick,
type = "button",
disabled = false,
loading = false,
size = "sm",
outline = false,
}) => (
<button
type={type}
className={`${className} border border-custom-primary font-medium duration-300 ${
size === "sm"
? "rounded px-3 py-2 text-xs"
: size === "md"
? "rounded-md px-3.5 py-2 text-sm"
: "rounded-lg px-4 py-2 text-base"
} ${disabled ? "cursor-not-allowed opacity-70 hover:opacity-70" : ""} ${
outline
? "bg-transparent text-custom-primary hover:bg-custom-primary hover:text-white"
: "text-white bg-custom-primary hover:border-opacity-90 hover:bg-opacity-90"
} ${loading ? "cursor-wait" : ""}`}
onClick={onClick}
disabled={disabled || loading}
>
{children}
</button>
);

View File

@ -1,32 +0,0 @@
// types
import { ButtonProps } from "./type";
export const SecondaryButton: React.FC<ButtonProps> = ({
children,
className = "",
onClick,
type = "button",
disabled = false,
loading = false,
size = "sm",
outline = false,
}) => (
<button
type={type}
className={`${className} border border-custom-border-200 font-medium duration-300 ${
size === "sm"
? "rounded px-3 py-2 text-xs"
: size === "md"
? "rounded-md px-3.5 py-2 text-sm"
: "rounded-lg px-4 py-2 text-base"
} ${disabled ? "cursor-not-allowed border-custom-border-200 bg-custom-background-90" : ""} ${
outline
? "bg-transparent hover:bg-custom-background-80"
: "bg-custom-background-100 hover:border-opacity-70 hover:bg-opacity-70"
} ${loading ? "cursor-wait" : ""}`}
onClick={onClick}
disabled={disabled || loading}
>
{children}
</button>
);

View File

@ -1,10 +0,0 @@
export type ButtonProps = {
children: React.ReactNode;
className?: string;
onClick?: (e: any) => void;
type?: "button" | "submit" | "reset";
disabled?: boolean;
loading?: boolean;
size?: "sm" | "md" | "lg";
outline?: boolean;
};

View File

@ -1,4 +1,3 @@
export * from "./buttons";
export * from "./dropdowns"; export * from "./dropdowns";
export * from "./graphs"; export * from "./graphs";
export * from "./input"; export * from "./input";

View File

@ -3,7 +3,7 @@ import { Fragment, useState } from "react";
// headless ui // headless ui
import { Menu, Transition } from "@headlessui/react"; import { Menu, Transition } from "@headlessui/react";
// ui // ui
import { Loader } from "components/ui"; import { Loader } from "@plane/ui";
// icons // icons
import { Check, ChevronDown, ChevronLeft, ChevronRight } from "lucide-react"; import { Check, ChevronDown, ChevronLeft, ChevronRight } from "lucide-react";

View File

@ -7,7 +7,8 @@ import { Dialog, Transition } from "@headlessui/react";
// services // services
import { WorkspaceService } from "services/workspace.service"; import { WorkspaceService } from "services/workspace.service";
// components // components
import { Loader, MarkdownRenderer } from "components/ui"; import { MarkdownRenderer } from "components/ui";
import { Loader } from "@plane/ui";
// icons // icons
import { X } from "lucide-react"; import { X } from "lucide-react";
// helpers // helpers

View File

@ -8,7 +8,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// ui // ui
import { DangerButton, SecondaryButton } from "components/ui"; import { Button } from "@plane/ui";
// icons // icons
import { AlertTriangle } from "lucide-react"; import { AlertTriangle } from "lucide-react";
// types // types
@ -112,10 +112,12 @@ export const DeleteProjectViewModal: React.FC<Props> = observer((props) => {
</div> </div>
</div> </div>
<div className="flex justify-end gap-2 p-4 sm:px-6"> <div className="flex justify-end gap-2 p-4 sm:px-6">
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton> <Button variant="neutral-primary" size="sm" onClick={handleClose}>
<DangerButton onClick={handleDeleteView} loading={isDeleteLoading}> Cancel
</Button>
<Button variant="danger" size="sm" onClick={handleDeleteView}>
{isDeleteLoading ? "Deleting..." : "Delete"} {isDeleteLoading ? "Deleting..." : "Delete"}
</DangerButton> </Button>
</div> </div>
</Dialog.Panel> </Dialog.Panel>
</Transition.Child> </Transition.Child>

View File

@ -7,7 +7,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// components // components
import { AppliedFiltersList, FilterSelection, FiltersDropdown } from "components/issues"; import { AppliedFiltersList, FilterSelection, FiltersDropdown } from "components/issues";
// ui // ui
import { Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui"; import { Button, Input, TextArea } from "@plane/ui";
// types // types
import { IProjectView } from "types"; import { IProjectView } from "types";
// constants // constants
@ -32,7 +32,6 @@ export const ProjectViewForm: React.FC<Props> = observer(({ handleFormSubmit, ha
control, control,
formState: { errors, isSubmitting }, formState: { errors, isSubmitting },
handleSubmit, handleSubmit,
register,
reset, reset,
setValue, setValue,
watch, watch,
@ -70,32 +69,45 @@ export const ProjectViewForm: React.FC<Props> = observer(({ handleFormSubmit, ha
<h3 className="text-lg font-medium leading-6 text-custom-text-100">{data ? "Update" : "Create"} View</h3> <h3 className="text-lg font-medium leading-6 text-custom-text-100">{data ? "Update" : "Create"} View</h3>
<div className="space-y-3"> <div className="space-y-3">
<div> <div>
<Input <Controller
id="name" control={control}
name="name" name="name"
type="name" rules={{
placeholder="Title"
autoComplete="off"
className="resize-none text-xl"
error={errors.name}
register={register}
validations={{
required: "Title is required", required: "Title is required",
maxLength: { maxLength: {
value: 255, value: 255,
message: "Title should be less than 255 characters", message: "Title should be less than 255 characters",
}, },
}} }}
render={({ field: { value, onChange } }) => (
<Input
id="name"
type="name"
name="name"
value={value}
onChange={onChange}
hasError={Boolean(errors.name)}
placeholder="Title"
className="resize-none text-xl"
/>
)}
/> />
</div> </div>
<div> <div>
<TextArea <Controller
id="description"
name="description" name="description"
placeholder="Description" control={control}
className="h-32 resize-none text-sm" render={({ field: { value, onChange } }) => (
error={errors.description} <TextArea
register={register} id="description"
name="description"
placeholder="Description"
className="resize-none text-sm"
hasError={Boolean(errors?.description)}
value={value}
onChange={onChange}
/>
)}
/> />
</div> </div>
<div> <div>
@ -147,8 +159,10 @@ export const ProjectViewForm: React.FC<Props> = observer(({ handleFormSubmit, ha
</div> </div>
</div> </div>
<div className="mt-5 flex justify-end gap-2"> <div className="mt-5 flex justify-end gap-2">
<SecondaryButton onClick={handleClose}>Cancel</SecondaryButton> <Button variant="neutral-primary" size="sm" onClick={handleClose}>
<PrimaryButton type="submit" loading={isSubmitting}> Cancel
</Button>
<Button variant="primary" size="sm" type="submit">
{data {data
? isSubmitting ? isSubmitting
? "Updating View..." ? "Updating View..."
@ -156,7 +170,7 @@ export const ProjectViewForm: React.FC<Props> = observer(({ handleFormSubmit, ha
: isSubmitting : isSubmitting
? "Creating View..." ? "Creating View..."
: "Create View"} : "Create View"}
</PrimaryButton> </Button>
</div> </div>
</form> </form>
); );

View File

@ -8,7 +8,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
import { ProjectViewListItem } from "components/views"; import { ProjectViewListItem } from "components/views";
import { EmptyState } from "components/common"; import { EmptyState } from "components/common";
// ui // ui
import { Input, Loader } from "components/ui"; import { Input, Loader } from "@plane/ui";
// assets // assets
import emptyView from "public/empty-state/view.svg"; import emptyView from "public/empty-state/view.svg";
// icons // icons
@ -48,7 +48,7 @@ export const ProjectViewsList = observer(() => {
value={query} value={query}
onChange={(e) => setQuery(e.target.value)} onChange={(e) => setQuery(e.target.value)}
placeholder="Search" placeholder="Search"
mode="trueTransparent" mode="true-transparent"
/> />
</div> </div>
</div> </div>

View File

@ -9,7 +9,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
import { TourRoot } from "components/onboarding"; import { TourRoot } from "components/onboarding";
import { UserGreetingsView } from "components/user"; import { UserGreetingsView } from "components/user";
import { CompletedIssuesGraph, IssuesList, IssuesPieChart, IssuesStats } from "components/workspace"; import { CompletedIssuesGraph, IssuesList, IssuesPieChart, IssuesStats } from "components/workspace";
import { PrimaryButton } from "components/ui"; import { Button } from "@plane/ui";
// images // images
import emptyDashboard from "public/empty-state/dashboard.svg"; import emptyDashboard from "public/empty-state/dashboard.svg";
@ -67,7 +67,9 @@ export const WorkspaceDashboardView = observer(() => {
<div className="p-5 md:p-8 pr-0"> <div className="p-5 md:p-8 pr-0">
<h5 className="text-xl font-semibold">Create a project</h5> <h5 className="text-xl font-semibold">Create a project</h5>
<p className="mt-2 mb-5">Manage your projects by creating issues, cycles, modules, views and pages.</p> <p className="mt-2 mb-5">Manage your projects by creating issues, cycles, modules, views and pages.</p>
<PrimaryButton <Button
variant="primary"
size="sm"
onClick={() => { onClick={() => {
const e = new KeyboardEvent("keydown", { const e = new KeyboardEvent("keydown", {
key: "p", key: "p",
@ -76,7 +78,7 @@ export const WorkspaceDashboardView = observer(() => {
}} }}
> >
Create Project Create Project
</PrimaryButton> </Button>
</div> </div>
<div className="hidden md:block self-end overflow-hidden pt-8"> <div className="hidden md:block self-end overflow-hidden pt-8">
<Image src={emptyDashboard} alt="Empty Dashboard" /> <Image src={emptyDashboard} alt="Empty Dashboard" />

View File

@ -4,7 +4,7 @@ import Link from "next/link";
import useSWR from "swr"; import useSWR from "swr";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// icons // icons
import { Spinner, PrimaryButton, SecondaryButton } from "components/ui"; import { Button, Spinner } from "@plane/ui";
// hooks // hooks
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
@ -67,12 +67,16 @@ export const WorkspaceAuthWrapper: FC<IWorkspaceAuthWrapper> = observer((props)
<div className="flex items-center justify-center gap-2"> <div className="flex items-center justify-center gap-2">
<Link href="/invitations"> <Link href="/invitations">
<a> <a>
<SecondaryButton>Check pending invites</SecondaryButton> <Button variant="neutral-primary" size="sm">
Check pending invites
</Button>
</a> </a>
</Link> </Link>
<Link href="/create-workspace"> <Link href="/create-workspace">
<a> <a>
<PrimaryButton>Create new workspace</PrimaryButton> <Button variant="primary" size="sm">
Create new workspace
</Button>
</a> </a>
</Link> </Link>
</div> </div>