luciddom 0.0.0-stage → 1.0.1

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 CHANGED
@@ -1,3 +1,153 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # LucidDOM.js
2
+
3
+ LucidDOM.js is a lightweight browser-side DOM helper. It wraps a parent element and provides methods for creating elements, selecting descendants, updating content, handling events, applying inline styles, and removing elements.
4
+
5
+ ## Installation
6
+
7
+ ### npm
8
+
9
+ Install LucidDOM from npm:
10
+
11
+ ```sh
12
+ npm install luciddom
13
+ ```
14
+
15
+ Import the default export in your app. Use a bundler that resolves npm packages:
16
+
17
+ ```html
18
+ <div id="app"></div>
19
+ <script type="module" src="./app.js"></script>
20
+ ```
21
+
22
+ ```js
23
+ // app.js
24
+ import LucidDOM from 'luciddom';
25
+
26
+ const app = new LucidDOM(document.querySelector('#app'));
27
+
28
+ const message = app.addElement({
29
+ tag: 'p',
30
+ className: 'message',
31
+ value: 'Hello from LucidDOM!'
32
+ });
33
+
34
+ message.styles({ color: 'darkslateblue', fontWeight: 'bold' });
35
+ ```
36
+
37
+ ### unpkg CDN
38
+
39
+ For a browser module without an npm install or bundler, import the package directly from unpkg:
40
+
41
+ ```html
42
+ <div id="app"></div>
43
+ <script type="module">
44
+ import LucidDOM from 'https://unpkg.com/luciddom@1.0.1/lucidDOM.js';
45
+
46
+ const app = new LucidDOM(document.querySelector('#app'));
47
+ app.addElement({
48
+ tag: 'p',
49
+ value: 'Hello from LucidDOM!'
50
+ });
51
+ </script>
52
+ ```
53
+
54
+ The constructor accepts a DOM element and scopes queries and element creation to it. If no parent is passed, it defaults to `document.body`.
55
+
56
+ ## Common operations
57
+
58
+ ### Select and update
59
+
60
+ ```js
61
+ const heading = app.select('h1');
62
+
63
+ if (heading.current) {
64
+ heading.update({ value: 'Welcome', className: 'page-title' });
65
+ heading.styles({ color: 'darkslateblue' });
66
+ }
67
+ ```
68
+
69
+ `select(selector)` uses `querySelector()` within the configured parent. The returned handle's `current` property is `null` when no element matches, so check it before using the handle.
70
+
71
+ ### Listen for events
72
+
73
+ ```js
74
+ const button = app.select('#submit');
75
+
76
+ function submitForm() {
77
+ console.log('Submitted');
78
+ }
79
+
80
+ button.on('click', submitForm);
81
+ // Later, remove the same listener with the same function reference:
82
+ button.off('click', submitForm);
83
+ ```
84
+
85
+ `on()` and `off()` are also available on the `LucidDOM` instance and act on its parent element.
86
+
87
+ ### Create and remove elements
88
+
89
+ ```js
90
+ const item = app.addElement({
91
+ tag: 'li',
92
+ className: 'todo-item',
93
+ value: 'Read the documentation'
94
+ });
95
+
96
+ item.on('click', () => console.log('Item clicked'));
97
+ item.remove();
98
+ ```
99
+
100
+ ## API overview
101
+
102
+ | API | Description |
103
+ | --- | --- |
104
+ | `new LucidDOM(parent?)` | Create an instance scoped to `parent`, defaulting to `document.body`. |
105
+ | `app.addElement(options)` | Create and append an element; returns a handle for events, styles, and removal. |
106
+ | `app.select(selector)` | Select the first matching descendant and return a handle with `current`. |
107
+ | `app.selectAll(selector)` | Select all matching descendants; `current` is the native `NodeList` and handle methods apply to every match. |
108
+ | `app.on(event, callback)` / `app.off(event, callback)` | Add or remove a listener on the parent element. |
109
+ | `app.styles(styleObject)` | Apply inline CSS styles to the parent element. |
110
+ | `handle.update(options)` | Update content and supported attributes on a selected element. |
111
+ | `handle.addClass(name)` / `handle.removeClass(name)` | Add or remove a class on a selected element. |
112
+ | `handle.remove()` | Remove the handled element from the DOM. |
113
+
114
+ `addElement()` accepts a required `tag` and these optional properties: `className`, `id`, `value`, `type`, `placeholder`, `name`, `htmlFor`, `formAction`, `formMethod`, `formTarget`, `formEnctype`, `formNoValidate`, `ariaLabel`, `title`, and `html`.
115
+
116
+ `value` sets text content (and the element's value property). `html` sets `innerHTML`; only pass trusted or sanitized markup. Prefer `value` for plain text.
117
+
118
+ ## Working with multiple matches
119
+
120
+ The handle from `selectAll()` applies its helper methods to each matching element. It supports event listeners, inline styles, adding and removing classes, updating supported attributes and content, removing the matches, and adding a child to each match.
121
+
122
+ ```js
123
+ const items = app.selectAll('.todo-item');
124
+
125
+ items.styles({ color: 'darkslateblue' });
126
+ items.addClass('is-visible');
127
+ items.update({ title: 'Visible item' });
128
+ items.on('click', (event) => {
129
+ console.log('Clicked:', event.currentTarget);
130
+ });
131
+
132
+ // `current` remains a native NodeList for custom per-element work.
133
+ items.current.forEach((item) => {
134
+ console.log(item.textContent);
135
+ });
136
+ ```
137
+
138
+ When nothing matches, `current` is an empty NodeList and helper methods do nothing. `select()` returns a handle even when there is no match; check `handle.current` before calling methods on that handle.
139
+
140
+ ## Build
141
+
142
+ The package includes an esbuild script to create a minified browser bundle:
143
+
144
+ ```sh
145
+ npm install
146
+ npm run build
147
+ ```
148
+
149
+ The output is written to `dist/luciddom.min.js`.
150
+
151
+ ## Documentation
152
+
153
+ See [docs.html](./docs.html) for the navigable guide, examples, and API reference.
@@ -0,0 +1,2 @@
1
+ (()=>{var x=class{constructor(l=document.querySelector("body")){this.parent=l,this.element}addElement({tag:l,className:e,id:t,value:i,type:r,placeholder:n,name:y,htmlFor:E,formAction:L,formMethod:a,formTarget:f,formEnctype:h,formNoValidate:c,ariaLabel:u,title:p,html:v}){try{return this.element=document.createElement(l),e&&(this.element.className=e),r&&(this.element.type=r),i&&(this.element.innerText=i),this.element.value=i,t&&(this.element.id=t),v&&(this.element.innerHTML=v),n&&(this.element.placeholder=n),this.element.name=y,p&&(this.element.title=p),u&&(this.element.ariaLabel=u),this.element.htmlFor=E,L&&(this.element.formAction=L),h&&(this.element.formEnctype=h),a&&(this.element.formMethod=a),f&&(this.element.formTarget=f),c&&(this.element.formNoValidate=c),this.parent.appendChild(this.element),{on:(d="",o=()=>{})=>{this.element.addEventListener(d,o)},off:(d="",o=()=>{})=>{this.element.removeEventListener(d,o)},styles:(d={})=>{Object.assign(this.element.style,d)},remove:()=>{this.element.remove()},addChildren:({tag:d,className:o,id:s,value:T,type:C,placeholder:g,name:q,htmlFor:S,formAction:F,formMethod:N,formTarget:O,formEnctype:j,formNoValidate:w,ariaLabel:A,title:H,html:V})=>{let m;return m=document.createElement(d),o&&(m.className=o),C&&(m.type=C),T&&(m.innerText=T),m.value=T,s&&(m.id=s),V&&(m.innerHTML=V),g&&(m.placeholder=g),m.name=q,H&&(m.title=H),A&&(m.ariaLabel=A),this.element.htmlFor=S,F&&(m.formAction=F),j&&(m.formEnctype=j),N&&(m.formMethod=N),O&&(m.formTarget=O),w&&(m.formNoValidate=w),this.element.appendChild(m),{on:(b="",M=()=>{})=>{this.element.addEventListener(b,M)},off:(b="",M=()=>{})=>{this.element.removeEventListener(b,M)},styles:(b={})=>{Object.assign(this.element.style,b)},remove:()=>{this.element.remove()}}}}}catch{throw new Error(new DOMException)}}on(l="",e=()=>{}){this.parent.addEventListener(l,e)}off(l="",e=()=>{}){this.parent.removeEventListener(l,e)}styles(l={}){Object.assign(this.parent.style,l)}addClass(l){this.element.classList.add(l)}removeClass(l){this.element.classList.remove(l)}select(l){let e=this.parent.querySelector(l);return{current:e,on:(t="",i=()=>{})=>{e.addEventListener(t,i)},off:(t="",i=()=>{})=>{e.removeEventListener(t,i)},styles:(t={})=>{Object.assign(e.style,t)},remove:()=>{e.remove()},addClass:t=>{e.classList.add(t)},removeClass:t=>{e.classList.remove(t)},update:({className:t,id:i,value:r,type:n,placeholder:y,name:E,htmlFor:L,formAction:a,formMethod:f,formTarget:h,formEnctype:c,formNoValidate:u,ariaLabel:p,title:v,html:d})=>{t&&(e.className=t),i&&(e.id=i),r&&(e.value=r),r&&(e.innerText=r),n&&(e.type=n),d&&(e.innerHTML=d),y&&(e.placeholder=y),e.name=E,e.htmlFor=L,a&&(e.formAction=a),c&&(e.formEnctype=c),f&&(e.formMethod=f),h&&(e.formTarget=h),u&&(e.formNoValidate=u),v&&(e.title=v),p&&(e.ariaLabel=p)},addChildren:({tag:t,className:i,id:r,value:n,type:y,placeholder:E,name:L,htmlFor:a,formAction:f,formMethod:h,formTarget:c,formEnctype:u,formNoValidate:p,ariaLabel:v,title:d,html:o})=>{try{return this.element=document.createElement(t),i&&(this.element.className=i),y&&(this.element.type=y),n&&(this.element.innerText=n),this.element.value=n,r&&(this.element.id=r),o&&(this.element.innerHTML=o),E&&(this.element.placeholder=E),this.element.name=L,d&&(this.element.title=d),v&&(this.element.ariaLabel=v),this.element.htmlFor=a,f&&(this.element.formAction=f),u&&(this.element.formEnctype=u),h&&(this.element.formMethod=h),c&&(this.element.formTarget=c),p&&(this.element.formNoValidate=p),e.appendChild(this.element),{on:(s="",T=()=>{})=>{this.element.addEventListener(s,T)},off:(s="",T=()=>{})=>{this.element.removeEventListener(s,T)},styles:(s={})=>{Object.assign(this.element.style,s)},remove:()=>{this.element.remove()}}}catch{throw new Error(new DOMException)}}}}selectAll(l){let e=this.parent.querySelectorAll(l);return{current:e,on:(t="",i=()=>{})=>{e.forEach(r=>r.addEventListener(t,i))},off:(t="",i=()=>{})=>{e.forEach(r=>r.removeEventListener(t,i))},styles:(t={})=>{e.forEach(i=>Object.assign(i.style,t))},remove:()=>{e.forEach(t=>t.remove())},addClass:t=>{e.forEach(i=>i.classList.add(t))},removeClass:t=>{e.forEach(i=>i.classList.remove(t))},update:(t={})=>{let{className:i,id:r,value:n,type:y,placeholder:E,name:L,htmlFor:a,formAction:f,formMethod:h,formTarget:c,formEnctype:u,formNoValidate:p,ariaLabel:v,title:d,html:o}=t;e.forEach(s=>{i!==void 0&&(s.className=i),r!==void 0&&(s.id=r),n!==void 0&&(s.value=n,s.innerText=n),y!==void 0&&(s.type=y),E!==void 0&&(s.placeholder=E),L!==void 0&&(s.name=L),o!==void 0&&(s.innerHTML=o),a!==void 0&&(s.htmlFor=a),f!==void 0&&(s.formAction=f),u!==void 0&&(s.formEnctype=u),h!==void 0&&(s.formMethod=h),c!==void 0&&(s.formTarget=c),p!==void 0&&(s.formNoValidate=p),d!==void 0&&(s.title=d),v!==void 0&&(s.ariaLabel=v)})},addChildren:t=>{let i=[];return e.forEach(r=>{let n=document.createElement(t.tag),{tag:y,className:E,id:L,value:a,type:f,placeholder:h,name:c,htmlFor:u,formAction:p,formMethod:v,formTarget:d,formEnctype:o,formNoValidate:s,ariaLabel:T,title:C,html:g}=t;E!==void 0&&(n.className=E),L!==void 0&&(n.id=L),a!==void 0&&(n.innerText=a,n.value=a),f!==void 0&&(n.type=f),h!==void 0&&(n.placeholder=h),c!==void 0&&(n.name=c),u!==void 0&&(n.htmlFor=u),p!==void 0&&(n.formAction=p),v!==void 0&&(n.formMethod=v),d!==void 0&&(n.formTarget=d),o!==void 0&&(n.formEnctype=o),s!==void 0&&(n.formNoValidate=s),T!==void 0&&(n.ariaLabel=T),C!==void 0&&(n.title=C),g!==void 0&&(n.innerHTML=g),r.appendChild(n),i.push(n)}),i}}}},k=x;})();
2
+ //# sourceMappingURL=luciddom.min.js.map