diff --git a/packages/ui/package.json b/packages/ui/package.json index 8b8f22098..725702618 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -64,10 +64,21 @@ "extends": "@silverhand/react" }, "stylelint": { - "extends": "@silverhand/eslint-config-react/.stylelintrc" + "extends": "@silverhand/eslint-config-react/.stylelintrc", + "rules": { + "selector-pseudo-class-no-unknown": [ + true, + { + "ignorePseudoClasses": [ + "global" + ] + } + ] + } }, "prettier": "@silverhand/eslint-config/.prettierrc", "dependencies": { + "react-device-detect": "^2.2.2", "use-debounced-loader": "^0.1.1" } } diff --git a/packages/ui/src/components/AppContent/index.module.scss b/packages/ui/src/components/AppContent/index.module.scss index b28d9b9b6..d77fba575 100644 --- a/packages/ui/src/components/AppContent/index.module.scss +++ b/packages/ui/src/components/AppContent/index.module.scss @@ -1,30 +1,61 @@ @use '@/scss/underscore' as _; -@use '@/scss/colors' as colors; -@use '@/scss/basic' as basic; +@use '@/scss/mobile' as mobile; +@use '@/scss/desktop' as desktop; -/* Foundation */ -.light { - @include colors.light-theme; -} - -.dark { - @include colors.dark-theme; -} - -body { - @include colors.universal; - @include basic.fonts; - @include basic.layout; - background: var(--color-base); - color: var(--color-text); - font: var(--font-body); -} .content { - position: absolute; - top: 0; - left: 0; - right: 0; - min-height: 100%; - background: var(--color-base); + @include _.flex_column; + background-color: var(--color-base); +} + +main { + position: absolute; + inset: 0; + background: var(--color-surface); + color: var(--color-text); + font: var(--font-body); + @include _.flex_column; +} + +/* Foundation */ +:global(body.mobile) { + &.light { + @include mobile.colors-light-theme; + } + + &.dark { + @include mobile.colors-dark-theme; + } + + @include mobile.colors-universal; + @include mobile.fonts; + @include mobile.layout; + + .content { + flex: 1; + align-self: stretch; + padding: _.unit(6) _.unit(5); + position: relative; + } +} + +:global(body.desktop) { + &.light { + @include desktop.colors-light-theme; + } + + &.dark { + @include desktop.colors-dark-theme; + } + + @include desktop.colors-universal; + @include desktop.fonts; + @include desktop.layout; + + .content { + width: 640px; + min-height: 640px; + position: relative; + padding: _.unit(6); + } } diff --git a/packages/ui/src/components/AppContent/index.tsx b/packages/ui/src/components/AppContent/index.tsx index 877ab17d2..3f248b54a 100644 --- a/packages/ui/src/components/AppContent/index.tsx +++ b/packages/ui/src/components/AppContent/index.tsx @@ -1,5 +1,6 @@ -import classNames from 'classnames'; +import { conditionalString } from '@silverhand/essentials'; import React, { ReactNode, useEffect, useCallback, useContext } from 'react'; +import { isMobile } from 'react-device-detect'; import { useDebouncedLoader } from 'use-debounced-loader'; import LoadingLayer from '@/components/LoadingLayer'; @@ -24,14 +25,17 @@ const AppContent = ({ children }: Props) => { }, [setToast]); useEffect(() => { - document.body.classList.remove(styles.light ?? ''); - document.body.classList.remove(styles.dark ?? ''); - document.body.classList.add(styles[theme] ?? ''); + document.body.classList.remove(conditionalString(styles.light), conditionalString(styles.dark)); + document.body.classList.add(conditionalString(styles[theme])); }, [theme]); + useEffect(() => { + document.body.classList.add(isMobile ? 'mobile' : 'desktop'); + }, []); + return ( -
- {children} +
+
{children}
{debouncedLoading && }
diff --git a/packages/ui/src/components/Drawer/index.module.scss b/packages/ui/src/components/Drawer/index.module.scss index 1c0ed4958..896f546ee 100644 --- a/packages/ui/src/components/Drawer/index.module.scss +++ b/packages/ui/src/components/Drawer/index.module.scss @@ -30,7 +30,6 @@ /* stylelint-disable selector-class-pattern */ -/* stylelint-disable-next-line selector-pseudo-class-no-unknown */ :global { .ReactModal__Content[role='popup'] { transform: translateY(100%); diff --git a/packages/ui/src/components/NavBar/index.module.scss b/packages/ui/src/components/NavBar/index.module.scss index 0ef896af7..e98e0527b 100644 --- a/packages/ui/src/components/NavBar/index.module.scss +++ b/packages/ui/src/components/NavBar/index.module.scss @@ -10,7 +10,7 @@ svg { position: absolute; - left: _.unit(4); + left: _.unit(-2); top: 50%; transform: translateY(-50%); fill: var(--color-text); diff --git a/packages/ui/src/pages/Callback/index.module.scss b/packages/ui/src/pages/Callback/index.module.scss index b4307e2e9..261cf702a 100644 --- a/packages/ui/src/pages/Callback/index.module.scss +++ b/packages/ui/src/pages/Callback/index.module.scss @@ -2,9 +2,9 @@ .wrapper { - @include _.page-wrapper; - position: absolute; - inset: 0; + @include _.full-page; + @include _.flex-column; + justify-content: flex-start; } .connector { diff --git a/packages/ui/src/pages/Consent/index.module.scss b/packages/ui/src/pages/Consent/index.module.scss index ababfac6a..98fe51026 100644 --- a/packages/ui/src/pages/Consent/index.module.scss +++ b/packages/ui/src/pages/Consent/index.module.scss @@ -1,7 +1,9 @@ @use '@/scss/underscore' as _; .wrapper { - @include _.page-wrapper; + @include _.full-page; + @include _.flex-column; + justify-content: flex-start; .header { margin-top: _.unit(30); diff --git a/packages/ui/src/pages/ErrorPage/index.module.scss b/packages/ui/src/pages/ErrorPage/index.module.scss index 1b6afa959..6c1734a25 100644 --- a/packages/ui/src/pages/ErrorPage/index.module.scss +++ b/packages/ui/src/pages/ErrorPage/index.module.scss @@ -1,14 +1,14 @@ @use '@/scss/underscore' as _; -.container { - position: absolute; - inset: 0; +.wrapper { + @include _.full-page; @include _.flex-column; align-items: stretch; - .wrapper { + .container { flex: 1; - @include _.page-wrapper; + @include _.flex-column; + justify-content: flex-start; } .icon { diff --git a/packages/ui/src/pages/ErrorPage/index.tsx b/packages/ui/src/pages/ErrorPage/index.tsx index 546e8a8a6..402b8c7c6 100644 --- a/packages/ui/src/pages/ErrorPage/index.tsx +++ b/packages/ui/src/pages/ErrorPage/index.tsx @@ -18,9 +18,9 @@ const ErrorPage = ({ title = 'description.not_found', message }: Props) => { const navigate = useNavigate(); return ( -
+
-
+
{t(title)}
{message &&
{message}
} diff --git a/packages/ui/src/pages/Passcode/index.module.scss b/packages/ui/src/pages/Passcode/index.module.scss index 45b789f15..65357687d 100644 --- a/packages/ui/src/pages/Passcode/index.module.scss +++ b/packages/ui/src/pages/Passcode/index.module.scss @@ -1,8 +1,11 @@ @use '@/scss/underscore' as _; .wrapper { - @include _.page-wrapper; - padding-top: _.unit(2); + @include _.full-page; +} + +.container { + margin-top: _.unit(2); } .title { diff --git a/packages/ui/src/pages/Passcode/index.tsx b/packages/ui/src/pages/Passcode/index.tsx index 86757a893..3f75e52d6 100644 --- a/packages/ui/src/pages/Passcode/index.tsx +++ b/packages/ui/src/pages/Passcode/index.tsx @@ -43,14 +43,14 @@ const Passcode = () => { } return ( - <> +
-
+
{t('action.enter_passcode')}
{t('description.enter_passcode', { address: target })}
- +
); }; diff --git a/packages/ui/src/pages/Register/index.module.scss b/packages/ui/src/pages/Register/index.module.scss index 7cfa4d351..c56283503 100644 --- a/packages/ui/src/pages/Register/index.module.scss +++ b/packages/ui/src/pages/Register/index.module.scss @@ -1,8 +1,11 @@ @use '@/scss/underscore' as _; .wrapper { - @include _.page-wrapper; - padding-top: _.unit(2); + @include _.full-page; +} + +.container { + margin-top: _.unit(2); } diff --git a/packages/ui/src/pages/Register/index.tsx b/packages/ui/src/pages/Register/index.tsx index 076309dc7..f41e84f5d 100644 --- a/packages/ui/src/pages/Register/index.tsx +++ b/packages/ui/src/pages/Register/index.tsx @@ -34,13 +34,13 @@ const Register = () => { } return ( - <> +
-
+
{t('action.create_account')}
{registerForm}
- +
); }; diff --git a/packages/ui/src/pages/SecondarySignIn/index.module.scss b/packages/ui/src/pages/SecondarySignIn/index.module.scss index 7cfa4d351..c56283503 100644 --- a/packages/ui/src/pages/SecondarySignIn/index.module.scss +++ b/packages/ui/src/pages/SecondarySignIn/index.module.scss @@ -1,8 +1,11 @@ @use '@/scss/underscore' as _; .wrapper { - @include _.page-wrapper; - padding-top: _.unit(2); + @include _.full-page; +} + +.container { + margin-top: _.unit(2); } diff --git a/packages/ui/src/pages/SecondarySignIn/index.tsx b/packages/ui/src/pages/SecondarySignIn/index.tsx index b405f19d1..d5ab02124 100644 --- a/packages/ui/src/pages/SecondarySignIn/index.tsx +++ b/packages/ui/src/pages/SecondarySignIn/index.tsx @@ -34,13 +34,13 @@ const SecondarySignIn = () => { } return ( - <> +
-
+
{t('action.sign_in')}
{signInForm}
- +
); }; diff --git a/packages/ui/src/pages/SignIn/index.module.scss b/packages/ui/src/pages/SignIn/index.module.scss index 80e5e90e0..924456c5c 100644 --- a/packages/ui/src/pages/SignIn/index.module.scss +++ b/packages/ui/src/pages/SignIn/index.module.scss @@ -1,7 +1,9 @@ @use '@/scss/underscore' as _; .wrapper { - @include _.page-wrapper; + @include _.full-page; + @include _.flex-column; + justify-content: flex-start; .header { margin: _.unit(8); diff --git a/packages/ui/src/pages/SocialRegister/index.module.scss b/packages/ui/src/pages/SocialRegister/index.module.scss index 43af2c306..61026a456 100644 --- a/packages/ui/src/pages/SocialRegister/index.module.scss +++ b/packages/ui/src/pages/SocialRegister/index.module.scss @@ -1,5 +1,9 @@ @use '@/scss/underscore' as _; .wrapper { - @include _.page-wrapper; + @include _.full-page; +} + +.container { + margin-top: _.unit(2); } diff --git a/packages/ui/src/pages/SocialRegister/index.tsx b/packages/ui/src/pages/SocialRegister/index.tsx index a2cad1ed0..c909ab783 100644 --- a/packages/ui/src/pages/SocialRegister/index.tsx +++ b/packages/ui/src/pages/SocialRegister/index.tsx @@ -20,12 +20,12 @@ const SocialRegister = () => { } return ( - <> +
-
+
- +
); }; diff --git a/packages/ui/src/scss/_basic.scss b/packages/ui/src/scss/_basic.scss deleted file mode 100644 index aed87afde..000000000 --- a/packages/ui/src/scss/_basic.scss +++ /dev/null @@ -1,22 +0,0 @@ -/* Foundation */ -$font-family: -apple-system, - system-ui, - 'BlinkMacSystemFont', - 'Segoe UI', - 'Roboto', - 'Helvetica Neue', - 'Helvetica', - 'Arial', - sans-serif; - -@mixin fonts { - --font-title: 600 32px/40px #{$font-family}; - --font-body-bold: 500 16px/20px #{$font-family}; - --font-body: 400 16px/20px #{$font-family}; - --font-body-small: 500 14px/18px #{$font-family}; - --font-caption: 400 14px/18px #{$font-family}; -} - -@mixin layout { - --radius: 8px; -} diff --git a/packages/ui/src/scss/_desktop.scss b/packages/ui/src/scss/_desktop.scss new file mode 100644 index 000000000..b60ff57a1 --- /dev/null +++ b/packages/ui/src/scss/_desktop.scss @@ -0,0 +1,63 @@ +/* Foundation */ +$font-family: -apple-system, + system-ui, + 'BlinkMacSystemFont', + 'Segoe UI', + 'Roboto', + 'Helvetica Neue', + 'Helvetica', + 'Arial', + sans-serif; + +@mixin colors-light-theme { + --color-surface: #ecebf6; + --color-base: #fff; + // legacy bellow + --color-text: #191c1d; + --color-icon: #747778; + --color-caption: #747778; + --color-outline: #78767f; + --color-border: #e0e3e3; + --color-disabled: #c4c7c7; + --color-primary: #5d34f2; + --color-layer: #eff1f1; + --color-error: #ba1b1b; + --color-toast: rgba(25, 28, 29, 80%); + --color-overlay: rgba(25, 28, 29, 16%); + --color-dialogue: #fff; +} + +@mixin colors-dark-theme { + --color-surface: #25272b; + --color-base: #2a2c32; + // legacy bellow + --color-text: #f7f8f8; + --color-icon: #a9acac; + --color-caption: #a9acac; + --color-outline: #928f9a; + --color-border: #444748; + --color-disabled: #5c5f60; + --color-primary: #7958ff; + --color-layer: linear-gradient(0deg, rgba(202, 190, 255, 14%), rgba(202, 190, 255, 14%)), linear-gradient(0deg, rgba(196, 199, 199, 2%), rgba(196, 199, 199, 2%)), #191c1d; + --color-error: #dd3730; + --color-toast: rgba(247, 248, 248, 80%); + --color-overlay: rgba(25, 28, 29, 40%); + --color-dialogue: linear-gradient(0deg, rgba(202, 190, 255, 8%), rgba(202, 190, 255, 8%)), linear-gradient(0deg, rgba(196, 199, 199, 2%), rgba(196, 199, 199, 2%)), #191c1d; +} + + +@mixin colors-universal { + --color-primary-button-text: #fff; +} + +@mixin fonts { + --font-title: 600 32px/40px #{$font-family}; + --font-body-bold: 500 16px/20px #{$font-family}; + --font-body: 400 16px/20px #{$font-family}; + --font-body-small: 500 14px/18px #{$font-family}; + --font-caption: 400 14px/18px #{$font-family}; +} + +@mixin layout { + --radius: 8px; +} diff --git a/packages/ui/src/scss/_colors.scss b/packages/ui/src/scss/_mobile.scss similarity index 64% rename from packages/ui/src/scss/_colors.scss rename to packages/ui/src/scss/_mobile.scss index dd04da37f..112dd75af 100644 --- a/packages/ui/src/scss/_colors.scss +++ b/packages/ui/src/scss/_mobile.scss @@ -1,4 +1,15 @@ -@mixin light-theme { +/* Foundation */ +$font-family: -apple-system, + system-ui, + 'BlinkMacSystemFont', + 'Segoe UI', + 'Roboto', + 'Helvetica Neue', + 'Helvetica', + 'Arial', + sans-serif; + +@mixin colors-light-theme { --color-text: #191c1d; --color-icon: #747778; --color-caption: #747778; @@ -11,10 +22,11 @@ --color-toast: rgba(25, 28, 29, 80%); --color-overlay: rgba(25, 28, 29, 16%); --color-base: #fff; + --color-surface: #fff; --color-dialogue: #fff; } -@mixin dark-theme { +@mixin colors-dark-theme { --color-text: #f7f8f8; --color-icon: #a9acac; --color-caption: #a9acac; @@ -27,9 +39,23 @@ --color-toast: rgba(247, 248, 248, 80%); --color-overlay: rgba(25, 28, 29, 40%); --color-base: #191c1d; + --color-surface: #191c1d; --color-dialogue: linear-gradient(0deg, rgba(202, 190, 255, 8%), rgba(202, 190, 255, 8%)), linear-gradient(0deg, rgba(196, 199, 199, 2%), rgba(196, 199, 199, 2%)), #191c1d; } -@mixin universal { + +@mixin colors-universal { --color-primary-button-text: #fff; } + +@mixin fonts { + --font-title: 600 32px/40px #{$font-family}; + --font-body-bold: 500 16px/20px #{$font-family}; + --font-body: 400 16px/20px #{$font-family}; + --font-body-small: 500 14px/18px #{$font-family}; + --font-caption: 400 14px/18px #{$font-family}; +} + +@mixin layout { + --radius: 8px; +} diff --git a/packages/ui/src/scss/_underscore.scss b/packages/ui/src/scss/_underscore.scss index bb63e0e2a..e368ae28d 100644 --- a/packages/ui/src/scss/_underscore.scss +++ b/packages/ui/src/scss/_underscore.scss @@ -29,11 +29,9 @@ color: var(--color-text); } -@mixin page-wrapper { - position: relative; - padding: unit(6) unit(5); - @include flex-column; - justify-content: flex-start; +@mixin full-page { + flex: 1; + align-self: stretch; } @mixin container-width { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 593fa84ba..2e50cb2a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -864,6 +864,7 @@ importers: postcss-modules: ^4.3.0 prettier: ^2.3.2 react: ^17.0.2 + react-device-detect: ^2.2.2 react-dom: ^17.0.2 react-i18next: ^11.15.4 react-modal: ^3.14.4 @@ -875,6 +876,7 @@ importers: typescript: ^4.6.2 use-debounced-loader: ^0.1.1 dependencies: + react-device-detect: 2.2.2_sfoxds7t5ydpegc3knd667wn6m use-debounced-loader: 0.1.1_react@17.0.2 devDependencies: '@logto/jest-config': link:../jest-config @@ -16755,6 +16757,17 @@ packages: - webpack dev: true + /react-device-detect/2.2.2_sfoxds7t5ydpegc3knd667wn6m: + resolution: {integrity: sha512-zSN1gIAztUekp5qUT/ybHwQ9fmOqVT1psxpSlTn1pe0CO+fnJHKRLOWWac5nKxOxvOpD/w84hk1I+EydrJp7SA==} + peerDependencies: + react: '>= 0.14.0' + react-dom: '>= 0.14.0' + dependencies: + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + ua-parser-js: 1.0.2 + dev: false + /react-dnd-html5-backend/16.0.0: resolution: {integrity: sha512-be3lKEbbT8FQcoTjFlQ4ZXG/NVrFNJu9W0INc5rm/5EFQpHCkz+xpbB2U8j9uh5Bvk7AsJyQrZznEut0hrNPIA==} dependencies: @@ -19530,6 +19543,10 @@ packages: resolution: {integrity: sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==} dev: true + /ua-parser-js/1.0.2: + resolution: {integrity: sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==} + dev: false + /uglify-js/3.15.3: resolution: {integrity: sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==} engines: {node: '>=0.8.0'}