Semantic-UI-React
Semantic-UI-React copied to clipboard
RFC: Dropdown header and divider shorthands
https://react.semantic-ui.com/modules/dropdown#dropdown-example-header
I wanna use Dropdown.Header
and Dropdown.Divider
in search
or multiple
dropdown, but it's currently not supported. So I suppose we should extend shorthand props to support it. But it can be done in many ways so it's better to consider different options.
Header
I think the header shorthand is pretty straitforward
import React from 'react'
import { Dropdown } from 'semantic-ui-react'
const options = [
{ content: 'Important', header: { icon: 'tags', content: 'Filter by tag' } },
{ content: 'Announcement' },
{ content: 'Discussion' }
]
// <Dropdown.Header icon='tags' content='Filter by tag' />
// <Dropdown.Item>Important</Dropdown.Item>
// <Dropdown.Item>Announcement</Dropdown.Item>
// <Dropdown.Item>Discussion</Dropdown.Item>
const DropdownExampleHeader = () => (
<Dropdown text='Filter' icon='filter' floating labeled button className='icon' options={options} />
)
export default DropdownExampleHeader
Divider
I think it should be implemented by using divider
shorthand with position as shorthand value. Possible positions will be 'top' | 'bottom' | 'both'
.
import React from 'react'
import { Dropdown } from 'semantic-ui-react'
const options = [
{ content: 'Important' },
{ content: 'Announcement', divider: 'top' },
{ content: 'Discussion' }
]
// <Dropdown.Item>Important</Dropdown.Item>
// <Dropdown.Divider />
// <Dropdown.Item>Announcement</Dropdown.Item>
// <Dropdown.Item>Discussion</Dropdown.Item>
const DropdownExampleDivider = () => (
<Dropdown text='Filter' icon='filter' floating labeled button className='icon' options={options} />
)
export default DropdownExampleDivider
Implementation from the top of my head
Before Dropdown.js#L1165
return _.map(options, (opt, i) => DropdownItem.create({
active: isActive(opt.value),
onClick: this.handleItemClick,
selected: selectedIndex === i,
...opt,
// Needed for handling click events on disabled items
style: { ...opt.style, pointerEvents: 'all' },
}))
After
return _.reduce(options, (accumulator, opt, i) => {
if (opt.header) {
accumulator.push(DropdownHeader.create({ ...opt.header }))
}
if (opt.divider === 'top' || opt.divider === 'both') {
accumulator.push(<DropdownDivider />)
}
accumulator.push(DropdownItem.create({
active: isActive(opt.value),
onClick: this.handleItemClick,
selected: selectedIndex === i,
...opt,
// Needed for handling click events on disabled items
style: { ...opt.style, pointerEvents: 'all' },
}))
if (opt.divider === 'bottom' || opt.divider === 'both') {
accumulator.push(<DropdownDivider />)
}
return accumulator
}
Thank you for starting this RFC. In addition to the linked #889, it is also closely related to #1365 (submenu's and nested dropdown menu's).
I'd propose that we standardize on the component
key to define which component the props are for. This would apply to any shorthand. Updating the example Dropdowns you provided above:
Header
const options = [
{ component: Dropdown.Header, icon: 'tags', content: 'Filter by tag' },
{ content: 'Important' },
{ content: 'Announcement' },
{ content: 'Discussion' }
]
// <Dropdown.Header icon='tags' content='Filter by tag' />
// <Dropdown.Item>Important</Dropdown.Item>
// <Dropdown.Item>Announcement</Dropdown.Item>
// <Dropdown.Item>Discussion</Dropdown.Item>
Divider
const options = [
{ content: 'Important' },
{ component: Dropdown.Divider },
{ content: 'Announcement' },
{ content: 'Discussion' }
]
// <Dropdown.Item>Important</Dropdown.Item>
// <Dropdown.Divider />
// <Dropdown.Item>Announcement</Dropdown.Item>
// <Dropdown.Item>Discussion</Dropdown.Item>
In this case why don't do something like
const options = [
{ component: <Dropdown.Header icon='tags' content='Filter by tag' /> },
{ content: 'Important' },
{ content: 'Announcement' },
{ content: 'Discussion' }
]
?
Here's another thing. Let's say we implemented this and updated the examples, like, the first one
const options = [
{ text: 'New' },
{ text: 'Open...', description: 'ctrl + o' },
{ text: 'Save as...', description: 'ctrl + s' },
{ text: 'Rename', description: 'ctrl + r' },
{ text: 'Make a copy' },
{ icon: 'folder', text: 'Move to folder' },
{ icon: 'trash', text: 'Move to trash' },
{ component: <Dropdown.Divider /> },
{ text: 'Download As...' },
{ text: 'Publish To Web' },
{ text: 'E-mail Collaborators' },
]
const DropdownExampleDropdown = () => (
<Dropdown text='File' options={options} />
)
The problem is now the state is fully managed so when clicking on some option we get all of our options bolded. It's because they has no value, so it's empty value now selected and all options are highlighted. But there shouldn't be any state management in a such use case, because it's not the value we wan't but immediate action on option selection.
So it raises two questions
- Should we update all examples to shortand or just leave such use cases be.
- Maybe we should get rid off subcomponents API completely?
Thanks for the PR, let's move discussions over there!
need this feature
Need this too, is the patch going to be merged?
+1
Please avoid +1 and status comments as they send all subscribers emails and notifications. All work is public and status can be tracked by looking at the open referenced PR, #1757. Additionally, emoji reactions on the original description are more useful as they do not send notifications and they enable issue sorting.
There has been no activity in this thread for 90 days. While we care about every issue and we’d love to see this fixed, the core team’s time is limited so we have to focus our attention on the issues that are most pressing. Therefore, we will likely not be able to get to this one.
However, PRs for this issue will of course be accepted and welcome!
If there is no more activity in the next 90 days, this issue will be closed automatically for housekeeping. To prevent this, simply leave a reply here. Thanks!
Finally, we have a decision there, we will go with the kind
prop, https://github.com/stardust-ui/react/issues/512
There has been no activity in this thread for 180 days. While we care about every issue and we’d love to see this fixed, the core team’s time is limited so we have to focus our attention on the issues that are most pressing. Therefore, we will likely not be able to get to this one.
However, PRs for this issue will of course be accepted and welcome!
If there is no more activity in the next 180 days, this issue will be closed automatically for housekeeping. To prevent this, simply leave a reply here. Thanks!
There has been no activity in this thread for 180 days. While we care about every issue and we’d love to see this fixed, the core team’s time is limited so we have to focus our attention on the issues that are most pressing. Therefore, we will likely not be able to get to this one.
However, PRs for this issue will of course be accepted and welcome!
If there is no more activity in the next 180 days, this issue will be closed automatically for housekeeping. To prevent this, simply leave a reply here. Thanks!
Hello @layershifter, since your feature #4029 is merged, is it possible to use shorthands for Dropdown options to create Header and Divider instead of item ? If yes, how ? I'm not sure to understand the feature correctly
I am in a case where I need a <Dropdown options={options} search multiple selection />
and separate the options in two sublist.
Here is a codesanbox to understand it better: https://codesandbox.io/s/friendly-noether-3rgf9?file=/src/index.js
If we don't use shorthands we have to recode the search, the selection and manage multiple values manually which is a bit annoying
What seems to do the trick after #4029 is to define headers and dividers as follows within the dropdown options:
const options = [
{
key: "header1",
children: () => <Dropdown.Header content="Header" />,
disabled: true
},
{
key: "divider1",
children: () => <Dropdown.Divider />,
disabled: true
},
{
key: "key1",
value: "value1",
text: "value1"
},
...
];