@redacto.io/consent-sdk-react 11.0.0 → 11.1.0-beta.1

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/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
- import { A as AppearanceStyle, N as NoticeControlStyle, a as NoticeMobileLayout, b as NoticeDesktopPosition, c as NoticeBackdrop, d as NoticePhoneFooter, e as NoticeTextScale, f as NoticeAppearance } from './types-B8qroG0j.mjs';
3
+ import { A as AppearanceStyle, N as NoticeControlStyle, a as NoticeMobileLayout, b as NoticeDesktopPosition, c as NoticeBackdrop, d as NoticePhoneFooter, e as NoticeTextScale, f as NoticeAppearance } from './types-CaqLBkJt.mjs';
4
4
  import { f as NoticeFontOptions } from './types-xaCyZUfo.mjs';
5
5
 
6
6
  /**
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
- import { A as AppearanceStyle, N as NoticeControlStyle, a as NoticeMobileLayout, b as NoticeDesktopPosition, c as NoticeBackdrop, d as NoticePhoneFooter, e as NoticeTextScale, f as NoticeAppearance } from './types-B8qroG0j.js';
3
+ import { A as AppearanceStyle, N as NoticeControlStyle, a as NoticeMobileLayout, b as NoticeDesktopPosition, c as NoticeBackdrop, d as NoticePhoneFooter, e as NoticeTextScale, f as NoticeAppearance } from './types-CaqLBkJt.js';
4
4
  import { f as NoticeFontOptions } from './types-xaCyZUfo.js';
5
5
 
6
6
  /**
package/dist/index.js CHANGED
@@ -1505,6 +1505,8 @@ var PREVIEW_FRAME_STYLE = {
1505
1505
  var LAYOUT_STYLE_ID = "redacto-notice-layout-styles";
1506
1506
  var DOCK_ATTRIBUTE = "data-redacto-sheet";
1507
1507
  var DOCKED = "dock";
1508
+ var PREVIEW_ATTRIBUTE = "data-redacto-preview";
1509
+ var PREVIEWED = "frame";
1508
1510
  var MOTION_ATTRIBUTE = "data-redacto-motion";
1509
1511
  var MOTION_OFF = "off";
1510
1512
  var NOTICE_ID_ATTRIBUTE = "data-redacto-notice-id";
@@ -1582,7 +1584,7 @@ var styles = {
1582
1584
  border: "none",
1583
1585
  display: "flex",
1584
1586
  flexDirection: "column",
1585
- maxHeight: "90vh",
1587
+ maxHeight: "90%",
1586
1588
  zIndex: 1e3,
1587
1589
  margin: 0,
1588
1590
  padding: 0,
@@ -1963,7 +1965,14 @@ var styles = {
1963
1965
  lineHeight: "150%",
1964
1966
  letterSpacing: "0.2px",
1965
1967
  cursor: "pointer",
1966
- margin: 0,
1968
+ // Longhands, not the `margin` shorthand: `declineSpacer` spreads
1969
+ // `marginRight` over this on the wide row only, and React clears a
1970
+ // longhand that sits beside a shorthand when a render drops it, which
1971
+ // leaves the value order-dependent.
1972
+ marginTop: 0,
1973
+ marginRight: 0,
1974
+ marginBottom: 0,
1975
+ marginLeft: 0,
1967
1976
  boxSizing: "border-box",
1968
1977
  textAlign: "center",
1969
1978
  fontFamily: "inherit"
@@ -3829,10 +3838,12 @@ var FLOAT_FRAMES_STILL = `
3829
3838
  var floatKeyframes = (frames) => [NOTICE_KEYFRAMES.float, NOTICE_KEYFRAMES.floatPill].map((name) => `@keyframes ${name} {${frames}
3830
3839
  }`).join("\n");
3831
3840
  var css = `
3832
- /* dvh tracks the phone's collapsing toolbars; vh stays inline as the
3833
- fallback for browsers without it. */
3841
+ /* dvh tracks the phone's collapsing toolbars; the inline percentage stays
3842
+ as the fallback for browsers without it. Never in the console preview:
3843
+ there the frame is the containing block the inline cap is measured
3844
+ against, and a viewport unit would overrule it with the window's height. */
3834
3845
  @supports (height: 100dvh) {
3835
- ${N}[${DOCK_ATTRIBUTE}="${DOCKED}"] {
3846
+ ${N}[${DOCK_ATTRIBUTE}="${DOCKED}"]:not([${PREVIEW_ATTRIBUTE}]) {
3836
3847
  max-height: 92dvh !important;
3837
3848
  }
3838
3849
  }
@@ -4074,7 +4085,7 @@ var modalPosition = ({
4074
4085
  if (isMobile) {
4075
4086
  return layout.mobileSheet ? {
4076
4087
  ...edgeDock(radius),
4077
- maxHeight: "92vh",
4088
+ maxHeight: "92%",
4078
4089
  paddingBottom: "env(safe-area-inset-bottom, 0px)"
4079
4090
  } : {};
4080
4091
  }
@@ -4087,7 +4098,7 @@ var modalPosition = ({
4087
4098
  case "bottom-bar":
4088
4099
  return {
4089
4100
  ...edgeDock(radius),
4090
- maxHeight: "70vh",
4101
+ maxHeight: "70%",
4091
4102
  paddingLeft: `max(0px, calc((100% - ${BOTTOM_BAR_CONTENT_WIDTH}) / 2))`,
4092
4103
  paddingRight: `max(0px, calc((100% - ${BOTTOM_BAR_CONTENT_WIDTH}) / 2))`
4093
4104
  };
@@ -4308,7 +4319,7 @@ var stylePatch = (p, {
4308
4319
  ...blur,
4309
4320
  border: `1px solid ${p.sheetEdge}`,
4310
4321
  boxShadow: docked ? p.shadow : p.floatShadow,
4311
- maxHeight: "85vh",
4322
+ maxHeight: "85%",
4312
4323
  overflow: "hidden",
4313
4324
  animation: `${NOTICE_KEYFRAMES.float} ${MOTION.dimMs}ms ${MOTION.outEase} both`
4314
4325
  },
@@ -5293,6 +5304,8 @@ var PurposeItem = ({
5293
5304
  initialDataElementSelections = {},
5294
5305
  controlSkin,
5295
5306
  rowClassName,
5307
+ showsDataElements = true,
5308
+ descriptionPlacement = "always",
5296
5309
  animateDisclosure = false
5297
5310
  }) => {
5298
5311
  var _a, _b;
@@ -5318,11 +5331,31 @@ var PurposeItem = ({
5318
5331
  }),
5319
5332
  [settings == null ? void 0 : settings.textColor]
5320
5333
  );
5321
- const dataElementsOpen = !collapsedPurposes[stateKey] && Boolean(purpose.data_elements) && purpose.data_elements.length > 0;
5334
+ const hasDataElements = showsDataElements && Boolean(purpose.data_elements) && purpose.data_elements.length > 0;
5335
+ const descriptionText = getTranslatedText(
5336
+ `purposes.description`,
5337
+ purpose.description,
5338
+ purpose.uuid
5339
+ );
5340
+ const disclosesDescription = descriptionPlacement === "expanded" && descriptionText.trim() !== "";
5341
+ const hasDisclosure = hasDataElements || disclosesDescription;
5342
+ const dataElementsOpen = !collapsedPurposes[stateKey] && hasDisclosure;
5343
+ const purposeDescription = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5344
+ "h3",
5345
+ {
5346
+ id: `purpose-description-${stateKey}`,
5347
+ style: {
5348
+ ...styles4.optionDescription,
5349
+ ...responsiveStyles.optionDescription,
5350
+ ...textStyle
5351
+ },
5352
+ children: descriptionText
5353
+ },
5354
+ `purpose-description-${purpose.uuid}-${selectedLanguage}`
5355
+ );
5322
5356
  const dataElements = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5323
5357
  "div",
5324
5358
  {
5325
- id: `purpose-${purpose.uuid}`,
5326
5359
  style: {
5327
5360
  ...styles4.dataElementsContainer,
5328
5361
  ...roomyControls ? styles4.dataElementsContainerRoomy : null
@@ -5442,30 +5475,36 @@ var PurposeItem = ({
5442
5475
  },
5443
5476
  `purpose-${purpose.uuid}-container-${selectedLanguage}`
5444
5477
  );
5478
+ const disclosureContents = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5479
+ disclosesDescription && purposeDescription,
5480
+ hasDataElements && dataElements
5481
+ ] });
5445
5482
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: rowClassName, children: [
5446
5483
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ...PART_PROPS.purpose, style: styles4.optionItem, children: [
5447
5484
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5448
5485
  "div",
5449
5486
  {
5450
5487
  style: styles4.optionLeft,
5451
- onClick: () => onPurposeCollapse(purpose.uuid, productUuid),
5452
- role: "button",
5453
- tabIndex: 0,
5454
- "aria-expanded": !collapsedPurposes[stateKey],
5455
- "aria-controls": `purpose-${purpose.uuid}`,
5456
- "aria-label": `${collapsedPurposes[stateKey] ? "Expand" : "Collapse"} ${getTranslatedText(
5457
- `purposes.name`,
5458
- purpose.name,
5459
- purpose.uuid
5460
- )} details`,
5461
- onKeyDown: (e) => {
5462
- if (e.key === "Enter" || e.key === " ") {
5463
- e.preventDefault();
5464
- onPurposeCollapse(purpose.uuid, productUuid);
5488
+ ...hasDisclosure && {
5489
+ onClick: () => onPurposeCollapse(purpose.uuid, productUuid),
5490
+ role: "button",
5491
+ tabIndex: 0,
5492
+ "aria-expanded": !collapsedPurposes[stateKey],
5493
+ "aria-controls": `purpose-${purpose.uuid}`,
5494
+ "aria-label": `${collapsedPurposes[stateKey] ? "Expand" : "Collapse"} ${getTranslatedText(
5495
+ `purposes.name`,
5496
+ purpose.name,
5497
+ purpose.uuid
5498
+ )} details`,
5499
+ onKeyDown: (e) => {
5500
+ if (e.key === "Enter" || e.key === " ") {
5501
+ e.preventDefault();
5502
+ onPurposeCollapse(purpose.uuid, productUuid);
5503
+ }
5465
5504
  }
5466
5505
  },
5467
5506
  children: [
5468
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5507
+ hasDisclosure && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5469
5508
  CollapseChevron,
5470
5509
  {
5471
5510
  open: !collapsedPurposes[stateKey],
@@ -5490,23 +5529,7 @@ var PurposeItem = ({
5490
5529
  },
5491
5530
  `purpose-name-${purpose.uuid}-${selectedLanguage}`
5492
5531
  ),
5493
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5494
- "h3",
5495
- {
5496
- id: `purpose-description-${stateKey}`,
5497
- style: {
5498
- ...styles4.optionDescription,
5499
- ...responsiveStyles.optionDescription,
5500
- ...textStyle
5501
- },
5502
- children: getTranslatedText(
5503
- `purposes.description`,
5504
- purpose.description,
5505
- purpose.uuid
5506
- )
5507
- },
5508
- `purpose-description-${purpose.uuid}-${selectedLanguage}`
5509
- )
5532
+ descriptionPlacement === "always" && purposeDescription
5510
5533
  ] })
5511
5534
  ]
5512
5535
  }
@@ -5532,7 +5555,13 @@ var PurposeItem = ({
5532
5555
  }
5533
5556
  )
5534
5557
  ] }),
5535
- animateDisclosure ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Collapse, { open: dataElementsOpen, children: dataElements }) : dataElementsOpen && dataElements
5558
+ hasDisclosure && (animateDisclosure ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Collapse, { open: dataElementsOpen, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { id: `purpose-${purpose.uuid}`, children: disclosureContents }) }) : (
5559
+ // The container is always drawn, empty while the row is closed:
5560
+ // `aria-controls` on the chevron names it, and a control that points
5561
+ // at an element which is not in the document is worse than no
5562
+ // control at all.
5563
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { id: `purpose-${purpose.uuid}`, children: dataElementsOpen && disclosureContents })
5564
+ ))
5536
5565
  ] }, purpose.uuid);
5537
5566
  };
5538
5567
  var RELATIONSHIP_OPTIONS = [
@@ -6450,7 +6479,7 @@ var NoticeConsentView = ({
6450
6479
  forceMobile,
6451
6480
  forceColorScheme
6452
6481
  }) => {
6453
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L;
6482
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M;
6454
6483
  const endpoints = useResolvedEndpoints(baseUrlProp, ledgerBaseUrlProp, {
6455
6484
  warn: !previewContent
6456
6485
  });
@@ -6527,6 +6556,9 @@ var NoticeConsentView = ({
6527
6556
  }, [noticeId]);
6528
6557
  const servedAppearance = content ? content.appearance : cachedAppearance;
6529
6558
  const showsProductSection = (servedAppearance == null ? void 0 : servedAppearance.show_product_section) !== false;
6559
+ const showsDataElements = (servedAppearance == null ? void 0 : servedAppearance.show_data_elements) !== false;
6560
+ const descriptionPlacement = (_a = servedAppearance == null ? void 0 : servedAppearance.purpose_description) != null ? _a : "always";
6561
+ const showsPurposeSectionHeading = (servedAppearance == null ? void 0 : servedAppearance.show_purpose_section_heading) !== false;
6530
6562
  const noticeAppearance = useNoticeAppearance(
6531
6563
  servedAppearance,
6532
6564
  settings,
@@ -6715,8 +6747,8 @@ var NoticeConsentView = ({
6715
6747
  const docked = isDocked(layout, isMobile);
6716
6748
  const headingColor = (noticeSettings == null ? void 0 : noticeSettings.headingColor) || DEFAULT_HEADING_COLOR;
6717
6749
  const textColor = (noticeSettings == null ? void 0 : noticeSettings.textColor) || DEFAULT_TEXT_COLOR;
6718
- const classicAccentColor = ((_b = (_a = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || (content == null ? void 0 : content.primary_color) || (content ? DEFAULT_ACCENT_COLOR : headingColor);
6719
- const accentColor = (_e = appearanceColors.toggle_on) != null ? _e : hasNoticeSkin(appearance) ? ((_d = (_c = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _c.acceptAll) == null ? void 0 : _d.backgroundColor) || classicAccentColor : classicAccentColor;
6750
+ const classicAccentColor = ((_c = (_b = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _b.accept) == null ? void 0 : _c.backgroundColor) || (content == null ? void 0 : content.primary_color) || (content ? DEFAULT_ACCENT_COLOR : headingColor);
6751
+ const accentColor = (_f = appearanceColors.toggle_on) != null ? _f : hasNoticeSkin(appearance) ? ((_e = (_d = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _d.acceptAll) == null ? void 0 : _e.backgroundColor) || classicAccentColor : classicAccentColor;
6720
6752
  const variantStyles = (0, import_react9.useMemo)(
6721
6753
  () => buildVariantStyles(
6722
6754
  styles,
@@ -6750,7 +6782,7 @@ var NoticeConsentView = ({
6750
6782
  docked
6751
6783
  ]
6752
6784
  );
6753
- const textScale = NOTICE_TEXT_SCALE_FACTORS[(_f = noticeAppearance.textScale) != null ? _f : DEFAULT_TEXT_SCALE];
6785
+ const textScale = NOTICE_TEXT_SCALE_FACTORS[(_g = noticeAppearance.textScale) != null ? _g : DEFAULT_TEXT_SCALE];
6754
6786
  const styles4 = (0, import_react9.useMemo)(
6755
6787
  () => {
6756
6788
  var _a2;
@@ -6815,7 +6847,7 @@ var NoticeConsentView = ({
6815
6847
  ...otpLocked && styles4.otpGateLocked
6816
6848
  };
6817
6849
  const drawsSwitches = layout.switchControl;
6818
- const roomyControls = drawsSwitches || ((_g = noticeSettings == null ? void 0 : noticeSettings.selectionControl) != null ? _g : DEFAULT_SELECTION_CONTROL) !== "checkbox";
6850
+ const roomyControls = drawsSwitches || ((_h = noticeSettings == null ? void 0 : noticeSettings.selectionControl) != null ? _h : DEFAULT_SELECTION_CONTROL) !== "checkbox";
6819
6851
  const appearanceRootProps = {
6820
6852
  [NOTICE_ROOT_ATTRIBUTE]: "",
6821
6853
  [NOTICE_ID_ATTRIBUTE]: noticeId,
@@ -8187,7 +8219,7 @@ var NoticeConsentView = ({
8187
8219
  if (ttsAudioUrls.privacy_policy_anchor_text_audio_url) {
8188
8220
  sequence.push(ttsAudioUrls.privacy_policy_anchor_text_audio_url);
8189
8221
  }
8190
- if (ttsAudioUrls.purpose_section_heading_audio_url) {
8222
+ if (showsPurposeSectionHeading && ttsAudioUrls.purpose_section_heading_audio_url) {
8191
8223
  sequence.push(ttsAudioUrls.purpose_section_heading_audio_url);
8192
8224
  }
8193
8225
  const purposesToProcess = categorizedPurposes ? [
@@ -8203,12 +8235,12 @@ var NoticeConsentView = ({
8203
8235
  if ((_a2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _a2.name_audio_url) {
8204
8236
  sequence.push(ttsAudioUrls.purposes_audio[purpose.uuid].name_audio_url);
8205
8237
  }
8206
- if ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url) {
8238
+ if (descriptionPlacement !== "hidden" && ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url)) {
8207
8239
  sequence.push(
8208
8240
  ttsAudioUrls.purposes_audio[purpose.uuid].description_audio_url
8209
8241
  );
8210
8242
  }
8211
- if (purpose.data_elements && purpose.data_elements.length > 0) {
8243
+ if (showsDataElements && purpose.data_elements && purpose.data_elements.length > 0) {
8212
8244
  purpose.data_elements.forEach((dataElement) => {
8213
8245
  var _a3;
8214
8246
  if ((_a3 = ttsAudioUrls.data_elements_audio[dataElement.uuid]) == null ? void 0 : _a3.name_audio_url) {
@@ -8259,7 +8291,7 @@ var NoticeConsentView = ({
8259
8291
  if (ttsAudioUrls.privacy_policy_anchor_text_audio_url) {
8260
8292
  elementIds.push("privacy-policy-link");
8261
8293
  }
8262
- if (ttsAudioUrls.purpose_section_heading_audio_url) {
8294
+ if (showsPurposeSectionHeading && ttsAudioUrls.purpose_section_heading_audio_url) {
8263
8295
  elementIds.push("purpose-section-heading");
8264
8296
  }
8265
8297
  const purposesToProcess = categorizedPurposes ? [
@@ -8275,10 +8307,12 @@ var NoticeConsentView = ({
8275
8307
  if ((_a2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _a2.name_audio_url) {
8276
8308
  elementIds.push(`purpose-name-${purpose.uuid}`);
8277
8309
  }
8278
- if ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url) {
8279
- elementIds.push(`purpose-description-${purpose.uuid}`);
8310
+ if (descriptionPlacement !== "hidden" && ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url)) {
8311
+ elementIds.push(
8312
+ descriptionPlacement === "always" ? `purpose-description-${purpose.uuid}` : null
8313
+ );
8280
8314
  }
8281
- if (purpose.data_elements && purpose.data_elements.length > 0) {
8315
+ if (showsDataElements && purpose.data_elements && purpose.data_elements.length > 0) {
8282
8316
  purpose.data_elements.forEach((dataElement) => {
8283
8317
  var _a3;
8284
8318
  if ((_a3 = ttsAudioUrls.data_elements_audio[dataElement.uuid]) == null ? void 0 : _a3.name_audio_url) {
@@ -8525,20 +8559,20 @@ var NoticeConsentView = ({
8525
8559
  };
8526
8560
  const acceptAllButtonStyle = {
8527
8561
  ...buttonStyle2,
8528
- backgroundColor: ((_i = (_h = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _h.acceptAll) == null ? void 0 : _i.backgroundColor) || ((_k = (_j = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _j.accept) == null ? void 0 : _k.backgroundColor) || (content == null ? void 0 : content.primary_color) || "#4f87ff",
8529
- color: ((_m = (_l = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _l.acceptAll) == null ? void 0 : _m.textColor) || ((_o = (_n = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _n.accept) == null ? void 0 : _o.textColor) || "#ffffff"
8562
+ backgroundColor: ((_j = (_i = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _i.acceptAll) == null ? void 0 : _j.backgroundColor) || ((_l = (_k = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _k.accept) == null ? void 0 : _l.backgroundColor) || (content == null ? void 0 : content.primary_color) || "#4f87ff",
8563
+ color: ((_n = (_m = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _m.acceptAll) == null ? void 0 : _n.textColor) || ((_p = (_o = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _o.accept) == null ? void 0 : _p.textColor) || "#ffffff"
8530
8564
  };
8531
8565
  const acceptSelectedButtonStyle = {
8532
8566
  ...buttonStyle2,
8533
- backgroundColor: (_p = appearanceColors.accept_bg) != null ? _p : skin ? skin.palette.accentWash : "#ffffff",
8534
- color: (_q = appearanceColors.accept_text) != null ? _q : accentColor,
8535
- borderColor: skin ? "transparent" : (_r = appearanceColors.accept_text) != null ? _r : accentColor
8567
+ backgroundColor: (_q = appearanceColors.accept_bg) != null ? _q : skin ? skin.palette.accentWash : "#ffffff",
8568
+ color: (_r = appearanceColors.accept_text) != null ? _r : accentColor,
8569
+ borderColor: skin ? "transparent" : (_s = appearanceColors.accept_text) != null ? _s : accentColor
8536
8570
  };
8537
8571
  const declineButtonStyle = {
8538
8572
  ...buttonStyle2,
8539
- backgroundColor: ((_t = (_s = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _s.decline) == null ? void 0 : _t.backgroundColor) || (skin ? "transparent" : "#ffffff"),
8540
- color: ((_v = (_u = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _u.decline) == null ? void 0 : _v.textColor) || (skin ? textColor : "#000000"),
8541
- borderColor: (_w = appearanceColors.decline_border) != null ? _w : (noticeSettings == null ? void 0 : noticeSettings.borderColor) || (skin ? skin.palette.outline : "#d0d5dd")
8573
+ backgroundColor: ((_u = (_t = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _t.decline) == null ? void 0 : _u.backgroundColor) || (skin ? "transparent" : "#ffffff"),
8574
+ color: ((_w = (_v = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _v.decline) == null ? void 0 : _w.textColor) || (skin ? textColor : "#000000"),
8575
+ borderColor: (_x = appearanceColors.decline_border) != null ? _x : (noticeSettings == null ? void 0 : noticeSettings.borderColor) || (skin ? skin.palette.outline : "#d0d5dd")
8542
8576
  };
8543
8577
  const confirmHint = (0, import_react9.useMemo)(() => {
8544
8578
  var _a2;
@@ -8619,7 +8653,7 @@ var NoticeConsentView = ({
8619
8653
  [content]
8620
8654
  );
8621
8655
  const showNoticePolicyLink = showsNoticePolicyLink(
8622
- (_y = (_x = content == null ? void 0 : content.products) == null ? void 0 : _x.length) != null ? _y : 0,
8656
+ (_z = (_y = content == null ? void 0 : content.products) == null ? void 0 : _y.length) != null ? _z : 0,
8623
8657
  productPolicyLinks.length
8624
8658
  );
8625
8659
  const handleAcceptAll = () => handleAccept("all");
@@ -8630,20 +8664,20 @@ var NoticeConsentView = ({
8630
8664
  const languageSelectorStyle = {
8631
8665
  borderRadius: hostRadius || styleRadii.button,
8632
8666
  borderColor: (noticeSettings == null ? void 0 : noticeSettings.borderColor) || (skin ? skin.palette.hairline : "#d0d5dd"),
8633
- backgroundColor: ((_A = (_z = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _z.language) == null ? void 0 : _A.backgroundColor) || (skin ? skin.palette.control : "#ffffff"),
8634
- color: ((_C = (_B = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _B.language) == null ? void 0 : _C.textColor) || (skin ? headingColor : "#344054")
8667
+ backgroundColor: ((_B = (_A = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _A.language) == null ? void 0 : _B.backgroundColor) || (skin ? skin.palette.control : "#ffffff"),
8668
+ color: ((_D = (_C = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _C.language) == null ? void 0 : _D.textColor) || (skin ? headingColor : "#344054")
8635
8669
  };
8636
8670
  const { borderRadius: _chipRadius, ...languageChipColors } = languageSelectorStyle;
8637
8671
  const languageMenuStyle = skin ? {
8638
- ...((_E = (_D = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _D.language) == null ? void 0 : _E.backgroundColor) && {
8672
+ ...((_F = (_E = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _E.language) == null ? void 0 : _F.backgroundColor) && {
8639
8673
  backgroundColor: noticeSettings.button.language.backgroundColor
8640
8674
  },
8641
8675
  color: languageSelectorStyle.color
8642
8676
  } : languageChipColors;
8643
8677
  const selectedLanguageItemStyle = {
8644
8678
  ...languageMenuStyle,
8645
- backgroundColor: ((_G = (_F = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _F.language) == null ? void 0 : _G.selectedBackgroundColor) || (skin ? skin.palette.accentWash : "#f3f4f6"),
8646
- color: ((_I = (_H = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _H.language) == null ? void 0 : _I.selectedTextColor) || (skin ? headingColor : "#344054"),
8679
+ backgroundColor: ((_H = (_G = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _G.language) == null ? void 0 : _H.selectedBackgroundColor) || (skin ? skin.palette.accentWash : "#f3f4f6"),
8680
+ color: ((_J = (_I = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _I.language) == null ? void 0 : _J.selectedTextColor) || (skin ? headingColor : "#344054"),
8647
8681
  fontWeight: 600
8648
8682
  };
8649
8683
  const isSectionOpen = (section) => openSections[section] || isTalkbackActive;
@@ -8823,6 +8857,7 @@ var NoticeConsentView = ({
8823
8857
  ...appearanceRootProps,
8824
8858
  ...PART_PROPS.root,
8825
8859
  ...docked && { [DOCK_ATTRIBUTE]: DOCKED },
8860
+ ...previewContent && { [PREVIEW_ATTRIBUTE]: PREVIEWED },
8826
8861
  style: isLoading && showsLoaderPill && skin ? (
8827
8862
  // The dialog itself shrinks to a pill until the notice
8828
8863
  // arrives, then grows into the sheet: one element, so the
@@ -9366,7 +9401,7 @@ var NoticeConsentView = ({
9366
9401
  `privacy-text-${selectedLanguage}`
9367
9402
  )
9368
9403
  ),
9369
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
9404
+ showsPurposeSectionHeading && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
9370
9405
  "h2",
9371
9406
  {
9372
9407
  id: "purpose-section-heading",
@@ -9389,6 +9424,8 @@ var NoticeConsentView = ({
9389
9424
  (purpose) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
9390
9425
  PurposeItem,
9391
9426
  {
9427
+ showsDataElements,
9428
+ descriptionPlacement,
9392
9429
  roomyControls,
9393
9430
  purpose,
9394
9431
  selectedPurposes,
@@ -9415,6 +9452,8 @@ var NoticeConsentView = ({
9415
9452
  categorizedPurposes.needsConsent.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
9416
9453
  PurposeItem,
9417
9454
  {
9455
+ showsDataElements,
9456
+ descriptionPlacement,
9418
9457
  roomyControls,
9419
9458
  purpose,
9420
9459
  selectedPurposes,
@@ -9490,6 +9529,8 @@ var NoticeConsentView = ({
9490
9529
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
9491
9530
  PurposeItem,
9492
9531
  {
9532
+ showsDataElements,
9533
+ descriptionPlacement,
9493
9534
  purpose,
9494
9535
  productUuid: group.product.uuid,
9495
9536
  selectedPurposes,
@@ -9526,6 +9567,8 @@ var NoticeConsentView = ({
9526
9567
  renderedPurposes.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
9527
9568
  PurposeItem,
9528
9569
  {
9570
+ showsDataElements,
9571
+ descriptionPlacement,
9529
9572
  roomyControls,
9530
9573
  purpose,
9531
9574
  selectedPurposes,
@@ -9727,8 +9770,8 @@ var NoticeConsentView = ({
9727
9770
  }
9728
9771
  ),
9729
9772
  otpLocked && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ...PART_PROPS.otp, style: styles4.otpGatePanel, children: [
9730
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: styles4.otpGateTitle, children: (_J = otpGate == null ? void 0 : otpGate.title) != null ? _J : chrome.otpTitle }),
9731
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: styles4.otpGateDescription, children: (_K = otpGate == null ? void 0 : otpGate.description) != null ? _K : chrome.otpDescription }),
9773
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: styles4.otpGateTitle, children: (_K = otpGate == null ? void 0 : otpGate.title) != null ? _K : chrome.otpTitle }),
9774
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: styles4.otpGateDescription, children: (_L = otpGate == null ? void 0 : otpGate.description) != null ? _L : chrome.otpDescription }),
9732
9775
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: styles4.otpGateDigits, children: Array.from({ length: OTP_GATE_LENGTH }).map(
9733
9776
  (_, i) => {
9734
9777
  var _a2;
@@ -9801,7 +9844,7 @@ var NoticeConsentView = ({
9801
9844
  },
9802
9845
  onClick: handleOtpConfirm,
9803
9846
  disabled: otpBusy || otpCode.length !== OTP_GATE_LENGTH,
9804
- children: otpBusy ? chrome.otpVerifying : (_L = otpGate == null ? void 0 : otpGate.submitLabel) != null ? _L : chrome.otpSubmit
9847
+ children: otpBusy ? chrome.otpVerifying : (_M = otpGate == null ? void 0 : otpGate.submitLabel) != null ? _M : chrome.otpSubmit
9805
9848
  }
9806
9849
  )
9807
9850
  ] }),
package/dist/index.mjs CHANGED
@@ -1311,6 +1311,8 @@ var PREVIEW_FRAME_STYLE = {
1311
1311
  var LAYOUT_STYLE_ID = "redacto-notice-layout-styles";
1312
1312
  var DOCK_ATTRIBUTE = "data-redacto-sheet";
1313
1313
  var DOCKED = "dock";
1314
+ var PREVIEW_ATTRIBUTE = "data-redacto-preview";
1315
+ var PREVIEWED = "frame";
1314
1316
  var MOTION_ATTRIBUTE = "data-redacto-motion";
1315
1317
  var MOTION_OFF = "off";
1316
1318
  var NOTICE_ID_ATTRIBUTE = "data-redacto-notice-id";
@@ -1388,7 +1390,7 @@ var styles = {
1388
1390
  border: "none",
1389
1391
  display: "flex",
1390
1392
  flexDirection: "column",
1391
- maxHeight: "90vh",
1393
+ maxHeight: "90%",
1392
1394
  zIndex: 1e3,
1393
1395
  margin: 0,
1394
1396
  padding: 0,
@@ -1769,7 +1771,14 @@ var styles = {
1769
1771
  lineHeight: "150%",
1770
1772
  letterSpacing: "0.2px",
1771
1773
  cursor: "pointer",
1772
- margin: 0,
1774
+ // Longhands, not the `margin` shorthand: `declineSpacer` spreads
1775
+ // `marginRight` over this on the wide row only, and React clears a
1776
+ // longhand that sits beside a shorthand when a render drops it, which
1777
+ // leaves the value order-dependent.
1778
+ marginTop: 0,
1779
+ marginRight: 0,
1780
+ marginBottom: 0,
1781
+ marginLeft: 0,
1773
1782
  boxSizing: "border-box",
1774
1783
  textAlign: "center",
1775
1784
  fontFamily: "inherit"
@@ -2956,10 +2965,12 @@ var FLOAT_FRAMES_STILL = `
2956
2965
  var floatKeyframes = (frames) => [NOTICE_KEYFRAMES.float, NOTICE_KEYFRAMES.floatPill].map((name) => `@keyframes ${name} {${frames}
2957
2966
  }`).join("\n");
2958
2967
  var css = `
2959
- /* dvh tracks the phone's collapsing toolbars; vh stays inline as the
2960
- fallback for browsers without it. */
2968
+ /* dvh tracks the phone's collapsing toolbars; the inline percentage stays
2969
+ as the fallback for browsers without it. Never in the console preview:
2970
+ there the frame is the containing block the inline cap is measured
2971
+ against, and a viewport unit would overrule it with the window's height. */
2961
2972
  @supports (height: 100dvh) {
2962
- ${N}[${DOCK_ATTRIBUTE}="${DOCKED}"] {
2973
+ ${N}[${DOCK_ATTRIBUTE}="${DOCKED}"]:not([${PREVIEW_ATTRIBUTE}]) {
2963
2974
  max-height: 92dvh !important;
2964
2975
  }
2965
2976
  }
@@ -3201,7 +3212,7 @@ var modalPosition = ({
3201
3212
  if (isMobile) {
3202
3213
  return layout.mobileSheet ? {
3203
3214
  ...edgeDock(radius),
3204
- maxHeight: "92vh",
3215
+ maxHeight: "92%",
3205
3216
  paddingBottom: "env(safe-area-inset-bottom, 0px)"
3206
3217
  } : {};
3207
3218
  }
@@ -3214,7 +3225,7 @@ var modalPosition = ({
3214
3225
  case "bottom-bar":
3215
3226
  return {
3216
3227
  ...edgeDock(radius),
3217
- maxHeight: "70vh",
3228
+ maxHeight: "70%",
3218
3229
  paddingLeft: `max(0px, calc((100% - ${BOTTOM_BAR_CONTENT_WIDTH}) / 2))`,
3219
3230
  paddingRight: `max(0px, calc((100% - ${BOTTOM_BAR_CONTENT_WIDTH}) / 2))`
3220
3231
  };
@@ -3435,7 +3446,7 @@ var stylePatch = (p, {
3435
3446
  ...blur,
3436
3447
  border: `1px solid ${p.sheetEdge}`,
3437
3448
  boxShadow: docked ? p.shadow : p.floatShadow,
3438
- maxHeight: "85vh",
3449
+ maxHeight: "85%",
3439
3450
  overflow: "hidden",
3440
3451
  animation: `${NOTICE_KEYFRAMES.float} ${MOTION.dimMs}ms ${MOTION.outEase} both`
3441
3452
  },
@@ -4304,6 +4315,8 @@ var PurposeItem = ({
4304
4315
  initialDataElementSelections = {},
4305
4316
  controlSkin,
4306
4317
  rowClassName,
4318
+ showsDataElements = true,
4319
+ descriptionPlacement = "always",
4307
4320
  animateDisclosure = false
4308
4321
  }) => {
4309
4322
  var _a, _b;
@@ -4329,11 +4342,31 @@ var PurposeItem = ({
4329
4342
  }),
4330
4343
  [settings == null ? void 0 : settings.textColor]
4331
4344
  );
4332
- const dataElementsOpen = !collapsedPurposes[stateKey] && Boolean(purpose.data_elements) && purpose.data_elements.length > 0;
4345
+ const hasDataElements = showsDataElements && Boolean(purpose.data_elements) && purpose.data_elements.length > 0;
4346
+ const descriptionText = getTranslatedText(
4347
+ `purposes.description`,
4348
+ purpose.description,
4349
+ purpose.uuid
4350
+ );
4351
+ const disclosesDescription = descriptionPlacement === "expanded" && descriptionText.trim() !== "";
4352
+ const hasDisclosure = hasDataElements || disclosesDescription;
4353
+ const dataElementsOpen = !collapsedPurposes[stateKey] && hasDisclosure;
4354
+ const purposeDescription = /* @__PURE__ */ jsx6(
4355
+ "h3",
4356
+ {
4357
+ id: `purpose-description-${stateKey}`,
4358
+ style: {
4359
+ ...styles4.optionDescription,
4360
+ ...responsiveStyles.optionDescription,
4361
+ ...textStyle
4362
+ },
4363
+ children: descriptionText
4364
+ },
4365
+ `purpose-description-${purpose.uuid}-${selectedLanguage}`
4366
+ );
4333
4367
  const dataElements = /* @__PURE__ */ jsx6(
4334
4368
  "div",
4335
4369
  {
4336
- id: `purpose-${purpose.uuid}`,
4337
4370
  style: {
4338
4371
  ...styles4.dataElementsContainer,
4339
4372
  ...roomyControls ? styles4.dataElementsContainerRoomy : null
@@ -4453,30 +4486,36 @@ var PurposeItem = ({
4453
4486
  },
4454
4487
  `purpose-${purpose.uuid}-container-${selectedLanguage}`
4455
4488
  );
4489
+ const disclosureContents = /* @__PURE__ */ jsxs5(Fragment3, { children: [
4490
+ disclosesDescription && purposeDescription,
4491
+ hasDataElements && dataElements
4492
+ ] });
4456
4493
  return /* @__PURE__ */ jsxs5("div", { className: rowClassName, children: [
4457
4494
  /* @__PURE__ */ jsxs5("div", { ...PART_PROPS.purpose, style: styles4.optionItem, children: [
4458
4495
  /* @__PURE__ */ jsxs5(
4459
4496
  "div",
4460
4497
  {
4461
4498
  style: styles4.optionLeft,
4462
- onClick: () => onPurposeCollapse(purpose.uuid, productUuid),
4463
- role: "button",
4464
- tabIndex: 0,
4465
- "aria-expanded": !collapsedPurposes[stateKey],
4466
- "aria-controls": `purpose-${purpose.uuid}`,
4467
- "aria-label": `${collapsedPurposes[stateKey] ? "Expand" : "Collapse"} ${getTranslatedText(
4468
- `purposes.name`,
4469
- purpose.name,
4470
- purpose.uuid
4471
- )} details`,
4472
- onKeyDown: (e) => {
4473
- if (e.key === "Enter" || e.key === " ") {
4474
- e.preventDefault();
4475
- onPurposeCollapse(purpose.uuid, productUuid);
4499
+ ...hasDisclosure && {
4500
+ onClick: () => onPurposeCollapse(purpose.uuid, productUuid),
4501
+ role: "button",
4502
+ tabIndex: 0,
4503
+ "aria-expanded": !collapsedPurposes[stateKey],
4504
+ "aria-controls": `purpose-${purpose.uuid}`,
4505
+ "aria-label": `${collapsedPurposes[stateKey] ? "Expand" : "Collapse"} ${getTranslatedText(
4506
+ `purposes.name`,
4507
+ purpose.name,
4508
+ purpose.uuid
4509
+ )} details`,
4510
+ onKeyDown: (e) => {
4511
+ if (e.key === "Enter" || e.key === " ") {
4512
+ e.preventDefault();
4513
+ onPurposeCollapse(purpose.uuid, productUuid);
4514
+ }
4476
4515
  }
4477
4516
  },
4478
4517
  children: [
4479
- /* @__PURE__ */ jsx6(
4518
+ hasDisclosure && /* @__PURE__ */ jsx6(
4480
4519
  CollapseChevron,
4481
4520
  {
4482
4521
  open: !collapsedPurposes[stateKey],
@@ -4501,23 +4540,7 @@ var PurposeItem = ({
4501
4540
  },
4502
4541
  `purpose-name-${purpose.uuid}-${selectedLanguage}`
4503
4542
  ),
4504
- /* @__PURE__ */ jsx6(
4505
- "h3",
4506
- {
4507
- id: `purpose-description-${stateKey}`,
4508
- style: {
4509
- ...styles4.optionDescription,
4510
- ...responsiveStyles.optionDescription,
4511
- ...textStyle
4512
- },
4513
- children: getTranslatedText(
4514
- `purposes.description`,
4515
- purpose.description,
4516
- purpose.uuid
4517
- )
4518
- },
4519
- `purpose-description-${purpose.uuid}-${selectedLanguage}`
4520
- )
4543
+ descriptionPlacement === "always" && purposeDescription
4521
4544
  ] })
4522
4545
  ]
4523
4546
  }
@@ -4543,7 +4566,13 @@ var PurposeItem = ({
4543
4566
  }
4544
4567
  )
4545
4568
  ] }),
4546
- animateDisclosure ? /* @__PURE__ */ jsx6(Collapse, { open: dataElementsOpen, children: dataElements }) : dataElementsOpen && dataElements
4569
+ hasDisclosure && (animateDisclosure ? /* @__PURE__ */ jsx6(Collapse, { open: dataElementsOpen, children: /* @__PURE__ */ jsx6("div", { id: `purpose-${purpose.uuid}`, children: disclosureContents }) }) : (
4570
+ // The container is always drawn, empty while the row is closed:
4571
+ // `aria-controls` on the chevron names it, and a control that points
4572
+ // at an element which is not in the document is worse than no
4573
+ // control at all.
4574
+ /* @__PURE__ */ jsx6("div", { id: `purpose-${purpose.uuid}`, children: dataElementsOpen && disclosureContents })
4575
+ ))
4547
4576
  ] }, purpose.uuid);
4548
4577
  };
4549
4578
  var RELATIONSHIP_OPTIONS = [
@@ -5461,7 +5490,7 @@ var NoticeConsentView = ({
5461
5490
  forceMobile,
5462
5491
  forceColorScheme
5463
5492
  }) => {
5464
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L;
5493
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M;
5465
5494
  const endpoints = useResolvedEndpoints(baseUrlProp, ledgerBaseUrlProp, {
5466
5495
  warn: !previewContent
5467
5496
  });
@@ -5538,6 +5567,9 @@ var NoticeConsentView = ({
5538
5567
  }, [noticeId]);
5539
5568
  const servedAppearance = content ? content.appearance : cachedAppearance;
5540
5569
  const showsProductSection = (servedAppearance == null ? void 0 : servedAppearance.show_product_section) !== false;
5570
+ const showsDataElements = (servedAppearance == null ? void 0 : servedAppearance.show_data_elements) !== false;
5571
+ const descriptionPlacement = (_a = servedAppearance == null ? void 0 : servedAppearance.purpose_description) != null ? _a : "always";
5572
+ const showsPurposeSectionHeading = (servedAppearance == null ? void 0 : servedAppearance.show_purpose_section_heading) !== false;
5541
5573
  const noticeAppearance = useNoticeAppearance(
5542
5574
  servedAppearance,
5543
5575
  settings,
@@ -5726,8 +5758,8 @@ var NoticeConsentView = ({
5726
5758
  const docked = isDocked(layout, isMobile);
5727
5759
  const headingColor = (noticeSettings == null ? void 0 : noticeSettings.headingColor) || DEFAULT_HEADING_COLOR;
5728
5760
  const textColor = (noticeSettings == null ? void 0 : noticeSettings.textColor) || DEFAULT_TEXT_COLOR;
5729
- const classicAccentColor = ((_b = (_a = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || (content == null ? void 0 : content.primary_color) || (content ? DEFAULT_ACCENT_COLOR : headingColor);
5730
- const accentColor = (_e = appearanceColors.toggle_on) != null ? _e : hasNoticeSkin(appearance) ? ((_d = (_c = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _c.acceptAll) == null ? void 0 : _d.backgroundColor) || classicAccentColor : classicAccentColor;
5761
+ const classicAccentColor = ((_c = (_b = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _b.accept) == null ? void 0 : _c.backgroundColor) || (content == null ? void 0 : content.primary_color) || (content ? DEFAULT_ACCENT_COLOR : headingColor);
5762
+ const accentColor = (_f = appearanceColors.toggle_on) != null ? _f : hasNoticeSkin(appearance) ? ((_e = (_d = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _d.acceptAll) == null ? void 0 : _e.backgroundColor) || classicAccentColor : classicAccentColor;
5731
5763
  const variantStyles = useMemo3(
5732
5764
  () => buildVariantStyles(
5733
5765
  styles,
@@ -5761,7 +5793,7 @@ var NoticeConsentView = ({
5761
5793
  docked
5762
5794
  ]
5763
5795
  );
5764
- const textScale = NOTICE_TEXT_SCALE_FACTORS[(_f = noticeAppearance.textScale) != null ? _f : DEFAULT_TEXT_SCALE];
5796
+ const textScale = NOTICE_TEXT_SCALE_FACTORS[(_g = noticeAppearance.textScale) != null ? _g : DEFAULT_TEXT_SCALE];
5765
5797
  const styles4 = useMemo3(
5766
5798
  () => {
5767
5799
  var _a2;
@@ -5826,7 +5858,7 @@ var NoticeConsentView = ({
5826
5858
  ...otpLocked && styles4.otpGateLocked
5827
5859
  };
5828
5860
  const drawsSwitches = layout.switchControl;
5829
- const roomyControls = drawsSwitches || ((_g = noticeSettings == null ? void 0 : noticeSettings.selectionControl) != null ? _g : DEFAULT_SELECTION_CONTROL) !== "checkbox";
5861
+ const roomyControls = drawsSwitches || ((_h = noticeSettings == null ? void 0 : noticeSettings.selectionControl) != null ? _h : DEFAULT_SELECTION_CONTROL) !== "checkbox";
5830
5862
  const appearanceRootProps = {
5831
5863
  [NOTICE_ROOT_ATTRIBUTE]: "",
5832
5864
  [NOTICE_ID_ATTRIBUTE]: noticeId,
@@ -7198,7 +7230,7 @@ var NoticeConsentView = ({
7198
7230
  if (ttsAudioUrls.privacy_policy_anchor_text_audio_url) {
7199
7231
  sequence.push(ttsAudioUrls.privacy_policy_anchor_text_audio_url);
7200
7232
  }
7201
- if (ttsAudioUrls.purpose_section_heading_audio_url) {
7233
+ if (showsPurposeSectionHeading && ttsAudioUrls.purpose_section_heading_audio_url) {
7202
7234
  sequence.push(ttsAudioUrls.purpose_section_heading_audio_url);
7203
7235
  }
7204
7236
  const purposesToProcess = categorizedPurposes ? [
@@ -7214,12 +7246,12 @@ var NoticeConsentView = ({
7214
7246
  if ((_a2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _a2.name_audio_url) {
7215
7247
  sequence.push(ttsAudioUrls.purposes_audio[purpose.uuid].name_audio_url);
7216
7248
  }
7217
- if ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url) {
7249
+ if (descriptionPlacement !== "hidden" && ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url)) {
7218
7250
  sequence.push(
7219
7251
  ttsAudioUrls.purposes_audio[purpose.uuid].description_audio_url
7220
7252
  );
7221
7253
  }
7222
- if (purpose.data_elements && purpose.data_elements.length > 0) {
7254
+ if (showsDataElements && purpose.data_elements && purpose.data_elements.length > 0) {
7223
7255
  purpose.data_elements.forEach((dataElement) => {
7224
7256
  var _a3;
7225
7257
  if ((_a3 = ttsAudioUrls.data_elements_audio[dataElement.uuid]) == null ? void 0 : _a3.name_audio_url) {
@@ -7270,7 +7302,7 @@ var NoticeConsentView = ({
7270
7302
  if (ttsAudioUrls.privacy_policy_anchor_text_audio_url) {
7271
7303
  elementIds.push("privacy-policy-link");
7272
7304
  }
7273
- if (ttsAudioUrls.purpose_section_heading_audio_url) {
7305
+ if (showsPurposeSectionHeading && ttsAudioUrls.purpose_section_heading_audio_url) {
7274
7306
  elementIds.push("purpose-section-heading");
7275
7307
  }
7276
7308
  const purposesToProcess = categorizedPurposes ? [
@@ -7286,10 +7318,12 @@ var NoticeConsentView = ({
7286
7318
  if ((_a2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _a2.name_audio_url) {
7287
7319
  elementIds.push(`purpose-name-${purpose.uuid}`);
7288
7320
  }
7289
- if ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url) {
7290
- elementIds.push(`purpose-description-${purpose.uuid}`);
7321
+ if (descriptionPlacement !== "hidden" && ((_b2 = ttsAudioUrls.purposes_audio[purpose.uuid]) == null ? void 0 : _b2.description_audio_url)) {
7322
+ elementIds.push(
7323
+ descriptionPlacement === "always" ? `purpose-description-${purpose.uuid}` : null
7324
+ );
7291
7325
  }
7292
- if (purpose.data_elements && purpose.data_elements.length > 0) {
7326
+ if (showsDataElements && purpose.data_elements && purpose.data_elements.length > 0) {
7293
7327
  purpose.data_elements.forEach((dataElement) => {
7294
7328
  var _a3;
7295
7329
  if ((_a3 = ttsAudioUrls.data_elements_audio[dataElement.uuid]) == null ? void 0 : _a3.name_audio_url) {
@@ -7536,20 +7570,20 @@ var NoticeConsentView = ({
7536
7570
  };
7537
7571
  const acceptAllButtonStyle = {
7538
7572
  ...buttonStyle2,
7539
- backgroundColor: ((_i = (_h = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _h.acceptAll) == null ? void 0 : _i.backgroundColor) || ((_k = (_j = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _j.accept) == null ? void 0 : _k.backgroundColor) || (content == null ? void 0 : content.primary_color) || "#4f87ff",
7540
- color: ((_m = (_l = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _l.acceptAll) == null ? void 0 : _m.textColor) || ((_o = (_n = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _n.accept) == null ? void 0 : _o.textColor) || "#ffffff"
7573
+ backgroundColor: ((_j = (_i = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _i.acceptAll) == null ? void 0 : _j.backgroundColor) || ((_l = (_k = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _k.accept) == null ? void 0 : _l.backgroundColor) || (content == null ? void 0 : content.primary_color) || "#4f87ff",
7574
+ color: ((_n = (_m = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _m.acceptAll) == null ? void 0 : _n.textColor) || ((_p = (_o = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _o.accept) == null ? void 0 : _p.textColor) || "#ffffff"
7541
7575
  };
7542
7576
  const acceptSelectedButtonStyle = {
7543
7577
  ...buttonStyle2,
7544
- backgroundColor: (_p = appearanceColors.accept_bg) != null ? _p : skin ? skin.palette.accentWash : "#ffffff",
7545
- color: (_q = appearanceColors.accept_text) != null ? _q : accentColor,
7546
- borderColor: skin ? "transparent" : (_r = appearanceColors.accept_text) != null ? _r : accentColor
7578
+ backgroundColor: (_q = appearanceColors.accept_bg) != null ? _q : skin ? skin.palette.accentWash : "#ffffff",
7579
+ color: (_r = appearanceColors.accept_text) != null ? _r : accentColor,
7580
+ borderColor: skin ? "transparent" : (_s = appearanceColors.accept_text) != null ? _s : accentColor
7547
7581
  };
7548
7582
  const declineButtonStyle = {
7549
7583
  ...buttonStyle2,
7550
- backgroundColor: ((_t = (_s = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _s.decline) == null ? void 0 : _t.backgroundColor) || (skin ? "transparent" : "#ffffff"),
7551
- color: ((_v = (_u = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _u.decline) == null ? void 0 : _v.textColor) || (skin ? textColor : "#000000"),
7552
- borderColor: (_w = appearanceColors.decline_border) != null ? _w : (noticeSettings == null ? void 0 : noticeSettings.borderColor) || (skin ? skin.palette.outline : "#d0d5dd")
7584
+ backgroundColor: ((_u = (_t = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _t.decline) == null ? void 0 : _u.backgroundColor) || (skin ? "transparent" : "#ffffff"),
7585
+ color: ((_w = (_v = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _v.decline) == null ? void 0 : _w.textColor) || (skin ? textColor : "#000000"),
7586
+ borderColor: (_x = appearanceColors.decline_border) != null ? _x : (noticeSettings == null ? void 0 : noticeSettings.borderColor) || (skin ? skin.palette.outline : "#d0d5dd")
7553
7587
  };
7554
7588
  const confirmHint = useMemo3(() => {
7555
7589
  var _a2;
@@ -7630,7 +7664,7 @@ var NoticeConsentView = ({
7630
7664
  [content]
7631
7665
  );
7632
7666
  const showNoticePolicyLink = showsNoticePolicyLink(
7633
- (_y = (_x = content == null ? void 0 : content.products) == null ? void 0 : _x.length) != null ? _y : 0,
7667
+ (_z = (_y = content == null ? void 0 : content.products) == null ? void 0 : _y.length) != null ? _z : 0,
7634
7668
  productPolicyLinks.length
7635
7669
  );
7636
7670
  const handleAcceptAll = () => handleAccept("all");
@@ -7641,20 +7675,20 @@ var NoticeConsentView = ({
7641
7675
  const languageSelectorStyle = {
7642
7676
  borderRadius: hostRadius || styleRadii.button,
7643
7677
  borderColor: (noticeSettings == null ? void 0 : noticeSettings.borderColor) || (skin ? skin.palette.hairline : "#d0d5dd"),
7644
- backgroundColor: ((_A = (_z = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _z.language) == null ? void 0 : _A.backgroundColor) || (skin ? skin.palette.control : "#ffffff"),
7645
- color: ((_C = (_B = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _B.language) == null ? void 0 : _C.textColor) || (skin ? headingColor : "#344054")
7678
+ backgroundColor: ((_B = (_A = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _A.language) == null ? void 0 : _B.backgroundColor) || (skin ? skin.palette.control : "#ffffff"),
7679
+ color: ((_D = (_C = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _C.language) == null ? void 0 : _D.textColor) || (skin ? headingColor : "#344054")
7646
7680
  };
7647
7681
  const { borderRadius: _chipRadius, ...languageChipColors } = languageSelectorStyle;
7648
7682
  const languageMenuStyle = skin ? {
7649
- ...((_E = (_D = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _D.language) == null ? void 0 : _E.backgroundColor) && {
7683
+ ...((_F = (_E = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _E.language) == null ? void 0 : _F.backgroundColor) && {
7650
7684
  backgroundColor: noticeSettings.button.language.backgroundColor
7651
7685
  },
7652
7686
  color: languageSelectorStyle.color
7653
7687
  } : languageChipColors;
7654
7688
  const selectedLanguageItemStyle = {
7655
7689
  ...languageMenuStyle,
7656
- backgroundColor: ((_G = (_F = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _F.language) == null ? void 0 : _G.selectedBackgroundColor) || (skin ? skin.palette.accentWash : "#f3f4f6"),
7657
- color: ((_I = (_H = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _H.language) == null ? void 0 : _I.selectedTextColor) || (skin ? headingColor : "#344054"),
7690
+ backgroundColor: ((_H = (_G = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _G.language) == null ? void 0 : _H.selectedBackgroundColor) || (skin ? skin.palette.accentWash : "#f3f4f6"),
7691
+ color: ((_J = (_I = noticeSettings == null ? void 0 : noticeSettings.button) == null ? void 0 : _I.language) == null ? void 0 : _J.selectedTextColor) || (skin ? headingColor : "#344054"),
7658
7692
  fontWeight: 600
7659
7693
  };
7660
7694
  const isSectionOpen = (section) => openSections[section] || isTalkbackActive;
@@ -7834,6 +7868,7 @@ var NoticeConsentView = ({
7834
7868
  ...appearanceRootProps,
7835
7869
  ...PART_PROPS.root,
7836
7870
  ...docked && { [DOCK_ATTRIBUTE]: DOCKED },
7871
+ ...previewContent && { [PREVIEW_ATTRIBUTE]: PREVIEWED },
7837
7872
  style: isLoading && showsLoaderPill && skin ? (
7838
7873
  // The dialog itself shrinks to a pill until the notice
7839
7874
  // arrives, then grows into the sheet: one element, so the
@@ -8377,7 +8412,7 @@ var NoticeConsentView = ({
8377
8412
  `privacy-text-${selectedLanguage}`
8378
8413
  )
8379
8414
  ),
8380
- /* @__PURE__ */ jsx6(
8415
+ showsPurposeSectionHeading && /* @__PURE__ */ jsx6(
8381
8416
  "h2",
8382
8417
  {
8383
8418
  id: "purpose-section-heading",
@@ -8400,6 +8435,8 @@ var NoticeConsentView = ({
8400
8435
  (purpose) => /* @__PURE__ */ jsx6(
8401
8436
  PurposeItem,
8402
8437
  {
8438
+ showsDataElements,
8439
+ descriptionPlacement,
8403
8440
  roomyControls,
8404
8441
  purpose,
8405
8442
  selectedPurposes,
@@ -8426,6 +8463,8 @@ var NoticeConsentView = ({
8426
8463
  categorizedPurposes.needsConsent.map((purpose) => /* @__PURE__ */ jsx6(
8427
8464
  PurposeItem,
8428
8465
  {
8466
+ showsDataElements,
8467
+ descriptionPlacement,
8429
8468
  roomyControls,
8430
8469
  purpose,
8431
8470
  selectedPurposes,
@@ -8501,6 +8540,8 @@ var NoticeConsentView = ({
8501
8540
  return /* @__PURE__ */ jsx6(
8502
8541
  PurposeItem,
8503
8542
  {
8543
+ showsDataElements,
8544
+ descriptionPlacement,
8504
8545
  purpose,
8505
8546
  productUuid: group.product.uuid,
8506
8547
  selectedPurposes,
@@ -8537,6 +8578,8 @@ var NoticeConsentView = ({
8537
8578
  renderedPurposes.map((purpose) => /* @__PURE__ */ jsx6(
8538
8579
  PurposeItem,
8539
8580
  {
8581
+ showsDataElements,
8582
+ descriptionPlacement,
8540
8583
  roomyControls,
8541
8584
  purpose,
8542
8585
  selectedPurposes,
@@ -8738,8 +8781,8 @@ var NoticeConsentView = ({
8738
8781
  }
8739
8782
  ),
8740
8783
  otpLocked && /* @__PURE__ */ jsxs5("div", { ...PART_PROPS.otp, style: styles4.otpGatePanel, children: [
8741
- /* @__PURE__ */ jsx6("p", { style: styles4.otpGateTitle, children: (_J = otpGate == null ? void 0 : otpGate.title) != null ? _J : chrome.otpTitle }),
8742
- /* @__PURE__ */ jsx6("p", { style: styles4.otpGateDescription, children: (_K = otpGate == null ? void 0 : otpGate.description) != null ? _K : chrome.otpDescription }),
8784
+ /* @__PURE__ */ jsx6("p", { style: styles4.otpGateTitle, children: (_K = otpGate == null ? void 0 : otpGate.title) != null ? _K : chrome.otpTitle }),
8785
+ /* @__PURE__ */ jsx6("p", { style: styles4.otpGateDescription, children: (_L = otpGate == null ? void 0 : otpGate.description) != null ? _L : chrome.otpDescription }),
8743
8786
  /* @__PURE__ */ jsx6("div", { style: styles4.otpGateDigits, children: Array.from({ length: OTP_GATE_LENGTH }).map(
8744
8787
  (_, i) => {
8745
8788
  var _a2;
@@ -8812,7 +8855,7 @@ var NoticeConsentView = ({
8812
8855
  },
8813
8856
  onClick: handleOtpConfirm,
8814
8857
  disabled: otpBusy || otpCode.length !== OTP_GATE_LENGTH,
8815
- children: otpBusy ? chrome.otpVerifying : (_L = otpGate == null ? void 0 : otpGate.submitLabel) != null ? _L : chrome.otpSubmit
8858
+ children: otpBusy ? chrome.otpVerifying : (_M = otpGate == null ? void 0 : otpGate.submitLabel) != null ? _M : chrome.otpSubmit
8816
8859
  }
8817
8860
  )
8818
8861
  ] }),
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { P as PrivacyCenterTheme } from './types-B8qroG0j.mjs';
3
+ import { P as PrivacyCenterTheme } from './types-CaqLBkJt.mjs';
4
4
  import * as _tanstack_react_query from '@tanstack/react-query';
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { P as PrivacyCenterTheme } from './types-B8qroG0j.js';
3
+ import { P as PrivacyCenterTheme } from './types-CaqLBkJt.js';
4
4
  import * as _tanstack_react_query from '@tanstack/react-query';
5
5
 
6
6
  /**
@@ -16,6 +16,8 @@ declare const NOTICE_BACKDROPS: readonly ["dim", "none"];
16
16
  declare const NOTICE_PHONE_FOOTERS: readonly ["stacked", "paired"];
17
17
  declare const NOTICE_TEXT_SCALES: readonly ["sm", "md", "lg"];
18
18
 
19
+ type PurposeDescriptionPlacement = "always" | "expanded" | "hidden";
20
+
19
21
  /**
20
22
  * Surface and layout family a notice is drawn with, chosen in the Redacto
21
23
  * console and served on `active_config.appearance.style`. Colours never come
@@ -55,6 +57,11 @@ type NoticeAppearance = Readonly<{
55
57
  collapsible_sections?: boolean;
56
58
  /** Only read when the notice covers one product. */
57
59
  show_product_section?: boolean;
60
+ /** Absent draws the data elements, and the chevron that opens them. */
61
+ show_data_elements?: boolean;
62
+ /** Where the purpose description goes. Absent draws it on the row. */
63
+ purpose_description?: PurposeDescriptionPlacement;
64
+ show_purpose_section_heading?: boolean;
58
65
  phone_footer?: string;
59
66
  auto_dark?: boolean;
60
67
  dark_colors?: NoticeAppearanceColors;
@@ -16,6 +16,8 @@ declare const NOTICE_BACKDROPS: readonly ["dim", "none"];
16
16
  declare const NOTICE_PHONE_FOOTERS: readonly ["stacked", "paired"];
17
17
  declare const NOTICE_TEXT_SCALES: readonly ["sm", "md", "lg"];
18
18
 
19
+ type PurposeDescriptionPlacement = "always" | "expanded" | "hidden";
20
+
19
21
  /**
20
22
  * Surface and layout family a notice is drawn with, chosen in the Redacto
21
23
  * console and served on `active_config.appearance.style`. Colours never come
@@ -55,6 +57,11 @@ type NoticeAppearance = Readonly<{
55
57
  collapsible_sections?: boolean;
56
58
  /** Only read when the notice covers one product. */
57
59
  show_product_section?: boolean;
60
+ /** Absent draws the data elements, and the chevron that opens them. */
61
+ show_data_elements?: boolean;
62
+ /** Where the purpose description goes. Absent draws it on the row. */
63
+ purpose_description?: PurposeDescriptionPlacement;
64
+ show_purpose_section_heading?: boolean;
58
65
  phone_footer?: string;
59
66
  auto_dark?: boolean;
60
67
  dark_colors?: NoticeAppearanceColors;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redacto.io/consent-sdk-react",
3
- "version": "11.0.0",
3
+ "version": "11.1.0-beta.1",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",