native-document 1.0.125 → 1.0.127

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 (37) hide show
  1. package/dist/native-document.components.min.js +132 -130
  2. package/dist/native-document.dev.js +55 -58
  3. package/dist/native-document.dev.js.map +1 -1
  4. package/dist/native-document.min.js +1 -1
  5. package/package.json +1 -1
  6. package/src/components/$traits/HasItems.js +39 -2
  7. package/src/components/BaseComponent.js +4 -0
  8. package/src/components/button/Button.js +15 -9
  9. package/src/components/menu/Menu.js +18 -7
  10. package/src/components/menu/MenuItem.js +13 -13
  11. package/src/components/menu/MenuLink.js +24 -0
  12. package/src/core/elements/anchor/anchor.js +3 -10
  13. package/src/core/utils/property-accumulator.js +1 -1
  14. package/src/router/Router.js +11 -0
  15. package/src/router/RouterComponent.js +3 -1
  16. package/src/ui/components/button/button.css +362 -0
  17. package/src/ui/components/button/button.render.js +63 -0
  18. package/src/ui/theme.js +2 -1
  19. package/src/ui/tokens/animation.scss +36 -0
  20. package/src/ui/tokens/colors-dark.scss +57 -0
  21. package/src/ui/tokens/colors.scss +54 -0
  22. package/src/ui/tokens/components.scss +32 -0
  23. package/src/ui/tokens/fonts.scss +57 -0
  24. package/src/ui/tokens/glass.scss +10 -0
  25. package/src/ui/tokens/index.scss +38 -0
  26. package/src/ui/tokens/layouts.scss +228 -0
  27. package/src/ui/tokens/opacity.scss +21 -0
  28. package/src/ui/tokens/others.scss +11 -0
  29. package/src/ui/tokens/radius.scss +6 -0
  30. package/src/ui/tokens/reset.scss +48 -0
  31. package/src/ui/tokens/shadows.scss +29 -0
  32. package/src/ui/tokens/spacings.scss +13 -0
  33. package/src/ui/tokens/vars.scss +35 -0
  34. package/src/ui/tokens/viewports.scss +30 -0
  35. package/utils.js +3 -1
  36. package/src/ui/components/button/Button.js +0 -8
  37. package/src/ui/tokens/vars.css +0 -0
@@ -11,8 +11,7 @@ export default function MenuItem(config = {}) {
11
11
 
12
12
  this.$description = {
13
13
  items: [],
14
- link: null,
15
- target: null,
14
+ action: null,
16
15
  label: null,
17
16
  icon: null,
18
17
  shortcut: null,
@@ -21,6 +20,7 @@ export default function MenuItem(config = {}) {
21
20
  value: null,
22
21
  data: null,
23
22
  render: null,
23
+ trailing: null,
24
24
  ...config
25
25
  };
26
26
 
@@ -40,18 +40,13 @@ MenuItem.prototype.label = function(label) {
40
40
  return this;
41
41
  };
42
42
 
43
- MenuItem.prototype.link = function(link) {
44
- this.$description.link = link;
43
+ MenuItem.prototype.icon = function(icon) {
44
+ this.$description.icon = icon;
45
45
  return this;
46
46
  };
47
47
 
48
- MenuItem.prototype.target = function(target) {
49
- this.$description.target = target;
50
- return this;
51
- }
52
-
53
- MenuItem.prototype.icon = function(icon) {
54
- this.$description.icon = icon;
48
+ MenuItem.prototype.trailing = function(trailing) {
49
+ this.$description.trailing = trailing;
55
50
  return this;
56
51
  };
57
52
 
@@ -61,12 +56,12 @@ MenuItem.prototype.shortcut = function(shortcut) {
61
56
  };
62
57
 
63
58
  MenuItem.prototype.disabled = function(disabled = true) {
64
- this.$description.disabled = disabled;
59
+ this.$description.disabled = BaseComponent.obs(disabled);
65
60
  return this;
66
61
  };
67
62
 
68
63
  MenuItem.prototype.selected = function(selected = true) {
69
- this.$description.selected = selected;
64
+ this.$description.selected = BaseComponent.obs(selected);
70
65
  return this;
71
66
  };
72
67
 
@@ -75,6 +70,11 @@ MenuItem.prototype.value = function(value) {
75
70
  return this;
76
71
  };
77
72
 
73
+ MenuItem.prototype.action = function(action) {
74
+ this.$description.action = action;
75
+ return this;
76
+ };
77
+
78
78
  MenuItem.prototype.data = function(data) {
79
79
  this.$description.data = data;
80
80
  return this;
@@ -0,0 +1,24 @@
1
+ import MenuItem from "./MenuItem";
2
+
3
+
4
+ export default function MenuLink(config) {
5
+ if(!(this instanceof MenuLink)) {
6
+ return new MenuLink(config);
7
+ }
8
+ MenuItem.call(this, config);
9
+ }
10
+
11
+ MenuLink.prototype = Object.create(MenuItem.prototype);
12
+ MenuLink.prototype.constructor = MenuLink;
13
+
14
+
15
+ MenuLink.defaultTemplate = null;
16
+
17
+ MenuLink.use = function(template) {
18
+ MenuLink.defaultTemplate = template.menuLink;
19
+ };
20
+
21
+ MenuLink.prototype.target = function (target) {
22
+ this.$description.target = target;
23
+ return this;
24
+ };
@@ -6,13 +6,6 @@ import oneChildAnchorOverwriting from "./one-child-anchor-overwriting";
6
6
  export default function Anchor(name, isUniqueChild = false) {
7
7
  const anchorFragment = new AnchorWithSentinel(name);
8
8
 
9
- /**
10
- * State :
11
- * 1. Not injected in the DOM
12
- * 2. Injected in the DOM and should be the only child of parent
13
- * 3. Injected in the DOM and the parent may have other children
14
- */
15
-
16
9
  anchorFragment.onConnectedOnce((parent) => {
17
10
  if(isUniqueChild) {
18
11
  oneChildAnchorOverwriting(anchorFragment, parent);
@@ -119,7 +112,7 @@ export default function Anchor(name, isUniqueChild = false) {
119
112
  return;
120
113
  }
121
114
  if(isParentUniqueChild(parent)) {
122
- anchorFragment.append.apply(anchorFragment, parent.childNodes);
115
+ anchorFragment.nativeAppend.apply(anchorFragment, parent.childNodes);
123
116
  parent.replaceChildren(anchorStart, anchorEnd);
124
117
  return;
125
118
  }
@@ -148,11 +141,11 @@ export default function Anchor(name, isUniqueChild = false) {
148
141
  return;
149
142
  }
150
143
  if(isParentUniqueChild(parent)) {
151
- parent.replaceChildren(anchorStart, childElement, anchorEnd);
144
+ parent.replaceChildren(anchorStart, child, anchorEnd);
152
145
  return;
153
146
  }
154
147
  anchorFragment.removeChildren();
155
- parent.insertBefore(childElement, anchorEnd);
148
+ parent.insertBefore(child, anchorEnd);
156
149
  };
157
150
 
158
151
  anchorFragment.setContent = anchorFragment.replaceContent;
@@ -7,7 +7,7 @@ export const cssPropertyAccumulator = function(initialValue = {}) {
7
7
  return {
8
8
  add(key, value) {
9
9
  if(isArray) {
10
- data.push(key+' : '+value);
10
+ data.push(key+': '+value);
11
11
  return;
12
12
  }
13
13
  data[key] = value;
@@ -118,6 +118,17 @@ export default function Router($options = {}) {
118
118
  * @returns {{route:Route, params:Object, query:Object, path:string}}
119
119
  */
120
120
  this.resolve = function(target) {
121
+ if(typeof target === 'string') {
122
+ const route = $routesByName[target];
123
+ if(route) {
124
+ return {
125
+ route,
126
+ params: [],
127
+ query: [],
128
+ path: route.url({ name: target })
129
+ };
130
+ }
131
+ }
121
132
  if(Validator.isJson(target)) {
122
133
  const route = $routesByName[target.name];
123
134
  if(!route) {
@@ -27,7 +27,6 @@ export function RouterComponent(router, container) {
27
27
  anchor = Anchor(path);
28
28
  anchor.appendChild(node);
29
29
  }
30
- console.log(anchor);
31
30
  $routeInstanceAnchors.set(node, anchor);
32
31
  return anchor;
33
32
  };
@@ -63,10 +62,12 @@ export function RouterComponent(router, container) {
63
62
  if(cachedLayout === $currentLayout) {
64
63
  const layoutAnchor = getNodeAnchorForLayout(nodeToInsert, path);
65
64
  removeLastNodeInserted();
65
+ $lastNodeInserted = nodeToInsert;
66
66
  layoutAnchor.replaceContent(nodeToInsert);
67
67
  return;
68
68
  }
69
69
  cleanContainer();
70
+ $lastNodeInserted = nodeToInsert;
70
71
  $currentLayout = cachedLayout;
71
72
  const layoutAnchor = getNodeAnchorForLayout(nodeToInsert, path);
72
73
  layoutAnchor.replaceContent(nodeToInsert);
@@ -74,6 +75,7 @@ export function RouterComponent(router, container) {
74
75
  return;
75
76
  }
76
77
  cleanContainer();
78
+ $lastNodeInserted = nodeToInsert;
77
79
  const anchor = getNodeAnchorForLayout(nodeToInsert, path);
78
80
 
79
81
  $currentLayout = ElementCreator.getChild(layout(anchor));
@@ -0,0 +1,362 @@
1
+ /* ─────────────────────────────────────────────
2
+ Button tokens
3
+ Dépend de : vars.css (colors, spacings, radius, fonts)
4
+ ───────────────────────────────────────────── */
5
+ :root {
6
+ /* Sizes — hauteurs */
7
+ --btn-height-sm: 28px;
8
+ --btn-height-md: 36px;
9
+ --btn-height-lg: 44px;
10
+
11
+ /* Sizes — paddings horizontaux */
12
+ --btn-padding-sm: var(--space-cozy) var(--space-cozy-comfortable);
13
+ --btn-padding-md: var(--space-cozy) var(--space-comfortable);
14
+ --btn-padding-lg: var(--space-cozy-comfortable) var(--space-relaxed);
15
+
16
+ /* Sizes — font */
17
+ --btn-font-size-sm: var(--note-size);
18
+ --btn-font-size-md: var(--description-size);
19
+ --btn-font-size-lg: var(--text-size);
20
+
21
+ /* Sizes — icon */
22
+ --btn-icon-size-sm: 14px;
23
+ --btn-icon-size-md: 16px;
24
+ --btn-icon-size-lg: 18px;
25
+
26
+ /* Shape */
27
+ --btn-radius: var(--radius-button);
28
+ --btn-radius-rounded: var(--radius-x);
29
+ --btn-radius-pill: var(--radius-pill);
30
+
31
+ /* Misc */
32
+ --btn-font-family: var(--font);
33
+ --btn-font-weight: 500;
34
+ --btn-gap: var(--space-cozy);
35
+ --btn-transition: background 120ms ease, color 120ms ease, border-color 120ms ease, opacity 120ms ease;
36
+ --btn-disabled-opacity: 0.45;
37
+ --btn-loader-size: 14px;
38
+ --btn-border-width: 1px;
39
+
40
+ /* ── Variants ── */
41
+
42
+ /* Primary */
43
+ --btn-primary-bg: var(--color-primary);
44
+ --btn-primary-bg-hover: var(--color-primary-hover);
45
+ --btn-primary-color: var(--white);
46
+ --btn-primary-border: var(--color-primary);
47
+ --btn-primary-border-hover: var(--color-primary-hover);
48
+
49
+ /* Secondary */
50
+ --btn-secondary-bg: var(--color-secondary);
51
+ --btn-secondary-bg-hover: var(--color-secondary-hover);
52
+ --btn-secondary-color: var(--color-secondary-text);
53
+ --btn-secondary-border: var(--color-secondary);
54
+ --btn-secondary-border-hover: var(--color-secondary-hover);
55
+
56
+ /* Danger */
57
+ --btn-danger-bg: var(--color-danger);
58
+ --btn-danger-bg-hover: var(--color-danger-hover);
59
+ --btn-danger-color: var(--white);
60
+ --btn-danger-border: var(--color-danger);
61
+ --btn-danger-border-hover: var(--color-danger-hover);
62
+
63
+ /* Success */
64
+ --btn-success-bg: var(--color-success);
65
+ --btn-success-bg-hover: var(--color-success-hover);
66
+ --btn-success-color: var(--white);
67
+ --btn-success-border: var(--color-success);
68
+ --btn-success-border-hover: var(--color-success-hover);
69
+
70
+ /* Warning */
71
+ --btn-warning-bg: var(--color-warning);
72
+ --btn-warning-bg-hover: var(--color-warning-hover);
73
+ --btn-warning-color: var(--white);
74
+ --btn-warning-border: var(--color-warning);
75
+ --btn-warning-border-hover: var(--color-warning-hover);
76
+
77
+ /* Info */
78
+ --btn-info-bg: var(--color-info);
79
+ --btn-info-bg-hover: var(--color-info-hover);
80
+ --btn-info-color: var(--white);
81
+ --btn-info-border: var(--color-info);
82
+ --btn-info-border-hover: var(--color-info-hover);
83
+
84
+ /* Ghost */
85
+ --btn-ghost-bg: var(--color-ghost);
86
+ --btn-ghost-bg-hover: var(--color-ghost-hover);
87
+ --btn-ghost-color: var(--color-ghost-text);
88
+ --btn-ghost-border: transparent;
89
+ --btn-ghost-border-hover: transparent;
90
+
91
+ /* Link */
92
+ --btn-link-bg: transparent;
93
+ --btn-link-bg-hover: transparent;
94
+ --btn-link-color: var(--color-link);
95
+ --btn-link-color-hover: var(--color-link-hover);
96
+ --btn-link-border: transparent;
97
+ }
98
+
99
+ /* ─────────────────────────────────────────────
100
+ Base
101
+ ───────────────────────────────────────────── */
102
+ .btn {
103
+ display: inline-flex;
104
+ align-items: center;
105
+ justify-content: center;
106
+ gap: var(--btn-gap);
107
+ border: var(--btn-border-width) solid transparent;
108
+ border-radius: var(--btn-radius);
109
+ cursor: pointer;
110
+ font-family: var(--btn-font-family);
111
+ font-weight: var(--btn-font-weight);
112
+ font-size: var(--btn-font-size-md);
113
+ height: var(--btn-height-md);
114
+ padding: var(--btn-padding-md);
115
+ line-height: 1;
116
+ white-space: nowrap;
117
+ text-decoration: none;
118
+ outline: none;
119
+ transition: var(--btn-transition);
120
+ user-select: none;
121
+ box-sizing: border-box;
122
+ vertical-align: middle;
123
+ }
124
+
125
+ /* ─────────────────────────────────────────────
126
+ Sizes
127
+ ───────────────────────────────────────────── */
128
+ .btn--sm {
129
+ height: var(--btn-height-sm);
130
+ padding: var(--btn-padding-sm);
131
+ font-size: var(--btn-font-size-sm);
132
+ }
133
+ .btn--lg {
134
+ height: var(--btn-height-lg);
135
+ padding: var(--btn-padding-lg);
136
+ font-size: var(--btn-font-size-lg);
137
+ }
138
+
139
+ /* ─────────────────────────────────────────────
140
+ Shapes
141
+ ───────────────────────────────────────────── */
142
+ .btn--rounded { border-radius: var(--btn-radius-rounded); }
143
+ .btn--pill { border-radius: var(--btn-radius-pill); }
144
+ .btn--circle {
145
+ border-radius: 50%;
146
+ padding: 0;
147
+ width: var(--btn-height-md);
148
+ }
149
+ .btn--sm.btn--circle { width: var(--btn-height-sm); }
150
+ .btn--lg.btn--circle { width: var(--btn-height-lg); }
151
+
152
+ /* ─────────────────────────────────────────────
153
+ Block
154
+ ───────────────────────────────────────────── */
155
+ .btn--block {
156
+ width: 100%;
157
+ display: flex;
158
+ }
159
+
160
+ /* ─────────────────────────────────────────────
161
+ Icon
162
+ ───────────────────────────────────────────── */
163
+ .btn__icon {
164
+ display: inline-flex;
165
+ align-items: center;
166
+ flex-shrink: 0;
167
+ width: var(--btn-icon-size-md);
168
+ height: var(--btn-icon-size-md);
169
+ }
170
+ .btn--sm .btn__icon {
171
+ width: var(--btn-icon-size-sm);
172
+ height: var(--btn-icon-size-sm);
173
+ }
174
+ .btn--lg .btn__icon {
175
+ width: var(--btn-icon-size-lg);
176
+ height: var(--btn-icon-size-lg);
177
+ }
178
+ .btn--icon-top,
179
+ .btn--icon-bottom { flex-direction: column; }
180
+
181
+ /* ─────────────────────────────────────────────
182
+ Loader
183
+ ───────────────────────────────────────────── */
184
+ .btn__loader {
185
+ display: inline-block;
186
+ width: var(--btn-loader-size);
187
+ height: var(--btn-loader-size);
188
+ border: 2px solid currentColor;
189
+ border-top-color: transparent;
190
+ border-radius: 50%;
191
+ flex-shrink: 0;
192
+ animation: btn-spin 0.6s linear infinite;
193
+ }
194
+ @keyframes btn-spin {
195
+ to { transform: rotate(360deg); }
196
+ }
197
+
198
+ /* ─────────────────────────────────────────────
199
+ States
200
+ ───────────────────────────────────────────── */
201
+ .btn:disabled,
202
+ .btn--disabled,
203
+ .btn--loading {
204
+ opacity: var(--btn-disabled-opacity);
205
+ cursor: not-allowed;
206
+ pointer-events: none;
207
+ }
208
+
209
+ /* ─────────────────────────────────────────────
210
+ Variants
211
+ ───────────────────────────────────────────── */
212
+
213
+ /* Primary */
214
+ .btn--primary {
215
+ background: var(--btn-primary-bg);
216
+ color: var(--btn-primary-color);
217
+ border-color: var(--btn-primary-border);
218
+ }
219
+ .btn--primary:hover {
220
+ background: var(--btn-primary-bg-hover);
221
+ border-color: var(--btn-primary-border-hover);
222
+ }
223
+
224
+ /* Secondary */
225
+ .btn--secondary {
226
+ background: var(--btn-secondary-bg);
227
+ color: var(--btn-secondary-color);
228
+ border-color: var(--btn-secondary-border);
229
+ }
230
+ .btn--secondary:hover {
231
+ background: var(--btn-secondary-bg-hover);
232
+ border-color: var(--btn-secondary-border-hover);
233
+ }
234
+
235
+ /* Danger */
236
+ .btn--danger {
237
+ background: var(--btn-danger-bg);
238
+ color: var(--btn-danger-color);
239
+ border-color: var(--btn-danger-border);
240
+ }
241
+ .btn--danger:hover {
242
+ background: var(--btn-danger-bg-hover);
243
+ border-color: var(--btn-danger-border-hover);
244
+ }
245
+
246
+ /* Success */
247
+ .btn--success {
248
+ background: var(--btn-success-bg);
249
+ color: var(--btn-success-color);
250
+ border-color: var(--btn-success-border);
251
+ }
252
+ .btn--success:hover {
253
+ background: var(--btn-success-bg-hover);
254
+ border-color: var(--btn-success-border-hover);
255
+ }
256
+
257
+ /* Warning */
258
+ .btn--warning {
259
+ background: var(--btn-warning-bg);
260
+ color: var(--btn-warning-color);
261
+ border-color: var(--btn-warning-border);
262
+ }
263
+ .btn--warning:hover {
264
+ background: var(--btn-warning-bg-hover);
265
+ border-color: var(--btn-warning-border-hover);
266
+ }
267
+
268
+ /* Info */
269
+ .btn--info {
270
+ background: var(--btn-info-bg);
271
+ color: var(--btn-info-color);
272
+ border-color: var(--btn-info-border);
273
+ }
274
+ .btn--info:hover {
275
+ background: var(--btn-info-bg-hover);
276
+ border-color: var(--btn-info-border-hover);
277
+ }
278
+
279
+ /* Ghost */
280
+ .btn--ghost {
281
+ background: var(--btn-ghost-bg);
282
+ color: var(--btn-ghost-color);
283
+ border-color: var(--btn-ghost-border);
284
+ }
285
+ .btn--ghost:hover {
286
+ background: var(--btn-ghost-bg-hover);
287
+ border-color: var(--btn-ghost-border-hover);
288
+ }
289
+
290
+ /* Link */
291
+ .btn--link {
292
+ background: var(--btn-link-bg);
293
+ color: var(--btn-link-color);
294
+ border-color: var(--btn-link-border);
295
+ text-decoration: underline;
296
+ text-underline-offset: 2px;
297
+ }
298
+ .btn--link:hover {
299
+ color: var(--btn-link-color-hover);
300
+ }
301
+
302
+ /* ─────────────────────────────────────────────
303
+ Outline modifier
304
+ ───────────────────────────────────────────── */
305
+ .btn--outline.btn--primary {
306
+ background: transparent;
307
+ color: var(--btn-primary-bg);
308
+ border-color: var(--btn-primary-bg);
309
+ }
310
+ .btn--outline.btn--primary:hover {
311
+ background: var(--btn-primary-bg);
312
+ color: var(--btn-primary-color);
313
+ }
314
+
315
+ .btn--outline.btn--danger {
316
+ background: transparent;
317
+ color: var(--btn-danger-bg);
318
+ border-color: var(--btn-danger-bg);
319
+ }
320
+ .btn--outline.btn--danger:hover {
321
+ background: var(--btn-danger-bg);
322
+ color: var(--btn-danger-color);
323
+ }
324
+
325
+ .btn--outline.btn--success {
326
+ background: transparent;
327
+ color: var(--btn-success-bg);
328
+ border-color: var(--btn-success-bg);
329
+ }
330
+ .btn--outline.btn--success:hover {
331
+ background: var(--btn-success-bg);
332
+ color: var(--btn-success-color);
333
+ }
334
+
335
+ .btn--outline.btn--warning {
336
+ background: transparent;
337
+ color: var(--btn-warning-bg);
338
+ border-color: var(--btn-warning-bg);
339
+ }
340
+ .btn--outline.btn--warning:hover {
341
+ background: var(--btn-warning-bg);
342
+ color: var(--btn-warning-color);
343
+ }
344
+
345
+ .btn--outline.btn--info {
346
+ background: transparent;
347
+ color: var(--btn-info-bg);
348
+ border-color: var(--btn-info-bg);
349
+ }
350
+ .btn--outline.btn--info:hover {
351
+ background: var(--btn-info-bg);
352
+ color: var(--btn-info-color);
353
+ }
354
+
355
+ .btn--outline.btn--secondary {
356
+ background: transparent;
357
+ color: var(--btn-secondary-color);
358
+ border-color: var(--gray-lite-2);
359
+ }
360
+ .btn--outline.btn--secondary:hover {
361
+ background: var(--btn-secondary-bg);
362
+ }
@@ -0,0 +1,63 @@
1
+ import { Button as NativeButton, Span } from 'native-document/elements';
2
+ import { classPropertyAccumulator } from 'native-document/utils';
3
+ import './button.css';
4
+
5
+ /**
6
+ * @param {Button} instance
7
+ * @returns {HTMLElement}
8
+ */
9
+ const ButtonRender = function(instance) {
10
+ const desc = instance.$description;
11
+
12
+ const classes = classPropertyAccumulator([
13
+ 'btn',
14
+ `btn--${desc.variant || 'secondary'}`,
15
+ desc.outline && 'btn--outline',
16
+ desc.block && 'btn--block',
17
+ desc.size === 'small' && 'btn--sm',
18
+ desc.size === 'large' && 'btn--lg',
19
+ desc.borderRadiusType && `btn--${desc.borderRadiusType}`,
20
+ ].filter(Boolean));
21
+
22
+ classes.add('btn--loading', desc.loading);
23
+ classes.add('btn--disabled', desc.disabled);
24
+
25
+ const content = buildContent(desc);
26
+
27
+ return NativeButton({
28
+ class: classes.value(),
29
+ type: desc.type || 'button',
30
+ disabled: desc.disabled,
31
+ }, content);
32
+ };
33
+
34
+ /**
35
+ * Construit le contenu du bouton
36
+ * icon + label + loader selon la configuration
37
+ */
38
+ const buildContent = (desc) => {
39
+ const content = [];
40
+
41
+ if (desc.loading) {
42
+ content.push(Span({ class: 'btn__loader' }));
43
+ }
44
+
45
+ if (desc.icon && isIconBefore(desc.iconPosition)) {
46
+ content.push(Span({ class: 'btn__icon' }, desc.icon));
47
+ }
48
+
49
+ if (desc.label != null) {
50
+ content.push(Span({ class: 'btn__label' }, desc.label));
51
+ }
52
+
53
+ if (desc.icon && isIconAfter(desc.iconPosition)) {
54
+ content.push(Span({ class: 'btn__icon' }, desc.icon));
55
+ }
56
+
57
+ return content;
58
+ };
59
+
60
+ const isIconBefore = (position) => !position || position === 'left' || position === 'top';
61
+ const isIconAfter = (position) => position === 'right' || position === 'bottom';
62
+
63
+ export default ButtonRender;
package/src/ui/theme.js CHANGED
@@ -1,5 +1,6 @@
1
+ import ButtonRender from "./components/button/button.render";
1
2
 
2
3
 
3
4
  export const DefaultTheme = {
4
-
5
+ Button: ButtonRender
5
6
  }
@@ -0,0 +1,36 @@
1
+ :root {
2
+ --fast: .2s;
3
+ --natural: .3s;
4
+ --medium: .5s;
5
+ --slow: 1s;
6
+ --very-slow: 5s;
7
+
8
+ --animate-very-fast: .2s;
9
+ --animate-fast: .5s;
10
+ --animate-relax: 1s;
11
+ --animate-slow: 2s;
12
+ }
13
+
14
+ @keyframes fadeInUp {
15
+ from {
16
+ opacity: 0;
17
+ transform: translateY(15px) scale(0.98);
18
+ }
19
+ to {
20
+ opacity: 1;
21
+ transform: translateY(0) scale(1);
22
+ }
23
+ }
24
+
25
+
26
+ @keyframes pulse-shadow {
27
+ 0% {
28
+ box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.7); /* Initial shadow (subtle or none) */
29
+ }
30
+ 70% {
31
+ box-shadow: 0 0 0 15px rgba(52, 152, 219, 0); /* Shadow expands and fades */
32
+ }
33
+ 100% {
34
+ box-shadow: 0 0 0 0 rgba(52, 152, 219, 0); /* Returns to initial state */
35
+ }
36
+ }