@3t-transform/threeteeui 0.2.107 → 0.2.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/tttx-checkbox.cjs.entry.js +1 -1
- package/dist/cjs/tttx-form.cjs.entry.js +184 -28
- package/dist/collection/components/atoms/tttx-checkbox/tttx-checkbox.js +1 -1
- package/dist/collection/components/molecules/tttx-form/lib/validityCheck.js +3 -1
- package/dist/collection/components/molecules/tttx-form/tttx-form.css +19 -0
- package/dist/collection/components/molecules/tttx-form/tttx-form.js +180 -26
- package/dist/collection/components/molecules/tttx-form/tttx-form.stories.js +64 -10
- package/dist/components/tttx-checkbox.js +1 -1
- package/dist/components/tttx-form.js +184 -28
- package/dist/esm/tttx-checkbox.entry.js +1 -1
- package/dist/esm/tttx-form.entry.js +184 -28
- package/dist/tttx/{p-61ef7773.entry.js → p-69e15a92.entry.js} +1 -1
- package/dist/tttx/p-91cf9bd4.entry.js +1 -0
- package/dist/tttx/tttx.esm.js +1 -1
- package/dist/types/components/molecules/tttx-form/tttx-form.d.ts +14 -0
- package/dist/types/components/molecules/tttx-form/tttx-form.stories.d.ts +64 -8
- package/package.json +4 -4
- package/dist/tttx/p-b2cfa283.entry.js +0 -1
|
@@ -121,6 +121,30 @@ const formSchema = {
|
|
|
121
121
|
},
|
|
122
122
|
},
|
|
123
123
|
},
|
|
124
|
+
startend: {
|
|
125
|
+
type: 'string',
|
|
126
|
+
format: 'string',
|
|
127
|
+
form: {
|
|
128
|
+
type: 'startenddate',
|
|
129
|
+
includeTime: true
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
expiration: {
|
|
133
|
+
type: 'radio',
|
|
134
|
+
form: {
|
|
135
|
+
type: 'radio',
|
|
136
|
+
label: 'Expiration',
|
|
137
|
+
options: [
|
|
138
|
+
{ label: 'Never expires', value: 'neverExpires' },
|
|
139
|
+
{ label: 'Will expire', value: 'willExpire' },
|
|
140
|
+
],
|
|
141
|
+
validation: {
|
|
142
|
+
required: {
|
|
143
|
+
message: 'Please select validity',
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
},
|
|
124
148
|
permissions: {
|
|
125
149
|
form: {
|
|
126
150
|
type: 'checkbox',
|
|
@@ -146,6 +170,9 @@ SingleFormItem.args = {
|
|
|
146
170
|
type: 'text',
|
|
147
171
|
label: 'Input Field',
|
|
148
172
|
validation: {
|
|
173
|
+
invalid: {
|
|
174
|
+
message: "This field is invalid"
|
|
175
|
+
},
|
|
149
176
|
required: {
|
|
150
177
|
message: 'Please enter something',
|
|
151
178
|
},
|
|
@@ -155,6 +182,21 @@ SingleFormItem.args = {
|
|
|
155
182
|
},
|
|
156
183
|
},
|
|
157
184
|
};
|
|
185
|
+
export const StartAndEndDateWithoutTime = args => `<tttx-form formSchema='${JSON.stringify(args.formSchema)}'></tttx-form>`;
|
|
186
|
+
StartAndEndDateWithoutTime.args = {
|
|
187
|
+
formSchema: {
|
|
188
|
+
properties: {
|
|
189
|
+
startend: {
|
|
190
|
+
type: 'string',
|
|
191
|
+
format: 'string',
|
|
192
|
+
form: {
|
|
193
|
+
type: 'startenddate',
|
|
194
|
+
includeTime: false
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
};
|
|
158
200
|
export const ExampleFormFromJSON = args => `<tttx-form id='form' formSchema='${JSON.stringify(args.formSchema)}'></tttx-form>
|
|
159
201
|
<hr/>
|
|
160
202
|
<button type='button' id='button'>Submit Form</button>
|
|
@@ -289,16 +331,12 @@ const formSchemaWithReadonly = {
|
|
|
289
331
|
},
|
|
290
332
|
},
|
|
291
333
|
},
|
|
292
|
-
|
|
334
|
+
startend: {
|
|
335
|
+
type: 'string',
|
|
336
|
+
format: 'string',
|
|
293
337
|
form: {
|
|
294
|
-
type: '
|
|
295
|
-
|
|
296
|
-
inlineLabel: 'Please grant permissions to use data',
|
|
297
|
-
validation: {
|
|
298
|
-
required: {
|
|
299
|
-
message: 'Please grant permissions to use data',
|
|
300
|
-
},
|
|
301
|
-
},
|
|
338
|
+
type: 'startenddate',
|
|
339
|
+
includeTime: true
|
|
302
340
|
},
|
|
303
341
|
},
|
|
304
342
|
expiration: {
|
|
@@ -317,6 +355,18 @@ const formSchemaWithReadonly = {
|
|
|
317
355
|
},
|
|
318
356
|
},
|
|
319
357
|
},
|
|
358
|
+
permissions: {
|
|
359
|
+
form: {
|
|
360
|
+
type: 'checkbox',
|
|
361
|
+
label: 'Permissions',
|
|
362
|
+
inlineLabel: 'Please grant permissions to use data',
|
|
363
|
+
validation: {
|
|
364
|
+
required: {
|
|
365
|
+
message: 'Please grant permissions to use data',
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
},
|
|
320
370
|
},
|
|
321
371
|
};
|
|
322
372
|
const data = {
|
|
@@ -328,7 +378,11 @@ const data = {
|
|
|
328
378
|
dob: '1973-06-02',
|
|
329
379
|
dropdown: 'chicken',
|
|
330
380
|
permissions: 'on',
|
|
331
|
-
expiration: 'willExpire'
|
|
381
|
+
expiration: 'willExpire',
|
|
382
|
+
'startend-startdate': '2021-09-01',
|
|
383
|
+
'startend-starttime': '09:00',
|
|
384
|
+
'startend-enddate': '2024-10-15',
|
|
385
|
+
'startend-endtime': '17:00'
|
|
332
386
|
};
|
|
333
387
|
export const PrePopulateForm = args => `<tttx-form id='form' formSchema='${JSON.stringify(args.formSchema)}' data='${JSON.stringify(args.data)}'></tttx-form>
|
|
334
388
|
<hr/>
|
|
@@ -30,7 +30,7 @@ const TttxCheckbox$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElemen
|
|
|
30
30
|
render() {
|
|
31
31
|
const checkBoxIcon = this.checked ? 'check_box' : 'check_box_outline_blank';
|
|
32
32
|
const renderedIcon = this.indeterminate ? 'indeterminate_check_box' : checkBoxIcon;
|
|
33
|
-
return (h(Host, null, h("label", { class: `tttx-checkbox ${this.inline ? '--inline' : ''}` }, h("input", { class: "tttx-checkbox__input", type: "checkbox", id: this.checkboxId, checked: this.checked, ref: (el) => this.checkbox = el }), h("tttx-icon", { color: this.checked ? 'blue' :
|
|
33
|
+
return (h(Host, null, h("label", { class: `tttx-checkbox ${this.inline ? '--inline' : ''}` }, h("input", { class: "tttx-checkbox__input", type: "checkbox", id: this.checkboxId, checked: this.checked, ref: (el) => this.checkbox = el }), h("tttx-icon", { color: this.checked ? 'blue' : 'grey', icon: renderedIcon, onClick: this.onClick.bind(this) }), h("span", { class: "tttx-checkbox__label" }, this.label))));
|
|
34
34
|
}
|
|
35
35
|
static get watchers() { return {
|
|
36
36
|
"indeterminate": ["watchIndeterminateChange"]
|
|
@@ -11,7 +11,9 @@ import { p as purify, d as domSanitiserOptions } from './domsanitiser.options.js
|
|
|
11
11
|
*/
|
|
12
12
|
function validityCheck(event) {
|
|
13
13
|
var _a, _b, _c, _d;
|
|
14
|
-
event.preventDefault
|
|
14
|
+
if (event.preventDefault) {
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
}
|
|
15
17
|
const target = event.target;
|
|
16
18
|
let hasError = true;
|
|
17
19
|
let errorMessage = '';
|
|
@@ -124,7 +126,7 @@ function setErrorState(target, hasError, errorMessage, parent = undefined) {
|
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
|
|
127
|
-
const tttxFormCss = ".material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}.material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}label{font-weight:500;font-size:16px;line-height:19px;color:#212121}label .optional{color:#757575;font-weight:normal}label .outer-container{position:relative}label .outer-container .left-icons,label .outer-container .right-icons{display:flex;position:absolute;height:24px;gap:8px}label .outer-container .left-icons tttx-icon,label .outer-container .right-icons tttx-icon{height:24px;width:24px}label .outer-container .left-icons{left:8px}label .outer-container .right-icons{right:8px}label .outer-container input{color:#212121;box-sizing:border-box;border:1px solid #d5d5d5;border-radius:4px;padding:0;padding-left:16px;padding-right:16px;margin-top:4px;}label .outer-container input.has-input-icon{padding-left:40px}label .outer-container input.has-input-icon.has-left-icon{padding-left:72px}label .outer-container input.has-left-icon{padding-left:40px}label .outer-container input.has-right-icon{padding-right:40px}label .outer-container input.invalid{border:1px solid #dc0000}label .outer-container input:not([type=submit]){font-family:\"Roboto\", serif;width:100%;height:36px;font-size:16px;line-height:19px}label .outer-container input[type=radio]{width:20px;height:20px}label .outer-container input[type=date]{background:white;display:block;min-width:calc(100% - 18px);line-height:37px}label .outer-container input[readonly]{cursor:default;pointer-events:none;user-select:none;color:gray}label .outer-container input:focus{border-color:#1479c6}label .outer-container input:focus-visible{outline:none}label .outer-container.inputBlock{display:flex;align-items:center;line-height:21px}label .outer-container.inputBlock .left-icons,label .outer-container.inputBlock .right-icons{margin-top:4px}label .outer-container.inputBlock.readonly{pointer-events:none;user-select:none;color:gray}label .outer-container.inputBlock.radioBlock{display:block}label .outer-container.inputInline{display:flex;white-space:nowrap;align-items:center;margin:0}label .outer-container.inputInline input{margin-top:0}label .secondarylabel{color:#757575;font-size:14px;line-height:16px;font-weight:normal;display:flex;margin-top:4px}label .errorBubble{position:relative;font-size:14px;line-height:16px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center;margin-top:4px}label .errorBubble:not(.visible){display:none}label .errorBubble span{color:#dc0000;font-size:16px;margin-right:4px}.material-symbols-rounded{font-family:\"Material Symbols Rounded\", sans-serif;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:#9e9e9e}button{cursor:pointer}.button{font-family:Roboto, serif;box-sizing:border-box;height:36px;min-width:36px;padding:0;margin:0;background:transparent;color:#212121;border:1px solid #c8c8c8;border-radius:4px;text-transform:uppercase;display:flex;justify-content:left;align-items:center;font-size:14px;font-weight:500}.button-content{display:block;padding:0 16px}.icon-left,.icon-right{margin-top:4px}.iconleft{padding-left:8px}.iconleft .button-content{padding-left:4px}.iconright{padding-right:8px}.iconright .button-content{padding-right:4px}.notext{padding:0 6px}.button:active{background:rgba(17, 17, 17, 0.2);border:1px solid #d5d5d5}.primary{background:#1479c6;border:1px solid #1479c6;color:white}.primary:active{background:#1464a2;border:1px solid #1464a2}.borderless{background:transparent;border:none;color:#212121}.borderless:active{background:rgba(17, 17, 17, 0.2);border:none}.borderless-circle{background:transparent;border:none;color:#212121;border-radius:50%}.borderless-circle:active{border:none}.borderless-circle:focus{border-color:transparent}.danger{background:#dc0000;border:1px solid #dc0000;color:white}.danger:active{background:#b00000;border:1px solid #b00000}.disabled{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}.disabled:active{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}@media (hover: hover){.button:hover{background:rgba(17, 17, 17, 0.1);border:1px solid #d5d5d5}.primary:hover{background:#146eb3;border:1px solid #146eb3}.borderless:hover{background:rgba(17, 17, 17, 0.1);border:none}.borderless-circle:hover{background:rgba(17, 17, 17, 0.1);border:none}.danger:hover{background:#c60000;border:1px solid #c60000}.disabled:hover{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}}:host{display:block}fieldset{margin:0;padding:0;border:none}label{display:block;position:relative;margin-bottom:16px}.inlineLabel{font-weight:400;display:inline-block;vertical-align:top;padding-top:4px}input[type=checkbox]{width:18px;height:18px}input~label{font-weight:400}select{font-family:\"Roboto\", serif;box-sizing:border-box;width:100%;height:36px;padding:0 16px;font-size:16px;border:1px solid #d5d5d5;border-radius:4px;margin-top:4px}.placeholder{color:#9e9e9e}.placeholder option{color:initial}select.invalid:invalid{border:1px solid #dc0000}select~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center}select~.errorBubble:not(.visible){visibility:hidden}select~.errorBubble span{color:#dc0000;font-size:16px;margin-right:4px;height:16px}select.invalid:invalid~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;visibility:visible}select:focus{border-color:#1479c6}select:focus-visible{outline:none}.button{padding:0 16px}.footer{display:flex;gap:16px;flex-direction:row-reverse}";
|
|
129
|
+
const tttxFormCss = ".material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}.material-symbols-rounded{font-variation-settings:\"FILL\" 1, \"wght\" 400, \"GRAD\" 0, \"opsz\" 24}label{font-weight:500;font-size:16px;line-height:19px;color:#212121}label .optional{color:#757575;font-weight:normal}label .outer-container{position:relative}label .outer-container .left-icons,label .outer-container .right-icons{display:flex;position:absolute;height:24px;gap:8px}label .outer-container .left-icons tttx-icon,label .outer-container .right-icons tttx-icon{height:24px;width:24px}label .outer-container .left-icons{left:8px}label .outer-container .right-icons{right:8px}label .outer-container input{color:#212121;box-sizing:border-box;border:1px solid #d5d5d5;border-radius:4px;padding:0;padding-left:16px;padding-right:16px;margin-top:4px;}label .outer-container input.has-input-icon{padding-left:40px}label .outer-container input.has-input-icon.has-left-icon{padding-left:72px}label .outer-container input.has-left-icon{padding-left:40px}label .outer-container input.has-right-icon{padding-right:40px}label .outer-container input.invalid{border:1px solid #dc0000}label .outer-container input:not([type=submit]){font-family:\"Roboto\", serif;width:100%;height:36px;font-size:16px;line-height:19px}label .outer-container input[type=radio]{width:20px;height:20px}label .outer-container input[type=date]{background:white;display:block;min-width:calc(100% - 18px);line-height:37px}label .outer-container input[readonly]{cursor:default;pointer-events:none;user-select:none;color:gray}label .outer-container input:focus{border-color:#1479c6}label .outer-container input:focus-visible{outline:none}label .outer-container.inputBlock{display:flex;align-items:center;line-height:21px}label .outer-container.inputBlock .left-icons,label .outer-container.inputBlock .right-icons{margin-top:4px}label .outer-container.inputBlock.readonly{pointer-events:none;user-select:none;color:gray}label .outer-container.inputBlock.radioBlock{display:block}label .outer-container.inputInline{display:flex;white-space:nowrap;align-items:center;margin:0}label .outer-container.inputInline input{margin-top:0}label .secondarylabel{color:#757575;font-size:14px;line-height:16px;font-weight:normal;display:flex;margin-top:4px}label .errorBubble{position:relative;font-size:14px;line-height:16px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center;margin-top:4px}label .errorBubble:not(.visible){display:none}label .errorBubble span{color:#dc0000;font-size:16px;margin-right:4px}.material-symbols-rounded{font-family:\"Material Symbols Rounded\", sans-serif;font-weight:400;font-style:normal;font-size:24px;line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:#9e9e9e}button{cursor:pointer}.button{font-family:Roboto, serif;box-sizing:border-box;height:36px;min-width:36px;padding:0;margin:0;background:transparent;color:#212121;border:1px solid #c8c8c8;border-radius:4px;text-transform:uppercase;display:flex;justify-content:left;align-items:center;font-size:14px;font-weight:500}.button-content{display:block;padding:0 16px}.icon-left,.icon-right{margin-top:4px}.iconleft{padding-left:8px}.iconleft .button-content{padding-left:4px}.iconright{padding-right:8px}.iconright .button-content{padding-right:4px}.notext{padding:0 6px}.button:active{background:rgba(17, 17, 17, 0.2);border:1px solid #d5d5d5}.primary{background:#1479c6;border:1px solid #1479c6;color:white}.primary:active{background:#1464a2;border:1px solid #1464a2}.borderless{background:transparent;border:none;color:#212121}.borderless:active{background:rgba(17, 17, 17, 0.2);border:none}.borderless-circle{background:transparent;border:none;color:#212121;border-radius:50%}.borderless-circle:active{border:none}.borderless-circle:focus{border-color:transparent}.danger{background:#dc0000;border:1px solid #dc0000;color:white}.danger:active{background:#b00000;border:1px solid #b00000}.disabled{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}.disabled:active{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}@media (hover: hover){.button:hover{background:rgba(17, 17, 17, 0.1);border:1px solid #d5d5d5}.primary:hover{background:#146eb3;border:1px solid #146eb3}.borderless:hover{background:rgba(17, 17, 17, 0.1);border:none}.borderless-circle:hover{background:rgba(17, 17, 17, 0.1);border:none}.danger:hover{background:#c60000;border:1px solid #c60000}.disabled:hover{background:#aeaeae;border:none;color:#4c4c4c;cursor:not-allowed}}:host{display:block}fieldset{margin:0;padding:0;border:none}label{display:block;position:relative;margin-bottom:16px}.inlineLabel{font-weight:400;display:inline-block;vertical-align:top;padding-top:4px}input[type=checkbox]{width:18px;height:18px}input~label{font-weight:400}select{font-family:\"Roboto\", serif;box-sizing:border-box;width:100%;height:36px;padding:0 16px;font-size:16px;border:1px solid #d5d5d5;border-radius:4px;margin-top:4px}.placeholder{color:#9e9e9e}.placeholder option{color:initial}select.invalid:invalid{border:1px solid #dc0000}select~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;display:flex;align-content:center;align-items:center;justify-items:center}select~.errorBubble:not(.visible){visibility:hidden}select~.errorBubble span{color:#dc0000;font-size:16px;margin-right:4px;height:16px}select.invalid:invalid~.errorBubble{position:relative;font-size:14px;font-weight:normal;width:100%;font-family:\"Roboto\", sans-serif;color:#dc0000;visibility:visible}select:focus{border-color:#1479c6}select:focus-visible{outline:none}.button{padding:0 16px}.footer{display:flex;gap:16px;flex-direction:row-reverse}label.flex-label{display:flex;flex-direction:column;width:300px;box-sizing:border-box}label.flex-label input[type=date]{flex-grow:1;min-width:auto}label.flex-label input[type=time]{min-width:auto;text-align:center;width:180px;margin-left:16px}";
|
|
128
130
|
|
|
129
131
|
const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
130
132
|
constructor() {
|
|
@@ -296,6 +298,59 @@ const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
|
296
298
|
// Return the input element
|
|
297
299
|
return input;
|
|
298
300
|
}
|
|
301
|
+
createStartEndDateComponent(formKey, formProperties) {
|
|
302
|
+
const startDate = document.createElement('input');
|
|
303
|
+
const endDate = document.createElement('input');
|
|
304
|
+
startDate.type = endDate.type = 'date';
|
|
305
|
+
startDate.name = `${formKey}-startdate`;
|
|
306
|
+
endDate.name = `${formKey}-enddate`;
|
|
307
|
+
startDate.setAttribute('data-formkey', formKey);
|
|
308
|
+
endDate.setAttribute('data-formkey', formKey);
|
|
309
|
+
if (formProperties.readonly) {
|
|
310
|
+
startDate.readOnly = true;
|
|
311
|
+
endDate.readOnly = true;
|
|
312
|
+
}
|
|
313
|
+
this.applyValidation(startDate, { required: { message: 'Please enter a start date' }, dateCompare: { to: endDate.name } });
|
|
314
|
+
this.applyValidation(endDate, { required: { message: 'Please enter an end date' }, dateCompare: { with: startDate.name, message: 'End date cannot be before the start date' } });
|
|
315
|
+
let startTime;
|
|
316
|
+
let endTime;
|
|
317
|
+
if (formProperties.includeTime) {
|
|
318
|
+
startTime = document.createElement('input');
|
|
319
|
+
endTime = document.createElement('input');
|
|
320
|
+
startTime.type = endTime.type = 'time';
|
|
321
|
+
startTime.name = `${formKey}-starttime`;
|
|
322
|
+
endTime.name = `${formKey}-endtime`;
|
|
323
|
+
startTime.setAttribute('data-formkey', formKey);
|
|
324
|
+
endTime.setAttribute('data-formkey', formKey);
|
|
325
|
+
if (formProperties.readonly) {
|
|
326
|
+
startTime.readOnly = true;
|
|
327
|
+
endTime.readOnly = true;
|
|
328
|
+
}
|
|
329
|
+
this.applyValidation(startTime, { required: { message: 'Please enter a start time' } });
|
|
330
|
+
this.applyValidation(endTime, { required: { message: 'Please enter an end time' } });
|
|
331
|
+
}
|
|
332
|
+
const startLabel = document.createElement('label');
|
|
333
|
+
startLabel.innerText = 'Start date';
|
|
334
|
+
const endLabel = document.createElement('label');
|
|
335
|
+
endLabel.innerText = 'End date';
|
|
336
|
+
const startContainer = document.createElement('div');
|
|
337
|
+
const endContainer = document.createElement('div');
|
|
338
|
+
startContainer.className = endContainer.className = 'outer-container inputBlock';
|
|
339
|
+
startLabel.className = endLabel.className = 'flex-label';
|
|
340
|
+
startContainer.append(startDate);
|
|
341
|
+
if (startTime) {
|
|
342
|
+
startContainer.append(startTime);
|
|
343
|
+
}
|
|
344
|
+
startLabel.append(startContainer);
|
|
345
|
+
startLabel.append(this.createErrorBubble());
|
|
346
|
+
endContainer.append(endDate);
|
|
347
|
+
if (endTime) {
|
|
348
|
+
endContainer.append(endTime);
|
|
349
|
+
}
|
|
350
|
+
endLabel.append(endContainer);
|
|
351
|
+
endLabel.append(this.createErrorBubble());
|
|
352
|
+
return { start: startLabel, end: endLabel };
|
|
353
|
+
}
|
|
299
354
|
/**
|
|
300
355
|
* Applies validation attributes to an input element based on the specified validation object.
|
|
301
356
|
* If a certain property is present in the object, it will set the corresponding attribute on
|
|
@@ -316,6 +371,7 @@ const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
|
316
371
|
* @param {string} [validation.minmax.max]
|
|
317
372
|
* @param {string} [validation.minmax.message]
|
|
318
373
|
* @param {string} [validation.maxlength] - The maximum length of the input field.
|
|
374
|
+
* @param {string} [validation.datecompare] - To compare start and end date fields.
|
|
319
375
|
* @return {void}
|
|
320
376
|
*/
|
|
321
377
|
applyValidation(input, validation) {
|
|
@@ -348,6 +404,16 @@ const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
|
348
404
|
if (validation.maxlength) {
|
|
349
405
|
input.setAttribute('maxlength', validation.maxlength);
|
|
350
406
|
}
|
|
407
|
+
// Custom validation parameters for start date and end date comparison
|
|
408
|
+
if (validation.dateCompare) {
|
|
409
|
+
if (validation.dateCompare.message && validation.dateCompare.with) {
|
|
410
|
+
input.setAttribute('data-compare', validation.dateCompare.message);
|
|
411
|
+
input.setAttribute('data-compare-with', validation.dateCompare.with);
|
|
412
|
+
}
|
|
413
|
+
if (validation.dateCompare.to) {
|
|
414
|
+
input.setAttribute('data-compare-to', validation.dateCompare.to);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
351
417
|
}
|
|
352
418
|
// Create a new error bubble element
|
|
353
419
|
createErrorBubble() {
|
|
@@ -464,6 +530,7 @@ const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
|
464
530
|
* @return {void}
|
|
465
531
|
*/
|
|
466
532
|
populateFormFromSchema() {
|
|
533
|
+
var _a;
|
|
467
534
|
// If there is no form schema, return early
|
|
468
535
|
if (!this._formSchema)
|
|
469
536
|
return;
|
|
@@ -471,9 +538,17 @@ const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
|
471
538
|
const properties = this._formSchema.properties;
|
|
472
539
|
const propertyKeys = Object.keys(properties);
|
|
473
540
|
// Loop through each property key and create an input, label, and error bubble for it
|
|
474
|
-
|
|
541
|
+
for (const formKey of propertyKeys) {
|
|
475
542
|
const formItem = properties[formKey];
|
|
476
543
|
const formProperties = formItem.form;
|
|
544
|
+
// complex form types which require
|
|
545
|
+
// custom HTML should be done here
|
|
546
|
+
if (formProperties.type === 'startenddate') {
|
|
547
|
+
const { start, end } = this.createStartEndDateComponent(formKey, formProperties);
|
|
548
|
+
this.template.content.append(start);
|
|
549
|
+
this.template.content.append(end);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
477
552
|
let input;
|
|
478
553
|
switch (formProperties.type) {
|
|
479
554
|
case 'select':
|
|
@@ -486,15 +561,22 @@ const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
|
486
561
|
input = this.createInput(formKey, formProperties);
|
|
487
562
|
}
|
|
488
563
|
// If the form property has validation, apply it to the input
|
|
489
|
-
if (formProperties.validation &&
|
|
564
|
+
if (formProperties.validation &&
|
|
565
|
+
formProperties.type !== 'radio') {
|
|
490
566
|
this.applyValidation(input, formProperties.validation);
|
|
491
567
|
}
|
|
492
568
|
// Create an error bubble and label element for the input
|
|
493
569
|
const errorBubble = this.createErrorBubble();
|
|
494
570
|
const label = this.createLabel(formProperties, input, errorBubble);
|
|
571
|
+
// If explicitly setting input as invalid, set invalid state and error message on render
|
|
572
|
+
if ((_a = formProperties.validation) === null || _a === void 0 ? void 0 : _a.invalid) {
|
|
573
|
+
const errorMessage = formProperties.validation.invalid.message;
|
|
574
|
+
input.setCustomValidity(errorMessage); // Prevents the invalid styling from resetting on blur
|
|
575
|
+
setErrorState(input, true, errorMessage);
|
|
576
|
+
}
|
|
495
577
|
// Append the label element to the form template
|
|
496
578
|
this.template.content.append(label);
|
|
497
|
-
}
|
|
579
|
+
}
|
|
498
580
|
}
|
|
499
581
|
/**
|
|
500
582
|
* Clones the form template and binds event listeners to its input elements. First, it checks if
|
|
@@ -515,47 +597,121 @@ const TttxForm$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
|
515
597
|
// Bind event listeners to form elements
|
|
516
598
|
const properties = this._formSchema.properties;
|
|
517
599
|
const propertyKeys = Object.keys(properties);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
const
|
|
521
|
-
for (const formInput of formInputs) {
|
|
600
|
+
for (const formKey of propertyKeys) {
|
|
601
|
+
const formItemsByKey = formItems.querySelectorAll(`[name^=${formKey}]`);
|
|
602
|
+
for (const formInput of formItemsByKey) {
|
|
522
603
|
// Bind events to form input elements
|
|
523
604
|
formInput.oninvalid = this.validityCheckWrapper.bind(this);
|
|
524
605
|
formInput.onblur = this.validityCheckWrapper.bind(this);
|
|
525
606
|
formInput.onkeyup = this.fieldChanged.bind(this);
|
|
526
607
|
formInput.onchange = this.fieldChanged.bind(this);
|
|
527
|
-
if (
|
|
528
|
-
|
|
608
|
+
if (properties[formKey].form.type === 'select' && formInput.classList.contains('placeholder')) {
|
|
609
|
+
formInput.addEventListener('change', () => {
|
|
610
|
+
formInput.classList.remove('placeholder');
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-with')) {
|
|
614
|
+
formInput.oninvalid = this.endDateComparisonValidator.bind(this);
|
|
615
|
+
formInput.onblur = this.endDateComparisonValidator.bind(this);
|
|
616
|
+
}
|
|
617
|
+
if (properties[formKey].form.type === 'startenddate' && formInput.type === 'time') {
|
|
618
|
+
formInput.oninvalid = this.startEndTimeComparitor.bind(this);
|
|
619
|
+
formInput.onblur = this.startEndTimeComparitor.bind(this);
|
|
620
|
+
}
|
|
621
|
+
if (properties[formKey].form.type === 'startenddate' && formInput.hasAttribute('data-compare-to')) {
|
|
622
|
+
formInput.oninvalid = this.startDateComparisonValidator.bind(this);
|
|
623
|
+
formInput.onblur = this.startDateComparisonValidator.bind(this);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
// populate with existing form data if available
|
|
628
|
+
if (this._data && Object.keys(this._data).length > 0) {
|
|
629
|
+
const dataKeys = Object.keys(this._data);
|
|
630
|
+
for (const key of dataKeys) {
|
|
631
|
+
const formItemsByKey = formItems.querySelectorAll(`[name=${key}]`);
|
|
632
|
+
for (const formItem of formItemsByKey) {
|
|
633
|
+
switch (formItem.type) {
|
|
529
634
|
case 'checkbox':
|
|
530
|
-
if (this._data[
|
|
531
|
-
|
|
635
|
+
if (this._data[key] === 'on') {
|
|
636
|
+
formItem.checked = true;
|
|
532
637
|
}
|
|
533
638
|
break;
|
|
534
639
|
case 'radio':
|
|
535
|
-
if (
|
|
536
|
-
|
|
640
|
+
if (formItem.value === this._data[key]) {
|
|
641
|
+
formItem.checked = true;
|
|
537
642
|
}
|
|
538
643
|
break;
|
|
539
644
|
default:
|
|
540
|
-
|
|
645
|
+
formItem.value = this._data[key];
|
|
541
646
|
}
|
|
542
647
|
}
|
|
543
|
-
// If explicitly setting input as invalid, set invalid state and error message on render
|
|
544
|
-
if ((_b = properties[formKey].form.validation) === null || _b === void 0 ? void 0 : _b.invalid) {
|
|
545
|
-
const errorMessage = properties[formKey].form.validation.invalid.message;
|
|
546
|
-
formInput.setCustomValidity(errorMessage); // Prevents the invalid styling from resetting on blur
|
|
547
|
-
setErrorState(formInput, true, errorMessage);
|
|
548
|
-
}
|
|
549
|
-
if (properties[formKey].form.type === 'select' && formInput.classList.contains('placeholder')) {
|
|
550
|
-
formInput.addEventListener('change', () => {
|
|
551
|
-
formInput.classList.remove('placeholder');
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
648
|
}
|
|
555
|
-
}
|
|
649
|
+
}
|
|
556
650
|
// Append the cloned form elements to the fieldset
|
|
557
651
|
this.fieldset.replaceChildren(formItems);
|
|
558
652
|
}
|
|
653
|
+
startEndTimeComparitor(event) {
|
|
654
|
+
var _a, _b;
|
|
655
|
+
const target = event.target;
|
|
656
|
+
const formKey = target.getAttribute('data-formkey');
|
|
657
|
+
const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[data-formkey=${formKey}]`));
|
|
658
|
+
if (timeFields.length === 4) {
|
|
659
|
+
const startTime = timeFields.find(t => t.name.endsWith('starttime'));
|
|
660
|
+
const endTime = timeFields.find(t => t.name.endsWith('endtime'));
|
|
661
|
+
const startDate = timeFields.find(t => t.name.endsWith('startdate'));
|
|
662
|
+
const endDate = timeFields.find(t => t.name.endsWith('enddate'));
|
|
663
|
+
if (startTime.valueAsNumber >= endTime.valueAsNumber && ((_a = startDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) === ((_b = endDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
|
|
664
|
+
setErrorState(endTime, true, 'End time cannot be the same or before the start time');
|
|
665
|
+
if (target.name.endsWith('starttime')) {
|
|
666
|
+
this.validityCheckWrapper(event);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
// clear any end time comparitor errors and perform the standard validity check on the event
|
|
671
|
+
endTime.setCustomValidity('');
|
|
672
|
+
setErrorState(endTime, false, null);
|
|
673
|
+
this.validityCheckWrapper(event);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
clearTimeComparitor(event) {
|
|
678
|
+
const target = event.target;
|
|
679
|
+
const formKey = target.getAttribute('data-formkey');
|
|
680
|
+
const timeFields = Array.from(target.parentElement.parentElement.parentElement.querySelectorAll(`[type=time][data-formkey=${formKey}]`));
|
|
681
|
+
if (timeFields.length) {
|
|
682
|
+
const endTime = timeFields.find(t => t.name.endsWith('endtime'));
|
|
683
|
+
endTime.setCustomValidity('');
|
|
684
|
+
setErrorState(endTime, false, null);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
startDateComparisonValidator(event) {
|
|
688
|
+
const startDate = event.target;
|
|
689
|
+
const compareToName = startDate.getAttribute('data-compare-to');
|
|
690
|
+
const endDate = startDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareToName}]`);
|
|
691
|
+
this.endDateComparisonValidator({ target: endDate }, true);
|
|
692
|
+
this.validityCheckWrapper(event);
|
|
693
|
+
}
|
|
694
|
+
endDateComparisonValidator(event, triggeredByStartDate = false) {
|
|
695
|
+
var _a, _b, _c, _d;
|
|
696
|
+
const endDate = event.target;
|
|
697
|
+
if (!endDate.value && triggeredByStartDate)
|
|
698
|
+
return;
|
|
699
|
+
const compareWithName = endDate.getAttribute('data-compare-with');
|
|
700
|
+
const startDate = endDate.parentElement.parentElement.parentElement.querySelector(`[name=${compareWithName}]`);
|
|
701
|
+
if (((_a = endDate.valueAsDate) === null || _a === void 0 ? void 0 : _a.valueOf()) < ((_b = startDate.valueAsDate) === null || _b === void 0 ? void 0 : _b.valueOf())) {
|
|
702
|
+
endDate.setCustomValidity(endDate.getAttribute('data-compare'));
|
|
703
|
+
setErrorState(endDate, true, endDate.getAttribute('data-compare'));
|
|
704
|
+
}
|
|
705
|
+
else if (((_c = endDate.valueAsDate) === null || _c === void 0 ? void 0 : _c.valueOf()) === ((_d = startDate.valueAsDate) === null || _d === void 0 ? void 0 : _d.valueOf())) {
|
|
706
|
+
endDate.setCustomValidity('');
|
|
707
|
+
this.validityCheckWrapper(event);
|
|
708
|
+
this.startEndTimeComparitor(event);
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
this.clearTimeComparitor(event);
|
|
712
|
+
this.validityCheckWrapper(event);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
559
715
|
validityCheckWrapper(event) {
|
|
560
716
|
const { target, hasError, errorMessage } = validityCheck(event);
|
|
561
717
|
setErrorState(target, hasError, errorMessage);
|
|
@@ -28,7 +28,7 @@ const TttxCheckbox = class {
|
|
|
28
28
|
render() {
|
|
29
29
|
const checkBoxIcon = this.checked ? 'check_box' : 'check_box_outline_blank';
|
|
30
30
|
const renderedIcon = this.indeterminate ? 'indeterminate_check_box' : checkBoxIcon;
|
|
31
|
-
return (h(Host, null, h("label", { class: `tttx-checkbox ${this.inline ? '--inline' : ''}` }, h("input", { class: "tttx-checkbox__input", type: "checkbox", id: this.checkboxId, checked: this.checked, ref: (el) => this.checkbox = el }), h("tttx-icon", { color: this.checked ? 'blue' :
|
|
31
|
+
return (h(Host, null, h("label", { class: `tttx-checkbox ${this.inline ? '--inline' : ''}` }, h("input", { class: "tttx-checkbox__input", type: "checkbox", id: this.checkboxId, checked: this.checked, ref: (el) => this.checkbox = el }), h("tttx-icon", { color: this.checked ? 'blue' : 'grey', icon: renderedIcon, onClick: this.onClick.bind(this) }), h("span", { class: "tttx-checkbox__label" }, this.label))));
|
|
32
32
|
}
|
|
33
33
|
static get watchers() { return {
|
|
34
34
|
"indeterminate": ["watchIndeterminateChange"]
|