Fix checkbox issues (#681)

* Fix checkbox issues

* Fix theme
This commit is contained in:
Charles Bochet
2023-07-15 14:16:02 -07:00
committed by GitHub
parent 2bbcf6980a
commit b982788100
11 changed files with 88 additions and 57 deletions

View File

@ -47,7 +47,7 @@ export function RequireOnboarded({
} }
}, [onboardingStatus, navigate]); }, [onboardingStatus, navigate]);
if (onboardingStatus !== OnboardingStatus.Completed) { if (onboardingStatus && onboardingStatus !== OnboardingStatus.Completed) {
return ( return (
<EmptyContainer> <EmptyContainer>
<FadeInStyle> <FadeInStyle>

View File

@ -59,11 +59,10 @@ export function useAuth() {
setTokenPair(verifyResult.data?.verify.tokens); setTokenPair(verifyResult.data?.verify.tokens);
setIsAuthenticating(false); setIsAuthenticating(false);
setCurrentUser(verifyResult.data?.verify.user);
return verifyResult.data?.verify; return verifyResult.data?.verify;
}, },
[setCurrentUser, setIsAuthenticating, setTokenPair, verify], [setIsAuthenticating, setTokenPair, verify],
); );
const handleLogin = useCallback( const handleLogin = useCallback(
@ -77,7 +76,8 @@ export function useAuth() {
const handleLogout = useCallback(() => { const handleLogout = useCallback(() => {
setTokenPair(null); setTokenPair(null);
}, [setTokenPair]); setCurrentUser(null);
}, [setTokenPair, setCurrentUser]);
const handleSignUp = useCallback( const handleSignUp = useCallback(
async (email: string, password: string, workspaceInviteHash?: string) => { async (email: string, password: string, workspaceInviteHash?: string) => {

View File

@ -8,9 +8,10 @@ import {
OnboardingStatus, OnboardingStatus,
} from '../utils/getOnboardingStatus'; } from '../utils/getOnboardingStatus';
export function useOnboardingStatus(): OnboardingStatus { export function useOnboardingStatus(): OnboardingStatus | undefined {
const [currentUser] = useRecoilState(currentUserState); const [currentUser] = useRecoilState(currentUserState);
const isLoggedIn = useIsLogged(); const isLoggedIn = useIsLogged();
const onboardingStatus = useMemo( const onboardingStatus = useMemo(
() => getOnboardingStatus(isLoggedIn, currentUser), () => getOnboardingStatus(isLoggedIn, currentUser),
[currentUser, isLoggedIn], [currentUser, isLoggedIn],

View File

@ -11,9 +11,15 @@ export function getOnboardingStatus(
isLoggedIn: boolean, isLoggedIn: boolean,
currentUser: CurrentUser | null, currentUser: CurrentUser | null,
) { ) {
if (!isLoggedIn || !currentUser) { if (!isLoggedIn) {
return OnboardingStatus.OngoingUserCreation; return OnboardingStatus.OngoingUserCreation;
} }
// if the user has not been fetched yet, we can't know the onboarding status
if (!currentUser) {
return undefined;
}
if (!currentUser.workspaceMember?.workspace.displayName) { if (!currentUser.workspaceMember?.workspace.displayName) {
return OnboardingStatus.OngoingWorkspaceCreation; return OnboardingStatus.OngoingWorkspaceCreation;
} }

View File

@ -114,8 +114,8 @@ export function CompanyBoardCard() {
[updatePipelineProgress], [updatePipelineProgress],
); );
const handleCheckboxChange = () => { const handleCheckboxChange = (checked: boolean) => {
setSelected(!selected); setSelected(checked);
}; };
if (!company || !pipelineProgress) { if (!company || !pipelineProgress) {

View File

@ -1,79 +1,98 @@
import * as React from 'react'; import * as React from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IconCheck } from '@/ui/icons/index'; import { IconCheck, IconMinus } from '@/ui/icons';
type OwnProps = { type OwnProps = {
checked: boolean; checked: boolean;
indeterminate?: boolean; indeterminate?: boolean;
onChange: () => void; onChange: (value: boolean) => void;
}; };
const StyledContainer = styled.div` const StyledInputContainer = styled.div`
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: center; `;
position: relative;
input[type='checkbox'] { const StyledInput = styled.input<{ indeterminate?: boolean }>`
accent-color: ${({ theme }) => theme.color.blue}; cursor: pointer;
margin: 0;
opacity: 0;
position: absolute;
z-index: 10;
& + label {
cursor: pointer; cursor: pointer;
height: 14px; height: 14px;
margin: 2px; padding: 0;
user-select: none; position: relative;
width: 14px; width: 14px;
} }
input[type='checkbox']::before { & + label:before {
background-color: ${({ theme }) => theme.background.primary}; background: ${({ theme }) => theme.background.primary};
border: 1px solid ${({ theme }) => theme.font.color.tertiary}; border: 1px solid ${({ theme }) => theme.border.color.strong};
border-radius: ${({ theme }) => theme.border.radius.xs}; border-radius: ${({ theme }) => theme.border.radius.sm};
content: ''; content: '';
display: block; cursor: pointer;
display: inline-block;
height: 12px; height: 12px;
width: 12px; width: 12px;
} }
input[type='checkbox']:hover::before { &:checked + label:before {
border: 1px solid ${({ theme }) => theme.font.color.primary};
}
input[type='checkbox']:checked::before {
border: 1px solid ${({ theme }) => theme.color.blue};
}
svg {
background: ${({ theme }) => theme.color.blue}; background: ${({ theme }) => theme.color.blue};
color: white; border-color: ${({ theme }) => theme.color.blue};
}
& + label:before {
background: ${({ theme, indeterminate }) =>
indeterminate ? theme.color.blue : theme.background.primary};
border-color: ${({ theme, indeterminate }) =>
indeterminate ? theme.color.blue : theme.border.color.inverted};
}
& + label > svg {
height: 12px; height: 12px;
left: 50%; left: 1px;
position: absolute; position: absolute;
top: 50%; stroke: ${({ theme }) => theme.grayScale.gray0};
transform: translate(-50%, -50%); top: 1px;
width: 12px; width: 12px;
} }
`; `;
export function Checkbox({ checked, onChange, indeterminate }: OwnProps) { export function Checkbox({ checked, onChange, indeterminate }: OwnProps) {
const ref = React.useRef<HTMLInputElement>(null); const [isInternalChecked, setIsInternalChecked] = React.useState(false);
React.useEffect(() => { React.useEffect(() => {
if (ref.current === null) return; setIsInternalChecked(checked);
if (typeof indeterminate === 'boolean') { }, [checked]);
ref.current.indeterminate = !checked && indeterminate;
} function handleChange(value: boolean) {
}, [ref, indeterminate, checked]); onChange(value);
setIsInternalChecked(!isInternalChecked);
}
return ( return (
<StyledContainer onClick={onChange}> <StyledInputContainer>
<input <StyledInput
ref={ref}
type="checkbox" type="checkbox"
name="styled-checkbox"
data-testid="input-checkbox" data-testid="input-checkbox"
checked={checked} checked={isInternalChecked}
indeterminate={indeterminate}
onChange={(event) => handleChange(event.target.checked)}
/> />
{checked && <IconCheck />} <label htmlFor="checkbox">
</StyledContainer> {indeterminate ? (
<IconMinus />
) : isInternalChecked ? (
<IconCheck />
) : (
<></>
)}
</label>
</StyledInputContainer>
); );
} }

View File

@ -21,8 +21,8 @@ export function CheckboxCell() {
const { currentRowSelected, setCurrentRowSelected } = useCurrentRowSelected(); const { currentRowSelected, setCurrentRowSelected } = useCurrentRowSelected();
function handleContainerClick() { function onChange(checked: boolean) {
handleCheckboxChange(!currentRowSelected); handleCheckboxChange(checked);
} }
function handleCheckboxChange(newCheckedValue: boolean) { function handleCheckboxChange(newCheckedValue: boolean) {
@ -33,7 +33,7 @@ export function CheckboxCell() {
return ( return (
<StyledContainer> <StyledContainer>
<Checkbox checked={currentRowSelected} onChange={handleContainerClick} /> <Checkbox checked={currentRowSelected} onChange={onChange} />
</StyledContainer> </StyledContainer>
); );
} }

View File

@ -17,18 +17,17 @@ const StyledContainer = styled.div`
export const SelectAllCheckbox = () => { export const SelectAllCheckbox = () => {
const { selectAllRows, allRowsSelectedStatus } = useSelectAllRows(); const { selectAllRows, allRowsSelectedStatus } = useSelectAllRows();
function handleContainerClick() {
selectAllRows();
}
const checked = allRowsSelectedStatus === 'all'; const checked = allRowsSelectedStatus === 'all';
const indeterminate = allRowsSelectedStatus === 'some'; const indeterminate = allRowsSelectedStatus === 'some';
function onChange(value: boolean) {
selectAllRows();
}
return ( return (
<StyledContainer> <StyledContainer>
<Checkbox <Checkbox
checked={checked} checked={checked}
onChange={handleContainerClick} onChange={onChange}
indeterminate={indeterminate} indeterminate={indeterminate}
/> />
</StyledContainer> </StyledContainer>

View File

@ -15,6 +15,7 @@ export { IconColorSwatch } from '@tabler/icons-react';
export { IconX } from '@tabler/icons-react'; export { IconX } from '@tabler/icons-react';
export { IconChevronLeft } from '@tabler/icons-react'; export { IconChevronLeft } from '@tabler/icons-react';
export { IconPlus } from '@tabler/icons-react'; export { IconPlus } from '@tabler/icons-react';
export { IconMinus } from '@tabler/icons-react';
export { IconLink } from '@tabler/icons-react'; export { IconLink } from '@tabler/icons-react';
export { IconUsers } from '@tabler/icons-react'; export { IconUsers } from '@tabler/icons-react';
export { IconCalendarEvent } from '@tabler/icons-react'; export { IconCalendarEvent } from '@tabler/icons-react';

View File

@ -18,7 +18,10 @@ export function useSelectAllRows() {
.getLoadable(tableRowIdsState) .getLoadable(tableRowIdsState)
.valueOrThrow(); .valueOrThrow();
if (allRowsSelectedStatus === 'none') { if (
allRowsSelectedStatus === 'none' ||
allRowsSelectedStatus === 'some'
) {
for (const rowId of tableRowIds) { for (const rowId of tableRowIds) {
set(isRowSelectedFamilyState(rowId), true); set(isRowSelectedFamilyState(rowId), true);
} }

View File

@ -14,6 +14,7 @@ export const borderLight = {
strong: grayScale.gray25, strong: grayScale.gray25,
medium: grayScale.gray20, medium: grayScale.gray20,
light: grayScale.gray15, light: grayScale.gray15,
inverted: grayScale.gray55,
}, },
...common, ...common,
}; };
@ -23,6 +24,7 @@ export const borderDark = {
strong: grayScale.gray60, strong: grayScale.gray60,
medium: grayScale.gray65, medium: grayScale.gray65,
light: grayScale.gray70, light: grayScale.gray70,
inverted: grayScale.gray30,
}, },
...common, ...common,
}; };