UI and icons fixes (#7177)
Some checks are pending
CI / build (push) Waiting to run
CI / svelte-check (push) Blocked by required conditions
CI / formatting (push) Blocked by required conditions
CI / test (push) Blocked by required conditions
CI / uitest (push) Waiting to run
CI / uitest-pg (push) Waiting to run
CI / uitest-qms (push) Waiting to run
CI / docker-build (push) Blocked by required conditions

This commit is contained in:
Alexander Platov 2024-11-17 18:43:12 +03:00 committed by GitHub
parent bcdfed6871
commit dd8ba84a9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 591 additions and 303 deletions

View File

@ -93,6 +93,11 @@
user-select: none;
box-shadow: var(--theme-popup-shadow);
@media screen and (max-width: 480px) {
width: 100%;
max-width: 100%;
}
.message {
margin-bottom: 1.75rem;
color: var(--theme-content-color);

View File

@ -900,6 +900,7 @@ a.no-line {
.leading-3 { line-height: .75rem; }
.tracking--05px { letter-spacing: -.5px; }
.tracking-1px { letter-spacing: 1px; }
.text-balance { text-wrap: balance; }
.over-underline {
cursor: pointer;

View File

@ -31,6 +31,8 @@
--tag-on-accent-PorpoiseText: #FFFFFF;
--tag-accent-SunshineBackground: #FFBD2E;
--border-color-global-error-border-color: #fb6863;
}
/* Dark Theme */

View File

@ -444,4 +444,9 @@
&.delete {
background: var(--text-editor-highlighted-node-delete-background-color);
}
}
}
// Hiding the selection of an empty line
.select-text p > br.ProseMirror-trailingBreak::selection {
background: transparent;
}

View File

@ -33,6 +33,7 @@
--spacing-4: 2rem;
--spacing-4_5: 2.25rem;
--spacing-5: 2.5rem;
--spacing-5_5: 2.75rem;
--spacing-6: 3rem;
--spacing-6_5: 3.5rem;
--spacing-7: 4rem;

View File

@ -543,6 +543,11 @@
.hulyModal-footer {
padding: var(--spacing-1_5);
}
@media screen and (max-width: 480px) {
width: 100vw;
height: var(--app-height);
min-width: 20rem;
}
}
&.type-aside,
&.type-popup {

View File

@ -50,6 +50,7 @@
}
&__title-wrap {
overflow-x: auto;
display: flex;
align-items: center;
min-width: 0;
@ -277,6 +278,12 @@
max-width: 90vw;
max-height: 90vh;
@media screen and (max-width: 480px) {
width: 100%;
max-width: 100%;
max-height: 100%;
}
.antiCard-header {
padding: .75rem .75rem .375rem;

View File

@ -0,0 +1,123 @@
<script lang="ts">
//
// © 2023 Hardcore Engineering, Inc. All Rights Reserved.
// Licensed under the Eclipse Public License v2.0 (SPDX: EPL-2.0).
//
import type { IntlString } from '@hcengineering/platform'
import { generateId } from '@hcengineering/core'
import { Label } from '../..'
export let id: string = generateId()
export let label: string | undefined = undefined
export let labelIntl: IntlString | undefined = undefined
export let labelParams: Record<string, any> | undefined = undefined
export let checked: boolean = false
export let indeterminate: boolean = false
export let disabled: boolean = false
export let error: boolean = false
export let required: boolean = false
</script>
<label class="checkbox-container" class:disabled>
<input type="checkbox" class="checkbox" {id} bind:checked {disabled} {indeterminate} {required} on:change />
<div class="checkbox-element" class:disabled class:error />
{#if label !== undefined || labelIntl !== undefined || $$slots.default !== undefined}
<div class="checkbox-label">
{#if labelIntl}<Label label={labelIntl} params={labelParams} />{:else}{label}{/if}
<slot />
</div>
{/if}
<slot name="after" />
</label>
<style lang="scss">
.checkbox-element {
position: relative;
flex-shrink: 0;
width: var(--spacing-2);
height: var(--spacing-2);
background-color: var(--selector-BackgroundColor);
border: 1px solid var(--selector-BorderColor);
border-radius: var(--extra-small-BorderRadius);
}
.checkbox-label {
color: var(--global-primary-TextColor);
user-select: none;
}
.checkbox {
overflow: hidden;
position: absolute;
margin: -1px;
padding: 0;
width: 1px;
height: 1px;
border: 0;
clip: rect(0 0 0 0);
&:checked + .checkbox-element,
&:indeterminate + .checkbox-element {
background-color: var(--selector-active-BackgroundColor);
border-color: var(--selector-active-BackgroundColor);
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0.625rem;
height: 0.5rem;
background-color: var(--selector-IconColor);
transform: translate(-50%, -50%);
}
}
&:checked + .checkbox-element::after {
clip-path: path(
'M9.7,0.5c0.4,0.4,0.4,1,0,1.4L4.1,7.8L0.3,4.2c-0.4-0.4-0.4-1,0-1.4c0.4-0.4,1-0.4,1.4,0L4,5l4.3-4.5C8.6,0.1,9.3,0.1,9.7,0.5z'
);
}
&:indeterminate + .checkbox-element::after {
clip-path: path('M0,4c0-0.6,0.4-1,1-1h8c0.6,0,1,0.4,1,1c0,0.6-0.4,1-1,1H1C0.4,5,0,4.6,0,4z');
}
&:disabled + .checkbox-element {
box-shadow: none;
background-color: var(--selector-disabled-BackgroundColor);
border-color: var(--selector-disabled-BorderColor);
& + .checkbox-label {
color: var(--global-disabled-TextColor);
}
}
& + .checkbox-element.error {
border-color: var(--border-color-global-error-border-color);
}
&:focus + .checkbox-element {
outline: 2px solid var(--global-focus-BorderColor);
outline-offset: 2px;
}
&:required + .checkbox-element + .checkbox-label::after {
content: '*';
position: relative;
top: -0.125rem;
left: 0.125rem;
color: var(--global-error-TextColor);
}
}
.checkbox-container {
display: inline-flex;
gap: var(--spacing-1_5);
min-width: var(--spacing-2);
min-height: var(--spacing-2);
&:not(.disabled) {
cursor: pointer;
&:active .checkbox-element {
outline: 2px solid var(--global-focus-BorderColor);
outline-offset: 2px;
}
&:hover .checkbox-element {
box-shadow: 0 0 0 4px var(--selector-hover-overlay-BackgroundColor);
}
}
}
</style>

View File

@ -0,0 +1,111 @@
<script lang="ts">
//
// © 2023 Hardcore Engineering, Inc. All Rights Reserved.
// Licensed under the Eclipse Public License v2.0 (SPDX: EPL-2.0).
//
import type { IntlString } from '@hcengineering/platform'
import { generateId } from '@hcengineering/core'
import { Label } from '../..'
export let id: string = generateId()
export let group: any
export let value: any
export let label: string | undefined = undefined
export let labelIntl: IntlString | undefined = undefined
export let labelParams: Record<string, any> | undefined = undefined
export let checked: boolean = false
export let disabled: boolean = false
export let error: boolean = false
</script>
<label class="radioButton-container" class:disabled>
<input type="radio" class="radioButton" {id} bind:group {value} {checked} {disabled} on:change />
<div class="radioButton-element" class:disabled class:error />
{#if label !== undefined || labelIntl !== undefined || $$slots.default !== undefined}
<div class="radioButton-label">
{#if labelIntl}<Label label={labelIntl} params={labelParams} />{:else}{label}{/if}
<slot />
</div>
{/if}
<slot name="after" />
</label>
<style lang="scss">
.radioButton-element {
position: relative;
flex-shrink: 0;
width: var(--spacing-2);
height: var(--spacing-2);
background-color: var(--selector-BackgroundColor);
border: 1px solid var(--selector-BorderColor);
border-radius: var(--large-BorderRadius);
}
.radioButton-label {
color: var(--global-primary-TextColor);
user-select: none;
}
.radioButton {
overflow: hidden;
position: absolute;
margin: -1px;
padding: 0;
width: 1px;
height: 1px;
border: 0;
clip: rect(0 0 0 0);
&:checked + .radioButton-element {
background-color: var(--selector-active-BackgroundColor);
border-color: var(--selector-active-BackgroundColor);
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: var(--spacing-0_75);
height: var(--spacing-0_75);
background-color: var(--selector-IconColor);
border-radius: 50%;
transform: translate(-50%, -50%);
}
}
&:disabled + .radioButton-element {
box-shadow: none;
background-color: var(--selector-disabled-BackgroundColor);
border-color: var(--selector-disabled-BorderColor);
&::after {
background-color: var(--selector-disabled-IconColor);
}
& + .radioButton-label {
color: var(--global-disabled-TextColor);
}
}
& + .radioButton-element.error {
border-color: var(--border-color-global-error-border-color);
}
&:focus + .radioButton-element {
outline: 2px solid var(--global-focus-BorderColor);
outline-offset: 2px;
}
}
.radioButton-container {
display: inline-flex;
gap: var(--spacing-2);
min-width: var(--spacing-2);
min-height: var(--spacing-2);
&:not(.disabled) {
cursor: pointer;
&:active .radioButton-element {
outline: 2px solid var(--global-focus-BorderColor);
outline-offset: 2px;
}
&:hover .radioButton-element {
box-shadow: 0 0 0 4px var(--selector-hover-overlay-BackgroundColor);
}
}
}
</style>

View File

@ -76,6 +76,12 @@
$: document.body.style.cursor = drag ? 'all-scroll' : 'default'
$: docSize = checkAdaptiveMatching($deviceInfo.size, 'md')
$: isFullMobile =
$deviceInfo.isMobile &&
$deviceInfo.isPortrait &&
['right', 'top', 'float', 'full', 'content', 'middle', 'centered', 'center', 'full-centered'].some(
(el) => element === el
)
function _update (result: any): void {
if (onUpdate !== undefined) onUpdate(result)
@ -100,7 +106,7 @@
contentPanel: HTMLElement | undefined
): void => {
const device: DeviceOptions = $deviceInfo
if ((fullSize || docSize) && (element === 'float' || element === 'centered')) {
if (((fullSize || docSize) && (element === 'float' || element === 'centered')) || isFullMobile) {
options = fitPopupElement(modalHTML, device, 'full', contentPanel, clientWidth, clientHeight)
options.props.maxHeight = '100vh'
if (!modalHTML.classList.contains('fullsize')) modalHTML.classList.add('fullsize')

View File

@ -158,6 +158,8 @@ export { default as HotkeyGroup } from './components/HotkeyGroup.svelte'
export { default as ModernWizardDialog } from './components/wizard/ModernWizardDialog.svelte'
export { default as ModernWizardBar } from './components/wizard/ModernWizardBar.svelte'
export { default as ModernTab } from './components/ModernTab.svelte'
export { default as ModernCheckbox } from './components/ModernCheckbox.svelte'
export { default as ModernRadioButton } from './components/ModernRadioButton.svelte'
export { default as IconAdd } from './components/icons/Add.svelte'
export { default as IconCircleAdd } from './components/icons/CircleAdd.svelte'

View File

@ -1,7 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="application" viewBox="0 0 1024 1024">
<path d="M904 512h-56c-4.4 0-8 3.6-8 8v320H184V184h320c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V520c0-4.4-3.6-8-8-8z" />
<path d="M355.9 534.9L354 653.8c-.1 8.9 7.1 16.2 16 16.2h.4l118-2.9c2-.1 4-.9 5.4-2.3l415.9-415c3.1-3.1 3.1-8.2 0-11.3L785.4 114.3c-1.6-1.6-3.6-2.3-5.7-2.3s-4.1.8-5.7 2.3l-415.8 415a8.3 8.3 0 00-2.3 5.6zm63.5 23.6L779.7 199l45.2 45.1-360.5 359.7-45.7 1.1.7-46.4z" />
<symbol id="application" viewBox="0 0 32 32">
<path d="M22.9,23.4c-0.6,0-1,0.4-1,1v1.5c0,0.5-0.2,1.1-0.6,1.5c-0.4,0.4-0.9,0.6-1.5,0.6H6.1c-0.5,0-1.1-0.2-1.5-0.6C4.2,27,4,26.5,4,25.9V12.2c0-0.5,0.2-1.1,0.6-1.5c0.4-0.4,0.9-0.6,1.5-0.6h1.5c0.6,0,1-0.4,1-1s-0.4-1-1-1H6.1C5,8.1,4,8.5,3.2,9.3C2.4,10.1,2,11.1,2,12.2v13.8C2,27,2.4,28,3.2,28.8C4,29.6,5,30,6.1,30h13.8c1.1,0,2.1-0.4,2.9-1.2c0.8-0.8,1.2-1.8,1.2-2.9v-1.5C23.9,23.9,23.4,23.4,22.9,23.4z" />
<path d="M30,6.2c0-1.1-0.4-2.2-1.2-3C28,2.4,26.9,2,25.8,2s-2.2,0.4-3,1.2l-2,2c0,0-0.1,0-0.1,0.1c0,0,0,0.1-0.1,0.1L9.9,16.1c-0.2,0.2-0.3,0.4-0.3,0.7v4.6c0,0.6,0.4,1,1,1h4.6c0.3,0,0.5-0.1,0.7-0.3l10.6-10.6c0,0,0.1,0,0.1-0.1c0,0,0-0.1,0.1-0.1l2-2C29.6,8.4,30,7.3,30,6.2z M14.8,20.4h-3.2v-3.2l9.7-9.7l3.1,3.1L14.8,20.4z M27.4,7.8l-1.4,1.4l-3.1-3.1l1.4-1.4c0.8-0.8,2.3-0.8,3.1,0c0.4,0.4,0.6,1,0.6,1.6S27.8,7.4,27.4,7.8z" />
</symbol>
<symbol id="survey" viewBox="0 0 24 24">
<path d="M13,6h8c0.6,0,1-0.4,1-1s-0.4-1-1-1h-8c-0.6,0-1,0.4-1,1S12.4,6,13,6z" />
<path d="M13,10h5c0.6,0,1-0.4,1-1s-0.4-1-1-1h-5c-0.6,0-1,0.4-1,1S12.4,10,13,10z" />
<path d="M21,14h-8c-0.6,0-1,0.4-1,1s0.4,1,1,1h8c0.6,0,1-0.4,1-1S21.6,14,21,14z" />
<path d="M18,18h-5c-0.6,0-1,0.4-1,1s0.4,1,1,1h5c0.6,0,1-0.4,1-1S18.6,18,18,18z" />
<path d="M8,3H4C2.9,3,2,3.9,2,5v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V5C10,3.9,9.1,3,8,3z M8,9H4V5h4V9z" />
<path d="M8,13H4c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C10,13.9,9.1,13,8,13z M8,19H4v-4h4V19z" />
</symbol>
<symbol id="radio" viewBox="0 0 15 15">
<path d="M7.5.877a6.623 6.623 0 100 13.246A6.623 6.623 0 007.5.877zM1.827 7.5a5.673 5.673 0 1111.346 0 5.673 5.673 0 01-11.346 0zm5.673 2a2 2 0 100-4 2 2 0 000 4z"/>
@ -12,8 +20,11 @@
<symbol id="textline" viewBox="0 0 24 24">
<path d="M17 7h5v10h-5v2a1 1 0 001 1h2v2h-2.5c-.55 0-1.5-.45-1.5-1 0 .55-.95 1-1.5 1H12v-2h2a1 1 0 001-1V5a1 1 0 00-1-1h-2V2h2.5c.55 0 1.5.45 1.5 1 0-.55.95-1 1.5-1H20v2h-2a1 1 0 00-1 1v2M2 7h11v2H4v6h9v2H2V7m18 8V9h-3v6h3z" />
</symbol>
<symbol id="page" viewBox="0 0 24 24">
<path d="M5 8v12h14V8H5zm0-2h14V4H5v2zm15 16H4a1 1 0 01-1-1V3a1 1 0 011-1h16a1 1 0 011 1v18a1 1 0 01-1 1zM7 10h4v4H7v-4zm0 6h10v2H7v-2zm6-5h4v2h-4v-2z" />
<symbol id="poll" viewBox="0 0 24 24">
<path d="M20.3,1.5H3.7c-1.2,0-2.2,1-2.2,2.2v16.7c0,1.2,0.9,2.2,2.2,2.2h16.7c1.3,0,2.2-0.9,2.2-2.2V3.7C22.5,2.4,21.6,1.5,20.3,1.5z M20.5,3.7v2.6H8.2V3.5h12.1C20.4,3.5,20.5,3.5,20.5,3.7z M3.7,3.5h2.6v2.8H3.5V3.7C3.5,3.6,3.6,3.5,3.7,3.5z M20.5,20.5c0,0-0.1,0-0.2,0H3.7c-0.2,0-0.2-0.1-0.2-0.2V8.2h17v12.1C20.5,20.4,20.5,20.5,20.5,20.5z" />
<path d="M17.3,16.4H6.7c-0.6,0-1,0.4-1,1s0.4,1,1,1h10.6c0.6,0,1-0.4,1-1S17.8,16.4,17.3,16.4z" />
<path d="M17.3,11.1h-4c-0.6,0-1,0.4-1,1s0.4,1,1,1h4c0.6,0,1-0.4,1-1S17.8,11.1,17.3,11.1z" />
<path d="M6.7,14.5h2.6c0.6,0,1-0.4,1-1v-2.6c0-0.6-0.4-1-1-1H6.7c-0.6,0-1,0.4-1,1v2.6C5.7,14,6.2,14.5,6.7,14.5z M7.7,11.8h0.6v0.6H7.7V11.8z" />
</symbol>
<symbol id="asterisk" viewBox="0 0 24 24">
<path d="M13 3v7.267l6.294-3.633 1 1.732-6.293 3.633 6.293 3.635-1 1.732L13 13.732V21h-2v-7.268l-6.294 3.634-1-1.732L9.999 12 3.706 8.366l1-1.732L11 10.267V3z" />
@ -27,14 +38,18 @@
<symbol id="submit" viewBox="0 0 32 32">
<path d="M4 8C4 5.79086 5.79086 4 8 4H21C21.5523 4 22 4.44772 22 5C22 5.55228 21.5523 6 21 6H8C6.89543 6 6 6.89543 6 8V24C6 25.1046 6.89543 26 8 26H24C25.1046 26 26 25.1046 26 24V17C26 16.4477 26.4477 16 27 16C27.5523 16 28 16.4477 28 17V24C28 26.2091 26.2091 28 24 28H8C5.79086 28 4 26.2091 4 24V8ZM29.7071 6.29289C30.0976 6.68342 30.0976 7.31658 29.7071 7.70711L17.7071 19.7071C17.3166 20.0976 16.6834 20.0976 16.2929 19.7071L10.2929 13.7071C9.90237 13.3166 9.90237 12.6834 10.2929 12.2929C10.6834 11.9024 11.3166 11.9024 11.7071 12.2929L17 17.5858L28.2929 6.29289C28.6834 5.90237 29.3166 5.90237 29.7071 6.29289Z" />
</symbol>
<symbol id="validate-ok" viewBox="0 0 1024 1024">
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z" />
<symbol id="validate-ok" viewBox="0 0 24 24">
<path d="M12,1.5C6.2,1.5,1.5,6.2,1.5,12c0,5.8,4.7,10.5,10.5,10.5c5.8,0,10.5-4.7,10.5-10.5C22.5,6.2,17.8,1.5,12,1.5z M12,20.5c-4.7,0-8.5-3.8-8.5-8.5c0-4.7,3.8-8.5,8.5-8.5c4.7,0,8.5,3.8,8.5,8.5C20.5,16.7,16.7,20.5,12,20.5z" />
<path d="M14.5,9.2l-3.5,3.5l-1.4-1.4c-0.4-0.4-1-0.4-1.4,0c-0.4,0.4-0.4,1,0,1.4l2.1,2.1c0.2,0.2,0.4,0.3,0.7,0.3s0.5-0.1,0.7-0.3l4.2-4.2c0.4-0.4,0.4-1,0-1.4S14.9,8.8,14.5,9.2z" />
</symbol>
<symbol id="validate-fail" viewBox="0 0 24 24">
<path d="M16.707 2.293A.996.996 0 0016 2H8a.996.996 0 00-.707.293l-5 5A.996.996 0 002 8v8c0 .266.105.52.293.707l5 5A.996.996 0 008 22h8c.266 0 .52-.105.707-.293l5-5A.996.996 0 0022 16V8a.996.996 0 00-.293-.707l-5-5zM13 17h-2v-2h2v2zm0-4h-2V7h2v6z" />
<path d="M21.9,7.1l-5-5c-0.4-0.4-0.9-0.6-1.4-0.6h-7c-0.6,0-1,0.2-1.4,0.6l-5,5C1.7,7.5,1.5,8,1.5,8.5v7c0,0.6,0.2,1,0.6,1.4l5,5c0.4,0.4,0.9,0.6,1.4,0.6h7c0.6,0,1-0.2,1.4-0.6l5-5c0.4-0.4,0.6-0.9,0.6-1.4v-7C22.5,8,22.3,7.5,21.9,7.1z M20.5,15.5l-5,5l-7,0l-5-5l0-7l5-5l0,0l7,0l5,5L20.5,15.5z" />
<path d="M12,13c0.6,0,1-0.4,1-1V7.8c0-0.6-0.4-1-1-1s-1,0.4-1,1V12C11,12.6,11.4,13,12,13z" />
<path d="M12,15.2L12,15.2c-0.6,0-1,0.4-1,1s0.5,1,1,1s1-0.4,1-1S12.6,15.2,12,15.2z" />
</symbol>
<symbol id="info" viewBox="0 0 16 16">
<path d="M7 4.75c0-.412.338-.75.75-.75h.5c.412 0 .75.338.75.75v.5c0 .412-.338.75-.75.75h-.5A.753.753 0 017 5.25v-.5zM10 12H6v-1h1V8H6V7h3v4h1z" />
<path d="M8 0a8 8 0 100 16A8 8 0 008 0zm0 14.5a6.5 6.5 0 110-13 6.5 6.5 0 010 13z" />
<symbol id="info" viewBox="0 0 24 24">
<path d="M12,1.5C6.2,1.5,1.5,6.2,1.5,12c0,5.8,4.7,10.5,10.5,10.5c5.8,0,10.5-4.7,10.5-10.5C22.5,6.2,17.8,1.5,12,1.5z M12,20.5c-4.7,0-8.5-3.8-8.5-8.5c0-4.7,3.8-8.5,8.5-8.5c4.7,0,8.5,3.8,8.5,8.5C20.5,16.7,16.7,20.5,12,20.5z" />
<path d="M12,8.8c0.6,0,1-0.4,1-1s-0.4-1-1-1h0c-0.6,0-1,0.4-1,1S11.5,8.8,12,8.8z" />
<path d="M13.1,15.2L13.1,15.2L13,12c0-0.6-0.4-1-1-1h-1.1c-0.6,0-1,0.4-1,1s0.4,1,1,1H11v3.2c0,0.6,0.4,1,1,1h1.1c0.6,0,1-0.4,1-1S13.6,15.2,13.1,15.2z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -20,12 +20,12 @@ const icons = require('../assets/icons.svg') as string // eslint-disable-line
loadMetadata(survey.icon, {
Application: `${icons}#application`,
Info: `${icons}#info`,
Poll: `${icons}#page`,
Poll: `${icons}#poll`,
Question: `${icons}#question`,
QuestionKindString: `${icons}#textline`,
QuestionKindOption: `${icons}#radio`,
QuestionKindOptions: `${icons}#checkbox`,
Survey: `${icons}#application`,
Survey: `${icons}#survey`,
Submit: `${icons}#submit`,
QuestionIsMandatory: `${icons}#asterisk`,
QuestionHasCustomOption: `${icons}#star`,

View File

@ -60,7 +60,7 @@
}
</script>
<div class="antiSection">
<div class="antiSection flex-gap-4">
{#if hasText(object.prompt)}
<div class="antiSection-header">
<span class="antiSection-header__title">
@ -70,21 +70,13 @@
{/if}
{#each object.questions ?? [] as question, index}
{#if isQuestionValid(question)}
<div class="question">
<PollQuestion
bind:this={questionNodes[index]}
bind:isAnswered={isAnswered[index]}
readonly={readonly || object.isCompleted}
on:answered={saveAnswers}
{question}
/>
</div>
<PollQuestion
bind:this={questionNodes[index]}
bind:isAnswered={isAnswered[index]}
readonly={readonly || object.isCompleted}
on:answered={saveAnswers}
{question}
/>
{/if}
{/each}
</div>
<style lang="scss">
.question {
margin-top: 1.25em;
}
</style>

View File

@ -18,14 +18,14 @@
import { MessageBox, getClient } from '@hcengineering/presentation'
import { Question, QuestionKind, Survey } from '@hcengineering/survey'
import {
Button,
EditBox,
Icon,
IconDelete,
SelectPopup,
eventToHTMLElement,
showPopup,
tooltip
tooltip,
ButtonIcon
} from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import survey from '../plugin'
@ -37,11 +37,14 @@
export let index: number
export let readonly: boolean = false
let editQuestion: EditBox
let hovered: boolean = false
$: question = parent?.questions?.[index] as Question
$: options = question?.options ?? []
$: questionIcon =
question === undefined
? undefined
? survey.icon.Question
: question.kind === QuestionKind.OPTIONS
? survey.icon.QuestionKindOptions
: question.kind === QuestionKind.OPTION
@ -134,6 +137,7 @@
}
function showQuestionParams (ev: MouseEvent): void {
hovered = true
showPopup(
SelectPopup,
{
@ -215,11 +219,13 @@
console.error('Unknown command id', id)
}
}
hovered = false
}
)
}
function showOptionParams (ev: MouseEvent, index: number): void {
hovered = true
showPopup(
SelectPopup,
{
@ -245,6 +251,7 @@
console.error('Unknown command id', id)
}
}
hovered = false
}
)
}
@ -335,93 +342,105 @@
isRootDragging = false
dispatch('dragEnd')
}
const focusQuestion = (): void => {
editQuestion.focusInput()
}
</script>
<div class="root" bind:this={rootElement} class:is-dragged={isRootDragging}>
<div class="header">
<div
bind:this={rootElement}
class="question-container flex-col flex-gap-2"
class:is-dragged={isRootDragging}
class:hovered
>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div class="flex-row-center flex-gap-3 text-base pr-2" on:click={focusQuestion}>
{#if question === undefined}
<Button noFocus={true} icon={survey.icon.Question} />
<div class="text">
<EditBox placeholder={survey.string.QuestionPlaceholder} bind:value={newQuestion} on:change={createQuestion} />
</div>
<ButtonIcon size={'small'} disabled icon={survey.icon.Question} />
<EditBox
bind:this={editQuestion}
kind={'editbox'}
placeholder={survey.string.QuestionPlaceholder}
bind:value={newQuestion}
on:change={createQuestion}
/>
{:else}
<div role="presentation" draggable={!readonly} on:dragstart={rootDragStart} on:dragend={rootDragEnd}>
<Button disabled={readonly} icon={questionIcon} on:click={showQuestionParams} />
</div>
<div class="text">
<EditBox
disabled={readonly}
placeholder={survey.string.QuestionPlaceholderEmpty}
bind:value={question.name}
on:change={changeName}
/>
{#if question.hasCustomOption && question.kind !== QuestionKind.STRING}
<span class="question-param-icon" use:tooltip={{ label: survey.string.QuestionTooltipCustomOption }}>
<Icon icon={survey.icon.QuestionHasCustomOption} size="medium" fill="var(--theme-won-color)" />
</span>
{/if}
{#if question.isMandatory}
<span class="question-param-icon" use:tooltip={{ label: survey.string.QuestionTooltipMandatory }}>
<Icon icon={survey.icon.QuestionIsMandatory} size="medium" fill="var(--theme-urgent-color)" />
</span>
{/if}
<ButtonIcon size={'small'} disabled={readonly} icon={questionIcon} on:click={showQuestionParams} />
</div>
<EditBox
bind:this={editQuestion}
kind={'editbox'}
disabled={readonly}
placeholder={survey.string.QuestionPlaceholderEmpty}
bind:value={question.name}
on:change={changeName}
/>
{#if question.hasCustomOption && question.kind !== QuestionKind.STRING}
<div class="flex-no-shrink" use:tooltip={{ label: survey.string.QuestionTooltipCustomOption }}>
<Icon icon={survey.icon.QuestionHasCustomOption} size={'small'} />
</div>
{/if}
{#if question.isMandatory}
<div class="flex-no-shrink" use:tooltip={{ label: survey.string.QuestionTooltipMandatory }}>
<Icon icon={survey.icon.QuestionIsMandatory} size={'small'} />
</div>
{/if}
{/if}
</div>
{#if question !== undefined && question.kind !== QuestionKind.STRING}
<div>
{#each options as option, index (index)}
{#each options as option, index (index)}
<div
class="flex-row-center flex-gap-3 option"
role="listitem"
bind:this={draggableElements[index]}
on:dragover={(ev) => {
dragOver(ev, index)
}}
on:dragleave={(ev) => {
dragLeave(ev, index)
}}
on:drop={dragDrop}
class:is-dragged={index === draggedIndex}
class:dragged-over={draggedIndex !== undefined &&
draggedOverIndex === index &&
draggedOverIndex !== draggedIndex &&
draggedOverIndex !== draggedIndex + 1}
>
<div
class="option"
role="listitem"
bind:this={draggableElements[index]}
on:dragover={(ev) => {
dragOver(ev, index)
role="presentation"
draggable={!readonly}
on:dragstart={(ev) => {
dragStart(ev, index)
}}
on:dragleave={(ev) => {
dragLeave(ev, index)
}}
on:drop={dragDrop}
class:is-dragged={index === draggedIndex}
class:dragged-over={draggedIndex !== undefined &&
draggedOverIndex === index &&
draggedOverIndex !== draggedIndex &&
draggedOverIndex !== draggedIndex + 1}
on:dragend={dragEnd}
>
<div
role="presentation"
draggable={!readonly}
on:dragstart={(ev) => {
dragStart(ev, index)
<ButtonIcon
disabled={readonly}
icon={questionIcon}
iconSize={'x-small'}
kind={'tertiary'}
size={'extra-small'}
on:click={(ev) => {
showOptionParams(ev, index)
}}
on:dragend={dragEnd}
>
<Button
disabled={readonly}
icon={questionIcon}
kind="list"
size="small"
on:click={(ev) => {
showOptionParams(ev, index)
}}
/>
</div>
<div class="text">
<EditBox
disabled={readonly}
placeholder={survey.string.QuestionPlaceholderOption}
bind:value={options[index]}
on:change={async () => {
await changeOption(index)
}}
/>
</div>
/>
</div>
{/each}
</div>
<EditBox
disabled={readonly}
placeholder={survey.string.QuestionPlaceholderOption}
bind:value={options[index]}
on:change={async () => {
await changeOption(index)
}}
/>
</div>
{/each}
{#if !readonly}
<div
class="option"
class="flex-row-center flex-gap-3 option"
role="listitem"
on:dragover={(ev) => {
dragOver(ev, options.length)
@ -432,54 +451,35 @@
on:drop={dragDrop}
class:dragged-over={draggedOverIndex === options.length && draggedIndex !== options.length - 1}
>
<Button noFocus={true} icon={survey.icon.Question} kind="list" size="small" />
<div class="text">
<EditBox placeholder={survey.string.QuestionPlaceholderOption} bind:value={newOption} on:change={addOption} />
</div>
<ButtonIcon disabled icon={survey.icon.Question} iconSize={'x-small'} kind={'tertiary'} size={'extra-small'} />
<EditBox placeholder={survey.string.QuestionPlaceholderOption} bind:value={newOption} on:change={addOption} />
</div>
{/if}
{/if}
</div>
<style lang="scss">
.root {
font-size: 1.05rem;
margin-top: 0.5em;
border-radius: var(--medium-BorderRadius);
padding: 0.5em;
.question-container {
padding: var(--spacing-1);
border-radius: var(--small-BorderRadius);
transition: opacity 0.1s ease-in;
&:hover {
background-color: var(--global-ui-hover-highlight-BackgroundColor);
background-color: var(--theme-popup-color); // var(--global-ui-hover-highlight-BackgroundColor);
}
&.hovered,
&:focus-within {
background-color: var(--theme-list-row-color);
}
}
.header {
display: flex;
align-items: center;
margin-bottom: 0.25em;
}
.text {
font-size: 0.95em;
margin-left: 1em;
margin-right: 1em;
flex-grow: 1;
display: flex;
}
.option {
display: flex;
align-items: center;
padding-left: 2em;
padding-top: 0.25em;
padding-bottom: 0.25em;
padding: var(--spacing-0_5) var(--spacing-0_5) var(--spacing-0_5) var(--spacing-5_5);
}
.is-dragged {
opacity: 0.2;
transition: opacity 0.1s ease-in;
}
.dragged-over {
transition: box-shadow 0.1s ease-in;
box-shadow: 0 -3px 0 0 var(--primary-button-outline);
}
.question-param-icon {
margin-left: 0.5em;
}
</style>

View File

@ -17,9 +17,10 @@
<script lang="ts">
import { getClient } from '@hcengineering/presentation'
import { Survey } from '@hcengineering/survey'
import { EditBox, FocusHandler, Label, createFocusManager } from '@hcengineering/ui'
import { EditBox, FocusHandler, Label, createFocusManager, Icon } from '@hcengineering/ui'
import EditQuestion from './EditQuestion.svelte'
import survey from '../plugin'
import IconQuestion from './icons/Question.svelte'
const manager = createFocusManager()
const client = getClient()
@ -87,85 +88,82 @@
<FocusHandler {manager} />
{#if object !== undefined}
<div class="flex-grow flex-col">
<div class="name">
<EditBox disabled={readonly} placeholder={survey.string.Name} bind:value={object.name} on:change={nameChange} />
</div>
<div class="prompt">
<EditBox
disabled={readonly}
placeholder={survey.string.PromptPlaceholder}
bind:value={object.prompt}
on:change={promptChange}
/>
</div>
<div class="antiSection">
<div class="antiSection-header">
<span class="antiSection-header__title">
<Label label={survey.string.Questions} />
</span>
<div class="flex-row-center flex-no-shrink step-tb-6">
<EditBox
disabled={readonly}
placeholder={survey.string.Name}
bind:value={object.name}
kind={'large-style'}
on:change={nameChange}
/>
</div>
<div class="step-tb-6">
<EditBox
disabled={readonly}
placeholder={survey.string.PromptPlaceholder}
bind:value={object.prompt}
on:change={promptChange}
/>
</div>
<div class="antiSection step-tb-6">
<div class="antiSection-header mb-3">
<div class="antiSection-header__icon">
<Icon icon={IconQuestion} size={'small'} />
</div>
{#each questions as question, index}
<div
role="listitem"
on:dragover={(ev) => {
dragOver(ev, index)
}}
on:dragleave={(ev) => {
dragLeave(ev, index)
}}
on:drop={dragDrop}
class:dragged-over={draggedIndex !== undefined &&
draggedOverIndex === index &&
draggedOverIndex !== draggedIndex &&
draggedOverIndex !== draggedIndex + 1}
>
<EditQuestion
{index}
{readonly}
parent={object}
on:dragStart={() => {
draggedIndex = index
}}
on:dragEnd={() => {
draggedIndex = undefined
draggedOverIndex = undefined
}}
/>
</div>
{/each}
{#if !readonly}
<div
role="listitem"
on:dragover={(ev) => {
dragOver(ev, questions.length)
}}
on:dragleave={(ev) => {
dragLeave(ev, questions.length)
}}
on:drop={dragDrop}
class:dragged-over={draggedOverIndex === questions.length && draggedIndex !== questions.length - 1}
>
<EditQuestion parent={object} index={-1} />
</div>
{/if}
<span class="antiSection-header__title">
<Label label={survey.string.Questions} />
</span>
</div>
{#each questions as question, index}
<div
role="listitem"
on:dragover={(ev) => {
dragOver(ev, index)
}}
on:dragleave={(ev) => {
dragLeave(ev, index)
}}
on:drop={dragDrop}
class:dragged-over={draggedIndex !== undefined &&
draggedOverIndex === index &&
draggedOverIndex !== draggedIndex &&
draggedOverIndex !== draggedIndex + 1}
>
<EditQuestion
{index}
{readonly}
parent={object}
on:dragStart={() => {
draggedIndex = index
}}
on:dragEnd={() => {
draggedIndex = undefined
draggedOverIndex = undefined
}}
/>
</div>
{/each}
{#if !readonly}
<div
role="listitem"
on:dragover={(ev) => {
dragOver(ev, questions.length)
}}
on:dragleave={(ev) => {
dragLeave(ev, questions.length)
}}
on:drop={dragDrop}
class:dragged-over={draggedOverIndex === questions.length && draggedIndex !== questions.length - 1}
>
<EditQuestion parent={object} index={-1} />
</div>
{/if}
</div>
{/if}
<style lang="scss">
.name {
font-weight: 500;
font-size: 1.25rem;
color: var(--caption-color);
display: flex;
}
.prompt {
font-weight: 400;
font-size: 1.05rem;
color: var(--caption-color);
margin-top: 1em;
margin-bottom: 1em;
div[role='listitem'] + div[role='listitem'] {
margin-top: var(--spacing-1);
}
.dragged-over {
transition: box-shadow 0.1s ease-in;

View File

@ -19,9 +19,9 @@
import { Panel } from '@hcengineering/panel'
import { createQuery } from '@hcengineering/presentation'
import { Survey } from '@hcengineering/survey'
import { Button, Icon, IconMoreH, Label, tooltip } from '@hcengineering/ui'
import { Button, Icon, IconMoreH, Label, tooltip, Breadcrumb } from '@hcengineering/ui'
import view from '@hcengineering/view'
import { DocNavLink, showMenu } from '@hcengineering/view-resources'
import { showMenu } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import EditSurvey from './EditSurvey.svelte'
import EditPoll from './EditPoll.svelte'
@ -53,7 +53,7 @@
<Panel
isHeader={false}
isSub={false}
isAside={true}
isAside={false}
{embedded}
{object}
on:open
@ -63,22 +63,20 @@
withoutInput={readonly}
>
<svelte:fragment slot="title">
<DocNavLink noUnderline {object}>
<div class="title">{object.name}</div>
</DocNavLink>
<Breadcrumb icon={survey.icon.Survey} title={object.name} size={'large'} isCurrent />
</svelte:fragment>
<svelte:fragment slot="utils">
{#if !readonly}
{#if preview}
{#if canSubmit}
<span use:tooltip={{ label: survey.string.ValidateOk }}>
<Icon size="x-large" icon={survey.icon.ValidateOk} fill="var(--theme-won-color)" />
</span>
<div use:tooltip={{ label: survey.string.ValidateOk }}>
<Icon size="x-large" icon={survey.icon.ValidateOk} fill="var(--positive-button-default)" />
</div>
{:else}
<span use:tooltip={{ label: survey.string.ValidateFail }}>
<Icon size="x-large" icon={survey.icon.ValidateFail} iconProps={{ opacity: 0.75 }} />
</span>
<div use:tooltip={{ label: survey.string.ValidateFail }}>
<Icon size="x-large" icon={survey.icon.ValidateFail} fill="var(--theme-trans-color)" />
</div>
{/if}
{/if}
<Button
@ -102,9 +100,9 @@
<div class="flex-col flex-grow flex-no-shrink">
{#if preview}
{#if poll !== undefined}
<div class="antiSection-empty solid flex-row mt-3">
<Icon icon={survey.icon.Info} size="large" />
<span class="content-dark-color" style="margin-left:1em">
<div class="antiSection-empty solid mb-8">
<Icon icon={survey.icon.Info} size={'large'} />
<span class="content-dark-color text-balance" style="margin-left:1em">
<Label label={survey.string.ValidateInfo} />
</span>
</div>

View File

@ -16,7 +16,7 @@
-->
<script lang="ts">
import { generateId } from '@hcengineering/core'
import { EditBox, Icon, Label, tooltip } from '@hcengineering/ui'
import { EditBox, Icon, Label, tooltip, ModernCheckbox, ModernRadioButton } from '@hcengineering/ui'
import { AnsweredQuestion, QuestionKind } from '@hcengineering/survey'
import { createEventDispatcher } from 'svelte'
import survey from '../plugin'
@ -133,110 +133,105 @@
}
return []
}
$: console.log('[!!!] question: ', question)
</script>
<div class="antiSection">
<div class="antiSection-header">
<span class="antiSection-header__title" style="display:flex">
{question.name}
{#if question.isMandatory && !readonly}
<span style="margin-left:0.25em" use:tooltip={{ label: survey.string.QuestionTooltipMandatory }}>
<Icon icon={survey.icon.QuestionIsMandatory} size="tiny" fill="var(--theme-urgent-color)" />
</span>
{/if}
</span>
<div class="question-answer-container flex-col flex-gap-3">
<div class="flex-row-center flex-gap-1 flex-no-shrink">
<span class="text-lg caption-color font-medium">{question.name}</span>
{#if question.isMandatory && !readonly}
<div
class="flex-no-shrink"
style:transform={'translateY(-0.25rem)'}
use:tooltip={{ label: survey.string.QuestionTooltipMandatory }}
>
<Icon icon={survey.icon.QuestionIsMandatory} size={'xx-small'} fill="var(--theme-urgent-color)" />
</div>
{/if}
</div>
{#if readonly}
{#each getReadonlyAnswers() as answer}
{#if answer}
<div class="answer">{answer}</div>
<div class="pl-6">{answer}</div>
{:else}
<div class="answer empty">
<div class="pl-6 content-halfcontent-color">
<Label label={survey.string.NoAnswer} />
</div>
{/if}
{/each}
{:else if question.kind === QuestionKind.OPTION}
{#each question.options ?? [] as option, i}
<div class="option">
<input type="radio" id={`${id}-${i}`} value={i} bind:group={selectedOption} on:change={optionChange} />
<label class="option__label" for={`${id}-${i}`}>
{option}
</label>
</div>
{/each}
{#if question.hasCustomOption}
<div class="option">
<input
type="radio"
id={`${id}-custom`}
value={customOption}
<div class="flex-col flex-gap-2 px-6">
{#each question.options ?? [] as option, i}
<ModernRadioButton
id={`${id}-${i}`}
value={i}
label={option}
bind:group={selectedOption}
on:change={optionChange}
/>
{/each}
{#if question.hasCustomOption}
<ModernRadioButton
id={`${id}-custom`}
value={customOption}
labelIntl={survey.string.AnswerCustomOption}
bind:group={selectedOption}
on:change={optionChange}
/>
<label class="option__label" for={`${id}-custom`}>
<Label label={survey.string.AnswerCustomOption} />
</label>
{#if selectedOption === customOption}
<div class="option__custom">
<EditBox bind:value={answer} on:change={answerChange} placeholder={survey.string.AnswerPlaceholder} />
<div class="pl-6">
<EditBox
kind={'ghost-large'}
bind:value={answer}
placeholder={survey.string.AnswerPlaceholder}
focusable
autoFocus
on:change={answerChange}
/>
</div>
{/if}
</div>
{/if}
{/if}
</div>
{:else if question.kind === QuestionKind.OPTIONS}
{#each question.options ?? [] as option, i}
<div class="option">
<input type="checkbox" id={`${id}-${i}`} bind:checked={selectedOptions[i]} on:change={optionsChange} />
<label class="option__label" for={`${id}-${i}`}>
{option}
</label>
</div>
{/each}
{#if question.hasCustomOption}
<div class="option">
<input
type="checkbox"
<div class="flex-col flex-gap-2 px-6">
{#each question.options ?? [] as option, i}
<ModernCheckbox id={`${id}-${i}`} label={option} bind:checked={selectedOptions[i]} on:change={optionsChange} />
{/each}
{#if question.hasCustomOption}
<ModernCheckbox
id={`${id}-custom`}
labelIntl={survey.string.AnswerCustomOption}
bind:checked={selectedOptions[customOption]}
on:change={optionsChange}
/>
<label class="option__label" for={`${id}-custom`}>
<Label label={survey.string.AnswerCustomOption} />
</label>
{#if selectedOptions[customOption]}
<div class="option__custom">
<EditBox bind:value={answer} on:change={answerChange} placeholder={survey.string.AnswerPlaceholder} />
<div class="pl-6">
<EditBox
kind={'ghost-large'}
bind:value={answer}
placeholder={survey.string.AnswerPlaceholder}
focusable
autoFocus
on:change={answerChange}
/>
</div>
{/if}
</div>
{/if}
{:else}
<div class="option">
<EditBox bind:value={answer} on:change={answerChange} placeholder={survey.string.AnswerPlaceholder} />
{/if}
</div>
{:else}
<EditBox
kind={'ghost-large'}
bind:value={answer}
placeholder={survey.string.AnswerPlaceholder}
focusable
on:change={answerChange}
/>
{/if}
</div>
<style lang="scss">
.option {
margin-left: 1em;
margin-top: 0.5em;
}
.option__label {
cursor: pointer;
margin-left: 0.25em;
}
.option__custom {
margin-left: 2em;
margin-top: 0.5em;
}
.answer {
margin-left: 2em;
margin-top: 0.5em;
&.empty {
opacity: 0.7;
}
:global(.question-answer-container + .question-answer-container) {
padding-top: var(--spacing-2);
border-top: 1px solid var(--theme-divider-color);
}
</style>

View File

@ -0,0 +1,14 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
export let fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M12,22.5C6.2,22.5,1.5,17.8,1.5,12C1.5,6.2,6.2,1.5,12,1.5c5.8,0,10.5,4.7,10.5,10.5C22.5,17.8,17.8,22.5,12,22.5z M12,3.5c-4.7,0-8.5,3.8-8.5,8.5c0,4.7,3.8,8.5,8.5,8.5c4.7,0,8.5-3.8,8.5-8.5C20.5,7.3,16.7,3.5,12,3.5z"
/>
<path d="M12,18.3c-0.6,0-1-0.4-1-1s0.4-1,1-1s1,0.4,1,1v0C13,17.8,12.6,18.3,12,18.3z" />
<path
d="M12,14.6c-0.5,0-1-0.4-1-0.9c0-0.6,0.1-1.1,0.4-1.6c0.3-0.5,0.8-0.8,1.3-1c0.2-0.1,0.5-0.2,0.6-0.4c0.2-0.2,0.3-0.4,0.4-0.7c0.1-0.3,0.1-0.5,0-0.8c0-0.3-0.2-0.5-0.3-0.7c-0.2-0.2-0.4-0.4-0.6-0.5c-0.2-0.1-0.5-0.1-0.8-0.2c-0.3,0-0.5,0.1-0.8,0.2c-0.2,0.1-0.5,0.3-0.6,0.5c-0.3,0.4-1,0.5-1.4,0.2c-0.4-0.3-0.5-1-0.2-1.4c0.3-0.5,0.8-0.8,1.3-1.1c0.5-0.3,1.1-0.4,1.7-0.4c0.6,0,1.2,0.1,1.7,0.4c0.5,0.3,1,0.6,1.3,1.1c0.3,0.5,0.6,1,0.7,1.6c0.1,0.6,0.1,1.2-0.1,1.7c-0.2,0.6-0.5,1.1-0.8,1.5c-0.4,0.4-0.9,0.8-1.4,1c-0.1,0.1-0.2,0.1-0.3,0.2C13,13.3,13,13.4,13,13.5C13,14.1,12.6,14.5,12,14.6C12,14.6,12,14.6,12,14.6z"
/>
</svg>

View File

@ -191,7 +191,10 @@
d="M16.1,14.5c-0.3-0.3-0.8-0.3-1.1,0l-2.3,2.3V10c0-0.4-0.3-0.8-0.8-0.8s-0.8,0.3-0.8,0.8v6.7l-2.2-2.2 c-0.3-0.3-0.8-0.3-1.1,0c-0.3,0.3-0.3,0.8,0,1.1l3.5,3.5c0.3,0.3,0.8,0.3,1.1,0l3.6-3.5C16.4,15.2,16.4,14.8,16.1,14.5z"
/>
</symbol>
<symbol id="note" viewBox="0 0 256 256">
<rect width="256" height="256" fill="none"></rect><line x1="96" x2="160" y1="96" y2="96" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"></line><line x1="96" x2="160" y1="128" y2="128" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"></line><line x1="96" x2="128" y1="160" y2="160" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"></line><path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" d="M156.68629,216H48a8,8,0,0,1-8-8V48a8,8,0,0,1,8-8H208a8,8,0,0,1,8,8V156.68629a8,8,0,0,1-2.34315,5.65686l-51.3137,51.3137A8,8,0,0,1,156.68629,216Z"></path><polyline fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="8" points="215.277 159.992 160 159.992 160 215.272"></polyline>
<symbol id="note" viewBox="0 0 32 32">
<path d="M28.1,5.8c0-2.1-1.7-3.8-3.8-3.8H7.6C5.6,2,3.9,3.7,3.9,5.8v20.4c0,2.1,1.7,3.8,3.8,3.8h12.1c0.1,0,0.3,0,0.4-0.1c0.1-0.1,0.2-0.1,0.3-0.2l7.4-7.4c0.1-0.1,0.2-0.2,0.2-0.3c0.1-0.1,0.1-0.3,0.1-0.4V5.8z M5.9,26.2V5.8c0-1,0.8-1.8,1.8-1.8h16.7c1,0,1.8,0.8,1.8,1.8v14.8h-3.6c-2.1,0-3.8,1.7-3.8,3.8V28H7.6C6.7,28,5.9,27.2,5.9,26.2z M24.7,22.6l-4,4v-2.2c0-1,0.8-1.8,1.8-1.8H24.7z" />
<path d="M9.5,11.4h13c0.6,0,1-0.4,1-1s-0.4-1-1-1h-13c-0.6,0-1,0.4-1,1S8.9,11.4,9.5,11.4z" />
<path d="M9.5,17h13c0.6,0,1-0.4,1-1s-0.4-1-1-1h-13c-0.6,0-1,0.4-1,1S8.9,17,9.5,17z" />
<path d="M15.1,20.6H9.5c-0.6,0-1,0.4-1,1s0.4,1,1,1h5.6c0.6,0,1-0.4,1-1S15.6,20.6,15.1,20.6z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -187,4 +187,9 @@
<path d="M19.0615 8.60896C20.0321 9.011 20.914 9.60028 21.6569 10.3431L10.3431 21.6569C9.60028 20.914 9.011 20.0321 8.60896 19.0615C8.20693 18.0909 8 17.0506 8 16C8 14.9494 8.20693 13.9091 8.60896 12.9385C9.011 11.9679 9.60028 11.086 10.3431 10.3431C11.086 9.60028 11.9679 9.011 12.9385 8.60896C13.9091 8.20693 14.9494 8 16 8C17.0506 8 18.0909 8.20693 19.0615 8.60896Z" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M30 16C30 23.732 23.732 30 16 30C8.26801 30 2 23.732 2 16C2 8.26801 8.26801 2 16 2C23.732 2 30 8.26801 30 16ZM28 16C28 22.6274 22.6274 28 16 28C9.37258 28 4 22.6274 4 16C4 9.37258 9.37258 4 16 4C22.6274 4 28 9.37258 28 16Z" />
</symbol>
<symbol id="labels" viewBox="0 0 24 24">
<path d="M17.2,13.9c0-0.4-0.1-0.8-0.2-1.2c-0.2-0.4-0.4-0.7-0.7-1L9.8,5.3C9.3,4.7,8.5,4.4,7.6,4.4h-3C3.8,4.4,3,4.7,2.4,5.3C1.8,5.9,1.5,6.7,1.5,7.5v3c0,0.8,0.3,1.6,0.9,2.2l6.5,6.5c0.3,0.3,0.6,0.5,1,0.7c0.4,0.2,0.8,0.2,1.2,0.2s0.8-0.1,1.2-0.2c0.4-0.2,0.7-0.4,1-0.7l3-3c0.3-0.3,0.5-0.6,0.7-1C17.1,14.8,17.2,14.4,17.2,13.9z M15.1,14.4c-0.1,0.1-0.1,0.3-0.2,0.4l-3,3c-0.1,0.1-0.2,0.2-0.4,0.2c-0.3,0.1-0.6,0.1-0.9,0c-0.1-0.1-0.3-0.1-0.4-0.2l-6.5-6.5c-0.2-0.2-0.3-0.5-0.3-0.8v-3c0-0.3,0.1-0.6,0.3-0.8C4,6.5,4.3,6.4,4.6,6.4h3c0.3,0,0.6,0.1,0.8,0.3l6.5,6.5c0.1,0.1,0.2,0.2,0.2,0.4c0.1,0.1,0.1,0.3,0.1,0.4C15.2,14.1,15.2,14.2,15.1,14.4z" />
<path d="M22.3,12.7c-0.2-0.4-0.4-0.7-0.7-1l-7.5-7.5c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l7.5,7.5c0.1,0.1,0.2,0.2,0.2,0.4c0.1,0.1,0.1,0.3,0.1,0.4s0,0.3-0.1,0.4c-0.1,0.1-0.1,0.3-0.2,0.4l-3,3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l3-3c0.3-0.3,0.5-0.6,0.7-1c0.2-0.4,0.2-0.8,0.2-1.2S22.4,13.1,22.3,12.7z" />
<path d="M5.7,7.5c-0.6,0-1,0.4-1,1s0.4,1,1,1h0c0.6,0,1-0.4,1-1S6.2,7.5,5.7,7.5z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -33,7 +33,7 @@ loadMetadata(tracker.icon, {
Magnifier: `${icons}#magnifier`,
Home: `${icons}#home`,
RedCircle: `${icons}#red-circle`,
Labels: `${icons}#priority-nopriority`, // TODO: add icon
Labels: `${icons}#labels`,
DueDate: `${icons}#dueDate`, // TODO: add icon
Parent: `${icons}#parent-issue`, // TODO: add icon
Milestone: `${icons}#milestone`,