uhc-portal-components-react 0.2.0 → 0.2.2

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
@@ -2,6 +2,33 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.2.2 - 2026-10-09
6
+
7
+ - Name the exact localized FHIR resource in the V2 editor heading without a
8
+ redundant resource-type subtitle.
9
+ - Keep terminology candidates in the existing selection dropdown and report a
10
+ successful zero-result search explicitly, clearing stale results whenever
11
+ the query or governed coding-system selection changes.
12
+ - Give the V2 profile-unlock panel an explicit light/dark accent surface and
13
+ support PIN-recovery actions inside the PIN fallback only after a rejected
14
+ PIN, while keeping unrelated profile actions separate.
15
+ - Use compact, accessible add/remove section actions with destructive
16
+ confirmation, semantic action colours and matching hover/focus hints.
17
+ - Let hosts place downloads, credential generation and update metadata in the
18
+ same responsive document footer as the final submit action.
19
+
20
+ ## 0.2.1 - 2026-10-08
21
+
22
+ - Add the opt-in `ProfileProtectionGateV2`, which identifies the exact
23
+ host-authorized profile or subject with accessible human-readable metadata
24
+ before passkey or PIN unlock. V1 remains unchanged.
25
+ - Route every schema-backed IPS resource through the progressive V2 clinical
26
+ editor, with schema-owned coded dropdowns, terminology-backed concepts,
27
+ date/time controls, optional-field selection and mandatory canonical coding.
28
+ - Let hosts attach entry-level credential actions to a staged clinical record;
29
+ creation updates only the local draft and viewing does not cross the final
30
+ document submission boundary.
31
+
5
32
  ## 0.2.0 - 2026-10-08
6
33
 
7
34
  - Promote the opt-in V2 clinical document authoring API to a minor release.
package/README.md CHANGED
@@ -50,6 +50,8 @@ The package deliberately exposes modules instead of a cloned application:
50
50
  - `PortalEntryHero`: identical product entry composition for every brand.
51
51
  - `PortalAccessChooser`: real-page navigation for professional access paths.
52
52
  - `ProfileProtectionGate`: fail-closed PIN unlock presentation.
53
+ - `ProfileProtectionGateV2`: opt-in passkey/PIN gate that identifies the exact
54
+ host-authorized target without exposing or selecting its technical id.
53
55
  - `ClinicalSectionSummary`: brand-neutral rendering of already-resolved IPS
54
56
  cards for personal and professional portals. Advanced viewers can set
55
57
  `showHeader={false}` when they retain their own expandable heading.
@@ -1 +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"}
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,+BAUD"}
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  /** Compact clinical action; authorization and callback behavior remain host-owned. */
3
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 }) });
4
+ return _jsx("button", { type: "button", className: `uhcp-clinical-icon-action uhcp-clinical-icon-action-${kind}`, "aria-label": label, title: label, "data-tooltip": label, disabled: disabled, onClick: onClick, children: _jsx(ActionIcon, { kind: kind }) });
5
5
  }
6
6
  function ActionIcon({ kind }) {
7
7
  if (kind === 'add')
@@ -30,6 +30,7 @@ export type ClinicalArtifactEditorCopyV2 = Readonly<{
30
30
  close: string;
31
31
  terminologyLoading: string;
32
32
  terminologyUnavailable: string;
33
+ terminologyEmpty?: string;
33
34
  terminologySources: string;
34
35
  readbackMissing: string;
35
36
  addField: string;
@@ -41,6 +42,7 @@ export type ClinicalArtifactEditorCopyV2 = Readonly<{
41
42
  selectCandidate: string;
42
43
  canonicalCode: string;
43
44
  canonicalDisplay: string;
45
+ codingRequired: string;
44
46
  documents: string;
45
47
  addDocuments: string;
46
48
  removeDocument: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ClinicalArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditorV2.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClinicalArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditorV2.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useId, useRef, useState } from 'react';
4
4
  import { ClinicalEditorLayer } from './ClinicalEditorLayer.js';
5
5
  import { readClinicalAttachment } from './ClinicalArtifactEditor.js';
@@ -19,6 +19,11 @@ export function ClinicalArtifactEditorV2({ request, authoringContext, copy, fiel
19
19
  async function submit() {
20
20
  setError('');
21
21
  try {
22
+ for (const field of fields) {
23
+ if (field.required && field.kind === 'coded-concept' && field.codeClaim && !claims[field.codeClaim]) {
24
+ throw new TypeError(copy.codingRequired);
25
+ }
26
+ }
22
27
  validate?.(claims);
23
28
  setSaving(true);
24
29
  const draft = {
@@ -49,7 +54,7 @@ export function ClinicalArtifactEditorV2({ request, authoringContext, copy, fiel
49
54
  setSaving(false);
50
55
  }
51
56
  }
52
- return _jsx(ClinicalEditorLayer, { onDismiss: onCancel, children: _jsxs("section", { className: "uhcp-clinical-editor uhcp-clinical-editor-v2", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsxs("p", { className: "uhcp-clinical-editor-resource-type", children: [copy.resourceType || 'FHIR resource', ": ", resourceTypeLabel || request.resourceType] }), _jsx("p", { children: copy.description })] }), _jsx("button", { type: "button", "aria-label": copy.close, onClick: onCancel, children: "\u00D7" })] }), _jsxs("form", { onSubmit: event => { event.preventDefault(); void submit(); }, children: [fields.filter(field => visibleClaims.includes(field.claim)).map(field => _jsxs("div", { className: "uhcp-progressive-field-v2", children: [!field.required ? _jsx("button", { type: "button", className: "uhcp-remove-field-v2", "aria-label": `${copy.removeField}: ${fieldLabel(field.claim)}`, onClick: () => { setVisibleClaims(current => current.filter(claim => claim !== field.claim)); if (field.kind === 'documents')
57
+ return _jsx(ClinicalEditorLayer, { onDismiss: onCancel, children: _jsxs("section", { className: "uhcp-clinical-editor uhcp-clinical-editor-v2", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsxs("h2", { id: titleId, children: [copy.title, " ", resourceTypeLabel || request.resourceType] }), _jsx("p", { children: copy.description })] }), _jsx("button", { type: "button", "aria-label": copy.close, onClick: onCancel, children: "\u00D7" })] }), _jsxs("form", { onSubmit: event => { event.preventDefault(); void submit(); }, children: [fields.filter(field => visibleClaims.includes(field.claim)).map(field => _jsxs("div", { className: "uhcp-progressive-field-v2", children: [!field.required ? _jsx("button", { type: "button", className: "uhcp-remove-field-v2", "aria-label": `${copy.removeField}: ${fieldLabel(field.claim)}`, onClick: () => { setVisibleClaims(current => current.filter(claim => claim !== field.claim)); if (field.kind === 'documents')
53
58
  setAttachments([]); setClaims(current => { const next = { ...current }; delete next[field.claim]; if (field.codeClaim)
54
59
  delete next[field.codeClaim]; if (field.displayClaim)
55
60
  delete next[field.displayClaim]; return next; }); }, children: "\u00D7" }) : null, field.kind === 'documents' ? _jsx(DocumentReferencesPropertyV2, { copy: copy, attachments: attachments, onFiles: files => { void Promise.all(files.map(readClinicalAttachment)).then(next => setAttachments(current => [...current, ...next])).catch(reason => setError(reason instanceof Error ? reason.message : String(reason))); }, onRemove: id => setAttachments(current => current.filter(attachment => attachment.id !== id)) })
@@ -33,6 +33,7 @@ export declare function CodedConceptPropertyV2({ resourceType, textClaim, codeCl
33
33
  searchTerminology: string;
34
34
  terminologyLoading: string;
35
35
  terminologyUnavailable: string;
36
+ terminologyEmpty?: string;
36
37
  terminologySources: string;
37
38
  selectCandidate: string;
38
39
  clearCoding: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ClinicalArtifactPropertiesV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactPropertiesV2.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClinicalArtifactPropertiesV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactPropertiesV2.tsx"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
19
19
  const [candidates, setCandidates] = useState([]);
20
20
  const [busy, setBusy] = useState(false);
21
21
  const [failed, setFailed] = useState(false);
22
+ const [searched, setSearched] = useState(false);
22
23
  useEffect(() => {
23
24
  if (!loadTerminologySources)
24
25
  return;
@@ -38,6 +39,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
38
39
  return;
39
40
  setBusy(true);
40
41
  setFailed(false);
42
+ setSearched(false);
41
43
  try {
42
44
  let governedSources = selectedSources;
43
45
  if (!governedSources.length && loadTerminologySources) {
@@ -48,6 +50,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
48
50
  setSelectedSources(governedSources);
49
51
  }
50
52
  setCandidates(await searchTerminology({ resourceType, claim: codeClaim, language: locale, text: query.trim(), taxonomyId, limit: 20, ...(governedSources.length ? { sources: governedSources } : {}) }));
53
+ setSearched(true);
51
54
  }
52
55
  catch {
53
56
  setCandidates([]);
@@ -57,7 +60,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
57
60
  setBusy(false);
58
61
  }
59
62
  };
60
- return _jsxs("div", { className: "uhcp-clinical-property-v2 uhcp-coded-concept-property-v2", children: [_jsxs("span", { className: "uhcp-clinical-editor-field-heading", children: [_jsxs("label", { htmlFor: `${codeClaim}-query`, children: [label, required ? ' *' : ''] }), textClaim ? _jsx(ClinicalSpeechInputButton, { resourceType: resourceType, claim: textClaim, locale: locale, fieldLabel: label, onTranscript: transcript => { setQuery(transcript); onChange({ text: transcript, code: '', display: '' }); } }) : null] }), _jsxs("div", { className: "uhcp-coded-concept-query-v2", children: [_jsx("input", { id: `${codeClaim}-query`, "aria-label": label, required: required, readOnly: Boolean(code), value: code ? (text || query || display) : query, onChange: event => { setQuery(event.currentTarget.value); onChange({ text: event.currentTarget.value, code: '', display: '' }); } }), _jsx("button", { type: "button", className: "uhcp-icon-button-v2", "aria-label": copy.searchTerminology, title: copy.searchTerminology, disabled: Boolean(code) || busy || query.trim().length < 2, onClick: () => void search(), children: _jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: _jsx("path", { d: "m21 21-4.35-4.35m1.35-5.65a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z" }) }) }), code ? _jsx("button", { type: "button", className: "uhcp-clear-code-v2", "aria-label": copy.clearCoding, title: copy.clearCoding, onClick: () => { setQuery(''); setCandidates([]); onChange({ text: '', code: '', display: '' }); }, children: "\u00D7" }) : null] }), sources.length ? _jsxs("fieldset", { className: "uhcp-coding-sources-v2", children: [_jsx("legend", { children: copy.terminologySources }), sources.map(source => _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: selectedSources.includes(source.id), onChange: event => setSelectedSources(current => event.currentTarget.checked ? [...new Set([...current, source.id])] : current.filter(value => value !== source.id)) }), source.label || source.id] }, source.id))] }) : null, busy ? _jsx("small", { role: "status", children: copy.terminologyLoading }) : null, failed ? _jsx("small", { role: "alert", children: copy.terminologyUnavailable }) : null, candidates.length ? _jsxs("label", { children: [copy.selectCandidate, _jsxs("select", { "aria-label": copy.selectCandidate, value: selectedToken, onChange: event => {
63
+ return _jsxs("div", { className: "uhcp-clinical-property-v2 uhcp-coded-concept-property-v2", children: [_jsxs("span", { className: "uhcp-clinical-editor-field-heading", children: [_jsxs("label", { htmlFor: `${codeClaim}-query`, children: [label, required ? ' *' : ''] }), textClaim ? _jsx(ClinicalSpeechInputButton, { resourceType: resourceType, claim: textClaim, locale: locale, fieldLabel: label, onTranscript: transcript => { setQuery(transcript); onChange({ text: transcript, code: '', display: '' }); } }) : null] }), _jsxs("div", { className: "uhcp-coded-concept-query-v2", children: [_jsx("input", { id: `${codeClaim}-query`, "aria-label": label, required: required, readOnly: Boolean(code), value: code ? (text || query || display) : query, onChange: event => { setQuery(event.currentTarget.value); setCandidates([]); setSearched(false); setFailed(false); onChange({ text: event.currentTarget.value, code: '', display: '' }); } }), _jsx("button", { type: "button", className: "uhcp-icon-button-v2", "aria-label": copy.searchTerminology, title: copy.searchTerminology, disabled: Boolean(code) || busy || query.trim().length < 2, onClick: () => void search(), children: _jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: _jsx("path", { d: "m21 21-4.35-4.35m1.35-5.65a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z" }) }) }), code ? _jsx("button", { type: "button", className: "uhcp-clear-code-v2", "aria-label": copy.clearCoding, title: copy.clearCoding, onClick: () => { setQuery(''); setCandidates([]); onChange({ text: '', code: '', display: '' }); }, children: "\u00D7" }) : null] }), sources.length ? _jsxs("fieldset", { className: "uhcp-coding-sources-v2", children: [_jsx("legend", { children: copy.terminologySources }), sources.map(source => _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: selectedSources.includes(source.id), onChange: event => { const checked = event.currentTarget.checked; setSelectedSources(current => checked ? [...new Set([...current, source.id])] : current.filter(value => value !== source.id)); setCandidates([]); setSearched(false); setFailed(false); } }), source.label || source.id] }, source.id))] }) : null, busy ? _jsx("small", { role: "status", children: copy.terminologyLoading }) : null, failed ? _jsx("small", { role: "alert", children: copy.terminologyUnavailable }) : null, searched && !busy && !failed && candidates.length === 0 ? _jsx("small", { role: "status", children: copy.terminologyEmpty || copy.terminologyUnavailable }) : null, candidates.length ? _jsxs("label", { children: [copy.selectCandidate, _jsxs("select", { "aria-label": copy.selectCandidate, value: selectedToken, onChange: event => {
61
64
  const candidate = candidates.find(value => `${value.system}|${value.code}` === event.currentTarget.value);
62
65
  if (!candidate)
63
66
  return;
@@ -65,7 +68,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
65
68
  setQuery(localText);
66
69
  onChange({ text: localText, code: `${candidate.system}|${candidate.code}`, display: candidate.display });
67
70
  setCandidates([]);
68
- }, children: [_jsx("option", { value: "" }), candidates.map(candidate => _jsxs("option", { value: `${candidate.system}|${candidate.code}`, children: [candidate.display, " (", candidate.code, ")"] }, `${candidate.system}|${candidate.code}`))] })] }) : null, code ? _jsxs("div", { className: "uhcp-selected-code-v2", children: [_jsxs("label", { children: [copy.canonicalCode, _jsx("input", { "aria-label": copy.canonicalCode, readOnly: true, value: code })] }), _jsxs("label", { children: [copy.canonicalDisplay, _jsx("input", { "aria-label": copy.canonicalDisplay, readOnly: true, value: display })] })] }) : null] });
71
+ }, children: [_jsx("option", { value: "" }), candidates.map(candidate => _jsxs("option", { value: `${candidate.system}|${candidate.code}`, children: [candidate.text && candidate.text !== candidate.display ? `${candidate.text} — ${candidate.display}` : candidate.display, " (", candidate.code, ")"] }, `${candidate.system}|${candidate.code}`))] })] }) : null, code ? _jsxs("div", { className: "uhcp-selected-code-v2", children: [_jsxs("label", { children: [copy.canonicalCode, _jsx("input", { "aria-label": copy.canonicalCode, readOnly: true, value: code })] }), _jsxs("label", { children: [copy.canonicalDisplay, _jsx("input", { "aria-label": copy.canonicalDisplay, readOnly: true, value: display })] })] }) : null] });
69
72
  }
70
73
  export function CodedSelectPropertyV2({ label, value, required, options, onChange }) {
71
74
  return _jsxs("label", { className: "uhcp-clinical-property-v2", children: [label, required ? ' *' : '', _jsxs("select", { "aria-label": label, required: required, value: value, onChange: event => onChange(event.currentTarget.value), children: [_jsx("option", { value: "" }), options.map(option => _jsx("option", { value: option.value, children: option.label }, option.value))] })] });
@@ -1,3 +1,4 @@
1
+ import { type ReactNode } from 'react';
1
2
  import 'gdc-common-utils-ts/utils/allergy-intolerance-entry-editor';
2
3
  import 'gdc-common-utils-ts/utils/condition-entry-editor';
3
4
  import 'gdc-common-utils-ts/utils/document-reference-entry-editor';
@@ -8,6 +9,7 @@ import 'gdc-common-utils-ts/utils/procedure-entry-editor';
8
9
  import type { MultichannelOperationSchema } from 'sos-data-utils-ts/multichannel-operation-schemas';
9
10
  import { type ClinicalArtifactAuthoringContext, type ClinicalArtifactDraft, type ClinicalArtifactEditorCopy, type ClinicalArtifactSchema, type ClinicalTerminologySearch, type ClinicalTerminologyCandidate, type ClinicalTerminologySourceSearch } from './ClinicalArtifactEditor.js';
10
11
  import { type ImmunizationArtifactEditorCopyV2 } from './ImmunizationArtifactEditorV2.js';
12
+ import type { ClinicalArtifactDraftV2 } from './ClinicalArtifactEditorV2.js';
11
13
  export type ClinicalBundleDraftSchema = Readonly<{
12
14
  schema: ClinicalArtifactSchema;
13
15
  operationSchema: MultichannelOperationSchema;
@@ -32,6 +34,8 @@ export type ClinicalBundleDraftEditorCopy = Readonly<{
32
34
  resourceType?: string;
33
35
  addSection?: string;
34
36
  addEntry?: string;
37
+ removeSection?: string;
38
+ removeSectionConfirm?: string;
35
39
  chooseResource?: string;
36
40
  edit: string;
37
41
  remove: string;
@@ -58,6 +62,21 @@ export type ClinicalBundleDraftEditorProps = Readonly<{
58
62
  onSubmitDraft: (bundle: ClinicalBundleDraft) => Promise<ClinicalBundleDraftSubmitOutcome>;
59
63
  editorVersion?: 'v1' | 'v2';
60
64
  editorV2Copy?: ImmunizationArtifactEditorCopyV2;
65
+ artifactCredentialAction?: Readonly<{
66
+ createLabel: string;
67
+ viewLabel: string;
68
+ isCreated: (draft: ClinicalArtifactDraftV2) => boolean;
69
+ onCreate: (input: Readonly<{
70
+ draft: ClinicalArtifactDraftV2;
71
+ bundle: ClinicalBundleDraft;
72
+ }>) => ClinicalArtifactDraftV2 | Promise<ClinicalArtifactDraftV2>;
73
+ onView: (input: Readonly<{
74
+ draft: ClinicalArtifactDraftV2;
75
+ bundle: ClinicalBundleDraft;
76
+ }>) => void;
77
+ }>;
78
+ /** Host-owned document actions rendered beside the final submit action. */
79
+ documentActions?: ReactNode;
61
80
  }>;
62
81
  type StagedArtifact = Readonly<{
63
82
  schema: ClinicalBundleDraftSchema;
@@ -70,7 +89,7 @@ type StagedArtifact = Readonly<{
70
89
  * It owns no authorization or persistence: the host supplies subject and
71
90
  * provenance and only `onSubmitDraft` may cross a persistence boundary.
72
91
  */
73
- export declare function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion, editorV2Copy, }: ClinicalBundleDraftEditorProps): import("react").JSX.Element;
92
+ export declare function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion, editorV2Copy, artifactCredentialAction, documentActions, }: ClinicalBundleDraftEditorProps): import("react").JSX.Element;
74
93
  export declare function combineClinicalDrafts(artifacts: readonly StagedArtifact[], authoringContext: ClinicalArtifactAuthoringContext, documentTitle: string): ClinicalBundleDraft;
75
94
  export type ClinicalBundleDraftEditorV2Props = Omit<ClinicalBundleDraftEditorProps, 'editorVersion' | 'editorV2Copy'> & Readonly<{
76
95
  editorV2Copy: ImmunizationArtifactEditorCopyV2;
@@ -1 +1 @@
1
- {"version":3,"file":"ClinicalBundleDraftEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalBundleDraftEditor.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClinicalBundleDraftEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalBundleDraftEditor.tsx"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ import 'gdc-common-utils-ts/utils/procedure-entry-editor';
16
16
  import { ClinicalArtifactEditor, } from './ClinicalArtifactEditor.js';
17
17
  import { ClinicalActionButton } from './ClinicalActionButton.js';
18
18
  import { ImmunizationArtifactEditorV2, } from './ImmunizationArtifactEditorV2.js';
19
+ import { SchemaClinicalArtifactEditorV2 } from './SchemaClinicalArtifactEditorV2.js';
19
20
  /**
20
21
  * Shared local-first IPS authoring workspace.
21
22
  *
@@ -23,7 +24,7 @@ import { ImmunizationArtifactEditorV2, } from './ImmunizationArtifactEditorV2.js
23
24
  * It owns no authorization or persistence: the host supplies subject and
24
25
  * provenance and only `onSubmitDraft` may cross a persistence boundary.
25
26
  */
26
- export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale = 'en', timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion = 'v1', editorV2Copy, }) {
27
+ export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale = 'en', timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion = 'v1', editorV2Copy, artifactCredentialAction, documentActions, }) {
27
28
  const [artifacts, setArtifacts] = useState(() => importedArtifacts(initialBundle, schemas));
28
29
  const [editor, setEditor] = useState();
29
30
  const [resourceChooser, setResourceChooser] = useState();
@@ -73,30 +74,49 @@ export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, loc
73
74
  setSubmitting(false);
74
75
  }
75
76
  }
76
- return _jsxs("section", { className: "uhcp-clinical-bundle-draft", "data-clinical-bundle-draft": true, children: [_jsxs("header", { children: [_jsx("h2", { children: copy.title }), _jsx("p", { children: copy.description })] }), notice ? _jsx("p", { role: "status", children: notice }) : null, error ? _jsx("p", { role: "alert", className: "uhcp-clinical-editor-error", children: error }) : null, availableSections.length ? _jsxs("div", { className: "uhcp-clinical-bundle-draft-create", children: [_jsxs("label", { children: [copy.section || 'Section', _jsx("select", { value: availableSections.some(section => section.label === selectedSection) ? selectedSection : availableSections[0]?.label, onChange: (event) => setSelectedSection(event.currentTarget.value), children: availableSections.map(section => _jsx("option", { value: section.label, children: section.label }, section.label)) })] }), _jsxs("button", { type: "button", onClick: () => {
77
+ return _jsxs("section", { className: "uhcp-clinical-bundle-draft", "data-clinical-bundle-draft": true, children: [_jsxs("header", { children: [_jsx("h2", { children: copy.title }), _jsx("p", { children: copy.description })] }), notice ? _jsx("p", { role: "status", children: notice }) : null, error ? _jsx("p", { role: "alert", className: "uhcp-clinical-editor-error", children: error }) : null, availableSections.length ? _jsxs("div", { className: "uhcp-clinical-bundle-draft-create", children: [_jsxs("label", { children: [copy.section || 'Section', _jsx("select", { value: availableSections.some(section => section.label === selectedSection) ? selectedSection : availableSections[0]?.label, onChange: (event) => setSelectedSection(event.currentTarget.value), children: availableSections.map(section => _jsx("option", { value: section.label, children: section.label }, section.label)) })] }), _jsx("button", { type: "button", onClick: () => {
77
78
  const label = availableSections.some(section => section.label === selectedSection) ? selectedSection : availableSections[0]?.label;
78
79
  if (!label)
79
80
  return;
80
81
  setActiveSections(current => [...current, label]);
81
82
  const nextAvailable = availableSections.find(section => section.label !== label);
82
83
  setSelectedSection(nextAvailable?.label ?? '');
83
- }, children: ["+ ", copy.addSection || copy.add] })] }) : null, sections.filter(section => activeSections.includes(section.label)).map(({ label, schemas: sectionSchemas }) => {
84
+ }, className: "uhcp-add-section-button", children: copy.addSection || copy.add })] }) : null, sections.filter(section => activeSections.includes(section.label)).map(({ label, schemas: sectionSchemas }) => {
84
85
  const sectionArtifacts = artifacts.filter((artifact) => artifact.schema.sectionLabel === label);
85
- return _jsxs("details", { open: true, children: [_jsxs("summary", { children: [label, " (", sectionArtifacts.length, ")"] }), _jsxs("button", { type: "button", onClick: () => {
86
+ return _jsxs("details", { open: true, children: [_jsxs("summary", { children: [label, " (", sectionArtifacts.length, ")"] }), _jsx("button", { type: "button", className: "uhcp-remove-section-button", "aria-label": `${copy.removeSection || copy.remove} ${label}`, title: `${copy.removeSection || copy.remove} ${label}`, "data-tooltip": `${copy.removeSection || copy.remove} ${label}`, onClick: () => {
87
+ if (sectionArtifacts.length && !window.confirm(copy.removeSectionConfirm || `Removing this section will delete all its draft entries. Continue?`))
88
+ return;
89
+ setArtifacts(current => current.filter(artifact => artifact.schema.sectionLabel !== label));
90
+ setActiveSections(current => current.filter(section => section !== label));
91
+ if (resourceChooser?.sectionLabel === label)
92
+ setResourceChooser(undefined);
93
+ if (editor?.schema.sectionLabel === label)
94
+ setEditor(undefined);
95
+ }, children: "\u2212" }), _jsx("button", { type: "button", className: "uhcp-add-entry-button", "aria-label": copy.addEntry || copy.add, title: copy.addEntry || copy.add, "data-tooltip": copy.addEntry || copy.add, onClick: () => {
86
96
  if (sectionSchemas.length === 1)
87
97
  setEditor({ schema: sectionSchemas[0] });
88
98
  else
89
99
  setResourceChooser({ sectionLabel: label, schemaKey: schemaKey(sectionSchemas[0]) });
90
- }, children: ["+ ", copy.addEntry || copy.add] }), resourceChooser?.sectionLabel === label ? _jsxs("div", { className: "uhcp-clinical-bundle-resource-choice", children: [_jsxs("label", { children: [copy.resourceType || 'Resource type', _jsx("select", { value: resourceChooser.schemaKey, onChange: event => setResourceChooser({ sectionLabel: label, schemaKey: event.currentTarget.value }), children: sectionSchemas.map(candidate => _jsx("option", { value: schemaKey(candidate), children: resourceTypeLabel?.(candidate.schema.resourceType) || candidate.artifactLabel }, schemaKey(candidate))) })] }), _jsx("button", { type: "button", onClick: () => {
100
+ }, children: "+" }), resourceChooser?.sectionLabel === label ? _jsxs("div", { className: "uhcp-clinical-bundle-resource-choice", children: [_jsxs("label", { children: [copy.resourceType || 'Resource type', _jsx("select", { value: resourceChooser.schemaKey, onChange: event => setResourceChooser({ sectionLabel: label, schemaKey: event.currentTarget.value }), children: sectionSchemas.map(candidate => _jsx("option", { value: schemaKey(candidate), children: resourceTypeLabel?.(candidate.schema.resourceType) || candidate.artifactLabel }, schemaKey(candidate))) })] }), _jsx("button", { type: "button", onClick: () => {
91
101
  const selected = sectionSchemas.find(candidate => schemaKey(candidate) === resourceChooser.schemaKey);
92
102
  if (selected)
93
103
  setEditor({ schema: selected });
94
104
  setResourceChooser(undefined);
95
105
  }, children: copy.chooseResource || copy.add })] }) : null, sectionArtifacts.length === 0 ? _jsx("p", { children: copy.empty }) : _jsx("ul", { children: sectionArtifacts.map((artifact) => {
96
106
  const title = artifactTitle(artifact.draft);
97
- return _jsxs("li", { children: [_jsxs("span", { children: [_jsx("strong", { children: title }), _jsx("small", { children: artifact.draft.resourceType })] }), _jsxs("span", { children: [_jsx(ClinicalActionButton, { kind: "edit", label: `${copy.edit} ${title}`, onClick: () => setEditor({ schema: artifact.schema, draft: artifact.draft }) }), _jsx(ClinicalActionButton, { kind: "delete", label: `${copy.remove} ${title}`, onClick: () => setArtifacts((current) => current.filter((candidate) => candidate.draft.id !== artifact.draft.id)) })] })] }, artifact.draft.id);
107
+ return _jsxs("li", { children: [_jsxs("span", { children: [_jsx("strong", { children: title }), _jsx("small", { children: artifact.draft.resourceType })] }), _jsxs("span", { children: [artifactCredentialAction ? _jsx("button", { type: "button", className: "uhcp-clinical-entry-credential-action", onClick: () => {
108
+ const draft = artifact.draft;
109
+ const bundle = combineClinicalDrafts([artifact], authoringContext, copy.title);
110
+ if (artifactCredentialAction.isCreated(draft)) {
111
+ artifactCredentialAction.onView({ draft, bundle });
112
+ return;
113
+ }
114
+ void Promise.resolve(artifactCredentialAction.onCreate({ draft, bundle })).then(nextDraft => {
115
+ setArtifacts(current => current.map(candidate => candidate.draft.id === draft.id ? { ...candidate, draft: nextDraft } : candidate));
116
+ }).catch(reason => setError(reason instanceof Error ? reason.message : String(reason)));
117
+ }, children: artifactCredentialAction.isCreated(artifact.draft) ? artifactCredentialAction.viewLabel : artifactCredentialAction.createLabel }) : null, _jsx(ClinicalActionButton, { kind: "edit", label: `${copy.edit} ${title}`, onClick: () => setEditor({ schema: artifact.schema, draft: artifact.draft }) }), _jsx(ClinicalActionButton, { kind: "delete", label: `${copy.remove} ${title}`, onClick: () => setArtifacts((current) => current.filter((candidate) => candidate.draft.id !== artifact.draft.id)) })] })] }, artifact.draft.id);
98
118
  }) })] }, label);
99
- }), activeSections.length === 0 ? _jsx("p", { children: copy.empty }) : null, _jsx("footer", { children: _jsx("button", { type: "button", disabled: artifacts.length === 0 || submitting, onClick: () => void submitDraft(), children: submitting ? copy.submitting : copy.submit }) }), editor && editorVersion === 'v2' && editor.schema.schema.resourceType === 'Immunization' && editorV2Copy ? _jsx(ImmunizationArtifactEditorV2, { request: editorRequest(editor), authoringContext: authoringContext, copy: editorV2Copy, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, resourceTypeLabel: resourceTypeLabel?.(editor.schema.schema.resourceType) || editor.schema.artifactLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : editor ? _jsx(ClinicalArtifactEditor, { request: editorRequest(editor), schema: editor.schema.schema, operationSchema: editor.schema.operationSchema, authoringContext: authoringContext, copy: copy.editor, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, resourceTypeLabel: resourceTypeLabel?.(editor.schema.schema.resourceType) || editor.schema.artifactLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : null] });
119
+ }), activeSections.length === 0 ? _jsx("p", { children: copy.empty }) : null, _jsxs("footer", { "data-testid": "clinical-document-actions", children: [documentActions ? _jsx("div", { className: "uhcp-clinical-document-secondary-actions", children: documentActions }) : null, _jsx("button", { type: "button", className: "uhcp-clinical-document-submit", disabled: artifacts.length === 0 || submitting, onClick: () => void submitDraft(), children: submitting ? copy.submitting : copy.submit })] }), editor && editorVersion === 'v2' && editor.schema.schema.resourceType === 'Immunization' && editorV2Copy ? _jsx(ImmunizationArtifactEditorV2, { request: editorRequest(editor), authoringContext: authoringContext, copy: editorV2Copy, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, resourceTypeLabel: resourceTypeLabel?.(editor.schema.schema.resourceType) || editor.schema.artifactLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : editor && editorVersion === 'v2' && editorV2Copy ? _jsx(SchemaClinicalArtifactEditorV2, { request: editorRequest(editor), schema: editor.schema.schema, authoringContext: authoringContext, copy: editorV2Copy, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, resourceTypeLabel: resourceTypeLabel?.(editor.schema.schema.resourceType) || editor.schema.artifactLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : editor ? _jsx(ClinicalArtifactEditor, { request: editorRequest(editor), schema: editor.schema.schema, operationSchema: editor.schema.operationSchema, authoringContext: authoringContext, copy: copy.editor, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, resourceTypeLabel: resourceTypeLabel?.(editor.schema.schema.resourceType) || editor.schema.artifactLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : null] });
100
120
  }
101
121
  function editorRequest(editor) {
102
122
  return {
@@ -0,0 +1,21 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { ProfileProtectionCopyV2, ProfileProtectionState, ProfileProtectionTargetV2, ProfileUnlockResult } from './contracts.js';
3
+ export type ProfileProtectionGateV2Props = Readonly<{
4
+ state: ProfileProtectionState;
5
+ target: ProfileProtectionTargetV2;
6
+ copy: ProfileProtectionCopyV2;
7
+ onUnlock?: (pin: string) => ProfileUnlockResult | Promise<ProfileUnlockResult>;
8
+ onPasskeyUnlock?: () => void | Promise<void>;
9
+ onRetry?: () => void;
10
+ pinFailureActions?: ReactNode;
11
+ secondaryActions?: ReactNode;
12
+ children: ReactNode;
13
+ }>;
14
+ /**
15
+ * Presentation-only profile gate that identifies the host-authorized target.
16
+ *
17
+ * The host resolves translations, authority and the opaque profile id. This
18
+ * component renders only human-readable metadata and never selects a target.
19
+ */
20
+ export declare function ProfileProtectionGateV2({ state, target, copy, onUnlock, onPasskeyUnlock, onRetry, pinFailureActions, secondaryActions, children, }: ProfileProtectionGateV2Props): import("react").JSX.Element;
21
+ //# sourceMappingURL=ProfileProtectionGateV2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProfileProtectionGateV2.d.ts","sourceRoot":"","sources":["../src/ProfileProtectionGateV2.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACnF,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,gBAAgB,CAAA;AAEvB,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,KAAK,EAAE,sBAAsB,CAAA;IAC7B,MAAM,EAAE,yBAAyB,CAAA;IACjC,IAAI,EAAE,uBAAuB,CAAA;IAC7B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAC9E,eAAe,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,iBAAiB,CAAC,EAAE,SAAS,CAAA;IAC7B,gBAAgB,CAAC,EAAE,SAAS,CAAA;IAC5B,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAC,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,eAAe,EACf,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,GACT,EAAE,4BAA4B,+BAuH9B"}
@@ -0,0 +1,83 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from 'react';
4
+ /**
5
+ * Presentation-only profile gate that identifies the host-authorized target.
6
+ *
7
+ * The host resolves translations, authority and the opaque profile id. This
8
+ * component renders only human-readable metadata and never selects a target.
9
+ */
10
+ export function ProfileProtectionGateV2({ state, target, copy, onUnlock, onPasskeyUnlock, onRetry, pinFailureActions, secondaryActions, children, }) {
11
+ const [pin, setPin] = useState('');
12
+ const [error, setError] = useState('');
13
+ const [busy, setBusy] = useState(false);
14
+ const [pinRejected, setPinRejected] = useState(false);
15
+ const input = useRef(null);
16
+ useEffect(() => {
17
+ setPin('');
18
+ setError('');
19
+ setPinRejected(false);
20
+ }, [state, target.title, target.subtitle]);
21
+ async function unlock(event) {
22
+ event.preventDefault();
23
+ if (pin.length < 6) {
24
+ setError(copy.pinRequired);
25
+ return;
26
+ }
27
+ if (!onUnlock) {
28
+ setError(copy.unlockUnavailable);
29
+ return;
30
+ }
31
+ setBusy(true);
32
+ try {
33
+ const result = await onUnlock(pin);
34
+ if (result === 'unlocked') {
35
+ setPin('');
36
+ setError('');
37
+ setPinRejected(false);
38
+ return;
39
+ }
40
+ setPinRejected(result === 'invalid-pin');
41
+ setError(result === 'invalid-pin'
42
+ ? copy.invalidPin
43
+ : result === 'temporarily-locked'
44
+ ? copy.temporarilyLocked
45
+ : copy.unlockUnavailable);
46
+ }
47
+ finally {
48
+ setBusy(false);
49
+ }
50
+ }
51
+ async function unlockWithPasskey() {
52
+ if (!onPasskeyUnlock)
53
+ return;
54
+ setBusy(true);
55
+ setError('');
56
+ try {
57
+ await onPasskeyUnlock();
58
+ }
59
+ catch {
60
+ setError(copy.unlockUnavailable);
61
+ }
62
+ finally {
63
+ setBusy(false);
64
+ }
65
+ }
66
+ if (state === 'not-required')
67
+ return _jsx(_Fragment, { children: children });
68
+ const title = state === 'checking'
69
+ ? copy.checkingTitle
70
+ : state === 'setup-required'
71
+ ? copy.setupTitle
72
+ : state === 'unavailable'
73
+ ? copy.unavailableTitle
74
+ : copy.unlockTitle;
75
+ const body = state === 'checking'
76
+ ? copy.checkingBody
77
+ : state === 'setup-required'
78
+ ? copy.setupBody
79
+ : state === 'unavailable'
80
+ ? copy.unavailableBody
81
+ : copy.unlockBody;
82
+ return (_jsxs("section", { className: "uhcp-profile-gate uhcp-profile-gate-v2", "aria-live": "polite", children: [_jsxs("div", { className: "uhcp-profile-target", children: [target.icon && _jsx("img", { src: target.icon.src, alt: target.icon.alt, width: target.icon.width, height: target.icon.height }), _jsxs("div", { className: "uhcp-profile-target-copy", children: [_jsx("span", { className: "uhcp-profile-target-eyebrow", children: target.eyebrow }), _jsx("strong", { children: target.title }), target.subtitle && _jsx("span", { children: target.subtitle })] }), target.badges?.length ? _jsx("ul", { className: "uhcp-profile-target-badges", "aria-label": target.eyebrow, children: target.badges.map(badge => _jsx("li", { children: badge }, badge)) }) : null, target.details?.length ? _jsx("dl", { className: "uhcp-profile-target-details", children: target.details.map(detail => _jsxs("div", { children: [_jsx("dt", { children: detail.label }), _jsx("dd", { children: detail.value })] }, `${detail.label}:${detail.value}`)) }) : null] }), _jsxs("div", { className: "uhcp-profile-gate-copy", children: [_jsx("h1", { children: title }), _jsx("p", { children: body })] }), state === 'locked' && onPasskeyUnlock && _jsx("button", { type: "button", "data-portal-action": "unlock-profile-with-passkey", disabled: busy, onClick: unlockWithPasskey, children: copy.unlockWithPasskey }), state === 'locked' && _jsxs("details", { className: "uhcp-profile-pin-fallback", open: !onPasskeyUnlock, children: [_jsx("summary", { children: onPasskeyUnlock ? copy.usePinInstead : copy.pinLabel }), _jsxs("form", { onSubmit: unlock, children: [_jsxs("label", { children: [copy.pinLabel, _jsx("input", { ref: input, type: "password", inputMode: "numeric", minLength: 6, autoComplete: "current-password", value: pin, onChange: (event) => setPin(event.target.value) })] }), error && _jsx("p", { role: "alert", className: "uhcp-error", children: error }), _jsx("button", { type: "submit", "data-portal-action": "unlock-profile", disabled: busy, children: copy.unlock })] }), pinRejected && pinFailureActions ? _jsx("div", { className: "uhcp-profile-pin-recovery", children: pinFailureActions }) : null] }), state === 'unavailable' && onRetry && _jsx("button", { type: "button", onClick: onRetry, children: copy.retry }), secondaryActions && _jsx("div", { className: "uhcp-profile-gate-secondary", children: secondaryActions })] }));
83
+ }
@@ -0,0 +1,10 @@
1
+ import { type ClinicalArtifactEditorV2Props, type ClinicalArtifactFieldV2 } from './ClinicalArtifactEditorV2.js';
2
+ import type { ClinicalArtifactSchema } from './ClinicalArtifactEditor.js';
3
+ export type SchemaClinicalArtifactEditorV2Props = Omit<ClinicalArtifactEditorV2Props, 'fields' | 'initialVisibleClaims' | 'initialClaims'> & Readonly<{
4
+ schema: ClinicalArtifactSchema;
5
+ }>;
6
+ /** Adapts every schema-backed IPS resource to the same progressive V2 editor. */
7
+ export declare function SchemaClinicalArtifactEditorV2({ schema, locale, ...props }: SchemaClinicalArtifactEditorV2Props): import("react").JSX.Element;
8
+ /** Keeps form control selection deterministic and owned by the canonical schema/catalog. */
9
+ export declare function clinicalArtifactFieldsV2FromSchema(schema: ClinicalArtifactSchema, locale?: string): readonly ClinicalArtifactFieldV2[];
10
+ //# sourceMappingURL=SchemaClinicalArtifactEditorV2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaClinicalArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/SchemaClinicalArtifactEditorV2.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAC7B,MAAM,+BAA+B,CAAA;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAEzE,MAAM,MAAM,mCAAmC,GAAG,IAAI,CAAC,6BAA6B,EAAE,QAAQ,GAAG,sBAAsB,GAAG,eAAe,CAAC,GAAG,QAAQ,CAAC;IACpJ,MAAM,EAAE,sBAAsB,CAAA;CAC/B,CAAC,CAAA;AAEF,iFAAiF;AACjF,wBAAgB,8BAA8B,CAAC,EAAE,MAAM,EAAE,MAAa,EAAE,GAAG,KAAK,EAAE,EAAE,mCAAmC,+BAQtH;AAED,4FAA4F;AAC5F,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,sBAAsB,EAAE,MAAM,SAAO,GAAG,SAAS,uBAAuB,EAAE,CA8BpI"}
@@ -0,0 +1,60 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { clinicalArtifactCodedOptionsForClaim } from 'fhir-data-utils-ts';
4
+ import { ClinicalArtifactEditorV2, } from './ClinicalArtifactEditorV2.js';
5
+ /** Adapts every schema-backed IPS resource to the same progressive V2 editor. */
6
+ export function SchemaClinicalArtifactEditorV2({ schema, locale = 'en', ...props }) {
7
+ return _jsx(ClinicalArtifactEditorV2, { ...props, locale: locale, fields: clinicalArtifactFieldsV2FromSchema(schema, locale), initialVisibleClaims: schema.requiredClaims, initialClaims: schema.initialClaims });
8
+ }
9
+ /** Keeps form control selection deterministic and owned by the canonical schema/catalog. */
10
+ export function clinicalArtifactFieldsV2FromSchema(schema, locale = 'en') {
11
+ const required = new Set(schema.requiredClaims);
12
+ const terminologyText = new Set(schema.terminologyTextClaims ?? []);
13
+ const pairedClaims = new Set();
14
+ const fields = [];
15
+ for (const textClaim of terminologyText) {
16
+ const pair = codedClaimPair(textClaim);
17
+ pairedClaims.add(pair.codeClaim);
18
+ pairedClaims.add(pair.displayClaim);
19
+ }
20
+ for (const claim of [...schema.requiredClaims, ...schema.optionalClaims]) {
21
+ if (pairedClaims.has(claim))
22
+ continue;
23
+ const options = clinicalArtifactCodedOptionsForClaim(claim, locale);
24
+ if (terminologyText.has(claim)) {
25
+ const pair = codedClaimPair(claim);
26
+ fields.push({ claim, textClaim: claim, codeClaim: pair.codeClaim, displayClaim: pair.displayClaim, kind: 'coded-concept', required: required.has(claim) });
27
+ }
28
+ else if (options.length) {
29
+ fields.push({ claim, kind: 'coded-select', required: required.has(claim), options: options.map(option => ({ value: option.code, label: option.label })) });
30
+ }
31
+ else if (isDateTimeClaim(claim)) {
32
+ fields.push({ claim, kind: 'date-time', required: required.has(claim) });
33
+ }
34
+ else if (isPositiveIntegerClaim(claim)) {
35
+ fields.push({ claim, kind: 'positive-integer', required: required.has(claim) });
36
+ }
37
+ else {
38
+ fields.push({ claim, kind: 'text', required: required.has(claim) });
39
+ }
40
+ }
41
+ fields.push({ claim: '__documents', kind: 'documents', transient: true });
42
+ return Object.freeze(fields);
43
+ }
44
+ function codedClaimPair(textClaim) {
45
+ if (textClaim.endsWith('-text')) {
46
+ const base = textClaim.slice(0, -'-text'.length);
47
+ return { codeClaim: base, displayClaim: `${base}-display` };
48
+ }
49
+ if (textClaim.endsWith('.code-text')) {
50
+ const base = textClaim.slice(0, -'-text'.length);
51
+ return { codeClaim: base, displayClaim: `${base}-display` };
52
+ }
53
+ return { codeClaim: `${textClaim}-code`, displayClaim: `${textClaim}-display` };
54
+ }
55
+ function isDateTimeClaim(claim) {
56
+ return /(?:^|[-.])(date|datetime|effective|onset)(?:$|[-.])/.test(claim);
57
+ }
58
+ function isPositiveIntegerClaim(claim) {
59
+ return /(?:dose-sequence|series-doses|timing-frequency)$/.test(claim);
60
+ }
@@ -87,4 +87,20 @@ export type ProfileProtectionCopy = Readonly<{
87
87
  unlock: string;
88
88
  retry: string;
89
89
  }>;
90
+ /** Human-readable metadata for a host-authorized profile or subject target. */
91
+ export type ProfileProtectionTargetV2 = Readonly<{
92
+ eyebrow: string;
93
+ title: string;
94
+ subtitle?: string;
95
+ icon?: PortalBrandAsset;
96
+ badges?: readonly string[];
97
+ details?: readonly Readonly<{
98
+ label: string;
99
+ value: string;
100
+ }>[];
101
+ }>;
102
+ export type ProfileProtectionCopyV2 = ProfileProtectionCopy & Readonly<{
103
+ unlockWithPasskey: string;
104
+ usePinInstead: string;
105
+ }>;
90
106
  //# sourceMappingURL=contracts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from './PortalCurrentSubject.js';
6
6
  export * from './PortalShell.js';
7
7
  export * from './PortalEntry.js';
8
8
  export * from './ProfileProtectionGate.js';
9
+ export * from './ProfileProtectionGateV2.js';
9
10
  export * from './PortalLoadingSkeleton.js';
10
11
  export * from './ClinicalSectionSummary.js';
11
12
  export * from './IpsBundleSummary.js';
@@ -15,6 +16,7 @@ export * from './ClinicalTimeline.js';
15
16
  export * from './ClinicalArtifactEditor.js';
16
17
  export * from './ClinicalArtifactPropertiesV2.js';
17
18
  export * from './ClinicalArtifactEditorV2.js';
19
+ export * from './SchemaClinicalArtifactEditorV2.js';
18
20
  export * from './ImmunizationArtifactEditorV2.js';
19
21
  export * from './ClinicalBundleDraftEditor.js';
20
22
  export * from './ClinicalSpeechInput.js';
@@ -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,2BAA2B,CAAA;AACzC,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,mCAAmC,CAAA;AACjD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,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,yBAAyB,CAAA;AACvC,cAAc,uCAAuC,CAAA;AACrD,cAAc,uBAAuB,CAAA;AACrC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8BAA8B,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,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,8BAA8B,CAAA;AAC5C,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,mCAAmC,CAAA;AACjD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,qCAAqC,CAAA;AACnD,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,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,yBAAyB,CAAA;AACvC,cAAc,uCAAuC,CAAA;AACrD,cAAc,uBAAuB,CAAA;AACrC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8BAA8B,CAAA"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ export * from './PortalCurrentSubject.js';
6
6
  export * from './PortalShell.js';
7
7
  export * from './PortalEntry.js';
8
8
  export * from './ProfileProtectionGate.js';
9
+ export * from './ProfileProtectionGateV2.js';
9
10
  export * from './PortalLoadingSkeleton.js';
10
11
  export * from './ClinicalSectionSummary.js';
11
12
  export * from './IpsBundleSummary.js';
@@ -15,6 +16,7 @@ export * from './ClinicalTimeline.js';
15
16
  export * from './ClinicalArtifactEditor.js';
16
17
  export * from './ClinicalArtifactPropertiesV2.js';
17
18
  export * from './ClinicalArtifactEditorV2.js';
19
+ export * from './SchemaClinicalArtifactEditorV2.js';
18
20
  export * from './ImmunizationArtifactEditorV2.js';
19
21
  export * from './ClinicalBundleDraftEditor.js';
20
22
  export * from './ClinicalSpeechInput.js';
package/dist/styles.css CHANGED
@@ -161,6 +161,27 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
161
161
  .uhcp-profile-gate label { color: var(--uhcp-muted); display: grid; gap: .45rem; }
162
162
  .uhcp-profile-gate input { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: .75rem; color: var(--uhcp-text); padding: .8rem; }
163
163
  .uhcp-profile-gate button { background: linear-gradient(135deg, var(--uhcp-action-start), var(--uhcp-action-end)); border: 0; border-radius: .75rem; color: #fff; cursor: pointer; font: inherit; font-weight: 800; padding: .8rem 1rem; }
164
+ .uhcp-profile-gate-v2 { background: linear-gradient(145deg, color-mix(in srgb, var(--uhcp-surface-accent) 76%, var(--uhcp-panel)), var(--uhcp-panel-muted)); border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 30%, var(--uhcp-border)); border-radius: 1.5rem; box-shadow: 0 1.2rem 3rem color-mix(in srgb, var(--uhcp-text) 10%, transparent); gap: 1rem; }
165
+ .uhcp-profile-target { background: linear-gradient(135deg, color-mix(in srgb, var(--uhcp-surface-accent) 80%, var(--uhcp-panel)), color-mix(in srgb, var(--uhcp-turquoise) 12%, var(--uhcp-panel))); border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 38%, var(--uhcp-border)); border-radius: 1rem; display: grid; gap: .8rem; padding: 1rem; }
166
+ .uhcp-profile-target > img { border-radius: .75rem; object-fit: contain; }
167
+ .uhcp-profile-target-copy { display: grid; gap: .2rem; }
168
+ .uhcp-profile-target-copy > strong { color: var(--uhcp-text); font-size: 1.2rem; }
169
+ .uhcp-profile-target-copy > span:last-child { color: var(--uhcp-muted); }
170
+ .uhcp-profile-target-eyebrow { color: var(--uhcp-muted); font-size: .78rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
171
+ .uhcp-profile-target-badges { display: flex; flex-wrap: wrap; gap: .45rem; list-style: none; margin: 0; padding: 0; }
172
+ .uhcp-profile-target-badges li { background: color-mix(in srgb, var(--uhcp-turquoise) 13%, var(--uhcp-panel)); border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 36%, var(--uhcp-border)); border-radius: 999px; color: var(--uhcp-text); padding: .35rem .65rem; }
173
+ .uhcp-profile-target-details { margin: 0; }
174
+ .uhcp-profile-target-details > div { display: grid; gap: .2rem; grid-template-columns: minmax(8rem, auto) 1fr; }
175
+ .uhcp-profile-target-details dt { color: var(--uhcp-muted); }
176
+ .uhcp-profile-target-details dd { color: var(--uhcp-text); font-weight: 700; margin: 0; }
177
+ .uhcp-profile-pin-fallback { border-top: 1px solid var(--uhcp-border); padding-top: .8rem; }
178
+ .uhcp-profile-pin-fallback summary { color: var(--uhcp-text); cursor: pointer; font-weight: 700; }
179
+ .uhcp-profile-pin-fallback form { margin-top: .8rem; }
180
+ .uhcp-profile-pin-recovery { display: flex; justify-content: flex-start; margin-top: .7rem; }
181
+ .uhcp-profile-pin-recovery button { background: transparent; border: 1px solid var(--uhcp-border); color: var(--uhcp-text); }
182
+ .uhcp-profile-gate-secondary { border-top: 1px solid var(--uhcp-border); display: grid; gap: .6rem; padding-top: .8rem; }
183
+ .uhcp-profile-gate-secondary .uhcp-add-profile-action { align-items: center; background: transparent; border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 35%, var(--uhcp-border)); color: var(--uhcp-text); display: inline-flex; gap: .65rem; justify-content: flex-start; }
184
+ .uhcp-profile-gate-secondary .uhcp-add-profile-action::first-letter { color: var(--uhcp-turquoise); font-size: 1.25em; }
164
185
  .uhcp-error { color: #c64747 !important; }
165
186
  .uhcp-shell { background: var(--uhcp-surface); color: var(--uhcp-text); min-height: 100vh; }
166
187
  .uhcp-main { min-height: calc(100vh - 4.5rem); }
@@ -503,29 +524,35 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
503
524
  .uhcp-clinical-bundle-draft { 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; }
504
525
  .uhcp-clinical-bundle-draft>header h2,.uhcp-clinical-bundle-draft>header p { margin:.15rem 0; }
505
526
  .uhcp-clinical-bundle-draft>header p,.uhcp-clinical-bundle-draft details>p { color:var(--uhcp-muted); }
506
- .uhcp-clinical-bundle-draft details { background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; padding:.85rem 1rem; }
527
+ .uhcp-clinical-bundle-draft details { background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; padding:.85rem 1rem; position:relative; }
507
528
  .uhcp-clinical-bundle-draft summary { cursor:pointer; font-weight:800; }
508
529
  .uhcp-clinical-bundle-draft-create { align-items:end; background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; display:grid; gap:.8rem; grid-template-columns:minmax(10rem,1fr) minmax(10rem,1fr) auto; padding:1rem; }
509
530
  .uhcp-clinical-bundle-draft-create label { display:grid; gap:.35rem; font-weight:700; }
510
531
  .uhcp-clinical-bundle-draft-create select { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.7rem; color:var(--uhcp-text); font:inherit; min-height:2.75rem; padding:.55rem .7rem; }
511
- .uhcp-clinical-bundle-draft-create button { background:linear-gradient(135deg,var(--uhcp-action-start),var(--uhcp-action-end)); border:0; border-radius:.75rem; color:#fff; cursor:pointer; font:inherit; font-weight:800; min-height:2.75rem; padding:.65rem 1rem; }
532
+ .uhcp-clinical-bundle-draft-create button.uhcp-add-section-button { background:color-mix(in srgb,var(--uhcp-turquoise) 13%,var(--uhcp-panel)); border:1px solid color-mix(in srgb,var(--uhcp-turquoise) 45%,var(--uhcp-border)); border-radius:.75rem; color:var(--uhcp-text); cursor:pointer; font:inherit; font-weight:800; min-height:2.75rem; padding:.65rem 1rem; }
512
533
  .uhcp-clinical-bundle-draft-create button:disabled { cursor:not-allowed; opacity:.5; }
534
+ .uhcp-clinical-bundle-draft .uhcp-add-entry-button { background:var(--uhcp-emerald); border:0; border-radius:.65rem; color:#fff; cursor:pointer; font-size:1.3rem; font-weight:900; height:2.5rem; margin-top:.65rem; width:2.5rem; }
535
+ .uhcp-clinical-bundle-draft .uhcp-remove-section-button { background:color-mix(in srgb,#c64747 12%,var(--uhcp-panel)); border:1px solid color-mix(in srgb,#c64747 42%,var(--uhcp-border)); border-radius:.6rem; color:#a72f2f; cursor:pointer; font-size:1.25rem; font-weight:900; height:2.25rem; position:absolute; right:.7rem; top:.55rem; width:2.25rem; }
513
536
  .uhcp-clinical-bundle-draft ul { display:grid; gap:.55rem; list-style:none; margin:.8rem 0 0; padding:0; }
514
537
  .uhcp-clinical-bundle-draft li { align-items:center; background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.8rem; display:flex; gap:1rem; justify-content:space-between; padding:.7rem; }
515
538
  .uhcp-clinical-bundle-draft li>span { display:flex; gap:.45rem; }
516
539
  .uhcp-clinical-bundle-draft li>span:first-child { align-items:flex-start; flex-direction:column; min-width:0; }
517
540
  .uhcp-clinical-bundle-draft li strong { overflow-wrap:anywhere; }
518
541
  .uhcp-clinical-bundle-draft li small { color:var(--uhcp-muted); }
519
- .uhcp-clinical-bundle-draft>footer { display:flex; justify-content:flex-end; }
520
- .uhcp-clinical-bundle-draft>footer button { background:linear-gradient(135deg,var(--uhcp-action-start),var(--uhcp-action-end)); border:0; border-radius:.75rem; color:#fff; cursor:pointer; font:inherit; font-weight:800; padding:.75rem 1rem; }
521
- .uhcp-clinical-bundle-draft>footer button:disabled { cursor:not-allowed; opacity:.5; }
542
+ .uhcp-clinical-bundle-draft>footer { align-items:center; background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; display:flex; gap:.75rem; justify-content:space-between; padding:.7rem .8rem; }
543
+ .uhcp-clinical-document-secondary-actions { align-items:center; display:flex; flex:1; flex-wrap:wrap; gap:.65rem; min-width:0; }
544
+ .uhcp-clinical-bundle-draft>footer .uhcp-clinical-document-submit { background:var(--uhcp-emerald); border:0; border-radius:.75rem; color:#fff; cursor:pointer; flex:0 0 auto; font:inherit; font-weight:800; padding:.75rem 1rem; }
545
+ .uhcp-clinical-bundle-draft>footer .uhcp-clinical-document-submit:disabled { cursor:not-allowed; opacity:.5; }
546
+ .uhcp-clinical-bundle-draft .uhcp-clinical-entry-credential-action { background:color-mix(in srgb,var(--uhcp-attention) 24%,var(--uhcp-panel)); border:1px solid color-mix(in srgb,var(--uhcp-attention) 58%,var(--uhcp-border)); color:var(--uhcp-text); }
547
+ .uhcp-clinical-bundle-draft button[data-tooltip],.uhcp-clinical-icon-action[data-tooltip] { position:relative; }
548
+ .uhcp-clinical-bundle-draft button[data-tooltip]:is(:hover,:focus-visible)::after,.uhcp-clinical-icon-action[data-tooltip]:is(:hover,:focus-visible)::after { background:var(--uhcp-text); border-radius:.45rem; bottom:calc(100% + .45rem); color:var(--uhcp-panel); content:attr(data-tooltip); font-size:.78rem; font-weight:700; left:50%; max-width:16rem; padding:.35rem .5rem; pointer-events:none; position:absolute; transform:translateX(-50%); white-space:nowrap; z-index:50; }
522
549
  .uhcp-clinical-editor-attachments { border:1px solid var(--uhcp-border); border-radius:.85rem; display:grid; gap:.65rem; grid-column:1/-1; padding:.85rem; }
523
550
  .uhcp-clinical-editor-attachments label { display:grid; gap:.35rem; }
524
551
  .uhcp-clinical-editor-attachments input[type=file] { border:1px dashed var(--uhcp-border); border-radius:.7rem; padding:.65rem; }
525
552
  .uhcp-clinical-editor-attachments ul { display:grid; gap:.4rem; list-style:none; margin:0; padding:0; }
526
553
  .uhcp-clinical-editor-attachments li { align-items:center; background:var(--uhcp-panel-muted); border-radius:.65rem; display:flex; justify-content:space-between; padding:.5rem .65rem; }
527
554
  .uhcp-clinical-editor-attachments li button { background:transparent; border:0; color:var(--uhcp-text); cursor:pointer; font-size:1.2rem; }
528
- @media (max-width:720px) { .uhcp-clinical-bundle-draft-create { grid-template-columns:1fr; } }
555
+ @media (max-width:720px) { .uhcp-clinical-bundle-draft-create { grid-template-columns:1fr; } .uhcp-clinical-bundle-draft>footer { align-items:stretch; flex-direction:column; } .uhcp-clinical-bundle-draft>footer .uhcp-clinical-document-submit { align-self:flex-end; } }
529
556
  .uhcp-clinical-title { font-weight: 800; margin: 0; }
530
557
  .uhcp-clinical-type { color: var(--uhcp-muted); font-size: .72rem; font-weight: 800; letter-spacing: .06em; margin: .35rem 0 0; text-transform: uppercase; }
531
558
  .uhcp-clinical-date, .uhcp-clinical-empty { color: var(--uhcp-muted); margin: .35rem 0 0; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uhc-portal-components-react",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
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",