uhc-portal-components-react 0.1.34 → 0.1.36

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/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ - Add a shared progressive animal, owner-or-caregiver and physical-evidence
6
+ onboarding form for veterinarian-assisted identity attestation.
7
+ - Add a capability-aware `SubjectIdentityCard` for provider-confirmed animal
8
+ identity and relationship readback.
9
+ - Add compact accessible clinical action buttons and a task-first emergency
10
+ hub with host-owned navigation and authorization.
11
+ - Let SOSChain hosts compose a task-first overview, keep secondary areas under
12
+ an accessible More menu and select cards without exposing identifiers in URLs.
13
+ - Make this repository the single source of truth for the cross-portal
14
+ BloodChain/UHC, VetChain Expo and HospitalApp component recovery inventory.
15
+ Keep consumer ownership and proof requirements beside the reusable React
16
+ component boundary instead of duplicating the matrix in one product portal.
17
+
18
+ ## 0.1.35
19
+
20
+ - Keep create actions in the clinical section header while edit and delete
21
+ actions belong to the exact resource card they modify.
22
+ - Render clinical editors in a top-level modal layer so sticky account menus
23
+ cannot cover them, and make composite date/time and blood-pressure controls
24
+ shrink or stack without escaping the dialog.
25
+
3
26
  ## 0.1.34
4
27
 
5
28
  - Keep clinical-write and association-management capabilities independent in
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # UHC Portal Components React
2
2
 
3
+ Historical reusable UI and flow anchors are tracked in
4
+ [`docs/LEGACY_FRONTEND_RECOVERY_INVENTORY.md`](docs/LEGACY_FRONTEND_RECOVERY_INVENTORY.md).
5
+
3
6
  Publishable, brand-neutral React components shared by:
4
7
 
5
8
  - UHC Personal
@@ -118,6 +121,15 @@ The package deliberately exposes modules instead of a cloned application:
118
121
  - `IdentityEvidenceDeclarationForm`: collects the business fields used to
119
122
  prepare a declaration. Hosts supply governed options and one high-level
120
123
  callback; the form never authors claims or handles certificates.
124
+ - `AnimalIdentityOnboarding`: one progressive animal, owner-or-caregiver and
125
+ physical-evidence journey recovered from the VetChain Expo flow. The host
126
+ creates the subject and returns the veterinarian-attested result.
127
+ - `SubjectIdentityCard`: capability-aware person or animal identity readback.
128
+ Facts, relationship status and edit authority are always provider supplied.
129
+ - `ClinicalActionButton`: compact add, edit and delete actions with complete
130
+ accessible names and host-owned authorization state.
131
+ - `EmergencyTaskHub`: task-first emergency navigation whose destinations and
132
+ availability are supplied by the authorized host.
121
133
 
122
134
  Clinical label semantics stay in `gdc-common-utils-ts` / the SDK reader. Hosts
123
135
  pass human titles to `ClinicalSectionSummary`: local `CodeableConcept.text`
@@ -154,4 +166,6 @@ UHC host application and must be extracted behind host-owned adapters. A brand
154
166
  adapter may change tokens, logo, product vocabulary, animal-specific forms and
155
167
  route destinations; it must not fork shared flow or authorization behavior.
156
168
 
157
- See [`docs/PERSONAL_FLOW_EXTRACTION.md`](docs/PERSONAL_FLOW_EXTRACTION.md).
169
+ See [`docs/PERSONAL_FLOW_EXTRACTION.md`](docs/PERSONAL_FLOW_EXTRACTION.md) and
170
+ the canonical cross-portal
171
+ [`docs/HISTORICAL_PORTAL_COMPONENT_RECOVERY_MATRIX.md`](docs/HISTORICAL_PORTAL_COMPONENT_RECOVERY_MATRIX.md).
@@ -0,0 +1,82 @@
1
+ import type { IdentityEvidenceStatus } from './IdentityEvidenceWorkspace.js';
2
+ export type AnimalControllerRelationship = 'owner' | 'caregiver';
3
+ export type AnimalIdentityOnboardingInput = Readonly<{
4
+ animalName: string;
5
+ taxonomyId: string;
6
+ birthDate?: string;
7
+ sex: 'female' | 'male' | 'other' | 'unknown';
8
+ identifierSystem: string;
9
+ identifierValue: string;
10
+ controllerLegalName: string;
11
+ controllerIdentifierType: string;
12
+ controllerIdentifierValue: string;
13
+ controllerCountry: string;
14
+ relationship: AnimalControllerRelationship;
15
+ ownerDocument: File;
16
+ animalDocument: File;
17
+ relationshipDocument: File;
18
+ controllerPin: string;
19
+ }>;
20
+ export type AnimalIdentityOnboardingCopy = Readonly<{
21
+ title: string;
22
+ intro: string;
23
+ animalStep: string;
24
+ controllerStep: string;
25
+ evidenceStep: string;
26
+ animalName: string;
27
+ taxonomyId: string;
28
+ birthDate: string;
29
+ sex: string;
30
+ sexUnknown: string;
31
+ sexFemale: string;
32
+ sexMale: string;
33
+ sexOther: string;
34
+ identifierSystem: string;
35
+ identifierValue: string;
36
+ controllerLegalName: string;
37
+ controllerIdentifierType: string;
38
+ controllerIdentifierValue: string;
39
+ controllerCountry: string;
40
+ relationship: string;
41
+ owner: string;
42
+ caregiver: string;
43
+ ownerDocument: string;
44
+ animalDocument: string;
45
+ relationshipDocument: string;
46
+ controllerPin: string;
47
+ submit: string;
48
+ }>;
49
+ /**
50
+ * Brand-neutral animal identity and controller-evidence editor recovered from
51
+ * the progressive VetChain Expo journey. The host persists and verifies the
52
+ * result; this component never grants authority or marks evidence verified.
53
+ */
54
+ export declare function AnimalIdentityOnboarding({ copy, onSubmit, submitAction, busy }: Readonly<{
55
+ copy: AnimalIdentityOnboardingCopy;
56
+ onSubmit: (input: AnimalIdentityOnboardingInput) => Promise<void> | void;
57
+ submitAction?: string;
58
+ busy?: boolean;
59
+ }>): import("react").JSX.Element;
60
+ export type SubjectIdentityCardSubject = Readonly<{
61
+ displayName: string;
62
+ kind: 'person' | 'animal';
63
+ imageUrl?: string;
64
+ facts: readonly Readonly<{
65
+ label: string;
66
+ value: string;
67
+ }>[];
68
+ }>;
69
+ /** Capability-aware readback. Values and status must come from the provider. */
70
+ export declare function SubjectIdentityCard({ subject, relationship, statusLabels, editLabel, canEdit, onEdit }: Readonly<{
71
+ subject: SubjectIdentityCardSubject;
72
+ relationship?: Readonly<{
73
+ label: string;
74
+ displayName: string;
75
+ status: IdentityEvidenceStatus;
76
+ }>;
77
+ statusLabels: Readonly<Record<IdentityEvidenceStatus, string>>;
78
+ editLabel?: string;
79
+ canEdit?: boolean;
80
+ onEdit?: () => void;
81
+ }>): import("react").JSX.Element;
82
+ //# sourceMappingURL=AnimalIdentityOnboarding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnimalIdentityOnboarding.d.ts","sourceRoot":"","sources":["../src/AnimalIdentityOnboarding.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ /**
4
+ * Brand-neutral animal identity and controller-evidence editor recovered from
5
+ * the progressive VetChain Expo journey. The host persists and verifies the
6
+ * result; this component never grants authority or marks evidence verified.
7
+ */
8
+ export function AnimalIdentityOnboarding({ copy, onSubmit, submitAction, busy = false }) {
9
+ const [submitting, setSubmitting] = useState(false);
10
+ async function submit(event) {
11
+ event.preventDefault();
12
+ const formElement = event.currentTarget;
13
+ const form = new FormData(formElement);
14
+ const ownerDocument = requiredFile(formElement, 'ownerDocument');
15
+ const animalDocument = requiredFile(formElement, 'animalDocument');
16
+ const relationshipDocument = requiredFile(formElement, 'relationshipDocument');
17
+ setSubmitting(true);
18
+ try {
19
+ await onSubmit({
20
+ animalName: requiredText(form, 'animalName'),
21
+ taxonomyId: requiredText(form, 'taxonomyId'),
22
+ birthDate: optionalText(form, 'birthDate'),
23
+ sex: requiredText(form, 'sex'),
24
+ identifierSystem: requiredText(form, 'identifierSystem'),
25
+ identifierValue: requiredText(form, 'identifierValue'),
26
+ controllerLegalName: requiredText(form, 'controllerLegalName'),
27
+ controllerIdentifierType: requiredText(form, 'controllerIdentifierType'),
28
+ controllerIdentifierValue: requiredText(form, 'controllerIdentifierValue'),
29
+ controllerCountry: requiredText(form, 'controllerCountry').toUpperCase(),
30
+ relationship: requiredText(form, 'relationship'),
31
+ ownerDocument,
32
+ animalDocument,
33
+ relationshipDocument,
34
+ controllerPin: requiredText(form, 'controllerPin'),
35
+ });
36
+ }
37
+ finally {
38
+ setSubmitting(false);
39
+ }
40
+ }
41
+ const disabled = busy || submitting;
42
+ return _jsxs("section", { className: "uhcp-animal-onboarding", "aria-labelledby": "animal-identity-onboarding-title", children: [_jsxs("header", { children: [_jsx("h2", { id: "animal-identity-onboarding-title", children: copy.title }), _jsx("p", { children: copy.intro })] }), _jsxs("form", { onSubmit: submit, children: [_jsxs("fieldset", { children: [_jsxs("legend", { children: [_jsx(StepNumber, { value: 1 }), " ", copy.animalStep] }), _jsxs("div", { className: "uhcp-animal-onboarding-fields", children: [_jsxs("label", { children: [copy.animalName, _jsx("input", { name: "animalName", required: true, maxLength: 80 })] }), _jsxs("label", { children: [copy.taxonomyId, _jsx("input", { name: "taxonomyId", required: true, inputMode: "numeric", pattern: "[1-9][0-9]{0,6}", defaultValue: "9615" })] }), _jsxs("label", { children: [copy.birthDate, _jsx("input", { name: "birthDate", type: "date" })] }), _jsxs("label", { children: [copy.sex, _jsxs("select", { name: "sex", defaultValue: "unknown", children: [_jsx("option", { value: "unknown", children: copy.sexUnknown }), _jsx("option", { value: "female", children: copy.sexFemale }), _jsx("option", { value: "male", children: copy.sexMale }), _jsx("option", { value: "other", children: copy.sexOther })] })] }), _jsxs("label", { children: [copy.identifierSystem, _jsxs("select", { name: "identifierSystem", defaultValue: "urn:iso:std:iso:11784:11785", children: [_jsx("option", { value: "urn:iso:std:iso:11784:11785", children: "ISO 11784/11785" }), _jsx("option", { value: "https://europa.eu/pet-passport", children: "EU pet passport" }), _jsx("option", { value: "https://vetchain.app/identifier/tattoo", children: "Tattoo" })] })] }), _jsxs("label", { children: [copy.identifierValue, _jsx("input", { name: "identifierValue", required: true, maxLength: 80, autoComplete: "off" })] })] })] }), _jsxs("fieldset", { children: [_jsxs("legend", { children: [_jsx(StepNumber, { value: 2 }), " ", copy.controllerStep] }), _jsxs("div", { className: "uhcp-animal-onboarding-fields", children: [_jsxs("label", { children: [copy.controllerLegalName, _jsx("input", { name: "controllerLegalName", required: true, maxLength: 160, autoComplete: "name" })] }), _jsxs("label", { children: [copy.controllerIdentifierType, _jsx("input", { name: "controllerIdentifierType", required: true, defaultValue: "national_identity_card", maxLength: 80 })] }), _jsxs("label", { children: [copy.controllerIdentifierValue, _jsx("input", { name: "controllerIdentifierValue", required: true, maxLength: 120, autoComplete: "off" })] }), _jsxs("label", { children: [copy.controllerCountry, _jsx("input", { name: "controllerCountry", required: true, pattern: "[A-Za-z]{2}", maxLength: 2, autoComplete: "country" })] }), _jsxs("label", { children: [copy.relationship, _jsxs("select", { name: "relationship", defaultValue: "owner", children: [_jsx("option", { value: "owner", children: copy.owner }), _jsx("option", { value: "caregiver", children: copy.caregiver })] })] })] })] }), _jsxs("fieldset", { children: [_jsxs("legend", { children: [_jsx(StepNumber, { value: 3 }), " ", copy.evidenceStep] }), _jsxs("div", { className: "uhcp-animal-onboarding-fields", children: [_jsxs("label", { children: [copy.ownerDocument, _jsx("input", { name: "ownerDocument", type: "file", accept: "application/pdf,image/jpeg,image/png", required: true })] }), _jsxs("label", { children: [copy.animalDocument, _jsx("input", { name: "animalDocument", type: "file", accept: "application/pdf,image/jpeg,image/png", required: true })] }), _jsxs("label", { children: [copy.relationshipDocument, _jsx("input", { name: "relationshipDocument", type: "file", accept: "application/pdf,image/jpeg,image/png", required: true })] }), _jsxs("label", { children: [copy.controllerPin, _jsx("input", { name: "controllerPin", type: "password", inputMode: "numeric", pattern: "[0-9]{6,12}", required: true, autoComplete: "new-password" })] })] })] }), _jsx("button", { type: "submit", className: "uhcp-animal-onboarding-submit", "data-portal-action": submitAction, disabled: disabled, children: copy.submit })] })] });
43
+ }
44
+ /** Capability-aware readback. Values and status must come from the provider. */
45
+ export function SubjectIdentityCard({ subject, relationship, statusLabels, editLabel, canEdit = false, onEdit }) {
46
+ const initial = subject.displayName.trim().slice(0, 1).toUpperCase() || '•';
47
+ return _jsxs("article", { className: "uhcp-subject-identity-card", children: [_jsxs("header", { children: [subject.imageUrl
48
+ ? _jsx("img", { src: subject.imageUrl, alt: "" })
49
+ : _jsx("span", { className: "uhcp-subject-identity-avatar", "aria-hidden": "true", children: initial }), _jsxs("div", { children: [_jsx("small", { children: subject.kind }), _jsx("h3", { children: subject.displayName })] }), canEdit && onEdit && editLabel ? _jsx("button", { type: "button", onClick: onEdit, children: editLabel }) : null] }), _jsx("dl", { children: subject.facts.map(fact => _jsxs("div", { children: [_jsx("dt", { children: fact.label }), _jsx("dd", { children: fact.value })] }, `${fact.label}:${fact.value}`)) }), relationship ? _jsxs("section", { className: "uhcp-subject-identity-relationship", children: [_jsx("span", { children: relationship.label }), _jsx("strong", { children: relationship.displayName }), _jsx("small", { className: `uhcp-identity-status uhcp-identity-status-${relationship.status}`, children: statusLabels[relationship.status] })] }) : null] });
50
+ }
51
+ function StepNumber({ value }) {
52
+ return _jsx("span", { className: "uhcp-identity-step-number", "aria-hidden": "true", children: value });
53
+ }
54
+ function requiredText(form, name) {
55
+ const value = form.get(name);
56
+ if (typeof value !== 'string' || !value.trim())
57
+ throw new Error(`animal_identity_${name}_required`);
58
+ return value.trim();
59
+ }
60
+ function optionalText(form, name) {
61
+ const value = form.get(name);
62
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
63
+ }
64
+ function requiredFile(form, name) {
65
+ const input = form.elements.namedItem(name);
66
+ const value = input instanceof HTMLInputElement ? input.files?.[0] : undefined;
67
+ if (!value || value.size < 1)
68
+ throw new Error(`animal_identity_${name}_required`);
69
+ return value;
70
+ }
@@ -0,0 +1,9 @@
1
+ export type ClinicalActionKind = 'add' | 'edit' | 'delete';
2
+ /** Compact clinical action; authorization and callback behavior remain host-owned. */
3
+ export declare function ClinicalActionButton({ kind, label, disabled, onClick }: Readonly<{
4
+ kind: ClinicalActionKind;
5
+ label: string;
6
+ disabled?: boolean;
7
+ onClick: () => void;
8
+ }>): import("react").JSX.Element;
9
+ //# sourceMappingURL=ClinicalActionButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClinicalActionButton.d.ts","sourceRoot":"","sources":["../src/ClinicalActionButton.tsx"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE1D,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAgB,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC;IACxF,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAC,+BASD"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /** Compact clinical action; authorization and callback behavior remain host-owned. */
3
+ export function ClinicalActionButton({ kind, label, disabled = false, onClick }) {
4
+ return _jsx("button", { type: "button", className: `uhcp-clinical-icon-action uhcp-clinical-icon-action-${kind}`, "aria-label": label, title: label, disabled: disabled, onClick: onClick, children: _jsx(ActionIcon, { kind: kind }) });
5
+ }
6
+ function ActionIcon({ kind }) {
7
+ if (kind === 'add')
8
+ return _jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "M12 5v14M5 12h14" }) });
9
+ if (kind === 'delete')
10
+ return _jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "M4 7h16m-10 4v6m4-6v6M9 7l1-3h4l1 3m3 0-1 14H7L6 7" }) });
11
+ return _jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "m4 20 4.2-1 10.9-10.9a2.1 2.1 0 0 0-3-3L5.2 16 4 20Zm10.7-13.5 3 3" }) });
12
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ClinicalArtifactEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditor.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClinicalArtifactEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditor.tsx"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useId, useMemo, useRef, useState } from 'react';
4
4
  import { clinicalArtifactEditorClaimsFromFhirR4, clinicalArtifactFhirR4ToFlat, composeFhirDateTimeFromLocalParts, splitFhirDateTimeForInput, } from 'fhir-data-utils-ts';
5
5
  import { buildMultichannelOperationBundle, MultichannelOperationMode, readMultichannelOperationFromBundle, selectMultichannelOperationClaimValues, } from 'sos-data-utils-ts/multichannel-operation-schemas';
6
+ import { ClinicalEditorLayer } from './ClinicalEditorLayer.js';
6
7
  /**
7
8
  * Shared human/animal clinical editor. The host owns authorization, transport,
8
9
  * persistence and terminology service access. A successful form submission is
@@ -125,27 +126,27 @@ export function ClinicalArtifactEditor({ request, schema, operationSchema, autho
125
126
  setSaving(false);
126
127
  }
127
128
  }
128
- return _jsxs("section", { className: "uhcp-clinical-editor", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descriptionId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsx("p", { id: descriptionId, children: copy.description })] }), _jsx("button", { type: "button", onClick: onCancel, "aria-label": copy.close, children: "\u00D7" })] }), _jsxs("form", { onSubmit: (event) => { event.preventDefault(); void submit(); }, children: [fields.map((claim) => {
129
- const parameter = claim.slice(request.resourceType.length + 1);
130
- const label = fieldLabel(claim);
131
- const terminologyEnabled = Boolean(searchTerminology && terminologyCodeClaim(request.resourceType, claim));
132
- const inputId = `${titleId}-${claim}`;
133
- const value = claims[claim] ?? '';
134
- const schemaNode = operationSchema?.properties.claims?.properties?.[claim];
135
- const update = (event) => {
136
- setClaims((current) => ({ ...current, [claim]: event.target.value }));
137
- if (terminologyEnabled)
138
- setActiveTerminologyClaim(claim);
139
- };
140
- if (isDateTimeSchemaNode(schemaNode))
141
- return _jsx(ClinicalDateTimeClaimField, { label: label, required: requiredClaims.has(claim), value: value, timeZone: timeZone, labels: copy.dateTime ?? DEFAULT_DATE_TIME_LABELS, onChange: (nextValue) => setClaims((current) => ({ ...current, [claim]: nextValue })) }, claim);
142
- return _jsxs("label", { className: isMultiline(parameter) ? 'uhcp-clinical-editor-wide' : undefined, htmlFor: inputId, children: [_jsxs("span", { children: [label, requiredClaims.has(claim) ? ' *' : ''] }), statusOptions(request.resourceType, parameter) ? _jsxs("select", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), onChange: update, children: [!requiredClaims.has(claim) ? _jsx("option", { value: "" }) : null, statusOptions(request.resourceType, parameter).map((option) => _jsx("option", { value: option, children: humanize(option) }, option))] }) : isMultiline(parameter) ? _jsx("textarea", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), rows: 3, onChange: update })
143
- : _jsx("input", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), type: fieldInputType(parameter, operationSchema?.properties.claims?.properties?.[claim]), onChange: update }), terminologyEnabled && activeTerminologyClaim === claim ? _jsxs("div", { className: "uhcp-terminology-results", children: [terminologyBusy ? _jsx("small", { role: "status", children: copy.terminologyLoading }) : null, terminologyError ? _jsx("small", { role: "alert", children: copy.terminologyUnavailable }) : null, candidates.length ? _jsx("ul", { children: candidates.map((candidate) => _jsx("li", { children: _jsxs("button", { type: "button", onClick: () => {
144
- setClaims((current) => selectedCodingClaims(request.resourceType, claim, candidate, acceptedClaims, current));
145
- setCandidates([]);
146
- setActiveTerminologyClaim(undefined);
147
- }, children: [candidate.display, _jsxs("small", { children: [candidate.system, " \u00B7 ", candidate.code] })] }) }, `${candidate.system}|${candidate.code}`)) }) : null] }) : null] }, claim);
148
- }), error ? _jsx("p", { className: "uhcp-clinical-editor-error", role: "alert", children: error }) : null, pending ? _jsx("p", { className: "uhcp-clinical-editor-pending", role: "status", children: copy.pending || pending }) : null, _jsxs("footer", { children: [_jsx("button", { type: "button", onClick: onCancel, children: copy.cancel }), _jsx("button", { type: "submit", disabled: saving, children: saving ? copy.saving : pending ? (copy.retry || copy.save) : copy.save })] })] })] });
129
+ return _jsx(ClinicalEditorLayer, { onDismiss: onCancel, children: _jsxs("section", { className: "uhcp-clinical-editor", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descriptionId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsx("p", { id: descriptionId, children: copy.description })] }), _jsx("button", { type: "button", onClick: onCancel, "aria-label": copy.close, children: "\u00D7" })] }), _jsxs("form", { onSubmit: (event) => { event.preventDefault(); void submit(); }, children: [fields.map((claim) => {
130
+ const parameter = claim.slice(request.resourceType.length + 1);
131
+ const label = fieldLabel(claim);
132
+ const terminologyEnabled = Boolean(searchTerminology && terminologyCodeClaim(request.resourceType, claim));
133
+ const inputId = `${titleId}-${claim}`;
134
+ const value = claims[claim] ?? '';
135
+ const schemaNode = operationSchema?.properties.claims?.properties?.[claim];
136
+ const update = (event) => {
137
+ setClaims((current) => ({ ...current, [claim]: event.target.value }));
138
+ if (terminologyEnabled)
139
+ setActiveTerminologyClaim(claim);
140
+ };
141
+ if (isDateTimeSchemaNode(schemaNode))
142
+ return _jsx(ClinicalDateTimeClaimField, { label: label, required: requiredClaims.has(claim), value: value, timeZone: timeZone, labels: copy.dateTime ?? DEFAULT_DATE_TIME_LABELS, onChange: (nextValue) => setClaims((current) => ({ ...current, [claim]: nextValue })) }, claim);
143
+ return _jsxs("label", { className: isMultiline(parameter) ? 'uhcp-clinical-editor-wide' : undefined, htmlFor: inputId, children: [_jsxs("span", { children: [label, requiredClaims.has(claim) ? ' *' : ''] }), statusOptions(request.resourceType, parameter) ? _jsxs("select", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), onChange: update, children: [!requiredClaims.has(claim) ? _jsx("option", { value: "" }) : null, statusOptions(request.resourceType, parameter).map((option) => _jsx("option", { value: option, children: humanize(option) }, option))] }) : isMultiline(parameter) ? _jsx("textarea", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), rows: 3, onChange: update })
144
+ : _jsx("input", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), type: fieldInputType(parameter, operationSchema?.properties.claims?.properties?.[claim]), onChange: update }), terminologyEnabled && activeTerminologyClaim === claim ? _jsxs("div", { className: "uhcp-terminology-results", children: [terminologyBusy ? _jsx("small", { role: "status", children: copy.terminologyLoading }) : null, terminologyError ? _jsx("small", { role: "alert", children: copy.terminologyUnavailable }) : null, candidates.length ? _jsx("ul", { children: candidates.map((candidate) => _jsx("li", { children: _jsxs("button", { type: "button", onClick: () => {
145
+ setClaims((current) => selectedCodingClaims(request.resourceType, claim, candidate, acceptedClaims, current));
146
+ setCandidates([]);
147
+ setActiveTerminologyClaim(undefined);
148
+ }, children: [candidate.display, _jsxs("small", { children: [candidate.system, " \u00B7 ", candidate.code] })] }) }, `${candidate.system}|${candidate.code}`)) }) : null] }) : null] }, claim);
149
+ }), error ? _jsx("p", { className: "uhcp-clinical-editor-error", role: "alert", children: error }) : null, pending ? _jsx("p", { className: "uhcp-clinical-editor-pending", role: "status", children: copy.pending || pending }) : null, _jsxs("footer", { children: [_jsx("button", { type: "button", onClick: onCancel, children: copy.cancel }), _jsx("button", { type: "submit", disabled: saving, children: saving ? copy.saving : pending ? (copy.retry || copy.save) : copy.save })] })] })] }) });
149
150
  }
150
151
  const DEFAULT_DATE_TIME_LABELS = Object.freeze({
151
152
  date: 'Date',
@@ -0,0 +1,8 @@
1
+ import type { ReactNode } from 'react';
2
+ export type ClinicalEditorLayerProps = Readonly<{
3
+ children: ReactNode;
4
+ onDismiss: () => void;
5
+ }>;
6
+ /** Places clinical editors above the complete portal shell, including sticky headers and menus. */
7
+ export declare function ClinicalEditorLayer({ children, onDismiss }: ClinicalEditorLayerProps): import("react").JSX.Element;
8
+ //# sourceMappingURL=ClinicalEditorLayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClinicalEditorLayer.d.ts","sourceRoot":"","sources":["../src/ClinicalEditorLayer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB,CAAC,CAAA;AAEF,mGAAmG;AACnG,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,wBAAwB,+BASpF"}
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createPortal } from 'react-dom';
4
+ /** Places clinical editors above the complete portal shell, including sticky headers and menus. */
5
+ export function ClinicalEditorLayer({ children, onDismiss }) {
6
+ const layer = _jsx("div", { className: "uhcp-clinical-editor-backdrop", onMouseDown: (event) => {
7
+ if (event.currentTarget === event.target)
8
+ onDismiss();
9
+ }, children: children });
10
+ return typeof document === 'undefined' ? layer : createPortal(layer, document.body);
11
+ }
@@ -9,6 +9,8 @@ export type ClinicalSummaryCard = Readonly<{
9
9
  value: string;
10
10
  unit?: string;
11
11
  }>[];
12
+ /** Actions belonging to this resource, rendered inside its card. */
13
+ actions?: ReactNode;
12
14
  }>;
13
15
  export type ClinicalSectionSummaryProps = Readonly<{
14
16
  code: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ClinicalSectionSummary.d.ts","sourceRoot":"","sources":["../src/ClinicalSectionSummary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,SAAS,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAA;CAC/E,CAAC,CAAA;AAEF,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAA;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACpD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oFAAoF;IACpF,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAC,CAAA;AAEF;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,iBAAkD,EAClD,OAAO,EACP,MAAa,EACb,QAAQ,EACR,UAAiB,GAClB,EAAE,2BAA2B,+BAiC7B"}
1
+ {"version":3,"file":"ClinicalSectionSummary.d.ts","sourceRoot":"","sources":["../src/ClinicalSectionSummary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,SAAS,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAA;IAC9E,oEAAoE;IACpE,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB,CAAC,CAAA;AAEF,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAA;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACpD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oFAAoF;IACpF,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAC,CAAA;AAEF;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EACJ,KAAK,EACL,SAAS,EACT,UAAU,EACV,iBAAkD,EAClD,OAAO,EACP,MAAa,EACb,QAAQ,EACR,UAAiB,GAClB,EAAE,2BAA2B,+BAkC7B"}
@@ -11,7 +11,7 @@ import { formatFhirTemporalForLocale } from 'fhir-data-utils-ts/fhir-temporal-pr
11
11
  export function ClinicalSectionSummary({ code, title, resources, emptyLabel, resourceTypeLabel = (resourceType) => resourceType, actions, locale = 'en', timeZone, showHeader = true, }) {
12
12
  return (_jsxs("section", { className: "uhcp-clinical-section", "data-ips-section": code, ...(showHeader ? { 'aria-labelledby': `uhcp-section-${code}` } : { 'aria-label': title }), children: [showHeader && (_jsxs("header", { children: [_jsxs("h3", { id: `uhcp-section-${code}`, children: [title, " ", _jsxs("span", { children: ["(", resources.length, ")"] })] }), actions] })), resources.length === 0
13
13
  ? _jsx("p", { className: "uhcp-clinical-empty", children: emptyLabel })
14
- : (_jsx("div", { className: "uhcp-clinical-grid", children: resources.map((resource) => (_jsxs("article", { className: "uhcp-clinical-card", "data-resource-type": resource.resourceType, children: [_jsx("p", { className: "uhcp-clinical-title", dir: "auto", children: _jsx("bdi", { children: resource.title }) }), _jsx("p", { className: "uhcp-clinical-type", children: resourceTypeLabel(resource.resourceType) }), resource.date && _jsx("p", { className: "uhcp-clinical-date", children: _jsx("time", { dateTime: resource.date, children: localizedTemporal(resource.date, locale, timeZone) }) }), resource.details?.length ? _jsx("dl", { className: "uhcp-clinical-details", children: resource.details.map((detail) => _jsxs("div", { children: [_jsx("dt", { children: detail.label }), _jsxs("dd", { children: [detail.value, detail.unit ? ` ${detail.unit}` : ''] })] }, `${detail.label}:${detail.value}:${detail.unit ?? ''}`)) }) : null] }, resource.key))) }))] }));
14
+ : (_jsx("div", { className: "uhcp-clinical-grid", children: resources.map((resource) => (_jsxs("article", { className: "uhcp-clinical-card", "data-resource-type": resource.resourceType, children: [_jsx("p", { className: "uhcp-clinical-title", dir: "auto", children: _jsx("bdi", { children: resource.title }) }), _jsx("p", { className: "uhcp-clinical-type", children: resourceTypeLabel(resource.resourceType) }), resource.date && _jsx("p", { className: "uhcp-clinical-date", children: _jsx("time", { dateTime: resource.date, children: localizedTemporal(resource.date, locale, timeZone) }) }), resource.details?.length ? _jsx("dl", { className: "uhcp-clinical-details", children: resource.details.map((detail) => _jsxs("div", { children: [_jsx("dt", { children: detail.label }), _jsxs("dd", { children: [detail.value, detail.unit ? ` ${detail.unit}` : ''] })] }, `${detail.label}:${detail.value}:${detail.unit ?? ''}`)) }) : null, resource.actions ? _jsx("div", { className: "uhcp-clinical-card-actions", children: resource.actions }) : null] }, resource.key))) }))] }));
15
15
  }
16
16
  function localizedTemporal(value, locale, timeZone) {
17
17
  try {
@@ -0,0 +1,27 @@
1
+ export type EmergencyTaskIcon = 'contact' | 'journey' | 'health' | 'scan';
2
+ export type EmergencyTaskItem = Readonly<{
3
+ id: string;
4
+ icon: EmergencyTaskIcon;
5
+ title: string;
6
+ description: string;
7
+ actionLabel: string;
8
+ href?: string;
9
+ status?: string;
10
+ }>;
11
+ export type EmergencyTaskHubCopy = Readonly<{
12
+ title: string;
13
+ description?: string;
14
+ unavailable: string;
15
+ }>;
16
+ /**
17
+ * Brand-neutral, task-first entry to the three SOSChain emergency workflows.
18
+ * Hosts resolve every href and status from server-authorized capabilities.
19
+ * Rendering an action never grants subject, clinical or communication access.
20
+ */
21
+ export declare function EmergencyTaskHub({ copy, tasks, layout, headingLevel }: Readonly<{
22
+ copy: EmergencyTaskHubCopy;
23
+ tasks: readonly EmergencyTaskItem[];
24
+ layout?: 'list' | 'grid';
25
+ headingLevel?: 1 | 2;
26
+ }>): import("react").JSX.Element;
27
+ //# sourceMappingURL=EmergencyTaskHub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmergencyTaskHub.d.ts","sourceRoot":"","sources":["../src/EmergencyTaskHub.tsx"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAA;AAEzE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,iBAAiB,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAe,EAAE,YAAgB,EAAE,EAAE,QAAQ,CAAC;IAC5F,IAAI,EAAE,oBAAoB,CAAA;IAC1B,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAA;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;CACrB,CAAC,+BAqBD"}
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Brand-neutral, task-first entry to the three SOSChain emergency workflows.
4
+ * Hosts resolve every href and status from server-authorized capabilities.
5
+ * Rendering an action never grants subject, clinical or communication access.
6
+ */
7
+ export function EmergencyTaskHub({ copy, tasks, layout = 'list', headingLevel = 2 }) {
8
+ const Heading = headingLevel === 1 ? 'h1' : 'h2';
9
+ return _jsxs("section", { className: `uhcp-emergency-task-hub${layout === 'grid' ? ' uhcp-emergency-task-hub-grid' : ''}`, "aria-labelledby": "emergency-task-hub-title", children: [_jsxs("header", { children: [_jsx(Heading, { id: "emergency-task-hub-title", children: copy.title }), copy.description ? _jsx("p", { children: copy.description }) : null] }), _jsx("div", { className: "uhcp-emergency-task-list", children: tasks.map((task) => _jsxs("article", { "data-emergency-task": task.id, children: [_jsx("span", { className: `uhcp-emergency-task-icon uhcp-emergency-task-icon-${task.icon}`, "aria-hidden": "true", children: _jsx(TaskIcon, { icon: task.icon }) }), _jsxs("div", { className: "uhcp-emergency-task-copy", children: [_jsx("h3", { children: task.title }), _jsx("p", { children: task.description }), task.status ? _jsx("small", { children: task.status }) : null] }), task.href
10
+ ? _jsxs("a", { href: task.href, children: [task.actionLabel, _jsx(ArrowIcon, {})] })
11
+ : _jsx("span", { className: "uhcp-emergency-task-unavailable", children: copy.unavailable })] }, task.id)) })] });
12
+ }
13
+ function TaskIcon({ icon }) {
14
+ if (icon === 'contact')
15
+ return _jsx("svg", { viewBox: "0 0 24 24", children: _jsx("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm8-1 2 2 3-4" }) });
16
+ if (icon === 'journey')
17
+ return _jsxs("svg", { viewBox: "0 0 24 24", children: [_jsx("circle", { cx: "6", cy: "18", r: "2" }), _jsx("circle", { cx: "18", cy: "6", r: "2" }), _jsx("path", { d: "M8 18h3a3 3 0 0 0 3-3v-6a3 3 0 0 1 3-3" })] });
18
+ if (icon === 'scan')
19
+ return _jsx("svg", { viewBox: "0 0 24 24", children: _jsx("path", { d: "M8 3H5a2 2 0 0 0-2 2v3m13-5h3a2 2 0 0 1 2 2v3M8 21H5a2 2 0 0 1-2-2v-3m13 5h3a2 2 0 0 0 2-2v-3M7 12h10" }) });
20
+ return _jsx("svg", { viewBox: "0 0 24 24", children: _jsx("path", { d: "M9 3h6v3h3v15H6V6h3V3Zm0 8h6m-6 4h6" }) });
21
+ }
22
+ function ArrowIcon() {
23
+ return _jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: _jsx("path", { d: "m9 5 7 7-7 7" }) });
24
+ }
@@ -11,6 +11,8 @@ export type IpsBundleSummaryProps = Readonly<{
11
11
  sectionTitle?: (section: ClinicalSectionView) => string;
12
12
  resourceTypeLabel?: (resourceType: string) => string;
13
13
  sectionActions?: (section: ClinicalSectionView) => ReactNode;
14
+ /** Resource-owned actions such as edit or delete, rendered inside that resource card. */
15
+ resourceActions?: (section: ClinicalSectionView, resource: ClinicalSectionView['resources'][number]) => ReactNode;
14
16
  timeline?: Readonly<{
15
17
  labels: ClinicalTimelineLabels;
16
18
  sectionFacetLabel: string;
@@ -26,5 +28,5 @@ export type IpsBundleSummaryProps = Readonly<{
26
28
  * native FHIR fields or canonical `resource.meta.claims` provide card content.
27
29
  * This component performs no ingestion, persistence or GW call.
28
30
  */
29
- export declare function IpsBundleSummary({ bundle, locale, timeZone, translateCode, emptyLabel, noSectionsLabel, sectionTitle, resourceTypeLabel, sectionActions, timeline, }: IpsBundleSummaryProps): import("react").JSX.Element;
31
+ export declare function IpsBundleSummary({ bundle, locale, timeZone, translateCode, emptyLabel, noSectionsLabel, sectionTitle, resourceTypeLabel, sectionActions, resourceActions, timeline, }: IpsBundleSummaryProps): import("react").JSX.Element;
30
32
  //# sourceMappingURL=IpsBundleSummary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IpsBundleSummary.d.ts","sourceRoot":"","sources":["../src/IpsBundleSummary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,mCAAmC,EACzC,MAAM,kDAAkD,CAAA;AAEzD,OAAO,EAAgD,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAEjH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,0BAA0B,CAAA;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,mCAAmC,KAAK,MAAM,GAAG,SAAS,CAAA;IAClF,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,MAAM,CAAA;IACvD,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACpD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,SAAS,CAAA;IAC5D,QAAQ,CAAC,EAAE,QAAQ,CAAC;QAClB,MAAM,EAAE,sBAAsB,CAAA;QAC9B,iBAAiB,EAAE,MAAM,CAAA;QACzB,sBAAsB,EAAE,MAAM,CAAA;KAC/B,CAAC,CAAA;CACH,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,aAAa,EACb,UAAU,EACV,eAA4B,EAC5B,YAAyC,EACzC,iBAAiB,EACjB,cAAc,EACd,QAAQ,GACT,EAAE,qBAAqB,+BAoEvB"}
1
+ {"version":3,"file":"IpsBundleSummary.d.ts","sourceRoot":"","sources":["../src/IpsBundleSummary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,mCAAmC,EACzC,MAAM,kDAAkD,CAAA;AAEzD,OAAO,EAAgD,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAEjH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,0BAA0B,CAAA;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,mCAAmC,KAAK,MAAM,GAAG,SAAS,CAAA;IAClF,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,MAAM,CAAA;IACvD,iBAAiB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAA;IACpD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,SAAS,CAAA;IAC5D,yFAAyF;IACzF,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,mBAAmB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,SAAS,CAAA;IACjH,QAAQ,CAAC,EAAE,QAAQ,CAAC;QAClB,MAAM,EAAE,sBAAsB,CAAA;QAC9B,iBAAiB,EAAE,MAAM,CAAA;QACzB,sBAAsB,EAAE,MAAM,CAAA;KAC/B,CAAC,CAAA;CACH,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,aAAa,EACb,UAAU,EACV,eAA4B,EAC5B,YAAyC,EACzC,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,QAAQ,GACT,EAAE,qBAAqB,+BAqEvB"}
@@ -11,7 +11,7 @@ import { ClinicalTimeline } from './ClinicalTimeline.js';
11
11
  * native FHIR fields or canonical `resource.meta.claims` provide card content.
12
12
  * This component performs no ingestion, persistence or GW call.
13
13
  */
14
- export function IpsBundleSummary({ bundle, locale, timeZone, translateCode, emptyLabel, noSectionsLabel = emptyLabel, sectionTitle = (section) => section.title, resourceTypeLabel, sectionActions, timeline, }) {
14
+ export function IpsBundleSummary({ bundle, locale, timeZone, translateCode, emptyLabel, noSectionsLabel = emptyLabel, sectionTitle = (section) => section.title, resourceTypeLabel, sectionActions, resourceActions, timeline, }) {
15
15
  const sections = toClinicalSectionViews(bundle, { locale, translateCode });
16
16
  const nativeResources = new Map((bundle.entry ?? bundle.data ?? []).flatMap((entry) => entry.fullUrl && entry.resource ? [[entry.fullUrl, entry.resource]] : []));
17
17
  if (sections.length === 0) {
@@ -48,6 +48,7 @@ export function IpsBundleSummary({ bundle, locale, timeZone, translateCode, empt
48
48
  resourceType: resource.resourceType,
49
49
  date: resource.date,
50
50
  details: observationComponentDetails(nativeResources.get(resource.fullUrl ?? '')),
51
+ actions: resourceActions?.(section, resource),
51
52
  })), emptyLabel: emptyLabel, resourceTypeLabel: resourceTypeLabel, actions: sectionActions?.(section), locale: locale, timeZone: timeZone }, section.code ?? `${section.title}:${sectionIndex}`)))] }));
52
53
  }
53
54
  function uniqueOptions(options) {
@@ -92,6 +92,15 @@ export type SoschainWorkspaceProps = Readonly<{
92
92
  addPlaceHref?: string;
93
93
  addProductHref?: string;
94
94
  importCardHref?: string;
95
+ /** Host-composed primary workflows for the selected subject overview. */
96
+ overviewContent?: ReactNode;
97
+ /** Areas kept visible; remaining areas move into the accessible More menu. */
98
+ primaryAreas?: readonly SoschainWorkspaceArea[];
99
+ moreLabel?: string;
100
+ /** Raw provider identifiers are hidden by SOSChain portals by default. */
101
+ showCardIdentifier?: boolean;
102
+ /** Selects a card in host-owned state without exposing its identifier in a URL. */
103
+ onSelectCard?: (identifier: string) => void;
95
104
  }>;
96
105
  /**
97
106
  * Shared subject-first SOSChain workspace for personal and professional apps.
@@ -100,5 +109,5 @@ export type SoschainWorkspaceProps = Readonly<{
100
109
  * communications. This presentational component never derives authority from
101
110
  * a selected role, card, tab or browser-controlled value.
102
111
  */
103
- export declare function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, healthSummary, clinicalReadOnly, careJourney, emergencyData, canManageAssociations, addPlaceHref, addProductHref, importCardHref, }: SoschainWorkspaceProps): import("react").JSX.Element;
112
+ export declare function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, healthSummary, clinicalReadOnly, careJourney, emergencyData, canManageAssociations, addPlaceHref, addProductHref, importCardHref, overviewContent, primaryAreas, moreLabel, showCardIdentifier, onSelectCard, }: SoschainWorkspaceProps): import("react").JSX.Element;
104
113
  //# sourceMappingURL=SoschainWorkspace.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SoschainWorkspace.d.ts","sourceRoot":"","sources":["../src/SoschainWorkspace.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SoschainWorkspace.d.ts","sourceRoot":"","sources":["../src/SoschainWorkspace.tsx"],"names":[],"mappings":"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"}
@@ -21,9 +21,9 @@ function AssociationList({ items, empty }) {
21
21
  * communications. This presentational component never derives authority from
22
22
  * a selected role, card, tab or browser-controlled value.
23
23
  */
24
- export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, healthSummary, clinicalReadOnly = true, careJourney = [], emergencyData = [], canManageAssociations, addPlaceHref, addProductHref, importCardHref, }) {
24
+ export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, healthSummary, clinicalReadOnly = true, careJourney = [], emergencyData = [], canManageAssociations, addPlaceHref, addProductHref, importCardHref, overviewContent, primaryAreas, moreLabel = 'More', showCardIdentifier = true, onSelectCard, }) {
25
25
  if (!selectedCard) {
26
- return (_jsxs("section", { className: "uhcp-sos-wrap", "aria-labelledby": "sos-card-picker-title", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.workspaceEyebrow }), _jsx("h1", { id: "sos-card-picker-title", children: copy.cardsTitle }), _jsx("p", { children: copy.cardsDescription }), importCardHref && copy.importCard ? _jsxs("a", { href: importCardHref, children: [copy.importCard, " \u2192"] }) : null] }), cards.length === 0 ? (_jsxs("div", { className: "uhcp-sos-empty-panel", children: [_jsx("h2", { children: copy.noCardTitle }), _jsx("p", { children: copy.noCardBody })] })) : (_jsx("ul", { className: "uhcp-sos-card-grid", children: cards.map((card) => (_jsx("li", { children: _jsxs("a", { href: card.openHref, children: [_jsx("span", { children: card.kindLabel }), _jsx("strong", { children: card.displayName }), _jsx("small", { children: card.identifier }), _jsxs("b", { children: [copy.openCard, " \u2192"] })] }) }, card.identifier))) }))] }));
26
+ return (_jsxs("section", { className: "uhcp-sos-wrap", "aria-labelledby": "sos-card-picker-title", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.workspaceEyebrow }), _jsx("h1", { id: "sos-card-picker-title", children: copy.cardsTitle }), _jsx("p", { children: copy.cardsDescription }), importCardHref && copy.importCard ? _jsxs("a", { href: importCardHref, children: [copy.importCard, " \u2192"] }) : null] }), cards.length === 0 ? (_jsxs("div", { className: "uhcp-sos-empty-panel", children: [_jsx("h2", { children: copy.noCardTitle }), _jsx("p", { children: copy.noCardBody })] })) : (_jsx("ul", { className: "uhcp-sos-card-grid", children: cards.map((card) => (_jsx("li", { children: onSelectCard ? _jsxs("button", { type: "button", onClick: () => onSelectCard(card.identifier), children: [_jsx("span", { children: card.kindLabel }), _jsx("strong", { children: card.displayName }), showCardIdentifier ? _jsx("small", { children: card.identifier }) : null, _jsxs("b", { children: [copy.openCard, " \u2192"] })] }) : _jsxs("a", { href: card.openHref, children: [_jsx("span", { children: card.kindLabel }), _jsx("strong", { children: card.displayName }), showCardIdentifier ? _jsx("small", { children: card.identifier }) : null, _jsxs("b", { children: [copy.openCard, " \u2192"] })] }) }, card.identifier))) }))] }));
27
27
  }
28
28
  const title = activeArea === 'places'
29
29
  ? copy.placesTitle
@@ -53,5 +53,5 @@ export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaH
53
53
  : copy.overviewBody;
54
54
  const clinicalAreaIsReadOnly = activeArea === 'care-journey' || (activeArea === 'health-summary' && clinicalReadOnly);
55
55
  const associationAreaIsReadOnly = !canManageAssociations && (activeArea === 'overview' || activeArea === 'places' || activeArea === 'products');
56
- return (_jsxs("section", { className: "uhcp-sos-wrap", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.selectedCard }), _jsx("h1", { children: selectedCard.displayName }), _jsxs("p", { children: [selectedCard.kindLabel, " \u00B7 ", selectedCard.identifier] })] }), _jsx("nav", { className: "uhcp-sos-tabs", "aria-label": copy.workspaceEyebrow, children: SOSCHAIN_SUBJECT_WORKSPACE_AREAS.map((area) => (_jsx("a", { href: areaHrefs[area], "aria-current": activeArea === area ? 'page' : undefined, children: copy.areas[area] }, area))) }), _jsxs("div", { className: "uhcp-sos-panel", children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { children: title }), _jsx("p", { children: body })] }), (clinicalAreaIsReadOnly || associationAreaIsReadOnly) && (_jsx("span", { className: "uhcp-sos-readonly", children: copy.readOnly })), canManageAssociations && activeArea === 'places' && addPlaceHref && _jsx("a", { href: addPlaceHref, children: copy.addPlace }), canManageAssociations && activeArea === 'products' && addProductHref && _jsx("a", { href: addProductHref, children: copy.addProduct })] }), activeArea === 'overview' && (_jsxs("div", { className: "uhcp-sos-overview-grid", children: [_jsxs("article", { children: [_jsx("strong", { children: places.length }), _jsx("span", { children: copy.areas.places })] }), _jsxs("article", { children: [_jsx("strong", { children: products.length }), _jsx("span", { children: copy.areas.products })] }), _jsxs("article", { children: [_jsx("strong", { children: communications.length }), _jsx("span", { children: copy.areas.communications })] }), _jsxs("article", { children: [_jsx("strong", { children: careJourney.length }), _jsx("span", { children: copy.areas['care-journey'] })] })] })), activeArea === 'health-summary' && (healthSummary ?? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyHealthSummary })), activeArea === 'care-journey' && (careJourney.length === 0 ? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyCareJourney }) : (_jsx("ol", { className: "uhcp-sos-timeline uhcp-sos-care-journey", children: careJourney.map((encounter) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx("span", { children: encounter.statusLabel }), _jsx("time", { dateTime: encounter.periodStart, children: encounter.periodStart })] }), _jsx("strong", { children: encounter.serviceLabel }), encounter.detail ? _jsx("p", { children: encounter.detail }) : null, encounter.locationLabel || encounter.periodEnd ? _jsx("small", { children: [encounter.locationLabel, encounter.periodEnd].filter(Boolean).join(' · ') }) : null] }, encounter.identifier))) }))), activeArea === 'emergency-data' && _jsx(ProtectedIndexEmergencyData, { copy: copy.emergencyData, items: emergencyData }), activeArea === 'places' && _jsx(AssociationList, { items: places, empty: copy.emptyPlaces }), activeArea === 'products' && _jsx(AssociationList, { items: products, empty: copy.emptyProducts }), activeArea === 'communications' && (communications.length === 0 ? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyCommunications }) : (_jsx("ol", { className: "uhcp-sos-timeline", children: communications.map((message) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx("span", { children: message.categoryLabel }), _jsx("time", { children: message.occurredAt })] }), _jsx("strong", { children: message.subject }), _jsx("p", { children: message.body }), _jsxs("small", { children: [message.sender, message.placeLabel ? ` · ${message.placeLabel}` : ''] })] }, message.identifier))) })))] })] }));
56
+ return (_jsxs("section", { className: "uhcp-sos-wrap", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.selectedCard }), _jsx("h1", { children: selectedCard.displayName }), _jsxs("p", { children: [selectedCard.kindLabel, showCardIdentifier ? ` · ${selectedCard.identifier}` : ''] })] }), _jsxs("nav", { className: "uhcp-sos-tabs", "aria-label": copy.workspaceEyebrow, children: [(primaryAreas ?? SOSCHAIN_SUBJECT_WORKSPACE_AREAS).map((area) => (_jsx("a", { href: areaHrefs[area], "aria-current": activeArea === area ? 'page' : undefined, children: copy.areas[area] }, area))), primaryAreas ? _jsxs("details", { className: "uhcp-sos-more", children: [_jsx("summary", { children: moreLabel }), _jsx("div", { children: SOSCHAIN_SUBJECT_WORKSPACE_AREAS.filter((area) => !primaryAreas.includes(area)).map((area) => (_jsx("a", { href: areaHrefs[area], "aria-current": activeArea === area ? 'page' : undefined, children: copy.areas[area] }, area))) })] }) : null] }), _jsxs("div", { className: "uhcp-sos-panel", children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { children: title }), _jsx("p", { children: body })] }), (clinicalAreaIsReadOnly || associationAreaIsReadOnly) && (_jsx("span", { className: "uhcp-sos-readonly", children: copy.readOnly })), canManageAssociations && activeArea === 'places' && addPlaceHref && _jsx("a", { href: addPlaceHref, children: copy.addPlace }), canManageAssociations && activeArea === 'products' && addProductHref && _jsx("a", { href: addProductHref, children: copy.addProduct })] }), activeArea === 'overview' && (overviewContent ?? (_jsxs("div", { className: "uhcp-sos-overview-grid", children: [_jsxs("article", { children: [_jsx("strong", { children: places.length }), _jsx("span", { children: copy.areas.places })] }), _jsxs("article", { children: [_jsx("strong", { children: products.length }), _jsx("span", { children: copy.areas.products })] }), _jsxs("article", { children: [_jsx("strong", { children: communications.length }), _jsx("span", { children: copy.areas.communications })] }), _jsxs("article", { children: [_jsx("strong", { children: careJourney.length }), _jsx("span", { children: copy.areas['care-journey'] })] })] }))), activeArea === 'health-summary' && (healthSummary ?? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyHealthSummary })), activeArea === 'care-journey' && (careJourney.length === 0 ? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyCareJourney }) : (_jsx("ol", { className: "uhcp-sos-timeline uhcp-sos-care-journey", children: careJourney.map((encounter) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx("span", { children: encounter.statusLabel }), _jsx("time", { dateTime: encounter.periodStart, children: encounter.periodStart })] }), _jsx("strong", { children: encounter.serviceLabel }), encounter.detail ? _jsx("p", { children: encounter.detail }) : null, encounter.locationLabel || encounter.periodEnd ? _jsx("small", { children: [encounter.locationLabel, encounter.periodEnd].filter(Boolean).join(' · ') }) : null] }, encounter.identifier))) }))), activeArea === 'emergency-data' && _jsx(ProtectedIndexEmergencyData, { copy: copy.emergencyData, items: emergencyData }), activeArea === 'places' && _jsx(AssociationList, { items: places, empty: copy.emptyPlaces }), activeArea === 'products' && _jsx(AssociationList, { items: products, empty: copy.emptyProducts }), activeArea === 'communications' && (communications.length === 0 ? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyCommunications }) : (_jsx("ol", { className: "uhcp-sos-timeline", children: communications.map((message) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx("span", { children: message.categoryLabel }), _jsx("time", { children: message.occurredAt })] }), _jsx("strong", { children: message.subject }), _jsx("p", { children: message.body }), _jsxs("small", { children: [message.sender, message.placeLabel ? ` · ${message.placeLabel}` : ''] })] }, message.identifier))) })))] })] }));
57
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"VitalSignArtifactEditor.d.ts","sourceRoot":"","sources":["../src/VitalSignArtifactEditor.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kDAAkD,CAAA;AAClG,OAAO,EAA0B,KAAK,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAEhG,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,2BAA2B,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;AAEzE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,kBAAkB,CAAC,EAAE,oBAAoB,CAAA;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,2BAA2B,CAAA;IACjC,UAAU,EAAE,mBAAmB,CAAA;IAC/B,eAAe,EAAE,CAAC,WAAW,EAAE,oBAAoB,KAAK,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAAA;IACvG,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,UAAU,EAAE,CAAC,MAAM,EAAE,0BAA0B,KAAK,IAAI,CAAA;CACzD,CAAC,CAAA;AAWF,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACP,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,eAAe,EACf,QAAQ,EACR,UAAU,GACX,EAAE,4BAA4B,+BAoD9B"}
1
+ {"version":3,"file":"VitalSignArtifactEditor.d.ts","sourceRoot":"","sources":["../src/VitalSignArtifactEditor.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kDAAkD,CAAA;AAClG,OAAO,EAA0B,KAAK,2BAA2B,EAAE,MAAM,uBAAuB,CAAA;AAGhG,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,2BAA2B,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;AAEzE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,MAAM,CAAA;IACxB,kBAAkB,CAAC,EAAE,oBAAoB,CAAA;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,2BAA2B,CAAA;IACjC,UAAU,EAAE,mBAAmB,CAAA;IAC/B,eAAe,EAAE,CAAC,WAAW,EAAE,oBAAoB,KAAK,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAAA;IACvG,QAAQ,EAAE,MAAM,IAAI,CAAA;IACpB,UAAU,EAAE,CAAC,MAAM,EAAE,0BAA0B,KAAK,IAAI,CAAA;CACzD,CAAC,CAAA;AAWF,gFAAgF;AAChF,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACP,gBAAgB,EAChB,kBAAkB,EAClB,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,eAAe,EACf,QAAQ,EACR,UAAU,GACX,EAAE,4BAA4B,+BAoD9B"}
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import { useId, useState } from 'react';
4
4
  import { composeFhirDateTimeFromLocalParts, splitFhirDateTimeForInput, VitalSignUnit, } from 'fhir-data-utils-ts';
5
5
  import { ClinicalDateTimeFields } from './ClinicalTimeline.js';
6
+ import { ClinicalEditorLayer } from './ClinicalEditorLayer.js';
6
7
  const VITAL_SIGN_KINDS = Object.freeze([
7
8
  'blood-pressure',
8
9
  'temperature',
@@ -45,7 +46,7 @@ export function VitalSignArtifactEditor({ entryId, subjectReference, initialMeas
45
46
  setSaving(false);
46
47
  }
47
48
  }
48
- return _jsxs("section", { className: "uhcp-clinical-editor", lang: locale, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descriptionId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsx("p", { id: descriptionId, children: copy.description })] }), _jsx("button", { type: "button", onClick: onCancel, "aria-label": copy.close, children: "\u00D7" })] }), _jsxs("form", { onSubmit: (event) => { event.preventDefault(); void submit(); }, children: [_jsxs("label", { children: [_jsxs("span", { children: [copy.kind, " *"] }), _jsx("select", { "aria-label": copy.kind, value: kind, onChange: (event) => setKind(event.target.value), children: VITAL_SIGN_KINDS.map((option) => _jsx("option", { value: option, children: kindLabels[option] }, option)) })] }), _jsxs("fieldset", { className: "uhcp-clinical-editor-date-time", children: [_jsxs("legend", { children: [copy.measuredAt, " *"] }), _jsx(ClinicalDateTimeFields, { value: measuredAt, onChange: setMeasuredAt, labels: copy.dateTime, timeZone: timeZone })] }), kind === 'blood-pressure' ? _jsxs(_Fragment, { children: [_jsxs("label", { children: [_jsxs("span", { children: [copy.systolic, " *"] }), _jsx("input", { "aria-label": copy.systolic, required: true, type: "number", value: systolic, onChange: (event) => setSystolic(event.target.value) })] }), _jsxs("label", { children: [_jsxs("span", { children: [copy.diastolic, " *"] }), _jsx("input", { "aria-label": copy.diastolic, required: true, type: "number", value: diastolic, onChange: (event) => setDiastolic(event.target.value) })] })] }) : _jsxs("label", { children: [_jsxs("span", { children: [copy.value, " *"] }), _jsx("input", { "aria-label": copy.value, required: true, type: "number", value: value, onChange: (event) => setValue(event.target.value) })] }), error ? _jsx("p", { className: "uhcp-clinical-editor-error", role: "alert", children: error }) : null, _jsxs("footer", { children: [_jsx("button", { type: "button", onClick: onCancel, children: copy.cancel }), _jsx("button", { type: "submit", disabled: saving, children: saving ? copy.saving : copy.save })] })] })] });
49
+ return _jsx(ClinicalEditorLayer, { onDismiss: onCancel, children: _jsxs("section", { className: "uhcp-clinical-editor", lang: locale, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descriptionId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsx("p", { id: descriptionId, children: copy.description })] }), _jsx("button", { type: "button", onClick: onCancel, "aria-label": copy.close, children: "\u00D7" })] }), _jsxs("form", { onSubmit: (event) => { event.preventDefault(); void submit(); }, children: [_jsxs("label", { children: [_jsxs("span", { children: [copy.kind, " *"] }), _jsx("select", { "aria-label": copy.kind, value: kind, onChange: (event) => setKind(event.target.value), children: VITAL_SIGN_KINDS.map((option) => _jsx("option", { value: option, children: kindLabels[option] }, option)) })] }), _jsxs("fieldset", { className: "uhcp-clinical-editor-date-time", children: [_jsxs("legend", { children: [copy.measuredAt, " *"] }), _jsx(ClinicalDateTimeFields, { value: measuredAt, onChange: setMeasuredAt, labels: copy.dateTime, timeZone: timeZone })] }), kind === 'blood-pressure' ? _jsxs(_Fragment, { children: [_jsxs("label", { children: [_jsxs("span", { children: [copy.systolic, " *"] }), _jsx("input", { "aria-label": copy.systolic, required: true, type: "number", value: systolic, onChange: (event) => setSystolic(event.target.value) })] }), _jsxs("label", { children: [_jsxs("span", { children: [copy.diastolic, " *"] }), _jsx("input", { "aria-label": copy.diastolic, required: true, type: "number", value: diastolic, onChange: (event) => setDiastolic(event.target.value) })] })] }) : _jsxs("label", { children: [_jsxs("span", { children: [copy.value, " *"] }), _jsx("input", { "aria-label": copy.value, required: true, type: "number", value: value, onChange: (event) => setValue(event.target.value) })] }), error ? _jsx("p", { className: "uhcp-clinical-editor-error", role: "alert", children: error }) : null, _jsxs("footer", { children: [_jsx("button", { type: "button", onClick: onCancel, children: copy.cancel }), _jsx("button", { type: "submit", disabled: saving, children: saving ? copy.saving : copy.save })] })] })] }) });
49
50
  }
50
51
  function unitFor(kind) {
51
52
  switch (kind) {
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export * from './ClinicalDocumentEncounterExplorer.js';
12
12
  export * from './AllClinicalSections.js';
13
13
  export * from './ClinicalTimeline.js';
14
14
  export * from './ClinicalArtifactEditor.js';
15
+ export * from './ClinicalActionButton.js';
15
16
  export * from './VitalSignArtifactEditor.js';
16
17
  export * from './InvitationAcceptancePanel.js';
17
18
  export * from './SubjectAccessRequestPanel.js';
@@ -26,4 +27,6 @@ export * from './LegalMarkdownDocument.js';
26
27
  export * from './IdentityEvidenceWorkspace.js';
27
28
  export * from './IdentityEvidenceDocumentPanel.js';
28
29
  export * from './IdentityEvidenceDeclarationForm.js';
30
+ export * from './AnimalIdentityOnboarding.js';
31
+ export * from './EmergencyTaskHub.js';
29
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wCAAwC,CAAA;AACtD,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0CAA0C,CAAA;AACxD,cAAc,kCAAkC,CAAA;AAChD,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,sCAAsC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wCAAwC,CAAA;AACtD,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0CAA0C,CAAA;AACxD,cAAc,kCAAkC,CAAA;AAChD,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,sCAAsC,CAAA;AACpD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uBAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ export * from './ClinicalDocumentEncounterExplorer.js';
12
12
  export * from './AllClinicalSections.js';
13
13
  export * from './ClinicalTimeline.js';
14
14
  export * from './ClinicalArtifactEditor.js';
15
+ export * from './ClinicalActionButton.js';
15
16
  export * from './VitalSignArtifactEditor.js';
16
17
  export * from './InvitationAcceptancePanel.js';
17
18
  export * from './SubjectAccessRequestPanel.js';
@@ -26,3 +27,5 @@ export * from './LegalMarkdownDocument.js';
26
27
  export * from './IdentityEvidenceWorkspace.js';
27
28
  export * from './IdentityEvidenceDocumentPanel.js';
28
29
  export * from './IdentityEvidenceDeclarationForm.js';
30
+ export * from './AnimalIdentityOnboarding.js';
31
+ export * from './EmergencyTaskHub.js';
package/dist/styles.css CHANGED
@@ -171,13 +171,16 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
171
171
  color: var(--uhcp-text);
172
172
  padding: 1.25rem;
173
173
  }
174
- .uhcp-clinical-editor { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:1.5rem; box-shadow:0 20px 60px rgb(15 23 42 / 22%); color:var(--uhcp-text); display:flex; flex-direction:column; inset:50% auto auto 50%; max-height:calc(100dvh - 2rem); max-width:48rem; overflow:hidden; padding:1.5rem; position:fixed; transform:translate(-50%,-50%); width:calc(100% - 2rem); z-index:60; }
174
+ .uhcp-clinical-editor-backdrop { align-items:center; background:rgb(15 23 42 / 42%); display:flex; inset:0; justify-content:center; padding:1rem; position:fixed; z-index:1000; }
175
+ .uhcp-clinical-editor { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:1.5rem; box-shadow:0 20px 60px rgb(15 23 42 / 22%); color:var(--uhcp-text); display:flex; flex-direction:column; max-height:calc(100dvh - 2rem); max-width:48rem; min-width:0; overflow:hidden; padding:1.5rem; width:100%; }
175
176
  .uhcp-clinical-editor>header { align-items:flex-start; display:flex; gap:1rem; justify-content:space-between; }
176
177
  .uhcp-clinical-editor h2,.uhcp-clinical-editor p { margin:.2rem 0; }
177
178
  .uhcp-clinical-editor>header>button { background:transparent; border:1px solid var(--uhcp-border); border-radius:50%; color:inherit; cursor:pointer; font-size:1.4rem; height:2.5rem; width:2.5rem; }
178
- .uhcp-clinical-editor form { display:grid; gap:1rem; grid-template-columns:repeat(2,minmax(0,1fr)); margin-top:1.25rem; overflow:auto; }
179
+ .uhcp-clinical-editor form { display:grid; gap:1rem; grid-template-columns:repeat(2,minmax(0,1fr)); margin-top:1.25rem; min-width:0; overflow:auto; }
179
180
  .uhcp-clinical-editor label { color:var(--uhcp-text); display:grid; font-weight:700; gap:.35rem; }
180
- .uhcp-clinical-editor input,.uhcp-clinical-editor select,.uhcp-clinical-editor textarea { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.7rem; color:inherit; font:inherit; padding:.75rem; }
181
+ .uhcp-clinical-editor label,.uhcp-clinical-editor fieldset { min-width:0; }
182
+ .uhcp-clinical-editor input,.uhcp-clinical-editor select,.uhcp-clinical-editor textarea { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.7rem; color:inherit; font:inherit; min-width:0; padding:.75rem; width:100%; }
183
+ .uhcp-clinical-editor-date-time { grid-column:1/-1; }
181
184
  .uhcp-clinical-editor-wide,.uhcp-clinical-editor-error,.uhcp-clinical-editor footer { grid-column:1/-1; }
182
185
  .uhcp-clinical-editor footer { background:var(--uhcp-panel); bottom:0; display:flex; gap:.75rem; justify-content:flex-end; padding:.75rem 0; position:sticky; z-index:2; }
183
186
  .uhcp-clinical-editor footer button,.uhcp-terminology-results button { border:1px solid var(--uhcp-border); border-radius:.7rem; cursor:pointer; font:inherit; padding:.7rem 1rem; }
@@ -447,7 +450,14 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
447
450
  .uhcp-clinical-section h3 { font-size: 1.125rem; margin: 0; }
448
451
  .uhcp-clinical-section h3 span { color: var(--uhcp-muted); }
449
452
  .uhcp-clinical-grid { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); margin-top: 1rem; }
450
- .uhcp-clinical-card { background: var(--uhcp-panel-muted); border-radius: 1rem; padding: 1rem; }
453
+ .uhcp-clinical-card { background: var(--uhcp-panel-muted); border-radius: 1rem; display: flex; flex-direction: column; min-width: 0; padding: 1rem; }
454
+ .uhcp-clinical-card-actions { align-items: center; display: flex; gap: .4rem; justify-content: flex-end; margin-top: .75rem; }
455
+ .uhcp-clinical-icon-action { align-items:center; background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.65rem; color:var(--uhcp-text); cursor:pointer; display:inline-flex; height:2.5rem; justify-content:center; padding:0; width:2.5rem; }
456
+ .uhcp-clinical-icon-action:hover { border-color:var(--uhcp-turquoise); color:var(--uhcp-turquoise); }
457
+ .uhcp-clinical-icon-action:focus-visible { outline:3px solid var(--uhcp-turquoise); outline-offset:2px; }
458
+ .uhcp-clinical-icon-action:disabled { cursor:not-allowed; opacity:.42; }
459
+ .uhcp-clinical-icon-action svg { fill:none; height:1.2rem; stroke:currentColor; stroke-linecap:round; stroke-linejoin:round; stroke-width:1.8; width:1.2rem; }
460
+ .uhcp-clinical-icon-action-delete:hover { border-color:var(--uhcp-attention); color:var(--uhcp-attention); }
451
461
  .uhcp-clinical-title { font-weight: 800; margin: 0; }
452
462
  .uhcp-clinical-type { color: var(--uhcp-muted); font-size: .72rem; font-weight: 800; letter-spacing: .06em; margin: .35rem 0 0; text-transform: uppercase; }
453
463
  .uhcp-clinical-date, .uhcp-clinical-empty { color: var(--uhcp-muted); margin: .35rem 0 0; }
@@ -468,10 +478,10 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
468
478
  .uhcp-clinical-timeline-list { display: grid; gap: .5rem; margin: 0; padding-left: 1.5rem; }
469
479
  .uhcp-clinical-timeline-list li { padding: .5rem; }
470
480
  .uhcp-clinical-timeline-list time { display: block; margin-top: .2rem; }
471
- .uhcp-clinical-date-time-fields { align-items: end; display: grid; gap: .5rem; grid-template-columns: minmax(9rem, 1fr) auto minmax(7rem, .7fr) auto; }
481
+ .uhcp-clinical-date-time-fields { align-items: end; display: grid; gap: .5rem; grid-template-columns: minmax(0, 1fr) auto minmax(0, .7fr) auto; min-width: 0; }
472
482
  .uhcp-clinical-date-time-fields label { display: grid; font-weight: 800; gap: .35rem; }
473
- .uhcp-clinical-date-time-fields input { border: 1px solid var(--uhcp-border); border-radius: .7rem; color: var(--uhcp-text); font: inherit; padding: .65rem; }
474
- @media (max-width: 620px) { .uhcp-clinical-range, .uhcp-clinical-date-time-fields { grid-template-columns: 1fr auto; } }
483
+ .uhcp-clinical-date-time-fields input { border: 1px solid var(--uhcp-border); border-radius: .7rem; color: var(--uhcp-text); font: inherit; min-width: 0; padding: .65rem; width: 100%; }
484
+ @media (max-width: 620px) { .uhcp-clinical-range, .uhcp-clinical-date-time-fields { grid-template-columns: minmax(0, 1fr) auto; } .uhcp-clinical-editor form { grid-template-columns:minmax(0,1fr); } .uhcp-clinical-editor-date-time,.uhcp-clinical-editor-wide,.uhcp-clinical-editor-error,.uhcp-clinical-editor footer { grid-column:1; } }
475
485
  .uhcp-clinical-details { display: grid; gap: .3rem; margin: .6rem 0 0; }
476
486
  .uhcp-clinical-details div { align-items: baseline; display: flex; gap: .75rem; justify-content: space-between; }
477
487
  .uhcp-clinical-details dt { color: var(--uhcp-muted); font-size: .78rem; }
@@ -591,14 +601,15 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
591
601
  .uhcp-sos-heading h1 { font-size: clamp(2rem, 5vw, 3.75rem); letter-spacing: -.04em; margin: .45rem 0; }
592
602
  .uhcp-sos-heading p, .uhcp-sos-panel header p { color: var(--uhcp-muted); line-height: 1.6; margin: 0; }
593
603
  .uhcp-sos-card-grid, .uhcp-sos-entity-list { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); list-style: none; margin: 2rem 0 0; padding: 0; }
594
- .uhcp-sos-card-grid a, .uhcp-sos-entity-list li { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 1.5rem; color: var(--uhcp-text); display: grid; gap: .65rem; padding: 1.4rem; text-decoration: none; }
595
- .uhcp-sos-card-grid a:hover { border-color: var(--uhcp-turquoise); transform: translateY(-2px); }
596
- .uhcp-sos-card-grid a:focus-visible, .uhcp-sos-tabs a:focus-visible, .uhcp-sos-panel a:focus-visible { outline: 3px solid var(--uhcp-turquoise); outline-offset: 3px; }
604
+ .uhcp-sos-card-grid a, .uhcp-sos-card-grid button, .uhcp-sos-entity-list li { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 1.5rem; color: var(--uhcp-text); display: grid; font: inherit; gap: .65rem; padding: 1.4rem; text-align: left; text-decoration: none; width: 100%; }
605
+ .uhcp-sos-card-grid a:hover, .uhcp-sos-card-grid button:hover { border-color: var(--uhcp-turquoise); transform: translateY(-2px); }
606
+ .uhcp-sos-card-grid a:focus-visible, .uhcp-sos-card-grid button:focus-visible, .uhcp-sos-tabs a:focus-visible, .uhcp-sos-panel a:focus-visible { outline: 3px solid var(--uhcp-turquoise); outline-offset: 3px; }
597
607
  .uhcp-sos-card-grid span, .uhcp-sos-card-grid small, .uhcp-sos-entity-list span, .uhcp-sos-entity-list small { color: var(--uhcp-muted); }
598
608
  .uhcp-sos-card-grid b { color: var(--uhcp-turquoise); }
599
609
  .uhcp-sos-tabs { display: flex; gap: .5rem; margin: 2rem 0 1rem; overflow-x: auto; padding: .25rem; }
600
610
  .uhcp-sos-tabs a { border-radius: 999px; color: var(--uhcp-muted); font-weight: 800; padding: .75rem 1rem; text-decoration: none; white-space: nowrap; }
601
611
  .uhcp-sos-tabs a[aria-current='page'] { background: linear-gradient(135deg, var(--uhcp-action-start), var(--uhcp-action-end)); color: #fff; }
612
+ .uhcp-sos-more{margin-left:auto;position:relative}.uhcp-sos-more>summary{border:1px solid var(--uhcp-border);border-radius:999px;color:var(--uhcp-muted);cursor:pointer;font-weight:800;list-style:none;padding:.7rem 1rem}.uhcp-sos-more>summary::-webkit-details-marker{display:none}.uhcp-sos-more>div{background:var(--uhcp-panel);border:1px solid var(--uhcp-border);border-radius:1rem;box-shadow:0 18px 45px rgb(22 39 66 / 14%);display:grid;min-width:13rem;padding:.45rem;position:absolute;right:0;top:calc(100% + .4rem);z-index:12}.uhcp-sos-more>div a{border-radius:.65rem}
602
613
  .uhcp-sos-panel, .uhcp-sos-empty-panel { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 2rem; padding: clamp(1.25rem, 4vw, 2.25rem); }
603
614
  .uhcp-sos-panel > header { align-items: flex-start; display: flex; gap: 1rem; justify-content: space-between; }
604
615
  .uhcp-sos-panel h2 { margin: 0 0 .35rem; }
@@ -618,7 +629,10 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
618
629
  @media (max-width: 620px) {
619
630
  .uhcp-sos-overview-grid { grid-template-columns: 1fr; }
620
631
  .uhcp-sos-panel > header { display: grid; }
632
+ .uhcp-sos-more{margin-left:0}.uhcp-sos-more>div{left:0;right:auto}
621
633
  }
634
+ .uhcp-emergency-task-hub{display:grid;gap:1.25rem;margin-top:1.5rem}.uhcp-emergency-task-hub>header h2{font-size:clamp(1.35rem,3vw,1.9rem);margin:0}.uhcp-emergency-task-hub>header p{color:var(--uhcp-muted);margin:.35rem 0 0}.uhcp-emergency-task-list{display:grid;gap:.8rem}.uhcp-emergency-task-list article{align-items:center;border:1px solid var(--uhcp-border);border-radius:1.15rem;display:grid;gap:1rem;grid-template-columns:auto minmax(0,1fr) auto;padding:1rem}.uhcp-emergency-task-icon{align-items:center;background:color-mix(in srgb,var(--uhcp-turquoise) 12%,var(--uhcp-panel));border-radius:50%;color:var(--uhcp-turquoise);display:flex;height:3.25rem;justify-content:center;width:3.25rem}.uhcp-emergency-task-icon svg,.uhcp-emergency-task-list article>a svg{fill:none;stroke:currentColor;stroke-linecap:round;stroke-linejoin:round;stroke-width:1.8}.uhcp-emergency-task-icon svg{height:1.65rem;width:1.65rem}.uhcp-emergency-task-copy h3{font-size:1.05rem;margin:0}.uhcp-emergency-task-copy p{color:var(--uhcp-muted);line-height:1.45;margin:.25rem 0 0}.uhcp-emergency-task-copy small{color:var(--uhcp-emerald);display:block;font-weight:750;margin-top:.35rem}.uhcp-emergency-task-list article>a{align-items:center;background:var(--uhcp-turquoise);border-radius:.75rem;color:#fff;display:inline-flex;font-weight:800;gap:.45rem;padding:.75rem .9rem;text-decoration:none}.uhcp-emergency-task-list article>a svg{height:1rem;width:1rem}.uhcp-emergency-task-unavailable{color:var(--uhcp-muted);font-size:.85rem;max-width:11rem}.uhcp-emergency-task-list article:has(>a):first-child{border-color:color-mix(in srgb,var(--uhcp-turquoise) 42%,var(--uhcp-border))}@media(max-width:720px){.uhcp-emergency-task-list article{align-items:start;grid-template-columns:auto 1fr}.uhcp-emergency-task-list article>a,.uhcp-emergency-task-unavailable{grid-column:1/-1;justify-content:center;max-width:none;text-align:center}}
635
+ .uhcp-emergency-task-hub-grid .uhcp-emergency-task-list{grid-template-columns:repeat(3,minmax(0,1fr))}.uhcp-emergency-task-hub-grid .uhcp-emergency-task-list article{align-content:start;grid-template-columns:1fr;min-height:16rem;padding:1.35rem}.uhcp-emergency-task-hub-grid .uhcp-emergency-task-icon{height:4rem;width:4rem}.uhcp-emergency-task-hub-grid .uhcp-emergency-task-copy h3{font-size:1.25rem}.uhcp-emergency-task-hub-grid .uhcp-emergency-task-list article>a{justify-content:space-between;margin-top:auto;width:100%}@media(max-width:840px){.uhcp-emergency-task-hub-grid .uhcp-emergency-task-list{grid-template-columns:1fr}.uhcp-emergency-task-hub-grid .uhcp-emergency-task-list article{min-height:0}}
622
636
  .uhcp-emergency-copy { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 2rem; color: var(--uhcp-text); padding: clamp(1.25rem, 4vw, 2.25rem); }
623
637
  .uhcp-emergency-copy > header { align-items: flex-start; display: flex; gap: 1.5rem; justify-content: space-between; }
624
638
  .uhcp-emergency-copy h2 { margin: 0 0 .45rem; }
@@ -640,3 +654,22 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
640
654
  .uhcp-legal-document{color:var(--uhcp-text);line-height:1.7}.uhcp-legal-document h2{font-size:clamp(1.6rem,4vw,2.35rem);line-height:1.15;margin:0 0 1.25rem}.uhcp-legal-document h3{font-size:1.2rem;line-height:1.3;margin:2rem 0 .65rem}.uhcp-legal-document p{margin:0 0 1rem}.uhcp-legal-document ul{margin:0 0 1rem;padding-left:1.4rem}.uhcp-legal-document code{background:var(--uhcp-panel-muted);border-radius:.3rem;padding:.08rem .3rem}
641
655
  .uhcp-consent-directory{background:var(--uhcp-panel);border:1px solid var(--uhcp-border);border-radius:1.5rem;color:var(--uhcp-text);display:grid;gap:1rem;padding:1.25rem}.uhcp-consent-directory>header{align-items:flex-start;display:flex;gap:1rem;justify-content:space-between}.uhcp-consent-directory h2,.uhcp-consent-directory p{margin:0}.uhcp-consent-directory>header p,.uhcp-consent-list article>p{color:var(--uhcp-muted)}.uhcp-consent-directory button,.uhcp-consent-directory select{background:var(--uhcp-panel);border:1px solid var(--uhcp-border);border-radius:.7rem;color:inherit;font:inherit;padding:.65rem .85rem}.uhcp-consent-list{display:grid;gap:.75rem}.uhcp-consent-list article{background:var(--uhcp-panel-muted);border:1px solid var(--uhcp-border);border-radius:1rem;display:grid;gap:.55rem;padding:1rem}.uhcp-consent-list article>div:first-child{align-items:center;display:flex;flex-wrap:wrap;gap:.55rem}.uhcp-consent-list article span{background:color-mix(in srgb,var(--uhcp-turquoise) 13%,transparent);border-radius:999px;font-size:.8rem;padding:.25rem .5rem}.uhcp-consent-actions{display:flex;flex-wrap:wrap;gap:.5rem}.uhcp-consent-editor{border-top:1px solid var(--uhcp-border);display:grid;gap:1rem;padding-top:1rem}.uhcp-consent-editor>label{display:grid;gap:.35rem}.uhcp-consent-editor fieldset{border:1px solid var(--uhcp-border);border-radius:1rem;display:flex;flex-wrap:wrap;gap:.75rem;margin:0;padding:1rem}.uhcp-consent-editor legend{font-weight:800;padding:0 .35rem}.uhcp-consent-editor fieldset label{align-items:center;display:flex;gap:.35rem}.uhcp-consent-editor>div{display:flex;gap:.6rem}@media(max-width:620px){.uhcp-consent-directory>header{display:grid}.uhcp-consent-editor fieldset{display:grid}}
642
656
  .uhcp-loading-skeleton{background:var(--uhcp-panel);border:1px solid var(--uhcp-border);border-radius:2rem;display:grid;gap:1rem;margin:0 auto;max-width:1160px;overflow:hidden;padding:clamp(1.25rem,4vw,2.5rem);position:relative}.uhcp-loading-skeleton::after{animation:uhcp-loading-sweep 1.45s ease-in-out infinite;background:linear-gradient(90deg,transparent,color-mix(in srgb,#fff 42%,transparent),transparent);content:"";inset:0;position:absolute;transform:translateX(-100%)}.uhcp-loading-label{height:1px;overflow:hidden;position:absolute;width:1px;clip-path:inset(50%)}.uhcp-loading-heading,.uhcp-loading-copy,.uhcp-loading-row span{animation:uhcp-loading-pulse 1.45s ease-in-out infinite;background:color-mix(in srgb,var(--uhcp-muted) 17%,var(--uhcp-panel-muted));border-radius:999px}.uhcp-loading-heading{height:2.25rem;max-width:23rem;width:62%}.uhcp-loading-copy{height:1rem;max-width:38rem;width:86%}.uhcp-loading-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));margin-top:.5rem}.uhcp-loading-row{background:var(--uhcp-panel-muted);border:1px solid var(--uhcp-border);border-radius:1.35rem;display:grid;gap:.8rem;padding:1.25rem}.uhcp-loading-row span{display:block;height:.8rem}.uhcp-loading-row span:nth-child(1){width:35%}.uhcp-loading-row span:nth-child(2){height:1.2rem;width:72%}.uhcp-loading-row span:nth-child(3){width:90%}.uhcp-loading-skeleton-compact{border-radius:1.25rem;padding:1.25rem}.uhcp-loading-skeleton-compact .uhcp-loading-heading{height:1.5rem}@keyframes uhcp-loading-pulse{0%,100%{opacity:.55}50%{opacity:1}}@keyframes uhcp-loading-sweep{to{transform:translateX(100%)}}@media(prefers-reduced-motion:reduce){.uhcp-loading-skeleton::after,.uhcp-loading-heading,.uhcp-loading-copy,.uhcp-loading-row span{animation:none}}
657
+ .uhcp-animal-onboarding { display: grid; gap: 1.25rem; }
658
+ .uhcp-animal-onboarding > header p { color: var(--uhcp-muted, #5f6875); margin: .35rem 0 0; }
659
+ .uhcp-animal-onboarding form { display: grid; gap: 1rem; }
660
+ .uhcp-animal-onboarding fieldset { border: 1px solid var(--uhcp-border, #d9dee7); border-radius: 1rem; margin: 0; padding: 1rem; }
661
+ .uhcp-animal-onboarding legend { align-items: center; display: flex; font-weight: 800; gap: .55rem; padding: 0 .35rem; }
662
+ .uhcp-animal-onboarding-fields { display: grid; gap: .85rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
663
+ .uhcp-animal-onboarding-fields label { display: grid; gap: .35rem; }
664
+ .uhcp-animal-onboarding-fields input, .uhcp-animal-onboarding-fields select { box-sizing: border-box; min-height: 2.8rem; width: 100%; }
665
+ .uhcp-animal-onboarding-submit { justify-self: start; }
666
+ .uhcp-emergency-task-hub > header h1 { font-size: clamp(1.35rem, 3vw, 1.9rem); margin: 0; }
667
+ .uhcp-subject-identity-card { border: 1px solid var(--uhcp-border, #d9dee7); border-radius: 1rem; display: grid; gap: 1rem; padding: 1rem; }
668
+ .uhcp-subject-identity-card > header { align-items: center; display: grid; gap: .8rem; grid-template-columns: auto 1fr auto; }
669
+ .uhcp-subject-identity-card img, .uhcp-subject-identity-avatar { align-items: center; aspect-ratio: 1; border-radius: 50%; display: flex; height: 3.5rem; justify-content: center; object-fit: cover; width: 3.5rem; }
670
+ .uhcp-subject-identity-avatar { background: var(--uhcp-accent-soft, #e9f3ff); font-size: 1.4rem; font-weight: 850; }
671
+ .uhcp-subject-identity-card h3 { margin: .15rem 0 0; }
672
+ .uhcp-subject-identity-card dl { display: grid; gap: .65rem; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); margin: 0; }
673
+ .uhcp-subject-identity-card dt { color: var(--uhcp-muted, #5f6875); font-size: .8rem; }
674
+ .uhcp-subject-identity-card dd { font-weight: 700; margin: .15rem 0 0; overflow-wrap: anywhere; }
675
+ .uhcp-subject-identity-relationship { align-items: center; background: var(--uhcp-surface-soft, #f6f8fb); border-radius: .8rem; display: grid; gap: .25rem; padding: .8rem; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uhc-portal-components-react",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
4
4
  "description": "Brand-neutral React portal shell, account preferences and protected-profile UI for UHC and VetChain portals.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",