Skip to content
This repository was archived by the owner on Jun 29, 2021. It is now read-only.

Commit bbe0b04

Browse files
Merge pull request #18 from commitd/sh-develop
Add draggaable option and minor updates
2 parents 507ceb7 + 7c9eddc commit bbe0b04

26 files changed

+1490
-653
lines changed

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = {
1414
'prettier/@typescript-eslint',
1515

1616
'plugin:react/recommended',
17+
"plugin:react-hooks/recommended",
1718
'plugin:security/recommended',
1819
// remove rules covered by prettier
1920
'prettier/@typescript-eslint',
@@ -88,6 +89,7 @@ module.exports = {
8889
'warn',
8990
{
9091
allowNullable: true,
92+
allowSafe: true,
9193
ignoreRhs: true
9294
}
9395
],

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=commitd_layout&metric=alert_status)](https://sonarcloud.io/dashboard?id=commitd_layout)
1313
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=commitd_layout&metric=coverage)](https://sonarcloud.io/dashboard?id=commitd_layout)
1414
![GitHub repo size](https://img.shields.io/github/repo-size/commitd/layout)
15+
![Bundle size](https://img.shields.io/bundlephobia/min/@committed/layout)
1516
[![Storybook](https://raw.githubusercontent.com/storybooks/brand/master/badge/badge-storybook.svg)](https://committed.software/layout)
1617

1718
For documentation see <https://committed.software/layout>

example/index.tsx

Lines changed: 248 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
Footer,
1111
LayoutConfig,
1212
useLayout,
13+
LAYOUT_CONFIG_DEFAULTS,
1314
} from '../dist'
1415
import {
1516
ThemeProvider,
@@ -20,6 +21,12 @@ import {
2021
List,
2122
Container,
2223
ThemeSwitch,
24+
FormGroup,
25+
FormControlLabel,
26+
Switch,
27+
CheckToken,
28+
Slider,
29+
Divider,
2330
} from '@committed/components'
2431
import AccountCircle from '@material-ui/icons/AccountCircle'
2532
import { LoremIpsum } from 'lorem-ipsum'
@@ -35,94 +42,253 @@ const lorem = new LoremIpsum({
3542
},
3643
})
3744

38-
const config: Partial<LayoutConfig> = {
39-
navVariant: {
40-
sm: 'temporary',
41-
md: 'persistent',
42-
lg: 'permanent',
43-
},
44-
headerPosition: {
45-
sm: 'relative',
46-
md: 'sticky',
47-
},
48-
collapsible: {
49-
md: true,
50-
lg: false,
51-
},
52-
headerResponse: {
53-
sm: 'static',
54-
md: 'squeezed',
55-
},
56-
contentResponse: {
57-
sm: 'static',
58-
md: 'squeezed',
59-
},
60-
footerResponse: {
61-
sm: 'static',
62-
md: 'squeezed',
63-
},
64-
}
45+
const text = lorem.generateParagraphs(1)
46+
6547
const Layout = () => {
6648
const layout = useLayout()
6749
return <Monospace>{JSON.stringify(layout, null, 2)}</Monospace>
6850
}
6951

70-
const App = () => (
71-
<ThemeProvider>
72-
<Root config={config}>
73-
<Header>
74-
<Typography variant="h5">Application Name</Typography>
75-
<Box flexGrow={1} />
76-
<IconButton color="inherit">
77-
<AccountCircle />
78-
</IconButton>
79-
<ThemeSwitch />
80-
</Header>
81-
<Nav>
82-
<List>
83-
<NavListItem
84-
key="item1"
85-
text="Menu Item 1"
86-
icon={<AccountCircle />}
87-
/>
88-
<NavListItem
89-
key="item2"
90-
text="Menu Item 2"
91-
icon={<AccountCircle />}
92-
/>
93-
<NavListItem
94-
key="item3"
95-
text="Menu Item 3"
96-
icon={<AccountCircle />}
97-
/>
98-
</List>
99-
</Nav>
100-
<Content>
101-
<Container maxWidth="lg">
102-
<Box pt={2}>
103-
<Box mb={2}>
104-
<Typography variant="h4">@committed/layout</Typography>
105-
</Box>
106-
<Layout />
107-
<Box mt={3}>
108-
{new Array(20).fill(null).map((i) => (
109-
<Box mb={1}>
110-
<Typography variant="body2" color="textSecondary">
111-
{lorem.generateParagraphs(1)}
112-
</Typography>
113-
</Box>
114-
))}
52+
interface SelectorProps {
53+
label: string
54+
value: string
55+
setValue: (newValue: string) => void
56+
values: string[]
57+
}
58+
59+
const Selector = ({ label, value, setValue, values }: SelectorProps) => (
60+
<>
61+
<Typography mt={3}>{label}</Typography>
62+
{values.map((key) => (
63+
<CheckToken
64+
color="primary"
65+
selected={value === key}
66+
onClick={() => setValue(key)}
67+
>
68+
{key}
69+
</CheckToken>
70+
))}
71+
<Divider mx={2} />
72+
</>
73+
)
74+
75+
interface NavWidthProps {
76+
setConfigNavWidth: (newValue: number) => void
77+
}
78+
79+
const NavWidth = ({ setConfigNavWidth }) => {
80+
const [hasDragged, setHasDragged] = React.useState(false)
81+
const {
82+
navWidth,
83+
dragged,
84+
setNavWidth,
85+
maxNavWidth,
86+
collapsedWidth,
87+
} = useLayout()
88+
89+
React.useEffect(() => {
90+
if (dragged) setHasDragged(true)
91+
}, [dragged])
92+
93+
const handleChange = (e: any, value: number) => {
94+
if (hasDragged) {
95+
setNavWidth(value)
96+
} else {
97+
setConfigNavWidth(value)
98+
}
99+
}
100+
return (
101+
<Slider
102+
value={navWidth}
103+
onChange={handleChange}
104+
valueLabelDisplay="auto"
105+
min={collapsedWidth}
106+
max={maxNavWidth}
107+
/>
108+
)
109+
}
110+
111+
const App = () => {
112+
const [draggable, setDraggable] = React.useState(false)
113+
114+
const [collapsible, setCollapsible] = React.useState(
115+
LAYOUT_CONFIG_DEFAULTS.collapsible
116+
)
117+
const [collapsedWidth, setCollapsedWidth] = React.useState(
118+
LAYOUT_CONFIG_DEFAULTS.collapsedWidth
119+
)
120+
const [navAnchor, setNavAnchor] = React.useState(
121+
LAYOUT_CONFIG_DEFAULTS.navAnchor
122+
)
123+
const [navVariant, setNavVariant] = React.useState(
124+
LAYOUT_CONFIG_DEFAULTS.navVariant
125+
)
126+
const [navWidth, setNavWidth] = React.useState(
127+
LAYOUT_CONFIG_DEFAULTS.navWidth
128+
)
129+
const [maxNavWidth, setMaxNavWidth] = React.useState(
130+
LAYOUT_CONFIG_DEFAULTS.maxNavWidth
131+
)
132+
const [headerPosition, setHeaderPosition] = React.useState(
133+
LAYOUT_CONFIG_DEFAULTS.headerPosition
134+
)
135+
const [headerResponse, setHeaderResponse] = React.useState(
136+
LAYOUT_CONFIG_DEFAULTS.headerResponse
137+
)
138+
const [contentResponse, setContentResponse] = React.useState(
139+
LAYOUT_CONFIG_DEFAULTS.contentResponse
140+
)
141+
const [footerResponse, setFooterResponse] = React.useState(
142+
LAYOUT_CONFIG_DEFAULTS.footerResponse
143+
)
144+
145+
const config = {
146+
collapsible,
147+
collapsedWidth,
148+
draggable,
149+
navAnchor,
150+
navVariant,
151+
navWidth,
152+
maxNavWidth,
153+
headerPosition,
154+
headerResponse,
155+
contentResponse,
156+
footerResponse,
157+
}
158+
159+
return (
160+
<ThemeProvider>
161+
<Root config={config}>
162+
<Header>
163+
<Typography variant="h5">Application Name</Typography>
164+
<Box flexGrow={1} />
165+
<IconButton color="inherit">
166+
<AccountCircle />
167+
</IconButton>
168+
<ThemeSwitch />
169+
</Header>
170+
<Nav>
171+
<List>
172+
<NavListItem
173+
key="item1"
174+
text="Menu Item 1"
175+
icon={<AccountCircle />}
176+
/>
177+
<NavListItem
178+
key="item2"
179+
text="Menu Item 2"
180+
icon={<AccountCircle />}
181+
/>
182+
<NavListItem
183+
key="item3"
184+
text="Menu Item 3"
185+
icon={<AccountCircle />}
186+
/>
187+
</List>
188+
</Nav>
189+
<Content>
190+
<Container maxWidth="lg">
191+
<Box pt={2}>
192+
<Box mb={2}>
193+
<Typography variant="h4">@committed/layout</Typography>
194+
</Box>
195+
<Layout />
196+
<FormGroup row>
197+
<FormControlLabel
198+
control={
199+
<Switch
200+
checked={draggable}
201+
onChange={() => setDraggable(!draggable)}
202+
color="primary"
203+
/>
204+
}
205+
label="Draggable"
206+
/>
207+
<FormControlLabel
208+
control={
209+
<Switch
210+
checked={collapsible}
211+
onChange={() => setCollapsible(!collapsible)}
212+
color="secondary"
213+
/>
214+
}
215+
label="Collapsible"
216+
/>
217+
</FormGroup>
218+
<Typography>Collapsed Width</Typography>
219+
<Slider
220+
value={collapsedWidth}
221+
onChange={(_e, value) => setCollapsedWidth(value)}
222+
valueLabelDisplay="auto"
223+
min={32}
224+
max={128}
225+
/>
226+
<Typography>Nav width</Typography>
227+
<NavWidth setConfigNavWidth={setNavWidth} />
228+
<Typography>Max Nav width</Typography>
229+
<Slider
230+
value={maxNavWidth}
231+
onChange={(_e, value) => setMaxNavWidth(value)}
232+
valueLabelDisplay="auto"
233+
min={64}
234+
max={2024}
235+
/>
236+
<Selector
237+
label="NavVariant"
238+
value={navVariant}
239+
setValue={setNavVariant}
240+
values={['permanent', 'persistent', 'temporary']}
241+
/>
242+
<Selector
243+
label="NavAnchor"
244+
value={navAnchor}
245+
setValue={setNavAnchor}
246+
values={['left', 'right']}
247+
/>
248+
<Selector
249+
label="HeaderPosition"
250+
value={headerPosition}
251+
setValue={setHeaderPosition}
252+
values={['static', 'relative', 'sticky', 'fixed', 'absolute']}
253+
/>
254+
<Selector
255+
label="HeaderResponse"
256+
value={headerResponse}
257+
setValue={setHeaderResponse}
258+
values={['static', 'squeezed', 'pushed', 'clipped']}
259+
/>
260+
<Selector
261+
label="ContentResponse"
262+
value={contentResponse}
263+
setValue={setContentResponse}
264+
values={['static', 'squeezed', 'pushed']}
265+
/>
266+
<Selector
267+
label="FooterResponse"
268+
value={footerResponse}
269+
setValue={setFooterResponse}
270+
values={['static', 'squeezed', 'pushed']}
271+
/>
272+
<Box mt={3}>
273+
{new Array(20).fill(null).map((i) => (
274+
<Box mb={1}>
275+
<Typography variant="body2" color="textSecondary">
276+
{text}
277+
</Typography>
278+
</Box>
279+
))}
280+
</Box>
115281
</Box>
282+
</Container>
283+
</Content>
284+
<Footer>
285+
<Box p={2}>
286+
<Typography>Footer</Typography>
116287
</Box>
117-
</Container>
118-
</Content>
119-
<Footer>
120-
<Box p={2}>
121-
<Typography>Footer</Typography>
122-
</Box>
123-
</Footer>
124-
</Root>
125-
</ThemeProvider>
126-
)
288+
</Footer>
289+
</Root>
290+
</ThemeProvider>
291+
)
292+
}
127293

128294
ReactDOM.render(<App />, document.getElementById('root'))

0 commit comments

Comments
 (0)