@appius-fr/apx 2.5.0 → 2.6.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/APX.mjs CHANGED
@@ -1,119 +1,122 @@
1
- import augmentWithListen from './modules/listen/listen.mjs';
2
- import augmentWithTristate from './modules/tristate/tristate.mjs';
3
- import dialog from './modules/dialog/dialog.mjs';
4
- import toast from './modules/toast/toast.mjs';
5
- import { loadCss } from './modules/common.mjs';
6
-
7
- /**
8
- * Creates an APX object that wraps one or more HTML elements.
9
- * @param {string|HTMLElement|NodeList|HTMLCollection|Array<HTMLElement>|jQuery|Function} input - The input to create the APX object from.
10
- * @returns {Object} The APX object.
11
- * @throws {Error} If the input type is invalid.
12
- * @example
13
- * // XPath
14
- * const apx1 = APX('//div[@class="example"]');
15
- *
16
- * // CSS selector
17
- * const apx2 = APX('.example');
18
- *
19
- * // Single element
20
- * const element = document.querySelector('.example');
21
- * const apx3 = APX(element);
22
- *
23
- * // NodeList or HTMLCollection
24
- * const nodeList = document.querySelectorAll('.example');
25
- * const apx4 = APX(nodeList);
26
- *
27
- * // Array of elements
28
- * const elements = [document.querySelector('.example1'), document.querySelector('.example2')];
29
- * const apx5 = APX(elements);
30
- *
31
- * // jQuery object
32
- * const $example = $('.example');
33
- * const apx6 = APX($example);
34
- *
35
- * // Function returning an APX object
36
- * const apx7 = APX(() => APX('.example'));
37
- */
38
- const APX = function (input, context = document) {
39
- let elements;
40
-
41
- // Validate context
42
- if (typeof context === 'string') {
43
- context = document.querySelector(context);
44
- }
45
- else if (APX.isAPXObject(context)) {
46
- context = context.first();
47
- } else if (!(context instanceof HTMLElement || context instanceof Document)) {
48
- throw new Error('Invalid context for APX');
49
- }
50
-
51
- if (typeof input === 'string' && input.startsWith('//')) {
52
- // XPath with context
53
- elements = document.evaluate(input, context, null, XPathResult.ANY_TYPE, null);
54
- let nodes = [];
55
- let node = elements.iterateNext();
56
- while (node) {
57
- nodes.push(node);
58
- node = elements.iterateNext();
59
- }
60
- elements = nodes;
61
- } else if (typeof input === 'string') {
62
- // CSS selector with context
63
- elements = context.querySelectorAll(input);
64
- } else if (input instanceof HTMLElement) {
65
- // Single element within context
66
- elements = context.contains(input) ? [input] : [];
67
- } else if (input instanceof NodeList || input instanceof HTMLCollection) {
68
- // NodeList or HTMLCollection within context
69
- elements = Array.from(input).filter(el => context.contains(el));
70
- } else if (Array.isArray(input) && input.every(el => el instanceof HTMLElement)) {
71
- // Array of elements within context
72
- elements = input.filter(el => context.contains(el));
73
- } else if (typeof jQuery != 'undefined' && input instanceof jQuery) {
74
- // jQuery object within context
75
- elements = Array.from(input.get()).filter(el => context.contains(el));
76
- } else if (typeof input === 'function') {
77
- // Function returning an APX object with context
78
- elements = APX(input(), context);
79
- } else {
80
- throw new Error('Invalid input type for APX');
81
- }
82
-
83
- var apx = {
84
- elements: elements,
85
- _isAPXObject: true
86
- };
87
- apx.length = elements.length;
88
- apx.each = function (callback) {
89
- if (this.elements instanceof Array) this.elements.forEach(callback);
90
- if (this.elements instanceof NodeList) Array.from(this.elements).forEach(callback);
91
- return this;
92
- };
93
- apx.get = function (index) {
94
- return this.elements[index];
95
- };
96
- apx.all = function () {
97
- if (this.elements instanceof Array) return this.elements;
98
- if (this.elements instanceof NodeList) return Array.from(this.elements);
99
- return this;
100
- };
101
- apx.first = function () {
102
- return this.get(0);
103
- };
104
- augmentWithListen(apx);
105
- augmentWithTristate(apx);
106
- return apx;
107
- };
108
-
109
- APX.loadCss = loadCss;
110
- APX.dialog = dialog;
111
- APX.toast = toast;
112
- APX.isAPXObject = function (obj) {
113
- return obj && obj._isAPXObject === true;
114
- }
115
- APX.is_numeric = (n) => {
116
- return !isNaN(n - parseFloat(n));
117
- }
118
-
1
+ import augmentWithListen from './modules/listen/listen.mjs';
2
+ import augmentWithTristate from './modules/tristate/tristate.mjs';
3
+ import dialog from './modules/dialog/dialog.mjs';
4
+ import toast from './modules/toast/toast.mjs';
5
+ import { loadCss } from './modules/common.mjs';
6
+ import { augmentWithPack, tools } from './modules/tools/exports.mjs';
7
+
8
+ /**
9
+ * Creates an APX object that wraps one or more HTML elements.
10
+ * @param {string|HTMLElement|NodeList|HTMLCollection|Array<HTMLElement>|jQuery|Function} input - The input to create the APX object from.
11
+ * @returns {Object} The APX object.
12
+ * @throws {Error} If the input type is invalid.
13
+ * @example
14
+ * // XPath
15
+ * const apx1 = APX('//div[@class="example"]');
16
+ *
17
+ * // CSS selector
18
+ * const apx2 = APX('.example');
19
+ *
20
+ * // Single element
21
+ * const element = document.querySelector('.example');
22
+ * const apx3 = APX(element);
23
+ *
24
+ * // NodeList or HTMLCollection
25
+ * const nodeList = document.querySelectorAll('.example');
26
+ * const apx4 = APX(nodeList);
27
+ *
28
+ * // Array of elements
29
+ * const elements = [document.querySelector('.example1'), document.querySelector('.example2')];
30
+ * const apx5 = APX(elements);
31
+ *
32
+ * // jQuery object
33
+ * const $example = $('.example');
34
+ * const apx6 = APX($example);
35
+ *
36
+ * // Function returning an APX object
37
+ * const apx7 = APX(() => APX('.example'));
38
+ */
39
+ const APX = function (input, context = document) {
40
+ let elements;
41
+
42
+ // Validate context
43
+ if (typeof context === 'string') {
44
+ context = document.querySelector(context);
45
+ }
46
+ else if (APX.isAPXObject(context)) {
47
+ context = context.first();
48
+ } else if (!(context instanceof HTMLElement || context instanceof Document)) {
49
+ throw new Error('Invalid context for APX');
50
+ }
51
+
52
+ if (typeof input === 'string' && input.startsWith('//')) {
53
+ // XPath with context
54
+ elements = document.evaluate(input, context, null, XPathResult.ANY_TYPE, null);
55
+ let nodes = [];
56
+ let node = elements.iterateNext();
57
+ while (node) {
58
+ nodes.push(node);
59
+ node = elements.iterateNext();
60
+ }
61
+ elements = nodes;
62
+ } else if (typeof input === 'string') {
63
+ // CSS selector with context
64
+ elements = context.querySelectorAll(input);
65
+ } else if (input instanceof HTMLElement) {
66
+ // Single element within context
67
+ elements = context.contains(input) ? [input] : [];
68
+ } else if (input instanceof NodeList || input instanceof HTMLCollection) {
69
+ // NodeList or HTMLCollection within context
70
+ elements = Array.from(input).filter(el => context.contains(el));
71
+ } else if (Array.isArray(input) && input.every(el => el instanceof HTMLElement)) {
72
+ // Array of elements within context
73
+ elements = input.filter(el => context.contains(el));
74
+ } else if (typeof jQuery != 'undefined' && input instanceof jQuery) {
75
+ // jQuery object within context
76
+ elements = Array.from(input.get()).filter(el => context.contains(el));
77
+ } else if (typeof input === 'function') {
78
+ // Function returning an APX object with context
79
+ elements = APX(input(), context);
80
+ } else {
81
+ throw new Error('Invalid input type for APX');
82
+ }
83
+
84
+ var apx = {
85
+ elements: elements,
86
+ _isAPXObject: true
87
+ };
88
+ apx.length = elements.length;
89
+ apx.each = function (callback) {
90
+ if (this.elements instanceof Array) this.elements.forEach(callback);
91
+ if (this.elements instanceof NodeList) Array.from(this.elements).forEach(callback);
92
+ return this;
93
+ };
94
+ apx.get = function (index) {
95
+ return this.elements[index];
96
+ };
97
+ apx.all = function () {
98
+ if (this.elements instanceof Array) return this.elements;
99
+ if (this.elements instanceof NodeList) return Array.from(this.elements);
100
+ return this;
101
+ };
102
+ apx.first = function () {
103
+ return this.get(0);
104
+ };
105
+ augmentWithListen(apx);
106
+ augmentWithTristate(apx);
107
+ augmentWithPack(apx);
108
+ return apx;
109
+ };
110
+
111
+ APX.loadCss = loadCss;
112
+ APX.dialog = dialog;
113
+ APX.toast = toast;
114
+ APX.tools = tools;
115
+ APX.isAPXObject = function (obj) {
116
+ return obj && obj._isAPXObject === true;
117
+ }
118
+ APX.is_numeric = (n) => {
119
+ return !isNaN(n - parseFloat(n));
120
+ }
121
+
119
122
  export default APX;
package/README.md CHANGED
@@ -2,36 +2,55 @@
2
2
 
3
3
  APX is a versatile DOM wrapper designed to simplify interactions with HTML elements. It provides a unified interface for working with various input types, including XPath, CSS selectors, individual HTMLElements, NodeLists, HTMLCollections, arrays of elements, jQuery objects, and even functions that return APX objects.
4
4
 
5
+ ## Core Library
6
+
7
+ The main APX library is defined in [`APX.mjs`](./APX.mjs), which provides the core DOM wrapping functionality and integrates all modules.
8
+
9
+ **Quick Start:**
10
+ ```javascript
11
+ import APX from './APX.mjs';
12
+
13
+ // Use APX to select and manipulate elements
14
+ APX('.my-class').each((el) => console.log(el));
15
+ ```
16
+
5
17
  ## Features
6
18
 
7
19
  - **XPath Support**: Easily select elements using XPath queries.
8
20
  - **CSS Selector Support**: Utilize CSS selectors for element selection.
9
21
  - **Enhanced Interactions**: Augmented with modules like `listen` for event handling and `tristate` for managing tristate logic.
10
- - **Utility Functions**: Includes tools like `loadCss`, and `dialog` for extended functionality.
22
+ - **Utility Functions**: Includes tools like `loadCss`, `dialog`, and `toast` for extended functionality.
11
23
  - **jQuery Compatibility**: Seamlessly works with jQuery objects.
12
24
  - **Function Input**: Accepts functions returning an APX object as input.
13
25
 
14
26
  ## Modules
15
27
 
16
- APX is enhanced with several modules, each adding specialized functionality:
28
+ APX is enhanced with several modules, each adding specialized functionality. Each module has its own detailed documentation:
17
29
 
18
30
  ### `listen`
19
31
 
20
- The `listen` module simplifies event handling for wrapped elements. It provides an intuitive way to attach and manage event listeners.
32
+ The `listen` module simplifies event handling for wrapped elements. It provides an intuitive way to attach and manage event listeners with support for event delegation, multiple callbacks, debouncing, and manual event triggering.
33
+
34
+ **Documentation:** [`modules/listen/README.md`](./modules/listen/README.md)
21
35
 
22
- Documentation: [`/modules/listen`](./modules/listen/listen.mjs)
36
+ **Quick Example:**
37
+ ```javascript
38
+ APX('.button').listen('click').do((event) => {
39
+ console.log('Button clicked!');
40
+ });
41
+ ```
23
42
 
24
43
  ### `tristate`
25
44
 
26
45
  The `tristate` module allows you to manage tristate logic (e.g., on/off/indeterminate) for HTML elements efficiently.
27
46
 
28
- Documentation: [`/modules/tristate`](./modules/tristate/tristate.mjs)
47
+ **Documentation:** [`modules/tristate/tristate.mjs`](./modules/tristate/tristate.mjs)
29
48
 
30
49
  ### `dialog`
31
50
 
32
- The `dialog` module provides utilities to create and manage modal dialogs.
51
+ The `dialog` module provides utilities to create and manage modal dialogs with lifecycle management, button interactions, and flexible content loading.
33
52
 
34
- Documentation: [`/modules/dialog`](./modules/dialog/dialog.mjs)
53
+ **Documentation:** [`modules/dialog/README.md`](./modules/dialog/README.md)
35
54
 
36
55
  Since 2.4.0, dialog content can be fetched via GET (default) or POST with optional payload and headers.
37
56
 
@@ -55,10 +74,11 @@ myDialog.open();
55
74
 
56
75
  ### `toast` (since 2.5.0)
57
76
 
58
- Minimal, framework‑agnostic toast notifications with auto‑loaded CSS and a small API. Exposed as `APX.toast`.
77
+ Minimal, framework‑agnostic toast notifications with auto‑loaded CSS and a small API. Exposed as `APX.toast`. Supports advanced positioning (sticky, relative, anchored), flow control, and container management.
59
78
 
60
- Quick start:
79
+ **Documentation:** [`modules/toast/README.md`](./modules/toast/README.md)
61
80
 
81
+ **Quick Start:**
62
82
  ```javascript
63
83
  // One‑liners on the default manager
64
84
  APX.toast.success('Saved!');
@@ -70,29 +90,41 @@ APX.toast({ message: 'Processing…', type: 'info', durationMs: 0 });
70
90
  // Configure defaults
71
91
  APX.toast.configure({ position: 'top-right', maxToasts: 4, dedupe: true });
72
92
 
73
- // Dedupe requires a stable id
74
- APX.toast.show({ id: 'status', message: 'Working…', type: 'info', durationMs: 0 });
75
- APX.toast.show({ id: 'status', message: 'Done', type: 'success', durationMs: 1500 });
76
-
77
93
  // Named managers (profiles)
78
94
  APX.toast.create('admin', { position: 'bottom-left' });
79
95
  APX.toast.use('admin').info('Admin ready');
80
96
  ```
81
97
 
82
- Notes:
83
- - CSS is auto‑imported by the toast module; no `<link>` needed.
84
- - Overflow policy enforces a strict cap: if `maxToasts` is exceeded, the oldest is removed immediately.
85
- - Named managers are accessible via `APX.toast.use('<name>')`.
86
-
87
- Demo pages (work from file:// via standalone build):
98
+ **Demo pages** (work from file:// via standalone build):
88
99
  - `demo/index.html` (landing)
89
100
  - `demo/modules/toast/index.html` (basic and advanced examples with code viewer)
90
101
 
102
+ ### `tools` (since 2.6.0)
103
+
104
+ The `tools` module provides utility functions for common web development tasks. Currently includes form handling utilities with more tools planned for future releases.
105
+
106
+ **Documentation:** [`modules/tools/README.md`](./modules/tools/README.md)
107
+
108
+ **Quick Start:**
109
+ ```javascript
110
+ // Convert form to JSON
111
+ const data = APX('form#myForm').pack();
112
+ // or
113
+ const data = APX.tools.packFormToJSON(document.querySelector('#myForm'));
114
+ ```
115
+
116
+ **Sub-modules:**
117
+ - **`form-packer`**: Convert HTML forms to JSON with support for nested objects, arrays, and complex structures.
118
+ - Documentation: [`modules/tools/form-packer/README.md`](./modules/tools/form-packer/README.md)
119
+
120
+ **Demo page:**
121
+ - `demo/modules/tools/index.html` (interactive form examples and validation)
122
+
91
123
  ### Utilities
92
124
 
93
125
  - **`loadCss`**: Dynamically load CSS files into your document.
94
126
 
95
- Documentation: [`/modules/common.mjs`](./modules/common.mjs)
127
+ Documentation: [`modules/common.mjs`](./modules/common.mjs)
96
128
 
97
129
  ## Usage
98
130
 
@@ -144,9 +176,10 @@ const apx7 = APX(() => APX('.example'));
144
176
 
145
177
  ### Utilities
146
178
 
147
- - **`APX.getApxPathURI()`**: Retrieve the URI path for a given element.
148
179
  - **`APX.loadCss()`**: Dynamically load CSS files.
149
- - **`APX.dialog()`**: Manage and display dialogs.
180
+ - **`APX.dialog()`**: Manage and display dialogs. See [`modules/dialog/README.md`](./modules/dialog/README.md)
181
+ - **`APX.toast`**: Toast notification system. See [`modules/toast/README.md`](./modules/toast/README.md)
182
+ - **`APX.tools`**: Utility functions. See [`modules/tools/README.md`](./modules/tools/README.md)
150
183
  - **`APX.isAPXObject(obj)`**: Check if an object is an APX object.
151
184
  - **`APX.is_numeric(n)`**: Check if a value is numeric.
152
185