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 autocompleteStyles from './styles/autocomplete.module.css'
|
||||
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 placeholder = 'Enter a city or airport'
|
||||
@@ -59,7 +60,6 @@ const App = () => {
|
||||
defaultListbox={defaultListbox}
|
||||
defaultListboxIsImmutable={false}
|
||||
id='autocomplete'
|
||||
itemComponent={Item}
|
||||
listbox={listbox}
|
||||
listboxIsImmutable={true}
|
||||
maxItems={maxItems}
|
||||
@@ -70,6 +70,8 @@ const App = () => {
|
||||
onTab={onTab}
|
||||
placeholder={placeholder}
|
||||
styles={autocompleteStyles}
|
||||
GroupName={GroupName}
|
||||
ItemContents={ItemContents}
|
||||
/>
|
||||
</div>
|
||||
</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 SplitMatch from '../splitMatch/splitMatch'
|
||||
import imgNewYork from'../../images/newyork.jpg'
|
||||
import styles from './item.module.css'
|
||||
import styles from './itemContents.module.css'
|
||||
|
||||
const SplitComponent = (props) => {
|
||||
const {
|
||||
@@ -20,7 +20,7 @@ const MatchComponent = (props) => {
|
||||
return <span className={styles.match}>{children}</span>
|
||||
}
|
||||
|
||||
export default function Item(props) {
|
||||
export default function ItemContents(props) {
|
||||
const {
|
||||
appearsInDefaultListbox,
|
||||
index,
|
||||
@@ -47,7 +47,7 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.groupName {
|
||||
.groupHeading {
|
||||
text-transform: uppercase;
|
||||
font-size: 0.8em;
|
||||
color: #777;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
exports[`ItemFirst > Component renders correctly 1`] = `
|
||||
[
|
||||
<div
|
||||
className="group-name-class"
|
||||
className="group-heading-class"
|
||||
>
|
||||
Cities
|
||||
</div>,
|
||||
|
||||
@@ -13,7 +13,7 @@ export default function Item(props) {
|
||||
} = useContext(StateContext)
|
||||
|
||||
const { customStyles, highlighted, query } = state
|
||||
const CustomItem = state.props.itemComponent
|
||||
const ItemContents = state.props.ItemContents
|
||||
const globalMatch = item.dataSearchType === 'contains'
|
||||
const isHighlighted = highlighted && index === highlighted.index
|
||||
|
||||
@@ -37,8 +37,8 @@ export default function Item(props) {
|
||||
dispatch(setSelected(index))
|
||||
}
|
||||
|
||||
const itemContents = (CustomItem)
|
||||
? <CustomItem
|
||||
const itemContents = (ItemContents)
|
||||
? <ItemContents
|
||||
appearsInDefaultListbox={item.defaultListbox}
|
||||
groupName={item.groupName}
|
||||
index={index}
|
||||
|
||||
@@ -6,10 +6,17 @@ export default function ItemFirst(props) {
|
||||
const { groupName, index, item } = props
|
||||
const { state } = useContext(StateContext)
|
||||
const { customStyles } = state
|
||||
const GroupName = state.props.GroupName
|
||||
|
||||
const groupHeading = !!groupName && (
|
||||
GroupName
|
||||
? <GroupName index={item.groupIndex}>{groupName}</GroupName>
|
||||
: groupName
|
||||
)
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{!!groupName && <div className={customStyles.groupName}>{groupName}</div>}
|
||||
{!!groupHeading && <div className={customStyles.groupHeading}>{groupHeading}</div>}
|
||||
<Item index={index} key={`item${index}`} item={item} />
|
||||
</React.Fragment>
|
||||
)
|
||||
|
||||
@@ -10,7 +10,7 @@ vi.mock('./item', () => ({ default: () => 'Item' }))
|
||||
describe('ItemFirst', () => {
|
||||
test('Component renders correctly', () => {
|
||||
const customStyles = {
|
||||
groupName: 'group-name-class'
|
||||
groupHeading: 'group-heading-class'
|
||||
}
|
||||
|
||||
const component = renderer.create(
|
||||
|
||||
@@ -73,7 +73,6 @@ Turnstone.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
displayField: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
id: PropTypes.string,
|
||||
itemComponent: PropTypes.elementType,
|
||||
listbox: listboxRules.isRequired,
|
||||
listboxIsImmutable: PropTypes.bool,
|
||||
matchText: PropTypes.bool,
|
||||
@@ -98,7 +97,9 @@ Turnstone.propTypes = {
|
||||
maxItems: PropTypes.number,
|
||||
styles: PropTypes.object,
|
||||
tabIndex: PropTypes.number,
|
||||
text: PropTypes.string
|
||||
text: PropTypes.string,
|
||||
ItemContents: PropTypes.elementType,
|
||||
GroupName: PropTypes.elementType
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
Reference in New Issue
Block a user