Skip to content

Commit

Permalink
feat(toggle): toggle input initialisation without animation (#504)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdebon authored Feb 23, 2023
1 parent dc71c07 commit f6879e9
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ export function PageSettingsPreviewEnvironmentsFeature() {
mode: 'onChange',
})

const watchEnvPreview = methods.watch('auto_preview')

const onSubmit = methods.handleSubmit(async (data) => {
if (data) {
setLoading(true)
Expand Down Expand Up @@ -80,27 +78,33 @@ export function PageSettingsPreviewEnvironmentsFeature() {
}
})

useEffect(() => {
const toggleAll = (value: boolean) => {
//set all preview applications "true" when env preview is true
if (loadingStatusEnvironmentDeploymentRules === 'loaded') {
applications?.forEach((application) => methods.setValue(application.id, watchEnvPreview))
applications?.forEach((application) => methods.setValue(application.id, value, { shouldDirty: true }))
}
}, [loadingStatusEnvironmentDeploymentRules, watchEnvPreview, methods, applications])
}

useEffect(() => {
if (loadingStatusEnvironment === 'loaded') dispatch(fetchEnvironmentDeploymentRules(environmentId))
}, [dispatch, loadingStatusEnvironment, environmentId])

useEffect(() => {
if (loadingStatusEnvironmentDeploymentRules === 'loaded') {
// !loading is here to prevent the toggle to glitch the time we are submitting the two api endpoints
if (loadingStatusEnvironmentDeploymentRules === 'loaded' && !loading) {
methods.setValue('auto_preview', environmentDeploymentRules?.auto_preview)
applications?.forEach((application) => methods.setValue(application.id, application.auto_preview))
}
}, [loadingStatusEnvironmentDeploymentRules, methods, environmentDeploymentRules, applications])

return (
<FormProvider {...methods}>
<PageSettingsPreviewEnvironments onSubmit={onSubmit} applications={applications} loading={loading} />
<PageSettingsPreviewEnvironments
onSubmit={onSubmit}
applications={applications}
loading={loading}
toggleAll={toggleAll}
/>
</FormProvider>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import PageSettingsPreviewEnvironments, {
const props: PageSettingsPreviewEnvironmentsProps = {
onSubmit: jest.fn(),
applications: applicationFactoryMock(3),
toggleAll: jest.fn(),
}

describe('PageSettingsPreviewEnvironments', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ export interface PageSettingsPreviewEnvironmentsProps {
onSubmit: () => void
loading: boolean
applications?: ApplicationEntity[]
toggleAll: (value: boolean) => void
}

export function PageSettingsPreviewEnvironments(props: PageSettingsPreviewEnvironmentsProps) {
const { onSubmit, applications, loading } = props
const { onSubmit, applications, loading, toggleAll } = props
const { control, formState } = useFormContext()

return (
Expand All @@ -30,7 +31,10 @@ export function PageSettingsPreviewEnvironments(props: PageSettingsPreviewEnviro
<InputToggle
dataTestId="toggle-all"
value={field.value}
onChange={field.onChange}
onChange={(value) => {
toggleAll(value)
field.onChange(value)
}}
title="Activate preview environment for all applications"
description="Automatically create a preview environment when a merge/pull request is submitted on one of your applications."
forceAlignTop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,29 @@ export interface InputToggleProps {
}

export function InputToggle(props: InputToggleProps) {
const {
small,
value = false,
onChange,
description,
title,
className = '',
forceAlignTop = false,
disabled = false,
} = props
const { small, value, onChange, description, title, className = '', forceAlignTop = false, disabled = false } = props

const [toggleActive, setToggleActive] = useState(value)
const [animateEnabled, setAnimateEnabled] = useState(false)

useEffect(() => {
setToggleActive(value)

// we need to put that in a timeout otherwise the animation classes are added too quickly and the animation is triggered
setTimeout(() => {
// if value is undefined or null, we don't want to animate
setAnimateEnabled(value !== undefined && value !== null)
}, 10)
}, [value])

const toggleSizeBg = small ? 'w-8 h-4.5' : 'w-12 h-6'
const toggleSizeCircle = small ? 'w-3.5 h-3.5' : 'w-5 h-5'

const changeToggle = () => {
if (disabled) return
// we need to put that in a timeout otherwise the animation classes are added too quickly and the animation is triggered

setAnimateEnabled(true)
onChange && onChange(!toggleActive)
setToggleActive(!toggleActive)
}
Expand All @@ -55,23 +56,25 @@ export function InputToggle(props: InputToggleProps) {
<input
type="checkbox"
defaultChecked={toggleActive}
defaultValue={toggleActive.toString()}
defaultValue={toggleActive?.toString()}
className="hidden"
disabled={disabled}
/>
<div
aria-label="bg"
className={`${toggleSizeBg} flex items-center rounded-full p-0.5 duration-300 ease-in-out ${
className={`${toggleSizeBg} flex items-center rounded-full p-0.5 ${
animateEnabled ? 'duration-300 ease-in-out' : ''
} ${
toggleActive
? `${small ? 'bg-brand-500' : 'bg-brand-500'}`
: `${small ? 'bg-element-light-lighter-600' : 'bg-gray-300'}`
}`}
>
<div
aria-label="circle"
className={`${toggleSizeCircle} bg-white rounded-full shadow-lg transform duration-300 ease-in-out ${
toggleActive ? `${small ? 'translate-x-3.5' : 'translate-x-6'}` : ''
}`}
className={`${toggleSizeCircle} bg-white rounded-full shadow-lg transform ${
animateEnabled ? 'duration-300 ease-in-out' : ''
} ${toggleActive ? `${small ? 'translate-x-3.5' : 'translate-x-6'}` : ''}`}
/>
</div>
</div>
Expand Down

0 comments on commit f6879e9

Please sign in to comment.