├── .github
└── workflows
│ └── release.yml
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── src
└── index.ts
└── tsconfig.json
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | release:
8 | name: Release
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v2
13 |
14 | - name: Setup Node.js
15 | uses: actions/setup-node@v2
16 | with:
17 | node-version: '12.x'
18 |
19 | - name: Install dependencies
20 | run: npm ci
21 |
22 | - name: Build
23 | run: npm run build
24 |
25 | - name: Release
26 | env:
27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
29 | run: npx semantic-release
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | test
4 | *.tgz
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## About
4 |
5 | This library is based on the [svelte-material-ui](https://github.com/hperrin/svelte-material-ui)
6 | useActions implementation.
7 |
8 | It enables you to use [actions](https://svelte.dev/docs#use_action) on custom components. Additionally you get type safety.
9 |
10 | ## Installation
11 |
12 | ```bash
13 | npm i svelte-useactions
14 |
15 | #or
16 |
17 | yarn add svelte-useactions
18 | ```
19 |
20 | ## Basic Example
21 |
22 | First create your component that accepts an array of actions.
23 |
24 | ```svelte
25 |
26 |
27 |
33 |
34 |
35 | ```
36 |
37 | Next define your action function
38 |
39 | ```ts
40 | // autofocus.ts
41 |
42 | export const autofocus: Action = (node) => {
43 | node.focus();
44 | };
45 | ```
46 |
47 | Now you can define actions for components.
48 |
49 | ```svelte
50 |
51 |
52 |
56 |
57 |
58 | ```
59 |
60 | You can also define parameters
61 |
62 | ```ts
63 | // autofocus.ts
64 |
65 | export const autofocus: Action = (node, text) => {
66 | node.focus();
67 | console.log(text);
68 | };
69 | ```
70 |
71 | ```svelte
72 |
73 |
74 |
75 | ```
76 |
77 | ## Note
78 |
79 | `createActionList` is merely used for type-safety. If you don't care
80 | about it you can just input a normal action list.
81 |
82 | Example:
83 |
84 | ```svelte
85 |
86 |
87 |
88 | ```
89 |
90 | ## API
91 |
92 | ### `useActions`
93 |
94 | Used in tandem with the `use` directive. Accepts an [action list](#actionlist) as a parameter.
95 |
96 | ```svelte
97 |
103 |
104 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | ```
123 |
124 | ### `ActionList`
125 |
126 | An array of tuples where the first item is the action and optionally the
127 | parameters of the action as the second item.
128 |
129 | ```ts
130 | let actions: ActionList = [];
131 | const duration = 500;
132 |
133 | // With one action
134 | actions = [[autofocus]];
135 |
136 | // One action with parameters
137 | actions = [[longpress, duration]];
138 |
139 | // Multiple actions
140 | actions = [[longpress, duration], [autofocus]];
141 | ```
142 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-useactions",
3 | "version": "0.0.0-development",
4 | "description": "",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "keywords": [],
8 | "files": [
9 | "dist"
10 | ],
11 | "author": "",
12 | "license": "ISC",
13 | "scripts": {
14 | "build": "tsc -p .",
15 | "watch": "tsc --watch -p .",
16 | "semantic-release": "semantic-release"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/paolotiu/svelte-useactions.git"
21 | },
22 | "devDependencies": {
23 | "semantic-release": "^17.4.4"
24 | },
25 | "release": {
26 | "branches": [
27 | "main"
28 | ]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * The return type of an action.
3 | */
4 | export type ActionReturn = {
5 | destroy?: () => void;
6 | update?: (params: Params) => void;
7 | } | void;
8 |
9 | /**
10 | * Action type shim
11 | */
12 | export type ActionLike = (node: Node, params: any) => any;
13 |
14 | /**
15 | * A primitive Action
16 | */
17 | export type Action = (
18 | node: Node,
19 | params?: Params
20 | ) => ActionReturn;
21 |
22 | /**
23 | * A list of actions
24 | */
25 | export type ActionList<
26 | Node extends HTMLElement,
27 | Arr extends Array> = Array>
28 | > = [
29 | ...{
30 | [I in keyof Arr]: Arr[I] extends ActionLike
31 | ? Parameters[1] extends undefined
32 | ? [Arr[I]]
33 | : [Arr[I], Parameters[1]]
34 | : never;
35 | }
36 | ];
37 |
38 | /**
39 | * A wrapper function that provides intellisense
40 | */
41 | export const createActionList = >>(
42 | actions: ActionList
43 | ): ActionList => {
44 | return actions;
45 | };
46 |
47 | /**
48 | * Takes in actions as a parameter and executes them all.
49 | * Also manages the update and destroy functions if present.
50 | */
51 | export const useActions = >>(
52 | node: Node,
53 | actions: ActionList
54 | ) => {
55 | const actionReturns: ActionReturn>[] = [];
56 |
57 | if (actions) {
58 | actions.forEach((currentTuple) => {
59 | const action = currentTuple[0];
60 | const params = currentTuple[1];
61 |
62 | actionReturns.push(action(node, params));
63 | });
64 | }
65 |
66 | return {
67 | update(actions: ActionList) {
68 | actions.forEach((currentTuple, i) => {
69 | const currentReturn = actionReturns[i];
70 | const params = currentTuple[1];
71 |
72 | if (!currentReturn) return;
73 |
74 | if (typeof params !== 'undefined') {
75 | currentReturn.update?.(params);
76 | }
77 | });
78 | },
79 | destroy() {
80 | actionReturns.forEach((currentReturn) => {
81 | if (currentReturn) currentReturn.destroy?.();
82 | });
83 | },
84 | };
85 | };
86 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "lib": ["ES2020", "DOM"],
6 | "declaration": true,
7 | "outDir": "./dist",
8 | "strict": true,
9 | "noUnusedLocals": true,
10 | "noUnusedParameters": true,
11 | "esModuleInterop": true,
12 | "skipLibCheck": true,
13 | "forceConsistentCasingInFileNames": true,
14 | "preserveSymlinks": true
15 | },
16 | "exclude": ["examples", "dist", "tests"],
17 | "include": ["src"]
18 | }
19 |
--------------------------------------------------------------------------------