uhc-portal-components-react 0.2.3 → 0.2.5

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,21 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.2.5 - 2026-10-09
6
+
7
+ - Render the protected organization target on a neutral light/dark panel with
8
+ its logo at the left and its role, legal context and selectable sector badge
9
+ in one readable stack at the right.
10
+
11
+ ## 0.2.4 - 2026-10-09
12
+
13
+ - Lead the protected-profile card with the unlock task, center the selected
14
+ sector context and place passkey/PIN controls immediately after it without
15
+ repeating a visible "profile to unlock" eyebrow.
16
+ - Add host-customizable selected, unlock and alternative action tokens so
17
+ portals can distinguish blue selection, orange unlock and recovery actions
18
+ consistently in light and dark themes.
19
+
5
20
  ## 0.2.3 - 2026-10-09
6
21
 
7
22
  - Keep the section-removal action at the far edge of its section while still
@@ -1 +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"}
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,+BAwH9B"}
@@ -79,5 +79,5 @@ export function ProfileProtectionGateV2({ state, target, copy, onUnlock, onPassk
79
79
  : state === 'unavailable'
80
80
  ? copy.unavailableBody
81
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 })] }));
82
+ return (_jsxs("section", { className: "uhcp-profile-gate uhcp-profile-gate-v2", "aria-live": "polite", children: [_jsxs("div", { className: "uhcp-profile-gate-copy", children: [_jsx("h1", { children: title }), _jsx("p", { children: body })] }), _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-content", children: [_jsxs("div", { className: "uhcp-profile-target-copy", children: [_jsx("strong", { children: target.title }), target.subtitle && _jsx("span", { children: target.subtitle })] }), target.badges?.length ? _jsx("ul", { className: "uhcp-profile-target-badges uhcp-profile-target-badges-centered", "aria-label": target.title, 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] })] }), state === 'locked' && onPasskeyUnlock && _jsx("button", { type: "button", className: "uhcp-action-unlock", "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", className: "uhcp-action-unlock", "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
83
  }
package/dist/styles.css CHANGED
@@ -13,6 +13,12 @@
13
13
  /* Intentionally invariant across light/dark, matching UHC Personal. */
14
14
  --uhcp-action-start: hsl(184 74% 34% / .96);
15
15
  --uhcp-action-end: hsl(214 70% 42% / .9);
16
+ --uhcp-selected-start: var(--uhcp-action-start);
17
+ --uhcp-selected-end: var(--uhcp-action-end);
18
+ --uhcp-unlock-start: hsl(28 91% 57%);
19
+ --uhcp-unlock-end: hsl(21 86% 48%);
20
+ --uhcp-unlock-text: #fff;
21
+ --uhcp-alternative: color-mix(in srgb, var(--uhcp-attention) 22%, var(--uhcp-panel));
16
22
  }
17
23
  html[data-density='small'] { font-size: 15px; }
18
24
  html[data-density='medium'] { font-size: 16px; }
@@ -161,24 +167,36 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
161
167
  .uhcp-profile-gate label { color: var(--uhcp-muted); display: grid; gap: .45rem; }
162
168
  .uhcp-profile-gate input { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: .75rem; color: var(--uhcp-text); padding: .8rem; }
163
169
  .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; }
170
+ .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; transition: background .18s ease, border-color .18s ease, box-shadow .18s ease; }
171
+ .uhcp-profile-gate-v2:is(:hover, :focus-within) { background: linear-gradient(145deg, color-mix(in srgb, var(--uhcp-surface-accent) 62%, var(--uhcp-panel)), color-mix(in srgb, var(--uhcp-selected-start) 12%, var(--uhcp-panel-muted))); border-color: color-mix(in srgb, var(--uhcp-selected-start) 50%, var(--uhcp-border)); box-shadow: 0 1.3rem 3.2rem color-mix(in srgb, var(--uhcp-selected-start) 18%, transparent); }
172
+ .uhcp-profile-gate-copy { text-align: center; }
173
+ .uhcp-profile-gate-copy h1, .uhcp-profile-gate-copy p { margin: 0; }
174
+ .uhcp-profile-gate-copy p { margin-top: .45rem; }
175
+ .uhcp-profile-target { align-items: center; background: var(--uhcp-panel); border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 32%, var(--uhcp-border)); border-radius: 1rem; display: grid; gap: 1rem; grid-template-columns: auto minmax(0, 1fr); padding: 1rem; }
176
+ .uhcp-profile-target > img { background: var(--uhcp-panel); border-radius: .75rem; object-fit: contain; }
177
+ .uhcp-profile-target-content { display: grid; gap: .65rem; min-width: 0; }
178
+ .uhcp-profile-target-copy { display: grid; gap: .2rem; text-align: left; }
168
179
  .uhcp-profile-target-copy > strong { color: var(--uhcp-text); font-size: 1.2rem; }
169
180
  .uhcp-profile-target-copy > span:last-child { color: var(--uhcp-muted); }
170
181
  .uhcp-profile-target-eyebrow { color: var(--uhcp-muted); font-size: .78rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
171
182
  .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; }
183
+ .uhcp-profile-target-badges-centered { justify-content: flex-start; }
184
+ .uhcp-profile-target-badges li { background: linear-gradient(135deg, var(--uhcp-selected-start), var(--uhcp-selected-end)); border: 1px solid transparent; border-radius: 999px; color: #fff; padding: .35rem .65rem; }
185
+ .uhcp-profile-gate .uhcp-action-unlock { background: linear-gradient(135deg, var(--uhcp-unlock-start), var(--uhcp-unlock-end)); color: var(--uhcp-unlock-text); }
173
186
  .uhcp-profile-target-details { margin: 0; }
174
187
  .uhcp-profile-target-details > div { display: grid; gap: .2rem; grid-template-columns: minmax(8rem, auto) 1fr; }
175
188
  .uhcp-profile-target-details dt { color: var(--uhcp-muted); }
176
189
  .uhcp-profile-target-details dd { color: var(--uhcp-text); font-weight: 700; margin: 0; }
190
+ @media (max-width: 34rem) {
191
+ .uhcp-profile-target { grid-template-columns: 1fr; justify-items: center; }
192
+ .uhcp-profile-target-content, .uhcp-profile-target-copy { text-align: center; width: 100%; }
193
+ .uhcp-profile-target-badges-centered { justify-content: center; }
194
+ }
177
195
  .uhcp-profile-pin-fallback { border-top: 1px solid var(--uhcp-border); padding-top: .8rem; }
178
196
  .uhcp-profile-pin-fallback summary { color: var(--uhcp-text); cursor: pointer; font-weight: 700; }
179
197
  .uhcp-profile-pin-fallback form { margin-top: .8rem; }
180
198
  .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); }
199
+ .uhcp-profile-pin-recovery button { background: var(--uhcp-alternative); border: 1px solid color-mix(in srgb, var(--uhcp-attention) 48%, var(--uhcp-border)); color: var(--uhcp-text); }
182
200
  .uhcp-profile-gate-secondary { border-top: 1px solid var(--uhcp-border); display: grid; gap: .6rem; padding-top: .8rem; }
183
201
  .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
202
  .uhcp-profile-gate-secondary .uhcp-add-profile-action::first-letter { color: var(--uhcp-turquoise); font-size: 1.25em; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uhc-portal-components-react",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
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",