@progressive-development/pd-forms 0.0.4 → 0.0.6
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/index.js +21 -0
- package/package.json +3 -2
- package/src/shared-input-styles.js +227 -0
- package/src/squi-base-ui-input.js +68 -0
- package/src/squi-base-ui.js +14 -0
- package/src/squi-button-group.js +52 -0
- package/src/squi-button.js +187 -0
- package/src/squi-checkbox.js +290 -0
- package/src/squi-form-container.js +51 -0
- package/src/squi-form-row.js +103 -0
- package/src/squi-input-area.js +185 -0
- package/src/squi-input.js +206 -0
- package/src/squi-radio-group.js +111 -0
- package/src/squi-select.js +308 -0
- package/src/components/test-el.js +0 -32
- package/test-el.js +0 -34
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { html, css } from "lit";
|
|
2
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
3
|
+
|
|
4
|
+
// import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
|
|
5
|
+
|
|
6
|
+
import '@progressive-development/pd-icon';
|
|
7
|
+
import { SquiBaseUIInput, INPUT_TYPE_CHECK } from "./squi-base-ui-input.js";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// import { installMediaQueryWatcher } from 'pwa-helpers/media-query.js';
|
|
11
|
+
|
|
12
|
+
export class SquiCheckbox extends SquiBaseUIInput {
|
|
13
|
+
static get properties() {
|
|
14
|
+
return {
|
|
15
|
+
hasInner: { type: Boolean },
|
|
16
|
+
// _panX: {type: Number},
|
|
17
|
+
// _panEnd: {type: Boolean},
|
|
18
|
+
isSwitch: { type: Boolean }
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this._inputType = INPUT_TYPE_CHECK;
|
|
25
|
+
// this._panEnd = false;
|
|
26
|
+
// this._panX = 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static get styles() {
|
|
30
|
+
return [
|
|
31
|
+
// SharedInputStyles,
|
|
32
|
+
css`
|
|
33
|
+
:host {
|
|
34
|
+
|
|
35
|
+
--my-icon-fill: var(--app-primary-color, #177E89);
|
|
36
|
+
--my-icon-active-fill: var(--app-primary-color, #177E89);
|
|
37
|
+
--my-icon-bg-color: var(--app-primary-color, #fefefe) ;
|
|
38
|
+
--my-icon-bg-active-color: var(--app-primary-color, #fefefe);
|
|
39
|
+
|
|
40
|
+
--my-bg-color: var(--squi-bg-color, #177E89);
|
|
41
|
+
--my-txt-color: var(--squi-bg-color, black);
|
|
42
|
+
|
|
43
|
+
--my-font: var(--squi-font-2, Montserrat);
|
|
44
|
+
|
|
45
|
+
/* ref copy from shared styles...*/
|
|
46
|
+
--my-error-color: var(--squi-error-color, #d6242d);
|
|
47
|
+
--my-error-background-color: var(--squi-error-background-color, #f6d4d4a1);
|
|
48
|
+
--my-border-radius: var(--squi-border-radius, 0rem);
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
/* TODO vars used in squi-icon */
|
|
53
|
+
--squi-checkbox-checked-color: var(--my-primary);
|
|
54
|
+
--squi-checkbox-unchecked-color: var(--my-ligth);
|
|
55
|
+
--squi-checkbox-bg: var(--my-dark);
|
|
56
|
+
--squi-checkbox-unchecked-bg: var(--my-dark);
|
|
57
|
+
--squi-checkbox-label-color: var(--my-primary);
|
|
58
|
+
|
|
59
|
+
--squi-checkbox-label-disabled-color: var(--app-copy-color, #303030);
|
|
60
|
+
|
|
61
|
+
/* Checkbox squi-icon */
|
|
62
|
+
--squi-icon-fill: var(--my-icon-bg-color);
|
|
63
|
+
--squi-icon-bg: var(--my-icon-fill);
|
|
64
|
+
--squi-icon-fill-active: var(--my-icon-bg-active-color);
|
|
65
|
+
--squi-icon-bg-active: var(--my-icon-active-fill);
|
|
66
|
+
|
|
67
|
+
display: inline-block;
|
|
68
|
+
font-size: .8rem;
|
|
69
|
+
}
|
|
70
|
+
/* Switch squi-icon */
|
|
71
|
+
:host([isSwitch]) {
|
|
72
|
+
--squi-icon-fill: var(--my-icon-fill);
|
|
73
|
+
--squi-icon-bg: var(--my-icon-bg-color);
|
|
74
|
+
--squi-icon-fill-active: var(--my-icon-active-fill);
|
|
75
|
+
--squi-icon-bg-active: var(--my-icon-bg-active-color);
|
|
76
|
+
}
|
|
77
|
+
div {
|
|
78
|
+
display: flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
}
|
|
82
|
+
div.disabled {
|
|
83
|
+
opacity: 0.5;
|
|
84
|
+
cursor: auto;
|
|
85
|
+
}
|
|
86
|
+
div.readonly {
|
|
87
|
+
cursor: auto;
|
|
88
|
+
}
|
|
89
|
+
.checkbox {
|
|
90
|
+
display: flex;
|
|
91
|
+
border-radius: 4px;
|
|
92
|
+
line-height: 0;
|
|
93
|
+
align-items: center;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
}
|
|
96
|
+
.checkbox squi-icon {
|
|
97
|
+
margin: .25rem;
|
|
98
|
+
}
|
|
99
|
+
.label {
|
|
100
|
+
margin-left: .5rem;
|
|
101
|
+
color: var(--my-txt-color);
|
|
102
|
+
font-family: var(--my-font);
|
|
103
|
+
}
|
|
104
|
+
.disabled .label {
|
|
105
|
+
color: var(--squi-checkbox-label-disabled-color, #6e6c6c);
|
|
106
|
+
}
|
|
107
|
+
.readonly .label {
|
|
108
|
+
color: var(--app-copy-color, var(--squi-checkbox-label-color, #303030));
|
|
109
|
+
}
|
|
110
|
+
/* Switch styles */
|
|
111
|
+
.switch {
|
|
112
|
+
height: var(--my-input-height); /* noch ohne effekt?*/
|
|
113
|
+
position: relative;
|
|
114
|
+
outline: 0;
|
|
115
|
+
-webkit-user-select: none;
|
|
116
|
+
-moz-user-select: none;
|
|
117
|
+
-ms-user-select: none;
|
|
118
|
+
user-select: none;
|
|
119
|
+
}
|
|
120
|
+
.switch-paddle {
|
|
121
|
+
display: inline-block;
|
|
122
|
+
vertical-align: baseline;
|
|
123
|
+
margin: 0;
|
|
124
|
+
position: relative;
|
|
125
|
+
min-width: 4rem;
|
|
126
|
+
max-width: 4rem;
|
|
127
|
+
height: 2rem;
|
|
128
|
+
border-radius: 0;
|
|
129
|
+
background: var(--my-bg-color);
|
|
130
|
+
font-weight: inherit;
|
|
131
|
+
color: inherit;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
}
|
|
134
|
+
.disabled .switch-paddle {
|
|
135
|
+
cursor: auto;
|
|
136
|
+
}
|
|
137
|
+
.readonly .switch-paddle {
|
|
138
|
+
cursor: auto;
|
|
139
|
+
max-width: 2rem;
|
|
140
|
+
min-width: 2rem;
|
|
141
|
+
background: none;
|
|
142
|
+
|
|
143
|
+
--squi-icon-bg: transparent;
|
|
144
|
+
--squi-icon-fill: var(--card-dark-red);
|
|
145
|
+
--squi-icon-fill-hover: var(--squi-icon-fill);
|
|
146
|
+
--squi-icon-fill-active: var(--card-medium-green);
|
|
147
|
+
}
|
|
148
|
+
.readonly .isChecked.switch-paddle squi-icon {
|
|
149
|
+
transform: translate3d(0, 0, 0);
|
|
150
|
+
left: 0.25rem;
|
|
151
|
+
}
|
|
152
|
+
.switch-paddle squi-icon {
|
|
153
|
+
position: absolute;
|
|
154
|
+
top: 0.25rem;
|
|
155
|
+
left: 0.25rem;
|
|
156
|
+
display: block;
|
|
157
|
+
width: 1.5rem;
|
|
158
|
+
height: 1.5rem;
|
|
159
|
+
-webkit-transform: translate3d(0, 0, 0);
|
|
160
|
+
transform: translate3d(0, 0, 0);
|
|
161
|
+
border-radius: 3px;
|
|
162
|
+
-webkit-transition: all 0.25s ease-out;
|
|
163
|
+
transition: all 0.25s ease-out;
|
|
164
|
+
content: '';
|
|
165
|
+
}
|
|
166
|
+
.isChecked.switch-paddle squi-icon {
|
|
167
|
+
left: 2.25rem;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* Copy from SharedINputStyles, not used for select => ref, or exclude error styles and reuse oder something... */
|
|
171
|
+
.error-box {
|
|
172
|
+
display: block;
|
|
173
|
+
color: var(--my-error-color);
|
|
174
|
+
background: var(--my-error-background-color);
|
|
175
|
+
border: 1px solid var(--my-error-color);
|
|
176
|
+
border-radius: var(--my-border-radius);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Error Msg Div for input, select, area */
|
|
180
|
+
.error-msg {
|
|
181
|
+
padding:0.25rem;
|
|
182
|
+
white-space: nowrap;
|
|
183
|
+
font-size: .8rem;
|
|
184
|
+
max-width: var(--squi-input-width, 250px);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@media (min-width: 580px) {
|
|
188
|
+
:host {
|
|
189
|
+
font-size: 1rem;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
`];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
firstUpdated() {
|
|
196
|
+
this.hasInner = !!this.innerHTML.trim().length;
|
|
197
|
+
// installMediaQueryWatcher(`(min-width: 780px)`, (matches) => matches ? this : this._updateScale(1.5));
|
|
198
|
+
// const paddle = el.shadowRoot.querySelectorAll('.switch-paddle');
|
|
199
|
+
// this.isSwitch ? Gestures.addListener(this, 'track', this.handleTrack.bind(this)) : '';
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
render() {
|
|
203
|
+
const checked = (this.value === 'true');
|
|
204
|
+
|
|
205
|
+
// eslint-disable-next-line lit-a11y/click-events-have-key-events
|
|
206
|
+
return html`<div @click="${this.onClick}" class="${classMap({'disabled': this.disabled, 'switch': this.isSwitch, 'readonly': this.readonly})}">
|
|
207
|
+
<a href="#" @click="${this.linkClick}" @keypress="${this.onKeyPress}"
|
|
208
|
+
class="${classMap({'switch-paddle': this.isSwitch, 'checkbox': !this.isSwitch, 'isChecked': checked, 'isUnchecked': !checked})}">
|
|
209
|
+
<squi-icon icon="checkBox" class="${classMap({'switch': this.isSwitch, 'checkBox': !this.isSwitch})}" ?activeIcon="${checked}"></squi-icon>
|
|
210
|
+
</a>
|
|
211
|
+
${this.hasInner
|
|
212
|
+
? html`<span class="label">
|
|
213
|
+
<slot></slot>
|
|
214
|
+
</span>`
|
|
215
|
+
: ""}
|
|
216
|
+
</div>
|
|
217
|
+
${this.errorMsg.length > 0 ? html`
|
|
218
|
+
<div class="error-box error">
|
|
219
|
+
<span class="error-msg">${this.errorMsg}</span>
|
|
220
|
+
</div>
|
|
221
|
+
` : ''}
|
|
222
|
+
`;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/*
|
|
226
|
+
update(changedProperties) {
|
|
227
|
+
//let { deltaX = 0, isFinal = false } = this._panX;
|
|
228
|
+
let isFinal = this._panEnd;
|
|
229
|
+
let deltaX = this._panX || 0;
|
|
230
|
+
//console.log(this._panData);
|
|
231
|
+
|
|
232
|
+
// Guard against an infinite loop by looking for index.
|
|
233
|
+
if (isFinal) {
|
|
234
|
+
console.log('deltaX', deltaX);
|
|
235
|
+
// TODO 250 half screen size?
|
|
236
|
+
if ( deltaX > 100) {
|
|
237
|
+
this.onClick(true);
|
|
238
|
+
} else if(deltaX < -100){
|
|
239
|
+
this.onClick(false);
|
|
240
|
+
}
|
|
241
|
+
this._panEnd = false;
|
|
242
|
+
}
|
|
243
|
+
// We don't want the latent deltaX when releasing a pan.
|
|
244
|
+
deltaX = (isFinal ? 0 : deltaX);
|
|
245
|
+
|
|
246
|
+
super.update(changedProperties);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
handleTrack(e) {
|
|
250
|
+
switch(e.detail.state) {
|
|
251
|
+
case 'start':
|
|
252
|
+
//this.message = 'Tracking started!';
|
|
253
|
+
break;
|
|
254
|
+
case 'track':
|
|
255
|
+
//this.message = 'Tracking in progress... ' + e.detail.x + ', ' + e.detail.y;
|
|
256
|
+
break;
|
|
257
|
+
case 'end':
|
|
258
|
+
this._panX = e.detail.dx;
|
|
259
|
+
this._panEnd = true;
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
*/
|
|
264
|
+
onClick() {
|
|
265
|
+
if (this.disabled || this.readonly) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const checked = (this.value === 'true');
|
|
269
|
+
this.value = checked ? 'false' : 'true';
|
|
270
|
+
this.dispatchEvent(
|
|
271
|
+
new CustomEvent("checkbox-changed", {
|
|
272
|
+
bubbles: true,
|
|
273
|
+
composed: true,
|
|
274
|
+
detail: {check: !checked, name: this.valueName},
|
|
275
|
+
})
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
onKeyPress(e) {
|
|
280
|
+
e.preventDefault();
|
|
281
|
+
if (e.keyCode === 32 || e.code === "Space") {
|
|
282
|
+
this.onClick();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// eslint-disable-next-line class-methods-use-this
|
|
287
|
+
linkClick(e) {
|
|
288
|
+
e.preventDefault();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
|
|
4
|
+
* This code may only be used under the BSD style license found at
|
|
5
|
+
* http://polymer.github.io/LICENSE.txt
|
|
6
|
+
* The complete set of authors may be found at
|
|
7
|
+
* http://polymer.github.io/AUTHORS.txt
|
|
8
|
+
* The complete set of contributors may be found at
|
|
9
|
+
* http://polymer.github.io/CONTRIBUTORS.txt
|
|
10
|
+
* Code distributed by Google as part of the polymer project is also
|
|
11
|
+
* subject to an additional IP rights grant found at
|
|
12
|
+
* http://polymer.github.io/PATENTS.txt
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {LitElement, html, css} from 'lit';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* An example element.
|
|
19
|
+
*
|
|
20
|
+
* @slot - This element has a slot
|
|
21
|
+
* @csspart button - The button
|
|
22
|
+
*/
|
|
23
|
+
export class SquiFormContainer extends LitElement {
|
|
24
|
+
|
|
25
|
+
static get styles() {
|
|
26
|
+
return css`
|
|
27
|
+
:host {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
align-items: left;
|
|
31
|
+
gap: 20px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static get properties() {
|
|
38
|
+
return {
|
|
39
|
+
// not needed at the moment
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
render() {
|
|
44
|
+
return html`
|
|
45
|
+
<form>
|
|
46
|
+
<slot></slot>
|
|
47
|
+
</form>
|
|
48
|
+
`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 The Polymer Project Authors. All rights reserved.
|
|
4
|
+
* This code may only be used under the BSD style license found at
|
|
5
|
+
* http://polymer.github.io/LICENSE.txt
|
|
6
|
+
* The complete set of authors may be found at
|
|
7
|
+
* http://polymer.github.io/AUTHORS.txt
|
|
8
|
+
* The complete set of contributors may be found at
|
|
9
|
+
* http://polymer.github.io/CONTRIBUTORS.txt
|
|
10
|
+
* Code distributed by Google as part of the polymer project is also
|
|
11
|
+
* subject to an additional IP rights grant found at
|
|
12
|
+
* http://polymer.github.io/PATENTS.txt
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {LitElement, html, css} from 'lit';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* An example element.
|
|
19
|
+
*
|
|
20
|
+
* @slot - This element has a slot
|
|
21
|
+
* @csspart button - The button
|
|
22
|
+
*/
|
|
23
|
+
export class SquiFormRow extends LitElement {
|
|
24
|
+
|
|
25
|
+
static get styles() {
|
|
26
|
+
return css`
|
|
27
|
+
:host {
|
|
28
|
+
|
|
29
|
+
/* Define size for row, depends on media queries */
|
|
30
|
+
--my-row-width: 800px;
|
|
31
|
+
--my-gap: 20px;
|
|
32
|
+
display: flex;
|
|
33
|
+
flex: 1 1 100%;
|
|
34
|
+
/*margin: 0 0 .5rem 0;*/
|
|
35
|
+
box-sizing: border-box;
|
|
36
|
+
min-width: var(--my-row-width);
|
|
37
|
+
max-width: 100%;
|
|
38
|
+
gap: var(--my-gap);
|
|
39
|
+
align-items: flex-start;
|
|
40
|
+
|
|
41
|
+
padding-top: var(--row-padding-top, 0px);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
::slotted(.quarter1) {
|
|
45
|
+
--squi-input-width: calc(var(--my-row-width) * 0.25 - (var(--my-gap) * 0.75));
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
::slotted(.quarter2) {
|
|
50
|
+
--squi-input-width: calc((var(--my-row-width) * 0.5) - (var(--my-gap) / 2));
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
::slotted(.quarter3) {
|
|
55
|
+
--squi-input-width: calc(var(--my-row-width) * 0.75 - (var(--my-gap) * 0.25));
|
|
56
|
+
}
|
|
57
|
+
/* Area is longer? Scrollbar? */
|
|
58
|
+
::slotted(.quarter3-area) {
|
|
59
|
+
--squi-input-width: calc((var(--my-row-width) - 22px) * 0.75 - (var(--my-gap) * 0.25));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
::slotted(.quarter4) {
|
|
63
|
+
--squi-input-width: var(--my-row-width);
|
|
64
|
+
}
|
|
65
|
+
/* Area is longer? Scrollbar? */
|
|
66
|
+
::slotted(.quarter4-area) {
|
|
67
|
+
--squi-input-width: calc(var(--my-row-width) - 22px);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@media (max-width: 930px) {
|
|
71
|
+
:host {
|
|
72
|
+
--my-row-width: 600px;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
@media (max-width: 650px) {
|
|
76
|
+
:host {
|
|
77
|
+
--my-row-width: 400px;
|
|
78
|
+
--my-gap: 10px;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
@media (max-width: 450px) {
|
|
82
|
+
:host {
|
|
83
|
+
--my-row-width: 300px;
|
|
84
|
+
--my-gap: 8px;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static get properties() {
|
|
92
|
+
return {
|
|
93
|
+
// not needed at the moment
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
render() {
|
|
98
|
+
return html`
|
|
99
|
+
<slot></slot>
|
|
100
|
+
`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { html, css } from 'lit';
|
|
2
|
+
import { classMap } from 'lit/directives/class-map';
|
|
3
|
+
import { SharedInputStyles } from './shared-input-styles.js';
|
|
4
|
+
|
|
5
|
+
import { SquiBaseUIInput, INPUT_TYPE_AREA } from './squi-base-ui-input.js';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
import '@progressive-development/pd-icon/pd-icon.js';
|
|
9
|
+
|
|
10
|
+
// https://github.com/Victor-Bernabe/lit-input
|
|
11
|
+
// https://levelup.gitconnected.com/build-a-material-like-input-web-component-using-litelement-20e9e0d203b6
|
|
12
|
+
/**
|
|
13
|
+
* Web component to input text implemented with LitElement.
|
|
14
|
+
*
|
|
15
|
+
* ### Styling
|
|
16
|
+
*
|
|
17
|
+
* All custom properties should start with `--squi-input`.
|
|
18
|
+
*
|
|
19
|
+
* Font and icon size will scale automatically with `squi-input`'s height.
|
|
20
|
+
*
|
|
21
|
+
* Custom property | Description | Default
|
|
22
|
+
* ----------------|-------------|--------
|
|
23
|
+
* `--squi-input-width` | Width | `250px`
|
|
24
|
+
* `--my-input-height` | Height | `30px`
|
|
25
|
+
* `--squi-input-border` | Border | `1px solid black`
|
|
26
|
+
* `--squi-input-border-focus` | Border when focused | `1px solid #4d90fe`
|
|
27
|
+
* `--squi-input-background-color` | Background color | `white`
|
|
28
|
+
* `--squi-input-font-size` | Font size | `calc(var(--my-input-height) / 1.8)`
|
|
29
|
+
* `--squi-input-text-color` | Text color | `inherit`
|
|
30
|
+
* `--squi-input-placeholder-color` | Placeholder text color | `#a0a0a0`
|
|
31
|
+
* `--squi-input-icon-fill-color` | Icon fill color | `currentcolor`
|
|
32
|
+
* `--squi-input-icon-stroke-color` | Icon stroke color | `none`
|
|
33
|
+
*
|
|
34
|
+
* ### Icon and text alignment
|
|
35
|
+
*
|
|
36
|
+
* The icon inside `squi-input` is hidden by default. To show it, set the attribute `icon-right` or `icon-left`.
|
|
37
|
+
*
|
|
38
|
+
* <squi-input icon-left></squi-input>
|
|
39
|
+
* <squi-input icon-right></squi-input>
|
|
40
|
+
*
|
|
41
|
+
* <squi-input icon-left .icon="${'hardware:headset'}"></squi-input>
|
|
42
|
+
*
|
|
43
|
+
* Text can be left or right aligned. Default is left alignment.
|
|
44
|
+
*
|
|
45
|
+
* <squi-input text-right></squi-input>
|
|
46
|
+
* <squi-input text-left></squi-input>
|
|
47
|
+
*/
|
|
48
|
+
export class SquiInputArea extends SquiBaseUIInput {
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Fired when `squi-input-area` has focus and the user press `Enter` key.
|
|
52
|
+
* @event enter-pressed
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Fired when `squi-input-area` has focus and the user press any key except `Enter`.
|
|
57
|
+
* @event key-pressed
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Fire when the `squi-input-area` loses focus.
|
|
62
|
+
* @event focus-lost
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Fire when the icon inside `squi-input-area` is clicked.
|
|
67
|
+
* @event icon-clicked
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
static get styles() {
|
|
71
|
+
return [
|
|
72
|
+
SharedInputStyles,
|
|
73
|
+
css`
|
|
74
|
+
/* 10 py scroll border rigth? => overwrite*/
|
|
75
|
+
.input-style {
|
|
76
|
+
width: var(--squi-input-width, 240px);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
`];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static get properties() {
|
|
83
|
+
return {
|
|
84
|
+
/** Placeholder for `squi-input` initial text. */
|
|
85
|
+
placeHolder: { type: String },
|
|
86
|
+
/**
|
|
87
|
+
* Icon to be shown inside `squi-input`.
|
|
88
|
+
*/
|
|
89
|
+
icon: { type: String },
|
|
90
|
+
name: { type: String },
|
|
91
|
+
rows: { type: Number },
|
|
92
|
+
cols: { type: Number },
|
|
93
|
+
minlength: { type: String },
|
|
94
|
+
maxlength: { type: String } // max length for field
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
constructor() {
|
|
99
|
+
super();
|
|
100
|
+
this._inputType = INPUT_TYPE_AREA;
|
|
101
|
+
this.placeHolder = '';
|
|
102
|
+
this.icon = 'toggleCollapse';
|
|
103
|
+
|
|
104
|
+
this.maxlength = 500;
|
|
105
|
+
this.name = '';
|
|
106
|
+
this.rows = 2;
|
|
107
|
+
this.value = '';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
render() {
|
|
111
|
+
return html`
|
|
112
|
+
<label for="${this.id}InputArea">${this.label}</label>
|
|
113
|
+
<div class="input ${classMap({'error': this.errorMsg.length > 0})}">
|
|
114
|
+
<squi-icon icon="toggleCollapse"
|
|
115
|
+
@click="${this._onIconClick}"></squi-icon>
|
|
116
|
+
<textarea
|
|
117
|
+
id="${this.id}InputArea"
|
|
118
|
+
class="input-style ${this.gradient ? 'gradient' : ''}"
|
|
119
|
+
rows="${this.rows}"
|
|
120
|
+
cols="${this.cols}"
|
|
121
|
+
placeholder="${this.placeHolder}"
|
|
122
|
+
?disabled="${this.disabled}"
|
|
123
|
+
?readonly="${this.readonly}"
|
|
124
|
+
@keyup="${this._onKeyUp}"
|
|
125
|
+
@blur="${this._onBlur}">${this.value}</textarea>
|
|
126
|
+
<!-- Sollte erst Clientseitig im Input validiert werden. Meldung verschwindet erst beim Submit nicht mehr zeitgemäß-->
|
|
127
|
+
${this.errorMsg.length > 0 ? html`<span class="error-msg">${this.errorMsg}</span>` : ''}
|
|
128
|
+
</div>
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
firstUpdated() {
|
|
133
|
+
// Save input reference for performance (bind html element to class property)
|
|
134
|
+
this._input = this.shadowRoot.querySelector('textarea');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
_onKeyUp(event) {
|
|
138
|
+
|
|
139
|
+
// set value (tbd überdenken)
|
|
140
|
+
this.value = this._input.value;
|
|
141
|
+
|
|
142
|
+
// If Enter key pressed, fire 'enter-pressed'
|
|
143
|
+
if(event.keyCode === 13) {
|
|
144
|
+
this.dispatchEvent(new CustomEvent('enter-pressed', {
|
|
145
|
+
detail: {
|
|
146
|
+
value: this._input.value
|
|
147
|
+
},
|
|
148
|
+
composed: true,
|
|
149
|
+
bubbles: true
|
|
150
|
+
}));
|
|
151
|
+
event.preventDefault();
|
|
152
|
+
} else {
|
|
153
|
+
// If any other key, fire 'key-pressed'
|
|
154
|
+
// this.errorMsg = ''; change with handler now...
|
|
155
|
+
this.dispatchEvent(new CustomEvent('key-pressed', {
|
|
156
|
+
detail: {
|
|
157
|
+
value: this._input.value,
|
|
158
|
+
name: this.valueName
|
|
159
|
+
},
|
|
160
|
+
composed: true,
|
|
161
|
+
bubbles: true
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
_onBlur() {
|
|
167
|
+
this.dispatchEvent(new CustomEvent('focus-lost', {
|
|
168
|
+
detail: {
|
|
169
|
+
value: this._input.value
|
|
170
|
+
},
|
|
171
|
+
composed: true,
|
|
172
|
+
bubbles: true
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
_onIconClick() {
|
|
177
|
+
this.dispatchEvent(new CustomEvent('icon-clicked', {
|
|
178
|
+
detail: {
|
|
179
|
+
value: this._input.value
|
|
180
|
+
},
|
|
181
|
+
composed: true,
|
|
182
|
+
bubbles: true
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
}
|