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,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;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {ElementCreator} from '../ElementCreator';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hydrates a cloned node with all attribute, class, style, and attachment bindings
|
|
5
|
+
* from a compiled BindingData object. Full update path — applies both static attributes
|
|
6
|
+
* and dynamic class/style maps.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
* @param {HTMLElement} node - Cloned DOM node to hydrate
|
|
10
|
+
* @param {BindingData} bindDingData - Pre-compiled binding metadata
|
|
11
|
+
* @param {Array} data - Data array passed to each binding callback
|
|
12
|
+
* @returns {true}
|
|
13
|
+
*/
|
|
14
|
+
export const hydrateFull = (node, bindDingData, data) => {
|
|
15
|
+
const cacheAttributes = bindDingData._cache;
|
|
16
|
+
|
|
17
|
+
for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
|
|
18
|
+
const attr = bindDingData._flatAttributes[i];
|
|
19
|
+
cacheAttributes[attr.name] = attr.value.apply(null, data);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
23
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
24
|
+
cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
ElementCreator.processAttributesDirect(node, cacheAttributes);
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Hydrates only the dynamic class and style bindings on a cloned node.
|
|
33
|
+
* Used when there are no static attribute bindings.
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
36
|
+
* @param {HTMLElement} node - Cloned DOM node to hydrate
|
|
37
|
+
* @param {BindingData} bindDingData - Pre-compiled binding metadata
|
|
38
|
+
* @param {Array} data - Data array passed to each binding callback
|
|
39
|
+
* @returns {true}
|
|
40
|
+
*/
|
|
41
|
+
export const hydrateDynamic = (node, bindDingData, data) => {
|
|
42
|
+
const cacheAttributes = bindDingData._cache;
|
|
43
|
+
|
|
44
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
45
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
46
|
+
cacheAttributes[dyn.name][dyn.key] = dyn.value.apply(null, data);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
ElementCreator.processClassAttribute(node, cacheAttributes.class);
|
|
50
|
+
ElementCreator.processStyleAttribute(node, cacheAttributes.style);
|
|
51
|
+
return true;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Hydrates only the dynamic class bindings on a cloned node.
|
|
56
|
+
*
|
|
57
|
+
* @internal
|
|
58
|
+
* @param {HTMLElement} node - Cloned DOM node to hydrate
|
|
59
|
+
* @param {BindingData} bindDingData - Pre-compiled binding metadata
|
|
60
|
+
* @param {Array} data - Data array passed to each binding callback
|
|
61
|
+
* @returns {true}
|
|
62
|
+
*/
|
|
63
|
+
export const hydrateClassAttribute = (node, bindDingData, data) => {
|
|
64
|
+
const classAttributes = bindDingData._cache.class;
|
|
65
|
+
|
|
66
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
67
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
68
|
+
classAttributes[dyn.key] = dyn.value.apply(null, data);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
ElementCreator.processClassAttribute(node, classAttributes);
|
|
72
|
+
return true;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Hydrates only the dynamic style bindings on a cloned node.
|
|
77
|
+
*
|
|
78
|
+
* @internal
|
|
79
|
+
* @param {HTMLElement} node - Cloned DOM node to hydrate
|
|
80
|
+
* @param {BindingData} bindDingData - Pre-compiled binding metadata
|
|
81
|
+
* @param {Array} data - Data array passed to each binding callback
|
|
82
|
+
* @returns {true}
|
|
83
|
+
*/
|
|
84
|
+
export const hydrateStyleAttribute = (node, bindDingData, data) => {
|
|
85
|
+
const styleAttributes = bindDingData._cache;
|
|
86
|
+
|
|
87
|
+
for(let i = 0, length = bindDingData._flatDynamiqueLength; i < length; i++) {
|
|
88
|
+
const dyn = bindDingData._flatDynamique[i];
|
|
89
|
+
styleAttributes[dyn.key] = dyn.value.apply(null, data);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
ElementCreator.processStyleAttribute(node, styleAttributes);
|
|
93
|
+
return true;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Hydrates only the static attribute bindings on a cloned node.
|
|
98
|
+
*
|
|
99
|
+
* @internal
|
|
100
|
+
* @param {HTMLElement} node - Cloned DOM node to hydrate
|
|
101
|
+
* @param {BindingData} bindDingData - Pre-compiled binding metadata
|
|
102
|
+
* @param {Array} data - Data array passed to each binding callback
|
|
103
|
+
* @returns {true}
|
|
104
|
+
*/
|
|
105
|
+
export const hydrateAttributes = (node, bindDingData, data) => {
|
|
106
|
+
const cacheAttributes = bindDingData._cache;
|
|
107
|
+
|
|
108
|
+
for(let i = 0, length = bindDingData._flatAttributesLength; i < length; i++) {
|
|
109
|
+
const attr = bindDingData._flatAttributes[i];
|
|
110
|
+
cacheAttributes[attr.name] = attr.value.apply(null, data);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
ElementCreator.processAttributesDirect(node, cacheAttributes);
|
|
114
|
+
return true;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Selects and returns the most efficient hydration function for the given BindingData.
|
|
119
|
+
* Called once during template compilation to assign the optimal update path.
|
|
120
|
+
*
|
|
121
|
+
* @internal
|
|
122
|
+
* @param {BindingData} bindDingData - Pre-compiled binding metadata
|
|
123
|
+
* @returns {Function} One of: hydrateFull, hydrateDynamic, hydrateClassAttribute, hydrateStyleAttribute, hydrateAttributes, or noUpdate
|
|
124
|
+
*/
|
|
125
|
+
export const getHydrator = (bindDingData) => {
|
|
126
|
+
if(!bindDingData._cache) {
|
|
127
|
+
return noUpdate;
|
|
128
|
+
}
|
|
129
|
+
if(bindDingData._flatAttributesLength && bindDingData._flatDynamiqueLength) {
|
|
130
|
+
return hydrateFull;
|
|
131
|
+
}
|
|
132
|
+
if(bindDingData._flatAttributesLength) {
|
|
133
|
+
return hydrateAttributes;
|
|
134
|
+
}
|
|
135
|
+
if(bindDingData._hasClassAttribute && bindDingData._hasStyleAttribute) {
|
|
136
|
+
return hydrateDynamic;
|
|
137
|
+
}
|
|
138
|
+
if(bindDingData._hasClassAttribute) {
|
|
139
|
+
return hydrateClassAttribute;
|
|
140
|
+
}
|
|
141
|
+
return hydrateStyleAttribute;
|
|
142
|
+
};
|