UBER-206: Redefined color palettes (#3243)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev
2023-05-24 22:53:06 +06:00
committed by GitHub
parent df5fc73eeb
commit 3776137a52
81 changed files with 897 additions and 578 deletions
@@ -29,13 +29,12 @@
import { createQuery, getClient, statusStore, ActionContext } from '@hcengineering/presentation'
import { Kanban, SpaceWithStates, Task, TaskGrouping, TaskOrdering } from '@hcengineering/task'
import {
ColorDefinition,
defaultBackground,
getEventPositionElement,
Label,
showPopup,
deviceOptionsStore as deviceInfo,
hslToRgb,
rgbToHsl,
AccentColor
themeStore
} from '@hcengineering/ui'
import {
AttributeModel,
@@ -81,8 +80,11 @@
$: dontUpdateRank = orderBy[0] !== TaskOrdering.Manual
$: lth = $deviceInfo.theme === 'theme-light'
const accentColors: AccentColor[] = []
let accentColors: Map<string, ColorDefinition> = new Map()
const setAccentColor = (n: number, ev: CustomEvent<ColorDefinition>) => {
accentColors.set(`${n}${$themeStore.dark}${groupByKey}`, ev.detail)
accentColors = accentColors
}
const spaceQuery = createQuery()
@@ -170,14 +172,6 @@
viewOptionsModel: ViewOptionModel[] | undefined
) {
categories = await getCategories(client, _class, docs, groupByKey, $statusStore, viewlet.descriptor)
categories.forEach((_, i) => {
if (accentColors[i] === undefined) {
accentColors[i] = {
textColor: 'var(--theme-caption-color)',
backgroundColor: lth ? '230, 230, 230' : '100, 100, 108'
}
}
})
for (const viewOption of viewOptionsModel ?? []) {
if (viewOption.actionTarget !== 'category') continue
const categoryFunc = viewOption as CategoryOption
@@ -244,16 +238,6 @@
})
const getDoneUpdate = (e: any) => ({ doneState: e.detail._id } as DocumentUpdate<Doc>)
const setAccentColor = (n: number, ev: CustomEvent) => {
const accColor = rgbToHsl(ev.detail.r, ev.detail.g, ev.detail.b)
const textColor = !lth ? { r: 255, g: 255, b: 255 } : hslToRgb(accColor.h, accColor.s, 0.3)
const bgColor = !lth ? hslToRgb(accColor.h, accColor.s, 0.55) : hslToRgb(accColor.h, accColor.s, 0.9)
accentColors[n] = {
textColor: !lth ? 'var(--theme-caption-color)' : `rgb(${textColor.r}, ${textColor.g}, ${textColor.b})`,
backgroundColor: `${bgColor.r}, ${bgColor.g}, ${bgColor.b}`
}
}
</script>
{#await cardPresenter then presenter}
@@ -283,37 +267,33 @@
on:contextmenu={(evt) => showMenu(evt.detail.evt, evt.detail.objects)}
>
<svelte:fragment slot="header" let:state let:count let:index>
<!-- {@const status = $statusStore.get(state._id)} -->
{#key lth}
<div
style:--kanban-header-rgb-color={accentColors[index]?.backgroundColor}
class="header flex-row-center"
class:gradient={!lth}
{@const color = accentColors.get(`${index}${$themeStore.dark}${groupByKey}`)}
{@const headerBGColor = color?.background ?? defaultBackground($themeStore.dark)}
<div style:background={headerBGColor} class="header flex-row-center">
<span
class="clear-mins fs-bold overflow-label pointer-events-none"
style:color={color?.title ?? 'var(--theme-caption-color)'}
>
<span
class="clear-mins fs-bold overflow-label pointer-events-none"
style:color={accentColors[index]?.textColor}
>
{#if groupByKey === noCategory}
<Label label={view.string.NoGrouping} />
{:else if headerComponent}
<svelte:component
this={headerComponent.presenter}
value={state}
{space}
size={'small'}
kind={'list-header'}
colorInherit={lth}
accent
on:accent-color={(ev) => setAccentColor(index, ev)}
/>
{/if}
</span>
<span class="counter ml-1">
{count}
</span>
</div>
{/key}
{#if groupByKey === noCategory}
<Label label={view.string.NoGrouping} />
{:else if headerComponent}
<svelte:component
this={headerComponent.presenter}
value={state}
{space}
size={'small'}
kind={'list-header'}
colorInherit={!$themeStore.dark}
accent
on:accent-color={(ev) => setAccentColor(index, ev)}
/>
{/if}
</span>
<span class="counter ml-1">
{count}
</span>
</div>
</svelte:fragment>
<svelte:fragment slot="card" let:object let:dragged>
<svelte:component this={presenter} {object} {dragged} {groupByKey} />
@@ -340,17 +320,6 @@
border: 1px solid var(--theme-divider-color);
border-radius: 0.25rem;
&:not(.gradient) {
background: rgba(var(--kanban-header-rgb-color), 1);
}
&.gradient {
background: linear-gradient(
90deg,
rgba(var(--kanban-header-rgb-color), 0.15),
rgba(var(--kanban-header-rgb-color), 0.05)
);
}
.counter {
color: var(--theme-dark-color);
}
@@ -16,19 +16,22 @@
<script lang="ts">
import type { DoneState } from '@hcengineering/task'
import task from '@hcengineering/task'
import { getPlatformColor } from '@hcengineering/ui'
import Won from '../icons/Won.svelte'
import { PaletteColorIndexes, getPlatformColorDef, themeStore } from '@hcengineering/ui'
import Lost from '../icons/Lost.svelte'
import Won from '../icons/Won.svelte'
export let value: DoneState | null | undefined
export let showTitle: boolean = true
$: color = value?._class === task.class.WonState ? getPlatformColor(0) : getPlatformColor(11)
$: color =
value?._class === task.class.WonState
? getPlatformColorDef(PaletteColorIndexes.Crocodile, $themeStore.dark)
: getPlatformColorDef(PaletteColorIndexes.Firework, $themeStore.dark)
</script>
{#if value}
<div class="flex-center">
<div class:mr-2={showTitle} style="color: {color};">
<div class:mr-2={showTitle} style="color: {color.color};">
<svelte:component this={value._class === task.class.WonState ? Won : Lost} size={'small'} />
</div>
{#if showTitle}
@@ -18,12 +18,18 @@
import { statusStore } from '@hcengineering/presentation'
import type { DoneState } from '@hcengineering/task'
import DoneStatePresenter from './DoneStatePresenter.svelte'
import DoneStateEditor from './DoneStateEditor.svelte'
export let value: Ref<DoneState> | StatusValue
export let showTitle: boolean = true
export let onChange: ((value: Ref<DoneState>) => void) | undefined = undefined
</script>
{#if value}
{@const state = $statusStore.get(typeof value === 'string' ? value : value.values[0]._id)}
<DoneStatePresenter value={state} {showTitle} />
{#if onChange !== undefined && state !== undefined}
<DoneStateEditor value={state._id} space={state.space} {onChange} kind="link" size="medium" />
{:else}
<DoneStatePresenter value={state} {showTitle} />
{/if}
{/if}
@@ -17,12 +17,12 @@
import { Class, Doc, Ref, SortingOrder } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { DoneState, SpaceWithStates } from '@hcengineering/task'
import { getPlatformColor, Label, resizeObserver } from '@hcengineering/ui'
import { Label, PaletteColorIndexes, getPlatformColor, resizeObserver, themeStore } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import task from '../../plugin'
import Won from '../icons/Won.svelte'
import Lost from '../icons/Lost.svelte'
import Unknown from '../icons/Unknown.svelte'
import Won from '../icons/Won.svelte'
export let space: Ref<SpaceWithStates>
let states: DoneState[] = []
@@ -42,7 +42,9 @@
}
)
function getColor (_class: Ref<Class<Doc>>): string {
return _class === task.class.WonState ? getPlatformColor(0) : getPlatformColor(11)
return _class === task.class.WonState
? getPlatformColor(PaletteColorIndexes.Crocodile, $themeStore.dark)
: getPlatformColor(PaletteColorIndexes.Firework, $themeStore.dark)
}
</script>
@@ -14,9 +14,15 @@
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher, onMount } from 'svelte'
import type { State } from '@hcengineering/task'
import { getColorNumberByText, getPlatformColor, hexToRgb, deviceOptionsStore as deviceInfo } from '@hcengineering/ui'
import {
ColorDefinition,
defaultBackground,
getColorNumberByText,
getPlatformColorDef,
themeStore
} from '@hcengineering/ui'
import { createEventDispatcher, onMount } from 'svelte'
export let value: State | undefined
export let shouldShowAvatar = true
@@ -28,25 +34,24 @@
const dispatch = createEventDispatcher()
const defaultFill = 'currentColor'
$: fill = value ? getPlatformColor(value.color ?? getColorNumberByText(value.name)) : defaultFill
$: lth = $deviceInfo.theme === 'theme-light'
const dispatchAccentColor = (fill: string) =>
dispatch(
'accent-color',
fill !== defaultFill ? hexToRgb(fill) : lth ? { r: 220, g: 220, b: 220 } : { r: 100, g: 100, b: 108 }
)
$: dispatchAccentColor(fill)
$: color = value ? getPlatformColorDef(value.color ?? getColorNumberByText(value.name), $themeStore.dark) : undefined
const dispatchAccentColor = (color?: ColorDefinition) => dispatch('accent-color', color)
$: dispatchAccentColor(color)
onMount(() => {
dispatchAccentColor(fill)
dispatchAccentColor(color)
})
</script>
{#if value}
<div class="flex-presenter" class:inline-presenter={inline}>
{#if shouldShowAvatar}
<div class="state-container" class:inline style="background-color: {fill}" />
<div
class="state-container"
class:inline
style="background-color: {color?.color ?? defaultBackground($themeStore.dark)}"
/>
{/if}
<span class="overflow-label label" class:nowrap={oneLine} class:no-underline={disabled}>{value.name}</span>
</div>
@@ -17,7 +17,7 @@
import { Ref } from '@hcengineering/core'
import { BreadcrumbsElement, statusStore } from '@hcengineering/presentation'
import task, { SpaceWithStates, State } from '@hcengineering/task'
import { getColorNumberByText, getPlatformColor, ScrollerBar } from '@hcengineering/ui'
import { ScrollerBar, getColorNumberByText, getPlatformColor, themeStore } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import type { StatesBarPosition } from '../..'
@@ -60,7 +60,7 @@
label={item.name}
position={getPosition(i)}
selected={item._id === state}
color={getPlatformColor(item.color ?? getColorNumberByText(item.name))}
color={getPlatformColor(item.color ?? getColorNumberByText(item.name), $themeStore.dark)}
on:click={(ev) => {
ev.stopPropagation()
if (item._id !== state) selectItem(ev, item)
@@ -19,22 +19,25 @@
import type { DoneState, KanbanTemplate, KanbanTemplateSpace, State } from '@hcengineering/task'
import {
CircleButton,
Component,
IconAdd,
IconCircles,
IconMoreH,
Label,
showPopup,
getPlatformColor,
PaletteColorIndexes,
defaultBackground,
eventToHTMLElement,
Component,
IconCircles,
getColorNumberByText
getColorNumberByText,
getPlatformColorDef,
showPopup,
themeStore
} from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import { ColorsPopup } from '@hcengineering/view-resources'
import StatusesPopup from './StatusesPopup.svelte'
import { createEventDispatcher } from 'svelte'
import task from '../../plugin'
import Won from '../icons/Won.svelte'
import Lost from '../icons/Lost.svelte'
import Won from '../icons/Won.svelte'
import StatusesPopup from './StatusesPopup.svelte'
export let template: KanbanTemplate | undefined = undefined
export let space: KanbanTemplateSpace | undefined = undefined
@@ -77,7 +80,7 @@
const onColorChange =
(state: State) =>
async (color: number | undefined): Promise<void> => {
if (color === undefined) {
if (color == null) {
return
}
@@ -104,10 +107,12 @@
</div>
<div class="mt-3">
{#each states as state, i}
{@const color = getPlatformColorDef(state.color ?? getColorNumberByText(state.name), $themeStore.dark)}
{#if state}
<div
bind:this={elements[i]}
class="flex-between states"
style:background={color.background ?? defaultBackground($themeStore.dark)}
draggable={true}
on:dragover|preventDefault={(ev) => {
dragover(ev, i)
@@ -127,14 +132,9 @@
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="color"
style="background-color: {getPlatformColor(state.color ?? getColorNumberByText(state.name))}"
style:background-color={color.color}
on:click={() => {
showPopup(
ColorsPopup,
{ selected: getPlatformColor(state.color ?? getColorNumberByText(state.name)) },
elements[i],
onColorChange(state)
)
showPopup(ColorsPopup, { selected: color.name }, elements[i], onColorChange(state))
}}
/>
<div class="flex-grow caption-color">
@@ -173,8 +173,13 @@
</div>
<div class="mt-4">
{#each wonStates as state}
{@const color = getPlatformColorDef(PaletteColorIndexes.Crocodile, $themeStore.dark)}
{#if state}
<div class="states flex-row-center">
<div
class="states flex-row-center"
style:color={color.title}
style:background={color.background ?? defaultBackground($themeStore.dark)}
>
<div class="bar" />
<div class="mr-2">
<Won size={'medium'} />
@@ -216,8 +221,13 @@
</div>
<div class="mt-4 mb-10">
{#each lostStates as state}
{@const color = getPlatformColorDef(PaletteColorIndexes.Firework, $themeStore.dark)}
{#if state}
<div class="states flex-row-center">
<div
class="states flex-row-center"
style:color={color.title}
style:background={color.background ?? defaultBackground($themeStore.dark)}
>
<div class="bar" />
<div class="mr-2">
<Lost size={'medium'} />
@@ -17,7 +17,7 @@
import { Ref, SortingOrder } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import task, { SpaceWithStates, State } from '@hcengineering/task'
import { getColorNumberByText, getPlatformColor, resizeObserver } from '@hcengineering/ui'
import { getColorNumberByText, getPlatformColorDef, resizeObserver, themeStore } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
export let space: Ref<SpaceWithStates>
@@ -42,16 +42,14 @@
<div class="scroll">
<div class="box">
{#each states as state}
{@const color = getPlatformColorDef(state.color ?? getColorNumberByText(state.name), $themeStore.dark)}
<button
class="menu-item"
on:click={() => {
dispatch('close', state)
}}
>
<div
class="color"
style="background-color: {getPlatformColor(state.color ?? getColorNumberByText(state.name))}"
/>
<div class="color" style:background-color={color.color} />
<span class="label">{state.name}</span>
</button>
{/each}
@@ -29,6 +29,7 @@
</script>
{#if value}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="flex-presenter" class:inline-presenter={inline} on:click={(ev) => show(ev.target)}>
<div class="icon">
<Icon icon={task.icon.Task} size={'small'} />
@@ -14,11 +14,11 @@
// limitations under the License.
-->
<script lang="ts">
import { getPlatformColor, Label } from '@hcengineering/ui'
import { getPlatformColor, Label, themeStore } from '@hcengineering/ui'
import task from '../../plugin'
export let value: boolean
$: color = value ? getPlatformColor(2) : getPlatformColor(10)
$: color = value ? getPlatformColor(2, $themeStore.dark) : getPlatformColor(16, $themeStore.dark)
$: text = value ? task.string.DoneState : task.string.UndoneState
</script>