zeplin-extension-style-kit
Version:
Models and utilities to generate CSS-like style code in Zeplin extensions.
366 lines (282 loc) • 13.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _angle = _interopRequireDefault(require("../values/angle"));
var _color = _interopRequireDefault(require("../values/color"));
var _gradient = _interopRequireDefault(require("../values/gradient"));
var _length = _interopRequireDefault(require("../values/length"));
var _scalar = _interopRequireDefault(require("../values/scalar"));
var _border = _interopRequireDefault(require("../declarations/border"));
var _shadow = _interopRequireDefault(require("../declarations/shadow"));
var _opacity = _interopRequireDefault(require("../declarations/opacity"));
var _width = _interopRequireDefault(require("../declarations/width"));
var _height = _interopRequireDefault(require("../declarations/height"));
var _objectFit = _interopRequireDefault(require("../declarations/objectFit"));
var _transform = _interopRequireDefault(require("../declarations/transform"));
var _mixBlendMode = _interopRequireDefault(require("../declarations/mixBlendMode"));
var _borderRadius = _interopRequireDefault(require("../declarations/borderRadius"));
var _backgroundBlendMode = _interopRequireDefault(require("../declarations/backgroundBlendMode"));
var _backgroundImage = _interopRequireDefault(require("../declarations/backgroundImage"));
var _backgroundColor = _interopRequireDefault(require("../declarations/backgroundColor"));
var _backgroundClip = _interopRequireDefault(require("../declarations/backgroundClip"));
var _backgroundOrigin = _interopRequireDefault(require("../declarations/backgroundOrigin"));
var _textFillColor = _interopRequireDefault(require("../declarations/textFillColor"));
var _textStroke = _interopRequireDefault(require("../declarations/textStroke"));
var _borderImageSource = _interopRequireDefault(require("../declarations/borderImageSource"));
var _borderWidth = _interopRequireDefault(require("../declarations/borderWidth"));
var _borderStyle = _interopRequireDefault(require("../declarations/borderStyle"));
var _borderImageSlice = _interopRequireDefault(require("../declarations/borderImageSlice"));
var _backdropFilter = _interopRequireDefault(require("../declarations/backdropFilter"));
var _filter = _interopRequireDefault(require("../declarations/filter"));
var _fontColor = _interopRequireDefault(require("../declarations/fontColor"));
var _textStyle = _interopRequireDefault(require("./textStyle"));
var _ruleSet = _interopRequireDefault(require("../ruleSet"));
var _utils = require("../utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var useRemUnitForMeasurement = function useRemUnitForMeasurement(_ref) {
var useForMeasurements = _ref.useForMeasurements;
return useForMeasurements;
};
var Layer = /*#__PURE__*/function () {
function Layer() {
var layerObject = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Layer);
this.object = layerObject;
this.declarations = this.collectDeclarations();
}
_createClass(Layer, [{
key: "getLayerTextStyleDeclarations",
value: function getLayerTextStyleDeclarations(textStyle) {
var layer = this.object;
var declarations = new _textStyle.default(textStyle).declarations;
if (layer.fills.length) {
declarations = declarations.filter(function (declaration) {
return !(declaration instanceof _color.default);
});
if (this.hasGradient) {
declarations.push(new ((0, _utils.webkit)(_backgroundClip.default))(["text"]));
declarations.push(new _backgroundClip.default(["text"]));
declarations.push(new _textFillColor.default("transparent"));
var bgImages = layer.fills.map(function (fill) {
return Layer.fillToGradient(fill, layer.rect.width, layer.rect.height);
});
if (textStyle.color) {
bgImages.push(new _color.default(textStyle.color).toGradient());
}
declarations.push(new _backgroundImage.default(bgImages));
} else {
var blentColor = (0, _utils.blendColors)(layer.fills.map(function (fill) {
return fill.color;
}));
if (textStyle.color) {
blentColor = blentColor.blend(textStyle.color);
}
declarations.push(new _fontColor.default(new _color.default(blentColor)));
}
}
return declarations;
}
}, {
key: "generateBorderDeclarations",
value: function generateBorderDeclarations() {
var _this$elementBorder = this.elementBorder,
fill = _this$elementBorder.fill,
thickness = _this$elementBorder.thickness,
layer = this.object;
if (layer.type === "text" && fill.type === "color") {
return [new ((0, _utils.webkit)(_textStroke.default))(new _length.default(thickness), new _color.default(fill.color))];
}
switch (fill.type) {
case "color":
return [new _border.default({
style: "solid",
width: new _length.default(thickness),
color: new _color.default(fill.color)
})];
case "gradient":
{
return [new _borderStyle.default("solid"), new _borderWidth.default(new _length.default(thickness)), new _borderImageSource.default(new _gradient.default(fill.gradient, layer.rect.width, layer.rect.height)), new _borderImageSlice.default(new _scalar.default(1))];
}
default:
return [];
}
}
}, {
key: "generateBlurDeclarations",
value: function generateBlurDeclarations() {
var blur = this.object.blur;
var filterFns = [{
fn: "blur",
args: [new _length.default(blur.radius)]
}];
if (blur.type === "background") {
return [new ((0, _utils.webkit)(_backdropFilter.default))(filterFns), new _backdropFilter.default(filterFns)];
}
return [new ((0, _utils.webkit)(_filter.default))(filterFns), new _filter.default(filterFns)];
}
}, {
key: "generateBackgroundDeclarations",
value: function generateBackgroundDeclarations() {
var backgroundImages = this.backgroundImages,
elementBorder = this.elementBorder,
fillColor = this.fillColor,
layer = this.object;
var declarations = [];
if (this.hasFill && this.hasBlendMode) {
declarations.push(new _backgroundBlendMode.default(layer.fills.map(function (fill) {
return fill.blendMode;
})));
}
if (backgroundImages) {
declarations.push(new _backgroundImage.default(backgroundImages));
if (layer.borderRadius && elementBorder && elementBorder.fill.type === "gradient") {
declarations.push(new _backgroundOrigin.default(["border-box"]));
declarations.push(new _backgroundClip.default([].concat(_toConsumableArray(Array(backgroundImages.length - 1).fill("content-box")), ["border-box"])));
}
} else if (fillColor) {
declarations.push(new _backgroundColor.default(fillColor));
}
return declarations;
}
/* eslint-disable complexity */
}, {
key: "collectDeclarations",
value: function collectDeclarations() {
var elementBorder = this.elementBorder,
layer = this.object;
var declarations = [new _width.default(new _length.default(layer.rect.width, {
useRemUnit: useRemUnitForMeasurement
})), new _height.default(new _length.default(layer.rect.height, {
useRemUnit: useRemUnitForMeasurement
}))];
if (layer.exportable) {
declarations.push(new _objectFit.default("contain"));
}
if (layer.rotation) {
declarations.push(new _transform.default([{
fn: "rotate",
args: [new _angle.default(-layer.rotation)]
}]));
}
if (layer.opacity !== 1) {
declarations.push(new _opacity.default(new _scalar.default(layer.opacity)));
}
if (layer.blendMode !== "normal") {
declarations.push(new _mixBlendMode.default(layer.blendMode));
}
if (layer.borderRadius) {
// TODO: different radii for each corner?
declarations.push(new _borderRadius.default(new _length.default(layer.borderRadius)));
}
if (layer.blur && layer.blur.radius) {
declarations = declarations.concat(this.generateBlurDeclarations());
}
if (layer.shadows.length) {
declarations.push(new _shadow.default(layer.shadows, layer.type === "text" ? _shadow.default.TYPES.TEXT : _shadow.default.TYPES.BOX));
}
if (elementBorder) {
declarations = declarations.concat(this.generateBorderDeclarations());
}
declarations = declarations.concat(this.generateBackgroundDeclarations());
return declarations;
}
}, {
key: "hasBlendMode",
get: function get() {
return this.object.fills.some(function (f) {
return f.blendMode && f.blendMode !== "normal";
});
}
}, {
key: "hasGradient",
get: function get() {
return this.object.fills.some(function (f) {
return f.type === "gradient";
});
}
}, {
key: "hasFill",
get: function get() {
return this.object.fills.length > 0;
}
}, {
key: "elementBorder",
get: function get() {
var borders = this.object.borders;
return borders.length ? borders[borders.length - 1] : null;
}
}, {
key: "backgroundImages",
get: function get() {
var _this = this;
var bgImages;
if (!this.hasFill) {
return null;
}
if (this.hasGradient || this.hasBlendMode) {
bgImages = this.object.fills.map(function (fill) {
return Layer.fillToGradient(fill, _this.object.rect.width, _this.object.rect.height);
});
}
if (this.elementBorder) {
if (this.object.borderRadius && this.elementBorder.fill.type === "gradient") {
var borderFill = new _gradient.default(this.elementBorder.fill.gradient, this.object.rect.width, this.object.rect.height);
if (bgImages) {
bgImages.push(borderFill);
} else if (this.fillColor) {
bgImages = [this.fillColor.toGradient(), borderFill];
} else {
/*
* Actually the background should be transparent if there are no fills,
* i.e. what's on the background of this layer should be shown.
* But we have no way of knowing the background of parent layer,
* and making it transparent will make fake-gradient-border background visible.
*/
var white = _color.default.fromRGBA({
r: 255,
g: 255,
b: 255,
a: 1
});
bgImages = [white.toGradient(), borderFill];
}
}
}
return bgImages;
}
}, {
key: "fillColor",
get: function get() {
if (this.hasFill && !this.hasGradient && !this.hasBlendMode) {
return new _color.default((0, _utils.blendColors)(this.object.fills.map(function (fill) {
return fill.color;
})));
}
return null;
}
}, {
key: "style",
get: function get() {
return new _ruleSet.default((0, _utils.selectorize)(this.object.name), this.declarations);
}
}], [{
key: "fillToGradient",
value: function fillToGradient(fill, width, height) {
return fill.type === "color" ? new _color.default(fill.color).toGradient() : new _gradient.default(fill.gradient, width, height);
}
}]);
return Layer;
}();
var _default = Layer;
exports.default = _default;