create-gardener 2.0.6 → 2.0.8
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 +187 -0
- package/package.json +1 -1
- package/template/buildHelper.js +5 -4
- package/template/buildHelper.test.js +78 -0
- package/template/jest.config.js +13 -0
- package/template/package.json +4 -1
- package/template/pnpm-lock.yaml +2761 -17
- package/template/src/backend/controllers/gardener/addPage.ts +3 -3
- package/template/src/backend/routes/gardener.route.ts +1 -1
- package/template/src/frontend/static/gardener.test.js +364 -0
- package/template/src/frontend/static/gardenerDev.js +4 -7
- package/template/src/frontend/static/style.css +21 -32
- package/template/src/frontend/template/template._.ejs +1 -0
- package/template/src/frontend/views/_.ejs +1 -0
- /package/{Readme.md → Readme.deprecated.md} +0 -0
|
@@ -41,12 +41,12 @@ async function findTemplate(fileName: string) {
|
|
|
41
41
|
|
|
42
42
|
export async function addPage(req: Request, res: Response) {
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
45
|
-
const name = pagename.replaceAll('/', '_');
|
|
44
|
+
const name: string = req.body.page;
|
|
45
|
+
// const name = pagename.replaceAll('/', '_');
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
const templatePath = await findTemplate(name);//path.join(frontendDir, findTemplate(name)); //path.join(frontendDir, 'frontendtemplate.ejs');
|
|
49
|
+
const templatePath = await findTemplate(name + '.ejs');//path.join(frontendDir, findTemplate(name)); //path.join(frontendDir, 'frontendtemplate.ejs');
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, test, expect, beforeEach, jest } from '@jest/globals';
|
|
6
|
+
import {
|
|
7
|
+
fetchElement,
|
|
8
|
+
appendElement,
|
|
9
|
+
createElement,
|
|
10
|
+
insertText,
|
|
11
|
+
replaceElement,
|
|
12
|
+
gardener
|
|
13
|
+
} from './gardener.js';
|
|
14
|
+
|
|
15
|
+
describe('fetchElement', () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
document.body.innerHTML = '';
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('should fetch element by query selector', () => {
|
|
21
|
+
document.body.innerHTML = '<div class="test-class"></div>';
|
|
22
|
+
const element = fetchElement('.test-class');
|
|
23
|
+
expect(element).toBeTruthy();
|
|
24
|
+
expect(element.className).toBe('test-class');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('should return null for non-existent element', () => {
|
|
28
|
+
const element = fetchElement('.non-existent');
|
|
29
|
+
expect(element).toBeNull();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('should fetch element by id', () => {
|
|
33
|
+
document.body.innerHTML = '<div id="test-id"></div>';
|
|
34
|
+
const element = fetchElement('#test-id');
|
|
35
|
+
expect(element).toBeTruthy();
|
|
36
|
+
expect(element.id).toBe('test-id');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('appendElement', () => {
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
document.body.innerHTML = '';
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('should append child to parent element', () => {
|
|
46
|
+
const parent = document.createElement('div');
|
|
47
|
+
const child = document.createElement('span');
|
|
48
|
+
document.body.appendChild(parent);
|
|
49
|
+
|
|
50
|
+
appendElement(parent, child);
|
|
51
|
+
expect(parent.children.length).toBe(1);
|
|
52
|
+
expect(parent.firstChild).toBe(child);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test('should append child using parent selector string', () => {
|
|
56
|
+
document.body.innerHTML = '<div class="parent"></div>';
|
|
57
|
+
const child = document.createElement('span');
|
|
58
|
+
|
|
59
|
+
appendElement('.parent', child);
|
|
60
|
+
const parent = document.querySelector('.parent');
|
|
61
|
+
expect(parent.children.length).toBe(1);
|
|
62
|
+
expect(parent.firstChild).toBe(child);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('should append multiple children', () => {
|
|
66
|
+
const parent = document.createElement('div');
|
|
67
|
+
const child1 = document.createElement('span');
|
|
68
|
+
const child2 = document.createElement('p');
|
|
69
|
+
|
|
70
|
+
appendElement(parent, child1);
|
|
71
|
+
appendElement(parent, child2);
|
|
72
|
+
|
|
73
|
+
expect(parent.children.length).toBe(2);
|
|
74
|
+
expect(parent.children[0]).toBe(child1);
|
|
75
|
+
expect(parent.children[1]).toBe(child2);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('createElement', () => {
|
|
80
|
+
test('should create element with given type', () => {
|
|
81
|
+
const element = createElement('div');
|
|
82
|
+
expect(element.tagName).toBe('DIV');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('should create element with single class', () => {
|
|
86
|
+
const element = createElement('div', ['test-class']);
|
|
87
|
+
expect(element.classList.contains('test-class')).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('should create element with multiple classes', () => {
|
|
91
|
+
const element = createElement('span', ['class1', 'class2', 'class3']);
|
|
92
|
+
expect(element.classList.contains('class1')).toBe(true);
|
|
93
|
+
expect(element.classList.contains('class2')).toBe(true);
|
|
94
|
+
expect(element.classList.contains('class3')).toBe(true);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('should create element without class if not provided', () => {
|
|
98
|
+
const element = createElement('p');
|
|
99
|
+
expect(element.className).toBe('');
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('insertText', () => {
|
|
104
|
+
test('should insert text into element', () => {
|
|
105
|
+
const element = document.createElement('div');
|
|
106
|
+
insertText(element, 'Hello World');
|
|
107
|
+
expect(element.innerText).toBe('Hello World');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('should replace existing text', () => {
|
|
111
|
+
const element = document.createElement('div');
|
|
112
|
+
element.innerText = 'Old Text';
|
|
113
|
+
insertText(element, 'New Text');
|
|
114
|
+
expect(element.innerText).toBe('New Text');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('should handle empty string', () => {
|
|
118
|
+
const element = document.createElement('div');
|
|
119
|
+
insertText(element, '');
|
|
120
|
+
expect(element.innerText).toBe('');
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe('replaceElement', () => {
|
|
125
|
+
beforeEach(() => {
|
|
126
|
+
document.body.innerHTML = '';
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('should replace element with another element', () => {
|
|
130
|
+
const original = document.createElement('div');
|
|
131
|
+
original.id = 'original';
|
|
132
|
+
const replacement = document.createElement('span');
|
|
133
|
+
replacement.id = 'replacement';
|
|
134
|
+
document.body.appendChild(original);
|
|
135
|
+
|
|
136
|
+
replaceElement(original, replacement);
|
|
137
|
+
expect(document.getElementById('original')).toBeNull();
|
|
138
|
+
expect(document.getElementById('replacement')).toBeTruthy();
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
test('should replace element using selector string', () => {
|
|
142
|
+
document.body.innerHTML = '<div class="original"></div>';
|
|
143
|
+
const replacement = document.createElement('span');
|
|
144
|
+
replacement.className = 'replacement';
|
|
145
|
+
|
|
146
|
+
replaceElement('.original', replacement);
|
|
147
|
+
expect(document.querySelector('.original')).toBeNull();
|
|
148
|
+
expect(document.querySelector('.replacement')).toBeTruthy();
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe('gardener', () => {
|
|
153
|
+
beforeEach(() => {
|
|
154
|
+
document.body.innerHTML = '';
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test('should return DOM element if nodeType is 1', () => {
|
|
158
|
+
const element = document.createElement('div');
|
|
159
|
+
const result = gardener(element);
|
|
160
|
+
expect(result).toBe(element);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('should create simple element', () => {
|
|
164
|
+
const dom = { t: 'div' };
|
|
165
|
+
const element = gardener(dom);
|
|
166
|
+
expect(element.tagName).toBe('DIV');
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('should create element with classes', () => {
|
|
170
|
+
const dom = { t: 'div', cn: ['class1', 'class2'] };
|
|
171
|
+
const element = gardener(dom);
|
|
172
|
+
expect(element.classList.contains('class1')).toBe(true);
|
|
173
|
+
expect(element.classList.contains('class2')).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('should create element with text content', () => {
|
|
177
|
+
const dom = { t: 'p', txt: 'Hello World' };
|
|
178
|
+
const element = gardener(dom);
|
|
179
|
+
expect(element.innerText).toBe('Hello World');
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test('should create element with attributes', () => {
|
|
183
|
+
const dom = {
|
|
184
|
+
t: 'input',
|
|
185
|
+
attr: { type: 'text', placeholder: 'Enter text', id: 'test-input' }
|
|
186
|
+
};
|
|
187
|
+
const element = gardener(dom);
|
|
188
|
+
expect(element.getAttribute('type')).toBe('text');
|
|
189
|
+
expect(element.getAttribute('placeholder')).toBe('Enter text');
|
|
190
|
+
expect(element.id).toBe('test-input');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('should create element with data attributes', () => {
|
|
194
|
+
const dom = {
|
|
195
|
+
t: 'div',
|
|
196
|
+
attr: { 'data-test': 'value', 'data-id': '123' }
|
|
197
|
+
};
|
|
198
|
+
const element = gardener(dom);
|
|
199
|
+
expect(element.getAttribute('data-test')).toBe('value');
|
|
200
|
+
expect(element.getAttribute('data-id')).toBe('123');
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test('should create element with aria attributes', () => {
|
|
204
|
+
const dom = {
|
|
205
|
+
t: 'button',
|
|
206
|
+
attr: { 'aria-label': 'Close', 'aria-expanded': 'false' }
|
|
207
|
+
};
|
|
208
|
+
const element = gardener(dom);
|
|
209
|
+
expect(element.getAttribute('aria-label')).toBe('Close');
|
|
210
|
+
expect(element.getAttribute('aria-expanded')).toBe('false');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
test('should create element with event listeners', () => {
|
|
214
|
+
const mockHandler = jest.fn();
|
|
215
|
+
const dom = {
|
|
216
|
+
t: 'button',
|
|
217
|
+
events: { click: mockHandler }
|
|
218
|
+
};
|
|
219
|
+
const element = gardener(dom);
|
|
220
|
+
element.click();
|
|
221
|
+
expect(mockHandler).toHaveBeenCalledTimes(1);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test('should create element with multiple event listeners', () => {
|
|
225
|
+
const clickHandler = jest.fn();
|
|
226
|
+
const mouseoverHandler = jest.fn();
|
|
227
|
+
const dom = {
|
|
228
|
+
t: 'div',
|
|
229
|
+
events: { click: clickHandler, mouseover: mouseoverHandler }
|
|
230
|
+
};
|
|
231
|
+
const element = gardener(dom);
|
|
232
|
+
|
|
233
|
+
element.click();
|
|
234
|
+
element.dispatchEvent(new Event('mouseover'));
|
|
235
|
+
|
|
236
|
+
expect(clickHandler).toHaveBeenCalledTimes(1);
|
|
237
|
+
expect(mouseoverHandler).toHaveBeenCalledTimes(1);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('should create nested elements', () => {
|
|
241
|
+
const dom = {
|
|
242
|
+
t: 'div',
|
|
243
|
+
children: [
|
|
244
|
+
{ t: 'span', txt: 'Child 1' },
|
|
245
|
+
{ t: 'p', txt: 'Child 2' }
|
|
246
|
+
]
|
|
247
|
+
};
|
|
248
|
+
const element = gardener(dom);
|
|
249
|
+
expect(element.children.length).toBe(2);
|
|
250
|
+
expect(element.children[0].tagName).toBe('SPAN');
|
|
251
|
+
expect(element.children[0].innerText).toBe('Child 1');
|
|
252
|
+
expect(element.children[1].tagName).toBe('P');
|
|
253
|
+
expect(element.children[1].innerText).toBe('Child 2');
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
test('should create deeply nested elements', () => {
|
|
257
|
+
const dom = {
|
|
258
|
+
t: 'div',
|
|
259
|
+
children: [
|
|
260
|
+
{
|
|
261
|
+
t: 'section',
|
|
262
|
+
children: [
|
|
263
|
+
{ t: 'h1', txt: 'Title' },
|
|
264
|
+
{ t: 'p', txt: 'Content' }
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
};
|
|
269
|
+
const element = gardener(dom);
|
|
270
|
+
expect(element.children.length).toBe(1);
|
|
271
|
+
expect(element.children[0].tagName).toBe('SECTION');
|
|
272
|
+
expect(element.children[0].children.length).toBe(2);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test('should create SVG element', () => {
|
|
276
|
+
const dom = { t: 'svg' };
|
|
277
|
+
const element = gardener(dom);
|
|
278
|
+
expect(element.tagName).toBe('svg');
|
|
279
|
+
expect(element.namespaceURI).toBe('http://www.w3.org/2000/svg');
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
test('should create SVG path element', () => {
|
|
283
|
+
const dom = {
|
|
284
|
+
t: 'path',
|
|
285
|
+
attr: { d: 'M10 10 H 90 V 90 H 10 Z' }
|
|
286
|
+
};
|
|
287
|
+
const element = gardener(dom);
|
|
288
|
+
expect(element.tagName).toBe('path');
|
|
289
|
+
expect(element.namespaceURI).toBe('http://www.w3.org/2000/svg');
|
|
290
|
+
expect(element.getAttribute('d')).toBe('M10 10 H 90 V 90 H 10 Z');
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
test('should create SVG with classes', () => {
|
|
294
|
+
const dom = {
|
|
295
|
+
t: 'circle',
|
|
296
|
+
cn: ['svg-class'],
|
|
297
|
+
attr: { cx: '50', cy: '50', r: '40' }
|
|
298
|
+
};
|
|
299
|
+
const element = gardener(dom);
|
|
300
|
+
expect(element.classList.contains('svg-class')).toBe(true);
|
|
301
|
+
expect(element.getAttribute('cx')).toBe('50');
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
test('should create complex SVG structure', () => {
|
|
305
|
+
const dom = {
|
|
306
|
+
t: 'svg',
|
|
307
|
+
attr: { width: '100', height: '100' },
|
|
308
|
+
children: [
|
|
309
|
+
{ t: 'circle', attr: { cx: '50', cy: '50', r: '40' } },
|
|
310
|
+
{ t: 'rect', attr: { x: '10', y: '10', width: '30', height: '30' } }
|
|
311
|
+
]
|
|
312
|
+
};
|
|
313
|
+
const element = gardener(dom);
|
|
314
|
+
expect(element.children.length).toBe(2);
|
|
315
|
+
expect(element.children[0].tagName).toBe('circle');
|
|
316
|
+
expect(element.children[1].tagName).toBe('rect');
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test('should handle property attributes like value', () => {
|
|
320
|
+
const dom = {
|
|
321
|
+
t: 'input',
|
|
322
|
+
attr: { value: 'test-value', selectedIndex: '2' }
|
|
323
|
+
};
|
|
324
|
+
const element = gardener(dom);
|
|
325
|
+
expect(element.getAttribute('value')).toBe('test-value');
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
test('should handle empty string attribute as boolean', () => {
|
|
329
|
+
const dom = {
|
|
330
|
+
t: 'button',
|
|
331
|
+
attr: { disabled: '' }
|
|
332
|
+
};
|
|
333
|
+
const element = gardener(dom);
|
|
334
|
+
expect(element.disabled).toBe(true);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
test('should create element with all features combined', () => {
|
|
338
|
+
const clickHandler = jest.fn();
|
|
339
|
+
const dom = {
|
|
340
|
+
t: 'div',
|
|
341
|
+
cn: ['container', 'main'],
|
|
342
|
+
txt: 'Container Text',
|
|
343
|
+
attr: { id: 'main-container', 'data-test': 'value' },
|
|
344
|
+
events: { click: clickHandler },
|
|
345
|
+
children: [
|
|
346
|
+
{ t: 'h1', txt: 'Title', cn: ['title'] },
|
|
347
|
+
{ t: 'p', txt: 'Paragraph' }
|
|
348
|
+
]
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const element = gardener(dom);
|
|
352
|
+
|
|
353
|
+
expect(element.tagName).toBe('DIV');
|
|
354
|
+
expect(element.classList.contains('container')).toBe(true);
|
|
355
|
+
expect(element.classList.contains('main')).toBe(true);
|
|
356
|
+
expect(element.innerText).toContain('Container Text');
|
|
357
|
+
expect(element.id).toBe('main-container');
|
|
358
|
+
expect(element.getAttribute('data-test')).toBe('value');
|
|
359
|
+
expect(element.children.length).toBe(2);
|
|
360
|
+
|
|
361
|
+
element.click();
|
|
362
|
+
expect(clickHandler).toHaveBeenCalled();
|
|
363
|
+
});
|
|
364
|
+
});
|
|
@@ -78,7 +78,7 @@ const pagebtns = gardener({
|
|
|
78
78
|
const result = await fetch('/savetemplate', {
|
|
79
79
|
method: 'POST',
|
|
80
80
|
headers: { "Content-Type": 'application/json' },
|
|
81
|
-
body: JSON.stringify({ path:
|
|
81
|
+
body: JSON.stringify({ path: fetchElement('#fileName').innerText })
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
const data = await result.json(); // ✅ fix
|
|
@@ -310,7 +310,6 @@ async function addComponent(txt, path) {
|
|
|
310
310
|
if (!res.ok) console.error('wrong');
|
|
311
311
|
|
|
312
312
|
const data = await res.json()
|
|
313
|
-
console.log(data);
|
|
314
313
|
|
|
315
314
|
}
|
|
316
315
|
catch (err) {
|
|
@@ -328,7 +327,6 @@ function opnPagedialog(btn = true) {
|
|
|
328
327
|
e.preventDefault()
|
|
329
328
|
const data = new FormData(e.target);
|
|
330
329
|
const input = Object.fromEntries(data.entries());
|
|
331
|
-
console.log(input)
|
|
332
330
|
|
|
333
331
|
const response = await fetch('/addpage', {
|
|
334
332
|
method: 'POST',
|
|
@@ -337,7 +335,6 @@ function opnPagedialog(btn = true) {
|
|
|
337
335
|
},
|
|
338
336
|
body: JSON.stringify(input)
|
|
339
337
|
}).then(res => res.json())
|
|
340
|
-
console.log(response)
|
|
341
338
|
opnPagedialog(false)
|
|
342
339
|
window.location.href = `${input.page}`
|
|
343
340
|
}
|
|
@@ -353,12 +350,10 @@ function opnPagedialog(btn = true) {
|
|
|
353
350
|
|
|
354
351
|
})
|
|
355
352
|
|
|
356
|
-
console.log('test')
|
|
357
353
|
appendElement(body, dialog);
|
|
358
354
|
fetchElement('.pathinput').focus();
|
|
359
355
|
}
|
|
360
356
|
else {
|
|
361
|
-
console.log('removed')
|
|
362
357
|
fetchElement('.addpageform').remove();
|
|
363
358
|
}
|
|
364
359
|
}
|
|
@@ -416,7 +411,6 @@ export function parser(element, isParent = true) {
|
|
|
416
411
|
element = fetchElement(element);
|
|
417
412
|
}
|
|
418
413
|
|
|
419
|
-
console.log(element)
|
|
420
414
|
const obj = {
|
|
421
415
|
t: element.tagName.toLowerCase(),
|
|
422
416
|
};
|
|
@@ -489,6 +483,9 @@ export class State {
|
|
|
489
483
|
cb(this.value);
|
|
490
484
|
this.cb.push(cb);
|
|
491
485
|
}
|
|
486
|
+
unregisterCb(cb) {
|
|
487
|
+
this.cb = this.cb.filter(c => c !== cb);
|
|
488
|
+
}
|
|
492
489
|
setTo(val) {
|
|
493
490
|
this.value = val;
|
|
494
491
|
this.cb.forEach(cb => { cb(val) });
|
|
@@ -273,9 +273,6 @@
|
|
|
273
273
|
.bottom-4 {
|
|
274
274
|
bottom: calc(var(--spacing) * 4);
|
|
275
275
|
}
|
|
276
|
-
.bottom-6 {
|
|
277
|
-
bottom: calc(var(--spacing) * 6);
|
|
278
|
-
}
|
|
279
276
|
.bottom-20 {
|
|
280
277
|
bottom: calc(var(--spacing) * 20);
|
|
281
278
|
}
|
|
@@ -306,6 +303,24 @@
|
|
|
306
303
|
.z-100 {
|
|
307
304
|
z-index: 100;
|
|
308
305
|
}
|
|
306
|
+
.container {
|
|
307
|
+
width: 100%;
|
|
308
|
+
@media (width >= 40rem) {
|
|
309
|
+
max-width: 40rem;
|
|
310
|
+
}
|
|
311
|
+
@media (width >= 48rem) {
|
|
312
|
+
max-width: 48rem;
|
|
313
|
+
}
|
|
314
|
+
@media (width >= 64rem) {
|
|
315
|
+
max-width: 64rem;
|
|
316
|
+
}
|
|
317
|
+
@media (width >= 80rem) {
|
|
318
|
+
max-width: 80rem;
|
|
319
|
+
}
|
|
320
|
+
@media (width >= 96rem) {
|
|
321
|
+
max-width: 96rem;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
309
324
|
.m-2 {
|
|
310
325
|
margin: calc(var(--spacing) * 2);
|
|
311
326
|
}
|
|
@@ -351,6 +366,9 @@
|
|
|
351
366
|
.grid {
|
|
352
367
|
display: grid;
|
|
353
368
|
}
|
|
369
|
+
.hidden {
|
|
370
|
+
display: none;
|
|
371
|
+
}
|
|
354
372
|
.inline {
|
|
355
373
|
display: inline;
|
|
356
374
|
}
|
|
@@ -369,9 +387,6 @@
|
|
|
369
387
|
.h-15 {
|
|
370
388
|
height: calc(var(--spacing) * 15);
|
|
371
389
|
}
|
|
372
|
-
.h-35 {
|
|
373
|
-
height: calc(var(--spacing) * 35);
|
|
374
|
-
}
|
|
375
390
|
.h-96 {
|
|
376
391
|
height: calc(var(--spacing) * 96);
|
|
377
392
|
}
|
|
@@ -393,12 +408,6 @@
|
|
|
393
408
|
.w-15 {
|
|
394
409
|
width: calc(var(--spacing) * 15);
|
|
395
410
|
}
|
|
396
|
-
.w-35 {
|
|
397
|
-
width: calc(var(--spacing) * 35);
|
|
398
|
-
}
|
|
399
|
-
.w-50 {
|
|
400
|
-
width: calc(var(--spacing) * 50);
|
|
401
|
-
}
|
|
402
411
|
.w-96 {
|
|
403
412
|
width: calc(var(--spacing) * 96);
|
|
404
413
|
}
|
|
@@ -555,9 +564,6 @@
|
|
|
555
564
|
.bg-gray-200 {
|
|
556
565
|
background-color: var(--color-gray-200);
|
|
557
566
|
}
|
|
558
|
-
.bg-gray-400 {
|
|
559
|
-
background-color: var(--color-gray-400);
|
|
560
|
-
}
|
|
561
567
|
.bg-gray-500 {
|
|
562
568
|
background-color: var(--color-gray-500);
|
|
563
569
|
}
|
|
@@ -570,9 +576,6 @@
|
|
|
570
576
|
.bg-green-300 {
|
|
571
577
|
background-color: var(--color-green-300);
|
|
572
578
|
}
|
|
573
|
-
.bg-green-500 {
|
|
574
|
-
background-color: var(--color-green-500);
|
|
575
|
-
}
|
|
576
579
|
.bg-green-700 {
|
|
577
580
|
background-color: var(--color-green-700);
|
|
578
581
|
}
|
|
@@ -793,13 +796,6 @@
|
|
|
793
796
|
}
|
|
794
797
|
}
|
|
795
798
|
}
|
|
796
|
-
.hover\:bg-gray-800 {
|
|
797
|
-
&:hover {
|
|
798
|
-
@media (hover: hover) {
|
|
799
|
-
background-color: var(--color-gray-800);
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
799
|
.hover\:bg-gray-900 {
|
|
804
800
|
&:hover {
|
|
805
801
|
@media (hover: hover) {
|
|
@@ -807,13 +803,6 @@
|
|
|
807
803
|
}
|
|
808
804
|
}
|
|
809
805
|
}
|
|
810
|
-
.hover\:bg-green-600 {
|
|
811
|
-
&:hover {
|
|
812
|
-
@media (hover: hover) {
|
|
813
|
-
background-color: var(--color-green-600);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
806
|
.hover\:bg-green-800 {
|
|
818
807
|
&:hover {
|
|
819
808
|
@media (hover: hover) {
|
|
File without changes
|