vira 31.20.0 → 31.21.1
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/elements/vira-checkbox.element.d.ts +2 -2
- package/dist/elements/vira-checkbox.element.js +8 -8
- package/dist/elements/vira-form.element.d.ts +15 -0
- package/dist/elements/vira-form.element.js +244 -147
- package/dist/elements/vira-input.element.d.ts +1 -0
- package/dist/elements/vira-input.element.js +23 -1
- package/dist/elements/vira-json-form.element.js +1 -1
- package/dist/elements/vira-select.element.d.ts +5 -0
- package/dist/elements/vira-select.element.js +25 -0
- package/dist/elements/vira-text-area.element.d.ts +1 -0
- package/dist/elements/vira-text-area.element.js +21 -0
- package/dist/util/shared-text-input-logic.d.ts +1 -0
- package/dist/util/vira-form-fields.d.ts +6 -1
- package/package.json +1 -1
|
@@ -17,10 +17,10 @@ export type ViraCheckboxInputs = {
|
|
|
17
17
|
} & PartialWithUndefined<{
|
|
18
18
|
stylePassthrough: Partial<Record<ViraCheckboxInnerElements, CSSResult>>;
|
|
19
19
|
attributePassthrough: Partial<Record<ViraCheckboxInnerElements, AttributeValues>>;
|
|
20
|
-
|
|
20
|
+
isDisabled: boolean;
|
|
21
21
|
label: string;
|
|
22
22
|
hasError: boolean;
|
|
23
|
-
|
|
23
|
+
useHorizontalLabel: boolean;
|
|
24
24
|
/** The checkbox will be filled with a form selection color when it is checked. */
|
|
25
25
|
fillWhenChecked: boolean;
|
|
26
26
|
/** The checkbox will be filled with a form error color when it is unchecked. */
|
|
@@ -15,7 +15,7 @@ import { ViraIcon } from './vira-icon.element.js';
|
|
|
15
15
|
export const ViraCheckbox = defineViraElement()({
|
|
16
16
|
tagName: 'vira-checkbox',
|
|
17
17
|
hostClasses: {
|
|
18
|
-
'vira-checkbox-horizontal': ({ inputs }) => !!inputs.
|
|
18
|
+
'vira-checkbox-horizontal': ({ inputs }) => !!inputs.useHorizontalLabel,
|
|
19
19
|
'vira-checkbox-filled-checked': ({ inputs }) => !!inputs.fillWhenChecked,
|
|
20
20
|
'vira-checkbox-filled-unchecked': ({ inputs }) => !!inputs.fillWhenUnchecked,
|
|
21
21
|
},
|
|
@@ -126,8 +126,8 @@ export const ViraCheckbox = defineViraElement()({
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
${hostClasses['vira-checkbox-horizontal'].selector} label {
|
|
129
|
-
flex-direction: row
|
|
130
|
-
align-items:
|
|
129
|
+
flex-direction: row;
|
|
130
|
+
align-items: center;
|
|
131
131
|
gap: 8px;
|
|
132
132
|
|
|
133
133
|
& .label-text {
|
|
@@ -140,7 +140,7 @@ export const ViraCheckbox = defineViraElement()({
|
|
|
140
140
|
},
|
|
141
141
|
render({ inputs, dispatch, events }) {
|
|
142
142
|
function updateValue() {
|
|
143
|
-
if (!inputs.
|
|
143
|
+
if (!inputs.isDisabled) {
|
|
144
144
|
dispatch(new events.valueChange(!inputs.value));
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -158,7 +158,7 @@ export const ViraCheckbox = defineViraElement()({
|
|
|
158
158
|
return html `
|
|
159
159
|
<label
|
|
160
160
|
class=${classMap({
|
|
161
|
-
disabled: !!inputs.
|
|
161
|
+
disabled: !!inputs.isDisabled,
|
|
162
162
|
})}
|
|
163
163
|
${attributes(inputs.attributePassthrough?.label)}
|
|
164
164
|
style=${ifDefined(inputs.stylePassthrough?.label)}
|
|
@@ -168,14 +168,14 @@ export const ViraCheckbox = defineViraElement()({
|
|
|
168
168
|
<span
|
|
169
169
|
class="custom-checkbox ${classMap({
|
|
170
170
|
checked: inputs.value,
|
|
171
|
-
disabled: !!inputs.
|
|
171
|
+
disabled: !!inputs.isDisabled,
|
|
172
172
|
error: !!inputs.hasError,
|
|
173
173
|
})}"
|
|
174
174
|
role="checkbox"
|
|
175
175
|
aria-label=${ifDefined(inputs.label || undefined)}
|
|
176
176
|
aria-checked=${inputs.value ? 'true' : 'false'}
|
|
177
|
-
aria-disabled=${inputs.
|
|
178
|
-
tabindex=${inputs.
|
|
177
|
+
aria-disabled=${inputs.isDisabled ? 'true' : 'false'}
|
|
178
|
+
tabindex=${inputs.isDisabled ? '-1' : '0'}
|
|
179
179
|
${attributes(inputs.attributePassthrough?.['custom-checkbox'])}
|
|
180
180
|
style=${ifDefined(inputs.stylePassthrough?.['custom-checkbox'])}
|
|
181
181
|
${listenToActivate(updateValue)}
|
|
@@ -29,6 +29,21 @@ export declare const ViraForm: import("element-vir").DeclarativeElementDefinitio
|
|
|
29
29
|
* @default false
|
|
30
30
|
*/
|
|
31
31
|
horizontalCheckboxes: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* When `true`, all form field labels render to the left of their inputs instead of above
|
|
34
|
+
* them.
|
|
35
|
+
*
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
useHorizontalLabels: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* When `true`, all fields in this form are prevented from user edits. Inputs, selects, and
|
|
41
|
+
* text areas render their current value as plain text; checkboxes render disabled since
|
|
42
|
+
* they have no native readonly mode.
|
|
43
|
+
*
|
|
44
|
+
* @default false
|
|
45
|
+
*/
|
|
46
|
+
isReadonly: boolean;
|
|
32
47
|
}>, {
|
|
33
48
|
lastIsValid: boolean;
|
|
34
49
|
}, {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getObjectTypedEntries } from '@augment-vir/common';
|
|
2
|
-
import { css, defineElementEvent, html, listen, nothing, testId } from 'element-vir';
|
|
2
|
+
import { css, defineElementEvent, html, listen, nothing, testId, } from 'element-vir';
|
|
3
|
+
import { viraFormCssVars } from '../styles/form-styles.js';
|
|
3
4
|
import { defineViraElement } from '../util/define-vira-element.js';
|
|
4
5
|
import { applyRequiredLabel, areFormFieldsValid, ViraFormFieldType, } from '../util/vira-form-fields.js';
|
|
5
6
|
import { ViraCheckbox } from './vira-checkbox.element.js';
|
|
@@ -14,6 +15,11 @@ import { ViraTextArea } from './vira-text-area.element.js';
|
|
|
14
15
|
*/
|
|
15
16
|
export const ViraForm = defineViraElement()({
|
|
16
17
|
tagName: 'vira-form',
|
|
18
|
+
state() {
|
|
19
|
+
return {
|
|
20
|
+
lastIsValid: false,
|
|
21
|
+
};
|
|
22
|
+
},
|
|
17
23
|
events: {
|
|
18
24
|
valueChange: defineElementEvent(),
|
|
19
25
|
validChange: defineElementEvent(),
|
|
@@ -34,12 +40,35 @@ export const ViraForm = defineViraElement()({
|
|
|
34
40
|
width: unset;
|
|
35
41
|
}
|
|
36
42
|
}
|
|
43
|
+
|
|
44
|
+
.horizontal-fields {
|
|
45
|
+
width: 100%;
|
|
46
|
+
border-collapse: separate;
|
|
47
|
+
border-spacing: 0 10px;
|
|
48
|
+
|
|
49
|
+
& th,
|
|
50
|
+
& td {
|
|
51
|
+
padding: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
& th {
|
|
55
|
+
padding: 0 8px;
|
|
56
|
+
vertical-align: middle;
|
|
57
|
+
white-space: nowrap;
|
|
58
|
+
font-weight: ${viraFormCssVars['vira-form-label-font-weight'].value};
|
|
59
|
+
text-align: right;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
& td {
|
|
63
|
+
width: 100%;
|
|
64
|
+
vertical-align: top;
|
|
65
|
+
|
|
66
|
+
& > ${ViraCheckbox}, & > ${ViraInput}, & > ${ViraSelect}, & > ${ViraTextArea} {
|
|
67
|
+
width: 100%;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
37
71
|
`,
|
|
38
|
-
state() {
|
|
39
|
-
return {
|
|
40
|
-
lastIsValid: false,
|
|
41
|
-
};
|
|
42
|
-
},
|
|
43
72
|
render({ inputs, dispatch, events, state, updateState }) {
|
|
44
73
|
const currentIsValid = areFormFieldsValid(inputs.fields);
|
|
45
74
|
if (currentIsValid !== state.lastIsValid) {
|
|
@@ -50,168 +79,236 @@ export const ViraForm = defineViraElement()({
|
|
|
50
79
|
allFieldsAreValid: currentIsValid,
|
|
51
80
|
}));
|
|
52
81
|
}
|
|
82
|
+
function wrapFormField({ fieldTemplate, label, }) {
|
|
83
|
+
if (inputs.useHorizontalLabels) {
|
|
84
|
+
return html `
|
|
85
|
+
<tr>
|
|
86
|
+
<th scope="row">${label}</th>
|
|
87
|
+
<td>${fieldTemplate}</td>
|
|
88
|
+
</tr>
|
|
89
|
+
`;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return fieldTemplate;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
53
95
|
const formFieldTemplates = getObjectTypedEntries(inputs.fields).map(([key, field,]) => {
|
|
96
|
+
const label = applyRequiredLabel(field.label, !!field.isRequired && !inputs.hideRequiredMarkers);
|
|
97
|
+
const isDisabled = !!(inputs.isDisabled || field.isDisabled);
|
|
98
|
+
const childLabel = inputs.useHorizontalLabels ? undefined : label;
|
|
99
|
+
const horizontalLabelAttributes = inputs.useHorizontalLabels && label
|
|
100
|
+
? {
|
|
101
|
+
'aria-label': label,
|
|
102
|
+
}
|
|
103
|
+
: {};
|
|
54
104
|
if (field.isHidden) {
|
|
55
105
|
return nothing;
|
|
56
106
|
}
|
|
57
107
|
else if (field.type === ViraFormFieldType.Checkbox) {
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
108
|
+
return wrapFormField({
|
|
109
|
+
label,
|
|
110
|
+
fieldTemplate: html `
|
|
111
|
+
<${ViraCheckbox.assign({
|
|
112
|
+
value: field.value || false,
|
|
113
|
+
isDisabled: !!(isDisabled || inputs.isReadonly),
|
|
114
|
+
hasError: field.hasError,
|
|
115
|
+
useHorizontalLabel: inputs.horizontalCheckboxes,
|
|
116
|
+
fillWhenChecked: field.fillWhenChecked,
|
|
117
|
+
fillWhenUnchecked: field.fillWhenUnchecked,
|
|
118
|
+
label: childLabel,
|
|
119
|
+
...(inputs.useHorizontalLabels && label
|
|
120
|
+
? {
|
|
121
|
+
attributePassthrough: {
|
|
122
|
+
'custom-checkbox': horizontalLabelAttributes,
|
|
123
|
+
},
|
|
124
|
+
}
|
|
125
|
+
: {}),
|
|
126
|
+
})}
|
|
127
|
+
${field.testId ? testId(field.testId) : nothing}
|
|
128
|
+
${listen(ViraCheckbox.events.valueChange, (event) => {
|
|
129
|
+
dispatch(new events.valueChange({
|
|
130
|
+
key,
|
|
131
|
+
...field,
|
|
132
|
+
value: event.detail,
|
|
133
|
+
}));
|
|
134
|
+
})}
|
|
135
|
+
></${ViraCheckbox}>
|
|
136
|
+
`,
|
|
137
|
+
});
|
|
76
138
|
}
|
|
77
139
|
else if (field.type === ViraFormFieldType.Select) {
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
140
|
+
return wrapFormField({
|
|
141
|
+
label,
|
|
142
|
+
fieldTemplate: html `
|
|
143
|
+
<${ViraSelect.assign({
|
|
144
|
+
options: field.options,
|
|
145
|
+
value: field.value,
|
|
146
|
+
placeholder: field.placeholder,
|
|
147
|
+
disabled: isDisabled,
|
|
148
|
+
isReadonly: inputs.isReadonly,
|
|
149
|
+
label: childLabel,
|
|
150
|
+
hasError: field.hasError,
|
|
151
|
+
icon: field.icon,
|
|
152
|
+
...(inputs.useHorizontalLabels && label
|
|
153
|
+
? {
|
|
154
|
+
attributePassthrough: {
|
|
155
|
+
select: horizontalLabelAttributes,
|
|
156
|
+
},
|
|
157
|
+
}
|
|
158
|
+
: {}),
|
|
159
|
+
})}
|
|
160
|
+
${field.testId ? testId(field.testId) : nothing}
|
|
161
|
+
${listen(ViraSelect.events.valueChange, (event) => {
|
|
162
|
+
dispatch(new events.valueChange({
|
|
163
|
+
key,
|
|
164
|
+
...field,
|
|
165
|
+
value: event.detail,
|
|
166
|
+
}));
|
|
167
|
+
})}
|
|
168
|
+
></${ViraSelect}>
|
|
169
|
+
`,
|
|
170
|
+
});
|
|
98
171
|
}
|
|
99
172
|
else if (field.type === ViraFormFieldType.TextArea) {
|
|
100
|
-
return
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
173
|
+
return wrapFormField({
|
|
174
|
+
label,
|
|
175
|
+
fieldTemplate: html `
|
|
176
|
+
<${ViraTextArea.assign({
|
|
177
|
+
value: field.value || '',
|
|
178
|
+
disabled: isDisabled,
|
|
179
|
+
hasError: field.hasError,
|
|
180
|
+
isReadonly: inputs.isReadonly,
|
|
181
|
+
label: childLabel,
|
|
182
|
+
placeholder: field.placeholder,
|
|
183
|
+
rows: field.rows,
|
|
184
|
+
preventResize: field.preventResize,
|
|
185
|
+
attributePassthrough: horizontalLabelAttributes,
|
|
186
|
+
})}
|
|
187
|
+
${field.testId ? testId(field.testId) : nothing}
|
|
188
|
+
${listen(ViraTextArea.events.valueChange, (event) => {
|
|
189
|
+
dispatch(new events.valueChange({
|
|
190
|
+
key,
|
|
191
|
+
...field,
|
|
192
|
+
value: event.detail,
|
|
193
|
+
}));
|
|
194
|
+
})}
|
|
195
|
+
></${ViraTextArea}>
|
|
196
|
+
`,
|
|
197
|
+
});
|
|
120
198
|
}
|
|
121
199
|
else if (field.type === ViraFormFieldType.Number) {
|
|
122
|
-
return
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
200
|
+
return wrapFormField({
|
|
201
|
+
label,
|
|
202
|
+
fieldTemplate: html `
|
|
203
|
+
<${ViraInput.assign({
|
|
204
|
+
value: field.value?.toString() || '',
|
|
205
|
+
disabled: isDisabled,
|
|
206
|
+
allowedInputs: /\d/,
|
|
207
|
+
hasError: field.hasError,
|
|
208
|
+
icon: field.icon,
|
|
209
|
+
isReadonly: inputs.isReadonly,
|
|
210
|
+
label: childLabel,
|
|
211
|
+
placeholder: field.placeholder,
|
|
212
|
+
showClearButton: inputs.showClearButtons,
|
|
213
|
+
type: ViraInputType.Number,
|
|
214
|
+
attributePassthrough: {
|
|
215
|
+
...horizontalLabelAttributes,
|
|
216
|
+
...(field.min === undefined
|
|
217
|
+
? {}
|
|
218
|
+
: {
|
|
219
|
+
min: String(field.min),
|
|
220
|
+
}),
|
|
221
|
+
...(field.max === undefined
|
|
222
|
+
? {}
|
|
223
|
+
: {
|
|
224
|
+
max: String(field.max),
|
|
225
|
+
}),
|
|
226
|
+
...(field.step === undefined
|
|
227
|
+
? {}
|
|
228
|
+
: {
|
|
229
|
+
step: String(field.step),
|
|
230
|
+
}),
|
|
231
|
+
},
|
|
232
|
+
})}
|
|
233
|
+
${field.testId ? testId(field.testId) : nothing}
|
|
234
|
+
${listen(ViraInput.events.valueChange, (event) => {
|
|
235
|
+
const numericValue = event.detail === '' ? undefined : Number(event.detail);
|
|
236
|
+
dispatch(new events.valueChange({
|
|
237
|
+
key,
|
|
238
|
+
...field,
|
|
239
|
+
value: numericValue,
|
|
240
|
+
}));
|
|
241
|
+
})}
|
|
242
|
+
></${ViraInput}>
|
|
243
|
+
`,
|
|
244
|
+
});
|
|
162
245
|
}
|
|
163
246
|
else {
|
|
164
|
-
return
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
autocomplete: 'new-password',
|
|
180
|
-
}
|
|
181
|
-
: field.type === ViraFormFieldType.ExistingPassword
|
|
247
|
+
return wrapFormField({
|
|
248
|
+
label,
|
|
249
|
+
fieldTemplate: html `
|
|
250
|
+
<${ViraInput.assign({
|
|
251
|
+
value: field.value || '',
|
|
252
|
+
disabled: isDisabled,
|
|
253
|
+
hasError: field.hasError,
|
|
254
|
+
icon: field.icon,
|
|
255
|
+
isReadonly: inputs.isReadonly,
|
|
256
|
+
label: childLabel,
|
|
257
|
+
placeholder: field.placeholder,
|
|
258
|
+
showClearButton: inputs.showClearButtons,
|
|
259
|
+
attributePassthrough: {
|
|
260
|
+
...horizontalLabelAttributes,
|
|
261
|
+
...(field.isUsername
|
|
182
262
|
? {
|
|
183
|
-
autocomplete: '
|
|
263
|
+
autocomplete: 'username',
|
|
184
264
|
}
|
|
185
|
-
: field.type === ViraFormFieldType.
|
|
265
|
+
: field.type === ViraFormFieldType.NewPassword
|
|
186
266
|
? {
|
|
187
|
-
autocomplete: '
|
|
267
|
+
autocomplete: 'new-password',
|
|
188
268
|
}
|
|
189
|
-
:
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
269
|
+
: field.type === ViraFormFieldType.ExistingPassword
|
|
270
|
+
? {
|
|
271
|
+
autocomplete: 'password',
|
|
272
|
+
}
|
|
273
|
+
: field.type === ViraFormFieldType.Email
|
|
274
|
+
? {
|
|
275
|
+
autocomplete: 'email',
|
|
276
|
+
}
|
|
277
|
+
: {}),
|
|
278
|
+
},
|
|
279
|
+
type: [
|
|
280
|
+
ViraFormFieldType.NewPassword,
|
|
281
|
+
ViraFormFieldType.ExistingPassword,
|
|
282
|
+
ViraFormFieldType.PlainPassword,
|
|
283
|
+
].includes(field.type)
|
|
284
|
+
? ViraInputType.Password
|
|
285
|
+
: field.type === ViraFormFieldType.Email
|
|
286
|
+
? ViraInputType.Email
|
|
287
|
+
: ViraInputType.Default,
|
|
288
|
+
})}
|
|
289
|
+
${field.testId ? testId(field.testId) : nothing}
|
|
290
|
+
${listen(ViraInput.events.valueChange, (event) => {
|
|
291
|
+
dispatch(new events.valueChange({
|
|
292
|
+
key,
|
|
293
|
+
...field,
|
|
294
|
+
value: event.detail,
|
|
295
|
+
}));
|
|
296
|
+
})}
|
|
297
|
+
></${ViraInput}>
|
|
298
|
+
`,
|
|
299
|
+
});
|
|
210
300
|
}
|
|
211
301
|
});
|
|
302
|
+
const formFieldsWrapper = inputs.useHorizontalLabels
|
|
303
|
+
? html `
|
|
304
|
+
<table class="horizontal-fields">
|
|
305
|
+
<tbody>${formFieldTemplates}</tbody>
|
|
306
|
+
</table>
|
|
307
|
+
`
|
|
308
|
+
: formFieldTemplates;
|
|
212
309
|
return html `
|
|
213
310
|
<form ${listen('submit', (event) => event.preventDefault())}>
|
|
214
|
-
${
|
|
311
|
+
${formFieldsWrapper}
|
|
215
312
|
<slot></slot>
|
|
216
313
|
</form>
|
|
217
314
|
`;
|
|
@@ -35,6 +35,7 @@ export declare const ViraInput: import("element-vir").DeclarativeElementDefiniti
|
|
|
35
35
|
} & PartialWithUndefined<{
|
|
36
36
|
placeholder: string;
|
|
37
37
|
disabled: boolean;
|
|
38
|
+
isReadonly: boolean;
|
|
38
39
|
allowedInputs: string | RegExp;
|
|
39
40
|
blockedInputs: string | RegExp;
|
|
40
41
|
disableBrowserHelps: boolean;
|
|
@@ -6,6 +6,7 @@ import { CloseX24Icon } from '../icons/icon-svgs/24/close-x-24.icon.js';
|
|
|
6
6
|
import { EyeClosed24Icon, EyeOpen24Icon } from '../icons/index.js';
|
|
7
7
|
import { createFocusStyles } from '../styles/focus.js';
|
|
8
8
|
import { viraFormCssVars } from '../styles/form-styles.js';
|
|
9
|
+
import { ViraSize, viraSizeHeights } from '../styles/form-variants.js';
|
|
9
10
|
import { noUserSelect, viraAnimationDurations, viraDisabledStyles } from '../styles/index.js';
|
|
10
11
|
import { noNativeFormStyles } from '../styles/native-styles.js';
|
|
11
12
|
import { defineViraElement } from '../util/define-vira-element.js';
|
|
@@ -36,7 +37,7 @@ export const ViraInput = defineViraElement()({
|
|
|
36
37
|
tagName: 'vira-input',
|
|
37
38
|
cssVars: {
|
|
38
39
|
'vira-input-padding-horizontal': '10px',
|
|
39
|
-
'vira-input-padding-vertical': '
|
|
40
|
+
'vira-input-padding-vertical': '5px',
|
|
40
41
|
},
|
|
41
42
|
styles: ({ hostClasses, cssVars }) => {
|
|
42
43
|
return css `
|
|
@@ -137,6 +138,7 @@ export const ViraInput = defineViraElement()({
|
|
|
137
138
|
max-width: 100%;
|
|
138
139
|
flex-grow: 1;
|
|
139
140
|
display: inline-flex;
|
|
141
|
+
min-height: ${viraSizeHeights[ViraSize.Medium]}px;
|
|
140
142
|
box-sizing: border-box;
|
|
141
143
|
align-items: center;
|
|
142
144
|
position: relative;
|
|
@@ -156,6 +158,10 @@ export const ViraInput = defineViraElement()({
|
|
|
156
158
|
margin-right: calc(${cssVars['vira-input-padding-horizontal'].value} - 4px);
|
|
157
159
|
}
|
|
158
160
|
|
|
161
|
+
.readonly-value {
|
|
162
|
+
overflow-wrap: anywhere;
|
|
163
|
+
}
|
|
164
|
+
|
|
159
165
|
input {
|
|
160
166
|
${noNativeFormStyles};
|
|
161
167
|
cursor: text;
|
|
@@ -293,6 +299,22 @@ export const ViraInput = defineViraElement()({
|
|
|
293
299
|
allowed: inputs.allowedInputs,
|
|
294
300
|
blocked: inputs.blockedInputs,
|
|
295
301
|
});
|
|
302
|
+
if (inputs.isReadonly) {
|
|
303
|
+
const readonlyValueTemplate = html `
|
|
304
|
+
<span class="readonly-value">${filteredValue}</span>
|
|
305
|
+
`;
|
|
306
|
+
if (inputs.label) {
|
|
307
|
+
return html `
|
|
308
|
+
<label>
|
|
309
|
+
<span class="input-label">${inputs.label}</span>
|
|
310
|
+
${readonlyValueTemplate}
|
|
311
|
+
</label>
|
|
312
|
+
`;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
return readonlyValueTemplate;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
296
318
|
const iconTemplate = inputs.icon
|
|
297
319
|
? html `
|
|
298
320
|
<${ViraIcon.assign({
|
|
@@ -290,7 +290,7 @@ export const ViraJsonForm = defineViraElement()({
|
|
|
290
290
|
return html `
|
|
291
291
|
<${ViraCheckbox.assign({
|
|
292
292
|
value: value === true,
|
|
293
|
-
|
|
293
|
+
isDisabled,
|
|
294
294
|
})}
|
|
295
295
|
${listen(ViraCheckbox.events.valueChange, (event) => {
|
|
296
296
|
emitReplaceAt(path, event.detail);
|
|
@@ -20,6 +20,11 @@ export declare const ViraSelect: import("element-vir").DeclarativeElementDefinit
|
|
|
20
20
|
/** If set to `true`, only minimal styles are applied. */
|
|
21
21
|
rawSelect: boolean;
|
|
22
22
|
disabled: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* When `true`, the currently selected option's label is rendered as plain text with no
|
|
25
|
+
* wrapper, border, or focus styles.
|
|
26
|
+
*/
|
|
27
|
+
isReadonly: boolean;
|
|
23
28
|
attributePassthrough: Readonly<PartialWithUndefined<{
|
|
24
29
|
label: AttributeValues;
|
|
25
30
|
select: AttributeValues;
|
|
@@ -185,6 +185,10 @@ export const ViraSelect = defineViraElement()({
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
.readonly-value {
|
|
189
|
+
overflow-wrap: anywhere;
|
|
190
|
+
}
|
|
191
|
+
|
|
188
192
|
${hostClasses['vira-select-disabled'].selector} {
|
|
189
193
|
cursor: not-allowed;
|
|
190
194
|
|
|
@@ -252,6 +256,27 @@ export const ViraSelect = defineViraElement()({
|
|
|
252
256
|
},
|
|
253
257
|
render({ inputs, state, dispatch, events }) {
|
|
254
258
|
const value = inputs.value || undefined;
|
|
259
|
+
if (inputs.isReadonly) {
|
|
260
|
+
const selectedOption = inputs.options
|
|
261
|
+
.flatMap((entry) => (isViraSelectOptionGroup(entry) ? [...entry.options] : [entry]))
|
|
262
|
+
.find((option) => option.value === value);
|
|
263
|
+
const readonlyValueTemplate = html `
|
|
264
|
+
<span class="readonly-value">
|
|
265
|
+
${selectedOption?.label || inputs.placeholder || ''}
|
|
266
|
+
</span>
|
|
267
|
+
`;
|
|
268
|
+
if (inputs.label) {
|
|
269
|
+
return html `
|
|
270
|
+
<label ${attributes(inputs.attributePassthrough?.label)}>
|
|
271
|
+
<span class="select-label">${inputs.label}</span>
|
|
272
|
+
${readonlyValueTemplate}
|
|
273
|
+
</label>
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
return readonlyValueTemplate;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
255
280
|
const placeholderOptionTemplate = inputs.placeholder || value == undefined
|
|
256
281
|
? html `
|
|
257
282
|
<option value="" disabled ?selected=${value == undefined}>
|
|
@@ -21,6 +21,7 @@ export declare const ViraTextArea: import("element-vir").DeclarativeElementDefin
|
|
|
21
21
|
} & PartialWithUndefined<{
|
|
22
22
|
placeholder: string;
|
|
23
23
|
disabled: boolean;
|
|
24
|
+
isReadonly: boolean;
|
|
24
25
|
allowedInputs: string | RegExp;
|
|
25
26
|
blockedInputs: string | RegExp;
|
|
26
27
|
disableBrowserHelps: boolean;
|
|
@@ -97,6 +97,11 @@ export const ViraTextArea = defineViraElement()({
|
|
|
97
97
|
pointer-events: none;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
.readonly-value {
|
|
101
|
+
white-space: pre-wrap;
|
|
102
|
+
overflow-wrap: anywhere;
|
|
103
|
+
}
|
|
104
|
+
|
|
100
105
|
${hostClasses['vira-text-area-prevent-resize'].selector} textarea {
|
|
101
106
|
resize: none;
|
|
102
107
|
}
|
|
@@ -154,6 +159,22 @@ export const ViraTextArea = defineViraElement()({
|
|
|
154
159
|
allowed: inputs.allowedInputs,
|
|
155
160
|
blocked: inputs.blockedInputs,
|
|
156
161
|
});
|
|
162
|
+
if (inputs.isReadonly) {
|
|
163
|
+
const readonlyValueTemplate = html `
|
|
164
|
+
<span class="readonly-value">${filteredValue}</span>
|
|
165
|
+
`;
|
|
166
|
+
if (inputs.label) {
|
|
167
|
+
return html `
|
|
168
|
+
<label>
|
|
169
|
+
<span class="text-area-label">${inputs.label}</span>
|
|
170
|
+
${readonlyValueTemplate}
|
|
171
|
+
</label>
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
return readonlyValueTemplate;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
157
178
|
const textAreaTemplate = html `
|
|
158
179
|
<span class="text-area-wrapper">
|
|
159
180
|
<textarea
|
|
@@ -12,6 +12,7 @@ export type SharedTextInputElementInputs = {
|
|
|
12
12
|
placeholder: string;
|
|
13
13
|
/** Set to true to trigger disabled styles and to block all user input. */
|
|
14
14
|
disabled: boolean;
|
|
15
|
+
isReadonly: boolean;
|
|
15
16
|
/**
|
|
16
17
|
* Only letters in the given string or matches to the given RegExp will be allowed.
|
|
17
18
|
* blockedInputs takes precedence over this input.
|
|
@@ -77,7 +77,12 @@ export type ViraFormField = ({
|
|
|
77
77
|
}> & CommonViraFormFields) | ({
|
|
78
78
|
type: ViraFormFieldType.Checkbox;
|
|
79
79
|
value: boolean | undefined;
|
|
80
|
-
} &
|
|
80
|
+
} & PartialWithUndefined<{
|
|
81
|
+
/** The checkbox will be filled with a form selection color when it is checked. */
|
|
82
|
+
fillWhenChecked: boolean;
|
|
83
|
+
/** The checkbox will be filled with a form error color when it is unchecked. */
|
|
84
|
+
fillWhenUnchecked: boolean;
|
|
85
|
+
}> & CommonViraFormFields) | ({
|
|
81
86
|
type: ViraFormFieldType.Number;
|
|
82
87
|
value: number | undefined;
|
|
83
88
|
} & PartialWithUndefined<{
|