@orangelogic/design-system 2.191.0 → 2.193.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 (62) hide show
  1. package/library/chunks/{asset-link-format.CEDcHah6.js → asset-link-format.BX1hdLgZ.js} +1249 -1083
  2. package/library/chunks/{color-swatch-group.tnhiQ0jp.js → color-swatch-group.BpEQJM1b.js} +4 -3
  3. package/library/chunks/{confirm-popover.CrQKEChc.js → confirm-popover.jCP9CdcD.js} +1 -1
  4. package/library/chunks/content-builder.BX4pHujE.js +60 -0
  5. package/library/chunks/{dialog.CWGtufDA.js → dialog.B6hZ7fvn.js} +2 -2
  6. package/library/chunks/{document-viewer.C90j1Xrr.js → document-viewer.DZsbpf0x.js} +3 -2
  7. package/library/chunks/{image.CTMzUqCC.js → image.BSvc6eti.js} +194 -191
  8. package/library/chunks/{toast.CXEAfCvN.js → toast.C5Ir5yKA.js} +1 -1
  9. package/library/chunks/transformation.CkwgrwKQ.js +312 -0
  10. package/library/components/asset-link-format.js +2 -2
  11. package/library/components/atoms.js +3 -3
  12. package/library/components/color-swatch-group.js +3 -3
  13. package/library/components/confirm-popover.js +2 -2
  14. package/library/components/cropper.js +1 -1
  15. package/library/components/dialog.js +1 -1
  16. package/library/components/document-viewer.js +2 -2
  17. package/library/components/drawer.js +2 -2
  18. package/library/components/file-on-demand.js +2 -2
  19. package/library/components/image.js +2 -3
  20. package/library/components/masonry.js +110 -79
  21. package/library/components/molecules.js +1 -1
  22. package/library/components/organisms.js +2 -2
  23. package/library/components/popup.js +100 -97
  24. package/library/components/select.js +16 -11
  25. package/library/components/types.js +22562 -22239
  26. package/library/components/video.js +1 -1
  27. package/library/package.json +1 -1
  28. package/library/packages/atoms/src/components/image/image.d.ts +38 -4
  29. package/library/packages/atoms/src/components/popup/popup.d.ts +11 -0
  30. package/library/packages/atoms/src/components/select/select.d.ts +8 -0
  31. package/library/packages/events/src/cx-asset-transformation-dialog-confirm.d.ts +2 -0
  32. package/library/packages/molecules/src/cropper/cropper.d.ts +0 -1
  33. package/library/packages/molecules/src/cropper/react/Cropper.d.ts +0 -1
  34. package/library/packages/molecules/src/gallery-item/gallery-item.d.ts +10 -0
  35. package/library/packages/molecules/src/masonry/masonry.d.ts +24 -0
  36. package/library/packages/organisms/src/asset-link-format/asset-link-format.d.ts +46 -2
  37. package/library/packages/organisms/src/asset-link-format/components/asset-link-format-proxy/asset-link-format-proxy.d.ts +36 -1
  38. package/library/packages/organisms/src/asset-transformation-dialog/asset-transformation-dialog.d.ts +20 -2
  39. package/library/packages/organisms/src/bento-grid/bento-grid.d.ts +101 -0
  40. package/library/packages/organisms/src/carousel/carousel.d.ts +26 -0
  41. package/library/packages/organisms/src/content-builder/blocks/image/image.d.ts +67 -1
  42. package/library/packages/organisms/src/content-builder/blocks/video/video.d.ts +5 -0
  43. package/library/packages/organisms/src/content-builder/components/config-form/config-form.d.ts +2 -1
  44. package/library/packages/organisms/src/content-builder/components/gallery-picker/gallery-picker.d.ts +6 -0
  45. package/library/packages/organisms/src/content-builder/configs/carousel.d.ts +1 -0
  46. package/library/packages/organisms/src/content-builder/configs/gallery.d.ts +1 -0
  47. package/library/packages/organisms/src/content-builder/configs/image.d.ts +2 -0
  48. package/library/packages/organisms/src/content-builder/configs/timeline.d.ts +1 -0
  49. package/library/packages/organisms/src/content-builder/configs/video.d.ts +1 -0
  50. package/library/packages/organisms/src/content-builder/configs-controller.d.ts +10 -0
  51. package/library/packages/organisms/src/content-builder/styleController.d.ts +2 -0
  52. package/library/packages/services/src/api/asset/asset.d.ts +10 -1
  53. package/library/packages/tools/src/fetch-image/fetch-image.d.ts +28 -5
  54. package/library/packages/types/src/asset-link-format.d.ts +0 -1
  55. package/library/packages/types/src/content-builder.d.ts +7 -0
  56. package/library/packages/types/src/gallery-item.d.ts +2 -0
  57. package/library/packages/types/src/masonry.d.ts +2 -0
  58. package/library/packages/utils/src/transformation/transformation.d.ts +100 -0
  59. package/library/react-web-component.d.ts +63 -7
  60. package/library/utils.js +193 -182
  61. package/package.json +1 -1
  62. package/library/chunks/transformation.8uLv6uwG.js +0 -264
@@ -41,12 +41,13 @@ export default class CxSbImage extends CxImage {
41
41
  'cx-resize-observer': typeof import('../../../../../atoms/src/index.ts').CxResizeObserver;
42
42
  'cx-skeleton': typeof import('../../../../../atoms/src/index.ts').CxSkeleton;
43
43
  'cx-space': typeof import('../../../../../atoms/src/index.ts').CxSpace;
44
- 'cx-spinner': typeof import('../../../../../atoms/src/index.ts').CxSpinner;
45
44
  };
46
45
  /**
47
46
  * Override the default behavior of retrying to load the image when it fails to load.
48
47
  */
49
48
  retryOnError: boolean;
49
+ /** Content-builder images keep their measured box visible while the asset loads. */
50
+ skeleton: boolean;
50
51
  /**
51
52
  * The path to the image to load in dark mode.
52
53
  */
@@ -87,6 +88,14 @@ export default class CxSbImage extends CxImage {
87
88
  * Asset transformation proxy format key for dark mode.
88
89
  */
89
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;
90
99
  /**
91
100
  * Asset transformations applied to the image.
92
101
  */
@@ -162,6 +171,22 @@ export default class CxSbImage extends CxImage {
162
171
  private resolvedSrc;
163
172
  /** Fresh URL re-resolved when the stored `srcDarkMode` has expired. */
164
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
+ /** Width of the proxy currently displayed; caps `srcset` so it never asks to upscale. */
180
+ private assetProxyWidth;
181
+ /**
182
+ * Whether an asset fetch has reported back for the current record.
183
+ *
184
+ * Tracked separately from `assetExtension` because "no extension" is a legitimate
185
+ * answer — a missing asset or a record without the field both yield an empty string.
186
+ * Gating on the empty string alone would hold `srcset` back forever in those cases;
187
+ * gating on this flag releases it as soon as the answer is in, whatever it says.
188
+ */
189
+ private hasResolvedAssetExtension;
165
190
  /**
166
191
  * Space list supplied by `cx-content-builder-viewer`, which fetches it once per
167
192
  * surface. The only source — this block never fetches the list itself.
@@ -192,6 +217,24 @@ export default class CxSbImage extends CxImage {
192
217
  get currentRecordId(): string;
193
218
  get currentSrc(): string;
194
219
  get currentTransformations(): Transformation[];
220
+ /** Whether the variant being displayed had its format picked by hand. */
221
+ get isCurrentFormatManual(): boolean;
222
+ /**
223
+ * The proxy format of the variant actually being displayed.
224
+ *
225
+ * Under `Auto` the asset's extension decides, so this stays a real proxy name and every
226
+ * consumer — the transformation URL and `srcset` alike — reads the same resolved value.
227
+ */
228
+ get currentFormat(): string;
229
+ /**
230
+ * Fields the child `cx-asset-data-display` must fetch for this block.
231
+ *
232
+ * The extension is always requested rather than only for the format that can serve
233
+ * an animated original. Requesting it unconditionally keeps the fetch shape stable
234
+ * (it does not change when the author switches format) and means `srcset` never has
235
+ * to wait on a follow-up fetch to learn whether this asset may be resized.
236
+ */
237
+ private get requestedAssetFields();
195
238
  get highlighterTabindex(): "0" | undefined;
196
239
  get highlighterRole(): "button" | "img";
197
240
  get highlighterClass(): {
@@ -214,10 +257,25 @@ export default class CxSbImage extends CxImage {
214
257
  * Whether the image has an click action.
215
258
  */
216
259
  private get hasClickAction();
260
+ /**
261
+ * The rendered width in CSS pixels, used as the `sizes` hint so the browser can pick
262
+ * the smallest `srcset` candidate that still covers the box.
263
+ *
264
+ * A `%` width carries no pixel value, so the measured `clientWidth` is used instead.
265
+ * Returns 0 when neither is known yet (before first layout), which makes the caller
266
+ * omit `sizes` and fall back to the browser's default `100vw` assumption.
267
+ */
268
+ private get displayWidth();
217
269
  handleClickActionChange(): Promise<void>;
218
270
  handleClickSpaceChange(): void;
219
271
  handleObjectFitChange(): Promise<void>;
220
272
  handleSrcChange(): void;
273
+ /**
274
+ * Drops a cached extension once the asset it described is replaced, so a new record
275
+ * cannot inherit the previous one's answer about whether it may be resized — nor its
276
+ * resolved flag, which would let `srcset` be built before the new answer arrives.
277
+ */
278
+ handleRecordIdChangeForExtension(): void;
221
279
  handleFetchedAssetDataChange(): void;
222
280
  /**
223
281
  * Support CMS5 click action for the image.
@@ -230,6 +288,14 @@ export default class CxSbImage extends CxImage {
230
288
  * own `cx-asset-data-display` fetch) into alt text and overlay content.
231
289
  */
232
290
  private applyFetchedAssetData;
291
+ /**
292
+ * Captures the asset's extension from a fetch result and marks the answer as in.
293
+ *
294
+ * A blank value leaves any previously known extension in place — a response that
295
+ * omitted the field says nothing about the asset — but still resolves the wait, so a
296
+ * record whose extension never arrives does not block `srcset` indefinitely.
297
+ */
298
+ private applyExtensionFromAssetData;
233
299
  /**
234
300
  * A stored space URL breaks once the space moves domain, so the link target is
235
301
  * 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
  };
@@ -1,4 +1,4 @@
1
- import { GetAllFormatCodesResponse, GetAssetsInFolderRequest, GetAssetsInFolderResponse, GetAssetsRequest, GetAssetsResponse, GetAuthorizedObjectsRequest, GetAuthorizedObjectsResponse, GetAvailableProxiesResponse, GetCropZoneSuggestionRequest, GetCropZoneSuggestionResponse, GetTransformAssetLinkResponse, SearchAssetsParams, SearchAssetsResponse } from './asset.types';
1
+ import { GetAllFormatCodesResponse, GetAssetsInFolderRequest, GetAssetsInFolderResponse, GetAssetsRequest, GetAssetsResponse, GetAuthorizedObjectsRequest, GetAuthorizedObjectsResponse, GetAvailableProxiesResponse, GetCropZoneSuggestionRequest, GetCropZoneSuggestionResponse, GetTransformAssetLinkResponse, SearchAssetsItem, SearchAssetsParams, SearchAssetsResponse } from './asset.types';
2
2
 
3
3
  export declare const DEFAULT_VIEW_SIZE = "CoreField.LargeSizePreview";
4
4
  export declare const FIELD_CORTEX_PATH = "Document.CortexPath";
@@ -19,6 +19,8 @@ export declare const FIELD_ORIGINAL_FILE_NAME = "CoreField.OriginalFileName";
19
19
  export declare const FIELD_UPDATED_FILE_NAME = "CoreField.UpdatedFileName";
20
20
  export declare const FIELD_LARGE_SIZE_PREVIEW_ID = "Document.DocumentDirectRepresentativeRID";
21
21
  export declare const LIBRARY_NAME = "Library";
22
+ /** Appended to a `path_*` key to carry that proxy's rendered width alongside its URI. */
23
+ export declare const MEDIA_FIELD_WIDTH_SUFFIX = "__width";
22
24
  export declare const MESSAGE_NEW_LINE = "\n";
23
25
  export declare const ORIGINAL_VIEW_SIZE = "CoreField.OriginalPreview";
24
26
  export declare const FIELD_DOC_SUBTYPE = "Document.DocSubType";
@@ -41,6 +43,13 @@ export declare function apiGetTransformAssetLink({ assetId, extension, format, s
41
43
  useSession?: string;
42
44
  }): Promise<GetTransformAssetLinkResponse | null>;
43
45
  export declare function apiGetAssets({ extraFields, getPermanentAssetsPaths, isSiteBuilder, recordIds, securityByPassToken, token, }: GetAssetsRequest): Promise<GetAssetsResponse>;
46
+ /**
47
+ * Reads the pixel width a `path_*` proxy field actually has.
48
+ *
49
+ * Each proxy is rendered at its own size, so this is the ceiling for resizing that URL —
50
+ * distinct from `CoreField.MaximumWidth`, which describes the original file.
51
+ */
52
+ export declare function readSearchAssetItemWidth(item: SearchAssetsItem, field: string): number | undefined;
44
53
  export declare function apiGetAssetsInFolder({ countPerPage, directParentFolderIdentifier, extraFields, getPermanentAssetsPaths, isSiteBuilder, limitedDocTypes, pageNumber, parentFolderIdentifier, searchTerm, securityByPassToken, sortOrder, token, }: GetAssetsInFolderRequest): Promise<GetAssetsInFolderResponse>;
45
54
  export declare function apiGetCropFocusMode({ autoCropMode, cropHeight, cropWidth, imageUrl, useSession, }: GetCropZoneSuggestionRequest): Promise<GetCropZoneSuggestionResponse | null>;
46
55
  export declare function apiGetAvailableProxies({ assetRecordId, isSiteBuilder, siteUrl, token, useSession, }: {
@@ -28,46 +28,69 @@ export declare class FetchImageController implements ReactiveController {
28
28
  constructor(host: ReactiveElement, options?: FetchImageControllerOptions);
29
29
  get totalDataCount(): number;
30
30
  setSecurityByPassToken(token: string | undefined): void;
31
- fetchImages({ end, extraFields, format, start, transformations, }: {
31
+ /**
32
+ * Changes how many items each request asks for.
33
+ *
34
+ * A new size moves every page boundary, so cached pages are dropped and the next fetch
35
+ * starts from page 1. `data` is kept — it is indexed absolutely, so the refetch
36
+ * overwrites in place instead of blanking the grid.
37
+ *
38
+ * Shrinking is ignored once pages are cached: collapsing already has what it needs.
39
+ */
40
+ setPageSize(pageSize: number): void;
41
+ fetchImages({ end, extraFields, format, manualFormat, start, transformations, }: {
32
42
  end: number;
33
43
  extraFields: string[];
34
44
  format?: string;
45
+ /**
46
+ * When false, `format` is ignored and each item resolves its own from its file
47
+ * extension. Defaults to true so existing callers keep their explicit format.
48
+ */
49
+ manualFormat?: boolean;
35
50
  start: number;
36
51
  transformations?: Transformation[];
37
52
  }): Promise<ExtendedGalleryItem[] | undefined>;
38
- fetchImagesInFolderBySlide({ activeSlide, extraFields, folderId, forceRefetch, format, minLimit, noPlaceholders, transformations, }: {
53
+ fetchImagesInFolderBySlide({ activeSlide, extraFields, folderId, forceRefetch, format, manualFormat, minLimit, noPlaceholders, transformations, }: {
39
54
  activeSlide: number;
40
55
  extraFields?: string[];
41
56
  folderId: string;
42
57
  forceRefetch?: boolean;
43
58
  format?: string;
59
+ manualFormat?: boolean;
44
60
  minLimit?: number;
45
61
  noPlaceholders?: boolean;
46
62
  transformations?: Transformation[];
47
63
  }): Promise<ExtendedGalleryItem[]>;
48
- fetchImagesByIDs({ extraFields, format, recordIds, transformations, }: {
64
+ fetchImagesByIDs({ extraFields, format, manualFormat, recordIds, transformations, }: {
49
65
  extraFields?: string[];
50
66
  format?: string;
67
+ /**
68
+ * When false, `format` is ignored and each item resolves its own from its file
69
+ * extension. Defaults to true so existing callers keep their explicit format.
70
+ */
71
+ manualFormat?: boolean;
51
72
  recordIds: string[];
52
73
  transformations?: Transformation[];
53
74
  }): Promise<ExtendedGalleryItem[]>;
54
- fetchImagesInFolderByPage({ extraFields, folderId, forceRefetch, format, noPlaceholders, page, pageSize, transformations, }: {
75
+ fetchImagesInFolderByPage({ extraFields, folderId, forceRefetch, format, manualFormat, noPlaceholders, page, pageSize, transformations, }: {
55
76
  extraFields?: string[];
56
77
  folderId: string;
57
78
  forceRefetch?: boolean;
58
79
  format?: string;
80
+ manualFormat?: boolean;
59
81
  noPlaceholders?: boolean;
60
82
  page: number;
61
83
  pageSize?: number;
62
84
  transformations?: Transformation[];
63
85
  }): Promise<ExtendedGalleryItem[]>;
64
- fetchImagesInFolderByChunk({ chunkSize: rawChunkSize, end, extraFields, folderId, forceRefetch, format, start, transformations, }: {
86
+ fetchImagesInFolderByChunk({ chunkSize: rawChunkSize, end, extraFields, folderId, forceRefetch, format, manualFormat, start, transformations, }: {
65
87
  chunkSize?: number;
66
88
  end?: number;
67
89
  extraFields?: string[];
68
90
  folderId: string;
69
91
  forceRefetch?: boolean;
70
92
  format?: string;
93
+ manualFormat?: boolean;
71
94
  start?: number;
72
95
  transformations?: Transformation[];
73
96
  }): AsyncGenerator<ExtendedGalleryItem[], void, unknown>;
@@ -58,7 +58,6 @@ export type Asset = {
58
58
  identifier: string;
59
59
  imageUrl: string;
60
60
  name: string;
61
- originalUrl: string;
62
61
  scrubUrl: string;
63
62
  size: string;
64
63
  tags: string;
@@ -64,6 +64,11 @@ export type PropertyConfig<T = Record<string, any>> = Omit<TraitProperties, 'opt
64
64
  defaultFormat?: string;
65
65
  dialogLabel?: string;
66
66
  formatKey?: string;
67
+ /**
68
+ * The block-attribute key that records whether the format was picked by hand. When
69
+ * absent or false the format follows the asset's file extension.
70
+ */
71
+ manualFormatKey?: string;
67
72
  multiple?: boolean;
68
73
  noCrop?: boolean;
69
74
  noResize?: boolean;
@@ -114,6 +119,8 @@ export type PropertyConfig<T = Record<string, any>> = Omit<TraitProperties, 'opt
114
119
  dialog: DialogType;
115
120
  /** The block-attribute key for the format used to resolve records' src URLs after picking. */
116
121
  formatKey?: string;
122
+ /** The block-attribute key recording whether that format was picked by hand. */
123
+ manualFormatKey?: string;
117
124
  transformationRecordIdKey?: string;
118
125
  transformationsKey?: string;
119
126
  };
@@ -25,10 +25,12 @@ export type GalleryItem = {
25
25
  className?: string;
26
26
  details?: string;
27
27
  docType?: MediaType | '';
28
+ extension?: string;
28
29
  filler?: boolean;
29
30
  header?: string;
30
31
  id: string;
31
32
  isClone?: boolean;
33
+ maxWidth?: string;
32
34
  name?: string;
33
35
  objectFit?: ObjectFit;
34
36
  openInNewTab?: boolean;
@@ -6,9 +6,11 @@ export declare enum MasonryVariant {
6
6
  }
7
7
  export type MasonryItem = {
8
8
  alt?: string;
9
+ extension?: string;
9
10
  hasError?: boolean;
10
11
  id: string;
11
12
  loading?: boolean;
13
+ maxWidth?: string;
12
14
  objectFit?: ObjectFit;
13
15
  src: string;
14
16
  };
@@ -1,5 +1,12 @@
1
1
  import { Asset, Parameter, Transformation } from '../../../types/src/asset-link-format';
2
2
 
3
+ /**
4
+ * Width ladder used for `srcset` candidates, in CSS pixels.
5
+ *
6
+ * Kept as a small fixed ladder rather than a per-item computed width so that many
7
+ * items sharing a display size resolve to the same URLs and stay CDN-cache friendly.
8
+ */
9
+ export declare const SRCSET_WIDTH_LADDER: readonly [400, 800, 1200, 1600, 2400];
3
10
  export declare function buildTransformationString({ asset, baseUrl, extension, options, parameters, transformations, useSession, }: {
4
11
  asset?: Asset;
5
12
  baseUrl?: string;
@@ -19,3 +26,96 @@ export declare function buildTransformationString({ asset, baseUrl, extension, o
19
26
  * and merged into an existing `/t/`. Other URLs keep the plain append behavior.
20
27
  */
21
28
  export declare function applyTransformationsToUrl(url: string, transformations: Transformation[]): string;
29
+ /**
30
+ * Inserts a width-only resize into an asset-link URL, preserving any transformations
31
+ * already present.
32
+ *
33
+ * `applyTransformationsToUrl` is deliberately not reused here: it *replaces* an existing
34
+ * `/t/` segment (dropping a configured crop/rotate/quality) and drops the prettyName tail
35
+ * when doing so. This function prepends the resize to an existing segment instead, so a
36
+ * user's configured transformations survive.
37
+ *
38
+ * Returns the URL unchanged when it is not an asset-link URL, so arbitrary external
39
+ * sources are never rewritten.
40
+ */
41
+ export declare function applyWidthToAssetUrl(url: string, width: number): string;
42
+ /**
43
+ * Whether the URL already carries a transformation segment.
44
+ *
45
+ * An existing `/t/` means a width was already chosen deliberately (a configured resize,
46
+ * crop or proxy format), so a ladder must not add a competing one.
47
+ */
48
+ export declare function hasTransformSegment(url: string): boolean;
49
+ /** Proxy format that is always transcoded to a raster image, whatever the source file is. */
50
+ export declare const AUTO_FALLBACK_FORMAT = "TR1";
51
+ /**
52
+ * Largest original file `Auto` will serve untouched, in bytes.
53
+ *
54
+ * Past this the transcoded proxy wins even for extensions that would normally keep their
55
+ * original: delivering a very large original costs the viewer more than the animation or
56
+ * alpha it preserves.
57
+ */
58
+ export declare const AUTO_ORIGINAL_FORMAT_MAX_BYTES: number;
59
+ /**
60
+ * Reads an asset file size into bytes, or `undefined` when the value says nothing usable.
61
+ *
62
+ * `CoreField.FileSize` is typed as a string and has been observed both as a plain byte
63
+ * count (`'1024'`) and as a formatted value (`'63.47 KB'`), so both are accepted. A bare
64
+ * number is read as bytes, matching the raw form.
65
+ *
66
+ * Returns `undefined` rather than `0` for unusable input so callers can tell "no size
67
+ * reported" apart from "genuinely empty file" — the two lead to different decisions.
68
+ */
69
+ export declare function parseFileSizeToBytes(size: string | number | null | undefined): number | undefined;
70
+ /**
71
+ * The largest width `Auto` may request for an item.
72
+ *
73
+ * Each proxy is rendered at a fixed size (a `TR1` may be 1200px where its `TRX` is 7360px),
74
+ * so resizing past it only asks the backend to upscale. Returns `undefined` under a manual
75
+ * format — the author's choice is left alone — and when the proxy reported no width.
76
+ */
77
+ export declare function resolveAutoMaxWidth(manualFormat: boolean, proxyWidth: string | number | null | undefined): number | undefined;
78
+ /**
79
+ * Picks the proxy format an asset should be served under when the author chose `Auto`
80
+ * instead of naming a format.
81
+ *
82
+ * Extensions that would lose something to a transcode (animation, alpha, bit depth) take
83
+ * the original-file proxy, but only up to `AUTO_ORIGINAL_FORMAT_MAX_BYTES`; everything
84
+ * else takes the transcoded raster proxy, which is the one `buildAssetSrcset` may resize.
85
+ *
86
+ * An unknown or missing extension resolves to the raster proxy — the safe default for the
87
+ * majority of assets, and the same value the format ladders already fall back to.
88
+ *
89
+ * An unknown *size* does not: a size the API did not report is treated as within the
90
+ * limit, so a missing field never silently strips a GIF of its animation.
91
+ */
92
+ export declare function resolveAutoFormat(extension: string | null | undefined, size?: string | number | null): string;
93
+ /**
94
+ * Builds a `srcset` value for an asset-link URL by emitting one width-only resize
95
+ * candidate per ladder entry, letting the browser fetch and decode only the pixels
96
+ * the layout actually needs.
97
+ *
98
+ * When `maxWidth` is known the list is bounded by the asset itself: rungs above it are
99
+ * dropped so the backend is never asked to upscale, rungs within
100
+ * `ORIGINAL_INSTEAD_OF_RESIZE_MARGIN` of it are dropped as near-duplicates, and the
101
+ * untransformed URL closes the list at its real width. That last candidate costs no
102
+ * render and is the only one that can serve the image sharp at full size.
103
+ *
104
+ * Returns an empty string when the URL is not an asset link, when it already carries
105
+ * a transformation (the width was configured upstream), or when it is an animated GIF
106
+ * served as the original file — resizing that flattens it to a still frame, so the
107
+ * original has to be delivered untouched.
108
+ */
109
+ export declare function buildAssetSrcset(url: string, options?: {
110
+ extension?: string | null;
111
+ format?: string;
112
+ maxWidth?: number;
113
+ widths?: readonly number[];
114
+ }): string;
115
+ /**
116
+ * Builds a `sizes` value from a known display width in CSS pixels.
117
+ *
118
+ * Rounded up to `step` so small layout changes (a resize that shifts a grid cell by a
119
+ * few pixels) do not produce a new value on every frame.
120
+ */
121
+ export declare function buildSizesFromDisplayWidth(displayWidth: number, step?: number): string;