create-gardener 1.1.2 → 1.1.4

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
@@ -63,7 +63,10 @@ src/
63
63
  │ ├── assets/ # original images
64
64
  │ ├── components/
65
65
  │ ├── gardener.js
66
- └── styles/
66
+ ├── styles/
67
+ │ └── frontendtemplate.ejs #starter file to create new page
68
+
69
+
67
70
 
68
71
  ├── frontendStatic/ # final static output (generated)
69
72
  └── tempfrontend/ # temporary build output (deleted after build)
@@ -103,12 +106,8 @@ pnpm run dev
103
106
  ## Image Optimization & Caching
104
107
 
105
108
  Gardener provides a **deterministic image optimization endpoint**.
109
+ put your images in ./src/frontend/assets and use /cache/[imagename]_[width]x[height].webp in img tag.
106
110
 
107
- ### Route
108
-
109
- ```
110
- GET /cache/:name
111
- ```
112
111
 
113
112
  ### Filename format
114
113
 
@@ -308,6 +307,7 @@ Creates an EJS page and registers a route.
308
307
 
309
308
  ⚠️ **Important**
310
309
 
310
+ * Gardener doesn't support <span>hi<span>rohan</span></span> use <span><span>hi</span><span>rohan</span></span> basically text node elements shouldn't have siblings.
311
311
  * `/addcomponent` and `/addpage` mutate files and routes
312
312
  * Intended for **local development only**
313
313
  * Do NOT expose publicly without authentication and sanitization
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "type": "git",
6
6
  "url": "https://github.com/ritishDas/gardener"
7
7
  },
8
- "version": "1.1.2",
8
+ "version": "1.1.4",
9
9
  "description": "A dom gardener converting dom elements into json and vice versa",
10
10
  "main": "index.js",
11
11
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-gardener",
3
- "version": "1.0.0",
3
+ "version": "1.1.4",
4
4
  "description": "A dom gardener converting dom elements into json and vice versa",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -17,3 +17,4 @@ router.route('/addpage').post(addPage);
17
17
 
18
18
 
19
19
  router.route('/').get((req, res) => res.render('_'));
20
+ router.route('/login').get((req, res) => res.render('_login'));
@@ -0,0 +1,55 @@
1
+
2
+ import { gardener, fetchElement, replaceElement } from '../gardener.js'
3
+
4
+ export default function thisfun() {
5
+ return gardener({
6
+ "t": "span",
7
+ "cn": [
8
+ "emailsvg"
9
+ ],
10
+ "children": [
11
+ {
12
+ "t": "svg",
13
+ "cn": [
14
+ "icon",
15
+ "icon-tabler",
16
+ "icons-tabler-outline",
17
+ "icon-tabler-mail"
18
+ ],
19
+ "attr": {
20
+ "xmlns": "http://www.w3.org/2000/svg",
21
+ "width": "24",
22
+ "height": "24",
23
+ "viewBox": "0 0 24 24",
24
+ "fill": "none",
25
+ "stroke": "currentColor",
26
+ "stroke-width": "2",
27
+ "stroke-linecap": "round",
28
+ "stroke-linejoin": "round"
29
+ },
30
+ "children": [
31
+ {
32
+ "t": "path",
33
+ "attr": {
34
+ "stroke": "none",
35
+ "d": "M0 0h24v24H0z",
36
+ "fill": "none"
37
+ }
38
+ },
39
+ {
40
+ "t": "path",
41
+ "attr": {
42
+ "d": "M3 7a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2v-10"
43
+ }
44
+ },
45
+ {
46
+ "t": "path",
47
+ "attr": {
48
+ "d": "M3 7l9 6l9 -6"
49
+ }
50
+ }
51
+ ]
52
+ }
53
+ ]
54
+ })
55
+ }
@@ -0,0 +1,50 @@
1
+
2
+ import { gardener } from '../gardener.js'
3
+
4
+ export default function () {
5
+ return gardener({
6
+ "t": "svg",
7
+ "cn": [
8
+ "eye"
9
+ ],
10
+ "attr": {
11
+ "xmlns": "http://www.w3.org/2000/svg",
12
+ "width": "24",
13
+ "height": "24",
14
+ "viewBox": "0 0 24 24",
15
+ "fill": "none",
16
+ "stroke": "currentColor",
17
+ "stroke-width": "2",
18
+ "stroke-linecap": "round",
19
+ "stroke-linejoin": "round"
20
+ },
21
+ "children": [
22
+ {
23
+ "t": "path",
24
+ "attr": {
25
+ "stroke": "none",
26
+ "d": "M0 0h24v24H0z",
27
+ "fill": "none"
28
+ }
29
+ },
30
+ {
31
+ "t": "path",
32
+ "attr": {
33
+ "d": "M10.585 10.587a2 2 0 0 0 2.829 2.828"
34
+ }
35
+ },
36
+ {
37
+ "t": "path",
38
+ "attr": {
39
+ "d": "M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87"
40
+ }
41
+ },
42
+ {
43
+ "t": "path",
44
+ "attr": {
45
+ "d": "M3 3l18 18"
46
+ }
47
+ }
48
+ ]
49
+ })
50
+ }
@@ -0,0 +1,44 @@
1
+
2
+ import { gardener } from '../gardener.js'
3
+
4
+ export default function () {
5
+ return gardener({
6
+ "t": "svg",
7
+ "cn": [
8
+ "eye"
9
+ ],
10
+ "attr": {
11
+ "xmlns": "http://www.w3.org/2000/svg",
12
+ "width": "24",
13
+ "height": "24",
14
+ "viewBox": "0 0 24 24",
15
+ "fill": "none",
16
+ "stroke": "currentColor",
17
+ "stroke-width": "2",
18
+ "stroke-linecap": "round",
19
+ "stroke-linejoin": "round"
20
+ },
21
+ "children": [
22
+ {
23
+ "t": "path",
24
+ "attr": {
25
+ "stroke": "none",
26
+ "d": "M0 0h24v24H0z",
27
+ "fill": "none"
28
+ }
29
+ },
30
+ {
31
+ "t": "path",
32
+ "attr": {
33
+ "d": "M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"
34
+ }
35
+ },
36
+ {
37
+ "t": "path",
38
+ "attr": {
39
+ "d": "M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6"
40
+ }
41
+ }
42
+ ]
43
+ })
44
+ }
@@ -0,0 +1,22 @@
1
+ async function postFetch(path, body) {
2
+ try {
3
+ const data = await fetch(path, {
4
+ credentials: 'include',
5
+ method: 'POST',
6
+ headers: {
7
+ 'Content-Type': 'application/json'
8
+ },
9
+ body: JSON.stringify(body)
10
+ });
11
+
12
+ return await data.json();
13
+ }
14
+ catch (err) {
15
+ console.error('error while requesting', err);
16
+ }
17
+ }
18
+
19
+ export async function userlogin(email, password) {
20
+ const result = await postFetch('/login', { email, password });
21
+ console.log(result);
22
+ }
@@ -0,0 +1,67 @@
1
+ import { gardener, replaceElement, fetchElement } from '/gardener.js';
2
+
3
+ export default function addNotification(noti) {
4
+ console.log('clicked');
5
+ replaceElement(fetchElement('.notification'), Notification(noti));
6
+ }
7
+
8
+ function Notification(notification) {
9
+ if (!notification) return null;
10
+
11
+ const statusStyles = {
12
+ success: "bg-[#2e7d32]",
13
+ warning: "bg-[#ed6c02]",
14
+ failure: "bg-[#d32f2f]",
15
+ };
16
+
17
+
18
+ return gardener({
19
+ "t": "div",
20
+ "cn": [
21
+ "notification",
22
+ "fixed",
23
+ "top-[-60px]",
24
+ "left-0",
25
+ "md:left-auto",
26
+ "md:right-[60px]",
27
+ "right-0",
28
+ "z-50",
29
+ "flex",
30
+ "justify-center",
31
+ "min-w-100",
32
+ "px-4",
33
+ "box-border"
34
+ ],
35
+ "children": [
36
+ {
37
+ "t": "div",
38
+ "cn": [
39
+ "flex",
40
+ "items-center",
41
+ "w-full",
42
+ "max-w-sm",
43
+ "p-4",
44
+ "rounded-2xl",
45
+ "shadow-xl",
46
+ "text-white",
47
+ "backdrop-blur-md",
48
+ "bg-opacity-95",
49
+ statusStyles[notification.status]
50
+ ],
51
+ "children": [
52
+ {
53
+ "t": "div",
54
+ "cn": [
55
+ "flex-1",
56
+ "text-sm",
57
+ "font-medium",
58
+ "tracking-wide"
59
+ ],
60
+ "txt": notification.message
61
+ }
62
+ ]
63
+ }
64
+ ]
65
+ });
66
+ }
67
+
@@ -0,0 +1,105 @@
1
+ import { gardener, replaceElement, fetchElement } from '/gardener.js'
2
+ import eyeoff from '/components/eyeoff.js'
3
+ import eyeon from '/components/eyeon.js'
4
+ export default function thisfun(visible) {
5
+
6
+ const svg = visible ? eyeoff() : eyeon();
7
+
8
+ return gardener({
9
+ "t": "div",
10
+ "cn": [
11
+ "w-full",
12
+ "passwordbox"
13
+ ],
14
+ "children": [
15
+ {
16
+ "t": "label",
17
+ "cn": [
18
+ "my-1",
19
+ "block"
20
+ ],
21
+ "txt": "Password"
22
+ },
23
+ {
24
+ "t": "span",
25
+ "cn": [
26
+ "border",
27
+ "border-gray-900",
28
+ "flex",
29
+ "space-x-1",
30
+ "items-center",
31
+ "h-8",
32
+ "p-1",
33
+ "rounded-md"
34
+ ],
35
+ "children": [
36
+ {
37
+ "t": "svg",
38
+ "cn": [
39
+ "icon",
40
+ "icon-tabler",
41
+ "icons-tabler-outline",
42
+ "icon-tabler-key"
43
+ ],
44
+ "attr": {
45
+ "xmlns": "http://www.w3.org/2000/svg",
46
+ "width": "24",
47
+ "height": "24",
48
+ "viewBox": "0 0 24 24",
49
+ "fill": "none",
50
+ "stroke": "currentColor",
51
+ "stroke-width": "2",
52
+ "stroke-linecap": "round",
53
+ "stroke-linejoin": "round"
54
+ },
55
+ "children": [
56
+ {
57
+ "t": "path",
58
+ "attr": {
59
+ "stroke": "none",
60
+ "d": "M0 0h24v24H0z",
61
+ "fill": "none"
62
+ }
63
+ },
64
+ {
65
+ "t": "path",
66
+ "attr": {
67
+ "d": "M16.555 3.843l3.602 3.602a2.877 2.877 0 0 1 0 4.069l-2.643 2.643a2.877 2.877 0 0 1 -4.069 0l-.301 -.301l-6.558 6.558a2 2 0 0 1 -1.239 .578l-.175 .008h-1.172a1 1 0 0 1 -.993 -.883l-.007 -.117v-1.172a2 2 0 0 1 .467 -1.284l.119 -.13l.414 -.414h2v-2h2v-2l2.144 -2.144l-.301 -.301a2.877 2.877 0 0 1 0 -4.069l2.643 -2.643a2.877 2.877 0 0 1 4.069 0"
68
+ }
69
+ },
70
+ {
71
+ "t": "path",
72
+ "attr": {
73
+ "d": "M15 9h.01"
74
+ }
75
+ }
76
+ ]
77
+ },
78
+ {
79
+ "t": "input",
80
+ "cn": [
81
+ "outline-none",
82
+ "inputbox",
83
+ "w-full"
84
+ ],
85
+ "attr": {
86
+ "type": visible ? 'text' : 'password',
87
+ "name": "password",
88
+ value: fetchElement('.inputbox').value,
89
+ "required": "",
90
+ }
91
+ },
92
+ {
93
+ t: 'span',
94
+ events: {
95
+ click: () => replaceElement(fetchElement(".passwordbox"), thisfun(!visible)),
96
+ },
97
+ children: [
98
+ svg
99
+ ]
100
+ }
101
+ ]
102
+ },
103
+ ]
104
+ })
105
+ }
@@ -4,23 +4,30 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <link rel="stylesheet" href="/style.css">
7
- <title>Gardener</title>
7
+ <link rel="stylesheet" href="/style2.css">
8
+ <title>Redvent:Login</title>
8
9
  </head>
9
10
  <body>
10
- <div id='body'>
11
+ <div class='notification'></div>
12
+ <div class="bg-gray-200 w-screen h-screen flex justify-center items-center" id='body'>
11
13
  <%- include('partials/loader') %>
14
+
15
+ <!-- Main Content-->
16
+
17
+
12
18
  <div class="hero flex justify-around items-center p-5 h-[90vh]">
13
19
  <p class='p-5'>
14
20
  Gardener is a front-end library for creating and manipulating DOM elements using a declarative JavaScript object syntax. It includes a development server with features like hot-reloading and on-the-fly component creation from existing HTML. The server also provides dynamic image resizing and caching.
15
21
  </p>
16
22
  <img src="/cache/w_500x500.webp" alt="logo" class="w-500">
17
23
  </div>
18
-
19
24
  </div>
20
25
  <script src='/global.js' type="module"></script>
21
- <script type="module">
26
+ <script type="module">
22
27
 
23
- </script>
28
+ import { parser, fetchElement, replaceElement, appendElement } from "/gardener.js";
29
+ </script>
24
30
  </body>
25
31
  </html>
26
32
 
33
+
@@ -333,10 +333,7 @@ export function gardener(Dom) {
333
333
 
334
334
  export function parser(element, isParent = true) {
335
335
  if (typeof element === 'string') {
336
- // If user passes raw HTML string
337
- const temp = document.createElement('div');
338
- temp.innerHTML = element.trim();
339
- element = temp.firstElementChild;
336
+ element = fetchElement(element);
340
337
  }
341
338
 
342
339
  const obj = {
@@ -0,0 +1 @@
1
+ /* your custom styles */
@@ -9,8 +9,11 @@
9
9
  <link href="/style.css" rel="stylesheet"/>
10
10
  </head>
11
11
 
12
- <body class="bg-slate-50 text-slate-900 antialiased">
12
+ <body>
13
13
 
14
+ <div id='body'>
15
+
16
+ <%- include('partials/loader') %>
14
17
  <div class="max-w-7xl mx-auto px-6 py-12 space-y-20">
15
18
 
16
19
  <!-- Hero / Introduction -->
@@ -32,6 +35,8 @@
32
35
  class="w-64 lg:w-80 rounded-2xl shadow-2xl"
33
36
  />
34
37
  </div>
38
+
39
+ <a href="/login" class='p-3 rounded-md bg-blue-400 inline-block'>Check A Demo Login Page</a>
35
40
  </section>
36
41
 
37
42
  <!-- Design Philosophy -->
@@ -212,5 +217,8 @@ replaceElement(
212
217
  import { parser, fetchElement } from "/gardener.js";
213
218
  // parser(fetchElement("#some-selector")); // uncomment when needed
214
219
  </script>
220
+ <div>
221
+
215
222
  </body>
216
223
  </html>
224
+
@@ -0,0 +1,73 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <link rel="stylesheet" href="/style.css">
7
+ <link rel="stylesheet" href="/style2.css">
8
+ <title>Redvent:Login</title>
9
+ </head>
10
+ <body>
11
+ <div class='notification'></div>
12
+ <div class="bg-gray-200 w-screen h-screen flex justify-center items-center" id='body'>
13
+
14
+ <%- include('partials/loader') %>
15
+ <div class="bg-white rounded-xl w-90 min-h-100 flex items-center flex-col">
16
+
17
+ <h1 class="text-center text-4xl p-5">Login</h1>
18
+ <form class="w-3/4 flex flex-col space-y-5 loginform" >
19
+
20
+ <div>
21
+
22
+ <label class="my-1 block">Email</label>
23
+ <span class="border border-gray-900 flex space-x-1 items-center h-8 p-1 rounded-md">
24
+ <span class='emailsvg'> </span>
25
+ <input type="email" class="outline-none w-full" name="email" required>
26
+ </span>
27
+ </div>
28
+
29
+
30
+ <div class="w-full">
31
+ <div class="passwordbox">
32
+ <input class='inputbox' value=""/>
33
+ </div>
34
+ <a href='/forgotpass' class="text-right block text-sm text-blue-800 mt-3">Forgot Password?</a>
35
+ </div>
36
+
37
+
38
+ <button type="submit" class="w-full bg-green-200 rounded-xl p-2 mt-5 hover:bg-green-300 hover:cursor-pointer transition-all">Submit</button>
39
+ </form>
40
+
41
+ </div>
42
+ </div>
43
+ <script src='/global.js' type="module"></script>
44
+ <script type="module">
45
+
46
+ import { parser, fetchElement, replaceElement, appendElement } from "/gardener.js";
47
+ import addNotification from "/components/notification.js";
48
+ import emailsvg from '/components/emailsvg.js';
49
+ import passwordbox from "/components/passwordBox.js";
50
+ import { userlogin } from "/components/nonui/api.js";
51
+
52
+ // mount password input
53
+ replaceElement(fetchElement(".passwordbox"), passwordbox(false));
54
+
55
+
56
+ fetchElement(".loginform").addEventListener("submit", async (e) => {
57
+ e.preventDefault();
58
+
59
+ const formdata = new FormData(e.target);
60
+ const result = Object.fromEntries(formdata);
61
+
62
+
63
+ const { email, password } = result;
64
+ await userlogin(email, password);
65
+
66
+ addNotification({status:'success',message:'Login SuccessFull'})
67
+ });
68
+
69
+ replaceElement(fetchElement('.emailsvg'),emailsvg());
70
+ </script>
71
+ </body>
72
+ </html>
73
+
@@ -1,54 +0,0 @@
1
-
2
- import { gardener, fetchElement, replaceElement } from '../gardener.js'
3
-
4
- export default function thisfun() {
5
- return gardener({
6
- "t": "div",
7
- "attr": {
8
- "id": "body"
9
- },
10
- "children": [
11
- {
12
- "t": "div",
13
- "cn": [
14
- "h-screen",
15
- "w-screen",
16
- "bg-white",
17
- "loader",
18
- "absolute"
19
- ],
20
- "attr": {
21
- "style": "transition: 0.4s; opacity: 0;"
22
- },
23
- "txt": ""
24
- },
25
- {
26
- "t": "div",
27
- "cn": [
28
- "hero",
29
- "flex",
30
- "justify-around",
31
- "items-center",
32
- "p-5",
33
- "h-[90vh]"
34
- ],
35
- "children": [
36
- {
37
- "t": "p",
38
- "cn": [
39
- "p-5"
40
- ],
41
- "txt": "Gardener is a front-end library for creating and manipulating DOM elements using a declarative JavaScript object syntax. It includes a development server with features like timely reload and on-the-fly component creation from existing HTML. The server also provides dynamic image resizing and caching."
42
- },
43
- {
44
- "t": "img",
45
- "attr": {
46
- "src": "/cache/gardener_500x500.webp",
47
- "alt": "logo"
48
- }
49
- }
50
- ]
51
- }
52
- ]
53
- })
54
- }