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,157 @@
|
|
|
1
|
+
import ObservableItem from '../../data/ObservableItem';
|
|
2
|
+
import { NDElement } from '../NDElement';
|
|
3
|
+
import TemplateBinding from '../TemplateBinding';
|
|
4
|
+
import { ElementCreator } from '../ElementCreator';
|
|
5
|
+
import PluginsManager from '../../utils/plugins-manager';
|
|
6
|
+
import ObservableChecker from '../../data/ObservableChecker';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extends a prototype with a non-enumerable, configurable, writable property.
|
|
10
|
+
*
|
|
11
|
+
* @param {Function} Constructor - The constructor whose prototype to extend
|
|
12
|
+
* @param {string} name - Property name
|
|
13
|
+
* @param {Function} fn - Implementation
|
|
14
|
+
*/
|
|
15
|
+
function extendsPrototype(Constructor, name, fn) {
|
|
16
|
+
Object.defineProperty(Constructor.prototype, name, {
|
|
17
|
+
value: fn,
|
|
18
|
+
enumerable: false,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// -- Static assignment (not a prototype method) -------------------------------
|
|
25
|
+
|
|
26
|
+
NDElement.$getChild = ElementCreator.getChild;
|
|
27
|
+
|
|
28
|
+
// -- toNdElement --------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Converts a string to a static text node.
|
|
32
|
+
* @returns {Text}
|
|
33
|
+
*/
|
|
34
|
+
extendsPrototype(Object, 'toNdElement', function() {
|
|
35
|
+
return ElementCreator.createStaticTextNode(null, JSON.stringify(this));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Converts a string to a static text node.
|
|
40
|
+
* @returns {Text}
|
|
41
|
+
*/
|
|
42
|
+
extendsPrototype(String, 'toNdElement', function() {
|
|
43
|
+
return ElementCreator.createStaticTextNode(null, this);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Converts a number to a static text node.
|
|
48
|
+
* @returns {Text}
|
|
49
|
+
*/
|
|
50
|
+
extendsPrototype(Number, 'toNdElement', function() {
|
|
51
|
+
return ElementCreator.createStaticTextNode(null, this.toString());
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Returns the element itself (identity for DOM compatibility).
|
|
56
|
+
* @returns {Element}
|
|
57
|
+
*/
|
|
58
|
+
extendsPrototype(Element, 'toNdElement', function() {
|
|
59
|
+
return this;
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Returns the text node itself (identity for DOM compatibility).
|
|
64
|
+
* @returns {Text}
|
|
65
|
+
*/
|
|
66
|
+
extendsPrototype(Text, 'toNdElement', function() {
|
|
67
|
+
return this;
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Returns the comment node itself (identity for DOM compatibility).
|
|
72
|
+
* @returns {Comment}
|
|
73
|
+
*/
|
|
74
|
+
extendsPrototype(Comment, 'toNdElement', function() {
|
|
75
|
+
return this;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns the document itself (identity for DOM compatibility).
|
|
80
|
+
* @returns {Document}
|
|
81
|
+
*/
|
|
82
|
+
extendsPrototype(Document, 'toNdElement', function() {
|
|
83
|
+
return this;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Returns the document fragment itself (identity for DOM compatibility).
|
|
88
|
+
* @returns {DocumentFragment}
|
|
89
|
+
*/
|
|
90
|
+
extendsPrototype(DocumentFragment, 'toNdElement', function() {
|
|
91
|
+
return this;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Converts the ObservableItem to a reactive text node that updates automatically when the value changes.
|
|
96
|
+
* @returns {Text}
|
|
97
|
+
*/
|
|
98
|
+
extendsPrototype(ObservableItem, 'toNdElement', function() {
|
|
99
|
+
return ElementCreator.createObservableNode(null, this);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* ObservableChecker shares the same reactive text node behaviour as ObservableItem.
|
|
104
|
+
* @returns {Text}
|
|
105
|
+
*/
|
|
106
|
+
extendsPrototype(ObservableChecker, 'toNdElement', ObservableItem.prototype.toNdElement);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Converts the NDElement to its underlying HTMLElement (or ghost DOM fragment if ghostDom was used).
|
|
110
|
+
* @returns {HTMLElement|DocumentFragment}
|
|
111
|
+
*/
|
|
112
|
+
extendsPrototype(NDElement, 'toNdElement', function() {
|
|
113
|
+
const element = this.$element ?? this.$build?.() ?? this.build?.() ?? null;
|
|
114
|
+
if (this.$attachements) {
|
|
115
|
+
if (!this.$attachements.contains(this.$element)) {
|
|
116
|
+
this.$attachements.append(this.$element);
|
|
117
|
+
}
|
|
118
|
+
return this.$attachements;
|
|
119
|
+
}
|
|
120
|
+
return element;
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Converts the array to a DocumentFragment containing all child elements.
|
|
125
|
+
* Each item is processed through ElementCreator.getChild().
|
|
126
|
+
* @returns {DocumentFragment}
|
|
127
|
+
*/
|
|
128
|
+
extendsPrototype(Array, 'toNdElement', function() {
|
|
129
|
+
const fragment = document.createDocumentFragment();
|
|
130
|
+
for (let i = 0, length = this.length; i < length; i++) {
|
|
131
|
+
const child = ElementCreator.getChild(this[i]);
|
|
132
|
+
if (child === null) continue;
|
|
133
|
+
fragment.appendChild(child);
|
|
134
|
+
}
|
|
135
|
+
return fragment;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Calls the function and converts its return value to a DOM node.
|
|
140
|
+
* Used internally by ElementCreator to process function-based children.
|
|
141
|
+
* @returns {Node}
|
|
142
|
+
*/
|
|
143
|
+
extendsPrototype(Function, 'toNdElement', function() {
|
|
144
|
+
const child = this;
|
|
145
|
+
if (process.env.NODE_ENV === 'development') {
|
|
146
|
+
PluginsManager.emit('BeforeProcessComponent', child);
|
|
147
|
+
}
|
|
148
|
+
return ElementCreator.getChild(child());
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Converts the TemplateBinding to a hydratable DOM node for use in TemplateCloner.
|
|
153
|
+
* @returns {Node}
|
|
154
|
+
*/
|
|
155
|
+
extendsPrototype(TemplateBinding, 'toNdElement', function() {
|
|
156
|
+
return ElementCreator.createHydratableNode(null, this);
|
|
157
|
+
});
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {NDElement} from '../NDElement';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {HTMLElement} el
|
|
5
|
+
* @param {number} timeout
|
|
6
|
+
*/
|
|
7
|
+
const waitForVisualEnd = (el, timeout = 1000) => {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
let isResolved = false;
|
|
10
|
+
|
|
11
|
+
const cleanupAndResolve = (e) => {
|
|
12
|
+
if (e && e.target !== el) return;
|
|
13
|
+
if (isResolved) return;
|
|
14
|
+
|
|
15
|
+
isResolved = true;
|
|
16
|
+
el.removeEventListener('transitionend', cleanupAndResolve);
|
|
17
|
+
el.removeEventListener('animationend', cleanupAndResolve);
|
|
18
|
+
clearTimeout(timer);
|
|
19
|
+
resolve();
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
el.addEventListener('transitionend', cleanupAndResolve);
|
|
23
|
+
el.addEventListener('animationend', cleanupAndResolve);
|
|
24
|
+
|
|
25
|
+
const timer = setTimeout(cleanupAndResolve, timeout);
|
|
26
|
+
|
|
27
|
+
const style = window.getComputedStyle(el);
|
|
28
|
+
const hasTransition = style.transitionDuration !== '0s';
|
|
29
|
+
const hasAnimation = style.animationDuration !== '0s';
|
|
30
|
+
|
|
31
|
+
if (!hasTransition && !hasAnimation) {
|
|
32
|
+
cleanupAndResolve();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Registers a beforeUnmount hook that plays an exit CSS transition before the element is removed.
|
|
39
|
+
* Adds the class `{transitionName}-exit`, waits for the transition/animation to end, then removes it.
|
|
40
|
+
*
|
|
41
|
+
* @param {string} transitionName - CSS class prefix for the exit transition
|
|
42
|
+
* @returns {this}
|
|
43
|
+
* @example
|
|
44
|
+
* Div({ class: 'modal' }).nd.transitionOut('fade');
|
|
45
|
+
* // Adds 'fade-exit' before removal, waits for transitionend/animationend
|
|
46
|
+
*/
|
|
47
|
+
NDElement.prototype.transitionOut = function(transitionName) {
|
|
48
|
+
const exitClass = transitionName + '-exit';
|
|
49
|
+
const el = this.$element;
|
|
50
|
+
this.beforeUnmount('transition-exit', async function() {
|
|
51
|
+
el.classes.add(exitClass);
|
|
52
|
+
await waitForVisualEnd(el);
|
|
53
|
+
el.classes.remove(exitClass);
|
|
54
|
+
});
|
|
55
|
+
return this;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Plays an enter CSS transition when the element is mounted into the DOM.
|
|
60
|
+
* Adds `{transitionName}-enter-from` immediately, then swaps to `{transitionName}-enter-to`
|
|
61
|
+
* on the next animation frame, and cleans up after the transition ends.
|
|
62
|
+
*
|
|
63
|
+
* @param {string} transitionName - CSS class prefix for the enter transition
|
|
64
|
+
* @returns {this}
|
|
65
|
+
* @example
|
|
66
|
+
* Div({ class: 'modal' }).nd.transitionIn('fade');
|
|
67
|
+
* // On mount: adds 'fade-enter-from', then swaps to 'fade-enter-to'
|
|
68
|
+
*/
|
|
69
|
+
NDElement.prototype.transitionIn = function(transitionName) {
|
|
70
|
+
const startClass = transitionName + '-enter-from';
|
|
71
|
+
const endClass = transitionName + '-enter-to';
|
|
72
|
+
|
|
73
|
+
const el = this.$element;
|
|
74
|
+
|
|
75
|
+
el.classes.add(startClass);
|
|
76
|
+
|
|
77
|
+
this.mounted(() => {
|
|
78
|
+
requestAnimationFrame(() => {
|
|
79
|
+
requestAnimationFrame(() => {
|
|
80
|
+
el.classes.remove(startClass);
|
|
81
|
+
el.classes.add(endClass);
|
|
82
|
+
|
|
83
|
+
waitForVisualEnd(el).then(() => {
|
|
84
|
+
el.classes.remove(endClass);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
return this;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Applies both enter and exit transitions to the element.
|
|
94
|
+
* Shorthand for calling .transitionIn(name) and .transitionOut(name).
|
|
95
|
+
*
|
|
96
|
+
* @param {string} transitionName - CSS class prefix for both enter and exit transitions
|
|
97
|
+
* @returns {this}
|
|
98
|
+
* @example
|
|
99
|
+
* Div({}).nd.transition('slide');
|
|
100
|
+
* // On mount: enter transition; on unmount: exit transition
|
|
101
|
+
*/
|
|
102
|
+
NDElement.prototype.transition = function (transitionName) {
|
|
103
|
+
this.transitionIn(transitionName);
|
|
104
|
+
this.transitionOut(transitionName);
|
|
105
|
+
return this;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Immediately applies a CSS animation class to the element.
|
|
110
|
+
* Removes the class automatically once the animation ends.
|
|
111
|
+
*
|
|
112
|
+
* @param {string} animationName - CSS animation class name to add
|
|
113
|
+
* @returns {this}
|
|
114
|
+
* @example
|
|
115
|
+
* Button('Click me').nd.animate('shake');
|
|
116
|
+
* // Adds 'shake' class, removes it when animationend fires
|
|
117
|
+
*/
|
|
118
|
+
NDElement.prototype.animate = function(animationName) {
|
|
119
|
+
const el = this.$element;
|
|
120
|
+
el.classes.add(animationName);
|
|
121
|
+
|
|
122
|
+
waitForVisualEnd(el).then(() => {
|
|
123
|
+
el.classes.remove(animationName);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
return this;
|
|
127
|
+
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import {ElementCreator} from '../ElementCreator';
|
|
2
|
+
import {createTextNode} from '../HtmlElementWrapper';
|
|
3
|
+
import {NDElement} from '../NDElement';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Stores deferred attribute, class, style, and event bindings for a cloneable element.
|
|
7
|
+
* Used internally by TemplateCloner to apply per-instance data to cloned DOM nodes.
|
|
8
|
+
* Not intended for direct use in application code.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
* @constructor
|
|
12
|
+
* @param {HTMLElement} $element - The template element to clone
|
|
13
|
+
*/
|
|
14
|
+
export default function NodeCloner($element) {
|
|
15
|
+
this.$element = $element;
|
|
16
|
+
this.$classes = null;
|
|
17
|
+
this.$styles = null;
|
|
18
|
+
this.$attrs = null;
|
|
19
|
+
this.$ndMethods = null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Attaches a template binding to the element by hydrating it with the specified method.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} methodName - Name of the hydration method to call
|
|
27
|
+
* @param {BindingHydrator} bindingHydrator - Template binding with $hydrate method
|
|
28
|
+
* @returns {HTMLElement} The underlying HTML element
|
|
29
|
+
* @example
|
|
30
|
+
* const onClick = $binder.attach((event, data) => console.log(data));
|
|
31
|
+
* element.nd.attach('onClick', onClick);
|
|
32
|
+
*/
|
|
33
|
+
NDElement.prototype.attach = function(methodName, bindingHydrator) {
|
|
34
|
+
if(typeof bindingHydrator === 'function') {
|
|
35
|
+
const element = this.$element;
|
|
36
|
+
element.nodeCloner = element.nodeCloner || new NodeCloner(element);
|
|
37
|
+
element.nodeCloner.attach(methodName, bindingHydrator);
|
|
38
|
+
return element;
|
|
39
|
+
}
|
|
40
|
+
bindingHydrator.$hydrate(this.$element, methodName);
|
|
41
|
+
return this.$element;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
NodeCloner.prototype.__$isNodeCloner = true;
|
|
45
|
+
|
|
46
|
+
const buildProperties = (cache, properties, data) => {
|
|
47
|
+
for(const key in properties) {
|
|
48
|
+
cache[key] = properties[key].apply(null, data);
|
|
49
|
+
}
|
|
50
|
+
return cache;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Pre-compiles all registered bindings into a sequence of optimised steps.
|
|
55
|
+
* Called once before the first clone operation. Subsequent calls are no-ops.
|
|
56
|
+
*
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
NodeCloner.prototype.resolve = function() {
|
|
60
|
+
if(this.$content) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const steps = [];
|
|
64
|
+
if(this.$ndMethods) {
|
|
65
|
+
const methods = Object.keys(this.$ndMethods);
|
|
66
|
+
if(methods.length === 1) {
|
|
67
|
+
const methodName = methods[0];
|
|
68
|
+
const callback = this.$ndMethods[methodName];
|
|
69
|
+
steps.push((clonedNode, data) => {
|
|
70
|
+
clonedNode.nd[methodName](callback.bind(clonedNode, ...data));
|
|
71
|
+
});
|
|
72
|
+
} else {
|
|
73
|
+
steps.push((clonedNode, data) => {
|
|
74
|
+
const nd = clonedNode.nd;
|
|
75
|
+
for(const methodName in this.$ndMethods) {
|
|
76
|
+
nd[methodName](this.$ndMethods[methodName].bind(clonedNode, ...data));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if(this.$classes) {
|
|
82
|
+
const cache = {};
|
|
83
|
+
const keys = Object.keys(this.$classes);
|
|
84
|
+
|
|
85
|
+
if(keys.length === 1) {
|
|
86
|
+
const key = keys[0];
|
|
87
|
+
const callback = this.$classes[key];
|
|
88
|
+
steps.push((clonedNode, data) => {
|
|
89
|
+
cache[key] = callback.apply(null, data);
|
|
90
|
+
ElementCreator.processClassAttribute(clonedNode, cache);
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
steps.push((clonedNode, data) => {
|
|
94
|
+
ElementCreator.processClassAttribute(clonedNode, buildProperties(cache, this.$classes, data));
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if(this.$styles) {
|
|
99
|
+
const cache = {};
|
|
100
|
+
const keys = Object.keys(this.$styles);
|
|
101
|
+
|
|
102
|
+
if(keys.length === 1) {
|
|
103
|
+
const key = keys[0];
|
|
104
|
+
const callback = this.$styles[key];
|
|
105
|
+
steps.push((clonedNode, data) => {
|
|
106
|
+
cache[key] = callback.apply(null, data);
|
|
107
|
+
ElementCreator.processStyleAttribute(clonedNode, cache);
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
steps.push((clonedNode, data) => {
|
|
111
|
+
ElementCreator.processStyleAttribute(clonedNode, buildProperties(cache, this.$styles, data));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if(this.$attrs) {
|
|
116
|
+
const cache = {};
|
|
117
|
+
const keys = Object.keys(this.$attrs);
|
|
118
|
+
|
|
119
|
+
if(keys.length === 1) {
|
|
120
|
+
const key = keys[0];
|
|
121
|
+
const callback = this.$attrs[key];
|
|
122
|
+
steps.push((clonedNode, data) => {
|
|
123
|
+
cache[key] = callback.apply(null, data);
|
|
124
|
+
ElementCreator.processAttributes(clonedNode, cache);
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
steps.push((clonedNode, data) => {
|
|
128
|
+
ElementCreator.processAttributes(clonedNode, buildProperties(cache, this.$attrs, data));
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const stepsCount = steps.length;
|
|
134
|
+
const $element = this.$element;
|
|
135
|
+
|
|
136
|
+
this.cloneNode = (data) => {
|
|
137
|
+
const clonedNode = $element.cloneNode(false);
|
|
138
|
+
for(let i = 0; i < stepsCount; i++) {
|
|
139
|
+
steps[i](clonedNode, data);
|
|
140
|
+
}
|
|
141
|
+
return clonedNode;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Clones the template element and applies all compiled binding steps with the given data.
|
|
147
|
+
*
|
|
148
|
+
* @internal
|
|
149
|
+
* @param {Array} data - Data array passed to each binding callback
|
|
150
|
+
* @returns {HTMLElement} The cloned and hydrated element
|
|
151
|
+
*/
|
|
152
|
+
NodeCloner.prototype.cloneNode = function(data) {
|
|
153
|
+
return this.$element.cloneNode(false);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Registers an NDElement method binding (e.g. onClick, onInput) to be applied on each clone.
|
|
158
|
+
*
|
|
159
|
+
* @internal
|
|
160
|
+
* @param {string} methodName - Name of the NDElement method to call (e.g. 'onClick')
|
|
161
|
+
* @param {Function} callback - Callback function to pass to the method
|
|
162
|
+
* @returns {NodeCloner} this
|
|
163
|
+
*/
|
|
164
|
+
NodeCloner.prototype.attach = function(methodName, callback) {
|
|
165
|
+
this.$ndMethods = this.$ndMethods || {};
|
|
166
|
+
this.$ndMethods[methodName] = callback;
|
|
167
|
+
return this;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Registers a reactive text content binding for the element.
|
|
172
|
+
*
|
|
173
|
+
* @internal
|
|
174
|
+
* @param {Function} valueorProperty - Function receiving data and returning the text content
|
|
175
|
+
* @returns {NodeCloner} this
|
|
176
|
+
*/
|
|
177
|
+
NodeCloner.prototype.text = function(valueorProperty) {
|
|
178
|
+
this.$content = valueorProperty;
|
|
179
|
+
if(typeof valueorProperty === 'function') {
|
|
180
|
+
this.cloneNode = (data) => createTextNode(valueorProperty.apply(null, data));
|
|
181
|
+
return this;
|
|
182
|
+
}
|
|
183
|
+
this.cloneNode = (data) => createTextNode(data[0][valueorProperty]);
|
|
184
|
+
return this;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Registers an attribute binding to be applied on each clone.
|
|
189
|
+
*
|
|
190
|
+
* @internal
|
|
191
|
+
* @param {string} attrName - Attribute name
|
|
192
|
+
* @param {{property: string, value: *}} value - Function receiving data and returning the attribute value
|
|
193
|
+
* @returns {NodeCloner} this
|
|
194
|
+
*/
|
|
195
|
+
NodeCloner.prototype.attr = function(attrName, value) {
|
|
196
|
+
if(attrName === 'class') {
|
|
197
|
+
this.$classes = this.$classes || {};
|
|
198
|
+
this.$classes[value.property] = value.value;
|
|
199
|
+
return this;
|
|
200
|
+
}
|
|
201
|
+
if(attrName === 'style') {
|
|
202
|
+
this.$styles = this.$styles || {};
|
|
203
|
+
this.$styles[value.property] = value.value;
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
206
|
+
this.$attrs = this.$attrs || {};
|
|
207
|
+
this.$attrs[attrName] = value.value;
|
|
208
|
+
return this;
|
|
209
|
+
};
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import TemplateBinding from '../TemplateBinding';
|
|
2
|
+
import { $hydrateFn} from './utils';
|
|
3
|
+
import NodeCloner from './NodeCloner';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a high-performance template cloner for repeated rendering of the same structure.
|
|
7
|
+
* On the first call, builds the template by calling $fn with a binder object.
|
|
8
|
+
* On subsequent calls, clones the compiled template and hydrates it with new data.
|
|
9
|
+
* Used internally by ForEachArray and other list renderers.
|
|
10
|
+
*
|
|
11
|
+
* @constructor
|
|
12
|
+
* @param {(binder: TemplateCloner) => HTMLElement} $fn - Function that builds the template using binder methods
|
|
13
|
+
* @example
|
|
14
|
+
* const cloner = new TemplateCloner((t) =>
|
|
15
|
+
* Div({},
|
|
16
|
+
* Span(t.text((item) => item.name)),
|
|
17
|
+
* Button({}, 'Delete').nd.onClick(t.event((item) => () => list.removeItem(item)))
|
|
18
|
+
* )
|
|
19
|
+
* );
|
|
20
|
+
* cloner.clone([item]); // returns a hydrated clone
|
|
21
|
+
*/
|
|
22
|
+
export function TemplateCloner($fn) {
|
|
23
|
+
let $node = null;
|
|
24
|
+
|
|
25
|
+
const assignClonerToNode = ($node) => {
|
|
26
|
+
const childNodes = $node.childNodes;
|
|
27
|
+
let containDynamicNode = !!$node.nodeCloner;
|
|
28
|
+
const childNodesLength = childNodes.length;
|
|
29
|
+
for(let i = 0; i < childNodesLength; i++) {
|
|
30
|
+
const child = childNodes[i];
|
|
31
|
+
if(child.nodeCloner) {
|
|
32
|
+
containDynamicNode = true;
|
|
33
|
+
}
|
|
34
|
+
const localContainDynamicNode = assignClonerToNode(child);
|
|
35
|
+
if(localContainDynamicNode) {
|
|
36
|
+
containDynamicNode = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if(!containDynamicNode) {
|
|
41
|
+
$node.dynamicCloneNode = $node.cloneNode.bind($node, true);
|
|
42
|
+
} else {
|
|
43
|
+
if($node.nodeCloner) {
|
|
44
|
+
$node.nodeCloner.resolve();
|
|
45
|
+
$node.dynamicCloneNode = (data) => {
|
|
46
|
+
const clonedNode = $node.nodeCloner.cloneNode(data);
|
|
47
|
+
for(let i = 0; i < childNodesLength; i++) {
|
|
48
|
+
clonedNode.appendChild(childNodes[i].dynamicCloneNode(data));
|
|
49
|
+
}
|
|
50
|
+
return clonedNode;
|
|
51
|
+
};
|
|
52
|
+
} else {
|
|
53
|
+
$node.dynamicCloneNode = (data) => {
|
|
54
|
+
const clonedNode = $node.cloneNode();
|
|
55
|
+
for(let i = 0; i < childNodesLength; i++) {
|
|
56
|
+
clonedNode.appendChild(childNodes[i].dynamicCloneNode(data));
|
|
57
|
+
}
|
|
58
|
+
return clonedNode;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return containDynamicNode;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Clones the compiled template and hydrates it with the given data.
|
|
69
|
+
* On the first call, also compiles the template (builds and optimizes binding steps).
|
|
70
|
+
*
|
|
71
|
+
* @param {Array} data - Data array passed to all binding callbacks
|
|
72
|
+
* @returns {HTMLElement} Cloned and hydrated DOM node
|
|
73
|
+
*/
|
|
74
|
+
this.clone = (data) => {
|
|
75
|
+
const binder = createTemplateCloner(this);
|
|
76
|
+
$node = $fn(binder);
|
|
77
|
+
if(!$node.nodeCloner) {
|
|
78
|
+
$node.nodeCloner = new NodeCloner($node);
|
|
79
|
+
}
|
|
80
|
+
assignClonerToNode($node);
|
|
81
|
+
this.clone = $node.dynamicCloneNode;
|
|
82
|
+
return $node.dynamicCloneNode(data);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
const createBinding = (hydrateFunction, targetType) => {
|
|
87
|
+
return new TemplateBinding((element, property) => {
|
|
88
|
+
$hydrateFn(hydrateFunction, targetType, element, property);
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Creates a style binding — the result of fn(data) is applied as inline styles.
|
|
94
|
+
*
|
|
95
|
+
* @param {((...data: any[]) => Record<string, string>)} fn - Function returning a style object
|
|
96
|
+
* @returns {TemplateBinding}
|
|
97
|
+
*/
|
|
98
|
+
this.style = (fn) => {
|
|
99
|
+
return createBinding(fn, 'style');
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Creates a class binding — the result of fn(data) is applied as a class map.
|
|
104
|
+
*
|
|
105
|
+
* @param {((...data: any[]) => Record<string, boolean>)} fn - Function returning a class map
|
|
106
|
+
* @returns {TemplateBinding}
|
|
107
|
+
*/
|
|
108
|
+
this.class = (fn) => {
|
|
109
|
+
return createBinding(fn, 'class');
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
this.property = (propertyName) => {
|
|
113
|
+
return this.value(propertyName);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Creates a text/value binding — the result is set as text content or input value.
|
|
118
|
+
* Alias: .text()
|
|
119
|
+
*
|
|
120
|
+
* @param {string|(((...data: any[]) => string))} callbackOrProperty - Property name (string) or callback returning the value
|
|
121
|
+
* @returns {TemplateBinding}
|
|
122
|
+
*/
|
|
123
|
+
this.value = (callbackOrProperty) => {
|
|
124
|
+
return createBinding(callbackOrProperty, 'value');
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Alias for .value() — creates a text content binding.
|
|
129
|
+
*
|
|
130
|
+
* @param {string|(((...data: any[]) => string))} callbackOrProperty
|
|
131
|
+
* @returns {TemplateBinding}
|
|
132
|
+
*/
|
|
133
|
+
this.text = this.value;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Creates an attribute binding — the result of fn(data) is set as an attribute value.
|
|
137
|
+
*
|
|
138
|
+
* @param {((...data: any[]) => string)} fn - Function returning the attribute value
|
|
139
|
+
* @returns {TemplateBinding}
|
|
140
|
+
*/
|
|
141
|
+
this.attr = (fn) => {
|
|
142
|
+
return createBinding(fn, 'attributes');
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates an event binding — fn(data) returns the event handler to attach.
|
|
147
|
+
*
|
|
148
|
+
* @param {((...data: any[]) => EventListener)} fn - Function returning the event callback
|
|
149
|
+
* @returns {TemplateBinding}
|
|
150
|
+
*/
|
|
151
|
+
this.attach = (fn) => {
|
|
152
|
+
return createBinding(fn, 'attach');
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
this.callback = this.attach;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
const createTemplateCloner = ($binder) => {
|
|
160
|
+
return new Proxy($binder, {
|
|
161
|
+
get(target, prop) {
|
|
162
|
+
if(prop in target) {
|
|
163
|
+
return target[prop];
|
|
164
|
+
}
|
|
165
|
+
if (typeof prop === 'symbol') return target[prop];
|
|
166
|
+
return target.value(prop);
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export function useCache(fn) {
|
|
172
|
+
let $cache = null;
|
|
173
|
+
|
|
174
|
+
let wrapper = (args) => {
|
|
175
|
+
$cache = new TemplateCloner(fn);
|
|
176
|
+
|
|
177
|
+
const node = $cache.clone(args);
|
|
178
|
+
wrapper = $cache.clone;
|
|
179
|
+
return node;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
if(fn.length < 2) {
|
|
183
|
+
return (...args) => {
|
|
184
|
+
return wrapper(args);
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return (_, __, ...args) => {
|
|
188
|
+
return wrapper([_, __, ...args]);
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export const template = useCache;
|