native-document 1.0.15 → 1.0.16-8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npmrc.example +1 -0
- package/.vitepress/config.js +166 -0
- package/CHANGELOG.md +153 -0
- package/cdn.js +19 -0
- package/components.d.ts +2 -0
- package/components.js +30 -0
- package/devtools/ComponentRegistry.js +113 -0
- package/devtools/index.js +8 -0
- package/devtools/plugin/dev-tools-plugin.js +15 -0
- package/devtools/transformers/nd-vite-devtools.js +55 -0
- package/devtools/transformers/src/transformComponentForHrm.js +73 -0
- package/devtools/transformers/src/transformJsFile.js +9 -0
- package/devtools/transformers/src/utils.js +79 -0
- package/devtools/transformers/templates/hrm.hook.template.js +46 -0
- package/devtools/transformers/templates/hrm.orbservable.hook.template.js +76 -0
- package/devtools/widget/Widget.js +49 -0
- package/devtools/widget/widget.css +81 -0
- package/devtools/widget.js +23 -0
- package/dist/native-document.components.min.css +1 -0
- package/dist/native-document.components.min.js +23847 -0
- package/dist/native-document.dev.js +8421 -1492
- package/dist/native-document.dev.js.map +1 -0
- package/dist/native-document.devtools.min.js +1 -0
- package/dist/native-document.min.js +1 -1
- package/docs/advanced-components.md +419 -0
- package/docs/anchor.md +181 -257
- package/docs/cache.md +180 -0
- package/docs/cli.md +179 -0
- package/docs/components/accordion.md +172 -0
- package/docs/components/alert.md +99 -0
- package/docs/components/avatar.md +160 -0
- package/docs/components/badge.md +102 -0
- package/docs/components/breadcrumb.md +89 -0
- package/docs/components/button.md +183 -0
- package/docs/components/card.md +69 -0
- package/docs/components/context-menu.md +118 -0
- package/docs/components/data-table.md +345 -0
- package/docs/components/dropdown.md +214 -0
- package/docs/components/form/autocomplete-field.md +81 -0
- package/docs/components/form/checkbox-field.md +41 -0
- package/docs/components/form/checkbox-group-field.md +54 -0
- package/docs/components/form/color-field.md +64 -0
- package/docs/components/form/date-field.md +92 -0
- package/docs/components/form/field-collection.md +63 -0
- package/docs/components/form/file-field.md +203 -0
- package/docs/components/form/form-control.md +87 -0
- package/docs/components/form/image-field.md +90 -0
- package/docs/components/form/index.md +115 -0
- package/docs/components/form/number-field.md +65 -0
- package/docs/components/form/radio-field.md +51 -0
- package/docs/components/form/select-field.md +123 -0
- package/docs/components/form/slider.md +136 -0
- package/docs/components/form/string-field.md +134 -0
- package/docs/components/form/textarea-field.md +65 -0
- package/docs/components/form-fields.md +372 -0
- package/docs/components/getting-started.md +264 -0
- package/docs/components/index.md +337 -0
- package/docs/components/layout.md +279 -0
- package/docs/components/list.md +73 -0
- package/docs/components/menu.md +215 -0
- package/docs/components/modal.md +156 -0
- package/docs/components/pagination.md +95 -0
- package/docs/components/popover.md +131 -0
- package/docs/components/progress.md +111 -0
- package/docs/components/shortcut-manager.md +221 -0
- package/docs/components/simple-table.md +107 -0
- package/docs/components/skeleton.md +155 -0
- package/docs/components/spinner.md +100 -0
- package/docs/components/splitter.md +133 -0
- package/docs/components/stepper.md +163 -0
- package/docs/components/switch.md +113 -0
- package/docs/components/tabs.md +153 -0
- package/docs/components/toast.md +119 -0
- package/docs/components/tooltip.md +151 -0
- package/docs/components/traits.md +261 -0
- package/docs/conditional-rendering.md +177 -502
- package/docs/contributing.md +300 -25
- package/docs/core-concepts.md +207 -366
- package/docs/elements.md +266 -254
- package/docs/extending-native-document-element.md +259 -0
- package/docs/filters.md +247 -0
- package/docs/getting-started.md +195 -257
- package/docs/i18n.md +241 -0
- package/docs/index.md +76 -0
- package/docs/lifecycle-events.md +146 -67
- package/docs/list-rendering.md +240 -460
- package/docs/memory-management.md +135 -46
- package/docs/native-document-element.md +487 -0
- package/docs/native-fetch.md +213 -0
- package/docs/observable-resource.md +364 -0
- package/docs/observables.md +690 -357
- package/docs/routing.md +246 -646
- package/docs/state-management.md +213 -306
- package/docs/svg-elements.md +231 -0
- package/docs/theming.md +409 -0
- package/docs/tutorials/.gitkeep +0 -0
- package/docs/validation.md +98 -91
- package/docs/vitepress-conventions.md +219 -0
- package/elements.d.ts +7 -0
- package/elements.js +3 -4
- package/eslint.config.js +35 -0
- package/i18n.js +1 -0
- package/i18n.ts +2 -0
- package/index.d.ts +21 -0
- package/index.def.js +1086 -0
- package/index.js +19 -13
- package/package.json +59 -9
- package/readme.md +296 -93
- package/rollup.config.js +52 -3
- package/router.d.ts +7 -0
- package/router.js +0 -0
- package/src/components/$traits/has-draggable/HasDraggable.d.ts +4 -0
- package/src/components/$traits/has-draggable/HasDraggable.js +82 -0
- package/src/components/$traits/has-draggable/has-draggable.css +8 -0
- package/src/components/$traits/has-items/HasItems.d.ts +9 -0
- package/src/components/$traits/has-items/HasItems.js +64 -0
- package/src/components/$traits/has-position/HasFullPosition.d.ts +14 -0
- package/src/components/$traits/has-position/HasFullPosition.js +95 -0
- package/src/components/$traits/has-position/HasPosition.d.ts +7 -0
- package/src/components/$traits/has-position/HasPosition.js +45 -0
- package/src/components/$traits/has-resizable/HasResizable.d.ts +13 -0
- package/src/components/$traits/has-resizable/HasResizable.js +122 -0
- package/src/components/$traits/has-resizable/has-resizable.css +121 -0
- package/src/components/$traits/has-validation/HasValidation.d.ts +17 -0
- package/src/components/$traits/has-validation/HasValidation.js +133 -0
- package/src/components/BaseComponent.d.ts +32 -0
- package/src/components/BaseComponent.js +247 -0
- package/src/components/accordion/Accordion.js +268 -0
- package/src/components/accordion/AccordionItem.js +233 -0
- package/src/components/accordion/index.js +7 -0
- package/src/components/accordion/types/Accordion.d.ts +47 -0
- package/src/components/accordion/types/AccordionItem.d.ts +48 -0
- package/src/components/alert/Alert.js +350 -0
- package/src/components/alert/index.js +6 -0
- package/src/components/alert/types/Alert.d.ts +62 -0
- package/src/components/avatar/Avatar.js +430 -0
- package/src/components/avatar/AvatarGroup.js +97 -0
- package/src/components/avatar/index.js +7 -0
- package/src/components/avatar/types/Avatar.d.ts +74 -0
- package/src/components/avatar/types/AvatarGroup.d.ts +32 -0
- package/src/components/badge/Badge.js +245 -0
- package/src/components/badge/index.js +6 -0
- package/src/components/badge/types/Badge.d.ts +51 -0
- package/src/components/base-component.css +0 -0
- package/src/components/breadcrumb/BreadCrumb.js +138 -0
- package/src/components/breadcrumb/index.js +5 -0
- package/src/components/breadcrumb/types/BreadCrumb.d.ts +42 -0
- package/src/components/button/Button.js +320 -0
- package/src/components/button/index.js +5 -0
- package/src/components/button/types/Button.d.ts +62 -0
- package/src/components/card/Card.js +282 -0
- package/src/components/card/index.js +5 -0
- package/src/components/card/types/Card.d.ts +42 -0
- package/src/components/context-menu/ContextMenu.js +127 -0
- package/src/components/context-menu/ContextMenuGroup.js +29 -0
- package/src/components/context-menu/ContextMenuItem.js +28 -0
- package/src/components/context-menu/index.js +10 -0
- package/src/components/context-menu/types/ContextMenu.d.ts +30 -0
- package/src/components/context-menu/types/ContextMenuGroup.d.ts +18 -0
- package/src/components/context-menu/types/ContextMenuItem.d.ts +18 -0
- package/src/components/divider/Divider.js +256 -0
- package/src/components/divider/index.js +6 -0
- package/src/components/divider/types/Divider.d.ts +55 -0
- package/src/components/dropdown/Dropdown.js +531 -0
- package/src/components/dropdown/DropdownDivider.js +45 -0
- package/src/components/dropdown/DropdownGroup.js +83 -0
- package/src/components/dropdown/DropdownItem.js +150 -0
- package/src/components/dropdown/DropdownTrigger.js +93 -0
- package/src/components/dropdown/helpers.js +53 -0
- package/src/components/dropdown/index.js +13 -0
- package/src/components/dropdown/types/Dropdown.d.ts +88 -0
- package/src/components/dropdown/types/DropdownDivider.d.ts +20 -0
- package/src/components/dropdown/types/DropdownGroup.d.ts +25 -0
- package/src/components/dropdown/types/DropdownItem.d.ts +41 -0
- package/src/components/dropdown/types/DropdownTrigger.d.ts +32 -0
- package/src/components/form/FormControl.js +498 -0
- package/src/components/form/field/Field.js +419 -0
- package/src/components/form/field/FieldCollection.js +292 -0
- package/src/components/form/field/types/AutocompleteField.js +168 -0
- package/src/components/form/field/types/CheckboxField.js +77 -0
- package/src/components/form/field/types/CheckboxGroupField.js +171 -0
- package/src/components/form/field/types/ColorField.js +102 -0
- package/src/components/form/field/types/DateField.js +315 -0
- package/src/components/form/field/types/EmailField.js +104 -0
- package/src/components/form/field/types/FileField.js +276 -0
- package/src/components/form/field/types/HiddenField.js +44 -0
- package/src/components/form/field/types/ImageField.js +138 -0
- package/src/components/form/field/types/NumberField.js +177 -0
- package/src/components/form/field/types/PasswordField.js +200 -0
- package/src/components/form/field/types/RadioField.js +145 -0
- package/src/components/form/field/types/RangeField.js +117 -0
- package/src/components/form/field/types/SearchField.js +66 -0
- package/src/components/form/field/types/SelectField.js +247 -0
- package/src/components/form/field/types/StringField.js +148 -0
- package/src/components/form/field/types/TelField.js +98 -0
- package/src/components/form/field/types/TextAreaField.js +142 -0
- package/src/components/form/field/types/TimeField.js +215 -0
- package/src/components/form/field/types/UrlField.js +115 -0
- package/src/components/form/field/types/file-field-mode/FileAvatarMode.js +183 -0
- package/src/components/form/field/types/file-field-mode/FileDropzoneMode.js +117 -0
- package/src/components/form/field/types/file-field-mode/FileItemPreview.js +150 -0
- package/src/components/form/field/types/file-field-mode/FileNativeMode.js +43 -0
- package/src/components/form/field/types/file-field-mode/FileUploadButtonMode.js +120 -0
- package/src/components/form/field/types/file-field-mode/FileWallMode.js +106 -0
- package/src/components/form/index.js +61 -0
- package/src/components/form/merge +0 -0
- package/src/components/form/types/Field.d.ts +73 -0
- package/src/components/form/types/FieldCollection.d.ts +53 -0
- package/src/components/form/types/FormControl.d.ts +64 -0
- package/src/components/form/types/fields/AutocompleteField.d.ts +48 -0
- package/src/components/form/types/fields/CheckboxField.d.ts +33 -0
- package/src/components/form/types/fields/CheckboxGroupField.d.ts +49 -0
- package/src/components/form/types/fields/ColorField.d.ts +37 -0
- package/src/components/form/types/fields/DateField.d.ts +70 -0
- package/src/components/form/types/fields/EmailField.d.ts +35 -0
- package/src/components/form/types/fields/FileAvatarMode.d.ts +46 -0
- package/src/components/form/types/fields/FileDropzoneMode.d.ts +28 -0
- package/src/components/form/types/fields/FileField.d.ts +56 -0
- package/src/components/form/types/fields/FileItemPreview.d.ts +35 -0
- package/src/components/form/types/fields/FileNativeMode.d.ts +21 -0
- package/src/components/form/types/fields/FileUploadButtonMode.d.ts +34 -0
- package/src/components/form/types/fields/FileWallMode.d.ts +32 -0
- package/src/components/form/types/fields/HiddenField.d.ts +26 -0
- package/src/components/form/types/fields/ImageField.d.ts +45 -0
- package/src/components/form/types/fields/NumberField.d.ts +48 -0
- package/src/components/form/types/fields/PasswordField.d.ts +46 -0
- package/src/components/form/types/fields/RadioField.d.ts +48 -0
- package/src/components/form/types/fields/RangeField.d.ts +44 -0
- package/src/components/form/types/fields/SearchField.d.ts +34 -0
- package/src/components/form/types/fields/SelectField.d.ts +71 -0
- package/src/components/form/types/fields/StringField.d.ts +48 -0
- package/src/components/form/types/fields/TelField.d.ts +37 -0
- package/src/components/form/types/fields/TextAreaField.d.ts +44 -0
- package/src/components/form/types/fields/TimeField.d.ts +51 -0
- package/src/components/form/types/fields/UrlField.d.ts +35 -0
- package/src/components/form/utils.js +17 -0
- package/src/components/form/validation/Validation.js +565 -0
- package/src/components/index.d.ts +160 -0
- package/src/components/list/HasListItem.js +171 -0
- package/src/components/list/List.js +125 -0
- package/src/components/list/ListDivider.js +39 -0
- package/src/components/list/ListGroup.js +135 -0
- package/src/components/list/ListItem.js +212 -0
- package/src/components/list/index.js +12 -0
- package/src/components/list/types/List.d.ts +43 -0
- package/src/components/list/types/ListGroup.d.ts +37 -0
- package/src/components/list/types/ListItem.d.ts +53 -0
- package/src/components/menu/HasMenuItem.js +182 -0
- package/src/components/menu/Menu.js +227 -0
- package/src/components/menu/MenuDivider.js +37 -0
- package/src/components/menu/MenuGroup.js +126 -0
- package/src/components/menu/MenuItem.js +190 -0
- package/src/components/menu/MenuLink.js +51 -0
- package/src/components/menu/index.js +14 -0
- package/src/components/menu/types/Menu.d.ts +60 -0
- package/src/components/menu/types/MenuDivider.d.ts +19 -0
- package/src/components/menu/types/MenuGroup.d.ts +44 -0
- package/src/components/menu/types/MenuItem.d.ts +46 -0
- package/src/components/menu/types/MenuLink.d.ts +16 -0
- package/src/components/modal/Modal.js +524 -0
- package/src/components/modal/index.js +5 -0
- package/src/components/modal/types/Modal.d.ts +94 -0
- package/src/components/pagination/Pagination.js +411 -0
- package/src/components/pagination/index.js +5 -0
- package/src/components/pagination/types/Pagination.d.ts +68 -0
- package/src/components/popover/Popover.js +459 -0
- package/src/components/popover/PopoverFooter.js +61 -0
- package/src/components/popover/PopoverHeader.js +68 -0
- package/src/components/popover/index.js +10 -0
- package/src/components/popover/types/Popover.d.ts +83 -0
- package/src/components/popover/types/PopoverFooter.d.ts +24 -0
- package/src/components/popover/types/PopoverHeader.d.ts +26 -0
- package/src/components/progress/Progress.js +401 -0
- package/src/components/progress/index.js +6 -0
- package/src/components/progress/types/Progress.d.ts +77 -0
- package/src/components/skeleton/Skeleton.js +228 -0
- package/src/components/skeleton/index.js +6 -0
- package/src/components/skeleton/types/Skeleton.d.ts +55 -0
- package/src/components/slider/Slider.js +406 -0
- package/src/components/slider/index.js +5 -0
- package/src/components/slider/types/Slider.d.ts +82 -0
- package/src/components/spacer/Spacer.js +27 -0
- package/src/components/spacer/index.js +5 -0
- package/src/components/spacer/types/Spacer.d.ts +19 -0
- package/src/components/spinner/Spinner.js +350 -0
- package/src/components/spinner/index.js +5 -0
- package/src/components/spinner/types/Spinner.d.ts +71 -0
- package/src/components/splitter/Splitter.js +164 -0
- package/src/components/splitter/SplitterGutter.js +140 -0
- package/src/components/splitter/SplitterPanel.js +143 -0
- package/src/components/splitter/index.js +10 -0
- package/src/components/splitter/types/Splitter.d.ts +38 -0
- package/src/components/splitter/types/SplitterGutter.d.ts +38 -0
- package/src/components/splitter/types/SplitterPanel.d.ts +41 -0
- package/src/components/stacks/AbsoluteStack.js +53 -0
- package/src/components/stacks/FixedStack.js +53 -0
- package/src/components/stacks/HStack.js +54 -0
- package/src/components/stacks/PositionStack.js +254 -0
- package/src/components/stacks/RelativeStack.js +53 -0
- package/src/components/stacks/Stack.js +166 -0
- package/src/components/stacks/VStack.js +55 -0
- package/src/components/stacks/index.js +21 -0
- package/src/components/stacks/types/AbsoluteStack.d.ts +16 -0
- package/src/components/stacks/types/FixedStack.d.ts +16 -0
- package/src/components/stacks/types/HStack.d.ts +16 -0
- package/src/components/stacks/types/PositionStack.d.ts +54 -0
- package/src/components/stacks/types/RelativeStack.d.ts +17 -0
- package/src/components/stacks/types/Stack.d.ts +39 -0
- package/src/components/stacks/types/VStack.d.ts +16 -0
- package/src/components/stepper/Stepper.js +461 -0
- package/src/components/stepper/StepperStep.js +241 -0
- package/src/components/stepper/index.js +8 -0
- package/src/components/stepper/types/Stepper.d.ts +68 -0
- package/src/components/stepper/types/StepperStep.d.ts +54 -0
- package/src/components/switch/Switch.js +266 -0
- package/src/components/switch/index.js +6 -0
- package/src/components/switch/types/Switch.d.ts +55 -0
- package/src/components/table/Column.js +212 -0
- package/src/components/table/ColumnGroup.js +90 -0
- package/src/components/table/DataTable.js +720 -0
- package/src/components/table/SimpleTable.js +139 -0
- package/src/components/table/index.js +7 -0
- package/src/components/table/types/Column.d.ts +49 -0
- package/src/components/table/types/ColumnGroup.d.ts +28 -0
- package/src/components/table/types/DataTable.d.ts +97 -0
- package/src/components/table/types/SimpleTable.d.ts +40 -0
- package/src/components/tabs/Tabs.js +395 -0
- package/src/components/tabs/index.js +6 -0
- package/src/components/tabs/types/Tabs.d.ts +78 -0
- package/src/components/toast/Toast.js +262 -0
- package/src/components/toast/ToastError.js +0 -0
- package/src/components/toast/ToastInfo.js +0 -0
- package/src/components/toast/ToastSuccess.js +0 -0
- package/src/components/toast/ToastWarning.js +0 -0
- package/src/components/toast/index.js +5 -0
- package/src/components/toast/types/Toast.d.ts +57 -0
- package/src/components/toast/types/ToastError.d.ts +7 -0
- package/src/components/toast/types/ToastInfo.d.ts +7 -0
- package/src/components/toast/types/ToastSuccess.d.ts +7 -0
- package/src/components/toast/types/ToastWarning.d.ts +7 -0
- package/src/components/tooltip/Tooltip.js +359 -0
- package/src/components/tooltip/index.js +5 -0
- package/src/components/tooltip/prototypes.js +6 -0
- package/src/components/tooltip/types/Tooltip.d.ts +65 -0
- package/src/{data → core/data}/MemoryManager.js +2 -3
- package/src/core/data/Observable.js +227 -0
- package/src/core/data/ObservableArray.js +522 -0
- package/src/core/data/ObservableChecker.js +39 -0
- package/src/core/data/ObservableItem.js +611 -0
- package/src/core/data/ObservableObject.js +274 -0
- package/src/core/data/ObservableResource.js +315 -0
- package/src/core/data/ObservableWhen.js +54 -0
- package/src/core/data/Store.js +520 -0
- package/src/core/data/observable-helpers/observable.is-to.js +390 -0
- package/src/core/data/observable-helpers/observable.prototypes.js +145 -0
- package/src/core/elements/anchor/anchor-with-sentinel.js +66 -0
- package/src/core/elements/anchor/anchor.js +210 -0
- package/src/core/elements/anchor/one-child-anchor-overwriting.js +66 -0
- package/src/core/elements/content-formatter.js +169 -0
- package/src/core/elements/control/for-each-array.js +292 -0
- package/src/{elements → core/elements}/control/for-each.js +42 -23
- package/src/core/elements/control/show-if.js +94 -0
- package/src/core/elements/control/show-when.js +54 -0
- package/src/core/elements/control/switch.js +141 -0
- package/src/core/elements/description-list.js +19 -0
- package/src/core/elements/form.js +255 -0
- package/src/core/elements/fragment.js +8 -0
- package/src/core/elements/html5-semantics.js +55 -0
- package/src/core/elements/img.js +59 -0
- package/src/{elements → core/elements}/index.js +4 -4
- package/src/core/elements/interactive.js +25 -0
- package/src/core/elements/list.js +37 -0
- package/src/core/elements/medias.js +37 -0
- package/src/core/elements/meta-data.js +43 -0
- package/src/core/elements/svg.js +61 -0
- package/src/core/elements/table.js +73 -0
- package/src/{errors → core/errors}/ArgTypesError.js +1 -1
- package/src/{errors → core/errors}/NativeDocumentError.js +0 -0
- package/src/core/utils/HasEventEmitter.js +85 -0
- package/src/core/utils/args-types.js +140 -0
- package/src/core/utils/cache.js +5 -0
- package/src/core/utils/callback-handler.js +50 -0
- package/src/core/utils/debug-manager.js +40 -0
- package/src/core/utils/events.js +148 -0
- package/src/core/utils/filters/date.js +178 -0
- package/src/core/utils/filters/index.js +4 -0
- package/src/core/utils/filters/standard.js +263 -0
- package/src/core/utils/filters/strings.js +67 -0
- package/src/core/utils/filters/utils.js +77 -0
- package/src/core/utils/formatters.js +90 -0
- package/src/core/utils/helpers.js +144 -0
- package/src/core/utils/localstorage.js +57 -0
- package/src/core/utils/memoize.js +115 -0
- package/src/core/utils/plugins-manager.js +81 -0
- package/src/core/utils/property-accumulator.js +72 -0
- package/src/core/utils/prototypes.js +44 -0
- package/src/core/utils/shortcut-manager.js +242 -0
- package/src/{utils → core/utils}/validator.js +58 -22
- package/src/core/wrappers/AttributesWrapper.js +98 -0
- package/src/core/wrappers/DocumentObserver.js +182 -0
- package/src/core/wrappers/ElementCreator.js +120 -0
- package/src/core/wrappers/HtmlElementWrapper.js +98 -0
- package/src/core/wrappers/NDElement.js +613 -0
- package/src/core/wrappers/NdPrototype.js +233 -0
- package/src/core/wrappers/SingletonView.js +99 -0
- package/src/core/wrappers/SvgElementWrapper.js +15 -0
- package/src/core/wrappers/TemplateBinding.js +7 -0
- package/src/core/wrappers/constants.js +66 -0
- package/src/core/wrappers/prototypes/attributes-extensions.js +179 -0
- package/src/core/wrappers/prototypes/bind-class-extensions.js +0 -0
- package/src/core/wrappers/prototypes/nd-element-extensions.js +157 -0
- package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +127 -0
- package/src/core/wrappers/template-cloner/NodeCloner.js +209 -0
- package/src/core/wrappers/template-cloner/TemplateCloner.js +192 -0
- package/src/core/wrappers/template-cloner/attributes-hydrator.js +142 -0
- package/src/core/wrappers/template-cloner/utils.js +173 -0
- package/src/fetch/NativeFetch.js +89 -0
- package/src/i18n/bin/scan.js +132 -0
- package/src/i18n/index.d.ts +2 -0
- package/src/i18n/service/I18nService.d.ts +27 -0
- package/src/i18n/service/I18nService.js +46 -0
- package/src/i18n/service/functions.d.ts +22 -0
- package/src/i18n/service/functions.js +29 -0
- package/src/router/Route.js +33 -8
- package/src/router/RouteGroupHelper.js +10 -2
- package/src/router/Router.js +63 -22
- package/src/router/RouterComponent.js +114 -6
- package/src/{errors → router/errors}/RouterError.js +0 -1
- package/src/router/link.js +9 -10
- package/src/router/modes/HashRouter.js +2 -2
- package/src/router/modes/HistoryRouter.js +2 -3
- package/src/router/modes/MemoryRouter.js +1 -1
- package/src/ui/components/accordion/AccordionItemRender.js +63 -0
- package/src/ui/components/accordion/AccordionRender.js +35 -0
- package/src/ui/components/accordion/accordion.css +121 -0
- package/src/ui/components/alert/AlertRender.js +81 -0
- package/src/ui/components/alert/alert.css +163 -0
- package/src/ui/components/avatar/avata-group/AvatarGroupRender.js +50 -0
- package/src/ui/components/avatar/avata-group/avatar-group.css +38 -0
- package/src/ui/components/avatar/avatar/AvatarRender.js +87 -0
- package/src/ui/components/avatar/avatar/avatar.css +189 -0
- package/src/ui/components/badge/BadgeRender.js +25 -0
- package/src/ui/components/badge/badge.css +168 -0
- package/src/ui/components/breadcrumb/BreadcrumbRender.js +44 -0
- package/src/ui/components/breadcrumb/breadcrumb.css +55 -0
- package/src/ui/components/button/ButtonRender.js +65 -0
- package/src/ui/components/button/button.css +296 -0
- package/src/ui/components/card/CardRender.js +133 -0
- package/src/ui/components/card/card.css +169 -0
- package/src/ui/components/contextmenu/ContextmenuRender.js +68 -0
- package/src/ui/components/contextmenu/contextmenu.css +36 -0
- package/src/ui/components/divider/DividerRender.js +70 -0
- package/src/ui/components/divider/divider.css +70 -0
- package/src/ui/components/dropdown/DropdownRender.js +92 -0
- package/src/ui/components/dropdown/divider/DropdownDividerRender.js +9 -0
- package/src/ui/components/dropdown/divider/dropdown-divider.css +0 -0
- package/src/ui/components/dropdown/dropdown.css +179 -0
- package/src/ui/components/dropdown/group/DropdownGroupRender.js +23 -0
- package/src/ui/components/dropdown/group/dropdown-group.css +0 -0
- package/src/ui/components/dropdown/item/DropdownItemRender.js +29 -0
- package/src/ui/components/dropdown/item/dropdown-item.css +0 -0
- package/src/ui/components/form/FieldCollectionRender.js +110 -0
- package/src/ui/components/form/FormControlRender.js +85 -0
- package/src/ui/components/form/field-collection.css +55 -0
- package/src/ui/components/form/fields/AutocompleteFieldRender.js +143 -0
- package/src/ui/components/form/fields/CheckboxFieldRender.js +59 -0
- package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +92 -0
- package/src/ui/components/form/fields/ColorFieldRender.js +30 -0
- package/src/ui/components/form/fields/DateFieldRender.js +155 -0
- package/src/ui/components/form/fields/EmailFieldRender.js +5 -0
- package/src/ui/components/form/fields/FieldRender.js +118 -0
- package/src/ui/components/form/fields/FileFieldRender.js +41 -0
- package/src/ui/components/form/fields/HiddenFieldRender.js +13 -0
- package/src/ui/components/form/fields/ImageFieldRender.js +0 -0
- package/src/ui/components/form/fields/NumberFieldRender.js +52 -0
- package/src/ui/components/form/fields/PasswordFieldRender.js +65 -0
- package/src/ui/components/form/fields/RadioFieldRender.js +77 -0
- package/src/ui/components/form/fields/RangeFieldRender.js +122 -0
- package/src/ui/components/form/fields/SelectFieldRender.js +248 -0
- package/src/ui/components/form/fields/SliderFieldRender.js +359 -0
- package/src/ui/components/form/fields/StringFieldRender.js +6 -0
- package/src/ui/components/form/fields/TelFieldRender.js +6 -0
- package/src/ui/components/form/fields/TextAreaFieldRender.js +96 -0
- package/src/ui/components/form/fields/TimeFieldRender.js +142 -0
- package/src/ui/components/form/fields/UrlFieldRender.js +6 -0
- package/src/ui/components/form/fields/date-field.css +32 -0
- package/src/ui/components/form/fields/field.css +402 -0
- package/src/ui/components/form/fields/file-field.css +79 -0
- package/src/ui/components/form/fields/password-field.css +50 -0
- package/src/ui/components/form/fields/range-field.css +120 -0
- package/src/ui/components/form/fields/slider.css +195 -0
- package/src/ui/components/form/file-upload-mode/FileAvatarModeRender.js +143 -0
- package/src/ui/components/form/file-upload-mode/FileDropzoneModeRender.js +108 -0
- package/src/ui/components/form/file-upload-mode/FileNativeModeRender.js +22 -0
- package/src/ui/components/form/file-upload-mode/FileUploadButtonModeRender.js +89 -0
- package/src/ui/components/form/file-upload-mode/FileWallModeRender.js +90 -0
- package/src/ui/components/form/file-upload-mode/file-avatar-mode.css +139 -0
- package/src/ui/components/form/file-upload-mode/file-dropzone-mode.css +88 -0
- package/src/ui/components/form/file-upload-mode/file-upload-button-mode.css +44 -0
- package/src/ui/components/form/file-upload-mode/file-wall-mode.css +88 -0
- package/src/ui/components/form/form-control.css +40 -0
- package/src/ui/components/form/helpers.js +111 -0
- package/src/ui/components/form/index.js +27 -0
- package/src/ui/components/list/ListRender.js +18 -0
- package/src/ui/components/list/divider/ListDividerRender.js +10 -0
- package/src/ui/components/list/divider/list-divider.css +12 -0
- package/src/ui/components/list/group/ListGroupRender.js +61 -0
- package/src/ui/components/list/group/list-group.css +62 -0
- package/src/ui/components/list/item/ListItemRender.js +238 -0
- package/src/ui/components/list/item/list-item.css +191 -0
- package/src/ui/components/list/list.css +24 -0
- package/src/ui/components/menu/MenuDividerRender.js +12 -0
- package/src/ui/components/menu/MenuGroupRender.js +59 -0
- package/src/ui/components/menu/MenuItemRender.js +57 -0
- package/src/ui/components/menu/MenuLinkRender.js +55 -0
- package/src/ui/components/menu/MenuRender.js +22 -0
- package/src/ui/components/menu/helpers.js +121 -0
- package/src/ui/components/menu/menu.css +308 -0
- package/src/ui/components/modal/ModalRender.js +118 -0
- package/src/ui/components/modal/modal.css +156 -0
- package/src/ui/components/pagination/PaginationRender.js +112 -0
- package/src/ui/components/pagination/pagination.css +63 -0
- package/src/ui/components/popover/PopoverRender.js +233 -0
- package/src/ui/components/popover/popover.css +139 -0
- package/src/ui/components/progress/ProgressRender.js +168 -0
- package/src/ui/components/progress/progress.css +197 -0
- package/src/ui/components/skeleton/SkeletonRender.js +136 -0
- package/src/ui/components/skeleton/skeleton.css +154 -0
- package/src/ui/components/spacer/SpacerRender.js +10 -0
- package/src/ui/components/spinner/SpinnerRender.js +47 -0
- package/src/ui/components/spinner/spinner.css +152 -0
- package/src/ui/components/splitter/SplitterGutterRender.js +94 -0
- package/src/ui/components/splitter/SplitterPanelRender.js +38 -0
- package/src/ui/components/splitter/SplitterRender.js +75 -0
- package/src/ui/components/splitter/splitter.css +128 -0
- package/src/ui/components/stacks/PositionStackRender.js +39 -0
- package/src/ui/components/stacks/StackRender.js +41 -0
- package/src/ui/components/stacks/absolute-stack/AbsoluteStackRender.js +5 -0
- package/src/ui/components/stacks/fixed-stack/FixedStackRender.js +5 -0
- package/src/ui/components/stacks/h-stack/HStackRender.js +7 -0
- package/src/ui/components/stacks/h-stack/h-stack.css +4 -0
- package/src/ui/components/stacks/index.js +5 -0
- package/src/ui/components/stacks/position-stack.css +62 -0
- package/src/ui/components/stacks/relative-stack/RelativeStackRender.js +7 -0
- package/src/ui/components/stacks/relative-stack/relative-stack.css +3 -0
- package/src/ui/components/stacks/stack.css +78 -0
- package/src/ui/components/stacks/v-stack/VStackRender.js +6 -0
- package/src/ui/components/stacks/v-stack/v-stack.css +4 -0
- package/src/ui/components/stepper/StepperRender.js +71 -0
- package/src/ui/components/stepper/StepperStepRender.js +67 -0
- package/src/ui/components/stepper/stepper.css +359 -0
- package/src/ui/components/switch/SwitchRender.js +83 -0
- package/src/ui/components/switch/switch.css +143 -0
- package/src/ui/components/table/data-table/DataTableRender.js +50 -0
- package/src/ui/components/table/data-table/bulk-actions.js +34 -0
- package/src/ui/components/table/data-table/data-table.css +246 -0
- package/src/ui/components/table/data-table/pagination.js +56 -0
- package/src/ui/components/table/data-table/tables.js +368 -0
- package/src/ui/components/table/data-table/toolbar.js +67 -0
- package/src/ui/components/table/simple-table/SimpleTableRender.js +203 -0
- package/src/ui/components/table/simple-table/simple-table.css +50 -0
- package/src/ui/components/tabs/TabsRender.js +226 -0
- package/src/ui/components/tabs/tabs.css +253 -0
- package/src/ui/components/toast/ToastRender.js +99 -0
- package/src/ui/components/toast/toast.css +201 -0
- package/src/ui/components/tooltip/TooltipRender.js +8 -0
- package/src/ui/components/tooltip/tooltip.css +113 -0
- package/src/ui/index.js +47 -0
- package/src/ui/theme.js +0 -0
- package/src/ui/theme.scss +1 -0
- package/src/ui/tokens/animation.scss +36 -0
- package/src/ui/tokens/colors-dark.scss +58 -0
- package/src/ui/tokens/colors.scss +54 -0
- package/src/ui/tokens/components.scss +32 -0
- package/src/ui/tokens/fonts.scss +57 -0
- package/src/ui/tokens/glass.scss +10 -0
- package/src/ui/tokens/index.scss +38 -0
- package/src/ui/tokens/layouts.scss +228 -0
- package/src/ui/tokens/opacity.scss +21 -0
- package/src/ui/tokens/others.scss +11 -0
- package/src/ui/tokens/radius.scss +6 -0
- package/src/ui/tokens/reset.scss +51 -0
- package/src/ui/tokens/shadows.scss +29 -0
- package/src/ui/tokens/spacings.scss +13 -0
- package/src/ui/tokens/vars.scss +35 -0
- package/src/ui/tokens/viewports.scss +30 -0
- package/types/args-types.d.ts +58 -0
- package/types/control-flow.d.ts +62 -0
- package/types/elements.d.ts +231 -0
- package/types/filters/dates.d.ts +43 -0
- package/types/filters/index.d.ts +4 -0
- package/types/filters/standard.d.ts +70 -0
- package/types/filters/strings.d.ts +21 -0
- package/types/filters/types.d.ts +20 -0
- package/types/forms.d.ts +84 -0
- package/types/globals.d.ts +543 -0
- package/types/images.d.ts +23 -0
- package/types/localStorage.ts +102 -0
- package/types/memoize.d.ts +26 -0
- package/types/native-fetch.d.ts +72 -0
- package/types/nd-element.d.ts +407 -0
- package/types/observable-resource.d.ts +3 -0
- package/types/observable.d.ts +227 -0
- package/types/plugins-manager.d.ts +65 -0
- package/types/polyfill.d.ts +18 -0
- package/types/property-accumulator.d.ts +33 -0
- package/types/router.d.ts +85 -0
- package/types/service.d.ts +23 -0
- package/types/singleton.d.ts +19 -0
- package/types/store.d.ts +63 -0
- package/types/template-cloner.ts +43 -0
- package/types/validator.ts +66 -0
- package/ui.js +1 -0
- package/utils.d.ts +4 -0
- package/utils.js +12 -0
- package/src/data/Observable.js +0 -55
- package/src/data/ObservableChecker.js +0 -39
- package/src/data/ObservableItem.js +0 -195
- package/src/data/Store.js +0 -74
- package/src/data/observable-helpers/array.js +0 -74
- package/src/data/observable-helpers/batch.js +0 -22
- package/src/data/observable-helpers/computed.js +0 -28
- package/src/data/observable-helpers/object.js +0 -111
- package/src/elements/anchor.js +0 -129
- package/src/elements/content-formatter.js +0 -32
- package/src/elements/control/for-each-array.js +0 -280
- package/src/elements/control/show-if.js +0 -79
- package/src/elements/control/switch.js +0 -98
- package/src/elements/description-list.js +0 -5
- package/src/elements/form.js +0 -71
- package/src/elements/html5-semantics.js +0 -12
- package/src/elements/img.js +0 -45
- package/src/elements/interactive.js +0 -7
- package/src/elements/list.js +0 -10
- package/src/elements/medias.js +0 -8
- package/src/elements/meta-data.js +0 -9
- package/src/elements/table.js +0 -14
- package/src/utils/args-types.js +0 -100
- package/src/utils/debug-manager.js +0 -31
- package/src/utils/helpers.js +0 -60
- package/src/utils/plugins-manager.js +0 -12
- package/src/utils/prototypes.js +0 -45
- package/src/wrappers/AttributesWrapper.js +0 -144
- package/src/wrappers/DocumentObserver.js +0 -80
- package/src/wrappers/ElementCreator.js +0 -114
- package/src/wrappers/HtmlElementEventsWrapper.js +0 -64
- package/src/wrappers/HtmlElementWrapper.js +0 -50
- package/src/wrappers/NdPrototype.js +0 -109
- 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
|
+
};
|