native-document 1.0.16 → 1.0.17-1.10

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 (681) hide show
  1. package/.npmrc.example +1 -0
  2. package/.vitepress/config.js +166 -0
  3. package/CHANGELOG.md +223 -0
  4. package/cdn.js +19 -0
  5. package/components.d.ts +2 -0
  6. package/components.js +32 -0
  7. package/devtools/ComponentRegistry.js +113 -0
  8. package/devtools/index.js +8 -0
  9. package/devtools/plugin/dev-tools-plugin.js +15 -0
  10. package/devtools/transformers/nd-vite-devtools.js +55 -0
  11. package/devtools/transformers/src/transformComponentForHrm.js +73 -0
  12. package/devtools/transformers/src/transformJsFile.js +9 -0
  13. package/devtools/transformers/src/utils.js +79 -0
  14. package/devtools/transformers/templates/hrm.hook.template.js +46 -0
  15. package/devtools/transformers/templates/hrm.orbservable.hook.template.js +76 -0
  16. package/devtools/widget/Widget.js +49 -0
  17. package/devtools/widget/widget.css +81 -0
  18. package/devtools/widget.js +23 -0
  19. package/dist/native-document.components.min.css +1 -0
  20. package/dist/native-document.components.min.js +23873 -0
  21. package/dist/native-document.dev.js +8464 -1515
  22. package/dist/native-document.dev.js.map +1 -0
  23. package/dist/native-document.devtools.min.js +1 -0
  24. package/dist/native-document.min.js +1 -1
  25. package/docs/advanced-components.md +419 -0
  26. package/docs/anchor.md +181 -257
  27. package/docs/cache.md +180 -0
  28. package/docs/cli.md +179 -0
  29. package/docs/components/accordion.md +172 -0
  30. package/docs/components/alert.md +99 -0
  31. package/docs/components/avatar.md +160 -0
  32. package/docs/components/badge.md +102 -0
  33. package/docs/components/breadcrumb.md +89 -0
  34. package/docs/components/button.md +183 -0
  35. package/docs/components/card.md +69 -0
  36. package/docs/components/context-menu.md +118 -0
  37. package/docs/components/data-table.md +345 -0
  38. package/docs/components/dropdown.md +214 -0
  39. package/docs/components/form/autocomplete-field.md +81 -0
  40. package/docs/components/form/checkbox-field.md +41 -0
  41. package/docs/components/form/checkbox-group-field.md +54 -0
  42. package/docs/components/form/color-field.md +64 -0
  43. package/docs/components/form/date-field.md +92 -0
  44. package/docs/components/form/field-collection.md +63 -0
  45. package/docs/components/form/file-field.md +203 -0
  46. package/docs/components/form/form-control.md +87 -0
  47. package/docs/components/form/image-field.md +90 -0
  48. package/docs/components/form/index.md +115 -0
  49. package/docs/components/form/number-field.md +65 -0
  50. package/docs/components/form/radio-field.md +51 -0
  51. package/docs/components/form/select-field.md +123 -0
  52. package/docs/components/form/slider.md +136 -0
  53. package/docs/components/form/string-field.md +134 -0
  54. package/docs/components/form/textarea-field.md +65 -0
  55. package/docs/components/form-fields.md +372 -0
  56. package/docs/components/getting-started.md +264 -0
  57. package/docs/components/icons.md +321 -0
  58. package/docs/components/index.md +337 -0
  59. package/docs/components/layout.md +279 -0
  60. package/docs/components/list.md +73 -0
  61. package/docs/components/menu.md +215 -0
  62. package/docs/components/modal.md +156 -0
  63. package/docs/components/pagination.md +95 -0
  64. package/docs/components/popover.md +131 -0
  65. package/docs/components/progress.md +111 -0
  66. package/docs/components/shortcut-manager.md +221 -0
  67. package/docs/components/simple-table.md +107 -0
  68. package/docs/components/skeleton.md +155 -0
  69. package/docs/components/spinner.md +100 -0
  70. package/docs/components/splitter.md +133 -0
  71. package/docs/components/stepper.md +163 -0
  72. package/docs/components/switch.md +113 -0
  73. package/docs/components/tabs.md +153 -0
  74. package/docs/components/toast.md +119 -0
  75. package/docs/components/tooltip.md +151 -0
  76. package/docs/components/traits.md +261 -0
  77. package/docs/conditional-rendering.md +177 -502
  78. package/docs/contributing.md +300 -25
  79. package/docs/core-concepts.md +207 -366
  80. package/docs/elements.md +266 -254
  81. package/docs/extending-native-document-element.md +259 -0
  82. package/docs/filters.md +247 -0
  83. package/docs/getting-started.md +195 -257
  84. package/docs/i18n.md +241 -0
  85. package/docs/index.md +76 -0
  86. package/docs/lifecycle-events.md +146 -67
  87. package/docs/list-rendering.md +240 -460
  88. package/docs/memory-management.md +135 -46
  89. package/docs/native-document-element.md +487 -0
  90. package/docs/native-fetch.md +213 -0
  91. package/docs/observable-resource.md +364 -0
  92. package/docs/observables.md +690 -357
  93. package/docs/routing.md +246 -646
  94. package/docs/state-management.md +213 -306
  95. package/docs/svg-elements.md +231 -0
  96. package/docs/theming.md +409 -0
  97. package/docs/tutorials/.gitkeep +0 -0
  98. package/docs/validation.md +98 -91
  99. package/docs/vitepress-conventions.md +219 -0
  100. package/elements.d.ts +7 -0
  101. package/elements.js +3 -4
  102. package/eslint.config.js +35 -0
  103. package/i18n.js +1 -0
  104. package/i18n.ts +2 -0
  105. package/index.d.ts +21 -0
  106. package/index.def.js +1086 -0
  107. package/index.js +19 -13
  108. package/package.json +65 -8
  109. package/readme.md +296 -93
  110. package/rollup.config.js +52 -3
  111. package/router.d.ts +7 -0
  112. package/router.js +0 -0
  113. package/src/components/$traits/has-draggable/HasDraggable.d.ts +4 -0
  114. package/src/components/$traits/has-draggable/HasDraggable.js +82 -0
  115. package/src/components/$traits/has-draggable/has-draggable.css +8 -0
  116. package/src/components/$traits/has-items/HasItems.d.ts +9 -0
  117. package/src/components/$traits/has-items/HasItems.js +64 -0
  118. package/src/components/$traits/has-position/HasFullPosition.d.ts +14 -0
  119. package/src/components/$traits/has-position/HasFullPosition.js +95 -0
  120. package/src/components/$traits/has-position/HasPosition.d.ts +7 -0
  121. package/src/components/$traits/has-position/HasPosition.js +45 -0
  122. package/src/components/$traits/has-resizable/HasResizable.d.ts +13 -0
  123. package/src/components/$traits/has-resizable/HasResizable.js +122 -0
  124. package/src/components/$traits/has-resizable/has-resizable.css +121 -0
  125. package/src/components/$traits/has-validation/HasValidation.d.ts +17 -0
  126. package/src/components/$traits/has-validation/HasValidation.js +133 -0
  127. package/src/components/BaseComponent.d.ts +32 -0
  128. package/src/components/BaseComponent.js +289 -0
  129. package/src/components/accordion/Accordion.js +269 -0
  130. package/src/components/accordion/AccordionItem.js +234 -0
  131. package/src/components/accordion/index.js +7 -0
  132. package/src/components/accordion/types/Accordion.d.ts +47 -0
  133. package/src/components/accordion/types/AccordionItem.d.ts +48 -0
  134. package/src/components/alert/Alert.js +354 -0
  135. package/src/components/alert/index.js +6 -0
  136. package/src/components/alert/types/Alert.d.ts +62 -0
  137. package/src/components/avatar/Avatar.js +431 -0
  138. package/src/components/avatar/AvatarGroup.js +98 -0
  139. package/src/components/avatar/index.js +7 -0
  140. package/src/components/avatar/types/Avatar.d.ts +74 -0
  141. package/src/components/avatar/types/AvatarGroup.d.ts +32 -0
  142. package/src/components/badge/Badge.js +246 -0
  143. package/src/components/badge/index.js +6 -0
  144. package/src/components/badge/types/Badge.d.ts +51 -0
  145. package/src/components/base-component.css +0 -0
  146. package/src/components/breadcrumb/BreadCrumb.js +142 -0
  147. package/src/components/breadcrumb/index.js +5 -0
  148. package/src/components/breadcrumb/types/BreadCrumb.d.ts +42 -0
  149. package/src/components/button/Button.js +321 -0
  150. package/src/components/button/index.js +5 -0
  151. package/src/components/button/types/Button.d.ts +62 -0
  152. package/src/components/card/Card.js +283 -0
  153. package/src/components/card/index.js +5 -0
  154. package/src/components/card/types/Card.d.ts +42 -0
  155. package/src/components/context-menu/ContextMenu.js +129 -0
  156. package/src/components/context-menu/ContextMenuGroup.js +31 -0
  157. package/src/components/context-menu/ContextMenuItem.js +30 -0
  158. package/src/components/context-menu/index.js +10 -0
  159. package/src/components/context-menu/types/ContextMenu.d.ts +30 -0
  160. package/src/components/context-menu/types/ContextMenuGroup.d.ts +18 -0
  161. package/src/components/context-menu/types/ContextMenuItem.d.ts +18 -0
  162. package/src/components/divider/Divider.js +258 -0
  163. package/src/components/divider/index.js +6 -0
  164. package/src/components/divider/types/Divider.d.ts +55 -0
  165. package/src/components/dropdown/Dropdown.js +532 -0
  166. package/src/components/dropdown/DropdownDivider.js +46 -0
  167. package/src/components/dropdown/DropdownGroup.js +84 -0
  168. package/src/components/dropdown/DropdownItem.js +151 -0
  169. package/src/components/dropdown/DropdownTrigger.js +94 -0
  170. package/src/components/dropdown/helpers.js +53 -0
  171. package/src/components/dropdown/index.js +13 -0
  172. package/src/components/dropdown/types/Dropdown.d.ts +88 -0
  173. package/src/components/dropdown/types/DropdownDivider.d.ts +20 -0
  174. package/src/components/dropdown/types/DropdownGroup.d.ts +25 -0
  175. package/src/components/dropdown/types/DropdownItem.d.ts +41 -0
  176. package/src/components/dropdown/types/DropdownTrigger.d.ts +32 -0
  177. package/src/components/form/FormControl.js +499 -0
  178. package/src/components/form/field/Field.js +420 -0
  179. package/src/components/form/field/FieldCollection.js +292 -0
  180. package/src/components/form/field/types/AutocompleteField.js +168 -0
  181. package/src/components/form/field/types/CheckboxField.js +77 -0
  182. package/src/components/form/field/types/CheckboxGroupField.js +171 -0
  183. package/src/components/form/field/types/ColorField.js +102 -0
  184. package/src/components/form/field/types/DateField.js +315 -0
  185. package/src/components/form/field/types/EmailField.js +104 -0
  186. package/src/components/form/field/types/FileField.js +276 -0
  187. package/src/components/form/field/types/HiddenField.js +44 -0
  188. package/src/components/form/field/types/ImageField.js +138 -0
  189. package/src/components/form/field/types/NumberField.js +177 -0
  190. package/src/components/form/field/types/PasswordField.js +200 -0
  191. package/src/components/form/field/types/RadioField.js +145 -0
  192. package/src/components/form/field/types/RangeField.js +117 -0
  193. package/src/components/form/field/types/SearchField.js +66 -0
  194. package/src/components/form/field/types/SelectField.js +247 -0
  195. package/src/components/form/field/types/StringField.js +148 -0
  196. package/src/components/form/field/types/TelField.js +98 -0
  197. package/src/components/form/field/types/TextAreaField.js +142 -0
  198. package/src/components/form/field/types/TimeField.js +215 -0
  199. package/src/components/form/field/types/UrlField.js +115 -0
  200. package/src/components/form/field/types/file-field-mode/FileAvatarMode.js +183 -0
  201. package/src/components/form/field/types/file-field-mode/FileDropzoneMode.js +117 -0
  202. package/src/components/form/field/types/file-field-mode/FileItemPreview.js +150 -0
  203. package/src/components/form/field/types/file-field-mode/FileNativeMode.js +43 -0
  204. package/src/components/form/field/types/file-field-mode/FileUploadButtonMode.js +120 -0
  205. package/src/components/form/field/types/file-field-mode/FileWallMode.js +106 -0
  206. package/src/components/form/index.js +61 -0
  207. package/src/components/form/merge +0 -0
  208. package/src/components/form/types/Field.d.ts +73 -0
  209. package/src/components/form/types/FieldCollection.d.ts +53 -0
  210. package/src/components/form/types/FormControl.d.ts +64 -0
  211. package/src/components/form/types/fields/AutocompleteField.d.ts +48 -0
  212. package/src/components/form/types/fields/CheckboxField.d.ts +33 -0
  213. package/src/components/form/types/fields/CheckboxGroupField.d.ts +49 -0
  214. package/src/components/form/types/fields/ColorField.d.ts +37 -0
  215. package/src/components/form/types/fields/DateField.d.ts +70 -0
  216. package/src/components/form/types/fields/EmailField.d.ts +35 -0
  217. package/src/components/form/types/fields/FileAvatarMode.d.ts +46 -0
  218. package/src/components/form/types/fields/FileDropzoneMode.d.ts +28 -0
  219. package/src/components/form/types/fields/FileField.d.ts +56 -0
  220. package/src/components/form/types/fields/FileItemPreview.d.ts +35 -0
  221. package/src/components/form/types/fields/FileNativeMode.d.ts +21 -0
  222. package/src/components/form/types/fields/FileUploadButtonMode.d.ts +34 -0
  223. package/src/components/form/types/fields/FileWallMode.d.ts +32 -0
  224. package/src/components/form/types/fields/HiddenField.d.ts +26 -0
  225. package/src/components/form/types/fields/ImageField.d.ts +45 -0
  226. package/src/components/form/types/fields/NumberField.d.ts +48 -0
  227. package/src/components/form/types/fields/PasswordField.d.ts +46 -0
  228. package/src/components/form/types/fields/RadioField.d.ts +48 -0
  229. package/src/components/form/types/fields/RangeField.d.ts +44 -0
  230. package/src/components/form/types/fields/SearchField.d.ts +34 -0
  231. package/src/components/form/types/fields/SelectField.d.ts +71 -0
  232. package/src/components/form/types/fields/StringField.d.ts +48 -0
  233. package/src/components/form/types/fields/TelField.d.ts +37 -0
  234. package/src/components/form/types/fields/TextAreaField.d.ts +44 -0
  235. package/src/components/form/types/fields/TimeField.d.ts +51 -0
  236. package/src/components/form/types/fields/UrlField.d.ts +35 -0
  237. package/src/components/form/utils.js +17 -0
  238. package/src/components/form/validation/Validation.js +565 -0
  239. package/src/components/icon/Icon.js +108 -0
  240. package/src/components/icon/icon-getters.js +142 -0
  241. package/src/components/icon/icons.js +171 -0
  242. package/src/components/icon/index.js +17 -0
  243. package/src/components/icon/types/Icon.d.ts +191 -0
  244. package/src/components/index.d.ts +165 -0
  245. package/src/components/list/HasListItem.js +171 -0
  246. package/src/components/list/List.js +125 -0
  247. package/src/components/list/ListDivider.js +39 -0
  248. package/src/components/list/ListGroup.js +135 -0
  249. package/src/components/list/ListItem.js +213 -0
  250. package/src/components/list/index.js +12 -0
  251. package/src/components/list/types/List.d.ts +56 -0
  252. package/src/components/list/types/ListDivider.ts +16 -0
  253. package/src/components/list/types/ListGroup.d.ts +59 -0
  254. package/src/components/list/types/ListItem.d.ts +52 -0
  255. package/src/components/menu/HasMenuItem.js +182 -0
  256. package/src/components/menu/Menu.js +230 -0
  257. package/src/components/menu/MenuDivider.js +38 -0
  258. package/src/components/menu/MenuGroup.js +127 -0
  259. package/src/components/menu/MenuItem.js +191 -0
  260. package/src/components/menu/MenuLink.js +52 -0
  261. package/src/components/menu/index.js +14 -0
  262. package/src/components/menu/types/Menu.d.ts +60 -0
  263. package/src/components/menu/types/MenuDivider.d.ts +19 -0
  264. package/src/components/menu/types/MenuGroup.d.ts +44 -0
  265. package/src/components/menu/types/MenuItem.d.ts +46 -0
  266. package/src/components/menu/types/MenuLink.d.ts +16 -0
  267. package/src/components/modal/Modal.js +528 -0
  268. package/src/components/modal/index.js +5 -0
  269. package/src/components/modal/types/Modal.d.ts +94 -0
  270. package/src/components/pagination/Pagination.js +412 -0
  271. package/src/components/pagination/index.js +5 -0
  272. package/src/components/pagination/types/Pagination.d.ts +68 -0
  273. package/src/components/popover/Popover.js +460 -0
  274. package/src/components/popover/PopoverFooter.js +62 -0
  275. package/src/components/popover/PopoverHeader.js +69 -0
  276. package/src/components/popover/index.js +10 -0
  277. package/src/components/popover/types/Popover.d.ts +83 -0
  278. package/src/components/popover/types/PopoverFooter.d.ts +24 -0
  279. package/src/components/popover/types/PopoverHeader.d.ts +26 -0
  280. package/src/components/progress/Progress.js +406 -0
  281. package/src/components/progress/index.js +6 -0
  282. package/src/components/progress/types/Progress.d.ts +77 -0
  283. package/src/components/skeleton/Skeleton.js +232 -0
  284. package/src/components/skeleton/index.js +6 -0
  285. package/src/components/skeleton/types/Skeleton.d.ts +55 -0
  286. package/src/components/slider/Slider.js +407 -0
  287. package/src/components/slider/index.js +5 -0
  288. package/src/components/slider/types/Slider.d.ts +82 -0
  289. package/src/components/spacer/Spacer.js +28 -0
  290. package/src/components/spacer/index.js +5 -0
  291. package/src/components/spacer/types/Spacer.d.ts +19 -0
  292. package/src/components/spinner/Spinner.js +351 -0
  293. package/src/components/spinner/index.js +5 -0
  294. package/src/components/spinner/types/Spinner.d.ts +71 -0
  295. package/src/components/splitter/Splitter.js +165 -0
  296. package/src/components/splitter/SplitterGutter.js +146 -0
  297. package/src/components/splitter/SplitterPanel.js +144 -0
  298. package/src/components/splitter/index.js +10 -0
  299. package/src/components/splitter/types/Splitter.d.ts +38 -0
  300. package/src/components/splitter/types/SplitterGutter.d.ts +38 -0
  301. package/src/components/splitter/types/SplitterPanel.d.ts +41 -0
  302. package/src/components/stacks/AbsoluteStack.js +54 -0
  303. package/src/components/stacks/FixedStack.js +54 -0
  304. package/src/components/stacks/HStack.js +55 -0
  305. package/src/components/stacks/PositionStack.js +255 -0
  306. package/src/components/stacks/RelativeStack.js +54 -0
  307. package/src/components/stacks/Stack.js +167 -0
  308. package/src/components/stacks/VStack.js +56 -0
  309. package/src/components/stacks/index.js +21 -0
  310. package/src/components/stacks/types/AbsoluteStack.d.ts +16 -0
  311. package/src/components/stacks/types/FixedStack.d.ts +16 -0
  312. package/src/components/stacks/types/HStack.d.ts +16 -0
  313. package/src/components/stacks/types/PositionStack.d.ts +54 -0
  314. package/src/components/stacks/types/RelativeStack.d.ts +17 -0
  315. package/src/components/stacks/types/Stack.d.ts +39 -0
  316. package/src/components/stacks/types/VStack.d.ts +16 -0
  317. package/src/components/stepper/Stepper.js +462 -0
  318. package/src/components/stepper/StepperStep.js +242 -0
  319. package/src/components/stepper/index.js +8 -0
  320. package/src/components/stepper/types/Stepper.d.ts +68 -0
  321. package/src/components/stepper/types/StepperStep.d.ts +54 -0
  322. package/src/components/switch/Switch.js +267 -0
  323. package/src/components/switch/index.js +6 -0
  324. package/src/components/switch/types/Switch.d.ts +55 -0
  325. package/src/components/table/Column.js +212 -0
  326. package/src/components/table/ColumnGroup.js +90 -0
  327. package/src/components/table/DataTable.js +721 -0
  328. package/src/components/table/SimpleTable.js +140 -0
  329. package/src/components/table/index.js +7 -0
  330. package/src/components/table/types/Column.d.ts +49 -0
  331. package/src/components/table/types/ColumnGroup.d.ts +28 -0
  332. package/src/components/table/types/DataTable.d.ts +97 -0
  333. package/src/components/table/types/SimpleTable.d.ts +40 -0
  334. package/src/components/tabs/Tabs.js +396 -0
  335. package/src/components/tabs/index.js +6 -0
  336. package/src/components/tabs/types/Tabs.d.ts +78 -0
  337. package/src/components/toast/Toast.js +263 -0
  338. package/src/components/toast/ToastError.js +0 -0
  339. package/src/components/toast/ToastInfo.js +0 -0
  340. package/src/components/toast/ToastSuccess.js +0 -0
  341. package/src/components/toast/ToastWarning.js +0 -0
  342. package/src/components/toast/index.js +5 -0
  343. package/src/components/toast/types/Toast.d.ts +57 -0
  344. package/src/components/toast/types/ToastError.d.ts +7 -0
  345. package/src/components/toast/types/ToastInfo.d.ts +7 -0
  346. package/src/components/toast/types/ToastSuccess.d.ts +7 -0
  347. package/src/components/toast/types/ToastWarning.d.ts +7 -0
  348. package/src/components/tooltip/Tooltip.js +360 -0
  349. package/src/components/tooltip/index.js +5 -0
  350. package/src/components/tooltip/prototypes.js +6 -0
  351. package/src/components/tooltip/types/Tooltip.d.ts +65 -0
  352. package/src/{data → core/data}/MemoryManager.js +8 -4
  353. package/src/core/data/Observable.js +227 -0
  354. package/src/core/data/ObservableArray.js +522 -0
  355. package/src/core/data/ObservableChecker.js +39 -0
  356. package/src/core/data/ObservableItem.js +629 -0
  357. package/src/core/data/ObservableObject.js +274 -0
  358. package/src/core/data/ObservableResource.js +315 -0
  359. package/src/core/data/ObservableWhen.js +54 -0
  360. package/src/core/data/Store.js +520 -0
  361. package/src/core/data/observable-helpers/observable.is-to.js +390 -0
  362. package/src/core/data/observable-helpers/observable.prototypes.js +145 -0
  363. package/src/core/elements/anchor/anchor-with-sentinel.js +66 -0
  364. package/src/core/elements/anchor/anchor.js +211 -0
  365. package/src/core/elements/anchor/one-child-anchor-overwriting.js +66 -0
  366. package/src/core/elements/content-formatter.js +202 -0
  367. package/src/core/elements/control/for-each-array-cache.js +59 -0
  368. package/src/core/elements/control/for-each-array.js +284 -0
  369. package/src/{elements → core/elements}/control/for-each.js +42 -23
  370. package/src/core/elements/control/show-if.js +94 -0
  371. package/src/core/elements/control/show-when.js +54 -0
  372. package/src/core/elements/control/switch.js +141 -0
  373. package/src/core/elements/description-list.js +19 -0
  374. package/src/core/elements/form.js +255 -0
  375. package/src/core/elements/fragment.js +8 -0
  376. package/src/core/elements/html5-semantics.js +55 -0
  377. package/src/core/elements/img.js +59 -0
  378. package/src/{elements → core/elements}/index.js +4 -4
  379. package/src/core/elements/interactive.js +25 -0
  380. package/src/core/elements/list.js +37 -0
  381. package/src/core/elements/medias.js +37 -0
  382. package/src/core/elements/meta-data.js +43 -0
  383. package/src/core/elements/svg.js +61 -0
  384. package/src/core/elements/table.js +73 -0
  385. package/src/{errors → core/errors}/ArgTypesError.js +1 -1
  386. package/src/{errors → core/errors}/NativeDocumentError.js +0 -0
  387. package/src/core/utils/HasEventEmitter.js +85 -0
  388. package/src/core/utils/args-types.js +140 -0
  389. package/src/core/utils/cache.js +5 -0
  390. package/src/core/utils/callback-handler.js +50 -0
  391. package/src/core/utils/debug-manager.js +40 -0
  392. package/src/core/utils/events.js +148 -0
  393. package/src/core/utils/filters/date.js +178 -0
  394. package/src/core/utils/filters/index.js +4 -0
  395. package/src/core/utils/filters/standard.js +263 -0
  396. package/src/core/utils/filters/strings.js +67 -0
  397. package/src/core/utils/filters/utils.js +77 -0
  398. package/src/core/utils/formatters.js +90 -0
  399. package/src/core/utils/helpers.js +144 -0
  400. package/src/core/utils/localstorage.js +57 -0
  401. package/src/core/utils/memoize.js +115 -0
  402. package/src/core/utils/plugins-manager.js +81 -0
  403. package/src/core/utils/property-accumulator.js +72 -0
  404. package/src/core/utils/prototypes.js +44 -0
  405. package/src/core/utils/shortcut-manager.js +242 -0
  406. package/src/{utils → core/utils}/validator.js +58 -22
  407. package/src/core/wrappers/AttributesWrapper.js +196 -0
  408. package/src/core/wrappers/DocumentObserver.js +182 -0
  409. package/src/core/wrappers/ElementCreator.js +140 -0
  410. package/src/core/wrappers/HtmlElementWrapper.js +122 -0
  411. package/src/core/wrappers/NDElement.js +639 -0
  412. package/src/core/wrappers/NdPrototype.js +225 -0
  413. package/src/core/wrappers/SingletonView.js +99 -0
  414. package/src/core/wrappers/SvgElementWrapper.js +15 -0
  415. package/src/core/wrappers/TemplateBinding.js +7 -0
  416. package/src/core/wrappers/constants.js +66 -0
  417. package/src/core/wrappers/prototypes/attributes-extensions.js +24 -0
  418. package/src/core/wrappers/prototypes/bind-class-extensions.js +0 -0
  419. package/src/core/wrappers/prototypes/nd-element-extensions.js +201 -0
  420. package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +127 -0
  421. package/src/core/wrappers/template-cloner/NodeCloner.js +209 -0
  422. package/src/core/wrappers/template-cloner/TemplateCloner.js +192 -0
  423. package/src/core/wrappers/template-cloner/attributes-hydrator.js +142 -0
  424. package/src/core/wrappers/template-cloner/utils.js +173 -0
  425. package/src/fetch/NativeFetch.js +89 -0
  426. package/src/i18n/bin/scan.js +132 -0
  427. package/src/i18n/index.d.ts +2 -0
  428. package/src/i18n/service/I18nService.d.ts +27 -0
  429. package/src/i18n/service/I18nService.js +46 -0
  430. package/src/i18n/service/functions.d.ts +22 -0
  431. package/src/i18n/service/functions.js +29 -0
  432. package/src/router/Route.js +33 -8
  433. package/src/router/RouteGroupHelper.js +10 -2
  434. package/src/router/Router.js +63 -22
  435. package/src/router/RouterComponent.js +114 -6
  436. package/src/{errors → router/errors}/RouterError.js +0 -1
  437. package/src/router/link.js +8 -9
  438. package/src/router/modes/HashRouter.js +2 -2
  439. package/src/router/modes/HistoryRouter.js +2 -3
  440. package/src/router/modes/MemoryRouter.js +1 -1
  441. package/src/ui/components/accordion/AccordionItemRender.js +85 -0
  442. package/src/ui/components/accordion/AccordionRender.js +35 -0
  443. package/src/ui/components/accordion/accordion.css +121 -0
  444. package/src/ui/components/alert/AlertRender.js +87 -0
  445. package/src/ui/components/alert/alert.css +163 -0
  446. package/src/ui/components/avatar/avata-group/AvatarGroupRender.js +50 -0
  447. package/src/ui/components/avatar/avata-group/avatar-group.css +38 -0
  448. package/src/ui/components/avatar/avatar/AvatarRender.js +87 -0
  449. package/src/ui/components/avatar/avatar/avatar.css +189 -0
  450. package/src/ui/components/badge/BadgeRender.js +25 -0
  451. package/src/ui/components/badge/badge.css +168 -0
  452. package/src/ui/components/breadcrumb/BreadcrumbRender.js +52 -0
  453. package/src/ui/components/breadcrumb/breadcrumb.css +55 -0
  454. package/src/ui/components/button/ButtonRender.js +68 -0
  455. package/src/ui/components/button/button.css +296 -0
  456. package/src/ui/components/card/CardRender.js +133 -0
  457. package/src/ui/components/card/card.css +169 -0
  458. package/src/ui/components/contextmenu/ContextmenuRender.js +70 -0
  459. package/src/ui/components/contextmenu/contextmenu.css +36 -0
  460. package/src/ui/components/divider/DividerRender.js +70 -0
  461. package/src/ui/components/divider/divider.css +70 -0
  462. package/src/ui/components/dropdown/DropdownRender.js +95 -0
  463. package/src/ui/components/dropdown/divider/DropdownDividerRender.js +9 -0
  464. package/src/ui/components/dropdown/divider/dropdown-divider.css +0 -0
  465. package/src/ui/components/dropdown/dropdown.css +179 -0
  466. package/src/ui/components/dropdown/group/DropdownGroupRender.js +23 -0
  467. package/src/ui/components/dropdown/group/dropdown-group.css +0 -0
  468. package/src/ui/components/dropdown/item/DropdownItemRender.js +34 -0
  469. package/src/ui/components/dropdown/item/dropdown-item.css +0 -0
  470. package/src/ui/components/form/FieldCollectionRender.js +114 -0
  471. package/src/ui/components/form/FormControlRender.js +85 -0
  472. package/src/ui/components/form/field-collection.css +55 -0
  473. package/src/ui/components/form/fields/AutocompleteFieldRender.js +143 -0
  474. package/src/ui/components/form/fields/CheckboxFieldRender.js +63 -0
  475. package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +96 -0
  476. package/src/ui/components/form/fields/ColorFieldRender.js +30 -0
  477. package/src/ui/components/form/fields/DateFieldRender.js +155 -0
  478. package/src/ui/components/form/fields/EmailFieldRender.js +5 -0
  479. package/src/ui/components/form/fields/FieldRender.js +118 -0
  480. package/src/ui/components/form/fields/FileFieldRender.js +41 -0
  481. package/src/ui/components/form/fields/HiddenFieldRender.js +13 -0
  482. package/src/ui/components/form/fields/ImageFieldRender.js +0 -0
  483. package/src/ui/components/form/fields/NumberFieldRender.js +52 -0
  484. package/src/ui/components/form/fields/PasswordFieldRender.js +65 -0
  485. package/src/ui/components/form/fields/RadioFieldRender.js +81 -0
  486. package/src/ui/components/form/fields/RangeFieldRender.js +126 -0
  487. package/src/ui/components/form/fields/SelectFieldRender.js +253 -0
  488. package/src/ui/components/form/fields/SliderFieldRender.js +362 -0
  489. package/src/ui/components/form/fields/StringFieldRender.js +6 -0
  490. package/src/ui/components/form/fields/TelFieldRender.js +6 -0
  491. package/src/ui/components/form/fields/TextAreaFieldRender.js +96 -0
  492. package/src/ui/components/form/fields/TimeFieldRender.js +142 -0
  493. package/src/ui/components/form/fields/UrlFieldRender.js +6 -0
  494. package/src/ui/components/form/fields/date-field.css +32 -0
  495. package/src/ui/components/form/fields/field.css +402 -0
  496. package/src/ui/components/form/fields/file-field.css +79 -0
  497. package/src/ui/components/form/fields/password-field.css +50 -0
  498. package/src/ui/components/form/fields/range-field.css +120 -0
  499. package/src/ui/components/form/fields/slider.css +195 -0
  500. package/src/ui/components/form/file-upload-mode/FileAvatarModeRender.js +143 -0
  501. package/src/ui/components/form/file-upload-mode/FileDropzoneModeRender.js +108 -0
  502. package/src/ui/components/form/file-upload-mode/FileNativeModeRender.js +22 -0
  503. package/src/ui/components/form/file-upload-mode/FileUploadButtonModeRender.js +89 -0
  504. package/src/ui/components/form/file-upload-mode/FileWallModeRender.js +90 -0
  505. package/src/ui/components/form/file-upload-mode/file-avatar-mode.css +139 -0
  506. package/src/ui/components/form/file-upload-mode/file-dropzone-mode.css +88 -0
  507. package/src/ui/components/form/file-upload-mode/file-upload-button-mode.css +44 -0
  508. package/src/ui/components/form/file-upload-mode/file-wall-mode.css +88 -0
  509. package/src/ui/components/form/form-control.css +40 -0
  510. package/src/ui/components/form/helpers.js +111 -0
  511. package/src/ui/components/form/index.js +27 -0
  512. package/src/ui/components/icon/material/MaterialIconRender.js +71 -0
  513. package/src/ui/components/icon/material/material.css +15 -0
  514. package/src/ui/components/icon/material/material.map.js +170 -0
  515. package/src/ui/components/icon/phosphor/PhosphorIconRender.js +71 -0
  516. package/src/ui/components/icon/phosphor/phosphor.css +17 -0
  517. package/src/ui/components/icon/phosphor/phosphor.map.js +165 -0
  518. package/src/ui/components/icon/tabler/TablerIconRender.js +58 -0
  519. package/src/ui/components/icon/tabler/tabler.css +14 -0
  520. package/src/ui/components/icon/tabler/tabler.map.js +165 -0
  521. package/src/ui/components/list/ListRender.js +18 -0
  522. package/src/ui/components/list/divider/ListDividerRender.js +10 -0
  523. package/src/ui/components/list/divider/list-divider.css +12 -0
  524. package/src/ui/components/list/group/ListGroupRender.js +61 -0
  525. package/src/ui/components/list/group/list-group.css +62 -0
  526. package/src/ui/components/list/item/ListItemRender.js +242 -0
  527. package/src/ui/components/list/item/list-item.css +191 -0
  528. package/src/ui/components/list/list.css +24 -0
  529. package/src/ui/components/menu/MenuDividerRender.js +12 -0
  530. package/src/ui/components/menu/MenuGroupRender.js +59 -0
  531. package/src/ui/components/menu/MenuItemRender.js +65 -0
  532. package/src/ui/components/menu/MenuLinkRender.js +66 -0
  533. package/src/ui/components/menu/MenuRender.js +27 -0
  534. package/src/ui/components/menu/helpers.js +122 -0
  535. package/src/ui/components/menu/menu.css +308 -0
  536. package/src/ui/components/modal/ModalRender.js +124 -0
  537. package/src/ui/components/modal/modal.css +156 -0
  538. package/src/ui/components/pagination/PaginationRender.js +112 -0
  539. package/src/ui/components/pagination/pagination.css +63 -0
  540. package/src/ui/components/popover/PopoverRender.js +233 -0
  541. package/src/ui/components/popover/popover.css +139 -0
  542. package/src/ui/components/progress/ProgressRender.js +177 -0
  543. package/src/ui/components/progress/progress.css +197 -0
  544. package/src/ui/components/skeleton/SkeletonRender.js +138 -0
  545. package/src/ui/components/skeleton/skeleton.css +154 -0
  546. package/src/ui/components/spacer/SpacerRender.js +10 -0
  547. package/src/ui/components/spinner/SpinnerRender.js +50 -0
  548. package/src/ui/components/spinner/spinner.css +152 -0
  549. package/src/ui/components/splitter/SplitterGutterRender.js +98 -0
  550. package/src/ui/components/splitter/SplitterPanelRender.js +42 -0
  551. package/src/ui/components/splitter/SplitterRender.js +77 -0
  552. package/src/ui/components/splitter/splitter.css +128 -0
  553. package/src/ui/components/stacks/PositionStackRender.js +39 -0
  554. package/src/ui/components/stacks/StackRender.js +41 -0
  555. package/src/ui/components/stacks/absolute-stack/AbsoluteStackRender.js +5 -0
  556. package/src/ui/components/stacks/fixed-stack/FixedStackRender.js +5 -0
  557. package/src/ui/components/stacks/h-stack/HStackRender.js +7 -0
  558. package/src/ui/components/stacks/h-stack/h-stack.css +4 -0
  559. package/src/ui/components/stacks/index.js +5 -0
  560. package/src/ui/components/stacks/position-stack.css +62 -0
  561. package/src/ui/components/stacks/relative-stack/RelativeStackRender.js +7 -0
  562. package/src/ui/components/stacks/relative-stack/relative-stack.css +3 -0
  563. package/src/ui/components/stacks/stack.css +78 -0
  564. package/src/ui/components/stacks/v-stack/VStackRender.js +6 -0
  565. package/src/ui/components/stacks/v-stack/v-stack.css +4 -0
  566. package/src/ui/components/stepper/StepperRender.js +72 -0
  567. package/src/ui/components/stepper/StepperStepRender.js +74 -0
  568. package/src/ui/components/stepper/stepper.css +359 -0
  569. package/src/ui/components/switch/SwitchRender.js +86 -0
  570. package/src/ui/components/switch/switch.css +143 -0
  571. package/src/ui/components/table/data-table/DataTableRender.js +54 -0
  572. package/src/ui/components/table/data-table/bulk-actions.js +34 -0
  573. package/src/ui/components/table/data-table/data-table.css +246 -0
  574. package/src/ui/components/table/data-table/pagination.js +56 -0
  575. package/src/ui/components/table/data-table/tables.js +368 -0
  576. package/src/ui/components/table/data-table/toolbar.js +67 -0
  577. package/src/ui/components/table/simple-table/SimpleTableRender.js +205 -0
  578. package/src/ui/components/table/simple-table/simple-table.css +50 -0
  579. package/src/ui/components/tabs/TabsRender.js +226 -0
  580. package/src/ui/components/tabs/tabs.css +253 -0
  581. package/src/ui/components/toast/ToastRender.js +103 -0
  582. package/src/ui/components/toast/toast.css +201 -0
  583. package/src/ui/components/tooltip/TooltipRender.js +8 -0
  584. package/src/ui/components/tooltip/tooltip.css +113 -0
  585. package/src/ui/index.js +52 -0
  586. package/src/ui/theme.js +0 -0
  587. package/src/ui/theme.scss +1 -0
  588. package/src/ui/tokens/animation.scss +36 -0
  589. package/src/ui/tokens/colors-dark.scss +58 -0
  590. package/src/ui/tokens/colors.scss +54 -0
  591. package/src/ui/tokens/components.scss +32 -0
  592. package/src/ui/tokens/fonts.scss +57 -0
  593. package/src/ui/tokens/glass.scss +10 -0
  594. package/src/ui/tokens/index.scss +38 -0
  595. package/src/ui/tokens/layouts.scss +228 -0
  596. package/src/ui/tokens/opacity.scss +21 -0
  597. package/src/ui/tokens/others.scss +11 -0
  598. package/src/ui/tokens/radius.scss +6 -0
  599. package/src/ui/tokens/reset.scss +51 -0
  600. package/src/ui/tokens/shadows.scss +29 -0
  601. package/src/ui/tokens/spacings.scss +13 -0
  602. package/src/ui/tokens/vars.scss +35 -0
  603. package/src/ui/tokens/viewports.scss +30 -0
  604. package/src/ui/utils/aria.js +19 -0
  605. package/tests/integration/ui/attributes-wrapper.test.js +177 -0
  606. package/tests/integration/ui/for-each-array.test.js +167 -0
  607. package/tests/integration/ui/lifecycle.test.js +146 -0
  608. package/tests/integration/ui/show-if.test.js +168 -0
  609. package/tests/unit/core/observable-array.test.js +404 -0
  610. package/tests/unit/core/observable-item.test.js +428 -0
  611. package/tests/unit/core/observable-object.test.js +239 -0
  612. package/tests/unit/core/observable-resource.test.js +323 -0
  613. package/tests/unit/core/store.test.js +347 -0
  614. package/tests/unit/router/route-matching.test.js +169 -0
  615. package/tests/unit/router/router-guards.test.js +189 -0
  616. package/tests/unit/utils/cache.test.js +120 -0
  617. package/tests/unit/utils/filters.test.js +394 -0
  618. package/types/args-types.d.ts +58 -0
  619. package/types/control-flow.d.ts +62 -0
  620. package/types/elements.d.ts +236 -0
  621. package/types/filters/dates.d.ts +43 -0
  622. package/types/filters/index.d.ts +4 -0
  623. package/types/filters/standard.d.ts +70 -0
  624. package/types/filters/strings.d.ts +21 -0
  625. package/types/filters/types.d.ts +20 -0
  626. package/types/forms.d.ts +84 -0
  627. package/types/globals.d.ts +543 -0
  628. package/types/images.d.ts +23 -0
  629. package/types/localStorage.ts +102 -0
  630. package/types/memoize.d.ts +26 -0
  631. package/types/native-fetch.d.ts +72 -0
  632. package/types/nd-element.d.ts +407 -0
  633. package/types/observable-resource.d.ts +3 -0
  634. package/types/observable.d.ts +227 -0
  635. package/types/plugins-manager.d.ts +65 -0
  636. package/types/polyfill.d.ts +18 -0
  637. package/types/property-accumulator.d.ts +33 -0
  638. package/types/router.d.ts +85 -0
  639. package/types/service.d.ts +23 -0
  640. package/types/singleton.d.ts +19 -0
  641. package/types/store.d.ts +63 -0
  642. package/types/template-cloner.ts +43 -0
  643. package/types/validator.ts +66 -0
  644. package/ui.js +1 -0
  645. package/utils.d.ts +4 -0
  646. package/utils.js +12 -0
  647. package/vitest.config.js +15 -0
  648. package/src/data/Observable.js +0 -55
  649. package/src/data/ObservableChecker.js +0 -39
  650. package/src/data/ObservableItem.js +0 -195
  651. package/src/data/Store.js +0 -74
  652. package/src/data/observable-helpers/array.js +0 -74
  653. package/src/data/observable-helpers/batch.js +0 -22
  654. package/src/data/observable-helpers/computed.js +0 -28
  655. package/src/data/observable-helpers/object.js +0 -111
  656. package/src/elements/anchor.js +0 -129
  657. package/src/elements/content-formatter.js +0 -32
  658. package/src/elements/control/for-each-array.js +0 -280
  659. package/src/elements/control/show-if.js +0 -79
  660. package/src/elements/control/switch.js +0 -98
  661. package/src/elements/description-list.js +0 -5
  662. package/src/elements/form.js +0 -71
  663. package/src/elements/html5-semantics.js +0 -12
  664. package/src/elements/img.js +0 -45
  665. package/src/elements/interactive.js +0 -7
  666. package/src/elements/list.js +0 -10
  667. package/src/elements/medias.js +0 -8
  668. package/src/elements/meta-data.js +0 -9
  669. package/src/elements/table.js +0 -14
  670. package/src/utils/args-types.js +0 -100
  671. package/src/utils/debug-manager.js +0 -31
  672. package/src/utils/helpers.js +0 -60
  673. package/src/utils/plugins-manager.js +0 -12
  674. package/src/utils/prototypes.js +0 -45
  675. package/src/wrappers/AttributesWrapper.js +0 -144
  676. package/src/wrappers/DocumentObserver.js +0 -80
  677. package/src/wrappers/ElementCreator.js +0 -114
  678. package/src/wrappers/HtmlElementEventsWrapper.js +0 -64
  679. package/src/wrappers/HtmlElementWrapper.js +0 -50
  680. package/src/wrappers/NdPrototype.js +0 -106
  681. package/src/wrappers/constants.js +0 -2
@@ -0,0 +1,284 @@
1
+ import Anchor from '../anchor/anchor';
2
+ import { ElementCreator } from '../../wrappers/ElementCreator';
3
+ import NativeDocumentError from '../../errors/NativeDocumentError';
4
+ import ForEachArrayCache from './for-each-array-cache';
5
+
6
+
7
+ const CREATE_AND_CACHE_ACTIONS = new Set(['clear', 'push', 'unshift', 'replace']);
8
+
9
+ const SELF_RENDER = (item) => item;
10
+
11
+ /**
12
+ * Renders items from an ObservableArray with optimized array-specific updates.
13
+ * Provides index observables and handles array mutations efficiently.
14
+ *
15
+ * @param {ObservableArray} data - ObservableArray to iterate over
16
+ * @param {((item: *, index: null|ObservableItem) => NdChild)?} callback - Function that renders each item (item, indexObservable) => ValidChild
17
+ * @param {Object?} [configs={}] - Configuration options
18
+ * @param {boolean} [configs.shouldKeepItemsInCache] - Whether to cache rendered items
19
+ * @param {boolean} [configs.isParentUniqueChild] - When it's the only child of the parent
20
+ * @returns {AnchorDocumentFragment} Fragment managing the list rendering
21
+ * @example
22
+ * const items = Observable.array([1, 2, 3]);
23
+ * ForEachArray(items, (item, index) =>
24
+ * Div({}, `Item ${item} at index ${index.val()}`)
25
+ * );
26
+ *
27
+ * items.push(4); // Automatically updates DOM
28
+ */
29
+ export function ForEachArray(data, callback, configs = {}) {
30
+ callback = callback || SELF_RENDER;
31
+ const element = Anchor('ForEach Array', configs.isParentUniqueChild);
32
+ const blockEnd = element.endElement();
33
+
34
+ let lastNumberOfItems = 0;
35
+ const isIndexRequired = callback.length >= 2;
36
+ const cache = new ForEachArrayCache(isIndexRequired);
37
+
38
+ const clear = (items) => {
39
+ element.removeChildren();
40
+ cleanCache(items);
41
+ lastNumberOfItems = 0;
42
+ };
43
+
44
+ const getItemChild = (item) => {
45
+ return cache.get(item)?.child;
46
+ };
47
+
48
+ const removeCacheItem = (item, removeChild = true) => {
49
+ const cacheItem = cache.get(item);
50
+ if(!cacheItem) {
51
+ return;
52
+ }
53
+ if(removeChild) {
54
+ const child = cacheItem.child;
55
+ child?.remove();
56
+ cache.delete(item);
57
+ }
58
+ cacheItem.indexObserver?.cleanup();
59
+ };
60
+
61
+ const createAndCache = (item) => {
62
+ const child = ElementCreator.getChild(callback(item, null));
63
+ if(process.env.NODE_ENV === 'development') {
64
+ if(!child) {
65
+ throw new NativeDocumentError('ForEachArray child can\'t be null or undefined!');
66
+ }
67
+ }
68
+ cache.set(item, child);
69
+ return child;
70
+ };
71
+
72
+ let createWithIndexAndCache = (item, indexKey) => {
73
+ const indexObserver = data.transform((items) => items.indexOf(item));
74
+ const child = ElementCreator.getChild(callback(item, indexObserver));
75
+ if(process.env.NODE_ENV === 'development') {
76
+ if(!child) {
77
+ throw new NativeDocumentError('ForEachArray child can\'t be null or undefined!');
78
+ }
79
+ }
80
+ cache.set(item, child, indexObserver);
81
+ return child;
82
+ };
83
+ if(!data.__$Observable) {
84
+ createWithIndexAndCache = (item, indexKey) => {
85
+ const child = ElementCreator.getChild(callback(item, indexKey));
86
+ if(process.env.NODE_ENV === 'development') {
87
+ if(!child) {
88
+ throw new NativeDocumentError('ForEachArray child can\'t be null or undefined!');
89
+ }
90
+ }
91
+ cache.set(item, child);
92
+ return child;
93
+ };
94
+ }
95
+
96
+ const getOrCreate = (item, indexKey) => {
97
+ const cacheItem = cache.get(item);
98
+ if(cacheItem) {
99
+ cacheItem.indexObserver?.set(indexKey);
100
+ return cacheItem.child;
101
+ }
102
+ return createAndCache(item, indexKey);
103
+ };
104
+
105
+ let buildItem = createAndCache;
106
+ const selectBuildStrategy = (action = null) => {
107
+ if(CREATE_AND_CACHE_ACTIONS.has(action)) {
108
+ buildItem = isIndexRequired ? createWithIndexAndCache : createAndCache;
109
+ return;
110
+ }
111
+ buildItem = cache.size ? getOrCreate : (isIndexRequired ? createWithIndexAndCache : createAndCache);
112
+ };
113
+
114
+
115
+ let cleanCache;
116
+
117
+ if(!isIndexRequired) {
118
+ cleanCache = cache.clear.bind(cache);
119
+ }
120
+ else if(configs.shouldKeepItemsInCache) {
121
+ cleanCache = () => {};
122
+ } else {
123
+ cleanCache = (items) => {
124
+ for (const [itemAsKey, _] of cache.entries()) {
125
+ if(items && items.includes(itemAsKey)) {
126
+ continue;
127
+ }
128
+ removeCacheItem(itemAsKey, false);
129
+ }
130
+ };
131
+ }
132
+
133
+ const removeByItem = (item, fragment) => {
134
+ const cacheItem = cache.get(item);
135
+ if(!cacheItem) {
136
+ return null;
137
+ }
138
+ const child = cacheItem.child;
139
+ if(!child) {
140
+ return null;
141
+ }
142
+
143
+ if(fragment) {
144
+ fragment.appendChild(child);
145
+ return;
146
+ }
147
+ child.remove();
148
+ };
149
+
150
+ let set = null;
151
+ if(Array.isArray(data)) {
152
+ set = () => {
153
+ clear(data);
154
+ Actions.appendToElement(data);
155
+ };
156
+ }
157
+ else {
158
+ set = () => {
159
+ const items = data.val();
160
+ clear(items);
161
+ Actions.appendToElement(items);
162
+ };
163
+ }
164
+
165
+ const Actions = {
166
+ toFragment: (items) =>{
167
+ const fragment = document.createDocumentFragment();
168
+ for(let i = 0, length = items.length; i < length; i++) {
169
+ fragment.appendChild(buildItem(items[i], lastNumberOfItems));
170
+ }
171
+ return fragment;
172
+ },
173
+ appendToElement: (items) => {
174
+ for(let i = 0, length = items.length; i < length; i++) {
175
+ element.appendChild(buildItem(items[i], i));
176
+ }
177
+ },
178
+ add: (items) => {
179
+ Actions.appendToElement(items);
180
+ },
181
+ replace: (items) => {
182
+ clear(items);
183
+ Actions.appendToElement(items);
184
+ },
185
+ set,
186
+ reOrder: (items) => {
187
+ let child = null;
188
+ for(const item of items) {
189
+ child = getItemChild(item);
190
+ if(child) {
191
+ element.appendChild(child);
192
+ }
193
+ }
194
+ child = null;
195
+ },
196
+ removeOne: (element, index) => {
197
+ removeCacheItem(element, true);
198
+ },
199
+ clear,
200
+ unshift: (values) => {
201
+ element.insertAtStartRaw(Actions.toFragment(values));
202
+ },
203
+ splice: (args, deleted) => {
204
+ const [start, deleteCount, ...values] = args;
205
+ let elementBeforeFirst = null;
206
+ const garbageFragment = document.createDocumentFragment();
207
+
208
+ if(deleted.length > 0) {
209
+ const firstItem = deleted[0];
210
+ if(deleted.length === 1) {
211
+ removeByItem(firstItem, garbageFragment);
212
+ } else if(deleted.length > 1) {
213
+ const firstChildRemoved = getItemChild(deleted[0]);
214
+ elementBeforeFirst = firstChildRemoved?.previousSibling;
215
+
216
+ for(let i = 0; i < deleted.length; i++) {
217
+ removeByItem(deleted[i], garbageFragment);
218
+ }
219
+ }
220
+ } else {
221
+ const indexBefore = (start - 1 >= 0) ? start - 1 : start;
222
+ const itemAtStart = data.at(indexBefore);
223
+ elementBeforeFirst = getItemChild(itemAtStart) || blockEnd.previousSibling;
224
+ }
225
+ garbageFragment.replaceChildren();
226
+
227
+ if(values && values.length && elementBeforeFirst) {
228
+ element.insertBeforeRaw(Actions.toFragment(values), elementBeforeFirst.nextSibling);
229
+ }
230
+
231
+ },
232
+ reverse: (_, reversed) => {
233
+ Actions.reOrder(reversed);
234
+ },
235
+ sort: (_, sorted) => {
236
+ Actions.reOrder(sorted);
237
+ },
238
+ remove: (_, deleted)=> {
239
+ Actions.removeOne(deleted);
240
+ },
241
+ pop: (_, deleted) => {
242
+ Actions.removeOne(deleted);
243
+ },
244
+ shift: (_, deleted) => {
245
+ Actions.removeOne(deleted);
246
+ },
247
+ swap: (args, elements) => {
248
+ const parent = element.getParent();
249
+
250
+ let childA = getItemChild(elements[0]);
251
+ let childB = getItemChild(elements[1]);
252
+ if(!childA || !childB) {
253
+ return;
254
+ }
255
+
256
+ const childBNext = childB.nextSibling;
257
+ parent.insertBefore(childB, childA);
258
+ parent.insertBefore(childA, childBNext);
259
+ childA = null;
260
+ childB = null;
261
+ },
262
+ };
263
+ Actions.merge = Actions.add;
264
+ Actions.push = Actions.add;
265
+
266
+ const buildContent = (items, _, operations = {}) => {
267
+ selectBuildStrategy(operations.action);
268
+
269
+ if(Actions[operations.action]) {
270
+ Actions[operations.action](operations.args, operations.result);
271
+ }
272
+ };
273
+
274
+ if(Array.isArray(data)) {
275
+ buildContent(data, null, { action: 'set' });
276
+ return element;
277
+ }
278
+
279
+ if(data.val().length) {
280
+ buildContent(data.val(), null, { action: 'set' });
281
+ }
282
+ data.subscribe(buildContent);
283
+ return element;
284
+ }
@@ -1,24 +1,40 @@
1
- import ObservableItem from "../../data/ObservableItem";
2
- import {Observable} from "../../data/Observable";
3
- import {createTextNode} from "../../wrappers/HtmlElementWrapper";
4
- import Validator from "../../utils/validator";
5
- import Anchor from "../anchor";
6
- import DebugManager from "../../utils/debug-manager";
7
- import {getKey} from "../../utils/helpers";
1
+ import {Observable} from '../../data/Observable';
2
+ import Validator from '../../utils/validator';
3
+ import Anchor from '../anchor/anchor';
4
+ import DebugManager from '../../utils/debug-manager';
5
+ import {getKey} from '../../utils/helpers';
6
+ import { ElementCreator } from '../../wrappers/ElementCreator';
7
+ import NativeDocumentError from '../../errors/NativeDocumentError';
8
+
9
+ const SELF_RENDER = (item) => item;
8
10
 
9
11
  /**
12
+ * Renders a list of items from an observable array or object, automatically updating when data changes.
13
+ * Efficiently manages DOM updates by tracking items with keys.
14
+ *
15
+ * @param {ObservableItem<Array|Object>} data - Observable containing array or object to iterate over
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
19
+ * @param {boolean} [options.shouldKeepItemsInCache=false] - Whether to cache rendered items
20
+ * @returns {AnchorDocumentFragment} Fragment managing the list rendering
21
+ * @example
22
+ * const users = Observable([
23
+ * { id: 1, name: 'John' },
24
+ * { id: 2, name: 'Jane' }
25
+ * ]);
26
+ * ForEach(users, (user) => Div({}, user.name), 'id');
10
27
  *
11
- * @param {Array|Object|ObservableItem} data
12
- * @param {Function} callback
13
- * @param {?Function} key
14
- * @returns {DocumentFragment}
28
+ * // With function key
29
+ * ForEach(items, (item) => Div({}, item), (item) => item.id);
15
30
  */
16
- export function ForEach(data, callback, key) {
17
- const element = new Anchor('ForEach');
31
+ export function ForEach(data, callback, key, { shouldKeepItemsInCache = false } = {}) {
32
+ callback = callback || SELF_RENDER;
33
+ const element = Anchor('ForEach');
18
34
  const blockEnd = element.endElement();
19
35
  const blockStart = element.startElement();
20
36
 
21
- let cache = new Map();
37
+ const cache = new Map();
22
38
  let lastKeyOrder = null;
23
39
  const keyIds = new Set();
24
40
 
@@ -28,13 +44,16 @@ export function ForEach(data, callback, key) {
28
44
  };
29
45
 
30
46
  const cleanCache = (parent) => {
47
+ if(shouldKeepItemsInCache) {
48
+ return;
49
+ }
31
50
  for(const [keyId, cacheItem] of cache.entries()) {
32
51
  if(keyIds.has(keyId)) {
33
52
  continue;
34
53
  }
35
54
  const child = cacheItem.child?.deref();
36
55
  if(parent && child) {
37
- parent.removeChild(child);
56
+ child.remove();
38
57
  }
39
58
  cacheItem.indexObserver?.cleanup();
40
59
  cacheItem.child = null;
@@ -59,9 +78,9 @@ export function ForEach(data, callback, key) {
59
78
 
60
79
  try {
61
80
  const indexObserver = callback.length >= 2 ? Observable(indexKey) : null;
62
- let child = callback(item, indexObserver);
63
- if(Validator.isStringOrObservable(child)) {
64
- child = createTextNode(child);
81
+ const child = ElementCreator.getChild(callback(item, indexObserver));
82
+ if(!child) {
83
+ throw new NativeDocumentError('ForEach child can\'t be null or undefined!');
65
84
  }
66
85
  cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
67
86
  } catch (e) {
@@ -82,15 +101,15 @@ export function ForEach(data, callback, key) {
82
101
  child && fragment.appendChild(child);
83
102
  }
84
103
  parent.insertBefore(fragment, blockEnd);
85
- }
104
+ };
86
105
 
87
106
  const diffingDOMUpdates = (parent) => {
88
107
  const operations = [];
89
- let fragment = document.createDocumentFragment();
108
+ const fragment = document.createDocumentFragment();
90
109
  const newKeys = Array.from(keyIds);
91
110
  const oldKeys = Array.from(lastKeyOrder);
92
111
 
93
- let currentPosition = blockStart;
112
+ const currentPosition = blockStart;
94
113
 
95
114
  for(const index in newKeys) {
96
115
  const itemKey = newKeys[index];
@@ -117,7 +136,7 @@ export function ForEach(data, callback, key) {
117
136
  keyIds.clear();
118
137
  if(Array.isArray(items)) {
119
138
  for(let i = 0, length = items.length; i < length; i++) {
120
- const keyId= handleContentItem(items[i], i);
139
+ const keyId = handleContentItem(items[i], i);
121
140
  keyIds.add(keyId);
122
141
  }
123
142
  } else {
@@ -145,7 +164,7 @@ export function ForEach(data, callback, key) {
145
164
 
146
165
  buildContent();
147
166
  if(Validator.isObservable(data)) {
148
- data.subscribe(buildContent)
167
+ data.subscribe(buildContent);
149
168
  }
150
169
  return element;
151
170
  }
@@ -0,0 +1,94 @@
1
+ import { Observable } from '../../data/Observable';
2
+ import Validator from '../../utils/validator';
3
+ import DebugManager from '../../utils/debug-manager.js';
4
+ import Anchor from '../anchor/anchor';
5
+ import {ElementCreator} from '../../wrappers/ElementCreator';
6
+
7
+ /**
8
+ * Conditionally shows an element based on an observable condition.
9
+ * The element is mounted/unmounted from the DOM as the condition changes.
10
+ *
11
+ * @param {ObservableItem<boolean>|ObservableChecker<boolean>|ObservableWhen} condition - Observable condition to watch
12
+ * @param {NdChild|(() => NdChild)} child - Element or content to show/hide
13
+ * @param {Object} [options={}] - Configuration options
14
+ * @param {string|null} [options.comment=null] - Comment for debugging
15
+ * @param {boolean} [options.shouldKeepInCache=true] - Whether to cache the element when hidden
16
+ * @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
17
+ * @example
18
+ * const isVisible = Observable(false);
19
+ * ShowIf(isVisible, Div({}, 'Hello World'));
20
+ */
21
+ export const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
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);
28
+ }
29
+ const element = Anchor('Show if : '+(comment || ''));
30
+
31
+ let childElement = null;
32
+ const getChildElement = () => {
33
+ if(childElement && shouldKeepInCache) {
34
+ return childElement;
35
+ }
36
+ childElement = ElementCreator.getChild(child);
37
+ if(Validator.isFragment(childElement)) {
38
+ childElement = Array.from(childElement.childNodes);
39
+ }
40
+ return childElement;
41
+ };
42
+
43
+ const currentValue = condition.val();
44
+
45
+ if(currentValue) {
46
+ element.appendChild(getChildElement());
47
+ }
48
+
49
+ condition.subscribe((value) => {
50
+ if(value) {
51
+ element.appendChild(getChildElement());
52
+ return;
53
+ }
54
+ element.remove();
55
+ });
56
+
57
+ return element;
58
+ };
59
+
60
+ /**
61
+ * Conditionally hides an element when the observable condition is true.
62
+ * Inverse of ShowIf - element is shown when condition is false.
63
+ *
64
+ * @param {ObservableItem<boolean>|ObservableChecker<boolean>} condition - Observable condition to watch
65
+ * @param {NdChild|(() => NdChild)} child - Element or content to show/hide
66
+ * @param {Object} [configs] - Configuration options
67
+ * @param {string|null} [configs.comment] - Comment for debugging
68
+ * @param {boolean} [configs.shouldKeepInCache] - Whether to cache element when hidden
69
+ * @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
70
+ * @example
71
+ * const hasError = Observable(false);
72
+ * HideIf(hasError, Div({}, 'Content'));
73
+ */
74
+ export const HideIf = function(condition, child, configs) {
75
+ const hideCondition = Observable(!condition.val());
76
+ condition.subscribe(value => hideCondition.set(!value));
77
+
78
+ return ShowIf(hideCondition, child, configs);
79
+ };
80
+
81
+ /**
82
+ * Conditionally hides an element when the observable condition is false.
83
+ * Same as ShowIf - element is shown when condition is true.
84
+ *
85
+ * @param {ObservableItem<boolean>|ObservableChecker<boolean>|ObservableWhen} condition - Observable condition to watch
86
+ * @param {NdChild|(() => NdChild)} child - Element or content to show/hide
87
+ * @param {Object} [configs] - Configuration options
88
+ * @param {string|null} [configs.comment] - Comment for debugging
89
+ * @param {boolean} [configs.shouldKeepInCache] - Whether to cache element when hidden
90
+ * @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
91
+ */
92
+ export const HideIfNot = function(condition, child, configs) {
93
+ return ShowIf(condition, child, configs);
94
+ };
@@ -0,0 +1,54 @@
1
+ import Validator from '../../utils/validator.js';
2
+ import NativeDocumentError from '../../errors/NativeDocumentError.js';
3
+ import {ShowIf} from './show-if.js';
4
+
5
+ /**
6
+ * Shows content when an observable equals a specific value.
7
+ * Can be called with 2 or 3 arguments.
8
+ *
9
+ * @overload
10
+ * @param {ObservableWhen} observerWhenResult - Result from observable.when(value)
11
+ * @param {NdChild|(() => NdChild)} view - Content to show when condition matches
12
+ * @returns {AnchorDocumentFragment}
13
+ *
14
+ * @overload
15
+ * @param {ObservableItem} observer - Observable to watch
16
+ * @param {*} target - Value to match
17
+ * @param {NdChild|(() => NdChild)} view - Content to show when observable equals target
18
+ * @returns {AnchorDocumentFragment}
19
+ *
20
+ * @example
21
+ * // 2 arguments
22
+ * const status = Observable('idle');
23
+ * ShowWhen(status.when('loading'), LoadingSpinner());
24
+ *
25
+ * // 3 arguments
26
+ * ShowWhen(status, 'loading', LoadingSpinner());
27
+ */
28
+ export const ShowWhen = function() {
29
+ if(arguments.length === 2) {
30
+ const [observer, target] = arguments;
31
+ if(!Validator.isObservableWhenResult(observer)) {
32
+ throw new NativeDocumentError('showWhen observer must be an ObservableWhenResult', {
33
+ data: observer,
34
+ 'help': 'Use observer.when(target) to create an ObservableWhenResult',
35
+ });
36
+ }
37
+ return ShowIf(observer, target);
38
+ }
39
+ if(arguments.length === 3) {
40
+ const [observer, target, view] = arguments;
41
+ if(!Validator.isObservable(observer)) {
42
+ throw new NativeDocumentError('showWhen observer must be an Observable', {
43
+ data: observer,
44
+ });
45
+ }
46
+ return ShowIf(observer.when(target), view);
47
+ }
48
+ throw new NativeDocumentError('showWhen must have 2 or 3 arguments', {
49
+ data: [
50
+ 'showWhen(observer, target, view)',
51
+ 'showWhen(observerWhenResult, view)',
52
+ ],
53
+ });
54
+ };
@@ -0,0 +1,141 @@
1
+ import NativeDocumentError from '../../errors/NativeDocumentError';
2
+ import Validator from '../../utils/validator';
3
+ import Anchor from '../anchor/anchor';
4
+ import {ElementCreator} from '../../wrappers/ElementCreator';
5
+
6
+
7
+
8
+ /**
9
+ * Displays different content based on the current value of an observable.
10
+ * Like a switch statement for UI - shows the content corresponding to current value.
11
+ *
12
+ * @param {ObservableItem|ObservableChecker} $condition - Observable to watch
13
+ * @param {Object<string|number, NdChild|(() => NdChild)>} values - Map of values to their corresponding content
14
+ * @param {boolean} [shouldKeepInCache=true] - Whether to cache rendered views
15
+ * @returns {AnchorDocumentFragment & {add: Function, remove: Function}} Fragment with dynamic methods
16
+ * @example
17
+ * const status = Observable('idle');
18
+ * const view = Match(status, {
19
+ * idle: Div({}, 'Ready'),
20
+ * loading: Div({}, 'Loading...'),
21
+ * error: Div({}, 'Error occurred')
22
+ * });
23
+ *
24
+ * // Dynamic addition
25
+ * view.add('success', Div({}, 'Success!'));
26
+ * view.remove('idle');
27
+ */
28
+ export const Match = function($condition, values, shouldKeepInCache = true) {
29
+
30
+ if(!Validator.isObservable($condition)) {
31
+ throw new NativeDocumentError('Toggle : condition must be an Observable');
32
+ }
33
+
34
+ const anchor = Anchor('Match');
35
+ const cache = new Map();
36
+
37
+ const getItem = function(key) {
38
+ if(shouldKeepInCache && cache.has(key)) {
39
+ return cache.get(key);
40
+ }
41
+ let item = values[key];
42
+ if(!item) {
43
+ return null;
44
+ }
45
+ item = ElementCreator.getChild(item);
46
+ if(Validator.isFragment(item)) {
47
+ item = Array.from(item.children);
48
+ }
49
+ shouldKeepInCache && cache.set(key, item);
50
+ return item;
51
+ };
52
+
53
+ const defaultValue = $condition.val();
54
+ const defaultContent = getItem(defaultValue);
55
+ if(defaultContent) {
56
+ anchor.appendChild(defaultContent);
57
+ }
58
+
59
+ $condition.subscribe(value => {
60
+ const content = getItem(value);
61
+ anchor.remove();
62
+ if(content) {
63
+ anchor.appendChild(content);
64
+ }
65
+ });
66
+
67
+ return anchor.nd.with({
68
+ add(key, view, shouldFocusOn = false) {
69
+ values[key] = view;
70
+ if(shouldFocusOn) {
71
+ $condition.set(key);
72
+ }
73
+ },
74
+ remove(key) {
75
+ shouldKeepInCache && cache.delete(key);
76
+ $condition.set([...cache.keys()].at(-1) ?? '');
77
+ delete values[key];
78
+ },
79
+ });
80
+ };
81
+
82
+
83
+ /**
84
+ * Displays one of two views based on a boolean observable condition.
85
+ * Simplified version of Match for true/false cases.
86
+ *
87
+ * @param {ObservableItem<boolean>|ObservableChecker<boolean>} $condition - Boolean observable to watch
88
+ * @param {ValidChild} onTrue - Content to show when condition is true
89
+ * @param {ValidChild} onFalse - Content to show when condition is false
90
+ * @returns {AnchorDocumentFragment} Fragment managing the conditional content
91
+ * @example
92
+ * const isLoggedIn = Observable(false);
93
+ * Switch(isLoggedIn,
94
+ * Div({}, 'Welcome back!'),
95
+ * Div({}, 'Please login')
96
+ * );
97
+ */
98
+ export const Switch = function ($condition, onTrue, onFalse) {
99
+ if(!Validator.isObservable($condition)) {
100
+ throw new NativeDocumentError('Toggle : condition must be an Observable');
101
+ }
102
+
103
+ return Match($condition.toBoolean(), {
104
+ true: onTrue,
105
+ false: onFalse,
106
+ });
107
+ };
108
+
109
+ /**
110
+ * Provides a fluent API for conditional rendering with show/otherwise pattern.
111
+ *
112
+ * @param {ObservableItem<boolean>|ObservableChecker<boolean>} $condition - Boolean observable to watch
113
+ * @returns {{show: Function, otherwise: Function}} Object with fluent methods
114
+ * @example
115
+ * const isLoading = Observable(false);
116
+ * When(isLoading)
117
+ * .show(LoadingSpinner())
118
+ * .otherwise(Content());
119
+ */
120
+ export const When = function($condition) {
121
+ if(!Validator.isObservable($condition)) {
122
+ throw new NativeDocumentError('When : condition must be an Observable');
123
+ }
124
+
125
+ let $onTrue = null;
126
+ let $onFalse = null;
127
+
128
+ return {
129
+ show(onTrue) {
130
+ $onTrue = onTrue;
131
+ return this;
132
+ },
133
+ otherwise(onFalse) {
134
+ $onFalse = onFalse;
135
+ return Switch($condition, $onTrue, $onFalse);
136
+ },
137
+ toNdElement() {
138
+ return Switch($condition, $onTrue, $onFalse);
139
+ },
140
+ };
141
+ };