UNPKG

@amaui/style

Version:
252 lines (191 loc) 10.6 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import Try from '@amaui/utils/try'; import isEnvironment from '@amaui/utils/isEnvironment'; import AmauiStyleSheet from './AmauiStyleSheet'; import { cammelCaseToKebabCase, getID, getRefs, is, valueResolve } from './utils'; const optionsDefault = { value_version: 'value', pure: false, parents: [], sort: true, prefix: true, rtl: true }; class AmauiStyleRuleProperty { constructor(value, property) { let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : optionsDefault; _defineProperty(this, "value_version", 'value'); _defineProperty(this, "pure", false); _defineProperty(this, "parents", []); _defineProperty(this, "values", { property: '', value: '', css: '' }); this.value = value; this.property = property; this.options = options; this.init(); } get parent() { return this.parents[this.parents.length - 1]; } get response() { return { css: this.values.css }; } get css() { return this.response.css; } updateValues() { // Response this.values.css = "".concat(this.values.property, ": ").concat(this.values.value, ";"); // For undefined animation name value if (this.values.css.indexOf('undefined') > -1) this.values.css = ''; } init(value) { var _this$amauiStyleSheet, _this$parent, _this$amauiStyleSheet2, _this$parent2; // Update values this.values.property = cammelCaseToKebabCase(this.property); this.values.value = value !== undefined ? value : this.value; // Options this.value_version = this.options.value_version || 'value'; this.pure = this.options.pure !== undefined ? this.options.pure : false; this.owner = this.options.owner; this.parents = this.options.parents || []; this.amauiStyle = this.options.amauiStyle; this.amauiStyleSheet = this.options.amauiStyleSheet; this.amauiStyleRule = this.options.amauiStyleRule; if (this.id === undefined) this.id = getID(); if (this.level === undefined) this.level = this.parents.length - 1; // Add to rules_owned to all parents this.parents.filter(parent => !(parent instanceof AmauiStyleSheet)).forEach(parent => parent.rules_owned.push(this)); // method or AmauiSubscription if (value === undefined && ['method', 'amaui_subscription'].indexOf(this.value_version) > -1) { if (this.value_version === 'method') this.values.value = Try(() => this.value(this.amauiStyleSheet.props));else if (this.value_version === 'amaui_subscription') { this.values.value = this.value.value; if (!this.value.subscribed) this.value.subscribed = []; if (this.value.subscribed.indexOf(this) === -1) { this.value.subscribe(this.update.bind(this)); this.value.subscribed.push(this); } } // Value this.values.value = is('function', this.values.value) ? Try(() => this.values.value(this.amauiStyleSheet.props)) : this.values.value; } // Value this.values.value = valueResolve(this.values.property, this.values.value, this.amauiStyle).value[0]; // Move through plugins // rtl const useRtl = this.amauiStyle.options.rule.rtl && (this.amauiStyleSheet === undefined || this.amauiStyleSheet.options.rule.rtl !== false) && (((_this$amauiStyleSheet = this.amauiStyleSheet) === null || _this$amauiStyleSheet === void 0 ? void 0 : _this$amauiStyleSheet.amauiTheme) === undefined || this.amauiStyleSheet.amauiTheme.options.rule.rtl) && // by default is true ((_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.options.rtl) !== false; if (useRtl) { const rtl = this.amauiStyle.subscriptions.rule.rtl.map(this.values); if (rtl !== null && rtl !== void 0 && rtl.value) { var _rtl$value, _rtl$value2; if (rtl !== null && rtl !== void 0 && (_rtl$value = rtl.value) !== null && _rtl$value !== void 0 && _rtl$value.property) this.values.property = rtl.value.property; if (rtl !== null && rtl !== void 0 && (_rtl$value2 = rtl.value) !== null && _rtl$value2 !== void 0 && _rtl$value2.value) this.values.value = rtl.value.value; } } // prefix const usePrefix = this.amauiStyle.options.rule.prefix && (this.amauiStyleSheet === undefined || this.amauiStyleSheet.options.rule.prefix !== false) && (((_this$amauiStyleSheet2 = this.amauiStyleSheet) === null || _this$amauiStyleSheet2 === void 0 ? void 0 : _this$amauiStyleSheet2.amauiTheme) === undefined || this.amauiStyleSheet.amauiTheme.options.rule.prefix !== false) && // by default is true ((_this$parent2 = this.parent) === null || _this$parent2 === void 0 ? void 0 : _this$parent2.options.prefix) !== false; if (usePrefix && this.values.property.indexOf('-') !== 0 && Try(() => this.values.value.indexOf('-') !== 0)) { var _this$amauiStyle$subs; const prefixes = ((_this$amauiStyle$subs = this.amauiStyle.subscriptions.rule.prefix.map({ value: this.values.value, property: this.values.property })) === null || _this$amauiStyle$subs === void 0 ? void 0 : _this$amauiStyle$subs.value) || []; if (!!prefixes.length) { prefixes.forEach(item => { var _this$parent3; const exists = (((_this$parent3 = this.parent) === null || _this$parent3 === void 0 ? void 0 : _this$parent3.rules) || []).find(rule_ => rule_ instanceof AmauiStyleRuleProperty && rule_.values.property === item.property && rule_.values.value === item.value); if (!exists && this.parent) { AmauiStyleRuleProperty.make(item.value, item.property, { value_version: 'value', pure: this.pure, owner: this.parent, parents: this.parents, amauiStyleRule: this.amauiStyleRule, amauiStyleSheet: this.parent.amauiStyleSheet, amauiStyle: this.parent.amauiStyle }); } }); } } // Add itself to owner rules if (this.owner) { const exists = this.owner.rules.find(rule => rule.value.id === this.id); if (!exists) this.owner.rules.push({ property: this.property, value: this }); this.level_actual = this.owner.level_actual + 1; } // Update values this.updateValues(); } // Update only if amauiStyleSheet is version 'dynamic' update(value) { var _domElement$style; // Init with value if (value !== undefined) this.init(value); // Make selector // ie. for animation, and animation-name this.makeSelector(); // Update the rule // method or AmauiSubscription if (value === undefined && ['method', 'amaui_subscription'].indexOf(this.value_version) > -1) { if (this.value_version === 'method') this.values.value = Try(() => this.value(this.amauiStyleSheet.props));else if (this.value_version === 'amaui_subscription') this.values.value = this.value.value; // Value this.values.value = is('function', this.values.value) ? Try(() => this.values.value(this.amauiStyleSheet.props)) : this.values.value; this.values.value = valueResolve(this.values.property, this.values.value, this.amauiStyle).value[0]; } // Update values this.updateValues(); const domElement = this.amauiStyleSheet.domElementForTesting || isEnvironment('browser') && window.document.createElement('div'); if (domElement) domElement.style[this.values.property] = this.values.value; const valueNew = (domElement === null || domElement === void 0 ? void 0 : (_domElement$style = domElement.style) === null || _domElement$style === void 0 ? void 0 : _domElement$style[this.values.property]) || this.values.value; // Only if rule reference exists if (this.owner.rule) { // Only update if value is diff from previous update if (this.owner.rule.style[this.values.property] !== valueNew) { var _this$values$value; const rule = this.owner.owner.rule || this.owner.owner.sheet; // For some reason important will not update the style property // updating it through rule.style[property] // only way is to fully remove the CSSStyleRule // and insert a new one with new value if (is('string', this.values.value) && (_this$values$value = this.values.value) !== null && _this$values$value !== void 0 && _this$values$value.includes('!important')) { let index = Array.from((rule === null || rule === void 0 ? void 0 : rule.cssRules) || []).findIndex(item => item === this.owner.rule); if (index > -1) { Try(() => rule.deleteRule(index)); // Update owner values so it includes // new update for this property value this.owner.updateValues(); index = Try(() => rule.insertRule(this.owner.values.css)); if (index > -1) this.owner.rule = rule.cssRules[index]; } } else Try(() => this.owner.rule.style[this.values.property] = this.values.value); // Update the values css string value this.values.css = "".concat(this.values.property, ": ").concat(this.values.value, ";"); } } } remove() { this.clear(); } makeSelector() { if (['animation', 'animation-name'].some(item => this.values.property.indexOf(item) > -1)) { const refs = getRefs(this.values.value); const refValues = refs.map(item => this.amauiStyleSheet.amauiStyleSheetManager.names.keyframes[item]).filter(Boolean); refs.forEach((ref, i) => this.values.value = this.values.value.replace("$".concat(ref), refValues[i])); // Update values this.updateValues(); } } clear() { var _this$owner; // rule if ((_this$owner = this.owner) !== null && _this$owner !== void 0 && _this$owner.rule) this.owner.rule.style[this.values.property] = ''; // rules if (this.owner) { const index = this.owner.rules.findIndex(item => item.value === this); if (index > -1) this.owner.rules.splice(index, 1); } // rules owned this.parents.filter(parent => !(parent instanceof AmauiStyleSheet)).forEach(parent => { const index = parent.rules_owned.findIndex(item => item.value === this); if (index > -1) parent.rules_owned.splice(index, 1); }); } static make(value, property) { let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { value_version: 'value', pure: false, parents: [this] }; return new AmauiStyleRuleProperty(value, property, options); } } export default AmauiStyleRuleProperty;