TSK-828, TSK-832: Fixed the application panel and scroll bars (#2733)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2023-03-15 08:58:43 +03:00 committed by GitHub
parent 0db9d1f786
commit 874dfda395
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 247 additions and 99 deletions

View File

@ -19,6 +19,8 @@
import { closeTooltip, tooltipstore } from '../tooltips'
import type { FadeOptions } from '../types'
import { defaultSP } from '../types'
import IconUpOutline from './icons/UpOutline.svelte'
import IconDownOutline from './icons/DownOutline.svelte'
export let padding: string | undefined = undefined
export let autoscroll: boolean = false
@ -28,22 +30,24 @@
export let horizontal: boolean = false
export let contentDirection: 'vertical' | 'vertical-reverse' | 'horizontal' = 'vertical'
export let noStretch: boolean = autoscroll
export let buttons: boolean = false
export let divScroll: HTMLElement | undefined = undefined
export function scroll (top: number, left?: number, behavior: 'auto' | 'smooth' = 'auto') {
if (divScroll && divHScroll) {
if (divScroll) {
if (top !== 0) divScroll.scroll({ top, left: 0, behavior })
if (left !== 0 || left !== undefined) divHScroll.scroll({ top: 0, left, behavior })
if (left !== 0 || left !== undefined) divScroll.scroll({ top: 0, left, behavior })
}
}
export function scrollBy (top: number, left?: number, behavior: 'auto' | 'smooth' = 'auto') {
if (divScroll && divHScroll) {
if (divScroll) {
if (top !== 0) divScroll.scrollBy({ top, left: 0, behavior })
if (left !== 0 || left !== undefined) divHScroll.scrollBy({ top: 0, left, behavior })
if (left !== 0 || left !== undefined) divScroll.scrollBy({ top: 0, left, behavior })
}
}
const dispatch = createEventDispatcher()
const stepScroll = 52
let mask: 'top' | 'bottom' | 'both' | 'none' = 'none'
let topCrop: 'top' | 'bottom' | 'full' | 'none' = 'none'
@ -54,6 +58,7 @@
let divBox: HTMLElement
let divBar: HTMLElement
let divBarH: HTMLElement
let divScrollContainer: HTMLElement
let isScrolling: 'vertical' | 'horizontal' | false = false
let dXY: number
let belowContent: number | undefined = undefined
@ -62,6 +67,7 @@
let rightContent: number | undefined = undefined
let scrolling: boolean = autoscroll
let firstScroll: boolean = autoscroll
let orientir: 'vertical' | 'horizontal' = 'vertical'
let timer: number
let timerH: number
@ -69,8 +75,9 @@
const inter = new Set<Element>()
$: fz = $themeOptions.fontSize
$: shiftTop = fade.offset?.top ? (fade.multipler?.top ?? 0) * fz : 0
$: shiftBottom = fade.offset?.bottom ? fade.multipler?.bottom! * fz : 0
$: shiftTop = fade.multipler?.top ? fade.multipler?.top * fz : 0
$: shiftBottom = fade.multipler?.bottom ? fade.multipler?.bottom * fz : 0
$: orientir = contentDirection === 'horizontal' ? 'horizontal' : 'vertical'
const checkBar = (): void => {
if (divBar && divScroll) {
@ -78,7 +85,7 @@
const scrollH = divScroll.scrollHeight
const proc = scrollH / trackH
divBar.style.height = divScroll.clientHeight / proc + 'px'
divBar.style.top = divScroll.scrollTop / proc + shiftTop + shiftBottom + 2 + 'px'
divBar.style.top = divScroll.scrollTop / proc + shiftTop + 2 + 'px'
if (mask === 'none') divBar.style.visibility = 'hidden'
else {
divBar.style.visibility = 'visible'
@ -260,7 +267,7 @@
const checkIntersectionFade = () => {
topCrop = 'none'
topCropValue = 0
if (!fade.offset?.top || !divScroll) return
if (!fade.multipler?.top || !divScroll) return
const offset = divScroll.getBoundingClientRect().top
inter.forEach((el) => {
const rect = el.getBoundingClientRect()
@ -320,11 +327,24 @@
let divHeight: number
const _resize = (): void => checkFade()
const tapScroll = (n: number, dir: 'up' | 'down') => {
if (divScroll) {
if (orientir === 'horizontal') divScroll.scrollBy({ top: 0, left: dir === 'up' ? -n : n, behavior: 'smooth' })
else divScroll.scrollBy({ top: dir === 'up' ? -n : n, left: 0, behavior: 'smooth' })
}
}
</script>
<svelte:window on:resize={_resize} />
<div class="scroller-container {invertScroll ? 'invert' : 'normal'}">
<div
bind:this={divScrollContainer}
class="scroller-container {orientir} {invertScroll ? 'invert' : 'normal'}"
class:buttons
style:--scroller-header-height={`${fade.multipler?.top ?? 0.125}rem`}
style:--scroller-footer-height={`${fade.multipler?.bottom ?? 0.125}rem`}
>
<div bind:this={divHScroll} class="horizontalBox flex-col flex-shrink">
<div
bind:this={divScroll}
@ -362,6 +382,32 @@
</div>
</div>
</div>
{#if buttons}
<button
class="scrollButton top {orientir}"
style:visibility={(orientir === 'vertical' && (mask === 'top' || mask === 'both')) ||
(orientir === 'horizontal' && (maskH === 'right' || maskH === 'both'))
? 'visible'
: 'hidden'}
on:click|preventDefault|stopPropagation={() => tapScroll(stepScroll, 'up')}
>
<div style:transform={orientir === 'horizontal' ? 'rotate(-90deg)' : ''}>
<IconUpOutline size={'medium'} />
</div>
</button>
<button
class="scrollButton bottom {orientir}"
style:visibility={(orientir === 'vertical' && (mask === 'bottom' || mask === 'both')) ||
(orientir === 'horizontal' && (maskH === 'left' || maskH === 'both'))
? 'visible'
: 'hidden'}
on:click|preventDefault|stopPropagation={() => tapScroll(stepScroll, 'down')}
>
<div style:transform={orientir === 'horizontal' ? 'rotate(-90deg)' : ''}>
<IconDownOutline size={'medium'} />
</div>
</button>
{/if}
<div
class="bar"
class:hovered={isScrolling === 'vertical'}
@ -372,8 +418,8 @@
<div
class="track"
class:hovered={isScrolling === 'vertical'}
class:fadeTopOffset={fade.offset?.top}
class:fadeBottomOffset={fade.offset?.bottom}
class:fadeTopOffset={fade.multipler?.top}
class:fadeBottomOffset={fade.multipler?.bottom}
/>
{#if horizontal}
<div
@ -392,6 +438,61 @@
</div>
<style lang="scss">
.scrollButton {
position: absolute;
color: var(--caption-color);
background-color: transparent;
border: 1px solid transparent;
border-radius: 0.25rem;
visibility: hidden;
transform-origin: center;
transition-property: opacity, transform;
transition-timing-function: var(--timing-main);
transition-duration: 0.1s;
transform: scale(0.8);
opacity: 0.1;
&:hover,
&:focus {
transform: scale(1);
opacity: 0.8;
}
&:hover {
background-color: var(--button-bg-color);
}
&:focus {
border-color: var(--primary-edit-border-color);
}
&.vertical {
width: 2rem;
height: 1.25rem;
}
&.horizontal {
width: 1.25rem;
height: 2rem;
}
&.top.vertical {
top: calc(var(--scroller-header-height) - 2rem);
left: 50%;
transform: translateX(-50%);
}
&.top.horizontal {
top: 50%;
left: -2rem;
transform: translateY(-50%);
}
&.bottom.vertical {
right: 50%;
bottom: calc(var(--scroller-footer-height) - 2rem);
transform: translateX(50%);
}
&.bottom.horizontal {
right: -2rem;
bottom: 50%;
transform: translateY(50%);
}
}
.overflowXauto {
overflow-x: auto;
}
@ -408,6 +509,12 @@
min-width: 0;
min-height: 0;
&.buttons.vertical {
margin: 1.5rem 0;
}
&.buttons.horizontal {
margin: 0 1.5rem;
}
&.normal {
.track,
.bar {
@ -415,7 +522,7 @@
}
.track-horizontal,
.bar-horizontal {
bottom: 2px;
bottom: var(--scroller-footer-height);
}
}
&.invert {
@ -476,11 +583,11 @@
top: var(--scroller-header-height);
}
&.fadeBottomOffset {
top: var(--scroller-footer-height);
bottom: var(--scroller-footer-height);
}
}
.track-horizontal {
bottom: 2px;
bottom: var(--scroller-footer-height);
left: 2px;
right: 2px;
height: 8px;
@ -529,7 +636,7 @@
}
.bar-horizontal {
left: 2px;
bottom: 2px;
bottom: var(--scroller-footer-height);
height: 8px;
min-width: 2rem;
max-width: calc(100% - 12px);

View File

@ -223,14 +223,14 @@ interface Sides<T> {
right?: T
}
export interface FadeOptions {
offset?: Sides<boolean>
multipler?: Sides<number>
}
export const defaultSP: FadeOptions = { multipler: { top: 0, bottom: 0 } }
export const tableSP: FadeOptions = { offset: { top: true, bottom: true }, multipler: { top: 2.5, bottom: 2.5 } }
export const tableHRscheduleY: FadeOptions = { offset: { top: true }, multipler: { top: 5, bottom: 0 } }
export const issueSP: FadeOptions = { offset: { top: true }, multipler: { top: 3, bottom: 0 } }
export const emojiSP: FadeOptions = { offset: { top: true }, multipler: { top: 1.5, bottom: 0 } }
export const tableSP: FadeOptions = { multipler: { top: 2.5, bottom: 2.5 } }
export const topSP: FadeOptions = { multipler: { top: 2.5, bottom: 0 } }
export const tableHRscheduleY: FadeOptions = { multipler: { top: 5, bottom: 0 } }
export const issueSP: FadeOptions = { multipler: { top: 3, bottom: 0 } }
export const emojiSP: FadeOptions = { multipler: { top: 1.5, bottom: 0 } }
export interface DeviceOptions {
docWidth: number

View File

@ -16,7 +16,9 @@
import type { IntlString, Asset } from '@hcengineering/platform'
import type { AnySvelteComponent } from '@hcengineering/ui'
import { createEventDispatcher } from 'svelte'
import { Icon, tooltip, IconColStar } from '@hcengineering/ui'
import { Icon, tooltip } from '@hcengineering/ui'
import PreviewOn from './icons/PreviewOn.svelte'
import PreviewOff from './icons/PreviewOff.svelte'
export let label: IntlString
export let icon: Asset | AnySvelteComponent
@ -43,11 +45,11 @@
dispatch('visible', !hidden)
}}
>
<IconColStar
size={'small'}
fill={hidden ? 'var(--warning-color)' : 'var(--activity-status-busy)'}
border={'var(--button-border-hover)'}
/>
{#if hidden}
<PreviewOff size={'small'} />
{:else}
<PreviewOn size={'small'} />
{/if}
</div>
{/if}
</button>
@ -125,6 +127,7 @@
bottom: 0.25rem;
height: 1rem;
width: 1rem;
color: var(--activity-status-busy);
transform-origin: center center;
transform: scale(1);
opacity: 0.8;
@ -136,6 +139,7 @@
opacity: 1;
}
&.hidden {
color: var(--warning-color);
transform: scale(0.7);
opacity: 0.5;

View File

@ -15,7 +15,7 @@
<script lang="ts">
import type { Ref } from '@hcengineering/core'
import { createQuery } from '@hcengineering/presentation'
import { IconDownOutline, NavLink, Scroller } from '@hcengineering/ui'
import { NavLink, Scroller } from '@hcengineering/ui'
import type { Application } from '@hcengineering/workbench'
import workbench from '@hcengineering/workbench'
import { hideApplication, showApplication } from '../utils'
@ -24,6 +24,7 @@
export let active: Ref<Application> | undefined
export let apps: Application[] = []
export let direction: 'vertical' | 'horizontal' = 'vertical'
export let shown: boolean = false
let loaded: boolean = false
let hiddenAppsIds: Ref<Application>[] = []
@ -32,8 +33,6 @@
hiddenAppsIds = res.map((r) => r.attachedTo)
loaded = true
})
let shown: boolean = false
</script>
<div class="flex-{direction === 'horizontal' ? 'row-center' : 'col'} clear-mins apps-{direction} relative">
@ -43,6 +42,7 @@
padding={direction === 'horizontal' ? '.25rem 0' : '0 .5rem'}
horizontal={direction === 'horizontal'}
contentDirection={direction}
buttons
>
<div class="apps-space-{direction}" />
{#each apps.filter((it) => (shown ? true : !hiddenAppsIds.includes(it._id))) as app}
@ -63,11 +63,6 @@
{/each}
<div class="apps-space-{direction}" />
</Scroller>
<div class="thinButton {direction}" class:shown on:click={() => (shown = !shown)}>
<div class="clear-mins pointer-events-none" class:rotate90={direction === 'horizontal'}>
<IconDownOutline size={'medium'} />
</div>
</div>
{/if}
</div>
@ -93,66 +88,4 @@
width: 0.25rem;
}
}
.thinButton {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
transform-origin: center center;
border-radius: 0.5rem;
opacity: 0.2;
cursor: pointer;
transition-property: opacity, transform;
transition-timing-function: var(--timing-main);
transition-duration: 0.1s;
&.vertical {
top: 100%;
left: 50%;
width: 2.5rem;
transform: translateX(-50%) scale(0.6) rotate(0deg);
&:hover {
transform: translateX(-50%) scale(0.8);
}
}
&.horizontal {
left: 100%;
top: 50%;
height: 2.5rem;
transform: translateY(-50%) scale(0.6);
&:hover {
transform: translateY(-50%) scale(0.8);
}
&.shown {
transform: translateY(-50%) scale(0.9) rotate(180deg);
&:hover {
transform: translateY(-50%) scale(1) rotate(180deg);
}
}
}
&:hover {
transform: translateX(-50%) scale(0.8);
background-color: var(--accent-bg-color);
opacity: 0.9;
}
&.shown {
transform: translateX(-50%) scale(0.9) rotate(180deg);
opacity: 0.8;
&:hover {
transform: translateX(-50%) scale(1) rotate(180deg);
background-color: var(--accent-bg-color);
opacity: 1;
}
}
}
.rotate90 {
transform-origin: center center;
transform: rotate(-90deg);
}
</style>

View File

@ -8,7 +8,8 @@
Label,
ListView,
navigate,
Scroller
Scroller,
topSP
} from '@hcengineering/ui'
import setting, { settingId } from '@hcengineering/setting'
import view, { Action, ActionCategory } from '@hcengineering/view'
@ -134,7 +135,7 @@
{/each}
{:else}
<!-- Keyboard shortcuts -->
<Scroller padding={'0 .5rem'} fade={{ offset: { top: true }, multipler: { top: 2.5, bottom: 0 } }}>
<Scroller padding={'0 .5rem'} fade={topSP}>
<ListView count={actions.length} noScroll>
<svelte:fragment slot="category" let:item>
{@const action = actions[item]}

View File

@ -56,9 +56,11 @@
import NavHeader from './NavHeader.svelte'
import Navigator from './Navigator.svelte'
import SpaceView from './SpaceView.svelte'
import Settings from './icons/Settings.svelte'
export let client: Client
let contentPanel: HTMLElement
let shownMenu: boolean = false
const { setTheme } = getContext('theme') as any
setClient(client)
@ -442,8 +444,12 @@
mini={appsMini}
notify={false}
/>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="thinButton {appsDirection}" class:shownMenu on:click={() => (shownMenu = !shownMenu)}>
<Settings size={'small'} />
</div>
</div>
<Applications {apps} active={currentApplication?._id} direction={appsDirection} />
<Applications {apps} active={currentApplication?._id} direction={appsDirection} bind:shown={shownMenu} />
<div class="info-box {appsDirection}" class:vertical-mobile={appsDirection === 'vertical' && appsMini}>
<AppItem
icon={request.icon.Requests}
@ -473,6 +479,7 @@
notify={hasNotification}
/>
<div class="flex-center" class:mt-2={appsDirection === 'vertical'} class:ml-2={appsDirection === 'horizontal'}>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
id="profile-button"
class="cursor-pointer"
@ -590,12 +597,14 @@
}
.hamburger-container {
display: flex;
align-items: center;
flex-shrink: 0;
&.portrait {
margin-left: 0.375rem;
}
&.landscape {
flex-direction: column;
margin-top: 0.25rem;
}
&.mini {
@ -665,4 +674,47 @@
}
}
}
.thinButton {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
padding: 0.25rem;
background-color: transparent;
border-radius: 0.25rem;
opacity: 0.2;
cursor: pointer;
transition-property: opacity, color, background-color;
transition-timing-function: var(--timing-main);
transition-duration: 0.1s;
&.vertical {
margin-top: 0.5rem;
width: 2.5rem;
}
&.horizontal {
margin-left: 0.5rem;
height: 2.5rem;
}
&:hover {
color: var(--accent-color);
background-color: var(--accent-bg-color);
opacity: 0.9;
}
&.shownMenu {
color: var(--accent-color);
background-color: var(--button-bg-color);
opacity: 0.8;
&:hover {
color: var(--caption-color);
background-color: var(--button-bg-hover);
opacity: 1;
}
}
}
</style>

View File

@ -0,0 +1,13 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
{fill}
d="M22,13l-2.4-2.4c0.1-0.1,0.3-0.2,0.4-0.3c0.7-0.6,1.2-1.2,1.6-1.9c0.2-0.4,0-0.8-0.3-1c-0.4-0.2-0.8,0-1,0.3c-0.3,0.5-0.7,1-1.2,1.4h0c-1.6,1.3-4.1,2.2-7.1,2.2c-3,0-5.6-0.9-7.1-2.2h0c-0.6-0.5-1-0.9-1.2-1.4C3.5,7.3,3,7.1,2.7,7.3C2.3,7.5,2.1,8,2.3,8.3c0.4,0.7,0.9,1.4,1.6,1.9c0.1,0.1,0.3,0.2,0.4,0.3L2,13c-0.3,0.3-0.3,0.8,0,1.1c0.3,0.3,0.8,0.3,1.1,0l2.7-2.7c0.9,0.4,1.9,0.8,2.9,1l-0.9,3.3c-0.1,0.4,0.1,0.8,0.5,0.9c0.4,0.1,0.8-0.1,0.9-0.5l0.9-3.4c0.6,0.1,1.2,0.1,1.9,0.1c0.6,0,1.3,0,1.9-0.1l0.9,3.4c0.1,0.4,0.5,0.6,0.9,0.5c0.4-0.1,0.6-0.5,0.5-0.9l-0.9-3.3c1.1-0.2,2.1-0.6,2.9-1L21,14c0.3,0.3,0.8,0.3,1.1,0C22.3,13.7,22.3,13.3,22,13z"
/>
</svg>

View File

@ -0,0 +1,19 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
{fill}
d="M4.5,8.4C6.3,6.9,9,5.2,12,5.2c3,0,5.7,1.6,7.5,3.2c0.9,0.8,1.7,1.6,2.2,2.1c0.3,0.3,0.5,0.5,0.6,0.7c0.1,0.1,0.1,0.2,0.2,0.2c0,0,0,0,0,0.1l0,0l0,0l0,0c0,0,0,0-0.6,0.4c0.6,0.4,0.6,0.4,0.6,0.4l0,0l0,0l0,0c0,0,0,0,0,0.1c0,0-0.1,0.1-0.2,0.2c-0.1,0.2-0.3,0.4-0.6,0.7c-0.5,0.6-1.3,1.4-2.2,2.1c-1.9,1.5-4.5,3.2-7.5,3.2c-3,0-5.7-1.6-7.5-3.2c-0.9-0.8-1.7-1.6-2.2-2.1c-0.3-0.3-0.5-0.5-0.6-0.7c-0.1-0.1-0.1-0.2-0.2-0.2c0,0,0,0,0-0.1l0,0l0,0l0,0c0,0,0,0,0.6-0.4c-0.6-0.4-0.6-0.4-0.6-0.4l0,0l0,0l0,0c0,0,0,0,0-0.1c0,0,0.1-0.1,0.2-0.2c0.1-0.2,0.3-0.4,0.6-0.7C2.8,10,3.5,9.2,4.5,8.4z M2,12l-0.6-0.4c-0.2,0.3-0.2,0.6,0,0.9L2,12z M3,12c0.1,0.1,0.2,0.3,0.4,0.4c0.5,0.5,1.2,1.3,2.1,2c1.8,1.5,4.1,2.8,6.6,2.8c2.5,0,4.8-1.4,6.6-2.8c0.9-0.7,1.6-1.4,2.1-2c0.1-0.2,0.3-0.3,0.4-0.4c-0.1-0.1-0.2-0.3-0.4-0.4c-0.5-0.5-1.2-1.3-2.1-2c-1.8-1.5-4.1-2.8-6.6-2.8c-2.5,0-4.8,1.4-6.6,2.8c-0.9,0.7-1.6,1.4-2.1,2C3.2,11.7,3.1,11.9,3,12z M22,12l0.6,0.4c0.2-0.3,0.2-0.6,0-0.9L22,12z"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
{fill}
d="M8.8,12c0-1.8,1.5-3.2,3.2-3.2s3.2,1.5,3.2,3.2s-1.5,3.2-3.2,3.2S8.8,13.8,8.8,12z M12,10.2c-1,0-1.8,0.8-1.8,1.8s0.8,1.8,1.8,1.8s1.8-0.8,1.8-1.8S13,10.2,12,10.2z"
/>
</svg>

View File

@ -0,0 +1,19 @@
<script lang="ts">
export let size: 'small' | 'medium' | 'large'
const fill: string = 'currentColor'
</script>
<svg class="svg-{size}" {fill} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
{fill}
d="M9.12596 1.6386C9.46935 1.54354 9.83221 1.7032 9.99413 2.02058C10.3672 2.75182 11.1261 3.24991 12 3.24991C12.8739 3.24991 13.6328 2.75182 14.0059 2.02058C14.1678 1.7032 14.5307 1.54354 14.874 1.6386C16.5585 2.10488 18.0759 2.97031 19.3184 4.12565C19.5611 4.35128 19.6269 4.70939 19.4804 5.00657C19.3331 5.30525 19.25 5.64181 19.25 5.99991C19.25 7.24254 20.2574 8.24991 21.5 8.24991L21.5314 8.24968C21.8629 8.24495 22.1583 8.4585 22.2576 8.77486C22.5777 9.79388 22.75 10.8775 22.75 11.9999C22.75 12.7407 22.6749 13.4648 22.5318 14.1647C22.4548 14.541 22.1059 14.7984 21.7237 14.7608C21.6504 14.7536 21.5758 14.7499 21.5 14.7499C20.2574 14.7499 19.25 15.7573 19.25 16.9999C19.25 17.553 19.4486 18.0578 19.7793 18.4497C20.027 18.7433 20.0128 19.1766 19.7465 19.4534C18.4777 20.7718 16.8745 21.7677 15.0721 22.3043C14.6807 22.4208 14.2681 22.2028 14.1437 21.8139C13.8535 20.9059 13.0024 20.2499 12 20.2499C10.9976 20.2499 10.1465 20.9059 9.85629 21.8139C9.73195 22.2028 9.31927 22.4208 8.92789 22.3043C7.12545 21.7677 5.52229 20.7718 4.25353 19.4534C3.98716 19.1766 3.97299 18.7433 4.22072 18.4497C4.55139 18.0578 4.75 17.553 4.75 16.9999C4.75 15.7573 3.74264 14.7499 2.5 14.7499C2.42423 14.7499 2.34963 14.7536 2.27634 14.7608C1.89406 14.7984 1.54519 14.541 1.46821 14.1647C1.32505 13.4648 1.25 12.7407 1.25 11.9999C1.25 10.8775 1.42227 9.79389 1.74236 8.77485C1.84173 8.4585 2.13705 8.24495 2.4686 8.24968L2.5 8.24991C3.74264 8.24991 4.75 7.24254 4.75 5.99991C4.75 5.64181 4.66689 5.30526 4.51962 5.00657C4.3731 4.70939 4.43894 4.35128 4.68159 4.12565C5.92411 2.97031 7.44153 2.10488 9.12596 1.6386ZM6.08277 4.88982C6.19152 5.24114 6.25 5.61415 6.25 5.99991C6.25 7.88936 4.85261 9.45244 3.03493 9.71204C2.84898 10.4431 2.75 11.2095 2.75 11.9999C2.75 12.4293 2.77921 12.8515 2.83567 13.2647C4.74948 13.4345 6.25 15.042 6.25 16.9999C6.25 17.6668 6.0754 18.294 5.76971 18.8371C6.62645 19.6183 7.63002 20.2403 8.73362 20.6569C9.37706 19.5189 10.598 18.7499 12 18.7499C13.402 18.7499 14.6229 19.5189 15.2664 20.6569C16.37 20.2403 17.3735 19.6183 18.2303 18.8371C17.9246 18.294 17.75 17.6668 17.75 16.9999C17.75 15.042 19.2505 13.4345 21.1643 13.2647C21.2208 12.8515 21.25 12.4293 21.25 11.9999C21.25 11.2095 21.151 10.4431 20.9651 9.71204C19.1474 9.45243 17.75 7.88935 17.75 5.99991C17.75 5.61415 17.8085 5.24114 17.9172 4.88982C17.0618 4.17701 16.0762 3.61605 15.0018 3.24766C14.3184 4.15887 13.2287 4.74991 12 4.74991C10.7713 4.74991 9.68158 4.15887 8.99819 3.24766C7.92382 3.61605 6.93823 4.17701 6.08277 4.88982Z"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
{fill}
d="M7.75 12C7.75 9.65279 9.65279 7.75 12 7.75C14.3472 7.75 16.25 9.65279 16.25 12C16.25 14.3472 14.3472 16.25 12 16.25C9.65279 16.25 7.75 14.3472 7.75 12ZM12 9.25C10.4812 9.25 9.25 10.4812 9.25 12C9.25 13.5188 10.4812 14.75 12 14.75C13.5188 14.75 14.75 13.5188 14.75 12C14.75 10.4812 13.5188 9.25 12 9.25Z"
/>
</svg>