import {Component_A} from './basic/as-component.js';
import {Button} from './as-button.js';
import {Input} from './as-input.js';
import {ErrorCode, ExceptionIdMap} from '../exception/exceptionDesc.js';
/**
* @typedef TComponents.VarIncrDecrProps
* @prop {object} [options] Additional options for the VarIncrDecr component.
* Items in this object include:
* - **responsive** (boolean, default: false): Whether the component should be responsive.
* @prop {string} [tips] Tooltip text for the component.
* @prop {Function} [onCreated] Function to be called when the component is created.
* @prop {Function} [onMounted] Function to be called when the component is mounted.
* @prop {string} [position] CSS position property.
* @prop {number} [width] Width of the component.
* @prop {number} [height] Height of the component.
* @prop {number} [top] Top position of the component.
* @prop {number} [left] Left position of the component.
* @prop {number} [borderRadius] Border radius of the component.
* @prop {number} [rotation] Rotation angle of the component.
* @prop {number} [zIndex] Z-index of the component.
* @prop {string} [border] Border style of the component.
* @prop {string} [color] Text color of the variable field.
* @prop {string} [size] Size style template of the component.
* @prop {object} [font] Font configuration for the variable value.
* This object controls text appearance:
* - **fontSize** (number, default: 12): Font size in pixels.
* - **fontFamily** (string, default: 'Segoe UI'): Font family name.
* @prop {boolean} [readOnly] If true, the value is displayed and can only be changed by increment/decrement.
* @prop {boolean} [useBorder] Whether to draw a border around the variable field.
* @prop {object} [regex] Regular expression configuration for validation.
* This object defines validation behavior:
* - **label** (string, default: 'Number'): Description of the regex rule.
* - **value** (string): Regex pattern used to validate the input.
* @prop {string|number} [text] Initial text value bound to the variable.
* @prop {object} [inputVar] Input variable binding configuration.
* This object configures the bound input variable:
* - **type** (string): Binding variable type.
* - **func** (string): Binding mode.
* - **value** (string): Initial value or variable path used for binding.
* - **isHidden** (boolean, default: false): Whether this binding is hidden in variable selectors.
* @prop {Function} [onChange] Callback function when the value changes.
* @prop {string} [keyboardHelperDesc] Description text shown in the keyboard helper.
* @prop {string|number} [step] Increment/decrement step applied on each button click.
* @prop {object} [numRange] Numeric range configuration.
* This object controls allowed value range:
* - **min** (number|null): Minimum allowed value.
* - **max** (number|null): Maximum allowed value.
* @prop {string} [defaultState] Default state of the component.
* @prop {string} [dataStruct] Custom data structure metadata for integration with other systems.
* @memberof TComponents
*/
/**
* @ignore
*/
const logModule = 'as-varincrdecr';
/**
* Component connected to a variable together with increment and decrement buttons.
* This class focuses on the specific properties of the VarIncrDecr component'.
* Since it inherits from Accessor_A, all basic properties (e.g., height, width) are available but documented in the Accessor_A part.
* @class TComponents.VarIncrDecr
* @extends TComponents.Component_A
* @memberof TComponents
* @param {HTMLElement} parent - DOM element in which this component is to be inserted
* @param {TComponents.VarIncrDecrProps} [props] - Properties of the component
* @property {TComponents.VarIncrDecrProps} _props - Properties of the component
* @property {Object|null} _bindData - Data binding information
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*/
export class VarIncrDecr extends Component_A {
constructor(parent, props = {}) {
super(parent, props);
/**
* @instance
* @private
* @type {TComponents.VarIncrDecrProps}
*/
this._props;
/**
* If bound to web data, `this._bindData` will have the format: { type: 'webdata', key: 'xxx' }.
* If bound to digital signal data, `this._bindData` will have the format: { type: 'digitalsignal', key: 'xxxx' }.
* If bound to rapid data, `this._bindData` will have the format: { type: 'rapiddata', dataType: 'xxx', module: 'xxx', name: 'xxx', task: 'xxx' }.
* @type {object|null}
*/
this._bindData = null;
}
/**
* @returns {string}
*/
get text() {
return this.child.var.text;
}
/**
* @description Sets the text property. (recommended to use value instead)
* @member {string} TComponents.VarIncrDecr#text
* @instance
* @param {string} text - The new text value
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* // Sets the text to '100'
* varIncrDecr.text = '100';
*/
set text(text) {
this.value = text;
}
/**
* @returns {string}
*/
get textX() {
return this.text;
}
/**
* @description Sets the text property silently.
* This will update the value but will NOT trigger the `onchange` event.
* Recommended for internal or programmatic updates, where change notification is not desired.
* @member {string} TComponents.VarIncrDecr#textX
* @instance
* @param {string} text - The new text value
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body);
* await varIncrDecr.render();
*
* // Silent update (onchange will NOT be triggered)
* varIncrDecr.textX = '100';
*/
set textX(text) {
this.valueX = text;
}
/**
* @returns {number}
*/
get value() {
const text = this.child.var.text;
if (typeof text == 'string' && !isNaN(Number(text))) {
return Number(text);
}
return text;
}
/**
* @description Sets the value property. (TBD)
* @member {number} TComponents.VarIncrDecr#value
* @instance
* @param {string|number} value - The new value
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* // Sets the value to 100
* varIncrDecr.value = 100;
*/
set value(value) {
if (this._props.text === value) {
return;
}
if (typeof value == 'string' && !isNaN(Number(value))) {
this.child.var.text = Number(value);
return;
}
this.child.var.text = value;
}
/**
* @returns {number}
*/
get valueX() {
return this.value;
}
/**
* @description Sets the value silently.
* If the value is numeric (or a numeric string), it will be converted to Number automatically. This will NOT trigger the `onchange` event.
* Recommended when updating the component state programmatically without notifying listeners.
* @member {number|string} TComponents.VarIncrDecr#valueX
* @instance
* @param {number|string} value - The new value
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body);
* await varIncrDecr.render();
*
* // Silent update (onchange will NOT be triggered)
* varIncrDecr.valueX = 100;
*/
set valueX(value) {
if (this._props.text === value) {
return;
}
if (typeof value == 'string' && !isNaN(Number(value))) {
this.child.var.textX = Number(value);
} else {
this.child.var.textX = value;
}
this.commitProps({text: value});
}
/**
*
* @returns {boolean}
*/
get useBorder() {
return this._props.useBorder;
}
/**
* @description Sets the useBorder property.
* @member {boolean} TComponents.VarIncrDecr#useBorder
* @instance
* @param {boolean} b - The new useBorder value
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* varIncrDecr.useBorder = true; // Sets the useBorder to true
*/
set useBorder(b) {
this.setProps({useBorder: b});
}
/**
*
* @returns {number|string}
*/
get step() {
return this._props.step;
}
/**
* @description Sets the step value.
* @member {number} TComponents.VarIncrDecr#step
* @instance
* @param {number|string} n - The new step value
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* // Sets the step to 5
* varIncrDecr.step = 5;
*/
set step(n) {
this.setProps({
step: n,
});
}
/**
* @returns {string}
*/
get keyboardHelperDesc() {
return this._props.keyboardHelperDesc;
}
/**
* @description Sets the keyboard helper description.
* @member {string} TComponents.VarIncrDecr#keyboardHelperDesc
* @instance
* @param {string} s - The new keyboard helper description
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* varIncrDecr.keyboardHelperDesc = 'Press + or - to increment or decrement the value'; // Sets the keyboard helper description
*/
set keyboardHelperDesc(s) {
this.setProps({
keyboardHelperDesc: s,
});
}
/**
* @description Returns the default values of class properties (excluding parent properties).
* @member TComponents.VarIncrDecr#defaultProps
* @method
* @protected
* @returns {TComponents.VarIncrDecrProps}
*/
defaultProps() {
return {
options: {
responsive: false,
},
tips: '',
// life cycle
onCreated: '',
onMounted: '',
onDispose: '',
// basic properties: X/Y/W/H/B/R/Z
position: 'static',
width: 120,
height: 32,
top: 0,
left: 0,
borderRadius: 4,
rotation: 0,
zIndex: 0,
// border
border: '1px solid #dbdbdb',
// color
color: 'black',
// size template
size: '',
// font
font: {
fontSize: 12,
fontFamily: 'Segoe UI',
},
// Special properties.
readOnly: false,
useBorder: true,
regex: {
label: 'Number',
value: '^-?[0-9]+(\\.[0-9]+)?$',
},
// Input variable binding properties.
text: '0',
inputVar: {
type: 'num', // 'any' | 'string' | 'num' | 'bool'
func: 'custom', // 'custom' | 'sync'
value: '0', // string
isHidden: false,
},
onChange: '',
// Special properties.
keyboardHelperDesc: 'No description',
step: '1',
numRange: {
min: null,
max: null,
},
defaultState: 'show_enable',
dataStruct: '',
};
}
/**
* @description Initialize the component.
* @member TComponents.VarIncrDecr#onInit
* @method
* @async
* @returns {void}
*/
async onInit() {}
/**
* @description Handler for change events.
* @member TComponents.VarIncrDecr~_onChange
* @method
* @private
* @param {any} value - The new value
* @returns {void}
*/
async _onChange(value) {
const oldValue = this._props.text;
try {
const numValue = Number(value);
await this.syncInputData(numValue);
this.child.var.textX = numValue;
} catch (e) {
this.child.var.textX = oldValue;
Component_A.popupEventError(e, 'syncInputData', logModule);
return;
}
try {
var fn = Component_A.genFuncTemplate(this._props.onChange, this);
fn && (await fn(value));
} catch (e) {
Component_A.popupEventError(e, 'onChange', logModule);
}
}
/**
* @description Maps the internal components.
* @member TComponents.VarIncrDecr#mapComponents
* @method
* @returns {object} The mapped components
*/
mapComponents() {
const varIns = new Input(this.find('.tc-varincrdecr-var'), {
options: {
responsive: true,
},
height: 32,
width: 50,
border: 'none',
onChange: this._cbOnChange.bind(this),
keyboardHelperDesc: this._props.keyboardHelperDesc,
text: this._props.text,
regex: this._props.regex,
font: this._props.font,
});
varIns.enabled = this.enabled;
const incrValueIns = new Button(this.find('.tc-varincrdecr-incr'), {
options: {
responsive: true,
},
height: 32,
width: 25,
backgroundColor: '#ccc',
onClick: this.cbIncr.bind(this),
text: '+',
color: 'black',
border: 'none',
borderRadius: 0,
});
incrValueIns.enabled = this.enabled;
const decrValueIns = new Button(this.find('.tc-varincrdecr-decr'), {
options: {
responsive: true,
},
height: 32,
width: 25,
backgroundColor: '#ccc',
onClick: this.cbDecr.bind(this),
text: '-',
color: 'black',
border: 'none',
borderRadius: 0,
});
decrValueIns.enabled = this.enabled;
// Bind on-change event.
// varIns.cbOnChange = this.cbOnChange.bind(this);
varIns.on('render', () => {
varIns.container.style.cssText = '';
varIns.find('.fp-components-input').style.cssText = `color: ${this._props.color};`;
});
return {
var: varIns,
incrValue: incrValueIns,
decrValue: decrValueIns,
};
}
/**
* @description Renders the component.
* @member TComponents.VarIncrDecr#onRender
* @method
* @async
* @throws {Error}
* @returns {Promise<void>} A promise that resolves when the component is rendered.
*/
async onRender() {
try {
this.removeAllEventListeners();
if (this._props.inputVar.func == Component_A.INPUTVAR_FUNC.SYNC) {
// Parse bind data value.
this._bindData = Component_A.getBindData(this._props.inputVar.value, this);
}
const fpWrapEl = this.find('.fp-components-varincrdecr');
if (Component_A._isHTMLElement(fpWrapEl)) {
fpWrapEl.style.border = this._props.useBorder ? this._props.border : 'none';
fpWrapEl.style.boxSizing = 'border-box';
fpWrapEl.style.borderRadius = `${this._props.borderRadius}px`;
}
// render tc-item style.
this._renderChildComponent();
this._addTips();
Component_A.resolveBindingExpression(this._props.text, this, 'textX');
} catch (e) {
// Runtime errors: write specific content to the log, throw error code
Logger.e(
logModule,
ErrorCode.FailedToRunOnRender,
`Error happens on onRender of VarIncrDecr component ${this.compId}.`,
e,
);
throw new Error(ErrorCode.FailedToRunOnRender, {cause: e});
}
}
/**
* @description Returns the HTML markup for the component.
* @member TComponents.VarIncrDecr#markup
* @method
* @returns {string} The HTML markup
*/
markup() {
return /*html*/ `
<div class="tc-varincrdecr">
<div class="fp-components-varincrdecr">
<div class="tc-varincrdecr-decr tc-item"></div>
<div class="tc-varincrdecr-var tc-item"></div>
<div class="tc-varincrdecr-incr tc-item"></div>
</div>
</div>
`;
}
/**
* @description Adjusts the layout of the component responsively.
* @member TComponents.VarIncrDecr~_renderChildComponent
* @method
* @private
* @returns {void}
*/
_renderChildComponent() {
// Force remove the child component's width and height.
this.child.var.container.classList.add('tc-varincrdecr-input');
this.child.var.container.style.cssText = '';
this.child.incrValue.container.classList.add('tc-varincrdecr-button');
this.child.incrValue.container.style.cssText = `0px ${this._props.borderRadius}px ${this._props.borderRadius}px 0px`;
this.child.decrValue.container.classList.add('tc-varincrdecr-button');
this.child.decrValue.container.style.cssText = `${this._props.borderRadius}px 0px 0px ${this._props.borderRadius}px`;
const fontEls = this.all('.fp-components-button-text');
for (let index = 0; index < fontEls.length; index++) {
const el = fontEls[index];
el.style.fontSize = `${this._props.font.fontSize}px`;
el.style.fontFamily = this._props.font.fontFamily;
el.style.color = this._props.color;
}
const varFont = this.find('.fp-components-input');
if (Component_A._isHTMLElement(varFont)) {
varFont.style.fontSize = `${this._props.font.fontSize}px`;
varFont.style.fontFamily = this._props.font.fontFamily;
varFont.style.color = this._props.color;
}
}
/**
* @description Callback function which is called when the button is pressed, it triggers any function registered with {@link onChange() onChange}
* @member TComponents.VarIncrDecr~_cbOnChange
* @param {any} value - The new value
* @private
* @async
* @retures {Promise<void>}
* @param {*} value
*/
async _cbOnChange(value) {
return this.cbOnChange(value);
}
/**
* @description Callback function which is called when the button is pressed, it triggers any function registered with {@link onChange() onChange}
* @member TComponents.VarIncrDecr#cbOnChange
* @param {any} value - The new value
* @deprecated This method is deprecated and will be removed in future versions. Please use `_cbOnChange` instead.
* @private
* @async
* @retures {Promise<void>}
* @throws {Error} If the value exceeds the defined range, an error is thrown and a popup is displayed.
* @example
* // Example usage:
* varIncrDecr.cbOnChange(100); // Sets the value to 100 and triggers onChange event
*/
async cbOnChange(value) {
const numValue = Number(value);
if (this._props.numRange.max != null && numValue > this._props.numRange.max) {
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {
cause: `The value cannot exceed the maximum value. Maximum value: ${this._props.numRange.max}`,
}),
'onChange',
logModule,
);
this.child.var.text = this._props.numRange.max;
return;
}
if (this._props.numRange.min != null && numValue < this._props.numRange.min) {
// User operation failed, log detailed error stack information to the console
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {
cause: `The value cannot be less than the minimum value. Minimum value: ${this._props.numRange.min}`,
}),
'onChange',
logModule,
);
this.child.var.text = this._props.numRange.min;
return;
}
this._onChange(value);
}
/**
* @description Callback function to update variable when increment button is clicked.
* @member TComponents.VarIncrDecr#cbIncr
* @method
* @private
* @async
* @throws {Error} If the value exceeds the defined range, an error is thrown and a popup is displayed.
* @returns {Promise<void>}
*/
async cbIncr() {
const value = Number(this.child.var.text);
if (isNaN(value)) {
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {cause: 'The value is not a valid number.'}),
'Increment',
logModule,
);
return;
}
// fix float number
const incrVal = typeof this._props.step == 'number' ? this._props.step : Number(this._props.step);
const decimalPlaces = Math.max(
(value.toString().split('.')[1] || '').length,
(incrVal.toString().split('.')[1] || '').length,
);
const incrValue = Number((value + incrVal).toFixed(decimalPlaces));
if (this._props.numRange.max != null && incrValue > this._props.numRange.max) {
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {
cause: `The value cannot exceed the maximum value. Maximum value: ${this._props.numRange.max}`,
}),
'Increment',
logModule,
);
return;
}
if (this._props.numRange.min != null && incrValue < this._props.numRange.min) {
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {
cause: `The value cannot be less than the minimum value. Minimum value: ${this._props.numRange.min}`,
}),
'Increment',
logModule,
);
return;
}
this._onChange(incrValue);
}
/**
* @description Callback function to update variable when decrement button is clicked.
* @member TComponents.VarIncrDecr#cbDecr
* @method
* @private
* @async
* @throws {Error} If the value is not a valid number or if it goes below the minimum value, an error is thrown and a popup is displayed.
* @returns {Promise<void>}
*/
async cbDecr() {
const value = Number(this.child.var.text);
if (isNaN(value)) {
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {cause: 'The value is not a valid number.'}),
'Decrement',
logModule,
);
return;
}
// fix float number
const decrVal = typeof this._props.step == 'number' ? this._props.step : Number(this._props.step);
const decimalPlaces = Math.max(
(value.toString().split('.')[1] || '').length,
(decrVal.toString().split('.')[1] || '').length,
);
const decrValue = Number((value - decrVal).toFixed(decimalPlaces));
if (this._props.numRange.min != null && decrValue < this._props.numRange.min) {
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {
cause: `The value cannot be less than the minimum value. Minimum value: ${this._props.numRange.min}`,
}),
'Decrement',
logModule,
);
return;
}
if (this._props.numRange.max != null && decrValue > this._props.numRange.max) {
Component_A.popupEventError(
new Error(ErrorCode.FailedToSetNum, {
cause: `The value cannot exceed the maximum value. Maximum value: ${this._props.numRange.max}`,
}),
'Decrement',
logModule,
);
return;
}
this._onChange(decrValue);
}
/**
* @returns {Function|undefined}
*/
get onChange() {
const fn = Component_A.genFuncTemplate(this._props.onChange, this);
if (typeof fn == 'function') return fn;
else return undefined;
}
/**
* @description Sets the `onChange` event handler.
* The handler can either be a string representing a function to be executed or a function itself.
* 1. If you are using an arrow function, like `()=>{}`,
* the `this` property of the scope may not refer to the varIncrDecr object.
* 2. If you are using string assignment to define code execution,
* the string should contain `only the body of the code (executable statements)`,
* not a complete function declaration. Therefore, including function keywords like function or async function is incorrect.
* - Correct (Statements Only): `xx.onChange = "console.log('Action done.');"`
* - Incorrect (Function Declaration): `xx.onChange = "function() { console.log('Action done.'); }"`
* @member {Function} TComponents.VarIncrDecr#onChange
* @instance
* @returns {void}
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* // Example 1: Using a string as the handler:
* varIncrDecr.onChange = "console.log('state changed', this.text);";
* @example
* // Example 2: Using a arrow function as the handler:
* // Note that the `this` context will not refer to the varIncrDecr object
* varIncrDecr.onChange = () => { console.log('state changed', varIncrDecr.text); };
* @example
* // Example 3: Using a common function as the handler:
* varIncrDecr.onChange = async function() {
* console.log('state changed', this.text);
* };
*/
set onChange(t) {
this.setProps({onChange: t});
}
/**
* @returns {number}
*/
get max() {
return this._props.numRange.max;
}
/**
* @description Sets the maximum value in the number range.
* @member {number} TComponents.VarIncrDecr#max
* @instance
* @param {number} t - The new maximum value.
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* varIncrDecr.max = 100; // Sets the maximum value to 100
*/
set max(t) {
if (typeof t !== 'number') {
throw new Error(ErrorCode.FailedToSetNum, {
cause: `The max value must be a number.`,
});
}
if (t <= this.min || t < this.value) {
throw new Error(ErrorCode.FailedToSetMax, {
cause: `The max value must be larger than min value`,
});
}
const numRange = {
min: this._props.numRange.min,
max: t,
};
this.setProps({numRange: numRange});
}
/**
* @returns {number}
*/
get min() {
return this._props.numRange.min;
}
/**
* @description Sets the minimum value in the number range.
* @member {number} TComponents.VarIncrDecr#min
* @instance
* @param {number} t - The new minimum value.
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* varIncrDecr.min = 0; // Sets the minimum value to 0
*/
set min(t) {
if (typeof t !== 'number') {
throw new Error(ErrorCode.FailedToSetNum, {
cause: `The min value must be a number.`,
});
}
if (t >= this.max || t > this.value) {
throw new Error(ErrorCode.FailedToSetMin, {
cause: `The min value must be less than max value`,
});
}
const numRange = {
min: t,
max: this._props.numRange.max,
};
this.setProps({numRange: numRange});
}
/**
* @deprecated Use {@link TComponents.VarIncrDecr#max} instead.
*/
get maxValue() {
return this._props.numRange.max;
}
/**
* @deprecated Use {@link TComponents.VarIncrDecr#max} instead.
* @description Sets the maximum value in the number range.
* @member {number} TComponents.VarIncrDecr#maxValue
* @instance
* @param {number} t - The new maximum value.
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* varIncrDecr.maxValue = 100; // Sets the maximum value to 100
*/
set maxValue(n) {
this.setProps({
numRange: {
max: n,
},
});
}
/**
* @deprecated Use {@link TComponents.VarIncrDecr#min} instead.
*/
get minValue() {
return this._props.numRange.min;
}
/**
* @deprecated Use {@link TComponents.VarIncrDecr#min} instead.
* @description Sets the minimum value in the number range.
* @member {number} TComponents.VarIncrDecr#min
* @instance
* @param {number} t - The new minimum value.
* @example
* const varIncrDecr = new TComponents.VarIncrDecr(document.body, {
* position: 'absolute',
* zIndex: 1000,
* });
*
* // Render the component.
* await varIncrDecr.render();
*
* varIncrDecr.minValue = 0; // Sets the minimum value to 0
*/
set minValue(n) {
this.setProps({
numRange: {
min: n,
},
});
}
}
/**
* @description Add css properties to the component
* @member TComponents.VarIncrDecr.loadCssClassFromString
* @method
* @static
* @param {string} css - The css string to be loaded into style tag
* @returns {void}
* @example
* TComponents.VarIncrDecr.loadCssClassFromString(`
* .tc-varincrdecr {
* height: inherit;
* }`
* );
*/
VarIncrDecr.loadCssClassFromString(/*css*/ `
.tc-varincrdecr {
height: inherit;
width: 100%;
min-width: 0px;
min-height: 0px;
padding: 0px;
margin: 0px;
}
.tc-varincrdecr .fp-components-varincrdecr-disabled,
.tc-varincrdecr .fp-components-varincrdecr {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
min-width: 0px;
min-height: 0px;
display: flex;
flex-direction: row;
border: 1px groove #ccc;
overflow: hidden;
}
.tc-varincrdecr .fp-components-varincrdecr-disabled{
cursor:not-allowed !important;
}
.tc-varincrdecr .fp-components-varincrdecr:hover{
opacity:0.7;
}
.fp-components-varincrdecr .t-component{
padding: 0px !important;
margin: 0px !important;
}
.tc-varincrdecr .fp-components-button,
.tc-varincrdecr .fp-components-button-disabled {
border: none;
border-radius: 0px;
padding: 0px;
min-width: 30px;
}
.tc-varincrdecr .fp-components-input {
border: none;
border-radius: 0px;
min-height: 0px;
justify-content: center;
}
.tc-varincrdecr .tc-container-row {
align-items: center;
height: 100%;
width: 100%;
}
.tc-varincrdecr .fp-components-button-text {
font-weight: bold;
font-size: 18px;
line-height: 15px;
}
.tc-varincrdecr .tc-item {
padding: 0px;
}
.tc-varincrdecr .tc-item > .t-component {
height: 100%;
width: 100%;
padding:0 !important;
margin:0 !important;
}
.tc-varincrdecr .tc-varincrdecr-incr,
.tc-varincrdecr .tc-varincrdecr-decr {
height: 100%;
width: 25%;
}
.tc-varincrdecr .tc-varincrdecr-var {
height: 100%;
width: 50%;
}
.tc-varincrdecr .tc-varincrdecr-button,
.tc-varincrdecr .tc-button,
.tc-varincrdecr .fp-components-button,
.tc-varincrdecr .tc-varincrdecr-input,
.tc-varincrdecr .tc-input {
height: 100% !important;
width: 100% !important;
}
.tc-varincrdecr .fp-components-input-container {
height: 100%;
width: 100%;
padding-top: 0px;
padding-bottom: 0px;
}
.tc-varincrdecr .fp-components-input {
display: flex;
align-items: center;
}
`);