jj 2.4.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.
- package/README.md +18 -57
- package/lib/JJD.d.ts +36 -25
- package/lib/JJD.js +56 -28
- package/lib/JJD.js.map +1 -1
- package/lib/JJDF.d.ts +19 -5
- package/lib/JJDF.js +32 -2
- package/lib/JJDF.js.map +1 -1
- package/lib/JJE.d.ts +96 -110
- package/lib/JJE.js +143 -154
- package/lib/JJE.js.map +1 -1
- package/lib/JJET.d.ts +79 -0
- package/lib/JJET.js +114 -0
- package/lib/JJET.js.map +1 -0
- package/lib/JJEx.d.ts +63 -0
- package/lib/JJEx.js +83 -0
- package/lib/JJEx.js.map +1 -0
- package/lib/JJHE.d.ts +26 -37
- package/lib/JJHE.js +34 -62
- package/lib/JJHE.js.map +1 -1
- package/lib/JJN-wrap.js +46 -0
- package/lib/JJN-wrap.js.map +1 -0
- package/lib/JJN.d.ts +10 -118
- package/lib/JJN.js +19 -176
- package/lib/JJN.js.map +1 -1
- package/lib/JJNx.d.ts +126 -0
- package/lib/JJNx.js +157 -0
- package/lib/JJNx.js.map +1 -0
- package/lib/JJSE.d.ts +32 -10
- package/lib/JJSE.js +36 -9
- package/lib/JJSE.js.map +1 -1
- package/lib/JJSR.d.ts +8 -4
- package/lib/JJSR.js +10 -5
- package/lib/JJSR.js.map +1 -1
- package/lib/JJT.d.ts +26 -13
- package/lib/JJT.js +38 -30
- package/lib/JJT.js.map +1 -1
- package/lib/bundle.js +755 -741
- package/lib/bundle.js.map +3 -3
- package/lib/bundle.min.js +1 -2
- package/lib/components.js +5 -4
- package/lib/components.js.map +1 -1
- package/lib/helpers.d.ts +3 -2
- package/lib/helpers.js +11 -9
- package/lib/helpers.js.map +1 -1
- package/lib/index.d.ts +20 -2
- package/lib/index.js +21 -2
- package/lib/index.js.map +1 -1
- package/lib/internal.d.ts +30 -0
- package/lib/internal.js +35 -0
- package/lib/internal.js.map +1 -0
- package/lib/types.d.ts +18 -30
- package/lib/util.d.ts +0 -28
- package/lib/util.js +0 -32
- package/lib/util.js.map +1 -1
- package/llms.txt +214 -0
- package/package.json +11 -3
- package/lib/case.test.js +0 -79
- package/lib/case.test.js.map +0 -1
- package/lib/mixin-types.d.ts +0 -143
- package/lib/mixin-types.js +0 -2
- package/lib/mixin-types.js.map +0 -1
- package/lib/mixins.d.ts +0 -77
- package/lib/mixins.js +0 -336
- package/lib/mixins.js.map +0 -1
- package/lib/util.test.d.ts +0 -1
- package/lib/util.test.js +0 -46
- package/lib/util.test.js.map +0 -1
- /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
|
+
"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
|
package/lib/case.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"case.test.js","sourceRoot":"","sources":["../src/case.test.ts"],"names":[],"mappings":"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"}
|
package/lib/mixin-types.d.ts
DELETED
|
@@ -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
|
-
setChildren(...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
|
-
}
|
package/lib/mixin-types.js
DELETED
package/lib/mixin-types.js.map
DELETED
|
@@ -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,77 +0,0 @@
|
|
|
1
|
-
import { JJN } from './JJN.js';
|
|
2
|
-
import { Wrappable, Wrapped } from './types.js';
|
|
3
|
-
export declare const wrapAll: typeof JJN.wrapAll, unwrap: typeof JJN.unwrap, unwrapAll: typeof JJN.unwrapAll, isWrapable: typeof JJN.isWrapable;
|
|
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
|
-
* Finds an element by ID in the document.
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* const el = byId('my-id')
|
|
28
|
-
* ```
|
|
29
|
-
*
|
|
30
|
-
* @param id - The ID to search for.
|
|
31
|
-
* @param throwIfNotFound - Whether to throw an error if not found. Defaults to true.
|
|
32
|
-
* @returns The wrapped element, or null if not found and throwIfNotFound is false.
|
|
33
|
-
* @throws {TypeError} If the element is not found and throwIfNotFound is true.
|
|
34
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById | Document.getElementById}
|
|
35
|
-
*/
|
|
36
|
-
export declare function byId(id: string, throwIfNotFound?: boolean): Wrapped | null;
|
|
37
|
-
/**
|
|
38
|
-
* Finds elements by class name in the document.
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```ts
|
|
42
|
-
* const items = byClass('list-item')
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* @param className - The class name to search for.
|
|
46
|
-
* @returns An array of wrapped elements.
|
|
47
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName | Document.getElementsByClassName}
|
|
48
|
-
*/
|
|
49
|
-
export declare function byClass(className: string): Wrapped[];
|
|
50
|
-
/**
|
|
51
|
-
* Finds the first element matching a selector in the document.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* const btn = query('.submit-btn')
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* @param selector - The CSS selector.
|
|
59
|
-
* @param throwIfNotFound - Whether to throw an error if not found. Defaults to true.
|
|
60
|
-
* @returns The wrapped element, or null.
|
|
61
|
-
* @throws {TypeError} If not found and throwIfNotFound is true.
|
|
62
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector | Document.querySelector}
|
|
63
|
-
*/
|
|
64
|
-
export declare function query(selector: string, throwIfNotFound?: boolean): Wrapped | null;
|
|
65
|
-
/**
|
|
66
|
-
* Finds all elements matching a selector in the document.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```ts
|
|
70
|
-
* const inputs = queryAll('input[type="text"]')
|
|
71
|
-
* ```
|
|
72
|
-
*
|
|
73
|
-
* @param selector - The CSS selector.
|
|
74
|
-
* @returns An array of wrapped elements.
|
|
75
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll | Document.querySelectorAll}
|
|
76
|
-
*/
|
|
77
|
-
export declare function queryAll(selector: string): Wrapped[];
|