native-document 1.0.139 → 1.0.140

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 (259) hide show
  1. package/components.js +1 -1
  2. package/devtools/ComponentRegistry.js +3 -2
  3. package/dist/native-document.components.min.css +1 -0
  4. package/dist/native-document.components.min.js +11618 -8748
  5. package/dist/native-document.dev.js +2645 -2166
  6. package/dist/native-document.dev.js.map +1 -1
  7. package/dist/native-document.min.js +1 -1
  8. package/index.js +1 -0
  9. package/package.json +5 -2
  10. package/rollup.config.js +5 -2
  11. package/src/components/$traits/has-draggable/HasDraggable.js +69 -0
  12. package/src/components/$traits/has-draggable/has-draggable.css +8 -0
  13. package/src/components/$traits/{HasItems.js → has-items/HasItems.js} +2 -11
  14. package/src/components/$traits/has-position/HasFullPosition.js +51 -0
  15. package/src/components/$traits/has-position/HasPosition.js +23 -0
  16. package/src/components/$traits/has-resizable/HasResizable.js +113 -0
  17. package/src/components/$traits/has-resizable/has-resizable.css +121 -0
  18. package/src/components/$traits/has-validation/HasValidation.js +86 -0
  19. package/src/components/BaseComponent.js +82 -7
  20. package/src/components/accordion/Accordion.js +37 -31
  21. package/src/components/accordion/AccordionItem.js +14 -21
  22. package/src/components/alert/Alert.js +48 -40
  23. package/src/components/avatar/Avatar.js +4 -3
  24. package/src/components/avatar/AvatarGroup.js +8 -2
  25. package/src/components/badge/Badge.js +7 -7
  26. package/src/components/base-component.css +0 -0
  27. package/src/components/breadcrumb/BreadCrumb.js +30 -21
  28. package/src/components/button/Button.js +3 -14
  29. package/src/components/context-menu/ContextMenu.js +49 -26
  30. package/src/components/dropdown/Dropdown.js +172 -34
  31. package/src/components/dropdown/DropdownDivider.js +4 -3
  32. package/src/components/dropdown/DropdownGroup.js +19 -19
  33. package/src/components/dropdown/DropdownItem.js +24 -18
  34. package/src/components/dropdown/helpers.js +52 -0
  35. package/src/components/form/FormControl.js +207 -108
  36. package/src/components/form/field/Field.js +106 -174
  37. package/src/components/form/field/FieldCollection.js +110 -203
  38. package/src/components/form/field/types/AutocompleteField.js +26 -5
  39. package/src/components/form/field/types/CheckboxField.js +4 -4
  40. package/src/components/form/field/types/CheckboxGroupField.js +11 -5
  41. package/src/components/form/field/types/ColorField.js +4 -4
  42. package/src/components/form/field/types/DateField.js +110 -18
  43. package/src/components/form/field/types/EmailField.js +2 -2
  44. package/src/components/form/field/types/FileField.js +87 -21
  45. package/src/components/form/field/types/HiddenField.js +4 -4
  46. package/src/components/form/field/types/ImageField.js +4 -4
  47. package/src/components/form/field/types/NumberField.js +5 -5
  48. package/src/components/form/field/types/PasswordField.js +28 -6
  49. package/src/components/form/field/types/RadioField.js +12 -8
  50. package/src/components/form/field/types/RangeField.js +29 -5
  51. package/src/components/form/field/types/SearchField.js +4 -4
  52. package/src/components/form/field/types/SelectField.js +75 -8
  53. package/src/components/form/field/types/StringField.js +4 -4
  54. package/src/components/form/field/types/TelField.js +4 -4
  55. package/src/components/form/field/types/TextAreaField.js +7 -5
  56. package/src/components/form/field/types/TimeField.js +52 -6
  57. package/src/components/form/field/types/UrlField.js +4 -5
  58. package/src/components/form/field/types/file-field-mode/FileAvatarMode.js +104 -0
  59. package/src/components/form/field/types/file-field-mode/FileDropzoneMode.js +59 -0
  60. package/src/components/form/field/types/file-field-mode/FileItemPreview.js +74 -0
  61. package/src/components/form/field/types/file-field-mode/FileNativeMode.js +21 -0
  62. package/src/components/form/field/types/file-field-mode/FileUploadButtonMode.js +59 -0
  63. package/src/components/form/field/types/file-field-mode/FileWallMode.js +53 -0
  64. package/src/components/form/index.js +14 -2
  65. package/src/components/form/validation/Validation.js +9 -0
  66. package/src/components/list/List.js +1 -1
  67. package/src/components/list/ListGroup.js +1 -1
  68. package/src/components/menu/HasMenuItem.js +133 -0
  69. package/src/components/menu/Menu.js +47 -56
  70. package/src/components/menu/MenuGroup.js +36 -8
  71. package/src/components/menu/MenuItem.js +24 -10
  72. package/src/components/menu/MenuLink.js +2 -0
  73. package/src/components/modal/Modal.js +153 -23
  74. package/src/components/pagination/Pagination.js +55 -21
  75. package/src/components/popover/Popover.js +127 -40
  76. package/src/components/progress/Progress.js +14 -24
  77. package/src/components/skeleton/Skeleton.js +36 -13
  78. package/src/components/slider/Slider.js +96 -70
  79. package/src/components/spinner/Spinner.js +4 -2
  80. package/src/components/splitter/Splitter.js +15 -8
  81. package/src/components/splitter/SplitterGutter.js +28 -7
  82. package/src/components/splitter/SplitterPanel.js +9 -15
  83. package/src/components/splitter/index.js +3 -1
  84. package/src/components/stacks/AbsoluteStack.js +33 -0
  85. package/src/components/stacks/FixedStack.js +33 -0
  86. package/src/components/stacks/PositionStack.js +146 -0
  87. package/src/components/stacks/RelativeStack.js +33 -0
  88. package/src/components/{layouts → stacks}/Stack.js +22 -3
  89. package/src/components/{layouts → stacks}/index.js +6 -4
  90. package/src/components/stepper/Stepper.js +159 -67
  91. package/src/components/stepper/StepperStep.js +49 -12
  92. package/src/components/switch/Switch.js +59 -29
  93. package/src/components/switch/index.js +6 -0
  94. package/src/components/table/Column.js +22 -26
  95. package/src/components/table/ColumnGroup.js +4 -13
  96. package/src/components/table/DataTable.js +388 -103
  97. package/src/components/table/SimpleTable.js +28 -143
  98. package/src/components/tabs/Tabs.js +142 -44
  99. package/src/components/toast/Toast.js +40 -35
  100. package/src/components/tooltip/Tooltip.js +152 -35
  101. package/src/core/data/ObservableArray.js +94 -30
  102. package/src/core/data/ObservableChecker.js +20 -75
  103. package/src/core/data/ObservableItem.js +35 -3
  104. package/src/core/data/observable-helpers/computed.js +2 -1
  105. package/src/core/data/observable-helpers/object.js +13 -8
  106. package/src/core/data/observable-helpers/observable.is-to.js +196 -0
  107. package/src/core/elements/anchor/anchor.js +3 -2
  108. package/src/core/elements/control/for-each-array.js +44 -30
  109. package/src/core/elements/control/for-each.js +6 -3
  110. package/src/core/elements/control/show-if.js +11 -6
  111. package/src/core/elements/control/switch.js +2 -1
  112. package/src/core/elements/index.js +1 -1
  113. package/src/core/elements/svg.js +61 -0
  114. package/src/core/utils/HasEventEmitter.js +6 -0
  115. package/src/core/utils/debug-manager.js +2 -5
  116. package/src/core/utils/filters/standard.js +2 -1
  117. package/src/core/utils/property-accumulator.js +35 -6
  118. package/src/core/utils/shortcut-manager.js +242 -0
  119. package/src/core/utils/validator.js +1 -1
  120. package/src/core/wrappers/AttributesWrapper.js +41 -4
  121. package/src/core/wrappers/DocumentObserver.js +0 -1
  122. package/src/core/wrappers/HtmlElementWrapper.js +1 -1
  123. package/src/core/wrappers/NDElement.js +15 -2
  124. package/src/core/wrappers/SvgElementWrapper.js +15 -0
  125. package/src/core/wrappers/prototypes/attributes-extensions.js +4 -1
  126. package/src/core/wrappers/prototypes/nd-element-extensions.js +8 -1
  127. package/src/router/Router.js +0 -1
  128. package/src/ui/components/accordion/AccordionItemRender.js +63 -0
  129. package/src/ui/components/accordion/AccordionRender.js +34 -0
  130. package/src/ui/components/accordion/accordion.css +121 -0
  131. package/src/ui/components/alert/AlertRender.js +80 -0
  132. package/src/ui/components/alert/alert.css +163 -0
  133. package/src/ui/components/avatar/avata-group/AvatarGroupRender.js +49 -0
  134. package/src/ui/components/avatar/avata-group/avatar-group.css +38 -0
  135. package/src/ui/components/avatar/avatar/AvatarRender.js +87 -0
  136. package/src/ui/components/avatar/avatar/avatar.css +189 -0
  137. package/src/ui/components/badge/BadgeRender.js +24 -0
  138. package/src/ui/components/badge/badge.css +168 -0
  139. package/src/ui/components/breadcrumb/BreadcrumbRender.js +43 -0
  140. package/src/ui/components/breadcrumb/breadcrumb.css +55 -0
  141. package/src/ui/components/button/ButtonRender.js +65 -0
  142. package/src/ui/components/button/button.css +288 -354
  143. package/src/ui/components/contextmenu/ContextmenuRender.js +70 -0
  144. package/src/ui/components/contextmenu/contextmenu.css +36 -0
  145. package/src/ui/components/divider/DividerRender.js +70 -0
  146. package/src/ui/components/divider/divider.css +70 -0
  147. package/src/ui/components/dropdown/DropdownRender.js +92 -0
  148. package/src/ui/components/dropdown/divider/DropdownDividerRender.js +9 -0
  149. package/src/ui/components/dropdown/divider/dropdown-divider.css +0 -0
  150. package/src/ui/components/dropdown/dropdown.css +179 -0
  151. package/src/ui/components/dropdown/group/DropdownGroupRender.js +23 -0
  152. package/src/ui/components/dropdown/group/dropdown-group.css +0 -0
  153. package/src/ui/components/dropdown/item/DropdownItemRender.js +29 -0
  154. package/src/ui/components/dropdown/item/dropdown-item.css +0 -0
  155. package/src/ui/components/form/FieldCollectionRender.js +110 -0
  156. package/src/ui/components/form/FormControlRender.js +84 -0
  157. package/src/ui/components/form/field-collection.css +55 -0
  158. package/src/ui/components/form/fields/AutocompleteFieldRender.js +143 -0
  159. package/src/ui/components/form/fields/CheckboxFieldRender.js +59 -0
  160. package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +92 -0
  161. package/src/ui/components/form/fields/ColorFieldRender.js +30 -0
  162. package/src/ui/components/form/fields/DateFieldRender.js +154 -0
  163. package/src/ui/components/form/fields/EmailFieldRender.js +5 -0
  164. package/src/ui/components/form/fields/FieldRender.js +117 -0
  165. package/src/ui/components/form/fields/FileFieldRender.js +41 -0
  166. package/src/ui/components/form/fields/HiddenFieldRender.js +14 -0
  167. package/src/ui/components/form/fields/ImageFieldRender.js +0 -0
  168. package/src/ui/components/form/fields/NumberFieldRender.js +52 -0
  169. package/src/ui/components/form/fields/PasswordFieldRender.js +65 -0
  170. package/src/ui/components/form/fields/RadioFieldRender.js +77 -0
  171. package/src/ui/components/form/fields/RangeFieldRender.js +121 -0
  172. package/src/ui/components/form/fields/SelectFieldRender.js +248 -0
  173. package/src/ui/components/form/fields/SliderFieldRender.js +359 -0
  174. package/src/ui/components/form/fields/StringFieldRender.js +6 -0
  175. package/src/ui/components/form/fields/TelFieldRender.js +6 -0
  176. package/src/ui/components/form/fields/TextAreaFieldRender.js +96 -0
  177. package/src/ui/components/form/fields/TimeFieldRender.js +141 -0
  178. package/src/ui/components/form/fields/UrlFieldRender.js +6 -0
  179. package/src/ui/components/form/fields/date-field.css +32 -0
  180. package/src/ui/components/form/fields/field.css +402 -0
  181. package/src/ui/components/form/fields/file-field.css +79 -0
  182. package/src/ui/components/form/fields/password-field.css +50 -0
  183. package/src/ui/components/form/fields/range-field.css +120 -0
  184. package/src/ui/components/form/fields/slider.css +195 -0
  185. package/src/ui/components/form/file-upload-mode/FileAvatarModeRender.js +143 -0
  186. package/src/ui/components/form/file-upload-mode/FileDropzoneModeRender.js +108 -0
  187. package/src/ui/components/form/file-upload-mode/FileNativeModeRender.js +22 -0
  188. package/src/ui/components/form/file-upload-mode/FileUploadButtonModeRender.js +89 -0
  189. package/src/ui/components/form/file-upload-mode/FileWallModeRender.js +91 -0
  190. package/src/ui/components/form/file-upload-mode/file-avatar-mode.css +139 -0
  191. package/src/ui/components/form/file-upload-mode/file-dropzone-mode.css +88 -0
  192. package/src/ui/components/form/file-upload-mode/file-upload-button-mode.css +44 -0
  193. package/src/ui/components/form/file-upload-mode/file-wall-mode.css +88 -0
  194. package/src/ui/components/form/form-control.css +40 -0
  195. package/src/ui/components/form/helpers.js +112 -0
  196. package/src/ui/components/form/index.js +61 -0
  197. package/src/ui/components/menu/MenuDividerRender.js +12 -0
  198. package/src/ui/components/menu/MenuGroupRender.js +60 -0
  199. package/src/ui/components/menu/MenuItemRender.js +57 -0
  200. package/src/ui/components/menu/MenuLinkRender.js +55 -0
  201. package/src/ui/components/menu/MenuRender.js +21 -0
  202. package/src/ui/components/menu/helpers.js +121 -0
  203. package/src/ui/components/menu/menu.css +308 -0
  204. package/src/ui/components/modal/ModalRender.js +119 -0
  205. package/src/ui/components/modal/modal.css +156 -0
  206. package/src/ui/components/pagination/PaginationRender.js +112 -0
  207. package/src/ui/components/pagination/pagination.css +63 -0
  208. package/src/ui/components/popover/PopoverRender.js +234 -0
  209. package/src/ui/components/popover/popover.css +139 -0
  210. package/src/ui/components/progress/ProgressRender.js +168 -0
  211. package/src/ui/components/progress/progress.css +197 -0
  212. package/src/ui/components/skeleton/SkeletonRender.js +79 -0
  213. package/src/ui/components/skeleton/skeleton.css +154 -0
  214. package/src/ui/components/spinner/SpinnerRender.js +46 -0
  215. package/src/ui/components/spinner/spinner.css +152 -0
  216. package/src/ui/components/splitter/SplitterGutterRender.js +94 -0
  217. package/src/ui/components/splitter/SplitterPanelRender.js +38 -0
  218. package/src/ui/components/splitter/SplitterRender.js +74 -0
  219. package/src/ui/components/splitter/splitter.css +128 -0
  220. package/src/ui/components/stacks/PositionStackRender.js +38 -0
  221. package/src/ui/components/stacks/StackRender.js +42 -0
  222. package/src/ui/components/stacks/absolute-stack/AbsoluteStackRender.js +5 -0
  223. package/src/ui/components/stacks/fixed-stack/FixedStackRender.js +5 -0
  224. package/src/ui/components/stacks/h-stack/HStackRender.js +7 -0
  225. package/src/ui/components/stacks/h-stack/h-stack.css +4 -0
  226. package/src/ui/components/stacks/index.js +15 -0
  227. package/src/ui/components/stacks/position-stack.css +62 -0
  228. package/src/ui/components/stacks/relative-stack/RelativeStackRender.js +7 -0
  229. package/src/ui/components/stacks/relative-stack/relative-stack.css +3 -0
  230. package/src/ui/components/stacks/stack.css +78 -0
  231. package/src/ui/components/stacks/v-stack/VStackRender.js +5 -0
  232. package/src/ui/components/stacks/v-stack/v-stack.css +4 -0
  233. package/src/ui/components/stepper/StepperRender.js +70 -0
  234. package/src/ui/components/stepper/StepperStepRender.js +67 -0
  235. package/src/ui/components/stepper/stepper.css +359 -0
  236. package/src/ui/components/switch/SwitchRender.js +82 -0
  237. package/src/ui/components/switch/switch.css +143 -0
  238. package/src/ui/components/table/data-table/DataTableRender.js +49 -0
  239. package/src/ui/components/table/data-table/bulk-actions.js +35 -0
  240. package/src/ui/components/table/data-table/data-table.css +246 -0
  241. package/src/ui/components/table/data-table/pagination.js +56 -0
  242. package/src/ui/components/table/data-table/tables.js +363 -0
  243. package/src/ui/components/table/data-table/toolbar.js +67 -0
  244. package/src/ui/components/table/simple-table/SimpleTableRender.js +188 -0
  245. package/src/ui/components/table/simple-table/simple-table.css +50 -0
  246. package/src/ui/components/tabs/TabsRender.js +226 -0
  247. package/src/ui/components/tabs/tabs.css +253 -0
  248. package/src/ui/components/toast/ToastRender.js +98 -0
  249. package/src/ui/components/toast/toast.css +201 -0
  250. package/src/ui/components/tooltip/TooltipRender.js +8 -0
  251. package/src/ui/components/tooltip/tooltip.css +113 -0
  252. package/src/ui/index.js +82 -0
  253. package/src/ui/tokens/colors-dark.scss +2 -1
  254. package/src/ui/tokens/reset.scss +3 -0
  255. package/types/control-flow.d.ts +2 -2
  256. package/src/components/layouts/ZStack.js +0 -41
  257. package/src/ui/components/button/button.render.js +0 -63
  258. /package/src/components/{layouts → stacks}/HStack.js +0 -0
  259. /package/src/components/{layouts → stacks}/VStack.js +0 -0
@@ -0,0 +1,196 @@
1
+ import ObservableItem from "../ObservableItem";
2
+ import { Observable } from "../Observable";
3
+
4
+ const $computed = (fn, dependencies) => Observable.computed(fn, dependencies);
5
+ const $checker = (obs, fn) => obs.transform(fn);
6
+
7
+ //
8
+ // is... -> ObservableChecker<boolean>
9
+ //
10
+
11
+ ObservableItem.prototype.isEqualTo = function (value) {
12
+ if (value?.__$Observable) {
13
+ return $computed((a, b) => a === b, [this, value]);
14
+ }
15
+ return $checker(this, x => x === value);
16
+ };
17
+
18
+ ObservableItem.prototype.isNotEqualTo = function (value) {
19
+ if (value?.__$Observable) {
20
+ return $computed((a, b) => a !== b, [this, value]);
21
+ }
22
+ return $checker(this, x => x !== value);
23
+ };
24
+
25
+ ObservableItem.prototype.isGreaterThan = function (value) {
26
+ if (value?.__$Observable) {
27
+ return $computed((a, b) => a > b, [this, value]);
28
+ }
29
+ return $checker(this, x => x > value);
30
+ };
31
+
32
+ ObservableItem.prototype.isGreaterThanOrEqualTo = function (value) {
33
+ if (value?.__$Observable) {
34
+ return $computed((a, b) => a >= b, [this, value]);
35
+ }
36
+ return $checker(this, x => x >= value);
37
+ };
38
+
39
+ ObservableItem.prototype.isLessThan = function (value) {
40
+ if (value?.__$Observable) {
41
+ return $computed((a, b) => a < b, [this, value]);
42
+ }
43
+ return $checker(this, x => x < value);
44
+ };
45
+
46
+ ObservableItem.prototype.isLessThanOrEqualTo = function (value) {
47
+ if (value?.__$Observable) {
48
+ return $computed((a, b) => a <= b, [this, value]);
49
+ }
50
+ return $checker(this, x => x <= value);
51
+ };
52
+
53
+ ObservableItem.prototype.isBetween = function (min, max) {
54
+ if (min.__$Observable && max.__$Observable) {
55
+ return $computed((x, a, b) => x >= a && x <= b, [this, min, max]);
56
+ }
57
+ if (min.__$Observable) {
58
+ return $computed((x, a) => x >= a && x <= max, [this, min]);
59
+ }
60
+ if (max.__$Observable) {
61
+ return $computed((x, b) => x >= min && x <= b, [this, max]);
62
+ }
63
+ return $checker(this, x => x >= min && x <= max);
64
+ };
65
+
66
+ ObservableItem.prototype.isNull = function () {
67
+ return $checker(this, x => x == null);
68
+ };
69
+
70
+ ObservableItem.prototype.isTruthy = function () {
71
+ return $checker(this, x => !!x);
72
+ };
73
+
74
+ ObservableItem.prototype.isFalsy = function () {
75
+ return $checker(this, x => !x);
76
+ };
77
+
78
+ ObservableItem.prototype.isStartingWith = function (str) {
79
+ if (str?.__$Observable) {
80
+ return $computed((a, b) => String(a).startsWith(b), [this, str]);
81
+ }
82
+ return $checker(this, x => String(x).startsWith(str));
83
+ };
84
+
85
+ ObservableItem.prototype.isEndingWith = function (str) {
86
+ if (str?.__$Observable) {
87
+ return $computed((a, b) => String(a).endsWith(b), [this, str]);
88
+ }
89
+ return $checker(this, x => String(x).endsWith(str));
90
+ };
91
+
92
+ ObservableItem.prototype.isMatchingPattern = function (regex) {
93
+ if (regex?.__$Observable) {
94
+ return $computed((a, b) => new RegExp(b).test(String(a)), [this, regex]);
95
+ }
96
+ return $checker(this, x => regex.test(String(x)));
97
+ };
98
+
99
+ ObservableItem.prototype.isEmpty = function () {
100
+ return $checker(this, x => x == null || x === '' || (Array.isArray(x) && x.length === 0));
101
+ };
102
+
103
+ ObservableItem.prototype.isNotEmpty = function () {
104
+ return $checker(this, x => x == null || x === '' || (Array.isArray(x) && x.length !== 0));
105
+ };
106
+
107
+ ObservableItem.prototype.isIncludes = function (value) {
108
+ if (value?.__$Observable) {
109
+ return $computed((a, b) => {
110
+ if (Array.isArray(a)) return a.includes(b);
111
+ return String(a).includes(String(b));
112
+ }, [this, value]);
113
+ }
114
+ return $checker(this, x => {
115
+ if (Array.isArray(x)) return x.includes(value);
116
+ return String(x).includes(String(value));
117
+ });
118
+ };
119
+
120
+ ObservableItem.prototype.isIncludedIn = function (array) {
121
+ if (array?.__$Observable) {
122
+ return $computed((a, b) => b.includes(a), [this, array]);
123
+ }
124
+ return $checker(this, x => array.includes(x));
125
+ };
126
+
127
+ ObservableItem.prototype.isOneOf = ObservableItem.prototype.isIncludedIn;
128
+
129
+ ObservableItem.prototype.isHaving = function (key) {
130
+ if (key?.__$Observable) {
131
+ return $computed((a, b) => b in Object(a), [this, key]);
132
+ }
133
+ return $checker(this, x => key in Object(x));
134
+ };
135
+
136
+ //
137
+ // to... -> ObservableChecker<any>
138
+ //
139
+
140
+ ObservableItem.prototype.toUpperCase = function () {
141
+ return $checker(this, x => String(x).toUpperCase());
142
+ };
143
+
144
+ ObservableItem.prototype.toLowerCase = function () {
145
+ return $checker(this, x => String(x).toLowerCase());
146
+ };
147
+
148
+ ObservableItem.prototype.toTrimmed = function () {
149
+ return $checker(this, x => String(x).trim());
150
+ };
151
+
152
+ ObservableItem.prototype.toBoolean = function () {
153
+ return $checker(this, x => !!x);
154
+ };
155
+
156
+ ObservableItem.prototype.toLiteral = function (template, placeholder = '${v}') {
157
+ return $checker(this, x => template.replace(placeholder, x));
158
+ };
159
+
160
+ ObservableItem.prototype.toFormatted = ObservableItem.prototype.toLiteral;
161
+
162
+ ObservableItem.prototype.toProperty = function (key) {
163
+ const keys = key.split('.');
164
+ return $checker(this, x => {
165
+ let value = x;
166
+ for (const k of keys) {
167
+ if (value == null) return undefined;
168
+ value = value[k];
169
+ }
170
+ return value;
171
+ });
172
+ };
173
+
174
+ ObservableItem.prototype.toLength = function () {
175
+ return $checker(this, x => (x == null ? 0 : x.length));
176
+ };
177
+
178
+ ObservableItem.prototype.toClamped = function (min, max) {
179
+ if (min.__$Observable && max.__$Observable) {
180
+ return $computed((x, a, b) => Math.min(Math.max(x, a), b), [this, min, max]);
181
+ }
182
+ if (min.__$Observable) {
183
+ return $computed((x, a) => Math.min(Math.max(x, a), max), [this, min]);
184
+ }
185
+ if (max.__$Observable) {
186
+ return $computed((x, b) => Math.min(Math.max(x, min), b), [this, max]);
187
+ }
188
+ return $checker(this, x => Math.min(Math.max(x, min), max));
189
+ };
190
+
191
+ ObservableItem.prototype.toPercent = function (total) {
192
+ if (total?.__$Observable) {
193
+ return $computed((a, b) => (b === 0 ? 0 : (a / b) * 100), [this, total]);
194
+ }
195
+ return $checker(this, x => (total === 0 ? 0 : (x / total) * 100));
196
+ };
@@ -24,12 +24,12 @@ export default function Anchor(name, isUniqueChild = false) {
24
24
  const isParentUniqueChild = isUniqueChild
25
25
  ? () => true: (parent) => (parent.firstChild === anchorStart && parent.lastChild === anchorEnd)
26
26
 
27
- const insertBefore = function(parent, child, target) {
27
+ const insertBefore = (parent, child, target) => {
28
28
  const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
29
29
  insertBeforeRaw(parent, childElement, target);
30
30
  };
31
31
 
32
- const insertBeforeRaw = function(parent, child, target) {
32
+ const insertBeforeRaw = (parent, child, target) => {
33
33
  if(parent === anchorFragment) {
34
34
  parent.nativeInsertBefore(child, target);
35
35
  return;
@@ -129,6 +129,7 @@ export default function Anchor(name, isUniqueChild = false) {
129
129
  anchorStart.remove();
130
130
  anchorEnd.remove();
131
131
  };
132
+ anchorFragment.delete = anchorFragment.removeWithAnchors;
132
133
 
133
134
  anchorFragment.replaceContent = function(child) {
134
135
  const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
@@ -1,19 +1,19 @@
1
1
  import Anchor from "../anchor/anchor";
2
- import {Observable} from "../../data/Observable";
3
- import Validator from "../../utils/validator";
4
2
  import { ElementCreator } from "../../wrappers/ElementCreator";
5
3
  import NativeDocumentError from "../../errors/NativeDocumentError";
6
4
 
7
5
 
8
6
  const CREATE_AND_CACHE_ACTIONS = new Set(['clear', 'push', 'unshift', 'replace']);
9
7
 
8
+ const SELF_RENDER = (item) => item;
9
+
10
10
  /**
11
11
  * Renders items from an ObservableArray with optimized array-specific updates.
12
12
  * Provides index observables and handles array mutations efficiently.
13
13
  *
14
14
  * @param {ObservableArray} data - ObservableArray to iterate over
15
- * @param {(item: *, index: null|ObservableItem) => NdChild} callback - Function that renders each item (item, indexObservable) => ValidChild
16
- * @param {Object} [configs={}] - Configuration options
15
+ * @param {((item: *, index: null|ObservableItem) => NdChild)?} callback - Function that renders each item (item, indexObservable) => ValidChild
16
+ * @param {Object?} [configs={}] - Configuration options
17
17
  * @param {boolean} [configs.shouldKeepItemsInCache] - Whether to cache rendered items
18
18
  * @param {boolean} [configs.isParentUniqueChild] - When it's the only child of the parent
19
19
  * @returns {AnchorDocumentFragment} Fragment managing the list rendering
@@ -26,6 +26,7 @@ const CREATE_AND_CACHE_ACTIONS = new Set(['clear', 'push', 'unshift', 'replace']
26
26
  * items.push(4); // Automatically updates DOM
27
27
  */
28
28
  export function ForEachArray(data, callback, configs = {}) {
29
+ callback = callback || SELF_RENDER;
29
30
  const element = Anchor('ForEach Array', configs.isParentUniqueChild);
30
31
  const blockEnd = element.endElement();
31
32
 
@@ -43,21 +44,6 @@ export function ForEachArray(data, callback, configs = {}) {
43
44
  return cache.get(item)?.child;
44
45
  };
45
46
 
46
- const updateIndexObservers = (items, startFrom = 0) => {
47
- if(!isIndexRequired) {
48
- return;
49
- }
50
- let index = startFrom;
51
- for(let i = startFrom, length = items?.length; i < length; i++) {
52
- const cacheItem = cache.get(items[i]);
53
- if(!cacheItem) {
54
- continue;
55
- }
56
- cacheItem.indexObserver?.set(index);
57
- index++;
58
- }
59
- };
60
-
61
47
  const removeCacheItem = (item, removeChild = true) => {
62
48
  const cacheItem = cache.get(item);
63
49
  if(!cacheItem) {
@@ -82,8 +68,8 @@ export function ForEachArray(data, callback, configs = {}) {
82
68
  return child;
83
69
  };
84
70
 
85
- const createWithIndexAndCache = (item, indexKey) => {
86
- const indexObserver = Observable(indexKey);
71
+ let createWithIndexAndCache = (item, indexKey) => {
72
+ const indexObserver = data.transform((items) => items.indexOf(item));
87
73
  const child = ElementCreator.getChild(callback(item, indexObserver));
88
74
  if(process.env.NODE_ENV === 'development') {
89
75
  if(!child) {
@@ -93,6 +79,18 @@ export function ForEachArray(data, callback, configs = {}) {
93
79
  cache.set(item, { child, indexObserver });
94
80
  return child;
95
81
  };
82
+ if(!data.__$Observable) {
83
+ createWithIndexAndCache = (item, indexKey) => {
84
+ const child = ElementCreator.getChild(callback(item, indexKey));
85
+ if(process.env.NODE_ENV === 'development') {
86
+ if(!child) {
87
+ throw new NativeDocumentError("ForEachArray child can't be null or undefined!");
88
+ }
89
+ }
90
+ cache.set(item, { child, indexObserver: null });
91
+ return child;
92
+ };
93
+ }
96
94
 
97
95
  const getOrCreate = (item, indexKey) => {
98
96
  const cacheItem = cache.get(item);
@@ -148,6 +146,21 @@ export function ForEachArray(data, callback, configs = {}) {
148
146
  child.remove();
149
147
  };
150
148
 
149
+ let set = null;
150
+ if(Array.isArray(data)) {
151
+ set = () => {
152
+ clear(data);
153
+ element.appendChildRaw(Actions.toFragment(data));
154
+ };
155
+ }
156
+ else {
157
+ set = () => {
158
+ const items = data.val();
159
+ clear(items);
160
+ element.appendChildRaw(Actions.toFragment(items));
161
+ };
162
+ }
163
+
151
164
  const Actions = {
152
165
  toFragment: (items) =>{
153
166
  const fragment = document.createDocumentFragment();
@@ -164,11 +177,7 @@ export function ForEachArray(data, callback, configs = {}) {
164
177
  clear(items);
165
178
  element.appendChildRaw(Actions.toFragment(items));
166
179
  },
167
- set: () => {
168
- const items = data.val();
169
- clear(items);
170
- element.appendChildRaw(Actions.toFragment(items));
171
- },
180
+ set,
172
181
  reOrder: (items) => {
173
182
  let child = null;
174
183
  const fragment = document.createDocumentFragment();
@@ -217,7 +226,9 @@ export function ForEachArray(data, callback, configs = {}) {
217
226
  }
218
227
  }
219
228
  } else {
220
- elementBeforeFirst = blockEnd;
229
+ const indexBefore = (start - 1 >= 0) ? start - 1 : start;
230
+ const itemAtStart = data.at(indexBefore);
231
+ elementBeforeFirst = getItemChild(itemAtStart) || blockEnd.previousSibling;
221
232
  }
222
233
  garbageFragment.replaceChildren();
223
234
 
@@ -266,13 +277,16 @@ export function ForEachArray(data, callback, configs = {}) {
266
277
  if(Actions[operations.action]) {
267
278
  Actions[operations.action](operations.args, operations.result);
268
279
  }
269
- updateIndexObservers(items, 0);
270
280
  };
271
281
 
282
+ if(Array.isArray(data)) {
283
+ buildContent(data, null, { action: 'set' });
284
+ return element;
285
+ }
286
+
272
287
  if(data.val().length) {
273
- buildContent(data.val(), null, {action: null});
288
+ buildContent(data.val(), null, { action: 'set' });
274
289
  }
275
290
  data.subscribe(buildContent);
276
-
277
291
  return element;
278
292
  }
@@ -6,14 +6,16 @@ import {getKey} from "../../utils/helpers";
6
6
  import { ElementCreator } from "../../wrappers/ElementCreator";
7
7
  import NativeDocumentError from "../../errors/NativeDocumentError";
8
8
 
9
+ const SELF_RENDER = (item) => item;
10
+
9
11
  /**
10
12
  * Renders a list of items from an observable array or object, automatically updating when data changes.
11
13
  * Efficiently manages DOM updates by tracking items with keys.
12
14
  *
13
15
  * @param {ObservableItem<Array|Object>} data - Observable containing array or object to iterate over
14
- * @param {(item: *, index: null|ObservableItem) => NdChild} callback - Function that renders each item (item, index) => ValidChild
15
- * @param {string|Function} [key] - Property name or function to generate unique keys for items
16
- * @param {Object} [options={}] - Configuration options
16
+ * @param {((item: *, index: null|ObservableItem) => NdChild)?} callback - Function that renders each item (item, index) => ValidChild
17
+ * @param {(string|Function)?} [key] - Property name or function to generate unique keys for items
18
+ * @param {Object?} [options={}] - Configuration options
17
19
  * @param {boolean} [options.shouldKeepItemsInCache=false] - Whether to cache rendered items
18
20
  * @returns {AnchorDocumentFragment} Fragment managing the list rendering
19
21
  * @example
@@ -27,6 +29,7 @@ import NativeDocumentError from "../../errors/NativeDocumentError";
27
29
  * ForEach(items, (item) => Div({}, item), (item) => item.id);
28
30
  */
29
31
  export function ForEach(data, callback, key, { shouldKeepItemsInCache = false } = {}) {
32
+ callback = callback || SELF_RENDER;
30
33
  const element = Anchor('ForEach');
31
34
  const blockEnd = element.endElement();
32
35
  const blockStart = element.startElement();
@@ -19,8 +19,12 @@ import {ElementCreator} from "../../wrappers/ElementCreator";
19
19
  * ShowIf(isVisible, Div({}, 'Hello World'));
20
20
  */
21
21
  export const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
22
- if(!(Validator.isObservable(condition)) && !Validator.isObservableWhenResult(condition)) {
23
- return DebugManager.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
22
+ if(!Validator.isObservable(condition)) {
23
+ if(typeof condition === "boolean") {
24
+ return condition ? ElementCreator.getChild(child) : null;
25
+ }
26
+
27
+ return DebugManager.warn('ShowIf', "ShowIf : condition must be an Observable or boolean / "+comment, condition);
24
28
  }
25
29
  const element = Anchor('Show if : '+(comment || ''));
26
30
 
@@ -41,12 +45,13 @@ export const ShowIf = function(condition, child, { comment = null, shouldKeepInC
41
45
  if(currentValue) {
42
46
  element.appendChild(getChildElement());
43
47
  }
44
- condition.subscribe(value => {
45
- if(value) {
48
+
49
+ condition.subscribe((value) => {
50
+ if(!!value) {
46
51
  element.appendChild(getChildElement());
47
- } else {
48
- element.remove();
52
+ return;
49
53
  }
54
+ element.remove();
50
55
  });
51
56
 
52
57
  return element;
@@ -73,6 +73,7 @@ export const Match = function($condition, values, shouldKeepInCache = true) {
73
73
  },
74
74
  remove(key) {
75
75
  shouldKeepInCache && cache.delete(key);
76
+ $condition.set([...cache.keys()].at(-1) ?? '');
76
77
  delete values[key];
77
78
  }
78
79
  });
@@ -99,7 +100,7 @@ export const Switch = function ($condition, onTrue, onFalse) {
99
100
  throw new NativeDocumentError("Toggle : condition must be an Observable");
100
101
  }
101
102
 
102
- return Match($condition, {
103
+ return Match($condition.toBoolean(), {
103
104
  true: onTrue,
104
105
  false: onFalse,
105
106
  });
@@ -15,7 +15,7 @@ export * from './list';
15
15
  export * from './medias';
16
16
  export * from './meta-data';
17
17
  export * from './table';
18
-
18
+ export * from './svg';
19
19
  /**
20
20
  * Creates an empty `DocumentFragment` wrapper.
21
21
  * Useful for grouping elements without adding a DOM node.
@@ -0,0 +1,61 @@
1
+ import SvgElementWrapper from "../wrappers/SvgElementWrapper";
2
+
3
+ export const SvgSvg = SvgElementWrapper('svg');
4
+ export const SvgCircle = SvgElementWrapper('circle');
5
+ export const SvgRect = SvgElementWrapper('rect');
6
+ export const SvgEllipse = SvgElementWrapper('ellipse');
7
+ export const SvgLine = SvgElementWrapper('line');
8
+ export const SvgPolyline = SvgElementWrapper('polyline');
9
+ export const SvgPolygon = SvgElementWrapper('polygon');
10
+ export const SvgPath = SvgElementWrapper('path');
11
+ export const SvgText = SvgElementWrapper('text');
12
+ export const SvgTSpan = SvgElementWrapper('tspan');
13
+ export const SvgTextPath = SvgElementWrapper('textPath');
14
+ export const SvgG = SvgElementWrapper('g');
15
+ export const SvgDefs = SvgElementWrapper('defs');
16
+ export const SvgUse = SvgElementWrapper('use');
17
+ export const SvgSymbol = SvgElementWrapper('symbol');
18
+ export const SvgClipPath = SvgElementWrapper('clipPath');
19
+ export const SvgMask = SvgElementWrapper('mask');
20
+ export const SvgMarker = SvgElementWrapper('marker');
21
+ export const SvgPattern = SvgElementWrapper('pattern');
22
+ export const SvgImage = SvgElementWrapper('image');
23
+ export const SvgForeignObject = SvgElementWrapper('foreignObject');
24
+ export const SvgSwitch = SvgElementWrapper('switch');
25
+ export const SvgLinearGradient = SvgElementWrapper('linearGradient');
26
+ export const SvgRadialGradient = SvgElementWrapper('radialGradient');
27
+ export const SvgStop = SvgElementWrapper('stop');
28
+ export const SvgFilter = SvgElementWrapper('filter');
29
+ export const SvgFEBlend = SvgElementWrapper('feBlend');
30
+ export const SvgFEColorMatrix = SvgElementWrapper('feColorMatrix');
31
+ export const SvgFEComposite = SvgElementWrapper('feComposite');
32
+ export const SvgFEFlood = SvgElementWrapper('feFlood');
33
+ export const SvgFEGaussianBlur = SvgElementWrapper('feGaussianBlur');
34
+ export const SvgFEMerge = SvgElementWrapper('feMerge');
35
+ export const SvgFEMergeNode = SvgElementWrapper('feMergeNode');
36
+ export const SvgFEOffset = SvgElementWrapper('feOffset');
37
+ export const SvgFETurbulence = SvgElementWrapper('feTurbulence');
38
+ export const SvgFEDisplacementMap = SvgElementWrapper('feDisplacementMap');
39
+ export const SvgFEDiffuseLighting = SvgElementWrapper('feDiffuseLighting');
40
+ export const SvgFESpecularLighting = SvgElementWrapper('feSpecularLighting');
41
+ export const SvgFEDistantLight = SvgElementWrapper('feDistantLight');
42
+ export const SvgFEPointLight = SvgElementWrapper('fePointLight');
43
+ export const SvgFESpotLight = SvgElementWrapper('feSpotLight');
44
+ export const SvgFEMorphology = SvgElementWrapper('feMorphology');
45
+ export const SvgFEConvolveMatrix = SvgElementWrapper('feConvolveMatrix');
46
+ export const SvgFEComponentTransfer = SvgElementWrapper('feComponentTransfer');
47
+ export const SvgFEFuncR = SvgElementWrapper('feFuncR');
48
+ export const SvgFEFuncG = SvgElementWrapper('feFuncG');
49
+ export const SvgFEFuncB = SvgElementWrapper('feFuncB');
50
+ export const SvgFEFuncA = SvgElementWrapper('feFuncA');
51
+ export const SvgAnimate = SvgElementWrapper('animate');
52
+ export const SvgAnimateTransform = SvgElementWrapper('animateTransform');
53
+ export const SvgAnimateMotion = SvgElementWrapper('animateMotion');
54
+ export const SvgMPath = SvgElementWrapper('mpath');
55
+ export const SvgSet = SvgElementWrapper('set');
56
+ export const SvgDesc = SvgElementWrapper('desc');
57
+ export const SvgTitle = SvgElementWrapper('title');
58
+ export const SvgMetadata = SvgElementWrapper('metadata');
59
+ export const SvgView = SvgElementWrapper('view');
60
+ export const SvgStyle = SvgElementWrapper('style');
61
+ export const SvgScript = SvgElementWrapper('script');
@@ -22,10 +22,16 @@ HasEventEmitter.prototype.on = function(eventName, callback) {
22
22
  };
23
23
 
24
24
  HasEventEmitter.prototype.hasListeners = function(eventName) {
25
+ if(!this.__$events) {
26
+ return false;
27
+ }
25
28
  return !!this.__$events.get(eventName);
26
29
  };
27
30
 
28
31
  HasEventEmitter.prototype.trigger = async function(eventName, ...args) {
32
+ if(!this.__$events) {
33
+ return;
34
+ }
29
35
  const callbacks = this.__$events.get(eventName);
30
36
  if(!callbacks) {
31
37
  // throw new NativeDocumentError(this.constructor.name, 'Event '+eventName+' not found');
@@ -2,11 +2,10 @@ let DebugManager = {};
2
2
 
3
3
  if(process.env.NODE_ENV === 'development') {
4
4
  DebugManager = {
5
- enabled: false,
5
+ enabled: true,
6
6
 
7
7
  enable() {
8
- this.enabled = true;
9
- console.log('🔍 NativeDocument Debug Mode enabled');
8
+ DebugManager.log('🔍 NativeDocument Debug Mode enabled');
10
9
  },
11
10
 
12
11
  disable() {
@@ -14,7 +13,6 @@ if(process.env.NODE_ENV === 'development') {
14
13
  },
15
14
 
16
15
  log(category, message, data) {
17
- if (!this.enabled) return;
18
16
  console.group(`🔍 [${category}] ${message}`);
19
17
  if (data) console.log(data);
20
18
  console.trace();
@@ -22,7 +20,6 @@ if(process.env.NODE_ENV === 'development') {
22
20
  },
23
21
 
24
22
  warn(category, message, data) {
25
- if (!this.enabled) return;
26
23
  console.warn(`⚠️ [${category}] ${message}`, data);
27
24
  },
28
25
 
@@ -1,5 +1,6 @@
1
1
  import Validator from "../../utils/validator";
2
2
  import { createFilter, createMultiSourceFilter } from "./utils";
3
+ import DebugManager from "../debug-manager";
3
4
 
4
5
 
5
6
  export function equals(observableOrValue){
@@ -70,7 +71,7 @@ export function match(patternObservableOrValue, asRegexObservableOrValue = true,
70
71
  const regex = new RegExp(pattern, flags);
71
72
  return regex.test(String(value));
72
73
  } catch (error){
73
- console.warn('Invalid regex pattern:', pattern, error);
74
+ DebugManager.warn('Invalid regex pattern:', pattern, error);
74
75
  return false;
75
76
  }
76
77
  }
@@ -2,18 +2,24 @@ import Validator from "./validator";
2
2
 
3
3
  export const cssPropertyAccumulator = function(initialValue = {}) {
4
4
  let data = Validator.isString(initialValue) ? initialValue.split(';').filter(Boolean) : initialValue;
5
- const isArray = Validator.isArray(data);
6
5
 
7
6
  return {
8
7
  add(key, value) {
9
- if(isArray) {
8
+ if(Array.isArray(data)) {
10
9
  data.push(key+': '+value);
11
10
  return;
12
11
  }
12
+ if(Validator.isObject(key)) {
13
+ value = key;
14
+ for(const property in value) {
15
+ data[property] = value[property];
16
+ }
17
+ return;
18
+ }
13
19
  data[key] = value;
14
20
  },
15
21
  value() {
16
- if(isArray) {
22
+ if(Array.isArray(data)) {
17
23
  return data.join(';').concat(';');
18
24
  }
19
25
  return { ...data };
@@ -23,18 +29,41 @@ export const cssPropertyAccumulator = function(initialValue = {}) {
23
29
 
24
30
  export const classPropertyAccumulator = function(initialValue = []) {
25
31
  let data = Validator.isString(initialValue) ? initialValue.split(" ").filter(Boolean) : initialValue;
26
- const isArray = Validator.isArray(data);
27
32
 
28
33
  return {
29
34
  add(key, value = true) {
30
- if(isArray) {
35
+ if(Validator.isJson(key)) {
36
+ for(const property in key) {
37
+ if(key[property]) {
38
+ data[property] = key[property];
39
+ }
40
+ }
41
+ return;
42
+ }
43
+ if(value != null || key.__$Observable) {
44
+ if(Array.isArray(data)) {
45
+ data = data.reduce((acc, item) => {
46
+ acc[item] = true;
47
+ return acc;
48
+ }, {});
49
+ }
50
+ if(key.__$Observable) {
51
+ const uniqueId = `obs-${Math.random().toString(36).substr(2, 9)}`
52
+ data[uniqueId] = key;
53
+ }
54
+ else {
55
+ data[key] = value;
56
+ }
57
+ return;
58
+ }
59
+ if(Array.isArray(data)) {
31
60
  data.push(key);
32
61
  return;
33
62
  }
34
63
  data[key] = value;
35
64
  },
36
65
  value() {
37
- if(isArray) {
66
+ if(Array.isArray(data)) {
38
67
  return data.join(' ');
39
68
  }
40
69
  return { ...data };