mirror of
https://github.com/fergalmoran/turnstone.git
synced 2025-12-22 09:49:56 +00:00
Add a GroupName custom component
This commit is contained in:
@@ -3,7 +3,8 @@ import Turnstone from '../../src/lib'
|
|||||||
import styles from './styles/App.module.css'
|
import styles from './styles/App.module.css'
|
||||||
import autocompleteStyles from './styles/autocomplete.module.css'
|
import autocompleteStyles from './styles/autocomplete.module.css'
|
||||||
import defaultListbox from '../_shared/defaultListbox'
|
import defaultListbox from '../_shared/defaultListbox'
|
||||||
import Item from './components/item/item'
|
import ItemContents from './components/itemContents/itemContents'
|
||||||
|
import GroupName from './components/groupName/groupName'
|
||||||
|
|
||||||
const maxItems = 10
|
const maxItems = 10
|
||||||
const placeholder = 'Enter a city or airport'
|
const placeholder = 'Enter a city or airport'
|
||||||
@@ -59,7 +60,6 @@ const App = () => {
|
|||||||
defaultListbox={defaultListbox}
|
defaultListbox={defaultListbox}
|
||||||
defaultListboxIsImmutable={false}
|
defaultListboxIsImmutable={false}
|
||||||
id='autocomplete'
|
id='autocomplete'
|
||||||
itemComponent={Item}
|
|
||||||
listbox={listbox}
|
listbox={listbox}
|
||||||
listboxIsImmutable={true}
|
listboxIsImmutable={true}
|
||||||
maxItems={maxItems}
|
maxItems={maxItems}
|
||||||
@@ -70,6 +70,8 @@ const App = () => {
|
|||||||
onTab={onTab}
|
onTab={onTab}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
styles={autocompleteStyles}
|
styles={autocompleteStyles}
|
||||||
|
GroupName={GroupName}
|
||||||
|
ItemContents={ItemContents}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
27
examples/geo/components/groupName/groupName.jsx
Normal file
27
examples/geo/components/groupName/groupName.jsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import styles from './groupName.module.css'
|
||||||
|
|
||||||
|
export default function GroupName(props) {
|
||||||
|
const {
|
||||||
|
children: name
|
||||||
|
} = props
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
cities: '\u{1F3D9}',
|
||||||
|
airports: '\u{2708}'
|
||||||
|
}
|
||||||
|
|
||||||
|
const icon = icons[name.toLowerCase()] || ''
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{icon && (
|
||||||
|
<span className={styles.icon}>
|
||||||
|
{icon}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{name}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
4
examples/geo/components/groupName/groupName.module.css
Normal file
4
examples/geo/components/groupName/groupName.module.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.icon {
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: 6px;
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import SplitMatch from '../splitMatch/splitMatch'
|
import SplitMatch from '../splitMatch/splitMatch'
|
||||||
import imgNewYork from'../../images/newyork.jpg'
|
import imgNewYork from'../../images/newyork.jpg'
|
||||||
import styles from './item.module.css'
|
import styles from './itemContents.module.css'
|
||||||
|
|
||||||
const SplitComponent = (props) => {
|
const SplitComponent = (props) => {
|
||||||
const {
|
const {
|
||||||
@@ -20,7 +20,7 @@ const MatchComponent = (props) => {
|
|||||||
return <span className={styles.match}>{children}</span>
|
return <span className={styles.match}>{children}</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Item(props) {
|
export default function ItemContents(props) {
|
||||||
const {
|
const {
|
||||||
appearsInDefaultListbox,
|
appearsInDefaultListbox,
|
||||||
index,
|
index,
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.groupName {
|
.groupHeading {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
color: #777;
|
color: #777;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
exports[`ItemFirst > Component renders correctly 1`] = `
|
exports[`ItemFirst > Component renders correctly 1`] = `
|
||||||
[
|
[
|
||||||
<div
|
<div
|
||||||
className="group-name-class"
|
className="group-heading-class"
|
||||||
>
|
>
|
||||||
Cities
|
Cities
|
||||||
</div>,
|
</div>,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default function Item(props) {
|
|||||||
} = useContext(StateContext)
|
} = useContext(StateContext)
|
||||||
|
|
||||||
const { customStyles, highlighted, query } = state
|
const { customStyles, highlighted, query } = state
|
||||||
const CustomItem = state.props.itemComponent
|
const ItemContents = state.props.ItemContents
|
||||||
const globalMatch = item.dataSearchType === 'contains'
|
const globalMatch = item.dataSearchType === 'contains'
|
||||||
const isHighlighted = highlighted && index === highlighted.index
|
const isHighlighted = highlighted && index === highlighted.index
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ export default function Item(props) {
|
|||||||
dispatch(setSelected(index))
|
dispatch(setSelected(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemContents = (CustomItem)
|
const itemContents = (ItemContents)
|
||||||
? <CustomItem
|
? <ItemContents
|
||||||
appearsInDefaultListbox={item.defaultListbox}
|
appearsInDefaultListbox={item.defaultListbox}
|
||||||
groupName={item.groupName}
|
groupName={item.groupName}
|
||||||
index={index}
|
index={index}
|
||||||
|
|||||||
@@ -6,10 +6,17 @@ export default function ItemFirst(props) {
|
|||||||
const { groupName, index, item } = props
|
const { groupName, index, item } = props
|
||||||
const { state } = useContext(StateContext)
|
const { state } = useContext(StateContext)
|
||||||
const { customStyles } = state
|
const { customStyles } = state
|
||||||
|
const GroupName = state.props.GroupName
|
||||||
|
|
||||||
|
const groupHeading = !!groupName && (
|
||||||
|
GroupName
|
||||||
|
? <GroupName index={item.groupIndex}>{groupName}</GroupName>
|
||||||
|
: groupName
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{!!groupName && <div className={customStyles.groupName}>{groupName}</div>}
|
{!!groupHeading && <div className={customStyles.groupHeading}>{groupHeading}</div>}
|
||||||
<Item index={index} key={`item${index}`} item={item} />
|
<Item index={index} key={`item${index}`} item={item} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ vi.mock('./item', () => ({ default: () => 'Item' }))
|
|||||||
describe('ItemFirst', () => {
|
describe('ItemFirst', () => {
|
||||||
test('Component renders correctly', () => {
|
test('Component renders correctly', () => {
|
||||||
const customStyles = {
|
const customStyles = {
|
||||||
groupName: 'group-name-class'
|
groupHeading: 'group-heading-class'
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = renderer.create(
|
const component = renderer.create(
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ Turnstone.propTypes = {
|
|||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
itemComponent: PropTypes.elementType,
|
|
||||||
listbox: listboxRules.isRequired,
|
listbox: listboxRules.isRequired,
|
||||||
listboxIsImmutable: PropTypes.bool,
|
listboxIsImmutable: PropTypes.bool,
|
||||||
matchText: PropTypes.bool,
|
matchText: PropTypes.bool,
|
||||||
@@ -98,7 +97,9 @@ Turnstone.propTypes = {
|
|||||||
maxItems: PropTypes.number,
|
maxItems: PropTypes.number,
|
||||||
styles: PropTypes.object,
|
styles: PropTypes.object,
|
||||||
tabIndex: PropTypes.number,
|
tabIndex: PropTypes.number,
|
||||||
text: PropTypes.string
|
text: PropTypes.string,
|
||||||
|
ItemContents: PropTypes.elementType,
|
||||||
|
GroupName: PropTypes.elementType
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
Reference in New Issue
Block a user