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

style(ui): add dark mode social icon (#1265)

* style(ui): add dark mode social icon

add dark mode social icon

* style(ui): social landing icon

social landing icon

* fix(ui): dark connector icon cr update

dark connector icon cr update

* fix(ui): cr fix

cr fix
This commit is contained in:
simeng-li 2022-07-01 10:07:43 +08:00 committed by GitHub
parent 5e819665c7
commit a5e44cf478
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 85 additions and 55 deletions

View file

@ -1,6 +1,5 @@
@use '@/scss/underscore' as _;
.socialButton {
border-radius: 50%;
@include _.flex-column;
@ -9,6 +8,10 @@
width: 40px;
height: 40px;
cursor: pointer;
&.inverse {
background: #fff;
}
}
.icon {
@ -20,13 +23,11 @@
:global(body.desktop) {
.socialButton {
background: var(--color-layer);
&:active {
&:not(.inverse):active {
background: var(--color-pressed);
}
&:hover:not(:active) {
&:not(.inverse):hover:not(:active) {
background: var(--color-hover);
}
}

View file

@ -1,24 +1,28 @@
import classNames from 'classnames';
import React from 'react';
import { ConnectorData } from '@/types';
import { isAppleConnector } from '@/utils/social-connectors';
import * as styles from './SocialIconButton.module.scss';
type Props = {
className?: string;
connector: ConnectorData;
logo: string;
target?: string;
onClick?: () => void;
};
const SocialIconButton = ({ className, connector, onClick }: Props) => {
const { target, logo } = connector;
return (
<button className={classNames(styles.socialButton, className)} onClick={onClick}>
{logo && <img src={logo} alt={target} className={styles.icon} />}
</button>
);
};
const SocialIconButton = ({ className, logo, target, onClick }: Props) => (
<button
className={classNames(
styles.socialButton,
isAppleConnector(target) && styles.inverse,
className
)}
onClick={onClick}
>
{logo && <img src={logo} alt={target} className={styles.icon} />}
</button>
);
export default SocialIconButton;

View file

@ -2,28 +2,25 @@ import classNames from 'classnames';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ConnectorData } from '@/types';
import * as socialLinkButtonStyles from './SocialLinkButton.module.scss';
import * as styles from './index.module.scss';
export type Props = {
isDisabled?: boolean;
className?: string;
connector: ConnectorData;
target: string;
logo: string;
name: Record<string, string>;
onClick?: () => void;
};
const SocialLinkButton = ({ isDisabled, className, connector, onClick }: Props) => {
const { target, name, logo } = connector;
const SocialLinkButton = ({ isDisabled, className, target, name, logo, onClick }: Props) => {
const {
t,
i18n: { language },
} = useTranslation();
// TODO: LOG-2393 should fix name[locale] syntax error
const foundName = Object.entries(name).find(([lang]) => lang === language);
const localName = foundName ? foundName[1] : name.en;
const localName = name[language] ?? target;
return (
<button

View file

@ -28,7 +28,12 @@ describe('Button Component', () => {
it('render SocialLinkButton', () => {
const connector = mockSocialConnectorData;
const { queryByText, container } = render(
<SocialLinkButton connector={connector} onClick={onClick} />
<SocialLinkButton
logo={connector.logo}
name={connector.name}
target={connector.target}
onClick={onClick}
/>
);
expect(queryByText('action.sign_in_with')).not.toBeNull();

View file

@ -13,13 +13,17 @@ type Props = {
};
const SocialLanding = ({ className, connectorId, isLoading = false }: Props) => {
const { experienceSettings } = useContext(PageContext);
const { experienceSettings, theme } = useContext(PageContext);
const connector = experienceSettings?.socialConnectors.find(({ id }) => id === connectorId);
return (
<div className={classNames(styles.container, className)}>
<div className={styles.connector}>
{connector?.logo ? <img src={connector.logo} /> : connectorId}
{connector ? (
<img src={theme === 'dark' ? connector.logoDark ?? connector.logo : connector.logo} />
) : (
connectorId
)}
</div>
{isLoading && <LoadingIcon />}
</div>

View file

@ -20,7 +20,7 @@ const SocialSignInDropdown = ({ isOpen, onClose, connectors, anchorRef }: Props)
i18n: { language },
} = useTranslation();
const [contentStyle, setContentStyle] = useState<{ top?: number; left?: number }>();
const { invokeSocialSignIn } = useSocial();
const { invokeSocialSignIn, theme } = useSocial();
const adjustPosition = useCallback(() => {
if (anchorRef?.current) {
@ -46,7 +46,7 @@ const SocialSignInDropdown = ({ isOpen, onClose, connectors, anchorRef }: Props)
}}
>
{connectors.map((connector) => {
const { id, name, logo } = connector;
const { id, name, logo, logoDark } = connector;
const languageKey = Object.keys(name).find((key) => key === language) ?? 'en';
const localName = name[languageKey as Language];
@ -58,7 +58,11 @@ const SocialSignInDropdown = ({ isOpen, onClose, connectors, anchorRef }: Props)
onClose();
}}
>
<img src={logo} alt={id} className={styles.socialLogo} />
<img
src={theme === 'dark' ? logoDark ?? logo : logo}
alt={id}
className={styles.socialLogo}
/>
<span>{localName}</span>
</DropdownItem>
);

View file

@ -6,6 +6,7 @@ import IconButton from '@/components/Button/IconButton';
import SocialIconButton from '@/components/Button/SocialIconButton';
import useSocial from '@/hooks/use-social';
import { ConnectorData } from '@/types';
import { isAppleConnector } from '@/utils/social-connectors';
import * as styles from './index.module.scss';
@ -24,20 +25,25 @@ const SocialSignInIconList = ({
moreButtonRef,
onMoreButtonClick,
}: Props) => {
const { invokeSocialSignIn } = useSocial();
const { invokeSocialSignIn, theme } = useSocial();
return (
<div className={classNames(styles.socialIconList, className)}>
{connectors.map((connector) => (
<SocialIconButton
key={connector.id}
className={styles.socialButton}
connector={connector}
onClick={() => {
void invokeSocialSignIn(connector);
}}
/>
))}
{connectors.map((connector) => {
const { id, target, logo, logoDark } = connector;
return (
<SocialIconButton
key={id}
className={styles.socialButton}
logo={(theme === 'dark' && !isAppleConnector(target) && logoDark) || logo}
target={target}
onClick={() => {
void invokeSocialSignIn(connector);
}}
/>
);
})}
{hasMore && (
<IconButton ref={moreButtonRef} className={styles.moreButton} onClick={onMoreButtonClick}>
<MoreSocialIcon />

View file

@ -25,7 +25,7 @@ const SocialSignInList = ({
onSocialSignInCallback,
}: Props) => {
const [expand, setExpand] = useState(false);
const { invokeSocialSignIn } = useSocial();
const { invokeSocialSignIn, theme } = useSocial();
const isOverSize = socialConnectors.length > defaultSize;
const displayAll = !isOverSize || !isCollapseEnabled;
@ -39,17 +39,23 @@ const SocialSignInList = ({
return (
<div className={classNames(styles.socialLinkList, className)}>
{displayConnectors.map((connector) => (
<SocialLinkButton
key={connector.id}
className={styles.socialLinkButton}
connector={connector}
onClick={() => {
void invokeSocialSignIn(connector);
onSocialSignInCallback?.();
}}
/>
))}
{displayConnectors.map((connector) => {
const { id, name, logo, logoDark, target } = connector;
return (
<SocialLinkButton
key={id}
className={styles.socialLinkButton}
name={name}
logo={(theme === 'dark' && logoDark) || logo}
target={target}
onClick={() => {
void invokeSocialSignIn(connector);
onSocialSignInCallback?.();
}}
/>
);
})}
{!displayAll && (
<IconButton
className={classNames(styles.expandIcon, expand && styles.expanded)}

View file

@ -10,7 +10,7 @@ import { PageContext } from './use-page-context';
import useTerms from './use-terms';
const useSocial = () => {
const { experienceSettings } = useContext(PageContext);
const { experienceSettings, theme } = useContext(PageContext);
const { termsValidation } = useTerms();
const { run: asyncInvokeSocialSignIn } = useApi(invokeSocialSignIn);
@ -64,6 +64,7 @@ const useSocial = () => {
);
return {
theme,
socialConnectors: experienceSettings?.socialConnectors ?? [],
invokeSocialSignIn: invokeSocialSignInHandler,
};

View file

@ -196,3 +196,5 @@ export const filterPreviewSocialConnectors = (
return Array.from(connectorMap.values());
};
export const isAppleConnector = (target?: string) => target === 'apple';