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
@@ -0,0 +1,113 @@
1
+
2
+ import './has-resizable.css';
3
+
4
+ export default function HasResizable() {}
5
+
6
+ HasResizable.prototype.makeResizable = function(parent, options = {}) {
7
+ if(!this.emit) {
8
+ throw new Error('HasResizable requires HasEventEmitter — add it via BaseComponent.use(Component, HasEventEmitter).');
9
+ }
10
+
11
+ const directions = options.directions || ['right', 'bottom', 'bottom-right'];
12
+ const sizeConstraint = options.size || { minWidth: 200, minHeight: 200 };
13
+ sizeConstraint.minWidth = sizeConstraint.minWidth || 200;
14
+ sizeConstraint.minHeight = sizeConstraint.minHeight || 200;
15
+
16
+ parent.classList.add('is-resizable');
17
+
18
+ const handles = [];
19
+
20
+ directions.forEach((direction) => {
21
+ const handle = document.createElement('div');
22
+ handle.className = 'resize-handle is-' + direction;
23
+ parent.appendChild(handle);
24
+ handles.push(handle);
25
+
26
+ setupResizeHandle(handle, parent, direction, sizeConstraint, this);
27
+ });
28
+
29
+ return () => {
30
+ handles.forEach(h => h.remove());
31
+ };
32
+ };
33
+
34
+ const setupResizeHandle = (handle, parent, direction, sizeConstraint, instance) => {
35
+ let isResizing = false;
36
+ let startX = 0;
37
+ let startY = 0;
38
+ let startW = 0;
39
+ let startH = 0;
40
+ let startLeft = 0;
41
+ let startTop = 0;
42
+
43
+ const onMouseDown = (e) => {
44
+ e.preventDefault();
45
+ e.stopPropagation();
46
+
47
+ isResizing = true;
48
+ startX = e.clientX;
49
+ startY = e.clientY;
50
+ startW = parent.offsetWidth;
51
+ startH = parent.offsetHeight;
52
+ startLeft = parent.offsetLeft;
53
+ startTop = parent.offsetTop;
54
+
55
+ document.body.classList.add('is-resizing');
56
+ instance.emit?.('onResizeStart', [e, startW, startH]);
57
+ };
58
+
59
+ const onMouseMove = (e) => {
60
+ if(!isResizing) {
61
+ return;
62
+ }
63
+
64
+ const dx = e.clientX - startX;
65
+ const dy = e.clientY - startY;
66
+
67
+ if(direction === 'right' || direction === 'top-right' || direction === 'bottom-right') {
68
+ const newWidth = Math.max(sizeConstraint.minWidth, startW + dx);
69
+ if(newWidth > sizeConstraint.minWidth && (!sizeConstraint.maxWidth || newWidth <= sizeConstraint.maxWidth)) {
70
+ parent.style.width = newWidth + 'px';
71
+ }
72
+ }
73
+
74
+ if(direction === 'left' || direction === 'top-left' || direction === 'bottom-left') {
75
+ const newWidth = Math.max(sizeConstraint.minWidth, startW - dx);
76
+ if(newWidth > sizeConstraint.minWidth && (!sizeConstraint.maxWidth || newWidth <= sizeConstraint.maxWidth)) {
77
+ parent.style.width = newWidth + 'px';
78
+ parent.style.left = (startLeft + dx) + 'px';
79
+ }
80
+ }
81
+
82
+ if(direction === 'bottom' || direction === 'bottom-right' || direction === 'bottom-left') {
83
+ const newHeight = Math.max(sizeConstraint.minHeight, startH + dy);
84
+ if(newHeight > sizeConstraint.minHeight && (!sizeConstraint.maxHeight || newHeight <= sizeConstraint.maxHeight)) {
85
+ parent.style.height = newHeight + 'px';
86
+ }
87
+ }
88
+
89
+ if(direction === 'top' || direction === 'top-right' || direction === 'top-left') {
90
+ const newHeight = Math.max(sizeConstraint.minHeight, startH - dy);
91
+ if(newHeight > sizeConstraint.minHeight && (!sizeConstraint.maxHeight || newHeight <= sizeConstraint.maxHeight)) {
92
+ parent.style.height = newHeight + 'px';
93
+ parent.style.top = (startTop + dy) + 'px';
94
+ }
95
+ }
96
+
97
+ instance.emit?.('onResize', [e, parent.offsetWidth, parent.offsetHeight]);
98
+ };
99
+
100
+ const onMouseUp = () => {
101
+ if(!isResizing) {
102
+ return;
103
+ }
104
+
105
+ isResizing = false;
106
+ document.body.classList.remove('is-resizing');
107
+ instance.emit?.('onResizeEnd', [parent.offsetWidth, parent.offsetHeight]);
108
+ };
109
+
110
+ handle.addEventListener('mousedown', onMouseDown);
111
+ document.addEventListener('mousemove', onMouseMove);
112
+ document.addEventListener('mouseup', onMouseUp);
113
+ };
@@ -0,0 +1,121 @@
1
+ :root {
2
+ --resize-handle-size: 3px;
3
+ --resize-handle-color: var(--gray-lite-3);
4
+ --resize-handle-color-hover: var(--gray-lite-1);
5
+ --resize-notch-size: 6px;
6
+ }
7
+
8
+ .is-resizable {
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ .resize-handle {
13
+ position: absolute;
14
+ z-index: 10;
15
+
16
+ &.is-right {
17
+ top: 0;
18
+ right: 0;
19
+ width: var(--resize-handle-size);
20
+ height: 100%;
21
+ cursor: ew-resize;
22
+
23
+ &:hover {
24
+ background: var(--resize-handle-color-hover);
25
+ opacity: 0.3;
26
+ }
27
+ }
28
+
29
+ &.is-left {
30
+ top: 0;
31
+ left: 0;
32
+ width: var(--resize-handle-size);
33
+ height: 100%;
34
+ cursor: ew-resize;
35
+
36
+ &:hover {
37
+ background: var(--resize-handle-color-hover);
38
+ opacity: 0.3;
39
+ }
40
+ }
41
+
42
+ &.is-top {
43
+ top: 0;
44
+ left: 0;
45
+ width: 100%;
46
+ height: var(--resize-handle-size);
47
+ cursor: ns-resize;
48
+
49
+ &:hover {
50
+ background: var(--resize-handle-color-hover);
51
+ opacity: 0.3;
52
+ }
53
+ }
54
+
55
+ &.is-bottom {
56
+ bottom: 0;
57
+ left: 0;
58
+ width: 100%;
59
+ height: var(--resize-handle-size);
60
+ cursor: ns-resize;
61
+
62
+ &:hover {
63
+ background: var(--resize-handle-color-hover);
64
+ opacity: 0.3;
65
+ }
66
+ }
67
+
68
+ &.is-top-left {
69
+ top: 0;
70
+ left: 0;
71
+ width: var(--resize-notch-size);
72
+ height: var(--resize-notch-size);
73
+ cursor: nwse-resize;
74
+ }
75
+
76
+ &.is-top-right {
77
+ top: 0;
78
+ right: 0;
79
+ width: var(--resize-notch-size);
80
+ height: var(--resize-notch-size);
81
+ cursor: nesw-resize;
82
+ }
83
+
84
+ &.is-bottom-left {
85
+ bottom: 0;
86
+ left: 0;
87
+ width: var(--resize-notch-size);
88
+ height: var(--resize-notch-size);
89
+ cursor: nesw-resize;
90
+ }
91
+
92
+ &.is-bottom-right {
93
+ bottom: 0;
94
+ right: 0;
95
+ width: var(--resize-notch-size);
96
+ height: var(--resize-notch-size);
97
+ cursor: nwse-resize;
98
+
99
+ &::after {
100
+ content: '';
101
+ position: absolute;
102
+ bottom: 3px;
103
+ right: 3px;
104
+ width: 0;
105
+ height: 0;
106
+ border-style: solid;
107
+ border-width: 0 0 var(--resize-notch-size) var(--resize-notch-size);
108
+ border-color: transparent transparent var(--resize-handle-color) transparent;
109
+ transition: border-color 0.15s ease;
110
+ }
111
+
112
+ &:hover::after {
113
+ border-color: transparent transparent var(--resize-handle-color-hover) transparent;
114
+ }
115
+ }
116
+ }
117
+
118
+ body.is-resizing {
119
+ cursor: nwse-resize;
120
+ user-select: none;
121
+ }
@@ -0,0 +1,86 @@
1
+ import {resolveParams} from "../../form/utils";
2
+ import BaseComponent from "../../BaseComponent";
3
+ import {Validation} from "../../form/validation/Validation";
4
+
5
+ export default function HasValidation() {}
6
+
7
+ HasValidation.prototype.required = function(message) {
8
+ this.$description.rules.push({
9
+ fn: Validation.required,
10
+ message: message || `${this.$description.label || this.$description.name} is required`
11
+ });
12
+ return this;
13
+ };
14
+
15
+ HasValidation.prototype.custom = function(validatorFn, message) {
16
+ this.$description.rules.push({
17
+ validate: validatorFn,
18
+ message: message || 'Validation failed'
19
+ });
20
+ return this;
21
+ };
22
+
23
+ HasValidation.prototype.addRule = function(validationFn, params, message) {
24
+ this.$description.rules.push({
25
+ fn: validationFn,
26
+ params: params || [],
27
+ message
28
+ });
29
+ return this;
30
+ };
31
+
32
+ HasValidation.prototype.requiredIf = function(condition, message) {
33
+ return this.addRule(Validation.requiredIf, [condition], message);
34
+ };
35
+
36
+ HasValidation.prototype.clearErrorOn = function(event) {
37
+ this.$description.clearErrorOn = event;
38
+ return this;
39
+ };
40
+
41
+ HasValidation.prototype.validateOn = function(event) {
42
+ this.$description.validateOn = event;
43
+ return this;
44
+ };
45
+
46
+ HasValidation.prototype.showErrors = function(show = true) {
47
+ this.$description.showErrors = BaseComponent.obs(show);
48
+ return this;
49
+ };
50
+
51
+ HasValidation.prototype.hideErrors = function() {
52
+ this.$description.showErrors.set(false);
53
+ return this;
54
+ };
55
+
56
+ HasValidation.prototype.setError = function(error) {
57
+ this.$description.errors?.set?.(error);
58
+ return this;
59
+ };
60
+
61
+ HasValidation.prototype.validate = function(allValues = {}) {
62
+ if(!this.$description.rules || this.$description.rules.length === 0) {
63
+ this.$description.errors.clear();
64
+ this.$description.hasErrors.set(false);
65
+ return {key: this.$description.key, errors: []};
66
+ }
67
+
68
+ const errors = [];
69
+ const value = this.value();
70
+
71
+ for(const rule of this.$description.rules) {
72
+ const paramsResolved = resolveParams(rule, allValues);
73
+ const validateFn = rule.validate || rule.fn;
74
+ const rawResult = validateFn(value, ...paramsResolved, allValues);
75
+ const result = typeof rawResult === 'boolean' ? {valid: rawResult} : rawResult;
76
+
77
+ if(!result.valid) {
78
+ errors.push(rule.message || result.message);
79
+ }
80
+ }
81
+
82
+ this.$description.errors.set(errors);
83
+ this.$description.hasErrors.set(errors.length > 0);
84
+
85
+ return {key: this.$description.key, errors};
86
+ };
@@ -1,22 +1,40 @@
1
+ import {classPropertyAccumulator, cssPropertyAccumulator} from "../../utils";
2
+ import {Observable} from "../../index";
3
+ import {ShowIf} from "../core/elements/index";
4
+ import Anchor from "../core/elements/anchor/anchor";
5
+ import {NDElement} from "../core/wrappers/NDElement";
6
+
7
+ import './base-component.css';
8
+
9
+
1
10
  /**
2
11
  *
3
12
  * @class
4
13
  */
5
14
  export default function BaseComponent() {
6
15
  this.$description = {};
16
+ this.$editableProps = null;
17
+ this.$attachements = null;
7
18
  }
8
19
 
9
20
  Object.defineProperty( BaseComponent.prototype, 'nd', {
10
21
  get: function() {
11
22
  if(this.$element) {
12
- return this.$element.nd;
23
+ const nd = this.$element.nd;
24
+ if(this.$attachements) {
25
+ nd.$attachements = this.$attachements;
26
+ }
27
+ return nd;
13
28
  }
14
29
  this.$storeElement(this.toNdElement());
15
- return this.$element?.nd;
30
+ const nd = this.$element.nd;
31
+ if(this.$attachements) {
32
+ nd.$attachements = this.$attachements;
33
+ }
34
+ return nd;
16
35
  }
17
36
  });
18
37
 
19
-
20
38
  BaseComponent.extends = function(Component, ...parents) {
21
39
  const MainParent = parents[0] || BaseComponent;
22
40
  Component.prototype = Object.create(MainParent.prototype);
@@ -41,17 +59,39 @@ BaseComponent.obs = (value) => {
41
59
  return value.__$Observable ? value : Observable(value);
42
60
  };
43
61
 
62
+ BaseComponent.prototype.setDescription = function(description) {
63
+ for(const key in description) {
64
+ if(this.$description[key]?.__$Observable) {
65
+ this.$description[key].set(description[key]);
66
+ continue;
67
+ }
68
+ this.$description[key] = description[key];
69
+ }
70
+ return this;
71
+ }
72
+
44
73
  BaseComponent.prototype.$storeElement = function(element) {
45
74
  this.$element = element;
46
75
  return this;
47
76
  };
48
77
 
78
+ BaseComponent.prototype.postBuild = function(callback) {
79
+ this.$postBuild = this.$postBuild || [];
80
+ this.$postBuild.push(callback);
81
+ return this;
82
+ }
83
+
84
+ BaseComponent.prototype.ghostDom = NDElement.prototype.ghostDom;
85
+
49
86
  BaseComponent.prototype.refSelf = function(target, name) {
50
87
  target[name] = this;
51
88
  return this;
52
89
  };
53
90
 
54
91
  BaseComponent.prototype.$build = function() {
92
+ if(this.$beforeRender) {
93
+ this.$beforeRender();
94
+ }
55
95
  const ComponentClass = this.constructor;
56
96
  const renderer = this.$description.render || ComponentClass.defaultTemplate;
57
97
 
@@ -67,9 +107,27 @@ BaseComponent.prototype.toNdElement = function() {
67
107
  return this.$element;
68
108
  }
69
109
  this.$element = this.$build();
110
+ if(this.$description.showIf) {
111
+ this.$element = ShowIf(this.$description.showIf, this.$element);
112
+ }
113
+ if(this.$postBuild) {
114
+ for(let i = 0; i < this.$postBuild.length; i++) {
115
+ this.$postBuild[i](this.$element);
116
+ }
117
+ this.$postBuild = null;
118
+ }
119
+ if(this.$attachements) {
120
+ const nd = this.$element.nd;
121
+ nd.ghostDom(this.$attachements);
122
+ this.$attachements = null;
123
+ return nd;
124
+ }
125
+
70
126
  return this.$element;
71
127
  };
72
128
 
129
+ BaseComponent.prototype.node = BaseComponent.prototype.toNdElement;
130
+
73
131
  BaseComponent.prototype.toJSON = function() {
74
132
  if(!this.$description) {
75
133
  return {};
@@ -83,4 +141,51 @@ BaseComponent.prototype.render = function(renderFn) {
83
141
  }
84
142
  this.$description.render = renderFn;
85
143
  return this;
86
- };
144
+ };
145
+
146
+ BaseComponent.prototype.getEditableProps = function() {
147
+ if(!this.$editableProps) {
148
+ const rawProps = this.$description.props || {};
149
+ this.$editableProps = {
150
+ ...rawProps,
151
+ class: classPropertyAccumulator(rawProps.class || {}),
152
+ style: cssPropertyAccumulator(rawProps.style || {})
153
+ };
154
+ }
155
+
156
+ return this.$editableProps;
157
+ };
158
+
159
+ BaseComponent.prototype.resolveProps = function() {
160
+ if(!this.$editableProps) {
161
+ return this.$description.props ? { ...this.$description.props } : {};
162
+ }
163
+ const props = { ...this.$editableProps };
164
+ if(props.class) {
165
+ props.class = props.class.value();
166
+ }
167
+ if(props.style) {
168
+ props.style = props.style.value();
169
+ }
170
+
171
+ return props;
172
+ };
173
+
174
+
175
+ BaseComponent.prototype.style = function(style) {
176
+ const props = this.getEditableProps();
177
+ props.style.add(style);
178
+ return this;
179
+ };
180
+
181
+ BaseComponent.prototype.showIf = function(condition) {
182
+ this.$description.showIf = BaseComponent.obs(condition);
183
+ return this;
184
+ };
185
+
186
+ BaseComponent.prototype.context = function(context) {
187
+ this.$description.$context = context;
188
+ return this;
189
+ }
190
+
191
+ BaseComponent.prototype.visibility = BaseComponent.prototype.showIf;
@@ -1,5 +1,6 @@
1
1
  import BaseComponent from "../BaseComponent";
2
2
  import HasEventEmitter from "../../core/utils/HasEventEmitter";
3
+ import AccordionItem from "./AccordionItem";
3
4
 
4
5
 
5
6
  /**
@@ -13,40 +14,51 @@ import HasEventEmitter from "../../core/utils/HasEventEmitter";
13
14
  * @returns {Accordion}
14
15
  * @class
15
16
  */
16
- export default function Accordion(config = {}) {
17
+ export default function Accordion(props = {}) {
17
18
  if (!(this instanceof Accordion)) {
18
- return new Accordion(config);
19
+ return new Accordion(props);
19
20
  }
20
21
 
22
+ BaseComponent.call(this, props);
23
+
21
24
  this.$description = {
22
25
  items: [],
23
26
  multiple: null,
24
27
  variant: null,
25
28
  renderContent: null,
26
- ...config
29
+ renderIndicator: null,
30
+ props
27
31
  };
28
32
  }
29
33
 
30
- BaseComponent.extends(Accordion, HasEventEmitter);
34
+ BaseComponent.extends(Accordion);
35
+ BaseComponent.use(Accordion, HasEventEmitter);
31
36
 
32
37
  Accordion.defaultTemplate = null;
33
-
34
-
35
- /**
36
- * Sets the default template for all Accordion instances
37
- * @param {{accordion: (accordion: Accordion) => ValidChildren}} template - Template object containing accordion factory function
38
- */
39
38
  Accordion.use = function(template) {
40
- Accordion.defaultTemplate = template.accordion;
39
+ Accordion.defaultTemplate = template;
41
40
  };
42
41
 
43
- /**
44
- * Adds an accordion item to the collection
45
- * @param {AccordionItem} accordionItem - The accordion item to add
46
- * @returns {Accordion}
47
- */
48
- Accordion.prototype.item = function(accordionItem) {
49
- this.$description.items.push(accordionItem);
42
+
43
+ Accordion.prototype.item = function(title, content, options) {
44
+ let item = null;
45
+
46
+ if(title instanceof AccordionItem) {
47
+ item = title;
48
+ }
49
+ else {
50
+ const config = typeof options === 'object' ? options : {};
51
+ item = new AccordionItem(config);
52
+ item.title(title);
53
+ item.content(content);
54
+ item.setDescription(config);
55
+ }
56
+
57
+ if(typeof options === 'function') {
58
+ options(item);
59
+ }
60
+
61
+ this.$description.items.push(item);
50
62
  return this;
51
63
  };
52
64
 
@@ -219,19 +231,13 @@ Accordion.prototype.renderContent = function(renderFn) {
219
231
  return this;
220
232
  };
221
233
 
234
+
222
235
  /**
223
- * Builds the accordion component
224
- * @private
236
+ * Sets the indicator render function
237
+ * @param {Function} renderFn - Function to render the indicator
238
+ * @returns {AccordionItem}
225
239
  */
226
- Accordion.prototype.$build = function() {
227
- // TODO: Implementation
228
- // this.$description.items.forEach(item => {
229
- // item.onExpand(() => {
230
- // if (!this.$description.multiple) {
231
- // this.$description.items
232
- // .filter(i => i !== item)
233
- // .forEach(i => i.expanded(false));
234
- // }
235
- // });
236
- // });
240
+ Accordion.prototype.renderIndicator = function(renderFn) {
241
+ this.$description.renderIndicator = renderFn;
242
+ return this;
237
243
  };
@@ -1,16 +1,19 @@
1
1
  import { $ } from '../../../index';
2
2
  import BaseComponent from "../BaseComponent";
3
+ import HasEventEmitter from "../../core/utils/HasEventEmitter";
3
4
 
4
5
  /**
5
6
  * Represents an individual item within an Accordion component
6
7
  * @param {{ id?: string|number, title?: string, icon?: string, collapsible?: boolean, content?: ValidChildren, renderHeader?: Function, renderContent?: Function, render?: Function, expanded?: Observable<boolean>, disabled?: boolean }} config - Configuration object
7
8
  * @class
8
9
  */
9
- export default function AccordionItem(config = {}) {
10
+ export default function AccordionItem(props = {}) {
10
11
  if(!(this instanceof AccordionItem)){
11
12
  return new AccordionItem()
12
13
  }
13
14
 
15
+ BaseComponent.call(this, props);
16
+
14
17
  this.$description = {
15
18
  id: null,
16
19
  title: null,
@@ -18,15 +21,22 @@ export default function AccordionItem(config = {}) {
18
21
  collapsible: true,
19
22
  content: null,
20
23
  renderHeader: null,
24
+ renderIndicator: null,
21
25
  renderContent: null,
22
26
  render: null,
23
27
  expanded: $(false),
24
- disabled: false,
25
- ...config
28
+ disabled: $(false),
29
+ props
26
30
  };
27
31
  }
28
32
 
29
33
  BaseComponent.extends(AccordionItem);
34
+ BaseComponent.use(AccordionItem, HasEventEmitter);
35
+
36
+ AccordionItem.defaultTemplate = null;
37
+ AccordionItem.use = function(template) {
38
+ AccordionItem.defaultTemplate = template;
39
+ };
30
40
 
31
41
  /**
32
42
  * Gets the id of the accordion item
@@ -128,7 +138,7 @@ AccordionItem.prototype.toggle = function() {
128
138
  * @returns {AccordionItem}
129
139
  */
130
140
  AccordionItem.prototype.disabled = function(disabled = true) {
131
- this.$description.disabled = disabled;
141
+ this.$description.disabled.set(disabled);
132
142
  return this;
133
143
  };
134
144
 
@@ -189,20 +199,3 @@ AccordionItem.prototype.renderIndicator = function(renderFn) {
189
199
  return this;
190
200
  };
191
201
 
192
- /**
193
- * Sets the render function for the entire item
194
- * @param {Function} renderFn - Function to render the item
195
- * @returns {AccordionItem}
196
- */
197
- AccordionItem.prototype.render = function(renderFn) {
198
- this.$description.render = renderFn;
199
- return this;
200
- }
201
-
202
- /**
203
- * Builds the accordion item component
204
- * @private
205
- */
206
- AccordionItem.prototype.$build = function() {
207
-
208
- };