TSK-1324: update popups and colors (#3152)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2023-05-10 14:40:50 +03:00 committed by GitHub
parent d486dea298
commit 93268d4dbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 293 additions and 223 deletions

View File

@ -241,29 +241,17 @@
}} }}
> >
{#if (allowDeselect && selected) || multiSelect || selected} {#if (allowDeselect && selected) || multiSelect || selected}
<div class="icon" class:disabled={readonly}> <div class="check" class:disabled={readonly}>
{#if obj._id === selected || selectedElements.has(obj._id)} {#if obj._id === selected || selectedElements.has(obj._id)}
<div bind:this={selectedDiv}> <div bind:this={selectedDiv} use:tooltip={{ label: titleDeselect ?? presentation.string.Deselect }}>
{#if titleDeselect}
<div class="clear-mins" use:tooltip={{ label: titleDeselect ?? presentation.string.Deselect }}>
<Icon icon={IconCheck} {size} /> <Icon icon={IconCheck} {size} />
</div> </div>
{:else}
<Icon icon={IconCheck} {size} />
{/if}
</div>
{/if} {/if}
</div> </div>
{/if} {/if}
<span class="label" class:disabled={readonly || isDeselectDisabled}> <span class="label" class:disabled={readonly || isDeselectDisabled}>
{#if obj._id === selected}
<div bind:this={selectedDiv}>
<slot name="item" item={obj} /> <slot name="item" item={obj} />
</div>
{:else}
<slot name="item" item={obj} />
{/if}
</span> </span>
</button> </button>
</svelte:fragment> </svelte:fragment>
@ -283,8 +271,4 @@
border-radius: 0.25rem; border-radius: 0.25rem;
box-shadow: none; box-shadow: none;
} }
.whereSelected {
height: 2px;
background-color: var(--theme-caret-color);
}
</style> </style>

View File

@ -23,11 +23,11 @@
export let size: IconSize export let size: IconSize
</script> </script>
<div class="flex-row-center"> <div class="flex-presenter">
<div class="flex-center caption-color flex-no-shrink"><IconFolder {size} /></div> <div class="icon medium-gap"><IconFolder {size} /></div>
<div class="flex-col ml-2 min-w-0"> <div class="flex-col">
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if} {#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
<div class="caption-color overflow-label"> <div class="label no-underline nowrap">
{value.name} {value.name}
{#if value.archived} {#if value.archived}
<Label label={presentation.string.Archived} /> <Label label={presentation.string.Archived} />
@ -35,14 +35,3 @@
</div> </div>
</div> </div>
</div> </div>
<style lang="scss">
.medium {
width: 1.75rem;
height: 1.75rem;
}
.large {
width: 2.25rem;
height: 2.25rem;
}
</style>

View File

@ -123,6 +123,7 @@
--theme-popup-color: #292938; --theme-popup-color: #292938;
--theme-popup-hover: #32323F; --theme-popup-hover: #32323F;
--theme-popup-divider: rgba(255, 255, 255, .1); --theme-popup-divider: rgba(255, 255, 255, .1);
--theme-popup-header: #3A3A47;
--theme-popup-shadow: 0px 4px 4px rgba(0, 0, 0, 0.1); // Light --theme-popup-shadow: 0px 4px 4px rgba(0, 0, 0, 0.1); // Light
--theme-panel-color: #1A1A28; --theme-panel-color: #1A1A28;
--theme-calendar-today-color: #fff; --theme-calendar-today-color: #fff;
@ -133,6 +134,7 @@
--theme-calendar-weekend-bgcolor: rgba(242, 153, 74, .05); --theme-calendar-weekend-bgcolor: rgba(242, 153, 74, .05);
--theme-error-color: #eb5757; --theme-error-color: #eb5757;
--theme-warning-color: #f2994a;
--theme-lost-color: #eb5757; --theme-lost-color: #eb5757;
--theme-won-color: #34DB80; --theme-won-color: #34DB80;
--theme-caret-color: #6e5ed2; --theme-caret-color: #6e5ed2;
@ -161,7 +163,6 @@
--accent-color: #d7d8db; --accent-color: #d7d8db;
--caption-color: #f7f8f8; --caption-color: #f7f8f8;
--white-color: #fff; --white-color: #fff;
--warning-color: #f2994a;
--divider-color: #303236; --divider-color: #303236;
--divider-trans-color: rgba(255, 255, 255, .12); --divider-trans-color: rgba(255, 255, 255, .12);
@ -284,6 +285,7 @@
--theme-popup-color: #FFFFFF; --theme-popup-color: #FFFFFF;
--theme-popup-hover: #F5F5F5; --theme-popup-hover: #F5F5F5;
--theme-popup-divider: rgba(0, 0, 0, .1); --theme-popup-divider: rgba(0, 0, 0, .1);
--theme-popup-header: #EBEBEB;
--theme-popup-shadow: 0px 4px 4px rgba(0, 0, 0, 0.1); --theme-popup-shadow: 0px 4px 4px rgba(0, 0, 0, 0.1);
--theme-panel-color: #FFFFFF; --theme-panel-color: #FFFFFF;
--theme-calendar-today-color: #000; --theme-calendar-today-color: #000;
@ -294,6 +296,7 @@
--theme-calendar-weekend-bgcolor: rgba(242, 153, 74, .1); --theme-calendar-weekend-bgcolor: rgba(242, 153, 74, .1);
--theme-error-color: #eb5757; // Dark --theme-error-color: #eb5757; // Dark
--theme-warning-color: #f2994a; // Dark
--theme-lost-color: #eb5757; // Dark --theme-lost-color: #eb5757; // Dark
--theme-won-color: #34DB80; // Dark --theme-won-color: #34DB80; // Dark
--theme-caret-color: #6e5ed2; --theme-caret-color: #6e5ed2;
@ -322,7 +325,6 @@
--theme-accent-color: rgba(0, 0, 0, .8); --theme-accent-color: rgba(0, 0, 0, .8);
--caption-color: #131416; --caption-color: #131416;
--white-color: #fff; --white-color: #fff;
--warning-color: #f2994a; // Dark
--divider-color: #e0e0e0; --divider-color: #e0e0e0;
--divider-trans-color: rgba(0, 0, 0, .12); --divider-trans-color: rgba(0, 0, 0, .12);

View File

@ -268,21 +268,22 @@ input.search {
cursor: pointer; cursor: pointer;
.icon { .icon {
color: var(--dark-color); color: var(--theme-dark-color);
&.circle { &.circle {
padding: .25rem; padding: .25rem;
background-color: var(--avatar-bg-color); background-color: var(--avatar-bg-color);
border-radius: 50%; border-radius: 50%;
} }
&:not(.small-gap) { margin-right: .5rem; } &:not(.small-gap, .medium-gap) { margin-right: .5rem; }
&.small-gap { margin-right: .25rem; } &.small-gap { margin-right: .25rem; }
&.medium-gap { margin-right: .375rem; }
} }
.label { .label {
min-width: 0; min-width: 0;
font-weight: 500; font-weight: 500;
text-align: left; text-align: left;
color: var(--accent-color); color: var(--theme-content-color);
overflow: hidden; overflow: hidden;
visibility: visible; visibility: visible;
@ -306,19 +307,19 @@ input.search {
margin-left: .75rem; margin-left: .75rem;
} }
&:hover { &:hover {
.icon { color: var(--caption-color); } .icon { color: var(--theme-caption-color); }
.label { .label {
color: var(--caption-color); color: var(--theme-caption-color);
&:not(.no-underline) { text-decoration: underline; } &:not(.no-underline) { text-decoration: underline; }
} }
.action { visibility: visible; } .action { visibility: visible; }
} }
&.not-selected { &.not-selected {
.label { color: var(--content-color); } .label { color: var(--theme-dark-color); }
&:hover .label, &:hover .label,
&:hover .icon { &:hover .icon {
color: var(--accent-color); color: var(--theme-content-color);
} }
} }
} }
@ -721,6 +722,7 @@ a.no-line {
} }
.cursor-pointer { cursor: pointer; } .cursor-pointer { cursor: pointer; }
.cursor-default { cursor: default; } .cursor-default { cursor: default; }
.cursor-inherit { cursor: inherit; }
.pointer-events-none { pointer-events: none; } .pointer-events-none { pointer-events: none; }
.select-text { user-select: text; } .select-text { user-select: text; }
@ -844,6 +846,15 @@ a.no-line {
} }
/* Backgrounds & Colors */ /* Backgrounds & Colors */
.dark-hover-content-color {
color: var(--theme-dark-color);
&:hover { color: var(--theme-content-color); }
}
.content-hover-caption-color {
color: var(--theme-content-color);
&:hover { color: var(--theme-caption-color); }
}
.background-body-color { background-color: var(--body-color); } .background-body-color { background-color: var(--body-color); }
.background-accent-bg-color { background-color: var(--accent-bg-color); } .background-accent-bg-color { background-color: var(--accent-bg-color); }
.background-highlight-select { background-color: var(--highlight-select); } .background-highlight-select { background-color: var(--highlight-select); }

View File

@ -117,7 +117,7 @@
.icon { .icon {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
color: var(--theme-caret-color); color: var(--theme-dark-color);
} }
.color { .color {
width: .875rem; width: .875rem;
@ -138,20 +138,25 @@
overflow: hidden; overflow: hidden;
} }
.check { .check {
display: flex; flex-shrink: 0;
align-items: center; width: 1rem;
margin-right: .75rem; height: 1rem;
margin-right: .375rem;
color: var(--theme-caret-color);
} }
.check-right { margin: 0 0 0 2rem; } .check-right { margin: 0 0 0 2rem; }
&:not(.withList):focus, &:not(.withList, .no-focus):focus,
&:not(.withList):hover { &:not(.withList):hover {
color: var(--theme-caption-color);
background-color: var(--theme-popup-hover); background-color: var(--theme-popup-hover);
}
&:not(.withList, .no-focus):focus,
&:not(.withList):hover,
&.selected,
&:hover {
color: var(--theme-caption-color);
.icon { color: var(--theme-content-color); } .icon { color: var(--theme-content-color); }
} }
&.no-focus:not(.withList):focus { background-color: var(--theme-popup-hover); }
&.no-focus:not(.withList):hover { background-color: var(--theme-popup-hover); }
} }
.sticky-wrapper { .sticky-wrapper {
display: flex; display: flex;
@ -173,13 +178,13 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: .125rem .25rem; padding: .375rem .25rem;
min-height: 1.5rem; min-height: 1.5rem;
font-weight: 500; font-weight: 500;
font-size: .75rem; font-size: .75rem;
text-align: left; text-align: left;
color: var(--theme-content-color); color: var(--theme-content-color);
background-color: var(--theme-comp-header-color); background-color: var(--theme-popup-header);
cursor: pointer; cursor: pointer;
.icon { .icon {
@ -193,6 +198,10 @@
&.show + .menu-group { height: auto; } &.show + .menu-group { height: auto; }
} }
} }
.whereSelected {
height: 2px;
background-color: var(--theme-caret-color);
}
} }
.antiPopup { .antiPopup {
@ -386,14 +395,18 @@
align-items: center; align-items: center;
flex-shrink: 0; flex-shrink: 0;
justify-content: flex-start; justify-content: flex-start;
padding: .25rem .75rem; padding: .25rem .5rem;
min-width: 0; min-width: 0;
min-height: 2rem; min-height: 2rem;
text-align: left; text-align: left;
color: var(--theme-content-color); color: var(--theme-content-color);
outline: none;
cursor: pointer; cursor: pointer;
.icon { color: var(--theme-dark-color); } .icon {
margin-right: .375rem;
color: var(--theme-dark-color);
}
&:focus .icon, &:focus .icon,
&.withHover:hover .icon, &.withHover:hover .icon,
&.withIconHover:hover .icon { color: var(--theme-caption-color); } &.withIconHover:hover .icon { color: var(--theme-caption-color); }
@ -450,6 +463,7 @@
.notifyPopup .content .mention { margin-top: 0 !important; } .notifyPopup .content .mention { margin-top: 0 !important; }
.helpAndSupportPopup { .helpAndSupportPopup {
height: 100%;
min-height: 100%; min-height: 100%;
min-width: 20rem; min-width: 20rem;
} }

View File

@ -48,34 +48,33 @@
cursor: pointer; cursor: pointer;
.icon { .icon {
color: var(--dark-color); color: var(--theme-halfcontent-color);
&.invisible { &.invisible {
opacity: 0; opacity: 0;
} }
} }
&:hover .icon { &:hover .icon {
color: var(--accent-color); color: var(--theme-caption-color);
opacity: 1; opacity: 1;
} }
&:focus-visible { &:focus-visible {
border: 1px solid var(--primary-button-focused-border); box-shadow: 0 0 0 2px var(--primary-button-focused-border);
box-shadow: 0 0 0 3px var(--primary-button-outline);
.icon { .icon {
color: var(--caption-color); color: var(--theme-caption-color);
opacity: 1; opacity: 1;
} }
} }
} }
.small { .small {
width: 1.143em; width: 1rem;
height: 1.143em; height: 1rem;
} }
.medium { .medium {
width: 1.429em; width: 1.25rem;
height: 1.429em; height: 1.25rem;
} }
.large { .large {
width: 1.715em; width: 1.5rem;
height: 1.715em; height: 1.5rem;
} }
</style> </style>

View File

@ -234,6 +234,9 @@
border-top-right-radius: 0.25rem; border-top-right-radius: 0.25rem;
border-bottom-right-radius: 0.25rem; border-bottom-right-radius: 0.25rem;
} }
&.sh-filter {
border-radius: 0 0 0.5rem 0.5rem;
}
&.bs-solid { &.bs-solid {
border-style: solid; border-style: solid;
} }
@ -254,8 +257,13 @@
} }
} }
&:focus { &:focus {
&:not(.sh-filter) {
box-shadow: 0 0 0 2px var(--primary-button-focused-border); box-shadow: 0 0 0 2px var(--primary-button-focused-border);
} }
&.sh-filter {
border-color: var(--primary-button-focused-border);
}
}
&:disabled { &:disabled {
color: var(--theme-dark-color); color: var(--theme-dark-color);
cursor: not-allowed; cursor: not-allowed;

View File

@ -19,10 +19,13 @@
import { deviceOptionsStore, resizeObserver } from '..' import { deviceOptionsStore, resizeObserver } from '..'
import { getPlatformColor } from '../colors' import { getPlatformColor } from '../colors'
import ListView from './ListView.svelte' import ListView from './ListView.svelte'
import Icon from './Icon.svelte'
import IconCheck from './icons/Check.svelte'
export let placeholder: IntlString | undefined = undefined export let placeholder: IntlString | undefined = undefined
export let placeholderParam: any | undefined = undefined export let placeholderParam: any | undefined = undefined
export let searchable: boolean = false export let searchable: boolean = false
export let selected: number | string | undefined = undefined
export let value: Array<{ id: number | string; color: number; label: string }> export let value: Array<{ id: number | string; color: number; label: string }>
let search: string = '' let search: string = ''
@ -92,11 +95,16 @@
<svelte:fragment slot="item" let:item> <svelte:fragment slot="item" let:item>
{@const itemValue = objects[item]} {@const itemValue = objects[item]}
<button <button
class="menu-item w-full" class="menu-item withList w-full"
on:click={() => { on:click={() => {
dispatch('close', itemValue) dispatch('close', itemValue)
}} }}
> >
<div class="check">
{#if itemValue.id === selected}
<Icon icon={IconCheck} size={'small'} />
{/if}
</div>
<div class="color" style="background-color: {getPlatformColor(itemValue.color)}" /> <div class="color" style="background-color: {getPlatformColor(itemValue.color)}" />
<span class="label">{itemValue.label}</span> <span class="label">{itemValue.label}</span>
</button> </button>

View File

@ -19,8 +19,9 @@
import { deviceOptionsStore, resizeObserver } from '..' import { deviceOptionsStore, resizeObserver } from '..'
import plugin from '../plugin' import plugin from '../plugin'
import type { DropdownTextItem } from '../types' import type { DropdownTextItem } from '../types'
import CheckBox from './CheckBox.svelte' import IconCheck from './icons/Check.svelte'
import ListView from './ListView.svelte' import ListView from './ListView.svelte'
import Icon from './Icon.svelte'
export let placeholder: IntlString = plugin.string.SearchDots export let placeholder: IntlString = plugin.string.SearchDots
export let items: DropdownTextItem[] export let items: DropdownTextItem[]
@ -130,10 +131,12 @@
} }
}} }}
> >
<div class="flex-grow caption-color lines-limit-2">{item.label}</div> <div class="check">
{#if isSelected(selected, item)} {#if isSelected(selected, item)}
<div class="check-right"><CheckBox checked primary /></div> <Icon icon={IconCheck} size={'small'} />
{/if} {/if}
</div>
<div class="labels overflow-label">{item.label}</div>
</button> </button>
</svelte:fragment> </svelte:fragment>
</ListView> </ListView>

View File

@ -131,7 +131,7 @@
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<div <div
use:tooltip={{ label: category.label }} use:tooltip={{ label: category.label }}
class="element m-0-5" class="element"
class:selected={currentCategory === category} class:selected={currentCategory === category}
on:click={() => handleScrollToCategory(category.id)} on:click={() => handleScrollToCategory(category.id)}
> >
@ -140,7 +140,7 @@
{/each} {/each}
</div> </div>
<div class="scrolling"> <div class="scrolling">
<Scroller bind:divScroll={div} on:scrolledCategories={handleScrolled} fade={emojiSP} noStretch> <Scroller bind:divScroll={div} on:scrolledCategories={handleScrolled} fade={emojiSP} noStretch checkForHeaders>
{#each categories as category} {#each categories as category}
<div id={category.id} class="scroll-header categoryHeader"> <div id={category.id} class="scroll-header categoryHeader">
<Label label={category.label} /> <Label label={category.label} />
@ -149,7 +149,7 @@
{#each category.emojis as emoji} {#each category.emojis as emoji}
{#if emoji !== undefined} {#if emoji !== undefined}
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="element m-0-5" on:click={() => dispatch('close', emoji)}>{emoji}</div> <div class="element" on:click={() => dispatch('close', emoji)}>{emoji}</div>
{/if} {/if}
{/each} {/each}
</div> </div>
@ -181,8 +181,8 @@
font-size: 0.75rem; font-size: 0.75rem;
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
color: var(--dark-color); color: var(--theme-caption-color);
background-color: var(--board-bg-color); background-color: var(--theme-popup-header);
border-radius: 0.25rem; border-radius: 0.25rem;
&:first-child { &:first-child {
margin-top: 0; margin-top: 0;
@ -198,18 +198,22 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 1.5rem; flex-shrink: 0;
height: 1.5rem; width: 1.75rem;
height: 1.75rem;
margin: 0.125rem;
padding: 0.25rem;
border-radius: 0.25rem; border-radius: 0.25rem;
color: var(--caption-color); color: var(--theme-content-color);
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background-color: var(--popup-bg-hover); color: var(--theme-caption-color);
background-color: var(--theme-popup-hover);
} }
&.selected { &.selected {
background-color: var(--popup-bg-hover); background-color: var(--theme-popup-header);
} }
} }
</style> </style>

View File

@ -15,7 +15,7 @@
<script lang="ts"> <script lang="ts">
import type { Asset, IntlString } from '@hcengineering/platform' import type { Asset, IntlString } from '@hcengineering/platform'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { deviceOptionsStore, mouseAttractor, resizeObserver } from '..' import { deviceOptionsStore, resizeObserver } from '..'
import { createFocusManager } from '../focus' import { createFocusManager } from '../focus'
import type { AnySvelteComponent } from '../types' import type { AnySvelteComponent } from '../types'
import EditBox from './EditBox.svelte' import EditBox from './EditBox.svelte'
@ -136,7 +136,9 @@
/> />
</div> </div>
{/if} {/if}
<div class:background-accent-bg-color={cHeight === 1} style:height={'2px'} /> {#if cHeight === 1}
<div class="whereSelected" />
{/if}
<div class="scroll" on:scroll={() => updateLocation(scrollDiv, selectedDiv, filteredObjects)} bind:this={scrollDiv}> <div class="scroll" on:scroll={() => updateLocation(scrollDiv, selectedDiv, filteredObjects)} bind:this={scrollDiv}>
<div class="box"> <div class="box">
<ListView <ListView
@ -148,15 +150,13 @@
<svelte:fragment slot="item" let:item={itemId}> <svelte:fragment slot="item" let:item={itemId}>
{@const item = filteredObjects[itemId]} {@const item = filteredObjects[itemId]}
<button <button
class="menu-item w-full" class="menu-item withList w-full"
class:selected={item.isSelected}
on:click={() => dispatch('close', item.id)} on:click={() => dispatch('close', item.id)}
on:focus={() => dispatch('update', item)}
on:mouseover={mouseAttractor(() => dispatch('update', item))}
on:mouseenter={mouseAttractor(() => dispatch('update', item))}
> >
<div class="flex-row-center" class:mt-2={huge} class:mb-2={huge}> <div class="flex-row-center pointer-events-none" class:mt-2={huge} class:mb-2={huge}>
{#if hasSelected} {#if hasSelected}
<div class="icon"> <div class="check">
{#if item.isSelected} {#if item.isSelected}
<div bind:this={selectedDiv}> <div bind:this={selectedDiv}>
<Icon icon={IconCheck} {size} /> <Icon icon={IconCheck} {size} />
@ -186,18 +186,24 @@
<svelte:fragment slot="category" let:item={row}> <svelte:fragment slot="category" let:item={row}>
{@const obj = filteredObjects[row]} {@const obj = filteredObjects[row]}
{#if obj.category && ((row === 0 && obj.category.label !== undefined) || obj.category.label !== filteredObjects[row - 1]?.category?.label)} {#if obj.category && ((row === 0 && obj.category.label !== undefined) || obj.category.label !== filteredObjects[row - 1]?.category?.label)}
<div class="flex p-1"> <div class="menu-group__header">
<div class="icon mr-2"> <div class="flex-row-center pl-1">
{#if obj.category.icon} {#if obj.category.icon}
<div class="clear-mins flex-no-shrink mr-2">
<Icon icon={obj.category.icon} size={'small'} /> <Icon icon={obj.category.icon} size={'small'} />
{/if}
</div> </div>
{/if}
<span class="overflow-label">
<Label label={obj.category.label} /> <Label label={obj.category.label} />
</span>
</div>
</div> </div>
{/if} {/if}
</svelte:fragment> </svelte:fragment>
</ListView> </ListView>
</div> </div>
</div> </div>
<div class:background-accent-bg-color={cHeight === -1} style:height={'2px'} /> {#if cHeight === -1}
<div class="whereSelected" />
{/if}
</div> </div>

View File

@ -37,9 +37,12 @@
$: optionsMod = { component: options.component ?? Menu, props, element, kind: 'submenu' } $: optionsMod = { component: options.component ?? Menu, props, element, kind: 'submenu' }
</script> </script>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div <div
bind:this={element} bind:this={element}
on:keydown on:keydown
on:mouseover
on:click on:click
use:tooltip={optionsMod} use:tooltip={optionsMod}
class="antiPopup-submenu" class="antiPopup-submenu"
@ -54,7 +57,7 @@
{/if} {/if}
{:else} {:else}
{#if icon} {#if icon}
<div class="icon mr-3"><Icon {icon} size={'small'} /></div> <div class="icon"><Icon {icon} size={'small'} /></div>
{/if} {/if}
<span class="overflow-label pr-1"> <span class="overflow-label pr-1">
{#if label}<Label {label} params={labelProps} /> {#if label}<Label {label} params={labelProps} />

View File

@ -165,7 +165,7 @@
color: var(--theme-content-color); color: var(--theme-content-color);
} }
&.warning { &.warning {
color: var(--warning-color); color: var(--theme-warning-color);
} }
&.critical { &.critical {
color: var(--theme-error-color); color: var(--theme-error-color);
@ -196,7 +196,7 @@
color: var(--caption-color); color: var(--caption-color);
} }
&.warning { &.warning {
color: var(--warning-color); color: var(--theme-warning-color);
} }
&.critical { &.critical {
color: var(--theme-error-color); color: var(--theme-error-color);

View File

@ -293,6 +293,7 @@
<button <button
bind:this={datePresenter} bind:this={datePresenter}
class="datetime-button {kind} {size}" class="datetime-button {kind} {size}"
class:notSelected={!value}
class:editable class:editable
class:edit class:edit
on:click={() => { on:click={() => {
@ -411,7 +412,7 @@
{new Date(value).getMinutes().toString().padStart(2, '0')} {new Date(value).getMinutes().toString().padStart(2, '0')}
{/if} {/if}
{:else} {:else}
<div class="content-color"> <div class="overflow-label">
<Label label={labelNull} /> <Label label={labelNull} />
</div> </div>
{/if} {/if}
@ -459,7 +460,7 @@
color: var(--theme-content-color); color: var(--theme-content-color);
} }
&.warning { &.warning {
color: var(--warning-color); color: var(--theme-warning-color);
} }
&.overdue { &.overdue {
color: var(--theme-error-color); color: var(--theme-error-color);
@ -515,7 +516,7 @@
color: var(--caption-color); color: var(--caption-color);
} }
&.warning { &.warning {
color: var(--warning-color); color: var(--theme-warning-color);
} }
&.overdue { &.overdue {
color: var(--theme-error-color); color: var(--theme-error-color);
@ -562,6 +563,7 @@
&.secondary { &.secondary {
padding: 0 0.625rem; padding: 0 0.625rem;
font-weight: 500;
color: var(--theme-caption-color); color: var(--theme-caption-color);
background-color: var(--theme-button-enabled); background-color: var(--theme-button-enabled);
border-color: var(--theme-button-border); border-color: var(--theme-button-border);
@ -633,5 +635,16 @@
.separator { .separator {
margin: 0 0.1rem; margin: 0 0.1rem;
} }
&.notSelected {
color: var(--theme-dark-color);
.btn-icon {
color: var(--theme-darker-color);
}
&:hover,
&:hover .btn-icon {
color: var(--theme-content-color);
}
}
} }
</style> </style>

View File

@ -65,7 +65,7 @@
margin-right: 1rem; margin-right: 1rem;
&.mIconContainerWarning { &.mIconContainerWarning {
color: var(--warning-color); color: var(--theme-warning-color);
} }
&.mIconContainerCritical { &.mIconContainerCritical {

View File

@ -138,7 +138,11 @@
> >
<WiFi <WiFi
size={'small'} size={'small'}
fill={$networkStatus === -1 ? 'red' : $networkStatus % 2 === 1 ? 'blue' : 'currentColor'} fill={$networkStatus === -1
? 'var(--theme-error-color)'
: $networkStatus % 2 === 1
? 'var(--theme-warning-color)'
: 'currentColor'}
/> />
</div> </div>
</div> </div>

View File

@ -126,7 +126,7 @@ export type ButtonKind =
| 'list' | 'list'
| 'list-header' | 'list-header'
export type ButtonSize = 'inline' | 'small' | 'medium' | 'large' | 'x-large' export type ButtonSize = 'inline' | 'small' | 'medium' | 'large' | 'x-large'
export type ButtonShape = 'rectangle' | 'rectangle-left' | 'rectangle-right' | 'circle' | 'round' | undefined export type ButtonShape = 'rectangle' | 'rectangle-left' | 'rectangle-right' | 'circle' | 'round' | 'filter' | undefined
export type EditStyle = 'editbox' | 'large-style' | 'small-style' | 'search-style' | 'underline' export type EditStyle = 'editbox' | 'large-style' | 'small-style' | 'search-style' | 'underline'
export interface PopupPositionElement { export interface PopupPositionElement {
getBoundingClientRect: () => DOMRect getBoundingClientRect: () => DOMRect

View File

@ -299,7 +299,7 @@
<style lang="scss"> <style lang="scss">
@keyframes highlight { @keyframes highlight {
50% { 50% {
background-color: var(--warning-color); background-color: var(--theme-warning-color);
} }
} }
.container { .container {

View File

@ -150,7 +150,7 @@
{getName(selected)} {getName(selected)}
{/if} {/if}
{:else} {:else}
<div class="flex-presenter"> <div class="flex-presenter not-selected">
{#if icon} {#if icon}
<div class="icon" class:small-gap={size === 'inline' || size === 'small'}> <div class="icon" class:small-gap={size === 'inline' || size === 'small'}>
<Icon {icon} size={kind === 'link' || kind === 'secondary' ? 'small' : size} /> <Icon {icon} size={kind === 'link' || kind === 'secondary' ? 'small' : size} />

View File

@ -193,7 +193,7 @@
<EditBox kind={'search-style'} focusIndex={1} focus bind:value={search} {placeholder} /> <EditBox kind={'search-style'} focusIndex={1} focus bind:value={search} {placeholder} />
</div> </div>
{#if cHeight === 1} {#if cHeight === 1}
<div class="background-content-accent-color" style:height={'1px'} /> <div class="whereSelected" />
{/if} {/if}
<div <div
class="scroll" class="scroll"
@ -209,15 +209,13 @@
{@const cl = hierarchy.getClass(contacts[item]._class)} {@const cl = hierarchy.getClass(contacts[item]._class)}
{#if item === 0 || (item > 0 && categorizedPersons.get(toAny(contacts[item - 1])._id) !== categorizedPersons.get(obj._id))} {#if item === 0 || (item > 0 && categorizedPersons.get(toAny(contacts[item - 1])._id) !== categorizedPersons.get(obj._id))}
<!--Category for first item--> <!--Category for first item-->
<div class="category-box"> <div class="menu-group__header category-box">
<div class="flex flex-grow overflow-label"> <div class="flex-row-center pl-1">
<span class="fs-medium flex-center mt-2 mb-2 ml-2">
{#if cl.icon} {#if cl.icon}
<Icon icon={cl.icon} size={'small'} /> <div class="clear-mins mr-2"><Icon icon={cl.icon} size={'small'} /></div>
{/if} {/if}
<div class="ml-1"> <span class="overflow-label">
<Label label={getCategoryTitle(category)} /> <Label label={getCategoryTitle(category)} />
</div>
</span> </span>
</div> </div>
</div> </div>
@ -227,49 +225,29 @@
<svelte:fragment slot="item" let:item> <svelte:fragment slot="item" let:item>
{@const obj = contacts[item]} {@const obj = contacts[item]}
<button <button
class="menu-item w-full" class="menu-item withList no-focus w-full"
class:background-button-bg-color={obj._id === selected} class:selected={obj._id === selected}
class:border-radius-1={obj._id === selected}
on:click={() => { on:click={() => {
handleSelection(undefined, item) handleSelection(undefined, item)
}} }}
> >
{#if allowDeselect && selected} {#if allowDeselect && selected}
<div class="icon"> <div class="check">
{#if obj._id === selected} {#if obj._id === selected}
<div bind:this={selectedDiv}> <div bind:this={selectedDiv} use:tooltip={{ label: titleDeselect ?? presentation.string.Deselect }}>
{#if titleDeselect}
<div class="clear-mins" use:tooltip={{ label: titleDeselect }}>
<Icon icon={IconCheck} {size} /> <Icon icon={IconCheck} {size} />
</div> </div>
{:else}
<Icon icon={IconCheck} {size} />
{/if} {/if}
</div> </div>
{/if} {/if}
</div>
{/if}
<span class="label">
{#if obj._id === selected}
<div bind:this={selectedDiv}>
<div class="flex flex-grow overflow-label">
<UserInfo size={'x-small'} value={obj} {icon} /> <UserInfo size={'x-small'} value={obj} {icon} />
</div>
</div>
{:else}
<div class="flex flex-grow overflow-label">
<UserInfo size={'x-small'} value={obj} {icon} />
</div>
{/if}
</span>
</button> </button>
</svelte:fragment> </svelte:fragment>
</ListView> </ListView>
</div> </div>
</div> </div>
{#if cHeight === -1} {#if cHeight === -1}
<div class="background-content-accent-color" style:height={'3px'} /> <div class="whereSelected" />
{/if} {/if}
</div> </div>

View File

@ -143,7 +143,7 @@
img { img {
object-fit: cover; object-fit: cover;
border: 2px solid var(--avatar-border-color); border: 1px solid var(--avatar-border-color);
} }
&.no-img { &.no-img {
border-color: transparent; border-color: transparent;
@ -195,7 +195,7 @@
} }
.ava-mask { .ava-mask {
position: absolute; position: absolute;
border: 2px solid var(--avatar-border-color); border: 1px solid var(--avatar-border-color);
border-radius: 50%; border-radius: 50%;
} }

View File

@ -293,6 +293,7 @@
bind:input={addBtn} bind:input={addBtn}
icon={contact.icon.SocialEdit} icon={contact.icon.SocialEdit}
label={displayItems.length === 0 ? presentation.string.AddSocialLinks : undefined} label={displayItems.length === 0 ? presentation.string.AddSocialLinks : undefined}
notSelected={displayItems.length === 0}
{kind} {kind}
{size} {size}
{shape} {shape}

View File

@ -30,6 +30,6 @@
<Avatar avatar={value.avatar} {size} {icon} on:accent-color /> <Avatar avatar={value.avatar} {size} {icon} on:accent-color />
<div class="flex-col min-w-0 {size === 'tiny' || size === 'inline' ? 'ml-1' : 'ml-2'}"> <div class="flex-col min-w-0 {size === 'tiny' || size === 'inline' ? 'ml-1' : 'ml-2'}">
{#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if} {#if subtitle}<div class="content-dark-color text-sm">{subtitle}</div>{/if}
<div class="content-color overflow-label text-left">{getName(value)}</div> <div class="label overflow-label text-left">{getName(value)}</div>
</div> </div>
</div> </div>

View File

@ -5,7 +5,7 @@
</symbol> </symbol>
<symbol id="track" viewBox="0 0 24 24"> <symbol id="track" viewBox="0 0 24 24">
<path d="M21.7,15L21,13.8c-0.6-1.1-1.1-2.3-1.2-3.4l-0.1-0.9c-0.5,0.2-1.1,0.4-1.6,0.4l0.1,0.7c0.1,1.5,0.6,2.9,1.4,4.2l0.7,1.2 c0.4,0.6,0.7,1.2,0.7,1.3c0,0.1-0.1,0.1-0.1,0.2c-0.1,0.1-1,0.1-1.5,0.1H4.8c-0.6,0-1.4,0-1.5-0.1l-0.1-0.1c0-0.1,0.5-0.8,0.7-1.4 l0.7-1.2c0.7-1.3,1.2-2.6,1.4-4.2l0.4-2.7c0.4-3,2.7-5.1,5.7-5.1c1,0,1.9,0.3,2.7,0.7c0.4-0.5,0.9-0.9,1.4-1.1C15,1.5,13.5,1,12,1 C8.2,1,5,3.9,4.5,7.7l-0.4,2.7c-0.1,1.2-0.5,2.4-1.2,3.4L2.2,15c-0.7,1.2-1.1,1.8-1,2.6c0.1,0.5,0.4,1,0.7,1.3 c0.6,0.5,1.3,0.5,2.7,0.5h3c0.2,1,0.8,1.9,1.5,2.5C10.1,22.6,11,23,12,23s2-0.4,2.7-1.1c0.7-0.6,1.2-1.5,1.5-2.5h3 c1.4,0,2.1,0,2.7-0.5c0.4-0.4,0.6-0.8,0.7-1.3C22.9,16.8,22.6,16.2,21.7,15z M13.6,20.6c-1,0.8-2.3,0.8-3.2,0 c-0.4-0.2-0.6-0.7-0.8-1.2h4.9C14.2,19.9,14,20.3,13.6,20.6z" /> <path d="M21.7,15L21,13.8c-0.6-1.1-1.1-2.3-1.2-3.4l-0.1-0.9c-0.5,0.2-1.1,0.4-1.6,0.4l0.1,0.7c0.1,1.5,0.6,2.9,1.4,4.2l0.7,1.2 c0.4,0.6,0.7,1.2,0.7,1.3c0,0.1-0.1,0.1-0.1,0.2c-0.1,0.1-1,0.1-1.5,0.1H4.8c-0.6,0-1.4,0-1.5-0.1l-0.1-0.1c0-0.1,0.5-0.8,0.7-1.4 l0.7-1.2c0.7-1.3,1.2-2.6,1.4-4.2l0.4-2.7c0.4-3,2.7-5.1,5.7-5.1c1,0,1.9,0.3,2.7,0.7c0.4-0.5,0.9-0.9,1.4-1.1C15,1.5,13.5,1,12,1 C8.2,1,5,3.9,4.5,7.7l-0.4,2.7c-0.1,1.2-0.5,2.4-1.2,3.4L2.2,15c-0.7,1.2-1.1,1.8-1,2.6c0.1,0.5,0.4,1,0.7,1.3 c0.6,0.5,1.3,0.5,2.7,0.5h3c0.2,1,0.8,1.9,1.5,2.5C10.1,22.6,11,23,12,23s2-0.4,2.7-1.1c0.7-0.6,1.2-1.5,1.5-2.5h3 c1.4,0,2.1,0,2.7-0.5c0.4-0.4,0.6-0.8,0.7-1.3C22.9,16.8,22.6,16.2,21.7,15z M13.6,20.6c-1,0.8-2.3,0.8-3.2,0 c-0.4-0.2-0.6-0.7-0.8-1.2h4.9C14.2,19.9,14,20.3,13.6,20.6z" />
<circle fill="var(--warning-color)" cx="18" cy="5.9" r="3"/> <circle fill="var(--theme-warning-color)" cx="18" cy="5.9" r="3"/>
</symbol> </symbol>
<symbol id="donttrack" viewBox="0 0 24 24"> <symbol id="donttrack" viewBox="0 0 24 24">
<path d="M21.7,15l-0.2,0.1L21.7,15L21,13.8c-0.6-1.1-1.1-2.3-1.2-3.4l-0.4-2.7C19,3.9,15.8,1,12,1S5,3.9,4.5,7.7l-0.4,2.7 c-0.1,1.2-0.5,2.4-1.2,3.4L2.2,15c-0.7,1.2-1.1,1.8-1,2.6c0.1,0.5,0.4,1,0.7,1.3c0.6,0.5,1.3,0.5,2.7,0.5h3c0.2,1,0.8,1.9,1.5,2.5 C10.1,22.6,11,23,12,23c1,0,2-0.4,2.7-1.1c0.7-0.6,1.2-1.5,1.5-2.5h3c1.4,0,2.1,0,2.7-0.5c0.4-0.4,0.6-0.8,0.7-1.3 C22.9,16.8,22.6,16.2,21.7,15z M14.5,19.4c-0.2,0.5-0.5,0.8-0.8,1.2l0,0c-1,0.8-2.3,0.8-3.2,0c-0.4-0.2-0.6-0.7-0.8-1.2H14.5z M20.9,17.5c-0.1,0.1-1,0.1-1.5,0.1H4.8c-0.6,0-1.4,0-1.5-0.1l-0.1-0.1c0-0.1,0.5-0.8,0.7-1.4l0.7-1.2c0.7-1.3,1.2-2.6,1.4-4.2 l0.4-2.7c0.4-3,2.7-5.1,5.7-5.1s5.4,2.1,5.7,5.1l0.4,2.7c0.1,1.5,0.6,2.9,1.4,4.2l0.7,1.2c0.4,0.6,0.7,1.2,0.7,1.3 C21,17.4,20.9,17.4,20.9,17.5z" /> <path d="M21.7,15l-0.2,0.1L21.7,15L21,13.8c-0.6-1.1-1.1-2.3-1.2-3.4l-0.4-2.7C19,3.9,15.8,1,12,1S5,3.9,4.5,7.7l-0.4,2.7 c-0.1,1.2-0.5,2.4-1.2,3.4L2.2,15c-0.7,1.2-1.1,1.8-1,2.6c0.1,0.5,0.4,1,0.7,1.3c0.6,0.5,1.3,0.5,2.7,0.5h3c0.2,1,0.8,1.9,1.5,2.5 C10.1,22.6,11,23,12,23c1,0,2-0.4,2.7-1.1c0.7-0.6,1.2-1.5,1.5-2.5h3c1.4,0,2.1,0,2.7-0.5c0.4-0.4,0.6-0.8,0.7-1.3 C22.9,16.8,22.6,16.2,21.7,15z M14.5,19.4c-0.2,0.5-0.5,0.8-0.8,1.2l0,0c-1,0.8-2.3,0.8-3.2,0c-0.4-0.2-0.6-0.7-0.8-1.2H14.5z M20.9,17.5c-0.1,0.1-1,0.1-1.5,0.1H4.8c-0.6,0-1.4,0-1.5-0.1l-0.1-0.1c0-0.1,0.5-0.8,0.7-1.4l0.7-1.2c0.7-1.3,1.2-2.6,1.4-4.2 l0.4-2.7c0.4-3,2.7-5.1,5.7-5.1s5.4,2.1,5.7,5.1l0.4,2.7c0.1,1.5,0.6,2.9,1.4,4.2l0.7,1.2c0.4,0.6,0.7,1.2,0.7,1.3 C21,17.4,20.9,17.4,20.9,17.5z" />

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -403,7 +403,7 @@
on:click={() => { on:click={() => {
showPopup( showPopup(
ColorPopup, ColorPopup,
{ value: states, searchable: true, placeholder: ui.string.SearchDots }, { value: states, searchable: true, placeholder: ui.string.SearchDots, selected: selectedState?._id },
btn, btn,
(result) => { (result) => {
if (result && result.id) { if (result && result.id) {

View File

@ -702,6 +702,7 @@
focusIndex={103} focusIndex={103}
label={recruit.string.AddDropHere} label={recruit.string.AddDropHere}
icon={IconAttachment} icon={IconAttachment}
notSelected
on:click={() => { on:click={() => {
inputFile.click() inputFile.click()
}} }}
@ -727,7 +728,7 @@
<style lang="scss"> <style lang="scss">
.resume { .resume {
box-shadow: 0 0 0 0 var(--primary-button-focused-border); box-shadow: 0 0 0 0 var(--primary-button-focused-border);
border-radius: 0.5rem; border-radius: 0.25rem;
transition: box-shadow 0.15s ease-in-out; transition: box-shadow 0.15s ease-in-out;
&.solid { &.solid {

View File

@ -38,6 +38,7 @@
{justify} {justify}
{width} {width}
{disabled} {disabled}
notSelected={value === undefined}
showTooltip={{ label: tooltip, direction: labelDirection }} showTooltip={{ label: tooltip, direction: labelDirection }}
on:click={() => { on:click={() => {
if (value === true) value = false if (value === true) value = false
@ -47,7 +48,7 @@
> >
<svelte:fragment slot="content"> <svelte:fragment slot="content">
<div class="flex-row-center flex-no-wrap pointer-events-none"> <div class="flex-row-center flex-no-wrap pointer-events-none">
<span class="overflow-label"> <span class="label overflow-label">
<Label {label} /> <Label {label} />
</span> </span>
<div class="btn-icon ml-1"> <div class="btn-icon ml-1">
@ -74,14 +75,14 @@
<style lang="scss"> <style lang="scss">
.btn-icon { .btn-icon {
color: var(--content-color); color: var(--theme-content-color);
transition: color 0.15s; transition: color 0.15s;
pointer-events: none; pointer-events: none;
&:hover { &:hover {
color: var(--caption-color); color: var(--theme-caption-color);
} }
&:disabled:hover { &:disabled:hover {
color: var(--content-color); color: var(--theme-content-color);
} }
} }

View File

@ -50,7 +50,7 @@
</span> </span>
{:else} {:else}
<div <div
class="text-sm flex flex-between tag-item" class="tag-item"
style={`${getTagStyle(getPlatformColor(tag?.color ?? element?.color ?? 0), selected)}`} style={`${getTagStyle(getPlatformColor(tag?.color ?? element?.color ?? 0), selected)}`}
on:click on:click
on:keydown on:keydown
@ -61,16 +61,16 @@
}} }}
> >
<span class="overflow-label max-w-40">{name}</span> <span class="overflow-label max-w-40">{name}</span>
<span class="ml-1">
{#if tag && tagIcon && schema !== '0'} {#if tag && tagIcon && schema !== '0'}
<span class="ml-1">
<Icon icon={tagIcon} size={'small'} /> <Icon icon={tagIcon} size={'small'} />
{/if}
</span> </span>
{/if}
{#if action} {#if action}
<div class="ml-1"> <div class="flex-center ml-1">
<ActionIcon <ActionIcon
icon={action} icon={action}
size={'medium'} size={'small'}
action={() => { action={() => {
dispatch('action') dispatch('action')
}} }}
@ -82,29 +82,28 @@
<style lang="scss"> <style lang="scss">
.tag-item { .tag-item {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0.125rem; margin: 0.125rem;
padding: 0.125rem 0.25rem; padding: 0 0.25rem;
min-width: 0;
border-radius: 0.25rem; min-height: 1.5rem;
text-transform: uppercase;
font-weight: 500; font-weight: 500;
font-size: 0.75rem; font-size: 0.75rem;
color: var(--theme-content-color);
border-radius: 0.25rem;
text-transform: uppercase;
color: var(--accent-color);
&:hover { &:hover {
color: var(--caption-color); color: var(--theme-caption-color);
} }
display: flex;
align-items: center;
justify-content: center;
} }
.tag-item-inline { .tag-item-inline {
position: relative; position: relative;
padding-left: 0.75rem; padding-left: 0.75rem;
font-weight: 500; font-weight: 500;
color: var(--accent-color); color: var(--theme-content-color);
&::before { &::before {
position: absolute; position: absolute;

View File

@ -20,7 +20,7 @@
import { TagCategory, TagElement } from '@hcengineering/tags' import { TagCategory, TagElement } from '@hcengineering/tags'
import { import {
Button, Button,
CheckBox, IconCheck,
getPlatformColor, getPlatformColor,
Icon, Icon,
IconAdd, IconAdd,
@ -174,19 +174,26 @@
({catObjects.length}) ({catObjects.length})
{/if} {/if}
</span> </span>
<span class="counter">{getCount(cat)}</span> <span class="counter">
{#key selected}
{getCount(cat)}
{/key}
</span>
</div> </div>
</button> </button>
<div class="menu-group"> <div class="menu-group">
{#each catObjects.slice(0, 50) as element} {#each catObjects.slice(0, 50) as element}
<button <button
class="menu-item" class="menu-item no-focus"
class:selected={isSelected(selected, element)}
on:click={() => { on:click={() => {
checkSelected(selected, element) checkSelected(selected, element)
}} }}
> >
<div class="check pointer-events-none"> <div class="check">
<CheckBox checked={isSelected(selected, element)} primary /> {#if isSelected(selected, element)}
<Icon icon={IconCheck} size={'small'} />
{/if}
</div> </div>
<div class="tag" style="background-color: {getPlatformColor(element.color)};" /> <div class="tag" style="background-color: {getPlatformColor(element.color)};" />
<span class="lines-limit-2">{element.title}</span> <span class="lines-limit-2">{element.title}</span>
@ -210,11 +217,12 @@
<style lang="scss"> <style lang="scss">
.counter { .counter {
margin-top: -0.125rem;
padding-right: 0.125rem; padding-right: 0.125rem;
min-width: 1.5rem; min-width: 1.5rem;
text-align: right; text-align: right;
font-size: 0.8125rem; font-size: 0.8125rem;
color: var(--caption-color); color: var(--theme-caption-color);
} }
.empty { .empty {
display: flex; display: flex;
@ -222,7 +230,7 @@
align-items: center; align-items: center;
height: 100%; height: 100%;
font-size: 0.75rem; font-size: 0.75rem;
color: var(--dark-color); color: var(--theme-dark-color);
border-top: 1px solid var(--popup-divider); border-top: 1px solid var(--theme-popup-divider);
} }
</style> </style>

View File

@ -122,16 +122,14 @@
icon={tracker.icon.Components} icon={tracker.icon.Components}
disabled={!isEditable} disabled={!isEditable}
{loading} {loading}
notSelected={!value}
{short} {short}
on:click={handleComponentEditorOpened} on:click={handleComponentEditorOpened}
><svelte:fragment slot="content">
<span
class="{enlargedText ? 'ml-1 text-base fs-bold' : 'text-md'} overflow-label {!value
? 'content-color'
: 'caption-color'} pointer-events-none"
> >
<svelte:fragment slot="content">
<span class="label {enlargedText ? 'ml-1 text-base fs-bold' : 'text-md'} overflow-label pointer-events-none">
<Label label={getEmbeddedLabel(componentText)} /> <Label label={getEmbeddedLabel(componentText)} />
</span> </span>
</svelte:fragment></Button </svelte:fragment>
> </Button>
{/if} {/if}

View File

@ -561,7 +561,7 @@
kind={'secondary'} kind={'secondary'}
size={'large'} size={'large'}
label={tracker.string.NoIssueTemplate} label={tracker.string.NoIssueTemplate}
icon={tracker.icon.Issues} icon={tracker.icon.IssueTemplates}
searchField={'title'} searchField={'title'}
allowDeselect={true} allowDeselect={true}
showNavigate={false} showNavigate={false}

View File

@ -41,7 +41,11 @@
: tracker.string.Backlog : tracker.string.Backlog
: undefined : undefined
$: statusesInfo = defaultComponentStatuses.map((s) => ({ id: s, ...componentStatusAssets[s] })) $: statusesInfo = defaultComponentStatuses.map((s) => ({
id: s,
isSelected: componentStatusAssets[s].label === selectedStatusLabel,
...componentStatusAssets[s]
}))
const handleComponentStatusEditorOpened = (event: MouseEvent) => { const handleComponentStatusEditorOpened = (event: MouseEvent) => {
if (!isEditable) { if (!isEditable) {

View File

@ -117,7 +117,7 @@
{params?.subTitlePostfix} {params?.subTitlePostfix}
</span> </span>
</div> </div>
<div class="flex-between"> <div class="flex-between gap-2">
<Button label={tracker.string.ViewIssue} on:click={handleIssueOpened} /> <Button label={tracker.string.ViewIssue} on:click={handleIssueOpened} />
<Button icon={tracker.icon.CopyURL} label={tracker.string.CopyIssueUrl} on:click={handleCopyUrl} /> <Button icon={tracker.icon.CopyURL} label={tracker.string.CopyIssueUrl} on:click={handleCopyUrl} />
</div> </div>

View File

@ -42,7 +42,7 @@
const client = getClient() const client = getClient()
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const prioritiesInfo = defaultPriorities.map((p) => ({ id: p, ...issuePriorities[p] })) let selectedPriority: IssuePriority | undefined = value.priority
const handlePriorityEditorOpened = (event: MouseEvent) => { const handlePriorityEditorOpened = (event: MouseEvent) => {
event.stopPropagation() event.stopPropagation()
@ -64,12 +64,21 @@
return return
} }
selectedPriority = newPriority
dispatch('change', newPriority) dispatch('change', newPriority)
if ('_class' in value) { if ('_class' in value) {
await client.update(value, { priority: newPriority }) await client.update(value, { priority: newPriority })
} }
} }
$: prioritiesInfo = defaultPriorities.map((p) => {
return {
id: p,
isSelected: selectedPriority === p,
...issuePriorities[p]
}
})
</script> </script>
{#if value} {#if value}

View File

@ -132,7 +132,7 @@
color: var(--theme-error-color) !important; color: var(--theme-error-color) !important;
} }
.showWarning { .showWarning {
color: var(--warning-color) !important; color: var(--theme-warning-color) !important;
} }
.romColor { .romColor {
color: var(--theme-content-color) !important; color: var(--theme-content-color) !important;

View File

@ -73,19 +73,25 @@
selectedSprint = sprints.find((it) => it._id === newSprintId) selectedSprint = sprints.find((it) => it._id === newSprintId)
} }
const getSprintInfo = (rawSprints: Sprint[]) => { const getSprintInfo = (rawSprints: Sprint[], sp: Sprint | undefined) => {
return [ return [
{ id: null, icon: tracker.icon.Sprint, label: tracker.string.NoSprint }, {
id: null,
icon: tracker.icon.Sprint,
label: tracker.string.NoSprint,
isSelected: sp === undefined
},
...rawSprints.map((p) => ({ ...rawSprints.map((p) => ({
id: p._id, id: p._id,
icon: tracker.icon.Sprint, icon: tracker.icon.Sprint,
text: p.label, text: p.label,
isSelected: sp ? p._id === sp._id : false,
category: sprintStatusAssets[p.status] category: sprintStatusAssets[p.status]
})) }))
] ]
} }
$: sprints = getSprintInfo(rawSprints) $: sprints = getSprintInfo(rawSprints, selectedSprint)
const handleSprintEditorOpened = async (event: MouseEvent): Promise<void> => { const handleSprintEditorOpened = async (event: MouseEvent): Promise<void> => {
event.stopPropagation() event.stopPropagation()
@ -138,15 +144,12 @@
{showTooltip} {showTooltip}
icon={sprintIcon} icon={sprintIcon}
disabled={!isEditable} disabled={!isEditable}
notSelected={!value}
{short} {short}
on:click={handleSprintEditorOpened} on:click={handleSprintEditorOpened}
> >
<svelte:fragment slot="content"> <svelte:fragment slot="content">
<span <span class="label {enlargedText ? 'text-base' : 'text-md'} fs-bold overflow-label pointer-events-none">
class="{enlargedText ? 'text-base' : 'text-md'} fs-bold overflow-label {!value
? 'content-color'
: 'caption-color'} pointer-events-none"
>
<Label label={getEmbeddedLabel(sprintText)} /> <Label label={getEmbeddedLabel(sprintText)} />
</span> </span>
</svelte:fragment> </svelte:fragment>

View File

@ -40,7 +40,11 @@
: tracker.string.Planned : tracker.string.Planned
: undefined : undefined
$: statusesInfo = defaultSprintStatuses.map((s) => ({ id: s, ...sprintStatusAssets[s] })) $: statusesInfo = defaultSprintStatuses.map((s) => ({
id: s,
isSelected: sprintStatusAssets[s].label === selectedStatusLabel,
...sprintStatusAssets[s]
}))
const handleSprintStatusEditorOpened = (event: MouseEvent) => { const handleSprintStatusEditorOpened = (event: MouseEvent) => {
if (!isEditable) { if (!isEditable) {

View File

@ -65,6 +65,7 @@
label={tracker.string.TimeSpendValue} label={tracker.string.TimeSpendValue}
labelParams={{ value: value.estimation }} labelParams={{ value: value.estimation }}
icon={tracker.icon.Estimation} icon={tracker.icon.Estimation}
notSelected={value.estimation === 0}
{justify} {justify}
{width} {width}
{size} {size}

View File

@ -43,6 +43,7 @@
{size} {size}
{justify} {justify}
{width} {width}
notSelected={!value}
on:click={(ev) => { on:click={(ev) => {
if (!shown && !readonly) { if (!shown && !readonly) {
showPopup(EditBoxPopup, { value }, eventToHTMLElement(ev), (res) => { showPopup(EditBoxPopup, { value }, eventToHTMLElement(ev), (res) => {
@ -57,9 +58,9 @@
> >
<svelte:fragment slot="content"> <svelte:fragment slot="content">
{#if value} {#if value}
<span class="overflow-label pointer-events-none">{value}</span> <span class="label overflow-label pointer-events-none">{value}</span>
{:else} {:else}
<span class="content-dark-color pointer-events-none"><Label label={placeholder} /></span> <span class="label pointer-events-none"><Label label={placeholder} /></span>
{/if} {/if}
</svelte:fragment> </svelte:fragment>
</Button> </Button>

View File

@ -18,6 +18,7 @@
import { LabelAndProps, LinkWrapper, tooltip } from '@hcengineering/ui' import { LabelAndProps, LinkWrapper, tooltip } from '@hcengineering/ui'
export let value: string | string[] | undefined export let value: string | string[] | undefined
export let oneLine: boolean = false
$: tooltipParams = getTooltip(value) $: tooltipParams = getTooltip(value)
@ -35,7 +36,7 @@
} }
</script> </script>
<span class="lines-limit-2 select-text" use:tooltip={tooltipParams}> <span class="{oneLine ? 'overflow-label' : 'lines-limit-2'} select-text" use:tooltip={tooltipParams}>
{#if Array.isArray(value)} {#if Array.isArray(value)}
{#each value as str, i} {#each value as str, i}
<span class:ml-1={i !== 0}><LinkWrapper text={str} /></span> <span class:ml-1={i !== 0}><LinkWrapper text={str} /></span>

View File

@ -211,6 +211,8 @@
} }
} }
} }
const elements: HTMLElement[] = []
</script> </script>
<div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}> <div class="selectPopup" use:resizeObserver={() => dispatch('changeContent')}>
@ -218,8 +220,12 @@
{#each getTypes(_class) as type, i} {#each getTypes(_class) as type, i}
{#if filter === undefined && type.component === view.component.ObjectFilter && hasNested(type)} {#if filter === undefined && type.component === view.component.ObjectFilter && hasNested(type)}
<Submenu <Submenu
bind:element={elements[i]}
on:keydown={(event) => keyDown(event, i)} on:keydown={(event) => keyDown(event, i)}
on:click={(event) => { on:mouseover={() => {
elements[i]?.focus()
}}
on:click={() => {
click(type) click(type)
}} }}
icon={type.icon} icon={type.icon}
@ -236,7 +242,7 @@
on:mouseover={(event) => { on:mouseover={(event) => {
event.currentTarget.focus() event.currentTarget.focus()
}} }}
on:click={(event) => { on:click={() => {
click(type) click(type)
}} }}
> >
@ -245,7 +251,7 @@
<Icon icon={type.icon} size={'small'} /> <Icon icon={type.icon} size={'small'} />
{/if} {/if}
</div> </div>
<div class="pr-1"><Label label={type.label} /></div> <div class="overflow-label pr-1"><Label label={type.label} /></div>
</button> </button>
{/if} {/if}
{/each} {/each}

View File

@ -19,7 +19,8 @@
import ui, { import ui, {
addNotification, addNotification,
Button, Button,
CheckBox, Icon,
IconCheck,
deviceOptionsStore, deviceOptionsStore,
Label, Label,
Loading, Loading,
@ -189,12 +190,14 @@
}} }}
> >
<div class="flex-between w-full"> <div class="flex-between w-full">
<div class="flex clear-mins overflow-label"> <div class="flex-row-center">
<div class="check pointer-events-none"> <div class="check pointer-events-none">
<CheckBox checked={isSelected(value, filter.value)} primary /> {#if isSelected(value, filter.value)}
<Icon icon={IconCheck} size={'small'} />
{/if}
</div> </div>
{#if value} {#if value}
<svelte:component this={attribute.presenter} {value} {...attribute.props} disabled /> <svelte:component this={attribute.presenter} {value} {...attribute.props} disabled oneLine />
{:else} {:else}
<Label label={ui.string.NotSelected} /> <Label label={ui.string.NotSelected} />
{/if} {/if}
@ -214,7 +217,7 @@
</div> </div>
</div> </div>
<Button <Button
shape={'round'} shape={'filter'}
label={view.string.Apply} label={view.string.Apply}
on:click={() => { on:click={() => {
onChange(filter) onChange(filter)

View File

@ -16,7 +16,7 @@
import { Class, Doc, FindResult, getObjectValue, Ref, SortingOrder, Space } from '@hcengineering/core' import { Class, Doc, FindResult, getObjectValue, Ref, SortingOrder, Space } from '@hcengineering/core'
import { translate } from '@hcengineering/platform' import { translate } from '@hcengineering/platform'
import presentation, { getClient } from '@hcengineering/presentation' import presentation, { getClient } from '@hcengineering/presentation'
import ui, { Button, CheckBox, Label, Loading, resizeObserver, deviceOptionsStore } from '@hcengineering/ui' import ui, { Button, Icon, IconCheck, Label, Loading, resizeObserver, deviceOptionsStore } from '@hcengineering/ui'
import { Filter } from '@hcengineering/view' import { Filter } from '@hcengineering/view'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { getPresenter } from '../../utils' import { getPresenter } from '../../utils'
@ -144,21 +144,24 @@
{#each Array.from(values.keys()) as value} {#each Array.from(values.keys()) as value}
{@const realValue = [...(realValues.get(value) ?? [])][0]} {@const realValue = [...(realValues.get(value) ?? [])][0]}
<button <button
class="menu-item" class="menu-item no-focus"
on:click={() => { on:click={() => {
toggle(value) toggle(value)
}} }}
> >
<div class="flex-between w-full"> <div class="flex-between w-full">
<div class="flex clear-mins"> <div class="flex-row-center">
<div class="check pointer-events-none"> <div class="check pointer-events-none">
<CheckBox checked={isSelected(value, selectedValues)} primary /> {#if isSelected(value, selectedValues)}
<Icon icon={IconCheck} size={'small'} />
{/if}
</div> </div>
{#if value !== undefined} {#if value !== undefined}
<svelte:component <svelte:component
this={attribute.presenter} this={attribute.presenter}
value={typeof value === 'string' ? realValue : value} value={typeof value === 'string' ? realValue : value}
{...attribute.props} {...attribute.props}
oneLine
/> />
{:else} {:else}
<Label label={ui.string.NotSelected} /> <Label label={ui.string.NotSelected} />
@ -175,7 +178,7 @@
</div> </div>
</div> </div>
<Button <Button
shape={'round'} shape={'filter'}
label={view.string.Apply} label={view.string.Apply}
on:click={() => { on:click={() => {
filter.value = Array.from(selectedValues.values()).map((p) => { filter.value = Array.from(selectedValues.values()).map((p) => {

View File

@ -149,7 +149,7 @@
opacity: 1; opacity: 1;
} }
&.hidden { &.hidden {
color: var(--warning-color); color: var(--theme-warning-color);
transform: scale(0.7); transform: scale(0.7);
opacity: 0.5; opacity: 0.5;

View File

@ -134,9 +134,10 @@
</div> </div>
</div> </div>
{/each} {/each}
<div class="flex-grow" />
{:else} {:else}
<!-- Keyboard shortcuts --> <!-- Keyboard shortcuts -->
<Scroller padding={'0 .5rem'} fade={topSP}> <Scroller padding={'0 .5rem'} fade={topSP} noStretch checkForHeaders>
<ListView count={actions.length} noScroll addClass={'rounded'} bind:selection> <ListView count={actions.length} noScroll addClass={'rounded'} bind:selection>
<svelte:fragment slot="category" let:item> <svelte:fragment slot="category" let:item>
{@const action = actions[item]} {@const action = actions[item]}
@ -220,7 +221,7 @@
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
align-items: flex-end; align-items: flex-end;
margin: 0 1rem; margin: 0 0.5rem 0.5rem;
padding-top: 0.625rem; padding-top: 0.625rem;
} }
.key-box { .key-box {