@ntix/components-scorad 1.0.2 → 1.0.4
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/LICENSE.md +1 -1
- package/README.md +28 -0
- package/VALIDATION.md +39 -0
- package/dist/@ntix/components-scorad.es.js +107 -46
- package/dist/@ntix/components-scorad.umd.js +19 -19
- package/dist/HTMLScoradValueElement.d.ts +37 -0
- package/dist/ScoradData.d.ts +1 -1
- package/dist/ScoradExtentData.d.ts +11 -7
- package/dist/ScoradExtentWeights.d.ts +1 -1
- package/dist/ScoradIntensityData.d.ts +11 -7
- package/dist/ScoradResources.d.ts +11 -0
- package/dist/ScoradScore.d.ts +14 -1
- package/dist/ScoradSubjectiveData.d.ts +7 -3
- package/dist/component.d.ts +36 -6
- package/dist/componentsScoradLogger.d.ts +8 -0
- package/dist/constants.d.ts +19 -4
- package/dist/extent/component.d.ts +50 -7
- package/dist/getScoradScore.d.ts +1 -2
- package/dist/index.d.ts +1 -0
- package/dist/intensity/component.d.ts +40 -7
- package/dist/label/component.d.ts +1 -1
- package/dist/options/component.d.ts +8 -11
- package/dist/subjective/component.d.ts +40 -7
- package/dist/weightings/component.d.ts +30 -7
- package/docs/HTMLScoradValueElement.md +35 -0
- package/docs/README.md +36 -0
- package/docs/ScoradData.md +13 -0
- package/docs/ScoradExtentData.md +63 -0
- package/docs/ScoradExtentWeights.md +13 -0
- package/docs/ScoradIntensityData.md +64 -0
- package/docs/ScoradResources.md +41 -0
- package/docs/ScoradScore.md +47 -0
- package/docs/ScoradSubjectiveData.md +32 -0
- package/docs/component.md +68 -0
- package/docs/componentsScoradLogger.md +14 -0
- package/docs/constants.md +99 -0
- package/docs/extent.component.md +86 -0
- package/docs/getScoradScore.md +25 -0
- package/docs/intensity.component.md +77 -0
- package/docs/selectScoradWeights.md +25 -0
- package/docs/subjective.component.md +77 -0
- package/docs/validateScoradData.md +26 -0
- package/docs/weightings.component.md +59 -0
- package/package.json +15 -7
package/LICENSE.md
CHANGED
package/README.md
CHANGED
|
@@ -2,12 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
A professional-grade component library for calculating and visualizing SCORAD (SCORing Atopic Dermatitis) assessments. Developed by Antix Software Limited.
|
|
4
4
|
|
|
5
|
+
**View the interactive demo [antix.co.uk/scorad](https://antix.co.uk/scorad)**
|
|
6
|
+
|
|
5
7
|
## Features
|
|
6
8
|
|
|
7
9
|
- Interactive Body Maps: High-performance SVG-based surface area selection.
|
|
8
10
|
- SCORAD Formula: Sections A (Extent), B (Intensity), and C (Subjective).
|
|
9
11
|
- Custom Elements: Easy integration with any framework or plain HTML.
|
|
10
12
|
|
|
13
|
+
## Validation & Accuracy
|
|
14
|
+
This component has been mathematically validated against the ETFAD SCORAD reference standards.
|
|
15
|
+
See [VALIDATION.md](./VALIDATION.md) for the full report and test coverage details.
|
|
16
|
+
|
|
11
17
|
## Installation
|
|
12
18
|
|
|
13
19
|
```shell
|
|
@@ -43,6 +49,28 @@ Then add the component to your HTML:
|
|
|
43
49
|
<scorad-component></scorad-component>
|
|
44
50
|
```
|
|
45
51
|
|
|
52
|
+
## Documentation
|
|
53
|
+
|
|
54
|
+
### 🧱 Components
|
|
55
|
+
*Primary UI elements for building the assessment.*
|
|
56
|
+
|
|
57
|
+
- [**Scorad Root**](./docs/component.md) – The main coordinator and score aggregator.
|
|
58
|
+
- [**Extent (Section A)**](./docs/extent.component.md) – Surface area calculation.
|
|
59
|
+
- [**Intensity (Section B)**](./docs/intensity.component.md) – Clinical sign grading.
|
|
60
|
+
- [**Subjective (Section C)**](./docs/subjective.component.md) – Patient-reported symptoms.
|
|
61
|
+
- [**Weightings**](./docs/weightings.component.md) – Adult/Child toggle.
|
|
62
|
+
|
|
63
|
+
### 📊 Data Models & Logic
|
|
64
|
+
*Records and calculation engines.*
|
|
65
|
+
|
|
66
|
+
- [**ScoradScore**](./docs/ScoradScore.md) – The output structure (A, B, C, Total).
|
|
67
|
+
- [**ScoradData**](./docs/ScoradData.md) – The complete assessment state.
|
|
68
|
+
- [**getScoradScore**](./docs/getScoradScore.md) – The mathematical formula implementation.
|
|
69
|
+
- [**Clinical Constants**](./docs/constants.md) – Max values and defaults.
|
|
70
|
+
|
|
71
|
+
### 🌐 Resources
|
|
72
|
+
- [**Localization (ScoradResources)**](./docs/ScoradResources.md) – UI strings and descriptions.
|
|
73
|
+
|
|
46
74
|
## Licensing
|
|
47
75
|
|
|
48
76
|
This package is NOT open-source. Usage is governed by the Antix Software License.
|
package/VALIDATION.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Validation: @ntix/components-scorad
|
|
2
|
+
|
|
3
|
+
## 1. Overview
|
|
4
|
+
This document outlines the validation procedures and mathematical accuracy of the SCORAD (SCORing Atopic Dermatitis) calculation logic within this package.
|
|
5
|
+
|
|
6
|
+
## 2. Reference Standard
|
|
7
|
+
The implementation is based on the consensus report of the European Task Force on Atopic Dermatitis (ETFAD).
|
|
8
|
+
|
|
9
|
+
**Formula:** $Score = \frac{A}{5} + \frac{7B}{2} + C$
|
|
10
|
+
|
|
11
|
+
- **A (Extent):** Surface area percentage (0–100). Includes adult/child weighting adjustments for head and limbs.
|
|
12
|
+
- **B (Intensity):** Sum of 6 clinical signs (0–3 each), max 18.
|
|
13
|
+
- **C (Subjective):** Sum of Pruritus and Insomnia (0–10 each), max 20.
|
|
14
|
+
|
|
15
|
+
## 3. Automated Test Suite
|
|
16
|
+
Validation is performed using `vitest` in a `happy-dom` environment. The following critical paths are verified on every build:
|
|
17
|
+
|
|
18
|
+
### 3.1. Boundary Testing
|
|
19
|
+
- **Minimum Score:** Confirmed $0.00$ when all inputs are zero.
|
|
20
|
+
- **Maximum Score:** Confirmed $103.00$ when all inputs are at maximum capacity.
|
|
21
|
+
|
|
22
|
+
### 3.2. Weighting & Precision
|
|
23
|
+
- **Intensity Weighting:** Verifies that Intensity (Section B) contributes to the total with a multiplier of $3.5$ (e.g., an Intensity of 3 results in a sub-score of 10.5).
|
|
24
|
+
- **Rounding:** Results are rounded to 2 decimal places to ensure consistency across clinical documentation.
|
|
25
|
+
|
|
26
|
+
### 3.3. Age-Based Extent (Adult vs Child)
|
|
27
|
+
- Validates the calculation across both adult and pediatric surface area distributions.
|
|
28
|
+
|
|
29
|
+
## 4. Error Handling & Safety
|
|
30
|
+
The library implements strict validation via `@ntix/components-core`. Calculations will fail with a descriptive `Failure` object if:
|
|
31
|
+
- Extent values exceed physiological maximums.
|
|
32
|
+
- Intensity values fall outside the 0–3 range.
|
|
33
|
+
- Subjective values fall outside the 0–10 range.
|
|
34
|
+
|
|
35
|
+
## 5. Summary
|
|
36
|
+
The @ntix/components-scorad calculation logic is deemed mathematically sound and compliant with the ETFAD standard for digital SCORAD assessments.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
© 2025 Antix Software Limited ([antix.co.uk](https://antix.co.uk)). Prepared for clinical and commercial review.
|
|
@@ -967,7 +967,7 @@ const SCORAD_EXTENT_MAX_VALUE = 100, SCORAD_INTENSITY_MAX_VALUE = 3, SCORAD_SUBJ
|
|
|
967
967
|
lowerLimbs: .28,
|
|
968
968
|
genitals: 0
|
|
969
969
|
};
|
|
970
|
-
var component_default$6 = ":host{--host-display:inline-flex;--host-font-size:1rem;flex-wrap:wrap;justify-content:center;align-items:center;position:relative}label{padding:var(--host-padding-unit)}svg{min-width:14rem;max-width:18rem;margin:var(--host-padding-unit)0;fill:#0000;stroke:var(--host-color);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;flex:16rem;overflow:visible}@media print{svg{flex:0 0 14rem;width:14rem}}path,line{vector-effect:non-scaling-stroke}path{opacity:.333}text,line{opacity:.667}g{outline:none}g[tabindex] path{opacity:1;fill:hsla(var(--scorad-h,0),var(--extent,\"0%\"),50%,var(--opacity,0))
|
|
970
|
+
var component_default$6 = ":host{--host-display:inline-flex;--host-font-size:1rem;flex-wrap:wrap;justify-content:center;align-items:center;position:relative}label{padding:var(--host-padding-unit)}svg{min-width:14rem;max-width:18rem;margin:var(--host-padding-unit)0;fill:#0000;stroke:var(--host-color);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;flex:16rem;overflow:visible}@media print{svg{flex:0 0 14rem;width:14rem}}path,line{vector-effect:non-scaling-stroke}path{opacity:.333}text,line{opacity:.667}g{outline:none}g[tabindex] path{opacity:1;fill:hsla(var(--scorad-h,0),var(--extent,\"0%\"),50%,var(--opacity,0))}:host(:not([aria-readonly=true])) g[tabindex] path{cursor:grab}:host(:not([aria-readonly=true])) :has(:active) g[tabindex] path{cursor:ns-resize}:is(:host(:not([aria-readonly=true])) :not(:has(:active)) g[tabindex]:hover path,:host(:not([aria-readonly=true])) :not(:has(:active)) g[tabindex]:hover line){stroke-width:2px;stroke:var(--host-primary-color);stroke-dasharray:2 3.5;opacity:1}:host(:not([aria-readonly=true])) g[tabindex]:focus path,:host(:not([aria-readonly=true])) g[tabindex]:active path,:host(:not([aria-readonly=true])) g[tabindex].selected path,:host(:not([aria-readonly=true])) g[tabindex]:focus line,:host(:not([aria-readonly=true])) g[tabindex]:active line,:host(:not([aria-readonly=true])) g[tabindex].selected line{stroke-width:2px;stroke:var(--host-primary-color);opacity:1;stroke-dasharray:none!important}g[tabindex] text{fill:var(--host-color);stroke:none;font-size:var(--host-font-size);text-anchor:end}g[tabindex].posterior-trunk text{text-anchor:start}:is(:host(:not([aria-readonly=true])) :not(:has(:active)) g[tabindex]:hover text,:host(:not([aria-readonly=true])) g[tabindex]:focus text,:host(:not([aria-readonly=true])) g[tabindex]:active text,:host(:not([aria-readonly=true])) g[tabindex].selected text){fill:var(--host-primary-color);opacity:1}";
|
|
971
971
|
const selectScoradWeights = (e) => e?.child ? SCORAD_CHILD_WEIGHTS : SCORAD_ADULT_WEIGHTS, validateScoradData = (e) => {
|
|
972
972
|
let t = [], n = (e, n, r) => {
|
|
973
973
|
for (let [i, a] of Object.entries(e)) validateScoradData.isValid(a, r) || t.push(validateScoradData.formatError(n, i, r, a));
|
|
@@ -1046,11 +1046,25 @@ const ScoradResources = {
|
|
|
1046
1046
|
};
|
|
1047
1047
|
var tag$6 = "scorad-extent", HTMLScoradExtentElement = class extends HTMLComponentElement {
|
|
1048
1048
|
connectedCallback() {
|
|
1049
|
-
this.render();
|
|
1049
|
+
this.render(), this.addEventListener("focusin", this.handleFocusIn, { once: !0 });
|
|
1050
|
+
}
|
|
1051
|
+
disconnectedCallback() {
|
|
1052
|
+
this.removeEventListener("focusin", this.handleFocusIn);
|
|
1050
1053
|
}
|
|
1054
|
+
handleFocusIn = () => {
|
|
1055
|
+
this.readonly || (this.committedValue = this.value, this.addEventListener("focusout", this.handleFocusOut, { once: !0 }));
|
|
1056
|
+
};
|
|
1057
|
+
handleFocusOut = () => {
|
|
1058
|
+
this.addEventListener("focusin", this.handleFocusIn, { once: !0 }), !areEqual(this.value, this.committedValue) && this.valueChange(this.value);
|
|
1059
|
+
};
|
|
1051
1060
|
child = !1;
|
|
1061
|
+
readonly = !1;
|
|
1062
|
+
committedValue = SCORAD_EXTENT_DEFAULT;
|
|
1052
1063
|
value = SCORAD_EXTENT_DEFAULT;
|
|
1053
1064
|
score;
|
|
1065
|
+
setValue = (e) => {
|
|
1066
|
+
this.value = e, this.errors = void 0, this.valueInput(this.value);
|
|
1067
|
+
};
|
|
1054
1068
|
errors;
|
|
1055
1069
|
afterRender() {
|
|
1056
1070
|
if (!this.value) {
|
|
@@ -1076,11 +1090,12 @@ var tag$6 = "scorad-extent", HTMLScoradExtentElement = class extends HTMLCompone
|
|
|
1076
1090
|
render() {
|
|
1077
1091
|
let e = (e) => {
|
|
1078
1092
|
let t = (t) => {
|
|
1093
|
+
if (this.readonly) return;
|
|
1079
1094
|
let n = Math.round(Math.min(100, Math.max(0, t)));
|
|
1080
|
-
this.
|
|
1095
|
+
this.setValue({
|
|
1081
1096
|
...this.value,
|
|
1082
1097
|
[e]: n
|
|
1083
|
-
}
|
|
1098
|
+
});
|
|
1084
1099
|
};
|
|
1085
1100
|
return (n) => {
|
|
1086
1101
|
if (!n) return;
|
|
@@ -1203,28 +1218,31 @@ var tag$6 = "scorad-extent", HTMLScoradExtentElement = class extends HTMLCompone
|
|
|
1203
1218
|
valueChange;
|
|
1204
1219
|
};
|
|
1205
1220
|
__decorate([Att(AttBoolean)], HTMLScoradExtentElement.prototype, "child", void 0), __decorate([Att({
|
|
1221
|
+
name: "aria-readonly",
|
|
1222
|
+
...AttTrueFalse
|
|
1223
|
+
})], HTMLScoradExtentElement.prototype, "readonly", void 0), __decorate([Att({
|
|
1206
1224
|
name: "has-errors",
|
|
1207
1225
|
write: (e) => e == null ? void 0 : "",
|
|
1208
1226
|
read: !1
|
|
1209
|
-
})], HTMLScoradExtentElement.prototype, "errors", void 0), __decorate([Watch("value", "errors")], HTMLScoradExtentElement.prototype, "afterRender", null), __decorate([Watch("child")], HTMLScoradExtentElement.prototype, "render", null), __decorate([Event()], HTMLScoradExtentElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradExtentElement.prototype, "valueChange", void 0), HTMLScoradExtentElement = __decorate([Component({
|
|
1227
|
+
})], HTMLScoradExtentElement.prototype, "errors", void 0), __decorate([Watch("value", "errors", "readonly")], HTMLScoradExtentElement.prototype, "afterRender", null), __decorate([Watch("child")], HTMLScoradExtentElement.prototype, "render", null), __decorate([Event()], HTMLScoradExtentElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradExtentElement.prototype, "valueChange", void 0), HTMLScoradExtentElement = __decorate([Component({
|
|
1210
1228
|
tag: tag$6,
|
|
1211
1229
|
css: [host_default, component_default$6],
|
|
1212
1230
|
delegatesFocus: !0
|
|
1213
1231
|
})], HTMLScoradExtentElement);
|
|
1214
|
-
var component_default$4 = ":host{--host-display:inline-flex;flex-direction:column;position:relative}scorad-options{align-self:center;margin-left:auto}", component_default$5 = ":host{--host-display:inline-flex;--host-option-width:var(--scorad-option-width,1.5em);--host-option-height:var(--scorad-option-height,1.5em);--host-option-border:var(--scorad-option-border,solid 1px var(--host-color));--host-option-border-selected:var(--scorad-option-border-selected,solid 2px var(--host-color));--host-option-color:var(--scorad-option-color,var(--host-color));--host-option-background:var(--scorad-option-background,transparent);--host-option-color-selected:var(--scorad-option-color-selected,var(--host-background-color));--host-option-background-selected:var(--scorad-option-background-selected,var(--host-color));gap:var(--host-spacing-unit);margin:var(--host-padding-unit)0;outline:none;width:max-content;position:relative}span{height:var(--host-option-height);width:var(--host-option-width);outline:var(--host-option-border);border-radius:var(--host-border-radius);padding:calc(.5*var(--host-padding-unit))var(--host-padding-unit);color:var(--host-option-color);background:var(--host-option-background)
|
|
1232
|
+
var component_default$4 = ":host{--host-display:inline-flex;flex-direction:column;position:relative}scorad-options{align-self:center;margin-left:auto}", component_default$5 = ":host{--host-display:inline-flex;--host-option-width:var(--scorad-option-width,1.5em);--host-option-height:var(--scorad-option-height,1.5em);--host-option-border:var(--scorad-option-border,solid 1px var(--host-color));--host-option-border-selected:var(--scorad-option-border-selected,solid 2px var(--host-color));--host-option-color:var(--scorad-option-color,var(--host-color));--host-option-background:var(--scorad-option-background,transparent);--host-option-color-selected:var(--scorad-option-color-selected,var(--host-background-color));--host-option-background-selected:var(--scorad-option-background-selected,var(--host-color));gap:var(--host-spacing-unit);margin:var(--host-padding-unit)0;outline:none;width:max-content;position:relative}span{height:var(--host-option-height);width:var(--host-option-width);outline:var(--host-option-border);border-radius:var(--host-border-radius);padding:calc(.5*var(--host-padding-unit))var(--host-padding-unit);color:var(--host-option-color);background:var(--host-option-background)}:host(:not([aria-readonly=true])) span{cursor:pointer}span:before{content:\"\";touch-action:none;pointer-events:none}span[aria-selected=true]{outline:var(--host-option-border-selected);color:var(--host-option-color-selected);background:var(--host-option-background-selected)}", tag$5 = "scorad-options", HTMLScoradOptionsElement = class extends HTMLComponentElement {
|
|
1215
1233
|
connectedCallback() {
|
|
1216
|
-
this.render(), this.addEventListener("focusin", this.
|
|
1234
|
+
this.render(), this.addEventListener("focusin", this.handleFocusIn, { once: !0 }), this.addEventListener("click", this.handleClick);
|
|
1217
1235
|
}
|
|
1218
1236
|
disconnectedCallback() {
|
|
1219
|
-
this.
|
|
1237
|
+
this.removeEventListener("focusin", this.handleFocusIn), this.removeEventListener("click", this.handleClick);
|
|
1220
1238
|
}
|
|
1221
|
-
|
|
1222
|
-
this.readonly || (this.committedValue = this.value, this.addEventListener("focusout", this.
|
|
1239
|
+
handleFocusIn = () => {
|
|
1240
|
+
this.readonly || (this.committedValue = this.value, this.addEventListener("focusout", this.handleFocusOut, { once: !0 }), this.addEventListener("keydown", this.handleKeydown));
|
|
1223
1241
|
};
|
|
1224
|
-
|
|
1225
|
-
this.removeEventListener("keydown", this.
|
|
1242
|
+
handleFocusOut = () => {
|
|
1243
|
+
this.removeEventListener("keydown", this.handleKeydown), this.addEventListener("focusin", this.handleFocusIn, { once: !0 }), this.setValue(this.value), this.value !== this.committedValue && this.valueChange(this.value);
|
|
1226
1244
|
};
|
|
1227
|
-
|
|
1245
|
+
handleClick = (e) => {
|
|
1228
1246
|
if (this.readonly) return;
|
|
1229
1247
|
e.stopPropagation(), e.preventDefault(), this.focus();
|
|
1230
1248
|
let t = e.composedPath()[0];
|
|
@@ -1232,7 +1250,7 @@ var component_default$4 = ":host{--host-display:inline-flex;flex-direction:colum
|
|
|
1232
1250
|
let n = Number.parseInt(t.dataset.value);
|
|
1233
1251
|
this.setValue(n);
|
|
1234
1252
|
};
|
|
1235
|
-
|
|
1253
|
+
handleKeydown = (e) => {
|
|
1236
1254
|
let t = this.value ?? 0;
|
|
1237
1255
|
switch (e.key) {
|
|
1238
1256
|
case "ArrowLeft":
|
|
@@ -1268,7 +1286,7 @@ var component_default$4 = ":host{--host-display:inline-flex;flex-direction:colum
|
|
|
1268
1286
|
afterRender() {
|
|
1269
1287
|
this.shadowRoot && this.shadowRoot.querySelectorAll("span").forEach((e) => {
|
|
1270
1288
|
let t = Number.parseInt(e.dataset.value);
|
|
1271
|
-
if (e.
|
|
1289
|
+
if (e.setAttribute("aria-selected", t === this.value ? "true" : "false"), !this.showHue) return;
|
|
1272
1290
|
if (t > this.value) {
|
|
1273
1291
|
e.style.backgroundColor = "";
|
|
1274
1292
|
return;
|
|
@@ -1289,7 +1307,7 @@ __decorate([Att({
|
|
|
1289
1307
|
})], HTMLScoradOptionsElement.prototype, "max", void 0), __decorate([Att(AttBoolean)], HTMLScoradOptionsElement.prototype, "showHue", void 0), __decorate([Att({
|
|
1290
1308
|
name: "aria-readonly",
|
|
1291
1309
|
...AttTrueFalse
|
|
1292
|
-
})], HTMLScoradOptionsElement.prototype, "readonly", void 0), __decorate([Att({ write: !1 })], HTMLScoradOptionsElement.prototype, "text", void 0), __decorate([Watch("min", "max", "text")], HTMLScoradOptionsElement.prototype, "render", null), __decorate([Watch("value")], HTMLScoradOptionsElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradOptionsElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradOptionsElement.prototype, "valueChange", void 0), HTMLScoradOptionsElement = __decorate([Component({
|
|
1310
|
+
})], HTMLScoradOptionsElement.prototype, "readonly", void 0), __decorate([Att({ write: !1 })], HTMLScoradOptionsElement.prototype, "text", void 0), __decorate([Watch("min", "max", "text")], HTMLScoradOptionsElement.prototype, "render", null), __decorate([Watch("value", "readonly")], HTMLScoradOptionsElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradOptionsElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradOptionsElement.prototype, "valueChange", void 0), HTMLScoradOptionsElement = __decorate([Component({
|
|
1293
1311
|
tag: tag$5,
|
|
1294
1312
|
css: [host_default, component_default$5]
|
|
1295
1313
|
})], HTMLScoradOptionsElement);
|
|
@@ -1297,6 +1315,7 @@ var tag$4 = "scorad-intensity", HTMLScoradIntensityElement = class extends HTMLC
|
|
|
1297
1315
|
connectedCallback() {
|
|
1298
1316
|
this.render();
|
|
1299
1317
|
}
|
|
1318
|
+
readonly = !1;
|
|
1300
1319
|
value = SCORAD_INTENSITY_DEFAULT;
|
|
1301
1320
|
score;
|
|
1302
1321
|
errors;
|
|
@@ -1311,7 +1330,7 @@ var tag$4 = "scorad-intensity", HTMLScoradIntensityElement = class extends HTMLC
|
|
|
1311
1330
|
n.dataset.value = `${t}`;
|
|
1312
1331
|
let r = n.querySelector("scorad-options");
|
|
1313
1332
|
if (!r) return;
|
|
1314
|
-
r.value = t, r.style.setProperty("--host-option-border", this.errors?.[e] == null ? null : "solid 1px var(--host-error-color)");
|
|
1333
|
+
r.value = t, r.readonly = this.readonly, r.style.setProperty("--host-option-border", this.errors?.[e] == null ? null : "solid 1px var(--host-error-color)");
|
|
1315
1334
|
}
|
|
1316
1335
|
}
|
|
1317
1336
|
render() {
|
|
@@ -1321,12 +1340,17 @@ var tag$4 = "scorad-intensity", HTMLScoradIntensityElement = class extends HTMLC
|
|
|
1321
1340
|
}
|
|
1322
1341
|
renderLevel(e) {
|
|
1323
1342
|
let t = (t) => {
|
|
1324
|
-
t && t.addEventListener("value-input", (t) => {
|
|
1343
|
+
t && (t.addEventListener("value-input", (t) => {
|
|
1325
1344
|
this.value = {
|
|
1326
1345
|
...this.value,
|
|
1327
1346
|
[e]: t.detail
|
|
1328
|
-
}, this.valueInput(this.value);
|
|
1329
|
-
})
|
|
1347
|
+
}, this.errors = void 0, this.valueInput(this.value);
|
|
1348
|
+
}), t.addEventListener("value-change", (t) => {
|
|
1349
|
+
this.value = {
|
|
1350
|
+
...this.value,
|
|
1351
|
+
[e]: t.detail
|
|
1352
|
+
}, this.errors = void 0, this.valueChange(this.value);
|
|
1353
|
+
}));
|
|
1330
1354
|
}, n = ScoradResources.intensity[e];
|
|
1331
1355
|
return html`
|
|
1332
1356
|
<scorad-label class="${toKebabCase(e)} row"
|
|
@@ -1342,10 +1366,13 @@ var tag$4 = "scorad-intensity", HTMLScoradIntensityElement = class extends HTMLC
|
|
|
1342
1366
|
valueChange;
|
|
1343
1367
|
};
|
|
1344
1368
|
__decorate([Att({
|
|
1369
|
+
name: "aria-readonly",
|
|
1370
|
+
...AttTrueFalse
|
|
1371
|
+
})], HTMLScoradIntensityElement.prototype, "readonly", void 0), __decorate([Att({
|
|
1345
1372
|
name: "has-errors",
|
|
1346
1373
|
write: (e) => e == null ? void 0 : "",
|
|
1347
1374
|
read: !1
|
|
1348
|
-
})], HTMLScoradIntensityElement.prototype, "errors", void 0), __decorate([Watch("value", "errors")], HTMLScoradIntensityElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradIntensityElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradIntensityElement.prototype, "valueChange", void 0), HTMLScoradIntensityElement = __decorate([Component({
|
|
1375
|
+
})], HTMLScoradIntensityElement.prototype, "errors", void 0), __decorate([Watch("value", "errors", "readonly")], HTMLScoradIntensityElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradIntensityElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradIntensityElement.prototype, "valueChange", void 0), HTMLScoradIntensityElement = __decorate([Component({
|
|
1349
1376
|
tag: tag$4,
|
|
1350
1377
|
css: [host_default, component_default$4],
|
|
1351
1378
|
delegatesFocus: !0
|
|
@@ -1354,6 +1381,7 @@ var component_default$3 = ":host{--host-display:inline-flex;--scorad-label-text-
|
|
|
1354
1381
|
connectedCallback() {
|
|
1355
1382
|
this.render();
|
|
1356
1383
|
}
|
|
1384
|
+
readonly = !1;
|
|
1357
1385
|
value = SCORAD_SUBJECTIVE_DEFAULT;
|
|
1358
1386
|
score;
|
|
1359
1387
|
errors;
|
|
@@ -1368,7 +1396,7 @@ var component_default$3 = ":host{--host-display:inline-flex;--scorad-label-text-
|
|
|
1368
1396
|
n.dataset.value = `${t}`;
|
|
1369
1397
|
let r = n.querySelector("scorad-options");
|
|
1370
1398
|
if (!r) return;
|
|
1371
|
-
r.value = t, r.style.setProperty("--host-option-border", this.errors?.[e] == null ? null : "solid 1px var(--host-error-color)");
|
|
1399
|
+
r.value = t, r.readonly = this.readonly, r.style.setProperty("--host-option-border", this.errors?.[e] == null ? null : "solid 1px var(--host-error-color)");
|
|
1372
1400
|
}
|
|
1373
1401
|
}
|
|
1374
1402
|
render() {
|
|
@@ -1398,10 +1426,13 @@ var component_default$3 = ":host{--host-display:inline-flex;--scorad-label-text-
|
|
|
1398
1426
|
valueChange;
|
|
1399
1427
|
};
|
|
1400
1428
|
__decorate([Att({
|
|
1429
|
+
name: "aria-readonly",
|
|
1430
|
+
...AttTrueFalse
|
|
1431
|
+
})], HTMLScoradSubjectiveElement.prototype, "readonly", void 0), __decorate([Att({
|
|
1401
1432
|
name: "has-errors",
|
|
1402
1433
|
write: (e) => e == null ? void 0 : "",
|
|
1403
1434
|
read: !1
|
|
1404
|
-
})], HTMLScoradSubjectiveElement.prototype, "errors", void 0), __decorate([Watch("value", "errors")], HTMLScoradSubjectiveElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradSubjectiveElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradSubjectiveElement.prototype, "valueChange", void 0), HTMLScoradSubjectiveElement = __decorate([Component({
|
|
1435
|
+
})], HTMLScoradSubjectiveElement.prototype, "errors", void 0), __decorate([Watch("value", "errors", "readonly")], HTMLScoradSubjectiveElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradSubjectiveElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradSubjectiveElement.prototype, "valueChange", void 0), HTMLScoradSubjectiveElement = __decorate([Component({
|
|
1405
1436
|
tag: tag$3,
|
|
1406
1437
|
css: [host_default, component_default$3],
|
|
1407
1438
|
delegatesFocus: !0
|
|
@@ -1410,6 +1441,7 @@ var component_default$2 = ":host{--host-display:inline-flex;padding:0 var(--host
|
|
|
1410
1441
|
connectedCallback() {
|
|
1411
1442
|
this.render();
|
|
1412
1443
|
}
|
|
1444
|
+
readonly = !1;
|
|
1413
1445
|
value = !1;
|
|
1414
1446
|
afterRender() {
|
|
1415
1447
|
if (this.value == null) {
|
|
@@ -1418,7 +1450,7 @@ var component_default$2 = ":host{--host-display:inline-flex;padding:0 var(--host
|
|
|
1418
1450
|
}
|
|
1419
1451
|
if (!this.shadowRoot) return;
|
|
1420
1452
|
let e = this.shadowRoot.querySelector("scorad-options");
|
|
1421
|
-
e && (e.value = this.value ? 1 : 0, e.text = ["Adult", "Child"]);
|
|
1453
|
+
e && (e.value = this.value ? 1 : 0, e.text = ["Adult", "Child"], e.readonly = this.readonly);
|
|
1422
1454
|
}
|
|
1423
1455
|
render() {
|
|
1424
1456
|
return html`
|
|
@@ -1434,7 +1466,10 @@ var component_default$2 = ":host{--host-display:inline-flex;padding:0 var(--host
|
|
|
1434
1466
|
valueInput;
|
|
1435
1467
|
valueChange;
|
|
1436
1468
|
};
|
|
1437
|
-
__decorate([
|
|
1469
|
+
__decorate([Att({
|
|
1470
|
+
name: "aria-readonly",
|
|
1471
|
+
...AttTrueFalse
|
|
1472
|
+
})], HTMLScoradWeightingsElement.prototype, "readonly", void 0), __decorate([Watch("value", "readonly")], HTMLScoradWeightingsElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradWeightingsElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradWeightingsElement.prototype, "valueChange", void 0), HTMLScoradWeightingsElement = __decorate([Component({
|
|
1438
1473
|
tag: tag$2,
|
|
1439
1474
|
css: [host_default, component_default$2],
|
|
1440
1475
|
delegatesFocus: !0
|
|
@@ -1453,12 +1488,12 @@ const getScoradScore = (e) => {
|
|
|
1453
1488
|
};
|
|
1454
1489
|
var component_default$1 = ":host{--host-display:var(--scorad-label-display,inline-flex);--host-options:var(--scorad-label-options,solid 1px var(--host-color));--host-text-min-width:var(--scorad-label-text-min-width,none);--host-text-max-width:var(--scorad-label-text-max-width,none);grid-column:1/3;grid-template-columns:subgrid;padding:var(--host-padding-unit);border-radius:var(--host-border-radius-outer);flex-wrap:wrap;align-content:baseline;align-items:baseline;position:relative}:host(:hover){outline:var(--host-outline-hover)}:host(:focus-within){outline:var(--host-outline-focus)}:host>label{min-width:var(--host-text-min-width);max-width:var(--host-text-max-width)}:host>label>slot[name=text]{transition:all .2s ease-in-out;display:block}:host>label>slot[name=description]{opacity:0;margin-bottom:-1.1em;transition:all .4s ease-in-out;display:block}:host(:hover)>label>slot[name=text],:host(:focus-within)>label>slot[name=text]{transform:translateY(-.5em)}:host(:hover)>label>slot[name=description],:host(:focus-within)>label>slot[name=description]{opacity:.667;transform:translateY(-.6em)}@media print{:host>label>slot[name=text]{transform:translateY(-.5em)}:host>label>slot[name=description]{opacity:.667;transform:translateY(-.6em)}}:host>label{padding:var(--host-padding-unit);flex:1;padding-left:0}", tag$1 = "scorad-label", HTMLScoradLabelElement = class extends HTMLComponentElement {
|
|
1455
1490
|
connectedCallback() {
|
|
1456
|
-
this.render(), this.addEventListener("click", this.
|
|
1491
|
+
this.render(), this.addEventListener("click", this.handleClick);
|
|
1457
1492
|
}
|
|
1458
1493
|
diconnectedCallback() {
|
|
1459
|
-
this.removeEventListener("click", this.
|
|
1494
|
+
this.removeEventListener("click", this.handleClick);
|
|
1460
1495
|
}
|
|
1461
|
-
|
|
1496
|
+
handleClick = (e) => {
|
|
1462
1497
|
this.querySelector(FOCUSABLE)?.focus();
|
|
1463
1498
|
};
|
|
1464
1499
|
text = "(label)";
|
|
@@ -1481,6 +1516,7 @@ var tag = "scorad-component", HTMLScoradElement = class extends HTMLComponentEle
|
|
|
1481
1516
|
connectedCallback() {
|
|
1482
1517
|
this.render();
|
|
1483
1518
|
}
|
|
1519
|
+
readonly = !1;
|
|
1484
1520
|
value = SCORAD_DEFAULT;
|
|
1485
1521
|
showErrors = !1;
|
|
1486
1522
|
afterRender() {
|
|
@@ -1497,13 +1533,13 @@ var tag = "scorad-component", HTMLScoradElement = class extends HTMLComponentEle
|
|
|
1497
1533
|
}, n);
|
|
1498
1534
|
e.innerText = `${t?.total ?? "Get Score"}`, e.style.color = this.showErrors && r != n ? "var(--host-error-color)" : "";
|
|
1499
1535
|
let i = this.shadowRoot.querySelector("scorad-subjective");
|
|
1500
|
-
i && (i.value = this.value?.subjective ?? SCORAD_SUBJECTIVE_DEFAULT, i.score = t?.B, this.showErrors && (i.errors = getValue(r, "subjective")));
|
|
1536
|
+
i && (i.value = this.value?.subjective ?? SCORAD_SUBJECTIVE_DEFAULT, i.score = t?.B, i.readonly = this.readonly, this.showErrors && (i.errors = getValue(r, "subjective")));
|
|
1501
1537
|
let a = this.shadowRoot.querySelector("scorad-intensity");
|
|
1502
|
-
a && (a.value = this.value?.intensity ?? SCORAD_INTENSITY_DEFAULT, a.score = t?.B, this.showErrors && (a.errors = getValue(r, "intensity")));
|
|
1538
|
+
a && (a.value = this.value?.intensity ?? SCORAD_INTENSITY_DEFAULT, a.score = t?.B, a.readonly = this.readonly, this.showErrors && (a.errors = getValue(r, "intensity")));
|
|
1503
1539
|
let o = this.shadowRoot.querySelector("scorad-extent");
|
|
1504
|
-
o && (o.child = this.value?.child ?? !1, o.value = this.value?.extent ?? SCORAD_EXTENT_DEFAULT, o.score = t?.A, this.showErrors && (o.errors = getValue(r, "extent")));
|
|
1540
|
+
o && (o.child = this.value?.child ?? !1, o.value = this.value?.extent ?? SCORAD_EXTENT_DEFAULT, o.score = t?.A, o.readonly = this.readonly, this.showErrors && (o.errors = getValue(r, "extent")));
|
|
1505
1541
|
let s = this.shadowRoot.querySelector("scorad-weightings");
|
|
1506
|
-
s && (s.value = this.value?.child ?? !1);
|
|
1542
|
+
s && (s.value = this.value?.child ?? !1, s.readonly = this.readonly);
|
|
1507
1543
|
}
|
|
1508
1544
|
render() {
|
|
1509
1545
|
return html`
|
|
@@ -1511,20 +1547,30 @@ var tag = "scorad-component", HTMLScoradElement = class extends HTMLComponentEle
|
|
|
1511
1547
|
<h3 slot="text">A</h3>
|
|
1512
1548
|
<p slot="description">extent - effected surface area</p>
|
|
1513
1549
|
<scorad-weightings ${(e) => {
|
|
1514
|
-
e instanceof HTMLScoradWeightingsElement && e.addEventListener("value-input", (e) => {
|
|
1550
|
+
e instanceof HTMLScoradWeightingsElement && (e.addEventListener("value-input", (e) => {
|
|
1515
1551
|
this.value = {
|
|
1516
1552
|
...this.value,
|
|
1517
1553
|
child: e.detail
|
|
1518
|
-
};
|
|
1519
|
-
})
|
|
1554
|
+
}, this.valueInput(this.value);
|
|
1555
|
+
}), e.addEventListener("value-change", (e) => {
|
|
1556
|
+
this.value = {
|
|
1557
|
+
...this.value,
|
|
1558
|
+
child: e.detail
|
|
1559
|
+
}, this.valueChange(this.value);
|
|
1560
|
+
}));
|
|
1520
1561
|
}}></scorad-weightings>
|
|
1521
1562
|
<scorad-extent tabindex="0" ${(e) => {
|
|
1522
|
-
e instanceof HTMLScoradExtentElement && e.addEventListener("value-input", (e) => {
|
|
1563
|
+
e instanceof HTMLScoradExtentElement && (e.addEventListener("value-input", (e) => {
|
|
1523
1564
|
this.value = {
|
|
1524
1565
|
...this.value,
|
|
1525
1566
|
extent: e.detail
|
|
1526
|
-
};
|
|
1527
|
-
})
|
|
1567
|
+
}, this.valueInput(this.value);
|
|
1568
|
+
}), e.addEventListener("value-change", (e) => {
|
|
1569
|
+
this.value = {
|
|
1570
|
+
...this.value,
|
|
1571
|
+
extent: e.detail
|
|
1572
|
+
}, this.valueChange(this.value);
|
|
1573
|
+
}));
|
|
1528
1574
|
}}></scorad-extent>
|
|
1529
1575
|
</scorad-label>
|
|
1530
1576
|
|
|
@@ -1532,12 +1578,17 @@ var tag = "scorad-component", HTMLScoradElement = class extends HTMLComponentEle
|
|
|
1532
1578
|
<h3 slot="text">B</h3>
|
|
1533
1579
|
<p slot="description">intensity - clinical sign severity</p>
|
|
1534
1580
|
<scorad-intensity tabindex="0" ${(e) => {
|
|
1535
|
-
e instanceof HTMLScoradIntensityElement && e.addEventListener("value-input", (e) => {
|
|
1581
|
+
e instanceof HTMLScoradIntensityElement && (e.addEventListener("value-input", (e) => {
|
|
1536
1582
|
this.value = {
|
|
1537
1583
|
...this.value,
|
|
1538
1584
|
intensity: e.detail
|
|
1539
|
-
};
|
|
1540
|
-
})
|
|
1585
|
+
}, this.valueInput(this.value);
|
|
1586
|
+
}), e.addEventListener("value-change", (e) => {
|
|
1587
|
+
this.value = {
|
|
1588
|
+
...this.value,
|
|
1589
|
+
intensity: e.detail
|
|
1590
|
+
}, this.valueChange(this.value);
|
|
1591
|
+
}));
|
|
1541
1592
|
}}></scorad-intensity>
|
|
1542
1593
|
</scorad-label>
|
|
1543
1594
|
|
|
@@ -1545,12 +1596,17 @@ var tag = "scorad-component", HTMLScoradElement = class extends HTMLComponentEle
|
|
|
1545
1596
|
<h3 slot="text">C</h3>
|
|
1546
1597
|
<p slot="description">subjective - patient reported symptoms</p>
|
|
1547
1598
|
<scorad-subjective tabindex="0" ${(e) => {
|
|
1548
|
-
e instanceof HTMLScoradSubjectiveElement && e.addEventListener("value-input", (e) => {
|
|
1599
|
+
e instanceof HTMLScoradSubjectiveElement && (e.addEventListener("value-input", (e) => {
|
|
1549
1600
|
this.value = {
|
|
1550
1601
|
...this.value,
|
|
1551
1602
|
subjective: e.detail
|
|
1552
|
-
};
|
|
1553
|
-
})
|
|
1603
|
+
}, this.valueInput(this.value);
|
|
1604
|
+
}), e.addEventListener("value-change", (e) => {
|
|
1605
|
+
this.value = {
|
|
1606
|
+
...this.value,
|
|
1607
|
+
subjective: e.detail
|
|
1608
|
+
}, this.valueChange(this.value);
|
|
1609
|
+
}));
|
|
1554
1610
|
}}></scorad-subjective>
|
|
1555
1611
|
</scorad-label>
|
|
1556
1612
|
|
|
@@ -1560,7 +1616,7 @@ var tag = "scorad-component", HTMLScoradElement = class extends HTMLComponentEle
|
|
|
1560
1616
|
${(e) => {
|
|
1561
1617
|
e instanceof HTMLScoradLabelElement && e.addEventListener("click", () => {
|
|
1562
1618
|
if (!this.shadowRoot) return;
|
|
1563
|
-
this.showErrors = !0
|
|
1619
|
+
this.showErrors = !0;
|
|
1564
1620
|
let e = this.shadowRoot.querySelector("[has-errors]");
|
|
1565
1621
|
e && (e.focus({ preventScroll: !0 }), e.scrollIntoView({
|
|
1566
1622
|
behavior: "smooth",
|
|
@@ -1573,8 +1629,13 @@ var tag = "scorad-component", HTMLScoradElement = class extends HTMLComponentEle
|
|
|
1573
1629
|
</scorad-label>
|
|
1574
1630
|
`;
|
|
1575
1631
|
}
|
|
1632
|
+
valueInput;
|
|
1633
|
+
valueChange;
|
|
1576
1634
|
};
|
|
1577
|
-
__decorate([
|
|
1635
|
+
__decorate([Att({
|
|
1636
|
+
name: "aria-readonly",
|
|
1637
|
+
...AttTrueFalse
|
|
1638
|
+
})], HTMLScoradElement.prototype, "readonly", void 0), __decorate([Watch("value", "showErrors", "readonly")], HTMLScoradElement.prototype, "afterRender", null), __decorate([Event()], HTMLScoradElement.prototype, "valueInput", void 0), __decorate([Event()], HTMLScoradElement.prototype, "valueChange", void 0), HTMLScoradElement = __decorate([Component({
|
|
1578
1639
|
tag,
|
|
1579
1640
|
css: [host_default, component_default],
|
|
1580
1641
|
delegatesFocus: !0
|