@amaui/style
Version:
CSS in JS styling solution
287 lines (286 loc) • 11.9 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const isEnvironment_1 = __importDefault(require("@amaui/utils/isEnvironment"));
const merge_1 = __importDefault(require("@amaui/utils/merge"));
const AmauiStyleSheet_1 = __importDefault(require("./AmauiStyleSheet"));
const utils_1 = require("./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, options = optionsDefault) {
this.value = value;
this.options = options;
this.status = 'idle';
this.mode = 'regular';
this.pure = false;
this.priority = 'upper';
this.values = {
css: '',
};
this.properties = {
static: [],
dynamic: [],
};
this.sheets = {
static: [],
dynamic: [],
};
this.names = {
classNames: {},
classes: {},
keyframes: {},
};
this.users = 0;
this.options = (0, merge_1.default)(options, optionsDefault, { copy: true });
this.init();
}
propertiesVersion(version = 'static', properties = 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 = ((0, utils_1.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${css}\n`;
}
});
// Dynamic
this.sheets.dynamic.forEach(sheet => {
const { css } = sheet.response;
if (css) {
this.values.css += `\n${css}\n`;
}
});
return this.values;
}
get css() {
return this.response.css;
}
init() {
var _a, _b;
this.id = (0, utils_1.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 || ((_b = (_a = this.options.style) === null || _a === void 0 ? void 0 : _a.attributes) === null || _b === void 0 ? void 0 : _b.method) || this.mode;
// if value is an object
if ((0, utils_1.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_1.default(this.propertiesVersion(), Object.assign({ 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
(0, utils_1.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 = (0, merge_1.default)(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_1.default(this.propertiesVersion(), Object.assign({ 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 = (0, merge_1.default)(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_1.default(this.propertiesVersion('dynamic'), Object.assign({ 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 = (0, merge_1.default)(response, sheet.names, { copy: true });
// Add id to the response
response.ids.dynamic.push(sheet.id);
}
if ((0, isEnvironment_1.default)('browser')) {
// Status
this.status = 'active';
}
// Update object names value
(0, utils_1.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 ((0, utils_1.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 = Object.assign({ ids: this.ids }, this.names);
this.amauiStyle.subscriptions.sheet_manager.update.emit(this);
return response;
}
remove(ids_ = []) {
const ids = (0, utils_1.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 ((0, utils_1.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[!(0, utils_1.dynamic)(value[prop]) ? 'static' : 'dynamic'][prop] = value[prop];
});
// @pure object
const pure = (0, merge_1.default)(value['@pure'] || {}, value['@p'] || {});
Object.keys(pure).forEach(prop => {
const isStatic = !(0, utils_1.dynamic)(pure[prop]);
pureValues[isStatic ? 'static' : 'dynamic'][prop] = Object.assign(Object.assign({}, ((0, merge_1.default)(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[!(0, utils_1.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;
}
}
exports.default = AmauiStyleSheetManager;