native-document 1.0.14 → 1.0.16-8.1

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 (643) 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 +8665 -1313
  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 +218 -131
  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 -501
  77. package/docs/contributing.md +300 -25
  78. package/docs/core-concepts.md +209 -367
  79. package/docs/elements.md +268 -255
  80. package/docs/extending-native-document-element.md +259 -0
  81. package/docs/filters.md +247 -0
  82. package/docs/getting-started.md +199 -260
  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 +387 -0
  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 -356
  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 -93
  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 -8
  107. package/package.json +59 -9
  108. package/readme.md +294 -90
  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 +9 -22
  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/core/elements/control/for-each.js +170 -0
  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 +5 -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 +181 -0
  400. package/src/core/wrappers/DocumentObserver.js +182 -0
  401. package/src/core/wrappers/ElementCreator.js +110 -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 +24 -0
  410. package/src/core/wrappers/prototypes/bind-class-extensions.js +0 -0
  411. package/src/core/wrappers/prototypes/nd-element-extensions.js +149 -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 -233
  617. package/src/data/ObservableChecker.js +0 -38
  618. package/src/data/ObservableItem.js +0 -116
  619. package/src/data/Store.js +0 -74
  620. package/src/elements/anchor.js +0 -84
  621. package/src/elements/content-formatter.js +0 -32
  622. package/src/elements/control/for-each.js +0 -174
  623. package/src/elements/control/show-if.js +0 -79
  624. package/src/elements/control/switch.js +0 -98
  625. package/src/elements/description-list.js +0 -5
  626. package/src/elements/form.js +0 -71
  627. package/src/elements/html5-semantics.js +0 -12
  628. package/src/elements/img.js +0 -45
  629. package/src/elements/interactive.js +0 -7
  630. package/src/elements/list.js +0 -6
  631. package/src/elements/medias.js +0 -8
  632. package/src/elements/meta-data.js +0 -9
  633. package/src/elements/table.js +0 -14
  634. package/src/utils/args-types.js +0 -100
  635. package/src/utils/debug-manager.js +0 -31
  636. package/src/utils/helpers.js +0 -37
  637. package/src/utils/plugins-manager.js +0 -12
  638. package/src/utils/prototypes.js +0 -45
  639. package/src/wrappers/AttributesWrapper.js +0 -157
  640. package/src/wrappers/DocumentObserver.js +0 -51
  641. package/src/wrappers/HtmlElementEventsWrapper.js +0 -77
  642. package/src/wrappers/HtmlElementWrapper.js +0 -206
  643. package/src/wrappers/constants.js +0 -2
@@ -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;
@@ -0,0 +1,142 @@
1
+ import {ElementCreator} from '../ElementCreator';
2
+
3
+ /**
4
+ * Hydrates a cloned node with all attribute, class, style, and attachment bindings
5
+ * from a compiled BindingData object. Full update path — applies both static attributes
6
+ * and dynamic class/style maps.
7
+ *
8
+ * @internal
9
+ * @param {HTMLElement} node - Cloned DOM node to hydrate
10
+ * @param {BindingData} bindDingData - Pre-compiled binding metadata
11
+ * @param {Array} data - Data array passed to each binding callback
12
+ * @returns {true}
13
+ */
14
+ export const hydrateFull = (node, bindDingData, data) => {
15
+ const cacheAttributes = bindDingData._cache;
16
+
17
+ for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
18
+ const attr = bindDingData._flatAttributes[i];
19
+ cacheAttributes[attr.name] = attr.value.apply(null, data);
20
+ }
21
+
22
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
23
+ const dyn = bindDingData._flatDynamique[i];
24
+ cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
25
+ }
26
+
27
+ ElementCreator.processAttributesDirect(node, cacheAttributes);
28
+ return true;
29
+ };
30
+
31
+ /**
32
+ * Hydrates only the dynamic class and style bindings on a cloned node.
33
+ * Used when there are no static attribute bindings.
34
+ *
35
+ * @internal
36
+ * @param {HTMLElement} node - Cloned DOM node to hydrate
37
+ * @param {BindingData} bindDingData - Pre-compiled binding metadata
38
+ * @param {Array} data - Data array passed to each binding callback
39
+ * @returns {true}
40
+ */
41
+ export const hydrateDynamic = (node, bindDingData, data) => {
42
+ const cacheAttributes = bindDingData._cache;
43
+
44
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
45
+ const dyn = bindDingData._flatDynamique[i];
46
+ cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
47
+ }
48
+
49
+ ElementCreator.processClassAttribute(node, cacheAttributes.class);
50
+ ElementCreator.processStyleAttribute(node, cacheAttributes.style);
51
+ return true;
52
+ };
53
+
54
+ /**
55
+ * Hydrates only the dynamic class bindings on a cloned node.
56
+ *
57
+ * @internal
58
+ * @param {HTMLElement} node - Cloned DOM node to hydrate
59
+ * @param {BindingData} bindDingData - Pre-compiled binding metadata
60
+ * @param {Array} data - Data array passed to each binding callback
61
+ * @returns {true}
62
+ */
63
+ export const hydrateClassAttribute = (node, bindDingData, data) => {
64
+ const classAttributes = bindDingData._cache.class;
65
+
66
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
67
+ const dyn = bindDingData._flatDynamique[i];
68
+ classAttributes[dyn.key] = dyn.value.apply(null, data);
69
+ }
70
+
71
+ ElementCreator.processClassAttribute(node, classAttributes);
72
+ return true;
73
+ };
74
+
75
+ /**
76
+ * Hydrates only the dynamic style bindings on a cloned node.
77
+ *
78
+ * @internal
79
+ * @param {HTMLElement} node - Cloned DOM node to hydrate
80
+ * @param {BindingData} bindDingData - Pre-compiled binding metadata
81
+ * @param {Array} data - Data array passed to each binding callback
82
+ * @returns {true}
83
+ */
84
+ export const hydrateStyleAttribute = (node, bindDingData, data) => {
85
+ const styleAttributes = bindDingData._cache;
86
+
87
+ for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
88
+ const dyn = bindDingData._flatDynamique[i];
89
+ styleAttributes[dyn.key] = dyn.value.apply(null, data);
90
+ }
91
+
92
+ ElementCreator.processStyleAttribute(node, styleAttributes);
93
+ return true;
94
+ };
95
+
96
+ /**
97
+ * Hydrates only the static attribute bindings on a cloned node.
98
+ *
99
+ * @internal
100
+ * @param {HTMLElement} node - Cloned DOM node to hydrate
101
+ * @param {BindingData} bindDingData - Pre-compiled binding metadata
102
+ * @param {Array} data - Data array passed to each binding callback
103
+ * @returns {true}
104
+ */
105
+ export const hydrateAttributes = (node, bindDingData, data) => {
106
+ const cacheAttributes = bindDingData._cache;
107
+
108
+ for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
109
+ const attr = bindDingData._flatAttributes[i];
110
+ cacheAttributes[attr.name] = attr.value.apply(null, data);
111
+ }
112
+
113
+ ElementCreator.processAttributesDirect(node, cacheAttributes);
114
+ return true;
115
+ };
116
+
117
+ /**
118
+ * Selects and returns the most efficient hydration function for the given BindingData.
119
+ * Called once during template compilation to assign the optimal update path.
120
+ *
121
+ * @internal
122
+ * @param {BindingData} bindDingData - Pre-compiled binding metadata
123
+ * @returns {Function} One of: hydrateFull, hydrateDynamic, hydrateClassAttribute, hydrateStyleAttribute, hydrateAttributes, or noUpdate
124
+ */
125
+ export const getHydrator = (bindDingData) => {
126
+ if(!bindDingData._cache) {
127
+ return noUpdate;
128
+ }
129
+ if(bindDingData._flatAttributesLength && bindDingData._flatDynamiqueLength) {
130
+ return hydrateFull;
131
+ }
132
+ if(bindDingData._flatAttributesLength) {
133
+ return hydrateAttributes;
134
+ }
135
+ if(bindDingData._hasClassAttribute && bindDingData._hasStyleAttribute) {
136
+ return hydrateDynamic;
137
+ }
138
+ if(bindDingData._hasClassAttribute) {
139
+ return hydrateClassAttribute;
140
+ }
141
+ return hydrateStyleAttribute;
142
+ };