@mypolis.eu/action-controller 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/dist/attributes.js +30 -0
- package/dist/attributes.js.map +1 -0
- package/dist/attributes.test.js +50 -0
- package/dist/attributes.test.js.map +1 -0
- package/dist/controller.js +145 -0
- package/dist/controller.js.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/query.js +84 -0
- package/dist/query.js.map +1 -0
- package/dist/register.js +21 -0
- package/dist/register.js.map +1 -0
- package/dist/types/attributes.d.ts +2 -0
- package/dist/types/attributes.d.ts.map +1 -0
- package/dist/types/attributes.test.d.ts +2 -0
- package/dist/types/attributes.test.d.ts.map +1 -0
- package/dist/types/controller.d.ts +15 -0
- package/dist/types/controller.d.ts.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/query.d.ts +7 -0
- package/dist/types/query.d.ts.map +1 -0
- package/dist/types/register.d.ts +3 -0
- package/dist/types/register.d.ts.map +1 -0
- package/package.json +37 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 MyPolis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# @mypolis.eu/action-controller
|
|
2
|
+
|
|
3
|
+
`@mypolis.eu/action-controller` is a lightweight TypeScript library that brings
|
|
4
|
+
declarative event handling to your web components. It allows you to connect DOM
|
|
5
|
+
events to methods on LitElement-based controllers using simple HTML data-action
|
|
6
|
+
attributes.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Declarative Event Handling**: Define actions directly in your HTML using
|
|
11
|
+
data-action attributes.
|
|
12
|
+
|
|
13
|
+
- **LitElement Based**: Controllers are extensions of LitElement, allowing you
|
|
14
|
+
to use all Lit features like reactive properties and efficient rendering.
|
|
15
|
+
|
|
16
|
+
- **Automatic Registration**: Easily register your controller classes as custom
|
|
17
|
+
elements.
|
|
18
|
+
|
|
19
|
+
- **Dynamic Content Ready**: Uses a MutationObserver to automatically bind
|
|
20
|
+
actions to new elements added to the DOM and clean up when they are removed.
|
|
21
|
+
|
|
22
|
+
- **Scoped Actions**: Actions are scoped to the controller that defines them,
|
|
23
|
+
ensuring clean component encapsulation.
|
|
24
|
+
|
|
25
|
+
- **DOM Query Helpers**: Includes query and queryAll utilities for accessing
|
|
26
|
+
elements within your controller's scope, often used with data-target
|
|
27
|
+
attributes.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
You'll also need to install lit as it's a peer dependency.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @mypolis.eu/action-controller lit
|
|
35
|
+
|
|
36
|
+
# or
|
|
37
|
+
|
|
38
|
+
yarn add @mypolis.eu/action-controller lit
|
|
39
|
+
|
|
40
|
+
# or
|
|
41
|
+
|
|
42
|
+
pnpm add @mypolis.eu/action-controller lit
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Core Concepts
|
|
46
|
+
|
|
47
|
+
### Controllers
|
|
48
|
+
|
|
49
|
+
Controllers are custom elements that extend the Controller class (which itself
|
|
50
|
+
extends LitElement). They encapsulate the behavior and state related to a piece
|
|
51
|
+
of UI. The Controller base class handles the setup of action listeners.
|
|
52
|
+
|
|
53
|
+
### Actions
|
|
54
|
+
|
|
55
|
+
Actions link DOM events on elements within a controller's template to methods
|
|
56
|
+
on that controller instance. They are defined using the data-action attribute.
|
|
57
|
+
|
|
58
|
+
**Syntax**: `data-action="eventType:controllerTagName#methodName eventType2:controllerTagName#methodName2 ..."`
|
|
59
|
+
|
|
60
|
+
- **eventType**: The name of the DOM event (e.g., click, input, custom-event).
|
|
61
|
+
|
|
62
|
+
- **controllerTagName**: The tag name of the controller custom element (e.g.,
|
|
63
|
+
my-greeter). This must match the tag name of the controller component where the
|
|
64
|
+
data-action attribute is placed.
|
|
65
|
+
|
|
66
|
+
- **methodName**: The name of the method to call on the controller instance. If
|
|
67
|
+
omitted (e.g., click:my-greeter), it defaults to handleEvent.
|
|
68
|
+
|
|
69
|
+
### Registration
|
|
70
|
+
|
|
71
|
+
Controllers are registered as custom elements using the @register decorator or
|
|
72
|
+
the register() function. This function automatically derives a kebab-case tag
|
|
73
|
+
name from your class name (e.g., MyExampleController becomes
|
|
74
|
+
my-example-controller).
|
|
75
|
+
|
|
76
|
+
### Targets
|
|
77
|
+
|
|
78
|
+
"Targets" are specific elements within a controller's view that you might want
|
|
79
|
+
to reference directly in your controller's logic. You can identify these
|
|
80
|
+
elements using data-target attributes (or any other selector) and access them
|
|
81
|
+
using the query and queryAll helper functions.
|
|
82
|
+
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
// dialog-trigger.ts
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import {Controller, target, register} from "@mypolis.eu/action-controller";
|
|
89
|
+
import type {SlDialog} from "@shoelace-style/shoelace";
|
|
90
|
+
|
|
91
|
+
@register
|
|
92
|
+
export class DialogTrigger extends Controller {
|
|
93
|
+
@target dialog!: SlDialog;
|
|
94
|
+
|
|
95
|
+
open() {
|
|
96
|
+
this.dialog.show();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
close() {
|
|
100
|
+
this.dialog.hide();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
// index.html
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<dialog-trigger>
|
|
109
|
+
<sl-dialog
|
|
110
|
+
data-error="default"
|
|
111
|
+
data-target="dialog-trigger.dialog"
|
|
112
|
+
>
|
|
113
|
+
<header>
|
|
114
|
+
<h4>Algo Correu Mal</h4>
|
|
115
|
+
<sl-button
|
|
116
|
+
size="small"
|
|
117
|
+
title="Cancelar"
|
|
118
|
+
data-action="click:dialog-trigger#close"
|
|
119
|
+
circle
|
|
120
|
+
>
|
|
121
|
+
<sl-icon
|
|
122
|
+
library="lucide"
|
|
123
|
+
name="x"
|
|
124
|
+
></sl-icon>
|
|
125
|
+
</sl-button>
|
|
126
|
+
</header>
|
|
127
|
+
<div>
|
|
128
|
+
<p>
|
|
129
|
+
Lamentamos, mas ocorreu um erro inesperado. Por favor, tente novamente dentro de momentos. Se a situação
|
|
130
|
+
persistir, não hesite em contactar o nosso suporte.
|
|
131
|
+
</p>
|
|
132
|
+
</div>
|
|
133
|
+
<button
|
|
134
|
+
data-action="click:dialog-trigger#close"
|
|
135
|
+
style="width: 100%"
|
|
136
|
+
>
|
|
137
|
+
Fechar
|
|
138
|
+
</button>
|
|
139
|
+
</sl-dialog>
|
|
140
|
+
</dialog-trigger>
|
|
141
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function parseAttributes(element) {
|
|
2
|
+
const result = {};
|
|
3
|
+
for (const [key, value] of Object.entries(element.dataset)) {
|
|
4
|
+
result[key] = parseValue(value);
|
|
5
|
+
}
|
|
6
|
+
return result;
|
|
7
|
+
}
|
|
8
|
+
const NUMBER_REGEX = /^\d+$/;
|
|
9
|
+
function parseValue(value) {
|
|
10
|
+
if (value === "true")
|
|
11
|
+
return true;
|
|
12
|
+
if (value === "false")
|
|
13
|
+
return false;
|
|
14
|
+
if (NUMBER_REGEX.test(value))
|
|
15
|
+
return Number(value);
|
|
16
|
+
const firstChar = value[0];
|
|
17
|
+
if (firstChar === "{" || firstChar === "[") {
|
|
18
|
+
try {
|
|
19
|
+
return JSON.parse(value);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// fall through to other parsing
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (value.includes(",")) {
|
|
26
|
+
return value.split(",").map((v) => v.trim());
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../src/attributes.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAgC,OAAoB;IAClF,MAAM,MAAM,GAAe,EAAE,CAAC;IAE9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,MAAc,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAM,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,YAAY,GAAG,OAAO,CAAC;AAE7B,SAAS,UAAU,CAAC,KAAa;IAChC,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACpC,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAI,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;QAC5C,IAAI,CAAC;YACJ,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACR,gCAAgC;QACjC,CAAC;IACF,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { assert } from "@open-wc/testing";
|
|
2
|
+
import { parseAttributes } from "./attributes";
|
|
3
|
+
describe("parseAttributes", () => {
|
|
4
|
+
let element;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
element = document.createElement("div");
|
|
7
|
+
});
|
|
8
|
+
test("parses string attributes", () => {
|
|
9
|
+
element.setAttribute("data-url", "/products");
|
|
10
|
+
assert.deepStrictEqual(parseAttributes(element), { url: "/products" });
|
|
11
|
+
});
|
|
12
|
+
test("parses boolean attributes", () => {
|
|
13
|
+
element.setAttribute("data-active", "true");
|
|
14
|
+
element.setAttribute("data-disabled", "false");
|
|
15
|
+
assert.deepStrictEqual(parseAttributes(element), {
|
|
16
|
+
active: true,
|
|
17
|
+
disabled: false
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
test("parses number attributes", () => {
|
|
21
|
+
element.setAttribute("data-count", "42");
|
|
22
|
+
assert.deepStrictEqual(parseAttributes(element), { count: 42 });
|
|
23
|
+
});
|
|
24
|
+
test("parses array attributes", () => {
|
|
25
|
+
element.setAttribute("data-tags", "one,two,three");
|
|
26
|
+
assert.deepStrictEqual(parseAttributes(element), {
|
|
27
|
+
tags: ["one", "two", "three"]
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
test("parses JSON attributes", () => {
|
|
31
|
+
element.setAttribute("data-config", '{"foo": "bar", "num": 123}');
|
|
32
|
+
assert.deepStrictEqual(parseAttributes(element), {
|
|
33
|
+
config: { foo: "bar", num: 123 }
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
test("handles kebab-case attributes", () => {
|
|
37
|
+
element.setAttribute("data-user-name", "John");
|
|
38
|
+
element.setAttribute("data-last-login-date", "2024-01-21");
|
|
39
|
+
assert.deepStrictEqual(parseAttributes(element), {
|
|
40
|
+
userName: "John",
|
|
41
|
+
lastLoginDate: "2024-01-21"
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
test("ignores non-data attributes", () => {
|
|
45
|
+
element.setAttribute("id", "test");
|
|
46
|
+
element.setAttribute("data-name", "John");
|
|
47
|
+
assert.deepStrictEqual(parseAttributes(element), { name: "John" });
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=attributes.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.test.js","sourceRoot":"","sources":["../src/attributes.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAE7C,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAChC,IAAI,OAAoB,CAAC;IAEzB,UAAU,CAAC,GAAG,EAAE;QACf,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACrC,OAAO,CAAC,YAAY,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAC9C,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAC,GAAG,EAAE,WAAW,EAAC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACtC,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC5C,OAAO,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE;YAChD,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,KAAK;SACf,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACrC,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAC,KAAK,EAAE,EAAE,EAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACpC,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QACnD,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE;YAChD,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;SAC7B,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACnC,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,4BAA4B,CAAC,CAAC;QAClE,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE;YAChD,MAAM,EAAE,EAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAC;SAC9B,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE;QAC1C,OAAO,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,YAAY,CAAC,sBAAsB,EAAE,YAAY,CAAC,CAAC;QAC3D,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE;YAChD,QAAQ,EAAE,MAAM;YAChB,aAAa,EAAE,YAAY;SAC3B,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACxC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAC,IAAI,EAAE,MAAM,EAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _Controller_instances, _Controller_handlers, _Controller_observer, _Controller_parseActions, _Controller_handleAction, _Controller_listenActions, _Controller_cleanupActions;
|
|
13
|
+
import { LitElement, html } from "lit";
|
|
14
|
+
import { findElements } from "./query";
|
|
15
|
+
import { parseAttributes } from "./attributes";
|
|
16
|
+
export class Controller extends LitElement {
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
_Controller_instances.add(this);
|
|
20
|
+
_Controller_handlers.set(this, new WeakMap());
|
|
21
|
+
_Controller_observer.set(this, void 0);
|
|
22
|
+
__classPrivateFieldSet(this, _Controller_observer, new MutationObserver(() => {
|
|
23
|
+
__classPrivateFieldGet(this, _Controller_instances, "m", _Controller_cleanupActions).call(this); // Clean up existing listeners
|
|
24
|
+
__classPrivateFieldGet(this, _Controller_instances, "m", _Controller_listenActions).call(this); // Add new listeners
|
|
25
|
+
}), "f");
|
|
26
|
+
}
|
|
27
|
+
connectedCallback() {
|
|
28
|
+
super.connectedCallback();
|
|
29
|
+
// Initial setup
|
|
30
|
+
__classPrivateFieldGet(this, _Controller_instances, "m", _Controller_listenActions).call(this);
|
|
31
|
+
// Start observing changes
|
|
32
|
+
__classPrivateFieldGet(this, _Controller_observer, "f").observe(this, {
|
|
33
|
+
childList: true,
|
|
34
|
+
subtree: true,
|
|
35
|
+
attributes: true,
|
|
36
|
+
attributeFilter: ["data-action", "data-query", "data-target", "data-trigger"]
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
disconnectedCallback() {
|
|
40
|
+
super.disconnectedCallback();
|
|
41
|
+
// Clean up existing listeners
|
|
42
|
+
__classPrivateFieldGet(this, _Controller_instances, "m", _Controller_cleanupActions).call(this);
|
|
43
|
+
// Stop observing
|
|
44
|
+
__classPrivateFieldGet(this, _Controller_observer, "f").disconnect();
|
|
45
|
+
}
|
|
46
|
+
render() {
|
|
47
|
+
return html `<slot />`;
|
|
48
|
+
}
|
|
49
|
+
eventDetail(event) {
|
|
50
|
+
// handle customevent
|
|
51
|
+
if (event instanceof CustomEvent && event.detail) {
|
|
52
|
+
return event.detail;
|
|
53
|
+
}
|
|
54
|
+
// handle data attributes
|
|
55
|
+
const target = event.target;
|
|
56
|
+
if (!target)
|
|
57
|
+
return {};
|
|
58
|
+
return parseAttributes(target);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
_Controller_handlers = new WeakMap(), _Controller_observer = new WeakMap(), _Controller_instances = new WeakSet(), _Controller_parseActions = function _Controller_parseActions(actionString) {
|
|
62
|
+
if (!actionString)
|
|
63
|
+
return [];
|
|
64
|
+
return actionString
|
|
65
|
+
.trim()
|
|
66
|
+
.split(/\s+/) // Split multiple actions defined in the string
|
|
67
|
+
.map((action) => {
|
|
68
|
+
// 1. Find the method separator first
|
|
69
|
+
const hashIndex = action.indexOf("#");
|
|
70
|
+
let eventAndControllerPart;
|
|
71
|
+
let method;
|
|
72
|
+
if (hashIndex === -1) {
|
|
73
|
+
// No '#' found, method defaults to 'handleEvent'
|
|
74
|
+
eventAndControllerPart = action;
|
|
75
|
+
method = "handleEvent";
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
eventAndControllerPart = action.substring(0, hashIndex);
|
|
79
|
+
method = action.substring(hashIndex + 1) || "handleEvent";
|
|
80
|
+
}
|
|
81
|
+
// 2. Find the LAST colon in the remaining part to separate event type from controller
|
|
82
|
+
const lastColonIndex = eventAndControllerPart.lastIndexOf(":");
|
|
83
|
+
// Check if a colon exists and separates non-empty parts
|
|
84
|
+
if (lastColonIndex <= 0 || lastColonIndex === eventAndControllerPart.length - 1) {
|
|
85
|
+
console.warn(`[Controller] Invalid action format: Could not determine event and controller in "${action}". Skipping.`);
|
|
86
|
+
return null; // Invalid format
|
|
87
|
+
}
|
|
88
|
+
const eventType = eventAndControllerPart.substring(0, lastColonIndex);
|
|
89
|
+
const controller = eventAndControllerPart.substring(lastColonIndex + 1);
|
|
90
|
+
// Final validation
|
|
91
|
+
if (!eventType || !controller || !method) {
|
|
92
|
+
console.warn(`[Controller] Invalid action format: Empty parts detected in "${action}". Skipping.`);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return { type: eventType, controller, method };
|
|
96
|
+
})
|
|
97
|
+
.filter((action) => action !== null);
|
|
98
|
+
}, _Controller_handleAction = function _Controller_handleAction(event, element, action) {
|
|
99
|
+
// look for the nearest controller matching the action's controller name
|
|
100
|
+
const controller = element.closest(action.controller);
|
|
101
|
+
if (!controller) {
|
|
102
|
+
console.warn(`Controller ${action.controller} not found`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// the method should exist on the controller, not the element
|
|
106
|
+
const method = controller[action.method];
|
|
107
|
+
if (typeof method !== "function") {
|
|
108
|
+
console.warn(`Method ${action.method} not found on controller ${action.controller}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
method.call(controller, event);
|
|
112
|
+
}, _Controller_listenActions = function _Controller_listenActions() {
|
|
113
|
+
findElements(this, "[data-action]").forEach((element) => {
|
|
114
|
+
const actionString = element.dataset.action;
|
|
115
|
+
if (!actionString)
|
|
116
|
+
return;
|
|
117
|
+
const handlers = [];
|
|
118
|
+
for (const action of __classPrivateFieldGet(this, _Controller_instances, "m", _Controller_parseActions).call(this, actionString)) {
|
|
119
|
+
if (action.controller !== this.tagName.toLowerCase())
|
|
120
|
+
continue;
|
|
121
|
+
const handler = (event) => __classPrivateFieldGet(this, _Controller_instances, "m", _Controller_handleAction).call(this, event, element, action);
|
|
122
|
+
element.addEventListener(action.type, handler);
|
|
123
|
+
handlers.push(handler);
|
|
124
|
+
}
|
|
125
|
+
if (handlers.length) {
|
|
126
|
+
__classPrivateFieldGet(this, _Controller_handlers, "f").set(element, handlers);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}, _Controller_cleanupActions = function _Controller_cleanupActions() {
|
|
130
|
+
findElements(this, "[data-action]").forEach((element) => {
|
|
131
|
+
const handlers = __classPrivateFieldGet(this, _Controller_handlers, "f").get(element);
|
|
132
|
+
if (!handlers)
|
|
133
|
+
return;
|
|
134
|
+
const actionString = element.dataset.action;
|
|
135
|
+
if (!actionString)
|
|
136
|
+
return;
|
|
137
|
+
for (const action of __classPrivateFieldGet(this, _Controller_instances, "m", _Controller_parseActions).call(this, actionString)) {
|
|
138
|
+
handlers.forEach((handler) => {
|
|
139
|
+
element.removeEventListener(action.type, handler);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
__classPrivateFieldSet(this, _Controller_handlers, new WeakMap(), "f"); // Reset handlers map
|
|
144
|
+
};
|
|
145
|
+
//# sourceMappingURL=controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAC,UAAU,EAAE,IAAI,EAAC,MAAM,KAAK,CAAC;AACrC,OAAO,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AACrC,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAQ7C,MAAM,OAAO,UAAW,SAAQ,UAAU;IAIzC;QACC,KAAK,EAAE,CAAC;;QAJT,+BAAY,IAAI,OAAO,EAAmC,EAAC;QAC3D,uCAA4B;QAI3B,uBAAA,IAAI,wBAAa,IAAI,gBAAgB,CAAC,GAAG,EAAE;YAC1C,uBAAA,IAAI,yDAAgB,MAApB,IAAI,CAAkB,CAAC,CAAC,8BAA8B;YACtD,uBAAA,IAAI,wDAAe,MAAnB,IAAI,CAAiB,CAAC,CAAC,oBAAoB;QAC5C,CAAC,CAAC,MAAA,CAAC;IACJ,CAAC;IAED,iBAAiB;QAChB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAE1B,gBAAgB;QAChB,uBAAA,IAAI,wDAAe,MAAnB,IAAI,CAAiB,CAAC;QAEtB,0BAA0B;QAC1B,uBAAA,IAAI,4BAAU,CAAC,OAAO,CAAC,IAAI,EAAE;YAC5B,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,IAAI;YAChB,eAAe,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,CAAC;SAC7E,CAAC,CAAC;IACJ,CAAC;IAED,oBAAoB;QACnB,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,8BAA8B;QAC9B,uBAAA,IAAI,yDAAgB,MAApB,IAAI,CAAkB,CAAC;QACvB,iBAAiB;QACjB,uBAAA,IAAI,4BAAU,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM;QACL,OAAO,IAAI,CAAA,UAAU,CAAC;IACvB,CAAC;IAED,WAAW,CAAgC,KAA6B;QACvE,qBAAqB;QACrB,IAAI,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,yBAAyB;QACzB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;QAC3C,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,CAAC;QAEvB,OAAO,eAAe,CAAI,MAAM,CAAC,CAAC;IACnC,CAAC;CAyGD;gLAvGc,YAAoB;IACjC,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,CAAC;IAE7B,OAAO,YAAY;SACjB,IAAI,EAAE;SACN,KAAK,CAAC,KAAK,CAAC,CAAC,+CAA+C;SAC5D,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,qCAAqC;QACrC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,sBAA8B,CAAC;QACnC,IAAI,MAAc,CAAC;QAEnB,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,iDAAiD;YACjD,sBAAsB,GAAG,MAAM,CAAC;YAChC,MAAM,GAAG,aAAa,CAAC;QACxB,CAAC;aAAM,CAAC;YACP,sBAAsB,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YACxD,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,aAAa,CAAC;QAC3D,CAAC;QAED,sFAAsF;QACtF,MAAM,cAAc,GAAG,sBAAsB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAE/D,wDAAwD;QACxD,IAAI,cAAc,IAAI,CAAC,IAAI,cAAc,KAAK,sBAAsB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjF,OAAO,CAAC,IAAI,CACX,oFAAoF,MAAM,cAAc,CACxG,CAAC;YACF,OAAO,IAAI,CAAC,CAAC,iBAAiB;QAC/B,CAAC;QAED,MAAM,SAAS,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QACtE,MAAM,UAAU,GAAG,sBAAsB,CAAC,SAAS,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;QAExE,mBAAmB;QACnB,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,gEAAgE,MAAM,cAAc,CAAC,CAAC;YACnG,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,EAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAC,CAAC;IAC9C,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,MAAM,EAAoB,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AACzD,CAAC,+DAEa,KAAY,EAAE,OAAgB,EAAE,MAAc;IAC3D,wEAAwE;IACxE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAc,MAAM,CAAC,UAAU,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,UAAU,YAAY,CAAC,CAAC;QAC1D,OAAO;IACR,CAAC;IAED,6DAA6D;IAC7D,MAAM,MAAM,GAAI,UAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,MAAM,4BAA4B,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QACrF,OAAO;IACR,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;IAGA,YAAY,CAAc,IAAI,EAAE,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACpE,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5C,IAAI,CAAC,YAAY;YAAE,OAAO;QAE1B,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAE5C,KAAK,MAAM,MAAM,IAAI,uBAAA,IAAI,uDAAc,MAAlB,IAAI,EAAe,YAAY,CAAC,EAAE,CAAC;YACvD,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;gBAAE,SAAS;YAE/D,MAAM,OAAO,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,uBAAA,IAAI,uDAAc,MAAlB,IAAI,EAAe,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YAE7E,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC/C,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,uBAAA,IAAI,4BAAU,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC;IAGA,YAAY,CAAc,IAAI,EAAE,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACpE,MAAM,QAAQ,GAAG,uBAAA,IAAI,4BAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5C,IAAI,CAAC,YAAY;YAAE,OAAO;QAE1B,KAAK,MAAM,MAAM,IAAI,uBAAA,IAAI,uDAAc,MAAlB,IAAI,EAAe,YAAY,CAAC,EAAE,CAAC;YACvD,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC5B,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACJ,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,uBAAA,IAAI,wBAAa,IAAI,OAAO,EAAE,MAAA,CAAC,CAAC,qBAAqB;AACtD,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAc,MAAM,cAAc,CAAC;AAErD,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAC,MAAM,SAAS,CAAC;AAEzD,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC"}
|
package/dist/query.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export function findElements(controller, query) {
|
|
2
|
+
const tag = controller.tagName.toLowerCase();
|
|
3
|
+
const elements = [];
|
|
4
|
+
// search shadow dom
|
|
5
|
+
if (controller.shadowRoot) {
|
|
6
|
+
const shadowElements = controller.shadowRoot.querySelectorAll(query);
|
|
7
|
+
for (let i = 0; i < shadowElements.length; i++) {
|
|
8
|
+
const el = shadowElements[i];
|
|
9
|
+
if (!el.closest(tag)) {
|
|
10
|
+
elements.push(el);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
// search light dom
|
|
15
|
+
const lightElements = controller.querySelectorAll(query);
|
|
16
|
+
for (let i = 0; i < lightElements.length; i++) {
|
|
17
|
+
const el = lightElements[i];
|
|
18
|
+
if (el.closest(tag) === controller) {
|
|
19
|
+
elements.push(el);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return elements;
|
|
23
|
+
}
|
|
24
|
+
export function queryAll(target, propertyKey) {
|
|
25
|
+
const ctor = target.constructor;
|
|
26
|
+
ctor.addInitializer((instance) => {
|
|
27
|
+
const getter = function () {
|
|
28
|
+
const controller = this.tagName.toLowerCase();
|
|
29
|
+
const query = `[data-query~="${controller}.${propertyKey}"]`;
|
|
30
|
+
return findElements(this, query);
|
|
31
|
+
};
|
|
32
|
+
Object.defineProperty(instance, propertyKey, {
|
|
33
|
+
get: getter,
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export function query(target, propertyKey) {
|
|
40
|
+
const ctor = target.constructor;
|
|
41
|
+
ctor.addInitializer((instance) => {
|
|
42
|
+
const getter = function () {
|
|
43
|
+
const controller = this.tagName.toLowerCase();
|
|
44
|
+
const query = `[data-query~="${controller}.${propertyKey}"]`;
|
|
45
|
+
return findElements(this, query)?.[0];
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(instance, propertyKey, {
|
|
48
|
+
get: getter,
|
|
49
|
+
enumerable: true,
|
|
50
|
+
configurable: true,
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export function target(target, propertyKey) {
|
|
55
|
+
const ctor = target.constructor;
|
|
56
|
+
ctor.addInitializer((instance) => {
|
|
57
|
+
const getter = function () {
|
|
58
|
+
const controller = this.tagName.toLowerCase();
|
|
59
|
+
const query = `[data-target~="${controller}.${propertyKey}"]`;
|
|
60
|
+
return findElements(this, query)?.[0];
|
|
61
|
+
};
|
|
62
|
+
Object.defineProperty(instance, propertyKey, {
|
|
63
|
+
get: getter,
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
export function targets(target, propertyKey) {
|
|
70
|
+
const ctor = target.constructor;
|
|
71
|
+
ctor.addInitializer((instance) => {
|
|
72
|
+
const getter = function () {
|
|
73
|
+
const controller = this.tagName.toLowerCase();
|
|
74
|
+
const query = `[data-target~="${controller}.${propertyKey}"]`;
|
|
75
|
+
return findElements(this, query);
|
|
76
|
+
};
|
|
77
|
+
Object.defineProperty(instance, propertyKey, {
|
|
78
|
+
get: getter,
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
|
package/dist/register.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const slugify = (str) => String(typeof str === "symbol" ? str.description : str)
|
|
2
|
+
.replace(/([A-Z]($|[a-z]))/g, "-$1")
|
|
3
|
+
.replace(/--/g, "-")
|
|
4
|
+
.replace(/^-|-$/, "")
|
|
5
|
+
.toLowerCase();
|
|
6
|
+
export function register(classObject) {
|
|
7
|
+
const name = slugify(classObject.name).replace(/-element$/, "");
|
|
8
|
+
try {
|
|
9
|
+
window.customElements.define(name, classObject);
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
window[classObject.name] = customElements.get(name);
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
// The only reason for window.customElements.define to throw a `NotSupportedError`
|
|
15
|
+
// is if the element has already been defined.
|
|
16
|
+
if (!(e instanceof DOMException && e.name === "NotSupportedError"))
|
|
17
|
+
throw e;
|
|
18
|
+
}
|
|
19
|
+
return classObject;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAY,EAAU,EAAE,CAC9C,MAAM,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC;KACpD,OAAO,CAAC,mBAAmB,EAAE,KAAK,CAAC;KACnC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;KACnB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;KACpB,WAAW,EAAE,CAAC;AAEnB,MAAM,UAAU,QAAQ,CACtB,WAAc;IAEd,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAEhE,IAAI,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAChD,aAAa;QACb,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,kFAAkF;QAClF,8CAA8C;QAC9C,IAAI,CAAC,CAAC,CAAC,YAAY,YAAY,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC;YAAE,MAAM,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../src/attributes.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAQ/F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.test.d.ts","sourceRoot":"","sources":["../../src/attributes.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LitElement } from "lit";
|
|
2
|
+
export type Action = {
|
|
3
|
+
type: string;
|
|
4
|
+
controller: string;
|
|
5
|
+
method: string;
|
|
6
|
+
};
|
|
7
|
+
export declare class Controller extends LitElement {
|
|
8
|
+
#private;
|
|
9
|
+
constructor();
|
|
10
|
+
connectedCallback(): void;
|
|
11
|
+
disconnectedCallback(): void;
|
|
12
|
+
render(): import("lit").TemplateResult<1>;
|
|
13
|
+
eventDetail<T extends Record<string, any>>(event: CustomEvent<T> | Event): Partial<T>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAO,MAAM,KAAK,CAAC;AAIrC,MAAM,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,qBAAa,UAAW,SAAQ,UAAU;;;IAYzC,iBAAiB;IAejB,oBAAoB;IAQpB,MAAM;IAIN,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC;CAoHrF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,KAAK,MAAM,EAAC,MAAM,cAAc,CAAC;AAErD,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAC,MAAM,SAAS,CAAC;AAEzD,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Controller } from "./controller";
|
|
2
|
+
export declare function findElements<T extends Element>(controller: HTMLElement, query: string): T[];
|
|
3
|
+
export declare function queryAll(target: Controller, propertyKey: string): void;
|
|
4
|
+
export declare function query(target: Controller, propertyKey: string): void;
|
|
5
|
+
export declare function target(target: Controller, propertyKey: string): void;
|
|
6
|
+
export declare function targets(target: Controller, propertyKey: string): void;
|
|
7
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,wBAAgB,YAAY,CAAC,CAAC,SAAS,OAAO,EAC5C,UAAU,EAAE,WAAW,EACvB,KAAK,EAAE,MAAM,GACZ,CAAC,EAAE,CAyBL;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAgB/D;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAgB5D;AAGD,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAgB7D;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAgB9D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/register.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,GAAI,KAAK,OAAO,KAAG,MAKrB,CAAC;AAEnB,wBAAgB,QAAQ,CAAC,CAAC,SAAS,wBAAwB,EACzD,WAAW,EAAE,CAAC,GACb,CAAC,CAaH"}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mypolis.eu/action-controller",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/types/index.d.ts",
|
|
8
|
+
"default": "./dist/index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"./dist",
|
|
13
|
+
"./package.json"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/mypolis/action-controller.git"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [],
|
|
20
|
+
"author": "Guilherme Rosado <guilherme.rosado@mypolis.eu>",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"lit": "^3.0.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@open-wc/testing": "^4.0.0",
|
|
27
|
+
"@tsconfig/node22": "^22.0.2",
|
|
28
|
+
"@types/mocha": "^10.0.10",
|
|
29
|
+
"@web/dev-server-esbuild": "^1.0.4",
|
|
30
|
+
"@web/test-runner": "^0.20.1",
|
|
31
|
+
"typescript": "^5.8.3",
|
|
32
|
+
"lit": "^3.2.1"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc -p tsconfig.json"
|
|
36
|
+
}
|
|
37
|
+
}
|