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; user-select: none;
box-shadow: var(--theme-popup-shadow); box-shadow: var(--theme-popup-shadow);
@media screen and (max-width: 480px) {
width: 100%;
max-width: 100%;
}
.message { .message {
margin-bottom: 1.75rem; margin-bottom: 1.75rem;
color: var(--theme-content-color); color: var(--theme-content-color);

View File

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

View File

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

View File

@ -445,3 +445,8 @@
background: var(--text-editor-highlighted-node-delete-background-color); 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: 2rem;
--spacing-4_5: 2.25rem; --spacing-4_5: 2.25rem;
--spacing-5: 2.5rem; --spacing-5: 2.5rem;
--spacing-5_5: 2.75rem;
--spacing-6: 3rem; --spacing-6: 3rem;
--spacing-6_5: 3.5rem; --spacing-6_5: 3.5rem;
--spacing-7: 4rem; --spacing-7: 4rem;

View File

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

View File

@ -50,6 +50,7 @@
} }
&__title-wrap { &__title-wrap {
overflow-x: auto;
display: flex; display: flex;
align-items: center; align-items: center;
min-width: 0; min-width: 0;
@ -277,6 +278,12 @@
max-width: 90vw; max-width: 90vw;
max-height: 90vh; max-height: 90vh;
@media screen and (max-width: 480px) {
width: 100%;
max-width: 100%;
max-height: 100%;
}
.antiCard-header { .antiCard-header {
padding: .75rem .75rem .375rem; 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' $: document.body.style.cursor = drag ? 'all-scroll' : 'default'
$: docSize = checkAdaptiveMatching($deviceInfo.size, 'md') $: 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 { function _update (result: any): void {
if (onUpdate !== undefined) onUpdate(result) if (onUpdate !== undefined) onUpdate(result)
@ -100,7 +106,7 @@
contentPanel: HTMLElement | undefined contentPanel: HTMLElement | undefined
): void => { ): void => {
const device: DeviceOptions = $deviceInfo 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 = fitPopupElement(modalHTML, device, 'full', contentPanel, clientWidth, clientHeight)
options.props.maxHeight = '100vh' options.props.maxHeight = '100vh'
if (!modalHTML.classList.contains('fullsize')) modalHTML.classList.add('fullsize') 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 ModernWizardDialog } from './components/wizard/ModernWizardDialog.svelte'
export { default as ModernWizardBar } from './components/wizard/ModernWizardBar.svelte' export { default as ModernWizardBar } from './components/wizard/ModernWizardBar.svelte'
export { default as ModernTab } from './components/ModernTab.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 IconAdd } from './components/icons/Add.svelte'
export { default as IconCircleAdd } from './components/icons/CircleAdd.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;"> <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="application" viewBox="0 0 1024 1024"> <symbol id="application" viewBox="0 0 32 32">
<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="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="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" /> <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>
<symbol id="radio" viewBox="0 0 15 15"> <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"/> <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"> <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" /> <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>
<symbol id="page" viewBox="0 0 24 24"> <symbol id="poll" 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" /> <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>
<symbol id="asterisk" viewBox="0 0 24 24"> <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" /> <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"> <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" /> <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>
<symbol id="validate-ok" viewBox="0 0 1024 1024"> <symbol id="validate-ok" viewBox="0 0 24 24">
<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" /> <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>
<symbol id="validate-fail" viewBox="0 0 24 24"> <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>
<symbol id="info" viewBox="0 0 16 16"> <symbol id="info" viewBox="0 0 24 24">
<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="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="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" /> <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> </symbol>
</svg> </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, { loadMetadata(survey.icon, {
Application: `${icons}#application`, Application: `${icons}#application`,
Info: `${icons}#info`, Info: `${icons}#info`,
Poll: `${icons}#page`, Poll: `${icons}#poll`,
Question: `${icons}#question`, Question: `${icons}#question`,
QuestionKindString: `${icons}#textline`, QuestionKindString: `${icons}#textline`,
QuestionKindOption: `${icons}#radio`, QuestionKindOption: `${icons}#radio`,
QuestionKindOptions: `${icons}#checkbox`, QuestionKindOptions: `${icons}#checkbox`,
Survey: `${icons}#application`, Survey: `${icons}#survey`,
Submit: `${icons}#submit`, Submit: `${icons}#submit`,
QuestionIsMandatory: `${icons}#asterisk`, QuestionIsMandatory: `${icons}#asterisk`,
QuestionHasCustomOption: `${icons}#star`, QuestionHasCustomOption: `${icons}#star`,

View File

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

View File

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

View File

@ -17,9 +17,10 @@
<script lang="ts"> <script lang="ts">
import { getClient } from '@hcengineering/presentation' import { getClient } from '@hcengineering/presentation'
import { Survey } from '@hcengineering/survey' 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 EditQuestion from './EditQuestion.svelte'
import survey from '../plugin' import survey from '../plugin'
import IconQuestion from './icons/Question.svelte'
const manager = createFocusManager() const manager = createFocusManager()
const client = getClient() const client = getClient()
@ -87,11 +88,16 @@
<FocusHandler {manager} /> <FocusHandler {manager} />
{#if object !== undefined} {#if object !== undefined}
<div class="flex-grow flex-col"> <div class="flex-row-center flex-no-shrink step-tb-6">
<div class="name"> <EditBox
<EditBox disabled={readonly} placeholder={survey.string.Name} bind:value={object.name} on:change={nameChange} /> disabled={readonly}
placeholder={survey.string.Name}
bind:value={object.name}
kind={'large-style'}
on:change={nameChange}
/>
</div> </div>
<div class="prompt"> <div class="step-tb-6">
<EditBox <EditBox
disabled={readonly} disabled={readonly}
placeholder={survey.string.PromptPlaceholder} placeholder={survey.string.PromptPlaceholder}
@ -99,8 +105,11 @@
on:change={promptChange} on:change={promptChange}
/> />
</div> </div>
<div class="antiSection"> <div class="antiSection step-tb-6">
<div class="antiSection-header"> <div class="antiSection-header mb-3">
<div class="antiSection-header__icon">
<Icon icon={IconQuestion} size={'small'} />
</div>
<span class="antiSection-header__title"> <span class="antiSection-header__title">
<Label label={survey.string.Questions} /> <Label label={survey.string.Questions} />
</span> </span>
@ -150,22 +159,11 @@
</div> </div>
{/if} {/if}
</div> </div>
</div>
{/if} {/if}
<style lang="scss"> <style lang="scss">
.name { div[role='listitem'] + div[role='listitem'] {
font-weight: 500; margin-top: var(--spacing-1);
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;
} }
.dragged-over { .dragged-over {
transition: box-shadow 0.1s ease-in; transition: box-shadow 0.1s ease-in;

View File

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

View File

@ -16,7 +16,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import { generateId } from '@hcengineering/core' 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 { AnsweredQuestion, QuestionKind } from '@hcengineering/survey'
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import survey from '../plugin' import survey from '../plugin'
@ -133,110 +133,105 @@
} }
return [] return []
} }
$: console.log('[!!!] question: ', question)
</script> </script>
<div class="antiSection"> <div class="question-answer-container flex-col flex-gap-3">
<div class="antiSection-header"> <div class="flex-row-center flex-gap-1 flex-no-shrink">
<span class="antiSection-header__title" style="display:flex"> <span class="text-lg caption-color font-medium">{question.name}</span>
{question.name}
{#if question.isMandatory && !readonly} {#if question.isMandatory && !readonly}
<span style="margin-left:0.25em" use:tooltip={{ label: survey.string.QuestionTooltipMandatory }}> <div
<Icon icon={survey.icon.QuestionIsMandatory} size="tiny" fill="var(--theme-urgent-color)" /> class="flex-no-shrink"
</span> 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} {/if}
</span>
</div> </div>
{#if readonly} {#if readonly}
{#each getReadonlyAnswers() as answer} {#each getReadonlyAnswers() as answer}
{#if answer} {#if answer}
<div class="answer">{answer}</div> <div class="pl-6">{answer}</div>
{:else} {:else}
<div class="answer empty"> <div class="pl-6 content-halfcontent-color">
<Label label={survey.string.NoAnswer} /> <Label label={survey.string.NoAnswer} />
</div> </div>
{/if} {/if}
{/each} {/each}
{:else if question.kind === QuestionKind.OPTION} {:else if question.kind === QuestionKind.OPTION}
<div class="flex-col flex-gap-2 px-6">
{#each question.options ?? [] as option, i} {#each question.options ?? [] as option, i}
<div class="option"> <ModernRadioButton
<input type="radio" id={`${id}-${i}`} value={i} bind:group={selectedOption} on:change={optionChange} /> id={`${id}-${i}`}
<label class="option__label" for={`${id}-${i}`}> value={i}
{option} label={option}
</label>
</div>
{/each}
{#if question.hasCustomOption}
<div class="option">
<input
type="radio"
id={`${id}-custom`}
value={customOption}
bind:group={selectedOption} bind:group={selectedOption}
on:change={optionChange} 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>
{/if}
</div>
{/if}
{: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} {/each}
{#if question.hasCustomOption} {#if question.hasCustomOption}
<div class="option"> <ModernRadioButton
<input
type="checkbox"
id={`${id}-custom`} id={`${id}-custom`}
value={customOption}
labelIntl={survey.string.AnswerCustomOption}
bind:group={selectedOption}
on:change={optionChange}
/>
{#if selectedOption === customOption}
<div class="pl-6">
<EditBox
kind={'ghost-large'}
bind:value={answer}
placeholder={survey.string.AnswerPlaceholder}
focusable
autoFocus
on:change={answerChange}
/>
</div>
{/if}
{/if}
</div>
{:else if question.kind === QuestionKind.OPTIONS}
<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]} bind:checked={selectedOptions[customOption]}
on:change={optionsChange} on:change={optionsChange}
/> />
<label class="option__label" for={`${id}-custom`}>
<Label label={survey.string.AnswerCustomOption} />
</label>
{#if selectedOptions[customOption]} {#if selectedOptions[customOption]}
<div class="option__custom"> <div class="pl-6">
<EditBox bind:value={answer} on:change={answerChange} placeholder={survey.string.AnswerPlaceholder} /> <EditBox
kind={'ghost-large'}
bind:value={answer}
placeholder={survey.string.AnswerPlaceholder}
focusable
autoFocus
on:change={answerChange}
/>
</div> </div>
{/if} {/if}
</div>
{/if} {/if}
</div>
{:else} {:else}
<div class="option"> <EditBox
<EditBox bind:value={answer} on:change={answerChange} placeholder={survey.string.AnswerPlaceholder} /> kind={'ghost-large'}
</div> bind:value={answer}
placeholder={survey.string.AnswerPlaceholder}
focusable
on:change={answerChange}
/>
{/if} {/if}
</div> </div>
<style lang="scss"> <style lang="scss">
.option { :global(.question-answer-container + .question-answer-container) {
margin-left: 1em; padding-top: var(--spacing-2);
margin-top: 0.5em; border-top: 1px solid var(--theme-divider-color);
}
.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;
}
} }
</style> </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" 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>
<symbol id="note" viewBox="0 0 256 256"> <symbol id="note" viewBox="0 0 32 32">
<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> <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> </symbol>
</svg> </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 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" /> <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>
<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> </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`, Magnifier: `${icons}#magnifier`,
Home: `${icons}#home`, Home: `${icons}#home`,
RedCircle: `${icons}#red-circle`, RedCircle: `${icons}#red-circle`,
Labels: `${icons}#priority-nopriority`, // TODO: add icon Labels: `${icons}#labels`,
DueDate: `${icons}#dueDate`, // TODO: add icon DueDate: `${icons}#dueDate`, // TODO: add icon
Parent: `${icons}#parent-issue`, // TODO: add icon Parent: `${icons}#parent-issue`, // TODO: add icon
Milestone: `${icons}#milestone`, Milestone: `${icons}#milestone`,