index.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = useMergeSemantic;
  8. exports.mergeClassNames = mergeClassNames;
  9. var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
  10. var React = _interopRequireWildcard(require("react"));
  11. var _classnames = _interopRequireDefault(require("classnames"));
  12. // ========================= ClassNames =========================
  13. function mergeClassNames(schema, ...classNames) {
  14. const mergedSchema = schema || {};
  15. return classNames.reduce((acc, cur) => {
  16. // Loop keys of the current classNames
  17. Object.keys(cur || {}).forEach(key => {
  18. const keySchema = mergedSchema[key];
  19. const curVal = cur[key];
  20. if (keySchema && typeof keySchema === 'object') {
  21. if (curVal && typeof curVal === 'object') {
  22. // Loop fill
  23. acc[key] = mergeClassNames(keySchema, acc[key], curVal);
  24. } else {
  25. // Covert string to object structure
  26. const {
  27. _default: defaultField
  28. } = keySchema;
  29. acc[key] = acc[key] || {};
  30. acc[key][defaultField] = (0, _classnames.default)(acc[key][defaultField], curVal);
  31. }
  32. } else {
  33. // Flatten fill
  34. acc[key] = (0, _classnames.default)(acc[key], curVal);
  35. }
  36. });
  37. return acc;
  38. }, {});
  39. }
  40. function useSemanticClassNames(schema, ...classNames) {
  41. return React.useMemo(() => mergeClassNames.apply(void 0, [schema].concat(classNames)), [classNames]);
  42. }
  43. // =========================== Styles ===========================
  44. function useSemanticStyles(...styles) {
  45. return React.useMemo(() => {
  46. return styles.reduce((acc, cur = {}) => {
  47. Object.keys(cur).forEach(key => {
  48. acc[key] = Object.assign(Object.assign({}, acc[key]), cur[key]);
  49. });
  50. return acc;
  51. }, {});
  52. }, [styles]);
  53. }
  54. // =========================== Export ===========================
  55. function fillObjectBySchema(obj, schema) {
  56. const newObj = Object.assign({}, obj);
  57. Object.keys(schema).forEach(key => {
  58. if (key !== '_default') {
  59. const nestSchema = schema[key];
  60. const nextValue = newObj[key] || {};
  61. newObj[key] = nestSchema ? fillObjectBySchema(nextValue, nestSchema) : nextValue;
  62. }
  63. });
  64. return newObj;
  65. }
  66. /**
  67. * Merge classNames and styles from multiple sources.
  68. * When `schema` is provided, it will **must** provide the nest object structure.
  69. */
  70. function useMergeSemantic(classNamesList, stylesList, schema) {
  71. const mergedClassNames = useSemanticClassNames.apply(void 0, [schema].concat((0, _toConsumableArray2.default)(classNamesList)));
  72. const mergedStyles = useSemanticStyles.apply(void 0, (0, _toConsumableArray2.default)(stylesList));
  73. return React.useMemo(() => {
  74. return [fillObjectBySchema(mergedClassNames, schema), fillObjectBySchema(mergedStyles, schema)];
  75. }, [mergedClassNames, mergedStyles]);
  76. }