1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-12-27 13:48:52 +02:00

[GH-1013] Fix visibility of clear button for select option (#1160)

* Show clear button for (multi)select property only when it is being edited.

* Files for multi-select property moved to separate folder.

* Extracted component for select property.

* Minor tweaks for Label style.

* Redundant code for clear button removed.

* Unit test for select property component added.

* Jest snapshots updated.

* Fix stylelint error.

* Jest snapshot updated.

Co-authored-by: Scott Bishel <scott.bishel@mattermost.com>
This commit is contained in:
kamre 2021-09-15 04:35:41 +07:00 committed by GitHub
parent 826e717af8
commit ca2116c04b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 371 additions and 191 deletions

View File

@ -56,6 +56,7 @@ exports[`components/propertyValueElement should match snapshot, select 1`] = `
<div>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -66,16 +67,6 @@ exports[`components/propertyValueElement should match snapshot, select 1`] = `
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -85,6 +76,7 @@ exports[`components/propertyValueElement should match snapshot, select, read-onl
<div>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span

View File

@ -28,6 +28,7 @@ exports[`components/cardDetail/CardDetailProperties should match snapshot 1`] =
</div>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -38,16 +39,6 @@ exports[`components/cardDetail/CardDetailProperties should match snapshot 1`] =
>
Jean-Luc Picard
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>

View File

@ -35,7 +35,7 @@
right: 0;
}
> .octo-propertyvalue {
.octo-propertyvalue {
margin: 4px 0 0;
font-size: 12px;
line-height: 18px;

View File

@ -6,7 +6,7 @@ import userEvent from '@testing-library/user-event'
import '@testing-library/jest-dom'
import {IntlProvider} from 'react-intl'
import {IPropertyOption, IPropertyTemplate} from '../../blocks/board'
import {IPropertyOption, IPropertyTemplate} from '../../../blocks/board'
import MultiSelect from './multiSelect'

View File

@ -3,11 +3,11 @@
import React, {useState} from 'react'
import {IPropertyOption, IPropertyTemplate} from '../../blocks/board'
import {IPropertyOption, IPropertyTemplate} from '../../../blocks/board'
import Label from '../../widgets/label'
import Label from '../../../widgets/label'
import ValueSelector from '../../widgets/valueSelector'
import ValueSelector from '../../../widgets/valueSelector'
type Props = {
emptyValue: string;
@ -44,7 +44,9 @@ const MultiSelectProperty = (props: Props): JSX.Element => {
</Label>
))}
{values.length === 0 && (
<Label color='empty'>{''}</Label>
<Label
color='empty'
>{''}</Label>
)}
</div>
)
@ -61,6 +63,7 @@ const MultiSelectProperty = (props: Props): JSX.Element => {
onDeleteOption={onDeleteOption}
onDeleteValue={(valueToRemove) => onDeleteValue(valueToRemove, values)}
onCreate={(newValue) => onCreate(newValue, values)}
onBlur={() => setOpen(false)}
/>
)
}

View File

@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/properties/select shows empty placeholder 1`] = `
<div>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
class="Label empty "
>
<span
class="Label-text"
>
Empty
</span>
</span>
</div>
</div>
`;
exports[`components/properties/select shows the selected option 1`] = `
<div>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
class="Label propColorDefault "
>
<span
class="Label-text"
>
one
</span>
</span>
</div>
</div>
`;

View File

@ -0,0 +1,193 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react'
import {render, screen} from '@testing-library/react'
import '@testing-library/jest-dom'
import userEvent from '@testing-library/user-event'
import {IPropertyTemplate} from '../../../blocks/board'
import {wrapIntl} from '../../../testUtils'
import Select from './select'
function selectPropertyTemplate(): IPropertyTemplate {
return {
id: 'select-template',
name: 'select',
type: 'select',
options: [
{
id: 'option-1',
value: 'one',
color: 'propColorDefault',
},
{
id: 'option-2',
value: 'two',
color: 'propColorGreen',
},
{
id: 'option-3',
value: 'three',
color: 'propColorRed',
},
],
}
}
function selectCallbacks() {
return {
onCreate: jest.fn(),
onChange: jest.fn(),
onChangeColor: jest.fn(),
onDeleteOption: jest.fn(),
onDeleteValue: jest.fn(),
}
}
describe('components/properties/select', () => {
const nonEditableSelectTestId = 'select-non-editable'
const clearButton = () => screen.queryByRole('button', {name: /clear/i})
it('shows the selected option', () => {
const propertyTemplate = selectPropertyTemplate()
const option = propertyTemplate.options[0]
const {container} = render(wrapIntl(
<Select
emptyValue={''}
propertyTemplate={propertyTemplate}
propertyValue={option.id}
isEditable={false}
{...selectCallbacks()}
/>,
))
expect(screen.getByText(option.value)).toBeInTheDocument()
expect(clearButton()).not.toBeInTheDocument()
expect(container).toMatchSnapshot()
})
it('shows empty placeholder', () => {
const propertyTemplate = selectPropertyTemplate()
const emptyValue = 'Empty'
const {container} = render(wrapIntl(
<Select
emptyValue={emptyValue}
propertyTemplate={propertyTemplate}
propertyValue={''}
isEditable={false}
{...selectCallbacks()}
/>,
))
expect(screen.getByText(emptyValue)).toBeInTheDocument()
expect(clearButton()).not.toBeInTheDocument()
expect(container).toMatchSnapshot()
})
it('shows the menu with options when preview is clicked', () => {
const propertyTemplate = selectPropertyTemplate()
const selected = propertyTemplate.options[1]
render(wrapIntl(
<Select
emptyValue={''}
propertyTemplate={propertyTemplate}
propertyValue={selected.id}
isEditable={true}
{...selectCallbacks()}
/>,
))
userEvent.click(screen.getByTestId(nonEditableSelectTestId))
// check that all options are visible
for (const option of propertyTemplate.options) {
const elements = screen.getAllByText(option.value)
// selected option is rendered twice: in the input and inside the menu
const expected = option.id === selected.id ? 2 : 1
expect(elements.length).toBe(expected)
}
expect(clearButton()).toBeInTheDocument()
})
it('can select the option from menu', () => {
const propertyTemplate = selectPropertyTemplate()
const optionToSelect = propertyTemplate.options[2]
const onChange = jest.fn()
render(wrapIntl(
<Select
emptyValue={'Empty'}
propertyTemplate={propertyTemplate}
propertyValue={''}
isEditable={true}
{...selectCallbacks()}
onChange={onChange}
/>,
))
userEvent.click(screen.getByTestId(nonEditableSelectTestId))
userEvent.click(screen.getByText(optionToSelect.value))
expect(clearButton()).not.toBeInTheDocument()
expect(onChange).toHaveBeenCalledWith(optionToSelect.id)
})
it('can clear the selected option', () => {
const propertyTemplate = selectPropertyTemplate()
const selected = propertyTemplate.options[1]
const onDeleteValue = jest.fn()
render(wrapIntl(
<Select
emptyValue={'Empty'}
propertyTemplate={propertyTemplate}
propertyValue={selected.id}
isEditable={true}
{...selectCallbacks()}
onDeleteValue={onDeleteValue}
/>,
))
userEvent.click(screen.getByTestId(nonEditableSelectTestId))
const clear = clearButton()
expect(clear).toBeInTheDocument()
userEvent.click(clear!)
expect(onDeleteValue).toHaveBeenCalled()
})
it('can create new option', () => {
const propertyTemplate = selectPropertyTemplate()
const initialOption = propertyTemplate.options[0]
const newOption = 'new-option'
const onCreate = jest.fn()
render(wrapIntl(
<Select
emptyValue={'Empty'}
propertyTemplate={propertyTemplate}
propertyValue={initialOption.id}
isEditable={true}
{...selectCallbacks()}
onCreate={onCreate}
/>,
))
userEvent.click(screen.getByTestId(nonEditableSelectTestId))
userEvent.type(screen.getByRole('textbox', {name: /value selector/i}), `${newOption}{enter}`)
expect(onCreate).toHaveBeenCalledWith(newOption)
})
})

View File

@ -0,0 +1,61 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useState} from 'react'
import {IPropertyOption, IPropertyTemplate} from '../../../blocks/board'
import Label from '../../../widgets/label'
import ValueSelector from '../../../widgets/valueSelector'
type Props = {
emptyValue: string
propertyValue: string
propertyTemplate: IPropertyTemplate
onCreate: (value: string) => void
onChange: (value: string) => void
onChangeColor: (option: IPropertyOption, color: string) => void
onDeleteOption: (option: IPropertyOption) => void
onDeleteValue: () => void;
isEditable: boolean
}
const SelectProperty = React.memo((props: Props) => {
const {emptyValue, propertyValue, propertyTemplate, isEditable} = props
const [open, setOpen] = useState(false)
const option = propertyTemplate.options.find((o) => o.id === propertyValue)
const propertyColorCssClassName = option?.color || ''
const displayValue = option?.value
const finalDisplayValue = displayValue || emptyValue
if (!isEditable || !open) {
return (
<div
className='octo-propertyvalue'
data-testid='select-non-editable'
tabIndex={0}
onClick={() => setOpen(true)}
>
<Label color={displayValue ? propertyColorCssClassName : 'empty'}>
<span className='Label-text'>{finalDisplayValue}</span>
</Label>
</div>
)
}
return (
<ValueSelector
emptyValue={emptyValue}
options={propertyTemplate.options}
value={propertyTemplate.options.find((p) => p.id === propertyValue)}
onCreate={props.onCreate}
onChange={(value) => props.onChange(value as string)}
onChangeColor={props.onChangeColor}
onDeleteOption={props.onDeleteOption}
onDeleteValue={props.onDeleteValue}
onBlur={() => setOpen(false)}
/>
)
})
export default SelectProperty

View File

@ -12,22 +12,17 @@ import mutator from '../mutator'
import {OctoUtils} from '../octoUtils'
import {Utils} from '../utils'
import Editable from '../widgets/editable'
import ValueSelector from '../widgets/valueSelector'
import Label from '../widgets/label'
import Switch from '../widgets/switch'
import IconButton from '../widgets/buttons/iconButton'
import CloseIcon from '../widgets/icons/close'
import UserProperty from './properties/user/user'
import MultiSelectProperty from './properties/multiSelect'
import MultiSelectProperty from './properties/multiSelect/multiSelect'
import URLProperty from './properties/link/link'
import LastModifiedBy from './properties/lastModifiedBy/lastModifiedBy'
import LastModifiedAt from './properties/lastModifiedAt/lastModifiedAt'
import CreatedAt from './properties/createdAt/createdAt'
import CreatedBy from './properties/createdBy/createdBy'
import DateRange from './properties/dateRange/dateRange'
import SelectProperty from './properties/select/select'
type Props = {
board: Board
@ -48,7 +43,6 @@ const PropertyValueElement = (props:Props): JSX.Element => {
const propertyValue = card.fields.properties[propertyTemplate.id]
const displayValue = OctoUtils.propertyDisplayValue(card, propertyValue, propertyTemplate, intl)
const finalDisplayValue = displayValue || emptyDisplayValue
const [open, setOpen] = useState(false)
const editableFields: Array<PropertyType> = ['text', 'number', 'email', 'url', 'phone']
@ -130,47 +124,12 @@ const PropertyValueElement = (props:Props): JSX.Element => {
}
if (propertyTemplate.type === 'select') {
let propertyColorCssClassName = ''
const cardPropertyValue = propertyTemplate.options.find((o) => o.id === propertyValue)
if (cardPropertyValue) {
propertyColorCssClassName = cardPropertyValue.color
}
if (readOnly || !board || !open) {
return (
<div
className='octo-propertyvalue'
tabIndex={0}
onClick={() => setOpen(true)}
>
<Label color={displayValue ? propertyColorCssClassName : 'empty'}>
<span className='Label-text'>{finalDisplayValue}</span>
{displayValue && !props.readOnly &&
<IconButton
onClick={onDeleteValue}
onMouseDown={(e: React.MouseEvent) => e.stopPropagation()}
icon={<CloseIcon/>}
title='Clear'
className='margin-left delete-value'
/>}
</Label>
</div>
)
}
return (
<ValueSelector
<SelectProperty
isEditable={!readOnly && Boolean(board)}
emptyValue={emptyDisplayValue}
options={propertyTemplate.options}
value={propertyTemplate.options.find((p) => p.id === propertyValue)}
onChange={(newValue) => {
mutator.changePropertyValue(card, propertyTemplate.id, newValue)
}}
onChangeColor={(option: IPropertyOption, colorId: string): void => {
mutator.changePropertyOptionColor(board, propertyTemplate, option, colorId)
}}
onDeleteOption={(option: IPropertyOption): void => {
mutator.deletePropertyOption(board, propertyTemplate, option)
}}
propertyValue={propertyValue as string}
propertyTemplate={propertyTemplate}
onCreate={
async (newValue) => {
const option: IPropertyOption = {
@ -182,6 +141,15 @@ const PropertyValueElement = (props:Props): JSX.Element => {
mutator.changePropertyValue(card, propertyTemplate.id, option.id)
}
}
onChange={(newValue) => {
mutator.changePropertyValue(card, propertyTemplate.id, newValue)
}}
onChangeColor={(option: IPropertyOption, colorId: string): void => {
mutator.changePropertyOptionColor(board, propertyTemplate, option, colorId)
}}
onDeleteOption={(option: IPropertyOption): void => {
mutator.deletePropertyOption(board, propertyTemplate, option)
}}
onDeleteValue={onDeleteValue}
/>
)

View File

@ -180,6 +180,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -190,16 +191,6 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 1`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -209,6 +200,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -276,6 +268,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -286,16 +279,6 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 1`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -305,6 +288,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -584,6 +568,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 2`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -594,16 +579,6 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 2`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -613,6 +588,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 2`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -680,6 +656,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 2`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -690,16 +667,6 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 2`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -709,6 +676,7 @@ exports[`components/table/Table extended should match snapshot with CreatedBy 2`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -988,6 +956,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedAt 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -998,16 +967,6 @@ exports[`components/table/Table extended should match snapshot with UpdatedAt 1`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -1017,6 +976,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedAt 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1084,6 +1044,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedAt 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1094,16 +1055,6 @@ exports[`components/table/Table extended should match snapshot with UpdatedAt 1`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -1113,6 +1064,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedAt 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1392,6 +1344,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1402,16 +1355,6 @@ exports[`components/table/Table extended should match snapshot with UpdatedBy 1`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -1421,6 +1364,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1488,6 +1432,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1498,16 +1443,6 @@ exports[`components/table/Table extended should match snapshot with UpdatedBy 1`
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -1517,6 +1452,7 @@ exports[`components/table/Table extended should match snapshot with UpdatedBy 1`
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1772,6 +1708,7 @@ exports[`components/table/Table should match snapshot 1`] = `
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -1782,16 +1719,6 @@ exports[`components/table/Table should match snapshot 1`] = `
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -1801,6 +1728,7 @@ exports[`components/table/Table should match snapshot 1`] = `
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -2255,6 +2183,7 @@ exports[`components/table/Table should match snapshot, read-only 1`] = `
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -2274,6 +2203,7 @@ exports[`components/table/Table should match snapshot, read-only 1`] = `
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span

View File

@ -137,6 +137,7 @@ exports[`components/table/TableRow should match snapshot, display properties 1`]
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -147,16 +148,6 @@ exports[`components/table/TableRow should match snapshot, display properties 1`]
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -166,6 +157,7 @@ exports[`components/table/TableRow should match snapshot, display properties 1`]
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -319,6 +311,7 @@ exports[`components/table/TableRow should match snapshot, resizing column 1`] =
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span
@ -329,16 +322,6 @@ exports[`components/table/TableRow should match snapshot, resizing column 1`] =
>
value 1
</span>
<div
aria-label="Clear"
class="Button IconButton margin-left delete-value"
role="button"
title="Clear"
>
<i
class="CompassIcon icon-close CloseIcon"
/>
</div>
</span>
</div>
</div>
@ -348,6 +331,7 @@ exports[`components/table/TableRow should match snapshot, resizing column 1`] =
>
<div
class="octo-propertyvalue"
data-testid="select-non-editable"
tabindex="0"
>
<span

View File

@ -3,7 +3,7 @@
import {IntlProvider} from 'react-intl'
import React from 'react'
export const wrapIntl = (children: any) => <IntlProvider locale='en'>{children}</IntlProvider>
export const wrapIntl = (children?: React.ReactNode): JSX.Element => <IntlProvider locale='en'>{children}</IntlProvider>
export function mockDOM(): void {
window.focus = jest.fn()

View File

@ -2,6 +2,8 @@
display: inline-flex;
align-items: center;
padding: 2px 8px;
margin-right: 5px;
margin-bottom: 5px;
border-radius: 3px;
line-height: 20px;
color: rgba(var(--center-channel-color-rgb), 0.8);
@ -9,8 +11,6 @@
text-transform: uppercase;
font-weight: 600;
font-size: 13px;
margin-right: 5px;
margin-bottom: 5px;
input {
line-height: 20px;

View File

@ -10,7 +10,7 @@ type Props = {
color?: string
title?: string
children: React.ReactNode
classNames?: string
className?: string
}
// Switch is an on-off style switch / checkbox
@ -21,7 +21,7 @@ function Label(props: Props): JSX.Element {
}
return (
<span
className={`Label ${color} ${props.classNames ? props.classNames : ''}`}
className={`Label ${color} ${props.className ? props.className : ''}`}
title={props.title}
>
{props.children}

View File

@ -36,6 +36,10 @@
padding-bottom: 0;
}
.Label-no-margin {
margin: 0;
}
.Label-single-select {
margin-bottom: 0;
}

View File

@ -32,6 +32,7 @@ type Props = {
onDeleteOption: (option: IPropertyOption) => void
isMulti?: boolean
onDeleteValue?: (value: IPropertyOption) => void
onBlur?: () => void
}
type LabelProps = {
@ -40,22 +41,26 @@ type LabelProps = {
onChangeColor: (option: IPropertyOption, color: string) => void
onDeleteOption: (option: IPropertyOption) => void
onDeleteValue?: (value: IPropertyOption) => void
isMulti?: boolean
}
const ValueSelectorLabel = React.memo((props: LabelProps): JSX.Element => {
const {option, onDeleteValue, meta} = props
const {option, onDeleteValue, meta, isMulti} = props
const intl = useIntl()
if (meta.context === 'value') {
let className = onDeleteValue ? 'Label-no-padding' : 'Label-single-select'
if (!isMulti) {
className += ' Label-no-margin'
}
return (
<Label
color={option.color}
classNames={`${onDeleteValue ? 'Label-no-padding' : 'Label-single-select'}`}
className={className}
>
<span className='Label-text'>{option.value}</span>
{onDeleteValue &&
<IconButton
onClick={() => onDeleteValue(option)}
onMouseDown={(e) => e.stopPropagation()}
icon={<CloseIcon/>}
title='Clear'
className='margin-left delete-value'
@ -114,6 +119,12 @@ const valueSelectorStyle = {
padding: '0 8px',
overflow: 'unset',
}),
singleValue: (provided: CSSObject): CSSObject => ({
...provided,
position: 'static',
top: 'unset',
transform: 'unset',
}),
multiValue: (provided: CSSObject): CSSObject => ({
...provided,
margin: 0,
@ -151,6 +162,7 @@ function ValueSelector(props: Props): JSX.Element {
<ValueSelectorLabel
option={option}
meta={meta}
isMulti={props.isMulti}
onChangeColor={props.onChangeColor}
onDeleteOption={props.onDeleteOption}
onDeleteValue={props.onDeleteValue}
@ -171,6 +183,7 @@ function ValueSelector(props: Props): JSX.Element {
props.onChange('')
}
}}
onBlur={props.onBlur}
onCreateOption={props.onCreate}
autoFocus={true}
value={props.value}