diff --git a/README.md b/README.md
index 273ee76..1d55155 100644
--- a/README.md
+++ b/README.md
@@ -19,6 +19,8 @@ Available actions:
- `longpress`
- `pannable`
- `lazyload`
+- `preventTabClose`
+- `shortcut`
## Included Actions
@@ -115,6 +117,55 @@ Demo: https://svelte.dev/repl/f12988de576b4bf9b541a2a59eb838f6?version=3.23.2
Discuss this action: https://github.com/sw-yx/svelte-actions/issues/2
+### ``preventTabClose`
+
+`export function preventTabClose(_, enabled: boolean)`
+
+Prevent current tab from being closed by user.
+
+Demo: https://svelte.dev/repl/a95db12c1b46433baac2817a0963dc93
+
+```svelte
+
+
+
+```
+
+Discuss this action: https://github.com/sw-yx/svelte-actions/pull/11
+
+### ``shortcut`
+
+```ts
+export function shortcut(node: Action, {
+ control?: boolean;
+ shift?: boolean;
+ alt?: boolean;
+ code: string;
+ callback?: () => void;
+})
+```
+
+Simplest possible way to add a keyboard shortcut to a div or a button.
+
+It either calls a callback or clicks on the node it was put on.
+
+Demo: https://svelte.dev/repl/acd92c9726634ec7b3d8f5f759824d15
+
+```svelte
+
+
+
+
+Clicked: {buttonCount}
+```
## Future actions considering adding
@@ -134,4 +185,4 @@ Click to vote:
-[Propose a new action here!](https://github.com/sw-yx/svelte-actions/issues/new)
\ No newline at end of file
+[Propose a new action here!](https://github.com/sw-yx/svelte-actions/issues/new)
diff --git a/src/index.ts b/src/index.ts
index 8a0e543..c85270d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -172,4 +172,75 @@ export function lazyload(node: HTMLElement, attributes: Object): ReturnType {
+ const handler = (e: BeforeUnloadEvent) => {
+ e.preventDefault();
+ e.returnValue = '';
+ },
+ setHandler = (shouldWork: boolean) =>
+ shouldWork ?
+ window.addEventListener('beforeunload', handler) :
+ window.removeEventListener('beforeunload', handler);
+
+ setHandler(enabled);
+
+ return {
+ update: setHandler,
+ destroy: () => setHandler(false),
+ };
+};
+
+/**
+ * Simplest possible way to add a keyboard shortcut to a div or a button.
+ * It either calls a callback or clicks on the node it was put on.
+ *
+ * Demo: https://svelte.dev/repl/acd92c9726634ec7b3d8f5f759824d15
+ */
+
+export type ShortcutSetting = {
+ control?: boolean;
+ shift?: boolean;
+ alt?: boolean;
+
+ code: string;
+
+ callback?: () => void;
+};
+export const shortcut: Action = (node, params: ShortcutSetting | undefined) => {
+ let handler: ((e: KeyboardEvent) => void) | undefined;
+
+ const removeHandler = () => window.removeEventListener('keydown', handler!),
+ setHandler = () => {
+ removeHandler();
+ if (!params) return;
+
+ handler = (e: KeyboardEvent) => {
+ if (
+ (!!params.alt != e.altKey) ||
+ (!!params.shift != e.shiftKey) ||
+ (!!params.control != (e.ctrlKey || e.metaKey)) ||
+ params.code != e.code
+ )
+ return;
+
+ e.preventDefault();
+
+ params.callback ? params.callback() : node.click();
+ };
+ window.addEventListener('keydown', handler);
+ };
+
+ setHandler();
+
+ return {
+ update: setHandler,
+ destroy: removeHandler,
+ };
+};