import {Component_A} from './basic/as-component.js';
import {FP_Text_A} from './fp-ext/fp-text-ext.js';
import {ErrorCode} from '../exception/exceptionDesc.js';
/**
* @typedef TComponents.TextProps
* @prop {object} [options] Additional options for the text component.
* Items in this object include:
* - **responsive** (boolean, default: false): Whether the text component should be responsive.
* @prop {string} [tips] Tooltip text for the component.
* @prop {Function} [onCreated] Function to be called when the text component is created.
* @prop {Function} [onMounted] Function to be called when the text component is mounted.
* @prop {string} [textType] Type of the text content, e.g. 'body', 'header' or 'description'.
* @prop {string} [text] Text content to display.
* @prop {string} [backgroundColor] Background color of the text area.
* @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} [color] Text color.
* @prop {object} [font] Font configuration for the text.
* This object controls text appearance:
* - **fontSize** (number, default: 12): Font size in pixels.
* - **fontFamily** (string, default: 'Segoe UI'): Font family name.
* - **style** (object): Font style configuration, containing `fontStyle`, `fontWeight`, `textDecoration`.
* - **textAlign** (string, default: 'left'): Text alignment of the text.
* @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-text';
/**
* @description Text component that displays various types of text (e.g., headers, body, description) with customizable styles.
* This class focuses on the specific properties of the Text 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.Text
* @extends TComponents.Component_A
* @memberof TComponents
* @param {HTMLElement} parent - HTML element that is going to be the parent of the component
* @param {TComponents.TextProps} props
* @example
* const text = new TComponents.Text(document.body, {
* position: 'absolute',
* zIndex: 1000,
* text: 'Hello',
* color: '#000',
* });
*
* // Render the component.
* text.render();
*/
export class Text extends Component_A {
constructor(parent, props = {}) {
super(parent, props);
/**
* @instance
* @private
* @type {TComponents.TextProps}
*/
this._props;
this._text = new FP_Text_A();
}
/**
* @description Returns the default values of class properties (excluding parent properties).
* @member TComponents.Text#defaultProps
* @method
* @protected
* @returns {TComponents.TextProps}
*/
defaultProps() {
return {
options: {
responsive: false,
},
tips: '',
// life cycle
onCreated: '',
onMounted: '',
onDispose: '',
// content & type
textType: 'body',
text: 'This is a Text',
// background
backgroundColor: 'rgba(255,255,255,0)',
// ⭐ W/H/X/Y/B/R/Z: Component required attributes.
position: 'static',
width: 72,
height: 32,
top: 0,
left: 0,
borderRadius: 4,
rotation: 0,
zIndex: 0,
// color
color: '#000000',
// font
font: {
fontSize: 12,
fontFamily: 'Segoe UI',
style: {
fontStyle: 'normal',
fontWeight: 'normal',
textDecoration: 'none',
},
textAlign: 'left',
},
defaultState: 'show_enable',
dataStruct: '',
};
}
/**
* @description Initializes the component asynchronously.
* @memberof TComponents.Text#onInit
* @method
* @async
* @returns {Promise<void>}
*/
async onInit() {}
/**
* @description Renders the text component and applies the styles and properties.
* @member TComponents.Text#onRender
* @method
* @throws {Error} Throws error code ErrorCode.FailedToRunOnRender when runtime error happens.
* @returns {void}
*/
onRender() {
try {
this.removeAllEventListeners();
if (this._props.labelPos === 'left' || this._props.labelPos === 'right') {
this.container.classList.add('justify-stretch');
}
this._text.text = this._props.text;
this._text.textType = this._props.textType;
this._text.borderRadius = this._props.borderRadius;
this._text.color = this._props.color;
this._text.backgroundColor = this._props.backgroundColor;
this._text.font = this._props.font;
const textContainer = this.find('.tc-text');
if (Component_A._isHTMLElement(textContainer)) this._text.attachToElement(textContainer);
this._addTips();
Component_A.resolveBindingExpression(this._props.text, this);
} catch (e) {
// Runtime errors: write specific content to the log, throw error code
Logger.e(
logModule,
ErrorCode.FailedToRunOnRender,
`Error happens on onRender of Text component ${this.compId}.`,
e,
);
throw new Error(ErrorCode.FailedToRunOnRender, {cause: e});
}
}
/**
* @description Returns the markup for the text component.
* @member TComponents.Text#markup
* @method
* @returns {string} HTML markup for the text component.
*/
markup() {
return /*html*/ `<div class="tc-text"></div>`;
}
/**
* @returns {string}
*/
get text() {
return this._props.text;
}
/**
* @description Sets the text content.
* @member {string} TComponents.Text#text
* @instance
* @param {string} value - The text content.
* @example
* const text = new TComponents.Text(document.body, {
* position: 'absolute',
* zIndex: 1000,
* text: 'Hello',
* color: '#000',
* });
*
* text.render();
*
* // Set text value.
* text.text = 'new Text';
*/
set text(value) {
this.commitProps({text: value});
this._text.text = value;
}
/**
* @returns {string}
*/
get textType() {
return this._props.textType;
}
/**
* @description Sets the text type and adjusts corresponding styles.
* The supported text types are:
* - `Header1`
* - `Header2`
* - `Header3`
* - `Body`
* - `Description`
* - `Error`
* - `Warning`
* - `Success`
* - `Information`
* @member {string} TComponents.Text#textType
* @instance
* @param {string} t - The text type.
* @example
* const text = new TComponents.Text(document.body, {
* position: 'absolute',
* zIndex: 1000,
* text: 'Hello',
* color: '#000',
* });
*
* text.render();
*
* // Set text tyoe.
* text.textType = 'Header1';
*/
set textType(t) {
let textType = this._props.textType;
let color = this._props.color;
let font = Object.assign({}, this._props.font);
if (t == 'Header1') {
textType = 'h1';
color = '#000';
font.fontSize = 32;
font.fontWeight = 'bold';
} else if (t == 'Header2') {
textType = 'h2';
color = '#000';
font.fontSize = 24;
font.fontWeight = 'bold';
} else if (t == 'Header3') {
textType = 'h3';
color = '#000';
font.fontSize = 19;
font.fontWeight = 'bold';
} else if (t == 'Body') {
textType = 'body';
color = '#000';
font.fontSize = 16;
} else if (t == 'Description') {
textType = 'description';
color = '#888';
font.fontSize = 16;
} else if (t == 'Error') {
textType = 'error';
color = 'red';
} else if (t == 'Warning') {
textType = 'warning';
color = 'orange';
} else if (t == 'Success') {
textType = 'success';
color = 'green';
} else if (t == 'Information') {
textType = 'information';
color = 'blue';
} else {
Logger.w(logModule, ErrorCode.FailedToSetTextType, `Invalid textType for component ${this.compId}.`, t);
return;
}
this.setProps({textType: textType, color: color, font: font});
}
}
/**
* @description Add css properties to the component
* @member TComponents.Text.loadCssClassFromString
* @method
* @static
* @param {string} css - The css string to be loaded into style tag
* @returns {void}
* @example
* TComponents.Text.loadCssClassFromString(`
* .tc-text {
* height: inherit;
* }`
* );
*/
Text.loadCssClassFromString(/*css*/ `
.tc-text {
height: inherit;
width: 100%;
min-width: 0px;
min-height: 0px;
padding: 0px;
margin: 0px;
}
.tc-text .fp-components-text,
.tc-text .fp-components-text-disabled {
height: 100%;
width: 100%;
min-width: 0px;
min-height: 0px;
padding: 0px;
margin: 0px;
overflow: hidden;
text-overflow: ellipsis;
display: flex;
align-items: center;
}
.tc-text .fp-components-text-disabled{
cursor:not-allowed !important;
}
.tc-text .fp-components-text:hover,
.tc-text .fp-components-text-disabled:hover{
opacity:0.7;
}
.fp-components-text-h1 {
font-size: 2em;
font-weight: bold;
color: #000;
}
.fp-components-text-h2 {
font-size: 1.5em;
font-weight: bold;
color: #000;
}
.fp-components-text-h3 {
font-size: 1.17em;
font-weight: bold;
color: #000;
}
.fp-components-text-description {
font-size: 1em;
color: #888;
}
.fp-components-text-error {
color: red;
}
.fp-components-text-warning {
color: orange;
}
.fp-components-text-success {
color: green;
}
.fp-components-text-information {
color: blue;
}
`);