@pyreon/coolgrid 0.24.4 → 0.24.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -11
- package/src/Col/component.tsx +0 -61
- package/src/Col/index.ts +0 -3
- package/src/Col/styled.ts +0 -107
- package/src/Container/component.tsx +0 -80
- package/src/Container/index.ts +0 -3
- package/src/Container/styled.ts +0 -37
- package/src/Container/utils.ts +0 -13
- package/src/Row/component.tsx +0 -78
- package/src/Row/index.ts +0 -3
- package/src/Row/styled.ts +0 -70
- package/src/__tests__/Col.test.ts +0 -138
- package/src/__tests__/Container.styled.test.ts +0 -49
- package/src/__tests__/Container.test.ts +0 -152
- package/src/__tests__/Row.test.ts +0 -142
- package/src/__tests__/config.test.ts +0 -120
- package/src/__tests__/contextCascading.test.ts +0 -114
- package/src/__tests__/coolgrid.browser.test.tsx +0 -181
- package/src/__tests__/index.test.ts +0 -35
- package/src/__tests__/native-markers.test.ts +0 -13
- package/src/__tests__/useContext.test.ts +0 -92
- package/src/__tests__/utils.test.ts +0 -144
- package/src/constants.ts +0 -26
- package/src/context/ContainerContext.ts +0 -9
- package/src/context/RowContext.ts +0 -9
- package/src/context/index.ts +0 -4
- package/src/env.d.ts +0 -6
- package/src/index.ts +0 -7
- package/src/theme.ts +0 -40
- package/src/types.ts +0 -72
- package/src/useContext.tsx +0 -52
- package/src/utils.ts +0 -23
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { getContainerWidth } from '../Container/utils'
|
|
3
|
-
|
|
4
|
-
describe('Container/utils – getContainerWidth', () => {
|
|
5
|
-
it('returns width from props when present', () => {
|
|
6
|
-
const result = getContainerWidth({ width: 960 }, {})
|
|
7
|
-
expect(result).toBe(960)
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
it('prefers props.width over theme.grid.container', () => {
|
|
11
|
-
const result = getContainerWidth(
|
|
12
|
-
{ width: 800 },
|
|
13
|
-
{ grid: { container: { xs: '100%', md: 720 } } },
|
|
14
|
-
)
|
|
15
|
-
expect(result).toBe(800)
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('falls back to theme.grid.container', () => {
|
|
19
|
-
const result = getContainerWidth({}, { grid: { container: { xs: '100%', md: 720 } } })
|
|
20
|
-
expect(result).toEqual({ xs: '100%', md: 720 })
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('falls back to theme.coolgrid.container when grid is missing', () => {
|
|
24
|
-
const result = getContainerWidth({}, { coolgrid: { container: { xs: '100%', lg: 960 } } })
|
|
25
|
-
expect(result).toEqual({ xs: '100%', lg: 960 })
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('returns undefined/falsy when nothing matches', () => {
|
|
29
|
-
expect(getContainerWidth({}, {})).toBeFalsy()
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('returns undefined/falsy when both are undefined', () => {
|
|
33
|
-
expect(getContainerWidth(undefined, undefined)).toBeFalsy()
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('returns undefined/falsy when both are empty objects', () => {
|
|
37
|
-
expect(getContainerWidth({}, {})).toBeFalsy()
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('returns string width from props', () => {
|
|
41
|
-
const result = getContainerWidth({ width: '100%' }, {})
|
|
42
|
-
expect(result).toBe('100%')
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('returns responsive object from props', () => {
|
|
46
|
-
const result = getContainerWidth({ width: { xs: '100%', md: 720, lg: 960 } }, {})
|
|
47
|
-
expect(result).toEqual({ xs: '100%', md: 720, lg: 960 })
|
|
48
|
-
})
|
|
49
|
-
})
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import type { VNode } from '@pyreon/core'
|
|
2
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
-
|
|
4
|
-
const mockProvide = vi.fn()
|
|
5
|
-
const mockUseContext = vi.fn()
|
|
6
|
-
|
|
7
|
-
vi.mock('@pyreon/core', async (importOriginal) => {
|
|
8
|
-
const original = await importOriginal<typeof import('@pyreon/core')>()
|
|
9
|
-
return {
|
|
10
|
-
...original,
|
|
11
|
-
provide: (...args: any[]) => {
|
|
12
|
-
mockProvide(...args)
|
|
13
|
-
},
|
|
14
|
-
useContext: (ctx: any) => {
|
|
15
|
-
if (mockUseContext.mock.calls.length > 0) {
|
|
16
|
-
return mockUseContext(ctx)
|
|
17
|
-
}
|
|
18
|
-
return original.useContext(ctx)
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const asVNode = (v: unknown) => v as VNode
|
|
24
|
-
|
|
25
|
-
describe('Container', () => {
|
|
26
|
-
beforeEach(() => {
|
|
27
|
-
vi.clearAllMocks()
|
|
28
|
-
// unistyle context returns empty theme
|
|
29
|
-
mockUseContext.mockReturnValue({ theme: {} })
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('returns a VNode', { timeout: 60_000 }, async () => {
|
|
33
|
-
// Long timeout: this test dynamic-imports Container on first run,
|
|
34
|
-
// which cold-loads the full styler → unistyle chain. On slow CI
|
|
35
|
-
// runners it consistently hits ~13-14s, flaking against the
|
|
36
|
-
// default 15s timeout. 30s gives comfortable headroom without
|
|
37
|
-
// masking real hangs.
|
|
38
|
-
const Container = (await import('../Container')).default
|
|
39
|
-
const result = asVNode(Container({ children: 'test' }))
|
|
40
|
-
expect(result).toBeDefined()
|
|
41
|
-
expect(result.type).toBeDefined()
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('has correct displayName', async () => {
|
|
45
|
-
const Container = (await import('../Container')).default
|
|
46
|
-
expect(Container.displayName).toBe('@pyreon/coolgrid/Container')
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('has correct pkgName', async () => {
|
|
50
|
-
const Container = (await import('../Container')).default
|
|
51
|
-
expect(Container.pkgName).toBe('@pyreon/coolgrid')
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('has PYREON__COMPONENT static', async () => {
|
|
55
|
-
const Container = (await import('../Container')).default
|
|
56
|
-
expect(Container.PYREON__COMPONENT).toBe('@pyreon/coolgrid/Container')
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
it('passes $coolgrid prop with width and extraStyles', async () => {
|
|
60
|
-
const Container = (await import('../Container')).default
|
|
61
|
-
const result = asVNode(Container({ children: 'test' }))
|
|
62
|
-
expect(result.props).toHaveProperty('$coolgrid')
|
|
63
|
-
expect(result.props.$coolgrid).toHaveProperty('width')
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('provides ContainerContext', async () => {
|
|
67
|
-
const Container = (await import('../Container')).default
|
|
68
|
-
Container({ columns: 12, gap: 16, children: 'test' })
|
|
69
|
-
expect(mockProvide).toHaveBeenCalledTimes(1)
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('provides context with grid values', async () => {
|
|
73
|
-
const Container = (await import('../Container')).default
|
|
74
|
-
Container({ columns: 24, gap: 16, gutter: 8, children: 'test' })
|
|
75
|
-
const config = mockProvide.mock.calls[0]?.[1] as Record<string, unknown>
|
|
76
|
-
expect(config.columns).toBe(24)
|
|
77
|
-
expect(config.gap).toBe(16)
|
|
78
|
-
expect(config.gutter).toBe(8)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('uses width prop to override containerWidth', async () => {
|
|
82
|
-
const Container = (await import('../Container')).default
|
|
83
|
-
const result = asVNode(Container({ width: 960, children: 'test' }))
|
|
84
|
-
expect((result.props.$coolgrid as Record<string, unknown>).width).toBe(960)
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
it('accepts width as function', async () => {
|
|
88
|
-
const Container = (await import('../Container')).default
|
|
89
|
-
const widthFn = (_containerWidth: any) => 800
|
|
90
|
-
const result = asVNode(Container({ width: widthFn as any, children: 'test' }))
|
|
91
|
-
expect((result.props.$coolgrid as Record<string, unknown>).width).toBe(800)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it('strips context keys from DOM props', async () => {
|
|
95
|
-
const Container = (await import('../Container')).default
|
|
96
|
-
const result = asVNode(
|
|
97
|
-
Container({
|
|
98
|
-
columns: 12,
|
|
99
|
-
gap: 16,
|
|
100
|
-
'data-testid': 'container',
|
|
101
|
-
children: 'test',
|
|
102
|
-
}),
|
|
103
|
-
)
|
|
104
|
-
expect(result.props['data-testid']).toBe('container')
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
it('passes css as extraStyles in $coolgrid', async () => {
|
|
108
|
-
const Container = (await import('../Container')).default
|
|
109
|
-
const customCss = 'background: red;'
|
|
110
|
-
const result = asVNode(Container({ css: customCss, children: 'test' }))
|
|
111
|
-
expect((result.props.$coolgrid as Record<string, unknown>).extraStyles).toBe(customCss)
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('provides context with all grid keys', async () => {
|
|
115
|
-
const Container = (await import('../Container')).default
|
|
116
|
-
Container({
|
|
117
|
-
columns: 12,
|
|
118
|
-
gap: 16,
|
|
119
|
-
gutter: 8,
|
|
120
|
-
padding: 4,
|
|
121
|
-
size: 6,
|
|
122
|
-
contentAlignX: 'center',
|
|
123
|
-
children: 'test',
|
|
124
|
-
})
|
|
125
|
-
const config = mockProvide.mock.calls[0]?.[1] as Record<string, unknown>
|
|
126
|
-
expect(config).toHaveProperty('columns')
|
|
127
|
-
expect(config).toHaveProperty('gap')
|
|
128
|
-
expect(config).toHaveProperty('gutter')
|
|
129
|
-
expect(config).toHaveProperty('padding')
|
|
130
|
-
expect(config).toHaveProperty('size')
|
|
131
|
-
expect(config).toHaveProperty('contentAlignX')
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
it('renders with data-coolgrid attribute in dev mode', async () => {
|
|
135
|
-
const Container = (await import('../Container')).default
|
|
136
|
-
const result = asVNode(Container({ children: 'test' }))
|
|
137
|
-
expect(result.props['data-coolgrid']).toBe('container')
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it("passes component prop as 'as'", async () => {
|
|
141
|
-
const Container = (await import('../Container')).default
|
|
142
|
-
const customComponent = (() => null) as any
|
|
143
|
-
const result = asVNode(Container({ component: customComponent, children: 'test' }))
|
|
144
|
-
expect(result.props.as).toBe(customComponent)
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
it('renders children in VNode', async () => {
|
|
148
|
-
const Container = (await import('../Container')).default
|
|
149
|
-
const result = asVNode(Container({ children: 'hello world' }))
|
|
150
|
-
expect(result.children).toBeDefined()
|
|
151
|
-
})
|
|
152
|
-
})
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import type { VNode } from '@pyreon/core'
|
|
2
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
-
|
|
4
|
-
const mockProvide = vi.fn()
|
|
5
|
-
const mockUseContext = vi.fn()
|
|
6
|
-
|
|
7
|
-
vi.mock('@pyreon/core', async (importOriginal) => {
|
|
8
|
-
const original = await importOriginal<typeof import('@pyreon/core')>()
|
|
9
|
-
return {
|
|
10
|
-
...original,
|
|
11
|
-
provide: (...args: any[]) => {
|
|
12
|
-
mockProvide(...args)
|
|
13
|
-
},
|
|
14
|
-
useContext: (ctx: any) => {
|
|
15
|
-
if (mockUseContext.mock.calls.length > 0) {
|
|
16
|
-
return mockUseContext(ctx)
|
|
17
|
-
}
|
|
18
|
-
return original.useContext(ctx)
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const asVNode = (v: unknown) => v as VNode
|
|
24
|
-
|
|
25
|
-
describe('Row', () => {
|
|
26
|
-
beforeEach(() => {
|
|
27
|
-
vi.clearAllMocks()
|
|
28
|
-
// unistyle context returns empty theme, container context returns empty
|
|
29
|
-
mockUseContext.mockReturnValue({})
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
// First test in this file pays the cold-import cost for the entire coolgrid
|
|
33
|
-
// module graph (@pyreon/core + ui-core + unistyle + styler + rocketstyle).
|
|
34
|
-
// Warm it takes ~200ms, but on cold CI shared runners the Vite transform of
|
|
35
|
-
// that graph can spike past the 15s default and time out (PR #225 flakes).
|
|
36
|
-
// Per-test timeout bump — subsequent tests in the file reuse the cached
|
|
37
|
-
// module and run in 0ms, so the global 15s budget stays strict everywhere
|
|
38
|
-
// else.
|
|
39
|
-
it('returns a VNode', { timeout: 60000 }, async () => {
|
|
40
|
-
const Row = (await import('../Row')).default
|
|
41
|
-
const result = asVNode(Row({ children: 'test' }))
|
|
42
|
-
expect(result).toBeDefined()
|
|
43
|
-
expect(result.type).toBeDefined()
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('has correct displayName', async () => {
|
|
47
|
-
const Row = (await import('../Row')).default
|
|
48
|
-
expect(Row.displayName).toBe('@pyreon/coolgrid/Row')
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it('has correct pkgName', async () => {
|
|
52
|
-
const Row = (await import('../Row')).default
|
|
53
|
-
expect(Row.pkgName).toBe('@pyreon/coolgrid')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('has PYREON__COMPONENT static', async () => {
|
|
57
|
-
const Row = (await import('../Row')).default
|
|
58
|
-
expect(Row.PYREON__COMPONENT).toBe('@pyreon/coolgrid/Row')
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
it('passes $coolgrid prop with row values', async () => {
|
|
62
|
-
const Row = (await import('../Row')).default
|
|
63
|
-
const result = asVNode(Row({ gap: 16, children: 'test' }))
|
|
64
|
-
expect(result.props).toHaveProperty('$coolgrid')
|
|
65
|
-
expect(result.props.$coolgrid).toHaveProperty('gap')
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it('provides RowContext', async () => {
|
|
69
|
-
const Row = (await import('../Row')).default
|
|
70
|
-
Row({ gap: 16, columns: 12, children: 'test' })
|
|
71
|
-
expect(mockProvide).toHaveBeenCalledTimes(1)
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
it('provides context with grid values', async () => {
|
|
75
|
-
const Row = (await import('../Row')).default
|
|
76
|
-
Row({ columns: 24, gap: 16, gutter: 8, children: 'test' })
|
|
77
|
-
const config = mockProvide.mock.calls[0]?.[1] as Record<string, unknown>
|
|
78
|
-
expect(config.columns).toBe(24)
|
|
79
|
-
expect(config.gap).toBe(16)
|
|
80
|
-
expect(config.gutter).toBe(8)
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('passes contentAlignX to $coolgrid', async () => {
|
|
84
|
-
const Row = (await import('../Row')).default
|
|
85
|
-
const result = asVNode(Row({ contentAlignX: 'center', children: 'test' }))
|
|
86
|
-
expect((result.props.$coolgrid as Record<string, unknown>).contentAlignX).toBe('center')
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('strips context keys from DOM props', async () => {
|
|
90
|
-
const Row = (await import('../Row')).default
|
|
91
|
-
const result = asVNode(
|
|
92
|
-
Row({
|
|
93
|
-
columns: 12,
|
|
94
|
-
gap: 16,
|
|
95
|
-
'data-testid': 'row',
|
|
96
|
-
children: 'test',
|
|
97
|
-
}),
|
|
98
|
-
)
|
|
99
|
-
expect(result.props['data-testid']).toBe('row')
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('passes css as extraStyles in $coolgrid when provided', async () => {
|
|
103
|
-
const Row = (await import('../Row')).default
|
|
104
|
-
const customCss = 'background: blue;'
|
|
105
|
-
const result = asVNode(Row({ css: customCss, children: 'test' }))
|
|
106
|
-
expect((result.props.$coolgrid as Record<string, unknown>).extraStyles).toBe(customCss)
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
it('passes gutter in $coolgrid', async () => {
|
|
110
|
-
const Row = (await import('../Row')).default
|
|
111
|
-
const result = asVNode(Row({ gutter: 24, children: 'test' }))
|
|
112
|
-
expect((result.props.$coolgrid as Record<string, unknown>).gutter).toBe(24)
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('provides context including colCss and colComponent', async () => {
|
|
116
|
-
const Row = (await import('../Row')).default
|
|
117
|
-
const colComp = (() => null) as any
|
|
118
|
-
Row({ colCss: 'color: red;', colComponent: colComp, children: 'test' })
|
|
119
|
-
const config = mockProvide.mock.calls[0]?.[1] as Record<string, unknown>
|
|
120
|
-
expect(config.colCss).toBe('color: red;')
|
|
121
|
-
expect(config.colComponent).toBe(colComp)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it('renders with data-coolgrid attribute in dev mode', async () => {
|
|
125
|
-
const Row = (await import('../Row')).default
|
|
126
|
-
const result = asVNode(Row({ children: 'test' }))
|
|
127
|
-
expect(result.props['data-coolgrid']).toBe('row')
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it("passes component prop as 'as'", async () => {
|
|
131
|
-
const Row = (await import('../Row')).default
|
|
132
|
-
const customComponent = (() => null) as any
|
|
133
|
-
const result = asVNode(Row({ component: customComponent, children: 'test' }))
|
|
134
|
-
expect(result.props.as).toBe(customComponent)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('renders children in VNode', async () => {
|
|
138
|
-
const Row = (await import('../Row')).default
|
|
139
|
-
const result = asVNode(Row({ children: 'hello' }))
|
|
140
|
-
expect(result.children).toBeDefined()
|
|
141
|
-
})
|
|
142
|
-
})
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
|
|
3
|
-
describe('config', () => {
|
|
4
|
-
describe('theme defaults', () => {
|
|
5
|
-
it('has correct default theme', async () => {
|
|
6
|
-
const theme = (await import('../theme')).default
|
|
7
|
-
expect(theme).toEqual({
|
|
8
|
-
rootSize: 16,
|
|
9
|
-
breakpoints: {
|
|
10
|
-
xs: 0,
|
|
11
|
-
sm: 576,
|
|
12
|
-
md: 768,
|
|
13
|
-
lg: 992,
|
|
14
|
-
xl: 1200,
|
|
15
|
-
},
|
|
16
|
-
grid: {
|
|
17
|
-
columns: 12,
|
|
18
|
-
container: {
|
|
19
|
-
xs: '100%',
|
|
20
|
-
sm: 540,
|
|
21
|
-
md: 720,
|
|
22
|
-
lg: 960,
|
|
23
|
-
xl: 1140,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
describe('defaultBreakpoints', () => {
|
|
31
|
-
it('has all standard breakpoints', async () => {
|
|
32
|
-
const { defaultBreakpoints } = await import('../theme')
|
|
33
|
-
expect(defaultBreakpoints).toEqual({
|
|
34
|
-
xs: 0,
|
|
35
|
-
sm: 576,
|
|
36
|
-
md: 768,
|
|
37
|
-
lg: 992,
|
|
38
|
-
xl: 1200,
|
|
39
|
-
})
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('breakpoints are in ascending order', async () => {
|
|
43
|
-
const { defaultBreakpoints } = await import('../theme')
|
|
44
|
-
const values = Object.values(defaultBreakpoints)
|
|
45
|
-
for (let i = 1; i < values.length; i++) {
|
|
46
|
-
expect(values[i]).toBeGreaterThan(values[i - 1] as number)
|
|
47
|
-
}
|
|
48
|
-
})
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
describe('defaultContainerWidths', () => {
|
|
52
|
-
it('has widths for all breakpoints', async () => {
|
|
53
|
-
const { defaultContainerWidths } = await import('../theme')
|
|
54
|
-
expect(defaultContainerWidths).toEqual({
|
|
55
|
-
xs: '100%',
|
|
56
|
-
sm: 540,
|
|
57
|
-
md: 720,
|
|
58
|
-
lg: 960,
|
|
59
|
-
xl: 1140,
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('xs is percentage, others are numbers', async () => {
|
|
64
|
-
const { defaultContainerWidths } = await import('../theme')
|
|
65
|
-
expect(typeof defaultContainerWidths.xs).toBe('string')
|
|
66
|
-
expect(typeof defaultContainerWidths.sm).toBe('number')
|
|
67
|
-
expect(typeof defaultContainerWidths.md).toBe('number')
|
|
68
|
-
expect(typeof defaultContainerWidths.lg).toBe('number')
|
|
69
|
-
expect(typeof defaultContainerWidths.xl).toBe('number')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('numeric widths are in ascending order', async () => {
|
|
73
|
-
const { defaultContainerWidths } = await import('../theme')
|
|
74
|
-
const numericWidths = [
|
|
75
|
-
defaultContainerWidths.sm,
|
|
76
|
-
defaultContainerWidths.md,
|
|
77
|
-
defaultContainerWidths.lg,
|
|
78
|
-
defaultContainerWidths.xl,
|
|
79
|
-
] as number[]
|
|
80
|
-
for (let i = 1; i < numericWidths.length; i++) {
|
|
81
|
-
expect(numericWidths[i]).toBeGreaterThan(numericWidths[i - 1] as number)
|
|
82
|
-
}
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
describe('ContainerContext', () => {
|
|
87
|
-
it('is created via createContext with an id', async () => {
|
|
88
|
-
const { ContainerContext } = await import('../context')
|
|
89
|
-
expect(ContainerContext).toHaveProperty('id')
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
describe('RowContext', () => {
|
|
94
|
-
it('is created via createContext with an id', async () => {
|
|
95
|
-
const { RowContext } = await import('../context')
|
|
96
|
-
expect(RowContext).toHaveProperty('id')
|
|
97
|
-
})
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
describe('constants', () => {
|
|
101
|
-
it('has correct PKG_NAME', async () => {
|
|
102
|
-
const { PKG_NAME } = await import('../constants')
|
|
103
|
-
expect(PKG_NAME).toBe('@pyreon/coolgrid')
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('has CONTEXT_KEYS', async () => {
|
|
107
|
-
const { CONTEXT_KEYS } = await import('../constants')
|
|
108
|
-
expect(CONTEXT_KEYS).toContain('columns')
|
|
109
|
-
expect(CONTEXT_KEYS).toContain('size')
|
|
110
|
-
expect(CONTEXT_KEYS).toContain('gap')
|
|
111
|
-
expect(CONTEXT_KEYS).toContain('padding')
|
|
112
|
-
expect(CONTEXT_KEYS).toContain('gutter')
|
|
113
|
-
expect(CONTEXT_KEYS).toContain('colCss')
|
|
114
|
-
expect(CONTEXT_KEYS).toContain('colComponent')
|
|
115
|
-
expect(CONTEXT_KEYS).toContain('rowCss')
|
|
116
|
-
expect(CONTEXT_KEYS).toContain('rowComponent')
|
|
117
|
-
expect(CONTEXT_KEYS).toContain('contentAlignX')
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
})
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type { VNode } from '@pyreon/core'
|
|
2
|
-
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
-
|
|
4
|
-
const mockProvide = vi.fn()
|
|
5
|
-
const mockUseContext = vi.fn()
|
|
6
|
-
|
|
7
|
-
vi.mock('@pyreon/core', async (importOriginal) => {
|
|
8
|
-
const original = await importOriginal<typeof import('@pyreon/core')>()
|
|
9
|
-
return {
|
|
10
|
-
...original,
|
|
11
|
-
provide: (...args: any[]) => {
|
|
12
|
-
mockProvide(...args)
|
|
13
|
-
},
|
|
14
|
-
useContext: (...args: any[]) => {
|
|
15
|
-
return mockUseContext(...args)
|
|
16
|
-
},
|
|
17
|
-
}
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const asVNode = (v: unknown) => v as VNode
|
|
21
|
-
|
|
22
|
-
describe('Context cascading: Container -> Row -> Col', () => {
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
vi.clearAllMocks()
|
|
25
|
-
// Default: unistyle theme context returns a ReactiveContext accessor
|
|
26
|
-
mockUseContext.mockReturnValue(() => ({ theme: {} }))
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('Container provides context with grid config', async () => {
|
|
30
|
-
const Container = (await import('../Container')).default
|
|
31
|
-
// Container calls useContext once (for unistyle theme)
|
|
32
|
-
Container({ columns: 12, gap: 16, gutter: 8, padding: 4, children: 'test' })
|
|
33
|
-
|
|
34
|
-
expect(mockProvide).toHaveBeenCalledTimes(1)
|
|
35
|
-
const config = mockProvide.mock.calls[0]?.[1] as Record<string, unknown>
|
|
36
|
-
|
|
37
|
-
expect(config.columns).toBe(12)
|
|
38
|
-
expect(config.gap).toBe(16)
|
|
39
|
-
expect(config.gutter).toBe(8)
|
|
40
|
-
expect(config.padding).toBe(4)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('Row reads Container context and provides its own', async () => {
|
|
44
|
-
const Row = (await import('../Row')).default
|
|
45
|
-
|
|
46
|
-
// Row calls useContext twice:
|
|
47
|
-
// 1st: ContainerContext (grid config from parent)
|
|
48
|
-
// 2nd: unistyle context (theme) inside useGridContext
|
|
49
|
-
mockUseContext
|
|
50
|
-
.mockReturnValueOnce({
|
|
51
|
-
columns: 12,
|
|
52
|
-
gap: 16,
|
|
53
|
-
gutter: 8,
|
|
54
|
-
padding: 4,
|
|
55
|
-
})
|
|
56
|
-
.mockReturnValueOnce(() => ({ theme: {} }))
|
|
57
|
-
|
|
58
|
-
Row({ children: 'test' })
|
|
59
|
-
|
|
60
|
-
const rowConfig = mockProvide.mock.calls[0]?.[1] as Record<string, unknown>
|
|
61
|
-
|
|
62
|
-
expect(rowConfig.columns).toBe(12)
|
|
63
|
-
expect(rowConfig.gap).toBe(16)
|
|
64
|
-
expect(rowConfig.gutter).toBe(8)
|
|
65
|
-
expect(rowConfig.padding).toBe(4)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it('Row can override Container values', async () => {
|
|
69
|
-
const Row = (await import('../Row')).default
|
|
70
|
-
|
|
71
|
-
// 1st call: ContainerContext, 2nd call: unistyle theme
|
|
72
|
-
mockUseContext.mockReturnValueOnce({ columns: 12, gap: 8 }).mockReturnValueOnce(() => ({ theme: {} }))
|
|
73
|
-
|
|
74
|
-
Row({ columns: 24, gap: 32, children: 'test' })
|
|
75
|
-
|
|
76
|
-
const rowConfig = mockProvide.mock.calls[0]?.[1] as Record<string, unknown>
|
|
77
|
-
|
|
78
|
-
expect(rowConfig.columns).toBe(24)
|
|
79
|
-
expect(rowConfig.gap).toBe(32)
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('Col reads Row context and passes $coolgrid', async () => {
|
|
83
|
-
const Col = (await import('../Col')).default
|
|
84
|
-
|
|
85
|
-
// Col calls useContext twice:
|
|
86
|
-
// 1st: RowContext, 2nd: unistyle theme inside useGridContext
|
|
87
|
-
mockUseContext.mockReturnValueOnce({ columns: 12, gap: 20 }).mockReturnValueOnce(() => ({ theme: {} }))
|
|
88
|
-
|
|
89
|
-
const result = asVNode(Col({ size: 4, children: 'test' }))
|
|
90
|
-
expect(result.props.$coolgrid).toBeDefined()
|
|
91
|
-
expect((result.props.$coolgrid as Record<string, unknown>).size).toBe(4)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it('Col does not provide context', async () => {
|
|
95
|
-
const Col = (await import('../Col')).default
|
|
96
|
-
|
|
97
|
-
Col({ size: 6, children: 'test' })
|
|
98
|
-
expect(mockProvide).not.toHaveBeenCalled()
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('Container calls provide', async () => {
|
|
102
|
-
const Container = (await import('../Container')).default
|
|
103
|
-
Container({ children: 'test' })
|
|
104
|
-
|
|
105
|
-
expect(mockProvide).toHaveBeenCalledTimes(1)
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
it('Row calls provide', async () => {
|
|
109
|
-
const Row = (await import('../Row')).default
|
|
110
|
-
Row({ children: 'test' })
|
|
111
|
-
|
|
112
|
-
expect(mockProvide).toHaveBeenCalledTimes(1)
|
|
113
|
-
})
|
|
114
|
-
})
|