UNPKG

@amaui/style

Version:
363 lines (294 loc) 10.8 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import isEnvironment from '@amaui/utils/isEnvironment'; import merge from '@amaui/utils/merge'; import AmauiStyleSheet from './AmauiStyleSheet'; import { dynamic, getID, is, names } from './utils'; const optionsDefault = { mode: 'regular', pure: false, priority: 'upper', style: { attributes: {} }, rule: { sort: true, prefix: true, rtl: true }, amaui_style_cache: true }; class AmauiStyleSheetManager { constructor(value) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : optionsDefault; _defineProperty(this, "status", 'idle'); _defineProperty(this, "mode", 'regular'); _defineProperty(this, "pure", false); _defineProperty(this, "priority", 'upper'); _defineProperty(this, "values", { css: '' }); _defineProperty(this, "properties", { static: [], dynamic: [] }); _defineProperty(this, "sheets", { static: [], dynamic: [] }); _defineProperty(this, "names", { classNames: {}, classes: {}, keyframes: {} }); _defineProperty(this, "users", 0); this.value = value; this.options = options; this.options = merge(options, optionsDefault, { copy: true }); this.init(); } propertiesVersion() { let version = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'static'; let properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.properties; const value = { '@pure': {} }; properties[version].forEach(item => { if (item.value['@pure']) value['@pure'][item.property] = item.value;else value[item.property] = item.value; }); if (!Object.keys(value['@pure']).length) delete value['@pure']; return value; } set props(value) { const ids = is('array', value.ids) ? value.ids : [value.ids]; // Update all dynamic sheets from ids value this.sheets.dynamic.filter(sheet => ids.some(id => sheet.id === id)).forEach(sheet => { // Update sheet.props = value.props; }); this.amauiStyle.subscriptions.sheet_manager.update_props.emit(this, value); } get ids() { const ids = { static: [], dynamic: [] }; Object.keys(this.sheets).forEach(version => { this.sheets[version].forEach(sheet => ids[version].push(sheet.id)); }); return ids; } get response() { // Response this.values.css = ""; // Static this.sheets.static.forEach(sheet => { const { css } = sheet.response; if (css) { this.values.css += "\n".concat(css, "\n"); } }); // Dynamic this.sheets.dynamic.forEach(sheet => { const { css } = sheet.response; if (css) { this.values.css += "\n".concat(css, "\n"); } }); return this.values; } get css() { return this.response.css; } init() { var _this$options$style, _this$options$style$a; this.id = getID(); // Options this.mode = this.options.mode || this.mode; this.pure = this.options.pure !== undefined ? this.options.pure : this.pure; this.priority = this.options.priority || this.priority; this.amauiTheme = this.options.amauiTheme; this.amauiStyle = this.options.amauiStyle; // Inherits first from amauiStyle this.mode = this.amauiStyle.mode || this.mode; this.options.name = this.options.name || ((_this$options$style = this.options.style) === null || _this$options$style === void 0 ? void 0 : (_this$options$style$a = _this$options$style.attributes) === null || _this$options$style$a === void 0 ? void 0 : _this$options$style$a.method) || this.mode; // if value is an object if (is('object', this.value)) { // Props put into values.static and values.dynamic const versions = this.versions(this.value); // Add values to the properties Object.keys(versions).forEach(version => { versions[version].forEach(item => { this.properties[version].push(item); }); }); // Make a static sheet only if it doesn't already exist if (!!this.properties.static.length && !this.sheets.static.length) { new AmauiStyleSheet(this.propertiesVersion(), { version: 'static', mode: this.mode, pure: this.pure, priority: this.priority, amauiStyleSheetManager: this, amauiTheme: this.amauiTheme, amauiStyle: this.amauiStyle, props: {}, ...this.options }); } } // Update names with methods names(this.names); // Add to amauiStyle this.amauiStyle.sheet_managers.push(this); // Update inited status this.status = 'inited'; } add(props) { let response = { ids: { static: this.ids.static, dynamic: [] } }; response = merge(response, this.names, { copy: true }); const sheets = [...this.sheets.static]; // If no static sheet // Usecase React.StrictMode purposefull add / remove / add of elements // while preserving their state meaning it will add, remove the static sheet // yet reuse the AmauiStyleSheetManager instance if (!this.sheets.static.length) { if (!!this.properties.static.length) { const sheet = new AmauiStyleSheet(this.propertiesVersion(), { version: 'static', mode: this.mode, pure: this.pure, priority: this.priority, amauiStyleSheetManager: this, amauiTheme: this.amauiTheme, amauiStyle: this.amauiStyle, props: {}, ...this.options }); sheets.push(sheet); // Add dynamic names into the response response = merge(response, sheet.names, { copy: true }); // Add id to the response response.ids.static.push(sheet.id); } } // Reviving the static status removed if (!!this.sheets.static.length) this.sheets.static.filter(sheet => sheet.status === 'remove').forEach(sheet => sheet.update(this.propertiesVersion())); // Static sheets.filter(sheet => sheet.version === 'static').forEach(sheet => { // Add sheet.add(props); }); // if values.dynamic min 1 prop make a dynamic sheet if (!!this.properties.dynamic.length) { const sheet = new AmauiStyleSheet(this.propertiesVersion('dynamic'), { version: 'dynamic', mode: this.mode, pure: this.pure, priority: this.priority, amauiStyleSheetManager: this, amauiTheme: this.amauiTheme, amauiStyle: this.amauiStyle, props: {}, ...this.options }); // Add sheet.add(props); // atm sheets.push(sheet); // Add dynamic names into the response response = merge(response, sheet.names, { copy: true }); // Add id to the response response.ids.dynamic.push(sheet.id); } if (isEnvironment('browser')) { // Status this.status = 'active'; } // Update object names value names(response); // Update users value this.users++; this.amauiStyle.subscriptions.sheet_manager.add.emit(this); return response; } // Make sure to also call all the update hooks update(value) { // Make all props into remove, add, update props if (is('object', value)) { const versions = { previous: { static: this.properties.static, dynamic: this.properties.dynamic }, new: { static: [], dynamic: [] } }; // Props put into values.static and values.dynamic const versions_values = this.versions(value); // Add values to the versions new Object.keys(versions_values).forEach(version => { versions_values[version].forEach(item => { versions.new[version].push(item); }); }); // Update // Static if (!!versions.new.static.length) this.sheets.static.forEach(sheet => sheet.update(this.propertiesVersion('static', versions_values))); // Dynamic if (!!versions.new.dynamic.length) this.sheets.dynamic.forEach(sheet => sheet.update(this.propertiesVersion('dynamic', versions_values))); } const response = { ids: this.ids, ...this.names }; this.amauiStyle.subscriptions.sheet_manager.update.emit(this); return response; } remove() { let ids_ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; const ids = is('array', ids_) ? ids_ : [ids_]; // Remove all dynamic sheets from ids value this.sheets.dynamic.filter(sheet => ids.some(id => sheet.id === id)).forEach(sheet => { // Remove sheet.remove(); }); // Update users value this.users--; // If no more users if (!this.users) { this.sheets.static.forEach(sheet => { // Remove sheet.remove(); }); // If no more !sheets.static.length and !sheets.dynamic.length // update status to idle else update status to remove this.status = !this.sheets.static.length && !this.sheets.dynamic.length ? 'idle' : 'remove'; this.amauiStyle.subscriptions.sheet_manager.remove.emit(ids, this); } } versions(value) { const response = { static: [], dynamic: [] }; if (is('object', value)) { const pureValues = { static: {}, dynamic: {} }; // pure props Object.keys(value).filter(prop => value[prop]['@pure'] === true || value[prop]['@p'] === true).forEach(prop => { pureValues[!dynamic(value[prop]) ? 'static' : 'dynamic'][prop] = value[prop]; }); // @pure object const pure = merge(value['@pure'] || {}, value['@p'] || {}); Object.keys(pure).forEach(prop => { const isStatic = !dynamic(pure[prop]); pureValues[isStatic ? 'static' : 'dynamic'][prop] = { ...merge(pureValues[isStatic ? 'static' : 'dynamic'][prop] || {}, pure[prop]), '@pure': true }; }); // regular props Object.keys(value).filter(prop => ['@pure', '@p'].indexOf(prop) === -1 && !(value[prop]['@pure'] === true || value[prop]['@p'] === true)).forEach(prop => { response[!dynamic(value[prop]) ? 'static' : 'dynamic'].push({ property: prop, value: value[prop] }); }); // Merge pure and regular props response.static = [...Object.keys(pureValues.static).map(prop => ({ property: prop, value: pureValues.static[prop] })), ...response.static]; response.dynamic = [...Object.keys(pureValues.dynamic).map(prop => ({ property: prop, value: pureValues.dynamic[prop] })), ...response.dynamic]; } return response; } } export default AmauiStyleSheetManager;