uhc-portal-components-react 0.2.31 → 0.2.32

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,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.32 - 2026-10-23
4
+
5
+ - Export the product-neutral subject communication composer so Emergency,
6
+ Personal and Professional screens submit through the same accessible UI
7
+ while their BFF adapters retain recipient and delivery authority.
8
+
3
9
  ## 0.2.31 - 2026-10-23
4
10
 
5
11
  - Add one concise, accessible `Sections` index for Personal portals so card,
@@ -35,4 +35,8 @@ export declare function SubjectCommunicationCenter({ subjectLabel, items, copy,
35
35
  copy?: SubjectCommunicationCenterCopy;
36
36
  composer?: SubjectCommunicationComposer;
37
37
  }>): import("react").JSX.Element;
38
+ /** Reusable message composer; product BFF adapters retain delivery authority. */
39
+ export declare function SubjectCommunicationComposerPanel({ composer }: Readonly<{
40
+ composer: SubjectCommunicationComposer;
41
+ }>): import("react").JSX.Element;
38
42
  //# sourceMappingURL=SubjectCommunicationCenter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubjectCommunicationCenter.d.ts","sourceRoot":"","sources":["../src/SubjectCommunicationCenter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAA;AAEzD,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,CAAA;AACxG,MAAM,MAAM,4BAA4B,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAA;AACzE,MAAM,MAAM,0BAA0B,GAAG,KAAK,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,CAAA;AAEnF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,wBAAwB,CAAA;IAC9B,QAAQ,EAAE,4BAA4B,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAA;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAC,CAAA;AAEF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,QAAQ,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClC,CAAC,CAAA;AAEF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;IACrC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAA;IAC7D,KAAK,EAAE,MAAM,CAAA;CACd,CAAC,CAAA;AAUF,6FAA6F;AAC7F,wBAAgB,0BAA0B,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,IAAmB,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IAC1G,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,SAAS,wBAAwB,EAAE,CAAA;IAC1C,IAAI,CAAC,EAAE,8BAA8B,CAAA;IACrC,QAAQ,CAAC,EAAE,4BAA4B,CAAA;CACxC,CAAC,+BAgDD"}
1
+ {"version":3,"file":"SubjectCommunicationCenter.d.ts","sourceRoot":"","sources":["../src/SubjectCommunicationCenter.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA4B,MAAM,OAAO,CAAA;AAEhE,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,CAAA;AACxG,MAAM,MAAM,4BAA4B,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAA;AACzE,MAAM,MAAM,0BAA0B,GAAG,KAAK,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,CAAA;AAEnF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,wBAAwB,CAAA;IAC9B,QAAQ,EAAE,4BAA4B,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAA;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAC,CAAA;AAEF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,QAAQ,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClC,CAAC,CAAA;AAEF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAA;IACrC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAA;IAC7D,KAAK,EAAE,MAAM,CAAA;CACd,CAAC,CAAA;AAUF,6FAA6F;AAC7F,wBAAgB,0BAA0B,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,IAAmB,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IAC1G,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,SAAS,wBAAwB,EAAE,CAAA;IAC1C,IAAI,CAAC,EAAE,8BAA8B,CAAA;IACrC,QAAQ,CAAC,EAAE,4BAA4B,CAAA;CACxC,CAAC,+BA2BD;AAED,iFAAiF;AACjF,wBAAgB,iCAAiC,CAAC,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IACvE,QAAQ,EAAE,4BAA4B,CAAA;CACvC,CAAC,+BAwBD"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo, useState } from 'react';
2
+ import { useId, useMemo, useState } from 'react';
3
3
  const DEFAULT_COPY = {
4
4
  heading: subjectLabel => `Communications for ${subjectLabel}`,
5
5
  filters: { all: 'All', messages: 'Messages', calls: 'Calls', emergency: 'Emergency' },
@@ -9,16 +9,21 @@ const FILTERS = ['all', 'messages', 'calls', 'emergency'];
9
9
  /** Brand-neutral, subject-scoped message and internet-call timeline for personal portals. */
10
10
  export function SubjectCommunicationCenter({ subjectLabel, items, copy = DEFAULT_COPY, composer }) {
11
11
  const [filter, setFilter] = useState('all');
12
- const [draft, setDraft] = useState('');
13
12
  const visibleItems = useMemo(() => items.filter(item => matchesFilter(item, filter)), [filter, items]);
14
- return _jsxs("section", { className: "subject-communication-center", "aria-labelledby": "subject-communication-center-title", children: [_jsx("h2", { id: "subject-communication-center-title", children: copy.heading(subjectLabel) }), _jsx("div", { className: "subject-communication-filters", "aria-label": copy.heading(subjectLabel), children: FILTERS.map(value => _jsx("button", { type: "button", "aria-pressed": filter === value, onClick: () => setFilter(value), children: copy.filters[value] }, value)) }), visibleItems.length === 0 ? _jsx("p", { className: "subject-communication-empty", children: copy.empty }) : _jsx("ol", { className: "subject-communication-list", role: "log", children: visibleItems.map(item => _jsxs("li", { "data-kind": item.kind, "data-category": item.category, "data-direction": item.direction || 'system', children: [item.avatarUrl ? _jsx("img", { className: "subject-communication-avatar", src: item.avatarUrl, alt: item.senderLabel || item.title }) : null, _jsxs("div", { className: "subject-communication-bubble", children: [item.senderLabel ? _jsx("span", { className: "subject-communication-sender", children: item.senderLabel }) : null, _jsx("strong", { children: item.title }), item.summary ? _jsx("p", { children: item.summary }) : null] }), _jsxs("div", { className: "subject-communication-meta", children: [item.timestamp ? _jsx("time", { dateTime: item.timestamp, children: item.timestamp }) : null, item.status ? _jsx("span", { children: item.status }) : null, item.action] })] }, item.id)) }), composer ? _jsxs("form", { className: "subject-communication-composer", onSubmit: event => {
15
- event.preventDefault();
16
- const text = draft.trim();
17
- if (!text || composer.disabled)
18
- return;
19
- void composer.onSend(text);
20
- setDraft('');
21
- }, children: [_jsx("label", { className: "subject-communication-composer-label", htmlFor: "subject-communication-composer-input", children: composer.placeholder }), _jsx("textarea", { id: "subject-communication-composer-input", "aria-label": composer.placeholder, placeholder: composer.placeholder, value: draft, disabled: composer.disabled, onChange: event => setDraft(event.target.value) }), _jsxs("div", { className: "subject-communication-composer-actions", children: [composer.onAttach && composer.attachLabel ? _jsx("button", { type: "button", disabled: composer.disabled, onClick: () => void composer.onAttach?.(), children: composer.attachLabel }) : null, _jsx("button", { type: "submit", disabled: composer.disabled || !draft.trim(), children: composer.sendLabel })] })] }) : null] });
13
+ return _jsxs("section", { className: "subject-communication-center", "aria-labelledby": "subject-communication-center-title", children: [_jsx("h2", { id: "subject-communication-center-title", children: copy.heading(subjectLabel) }), _jsx("div", { className: "subject-communication-filters", "aria-label": copy.heading(subjectLabel), children: FILTERS.map(value => _jsx("button", { type: "button", "aria-pressed": filter === value, onClick: () => setFilter(value), children: copy.filters[value] }, value)) }), visibleItems.length === 0 ? _jsx("p", { className: "subject-communication-empty", children: copy.empty }) : _jsx("ol", { className: "subject-communication-list", role: "log", children: visibleItems.map(item => _jsxs("li", { "data-kind": item.kind, "data-category": item.category, "data-direction": item.direction || 'system', children: [item.avatarUrl ? _jsx("img", { className: "subject-communication-avatar", src: item.avatarUrl, alt: item.senderLabel || item.title }) : null, _jsxs("div", { className: "subject-communication-bubble", children: [item.senderLabel ? _jsx("span", { className: "subject-communication-sender", children: item.senderLabel }) : null, _jsx("strong", { children: item.title }), item.summary ? _jsx("p", { children: item.summary }) : null] }), _jsxs("div", { className: "subject-communication-meta", children: [item.timestamp ? _jsx("time", { dateTime: item.timestamp, children: item.timestamp }) : null, item.status ? _jsx("span", { children: item.status }) : null, item.action] })] }, item.id)) }), composer ? _jsx(SubjectCommunicationComposerPanel, { composer: composer }) : null] });
14
+ }
15
+ /** Reusable message composer; product BFF adapters retain delivery authority. */
16
+ export function SubjectCommunicationComposerPanel({ composer }) {
17
+ const inputId = useId();
18
+ const [draft, setDraft] = useState('');
19
+ return _jsxs("form", { className: "subject-communication-composer", onSubmit: event => {
20
+ event.preventDefault();
21
+ const text = draft.trim();
22
+ if (!text || composer.disabled)
23
+ return;
24
+ void composer.onSend(text);
25
+ setDraft('');
26
+ }, children: [_jsx("label", { className: "subject-communication-composer-label", htmlFor: inputId, children: composer.placeholder }), _jsx("textarea", { id: inputId, "aria-label": composer.placeholder, placeholder: composer.placeholder, value: draft, disabled: composer.disabled, onChange: event => setDraft(event.target.value) }), _jsxs("div", { className: "subject-communication-composer-actions", children: [composer.onAttach && composer.attachLabel ? _jsx("button", { type: "button", disabled: composer.disabled, onClick: () => void composer.onAttach?.(), children: composer.attachLabel }) : null, _jsx("button", { type: "submit", disabled: composer.disabled || !draft.trim(), children: composer.sendLabel })] })] });
22
27
  }
23
28
  function matchesFilter(item, filter) {
24
29
  if (filter === 'all')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uhc-portal-components-react",
3
- "version": "0.2.31",
3
+ "version": "0.2.32",
4
4
  "description": "Brand-neutral React portal screens, account preferences and protected-profile UI.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -22,7 +22,7 @@
22
22
  "clean": "rm -rf dist",
23
23
  "build": "npm run clean && tsc && cp src/styles.css dist/styles.css",
24
24
  "typecheck": "tsc --noEmit",
25
- "test": "vitest run",
25
+ "test": "vitest run --maxWorkers=1",
26
26
  "check": "npm run typecheck && npm test && npm run build",
27
27
  "prepack": "npm run check"
28
28
  },