Moving the label concept into its own component
This commit is contained in:
parent
1b285939f3
commit
d573f97fe6
11 changed files with 85 additions and 56 deletions
|
@ -35,6 +35,12 @@
|
|||
background-color: rgba(var(--body-color), 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.Label{
|
||||
.Editable {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import OptionsIcon from '../../widgets/icons/options'
|
|||
import Menu from '../../widgets/menu'
|
||||
import MenuWrapper from '../../widgets/menuWrapper'
|
||||
import Editable from '../../widgets/editable'
|
||||
import Label from '../../widgets/label'
|
||||
|
||||
type Props = {
|
||||
boardTree: BoardTree
|
||||
|
@ -72,8 +73,7 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
|
|||
}}
|
||||
>
|
||||
{!group.option.id &&
|
||||
<div
|
||||
className='octo-label'
|
||||
<Label
|
||||
title={intl.formatMessage({
|
||||
id: 'BoardComponent.no-property-title',
|
||||
defaultMessage: 'Items with an empty {property} property will go here. This column cannot be removed.',
|
||||
|
@ -86,24 +86,25 @@ export default function KanbanColumnHeader(props: Props): JSX.Element {
|
|||
property: boardTree.groupByProperty!.name,
|
||||
}}
|
||||
/>
|
||||
</div>}
|
||||
</Label>}
|
||||
{group.option.id &&
|
||||
<Editable
|
||||
className={`octo-label ${group.option.color}`}
|
||||
value={groupTitle}
|
||||
placeholderText='New Select'
|
||||
onChange={setGroupTitle}
|
||||
onSave={() => {
|
||||
if (groupTitle.trim() === '') {
|
||||
<Label color={group.option.color}>
|
||||
<Editable
|
||||
value={groupTitle}
|
||||
placeholderText='New Select'
|
||||
onChange={setGroupTitle}
|
||||
onSave={() => {
|
||||
if (groupTitle.trim() === '') {
|
||||
setGroupTitle(group.option.value)
|
||||
}
|
||||
props.propertyNameChanged(group.option, groupTitle)
|
||||
}}
|
||||
onCancel={() => {
|
||||
setGroupTitle(group.option.value)
|
||||
}
|
||||
props.propertyNameChanged(group.option, groupTitle)
|
||||
}}
|
||||
onCancel={() => {
|
||||
setGroupTitle(group.option.value)
|
||||
}}
|
||||
readonly={props.readonly}
|
||||
/>}
|
||||
}}
|
||||
readonly={props.readonly}
|
||||
/>
|
||||
</Label>}
|
||||
<Button>{`${group.cards.length}`}</Button>
|
||||
<div className='octo-spacer'/>
|
||||
{!props.readonly &&
|
||||
|
|
|
@ -11,6 +11,7 @@ import Button from '../../widgets/buttons/button'
|
|||
import Menu from '../../widgets/menu'
|
||||
import MenuWrapper from '../../widgets/menuWrapper'
|
||||
import ShowIcon from '../../widgets/icons/show'
|
||||
import Label from '../../widgets/label'
|
||||
|
||||
type Props = {
|
||||
boardTree: BoardTree
|
||||
|
@ -60,12 +61,12 @@ export default function KanbanHiddenColumnItem(props: Props): JSX.Element {
|
|||
<MenuWrapper
|
||||
disabled={props.readonly}
|
||||
>
|
||||
<div
|
||||
<Label
|
||||
key={group.option.id || 'empty'}
|
||||
className={`octo-label ${group.option.color}`}
|
||||
color={group.option.color}
|
||||
>
|
||||
{group.option.value}
|
||||
</div>
|
||||
</Label>
|
||||
<Menu>
|
||||
<Menu.Text
|
||||
id='show'
|
||||
|
|
|
@ -11,6 +11,7 @@ import {Utils} from '../utils'
|
|||
import {BoardTree} from '../viewModel/boardTree'
|
||||
import Editable from '../widgets/editable'
|
||||
import ValueSelector from '../widgets/valueSelector'
|
||||
import Label from '../widgets/label'
|
||||
|
||||
type Props = {
|
||||
boardTree?: BoardTree
|
||||
|
@ -35,18 +36,13 @@ const PropertyValueElement = (props:Props): JSX.Element => {
|
|||
propertyColorCssClassName = cardPropertyValue.color
|
||||
}
|
||||
|
||||
let className = 'octo-propertyvalue octo-label'
|
||||
if (!displayValue) {
|
||||
className += ' empty'
|
||||
}
|
||||
|
||||
if (readOnly || !boardTree) {
|
||||
return (
|
||||
<div
|
||||
className={`${className} ${propertyColorCssClassName}`}
|
||||
className='octo-property-value'
|
||||
tabIndex={0}
|
||||
>
|
||||
{finalDisplayValue}
|
||||
<Label color={displayValue ? propertyColorCssClassName : 'empty'}>{finalDisplayValue}</Label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.octo-label {
|
||||
.Label {
|
||||
color: rgba(var(--body-color), 0.6);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import {BoardTree} from '../../viewModel/boardTree'
|
|||
import SortDownIcon from '../../widgets/icons/sortDown'
|
||||
import SortUpIcon from '../../widgets/icons/sortUp'
|
||||
import MenuWrapper from '../../widgets/menuWrapper'
|
||||
import Label from '../../widgets/label'
|
||||
|
||||
import {HorizontalGrip} from '../horizontalGrip'
|
||||
|
||||
|
@ -69,15 +70,13 @@ class Table extends React.Component<Props, State> {
|
|||
style={{overflow: 'unset', width: this.columnWidth(Constants.titleColumnId)}}
|
||||
>
|
||||
<MenuWrapper disabled={this.props.readonly}>
|
||||
<div
|
||||
className='octo-label'
|
||||
>
|
||||
<Label>
|
||||
<FormattedMessage
|
||||
id='TableComponent.name'
|
||||
defaultMessage='Name'
|
||||
/>
|
||||
{titleSortIcon}
|
||||
</div>
|
||||
</Label>
|
||||
<TableHeaderMenu
|
||||
boardTree={boardTree}
|
||||
templateId={Constants.titleColumnId}
|
||||
|
@ -157,7 +156,6 @@ class Table extends React.Component<Props, State> {
|
|||
disabled={this.props.readonly}
|
||||
>
|
||||
<div
|
||||
className='octo-label'
|
||||
draggable={!this.props.readonly}
|
||||
onDragStart={() => {
|
||||
this.draggedHeaderTemplate = template
|
||||
|
@ -166,8 +164,10 @@ class Table extends React.Component<Props, State> {
|
|||
this.draggedHeaderTemplate = undefined
|
||||
}}
|
||||
>
|
||||
{template.name}
|
||||
{sortIcon}
|
||||
<Label>
|
||||
{template.name}
|
||||
{sortIcon}
|
||||
</Label>
|
||||
</div>
|
||||
<TableHeaderMenu
|
||||
boardTree={boardTree}
|
||||
|
|
|
@ -128,19 +128,6 @@ button {
|
|||
background-color: rgba(128, 192, 255, 0.4);
|
||||
}
|
||||
|
||||
.octo-label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 8px;
|
||||
border-radius: 3px;
|
||||
line-height: 20px;
|
||||
color: rgba(var(--body-color), .8);
|
||||
white-space: nowrap;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.octo-spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
|
12
webapp/src/widgets/label.scss
Normal file
12
webapp/src/widgets/label.scss
Normal file
|
@ -0,0 +1,12 @@
|
|||
.Label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 8px;
|
||||
border-radius: 3px;
|
||||
line-height: 20px;
|
||||
color: rgba(var(--body-color), .8);
|
||||
white-space: nowrap;
|
||||
text-transform: uppercase;
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
}
|
25
webapp/src/widgets/label.tsx
Normal file
25
webapp/src/widgets/label.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React from 'react'
|
||||
|
||||
import './label.scss'
|
||||
|
||||
type Props = {
|
||||
color?: string
|
||||
title?: string
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
// Switch is an on-off style switch / checkbox
|
||||
function Label(props: Props): JSX.Element {
|
||||
return (
|
||||
<span
|
||||
className={`Label ${props.color || 'empty'}`}
|
||||
title={props.title}
|
||||
>
|
||||
{props.children}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(Label)
|
|
@ -7,7 +7,7 @@
|
|||
background-color: rgba(var(--body-color), 0.1),
|
||||
}
|
||||
|
||||
> .octo-label {
|
||||
> .Label {
|
||||
margin: 0 10px;
|
||||
&.empty {
|
||||
color: rgba(var(--body-color), 0.6);
|
||||
|
@ -17,7 +17,7 @@
|
|||
.value-menu-option {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
.octo-label-container {
|
||||
.label-container {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.MenuWrapper {
|
||||
|
|
|
@ -14,6 +14,7 @@ import MenuWrapper from './menuWrapper'
|
|||
import IconButton from './buttons/iconButton'
|
||||
import OptionsIcon from './icons/options'
|
||||
import DeleteIcon from './icons/delete'
|
||||
import Label from './label'
|
||||
|
||||
import './valueSelector.scss'
|
||||
|
||||
|
@ -39,12 +40,12 @@ type LabelProps = {
|
|||
const ValueSelectorLabel = React.memo((props: LabelProps): JSX.Element => {
|
||||
const {option, meta} = props
|
||||
if (meta.context === 'value') {
|
||||
return <span className={`octo-label ${option.color}`} >{option.value}</span>
|
||||
return <Label color={option.color}>{option.value}</Label>
|
||||
}
|
||||
return (
|
||||
<div className='value-menu-option'>
|
||||
<div className='octo-label-container'>
|
||||
<div className={`octo-label ${option.color}`}>{option.value}</div>
|
||||
<div className='label-container'>
|
||||
<Label color={option.color}>{option.value}</Label>
|
||||
</div>
|
||||
<MenuWrapper stopPropagationOnToggle={true}>
|
||||
<IconButton icon={<OptionsIcon/>}/>
|
||||
|
@ -79,9 +80,9 @@ function ValueSelector(props: Props): JSX.Element {
|
|||
className='ValueSelector'
|
||||
onClick={() => setActivated(true)}
|
||||
>
|
||||
<span className={`octo-label ${props.value ? props.value.color : 'empty'}`}>
|
||||
<Label color={props.value ? props.value.color : 'empty'}>
|
||||
{props.value ? props.value.value : props.emptyValue}
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue