181 lines
4.5 KiB
JavaScript
181 lines
4.5 KiB
JavaScript
|
|
|
|
class Editor
|
|
{
|
|
#alias;
|
|
#templateLabel = field => field;
|
|
#templateDescription = field => field;
|
|
|
|
tabs = [];
|
|
fields = [];
|
|
|
|
|
|
constructor(alias)
|
|
{
|
|
this.#alias = alias;
|
|
}
|
|
|
|
|
|
get alias()
|
|
{
|
|
return this.#alias;
|
|
}
|
|
|
|
/**
|
|
* Overrides the string generation for the label
|
|
* @param {function} callback - Called when a label is constructed
|
|
*/
|
|
set onLabelCreate(callback)
|
|
{
|
|
if (typeof callback !== 'function')
|
|
{
|
|
console.warn(`[zero] onLabelCreate excepts a function as the first parameter`);
|
|
return;
|
|
}
|
|
this.#templateLabel = callback;
|
|
}
|
|
|
|
/**
|
|
* Overrides the string generation for the label description
|
|
* @param {function} callback - Called when a description is constructed
|
|
*/
|
|
set onDescriptionCreate(callback)
|
|
{
|
|
if (typeof callback !== 'function')
|
|
{
|
|
console.warn(`[zero] onDescriptionCreate excepts a function as the first parameter`);
|
|
return;
|
|
}
|
|
this.#templateDescription = callback;
|
|
}
|
|
|
|
|
|
/**
|
|
* A tab within an editor
|
|
* @typedef {object} EditorTab
|
|
* @param {string} alias - Alias for the tab
|
|
* @param {string} name - Name of the tab (can be a translation)
|
|
* @param {number|function} [count] - Output a count indicator
|
|
* @param {boolean|function} [disabled] - Conditionally disable the tab and its content
|
|
*/
|
|
|
|
/**
|
|
* Add a new tab to the editor
|
|
* @param {string} alias - Alias for the tab
|
|
* @param {string} name - Name of the tab (can be a translation)
|
|
* @param {number|function} [count] - Output a count indicator
|
|
* @param {boolean|function} [disabled] - Conditionally disable the tab and its content
|
|
* @returns {EditorTab}
|
|
*/
|
|
tab(alias, name, count, disabled)
|
|
{
|
|
if (typeof disabled !== 'undefined' && typeof disabled !== 'boolean' && typeof disabled !== 'function')
|
|
{
|
|
console.warn(`[zero] editor.tab: the disabled property has to be of type [boolean, function, undefined]`);
|
|
return;
|
|
}
|
|
|
|
if (typeof count !== 'undefined' && typeof count !== 'number' && typeof count !== 'function')
|
|
{
|
|
console.warn(`[zero] editor.tab: the count property has to be of type [number, function, undefined]`);
|
|
return;
|
|
}
|
|
|
|
if (this.tabs.find(x => x.alias === alias))
|
|
{
|
|
console.warn(`[zero] the editor ${this.#alias} does already have a tab with the alias ${alias}`);
|
|
return;
|
|
}
|
|
|
|
const tab = this._createTab(alias, name, disabled, count);
|
|
this.tabs.push(tab);
|
|
|
|
return tab;
|
|
}
|
|
|
|
|
|
/**
|
|
* Add a new tab to the editor
|
|
* @param {string} path - Model path
|
|
* @param {object} [options] - Custom options
|
|
* @param {string} [options.label] - A custom label for this field (otherwise it's generated via `onLabelCreate`)
|
|
* @param {string} [options.description] - A custom description for this field (otherwise it's generated via `onDescriptionCreate`)
|
|
* @param {string} [options.helpText] - Display a help text below the field
|
|
* @param {boolean|function} [options.condition] - Conditionally hide the field
|
|
* @param {boolean|function} [options.disabled=false] - Conditionally disable the field
|
|
* @param {string|object} [options.tab] - Add this field to a tab (by passing the alias or the tab instance)
|
|
* @param {string} [options.class] - Append HTML class to the generated property
|
|
* @returns {EditorField}
|
|
*/
|
|
field(path, options)
|
|
{
|
|
const field = new EditorField(path, options);
|
|
return field;
|
|
}
|
|
|
|
|
|
/**
|
|
* Create a new tab instance
|
|
* @returns {EditorTab}
|
|
*/
|
|
_createTab(alias, name, disabled, count)
|
|
{
|
|
return {
|
|
alias,
|
|
name,
|
|
disabled,
|
|
count,
|
|
field: (path, options) =>
|
|
{
|
|
options = options || {};
|
|
options.tab = alias;
|
|
return this.field(path, options);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
|
|
class EditorField
|
|
{
|
|
path = null;
|
|
options = {
|
|
label: null,
|
|
description: null,
|
|
helpText: null,
|
|
condition: null,
|
|
disabled: false,
|
|
tab: null,
|
|
class: ''
|
|
};
|
|
|
|
constructor(path, options)
|
|
{
|
|
this.path = path;
|
|
this.options = { ...this.options, ...options };
|
|
}
|
|
|
|
|
|
/**
|
|
* Render a text input field
|
|
* @param {callback} [maxLength] - Maximum length of the input
|
|
* @param {string} [placeholder] - Placeholder text (can be a translation)
|
|
*/
|
|
text(maxLength, placeholder)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Set this field as required
|
|
* @param {function} [condition] - Optionally only require this field when a condition is fulfilled
|
|
*/
|
|
required(condition)
|
|
{
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
export default Editor; |