Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(menubar): add a new button Display All Shortcuts #238

Merged
merged 3 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 128 additions & 15 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import GoToDialog from '@/components/GoToDialog.svelte';
import FindDialog from '@/components/FindDialog.svelte';
import Loading from '@/components/Loading.svelte';
import ShortcutsDialog from '@/components/ShortcutsDialog.svelte';
</script>

{#await Notpad.init()}
Expand All @@ -29,6 +30,7 @@
<FontDialog />
<LicenseDialog />
<AboutDialog />
<ShortcutsDialog />
<GoToDialog />
<FindDialog />
<Shortcuts />
Expand Down
41 changes: 27 additions & 14 deletions src/lib/components/AboutDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,34 @@
</script>

<Dialog.Root open={$open} onOpenChange={open.set}>
<Dialog.Content class="max-h-[80vh] max-w-2xl overflow-y-auto [&_a]:text-blue-500">
<Dialog.Title>About Notpad</Dialog.Title>
<hr />
<Dialog.Content class="max-w-2xl overflow-y-auto [&_a]:text-blue-500">
<Dialog.Header>
<Dialog.Title>About Notpad</Dialog.Title>
</Dialog.Header>

<Dialog.Header class="flex flex-row items-center justify-start gap-4 text-left">
<img class="w-20" alt="icon" src={$mode == 'dark' ? appIconDark : appIconLight} />
<div class="max-h-[60vh] overflow-y-auto pr-3 text-base">
<div class="mb-3 flex flex-row items-center justify-start gap-4 text-left">
<img class="w-20" alt="icon" src={$mode == 'dark' ? appIconDark : appIconLight} />

<div>
<span class="text-xl font-bold">Notpad</span><br />
Version {appJson.version}<br />
<a href="https://github.com/Muhammed-Rahif" target="_blank">Muhammed-Rahif</a>
<span class="text-sm">© 2024. All rights reserved.</span>
<div>
<span class="text-xl font-bold">Notpad</span><br />
Version {appJson.version}<br />
<a href="https://github.com/Muhammed-Rahif" target="_blank">Muhammed-Rahif</a>
<span class="text-sm">© 2024. All rights reserved.</span>
</div>
</div>
</Dialog.Header>
<Dialog.Description class="text-base">

<p class="mb-3">
Notpad is a simple, open source, beautiful note-taking app that helps you to take notes and
organize your thoughts. It is designed to be minimal and distraction-free, so you can focus
on your ideas. Notpad is an open-source project. You can contribute to the project by fixing
bugs, improving the codebase, or adding new features. The project is hosted on
<a href="https://github.com/Muhammed-Rahif/Notpad/" target="_blank">GitHub.</a>
If you have any questions, feedback, or suggestions, feel free to
<a href="https://github.com/Muhammed-Rahif/Notpad/issues/new/" target="_blank">
create an issue.
</a>
</p>
<p class="mb-3">
Notpad is a simple, open source, beautiful note-taking app that helps you to take notes and
organize your thoughts. It is designed to be minimal and distraction-free, so you can focus
Expand All @@ -71,7 +84,7 @@
{#if contributors}
<div transition:slide|global>
<p>Our Valuable Contributors:</p>
<ul class="mt-1 max-h-36 overflow-y-auto">
<ul class="mt-1">
{#each contributors as contributor}
{@const isAuthor = contributor.login == 'Muhammed-Rahif'}
<a href={contributor.html_url} target="_blank">
Expand Down Expand Up @@ -117,7 +130,7 @@
<a href="https://github.com/Muhammed-Rahif" target="_blank">Muhammed-Rahif.</a>
</small>
</p>
</Dialog.Description>
</div>

<Dialog.Footer class="gap-y-2">
<Button variant="secondary" class="relative sm:pr-20" on:click={showLicense}>
Expand Down
14 changes: 7 additions & 7 deletions src/lib/components/FindDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@
</script>

<Dialog.Root open={$open} onOpenChange={open.set} preventScroll={false}>
<Dialog.Content
overlayClass="bg-transparent backdrop-blur-[.8px]"
class="top-14 translate-y-0 bg-neutral-100 dark:bg-neutral-900"
>
<Dialog.Title>Find And Replace</Dialog.Title>
<Dialog.Description class="flex flex-col gap-3">
<Dialog.Content class="top-14 translate-y-0">
<Dialog.Header>
<Dialog.Title>Find And Replace</Dialog.Title>
</Dialog.Header>

<div class="flex flex-col gap-3">
<div class="flex">
<Input
autocomplete="off"
Expand Down Expand Up @@ -110,7 +110,7 @@
Case sensitive
</Label>
</div>
</Dialog.Description>
</div>
<Dialog.Footer class="gap-y-2">
<Button
type="button"
Expand Down
14 changes: 7 additions & 7 deletions src/lib/components/GoToDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@
</script>

<Dialog.Root open={$open} onOpenChange={open.set} preventScroll={false}>
<Dialog.Content
overlayClass="bg-transparent backdrop-blur-[.8px]"
class="top-14 translate-y-0 bg-neutral-100 dark:bg-neutral-900"
>
<Dialog.Title>Go To</Dialog.Title>
<Dialog.Description class="flex gap-3">
<Dialog.Content class="top-14 translate-y-0">
<Dialog.Header>
<Dialog.Title>Go To</Dialog.Title>
</Dialog.Header>

<div class="flex gap-3">
<div class="flex w-full max-w-sm flex-col gap-1.5">
<Label for="line">Line</Label>
<Input
Expand Down Expand Up @@ -71,6 +71,6 @@
</div>

<Button type="button" class="mt-auto" on:click={submitGoTo}>Go</Button>
</Dialog.Description>
</div>
</Dialog.Content>
</Dialog.Root>
14 changes: 10 additions & 4 deletions src/lib/components/LicenseDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.`;

$: licenseParagraphs = licenseText.split(/\n\n/g).map((line) => {
return { text: line, br: '<br><br>' };
return { text: line, br: true };
});

onMount(async () => {
Expand All @@ -47,12 +47,18 @@ SOFTWARE.`;

<Dialog.Root open={$open} onOpenChange={open.set}>
<Dialog.Content class="[&_a]:text-blue-500">
<Dialog.Title>Notpad License</Dialog.Title>
<hr />
<Dialog.Header>
<Dialog.Title>Notpad License</Dialog.Title>
</Dialog.Header>

<Dialog.Description class="max-h-96 overflow-y-auto pr-2">
{#each licenseParagraphs as { text, br }}
{text}
{br}

{#if br}
<br />
<br />
{/if}
{/each}
</Dialog.Description>
<Dialog.Footer>
Expand Down
7 changes: 7 additions & 0 deletions src/lib/components/MenuBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
import { openAboutDialog } from '@/components/AboutDialog.svelte';
import { toggleGoToDialog } from '@/components/GoToDialog.svelte';
import { toggleFindDialog } from '@/components/FindDialog.svelte';
import { openShortcutsDialog } from '@/src/lib/components/ShortcutsDialog.svelte';
import InfoIcon from './icons/Info.svelte';
import KeyboardIcon from '@/components/icons/Keyboard.svelte';
import GithubOultineIcon from './icons/GithubOultine.svelte';

let innerWidth = window.innerWidth;
Expand Down Expand Up @@ -145,6 +147,11 @@
<Menubar.Menu>
<Menubar.Trigger>Help</Menubar.Trigger>
<Menubar.Content>
<Menubar.Item class="flex items-center gap-2" on:click={openShortcutsDialog}>
<KeyboardIcon class="text-xl" />
Shortcuts
</Menubar.Item>
<Menubar.Separator />
<a href="https://github.com/Muhammed-Rahif/Notpad" target="_blank">
<Menubar.Item class="flex items-center gap-2">
<GithubOultineIcon class="text-xl" />
Expand Down
77 changes: 77 additions & 0 deletions src/lib/components/ShortcutsDialog.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<script context="module">
import { writable } from 'svelte/store';

// Store to control the dialog's open state
const open = writable(false);

// Function to open the dialog
export function openShortcutsDialog() {
open.set(true);
}
</script>

<script lang="ts">
import * as Table from '@/components/ui/table';
import * as Dialog from '@/components/ui/dialog';
import * as Menubar from '@/components/ui/menubar';

const shortcuts = {
New: 'Ctrl + Alt + N',
Open: 'Ctrl + O',
Save: 'Ctrl + S',
Print: 'Ctrl + P',
Undo: 'Ctrl + Z',
Redo: 'Ctrl + Y',
Cut: 'Ctrl + X',
Copy: 'Ctrl + C',
Paste: 'Ctrl + V',
'Select All': 'Ctrl + A',
'Find/Replace': 'Ctrl + F',
'Go To': 'Ctrl + G',
'Full Screen': 'F11'
};
</script>

<Dialog.Root open={$open} onOpenChange={open.set}>
<Dialog.Trigger />

<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Shortcuts</Dialog.Title>
<Dialog.Description>
Here is a list of keyboard shortcuts that you can use to quickly perform actions in this
application.
</Dialog.Description>
</Dialog.Header>

<div class="w-full">
<div class="sticky top-0 bg-muted">
<Table.Root class="table w-full">
<Table.Header>
<Table.Row>
<Table.Head class="text-center">Function</Table.Head>
<Table.Head class="text-center">Shortcuts</Table.Head>
</Table.Row>
</Table.Header>
</Table.Root>
</div>

<div class="max-h-[60vh] overflow-y-auto">
<Table.Root class="table w-full">
<Table.Body>
{#each Object.entries(shortcuts) as [action, shortcut]}
<Table.Row>
<Table.Cell class="text-center">{action}</Table.Cell>
<Table.Cell class="text-center">
<Menubar.Shortcut>
{shortcut}
</Menubar.Shortcut>
</Table.Cell>
</Table.Row>
{/each}
</Table.Body>
</Table.Root>
</div>
</div>
</Dialog.Content>
</Dialog.Root>
4 changes: 2 additions & 2 deletions src/lib/components/font-dialog/FontDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@
</script>

<Dialog.Root open={$open} onOpenChange={open.set}>
<Dialog.Content class="max-h-[80vh] overflow-y-auto sm:max-w-[600px]">
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Font</Dialog.Title>
<Dialog.Description>
Select a font family and size from the list below to change the appearance of your text.
</Dialog.Description>
</Dialog.Header>

<div class="flex gap-3 py-4 max-[464px]:flex-col">
<div class="flex gap-3 max-[464px]:flex-col">
<FontFamilyCombobox bind:value={fontFamily} />
<FontSizeCombobox bind:value={fontSize} />
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/lib/components/icons/Keyboard.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
<path
fill="currentColor"
d="M4 19q-.825 0-1.412-.587T2 17V7q0-.825.588-1.412T4 5h16q.825 0 1.413.588T22 7v10q0 .825-.587 1.413T20 19zm4-3h8v-2H8zm-3-3h2v-2H5zm3 0h2v-2H8zm3 0h2v-2h-2zm3 0h2v-2h-2zm3 0h2v-2h-2zM5 10h2V8H5zm3 0h2V8H8zm3 0h2V8h-2zm3 0h2V8h-2zm3 0h2V8h-2z"
/>
</svg>
21 changes: 5 additions & 16 deletions src/lib/components/ui/dialog/dialog-content.svelte
Original file line number Diff line number Diff line change
@@ -1,40 +1,29 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
import Cross2 from 'svelte-radix/Cross2.svelte';
import * as Dialog from './';
import { cn, flyAndScale } from '@/utils';
import * as Dialog from './index.js';
import { cn, flyAndScale } from '@/utils.js';

type $$Props = DialogPrimitive.ContentProps & {
overlayClass?: DialogPrimitive.OverlayProps['class'];
};
type $$Props = DialogPrimitive.ContentProps;

let className: $$Props['class'] = undefined;
export let transition: $$Props['transition'] = flyAndScale;
export let transitionConfig: $$Props['transitionConfig'] = {
duration: 200
};
export { className as class };

export let overlayClass: DialogPrimitive.OverlayProps['class'] = undefined;
</script>

<Dialog.Portal>
<Dialog.Overlay class={overlayClass} />
<Dialog.Overlay />
<DialogPrimitive.Content
{transition}
{transitionConfig}
class={cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg sm:rounded-lg md:w-full',
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 pt-0 shadow-lg sm:rounded-lg md:w-full',
className
)}
{...$$restProps}
>
<slot />
<DialogPrimitive.Close
class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none"
>
<Cross2 class="h-4 w-4" />
<span class="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</Dialog.Portal>
16 changes: 8 additions & 8 deletions src/lib/components/ui/dialog/dialog-description.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<script lang="ts">
import { Dialog as DialogPrimitive } from 'bits-ui';
import { cn } from '@/utils';
import { Dialog as DialogPrimitive } from "bits-ui";
import { cn } from "@/utils.js";

type $$Props = DialogPrimitive.DescriptionProps;
type $$Props = DialogPrimitive.DescriptionProps;

let className: $$Props['class'] = undefined;
export { className as class };
let className: $$Props["class"] = undefined;
export { className as class };
</script>

<DialogPrimitive.Description
class={cn('text-sm text-muted-foreground', className)}
{...$$restProps}
class={cn("text-muted-foreground text-sm", className)}
{...$$restProps}
>
<slot />
<slot />
</DialogPrimitive.Description>
16 changes: 8 additions & 8 deletions src/lib/components/ui/dialog/dialog-footer.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements';
import { cn } from '@/utils';
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "@/utils.js";

type $$Props = HTMLAttributes<HTMLDivElement>;
type $$Props = HTMLAttributes<HTMLDivElement>;

let className: $$Props['class'] = undefined;
export { className as class };
let className: $$Props["class"] = undefined;
export { className as class };
</script>

<div
class={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
{...$$restProps}
class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
{...$$restProps}
>
<slot />
<slot />
</div>
Loading