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,613 @@
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
+ }
42
+ this.$attachements.appendChild(NDElement.$getChild(element));
43
+ return this;
44
+ };
45
+
46
+ /**
47
+ * Returns the underlying HTMLElement. Used internally for type coercion.
48
+ *
49
+ * @returns {HTMLElement}
50
+ */
51
+ NDElement.prototype.valueOf = function() {
52
+ return this.$element;
53
+ };
54
+
55
+ /**
56
+ * Stores the underlying HTMLElement in target[name].
57
+ * Use this to keep a reference to the raw DOM node.
58
+ *
59
+ * @param {Record<string, any>} target - Object to store the reference in
60
+ * @param {string} name - Property name to assign on the target object
61
+ * @returns {this}
62
+ * @example
63
+ * const refs = {};
64
+ * Input({ type: 'text' }).nd.ref(refs, 'emailInput');
65
+ * refs.emailInput.focus();
66
+ */
67
+ NDElement.prototype.ref = function(target, name) {
68
+ target[name] = this.$element;
69
+ return this;
70
+ };
71
+
72
+ /**
73
+ * Stores the NDElement instance itself in target[name].
74
+ * Use this to expose a component's public API to a parent (via .with()).
75
+ *
76
+ * @param {Record<string, any>} target - Object to store the reference in
77
+ * @param {string} name - Property name to assign on the target object
78
+ * @returns {this}
79
+ * @example
80
+ * const refs = {};
81
+ * Counter()
82
+ * .nd.with({ increment() { count.$value++; return this; } })
83
+ * .refSelf(refs, 'counter');
84
+ *
85
+ * refs.counter.increment();
86
+ */
87
+ NDElement.prototype.refSelf = function(target, name) {
88
+ target[name] = this;
89
+ // TODO: @DIM to check
90
+ // target[name] = new NDElement(this.$element);
91
+ return this;
92
+ };
93
+
94
+ /**
95
+ * Calls .nd.remove() on all child NDElements before removing this element.
96
+ * Used to propagate lifecycle cleanup through the component tree.
97
+ *
98
+ * @returns {this}
99
+ */
100
+ NDElement.prototype.unmountChildren = function() {
101
+ let element = this.$element;
102
+ for(let i = 0, length = element.children.length; i < length; i++) {
103
+ let elementChildren = element.children[i];
104
+ if(!elementChildren.$ndProx) {
105
+ elementChildren.nd?.remove();
106
+ }
107
+ elementChildren = null;
108
+ }
109
+ element = null;
110
+ return this;
111
+ };
112
+
113
+ /**
114
+ * Removes the element from the DOM and cleans up its lifecycle observers.
115
+ * Also calls unmountChildren() recursively.
116
+ *
117
+ * @returns {this}
118
+ */
119
+ NDElement.prototype.remove = function() {
120
+ let element = this.$element;
121
+ element.nd.unmountChildren();
122
+ element.$ndProx = null;
123
+
124
+ $lifeCycleObservers.delete(element);
125
+
126
+ element = null;
127
+ return this;
128
+ };
129
+
130
+ const $lifeCycleObservers = new WeakMap();
131
+
132
+ /**
133
+ * Registers mounted and/or unmounted lifecycle callbacks for this element.
134
+ * Uses MutationObserver internally to detect DOM insertion and removal.
135
+ *
136
+ * @param {{ mounted?: (el: HTMLElement) => void, unmounted?: (el: HTMLElement) => boolean|void }} states - Lifecycle hooks
137
+ * @returns {this}
138
+ * @example
139
+ * Div({}).nd.lifecycle({
140
+ * mounted: (el) => console.log('mounted', el),
141
+ * unmounted: (el) => console.log('unmounted', el),
142
+ * });
143
+ */
144
+ NDElement.prototype.lifecycle = function(states) {
145
+ const el = this.$element;
146
+ if (!$lifeCycleObservers.has(el)) {
147
+ $lifeCycleObservers.set(el, DocumentObserver.watch(el));
148
+ }
149
+ const observer = $lifeCycleObservers.get(el);
150
+
151
+ if(states.mounted) {
152
+ this.$element.setAttribute('data--nd-mounted', '1');
153
+ observer.mounted(states.mounted);
154
+ }
155
+ if(states.unmounted) {
156
+ this.$element.setAttribute('data--nd-unmounted', '1');
157
+ observer.unmounted(states.unmounted);
158
+ }
159
+ return this;
160
+ };
161
+
162
+ /**
163
+ * Registers an unmounted callback that cleans up all beforeUnmount handlers
164
+ * and aborts any pending async operations on this element and its children.
165
+ *
166
+ * @returns {this}
167
+ */
168
+ NDElement.prototype.destroyOnUnmount = function() {
169
+ this.unmounted(() => this.destroy());
170
+ return this;
171
+ };
172
+
173
+ /**
174
+ * aborts any pending async operations on this element and its children.
175
+ *
176
+ * @returns {this}
177
+ */
178
+ NDElement.prototype.destroy = function() {
179
+ this.$element?.querySelectorAll('[data--nd-before-unmount]').forEach(child => {
180
+ child.remove();
181
+ child.__$controller?.abort();
182
+ child.__$controller = null;
183
+ $lifeCycleObservers.delete(child);
184
+ });
185
+
186
+ this.$element.__$controller?.abort();
187
+ this.$element.__$controller = null;
188
+ $lifeCycleObservers.delete(this.$element);
189
+ this.$element = null;
190
+ };
191
+
192
+ /**
193
+ * Shorthand for lifecycle({ mounted: callback }).
194
+ *
195
+ * @param {(el: HTMLElement) => void} callback - Called when element is inserted into the DOM
196
+ * @returns {this}
197
+ */
198
+ NDElement.prototype.mounted = function(callback) {
199
+ return this.lifecycle({ mounted: callback });
200
+ };
201
+
202
+ /**
203
+ * Shorthand for lifecycle({ unmounted: callback }).
204
+ *
205
+ * @param {(el: HTMLElement) => boolean|void} callback - Called when element is removed from the DOM
206
+ * @returns {this}
207
+ */
208
+ NDElement.prototype.unmounted = function(callback) {
209
+ return this.lifecycle({ unmounted: callback });
210
+ };
211
+
212
+ /**
213
+ * Registers an async callback to run before this element is removed from the DOM.
214
+ * The element's .remove() is delayed until all beforeUnmount callbacks resolve.
215
+ *
216
+ * @param {string} id - Unique identifier for this callback (allows overwriting)
217
+ * @param {(this: NDElement, el: HTMLElement) => void|Promise<void>} callback - Async-compatible callback
218
+ * @returns {this}
219
+ * @example
220
+ * Div({}).nd.beforeUnmount('fade-out', async (el) => {
221
+ * await el.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 300 }).finished;
222
+ * });
223
+ */
224
+ NDElement.prototype.beforeUnmount = function(id, callback) {
225
+ const el = this.$element;
226
+
227
+ if(!DocumentObserver.beforeUnmount.has(el)) {
228
+ DocumentObserver.beforeUnmount.set(el, new Map());
229
+ const originalRemove = el.remove.bind(el);
230
+
231
+ let $isUnmounting = false;
232
+ this.$element.setAttribute('data--nd-before-unmount', '1');
233
+
234
+ el.remove = async () => {
235
+ if($isUnmounting) {
236
+ return;
237
+ }
238
+ $isUnmounting = true;
239
+
240
+ try {
241
+ const callbacks = DocumentObserver.beforeUnmount.get(el);
242
+ for (const cb of callbacks.values()) {
243
+ await cb.call(this, el);
244
+ }
245
+ } finally {
246
+ originalRemove();
247
+ $isUnmounting = false;
248
+ }
249
+ };
250
+ }
251
+
252
+ DocumentObserver.beforeUnmount.get(el).set(id, callback);
253
+ return this;
254
+ };
255
+
256
+ /**
257
+ * Returns the underlying HTMLElement.
258
+ * Alias: .node()
259
+ *
260
+ * @returns {HTMLElement}
261
+ */
262
+ NDElement.prototype.htmlElement = function() {
263
+ return this.$element;
264
+ };
265
+
266
+ NDElement.prototype.node = NDElement.prototype.htmlElement;
267
+
268
+ /**
269
+ * Attaches a Shadow DOM to this element, redirecting all child appends to the shadow root.
270
+ *
271
+ * @param {'open'|'closed'} mode - Shadow DOM encapsulation mode
272
+ * @param {string|null} [style=null] - Optional CSS string to inject into the shadow root
273
+ * @returns {this}
274
+ */
275
+ NDElement.prototype.shadow = function(mode, style = null) {
276
+ const $element = this.$element;
277
+ const children = Array.from($element.childNodes);
278
+ const shadowRoot = $element.attachShadow({ mode });
279
+ if(style) {
280
+ const styleNode = document.createElement('style');
281
+ styleNode.textContent = style;
282
+ shadowRoot.appendChild(styleNode);
283
+ }
284
+ $element.append = shadowRoot.append.bind(shadowRoot);
285
+ $element.appendChild = shadowRoot.appendChild.bind(shadowRoot);
286
+ shadowRoot.append(...children);
287
+
288
+ return this;
289
+ };
290
+
291
+ /**
292
+ * Shorthand for .shadow('open', style).
293
+ *
294
+ * @param {string|null} [style=null] - Optional CSS string to inject into the shadow root
295
+ * @returns {this}
296
+ */
297
+ NDElement.prototype.openShadow = function(style = null) {
298
+ return this.shadow('open', style);
299
+ };
300
+
301
+ /**
302
+ * Shorthand for .shadow('closed', style).
303
+ *
304
+ * @param {string|null} [style=null] - Optional CSS string to inject into the shadow root
305
+ * @returns {this}
306
+ */
307
+ NDElement.prototype.closedShadow = function(style = null) {
308
+ return this.shadow('closed', style);
309
+ };
310
+
311
+ /**
312
+ * Extends the current NDElement instance with custom methods.
313
+ * Methods are bound to the instance and available for chaining.
314
+ *
315
+ * @param {Object} methods - Object containing method definitions
316
+ * @returns {this} The NDElement instance with added methods for chaining
317
+ * @example
318
+ * element.nd.with({
319
+ * highlight() {
320
+ * this.$element.style.background = 'yellow';
321
+ * return this;
322
+ * }
323
+ * }).highlight().onClick(() => console.log('Clicked'));
324
+ */
325
+ NDElement.prototype.with = function(methods) {
326
+ if (!methods || typeof methods !== 'object') {
327
+ throw new NativeDocumentError('extend() requires an object of methods');
328
+ }
329
+ if(process.env.NODE_ENV === 'development') {
330
+ if (!this.$localExtensions) {
331
+ this.$localExtensions = new Map();
332
+ }
333
+ }
334
+
335
+ for (const name in methods) {
336
+ const method = methods[name];
337
+
338
+ if (typeof method !== 'function') {
339
+ DebugManager.warn(`⚠️ extends(): "${name}" is not a function, skipping`);
340
+ continue;
341
+ }
342
+ if(process.env.NODE_ENV === 'development') {
343
+ if (this[name] && !this.$localExtensions.has(name)) {
344
+ DebugManager.warn('NDElement.extend', `Method "${name}" already exists and will be overwritten`);
345
+ }
346
+ this.$localExtensions.set(name, method);
347
+ }
348
+
349
+ this[name] = method.bind(this);
350
+ }
351
+
352
+ return this;
353
+ };
354
+
355
+ /**
356
+ * Sets a single attribute on the element.
357
+ * If value is an ObservableItem, the attribute is updated reactively.
358
+ *
359
+ * @param {string} name - Attribute name
360
+ * @param {string|ObservableItem<string>} value - Attribute value, static or reactive
361
+ * @returns {this}
362
+ * @example
363
+ * Input({}).nd.attr('placeholder', label); // reactive placeholder
364
+ */
365
+ NDElement.prototype.attr = function(name, value) {
366
+ if(value?.__$Observable) {
367
+ bindAttributeWithObservable(this.$element, name, value);
368
+ return this;
369
+ }
370
+ this.$element.setAttribute(name, value);
371
+ return this;
372
+ };
373
+
374
+ /**
375
+ * Applies a batch of attributes to the element via AttributesWrapper.
376
+ * Supports reactive values, class maps, and style maps.
377
+ *
378
+ * @param {Object} attrs - Attributes object (same format as HtmlElementWrapper props)
379
+ * @returns {this}
380
+ */
381
+ NDElement.prototype.attrs = function(attrs) {
382
+ attributesWrapper(this.$element, attrs);
383
+ return this;
384
+ };
385
+
386
+ /**
387
+ * Applies a reactive class map to the element.
388
+ * Each key is a class name; each value is a boolean or ObservableItem<boolean>.
389
+ *
390
+ * @param {Record<string, boolean|ObservableItem<boolean>>} classes - Class map
391
+ * @returns {this}
392
+ */
393
+ NDElement.prototype.class = function(classes) {
394
+ bindClassAttribute(this.$element, classes);
395
+ return this;
396
+ };
397
+
398
+ /**
399
+ * Applies a reactive style map to the element.
400
+ * Each key is a CSS property; each value is a string or ObservableItem<string>.
401
+ *
402
+ * @param {Record<string, string|ObservableItem<string>>} style - Style map
403
+ * @returns {this}
404
+ */
405
+ NDElement.prototype.style = function(style) {
406
+ bindStyleAttribute(this.$element, style);
407
+ return this;
408
+ };
409
+
410
+
411
+ /**
412
+ * Extends the NDElement prototype with new methods available to all NDElement instances.
413
+ * Use this to add global methods to all NDElements.
414
+ *
415
+ * @param {Object} methods - Object containing method definitions to add to prototype
416
+ * @returns {typeof NDElement} The NDElement constructor
417
+ * @throws {NativeDocumentError} If methods is not an object or contains non-function values
418
+ * @example
419
+ * NDElement.extend({
420
+ * fadeIn() {
421
+ * this.$element.style.opacity = '1';
422
+ * return this;
423
+ * }
424
+ * });
425
+ * // Now all NDElements have .fadeIn() method
426
+ * Div().nd.fadeIn();
427
+ */
428
+ NDElement.extend = function(methods) {
429
+ if (!methods || typeof methods !== 'object') {
430
+ throw new NativeDocumentError('NDElement.extend() requires an object of methods');
431
+ }
432
+
433
+ if (Array.isArray(methods)) {
434
+ throw new NativeDocumentError('NDElement.extend() requires an object, not an array');
435
+ }
436
+
437
+ const protectedMethods = new Set([
438
+ 'constructor', 'valueOf', '$element', '$observer',
439
+ 'ref', 'remove', 'cleanup', 'with', 'extend', 'attach',
440
+ 'lifecycle', 'mounted', 'unmounted', 'unmountChildren',
441
+ ]);
442
+
443
+ for (const name in methods) {
444
+ if (!Object.hasOwn(methods, name)) {
445
+ continue;
446
+ }
447
+
448
+ const method = methods[name];
449
+
450
+ if (typeof method !== 'function') {
451
+ DebugManager.warn('NDElement.extend', `"${name}" is not a function, skipping`);
452
+ continue;
453
+ }
454
+
455
+ if (protectedMethods.has(name)) {
456
+ DebugManager.error('NDElement.extend', `Cannot override protected method "${name}"`);
457
+ throw new NativeDocumentError(`Cannot override protected method "${name}"`);
458
+ }
459
+
460
+ if (NDElement.prototype[name]) {
461
+ DebugManager.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
462
+ }
463
+
464
+ NDElement.prototype[name] = method;
465
+ }
466
+ if(process.env.NODE_ENV === 'development') {
467
+ PluginsManager.emit('NDElementExtended', methods);
468
+ }
469
+
470
+ return NDElement;
471
+ };
472
+
473
+
474
+ /**
475
+ * The global sanitizer function used by nd.html() when sanitize option is enabled.
476
+ * Must be set via NDElement.setSanitizer() before using {sanitize: true}.
477
+ *
478
+ * @type {Function|null}
479
+ */
480
+ NDElement.$sanitizer = null;
481
+
482
+ /**
483
+ * Configures the global sanitizer for nd.html().
484
+ * The sanitizer function receives the HTML string and an optional config object.
485
+ * Designed to be decoupled from any specific sanitizer library.
486
+ *
487
+ * @param {Function} sanitizerFn - Sanitizer function (html, config) => string
488
+ * @returns {typeof NDElement}
489
+ * @throws {NativeDocumentError} If sanitizerFn is not a function
490
+ * @example
491
+ * import DOMPurify from 'dompurify';
492
+ * NDElement.setSanitizer((html, config) => DOMPurify.sanitize(html, config));
493
+ */
494
+ NDElement.setSanitizer = function(sanitizerFn) {
495
+ if(typeof sanitizerFn !== 'function') {
496
+ throw new NativeDocumentError('NDElement.setSanitizer() expects a function');
497
+ }
498
+ NDElement.$sanitizer = sanitizerFn;
499
+ return NDElement;
500
+ };
501
+
502
+ /**
503
+ * Sets the inner HTML of the element.
504
+ * Requires either {unsafe: true} to bypass security checks,
505
+ * or {sanitize: true|Object|Function} to sanitize the content.
506
+ * Supports Observable values for reactive HTML updates.
507
+ *
508
+ * @param {string|ObservableItem} content - HTML string or Observable<string>
509
+ * @param {Object} [options={}]
510
+ * @param {boolean} [options.unsafe=false] - Bypass security check. Use only with trusted content.
511
+ * @param {boolean|Object|Function} [options.sanitize=false] - Sanitize strategy:
512
+ * - true: use global sanitizer with default config
513
+ * - Object: use global sanitizer with custom config
514
+ * - Function: use this function directly as sanitizer (html) => string
515
+ * @returns {this}
516
+ * @throws {NativeDocumentError} If sanitize is true/Object but no global sanitizer is configured
517
+ * @example
518
+ * // Unsafe — trusted content only
519
+ * el.nd.html('<strong>Hello</strong>', {unsafe: true})
520
+ *
521
+ * // Global sanitizer with default config
522
+ * el.nd.html($userContent, {sanitize: true})
523
+ *
524
+ * // Global sanitizer with custom config
525
+ * el.nd.html($userContent, {sanitize: {
526
+ * ALLOWED_TAGS: ['b', 'i', 'strong', 'a'],
527
+ * ALLOWED_ATTR: ['href'],
528
+ * }})
529
+ *
530
+ * // Custom sanitizer function for this specific case
531
+ * el.nd.html($userContent, {sanitize: (html) => myCustomSanitizer(html)})
532
+ *
533
+ * // Reactive with sanitize
534
+ * el.nd.html($content, {sanitize: true})
535
+ */
536
+ NDElement.prototype.html = function(content, {unsafe = false, sanitize = false} = {}) {
537
+ const $element = this.$element;
538
+ const apply = (value) => {
539
+ if(sanitize) {
540
+ if(typeof sanitize === 'function') {
541
+ $element.innerHTML = sanitize(value);
542
+ return;
543
+ }
544
+
545
+ if(!NDElement.$sanitizer) {
546
+ throw new NativeDocumentError('nd.html() — no sanitizer configured. Call NDElement.setSanitizer() first.');
547
+ }
548
+ const config = sanitize === true ? {} : sanitize;
549
+ $element.innerHTML = NDElement.$sanitizer(value, config);
550
+ return;
551
+ }
552
+
553
+ if(!unsafe) {
554
+ console.warn('nd.html() — use {unsafe: true} or {sanitize: true|Object|Function}');
555
+ return;
556
+ }
557
+
558
+ $element.innerHTML = value;
559
+ };
560
+
561
+ if(content?.__$Observable) {
562
+ content.subscribe(apply);
563
+ apply(content.val());
564
+ return this;
565
+ }
566
+
567
+ apply(content);
568
+ return this;
569
+ };
570
+
571
+ /**
572
+ * Makes the element content editable and binds it to an Observable.
573
+ * Changes in the DOM update the Observable, and changes to the Observable
574
+ * update the DOM (only when the element is not focused to avoid cursor issues).
575
+ *
576
+ * @param {ObservableItem} $obs - Observable to bind to the element content
577
+ * @param {Object} [options={}]
578
+ * @param {string} [options.format='html'] - 'html' uses innerHTML, 'text' uses innerText
579
+ * @returns {this}
580
+ * @example
581
+ * // Basic usage
582
+ * const $content = $('<b>Hello</b>');
583
+ * Div({}).nd.contentEditable($content)
584
+ *
585
+ * // Text only
586
+ * Div({}).nd.contentEditable($content, {format: 'text'})
587
+ */
588
+ NDElement.prototype.contentEditable = function($obs, {format = 'html'} = {}) {
589
+ this.$element.contentEditable = true;
590
+
591
+ const getValue = format === 'text'
592
+ ? () => this.$element.innerText
593
+ : () => this.$element.innerHTML;
594
+
595
+ const setValue = format === 'text'
596
+ ? (value) => { this.$element.innerText = value; }
597
+ : (value) => { this.$element.innerHTML = value; };
598
+
599
+ if($obs?.__$Observable) {
600
+ $obs.subscribe((value) => {
601
+ if(document.activeElement !== this.$element) {
602
+ setValue(value);
603
+ }
604
+ });
605
+ setValue($obs.val() || '');
606
+ }
607
+
608
+ this.$element.addEventListener('input', () => {
609
+ $obs?.set(getValue());
610
+ }, { signal: this.$getSignal() });
611
+
612
+ return this;
613
+ };