-
-
Notifications
You must be signed in to change notification settings - Fork 409
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: updated settings - new form wrapper (#3725)
* feat: add desktop version of settings form wrapper * chore: move components into forms display section * feat: update wrapper for mobile
- Loading branch information
Showing
15 changed files
with
374 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
packages/components/src/SettingsFormWrapper/SettingsFormTab.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import '@testing-library/jest-dom/vitest' | ||
|
||
import { Tabs } from '@mui/base/Tabs' | ||
import { describe, expect, it } from 'vitest' | ||
|
||
import { render } from '../test/utils' | ||
import { SettingsFormTab } from './SettingsFormTab' | ||
|
||
describe('SettingsFormTab', () => { | ||
it('renders all expected props', () => { | ||
const bodyText = 'Profile settings area' | ||
const headerText = 'Header area' | ||
const notificationText = 'Success message' | ||
|
||
const { getByText } = render( | ||
<Tabs defaultValue={0}> | ||
<SettingsFormTab | ||
tab={{ | ||
body: <>{bodyText}</>, | ||
header: <>{headerText}</>, | ||
notifications: <>{notificationText}</>, | ||
title: 'Profile', | ||
glyph: 'comment', | ||
}} | ||
value={0} | ||
/> | ||
</Tabs>, | ||
) | ||
|
||
expect(getByText(bodyText)).toBeInTheDocument() | ||
expect(getByText(headerText)).toBeInTheDocument() | ||
expect(getByText(notificationText)).toBeInTheDocument() | ||
}) | ||
}) |
40 changes: 40 additions & 0 deletions
40
packages/components/src/SettingsFormWrapper/SettingsFormTab.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { TabPanel } from '@mui/base/TabPanel' | ||
import { Card } from '@theme-ui/components' | ||
import { Box } from 'theme-ui' | ||
|
||
import type { availableGlyphs } from '../Icon/types' | ||
|
||
export interface ITab { | ||
header?: React.ReactNode | ||
notifications?: React.ReactNode | ||
body: React.ReactNode | ||
glyph: availableGlyphs | ||
title: string | ||
} | ||
|
||
interface IProps { | ||
tab: ITab | ||
value: number | ||
} | ||
|
||
export const SettingsFormTab = (props: IProps) => { | ||
const { tab, value } = props | ||
const { body, header, notifications } = tab | ||
|
||
const sx = { | ||
borderRadius: 3, | ||
marginBottom: 3, | ||
padding: 3, | ||
overflow: 'hidden', | ||
} | ||
|
||
return ( | ||
<TabPanel value={value}> | ||
{header && ( | ||
<Card sx={{ ...sx, backgroundColor: 'softblue' }}>{header}</Card> | ||
)} | ||
{notifications && <Box sx={{ ...sx, padding: 0 }}>{notifications}</Box>} | ||
<Card sx={sx}>{body}</Card> | ||
</TabPanel> | ||
) | ||
} |
42 changes: 42 additions & 0 deletions
42
packages/components/src/SettingsFormWrapper/SettingsFormTabList.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import '@testing-library/jest-dom/vitest' | ||
|
||
import { Tabs } from '@mui/base/Tabs' | ||
import { describe, expect, it } from 'vitest' | ||
|
||
import { render } from '../test/utils' | ||
import { SettingsFormTabList } from './SettingsFormTabList' | ||
|
||
import type { availableGlyphs } from '../Icon/types' | ||
|
||
describe('SettingsFormTab', () => { | ||
const title = 'Tab Title' | ||
const tab = { | ||
body: <></>, | ||
title, | ||
glyph: 'comment' as availableGlyphs, | ||
} | ||
|
||
it('renders when more than one tab provided', () => { | ||
const { getAllByText } = render( | ||
<Tabs defaultValue={0}> | ||
<SettingsFormTabList | ||
value={0} | ||
setValue={() => null} | ||
tabs={[tab, tab]} | ||
/> | ||
</Tabs>, | ||
) | ||
|
||
expect(getAllByText('Tab Title')[0]).toBeInTheDocument() | ||
}) | ||
|
||
it('renders nothing when only one tab provided', () => { | ||
const { queryByText } = render( | ||
<Tabs defaultValue={0}> | ||
<SettingsFormTabList value={0} setValue={() => null} tabs={[tab]} /> | ||
</Tabs>, | ||
) | ||
|
||
expect(queryByText(title)).not.toBeInTheDocument() | ||
}) | ||
}) |
105 changes: 105 additions & 0 deletions
105
packages/components/src/SettingsFormWrapper/SettingsFormTabList.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import styled from '@emotion/styled' | ||
import { Tab as BaseTab, tabClasses } from '@mui/base/Tab' | ||
import { TabsList as BaseTabsList } from '@mui/base/TabsList' | ||
import { Box, Select } from 'theme-ui' | ||
|
||
import { Icon } from '../Icon/Icon' | ||
|
||
import type { ITab } from './SettingsFormTab' | ||
|
||
interface IProps { | ||
tabs: ITab[] | ||
value: number | ||
setValue: (value: number) => void | ||
} | ||
|
||
export const SettingsFormTabList = (props: IProps) => { | ||
const { tabs, value, setValue } = props | ||
|
||
if (tabs.length === 1) return | ||
|
||
const Tab = styled(BaseTab)` | ||
color: grey; | ||
cursor: pointer; | ||
background-color: transparent; | ||
padding: 12px 18px; | ||
border: none; | ||
border-radius: 12px; | ||
display: flex; | ||
gap: 8px; | ||
justify-content: flex-start; | ||
&:hover { | ||
background-color: white; | ||
} | ||
&:focus { | ||
outline: 2px solid #666; | ||
} | ||
&.${tabClasses.disabled} { | ||
opacity: 0.5; | ||
cursor: not-allowed; | ||
} | ||
&.${tabClasses.selected} { | ||
color: #1b1b1b; | ||
outline: 2px solid #1b1b1b; | ||
background-color: #e2edf7; | ||
} | ||
` | ||
|
||
const TabsList = styled(BaseTabsList)` | ||
border-radius: inherit; | ||
display: flex; | ||
flex: 2; | ||
gap: 12px; | ||
flex-direction: column; | ||
justify-content: flex-start; | ||
align-content: flex-start; | ||
` | ||
|
||
const defaultValue = tabs.find((_, index) => index === value)?.title || '' | ||
|
||
return ( | ||
<> | ||
<Box sx={{ display: ['none', 'inherit'] }}> | ||
<TabsList> | ||
{tabs.map(({ glyph, title }, index) => { | ||
return ( | ||
<Tab key={index}> | ||
<Icon glyph={glyph} /> {title} | ||
</Tab> | ||
) | ||
})} | ||
</TabsList> | ||
</Box> | ||
|
||
<Box sx={{ display: ['inherit', 'none'] }}> | ||
<TabsList> | ||
<Select | ||
arrow={ | ||
<Icon | ||
glyph="arrow-full-down" | ||
sx={{ | ||
ml: -7, | ||
alignSelf: 'center', | ||
pointerEvents: 'none', | ||
}} | ||
/> | ||
} | ||
defaultValue={defaultValue} | ||
> | ||
{tabs.map(({ title }, index) => { | ||
return ( | ||
<option key={index} onClick={() => setValue(index)}> | ||
{title} | ||
</option> | ||
) | ||
})} | ||
</Select> | ||
</TabsList> | ||
</Box> | ||
</> | ||
) | ||
} |
63 changes: 63 additions & 0 deletions
63
packages/components/src/SettingsFormWrapper/SettingsFormWrapper.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { Alert, Flex, Text } from 'theme-ui' | ||
|
||
import { SettingsFormWrapper } from './SettingsFormWrapper' | ||
|
||
import type { Meta, StoryFn } from '@storybook/react' | ||
|
||
export default { | ||
title: 'Forms/SettingsFormWrapper', | ||
component: SettingsFormWrapper, | ||
} as Meta<typeof SettingsFormWrapper> | ||
|
||
export const Default: StoryFn<typeof SettingsFormWrapper> = () => ( | ||
<div style={{ maxWidth: '900px' }}> | ||
<SettingsFormWrapper | ||
tabs={[ | ||
{ | ||
title: 'Profile', | ||
header: ( | ||
<Flex sx={{ gap: 2, flexDirection: 'column' }}> | ||
<Text as="h3">✏️ Complete your profile</Text> | ||
<Text> | ||
In order to post comments or create content, we'd like you to | ||
share something about yourself. | ||
</Text> | ||
</Flex> | ||
), | ||
body: <>Form Body 1</>, | ||
glyph: 'thunderbolt', | ||
}, | ||
{ | ||
title: 'Notifications', | ||
body: <>Form Body 2</>, | ||
notifications: ( | ||
<Alert variant="success">Nice, all submitted fine.</Alert> | ||
), | ||
glyph: 'account-circle', | ||
}, | ||
{ | ||
title: 'Bad', | ||
body: <>Form Body 3</>, | ||
header: <>Bad thing header</>, | ||
notifications: <Alert variant="failure">Problem! Sort it out!</Alert>, | ||
glyph: 'bazar', | ||
}, | ||
]} | ||
/> | ||
</div> | ||
) | ||
|
||
export const SingleTab: StoryFn<typeof SettingsFormWrapper> = () => ( | ||
<div style={{ maxWidth: '900px' }}> | ||
<SettingsFormWrapper | ||
tabs={[ | ||
{ | ||
title: 'Profile', | ||
body: <>Anything for the moment</>, | ||
header: <>header</>, | ||
glyph: 'thunderbolt', | ||
}, | ||
]} | ||
/> | ||
</div> | ||
) |
24 changes: 24 additions & 0 deletions
24
packages/components/src/SettingsFormWrapper/SettingsFormWrapper.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import '@testing-library/jest-dom/vitest' | ||
|
||
import { fireEvent } from '@testing-library/react' | ||
import { describe, expect, it } from 'vitest' | ||
|
||
import { render } from '../test/utils' | ||
import { Default } from './SettingsFormWrapper.stories' | ||
|
||
import type { IProps } from './SettingsFormWrapper' | ||
|
||
describe('SettingsFormWrapper', () => { | ||
it('changes the tab display as expected', async () => { | ||
const screen = render(<Default {...(Default.args as IProps)} />) | ||
expect(screen.getByText('Form Body 1')).toBeInTheDocument() | ||
|
||
const tabThree = screen.getAllByText('Bad', { | ||
exact: false, | ||
})[0] | ||
|
||
await fireEvent.click(tabThree) | ||
|
||
expect(screen.getByText('Form Body 3')).toBeInTheDocument() | ||
}) | ||
}) |
Oops, something went wrong.