@studiometa/js-toolkit 4.0.0-alpha.1 → 4.0.0-alpha.3
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/README.md +10 -0
- package/dist/Base.d.ts +0 -2
- package/dist/Base.js +1 -2
- package/dist/Base.js.map +1 -1
- package/dist/attribute-namespaces.d.ts +0 -2
- package/dist/attribute-namespaces.js +1 -2
- package/dist/attributes.d.ts +0 -2
- package/dist/attributes.js +1 -2
- package/dist/children-watchers.d.ts +0 -2
- package/dist/children-watchers.js +1 -2
- package/dist/component-brand.d.ts +0 -2
- package/dist/component-brand.js +1 -2
- package/dist/component-declarations.d.ts +0 -2
- package/dist/component-declarations.js +1 -2
- package/dist/context-subscription.d.ts +0 -2
- package/dist/context-subscription.js +1 -2
- package/dist/context.d.ts +0 -2
- package/dist/context.js +1 -2
- package/dist/decorators.d.ts +0 -2
- package/dist/decorators.js +1 -2
- package/dist/diagnostic-contract.d.ts +0 -2
- package/dist/diagnostic-contract.js +1 -2
- package/dist/diagnostics.d.ts +0 -2
- package/dist/diagnostics.js +1 -2
- package/dist/document-order.d.ts +0 -2
- package/dist/document-order.js +1 -2
- package/dist/dom-mutations.d.ts +0 -2
- package/dist/dom-mutations.js +1 -2
- package/dist/events.d.ts +0 -2
- package/dist/events.js +1 -2
- package/dist/group.d.ts +0 -2
- package/dist/group.js +1 -2
- package/dist/instances.d.ts +0 -2
- package/dist/instances.js +1 -2
- package/dist/manifest.d.ts +0 -2
- package/dist/manifest.js +1 -2
- package/dist/mount-strategies.d.ts +0 -2
- package/dist/mount-strategies.js +1 -2
- package/dist/negotiated-events.d.ts +0 -2
- package/dist/negotiated-events.js +1 -2
- package/dist/protocol-symbols.d.ts +0 -2
- package/dist/protocol-symbols.js +1 -2
- package/dist/registry.d.ts +0 -2
- package/dist/registry.js +1 -2
- package/dist/responsive-options.d.ts +0 -2
- package/dist/responsive-options.js +1 -2
- package/dist/scheduler.d.ts +0 -2
- package/dist/scheduler.js +1 -2
- package/dist/scheduler.js.map +1 -1
- package/dist/services/breakpoint.d.ts +0 -2
- package/dist/services/breakpoint.js +1 -2
- package/dist/services/drag.d.ts +0 -2
- package/dist/services/drag.js +1 -2
- package/dist/services/in-view.d.ts +0 -2
- package/dist/services/in-view.js +1 -2
- package/dist/services/key.d.ts +0 -2
- package/dist/services/key.js +1 -2
- package/dist/services/media.d.ts +0 -2
- package/dist/services/media.js +1 -2
- package/dist/services/mixin.d.ts +0 -2
- package/dist/services/mixin.js +1 -2
- package/dist/services/mutation.d.ts +0 -2
- package/dist/services/mutation.js +1 -2
- package/dist/services/pointer.d.ts +0 -2
- package/dist/services/pointer.js +1 -2
- package/dist/services/raf.d.ts +0 -2
- package/dist/services/raf.js +1 -2
- package/dist/services/resize.d.ts +0 -2
- package/dist/services/resize.js +1 -2
- package/dist/services/scroll-progress-offset.d.ts +0 -2
- package/dist/services/scroll-progress-offset.js +1 -2
- package/dist/services/scroll-progress.d.ts +0 -2
- package/dist/services/scroll-progress.js +1 -2
- package/dist/services/scroll.d.ts +0 -2
- package/dist/services/scroll.js +1 -2
- package/dist/services/service.d.ts +0 -2
- package/dist/services/service.js +1 -2
- package/dist/services/toggle.d.ts +0 -2
- package/dist/services/toggle.js +1 -2
- package/dist/services/until.d.ts +0 -2
- package/dist/services/until.js +1 -2
- package/dist/shared-runtime.d.ts +0 -2
- package/dist/shared-runtime.js +1 -2
- package/dist/storage/createStorage.d.ts +0 -2
- package/dist/storage/createStorage.js +1 -2
- package/dist/storage/index.d.ts +0 -2
- package/dist/storage/index.js +1 -2
- package/dist/storage/providers.d.ts +0 -2
- package/dist/storage/providers.js +1 -2
- package/dist/storage/serializers.d.ts +0 -2
- package/dist/storage/serializers.js +1 -2
- package/dist/storage/sync.d.ts +0 -2
- package/dist/storage/sync.js +1 -2
- package/dist/storage/types.d.ts +0 -2
- package/dist/subpaths/BREAKPOINTS.js +1 -2
- package/dist/subpaths/Base.js +1 -2
- package/dist/subpaths/DIAGNOSTICS.js +1 -2
- package/dist/subpaths/DRAG_MODES.js +1 -2
- package/dist/subpaths/EVENTS.js +1 -2
- package/dist/subpaths/MOUNT_ATTRIBUTE.js +1 -2
- package/dist/subpaths/SWAP_MODES.js +1 -2
- package/dist/subpaths/children.js +1 -2
- package/dist/subpaths/component.js +1 -2
- package/dist/subpaths/createContext.js +1 -2
- package/dist/subpaths/createFallbackProvider.js +1 -2
- package/dist/subpaths/createGroup.js +1 -2
- package/dist/subpaths/createLocalStorage.js +1 -2
- package/dist/subpaths/createMemoryStorageProvider.js +1 -2
- package/dist/subpaths/createService.js +1 -2
- package/dist/subpaths/createServiceMixin.js +1 -2
- package/dist/subpaths/createSessionStorage.js +1 -2
- package/dist/subpaths/createStorage.js +1 -2
- package/dist/subpaths/createUrlSearchParamsInHashProvider.js +1 -2
- package/dist/subpaths/createUrlSearchParamsInHashStorage.js +1 -2
- package/dist/subpaths/createUrlSearchParamsProvider.js +1 -2
- package/dist/subpaths/createUrlSearchParamsStorage.js +1 -2
- package/dist/subpaths/defaultScheduler.js +1 -2
- package/dist/subpaths/defineManifest.js +1 -2
- package/dist/subpaths/domUpdate.js +1 -2
- package/dist/subpaths/emitExtendable.js +1 -2
- package/dist/subpaths/fromMetaGlob.js +1 -2
- package/dist/subpaths/fromWebpackContext.js +1 -2
- package/dist/subpaths/getBreakpoints.js +1 -2
- package/dist/subpaths/getInstance.js +1 -2
- package/dist/subpaths/getInstances.js +1 -2
- package/dist/subpaths/getMountedInstances.js +1 -2
- package/dist/subpaths/getUnmountedInstances.js +1 -2
- package/dist/subpaths/inject.js +1 -2
- package/dist/subpaths/injectContext.js +1 -2
- package/dist/subpaths/injectContextSync.js +1 -2
- package/dist/subpaths/jsonSerializer.js +1 -2
- package/dist/subpaths/localStorageProvider.js +1 -2
- package/dist/subpaths/memoryStorageProvider.js +1 -2
- package/dist/subpaths/namespaceQualifier.js +1 -2
- package/dist/subpaths/nextFrame.js +1 -2
- package/dist/subpaths/on.js +1 -2
- package/dist/subpaths/perTarget.js +1 -2
- package/dist/subpaths/provide.js +1 -2
- package/dist/subpaths/provideContext.js +1 -2
- package/dist/subpaths/provideRootContext.js +1 -2
- package/dist/subpaths/read.js +1 -2
- package/dist/subpaths/registerComponent.js +1 -2
- package/dist/subpaths/registerComponents.js +1 -2
- package/dist/subpaths/registerManifest.js +1 -2
- package/dist/subpaths/reportDiagnostic.js +1 -2
- package/dist/subpaths/sessionStorageProvider.js +1 -2
- package/dist/subpaths/setBreakpoints.js +1 -2
- package/dist/subpaths/signal.js +1 -2
- package/dist/subpaths/subscribeContext.js +1 -2
- package/dist/subpaths/swap.js +1 -2
- package/dist/subpaths/toggle.js +1 -2
- package/dist/subpaths/until.js +1 -2
- package/dist/subpaths/urlSearchParamsInHashProvider.js +1 -2
- package/dist/subpaths/urlSearchParamsProvider.js +1 -2
- package/dist/subpaths/useBreakpoint.js +1 -2
- package/dist/subpaths/useDrag.js +1 -2
- package/dist/subpaths/useInView.js +1 -2
- package/dist/subpaths/useKey.js +1 -2
- package/dist/subpaths/useMediaQuery.js +1 -2
- package/dist/subpaths/useMutation.js +1 -2
- package/dist/subpaths/usePointer.js +1 -2
- package/dist/subpaths/usePrefersReducedMotion.js +1 -2
- package/dist/subpaths/useRaf.js +1 -2
- package/dist/subpaths/useResize.js +1 -2
- package/dist/subpaths/useScroll.js +1 -2
- package/dist/subpaths/useScrollProgress.js +1 -2
- package/dist/subpaths/useWindowScroll.js +1 -2
- package/dist/subpaths/useWindowSize.js +1 -2
- package/dist/subpaths/utils/DEFAULT_DAMP_FACTOR.js +1 -2
- package/dist/subpaths/utils/INERTIA_FRAME.js +1 -2
- package/dist/subpaths/utils/MAX_SPRING_RATIO.js +1 -2
- package/dist/subpaths/utils/SCROLL_ALIGNMENTS.js +1 -2
- package/dist/subpaths/utils/SCROLL_AXES.js +1 -2
- package/dist/subpaths/utils/TRANSFORM_PROPS.js +1 -2
- package/dist/subpaths/utils/TRANSITION_OPTIONS.js +1 -2
- package/dist/subpaths/utils/camelCase.js +1 -2
- package/dist/subpaths/utils/capitalize.js +1 -2
- package/dist/subpaths/utils/clamp.js +1 -2
- package/dist/subpaths/utils/clamp01.js +1 -2
- package/dist/subpaths/utils/clampDampFactor.js +1 -2
- package/dist/subpaths/utils/createEaseInOut.js +1 -2
- package/dist/subpaths/utils/createEaseOut.js +1 -2
- package/dist/subpaths/utils/createElement.js +1 -2
- package/dist/subpaths/utils/createRange.js +1 -2
- package/dist/subpaths/utils/damp.js +1 -2
- package/dist/subpaths/utils/debounce.js +1 -2
- package/dist/subpaths/utils/decayOver.js +1 -2
- package/dist/subpaths/utils/deepmerge.js +1 -2
- package/dist/subpaths/utils/easeInCirc.js +1 -2
- package/dist/subpaths/utils/easeInCubic.js +1 -2
- package/dist/subpaths/utils/easeInExpo.js +1 -2
- package/dist/subpaths/utils/easeInOutCirc.js +1 -2
- package/dist/subpaths/utils/easeInOutCubic.js +1 -2
- package/dist/subpaths/utils/easeInOutExpo.js +1 -2
- package/dist/subpaths/utils/easeInOutQuad.js +1 -2
- package/dist/subpaths/utils/easeInOutQuart.js +1 -2
- package/dist/subpaths/utils/easeInOutQuint.js +1 -2
- package/dist/subpaths/utils/easeInOutSine.js +1 -2
- package/dist/subpaths/utils/easeInQuad.js +1 -2
- package/dist/subpaths/utils/easeInQuart.js +1 -2
- package/dist/subpaths/utils/easeInQuint.js +1 -2
- package/dist/subpaths/utils/easeInSine.js +1 -2
- package/dist/subpaths/utils/easeLinear.js +1 -2
- package/dist/subpaths/utils/easeOutCirc.js +1 -2
- package/dist/subpaths/utils/easeOutCubic.js +1 -2
- package/dist/subpaths/utils/easeOutExpo.js +1 -2
- package/dist/subpaths/utils/easeOutQuad.js +1 -2
- package/dist/subpaths/utils/easeOutQuart.js +1 -2
- package/dist/subpaths/utils/easeOutQuint.js +1 -2
- package/dist/subpaths/utils/easeOutSine.js +1 -2
- package/dist/subpaths/utils/enterTransition.js +1 -2
- package/dist/subpaths/utils/fold.js +1 -2
- package/dist/subpaths/utils/getOffsetSizes.js +1 -2
- package/dist/subpaths/utils/historyPush.js +1 -2
- package/dist/subpaths/utils/historyReplace.js +1 -2
- package/dist/subpaths/utils/inertiaDecay.js +1 -2
- package/dist/subpaths/utils/inertiaFinalValue.js +1 -2
- package/dist/subpaths/utils/inertiaStep.js +1 -2
- package/dist/subpaths/utils/inertiaTimeConstant.js +1 -2
- package/dist/subpaths/utils/isBoolean.js +1 -2
- package/dist/subpaths/utils/isDefined.js +1 -2
- package/dist/subpaths/utils/isFunction.js +1 -2
- package/dist/subpaths/utils/isNull.js +1 -2
- package/dist/subpaths/utils/isNumber.js +1 -2
- package/dist/subpaths/utils/isObject.js +1 -2
- package/dist/subpaths/utils/isString.js +1 -2
- package/dist/subpaths/utils/kebabCase.js +1 -2
- package/dist/subpaths/utils/leaveTransition.js +1 -2
- package/dist/subpaths/utils/lerp.js +1 -2
- package/dist/subpaths/utils/loadImage.js +1 -2
- package/dist/subpaths/utils/loadLink.js +1 -2
- package/dist/subpaths/utils/loadScript.js +1 -2
- package/dist/subpaths/utils/lockScroll.js +1 -2
- package/dist/subpaths/utils/lowerCase.js +1 -2
- package/dist/subpaths/utils/map.js +1 -2
- package/dist/subpaths/utils/matrix.js +1 -2
- package/dist/subpaths/utils/mean.js +1 -2
- package/dist/subpaths/utils/memo.js +1 -2
- package/dist/subpaths/utils/noop.js +1 -2
- package/dist/subpaths/utils/noopValue.js +1 -2
- package/dist/subpaths/utils/objectToURLSearchParams.js +1 -2
- package/dist/subpaths/utils/pascalCase.js +1 -2
- package/dist/subpaths/utils/random.js +1 -2
- package/dist/subpaths/utils/randomInt.js +1 -2
- package/dist/subpaths/utils/randomItem.js +1 -2
- package/dist/subpaths/utils/round.js +1 -2
- package/dist/subpaths/utils/saveActiveElement.js +1 -2
- package/dist/subpaths/utils/scrollPosition.js +1 -2
- package/dist/subpaths/utils/scrollTo.js +1 -2
- package/dist/subpaths/utils/selectorFor.js +1 -2
- package/dist/subpaths/utils/setClassesOrStyles.js +1 -2
- package/dist/subpaths/utils/smoothTo.js +1 -2
- package/dist/subpaths/utils/snakeCase.js +1 -2
- package/dist/subpaths/utils/spring.js +1 -2
- package/dist/subpaths/utils/throttle.js +1 -2
- package/dist/subpaths/utils/transform.js +1 -2
- package/dist/subpaths/utils/transition.js +1 -2
- package/dist/subpaths/utils/trapFocus.js +1 -2
- package/dist/subpaths/utils/untrapFocus.js +1 -2
- package/dist/subpaths/utils/upperCase.js +1 -2
- package/dist/subpaths/utils/wait.js +1 -2
- package/dist/subpaths/utils/withLeadingCharacters.js +1 -2
- package/dist/subpaths/utils/withLeadingSlash.js +1 -2
- package/dist/subpaths/utils/withTrailingCharacters.js +1 -2
- package/dist/subpaths/utils/withTrailingSlash.js +1 -2
- package/dist/subpaths/utils/withoutLeadingCharacters.js +1 -2
- package/dist/subpaths/utils/withoutLeadingCharactersRecursive.js +1 -2
- package/dist/subpaths/utils/withoutLeadingSlash.js +1 -2
- package/dist/subpaths/utils/withoutTrailingCharacters.js +1 -2
- package/dist/subpaths/utils/withoutTrailingCharactersRecursive.js +1 -2
- package/dist/subpaths/utils/withoutTrailingSlash.js +1 -2
- package/dist/subpaths/utils/wrap.js +1 -2
- package/dist/subpaths/viewTransition.js +1 -2
- package/dist/subpaths/warn.js +1 -2
- package/dist/subpaths/watchAttributeNamespace.js +1 -2
- package/dist/subpaths/watchAttributes.js +1 -2
- package/dist/subpaths/whenDOMSettled.js +1 -2
- package/dist/subpaths/withDrag.js +1 -2
- package/dist/subpaths/withInView.js +1 -2
- package/dist/subpaths/withKey.js +1 -2
- package/dist/subpaths/withMutation.js +1 -2
- package/dist/subpaths/withPointer.js +1 -2
- package/dist/subpaths/withRaf.js +1 -2
- package/dist/subpaths/withResize.js +1 -2
- package/dist/subpaths/withScroll.js +1 -2
- package/dist/subpaths/withScrollProgress.js +1 -2
- package/dist/subpaths/write.js +1 -2
- package/dist/swap.d.ts +0 -2
- package/dist/swap.js +1 -2
- package/dist/test/index.d.ts +0 -2
- package/dist/test/index.js +1 -2
- package/dist/utils/deepmerge.d.ts +0 -2
- package/dist/utils/deepmerge.js +1 -2
- package/dist/utils/dom.d.ts +0 -2
- package/dist/utils/dom.js +1 -2
- package/dist/utils/easings.d.ts +0 -2
- package/dist/utils/easings.js +1 -2
- package/dist/utils/focus.d.ts +0 -2
- package/dist/utils/focus.js +1 -2
- package/dist/utils/history.d.ts +0 -2
- package/dist/utils/history.js +1 -2
- package/dist/utils/is.d.ts +0 -2
- package/dist/utils/is.js +1 -2
- package/dist/utils/load.d.ts +0 -2
- package/dist/utils/load.js +1 -2
- package/dist/utils/maths.d.ts +0 -2
- package/dist/utils/maths.js +1 -2
- package/dist/utils/memo.d.ts +0 -2
- package/dist/utils/memo.js +1 -2
- package/dist/utils/noop.d.ts +0 -2
- package/dist/utils/noop.js +1 -2
- package/dist/utils/random.d.ts +0 -2
- package/dist/utils/random.js +1 -2
- package/dist/utils/scroll-lock.d.ts +0 -2
- package/dist/utils/scroll-lock.js +1 -2
- package/dist/utils/scrollTo.d.ts +0 -2
- package/dist/utils/scrollTo.js +1 -2
- package/dist/utils/selectors.d.ts +0 -2
- package/dist/utils/selectors.js +1 -2
- package/dist/utils/smoothTo.d.ts +0 -2
- package/dist/utils/smoothTo.js +1 -2
- package/dist/utils/strings.d.ts +0 -2
- package/dist/utils/strings.js +1 -2
- package/dist/utils/timing.d.ts +0 -2
- package/dist/utils/timing.js +1 -2
- package/dist/utils/transform.d.ts +0 -2
- package/dist/utils/transform.js +1 -2
- package/dist/utils/transition.d.ts +0 -2
- package/dist/utils/transition.js +1 -2
- package/dist/viewTransition.d.ts +0 -2
- package/dist/viewTransition.js +1 -2
- package/package.json +6 -3
- package/skills/studiometa-js-toolkit/SKILL.md +87 -0
- package/skills/studiometa-js-toolkit/references/api/configuration.md +169 -0
- package/skills/studiometa-js-toolkit/references/api/context/createContext.md +46 -0
- package/skills/studiometa-js-toolkit/references/api/context/createGroup.md +67 -0
- package/skills/studiometa-js-toolkit/references/api/context/index.md +69 -0
- package/skills/studiometa-js-toolkit/references/api/context/injectContext.md +58 -0
- package/skills/studiometa-js-toolkit/references/api/context/injectContextSync.md +44 -0
- package/skills/studiometa-js-toolkit/references/api/context/provideContext.md +61 -0
- package/skills/studiometa-js-toolkit/references/api/context/provideRootContext.md +42 -0
- package/skills/studiometa-js-toolkit/references/api/context/signal.md +85 -0
- package/skills/studiometa-js-toolkit/references/api/context/subscribeContext.md +71 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/children.md +92 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/component.md +75 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/index.md +41 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/inject.md +73 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/on.md +149 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/provide.md +77 -0
- package/skills/studiometa-js-toolkit/references/api/decorators/read-write.md +93 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/DIAGNOSTICS.md +137 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/EVENTS.md +45 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/index.md +58 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/reportDiagnostic.md +67 -0
- package/skills/studiometa-js-toolkit/references/api/diagnostics/warn.md +54 -0
- package/skills/studiometa-js-toolkit/references/api/dom/breakpoints.md +81 -0
- package/skills/studiometa-js-toolkit/references/api/dom/domUpdate.md +70 -0
- package/skills/studiometa-js-toolkit/references/api/dom/emitExtendable.md +68 -0
- package/skills/studiometa-js-toolkit/references/api/dom/index.md +26 -0
- package/skills/studiometa-js-toolkit/references/api/dom/swap.md +105 -0
- package/skills/studiometa-js-toolkit/references/api/dom/watchAttributeNamespace.md +96 -0
- package/skills/studiometa-js-toolkit/references/api/dom/watchAttributes.md +56 -0
- package/skills/studiometa-js-toolkit/references/api/dom/whenDOMSettled.md +41 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-component.md +105 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-mount.md +69 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-option.md +106 -0
- package/skills/studiometa-js-toolkit/references/api/html/data-ref.md +63 -0
- package/skills/studiometa-js-toolkit/references/api/html/index.md +32 -0
- package/skills/studiometa-js-toolkit/references/api/index.md +73 -0
- package/skills/studiometa-js-toolkit/references/api/instance-events.md +75 -0
- package/skills/studiometa-js-toolkit/references/api/instance-methods.md +267 -0
- package/skills/studiometa-js-toolkit/references/api/instance-properties.md +90 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-events.md +149 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-lifecycle.md +90 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-options.md +96 -0
- package/skills/studiometa-js-toolkit/references/api/methods-hooks-services.md +164 -0
- package/skills/studiometa-js-toolkit/references/api/registry/defineManifest.md +57 -0
- package/skills/studiometa-js-toolkit/references/api/registry/fromMetaGlob.md +33 -0
- package/skills/studiometa-js-toolkit/references/api/registry/fromWebpackContext.md +37 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getInstance.md +52 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getInstances.md +48 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getMountedInstances.md +39 -0
- package/skills/studiometa-js-toolkit/references/api/registry/getUnmountedInstances.md +46 -0
- package/skills/studiometa-js-toolkit/references/api/registry/index.md +49 -0
- package/skills/studiometa-js-toolkit/references/api/registry/registerComponent.md +93 -0
- package/skills/studiometa-js-toolkit/references/api/registry/registerComponents.md +37 -0
- package/skills/studiometa-js-toolkit/references/api/registry/registerManifest.md +72 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/defaultScheduler.md +104 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/index.md +27 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/nextFrame.md +31 -0
- package/skills/studiometa-js-toolkit/references/api/scheduler/viewTransition.md +53 -0
- package/skills/studiometa-js-toolkit/references/api/services/createService.md +95 -0
- package/skills/studiometa-js-toolkit/references/api/services/createServiceMixin.md +81 -0
- package/skills/studiometa-js-toolkit/references/api/services/index.md +94 -0
- package/skills/studiometa-js-toolkit/references/api/services/mixins.md +148 -0
- package/skills/studiometa-js-toolkit/references/api/services/perTarget.md +65 -0
- package/skills/studiometa-js-toolkit/references/api/services/toggle.md +80 -0
- package/skills/studiometa-js-toolkit/references/api/services/until.md +44 -0
- package/skills/studiometa-js-toolkit/references/api/services/useBreakpoint.md +42 -0
- package/skills/studiometa-js-toolkit/references/api/services/useDrag.md +119 -0
- package/skills/studiometa-js-toolkit/references/api/services/useInView.md +64 -0
- package/skills/studiometa-js-toolkit/references/api/services/useKey.md +105 -0
- package/skills/studiometa-js-toolkit/references/api/services/useMediaQuery.md +45 -0
- package/skills/studiometa-js-toolkit/references/api/services/useMutation.md +69 -0
- package/skills/studiometa-js-toolkit/references/api/services/usePointer.md +91 -0
- package/skills/studiometa-js-toolkit/references/api/services/usePrefersReducedMotion.md +42 -0
- package/skills/studiometa-js-toolkit/references/api/services/useRaf.md +91 -0
- package/skills/studiometa-js-toolkit/references/api/services/useResize.md +60 -0
- package/skills/studiometa-js-toolkit/references/api/services/useScroll.md +88 -0
- package/skills/studiometa-js-toolkit/references/api/services/useScrollProgress.md +88 -0
- package/skills/studiometa-js-toolkit/references/api/services/useWindowScroll.md +25 -0
- package/skills/studiometa-js-toolkit/references/api/services/useWindowSize.md +25 -0
- package/skills/studiometa-js-toolkit/references/api/storage/createStorage.md +126 -0
- package/skills/studiometa-js-toolkit/references/api/storage/index.md +33 -0
- package/skills/studiometa-js-toolkit/references/api/storage/presets.md +58 -0
- package/skills/studiometa-js-toolkit/references/api/storage/providers.md +109 -0
- package/skills/studiometa-js-toolkit/references/api/test/index.md +214 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/attribute-grammar.md +93 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/mutation-engine.md +71 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/philosophy.md +78 -0
- package/skills/studiometa-js-toolkit/references/guide/concepts/the-registry.md +110 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/autoloading.md +104 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/handling-diagnostics.md +104 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/mount-strategies.md +95 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/scheduling-work.md +124 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/sharing-state.md +218 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/swapping-content.md +92 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/testing-components.md +137 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/typing-components.md +190 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/using-decorators.md +168 -0
- package/skills/studiometa-js-toolkit/references/guide/going-further/using-storage.md +125 -0
- package/skills/studiometa-js-toolkit/references/guide/index.md +163 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/installation.md +144 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/lifecycle-hooks.md +174 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/managing-components.md +229 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/managing-options.md +235 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/managing-refs.md +174 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/using-services.md +218 -0
- package/skills/studiometa-js-toolkit/references/guide/introduction/working-with-events.md +251 -0
- package/skills/studiometa-js-toolkit/references/guide/migration/v3-to-v4.md +373 -0
- package/skills/studiometa-js-toolkit/references/utils/css.md +98 -0
- package/skills/studiometa-js-toolkit/references/utils/dom.md +54 -0
- package/skills/studiometa-js-toolkit/references/utils/easings.md +217 -0
- package/skills/studiometa-js-toolkit/references/utils/focus.md +84 -0
- package/skills/studiometa-js-toolkit/references/utils/history.md +69 -0
- package/skills/studiometa-js-toolkit/references/utils/index.md +53 -0
- package/skills/studiometa-js-toolkit/references/utils/is.md +84 -0
- package/skills/studiometa-js-toolkit/references/utils/load.md +59 -0
- package/skills/studiometa-js-toolkit/references/utils/math.md +129 -0
- package/skills/studiometa-js-toolkit/references/utils/motion.md +218 -0
- package/skills/studiometa-js-toolkit/references/utils/objects.md +68 -0
- package/skills/studiometa-js-toolkit/references/utils/scroll.md +128 -0
- package/skills/studiometa-js-toolkit/references/utils/strings.md +176 -0
- package/skills/studiometa-js-toolkit/references/utils/timing.md +111 -0
- package/skills/studiometa-js-toolkit/references/utils/transitions.md +122 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
npm install @studiometa/js-toolkit@next
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
**The `next` tag is not optional yet**
|
|
8
|
+
|
|
9
|
+
4.0 is still a prerelease, so it publishes to the `next` dist-tag. Plain `npm install @studiometa/js-toolkit` installs 3.x, which is a different framework — the tag is what selects this one. `next` becomes `latest` when 4.0.0 ships.
|
|
10
|
+
|
|
11
|
+
## Importing
|
|
12
|
+
|
|
13
|
+
The root barrel carries everything a page normally needs:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import { Base, registerComponent } from '@studiometa/js-toolkit';
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Utilities live on `/utils`:
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
import { clamp, damp } from '@studiometa/js-toolkit/utils';
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Test helpers live on `/test`:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import { mount, settle } from '@studiometa/js-toolkit/test';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### One subpath per export
|
|
32
|
+
|
|
33
|
+
Every public export also has a subpath of its own — 197 of them. The barrel is convenient; the subpath is precise:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import { Base } from '@studiometa/js-toolkit/Base';
|
|
37
|
+
import { useScroll } from '@studiometa/js-toolkit/useScroll';
|
|
38
|
+
import { clamp } from '@studiometa/js-toolkit/utils/clamp';
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Which one to reach for depends on how the code is delivered:
|
|
42
|
+
|
|
43
|
+
- **With a bundler**, prefer the barrel. Tree-shaking removes what you do not import, and the barrel keeps the import lines short.
|
|
44
|
+
- **From an ESM CDN, with no build step**, prefer the subpath. There is no bundler to shake the graph, so a barrel import downloads the barrel's whole module graph before the first line of your code runs.
|
|
45
|
+
|
|
46
|
+
The subpath layout is what keeps a dependency contained. `morphdom` is reachable through [`swap()`](../../api/dom/swap.md) only, so a page that never swaps content never downloads it.
|
|
47
|
+
|
|
48
|
+
## No build step
|
|
49
|
+
|
|
50
|
+
v4 needs no compiler. Every decorator is sugar over a function that works without it, so a page loaded from an ESM CDN keeps the whole framework:
|
|
51
|
+
|
|
52
|
+
```html
|
|
53
|
+
<script type="module">
|
|
54
|
+
import { Base } from 'https://esm.sh/@studiometa/js-toolkit@next/Base';
|
|
55
|
+
import { registerComponent } from 'https://esm.sh/@studiometa/js-toolkit@next/registerComponent';
|
|
56
|
+
|
|
57
|
+
class Counter extends Base {
|
|
58
|
+
static config = { name: 'Counter', refs: ['output'] };
|
|
59
|
+
|
|
60
|
+
count = 0;
|
|
61
|
+
|
|
62
|
+
onClick() {
|
|
63
|
+
this.count += 1;
|
|
64
|
+
this.$refs.output.textContent = String(this.count);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
registerComponent(Counter);
|
|
69
|
+
</script>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## With a build step
|
|
73
|
+
|
|
74
|
+
### Vite
|
|
75
|
+
|
|
76
|
+
Nothing to configure for the framework itself. Vite 8 transforms TypeScript with Oxc, which passes decorators through untouched — so if you use the [decorators](../going-further/using-decorators.md), add a transform that compiles them:
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
// vite.config.js
|
|
80
|
+
import { defineConfig } from 'vite';
|
|
81
|
+
import swc from '@rollup/plugin-swc';
|
|
82
|
+
|
|
83
|
+
export default defineConfig({
|
|
84
|
+
plugins: [
|
|
85
|
+
{
|
|
86
|
+
...swc({ swc: { jsc: { target: 'es2022', transform: { decoratorVersion: '2023-11' } } } }),
|
|
87
|
+
// Compile only the files that contain a decorator.
|
|
88
|
+
enforce: 'pre',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### TypeScript
|
|
95
|
+
|
|
96
|
+
Stage-3 decorators need no flag on TypeScript 5. Turn `experimentalDecorators` **off**:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"compilerOptions": {
|
|
101
|
+
"target": "ES2022",
|
|
102
|
+
"module": "Preserve",
|
|
103
|
+
"moduleResolution": "bundler",
|
|
104
|
+
"experimentalDecorators": false,
|
|
105
|
+
"useDefineForClassFields": true,
|
|
106
|
+
"strict": true
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
See [TypeScript](../going-further/typing-components.md) for how to type a component's refs, options and events.
|
|
112
|
+
|
|
113
|
+
## Autoloading
|
|
114
|
+
|
|
115
|
+
A page that declares its components in the markup does not have to import them all up front. Map each `data-component` token to a dynamic import and the registry downloads a chunk when an element needs it:
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
import { registerManifest } from '@studiometa/js-toolkit';
|
|
119
|
+
|
|
120
|
+
registerManifest({
|
|
121
|
+
Accordion: () => import('./components/Accordion.js'),
|
|
122
|
+
Map: { load: () => import('./components/Map.js'), mountStrategy: 'visible' },
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
See [Autoloading](../going-further/autoloading.md).
|
|
127
|
+
|
|
128
|
+
## Agent skills
|
|
129
|
+
|
|
130
|
+
The package ships the `studiometa-js-toolkit` [agent skill](https://agentskills.io). It teaches coding agents the v4 API and holds the documentation of the installed version, so an agent does not write v3 code. Link it into your project with the [`skills` CLI](https://github.com/vercel-labs/skills):
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npx skills experimental_sync
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The command links the skills of your dependencies from `node_modules` into the agent folders (`.agents/skills/`, `.claude/skills/`…). `@studiometa/ui` asks the CLI for this skill too, so a project that only lists `@studiometa/ui` also gets it.
|
|
137
|
+
|
|
138
|
+
Without npm, install the skills from this website. It publishes them at `/.well-known/agent-skills/index.json`, as the [Agent Skills Discovery](https://specification.website/spec/agent-readiness/agent-skills-discovery/) convention defines:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npx skills add https://js-toolkit-v4.studiometa.dev
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
These skills match the version that this website documents, which can differ from the version that your project installs. Prefer `npx skills experimental_sync` in a project that installs the package.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Lifecycle
|
|
2
|
+
|
|
3
|
+
**`mount` and `unmount` are the whole lifecycle.** There is no third, permanent notion: a component never declares that its work is over, and nothing marks an instance as never mountable again.
|
|
4
|
+
|
|
5
|
+
## The two notions
|
|
6
|
+
|
|
7
|
+
| Notion | What it is | Effect |
|
|
8
|
+
| ---------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
9
|
+
| **disconnected** | The element left the document. | The registry calls `$unmount()`. The instance **stays on its element**, and a re-inserted element mounts it again. |
|
|
10
|
+
| **unmount** | The reversible opposite of mount. | Unbinds the cycle's listeners, runs the `mounted()` cleanups, cancels the scheduled tasks, calls `unmounted()`. |
|
|
11
|
+
|
|
12
|
+
A **move** gives one removal record and one addition record: the instance is unmounted and then mounted again, with the same identity, and the state of the cycle starts over. This is the behaviour of `disconnectedCallback` and `connectedCallback` for custom elements.
|
|
13
|
+
|
|
14
|
+
**Unmounting a parent does not unmount its children.** Each element answers for itself.
|
|
15
|
+
|
|
16
|
+
## `mounted()` and `unmounted()`
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
import { Base } from '@studiometa/js-toolkit';
|
|
20
|
+
|
|
21
|
+
class Player extends Base {
|
|
22
|
+
static config = { name: 'Player' };
|
|
23
|
+
|
|
24
|
+
mounted() {
|
|
25
|
+
console.log('the element is in the document');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
unmounted() {
|
|
29
|
+
console.log('the element left, or the declaration was withdrawn');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## `mounted()` returns its cleanup
|
|
35
|
+
|
|
36
|
+
`mounted()` can return a function, or an array of functions, sync or async. They run on the next `$unmount()`:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import { Base, useScroll } from '@studiometa/js-toolkit';
|
|
40
|
+
|
|
41
|
+
class Header extends Base {
|
|
42
|
+
static config = { name: 'Header' };
|
|
43
|
+
|
|
44
|
+
mounted() {
|
|
45
|
+
// `subscribe()` returns its own unsubscribe — hand it straight back.
|
|
46
|
+
return useScroll().subscribe(({ directionY }) => {
|
|
47
|
+
this.$el.classList.toggle('is-hidden', directionY > 0);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Several cleanups: return an array.
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
import { Base, useResize, useScroll } from '@studiometa/js-toolkit';
|
|
57
|
+
|
|
58
|
+
class Sticky extends Base {
|
|
59
|
+
static config = { name: 'Sticky' };
|
|
60
|
+
|
|
61
|
+
mounted() {
|
|
62
|
+
return [useScroll().subscribe(() => {}), useResize().subscribe(() => {})];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
An async `mounted()` works the same way:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { Base, createContext, type Signal } from '@studiometa/js-toolkit';
|
|
71
|
+
|
|
72
|
+
const CountContext = createContext<Signal<number>>('count');
|
|
73
|
+
|
|
74
|
+
class TodoCount extends Base {
|
|
75
|
+
static config = { name: 'TodoCount' };
|
|
76
|
+
|
|
77
|
+
async mounted() {
|
|
78
|
+
const signal = await this.$inject(CountContext);
|
|
79
|
+
// Released on unmount, even if the await resolved after it.
|
|
80
|
+
return signal.subscribe((count) => {
|
|
81
|
+
this.$el.textContent = String(count);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
If an async `mounted()` resolves **after** the unmount, the cleanup runs immediately.
|
|
88
|
+
|
|
89
|
+
`unmounted()` stays available for the cases the returned cleanup does not fit.
|
|
90
|
+
|
|
91
|
+
## What is unmount-scoped, and what is not
|
|
92
|
+
|
|
93
|
+
| Registered in | Scope | Released by |
|
|
94
|
+
| ----------------------------------------- | ---------------- | ---------------------------------- |
|
|
95
|
+
| a `mounted()` return value | the mount cycle | the next `$unmount()` |
|
|
96
|
+
| a pending `$inject()` request | the mount cycle | the next `$unmount()` |
|
|
97
|
+
| `on<X><Event>` handlers, service mixins | the mount cycle | the next `$unmount()` |
|
|
98
|
+
| `$read()` / `$write()` tasks | the mount cycle | the next `$unmount()` cancels them |
|
|
99
|
+
| `$provide()` in a field initializer | the **instance** | nothing — it dies with the element |
|
|
100
|
+
| `$watchChildren()` in a field initializer | the **instance** | nothing — it dies with the element |
|
|
101
|
+
|
|
102
|
+
A component whose declaration is withdrawn therefore keeps providing context until its element goes.
|
|
103
|
+
|
|
104
|
+
## "Do this once per element"
|
|
105
|
+
|
|
106
|
+
Because `$unmount()` leaves the instance on its element, **a plain field survives every move, re-insertion and `swap()` that preserves the element**. "Once per element" is instance state, not a lifecycle decision:
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
import { Base } from '@studiometa/js-toolkit';
|
|
110
|
+
|
|
111
|
+
class Reveal extends Base {
|
|
112
|
+
static config = { name: 'Reveal' };
|
|
113
|
+
|
|
114
|
+
hasRevealed = false;
|
|
115
|
+
|
|
116
|
+
mounted() {
|
|
117
|
+
if (this.hasRevealed) return;
|
|
118
|
+
this.$el.classList.add('is-revealed');
|
|
119
|
+
this.hasRevealed = true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
What a field does **not** survive is an element that is genuinely replaced — which is exactly when the work should run again.
|
|
125
|
+
|
|
126
|
+
## Withdrawing a declaration
|
|
127
|
+
|
|
128
|
+
When an element stops declaring a component — the token leaves `data-component`, or a responsive declaration stops matching — the registry unmounts the instance and **drops it from the element**, so declaring the name again builds a new one.
|
|
129
|
+
|
|
130
|
+
That is the registry rearranging its own bookkeeping. The instance only ever sees `$unmount()`.
|
|
131
|
+
|
|
132
|
+
## Announcements
|
|
133
|
+
|
|
134
|
+
Every instance dispatches a framework event on mount and on unmount, carrying itself in the payload:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { EVENTS, type LifecycleEventDetail } from '@studiometa/js-toolkit';
|
|
138
|
+
|
|
139
|
+
document.addEventListener(EVENTS.component.mounted, (event) => {
|
|
140
|
+
const { instance } = (event as CustomEvent<LifecycleEventDetail>).detail;
|
|
141
|
+
console.log(`${instance.$id} mounted`);
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- The **mount** event bubbles from the element, so any ancestor can follow its descendants with no declaration.
|
|
146
|
+
- The **unmount** event dispatches from `document`, because the element can already be detached.
|
|
147
|
+
- An instance that is scheduled but **not mounted** announces nothing.
|
|
148
|
+
|
|
149
|
+
See [`$watchChildren()`](../../api/instance-methods.md#watchchildren) for the component-level API built on this.
|
|
150
|
+
|
|
151
|
+
## Waiting for the DOM to settle
|
|
152
|
+
|
|
153
|
+
`whenDOMSettled()` is the completion boundary for morphing, fetch updates and breakpoint crossings. It drains the pending mutation records, follows the mutation chains of eager lifecycle work, and resolves after the eager mounts and the teardown:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { whenDOMSettled } from '@studiometa/js-toolkit';
|
|
157
|
+
|
|
158
|
+
async function replace(el: Element, html: string) {
|
|
159
|
+
el.innerHTML = html;
|
|
160
|
+
await whenDOMSettled();
|
|
161
|
+
// Every eager component in the new markup has mounted.
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
It does **not** wait for visibility, interaction, idle or media conditions, and it does not await the promises returned by `mounted()`. [`swap()`](../../api/dom/swap.md) awaits it for you.
|
|
166
|
+
|
|
167
|
+
## Manual mounting
|
|
168
|
+
|
|
169
|
+
`$mount()` and `$unmount()` are public, and calling them is legitimate — but on a page the registry does it, and doing it yourself is nearly always a sign that a [mount strategy](../going-further/mount-strategies.md) is the answer instead.
|
|
170
|
+
|
|
171
|
+
```js
|
|
172
|
+
instance.$unmount(); // reversible, the instance stays on its element
|
|
173
|
+
instance.$mount(); // a new cycle, same identity
|
|
174
|
+
```
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Components
|
|
2
|
+
|
|
3
|
+
A component is a class that extends `Base`, a name in the registry, and a `data-component` attribute in the markup. All three are needed, and nothing else is.
|
|
4
|
+
|
|
5
|
+
## Declaring a component
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import { Base, registerComponent } from '@studiometa/js-toolkit';
|
|
9
|
+
|
|
10
|
+
class Counter extends Base {
|
|
11
|
+
static config = {
|
|
12
|
+
name: 'Counter',
|
|
13
|
+
refs: ['output'],
|
|
14
|
+
options: { step: { type: Number, default: 1 } },
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
count = 0;
|
|
18
|
+
|
|
19
|
+
onClick() {
|
|
20
|
+
this.count += this.$options.step;
|
|
21
|
+
this.$refs.output.textContent = String(this.count);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
registerComponent(Counter);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```html
|
|
29
|
+
<button data-component="Counter" data-option-step="5">
|
|
30
|
+
clicked
|
|
31
|
+
<span data-ref="output">0</span>
|
|
32
|
+
times
|
|
33
|
+
</button>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`config.name` is the name the registry uses and the token the markup writes. It is also what gives each instance its [`$id`](../../api/instance-properties.md#id).
|
|
37
|
+
|
|
38
|
+
## Registering
|
|
39
|
+
|
|
40
|
+
`registerComponent(ComponentClass)` puts one name in the registry and scans the document for it. `registerComponents(...classes)` does the same for several:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
import { Base, registerComponents } from '@studiometa/js-toolkit';
|
|
44
|
+
|
|
45
|
+
class Accordion extends Base {
|
|
46
|
+
static config = { name: 'Accordion' };
|
|
47
|
+
}
|
|
48
|
+
class Slider extends Base {
|
|
49
|
+
static config = { name: 'Slider' };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
registerComponents(Accordion, Slider);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**There is no `createApp()`**
|
|
56
|
+
|
|
57
|
+
v4 has no root component and no application object. A component is registered, not mounted by a parent, so nothing has to own the page. Register the components a page uses and the registry does the rest.
|
|
58
|
+
|
|
59
|
+
**One name gives one entry**, as with `customElements.define()`. A second registration under a name already taken gives a `registry.conflict` warning and is ignored.
|
|
60
|
+
|
|
61
|
+
## Several components on one element
|
|
62
|
+
|
|
63
|
+
`data-component` holds a whitespace-separated token list, and each token gets its own instance:
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<a href="/next" data-component="Action Analytics Prefetch">Next</a>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The three instances are independent. They share the element and nothing else.
|
|
70
|
+
|
|
71
|
+
## Nesting
|
|
72
|
+
|
|
73
|
+
Children are not constructed by their parent. A nested `data-component` is discovered by the same registry, on its own:
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<div data-component="Accordion">
|
|
77
|
+
<div data-component="AccordionItem">…</div>
|
|
78
|
+
<div data-component="AccordionItem">…</div>
|
|
79
|
+
</div>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
What the parent declares in `config.components` is a **family**, and it does two jobs:
|
|
83
|
+
|
|
84
|
+
1. registering that family when the parent registers, so one `registerComponent()` call covers a whole tree;
|
|
85
|
+
2. giving the name set that [`on<Child><Event>`](working-with-events.md#child-events) resolution needs.
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
import { Base, registerComponent } from '@studiometa/js-toolkit';
|
|
89
|
+
|
|
90
|
+
class AccordionItem extends Base {
|
|
91
|
+
static config = { name: 'AccordionItem' };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
class Accordion extends Base {
|
|
95
|
+
static config = {
|
|
96
|
+
name: 'Accordion',
|
|
97
|
+
components: { AccordionItem },
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Registers `Accordion` *and* `AccordionItem`.
|
|
102
|
+
registerComponent(Accordion);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A value can also be a thunk, which makes the child its own chunk:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
static config = {
|
|
109
|
+
name: 'Accordion',
|
|
110
|
+
components: {
|
|
111
|
+
AccordionItem: () => import('./AccordionItem.js'),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The key supplies the name, so the registry knows `AccordionItem` with nothing downloaded. See [Autoloading](../going-further/autoloading.md).
|
|
117
|
+
|
|
118
|
+
**`config.components` is not ownership**
|
|
119
|
+
|
|
120
|
+
Declaring a child does not make the parent construct it, does not make the parent's unmount unmount it, and does not restrict where the child may appear. Nesting is DOM ancestry, always.
|
|
121
|
+
|
|
122
|
+
## Finding other components
|
|
123
|
+
|
|
124
|
+
There is no `$parent` and no `$children`. A component that needs to reach another one has four channels, in order of preference:
|
|
125
|
+
|
|
126
|
+
| Direction | Use |
|
|
127
|
+
| ----------------------- | -------------------------------------------------------------------------------- |
|
|
128
|
+
| parent → children | [`$watchChildren()`](../../api/instance-methods.md#watchchildren) or `$query(name)` |
|
|
129
|
+
| child → parent | [`$emit()`](../../api/instance-methods.md#emit) and the parent's `on<Child><Event>` |
|
|
130
|
+
| ancestor lookup, ad hoc | [`$closest(name)`](../../api/instance-methods.md#closest) — guard the result |
|
|
131
|
+
| shared state either way | [provide/inject](../going-further/sharing-state.md) |
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
import { Base } from '@studiometa/js-toolkit';
|
|
135
|
+
|
|
136
|
+
class Accordion extends Base {
|
|
137
|
+
static config = { name: 'Accordion', components: {} };
|
|
138
|
+
|
|
139
|
+
// A live collection, in document order, kept for the life of this instance.
|
|
140
|
+
items = this.$watchChildren('AccordionItem');
|
|
141
|
+
|
|
142
|
+
closeAll() {
|
|
143
|
+
for (const item of this.items) item.$el.removeAttribute('data-option-open');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Page-wide lookups
|
|
149
|
+
|
|
150
|
+
Outside a component, four functions answer from the DOM. They keep no registry of instances:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import {
|
|
154
|
+
getInstance,
|
|
155
|
+
getInstances,
|
|
156
|
+
getMountedInstances,
|
|
157
|
+
getUnmountedInstances,
|
|
158
|
+
} from '@studiometa/js-toolkit';
|
|
159
|
+
|
|
160
|
+
const section = document.querySelector('section')!;
|
|
161
|
+
|
|
162
|
+
getMountedInstances('Dialog'); // the live ones — safe to call a method on
|
|
163
|
+
getInstances('Dialog', section); // every one built in a region
|
|
164
|
+
getUnmountedInstances('Dialog'); // built, then stood down
|
|
165
|
+
getInstance(section, 'Dialog'); // the one on this element, mounted or not
|
|
166
|
+
getInstances(section); // everything on one element
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
See the [Registry reference](../../api/registry/index.md) for the full contract of each.
|
|
170
|
+
|
|
171
|
+
## Extending a component
|
|
172
|
+
|
|
173
|
+
There is no `withExtraConfig()`. To extend a component with a different config, declare a class. `$config` walks the prototype chain, so `refs`, `options` and `components` merge:
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
import { Base, registerComponent } from '@studiometa/js-toolkit';
|
|
177
|
+
|
|
178
|
+
class AbstractControl extends Base {
|
|
179
|
+
static config = {
|
|
180
|
+
name: 'AbstractControl',
|
|
181
|
+
refs: ['button'],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
class NavigationControl extends AbstractControl {
|
|
186
|
+
static config = {
|
|
187
|
+
name: 'NavigationControl',
|
|
188
|
+
// `refs` merges: ['button', 'compass']
|
|
189
|
+
refs: ['compass'],
|
|
190
|
+
options: { showCompass: Boolean },
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
registerComponent(NavigationControl);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
To extend a class you cannot edit, do it in expression position:
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
registerComponent(
|
|
201
|
+
class extends Vendor {
|
|
202
|
+
static config = { name: 'CompactVendor', options: { compact: Boolean } };
|
|
203
|
+
},
|
|
204
|
+
);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## When a component mounts
|
|
208
|
+
|
|
209
|
+
By default an instance mounts as soon as its element enters the document. `config.mountStrategy` and the `data-mount` attribute change that:
|
|
210
|
+
|
|
211
|
+
```html
|
|
212
|
+
<div data-component="Map" data-mount="visible"></div>
|
|
213
|
+
<div data-component="Chat" data-mount="interaction:page"></div>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
A component that waits has **no instance**: it is invisible to `$query()`, `$closest()`, `$watchChildren()` and `getInstances()`, and it announces nothing. See [Mount strategies](../going-further/mount-strategies.md).
|
|
217
|
+
|
|
218
|
+
## Responsive declarations
|
|
219
|
+
|
|
220
|
+
`data-component` takes one breakpoint-scoped companion, so a component can exist at some widths and not others:
|
|
221
|
+
|
|
222
|
+
```html
|
|
223
|
+
<div
|
|
224
|
+
data-component="Action Analytics"
|
|
225
|
+
data-component:xxs="MobileMenu"
|
|
226
|
+
data-component:m="DesktopMenu"></div>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
The unconditional set is always active. The scoped set is resolved by walking from the widest active suffix down to the first attribute present, and it **replaces** rather than merges. A name that stops being declared is unmounted and dropped from the element; a crossing back builds a new instance. See [`data-component`](../../api/html/data-component.md).
|