mirror of
https://github.com/logto-io/logto.git
synced 2025-03-10 22:22:45 -05:00
* refactor: updated button component in packages/ui * docs: added comment for window.timeout * docs: added prefix to comment * fix: removed unwanted style changes * fix(ui): update button props update button props, add ut * fix(ui): fix merge conflicts fix merge conflicts Co-authored-by: simeng-li <simeng@silverhand.io>
This commit is contained in:
parent
5f81cd1ef5
commit
970d360988
12 changed files with 62 additions and 62 deletions
|
@ -2,8 +2,8 @@ import { render, fireEvent } from '@testing-library/react';
|
|||
|
||||
import { mockSocialConnectorData } from '@/__mocks__/logto';
|
||||
|
||||
import Button from '.';
|
||||
import SocialLinkButton from './SocialLinkButton';
|
||||
import Button from './index';
|
||||
|
||||
describe('Button Component', () => {
|
||||
const onClick = jest.fn();
|
||||
|
@ -12,16 +12,11 @@ describe('Button Component', () => {
|
|||
onClick.mockClear();
|
||||
});
|
||||
|
||||
it('render Button', () => {
|
||||
const { queryByText, container } = render(<Button onClick={onClick}>foo</Button>);
|
||||
expect(queryByText('foo')).not.toBeNull();
|
||||
|
||||
const button = container.querySelector('button');
|
||||
|
||||
if (button) {
|
||||
fireEvent.click(button);
|
||||
expect(onClick).toBeCalled();
|
||||
}
|
||||
it('render Default Button', () => {
|
||||
const { queryByText, getByText } = render(<Button title="action.confirm" onClick={onClick} />);
|
||||
expect(queryByText('action.confirm')).not.toBeNull();
|
||||
fireEvent.click(getByText('action.confirm'));
|
||||
expect(onClick).toBeCalled();
|
||||
});
|
||||
|
||||
it('render SocialLinkButton', () => {
|
||||
|
|
|
@ -1,41 +1,56 @@
|
|||
import { I18nKey } from '@logto/phrases-ui';
|
||||
import classNames from 'classnames';
|
||||
import { ReactNode } from 'react';
|
||||
import { HTMLProps } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
export type Props = {
|
||||
export type ButtonType = 'primary' | 'secondary' | 'outline';
|
||||
|
||||
type BaseProps = Omit<HTMLProps<HTMLButtonElement>, 'type' | 'size' | 'title'> & {
|
||||
htmlType?: 'button' | 'submit' | 'reset';
|
||||
type?: ButtonType;
|
||||
size?: 'small' | 'large';
|
||||
isDisabled?: boolean;
|
||||
className?: string;
|
||||
children: ReactNode | Record<string, unknown>;
|
||||
type?: 'primary' | 'secondary' | 'outline';
|
||||
size?: 'small' | 'large';
|
||||
onClick?: React.MouseEventHandler;
|
||||
};
|
||||
|
||||
type Props = BaseProps & {
|
||||
title: I18nKey;
|
||||
i18nProps?: Record<string, string>;
|
||||
};
|
||||
|
||||
const Button = ({
|
||||
htmlType = 'button',
|
||||
type = 'primary',
|
||||
size = 'large',
|
||||
isDisabled,
|
||||
title,
|
||||
i18nProps,
|
||||
className,
|
||||
children,
|
||||
isDisabled = false,
|
||||
onClick,
|
||||
}: Props) => (
|
||||
<button
|
||||
disabled={isDisabled}
|
||||
className={classNames(
|
||||
styles.button,
|
||||
styles[type],
|
||||
styles[size],
|
||||
isDisabled && styles.disabled,
|
||||
className
|
||||
)}
|
||||
type={htmlType}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
...rest
|
||||
}: Props) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<button
|
||||
disabled={isDisabled}
|
||||
className={classNames(
|
||||
styles.button,
|
||||
styles[type],
|
||||
styles[size],
|
||||
isDisabled && styles.isDisabled,
|
||||
className
|
||||
)}
|
||||
type={htmlType}
|
||||
onClick={onClick}
|
||||
{...rest}
|
||||
>
|
||||
{t(title, { ...i18nProps })}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default Button;
|
||||
|
|
|
@ -37,12 +37,8 @@ const AcModal = ({
|
|||
</div>
|
||||
<div className={styles.content}>{children}</div>
|
||||
<div className={styles.footer}>
|
||||
<Button type="outline" size="small" onClick={onClose}>
|
||||
{t(cancelText)}
|
||||
</Button>
|
||||
<Button size="small" onClick={onConfirm ?? onClose}>
|
||||
{t(confirmText)}
|
||||
</Button>
|
||||
<Button title={cancelText} type="outline" size="small" onClick={onClose} />
|
||||
<Button title={confirmText} size="small" onClick={onConfirm ?? onClose} />
|
||||
</div>
|
||||
</div>
|
||||
</ReactModal>
|
||||
|
|
|
@ -52,10 +52,8 @@ const IframeConfirmModal = ({
|
|||
/>
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<Button type="secondary" onClick={onClose}>
|
||||
{t(cancelText)}
|
||||
</Button>
|
||||
<Button onClick={onConfirm ?? onClose}>{t(confirmText)}</Button>
|
||||
<Button title={cancelText} type="secondary" onClick={onClose} />
|
||||
<Button title={confirmText} onClick={onConfirm ?? onClose} />
|
||||
</div>
|
||||
</div>
|
||||
</ReactModal>
|
||||
|
|
|
@ -29,10 +29,8 @@ const MobileModal = ({
|
|||
<div className={styles.container}>
|
||||
<div className={styles.content}>{children}</div>
|
||||
<div className={styles.footer}>
|
||||
<Button type="secondary" onClick={onClose}>
|
||||
{t(cancelText)}
|
||||
</Button>
|
||||
<Button onClick={onConfirm ?? onClose}>{t(confirmText)}</Button>
|
||||
<Button title={cancelText} type="secondary" onClick={onClose} />
|
||||
<Button title={confirmText} onClick={onConfirm ?? onClose} />
|
||||
</div>
|
||||
</div>
|
||||
</ReactModal>
|
||||
|
|
|
@ -122,7 +122,7 @@ const CreateAccount = ({ className, autoFocus }: Props) => {
|
|||
/>
|
||||
<TermsOfUse className={styles.terms} />
|
||||
|
||||
<Button onClick={async () => onSubmitHandler()}>{t('action.create')}</Button>
|
||||
<Button title="action.create" onClick={async () => onSubmitHandler()} />
|
||||
|
||||
<input hidden type="submit" />
|
||||
</form>
|
||||
|
|
|
@ -119,7 +119,7 @@ const EmailPasswordless = ({ type, autoFocus, onSubmitValidation, children, clas
|
|||
|
||||
{children && <div className={styles.childWrapper}>{children}</div>}
|
||||
|
||||
<Button onClick={async () => onSubmitHandler()}>{t('action.continue')}</Button>
|
||||
<Button title="action.continue" onClick={async () => onSubmitHandler()} />
|
||||
|
||||
<input hidden type="submit" />
|
||||
</form>
|
||||
|
|
|
@ -133,7 +133,7 @@ const PhonePasswordless = ({ type, autoFocus, onSubmitValidation, children, clas
|
|||
/>
|
||||
{children && <div className={styles.childWrapper}>{children}</div>}
|
||||
|
||||
<Button onClick={async () => onSubmitHandler()}>{t('action.continue')}</Button>
|
||||
<Button title="action.continue" onClick={async () => onSubmitHandler()} />
|
||||
|
||||
<input hidden type="submit" />
|
||||
</form>
|
||||
|
|
|
@ -81,7 +81,7 @@ const ResetPassword = ({ className, autoFocus }: Props) => {
|
|||
}}
|
||||
/>
|
||||
|
||||
<Button onClick={async () => onSubmitHandler()}>{t('action.confirm')}</Button>
|
||||
<Button title="action.confirm" onClick={async () => onSubmitHandler()} />
|
||||
|
||||
<input hidden type="submit" />
|
||||
</form>
|
||||
|
|
|
@ -25,23 +25,22 @@ const SocialCreateAccount = ({ connectorId, className }: Props) => {
|
|||
<>
|
||||
<div className={styles.desc}>{t('description.social_bind_with_existing')}</div>
|
||||
<Button
|
||||
title="action.bind"
|
||||
i18nProps={{ address: relatedUser }}
|
||||
onClick={() => {
|
||||
bindSocialRelatedUser(connectorId);
|
||||
}}
|
||||
>
|
||||
{t('action.bind', { address: relatedUser })}
|
||||
</Button>
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div className={styles.desc}>{t('description.social_create_account')}</div>
|
||||
<Button
|
||||
title="action.create"
|
||||
type={relatedUser ? 'secondary' : 'primary'}
|
||||
onClick={() => {
|
||||
registerWithSocial(connectorId);
|
||||
}}
|
||||
>
|
||||
{t('action.create')}
|
||||
</Button>
|
||||
/>
|
||||
<SignInMethodsLink
|
||||
signInMethods={localSignInMethods}
|
||||
template="social_bind_with"
|
||||
|
|
|
@ -114,7 +114,7 @@ const UsernameSignIn = ({ className, autoFocus }: Props) => {
|
|||
)}
|
||||
<TermsOfUse className={styles.terms} />
|
||||
|
||||
<Button onClick={async () => onSubmitHandler()}>{t('action.sign_in')}</Button>
|
||||
<Button title="action.sign_in" onClick={async () => onSubmitHandler()} />
|
||||
|
||||
<input hidden type="submit" />
|
||||
</form>
|
||||
|
|
|
@ -29,12 +29,11 @@ const ErrorPage = ({ title = 'description.not_found', message, rawMessage }: Pro
|
|||
</div>
|
||||
<Button
|
||||
className={styles.backButton}
|
||||
title="action.back"
|
||||
onClick={() => {
|
||||
navigate(-1);
|
||||
}}
|
||||
>
|
||||
{t('action.back')}
|
||||
</Button>
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue