@orangelogic/design-system 3.4.0 → 3.5.0

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.
Files changed (56) hide show
  1. package/library/chunks/{asset-link-format.O2It93rl.js → asset-link-format.SaFYESLe.js} +1140 -992
  2. package/library/chunks/{color-swatch-group.CTcv62MK.js → color-swatch-group.Bu1ev_Af.js} +2 -2
  3. package/library/chunks/{document-viewer.D6PxGcEL.js → document-viewer.hfxnrrUV.js} +3 -3
  4. package/library/chunks/{image.B-4cVbol.js → image.ysU1iW6e.js} +1 -1
  5. package/library/chunks/{menu-item.DgUMVYe5.js → menu-item.uFqeX_J6.js} +12 -12
  6. package/library/chunks/{tab-group.BSl6GdIO.js → tab-group.CdTSrsM1.js} +1 -1
  7. package/library/chunks/transformation.BfIEi4p4.js +300 -0
  8. package/library/components/asset-link-format.js +2 -2
  9. package/library/components/atoms.js +4 -4
  10. package/library/components/color-swatch-group.js +1 -1
  11. package/library/components/cropper.js +1 -1
  12. package/library/components/document-viewer.js +2 -2
  13. package/library/components/file-on-demand.js +1 -1
  14. package/library/components/image.js +1 -1
  15. package/library/components/masonry.js +65 -49
  16. package/library/components/menu-item.js +1 -1
  17. package/library/components/menu-section.js +16 -13
  18. package/library/components/menu.js +1 -1
  19. package/library/components/organisms.js +2 -2
  20. package/library/components/tab-group.js +2 -2
  21. package/library/components/types.js +12386 -12220
  22. package/library/components/video.js +1 -1
  23. package/library/package.json +1 -1
  24. package/library/packages/atoms/src/components/image/image.d.ts +6 -0
  25. package/library/packages/atoms/src/components/menu-section/menu-section.d.ts +1 -0
  26. package/library/packages/events/src/cx-asset-transformation-dialog-confirm.d.ts +2 -0
  27. package/library/packages/molecules/src/cropper/cropper.d.ts +0 -1
  28. package/library/packages/molecules/src/cropper/react/Cropper.d.ts +0 -1
  29. package/library/packages/molecules/src/masonry/masonry.d.ts +15 -0
  30. package/library/packages/molecules/src/view-and-sort/view-and-sort.d.ts +2 -0
  31. package/library/packages/organisms/src/asset-link-format/asset-link-format.d.ts +46 -2
  32. package/library/packages/organisms/src/asset-link-format/components/asset-link-format-proxy/asset-link-format-proxy.d.ts +36 -1
  33. package/library/packages/organisms/src/asset-transformation-dialog/asset-transformation-dialog.d.ts +20 -2
  34. package/library/packages/organisms/src/bento-grid/bento-grid.d.ts +13 -0
  35. package/library/packages/organisms/src/carousel/carousel.d.ts +13 -0
  36. package/library/packages/organisms/src/content-builder/blocks/image/image.d.ts +54 -0
  37. package/library/packages/organisms/src/content-builder/blocks/video/video.d.ts +5 -0
  38. package/library/packages/organisms/src/content-builder/components/config-form/config-form.d.ts +2 -1
  39. package/library/packages/organisms/src/content-builder/components/gallery-picker/gallery-picker.d.ts +6 -0
  40. package/library/packages/organisms/src/content-builder/configs/carousel.d.ts +1 -0
  41. package/library/packages/organisms/src/content-builder/configs/gallery.d.ts +1 -0
  42. package/library/packages/organisms/src/content-builder/configs/image.d.ts +2 -0
  43. package/library/packages/organisms/src/content-builder/configs/timeline.d.ts +1 -0
  44. package/library/packages/organisms/src/content-builder/configs/video.d.ts +1 -0
  45. package/library/packages/organisms/src/content-builder/configs-controller.d.ts +10 -0
  46. package/library/packages/organisms/src/content-builder/styleController.d.ts +2 -0
  47. package/library/packages/tools/src/fetch-image/fetch-image.d.ts +28 -5
  48. package/library/packages/types/src/asset-link-format.d.ts +0 -1
  49. package/library/packages/types/src/content-builder.d.ts +7 -0
  50. package/library/packages/types/src/gallery-item.d.ts +1 -0
  51. package/library/packages/types/src/masonry.d.ts +1 -0
  52. package/library/packages/utils/src/transformation/transformation.d.ts +42 -3
  53. package/library/react-web-component.d.ts +51 -7
  54. package/library/utils.js +113 -109
  55. package/package.json +1 -1
  56. package/library/chunks/transformation.CWKaoGaY.js +0 -254
@@ -1,7 +1,7 @@
1
1
  import { _ as kd, a as Sa, b as Be, c as Je } from "../chunks/inheritsLoose.BuSn_CvZ.js";
2
2
  import { c as ps, a as Bn } from "../chunks/_commonjsHelpers.DQNKXVTB.js";
3
3
  import { r as Sb } from "../chunks/___vite-browser-external_commonjs-proxy.C2tf3HsQ.js";
4
- import { C as Cb } from "../chunks/image.B-4cVbol.js";
4
+ import { C as Cb } from "../chunks/image.ysU1iW6e.js";
5
5
  import Mb from "./resize-observer.js";
6
6
  import { r as Db, R as Pb, a as Rp, b as Lb } from "../chunks/resizable-component.styles.CAfXABBc.js";
7
7
  import { c as Rb } from "../chunks/component.styles.CRO4Odto.js";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orangelogic/design-system",
3
3
  "type": "module",
4
- "version": "3.4.0",
4
+ "version": "3.5.0",
5
5
  "license": "UNLICENSED",
6
6
  "types": "library/types.d.ts",
7
7
  "scripts": {
@@ -139,6 +139,12 @@ export default class CxImage extends ResizableElement {
139
139
  retryOnError: boolean;
140
140
  /**
141
141
  * Maximum number of retry attempts when `retry-on-error` is enabled.
142
+ *
143
+ * Set high enough to outlast a transient backend overload: a page full of images
144
+ * can push the transform service into 503s, and those images need to keep retrying
145
+ * until it recovers rather than falling back to a broken-image icon. The backoff is
146
+ * exponential and capped at 10s per attempt, so the attempts spread out instead of
147
+ * adding to the load.
142
148
  */
143
149
  maxRetries: number;
144
150
  /**
@@ -23,6 +23,7 @@ export default class CxMenuSection extends CortexElement {
23
23
  private mutationObserver;
24
24
  connectedCallback(): void;
25
25
  disconnectedCallback(): void;
26
+ runFirstUpdated(): void;
26
27
  private handleSlotChange;
27
28
  render(): import('lit').TemplateResult<1>;
28
29
  }
@@ -2,6 +2,8 @@ import { Transformation } from '../../types/src/asset-link-format';
2
2
 
3
3
  export type CxAssetTransformationDialogConfirmEvent = CustomEvent<{
4
4
  format: string;
5
+ /** False when the format follows the asset's file extension instead of an explicit pick. */
6
+ manualFormat: boolean;
5
7
  transformations: Transformation[];
6
8
  }>;
7
9
  declare global {
@@ -28,7 +28,6 @@ export default class CxCropper extends CortexElement {
28
28
  image: {
29
29
  extension: string;
30
30
  height: number;
31
- originalUrl: string;
32
31
  rotation: number;
33
32
  url: string;
34
33
  width: number;
@@ -17,7 +17,6 @@ type Props = {
17
17
  image: {
18
18
  extension: string;
19
19
  height: number;
20
- originalUrl: string;
21
20
  rotation: number;
22
21
  url: string;
23
22
  width: number;
@@ -59,6 +59,19 @@ export default class CxMasonry extends CortexElement {
59
59
  * The key to use for the id of the items in the masonry layout.
60
60
  */
61
61
  idKey: keyof MasonryItem;
62
+ /**
63
+ * The proxy format the item images were resolved with.
64
+ *
65
+ * Only used to decide whether a `srcset` may be generated: an original-file format
66
+ * paired with an animated source must be delivered untouched.
67
+ */
68
+ format: string;
69
+ /**
70
+ * Whether `format` was picked by hand. When false each item's format follows its own
71
+ * file extension instead, so a mixed list can serve animated originals and resizable
72
+ * raster proxies side by side.
73
+ */
74
+ manualFormat: boolean;
62
75
  /**
63
76
  * When true, forwards `no-crossorigin` to each inner `<cx-image>`, disabling CORS mode
64
77
  * (e.g. in Site Builder contexts where CORS headers are absent).
@@ -90,6 +103,8 @@ export default class CxMasonry extends CortexElement {
90
103
  * the default `100vw`.
91
104
  */
92
105
  private get itemSizes();
106
+ /** The format one item is served under: the configured one, or derived from its extension. */
107
+ private resolveItemFormat;
93
108
  handleItemClick(event: MouseEvent, item: MasonryItem): void;
94
109
  handleSortableUpdate(event: Sortable.SortableEvent): void;
95
110
  renderActions(item: MasonryItem): import('lit').TemplateResult<1>;
@@ -7,6 +7,7 @@ import { default as CxLineClamp } from '../../../atoms/src/components/line-clamp
7
7
  import { default as CxMenu } from '../../../atoms/src/components/menu/menu.ts';
8
8
  import { default as CxMenuItem } from '../../../atoms/src/components/menu-item/menu-item.ts';
9
9
  import { default as CxMenuLabel } from '../../../atoms/src/components/menu-label/menu-label.ts';
10
+ import { default as CxMenuSection } from '../../../atoms/src/components/menu-section/menu-section.ts';
10
11
  import { default as CxSpace } from '../../../atoms/src/components/space/space.ts';
11
12
  import { default as CxSwitch } from '../../../atoms/src/components/switch/switch.ts';
12
13
  import { default as CxTooltip } from '../../../atoms/src/components/tooltip/tooltip.ts';
@@ -35,6 +36,7 @@ export default class CxViewAndSort extends CortexElement {
35
36
  'cx-menu': typeof CxMenu;
36
37
  'cx-menu-item': typeof CxMenuItem;
37
38
  'cx-menu-label': typeof CxMenuLabel;
39
+ 'cx-menu-section': typeof CxMenuSection;
38
40
  'cx-space': typeof CxSpace;
39
41
  'cx-switch': typeof CxSwitch;
40
42
  'cx-tooltip': typeof CxTooltip;
@@ -111,6 +111,18 @@ export default class CxAssetLinkFormat extends CortexElement {
111
111
  * This is a string that represents the ID of the selected proxy format from the list of available proxies.
112
112
  */
113
113
  defaultProxy: string;
114
+ /**
115
+ * Whether the format listbox offers an `Auto` entry, which derives the proxy from the
116
+ * asset's file extension instead of the author naming one.
117
+ */
118
+ canAutoFormat: boolean;
119
+ /**
120
+ * Whether `Auto` is the current choice.
121
+ *
122
+ * Tracked next to `selectedProxy` rather than encoded into it, so `selectedProxy` stays
123
+ * a real proxy id for every consumer that reads it — only the origin of that id differs.
124
+ */
125
+ autoFormat: boolean;
114
126
  useCustomExtension: boolean;
115
127
  noMetadata: boolean;
116
128
  noFormat: boolean;
@@ -133,13 +145,12 @@ export default class CxAssetLinkFormat extends CortexElement {
133
145
  activeSetting: string;
134
146
  /**
135
147
  * The currently selected format for the asset link.
136
- * This is an object that contains details about the selected format, such as `extension`, `height`, `keepMetadata`, `originalUrl`, `proxyUrl`, `quality`, `rotation`, `url`, `width`, `x`, and `y`.
148
+ * This is an object that contains details about the selected format, such as `extension`, `height`, `keepMetadata`, `proxyUrl`, `quality`, `rotation`, `url`, `width`, `x`, and `y`.
137
149
  */
138
150
  selectedFormat: {
139
151
  extension: string;
140
152
  height: number;
141
153
  keepMetadata: boolean;
142
- originalUrl: string;
143
154
  quality: number;
144
155
  rotation: number;
145
156
  url: string;
@@ -194,6 +205,10 @@ export default class CxAssetLinkFormat extends CortexElement {
194
205
  private frozenIndex;
195
206
  /** Snapshot saved on Reset to allow one Undo step back to the pre-reset state. */
196
207
  private preResetTransformations;
208
+ /** The `Auto` state saved alongside `preResetTransformations`, restored by the same Undo. */
209
+ private preResetAutoFormat;
210
+ /** The proxy saved alongside `preResetAutoFormat`, so Undo restores the pair together. */
211
+ private preResetSelectedProxy;
197
212
  /** True when there are transformations beyond the frozen index (i.e. user has added new ones). */
198
213
  private get hasUnfrozenTransformations();
199
214
  private apiGetTransformAssetLink;
@@ -319,6 +334,13 @@ export default class CxAssetLinkFormat extends CortexElement {
319
334
  private handleCropperElementChange;
320
335
  private handleCropperSelectorChange;
321
336
  private handleAssetChange;
337
+ /**
338
+ * The proxy id to fall back to when none is set or the current one is not in the list.
339
+ *
340
+ * Under `Auto` the asset's extension decides, so the first proxy in the list is only a
341
+ * last resort — used when the mapped format is not offered for this asset.
342
+ */
343
+ private resolveFallbackProxyId;
322
344
  private handleProxiesChange;
323
345
  handleSelectedProxyChange(oldValue: unknown): Promise<void>;
324
346
  handleLoadingChange(): void;
@@ -332,6 +354,14 @@ export default class CxAssetLinkFormat extends CortexElement {
332
354
  private onCropDragStart;
333
355
  private onDetailsShow;
334
356
  private onDetailsHide;
357
+ /**
358
+ * The proxy id that `Auto` resolves to for the current asset, or `''` when the mapped
359
+ * format is not among the available proxies.
360
+ *
361
+ * `resolveAutoFormat` yields a proxy *name* (`TRX` / `TR1`) while `selectedProxy` holds
362
+ * a proxy *id*, so the name has to be looked up in `proxies` rather than used directly.
363
+ */
364
+ private get autoResolvedProxyId();
335
365
  private onProxyChange;
336
366
  private onCropModeChange;
337
367
  private onCropFocusModeChange;
@@ -347,6 +377,20 @@ export default class CxAssetLinkFormat extends CortexElement {
347
377
  private onMetadataChange;
348
378
  private onExtensionChange;
349
379
  private syncQuality;
380
+ /**
381
+ * Whether there is anything for Reset to undo.
382
+ *
383
+ * Transformations are one way to diverge from the defaults; leaving `Auto` for an
384
+ * explicit format is another, and Reset is what puts that back.
385
+ */
386
+ private get hasResettableState();
387
+ /**
388
+ * Drops the one-step Reset snapshot.
389
+ *
390
+ * Called whenever the user applies a new transformation: at that point Undo means
391
+ * "remove that transformation", not "go back to before the Reset".
392
+ */
393
+ private clearResetSnapshot;
350
394
  private handleUndo;
351
395
  private handleReset;
352
396
  render(): TemplateResult;
@@ -1,5 +1,6 @@
1
1
  import { default as CxButton } from '../../../../../atoms/src/components/button/button.ts';
2
2
  import { default as CxDetails } from '../../../../../atoms/src/components/details/details.ts';
3
+ import { default as CxDivider } from '../../../../../atoms/src/components/divider/divider.ts';
3
4
  import { default as CxIcon } from '../../../../../atoms/src/components/icon/icon.ts';
4
5
  import { default as CxOption } from '../../../../../atoms/src/components/option/option.ts';
5
6
  import { default as CxSelect } from '../../../../../atoms/src/components/select/select.ts';
@@ -9,7 +10,23 @@ import { default as CortexElement } from '../../../../../base/src/cortex-element
9
10
  import { Proxy } from '../../../../../types/src/asset-link-format';
10
11
  import { CSSResultGroup, TemplateResult } from 'lit';
11
12
 
12
- export type CxAssetLinkFormatProxyChangeEvent = CustomEvent<Proxy>;
13
+ /**
14
+ * Listbox value for the `Auto` entry. Not a proxy id — no `Proxy` can ever carry it, so it
15
+ * is safe to distinguish the two cases by comparing against this constant.
16
+ */
17
+ export declare const AUTO_FORMAT_OPTION_VALUE = "auto";
18
+ /**
19
+ * Either a named proxy or the `Auto` choice.
20
+ *
21
+ * `Auto` carries no proxy: this component does not own the asset, so it cannot resolve
22
+ * which format the extension maps to. The parent does that and sets `selectedProxy`.
23
+ */
24
+ export type CxAssetLinkFormatProxyChangeDetail = (Proxy & {
25
+ autoFormat?: false;
26
+ }) | {
27
+ autoFormat: true;
28
+ };
29
+ export type CxAssetLinkFormatProxyChangeEvent = CustomEvent<CxAssetLinkFormatProxyChangeDetail>;
13
30
  /**
14
31
  * @summary The `cx-asset-link-format-proxy` component is used to select a proxy format for an asset link.
15
32
  *
@@ -20,6 +37,7 @@ export default class CxAssetLinkFormatProxy extends CortexElement {
20
37
  static readonly dependencies: {
21
38
  'cx-button': typeof CxButton;
22
39
  'cx-details': typeof CxDetails;
40
+ 'cx-divider': typeof CxDivider;
23
41
  'cx-icon': typeof CxIcon;
24
42
  'cx-option': typeof CxOption;
25
43
  'cx-select': typeof CxSelect;
@@ -50,6 +68,18 @@ export default class CxAssetLinkFormatProxy extends CortexElement {
50
68
  * @default []
51
69
  */
52
70
  items: Proxy[];
71
+ /**
72
+ * Whether the listbox offers an `Auto` entry that derives the format from the asset's
73
+ * file extension instead of naming one.
74
+ * @default false
75
+ */
76
+ canAutoFormat: boolean;
77
+ /**
78
+ * Whether `Auto` is the current choice. Kept separate from `value` so the resolved
79
+ * format stays readable while the listbox still shows `Auto` as selected.
80
+ * @default false
81
+ */
82
+ autoFormat: boolean;
53
83
  /**
54
84
  * The loading state of the component.
55
85
  * This is used to indicate that an operation is in progress, such as applying a new quality value.
@@ -63,6 +93,11 @@ export default class CxAssetLinkFormatProxy extends CortexElement {
63
93
  * @default ''
64
94
  */
65
95
  scopedValue: string;
96
+ /**
97
+ * The listbox value that represents the committed choice: the `Auto` entry when that is
98
+ * active, otherwise the resolved proxy id.
99
+ */
100
+ private get committedValue();
66
101
  handleValueChange(): void;
67
102
  handleOpenChange(): void;
68
103
  private handleProxyChange;
@@ -20,7 +20,7 @@ import { default as CxAssetLinkFormat } from '../asset-link-format/asset-link-fo
20
20
  * `cx-icon-button`. Automatically disabled when `asset-id` is not set.
21
21
  *
22
22
  * @event cx-asset-transformation-dialog-cancel - Emitted when the user closes or cancels the dialog.
23
- * @event {{ detail: { format: string; transformations: Transformation[] } }} cx-asset-transformation-dialog-confirm - Emitted when the user saves, with the selected proxy id and transformation array.
23
+ * @event {{ detail: { format: string; manualFormat: boolean; transformations: Transformation[] } }} cx-asset-transformation-dialog-confirm - Emitted when the user saves, with the resolved proxy id, whether that id was picked by hand rather than derived from the asset extension, and the transformation array.
24
24
  * @event cx-asset-transformation-dialog-delete - Emitted when the user resets the format to its default and clears the saved transformations via the reset button.
25
25
  */
26
26
  export default class CxAssetTransformationDialog extends CortexElement {
@@ -64,6 +64,11 @@ export default class CxAssetTransformationDialog extends CortexElement {
64
64
  format: string;
65
65
  /** The default format to fall back to if the asset has no transformations or selected proxy. */
66
66
  defaultFormat: string;
67
+ /**
68
+ * Whether the author picked the format by hand rather than letting it follow the asset's
69
+ * file extension. `false` (the default) means `Auto`.
70
+ */
71
+ manualFormat: boolean;
67
72
  /** Optional label rendered as the dialog title. Falls back to the localized "Asset format" term. */
68
73
  dialogLabel: string;
69
74
  /** The transformations applied when the user last saved, passed back into cx-asset-link-format on reopen. */
@@ -86,8 +91,21 @@ export default class CxAssetTransformationDialog extends CortexElement {
86
91
  private proxies;
87
92
  /** False while the authorization check is in flight or after it confirms no access. */
88
93
  private canAccess;
94
+ /**
95
+ * Whether the author changed anything away from the block's defaults, which is what the
96
+ * Reset control acts on.
97
+ *
98
+ * `Auto` is the default, so any manual format counts as an edit — including one that
99
+ * happens to resolve to the same proxy as `defaultFormat`. Comparing the codes instead
100
+ * would leave the author no way back to `Auto` from that format.
101
+ */
89
102
  private get hasTransformations();
90
- /** Resolves the selected format code to its proxy label, falling back to the raw code. */
103
+ /**
104
+ * The label shown in the settings row.
105
+ *
106
+ * Under `Auto` the stored format is only what the extension happened to resolve to, so
107
+ * naming it would read as an explicit choice the author never made.
108
+ */
91
109
  private get resolvedFormatLabel();
92
110
  handleAssetIdChange(): Promise<void>;
93
111
  handleCanAccessChange(): void;
@@ -116,6 +116,19 @@ export default class CxBentoGrid extends CortexElement {
116
116
  * Unloaded slots are approximated as 1×1 items.
117
117
  */
118
118
  totalItems: number;
119
+ /**
120
+ * The proxy format the item images were resolved with.
121
+ *
122
+ * Only used to decide whether a `srcset` may be generated: an original-file format
123
+ * paired with an animated source must be delivered untouched.
124
+ */
125
+ format: string;
126
+ /**
127
+ * Whether `format` was picked by hand. When false each item's format follows its own
128
+ * file extension instead, so a mixed grid can serve animated originals and resizable
129
+ * raster proxies side by side.
130
+ */
131
+ manualFormat: boolean;
119
132
  /**
120
133
  * Delay in milliseconds between releasing one row of images and the next.
121
134
  *
@@ -72,6 +72,19 @@ export default class CxCarousel extends CortexElement {
72
72
  * The real total number of data in the carousel. Not affected by chunking.
73
73
  */
74
74
  totalData: number;
75
+ /**
76
+ * The proxy format the slide images were resolved with.
77
+ *
78
+ * Only used to decide whether a `srcset` may be generated: an original-file format
79
+ * paired with an animated source must be delivered untouched.
80
+ */
81
+ format: string;
82
+ /**
83
+ * Whether `format` was picked by hand. When false each slide's format follows its own
84
+ * file extension instead, so a mixed carousel can serve animated originals and
85
+ * resizable raster proxies side by side.
86
+ */
87
+ manualFormat: boolean;
75
88
  /**
76
89
  * When set, allows the user to navigate the carousel in the same direction indefinitely.
77
90
  */
@@ -88,6 +88,14 @@ export default class CxSbImage extends CxImage {
88
88
  * Asset transformation proxy format key for dark mode.
89
89
  */
90
90
  formatDarkMode: string;
91
+ /**
92
+ * Whether `format` was picked by hand. When false the format follows the asset's file
93
+ * extension instead, so an animated GIF keeps its original file and everything else
94
+ * takes the transcoded raster proxy that `srcset` is allowed to resize.
95
+ */
96
+ manualFormat: boolean;
97
+ /** Whether `formatDarkMode` was picked by hand. See `manualFormat`. */
98
+ manualFormatDarkMode: boolean;
91
99
  /**
92
100
  * Asset transformations applied to the image.
93
101
  */
@@ -163,6 +171,20 @@ export default class CxSbImage extends CxImage {
163
171
  private resolvedSrc;
164
172
  /** Fresh URL re-resolved when the stored `srcDarkMode` has expired. */
165
173
  private resolvedSrcDarkMode;
174
+ /**
175
+ * The asset's file extension. Lets an animated GIF opt out of `srcset`, which a
176
+ * server-side resize would flatten to a still frame.
177
+ */
178
+ private assetExtension;
179
+ /**
180
+ * Whether an asset fetch has reported back for the current record.
181
+ *
182
+ * Tracked separately from `assetExtension` because "no extension" is a legitimate
183
+ * answer — a missing asset or a record without the field both yield an empty string.
184
+ * Gating on the empty string alone would hold `srcset` back forever in those cases;
185
+ * gating on this flag releases it as soon as the answer is in, whatever it says.
186
+ */
187
+ private hasResolvedAssetExtension;
166
188
  /**
167
189
  * Space list supplied by `cx-content-builder-viewer`, which fetches it once per
168
190
  * surface. The only source — this block never fetches the list itself.
@@ -193,6 +215,24 @@ export default class CxSbImage extends CxImage {
193
215
  get currentRecordId(): string;
194
216
  get currentSrc(): string;
195
217
  get currentTransformations(): Transformation[];
218
+ /** Whether the variant being displayed had its format picked by hand. */
219
+ get isCurrentFormatManual(): boolean;
220
+ /**
221
+ * The proxy format of the variant actually being displayed.
222
+ *
223
+ * Under `Auto` the asset's extension decides, so this stays a real proxy name and every
224
+ * consumer — the transformation URL and `srcset` alike — reads the same resolved value.
225
+ */
226
+ get currentFormat(): string;
227
+ /**
228
+ * Fields the child `cx-asset-data-display` must fetch for this block.
229
+ *
230
+ * The extension is always requested rather than only for the format that can serve
231
+ * an animated original. Requesting it unconditionally keeps the fetch shape stable
232
+ * (it does not change when the author switches format) and means `srcset` never has
233
+ * to wait on a follow-up fetch to learn whether this asset may be resized.
234
+ */
235
+ private get requestedAssetFields();
196
236
  get highlighterTabindex(): "0" | undefined;
197
237
  get highlighterRole(): "button" | "img";
198
238
  get highlighterClass(): {
@@ -228,6 +268,12 @@ export default class CxSbImage extends CxImage {
228
268
  handleClickSpaceChange(): void;
229
269
  handleObjectFitChange(): Promise<void>;
230
270
  handleSrcChange(): void;
271
+ /**
272
+ * Drops a cached extension once the asset it described is replaced, so a new record
273
+ * cannot inherit the previous one's answer about whether it may be resized — nor its
274
+ * resolved flag, which would let `srcset` be built before the new answer arrives.
275
+ */
276
+ handleRecordIdChangeForExtension(): void;
231
277
  handleFetchedAssetDataChange(): void;
232
278
  /**
233
279
  * Support CMS5 click action for the image.
@@ -240,6 +286,14 @@ export default class CxSbImage extends CxImage {
240
286
  * own `cx-asset-data-display` fetch) into alt text and overlay content.
241
287
  */
242
288
  private applyFetchedAssetData;
289
+ /**
290
+ * Captures the asset's extension from a fetch result and marks the answer as in.
291
+ *
292
+ * A blank value leaves any previously known extension in place — a response that
293
+ * omitted the field says nothing about the asset — but still resolves the wait, so a
294
+ * record whose extension never arrives does not block `srcset` indefinitely.
295
+ */
296
+ private applyExtensionFromAssetData;
243
297
  /**
244
298
  * A stored space URL breaks once the space moves domain, so the link target is
245
299
  * re-resolved against the list the viewer supplies. Without that list the stored
@@ -72,6 +72,11 @@ export default class CxSbVideo extends CxVideo {
72
72
  * Thumbnail proxy format key (e.g. "webp", "jpg").
73
73
  */
74
74
  thumbnailFormat: string;
75
+ /**
76
+ * Whether `thumbnailFormat` was picked by hand. When false the thumbnail's format
77
+ * follows the poster asset's file extension instead.
78
+ */
79
+ manualThumbnailFormat: boolean;
75
80
  /**
76
81
  * Transformations applied to the thumbnail image.
77
82
  */
@@ -27,7 +27,6 @@ import { default as CxTooltip } from '../../../../../atoms/src/components/toolti
27
27
  import { default as CxTypography } from '../../../../../atoms/src/components/typography/typography.ts';
28
28
  import { default as CxVisuallyHidden } from '../../../../../atoms/src/components/visually-hidden/visually-hidden.ts';
29
29
  import { default as CortexElement } from '../../../../../base/src/cortex-element.ts';
30
- import { CxFontPicker, CxIconPicker } from '../../../../../molecules/src/index.ts';
31
30
  import { default as CxAssetFormatPicker } from '../../../../../molecules/src/asset-format-picker/asset-format-picker.ts';
32
31
  import { default as CxAssetPicker } from '../../../../../molecules/src/asset-picker/asset-picker.ts';
33
32
  import { default as CxBicolorPicker } from '../../../../../molecules/src/bicolor-picker/bicolor-picker.ts';
@@ -36,6 +35,8 @@ import { default as CxConfirmPopover } from '../../../../../molecules/src/confir
36
35
  import { default as CxCornerPositionInputGroup } from '../../../../../molecules/src/corner-position-input-group/corner-position-input-group.ts';
37
36
  import { default as CxDownloadFormatPicker } from '../../../../../molecules/src/download-format-picker/download-format-picker.ts';
38
37
  import { default as CxDynamicSelect } from '../../../../../molecules/src/dynamic-select/dynamic-select.ts';
38
+ import { default as CxFontPicker } from '../../../../../molecules/src/font-picker/font-picker.ts';
39
+ import { default as CxIconPicker } from '../../../../../molecules/src/icon-picker/icon-picker.ts';
39
40
  import { default as CxPaddingInputGroup } from '../../../../../molecules/src/padding-input-group/padding-input-group.ts';
40
41
  import { default as CxPositionPicker } from '../../../../../molecules/src/position-picker/position-picker.ts';
41
42
  import { default as CxShadowInputGroup } from '../../../../../molecules/src/shadow-input-group/shadow-input-group.ts';
@@ -55,6 +55,11 @@ export default class CxGalleryPicker extends CortexElement implements CortexForm
55
55
  * The asset format code used to resolve image src URLs.
56
56
  */
57
57
  format: string;
58
+ /**
59
+ * Whether `format` was picked by hand. When false each item's format follows its own
60
+ * file extension instead.
61
+ */
62
+ manualFormat: boolean;
58
63
  /**
59
64
  * The boundary property of the confirm popover's dropdown/dialog popup.
60
65
  */
@@ -69,6 +74,7 @@ export default class CxGalleryPicker extends CortexElement implements CortexForm
69
74
  loading: boolean;
70
75
  masonryData: Array<{
71
76
  alt?: string;
77
+ extension?: string;
72
78
  id: string;
73
79
  rawId?: string;
74
80
  src?: string;
@@ -27,6 +27,7 @@ type Attributes = {
27
27
  'highlight-drop-shadow': boolean;
28
28
  'item-height': string;
29
29
  loop: boolean;
30
+ 'manual-format'?: boolean;
30
31
  navigation: string;
31
32
  orientation: string;
32
33
  'peek-slides': boolean;
@@ -29,6 +29,7 @@ type Attribute = {
29
29
  'highlight-siblings-fade-out': boolean;
30
30
  'item-height': string;
31
31
  'large-content-position': GalleryItemContentPosition;
32
+ 'manual-format'?: boolean;
32
33
  'max-rows': string;
33
34
  navigation: 'both' | 'arrows' | 'pagination';
34
35
  orientation: Orientation;
@@ -32,6 +32,8 @@ type Attribute = {
32
32
  'highlight-border'?: CxImage['highlightBorder'];
33
33
  'highlight-color-overlay'?: CxImage['highlightColorOverlay'];
34
34
  'highlight-drop-shadow'?: CxImage['highlightDropShadow'];
35
+ 'manual-format'?: CxImage['manualFormat'];
36
+ 'manual-format-dark-mode'?: CxImage['manualFormatDarkMode'];
35
37
  'object-fit': CxImage['objectFit'];
36
38
  'open-in-new-tab'?: CxImage['openInNewTab'];
37
39
  'page-url'?: CxImage['pageUrl'];
@@ -4,6 +4,7 @@ import { LocalizeController } from '../../../../utils/src/custom-element/i18n';
4
4
  type Attributes = {
5
5
  data: string;
6
6
  format: string;
7
+ 'manual-format'?: boolean;
7
8
  'min-tab-width': string;
8
9
  'multi-language': boolean;
9
10
  'navigation-arrows': boolean;
@@ -30,6 +30,7 @@ type Attribute = {
30
30
  height: CxVideo['height'];
31
31
  'height-mode': CxVideo['heightMode'];
32
32
  loop: CxVideo['loop'];
33
+ 'manual-thumbnail-format'?: boolean;
33
34
  name: CxVideo['name'];
34
35
  'name-source-field': CxVideo['nameSourceField'];
35
36
  'open-in-new-tab'?: CxVideo['openInNewTab'];
@@ -70,6 +70,7 @@ export default class ConfigsController {
70
70
  'highlight-drop-shadow': boolean;
71
71
  'item-height': string;
72
72
  loop: boolean;
73
+ 'manual-format'?: boolean;
73
74
  navigation: string;
74
75
  orientation: string;
75
76
  'peek-slides': boolean;
@@ -204,6 +205,7 @@ export default class ConfigsController {
204
205
  'highlight-siblings-fade-out': boolean;
205
206
  'item-height': string;
206
207
  'large-content-position': import('../../../types/src/highlightable-element').HighlightableElementContentPosition;
208
+ 'manual-format'?: boolean;
207
209
  'max-rows': string;
208
210
  navigation: "both" | "arrows" | "pagination";
209
211
  orientation: import('../../../types/src/index.ts').Orientation;
@@ -264,6 +266,8 @@ export default class ConfigsController {
264
266
  'highlight-border'?: import('./blocks/image/image').default["highlightBorder"];
265
267
  'highlight-color-overlay'?: import('./blocks/image/image').default["highlightColorOverlay"];
266
268
  'highlight-drop-shadow'?: import('./blocks/image/image').default["highlightDropShadow"];
269
+ 'manual-format'?: import('./blocks/image/image').default["manualFormat"];
270
+ 'manual-format-dark-mode'?: import('./blocks/image/image').default["manualFormatDarkMode"];
267
271
  'object-fit': import('./blocks/image/image').default["objectFit"];
268
272
  'open-in-new-tab'?: import('./blocks/image/image').default["openInNewTab"];
269
273
  'page-url'?: import('./blocks/image/image').default["pageUrl"];
@@ -299,6 +303,7 @@ export default class ConfigsController {
299
303
  }>[] | import('../../../types/src/content-builder').PropertyConfig<{
300
304
  data: string;
301
305
  format: string;
306
+ 'manual-format'?: boolean;
302
307
  'min-tab-width': string;
303
308
  'multi-language': boolean;
304
309
  'navigation-arrows': boolean;
@@ -332,6 +337,7 @@ export default class ConfigsController {
332
337
  height: import('./blocks/video/video').default["height"];
333
338
  'height-mode': import('./blocks/video/video').default["heightMode"];
334
339
  loop: import('./blocks/video/video').default["loop"];
340
+ 'manual-thumbnail-format'?: boolean;
335
341
  name: import('./blocks/video/video').default["name"];
336
342
  'name-source-field': import('./blocks/video/video').default["nameSourceField"];
337
343
  'open-in-new-tab'?: import('./blocks/video/video').default["openInNewTab"];
@@ -412,6 +418,7 @@ export default class ConfigsController {
412
418
  'highlight-drop-shadow': boolean;
413
419
  'item-height': string;
414
420
  loop: boolean;
421
+ 'manual-format'?: boolean;
415
422
  navigation: string;
416
423
  orientation: string;
417
424
  'peek-slides': boolean;
@@ -543,6 +550,7 @@ export default class ConfigsController {
543
550
  'highlight-siblings-fade-out': boolean;
544
551
  'item-height': string;
545
552
  'large-content-position': import('../../../types/src/highlightable-element').HighlightableElementContentPosition;
553
+ 'manual-format'?: boolean;
546
554
  'max-rows': string;
547
555
  navigation: "both" | "arrows" | "pagination";
548
556
  orientation: import('../../../types/src/index.ts').Orientation;
@@ -575,6 +583,7 @@ export default class ConfigsController {
575
583
  } | {
576
584
  data: string;
577
585
  format: string;
586
+ 'manual-format'?: boolean;
578
587
  'min-tab-width': string;
579
588
  'multi-language': boolean;
580
589
  'navigation-arrows': boolean;
@@ -608,6 +617,7 @@ export default class ConfigsController {
608
617
  height: import('./blocks/video/video').default["height"];
609
618
  'height-mode': import('./blocks/video/video').default["heightMode"];
610
619
  loop: import('./blocks/video/video').default["loop"];
620
+ 'manual-thumbnail-format'?: boolean;
611
621
  name: import('./blocks/video/video').default["name"];
612
622
  'name-source-field': import('./blocks/video/video').default["nameSourceField"];
613
623
  'open-in-new-tab'?: import('./blocks/video/video').default["openInNewTab"];
@@ -59,6 +59,7 @@ export default class StyleController {
59
59
  defaultFormat?: string;
60
60
  dialogLabel?: string;
61
61
  formatKey?: string;
62
+ manualFormatKey?: string;
62
63
  multiple?: boolean;
63
64
  noCrop?: boolean;
64
65
  noResize?: boolean;
@@ -102,6 +103,7 @@ export default class StyleController {
102
103
  galleryPickerConfigs?: {
103
104
  dialog: import('../../../types/src/content-builder').DialogType;
104
105
  formatKey?: string;
106
+ manualFormatKey?: string;
105
107
  transformationRecordIdKey?: string;
106
108
  transformationsKey?: string;
107
109
  };