@freshworks/crayons
Version:
Crayons Web Components library
529 lines (528 loc) • 15.3 kB
JavaScript
import { Component, Element, Prop, State, h, Method, Event, } from '@stencil/core';
import { parse, format, addMinutes } from 'date-fns';
import { enUS } from 'date-fns/locale';
import { renderHiddenField } from '../../utils';
export class Timepicker {
constructor() {
/**
* State for all the time values
*/
this.timeValues = [];
/**
* Format in which time values are populated in the list box. If the value is hh:mm p, the time values are in the 12-hour format. If the value is hh:mm, the time values are in the 24-hr format.
*/
this.format = 'hh:mm a';
/**
* Set true to disable the element
*/
this.disabled = false;
/**
* Represent the intervals and can be a number or array of numbers representing the minute values in an hour
*/
this.isMeridianFormat = this.format === 'hh:mm a';
/**
* Name of the component, saved as part of form data.
*/
this.name = '';
/**
* Time interval between the values displayed in the list, specified in minutes.
*/
this.interval = 30;
/**
* Lower time-limit for the values displayed in the list. If this attribute's value is in the hh:mm format, it is assumed to be hh:mm AM.
*/
this.minTime = this.isMeridianFormat ? '12:00 AM' : '00:00';
/**
* Upper time-limit for the values displayed in the list. If this attribute's value is in the hh:mm format, it is assumed to be hh:mm AM.
*/
this.maxTime = this.isMeridianFormat ? '11:30 PM' : '23:30';
/**
* Specifies the input box as a mandatory field and displays an asterisk next to the label. If the attribute's value is undefined, the value is set to false.
*/
this.required = false;
/**
* Theme based on which the input of the timepicker is styled.
*/
this.state = 'normal';
/**
* Hint text displayed below the text box.
*/
this.hintText = '';
/**
* Warning text displayed below the text box.
*/
this.warningText = '';
/**
* Error text displayed below the text box.
*/
this.errorText = '';
/**
* Label displayed on the interface, for the component.
*/
this.label = '';
/**
* Placement of the options list with respect to timepicker.
*/
this.optionsPlacement = 'bottom';
/**
* Whether the arrow/caret should be shown in the timepicker.
*/
this.caret = true;
/**
* Boolean representing whethere it is default end time
*/
this.isDefaultEndTime = ['11:30 PM', '23:30'].includes(this.maxTime);
this.getTimeOptionsMeta = (nonMeridianFormat) => {
const preferredFormat = this.format;
const timeIntervalArgs = {
interval: this.interval,
startTime: format(parse(this.minTime, preferredFormat, new Date()), nonMeridianFormat, {
locale: enUS,
}),
endTime: format(parse(this.maxTime, preferredFormat, new Date()), nonMeridianFormat, {
locale: enUS,
}),
};
return timeIntervalArgs;
};
this.setTimeValues = () => {
const meridianFormat = 'hh:mm a';
const nonMeridianFormat = 'HH:mm';
const { interval, startTime, endTime } = this.getTimeOptionsMeta(nonMeridianFormat);
parse(startTime, nonMeridianFormat, new Date()).valueOf();
let currentTimeInMs = parse(startTime, nonMeridianFormat, new Date()).valueOf();
const endTimeInMs = parse(endTime, nonMeridianFormat, new Date()).valueOf();
while (currentTimeInMs <= endTimeInMs) {
this.timeValues.push({
meridianFormat: format(currentTimeInMs, meridianFormat, {
locale: enUS,
}),
nonMeridianFormat: format(currentTimeInMs, nonMeridianFormat, {
locale: enUS,
}),
});
currentTimeInMs = addMinutes(currentTimeInMs, interval).valueOf();
}
};
this.onBlur = (e) => {
this.fwBlur.emit({
event: e,
name: this.name,
});
};
this.onFocus = () => {
this.fwFocus.emit();
};
}
currentTimeLabel(time) {
return this.isMeridianFormat ? time.meridianFormat : time.nonMeridianFormat;
}
currentTimeValue(time) {
return time.nonMeridianFormat;
}
setTimeValue(e) {
const { value } = e.detail;
if (value)
this.fwChange.emit({
event: e,
name: this.name,
value: value,
});
}
setEndTime() {
if (this.isDefaultEndTime) {
this.maxTime = this.isMeridianFormat ? `11:59 PM` : `23:59`;
}
}
/**
* Sets focus on a specific `fw-timepicker`.
*/
async setFocus() {
if (this.nativeInput) {
this.nativeInput.focus();
}
}
componentWillLoad() {
if (this.interval !== 30) {
this.setEndTime();
}
this.setTimeValues();
}
render() {
const { host, name, value } = this;
renderHiddenField(host, name, value);
return (h("div", { class: 'timepicker' },
h("fw-select", { name: this.name, label: this.label, hintText: this.hintText, errorText: this.errorText, warningText: this.warningText, disabled: this.disabled, value: this.value, required: this.required, onFwChange: (e) => this.setTimeValue(e), onFwBlur: this.onBlur, ref: (el) => (this.nativeInput = el), state: this.state, placeholder: this.placeholder, search: false, optionsPlacement: this.optionsPlacement, caret: this.caret }, this.timeValues.map((time) => (h("fw-select-option", { value: this.currentTimeValue(time) }, this.currentTimeLabel(time)))))));
}
static get is() { return "fw-timepicker"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() { return {
"$": ["timepicker.scss"]
}; }
static get styleUrls() { return {
"$": ["timepicker.css"]
}; }
static get properties() { return {
"format": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'hh:mm a' | 'HH:mm'",
"resolved": "\"HH:mm\" | \"hh:mm a\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Format in which time values are populated in the list box. If the value is hh:mm p, the time values are in the 12-hour format. If the value is hh:mm, the time values are in the 24-hr format."
},
"attribute": "format",
"reflect": false,
"defaultValue": "'hh:mm a'"
},
"disabled": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Set true to disable the element"
},
"attribute": "disabled",
"reflect": false,
"defaultValue": "false"
},
"value": {
"type": "string",
"mutable": true,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Time output value"
},
"attribute": "value",
"reflect": false
},
"name": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Name of the component, saved as part of form data."
},
"attribute": "name",
"reflect": false,
"defaultValue": "''"
},
"interval": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Time interval between the values displayed in the list, specified in minutes."
},
"attribute": "interval",
"reflect": false,
"defaultValue": "30"
},
"minTime": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Lower time-limit for the values displayed in the list. If this attribute's value is in the hh:mm format, it is assumed to be hh:mm AM."
},
"attribute": "min-time",
"reflect": false,
"defaultValue": "this.isMeridianFormat ? '12:00 AM' : '00:00'"
},
"maxTime": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Upper time-limit for the values displayed in the list. If this attribute's value is in the hh:mm format, it is assumed to be hh:mm AM."
},
"attribute": "max-time",
"reflect": false,
"defaultValue": "this.isMeridianFormat ? '11:30 PM' : '23:30'"
},
"required": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies the input box as a mandatory field and displays an asterisk next to the label. If the attribute's value is undefined, the value is set to false."
},
"attribute": "required",
"reflect": false,
"defaultValue": "false"
},
"state": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'normal' | 'warning' | 'error'",
"resolved": "\"error\" | \"normal\" | \"warning\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Theme based on which the input of the timepicker is styled."
},
"attribute": "state",
"reflect": false,
"defaultValue": "'normal'"
},
"hintText": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Hint text displayed below the text box."
},
"attribute": "hint-text",
"reflect": false,
"defaultValue": "''"
},
"warningText": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Warning text displayed below the text box."
},
"attribute": "warning-text",
"reflect": false,
"defaultValue": "''"
},
"errorText": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Error text displayed below the text box."
},
"attribute": "error-text",
"reflect": false,
"defaultValue": "''"
},
"label": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Label displayed on the interface, for the component."
},
"attribute": "label",
"reflect": false,
"defaultValue": "''"
},
"placeholder": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string | null",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Text displayed in the select before an option is selected."
},
"attribute": "placeholder",
"reflect": false
},
"optionsPlacement": {
"type": "string",
"mutable": false,
"complexType": {
"original": "PopoverPlacementType",
"resolved": "\"bottom\" | \"bottom-end\" | \"bottom-start\" | \"left\" | \"left-end\" | \"left-start\" | \"right\" | \"right-end\" | \"right-start\" | \"top\" | \"top-end\" | \"top-start\"",
"references": {
"PopoverPlacementType": {
"location": "import",
"path": "../../utils/types"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Placement of the options list with respect to timepicker."
},
"attribute": "options-placement",
"reflect": true,
"defaultValue": "'bottom'"
},
"caret": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Whether the arrow/caret should be shown in the timepicker."
},
"attribute": "caret",
"reflect": false,
"defaultValue": "true"
}
}; }
static get states() { return {
"timeValues": {},
"isMeridianFormat": {},
"isDefaultEndTime": {}
}; }
static get events() { return [{
"method": "fwChange",
"name": "fwChange",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Triggered when a value is selected or deselected from the list box options."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "fwBlur",
"name": "fwBlur",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Triggered when the list box loses focus."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}, {
"method": "fwFocus",
"name": "fwFocus",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "Triggered when the list box comes into focus."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}]; }
static get methods() { return {
"setFocus": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Sets focus on a specific `fw-timepicker`.",
"tags": []
}
}
}; }
static get elementRef() { return "host"; }
}