StyleContext.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.StyleProvider = exports.CSS_IN_JS_INSTANCE = exports.ATTR_TOKEN = exports.ATTR_MARK = exports.ATTR_CACHE_PATH = void 0;
  7. exports.createCache = createCache;
  8. exports.useStyleProvider = exports.useStyleInject = exports.styleProviderProps = exports.default = void 0;
  9. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  10. var _vue = require("vue");
  11. var _Cache = _interopRequireDefault(require("./Cache"));
  12. var _type = require("../type");
  13. const ATTR_TOKEN = exports.ATTR_TOKEN = 'data-token-hash';
  14. const ATTR_MARK = exports.ATTR_MARK = 'data-css-hash';
  15. const ATTR_CACHE_PATH = exports.ATTR_CACHE_PATH = 'data-cache-path';
  16. // Mark css-in-js instance in style element
  17. const CSS_IN_JS_INSTANCE = exports.CSS_IN_JS_INSTANCE = '__cssinjs_instance__';
  18. function createCache() {
  19. const cssinjsInstanceId = Math.random().toString(12).slice(2);
  20. // Tricky SSR: Move all inline style to the head.
  21. // PS: We do not recommend tricky mode.
  22. if (typeof document !== 'undefined' && document.head && document.body) {
  23. const styles = document.body.querySelectorAll(`style[${ATTR_MARK}]`) || [];
  24. const {
  25. firstChild
  26. } = document.head;
  27. Array.from(styles).forEach(style => {
  28. style[CSS_IN_JS_INSTANCE] = style[CSS_IN_JS_INSTANCE] || cssinjsInstanceId;
  29. // Not force move if no head
  30. // Not force move if no head
  31. if (style[CSS_IN_JS_INSTANCE] === cssinjsInstanceId) {
  32. document.head.insertBefore(style, firstChild);
  33. }
  34. });
  35. // Deduplicate of moved styles
  36. const styleHash = {};
  37. Array.from(document.querySelectorAll(`style[${ATTR_MARK}]`)).forEach(style => {
  38. var _a;
  39. const hash = style.getAttribute(ATTR_MARK);
  40. if (styleHash[hash]) {
  41. if (style[CSS_IN_JS_INSTANCE] === cssinjsInstanceId) {
  42. (_a = style.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(style);
  43. }
  44. } else {
  45. styleHash[hash] = true;
  46. }
  47. });
  48. }
  49. return new _Cache.default(cssinjsInstanceId);
  50. }
  51. const StyleContextKey = Symbol('StyleContextKey');
  52. // fix: https://github.com/vueComponent/ant-design-vue/issues/7023
  53. const getCache = () => {
  54. var _a, _b, _c;
  55. const instance = (0, _vue.getCurrentInstance)();
  56. let cache;
  57. if (instance && instance.appContext) {
  58. const globalCache = (_c = (_b = (_a = instance.appContext) === null || _a === void 0 ? void 0 : _a.config) === null || _b === void 0 ? void 0 : _b.globalProperties) === null || _c === void 0 ? void 0 : _c.__ANTDV_CSSINJS_CACHE__;
  59. if (globalCache) {
  60. cache = globalCache;
  61. } else {
  62. cache = createCache();
  63. if (instance.appContext.config.globalProperties) {
  64. instance.appContext.config.globalProperties.__ANTDV_CSSINJS_CACHE__ = cache;
  65. }
  66. }
  67. } else {
  68. cache = createCache();
  69. }
  70. return cache;
  71. };
  72. const defaultStyleContext = {
  73. cache: createCache(),
  74. defaultCache: true,
  75. hashPriority: 'low'
  76. };
  77. // fix: https://github.com/vueComponent/ant-design-vue/issues/6912
  78. const useStyleInject = () => {
  79. const cache = getCache();
  80. return (0, _vue.inject)(StyleContextKey, (0, _vue.shallowRef)((0, _extends2.default)((0, _extends2.default)({}, defaultStyleContext), {
  81. cache
  82. })));
  83. };
  84. exports.useStyleInject = useStyleInject;
  85. const useStyleProvider = props => {
  86. const parentContext = useStyleInject();
  87. const context = (0, _vue.shallowRef)((0, _extends2.default)((0, _extends2.default)({}, defaultStyleContext), {
  88. cache: createCache()
  89. }));
  90. (0, _vue.watch)([() => (0, _vue.unref)(props), parentContext], () => {
  91. const mergedContext = (0, _extends2.default)({}, parentContext.value);
  92. const propsValue = (0, _vue.unref)(props);
  93. Object.keys(propsValue).forEach(key => {
  94. const value = propsValue[key];
  95. if (propsValue[key] !== undefined) {
  96. mergedContext[key] = value;
  97. }
  98. });
  99. const {
  100. cache
  101. } = propsValue;
  102. mergedContext.cache = mergedContext.cache || createCache();
  103. mergedContext.defaultCache = !cache && parentContext.value.defaultCache;
  104. context.value = mergedContext;
  105. }, {
  106. immediate: true
  107. });
  108. (0, _vue.provide)(StyleContextKey, context);
  109. return context;
  110. };
  111. exports.useStyleProvider = useStyleProvider;
  112. const styleProviderProps = () => ({
  113. autoClear: (0, _type.booleanType)(),
  114. /** @private Test only. Not work in production. */
  115. mock: (0, _type.stringType)(),
  116. /**
  117. * Only set when you need ssr to extract style on you own.
  118. * If not provided, it will auto create <style /> on the end of Provider in server side.
  119. */
  120. cache: (0, _type.objectType)(),
  121. /** Tell children that this context is default generated context */
  122. defaultCache: (0, _type.booleanType)(),
  123. /** Use `:where` selector to reduce hashId css selector priority */
  124. hashPriority: (0, _type.stringType)(),
  125. /** Tell cssinjs where to inject style in */
  126. container: (0, _type.someType)(),
  127. /** Component wil render inline `<style />` for fallback in SSR. Not recommend. */
  128. ssrInline: (0, _type.booleanType)(),
  129. /** Transform css before inject in document. Please note that `transformers` do not support dynamic update */
  130. transformers: (0, _type.arrayType)(),
  131. /**
  132. * Linters to lint css before inject in document.
  133. * Styles will be linted after transforming.
  134. * Please note that `linters` do not support dynamic update.
  135. */
  136. linters: (0, _type.arrayType)()
  137. });
  138. exports.styleProviderProps = styleProviderProps;
  139. const StyleProvider = exports.StyleProvider = (0, _type.withInstall)((0, _vue.defineComponent)({
  140. name: 'AStyleProvider',
  141. inheritAttrs: false,
  142. props: styleProviderProps(),
  143. setup(props, _ref) {
  144. let {
  145. slots
  146. } = _ref;
  147. useStyleProvider(props);
  148. return () => {
  149. var _a;
  150. return (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots);
  151. };
  152. }
  153. }));
  154. var _default = exports.default = {
  155. useStyleInject,
  156. useStyleProvider,
  157. StyleProvider
  158. };