native-document 1.0.15 → 1.0.16-8.2

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 (649) hide show
  1. package/.npmrc.example +1 -0
  2. package/.vitepress/config.js +166 -0
  3. package/CHANGELOG.md +153 -0
  4. package/cdn.js +19 -0
  5. package/components.d.ts +2 -0
  6. package/components.js +30 -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 +23847 -0
  21. package/dist/native-document.dev.js +8421 -1492
  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/index.md +337 -0
  58. package/docs/components/layout.md +279 -0
  59. package/docs/components/list.md +73 -0
  60. package/docs/components/menu.md +215 -0
  61. package/docs/components/modal.md +156 -0
  62. package/docs/components/pagination.md +95 -0
  63. package/docs/components/popover.md +131 -0
  64. package/docs/components/progress.md +111 -0
  65. package/docs/components/shortcut-manager.md +221 -0
  66. package/docs/components/simple-table.md +107 -0
  67. package/docs/components/skeleton.md +155 -0
  68. package/docs/components/spinner.md +100 -0
  69. package/docs/components/splitter.md +133 -0
  70. package/docs/components/stepper.md +163 -0
  71. package/docs/components/switch.md +113 -0
  72. package/docs/components/tabs.md +153 -0
  73. package/docs/components/toast.md +119 -0
  74. package/docs/components/tooltip.md +151 -0
  75. package/docs/components/traits.md +261 -0
  76. package/docs/conditional-rendering.md +177 -502
  77. package/docs/contributing.md +300 -25
  78. package/docs/core-concepts.md +207 -366
  79. package/docs/elements.md +266 -254
  80. package/docs/extending-native-document-element.md +259 -0
  81. package/docs/filters.md +247 -0
  82. package/docs/getting-started.md +195 -257
  83. package/docs/i18n.md +241 -0
  84. package/docs/index.md +76 -0
  85. package/docs/lifecycle-events.md +146 -67
  86. package/docs/list-rendering.md +240 -460
  87. package/docs/memory-management.md +135 -46
  88. package/docs/native-document-element.md +487 -0
  89. package/docs/native-fetch.md +213 -0
  90. package/docs/observable-resource.md +364 -0
  91. package/docs/observables.md +690 -357
  92. package/docs/routing.md +246 -646
  93. package/docs/state-management.md +213 -306
  94. package/docs/svg-elements.md +231 -0
  95. package/docs/theming.md +409 -0
  96. package/docs/tutorials/.gitkeep +0 -0
  97. package/docs/validation.md +98 -91
  98. package/docs/vitepress-conventions.md +219 -0
  99. package/elements.d.ts +7 -0
  100. package/elements.js +3 -4
  101. package/eslint.config.js +35 -0
  102. package/i18n.js +1 -0
  103. package/i18n.ts +2 -0
  104. package/index.d.ts +21 -0
  105. package/index.def.js +1086 -0
  106. package/index.js +19 -13
  107. package/package.json +59 -9
  108. package/readme.md +296 -93
  109. package/rollup.config.js +52 -3
  110. package/router.d.ts +7 -0
  111. package/router.js +0 -0
  112. package/src/components/$traits/has-draggable/HasDraggable.d.ts +4 -0
  113. package/src/components/$traits/has-draggable/HasDraggable.js +82 -0
  114. package/src/components/$traits/has-draggable/has-draggable.css +8 -0
  115. package/src/components/$traits/has-items/HasItems.d.ts +9 -0
  116. package/src/components/$traits/has-items/HasItems.js +64 -0
  117. package/src/components/$traits/has-position/HasFullPosition.d.ts +14 -0
  118. package/src/components/$traits/has-position/HasFullPosition.js +95 -0
  119. package/src/components/$traits/has-position/HasPosition.d.ts +7 -0
  120. package/src/components/$traits/has-position/HasPosition.js +45 -0
  121. package/src/components/$traits/has-resizable/HasResizable.d.ts +13 -0
  122. package/src/components/$traits/has-resizable/HasResizable.js +122 -0
  123. package/src/components/$traits/has-resizable/has-resizable.css +121 -0
  124. package/src/components/$traits/has-validation/HasValidation.d.ts +17 -0
  125. package/src/components/$traits/has-validation/HasValidation.js +133 -0
  126. package/src/components/BaseComponent.d.ts +32 -0
  127. package/src/components/BaseComponent.js +247 -0
  128. package/src/components/accordion/Accordion.js +268 -0
  129. package/src/components/accordion/AccordionItem.js +233 -0
  130. package/src/components/accordion/index.js +7 -0
  131. package/src/components/accordion/types/Accordion.d.ts +47 -0
  132. package/src/components/accordion/types/AccordionItem.d.ts +48 -0
  133. package/src/components/alert/Alert.js +350 -0
  134. package/src/components/alert/index.js +6 -0
  135. package/src/components/alert/types/Alert.d.ts +62 -0
  136. package/src/components/avatar/Avatar.js +430 -0
  137. package/src/components/avatar/AvatarGroup.js +97 -0
  138. package/src/components/avatar/index.js +7 -0
  139. package/src/components/avatar/types/Avatar.d.ts +74 -0
  140. package/src/components/avatar/types/AvatarGroup.d.ts +32 -0
  141. package/src/components/badge/Badge.js +245 -0
  142. package/src/components/badge/index.js +6 -0
  143. package/src/components/badge/types/Badge.d.ts +51 -0
  144. package/src/components/base-component.css +0 -0
  145. package/src/components/breadcrumb/BreadCrumb.js +138 -0
  146. package/src/components/breadcrumb/index.js +5 -0
  147. package/src/components/breadcrumb/types/BreadCrumb.d.ts +42 -0
  148. package/src/components/button/Button.js +320 -0
  149. package/src/components/button/index.js +5 -0
  150. package/src/components/button/types/Button.d.ts +62 -0
  151. package/src/components/card/Card.js +282 -0
  152. package/src/components/card/index.js +5 -0
  153. package/src/components/card/types/Card.d.ts +42 -0
  154. package/src/components/context-menu/ContextMenu.js +127 -0
  155. package/src/components/context-menu/ContextMenuGroup.js +29 -0
  156. package/src/components/context-menu/ContextMenuItem.js +28 -0
  157. package/src/components/context-menu/index.js +10 -0
  158. package/src/components/context-menu/types/ContextMenu.d.ts +30 -0
  159. package/src/components/context-menu/types/ContextMenuGroup.d.ts +18 -0
  160. package/src/components/context-menu/types/ContextMenuItem.d.ts +18 -0
  161. package/src/components/divider/Divider.js +256 -0
  162. package/src/components/divider/index.js +6 -0
  163. package/src/components/divider/types/Divider.d.ts +55 -0
  164. package/src/components/dropdown/Dropdown.js +531 -0
  165. package/src/components/dropdown/DropdownDivider.js +45 -0
  166. package/src/components/dropdown/DropdownGroup.js +83 -0
  167. package/src/components/dropdown/DropdownItem.js +150 -0
  168. package/src/components/dropdown/DropdownTrigger.js +93 -0
  169. package/src/components/dropdown/helpers.js +53 -0
  170. package/src/components/dropdown/index.js +13 -0
  171. package/src/components/dropdown/types/Dropdown.d.ts +88 -0
  172. package/src/components/dropdown/types/DropdownDivider.d.ts +20 -0
  173. package/src/components/dropdown/types/DropdownGroup.d.ts +25 -0
  174. package/src/components/dropdown/types/DropdownItem.d.ts +41 -0
  175. package/src/components/dropdown/types/DropdownTrigger.d.ts +32 -0
  176. package/src/components/form/FormControl.js +498 -0
  177. package/src/components/form/field/Field.js +419 -0
  178. package/src/components/form/field/FieldCollection.js +292 -0
  179. package/src/components/form/field/types/AutocompleteField.js +168 -0
  180. package/src/components/form/field/types/CheckboxField.js +77 -0
  181. package/src/components/form/field/types/CheckboxGroupField.js +171 -0
  182. package/src/components/form/field/types/ColorField.js +102 -0
  183. package/src/components/form/field/types/DateField.js +315 -0
  184. package/src/components/form/field/types/EmailField.js +104 -0
  185. package/src/components/form/field/types/FileField.js +276 -0
  186. package/src/components/form/field/types/HiddenField.js +44 -0
  187. package/src/components/form/field/types/ImageField.js +138 -0
  188. package/src/components/form/field/types/NumberField.js +177 -0
  189. package/src/components/form/field/types/PasswordField.js +200 -0
  190. package/src/components/form/field/types/RadioField.js +145 -0
  191. package/src/components/form/field/types/RangeField.js +117 -0
  192. package/src/components/form/field/types/SearchField.js +66 -0
  193. package/src/components/form/field/types/SelectField.js +247 -0
  194. package/src/components/form/field/types/StringField.js +148 -0
  195. package/src/components/form/field/types/TelField.js +98 -0
  196. package/src/components/form/field/types/TextAreaField.js +142 -0
  197. package/src/components/form/field/types/TimeField.js +215 -0
  198. package/src/components/form/field/types/UrlField.js +115 -0
  199. package/src/components/form/field/types/file-field-mode/FileAvatarMode.js +183 -0
  200. package/src/components/form/field/types/file-field-mode/FileDropzoneMode.js +117 -0
  201. package/src/components/form/field/types/file-field-mode/FileItemPreview.js +150 -0
  202. package/src/components/form/field/types/file-field-mode/FileNativeMode.js +43 -0
  203. package/src/components/form/field/types/file-field-mode/FileUploadButtonMode.js +120 -0
  204. package/src/components/form/field/types/file-field-mode/FileWallMode.js +106 -0
  205. package/src/components/form/index.js +61 -0
  206. package/src/components/form/merge +0 -0
  207. package/src/components/form/types/Field.d.ts +73 -0
  208. package/src/components/form/types/FieldCollection.d.ts +53 -0
  209. package/src/components/form/types/FormControl.d.ts +64 -0
  210. package/src/components/form/types/fields/AutocompleteField.d.ts +48 -0
  211. package/src/components/form/types/fields/CheckboxField.d.ts +33 -0
  212. package/src/components/form/types/fields/CheckboxGroupField.d.ts +49 -0
  213. package/src/components/form/types/fields/ColorField.d.ts +37 -0
  214. package/src/components/form/types/fields/DateField.d.ts +70 -0
  215. package/src/components/form/types/fields/EmailField.d.ts +35 -0
  216. package/src/components/form/types/fields/FileAvatarMode.d.ts +46 -0
  217. package/src/components/form/types/fields/FileDropzoneMode.d.ts +28 -0
  218. package/src/components/form/types/fields/FileField.d.ts +56 -0
  219. package/src/components/form/types/fields/FileItemPreview.d.ts +35 -0
  220. package/src/components/form/types/fields/FileNativeMode.d.ts +21 -0
  221. package/src/components/form/types/fields/FileUploadButtonMode.d.ts +34 -0
  222. package/src/components/form/types/fields/FileWallMode.d.ts +32 -0
  223. package/src/components/form/types/fields/HiddenField.d.ts +26 -0
  224. package/src/components/form/types/fields/ImageField.d.ts +45 -0
  225. package/src/components/form/types/fields/NumberField.d.ts +48 -0
  226. package/src/components/form/types/fields/PasswordField.d.ts +46 -0
  227. package/src/components/form/types/fields/RadioField.d.ts +48 -0
  228. package/src/components/form/types/fields/RangeField.d.ts +44 -0
  229. package/src/components/form/types/fields/SearchField.d.ts +34 -0
  230. package/src/components/form/types/fields/SelectField.d.ts +71 -0
  231. package/src/components/form/types/fields/StringField.d.ts +48 -0
  232. package/src/components/form/types/fields/TelField.d.ts +37 -0
  233. package/src/components/form/types/fields/TextAreaField.d.ts +44 -0
  234. package/src/components/form/types/fields/TimeField.d.ts +51 -0
  235. package/src/components/form/types/fields/UrlField.d.ts +35 -0
  236. package/src/components/form/utils.js +17 -0
  237. package/src/components/form/validation/Validation.js +565 -0
  238. package/src/components/index.d.ts +160 -0
  239. package/src/components/list/HasListItem.js +171 -0
  240. package/src/components/list/List.js +125 -0
  241. package/src/components/list/ListDivider.js +39 -0
  242. package/src/components/list/ListGroup.js +135 -0
  243. package/src/components/list/ListItem.js +212 -0
  244. package/src/components/list/index.js +12 -0
  245. package/src/components/list/types/List.d.ts +43 -0
  246. package/src/components/list/types/ListGroup.d.ts +37 -0
  247. package/src/components/list/types/ListItem.d.ts +53 -0
  248. package/src/components/menu/HasMenuItem.js +182 -0
  249. package/src/components/menu/Menu.js +227 -0
  250. package/src/components/menu/MenuDivider.js +37 -0
  251. package/src/components/menu/MenuGroup.js +126 -0
  252. package/src/components/menu/MenuItem.js +190 -0
  253. package/src/components/menu/MenuLink.js +51 -0
  254. package/src/components/menu/index.js +14 -0
  255. package/src/components/menu/types/Menu.d.ts +60 -0
  256. package/src/components/menu/types/MenuDivider.d.ts +19 -0
  257. package/src/components/menu/types/MenuGroup.d.ts +44 -0
  258. package/src/components/menu/types/MenuItem.d.ts +46 -0
  259. package/src/components/menu/types/MenuLink.d.ts +16 -0
  260. package/src/components/modal/Modal.js +524 -0
  261. package/src/components/modal/index.js +5 -0
  262. package/src/components/modal/types/Modal.d.ts +94 -0
  263. package/src/components/pagination/Pagination.js +411 -0
  264. package/src/components/pagination/index.js +5 -0
  265. package/src/components/pagination/types/Pagination.d.ts +68 -0
  266. package/src/components/popover/Popover.js +459 -0
  267. package/src/components/popover/PopoverFooter.js +61 -0
  268. package/src/components/popover/PopoverHeader.js +68 -0
  269. package/src/components/popover/index.js +10 -0
  270. package/src/components/popover/types/Popover.d.ts +83 -0
  271. package/src/components/popover/types/PopoverFooter.d.ts +24 -0
  272. package/src/components/popover/types/PopoverHeader.d.ts +26 -0
  273. package/src/components/progress/Progress.js +401 -0
  274. package/src/components/progress/index.js +6 -0
  275. package/src/components/progress/types/Progress.d.ts +77 -0
  276. package/src/components/skeleton/Skeleton.js +228 -0
  277. package/src/components/skeleton/index.js +6 -0
  278. package/src/components/skeleton/types/Skeleton.d.ts +55 -0
  279. package/src/components/slider/Slider.js +406 -0
  280. package/src/components/slider/index.js +5 -0
  281. package/src/components/slider/types/Slider.d.ts +82 -0
  282. package/src/components/spacer/Spacer.js +27 -0
  283. package/src/components/spacer/index.js +5 -0
  284. package/src/components/spacer/types/Spacer.d.ts +19 -0
  285. package/src/components/spinner/Spinner.js +350 -0
  286. package/src/components/spinner/index.js +5 -0
  287. package/src/components/spinner/types/Spinner.d.ts +71 -0
  288. package/src/components/splitter/Splitter.js +164 -0
  289. package/src/components/splitter/SplitterGutter.js +140 -0
  290. package/src/components/splitter/SplitterPanel.js +143 -0
  291. package/src/components/splitter/index.js +10 -0
  292. package/src/components/splitter/types/Splitter.d.ts +38 -0
  293. package/src/components/splitter/types/SplitterGutter.d.ts +38 -0
  294. package/src/components/splitter/types/SplitterPanel.d.ts +41 -0
  295. package/src/components/stacks/AbsoluteStack.js +53 -0
  296. package/src/components/stacks/FixedStack.js +53 -0
  297. package/src/components/stacks/HStack.js +54 -0
  298. package/src/components/stacks/PositionStack.js +254 -0
  299. package/src/components/stacks/RelativeStack.js +53 -0
  300. package/src/components/stacks/Stack.js +166 -0
  301. package/src/components/stacks/VStack.js +55 -0
  302. package/src/components/stacks/index.js +21 -0
  303. package/src/components/stacks/types/AbsoluteStack.d.ts +16 -0
  304. package/src/components/stacks/types/FixedStack.d.ts +16 -0
  305. package/src/components/stacks/types/HStack.d.ts +16 -0
  306. package/src/components/stacks/types/PositionStack.d.ts +54 -0
  307. package/src/components/stacks/types/RelativeStack.d.ts +17 -0
  308. package/src/components/stacks/types/Stack.d.ts +39 -0
  309. package/src/components/stacks/types/VStack.d.ts +16 -0
  310. package/src/components/stepper/Stepper.js +461 -0
  311. package/src/components/stepper/StepperStep.js +241 -0
  312. package/src/components/stepper/index.js +8 -0
  313. package/src/components/stepper/types/Stepper.d.ts +68 -0
  314. package/src/components/stepper/types/StepperStep.d.ts +54 -0
  315. package/src/components/switch/Switch.js +266 -0
  316. package/src/components/switch/index.js +6 -0
  317. package/src/components/switch/types/Switch.d.ts +55 -0
  318. package/src/components/table/Column.js +212 -0
  319. package/src/components/table/ColumnGroup.js +90 -0
  320. package/src/components/table/DataTable.js +720 -0
  321. package/src/components/table/SimpleTable.js +139 -0
  322. package/src/components/table/index.js +7 -0
  323. package/src/components/table/types/Column.d.ts +49 -0
  324. package/src/components/table/types/ColumnGroup.d.ts +28 -0
  325. package/src/components/table/types/DataTable.d.ts +97 -0
  326. package/src/components/table/types/SimpleTable.d.ts +40 -0
  327. package/src/components/tabs/Tabs.js +395 -0
  328. package/src/components/tabs/index.js +6 -0
  329. package/src/components/tabs/types/Tabs.d.ts +78 -0
  330. package/src/components/toast/Toast.js +262 -0
  331. package/src/components/toast/ToastError.js +0 -0
  332. package/src/components/toast/ToastInfo.js +0 -0
  333. package/src/components/toast/ToastSuccess.js +0 -0
  334. package/src/components/toast/ToastWarning.js +0 -0
  335. package/src/components/toast/index.js +5 -0
  336. package/src/components/toast/types/Toast.d.ts +57 -0
  337. package/src/components/toast/types/ToastError.d.ts +7 -0
  338. package/src/components/toast/types/ToastInfo.d.ts +7 -0
  339. package/src/components/toast/types/ToastSuccess.d.ts +7 -0
  340. package/src/components/toast/types/ToastWarning.d.ts +7 -0
  341. package/src/components/tooltip/Tooltip.js +359 -0
  342. package/src/components/tooltip/index.js +5 -0
  343. package/src/components/tooltip/prototypes.js +6 -0
  344. package/src/components/tooltip/types/Tooltip.d.ts +65 -0
  345. package/src/{data → core/data}/MemoryManager.js +2 -3
  346. package/src/core/data/Observable.js +227 -0
  347. package/src/core/data/ObservableArray.js +522 -0
  348. package/src/core/data/ObservableChecker.js +39 -0
  349. package/src/core/data/ObservableItem.js +611 -0
  350. package/src/core/data/ObservableObject.js +274 -0
  351. package/src/core/data/ObservableResource.js +315 -0
  352. package/src/core/data/ObservableWhen.js +54 -0
  353. package/src/core/data/Store.js +520 -0
  354. package/src/core/data/observable-helpers/observable.is-to.js +390 -0
  355. package/src/core/data/observable-helpers/observable.prototypes.js +145 -0
  356. package/src/core/elements/anchor/anchor-with-sentinel.js +66 -0
  357. package/src/core/elements/anchor/anchor.js +210 -0
  358. package/src/core/elements/anchor/one-child-anchor-overwriting.js +66 -0
  359. package/src/core/elements/content-formatter.js +169 -0
  360. package/src/core/elements/control/for-each-array.js +292 -0
  361. package/src/{elements → core/elements}/control/for-each.js +42 -23
  362. package/src/core/elements/control/show-if.js +94 -0
  363. package/src/core/elements/control/show-when.js +54 -0
  364. package/src/core/elements/control/switch.js +141 -0
  365. package/src/core/elements/description-list.js +19 -0
  366. package/src/core/elements/form.js +255 -0
  367. package/src/core/elements/fragment.js +8 -0
  368. package/src/core/elements/html5-semantics.js +55 -0
  369. package/src/core/elements/img.js +59 -0
  370. package/src/{elements → core/elements}/index.js +4 -4
  371. package/src/core/elements/interactive.js +25 -0
  372. package/src/core/elements/list.js +37 -0
  373. package/src/core/elements/medias.js +37 -0
  374. package/src/core/elements/meta-data.js +43 -0
  375. package/src/core/elements/svg.js +61 -0
  376. package/src/core/elements/table.js +73 -0
  377. package/src/{errors → core/errors}/ArgTypesError.js +1 -1
  378. package/src/{errors → core/errors}/NativeDocumentError.js +0 -0
  379. package/src/core/utils/HasEventEmitter.js +85 -0
  380. package/src/core/utils/args-types.js +140 -0
  381. package/src/core/utils/cache.js +5 -0
  382. package/src/core/utils/callback-handler.js +50 -0
  383. package/src/core/utils/debug-manager.js +40 -0
  384. package/src/core/utils/events.js +148 -0
  385. package/src/core/utils/filters/date.js +178 -0
  386. package/src/core/utils/filters/index.js +4 -0
  387. package/src/core/utils/filters/standard.js +263 -0
  388. package/src/core/utils/filters/strings.js +67 -0
  389. package/src/core/utils/filters/utils.js +77 -0
  390. package/src/core/utils/formatters.js +90 -0
  391. package/src/core/utils/helpers.js +144 -0
  392. package/src/core/utils/localstorage.js +57 -0
  393. package/src/core/utils/memoize.js +115 -0
  394. package/src/core/utils/plugins-manager.js +81 -0
  395. package/src/core/utils/property-accumulator.js +72 -0
  396. package/src/core/utils/prototypes.js +44 -0
  397. package/src/core/utils/shortcut-manager.js +242 -0
  398. package/src/{utils → core/utils}/validator.js +58 -22
  399. package/src/core/wrappers/AttributesWrapper.js +98 -0
  400. package/src/core/wrappers/DocumentObserver.js +182 -0
  401. package/src/core/wrappers/ElementCreator.js +120 -0
  402. package/src/core/wrappers/HtmlElementWrapper.js +98 -0
  403. package/src/core/wrappers/NDElement.js +613 -0
  404. package/src/core/wrappers/NdPrototype.js +233 -0
  405. package/src/core/wrappers/SingletonView.js +99 -0
  406. package/src/core/wrappers/SvgElementWrapper.js +15 -0
  407. package/src/core/wrappers/TemplateBinding.js +7 -0
  408. package/src/core/wrappers/constants.js +66 -0
  409. package/src/core/wrappers/prototypes/attributes-extensions.js +179 -0
  410. package/src/core/wrappers/prototypes/bind-class-extensions.js +0 -0
  411. package/src/core/wrappers/prototypes/nd-element-extensions.js +157 -0
  412. package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +127 -0
  413. package/src/core/wrappers/template-cloner/NodeCloner.js +209 -0
  414. package/src/core/wrappers/template-cloner/TemplateCloner.js +192 -0
  415. package/src/core/wrappers/template-cloner/attributes-hydrator.js +142 -0
  416. package/src/core/wrappers/template-cloner/utils.js +173 -0
  417. package/src/fetch/NativeFetch.js +89 -0
  418. package/src/i18n/bin/scan.js +132 -0
  419. package/src/i18n/index.d.ts +2 -0
  420. package/src/i18n/service/I18nService.d.ts +27 -0
  421. package/src/i18n/service/I18nService.js +46 -0
  422. package/src/i18n/service/functions.d.ts +22 -0
  423. package/src/i18n/service/functions.js +29 -0
  424. package/src/router/Route.js +33 -8
  425. package/src/router/RouteGroupHelper.js +10 -2
  426. package/src/router/Router.js +63 -22
  427. package/src/router/RouterComponent.js +114 -6
  428. package/src/{errors → router/errors}/RouterError.js +0 -1
  429. package/src/router/link.js +9 -10
  430. package/src/router/modes/HashRouter.js +2 -2
  431. package/src/router/modes/HistoryRouter.js +2 -3
  432. package/src/router/modes/MemoryRouter.js +1 -1
  433. package/src/ui/components/accordion/AccordionItemRender.js +63 -0
  434. package/src/ui/components/accordion/AccordionRender.js +35 -0
  435. package/src/ui/components/accordion/accordion.css +121 -0
  436. package/src/ui/components/alert/AlertRender.js +81 -0
  437. package/src/ui/components/alert/alert.css +163 -0
  438. package/src/ui/components/avatar/avata-group/AvatarGroupRender.js +50 -0
  439. package/src/ui/components/avatar/avata-group/avatar-group.css +38 -0
  440. package/src/ui/components/avatar/avatar/AvatarRender.js +87 -0
  441. package/src/ui/components/avatar/avatar/avatar.css +189 -0
  442. package/src/ui/components/badge/BadgeRender.js +25 -0
  443. package/src/ui/components/badge/badge.css +168 -0
  444. package/src/ui/components/breadcrumb/BreadcrumbRender.js +44 -0
  445. package/src/ui/components/breadcrumb/breadcrumb.css +55 -0
  446. package/src/ui/components/button/ButtonRender.js +65 -0
  447. package/src/ui/components/button/button.css +296 -0
  448. package/src/ui/components/card/CardRender.js +133 -0
  449. package/src/ui/components/card/card.css +169 -0
  450. package/src/ui/components/contextmenu/ContextmenuRender.js +68 -0
  451. package/src/ui/components/contextmenu/contextmenu.css +36 -0
  452. package/src/ui/components/divider/DividerRender.js +70 -0
  453. package/src/ui/components/divider/divider.css +70 -0
  454. package/src/ui/components/dropdown/DropdownRender.js +92 -0
  455. package/src/ui/components/dropdown/divider/DropdownDividerRender.js +9 -0
  456. package/src/ui/components/dropdown/divider/dropdown-divider.css +0 -0
  457. package/src/ui/components/dropdown/dropdown.css +179 -0
  458. package/src/ui/components/dropdown/group/DropdownGroupRender.js +23 -0
  459. package/src/ui/components/dropdown/group/dropdown-group.css +0 -0
  460. package/src/ui/components/dropdown/item/DropdownItemRender.js +29 -0
  461. package/src/ui/components/dropdown/item/dropdown-item.css +0 -0
  462. package/src/ui/components/form/FieldCollectionRender.js +110 -0
  463. package/src/ui/components/form/FormControlRender.js +85 -0
  464. package/src/ui/components/form/field-collection.css +55 -0
  465. package/src/ui/components/form/fields/AutocompleteFieldRender.js +143 -0
  466. package/src/ui/components/form/fields/CheckboxFieldRender.js +59 -0
  467. package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +92 -0
  468. package/src/ui/components/form/fields/ColorFieldRender.js +30 -0
  469. package/src/ui/components/form/fields/DateFieldRender.js +155 -0
  470. package/src/ui/components/form/fields/EmailFieldRender.js +5 -0
  471. package/src/ui/components/form/fields/FieldRender.js +118 -0
  472. package/src/ui/components/form/fields/FileFieldRender.js +41 -0
  473. package/src/ui/components/form/fields/HiddenFieldRender.js +13 -0
  474. package/src/ui/components/form/fields/ImageFieldRender.js +0 -0
  475. package/src/ui/components/form/fields/NumberFieldRender.js +52 -0
  476. package/src/ui/components/form/fields/PasswordFieldRender.js +65 -0
  477. package/src/ui/components/form/fields/RadioFieldRender.js +77 -0
  478. package/src/ui/components/form/fields/RangeFieldRender.js +122 -0
  479. package/src/ui/components/form/fields/SelectFieldRender.js +248 -0
  480. package/src/ui/components/form/fields/SliderFieldRender.js +359 -0
  481. package/src/ui/components/form/fields/StringFieldRender.js +6 -0
  482. package/src/ui/components/form/fields/TelFieldRender.js +6 -0
  483. package/src/ui/components/form/fields/TextAreaFieldRender.js +96 -0
  484. package/src/ui/components/form/fields/TimeFieldRender.js +142 -0
  485. package/src/ui/components/form/fields/UrlFieldRender.js +6 -0
  486. package/src/ui/components/form/fields/date-field.css +32 -0
  487. package/src/ui/components/form/fields/field.css +402 -0
  488. package/src/ui/components/form/fields/file-field.css +79 -0
  489. package/src/ui/components/form/fields/password-field.css +50 -0
  490. package/src/ui/components/form/fields/range-field.css +120 -0
  491. package/src/ui/components/form/fields/slider.css +195 -0
  492. package/src/ui/components/form/file-upload-mode/FileAvatarModeRender.js +143 -0
  493. package/src/ui/components/form/file-upload-mode/FileDropzoneModeRender.js +108 -0
  494. package/src/ui/components/form/file-upload-mode/FileNativeModeRender.js +22 -0
  495. package/src/ui/components/form/file-upload-mode/FileUploadButtonModeRender.js +89 -0
  496. package/src/ui/components/form/file-upload-mode/FileWallModeRender.js +90 -0
  497. package/src/ui/components/form/file-upload-mode/file-avatar-mode.css +139 -0
  498. package/src/ui/components/form/file-upload-mode/file-dropzone-mode.css +88 -0
  499. package/src/ui/components/form/file-upload-mode/file-upload-button-mode.css +44 -0
  500. package/src/ui/components/form/file-upload-mode/file-wall-mode.css +88 -0
  501. package/src/ui/components/form/form-control.css +40 -0
  502. package/src/ui/components/form/helpers.js +111 -0
  503. package/src/ui/components/form/index.js +27 -0
  504. package/src/ui/components/list/ListRender.js +18 -0
  505. package/src/ui/components/list/divider/ListDividerRender.js +10 -0
  506. package/src/ui/components/list/divider/list-divider.css +12 -0
  507. package/src/ui/components/list/group/ListGroupRender.js +61 -0
  508. package/src/ui/components/list/group/list-group.css +62 -0
  509. package/src/ui/components/list/item/ListItemRender.js +238 -0
  510. package/src/ui/components/list/item/list-item.css +191 -0
  511. package/src/ui/components/list/list.css +24 -0
  512. package/src/ui/components/menu/MenuDividerRender.js +12 -0
  513. package/src/ui/components/menu/MenuGroupRender.js +59 -0
  514. package/src/ui/components/menu/MenuItemRender.js +57 -0
  515. package/src/ui/components/menu/MenuLinkRender.js +55 -0
  516. package/src/ui/components/menu/MenuRender.js +22 -0
  517. package/src/ui/components/menu/helpers.js +121 -0
  518. package/src/ui/components/menu/menu.css +308 -0
  519. package/src/ui/components/modal/ModalRender.js +118 -0
  520. package/src/ui/components/modal/modal.css +156 -0
  521. package/src/ui/components/pagination/PaginationRender.js +112 -0
  522. package/src/ui/components/pagination/pagination.css +63 -0
  523. package/src/ui/components/popover/PopoverRender.js +233 -0
  524. package/src/ui/components/popover/popover.css +139 -0
  525. package/src/ui/components/progress/ProgressRender.js +168 -0
  526. package/src/ui/components/progress/progress.css +197 -0
  527. package/src/ui/components/skeleton/SkeletonRender.js +136 -0
  528. package/src/ui/components/skeleton/skeleton.css +154 -0
  529. package/src/ui/components/spacer/SpacerRender.js +10 -0
  530. package/src/ui/components/spinner/SpinnerRender.js +47 -0
  531. package/src/ui/components/spinner/spinner.css +152 -0
  532. package/src/ui/components/splitter/SplitterGutterRender.js +94 -0
  533. package/src/ui/components/splitter/SplitterPanelRender.js +38 -0
  534. package/src/ui/components/splitter/SplitterRender.js +75 -0
  535. package/src/ui/components/splitter/splitter.css +128 -0
  536. package/src/ui/components/stacks/PositionStackRender.js +39 -0
  537. package/src/ui/components/stacks/StackRender.js +41 -0
  538. package/src/ui/components/stacks/absolute-stack/AbsoluteStackRender.js +5 -0
  539. package/src/ui/components/stacks/fixed-stack/FixedStackRender.js +5 -0
  540. package/src/ui/components/stacks/h-stack/HStackRender.js +7 -0
  541. package/src/ui/components/stacks/h-stack/h-stack.css +4 -0
  542. package/src/ui/components/stacks/index.js +5 -0
  543. package/src/ui/components/stacks/position-stack.css +62 -0
  544. package/src/ui/components/stacks/relative-stack/RelativeStackRender.js +7 -0
  545. package/src/ui/components/stacks/relative-stack/relative-stack.css +3 -0
  546. package/src/ui/components/stacks/stack.css +78 -0
  547. package/src/ui/components/stacks/v-stack/VStackRender.js +6 -0
  548. package/src/ui/components/stacks/v-stack/v-stack.css +4 -0
  549. package/src/ui/components/stepper/StepperRender.js +71 -0
  550. package/src/ui/components/stepper/StepperStepRender.js +67 -0
  551. package/src/ui/components/stepper/stepper.css +359 -0
  552. package/src/ui/components/switch/SwitchRender.js +83 -0
  553. package/src/ui/components/switch/switch.css +143 -0
  554. package/src/ui/components/table/data-table/DataTableRender.js +50 -0
  555. package/src/ui/components/table/data-table/bulk-actions.js +34 -0
  556. package/src/ui/components/table/data-table/data-table.css +246 -0
  557. package/src/ui/components/table/data-table/pagination.js +56 -0
  558. package/src/ui/components/table/data-table/tables.js +368 -0
  559. package/src/ui/components/table/data-table/toolbar.js +67 -0
  560. package/src/ui/components/table/simple-table/SimpleTableRender.js +203 -0
  561. package/src/ui/components/table/simple-table/simple-table.css +50 -0
  562. package/src/ui/components/tabs/TabsRender.js +226 -0
  563. package/src/ui/components/tabs/tabs.css +253 -0
  564. package/src/ui/components/toast/ToastRender.js +99 -0
  565. package/src/ui/components/toast/toast.css +201 -0
  566. package/src/ui/components/tooltip/TooltipRender.js +8 -0
  567. package/src/ui/components/tooltip/tooltip.css +113 -0
  568. package/src/ui/index.js +47 -0
  569. package/src/ui/theme.js +0 -0
  570. package/src/ui/theme.scss +1 -0
  571. package/src/ui/tokens/animation.scss +36 -0
  572. package/src/ui/tokens/colors-dark.scss +58 -0
  573. package/src/ui/tokens/colors.scss +54 -0
  574. package/src/ui/tokens/components.scss +32 -0
  575. package/src/ui/tokens/fonts.scss +57 -0
  576. package/src/ui/tokens/glass.scss +10 -0
  577. package/src/ui/tokens/index.scss +38 -0
  578. package/src/ui/tokens/layouts.scss +228 -0
  579. package/src/ui/tokens/opacity.scss +21 -0
  580. package/src/ui/tokens/others.scss +11 -0
  581. package/src/ui/tokens/radius.scss +6 -0
  582. package/src/ui/tokens/reset.scss +51 -0
  583. package/src/ui/tokens/shadows.scss +29 -0
  584. package/src/ui/tokens/spacings.scss +13 -0
  585. package/src/ui/tokens/vars.scss +35 -0
  586. package/src/ui/tokens/viewports.scss +30 -0
  587. package/types/args-types.d.ts +58 -0
  588. package/types/control-flow.d.ts +62 -0
  589. package/types/elements.d.ts +231 -0
  590. package/types/filters/dates.d.ts +43 -0
  591. package/types/filters/index.d.ts +4 -0
  592. package/types/filters/standard.d.ts +70 -0
  593. package/types/filters/strings.d.ts +21 -0
  594. package/types/filters/types.d.ts +20 -0
  595. package/types/forms.d.ts +84 -0
  596. package/types/globals.d.ts +543 -0
  597. package/types/images.d.ts +23 -0
  598. package/types/localStorage.ts +102 -0
  599. package/types/memoize.d.ts +26 -0
  600. package/types/native-fetch.d.ts +72 -0
  601. package/types/nd-element.d.ts +407 -0
  602. package/types/observable-resource.d.ts +3 -0
  603. package/types/observable.d.ts +227 -0
  604. package/types/plugins-manager.d.ts +65 -0
  605. package/types/polyfill.d.ts +18 -0
  606. package/types/property-accumulator.d.ts +33 -0
  607. package/types/router.d.ts +85 -0
  608. package/types/service.d.ts +23 -0
  609. package/types/singleton.d.ts +19 -0
  610. package/types/store.d.ts +63 -0
  611. package/types/template-cloner.ts +43 -0
  612. package/types/validator.ts +66 -0
  613. package/ui.js +1 -0
  614. package/utils.d.ts +4 -0
  615. package/utils.js +12 -0
  616. package/src/data/Observable.js +0 -55
  617. package/src/data/ObservableChecker.js +0 -39
  618. package/src/data/ObservableItem.js +0 -195
  619. package/src/data/Store.js +0 -74
  620. package/src/data/observable-helpers/array.js +0 -74
  621. package/src/data/observable-helpers/batch.js +0 -22
  622. package/src/data/observable-helpers/computed.js +0 -28
  623. package/src/data/observable-helpers/object.js +0 -111
  624. package/src/elements/anchor.js +0 -129
  625. package/src/elements/content-formatter.js +0 -32
  626. package/src/elements/control/for-each-array.js +0 -280
  627. package/src/elements/control/show-if.js +0 -79
  628. package/src/elements/control/switch.js +0 -98
  629. package/src/elements/description-list.js +0 -5
  630. package/src/elements/form.js +0 -71
  631. package/src/elements/html5-semantics.js +0 -12
  632. package/src/elements/img.js +0 -45
  633. package/src/elements/interactive.js +0 -7
  634. package/src/elements/list.js +0 -10
  635. package/src/elements/medias.js +0 -8
  636. package/src/elements/meta-data.js +0 -9
  637. package/src/elements/table.js +0 -14
  638. package/src/utils/args-types.js +0 -100
  639. package/src/utils/debug-manager.js +0 -31
  640. package/src/utils/helpers.js +0 -60
  641. package/src/utils/plugins-manager.js +0 -12
  642. package/src/utils/prototypes.js +0 -45
  643. package/src/wrappers/AttributesWrapper.js +0 -144
  644. package/src/wrappers/DocumentObserver.js +0 -80
  645. package/src/wrappers/ElementCreator.js +0 -114
  646. package/src/wrappers/HtmlElementEventsWrapper.js +0 -64
  647. package/src/wrappers/HtmlElementWrapper.js +0 -50
  648. package/src/wrappers/NdPrototype.js +0 -109
  649. package/src/wrappers/constants.js +0 -2
@@ -0,0 +1,157 @@
1
+ import ObservableItem from '../../data/ObservableItem';
2
+ import { NDElement } from '../NDElement';
3
+ import TemplateBinding from '../TemplateBinding';
4
+ import { ElementCreator } from '../ElementCreator';
5
+ import PluginsManager from '../../utils/plugins-manager';
6
+ import ObservableChecker from '../../data/ObservableChecker';
7
+
8
+ /**
9
+ * Extends a prototype with a non-enumerable, configurable, writable property.
10
+ *
11
+ * @param {Function} Constructor - The constructor whose prototype to extend
12
+ * @param {string} name - Property name
13
+ * @param {Function} fn - Implementation
14
+ */
15
+ function extendsPrototype(Constructor, name, fn) {
16
+ Object.defineProperty(Constructor.prototype, name, {
17
+ value: fn,
18
+ enumerable: false,
19
+ configurable: true,
20
+ writable: true,
21
+ });
22
+ }
23
+
24
+ // -- Static assignment (not a prototype method) -------------------------------
25
+
26
+ NDElement.$getChild = ElementCreator.getChild;
27
+
28
+ // -- toNdElement --------------------------------------------------------------
29
+
30
+ /**
31
+ * Converts a string to a static text node.
32
+ * @returns {Text}
33
+ */
34
+ extendsPrototype(Object, 'toNdElement', function() {
35
+ return ElementCreator.createStaticTextNode(null, JSON.stringify(this));
36
+ });
37
+
38
+ /**
39
+ * Converts a string to a static text node.
40
+ * @returns {Text}
41
+ */
42
+ extendsPrototype(String, 'toNdElement', function() {
43
+ return ElementCreator.createStaticTextNode(null, this);
44
+ });
45
+
46
+ /**
47
+ * Converts a number to a static text node.
48
+ * @returns {Text}
49
+ */
50
+ extendsPrototype(Number, 'toNdElement', function() {
51
+ return ElementCreator.createStaticTextNode(null, this.toString());
52
+ });
53
+
54
+ /**
55
+ * Returns the element itself (identity for DOM compatibility).
56
+ * @returns {Element}
57
+ */
58
+ extendsPrototype(Element, 'toNdElement', function() {
59
+ return this;
60
+ });
61
+
62
+ /**
63
+ * Returns the text node itself (identity for DOM compatibility).
64
+ * @returns {Text}
65
+ */
66
+ extendsPrototype(Text, 'toNdElement', function() {
67
+ return this;
68
+ });
69
+
70
+ /**
71
+ * Returns the comment node itself (identity for DOM compatibility).
72
+ * @returns {Comment}
73
+ */
74
+ extendsPrototype(Comment, 'toNdElement', function() {
75
+ return this;
76
+ });
77
+
78
+ /**
79
+ * Returns the document itself (identity for DOM compatibility).
80
+ * @returns {Document}
81
+ */
82
+ extendsPrototype(Document, 'toNdElement', function() {
83
+ return this;
84
+ });
85
+
86
+ /**
87
+ * Returns the document fragment itself (identity for DOM compatibility).
88
+ * @returns {DocumentFragment}
89
+ */
90
+ extendsPrototype(DocumentFragment, 'toNdElement', function() {
91
+ return this;
92
+ });
93
+
94
+ /**
95
+ * Converts the ObservableItem to a reactive text node that updates automatically when the value changes.
96
+ * @returns {Text}
97
+ */
98
+ extendsPrototype(ObservableItem, 'toNdElement', function() {
99
+ return ElementCreator.createObservableNode(null, this);
100
+ });
101
+
102
+ /**
103
+ * ObservableChecker shares the same reactive text node behaviour as ObservableItem.
104
+ * @returns {Text}
105
+ */
106
+ extendsPrototype(ObservableChecker, 'toNdElement', ObservableItem.prototype.toNdElement);
107
+
108
+ /**
109
+ * Converts the NDElement to its underlying HTMLElement (or ghost DOM fragment if ghostDom was used).
110
+ * @returns {HTMLElement|DocumentFragment}
111
+ */
112
+ extendsPrototype(NDElement, 'toNdElement', function() {
113
+ const element = this.$element ?? this.$build?.() ?? this.build?.() ?? null;
114
+ if (this.$attachements) {
115
+ if (!this.$attachements.contains(this.$element)) {
116
+ this.$attachements.append(this.$element);
117
+ }
118
+ return this.$attachements;
119
+ }
120
+ return element;
121
+ });
122
+
123
+ /**
124
+ * Converts the array to a DocumentFragment containing all child elements.
125
+ * Each item is processed through ElementCreator.getChild().
126
+ * @returns {DocumentFragment}
127
+ */
128
+ extendsPrototype(Array, 'toNdElement', function() {
129
+ const fragment = document.createDocumentFragment();
130
+ for (let i = 0, length = this.length; i < length; i++) {
131
+ const child = ElementCreator.getChild(this[i]);
132
+ if (child === null) continue;
133
+ fragment.appendChild(child);
134
+ }
135
+ return fragment;
136
+ });
137
+
138
+ /**
139
+ * Calls the function and converts its return value to a DOM node.
140
+ * Used internally by ElementCreator to process function-based children.
141
+ * @returns {Node}
142
+ */
143
+ extendsPrototype(Function, 'toNdElement', function() {
144
+ const child = this;
145
+ if (process.env.NODE_ENV === 'development') {
146
+ PluginsManager.emit('BeforeProcessComponent', child);
147
+ }
148
+ return ElementCreator.getChild(child());
149
+ });
150
+
151
+ /**
152
+ * Converts the TemplateBinding to a hydratable DOM node for use in TemplateCloner.
153
+ * @returns {Node}
154
+ */
155
+ extendsPrototype(TemplateBinding, 'toNdElement', function() {
156
+ return ElementCreator.createHydratableNode(null, this);
157
+ });
@@ -0,0 +1,127 @@
1
+ import {NDElement} from '../NDElement';
2
+
3
+ /**
4
+ * @param {HTMLElement} el
5
+ * @param {number} timeout
6
+ */
7
+ const waitForVisualEnd = (el, timeout = 1000) => {
8
+ return new Promise((resolve) => {
9
+ let isResolved = false;
10
+
11
+ const cleanupAndResolve = (e) => {
12
+ if (e && e.target !== el) return;
13
+ if (isResolved) return;
14
+
15
+ isResolved = true;
16
+ el.removeEventListener('transitionend', cleanupAndResolve);
17
+ el.removeEventListener('animationend', cleanupAndResolve);
18
+ clearTimeout(timer);
19
+ resolve();
20
+ };
21
+
22
+ el.addEventListener('transitionend', cleanupAndResolve);
23
+ el.addEventListener('animationend', cleanupAndResolve);
24
+
25
+ const timer = setTimeout(cleanupAndResolve, timeout);
26
+
27
+ const style = window.getComputedStyle(el);
28
+ const hasTransition = style.transitionDuration !== '0s';
29
+ const hasAnimation = style.animationDuration !== '0s';
30
+
31
+ if (!hasTransition && !hasAnimation) {
32
+ cleanupAndResolve();
33
+ }
34
+ });
35
+ };
36
+
37
+ /**
38
+ * Registers a beforeUnmount hook that plays an exit CSS transition before the element is removed.
39
+ * Adds the class `{transitionName}-exit`, waits for the transition/animation to end, then removes it.
40
+ *
41
+ * @param {string} transitionName - CSS class prefix for the exit transition
42
+ * @returns {this}
43
+ * @example
44
+ * Div({ class: 'modal' }).nd.transitionOut('fade');
45
+ * // Adds 'fade-exit' before removal, waits for transitionend/animationend
46
+ */
47
+ NDElement.prototype.transitionOut = function(transitionName) {
48
+ const exitClass = transitionName + '-exit';
49
+ const el = this.$element;
50
+ this.beforeUnmount('transition-exit', async function() {
51
+ el.classes.add(exitClass);
52
+ await waitForVisualEnd(el);
53
+ el.classes.remove(exitClass);
54
+ });
55
+ return this;
56
+ };
57
+
58
+ /**
59
+ * Plays an enter CSS transition when the element is mounted into the DOM.
60
+ * Adds `{transitionName}-enter-from` immediately, then swaps to `{transitionName}-enter-to`
61
+ * on the next animation frame, and cleans up after the transition ends.
62
+ *
63
+ * @param {string} transitionName - CSS class prefix for the enter transition
64
+ * @returns {this}
65
+ * @example
66
+ * Div({ class: 'modal' }).nd.transitionIn('fade');
67
+ * // On mount: adds 'fade-enter-from', then swaps to 'fade-enter-to'
68
+ */
69
+ NDElement.prototype.transitionIn = function(transitionName) {
70
+ const startClass = transitionName + '-enter-from';
71
+ const endClass = transitionName + '-enter-to';
72
+
73
+ const el = this.$element;
74
+
75
+ el.classes.add(startClass);
76
+
77
+ this.mounted(() => {
78
+ requestAnimationFrame(() => {
79
+ requestAnimationFrame(() => {
80
+ el.classes.remove(startClass);
81
+ el.classes.add(endClass);
82
+
83
+ waitForVisualEnd(el).then(() => {
84
+ el.classes.remove(endClass);
85
+ });
86
+ });
87
+ });
88
+ });
89
+ return this;
90
+ };
91
+
92
+ /**
93
+ * Applies both enter and exit transitions to the element.
94
+ * Shorthand for calling .transitionIn(name) and .transitionOut(name).
95
+ *
96
+ * @param {string} transitionName - CSS class prefix for both enter and exit transitions
97
+ * @returns {this}
98
+ * @example
99
+ * Div({}).nd.transition('slide');
100
+ * // On mount: enter transition; on unmount: exit transition
101
+ */
102
+ NDElement.prototype.transition = function (transitionName) {
103
+ this.transitionIn(transitionName);
104
+ this.transitionOut(transitionName);
105
+ return this;
106
+ };
107
+
108
+ /**
109
+ * Immediately applies a CSS animation class to the element.
110
+ * Removes the class automatically once the animation ends.
111
+ *
112
+ * @param {string} animationName - CSS animation class name to add
113
+ * @returns {this}
114
+ * @example
115
+ * Button('Click me').nd.animate('shake');
116
+ * // Adds 'shake' class, removes it when animationend fires
117
+ */
118
+ NDElement.prototype.animate = function(animationName) {
119
+ const el = this.$element;
120
+ el.classes.add(animationName);
121
+
122
+ waitForVisualEnd(el).then(() => {
123
+ el.classes.remove(animationName);
124
+ });
125
+
126
+ return this;
127
+ };
@@ -0,0 +1,209 @@
1
+ import {ElementCreator} from '../ElementCreator';
2
+ import {createTextNode} from '../HtmlElementWrapper';
3
+ import {NDElement} from '../NDElement';
4
+
5
+ /**
6
+ * Stores deferred attribute, class, style, and event bindings for a cloneable element.
7
+ * Used internally by TemplateCloner to apply per-instance data to cloned DOM nodes.
8
+ * Not intended for direct use in application code.
9
+ *
10
+ * @internal
11
+ * @constructor
12
+ * @param {HTMLElement} $element - The template element to clone
13
+ */
14
+ export default function NodeCloner($element) {
15
+ this.$element = $element;
16
+ this.$classes = null;
17
+ this.$styles = null;
18
+ this.$attrs = null;
19
+ this.$ndMethods = null;
20
+ }
21
+
22
+
23
+ /**
24
+ * Attaches a template binding to the element by hydrating it with the specified method.
25
+ *
26
+ * @param {string} methodName - Name of the hydration method to call
27
+ * @param {BindingHydrator} bindingHydrator - Template binding with $hydrate method
28
+ * @returns {HTMLElement} The underlying HTML element
29
+ * @example
30
+ * const onClick = $binder.attach((event, data) => console.log(data));
31
+ * element.nd.attach('onClick', onClick);
32
+ */
33
+ NDElement.prototype.attach = function(methodName, bindingHydrator) {
34
+ if(typeof bindingHydrator === 'function') {
35
+ const element = this.$element;
36
+ element.nodeCloner = element.nodeCloner || new NodeCloner(element);
37
+ element.nodeCloner.attach(methodName, bindingHydrator);
38
+ return element;
39
+ }
40
+ bindingHydrator.$hydrate(this.$element, methodName);
41
+ return this.$element;
42
+ };
43
+
44
+ NodeCloner.prototype.__$isNodeCloner = true;
45
+
46
+ const buildProperties = (cache, properties, data) => {
47
+ for(const key in properties) {
48
+ cache[key] = properties[key].apply(null, data);
49
+ }
50
+ return cache;
51
+ };
52
+
53
+ /**
54
+ * Pre-compiles all registered bindings into a sequence of optimised steps.
55
+ * Called once before the first clone operation. Subsequent calls are no-ops.
56
+ *
57
+ * @internal
58
+ */
59
+ NodeCloner.prototype.resolve = function() {
60
+ if(this.$content) {
61
+ return;
62
+ }
63
+ const steps = [];
64
+ if(this.$ndMethods) {
65
+ const methods = Object.keys(this.$ndMethods);
66
+ if(methods.length === 1) {
67
+ const methodName = methods[0];
68
+ const callback = this.$ndMethods[methodName];
69
+ steps.push((clonedNode, data) => {
70
+ clonedNode.nd[methodName](callback.bind(clonedNode, ...data));
71
+ });
72
+ } else {
73
+ steps.push((clonedNode, data) => {
74
+ const nd = clonedNode.nd;
75
+ for(const methodName in this.$ndMethods) {
76
+ nd[methodName](this.$ndMethods[methodName].bind(clonedNode, ...data));
77
+ }
78
+ });
79
+ }
80
+ }
81
+ if(this.$classes) {
82
+ const cache = {};
83
+ const keys = Object.keys(this.$classes);
84
+
85
+ if(keys.length === 1) {
86
+ const key = keys[0];
87
+ const callback = this.$classes[key];
88
+ steps.push((clonedNode, data) => {
89
+ cache[key] = callback.apply(null, data);
90
+ ElementCreator.processClassAttribute(clonedNode, cache);
91
+ });
92
+ } else {
93
+ steps.push((clonedNode, data) => {
94
+ ElementCreator.processClassAttribute(clonedNode, buildProperties(cache, this.$classes, data));
95
+ });
96
+ }
97
+ }
98
+ if(this.$styles) {
99
+ const cache = {};
100
+ const keys = Object.keys(this.$styles);
101
+
102
+ if(keys.length === 1) {
103
+ const key = keys[0];
104
+ const callback = this.$styles[key];
105
+ steps.push((clonedNode, data) => {
106
+ cache[key] = callback.apply(null, data);
107
+ ElementCreator.processStyleAttribute(clonedNode, cache);
108
+ });
109
+ } else {
110
+ steps.push((clonedNode, data) => {
111
+ ElementCreator.processStyleAttribute(clonedNode, buildProperties(cache, this.$styles, data));
112
+ });
113
+ }
114
+ }
115
+ if(this.$attrs) {
116
+ const cache = {};
117
+ const keys = Object.keys(this.$attrs);
118
+
119
+ if(keys.length === 1) {
120
+ const key = keys[0];
121
+ const callback = this.$attrs[key];
122
+ steps.push((clonedNode, data) => {
123
+ cache[key] = callback.apply(null, data);
124
+ ElementCreator.processAttributes(clonedNode, cache);
125
+ });
126
+ } else {
127
+ steps.push((clonedNode, data) => {
128
+ ElementCreator.processAttributes(clonedNode, buildProperties(cache, this.$attrs, data));
129
+ });
130
+ }
131
+ }
132
+
133
+ const stepsCount = steps.length;
134
+ const $element = this.$element;
135
+
136
+ this.cloneNode = (data) => {
137
+ const clonedNode = $element.cloneNode(false);
138
+ for(let i = 0; i < stepsCount; i++) {
139
+ steps[i](clonedNode, data);
140
+ }
141
+ return clonedNode;
142
+ };
143
+ };
144
+
145
+ /**
146
+ * Clones the template element and applies all compiled binding steps with the given data.
147
+ *
148
+ * @internal
149
+ * @param {Array} data - Data array passed to each binding callback
150
+ * @returns {HTMLElement} The cloned and hydrated element
151
+ */
152
+ NodeCloner.prototype.cloneNode = function(data) {
153
+ return this.$element.cloneNode(false);
154
+ };
155
+
156
+ /**
157
+ * Registers an NDElement method binding (e.g. onClick, onInput) to be applied on each clone.
158
+ *
159
+ * @internal
160
+ * @param {string} methodName - Name of the NDElement method to call (e.g. 'onClick')
161
+ * @param {Function} callback - Callback function to pass to the method
162
+ * @returns {NodeCloner} this
163
+ */
164
+ NodeCloner.prototype.attach = function(methodName, callback) {
165
+ this.$ndMethods = this.$ndMethods || {};
166
+ this.$ndMethods[methodName] = callback;
167
+ return this;
168
+ };
169
+
170
+ /**
171
+ * Registers a reactive text content binding for the element.
172
+ *
173
+ * @internal
174
+ * @param {Function} valueorProperty - Function receiving data and returning the text content
175
+ * @returns {NodeCloner} this
176
+ */
177
+ NodeCloner.prototype.text = function(valueorProperty) {
178
+ this.$content = valueorProperty;
179
+ if(typeof valueorProperty === 'function') {
180
+ this.cloneNode = (data) => createTextNode(valueorProperty.apply(null, data));
181
+ return this;
182
+ }
183
+ this.cloneNode = (data) => createTextNode(data[0][valueorProperty]);
184
+ return this;
185
+ };
186
+
187
+ /**
188
+ * Registers an attribute binding to be applied on each clone.
189
+ *
190
+ * @internal
191
+ * @param {string} attrName - Attribute name
192
+ * @param {{property: string, value: *}} value - Function receiving data and returning the attribute value
193
+ * @returns {NodeCloner} this
194
+ */
195
+ NodeCloner.prototype.attr = function(attrName, value) {
196
+ if(attrName === 'class') {
197
+ this.$classes = this.$classes || {};
198
+ this.$classes[value.property] = value.value;
199
+ return this;
200
+ }
201
+ if(attrName === 'style') {
202
+ this.$styles = this.$styles || {};
203
+ this.$styles[value.property] = value.value;
204
+ return this;
205
+ }
206
+ this.$attrs = this.$attrs || {};
207
+ this.$attrs[attrName] = value.value;
208
+ return this;
209
+ };
@@ -0,0 +1,192 @@
1
+ import TemplateBinding from '../TemplateBinding';
2
+ import { $hydrateFn} from './utils';
3
+ import NodeCloner from './NodeCloner';
4
+
5
+ /**
6
+ * Creates a high-performance template cloner for repeated rendering of the same structure.
7
+ * On the first call, builds the template by calling $fn with a binder object.
8
+ * On subsequent calls, clones the compiled template and hydrates it with new data.
9
+ * Used internally by ForEachArray and other list renderers.
10
+ *
11
+ * @constructor
12
+ * @param {(binder: TemplateCloner) => HTMLElement} $fn - Function that builds the template using binder methods
13
+ * @example
14
+ * const cloner = new TemplateCloner((t) =>
15
+ * Div({},
16
+ * Span(t.text((item) => item.name)),
17
+ * Button({}, 'Delete').nd.onClick(t.event((item) => () => list.removeItem(item)))
18
+ * )
19
+ * );
20
+ * cloner.clone([item]); // returns a hydrated clone
21
+ */
22
+ export function TemplateCloner($fn) {
23
+ let $node = null;
24
+
25
+ const assignClonerToNode = ($node) => {
26
+ const childNodes = $node.childNodes;
27
+ let containDynamicNode = !!$node.nodeCloner;
28
+ const childNodesLength = childNodes.length;
29
+ for(let i = 0; i < childNodesLength; i++) {
30
+ const child = childNodes[i];
31
+ if(child.nodeCloner) {
32
+ containDynamicNode = true;
33
+ }
34
+ const localContainDynamicNode = assignClonerToNode(child);
35
+ if(localContainDynamicNode) {
36
+ containDynamicNode = true;
37
+ }
38
+ }
39
+
40
+ if(!containDynamicNode) {
41
+ $node.dynamicCloneNode = $node.cloneNode.bind($node, true);
42
+ } else {
43
+ if($node.nodeCloner) {
44
+ $node.nodeCloner.resolve();
45
+ $node.dynamicCloneNode = (data) => {
46
+ const clonedNode = $node.nodeCloner.cloneNode(data);
47
+ for(let i = 0; i < childNodesLength; i++) {
48
+ clonedNode.appendChild(childNodes[i].dynamicCloneNode(data));
49
+ }
50
+ return clonedNode;
51
+ };
52
+ } else {
53
+ $node.dynamicCloneNode = (data) => {
54
+ const clonedNode = $node.cloneNode();
55
+ for(let i = 0; i < childNodesLength; i++) {
56
+ clonedNode.appendChild(childNodes[i].dynamicCloneNode(data));
57
+ }
58
+ return clonedNode;
59
+ };
60
+ }
61
+ }
62
+
63
+ return containDynamicNode;
64
+ };
65
+
66
+
67
+ /**
68
+ * Clones the compiled template and hydrates it with the given data.
69
+ * On the first call, also compiles the template (builds and optimizes binding steps).
70
+ *
71
+ * @param {Array} data - Data array passed to all binding callbacks
72
+ * @returns {HTMLElement} Cloned and hydrated DOM node
73
+ */
74
+ this.clone = (data) => {
75
+ const binder = createTemplateCloner(this);
76
+ $node = $fn(binder);
77
+ if(!$node.nodeCloner) {
78
+ $node.nodeCloner = new NodeCloner($node);
79
+ }
80
+ assignClonerToNode($node);
81
+ this.clone = $node.dynamicCloneNode;
82
+ return $node.dynamicCloneNode(data);
83
+ };
84
+
85
+
86
+ const createBinding = (hydrateFunction, targetType) => {
87
+ return new TemplateBinding((element, property) => {
88
+ $hydrateFn(hydrateFunction, targetType, element, property);
89
+ });
90
+ };
91
+
92
+ /**
93
+ * Creates a style binding — the result of fn(data) is applied as inline styles.
94
+ *
95
+ * @param {((...data: any[]) => Record<string, string>)} fn - Function returning a style object
96
+ * @returns {TemplateBinding}
97
+ */
98
+ this.style = (fn) => {
99
+ return createBinding(fn, 'style');
100
+ };
101
+
102
+ /**
103
+ * Creates a class binding — the result of fn(data) is applied as a class map.
104
+ *
105
+ * @param {((...data: any[]) => Record<string, boolean>)} fn - Function returning a class map
106
+ * @returns {TemplateBinding}
107
+ */
108
+ this.class = (fn) => {
109
+ return createBinding(fn, 'class');
110
+ };
111
+
112
+ this.property = (propertyName) => {
113
+ return this.value(propertyName);
114
+ };
115
+
116
+ /**
117
+ * Creates a text/value binding — the result is set as text content or input value.
118
+ * Alias: .text()
119
+ *
120
+ * @param {string|(((...data: any[]) => string))} callbackOrProperty - Property name (string) or callback returning the value
121
+ * @returns {TemplateBinding}
122
+ */
123
+ this.value = (callbackOrProperty) => {
124
+ return createBinding(callbackOrProperty, 'value');
125
+ };
126
+
127
+ /**
128
+ * Alias for .value() — creates a text content binding.
129
+ *
130
+ * @param {string|(((...data: any[]) => string))} callbackOrProperty
131
+ * @returns {TemplateBinding}
132
+ */
133
+ this.text = this.value;
134
+
135
+ /**
136
+ * Creates an attribute binding — the result of fn(data) is set as an attribute value.
137
+ *
138
+ * @param {((...data: any[]) => string)} fn - Function returning the attribute value
139
+ * @returns {TemplateBinding}
140
+ */
141
+ this.attr = (fn) => {
142
+ return createBinding(fn, 'attributes');
143
+ };
144
+
145
+ /**
146
+ * Creates an event binding — fn(data) returns the event handler to attach.
147
+ *
148
+ * @param {((...data: any[]) => EventListener)} fn - Function returning the event callback
149
+ * @returns {TemplateBinding}
150
+ */
151
+ this.attach = (fn) => {
152
+ return createBinding(fn, 'attach');
153
+ };
154
+
155
+ this.callback = this.attach;
156
+ }
157
+
158
+
159
+ const createTemplateCloner = ($binder) => {
160
+ return new Proxy($binder, {
161
+ get(target, prop) {
162
+ if(prop in target) {
163
+ return target[prop];
164
+ }
165
+ if (typeof prop === 'symbol') return target[prop];
166
+ return target.value(prop);
167
+ },
168
+ });
169
+ };
170
+
171
+ export function useCache(fn) {
172
+ let $cache = null;
173
+
174
+ let wrapper = (args) => {
175
+ $cache = new TemplateCloner(fn);
176
+
177
+ const node = $cache.clone(args);
178
+ wrapper = $cache.clone;
179
+ return node;
180
+ };
181
+
182
+ if(fn.length < 2) {
183
+ return (...args) => {
184
+ return wrapper(args);
185
+ };
186
+ }
187
+ return (_, __, ...args) => {
188
+ return wrapper([_, __, ...args]);
189
+ };
190
+ }
191
+
192
+ export const template = useCache;