🚧 add tag type picker

This commit is contained in:
yanyongyu 2021-12-31 18:21:32 +08:00
parent 56677616b4
commit c48231454e
7 changed files with 195 additions and 145 deletions

View File

@ -1,44 +1,10 @@
import clsx from "clsx";
import React from "react";
import Link from "@docusaurus/Link";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import type { Obj, Tag as TagType } from "../../libs/store";
function pickTextColor(bgColor, lightColor, darkColor) {
var color = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB
return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? darkColor : lightColor;
}
export function Tag({
label,
color,
className,
onClick,
}: TagType & {
className?: string;
onClick?: React.MouseEventHandler<HTMLSpanElement>;
}): JSX.Element {
return (
<span
className={clsx(
"inline-flex px-3 rounded-full items-center align-middle mr-2",
className
)}
style={{
backgroundColor: color,
color: pickTextColor(color, "#fff", "#000"),
}}
onClick={onClick}
>
{label}
</span>
);
}
import type { Obj } from "../../libs/store";
import Tag from "../Tag";
export default function Card({
module_name,
@ -79,16 +45,7 @@ export default function Card({
{tags && (
<div className="pt-2 pb-4">
{tags.map((tag, index) => (
<span
key={index}
className="inline-flex px-3 rounded-full items-center align-middle mr-2"
style={{
backgroundColor: tag.color,
color: pickTextColor(tag.color, "#fff", "#000"),
}}
>
{tag.label}
</span>
<Tag key={index} {...tag} />
))}
</div>
)}

View File

@ -32,7 +32,11 @@ export default function Modal({
{ hidden: !active }
)}
>
{children}
<div className="w-full max-w-[600px] max-h-[90%] overflow-y-auto rounded shadow-lg m-6 origin-center transition z-[inherit] pointer-events-auto thin-scrollbar">
<div className="bg-light-nonepress-100 dark:bg-dark-nonepress-100">
{children}
</div>
</div>
</div>
</>
);

View File

@ -0,0 +1,9 @@
import React from "react";
export default function ModalAction({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return <div className="px-4 py-2 flex justify-end">{children}</div>;
}

View File

@ -0,0 +1,9 @@
import React from "react";
export default function ModalContent({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return <div className="px-6 pb-5 w-full">{children}</div>;
}

View File

@ -0,0 +1,9 @@
import React from "react";
export default function ModalTitle({ title }: { title: string }): JSX.Element {
return (
<div className="px-6 pt-4 pb-2 font-medium text-xl">
<span>{title}</span>
</div>
);
}

View File

@ -1,13 +1,17 @@
import clsx from "clsx";
import React, { useState } from "react";
import React, { useRef, useState } from "react";
import { ChromePicker } from "react-color";
import { usePagination } from "react-use-pagination";
import plugins from "../../static/plugins.json";
import { Tag, useFilteredObjs } from "../libs/store";
import Card, { Tag as TagComponent } from "./Card";
import Card from "./Card";
import Modal from "./Modal";
import ModalAction from "./ModalAction";
import ModalContent from "./ModalContent";
import ModalTitle from "./ModalTitle";
import Paginate from "./Paginate";
import TagComponent from "./Tag";
export default function Adapter(): JSX.Element {
const [modalOpen, setModalOpen] = useState<boolean>(false);
@ -31,9 +35,12 @@ export default function Adapter(): JSX.Element {
moduleName: string;
homepage: string;
}>({ name: "", desc: "", projectLink: "", moduleName: "", homepage: "" });
const ref = useRef<HTMLInputElement>(null);
const [tags, setTags] = useState<Tag[]>([]);
const [label, setLabel] = useState<string>("");
const [color, setColor] = useState<string>("#ea5252");
const onSubmit = () => {
setModalOpen(false);
const title = encodeURIComponent(`Plugin: ${form.name}`).replace(
@ -103,6 +110,10 @@ ${JSON.stringify(tags)}
const delTag = (index: number) => {
setTags(tags.filter((_, i) => i !== index));
};
const insertTagType = (text: string) => {
setLabel(text + label);
ref.current.value = text + label;
};
return (
<>
@ -132,114 +143,127 @@ ${JSON.stringify(tags)}
<Paginate {...props} />
</div>
<Modal active={modalOpen} setActive={setModalOpen}>
<div className="w-full max-w-[600px] max-h-[90%] overflow-y-auto rounded shadow-lg m-6 origin-center transition z-[inherit] pointer-events-auto thin-scrollbar">
<div className="bg-light-nonepress-100 dark:bg-dark-nonepress-100">
<div className="px-6 pt-4 pb-2 font-medium text-xl">
<span></span>
</div>
<div className="px-6 pb-5 w-full">
<form onSubmit={onSubmit}>
<div className="grid grid-cols-1 gap-4 p-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="name"
maxLength={20}
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="desc"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">PyPI :</span>
<input
type="text"
name="projectLink"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">import :</span>
<input
type="text"
name="moduleName"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">/:</span>
<input
type="text"
name="homepage"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
</div>
</form>
<div className="px-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
{tags.map((tag, index) => (
<TagComponent
key={index}
{...tag}
className="cursor-pointer"
onClick={() => delTag(index)}
/>
))}
</label>
</div>
<div className="px-4 pt-4">
<ModalTitle title={"插件信息"} />
<ModalContent>
<form onSubmit={onSubmit}>
<div className="grid grid-cols-1 gap-4 p-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="name"
maxLength={20}
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChangeLabel}
onChange={onChange}
/>
<ChromePicker
className="mt-2"
color={color}
disableAlpha={true}
onChangeComplete={onChangeColor}
</label>
<label className="flex flex-wrap">
<span className="mr-2">:</span>
<input
type="text"
name="desc"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
<div className="flex mt-2">
<TagComponent label={label} color={color} />
<button
className={clsx(
"px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]",
{ "pointer-events-none opacity-60": !validateTag() }
)}
onClick={newTag}
>
</button>
</div>
</div>
</label>
<label className="flex flex-wrap">
<span className="mr-2">PyPI :</span>
<input
type="text"
name="projectLink"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">import :</span>
<input
type="text"
name="moduleName"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
<label className="flex flex-wrap">
<span className="mr-2">/:</span>
<input
type="text"
name="homepage"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChange}
/>
</label>
</div>
<div className="px-4 py-2 flex justify-end">
<button className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]" onClick={() => setModalOpen(false)}>
</form>
<div className="px-4">
<label className="flex flex-wrap">
<span className="mr-2">:</span>
{tags.map((tag, index) => (
<TagComponent
key={index}
{...tag}
className="cursor-pointer"
onClick={() => delTag(index)}
/>
))}
</label>
</div>
<div className="px-4 pt-4">
<input
ref={ref}
type="text"
className="px-2 flex-grow rounded bg-light-nonepress-200 dark:bg-dark-nonepress-200"
onChange={onChangeLabel}
/>
<ChromePicker
className="mt-2"
color={color}
disableAlpha={true}
onChangeComplete={onChangeColor}
/>
<div className="flex flex-wrap mt-2 items-center">
<span className="mr-2">Type:</span>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => insertTagType("a:")}
>
Adapter
</button>
<button
className="ml-2 px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={onSubmit}
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => insertTagType("t:")}
>
Topic
</button>
</div>
<div className="flex mt-2">
<TagComponent label={label} color={color} />
<button
className={clsx(
"px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]",
{ "pointer-events-none opacity-60": !validateTag() }
)}
onClick={newTag}
>
</button>
</div>
</div>
</div>
</ModalContent>
<ModalAction>
<button
className="px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={() => setModalOpen(false)}
>
</button>
<button
className="ml-2 px-2 h-9 min-w-[64px] rounded text-hero hover:bg-hero hover:bg-opacity-[.08]"
onClick={onSubmit}
>
</button>
</ModalAction>
</Modal>
</>
);

View File

@ -0,0 +1,38 @@
import clsx from "clsx";
import React from "react";
import { Tag as TagType } from "../../libs/store";
function pickTextColor(bgColor, lightColor, darkColor) {
var color = bgColor.charAt(0) === "#" ? bgColor.substring(1, 7) : bgColor;
var r = parseInt(color.substring(0, 2), 16); // hexToR
var g = parseInt(color.substring(2, 4), 16); // hexToG
var b = parseInt(color.substring(4, 6), 16); // hexToB
return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? darkColor : lightColor;
}
export default function Tag({
label,
color,
className,
onClick,
}: TagType & {
className?: string;
onClick?: React.MouseEventHandler<HTMLSpanElement>;
}): JSX.Element {
return (
<span
className={clsx(
"inline-flex px-3 rounded-full items-center align-middle mr-2",
className
)}
style={{
backgroundColor: color,
color: pickTextColor(color, "#fff", "#000"),
}}
onClick={onClick}
>
{label}
</span>
);
}