cradova 2.2.2 → 2.3.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 (3) hide show
  1. package/README.md +276 -110
  2. package/dist/index.js +302 -298
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -49,11 +49,12 @@ Cradova follows the [VJS specification](https://github.com/fridaycandour/cradova
49
49
 
50
50
  Cradova is aimed to be fast and simple with and fewer abstractions and yet easily composable.
51
51
 
52
- Cradova does't rely on visual DOM or diff algorithms to manage the DOM, instead, State management is done more elegantly with a simple predictive model, manually and easily with all the speed.
52
+ Cradova is not built on visual DOM or diff algorithms.
53
+ Instead, State management is done more elegantly with a simple predictive model, simple and easy with all the speed.
53
54
 
54
- ### is this a big benefit?
55
+ ## Is this a big benefit?
55
56
 
56
- Undoubtedly, this provides a significant advantage. You can experience it firsthand and decide for yourself.
57
+ Undoubtedly, this provides a significant advantage. You can experience it firsthand and decide.
57
58
 
58
59
  Cradova has already been utilized in multiple production projects, and we will continuously update this page to showcase our advancements as we keep improving.
59
60
 
@@ -83,12 +84,10 @@ npm i cradova
83
84
 
84
85
  Many aspects of Cradova are not reflected in the following example. More functionality will be entailed in future docs.
85
86
 
86
- Here's an example of create a basic component in Cradova:
87
+ ## A basic component in Cradova:
87
88
 
88
89
  ```js
89
- // cradova v2.0.0 comes with all html tags prebuilt and fully typed
90
- // this gives your app more performance gain.
91
- import _, { h1 } from "cradova";
90
+ import { div, h1 } from "cradova";
92
91
 
93
92
  function Hello(name) {
94
93
  return h1("Hello " + name, {
@@ -99,88 +98,56 @@ function Hello(name) {
99
98
  });
100
99
  }
101
100
 
102
- // document fragment empty cradova call _()
103
-
104
- const html = _(Hello("peter"), Hello("joe"));
101
+ const html = div(Hello("peter"), Hello("joe"));
105
102
 
106
103
  document.body.append(html);
107
104
  ```
108
105
 
109
- ```js
110
- // regular example
111
- import _ from "cradova";
112
-
113
- function Hello(name) {
114
- return _("h1", "Hello " + name);
115
- }
116
-
117
- const html = _(Hello("peter"), Hello("joe"));
118
-
119
- document.body.append(html);
120
- ```
106
+ ## working with state:
121
107
 
122
- ## Using Screen
108
+ this a collection of basic examples
109
+ you can choose any that best suite what problem you want to solve
123
110
 
124
111
  ```js
125
- import _, { Screen, Router } from "cradova";
112
+ import _, {
113
+ button,
114
+ createSignal,
115
+ Ref,
116
+ reference,
117
+ h1,
118
+ br,
119
+ div,
120
+ } from "../dist/index.js";
126
121
 
127
- function HelloMessage(name) {
128
- // an effect run once after screen renders
129
- this.effect(() => {
130
- const name = new Promise((res) => {
131
- res("friday");
132
- });
133
- this.updateState(await name)
122
+ function Hello(name) {
123
+ return h1("Hello " + name, {
124
+ className: "title",
125
+ style: {
126
+ color: "grey",
127
+ },
134
128
  });
135
- // effects can be used to make api calls needed for the page
136
- return _("div", "Hello " + name);
137
129
  }
138
130
 
131
+ const html = div(Hello("peter"), Hello("joe"));
132
+
133
+ // reference (not state)
134
+
135
+ function typingExample() {
136
+ const re = new reference();
137
+ return _(
138
+ "div",
139
+ input({
140
+ oninput() {
141
+ re.text.innerText = this.value;
142
+ },
143
+ placeholder: "typing simulation",
144
+ }),
145
+ p(" no thing typed yet!", { reference: re.bindAs("text") })
146
+ );
147
+ }
139
148
 
140
- /*
141
-
142
- when using router and screens
143
-
144
- cradova will create a div with data-cra-id=cradova-app-wrapper
145
-
146
- if it already exist cradova will use it instead
147
-
148
- so if you want to use your own mount point then create a div with data-cra-id="cradova-app-wrapper"
149
-
150
- */
151
-
152
- const home = new Screen({
153
- name: "hello page", // page title
154
- template: HelloMessage,
155
- ...
156
- });
157
-
158
- Router.route("/", home);
159
-
160
- // navigates to that page
161
- // Router.navigate("/home", data, force);
162
- // get the page ready in the background
163
- // Router.packageScreen("/home");
164
- // get route params for this page
165
- // Router.getParams();
166
-
167
- ```
168
-
169
- ## State management
170
-
171
- ```js
172
-
173
-
174
- // element can have this.updateState when the shouldUpdate props is true
175
-
176
- // Ref components
177
-
178
- // state can be managed from a store when using createSignal or simpleStores
179
- // this method is not yet documented
180
-
181
- import _, { Ref } from "cradova";
182
-
183
- // simple count
149
+ // setting shouldUpdate to true
150
+ // gives you this.updateState binding
184
151
 
185
152
  function counter() {
186
153
  let num = 0;
@@ -193,32 +160,42 @@ function counter() {
193
160
  });
194
161
  }
195
162
 
163
+ // Another example with data- attribute
164
+
196
165
  function dataCounter() {
197
166
  return _("h1| 0", {
198
167
  shouldUpdate: true,
199
168
  "data-num": "0",
200
169
  onclick() {
201
- const num = Number(this.getAttribute("data-num")) + 1;
202
- this.updateState({ text: num, $num: num });
170
+ const num = this.getAttribute("data-num") * 1 + 1;
171
+ this.updateState({ text: num, "data-num": num });
203
172
  },
204
173
  });
205
174
  }
206
175
 
207
- function HelloMessage(name = "no name") {
208
- return _("div.foo#bar", {
176
+ // hello message
177
+
178
+ function HelloMessage() {
179
+ return div({
209
180
  shouldUpdate: true,
210
- text: "hello " + name,
181
+ text: "Click to get a greeting",
211
182
  onclick() {
212
183
  const name = prompt("what are your names");
213
- this.updateState({ text: "hello " + name });
184
+ this.updateState({
185
+ text: name ? "hello " + name : "Click to get a greeting",
186
+ });
214
187
  },
215
188
  });
216
189
  }
217
190
 
218
- const nameRef = new Ref(function ( name ) {
191
+ // using cradova Ref
192
+
193
+ const nameRef = new Ref(function (name) {
219
194
  const self = this;
220
195
  return _("div.foo#bar", {
221
- text: "hello" + (name || "no name"),
196
+ text: name
197
+ ? "hello " + (name || " user 2")
198
+ : "Click to get a second greeting",
222
199
  onclick() {
223
200
  const name = prompt();
224
201
  self.updateState(name);
@@ -226,62 +203,251 @@ const nameRef = new Ref(function ( name ) {
226
203
  });
227
204
  });
228
205
 
229
- /*
230
- cradova Ref are component objects
231
- with methods for rendering, pre-rendering, and updating a it dom elements.
206
+ function App() {
207
+ return div(counter, dataCounter, HelloMessage, br, nameRef);
208
+ }
232
209
 
233
- Ref also has the feature to stash input values need by the components
210
+ // add your app to the DOM
234
211
 
235
- */
212
+ document.body.append(App());
213
+ ```
214
+
215
+ ## Simple Todo list
216
+
217
+ Let's see a simple TodoList example
218
+
219
+ ```js
220
+ import _, {
221
+ button,
222
+ createSignal,
223
+ css,
224
+ div,
225
+ input,
226
+ main,
227
+ p,
228
+ Ref,
229
+ reference,
230
+ } from "../dist/index.js";
231
+
232
+ function TodoList() {
233
+ // can be used to hold multiple references
234
+ const referenceSet = new reference();
235
+
236
+ // creating a store
237
+ const todoStore = new createSignal([
238
+ "take bath",
239
+ "code code code",
240
+ "take a break",
241
+ ]);
242
+
243
+ // create actions
244
+ todoStore.createAction("add-todo", function (todo) {
245
+ this.set([...this.value, todo]);
246
+ });
236
247
 
248
+ todoStore.createAction("remove-todo", function (todo) {
249
+ const ind = this.value.indexOf(todo);
250
+ this.value.splice(ind, 1);
251
+ this.set(this.value);
252
+ });
237
253
 
238
- function Home() {
239
- return _("div.foo#bar",
240
- counter,
241
- dataCounter,
242
- HelloMessage,
243
- nameRef.render( "no name" )
254
+ // bind Ref to Signal
255
+ todoStore.bindRef(todoList);
256
+
257
+ // markup
258
+ return main(
259
+ _`|Todo List`,
260
+ div(
261
+ input({
262
+ placeholder: "type in todo",
263
+ reference: referenceSet.bindAs("todoInput"),
264
+ }),
265
+ button("Add todo", {
266
+ onclick() {
267
+ todoStore.fireAction("add-todo", referenceSet.todoInput.value);
268
+ referenceSet.todoInput.value = "";
269
+ },
270
+ })
271
+ ),
272
+ todoList.render
244
273
  );
245
274
  }
246
275
 
276
+ const todoList = new Ref(function () {
277
+ const self = this;
278
+ return div(
279
+ self.Signal.value.map((item) =>
280
+ p(item, {
281
+ title: "click to remove",
282
+ onclick() {
283
+ self.Signal.fireAction("remove-todo", item);
284
+ },
285
+ })
286
+ )
287
+ );
288
+ });
289
+
290
+ document.body.appendChild(TodoList());
291
+
292
+ css`
293
+ body {
294
+ box-sizing: border-box;
295
+ display: flex;
296
+ }
297
+ main {
298
+ margin: auto;
299
+ }
300
+ main > p {
301
+ font-size: 2rem;
302
+ }
303
+ `;
304
+ ```
305
+
306
+ ## working with screen and Router:
307
+
308
+ unlike just appending stuff to the DOM,
309
+ a better to build apps is to use a routing system.
310
+
311
+ Cradova Router is a module that allows you do the following:
312
+
313
+ Create specified routes in you application
314
+ help you orchestrate navigation
315
+ render a screen on a route
316
+ pre-render a screen in the background if you want to.
317
+ listen to Navigation changes
318
+ create error boundary at screen level.
319
+ persist rendered screens by default
320
+ allow parallel screen rendering for every unique route scheme
321
+
322
+ let's try an example.
323
+
324
+ ```js
325
+ import _, { Screen, Router } from "cradova";
326
+
327
+ // Ref can be used as screens
328
+
329
+ const template = new Ref(function (name) {
330
+ // an effect run once after screen renders
331
+ const self = this;
332
+ self.effect(() => {
333
+ const name = new Promise((res) => {
334
+ res("john doe");
335
+ });
336
+ setTimeout(async () => {
337
+ self.updateState(await name);
338
+ }, 1000);
339
+ });
340
+ // effects can be used to make api calls needed for the page
341
+ return _("div", name ? ">>>>>>>> Hello " + name : " loading...");
342
+ });
343
+
247
344
  const home = new Screen({
248
345
  name: "home page", // page title
249
- template: Home,
250
- ...
346
+ template,
347
+ });
348
+
349
+ // in your routes.ts file
350
+ Router.BrowserRoutes({
351
+ "/home": home,
352
+ "/lazy-loaded-home": async () => await import("./home"),
251
353
  });
354
+ // creates these routes
252
355
 
253
- /*
356
+ Router.packageScreen("/home", data);
357
+ // get the page ready in the background
358
+
359
+ Router.navigate("/home", data);
360
+ // navigates to that page
254
361
 
255
- Nice things about cradova screens
362
+ Router.getParams();
363
+ // get route params for this current page
364
+
365
+ Router.onPageEvent((lastRoute, newRoute) => {
366
+ console.log(lastRoute, newRoute);
367
+ });
368
+ // listen for navigation changes
369
+ ```
370
+
371
+ ### More info
372
+
373
+ ---
374
+
375
+ More info on cradova Router
376
+
377
+ ---
378
+
379
+ Every cradova app mounts on a div with attribute data-wrapper="app"
380
+
381
+ if it already exist cradova will use it instead.
382
+
383
+ cradova will create a div with data-wrapper="app" if it doesn't exists already.
384
+
385
+ so if you want to use your own mount point then create a div with data-wrapper="app".
386
+
387
+ ---
388
+
389
+ More info on cradova screens
390
+
391
+ ---
256
392
 
257
393
  screens are rendered once by default to hack
258
394
  responsiveness making your app work fast as user navigates.
259
395
 
260
396
  this behavior can be override
261
397
  by passing
262
- prerender: false
398
+ persist: false
263
399
  in the constructor
264
400
 
265
-
266
401
  Cradova screens has
267
402
  onActivate() and
268
- onDeactivate() methods
403
+ onDeactivate() methods which is also available in the
404
+ component function on the this variable bound to it.
269
405
 
270
- these allow you manage rendering
271
- circle for each in your app
406
+ this allow you manage rendering
407
+ circle for each screen in your app
272
408
 
273
- */
409
+ ---
274
410
 
275
- Router.route("/", home);
276
- ```
411
+ More info on cradova Ref
412
+
413
+ ---
414
+
415
+ Refs are dynamic components, they have simple abstractions like:
416
+
417
+ - Effects
418
+ - stash
419
+ - preRender
420
+ - updateState
421
+
422
+ these behaviors allow you manage rendering
423
+ circle for refs in your app
424
+
425
+ ---
426
+
427
+ More info on cradova createSignal
428
+
429
+ ---
430
+
431
+ Cradova Signals allows you to create powerful data stores.
432
+
433
+ with ability to:
434
+
435
+ - create store
436
+ - create actions and fire them
437
+ - bind a Ref
438
+ - listen to changes
439
+ - persist changes to localStorage
440
+ - update a cradova Ref and bindings automatically
441
+
442
+ With these simple and easy abstractions, you can use datastores with powerful convenience.
277
443
 
278
444
  ## Documentation
279
445
 
280
- At the moment, we're in the process of creating documentation for Cradova, and we have limited resources. If you're interested in lending a hand, we invite you to join our community, gain firsthand experience, and contribute to the advancement of Cradova.
446
+ At the moment, we're in the process of creating a documentation website for Cradova, and we have limited resources. If you're interested in lending a hand, we invite you to join our community, gain firsthand experience, and contribute to the advancement of Cradova.
281
447
 
282
448
  ## Getting Help
283
449
 
284
- To get further insights and help on Cradova, visit our new [Telegram Community Chat](https://t.me/cradovaframework).
450
+ To get further insights and help on Cradova, visit our [Discord](https://discord.gg/b7fvMg38) and [Telegram](https://t.me/cradovaframework) Community Chats.
285
451
 
286
452
  ## Contributing
287
453