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

Commit 1e169f1

Browse files
committed
fix(menu): allow menu option group to use array prop
1 parent c4307d6 commit 1e169f1

File tree

2 files changed

+187
-107
lines changed

2 files changed

+187
-107
lines changed

packages/chakra-ui-core/src/CMenu/CMenu.stories.js

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
import { storiesOf } from '@storybook/vue'
2-
import { CMenu, CFade, CMenuGroup, CMenuButton, CMenuList, CMenuOptionGroup, CImage, CMenuItemOption, CMenuItem, CMenuDivider, CIcon } from '..'
2+
import {
3+
CMenu,
4+
CFade,
5+
CMenuGroup,
6+
CMenuButton,
7+
CMenuList,
8+
CMenuOptionGroup,
9+
CImage,
10+
CMenuItemOption,
11+
CMenuItem,
12+
CMenuDivider,
13+
CIcon
14+
} from '..'
315

416
storiesOf('UI | Menu', module)
517
.add('With internal state', () => ({
6-
components: { CFade, CMenu, CMenuGroup, CMenuButton, CMenuList, CMenuItem, CMenuDivider },
18+
components: {
19+
CFade,
20+
CMenu,
21+
CMenuGroup,
22+
CMenuButton,
23+
CMenuList,
24+
CMenuItem,
25+
CMenuDivider
26+
},
727
template: `
828
<CMenu v-slot="{ isOpen }" :close-on-blur="false">
929
<CMenuButton right-icon="chevron-down" variantColor="pink">
@@ -26,7 +46,15 @@ storiesOf('UI | Menu', module)
2646
`
2747
}))
2848
.add('With letter navigation', () => ({
29-
components: { CMenu, CMenuGroup, CMenuButton, CMenuList, CMenuItem, CMenuDivider, CIcon },
49+
components: {
50+
CMenu,
51+
CMenuGroup,
52+
CMenuButton,
53+
CMenuList,
54+
CMenuItem,
55+
CMenuDivider,
56+
CIcon
57+
},
3058
template: `
3159
<CMenu>
3260
<CMenuButton
@@ -51,7 +79,16 @@ storiesOf('UI | Menu', module)
5179
`
5280
}))
5381
.add('With Menu Options', () => ({
54-
components: { CMenu, CMenuGroup, CMenuButton, CMenuList, CMenuOptionGroup, CMenuItemOption, CMenuItem, CMenuDivider },
82+
components: {
83+
CMenu,
84+
CMenuGroup,
85+
CMenuButton,
86+
CMenuList,
87+
CMenuOptionGroup,
88+
CMenuItemOption,
89+
CMenuItem,
90+
CMenuDivider
91+
},
5592
template: `
5693
<CMenu :closeOnSelect="false">
5794
<CMenuButton variantColor="blue">
@@ -73,7 +110,17 @@ storiesOf('UI | Menu', module)
73110
`
74111
}))
75112
.add('Letter navigation', () => ({
76-
components: { CMenu, CMenuGroup, CMenuButton, CImage, CMenuList, CMenuOptionGroup, CMenuItemOption, CMenuItem, CMenuDivider },
113+
components: {
114+
CMenu,
115+
CMenuGroup,
116+
CMenuButton,
117+
CImage,
118+
CMenuList,
119+
CMenuOptionGroup,
120+
CMenuItemOption,
121+
CMenuItem,
122+
CMenuDivider
123+
},
77124
template: `
78125
<c-menu>
79126
<c-menu-button as="button" right-icon="chevron-down">
@@ -105,7 +152,15 @@ storiesOf('UI | Menu', module)
105152
`
106153
}))
107154
.add('No close on blur', () => ({
108-
components: { CMenu, CMenuGroup, CMenuButton, CMenuList, CMenuItem, CMenuDivider, CIcon },
155+
components: {
156+
CMenu,
157+
CMenuGroup,
158+
CMenuButton,
159+
CMenuList,
160+
CMenuItem,
161+
CMenuDivider,
162+
CIcon
163+
},
109164
template: `
110165
<CMenu :closeOnBlur="false">
111166
<CMenuButton as="Button" rightIcon="chevron-down">

packages/chakra-ui-core/src/CMenu/CMenuOption.js

Lines changed: 126 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const CMenuItemOption = {
2222
type: String,
2323
isDisabled: Boolean,
2424
isChecked: Boolean,
25-
value: [String, Number]
25+
value: [String, Number, Array]
2626
},
2727
computed: {
2828
context () {
@@ -102,55 +102,63 @@ const CMenuItemOption = {
102102
}
103103
},
104104
render (h) {
105-
return h(CPseudoBox, {
106-
props: {
107-
as: 'button'
108-
},
109-
attrs: {
110-
...this.menuItemStyles,
111-
display: 'flex',
112-
minHeight: '32px',
113-
alignItems: 'center',
114-
...this.$attrs,
115-
role: this.role,
116-
tabindex: -1,
117-
'aria-checked': this.isChecked,
118-
disabled: this.isDisabled,
119-
'aria-disabled': this.isDisabled,
120-
'data-chakra-component': 'CMenuItemOption'
121-
},
122-
nativeOn: {
123-
click: this.handleClick,
124-
mouseenter: this.handleMouseEnter,
125-
mouseleave: this.handleMouseLeave,
126-
keydown: this.handleKeyDown
127-
}
128-
}, [
129-
h(CIcon, {
105+
return h(
106+
CPseudoBox,
107+
{
130108
props: {
131-
name: 'check'
109+
as: 'button'
132110
},
133111
attrs: {
134-
opacity: this.isChecked ? 1 : 0,
135-
color: 'currentColor',
136-
size: '1em',
137-
ml: '1rem',
138-
mr: '-4px',
139-
'aria-hidden': true,
140-
'data-menuitem-icon': ''
141-
}
142-
}),
143-
h(CBox, {
144-
props: {
145-
as: 'span'
112+
...this.menuItemStyles,
113+
display: 'flex',
114+
minHeight: '32px',
115+
alignItems: 'center',
116+
...this.$attrs,
117+
role: this.role,
118+
tabindex: -1,
119+
'aria-checked': this.isChecked,
120+
disabled: this.isDisabled,
121+
'aria-disabled': this.isDisabled,
122+
'data-chakra-component': 'CMenuItemOption'
146123
},
147-
attrs: {
148-
textAlign: 'left',
149-
flex: '1',
150-
mx: '1rem'
124+
nativeOn: {
125+
click: this.handleClick,
126+
mouseenter: this.handleMouseEnter,
127+
mouseleave: this.handleMouseLeave,
128+
keydown: this.handleKeyDown
151129
}
152-
}, this.$slots.default)
153-
])
130+
},
131+
[
132+
h(CIcon, {
133+
props: {
134+
name: 'check'
135+
},
136+
attrs: {
137+
opacity: this.isChecked ? 1 : 0,
138+
color: 'currentColor',
139+
size: '1em',
140+
ml: '1rem',
141+
mr: '-4px',
142+
'aria-hidden': true,
143+
'data-menuitem-icon': ''
144+
}
145+
}),
146+
h(
147+
CBox,
148+
{
149+
props: {
150+
as: 'span'
151+
},
152+
attrs: {
153+
textAlign: 'left',
154+
flex: '1',
155+
mx: '1rem'
156+
}
157+
},
158+
this.$slots.default
159+
)
160+
]
161+
)
154162
}
155163
}
156164

@@ -173,7 +181,7 @@ const CMenuOptionGroup = {
173181
name: String,
174182
title: String,
175183
value: {
176-
type: [String, Number],
184+
type: [String, Number, Array],
177185
default: null
178186
},
179187
defaultValue: [String, Number, Array]
@@ -229,87 +237,104 @@ const CMenuOptionGroup = {
229237
if (!this.$slots || !this.$slots.default) {
230238
return h(null)
231239
} else if (!this.$slots.default.length) {
232-
return console.error('[Chakra-ui]: <CMenuOptionGroup /> component expects at least one child node.')
240+
return console.error(
241+
'[Chakra-ui]: <CMenuOptionGroup /> component expects at least one child node.'
242+
)
233243
}
234244

235245
const children = this.$slots.default.filter(e => e.tag)
236246

237247
const clonedChildNodes = children.map((vnode) => {
238248
let result
239249
const cloned = cloneVNode(vnode, h)
240-
if (!cloned.componentOptions) return console.error('Chakra-ui: <CMenuOptionGroup /> component expects valid component as children')
250+
if (!cloned.componentOptions)
251+
return console.error(
252+
'Chakra-ui: <CMenuOptionGroup /> component expects valid component as children'
253+
)
241254

242255
if (this.type === 'radio') {
243-
result = h(cloned.componentOptions.Ctor, {
244-
...cloned.data,
245-
props: {
246-
...(cloned.data.props || {}),
247-
...cloned.componentOptions.propsData,
248-
type: this.type,
249-
name: this.name || this.fallbackName,
250-
isChecked: cloned.componentOptions.propsData.value === this.computedValue
251-
},
252-
attrs: {
253-
...(cloned.data.attrs || {})
254-
},
255-
key: cloned.componentOptions.propsData.value,
256-
nativeOn: {
257-
click: (event) => {
258-
this.handleChange(cloned.componentOptions.propsData.value)
256+
result = h(
257+
cloned.componentOptions.Ctor,
258+
{
259+
...cloned.data,
260+
props: {
261+
...(cloned.data.props || {}),
262+
...cloned.componentOptions.propsData,
263+
type: this.type,
264+
name: this.name || this.fallbackName,
265+
isChecked:
266+
cloned.componentOptions.propsData.value === this.computedValue
267+
},
268+
attrs: {
269+
...(cloned.data.attrs || {})
259270
},
260-
keydown: (event) => {
261-
if (['Enter', ' '].includes(event.key)) {
262-
event.preventDefault()
271+
key: cloned.componentOptions.propsData.value,
272+
nativeOn: {
273+
click: (event) => {
263274
this.handleChange(cloned.componentOptions.propsData.value)
275+
},
276+
keydown: (event) => {
277+
if (['Enter', ' '].includes(event.key)) {
278+
event.preventDefault()
279+
this.handleChange(cloned.componentOptions.propsData.value)
280+
}
264281
}
265282
}
266-
}
267-
}, cloned.componentOptions.children)
283+
},
284+
cloned.componentOptions.children
285+
)
268286
}
269287

270288
if (this.type === 'checkbox') {
271-
result = h(cloned.componentOptions.Ctor, {
272-
...cloned.data,
273-
props: {
274-
...(cloned.data.props || {}),
275-
...cloned.componentOptions.propsData,
276-
type: this.type,
277-
isChecked: this.computedValue.includes(cloned.componentOptions.propsData.value)
278-
},
279-
attrs: {
280-
...(cloned.data.attrs || {})
281-
},
282-
key: cloned.componentOptions.propsData.value,
283-
nativeOn: {
284-
click: (event) => {
285-
this.handleChange(cloned.componentOptions.propsData.value)
289+
result = h(
290+
cloned.componentOptions.Ctor,
291+
{
292+
...cloned.data,
293+
props: {
294+
...(cloned.data.props || {}),
295+
...cloned.componentOptions.propsData,
296+
type: this.type,
297+
isChecked: this.computedValue.includes(
298+
cloned.componentOptions.propsData.value
299+
)
300+
},
301+
attrs: {
302+
...(cloned.data.attrs || {})
286303
},
287-
keydown: (event) => {
288-
if (['Enter', ' '].includes(event.key)) {
289-
event.preventDefault()
304+
key: cloned.componentOptions.propsData.value,
305+
nativeOn: {
306+
click: (event) => {
290307
this.handleChange(cloned.componentOptions.propsData.value)
308+
},
309+
keydown: (event) => {
310+
if (['Enter', ' '].includes(event.key)) {
311+
event.preventDefault()
312+
this.handleChange(cloned.componentOptions.propsData.value)
313+
}
291314
}
292315
}
293-
}
294-
}, cloned.componentOptions.children)
316+
},
317+
cloned.componentOptions.children
318+
)
295319
}
296320

297321
return result
298322
})
299323

300-
return h(CMenuGroup, {
301-
props: {
302-
title: this.title
324+
return h(
325+
CMenuGroup,
326+
{
327+
props: {
328+
title: this.title
329+
},
330+
attrs: {
331+
...this.$attrs,
332+
'data-chakra-component': 'CMenuOptionGroup'
333+
}
303334
},
304-
attrs: {
305-
...this.$attrs,
306-
'data-chakra-component': 'CMenuOptionGroup'
307-
}
308-
}, clonedChildNodes)
335+
clonedChildNodes
336+
)
309337
}
310338
}
311339

312-
export {
313-
CMenuItemOption,
314-
CMenuOptionGroup
315-
}
340+
export { CMenuItemOption, CMenuOptionGroup }

0 commit comments

Comments
 (0)