diff --git a/packages/ui/src/components/calendar/DateInputBox.svelte b/packages/ui/src/components/calendar/DateInputBox.svelte index 792e40d800..47a30ae11c 100644 --- a/packages/ui/src/components/calendar/DateInputBox.svelte +++ b/packages/ui/src/components/calendar/DateInputBox.svelte @@ -22,6 +22,7 @@ export let currentDate: Date | null export let withTime: boolean = false + export let kind: 'default' | 'plain' = 'default' type TEdits = 'day' | 'month' | 'year' | 'hour' | 'min' interface IEdits { @@ -200,8 +201,9 @@ }) </script> -<div class="datetime-input"> +<div class="datetime-input {kind}"> <div class="flex-row-center"> + <!-- svelte-ignore a11y-no-noninteractive-tabindex --> <span bind:this={edits[0].el} class="digit" @@ -215,6 +217,7 @@ {:else}<Label label={ui.string.DD} />{/if} </span> <span class="separator">.</span> + <!-- svelte-ignore a11y-no-noninteractive-tabindex --> <span bind:this={edits[1].el} class="digit" @@ -228,6 +231,7 @@ {:else}<Label label={ui.string.MM} />{/if} </span> <span class="separator">.</span> + <!-- svelte-ignore a11y-no-noninteractive-tabindex --> <span bind:this={edits[2].el} class="digit" @@ -242,6 +246,7 @@ </span> {#if withTime} <div class="time-divider" /> + <!-- svelte-ignore a11y-no-noninteractive-tabindex --> <span bind:this={edits[3].el} class="digit" @@ -255,6 +260,7 @@ {:else}<Label label={ui.string.HH} />{/if} </span> <span class="separator">:</span> + <!-- svelte-ignore a11y-no-noninteractive-tabindex --> <span bind:this={edits[4].el} class="digit" @@ -270,9 +276,11 @@ {/if} </div> {#if currentDate} + <!-- svelte-ignore a11y-click-events-have-key-events --> + <!-- svelte-ignore a11y-no-noninteractive-tabindex --> <div class="close-btn" - tabindex="0" + tabindex={0} on:click={() => { selected = 'day' startTyping = true @@ -293,15 +301,9 @@ align-items: center; flex-shrink: 0; margin: 0; - padding: 0.75rem; height: 3rem; font-family: inherit; - font-size: 1rem; color: var(--theme-content-color); - background-color: var(--theme-bg-color); - border: 1px solid var(--theme-button-border); - border-radius: 0.25rem; - transition: border-color 0.15s ease; &:hover { border-color: var(--theme-button-default); @@ -332,9 +334,6 @@ .digit { position: relative; - padding: 0 0.125rem; - height: 1.5rem; - line-height: 1.5rem; color: var(--theme-caption-color); outline: none; border-radius: 0.125rem; @@ -355,14 +354,47 @@ } .time-divider { flex-shrink: 0; - margin: 0 0.25rem; width: 1px; min-width: 1px; - height: 0.75rem; background-color: var(--theme-button-border); } - .separator { - margin: 0 0.1rem; + + &.plain:not(.default) { + padding: 0.5rem 0; + font-size: 1.25rem; + + .digit { + padding: 0.5rem 0.125rem; + line-height: 1.25rem; + } + .separator { + margin: 0; + } + .time-divider { + margin: 0 0.375rem; + height: 1.5rem; + } + } + &.default:not(.plain) { + padding: 0.75rem; + font-size: 1rem; + background-color: var(--theme-bg-color); + border: 1px solid var(--theme-button-border); + border-radius: 0.25rem; + transition: border-color 0.15s ease; + + .digit { + padding: 0 0.125rem; + height: 1.5rem; + line-height: 1.5rem; + } + .separator { + margin: 0 0.1rem; + } + .time-divider { + margin: 0 0.25rem; + height: 0.75rem; + } } } </style> diff --git a/packages/ui/src/components/calendar/DatePopup.svelte b/packages/ui/src/components/calendar/DatePopup.svelte index 08a6613024..2e080314a8 100644 --- a/packages/ui/src/components/calendar/DatePopup.svelte +++ b/packages/ui/src/components/calendar/DatePopup.svelte @@ -16,15 +16,19 @@ import { DateRangeMode } from '@hcengineering/core' import { IntlString } from '@hcengineering/platform' import { createEventDispatcher } from 'svelte' + import { + ActionIcon, + Button, + Scroller, + deviceOptionsStore as deviceInfo, + checkAdaptiveMatching, + Label, + IconClose + } from '../..' import ui from '../../plugin' - import ActionIcon from '../ActionIcon.svelte' - import Button from '../Button.svelte' - import Label from '../Label.svelte' - import IconClose from '../icons/Close.svelte' import DateInputBox from './DateInputBox.svelte' import MonthSquare from './MonthSquare.svelte' import Shifts from './Shifts.svelte' - import { Scroller, deviceOptionsStore as deviceInfo } from '../..' export let currentDate: Date | null export let withTime: boolean = false @@ -36,7 +40,12 @@ const dispatch = createEventDispatcher() const today: Date = new Date(Date.now()) + $: devSize = $deviceInfo.size + $: oneMonth = checkAdaptiveMatching(devSize, 'sm') + $: docHeight = $deviceInfo.docHeight + const rem = (n: number, fs: number): number => n * fs + $: scrolled = docHeight < rem(39, $deviceInfo.fontSize) let viewDate: Date = currentDate ?? today let viewDateSec: Date @@ -93,51 +102,74 @@ /> </div> <div class="content"> - <Scroller padding={'1.5rem 2rem'} thinScrollBars> - <div class="label"> - <span class="bold"><Label {label} /></span> - {#if detail} - <span class="divider">-</span> - <Label label={detail} /> - {/if} - </div> - - <DateInputBox - bind:this={dateInput} - bind:currentDate - {withTime} - on:close={() => closeDP(withTime)} - on:save={() => saveDate(withTime)} - /> + {#if detail} + <div class="label"><Label label={detail} /></div> + {/if} + <DateInputBox + bind:this={dateInput} + bind:currentDate + {withTime} + kind={'plain'} + on:close={() => closeDP(withTime)} + on:save={() => saveDate(withTime)} + /> + <div class="divider" class:x2={!scrolled} /> + {#if scrolled} + <Scroller thinScrollBars> + <div class="divider" /> + <div class="month-group"> + <MonthSquare + bind:currentDate + {viewDate} + {mondayStart} + viewUpdate={false} + hideNavigator={'all'} + noPadding + on:update={(result) => updateDate(result.detail)} + /> + {#if !oneMonth} + <div class="space" /> + <MonthSquare + bind:currentDate + viewDate={viewDateSec} + {mondayStart} + viewUpdate={false} + noPadding + on:update={(result) => updateDate(result.detail)} + on:navigation={(result) => navigateMonth(result.detail)} + /> + {/if} + </div> + </Scroller> + {:else} <div class="month-group"> <MonthSquare bind:currentDate {viewDate} {mondayStart} viewUpdate={false} - hideNavigator="all" + hideNavigator={'all'} + noPadding on:update={(result) => updateDate(result.detail)} /> - <MonthSquare - bind:currentDate - viewDate={viewDateSec} - {mondayStart} - viewUpdate={false} - on:update={(result) => updateDate(result.detail)} - on:navigation={(result) => navigateMonth(result.detail)} - /> + {#if !oneMonth} + <div class="space" /> + <MonthSquare + bind:currentDate + viewDate={viewDateSec} + {mondayStart} + viewUpdate={false} + noPadding + on:update={(result) => updateDate(result.detail)} + on:navigation={(result) => navigateMonth(result.detail)} + /> + {/if} </div> - </Scroller> + {/if} </div> <div class="footer"> - <Button - kind={'accented'} - label={ui.string.Save} - size={'x-large'} - width={'100%'} - on:click={() => closeDP(withTime)} - /> + <Button kind={'accented'} label={ui.string.Save} size={'large'} on:click={() => closeDP(withTime)} /> </div> </div> <Shifts @@ -159,7 +191,7 @@ max-height: calc(100vh - 2rem); width: max-content; height: max-content; - color: var(--caption-color); + color: var(--theme-caption-color); background: var(--theme-popup-color); border-radius: 0.5rem; box-shadow: var(--theme-popup-shadow); @@ -168,42 +200,46 @@ display: flex; justify-content: space-between; align-items: center; - padding: 1rem 1.5rem 1rem 2rem; - border-bottom: 1px solid var(--theme-popup-divider); + padding: 1.5rem; } .content { overflow: hidden; display: flex; flex-direction: column; + padding: 0 1.5rem 1.5rem; min-height: 0; .label { - padding-left: 2px; margin-bottom: 0.25rem; - font-size: 0.8125rem; - color: var(--theme-content-color); - - .bold { - font-weight: 500; - color: var(--theme-caption-color); - } - .divider { - margin: 0 0.25rem; - line-height: 1.4375rem; - color: var(--theme-darker-color); - } + font-size: 0.875rem; + color: var(--theme-dark-color); } .month-group { display: flex; flex-wrap: nowrap; - margin: 0.5rem -0.5rem 0; + + .space { + flex-shrink: 0; + width: 2rem; + } + } + } + .divider { + flex-shrink: 0; + height: 0.75rem; + + &.x2 { + height: 1.5rem; } } .footer { - padding: 1rem 2rem; + display: flex; + flex-direction: row-reverse; + align-items: center; + padding: 1rem 1.5rem; border-top: 1px solid var(--theme-popup-divider); } } diff --git a/packages/ui/src/components/calendar/MonthSquare.svelte b/packages/ui/src/components/calendar/MonthSquare.svelte index c15135a493..ac494af367 100644 --- a/packages/ui/src/components/calendar/MonthSquare.svelte +++ b/packages/ui/src/components/calendar/MonthSquare.svelte @@ -14,9 +14,9 @@ --> <script lang="ts"> import { afterUpdate, createEventDispatcher } from 'svelte' - import IconNavPrev from '../icons/NavPrev.svelte' - import IconNavNext from '../icons/NavNext.svelte' - import Icon from '../Icon.svelte' + import IconArrowLeft from '../icons/ArrowLeft.svelte' + import IconArrowRight from '../icons/ArrowRight.svelte' + import Button from '../Button.svelte' import { firstDay, day, getWeekDayName, areDatesEqual, getMonthName, weekday, isWeekend } from './internal/DateUtils' import { capitalizeFirstLetter } from '../../utils' @@ -25,6 +25,7 @@ export let mondayStart: boolean = true export let hideNavigator: 'all' | 'left' | 'right' | 'none' = 'none' export let viewUpdate: boolean = true + export let noPadding: boolean = false export let displayedWeeksCount = 6 export let selectedTo: Date | null | undefined = undefined @@ -81,32 +82,36 @@ <div class="month-container"> <div class="header"> {#if viewDate} - <div - class="btn" - class:hideNavigator={hideNavigator === 'left' || hideNavigator === 'all'} - on:click={() => { - if (viewUpdate) viewDate.setMonth(viewDate.getMonth() - 1) - dispatch('navigation', -1) - }} - > - <div class="icon-btn"><Icon icon={IconNavPrev} size={'full'} /></div> - </div> <div class="monthYear">{monthYear}</div> - <div - class="btn" - class:hideNavigator={hideNavigator === 'right' || hideNavigator === 'all'} - on:click={() => { - if (viewUpdate) viewDate.setMonth(viewDate.getMonth() + 1) - dispatch('navigation', 1) - }} - > - <div class="icon-btn"><Icon icon={IconNavNext} size={'full'} /></div> + <div class="flex-row-center gap-1-5 mr-1"> + {#if !(hideNavigator === 'left' || hideNavigator === 'all')} + <Button + kind={'ghost'} + size={'medium'} + icon={IconArrowLeft} + on:click={() => { + if (viewUpdate) viewDate.setMonth(viewDate.getMonth() - 1) + dispatch('navigation', -1) + }} + /> + {/if} + {#if !(hideNavigator === 'right' || hideNavigator === 'all')} + <Button + kind={'ghost'} + size={'medium'} + icon={IconArrowRight} + on:click={() => { + if (viewUpdate) viewDate.setMonth(viewDate.getMonth() + 1) + dispatch('navigation', 1) + }} + /> + {/if} </div> {/if} </div> {#if viewDate} - <div class="calendar"> + <div class="calendar" class:noPadding> {#each [...Array(7).keys()] as dayOfWeek} <span class="caption" >{capitalizeFirstLetter(getWeekDayName(day(firstDayOfCurrentMonth, dayOfWeek), 'short'))}</span @@ -125,6 +130,7 @@ class:endRow={dayOfWeek === 6 || isNextDateWrong(date) || isEnd(currentDate, selectedTo, date)} class:wrongMonth={wrongM} > + <!-- svelte-ignore a11y-click-events-have-key-events --> <div class="day" class:weekend={isWeekend(date)} @@ -161,14 +167,16 @@ flex-direction: column; min-height: 0; height: 100%; - color: var(--caption-color); + color: var(--theme-caption-color); .header { display: flex; justify-content: space-between; align-items: center; - padding: 1rem 0.5rem 0.75rem; - color: var(--caption-color); + flex-shrink: 0; + margin-bottom: 0.25rem; + height: 2.25rem; + color: var(--theme-caption-color); .monthYear { font-weight: 500; @@ -177,29 +185,6 @@ text-transform: capitalize; } } - .hideNavigator { - visibility: hidden; - } - - .btn { - display: flex; - justify-content: center; - align-items: center; - width: 2rem; - height: 2rem; - color: var(--dark-color); - border-radius: 0.25rem; - background-color: var(--theme-refinput-color); - border: 1px solid var(--theme-refinput-color); - cursor: pointer; - - .icon-btn { - height: 0.75rem; - } - &:hover { - color: var(--accent-color); - } - } } } @@ -207,7 +192,6 @@ position: relative; display: grid; grid-template-columns: repeat(7, 1fr); - padding: 0 1rem 1rem; .caption, .day { @@ -217,17 +201,23 @@ width: 2rem; height: 2rem; font-size: 1rem; - color: var(--content-color); + color: var(--theme-content-color); } .caption { - align-items: start; - height: 2rem; - padding: 0.25rem; - color: var(--dark-color); + margin-bottom: 0.5rem; + height: 2.25rem; + color: var(--theme-dark-color); &::first-letter { text-transform: capitalize; } } + &:not(.noPadding) { + padding: 0 1rem 1rem; + + .caption { + padding: 0.25rem; + } + } .container { border: 0px solid transparent; @@ -236,8 +226,7 @@ &.range:not(.wrongMonth), &.selected:not(.wrongMonth) { - color: var(--caption-color); - background-color: var(--accented-button-transparent); + color: var(--theme-caption-color); } &.startRow:not(.wrongMonth) { border-top-left-radius: 0.25rem; @@ -255,24 +244,24 @@ .day { position: relative; - color: var(--accent-color); - background-color: rgba(var(--accent-color), 0.05); + color: var(--theme-content-color); + // background-color: rgba(var(--theme-content-color), 0.05); border: 1px solid transparent; border-radius: 0.25rem; cursor: pointer; &.weekend { - color: var(--content-color); + color: var(--theme-content-color); } &.wrongMonth { - color: var(--dark-color); + color: var(--theme-trans-color); cursor: default; } &.today:not(.worngMonth, .selected, .range) { font-weight: 500; - background-color: rgba(76, 56, 188, 0.2); - border-radius: 50%; + background-color: var(--theme-button-focused); + border-color: var(--theme-button-border); } &.selected:not(.wrongMonth) { color: var(--accented-button-color); @@ -280,7 +269,7 @@ } &:not(.wrongMonth):hover { - color: var(--caption-color); + color: var(--theme-caption-color); background-color: var(--accented-button-transparent); } } @@ -288,11 +277,11 @@ &::before { position: absolute; content: ''; - top: 2rem; + top: 2.25rem; left: 0; width: 100%; height: 1px; - background-color: var(--button-bg-color); + background-color: var(--theme-divider-color); } } </style>