mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-22 16:27:22 +00:00
UBER-1127: updated status bar layout (#3940)
Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
parent
429574ce1d
commit
cbd7e82e8f
@ -15,28 +15,36 @@
|
||||
<script lang="ts">
|
||||
import platform, { loadPluginStrings, setMetadata } from '@hcengineering/platform'
|
||||
import { onMount, setContext } from 'svelte'
|
||||
import { ThemeOptions, getCurrentFontSize, getCurrentLanguage, getCurrentTheme, themeStore as themeOptions } from './'
|
||||
import {
|
||||
ThemeOptions,
|
||||
getCurrentFontSize,
|
||||
getCurrentLanguage,
|
||||
getCurrentTheme,
|
||||
isThemeDark,
|
||||
themeStore as themeOptions
|
||||
} from './'
|
||||
|
||||
const currentTheme = getCurrentTheme()
|
||||
const currentFontSize = getCurrentFontSize()
|
||||
let currentLanguage = getCurrentLanguage()
|
||||
|
||||
const setOptions = (currentFont: string, theme: string, language: string) => {
|
||||
themeOptions.set(new ThemeOptions(currentFont === 'normal-font' ? 16 : 14, theme === 'theme-dark', language))
|
||||
themeOptions.set(new ThemeOptions(currentFont === 'normal-font' ? 16 : 14, isThemeDark(theme), language))
|
||||
}
|
||||
|
||||
const getRealTheme = (theme: string): string => (isThemeDark(theme) ? 'theme-dark' : 'theme-light')
|
||||
const setRootColors = (theme: string, set = true) => {
|
||||
if (set) {
|
||||
localStorage.setItem('theme', theme)
|
||||
}
|
||||
document.documentElement.setAttribute('class', `${theme} ${getCurrentFontSize()}`)
|
||||
document.documentElement.setAttribute('class', `${getRealTheme(theme)} ${getCurrentFontSize()}`)
|
||||
setOptions(getCurrentFontSize(), theme, getCurrentLanguage())
|
||||
}
|
||||
const setRootFontSize = (fontsize: string, set = true) => {
|
||||
if (set) {
|
||||
localStorage.setItem('fontsize', fontsize)
|
||||
}
|
||||
document.documentElement.setAttribute('class', `${getCurrentTheme()} ${fontsize}`)
|
||||
document.documentElement.setAttribute('class', `${getRealTheme(getCurrentTheme())} ${fontsize}`)
|
||||
setOptions(fontsize, getCurrentTheme(), getCurrentLanguage())
|
||||
}
|
||||
const setLanguage = async (language: string, set: boolean = true) => {
|
||||
|
@ -27,26 +27,33 @@ export const setDefaultLanguage = (language: string): void => {
|
||||
}
|
||||
}
|
||||
|
||||
function isSystemThemeDark (): boolean {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
}
|
||||
|
||||
function getDefaultTheme (): string {
|
||||
return isSystemThemeDark() ? 'theme-dark' : 'theme-light'
|
||||
function getDefaultProps (prop: string, value: string): string {
|
||||
localStorage.setItem(prop, value)
|
||||
return value
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const getCurrentTheme = (): string => localStorage.getItem('theme') ?? getDefaultTheme()
|
||||
export const isSystemThemeDark = (): boolean => window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const getCurrentFontSize = (): string => localStorage.getItem('fontsize') ?? 'normal-font'
|
||||
export const isThemeDark = (theme: string): boolean =>
|
||||
theme === 'theme-dark' || (theme === 'theme-system' && isSystemThemeDark())
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const getCurrentLanguage = (): string => localStorage.getItem('lang') ?? 'en'
|
||||
export const getCurrentTheme = (): string => localStorage.getItem('theme') ?? getDefaultProps('theme', 'theme-system')
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const getCurrentFontSize = (): string =>
|
||||
localStorage.getItem('fontsize') ?? getDefaultProps('fontsize', 'normal-font')
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const getCurrentLanguage = (): string => localStorage.getItem('lang') ?? getDefaultProps('lang', 'en')
|
||||
|
||||
export class ThemeOptions {
|
||||
constructor (readonly fontSize: number, readonly dark: boolean, readonly language: string) {}
|
||||
@ -54,7 +61,7 @@ export class ThemeOptions {
|
||||
export const themeStore = writable<ThemeOptions>(
|
||||
new ThemeOptions(
|
||||
getCurrentFontSize() === 'normal-font' ? 16 : 14,
|
||||
getCurrentTheme() === 'theme-dark',
|
||||
isThemeDark(getCurrentTheme()),
|
||||
getCurrentLanguage()
|
||||
)
|
||||
)
|
||||
|
@ -76,6 +76,8 @@
|
||||
--text-editor-highlighted-node-delete-background-color: #F6DCDA;
|
||||
--text-editor-highlighted-node-delete-font-color: #54201C;
|
||||
|
||||
--theme-clockface-sec-arrow: conic-gradient(at 50% -10px, rgba(255, 0, 0, 0), rgba(255, 0, 0, 0) 49%, #F47758 50%, rgba(255, 0, 0, 0) 51%, rgba(255, 0, 0, 0) 100%);
|
||||
--theme-clockface-sec-holder: #F47758;
|
||||
}
|
||||
|
||||
/* Dark Theme */
|
||||
@ -117,7 +119,7 @@
|
||||
--theme-bg-dark-color: rgba(0, 0, 0, .2);
|
||||
--theme-back-color: #0f0f18;
|
||||
--theme-overlay-color: rgba(0, 0, 0, .3);
|
||||
--theme-statusbar-color: #2C2C35;
|
||||
--theme-statusbar-color: #1A1928;
|
||||
--theme-navpanel-color: #14141F;
|
||||
--theme-navpanel-hovered: rgba(255, 255, 255, .04);
|
||||
--theme-navpanel-selected: rgba(255, 255, 255, .08);
|
||||
@ -173,6 +175,7 @@
|
||||
--theme-popup-divider: rgba(255, 255, 255, .09);
|
||||
--theme-popup-header: #3A3A47;
|
||||
--theme-popup-shadow: 0 0 .5rem rgba(0, 0, 0, .2);
|
||||
--theme-popup-checkicon: #FFFFFF99;
|
||||
--theme-panel-color: #1A1A28;
|
||||
--theme-calendar-today-color: #fff;
|
||||
--theme-calendar-holiday-color: #eb5757;
|
||||
@ -285,6 +288,14 @@
|
||||
|
||||
--text-editor-toc-default-color: rgba(255, 255, 255, 0.1);
|
||||
--text-editor-toc-hovered-color: rgba(255, 255, 255, 0.4);
|
||||
|
||||
--theme-clockface-back: radial-gradient(farthest-corner at 50% 0%, #bbb, #fff 100%);
|
||||
--theme-clockface-shadow: inset 0 -3px 10px #aaa;
|
||||
--theme-clockface-hours: #666;
|
||||
--theme-clockface-quarter: #31302e;
|
||||
--theme-clockface-min-arrow: conic-gradient(at 50% -10px, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0) 49%, #2F2F3A 50%, rgba(0, 0, 0, 0) 51%, rgba(0, 0, 0, 0) 100%);
|
||||
--theme-clockface-arrows-holder: radial-gradient(at top center, #2F2F3A, #555555);
|
||||
--theme-clockface-arrows-shadow: 0 0 1px white;
|
||||
}
|
||||
|
||||
/* Light Theme */
|
||||
@ -326,7 +337,7 @@
|
||||
--theme-bg-dark-color: rgba(255, 255, 255, .8);
|
||||
--theme-back-color: #D9D9DD;
|
||||
--theme-overlay-color: rgba(0, 0, 0, .2);
|
||||
--theme-statusbar-color: #bfbfc6;
|
||||
--theme-statusbar-color: #FFF;
|
||||
--theme-navpanel-color: #FBFBFC;
|
||||
--theme-navpanel-hovered: rgba(0, 0, 0, .04);
|
||||
--theme-navpanel-selected: rgba(0, 0, 0, .08);
|
||||
@ -382,6 +393,7 @@
|
||||
--theme-popup-divider: rgba(0, 0, 0, .09);
|
||||
--theme-popup-header: #EBEBEB;
|
||||
--theme-popup-shadow: 0 0 .5rem rgba(0, 0, 0, .2);
|
||||
--theme-popup-checkicon: #205DC2;
|
||||
--theme-panel-color: #FFFFFF;
|
||||
--theme-calendar-today-color: #000;
|
||||
--theme-calendar-holiday-color: #eb5757;
|
||||
@ -494,4 +506,12 @@
|
||||
|
||||
--text-editor-toc-default-color: rgba(0, 0, 0, 0.1);
|
||||
--text-editor-toc-hovered-color: rgba(0, 0, 0, 0.4);
|
||||
|
||||
--theme-clockface-back: radial-gradient(farthest-corner at 50% 0%, #606060, #000 100%);
|
||||
--theme-clockface-shadow: inset 0 -3px 10px #000;
|
||||
--theme-clockface-hours: #999;
|
||||
--theme-clockface-quarter: #CECFD1;
|
||||
--theme-clockface-min-arrow: conic-gradient(at 50% -10px, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0) 49%, white 50%, rgba(255, 255, 255, 0) 51%, rgba(255, 255, 255, 0) 100%);
|
||||
--theme-clockface-arrows-holder: radial-gradient(at top center, #eee, #aaa);
|
||||
--theme-clockface-arrows-shadow: 0 0 1px black;
|
||||
}
|
||||
|
@ -444,6 +444,7 @@ input.search {
|
||||
.gapV-12 > *:not(:last-child) { margin-bottom: 3rem; }
|
||||
.gap-around-2 > * { margin: .25rem; }
|
||||
.gap-around-4 > * { margin: .5rem; }
|
||||
.gap-statusbar > *:not(:last-child) { margin-right: 12px; }
|
||||
|
||||
/* --------- */
|
||||
.sm-tool-icon {
|
||||
@ -686,6 +687,7 @@ input.search {
|
||||
.min-w-8 { min-width: 2rem; }
|
||||
.min-w-9 { min-width: 2.25rem; }
|
||||
.min-w-12 { min-width: 3rem; }
|
||||
.min-w-50 { min-width: 12.5rem; }
|
||||
.min-w-60 { min-width: 15rem; }
|
||||
.min-w-80 { min-width: 20rem; }
|
||||
.min-w-100 { min-width: 25rem; }
|
||||
@ -818,6 +820,7 @@ a.no-line {
|
||||
color: var(--theme-dark-color);
|
||||
user-select: none;
|
||||
}
|
||||
.text-16px { font-size: 16px; }
|
||||
.text-xs { font-size: .625rem; }
|
||||
.text-11px { font-size: .6875rem; }
|
||||
.text-sm { font-size: .75rem; }
|
||||
@ -837,7 +840,9 @@ a.no-line {
|
||||
.lower { text-transform: lowercase; }
|
||||
.text-left { text-align: left; }
|
||||
.text-center { text-align: center; }
|
||||
.leading-16px { line-height: 16px; }
|
||||
.leading-3 { line-height: .75rem; }
|
||||
.tracking--05px { letter-spacing: -.5px; }
|
||||
.tracking-1px { letter-spacing: 1px; }
|
||||
|
||||
.over-underline {
|
||||
|
@ -60,6 +60,7 @@
|
||||
&.short { max-width: 8.5rem; }
|
||||
&.accent { font-weight: 500; }
|
||||
&.sh-no-shape { border-radius: .375rem; }
|
||||
&.sh-round-small { border-radius: .25rem; }
|
||||
&.sh-round { border-radius: .5rem; }
|
||||
&.sh-round2 { border-radius: .75rem; }
|
||||
&.sh-circle { border-radius: 1rem; }
|
||||
@ -86,6 +87,7 @@
|
||||
|
||||
&.bs-solid { border-style: solid; }
|
||||
&.bs-dashed { border-style: dashed; }
|
||||
&.bs-none { border: none; }
|
||||
&.jf-left { justify-content: flex-start; }
|
||||
&.jf-center { justify-content: center; }
|
||||
&.only-icon {
|
||||
@ -99,7 +101,9 @@
|
||||
border-color: var(--theme-button-border);
|
||||
|
||||
&:hover { background-color: var(--theme-button-hovered); }
|
||||
&:active { background-color: var(--theme-button-pressed); }
|
||||
&:active,
|
||||
&.pressed,
|
||||
&.pressed:hover { background-color: var(--theme-button-pressed); }
|
||||
&:focus {
|
||||
background-color: var(--theme-button-focused);
|
||||
border-color: var(--theme-button-focused-border);
|
||||
@ -137,7 +141,9 @@
|
||||
}
|
||||
&.ghost, &.stepper {
|
||||
&:hover { background-color: var(--theme-button-hovered); }
|
||||
&:active { background-color: var(--theme-button-pressed); }
|
||||
&:active,
|
||||
&.pressed,
|
||||
&.pressed:hover { background-color: var(--theme-button-pressed); }
|
||||
&.selected { background-color: var(--highlight-select); }
|
||||
&.selected:hover { background-color: var(--highlight-select-hover); }
|
||||
}
|
||||
@ -200,7 +206,7 @@
|
||||
}
|
||||
}
|
||||
&.regular, &.ghost {
|
||||
&:hover, &:active, &:focus { color: var(--theme-caption-color); }
|
||||
&:hover, &:active, &.pressed, &.pressed:hover, &:focus { color: var(--theme-caption-color); }
|
||||
}
|
||||
&.primary,
|
||||
&.secondary,
|
||||
@ -218,7 +224,9 @@
|
||||
background-color: var(--primary-button-default);
|
||||
|
||||
&:hover { background-color: var(--primary-button-hovered); }
|
||||
&:active { background-color: var(--primary-button-pressed); }
|
||||
&:active,
|
||||
&.pressed,
|
||||
&.pressed:hover { background-color: var(--primary-button-pressed); }
|
||||
&:focus { background-color: var(--primary-button-focused); }
|
||||
&:disabled {
|
||||
color: var(--primary-button-disabled-color);
|
||||
@ -231,7 +239,9 @@
|
||||
&.secondary {
|
||||
background-color: var(--secondary-button-default);
|
||||
&:hover { background-color: var(--secondary-button-hovered); }
|
||||
&:active { background-color: var(--secondary-button-pressed); }
|
||||
&:active,
|
||||
&.pressed,
|
||||
&.pressed:hover { background-color: var(--secondary-button-pressed); }
|
||||
&:focus { background-color: var(--secondary-button-focused); }
|
||||
&:disabled {
|
||||
color: var(--secondary-button-disabled-color);
|
||||
@ -241,7 +251,9 @@
|
||||
&.positive {
|
||||
background-color: var(--positive-button-default);
|
||||
&:hover { background-color: var(--positive-button-hovered); }
|
||||
&:active { background-color: var(--positive-button-pressed); }
|
||||
&:active,
|
||||
&.pressed,
|
||||
&.pressed:hover { background-color: var(--positive-button-pressed); }
|
||||
&:focus { background-color: var(--positive-button-focused); }
|
||||
&:disabled {
|
||||
color: var(--positive-button-disabled-color);
|
||||
@ -251,7 +263,9 @@
|
||||
&.negative {
|
||||
background-color: var(--negative-button-default);
|
||||
&:hover { background-color: var(--negative-button-hovered); }
|
||||
&:active { background-color: var(--negative-button-pressed); }
|
||||
&:active,
|
||||
&.pressed,
|
||||
&.pressed:hover { background-color: var(--negative-button-pressed); }
|
||||
&:focus { background-color: var(--negative-button-focused); }
|
||||
&:disabled {
|
||||
color: var(--negative-button-disabled-color);
|
||||
@ -269,7 +283,9 @@
|
||||
.btn-right-icon { color: var(--theme-button-contrast-color); }
|
||||
|
||||
&:hover { background-color: var(--theme-button-contrast-hovered); }
|
||||
&:active { background-color: var(--theme-button-contrast-pressed); }
|
||||
&:active,
|
||||
&.pressed,
|
||||
&.pressed:hover { background-color: var(--theme-button-contrast-pressed); }
|
||||
&:focus { background-color: var(--theme-button-contrast-hovered); }
|
||||
&:disabled {
|
||||
color: var(--theme-button-contrast-disabled-color);
|
||||
@ -311,5 +327,20 @@
|
||||
.btn-right-icon { opacity: .5; }
|
||||
}
|
||||
|
||||
.resetIconSize { font-size: 16px; }
|
||||
}
|
||||
.resetIconSize,
|
||||
&.resetIconSize { font-size: 16px !important; }
|
||||
|
||||
&.statusButton {
|
||||
padding: 0 8px;
|
||||
height: 20px;
|
||||
min-width: 20px;
|
||||
font-size: 13px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.square {
|
||||
flex-shrink: 0;
|
||||
padding: 2px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,6 +271,31 @@
|
||||
padding: .5rem 0 1.25rem;
|
||||
}
|
||||
|
||||
/* Statusbar - Popup */
|
||||
.statusPopup-option {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
&:not(:last-child) { margin-right: 12px; }
|
||||
|
||||
.label {
|
||||
margin-top: .5rem;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
color: var(--theme-darker-color);
|
||||
}
|
||||
|
||||
&:hover .label { color: var(--theme-dark-color); }
|
||||
&.selected .label {
|
||||
font-weight: 600;
|
||||
color: var(--theme-content-color);
|
||||
}
|
||||
&:not(.selected) { cursor: pointer; }
|
||||
}
|
||||
|
||||
/* Basic */
|
||||
.antiGrid {
|
||||
display: flex;
|
||||
|
@ -71,12 +71,14 @@
|
||||
scrollbar-color: var(--theme-comp-header-color) var(--theme-back-color);
|
||||
scrollbar-width: none;
|
||||
--body-font-size: .875rem;
|
||||
--status-bar-height: 36px;
|
||||
--panel-aside-width: 25rem; // 20rem;
|
||||
--font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto;
|
||||
--mono-font: 'IBM Plex Mono', monospace;
|
||||
--timing-shadow: cubic-bezier(0,.65,.35,1);
|
||||
--timing-main: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
--timing-rotate: cubic-bezier(.28,1.92,.39,.56);
|
||||
--timing-clock: cubic-bezier(.35,2.1,.79,.71);
|
||||
// transition-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
|
||||
&::after,
|
||||
|
@ -358,7 +358,7 @@
|
||||
&.halfMargin { margin: .25rem 0; }
|
||||
}
|
||||
}
|
||||
&:not(.thinStyle) .ap-menuItem:not(.separator, .withComp) { padding: .25rem .5rem; }
|
||||
&:not(.thinStyle) .ap-menuItem:not(.separator, .withComp) { padding: .625rem .5rem; }
|
||||
&.thinStyle {
|
||||
border-radius: .75rem;
|
||||
|
||||
@ -378,7 +378,7 @@
|
||||
margin-left: 1rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
color: var(--theme-dark-color);
|
||||
color: var(--theme-popup-checkicon);
|
||||
}
|
||||
.ap-subheader {
|
||||
flex-shrink: 0;
|
||||
|
@ -61,6 +61,11 @@
|
||||
"TravelAndPlaces": "Travel & Places",
|
||||
"Objects": "Objects",
|
||||
"Food": "Food",
|
||||
"MoreCount": "{count} more"
|
||||
"MoreCount": "{count} more",
|
||||
"Spacious": "Spacious",
|
||||
"Compact": "Compact",
|
||||
"ThemeLight": "Light",
|
||||
"ThemeDark": "Dark",
|
||||
"ThemeSystem": "System"
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,11 @@
|
||||
"TravelAndPlaces": "Путешествия & Места",
|
||||
"Objects": "Объекты",
|
||||
"Food": "Еда",
|
||||
"MoreCount": "Ещё {count}"
|
||||
"MoreCount": "Ещё {count}",
|
||||
"Spacious": "Просторный",
|
||||
"Compact": "Компактный",
|
||||
"ThemeLight": "Светлая",
|
||||
"ThemeDark": "Тёмная",
|
||||
"ThemeSystem": "Системная"
|
||||
}
|
||||
}
|
||||
|
@ -46,14 +46,15 @@
|
||||
export let loading: boolean = false
|
||||
export let width: string | undefined = undefined
|
||||
export let height: string | undefined = undefined
|
||||
export let resetIconSize: boolean = false
|
||||
export let resetIconSize: 'none' | 'icon' | 'full' = 'none'
|
||||
export let highlight: boolean = false
|
||||
export let pressed: boolean = false
|
||||
export let selected: boolean = false
|
||||
export let notSelected: boolean = false
|
||||
export let focus: boolean = false
|
||||
export let click: boolean = false
|
||||
export let title: string | undefined = undefined
|
||||
export let borderStyle: 'solid' | 'dashed' = 'solid'
|
||||
export let borderStyle: 'solid' | 'dashed' | 'none' = 'solid'
|
||||
export let id: string | undefined = undefined
|
||||
export let input: HTMLButtonElement | undefined = undefined
|
||||
export let showTooltip: LabelAndProps | undefined = undefined
|
||||
@ -121,12 +122,14 @@
|
||||
class:no-focus={noFocus}
|
||||
class:accent
|
||||
class:highlight
|
||||
class:pressed
|
||||
class:selected
|
||||
class:notSelected
|
||||
class:iconL={(icon || $$slots.icon) && (label || $$slots.content)}
|
||||
class:iconR={(iconRight || $$slots.iconRight) && (label || $$slots.content)}
|
||||
disabled={disabled || loading}
|
||||
class:short
|
||||
class:resetIconSize={resetIconSize === 'full'}
|
||||
style:width
|
||||
style:height
|
||||
style:flex-shrink={shrink}
|
||||
@ -141,14 +144,14 @@
|
||||
{id}
|
||||
>
|
||||
{#if icon && !loading}
|
||||
<div class="btn-icon pointer-events-none" class:resetIconSize>
|
||||
<div class="btn-icon pointer-events-none" class:resetIconSize={resetIconSize === 'icon'}>
|
||||
<Icon bind:icon size={iconSize} {iconProps} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if loading}
|
||||
<div
|
||||
class="btn-icon pointer-events-none spinner"
|
||||
class:resetIconSize
|
||||
class:resetIconSize={resetIconSize === 'icon'}
|
||||
style:color={primary ? 'var(--primary-button-color)' : 'var(--theme-caption-color)'}
|
||||
>
|
||||
<Spinner size={iconSize === 'inline' ? 'inline' : 'small'} />
|
||||
@ -160,7 +163,7 @@
|
||||
</span>
|
||||
{/if}
|
||||
{#if iconRight}
|
||||
<div class="btn-right-icon pointer-events-none" class:resetIconSize>
|
||||
<div class="btn-right-icon pointer-events-none" class:resetIconSize={resetIconSize === 'icon'}>
|
||||
<Icon bind:icon={iconRight} size={iconRightSize} iconProps={iconRightProps} />
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -126,3 +126,7 @@ export const getDueDateIconModifier = (
|
||||
export function getFormattedDate (value: number | null): string {
|
||||
return value === null ? '' : new Date(value).toLocaleString('default', { month: 'short', day: 'numeric' })
|
||||
}
|
||||
|
||||
export const getTimeZoneName = (): string => {
|
||||
return Intl.DateTimeFormat().resolvedOptions().timeZone.split('/')[1]
|
||||
}
|
||||
|
@ -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}" viewBox="0 0 16 16" {fill} xmlns="http://www.w3.org/2000/svg">
|
||||
|
@ -1,9 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { onDestroy } from 'svelte'
|
||||
import { showPopup, getTimeZoneName } from '../..'
|
||||
import ClockPopup from './ClockPopup.svelte'
|
||||
|
||||
let hours = ''
|
||||
let minutes = ''
|
||||
let delimiter = false
|
||||
let delimiter: boolean = false
|
||||
let pressed: boolean = false
|
||||
|
||||
function updateTime () {
|
||||
const date = new Date()
|
||||
@ -20,8 +23,18 @@
|
||||
onDestroy(() => clearInterval(interval))
|
||||
</script>
|
||||
|
||||
<div style="min-width: 40px">
|
||||
<button
|
||||
class="antiButton ghost jf-center bs-none no-focus statusButton"
|
||||
class:pressed
|
||||
on:click={(ev) => {
|
||||
pressed = true
|
||||
showPopup(ClockPopup, {}, 'status', () => {
|
||||
pressed = false
|
||||
})
|
||||
}}
|
||||
>
|
||||
<span>{getTimeZoneName()}</span>
|
||||
<span>{hours}</span>
|
||||
<span style="visibility: {delimiter ? 'visible' : 'hidden'}">:</span>
|
||||
<span style:visibility={delimiter ? 'visible' : 'hidden'}>:</span>
|
||||
<span>{minutes}</span>
|
||||
</div>
|
||||
</button>
|
||||
|
140
packages/ui/src/components/internal/ClockFace.svelte
Normal file
140
packages/ui/src/components/internal/ClockFace.svelte
Normal file
@ -0,0 +1,140 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { onDestroy } from 'svelte'
|
||||
|
||||
const clock: Array<{ value: number; class: string }> = [
|
||||
{ value: 0, class: 'hour-arrow' },
|
||||
{ value: 0, class: 'minute-arrow' },
|
||||
{ value: 0, class: 'second-arrow' }
|
||||
]
|
||||
let reqId: any
|
||||
|
||||
const updateTime = (): void => {
|
||||
const now = new Date()
|
||||
const startDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0).getTime()
|
||||
const diff = now.getTime() - startDay
|
||||
let h = diff / 3600000
|
||||
if (h > 12) h -= 12
|
||||
const m = (diff / 1000 / 60) % 60
|
||||
const s = (diff / 1000) % 60
|
||||
clock[0].value = h * 30
|
||||
clock[1].value = m * 6
|
||||
clock[2].value = s * 6
|
||||
setTimeout(() => (reqId = requestAnimationFrame(updateTime)), 1000 / 25)
|
||||
}
|
||||
|
||||
reqId = requestAnimationFrame(updateTime)
|
||||
onDestroy(() => clearInterval(reqId))
|
||||
</script>
|
||||
|
||||
<div class="clockFace-container">
|
||||
{#each [...Array(12).keys()] as hour}
|
||||
<div class="hour" data-hour={hour === 0 ? '12' : `${hour}`} />
|
||||
{/each}
|
||||
{#each clock as arrow}
|
||||
<div class={arrow.class} style:transform={`rotate(${arrow.value}deg)`} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.hour {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
left: 50%;
|
||||
width: 1px;
|
||||
height: 2px;
|
||||
background: var(--theme-clockface-hours);
|
||||
transform-origin: 50% 29px;
|
||||
transform: rotate(0deg);
|
||||
|
||||
@for $i from 2 through 12 {
|
||||
&:nth-child(#{$i}) {
|
||||
transform: rotate(#{$i * 30 - 30}deg);
|
||||
}
|
||||
}
|
||||
&:nth-child(3n + 1) {
|
||||
height: 5px;
|
||||
background: var(--theme-clockface-quarter);
|
||||
}
|
||||
}
|
||||
|
||||
.clockFace-container {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: var(--theme-clockface-back);
|
||||
border-radius: 50%;
|
||||
box-shadow: var(--theme-clockface-shadow);
|
||||
|
||||
.second-arrow,
|
||||
.minute-arrow,
|
||||
.hour-arrow {
|
||||
position: absolute;
|
||||
left: calc(50% - 0.5px);
|
||||
box-shadow: va(--theme-clockface-arrows-shadow);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
.anim {
|
||||
transition-property: transform;
|
||||
transition-timing-function: var(--timing-clock);
|
||||
transition-duration: 0.25s;
|
||||
}
|
||||
.second-arrow {
|
||||
top: 2px;
|
||||
width: 2px;
|
||||
height: 34px;
|
||||
background: var(--theme-clockface-sec-arrow);
|
||||
transform-origin: 50% 28px;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
border-radius: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
&::before {
|
||||
top: 25px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
background-color: var(--theme-clockface-sec-holder);
|
||||
}
|
||||
&::after {
|
||||
top: 26px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
background: var(--theme-clockface-arrows-holder);
|
||||
}
|
||||
}
|
||||
.minute-arrow {
|
||||
top: 4px;
|
||||
width: 2px;
|
||||
height: 32px;
|
||||
background: var(--theme-clockface-min-arrow);
|
||||
transform-origin: 50% 26px;
|
||||
}
|
||||
.hour-arrow {
|
||||
top: 12px;
|
||||
left: calc(50% - 1px);
|
||||
width: 3px;
|
||||
height: 24px;
|
||||
background: var(--theme-clockface-min-arrow);
|
||||
transform-origin: 50% 18px;
|
||||
}
|
||||
}
|
||||
</style>
|
27
packages/ui/src/components/internal/ClockPopup.svelte
Normal file
27
packages/ui/src/components/internal/ClockPopup.svelte
Normal file
@ -0,0 +1,27 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { getTimeZoneName } from '../..'
|
||||
import ClockFace from './ClockFace.svelte'
|
||||
</script>
|
||||
|
||||
<div class="antiPopup" style:flex-direction={'row'} style:padding={'12px'}>
|
||||
<div class="statusPopup-option">
|
||||
<ClockFace />
|
||||
<span class="label overflow-label">
|
||||
{getTimeZoneName()}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
55
packages/ui/src/components/internal/FontSizeButton.svelte
Normal file
55
packages/ui/src/components/internal/FontSizeButton.svelte
Normal file
@ -0,0 +1,55 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte'
|
||||
import FontSize from './icons/FontSize.svelte'
|
||||
|
||||
export let size: string
|
||||
export let focused: string
|
||||
|
||||
let btn: HTMLButtonElement
|
||||
|
||||
onMount(() => {
|
||||
if (focused === size) btn.focus()
|
||||
})
|
||||
</script>
|
||||
|
||||
<button
|
||||
bind:this={btn}
|
||||
class="antiButton regular sh-no-shape jf-center bs-solid no-focus statusPopupButton"
|
||||
class:focused={focused === size}
|
||||
>
|
||||
<FontSize size={size === 'small-font' ? '20px' : '28px'} />
|
||||
</button>
|
||||
|
||||
<style lang="scss">
|
||||
.statusPopupButton {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 6px;
|
||||
|
||||
&.focused::before,
|
||||
&:focus::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
inset: -3px;
|
||||
border: 1px solid var(--primary-button-default);
|
||||
border-radius: 8.5px;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
</style>
|
43
packages/ui/src/components/internal/FontSizePopup.svelte
Normal file
43
packages/ui/src/components/internal/FontSizePopup.svelte
Normal file
@ -0,0 +1,43 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
import FontSizeButton from './FontSizeButton.svelte'
|
||||
import { Label, deviceOptionsStore as deviceInfo } from '../..'
|
||||
|
||||
export let fontsizes: Array<{ id: string; label: IntlString; size: number }>
|
||||
export let selected: string = ''
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const select = (size: string): void => {
|
||||
if (selected === size) return
|
||||
selected = size
|
||||
dispatch('close', size)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiPopup" style:flex-direction={'row'} style:padding={'12px'}>
|
||||
{#each fontsizes as font}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="statusPopup-option" class:selected={selected === font.id} on:click={() => select(font.id)}>
|
||||
<FontSizeButton size={font.id} focused={selected} />
|
||||
<span class="label overflow-label" class:tracking--05px={$deviceInfo.language === 'ru'}>
|
||||
<Label label={font.label} />
|
||||
</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
@ -14,28 +14,45 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import ui, { popupstore, showPopup, deviceOptionsStore as deviceInfo } from '../..'
|
||||
import FontSize from './icons/FontSize.svelte'
|
||||
import { popupstore } from '../../popups'
|
||||
import { deviceOptionsStore as deviceInfo } from '../..'
|
||||
import FontSizePopup from './FontSizePopup.svelte'
|
||||
|
||||
const { currentFontSize, setFontSize } = getContext('fontsize') as {
|
||||
currentFontSize: string
|
||||
setFontSize: (size: string) => void
|
||||
}
|
||||
|
||||
const fontsizes = ['small-font', 'normal-font']
|
||||
const fontsizes: Array<{ id: string; label: IntlString; size: number }> = [
|
||||
{ id: 'normal-font', label: ui.string.Spacious, size: 16 },
|
||||
{ id: 'small-font', label: ui.string.Compact, size: 14 }
|
||||
]
|
||||
let pressed: boolean = false
|
||||
let btn: HTMLButtonElement
|
||||
|
||||
let current = fontsizes.indexOf(currentFontSize)
|
||||
let current = fontsizes.findIndex((fs) => fs.id === currentFontSize)
|
||||
|
||||
function changeFontSize () {
|
||||
current++
|
||||
setFontSize(fontsizes[current % fontsizes.length])
|
||||
$popupstore = $popupstore
|
||||
function changeFontSize (ev: MouseEvent) {
|
||||
pressed = true
|
||||
showPopup(FontSizePopup, { fontsizes, selected: fontsizes[current].id }, btn, (result) => {
|
||||
if (result) {
|
||||
setFontSize(result)
|
||||
current = fontsizes.findIndex((fs) => fs.id === result)
|
||||
$popupstore = $popupstore
|
||||
}
|
||||
pressed = false
|
||||
})
|
||||
}
|
||||
$: $deviceInfo.fontSize = fontsizes[current % fontsizes.length] === 'normal-font' ? 16 : 14
|
||||
$: $deviceInfo.fontSize = fontsizes[current].size
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="flex-center" on:click={changeFontSize}>
|
||||
<button
|
||||
bind:this={btn}
|
||||
class="antiButton ghost jf-center bs-none no-focus resetIconSize statusButton square"
|
||||
class:pressed
|
||||
style:color={'var(--theme-dark-color)'}
|
||||
on:click={changeFontSize}
|
||||
>
|
||||
<FontSize />
|
||||
</div>
|
||||
</button>
|
||||
|
@ -15,26 +15,31 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import Label from '../Label.svelte'
|
||||
import IconCheck from '../icons/Check.svelte'
|
||||
|
||||
export let langs: any
|
||||
export let selected: string
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
<div class="antiPopup">
|
||||
<div class="antiPopup" style:min-width={'200px'}>
|
||||
<div class="ap-space x2" />
|
||||
{#each langs as lang}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="ap-menuItem hoverable flex-row-center"
|
||||
class="ap-menuItem hoverable flex-row-center leading-16px"
|
||||
on:click={() => {
|
||||
dispatch('close', lang.id)
|
||||
}}
|
||||
>
|
||||
<svg class="svg-small">
|
||||
<use href="#{lang.id}-flag" />
|
||||
</svg>
|
||||
<div class="ml-2"><Label label={lang.label} /></div>
|
||||
<div class="svg-16px flex-no-shrink text-16px mr-2">{@html lang.logo}</div>
|
||||
<span class="overflow-label flex-grow"><Label label={lang.label} /></span>
|
||||
<div class="ap-check">
|
||||
{#if lang.id === selected}
|
||||
<IconCheck size={'small'} fill={'var(--primary-button-default)'} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="ap-space x2" />
|
||||
|
@ -17,9 +17,9 @@
|
||||
import { getMetadata } from '@hcengineering/platform'
|
||||
import { showPopup } from '../..'
|
||||
import LangPopup from './LangPopup.svelte'
|
||||
import ui from '../../plugin'
|
||||
import ui, { deviceOptionsStore as deviceInfo } from '../..'
|
||||
|
||||
import Flags from './icons/Flags.svelte'
|
||||
let pressed: boolean = false
|
||||
|
||||
const { currentLanguage, setLanguage } = getContext('lang') as {
|
||||
currentLanguage: string
|
||||
@ -27,8 +27,8 @@
|
||||
}
|
||||
const uiLangs = new Set(getMetadata(ui.metadata.Languages))
|
||||
const langs = [
|
||||
{ id: 'en', label: ui.string.English },
|
||||
{ id: 'ru', label: ui.string.Russian }
|
||||
{ id: 'en', label: ui.string.English, logo: '🇺🇸' },
|
||||
{ id: 'ru', label: ui.string.Russian, logo: '🇷🇺' }
|
||||
].filter((lang) => uiLangs.has(lang.id))
|
||||
|
||||
if (langs.findIndex((l) => l.id === currentLanguage) < 0 && langs.length !== 0) {
|
||||
@ -46,28 +46,28 @@
|
||||
const isSelectable = langs.length > 1
|
||||
|
||||
$: selected = langs.find((item) => item.id === currentLanguage)
|
||||
let trigger: HTMLElement
|
||||
|
||||
const selectLanguage = (): void => {
|
||||
if (!isSelectable) {
|
||||
return
|
||||
}
|
||||
pressed = true
|
||||
|
||||
showPopup(LangPopup, { langs }, trigger, (result) => {
|
||||
showPopup(LangPopup, { langs, selected: selected?.id }, 'status', (result) => {
|
||||
if (result) {
|
||||
selected = langs.find((item) => item.id === result)
|
||||
setLanguage(result)
|
||||
}
|
||||
pressed = false
|
||||
})
|
||||
}
|
||||
$: $deviceInfo.language = selected?.id
|
||||
</script>
|
||||
|
||||
<Flags />
|
||||
{#if selected}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div bind:this={trigger} class="flex-center {isSelectable ? 'cursor-pointer' : ''}" on:click={selectLanguage}>
|
||||
<svg class="svg-16px">
|
||||
<use href="#{selected.id}-flag" />
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
<button
|
||||
class="antiButton ghost jf-center bs-none no-focus resetIconSize statusButton square"
|
||||
class:pressed
|
||||
on:click={selectLanguage}
|
||||
>
|
||||
{@html selected?.logo}
|
||||
</button>
|
||||
|
@ -12,13 +12,17 @@
|
||||
import StatusComponent from '../Status.svelte'
|
||||
import Clock from './Clock.svelte'
|
||||
// import Mute from './icons/Mute.svelte'
|
||||
import { checkMobile, deviceOptionsStore as deviceInfo, networkStatus } from '../../'
|
||||
import {
|
||||
checkMobile,
|
||||
deviceOptionsStore as deviceInfo
|
||||
// networkStatus
|
||||
} from '../../'
|
||||
import uiPlugin from '../../plugin'
|
||||
import Label from '../Label.svelte'
|
||||
import FontSizeSelector from './FontSizeSelector.svelte'
|
||||
import Computer from './icons/Computer.svelte'
|
||||
import Phone from './icons/Phone.svelte'
|
||||
import WiFi from './icons/WiFi.svelte'
|
||||
// import Computer from './icons/Computer.svelte'
|
||||
// import Phone from './icons/Phone.svelte'
|
||||
// import WiFi from './icons/WiFi.svelte'
|
||||
import LangSelector from './LangSelector.svelte'
|
||||
import ThemeSelector from './ThemeSelector.svelte'
|
||||
|
||||
@ -76,7 +80,7 @@
|
||||
let docHeight: number = window.innerHeight
|
||||
|
||||
let isMobile: boolean
|
||||
let alwaysMobile: boolean = false
|
||||
const alwaysMobile: boolean = false
|
||||
$: isMobile = alwaysMobile || checkMobile()
|
||||
let isPortrait: boolean
|
||||
$: isPortrait = docWidth <= docHeight
|
||||
@ -159,17 +163,12 @@
|
||||
<div class="clock">
|
||||
<Clock />
|
||||
</div>
|
||||
<div class="flex-center widget">
|
||||
<div class="flex-row-center gap-statusbar">
|
||||
<FontSizeSelector />
|
||||
<ThemeSelector />
|
||||
<LangSelector />
|
||||
</div>
|
||||
<div class="flex-center widget cursor-pointer">
|
||||
<ThemeSelector />
|
||||
</div>
|
||||
<div class="flex-center widget cursor-pointer">
|
||||
<FontSizeSelector />
|
||||
</div>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
<!-- <div
|
||||
class="flex-center widget"
|
||||
class:rotated={!isPortrait && isMobile}
|
||||
on:click={() => {
|
||||
@ -183,7 +182,6 @@
|
||||
size={'small'}
|
||||
/>
|
||||
</div>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="flex-center widget cursor-pointer"
|
||||
on:click={(evt) => {
|
||||
@ -198,7 +196,7 @@
|
||||
? 'var(--theme-warning-color)'
|
||||
: 'currentColor'}
|
||||
/>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -215,10 +213,6 @@
|
||||
</Theme>
|
||||
|
||||
<style lang="scss">
|
||||
* {
|
||||
--status-bar-height: 32px;
|
||||
}
|
||||
|
||||
#ui-root {
|
||||
position: relative;
|
||||
display: flex;
|
||||
@ -235,6 +229,7 @@
|
||||
font-size: 12px;
|
||||
line-height: 150%;
|
||||
background-color: var(--theme-statusbar-color);
|
||||
border-bottom: 1px solid var(--theme-navpanel-divider);
|
||||
|
||||
.maintenanceScheduled {
|
||||
padding: 0 0.5rem;
|
||||
@ -251,16 +246,12 @@
|
||||
text-align: center;
|
||||
}
|
||||
.clock {
|
||||
margin: 0 16px 0 24px;
|
||||
font-weight: 500;
|
||||
user-select: none;
|
||||
margin: 0 12px 0 8px;
|
||||
}
|
||||
.widget {
|
||||
-webkit-app-region: no-drag;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
font-size: 14px;
|
||||
color: var(--content-color);
|
||||
font-size: 13px;
|
||||
color: var(--theme-content-color);
|
||||
transition: transform 0.15s ease-in-out;
|
||||
|
||||
&.rotated {
|
||||
|
151
packages/ui/src/components/internal/ThemeButton.svelte
Normal file
151
packages/ui/src/components/internal/ThemeButton.svelte
Normal file
@ -0,0 +1,151 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte'
|
||||
import FontSize from './icons/FontSize.svelte'
|
||||
import CheckCircled from './icons/CheckCircled.svelte'
|
||||
|
||||
export let size: string
|
||||
export let focused: string
|
||||
|
||||
let btn: HTMLButtonElement
|
||||
|
||||
onMount(() => {
|
||||
if (focused === size) btn.focus()
|
||||
})
|
||||
</script>
|
||||
|
||||
<button
|
||||
bind:this={btn}
|
||||
class="antiButton regular sh-no-shape jf-center bs-none no-focus statusPopupThemeButton"
|
||||
class:focused={focused === size}
|
||||
class:both={size === 'theme-system'}
|
||||
>
|
||||
{#if size === 'theme-light' || size === 'theme-system'}
|
||||
<div class="light-container">
|
||||
<div class="paper"><FontSize /></div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if size === 'theme-dark' || size === 'theme-system'}
|
||||
<div class="dark-container">
|
||||
<div class="paper"><FontSize /></div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if focused === size}
|
||||
<CheckCircled />
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<style lang="scss">
|
||||
:global(.statusPopupThemeButton svg.check) {
|
||||
position: absolute;
|
||||
bottom: 3px;
|
||||
right: 3px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.statusPopupThemeButton {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
width: 76px;
|
||||
height: 56px;
|
||||
border-radius: 6px;
|
||||
|
||||
.light-container {
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
|
||||
.paper {
|
||||
color: #000000cc;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-left: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
.dark-container {
|
||||
background-color: #3f3f3f;
|
||||
|
||||
.paper {
|
||||
color: #ffffffcc;
|
||||
background-color: #161516;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-left: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
}
|
||||
.light-container,
|
||||
.dark-container {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
|
||||
.paper {
|
||||
padding: 6px 0 0 6px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 4px 0px 5.5px 0px;
|
||||
}
|
||||
}
|
||||
&.both {
|
||||
.light-container {
|
||||
border-right: none;
|
||||
border-radius: 5.75px 0 0 5.75px;
|
||||
}
|
||||
.dark-container {
|
||||
border-radius: 0 5.75px 5.75px 0;
|
||||
}
|
||||
.light-container,
|
||||
.dark-container {
|
||||
width: 50%;
|
||||
|
||||
.paper {
|
||||
margin: 16px 0 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:not(.both) {
|
||||
.dark-container {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.light-container,
|
||||
.dark-container {
|
||||
width: 100%;
|
||||
border-radius: 5.75px;
|
||||
|
||||
.paper {
|
||||
margin: 16px 0 0 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover:not(:focus) {
|
||||
.light-container .paper {
|
||||
color: #000;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.dark-container .paper {
|
||||
color: #fff;
|
||||
background-color: #222222;
|
||||
}
|
||||
}
|
||||
&.focused::before,
|
||||
&:focus::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
inset: -3px;
|
||||
border: 1px solid var(--primary-button-default);
|
||||
border-radius: 8.5px;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
</style>
|
43
packages/ui/src/components/internal/ThemePopup.svelte
Normal file
43
packages/ui/src/components/internal/ThemePopup.svelte
Normal file
@ -0,0 +1,43 @@
|
||||
<!--
|
||||
// Copyright © 2023 Hardcore Engineering Inc.
|
||||
//
|
||||
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License. You may
|
||||
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
import ThemeButton from './ThemeButton.svelte'
|
||||
import { Label } from '../..'
|
||||
|
||||
export let themes: Array<{ id: string; label: IntlString; size: number }>
|
||||
export let selected: string = ''
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const select = (size: string): void => {
|
||||
if (selected === size) return
|
||||
selected = size
|
||||
dispatch('close', size)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiPopup" style:flex-direction={'row'} style:padding={'12px'}>
|
||||
{#each themes as theme}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="statusPopup-option" class:selected={selected === theme.id} on:click={() => select(theme.id)}>
|
||||
<ThemeButton size={theme.id} focused={selected} />
|
||||
<span class="label overflow-label">
|
||||
<Label label={theme.label} />
|
||||
</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
@ -1,23 +1,53 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte'
|
||||
import Mute from './icons/Mute.svelte'
|
||||
import { deviceOptionsStore as deviceInfo } from '../../'
|
||||
import { IntlString } from '@hcengineering/platform'
|
||||
import ui, { showPopup, deviceOptionsStore as deviceInfo } from '../..'
|
||||
import Theme from './icons/Theme.svelte'
|
||||
import ThemePopup from './ThemePopup.svelte'
|
||||
import { isSystemThemeDark } from '@hcengineering/theme'
|
||||
|
||||
const { currentTheme, setTheme } = getContext('theme') as { currentTheme: string; setTheme: (theme: string) => void }
|
||||
|
||||
const themes = ['theme-light', 'theme-dark']
|
||||
const themes: Array<{ id: string; label: IntlString }> = [
|
||||
{ id: 'theme-light', label: ui.string.ThemeLight },
|
||||
{ id: 'theme-dark', label: ui.string.ThemeDark },
|
||||
{ id: 'theme-system', label: ui.string.ThemeSystem }
|
||||
]
|
||||
let pressed: boolean = false
|
||||
let remove: any = null
|
||||
|
||||
let current = themes.indexOf(currentTheme)
|
||||
$deviceInfo.theme = currentTheme
|
||||
let current = themes.findIndex((th) => th.id === currentTheme)
|
||||
|
||||
function changeTheme () {
|
||||
current++
|
||||
setTheme(themes[current % themes.length])
|
||||
$deviceInfo.theme = themes[current % themes.length]
|
||||
function changeTheme (ev: MouseEvent) {
|
||||
pressed = true
|
||||
showPopup(ThemePopup, { themes, selected: themes[current].id }, 'status', (result) => {
|
||||
if (result) {
|
||||
setTheme(result)
|
||||
current = themes.findIndex((th) => th.id === result)
|
||||
}
|
||||
pressed = false
|
||||
})
|
||||
}
|
||||
$: $deviceInfo.theme = themes[current].id
|
||||
$: if (themes[current].id === 'theme-system') checkSystemTheme()
|
||||
|
||||
const checkSystemTheme = () => {
|
||||
if (remove !== null || themes[current].id !== 'theme-system') remove()
|
||||
const isDark = isSystemThemeDark()
|
||||
const media = matchMedia(`(prefers-color-scheme: ${isDark ? 'light' : 'dark'})`)
|
||||
setTheme(themes[current].id)
|
||||
media.addEventListener('change', checkSystemTheme)
|
||||
remove = () => {
|
||||
media.removeEventListener('change', checkSystemTheme)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="flex-center" on:click={changeTheme}>
|
||||
<Mute />
|
||||
</div>
|
||||
<button
|
||||
class="antiButton ghost jf-center bs-none no-focus resetIconSize statusButton square"
|
||||
class:pressed
|
||||
style:color={'var(--theme-dark-color)'}
|
||||
on:click={changeTheme}
|
||||
>
|
||||
<Theme />
|
||||
</button>
|
||||
|
@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
export let fill: string = 'var(--primary-button-default)'
|
||||
</script>
|
||||
|
||||
<svg class="svg-16px check" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M4.11101 2.17959C5.26216 1.41042 6.61553 0.999878 8 0.999878C9.85652 0.999878 11.637 1.73738 12.9497 3.05013C14.2625 4.36288 15 6.14336 15 7.99988C15 9.38435 14.5895 10.7377 13.8203 11.8889C13.0511 13.04 11.9579 13.9372 10.6788 14.467C9.3997 14.9968 7.99224 15.1355 6.63437 14.8654C5.2765 14.5953 4.02922 13.9286 3.05026 12.9496C2.07129 11.9707 1.4046 10.7234 1.13451 9.36551C0.86441 8.00764 1.00303 6.60018 1.53285 5.32109C2.06266 4.04201 2.95987 2.94876 4.11101 2.17959ZM11.3536 6.35355C11.5488 6.15829 11.5488 5.84171 11.3536 5.64645C11.1583 5.45118 10.8417 5.45118 10.6464 5.64645L7 9.29289L5.35355 7.64645C5.15829 7.45118 4.84171 7.45118 4.64645 7.64645C4.45118 7.84171 4.45118 8.15829 4.64645 8.35355L6.64645 10.3536C6.84171 10.5488 7.15829 10.5488 7.35355 10.3536L11.3536 6.35355Z"
|
||||
/>
|
||||
</svg>
|
@ -1,84 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="usa-star" viewBox="0 -0.5 0.5 0.5">
|
||||
<polygon
|
||||
points="0.3,-0.3 0.4,-0.5 0.2,-0.4 0.2,-0.4 0.2,-0.4 0.1,-0.5 0.2,-0.3 0.2,-0.3 0.2,-0.3 0,-0.2 0.2,-0.2 0.2,0 0.3,-0.2 0.3,-0.2 0.3,-0.2 0.5,-0.2 0.3,-0.3 0.3,-0.3 "
|
||||
/>
|
||||
</symbol>
|
||||
<symbol id="en-flag" viewBox="0 0 16 16">
|
||||
<g fill={'#DB2E2E'}>
|
||||
<rect y="6.1" width="16" height="0.8" />
|
||||
<rect y="4.5" width="16" height="0.8" />
|
||||
<rect y="3" width="16" height="0.8" />
|
||||
<rect y="7.6" width="16" height="0.8" />
|
||||
<rect y="9.2" width="16" height="0.8" />
|
||||
<rect y="10.7" width="16" height="0.8" />
|
||||
<rect y="12.2" width="16" height="0.8" />
|
||||
</g>
|
||||
<g fill={'#FFFFFF'}>
|
||||
<rect y="5.3" width="16" height="0.8" />
|
||||
<rect y="3.8" width="16" height="0.8" />
|
||||
<rect y="6.8" width="16" height="0.8" />
|
||||
<rect y="8.4" width="16" height="0.8" />
|
||||
<rect y="9.9" width="16" height="0.8" />
|
||||
<rect y="11.5" width="16" height="0.8" />
|
||||
</g>
|
||||
<rect fill={'#2E4593'} y="3" width="6" height="4.6" />
|
||||
<g fill={'#FFFFFF'}>
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.2971 3.1931)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.2774 3.1931)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.2414 3.1931)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.2254 3.1931)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.2313 3.1931)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 5.1989 3.1931)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.7922 3.6606)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.7726 3.6606)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.7366 3.6606)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.7206 3.6606)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.7265 3.6606)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.7922 4.601)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.7726 4.601)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.7366 4.601)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.7206 4.601)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.7265 4.601)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.7922 5.5424)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.7726 5.5424)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.7366 5.5424)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.7206 5.5424)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.7265 5.5424)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.7922 6.4829)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.7726 6.4829)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.7366 6.4829)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.7206 6.4829)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.7265 6.4829)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.2971 4.1299)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.2774 4.1299)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.2414 4.1299)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.2254 4.1299)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.2313 4.1299)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 5.1989 4.1299)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.2971 5.0712)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.2774 5.0712)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.2414 5.0712)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.2254 5.0712)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.2313 5.0712)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 5.1989 5.0712)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.2971 6.0135)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.2774 6.0135)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.2414 6.0135)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.2254 6.0135)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.2313 6.0135)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 5.1989 6.0135)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 0.2971 6.9558)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 1.2774 6.9558)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 2.2414 6.9558)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 3.2254 6.9558)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 4.2313 6.9558)" />
|
||||
<use xlink:href="#usa-star" width="0.5" height="0.5" y="-0.5" transform="matrix(1 0 0 -1 5.1989 6.9558)" />
|
||||
</g>
|
||||
</symbol>
|
||||
<symbol id="ru-flag" viewBox="0 0 16 16">
|
||||
<rect fill={'#FDFFFF'} y="3" width="16" height="3.3" />
|
||||
<rect fill={'#DB2E2E'} y="9.7" width="16" height="3.3" />
|
||||
<rect fill={'#3C5EBF'} y="6.3" width="16" height="3.3" />
|
||||
</symbol>
|
||||
</svg>
|
Before Width: | Height: | Size: 6.9 KiB |
@ -1,12 +1,13 @@
|
||||
<script lang="ts">
|
||||
const fill: string = 'currentColor'
|
||||
export let size: string = '16px'
|
||||
export let fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-16px" {fill} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<path d="M5.1,4.6L0,19.4h2.1l1.5-4.2h5.7l1.5,4.2h2.1L7.7,4.6H5.1z M3.9,13.4l2.3-6.9h0.2l2.4,6.9H3.9z" />
|
||||
<path
|
||||
d="M23,17.6v-5.7c0-1.1-0.3-2.1-1.1-2.8c-0.8-0.7-1.8-1-3.3-1c-1,0-1.8,0.2-2.4,0.7c-0.7,0.5-1.1,1-1.5,1.5l1.1,1.1 c0.3-0.5,0.7-1,1.1-1.3c0.5-0.3,1-0.5,1.6-0.5c0.8,0,1.5,0.2,1.8,0.7c0.3,0.3,0.7,1,0.7,1.6v1h-2.1c-1.6,0-2.8,0.3-3.6,0.8 c-0.8,0.5-1.1,1.3-1.1,2.4c0,1,0.3,1.8,1,2.4c0.7,0.7,1.5,0.8,2.6,0.8c0.8,0,1.5-0.2,2-0.5c0.5-0.3,1-0.8,1.1-1.5h0.2 c0,0.5,0.3,1,0.5,1.3c0.3,0.3,0.8,0.5,1.3,0.5H24v-1.6C24,17.6,23,17.6,23,17.6z M20.9,16.2c0,0.5-0.3,1-0.8,1.3s-1.1,0.5-2,0.5 c-0.7,0-1.1-0.2-1.5-0.5s-0.5-0.7-0.5-1.1v-0.5c0-0.5,0.2-1,0.7-1.1c0.5-0.3,1.1-0.3,2-0.3h2.1V16.2z"
|
||||
/>
|
||||
</g>
|
||||
<svg style:width={size} style:height={size} {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M23.8382 23.1294C26.1022 23.1294 27.7617 21.7172 27.7617 19.797V18.7192L24.134 18.9422C22.0501 19.0661 20.9695 19.797 20.9695 21.0854C20.9695 22.3242 22.0886 23.1294 23.8382 23.1294ZM23.3622 25C20.545 25 18.6797 23.4391 18.6797 21.073C18.6797 18.7812 20.5064 17.4309 23.8767 17.2327L27.7617 17.0097V15.8947C27.7617 14.2347 26.6296 13.318 24.5843 13.318C22.9763 13.318 21.7799 14.1108 21.5098 15.3744H19.3615C19.4258 13.1198 21.7027 11.3978 24.61 11.3978C27.8903 11.3978 30 13.0826 30 15.7089V24.8761H27.8775V22.5596H27.826C27.0413 24.0461 25.3047 25 23.3622 25Z"
|
||||
/>
|
||||
<path
|
||||
d="M15.5458 24.8761L13.6805 19.7598H6.29658L4.4313 24.8761H2L8.84365 7H11.1334L17.9771 24.8761H15.5458ZM9.94996 9.71301L6.97837 17.8644H12.9987L10.0271 9.71301H9.94996Z"
|
||||
/>
|
||||
</svg>
|
||||
|
@ -1,9 +0,0 @@
|
||||
<script lang="ts">
|
||||
const fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-16px" {fill} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M14.3,8c-0.2-0.1-0.5-0.1-0.7,0c-1.6,1.2-3.9,1-5.3-0.4C6.9,6.2,6.7,4,7.9,2.4c0.1-0.2,0.2-0.4,0-0.7 C7.9,1.5,7.6,1.4,7.4,1.4c-3.5,0.3-6.1,3.3-6,6.8c0.1,3.5,2.9,6.3,6.4,6.4c0.1,0,0.1,0,0.2,0c3.4,0,6.3-2.6,6.6-6 C14.6,8.4,14.5,8.1,14.3,8z M7.8,13.4C5,13.3,2.7,11,2.6,8.2C2.5,5.7,4.1,3.6,6.3,2.9C5.5,4.8,6,7,7.5,8.5c1.5,1.5,3.8,1.9,5.7,1.2 C12.4,11.9,10.3,13.5,7.8,13.4z"
|
||||
/>
|
||||
</svg>
|
9
packages/ui/src/components/internal/icons/Theme.svelte
Normal file
9
packages/ui/src/components/internal/icons/Theme.svelte
Normal file
@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
export let fill: string = 'currentColor'
|
||||
</script>
|
||||
|
||||
<svg class="svg-16px" {fill} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M16,2C8.3,2,2,8.3,2,16s6.3,14,14,14s14-6.3,14-14S23.7,2,16,2z M12.4,27.5c-1.5-0.5-2.9-1.2-4.1-2.2c-0.6-0.5-1.1-1-1.6-1.6c-1-1.2-1.7-2.6-2.2-4.1C4.2,18.4,4,17.2,4,16C4,9.4,9.4,4,16,4v24C14.8,28,13.6,27.8,12.4,27.5z"
|
||||
/>
|
||||
</svg>
|
@ -87,7 +87,12 @@ export const uis = plugin(uiId, {
|
||||
TravelAndPlaces: '' as IntlString,
|
||||
Food: '' as IntlString,
|
||||
MoreCount: '' as IntlString,
|
||||
Objects: '' as IntlString
|
||||
Objects: '' as IntlString,
|
||||
Spacious: '' as IntlString,
|
||||
Compact: '' as IntlString,
|
||||
ThemeLight: '' as IntlString,
|
||||
ThemeDark: '' as IntlString,
|
||||
ThemeSystem: '' as IntlString
|
||||
},
|
||||
metadata: {
|
||||
DefaultApplication: '' as Metadata<AnyComponent>,
|
||||
|
@ -329,6 +329,9 @@ export function fitPopupElement (
|
||||
newProps.bottom = '12px'
|
||||
newProps.right = '12px'
|
||||
show = true
|
||||
} else if (element === 'status') {
|
||||
newProps.top = 'calc(var(--status-bar-height) + 7.5px)'
|
||||
newProps.right = '12px'
|
||||
}
|
||||
} else {
|
||||
if (clientWidth !== undefined && clientHeight !== undefined) {
|
||||
|
@ -157,6 +157,7 @@ export type ButtonShape =
|
||||
| 'circle'
|
||||
| 'round'
|
||||
| 'round2'
|
||||
| 'round-small'
|
||||
| 'filter'
|
||||
| undefined
|
||||
export type EditStyle =
|
||||
@ -196,6 +197,7 @@ export type PopupPosAlignment =
|
||||
| 'help-center'
|
||||
| 'centered'
|
||||
| 'center'
|
||||
| 'status'
|
||||
|
||||
export function isPopupPosAlignment (x: any): x is PopupPosAlignment {
|
||||
return (
|
||||
@ -349,7 +351,8 @@ export interface DeviceOptions {
|
||||
sizes: Record<WidthType, boolean>
|
||||
minWidth: boolean
|
||||
twoRows: boolean
|
||||
theme?: any
|
||||
theme?: string
|
||||
language?: string
|
||||
}
|
||||
|
||||
export interface TimelineItem {
|
||||
|
Loading…
Reference in New Issue
Block a user