native-document 1.0.187 → 1.0.188
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/button/CopyButton.js +37 -0
- package/src/components/button/PasteButton.js +32 -0
- package/src/components/button/ResetButton.js +5 -0
- package/src/components/button/SubmitButton.js +5 -0
- package/src/components/button/index.js +8 -0
- package/src/components/button/types/Button.d.ts +0 -2
- package/src/components/button/types/CopyButton.d.ts +16 -0
- package/src/components/button/types/PasteButton.d.ts +16 -0
- package/src/components/button/types/ResetButton.d.ts +6 -0
- package/src/components/button/types/SubmitButton.d.ts +6 -0
- package/src/components/form/field/types/RadioField.js +10 -0
- package/src/components/form/types/fields/RadioField.d.ts +2 -0
- package/src/components/index.d.ts +4 -0
- package/src/components/table/DataTable.js +8 -4
- package/src/core/data/ObservableArray.js +7 -3
- package/src/router/Route.js +14 -3
- package/src/ui/components/button/CopyButtonRender.js +13 -0
- package/src/ui/components/button/PasteButtonRender.js +14 -0
- package/src/ui/components/form/fields/RadioFieldRender.js +7 -2
- package/src/ui/index.js +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.188",
|
|
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",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import BaseComponent from '../BaseComponent';
|
|
2
|
+
import Button from './Button';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export default function CopyButton(content, props){
|
|
6
|
+
|
|
7
|
+
if(!(this instanceof CopyButton)) {
|
|
8
|
+
return new CopyButton(content, props);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
Button.call(this, content, props);
|
|
12
|
+
|
|
13
|
+
Object.assign(this.$description, {
|
|
14
|
+
target: null,
|
|
15
|
+
content,
|
|
16
|
+
props,
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
BaseComponent.extends(CopyButton, Button);
|
|
22
|
+
|
|
23
|
+
CopyButton.defaultTemplate = null;
|
|
24
|
+
CopyButton.use = function (render){
|
|
25
|
+
CopyButton.defaultTemplate = render;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param {Observable} $observable
|
|
31
|
+
* @returns {CopyButton}
|
|
32
|
+
*/
|
|
33
|
+
CopyButton.prototype.from = function($observable) {
|
|
34
|
+
this.$description.target = $observable;
|
|
35
|
+
return this;
|
|
36
|
+
};
|
|
37
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import Button from './Button';
|
|
2
|
+
import BaseComponent from '../BaseComponent';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export default function PasteButton(content, props) {
|
|
6
|
+
|
|
7
|
+
if(!(this instanceof PasteButton)) {
|
|
8
|
+
return new PasteButton(content, props);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
Button.call(this, content, props);
|
|
12
|
+
|
|
13
|
+
Object.assign(this.$description, {
|
|
14
|
+
content,
|
|
15
|
+
props,
|
|
16
|
+
target: null,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
BaseComponent.extends(PasteButton, Button);
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
PasteButton.defaultTemplate = null;
|
|
24
|
+
PasteButton.use = function (render){
|
|
25
|
+
PasteButton.defaultTemplate = render;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
PasteButton.prototype.into = function($observable) {
|
|
30
|
+
this.$description.target = $observable;
|
|
31
|
+
return this;
|
|
32
|
+
};
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import Button from './Button';
|
|
2
|
+
import SubmitButton from './SubmitButton';
|
|
3
|
+
import ResetButton from './ResetButton';
|
|
4
|
+
import PasteButton from './PasteButton';
|
|
5
|
+
import CopyButton from './CopyButton';
|
|
2
6
|
|
|
3
7
|
export {
|
|
4
8
|
Button,
|
|
9
|
+
SubmitButton,
|
|
10
|
+
ResetButton,
|
|
11
|
+
PasteButton,
|
|
12
|
+
CopyButton,
|
|
5
13
|
};
|
|
@@ -53,10 +53,8 @@ export interface ButtonInterface extends BaseComponent {
|
|
|
53
53
|
export declare function Button(label: ValidChild, props?: Record<string, unknown>): ButtonInterface;
|
|
54
54
|
export declare namespace Button {
|
|
55
55
|
|
|
56
|
-
|
|
57
56
|
function use(template: (description: ButtonDescription, instance: ButtonInterface) => ValidChild): void;
|
|
58
57
|
function preset(name: string, callback: (instance: ButtonInterface) => ButtonInterface): void;
|
|
59
58
|
function presets(presets: Record<string, (instance: ButtonInterface) => ButtonInterface>): void;
|
|
60
59
|
|
|
61
|
-
|
|
62
60
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {ButtonInterface} from "./Button";
|
|
2
|
+
import {ObservableItem} from "../../../../types/observable";
|
|
3
|
+
import {ValidChild} from "../../../../types/elements";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export interface CopyButtonInterface extends ButtonInterface{
|
|
7
|
+
|
|
8
|
+
from($observable: ObservableItem): this;
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
export declare function CopyButton(label: ValidChild, props?: Record<string, unknown>): CopyButtonInterface;
|
|
12
|
+
export declare namespace CopyButton {
|
|
13
|
+
|
|
14
|
+
function use(template: (description: ButtonInterface, instance: ButtonInterface) => ValidChild): void;
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {ButtonDescription, ButtonInterface} from "./Button";
|
|
2
|
+
import {ObservableItem} from "../../../../types/observable";
|
|
3
|
+
import type {ValidChild} from "../../../../types/elements";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export interface PasteButtonInterface extends ButtonInterface{
|
|
7
|
+
|
|
8
|
+
into($observable: ObservableItem): this;
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
export declare function PasteButton(label: ValidChild, props?: Record<string, unknown>): PasteButtonInterface;
|
|
12
|
+
export declare namespace PasteButton {
|
|
13
|
+
|
|
14
|
+
function use(template: (description: ButtonDescription, instance: ButtonInterface) => ValidChild): void;
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -39,6 +39,7 @@ export default function RadioField(name, props = {}) {
|
|
|
39
39
|
options: [],
|
|
40
40
|
layout: 'vertical',
|
|
41
41
|
checked: false,
|
|
42
|
+
renderItem: null,
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -142,4 +143,13 @@ RadioField.prototype.vertical = function() {
|
|
|
142
143
|
RadioField.prototype.grid = function() {
|
|
143
144
|
this.$description.layout = 'grid';
|
|
144
145
|
return this;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @param {Function} renderFn
|
|
150
|
+
* @returns {RadioField}
|
|
151
|
+
*/
|
|
152
|
+
RadioField.prototype.renderItem = function(renderFn) {
|
|
153
|
+
this.$description.renderItem = renderFn;
|
|
154
|
+
return this;
|
|
145
155
|
};
|
|
@@ -2,6 +2,7 @@ import type { ValidChild } from '../../../../../types/elements';
|
|
|
2
2
|
import type { ObservableItem } from '../../../../../types/observable';
|
|
3
3
|
import type { GlobalAttributes } from '../../../../../types/globals';
|
|
4
4
|
import type { FieldInterface } from '../Field';
|
|
5
|
+
import {HTMLInputElement} from "happy-dom";
|
|
5
6
|
|
|
6
7
|
interface RadioOption {
|
|
7
8
|
value: unknown;
|
|
@@ -35,6 +36,7 @@ export interface RadioFieldInterface extends Omit<FieldInterface, 'render' | 'mo
|
|
|
35
36
|
horizontal(): this;
|
|
36
37
|
vertical(): this;
|
|
37
38
|
grid(): this;
|
|
39
|
+
renderItem(item: (input: HTMLInputElement, data: RadioOption) => ValidChild): this;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
|
|
@@ -31,6 +31,10 @@ export type { BreadCrumb, BreadCrumbInterface, BreadCrumbDescription } from './b
|
|
|
31
31
|
|
|
32
32
|
// --- Button ------------------------------------------------------------------
|
|
33
33
|
export type { Button, ButtonInterface, ButtonDescription } from './button/types/Button';
|
|
34
|
+
export type { CopyButton } from './button/types/CopyButton';
|
|
35
|
+
export type { PasteButton } from './button/types/PasteButton';
|
|
36
|
+
export type { SubmitButton } from './button/types/SubmitButton';
|
|
37
|
+
export type { ResetButton } from './button/types/ResetButton';
|
|
34
38
|
|
|
35
39
|
// --- Card --------------------------------------------------------------------
|
|
36
40
|
export type { Card, CardInterface, CardDescription } from './card/types/Card';
|
|
@@ -363,20 +363,24 @@ DataTable.prototype.onSort = function(handler) {
|
|
|
363
363
|
// ---------------------------------------------
|
|
364
364
|
|
|
365
365
|
/**
|
|
366
|
-
* @param {
|
|
366
|
+
* @param {boolean} [enabled]
|
|
367
|
+
* @param {Observable} [model]
|
|
367
368
|
* @returns {this}
|
|
368
369
|
*/
|
|
369
|
-
DataTable.prototype.searchable = function(enabled = true) {
|
|
370
|
+
DataTable.prototype.searchable = function(enabled = true, model = null) {
|
|
370
371
|
this.$description.searchable = enabled;
|
|
372
|
+
this.$description.$search = model;
|
|
371
373
|
return this;
|
|
372
374
|
};
|
|
373
375
|
|
|
374
376
|
/**
|
|
375
|
-
* @param {
|
|
377
|
+
* @param {boolean} [enabled]
|
|
378
|
+
* @param {Record<string, *>?} filters
|
|
376
379
|
* @returns {this}
|
|
377
380
|
*/
|
|
378
|
-
DataTable.prototype.filterable = function(enabled = true) {
|
|
381
|
+
DataTable.prototype.filterable = function(enabled = true, filters = null) {
|
|
379
382
|
this.$description.filterable = enabled;
|
|
383
|
+
this.$description.defaultFilter = filters;
|
|
380
384
|
return this;
|
|
381
385
|
};
|
|
382
386
|
|
|
@@ -278,6 +278,7 @@ ObservableArray.prototype.populateAndRender = function(iteration, callback) {
|
|
|
278
278
|
* The filtered array updates automatically when source data or predicates change.
|
|
279
279
|
*
|
|
280
280
|
* @param {Object} predicates - Object mapping property names to filter conditions or functions
|
|
281
|
+
* @param {Observable[]?} dependencies - dependencies list when predicates is a function
|
|
281
282
|
* @returns {ObservableArray} A new observable array containing filtered items
|
|
282
283
|
* @example
|
|
283
284
|
* const users = Observable.array([
|
|
@@ -287,9 +288,9 @@ ObservableArray.prototype.populateAndRender = function(iteration, callback) {
|
|
|
287
288
|
*
|
|
288
289
|
* const adults = users.where({ age: (val) => val >= 18 });
|
|
289
290
|
*/
|
|
290
|
-
ObservableArray.prototype.where = function(predicates) {
|
|
291
|
+
ObservableArray.prototype.where = function(predicates, dependencies = null) {
|
|
291
292
|
if(typeof predicates === 'function') {
|
|
292
|
-
predicates = { _: predicates };
|
|
293
|
+
predicates = { _: predicates, dependencies };
|
|
293
294
|
}
|
|
294
295
|
const sourceArray = this;
|
|
295
296
|
const observableDependencies = [sourceArray];
|
|
@@ -322,7 +323,10 @@ ObservableArray.prototype.where = function(predicates) {
|
|
|
322
323
|
if(key === '_') {
|
|
323
324
|
if (!callback(item)) return false;
|
|
324
325
|
} else {
|
|
325
|
-
|
|
326
|
+
const valueSource = item[key];
|
|
327
|
+
if (!callback(valueSource?.__$Observable ? valueSource.val() : valueSource)) {
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
326
330
|
}
|
|
327
331
|
}
|
|
328
332
|
return true;
|
package/src/router/Route.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {trim} from '../core/utils/helpers.js';
|
|
2
|
+
import {Observable} from '../core/data/Observable';
|
|
2
3
|
|
|
3
4
|
export const RouteParamPatterns = {
|
|
4
5
|
id: '[0-9]+',
|
|
@@ -112,16 +113,26 @@ export function Route($path, $component, $options = {}) {
|
|
|
112
113
|
/**
|
|
113
114
|
* @param {{params: ?Object, query: ?Object, basePath: ?string}} configs
|
|
114
115
|
*/
|
|
115
|
-
this.url = function(configs) {
|
|
116
|
+
this.url = function(configs = {}) {
|
|
116
117
|
const path = $path.replace(/\{(.*?)}/ig, (block, definition) => {
|
|
117
118
|
const description = paramsExtractor(definition);
|
|
118
119
|
if(configs.params && configs.params[description.name]) {
|
|
119
|
-
|
|
120
|
+
const value = configs.params[description.name];
|
|
121
|
+
return value?.__$Observable ? value.val() : value;
|
|
120
122
|
}
|
|
121
123
|
throw new Error(`Missing parameter '${description.name}'`);
|
|
122
124
|
});
|
|
123
125
|
|
|
124
|
-
|
|
126
|
+
let queries = null;
|
|
127
|
+
if(typeof configs.query === 'object') {
|
|
128
|
+
queries = {};
|
|
129
|
+
for(const property in configs.query) {
|
|
130
|
+
const value = configs.query[property];
|
|
131
|
+
queries[property] = value?.__$Observable ? value.val() : value;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const queryString = (queries) ? (new URLSearchParams(queries)).toString() : null;
|
|
125
136
|
return (configs.basePath ? configs.basePath : '') + (queryString ? `${path}?${queryString}` : path);
|
|
126
137
|
};
|
|
127
138
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import ButtonRender from './ButtonRender';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export default function CopyButtonRender($desc, instance) {
|
|
5
|
+
|
|
6
|
+
return ButtonRender($desc, instance).onClick(() => {
|
|
7
|
+
if(!$desc.target) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
navigator.clipboard.writeText($desc.target.val());
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {ButtonRender} from '../../index';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export default function PasteButtonRender($desc, instance) {
|
|
5
|
+
|
|
6
|
+
return ButtonRender($desc, instance).onClick(() => {
|
|
7
|
+
if(!$desc.target) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
navigator.clipboard.readText().then(text => {
|
|
11
|
+
$desc.target.set(text);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -47,7 +47,7 @@ const buildOptions = ($desc, instance) => {
|
|
|
47
47
|
instance.validate();
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
const buildOption = (option) => {
|
|
50
|
+
const buildOption = ($desc, option) => {
|
|
51
51
|
const optValue = option.value ?? option;
|
|
52
52
|
const optLabel = option.label ?? option;
|
|
53
53
|
const optId = ($desc.id || $desc.name) + '-' + optValue;
|
|
@@ -64,6 +64,10 @@ const buildOptions = ($desc, instance) => {
|
|
|
64
64
|
|
|
65
65
|
input.nd.onChange(() => onSelect(optValue));
|
|
66
66
|
|
|
67
|
+
if($desc.renderItem) {
|
|
68
|
+
return Div({class: 'field-radio-wrapper'}, $desc.renderItem(input, option));
|
|
69
|
+
}
|
|
70
|
+
|
|
67
71
|
return Div({class: 'field-radio-wrapper'}, [
|
|
68
72
|
input,
|
|
69
73
|
Label({class: 'field-radio-label', for: optId}, optLabel),
|
|
@@ -71,11 +75,12 @@ const buildOptions = ($desc, instance) => {
|
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
const isRequired = $desc.rules?.some(rule => rule.fn?.name === 'required');
|
|
78
|
+
const optionBuilder = buildOption.bind(null, $desc);
|
|
74
79
|
return Div({
|
|
75
80
|
class: 'field-radio-group is-' + ($desc.layout || 'vertical'),
|
|
76
81
|
// [a11y] role=radiogroup, aria-required
|
|
77
82
|
role: 'radiogroup',
|
|
78
83
|
...( isRequired ? { 'aria-required': 'true' } : {} ),
|
|
79
84
|
...($desc.elementsProps.wrapper || {}),
|
|
80
|
-
}, ForEachArray($options,
|
|
85
|
+
}, ForEachArray($options, optionBuilder));
|
|
81
86
|
};
|
package/src/ui/index.js
CHANGED
|
@@ -6,6 +6,8 @@ export { default as DividerRender } from './components/divider/DividerRender';
|
|
|
6
6
|
export { default as SkeletonRender } from './components/skeleton/SkeletonRender';
|
|
7
7
|
export { default as ProgressRender } from './components/progress/ProgressRender';
|
|
8
8
|
export { default as ButtonRender } from './components/button/ButtonRender';
|
|
9
|
+
export { default as CopyButtonRender } from './components/button/CopyButtonRender';
|
|
10
|
+
export { default as PasteButtonRender } from './components/button/PasteButtonRender';
|
|
9
11
|
export { default as AlertRender } from './components/alert/AlertRender';
|
|
10
12
|
export { default as ToastRender } from './components/toast/ToastRender';
|
|
11
13
|
export { default as PopoverRender } from './components/popover/PopoverRender';
|