@scania/tegel
Version:
Tegel Design System
601 lines (600 loc) • 23.2 kB
JavaScript
import { h } from "@stencil/core";
import generateUniqueId from "../../utils/generateUniqueId";
export class TdsDatetime {
constructor() {
this.getDefaultValue = () => {
const dateTimeObj = {
year: this.defaultValue.slice(0, 4),
month: this.defaultValue.slice(5, 7),
week: this.defaultValue.slice(6, 8),
day: this.defaultValue.slice(8, 10),
hours: this.defaultValue.slice(11, 13),
minutes: this.defaultValue.slice(14, 16),
};
switch (this.type) {
case 'datetime-local':
return `${dateTimeObj.year}-${dateTimeObj.month}-${dateTimeObj.day}T${dateTimeObj.hours}:${dateTimeObj.minutes}`;
case 'date':
return `${dateTimeObj.year}-${dateTimeObj.month}-${dateTimeObj.day}`;
case 'month':
return `${dateTimeObj.year}-${dateTimeObj.month}`;
case 'week':
return `${dateTimeObj.year}-W${dateTimeObj.week}`;
case 'time':
return `${this.defaultValue.slice(0, 2)}:${this.defaultValue.slice(3, 5)}`;
default:
throw new Error('Invalid type.');
}
};
this.type = 'datetime-local';
this.value = '';
this.min = undefined;
this.max = undefined;
this.defaultValue = 'none';
this.disabled = false;
this.size = 'lg';
this.noMinWidth = false;
this.modeVariant = null;
this.name = `datetime-${generateUniqueId()}`;
this.state = undefined;
this.autofocus = false;
this.label = '';
this.labelPosition = 'no-label';
this.helper = '';
this.tdsAriaLabel = undefined;
this.focusInput = undefined;
}
/** Method that resets the value of the Datetime, using defaultValue if is not 'none' */
async reset() {
this.internalReset();
this.tdsChange.emit({
name: this.name,
value: this.value,
});
}
/** Method that sets the value of the datetime element */
async setValue(newValue) {
this.value = newValue;
}
/** Method to programmatically focus the datetime element */
async focusElement() {
if (this.textInput) {
this.textInput.focus();
this.focusInput = true;
}
}
componentWillLoad() {
if (this.defaultValue !== 'none') {
this.value = this.getDefaultValue();
}
}
// Listener if input enters focus state
handleFocusIn() {
this.focusInput = true;
}
// Listener if input leaves focus state
handleFocusOut() {
this.focusInput = false;
}
// Data input event in value prop
handleInput(e) {
this.value = e.target.value;
this.tdsInput.emit(e);
}
// Change event isn't a composed:true by default in for input
handleChange(e) {
this.tdsChange.emit(e);
}
/** Set the input as focus when clicking the whole Datetime with suffix/prefix */
handleFocusClick(e) {
this.textInput.focus();
this.tdsFocus.emit(e);
}
/** Set the input as focus when clicking the whole Datetime with suffix/prefix */
handleBlur(e) {
this.textInput.blur();
this.tdsBlur.emit(e);
}
/** Method that resets the dateteime without emitting an event. */
internalReset() {
const value = '';
if (this.defaultValue !== 'none') {
this.value = this.getDefaultValue();
}
this.value = value;
}
connectedCallback() {
if (!this.tdsAriaLabel && !this.label) {
console.warn('Tegel Datetime component: provide the label or tdsAriaLabel prop for improved accessibility');
}
}
render() {
let className = ' tds-datetime-input';
if (this.size === 'md') {
className += `${className}-md`;
}
if (this.size === 'sm') {
className += `${className}-sm`;
}
const classNames = {
'tds-form-datetime-nomin': this.noMinWidth,
'tds-form-datetime': true,
'tds-datetime-focus': this.focusInput,
'tds-datetime-data': this.value.length > 0,
'tds-form-datetime-disabled': this.disabled,
[`tds-form-datetime-${this.size}`]: ['md', 'sm'].includes(this.size),
[`tds-form-datetime-${this.state}`]: ['error', 'success'].includes(this.state),
[`tds-mode-variant-${this.modeVariant}`]: this.modeVariant !== null,
'tds-datetime-container-label-inside': this.label && this.labelPosition === 'inside' && this.size !== 'sm',
};
const iphone = navigator.userAgent.toLowerCase().includes('iphone');
return (h("div", { key: '28c414fb800bb7e1411feb93b03b4ec4732e60fb', class: classNames, onKeyDown: (e) => {
if (e.key === 'Enter') {
const browserIsChrome = navigator.userAgent.toLowerCase().includes('chrome');
if (browserIsChrome) {
// showPicker currently only works reliably for date inputs in Chrome and Chromium-based browsers:
this.textInput.showPicker();
}
}
} }, this.labelPosition === 'outside' && this.label && (h("label", { key: '8498489db26eeffef963d57dd8aaaa27903e3e98', htmlFor: this.name, class: "tds-datetime-label" }, this.label)), h("div", { key: 'e62f09d543d12a3d9578bee5249171c85c7e3f03', onClick: (e) => this.handleFocusClick(e), class: "tds-datetime-container" }, h("div", { key: '0d083993b8f447918d0110ba78f18586d5afac1c', class: `tds-datetime-input-container type-${this.type}` }, h("input", { key: 'cdec8e9e1c8f355858031f34799fac7dd8d03c4b', ref: (inputEl) => {
this.textInput = inputEl;
}, class: className, type: this.type, disabled: this.disabled, value: this.value, min: this.min, max: this.max, autofocus: this.autofocus, name: this.name, id: this.name, onInput: (e) => this.handleInput(e), onBlur: (e) => this.handleBlur(e), onChange: (e) => this.handleChange(e), "aria-label": this.tdsAriaLabel ? this.tdsAriaLabel : this.label }), this.labelPosition === 'inside' && this.size !== 'sm' && this.label && (h("label", { key: 'f5ab00bd2a3dca4a46981da7e54ff6dcacfb6529', class: `tds-datetime-label-inside ${iphone && 'iphone'}`, htmlFor: this.name }, this.label)), h("div", { key: 'ce7799142c01703e7d3add1bc3d0fb474dec25e3', class: "datetime-icon icon-datetime-local" }, h("tds-icon", { key: '189b60ff034d2e0bc49e9461fc9970846a7e10a2', size: "20px", name: "calendar", svgTitle: "Calendar" })), h("div", { key: '192c46c706e8d8ca8613e832df2f77e981b64e2a', class: "datetime-icon icon-time" }, h("tds-icon", { key: 'e0cb4c98ccd40cb6d5b82d313aa48da8e4564b57', size: "20px", name: "clock", svgTitle: "Clock" }))), h("div", { key: '5a677ae45553060d459e1002741c0bed7ae1cefa', class: "tds-datetime-bar" })), this.helper && (h("div", { key: '0b132b2f580c3dffcfceff2ba8b4c2315ca8cd50', class: "tds-datetime-helper" }, h("div", { key: 'b17e1f96757072c8092e4cbe6e66b45b209a16ae', class: "tds-helper" }, this.state === 'error' && h("tds-icon", { key: '8afde58643e719da112bad1dcdc47f363c85490c', name: "error", size: "16px", svgTitle: "error" }), this.helper)))));
}
static get is() { return "tds-datetime"; }
static get encapsulation() { return "scoped"; }
static get originalStyleUrls() {
return {
"$": ["datetime.scss"]
};
}
static get styleUrls() {
return {
"$": ["datetime.css"]
};
}
static get properties() {
return {
"type": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'datetime-local' | 'date' | 'month' | 'week' | 'time'",
"resolved": "\"date\" | \"datetime-local\" | \"month\" | \"time\" | \"week\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Sets an input type"
},
"attribute": "type",
"reflect": true,
"defaultValue": "'datetime-local'"
},
"value": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Value of the input text"
},
"attribute": "value",
"reflect": true,
"defaultValue": "''"
},
"min": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Sets min value. Example for different types: datetime=\"2023-01-31T00:00\" date=\"2023-01-01\" time=\"15:00\""
},
"attribute": "min",
"reflect": false
},
"max": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Sets max value. Example for different types: datetime=\"2023-01-31T00:00\" date=\"2023-01-01\" time=\"15:00\""
},
"attribute": "max",
"reflect": false
},
"defaultValue": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string | 'none'",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Default value of the component. Format for time: HH-MM. Format for date: YY-MM-DD. Format for month: YY-MM. Format for week: YY-Www Format for date-time: YY-MM-DDTHH-MM"
},
"attribute": "default-value",
"reflect": false,
"defaultValue": "'none'"
},
"disabled": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set input in disabled state"
},
"attribute": "disabled",
"reflect": false,
"defaultValue": "false"
},
"size": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'sm' | 'md' | 'lg'",
"resolved": "\"lg\" | \"md\" | \"sm\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Size of the input"
},
"attribute": "size",
"reflect": false,
"defaultValue": "'lg'"
},
"noMinWidth": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Resets min width rule"
},
"attribute": "no-min-width",
"reflect": false,
"defaultValue": "false"
},
"modeVariant": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'primary' | 'secondary'",
"resolved": "\"primary\" | \"secondary\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set the variant of the Datetime component."
},
"attribute": "mode-variant",
"reflect": false,
"defaultValue": "null"
},
"name": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Name property. Uses a unique ID as fallback if not specified."
},
"attribute": "name",
"reflect": false,
"defaultValue": "`datetime-${generateUniqueId()}`"
},
"state": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Error state of input"
},
"attribute": "state",
"reflect": false
},
"autofocus": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Autofocus for input"
},
"attribute": "autofocus",
"reflect": false,
"defaultValue": "false"
},
"label": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Label text for the component"
},
"attribute": "label",
"reflect": false,
"defaultValue": "''"
},
"labelPosition": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'inside' | 'outside' | 'no-label'",
"resolved": "\"inside\" | \"no-label\" | \"outside\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Position of the label"
},
"attribute": "label-position",
"reflect": false,
"defaultValue": "'no-label'"
},
"helper": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Helper text for the component"
},
"attribute": "helper",
"reflect": false,
"defaultValue": "''"
},
"tdsAriaLabel": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Value for the aria-label attribute"
},
"attribute": "tds-aria-label",
"reflect": false
}
};
}
static get states() {
return {
"focusInput": {}
};
}
static get events() {
return [{
"method": "tdsChange",
"name": "tdsChange",
"bubbles": true,
"cancelable": false,
"composed": true,
"docs": {
"tags": [],
"text": "Change event for the Datetime"
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "tdsBlur",
"name": "tdsBlur",
"bubbles": true,
"cancelable": false,
"composed": true,
"docs": {
"tags": [],
"text": "Blur event for the Datetime"
},
"complexType": {
"original": "FocusEvent",
"resolved": "FocusEvent",
"references": {
"FocusEvent": {
"location": "global",
"id": "global::FocusEvent"
}
}
}
}, {
"method": "tdsFocus",
"name": "tdsFocus",
"bubbles": true,
"cancelable": false,
"composed": true,
"docs": {
"tags": [],
"text": "Focus event for the Datetime"
},
"complexType": {
"original": "FocusEvent",
"resolved": "FocusEvent",
"references": {
"FocusEvent": {
"location": "global",
"id": "global::FocusEvent"
}
}
}
}, {
"method": "tdsInput",
"name": "tdsInput",
"bubbles": true,
"cancelable": false,
"composed": true,
"docs": {
"tags": [],
"text": "Input event for the Datetime"
},
"complexType": {
"original": "InputEvent",
"resolved": "InputEvent",
"references": {
"InputEvent": {
"location": "global",
"id": "global::InputEvent"
}
}
}
}];
}
static get methods() {
return {
"reset": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Method that resets the value of the Datetime, using defaultValue if is not 'none'",
"tags": []
}
},
"setValue": {
"complexType": {
"signature": "(newValue: string) => Promise<void>",
"parameters": [{
"name": "newValue",
"type": "string",
"docs": ""
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Method that sets the value of the datetime element",
"tags": []
}
},
"focusElement": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Method to programmatically focus the datetime element",
"tags": []
}
}
};
}
static get listeners() {
return [{
"name": "focusin",
"method": "handleFocusIn",
"target": undefined,
"capture": false,
"passive": false
}, {
"name": "focusout",
"method": "handleFocusOut",
"target": undefined,
"capture": false,
"passive": false
}];
}
}