mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 22:23:42 +01:00
Merge pull request #24965 from overleaf/td-downshift-9-upgrade
Upgrade Downshift to version 9 GitOrigin-RevId: b36904ab0c82c09a633a25cd6fed651d7c8b19f7
This commit is contained in:
Generated
+32
-15
@@ -3290,9 +3290,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.23.2",
|
"version": "7.27.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
|
||||||
"integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
|
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.14.0"
|
"regenerator-runtime": "^0.14.0"
|
||||||
},
|
},
|
||||||
@@ -20400,21 +20401,36 @@
|
|||||||
"integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA=="
|
"integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA=="
|
||||||
},
|
},
|
||||||
"node_modules/downshift": {
|
"node_modules/downshift": {
|
||||||
"version": "6.1.7",
|
"version": "9.0.9",
|
||||||
"resolved": "https://registry.npmjs.org/downshift/-/downshift-6.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/downshift/-/downshift-9.0.9.tgz",
|
||||||
"integrity": "sha512-cVprZg/9Lvj/uhYRxELzlu1aezRcgPWBjTvspiGTVEU64gF5pRdSRKFVLcxqsZC637cLAGMbL40JavEfWnqgNg==",
|
"integrity": "sha512-ygOT8blgiz5liDuEFAIaPeU4dDEa+w9p6PHVUisPIjrkF5wfR59a52HpGWAVVMoWnoFO8po2mZSScKZueihS7g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.14.8",
|
"@babel/runtime": "^7.24.5",
|
||||||
"compute-scroll-into-view": "^1.0.17",
|
"compute-scroll-into-view": "^3.1.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.8.1",
|
||||||
"react-is": "^17.0.2",
|
"react-is": "18.2.0",
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.6.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=16.12.0"
|
"react": ">=16.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/downshift/node_modules/compute-scroll-into-view": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz",
|
||||||
|
"integrity": "sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/downshift/node_modules/react-is": {
|
||||||
|
"version": "18.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||||
|
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/dropbox": {
|
"node_modules/dropbox": {
|
||||||
"version": "10.34.0",
|
"version": "10.34.0",
|
||||||
"resolved": "https://registry.npmjs.org/dropbox/-/dropbox-10.34.0.tgz",
|
"resolved": "https://registry.npmjs.org/dropbox/-/dropbox-10.34.0.tgz",
|
||||||
@@ -39925,9 +39941,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.5.2",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA=="
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"license": "0BSD"
|
||||||
},
|
},
|
||||||
"node_modules/tsscmp": {
|
"node_modules/tsscmp": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
@@ -45355,7 +45372,7 @@
|
|||||||
"daterangepicker": "2.1.27",
|
"daterangepicker": "2.1.27",
|
||||||
"diff": "^5.1.0",
|
"diff": "^5.1.0",
|
||||||
"dompurify": "^3.2.4",
|
"dompurify": "^3.2.4",
|
||||||
"downshift": "^6.1.0",
|
"downshift": "^9.0.9",
|
||||||
"es6-promise": "^4.2.8",
|
"es6-promise": "^4.2.8",
|
||||||
"escodegen": "^2.0.0",
|
"escodegen": "^2.0.0",
|
||||||
"eslint-config-standard-jsx": "^11.0.0",
|
"eslint-config-standard-jsx": "^11.0.0",
|
||||||
|
|||||||
+1
-8
@@ -24,10 +24,8 @@ function Downshift({ setValue, inputRef }: CountryInputProps) {
|
|||||||
getLabelProps,
|
getLabelProps,
|
||||||
getMenuProps,
|
getMenuProps,
|
||||||
getInputProps,
|
getInputProps,
|
||||||
getComboboxProps,
|
|
||||||
getItemProps,
|
getItemProps,
|
||||||
highlightedIndex,
|
highlightedIndex,
|
||||||
openMenu,
|
|
||||||
selectedItem,
|
selectedItem,
|
||||||
} = useCombobox({
|
} = useCombobox({
|
||||||
inputValue,
|
inputValue,
|
||||||
@@ -50,7 +48,7 @@ function Downshift({ setValue, inputRef }: CountryInputProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('dropdown', 'd-block')}>
|
<div className={classnames('dropdown', 'd-block')}>
|
||||||
<div {...getComboboxProps()}>
|
<div>
|
||||||
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
|
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
|
||||||
<label {...getLabelProps()} className="visually-hidden">
|
<label {...getLabelProps()} className="visually-hidden">
|
||||||
{t('country')}
|
{t('country')}
|
||||||
@@ -60,11 +58,6 @@ function Downshift({ setValue, inputRef }: CountryInputProps) {
|
|||||||
onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
|
onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setInputValue(event.target.value)
|
setInputValue(event.target.value)
|
||||||
},
|
},
|
||||||
onFocus: () => {
|
|
||||||
if (!isOpen) {
|
|
||||||
openMenu()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ref: inputRef,
|
ref: inputRef,
|
||||||
})}
|
})}
|
||||||
placeholder={t('country')}
|
placeholder={t('country')}
|
||||||
|
|||||||
@@ -47,10 +47,8 @@ function Downshift({
|
|||||||
getLabelProps,
|
getLabelProps,
|
||||||
getMenuProps,
|
getMenuProps,
|
||||||
getInputProps,
|
getInputProps,
|
||||||
getComboboxProps,
|
|
||||||
getItemProps,
|
getItemProps,
|
||||||
highlightedIndex,
|
highlightedIndex,
|
||||||
openMenu,
|
|
||||||
selectedItem,
|
selectedItem,
|
||||||
} = useCombobox({
|
} = useCombobox({
|
||||||
inputValue,
|
inputValue,
|
||||||
@@ -82,8 +80,7 @@ function Downshift({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('dropdown', 'd-block')}>
|
<div className={classnames('dropdown', 'd-block')}>
|
||||||
<div {...getComboboxProps()}>
|
<div>
|
||||||
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
|
|
||||||
<OLFormLabel
|
<OLFormLabel
|
||||||
{...getLabelProps()}
|
{...getLabelProps()}
|
||||||
className={showLabel ? '' : 'visually-hidden'}
|
className={showLabel ? '' : 'visually-hidden'}
|
||||||
@@ -95,11 +92,6 @@ function Downshift({
|
|||||||
onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
|
onChange: (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setValue(event.target.value)
|
setValue(event.target.value)
|
||||||
},
|
},
|
||||||
onFocus: () => {
|
|
||||||
if (!isOpen) {
|
|
||||||
openMenu()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ref: inputRef,
|
ref: inputRef,
|
||||||
})}
|
})}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
|||||||
+1
-6
@@ -94,7 +94,6 @@ export default function SelectCollaborators({
|
|||||||
getLabelProps,
|
getLabelProps,
|
||||||
getMenuProps,
|
getMenuProps,
|
||||||
getInputProps,
|
getInputProps,
|
||||||
getComboboxProps,
|
|
||||||
highlightedIndex,
|
highlightedIndex,
|
||||||
getItemProps,
|
getItemProps,
|
||||||
reset,
|
reset,
|
||||||
@@ -171,11 +170,7 @@ export default function SelectCollaborators({
|
|||||||
|
|
||||||
<div className="host">
|
<div className="host">
|
||||||
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
|
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions */}
|
||||||
<div
|
<div className="tags form-control" onClick={focusInput}>
|
||||||
{...getComboboxProps()}
|
|
||||||
className="tags form-control"
|
|
||||||
onClick={focusInput}
|
|
||||||
>
|
|
||||||
{selectedItems.map((selectedItem, index) => (
|
{selectedItems.map((selectedItem, index) => (
|
||||||
<SelectedItem
|
<SelectedItem
|
||||||
key={`selected-item-${index}`}
|
key={`selected-item-${index}`}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export type DropdownProps = {
|
|||||||
export type DropdownItemProps = PropsWithChildren<{
|
export type DropdownItemProps = PropsWithChildren<{
|
||||||
active?: boolean
|
active?: boolean
|
||||||
as?: ElementType
|
as?: ElementType
|
||||||
|
type?: string
|
||||||
description?: ReactNode
|
description?: ReactNode
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
eventKey?: string | number
|
eventKey?: string | number
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable jsx-a11y/label-has-for */
|
|
||||||
/* eslint-disable jsx-a11y/label-has-associated-control */
|
|
||||||
import {
|
import {
|
||||||
useRef,
|
useRef,
|
||||||
useEffect,
|
useEffect,
|
||||||
@@ -89,6 +87,7 @@ export const Select = <T,>({
|
|||||||
} = useSelect({
|
} = useSelect({
|
||||||
items: items ?? [],
|
items: items ?? [],
|
||||||
itemToString,
|
itemToString,
|
||||||
|
isItemDisabled: item => itemToDisabled?.(item) || false,
|
||||||
selectedItem: selected || defaultItem,
|
selectedItem: selected || defaultItem,
|
||||||
onSelectedItemChange: changes => {
|
onSelectedItemChange: changes => {
|
||||||
if (onSelectedItemChanged) {
|
if (onSelectedItemChanged) {
|
||||||
@@ -124,22 +123,18 @@ export const Select = <T,>({
|
|||||||
}
|
}
|
||||||
}, [name, itemToString, selectedItem, defaultItem])
|
}, [name, itemToString, selectedItem, defaultItem])
|
||||||
|
|
||||||
const handleMenuKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {
|
const onKeyDown: KeyboardEventHandler<HTMLInputElement> = useCallback(
|
||||||
if (event.key === 'Escape' && isOpen) {
|
|
||||||
event.stopPropagation()
|
|
||||||
closeMenu()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onKeyDown: KeyboardEventHandler<HTMLButtonElement> = useCallback(
|
|
||||||
event => {
|
event => {
|
||||||
if ((event.key === 'Enter' || event.key === ' ') && !isOpen) {
|
if ((event.key === 'Enter' || event.key === ' ') && !isOpen) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
;(event.nativeEvent as any).preventDownshiftDefault = true
|
;(event.nativeEvent as any).preventDownshiftDefault = true
|
||||||
openMenu()
|
openMenu()
|
||||||
|
} else if (event.key === 'Escape' && isOpen) {
|
||||||
|
event.stopPropagation()
|
||||||
|
closeMenu()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isOpen, openMenu]
|
[closeMenu, isOpen, openMenu]
|
||||||
)
|
)
|
||||||
|
|
||||||
let value: string | undefined
|
let value: string | undefined
|
||||||
@@ -187,16 +182,22 @@ export const Select = <T,>({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<ul
|
<ul
|
||||||
{...getMenuProps({ disabled, onKeyDown: handleMenuKeyDown })}
|
{...getMenuProps({ disabled })}
|
||||||
className={classNames('dropdown-menu w-100', { show: isOpen })}
|
className={classNames('dropdown-menu w-100', { show: isOpen })}
|
||||||
>
|
>
|
||||||
{isOpen &&
|
{isOpen &&
|
||||||
items?.map((item, index) => {
|
items?.map((item, index) => {
|
||||||
const isDisabled = itemToDisabled && itemToDisabled(item)
|
// We're using an actual disabled button so we don't need the
|
||||||
|
// aria-disabled prop
|
||||||
|
const { 'aria-disabled': disabled, ...itemProps } = getItemProps({
|
||||||
|
item,
|
||||||
|
index,
|
||||||
|
})
|
||||||
return (
|
return (
|
||||||
<li role="none" key={itemToKey(item)}>
|
<li role="none" key={itemToKey(item)}>
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
as="button"
|
as="button"
|
||||||
|
type="button"
|
||||||
className={classNames({
|
className={classNames({
|
||||||
'select-highlighted': highlightedIndex === index,
|
'select-highlighted': highlightedIndex === index,
|
||||||
})}
|
})}
|
||||||
@@ -207,7 +208,8 @@ export const Select = <T,>({
|
|||||||
description={
|
description={
|
||||||
itemToSubtitle ? itemToSubtitle(item) : undefined
|
itemToSubtitle ? itemToSubtitle(item) : undefined
|
||||||
}
|
}
|
||||||
{...getItemProps({ item, index, disabled: isDisabled })}
|
{...itemProps}
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{itemToString(item)}
|
{itemToString(item)}
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
|
|||||||
@@ -283,7 +283,7 @@
|
|||||||
"daterangepicker": "2.1.27",
|
"daterangepicker": "2.1.27",
|
||||||
"diff": "^5.1.0",
|
"diff": "^5.1.0",
|
||||||
"dompurify": "^3.2.4",
|
"dompurify": "^3.2.4",
|
||||||
"downshift": "^6.1.0",
|
"downshift": "^9.0.9",
|
||||||
"es6-promise": "^4.2.8",
|
"es6-promise": "^4.2.8",
|
||||||
"escodegen": "^2.0.0",
|
"escodegen": "^2.0.0",
|
||||||
"eslint-config-standard-jsx": "^11.0.0",
|
"eslint-config-standard-jsx": "^11.0.0",
|
||||||
|
|||||||
@@ -64,17 +64,17 @@ describe('<Select />', function () {
|
|||||||
it('renders default text', function () {
|
it('renders default text', function () {
|
||||||
render({ defaultText: 'Choose an item' })
|
render({ defaultText: 'Choose an item' })
|
||||||
cy.findByTestId('spinner').should('not.exist')
|
cy.findByTestId('spinner').should('not.exist')
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' })
|
cy.findByRole('combobox').should('have.value', 'Choose an item')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders default item', function () {
|
it('renders default item', function () {
|
||||||
render({ defaultItem: testData[2] })
|
render({ defaultItem: testData[2] })
|
||||||
cy.findByRole('textbox', { name: 'Demo item 3' })
|
cy.findByRole('combobox').should('have.value', 'Demo item 3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('default item takes precedence over default text', function () {
|
it('default item takes precedence over default text', function () {
|
||||||
render({ defaultText: 'Choose an item', defaultItem: testData[2] })
|
render({ defaultText: 'Choose an item', defaultItem: testData[2] })
|
||||||
cy.findByRole('textbox', { name: 'Demo item 3' })
|
cy.findByRole('combobox').should('have.value', 'Demo item 3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders label', function () {
|
it('renders label', function () {
|
||||||
@@ -83,8 +83,8 @@ describe('<Select />', function () {
|
|||||||
label: 'test label',
|
label: 'test label',
|
||||||
optionalLabel: false,
|
optionalLabel: false,
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'test label' })
|
cy.findByRole('combobox', { name: 'test label' })
|
||||||
cy.findByRole('textbox', { name: '(Optional)' }).should('not.exist')
|
cy.findByRole('combobox', { name: '(Optional)' }).should('not.exist')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders optional label', function () {
|
it('renders optional label', function () {
|
||||||
@@ -93,7 +93,7 @@ describe('<Select />', function () {
|
|||||||
label: 'test label',
|
label: 'test label',
|
||||||
optionalLabel: true,
|
optionalLabel: true,
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'test label (Optional)' })
|
cy.findByRole('combobox', { name: 'test label (Optional)' })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders a spinner while loading when there is a label', function () {
|
it('renders a spinner while loading when there is a label', function () {
|
||||||
@@ -117,7 +117,7 @@ describe('<Select />', function () {
|
|||||||
describe('items rendering', function () {
|
describe('items rendering', function () {
|
||||||
it('renders all items', function () {
|
it('renders all items', function () {
|
||||||
render({ defaultText: 'Choose an item' })
|
render({ defaultText: 'Choose an item' })
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click()
|
cy.findByRole('combobox').click()
|
||||||
|
|
||||||
cy.findByRole('option', { name: 'Demo item 1' })
|
cy.findByRole('option', { name: 'Demo item 1' })
|
||||||
cy.findByRole('option', { name: 'Demo item 2' })
|
cy.findByRole('option', { name: 'Demo item 2' })
|
||||||
@@ -129,7 +129,7 @@ describe('<Select />', function () {
|
|||||||
defaultText: 'Choose an item',
|
defaultText: 'Choose an item',
|
||||||
itemToSubtitle: x => String(x?.sub),
|
itemToSubtitle: x => String(x?.sub),
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click()
|
cy.findByRole('combobox').click()
|
||||||
|
|
||||||
cy.findByRole('option', { name: 'Demo item 1 Subtitle 1' })
|
cy.findByRole('option', { name: 'Demo item 1 Subtitle 1' })
|
||||||
cy.findByRole('option', { name: 'Demo item 2 Subtitle 2' })
|
cy.findByRole('option', { name: 'Demo item 2 Subtitle 2' })
|
||||||
@@ -140,27 +140,27 @@ describe('<Select />', function () {
|
|||||||
describe('item selection', function () {
|
describe('item selection', function () {
|
||||||
it('cannot select an item when disabled', function () {
|
it('cannot select an item when disabled', function () {
|
||||||
render({ defaultText: 'Choose an item', disabled: true })
|
render({ defaultText: 'Choose an item', disabled: true })
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click({
|
cy.findByRole('combobox').click({
|
||||||
force: true,
|
force: true,
|
||||||
})
|
})
|
||||||
cy.findByRole('option', { name: 'Demo item 1' }).should('not.exist')
|
cy.findByRole('option', { name: 'Demo item 1' }).should('not.exist')
|
||||||
cy.findByRole('option', { name: 'Demo item 2' }).should('not.exist')
|
cy.findByRole('option', { name: 'Demo item 2' }).should('not.exist')
|
||||||
cy.findByRole('option', { name: 'Demo item 3' }).should('not.exist')
|
cy.findByRole('option', { name: 'Demo item 3' }).should('not.exist')
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' })
|
cy.findByRole('combobox').should('have.value', 'Choose an item')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('renders only the selected item after selection', function () {
|
it('renders only the selected item after selection', function () {
|
||||||
render({ defaultText: 'Choose an item' })
|
render({ defaultText: 'Choose an item' })
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click()
|
cy.findByRole('combobox').click()
|
||||||
|
|
||||||
cy.findByRole('option', { name: 'Demo item 1' })
|
cy.findByRole('option', { name: 'Demo item 1' })
|
||||||
cy.findByRole('option', { name: 'Demo item 2' })
|
cy.findByRole('option', { name: 'Demo item 2' })
|
||||||
cy.findByRole('option', { name: 'Demo item 3' }).click()
|
cy.findByRole('option', { name: 'Demo item 3' }).click()
|
||||||
|
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).should('not.exist')
|
cy.findByRole('combobox').should('not.have.value', 'Choose an item')
|
||||||
cy.findByRole('option', { name: 'Demo item 1' }).should('not.exist')
|
cy.findByRole('option', { name: 'Demo item 1' }).should('not.exist')
|
||||||
cy.findByRole('option', { name: 'Demo item 2' }).should('not.exist')
|
cy.findByRole('option', { name: 'Demo item 2' }).should('not.exist')
|
||||||
cy.findByRole('textbox', { name: 'Demo item 3' })
|
cy.findByRole('combobox').should('have.value', 'Demo item 3')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('invokes callback after selection', function () {
|
it('invokes callback after selection', function () {
|
||||||
@@ -170,7 +170,7 @@ describe('<Select />', function () {
|
|||||||
defaultText: 'Choose an item',
|
defaultText: 'Choose an item',
|
||||||
onSelectedItemChanged: selectionHandler,
|
onSelectedItemChanged: selectionHandler,
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click()
|
cy.findByRole('combobox').click()
|
||||||
cy.findByRole('option', { name: 'Demo item 2' }).click()
|
cy.findByRole('option', { name: 'Demo item 2' }).click()
|
||||||
|
|
||||||
cy.get('@selectionHandler').should(
|
cy.get('@selectionHandler').should(
|
||||||
@@ -195,7 +195,7 @@ describe('<Select />', function () {
|
|||||||
const submitHandler = cy.stub().as('submitHandler')
|
const submitHandler = cy.stub().as('submitHandler')
|
||||||
render({ defaultItem: testData[1], onSubmit: submitHandler })
|
render({ defaultItem: testData[1], onSubmit: submitHandler })
|
||||||
|
|
||||||
cy.findByRole('textbox', { name: 'Demo item 2' }).click() // open dropdown
|
cy.findByRole('combobox').click() // open dropdown
|
||||||
cy.findByText('Demo item 3').click() // choose a different item
|
cy.findByText('Demo item 3').click() // choose a different item
|
||||||
|
|
||||||
cy.findByText('submit').click()
|
cy.findByText('submit').click()
|
||||||
@@ -262,7 +262,7 @@ describe('<Select />', function () {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
cy.findByRole('textbox', { name: 'Demo item 1' }).click() // open dropdown
|
cy.findByRole('combobox').click() // open dropdown
|
||||||
cy.findByRole('option', { name: 'Demo item 3' }).click() // choose a different item
|
cy.findByRole('option', { name: 'Demo item 3' }).click() // choose a different item
|
||||||
|
|
||||||
cy.findByText('submit').click()
|
cy.findByText('submit').click()
|
||||||
@@ -275,11 +275,10 @@ describe('<Select />', function () {
|
|||||||
describe('keyboard navigation', function () {
|
describe('keyboard navigation', function () {
|
||||||
it('can select an item using the keyboard', function () {
|
it('can select an item using the keyboard', function () {
|
||||||
render({ defaultText: 'Choose an item' })
|
render({ defaultText: 'Choose an item' })
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).type(
|
cy.findByRole('combobox').type('{Enter}{downArrow}{Enter}', {
|
||||||
'{Enter}{downArrow}{Enter}',
|
force: true,
|
||||||
{ force: true }
|
})
|
||||||
)
|
cy.findByRole('combobox').should('exist')
|
||||||
cy.findByRole('textbox', { name: 'Demo item 1' }).should('exist')
|
|
||||||
cy.findByRole('option', { name: 'Demo item 2' }).should('not.exist')
|
cy.findByRole('option', { name: 'Demo item 2' }).should('not.exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -290,9 +289,9 @@ describe('<Select />', function () {
|
|||||||
defaultText: 'Choose an item',
|
defaultText: 'Choose an item',
|
||||||
selectedIcon: true,
|
selectedIcon: true,
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click()
|
cy.findByRole('combobox').click()
|
||||||
cy.findByRole('option', { name: 'Demo item 1' }).click()
|
cy.findByRole('option', { name: 'Demo item 1' }).click()
|
||||||
cy.findByRole('textbox', { name: 'Demo item 1' }).click()
|
cy.findByRole('combobox').click()
|
||||||
|
|
||||||
cy.findByText('check').should('exist')
|
cy.findByText('check').should('exist')
|
||||||
})
|
})
|
||||||
@@ -301,9 +300,9 @@ describe('<Select />', function () {
|
|||||||
defaultText: 'Choose an item',
|
defaultText: 'Choose an item',
|
||||||
selectedIcon: false,
|
selectedIcon: false,
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click()
|
cy.findByRole('combobox').click()
|
||||||
cy.findByRole('option', { name: 'Demo item 1' }).click()
|
cy.findByRole('option', { name: 'Demo item 1' }).click()
|
||||||
cy.findByRole('textbox', { name: 'Demo item 1' }).click()
|
cy.findByRole('combobox').click()
|
||||||
|
|
||||||
cy.findByText('check').should('not.exist')
|
cy.findByText('check').should('not.exist')
|
||||||
})
|
})
|
||||||
@@ -315,7 +314,7 @@ describe('<Select />', function () {
|
|||||||
defaultText: 'Choose an item',
|
defaultText: 'Choose an item',
|
||||||
itemToDisabled: x => x?.key === 2,
|
itemToDisabled: x => x?.key === 2,
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).click()
|
cy.findByRole('combobox').click()
|
||||||
cy.findByRole('option', { name: 'Demo item 2' }).click({ force: true })
|
cy.findByRole('option', { name: 'Demo item 2' }).click({ force: true })
|
||||||
// still showing other list items
|
// still showing other list items
|
||||||
cy.findByRole('option', { name: 'Demo item 3' }).should('exist')
|
cy.findByRole('option', { name: 'Demo item 3' }).should('exist')
|
||||||
@@ -331,7 +330,7 @@ describe('<Select />', function () {
|
|||||||
defaultText: 'Choose an item',
|
defaultText: 'Choose an item',
|
||||||
selected: testData[1],
|
selected: testData[1],
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Demo item 2' }).should('exist')
|
cy.findByRole('combobox').should('have.value', 'Demo item 2')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should show default text when selected is null', function () {
|
it('should show default text when selected is null', function () {
|
||||||
@@ -339,7 +338,7 @@ describe('<Select />', function () {
|
|||||||
selected: null,
|
selected: null,
|
||||||
defaultText: 'Choose an item',
|
defaultText: 'Choose an item',
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Choose an item' }).should('exist')
|
cy.findByRole('combobox').should('have.value', 'Choose an item')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
+24
-20
@@ -304,7 +304,7 @@ describe('<EmailsSection />', function () {
|
|||||||
|
|
||||||
await userEvent.click(screen.getByRole('button', { name: /let us know/i }))
|
await userEvent.click(screen.getByRole('button', { name: /let us know/i }))
|
||||||
|
|
||||||
const universityInput = screen.getByRole<HTMLInputElement>('textbox', {
|
const universityInput = screen.getByRole<HTMLInputElement>('combobox', {
|
||||||
name: /university/i,
|
name: /university/i,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -321,7 +321,7 @@ describe('<EmailsSection />', function () {
|
|||||||
|
|
||||||
// Select the country from dropdown
|
// Select the country from dropdown
|
||||||
await userEvent.type(
|
await userEvent.type(
|
||||||
screen.getByRole('textbox', {
|
screen.getByRole('combobox', {
|
||||||
name: /country/i,
|
name: /country/i,
|
||||||
}),
|
}),
|
||||||
country
|
country
|
||||||
@@ -339,9 +339,11 @@ describe('<EmailsSection />', function () {
|
|||||||
await screen.findByText(userEmailData.affiliation.institution.name)
|
await screen.findByText(userEmailData.affiliation.institution.name)
|
||||||
)
|
)
|
||||||
|
|
||||||
const roleInput = screen.getByRole('textbox', { name: /role/i })
|
const roleInput = screen.getByRole('combobox', { name: /role/i })
|
||||||
await userEvent.type(roleInput, userEmailData.affiliation.role!)
|
await userEvent.type(roleInput, userEmailData.affiliation.role!)
|
||||||
const departmentInput = screen.getByRole('textbox', { name: /department/i })
|
const departmentInput = screen.getByRole('combobox', {
|
||||||
|
name: /department/i,
|
||||||
|
})
|
||||||
await userEvent.click(departmentInput)
|
await userEvent.click(departmentInput)
|
||||||
await userEvent.click(screen.getByText(customDepartment))
|
await userEvent.click(screen.getByText(customDepartment))
|
||||||
|
|
||||||
@@ -415,7 +417,7 @@ describe('<EmailsSection />', function () {
|
|||||||
await userEvent.click(screen.getByRole('button', { name: /let us know/i }))
|
await userEvent.click(screen.getByRole('button', { name: /let us know/i }))
|
||||||
|
|
||||||
// select a country
|
// select a country
|
||||||
const countryInput = screen.getByRole<HTMLInputElement>('textbox', {
|
const countryInput = screen.getByRole<HTMLInputElement>('combobox', {
|
||||||
name: /country/i,
|
name: /country/i,
|
||||||
})
|
})
|
||||||
await userEvent.click(countryInput)
|
await userEvent.click(countryInput)
|
||||||
@@ -423,7 +425,7 @@ describe('<EmailsSection />', function () {
|
|||||||
await userEvent.click(await screen.findByText('Germany'))
|
await userEvent.click(await screen.findByText('Germany'))
|
||||||
|
|
||||||
// match several universities on initial typing
|
// match several universities on initial typing
|
||||||
const universityInput = screen.getByRole<HTMLInputElement>('textbox', {
|
const universityInput = screen.getByRole<HTMLInputElement>('combobox', {
|
||||||
name: /university/i,
|
name: /university/i,
|
||||||
})
|
})
|
||||||
await userEvent.click(universityInput)
|
await userEvent.click(universityInput)
|
||||||
@@ -457,7 +459,7 @@ describe('<EmailsSection />', function () {
|
|||||||
|
|
||||||
await userEvent.click(screen.getByRole('button', { name: /let us know/i }))
|
await userEvent.click(screen.getByRole('button', { name: /let us know/i }))
|
||||||
|
|
||||||
const universityInput = screen.getByRole<HTMLInputElement>('textbox', {
|
const universityInput = screen.getByRole<HTMLInputElement>('combobox', {
|
||||||
name: /university/i,
|
name: /university/i,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -474,7 +476,7 @@ describe('<EmailsSection />', function () {
|
|||||||
|
|
||||||
// Select the country from dropdown
|
// Select the country from dropdown
|
||||||
await userEvent.type(
|
await userEvent.type(
|
||||||
screen.getByRole('textbox', {
|
screen.getByRole('combobox', {
|
||||||
name: /country/i,
|
name: /country/i,
|
||||||
}),
|
}),
|
||||||
country
|
country
|
||||||
@@ -489,9 +491,11 @@ describe('<EmailsSection />', function () {
|
|||||||
// Enter the university manually
|
// Enter the university manually
|
||||||
await userEvent.type(universityInput, newUniversity)
|
await userEvent.type(universityInput, newUniversity)
|
||||||
|
|
||||||
const roleInput = screen.getByRole('textbox', { name: /role/i })
|
const roleInput = screen.getByRole('combobox', { name: /role/i })
|
||||||
await userEvent.type(roleInput, userEmailData.affiliation.role!)
|
await userEvent.type(roleInput, userEmailData.affiliation.role!)
|
||||||
const departmentInput = screen.getByRole('textbox', { name: /department/i })
|
const departmentInput = screen.getByRole('combobox', {
|
||||||
|
name: /department/i,
|
||||||
|
})
|
||||||
await userEvent.type(departmentInput, userEmailData.affiliation.department!)
|
await userEvent.type(departmentInput, userEmailData.affiliation.department!)
|
||||||
|
|
||||||
const userEmailDataCopy = {
|
const userEmailDataCopy = {
|
||||||
@@ -577,37 +581,37 @@ describe('<EmailsSection />', function () {
|
|||||||
fetchMock.removeRoutes().clearHistory()
|
fetchMock.removeRoutes().clearHistory()
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen.queryByRole('textbox', {
|
screen.queryByRole('combobox', {
|
||||||
name: /country/i,
|
name: /country/i,
|
||||||
})
|
})
|
||||||
).to.be.null
|
).to.be.null
|
||||||
expect(
|
expect(
|
||||||
screen.queryByRole('textbox', {
|
screen.queryByRole('combobox', {
|
||||||
name: /university/i,
|
name: /university/i,
|
||||||
})
|
})
|
||||||
).to.be.null
|
).to.be.null
|
||||||
screen.getByRole('textbox', {
|
screen.getByRole('combobox', {
|
||||||
name: /role/i,
|
name: /role/i,
|
||||||
})
|
})
|
||||||
screen.getByRole('textbox', {
|
screen.getByRole('combobox', {
|
||||||
name: /department/i,
|
name: /department/i,
|
||||||
})
|
})
|
||||||
|
|
||||||
await userEvent.click(screen.getByRole('button', { name: /change/i }))
|
await userEvent.click(screen.getByRole('button', { name: /change/i }))
|
||||||
|
|
||||||
screen.getByRole('textbox', {
|
screen.getByRole('combobox', {
|
||||||
name: /country/i,
|
name: /country/i,
|
||||||
})
|
})
|
||||||
screen.getByRole('textbox', {
|
screen.getByRole('combobox', {
|
||||||
name: /university/i,
|
name: /university/i,
|
||||||
})
|
})
|
||||||
expect(
|
expect(
|
||||||
screen.queryByRole('textbox', {
|
screen.queryByRole('combobox', {
|
||||||
name: /role/i,
|
name: /role/i,
|
||||||
})
|
})
|
||||||
).to.be.null
|
).to.be.null
|
||||||
expect(
|
expect(
|
||||||
screen.queryByRole('textbox', {
|
screen.queryByRole('combobox', {
|
||||||
name: /department/i,
|
name: /department/i,
|
||||||
})
|
})
|
||||||
).to.be.null
|
).to.be.null
|
||||||
@@ -668,11 +672,11 @@ describe('<EmailsSection />', function () {
|
|||||||
.post('/user/emails/confirm-secondary', 200)
|
.post('/user/emails/confirm-secondary', 200)
|
||||||
|
|
||||||
await userEvent.type(
|
await userEvent.type(
|
||||||
screen.getByRole('textbox', { name: /role/i }),
|
screen.getByRole('combobox', { name: /role/i }),
|
||||||
userEmailData.affiliation.role!
|
userEmailData.affiliation.role!
|
||||||
)
|
)
|
||||||
await userEvent.type(
|
await userEvent.type(
|
||||||
screen.getByRole('textbox', { name: /department/i }),
|
screen.getByRole('combobox', { name: /department/i }),
|
||||||
userEmailData.affiliation.department!
|
userEmailData.affiliation.department!
|
||||||
)
|
)
|
||||||
await userEvent.click(
|
await userEvent.click(
|
||||||
|
|||||||
+1
-1
@@ -146,7 +146,7 @@ describe('user role and institution', function () {
|
|||||||
await fetchMock.callHistory.flush(true)
|
await fetchMock.callHistory.flush(true)
|
||||||
fetchMock.removeRoutes().clearHistory()
|
fetchMock.removeRoutes().clearHistory()
|
||||||
|
|
||||||
fireEvent.click(screen.getByRole('textbox', { name: /department/i }))
|
fireEvent.click(screen.getByRole('combobox', { name: /department/i }))
|
||||||
|
|
||||||
screen.getByText(fakeDepartment)
|
screen.getByText(fakeDepartment)
|
||||||
})
|
})
|
||||||
|
|||||||
+22
-9
@@ -126,7 +126,7 @@ describe('<FigureModal />', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('Lists files from project', function () {
|
it('Lists files from project', function () {
|
||||||
cy.findByRole('textbox', { name: 'Image file' }).click()
|
cy.findByRole('combobox', { name: 'Image file' }).click()
|
||||||
cy.findByRole('listbox')
|
cy.findByRole('listbox')
|
||||||
.children()
|
.children()
|
||||||
.should('have.length', 2)
|
.should('have.length', 2)
|
||||||
@@ -137,7 +137,7 @@ describe('<FigureModal />', function () {
|
|||||||
|
|
||||||
it('Enables insert button when choosing file', function () {
|
it('Enables insert button when choosing file', function () {
|
||||||
cy.findByRole('button', { name: 'Insert figure' }).should('be.disabled')
|
cy.findByRole('button', { name: 'Insert figure' }).should('be.disabled')
|
||||||
cy.findByRole('textbox', { name: 'Image file' }).click()
|
cy.findByRole('combobox', { name: 'Image file' }).click()
|
||||||
cy.findByRole('listbox').within(() => {
|
cy.findByRole('listbox').within(() => {
|
||||||
cy.findByText('frog.jpg').click()
|
cy.findByText('frog.jpg').click()
|
||||||
})
|
})
|
||||||
@@ -145,7 +145,7 @@ describe('<FigureModal />', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('Inserts file when pressing insert button', function () {
|
it('Inserts file when pressing insert button', function () {
|
||||||
cy.findByRole('textbox', { name: 'Image file' }).click()
|
cy.findByRole('combobox', { name: 'Image file' }).click()
|
||||||
cy.findByRole('listbox').within(() => {
|
cy.findByRole('listbox').within(() => {
|
||||||
cy.findByText('frog.jpg').click()
|
cy.findByText('frog.jpg').click()
|
||||||
})
|
})
|
||||||
@@ -166,8 +166,8 @@ describe('<FigureModal />', function () {
|
|||||||
cy.findByRole('menu').within(() => {
|
cy.findByRole('menu').within(() => {
|
||||||
cy.findByRole('button', { name: 'From another project' }).click()
|
cy.findByRole('button', { name: 'From another project' }).click()
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Project' }).as('project-dropdown')
|
cy.findByRole('combobox', { name: 'Project' }).as('project-dropdown')
|
||||||
cy.findByRole('textbox', { name: 'Image file' }).as('file-dropdown')
|
cy.findByRole('combobox', { name: 'Image file' }).as('file-dropdown')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('List projects and files in projects', function () {
|
it('List projects and files in projects', function () {
|
||||||
@@ -203,6 +203,19 @@ describe('<FigureModal />', function () {
|
|||||||
cy.findByRole('button', { name: 'Insert figure' }).should('be.enabled')
|
cy.findByRole('button', { name: 'Insert figure' }).should('be.enabled')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Closes project dropdown on pressing Esc key but leaves modal open', function () {
|
||||||
|
cy.findByRole('button', { name: 'Insert figure' }).should('be.disabled')
|
||||||
|
cy.get('@project-dropdown').click()
|
||||||
|
cy.findByRole('listbox').should('exist')
|
||||||
|
cy.get('@project-dropdown').type('{esc}', { force: true })
|
||||||
|
cy.findByRole('listbox').should('not.exist')
|
||||||
|
cy.findByRole('dialog').should('exist')
|
||||||
|
|
||||||
|
// Check that a subsequent press of the Esc key closes the modal
|
||||||
|
cy.get('@project-dropdown').type('{esc}', { force: true })
|
||||||
|
cy.findByRole('dialog').should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
it('Creates linked file when pressing insert', function () {
|
it('Creates linked file when pressing insert', function () {
|
||||||
cy.get('@project-dropdown').click()
|
cy.get('@project-dropdown').click()
|
||||||
cy.findByRole('listbox').within(() => {
|
cy.findByRole('listbox').within(() => {
|
||||||
@@ -235,7 +248,7 @@ describe('<FigureModal />', function () {
|
|||||||
cy.findByRole('option', { name: 'My first project' }).click()
|
cy.findByRole('option', { name: 'My first project' }).click()
|
||||||
})
|
})
|
||||||
cy.findByRole('button', { name: 'select from output files' }).click()
|
cy.findByRole('button', { name: 'select from output files' }).click()
|
||||||
cy.findByRole('textbox', { name: 'Output file' }).click()
|
cy.findByRole('combobox', { name: 'Output file' }).click()
|
||||||
cy.findByRole('listbox').within(() => {
|
cy.findByRole('listbox').within(() => {
|
||||||
cy.findByRole('option', { name: 'output.pdf' }).click()
|
cy.findByRole('option', { name: 'output.pdf' }).click()
|
||||||
})
|
})
|
||||||
@@ -298,7 +311,7 @@ describe('<FigureModal />', function () {
|
|||||||
cy.findByRole('menu').within(() => {
|
cy.findByRole('menu').within(() => {
|
||||||
cy.findByText('From another project').click()
|
cy.findByText('From another project').click()
|
||||||
})
|
})
|
||||||
cy.findByRole('textbox', { name: 'Project' }).click()
|
cy.findByRole('combobox', { name: 'Project' }).click()
|
||||||
cy.findByRole('listbox').within(() => {
|
cy.findByRole('listbox').within(() => {
|
||||||
cy.findByRole('option', { name: 'My first project' }).click()
|
cy.findByRole('option', { name: 'My first project' }).click()
|
||||||
})
|
})
|
||||||
@@ -322,7 +335,7 @@ describe('<FigureModal />', function () {
|
|||||||
})
|
})
|
||||||
expectNoOutputSwitch()
|
expectNoOutputSwitch()
|
||||||
it('should show output file selector', function () {
|
it('should show output file selector', function () {
|
||||||
cy.findByRole('textbox', { name: 'Output file' }).click()
|
cy.findByRole('combobox', { name: 'Output file' }).click()
|
||||||
cy.findByRole('listbox').within(() => {
|
cy.findByRole('listbox').within(() => {
|
||||||
cy.findByRole('option', { name: 'output.pdf' }).click()
|
cy.findByRole('option', { name: 'output.pdf' }).click()
|
||||||
})
|
})
|
||||||
@@ -341,7 +354,7 @@ describe('<FigureModal />', function () {
|
|||||||
expectNoOutputSwitch()
|
expectNoOutputSwitch()
|
||||||
|
|
||||||
it('should show source file selector', function () {
|
it('should show source file selector', function () {
|
||||||
cy.findByRole('textbox', { name: 'Image file' }).click()
|
cy.findByRole('combobox', { name: 'Image file' }).click()
|
||||||
cy.findByRole('listbox').within(() => {
|
cy.findByRole('listbox').within(() => {
|
||||||
cy.findByRole('option', { name: 'frog.jpg' }).click()
|
cy.findByRole('option', { name: 'frog.jpg' }).click()
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user