mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
TSK-1323: Fix colors for list (#3069)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
123eb6e3ad
commit
ef987eef56
@ -82,6 +82,27 @@ export function hexColorToNumber (hexColor: string): number {
|
||||
return parseInt(hexColor.replace('#', ''), 16)
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function hexToRgb (color: string): { r: number, g: number, b: number } {
|
||||
if (!color.startsWith('#')) {
|
||||
return { r: 128, g: 128, b: 128 }
|
||||
}
|
||||
color = color.replace('#', '')
|
||||
if (color.length === 3) {
|
||||
color = color
|
||||
.split('')
|
||||
.map((c) => c + c)
|
||||
.join('')
|
||||
}
|
||||
return {
|
||||
r: parseInt(color.slice(0, 2), 16),
|
||||
g: parseInt(color.slice(2, 4), 16),
|
||||
b: parseInt(color.slice(4, 6), 16)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -110,54 +131,106 @@ export function numberToRGB (color: number, alpha?: number): string {
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function hsvToRGB (h: number, s: number, v: number): { r: number, g: number, b: number, rgb: string } {
|
||||
export function hslToRgb (h: number, s: number, l: number): { r: number, g: number, b: number } {
|
||||
s /= 100
|
||||
l /= 100
|
||||
const k = (n: number): number => (n + h / 30) % 12
|
||||
const a = s * Math.min(l, 1 - l)
|
||||
const f = (n: number): number => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)))
|
||||
return { r: 255 * f(0), g: 255 * f(8), b: 255 * f(4) }
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function rgbToHex (color: { r: number, g: number, b: number }): string {
|
||||
function addZero (d: string): string {
|
||||
if (d.length < 2) {
|
||||
return '0' + d
|
||||
}
|
||||
return d
|
||||
}
|
||||
return (
|
||||
'#' +
|
||||
addZero((Math.round(color.r) % 255).toString(16)) +
|
||||
addZero((Math.round(color.g) % 255).toString(16)) +
|
||||
addZero((Math.round(color.b) % 255).toString(16))
|
||||
)
|
||||
}
|
||||
|
||||
export async function svgToColor (img: SVGSVGElement): Promise<{ r: number, g: number, b: number } | undefined> {
|
||||
const outerHTML = img.outerHTML
|
||||
const blob = new Blob([outerHTML], { type: 'image/svg+xml;charset=utf-8' })
|
||||
const blobURL = URL.createObjectURL(blob)
|
||||
const image = new Image()
|
||||
return await new Promise((resolve) => {
|
||||
image.setAttribute('crossOrigin', '')
|
||||
image.src = blobURL
|
||||
image.onload = () => {
|
||||
resolve(imageToColor(image))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export function imageToColor (image: HTMLImageElement): { r: number, g: number, b: number } | undefined {
|
||||
const canvas = document.createElement('canvas')
|
||||
|
||||
const height = (canvas.height = image.naturalHeight ?? image.offsetHeight ?? image.height)
|
||||
const width = (canvas.width = image.naturalWidth ?? image.offsetWidth ?? image.width)
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
|
||||
const blockSize = 5
|
||||
|
||||
let r: number = 0
|
||||
let g: number = 0
|
||||
let b: number = 0
|
||||
const i = Math.floor(h * 6)
|
||||
const f = h * 6 - i
|
||||
const p = v * (1 - s)
|
||||
const q = v * (1 - f * s)
|
||||
const t = v * (1 - (1 - f) * s)
|
||||
switch (i % 6) {
|
||||
case 0:
|
||||
r = v
|
||||
g = t
|
||||
b = p
|
||||
break
|
||||
case 1:
|
||||
r = q
|
||||
g = v
|
||||
b = p
|
||||
break
|
||||
case 2:
|
||||
r = p
|
||||
g = v
|
||||
b = t
|
||||
break
|
||||
case 3:
|
||||
r = p
|
||||
g = q
|
||||
b = v
|
||||
break
|
||||
case 4:
|
||||
r = t
|
||||
g = p
|
||||
b = v
|
||||
break
|
||||
case 5:
|
||||
r = v
|
||||
g = p
|
||||
b = q
|
||||
break
|
||||
let count = 0
|
||||
|
||||
const context = canvas.getContext('2d')
|
||||
|
||||
if (context != null) {
|
||||
context.drawImage(image, 0, 0, width, height)
|
||||
context.beginPath()
|
||||
context.arc(0, 0, 60, 0, Math.PI * 2, true)
|
||||
context.clip()
|
||||
context.fillRect(0, 0, width, height)
|
||||
|
||||
const data = context?.getImageData(0, 0, width, height).data
|
||||
|
||||
const length = data.length
|
||||
|
||||
let i = 0
|
||||
while (i < length) {
|
||||
if (data[i] > 5 && data[i + 1] > 5 && data[i + 2] > 5 && data[i + 3] > 50) {
|
||||
++count
|
||||
r += data[i]
|
||||
g += data[i + 1]
|
||||
b += data[i + 2]
|
||||
}
|
||||
r = Math.round(r * 255)
|
||||
g = Math.round(g * 255)
|
||||
b = Math.round(b * 255)
|
||||
i += blockSize * 4
|
||||
}
|
||||
|
||||
r = Math.round(r / count)
|
||||
g = Math.round(g / count)
|
||||
b = Math.round(b / count)
|
||||
return { r, g, b }
|
||||
}
|
||||
}
|
||||
|
||||
export function rgbToHsl (r: number, g: number, b: number): { h: number, s: number, l: number } {
|
||||
r /= 255
|
||||
g /= 255
|
||||
b /= 255
|
||||
const l = Math.max(r, g, b)
|
||||
const s = l - Math.min(r, g, b)
|
||||
const h = s > 0 ? (l === r ? (g - b) / s : l === g ? 2 + (b - r) / s : 4 + (r - g) / s) : 0
|
||||
return {
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
rgb: '#' + r.toString(16) + g.toString(16) + b.toString(16)
|
||||
h: 60 * h < 0 ? 60 * h + 360 : 60 * h,
|
||||
s: 100 * (s > 0 ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
|
||||
l: (100 * (2 * l - s)) / 2
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
export let size: 'small' | 'medium' | 'large'
|
||||
const fill: string = 'currentColor'
|
||||
export let fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-{size}" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -15,7 +15,7 @@
|
||||
import { Timestamp } from '@hcengineering/core'
|
||||
import type { Asset, IntlString } from '@hcengineering/platform'
|
||||
import { /* Metadata, Plugin, plugin, */ Resource /*, Service */ } from '@hcengineering/platform'
|
||||
import { /* getContext, */ SvelteComponent } from 'svelte'
|
||||
import { /* getContext, */ ComponentType } from 'svelte'
|
||||
|
||||
/**
|
||||
* Describe a browser URI location parsed to path, query and fragment.
|
||||
@ -55,7 +55,7 @@ export function areLocationsEqual (loc1: Location, loc2: Location): boolean {
|
||||
return keys1.findIndex((k) => loc1.query?.[k] !== loc2.query?.[k]) < 0
|
||||
}
|
||||
|
||||
export type AnySvelteComponent = typeof SvelteComponent
|
||||
export type AnySvelteComponent = ComponentType
|
||||
export type Component<C extends AnySvelteComponent> = Resource<C>
|
||||
export type AnyComponent = Resource<AnySvelteComponent>
|
||||
|
||||
|
@ -145,7 +145,7 @@
|
||||
>
|
||||
{#if selected}
|
||||
{#if hideIcon || selected}
|
||||
<UserInfo value={selected} size={kind === 'link' ? 'x-small' : 'tiny'} {icon} />
|
||||
<UserInfo value={selected} size={kind === 'link' ? 'x-small' : 'tiny'} {icon} on:accent-color />
|
||||
{:else}
|
||||
{getName(selected)}
|
||||
{/if}
|
||||
|
@ -31,7 +31,8 @@
|
||||
import { Client, Ref } from '@hcengineering/core'
|
||||
import { Asset, getResource } from '@hcengineering/platform'
|
||||
import { getBlobURL, getClient } from '@hcengineering/presentation'
|
||||
import { AnySvelteComponent, Icon, IconSize } from '@hcengineering/ui'
|
||||
import { AnySvelteComponent, Icon, IconSize, hexToRgb, imageToColor } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { getAvatarProviderId } from '../utils'
|
||||
import AvatarIcon from './icons/Avatar.svelte'
|
||||
|
||||
@ -43,6 +44,8 @@
|
||||
let url: string | undefined
|
||||
let avatarProvider: AvatarProvider | undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
async function update (size: IconSize, avatar?: string | null, direct?: Blob) {
|
||||
if (direct !== undefined) {
|
||||
getBlobURL(direct).then((blobURL) => {
|
||||
@ -78,17 +81,44 @@
|
||||
|
||||
const color = (await getResource(avatarProvider.getUrl))(uri, size)
|
||||
style = `background-color: ${color}`
|
||||
accentColor = hexToRgb(color)
|
||||
dispatch('accent-color', accentColor)
|
||||
}
|
||||
}
|
||||
$: updateStyle(avatar, avatarProvider)
|
||||
|
||||
let imageElement: HTMLImageElement | undefined = undefined
|
||||
let accentColor: any | undefined
|
||||
</script>
|
||||
|
||||
<div class="ava-{size} flex-center avatar-container" class:no-img={!url} {style}>
|
||||
{#if url}
|
||||
{#if size === 'large' || size === 'x-large'}
|
||||
<img class="ava-{size} ava-blur" src={url} alt={''} />
|
||||
<img
|
||||
class="ava-{size} ava-blur"
|
||||
src={url}
|
||||
alt={''}
|
||||
bind:this={imageElement}
|
||||
on:load={(data) => {
|
||||
if (imageElement !== undefined) {
|
||||
accentColor = imageToColor(imageElement)
|
||||
dispatch('accent-color', accentColor)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<img class="ava-{size} ava-mask" src={url} alt={''} />
|
||||
<img
|
||||
class="ava-{size} ava-mask"
|
||||
src={url}
|
||||
alt={''}
|
||||
bind:this={imageElement}
|
||||
on:load={(data) => {
|
||||
if (imageElement !== undefined) {
|
||||
accentColor = imageToColor(imageElement)
|
||||
dispatch('accent-color', accentColor)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<Icon icon={icon ?? AvatarIcon} {size} />
|
||||
{/if}
|
||||
|
@ -38,6 +38,7 @@
|
||||
showNavigate={false}
|
||||
justify={'left'}
|
||||
on:change={({ detail }) => onChange?.(detail)}
|
||||
on:accent-color
|
||||
/>
|
||||
{:else}
|
||||
<EmployeePresenter
|
||||
@ -53,5 +54,6 @@
|
||||
disableClick
|
||||
{colorInherit}
|
||||
{accent}
|
||||
on:accent-color
|
||||
/>
|
||||
{/if}
|
||||
|
@ -38,4 +38,5 @@
|
||||
{accent}
|
||||
{defaultName}
|
||||
statusLabel={value?.active === false && shouldShowName ? contact.string.Inactive : undefined}
|
||||
on:accent-color
|
||||
/>
|
||||
|
@ -17,11 +17,29 @@
|
||||
{#if Array.isArray(value)}
|
||||
<div class="inline-content">
|
||||
{#each value as employee}
|
||||
<EmployeeAttributePresenter value={employee} {kind} {tooltipLabels} {onChange} {inline} {colorInherit} {accent} />
|
||||
<EmployeeAttributePresenter
|
||||
value={employee}
|
||||
{kind}
|
||||
{tooltipLabels}
|
||||
{onChange}
|
||||
{inline}
|
||||
{colorInherit}
|
||||
{accent}
|
||||
on:accent-color
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<EmployeeAttributePresenter {value} {kind} {tooltipLabels} {onChange} {inline} {colorInherit} {accent} />
|
||||
<EmployeeAttributePresenter
|
||||
{value}
|
||||
{kind}
|
||||
{tooltipLabels}
|
||||
{onChange}
|
||||
{inline}
|
||||
{colorInherit}
|
||||
{accent}
|
||||
on:accent-color
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -57,7 +57,7 @@
|
||||
class:mr-2={shouldShowName && !enlargedText}
|
||||
class:mr-3={shouldShowName && enlargedText}
|
||||
>
|
||||
<Avatar size={avatarSize} avatar={value.avatar} />
|
||||
<Avatar size={avatarSize} avatar={value.avatar} on:accent-color />
|
||||
</span>
|
||||
{/if}
|
||||
{#if shouldShowName}
|
||||
@ -79,7 +79,7 @@
|
||||
class:mr-2={shouldShowName && !enlargedText}
|
||||
class:mr-3={shouldShowName && enlargedText}
|
||||
>
|
||||
<Avatar size={avatarSize} />
|
||||
<Avatar size={avatarSize} on:accent-color />
|
||||
</span>
|
||||
{/if}
|
||||
{#if shouldShowName && defaultName}
|
||||
|
@ -78,5 +78,6 @@
|
||||
{colorInherit}
|
||||
{accent}
|
||||
bind:element
|
||||
on:accent-color
|
||||
/>
|
||||
{/if}
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="flex-row-center" on:click>
|
||||
<Avatar avatar={value.avatar} {size} {icon} />
|
||||
<Avatar avatar={value.avatar} {size} {icon} on:accent-color />
|
||||
<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}
|
||||
<div class="content-accent-color overflow-label text-left">{getName(value)}</div>
|
||||
|
@ -26,6 +26,6 @@
|
||||
|
||||
<div class="icon">
|
||||
{#if status}
|
||||
<IssueStatusIcon value={status} size="small" />
|
||||
<IssueStatusIcon value={status} size="small" on:accent-color />
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -1,18 +1,34 @@
|
||||
<script lang="ts">
|
||||
import { StatusCategory } from '@hcengineering/core'
|
||||
import { IconSize } from '@hcengineering/ui'
|
||||
import { IconSize, hexToRgb } from '@hcengineering/ui'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import tracker from '../../plugin'
|
||||
|
||||
export let size: IconSize
|
||||
export let fill: string = 'currentColor'
|
||||
const defaultFill = 'currentColor'
|
||||
export let fill: string = defaultFill
|
||||
export let category: StatusCategory
|
||||
export let statusIcon: {
|
||||
index: number | undefined
|
||||
count: number | undefined
|
||||
} = { index: 0, count: 0 }
|
||||
|
||||
let element: SVGSVGElement
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const dispatchAccentColor = (fill: string) =>
|
||||
dispatch('accent-color', fill !== defaultFill ? hexToRgb(fill) : 'var(--theme-halfcontent-color)')
|
||||
|
||||
$: dispatchAccentColor(fill)
|
||||
|
||||
onMount(() => {
|
||||
dispatchAccentColor(fill)
|
||||
})
|
||||
</script>
|
||||
|
||||
<svg
|
||||
bind:this={element}
|
||||
class="svg-{size}"
|
||||
{fill}
|
||||
id={category._id}
|
||||
|
@ -14,11 +14,10 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import core, { StatusCategory, WithLookup } from '@hcengineering/core'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { createQuery, getClient, statusStore } from '@hcengineering/presentation'
|
||||
import { IssueStatus } from '@hcengineering/tracker'
|
||||
import { getPlatformColor, IconSize } from '@hcengineering/ui'
|
||||
import { IconSize, getPlatformColor } from '@hcengineering/ui'
|
||||
import tracker from '../../plugin'
|
||||
import { statusStore } from '@hcengineering/presentation'
|
||||
import StatusIcon from '../icons/StatusIcon.svelte'
|
||||
|
||||
export let value: WithLookup<IssueStatus>
|
||||
@ -78,5 +77,5 @@
|
||||
</script>
|
||||
|
||||
{#if icon !== undefined && color !== undefined && category !== undefined}
|
||||
<StatusIcon {category} {size} fill={color} {statusIcon} />
|
||||
<StatusIcon on:accent-color {category} {size} fill={color} {statusIcon} />
|
||||
{/if}
|
||||
|
@ -27,7 +27,7 @@
|
||||
{#if value}
|
||||
<div class="flex-presenter cursor-default" style:color={'inherit'}>
|
||||
{#if !inline}
|
||||
<IssueStatusIcon {value} {size} />
|
||||
<IssueStatusIcon {value} {size} on:accent-color />
|
||||
{/if}
|
||||
<span
|
||||
class="overflow-label"
|
||||
|
@ -31,5 +31,6 @@
|
||||
{kind}
|
||||
{colorInherit}
|
||||
{accent}
|
||||
on:accent-color
|
||||
/>
|
||||
{/if}
|
||||
|
@ -13,55 +13,65 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Doc, Ref, Space } from '@hcengineering/core'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import ui, {
|
||||
ActionIcon,
|
||||
AnyComponent,
|
||||
Button,
|
||||
IconAdd,
|
||||
IconCollapseArrow,
|
||||
IconMoreH,
|
||||
Label,
|
||||
hsvToRGB,
|
||||
IconCollapseArrow,
|
||||
deviceOptionsStore as deviceInfo
|
||||
deviceOptionsStore as deviceInfo,
|
||||
eventToHTMLElement,
|
||||
hslToRgb,
|
||||
rgbToHsl,
|
||||
showPopup
|
||||
} from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { noCategory } from '../../viewOptions'
|
||||
import view from '../../plugin'
|
||||
import { Doc, Ref, Space } from '@hcengineering/core'
|
||||
import { AttributeModel } from '@hcengineering/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import view from '../../plugin'
|
||||
import { noCategory } from '../../viewOptions'
|
||||
|
||||
export let groupByKey: string
|
||||
export let category: any
|
||||
export let headerComponent: AttributeModel | undefined
|
||||
export let space: Ref<Space> | undefined
|
||||
export let createItemDialog: AnyComponent | undefined
|
||||
export let createItemLabel: IntlString | undefined
|
||||
export let limited: number
|
||||
export let items: Doc[]
|
||||
export let extraHeaders: AnyComponent[] | undefined
|
||||
export let flat = false
|
||||
export let collapsed = false
|
||||
export let lastCat = false
|
||||
export let props: Record<string, any> = {}
|
||||
export let level: number
|
||||
|
||||
export let createItemDialog: AnyComponent | undefined
|
||||
export let createItemLabel: IntlString | undefined
|
||||
export let extraHeaders: AnyComponent[] | undefined
|
||||
export let props: Record<string, any> = {}
|
||||
export let newObjectProps: (doc: Doc) => Record<string, any> | undefined
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
// const handleCreateItem = (event: MouseEvent) => {
|
||||
// if (createItemDialog === undefined) return
|
||||
// showPopup(createItemDialog, newObjectProps(items[0]), eventToHTMLElement(event))
|
||||
// }
|
||||
const hue = Math.random()
|
||||
$: lth = $deviceInfo.theme === 'theme-light'
|
||||
$: headerBGColor = lth ? hsvToRGB(hue, 0.15, 0.9) : hsvToRGB(hue, 0.15, 0.3)
|
||||
$: headerTextColor = lth ? hsvToRGB(hue, 0.5, 0.5) : hsvToRGB(hue, 0.6, 0.95)
|
||||
|
||||
let accentColor = { h: 0, s: 0, l: 65 }
|
||||
|
||||
$: headerBGColor = !lth
|
||||
? hslToRgb(accentColor.h, accentColor.s, accentColor.l / 1.5 + (mouseOver ? -20 : 0))
|
||||
: hslToRgb(accentColor.h, accentColor.s, accentColor.l * 1.5 + (mouseOver ? -20 : 0))
|
||||
|
||||
const handleCreateItem = (event: MouseEvent) => {
|
||||
if (createItemDialog === undefined) return
|
||||
showPopup(createItemDialog, newObjectProps(items[0]), eventToHTMLElement(event))
|
||||
}
|
||||
let mouseOver = false
|
||||
</script>
|
||||
|
||||
{#if headerComponent || groupByKey === noCategory}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
style:z-index={10 - level}
|
||||
style:--list-header-color={headerBGColor.rgb}
|
||||
style:--list-header-rgb-color={`${headerBGColor.r}, ${headerBGColor.g}, ${headerBGColor.b}`}
|
||||
class="flex-between categoryHeader row"
|
||||
class:gradient={!lth}
|
||||
@ -69,19 +79,30 @@
|
||||
class:collapsed
|
||||
class:subLevel={level !== 0}
|
||||
class:lastCat
|
||||
on:focus={() => {
|
||||
mouseOver = true
|
||||
}}
|
||||
on:mouseenter={() => {
|
||||
mouseOver = true
|
||||
}}
|
||||
on:mouseover={() => {
|
||||
mouseOver = true
|
||||
}}
|
||||
on:mouseleave={() => {
|
||||
mouseOver = false
|
||||
}}
|
||||
on:click={() => dispatch('collapse')}
|
||||
>
|
||||
<div class="flex-row-center clear-mins">
|
||||
{#if level === 0}
|
||||
<div class="chevron"><IconCollapseArrow size={'small'} /></div>
|
||||
{/if}
|
||||
<!-- <FixedColumn key={`list_groupBy_${groupByKey}`} justify={'left'}> -->
|
||||
{#if groupByKey === noCategory}
|
||||
<span style:color={headerTextColor.rgb} class="text-base fs-bold overflow-label pointer-events-none">
|
||||
<span class="text-base fs-bold overflow-label pointer-events-none">
|
||||
<Label label={view.string.NoGrouping} />
|
||||
</span>
|
||||
{:else if headerComponent}
|
||||
<span class="clear-mins" style:color={headerTextColor.rgb}>
|
||||
<span class="clear-mins">
|
||||
<svelte:component
|
||||
this={headerComponent.presenter}
|
||||
value={category}
|
||||
@ -90,17 +111,12 @@
|
||||
kind={'list-header'}
|
||||
colorInherit={lth && level === 0}
|
||||
accent={level === 0}
|
||||
on:accent-color={(evt) => {
|
||||
accentColor = rgbToHsl(evt.detail.r, evt.detail.g, evt.detail.b)
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
{/if}
|
||||
<!-- </FixedColumn> -->
|
||||
<!-- {#if extraHeaders}
|
||||
{#each extraHeaders as extra}
|
||||
<FixedColumn key={`list_groupBy_${groupByKey}_extra_${extra}`} justify={'left'}>
|
||||
<Component is={extra} props={{ ...props, value: category, docs: items }} />
|
||||
</FixedColumn>
|
||||
{/each}
|
||||
{/if} -->
|
||||
{#if limited < items.length}
|
||||
<div class="antiSection-header__counter flex-row-center mx-2">
|
||||
<span class="caption-color">{limited}</span>
|
||||
@ -119,14 +135,16 @@
|
||||
<span class="antiSection-header__counter ml-2">{items.length}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- {#if createItemDialog !== undefined && createItemLabel !== undefined}
|
||||
{#if createItemDialog !== undefined && createItemLabel !== undefined}
|
||||
<div class:on-hover={!mouseOver}>
|
||||
<Button
|
||||
icon={IconAdd}
|
||||
kind={'transparent'}
|
||||
showTooltip={{ label: createItemLabel }}
|
||||
on:click={handleCreateItem}
|
||||
/>
|
||||
{/if} -->
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@ -135,12 +153,16 @@
|
||||
position: relative;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
padding: 0 2.5rem 0 0.75rem;
|
||||
padding: 0 0.75rem 0 0.75rem;
|
||||
height: 2.75rem;
|
||||
min-height: 2.75rem;
|
||||
min-width: 0;
|
||||
background: var(--theme-bg-color);
|
||||
|
||||
.on-hover {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.chevron {
|
||||
flex-shrink: 0;
|
||||
min-width: 0;
|
||||
@ -151,10 +173,14 @@
|
||||
transition: transform 0.15s ease-in-out;
|
||||
}
|
||||
&:not(.gradient)::before {
|
||||
background: var(--list-header-color);
|
||||
background: rgba(var(--list-header-rgb-color), 0.15);
|
||||
}
|
||||
&.gradient::before {
|
||||
background: linear-gradient(90deg, var(--list-header-color), rgba(var(--list-header-rgb-color), 0.3));
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(var(--list-header-rgb-color), 0.15),
|
||||
rgba(var(--list-header-rgb-color), 0.05)
|
||||
);
|
||||
}
|
||||
&::before {
|
||||
box-sizing: border-box;
|
||||
@ -187,7 +213,7 @@
|
||||
border-left: 1px solid var(--theme-list-border-color);
|
||||
border-right: 1px solid var(--theme-list-border-color);
|
||||
border-bottom: 1px solid var(--theme-list-subheader-divider);
|
||||
// here shoul be top 3rem for sticky, but with ExpandCollapse it gives strange behavior
|
||||
// here should be top 3rem for sticky, but with ExpandCollapse it gives strange behavior
|
||||
|
||||
&::before {
|
||||
content: none;
|
||||
@ -206,8 +232,4 @@
|
||||
padding: 0 0.25rem 0 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
// .row:not(:last-child) {
|
||||
// border-bottom: 1px solid var(--accent-bg-color);
|
||||
// }
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user