native-document 1.0.16 → 1.0.17-1.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 (680) hide show
  1. package/.npmrc.example +1 -0
  2. package/.vitepress/config.js +166 -0
  3. package/CHANGELOG.md +223 -0
  4. package/cdn.js +19 -0
  5. package/components.d.ts +2 -0
  6. package/components.js +32 -0
  7. package/devtools/ComponentRegistry.js +113 -0
  8. package/devtools/index.js +8 -0
  9. package/devtools/plugin/dev-tools-plugin.js +15 -0
  10. package/devtools/transformers/nd-vite-devtools.js +55 -0
  11. package/devtools/transformers/src/transformComponentForHrm.js +73 -0
  12. package/devtools/transformers/src/transformJsFile.js +9 -0
  13. package/devtools/transformers/src/utils.js +79 -0
  14. package/devtools/transformers/templates/hrm.hook.template.js +46 -0
  15. package/devtools/transformers/templates/hrm.orbservable.hook.template.js +76 -0
  16. package/devtools/widget/Widget.js +49 -0
  17. package/devtools/widget/widget.css +81 -0
  18. package/devtools/widget.js +23 -0
  19. package/dist/native-document.components.min.css +1 -0
  20. package/dist/native-document.components.min.js +23873 -0
  21. package/dist/native-document.dev.js +8464 -1515
  22. package/dist/native-document.dev.js.map +1 -0
  23. package/dist/native-document.devtools.min.js +1 -0
  24. package/dist/native-document.min.js +1 -1
  25. package/docs/advanced-components.md +419 -0
  26. package/docs/anchor.md +181 -257
  27. package/docs/cache.md +180 -0
  28. package/docs/cli.md +179 -0
  29. package/docs/components/accordion.md +172 -0
  30. package/docs/components/alert.md +99 -0
  31. package/docs/components/avatar.md +160 -0
  32. package/docs/components/badge.md +102 -0
  33. package/docs/components/breadcrumb.md +89 -0
  34. package/docs/components/button.md +183 -0
  35. package/docs/components/card.md +69 -0
  36. package/docs/components/context-menu.md +118 -0
  37. package/docs/components/data-table.md +345 -0
  38. package/docs/components/dropdown.md +214 -0
  39. package/docs/components/form/autocomplete-field.md +81 -0
  40. package/docs/components/form/checkbox-field.md +41 -0
  41. package/docs/components/form/checkbox-group-field.md +54 -0
  42. package/docs/components/form/color-field.md +64 -0
  43. package/docs/components/form/date-field.md +92 -0
  44. package/docs/components/form/field-collection.md +63 -0
  45. package/docs/components/form/file-field.md +203 -0
  46. package/docs/components/form/form-control.md +87 -0
  47. package/docs/components/form/image-field.md +90 -0
  48. package/docs/components/form/index.md +115 -0
  49. package/docs/components/form/number-field.md +65 -0
  50. package/docs/components/form/radio-field.md +51 -0
  51. package/docs/components/form/select-field.md +123 -0
  52. package/docs/components/form/slider.md +136 -0
  53. package/docs/components/form/string-field.md +134 -0
  54. package/docs/components/form/textarea-field.md +65 -0
  55. package/docs/components/form-fields.md +372 -0
  56. package/docs/components/getting-started.md +264 -0
  57. package/docs/components/icons.md +321 -0
  58. package/docs/components/index.md +337 -0
  59. package/docs/components/layout.md +279 -0
  60. package/docs/components/list.md +73 -0
  61. package/docs/components/menu.md +215 -0
  62. package/docs/components/modal.md +156 -0
  63. package/docs/components/pagination.md +95 -0
  64. package/docs/components/popover.md +131 -0
  65. package/docs/components/progress.md +111 -0
  66. package/docs/components/shortcut-manager.md +221 -0
  67. package/docs/components/simple-table.md +107 -0
  68. package/docs/components/skeleton.md +155 -0
  69. package/docs/components/spinner.md +100 -0
  70. package/docs/components/splitter.md +133 -0
  71. package/docs/components/stepper.md +163 -0
  72. package/docs/components/switch.md +113 -0
  73. package/docs/components/tabs.md +153 -0
  74. package/docs/components/toast.md +119 -0
  75. package/docs/components/tooltip.md +151 -0
  76. package/docs/components/traits.md +261 -0
  77. package/docs/conditional-rendering.md +177 -502
  78. package/docs/contributing.md +300 -25
  79. package/docs/core-concepts.md +207 -366
  80. package/docs/elements.md +266 -254
  81. package/docs/extending-native-document-element.md +259 -0
  82. package/docs/filters.md +247 -0
  83. package/docs/getting-started.md +195 -257
  84. package/docs/i18n.md +241 -0
  85. package/docs/index.md +76 -0
  86. package/docs/lifecycle-events.md +146 -67
  87. package/docs/list-rendering.md +240 -460
  88. package/docs/memory-management.md +135 -46
  89. package/docs/native-document-element.md +487 -0
  90. package/docs/native-fetch.md +213 -0
  91. package/docs/observable-resource.md +364 -0
  92. package/docs/observables.md +690 -357
  93. package/docs/routing.md +246 -646
  94. package/docs/state-management.md +213 -306
  95. package/docs/svg-elements.md +231 -0
  96. package/docs/theming.md +409 -0
  97. package/docs/tutorials/.gitkeep +0 -0
  98. package/docs/validation.md +98 -91
  99. package/docs/vitepress-conventions.md +219 -0
  100. package/elements.d.ts +7 -0
  101. package/elements.js +3 -4
  102. package/eslint.config.js +35 -0
  103. package/i18n.js +1 -0
  104. package/i18n.ts +2 -0
  105. package/index.d.ts +21 -0
  106. package/index.def.js +1086 -0
  107. package/index.js +19 -13
  108. package/package.json +65 -8
  109. package/readme.md +296 -93
  110. package/rollup.config.js +52 -3
  111. package/router.d.ts +7 -0
  112. package/router.js +0 -0
  113. package/src/components/$traits/has-draggable/HasDraggable.d.ts +4 -0
  114. package/src/components/$traits/has-draggable/HasDraggable.js +82 -0
  115. package/src/components/$traits/has-draggable/has-draggable.css +8 -0
  116. package/src/components/$traits/has-items/HasItems.d.ts +9 -0
  117. package/src/components/$traits/has-items/HasItems.js +64 -0
  118. package/src/components/$traits/has-position/HasFullPosition.d.ts +14 -0
  119. package/src/components/$traits/has-position/HasFullPosition.js +95 -0
  120. package/src/components/$traits/has-position/HasPosition.d.ts +7 -0
  121. package/src/components/$traits/has-position/HasPosition.js +45 -0
  122. package/src/components/$traits/has-resizable/HasResizable.d.ts +13 -0
  123. package/src/components/$traits/has-resizable/HasResizable.js +122 -0
  124. package/src/components/$traits/has-resizable/has-resizable.css +121 -0
  125. package/src/components/$traits/has-validation/HasValidation.d.ts +17 -0
  126. package/src/components/$traits/has-validation/HasValidation.js +133 -0
  127. package/src/components/BaseComponent.d.ts +32 -0
  128. package/src/components/BaseComponent.js +289 -0
  129. package/src/components/accordion/Accordion.js +269 -0
  130. package/src/components/accordion/AccordionItem.js +234 -0
  131. package/src/components/accordion/index.js +7 -0
  132. package/src/components/accordion/types/Accordion.d.ts +47 -0
  133. package/src/components/accordion/types/AccordionItem.d.ts +48 -0
  134. package/src/components/alert/Alert.js +354 -0
  135. package/src/components/alert/index.js +6 -0
  136. package/src/components/alert/types/Alert.d.ts +62 -0
  137. package/src/components/avatar/Avatar.js +431 -0
  138. package/src/components/avatar/AvatarGroup.js +98 -0
  139. package/src/components/avatar/index.js +7 -0
  140. package/src/components/avatar/types/Avatar.d.ts +74 -0
  141. package/src/components/avatar/types/AvatarGroup.d.ts +32 -0
  142. package/src/components/badge/Badge.js +246 -0
  143. package/src/components/badge/index.js +6 -0
  144. package/src/components/badge/types/Badge.d.ts +51 -0
  145. package/src/components/base-component.css +0 -0
  146. package/src/components/breadcrumb/BreadCrumb.js +142 -0
  147. package/src/components/breadcrumb/index.js +5 -0
  148. package/src/components/breadcrumb/types/BreadCrumb.d.ts +42 -0
  149. package/src/components/button/Button.js +321 -0
  150. package/src/components/button/index.js +5 -0
  151. package/src/components/button/types/Button.d.ts +62 -0
  152. package/src/components/card/Card.js +283 -0
  153. package/src/components/card/index.js +5 -0
  154. package/src/components/card/types/Card.d.ts +42 -0
  155. package/src/components/context-menu/ContextMenu.js +129 -0
  156. package/src/components/context-menu/ContextMenuGroup.js +31 -0
  157. package/src/components/context-menu/ContextMenuItem.js +30 -0
  158. package/src/components/context-menu/index.js +10 -0
  159. package/src/components/context-menu/types/ContextMenu.d.ts +30 -0
  160. package/src/components/context-menu/types/ContextMenuGroup.d.ts +18 -0
  161. package/src/components/context-menu/types/ContextMenuItem.d.ts +18 -0
  162. package/src/components/divider/Divider.js +258 -0
  163. package/src/components/divider/index.js +6 -0
  164. package/src/components/divider/types/Divider.d.ts +55 -0
  165. package/src/components/dropdown/Dropdown.js +532 -0
  166. package/src/components/dropdown/DropdownDivider.js +46 -0
  167. package/src/components/dropdown/DropdownGroup.js +84 -0
  168. package/src/components/dropdown/DropdownItem.js +151 -0
  169. package/src/components/dropdown/DropdownTrigger.js +94 -0
  170. package/src/components/dropdown/helpers.js +53 -0
  171. package/src/components/dropdown/index.js +13 -0
  172. package/src/components/dropdown/types/Dropdown.d.ts +88 -0
  173. package/src/components/dropdown/types/DropdownDivider.d.ts +20 -0
  174. package/src/components/dropdown/types/DropdownGroup.d.ts +25 -0
  175. package/src/components/dropdown/types/DropdownItem.d.ts +41 -0
  176. package/src/components/dropdown/types/DropdownTrigger.d.ts +32 -0
  177. package/src/components/form/FormControl.js +499 -0
  178. package/src/components/form/field/Field.js +420 -0
  179. package/src/components/form/field/FieldCollection.js +292 -0
  180. package/src/components/form/field/types/AutocompleteField.js +168 -0
  181. package/src/components/form/field/types/CheckboxField.js +77 -0
  182. package/src/components/form/field/types/CheckboxGroupField.js +171 -0
  183. package/src/components/form/field/types/ColorField.js +102 -0
  184. package/src/components/form/field/types/DateField.js +315 -0
  185. package/src/components/form/field/types/EmailField.js +104 -0
  186. package/src/components/form/field/types/FileField.js +276 -0
  187. package/src/components/form/field/types/HiddenField.js +44 -0
  188. package/src/components/form/field/types/ImageField.js +138 -0
  189. package/src/components/form/field/types/NumberField.js +177 -0
  190. package/src/components/form/field/types/PasswordField.js +200 -0
  191. package/src/components/form/field/types/RadioField.js +145 -0
  192. package/src/components/form/field/types/RangeField.js +117 -0
  193. package/src/components/form/field/types/SearchField.js +66 -0
  194. package/src/components/form/field/types/SelectField.js +247 -0
  195. package/src/components/form/field/types/StringField.js +148 -0
  196. package/src/components/form/field/types/TelField.js +98 -0
  197. package/src/components/form/field/types/TextAreaField.js +142 -0
  198. package/src/components/form/field/types/TimeField.js +215 -0
  199. package/src/components/form/field/types/UrlField.js +115 -0
  200. package/src/components/form/field/types/file-field-mode/FileAvatarMode.js +183 -0
  201. package/src/components/form/field/types/file-field-mode/FileDropzoneMode.js +117 -0
  202. package/src/components/form/field/types/file-field-mode/FileItemPreview.js +150 -0
  203. package/src/components/form/field/types/file-field-mode/FileNativeMode.js +43 -0
  204. package/src/components/form/field/types/file-field-mode/FileUploadButtonMode.js +120 -0
  205. package/src/components/form/field/types/file-field-mode/FileWallMode.js +106 -0
  206. package/src/components/form/index.js +61 -0
  207. package/src/components/form/merge +0 -0
  208. package/src/components/form/types/Field.d.ts +73 -0
  209. package/src/components/form/types/FieldCollection.d.ts +53 -0
  210. package/src/components/form/types/FormControl.d.ts +64 -0
  211. package/src/components/form/types/fields/AutocompleteField.d.ts +48 -0
  212. package/src/components/form/types/fields/CheckboxField.d.ts +33 -0
  213. package/src/components/form/types/fields/CheckboxGroupField.d.ts +49 -0
  214. package/src/components/form/types/fields/ColorField.d.ts +37 -0
  215. package/src/components/form/types/fields/DateField.d.ts +70 -0
  216. package/src/components/form/types/fields/EmailField.d.ts +35 -0
  217. package/src/components/form/types/fields/FileAvatarMode.d.ts +46 -0
  218. package/src/components/form/types/fields/FileDropzoneMode.d.ts +28 -0
  219. package/src/components/form/types/fields/FileField.d.ts +56 -0
  220. package/src/components/form/types/fields/FileItemPreview.d.ts +35 -0
  221. package/src/components/form/types/fields/FileNativeMode.d.ts +21 -0
  222. package/src/components/form/types/fields/FileUploadButtonMode.d.ts +34 -0
  223. package/src/components/form/types/fields/FileWallMode.d.ts +32 -0
  224. package/src/components/form/types/fields/HiddenField.d.ts +26 -0
  225. package/src/components/form/types/fields/ImageField.d.ts +45 -0
  226. package/src/components/form/types/fields/NumberField.d.ts +48 -0
  227. package/src/components/form/types/fields/PasswordField.d.ts +46 -0
  228. package/src/components/form/types/fields/RadioField.d.ts +48 -0
  229. package/src/components/form/types/fields/RangeField.d.ts +44 -0
  230. package/src/components/form/types/fields/SearchField.d.ts +34 -0
  231. package/src/components/form/types/fields/SelectField.d.ts +71 -0
  232. package/src/components/form/types/fields/StringField.d.ts +48 -0
  233. package/src/components/form/types/fields/TelField.d.ts +37 -0
  234. package/src/components/form/types/fields/TextAreaField.d.ts +44 -0
  235. package/src/components/form/types/fields/TimeField.d.ts +51 -0
  236. package/src/components/form/types/fields/UrlField.d.ts +35 -0
  237. package/src/components/form/utils.js +17 -0
  238. package/src/components/form/validation/Validation.js +565 -0
  239. package/src/components/icon/Icon.js +108 -0
  240. package/src/components/icon/icon-getters.js +142 -0
  241. package/src/components/icon/icons.js +171 -0
  242. package/src/components/icon/index.js +17 -0
  243. package/src/components/icon/types/Icon.d.ts +191 -0
  244. package/src/components/index.d.ts +165 -0
  245. package/src/components/list/HasListItem.js +171 -0
  246. package/src/components/list/List.js +125 -0
  247. package/src/components/list/ListDivider.js +39 -0
  248. package/src/components/list/ListGroup.js +135 -0
  249. package/src/components/list/ListItem.js +213 -0
  250. package/src/components/list/index.js +12 -0
  251. package/src/components/list/types/List.d.ts +56 -0
  252. package/src/components/list/types/ListDivider.ts +16 -0
  253. package/src/components/list/types/ListGroup.d.ts +59 -0
  254. package/src/components/list/types/ListItem.d.ts +52 -0
  255. package/src/components/menu/HasMenuItem.js +182 -0
  256. package/src/components/menu/Menu.js +230 -0
  257. package/src/components/menu/MenuDivider.js +38 -0
  258. package/src/components/menu/MenuGroup.js +127 -0
  259. package/src/components/menu/MenuItem.js +191 -0
  260. package/src/components/menu/MenuLink.js +52 -0
  261. package/src/components/menu/index.js +14 -0
  262. package/src/components/menu/types/Menu.d.ts +60 -0
  263. package/src/components/menu/types/MenuDivider.d.ts +19 -0
  264. package/src/components/menu/types/MenuGroup.d.ts +44 -0
  265. package/src/components/menu/types/MenuItem.d.ts +46 -0
  266. package/src/components/menu/types/MenuLink.d.ts +16 -0
  267. package/src/components/modal/Modal.js +528 -0
  268. package/src/components/modal/index.js +5 -0
  269. package/src/components/modal/types/Modal.d.ts +94 -0
  270. package/src/components/pagination/Pagination.js +412 -0
  271. package/src/components/pagination/index.js +5 -0
  272. package/src/components/pagination/types/Pagination.d.ts +68 -0
  273. package/src/components/popover/Popover.js +460 -0
  274. package/src/components/popover/PopoverFooter.js +62 -0
  275. package/src/components/popover/PopoverHeader.js +69 -0
  276. package/src/components/popover/index.js +10 -0
  277. package/src/components/popover/types/Popover.d.ts +83 -0
  278. package/src/components/popover/types/PopoverFooter.d.ts +24 -0
  279. package/src/components/popover/types/PopoverHeader.d.ts +26 -0
  280. package/src/components/progress/Progress.js +406 -0
  281. package/src/components/progress/index.js +6 -0
  282. package/src/components/progress/types/Progress.d.ts +77 -0
  283. package/src/components/skeleton/Skeleton.js +232 -0
  284. package/src/components/skeleton/index.js +6 -0
  285. package/src/components/skeleton/types/Skeleton.d.ts +55 -0
  286. package/src/components/slider/Slider.js +407 -0
  287. package/src/components/slider/index.js +5 -0
  288. package/src/components/slider/types/Slider.d.ts +82 -0
  289. package/src/components/spacer/Spacer.js +28 -0
  290. package/src/components/spacer/index.js +5 -0
  291. package/src/components/spacer/types/Spacer.d.ts +19 -0
  292. package/src/components/spinner/Spinner.js +351 -0
  293. package/src/components/spinner/index.js +5 -0
  294. package/src/components/spinner/types/Spinner.d.ts +71 -0
  295. package/src/components/splitter/Splitter.js +165 -0
  296. package/src/components/splitter/SplitterGutter.js +146 -0
  297. package/src/components/splitter/SplitterPanel.js +144 -0
  298. package/src/components/splitter/index.js +10 -0
  299. package/src/components/splitter/types/Splitter.d.ts +38 -0
  300. package/src/components/splitter/types/SplitterGutter.d.ts +38 -0
  301. package/src/components/splitter/types/SplitterPanel.d.ts +41 -0
  302. package/src/components/stacks/AbsoluteStack.js +54 -0
  303. package/src/components/stacks/FixedStack.js +54 -0
  304. package/src/components/stacks/HStack.js +55 -0
  305. package/src/components/stacks/PositionStack.js +255 -0
  306. package/src/components/stacks/RelativeStack.js +54 -0
  307. package/src/components/stacks/Stack.js +167 -0
  308. package/src/components/stacks/VStack.js +56 -0
  309. package/src/components/stacks/index.js +21 -0
  310. package/src/components/stacks/types/AbsoluteStack.d.ts +16 -0
  311. package/src/components/stacks/types/FixedStack.d.ts +16 -0
  312. package/src/components/stacks/types/HStack.d.ts +16 -0
  313. package/src/components/stacks/types/PositionStack.d.ts +54 -0
  314. package/src/components/stacks/types/RelativeStack.d.ts +17 -0
  315. package/src/components/stacks/types/Stack.d.ts +39 -0
  316. package/src/components/stacks/types/VStack.d.ts +16 -0
  317. package/src/components/stepper/Stepper.js +462 -0
  318. package/src/components/stepper/StepperStep.js +242 -0
  319. package/src/components/stepper/index.js +8 -0
  320. package/src/components/stepper/types/Stepper.d.ts +68 -0
  321. package/src/components/stepper/types/StepperStep.d.ts +54 -0
  322. package/src/components/switch/Switch.js +267 -0
  323. package/src/components/switch/index.js +6 -0
  324. package/src/components/switch/types/Switch.d.ts +55 -0
  325. package/src/components/table/Column.js +212 -0
  326. package/src/components/table/ColumnGroup.js +90 -0
  327. package/src/components/table/DataTable.js +721 -0
  328. package/src/components/table/SimpleTable.js +140 -0
  329. package/src/components/table/index.js +7 -0
  330. package/src/components/table/types/Column.d.ts +49 -0
  331. package/src/components/table/types/ColumnGroup.d.ts +28 -0
  332. package/src/components/table/types/DataTable.d.ts +97 -0
  333. package/src/components/table/types/SimpleTable.d.ts +40 -0
  334. package/src/components/tabs/Tabs.js +396 -0
  335. package/src/components/tabs/index.js +6 -0
  336. package/src/components/tabs/types/Tabs.d.ts +78 -0
  337. package/src/components/toast/Toast.js +263 -0
  338. package/src/components/toast/ToastError.js +0 -0
  339. package/src/components/toast/ToastInfo.js +0 -0
  340. package/src/components/toast/ToastSuccess.js +0 -0
  341. package/src/components/toast/ToastWarning.js +0 -0
  342. package/src/components/toast/index.js +5 -0
  343. package/src/components/toast/types/Toast.d.ts +57 -0
  344. package/src/components/toast/types/ToastError.d.ts +7 -0
  345. package/src/components/toast/types/ToastInfo.d.ts +7 -0
  346. package/src/components/toast/types/ToastSuccess.d.ts +7 -0
  347. package/src/components/toast/types/ToastWarning.d.ts +7 -0
  348. package/src/components/tooltip/Tooltip.js +360 -0
  349. package/src/components/tooltip/index.js +5 -0
  350. package/src/components/tooltip/prototypes.js +6 -0
  351. package/src/components/tooltip/types/Tooltip.d.ts +65 -0
  352. package/src/{data → core/data}/MemoryManager.js +2 -3
  353. package/src/core/data/Observable.js +227 -0
  354. package/src/core/data/ObservableArray.js +522 -0
  355. package/src/core/data/ObservableChecker.js +39 -0
  356. package/src/core/data/ObservableItem.js +611 -0
  357. package/src/core/data/ObservableObject.js +274 -0
  358. package/src/core/data/ObservableResource.js +315 -0
  359. package/src/core/data/ObservableWhen.js +54 -0
  360. package/src/core/data/Store.js +520 -0
  361. package/src/core/data/observable-helpers/observable.is-to.js +390 -0
  362. package/src/core/data/observable-helpers/observable.prototypes.js +145 -0
  363. package/src/core/elements/anchor/anchor-with-sentinel.js +66 -0
  364. package/src/core/elements/anchor/anchor.js +210 -0
  365. package/src/core/elements/anchor/one-child-anchor-overwriting.js +66 -0
  366. package/src/core/elements/content-formatter.js +183 -0
  367. package/src/core/elements/control/for-each-array.js +292 -0
  368. package/src/{elements → core/elements}/control/for-each.js +42 -23
  369. package/src/core/elements/control/show-if.js +94 -0
  370. package/src/core/elements/control/show-when.js +54 -0
  371. package/src/core/elements/control/switch.js +141 -0
  372. package/src/core/elements/description-list.js +19 -0
  373. package/src/core/elements/form.js +255 -0
  374. package/src/core/elements/fragment.js +8 -0
  375. package/src/core/elements/html5-semantics.js +55 -0
  376. package/src/core/elements/img.js +59 -0
  377. package/src/{elements → core/elements}/index.js +4 -4
  378. package/src/core/elements/interactive.js +25 -0
  379. package/src/core/elements/list.js +37 -0
  380. package/src/core/elements/medias.js +37 -0
  381. package/src/core/elements/meta-data.js +43 -0
  382. package/src/core/elements/svg.js +61 -0
  383. package/src/core/elements/table.js +73 -0
  384. package/src/{errors → core/errors}/ArgTypesError.js +1 -1
  385. package/src/{errors → core/errors}/NativeDocumentError.js +0 -0
  386. package/src/core/utils/HasEventEmitter.js +85 -0
  387. package/src/core/utils/args-types.js +140 -0
  388. package/src/core/utils/cache.js +5 -0
  389. package/src/core/utils/callback-handler.js +50 -0
  390. package/src/core/utils/debug-manager.js +40 -0
  391. package/src/core/utils/events.js +148 -0
  392. package/src/core/utils/filters/date.js +178 -0
  393. package/src/core/utils/filters/index.js +4 -0
  394. package/src/core/utils/filters/standard.js +263 -0
  395. package/src/core/utils/filters/strings.js +67 -0
  396. package/src/core/utils/filters/utils.js +77 -0
  397. package/src/core/utils/formatters.js +90 -0
  398. package/src/core/utils/helpers.js +144 -0
  399. package/src/core/utils/localstorage.js +57 -0
  400. package/src/core/utils/memoize.js +115 -0
  401. package/src/core/utils/plugins-manager.js +81 -0
  402. package/src/core/utils/property-accumulator.js +72 -0
  403. package/src/core/utils/prototypes.js +44 -0
  404. package/src/core/utils/shortcut-manager.js +242 -0
  405. package/src/{utils → core/utils}/validator.js +58 -22
  406. package/src/core/wrappers/AttributesWrapper.js +240 -0
  407. package/src/core/wrappers/DocumentObserver.js +182 -0
  408. package/src/core/wrappers/ElementCreator.js +140 -0
  409. package/src/core/wrappers/HtmlElementWrapper.js +117 -0
  410. package/src/core/wrappers/NDElement.js +643 -0
  411. package/src/core/wrappers/NdPrototype.js +233 -0
  412. package/src/core/wrappers/SingletonView.js +99 -0
  413. package/src/core/wrappers/SvgElementWrapper.js +15 -0
  414. package/src/core/wrappers/TemplateBinding.js +7 -0
  415. package/src/core/wrappers/constants.js +66 -0
  416. package/src/core/wrappers/prototypes/attributes-extensions.js +24 -0
  417. package/src/core/wrappers/prototypes/bind-class-extensions.js +0 -0
  418. package/src/core/wrappers/prototypes/nd-element-extensions.js +125 -0
  419. package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +127 -0
  420. package/src/core/wrappers/template-cloner/NodeCloner.js +209 -0
  421. package/src/core/wrappers/template-cloner/TemplateCloner.js +192 -0
  422. package/src/core/wrappers/template-cloner/attributes-hydrator.js +142 -0
  423. package/src/core/wrappers/template-cloner/utils.js +173 -0
  424. package/src/fetch/NativeFetch.js +89 -0
  425. package/src/i18n/bin/scan.js +132 -0
  426. package/src/i18n/index.d.ts +2 -0
  427. package/src/i18n/service/I18nService.d.ts +27 -0
  428. package/src/i18n/service/I18nService.js +46 -0
  429. package/src/i18n/service/functions.d.ts +22 -0
  430. package/src/i18n/service/functions.js +29 -0
  431. package/src/router/Route.js +33 -8
  432. package/src/router/RouteGroupHelper.js +10 -2
  433. package/src/router/Router.js +63 -22
  434. package/src/router/RouterComponent.js +114 -6
  435. package/src/{errors → router/errors}/RouterError.js +0 -1
  436. package/src/router/link.js +8 -9
  437. package/src/router/modes/HashRouter.js +2 -2
  438. package/src/router/modes/HistoryRouter.js +2 -3
  439. package/src/router/modes/MemoryRouter.js +1 -1
  440. package/src/ui/components/accordion/AccordionItemRender.js +85 -0
  441. package/src/ui/components/accordion/AccordionRender.js +35 -0
  442. package/src/ui/components/accordion/accordion.css +121 -0
  443. package/src/ui/components/alert/AlertRender.js +87 -0
  444. package/src/ui/components/alert/alert.css +163 -0
  445. package/src/ui/components/avatar/avata-group/AvatarGroupRender.js +50 -0
  446. package/src/ui/components/avatar/avata-group/avatar-group.css +38 -0
  447. package/src/ui/components/avatar/avatar/AvatarRender.js +87 -0
  448. package/src/ui/components/avatar/avatar/avatar.css +189 -0
  449. package/src/ui/components/badge/BadgeRender.js +25 -0
  450. package/src/ui/components/badge/badge.css +168 -0
  451. package/src/ui/components/breadcrumb/BreadcrumbRender.js +52 -0
  452. package/src/ui/components/breadcrumb/breadcrumb.css +55 -0
  453. package/src/ui/components/button/ButtonRender.js +68 -0
  454. package/src/ui/components/button/button.css +296 -0
  455. package/src/ui/components/card/CardRender.js +133 -0
  456. package/src/ui/components/card/card.css +169 -0
  457. package/src/ui/components/contextmenu/ContextmenuRender.js +70 -0
  458. package/src/ui/components/contextmenu/contextmenu.css +36 -0
  459. package/src/ui/components/divider/DividerRender.js +70 -0
  460. package/src/ui/components/divider/divider.css +70 -0
  461. package/src/ui/components/dropdown/DropdownRender.js +95 -0
  462. package/src/ui/components/dropdown/divider/DropdownDividerRender.js +9 -0
  463. package/src/ui/components/dropdown/divider/dropdown-divider.css +0 -0
  464. package/src/ui/components/dropdown/dropdown.css +179 -0
  465. package/src/ui/components/dropdown/group/DropdownGroupRender.js +23 -0
  466. package/src/ui/components/dropdown/group/dropdown-group.css +0 -0
  467. package/src/ui/components/dropdown/item/DropdownItemRender.js +34 -0
  468. package/src/ui/components/dropdown/item/dropdown-item.css +0 -0
  469. package/src/ui/components/form/FieldCollectionRender.js +114 -0
  470. package/src/ui/components/form/FormControlRender.js +85 -0
  471. package/src/ui/components/form/field-collection.css +55 -0
  472. package/src/ui/components/form/fields/AutocompleteFieldRender.js +143 -0
  473. package/src/ui/components/form/fields/CheckboxFieldRender.js +63 -0
  474. package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +96 -0
  475. package/src/ui/components/form/fields/ColorFieldRender.js +30 -0
  476. package/src/ui/components/form/fields/DateFieldRender.js +155 -0
  477. package/src/ui/components/form/fields/EmailFieldRender.js +5 -0
  478. package/src/ui/components/form/fields/FieldRender.js +118 -0
  479. package/src/ui/components/form/fields/FileFieldRender.js +41 -0
  480. package/src/ui/components/form/fields/HiddenFieldRender.js +13 -0
  481. package/src/ui/components/form/fields/ImageFieldRender.js +0 -0
  482. package/src/ui/components/form/fields/NumberFieldRender.js +52 -0
  483. package/src/ui/components/form/fields/PasswordFieldRender.js +65 -0
  484. package/src/ui/components/form/fields/RadioFieldRender.js +81 -0
  485. package/src/ui/components/form/fields/RangeFieldRender.js +126 -0
  486. package/src/ui/components/form/fields/SelectFieldRender.js +253 -0
  487. package/src/ui/components/form/fields/SliderFieldRender.js +362 -0
  488. package/src/ui/components/form/fields/StringFieldRender.js +6 -0
  489. package/src/ui/components/form/fields/TelFieldRender.js +6 -0
  490. package/src/ui/components/form/fields/TextAreaFieldRender.js +96 -0
  491. package/src/ui/components/form/fields/TimeFieldRender.js +142 -0
  492. package/src/ui/components/form/fields/UrlFieldRender.js +6 -0
  493. package/src/ui/components/form/fields/date-field.css +32 -0
  494. package/src/ui/components/form/fields/field.css +402 -0
  495. package/src/ui/components/form/fields/file-field.css +79 -0
  496. package/src/ui/components/form/fields/password-field.css +50 -0
  497. package/src/ui/components/form/fields/range-field.css +120 -0
  498. package/src/ui/components/form/fields/slider.css +195 -0
  499. package/src/ui/components/form/file-upload-mode/FileAvatarModeRender.js +143 -0
  500. package/src/ui/components/form/file-upload-mode/FileDropzoneModeRender.js +108 -0
  501. package/src/ui/components/form/file-upload-mode/FileNativeModeRender.js +22 -0
  502. package/src/ui/components/form/file-upload-mode/FileUploadButtonModeRender.js +89 -0
  503. package/src/ui/components/form/file-upload-mode/FileWallModeRender.js +90 -0
  504. package/src/ui/components/form/file-upload-mode/file-avatar-mode.css +139 -0
  505. package/src/ui/components/form/file-upload-mode/file-dropzone-mode.css +88 -0
  506. package/src/ui/components/form/file-upload-mode/file-upload-button-mode.css +44 -0
  507. package/src/ui/components/form/file-upload-mode/file-wall-mode.css +88 -0
  508. package/src/ui/components/form/form-control.css +40 -0
  509. package/src/ui/components/form/helpers.js +111 -0
  510. package/src/ui/components/form/index.js +27 -0
  511. package/src/ui/components/icon/material/MaterialIconRender.js +71 -0
  512. package/src/ui/components/icon/material/material.css +15 -0
  513. package/src/ui/components/icon/material/material.map.js +170 -0
  514. package/src/ui/components/icon/phosphor/PhosphorIconRender.js +71 -0
  515. package/src/ui/components/icon/phosphor/phosphor.css +17 -0
  516. package/src/ui/components/icon/phosphor/phosphor.map.js +165 -0
  517. package/src/ui/components/icon/tabler/TablerIconRender.js +58 -0
  518. package/src/ui/components/icon/tabler/tabler.css +14 -0
  519. package/src/ui/components/icon/tabler/tabler.map.js +165 -0
  520. package/src/ui/components/list/ListRender.js +18 -0
  521. package/src/ui/components/list/divider/ListDividerRender.js +10 -0
  522. package/src/ui/components/list/divider/list-divider.css +12 -0
  523. package/src/ui/components/list/group/ListGroupRender.js +61 -0
  524. package/src/ui/components/list/group/list-group.css +62 -0
  525. package/src/ui/components/list/item/ListItemRender.js +242 -0
  526. package/src/ui/components/list/item/list-item.css +191 -0
  527. package/src/ui/components/list/list.css +24 -0
  528. package/src/ui/components/menu/MenuDividerRender.js +12 -0
  529. package/src/ui/components/menu/MenuGroupRender.js +59 -0
  530. package/src/ui/components/menu/MenuItemRender.js +65 -0
  531. package/src/ui/components/menu/MenuLinkRender.js +66 -0
  532. package/src/ui/components/menu/MenuRender.js +27 -0
  533. package/src/ui/components/menu/helpers.js +122 -0
  534. package/src/ui/components/menu/menu.css +308 -0
  535. package/src/ui/components/modal/ModalRender.js +124 -0
  536. package/src/ui/components/modal/modal.css +156 -0
  537. package/src/ui/components/pagination/PaginationRender.js +112 -0
  538. package/src/ui/components/pagination/pagination.css +63 -0
  539. package/src/ui/components/popover/PopoverRender.js +233 -0
  540. package/src/ui/components/popover/popover.css +139 -0
  541. package/src/ui/components/progress/ProgressRender.js +177 -0
  542. package/src/ui/components/progress/progress.css +197 -0
  543. package/src/ui/components/skeleton/SkeletonRender.js +138 -0
  544. package/src/ui/components/skeleton/skeleton.css +154 -0
  545. package/src/ui/components/spacer/SpacerRender.js +10 -0
  546. package/src/ui/components/spinner/SpinnerRender.js +50 -0
  547. package/src/ui/components/spinner/spinner.css +152 -0
  548. package/src/ui/components/splitter/SplitterGutterRender.js +98 -0
  549. package/src/ui/components/splitter/SplitterPanelRender.js +42 -0
  550. package/src/ui/components/splitter/SplitterRender.js +77 -0
  551. package/src/ui/components/splitter/splitter.css +128 -0
  552. package/src/ui/components/stacks/PositionStackRender.js +39 -0
  553. package/src/ui/components/stacks/StackRender.js +41 -0
  554. package/src/ui/components/stacks/absolute-stack/AbsoluteStackRender.js +5 -0
  555. package/src/ui/components/stacks/fixed-stack/FixedStackRender.js +5 -0
  556. package/src/ui/components/stacks/h-stack/HStackRender.js +7 -0
  557. package/src/ui/components/stacks/h-stack/h-stack.css +4 -0
  558. package/src/ui/components/stacks/index.js +5 -0
  559. package/src/ui/components/stacks/position-stack.css +62 -0
  560. package/src/ui/components/stacks/relative-stack/RelativeStackRender.js +7 -0
  561. package/src/ui/components/stacks/relative-stack/relative-stack.css +3 -0
  562. package/src/ui/components/stacks/stack.css +78 -0
  563. package/src/ui/components/stacks/v-stack/VStackRender.js +6 -0
  564. package/src/ui/components/stacks/v-stack/v-stack.css +4 -0
  565. package/src/ui/components/stepper/StepperRender.js +72 -0
  566. package/src/ui/components/stepper/StepperStepRender.js +74 -0
  567. package/src/ui/components/stepper/stepper.css +359 -0
  568. package/src/ui/components/switch/SwitchRender.js +86 -0
  569. package/src/ui/components/switch/switch.css +143 -0
  570. package/src/ui/components/table/data-table/DataTableRender.js +54 -0
  571. package/src/ui/components/table/data-table/bulk-actions.js +34 -0
  572. package/src/ui/components/table/data-table/data-table.css +246 -0
  573. package/src/ui/components/table/data-table/pagination.js +56 -0
  574. package/src/ui/components/table/data-table/tables.js +368 -0
  575. package/src/ui/components/table/data-table/toolbar.js +67 -0
  576. package/src/ui/components/table/simple-table/SimpleTableRender.js +205 -0
  577. package/src/ui/components/table/simple-table/simple-table.css +50 -0
  578. package/src/ui/components/tabs/TabsRender.js +226 -0
  579. package/src/ui/components/tabs/tabs.css +253 -0
  580. package/src/ui/components/toast/ToastRender.js +103 -0
  581. package/src/ui/components/toast/toast.css +201 -0
  582. package/src/ui/components/tooltip/TooltipRender.js +8 -0
  583. package/src/ui/components/tooltip/tooltip.css +113 -0
  584. package/src/ui/index.js +52 -0
  585. package/src/ui/theme.js +0 -0
  586. package/src/ui/theme.scss +1 -0
  587. package/src/ui/tokens/animation.scss +36 -0
  588. package/src/ui/tokens/colors-dark.scss +58 -0
  589. package/src/ui/tokens/colors.scss +54 -0
  590. package/src/ui/tokens/components.scss +32 -0
  591. package/src/ui/tokens/fonts.scss +57 -0
  592. package/src/ui/tokens/glass.scss +10 -0
  593. package/src/ui/tokens/index.scss +38 -0
  594. package/src/ui/tokens/layouts.scss +228 -0
  595. package/src/ui/tokens/opacity.scss +21 -0
  596. package/src/ui/tokens/others.scss +11 -0
  597. package/src/ui/tokens/radius.scss +6 -0
  598. package/src/ui/tokens/reset.scss +51 -0
  599. package/src/ui/tokens/shadows.scss +29 -0
  600. package/src/ui/tokens/spacings.scss +13 -0
  601. package/src/ui/tokens/vars.scss +35 -0
  602. package/src/ui/tokens/viewports.scss +30 -0
  603. package/src/ui/utils/aria.js +19 -0
  604. package/tests/integration/ui/attributes-wrapper.test.js +177 -0
  605. package/tests/integration/ui/for-each-array.test.js +167 -0
  606. package/tests/integration/ui/lifecycle.test.js +146 -0
  607. package/tests/integration/ui/show-if.test.js +168 -0
  608. package/tests/unit/core/observable-array.test.js +404 -0
  609. package/tests/unit/core/observable-item.test.js +428 -0
  610. package/tests/unit/core/observable-object.test.js +239 -0
  611. package/tests/unit/core/observable-resource.test.js +323 -0
  612. package/tests/unit/core/store.test.js +347 -0
  613. package/tests/unit/router/route-matching.test.js +169 -0
  614. package/tests/unit/router/router-guards.test.js +189 -0
  615. package/tests/unit/utils/cache.test.js +120 -0
  616. package/tests/unit/utils/filters.test.js +394 -0
  617. package/types/args-types.d.ts +58 -0
  618. package/types/control-flow.d.ts +62 -0
  619. package/types/elements.d.ts +231 -0
  620. package/types/filters/dates.d.ts +43 -0
  621. package/types/filters/index.d.ts +4 -0
  622. package/types/filters/standard.d.ts +70 -0
  623. package/types/filters/strings.d.ts +21 -0
  624. package/types/filters/types.d.ts +20 -0
  625. package/types/forms.d.ts +84 -0
  626. package/types/globals.d.ts +543 -0
  627. package/types/images.d.ts +23 -0
  628. package/types/localStorage.ts +102 -0
  629. package/types/memoize.d.ts +26 -0
  630. package/types/native-fetch.d.ts +72 -0
  631. package/types/nd-element.d.ts +407 -0
  632. package/types/observable-resource.d.ts +3 -0
  633. package/types/observable.d.ts +227 -0
  634. package/types/plugins-manager.d.ts +65 -0
  635. package/types/polyfill.d.ts +18 -0
  636. package/types/property-accumulator.d.ts +33 -0
  637. package/types/router.d.ts +85 -0
  638. package/types/service.d.ts +23 -0
  639. package/types/singleton.d.ts +19 -0
  640. package/types/store.d.ts +63 -0
  641. package/types/template-cloner.ts +43 -0
  642. package/types/validator.ts +66 -0
  643. package/ui.js +1 -0
  644. package/utils.d.ts +4 -0
  645. package/utils.js +12 -0
  646. package/vitest.config.js +15 -0
  647. package/src/data/Observable.js +0 -55
  648. package/src/data/ObservableChecker.js +0 -39
  649. package/src/data/ObservableItem.js +0 -195
  650. package/src/data/Store.js +0 -74
  651. package/src/data/observable-helpers/array.js +0 -74
  652. package/src/data/observable-helpers/batch.js +0 -22
  653. package/src/data/observable-helpers/computed.js +0 -28
  654. package/src/data/observable-helpers/object.js +0 -111
  655. package/src/elements/anchor.js +0 -129
  656. package/src/elements/content-formatter.js +0 -32
  657. package/src/elements/control/for-each-array.js +0 -280
  658. package/src/elements/control/show-if.js +0 -79
  659. package/src/elements/control/switch.js +0 -98
  660. package/src/elements/description-list.js +0 -5
  661. package/src/elements/form.js +0 -71
  662. package/src/elements/html5-semantics.js +0 -12
  663. package/src/elements/img.js +0 -45
  664. package/src/elements/interactive.js +0 -7
  665. package/src/elements/list.js +0 -10
  666. package/src/elements/medias.js +0 -8
  667. package/src/elements/meta-data.js +0 -9
  668. package/src/elements/table.js +0 -14
  669. package/src/utils/args-types.js +0 -100
  670. package/src/utils/debug-manager.js +0 -31
  671. package/src/utils/helpers.js +0 -60
  672. package/src/utils/plugins-manager.js +0 -12
  673. package/src/utils/prototypes.js +0 -45
  674. package/src/wrappers/AttributesWrapper.js +0 -144
  675. package/src/wrappers/DocumentObserver.js +0 -80
  676. package/src/wrappers/ElementCreator.js +0 -114
  677. package/src/wrappers/HtmlElementEventsWrapper.js +0 -64
  678. package/src/wrappers/HtmlElementWrapper.js +0 -50
  679. package/src/wrappers/NdPrototype.js +0 -106
  680. package/src/wrappers/constants.js +0 -2
@@ -0,0 +1,643 @@
1
+ import DocumentObserver from './DocumentObserver';
2
+ import PluginsManager from '../utils/plugins-manager';
3
+ import NativeDocumentError from '../errors/NativeDocumentError.js';
4
+ import DebugManager from '../utils/debug-manager.js';
5
+ import attributesWrapper, {
6
+ bindAttributeWithObservable,
7
+ bindClassAttribute,
8
+ bindStyleAttribute,
9
+ } from './AttributesWrapper';
10
+
11
+ /**
12
+ * Wraps an HTMLElement with NativeDocument's reactivity and lifecycle API.
13
+ * Created automatically by HtmlElementWrapper — not intended to be instantiated directly.
14
+ *
15
+ * @constructor
16
+ * @param {HTMLElement} element - The underlying HTML element to wrap
17
+ */
18
+ export function NDElement(element) {
19
+ this.$element = element;
20
+ this.$attachements = null;
21
+ if(process.env.NODE_ENV === 'development') {
22
+ PluginsManager.emit('NDElementCreated', element, this);
23
+ }
24
+ }
25
+
26
+
27
+ NDElement.prototype.__$isNDElement = true;
28
+
29
+ NDElement.$getChild = (el) => el;
30
+
31
+ /**
32
+ * Appends a child element to an internal DocumentFragment (ghost DOM),
33
+ * keeping it detached from the main document until explicitly mounted.
34
+ *
35
+ * @param {HTMLElement|DocumentFragment|NDElement} element - Element to append
36
+ * @returns {this}
37
+ */
38
+ NDElement.prototype.ghostDom = function(element) {
39
+ if(!this.$attachements) {
40
+ this.$attachements = document.createDocumentFragment();
41
+ this.toNdElement = () => {
42
+ const fragment = document.createDocumentFragment();
43
+ if(!this.$attachements.contains(this.$element)) {
44
+ fragment.appendChild(this.$element);
45
+ }
46
+ fragment.appendChild(this.$attachements);
47
+ return fragment;
48
+ };
49
+ }
50
+ const child = NDElement.$getChild(element);
51
+ if(child) {
52
+ this.$attachements.appendChild(child);
53
+ }
54
+ return this;
55
+ };
56
+
57
+ /**
58
+ * Returns the underlying HTMLElement. Used internally for type coercion.
59
+ *
60
+ * @returns {HTMLElement}
61
+ */
62
+ NDElement.prototype.valueOf = function() {
63
+ return this.$element;
64
+ };
65
+
66
+ /**
67
+ * Stores the underlying HTMLElement in target[name].
68
+ * Use this to keep a reference to the raw DOM node.
69
+ *
70
+ * @param {Record<string, any>} target - Object to store the reference in
71
+ * @param {string} name - Property name to assign on the target object
72
+ * @returns {this}
73
+ * @example
74
+ * const refs = {};
75
+ * Input({ type: 'text' }).nd.ref(refs, 'emailInput');
76
+ * refs.emailInput.focus();
77
+ */
78
+ NDElement.prototype.ref = function(target, name) {
79
+ target[name] = this.$element;
80
+ return this;
81
+ };
82
+
83
+ /**
84
+ * Stores the NDElement instance itself in target[name].
85
+ * Use this to expose a component's public API to a parent (via .with()).
86
+ *
87
+ * @param {Record<string, any>} target - Object to store the reference in
88
+ * @param {string} name - Property name to assign on the target object
89
+ * @returns {this}
90
+ * @example
91
+ * const refs = {};
92
+ * Counter()
93
+ * .nd.with({ increment() { count.$value++; return this; } })
94
+ * .refSelf(refs, 'counter');
95
+ *
96
+ * refs.counter.increment();
97
+ */
98
+ NDElement.prototype.refSelf = function(target, name) {
99
+ target[name] = this;
100
+ // TODO: @DIM to check
101
+ // target[name] = new NDElement(this.$element);
102
+ return this;
103
+ };
104
+
105
+ /**
106
+ * Calls .nd.remove() on all child NDElements before removing this element.
107
+ * Used to propagate lifecycle cleanup through the component tree.
108
+ *
109
+ * @returns {this}
110
+ */
111
+ NDElement.prototype.unmountChildren = function() {
112
+ let element = this.$element;
113
+ for(let i = 0, length = element.children.length; i < length; i++) {
114
+ let elementChildren = element.children[i];
115
+ if(!elementChildren.$ndProx) {
116
+ elementChildren.nd?.remove();
117
+ }
118
+ elementChildren = null;
119
+ }
120
+ element = null;
121
+ return this;
122
+ };
123
+
124
+ /**
125
+ * Removes the element from the DOM and cleans up its lifecycle observers.
126
+ * Also calls unmountChildren() recursively.
127
+ *
128
+ * @returns {this}
129
+ */
130
+ NDElement.prototype.remove = function() {
131
+ let element = this.$element;
132
+ element.nd.unmountChildren();
133
+ element.$ndProx = null;
134
+
135
+ $lifeCycleObservers.delete(element);
136
+
137
+ element = null;
138
+ return this;
139
+ };
140
+
141
+ const $lifeCycleObservers = new WeakMap();
142
+
143
+ /**
144
+ * Registers mounted and/or unmounted lifecycle callbacks for this element.
145
+ * Uses MutationObserver internally to detect DOM insertion and removal.
146
+ *
147
+ * @param {{ mounted?: (el: HTMLElement) => void, unmounted?: (el: HTMLElement) => boolean|void }} states - Lifecycle hooks
148
+ * @returns {this}
149
+ * @example
150
+ * Div({}).nd.lifecycle({
151
+ * mounted: (el) => console.log('mounted', el),
152
+ * unmounted: (el) => console.log('unmounted', el),
153
+ * });
154
+ */
155
+ NDElement.prototype.lifecycle = function(states) {
156
+ const el = this.$element;
157
+ if (!$lifeCycleObservers.has(el)) {
158
+ $lifeCycleObservers.set(el, DocumentObserver.watch(el));
159
+ }
160
+ const observer = $lifeCycleObservers.get(el);
161
+
162
+ if(states.mounted) {
163
+ this.$element.setAttribute('data--nd-mounted', '1');
164
+ observer.mounted(states.mounted);
165
+ }
166
+ if(states.unmounted) {
167
+ this.$element.setAttribute('data--nd-unmounted', '1');
168
+ observer.unmounted(states.unmounted);
169
+ }
170
+ return this;
171
+ };
172
+
173
+ /**
174
+ * Registers an unmounted callback that cleans up all beforeUnmount handlers
175
+ * and aborts any pending async operations on this element and its children.
176
+ *
177
+ * @returns {this}
178
+ */
179
+ NDElement.prototype.destroyOnUnmount = function() {
180
+ this.unmounted(() => this.destroy());
181
+ return this;
182
+ };
183
+
184
+ /**
185
+ * aborts any pending async operations on this element and its children.
186
+ *
187
+ * @returns {this}
188
+ */
189
+ NDElement.prototype.destroy = function() {
190
+ if(!this.$element) {
191
+ return this;
192
+ }
193
+ const observer = $lifeCycleObservers.get(this.$element);
194
+ if(observer) {
195
+ observer.disconnect();
196
+ }
197
+
198
+ const children = this.$element?.querySelectorAll('[data--nd-before-unmount]') || [];
199
+
200
+ for(let i = 0, length = children.length; i < length; i++) {
201
+ const child = children[i];
202
+ child.remove();
203
+ child.__$controller?.abort();
204
+ child.__$controller = null;
205
+ $lifeCycleObservers.delete(child);
206
+ }
207
+
208
+ const treeWalker = document.createTreeWalker(this.$element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
209
+ console.log(treeWalker);
210
+ while(treeWalker.nextNode()) {
211
+ const node = treeWalker.currentNode;
212
+ node.ndDestroy?.();
213
+ }
214
+
215
+ this.$element.ndDestroy?.();
216
+ this.$element.__$controller?.abort();
217
+ this.$element.__$controller = null;
218
+ $lifeCycleObservers.delete(this.$element);
219
+ this.$element = null;
220
+ };
221
+
222
+ /**
223
+ * Shorthand for lifecycle({ mounted: callback }).
224
+ *
225
+ * @param {(el: HTMLElement) => void} callback - Called when element is inserted into the DOM
226
+ * @returns {this}
227
+ */
228
+ NDElement.prototype.mounted = function(callback) {
229
+ return this.lifecycle({ mounted: callback });
230
+ };
231
+
232
+ /**
233
+ * Shorthand for lifecycle({ unmounted: callback }).
234
+ *
235
+ * @param {(el: HTMLElement) => boolean|void} callback - Called when element is removed from the DOM
236
+ * @returns {this}
237
+ */
238
+ NDElement.prototype.unmounted = function(callback) {
239
+ return this.lifecycle({ unmounted: callback });
240
+ };
241
+
242
+ /**
243
+ * Registers an async callback to run before this element is removed from the DOM.
244
+ * The element's .remove() is delayed until all beforeUnmount callbacks resolve.
245
+ *
246
+ * @param {string} id - Unique identifier for this callback (allows overwriting)
247
+ * @param {(this: NDElement, el: HTMLElement) => void|Promise<void>} callback - Async-compatible callback
248
+ * @returns {this}
249
+ * @example
250
+ * Div({}).nd.beforeUnmount('fade-out', async (el) => {
251
+ * await el.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 300 }).finished;
252
+ * });
253
+ */
254
+ NDElement.prototype.beforeUnmount = function(id, callback) {
255
+ const el = this.$element;
256
+
257
+ if(!DocumentObserver.beforeUnmount.has(el)) {
258
+ DocumentObserver.beforeUnmount.set(el, new Map());
259
+ const originalRemove = el.remove.bind(el);
260
+
261
+ let $isUnmounting = false;
262
+ this.$element.setAttribute('data--nd-before-unmount', '1');
263
+
264
+ el.remove = async () => {
265
+ if($isUnmounting) {
266
+ return;
267
+ }
268
+ $isUnmounting = true;
269
+
270
+ try {
271
+ const callbacks = DocumentObserver.beforeUnmount.get(el);
272
+ for (const cb of callbacks.values()) {
273
+ await cb.call(this, el);
274
+ }
275
+ } finally {
276
+ originalRemove();
277
+ $isUnmounting = false;
278
+ }
279
+ };
280
+ }
281
+
282
+ DocumentObserver.beforeUnmount.get(el).set(id, callback);
283
+ return this;
284
+ };
285
+
286
+ /**
287
+ * Returns the underlying HTMLElement.
288
+ * Alias: .node()
289
+ *
290
+ * @returns {HTMLElement}
291
+ */
292
+ NDElement.prototype.htmlElement = function() {
293
+ return this.$element;
294
+ };
295
+
296
+ NDElement.prototype.node = NDElement.prototype.htmlElement;
297
+
298
+ /**
299
+ * Attaches a Shadow DOM to this element, redirecting all child appends to the shadow root.
300
+ *
301
+ * @param {'open'|'closed'} mode - Shadow DOM encapsulation mode
302
+ * @param {string|null} [style=null] - Optional CSS string to inject into the shadow root
303
+ * @returns {this}
304
+ */
305
+ NDElement.prototype.shadow = function(mode, style = null) {
306
+ const $element = this.$element;
307
+ const children = Array.from($element.childNodes);
308
+ const shadowRoot = $element.attachShadow({ mode });
309
+ if(style) {
310
+ const styleNode = document.createElement('style');
311
+ styleNode.textContent = style;
312
+ shadowRoot.appendChild(styleNode);
313
+ }
314
+ $element.append = shadowRoot.append.bind(shadowRoot);
315
+ $element.appendChild = shadowRoot.appendChild.bind(shadowRoot);
316
+ shadowRoot.append(...children);
317
+
318
+ return this;
319
+ };
320
+
321
+ /**
322
+ * Shorthand for .shadow('open', style).
323
+ *
324
+ * @param {string|null} [style=null] - Optional CSS string to inject into the shadow root
325
+ * @returns {this}
326
+ */
327
+ NDElement.prototype.openShadow = function(style = null) {
328
+ return this.shadow('open', style);
329
+ };
330
+
331
+ /**
332
+ * Shorthand for .shadow('closed', style).
333
+ *
334
+ * @param {string|null} [style=null] - Optional CSS string to inject into the shadow root
335
+ * @returns {this}
336
+ */
337
+ NDElement.prototype.closedShadow = function(style = null) {
338
+ return this.shadow('closed', style);
339
+ };
340
+
341
+ /**
342
+ * Extends the current NDElement instance with custom methods.
343
+ * Methods are bound to the instance and available for chaining.
344
+ *
345
+ * @param {Object} methods - Object containing method definitions
346
+ * @returns {this} The NDElement instance with added methods for chaining
347
+ * @example
348
+ * element.nd.with({
349
+ * highlight() {
350
+ * this.$element.style.background = 'yellow';
351
+ * return this;
352
+ * }
353
+ * }).highlight().onClick(() => console.log('Clicked'));
354
+ */
355
+ NDElement.prototype.with = function(methods) {
356
+ if (!methods || typeof methods !== 'object') {
357
+ throw new NativeDocumentError('extend() requires an object of methods');
358
+ }
359
+ if(process.env.NODE_ENV === 'development') {
360
+ if (!this.$localExtensions) {
361
+ this.$localExtensions = new Map();
362
+ }
363
+ }
364
+
365
+ for (const name in methods) {
366
+ const method = methods[name];
367
+
368
+ if (typeof method !== 'function') {
369
+ DebugManager.warn(`⚠️ extends(): "${name}" is not a function, skipping`);
370
+ continue;
371
+ }
372
+ if(process.env.NODE_ENV === 'development') {
373
+ if (this[name] && !this.$localExtensions.has(name)) {
374
+ DebugManager.warn('NDElement.extend', `Method "${name}" already exists and will be overwritten`);
375
+ }
376
+ this.$localExtensions.set(name, method);
377
+ }
378
+
379
+ this[name] = method.bind(this);
380
+ }
381
+
382
+ return this;
383
+ };
384
+
385
+ /**
386
+ * Sets a single attribute on the element.
387
+ * If value is an ObservableItem, the attribute is updated reactively.
388
+ *
389
+ * @param {string} name - Attribute name
390
+ * @param {string|ObservableItem<string>} value - Attribute value, static or reactive
391
+ * @returns {this}
392
+ * @example
393
+ * Input({}).nd.attr('placeholder', label); // reactive placeholder
394
+ */
395
+ NDElement.prototype.attr = function(name, value) {
396
+ if(value?.__$Observable) {
397
+ bindAttributeWithObservable(this.$element, name, value);
398
+ return this;
399
+ }
400
+ this.$element.setAttribute(name, value);
401
+ return this;
402
+ };
403
+
404
+ /**
405
+ * Applies a batch of attributes to the element via AttributesWrapper.
406
+ * Supports reactive values, class maps, and style maps.
407
+ *
408
+ * @param {Object} attrs - Attributes object (same format as HtmlElementWrapper props)
409
+ * @returns {this}
410
+ */
411
+ NDElement.prototype.attrs = function(attrs) {
412
+ attributesWrapper(this.$element, attrs);
413
+ return this;
414
+ };
415
+
416
+ /**
417
+ * Applies a reactive class map to the element.
418
+ * Each key is a class name; each value is a boolean or ObservableItem<boolean>.
419
+ *
420
+ * @param {Record<string, boolean|ObservableItem<boolean>>} classes - Class map
421
+ * @returns {this}
422
+ */
423
+ NDElement.prototype.class = function(classes) {
424
+ bindClassAttribute(this.$element, classes);
425
+ return this;
426
+ };
427
+
428
+ /**
429
+ * Applies a reactive style map to the element.
430
+ * Each key is a CSS property; each value is a string or ObservableItem<string>.
431
+ *
432
+ * @param {Record<string, string|ObservableItem<string>>} style - Style map
433
+ * @returns {this}
434
+ */
435
+ NDElement.prototype.style = function(style) {
436
+ bindStyleAttribute(this.$element, style);
437
+ return this;
438
+ };
439
+
440
+
441
+ /**
442
+ * Extends the NDElement prototype with new methods available to all NDElement instances.
443
+ * Use this to add global methods to all NDElements.
444
+ *
445
+ * @param {Object} methods - Object containing method definitions to add to prototype
446
+ * @returns {typeof NDElement} The NDElement constructor
447
+ * @throws {NativeDocumentError} If methods is not an object or contains non-function values
448
+ * @example
449
+ * NDElement.extend({
450
+ * fadeIn() {
451
+ * this.$element.style.opacity = '1';
452
+ * return this;
453
+ * }
454
+ * });
455
+ * // Now all NDElements have .fadeIn() method
456
+ * Div().nd.fadeIn();
457
+ */
458
+ NDElement.extend = function(methods) {
459
+ if (!methods || typeof methods !== 'object') {
460
+ throw new NativeDocumentError('NDElement.extend() requires an object of methods');
461
+ }
462
+
463
+ if (Array.isArray(methods)) {
464
+ throw new NativeDocumentError('NDElement.extend() requires an object, not an array');
465
+ }
466
+
467
+ const protectedMethods = new Set([
468
+ 'constructor', 'valueOf', '$element', '$observer',
469
+ 'ref', 'remove', 'cleanup', 'with', 'extend', 'attach',
470
+ 'lifecycle', 'mounted', 'unmounted', 'unmountChildren',
471
+ ]);
472
+
473
+ for (const name in methods) {
474
+ if (!Object.hasOwn(methods, name)) {
475
+ continue;
476
+ }
477
+
478
+ const method = methods[name];
479
+
480
+ if (typeof method !== 'function') {
481
+ DebugManager.warn('NDElement.extend', `"${name}" is not a function, skipping`);
482
+ continue;
483
+ }
484
+
485
+ if (protectedMethods.has(name)) {
486
+ DebugManager.error('NDElement.extend', `Cannot override protected method "${name}"`);
487
+ throw new NativeDocumentError(`Cannot override protected method "${name}"`);
488
+ }
489
+
490
+ if (NDElement.prototype[name]) {
491
+ DebugManager.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
492
+ }
493
+
494
+ NDElement.prototype[name] = method;
495
+ }
496
+ if(process.env.NODE_ENV === 'development') {
497
+ PluginsManager.emit('NDElementExtended', methods);
498
+ }
499
+
500
+ return NDElement;
501
+ };
502
+
503
+
504
+ /**
505
+ * The global sanitizer function used by nd.html() when sanitize option is enabled.
506
+ * Must be set via NDElement.setSanitizer() before using {sanitize: true}.
507
+ *
508
+ * @type {Function|null}
509
+ */
510
+ NDElement.$sanitizer = null;
511
+
512
+ /**
513
+ * Configures the global sanitizer for nd.html().
514
+ * The sanitizer function receives the HTML string and an optional config object.
515
+ * Designed to be decoupled from any specific sanitizer library.
516
+ *
517
+ * @param {Function} sanitizerFn - Sanitizer function (html, config) => string
518
+ * @returns {typeof NDElement}
519
+ * @throws {NativeDocumentError} If sanitizerFn is not a function
520
+ * @example
521
+ * import DOMPurify from 'dompurify';
522
+ * NDElement.setSanitizer((html, config) => DOMPurify.sanitize(html, config));
523
+ */
524
+ NDElement.setSanitizer = function(sanitizerFn) {
525
+ if(typeof sanitizerFn !== 'function') {
526
+ throw new NativeDocumentError('NDElement.setSanitizer() expects a function');
527
+ }
528
+ NDElement.$sanitizer = sanitizerFn;
529
+ return NDElement;
530
+ };
531
+
532
+ /**
533
+ * Sets the inner HTML of the element.
534
+ * Requires either {unsafe: true} to bypass security checks,
535
+ * or {sanitize: true|Object|Function} to sanitize the content.
536
+ * Supports Observable values for reactive HTML updates.
537
+ *
538
+ * @param {string|ObservableItem} content - HTML string or Observable<string>
539
+ * @param {Object} [options={}]
540
+ * @param {boolean} [options.unsafe=false] - Bypass security check. Use only with trusted content.
541
+ * @param {boolean|Object|Function} [options.sanitize=false] - Sanitize strategy:
542
+ * - true: use global sanitizer with default config
543
+ * - Object: use global sanitizer with custom config
544
+ * - Function: use this function directly as sanitizer (html) => string
545
+ * @returns {this}
546
+ * @throws {NativeDocumentError} If sanitize is true/Object but no global sanitizer is configured
547
+ * @example
548
+ * // Unsafe — trusted content only
549
+ * el.nd.html('<strong>Hello</strong>', {unsafe: true})
550
+ *
551
+ * // Global sanitizer with default config
552
+ * el.nd.html($userContent, {sanitize: true})
553
+ *
554
+ * // Global sanitizer with custom config
555
+ * el.nd.html($userContent, {sanitize: {
556
+ * ALLOWED_TAGS: ['b', 'i', 'strong', 'a'],
557
+ * ALLOWED_ATTR: ['href'],
558
+ * }})
559
+ *
560
+ * // Custom sanitizer function for this specific case
561
+ * el.nd.html($userContent, {sanitize: (html) => myCustomSanitizer(html)})
562
+ *
563
+ * // Reactive with sanitize
564
+ * el.nd.html($content, {sanitize: true})
565
+ */
566
+ NDElement.prototype.html = function(content, {unsafe = false, sanitize = false} = {}) {
567
+ const $element = this.$element;
568
+ const apply = (value) => {
569
+ if(sanitize) {
570
+ if(typeof sanitize === 'function') {
571
+ $element.innerHTML = sanitize(value);
572
+ return;
573
+ }
574
+
575
+ if(!NDElement.$sanitizer) {
576
+ throw new NativeDocumentError('nd.html() — no sanitizer configured. Call NDElement.setSanitizer() first.');
577
+ }
578
+ const config = sanitize === true ? {} : sanitize;
579
+ $element.innerHTML = NDElement.$sanitizer(value, config);
580
+ return;
581
+ }
582
+
583
+ if(!unsafe) {
584
+ console.warn('nd.html() — use {unsafe: true} or {sanitize: true|Object|Function}');
585
+ return;
586
+ }
587
+
588
+ $element.innerHTML = value;
589
+ };
590
+
591
+ if(content?.__$Observable) {
592
+ content.subscribe(apply);
593
+ apply(content.val());
594
+ return this;
595
+ }
596
+
597
+ apply(content);
598
+ return this;
599
+ };
600
+
601
+ /**
602
+ * Makes the element content editable and binds it to an Observable.
603
+ * Changes in the DOM update the Observable, and changes to the Observable
604
+ * update the DOM (only when the element is not focused to avoid cursor issues).
605
+ *
606
+ * @param {ObservableItem} $obs - Observable to bind to the element content
607
+ * @param {Object} [options={}]
608
+ * @param {string} [options.format='html'] - 'html' uses innerHTML, 'text' uses innerText
609
+ * @returns {this}
610
+ * @example
611
+ * // Basic usage
612
+ * const $content = $('<b>Hello</b>');
613
+ * Div({}).nd.contentEditable($content)
614
+ *
615
+ * // Text only
616
+ * Div({}).nd.contentEditable($content, {format: 'text'})
617
+ */
618
+ NDElement.prototype.contentEditable = function($obs, {format = 'html'} = {}) {
619
+ this.$element.contentEditable = true;
620
+
621
+ const getValue = format === 'text'
622
+ ? () => this.$element.innerText
623
+ : () => this.$element.innerHTML;
624
+
625
+ const setValue = format === 'text'
626
+ ? (value) => { this.$element.innerText = value; }
627
+ : (value) => { this.$element.innerHTML = value; };
628
+
629
+ if($obs?.__$Observable) {
630
+ $obs.subscribe((value) => {
631
+ if(document.activeElement !== this.$element) {
632
+ setValue(value);
633
+ }
634
+ });
635
+ setValue($obs.val() || '');
636
+ }
637
+
638
+ this.$element.addEventListener('input', () => {
639
+ $obs?.set(getValue());
640
+ }, { signal: this.$getSignal() });
641
+
642
+ return this;
643
+ };