mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore(frontend): fix clsx
This commit is contained in:
@ -1,11 +1,10 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
import { useWorkspaceSettingStore } from "@/store/v1";
|
||||
import { WorkspaceGeneralSetting } from "@/types/proto/api/v1/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { cn } from "@/utils/utils";
|
||||
|
||||
interface Props {
|
||||
month: string; // Format: 2021-1
|
||||
@ -66,9 +65,9 @@ const ActivityCalendar = (props: Props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={clsx("w-full h-auto shrink-0 grid grid-cols-7 grid-flow-row gap-1")}>
|
||||
<div className={cn("w-full h-auto shrink-0 grid grid-cols-7 grid-flow-row gap-1")}>
|
||||
{weekDays.map((day, index) => (
|
||||
<div key={index} className={clsx("w-6 h-5 text-xs flex justify-center items-center cursor-default opacity-60")}>
|
||||
<div key={index} className={cn("w-6 h-5 text-xs flex justify-center items-center cursor-default opacity-60")}>
|
||||
{day}
|
||||
</div>
|
||||
))}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { CssVarsProvider } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { Provider } from "react-redux";
|
||||
@ -7,6 +6,7 @@ import CommonContextProvider from "@/layouts/CommonContextProvider";
|
||||
import store from "@/store";
|
||||
import { useDialogStore } from "@/store/module";
|
||||
import theme from "@/theme";
|
||||
import { cn } from "@/utils";
|
||||
import "@/less/base-dialog.less";
|
||||
|
||||
interface DialogConfig {
|
||||
@ -56,8 +56,8 @@ const BaseDialog: React.FC<Props> = (props: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={clsx("dialog-wrapper", className)} onMouseDown={handleSpaceClicked}>
|
||||
<div ref={dialogContainerRef} className={clsx("dialog-container")} onMouseDown={(e) => e.stopPropagation()}>
|
||||
<div className={cn("dialog-wrapper", className)} onMouseDown={handleSpaceClicked}>
|
||||
<div ref={dialogContainerRef} className={cn("dialog-container")} onMouseDown={(e) => e.stopPropagation()}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import clsx from "clsx";
|
||||
import useDebounce from "react-use/lib/useDebounce";
|
||||
import SearchBar from "@/components/SearchBar";
|
||||
import { useUserStatsStore } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import TagsSection from "../HomeSidebar/TagsSection";
|
||||
import StatisticsView from "../StatisticsView";
|
||||
|
||||
@ -22,7 +22,7 @@ const ExploreSidebar = (props: Props) => {
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start",
|
||||
props.className,
|
||||
)}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import clsx from "clsx";
|
||||
import useDebounce from "react-use/lib/useDebounce";
|
||||
import SearchBar from "@/components/SearchBar";
|
||||
import StatisticsView from "@/components/StatisticsView";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useMemoList, useUserStatsStore } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import TagsSection from "./TagsSection";
|
||||
|
||||
interface Props {
|
||||
@ -25,7 +25,7 @@ const HomeSidebar = (props: Props) => {
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start",
|
||||
props.className,
|
||||
)}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Dropdown, Menu, MenuButton, MenuItem, Switch } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { Edit3Icon, HashIcon, MoreVerticalIcon, TagsIcon, TrashIcon } from "lucide-react";
|
||||
import toast from "react-hot-toast";
|
||||
import useLocalStorage from "react-use/lib/useLocalStorage";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
import { useMemoFilterStore, useUserStatsStore, useUserStatsTags } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import showRenameTagDialog from "../RenameTagDialog";
|
||||
import TagTree from "../TagTree";
|
||||
@ -94,7 +94,7 @@ const TagsSection = (props: Props) => {
|
||||
</Menu>
|
||||
</Dropdown>
|
||||
<div
|
||||
className={clsx("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}
|
||||
className={cn("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}
|
||||
onClick={() => handleTagClick(tag)}
|
||||
>
|
||||
<span className="truncate dark:opacity-80">{tag}</span>
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { InboxIcon, LoaderIcon, MessageCircleIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
@ -10,6 +9,7 @@ import { activityNamePrefix, useInboxStore, useMemoStore, useUserStore } from "@
|
||||
import { Inbox, Inbox_Status } from "@/types/proto/api/v1/inbox_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { User } from "@/types/proto/api/v1/user_service";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { memoLink } from "@/utils/memo";
|
||||
|
||||
@ -74,7 +74,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
|
||||
return (
|
||||
<div className="w-full flex flex-row justify-start items-start gap-3">
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"shrink-0 mt-2 p-2 rounded-full border",
|
||||
inbox.status === Inbox_Status.UNREAD
|
||||
? "border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800"
|
||||
@ -86,7 +86,7 @@ const MemoCommentMessage = ({ inbox }: Props) => {
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 dark:border-zinc-700 hover:bg-gray-100 dark:hover:bg-zinc-700",
|
||||
inbox.status !== Inbox_Status.UNREAD && "opacity-60",
|
||||
)}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { ArrowUpIcon, InboxIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
@ -7,6 +6,7 @@ import { activityServiceClient } from "@/grpcweb";
|
||||
import { activityNamePrefix, useInboxStore } from "@/store/v1";
|
||||
import { Activity } from "@/types/proto/api/v1/activity_service";
|
||||
import { Inbox, Inbox_Status } from "@/types/proto/api/v1/inbox_service";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
@ -58,7 +58,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
|
||||
return (
|
||||
<div className="w-full flex flex-row justify-start items-start gap-3">
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"shrink-0 mt-2 p-2 rounded-full border",
|
||||
inbox.status === Inbox_Status.UNREAD
|
||||
? "border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800"
|
||||
@ -70,7 +70,7 @@ const VersionUpdateMessage = ({ inbox }: Props) => {
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 dark:border-zinc-700 hover:bg-gray-100 dark:hover:bg-zinc-700",
|
||||
inbox.status !== Inbox_Status.UNREAD && "opacity-60",
|
||||
)}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import copy from "copy-to-clipboard";
|
||||
import {
|
||||
ArchiveIcon,
|
||||
@ -20,6 +19,7 @@ import { useMemoStore, useUserStatsStore } from "@/store/v1";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { NodeType } from "@/types/proto/api/v1/markdown_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { memoLink } from "@/utils/memo";
|
||||
|
||||
@ -166,7 +166,7 @@ const MemoActionMenu = (props: Props) => {
|
||||
return (
|
||||
<Dropdown>
|
||||
<MenuButton slots={{ root: "div" }}>
|
||||
<span className={clsx("flex justify-center items-center rounded-full hover:opacity-70", props.className)}>
|
||||
<span className={cn("flex justify-center items-center rounded-full hover:opacity-70", props.className)}>
|
||||
<MoreVerticalIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
</span>
|
||||
</MenuButton>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import clsx from "clsx";
|
||||
import copy from "copy-to-clipboard";
|
||||
import hljs from "highlight.js";
|
||||
import { CopyIcon } from "lucide-react";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { cn } from "@/utils";
|
||||
import MermaidBlock from "./MermaidBlock";
|
||||
import { BaseProps } from "./types";
|
||||
|
||||
@ -66,9 +66,9 @@ const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
|
||||
</div>
|
||||
|
||||
<div className="overflow-auto">
|
||||
<pre className={clsx("no-wrap overflow-auto", "w-full p-2 bg-amber-50 dark:bg-zinc-700 relative")}>
|
||||
<pre className={cn("no-wrap overflow-auto", "w-full p-2 bg-amber-50 dark:bg-zinc-700 relative")}>
|
||||
<code
|
||||
className={clsx(`language-${formatedLanguage}`, "block text-sm leading-5")}
|
||||
className={cn(`language-${formatedLanguage}`, "block text-sm leading-5")}
|
||||
dangerouslySetInnerHTML={{ __html: highlightedCode }}
|
||||
></code>
|
||||
</pre>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import clsx from "clsx";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { ArrowUpRightIcon } from "lucide-react";
|
||||
import { useContext, useEffect } from "react";
|
||||
@ -7,6 +6,7 @@ import { Link } from "react-router-dom";
|
||||
import MemoResourceListView from "@/components/MemoResourceListView";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { extractMemoIdFromName, useMemoStore } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import { memoLink } from "@/utils/memo";
|
||||
import MemoContent from "..";
|
||||
import { RendererContext } from "../types";
|
||||
@ -45,7 +45,7 @@ const EmbeddedMemo = ({ resourceId: uid, params: paramsStr }: Props) => {
|
||||
// Add the memo to the set of embedded memos. This is used to prevent infinite loops when a memo embeds itself.
|
||||
context.embeddedMemos.add(memoName);
|
||||
const contentNode = useSnippet ? (
|
||||
<div className={clsx("text-gray-800 dark:text-gray-400", inlineMode ? "" : "line-clamp-3")}>{memo.snippet}</div>
|
||||
<div className={cn("text-gray-800 dark:text-gray-400", inlineMode ? "" : "line-clamp-3")}>{memo.snippet}</div>
|
||||
) : (
|
||||
<>
|
||||
<MemoContent
|
||||
|
@ -1,8 +1,8 @@
|
||||
import clsx from "clsx";
|
||||
import { useEffect } from "react";
|
||||
import MemoResourceListView from "@/components/MemoResourceListView";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { useResourceStore } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import Error from "./Error";
|
||||
|
||||
interface Props {
|
||||
@ -53,7 +53,7 @@ const EmbeddedResource = ({ resourceId: uid, params: paramsStr }: Props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={clsx("max-w-full", getAdditionalClassNameWithParams(params))}>
|
||||
<div className={cn("max-w-full", getAdditionalClassNameWithParams(params))}>
|
||||
<MemoResourceListView resources={[resource]} />
|
||||
</div>
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import clsx from "clsx";
|
||||
import { head } from "lodash-es";
|
||||
import React from "react";
|
||||
import { ListNode_Kind, Node, NodeType } from "@/types/proto/api/v1/markdown_service";
|
||||
import { cn } from "@/utils";
|
||||
import Renderer from "./Renderer";
|
||||
|
||||
interface Props {
|
||||
@ -43,7 +43,7 @@ const List: React.FC<Props> = ({ kind, indent, children }: Props) => {
|
||||
return React.createElement(
|
||||
getListContainer(),
|
||||
{
|
||||
className: clsx(
|
||||
className: cn(
|
||||
`list-inside ${kind === ListNode_Kind.ORDERED ? "list-decimal" : kind === ListNode_Kind.UNORDERED ? "list-disc" : "list-none"}`,
|
||||
indent > 0 ? `pl-${2 * indent}` : "",
|
||||
),
|
||||
|
@ -1,6 +1,6 @@
|
||||
import TeX from "@matejmazur/react-katex";
|
||||
import clsx from "clsx";
|
||||
import "katex/dist/katex.min.css";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
content: string;
|
||||
@ -8,7 +8,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const Math: React.FC<Props> = ({ content, block }: Props) => {
|
||||
return <TeX className={clsx("max-w-full", block ? "w-full block" : "inline text-sm")} block={block} math={content}></TeX>;
|
||||
return <TeX className={cn("max-w-full", block ? "w-full block" : "inline text-sm")} block={block} math={content}></TeX>;
|
||||
};
|
||||
|
||||
export default Math;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import clsx from "clsx";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
content: string;
|
||||
@ -10,10 +10,10 @@ const Spoiler: React.FC<Props> = ({ content }: Props) => {
|
||||
|
||||
return (
|
||||
<span
|
||||
className={clsx("inline cursor-pointer select-none", isRevealed ? "" : "bg-gray-200 dark:bg-zinc-700")}
|
||||
className={cn("inline cursor-pointer select-none", isRevealed ? "" : "bg-gray-200 dark:bg-zinc-700")}
|
||||
onClick={() => setIsRevealed(!isRevealed)}
|
||||
>
|
||||
<span className={clsx(isRevealed ? "opacity-100" : "opacity-0")}>{content}</span>
|
||||
<span className={cn(isRevealed ? "opacity-100" : "opacity-0")}>{content}</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
@ -1,9 +1,9 @@
|
||||
import clsx from "clsx";
|
||||
import { useContext } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { Routes } from "@/router";
|
||||
import { stringifyFilters, useMemoFilterStore } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import { RendererContext } from "./types";
|
||||
|
||||
interface Props {
|
||||
@ -44,10 +44,7 @@ const Tag: React.FC<Props> = ({ content }: Props) => {
|
||||
|
||||
return (
|
||||
<span
|
||||
className={clsx(
|
||||
"inline-block w-auto text-blue-600 dark:text-blue-400",
|
||||
context.disableFilter ? "" : "cursor-pointer hover:opacity-80",
|
||||
)}
|
||||
className={cn("inline-block w-auto text-blue-600 dark:text-blue-400", context.disableFilter ? "" : "cursor-pointer hover:opacity-80")}
|
||||
onClick={handleTagClick}
|
||||
>
|
||||
#{content}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Checkbox } from "@usememos/mui";
|
||||
import clsx from "clsx";
|
||||
import { useContext, useState } from "react";
|
||||
import { markdownServiceClient } from "@/grpcweb";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
import { Node, TaskListItemNode } from "@/types/proto/api/v1/markdown_service";
|
||||
import { cn } from "@/utils";
|
||||
import Renderer from "./Renderer";
|
||||
import { RendererContext } from "./types";
|
||||
|
||||
@ -39,11 +39,11 @@ const TaskListItem: React.FC<Props> = ({ node, complete, children }: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<li className={clsx("w-full grid grid-cols-[24px_1fr]")}>
|
||||
<li className={cn("w-full grid grid-cols-[24px_1fr]")}>
|
||||
<span className="w-6 h-6 flex justify-start items-center">
|
||||
<Checkbox size="sm" checked={checked} disabled={context.readonly} onChange={(e) => handleCheckboxChange(e.target.checked)} />
|
||||
</span>
|
||||
<p className={clsx(complete && "line-through opacity-80")}>
|
||||
<p className={cn(complete && "line-through opacity-80")}>
|
||||
{children.map((child, index) => (
|
||||
<Renderer key={`${child.type}-${index}`} index={String(index)} node={child} />
|
||||
))}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import clsx from "clsx";
|
||||
import { memo, useEffect, useRef, useState } from "react";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
import { Node, NodeType } from "@/types/proto/api/v1/markdown_service";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { isSuperUser } from "@/utils/user";
|
||||
import Renderer from "./Renderer";
|
||||
@ -86,7 +86,7 @@ const MemoContent: React.FC<Props> = (props: Props) => {
|
||||
<div className={`w-full flex flex-col justify-start items-start text-gray-800 dark:text-gray-400 ${className || ""}`}>
|
||||
<div
|
||||
ref={memoContentContainerRef}
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"relative w-full max-w-full word-break text-base leading-snug space-y-2 whitespace-pre-wrap",
|
||||
showCompactMode == "ALL" && "line-clamp-6 max-h-60",
|
||||
contentClassName,
|
||||
|
@ -1,8 +1,8 @@
|
||||
import clsx from "clsx";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { CheckCircleIcon, Code2Icon, HashIcon, LinkIcon } from "lucide-react";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo, MemoProperty } from "@/types/proto/api/v1/memo_service";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import MemoRelationForceGraph from "../MemoRelationForceGraph";
|
||||
|
||||
@ -20,10 +20,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={clsx(
|
||||
"relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start",
|
||||
className,
|
||||
)}
|
||||
className={cn("relative w-full h-auto max-h-screen overflow-auto hide-scrollbar flex flex-col justify-start items-start", className)}
|
||||
>
|
||||
<div className="flex flex-col justify-start items-start w-full px-1 gap-2 h-auto shrink-0 flex-nowrap hide-scrollbar">
|
||||
{shouldShowRelationGraph && (
|
||||
@ -95,7 +92,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||
className="shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-gray-600 dark:text-gray-400 dark:border-zinc-800"
|
||||
>
|
||||
<HashIcon className="group-hover:hidden w-4 h-auto shrink-0 opacity-40" />
|
||||
<div className={clsx("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}>
|
||||
<div className={cn("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}>
|
||||
<span className="truncate dark:opacity-80">{tag}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Option, Select } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { Settings2Icon } from "lucide-react";
|
||||
import { useMemoFilterStore } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "./ui/Popover";
|
||||
|
||||
@ -17,7 +17,7 @@ const MemoDisplaySettingMenu = ({ className }: Props) => {
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger
|
||||
className={clsx(className, isApplying ? "text-teal-600 bg-teal-50 dark:text-teal-500 dark:bg-teal-900 rounded-sm" : "opacity-40")}
|
||||
className={cn(className, isApplying ? "text-teal-600 bg-teal-50 dark:text-teal-500 dark:bg-teal-900 rounded-sm" : "opacity-40")}
|
||||
>
|
||||
<Settings2Icon className="w-4 h-auto shrink-0" />
|
||||
</PopoverTrigger>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import clsx from "clsx";
|
||||
import Fuse from "fuse.js";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import getCaretCoordinates from "textarea-caret";
|
||||
import OverflowTip from "@/components/kit/OverflowTip";
|
||||
import { useUserStatsTags } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import { EditorRefActions } from ".";
|
||||
|
||||
type Props = {
|
||||
@ -110,7 +110,7 @@ const TagSuggestions = ({ editorRef, editorActions }: Props) => {
|
||||
<div
|
||||
key={tag}
|
||||
onMouseDown={() => autocomplete(tag)}
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"rounded p-1 px-2 w-full truncate text-sm dark:text-gray-300 cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800",
|
||||
i === selected ? "bg-zinc-300 dark:bg-zinc-600" : "",
|
||||
)}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import clsx from "clsx";
|
||||
import { last } from "lodash-es";
|
||||
import { forwardRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||
import { markdownServiceClient } from "@/grpcweb";
|
||||
import { NodeType, OrderedListItemNode, TaskListItemNode, UnorderedListItemNode } from "@/types/proto/api/v1/markdown_service";
|
||||
import { cn } from "@/utils";
|
||||
import TagSuggestions from "./TagSuggestions";
|
||||
|
||||
export interface EditorRefActions {
|
||||
@ -187,10 +187,7 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"flex flex-col justify-start items-start relative w-full h-auto max-h-[50vh] bg-inherit dark:text-gray-300",
|
||||
className,
|
||||
)}
|
||||
className={cn("flex flex-col justify-start items-start relative w-full h-auto max-h-[50vh] bg-inherit dark:text-gray-300", className)}
|
||||
>
|
||||
<textarea
|
||||
className="w-full h-full my-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent outline-none whitespace-pre-wrap word-break"
|
||||
|
@ -75,15 +75,15 @@ const MemoFilters = () => {
|
||||
|
||||
return (
|
||||
<div className="w-full mb-2 flex flex-row justify-start items-start gap-2">
|
||||
<span className="flex flex-row items-center gap-0.5 text-gray-500 text-sm leading-6 border border-transparent">
|
||||
<span className="flex flex-row items-center gap-0.5 text-gray-500 text-sm leading-7 border border-transparent">
|
||||
<FilterIcon className="w-4 h-auto opacity-60 inline" />
|
||||
{t("memo.filters")}
|
||||
</span>
|
||||
<div className="flex flex-row justify-start items-center flex-wrap gap-2 leading-6 h-6">
|
||||
<div className="flex flex-row justify-start items-center flex-wrap gap-x-2 gap-y-1 leading-7 h-7">
|
||||
{filters.map((filter) => (
|
||||
<div
|
||||
key={getMemoFilterKey(filter)}
|
||||
className="flex flex-row items-center gap-1 bg-white dark:bg-zinc-800 border dark:border-zinc-700 pl-1.5 pr-1 rounded-md hover:line-through cursor-pointer"
|
||||
className="w-auto h-full flex flex-row items-center gap-1 bg-white dark:bg-zinc-800 border dark:border-zinc-700 pl-1.5 pr-1 rounded-md hover:line-through cursor-pointer"
|
||||
onClick={() => memoFilterStore.removeFilter((f) => isEqual(f, filter))}
|
||||
>
|
||||
<FactorIcon className="w-4 h-auto text-gray-500 dark:text-gray-400 opacity-60" factor={filter.factor} />
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useColorScheme } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import ForceGraph2D, { ForceGraphMethods, LinkObject, NodeObject } from "react-force-graph-2d";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { cn } from "@/utils";
|
||||
import { memoLink } from "@/utils/memo";
|
||||
import { LinkType, NodeType } from "./types";
|
||||
import { convertMemoRelationsToGraphData } from "./utils";
|
||||
@ -40,7 +40,7 @@ const MemoRelationForceGraph = ({ className, memo, parentPage }: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className={clsx("dark:opacity-80", className)}>
|
||||
<div ref={containerRef} className={cn("dark:opacity-80", className)}>
|
||||
<ForceGraph2D
|
||||
ref={graphRef}
|
||||
width={graphSize.width}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import clsx from "clsx";
|
||||
import { LinkIcon, MilestoneIcon } from "lucide-react";
|
||||
import { memo, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { MemoRelation } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
memo: Memo;
|
||||
@ -32,7 +32,7 @@ const MemoRelationListView = (props: Props) => {
|
||||
<div className="w-full flex flex-row justify-start items-center mb-1 gap-3 opacity-60">
|
||||
{referencingMemoList.length > 0 && (
|
||||
<button
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500",
|
||||
selectedTab === "referencing" && "text-gray-800 dark:text-gray-400",
|
||||
)}
|
||||
@ -45,7 +45,7 @@ const MemoRelationListView = (props: Props) => {
|
||||
)}
|
||||
{referencedMemoList.length > 0 && (
|
||||
<button
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500",
|
||||
selectedTab === "referenced" && "text-gray-800 dark:text-gray-400",
|
||||
)}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { BookmarkIcon, MessageCircleMoreIcon } from "lucide-react";
|
||||
import { memo, useCallback, useRef, useState } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
@ -12,6 +11,7 @@ import { MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo, Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import { WorkspaceMemoRelatedSetting } from "@/types/proto/api/v1/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { convertVisibilityToString, memoLink } from "@/utils/memo";
|
||||
import { isSuperUser } from "@/utils/user";
|
||||
@ -125,7 +125,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"group relative flex flex-col justify-start items-start w-full px-4 py-3 mb-2 gap-2 bg-white dark:bg-zinc-800 rounded-lg border border-white dark:border-zinc-800 hover:border-gray-200 dark:hover:border-zinc-700",
|
||||
props.showPinned && memo.pinned && "border-gray-200 border dark:border-zinc-700",
|
||||
className,
|
||||
@ -188,7 +188,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
|
||||
</div>
|
||||
{!isInMemoDetailPage && (workspaceMemoRelatedSetting.enableComment || commentAmount > 0) && (
|
||||
<Link
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"flex flex-row justify-start items-center hover:opacity-70",
|
||||
commentAmount === 0 && "invisible group-hover:visible",
|
||||
)}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import clsx from "clsx";
|
||||
import useWindowScroll from "react-use/lib/useWindowScroll";
|
||||
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||
import { useWorkspaceSettingStore } from "@/store/v1";
|
||||
import { WorkspaceGeneralSetting } from "@/types/proto/api/v1/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { cn } from "@/utils";
|
||||
import NavigationDrawer from "./NavigationDrawer";
|
||||
|
||||
interface Props {
|
||||
@ -21,7 +21,7 @@ const MobileHeader = (props: Props) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"sticky top-0 pt-3 pb-2 sm:pt-2 px-4 sm:px-6 sm:mb-1 bg-zinc-100 dark:bg-zinc-900 bg-opacity-80 backdrop-blur-lg flex md:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-1",
|
||||
offsetTop > 0 && "shadow-md",
|
||||
className,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { ArchiveIcon, BellIcon, Globe2Icon, HomeIcon, LogInIcon, PaperclipIcon, SettingsIcon, SmileIcon, User2Icon } from "lucide-react";
|
||||
import { useEffect } from "react";
|
||||
import { NavLink } from "react-router-dom";
|
||||
@ -7,6 +6,7 @@ import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { Routes } from "@/router";
|
||||
import { useInboxStore } from "@/store/v1";
|
||||
import { Inbox_Status } from "@/types/proto/api/v1/inbox_service";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import UserBanner from "./UserBanner";
|
||||
|
||||
@ -116,14 +116,14 @@ const Navigation = (props: Props) => {
|
||||
|
||||
return (
|
||||
<header
|
||||
className={clsx("w-full h-full overflow-auto flex flex-col justify-start items-start py-4 md:pt-6 z-30 hide-scrollbar", className)}
|
||||
className={cn("w-full h-full overflow-auto flex flex-col justify-start items-start py-4 md:pt-6 z-30 hide-scrollbar", className)}
|
||||
>
|
||||
<UserBanner collapsed={collapsed} />
|
||||
<div className="w-full px-1 py-2 flex flex-col justify-start items-start shrink-0 space-y-2">
|
||||
{navLinks.map((navLink) => (
|
||||
<NavLink
|
||||
className={({ isActive }) =>
|
||||
clsx(
|
||||
cn(
|
||||
"px-2 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-400 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-700 dark:hover:bg-zinc-800",
|
||||
collapsed ? "" : "w-full px-4",
|
||||
isActive ? "bg-white drop-shadow-sm dark:bg-zinc-800 border-gray-200 dark:border-zinc-700" : "border-transparent",
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Dropdown, Menu, MenuButton } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { SmilePlusIcon } from "lucide-react";
|
||||
import { useRef, useState } from "react";
|
||||
import useClickAway from "react-use/lib/useClickAway";
|
||||
@ -9,6 +8,7 @@ import { useMemoStore, useWorkspaceSettingStore } from "@/store/v1";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { WorkspaceMemoRelatedSetting } from "@/types/proto/api/v1/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
memo: Memo;
|
||||
@ -63,7 +63,7 @@ const ReactionSelector = (props: Props) => {
|
||||
<Dropdown open={open} onOpenChange={(_, isOpen) => setOpen(isOpen)}>
|
||||
<MenuButton slots={{ root: "div" }}>
|
||||
<span
|
||||
className={clsx("h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70", className)}
|
||||
className={cn("h-7 w-7 flex justify-center items-center rounded-full border dark:border-zinc-700 hover:opacity-70", className)}
|
||||
>
|
||||
<SmilePlusIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
||||
</span>
|
||||
@ -75,7 +75,7 @@ const ReactionSelector = (props: Props) => {
|
||||
return (
|
||||
<span
|
||||
key={reactionType}
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"inline-flex w-auto text-base cursor-pointer rounded px-1 text-gray-500 dark:text-gray-400 hover:opacity-80",
|
||||
hasReacted(reactionType) && "bg-blue-100 dark:bg-zinc-800",
|
||||
)}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useMemoStore } from "@/store/v1";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { User } from "@/types/proto/api/v1/user_service";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
memo: Memo;
|
||||
@ -67,7 +67,7 @@ const ReactionView = (props: Props) => {
|
||||
return (
|
||||
<Tooltip title={stringifyUsers(users, reactionType)} placement="top">
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"h-7 border px-2 py-0.5 rounded-full flex flex-row justify-center items-center gap-1 dark:border-zinc-700",
|
||||
"text-sm text-gray-600 dark:text-gray-400",
|
||||
currentUser && !readonly && "cursor-pointer",
|
||||
|
@ -1,4 +1,3 @@
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
BinaryIcon,
|
||||
BookIcon,
|
||||
@ -12,6 +11,7 @@ import {
|
||||
} from "lucide-react";
|
||||
import React from "react";
|
||||
import { Resource } from "@/types/proto/api/v1/resource_service";
|
||||
import { cn } from "@/utils";
|
||||
import { getResourceType, getResourceUrl } from "@/utils/resource";
|
||||
import showPreviewImageDialog from "./PreviewImageDialog";
|
||||
import SquareDiv from "./kit/SquareDiv";
|
||||
@ -26,7 +26,7 @@ const ResourceIcon = (props: Props) => {
|
||||
const { resource } = props;
|
||||
const resourceType = getResourceType(resource);
|
||||
const resourceUrl = getResourceUrl(resource);
|
||||
const className = clsx("w-full h-auto", props.className);
|
||||
const className = cn("w-full h-auto", props.className);
|
||||
const strokeWidth = props.strokeWidth;
|
||||
|
||||
const previewResource = () => {
|
||||
@ -35,7 +35,7 @@ const ResourceIcon = (props: Props) => {
|
||||
|
||||
if (resourceType === "image/*") {
|
||||
return (
|
||||
<SquareDiv className={clsx(className, "flex items-center justify-center overflow-clip")}>
|
||||
<SquareDiv className={cn(className, "flex items-center justify-center overflow-clip")}>
|
||||
<img
|
||||
className="min-w-full min-h-full object-cover"
|
||||
src={resource.externalLink ? resourceUrl : resourceUrl + "?thumbnail=true"}
|
||||
@ -73,7 +73,7 @@ const ResourceIcon = (props: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div onClick={previewResource} className={clsx(className, "max-w-[4rem] opacity-50")}>
|
||||
<div onClick={previewResource} className={cn(className, "max-w-[4rem] opacity-50")}>
|
||||
{getResourceIcon()}
|
||||
</div>
|
||||
);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
import { countBy } from "lodash-es";
|
||||
import { CheckCircleIcon, ChevronDownIcon, ChevronUpIcon, Code2Icon, LinkIcon, ListTodoIcon } from "lucide-react";
|
||||
@ -8,6 +7,7 @@ import useAsyncEffect from "@/hooks/useAsyncEffect";
|
||||
import i18n from "@/i18n";
|
||||
import { useMemoFilterStore, useUserStatsStore } from "@/store/v1";
|
||||
import { UserStats_MemoTypeStats } from "@/types/proto/api/v1/user_service";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import ActivityCalendar from "./ActivityCalendar";
|
||||
|
||||
@ -42,7 +42,7 @@ const StatisticsView = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="group w-full mt-2 py-2 space-y-1 text-gray-500 dark:text-gray-400">
|
||||
<div className="group w-full mt-4 space-y-1 text-gray-500 dark:text-gray-400">
|
||||
<div className="w-full mb-1 flex flex-row justify-between items-center gap-1">
|
||||
<div className="relative text-sm font-medium inline-flex flex-row items-center w-auto dark:text-gray-400 truncate">
|
||||
<span className="truncate">
|
||||
@ -74,7 +74,7 @@ const StatisticsView = () => {
|
||||
</div>
|
||||
<div className="pt-1 w-full flex flex-row justify-start items-center gap-x-2 gap-y-1 flex-wrap">
|
||||
<div
|
||||
className={clsx("w-auto border dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center")}
|
||||
className={cn("w-auto border dark:border-zinc-800 pl-1.5 pr-2 py-0.5 rounded-md flex justify-between items-center")}
|
||||
onClick={() => memoFilterStore.addFilter({ factor: "property.hasLink", value: "" })}
|
||||
>
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
@ -84,7 +84,7 @@ const StatisticsView = () => {
|
||||
<span className="text-sm truncate">{memoTypeStats.linkCount}</span>
|
||||
</div>
|
||||
<div
|
||||
className={clsx("w-auto border dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center")}
|
||||
className={cn("w-auto border dark:border-zinc-800 pl-1.5 pr-2 py-0.5 rounded-md flex justify-between items-center")}
|
||||
onClick={() => memoFilterStore.addFilter({ factor: "property.hasTaskList", value: "" })}
|
||||
>
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
@ -104,7 +104,7 @@ const StatisticsView = () => {
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={clsx("w-auto border dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center")}
|
||||
className={cn("w-auto border dark:border-zinc-800 pl-1.5 pr-2 py-0.5 rounded-md flex justify-between items-center")}
|
||||
onClick={() => memoFilterStore.addFilter({ factor: "property.hasCode", value: "" })}
|
||||
>
|
||||
<div className="w-auto flex justify-start items-center mr-1">
|
||||
|
@ -1,4 +1,4 @@
|
||||
import clsx from "clsx";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
avatarUrl?: string;
|
||||
@ -8,7 +8,7 @@ interface Props {
|
||||
const UserAvatar = (props: Props) => {
|
||||
const { avatarUrl, className } = props;
|
||||
return (
|
||||
<div className={clsx(`w-8 h-8 overflow-clip rounded-xl`, className)}>
|
||||
<div className={cn(`w-8 h-8 overflow-clip rounded-xl`, className)}>
|
||||
<img
|
||||
className="w-full h-auto shadow min-w-full min-h-full object-cover dark:opacity-80"
|
||||
src={avatarUrl || "/full-logo.webp"}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Dropdown, Menu, MenuButton, MenuItem } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { LogOutIcon, SmileIcon } from "lucide-react";
|
||||
import { authServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
@ -8,6 +7,7 @@ import { Routes } from "@/router";
|
||||
import { useWorkspaceSettingStore } from "@/store/v1";
|
||||
import { WorkspaceGeneralSetting } from "@/types/proto/api/v1/workspace_setting_service";
|
||||
import { WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import UserAvatar from "./UserAvatar";
|
||||
|
||||
@ -36,7 +36,7 @@ const UserBanner = (props: Props) => {
|
||||
<Dropdown>
|
||||
<MenuButton disabled={!user} slots={{ root: "div" }}>
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"py-1 my-1 w-auto flex flex-row justify-start items-center cursor-pointer text-gray-800 dark:text-gray-400",
|
||||
collapsed ? "px-1" : "px-3",
|
||||
)}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
import { Globe2Icon, LockIcon, UsersIcon } from "lucide-react";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
visibility: Visibility;
|
||||
@ -21,7 +21,7 @@ const VisibilityIcon = (props: Props) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <VIcon className={clsx("w-4 h-auto text-gray-500 dark:text-gray-400")} />;
|
||||
return <VIcon className={cn("w-4 h-auto text-gray-500 dark:text-gray-400")} />;
|
||||
};
|
||||
|
||||
export default VisibilityIcon;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import clsx from "clsx";
|
||||
import { useRef, useState, useEffect } from "react";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
@ -21,7 +21,7 @@ const OverflowTip = ({ children, className }: Props) => {
|
||||
|
||||
return (
|
||||
<Tooltip title={children} placement="top" arrow disableHoverListener={!isOverflowed}>
|
||||
<div ref={textElementRef} className={clsx("truncate", className)}>
|
||||
<div ref={textElementRef} className={cn("truncate", className)}>
|
||||
{children}
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
import clsx from "clsx";
|
||||
import * as React from "react";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
const Popover = PopoverPrimitive.Root;
|
||||
|
||||
@ -16,8 +16,8 @@ const PopoverContent = React.forwardRef<
|
||||
ref={ref}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={clsx(
|
||||
"z-[2000] w-auto rounded-md bg-white dark:bg-zinc-900 border dark:border-zinc-800 bg-popover p-2 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className={cn(
|
||||
"z-[2000] w-auto rounded-md bg-white dark:bg-zinc-900 border dark:border-zinc-800 p-2 shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Tooltip } from "@mui/joy";
|
||||
import { Button } from "@usememos/mui";
|
||||
import clsx from "clsx";
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
|
||||
import { Suspense, useEffect, useMemo, useState } from "react";
|
||||
import { Outlet, useLocation, useSearchParams } from "react-router-dom";
|
||||
@ -12,6 +11,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||
import Loading from "@/pages/Loading";
|
||||
import { Routes } from "@/router";
|
||||
import { useMemoFilterStore } from "@/store/v1";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
const RootLayout = () => {
|
||||
@ -47,18 +47,18 @@ const RootLayout = () => {
|
||||
<Loading />
|
||||
) : (
|
||||
<div className="w-full min-h-full">
|
||||
<div className={clsx("w-full transition-all mx-auto flex flex-row justify-center items-start", collapsed ? "sm:pl-16" : "sm:pl-56")}>
|
||||
<div className={cn("w-full transition-all mx-auto flex flex-row justify-center items-start", collapsed ? "sm:pl-16" : "sm:pl-56")}>
|
||||
{sm && (
|
||||
<div
|
||||
className={clsx(
|
||||
className={cn(
|
||||
"group flex flex-col justify-start items-start fixed top-0 left-0 select-none border-r dark:border-zinc-800 h-full bg-zinc-50 dark:bg-zinc-800 dark:bg-opacity-40 transition-all hover:shadow-xl z-2",
|
||||
collapsed ? "w-16 px-2" : "w-56 px-4",
|
||||
)}
|
||||
>
|
||||
<Navigation className="!h-auto" collapsed={collapsed} />
|
||||
<div className={clsx("w-full grow h-auto flex flex-col justify-end", collapsed ? "items-center" : "items-start")}>
|
||||
<div className={cn("w-full grow h-auto flex flex-col justify-end", collapsed ? "items-center" : "items-start")}>
|
||||
<div
|
||||
className={clsx("hidden py-3 group-hover:flex flex-col justify-center items-center")}
|
||||
className={cn("hidden py-3 group-hover:flex flex-col justify-center items-center")}
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
>
|
||||
{!collapsed ? (
|
||||
|
@ -354,8 +354,8 @@
|
||||
"workspace-section": {
|
||||
"disallow-user-registration": "Disallow user registration",
|
||||
"disallow-password-auth": "Disallow password auth",
|
||||
"disallow-change-username": "Disallow Change Username",
|
||||
"disallow-change-nickname": "Disallow Change Nickname",
|
||||
"disallow-change-username": "Disallow changing username",
|
||||
"disallow-change-nickname": "Disallow changing nickname",
|
||||
"week-start-day": "Week start day",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday",
|
||||
@ -391,4 +391,4 @@
|
||||
"blogs": "Blogs",
|
||||
"documents": "Documents"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import clsx from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
import { useMemo } from "react";
|
||||
import { ExploreSidebar, ExploreSidebarDrawer } from "@/components/ExploreSidebar";
|
||||
@ -11,6 +10,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||
import { useMemoFilterStore } from "@/store/v1";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
const Explore = () => {
|
||||
const { md } = useResponsiveWidth();
|
||||
@ -59,8 +59,8 @@ const Explore = () => {
|
||||
<ExploreSidebarDrawer />
|
||||
</MobileHeader>
|
||||
)}
|
||||
<div className={clsx("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
|
||||
<div className={clsx(md ? "w-[calc(100%-15rem)]" : "w-full")}>
|
||||
<div className={cn("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
|
||||
<div className={cn(md ? "w-[calc(100%-15rem)]" : "w-full")}>
|
||||
<MemoFilters />
|
||||
<div className="flex flex-col justify-start items-start w-full max-w-full">
|
||||
<PagedMemoList
|
||||
|
@ -1,4 +1,3 @@
|
||||
import clsx from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
import { useMemo } from "react";
|
||||
import { HomeSidebar, HomeSidebarDrawer } from "@/components/HomeSidebar";
|
||||
@ -12,6 +11,7 @@ import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||
import { useMemoFilterStore } from "@/store/v1";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { cn } from "@/utils";
|
||||
|
||||
const Home = () => {
|
||||
const { md } = useResponsiveWidth();
|
||||
@ -60,8 +60,8 @@ const Home = () => {
|
||||
<HomeSidebarDrawer />
|
||||
</MobileHeader>
|
||||
)}
|
||||
<div className={clsx("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
|
||||
<div className={clsx(md ? "w-[calc(100%-15rem)]" : "w-full")}>
|
||||
<div className={cn("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
|
||||
<div className={cn(md ? "w-[calc(100%-15rem)]" : "w-full")}>
|
||||
<MemoEditor className="mb-2" cacheKey="home-memo-editor" />
|
||||
<MemoFilters />
|
||||
<div className="flex flex-col justify-start items-start w-full max-w-full">
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { Button } from "@usememos/mui";
|
||||
import clsx from "clsx";
|
||||
import { ArrowUpLeftFromCircleIcon, MessageCircleIcon } from "lucide-react";
|
||||
import { ClientError } from "nice-grpc-web";
|
||||
import { useEffect, useState } from "react";
|
||||
@ -16,6 +15,7 @@ import { memoNamePrefix, useMemoStore, useWorkspaceSettingStore } from "@/store/
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_relation_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { WorkspaceMemoRelatedSetting, WorkspaceSettingKey } from "@/types/proto/store/workspace_setting";
|
||||
import { cn } from "@/utils";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { memoLink } from "@/utils/memo";
|
||||
|
||||
@ -92,8 +92,8 @@ const MemoDetail = () => {
|
||||
<MemoDetailSidebarDrawer memo={memo} parentPage={locationState?.from} />
|
||||
</MobileHeader>
|
||||
)}
|
||||
<div className={clsx("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
|
||||
<div className={clsx(md ? "w-[calc(100%-15rem)]" : "w-full")}>
|
||||
<div className={cn("w-full flex flex-row justify-start items-start px-4 sm:px-6 gap-4")}>
|
||||
<div className={cn(md ? "w-[calc(100%-15rem)]" : "w-full")}>
|
||||
{parentMemo && (
|
||||
<div className="w-auto inline-block mb-2">
|
||||
<Link
|
||||
|
1
web/src/utils/index.ts
Normal file
1
web/src/utils/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./utils";
|
@ -1,6 +1,6 @@
|
||||
import { type ClassValue, clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
export const cn = (...inputs: ClassValue[]) => {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user