UBER-675: updated layout of Radio and Circle button (#3638)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2023-08-28 09:08:43 +03:00 committed by GitHub
parent f56d65dc20
commit 18b04717f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 207 additions and 92 deletions

View File

@ -38,6 +38,15 @@
--negative-button-pressed: #BF3636; --negative-button-pressed: #BF3636;
--negative-button-focused: #CA4242; --negative-button-focused: #CA4242;
--theme-primary-default: #205DC2;
--theme-primary-hovered: #3575DE;
--theme-primary-pressed: #1C52AB;
--theme-primary-disabled: #0000001F;
--theme-primary-accented-default: #D3E1F8;
--theme-primary-accented-hovered: #BDD2F5;
--theme-primary-accented-pressed: #A7C3F1;
--theme-primary-accented-focused: #BDD2F5;
--white-color: #fff; --white-color: #fff;
--duotone-color: rgba(126, 134, 158, .25); --duotone-color: rgba(126, 134, 158, .25);
@ -144,7 +153,6 @@
--theme-editbox-focus-color: rgba(255, 255, 255, .04); --theme-editbox-focus-color: rgba(255, 255, 255, .04);
--theme-editbox-focus-border: #5190EC; --theme-editbox-focus-border: #5190EC;
--theme-editbox-default-focus-border: #205DC2; // Light
--theme-tablist-color: rgba(0, 0, 0, .02); --theme-tablist-color: rgba(0, 0, 0, .02);
--theme-tablist-plain-color: #2A64C4; // Light --theme-tablist-plain-color: #2A64C4; // Light
--theme-tablist-plain-divider: rgba(255, 255, 255, .07); // Light invert --theme-tablist-plain-divider: rgba(255, 255, 255, .07); // Light invert
@ -340,7 +348,6 @@
--theme-editbox-focus-color: rgba(0, 0, 0, .08); --theme-editbox-focus-color: rgba(0, 0, 0, .08);
--theme-editbox-focus-border: #5190EC; --theme-editbox-focus-border: #5190EC;
--theme-editbox-default-focus-border: #205DC2;
--theme-tablist-color: rgba(0, 0, 0, .02); --theme-tablist-color: rgba(0, 0, 0, .02);
--theme-tablist-plain-color: #2A64C4; --theme-tablist-plain-color: #2A64C4;
--theme-tablist-plain-divider: rgba(0, 0, 0, .07); --theme-tablist-plain-divider: rgba(0, 0, 0, .07);

View File

@ -303,70 +303,115 @@
/* Radio Button */ /* Radio Button */
.antiRadio { .antiRadio {
position: absolute; position: relative;
width: 1px; display: inline-flex;
height: 1px; align-items: center;
margin: -1px; height: min-content;
border: 0; min-width: 0;
padding: 0; outline: none;
clip: rect(0 0 0 0);
overflow: hidden;
& + label { input {
position: relative; position: absolute;
margin-top: .375rem; width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
clip: rect(0 0 0 0);
overflow: hidden;
}
&.gap-none { margin-bottom: 0; }
&.gap-small { margin-bottom: .25rem; }
&.gap-medium { margin-bottom: .5rem; }
label {
padding-left: 1.375rem; padding-left: 1.375rem;
font-size: .8125rem; font-size: .8125rem;
color: var(--theme-content-color);
&.gap-none { margin-bottom: .375rem; }
&.gap-small { margin-bottom: .625rem; }
&.gap-medium { margin-bottom: .875rem; }
&::before,
&::after { &::after {
position: absolute; position: absolute;
border-radius: 50%; top: .25rem;
}
&::before {
content: '';
top: .0625rem;
left: 0;
width: 1rem;
height: 1rem;
background-color: var(--theme-button-default);
border: 1px solid var(--theme-button-border);
}
&::after {
top: .3125rem;
left: .25rem; left: .25rem;
width: .5rem; width: .5rem;
height: .5rem; height: .5rem;
background-color: var(--accented-button-color); background-color: var(--accented-button-color);
border-radius: 50%;
opacity: .8;
z-index: 1;
} }
} }
&:not(:disabled, :checked) + label:hover::before { background-color: var(--theme-button-hovered); }
&:not(:disabled):active + label::before { background-color: var(--theme-button-pressed); } &::before,
&:disabled + label::before { &::after {
background-color: var(--theme-button-border); position: absolute;
border-color: transparent; border-radius: 50%;
} }
&:focus + label::before { box-shadow: 0 0 0 2px var(--accented-button-outline); } &::before {
&:focus:not(:checked) + label::before { top: -.1875rem;
background-color: var(--theme-button-focused); left: -.1875rem;
border-color: var(--theme-button-focused-border); width: 1.375rem;
height: 1.375rem;
border: 1px solid var(--theme-primary-default);
} }
&:checked + label::before { &::after {
background-color: var(--accented-button-default); content: '';
border-color: var(--accented-button-border); top: 0rem;
left: 0rem;
width: 1rem;
height: 1rem;
background-color: var(--theme-button-default);
border: 1px solid var(--theme-divider-color);
} }
&:checked:focus + label::before { background-color: var(--accented-button-focused); } &:not(.disabled, .checked):hover {
&:checked:hover + label::before { background-color: var(--accented-button-hovered); } &::after { background-color: var(--theme-button-hovered); }
&:checked:active + label::before { background-color: var(--accented-button-pressed); } label { color: var(--theme-caption-color); }
&:checked:disabled + label::before { }
background-color: var(--accented-button-disabled); &.checked:not(.disabled):hover {
border-color: var(--theme-button-border); &::after { background-color: var(--theme-primary-hovered); }
label {
color: var(--theme-caption-color);
&::after { opacity: 1; }
}
}
&:focus-within:not(.disabled) {
&::before { content: ''; }
label { color: var(--theme-caption-color); }
&.checked {
label::after { opacity: 1; }
&:active::after { background-color: var(--theme-primary-pressed); }
}
}
&.checked:not(.disabled) {
&::after { background-color: var(--theme-primary-default); }
label::after { content: ''; }
}
&.disabled {
cursor: not-allowed;
&::after {
background-color: var(--theme-primary-disabled);
border-color: transparent;
}
label {
color: var(--theme-darker-color);
cursor: not-allowed;
}
&.checked label::after {
content: '';
opacity: .4;
}
}
&:not(.disabled),
&:not(.disabled) label { cursor: pointer; }
&:not(.disabled):active {
&::after { background-color: var(--theme-primary-pressed); }
label::after {
content: '';
opacity: 1;
}
} }
&:checked + label::after { content: ''; }
} }
/* StatesBar */ /* StatesBar */
@ -811,7 +856,7 @@
bottom: -.125rem; bottom: -.125rem;
left: -.125rem; left: -.125rem;
right: -.125rem; right: -.125rem;
border: 1px solid var(--theme-editbox-default-focus-border); border: 1px solid var(--theme-primary-default);
border-radius: .5rem; border-radius: .5rem;
z-index: -1; z-index: -1;
} }

View File

@ -85,7 +85,7 @@
&:hover { background-color: var(--theme-button-hovered); } &:hover { background-color: var(--theme-button-hovered); }
&.focusable:focus-within { &.focusable:focus-within {
background-color: var(--theme-button-focused); background-color: var(--theme-button-focused);
border-color: var(--theme-editbox-default-focus-border); border-color: var(--theme-primary-default);
} }
&.disabled { &.disabled {
color: var(--theme-dark-color); color: var(--theme-dark-color);

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte'
import type { Asset } from '@hcengineering/platform' import type { Asset } from '@hcengineering/platform'
import type { AnySvelteComponent, ButtonSize } from '../types' import type { AnySvelteComponent, ButtonSize } from '../types'
import Icon from './Icon.svelte' import Icon from './Icon.svelte'
@ -22,16 +23,30 @@
export let ghost: boolean = false export let ghost: boolean = false
export let selected: boolean = false export let selected: boolean = false
export let accented: boolean = false export let accented: boolean = false
export let disabled: boolean = false
export let id: string | undefined = undefined export let id: string | undefined = undefined
const dispatch = createEventDispatcher()
function onKeydown (key: KeyboardEvent): void {
if (key.code === 'Space') {
key.preventDefault()
key.stopPropagation()
dispatch('selected')
}
}
</script> </script>
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div <div
{id} {id}
class="flex-center icon-button icon-{size}" class="flex-center icon-button icon-{size}"
class:selected class:selected
class:ghost class:ghost
class:accented class:accented
class:disabled
tabindex="0"
on:keydown={onKeydown}
on:click|stopPropagation on:click|stopPropagation
on:mousemove on:mousemove
> >
@ -46,14 +61,39 @@
<style lang="scss"> <style lang="scss">
.icon-button { .icon-button {
position: relative;
flex-shrink: 0; flex-shrink: 0;
color: var(--caption-color); color: var(--theme-content-color);
border: 1px solid var(--trans-content-20); background-color: var(--theme-button-default);
border: 1px solid var(--theme-divider-color);
border-radius: 50%; border-radius: 50%;
outline: none;
cursor: pointer; cursor: pointer;
&::before {
position: absolute;
top: -0.25rem;
bottom: -0.25rem;
left: -0.25rem;
right: -0.25rem;
border: 1px solid var(--theme-primary-default);
border-radius: 50%;
}
&:hover { &:hover {
border-color: var(--button-border-hover); background-color: var(--theme-button-hovered);
}
&:active {
background-color: var(--theme-button-pressed);
}
&:focus {
background-color: var(--theme-button-focused);
&::before {
content: '';
}
}
&.disabled {
background-color: transparent;
} }
.content { .content {
pointer-events: none; pointer-events: none;
@ -69,14 +109,18 @@
} }
} }
&.accented { &.accented {
color: var(--accented-button-color); background-color: var(--theme-primary-accented-default);
background-color: var(--accented-button-default);
border-color: var(--accented-button-border);
&:hover { &:hover {
background-color: var(--accented-button-hovered); background-color: var(--theme-primary-accented-hovered);
} }
&:active { &:active {
background-color: var(--accented-button-pressed); background-color: var(--theme-primary-accented-pressed);
}
&:focus {
background-color: var(--theme-primary-accented-focused);
}
&.disabled {
background-color: var(--theme-primary-disabled);
} }
} }
} }

View File

@ -17,11 +17,15 @@
export let rowGap: number = 2.5 export let rowGap: number = 2.5
export let columnGap: number = 1.5 export let columnGap: number = 1.5
export let topGap: boolean = false export let topGap: boolean = false
export let equalHeight: boolean = false
export let alignItems: 'start' | 'center' | 'end' | 'stretch' = 'center'
$: style = `grid-template-columns: repeat(${column}, 1fr); row-gap: ${rowGap}rem; column-gap: ${columnGap}rem;` $: style = `grid-template-columns: repeat(${column}, 1fr); row-gap: ${rowGap}rem; column-gap: ${columnGap}rem;${
equalHeight ? ' grid-auto-rows: 1fr;' : ''
}`
</script> </script>
<div class="grid" {style} style:margin-top={topGap ? `${rowGap}rem` : 0}> <div class="grid" {style} style:margin-top={topGap ? `${rowGap}rem` : 0} style:align-items={alignItems}>
<slot /> <slot />
</div> </div>

View File

@ -21,6 +21,7 @@
export let group: any export let group: any
export let value: any export let value: any
export let disabled: boolean = false export let disabled: boolean = false
export let labelOverflow: boolean = false
export let label: string | undefined = undefined export let label: string | undefined = undefined
export let labelIntl: IntlString | undefined = undefined export let labelIntl: IntlString | undefined = undefined
export let labelParams: Record<string, any> | undefined = undefined export let labelParams: Record<string, any> | undefined = undefined
@ -28,22 +29,32 @@
export let gap: 'small' | 'medium' | 'none' = 'none' export let gap: 'small' | 'medium' | 'none' = 'none'
</script> </script>
<input <!-- svelte-ignore a11y-click-events-have-key-events -->
class="antiRadio" <div
{id} class="antiRadio gap-{gap}"
type="radio" class:disabled
bind:group class:checked={group === value}
{value} tabindex="-1"
{disabled}
on:click={() => { on:click={() => {
if (!disabled && group !== value) action() if (!disabled && group !== value) action()
}} }}
/> >
<label for={id} class="gap-{gap}"> <input
<slot /> {id}
{#if labelIntl} type="radio"
<Label label={labelIntl} params={labelParams} /> bind:group
{:else} {value}
{label} {disabled}
{/if} on:click={() => {
</label> if (!disabled && group !== value) action()
}}
/>
<label for={id} class:overflow-label={labelOverflow}>
<slot />
{#if labelIntl}
<Label label={labelIntl} params={labelParams} />
{:else}
{label}
{/if}
</label>
</div>

View File

@ -111,6 +111,7 @@
</script> </script>
{#if object !== undefined} {#if object !== undefined}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<Panel <Panel
icon={board.icon.Card} icon={board.icon.Card}
title={object?.title} title={object?.title}

View File

@ -20,6 +20,7 @@
DropdownIntlItem, DropdownIntlItem,
DropdownLabelsIntl, DropdownLabelsIntl,
Grid, Grid,
Row,
Label, Label,
NumberInput, NumberInput,
RadioButton RadioButton
@ -121,12 +122,13 @@
{#if periodType === 'WEEKLY'} {#if periodType === 'WEEKLY'}
<div class="flex-row-center mt-3"> <div class="flex-row-center mt-3">
<span class="min-w-12"><Label label={calendar.string.On} /></span> <span class="min-w-12"><Label label={calendar.string.On} /></span>
<div class="flex-row-center flex-gap-2 ml-1-5"> <div class="flex-row-center gap-1-5 ml-1-5">
{#each weekdays as day} {#each weekdays as day}
<CircleButton <CircleButton
size="medium" size={'medium'}
accented={isActive(day.id, selectedWeekdays)} accented={isActive(day.id, selectedWeekdays)}
on:click={() => weekdayClick(day.id)} on:click={() => weekdayClick(day.id)}
on:selected={() => weekdayClick(day.id)}
> >
<div class="flex-row-center weekday" slot="content"> <div class="flex-row-center weekday" slot="content">
<Label label={day.label} /> <Label label={day.label} />
@ -139,16 +141,17 @@
<div class="flex-row-center mt-3 mb-3 min-h-8"> <div class="flex-row-center mt-3 mb-3 min-h-8">
<Label label={calendar.string.Ends} /> <Label label={calendar.string.Ends} />
</div> </div>
<Grid columnGap={0.375} rowGap={0.75}> <Grid columnGap={0.375} rowGap={0.75} equalHeight>
<RadioButton <Row>
labelIntl={calendar.string.Never} <RadioButton
value={'never'} labelIntl={calendar.string.Never}
group={selected} value={'never'}
action={() => { group={selected}
selected = 'never' action={() => {
}} selected = 'never'
/> }}
<div /> />
</Row>
<RadioButton <RadioButton
labelIntl={calendar.string.OnUntil} labelIntl={calendar.string.OnUntil}
value={'on'} value={'on'}
@ -215,7 +218,7 @@
.weekday { .weekday {
overflow: hidden; overflow: hidden;
font-size: 0.75rem; font-size: 0.6875rem;
} }
.pool { .pool {