mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-24 18:12:48 +03:00
Improve modal UI and discard changes (#5148)
* style(modal): Update header padding and add color to body * style: Update font color in modal body paragraphs * feat(ui): improve DemoModal structure and props usage * style: Remove unnecessary global styles from Modal component * feat(ui): Update DemoModal component onclick event and add onSubmit handler * StoryBook: Update text in DemoModal * add missing "submit" * modal lint/checks fixes * Update "Discard changes" modal
This commit is contained in:
parent
436cd41f44
commit
c6482a94de
@ -12,6 +12,7 @@
|
|||||||
import { getContext } from '@gitbutler/shared/context';
|
import { getContext } from '@gitbutler/shared/context';
|
||||||
import Button from '@gitbutler/ui/Button.svelte';
|
import Button from '@gitbutler/ui/Button.svelte';
|
||||||
import Modal from '@gitbutler/ui/Modal.svelte';
|
import Modal from '@gitbutler/ui/Modal.svelte';
|
||||||
|
import FileListItem from '@gitbutler/ui/file/FileListItem.svelte';
|
||||||
import { join } from '@tauri-apps/api/path';
|
import { join } from '@tauri-apps/api/path';
|
||||||
|
|
||||||
export let branchId: string | undefined;
|
export let branchId: string | undefined;
|
||||||
@ -116,19 +117,27 @@
|
|||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
width="small"
|
width="small"
|
||||||
|
type="warning"
|
||||||
title="Discard changes"
|
title="Discard changes"
|
||||||
bind:this={confirmationModal}
|
bind:this={confirmationModal}
|
||||||
onSubmit={confirmDiscard}
|
onSubmit={confirmDiscard}
|
||||||
>
|
>
|
||||||
{#snippet children(item)}
|
{#snippet children(item)}
|
||||||
<div>
|
{#if item.files.length < 10}
|
||||||
Discarding changes to the following files:
|
<p class="discard-caption">
|
||||||
|
Are you sure you want to discard the changes<br />to the following files:
|
||||||
|
</p>
|
||||||
<ul class="file-list">
|
<ul class="file-list">
|
||||||
{#each item.files as file}
|
{#each item.files as file}
|
||||||
<li><code class="code-string">{file.path}</code></li>
|
<FileListItem filePath={file.path} fileStatus={file.status} clickable={false} />
|
||||||
|
<!-- <li><code class="code-string">{file.path}</code></li> -->
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
{:else}
|
||||||
|
Discard the changes to all <span class="text-bold">
|
||||||
|
{item.files.length} files
|
||||||
|
</span>?
|
||||||
|
{/if}
|
||||||
{/snippet}
|
{/snippet}
|
||||||
{#snippet controls(close, item)}
|
{#snippet controls(close, item)}
|
||||||
<Button style="ghost" outline onclick={close}>Cancel</Button>
|
<Button style="ghost" outline onclick={close}>Cancel</Button>
|
||||||
@ -137,12 +146,14 @@
|
|||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.file-list {
|
.discard-caption {
|
||||||
list-style: disc;
|
color: var(--clr-text-2);
|
||||||
padding-left: 20px;
|
|
||||||
padding-top: 6px;
|
|
||||||
}
|
}
|
||||||
.file-list li {
|
.file-list {
|
||||||
padding: 2px;
|
padding: 4px 0;
|
||||||
|
border-radius: var(--radius-m);
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid var(--clr-border-2);
|
||||||
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
<svelte:window on:keydown={handleKeyDown} />
|
<svelte:window on:keydown={handleKeyDown} />
|
||||||
|
|
||||||
<Modal bind:this={modal}>
|
<Modal bind:this={modal} onSubmit={submit}>
|
||||||
<h2 class="text-18 text-bold">Create an topic</h2>
|
<h2 class="text-18 text-bold">Create an topic</h2>
|
||||||
|
|
||||||
<div class="input">
|
<div class="input">
|
||||||
@ -93,7 +93,7 @@
|
|||||||
|
|
||||||
{#snippet controls()}
|
{#snippet controls()}
|
||||||
<Button onclick={() => modal?.close()}>Cancel</Button>
|
<Button onclick={() => modal?.close()}>Cancel</Button>
|
||||||
<Button kind="solid" style="pop" onclick={submit} loading={submitProgress === 'loading'}
|
<Button kind="solid" style="pop" type="submit" loading={submitProgress === 'loading'}
|
||||||
>{topic ? 'Update' : 'Create'}</Button
|
>{topic ? 'Update' : 'Create'}</Button
|
||||||
>
|
>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
@ -4,13 +4,12 @@
|
|||||||
import { portal } from '$lib/utils/portal';
|
import { portal } from '$lib/utils/portal';
|
||||||
import { pxToRem } from '$lib/utils/pxToRem';
|
import { pxToRem } from '$lib/utils/pxToRem';
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import type iconsJson from '$lib/data/icons.json';
|
|
||||||
import type { Snippet } from 'svelte';
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
width?: 'medium' | 'large' | 'small' | 'xsmall' | number;
|
width?: 'medium' | 'large' | 'small' | 'xsmall' | number;
|
||||||
|
type?: 'info' | 'warning' | 'error' | 'success';
|
||||||
title?: string;
|
title?: string;
|
||||||
icon?: keyof typeof iconsJson;
|
|
||||||
noPadding?: boolean;
|
noPadding?: boolean;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
onSubmit?: (close: () => void) => void;
|
onSubmit?: (close: () => void) => void;
|
||||||
@ -22,7 +21,7 @@
|
|||||||
const {
|
const {
|
||||||
width = 'medium',
|
width = 'medium',
|
||||||
title,
|
title,
|
||||||
icon,
|
type = 'info',
|
||||||
onClose,
|
onClose,
|
||||||
children,
|
children,
|
||||||
controls,
|
controls,
|
||||||
@ -102,9 +101,18 @@
|
|||||||
>
|
>
|
||||||
{#if title}
|
{#if title}
|
||||||
<div class="modal__header">
|
<div class="modal__header">
|
||||||
{#if icon}
|
{#if type === 'warning'}
|
||||||
<Icon name={icon} />
|
<Icon name="warning" color="warning" />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if type === 'error'}
|
||||||
|
<Icon name="error" color="error" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if type === 'success'}
|
||||||
|
<Icon name="success" color="success" />
|
||||||
|
{/if}
|
||||||
|
|
||||||
<h2 class="text-14 text-semibold">
|
<h2 class="text-14 text-semibold">
|
||||||
{title}
|
{title}
|
||||||
</h2>
|
</h2>
|
||||||
@ -112,7 +120,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="modal__body custom-scrollbar text-13 text-body" class:no-padding={noPadding}>
|
<div class="modal__body custom-scrollbar text-13 text-body" class:no-padding={noPadding}>
|
||||||
{@render children(item, close)}
|
{#if children}
|
||||||
|
{@render children(item, close)}
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if controls}
|
{#if controls}
|
||||||
@ -171,9 +181,8 @@
|
|||||||
|
|
||||||
.modal__header {
|
.modal__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px;
|
padding: 16px 16px 0;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
border-bottom: 1px solid var(--clr-border-2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal__body {
|
.modal__body {
|
||||||
@ -186,8 +195,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal__body > :global(code),
|
.modal__body :global(code),
|
||||||
.modal__body > :global(pre) {
|
.modal__body :global(pre) {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import iconsJson from '$lib/data/icons.json';
|
|
||||||
import Button from '$lib/Button.svelte';
|
import Button from '$lib/Button.svelte';
|
||||||
import Modal from '$lib/Modal.svelte';
|
import Modal from '$lib/Modal.svelte';
|
||||||
import { type SvelteComponent } from 'svelte';
|
|
||||||
|
|
||||||
interface Props {
|
const { ...args }: typeof Modal = $props();
|
||||||
width?: 'small' | 'large' | 'medium' | 'xsmall' | number;
|
|
||||||
title?: string;
|
|
||||||
icon?: keyof typeof iconsJson;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { ...args }: Props = $props();
|
let modal: Modal;
|
||||||
|
|
||||||
let modal: SvelteComponent<Props>;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -20,13 +12,14 @@
|
|||||||
modal?.show();
|
modal?.show();
|
||||||
}}>Show</Button
|
}}>Show</Button
|
||||||
>
|
>
|
||||||
<Modal bind:this={modal} {...args}>
|
<Modal bind:this={modal} {...args} onSubmit={() => console.log('submitted')}>
|
||||||
<p>Wonderful modal content</p>
|
A branch with the same name already exists. Do you want to merge this branch into the current
|
||||||
|
branch?
|
||||||
|
|
||||||
{#snippet controls(close)}
|
{#snippet controls(close)}
|
||||||
<Button onclick={() => close()}>Close</Button>
|
<Button style="ghost" outline onclick={() => close()}>Cancel</Button>
|
||||||
<Button style="pop" kind="solid" type="submit" onclick={() => console.log('Submit clicked')}
|
<Button style="pop" kind="solid" type="submit" onclick={() => console.log('clicked')}
|
||||||
>Submit</Button
|
>Merge</Button
|
||||||
>
|
>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
import DemoModal from './DemoModal.svelte';
|
import DemoModal from './DemoModal.svelte';
|
||||||
import iconsJson from '$lib/data/icons.json';
|
import type { StoryObj } from '@storybook/svelte';
|
||||||
import type { Meta, StoryObj } from '@storybook/svelte';
|
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
title: 'Overlays / Modal',
|
title: 'Overlays / Modal',
|
||||||
component: DemoModal,
|
component: DemoModal as any,
|
||||||
argTypes: {
|
argTypes: {
|
||||||
width: {
|
width: {
|
||||||
control: 'select',
|
control: 'select',
|
||||||
options: ['default', 'small', 'large']
|
options: ['default', 'small', 'large']
|
||||||
},
|
},
|
||||||
title: { control: 'text' },
|
title: { control: 'text' },
|
||||||
icon: {
|
type: {
|
||||||
control: 'select',
|
control: 'select',
|
||||||
options: [undefined, ...Object.keys(iconsJson)]
|
options: ['info', 'success', 'warning', 'error']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} satisfies Meta<DemoModal>;
|
};
|
||||||
|
|
||||||
export default meta;
|
export default meta;
|
||||||
type Story = StoryObj<typeof meta>;
|
type Story = StoryObj<typeof meta>;
|
||||||
@ -25,6 +24,7 @@ export const DefaultStory: Story = {
|
|||||||
name: 'Modal',
|
name: 'Modal',
|
||||||
args: {
|
args: {
|
||||||
width: 'small',
|
width: 'small',
|
||||||
|
type: 'info',
|
||||||
title: 'This is a fantastic modal :D'
|
title: 'This is a fantastic modal :D'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user