uhc-portal-components-react 0.1.30 → 0.1.31

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
@@ -147,6 +147,11 @@
147
147
 
148
148
  ## Unreleased
149
149
 
150
+ - Add a reusable, accessible Consent permission directory/editor for
151
+ provider-backed create, edit, suspend/reactivate and delete flows. The host
152
+ owns the schema-backed Bundle mutation and must return authoritative
153
+ readback; the component performs no optimistic authorization mutation.
154
+
150
155
  - Add the repository-wide mandatory red-green-refactor contributor contract
151
156
  and mark the existing component suites with an explicit TDD contract header.
152
157
  - Correct the reuse contract: the package currently provides presentation
@@ -0,0 +1,60 @@
1
+ import { type ConsentDecision, type ConsentStatus } from 'gdc-common-utils-ts/models/consent-rule';
2
+ export type ConsentPermissionOption = Readonly<{
3
+ value: string;
4
+ label: string;
5
+ }>;
6
+ export type ConsentPermissionContact = Readonly<{
7
+ id: string;
8
+ name: string;
9
+ }>;
10
+ export type ConsentPermissionRecord = Readonly<{
11
+ id: string;
12
+ contactReference: string;
13
+ contactName: string;
14
+ decision: ConsentDecision;
15
+ status: ConsentStatus;
16
+ purposes: readonly string[];
17
+ roles: readonly string[];
18
+ targets: readonly string[];
19
+ }>;
20
+ export type ConsentPermissionDraft = Readonly<Omit<ConsentPermissionRecord, 'id' | 'contactName'> & {
21
+ id?: string;
22
+ contactName?: string;
23
+ }>;
24
+ export type ConsentPermissionDirectoryCopy = Readonly<{
25
+ title: string;
26
+ empty: string;
27
+ add: string;
28
+ edit: string;
29
+ remove: string;
30
+ suspend: string;
31
+ activate: string;
32
+ save: string;
33
+ cancel: string;
34
+ contact: string;
35
+ decision: string;
36
+ permit: string;
37
+ deny: string;
38
+ status: string;
39
+ active: string;
40
+ inactive: string;
41
+ purposes: string;
42
+ roles: string;
43
+ targets: string;
44
+ saving: string;
45
+ loadError: string;
46
+ required: string;
47
+ }>;
48
+ export declare function ConsentPermissionDirectory({ records, contacts, purposeOptions, roleOptions, targetOptions, copy, editable, onSave, onStatusChange, onDelete }: Readonly<{
49
+ records: readonly ConsentPermissionRecord[];
50
+ contacts: readonly ConsentPermissionContact[];
51
+ purposeOptions: readonly ConsentPermissionOption[];
52
+ roleOptions: readonly ConsentPermissionOption[];
53
+ targetOptions: readonly ConsentPermissionOption[];
54
+ copy: ConsentPermissionDirectoryCopy;
55
+ editable?: boolean;
56
+ onSave?: (draft: ConsentPermissionDraft) => Promise<void> | void;
57
+ onStatusChange?: (id: string, status: ConsentStatus) => Promise<void> | void;
58
+ onDelete?: (id: string) => Promise<void> | void;
59
+ }>): import("react").JSX.Element;
60
+ //# sourceMappingURL=ConsentPermissionDirectory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentPermissionDirectory.d.ts","sourceRoot":"","sources":["../src/ConsentPermissionDirectory.tsx"],"names":[],"mappings":"AACA,OAAO,EAAqC,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAErI,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAChF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAC7E,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,EAAE,EAAE,MAAM,CAAA;IACV,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,eAAe,CAAA;IACzB,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3B,CAAC,CAAA;AACF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC,IAAI,CAAC,uBAAuB,EAAE,IAAI,GAAG,aAAa,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAC1I,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;IAC1G,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;IAC7F,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;IAClG,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CACpD,CAAC,CAAA;AAEF,wBAAgB,0BAA0B,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,QAAgB,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IAC/K,OAAO,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAC3C,QAAQ,EAAE,SAAS,wBAAwB,EAAE,CAAA;IAC7C,cAAc,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAClD,WAAW,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAC/C,aAAa,EAAE,SAAS,uBAAuB,EAAE,CAAA;IACjD,IAAI,EAAE,8BAA8B,CAAA;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAChE,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC5E,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAChD,CAAC,+BAiED"}
@@ -0,0 +1,52 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from 'react';
3
+ import { ConsentDecisions, ConsentStatuses } from 'gdc-common-utils-ts/models/consent-rule';
4
+ export function ConsentPermissionDirectory({ records, contacts, purposeOptions, roleOptions, targetOptions, copy, editable = false, onSave, onStatusChange, onDelete }) {
5
+ const [editing, setEditing] = useState(null);
6
+ const [saving, setSaving] = useState(false);
7
+ const [error, setError] = useState('');
8
+ const labels = useMemo(() => new Map([...purposeOptions, ...roleOptions, ...targetOptions].map(({ value, label }) => [value, label])), [purposeOptions, roleOptions, targetOptions]);
9
+ async function save() {
10
+ if (!editing || !editing.contactReference || !editing.purposes.length || !editing.roles.length || !editing.targets.length) {
11
+ setError(copy.required);
12
+ return;
13
+ }
14
+ setSaving(true);
15
+ setError('');
16
+ try {
17
+ await onSave?.(editing);
18
+ setEditing(null);
19
+ }
20
+ catch {
21
+ setError(copy.loadError);
22
+ }
23
+ finally {
24
+ setSaving(false);
25
+ }
26
+ }
27
+ async function changeStatus(record) {
28
+ setError('');
29
+ try {
30
+ await onStatusChange?.(record.id, record.status === ConsentStatuses.Active ? ConsentStatuses.Inactive : ConsentStatuses.Active);
31
+ }
32
+ catch {
33
+ setError(copy.loadError);
34
+ }
35
+ }
36
+ async function remove(record) {
37
+ setError('');
38
+ try {
39
+ await onDelete?.(record.id);
40
+ }
41
+ catch {
42
+ setError(copy.loadError);
43
+ }
44
+ }
45
+ return _jsxs("section", { className: "uhcp-consent-directory", "aria-labelledby": "uhcp-consent-directory-title", children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: "uhcp-consent-directory-title", children: copy.title }), _jsx("p", { children: records.length ? `${records.length}` : copy.empty })] }), editable ? _jsx("button", { type: "button", onClick: () => setEditing(emptyDraft()), children: copy.add }) : null] }), error ? _jsx("p", { role: "alert", children: error }) : null, _jsx("div", { className: "uhcp-consent-list", children: records.map((record) => _jsxs("article", { children: [_jsxs("div", { children: [_jsx("strong", { children: record.contactName }), _jsx("span", { children: record.decision === ConsentDecisions.Permit ? copy.permit : copy.deny }), _jsx("span", { children: record.status === ConsentStatuses.Active ? copy.active : copy.inactive })] }), _jsx("p", { children: record.purposes.map((value) => labels.get(value) ?? value).join(', ') }), _jsx("p", { children: record.roles.map((value) => labels.get(value) ?? value).join(', ') }), _jsx("p", { children: record.targets.map((value) => labels.get(value) ?? value).join(', ') }), editable ? _jsxs("div", { className: "uhcp-consent-actions", children: [_jsx("button", { type: "button", "aria-label": `${copy.edit} ${record.contactName}`, onClick: () => setEditing(record), children: copy.edit }), _jsx("button", { type: "button", "aria-label": `${record.status === ConsentStatuses.Active ? copy.suspend : copy.activate} ${record.contactName}`, onClick: () => void changeStatus(record), children: record.status === ConsentStatuses.Active ? copy.suspend : copy.activate }), _jsx("button", { type: "button", "aria-label": `${copy.remove} ${record.contactName}`, onClick: () => void remove(record), children: copy.remove })] }) : null] }, record.id)) }), editing ? _jsxs("form", { className: "uhcp-consent-editor", onSubmit: (event) => { event.preventDefault(); void save(); }, children: [_jsxs("label", { children: [copy.contact, _jsxs("select", { value: editing.contactReference, onChange: (event) => setEditing({ ...editing, contactReference: event.target.value, contactName: contacts.find(({ id }) => id === event.target.value)?.name }), children: [_jsx("option", { value: "" }), contacts.map((contact) => _jsx("option", { value: contact.id, children: contact.name }, contact.id))] })] }), _jsxs("label", { children: [copy.decision, _jsxs("select", { value: editing.decision, onChange: (event) => setEditing({ ...editing, decision: event.target.value }), children: [_jsx("option", { value: ConsentDecisions.Permit, children: copy.permit }), _jsx("option", { value: ConsentDecisions.Deny, children: copy.deny })] })] }), _jsxs("label", { children: [copy.status, _jsxs("select", { value: editing.status, onChange: (event) => setEditing({ ...editing, status: event.target.value }), children: [_jsx("option", { value: ConsentStatuses.Active, children: copy.active }), _jsx("option", { value: ConsentStatuses.Inactive, children: copy.inactive })] })] }), _jsx(OptionGroup, { legend: copy.purposes, options: purposeOptions, selected: editing.purposes, onChange: (purposes) => setEditing({ ...editing, purposes }) }), _jsx(OptionGroup, { legend: copy.roles, options: roleOptions, selected: editing.roles, onChange: (roles) => setEditing({ ...editing, roles }) }), _jsx(OptionGroup, { legend: copy.targets, options: targetOptions, selected: editing.targets, onChange: (targets) => setEditing({ ...editing, targets }) }), _jsxs("div", { children: [_jsx("button", { type: "submit", disabled: saving, children: saving ? copy.saving : copy.save }), _jsx("button", { type: "button", onClick: () => setEditing(null), children: copy.cancel })] })] }) : null] });
46
+ }
47
+ function OptionGroup({ legend, options, selected, onChange }) {
48
+ return _jsxs("fieldset", { children: [_jsx("legend", { children: legend }), options.map((option) => _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: selected.includes(option.value), onChange: (event) => onChange(event.target.checked ? [...selected, option.value] : selected.filter((value) => value !== option.value)) }), option.label] }, option.value))] });
49
+ }
50
+ function emptyDraft() {
51
+ return Object.freeze({ contactReference: '', decision: ConsentDecisions.Permit, status: ConsentStatuses.Active, purposes: Object.freeze([]), roles: Object.freeze([]), targets: Object.freeze([]) });
52
+ }
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from './SubjectAccessRequestPanel.js';
18
18
  export * from './SoschainWorkspace.js';
19
19
  export * from './EncounterTransferConsole.js';
20
20
  export * from './EmergencyContactDirectory.js';
21
+ export * from './ConsentPermissionDirectory.js';
21
22
  export * from './OrganizationWorkforceAdministration.js';
22
23
  export * from './ProtectedIndexEmergencyData.js';
23
24
  export * from './PortalSettingsPanel.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,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,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,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"}
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ export * from './SubjectAccessRequestPanel.js';
18
18
  export * from './SoschainWorkspace.js';
19
19
  export * from './EncounterTransferConsole.js';
20
20
  export * from './EmergencyContactDirectory.js';
21
+ export * from './ConsentPermissionDirectory.js';
21
22
  export * from './OrganizationWorkforceAdministration.js';
22
23
  export * from './ProtectedIndexEmergencyData.js';
23
24
  export * from './PortalSettingsPanel.js';
package/dist/styles.css CHANGED
@@ -638,4 +638,5 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
638
638
  @media (max-width: 620px) { .uhcp-emergency-copy > header { display: grid; } .uhcp-emergency-copy-legend { width: 100%; } }
639
639
  .uhcp-settings{max-width:72rem;margin:0 auto;padding:2rem 1rem 4rem;display:grid;gap:1rem}.uhcp-settings>header,.uhcp-settings>section{background:var(--uhcp-surface,#fff);border:1px solid var(--uhcp-border,#dbe4ea);border-radius:1rem;padding:1.25rem}.uhcp-settings h1,.uhcp-settings h2{margin-top:0}.uhcp-settings fieldset{border:0;padding:0;margin:1rem 0;display:flex;gap:.5rem;flex-wrap:wrap}.uhcp-settings legend{width:100%;font-weight:700;margin-bottom:.5rem}.uhcp-settings button,.uhcp-settings-links a{border:1px solid var(--uhcp-border,#c9d7df);border-radius:.7rem;background:transparent;color:inherit;padding:.65rem .85rem;text-decoration:none}.uhcp-settings button[aria-pressed=true]{background:var(--uhcp-accent,#dceff7);border-color:var(--uhcp-accent-strong,#2489a7)}.uhcp-settings-links{display:flex;gap:.6rem;flex-wrap:wrap}
640
640
  .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
+ .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}}
641
642
  .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}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uhc-portal-components-react",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
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",