native-document 1.0.138 → 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 +11506 -8566
  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 +109 -4
  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
@@ -1,29 +1,85 @@
1
1
  /**
2
2
  * Tooltip - Interface
3
3
  */
4
+ import {Observable} from "../../../index";
5
+ import {NDElement} from "../../core/wrappers/NDElement";
6
+ import BaseComponent from "../BaseComponent";
7
+ import HasEventEmitter from "../../core/utils/HasEventEmitter";
8
+ import DebugManager from "../../core/utils/debug-manager";
4
9
 
5
- export default function Tooltip(target, content, config = {}) {
10
+ export default function Tooltip(content, props = {}) {
6
11
  if (!(this instanceof Tooltip)) {
7
- return new Tooltip(target, content, config);
12
+ return new Tooltip(content, props);
8
13
  }
9
14
 
15
+ BaseComponent.call(this, props);
16
+
10
17
  this.$description = {
11
- title: null,
12
- content: null,
18
+ trigger: null,
19
+ interaction: 'hover',
20
+ content,
13
21
  position: 'top',
14
- trigger: 'hover',
15
- target: target,
22
+ title: null,
23
+ isOpen: Observable(false),
24
+ offset: 8,
25
+ shift: {},
16
26
  hideDelay: 0,
17
27
  arrow: true,
18
28
  interactive: true,
19
29
  variant: null,
20
- ...config,
30
+ updatePositionOn: null,
31
+ props,
21
32
  };
22
33
  }
23
34
 
24
- Tooltip.use = function(template) {};
35
+ BaseComponent.extends(Tooltip);
36
+ BaseComponent.use(Tooltip, HasEventEmitter);
37
+
25
38
  Tooltip.defaultTemplate = null;
26
39
 
40
+ Tooltip.use = function(template) {
41
+ Tooltip.defaultTemplate = template;
42
+ if(!NDElement.prototype.tooltip) {
43
+ NDElement.prototype.tooltip = function(content, props) {
44
+ this.ghostDom((content instanceof Tooltip)
45
+ ? content.trigger(this.$element)
46
+ : Tooltip(content, props).trigger(this.$element));
47
+ return this;
48
+ };
49
+ }
50
+ if(!BaseComponent.prototype.tooltip) {
51
+ BaseComponent.prototype.tooltip = function(content, props) {
52
+ this.postBuild(() => {
53
+ if(content instanceof Tooltip) {
54
+ this.ghostDom(content.trigger(this.$element));
55
+ } else {
56
+ this.ghostDom(Tooltip(content, props).trigger(this.$element));
57
+ }
58
+ });
59
+ return this;
60
+ };
61
+ }
62
+ };
63
+
64
+ Tooltip.preset = function(name, callback) {
65
+ if (Tooltip.prototype[name] || Tooltip[name]) {
66
+ DebugManager.warn(`Warning: the ${name} method already exist in Tooltip.`);
67
+ return;
68
+ }
69
+ Tooltip[name] = (content, props) => callback(new Tooltip(content, props));
70
+ };
71
+
72
+ Tooltip.presets = function(presets) {
73
+ for (const name in presets) {
74
+ Tooltip.preset(name, presets[name]);
75
+ }
76
+ };
77
+
78
+ Tooltip.prototype.trigger = function(trigger) {
79
+ this.$description.trigger = trigger;
80
+ return this;
81
+ };
82
+
27
83
  Tooltip.prototype.title = function(title) {
28
84
  this.$description.title = title;
29
85
  return this;
@@ -32,40 +88,70 @@ Tooltip.prototype.content = function(content) {
32
88
  this.$description.content = content;
33
89
  return this;
34
90
  };
91
+ Tooltip.prototype.variant = function(variant) {
92
+ this.$description.variant = variant;
93
+ return this;
94
+ };
95
+
96
+ Tooltip.prototype.primary = function() {
97
+ this.$description.variant = 'primary';
98
+ return this;
99
+ };
100
+
101
+ Tooltip.prototype.success = function() {
102
+ this.$description.variant = 'success';
103
+ return this;
104
+ };
105
+
106
+ Tooltip.prototype.warning = function() {
107
+ this.$description.variant = 'warning';
108
+ return this;
109
+ };
110
+
111
+ Tooltip.prototype.danger = function() {
112
+ this.$description.variant = 'danger';
113
+ return this;
114
+ };
115
+
116
+ Tooltip.prototype.info = function() {
117
+ this.$description.variant = 'info';
118
+ return this;
119
+ };
35
120
 
36
121
  Tooltip.prototype.position = function(position) {
37
122
  this.$description.position = position;
38
123
  return this;
39
124
  };
40
- Tooltip.prototype.top = function() {
41
- return this.position('top');
42
- };
43
- Tooltip.prototype.bottom = function() {
44
- return this.position('bottom');
125
+ Tooltip.prototype.atTop = function() {
126
+ this.$description.position = 'top';
127
+ return this;
45
128
  };
46
- Tooltip.prototype.left = function() {
47
- return this.position('left');
129
+ Tooltip.prototype.atBottom = function() {
130
+ this.$description.position = 'bottom';
131
+ return this;
48
132
  };
49
- Tooltip.prototype.right = function() {
50
- return this.position('right');
133
+ Tooltip.prototype.atLeft = function() {
134
+ this.$description.position = 'left';
135
+ return this;
51
136
  };
52
- Tooltip.prototype.auto = function() {
53
- return this.position('auto');
137
+ Tooltip.prototype.atRight = function() {
138
+ this.$description.position = 'right';
139
+ return this;
54
140
  };
55
141
 
56
- Tooltip.prototype.trigger = function(trigger, target = null) {
57
- this.$description.trigger = trigger;
58
- this.$description.target = target;
142
+ Tooltip.prototype.onClicked = function() {
143
+ this.$description.interaction = 'click';
59
144
  return this;
60
145
  };
61
- Tooltip.prototype.showOnHover = function(target = null) {
62
- return this.trigger('hover', target);
63
- };
64
- Tooltip.prototype.showOnClick = function(target = null) {
65
- return this.trigger('click', target);
146
+
147
+ Tooltip.prototype.onHovered = function() {
148
+ this.$description.interaction = 'hover';
149
+ return this;
66
150
  };
67
- Tooltip.prototype.showOnFocus = function(target = null) {
68
- return this.trigger('focus', target);
151
+
152
+ Tooltip.prototype.onFocused = function() {
153
+ this.$description.interaction = 'focus';
154
+ return this;
69
155
  };
70
156
 
71
157
  Tooltip.prototype.hideDelay = function(ms) {
@@ -81,18 +167,49 @@ Tooltip.prototype.interactive = function(isInteractive = true) {
81
167
  return this;
82
168
  }
83
169
 
84
- Tooltip.prototype.variant = function(variant) {
85
- this.$description.variant = variant;
170
+ Tooltip.prototype.open = function() {
171
+ this.$description.isOpen.set(true);
172
+ this.emit('open');
173
+ return this;
174
+ };
175
+
176
+ Tooltip.prototype.close = function() {
177
+ this.$description.isOpen.set(false);
178
+ this.emit('close');
86
179
  return this;
87
180
  };
88
181
 
89
- Tooltip.prototype.show = function() {};
90
- Tooltip.prototype.hide = function() {};
182
+ Tooltip.prototype.toggle = function() {
183
+ this.$description.isOpen.val() ? this.close() : this.open();
184
+ return this;
185
+ };
186
+
187
+ Tooltip.prototype.onOpen = function(handler) {
188
+ this.on('open', handler);
189
+ return this;
190
+ };
191
+
192
+ Tooltip.prototype.onClose = function(handler) {
193
+ this.on('close', handler);
194
+ return this;
195
+ };
91
196
 
92
197
  Tooltip.prototype.render = function(renderFn) {
93
198
  this.$description.render = renderFn;
94
199
  return this;
95
200
  };
96
201
 
97
- Tooltip.prototype.$build = function() {};
98
- Tooltip.prototype.toNdElement = function() {};
202
+ Tooltip.prototype.offset = function(offset) {
203
+ this.$description.offset = offset;
204
+ return this;
205
+ };
206
+
207
+ Tooltip.prototype.shift = function(shift) {
208
+ this.$description.shift = shift;
209
+ return this;
210
+ };
211
+
212
+ Tooltip.prototype.updatePositionOn = function(updatePositionOn) {
213
+ this.$description.updatePositionOn = updatePositionOn;
214
+ return this;
215
+ };
@@ -9,7 +9,6 @@ import {nextTick} from "../utils/helpers";
9
9
  const mutationMethods = ['push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice'];
10
10
  const noMutationMethods = ['map', 'forEach', 'filter', 'reduce', 'some', 'every', 'find', 'findIndex', 'concat', 'includes', 'indexOf'];
11
11
 
12
-
13
12
  /**
14
13
  *
15
14
  * @param target
@@ -36,13 +35,26 @@ Object.defineProperty(ObservableArray.prototype, 'length', {
36
35
  get() {
37
36
  return this.$currentValue.length;
38
37
  }
39
- })
38
+ });
39
+
40
+
41
+ ObservableArray.prototype.$mutate = function(action, args, mutateFn) {
42
+ if(this.$mutationInterceptor) {
43
+ const value = this.$mutationInterceptor(args, { action });
44
+ if(args !== undefined) {
45
+ args = value;
46
+ }
47
+ }
48
+ mutateFn(args);
49
+ };
40
50
 
41
51
  mutationMethods.forEach((method) => {
42
52
  ObservableArray.prototype[method] = function(...values) {
43
- const result = this.$currentValue[method].apply(this.$currentValue, values);
44
- this.trigger({ action: method, args: values, result });
45
- return result;
53
+ return this.$mutate(method, values, (argsToUse) => {
54
+ const result = this.$currentValue[method].apply(this.$currentValue, argsToUse);
55
+ this.trigger({ action: method, args: argsToUse, result });
56
+ return result;
57
+ })
46
58
  };
47
59
  });
48
60
 
@@ -52,6 +64,7 @@ noMutationMethods.forEach((method) => {
52
64
  };
53
65
  });
54
66
 
67
+
55
68
  const $clearEvent = { action: 'clear' };
56
69
 
57
70
  /**
@@ -66,8 +79,10 @@ ObservableArray.prototype.clear = function() {
66
79
  if(this.$currentValue.length === 0) {
67
80
  return;
68
81
  }
69
- this.$currentValue.length = 0;
70
- this.trigger($clearEvent);
82
+ this.$mutate('clear', [], () => {
83
+ this.$currentValue.length = 0;
84
+ this.trigger($clearEvent);
85
+ });
71
86
  return true;
72
87
  };
73
88
 
@@ -95,8 +110,10 @@ ObservableArray.prototype.at = function(index) {
95
110
  * items.merge([3, 4]); // [1, 2, 3, 4]
96
111
  */
97
112
  ObservableArray.prototype.merge = function(values) {
98
- this.$currentValue.push.apply(this.$currentValue, values);
99
- this.trigger({ action: 'merge', args: values });
113
+ this.$mutate('merge', values, (valuesToMerge) => {
114
+ this.$currentValue.push.apply(this.$currentValue, valuesToMerge);
115
+ this.trigger({ action: 'merge', args: valuesToMerge });
116
+ });
100
117
  };
101
118
 
102
119
  /**
@@ -129,25 +146,39 @@ ObservableArray.prototype.count = function(condition) {
129
146
  * items.swap(0, 2); // ['c', 'b', 'a']
130
147
  */
131
148
  ObservableArray.prototype.swap = function(indexA, indexB) {
132
- const value = this.$currentValue;
133
- const length = value.length;
134
- if(length < indexA || length < indexB) {
135
- return false;
136
- }
137
- if(indexB < indexA) {
138
- const temp = indexA;
139
- indexA = indexB;
140
- indexB = temp;
141
- }
142
- const elementA = value[indexA];
143
- const elementB = value[indexB]
149
+ this.$mutate('swap', [indexA, indexB], ([indexA, indexB]) => {
150
+ const value = this.$currentValue;
151
+ const length = value.length;
152
+ if(indexB < indexA) {
153
+ const temp = indexA;
154
+ indexA = indexB;
155
+ indexB = temp;
156
+ }
157
+ if(length < indexA || length < indexB) {
158
+ return false;
159
+ }
160
+ const elementA = value[indexA];
161
+ const elementB = value[indexB]
144
162
 
145
- value[indexA] = elementB;
146
- value[indexB] = elementA;
147
- this.trigger({ action: 'swap', args: [indexA, indexB], result: [elementA, elementB] });
163
+ value[indexA] = elementB;
164
+ value[indexB] = elementA;
165
+ this.trigger({ action: 'swap', args: [indexA, indexB], result: [elementA, elementB] });
166
+ });
148
167
  return true;
149
168
  };
150
169
 
170
+ ObservableArray.prototype.swapItems = function(itemA, itemB) {
171
+ const indexA = this.$currentValue.indexOf(itemA);
172
+ const indexB = this.$currentValue.indexOf(itemB);
173
+
174
+ return this.swap(indexA, indexB);
175
+ };
176
+
177
+ ObservableArray.prototype.insertAfter = function(data, target) {
178
+ const targetIndex = this.$currentValue.indexOf(target);
179
+ return this.splice(targetIndex + 1, 0, data);
180
+ };
181
+
151
182
  /**
152
183
  * Removes the element at the specified index and triggers an update.
153
184
  *
@@ -158,11 +189,14 @@ ObservableArray.prototype.swap = function(indexA, indexB) {
158
189
  * items.remove(1); // ['b'] - Array is now ['a', 'c']
159
190
  */
160
191
  ObservableArray.prototype.remove = function(index) {
161
- const deleted = this.$currentValue.splice(index, 1);
162
- if(deleted.length === 0) {
163
- return [];
164
- }
165
- this.trigger({ action: 'remove', args: [index], result: deleted[0] });
192
+ let deleted = [];
193
+ this.$mutate('remove', [index], ([idx]) => {
194
+ deleted = this.$currentValue.splice(idx, 1);
195
+ if(deleted.length === 0) {
196
+ return;
197
+ }
198
+ this.trigger({action: 'remove', args: [idx], result: deleted[0]});
199
+ });
166
200
  return deleted;
167
201
  };
168
202
 
@@ -191,7 +225,7 @@ ObservableArray.prototype.removeItem = function(item) {
191
225
  * const items = Observable.array([]);
192
226
  * items.isEmpty(); // true
193
227
  */
194
- ObservableArray.prototype.isEmpty = function() {
228
+ ObservableArray.prototype.empty = function() {
195
229
  return this.$currentValue.length === 0;
196
230
  };
197
231
 
@@ -218,9 +252,13 @@ ObservableArray.prototype.populateAndRender = function(iteration, callback) {
218
252
  * { name: 'John', age: 25 },
219
253
  * { name: 'Jane', age: 30 }
220
254
  * ]);
255
+ *
221
256
  * const adults = users.where({ age: (val) => val >= 18 });
222
257
  */
223
258
  ObservableArray.prototype.where = function(predicates) {
259
+ if(typeof predicates === 'function') {
260
+ predicates = { _: predicates };
261
+ }
224
262
  const sourceArray = this;
225
263
  const observableDependencies = [sourceArray];
226
264
  const filterCallbacks = {};
@@ -380,4 +418,30 @@ ObservableArray.prototype.deepSubscribe = function(callback) {
380
418
  };
381
419
  };
382
420
 
421
+
422
+ ObservableArray.prototype.sync = function(targetObservable) {
423
+ if (!targetObservable || !targetObservable.__$isObservableArray) {
424
+ throw new NativeDocumentError('ObservableArray.sync : target must be an ObservableArray');
425
+ }
426
+
427
+ targetObservable.set([...this.$currentValue]);
428
+
429
+ const sync = (currentValue, _, operations) => {
430
+ if (!operations) {
431
+ targetObservable.set([...currentValue]);
432
+ return;
433
+ }
434
+
435
+ const { action, args } = operations;
436
+ targetObservable[action].apply(targetObservable, args);
437
+ };
438
+ this.subscribe(sync);
439
+
440
+ return () => this.unsubscribe(sync);
441
+ };
442
+
443
+ ObservableArray.prototype.clone = function() {
444
+ return new ObservableArray(this.resolve());
445
+ };
446
+
383
447
  export default ObservableArray;
@@ -1,3 +1,6 @@
1
+ import ObservableItem from "./ObservableItem";
2
+ import PluginsManager from "../utils/plugins-manager";
3
+
1
4
  /**
2
5
  *
3
6
  * @param {ObservableItem} $observable
@@ -6,89 +9,31 @@
6
9
  */
7
10
  export default function ObservableChecker($observable, $checker) {
8
11
  this.observable = $observable;
9
- this.checker = $checker;
10
- this.unSubscriptions = [];
11
- }
12
12
 
13
- export const ObservablePipe = ObservableChecker;
13
+ ObservableItem.call(this);
14
+ if(process.env.NODE_ENV === 'development') {
15
+ PluginsManager.emit('CreateObservableChecker', this);
16
+ }
14
17
 
15
- ObservableChecker.prototype.__$Observable = true;
16
- ObservableChecker.prototype.__$isObservableChecker = true;
18
+ this.$mutation = $checker;
17
19
 
18
- /**
19
- * Subscribes to changes in the checked/transformed value.
20
- *
21
- * @param {Function} callback - Function called with the transformed value when observable changes
22
- * @returns {Function} Unsubscribe function
23
- * @example
24
- * const count = Observable(5);
25
- * const doubled = count.check(n => n * 2);
26
- * doubled.subscribe(value => console.log(value)); // Logs: 10
27
- */
28
- ObservableChecker.prototype.subscribe = function(callback) {
29
- const unSubscribe = this.observable.subscribe((value) => {
30
- callback && callback(this.checker(value));
20
+ $observable.subscribe((newValue) => {
21
+ this.$updateWithMutation(newValue);
31
22
  });
32
- this.unSubscriptions.push(unSubscribe);
33
- return unSubscribe;
34
- };
35
23
 
36
- /**
37
- * Creates a new ObservableChecker by applying another transformation.
38
- * Allows chaining transformations.
39
- *
40
- * @param {(value: *) => *} callback - Transformation function to apply to the current checked value
41
- * @returns {ObservableChecker} New ObservableChecker with chained transformation
42
- * @example
43
- * const count = Observable(5);
44
- * const result = count.check(n => n * 2).check(n => n + 1);
45
- * result.val(); // 11
46
- */
47
- ObservableChecker.prototype.check = function(callback) {
48
- return this.observable.check(() => callback(this.val()));
24
+ this.$updateWithMutation($observable.val());
49
25
  }
50
26
 
51
- /**
52
- * Gets the current transformed/checked value.
53
- *
54
- * @returns {*} The result of applying the checker function to the observable's current value
55
- * @example
56
- * const count = Observable(5);
57
- * const doubled = count.check(n => n * 2);
58
- * doubled.val(); // 10
59
- */
60
- ObservableChecker.prototype.val = function() {
61
- return this.checker && this.checker(this.observable.val());
62
- }
27
+ ObservableChecker.prototype = Object.create(ObservableItem.prototype);
28
+ ObservableChecker.prototype.constructor = ObservableChecker;
29
+ ObservableChecker.prototype.__$Observable = true;
30
+ ObservableChecker.prototype.__$isObservableChecker = true;
63
31
 
64
- /**
65
- * Sets the value of the underlying observable (not the transformed value).
66
- *
67
- * @param {*} value - New value for the underlying observable
68
- * @example
69
- * const count = Observable(5);
70
- * const doubled = count.check(n => n * 2);
71
- * doubled.set(10); // Sets count to 10, doubled.val() returns 20
72
- */
73
- ObservableChecker.prototype.set = function(value) {
74
- return this.observable.set(value);
75
- };
76
32
 
77
- /**
78
- * Manually triggers the underlying observable to notify subscribers.
79
- *
80
- * @example
81
- * const count = Observable(5);
82
- * const doubled = count.check(n => n * 2);
83
- * doubled.trigger(); // Notifies all subscribers
84
- */
85
- ObservableChecker.prototype.trigger = function() {
86
- return this.observable.trigger();
87
- };
33
+ export const ObservablePipe = ObservableChecker;
34
+ ObservablePipe.prototype.constructor = ObservablePipe;
88
35
 
89
- /**
90
- * Cleans up the underlying observable and all its subscriptions.
91
- */
92
- ObservableChecker.prototype.cleanup = function() {
93
- return this.observable.cleanup();
36
+ ObservableChecker.prototype.$updateWithMutation = function(newValue) {
37
+ newValue = this.$mutation(newValue);
38
+ return this.set(newValue);
94
39
  };
@@ -73,6 +73,11 @@ ObservableItem.prototype.intercept = function(callback) {
73
73
  return this;
74
74
  };
75
75
 
76
+ ObservableItem.prototype.interceptMutations = function(callback) {
77
+ this.$mutationInterceptor = callback;
78
+ return this;
79
+ };
80
+
76
81
  ObservableItem.prototype.triggerFirstListener = function(operations) {
77
82
  this.$firstListener(this.$currentValue, this.$previousValue, operations);
78
83
  };
@@ -115,6 +120,8 @@ ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations)
115
120
  ObservableItem.prototype.assocTrigger = function() {
116
121
  this.$firstListener = null;
117
122
  if(this.$watchers?.size && this.$listeners?.length) {
123
+ this.$firstListener = this.$listeners[0];
124
+ this.trigger = this.$firstListener.length === 0 ? this.$firstListener : this.triggerFirstListener
118
125
  this.trigger = (this.$listeners.length === 1) ? this.triggerWatchersAndFirstListener : this.triggerAll;
119
126
  return;
120
127
  }
@@ -167,7 +174,8 @@ ObservableItem.prototype.$setWithInterceptor = function(data) {
167
174
  }
168
175
 
169
176
  this.$updateWithNewValue(newValue);
170
- }
177
+ };
178
+
171
179
 
172
180
  /**
173
181
  * @param {*} data
@@ -366,10 +374,20 @@ ObservableItem.prototype.check = function(callback) {
366
374
  };
367
375
 
368
376
  ObservableItem.prototype.transform = ObservableItem.prototype.check;
369
- ObservableItem.prototype.pluck = ObservableItem.prototype.check;
370
- ObservableItem.prototype.is = ObservableItem.prototype.check;
377
+ ObservableItem.prototype.pluck = function(property) {
378
+ return new ObservableChecker(this, (value) => value[property]);
379
+ };
380
+ ObservableItem.prototype.is = function(callbackOrValue) {
381
+ if(typeof callbackOrValue === 'function') {
382
+ return new ObservableChecker(this, callbackOrValue);
383
+ }
384
+ return new ObservableChecker(this, (value) => value === callbackOrValue);
385
+ };
371
386
  ObservableItem.prototype.select = ObservableItem.prototype.check;
372
387
 
388
+
389
+
390
+
373
391
  /**
374
392
  * Gets a property value from the observable's current value.
375
393
  * If the property is an observable, returns its value.
@@ -573,4 +591,18 @@ ObservableItem.prototype.persist = function(key, options = {}) {
573
591
  saver(key, options.set ? options.set(newValue) : newValue);
574
592
  });
575
593
  return this;
594
+ };
595
+
596
+ ObservableItem.prototype.clone = function() {
597
+ let clonedValue = this.$currentValue;
598
+
599
+ if(clonedValue && typeof clonedValue === 'object') {
600
+ if(typeof clonedValue.clone === 'function') {
601
+ clonedValue = clonedValue.clone();
602
+ } else {
603
+ clonedValue = structuredClone(clonedValue);
604
+ }
605
+ }
606
+
607
+ return new ObservableItem(clonedValue);
576
608
  };
@@ -27,7 +27,8 @@ import {nextTick} from "../../utils/helpers";
27
27
  Observable.computed = function(callback, dependencies = []) {
28
28
  const initialValue = callback();
29
29
  const observable = new ObservableItem(initialValue);
30
- const updatedValue = nextTick(() => observable.set(callback()));
30
+ const getValues = () => dependencies.map((item) => item.val());
31
+ const updatedValue = nextTick(() => observable.set(callback(...getValues())));
31
32
  if(process.env.NODE_ENV === 'development') {
32
33
  PluginsManager.emit('CreateObservableComputed', observable, dependencies);
33
34
  }
@@ -1,6 +1,7 @@
1
1
  import Validator from "../../utils/validator";
2
2
  import {Observable} from "../Observable";
3
3
  import {ObservableObject} from "../ObservableObject";
4
+ import ObservableItem from "../ObservableItem";
4
5
 
5
6
 
6
7
  Observable.init = function(initialValue, configs = null) {
@@ -22,22 +23,26 @@ Observable.arrayOfObject = function(data) {
22
23
  * @returns {{}|*|null}
23
24
  */
24
25
  Observable.value = function(data) {
25
- if(Validator.isObservable(data)) {
26
- return data.val();
27
- }
28
- if(Validator.isProxy(data)) {
29
- return data.$value;
30
- }
31
- if(Validator.isArray(data)) {
26
+ if(data?.__$isObservableArray) {
32
27
  const result = [];
33
28
  for(let i = 0, length = data.length; i < length; i++) {
34
- const item = data[i];
29
+ const item = data.at(i);
35
30
  result.push(Observable.value(item));
36
31
  }
37
32
  return result;
38
33
  }
34
+ if(data?.__$Observable) {
35
+ return data.val();
36
+ }
37
+ if(Validator.isProxy(data)) {
38
+ return data.$value;
39
+ }
39
40
  return data;
40
41
  };
41
42
 
43
+ ObservableItem.prototype.resolve = function () {
44
+ return Observable.value(this);
45
+ };
46
+
42
47
  Observable.object = Observable.init;
43
48
  Observable.json = Observable.init;