Skip to content

Commit

Permalink
chore(connection-form): clean up connection form styles; address moda…
Browse files Browse the repository at this point in the history
…l jumping behavior (#5836)

* chore(components): allow to control accordion state

* chore(connection-form): separate form layout styles from the content; stretch connection modal to the full available height when advanced is expanded

* chore(form): make sure that all advanced tabs are consistently using FormFieldContainer for spacing

* chore(form): add scrollable spacing at the end of the form content

* chore(form): fix typo

* chore(form): padding not margin

because margin doesn't add scrollable space
  • Loading branch information
gribnoysup committed May 24, 2024
1 parent 8eaca37 commit a76292a
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 290 deletions.
26 changes: 19 additions & 7 deletions packages/compass-components/src/components/accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useCallback, useRef, useState } from 'react';
import { spacing } from '@leafygreen-ui/tokens';
import { css, cx } from '@leafygreen-ui/emotion';
import { palette } from '@leafygreen-ui/palette';
Expand Down Expand Up @@ -50,16 +50,30 @@ const buttonHintStyles = css({
interface AccordionProps extends React.HTMLProps<HTMLButtonElement> {
text: string | React.ReactNode;
hintText?: string;
open?: boolean;
setOpen?: (newValue: boolean) => void;
}
function Accordion({
text,
hintText,
open: _open,
setOpen: _setOpen,
...props
}: React.PropsWithChildren<AccordionProps>): React.ReactElement {
const darkMode = useDarkMode();
const [open, setOpen] = useState(false);
const regionId = useId('region-');
const labelId = useId('label-');
const [localOpen, setLocalOpen] = useState(_open ?? false);
const setOpenRef = useRef(_setOpen);
setOpenRef.current = _setOpen;
const onOpenChange = useCallback(() => {
setLocalOpen((prevValue) => {
const newValue = !prevValue;
setOpenRef.current?.(newValue);
return newValue;
});
}, []);
const regionId = useId();
const labelId = useId();
const open = typeof _open !== 'undefined' ? _open : localOpen;
return (
<>
<button
Expand All @@ -72,9 +86,7 @@ function Accordion({
type="button"
aria-expanded={open ? 'true' : 'false'}
aria-controls={regionId}
onClick={() => {
setOpen((currentOpen) => !currentOpen);
}}
onClick={onOpenChange}
>
<span className={buttonIconContainerStyles}>
<Icon glyph={open ? 'ChevronDown' : 'ChevronRight'} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,23 @@ function AdvancedConnectionOptions({
errors,
updateConnectionFormField,
connectionOptions,
open,
setOpen,
}: {
errors: ConnectionFormError[];
disabled: boolean;
updateConnectionFormField: UpdateConnectionFormField;
connectionOptions: ConnectionOptions;
}): React.ReactElement {
} & Pick<
React.ComponentProps<typeof Accordion>,
'open' | 'setOpen'
>): React.ReactElement {
return (
<Accordion
data-testid="advanced-connection-options"
text="Advanced Connection Options"
open={open}
setOpen={setOpen}
>
<div className={connectionTabsContainer}>
{disabled && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ const tabsStyles = css({
marginTop: spacing[2],
});

const tabContentStyles = css({
// Remove margin from the last form element so that we can consistently apply
// the same padding for the whole connection form content
'& > :last-child': {
marginBottom: 0,
},
});

const tabWithErrorIndicatorStyles = css({
position: 'relative',
'&::after': {
Expand Down Expand Up @@ -131,12 +139,14 @@ function AdvancedOptionsTabs({
data-testid={`connection-${tabObject.id}-tab`}
data-has-error={showTabErrorIndicator}
>
<TabComponent
errors={errors}
connectionStringUrl={connectionStringUrl}
updateConnectionFormField={updateConnectionFormField}
connectionOptions={connectionOptions}
/>
<div className={tabContentStyles}>
<TabComponent
errors={errors}
connectionStringUrl={connectionStringUrl}
updateConnectionFormField={updateConnectionFormField}
connectionOptions={connectionOptions}
/>
</div>
</Tab>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import {
RadioBox,
RadioBoxGroup,
TextInput,
css,
spacing,
} from '@mongodb-js/compass-components';
import type ConnectionStringUrl from 'mongodb-connection-string-url';
import type { MongoClientOptions, ReadPreferenceMode } from 'mongodb';
Expand Down Expand Up @@ -48,10 +46,6 @@ export const readPreferences: ReadPreference[] = [
},
];

const containerStyles = css({
marginTop: spacing[3],
});

function AdvancedTab({
updateConnectionFormField,
connectionStringUrl,
Expand Down Expand Up @@ -96,45 +90,48 @@ function AdvancedTab({
);

return (
<div className={containerStyles}>
<>
{/* Read Preferences */}
<Label htmlFor="read-preferences">Read Preference</Label>
<RadioBoxGroup
onChange={({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
handleFieldChanged(
'readPreference',
// Unset the read preference when default is selected.
value === defaultReadPreference ? undefined : value
);
}}
value={readPreference ?? defaultReadPreference}
data-testid="read-preferences"
id="read-preferences"
size="compact"
>
<RadioBox
id="default-preference-button"
data-testid="default-preference-button"
key="defaultReadPreference"
value={defaultReadPreference}
checked={!readPreference}
<FormFieldContainer>
<Label htmlFor="read-preferences">Read Preference</Label>
<RadioBoxGroup
onChange={({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
handleFieldChanged(
'readPreference',
// Unset the read preference when default is selected.
value === defaultReadPreference ? undefined : value
);
}}
value={readPreference ?? defaultReadPreference}
data-testid="read-preferences"
id="read-preferences"
size="compact"
>
Default
</RadioBox>
{readPreferences.map(({ title, id }) => {
return (
<RadioBox
id={`${id}-preference-button`}
data-testid={`${id}-preference-button`}
checked={readPreference === id}
value={id}
key={id}
>
{title}
</RadioBox>
);
})}
</RadioBoxGroup>
<RadioBox
id="default-preference-button"
data-testid="default-preference-button"
key="defaultReadPreference"
value={defaultReadPreference}
checked={!readPreference}
>
Default
</RadioBox>
{readPreferences.map(({ title, id }) => {
return (
<RadioBox
id={`${id}-preference-button`}
data-testid={`${id}-preference-button`}
checked={readPreference === id}
value={id}
key={id}
>
{title}
</RadioBox>
);
})}
</RadioBoxGroup>
</FormFieldContainer>

{/* Replica Set */}
<FormFieldContainer>
<TextInput
Expand Down Expand Up @@ -169,11 +166,13 @@ function AdvancedTab({
}
/>
</FormFieldContainer>
<UrlOptions
connectionStringUrl={connectionStringUrl}
updateConnectionFormField={updateConnectionFormField}
/>
</div>
<FormFieldContainer>
<UrlOptions
connectionStringUrl={connectionStringUrl}
updateConnectionFormField={updateConnectionFormField}
/>
</FormFieldContainer>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
Label,
RadioBox,
RadioBoxGroup,
spacing,
css,
FormFieldContainer,
} from '@mongodb-js/compass-components';
import type ConnectionStringUrl from 'mongodb-connection-string-url';
import type { AuthMechanism } from 'mongodb';
Expand Down Expand Up @@ -66,12 +66,8 @@ const options: TabOption[] = [
},
];

const containerStyles = css({
marginTop: spacing[3],
});

const contentStyles = css({
marginTop: spacing[3],
display: 'contents',
});

function getSelectedAuthTabForConnectionString(
Expand Down Expand Up @@ -141,31 +137,33 @@ function AuthenticationTab({
const AuthOptionContent = selectedAuthTab.component;

return (
<div className={containerStyles}>
<Label htmlFor="authentication-method-radio-box-group">
Authentication Method
</Label>
<RadioBoxGroup
id="authentication-method-radio-box-group"
data-testid="authentication-method-radio-box-group"
onChange={optionSelected}
value={selectedAuthTab.id}
size="compact"
>
{enabledAuthOptions.map(({ title, id }) => {
return (
<RadioBox
id={`connection-authentication-method-${id}-button`}
data-testid={`connection-authentication-method-${id}-button`}
checked={selectedAuthTab.id === id}
value={id}
key={id}
>
{title}
</RadioBox>
);
})}
</RadioBoxGroup>
<>
<FormFieldContainer>
<Label htmlFor="authentication-method-radio-box-group">
Authentication Method
</Label>
<RadioBoxGroup
id="authentication-method-radio-box-group"
data-testid="authentication-method-radio-box-group"
onChange={optionSelected}
value={selectedAuthTab.id}
size="compact"
>
{enabledAuthOptions.map(({ title, id }) => {
return (
<RadioBox
id={`connection-authentication-method-${id}-button`}
data-testid={`connection-authentication-method-${id}-button`}
checked={selectedAuthTab.id === id}
value={id}
key={id}
>
{title}
</RadioBox>
);
})}
</RadioBoxGroup>
</FormFieldContainer>
<div
className={contentStyles}
data-testid={`${selectedAuthTab.id}-tab-content`}
Expand All @@ -177,7 +175,7 @@ function AuthenticationTab({
connectionOptions={connectionOptions}
/>
</div>
</div>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ const options: KMSProviderMetadata[] = [
},
];

const containerStyles = css({
marginTop: spacing[3],
});

const accordionContainerStyles = css({
marginTop: spacing[3],
});
Expand Down Expand Up @@ -127,14 +123,18 @@ function CSFLETab({
);

return (
<div className={containerStyles}>
<Banner>
In-Use Encryption is an Enterprise/Atlas-only feature of MongoDB.&nbsp;
{/* TODO(COMPASS-5925): Use generic In-Use Encryption URL */}
<Link href="https://dochub.mongodb.org/core/rqe-encrypted-fields">
Learn More
</Link>
</Banner>
<>
<FormFieldContainer>
<Banner>
In-Use Encryption is an Enterprise/Atlas-only feature of
MongoDB.&nbsp;
{/* TODO(COMPASS-5925): Use generic In-Use Encryption URL */}
<Link href="https://dochub.mongodb.org/core/rqe-encrypted-fields">
Learn More
</Link>
</Banner>
</FormFieldContainer>

<FormFieldContainer>
<TextInput
onChange={({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -244,7 +244,7 @@ function CSFLETab({
/>
</FormFieldContainer>
)}
</div>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function GeneralTab({
updateConnectionFormField: UpdateConnectionFormField;
}): React.ReactElement {
return (
<div>
<>
<FormFieldContainer>
<SchemeInput
errors={errors}
Expand All @@ -30,7 +30,7 @@ function GeneralTab({
connectionStringUrl={connectionStringUrl}
updateConnectionFormField={updateConnectionFormField}
/>
</div>
</>
);
}

Expand Down
Loading

0 comments on commit a76292a

Please sign in to comment.