Merge pull request #2991 from gitbutlerapp/CSS-fixes

CSS fixes
This commit is contained in:
Pavel Laptev 2024-03-02 22:22:11 +01:00 committed by GitHub
commit 5f928c6d44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 84 additions and 50 deletions

View File

@ -14,6 +14,7 @@
export let iconAlign: 'left' | 'right' = 'right';
export let color: ButtonColor = 'primary';
export let kind: 'filled' | 'outlined' = 'filled';
export let isDropdownChild = false;
export let disabled = false;
export let notClickable = false;
export let id: string | undefined = undefined;
@ -27,9 +28,6 @@
export let element: HTMLAnchorElement | HTMLButtonElement | HTMLElement | null = null;
let className = '';
export { className as class };
const SLOTS = $$props.$$slots;
onMount(() => {
@ -39,7 +37,7 @@
</script>
<button
class={`btn ${className}`}
class="btn"
class:medium={size == 'medium'}
class:large={size == 'large'}
class:error-outline={color == 'error' && kind == 'outlined'}
@ -55,6 +53,7 @@
class:wide
class:grow
class:not-clickable={notClickable}
class:is-dropdown={isDropdownChild}
style:align-self={align}
style:width={width ? pxToRem(width) : undefined}
use:tooltip={help}
@ -78,6 +77,7 @@
<style lang="postcss">
.btn {
z-index: 1;
position: relative;
display: inline-flex;
align-items: center;
@ -198,4 +198,33 @@
height: var(--size-btn-l);
padding: var(--space-6) var(--space-8);
}
/* DROPDOWN */
.is-dropdown {
&:first-of-type {
flex: 1;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: none;
&.primary-filled {
&:after {
content: '';
z-index: 2;
position: absolute;
top: 0;
right: 0;
width: 1px;
height: 100%;
background: var(--clr-theme-scale-ntrl-100);
opacity: 0.4;
}
}
}
&:last-of-type {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
</style>

View File

@ -1,7 +1,6 @@
<script lang="ts">
import { clickOutside } from '$lib/clickOutside';
import Button from '$lib/components/Button.svelte';
import { joinClassNames } from '$lib/utils/joinClassNames';
import type iconsJson from '$lib/icons/icons.json';
export let icon: keyof typeof iconsJson | undefined = undefined;
@ -29,24 +28,17 @@
<div class="dropdown-wrapper" class:wide>
<div class="dropdown" bind:this={container}>
<Button
class={joinClassNames([
'dropdown__text-btn',
kind == 'outlined' ? 'dropdown__text-btn_outlined' : 'dropdown__text-btn_filled',
wide ? 'wide-text-btn' : ''
])}
{color}
{icon}
{kind}
{help}
iconAlign="left"
disabled={disabled || loading}
isDropdownChild
on:click><slot /></Button
>
<Button
class={joinClassNames([
'dropdown__icon-btn',
kind == 'outlined' ? 'dropdown__icon-btn_outlined' : ''
])}
class="dropdown__icon-btn"
bind:element={iconElt}
{color}
{kind}
@ -54,6 +46,7 @@
icon={visible ? 'chevron-top' : 'chevron-down'}
{loading}
disabled={disabled || loading}
isDropdownChild
on:click={() => (visible = !visible)}
/>
</div>
@ -97,18 +90,6 @@
}
}
.dropdown-wrapper :global(.dropdown__text-btn_outlined) {
transform: translateX(1px);
}
.dropdown-wrapper :global(.dropdown__text-btn_filled) {
border-right: 1px solid var(--clr-theme-scale-pop-50);
}
.dropdown-wrapper :global(.dropdown__icon-btn_outlined):disabled {
border-left: 1px solid transparent;
}
.dropdown {
display: flex;
flex-grow: 1;
@ -126,8 +107,4 @@
.wide {
width: 100%;
}
.dropdown-wrapper :global(.wide-text-btn) {
flex: 1;
}
</style>

View File

@ -26,9 +26,18 @@
style:fill-opacity={opacity}
style:width={pxToRem(size)}
style:height={pxToRem(size)}
style="--spinner-radius: {spinnerRadius}"
>
{#if name == 'spinner'}
<circle class="spinner-path" cx="8" cy="8" r={spinnerRadius} fill="none" />
<circle
class="spinner-back-path"
cx="8"
cy="8"
r="var(--spinner-radius)"
fill="none"
vector-effect="non-scaling-stroke"
/>
{:else}
<path fill="currentColor" d={iconsJson[name]} />
{/if}
@ -36,6 +45,7 @@
<style lang="postcss">
.icon-wrapper {
--spinner-stroke-width: calc(var(--space-2) / 1.4);
flex-shrink: 0;
pointer-events: none;
display: inline-block;
@ -64,22 +74,28 @@
}
}
.spinner-path {
stroke-width: calc(var(--space-2) / 1.3);
stroke-width: var(--spinner-stroke-width);
stroke: currentColor;
animation: spinning-path 1.5s infinite ease-in-out;
animation: spinning-path 2s infinite ease-in-out;
}
.spinner-back-path {
stroke-width: var(--spinner-stroke-width);
stroke: currentColor;
opacity: 0.3;
}
@keyframes spinning-path {
0% {
stroke-dasharray: 1, 200;
stroke-dasharray: 1, 120;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 60, 200;
stroke-dashoffset: -12;
60% {
stroke-dasharray: 60, 120;
stroke-dashoffset: -10;
}
100% {
stroke-dasharray: 60, 200;
stroke-dashoffset: -34;
stroke-dasharray: 60, 120;
stroke-dashoffset: calc(-1 * var(--spinner-radius) * 5.5);
}
}
</style>

View File

@ -58,7 +58,6 @@
const startedAt = checksStatus.startedAt;
if (!startedAt) return;
const secondsAgo = (new Date().getTime() - startedAt.getTime()) / 1000;
let timeUntilUdate: number | undefined = undefined;
if (secondsAgo < 600) {
timeUntilUdate = 30;
@ -67,12 +66,10 @@
} else if (secondsAgo < 3600) {
timeUntilUdate = 120;
}
if (!timeUntilUdate) {
// Stop polling for status.
return;
}
setTimeout(() => fetchPrStatus(), timeUntilUdate * 1000);
}
@ -80,6 +77,7 @@
$: checksColor = getChecksColor(checksStatus);
$: statusIcon = getStatusIcon();
$: statusColor = getStatusColor();
$: statusLabel = getPrStatusLabel();
$: if ($pr$) fetchPrStatus();
@ -90,23 +88,27 @@
if (status.completed) {
return status.success ? 'success' : 'error';
}
return 'warning';
}
function getChecksIcon(status: ChecksStatus): keyof typeof iconsJson | undefined {
if (status?.error) return 'error';
if (isFetching) return 'spinner';
if (status?.error) return 'error-small';
if (!status) return;
if (status && !status.hasChecks) return;
if (status.completed) {
return status.success ? 'success' : 'error';
return status.success ? 'success-small' : 'error-small';
}
return 'spinner';
}
function statusToTagText(status: ChecksStatus | undefined): string | undefined {
if (status?.error) return 'error';
if (!status) return;
if (status && !status.hasChecks) return;
if (status && !status.hasChecks) return 'No checks';
if (status.completed) {
return status.success ? 'Checks passed' : 'Checks failed';
}
@ -147,27 +149,36 @@
{$pr$.title}
</div>
<div class="pr-tags">
<Tag icon={statusIcon} color={statusColor} border verticalOrientation={isLaneCollapsed}>
{getPrStatusLabel()}
<Tag
icon={statusIcon}
color={statusColor}
filled={statusLabel !== 'open'}
verticalOrientation={isLaneCollapsed}
>
{statusLabel}
</Tag>
{#if branch.upstream && checksIcon}
<Tag
icon={checksIcon}
color={checksColor}
filled={checksIcon == 'success'}
filled={checksIcon == 'success-small'}
clickable
border
verticalOrientation={isLaneCollapsed}
on:click={fetchPrStatus}
help="Refresh checks status"
>
{statusToTagText(checksStatus)}
</Tag>
{:else}
<Tag color="light" verticalOrientation={isLaneCollapsed} help="Fetching checks status">
No checks
</Tag>
{/if}
<Tag
icon="open-link"
color="ghost"
border
clickable
border
verticalOrientation={isLaneCollapsed}
on:click={(e) => {
const url = $pr$?.htmlUrl;

View File

@ -55,7 +55,7 @@
</span>
{#if icon}
<div class="icon" class:verticalIcon={verticalOrientation}>
<Icon name={icon} />
<Icon name={icon} spinnerRadius={3.5} />
</div>
{/if}
</div>

View File

@ -1,4 +1,5 @@
.tooltip {
pointer-events: none;
background-color: var(--clr-core-ntrl-10);
border-radius: var(--radius-s);
border: 1px solid var(--clr-core-ntrl-30);