Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit 474ea57

Browse files
committed
feat(layout): add SimpleGrid component, test, examples
1 parent f4d7b0a commit 474ea57

File tree

5 files changed

+184
-0
lines changed

5 files changed

+184
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<template>
2+
<c-button size="sm" @click="minw = '200px'" mb="4"
3+
>increase min width</c-button
4+
>
5+
<c-simple-grid
6+
columns="2"
7+
:spacingX="['5px', '40px']"
8+
:spacingY="['5px', '20px']"
9+
:minChildWidth="minw"
10+
>
11+
<c-box bg="tomato" height="80px"></c-box>
12+
<c-box bg="tomato" height="80px"></c-box>
13+
<c-box bg="tomato" height="80px"></c-box>
14+
<c-box bg="tomato" height="80px"></c-box>
15+
<c-box bg="tomato" height="80px"></c-box>
16+
</c-simple-grid>
17+
</template>
18+
<script setup lang="ts">
19+
import { ref } from 'vue-demi'
20+
21+
const minw = ref('100px')
22+
</script>

packages/layout/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ export * from './link'
1010
export * from './link-box'
1111
export * from './list'
1212
export * from './kbd'
13+
export * from './simple-grid'
1314
export * from './stack'

packages/layout/src/simple-grid.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { CIcon } from '@chakra-ui/c-icon'
2+
import {
3+
HTMLChakraProps,
4+
SystemProps,
5+
ThemingProps,
6+
useMultiStyleConfig,
7+
useStyles,
8+
StylesProvider,
9+
ResponsiveValue,
10+
} from '@chakra-ui/vue-system'
11+
import { h, defineComponent, PropType, computed } from 'vue'
12+
import { chakra, DOMElements } from '@chakra-ui/vue-system'
13+
import { getValidChildren, SNAO } from '@chakra-ui/vue-utils'
14+
import { CGrid, GridProps } from './grid'
15+
import { isNull, isNumber, mapResponsive } from '@chakra-ui/utils'
16+
17+
interface SimpleGridOptions {
18+
/**
19+
* The width at which child elements will break into columns. Pass a number for pixel values or a string for any other valid CSS length.
20+
*/
21+
minChildWidth?: GridProps['minWidth']
22+
/**
23+
* The number of columns
24+
*/
25+
columns?: ResponsiveValue<number>
26+
/**
27+
* The gap between the grid items
28+
*/
29+
spacing?: GridProps['gridGap']
30+
/**
31+
* The column gap between the grid items
32+
*/
33+
spacingX?: GridProps['gridGap']
34+
/**
35+
* The row gap between the grid items
36+
*/
37+
spacingY?: GridProps['gridGap']
38+
}
39+
40+
export interface SimpleGridProps extends GridProps, SimpleGridOptions {}
41+
42+
/**
43+
* SimpleGrid
44+
*
45+
* Vue component make that providers a simpler interface, and
46+
* make its easy to create responsive grid layouts.
47+
*
48+
* @see Docs https://vue.chakra-ui.com/docs/layout/simple-grid
49+
*/
50+
export const CSimpleGrid = defineComponent({
51+
props: {
52+
as: {
53+
type: [Object, String] as PropType<DOMElements>,
54+
default: 'ul',
55+
},
56+
minChildWidth: SNAO as PropType<SimpleGridProps['minWidth']>,
57+
columns: SNAO as PropType<SimpleGridProps['columns']>,
58+
spacing: SNAO as PropType<SimpleGridProps['gridGap']>,
59+
spacingX: SNAO as PropType<SimpleGridProps['gridGap']>,
60+
spacingY: SNAO as PropType<SimpleGridProps['gridGap']>,
61+
},
62+
setup(props, { slots, attrs }) {
63+
const templateColumns = computed(() =>
64+
props.minChildWidth
65+
? widthToColumns(props.minChildWidth)
66+
: countToColumns(props.columns)
67+
)
68+
69+
return () => {
70+
return h(
71+
CGrid,
72+
{
73+
label: 'simple-grid',
74+
gap: props.spacing,
75+
columnGap: props.spacingX,
76+
rowGap: props.spacingY,
77+
templateColumns: templateColumns.value,
78+
...attrs,
79+
},
80+
slots
81+
)
82+
}
83+
},
84+
})
85+
86+
function toPx(n: string | number) {
87+
return isNumber(n) ? `${n}px` : n
88+
}
89+
90+
function widthToColumns(width: any) {
91+
return mapResponsive(width, (value) =>
92+
isNull(value) ? null : `repeat(auto-fit, minmax(${toPx(value)}, 1fr))`
93+
)
94+
}
95+
96+
function countToColumns(count: any) {
97+
return mapResponsive(count, (value) =>
98+
isNull(value) ? null : `repeat(${value}, minmax(0, 1fr))`
99+
)
100+
}

packages/layout/tests/__snapshots__/layout.test.ts.snap

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,40 @@ exports[`<CList /> <CListItem /> <CUnorderedList /> <COrderedList /> <CListIcon
363363
</DocumentFragment>
364364
`;
365365

366+
exports[`<CSimpleGrid /> should render properly 1`] = `
367+
<DocumentFragment>
368+
<div
369+
class="chakra-simple-grid css-12tmpmw"
370+
>
371+
<div
372+
class="chakra-box css-9rloc5"
373+
>
374+
simple 1
375+
</div>
376+
<div
377+
class="chakra-box css-9rloc5"
378+
>
379+
simple 2
380+
</div>
381+
<div
382+
class="chakra-box css-9rloc5"
383+
>
384+
simple 3
385+
</div>
386+
<div
387+
class="chakra-box css-9rloc5"
388+
>
389+
simple 4
390+
</div>
391+
<div
392+
class="chakra-box css-9rloc5"
393+
>
394+
simple 5
395+
</div>
396+
</div>
397+
</DocumentFragment>
398+
`;
399+
366400
exports[`<CSquare /> & <CCircle /> should render properly 1`] = `
367401
<DocumentFragment>
368402
<div

packages/layout/tests/layout.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
CLinkOverlay,
1414
CBadge,
1515
CStack,
16+
CSimpleGrid,
1617
CVStack,
1718
CHStack,
1819
CGridItem,
@@ -328,3 +329,29 @@ describe('<CList /> <CListItem /> <CUnorderedList /> <COrderedList /> <CListIcon
328329
expect(asFragment()).toMatchSnapshot()
329330
})
330331
})
332+
333+
describe('<CSimpleGrid />', () => {
334+
const renderComponent = () =>
335+
render({
336+
components: { CSimpleGrid, CBox },
337+
template: `
338+
<c-simple-grid
339+
columns="2"
340+
:spacingX="['5px', '40px']"
341+
:spacingY="['5px', '20px']"
342+
minChildWidth="100px"
343+
>
344+
<c-box bg="tomato" height="80px">simple 1</c-box>
345+
<c-box bg="tomato" height="80px">simple 2</c-box>
346+
<c-box bg="tomato" height="80px">simple 3</c-box>
347+
<c-box bg="tomato" height="80px">simple 4</c-box>
348+
<c-box bg="tomato" height="80px">simple 5</c-box>
349+
</c-simple-grid>
350+
`,
351+
})
352+
353+
it('should render properly', async () => {
354+
const { asFragment } = renderComponent()
355+
expect(asFragment()).toMatchSnapshot()
356+
})
357+
})

0 commit comments

Comments
 (0)