0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(experience): use vite

This commit is contained in:
Gao Sun 2024-07-24 13:52:44 +08:00
parent 6c1f4283a9
commit 3bf756f2b5
No known key found for this signature in database
GPG key ID: 13EBE123E4773688
107 changed files with 296 additions and 1994 deletions

View file

@ -0,0 +1,12 @@
---
"@logto/experience": minor
"@logto/demo-app": minor
"@logto/console": minor
---
use Vite for transpilation and bundling
Removed ParcelJS and replaced with Vite. No breaking changes should be expected, but use a minor version bump to catch your attention.
> [!Important]
> The browserlist configuration for `@logto/experience` and been synced with what is stated in README.md.

View file

@ -33,5 +33,4 @@ dump.rdb
.devcontainer .devcontainer
.github .github
.husky .husky
.parcel-cache
.vscode .vscode

6
.npmrc
View file

@ -1,6 +0,0 @@
# Hoist for Parcel
public-hoist-pattern[]=@parcel/*
public-hoist-pattern[]=postcss
public-hoist-pattern[]=process
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=buffer

View file

@ -18,7 +18,7 @@ fi
# Some node packages use `src` as their dist folder, so ignore them from the rm list in the end # Some node packages use `src` as their dist folder, so ignore them from the rm list in the end
find \ find \
.git .changeset .devcontainer .github .husky .parcel-cache .scripts .vscode pnpm-*.yaml *.js \ .git .changeset .devcontainer .github .husky .scripts .vscode pnpm-*.yaml *.js \
packages/**/src \ packages/**/src \
packages/**/*.config.js packages/**/*.config.ts packages/**/tsconfig*.json \ packages/**/*.config.js packages/**/*.config.ts packages/**/tsconfig*.json \
! -path '**/node_modules/**' \ ! -path '**/node_modules/**' \

View file

@ -10,7 +10,7 @@
"scope": "javascriptreact,typescriptreact", "scope": "javascriptreact,typescriptreact",
"prefix": "isc", "prefix": "isc",
"body": [ "body": [
"import * as styles from './index.module.scss';", "import styles from './index.module.scss';",
"$0" "$0"
], ],
"description": "Import SCSS styles from the same directory." "description": "Import SCSS styles from the same directory."

View file

@ -14,7 +14,6 @@ RUN apk add --no-cache python3 make g++ rsync
COPY . . COPY . .
### Install dependencies and build ### ### Install dependencies and build ###
RUN node .scripts/update-parcelrc.js
RUN pnpm i RUN pnpm i
### Set if dev features enabled ### ### Set if dev features enabled ###
@ -35,7 +34,7 @@ RUN rm -rf node_modules packages/**/node_modules
RUN NODE_ENV=production pnpm i RUN NODE_ENV=production pnpm i
### Clean up ### ### Clean up ###
RUN rm -rf .scripts .parcel-cache pnpm-*.yaml packages/cloud RUN rm -rf .scripts pnpm-*.yaml packages/cloud
###### [STAGE] Seal ###### ###### [STAGE] Seal ######
FROM node:20-alpine as app FROM node:20-alpine as app

View file

@ -52,9 +52,5 @@
}, },
"dependencies": { "dependencies": {
"@logto/cli": "workspace:^1.1.0" "@logto/cli": "workspace:^1.1.0"
},
"//": "@see https://parceljs.org/features/dependency-resolution/#package-exports",
"@parcel/resolver-default": {
"packageExports": true
} }
} }

View file

@ -52,6 +52,9 @@ Images and other assets (if any) should be placed in the `assets` directory of t
### Update metadata ### Update metadata
> [!Note]
> This section is outdated and we should test if it's still necessary.
Since Parcel doesn't support dynamic import (see [#112](https://github.com/parcel-bundler/parcel/issues/112) [#125](https://github.com/parcel-bundler/parcel/issues/125)), we need to run `node generate-metadata.js` to update the metadata in `index.ts`, thus we can use it in the guide components with React lazy loading. Since Parcel doesn't support dynamic import (see [#112](https://github.com/parcel-bundler/parcel/issues/112) [#125](https://github.com/parcel-bundler/parcel/issues/125)), we need to run `node generate-metadata.js` to update the metadata in `index.ts`, thus we can use it in the guide components with React lazy loading.
This may be fixed by replacing Parcel with something else. This may be fixed by replacing Parcel with something else.

View file

@ -4,6 +4,8 @@ import classNames from 'classnames';
import { memo, useRef } from 'react'; import { memo, useRef } from 'react';
import ReactMarkdown from 'react-markdown'; import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm'; import remarkGfm from 'remark-gfm';
// TODO: @charles double check if this is still needed
/** /**
* Workaround for the markdown crash issue in the parcel dev build. It seems parcel does * Workaround for the markdown crash issue in the parcel dev build. It seems parcel does
* something clever in dev mode and messing up the `hastToReact` module. Manually adding * something clever in dev mode and messing up the `hastToReact` module. Manually adding

View file

@ -45,15 +45,7 @@ export default function koaSpaProxy<StateT, ContextT extends IRouterParamContext
getConsoleLogFromContext(ctx).plain(`\tproxy --> ${target}`); getConsoleLogFromContext(ctx).plain(`\tproxy --> ${target}`);
}, },
rewrite: (requestPath) => { rewrite: (requestPath) => {
const fullPath = '/' + path.join(prefix, requestPath); return '/' + path.join(prefix, requestPath);
// Static files
if (requestPath.includes('.')) {
return fullPath;
}
// In-app routes
// We'll gradually migrate our single-page apps to use vite, which can directly return the full path
return packagePath === 'demo-app' || packagePath === 'console' ? fullPath : requestPath;
}, },
}); });

View file

@ -0,0 +1,2 @@
// eslint-disable-next-line import/no-unassigned-import
import 'vite/client';

View file

@ -1,6 +1,4 @@
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
// eslint-disable-next-line import/no-unassigned-import
import '@logto/core-kit/declaration';
import App from './App'; import App from './App';

View file

@ -0,0 +1,22 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
extends: '@silverhand/react',
rules: {
'jsx-a11y/no-autofocus': 'off',
'unicorn/prefer-string-replace-all': 'off',
},
overrides: [
{
files: ['*.config.js', '*.config.ts', '*.d.ts'],
rules: {
'import/no-unused-modules': 'off',
},
},
{
files: ['*.d.ts'],
rules: {
'import/no-unassigned-import': 'off',
},
},
],
};

View file

@ -1,16 +0,0 @@
{
"extends": "@parcel/config-default",
"transformers": {
"**/assets/icons/*.svg": [
"@parcel/transformer-svg-react"
]
},
"compressors": {
"*.{html,css,js,svg,map}": [
"...",
"@parcel/compressor-gzip",
"@parcel/compressor-brotli"
]
},
"resolvers": ["parcel-resolver-ignore", "..."]
}

View file

@ -1,20 +0,0 @@
{
"extends": "@parcel/config-default",
"optimizers": {
// Disable optimizers in arm64 arch https://github.com/parcel-bundler/parcel/issues/7402
"*.{jpg,jpeg,png}": []
},
"transformers": {
"**/assets/icons/*.svg": [
"@parcel/transformer-svg-react"
]
},
"compressors": {
"*.{html,css,js,svg,map}": [
"...",
"@parcel/compressor-gzip",
"@parcel/compressor-brotli"
]
},
"resolvers": ["parcel-resolver-ignore", "..."]
}

View file

@ -14,7 +14,7 @@
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="app"></div> <div id="app"></div>
<script type="module" src="index.tsx"></script> <script type="module" src="src/index.tsx"></script>
</body> </body>
</html> </html>

View file

@ -25,7 +25,7 @@ const config: Config.InitialOptions = {
'\\.(png)$': 'jest-transform-stub', '\\.(png)$': 'jest-transform-stub',
}, },
moduleNameMapper: { moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1', '^@/([^?]*)(\\?.*)?$': '<rootDir>/src/$1',
'^@logto/shared/(.*)$': '<rootDir>/../shared/lib/$1', '^@logto/shared/(.*)$': '<rootDir>/../shared/lib/$1',
'\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', '\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
}, },

View file

@ -9,10 +9,10 @@
], ],
"scripts": { "scripts": {
"precommit": "lint-staged", "precommit": "lint-staged",
"start": "parcel src/index.html", "start": "vite",
"dev": "cross-env PORT=5001 parcel src/index.html --no-cache --hmr-port 6001", "dev": "vite",
"check": "tsc --noEmit", "check": "tsc --noEmit",
"build": "pnpm check && rm -rf dist && parcel build src/index.html --no-autoinstall --no-cache --detailed-report", "build": "pnpm check && vite build",
"lint": "eslint --ext .ts --ext .tsx src", "lint": "eslint --ext .ts --ext .tsx src",
"lint:report": "pnpm lint --format json --output-file report.json", "lint:report": "pnpm lint --format json --output-file report.json",
"stylelint": "stylelint \"src/**/*.scss\"", "stylelint": "stylelint \"src/**/*.scss\"",
@ -27,11 +27,6 @@
"@logto/phrases": "workspace:^1.12.0", "@logto/phrases": "workspace:^1.12.0",
"@logto/phrases-experience": "workspace:^1.7.0", "@logto/phrases-experience": "workspace:^1.7.0",
"@logto/schemas": "workspace:^1.18.0", "@logto/schemas": "workspace:^1.18.0",
"@parcel/compressor-brotli": "2.9.3",
"@parcel/compressor-gzip": "2.9.3",
"@parcel/core": "2.9.3",
"@parcel/transformer-sass": "2.9.3",
"@parcel/transformer-svg-react": "2.9.3",
"@react-spring/shared": "^9.6.1", "@react-spring/shared": "^9.6.1",
"@react-spring/web": "^9.6.1", "@react-spring/web": "^9.6.1",
"@silverhand/eslint-config": "6.0.1", "@silverhand/eslint-config": "6.0.1",
@ -52,11 +47,13 @@
"@types/react-helmet": "^6.1.6", "@types/react-helmet": "^6.1.6",
"@types/react-modal": "^3.13.1", "@types/react-modal": "^3.13.1",
"@types/react-router-dom": "^5.3.2", "@types/react-router-dom": "^5.3.2",
"@vitejs/plugin-react": "^4.3.1",
"browserslist": "^4.23.2",
"browserslist-to-esbuild": "^2.1.1",
"camelcase-keys": "^9.1.3", "camelcase-keys": "^9.1.3",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"color": "^4.2.3", "color": "^4.2.3",
"core-js": "^3.34.0", "core-js": "^3.34.0",
"cross-env": "^7.0.3",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"i18next": "^22.4.15", "i18next": "^22.4.15",
"i18next-browser-languagedetector": "^8.0.0", "i18next-browser-languagedetector": "^8.0.0",
@ -69,8 +66,6 @@
"ky": "^1.2.3", "ky": "^1.2.3",
"libphonenumber-js": "^1.10.51", "libphonenumber-js": "^1.10.51",
"lint-staged": "^15.0.0", "lint-staged": "^15.0.0",
"parcel": "2.9.3",
"parcel-resolver-ignore": "^2.1.3",
"postcss": "^8.4.31", "postcss": "^8.4.31",
"postcss-modules": "^4.3.0", "postcss-modules": "^4.3.0",
"prettier": "^3.0.0", "prettier": "^3.0.0",
@ -90,42 +85,13 @@
"tiny-cookie": "^2.4.1", "tiny-cookie": "^2.4.1",
"typescript": "^5.5.3", "typescript": "^5.5.3",
"use-debounced-loader": "^0.1.1", "use-debounced-loader": "^0.1.1",
"zod": "^3.23.8" "vite": "^5.3.4",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-svgr": "^4.2.0"
}, },
"engines": { "engines": {
"node": "^20.9.0" "node": "^20.9.0"
}, },
"//": "https://github.com/parcel-bundler/parcel/issues/7636",
"targets": {
"default": {
"engines": {
"browsers": [
"defaults",
">0.3%",
"Chrome >= 52",
"Firefox >= 55",
"Safari >= 10",
"Edge >= 13",
"iOS >= 10",
"Electron >= 0.36"
]
}
}
},
"parcelIgnore": [
"^/api/.+"
],
"alias": {
"@/*": "./src/$1",
"superstruct": "./node_modules/superstruct/dist/index.mjs"
},
"eslintConfig": {
"extends": "@silverhand/react",
"rules": {
"jsx-a11y/no-autofocus": "off",
"unicorn/prefer-string-replace-all": "off"
}
},
"stylelint": { "stylelint": {
"extends": "@silverhand/eslint-config-react/.stylelintrc" "extends": "@silverhand/eslint-config-react/.stylelintrc"
}, },

View file

@ -7,7 +7,7 @@ import usePlatform from '@/hooks/use-platform';
import { layoutClassNames } from '@/utils/consts'; import { layoutClassNames } from '@/utils/consts';
import CustomContent from './CustomContent'; import CustomContent from './CustomContent';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const AppLayout = () => { const AppLayout = () => {
const { isMobile } = usePlatform(); const { isMobile } = usePlatform();

View file

@ -10,7 +10,7 @@ import PageMeta from '@/components/PageMeta';
import { layoutClassNames } from '@/utils/consts'; import { layoutClassNames } from '@/utils/consts';
import { getBrandingLogoUrl } from '@/utils/logo'; import { getBrandingLogoUrl } from '@/utils/logo';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type ThirdPartyBranding = ConsentInfoResponse['application']['branding']; type ThirdPartyBranding = ConsentInfoResponse['application']['branding'];

View file

@ -8,7 +8,7 @@ import usePlatform from '@/hooks/use-platform';
import { InlineNotification } from '../../components/Notification'; import { InlineNotification } from '../../components/Notification';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly title: TFuncKey; readonly title: TFuncKey;

View file

@ -3,7 +3,7 @@ import { type ReactNode } from 'react';
import DynamicT from '@/components/DynamicT'; import DynamicT from '@/components/DynamicT';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly title: TFuncKey; readonly title: TFuncKey;

View file

@ -1,4 +1,4 @@
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly children: React.ReactNode; readonly children: React.ReactNode;

View file

@ -10,7 +10,7 @@ import defaultAppleTouchLogo from '@/assets/apple-touch-icon.png';
import defaultFavicon from '@/assets/favicon.png'; import defaultFavicon from '@/assets/favicon.png';
import { type SignInExperienceResponse } from '@/types'; import { type SignInExperienceResponse } from '@/types';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const themeToFavicon = Object.freeze({ const themeToFavicon = Object.freeze({
[Theme.Light]: 'favicon', [Theme.Light]: 'favicon',

View file

@ -6,7 +6,7 @@ import LoadingBar from 'react-top-loading-bar';
import NavBar from '@/components/NavBar'; import NavBar from '@/components/NavBar';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type ModalProps = { type ModalProps = {
readonly className?: string; readonly className?: string;

View file

@ -2,11 +2,11 @@ import type { Nullable } from '@silverhand/essentials';
import classNames from 'classnames'; import classNames from 'classnames';
import type { TFuncKey } from 'i18next'; import type { TFuncKey } from 'i18next';
import ConnectIcon from '@/assets/icons/connect-icon.svg'; import ConnectIcon from '@/assets/icons/connect-icon.svg?react';
import DynamicT from '../DynamicT'; import DynamicT from '../DynamicT';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export type Props = { export type Props = {
readonly className?: string; readonly className?: string;

View file

@ -2,7 +2,7 @@ import classNames from 'classnames';
import type { HTMLProps, Ref } from 'react'; import type { HTMLProps, Ref } from 'react';
import { forwardRef } from 'react'; import { forwardRef } from 'react';
import * as styles from './IconButton.module.scss'; import styles from './IconButton.module.scss';
export type Props = Omit<HTMLProps<HTMLButtonElement>, 'type'>; export type Props = Omit<HTMLProps<HTMLButtonElement>, 'type'>;

View file

@ -2,15 +2,15 @@ import { MfaFactor } from '@logto/schemas';
import classNames from 'classnames'; import classNames from 'classnames';
import { type TFuncKey } from 'i18next'; import { type TFuncKey } from 'i18next';
import ArrowNext from '@/assets/icons/arrow-next.svg'; import ArrowNext from '@/assets/icons/arrow-next.svg?react';
import FactorBackupCode from '@/assets/icons/factor-backup-code.svg'; import FactorBackupCode from '@/assets/icons/factor-backup-code.svg?react';
import FactorTotp from '@/assets/icons/factor-totp.svg'; import FactorTotp from '@/assets/icons/factor-totp.svg?react';
import FactorWebAuthn from '@/assets/icons/factor-webauthn.svg'; import FactorWebAuthn from '@/assets/icons/factor-webauthn.svg?react';
import DynamicT from '../DynamicT'; import DynamicT from '../DynamicT';
import * as mfaFactorButtonStyles from './MfaFactorButton.module.scss'; import mfaFactorButtonStyles from './MfaFactorButton.module.scss';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export type Props = { export type Props = {
readonly factor: MfaFactor; readonly factor: MfaFactor;

View file

@ -1,6 +1,6 @@
import Ring from '@/assets/icons/loading-ring.svg'; import Ring from '@/assets/icons/loading-ring.svg?react';
import * as RotatingRingIconStyles from './RotatingRingIcon.module.scss'; import RotatingRingIconStyles from './RotatingRingIcon.module.scss';
const RotatingRingIcon = () => <Ring className={RotatingRingIconStyles.icon} />; const RotatingRingIcon = () => <Ring className={RotatingRingIconStyles.icon} />;

View file

@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next';
import { useDebouncedLoader } from 'use-debounced-loader'; import { useDebouncedLoader } from 'use-debounced-loader';
import RotatingRingIcon from './RotatingRingIcon'; import RotatingRingIcon from './RotatingRingIcon';
import * as socialLinkButtonStyles from './SocialLinkButton.module.scss'; import socialLinkButtonStyles from './SocialLinkButton.module.scss';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export type Props = { export type Props = {
readonly isDisabled?: boolean; readonly isDisabled?: boolean;

View file

@ -6,7 +6,7 @@ import { useDebouncedLoader } from 'use-debounced-loader';
import DynamicT from '../DynamicT'; import DynamicT from '../DynamicT';
import RotatingRingIcon from './RotatingRingIcon'; import RotatingRingIcon from './RotatingRingIcon';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export type ButtonType = 'primary' | 'secondary'; export type ButtonType = 'primary' | 'secondary';

View file

@ -2,9 +2,9 @@ import classNames from 'classnames';
import type { InputHTMLAttributes, Ref } from 'react'; import type { InputHTMLAttributes, Ref } from 'react';
import { forwardRef } from 'react'; import { forwardRef } from 'react';
import CheckBox from '@/assets/icons/checkbox-icon.svg'; import CheckBox from '@/assets/icons/checkbox-icon.svg?react';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly size?: 'small' | 'default'; readonly size?: 'small' | 'default';

View file

@ -3,14 +3,14 @@ import { useRef } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import ReactModal from 'react-modal'; import ReactModal from 'react-modal';
import CloseIcon from '@/assets/icons/close-icon.svg'; import CloseIcon from '@/assets/icons/close-icon.svg?react';
import Button from '@/components/Button'; import Button from '@/components/Button';
import IconButton from '@/components/Button/IconButton'; import IconButton from '@/components/Button/IconButton';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import * as modalStyles from '../../scss/modal.module.scss'; import modalStyles from '../../scss/modal.module.scss';
import * as styles from './Acmodal.module.scss'; import styles from './Acmodal.module.scss';
import type { ModalProps } from './type'; import type { ModalProps } from './type';
const AcModal = ({ const AcModal = ({

View file

@ -3,9 +3,9 @@ import ReactModal from 'react-modal';
import Button from '@/components/Button'; import Button from '@/components/Button';
import * as modalStyles from '../../scss/modal.module.scss'; import modalStyles from '../../scss/modal.module.scss';
import * as styles from './MobileModal.module.scss'; import styles from './MobileModal.module.scss';
import type { ModalProps } from './type'; import type { ModalProps } from './type';
const MobileModal = ({ const MobileModal = ({

View file

@ -3,7 +3,7 @@ import type { TFuncKey } from 'i18next';
import DynamicT from '../DynamicT'; import DynamicT from '../DynamicT';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -3,7 +3,7 @@ import type { TFuncKey } from 'i18next';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type RemovePrefix<T extends string, Prefix extends T> = T extends `${Prefix}${string}` ? never : T; type RemovePrefix<T extends string, Prefix extends T> = T extends `${Prefix}${string}` ? never : T;

View file

@ -1,6 +1,6 @@
import classNames from 'classnames'; import classNames from 'classnames';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly label: string; readonly label: string;

View file

@ -14,7 +14,7 @@ import {
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
import NotchedBorder from './NotchedBorder'; import NotchedBorder from './NotchedBorder';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export type Props = Omit<HTMLProps<HTMLInputElement>, 'prefix'> & { export type Props = Omit<HTMLProps<HTMLInputElement>, 'prefix'> & {
readonly className?: string; readonly className?: string;

View file

@ -2,8 +2,8 @@ import type { Nullable } from '@silverhand/essentials';
import type { Ref } from 'react'; import type { Ref } from 'react';
import { forwardRef, useRef, useImperativeHandle } from 'react'; import { forwardRef, useRef, useImperativeHandle } from 'react';
import PasswordHideIcon from '@/assets/icons/password-hide-icon.svg'; import PasswordHideIcon from '@/assets/icons/password-hide-icon.svg?react';
import PasswordShowIcon from '@/assets/icons/password-show-icon.svg'; import PasswordShowIcon from '@/assets/icons/password-show-icon.svg?react';
import IconButton from '@/components/Button/IconButton'; import IconButton from '@/components/Button/IconButton';
import useToggle from '@/hooks/use-toggle'; import useToggle from '@/hooks/use-toggle';

View file

@ -3,7 +3,7 @@ import { useSpring, animated, config } from '@react-spring/web';
import type { Nullable } from '@silverhand/essentials'; import type { Nullable } from '@silverhand/essentials';
import { cloneElement, useCallback, useRef, useState } from 'react'; import { cloneElement, useCallback, useRef, useState } from 'react';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly children: JSX.Element; // Limit to one element readonly children: JSX.Element; // Limit to one element

View file

@ -6,8 +6,8 @@ import { useCallback, useLayoutEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import ReactModal from 'react-modal'; import ReactModal from 'react-modal';
import CheckMark from '@/assets/icons/check-mark.svg'; import CheckMark from '@/assets/icons/check-mark.svg?react';
import SearchIcon from '@/assets/icons/search-icon.svg'; import SearchIcon from '@/assets/icons/search-icon.svg?react';
import InputField from '@/components/InputFields/InputField'; import InputField from '@/components/InputFields/InputField';
import NavBar from '@/components/NavBar'; import NavBar from '@/components/NavBar';
import useDebounce from '@/hooks/use-debounce'; import useDebounce from '@/hooks/use-debounce';
@ -15,7 +15,7 @@ import usePlatform from '@/hooks/use-platform';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import type { CountryMetaData } from '@/utils/country-code'; import type { CountryMetaData } from '@/utils/country-code';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly isOpen: boolean; readonly isOpen: boolean;

View file

@ -3,12 +3,12 @@ import classNames from 'classnames';
import type { ForwardedRef } from 'react'; import type { ForwardedRef } from 'react';
import { useState, useMemo, forwardRef } from 'react'; import { useState, useMemo, forwardRef } from 'react';
import DownArrowIcon from '@/assets/icons/arrow-down.svg'; import DownArrowIcon from '@/assets/icons/arrow-down.svg?react';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import { getCountryList, getDefaultCountryCallingCode } from '@/utils/country-code'; import { getCountryList, getDefaultCountryCallingCode } from '@/utils/country-code';
import CountryCodeDropdown from './CountryCodeDropdown'; import CountryCodeDropdown from './CountryCodeDropdown';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -4,7 +4,7 @@ import type { Nullable } from '@silverhand/essentials';
import type { HTMLProps, Ref } from 'react'; import type { HTMLProps, Ref } from 'react';
import { useEffect, useImperativeHandle, useRef, forwardRef } from 'react'; import { useEffect, useImperativeHandle, useRef, forwardRef } from 'react';
import ClearIcon from '@/assets/icons/clear-icon.svg'; import ClearIcon from '@/assets/icons/clear-icon.svg?react';
import IconButton from '@/components/Button/IconButton'; import IconButton from '@/components/Button/IconButton';
import InputField from '../InputField'; import InputField from '../InputField';

View file

@ -1,8 +1,8 @@
import classNames from 'classnames'; import classNames from 'classnames';
import LoadingSvg from '@/assets/icons/loading-icon.svg'; import LoadingSvg from '@/assets/icons/loading-icon.svg?react';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -1,7 +1,7 @@
import LoadingMask from '../LoadingMask'; import LoadingMask from '../LoadingMask';
import LoadingIcon from './LoadingIcon'; import LoadingIcon from './LoadingIcon';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export { default as LoadingIcon } from './LoadingIcon'; export { default as LoadingIcon } from './LoadingIcon';

View file

@ -1,6 +1,6 @@
import { type ReactNode } from 'react'; import { type ReactNode } from 'react';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly children?: ReactNode; readonly children?: ReactNode;

View file

@ -2,11 +2,11 @@ import { Theme } from '@logto/schemas';
import { useContext } from 'react'; import { useContext } from 'react';
import PageContext from '@/Providers/PageContextProvider/PageContext'; import PageContext from '@/Providers/PageContextProvider/PageContext';
import LogtoLogtoDark from '@/assets/icons/logto-logo-dark.svg'; import LogtoLogtoDark from '@/assets/icons/logto-logo-dark.svg?react';
import LogtoLogoLight from '@/assets/icons/logto-logo-light.svg'; import LogtoLogoLight from '@/assets/icons/logto-logo-light.svg?react';
import LogtoLogoShadow from '@/assets/icons/logto-logo-shadow.svg'; import LogtoLogoShadow from '@/assets/icons/logto-logo-shadow.svg?react';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const logtoUrl = `https://logto.io/?${new URLSearchParams({ const logtoUrl = `https://logto.io/?${new URLSearchParams({
utm_source: 'sign_in', utm_source: 'sign_in',

View file

@ -3,11 +3,11 @@ import { useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import ArrowPrev from '@/assets/icons/arrow-prev.svg'; import ArrowPrev from '@/assets/icons/arrow-prev.svg?react';
import NavClose from '@/assets/icons/nav-close.svg'; import NavClose from '@/assets/icons/nav-close.svg?react';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly title?: string; readonly title?: string;

View file

@ -2,10 +2,10 @@ import classNames from 'classnames';
import type { CSSProperties, ForwardedRef, ReactNode } from 'react'; import type { CSSProperties, ForwardedRef, ReactNode } from 'react';
import { forwardRef } from 'react'; import { forwardRef } from 'react';
import InfoIcon from '@/assets/icons/info-icon.svg'; import InfoIcon from '@/assets/icons/info-icon.svg?react';
import TextLink from '@/components/TextLink'; import TextLink from '@/components/TextLink';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
/* eslint-disable react/require-default-props */ /* eslint-disable react/require-default-props */
type Props = { type Props = {

View file

@ -3,7 +3,7 @@ import type { TFuncKey } from 'i18next';
import DynamicT from '@/components/DynamicT'; import DynamicT from '@/components/DynamicT';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -1,4 +1,4 @@
import SwitchIcon from '@/assets/icons/switch-icon.svg'; import SwitchIcon from '@/assets/icons/switch-icon.svg?react';
import { UserMfaFlow } from '@/types'; import { UserMfaFlow } from '@/types';
import { type MfaFlowState } from '@/types/guard'; import { type MfaFlowState } from '@/types/guard';

View file

@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
import TextLink, { type Props as TextLinkProps } from '@/components/TextLink'; import TextLink, { type Props as TextLinkProps } from '@/components/TextLink';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly linkType?: TextLinkProps['type']; readonly linkType?: TextLinkProps['type'];

View file

@ -11,7 +11,7 @@ import usePlatform from '@/hooks/use-platform';
import DynamicT from '../DynamicT'; import DynamicT from '../DynamicT';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export type Props = AnchorHTMLAttributes<HTMLAnchorElement> & { export type Props = AnchorHTMLAttributes<HTMLAnchorElement> & {
readonly className?: string; readonly className?: string;

View file

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import ReactModal from 'react-modal'; import ReactModal from 'react-modal';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly message: string; readonly message: string;

View file

@ -3,7 +3,7 @@ import { useMemo, useRef, useCallback, useEffect } from 'react';
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export const defaultLength = 6; export const defaultLength = 6;

View file

@ -1,4 +0,0 @@
import { yes } from '@silverhand/essentials';
export const isDevFeaturesEnabled =
process.env.NODE_ENV !== 'production' || yes(process.env.DEV_FEATURES_ENABLED);

View file

@ -2,7 +2,7 @@ import { useContext, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import PageContext from '@/Providers/PageContextProvider/PageContext'; import PageContext from '@/Providers/PageContextProvider/PageContext';
import DevIcon from '@/assets/icons/dev-icon.svg'; import DevIcon from '@/assets/icons/dev-icon.svg?react';
import usePlatform from '@/hooks/use-platform'; import usePlatform from '@/hooks/use-platform';
/** /**

View file

@ -8,7 +8,7 @@ import useStartWebAuthnProcessing from '@/hooks/use-start-webauthn-processing';
import { UserMfaFlow } from '@/types'; import { UserMfaFlow } from '@/types';
import { type MfaFlowState } from '@/types/guard'; import { type MfaFlowState } from '@/types/guard';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly flow: UserMfaFlow; readonly flow: UserMfaFlow;

View file

@ -8,7 +8,7 @@ import ErrorMessage from '@/components/ErrorMessage';
import { PasswordInputField } from '@/components/InputFields'; import { PasswordInputField } from '@/components/InputFields';
import HiddenIdentifierInput from './HiddenIdentifierInput'; import HiddenIdentifierInput from './HiddenIdentifierInput';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import ClearIcon from '@/assets/icons/clear-icon.svg'; import ClearIcon from '@/assets/icons/clear-icon.svg?react';
import Button from '@/components/Button'; import Button from '@/components/Button';
import IconButton from '@/components/Button/IconButton'; import IconButton from '@/components/Button/IconButton';
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
@ -11,7 +11,7 @@ import { InputField } from '@/components/InputFields';
import HiddenIdentifierInput from './HiddenIdentifierInput'; import HiddenIdentifierInput from './HiddenIdentifierInput';
import TogglePassword from './TogglePassword'; import TogglePassword from './TogglePassword';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import Checkbox from '@/components/Checkbox'; import Checkbox from '@/components/Checkbox';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly isChecked?: boolean; readonly isChecked?: boolean;

View file

@ -3,7 +3,7 @@ import classNames from 'classnames';
import { LoadingIcon } from '@/components/LoadingLayer'; import { LoadingIcon } from '@/components/LoadingLayer';
import useConnectors from '@/hooks/use-connectors'; import useConnectors from '@/hooks/use-connectors';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -11,7 +11,7 @@ import useSocialRegister from '@/hooks/use-social-register';
import type { SocialRelatedUserInfo } from '@/types/guard'; import type { SocialRelatedUserInfo } from '@/types/guard';
import { maskEmail, maskPhone } from '@/utils/format'; import { maskEmail, maskPhone } from '@/utils/format';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import useBindSocialRelatedUser from './use-social-link-related-user'; import useBindSocialRelatedUser from './use-social-link-related-user';
type Props = { type Props = {

View file

@ -6,7 +6,7 @@ import SocialLinkButton from '@/components/Button/SocialLinkButton';
import useNativeMessageListener from '@/hooks/use-native-message-listener'; import useNativeMessageListener from '@/hooks/use-native-message-listener';
import { getLogoUrl } from '@/utils/logo'; import { getLogoUrl } from '@/utils/logo';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import useSocial from './use-social'; import useSocial from './use-social';
type Props = { type Props = {

View file

@ -7,7 +7,7 @@ import TermsLinks from '@/components/TermsLinks';
import useTerms from '@/hooks/use-terms'; import useTerms from '@/hooks/use-terms';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -5,7 +5,7 @@ import Button from '@/components/Button';
import VerificationCodeInput from '@/components/VerificationCode'; import VerificationCodeInput from '@/components/VerificationCode';
import { type UserMfaFlow } from '@/types'; import { type UserMfaFlow } from '@/types';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import useTotpCodeVerification from './use-totp-code-verification'; import useTotpCodeVerification from './use-totp-code-verification';
const totpCodeLength = 6; const totpCodeLength = 6;

View file

@ -1,4 +1,4 @@
import SwitchIcon from '@/assets/icons/switch-icon.svg'; import SwitchIcon from '@/assets/icons/switch-icon.svg?react';
import TextLink from '@/components/TextLink'; import TextLink from '@/components/TextLink';
import { UserFlow } from '@/types'; import { UserFlow } from '@/types';

View file

@ -9,7 +9,7 @@ import VerificationCodeInput, { defaultLength } from '@/components/VerificationC
import { UserFlow } from '@/types'; import { UserFlow } from '@/types';
import PasswordSignInLink from './PasswordSignInLink'; import PasswordSignInLink from './PasswordSignInLink';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import useResendVerificationCode from './use-resend-verification-code'; import useResendVerificationCode from './use-resend-verification-code';
import { getCodeVerificationHookByFlow } from './utils'; import { getCodeVerificationHookByFlow } from './utils';

View file

@ -1,65 +0,0 @@
// Copied from react-scripts/lib/react-app.d.ts
declare module '*.avif' {
const src: string;
export default src;
}
declare module '*.bmp' {
const src: string;
export default src;
}
declare module '*.gif' {
const src: string;
export default src;
}
declare module '*.jpg' {
const src: string;
export default src;
}
declare module '*.jpeg' {
const src: string;
export default src;
}
declare module '*.png' {
const src: string;
export default src;
}
declare module '*.webp' {
const src: string;
export default src;
}
declare module '*.svg' {
import type * as React from 'react';
export const ReactComponent: React.FunctionComponent<
React.SVGProps<SVGSVGElement> & { title?: string }
>;
const src: string;
export default src;
}
declare module '*.module.css' {
const classes: Readonly<Record<string, string>>;
export default classes;
export = classes;
}
declare module '*.module.scss' {
const classes: Readonly<Record<string, string>>;
export default classes;
export = classes;
}
declare module '*.module.sass' {
const classes: Readonly<Record<string, string>>;
export default classes;
export = classes;
}

View file

@ -6,7 +6,6 @@
* Reference: https://github.com/remix-run/react-router/issues/10241 * Reference: https://github.com/remix-run/react-router/issues/10241
*/ */
// eslint-disable-next-line import/no-unassigned-import
import 'react-router-dom'; import 'react-router-dom';
declare module 'react-router-dom' { declare module 'react-router-dom' {

View file

@ -0,0 +1,2 @@
import 'vite/client';
import 'vite-plugin-svgr/client';

View file

@ -4,7 +4,7 @@ import { useParams } from 'react-router-dom';
import StaticPageLayout from '@/Layout/StaticPageLayout'; import StaticPageLayout from '@/Layout/StaticPageLayout';
import SocialLanding from '@/containers/SocialLanding'; import SocialLanding from '@/containers/SocialLanding';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import useSocialCallbackHandler from './use-social-callback-handler'; import useSocialCallbackHandler from './use-social-callback-handler';
type Parameters = { type Parameters = {

View file

@ -2,11 +2,11 @@ import { type ConsentInfoResponse } from '@logto/schemas';
import classNames from 'classnames'; import classNames from 'classnames';
import { type ReactNode } from 'react'; import { type ReactNode } from 'react';
import CheckMark from '@/assets/icons/check-mark.svg'; import CheckMark from '@/assets/icons/check-mark.svg?react';
import OrganizationIcon from '@/assets/icons/organization-icon.svg'; import OrganizationIcon from '@/assets/icons/organization-icon.svg?react';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export type Organization = Exclude<ConsentInfoResponse['organizations'], undefined>[number]; export type Organization = Exclude<ConsentInfoResponse['organizations'], undefined>[number];

View file

@ -6,7 +6,7 @@ import usePlatform from '@/hooks/use-platform';
import OrganizationItem from '../OrganizationItem'; import OrganizationItem from '../OrganizationItem';
import { type Organization } from '../OrganizationItem'; import { type Organization } from '../OrganizationItem';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly isOpen: boolean; readonly isOpen: boolean;

View file

@ -3,13 +3,13 @@ import classNames from 'classnames';
import { useState, useRef } from 'react'; import { useState, useRef } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import ExpandableIcon from '@/assets/icons/expandable-icon.svg'; import ExpandableIcon from '@/assets/icons/expandable-icon.svg?react';
import ScopeGroup from '../ScopeGroup'; import ScopeGroup from '../ScopeGroup';
import OrganizationItem, { type Organization } from './OrganizationItem'; import OrganizationItem, { type Organization } from './OrganizationItem';
import OrganizationSelectorModal from './OrganizationSelectorModal'; import OrganizationSelectorModal from './OrganizationSelectorModal';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
export { type Organization } from './OrganizationItem'; export { type Organization } from './OrganizationItem';

View file

@ -2,11 +2,11 @@ import { type Nullable } from '@silverhand/essentials';
import classNames from 'classnames'; import classNames from 'classnames';
import { useState, useCallback } from 'react'; import { useState, useCallback } from 'react';
import DownArrowIcon from '@/assets/icons/arrow-down.svg'; import DownArrowIcon from '@/assets/icons/arrow-down.svg?react';
import CheckMark from '@/assets/icons/check-mark.svg'; import CheckMark from '@/assets/icons/check-mark.svg?react';
import { onKeyDownHandler } from '@/utils/a11y'; import { onKeyDownHandler } from '@/utils/a11y';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type ScopeGroupProps = { type ScopeGroupProps = {
readonly groupName: string; readonly groupName: string;

View file

@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
import ScopeGroup from '../ScopeGroup'; import ScopeGroup from '../ScopeGroup';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const isUserScope = (scope: string): scope is UserScope => const isUserScope = (scope: string): scope is UserScope =>
Object.values<string>(UserScope).includes(scope); Object.values<string>(UserScope).includes(scope);

View file

@ -2,9 +2,9 @@ import { type ConsentInfoResponse } from '@logto/schemas';
import classNames from 'classnames'; import classNames from 'classnames';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import UserAvatar from '@/assets/icons/default-user-avatar.svg'; import UserAvatar from '@/assets/icons/default-user-avatar.svg?react';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly user: ConsentInfoResponse['user']; readonly user: ConsentInfoResponse['user'];

View file

@ -15,7 +15,7 @@ import useGlobalRedirectTo from '@/hooks/use-global-redirect-to';
import OrganizationSelector, { type Organization } from './OrganizationSelector'; import OrganizationSelector, { type Organization } from './OrganizationSelector';
import ScopesListCard from './ScopesListCard'; import ScopesListCard from './ScopesListCard';
import UserProfile from './UserProfile'; import UserProfile from './UserProfile';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import { getRedirectUriOrigin } from './util'; import { getRedirectUriOrigin } from './util';
const Consent = () => { const Consent = () => {

View file

@ -12,7 +12,7 @@ import type {
} from '@/components/InputFields/SmartInputField'; } from '@/components/InputFields/SmartInputField';
import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form'; import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -7,7 +7,7 @@ import type { VerificationCodeIdentifier } from '@/types';
import { registeredSocialIdentityStateGuard } from '@/types/guard'; import { registeredSocialIdentityStateGuard } from '@/types/guard';
import { maskEmail } from '@/utils/format'; import { maskEmail } from '@/utils/format';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const SocialIdentityNotification = ({ const SocialIdentityNotification = ({
missingProfileTypes, missingProfileTypes,

View file

@ -4,13 +4,13 @@ import { useContext } from 'react';
import StaticPageLayout from '@/Layout/StaticPageLayout'; import StaticPageLayout from '@/Layout/StaticPageLayout';
import PageContext from '@/Providers/PageContextProvider/PageContext'; import PageContext from '@/Providers/PageContextProvider/PageContext';
import EmptyStateDark from '@/assets/icons/empty-state-dark.svg'; import EmptyStateDark from '@/assets/icons/empty-state-dark.svg?react';
import EmptyState from '@/assets/icons/empty-state.svg'; import EmptyState from '@/assets/icons/empty-state.svg?react';
import DynamicT from '@/components/DynamicT'; import DynamicT from '@/components/DynamicT';
import NavBar from '@/components/NavBar'; import NavBar from '@/components/NavBar';
import PageMeta from '@/components/PageMeta'; import PageMeta from '@/components/PageMeta';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly title?: TFuncKey; readonly title?: TFuncKey;

View file

@ -12,7 +12,7 @@ import type { VerificationCodeIdentifier } from '@/types';
import { UserFlow } from '@/types'; import { UserFlow } from '@/types';
import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form'; import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -14,7 +14,7 @@ import { UserMfaFlow } from '@/types';
import { backupCodeBindingStateGuard } from '@/types/guard'; import { backupCodeBindingStateGuard } from '@/types/guard';
import { isNativeWebview } from '@/utils/native-sdk'; import { isNativeWebview } from '@/utils/native-sdk';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const BackupCodeBinding = () => { const BackupCodeBinding = () => {
const { copyText, downloadText } = useTextHandler(); const { copyText, downloadText } = useTextHandler();

View file

@ -8,7 +8,7 @@ import usePlatform from '@/hooks/use-platform';
import useTextHandler from '@/hooks/use-text-handler'; import useTextHandler from '@/hooks/use-text-handler';
import { type TotpBindingState } from '@/types/guard'; import { type TotpBindingState } from '@/types/guard';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const SecretSection = ({ secret, secretQrCode }: TotpBindingState) => { const SecretSection = ({ secret, secretQrCode }: TotpBindingState) => {
const { t } = useTranslation(); const { t } = useTranslation();

View file

@ -12,7 +12,7 @@ import { totpBindingStateGuard } from '@/types/guard';
import SecretSection from './SecretSection'; import SecretSection from './SecretSection';
import VerificationSection from './VerificationSection'; import VerificationSection from './VerificationSection';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const TotpBinding = () => { const TotpBinding = () => {
const { state } = useLocation(); const { state } = useLocation();

View file

@ -13,7 +13,7 @@ import { UserMfaFlow } from '@/types';
import { webAuthnStateGuard } from '@/types/guard'; import { webAuthnStateGuard } from '@/types/guard';
import { isWebAuthnOptions } from '@/utils/webauthn'; import { isWebAuthnOptions } from '@/utils/webauthn';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const WebAuthnBinding = () => { const WebAuthnBinding = () => {
const { state } = useLocation(); const { state } = useLocation();

View file

@ -13,7 +13,7 @@ import useSendMfaPayload from '@/hooks/use-send-mfa-payload';
import ErrorPage from '@/pages/ErrorPage'; import ErrorPage from '@/pages/ErrorPage';
import { UserMfaFlow } from '@/types'; import { UserMfaFlow } from '@/types';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type FormState = { type FormState = {
code: string; code: string;

View file

@ -6,7 +6,7 @@ import useMfaFlowState from '@/hooks/use-mfa-factors-state';
import ErrorPage from '@/pages/ErrorPage'; import ErrorPage from '@/pages/ErrorPage';
import { UserMfaFlow } from '@/types'; import { UserMfaFlow } from '@/types';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const TotpVerification = () => { const TotpVerification = () => {
const flowState = useMfaFlowState(); const flowState = useMfaFlowState();

View file

@ -12,7 +12,7 @@ import { UserMfaFlow } from '@/types';
import { webAuthnStateGuard } from '@/types/guard'; import { webAuthnStateGuard } from '@/types/guard';
import { isWebAuthnOptions } from '@/utils/webauthn'; import { isWebAuthnOptions } from '@/utils/webauthn';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const WebAuthnVerification = () => { const WebAuthnVerification = () => {
const { state } = useLocation(); const { state } = useLocation();

View file

@ -5,7 +5,7 @@ import { Controller, useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext'; import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext';
import LockIcon from '@/assets/icons/lock.svg'; import LockIcon from '@/assets/icons/lock.svg?react';
import Button from '@/components/Button'; import Button from '@/components/Button';
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
import { SmartInputField } from '@/components/InputFields'; import { SmartInputField } from '@/components/InputFields';
@ -15,7 +15,7 @@ import useSingleSignOnWatch from '@/hooks/use-single-sign-on-watch';
import useTerms from '@/hooks/use-terms'; import useTerms from '@/hooks/use-terms';
import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form'; import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import useOnSubmit from './use-on-submit'; import useOnSubmit from './use-on-submit';
type Props = { type Props = {

View file

@ -18,7 +18,7 @@ import useTerms from '@/hooks/use-terms';
import ErrorPage from '../ErrorPage'; import ErrorPage from '../ErrorPage';
import IdentifierRegisterForm from './IdentifierRegisterForm'; import IdentifierRegisterForm from './IdentifierRegisterForm';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const RegisterFooter = () => { const RegisterFooter = () => {
const { t } = useTranslation(); const { t } = useTranslation();

View file

@ -5,7 +5,7 @@ import { useForm, Controller } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext'; import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext';
import LockIcon from '@/assets/icons/lock.svg'; import LockIcon from '@/assets/icons/lock.svg?react';
import Button from '@/components/Button'; import Button from '@/components/Button';
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
import { SmartInputField } from '@/components/InputFields'; import { SmartInputField } from '@/components/InputFields';
@ -15,7 +15,7 @@ import useSingleSignOnWatch from '@/hooks/use-single-sign-on-watch';
import useTerms from '@/hooks/use-terms'; import useTerms from '@/hooks/use-terms';
import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form'; import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
import useOnSubmit from './use-on-submit'; import useOnSubmit from './use-on-submit';
type Props = { type Props = {

View file

@ -6,7 +6,7 @@ import useTerms from '@/hooks/use-terms';
import IdentifierSignInForm from './IdentifierSignInForm'; import IdentifierSignInForm from './IdentifierSignInForm';
import PasswordSignInForm from './PasswordSignInForm'; import PasswordSignInForm from './PasswordSignInForm';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly signInMethods: SignIn['methods']; readonly signInMethods: SignIn['methods'];

View file

@ -5,7 +5,7 @@ import { useForm, Controller } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext'; import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext';
import LockIcon from '@/assets/icons/lock.svg'; import LockIcon from '@/assets/icons/lock.svg?react';
import Button from '@/components/Button'; import Button from '@/components/Button';
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
import { SmartInputField, PasswordInputField } from '@/components/InputFields'; import { SmartInputField, PasswordInputField } from '@/components/InputFields';
@ -18,7 +18,7 @@ import useSingleSignOnWatch from '@/hooks/use-single-sign-on-watch';
import useTerms from '@/hooks/use-terms'; import useTerms from '@/hooks/use-terms';
import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form'; import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type Props = { type Props = {
readonly className?: string; readonly className?: string;

View file

@ -18,7 +18,7 @@ import useTerms from '@/hooks/use-terms';
import ErrorPage from '../ErrorPage'; import ErrorPage from '../ErrorPage';
import Main from './Main'; import Main from './Main';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const SignInFooters = () => { const SignInFooters = () => {
const { t } = useTranslation(); const { t } = useTranslation();

View file

@ -1,6 +1,6 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import SwitchIcon from '@/assets/icons/switch-icon.svg'; import SwitchIcon from '@/assets/icons/switch-icon.svg?react';
import TextLink from '@/components/TextLink'; import TextLink from '@/components/TextLink';
import useSendVerificationCode from '@/hooks/use-send-verification-code'; import useSendVerificationCode from '@/hooks/use-send-verification-code';
import useToast from '@/hooks/use-toast'; import useToast from '@/hooks/use-toast';

View file

@ -13,7 +13,7 @@ import ForgotPasswordLink from '@/containers/ForgotPasswordLink';
import usePasswordSignIn from '@/hooks/use-password-sign-in'; import usePasswordSignIn from '@/hooks/use-password-sign-in';
import { useForgotPasswordSettings } from '@/hooks/use-sie'; import { useForgotPasswordSettings } from '@/hooks/use-sie';
import * as styles from '../index.module.scss'; import styles from '../index.module.scss';
import VerificationCodeLink from './VerificationCodeLink'; import VerificationCodeLink from './VerificationCodeLink';

View file

@ -9,7 +9,7 @@ import useNativeMessageListener from '@/hooks/use-native-message-listener';
import useSingleSignOn from '@/hooks/use-single-sign-on'; import useSingleSignOn from '@/hooks/use-single-sign-on';
import { getLogoUrl } from '@/utils/logo'; import { getLogoUrl } from '@/utils/logo';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
const SingleSignOnConnectors = () => { const SingleSignOnConnectors = () => {
const { theme } = useContext(PageContext); const { theme } = useContext(PageContext);

View file

@ -4,7 +4,7 @@ import { Controller, useForm } from 'react-hook-form';
import SecondaryPageLayout from '@/Layout/SecondaryPageLayout'; import SecondaryPageLayout from '@/Layout/SecondaryPageLayout';
import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext'; import UserInteractionContext from '@/Providers/UserInteractionContextProvider/UserInteractionContext';
import LockIcon from '@/assets/icons/lock.svg'; import LockIcon from '@/assets/icons/lock.svg?react';
import Button from '@/components/Button'; import Button from '@/components/Button';
import ErrorMessage from '@/components/ErrorMessage'; import ErrorMessage from '@/components/ErrorMessage';
import SmartInputField, { import SmartInputField, {
@ -13,7 +13,7 @@ import SmartInputField, {
import useOnSubmit from '@/hooks/use-check-single-sign-on'; import useOnSubmit from '@/hooks/use-check-single-sign-on';
import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form'; import { getGeneralIdentifierErrorMessage, validateIdentifierField } from '@/utils/form';
import * as styles from './index.module.scss'; import styles from './index.module.scss';
type FormState = { type FormState = {
identifier: IdentifierInputValue; identifier: IdentifierInputValue;

Some files were not shown because too many files have changed in this diff Show more