defaults.mjs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Utilities
  2. import { computed, inject, provide, ref, shallowRef, unref, watchEffect } from 'vue';
  3. import { getCurrentInstance } from "../util/getCurrentInstance.mjs";
  4. import { mergeDeep, toKebabCase } from "../util/helpers.mjs";
  5. import { injectSelf } from "../util/injectSelf.mjs"; // Types
  6. export const DefaultsSymbol = Symbol.for('vuetify:defaults');
  7. export function createDefaults(options) {
  8. return ref(options);
  9. }
  10. export function injectDefaults() {
  11. const defaults = inject(DefaultsSymbol);
  12. if (!defaults) throw new Error('[Vuetify] Could not find defaults instance');
  13. return defaults;
  14. }
  15. export function provideDefaults(defaults, options) {
  16. const injectedDefaults = injectDefaults();
  17. const providedDefaults = ref(defaults);
  18. const newDefaults = computed(() => {
  19. const disabled = unref(options?.disabled);
  20. if (disabled) return injectedDefaults.value;
  21. const scoped = unref(options?.scoped);
  22. const reset = unref(options?.reset);
  23. const root = unref(options?.root);
  24. if (providedDefaults.value == null && !(scoped || reset || root)) return injectedDefaults.value;
  25. let properties = mergeDeep(providedDefaults.value, {
  26. prev: injectedDefaults.value
  27. });
  28. if (scoped) return properties;
  29. if (reset || root) {
  30. const len = Number(reset || Infinity);
  31. for (let i = 0; i <= len; i++) {
  32. if (!properties || !('prev' in properties)) {
  33. break;
  34. }
  35. properties = properties.prev;
  36. }
  37. if (properties && typeof root === 'string' && root in properties) {
  38. properties = mergeDeep(mergeDeep(properties, {
  39. prev: properties
  40. }), properties[root]);
  41. }
  42. return properties;
  43. }
  44. return properties.prev ? mergeDeep(properties.prev, properties) : properties;
  45. });
  46. provide(DefaultsSymbol, newDefaults);
  47. return newDefaults;
  48. }
  49. function propIsDefined(vnode, prop) {
  50. return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
  51. }
  52. export function internalUseDefaults() {
  53. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  54. let name = arguments.length > 1 ? arguments[1] : undefined;
  55. let defaults = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : injectDefaults();
  56. const vm = getCurrentInstance('useDefaults');
  57. name = name ?? vm.type.name ?? vm.type.__name;
  58. if (!name) {
  59. throw new Error('[Vuetify] Could not determine component name');
  60. }
  61. const componentDefaults = computed(() => defaults.value?.[props._as ?? name]);
  62. const _props = new Proxy(props, {
  63. get(target, prop) {
  64. const propValue = Reflect.get(target, prop);
  65. if (prop === 'class' || prop === 'style') {
  66. return [componentDefaults.value?.[prop], propValue].filter(v => v != null);
  67. } else if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
  68. return componentDefaults.value?.[prop] !== undefined ? componentDefaults.value?.[prop] : defaults.value?.global?.[prop] !== undefined ? defaults.value?.global?.[prop] : propValue;
  69. }
  70. return propValue;
  71. }
  72. });
  73. const _subcomponentDefaults = shallowRef();
  74. watchEffect(() => {
  75. if (componentDefaults.value) {
  76. const subComponents = Object.entries(componentDefaults.value).filter(_ref => {
  77. let [key] = _ref;
  78. return key.startsWith(key[0].toUpperCase());
  79. });
  80. _subcomponentDefaults.value = subComponents.length ? Object.fromEntries(subComponents) : undefined;
  81. } else {
  82. _subcomponentDefaults.value = undefined;
  83. }
  84. });
  85. function provideSubDefaults() {
  86. const injected = injectSelf(DefaultsSymbol, vm);
  87. provide(DefaultsSymbol, computed(() => {
  88. return _subcomponentDefaults.value ? mergeDeep(injected?.value ?? {}, _subcomponentDefaults.value) : injected?.value;
  89. }));
  90. }
  91. return {
  92. props: _props,
  93. provideSubDefaults
  94. };
  95. }
  96. export function useDefaults() {
  97. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  98. let name = arguments.length > 1 ? arguments[1] : undefined;
  99. const {
  100. props: _props,
  101. provideSubDefaults
  102. } = internalUseDefaults(props, name);
  103. provideSubDefaults();
  104. return _props;
  105. }
  106. //# sourceMappingURL=defaults.mjs.map