Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(flat-components): add appearance picker component #1373

Merged
merged 2 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import "./style.less";

import { Checkbox, Radio } from "antd";
import type { CheckboxChangeEvent } from "antd/lib/checkbox";
import React, { useEffect, useState } from "react";
import { Checkbox, Radio, RadioChangeEvent } from "antd";
import React, { useContext, useEffect, useState } from "react";
import { UserSettingLayoutContainer } from "../UserSettingLayoutContainer";
import { ipcSyncByApp, ipcAsyncByApp } from "../../../utils/ipc";
import { useTranslation } from "react-i18next";
import { AppearancePicker, FlatPrefersColorScheme } from "flat-components";
import { ConfigStoreContext } from "../../../components/StoreProvider";

enum SelectLanguage {
Chinese,
Expand All @@ -15,6 +16,7 @@ enum SelectLanguage {
export const GeneralSettingPage = (): React.ReactElement => {
const { t, i18n } = useTranslation();
const [openAtLogin, setOpenAtLogin] = useState(false);
const configStore = useContext(ConfigStoreContext);

useEffect(() => {
ipcSyncByApp("get-open-at-login")
Expand All @@ -33,11 +35,16 @@ export const GeneralSettingPage = (): React.ReactElement => {
});
};

async function changeLanguage(event: CheckboxChangeEvent): Promise<void> {
async function changeLanguage(event: RadioChangeEvent): Promise<void> {
const language: SelectLanguage = event.target.value;
await i18n.changeLanguage(language === SelectLanguage.Chinese ? "zh-CN" : "en");
}

const changeAppearance = (event: RadioChangeEvent): void => {
const prefersColorScheme: FlatPrefersColorScheme = event.target.value;
configStore.updatePrefersColorScheme(prefersColorScheme);
};

return (
<UserSettingLayoutContainer>
<div className="general-setting-container">
Expand All @@ -60,6 +67,13 @@ export const GeneralSettingPage = (): React.ReactElement => {
<Radio value={SelectLanguage.English}>English</Radio>
</Radio.Group>
</div>
<div className="general-setting-appearance-picker-container">
<span>{t("flat-appearance-setting")}</span>
<AppearancePicker
changeAppearance={changeAppearance}
defaultValue={configStore.prefersColorScheme}
/>
</div>
</div>
</UserSettingLayoutContainer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@
}
}
}

.general-setting-appearance-picker-container{
> span {
display: block;
padding-top: 8px;
padding-bottom: 3px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import { Meta, Story } from "@storybook/react";
import { BrowserRouter as Router } from "react-router-dom";
import { AppearancePicker, AppearancePickerProps } from ".";

const storyMeta: Meta = {
title: "SettingPage/AppearancePicker",
component: AppearancePicker,
};

export default storyMeta;

export const Overview: Story<AppearancePickerProps> = args => (
<Router>
<div className="vh-75 mw8-ns">
<AppearancePicker {...args} />
</div>
</Router>
);
Overview.args = {
defaultValue: "light",
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import lightSVG from "./icons/light.svg";
import darkSVG from "./icons/dark.svg";
import autoSVG from "./icons/auto.svg";
import "./style.less";

import React from "react";
import { useTranslation } from "react-i18next";
import { Radio, RadioChangeEvent } from "antd";
import { FlatPrefersColorScheme } from "../../FlatThemeProvider";

export interface AppearancePickerProps {
defaultValue: FlatPrefersColorScheme;
changeAppearance: (event: RadioChangeEvent) => void;
}

export const AppearancePicker: React.FC<AppearancePickerProps> = ({
defaultValue,
changeAppearance,
}) => {
const { t } = useTranslation();
return (
<div className="appearance-picker-container">
<Radio.Group defaultValue={defaultValue} onChange={changeAppearance}>
<Radio value={"light"}>
<div className="appearance-picker-option">
<img src={lightSVG} />
<span>{t("flat-appearance-light")}</span>
</div>
</Radio>
<Radio value={"dark"}>
<div className="appearance-picker-option">
<img src={darkSVG} />
<span>{t("flat-appearance-dark")}</span>
</div>
</Radio>
<Radio value={"auto"}>
<div className="appearance-picker-option">
<img src={autoSVG} />
<span>{t("flat-appearance-auto")}</span>
</div>
</Radio>
</Radio.Group>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.appearance-picker-container {
> .ant-radio-group {
> .ant-radio-wrapper {
border-radius: 4px;
padding: 4px;

> span {
padding: 0;
}

.ant-radio {
margin-top: 9px;
}

&::after {
content: "";
top: 0;
left: 0;
width: 100%;
height: 75%;
position: absolute;
border-radius: 4px;
transition: border-color 0.4s;
}

&.ant-radio-wrapper-checked,
&:hover,
&:active {
&::after {
border: 2px solid var(--primary);
}
}
}

.ant-radio {
display: none;
}
}
}

.appearance-picker-option {
display: flex;
flex-direction: column;
align-items: center;

> span {
padding-top: 8px;
}
}
1 change: 1 addition & 0 deletions packages/flat-components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ export * from "./components/DeviceTestPage";
export * from "./components/ClassroomPage/CloudRecordBtn";
export * from "./components/ClassroomPage/Timer";
export * from "./components/FlatIcons";
export * from "./components/SettingPage/AppearancePicker";
10 changes: 7 additions & 3 deletions packages/flat-i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@
"repeat-frequency": "Every {{week}}",
"schedule-room-detail": "Ends at {{time}} with {{length}} rooms",
"schedule-room-type": "Room type: {{type}}",
"view-all-rooms-in-periodic-rooms": "View all {{count}} rooms",
"view-all-rooms-in-periodic-rooms": "View all ({{count}}) rooms",
"ending": "Ending...",
"follow-your-perspective-tips": "Other users will follow your perspective",
"interactive-mode": "Currently in interactive mode",
Expand Down Expand Up @@ -398,6 +398,10 @@
"exit": "Exit",
"side-panel": {
"hide": "Hide",
"show": "Show"
}
"show": "Show"
},
"flat-appearance-light": "Light",
"flat-appearance-dark": "Dark",
"flat-appearance-auto": "Auto",
"flat-appearance-setting": "Appearance"
}
10 changes: 7 additions & 3 deletions packages/flat-i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@
"schedule-room-default-title": "{{name}} 预定的房间",
"delete-room-records": "删除房间记录",
"delete-room-records-tips": "确定删除当前房间记录?",
"view-all-rooms-in-periodic-rooms": "查看全部 {{count}} 场房间",
"view-all-rooms-in-periodic-rooms": "查看全部 ({{count}}) 场房间",
"repeat-frequency": "每{{week}}",
"schedule-room-type": "房间类型:{{type}}",
"schedule-room-detail": "结束于 {{time}} ,共 {{length}} 个房间",
Expand Down Expand Up @@ -398,6 +398,10 @@
"exit": "退出",
"side-panel": {
"hide": "折叠",
"show": "展开"
}
"show": "展开"
},
"flat-appearance-light": "浅色",
"flat-appearance-dark": "深色",
"flat-appearance-auto": "自动",
"flat-appearance-setting": "外观"
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
}
}

.general-setting-appearance-picker-container{
> span {
display: block;
padding-top: 8px;
padding-bottom: 3px;
}
}

.general-setting-device-test-box {
padding-top: 12px;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import "./index.less";

import { FlatPrefersColorScheme, AppearancePicker } from "flat-components";
import { Checkbox, Radio } from "antd";
import React, { useContext } from "react";
import { UserSettingLayoutContainer } from "../UserSettingLayoutContainer";
import { useTranslation } from "react-i18next";
import type { CheckboxChangeEvent } from "antd/lib/checkbox";
import { GlobalStoreContext } from "../../../components/StoreProvider";
import { ConfigStoreContext, GlobalStoreContext } from "../../../components/StoreProvider";

enum SelectLanguage {
Chinese,
Expand All @@ -14,6 +15,7 @@ enum SelectLanguage {

export const GeneralSettingPage = (): React.ReactElement => {
const globalStore = useContext(GlobalStoreContext);
const configStore = useContext(ConfigStoreContext);

const { t, i18n } = useTranslation();

Expand All @@ -22,6 +24,11 @@ export const GeneralSettingPage = (): React.ReactElement => {
void i18n.changeLanguage(language === SelectLanguage.Chinese ? "zh-CN" : "en");
}

const changeAppearance = (event: CheckboxChangeEvent): void => {
const prefersColorScheme: FlatPrefersColorScheme = event.target.value;
configStore.updatePrefersColorScheme(prefersColorScheme);
};

return (
<UserSettingLayoutContainer>
<div className="general-setting-container">
Expand All @@ -39,6 +46,13 @@ export const GeneralSettingPage = (): React.ReactElement => {
<Radio value={SelectLanguage.English}>English</Radio>
</Radio.Group>
</div>
<div className="general-setting-appearance-picker-container">
<span>{t("flat-appearance-setting")}</span>
<AppearancePicker
changeAppearance={changeAppearance}
defaultValue={configStore.prefersColorScheme}
/>
</div>
<div className="general-setting-device-test-box">
<div className="general-setting-checkbox-title">{t("device-test-option")}</div>
<Checkbox
Expand Down