Skip to content

Commit 6db7706

Browse files
committed
✨ Add Flex component
1 parent 8f75064 commit 6db7706

File tree

10 files changed

+540
-0
lines changed

10 files changed

+540
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ import { Accordion } from 'webcoreui/react'
237237
- [ConditionalWrapper](https://github.com/Frontendland/webcoreui/tree/main/src/components/ConditionalWrapper)
238238
- [Copy](https://github.com/Frontendland/webcoreui/tree/main/src/components/Copy)
239239
- [DataTable](https://github.com/Frontendland/webcoreui/tree/main/src/components/DataTable)
240+
- [Flex](https://github.com/Frontendland/webcoreui/tree/main/src/components/Flex)
240241
- [Footer](https://github.com/Frontendland/webcoreui/tree/main/src/components/Footer)
241242
- [Group](https://github.com/Frontendland/webcoreui/tree/main/src/components/Group)
242243
- [Icon](https://github.com/Frontendland/webcoreui/tree/main/src/components/Icon)

src/components/Flex/Flex.astro

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
import type { FlexProps } from './flex'
3+
4+
import { classNames } from '../../utils/classNames'
5+
import { getLayoutClasses } from '../../utils/getLayoutClasses'
6+
7+
interface Props extends FlexProps {}
8+
9+
const {
10+
element = 'div',
11+
gap,
12+
alignment,
13+
direction,
14+
wrap,
15+
className,
16+
...rest
17+
} = Astro.props
18+
19+
const Component = element
20+
21+
const classes = classNames([
22+
'flex',
23+
getLayoutClasses({ gap, alignment, direction, wrap }),
24+
className
25+
])
26+
27+
const props = {
28+
class: classes
29+
}
30+
---
31+
32+
<Component {...props} {...rest}>
33+
<slot />
34+
</Component>

src/components/Flex/Flex.svelte

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script lang="ts">
2+
import type { FlexProps } from './flex'
3+
4+
import { classNames } from '../../utils/classNames'
5+
import { getLayoutClasses } from '../../utils/getLayoutClasses'
6+
7+
export let element: FlexProps['className'] = 'div'
8+
export let gap: FlexProps['gap'] = ''
9+
export let alignment: FlexProps['alignment'] = {}
10+
export let direction: FlexProps['direction'] = ''
11+
export let wrap: FlexProps['wrap'] = ''
12+
export let className: FlexProps['className'] = ''
13+
14+
const classes = classNames([
15+
'flex',
16+
getLayoutClasses({ gap, alignment, direction, wrap }),
17+
className
18+
])
19+
20+
const props = {
21+
class: classes
22+
}
23+
</script>
24+
25+
<svelte:element this={element} {...props} {...$$restProps}>
26+
<slot />
27+
</svelte:element>

src/components/Flex/Flex.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react'
2+
import type { ReactFlexProps } from './flex'
3+
4+
import { classNames } from '../../utils/classNames'
5+
import { getLayoutClasses } from '../../utils/getLayoutClasses'
6+
7+
const Flex = ({
8+
Element = 'div',
9+
gap,
10+
alignment,
11+
direction,
12+
wrap,
13+
className,
14+
children,
15+
...rest
16+
}: ReactFlexProps) => {
17+
const classes = classNames([
18+
'flex',
19+
getLayoutClasses({ gap, alignment, direction, wrap }),
20+
className
21+
])
22+
23+
return (
24+
<Element className={classes} {...rest}>
25+
{children}
26+
</Element>
27+
)
28+
}
29+
30+
export default Flex

src/components/Flex/flex.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type {
2+
Direction,
3+
Gap,
4+
HorizontalAlignment,
5+
Responsive,
6+
VerticalAlignment,
7+
Wrap
8+
} from '../../utils/getLayoutClasses'
9+
10+
type Alignment = {
11+
horizontal?: HorizontalAlignment
12+
vertical?: VerticalAlignment
13+
}
14+
15+
export type FlexProps = {
16+
element?: string
17+
gap?: Responsive<Gap>
18+
alignment?: Responsive<Alignment>
19+
direction?: Responsive<Direction>
20+
wrap?: Responsive<Wrap>
21+
className?: string
22+
}
23+
24+
export type ReactFlexProps = {
25+
Element?: keyof JSX.IntrinsicElements
26+
children: React.ReactNode
27+
} & Omit<FlexProps, 'element'>

src/pages/components/flex.astro

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
import Box from '@static/Box.astro'
3+
import ComponentWrapper from '@static/ComponentWrapper.astro'
4+
import Layout from '@static/Layout.astro'
5+
6+
import AstroFlex from '@components/Flex/Flex.astro'
7+
import SvelteFlex from '@components/Flex/Flex.svelte'
8+
import ReactFlex from '@components/Flex/Flex.tsx'
9+
10+
import { getSections } from '@helpers'
11+
12+
import type { Gap, Responsive } from '@utils/getLayoutClasses'
13+
14+
const sections = getSections({
15+
title: 'flex items',
16+
components: [AstroFlex, SvelteFlex, ReactFlex]
17+
})
18+
19+
const gap = {
20+
xs: 'xs',
21+
sm: 'sm',
22+
md: 'md',
23+
lg: 'default'
24+
} as Responsive<Gap>
25+
---
26+
27+
<Layout>
28+
<h1>Flex</h1>
29+
<div class="grid md-2 lg-3">
30+
<ComponentWrapper type="Astro">
31+
<AstroFlex gap={gap}>
32+
<Box>1</Box>
33+
<Box>2</Box>
34+
<Box>3</Box>
35+
</AstroFlex>
36+
</ComponentWrapper>
37+
38+
<ComponentWrapper type="Svelte">
39+
<SvelteFlex gap={gap}>
40+
<Box>1</Box>
41+
<Box>2</Box>
42+
<Box>3</Box>
43+
</SvelteFlex>
44+
</ComponentWrapper>
45+
46+
<ComponentWrapper type="React">
47+
<ReactFlex gap={gap}>
48+
<Box>1</Box>
49+
<Box>2</Box>
50+
<Box>3</Box>
51+
</ReactFlex>
52+
</ComponentWrapper>
53+
</div>
54+
55+
{sections.map(section => (
56+
<h1>{section.title}</h1>
57+
<Fragment>
58+
{section.subTitle && <h2 set:html={section.subTitle} />}
59+
</Fragment>
60+
<div class="grid md-2 lg-3">
61+
<ComponentWrapper title="Default">
62+
<section.component>
63+
<Box>1</Box>
64+
<Box>2</Box>
65+
<Box>3</Box>
66+
</section.component>
67+
</ComponentWrapper>
68+
69+
<ComponentWrapper title="Custom gap">
70+
<section.component gap="xs">
71+
<Box>1</Box>
72+
<Box>2</Box>
73+
<Box>3</Box>
74+
</section.component>
75+
</ComponentWrapper>
76+
77+
<ComponentWrapper title="Custom direction">
78+
<section.component direction="column">
79+
<Box>1</Box>
80+
<Box>2</Box>
81+
<Box>3</Box>
82+
</section.component>
83+
</ComponentWrapper>
84+
85+
<ComponentWrapper title="Row reverse">
86+
<section.component direction="row-reverse">
87+
<Box>1</Box>
88+
<Box>2</Box>
89+
<Box>3</Box>
90+
</section.component>
91+
</ComponentWrapper>
92+
93+
<ComponentWrapper title="Column reverse">
94+
<section.component direction="column-reverse">
95+
<Box>1</Box>
96+
<Box>2</Box>
97+
<Box>3</Box>
98+
</section.component>
99+
</ComponentWrapper>
100+
101+
<ComponentWrapper title="Horizontal alignment">
102+
<section.component alignment={{ horizontal: 'center' }}>
103+
<Box>1</Box>
104+
<Box>2</Box>
105+
<Box>3</Box>
106+
</section.component>
107+
</ComponentWrapper>
108+
109+
<ComponentWrapper title="Vertical alignment">
110+
<section.component alignment={{ vertical: 'center' }} direction="column">
111+
<Box>1</Box>
112+
<Box>2</Box>
113+
<Box>3</Box>
114+
</section.component>
115+
</ComponentWrapper>
116+
117+
<ComponentWrapper title="Wrapping">
118+
<section.component wrap="wrap">
119+
<Box>1</Box>
120+
<Box>2</Box>
121+
<Box>3</Box>
122+
<Box>4</Box>
123+
<Box>5</Box>
124+
<Box>6</Box>
125+
</section.component>
126+
</ComponentWrapper>
127+
128+
<ComponentWrapper title="Multiple properties">
129+
<section.component
130+
gap="sm"
131+
wrap="wrap"
132+
alignment={{ horizontal: 'center', vertical: 'center' }}
133+
direction="row-reverse"
134+
>
135+
<Box>1</Box>
136+
<Box>2</Box>
137+
<Box>3</Box>
138+
<Box>4</Box>
139+
<Box>5</Box>
140+
<Box>6</Box>
141+
</section.component>
142+
</ComponentWrapper>
143+
</div>
144+
))}
145+
</Layout>

src/pages/css/utilities.astro

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ const wraps = [
7373
</Card>
7474

7575
<h3>Flex</h3>
76+
77+
<p>You can also use the <code><a href="/components/flex">Flex</a></code> component to build flexible layouts.</p>
78+
7679
<Card className="my" title="Gaps">
7780
{spacings.map(space => (
7881
<div class:list={['flex mb', space]}>

src/pages/index.astro

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Checkbox from '@components/Checkbox/Checkbox.astro'
1717
import Collapsible from '@components/Collapsible/Collapsible.astro'
1818
import Copy from '@components/Copy/Copy.astro'
1919
import DataTable from '@components/DataTable/DataTable.astro'
20+
import Flex from '@components/Flex/Flex.astro'
2021
import Footer from '@components/Footer/Footer.astro'
2122
import Group from '@components/Group/Group.astro'
2223
import Icon from '@components/Icon/Icon.astro'
@@ -162,6 +163,13 @@ import {
162163
className="data-table absolute"
163164
/>
164165
</CardWrapper>
166+
<CardWrapper title="Flex" href="/components/flex">
167+
<Flex gap="xs" wrap="wrap">
168+
<Box>1</Box>
169+
<Box>2</Box>
170+
<Box>3</Box>
171+
</Flex>
172+
</CardWrapper>
165173
<CardWrapper title="Footer" href="/components/footer">
166174
<Footer columns={[{ title: 'WEBCORE', items: [] }]} />
167175
</CardWrapper>

0 commit comments

Comments
 (0)