Merge pull request #4886 from gitbutlerapp/UI-fixes-Hunk-preview-and-checkboxes

UI fixes: Hunk preview and checkboxes
This commit is contained in:
Esteban Vega 2024-09-12 10:46:56 +02:00 committed by GitHub
commit a6692415e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 123 additions and 238 deletions

View File

@ -1,11 +1,10 @@
<script lang="ts">
import HunkViewer from '$lib/hunk/HunkViewer.svelte';
import InfoMessage from '$lib/shared/InfoMessage.svelte';
import LargeDiffMessage from '$lib/shared/LargeDiffMessage.svelte';
import { computeAddedRemovedByHunk } from '$lib/utils/metrics';
import { getLocalCommits, getLocalAndRemoteCommits } from '$lib/vbranches/contexts';
import { getLockText } from '$lib/vbranches/tooltip';
import Icon from '@gitbutler/ui/Icon.svelte';
import Tooltip from '@gitbutler/ui/Tooltip.svelte';
import type { HunkSection, ContentSection } from '$lib/utils/fileSections';
interface Props {
@ -68,22 +67,26 @@
{#each sections as section}
{@const { added, removed } = computeAddedRemovedByHunk(section)}
{#if 'hunk' in section}
{@const isHunkLocked = section.hunk.lockedTo && section.hunk.lockedTo.length > 0 && commits}
<div class="hunk-wrapper">
<div class="indicators text-11 text-semibold">
<div class="text-10 semibold added-removed">
<span class="added">+{added}</span>
<span class="removed">-{removed}</span>
{#if isHunkLocked || section.hunk.poisoned}
<div class="indicators text-11 text-semibold">
{#if isHunkLocked}
<InfoMessage filled outlined={false} style="warning" icon="locked">
<svelte:fragment slot="content"
>{getLockText(section.hunk.lockedTo, commits)}</svelte:fragment
>
</InfoMessage>
{/if}
{#if section.hunk.poisoned}
<InfoMessage filled outlined={false}>
<svelte:fragment slot="content"
>Can not manage this hunk because it depends on changes from multiple branches</svelte:fragment
>
</InfoMessage>
{/if}
</div>
{#if section.hunk.lockedTo && section.hunk.lockedTo.length > 0 && commits}
<Tooltip text={getLockText(section.hunk.lockedTo, commits)}>
<Icon name="locked-small" color="warning" />
</Tooltip>
{/if}
{#if section.hunk.poisoned}
Can not manage this hunk because it depends on changes from multiple branches
{/if}
</div>
{/if}
<HunkViewer
{filePath}
{section}
@ -116,30 +119,10 @@
flex-direction: column;
gap: 10px;
}
.indicators {
display: flex;
align-items: center;
gap: 2px;
}
.added-removed {
display: flex;
border-radius: var(--radius-s);
overflow: hidden;
}
.removed,
.added {
padding: 2px 4px;
}
.added {
color: var(--clr-scale-succ-30);
background-color: var(--clr-theme-succ-bg);
}
.removed {
color: var(--clr-scale-err-30);
background-color: var(--clr-theme-err-bg);
}
</style>

View File

@ -311,9 +311,10 @@
{#snippet countColumn(row: Row, side: CountColumnSide)}
<td
class="table__numberColumn"
data-no-drag
class:diff-line-deletion={row.type === SectionType.RemovedLines}
class:diff-line-addition={row.type === SectionType.AddedLines}
style="--number-col-width: {NUMBER_COLUMN_WIDTH_PX}px;"
style="--number-col-width: {NUMBER_COLUMN_WIDTH_PX + 2}px;"
align="center"
class:is-last={row.isLast}
class:is-before={side === CountColumnSide.Before}
@ -329,46 +330,43 @@
<div
bind:clientWidth={tableWidth}
class="table__wrapper hide-native-scrollbar"
style="--tab-size: {tabSize}; --cursor: {draggingDisabled ? 'default' : 'grab'}"
style="--tab-size: {tabSize}"
>
<ScrollableContainer horz padding={{ left: NUMBER_COLUMN_WIDTH_PX * 2 + 2 }}>
<table data-hunk-id={hunk.id} class="table__section">
<thead>
<tr>
<th
class="table__checkbox-container"
class:selected={isSelected}
colspan={2}
onclick={() => {
selectable && handleSelected(hunk, !isSelected);
}}
>
<thead class="table__title">
<tr
onclick={() => {
selectable && handleSelected(hunk, !isSelected);
}}
>
<th class="table__checkbox-container" class:selected={isSelected} colspan={2}>
<div class="table__checkbox">
<Checkbox
checked={isSelected}
style="blue"
onclick={() => {
selectable && handleSelected(hunk, !isSelected);
}}
/>
</div>
<div
class="table__title"
style="--number-col-width: {NUMBER_COLUMN_WIDTH_PX}px; --table-width: {tableWidth}px"
>
<p class="table__title-content text-12">
{`@@ -${hunkLineInfo.beforLineStart},${hunkLineInfo.beforeLineCount} +${hunkLineInfo.afterLineStart},${hunkLineInfo.afterLineCount} @@`}
</p>
{#if !draggingDisabled}
<div class="table__drag-handle">
<Icon name="draggable-narrow" />
</div>
{#if selectable}
<Checkbox
checked={isSelected}
small
onclick={() => {
selectable && handleSelected(hunk, !isSelected);
}}
/>
{/if}
</div>
</th>
<th class="table__title-container"> </th>
<td class="table__title-content">
<span style="left: {NUMBER_COLUMN_WIDTH_PX * 2}px">
{`@@ -${hunkLineInfo.beforLineStart},${hunkLineInfo.beforeLineCount} +${hunkLineInfo.afterLineStart},${hunkLineInfo.afterLineCount} @@`}
</span>
{#if !draggingDisabled}
<div class="table__drag-handle">
<Icon name="draggable" />
</div>
{/if}
</td>
</tr>
</thead>
<tbody>
{#each renderRows as row}
<tr data-no-drag>
@ -399,40 +397,23 @@
</ScrollableContainer>
</div>
<style>
<style lang="postcss">
.table__wrapper {
border-radius: var(--radius-s);
border-radius: var(--radius-m);
background-color: var(--clr-diff-line-bg);
overflow-x: auto;
border: 1px solid var(--clr-border-2);
&:hover .table__drag-handle {
transform: translateY(0) translateX(0) scale(1);
transform: scale(1);
opacity: 1;
pointer-events: auto;
}
}
.table__drag-handle {
box-sizing: border-box;
cursor: grab;
background-color: var(--clr-bg-1);
display: flex;
justify-content: center;
align-items: center;
border-radius: var(--radius-s);
opacity: 0;
transform: translateY(10%) translateX(-10%) scale(0.9);
transform-origin: top right;
pointer-events: none;
transition:
opacity 0.2s,
transform 0.2s;
}
table,
.table__section {
width: 100%;
font-family: monospace;
font-family: var(--mono-font-family);
border-collapse: separate;
border-spacing: 0;
}
@ -453,12 +434,14 @@
top: 0;
left: 0;
position: sticky;
height: 28px;
}
.table__checkbox-container {
/* border: 1px solid var(--clr-border-2); */
z-index: var(--z-lifted);
box-shadow: inset 0 0 0 1px var(--clr-border-2);
border-right: 1px solid var(--clr-border-2);
border-bottom: 1px solid var(--clr-border-2);
background-color: var(--clr-diff-count-bg);
border-top-left-radius: var(--radius-s);
box-sizing: border-box;
@ -466,7 +449,8 @@
&.selected {
background-color: var(--clr-diff-selected-count-bg);
border-color: var(--clr-diff-selected-count-border);
box-shadow: inset 0 0 0 1px var(--clr-diff-selected-count-border);
border-right: 1px solid var(--clr-diff-selected-count-border);
border-bottom: 1px solid var(--clr-diff-selected-count-border);
}
}
@ -477,24 +461,38 @@
}
.table__title {
position: absolute;
top: 0;
left: calc(var(--number-col-width) * 2);
width: calc(var(--table-width) - var(--number-col-width) * 2);
cursor: grab;
user-select: none;
}
.table__drag-handle {
position: fixed;
right: 6px;
top: 6px;
box-sizing: border-box;
background-color: var(--clr-bg-1);
display: flex;
justify-content: center;
align-items: center;
justify-content: space-between;
border-top: 1px solid var(--clr-border-2);
border-right: 1px solid var(--clr-border-2);
border-bottom: 1px solid var(--clr-border-2);
border-top-right-radius: var(--radius-s);
border-radius: var(--radius-s);
opacity: 0;
transform: scale(0.9);
transform-origin: top right;
pointer-events: none;
color: var(--clr-text-2);
transition:
opacity 0.2s,
transform 0.2s;
}
.table__title-content {
position: relative;
font-family: var(--mono-font-family);
font-size: 12px;
padding: 4px 6px;
text-wrap: nowrap;
color: var(--clr-text-2);
border-bottom: 1px solid var(--clr-border-2);
}
.table__numberColumn {
@ -505,7 +503,6 @@
text-align: center;
padding: 0 4px;
text-align: right;
cursor: var(--cursor);
user-select: none;
position: sticky;
@ -513,23 +510,22 @@
width: var(--number-col-width);
min-width: var(--number-col-width);
box-shadow: inset -1px 0 0 0 var(--clr-diff-count-border);
border-right: 1px solid var(--clr-border-2);
&.diff-line-addition {
background-color: var(--clr-diff-addition-count-bg);
color: var(--clr-diff-addition-count-text);
box-shadow: inset -1px 0 0 0 var(--clr-diff-addition-count-border);
border-color: var(--clr-diff-addition-count-border);
}
&.diff-line-deletion {
background-color: var(--clr-diff-deletion-count-bg);
color: var(--clr-diff-deletion-count-text);
box-shadow: inset -1px 0 0 0 var(--clr-diff-deletion-count-border);
border-color: var(--clr-diff-deletion-count-border);
}
&.selected {
background-color: var(--clr-diff-selected-count-bg);
box-shadow: inset -1px 0 0 0 var(--clr-diff-selected-count-border);
color: var(--clr-diff-selected-count-text);
border-color: var(--clr-diff-selected-count-border);
}
@ -538,10 +534,6 @@
border-bottom-width: 1px;
}
&.is-before {
border-left-width: 1px;
}
&.is-before.is-last {
border-bottom-left-radius: var(--radius-s);
}
@ -551,18 +543,6 @@
width: var(--number-col-width);
min-width: var(--number-col-width);
left: 0px;
&.diff-line-addition {
box-shadow: inset -1px 0 0 0 var(--clr-diff-addition-count-border);
}
&.diff-line-deletion {
box-shadow: inset -1px 0 0 0 var(--clr-diff-deletion-count-border);
}
&.selected {
box-shadow: inset -1px 0 0 0 var(--clr-diff-selected-count-border);
}
}
.table__textContent {
@ -575,12 +555,5 @@
white-space: pre;
user-select: text;
cursor: text;
border-right: 1px solid var(--clr-border-2);
&.is-last {
box-shadow: inset 0 -1px 0 0 var(--clr-border-2);
border-bottom-right-radius: var(--radius-s);
}
}
</style>

View File

@ -1,5 +1,5 @@
<script lang="ts" module>
export type CheckboxStyle = 'default' | 'blue' | 'neutral';
export type CheckboxStyle = 'default' | 'neutral';
export interface CheckboxProps {
name?: string;
small?: boolean;
@ -130,19 +130,6 @@
}
}
&.blue:indeterminate {
background-color: var(--clr-diff-selected-checkbox);
box-shadow: inset 0 0 0 1px var(--clr-diff-selected-checkbox);
&:hover {
background-color: var(--clr-diff-selected-checkbox-hover);
}
&::before {
background-color: white;
}
}
/* checked */
&:checked {
&:disabled {
@ -176,15 +163,6 @@
}
}
&.blue:checked {
background-color: var(--clr-diff-selected-checkbox);
box-shadow: inset 0 0 0 1px var(--clr-diff-selected-checkbox);
&:hover {
background-color: var(--clr-diff-selected-checkbox-hover);
}
}
&::after {
content: '';
position: absolute;

View File

@ -649,7 +649,7 @@
},
"50": {
"$type": "color",
"$value": "#dc9b14",
"$value": "#dc9914",
"$description": "",
"$extensions": {
"mode": {},
@ -665,7 +665,7 @@
},
"60": {
"$type": "color",
"$value": "#f4bb6c",
"$value": "#f4c06c",
"$description": "",
"$extensions": {
"mode": {},
@ -681,7 +681,7 @@
},
"70": {
"$type": "color",
"$value": "#feddae",
"$value": "#fee1ae",
"$description": "",
"$extensions": {
"mode": {},
@ -697,7 +697,7 @@
},
"80": {
"$type": "color",
"$value": "#ffe8c7",
"$value": "#ffecc7",
"$description": "",
"$extensions": {
"mode": {},
@ -713,7 +713,7 @@
},
"90": {
"$type": "color",
"$value": "#fff2e0",
"$value": "#fff7e0",
"$description": "",
"$extensions": {
"mode": {},
@ -729,7 +729,7 @@
},
"95": {
"$type": "color",
"$value": "#fdf7ed",
"$value": "#fdf9ed",
"$description": "",
"$extensions": {
"mode": {},
@ -3652,12 +3652,12 @@
"selected": {
"count-bg": {
"$type": "color",
"$value": "#e1eeff",
"$value": "{clr-core.pop.70}",
"$description": "",
"$extensions": {
"mode": {
"light": "#e1eeff",
"dark": "#133161"
"light": "{clr-core.pop.70}",
"dark": "{clr-core.pop.10}"
},
"figma": {
"variableId": "VariableID:3935:251",
@ -3671,12 +3671,12 @@
},
"count-border": {
"$type": "color",
"$value": "#9dc3f5",
"$value": "{clr-core.pop.60}",
"$description": "",
"$extensions": {
"mode": {
"light": "#9dc3f5",
"dark": "#2464ae"
"light": "{clr-core.pop.60}",
"dark": "{clr-core.pop.30}"
},
"figma": {
"variableId": "VariableID:3935:253",
@ -3690,12 +3690,12 @@
},
"count-text": {
"$type": "color",
"$value": "#6187dc",
"$value": "{clr-core.pop.40}",
"$description": "",
"$extensions": {
"mode": {
"light": "#6187dc",
"dark": "#6aaeff"
"light": "{clr-core.pop.40}",
"dark": "{clr-core.pop.50}"
},
"figma": {
"variableId": "VariableID:3935:254",
@ -3706,44 +3706,6 @@
}
}
}
},
"checkbox": {
"$type": "color",
"$value": "#378bf2",
"$description": "",
"$extensions": {
"mode": {
"light": "#378bf2",
"dark": "#2581f3"
},
"figma": {
"variableId": "VariableID:4469:4018",
"collection": {
"id": "VariableCollectionId:8:1868",
"name": "clr",
"defaultModeId": "8:5"
}
}
}
},
"checkbox-hover": {
"$type": "color",
"$value": "#196dd4",
"$description": "",
"$extensions": {
"mode": {
"light": "#196dd4",
"dark": "#1165cc"
},
"figma": {
"variableId": "VariableID:4499:8368",
"collection": {
"id": "VariableCollectionId:8:1868",
"name": "clr",
"defaultModeId": "8:5"
}
}
}
}
},
"count-text": {
@ -4175,7 +4137,7 @@
"useDTCGKeys": true,
"colorMode": "hex",
"variableCollections": ["clr-core", "clr", "size", "radius"],
"createdAt": "2024-09-10T12:38:43.089Z"
"createdAt": "2024-09-11T23:46:21.639Z"
}
}
}

View File

@ -13,9 +13,16 @@ export const CheckboxStory: Story = {
name: 'Checkbox',
args: {
name: 'Checkbox',
style: 'default',
checked: false,
disabled: false,
indeterminate: false,
small: false
},
argTypes: {
style: {
options: ['default', 'neutral'],
control: { type: 'select' }
}
}
};

View File

@ -43,12 +43,12 @@
--clr-core-warn-20: color(srgb 0.3764705882352941 0.2549019607843137 0.08627450980392157);
--clr-core-warn-30: color(srgb 0.5411764705882353 0.34901960784313724 0.0784313725490196);
--clr-core-warn-40: color(srgb 0.7803921568627451 0.4980392156862745 0.10196078431372549);
--clr-core-warn-50: color(srgb 0.8627450980392157 0.6078431372549019 0.0784313725490196);
--clr-core-warn-60: color(srgb 0.9568627450980393 0.7333333333333333 0.4235294117647059);
--clr-core-warn-70: color(srgb 0.996078431372549 0.8666666666666667 0.6823529411764706);
--clr-core-warn-80: color(srgb 1 0.9098039215686274 0.7803921568627451);
--clr-core-warn-90: color(srgb 1 0.9490196078431372 0.8784313725490196);
--clr-core-warn-95: color(srgb 0.9921568627450981 0.9686274509803922 0.9294117647058824);
--clr-core-warn-50: color(srgb 0.8627450980392157 0.6 0.0784313725490196);
--clr-core-warn-60: color(srgb 0.9568627450980393 0.7529411764705882 0.4235294117647059);
--clr-core-warn-70: color(srgb 0.996078431372549 0.8823529411764706 0.6823529411764706);
--clr-core-warn-80: color(srgb 1 0.9254901960784314 0.7803921568627451);
--clr-core-warn-90: color(srgb 1 0.9686274509803922 0.8784313725490196);
--clr-core-warn-95: color(srgb 0.9921568627450981 0.9764705882352941 0.9294117647058824);
--clr-core-succ-5: color(srgb 0.050980392156862744 0.14901960784313725 0.10196078431372549);
--clr-core-succ-10: color(srgb 0.10980392156862745 0.25098039215686274 0.1843137254901961);
--clr-core-succ-20: color(srgb 0.13333333333333333 0.3254901960784314 0.23529411764705882);
@ -203,19 +203,9 @@
--clr-diff-line-bg: var(--clr-bg-1);
--clr-diff-count-bg: color(srgb 0.9686274509803922 0.9686274509803922 0.9647058823529412);
--clr-diff-count-border: var(--clr-border-2);
--clr-diff-selected-count-bg: color(srgb 0.8823529411764706 0.9333333333333333 1);
--clr-diff-selected-count-border: color(
srgb 0.615686274509804 0.7647058823529411 0.9607843137254902
);
--clr-diff-selected-count-text: color(
srgb 0.3803921568627451 0.5294117647058824 0.8627450980392157
);
--clr-diff-selected-checkbox: color(
srgb 0.21568627450980393 0.5450980392156862 0.9490196078431372
);
--clr-diff-selected-checkbox-hover: color(
srgb 0.09803921568627451 0.42745098039215684 0.8313725490196079
);
--clr-diff-selected-count-bg: var(--clr-core-pop-70);
--clr-diff-selected-count-border: var(--clr-core-pop-60);
--clr-diff-selected-count-text: var(--clr-core-pop-40);
--clr-diff-count-text: var(--clr-text-3);
--clr-diff-deletion-line-bg: color(srgb 1 0.9411764705882353 0.9490196078431372);
--clr-diff-deletion-line-highlight: color(
@ -391,17 +381,9 @@
--clr-diff-line-bg: var(--clr-bg-1);
--clr-diff-count-bg: color(srgb 0.18823529411764706 0.17254901960784313 0.16862745098039217);
--clr-diff-count-border: var(--clr-border-2);
--clr-diff-selected-count-bg: color(
srgb 0.07450980392156863 0.19215686274509805 0.3803921568627451
);
--clr-diff-selected-count-border: color(
srgb 0.1411764705882353 0.39215686274509803 0.6823529411764706
);
--clr-diff-selected-count-text: color(srgb 0.41568627450980394 0.6823529411764706 1);
--clr-diff-selected-checkbox: color(
srgb 0.1450980392156863 0.5058823529411764 0.9529411764705882
);
--clr-diff-selected-checkbox-hover: color(srgb 0.06666666666666667 0.396078431372549 0.8);
--clr-diff-selected-count-bg: var(--clr-core-pop-10);
--clr-diff-selected-count-border: var(--clr-core-pop-30);
--clr-diff-selected-count-text: var(--clr-core-pop-50);
--clr-diff-count-text: var(--clr-text-3);
--clr-diff-deletion-line-bg: color(
srgb 0.23529411764705882 0.07450980392156863 0.10588235294117647