chore: migrate Button to @revoltchat/ui (#617)

* chore: start moving Button over

* fix: convert ServerIdentityModal

* fix: modal button styling

* fix: popover styles

* fix: clean up references to ui/*.*

* fix: button sizing

Co-authored-by: Ed L <beartechtalks@gmail.com>
This commit is contained in:
Paul Makles 2022-05-23 21:21:29 +01:00 committed by GitHub
parent 6fdd701b38
commit be12c6da20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 156 additions and 361 deletions

View file

@ -4,6 +4,7 @@ module.exports = {
jsxBracketSameLine: true, jsxBracketSameLine: true,
importOrder: [ importOrder: [
"preact|classnames|.scss$", "preact|classnames|.scss$",
"^@revoltchat",
"/(lib)", "/(lib)",
"/(redux|mobx)", "/(redux|mobx)",
"/(context)", "/(context)",

View file

@ -6,10 +6,11 @@ import styled from "styled-components/macro";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { useApplicationState } from "../../mobx/State"; import { useApplicationState } from "../../mobx/State";
import { SECTION_NSFW } from "../../mobx/stores/Layout"; import { SECTION_NSFW } from "../../mobx/stores/Layout";
import Button from "../ui/Button";
import Checkbox from "../ui/Checkbox"; import Checkbox from "../ui/Checkbox";
import { Children } from "../../types/Preact"; import { Children } from "../../types/Preact";
@ -85,11 +86,11 @@ export default observer((props: Props) => {
<Text id="app.main.channel.nsfw.confirm" /> <Text id="app.main.channel.nsfw.confirm" />
</Checkbox> </Checkbox>
<div className="actions"> <div className="actions">
<Button contrast onClick={() => history.goBack()}> <Button palette="secondary" onClick={() => history.goBack()}>
<Text id="app.special.modals.actions.back" /> <Text id="app.special.modals.actions.back" />
</Button> </Button>
<Button <Button
contrast palette="secondary"
onClick={() => onClick={() =>
layout.getSectionState(SECTION_NSFW) && setAgeGate(true) layout.getSectionState(SECTION_NSFW) && setAgeGate(true)
}> }>

View file

@ -7,6 +7,8 @@ import styled, { css } from "styled-components/macro";
import { useContext, useEffect, useState } from "preact/hooks"; import { useContext, useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { isTouchscreenDevice } from "../../../../lib/isTouchscreenDevice"; import { isTouchscreenDevice } from "../../../../lib/isTouchscreenDevice";
import { import {
@ -17,7 +19,6 @@ import {
import { takeError } from "../../../../context/revoltjs/util"; import { takeError } from "../../../../context/revoltjs/util";
import ServerIcon from "../../../../components/common/ServerIcon"; import ServerIcon from "../../../../components/common/ServerIcon";
import Button from "../../../../components/ui/Button";
import Overline from "../../../ui/Overline"; import Overline from "../../../ui/Overline";
import Preloader from "../../../ui/Preloader"; import Preloader from "../../../ui/Preloader";

View file

@ -5,10 +5,11 @@ import styled from "styled-components/macro";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { useClient } from "../../../context/revoltjs/RevoltClient"; import { useClient } from "../../../context/revoltjs/RevoltClient";
import Message from "../../common/messaging/Message"; import Message from "../../common/messaging/Message";
import Button from "../../ui/Button";
import InputBox from "../../ui/InputBox"; import InputBox from "../../ui/InputBox";
import Overline from "../../ui/Overline"; import Overline from "../../ui/Overline";
import Preloader from "../../ui/Preloader"; import Preloader from "../../ui/Preloader";
@ -118,7 +119,7 @@ export function SearchSidebar({ close }: Props) {
<Button <Button
key={key} key={key}
compact compact
accent={sort === key} palette={sort === key ? "accent" : "primary"}
onClick={() => setSort(key as Sort)}> onClick={() => setSort(key as Sort)}>
<Text <Text
id={`app.main.channel.search.sort.${key.toLowerCase()}`} id={`app.main.channel.search.sort.${key.toLowerCase()}`}

View file

@ -3,12 +3,13 @@ import styled from "styled-components/macro";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { Button } from "@revoltchat/ui";
import { useApplicationState } from "../../../mobx/State"; import { useApplicationState } from "../../../mobx/State";
import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { useIntermediate } from "../../../context/intermediate/Intermediate";
import Tooltip from "../../common/Tooltip"; import Tooltip from "../../common/Tooltip";
import Button from "../../ui/Button";
const Actions = styled.div` const Actions = styled.div`
gap: 8px; gap: 8px;
@ -46,7 +47,10 @@ export default function ThemeTools() {
content={ content={
<Text id="app.settings.pages.appearance.reset_overrides" /> <Text id="app.settings.pages.appearance.reset_overrides" />
}> }>
<Button contrast iconbutton onClick={theme.reset}> <Button
palette="secondary"
compact="icon"
onClick={theme.reset}>
<Reset size={22} /> <Reset size={22} />
</Button> </Button>
</Tooltip> </Tooltip>
@ -61,8 +65,8 @@ export default function ThemeTools() {
<Tooltip <Tooltip
content={<Text id="app.settings.pages.appearance.import" />}> content={<Text id="app.settings.pages.appearance.import" />}>
<Button <Button
contrast palette="secondary"
iconbutton compact="icon"
onClick={async () => { onClick={async () => {
try { try {
const text = await navigator.clipboard.readText(); const text = await navigator.clipboard.readText();

View file

@ -1,148 +0,0 @@
import styled, { css } from "styled-components/macro";
interface Props {
readonly compact?: boolean;
readonly accent?: boolean;
readonly contrast?: boolean;
readonly plain?: boolean;
readonly error?: boolean;
readonly gold?: boolean;
readonly iconbutton?: boolean;
}
export type ButtonProps = Props &
Omit<JSX.HTMLAttributes<HTMLButtonElement>, "as">;
export default styled.button<Props>`
//z-index: 1;
display: flex;
height: 38px;
min-width: 96px;
align-items: center;
justify-content: center;
padding: 2px 16px;
font-size: 0.8125rem;
font-family: inherit;
font-weight: 500;
flex-shrink: 0;
transition: 0.2s ease opacity;
transition: 0.2s ease background-color;
background: var(--primary-background);
color: var(--foreground);
border-radius: var(--border-radius);
cursor: pointer;
border: none;
&:hover {
background: var(--secondary-header);
}
&:disabled {
cursor: not-allowed;
background: var(--primary-background);
}
&:active {
background: var(--secondary-background);
}
${(props) =>
props.compact &&
css`
height: 32px !important;
padding: 2px 12px !important;
font-size: 13px;
`}
${(props) =>
props.iconbutton &&
css`
height: 38px !important;
width: 38px !important;
min-width: unset !important;
`}
${(props) =>
props.accent &&
css`
background: var(--accent) !important;
`}
${(props) =>
props.plain &&
css`
background: transparent !important;
&:hover {
text-decoration: underline;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&:active {
background: var(--secondary-background);
}
`}
${(props) =>
props.contrast &&
css`
padding: 4px 8px;
background: var(--secondary-header);
&:hover {
background: var(--primary-header);
}
&:disabled {
cursor: not-allowed;
background: var(--secondary-header);
}
&:active {
background: var(--secondary-background);
}
`}
${(props) =>
props.error &&
css`
color: white;
font-weight: 600;
background: var(--error);
&:hover {
filter: brightness(1.2);
background: var(--error);
}
&:disabled {
cursor: not-allowed;
background: var(--error);
}
`}
${(props) =>
props.gold &&
css`
color: black;
font-weight: 600;
background: goldenrod;
&:hover {
filter: brightness(1.2);
background: goldenrod;
}
&:disabled {
cursor: not-allowed;
background: goldenrod;
}
`}
`;

View file

@ -3,10 +3,12 @@ import styled, { css, keyframes } from "styled-components/macro";
import { createPortal, useCallback, useEffect, useState } from "preact/compat"; import { createPortal, useCallback, useEffect, useState } from "preact/compat";
import { Button } from "@revoltchat/ui";
import { Props as ButtonProps } from "@revoltchat/ui/esm/components/design/atoms/inputs/Button";
import { internalSubscribe } from "../../lib/eventEmitter"; import { internalSubscribe } from "../../lib/eventEmitter";
import { Children } from "../../types/Preact"; import { Children } from "../../types/Preact";
import Button, { ButtonProps } from "./Button";
const open = keyframes` const open = keyframes`
0% {opacity: 0;} 0% {opacity: 0;}
@ -145,7 +147,11 @@ const ModalActions = styled.div`
border-radius: 0 0 var(--border-radius) var(--border-radius); border-radius: 0 0 var(--border-radius) var(--border-radius);
`; `;
export type Action = Omit<ButtonProps, "onClick"> & { export type Action = Omit<
JSX.HTMLAttributes<HTMLButtonElement>,
"as" | "onClick"
> & {
palette?: ButtonProps["palette"];
confirmation?: boolean; confirmation?: boolean;
onClick: () => void; onClick: () => void;
}; };
@ -163,6 +169,7 @@ interface Props {
onClose?: () => void; onClose?: () => void;
actions?: Action[]; actions?: Action[];
disabled?: boolean; disabled?: boolean;
palette?: ButtonProps["palette"];
border?: boolean; border?: boolean;
visible: boolean; visible: boolean;
} }
@ -241,6 +248,7 @@ export default function Modal(props: Props) {
<ModalActions> <ModalActions>
{props.actions.map((x, index) => ( {props.actions.map((x, index) => (
<Button <Button
palette={props.palette}
key={index} key={index}
{...x} {...x}
disabled={props.disabled} disabled={props.disabled}

View file

@ -27,8 +27,7 @@ export function ExternalLinkModal({ onClose, link }: Props) {
onClose(); onClose();
}, },
confirmation: true, confirmation: true,
contrast: true, palette: "accent",
accent: true,
children: "Continue", children: "Continue",
}, },
{ {
@ -46,7 +45,7 @@ export function ExternalLinkModal({ onClose, link }: Props) {
openLink(link, true); openLink(link, true);
onClose(); onClose();
}, },
plain: true, palette: "plain",
children: ( children: (
<Text id="app.special.modals.external_links.trust_domain" /> <Text id="app.special.modals.external_links.trust_domain" />
), ),

View file

@ -4,7 +4,8 @@ import styles from "./Onboarding.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import Button from "../../../components/ui/Button"; import { Button } from "@revoltchat/ui";
import Preloader from "../../../components/ui/Preloader"; import Preloader from "../../../components/ui/Preloader";
import wideSVG from "/assets/wide.svg"; import wideSVG from "/assets/wide.svg";

View file

@ -135,8 +135,7 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
actions={[ actions={[
{ {
confirmation: true, confirmation: true,
contrast: true, palette: "error",
error: true,
children: ( children: (
<Text <Text
id={`app.special.modals.actions.${event[1]}`} id={`app.special.modals.actions.${event[1]}`}
@ -201,8 +200,7 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
actions={[ actions={[
{ {
confirmation: true, confirmation: true,
contrast: true, palette: "error",
error: true,
children: ( children: (
<Text id="app.special.modals.actions.delete" /> <Text id="app.special.modals.actions.delete" />
), ),
@ -223,7 +221,7 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
<Text id="app.special.modals.actions.cancel" /> <Text id="app.special.modals.actions.cancel" />
), ),
onClick: onClose, onClick: onClose,
plain: true, palette: "plain",
}, },
]} ]}
content={ content={
@ -304,8 +302,7 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
children: ( children: (
<Text id="app.special.modals.actions.kick" /> <Text id="app.special.modals.actions.kick" />
), ),
contrast: true, palette: "error",
error: true,
confirmation: true, confirmation: true,
onClick: async () => { onClick: async () => {
setProcessing(true); setProcessing(true);
@ -358,8 +355,8 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
children: ( children: (
<Text id="app.special.modals.actions.ban" /> <Text id="app.special.modals.actions.ban" />
), ),
contrast: true, palette: "error",
error: true,
confirmation: true, confirmation: true,
onClick: async () => { onClick: async () => {
setProcessing(true); setProcessing(true);
@ -417,7 +414,8 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
actions={[ actions={[
{ {
confirmation: true, confirmation: true,
contrast: true, palette: "secondary",
children: ( children: (
<Text id="app.special.modals.actions.create" /> <Text id="app.special.modals.actions.create" />
), ),
@ -492,7 +490,7 @@ export const SpecialPromptModal = observer((props: SpecialProps) => {
actions={[ actions={[
{ {
confirmation: true, confirmation: true,
contrast: true, palette: "secondary",
children: ( children: (
<Text id="app.special.modals.actions.create" /> <Text id="app.special.modals.actions.create" />
), ),

View file

@ -7,32 +7,31 @@ interface Props {
confirm: () => void; confirm: () => void;
} }
export function SessionsModal({ onClose, confirm}: Props) { export function SessionsModal({ onClose, confirm }: Props) {
return ( return (
<Modal <Modal
visible={true} visible={true}
onClose={onClose} onClose={onClose}
title={<Text id={"app.special.modals.sessions.title"} />} title={<Text id={"app.special.modals.sessions.title"} />}
actions={[ actions={[
{ {
onClick: () => { onClick: () => {
onClose() onClose();
},
confirmation: true,
palette: "accent",
children: <Text id="app.special.modals.actions.back" />,
}, },
confirmation: true, {
contrast: true, onClick: () => {
accent: true, confirm();
children: <Text id="app.special.modals.actions.back"/> onClose();
}, },
{ confirmation: true,
onClick: () => { children: <Text id="app.special.modals.sessions.accept" />,
confirm()
onClose()
}, },
confirmation: true, ]}>
children: <Text id="app.special.modals.sessions.accept"/> <Text id="app.special.modals.sessions.short" /> <br />
}
]}>
<Text id="app.special.modals.sessions.short" /> <br />
</Modal> </Modal>
) );
} }

View file

@ -43,13 +43,12 @@ export function CreateBotModal({ onClose, onCreate }: Props) {
actions={[ actions={[
{ {
confirmation: true, confirmation: true,
contrast: true, palette: "accent",
accent: true,
onClick: handleSubmit(onSubmit), onClick: handleSubmit(onSubmit),
children: <Text id="app.special.modals.actions.create" />, children: <Text id="app.special.modals.actions.create" />,
}, },
{ {
plain: true, palette: "plain",
onClick: onClose, onClick: onClose,
children: <Text id="app.special.modals.actions.cancel" />, children: <Text id="app.special.modals.actions.cancel" />,
}, },

View file

@ -88,7 +88,7 @@ export function ModifyAccountModal({ onClose, field }: Props) {
{ {
onClick: onClose, onClick: onClose,
children: <Text id="app.special.modals.actions.cancel" />, children: <Text id="app.special.modals.actions.cancel" />,
plain: true, palette: "plain",
}, },
]}> ]}>
{/* Preact / React typing incompatabilities */} {/* Preact / React typing incompatabilities */}

View file

@ -5,9 +5,10 @@ import styles from "./ServerIdentityModal.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { noop } from "../../../lib/js"; import { noop } from "../../../lib/js";
import Button from "../../../components/ui/Button";
import InputBox from "../../../components/ui/InputBox"; import InputBox from "../../../components/ui/InputBox";
import Modal from "../../../components/ui/Modal"; import Modal from "../../../components/ui/Modal";
import Overline from "../../../components/ui/Overline"; import Overline from "../../../components/ui/Overline";
@ -95,7 +96,7 @@ export const ServerIdentityModal = observer(({ server, onClose }: Props) => {
</Button> </Button>
{currentNickname !== "" && ( {currentNickname !== "" && (
<Button <Button
plain palette="plain"
onClick={() => onClick={() =>
member.edit({ remove: ["Nickname"] }) member.edit({ remove: ["Nickname"] })
}> }>

View file

@ -15,6 +15,8 @@ import styles from "./UserProfile.module.scss";
import { Localizer, Text } from "preact-i18n"; import { Localizer, Text } from "preact-i18n";
import { useContext, useEffect, useLayoutEffect, useState } from "preact/hooks"; import { useContext, useEffect, useLayoutEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { noop } from "../../../lib/js"; import { noop } from "../../../lib/js";
import ChannelIcon from "../../../components/common/ChannelIcon"; import ChannelIcon from "../../../components/common/ChannelIcon";
@ -24,7 +26,6 @@ import UserBadges from "../../../components/common/user/UserBadges";
import UserIcon from "../../../components/common/user/UserIcon"; import UserIcon from "../../../components/common/user/UserIcon";
import { Username } from "../../../components/common/user/UserShort"; import { Username } from "../../../components/common/user/UserShort";
import UserStatus from "../../../components/common/user/UserStatus"; import UserStatus from "../../../components/common/user/UserStatus";
import Button from "../../../components/ui/Button";
import IconButton from "../../../components/ui/IconButton"; import IconButton from "../../../components/ui/IconButton";
import Modal from "../../../components/ui/Modal"; import Modal from "../../../components/ui/Modal";
import Overline from "../../../components/ui/Overline"; import Overline from "../../../components/ui/Overline";
@ -195,7 +196,10 @@ export const UserProfile = observer(
</div> </div>
{isPublicBot && ( {isPublicBot && (
<Link to={`/bot/${user._id}`}> <Link to={`/bot/${user._id}`}>
<Button accent compact onClick={onClose}> <Button
palette="accent"
compact
onClick={onClose}>
Add to server Add to server
</Button> </Button>
</Link> </Link>

View file

@ -6,14 +6,14 @@ import {
VolumeFull, VolumeFull,
VolumeMute, VolumeMute,
} from "@styled-icons/boxicons-solid"; } from "@styled-icons/boxicons-solid";
import { Hashnode, Speakerdeck, Teamspeak } from "@styled-icons/simple-icons";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import styled from "styled-components/macro"; import styled from "styled-components/macro";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useMemo } from "preact/hooks"; import { useMemo } from "preact/hooks";
import VoiceClient from "../../../lib/vortex/VoiceClient"; import { Button } from "@revoltchat/ui";
import { voiceState, VoiceStatus } from "../../../lib/vortex/VoiceState"; import { voiceState, VoiceStatus } from "../../../lib/vortex/VoiceState";
import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { useIntermediate } from "../../../context/intermediate/Intermediate";
@ -21,7 +21,6 @@ import { useClient } from "../../../context/revoltjs/RevoltClient";
import Tooltip from "../../../components/common/Tooltip"; import Tooltip from "../../../components/common/Tooltip";
import UserIcon from "../../../components/common/user/UserIcon"; import UserIcon from "../../../components/common/user/UserIcon";
import Button from "../../../components/ui/Button";
interface Props { interface Props {
id: string; id: string;
@ -145,7 +144,7 @@ export default observer(({ id }: Props) => {
</div> </div>
<div className="actions"> <div className="actions">
<Tooltip content={"Leave call"} placement={"top"}> <Tooltip content={"Leave call"} placement={"top"}>
<Button error onClick={voiceState.disconnect}> <Button palette="error" onClick={voiceState.disconnect}>
<PhoneOff width={20} /> <PhoneOff width={20} />
</Button> </Button>
</Tooltip> </Tooltip>

View file

@ -7,6 +7,8 @@ import styles from "./Invite.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useContext, useEffect, useState } from "preact/hooks"; import { useContext, useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { defer } from "../../lib/defer"; import { defer } from "../../lib/defer";
import { TextReact } from "../../lib/i18n"; import { TextReact } from "../../lib/i18n";
@ -22,7 +24,6 @@ import { takeError } from "../../context/revoltjs/util";
import ServerIcon from "../../components/common/ServerIcon"; import ServerIcon from "../../components/common/ServerIcon";
import UserIcon from "../../components/common/user/UserIcon"; import UserIcon from "../../components/common/user/UserIcon";
import Button from "../../components/ui/Button";
import Overline from "../../components/ui/Overline"; import Overline from "../../components/ui/Overline";
import Preloader from "../../components/ui/Preloader"; import Preloader from "../../components/ui/Preloader";
@ -71,7 +72,7 @@ export default function Invite() {
<Text id="app.special.invite.invalid_desc" /> <Text id="app.special.invite.invalid_desc" />
</h2> </h2>
<div style="cursor: pointer;"> <div style="cursor: pointer;">
<Button contrast> <Button palette="secondary">
<ArrowBack <ArrowBack
size={32} size={32}
onClick={() => onClick={() =>
@ -152,7 +153,7 @@ export default function Invite() {
</h3> </h3>
<Overline type="error" error={error} /> <Overline type="error" error={error} />
<Button <Button
contrast palette="secondary"
onClick={async () => { onClick={async () => {
if (status === ClientStatus.READY) { if (status === ClientStatus.READY) {
return history.push("/"); return history.push("/");

View file

@ -1,13 +1,14 @@
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { API, Permission } from "revolt.js"; import { API } from "revolt.js";
import styled from "styled-components/macro"; import styled from "styled-components/macro";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { useClient } from "../../context/revoltjs/RevoltClient"; import { useClient } from "../../context/revoltjs/RevoltClient";
import UserIcon from "../../components/common/user/UserIcon"; import UserIcon from "../../components/common/user/UserIcon";
import Button from "../../components/ui/Button";
import ComboBox from "../../components/ui/ComboBox"; import ComboBox from "../../components/ui/ComboBox";
import Overline from "../../components/ui/Overline"; import Overline from "../../components/ui/Overline";
import Preloader from "../../components/ui/Preloader"; import Preloader from "../../components/ui/Preloader";
@ -78,7 +79,7 @@ export default function InviteBot() {
))} ))}
</ComboBox> </ComboBox>
<Button <Button
contrast palette="secondary"
onClick={() => onClick={() =>
server !== "none" && server !== "none" &&
client.bots.invite(data._id, { server }) client.bots.invite(data._id, { server })
@ -103,7 +104,7 @@ export default function InviteBot() {
))} ))}
</ComboBox> </ComboBox>
<Button <Button
contrast palette="secondary"
onClick={() => onClick={() =>
group !== "none" && group !== "none" &&
client.bots.invite(data._id, { group }) client.bots.invite(data._id, { group })

View file

@ -1,18 +1,17 @@
import { CheckCircle, Envelope } from "@styled-icons/boxicons-regular";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import styles from "../Login.module.scss"; import styles from "../Login.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useContext, useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { useApplicationState } from "../../../mobx/State"; import { useApplicationState } from "../../../mobx/State";
import { AppContext } from "../../../context/revoltjs/RevoltClient";
import { takeError } from "../../../context/revoltjs/util"; import { takeError } from "../../../context/revoltjs/util";
import Button from "../../../components/ui/Button";
import Overline from "../../../components/ui/Overline"; import Overline from "../../../components/ui/Overline";
import Preloader from "../../../components/ui/Preloader"; import Preloader from "../../../components/ui/Preloader";
import WaveSVG from "../../settings/assets/wave.svg"; import WaveSVG from "../../settings/assets/wave.svg";
@ -146,10 +145,22 @@ export const Form = observer(({ page, callback }: Props) => {
<div className={styles.welcome}> <div className={styles.welcome}>
<div className={styles.title}> <div className={styles.title}>
<img src={WaveSVG} draggable={false} /> <img src={WaveSVG} draggable={false} />
<Text id={page === "create" ? "login.welcome2" : "login.welcome"} /> <Text
id={
page === "create"
? "login.welcome2"
: "login.welcome"
}
/>
</div> </div>
<div className={styles.subtitle}> <div className={styles.subtitle}>
<Text id={page === "create" ? "login.subtitle2" : "login.subtitle"} /> <Text
id={
page === "create"
? "login.subtitle2"
: "login.subtitle"
}
/>
<div>(app.revolt.chat)</div> <div>(app.revolt.chat)</div>
</div> </div>
</div> </div>

View file

@ -1,7 +1,7 @@
import styles from "../Login.module.scss"; import styles from "../Login.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import Button from "../../../components/ui/Button"; import { Button } from "@revoltchat/ui";
interface Props { interface Props {
email?: string; email?: string;

View file

@ -5,11 +5,12 @@ import styled from "styled-components/macro";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { FileUploader } from "../../../context/revoltjs/FileUploads"; import { FileUploader } from "../../../context/revoltjs/FileUploads";
import Button from "../../../components/ui/Button";
import Checkbox from "../../../components/ui/Checkbox"; import Checkbox from "../../../components/ui/Checkbox";
import InputBox from "../../../components/ui/InputBox"; import InputBox from "../../../components/ui/InputBox";
@ -129,7 +130,7 @@ export default observer(({ channel }: Props) => {
</Checkbox> </Checkbox>
)} )}
<p> <p>
<Button onClick={save} contrast disabled={!changed}> <Button onClick={save} palette="secondary" disabled={!changed}>
<Text id="app.special.modals.actions.save" /> <Text id="app.special.modals.actions.save" />
</Button> </Button>
</p> </p>

View file

@ -14,6 +14,8 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useContext, useEffect, useState } from "preact/hooks"; import { useContext, useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import { stopPropagation } from "../../../lib/stopPropagation"; import { stopPropagation } from "../../../lib/stopPropagation";
import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { useIntermediate } from "../../../context/intermediate/Intermediate";
@ -25,7 +27,6 @@ import {
import Tooltip from "../../../components/common/Tooltip"; import Tooltip from "../../../components/common/Tooltip";
import UserIcon from "../../../components/common/user/UserIcon"; import UserIcon from "../../../components/common/user/UserIcon";
import Button from "../../../components/ui/Button";
import Tip from "../../../components/ui/Tip"; import Tip from "../../../components/ui/Tip";
import CategoryButton from "../../../components/ui/fluent/CategoryButton"; import CategoryButton from "../../../components/ui/fluent/CategoryButton";
@ -101,7 +102,9 @@ export const Account = observer(() => {
</div> </div>
</div> </div>
<Button onClick={() => switchPage("profile")} contrast> <Button
onClick={() => switchPage("profile")}
palette="secondary">
<Text id="app.settings.pages.profile.edit_profile" /> <Text id="app.settings.pages.profile.edit_profile" />
</Button> </Button>
</div> </div>

View file

@ -2,11 +2,11 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { TextReact } from "../../../lib/i18n"; import { Button } from "@revoltchat/ui";
import { stopPropagation } from "../../../lib/stopPropagation"; import { stopPropagation } from "../../../lib/stopPropagation";
import { voiceState } from "../../../lib/vortex/VoiceState"; import { voiceState } from "../../../lib/vortex/VoiceState";
import Button from "../../../components/ui/Button";
import ComboBox from "../../../components/ui/ComboBox"; import ComboBox from "../../../components/ui/ComboBox";
import Overline from "../../../components/ui/Overline"; import Overline from "../../../components/ui/Overline";
import Tip from "../../../components/ui/Tip"; import Tip from "../../../components/ui/Tip";
@ -162,8 +162,10 @@ export function Audio() {
{!permission && ( {!permission && (
<Button <Button
compact compact
onClick={(e) => handleAskForPermission(e)} onClick={(e: any) =>
error> handleAskForPermission(e)
}
palette="error">
<Text id="app.settings.pages.audio.button_grant" /> <Text id="app.settings.pages.audio.button_grant" />
</Button> </Button>
)} )}

View file

@ -11,6 +11,8 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useCallback, useEffect, useState } from "preact/hooks"; import { useCallback, useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { internalEmit } from "../../../lib/eventEmitter"; import { internalEmit } from "../../../lib/eventEmitter";
import { useTranslation } from "../../../lib/i18n"; import { useTranslation } from "../../../lib/i18n";
@ -26,7 +28,6 @@ import AutoComplete, {
import CollapsibleSection from "../../../components/common/CollapsibleSection"; import CollapsibleSection from "../../../components/common/CollapsibleSection";
import Tooltip from "../../../components/common/Tooltip"; import Tooltip from "../../../components/common/Tooltip";
import UserIcon from "../../../components/common/user/UserIcon"; import UserIcon from "../../../components/common/user/UserIcon";
import Button from "../../../components/ui/Button";
import Checkbox from "../../../components/ui/Checkbox"; import Checkbox from "../../../components/ui/Checkbox";
import InputBox from "../../../components/ui/InputBox"; import InputBox from "../../../components/ui/InputBox";
import Tip from "../../../components/ui/Tip"; import Tip from "../../../components/ui/Tip";
@ -343,7 +344,7 @@ function BotCard({ bot, onDelete, onUpdate }: Props) {
setEditMode(false); setEditMode(false);
} else setEditMode(true); } else setEditMode(true);
}} }}
contrast> palette="secondary">
<Text <Text
id={`app.special.modals.actions.${ id={`app.special.modals.actions.${
editMode ? "cancel" : "edit" editMode ? "cancel" : "edit"
@ -479,7 +480,7 @@ function BotCard({ bot, onDelete, onUpdate }: Props) {
<Text id="app.special.modals.actions.save" /> <Text id="app.special.modals.actions.save" />
</Button> </Button>
<Button <Button
error palette="error"
onClick={async () => { onClick={async () => {
setSaving(true); setSaving(true);
openScreen({ openScreen({

View file

@ -2,7 +2,8 @@ import { Refresh } from "@styled-icons/boxicons-regular";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import Button from "../../../components/ui/Button"; import { Button } from "@revoltchat/ui";
import Checkbox from "../../../components/ui/Checkbox"; import Checkbox from "../../../components/ui/Checkbox";
import Tip from "../../../components/ui/Tip"; import Tip from "../../../components/ui/Tip";
import CategoryButton from "../../../components/ui/fluent/CategoryButton"; import CategoryButton from "../../../components/ui/fluent/CategoryButton";
@ -129,14 +130,14 @@ export function Native() {
</Checkbox> </Checkbox>
<p style={{ display: "flex", gap: "8px" }}> <p style={{ display: "flex", gap: "8px" }}>
<Button <Button
contrast palette="secondary"
compact compact
disabled={!hintReload} disabled={!hintReload}
onClick={window.native.reload}> onClick={window.native.reload}>
Reload Page Reload Page
</Button> </Button>
<Button <Button
contrast palette="secondary"
compact compact
disabled={!hintRelaunch} disabled={!hintRelaunch}
onClick={window.native.relaunch}> onClick={window.native.relaunch}>
@ -148,7 +149,7 @@ export function Native() {
<> <>
<h5>Development mode is currently on.</h5> <h5>Development mode is currently on.</h5>
<Button <Button
contrast palette="secondary"
compact compact
onClick={() => { onClick={() => {
window.native.set("build", "stable"); window.native.set("build", "stable");
@ -182,7 +183,7 @@ export function Native() {
</Checkbox> </Checkbox>
<p> <p>
<Button <Button
error palette="error"
compact compact
disabled={!confirmDev} disabled={!confirmDev}
onClick={() => { onClick={() => {

View file

@ -5,9 +5,10 @@ import styled from "styled-components";
import styles from "./Panes.module.scss"; import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { Button } from "@revoltchat/ui";
import { useApplicationState } from "../../../mobx/State"; import { useApplicationState } from "../../../mobx/State";
import Button from "../../../components/ui/Button";
import { CheckboxBase, Checkmark } from "../../../components/ui/Checkbox"; import { CheckboxBase, Checkmark } from "../../../components/ui/Checkbox";
import Tip from "../../../components/ui/Tip"; import Tip from "../../../components/ui/Tip";
@ -88,7 +89,7 @@ function PluginCard({ plugin }: CardProps) {
</div> </div>
<div className={styles.buttonRow}> <div className={styles.buttonRow}>
<Button <Button
error palette="error"
onClick={() => onClick={() =>
plugins.remove(plugin.namespace, plugin.id) plugins.remove(plugin.namespace, plugin.id)
}> }>

View file

@ -7,6 +7,8 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useCallback, useContext, useEffect, useState } from "preact/hooks"; import { useCallback, useContext, useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { useTranslation } from "../../../lib/i18n"; import { useTranslation } from "../../../lib/i18n";
@ -21,7 +23,6 @@ import {
import AutoComplete, { import AutoComplete, {
useAutoComplete, useAutoComplete,
} from "../../../components/common/AutoComplete"; } from "../../../components/common/AutoComplete";
import Button from "../../../components/ui/Button";
import Tip from "../../../components/ui/Tip"; import Tip from "../../../components/ui/Tip";
export const Profile = observer(() => { export const Profile = observer(() => {
@ -191,7 +192,7 @@ export const Profile = observer(() => {
</div> </div>
<p> <p>
<Button <Button
contrast palette="secondary"
onClick={() => { onClick={() => {
setChanged(false); setChanged(false);
client.users.edit({ client.users.edit({

View file

@ -18,11 +18,12 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useContext, useEffect, useState } from "preact/hooks"; import { useContext, useEffect, useState } from "preact/hooks";
import { dayjs } from "../../../context/Locale"; import { Button } from "@revoltchat/ui";
import { AppContext } from "../../../context/revoltjs/RevoltClient";
import { useIntermediate } from "../../../context/intermediate/Intermediate"; import { dayjs } from "../../../context/Locale";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import { AppContext } from "../../../context/revoltjs/RevoltClient";
import Button from "../../../components/ui/Button";
import Preloader from "../../../components/ui/Preloader"; import Preloader from "../../../components/ui/Preloader";
import Tip from "../../../components/ui/Tip"; import Tip from "../../../components/ui/Tip";
import CategoryButton from "../../../components/ui/fluent/CategoryButton"; import CategoryButton from "../../../components/ui/fluent/CategoryButton";
@ -229,12 +230,16 @@ export function Sessions() {
setDelete(del); setDelete(del);
for (const id of del) { for (const id of del) {
await client.api.delete(`/auth/session/${id as ""}`); await client.api.delete(
`/auth/session/${id as ""}`,
);
} }
setSessions(sessions.filter((x) => x._id === deviceId)); setSessions(
} sessions.filter((x) => x._id === deviceId),
}) );
},
});
}} }}
icon={<LogOut size={24} color={"var(--error)"} />} icon={<LogOut size={24} color={"var(--error)"} />}
action={"chevron"} action={"chevron"}
@ -255,4 +260,3 @@ export function Sessions() {
</div> </div>
); );
} }

View file

@ -9,14 +9,14 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useEffect, useMemo, useState } from "preact/hooks"; import { useEffect, useMemo, useState } from "preact/hooks";
import { Button, Preloader } from "@revoltchat/ui";
import UserIcon from "../../../components/common/user/UserIcon"; import UserIcon from "../../../components/common/user/UserIcon";
import { Username } from "../../../components/common/user/UserShort"; import { Username } from "../../../components/common/user/UserShort";
import Button from "../../../components/ui/Button";
import Checkbox from "../../../components/ui/Checkbox"; import Checkbox from "../../../components/ui/Checkbox";
import IconButton from "../../../components/ui/IconButton"; import IconButton from "../../../components/ui/IconButton";
import InputBox from "../../../components/ui/InputBox"; import InputBox from "../../../components/ui/InputBox";
import Overline from "../../../components/ui/Overline"; import Overline from "../../../components/ui/Overline";
import { Preloader } from "@revoltchat/ui";
interface InnerProps { interface InnerProps {
member: Member; member: Member;
@ -74,7 +74,7 @@ const Inner = observer(({ member }: InnerProps) => {
); );
})} })}
<Button <Button
compact palette="secondary"
disabled={isEqual(member.roles ?? [], roles)} disabled={isEqual(member.roles ?? [], roles)}
onClick={() => onClick={() =>
member.edit({ member.edit({

View file

@ -7,13 +7,14 @@ import styles from "./Panes.module.scss";
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Button } from "@revoltchat/ui";
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize"; import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { noop } from "../../../lib/js"; import { noop } from "../../../lib/js";
import { FileUploader } from "../../../context/revoltjs/FileUploads"; import { FileUploader } from "../../../context/revoltjs/FileUploads";
import { getChannelName } from "../../../context/revoltjs/util"; import { getChannelName } from "../../../context/revoltjs/util";
import Button from "../../../components/ui/Button";
import ComboBox from "../../../components/ui/ComboBox"; import ComboBox from "../../../components/ui/ComboBox";
import InputBox from "../../../components/ui/InputBox"; import InputBox from "../../../components/ui/InputBox";
@ -182,7 +183,7 @@ export const Overview = observer(({ server }: Props) => {
))} ))}
<p> <p>
<Button onClick={save} contrast disabled={!changed}> <Button onClick={save} palette="secondary" disabled={!changed}>
<Text id="app.special.modals.actions.save" /> <Text id="app.special.modals.actions.save" />
</Button> </Button>
</p> </p>

View file

@ -19,5 +19,5 @@
"types": ["vite-plugin-pwa/client"], "types": ["vite-plugin-pwa/client"],
"experimentalDecorators": true "experimentalDecorators": true
}, },
"include": ["src", "ui/ui.tsx", "external/lang/Languages.ts"] "include": ["src", "external/lang/Languages.ts"]
} }

View file

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Revolt UI</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/ui/ui.tsx"></script>
</body>
</html>

View file

@ -1,87 +0,0 @@
import styled from "styled-components/macro";
import "../src/styles/index.scss";
import { render } from "preact";
import { useState } from "preact/hooks";
import Theme from "../src/context/Theme";
import Banner from "../src/components/ui/Banner";
import Button from "../src/components/ui/Button";
import Checkbox from "../src/components/ui/Checkbox";
import ColourSwatches from "../src/components/ui/ColourSwatches";
import ComboBox from "../src/components/ui/ComboBox";
import InputBox from "../src/components/ui/InputBox";
import Overline from "../src/components/ui/Overline";
import Radio from "../src/components/ui/Radio";
import Tip from "../src/components/ui/Tip";
export const UIDemo = styled.div`
gap: 12px;
padding: 12px;
display: flex;
flex-direction: column;
align-items: flex-start;
`;
export function UI() {
let [checked, setChecked] = useState(false);
let [colour, setColour] = useState("#FD6671");
let [selected, setSelected] = useState<"a" | "b" | "c">("a");
return (
<>
<Button>Button (normal)</Button>
<Button contrast>Button (contrast)</Button>
<Button error>Button (error)</Button>
<Button contrast error>
Button (contrast + error)
</Button>
<Banner>I am a banner!</Banner>
<Checkbox
checked={checked}
onChange={setChecked}
description="ok gamer">
Do you want thing??
</Checkbox>
<ComboBox>
<option>Select an option.</option>
<option>1</option>
<option>2</option>
<option>3</option>
</ComboBox>
<InputBox placeholder="Normal input box..." />
<InputBox placeholder="Contrast input box..." contrast />
<InputBox value="Input box with value" />
<InputBox value="Contrast with value" contrast />
<ColourSwatches value={colour} onChange={(v) => setColour(v)} />
<Tip hideSeparator>I am a tip! I provide valuable information.</Tip>
<Radio checked={selected === "a"} onSelect={() => setSelected("a")}>
First option
</Radio>
<Radio checked={selected === "b"} onSelect={() => setSelected("b")}>
Second option
</Radio>
<Radio checked={selected === "c"} onSelect={() => setSelected("c")}>
Last option
</Radio>
<Overline>Normal overline</Overline>
<Overline type="subtle">Subtle overline</Overline>
<Overline type="error">Error overline</Overline>
<Overline error="with error">Normal overline</Overline>
<Overline type="subtle" error="with error">
Subtle overline
</Overline>
</>
);
}
render(
<>
<UIDemo>
<UI />
</UIDemo>
<Theme />
</>,
document.getElementById("app")!,
);

View file

@ -119,7 +119,6 @@ export default defineConfig({
rollupOptions: { rollupOptions: {
input: { input: {
main: resolve(__dirname, "index.html"), main: resolve(__dirname, "index.html"),
ui: resolve(__dirname, "ui/index.html"),
}, },
}, },
}, },