@cocreate/elements 1.46.0 → 1.48.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/CONTRIBUTING.md CHANGED
@@ -13,7 +13,7 @@ Fork the [project on Github](https://github.com/CoCreate-app/CoCreate-elements)
13
13
  ```
14
14
  git elements https://github.com/contributor/CoCreate-elements.git
15
15
  cd CoCreate-elements
16
- git remote add upstream https://github.com/CoCreate-app/CoCreate-elements.git
16
+ git remote add upstream https://gitlab.com/cocreatejs/CoCreate-elements.git
17
17
  ```
18
18
 
19
19
  ## Create a Topic Branch
package/README.md CHANGED
@@ -1,76 +1,461 @@
1
- # CoCreate-elements
1
+ # @cocreate/elements
2
+
3
+ Bind any HTML element directly to your data using HTML5 attributes. An element declares *where its value lives* — a storage, database, array, document, and key — and the module handles the rest: reading the value in, writing changes back, and keeping it synchronized in realtime as other clients and servers broadcast updates. There is no query code, no fetch layer, and no view model. The markup is the data binding.
4
+
5
+ ---
6
+
7
+ ## Documentation
8
+
9
+ For a complete guide and working demo refer to the [documentation](https://cocreate.app/docs/elements).
10
+
11
+ ## Table of Contents
12
+
13
+ * [Features](#features)
14
+ * [Installation](#installation)
15
+ * [Usage](#usage)
16
+ * [How it Works](#how-it-works)
17
+ * [The Data Scope](#the-data-scope)
18
+ * [Core Attributes](#core-attributes)
19
+ * [Behavior Attributes](#behavior-attributes)
20
+ * [Key Expressions](#key-expressions)
21
+ * [Value Pipeline](#value-pipeline)
22
+ * [Forms](#forms)
23
+ * [Filtering and Lists](#filtering-and-lists)
24
+ * [Realtime Synchronization](#realtime-synchronization)
25
+ * [Actions](#actions)
26
+ * [Element Methods](#element-methods)
27
+ * [JavaScript API](#javascript-api)
28
+ * [Behavior Notes](#behavior-notes)
29
+ * [Announcements](#announcements)
30
+ * [Roadmap](#roadmap)
31
+ * [How to Contribute](#how-to-contribute)
32
+ * [About](#about)
33
+ * [License](#license)
34
+
35
+ ---
36
+
37
+ ## Features
38
+
39
+ * **Declarative Data Binding:** Point an element at a document field and it reads, renders, and persists that field without any application code.
40
+ * **Automatic CRUD Resolution:** The operation is inferred from the attributes present, so the same markup creates a record when it has no id and updates it when it does.
41
+ * **Realtime Two-Way Sync:** Elements subscribe to their own data scope and update instantly when the underlying record changes anywhere in the system.
42
+ * **Batched Reads:** Elements sharing a scope are collected into a single query, so a document bound across twenty fields performs one read.
43
+ * **Forms as Documents:** A form groups fields into one payload, propagates its scope to its children, and saves them as a single operation.
44
+ * **Value Transformation Pipeline:** Type coercion, prefixes, suffixes, replacements, casing, and encoding are applied on the way in and out.
45
+ * **Filter Integration:** Works with `@cocreate/filter` to drive queries, sorting, pagination, and infinite scroll from markup.
46
+ * **Action Integration:** Registers `save`, `delete`, and `reset` so persistence composes into action chains.
47
+ * **Automatic Binding:** Elements inserted later, including rendered templates, are initialized and subscribed automatically.
48
+
49
+ ---
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ npm install @cocreate/elements
55
+ ```
2
56
 
3
- Fetch content into any html element by using html5 attributes to query data stored in CoCreate headless CMS. If data is changed it will instantly reflect in html tags as changes are broadcasted in realtime Take it for a spin in our [playground!](https://cocreate.app/docs/elements)
57
+ ```bash
58
+ yarn add @cocreate/elements
59
+ ```
4
60
 
5
- ![minified](https://img.badgesize.io/https://cdn.cocreate.app/elements/latest/CoCreate-elements.min.js?style=flat-square&label=minified&color=orange)
6
- ![gzip](https://img.badgesize.io/https://cdn.cocreate.app/elements/latest/CoCreate-elements.min.js?compression=gzip&style=flat-square&label=gzip&color=yellow)
7
- ![brotli](https://img.badgesize.io/https://cdn.cocreate.app/elements/latest/CoCreate-elements.min.js?compression=brotli&style=flat-square&label=brotli)
8
- ![GitHub latest release](https://img.shields.io/github/v/release/CoCreate-app/CoCreate-elements?style=flat-square)
9
- ![License](https://img.shields.io/github/license/CoCreate-app/CoCreate-elements?style=flat-square)
10
- ![Hiring](https://img.shields.io/static/v1?style=flat-square&label=&message=Hiring&color=blueviolet)
61
+ ### CDN
11
62
 
12
- ![CoCreate-elements](https://cdn.cocreate.app/docs/CoCreate-elements.gif)
63
+ ```html
64
+ <script src="https://cdn.cocreate.app/elements/latest/CoCreate-elements.min.js"></script>
65
+ ```
13
66
 
14
- ## [Docs & Demo](https://cocreate.app/docs/elements)
67
+ ---
15
68
 
16
- For a complete guide and working demo refer to the [doumentation](https://cocreate.app/docs/elements)
69
+ ## Usage
17
70
 
18
- ## CDN
71
+ ### Display a Value
19
72
 
20
73
  ```html
21
- <script src="https://cdn.cocreate.app/elements/latest/CoCreate-elements.min.js"></script>
74
+ <span array="users" object="64b9a32e18f21bc56789abcd" key="name"></span>
22
75
  ```
23
76
 
77
+ The element reads the `name` field of that document and renders it. If the document changes anywhere in the system, the element updates.
78
+
79
+ ### Edit a Value
80
+
24
81
  ```html
25
- <script src="https://cdn.cocreate.app/elements/latest/CoCreate-elements.min.css"></script>
82
+ <input
83
+ array="users"
84
+ object="64b9a32e18f21bc56789abcd"
85
+ key="email"
86
+ realtime="true" />
26
87
  ```
27
88
 
28
- ## NPM
89
+ With `realtime`, every keystroke persists the field. Without it, the value is saved when a `save` action runs.
90
+
91
+ ### Group Fields Into a Document
29
92
 
30
- ```shell
31
- $ npm i @cocreate/elements
93
+ ```html
94
+ <form array="users" object="64b9a32e18f21bc56789abcd">
95
+ <input key="name" />
96
+ <input key="email" />
97
+ <textarea key="bio"></textarea>
98
+
99
+ <button actions="save">Save</button>
100
+ </form>
32
101
  ```
33
102
 
34
- ## yarn
103
+ The form propagates its scope to every field, so each input only declares its `key`. Saving sends one payload containing all three fields.
104
+
105
+ ### Create a Record
35
106
 
36
- ```shell
37
- $ yarn install @cocreate/elements
107
+ ```html
108
+ <form array="users" object>
109
+ <input key="name" />
110
+ <input key="email" />
111
+
112
+ <button actions="save, reset">Create</button>
113
+ </form>
38
114
  ```
39
115
 
40
- # Table of Contents
116
+ An empty `object` attribute means "no document yet". On save the module issues a create, then writes the new id back into the form and its fields, so subsequent saves update the same record.
41
117
 
42
- - [Table of Contents](#table-of-contents)
43
- - [Announcements](#announcements)
44
- - [Roadmap](#roadmap)
45
- - [How to Contribute](#how-to-contribute)
46
- - [About](#about)
47
- - [License](#license)
118
+ ### Render a List
48
119
 
49
- <a name="announcements"></a>
120
+ ```html
121
+ <div
122
+ array="users"
123
+ object
124
+ filter-query-key="status"
125
+ filter-query-value="active"
126
+ filter-limit="20"
127
+ filter-sort-key="name"
128
+ render-query="[template]">
129
+ <div template>
130
+ <span>{{object.name}}</span>
131
+ <span>{{object.email}}</span>
132
+ </div>
133
+ </div>
134
+ ```
50
135
 
51
- # Announcements
136
+ ### Delete a Record
52
137
 
53
- All updates to this library are documented in our [CHANGELOG](https://github.com/CoCreate-app/CoCreate-elements/blob/master/CHANGELOG.md) and [releases](https://github.com/CoCreate-app/CoCreate-elements/releases). You may also subscribe to email for releases and breaking changes.
138
+ ```html
139
+ <button
140
+ array="users"
141
+ object="64b9a32e18f21bc56789abcd"
142
+ actions="delete">
143
+ Delete
144
+ </button>
145
+ ```
146
+
147
+ Multiple targets can be selected with `delete-query`. Each target declares its
148
+ own CRUD scope; object targets sharing the same storage, database, and array are
149
+ sent in one delete request.
150
+
151
+ ```html
152
+ <button
153
+ actions="delete"
154
+ delete-query="$document [data-delete]:checked[]">
155
+ Delete selected
156
+ </button>
157
+
158
+ <input
159
+ type="checkbox"
160
+ data-delete
161
+ array="users"
162
+ object="64b9a32e18f21bc56789abcd" />
163
+ ```
164
+
165
+ ---
166
+
167
+ ## How it Works
168
+
169
+ 1. On load the module scans for elements declaring `storage`, `database`, `array`, or `render-json`.
170
+ 2. Each element's attributes are parsed into a normalized CRUD payload, and its **type** is inferred from which attributes are present.
171
+ 3. A **dataKey** is generated from the scope, and every element sharing that key is grouped together. Field-level `key` is deliberately excluded from document-scope keys so all fields of one document share a single scope.
172
+ 4. The scope is subscribed to over the socket so future changes are pushed to every bound element.
173
+ 5. Reads are debounced and batched, so one query serves every element in the scope.
174
+ 6. The response is distributed to each element, which extracts its own field and renders it through the value pipeline.
175
+ 7. Editable elements listen for input. When `realtime` is enabled, changes persist automatically.
176
+ 8. Writes resolve to a create or an update depending on whether an id is present, and the resulting id is propagated back into the markup.
177
+
178
+ ---
179
+
180
+ ## The Data Scope
181
+
182
+ Attributes describe a hierarchy, from the storage provider down to a single field.
183
+
184
+ | Level | Attribute | Description |
185
+ | ----- | --------- | ----------- |
186
+ | Storage | `storage` | Storage provider or alias |
187
+ | Database | `database` | Database name |
188
+ | Array | `array` | Collection, table, or dataset |
189
+ | Index | `index` | Index within the array |
190
+ | Object | `object` | Document id, empty for a new document |
191
+ | Key | `key` | Field within the document |
192
+
193
+ The **type** of operation is inferred from the deepest level present:
194
+
195
+ | Attributes Present | Inferred Type |
196
+ | ------------------ | ------------- |
197
+ | `object` or `key` (with `array`) | `object` |
198
+ | `index` (with `array`) | `index` |
199
+ | `array` | `array` |
200
+ | `database` | `database` |
201
+ | `storage` | `storage` |
202
+
203
+ Any of these may hold a comma separated list to target several scopes at once.
54
204
 
55
- <a name="roadmap"></a>
205
+ ```html
206
+ <div array="users, admins" key="name"></div>
207
+ ```
56
208
 
57
- # Roadmap
209
+ ---
210
+
211
+ ## Core Attributes
212
+
213
+ | Attribute | Description |
214
+ | --------- | ----------- |
215
+ | `storage` | Storage provider targeted by the operation |
216
+ | `database` | Database name, defaults to the organization |
217
+ | `array` | Collection or table name |
218
+ | `index` | Index scope within the array |
219
+ | `object` | Document id. Empty creates a new document, `ObjectId()` generates one, `pending` marks a create in flight |
220
+ | `key` | Field path within the document |
221
+ | `updateName` | Rename target when updating a named scope |
222
+ | `organization_id` | Tenant identifier |
223
+ | `host` | Host context |
224
+ | `apikey` | API key used for the operation |
225
+ | `room` | Realtime room scope |
226
+ | `reference` | When `false`, strips storage metadata from the returned object |
227
+
228
+ ---
229
+
230
+ ## Behavior Attributes
231
+
232
+ Each of these accepts `"false"` to opt out, and most default to enabled.
233
+
234
+ | Attribute | Description |
235
+ | --------- | ----------- |
236
+ | `crud="false"` | Excludes the element from binding entirely |
237
+ | `read="false"` | Element never reads, it only writes |
238
+ | `save="false"` | Element never writes, it only reads |
239
+ | `update="false"` | Element ignores incoming updates after its first read |
240
+ | `listen="false"` | Element ignores broadcasts, but still accepts its own reads |
241
+ | `delete` | Marks the element as a delete target |
242
+ | `upsert` | Creates the document if it does not exist when updating |
243
+ | `realtime="true"` | Persists on every input event |
244
+ | `crdt="true"` | Routes text edits through collaborative merge instead of overwriting |
245
+ | `broadcast="false"` | Suppresses broadcasting the change to other clients |
246
+ | `broadcast-sender="false"` | Suppresses echoing the change back to the sender |
247
+ | `broadcast-client="false"` | Suppresses propagation to other tabs |
248
+ | `form-attributes="false"` | Prevents the element from inheriting its form's scope |
249
+ | `reset` | Controls reset behavior, see [Forms](#forms) |
250
+ | `splice`, `slice`, `update` | Array mutation modes when the key targets an index |
251
+
252
+ ---
253
+
254
+ ## Key Expressions
255
+
256
+ `key` supports more than a plain field name.
257
+
258
+ | Expression | Resolves To |
259
+ | ---------- | ----------- |
260
+ | `name` | A top-level field |
261
+ | `profile.address.city` | A nested field via dot notation |
262
+ | `tags[0]` | An array member by index |
263
+ | `{}` | The entire document, for reading or writing whole objects |
264
+ | `tags.$length` | The length of an array field |
265
+ | `$data` | The complete response payload |
266
+ | `$object` / `$array` | The full result collection for the current type |
58
267
 
59
- If you are interested in the future direction of this project, please take a look at our open [issues](https://github.com/CoCreate-app/CoCreate-elements/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-elements/pulls). We would love to hear your feedback.
268
+ ```html
269
+ <span array="posts" object="64b9a32e18f21bc56789abcd" key="comments.$length"></span>
270
+ ```
60
271
 
61
- <a name="about"></a>
272
+ ---
273
+
274
+ ## Value Pipeline
275
+
276
+ Values are transformed on the way in and out by `@cocreate/element-prototype`. These attributes apply to any bound element.
277
+
278
+ | Attribute | Description |
279
+ | --------- | ----------- |
280
+ | `value-type` | Coerces the value, for example `json`, `html`, `text`, `array`, `number` |
281
+ | `value-prefix` | Prepends a string |
282
+ | `value-suffix` | Appends a string |
283
+ | `value-replace` | Replaces the first match of a pattern |
284
+ | `value-replaceall` | Replaces every match of a pattern |
285
+ | `value-replacement` | Replacement string used by the above |
286
+ | `value-lowercase` | Lowercases the value |
287
+ | `value-uppercase` | Uppercases the value |
288
+ | `value-encode` | Encodes the value, for example base64 or URI |
289
+ | `value-decode` | Decodes the value |
290
+ | `value-remove-query` | Removes matching nodes before reading an HTML value |
291
+ | `value-dispatch` | Clears the value when a query returns no results |
292
+ | `value-bubbles` | Bubbles the synthetic input event |
293
+ | `value-query` | Composes this element's value from other elements |
294
+ | `value-attribute` | Writes the composed value to an attribute instead of the value |
62
295
 
63
- # About
296
+ ```html
297
+ <textarea
298
+ array="files"
299
+ object="64b9a32e18f21bc56789abcd"
300
+ key="src"
301
+ value-type="text"
302
+ value-replaceall="/```html\n|\n```/g"></textarea>
303
+ ```
64
304
 
65
- CoCreate-elements is guided and supported by the CoCreate Developer Experience Team.
305
+ ---
66
306
 
67
- Please Email the Developer Experience Team [here](mailto:develop@cocreate.app) in case of any queries.
307
+ ## Forms
68
308
 
69
- CoCreate-elements is maintained and funded by CoCreate. The names and logos for CoCreate are trademarks of CoCreate, LLC.
309
+ ### Scope Inheritance
310
+
311
+ A form propagates `organization_id`, `host`, `storage`, `database`, `array`, `index`, `object`, and `key` to descendant elements that participate in binding. Add `form-attributes="false"` to an element that must keep its own scope.
312
+
313
+ ### Generated Ids
314
+
315
+ `object="ObjectId()"` generates a client-side id at initialization, letting related records reference each other before they are persisted.
316
+
317
+ ### Saving
318
+
319
+ Saving a form collects every bound field into one payload per type and issues a single operation. Saving an individual element inside a form delegates to the form, so a field never writes a partial document by accident.
320
+
321
+ ### Reset
322
+
323
+ The `reset` attribute controls what a reset preserves.
324
+
325
+ | Value | Document Id | Value |
326
+ | ----- | ----------- | ----- |
327
+ | omitted | cleared | cleared |
328
+ | `object` | cleared | preserved |
329
+ | `value` | preserved | cleared |
330
+ | `false` | preserved | preserved |
331
+
332
+ ```html
333
+ <input key="organization_id" value="$organization_id" reset="false" hidden />
334
+ ```
335
+
336
+ ---
337
+
338
+ ## Filtering and Lists
339
+
340
+ Filter attributes from `@cocreate/filter` compose directly with a bound scope to drive queries, sorting, limits, and pagination.
341
+
342
+ ```html
343
+ <div
344
+ array="posts"
345
+ object
346
+ filter-query-key="status"
347
+ filter-query-value="published"
348
+ filter-sort-key="created.on"
349
+ filter-sort-direction="desc"
350
+ filter-limit="10"
351
+ render-query="[template]">
352
+ <div filter-on="scroll" filter-query="$parent"></div>
353
+ <article template>{{object.title}}</article>
354
+ </div>
355
+ ```
70
356
 
71
- <a name="contribute"></a>
357
+ A filter element may target another element with `filter-query`, so an input elsewhere on the page can drive a list's query. Changing a filter re-reads the scope and re-renders.
72
358
 
73
- # How to Contribute
359
+ ---
360
+
361
+ ## Realtime Synchronization
362
+
363
+ Every scope subscribes over the socket on two channels: one for the specific document and one for the collection it belongs to. A change therefore reaches both the element bound to that record and any list rendering the collection.
364
+
365
+ Subscriptions are reference counted. When the last element bound to a scope is removed from the DOM, the module unsubscribes automatically, so rendered lists and modals do not leak channels.
366
+
367
+ ---
368
+
369
+ ## Actions
370
+
371
+ | Action | Completion Event | Behavior |
372
+ | ------ | ---------------- | -------- |
373
+ | `save` | `saved` | Persists the element, or its form when it belongs to one |
374
+ | `delete` | `deleted` | Deletes the bound document, honoring `delete-query` for multiple targets |
375
+ | `reset` | `reset` | Restores the form according to each field's `reset` attribute |
376
+
377
+ ```html
378
+ <button actions="save, reset">Save and clear</button>
379
+ ```
380
+
381
+ ---
382
+
383
+ ## Element Methods
384
+
385
+ Binding attaches methods directly to elements, so imperative code and action chains share one implementation.
386
+
387
+ | Method | Available On | Description |
388
+ | ------ | ------------ | ----------- |
389
+ | `getValue()` | any bound element | Reads the value through the value pipeline |
390
+ | `setValue(value)` | any bound element | Writes the value and dispatches input and change |
391
+ | `read()` | any bound element | Re-reads the element's scope |
392
+ | `save()` | any bound element or form | Persists the element or the whole form |
393
+ | `getData()` | forms | Returns the assembled payload without saving |
394
+ | `getFilter()` / `setFilter()` | filtered elements | Reads or replaces the active filter, re-reading the scope |
395
+
396
+ ```javascript
397
+ const form = document.querySelector("#profile");
398
+ const payload = await form.getData();
399
+ await form.save();
400
+ ```
401
+
402
+ ---
403
+
404
+ ## JavaScript API
405
+
406
+ ```javascript
407
+ import elements from "@cocreate/elements";
408
+
409
+ elements.init();
410
+ elements.init(document.querySelector("#profile"));
411
+ ```
412
+
413
+ | Method | Description |
414
+ | ------ | ----------- |
415
+ | `init(element)` | Initializes an element, a collection, or the whole document |
416
+ | `read(element, data, dataKey)` | Reads a scope and distributes the result |
417
+ | `save(element, action)` | Persists an element or form |
418
+ | `getData(element)` | Assembles the payload for an element or form |
419
+ | `getDataObject(element)` | Normalizes an element's attributes into a CRUD payload |
420
+ | `reset(action)` | Runs reset logic for a form |
421
+ | `setDataType(element, data, action)` | Applies a created record's id back into the markup |
422
+ | `elements`, `keys`, `forms` | Internal registries of bound elements and scopes |
423
+
424
+ ---
425
+
426
+ ## Behavior Notes
427
+
428
+ * An element must declare `storage`, `database`, or `array` to be initialized. A lone `object` or `key` is not a binding, which is why fields inside a form rely on inherited scope.
429
+ * Reads are debounced for 500ms and deduplicated per scope, so many elements binding one document produce a single query.
430
+ * An element reads once per scope. Changing a filter or calling `read()` resets that state.
431
+ * A document id must be a 24 character hexadecimal value, or the placeholders `pending` and `ObjectId()`.
432
+ * Elements rendered on the server carry a `rendered` marker and skip their first client render, preserving server output.
433
+ * Save on input requires `realtime`, and never applies to a `_id` field.
434
+ * When `crdt` is enabled and a document id exists, text edits merge collaboratively rather than overwriting.
435
+
436
+ ---
437
+
438
+ ## Announcements
439
+
440
+ All updates to this library are documented in our [CHANGELOG](https://github.com/CoCreate-app/CoCreate-elements/blob/master/CHANGELOG.md) and [releases](https://github.com/CoCreate-app/CoCreate-elements/releases). You may also subscribe to email for releases and breaking changes.
441
+
442
+ ---
443
+
444
+ ## Roadmap
445
+
446
+ Upcoming enhancements include:
447
+
448
+ * Expanded array mutation operators
449
+ * Optimistic write rollback on failure
450
+ * Schema-aware value coercion
451
+ * Development mode diagnostics for unbound and misconfigured scopes
452
+ * Devtools inspection of an element's scope and subscriptions
453
+
454
+ If you are interested in the future direction of this project, please take a look at our open [issues](https://github.com/CoCreate-app/CoCreate-elements/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-elements/pulls). We would love to hear your feedback.
455
+
456
+ ---
457
+
458
+ ## How to Contribute
74
459
 
75
460
  We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING](https://github.com/CoCreate-app/CoCreate-elements/blob/master/CONTRIBUTING.md) guide for details.
76
461
 
@@ -78,14 +463,52 @@ We want this library to be community-driven, and CoCreate led. We need your help
78
463
 
79
464
  We appreciate your continued support, thank you!
80
465
 
81
- <a name="license"></a>
466
+ ---
467
+
468
+ ## About
469
+
470
+ CoCreate-elements is guided and supported by the CoCreate Developer Experience Team.
471
+
472
+ Please Email the Developer Experience Team [here](mailto:develop@cocreate.app) in case of any queries.
473
+
474
+ CoCreate-elements is maintained and funded by CoCreate. The names and logos for CoCreate are trademarks of CoCreate, LLC.
475
+
476
+ ---
82
477
 
83
- # License
478
+ ## License
84
479
 
85
480
  This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
86
481
 
87
- - **Open Source Use**: For open-source projects and non-commercial use, this software is available under the AGPLv3. The AGPLv3 allows you to freely use, modify, and distribute this software, provided that all modifications and derivative works are also licensed under the AGPLv3. For the full license text, see the [LICENSE file](https://github.com/CoCreate-app/CoCreate-element/blob/master/LICENSE).
482
+ * **Open Source Use**: For open-source projects and non-commercial use, this software is available under the AGPLv3. The AGPLv3 allows you to freely use, modify, and distribute this software, provided that all modifications and derivative works are also licensed under the AGPLv3. For the full license text, see the [LICENSE file](https://github.com/CoCreate-app/CoCreate-elements/blob/master/LICENSE).
88
483
 
89
- - **Commercial Use**: For-profit companies and individuals intending to use this software for commercial purposes must obtain a commercial license. The commercial license is available when you sign up for an API key on our [website](https://cocreate.app). This license permits proprietary use and modification of the software without the copyleft requirements of the AGPLv3. It is ideal for integrating this software into proprietary commercial products and applications.
484
+ * **Commercial Use**: For-profit companies and individuals intending to use this software for commercial purposes must obtain a commercial license. The commercial license is available when you sign up for an API key on our [website](https://cocreate.app). This license permits proprietary use and modification of the software without the copyleft requirements of the AGPLv3. It is ideal for integrating this software into proprietary commercial products and applications.
90
485
 
91
486
  If you have not purchased a commercial license and intend to use this software for commercial purposes, you are required to sign up for an API key on our website.
487
+
488
+
489
+ ### Enter shortcuts for action buttons
490
+
491
+ Set `submit-query` on a form or an inner section to explicitly select the action
492
+ element Enter should click from a single-line input:
493
+
494
+ ```html
495
+ <form>
496
+ <section submit-query="#next-step">
497
+ <input name="name" />
498
+ <button id="next-step" type="button" actions="disabled, validate, save, disabled">Next</button>
499
+ </section>
500
+ </form>
501
+ ```
502
+
503
+ The nearest `submit-query` within the form wins. Its value uses CoCreate query
504
+ selectors, resolved from the element carrying the attribute. The resolved
505
+ target must have `actions`, belong to the same form, and be visible and enabled.
506
+ No action target is inferred when the attribute is absent. Empty or unresolved
507
+ queries, multiple returned targets, and disabled targets do not fall through to
508
+ native submission. Held Enter does not repeatedly activate the button.
509
+
510
+ Textareas, selects, editable content, input widgets, composition, modified
511
+ keystrokes, and events already handled by another listener keep their normal
512
+ keyboard behavior. This shortcut calls `.click()`; it does not submit the form
513
+ itself. Existing `action`/`method` handling remains separate, and a submit button
514
+ with `actions` can still preprocess an external submission through its chain.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/elements",
3
- "version": "1.46.0",
3
+ "version": "1.48.0",
4
4
  "description": "Fetch content into any html element by using html5 attributes to query data stored in CoCreate headless CMS. If data is changed it will instantly reflect in html tags as changes are broadcasted in realtime",
5
5
  "keywords": [
6
6
  "elements",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "git+https://github.com/CoCreate-app/CoCreate-elements.git"
25
+ "url": "git+https://gitlab.com/cocreatejs/CoCreate-elements.git"
26
26
  },
27
27
  "author": "CoCreate LLC",
28
28
  "license": "AGPL-3.0",
@@ -37,15 +37,16 @@
37
37
  "main": "./src/index.js",
38
38
  "dependencies": {
39
39
  "@cocreate/actions": "^1.24.0",
40
- "@cocreate/crud-client": "^1.36.1",
40
+ "@cocreate/crud-client": "^1.37.0",
41
41
  "@cocreate/element-prototype": "^1.35.0",
42
- "@cocreate/filter": "^1.36.0",
43
- "@cocreate/observer": "^1.22.0",
44
- "@cocreate/render": "^1.50.0",
45
- "@cocreate/utils": "^1.52.0"
42
+ "@cocreate/filter": "^1.37.0",
43
+ "@cocreate/observer": "^1.23.0",
44
+ "@cocreate/render": "^1.51.0",
45
+ "@cocreate/socket-client": "^1.43.0",
46
+ "@cocreate/utils": "^1.54.0"
46
47
  },
47
48
  "devDependencies": {
48
- "@cocreate/webpack": "^1.8.0"
49
+ "@cocreate/webpack": "^1.9.0"
49
50
  },
50
51
  "allowScripts": {
51
52
  "@cocreate/actions@1.21.4": true,