Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

Commit

Permalink
Merge 23a369c into 4abf4eb
Browse files Browse the repository at this point in the history
  • Loading branch information
tinkertrain committed Mar 22, 2021
2 parents 4abf4eb + 23a369c commit 37f4236
Show file tree
Hide file tree
Showing 32 changed files with 5,873 additions and 2,745 deletions.
12 changes: 6 additions & 6 deletions .storybook/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
[
"@babel/preset-env",
{
"loose": true,
"loose": false,
"shippedProposals": true,
"targets": {
"ie": 11,
"edge": 14,
"firefox": 45,
"chrome": 49,
"safari": 10,
"ie": "11",
"edge": "16",
"firefox": "85",
"chrome": "86",
"safari": "12",
"node": "12.16.3"
}
}
Expand Down
9 changes: 5 additions & 4 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,18 @@ module.exports = api => {
targets: {
ie: '11',
edge: '16',
firefox: '60',
chrome: '65',
safari: '10',
firefox: '85',
chrome: '86',
safari: '12',
node: '12.16.3',
},
loose: true,
loose: false,
shippedProposals: true,
},
],
'@babel/react',
],
plugins: plugins,
exclude: ['node_modules'],
}
}
5,575 changes: 2,868 additions & 2,707 deletions package-lock.json

Large diffs are not rendered by default.

25 changes: 13 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@helpscout/hsds-react",
"version": "3.10.7",
"version": "3.11.0-0",
"private": false,
"main": "dist/index.js",
"module": "dist/index.es.js",
Expand Down Expand Up @@ -94,6 +94,7 @@
"array-move": "2.1.0",
"compute-scroll-into-view": "1.0.11",
"dash-get": "1.0.2",
"downshift": "^6.1.0",
"fast-deep-equal": "^2.0.1",
"invariant": "2.2.4",
"path-to-regexp": "2.4.0",
Expand All @@ -111,18 +112,18 @@
"@babel/plugin-transform-runtime": "^7.4.3",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@helpscout/colorway": "0.9.2",
"@helpscout/colorway": "0.9.5",
"@helpscout/helix": "^0.1.0",
"@helpscout/prestart": "^0.0.9",
"@storybook/addon-a11y": "6.1.15",
"@storybook/addon-actions": "6.1.15",
"@storybook/addon-docs": "6.1.15",
"@storybook/addon-knobs": "6.1.15",
"@storybook/addon-links": "6.1.15",
"@storybook/addons": "6.1.15",
"@storybook/cli": "6.1.15",
"@storybook/react": "6.1.15",
"@storybook/theming": "6.1.15",
"@storybook/addon-a11y": "6.1.20",
"@storybook/addon-actions": "6.1.20",
"@storybook/addon-docs": "6.1.20",
"@storybook/addon-knobs": "6.1.20",
"@storybook/addon-links": "6.1.20",
"@storybook/addons": "6.1.20",
"@storybook/cli": "6.1.20",
"@storybook/react": "6.1.20",
"@storybook/theming": "6.1.20",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.0.4",
"@testing-library/user-event": "^12.1.5",
Expand Down Expand Up @@ -181,7 +182,7 @@
"sinon": "^5.0.10",
"slugify": "^1.3.1",
"start-server-and-test": "^1.10.11",
"storybook-addon-designs": "^5.4.3",
"storybook-addon-designs": "^5.4.5",
"styled-components": "5.1.1",
"stylelint": "^13.6.1",
"stylelint-config-prettier": "^8.0.2",
Expand Down
2 changes: 1 addition & 1 deletion src/components/AttachmentList/AttachmentList.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Attachment } from '../index'
import AttachmentList from './'

<Meta
title="Components/Badges/Attachment"
title="Components/Badges/AttachmentList"
component={AttachmentList}
parameters={{
design: {
Expand Down
1 change: 1 addition & 0 deletions src/components/Depth/Depth.jsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* istanbul ignore file */
import React from 'react'
import PropTypes from 'prop-types'
import { classNames } from '../../utilities/classNames'
Expand Down
157 changes: 157 additions & 0 deletions src/components/DropList/DropList.Combobox.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import React, { useState, useRef, useEffect } from 'react'
import { useCombobox } from 'downshift'
import { noop } from '../../utilities/other'
import {
itemToString,
isItemSelected,
renderListContents,
setInitialSelection,
} from './DropList.utils'
import {
getA11ySelectionMessageCommon,
onIsOpenChangeCommon,
onStateChangeCommon,
stateReducerCommon,
} from './DropList.downshift.common'
import {
DropListWrapperUI,
InputSearchHolderUI,
MenuListUI,
} from './DropList.css'
import ListItem, { generateListItemKey } from './DropList.ListItem'
import { VARIANTS } from './DropList.constants'

function Combobox({
closeOnSelection = true,
customEmptyList = null,
'data-cy': dataCy = `DropList.${VARIANTS.COMBOBOX}`,
initialSelectedItem,
isOpen = false,
items = [],
onSelectionChange = noop,
renderCustomListItem = null,
toggleOpenedState = noop,
withMultipleSelection = false,
}) {
const initialSelectedItemsArr = setInitialSelection({
initialSelectedItem,
withMultipleSelection,
})
const [inputItems, setInputItems] = useState(items)
const [selectedItems, setSelectedItems] = useState(initialSelectedItemsArr)
const inputEl = useRef(null)

const {
getComboboxProps,
getInputProps,
getItemProps,
getMenuProps,
highlightedIndex,
inputValue,
selectItem,
selectedItem,
} = useCombobox({
initialInputValue: '',
initialIsOpen: isOpen,
initialSelectedItem,
isOpen,
items: inputItems,
itemToString,

getA11ySelectionMessage: ({ selectedItem }) => {
return getA11ySelectionMessageCommon({
selectedItem,
selectedItems,
withMultipleSelection,
})
},

onInputValueChange({ inputValue }) {
setInputItems(
items.filter(item =>
itemToString(item).toLowerCase().startsWith(inputValue.toLowerCase())
)
)
},

onIsOpenChange(changes) {
onIsOpenChangeCommon({
closeOnSelection,
toggleOpenedState,
type: `${VARIANTS.COMBOBOX}.${changes.type}`,
})
},

onStateChange(changes) {
onStateChangeCommon({
changes,
onSelectionChange,
selectItem,
selectedItems,
setSelectedItems,
type: `${VARIANTS.COMBOBOX}.${changes.type}`,
withMultipleSelection,
})
},

stateReducer(state, actionAndChanges) {
const { changes, type } = actionAndChanges

return stateReducerCommon({
changes,
closeOnSelection,
selectedItems,
state,
type: `${VARIANTS.COMBOBOX}.${type}`,
withMultipleSelection,
})
},
})

useEffect(() => {
isOpen && inputEl.current.focus()
}, [isOpen])

function renderListItem(item, index) {
const itemProps = {
highlightedIndex,
index,
isSelected: isItemSelected({
item,
selectedItem,
selectedItems,
}),
item,
key: generateListItemKey(item, index),
withMultipleSelection,
renderCustomListItem,
...getItemProps({ item, index }),
}

return <ListItem {...itemProps} />
}

return (
<DropListWrapperUI
className="DropList DropList__Combobox"
data-cy={dataCy}
variant="combobox"
{...getComboboxProps()}
>
<InputSearchHolderUI show={items.length > 0}>
<input {...getInputProps({ ref: inputEl })} placeholder="Search" />
</InputSearchHolderUI>
<MenuListUI className="MenuList MenuList-Combobox" {...getMenuProps()}>
{renderListContents({
customEmptyList,
emptyList: items.length === 0,
inputValue,
items: inputItems,
renderListItem,
})}
</MenuListUI>
</DropListWrapperUI>
)
}

export default Combobox
93 changes: 93 additions & 0 deletions src/components/DropList/DropList.ListItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, { forwardRef } from 'react'
import { classNames } from '../../utilities/classNames'
import { isFunction, isObject, isString } from '../../utilities/is'
import { isItemADivider, isItemAGroupLabel } from './DropList.utils'
import {
DividerUI,
GroupLabelUI,
ListItemUI,
SelectedBadge,
} from './DropList.css'

const ListItem = forwardRef(
(
{
item,
index,
highlightedIndex,
withMultipleSelection,
isSelected,
renderCustomListItem,
...itemProps
},
ref
) => {
if (isItemADivider(item)) {
return (
<DividerUI className="DropListItem--divider" key={`divider_${index}`} />
)
}

if (isItemAGroupLabel(item)) {
return (
<GroupLabelUI
className="DropListItem--groupLabel"
key={`group_label_${index}`}
>
{item.label}
</GroupLabelUI>
)
}

function getListItemClassNames(extraClassNames) {
return classNames(
'DropListItem',
isSelected && 'is-selected',
highlightedIndex === index && 'is-highlighted',
withMultipleSelection && 'with-multiple-selection',
isString(extraClassNames) && extraClassNames
)
}

if (renderCustomListItem != null && isFunction(renderCustomListItem)) {
return (
<li
className={getListItemClassNames('DropListItem--custom')}
ref={ref}
{...itemProps}
>
{renderCustomListItem({
item,
isSelected,
isHighlighted: highlightedIndex === index,
withMultipleSelection,
})}
</li>
)
}

return (
<ListItemUI
className={getListItemClassNames()}
highlighted={highlightedIndex === index}
ref={ref}
selected={isSelected}
withMultipleSelection={withMultipleSelection}
{...itemProps}
>
<span>{isObject(item) ? item.label : item}</span>
{withMultipleSelection ? (
<SelectedBadge isSelected={isSelected} />
) : null}
</ListItemUI>
)
}
)

export function generateListItemKey(item, index) {
return isObject(item)
? item.id || `${item.label}_${index}`
: `${item}_${index}`
}

export default ListItem

0 comments on commit 37f4236

Please sign in to comment.