feat(@ui): migrate checkbox component

This commit is contained in:
Paul Makles
2022-05-29 16:34:54 +01:00
parent 20d31babce
commit 4bcfa601a5
18 changed files with 239 additions and 361 deletions

View File

@@ -5,13 +5,12 @@ import styled from "styled-components/macro";
import { Text } from "preact-i18n";
import { useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { Button, Checkbox } from "@revoltchat/ui";
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { FileUploader } from "../../../context/revoltjs/FileUploads";
import Checkbox from "../../../components/ui/Checkbox";
import InputBox from "../../../components/ui/InputBox";
interface Props {
@@ -120,14 +119,14 @@ export default observer(({ channel }: Props) => {
""
) : (
<Checkbox
checked={nsfw ?? false}
value={nsfw ?? false}
onChange={(nsfwchange) => {
setNSFW(nsfwchange);
if (!changed) setChanged(true);
}}
description="Set this channel to NSFW.">
NSFW
</Checkbox>
title="NSFW"
description="Set this channel to NSFW."
/>
)}
<p>
<Button onClick={save} palette="secondary" disabled={!changed}>

View File

@@ -3,14 +3,14 @@ import { observer } from "mobx-react-lite";
import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
import { Checkbox } from "@revoltchat/ui";
import { useApplicationState } from "../../../mobx/State";
import {
AVAILABLE_EXPERIMENTS,
EXPERIMENTS,
} from "../../../mobx/stores/Experiments";
import Checkbox from "../../../components/ui/Checkbox";
export const ExperimentsPage = observer(() => {
const experiments = useApplicationState().experiments;
@@ -22,11 +22,11 @@ export const ExperimentsPage = observer(() => {
{AVAILABLE_EXPERIMENTS.map((key) => (
<Checkbox
key={key}
checked={experiments.isEnabled(key)}
value={experiments.isEnabled(key)}
onChange={(enabled) => experiments.setEnabled(key, enabled)}
description={EXPERIMENTS[key].description}>
{EXPERIMENTS[key].title}
</Checkbox>
description={EXPERIMENTS[key].description}
title={EXPERIMENTS[key].title}
/>
))}
{AVAILABLE_EXPERIMENTS.length === 0 && (
<div className={styles.empty}>

View File

@@ -5,6 +5,8 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
import { useMemo } from "preact/hooks";
import { Checkbox } from "@revoltchat/ui";
import { useApplicationState } from "../../../mobx/State";
import britannyFlagSVG from "../assets/flags/brittany.svg";
@@ -21,7 +23,6 @@ import {
Languages as Langs,
} from "../../../../external/lang/Languages";
import Emoji from "../../../components/common/Emoji";
import Checkbox from "../../../components/ui/Checkbox";
import Tip from "../../../components/ui/Tip";
type Key = [Language, LanguageEntry];
@@ -41,66 +42,82 @@ function Entry({ entry: [x, lang], selected, onSelect }: Props) {
<Checkbox
key={x}
className={styles.entry}
checked={selected}
onChange={onSelect}>
<div className={styles.flag}>
{lang.i18n === "vec" ? (
<img
src={venetoFlagSVG}
width={42}
loading="lazy"
style={{ objectFit: "cover", borderRadius: "6px" }}
/>
) : lang.i18n === "br" ? (
<img
src={britannyFlagSVG}
width={42}
loading="lazy"
style={{ objectFit: "cover", borderRadius: "6px" }}
/>
) : lang.i18n === "ckb" ? (
<img
src={kurdistanFlagSVG}
width={42}
loading="lazy"
style={{ objectFit: "cover", borderRadius: "6px" }}
/>
) : lang.i18n === "eo" ? (
<img
src={esperantoFlagSVG}
width={42}
loading="lazy"
style={{ objectFit: "cover", borderRadius: "6px" }}
/>
) : lang.i18n === "ta" ? (
<img
src={tamilFlagPNG}
width={42}
loading="lazy"
style={{ objectFit: "cover" }}
/>
) : lang.emoji === "🙂" ? (
<img
src={tokiponaSVG}
width={42}
loading="lazy"
style={{ borderRadius: "6px" }}
/>
) : lang.emoji === "🪄" ? (
<img
src={enchantingTableWEBP}
width={42}
loading="lazy"
style={{ objectFit: "contain" }}
/>
) : (
<Emoji size={42} emoji={lang.emoji} />
)}
</div>
<span className={styles.description}>
{lang.display} {lang.verified && <Check size={16} />}
</span>
</Checkbox>
value={selected}
onChange={onSelect}
title={
<>
<div className={styles.flag}>
{lang.i18n === "vec" ? (
<img
src={venetoFlagSVG}
width={42}
loading="lazy"
style={{
objectFit: "cover",
borderRadius: "6px",
}}
/>
) : lang.i18n === "br" ? (
<img
src={britannyFlagSVG}
width={42}
loading="lazy"
style={{
objectFit: "cover",
borderRadius: "6px",
}}
/>
) : lang.i18n === "ckb" ? (
<img
src={kurdistanFlagSVG}
width={42}
loading="lazy"
style={{
objectFit: "cover",
borderRadius: "6px",
}}
/>
) : lang.i18n === "eo" ? (
<img
src={esperantoFlagSVG}
width={42}
loading="lazy"
style={{
objectFit: "cover",
borderRadius: "6px",
}}
/>
) : lang.i18n === "ta" ? (
<img
src={tamilFlagPNG}
width={42}
loading="lazy"
style={{ objectFit: "cover" }}
/>
) : lang.emoji === "🙂" ? (
<img
src={tokiponaSVG}
width={42}
loading="lazy"
style={{ borderRadius: "6px" }}
/>
) : lang.emoji === "🪄" ? (
<img
src={enchantingTableWEBP}
width={42}
loading="lazy"
style={{ objectFit: "contain" }}
/>
) : (
<Emoji size={42} emoji={lang.emoji} />
)}
</div>
<span className={styles.description}>
{lang.display} {lang.verified && <Check size={16} />}
</span>
</>
}
/>
);
}

View File

@@ -11,7 +11,7 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
import { useCallback, useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { Button, Checkbox } from "@revoltchat/ui";
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { internalEmit } from "../../../lib/eventEmitter";
@@ -28,7 +28,6 @@ import AutoComplete, {
import CollapsibleSection from "../../../components/common/CollapsibleSection";
import Tooltip from "../../../components/common/Tooltip";
import UserIcon from "../../../components/common/user/UserIcon";
import Checkbox from "../../../components/ui/Checkbox";
import InputBox from "../../../components/ui/InputBox";
import Tip from "../../../components/ui/Tip";
import CategoryButton from "../../../components/ui/fluent/CategoryButton";
@@ -436,15 +435,14 @@ function BotCard({ bot, onDelete, onUpdate }: Props) {
/>
</CollapsibleSection>
<Checkbox
checked={data.public}
value={data.public}
disabled={saving}
contrast
title={<Text id="app.settings.pages.bots.public_bot" />}
description={
<Text id="app.settings.pages.bots.public_bot_desc" />
}
onChange={(v) => setData({ ...data, public: v })}>
<Text id="app.settings.pages.bots.public_bot" />
</Checkbox>
onChange={(v) => setData({ ...data, public: v })}
/>
<h3>
<Text id="app.settings.pages.bots.interactions_url" />
</h3>

View File

@@ -2,12 +2,12 @@ import { Refresh } from "@styled-icons/boxicons-regular";
import { useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { Button, Checkbox } from "@revoltchat/ui";
import RLogo from "../assets/revolt_r.svg";
import Checkbox from "../../../components/ui/Checkbox";
import Tip from "../../../components/ui/Tip";
import CategoryButton from "../../../components/ui/fluent/CategoryButton";
import RLogo from "../assets/revolt_r.svg";
export function Native() {
if (typeof window.native === "undefined") return null;
@@ -30,7 +30,7 @@ export function Native() {
<Tip hideSeparator>Some options might require a restart.</Tip>
<h3>App Behavior</h3>
<Checkbox
checked={autoStart ?? false}
value={autoStart ?? false}
disabled={typeof autoStart === "undefined"}
onChange={async (v) => {
if (v) {
@@ -41,12 +41,12 @@ export function Native() {
setAutoStart(v);
}}
description="Launch Revolt when you log into your computer.">
Start with computer
</Checkbox>
title="Start with computer"
description="Launch Revolt when you log into your computer."
/>
<Checkbox
checked={config.minimiseToTray}
value={config.minimiseToTray}
onChange={(minimiseToTray) => {
window.native.set("minimiseToTray", minimiseToTray);
setConfig({
@@ -54,11 +54,11 @@ export function Native() {
minimiseToTray,
});
}}
description="Instead of closing, Revolt will hide in your tray.">
Minimise to Tray
</Checkbox>
title="Minimise to Tray"
description="Instead of closing, Revolt will hide in your tray."
/>
<Checkbox
checked={config.discordRPC}
value={config.discordRPC}
onChange={(discordRPC) => {
window.native.set("discordRPC", discordRPC);
setConfig({
@@ -66,11 +66,11 @@ export function Native() {
discordRPC,
});
}}
description="Rep Revolt on your Discord status.">
Enable Discord status
</Checkbox>
title="Enable Discord status"
description="Rep Revolt on your Discord status."
/>
<Checkbox
checked={config.build === "nightly"}
value={config.build === "nightly"}
onChange={(nightly) => {
const build = nightly ? "nightly" : "stable";
window.native.set("build", build);
@@ -80,12 +80,13 @@ export function Native() {
build,
});
}}
description="Use the beta branch of Revolt.">
Revolt Nightly
</Checkbox>
title="Revolt Nightly"
description="Use the beta branch of Revolt."
/>
<h3>Titlebar</h3>
<Checkbox
checked={!config.frame}
value={!config.frame}
onChange={(frame) => {
window.native.set("frame", !frame);
setHintRelaunch(true);
@@ -94,12 +95,12 @@ export function Native() {
frame: !frame,
});
}}
description={<>Let Revolt use its own window frame.</>}>
Custom window frame
</Checkbox>
title="Custom window frame"
description="Let Revolt use its own window frame."
/>
<Checkbox //FIXME: In Titlebar.tsx, enable .quick css
disabled={true}
checked={!config.frame}
value={!config.frame}
onChange={(frame) => {
window.native.set("frame", !frame);
setHintRelaunch(true);
@@ -108,12 +109,12 @@ export function Native() {
frame: !frame,
});
}}
description="Show mute/deafen buttons on the titlebar.">
Enable quick action buttons
</Checkbox>
title="Enable quick action buttons"
description="Show mute/deafen buttons on the titlebar."
/>
<h3>Advanced</h3>
<Checkbox
checked={config.hardwareAcceleration}
value={config.hardwareAcceleration}
onChange={async (hardwareAcceleration) => {
window.native.set(
"hardwareAcceleration",
@@ -125,9 +126,10 @@ export function Native() {
hardwareAcceleration,
});
}}
description="Uses your GPU to render the app, disable if you run into visual issues.">
Hardware Acceleration
</Checkbox>
title="Hardware Acceleration"
description="Uses your GPU to render the app, disable if you run into visual issues."
/>
<p style={{ display: "flex", gap: "8px" }}>
<Button
palette="secondary"
@@ -161,8 +163,9 @@ export function Native() {
) : (
<>
<Checkbox
checked={confirmDev}
value={confirmDev}
onChange={setConfirmDev}
title="I understand there's no going back."
description={
<>
This will change the app to the 'dev' branch,
@@ -178,9 +181,8 @@ export function Native() {
<br />
<code>yarn dev --port 3001</code>
</>
}>
I understand there's no going back.
</Checkbox>
}
/>
<p>
<Button
palette="error"

View File

@@ -4,6 +4,8 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
import { useContext, useEffect, useState } from "preact/hooks";
import { Checkbox } from "@revoltchat/ui";
import { urlBase64ToUint8Array } from "../../../lib/conversion";
import { useApplicationState } from "../../../mobx/State";
@@ -11,8 +13,6 @@ import { useApplicationState } from "../../../mobx/State";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import { AppContext } from "../../../context/revoltjs/RevoltClient";
import Checkbox from "../../../components/ui/Checkbox";
export const Notifications = observer(() => {
const client = useContext(AppContext);
const { openScreen } = useIntermediate();
@@ -38,7 +38,10 @@ export const Notifications = observer(() => {
</h3>
<Checkbox
disabled={!("Notification" in window)}
checked={settings.get("notifications:desktop", false)!}
value={settings.get("notifications:desktop", false)!}
title={
<Text id="app.settings.pages.notifications.enable_desktop" />
}
description={
<Text id="app.settings.pages.notifications.descriptions.enable_desktop" />
}
@@ -56,12 +59,14 @@ export const Notifications = observer(() => {
}
settings.set("notifications:desktop", desktopEnabled);
}}>
<Text id="app.settings.pages.notifications.enable_desktop" />
</Checkbox>
}}
/>
<Checkbox
disabled={typeof pushEnabled === "undefined"}
checked={pushEnabled ?? false}
value={pushEnabled ?? false}
title={
<Text id="app.settings.pages.notifications.enable_push" />
}
description={
<Text id="app.settings.pages.notifications.descriptions.enable_push" />
}
@@ -102,21 +107,24 @@ export const Notifications = observer(() => {
} catch (err) {
console.error("Failed to enable push!", err);
}
}}>
<Text id="app.settings.pages.notifications.enable_push" />
</Checkbox>
}}
/>
<h3>
<Text id="app.settings.pages.notifications.sounds" />
</h3>
{settings.sounds.getState().map(({ id, enabled }) => (
<Checkbox
key={id}
checked={enabled}
value={enabled}
title={
<Text
id={`app.settings.pages.notifications.sound.${id}`}
/>
}
onChange={(enabled) =>
settings.sounds.setEnabled(id, enabled)
}>
<Text id={`app.settings.pages.notifications.sound.${id}`} />
</Checkbox>
}
/>
))}
</div>
);

View File

@@ -485,7 +485,7 @@
}
}
.entry > span > span {
.entry > div div {
gap: 8px;
display: flex;
align-items: center;

View File

@@ -1,15 +1,12 @@
import { Check } from "@styled-icons/boxicons-regular";
import { observer } from "mobx-react-lite";
import styled from "styled-components";
import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
import { Button } from "@revoltchat/ui";
import { Button, Checkbox } from "@revoltchat/ui";
import { useApplicationState } from "../../../mobx/State";
import { CheckboxBase, Checkmark } from "../../../components/ui/Checkbox";
import Tip from "../../../components/ui/Tip";
// Just keeping this here for general purpose. Should probably be exported
@@ -21,45 +18,10 @@ interface Plugin {
enabled: boolean | undefined;
}
const CustomCheckboxBase = styled(CheckboxBase)`
margin-top: 0 !important;
`;
export interface CheckboxProps {
checked: boolean;
disabled?: boolean;
onChange: (state: boolean) => void;
}
function PluginCheckbox(props: CheckboxProps) {
// HACK HACK HACK(lexisother): THIS ENTIRE THING IS A HACK!!!!
/*
Until some reviewer points me in the right direction, I've resorted to
fabricating my own checkbox component.
"WHY?!", you might ask. Well, the normal `Checkbox` component can take
textual contents, and *also* adds a `margin-top` of 20 pixels.
We... don't need that. At all. *Especially* the margin. It makes our card
look disproportionate.
Apologies, @insert!
*/
return (
<CustomCheckboxBase disabled={props.disabled}>
<input
type="checkbox"
checked={props.checked}
onChange={() =>
!props.disabled && props.onChange(!props.checked)
}
/>
<Checkmark checked={props.checked} className="check">
<Check size={20} />
</Checkmark>
</CustomCheckboxBase>
);
}
interface CardProps {
plugin: Plugin;
}
function PluginCard({ plugin }: CardProps) {
const plugins = useApplicationState().plugins;
@@ -70,12 +32,14 @@ function PluginCard({ plugin }: CardProps) {
<div key={plugin.id} className={styles.botCard}>
<div className={styles.infocontainer}>
<div className={styles.infoheader}>
<div className={styles.container}>
{plugin.namespace} / {plugin.id}
</div>
<PluginCheckbox
<Checkbox
key={plugin.id}
checked={plugin.enabled!}
value={plugin.enabled!}
title={
<>
{plugin.namespace} / {plugin.id}
</>
}
onChange={() => {
!plugin.enabled
? plugins.load(plugin.namespace, plugin.id)

View File

@@ -3,11 +3,11 @@ import { observer } from "mobx-react-lite";
import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
import { Checkbox } from "@revoltchat/ui";
import { useApplicationState } from "../../../mobx/State";
import { SyncKeys } from "../../../mobx/stores/Sync";
import Checkbox from "../../../components/ui/Checkbox";
export const Sync = observer(() => {
const sync = useApplicationState().sync;
@@ -30,15 +30,15 @@ export const Sync = observer(() => {
).map(([key, title]) => (
<Checkbox
key={key}
checked={sync.isEnabled(key)}
value={sync.isEnabled(key)}
title={<Text id={`app.settings.pages.${title}`} />}
description={
<Text
id={`app.settings.pages.sync.descriptions.${key}`}
/>
}
onChange={() => sync.toggle(key)}>
<Text id={`app.settings.pages.${title}`} />
</Checkbox>
onChange={() => sync.toggle(key)}
/>
))}
{/*<h5 style={{ marginTop: "20px", color: "grey" }}>
Last sync at 12:00

View File

@@ -9,11 +9,10 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n";
import { useEffect, useMemo, useState } from "preact/hooks";
import { Button, Preloader } from "@revoltchat/ui";
import { Button, Checkbox, Preloader } from "@revoltchat/ui";
import UserIcon from "../../../components/common/user/UserIcon";
import { Username } from "../../../components/common/user/UserShort";
import Checkbox from "../../../components/ui/Checkbox";
import IconButton from "../../../components/ui/IconButton";
import InputBox from "../../../components/ui/InputBox";
import Overline from "../../../components/ui/Overline";
@@ -54,7 +53,15 @@ const Inner = observer(({ member }: InnerProps) => {
return (
<Checkbox
key={key}
checked={roles.includes(key) ?? false}
value={roles.includes(key) ?? false}
title={
<span
style={{
color: role.colour,
}}>
{role.name}
</span>
}
onChange={(v) => {
if (v) {
setRoles([...roles, key]);
@@ -63,14 +70,8 @@ const Inner = observer(({ member }: InnerProps) => {
roles.filter((x) => x !== key),
);
}
}}>
<span
style={{
color: role.colour,
}}>
{role.name}
</span>
</Checkbox>
}}
/>
);
})}
<Button

View File

@@ -5,16 +5,21 @@ import { Server } from "revolt.js";
import { Text } from "preact-i18n";
import { useMemo, useState } from "preact/hooks";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import {
Button,
PermissionsLayout,
SpaceBetween,
H1,
Checkbox,
} from "@revoltchat/ui";
import Checkbox from "../../../components/ui/Checkbox";
import ColourSwatches from "../../../components/ui/ColourSwatches";
import InputBox from "../../../components/ui/InputBox";
import Overline from "../../../components/ui/Overline";
import { Button, PermissionsLayout, SpaceBetween, H1 } from "@revoltchat/ui";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import { PermissionList } from "../../../components/settings/roles/PermissionList";
import { RoleOrDefault } from "../../../components/settings/roles/RoleSelection";
import ColourSwatches from "../../../components/ui/ColourSwatches";
import InputBox from "../../../components/ui/InputBox";
import Overline from "../../../components/ui/Overline";
interface Props {
server: Server;
@@ -169,17 +174,19 @@ export const Roles = observer(({ server }: Props) => {
</Overline>
<p>
<Checkbox
checked={
value={
currentRoleValue.hoist ?? false
}
onChange={(hoist) =>
setValue({ ...value, hoist })
}
title={
<Text id="app.settings.permissions.hoist_role" />
}
description={
<Text id="app.settings.permissions.hoist_desc" />
}>
<Text id="app.settings.permissions.hoist_role" />
</Checkbox>
}
/>
</p>
</section>
<section>