vuetify
Version:
Vue Material Component Framework
71 lines (69 loc) • 3.09 kB
JavaScript
// Utils
import { defineComponent as _defineComponent,
// eslint-disable-line no-restricted-imports
computed, getCurrentInstance, shallowRef, watchEffect } from 'vue';
import { consoleWarn } from "./console.mjs";
import { mergeDeep, toKebabCase } from "./helpers.mjs";
import { injectSelf } from "./injectSelf.mjs";
import { propsFactory } from "./propsFactory.mjs";
import { DefaultsSymbol, provideDefaults, useDefaults } from "../composables/defaults.mjs";
import { useToggleScope } from "../composables/toggleScope.mjs"; // Types
function propIsDefined(vnode, prop) {
return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
}
export const defineComponent = function defineComponent(options) {
options._setup = options._setup ?? options.setup;
if (!options.name) {
consoleWarn('The component is missing an explicit name, unable to generate default prop value');
return options;
}
if (options._setup) {
options.props = options.props ?? {};
options.props = propsFactory(options.props, toKebabCase(options.name))();
options.props._as = String;
options.setup = function setup(props, ctx) {
const defaults = useDefaults();
// Skip props proxy if defaults are not provided
if (!defaults.value) return options._setup(props, ctx);
const vm = getCurrentInstance();
const componentDefaults = computed(() => defaults.value[props._as ?? options.name]);
const _props = new Proxy(props, {
get(target, prop) {
if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
return componentDefaults.value?.[prop] ?? defaults.value.global?.[prop] ?? target[prop];
}
return Reflect.get(target, prop);
}
});
const _subcomponentDefaults = shallowRef();
watchEffect(() => {
if (componentDefaults.value) {
const subComponents = Object.entries(componentDefaults.value).filter(_ref => {
let [key] = _ref;
return key.startsWith(key[0].toUpperCase());
});
if (subComponents.length) _subcomponentDefaults.value = Object.fromEntries(subComponents);
}
});
const setupBindings = options._setup(_props, ctx);
// If subcomponent defaults are provided, override any
// subcomponents provided by the component's setup function.
// This uses injectSelf so must be done after the original setup to work.
useToggleScope(_subcomponentDefaults, () => {
provideDefaults(mergeDeep(injectSelf(DefaultsSymbol)?.value ?? {}, _subcomponentDefaults.value));
});
return setupBindings;
};
}
return options;
};
// Implementation
export function genericComponent() {
let exposeDefaults = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
return options => (exposeDefaults ? defineComponent : _defineComponent)(options);
}
export function defineFunctionalComponent(props, render) {
render.props = props;
return render;
}
//# sourceMappingURL=defineComponent.mjs.map