native-document 1.0.291 → 1.0.293
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/package.json +1 -1
- package/src/components/form/field/Field.js +1 -0
- package/src/core/data/Observable.js +7 -0
- package/src/router/Route.js +3 -0
- package/src/router/RouteGroupHelper.js +5 -0
- package/src/router/Router.js +14 -4
- package/src/router/RouterComponent.js +50 -23
- package/src/router/modes/HistoryRouter.js +4 -2
- package/src/ui/components/button/CopyButtonRender.js +1 -1
- package/src/ui/components/dropdown/dropdown.css +1 -1
- package/src/ui/components/form/FormControlRender.js +12 -0
- package/src/ui/components/popover/PopoverRender.js +4 -4
- package/src/ui/components/popover/popover.css +7 -2
- package/src/ui/components/tooltip/tooltip.css +0 -1
- package/types/router.d.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "native-document",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.293",
|
|
4
4
|
"description": "A reactive JavaScript framework that preserves native DOM simplicity without sacrificing modern features",
|
|
5
5
|
"author": "AfroCodeur <https://github.com/afrocodeur>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -239,6 +239,13 @@ Observable.value = function(data) {
|
|
|
239
239
|
if(data?.__$Observable) {
|
|
240
240
|
return data.val();
|
|
241
241
|
}
|
|
242
|
+
if(Validator.isJson(data)) {
|
|
243
|
+
const output = {};
|
|
244
|
+
for(const key in data) {
|
|
245
|
+
output[key] = Observable.value(data[key]);
|
|
246
|
+
}
|
|
247
|
+
return output;
|
|
248
|
+
}
|
|
242
249
|
return data;
|
|
243
250
|
};
|
|
244
251
|
|
package/src/router/Route.js
CHANGED
|
@@ -34,6 +34,7 @@ export const RouteParamPatterns = {
|
|
|
34
34
|
* @param {boolean} [$options.shouldRebuild] - Whether to rebuild component on each navigation
|
|
35
35
|
* @param {Object} [$options.with] - Custom parameter validation patterns
|
|
36
36
|
* @param {Function} [$options.layout] - Layout component wrapper function
|
|
37
|
+
* @param {Function[]} [$options.layouts] - All prent Layouts component wrapper function
|
|
37
38
|
*/
|
|
38
39
|
export function Route($path, $component, $options = {}) {
|
|
39
40
|
|
|
@@ -46,6 +47,7 @@ export function Route($path, $component, $options = {}) {
|
|
|
46
47
|
const $shouldRebuild = $options.shouldRebuild || false;
|
|
47
48
|
const $paramsValidators = $options.with || {};
|
|
48
49
|
const $layout = $options.layout || null;
|
|
50
|
+
const $layouts = $options.layouts || null;
|
|
49
51
|
|
|
50
52
|
const $params = {};
|
|
51
53
|
const $paramsNames = [];
|
|
@@ -91,6 +93,7 @@ export function Route($path, $component, $options = {}) {
|
|
|
91
93
|
this.shouldRebuild = () => $shouldRebuild;
|
|
92
94
|
this.path = () => $path;
|
|
93
95
|
this.layout = () => $layout;
|
|
96
|
+
this.layouts = () => $layouts;
|
|
94
97
|
|
|
95
98
|
/**
|
|
96
99
|
*
|
package/src/router/Router.js
CHANGED
|
@@ -63,6 +63,10 @@ export default function Router($options = {}) {
|
|
|
63
63
|
middlewares: RouteGroupHelper.fullMiddlewares($groupTree, options?.middlewares || []),
|
|
64
64
|
name: options?.name ? RouteGroupHelper.fullName($groupTree, options.name) : null,
|
|
65
65
|
layout: options?.layout || RouteGroupHelper.layout($groupTree),
|
|
66
|
+
layouts: [
|
|
67
|
+
...RouteGroupHelper.layouts($groupTree),
|
|
68
|
+
...(options?.layout ? [options.layout] : []),
|
|
69
|
+
],
|
|
66
70
|
});
|
|
67
71
|
$routes.push(route);
|
|
68
72
|
if(route.name()) {
|
|
@@ -205,8 +209,6 @@ export default function Router($options = {}) {
|
|
|
205
209
|
$currentState.query = query;
|
|
206
210
|
$currentState.path = path;
|
|
207
211
|
|
|
208
|
-
console.log({ builded: true })
|
|
209
|
-
|
|
210
212
|
const middlewares = [...route.middlewares(), trigger];
|
|
211
213
|
let currentIndex = 0;
|
|
212
214
|
const request = { ...$currentState };
|
|
@@ -223,7 +225,7 @@ export default function Router($options = {}) {
|
|
|
223
225
|
|
|
224
226
|
this.currentRouteName = function() {
|
|
225
227
|
return $currentState.route.name();
|
|
226
|
-
}
|
|
228
|
+
};
|
|
227
229
|
|
|
228
230
|
}
|
|
229
231
|
|
|
@@ -287,16 +289,24 @@ Router.get = function(name) {
|
|
|
287
289
|
|
|
288
290
|
Router.currentRoute = function(name = null) {
|
|
289
291
|
return Router.get(name).currentState().route;
|
|
290
|
-
}
|
|
292
|
+
};
|
|
291
293
|
|
|
292
294
|
Router.push = function(target, name = null) {
|
|
293
295
|
return Router.get(name).push(target);
|
|
294
296
|
};
|
|
295
297
|
|
|
298
|
+
Router.pushToo = function(routeName, params = {}, routerName = null) {
|
|
299
|
+
return Router.get(routerName).push({ name: routeName, params });
|
|
300
|
+
};
|
|
301
|
+
|
|
296
302
|
Router.replace = function(target, name = null) {
|
|
297
303
|
return Router.get(name).replace(target);
|
|
298
304
|
};
|
|
299
305
|
|
|
306
|
+
Router.replaceTo = function(routeName, params = {}, routerName = null) {
|
|
307
|
+
return Router.get(routerName).replace({ name: routeName, params });
|
|
308
|
+
};
|
|
309
|
+
|
|
300
310
|
Router.forward = function(name = null) {
|
|
301
311
|
return Router.get(name).forward();
|
|
302
312
|
};
|
|
@@ -18,6 +18,7 @@ export function RouterComponent(router, container) {
|
|
|
18
18
|
|
|
19
19
|
const $lifecycles = new Map();
|
|
20
20
|
let $currentPath = null;
|
|
21
|
+
let $mountedChain = [];
|
|
21
22
|
|
|
22
23
|
const getNodeAnchorForLayout = (node, path) => {
|
|
23
24
|
const existingAnchor = $routeInstanceAnchors.get(node);
|
|
@@ -55,39 +56,65 @@ export function RouterComponent(router, container) {
|
|
|
55
56
|
return nodeToInsert;
|
|
56
57
|
};
|
|
57
58
|
|
|
58
|
-
const updateContainerByLayout = (
|
|
59
|
+
const updateContainerByLayout = (layouts, node, route, path) => {
|
|
60
|
+
|
|
59
61
|
const nodeToInsert = getNodeToInsert(node);
|
|
62
|
+
let matchDepth = 0;
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
layoutAnchor.replaceContent(nodeToInsert);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
cleanContainer();
|
|
64
|
+
while (matchDepth < $mountedChain.length && matchDepth < layouts.length && $mountedChain[matchDepth].layoutFn === layouts[matchDepth]) {
|
|
65
|
+
matchDepth++;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (matchDepth === layouts.length && matchDepth === $mountedChain.length) {
|
|
69
|
+
removeLastNodeInserted();
|
|
71
70
|
$lastNodeInserted = nodeToInsert;
|
|
72
|
-
$
|
|
73
|
-
const layoutAnchor = getNodeAnchorForLayout(nodeToInsert, path);
|
|
74
|
-
layoutAnchor.replaceContent(nodeToInsert);
|
|
75
|
-
container.appendChild($currentLayout);
|
|
71
|
+
$mountedChain[matchDepth - 1]?.anchor?.replaceContent(nodeToInsert);
|
|
76
72
|
return;
|
|
77
73
|
}
|
|
78
|
-
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if ($mountedChain[matchDepth]) {
|
|
77
|
+
$mountedChain[matchDepth].element.remove();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const $mountedChainKeep = $mountedChain.slice(0, matchDepth);
|
|
81
|
+
const newLayers = [];
|
|
82
|
+
let slot = nodeToInsert;
|
|
79
83
|
$lastNodeInserted = nodeToInsert;
|
|
80
|
-
const anchor = getNodeAnchorForLayout(nodeToInsert, path);
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
for(let i = layouts.length - 1; i >= matchDepth; i -= 1) {
|
|
86
|
+
const layout = layouts[i];
|
|
87
|
+
let cached = $layoutCache.get(layout);
|
|
88
|
+
if(!cached) {
|
|
89
|
+
const anchor = getNodeAnchorForLayout(slot, `${path}:layout:${i}`);
|
|
90
|
+
const element = ElementCreator.getChild(layout(anchor));
|
|
91
|
+
cached = { element, anchor };
|
|
92
|
+
$layoutCache.set(layout, cached);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
cached.anchor.replaceContent(slot);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
newLayers.unshift({ layoutFn: layout, anchor: cached.anchor, element: cached.element });
|
|
99
|
+
slot = cached.element;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
$mountedChain = [...$mountedChainKeep, ...newLayers];
|
|
103
|
+
|
|
104
|
+
if (matchDepth === 0) {
|
|
105
|
+
container.appendChild(newLayers[0].element);
|
|
106
|
+
} else {
|
|
107
|
+
$mountedChainKeep[matchDepth - 1].anchor.replaceContent(newLayers[0]?.element || slot);
|
|
108
|
+
}
|
|
109
|
+
|
|
85
110
|
};
|
|
86
111
|
|
|
87
112
|
const updateContainer = function(node, route, path) {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
113
|
+
const layouts = route.layouts();
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if(layouts.length) {
|
|
117
|
+
updateContainerByLayout(layouts, node, route, path);
|
|
91
118
|
return;
|
|
92
119
|
}
|
|
93
120
|
const nodeToInsert = getNodeToInsert(node);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import DebugManager from '../../core/utils/debug-manager.js';
|
|
2
|
+
import {Observable} from '../../core/data/Observable';
|
|
2
3
|
|
|
3
4
|
export default function HistoryRouter() {
|
|
4
5
|
|
|
@@ -12,8 +13,9 @@ export default function HistoryRouter() {
|
|
|
12
13
|
if(window.history.state && window.history.state.path === path) {
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const resolvedParams = Observable.value(params);
|
|
17
|
+
window.history.pushState({ name: route.name(), params: resolvedParams, path}, route.name() || path , path);
|
|
18
|
+
this.handleRouteChange(route, resolvedParams, query, path);
|
|
17
19
|
} catch (e) {
|
|
18
20
|
DebugManager.error('HistoryRouter', 'Error in pushState', e);
|
|
19
21
|
}
|
|
@@ -29,6 +29,7 @@ export default function FormControlRender($desc, instance) {
|
|
|
29
29
|
fields: fieldsObject,
|
|
30
30
|
errors: errorsSummary,
|
|
31
31
|
form: instance,
|
|
32
|
+
data: dataProxy(fieldsObject),
|
|
32
33
|
}, instance);
|
|
33
34
|
|
|
34
35
|
if(!((form instanceof HTMLFormElement) || form?.$element instanceof HTMLFormElement)) {
|
|
@@ -44,6 +45,17 @@ export default function FormControlRender($desc, instance) {
|
|
|
44
45
|
return form;
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
const dataProxy = (fieldsObject) => {
|
|
49
|
+
const data = {};
|
|
50
|
+
for(const name in fieldsObject) {
|
|
51
|
+
if(!fieldsObject[name]?.$model) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
data[name] = fieldsObject[name].$model();
|
|
55
|
+
}
|
|
56
|
+
return data;
|
|
57
|
+
};
|
|
58
|
+
|
|
47
59
|
const buildDefaultLayout = ({ fields, errors, form }) => {
|
|
48
60
|
return Form({ class: 'form-control-default', ...form.resolveProps() }, [
|
|
49
61
|
...Object.values(fields),
|
|
@@ -35,9 +35,9 @@ export default function PopoverRender($desc, instance, classPrefix = 'popover')
|
|
|
35
35
|
: $desc.trigger).toNdElement();
|
|
36
36
|
|
|
37
37
|
const editableProps = instance.getEditableProps();
|
|
38
|
-
const toUnit = v => v + 'px';
|
|
39
38
|
|
|
40
39
|
const popoverId = classPrefix+'-nd-' + (++$popoverId);
|
|
40
|
+
const toUnit = v => v + 'px';
|
|
41
41
|
const $x = Observable(10).intercept(toUnit);
|
|
42
42
|
const $y = Observable(0).intercept(toUnit);
|
|
43
43
|
|
|
@@ -48,7 +48,7 @@ export default function PopoverRender($desc, instance, classPrefix = 'popover')
|
|
|
48
48
|
editableProps.class.add(classPrefix);
|
|
49
49
|
}
|
|
50
50
|
editableProps.class.add('is-'+$desc.variant);
|
|
51
|
-
editableProps.style.add({left: $x, top: $y});
|
|
51
|
+
editableProps.style.add({ '--popover-left-position': $x, '--popover-top-position': $y});
|
|
52
52
|
|
|
53
53
|
const popover = Div({
|
|
54
54
|
popover: 'manual',
|
|
@@ -134,8 +134,8 @@ export default function PopoverRender($desc, instance, classPrefix = 'popover')
|
|
|
134
134
|
}[side];
|
|
135
135
|
|
|
136
136
|
Object.assign(popoverArrow.style, {
|
|
137
|
-
left: arrowData.x != null ?
|
|
138
|
-
top: arrowData.y != null ?
|
|
137
|
+
left: arrowData.x != null ? arrowData.x + 'px' : '',
|
|
138
|
+
top: arrowData.y != null ? arrowData.y + 'px' : '',
|
|
139
139
|
[staticSide]: '-4px',
|
|
140
140
|
});
|
|
141
141
|
|
|
@@ -14,8 +14,11 @@
|
|
|
14
14
|
--popover-arrow-size: 8px;
|
|
15
15
|
--popover-animation-duration: 0.15s;
|
|
16
16
|
|
|
17
|
-
--popover-left-offset:
|
|
18
|
-
--popover-top-offset:
|
|
17
|
+
--popover-left-offset: 0px;
|
|
18
|
+
--popover-top-offset: 0px;
|
|
19
|
+
|
|
20
|
+
--popover-top-position: 0px;
|
|
21
|
+
--popover-left-position: 0px;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
|
|
@@ -45,6 +48,8 @@
|
|
|
45
48
|
padding: 0;
|
|
46
49
|
inset: unset;
|
|
47
50
|
overflow: initial;
|
|
51
|
+
top: calc(var(--popover-top-position) + var(--popover-top-offset));
|
|
52
|
+
left: calc(var(--popover-left-position) + var(--popover-left-offset));
|
|
48
53
|
|
|
49
54
|
&.is-primary {
|
|
50
55
|
--popover-bg: var(--color-primary);
|
package/types/router.d.ts
CHANGED
|
@@ -73,7 +73,9 @@ export interface RouterStatic {
|
|
|
73
73
|
create(options: { mode: 'memory' | 'history' | 'hash'; name?: string; entry?: string }, callback: (router: Router) => void): Router;
|
|
74
74
|
get(name?: string): Router;
|
|
75
75
|
push(target: string | { name: string; params?: RouteParams; query?: QueryParams }, name?: string): void;
|
|
76
|
+
pushTo(routeName: string, params?: RouteParams, routerName?: string): void;
|
|
76
77
|
replace(target: string | { name: string; params?: RouteParams; query?: QueryParams }, name?: string): void;
|
|
78
|
+
replaceTo(routeName: string, params?: RouteParams, routerName?: string): void;
|
|
77
79
|
forward(name?: string): void;
|
|
78
80
|
back(name?: string): void;
|
|
79
81
|
}
|