mirror of
https://github.com/makeplane/plane.git
synced 2026-02-24 12:11:39 +01:00
chore: update component styles and class names for consistency across the application
This commit is contained in:
@@ -52,11 +52,11 @@ const CreateWorkspacePage = observer(function CreateWorkspacePage() {
|
||||
|
||||
return (
|
||||
<AuthenticationWrapper>
|
||||
<div className="flex h-full flex-col gap-y-2 overflow-hidden sm:flex-row sm:gap-y-0">
|
||||
<div className="flex h-full flex-col gap-y-2 overflow-hidden sm:flex-row sm:gap-y-0 bg-surface-1">
|
||||
<div className="relative h-1/6 flex-shrink-0 sm:w-2/12 md:w-3/12 lg:w-1/5">
|
||||
<div className="absolute left-0 top-1/2 h-[0.5px] w-full -translate-y-1/2 border-b-[0.5px] border-subtle sm:left-1/2 sm:top-0 sm:h-screen sm:w-[0.5px] sm:-translate-x-1/2 sm:translate-y-0 sm:border-r-[0.5px] md:left-1/3" />
|
||||
<Link
|
||||
className="absolute left-5 top-1/2 grid -translate-y-1/2 place-items-center bg-surface-1 px-3 sm:left-1/2 sm:top-12 sm:-translate-x-[15px] sm:translate-y-0 sm:px-0 sm:py-5 md:left-1/3"
|
||||
className="absolute left-5 top-1/2 grid -translate-y-1/2 place-items-center px-3 sm:left-1/2 sm:top-12 sm:-translate-x-[15px] sm:translate-y-0 sm:px-0 sm:py-5 md:left-1/3"
|
||||
href="/"
|
||||
>
|
||||
<PlaneLogo className="h-9 w-auto text-primary" />
|
||||
|
||||
@@ -131,7 +131,7 @@ function UserInvitationsPage() {
|
||||
<div className="absolute left-0 top-1/2 h-[0.5px] w-full -translate-y-1/2 border-b-[0.5px] border-subtle sm:left-1/2 sm:top-0 sm:h-screen sm:w-[0.5px] sm:-translate-x-1/2 sm:translate-y-0 sm:border-r-[0.5px] md:left-1/3" />
|
||||
<Link
|
||||
href="/"
|
||||
className="absolute left-5 top-1/2 grid -translate-y-1/2 place-items-center bg-surface-1 px-3 sm:left-1/2 sm:top-12 sm:-translate-x-[15px] sm:translate-y-0 sm:px-0 sm:py-5 md:left-1/3 z-10"
|
||||
className="absolute left-5 top-1/2 grid -translate-y-1/2 place-items-center px-3 sm:left-1/2 sm:top-12 sm:-translate-x-[15px] sm:translate-y-0 sm:px-0 sm:py-5 md:left-1/3 z-10"
|
||||
>
|
||||
<PlaneLogo className="h-9 w-auto text-primary" />
|
||||
</Link>
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { EditorRefApi } from "@plane/editor";
|
||||
import { CloseIcon } from "@plane/propel/icons";
|
||||
// plane imports
|
||||
import type { TCommentsOperations, TIssueComment } from "@plane/types";
|
||||
import { isCommentEmpty } from "@plane/utils";
|
||||
import { cn, isCommentEmpty } from "@plane/utils";
|
||||
// components
|
||||
import { LiteTextEditor } from "@/components/editor/lite-text";
|
||||
|
||||
@@ -46,7 +46,7 @@ export const CommentCardEditForm = observer(function CommentCardEditForm(props:
|
||||
});
|
||||
const commentHTML = watch("comment_html");
|
||||
|
||||
const isEmpty = isCommentEmpty(commentHTML ?? undefined);
|
||||
const isEmpty = isCommentEmpty(commentHTML);
|
||||
const isEditorReadyToDiscard = editorRef.current?.isEditorReadyToDiscard();
|
||||
const isSubmitButtonDisabled = isSubmitting || !isEditorReadyToDiscard;
|
||||
const isDisabled = isSubmitting || isEmpty || isSubmitButtonDisabled;
|
||||
@@ -99,36 +99,53 @@ export const CommentCardEditForm = observer(function CommentCardEditForm(props:
|
||||
return asset_id;
|
||||
}}
|
||||
projectId={projectId}
|
||||
parentClassName="p-2"
|
||||
parentClassName="p-2 bg-surface-1"
|
||||
displayConfig={{
|
||||
fontSize: "small-font",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex gap-1 self-end">
|
||||
<div className="flex gap-2 self-end">
|
||||
{!isEmpty && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleSubmit(onEnter)}
|
||||
disabled={isDisabled}
|
||||
className={`group rounded-sm border border-green-500 bg-green-500/20 p-2 shadow-md duration-300 ${
|
||||
isEmpty ? "cursor-not-allowed bg-gray-200" : "hover:bg-green-500"
|
||||
}`}
|
||||
className={cn(
|
||||
"group rounded-lg border size-7 flex items-center justify-center shadow-md duration-300",
|
||||
isDisabled
|
||||
? "cursor-not-allowed border-green-500/50 bg-green-500/10"
|
||||
: "border-green-500 bg-green-500/20 hover:bg-green-500"
|
||||
)}
|
||||
>
|
||||
<Check
|
||||
className={`h-3 w-3 text-green-500 duration-300 ${isEmpty ? "text-black" : "group-hover:text-on-color"}`}
|
||||
className={cn(
|
||||
"size-4 duration-300",
|
||||
isDisabled ? "text-green-500/50" : "text-green-500 group-hover:text-on-color"
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className="group rounded-sm border border-red-500 bg-red-500/20 p-2 shadow-md duration-300 hover:bg-red-500"
|
||||
disabled={isSubmitting}
|
||||
className={cn(
|
||||
"group rounded-lg border size-7 flex items-center justify-center shadow-md duration-300",
|
||||
isSubmitting
|
||||
? "cursor-not-allowed border-red-500/50 bg-red-500/10"
|
||||
: "border-red-500 bg-red-500/20 hover:bg-red-500"
|
||||
)}
|
||||
onClick={() => {
|
||||
setIsEditing(false);
|
||||
editorRef.current?.setEditorValue(comment.comment_html ?? "<p></p>");
|
||||
}}
|
||||
>
|
||||
<CloseIcon className="size-3 text-red-500 duration-300 group-hover:text-on-color" />
|
||||
<CloseIcon
|
||||
className={cn(
|
||||
"size-5 duration-300",
|
||||
isSubmitting ? "text-red-500/50" : "text-red-500 group-hover:text-on-color"
|
||||
)}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -156,10 +156,10 @@ export const CycleSidebarHeader = observer(function CycleSidebarHeader(props: Pr
|
||||
<div className="sticky z-10 top-0 pt-2 flex items-center justify-between bg-surface-1">
|
||||
<div className="flex items-center justify-center size-5">
|
||||
<button
|
||||
className="flex size-4 items-center justify-center rounded-full bg-layer-3"
|
||||
className="flex size-6 items-center justify-center rounded-full bg-layer-3 hover:bg-layer-3-hover flex-shrink-0"
|
||||
onClick={() => handleClose()}
|
||||
>
|
||||
<ChevronRightIcon className="h-3 w-3 stroke-2 text-on-color" />
|
||||
<ChevronRightIcon className="size-4 stroke-2 text-secondary" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,7 +168,7 @@ export const CycleSidebarHeader = observer(function CycleSidebarHeader(props: Pr
|
||||
<h4 className="w-full break-words text-18 font-semibold text-primary">{cycleDetails.name}</h4>
|
||||
{currentCycle && (
|
||||
<span
|
||||
className="flex h-6 min-w-20 px-3 items-center justify-center rounded-sm text-center text-11 font-medium"
|
||||
className="flex h-6 min-w-20 px-3 items-center justify-center rounded-sm text-center text-11 font-medium whitespace-nowrap truncate"
|
||||
style={{
|
||||
color: currentCycle.color,
|
||||
backgroundColor: `${currentCycle.color}20`,
|
||||
|
||||
@@ -82,7 +82,7 @@ export const CyclesListItem = observer(function CyclesListItem(props: TCyclesLis
|
||||
prependTitleElement={
|
||||
<CircularProgressIndicator size={30} percentage={progress} strokeWidth={3}>
|
||||
{progress === 100 ? (
|
||||
<Check className="h-3 w-3 stroke-2 text-accent-primary" />
|
||||
<Check className="h-3 w-3 stroke-2" />
|
||||
) : (
|
||||
<span className="text-9 text-primary">{`${progress}%`}</span>
|
||||
)}
|
||||
|
||||
@@ -35,9 +35,9 @@ export const LabelListItem = observer(function LabelListItem(props: TLabelListIt
|
||||
key={labelId}
|
||||
type="button"
|
||||
className={cn(
|
||||
"h-full w-min flex items-center gap-1.5 rounded-lg px-2 py-0.5 bg-layer-transparent-active hover:bg-layer-transparent-hover text-body-xs-regular text-tertiary",
|
||||
"h-full w-min flex items-center gap-1.5 rounded-lg px-2 py-0.5 bg-layer-transparent-active group text-body-xs-regular text-tertiary",
|
||||
{
|
||||
"cursor-pointer hover:border-danger-strong hover:bg-danger-subtle": !disabled,
|
||||
"cursor-pointer": !disabled,
|
||||
}
|
||||
)}
|
||||
onClick={handleLabel}
|
||||
|
||||
@@ -25,7 +25,7 @@ export const ModuleStatusDropdown = observer(function ModuleStatusDropdown(props
|
||||
<CustomSelect
|
||||
customButton={
|
||||
<span
|
||||
className={`flex h-6 w-20 items-center justify-center rounded-xs text-center text-11 ${
|
||||
className={`flex h-6 w-20 items-center justify-center rounded-sm text-center text-11 ${
|
||||
isDisabled ? "cursor-not-allowed" : "cursor-pointer"
|
||||
}`}
|
||||
style={{
|
||||
|
||||
@@ -166,7 +166,7 @@ export const ModuleQuickActions = observer(function ModuleQuickActions(props: Pr
|
||||
)}
|
||||
disabled={item.disabled}
|
||||
>
|
||||
{item.icon && <item.icon className={cn("h-3 w-3", item.iconClassName)} />}
|
||||
{item.icon && <item.icon className={cn("h-3 w-3 flex-shrink-0", item.iconClassName)} />}
|
||||
<div>
|
||||
<h5>{item.title}</h5>
|
||||
{item.description && (
|
||||
|
||||
@@ -198,7 +198,7 @@ export const ProjectCard = observer(function ProjectCard(props: Props) {
|
||||
}
|
||||
}}
|
||||
data-prevent-progress={!isMemberOfProject || isArchived}
|
||||
className="flex flex-col border border-subtle bg-layer-2 hover:bg-layer-2-hover hover:shadow-raised-200 rounded-xl overflow-hidden"
|
||||
className="flex flex-col border border-subtle bg-layer-2 hover:shadow-raised-2x00 rounded-lg overflow-hidden duration-300 transition-all"
|
||||
>
|
||||
<ContextMenu parentRef={projectCardRef} items={MENU_ITEMS} />
|
||||
<div className="relative h-[118px] w-full rounded-t ">
|
||||
|
||||
@@ -32,7 +32,7 @@ function ProjectCreateHeader(props: Props) {
|
||||
const { getIndex } = getTabIndex(ETabIndices.PROJECT_CREATE, isMobile);
|
||||
|
||||
return (
|
||||
<div className="group relative h-44 w-full rounded-lg bg-layer-1">
|
||||
<div className="group relative h-44 w-full rounded-lg">
|
||||
{coverImage && (
|
||||
<img
|
||||
src={getCoverImageDisplayURL(coverImage, DEFAULT_COVER_IMAGE_URL)}
|
||||
|
||||
@@ -170,8 +170,8 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props:
|
||||
{t("workspace_creation.form.url.label")}
|
||||
<span className="ml-0.5 text-red-500">*</span>
|
||||
</label>
|
||||
<div className="flex w-full items-center rounded-md border-[0.5px] border-subtle px-3">
|
||||
<span className="whitespace-nowrap text-13 text-secondary">{window && window.location.host}/</span>
|
||||
<div className="flex w-full items-center rounded-md border-[0.5px] border-subtle px-3 bg-layer-1">
|
||||
<span className="whitespace-nowrap text-12 text-secondary">{window && window.location.host}/</span>
|
||||
<Controller
|
||||
control={control}
|
||||
name="slug"
|
||||
@@ -195,7 +195,7 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props:
|
||||
ref={ref}
|
||||
hasError={Boolean(errors.slug)}
|
||||
placeholder={t("workspace_creation.form.url.placeholder")}
|
||||
className="block w-full rounded-md border-none bg-transparent !px-0 py-2 text-13"
|
||||
className="block w-full rounded-md border-none bg-transparent !px-0 py-2 text-12"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
@@ -229,7 +229,7 @@ export const CreateWorkspaceForm = observer(function CreateWorkspaceForm(props:
|
||||
</span>
|
||||
)
|
||||
}
|
||||
buttonClassName="!border-[0.5px] !border-subtle !shadow-none"
|
||||
buttonClassName="!border-[0.5px] !border-subtle !shadow-none bg-layer-1 text-12"
|
||||
input
|
||||
>
|
||||
{ORGANIZATION_SIZE.map((item) => (
|
||||
|
||||
@@ -87,21 +87,27 @@ const SidebarDropdownItem = observer(function SidebarDropdownItem(props: TProps)
|
||||
{[EUserPermissions.ADMIN, EUserPermissions.MEMBER].includes(workspace?.role) && (
|
||||
<Link
|
||||
href={`/${workspace.slug}/settings`}
|
||||
onClick={handleClose}
|
||||
className="flex border border-subtle rounded-md py-1 px-2 gap-1 hover:text-secondary text-tertiary hover:border-strong bg-layer-3 hover:bg-layer-3-hover"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleClose();
|
||||
}}
|
||||
className="flex border border-strong rounded-md py-1.5 px-2.5 gap-1.5 hover:text-secondary text-secondary hover:border-strong bg-layer-2 hover:shadow-raised-100 transition-colors"
|
||||
>
|
||||
<Settings className="h-4 w-4 my-auto" />
|
||||
<span className="text-13 font-medium my-auto">{t("settings")}</span>
|
||||
<Settings className="h-4 w-4 my-auto flex-shrink-0" />
|
||||
<span className="text-13 font-medium my-auto whitespace-nowrap">{t("settings")}</span>
|
||||
</Link>
|
||||
)}
|
||||
{[EUserPermissions.ADMIN].includes(workspace?.role) && (
|
||||
<Link
|
||||
href={`/${workspace.slug}/settings/members`}
|
||||
onClick={handleClose}
|
||||
className="flex border border-subtle rounded-md py-1 px-2 gap-1 hover:text-secondary text-tertiary hover:border-strong bg-layer-3 hover:bg-layer-3-hover"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleClose();
|
||||
}}
|
||||
className="flex border border-strong rounded-md py-1.5 px-2.5 gap-1.5 hover:text-secondary text-secondary hover:border-strong bg-layer-2 hover:shadow-raised-100 transition-colors"
|
||||
>
|
||||
<UserPlus className="h-4 w-4 my-auto" />
|
||||
<span className="text-13 font-medium my-auto">
|
||||
<UserPlus className="h-4 w-4 my-auto flex-shrink-0" />
|
||||
<span className="text-13 font-medium my-auto whitespace-nowrap">
|
||||
{t("project_settings.members.invite_members.title")}
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
@@ -126,7 +126,7 @@ export const WorkspaceAuthWrapper = observer(function WorkspaceAuthWrapper(props
|
||||
// if list of workspaces are not there then we have to render the spinner
|
||||
if (isParentLoading || allWorkspaces === undefined || loader) {
|
||||
return (
|
||||
<div className="grid h-full place-items-center bg-surface-1 p-4 rounded-lg border border-subtle">
|
||||
<div className="grid h-full place-items-center p-4 rounded-lg border border-subtle">
|
||||
<div className="flex flex-col items-center gap-3 text-center">
|
||||
<LogoSpinner />
|
||||
</div>
|
||||
@@ -157,7 +157,7 @@ export const WorkspaceAuthWrapper = observer(function WorkspaceAuthWrapper(props
|
||||
</div>
|
||||
<div className="relative flex h-full w-full flex-grow flex-col items-center justify-center space-y-3">
|
||||
<div className="relative flex-shrink-0">
|
||||
<img src={WorkSpaceNotAvailable} className="h-[220px] object-cover object-center" alt="Plane logo" />
|
||||
<img src={WorkSpaceNotAvailable} className="h-[220px] object-contain object-center" alt="Plane logo" />
|
||||
</div>
|
||||
<h3 className="text-center text-16 font-semibold">Workspace not found</h3>
|
||||
<p className="text-center text-13 text-secondary">
|
||||
|
||||
@@ -105,7 +105,7 @@ ul[data-type="taskList"] li > div {
|
||||
}
|
||||
|
||||
ul[data-type="taskList"] li > label input[type="checkbox"] {
|
||||
@apply border! border-strong/20!;
|
||||
@apply border! border-strong!;
|
||||
outline: none;
|
||||
border-radius: 2px;
|
||||
transform: scale(1.05);
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface DialogTitleProps extends React.ComponentProps<typeof BaseDialog
|
||||
|
||||
// Constants
|
||||
const OVERLAY_CLASSNAME = cn("fixed inset-0 z-backdrop bg-backdrop");
|
||||
const BASE_CLASSNAME = "relative text-left bg-surface-1 rounded-lg shadow-md w-full z-modal";
|
||||
const BASE_CLASSNAME = "relative text-left bg-surface-1 rounded-lg shadow-md w-full z-modal border border-subtle";
|
||||
|
||||
// Utility functions
|
||||
const getPositionClassNames = (position: DialogPosition) =>
|
||||
|
||||
@@ -29,10 +29,10 @@ const Input = React.forwardRef(function Input(props: InputProps, ref: React.Forw
|
||||
type={type}
|
||||
name={name}
|
||||
className={cn(
|
||||
"block rounded-md bg-transparent text-13 placeholder-custom-text-400 focus:outline-none",
|
||||
"block rounded-md bg-layer-1 text-13 placeholder-tertiary border-subtle-1 focus:outline-none",
|
||||
{
|
||||
"rounded-md border-[0.5px] border-subtle": mode === "primary",
|
||||
"rounded-sm border-none bg-transparent ring-0 transition-all focus:ring-1 focus:ring-custom-primary":
|
||||
"rounded-md border-[0.5px]": mode === "primary",
|
||||
"rounded-sm border-none bg-transparent ring-0 transition-all focus:ring-1 focus:ring-accent-strong":
|
||||
mode === "transparent",
|
||||
"rounded-sm border-none bg-transparent ring-0": mode === "true-transparent",
|
||||
"border-red-500": hasError,
|
||||
|
||||
@@ -40,7 +40,7 @@ const TabsRoot = React.forwardRef(function TabsRoot(
|
||||
const TabsList = React.forwardRef(function TabsList(
|
||||
{
|
||||
className,
|
||||
background = "layer-1",
|
||||
background = "layer-2",
|
||||
...props
|
||||
}: React.ComponentProps<typeof TabsPrimitive.List> & {
|
||||
background?: BackgroundVariant;
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
--background-color-danger-transparent-hover: var(--color-red-100);
|
||||
--background-color-danger-transparent-active: var(--color-red-100);
|
||||
--background-color-danger-transparent-selected: var(--color-red-100);
|
||||
--background-color-backdrop: var(--color-alpha-black-400);
|
||||
--background-color-backdrop: var(--color-alpha-black-500);
|
||||
|
||||
/* Border colors */
|
||||
--border-color-subtle: var(--color-neutral-400);
|
||||
@@ -674,7 +674,7 @@
|
||||
--background-color-danger-transparent-hover: var(--color-red-100);
|
||||
--background-color-danger-transparent-active: var(--color-red-100);
|
||||
--background-color-danger-transparent-selected: var(--color-red-100);
|
||||
--background-color-backdrop: var(--color-alpha-white-200);
|
||||
--background-color-backdrop: var(--color-alpha-black-1000);
|
||||
|
||||
/* Border colors */
|
||||
--border-color-subtle: var(--color-neutral-400);
|
||||
|
||||
@@ -30,9 +30,9 @@ const Input = React.forwardRef(function Input(props: InputProps, ref: React.Forw
|
||||
type={type}
|
||||
name={name}
|
||||
className={cn(
|
||||
"block rounded-md bg-transparent text-13 placeholder-custom-text-400 focus:outline-none",
|
||||
"block rounded-md bg-layer-1 text-13 placeholder-tertiary border-subtle-1 focus:outline-none",
|
||||
{
|
||||
"rounded-md border-[0.5px] border-subtle": mode === "primary",
|
||||
"rounded-md border-[0.5px]": mode === "primary",
|
||||
"rounded-sm border-none bg-transparent ring-0 transition-all focus:ring-1 focus:ring-custom-primary":
|
||||
mode === "transparent",
|
||||
"rounded-sm border-none bg-transparent ring-0": mode === "true-transparent",
|
||||
|
||||
@@ -9,7 +9,7 @@ interface ICircularProgressIndicator {
|
||||
}
|
||||
|
||||
export function CircularProgressIndicator(props: ICircularProgressIndicator) {
|
||||
const { size = 40, percentage = 25, strokeWidth = 6, strokeColor = "stroke-accent-primary", children } = props;
|
||||
const { size = 40, percentage = 25, strokeWidth = 6, strokeColor = "stroke-success", children } = props;
|
||||
|
||||
const sqSize = size;
|
||||
const radius = (size - strokeWidth) / 2;
|
||||
|
||||
@@ -19,22 +19,26 @@ type TTabListProps = {
|
||||
tabClassName?: string;
|
||||
size?: "sm" | "md" | "lg";
|
||||
selectedTab?: string;
|
||||
autoWrap?: boolean;
|
||||
onTabChange?: (key: string) => void;
|
||||
};
|
||||
|
||||
export function TabList({
|
||||
tabs,
|
||||
tabListClassName,
|
||||
tabClassName,
|
||||
size = "md",
|
||||
selectedTab,
|
||||
onTabChange,
|
||||
}: TTabListProps) {
|
||||
export function TabList({ autoWrap = true, ...props }: TTabListProps) {
|
||||
return autoWrap ? (
|
||||
<Tab.Group>
|
||||
<TabListInner {...props} />
|
||||
</Tab.Group>
|
||||
) : (
|
||||
<TabListInner {...props} />
|
||||
);
|
||||
}
|
||||
|
||||
function TabListInner({ tabs, tabListClassName, tabClassName, size = "md", selectedTab, onTabChange }: TTabListProps) {
|
||||
return (
|
||||
<Tab.List
|
||||
as="div"
|
||||
className={cn(
|
||||
"flex w-full min-w-fit items-center justify-between gap-1.5 rounded-md text-13 p-0.5 bg-layer-1/60",
|
||||
"flex w-full min-w-fit items-center justify-between gap-1.5 rounded-md text-13 p-0.5 bg-layer-1",
|
||||
tabListClassName
|
||||
)}
|
||||
>
|
||||
@@ -65,7 +69,9 @@ export function TabList({
|
||||
}}
|
||||
disabled={tab.disabled}
|
||||
>
|
||||
{tab.icon && <tab.icon className="size-4" />}
|
||||
{tab.icon && (
|
||||
<tab.icon className={cn({ "size-3": size === "sm", "size-4": size === "md", "size-5": size === "lg" })} />
|
||||
)}
|
||||
{tab.label}
|
||||
</Tab>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user