mbg-val-input 0.4.2 → 0.5.0
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/README.md +135 -6
- package/demo/index.html +6 -0
- package/dist/src/MbgValInput.d.ts +3 -2
- package/dist/src/MbgValInput.js +60 -21
- package/dist/src/MbgValInput.js.map +1 -1
- package/dist/src/currency-input.d.ts +2 -2
- package/dist/src/currency-input.js +4 -4
- package/dist/src/currency-input.js.map +1 -1
- package/dist/src/design-tokens.d.ts +1 -0
- package/dist/src/design-tokens.js +32 -0
- package/dist/src/design-tokens.js.map +1 -0
- package/dist/stories/index.stories.d.ts +9 -0
- package/dist/stories/index.stories.js +44 -1
- package/dist/stories/index.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/MbgValInput.ts +57 -20
- package/src/currency-input.ts +8 -4
- package/src/design-tokens.ts +32 -0
- package/stories/index.stories.ts +50 -0
package/src/MbgValInput.ts
CHANGED
|
@@ -4,8 +4,10 @@ import { property, query } from 'lit/decorators.js';
|
|
|
4
4
|
import type { MdSwitch } from '@material/web/switch/switch.js';
|
|
5
5
|
import { currencyInput } from './currency-input.js';
|
|
6
6
|
|
|
7
|
+
import { designTokens } from './design-tokens.js';
|
|
8
|
+
|
|
7
9
|
import '@material/web/textfield/outlined-text-field.js';
|
|
8
|
-
import '@material/web/select/
|
|
10
|
+
import '@material/web/select/outlined-select.js';
|
|
9
11
|
import '@material/web/select/select-option.js';
|
|
10
12
|
import '@material/web/switch/switch.js';
|
|
11
13
|
|
|
@@ -38,6 +40,8 @@ function sanitizeAndValidateInt(
|
|
|
38
40
|
isUserInput: boolean,
|
|
39
41
|
isSigned = true,
|
|
40
42
|
) {
|
|
43
|
+
if (!value) return '';
|
|
44
|
+
|
|
41
45
|
// allow leading negative sign
|
|
42
46
|
const signed = value[0] === '-' ? '-' : '';
|
|
43
47
|
const negative = signed === '-';
|
|
@@ -104,6 +108,8 @@ function sanitizeAndValidateFloat(
|
|
|
104
108
|
isUserInput: boolean,
|
|
105
109
|
size: 32 | 64,
|
|
106
110
|
) {
|
|
111
|
+
if (!value) return '';
|
|
112
|
+
|
|
107
113
|
let sanitized = '';
|
|
108
114
|
|
|
109
115
|
// allow leading negative sign
|
|
@@ -177,18 +183,20 @@ function sanitizeAndValidateFloat(
|
|
|
177
183
|
}
|
|
178
184
|
|
|
179
185
|
function sanitizeOctet(value: string) {
|
|
180
|
-
return value
|
|
186
|
+
return value?.replace(/[^0-9a-fA-F]/g, '');
|
|
181
187
|
}
|
|
182
188
|
|
|
183
189
|
function sanitizeObjRef(value: string) {
|
|
184
|
-
return value
|
|
190
|
+
return value?.replace(/[^A-Za-z0-9_/$]/g, '');
|
|
185
191
|
}
|
|
186
192
|
|
|
187
193
|
function sanitizeBitString(value: string) {
|
|
188
|
-
return value
|
|
194
|
+
return value?.replace(/[^01]/g, '');
|
|
189
195
|
}
|
|
190
196
|
|
|
191
197
|
function formatTimestamp(input: string) {
|
|
198
|
+
if (!input) return '';
|
|
199
|
+
|
|
192
200
|
const digits = input.replace(/\D/g, '');
|
|
193
201
|
|
|
194
202
|
// Extract parts
|
|
@@ -213,16 +221,27 @@ function formatTimestamp(input: string) {
|
|
|
213
221
|
|
|
214
222
|
/** Web Component for inputting IEC61850-6 "Val" values */
|
|
215
223
|
export class MbgValInput extends LitElement {
|
|
216
|
-
static styles =
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
224
|
+
static styles = [
|
|
225
|
+
designTokens,
|
|
226
|
+
css`
|
|
227
|
+
md-outlined-text-field.Timestamp {
|
|
228
|
+
min-width: 250px;
|
|
229
|
+
max-width: 100%;
|
|
230
|
+
width: auto;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.boolean-input {
|
|
234
|
+
display: flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
gap: 0.5rem;
|
|
237
|
+
}
|
|
238
|
+
`,
|
|
239
|
+
];
|
|
223
240
|
|
|
224
241
|
@property({ type: String }) bType?: string;
|
|
225
242
|
|
|
243
|
+
@property({ type: Boolean }) readOnly = false;
|
|
244
|
+
|
|
226
245
|
// If the DA/BDA is assigned a Val in DataTypeTemplates
|
|
227
246
|
@property({ type: String }) default = '';
|
|
228
247
|
|
|
@@ -304,6 +323,7 @@ export class MbgValInput extends LitElement {
|
|
|
304
323
|
type="text"
|
|
305
324
|
value="${validatedDefault ?? nothing}"
|
|
306
325
|
@input="${this.handleBigIntInput}"
|
|
326
|
+
?disabled="${this.readOnly}"
|
|
307
327
|
></md-outlined-text-field>`;
|
|
308
328
|
}
|
|
309
329
|
|
|
@@ -316,6 +336,7 @@ export class MbgValInput extends LitElement {
|
|
|
316
336
|
max="${max}"
|
|
317
337
|
value="${validatedDefault ?? nothing}"
|
|
318
338
|
@input="${this.handleIntInput}"
|
|
339
|
+
?disabled="${this.readOnly}"
|
|
319
340
|
></md-outlined-text-field>`;
|
|
320
341
|
}
|
|
321
342
|
|
|
@@ -353,6 +374,7 @@ export class MbgValInput extends LitElement {
|
|
|
353
374
|
type="text"
|
|
354
375
|
value="${validatedDefault ?? nothing}"
|
|
355
376
|
@input="${this.handleFloatInput}"
|
|
377
|
+
?disabled="${this.readOnly}"
|
|
356
378
|
></md-outlined-text-field>
|
|
357
379
|
`;
|
|
358
380
|
}
|
|
@@ -374,6 +396,7 @@ export class MbgValInput extends LitElement {
|
|
|
374
396
|
value="${sanitizeOctet(this.default) ?? nothing}"
|
|
375
397
|
maxlength="${size * 2}"
|
|
376
398
|
@input="${this.handleOctetInput}"
|
|
399
|
+
?disabled="${this.readOnly}"
|
|
377
400
|
></md-outlined-text-field>
|
|
378
401
|
`;
|
|
379
402
|
}
|
|
@@ -394,6 +417,7 @@ export class MbgValInput extends LitElement {
|
|
|
394
417
|
value="${this.default ?? nothing}"
|
|
395
418
|
maxlength="${size}"
|
|
396
419
|
@input="${this.handleStringInput}"
|
|
420
|
+
?disabled="${this.readOnly}"
|
|
397
421
|
></md-outlined-text-field>
|
|
398
422
|
`;
|
|
399
423
|
}
|
|
@@ -410,7 +434,11 @@ export class MbgValInput extends LitElement {
|
|
|
410
434
|
}
|
|
411
435
|
|
|
412
436
|
return html`
|
|
413
|
-
<md-
|
|
437
|
+
<md-outlined-select
|
|
438
|
+
id="input"
|
|
439
|
+
label="${this.label}"
|
|
440
|
+
?disabled="${this.readOnly}"
|
|
441
|
+
>
|
|
414
442
|
${ordinals.map(
|
|
415
443
|
(ordinal, index) => html`
|
|
416
444
|
<md-select-option
|
|
@@ -422,7 +450,7 @@ export class MbgValInput extends LitElement {
|
|
|
422
450
|
</md-select-option>
|
|
423
451
|
`,
|
|
424
452
|
)}
|
|
425
|
-
</md-
|
|
453
|
+
</md-outlined-select>
|
|
426
454
|
`;
|
|
427
455
|
}
|
|
428
456
|
|
|
@@ -449,6 +477,7 @@ export class MbgValInput extends LitElement {
|
|
|
449
477
|
label="${this.label}"
|
|
450
478
|
value="${validatedDefault ?? nothing}"
|
|
451
479
|
@input="${this.handleTimestampInput}"
|
|
480
|
+
?disabled="${this.readOnly}"
|
|
452
481
|
></md-outlined-text-field>
|
|
453
482
|
`;
|
|
454
483
|
}
|
|
@@ -470,13 +499,14 @@ export class MbgValInput extends LitElement {
|
|
|
470
499
|
value="${sanitizeObjRef(this.default) ?? nothing}"
|
|
471
500
|
maxlength="255"
|
|
472
501
|
@input="${this.handleObjRefInput}"
|
|
502
|
+
?disabled="${this.readOnly}"
|
|
473
503
|
></md-outlined-text-field>
|
|
474
504
|
`;
|
|
475
505
|
}
|
|
476
506
|
|
|
477
507
|
dbposInput() {
|
|
478
508
|
return html`
|
|
479
|
-
<md-
|
|
509
|
+
<md-outlined-select id="input" label="${this.label}" ?disabled="${this.readOnly}">
|
|
480
510
|
<md-select-option value="0" ?selected=${this.default === '0'}>
|
|
481
511
|
<div slot="headline">0 - intermediate-state</div>
|
|
482
512
|
</md-select-option>
|
|
@@ -491,13 +521,13 @@ export class MbgValInput extends LitElement {
|
|
|
491
521
|
<md-select-option value="3" ?selected=${this.default === '3'}>
|
|
492
522
|
<div slot="headline">3 - bad-state</div>
|
|
493
523
|
</md-select-option>
|
|
494
|
-
</md-
|
|
524
|
+
</md-outlined-select>
|
|
495
525
|
`;
|
|
496
526
|
}
|
|
497
527
|
|
|
498
528
|
tcmdInput() {
|
|
499
529
|
return html`
|
|
500
|
-
<md-
|
|
530
|
+
<md-outlined-select id="input" label="${this.label}" ?disabled="${this.readOnly}">
|
|
501
531
|
<md-select-option value="0" ?selected=${this.default === '0'}>
|
|
502
532
|
<div slot="headline">0 - neutral</div>
|
|
503
533
|
</md-select-option>
|
|
@@ -512,7 +542,7 @@ export class MbgValInput extends LitElement {
|
|
|
512
542
|
<md-select-option value="3" ?selected=${this.default === '3'}>
|
|
513
543
|
<div slot="headline">3 - reserved</div>
|
|
514
544
|
</md-select-option>
|
|
515
|
-
</md-
|
|
545
|
+
</md-outlined-select>
|
|
516
546
|
`;
|
|
517
547
|
}
|
|
518
548
|
|
|
@@ -533,6 +563,7 @@ export class MbgValInput extends LitElement {
|
|
|
533
563
|
value="${sanitizeBitString(this.default) ?? nothing}"
|
|
534
564
|
maxlength="${size}"
|
|
535
565
|
@input="${this.handleBitStringInput}"
|
|
566
|
+
?disabled="${this.readOnly}"
|
|
536
567
|
></md-outlined-text-field>
|
|
537
568
|
`;
|
|
538
569
|
}
|
|
@@ -550,9 +581,14 @@ export class MbgValInput extends LitElement {
|
|
|
550
581
|
|
|
551
582
|
get inputs(): Partial<Record<string, TemplateResult>> {
|
|
552
583
|
return {
|
|
553
|
-
BOOLEAN: html`<label
|
|
584
|
+
BOOLEAN: html`<label class="boolean-input"
|
|
554
585
|
>${this.label}
|
|
555
|
-
<md-switch
|
|
586
|
+
<md-switch
|
|
587
|
+
id="input"
|
|
588
|
+
?disabled="${this.readOnly}"
|
|
589
|
+
?selected=${xmlBoolean(this.default)}
|
|
590
|
+
icons
|
|
591
|
+
></md-switch
|
|
556
592
|
></label>`,
|
|
557
593
|
INT8: this.intInput(8),
|
|
558
594
|
INT16: this.intInput(16),
|
|
@@ -576,7 +612,7 @@ export class MbgValInput extends LitElement {
|
|
|
576
612
|
VisString255: this.stringInput(255),
|
|
577
613
|
Unicode255: this.stringInput(255),
|
|
578
614
|
Quality: this.bitstringInput(14),
|
|
579
|
-
Currency: currencyInput(this.label, this.default),
|
|
615
|
+
Currency: currencyInput(this.label, this.default, this.readOnly),
|
|
580
616
|
Enum: this.enumInput(),
|
|
581
617
|
Timestamp: this.timestampInput(),
|
|
582
618
|
ObjRef: this.objrefInput(),
|
|
@@ -599,6 +635,7 @@ export class MbgValInput extends LitElement {
|
|
|
599
635
|
id="input"
|
|
600
636
|
label="${this.label}"
|
|
601
637
|
value="${this.default ?? nothing}"
|
|
638
|
+
?disabled="${this.readOnly}"
|
|
602
639
|
></md-outlined-text-field>`
|
|
603
640
|
);
|
|
604
641
|
}
|
package/src/currency-input.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { html } from 'lit';
|
|
2
2
|
|
|
3
|
-
import '@material/web/select/
|
|
3
|
+
import '@material/web/select/outlined-select.js';
|
|
4
4
|
import '@material/web/select/select-option.js';
|
|
5
5
|
|
|
6
|
-
export function currencyInput(
|
|
6
|
+
export function currencyInput(
|
|
7
|
+
label: string,
|
|
8
|
+
defaultVal: string,
|
|
9
|
+
readOnly: boolean,
|
|
10
|
+
) {
|
|
7
11
|
return html`
|
|
8
|
-
<md-
|
|
12
|
+
<md-outlined-select id="input" label="${label}" ?disabled="${readOnly}">
|
|
9
13
|
<md-select-option value="AED" ?selected=${defaultVal === 'AED'}>
|
|
10
14
|
<div slot="headline">AED (UAE Dirham)</div>
|
|
11
15
|
</md-select-option>
|
|
@@ -492,6 +496,6 @@ export function currencyInput(label: string, defaultVal: string) {
|
|
|
492
496
|
<md-select-option value="ZWG" ?selected=${defaultVal === 'ZWG'}>
|
|
493
497
|
<div slot="headline">ZWG (Zimbabwe Gold)</div>
|
|
494
498
|
</md-select-option>
|
|
495
|
-
</md-
|
|
499
|
+
</md-outlined-select>
|
|
496
500
|
`;
|
|
497
501
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
|
|
3
|
+
export const designTokens = css`
|
|
4
|
+
:host {
|
|
5
|
+
/* public design tokens */
|
|
6
|
+
--mbg-val-input-shape: 4px;
|
|
7
|
+
--mbg-val-input-space: 16px;
|
|
8
|
+
--mbg-val-input-height: 56px;
|
|
9
|
+
--mbg-val-input-width: auto;
|
|
10
|
+
--mbg-val-input-min-width: 100px;
|
|
11
|
+
--mbg-val-input-max-width: 100%;
|
|
12
|
+
|
|
13
|
+
/* assign values specific to the text field */
|
|
14
|
+
--md-outlined-text-field-container-shape: var(--mbg-val-input-shape, 4px);
|
|
15
|
+
--md-outlined-text-field-top-space: var(--mbg-val-input-space, 16px);
|
|
16
|
+
--md-outlined-text-field-bottom-space: var(--mbg-val-input-space, 16px);
|
|
17
|
+
|
|
18
|
+
/* assign values specific to the select field */
|
|
19
|
+
--md-outlined-select-text-field-container-shape: var(
|
|
20
|
+
--mbg-val-input-shape,
|
|
21
|
+
4px
|
|
22
|
+
);
|
|
23
|
+
--md-outlined-field-top-space: var(--mbg-val-input-space, 16px);
|
|
24
|
+
--md-outlined-field-bottom-space: var(--mbg-val-input-space, 16px);
|
|
25
|
+
|
|
26
|
+
/* assign universal values */
|
|
27
|
+
height: var(--mbg-val-input-height, 56px);
|
|
28
|
+
width: var(--mbg-val-input-width, auto);
|
|
29
|
+
min-width: var(--mbg-val-input-min-width, 100px);
|
|
30
|
+
max-width: var(--mbg-val-input-max-width, 100%);
|
|
31
|
+
}
|
|
32
|
+
`;
|
package/stories/index.stories.ts
CHANGED
|
@@ -6,6 +6,7 @@ export default {
|
|
|
6
6
|
component: 'mbg-val-input',
|
|
7
7
|
argTypes: {
|
|
8
8
|
bType: { control: 'text' },
|
|
9
|
+
readOnly: { control: 'boolean' },
|
|
9
10
|
defaultVal: { control: 'text' },
|
|
10
11
|
enumOrdinals: { control: 'array' },
|
|
11
12
|
enumLabels: { control: 'array' },
|
|
@@ -22,6 +23,7 @@ interface Story<T> {
|
|
|
22
23
|
|
|
23
24
|
interface ArgTypes {
|
|
24
25
|
bType?: string;
|
|
26
|
+
readOnly?: boolean;
|
|
25
27
|
defaultVal?: string;
|
|
26
28
|
enumOrdinals?: string[];
|
|
27
29
|
enumLabels?: string[];
|
|
@@ -31,6 +33,7 @@ interface ArgTypes {
|
|
|
31
33
|
|
|
32
34
|
const Template: Story<ArgTypes> = ({
|
|
33
35
|
bType,
|
|
36
|
+
readOnly,
|
|
34
37
|
defaultVal,
|
|
35
38
|
enumOrdinals,
|
|
36
39
|
enumLabels,
|
|
@@ -39,6 +42,7 @@ const Template: Story<ArgTypes> = ({
|
|
|
39
42
|
}: ArgTypes) => html`
|
|
40
43
|
<mbg-val-input
|
|
41
44
|
.bType=${bType}
|
|
45
|
+
.readOnly=${readOnly}
|
|
42
46
|
.default=${defaultVal}
|
|
43
47
|
.enumOrdinals=${JSON.stringify(enumOrdinals)}
|
|
44
48
|
.enumLabels=${JSON.stringify(enumLabels)}
|
|
@@ -66,6 +70,14 @@ BooleanWithDefault.args = {
|
|
|
66
70
|
label: 'Boolean (Default: true)',
|
|
67
71
|
};
|
|
68
72
|
|
|
73
|
+
export const BooleanReadOnly = Template.bind({});
|
|
74
|
+
BooleanReadOnly.args = {
|
|
75
|
+
bType: 'BOOLEAN',
|
|
76
|
+
defaultVal: 'true',
|
|
77
|
+
readOnly: true,
|
|
78
|
+
label: 'Boolean (Default: true)',
|
|
79
|
+
};
|
|
80
|
+
|
|
69
81
|
export const Int32U = Template.bind({});
|
|
70
82
|
Int32U.args = {
|
|
71
83
|
bType: 'INT32U',
|
|
@@ -82,6 +94,7 @@ export const Int64WithDefault = Template.bind({});
|
|
|
82
94
|
Int64WithDefault.args = {
|
|
83
95
|
bType: 'INT64',
|
|
84
96
|
defaultVal: '-42',
|
|
97
|
+
readOnly: true,
|
|
85
98
|
label: 'INT64 (Default: -42)',
|
|
86
99
|
};
|
|
87
100
|
|
|
@@ -116,6 +129,7 @@ Octet16.args = {
|
|
|
116
129
|
bType: 'Octet16',
|
|
117
130
|
defaultVal: '0123456789ABCDEF0123456789ABCDEF',
|
|
118
131
|
label: 'Octet16',
|
|
132
|
+
readOnly: true,
|
|
119
133
|
};
|
|
120
134
|
|
|
121
135
|
export const VisString32 = Template.bind({});
|
|
@@ -145,6 +159,14 @@ Currency.args = {
|
|
|
145
159
|
label: 'Currency',
|
|
146
160
|
};
|
|
147
161
|
|
|
162
|
+
export const CurrencyReadOnly = Template.bind({});
|
|
163
|
+
CurrencyReadOnly.args = {
|
|
164
|
+
bType: 'Currency',
|
|
165
|
+
defaultVal: 'JPY',
|
|
166
|
+
readOnly: true,
|
|
167
|
+
label: 'Currency',
|
|
168
|
+
};
|
|
169
|
+
|
|
148
170
|
export const EnumHlth = Template.bind({});
|
|
149
171
|
EnumHlth.args = {
|
|
150
172
|
bType: 'Enum',
|
|
@@ -154,6 +176,16 @@ EnumHlth.args = {
|
|
|
154
176
|
defaultVal: '1',
|
|
155
177
|
};
|
|
156
178
|
|
|
179
|
+
export const EnumHlthReadOnly = Template.bind({});
|
|
180
|
+
EnumHlthReadOnly.args = {
|
|
181
|
+
bType: 'Enum',
|
|
182
|
+
enumOrdinals: ['1', '2', '3'],
|
|
183
|
+
enumLabels: ['Ok', 'Warning', 'Alarm'],
|
|
184
|
+
label: 'Enum - HealthKind',
|
|
185
|
+
defaultVal: '1',
|
|
186
|
+
readOnly: true,
|
|
187
|
+
};
|
|
188
|
+
|
|
157
189
|
export const Timestamp = Template.bind({});
|
|
158
190
|
Timestamp.args = {
|
|
159
191
|
bType: 'Timestamp',
|
|
@@ -170,9 +202,17 @@ ObjRef.args = {
|
|
|
170
202
|
|
|
171
203
|
export const Dbpos = Template.bind({});
|
|
172
204
|
Dbpos.args = {
|
|
205
|
+
bType: 'Dbpos',
|
|
206
|
+
label: 'Double-Point Status',
|
|
207
|
+
defaultVal: '0',
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export const DbposReadOnly = Template.bind({});
|
|
211
|
+
DbposReadOnly.args = {
|
|
173
212
|
bType: 'Dbpos',
|
|
174
213
|
label: 'Double-Point Status',
|
|
175
214
|
defaultVal: '2',
|
|
215
|
+
readOnly: true,
|
|
176
216
|
};
|
|
177
217
|
|
|
178
218
|
export const Tcmd = Template.bind({});
|
|
@@ -182,6 +222,14 @@ Tcmd.args = {
|
|
|
182
222
|
defaultVal: '2',
|
|
183
223
|
};
|
|
184
224
|
|
|
225
|
+
export const TcmdReadOnly = Template.bind({});
|
|
226
|
+
TcmdReadOnly.args = {
|
|
227
|
+
bType: 'Tcmd',
|
|
228
|
+
label: 'Tap Command',
|
|
229
|
+
defaultVal: '3',
|
|
230
|
+
readOnly: true,
|
|
231
|
+
};
|
|
232
|
+
|
|
185
233
|
export const EntryTime = Template.bind({});
|
|
186
234
|
EntryTime.args = {
|
|
187
235
|
bType: 'EntryTime',
|
|
@@ -206,6 +254,7 @@ OptFlds.args = {
|
|
|
206
254
|
bType: 'OptFlds',
|
|
207
255
|
label: 'Optional Fields',
|
|
208
256
|
defaultVal: '0000000011',
|
|
257
|
+
readOnly: false,
|
|
209
258
|
};
|
|
210
259
|
|
|
211
260
|
export const SvOptFlds = Template.bind({});
|
|
@@ -213,6 +262,7 @@ SvOptFlds.args = {
|
|
|
213
262
|
bType: 'SvOptFlds',
|
|
214
263
|
label: 'Sampled Values Optional Fields',
|
|
215
264
|
defaultVal: '000101',
|
|
265
|
+
readOnly: true,
|
|
216
266
|
};
|
|
217
267
|
|
|
218
268
|
export const LogOptFlds = Template.bind({});
|