mirror of
https://github.com/Yidadaa/ChatGPT-Next-Web.git
synced 2025-08-21 00:45:58 +08:00
feat: improve components structure
This commit is contained in:
83
app/components/button/button.module.scss
Normal file
83
app/components/button/button.module.scss
Normal file
@@ -0,0 +1,83 @@
|
||||
.icon-button {
|
||||
background-color: var(--white);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
color: var(--black);
|
||||
|
||||
&[disabled] {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.primary {
|
||||
background-color: var(--primary);
|
||||
color: white;
|
||||
|
||||
path {
|
||||
fill: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.danger {
|
||||
color: rgba($color: red, $alpha: 0.8);
|
||||
border-color: rgba($color: red, $alpha: 0.5);
|
||||
background-color: rgba($color: red, $alpha: 0.05);
|
||||
|
||||
&:hover {
|
||||
border-color: red;
|
||||
background-color: rgba($color: red, $alpha: 0.1);
|
||||
}
|
||||
|
||||
path {
|
||||
fill: red !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.shadow {
|
||||
box-shadow: var(--card-shadow);
|
||||
}
|
||||
|
||||
.border {
|
||||
border: var(--border-in-light);
|
||||
}
|
||||
|
||||
.icon-button-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.icon-button {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-button-text {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
51
app/components/button/button.tsx
Normal file
51
app/components/button/button.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import * as React from "react";
|
||||
|
||||
import styles from "./button.module.scss";
|
||||
|
||||
export type ButtonType = "primary" | "danger" | null;
|
||||
|
||||
export function IconButton(props: {
|
||||
onClick?: () => void;
|
||||
icon?: JSX.Element;
|
||||
type?: ButtonType;
|
||||
text?: string;
|
||||
bordered?: boolean;
|
||||
shadow?: boolean;
|
||||
className?: string;
|
||||
title?: string;
|
||||
disabled?: boolean;
|
||||
tabIndex?: number;
|
||||
autoFocus?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
className={
|
||||
styles["icon-button"] +
|
||||
` ${props.bordered && styles.border} ${props.shadow && styles.shadow} ${
|
||||
props.className ?? ""
|
||||
} clickable ${styles[props.type ?? ""]}`
|
||||
}
|
||||
onClick={props.onClick}
|
||||
title={props.title}
|
||||
disabled={props.disabled}
|
||||
role="button"
|
||||
tabIndex={props.tabIndex}
|
||||
autoFocus={props.autoFocus}
|
||||
>
|
||||
{props.icon && (
|
||||
<div
|
||||
className={
|
||||
styles["icon-button-icon"] +
|
||||
` ${props.type === "primary" && "no-dark"}`
|
||||
}
|
||||
>
|
||||
{props.icon}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{props.text && (
|
||||
<div className={styles["icon-button-text"]}>{props.text}</div>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
}
|
1
app/components/button/index.tsx
Normal file
1
app/components/button/index.tsx
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./button";
|
Reference in New Issue
Block a user