native-document 1.0.15 → 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.
- 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 +181 -0
- package/src/core/wrappers/DocumentObserver.js +182 -0
- package/src/core/wrappers/ElementCreator.js +110 -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 +24 -0
- package/src/core/wrappers/prototypes/bind-class-extensions.js +0 -0
- package/src/core/wrappers/prototypes/nd-element-extensions.js +149 -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,487 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: NDElement
|
|
3
|
+
description: The NDElement wrapper enhances native HTML elements with fluent event handling, lifecycle hooks, transitions, and DOM utilities
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# NDElement
|
|
7
|
+
|
|
8
|
+
`NDElement` is a wrapper class that enhances native HTML elements with fluent event handling, lifecycle hooks, transitions, and DOM utilities - while preserving full access to the underlying native element.
|
|
9
|
+
|
|
10
|
+
## Accessing NDElement
|
|
11
|
+
|
|
12
|
+
Every element created with NativeDocument automatically has an `nd` property that returns its `NDElement` instance:
|
|
13
|
+
|
|
14
|
+
```javascript
|
|
15
|
+
const element = Div('Hello World');
|
|
16
|
+
const ndElement = element.nd; // NDElement instance
|
|
17
|
+
|
|
18
|
+
// Chain directly
|
|
19
|
+
Div('Hello').nd.onClick(() => console.log('Clicked!'));
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Once you call `.nd`, subsequent methods chain directly, no need to repeat `.nd`:
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
Button('Interactive')
|
|
26
|
+
.nd
|
|
27
|
+
.onClick(e => console.log('Clicked'))
|
|
28
|
+
.onMouseEnter(e => e.target.style.background = 'blue')
|
|
29
|
+
.onMouseLeave(e => e.target.style.background = '')
|
|
30
|
+
.mounted(el => console.log('Button mounted'));
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Properties
|
|
34
|
+
|
|
35
|
+
### `$element`
|
|
36
|
+
The encapsulated native HTML element.
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
const div = Div('Content');
|
|
40
|
+
const htmlElement = div.nd.$element; // Native HTMLDivElement
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### `$observer`
|
|
44
|
+
Lifecycle observer, used internally for DOM monitoring.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Event Handling
|
|
49
|
+
|
|
50
|
+
### Auto-generated event methods
|
|
51
|
+
|
|
52
|
+
NDElement generates methods for all standard DOM events in four variants:
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
// Standard
|
|
56
|
+
element.nd.onClick(callback)
|
|
57
|
+
|
|
58
|
+
// Prevents default behavior
|
|
59
|
+
element.nd.onPreventClick(callback)
|
|
60
|
+
|
|
61
|
+
// Stops event propagation
|
|
62
|
+
element.nd.onStopClick(callback)
|
|
63
|
+
|
|
64
|
+
// Both preventDefault() and stopPropagation()
|
|
65
|
+
element.nd.onPreventStopClick(callback)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// Standard usage
|
|
70
|
+
Button('Submit').nd.onClick(e => console.log('Clicked'));
|
|
71
|
+
Input().nd.onInput(e => console.log('Value:', e.target.value));
|
|
72
|
+
|
|
73
|
+
// Prevent default
|
|
74
|
+
Link({ href: '/page' })
|
|
75
|
+
.nd
|
|
76
|
+
.onPreventClick(e => {
|
|
77
|
+
router.push('/page');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Stop propagation
|
|
81
|
+
Div([
|
|
82
|
+
Button('Child').nd.onStopClick(e => console.log("Won't bubble"))
|
|
83
|
+
]).nd.onClick(() => console.log('Never called'));
|
|
84
|
+
|
|
85
|
+
// Prevent + stop
|
|
86
|
+
Form().nd.onPreventStopSubmit(handleFormSubmit);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Supported events
|
|
90
|
+
|
|
91
|
+
**Mouse:** `Click`, `DblClick`, `MouseDown`, `MouseEnter`, `MouseLeave`, `MouseMove`, `MouseOut`, `MouseOver`, `MouseUp`, `Wheel`
|
|
92
|
+
|
|
93
|
+
**Keyboard:** `KeyDown`, `KeyPress`, `KeyUp`
|
|
94
|
+
|
|
95
|
+
**Form:** `Blur`, `Change`, `Focus`, `Input`, `Invalid`, `Reset`, `Search`, `Select`, `Submit`
|
|
96
|
+
|
|
97
|
+
**Drag & Drop:** `Drag`, `DragEnd`, `DragEnter`, `DragLeave`, `DragOver`, `DragStart`, `Drop`
|
|
98
|
+
|
|
99
|
+
**Media:** `Abort`, `CanPlay`, `CanPlayThrough`, `DurationChange`, `Emptied`, `Ended`, `LoadedData`, `LoadedMetadata`, `LoadStart`, `Pause`, `Play`, `Playing`, `Progress`, `RateChange`, `Seeked`, `Seeking`, `Stalled`, `Suspend`, `TimeUpdate`, `VolumeChange`, `Waiting`
|
|
100
|
+
|
|
101
|
+
**Window:** `AfterPrint`, `BeforePrint`, `BeforeUnload`, `Error`, `HashChange`, `Load`, `Offline`, `Online`, `PageHide`, `PageShow`, `Resize`, `Scroll`, `Unload`
|
|
102
|
+
|
|
103
|
+
### `.on(name, callback, options)` - Generic event
|
|
104
|
+
|
|
105
|
+
Registers any DOM event. Uses `AbortController` internally - listeners are **automatically removed when the element is unmounted**, no manual cleanup needed:
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
element.nd.on('scroll', callback, { passive: true })
|
|
109
|
+
element.nd.on('customEvent', callback)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### `.off(name, callback)` - Remove a specific listener
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
const handler = e => console.log(e);
|
|
116
|
+
|
|
117
|
+
element.nd.on('click', handler);
|
|
118
|
+
element.nd.off('click', handler);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `.once(name, callback)` - One-time listener
|
|
122
|
+
|
|
123
|
+
Fires once then removes itself automatically:
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
element.nd.once('click', () => console.log('First click only'));
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### `.emit(name, detail?)` - Dispatch a custom event
|
|
130
|
+
|
|
131
|
+
```javascript
|
|
132
|
+
element.nd.emit('my-event', { value: 42 });
|
|
133
|
+
|
|
134
|
+
// Listen for it on a parent
|
|
135
|
+
parent.nd.on('my-event', e => console.log(e.detail.value)); // 42
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Attribute Methods
|
|
141
|
+
|
|
142
|
+
### `.attr(name, value)` - Set a single attribute
|
|
143
|
+
|
|
144
|
+
Accepts a plain value or an observable:
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
element.nd.attr('aria-label', 'Close button');
|
|
148
|
+
element.nd.attr('aria-expanded', isOpen); // reactive
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `.attrs(attrs)` - Set multiple attributes
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
element.nd.attrs({
|
|
155
|
+
'aria-label': 'Close',
|
|
156
|
+
'aria-expanded': isOpen,
|
|
157
|
+
'data-id': '123'
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### `.class(classes)` - Bind class object
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
element.nd.class({
|
|
165
|
+
'active': isActive,
|
|
166
|
+
'disabled': isDisabled,
|
|
167
|
+
'hidden': isVisible.isFalsy()
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### `.style(style)` - Bind style object
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
element.nd.style({
|
|
175
|
+
color: theme.format(t => t === 'dark' ? '#fff' : '#333'),
|
|
176
|
+
opacity: isVisible.format(v => v ? 1 : 0.5)
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Utility Methods
|
|
183
|
+
|
|
184
|
+
### `ref(target, name)` / `refSelf(target, name)`
|
|
185
|
+
|
|
186
|
+
Both store a reference on a target object but store different things:
|
|
187
|
+
|
|
188
|
+
- **`ref(target, name)`** - stores the **native HTML element** (`this.$element`) - use for direct DOM access
|
|
189
|
+
- **`refSelf(target, name)`** - stores the **`NDElement` instance** (`this`) - use to keep calling `.nd` methods
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
const refs = {};
|
|
193
|
+
|
|
194
|
+
Div([
|
|
195
|
+
Input({ type: 'text' }).nd.ref(refs, 'nameInput'), // refs.nameInput -> HTMLInputElement
|
|
196
|
+
Input({ type: 'text' }).nd.refSelf(refs, 'emailInput'), // refs.emailInput -> NDElement instance
|
|
197
|
+
|
|
198
|
+
Button('Actions')
|
|
199
|
+
.nd
|
|
200
|
+
.onClick(() => {
|
|
201
|
+
refs.nameInput.focus(); // native DOM method
|
|
202
|
+
refs.emailInput.onInput(e => console.log(e.target.value)); // nd method
|
|
203
|
+
})
|
|
204
|
+
]);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### `htmlElement()` / `node()`
|
|
208
|
+
|
|
209
|
+
Returns the native HTML element, both are aliases for `$element`:
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
const div = Div('Hello');
|
|
213
|
+
div.nd.htmlElement(); // HTMLDivElement
|
|
214
|
+
div.nd.node(); // same
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### `remove()`
|
|
218
|
+
|
|
219
|
+
Removes the element from the DOM and cleans up its internal references:
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
const element = Div('Temporary');
|
|
223
|
+
element.nd.remove();
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### `unmountChildren()`
|
|
227
|
+
|
|
228
|
+
Unmounts all child elements and cleans up their references:
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
const container = Div([Div('Child 1'), Div('Child 2')]);
|
|
232
|
+
container.nd.unmountChildren();
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### `ghostDom(element)`
|
|
236
|
+
|
|
237
|
+
Appends an element to an internal `DocumentFragment` attached to the component. When the component is inserted into the DOM, both the main element and the ghost elements are injected together - but the user only interacts with the main element.
|
|
238
|
+
|
|
239
|
+
This is primarily useful when building components that need a companion element in the DOM. For example, a `Button` that controls a `Dropdown`: the button is the returned element, the dropdown lives in the ghost DOM. Both are rendered, but only the button is exposed to the parent:
|
|
240
|
+
|
|
241
|
+
```javascript
|
|
242
|
+
function DropdownButton(label, items) {
|
|
243
|
+
const isOpen = Observable(false);
|
|
244
|
+
|
|
245
|
+
const dropdown = Div({ class: 'dropdown' }, [
|
|
246
|
+
ShowIf(isOpen, () => Ul(items.map(item => Li(item))))
|
|
247
|
+
]);
|
|
248
|
+
|
|
249
|
+
return Button(label)
|
|
250
|
+
.nd
|
|
251
|
+
.onClick(() => isOpen.toggle())
|
|
252
|
+
.ghostDom(dropdown); // dropdown is injected into DOM alongside the button
|
|
253
|
+
// but the parent only receives the button
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Usage - the parent only works with the button
|
|
257
|
+
const btn = DropdownButton('Options', ['Edit', 'Delete']);
|
|
258
|
+
document.body.appendChild(btn);
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### `attach(methodName, bindingHydrator)`
|
|
262
|
+
|
|
263
|
+
Attaches a template binding hydrator to the element. Used internally by the `useCache` and `useSingleton` rendering systems:
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
element.nd.attach('onClick', bindingHydrator);
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
See [Advanced Components](./advanced-components.md) for practical usage.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Lifecycle Management
|
|
274
|
+
|
|
275
|
+
### `mounted(callback)`
|
|
276
|
+
|
|
277
|
+
Fires when the element is added to the DOM:
|
|
278
|
+
|
|
279
|
+
```javascript
|
|
280
|
+
Div('Content')
|
|
281
|
+
.nd
|
|
282
|
+
.mounted(element => {
|
|
283
|
+
console.log('In the DOM');
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### `unmounted(callback)`
|
|
288
|
+
|
|
289
|
+
Fires when the element is removed from the DOM:
|
|
290
|
+
|
|
291
|
+
```javascript
|
|
292
|
+
Div('Content')
|
|
293
|
+
.nd
|
|
294
|
+
.unmounted(element => {
|
|
295
|
+
console.log('Removed from DOM');
|
|
296
|
+
// Only clean up external resources here (timers, websockets)
|
|
297
|
+
// Do NOT clean up observables unless the element is permanently destroyed
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### `lifecycle({ mounted, unmounted })`
|
|
302
|
+
|
|
303
|
+
Configures both hooks at once:
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
Div('Content')
|
|
307
|
+
.nd
|
|
308
|
+
.lifecycle({
|
|
309
|
+
mounted: el => console.log('Mounted'),
|
|
310
|
+
unmounted: el => console.log('Unmounted')
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### `beforeUnmount(id, callback)`
|
|
315
|
+
|
|
316
|
+
Registers an async callback that runs before the element is removed. Useful for exit animations or data saving:
|
|
317
|
+
|
|
318
|
+
```javascript
|
|
319
|
+
Div('Content')
|
|
320
|
+
.nd
|
|
321
|
+
.beforeUnmount('save', async () => {
|
|
322
|
+
await saveData();
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Transitions
|
|
329
|
+
|
|
330
|
+
### `transition(name)`
|
|
331
|
+
|
|
332
|
+
Applies both enter and exit transitions via CSS classes:
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
Div('Content').nd.transition('fade');
|
|
336
|
+
// On mount: adds 'fade-enter-from', then 'fade-enter-to'
|
|
337
|
+
// On unmount: adds 'fade-exit'
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### `transitionIn(name)` / `transitionOut(name)`
|
|
341
|
+
|
|
342
|
+
Apply only the enter or exit transition:
|
|
343
|
+
|
|
344
|
+
```javascript
|
|
345
|
+
Div('Content')
|
|
346
|
+
.nd
|
|
347
|
+
.transitionIn('slide-down')
|
|
348
|
+
.transitionOut('slide-up');
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### `animate(name)`
|
|
352
|
+
|
|
353
|
+
Triggers a one-shot CSS animation, adds the class then removes it automatically:
|
|
354
|
+
|
|
355
|
+
```javascript
|
|
356
|
+
Button('Click').nd.onClick(function() {
|
|
357
|
+
this.nd.animate('bounce');
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Extending NDElement
|
|
364
|
+
|
|
365
|
+
### `.nd.with(methods)` - Exposing child component methods
|
|
366
|
+
|
|
367
|
+
`.with()` is designed for components that need to **expose internal control methods to their parent** without leaking their internal observables. The parent accesses these methods via `refSelf`.
|
|
368
|
+
|
|
369
|
+
A typical use case is a component like a media player or a counter that must expose `play`, `pause`, `reset` - letting the parent control it without knowing its internal state:
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
function Counter(initialValue = 0) {
|
|
373
|
+
const count = Observable(initialValue); // internal - never exposed
|
|
374
|
+
let interval = null;
|
|
375
|
+
|
|
376
|
+
return Div({ class: 'counter' }, [
|
|
377
|
+
Div(['Count: ', count]),
|
|
378
|
+
])
|
|
379
|
+
.nd
|
|
380
|
+
.with({
|
|
381
|
+
play() {
|
|
382
|
+
if (interval) return this;
|
|
383
|
+
interval = setInterval(() => count.$value++, 1000);
|
|
384
|
+
return this;
|
|
385
|
+
},
|
|
386
|
+
pause() {
|
|
387
|
+
clearInterval(interval);
|
|
388
|
+
interval = null;
|
|
389
|
+
return this;
|
|
390
|
+
},
|
|
391
|
+
reset() {
|
|
392
|
+
this.pause();
|
|
393
|
+
count.set(initialValue);
|
|
394
|
+
return this;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Parent controls the counter via refSelf - no internal state exposed
|
|
400
|
+
const refs = {};
|
|
401
|
+
|
|
402
|
+
Div([
|
|
403
|
+
Counter(0).nd.refSelf(refs, 'counter'),
|
|
404
|
+
Button('Play').nd.onClick(() => refs.counter.play()),
|
|
405
|
+
Button('Pause').nd.onClick(() => refs.counter.pause()),
|
|
406
|
+
Button('Reset').nd.onClick(() => refs.counter.reset())
|
|
407
|
+
]);
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
> `.with()` only affects the current instance. The methods are not available on other elements.
|
|
411
|
+
|
|
412
|
+
### `NDElement.extend(methods)` - App-wide methods
|
|
413
|
+
|
|
414
|
+
Adds methods to **all NDElement instances** via the prototype. Use for app-wide utilities:
|
|
415
|
+
|
|
416
|
+
```javascript
|
|
417
|
+
NDElement.extend({
|
|
418
|
+
onEnter(callback) {
|
|
419
|
+
this.$element.addEventListener('keyup', e => {
|
|
420
|
+
if (e.key === 'Enter') callback(e);
|
|
421
|
+
});
|
|
422
|
+
return this;
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
// Available on every element
|
|
427
|
+
Input().nd.onEnter(e => console.log('Enter pressed'));
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Protected methods
|
|
431
|
+
|
|
432
|
+
The following method names **cannot be overridden** via `NDElement.extend()` - attempting to do so throws a `NativeDocumentError`:
|
|
433
|
+
|
|
434
|
+
`constructor`, `valueOf`, `$element`, `$observer`, `ref`, `remove`, `cleanup`, `with`, `extend`, `attach`, `lifecycle`, `mounted`, `unmounted`, `unmountChildren`
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Shadow DOM
|
|
439
|
+
|
|
440
|
+
```javascript
|
|
441
|
+
// Open shadow DOM (inspectable in DevTools)
|
|
442
|
+
Div('Content')
|
|
443
|
+
.nd
|
|
444
|
+
.openShadow(`
|
|
445
|
+
:host { display: block; padding: 20px; }
|
|
446
|
+
p { color: blue; }
|
|
447
|
+
`);
|
|
448
|
+
|
|
449
|
+
// Closed shadow DOM (private)
|
|
450
|
+
Div('Content').nd.closedShadow(`p { color: red; }`);
|
|
451
|
+
|
|
452
|
+
// Manual mode
|
|
453
|
+
Div('Content').nd.shadow('open', `/* scoped styles */`);
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## Integration with Observables
|
|
459
|
+
|
|
460
|
+
```javascript
|
|
461
|
+
const isVisible = Observable(false);
|
|
462
|
+
const message = Observable('Hello');
|
|
463
|
+
|
|
464
|
+
Div([
|
|
465
|
+
Button('Toggle').nd.onClick(() => isVisible.toggle()),
|
|
466
|
+
ShowIf(isVisible, () =>
|
|
467
|
+
P(message).nd.onClick(() => message.set('Clicked!'))
|
|
468
|
+
)
|
|
469
|
+
]);
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## Next Steps
|
|
475
|
+
|
|
476
|
+
- **[Extending NDElement](./extending-native-document-element.md)** - Adding custom methods
|
|
477
|
+
- **[Lifecycle Events](./lifecycle-events.md)** - Mounted, unmounted, beforeUnmount in depth
|
|
478
|
+
- **[Advanced Components](./advanced-components.md)** - Template caching and singleton views
|
|
479
|
+
- **[Memory Management](./memory-management.md)** - Cleanup and auto-cleanup
|
|
480
|
+
- **[Observables](./observables.md)** - Reactive state management
|
|
481
|
+
- **[Anchor](./anchor.md)** - Anchor
|
|
482
|
+
|
|
483
|
+
## Utilities
|
|
484
|
+
|
|
485
|
+
- **[Cache](./cache.md)** - Lazy initialization and singleton patterns
|
|
486
|
+
- **[NativeFetch](./native-fetch.md)** - HTTP client with interceptors
|
|
487
|
+
- **[Filters](./filters.md)** - Data filtering helpers
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: NativeFetch
|
|
3
|
+
description: HTTP client built on the native Fetch API with request and response interceptors
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# NativeFetch
|
|
7
|
+
|
|
8
|
+
NativeFetch is an HTTP client built on top of the native Fetch API. It adds interceptors, a base URL, and automatic JSON handling.
|
|
9
|
+
|
|
10
|
+
```javascript
|
|
11
|
+
import { utils } from 'native-document';
|
|
12
|
+
const { NativeFetch } = utils;
|
|
13
|
+
|
|
14
|
+
// Or
|
|
15
|
+
import { NativeFetch } from 'native-document/utils';
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Creating an Instance
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
const api = new NativeFetch('https://api.example.com');
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## HTTP Methods
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
// GET
|
|
32
|
+
const users = await api.get('/users');
|
|
33
|
+
const user = await api.get('/users/123');
|
|
34
|
+
|
|
35
|
+
// GET with query parameters
|
|
36
|
+
const page = await api.get('/users', { page: 1, limit: 20, sort: 'name' });
|
|
37
|
+
// -> GET /users?page=1&limit=20&sort=name
|
|
38
|
+
|
|
39
|
+
// POST
|
|
40
|
+
const newUser = await api.post('/users', { name: 'Alice', email: 'alice@example.com' });
|
|
41
|
+
|
|
42
|
+
// PUT
|
|
43
|
+
const updated = await api.put('/users/123', { name: 'Alice Updated' });
|
|
44
|
+
|
|
45
|
+
// PATCH
|
|
46
|
+
const patched = await api.patch('/users/123', { status: 'active' });
|
|
47
|
+
|
|
48
|
+
// DELETE
|
|
49
|
+
await api.delete('/users/123');
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Interceptors
|
|
55
|
+
|
|
56
|
+
### Request interceptors
|
|
57
|
+
|
|
58
|
+
Run before the request is sent:
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
// Add authentication
|
|
62
|
+
api.interceptors.request(config => {
|
|
63
|
+
const token = localStorage.getItem('token');
|
|
64
|
+
if (token) {
|
|
65
|
+
config.headers['Authorization'] = `Bearer ${token}`;
|
|
66
|
+
}
|
|
67
|
+
return config;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Add custom headers
|
|
71
|
+
api.interceptors.request(config => {
|
|
72
|
+
config.headers['X-App-Version'] = '1.0.0';
|
|
73
|
+
return config;
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Response interceptors
|
|
78
|
+
|
|
79
|
+
Run after the response is received:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
// Handle 401
|
|
83
|
+
api.interceptors.response(response => {
|
|
84
|
+
if (response.status === 401) {
|
|
85
|
+
Store.get('auth').set({ user: null, token: null, isLoggedIn: false });
|
|
86
|
+
window.location.href = '/login';
|
|
87
|
+
}
|
|
88
|
+
return response;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Unwrap data envelope
|
|
92
|
+
api.interceptors.response(response => {
|
|
93
|
+
if (response.data?.result) {
|
|
94
|
+
return { ...response, data: response.data.result };
|
|
95
|
+
}
|
|
96
|
+
return response;
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Multiple interceptors run in the order they were registered.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Practical Example - API Service Layer
|
|
105
|
+
|
|
106
|
+
Combine with `Cache` for a clean service pattern:
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
import { Cache, NativeFetch } from 'native-document/utils';
|
|
110
|
+
import { Store } from 'native-document';
|
|
111
|
+
|
|
112
|
+
// Singleton API client
|
|
113
|
+
const getAPI = Cache.singleton(() => {
|
|
114
|
+
const client = new NativeFetch('https://api.example.com');
|
|
115
|
+
|
|
116
|
+
client.interceptors.request(config => {
|
|
117
|
+
const token = Store.get('auth').$value?.token;
|
|
118
|
+
if (token) {
|
|
119
|
+
config.headers['Authorization'] = `Bearer ${token}`;
|
|
120
|
+
}
|
|
121
|
+
return config;
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
client.interceptors.response(response => {
|
|
125
|
+
if (response.status === 401) {
|
|
126
|
+
Store.reset('auth');
|
|
127
|
+
Router.push({ name: 'login' });
|
|
128
|
+
}
|
|
129
|
+
return response;
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return client;
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Resource endpoints via memoize
|
|
136
|
+
const API = Cache.memoize(resource => {
|
|
137
|
+
const client = getAPI();
|
|
138
|
+
return {
|
|
139
|
+
list: (params = {}) => client.get(`/${resource}`, params),
|
|
140
|
+
get: (id) => client.get(`/${resource}/${id}`),
|
|
141
|
+
create: (data) => client.post(`/${resource}`, data),
|
|
142
|
+
update: (id, data) => client.put(`/${resource}/${id}`, data),
|
|
143
|
+
delete: (id) => client.delete(`/${resource}/${id}`)
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Usage
|
|
148
|
+
const users = await API.users.list({ page: 1 });
|
|
149
|
+
const user = await API.users.get('123');
|
|
150
|
+
const newUser = await API.users.create({ name: 'Alice' });
|
|
151
|
+
await API.users.delete('123');
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Loading State with Observables
|
|
157
|
+
|
|
158
|
+
```javascript
|
|
159
|
+
const isLoading = Observable(false);
|
|
160
|
+
const requestCount = Observable(0);
|
|
161
|
+
|
|
162
|
+
api.interceptors.request(config => {
|
|
163
|
+
requestCount.set(requestCount.val() + 1);
|
|
164
|
+
isLoading.set(true);
|
|
165
|
+
return config;
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
api.interceptors.response(response => {
|
|
169
|
+
const count = requestCount.val() - 1;
|
|
170
|
+
requestCount.set(count);
|
|
171
|
+
if (count === 0) {
|
|
172
|
+
isLoading.set(false);
|
|
173
|
+
}
|
|
174
|
+
return response;
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
ShowIf(isLoading.isTruthy(), Div({ class: 'spinner' }, 'Loading...'))
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Response Format
|
|
183
|
+
|
|
184
|
+
NativeFetch returns a consistent response object:
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
{
|
|
188
|
+
ok: boolean, // true if status 200-299
|
|
189
|
+
status: number, // HTTP status code
|
|
190
|
+
statusText: string, // status message
|
|
191
|
+
headers: Headers, // response headers
|
|
192
|
+
data: any, // parsed JSON body
|
|
193
|
+
url: string // request URL
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Best Practices
|
|
200
|
+
|
|
201
|
+
1. Create a single instance via `Cache.singleton()` - not a new instance per request
|
|
202
|
+
2. Use `Cache.memoize()` for resource-based endpoint collections
|
|
203
|
+
3. Handle authentication and errors in interceptors - not in each call
|
|
204
|
+
4. Use `Promise.all()` for parallel requests instead of sequential awaits
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Next Steps
|
|
209
|
+
|
|
210
|
+
- **[Cache](./cache.md)** - Lazy initialization and singleton patterns
|
|
211
|
+
- **[Filters](./filters.md)** - Data filtering helpers
|
|
212
|
+
- **[State Management](./state-management.md)** - Global state with Store
|
|
213
|
+
- **[Observable Resource](./observable-resource.md)** - Async data with built-in states
|