feat: checkbox component

This commit is contained in:
mrbunker
2024-09-21 15:11:19 +08:00
parent f37890e59e
commit 476dd008cd
5 changed files with 158 additions and 26 deletions

View File

@@ -0,0 +1,31 @@
import Tooltip from "./Tooltip";
interface CheckboxProps {
label: string;
value: boolean;
tip?: string;
onChange: (checked: boolean) => void;
}
const Checkbox = ({ label, value, tip, onChange }: CheckboxProps): JSX.Element => {
const handleChange = (event: JSX.TargetedEvent<HTMLInputElement>) => {
onChange(event.currentTarget.checked);
};
return (
<label className="jop-checkbox">
<input
type="checkbox"
className="jop-checkbox-input"
checked={value}
onChange={handleChange}
/>
<span className="jop-checkbox-custom"></span>
<Tooltip content={tip || ""}>
<span className="jop-checkbox-label">{label}</span>
</Tooltip>
</label>
);
};
export default Checkbox;

View File

@@ -1,5 +1,6 @@
import { Dispatch, StateUpdater, useState } from "preact/hooks";
import { SiteItem } from "@/utils/siteList";
import Checkbox from "./Checkbox";
const Setting = ({
siteList,
@@ -10,9 +11,9 @@ const Setting = ({
setDisables: Dispatch<StateUpdater<string[]>>;
disables: SiteItem["name"][];
}) => {
const [showSetting, setShowSetting] = useState(false);
const [showSetting, setShowSetting] = useState(true);
const changeCheck = (item: SiteItem, isHidden: boolean) => {
const hanleListChange = (item: SiteItem, isHidden: boolean) => {
if (isHidden) {
setDisables(disables.filter((disItem) => disItem !== item.name));
} else {
@@ -22,38 +23,28 @@ const Setting = ({
return (
<>
{!showSetting ? (
<div
className="jop-button_def"
onClick={() => {
setShowSetting(!showSetting);
}}
>
{!showSetting && (
<div className="jop-button_def" onClick={() => setShowSetting(!showSetting)}>
</div>
) : (
<h4 className="jop-setting-title"></h4>
)}
{showSetting && (
<>
<div className="jop-setting">
<div className="jop-setting-list">
<Group title="勾选默认显示的网站:">
{siteList.map((item) => {
const isHidden = disables.includes(item.name);
return (
<div
className="jop-setting-item"
onClick={() => {
changeCheck(item, isHidden);
}}
>
{item.name}
<input type="checkbox" className="jop-setting-checkbox" checked={!isHidden} />
</div>
<Checkbox
label={item.name}
value={!isHidden}
onChange={(checked) => hanleListChange(item, checked)}
/>
);
})}
</Group>
</div>
</div>
<div
className="jop-button_def"
onClick={() => {
@@ -68,4 +59,13 @@ const Setting = ({
);
};
const Group = ({ title, children }: { title: string; children: React.ReactNode }) => {
return (
<>
<h4 className="jop-setting-title">{title}</h4>
<div className="jop-setting-list">{children}</div>
</>
);
};
export default Setting;

View File

@@ -0,0 +1,23 @@
import { useState } from "preact/hooks";
interface TooltipProps {
content: string;
children: preact.ComponentChildren;
}
const Tooltip = ({ content, children }: TooltipProps) => {
const [isVisible, setIsVisible] = useState(false);
return (
<div
className="jop-tooltip-container"
onMouseEnter={() => setIsVisible(true)}
onMouseLeave={() => setIsVisible(false)}
>
{children}
{isVisible && content && <div className="jop-tooltip">{content}</div>}
</div>
);
};
export default Tooltip;

View File

@@ -9,7 +9,6 @@
height: 100%;
z-index: 1;
transition: right 200ms ease-in-out;
font-family: Roboto, Helvetica, Arial, sans-serif;
color: black;
}
@@ -21,7 +20,6 @@
align-items: center;
justify-content: center;
box-sizing: border-box;
/* min-width: 50px; */
padding: 3px 10px;
border-radius: 4px;
font-weight: 500;
@@ -106,17 +104,20 @@
}
/* */
.jop-setting{
margin-top:20px;
}
.jop-setting-list {
display: flex;
flex-wrap: wrap;
}
.jop-setting-title {
margin: 10px 0 5px 0;
font-weight: 700;
}
.jop-setting-item {
display: flex;
height: 20px;
justify-content: center;
align-items: center;
margin-right: 15px;
user-select: none;
@@ -148,3 +149,78 @@ input[type="radio"] {
cursor: pointer;
}
/* */
.jop-tooltip-container {
position: relative;
display: inline-block;
}
.jop-tooltip {
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: #fff;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
z-index: 1000;
}
.jop-setting-label {
cursor: pointer;
}
.jop-checkbox {
display: inline-flex;
align-items: center;
cursor: pointer;
margin-right: 15px;
user-select: none;
}
.jop-checkbox-input {
position: absolute;
opacity: 0;
cursor: pointer;
}
.jop-checkbox-custom {
position: relative;
display: inline-block;
width: 16px;
height: 16px;
background-color: #fff;
border: 1px solid #dcdfe6;
border-radius: 2px;
transition: all 0.3s;
}
.jop-checkbox-input:checked + .jop-checkbox-custom {
background-color: #409eff;
border-color: #409eff;
}
.jop-checkbox-input:checked + .jop-checkbox-custom::after {
content: "";
position: absolute;
top: 1px;
left: 4px;
width: 5px;
height: 10px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
.jop-checkbox-label {
margin-left: 3px;
font-size: 14px;
color: #606266;
}
.jop-checkbox:hover .jop-checkbox-custom {
border-color: #409eff;
}

View File

@@ -4,7 +4,9 @@ import preact from "@preact/preset-vite";
import { siteList } from "./src/utils/siteList";
import { libSites } from "./src/utils/libSites";
const connectList = siteList.map((site) => site.hostname).concat(["javdb008.com", "g64w.com"]);
const connectList = siteList
.map((site) => site.hostname)
.concat(["javdb368.com", "javdb369.com", "g64w.com"]);
const includeList = libSites.map((libItem) => libItem.href);