litewire 1.0.0 → 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,5 +1,9 @@
1
1
  # Litewire Framework
2
2
 
3
+ ```bash
4
+ npm i litewire
5
+ ```
6
+
3
7
  ## Complete Architecture Manual & Reference Guide
4
8
 
5
9
  A comprehensive technical breakdown of the HTML-driven AJAX engine, dynamic component loader, DOM swapping, state management, and lifecycle events.
@@ -57,8 +61,8 @@ To support deployment in deeply nested directories or custom app sub-paths, Lite
57
61
  ```javascript
58
62
  // Custom manual instantiation with options
59
63
  const customLitewire = new Litewire({
60
- baseUrl: '[https://api.myproject.com](https://api.myproject.com)',
61
- loadingClass: 'is-loading' // Class applied to active triggers and indicators
64
+ baseUrl: "[https://api.myproject.com](https://api.myproject.com)",
65
+ loadingClass: "is-loading", // Class applied to active triggers and indicators
62
66
  });
63
67
  ```
64
68
 
@@ -68,18 +72,18 @@ const customLitewire = new Litewire({
68
72
 
69
73
  All core functionalities are driven by attaching `lw-*` attributes directly to standard HTML tags.
70
74
 
71
- | Attribute | Accepted Values | Default | Functional Description |
72
- |---|---|---|---|
73
- | `lw-get` | Relative / Absolute Path | None | Executes an HTTP GET request to the specified endpoint. |
74
- | `lw-post` | Relative / Absolute Path | None | Executes an HTTP POST request. Submits form payload if bound to or inside a `<form>`. |
75
- | `lw-put` | Relative / Absolute Path | None | Executes an HTTP PUT request with FormData payload attachment. |
76
- | `lw-delete` | Relative / Absolute Path | None | Executes an HTTP DELETE request. |
77
- | `lw-trigger` | `click`, `submit`, `load`, custom | Contextual | Overrides trigger event. Defaults to `submit` for forms, `click` for interactive tags. `load` fires instantly. |
78
- | `lw-target` | CSS Selector | Self Element | Specifies the container element where the returned HTML response will be rendered. |
79
- | `lw-swap` | `innerHTML`, `outerHTML`, `prepend`, `append` | `innerHTML` | Controls how the received HTML response replaces or integrates into the target element. |
80
- | `lw-indicator` | CSS Selector | `.litewire-indicator` | Specifies target loading elements. Automatically toggles the active `loadingClass` during request execution. |
81
- | `lw-push-url` | `true`, `false`, Custom Path | `false` | Pushes a new state to the browser history, caching DOM contents for native back/forward navigation. |
82
- | `lw-component` | JS File Path | None | Asynchronously imports a JavaScript module and mounts it directly onto the host DOM element. |
75
+ | Attribute | Accepted Values | Default | Functional Description |
76
+ | -------------- | --------------------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------- |
77
+ | `lw-get` | Relative / Absolute Path | None | Executes an HTTP GET request to the specified endpoint. |
78
+ | `lw-post` | Relative / Absolute Path | None | Executes an HTTP POST request. Submits form payload if bound to or inside a `<form>`. |
79
+ | `lw-put` | Relative / Absolute Path | None | Executes an HTTP PUT request with FormData payload attachment. |
80
+ | `lw-delete` | Relative / Absolute Path | None | Executes an HTTP DELETE request. |
81
+ | `lw-trigger` | `click`, `submit`, `load`, custom | Contextual | Overrides trigger event. Defaults to `submit` for forms, `click` for interactive tags. `load` fires instantly. |
82
+ | `lw-target` | CSS Selector | Self Element | Specifies the container element where the returned HTML response will be rendered. |
83
+ | `lw-swap` | `innerHTML`, `outerHTML`, `prepend`, `append` | `innerHTML` | Controls how the received HTML response replaces or integrates into the target element. |
84
+ | `lw-indicator` | CSS Selector | `.litewire-indicator` | Specifies target loading elements. Automatically toggles the active `loadingClass` during request execution. |
85
+ | `lw-push-url` | `true`, `false`, Custom Path | `false` | Pushes a new state to the browser history, caching DOM contents for native back/forward navigation. |
86
+ | `lw-component` | JS File Path | None | Asynchronously imports a JavaScript module and mounts it directly onto the host DOM element. |
83
87
 
84
88
  ---
85
89
 
@@ -104,33 +108,33 @@ When an element with `lw-component="path/to/module.js"` is injected into the DOM
104
108
 
105
109
  ```html
106
110
  <!-- Target element containing component directives and dataset parameters -->
107
- <div
108
- lw-component="assets/js/uploader.js"
109
- data-max-files="5"
110
- data-allowed-types="image/png,image/jpeg">
111
- </div>
111
+ <div
112
+ lw-component="assets/js/uploader.js"
113
+ data-max-files="5"
114
+ data-allowed-types="image/png,image/jpeg"
115
+ ></div>
112
116
  ```
113
117
 
114
118
  #### JavaScript Module (`assets/js/uploader.js`)
115
119
 
116
120
  ```javascript
117
121
  export default class ImageUploader {
118
- constructor(element, params) {
119
- this.container = element;
120
- this.maxFiles = params.maxFiles || 1;
121
- this.allowedTypes = params.allowedTypes || '*';
122
-
123
- this.render();
124
- }
122
+ constructor(element, params) {
123
+ this.container = element;
124
+ this.maxFiles = params.maxFiles || 1;
125
+ this.allowedTypes = params.allowedTypes || "*";
126
+
127
+ this.render();
128
+ }
125
129
 
126
- render() {
127
- this.container.innerHTML = `
130
+ render() {
131
+ this.container.innerHTML = `
128
132
  <div class="upload-box">
129
133
  <p>Upload up to ${this.maxFiles} files (${this.allowedTypes})</p>
130
134
  <input type="file" multiple accept="${this.allowedTypes}">
131
135
  </div>
132
136
  `;
133
- }
137
+ }
134
138
  }
135
139
  ```
136
140
 
@@ -171,22 +175,22 @@ Enabling history tracking via `lw-push-url="true"` allows AJAX-driven applicatio
171
175
 
172
176
  Litewire dispatches standard, bubbling DOM events during the request lifecycles. Custom JavaScript code can hook into these lifecycle stages using standard `addEventListener` calls.
173
177
 
174
- | Event Name | `event.detail` | Description / Usage |
175
- |---|---|---|
176
- | `litewire:beforeRequest` | `null` | Fires immediately before the HTTP request is initiated. Ideal for disabling inputs or custom client validation. |
177
- | `litewire:afterRequest` | `null` | Fires after the request succeeds and the HTML content swap is complete. Ideal for triggering animations. |
178
- | `litewire:error` | `{ error: Error }` | Fires if a network error occurs or the HTTP response returns an error status (non-2xx). |
178
+ | Event Name | `event.detail` | Description / Usage |
179
+ | ------------------------ | ------------------ | --------------------------------------------------------------------------------------------------------------- |
180
+ | `litewire:beforeRequest` | `null` | Fires immediately before the HTTP request is initiated. Ideal for disabling inputs or custom client validation. |
181
+ | `litewire:afterRequest` | `null` | Fires after the request succeeds and the HTML content swap is complete. Ideal for triggering animations. |
182
+ | `litewire:error` | `{ error: Error }` | Fires if a network error occurs or the HTTP response returns an error status (non-2xx). |
179
183
 
180
184
  ### Lifecycle Hooks Example
181
185
 
182
186
  ```javascript
183
187
  // Global logging and notification system integration
184
- document.addEventListener('litewire:beforeRequest', (e) => {
185
- console.log('Initiating Litewire request from:', e.target);
188
+ document.addEventListener("litewire:beforeRequest", (e) => {
189
+ console.log("Initiating Litewire request from:", e.target);
186
190
  });
187
191
 
188
- document.addEventListener('litewire:error', (e) => {
189
- alert(`Request failed: ${e.detail.error.message}`);
192
+ document.addEventListener("litewire:error", (e) => {
193
+ alert(`Request failed: ${e.detail.error.message}`);
190
194
  });
191
195
  ```
192
196
 
@@ -201,7 +205,7 @@ Litewire natively secures outgoing write operations (`POST`, `PUT`, `DELETE`) ag
201
205
  Before dispatching non-GET requests, Litewire scans the host page head for a CSRF meta tag:
202
206
 
203
207
  ```html
204
- <meta name="csrf-token" content="abc123securehash456">
208
+ <meta name="csrf-token" content="abc123securehash456" />
205
209
  ```
206
210
 
207
211
  If detected, Litewire automatically includes the retrieved token into the HTTP request headers:
@@ -218,14 +222,15 @@ X-CSRF-TOKEN: abc123securehash456
218
222
 
219
223
  ```html
220
224
  <!-- Live search input updating target table and browser address bar -->
221
- <input
222
- type="text"
223
- name="q"
224
- placeholder="Search users..."
225
- lw-get="/users/search"
226
- lw-trigger="keyup"
227
- lw-target="#user-table-body"
228
- lw-push-url="true">
225
+ <input
226
+ type="text"
227
+ name="q"
228
+ placeholder="Search users..."
229
+ lw-get="/users/search"
230
+ lw-trigger="keyup"
231
+ lw-target="#user-table-body"
232
+ lw-push-url="true"
233
+ />
229
234
 
230
235
  <table>
231
236
  <tbody id="user-table-body">
@@ -234,14 +239,47 @@ X-CSRF-TOKEN: abc123securehash456
234
239
  </table>
235
240
  ```
236
241
 
242
+ ```php
243
+ // Route
244
+ Route::get('/users/search', 'UsersController@search')->name('user.search');
245
+
246
+ //UserController
247
+ public function search(Request $request)
248
+ {
249
+ $query = $request->input('q', '');
250
+ $search = $this->model('UsersModel')->searchUser($query);
251
+ $data = [
252
+ 'users' => $search
253
+ ];
254
+
255
+ $html = $this->render('users/search', $data);
256
+ return $this->response($html);
257
+ }
258
+
259
+ //Blade
260
+ @if (!empty($users))
261
+ @foreach ($users as $index => $user)
262
+ <tr>
263
+ <td>{{ $index + 1 }}</td>
264
+ <td>{{ $user['fullname'] }}</td>
265
+ </tr>
266
+ @endforeach
267
+ @endif
268
+ ```
269
+
237
270
  ### Pattern B: Form Submission with Indicator & Append Swap
238
271
 
239
272
  ```html
240
- <form lw-post="/comments/add" lw-target="#comments-list" lw-swap="append" lw-indicator="#spinner">
273
+ <form
274
+ lw-post="/comments/add"
275
+ lw-target="#comments-list"
276
+ lw-swap="append"
277
+ lw-indicator="#spinner"
278
+ >
241
279
  <textarea name="comment" required placeholder="Write a comment..."></textarea>
242
-
280
+
243
281
  <button type="submit">
244
- Post Comment
282
+ Post Comment
245
283
  <span id="spinner" class="litewire-indicator hidden">Posting...</span>
246
284
  </button>
247
285
  </form>
@@ -255,9 +293,13 @@ X-CSRF-TOKEN: abc123securehash456
255
293
 
256
294
  ```html
257
295
  <!-- Automatically fetches and replaces content once page loads -->
258
- <div lw-get="/analytics/widget" lw-trigger="load" lw-target="#analytics-container">
259
- <p>Loading real-time analytics data...</p>
296
+ <div
297
+ lw-get="/analytics/widget"
298
+ lw-trigger="load"
299
+ lw-target="#analytics-container"
300
+ >
301
+ <p>Loading real-time analytics data...</p>
260
302
  </div>
261
303
 
262
304
  <div id="analytics-container"></div>
263
- ```
305
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litewire",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A lightweight HTML-driven AJAX engine and dynamic ES module component loader.",
5
5
  "main": "src/litewire.js",
6
6
  "module": "src/litewire.js",
@@ -30,4 +30,4 @@
30
30
  "url": "https://github.com/languaojs/litewire/issues"
31
31
  },
32
32
  "homepage": "https://github.com/languaojs/litewire#readme"
33
- }
33
+ }
package/src/litewire.js CHANGED
@@ -97,7 +97,7 @@ class Litewire {
97
97
  if (!path) return;
98
98
 
99
99
  const cleanPath = path.replace(/^\/+/, '');
100
- const url = `${this.baseUrl}/${cleanPath}`;
100
+ let url = `${this.baseUrl}/${cleanPath}`;
101
101
 
102
102
  const options = { method: method.toUpperCase(), headers: {} };
103
103
 
@@ -106,7 +106,21 @@ class Litewire {
106
106
  options.headers['X-CSRF-TOKEN'] = csrfToken;
107
107
  }
108
108
 
109
- if (method !== 'get') {
109
+ if (method === 'get') {
110
+ const form = el.tagName === 'FORM' ? el : el.closest('form');
111
+ let params = new URLSearchParams();
112
+
113
+ if (form) {
114
+ params = new URLSearchParams(new FormData(form));
115
+ } else if (el.name && el.value !== undefined) {
116
+ params.append(el.name, el.value);
117
+ }
118
+
119
+ const queryString = params.toString();
120
+ if (queryString) {
121
+ url += (url.includes('?') ? '&' : '?') + queryString;
122
+ }
123
+ } else {
110
124
  const form = el.tagName === 'FORM' ? el : el.closest('form');
111
125
  if (form) {
112
126
  options.body = new FormData(form);