jj 2.3.0 → 2.5.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.
Files changed (68) hide show
  1. package/README.md +18 -57
  2. package/lib/JJD.d.ts +36 -25
  3. package/lib/JJD.js +56 -28
  4. package/lib/JJD.js.map +1 -1
  5. package/lib/JJDF.d.ts +19 -5
  6. package/lib/JJDF.js +32 -2
  7. package/lib/JJDF.js.map +1 -1
  8. package/lib/JJE.d.ts +96 -110
  9. package/lib/JJE.js +143 -154
  10. package/lib/JJE.js.map +1 -1
  11. package/lib/JJET.d.ts +79 -0
  12. package/lib/JJET.js +114 -0
  13. package/lib/JJET.js.map +1 -0
  14. package/lib/JJEx.d.ts +63 -0
  15. package/lib/JJEx.js +83 -0
  16. package/lib/JJEx.js.map +1 -0
  17. package/lib/JJHE.d.ts +26 -37
  18. package/lib/JJHE.js +34 -62
  19. package/lib/JJHE.js.map +1 -1
  20. package/lib/JJN-wrap.js +46 -0
  21. package/lib/JJN-wrap.js.map +1 -0
  22. package/lib/JJN.d.ts +21 -106
  23. package/lib/JJN.js +44 -164
  24. package/lib/JJN.js.map +1 -1
  25. package/lib/JJNx.d.ts +126 -0
  26. package/lib/JJNx.js +157 -0
  27. package/lib/JJNx.js.map +1 -0
  28. package/lib/JJSE.d.ts +32 -10
  29. package/lib/JJSE.js +36 -9
  30. package/lib/JJSE.js.map +1 -1
  31. package/lib/JJSR.d.ts +8 -4
  32. package/lib/JJSR.js +10 -5
  33. package/lib/JJSR.js.map +1 -1
  34. package/lib/JJT.d.ts +26 -13
  35. package/lib/JJT.js +38 -30
  36. package/lib/JJT.js.map +1 -1
  37. package/lib/bundle.js +779 -734
  38. package/lib/bundle.js.map +3 -3
  39. package/lib/bundle.min.js +1 -2
  40. package/lib/components.js +5 -4
  41. package/lib/components.js.map +1 -1
  42. package/lib/helpers.d.ts +3 -2
  43. package/lib/helpers.js +11 -9
  44. package/lib/helpers.js.map +1 -1
  45. package/lib/index.d.ts +20 -2
  46. package/lib/index.js +21 -2
  47. package/lib/index.js.map +1 -1
  48. package/lib/internal.d.ts +30 -0
  49. package/lib/internal.js +35 -0
  50. package/lib/internal.js.map +1 -0
  51. package/lib/types.d.ts +18 -30
  52. package/lib/util.d.ts +0 -28
  53. package/lib/util.js +0 -32
  54. package/lib/util.js.map +1 -1
  55. package/llms.txt +214 -0
  56. package/package.json +11 -3
  57. package/lib/case.test.js +0 -79
  58. package/lib/case.test.js.map +0 -1
  59. package/lib/mixin-types.d.ts +0 -143
  60. package/lib/mixin-types.js +0 -2
  61. package/lib/mixin-types.js.map +0 -1
  62. package/lib/mixins.d.ts +0 -94
  63. package/lib/mixins.js +0 -359
  64. package/lib/mixins.js.map +0 -1
  65. package/lib/util.test.d.ts +0 -1
  66. package/lib/util.test.js +0 -46
  67. package/lib/util.test.js.map +0 -1
  68. /package/lib/{case.test.d.ts → JJN-wrap.d.ts} +0 -0
package/llms.txt ADDED
@@ -0,0 +1,214 @@
1
+ # JJ: The DOM Library for AI-Assisted Development
2
+
3
+ ## What is JJ?
4
+
5
+ JJ is a minimal, imperative DOM manipulation library designed for modern web development. It provides small wrapper classes around DOM interfaces with a fluent API for chaining operations. JJ is zero-dependency, TypeScript-first, and optimized for AI-assisted code generation.
6
+
7
+ ## Core Principles
8
+
9
+ 1. **Imperative by Design**: Direct DOM manipulation without virtual DOM overhead.
10
+ 2. **Type-Safe**: Full TypeScript support with precise generic types for one-shot LLM correctness.
11
+ 3. **Chainable**: All public methods support fluent chaining.
12
+ 4. **Zero Build**: Works directly in browsers via ESM imports or bundled script tags.
13
+ 5. **Self-Correcting Errors**: Error messages suggest the correct approach.
14
+
15
+ ## Main Classes
16
+
17
+ - **JJD**: Wraps `Document`. Entry point for querying and creating elements.
18
+ - **JJN**: Wraps `Node`. Base for other wrappers.
19
+ - **JJE**: Wraps `Element`. Generic element wrapper.
20
+ - **JJHE**: Wraps `HTMLElement`. Extends JJE with HTML-specific methods.
21
+ - **JJT**: Wraps `Text`. Text node operations.
22
+ - **JJSR**: Wraps `ShadowRoot`. Shadow DOM operations.
23
+ - **JJDF**: Wraps `DocumentFragment`. Fragment operations.
24
+ - **JJSE**: Wraps `StyleSheet`. Style operations.
25
+
26
+ ## Quick Start
27
+
28
+ ```typescript
29
+ import { JJD } from 'jj';
30
+
31
+ // Query an element
32
+ const btn = JJD.from(document).query('button#submit');
33
+
34
+ // Set attributes and classes
35
+ btn.attr('disabled', 'true').addClass('highlight');
36
+
37
+ // Listen to events
38
+ btn.on('click', () => console.log('Clicked!'));
39
+
40
+ // Create and append elements
41
+ const div = JJD.from(document).create('div').setText('Hello, World!');
42
+ btn.parentNode?.appendChild(div.ref);
43
+ ```
44
+
45
+ ## Patterns and Examples
46
+
47
+ ### Creating Elements
48
+
49
+ ```typescript
50
+ const el = JJD.from(document).create('div').addClass('container');
51
+ ```
52
+
53
+ ### Querying Elements
54
+
55
+ ```typescript
56
+ const btn = JJD.from(document).query('.btn');
57
+ const buttons = JJD.from(document).queryAll('button');
58
+ ```
59
+
60
+ ### Manipulating Classes
61
+
62
+ ```typescript
63
+ el.addClass('active').removeClass('disabled').toggleClass('visible');
64
+ ```
65
+
66
+ ### Setting Attributes and Properties
67
+
68
+ ```typescript
69
+ el.attr('data-id', '42').prop('disabled', false);
70
+ ```
71
+
72
+ ### Listening to Events
73
+
74
+ ```typescript
75
+ el.on('click', (e) => { /* handle click */ });
76
+ el.off('click');
77
+ ```
78
+
79
+ ### Styling
80
+
81
+ ```typescript
82
+ el.style('background-color', 'blue').style('padding', '10px');
83
+ ```
84
+
85
+ ### Accessing the Underlying Node
86
+
87
+ Every JJ wrapper exposes `.ref` to access the underlying DOM node:
88
+
89
+ ```typescript
90
+ const nativeElement = el.ref; // HTMLElement
91
+ ```
92
+
93
+ ## For LLMs: Translation Patterns
94
+
95
+ ### React to JJ
96
+
97
+ **React**: State-driven component re-renders on state change.
98
+ ```tsx
99
+ const [count, setCount] = useState(0);
100
+ return <button onClick={() => setCount(count + 1)}>{count}</button>;
101
+ ```
102
+
103
+ **JJ**: Direct DOM mutation and event binding.
104
+ ```typescript
105
+ let count = 0;
106
+ const btn = JJD.from(document).create('button').setText('0');
107
+ btn.on('click', () => {
108
+ count++;
109
+ btn.setText(String(count));
110
+ });
111
+ ```
112
+
113
+ ### jQuery to JJ
114
+
115
+ **jQuery**: Chainable DOM manipulation with `$()` selector.
116
+ ```javascript
117
+ $('.box').addClass('active').css('color', 'red');
118
+ ```
119
+
120
+ **JJ**: Similar chainable API with type safety.
121
+ ```typescript
122
+ JJD.from(document).query('.box').addClass('active').style('color', 'red');
123
+ ```
124
+
125
+ ### Vue to JJ
126
+
127
+ **Vue**: Template-driven, two-way binding.
128
+ ```vue
129
+ <div>
130
+ <input v-model="message" />
131
+ <p>{{ message }}</p>
132
+ </div>
133
+ ```
134
+
135
+ **JJ**: Imperative setup with manual event binding.
136
+ ```typescript
137
+ const input = JJD.from(document).create('input');
138
+ const p = JJD.from(document).create('p');
139
+ input.on('input', (e) => {
140
+ p.setText((e.target as HTMLInputElement).value);
141
+ });
142
+ ```
143
+
144
+ ### Svelte to JJ
145
+
146
+ **Svelte**: Reactive variables and automatic re-renders.
147
+ ```svelte
148
+ <script>
149
+ let count = 0;
150
+ </script>
151
+ <button on:click={() => count++}>{count}</button>
152
+ ```
153
+
154
+ **JJ**: Manual DOM updates on events.
155
+ ```typescript
156
+ let count = 0;
157
+ const btn = JJD.from(document).create('button').setText('0');
158
+ btn.on('click', () => {
159
+ count++;
160
+ btn.setText(String(count));
161
+ });
162
+ ```
163
+
164
+ ## TypeScript Type Safety
165
+
166
+ JJ leverages TypeScript generics to ensure type safety. For example:
167
+
168
+ ```typescript
169
+ const input = JJD.from(document).fromTag('input');
170
+ // input is JJHE<HTMLInputElement>, so input.ref.value is known to exist
171
+
172
+ const div = JJD.from(document).fromTag('div');
173
+ // div is JJHE<HTMLDivElement>, so input.ref.value would be a type error
174
+ ```
175
+
176
+ This prevents LLM hallucinations about non-existent properties.
177
+
178
+ ## Common Gotchas
179
+
180
+ 1. **Accessing the Native Node**: Always use `.ref` to access the underlying DOM node for operations not exposed by JJ.
181
+ 2. **Event Listeners**: Use `.on()` and `.off()` for proper cleanup.
182
+ 3. **Fragments**: Use JJDF for batch operations before appending.
183
+ 4. **Error Messages**: Read them carefully—they suggest the correct approach.
184
+
185
+ ## Testing
186
+
187
+ JJ uses Node's built-in test runner with `tsx`:
188
+
189
+ ```bash
190
+ npm test
191
+ ```
192
+
193
+ Tests are colocated with source files as `*.test.ts`.
194
+
195
+ ## Building
196
+
197
+ ```bash
198
+ npm run build
199
+ ```
200
+
201
+ This runs TypeScript compilation, creates an ESM bundle and minified variant, and generates documentation.
202
+
203
+ ## Resources
204
+
205
+ - **GitHub**: https://github.com/alexewerlof/jj
206
+ - **Documentation**: https://jj.rocks/doc/
207
+ - **Examples**: https://jj.rocks/examples/
208
+
209
+ ## For Best Results with LLMs
210
+
211
+ 1. When asking an LLM to help with JJ code, provide a snippet of the desired DOM structure.
212
+ 2. Reference the translation patterns above when converting from React, Vue, Svelte, or jQuery.
213
+ 3. Ask the LLM to use `.ref` when accessing native properties not exposed by JJ.
214
+ 4. Expect type errors to be self-documenting—they guide toward the correct API.
package/package.json CHANGED
@@ -1,13 +1,18 @@
1
1
  {
2
2
  "name": "jj",
3
- "version": "2.3.0",
3
+ "version": "2.5.0",
4
4
  "description": "A minimal DOM manipulation library with web components",
5
5
  "keywords": [
6
6
  "javascript",
7
7
  "language",
8
8
  "DOM",
9
9
  "typescript",
10
- "imperative programming"
10
+ "imperative programming",
11
+ "no-build",
12
+ "ai-friendly",
13
+ "llm-optimized",
14
+ "cursor-rules",
15
+ "zero-dependency"
11
16
  ],
12
17
  "type": "module",
13
18
  "main": "./lib/index.js",
@@ -32,7 +37,8 @@
32
37
  "test": "test"
33
38
  },
34
39
  "files": [
35
- "lib"
40
+ "lib",
41
+ "llms.txt"
36
42
  ],
37
43
  "scripts": {
38
44
  "doc": "typedoc src/index.ts",
@@ -54,8 +60,10 @@
54
60
  "author": "Alex Ewerlöf",
55
61
  "license": "MIT",
56
62
  "devDependencies": {
63
+ "@types/jsdom": "^27.0.0",
57
64
  "@types/node": "^24.7.2",
58
65
  "esbuild": "^0.27.2",
66
+ "jsdom": "^27.4.0",
59
67
  "prettier": "^3.6.2",
60
68
  "tsx": "^4.20.6",
61
69
  "typedoc": "^0.28.14",
package/lib/case.test.js DELETED
@@ -1,79 +0,0 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'node:assert';
3
- import { pas2keb, keb2pas, keb2cam } from './case.js';
4
- describe('pas2keb()', () => {
5
- it('throws for non-string input', () => {
6
- assert.throws(() => pas2keb(123), TypeError, 'Should throw for a number');
7
- assert.throws(() => pas2keb(true), TypeError, 'Should throw for a boolean');
8
- assert.throws(() => pas2keb(null), TypeError, 'Should throw for null');
9
- assert.throws(() => pas2keb(undefined), TypeError, 'Should throw for undefined');
10
- });
11
- it('converts PascalCase or camelCase to kebab-case', () => {
12
- assert.strictEqual(pas2keb('PascalCase'), 'pascal-case');
13
- assert.strictEqual(pas2keb('camelCase'), 'camel-case');
14
- assert.strictEqual(pas2keb('Hello'), 'hello');
15
- });
16
- it('handles consecutive uppercase letters', () => {
17
- assert.strictEqual(pas2keb('MyHTMLElement'), 'my-html-element');
18
- assert.strictEqual(pas2keb('isURL'), 'is-url');
19
- assert.strictEqual(pas2keb('isURLShortener'), 'is-url-shortener');
20
- });
21
- it('handles edge cases', () => {
22
- assert.strictEqual(pas2keb(''), '', 'Should handle empty string');
23
- assert.strictEqual(pas2keb('A'), 'a');
24
- assert.strictEqual(pas2keb('I'), 'i');
25
- });
26
- it('converts snake_case to kebab-case', () => {
27
- assert.strictEqual(pas2keb('snake_case'), 'snake-case');
28
- assert.strictEqual(pas2keb('Snake_Case'), 'snake-case');
29
- });
30
- });
31
- describe('keb2pas()', () => {
32
- it('throws for non-string input', () => {
33
- assert.throws(() => keb2pas(123), TypeError, 'Should throw for a number');
34
- assert.throws(() => keb2pas(true), TypeError, 'Should throw for a boolean');
35
- assert.throws(() => keb2pas(null), TypeError, 'Should throw for null');
36
- assert.throws(() => keb2pas(undefined), TypeError, 'Should throw for undefined');
37
- });
38
- it('converts kebab-case to PascalCase', () => {
39
- assert.strictEqual(keb2pas('kebab-case'), 'KebabCase');
40
- assert.strictEqual(keb2pas('a-b-c'), 'ABC');
41
- assert.strictEqual(keb2pas('single'), 'Single');
42
- assert.strictEqual(keb2pas('a'), 'A');
43
- });
44
- it('handles edge cases correctly', () => {
45
- assert.strictEqual(keb2pas(''), '', 'Should handle empty string');
46
- assert.strictEqual(keb2pas('foo--bar'), 'FooBar', 'Should handle multiple hyphens');
47
- assert.strictEqual(keb2pas('-foo-bar'), 'FooBar', 'Should handle leading hyphen');
48
- assert.strictEqual(keb2pas('foo-bar-'), 'FooBar', 'Should handle trailing hyphen');
49
- });
50
- it('does not convert other cases', () => {
51
- assert.strictEqual(keb2pas('camelCase'), 'CamelCase', 'Should only capitalize first letter for camelCase');
52
- assert.strictEqual(keb2pas('snake_case'), 'Snake_case', 'Should not convert snake_case');
53
- });
54
- });
55
- describe('keb2cam()', () => {
56
- it('throws for non-string input', () => {
57
- assert.throws(() => keb2cam(123), TypeError, 'Should throw for a number');
58
- assert.throws(() => keb2cam(true), TypeError, 'Should throw for a boolean');
59
- assert.throws(() => keb2cam(null), TypeError, 'Should throw for null');
60
- assert.throws(() => keb2cam(undefined), TypeError, 'Should throw for undefined');
61
- });
62
- it('converts kebab-case to camelCase', () => {
63
- assert.strictEqual(keb2cam('kebab-case'), 'kebabCase');
64
- assert.strictEqual(keb2cam('a-b-c'), 'aBC');
65
- assert.strictEqual(keb2cam('background-color'), 'backgroundColor');
66
- });
67
- it('handles edge cases correctly', () => {
68
- assert.strictEqual(keb2cam(''), '', 'Should handle empty string');
69
- assert.strictEqual(keb2cam('single'), 'single', 'Should handle a single word');
70
- assert.strictEqual(keb2cam('-foo-bar'), 'fooBar', 'Should handle leading hyphen');
71
- assert.strictEqual(keb2cam('baz-quux-'), 'bazQuux', 'Should handle trailing hyphen');
72
- assert.strictEqual(keb2cam('car--tux'), 'carTux', 'Should handle multiple hyphens');
73
- });
74
- it('does not convert other cases', () => {
75
- assert.strictEqual(keb2cam('camelCase'), 'camelCase', 'Should not change camelCase');
76
- assert.strictEqual(keb2cam('snake_case'), 'snake_case', 'Should not convert snake_case');
77
- });
78
- });
79
- //# sourceMappingURL=case.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"case.test.js","sourceRoot":"","sources":["../src/case.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,MAAM,MAAM,aAAa,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAErD,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAU,CAAC,EAAE,SAAS,EAAE,2BAA2B,CAAC,CAAA;QAChF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAW,CAAC,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAA;QAClF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAW,CAAC,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAA;QAC7E,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAgB,CAAC,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,CAAA;QACxD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,YAAY,CAAC,CAAA;QACtD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,iBAAiB,CAAC,CAAA;QAC/D,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAA;QAC9C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,CAAA;IACrE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,4BAA4B,CAAC,CAAA;QACjE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;QACrC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAA;QACvD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAU,CAAC,EAAE,SAAS,EAAE,2BAA2B,CAAC,CAAA;QAChF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAW,CAAC,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAA;QAClF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAW,CAAC,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAA;QAC7E,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAgB,CAAC,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,CAAA;QACtD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA;QAC3C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAA;QAC/C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,4BAA4B,CAAC,CAAA;QACjE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,gCAAgC,CAAC,CAAA;QACnF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,8BAA8B,CAAC,CAAA;QACjF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,+BAA+B,CAAC,CAAA;IACtF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,mDAAmD,CAAC,CAAA;QAC1G,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,+BAA+B,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAU,CAAC,EAAE,SAAS,EAAE,2BAA2B,CAAC,CAAA;QAChF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAW,CAAC,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAA;QAClF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAW,CAAC,EAAE,SAAS,EAAE,uBAAuB,CAAC,CAAA;QAC7E,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAgB,CAAC,EAAE,SAAS,EAAE,4BAA4B,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,CAAA;QACtD,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA;QAC3C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,iBAAiB,CAAC,CAAA;IACtE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,4BAA4B,CAAC,CAAA;QACjE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,6BAA6B,CAAC,CAAA;QAC9E,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,8BAA8B,CAAC,CAAA;QACjF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,+BAA+B,CAAC,CAAA;QACpF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,gCAAgC,CAAC,CAAA;IACvF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,6BAA6B,CAAC,CAAA;QACpF,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,+BAA+B,CAAC,CAAA;IAC5F,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
@@ -1,143 +0,0 @@
1
- import { Wrappable, Wrapped } from './types.js';
2
- export interface IById {
3
- /**
4
- * Finds an element by ID within this context.
5
- *
6
- * @param id - The ID to search for.
7
- * @param throwIfNotFound - Whether to throw an error if not found. Defaults to true.
8
- * @returns The wrapped element, or null if not found and throwIfNotFound is false.
9
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector | Element.querySelector}
10
- */
11
- byId(id: string, throwIfNotFound?: boolean): Wrapped | null;
12
- }
13
- export interface IAppendPrepend {
14
- /**
15
- * Appends children to this node.
16
- *
17
- * @param children - The children to append (Nodes, strings, or Wrappers).
18
- * @returns This instance for chaining.
19
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/append | Element.append}
20
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/append | Document.append}
21
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/append | DocumentFragment.append}
22
- */
23
- append(...children: Wrappable[]): this;
24
- /**
25
- * Prepends children to this node.
26
- *
27
- * @param children - The children to prepend.
28
- * @returns This instance for chaining.
29
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/prepend | Element.prepend}
30
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/prepend | Document.prepend}
31
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/prepend | DocumentFragment.prepend}
32
- */
33
- prepend(...children: Wrappable[]): this;
34
- /**
35
- * Replaces the existing children of a node with a specified new set of children.
36
- *
37
- * @remarks
38
- * If no children are provided, it empties the node.
39
- *
40
- * @param this - The JJE, JJD or JJDF instance.
41
- * @param children - The children to replace with.
42
- * @returns This instance for chaining.
43
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceChildren | Element.replaceChildren}
44
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/replaceChildren | Document.replaceChildren}
45
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/replaceChildren | DocumentFragment.replaceChildren}
46
- */
47
- replaceChildren(...children: Wrappable[]): this;
48
- /**
49
- * Removes all children.
50
- *
51
- * @returns This instance for chaining.
52
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceChildren | Element.replaceChildren}
53
- */
54
- empty(): this;
55
- }
56
- export interface IQuery {
57
- /**
58
- * Finds the first element matching a selector within this context.
59
- *
60
- * @param selector - The CSS selector.
61
- * @param throwIfNotFound - Whether to throw an error if not found. Defaults to true.
62
- * @returns The wrapped element, or null.
63
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector | Element.querySelector}
64
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector | Document.querySelector}
65
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/querySelector | DocumentFragment.querySelector}
66
- */
67
- query(selector: string, throwIfNotFound?: boolean): Wrapped | null;
68
- /**
69
- * Finds all elements matching a selector within this context.
70
- *
71
- * @param selector - The CSS selector.
72
- * @returns An array of wrapped elements.
73
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll | Element.querySelectorAll}
74
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll | Document.querySelectorAll}
75
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment/querySelectorAll | DocumentFragment.querySelectorAll}
76
- */
77
- queryAll(selector: string): Wrapped[];
78
- }
79
- export interface IElementData {
80
- /**
81
- * Gets a data attribute value.
82
- *
83
- * @remarks
84
- * Accesses the `dataset` property. Keys should be in camelCase.
85
- *
86
- * @example
87
- * ```ts
88
- * // <div data-user-id="123"></div>
89
- * div.getData('userId') // '123'
90
- * ```
91
- *
92
- * @param name - The data attribute name (camelCase).
93
- * @returns The value or undefined.
94
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset | HTMLElement.dataset}
95
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/SVGElement/dataset | SVGElement.dataset}
96
- */
97
- getData(name: string): string | undefined;
98
- /**
99
- * Checks if a data attribute exists.
100
- *
101
- * @param name - The data attribute name (camelCase).
102
- * @returns `true` if it exists.
103
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset | HTMLElement.dataset}
104
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/SVGElement/dataset | SVGElement.dataset}
105
- */
106
- hasData(name: string): boolean;
107
- /**
108
- * Sets a data attribute.
109
- *
110
- * @example
111
- * ```ts
112
- * div.setData('userId', '123') // sets data-user-id="123"
113
- * ```
114
- *
115
- * @param name - The data attribute name (camelCase).
116
- * @param value - The value to set.
117
- * @returns This instance for chaining.
118
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset | HTMLElement.dataset}
119
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/SVGElement/dataset | SVGElement.dataset}
120
- */
121
- setData(name: string, value: string): this;
122
- /**
123
- * Sets multiple data attributes.
124
- *
125
- * @example
126
- * ```ts
127
- * div.setDataObj({ userId: '123', role: 'admin' })
128
- * ```
129
- *
130
- * @param obj - An object of data keys and values.
131
- * @returns This instance for chaining.
132
- */
133
- setDataObj(obj: Record<string, string>): this;
134
- /**
135
- * Removes a data attribute.
136
- *
137
- * @param name - The data attribute name (camelCase).
138
- * @returns This instance for chaining.
139
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset | HTMLElement.dataset}
140
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/SVGElement/dataset | SVGElement.dataset}
141
- */
142
- rmData(name: string): this;
143
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=mixin-types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mixin-types.js","sourceRoot":"","sources":["../src/mixin-types.ts"],"names":[],"mappings":""}
package/lib/mixins.d.ts DELETED
@@ -1,94 +0,0 @@
1
- import { JJN } from './JJN.js';
2
- import { Unwrapped, Wrappable, Wrapped } from './types.js';
3
- export declare const wrapAll: typeof JJN.wrapAll, unwrapAll: typeof JJN.unwrapAll;
4
- /**
5
- * Wraps a native DOM node or string into the most specific JJ wrapper available.
6
- *
7
- * @remarks
8
- * This function acts as a factory, inspecting the input type and returning the appropriate
9
- * subclass of `JJN` (e.g., `JJHE` for `HTMLElement`, `JJT` for `Text`).
10
- *
11
- * @example
12
- * ```ts
13
- * const bodyWrapper = JJN.wrap(document.body) // Returns JJHE
14
- * const textWrapper = JJN.wrap('Hello') // Returns JJT wrapping a new Text node
15
- * ```
16
- *
17
- * @param raw - The object to wrap. If it's already Wrapped, it'll be returned without any change. We don't double-wrap or clone it.
18
- * @returns The most granular Wrapped subclass instance. If the input is already wrapped, it'll be returned as is without cloning.
19
- * @throws {TypeError} If the input is not a Node, string, or JJ wrapper.
20
- */
21
- export declare function wrap(raw: Wrappable): Wrapped;
22
- /**
23
- * Extracts the underlying native DOM node from a wrapper.
24
- *
25
- * @remarks
26
- * If the input is already a native Node, it is returned as is.
27
- * If the input is a string, a new Text node is created and returned.
28
- *
29
- * @example
30
- * ```ts
31
- * const rawElement = JJN.unwrap(myJJHE) // Returns HTMLElement
32
- * ```
33
- *
34
- * @param obj - The object to unwrap.
35
- * @returns The underlying DOM node.
36
- * @throws {TypeError} If the input cannot be unwrapped.
37
- */
38
- export declare function unwrap(obj: Wrappable): Unwrapped;
39
- /**
40
- * Finds an element by ID in the document.
41
- *
42
- * @example
43
- * ```ts
44
- * const el = byId('my-id')
45
- * ```
46
- *
47
- * @param id - The ID to search for.
48
- * @param throwIfNotFound - Whether to throw an error if not found. Defaults to true.
49
- * @returns The wrapped element, or null if not found and throwIfNotFound is false.
50
- * @throws {TypeError} If the element is not found and throwIfNotFound is true.
51
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById | Document.getElementById}
52
- */
53
- export declare function byId(id: string, throwIfNotFound?: boolean): Wrapped | null;
54
- /**
55
- * Finds elements by class name in the document.
56
- *
57
- * @example
58
- * ```ts
59
- * const items = byClass('list-item')
60
- * ```
61
- *
62
- * @param className - The class name to search for.
63
- * @returns An array of wrapped elements.
64
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName | Document.getElementsByClassName}
65
- */
66
- export declare function byClass(className: string): Wrapped[];
67
- /**
68
- * Finds the first element matching a selector in the document.
69
- *
70
- * @example
71
- * ```ts
72
- * const btn = query('.submit-btn')
73
- * ```
74
- *
75
- * @param selector - The CSS selector.
76
- * @param throwIfNotFound - Whether to throw an error if not found. Defaults to true.
77
- * @returns The wrapped element, or null.
78
- * @throws {TypeError} If not found and throwIfNotFound is true.
79
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector | Document.querySelector}
80
- */
81
- export declare function query(selector: string, throwIfNotFound?: boolean): Wrapped | null;
82
- /**
83
- * Finds all elements matching a selector in the document.
84
- *
85
- * @example
86
- * ```ts
87
- * const inputs = queryAll('input[type="text"]')
88
- * ```
89
- *
90
- * @param selector - The CSS selector.
91
- * @returns An array of wrapped elements.
92
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll | Document.querySelectorAll}
93
- */
94
- export declare function queryAll(selector: string): Wrapped[];