@datocms/svelte 4.2.3 → 4.2.4

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/README.md CHANGED
@@ -37,6 +37,7 @@ A set of components to work faster with [DatoCMS](https://www.datocms.com/) in S
37
37
 
38
38
  Components:
39
39
 
40
+ - [`<ContentLink />` for Visual Editing with click-to-edit overlays](src/lib/components/ContentLink)
40
41
  - [`<Image />` and `<NakedImage />`](src/lib/components/Image)
41
42
  - [`<VideoPlayer />`](src/lib/components/VideoPlayer)
42
43
  - [`<StructuredText />`](src/lib/components/StructuredText)
@@ -0,0 +1,40 @@
1
+ <script>import { createController } from "@datocms/content-link";
2
+ import { onDestroy, onMount } from "svelte";
3
+ export let onNavigateTo = void 0;
4
+ export let currentPath = void 0;
5
+ export let enableClickToEdit = void 0;
6
+ export let stripStega = void 0;
7
+ export let root = void 0;
8
+ let controller = null;
9
+ let onNavigateToCallback = onNavigateTo;
10
+ $:
11
+ onNavigateToCallback = onNavigateTo;
12
+ onMount(() => {
13
+ controller = createController({
14
+ // Handle navigation requests from the Web Previews plugin
15
+ // Inside Visual mode, users can navigate to different URLs (like a browser bar)
16
+ // and the plugin will request the preview to navigate accordingly
17
+ // The callback is accessed via variable, so changes don't trigger recreation
18
+ onNavigateTo: onNavigateToCallback ? (path) => onNavigateToCallback?.(path) : void 0,
19
+ // Optionally limit scanning to a specific root
20
+ root,
21
+ // Control stega encoding stripping behavior
22
+ ...stripStega !== void 0 ? { stripStega } : {}
23
+ });
24
+ if (enableClickToEdit !== void 0) {
25
+ controller.enableClickToEdit(
26
+ enableClickToEdit === true ? void 0 : enableClickToEdit
27
+ );
28
+ }
29
+ });
30
+ $:
31
+ if (currentPath !== void 0 && controller) {
32
+ controller.setCurrentPath(currentPath);
33
+ }
34
+ onDestroy(() => {
35
+ if (controller) {
36
+ controller.dispose();
37
+ controller = null;
38
+ }
39
+ });
40
+ </script>
@@ -0,0 +1,40 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ /**
5
+ * Callback invoked when the Web Previews plugin requests navigation to a different URL.
6
+ * This is used for client-side routing integration.
7
+ *
8
+ * Example with SvelteKit: onNavigateTo={(path) => goto(path)}
9
+ */ onNavigateTo?: ((path: string) => void) | undefined;
10
+ /**
11
+ * Current pathname to sync with the Web Previews plugin.
12
+ * This keeps the plugin in sync with the current page being previewed.
13
+ *
14
+ * Example with SvelteKit: currentPath={$page.url.pathname}
15
+ */ currentPath?: string | undefined;
16
+ /**
17
+ * Enable click-to-edit on mount. Pass true for default behavior or an object with scrollToNearestTarget.
18
+ * If undefined, click-to-edit is disabled and editors can use Alt/Option key for temporary activation.
19
+ */ enableClickToEdit?: true | {
20
+ scrollToNearestTarget: true;
21
+ } | undefined;
22
+ /**
23
+ * Whether to strip stega encoding from text nodes after stamping.
24
+ */ stripStega?: boolean | undefined;
25
+ /**
26
+ * Ref to limit scanning to this root instead of document.
27
+ * Useful for limiting the scope of content link detection to a specific container.
28
+ */ root?: ParentNode | undefined;
29
+ };
30
+ events: {
31
+ [evt: string]: CustomEvent<any>;
32
+ };
33
+ slots: {};
34
+ };
35
+ export type ContentLinkProps = typeof __propDef.props;
36
+ export type ContentLinkEvents = typeof __propDef.events;
37
+ export type ContentLinkSlots = typeof __propDef.slots;
38
+ export default class ContentLink extends SvelteComponent<ContentLinkProps, ContentLinkEvents, ContentLinkSlots> {
39
+ }
40
+ export {};
@@ -0,0 +1,360 @@
1
+ # ContentLink component for Visual Editing
2
+
3
+ `<ContentLink />` is a Svelte component that enables **Visual Editing** for your DatoCMS content. It provides click-to-edit overlays that allow editors to click on any content element on your website to instantly open the DatoCMS editor and modify that specific field.
4
+
5
+ This component is built on top of the [`@datocms/content-link`](https://www.npmjs.com/package/@datocms/content-link) library and provides a seamless integration for Svelte and SvelteKit projects.
6
+
7
+ ## What is Visual Editing?
8
+
9
+ Visual Editing transforms how content editors interact with your website. Instead of navigating through forms and fields in a CMS, editors can:
10
+
11
+ 1. **See their content in context** - Preview exactly how content appears on the live site
12
+ 2. **Click to edit** - Click directly on any text, image, or field to open the editor
13
+ 3. **Navigate seamlessly** - Jump between pages in the preview, and the CMS follows along
14
+ 4. **Get instant feedback** - Changes in the CMS are reflected immediately in the preview
15
+
16
+ This drastically improves the editing experience, especially for non-technical users who can now edit content without understanding the underlying CMS structure.
17
+
18
+ ## Out-of-the-box features
19
+
20
+ - **Click-to-edit overlays**: Visual indicators showing which content is editable
21
+ - **Stega decoding**: Automatically detects and decodes editing metadata embedded in content
22
+ - **Keyboard shortcuts**: Hold Alt/Option to temporarily enable editing mode
23
+ - **Flash-all highlighting**: Show all editable areas at once for quick orientation
24
+ - **Bidirectional navigation**: Sync navigation between preview and DatoCMS editor
25
+ - **Framework-agnostic**: Works with SvelteKit or any routing solution
26
+ - **StructuredText integration**: Special support for complex structured content fields
27
+ - **[Web Previews plugin](https://www.datocms.com/marketplace/plugins/i/datocms-plugin-web-previews) integration**: Seamless integration with DatoCMS's editing interface
28
+
29
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
30
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
31
+
32
+ - [Installation](#installation)
33
+ - [Basic Setup](#basic-setup)
34
+ - [1. Fetch content with stega encoding](#1-fetch-content-with-stega-encoding)
35
+ - [2. Add ContentLink component to your app](#2-add-contentlink-component-to-your-app)
36
+ - [SvelteKit integration](#sveltekit-integration)
37
+ - [Enabling click-to-edit](#enabling-click-to-edit)
38
+ - [Flash-all highlighting](#flash-all-highlighting)
39
+ - [Props](#props)
40
+ - [StructuredText integration](#structuredtext-integration)
41
+ - [Edit groups with `data-datocms-content-link-group`](#edit-groups-with-data-datocms-content-link-group)
42
+ - [Edit boundaries with `data-datocms-content-link-boundary`](#edit-boundaries-with-data-datocms-content-link-boundary)
43
+ - [Manual overlays with `data-datocms-content-link-url`](#manual-overlays-with-data-datocms-content-link-url)
44
+ - [Low-level utilities](#low-level-utilities)
45
+ - [`decodeStega`](#decodestega)
46
+ - [`stripStega`](#stripstega)
47
+ - [Troubleshooting](#troubleshooting)
48
+ - [Click-to-edit overlays not appearing](#click-to-edit-overlays-not-appearing)
49
+ - [Navigation not syncing with Web Previews plugin](#navigation-not-syncing-with-web-previews-plugin)
50
+ - [StructuredText blocks not clickable](#structuredtext-blocks-not-clickable)
51
+
52
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ npm install --save @datocms/svelte
58
+ ```
59
+
60
+ The package includes `@datocms/content-link` as a dependency, which provides the underlying controller for Visual Editing functionality.
61
+
62
+ ## Basic Setup
63
+
64
+ Visual Editing requires two steps:
65
+
66
+ ### 1. Fetch content with stega encoding
67
+
68
+ When fetching content from DatoCMS, enable stega encoding to embed editing metadata:
69
+
70
+ ```js
71
+ import { executeQuery } from '@datocms/cda-client';
72
+
73
+ const query = `
74
+ query {
75
+ page {
76
+ title
77
+ content
78
+ }
79
+ }
80
+ `;
81
+
82
+ const result = await executeQuery(query, {
83
+ token: 'YOUR_API_TOKEN',
84
+ environment: 'main',
85
+ // Enable stega encoding
86
+ contentLink: 'v1',
87
+ // Set your site's base URL for editing links
88
+ baseEditingUrl: 'https://your-project.admin.datocms.com',
89
+ });
90
+ ```
91
+
92
+ The `contentLink` option encodes invisible metadata into text fields, while `baseEditingUrl` tells DatoCMS where your preview is hosted.
93
+
94
+ ### 2. Add ContentLink component to your app
95
+
96
+ Add the `<ContentLink />` component to your app. It doesn't render any visible output but sets up the click-to-edit functionality:
97
+
98
+ ```svelte
99
+ <script>
100
+ import { ContentLink } from '@datocms/svelte';
101
+ </script>
102
+
103
+ <ContentLink />
104
+
105
+ <!-- Your content here -->
106
+ ```
107
+
108
+ That's it! The component will automatically detect editable content and create interactive overlays.
109
+
110
+ ## SvelteKit integration
111
+
112
+ For SvelteKit projects, you can integrate with the routing system to enable full Web Previews plugin support:
113
+
114
+ ```svelte
115
+ <script>
116
+ import { ContentLink } from '@datocms/svelte';
117
+ import { goto } from '$app/navigation';
118
+ import { page } from '$app/stores';
119
+ </script>
120
+
121
+ <ContentLink
122
+ onNavigateTo={(path) => goto(path)}
123
+ currentPath={$page.url.pathname}
124
+ />
125
+
126
+ <!-- Your content here -->
127
+ ```
128
+
129
+ This integration enables:
130
+ - **Navigation from plugin**: When editors navigate to a different URL in the Visual Editing mode, your preview updates accordingly
131
+ - **Current path sync**: The plugin knows which page is currently being previewed
132
+
133
+ ## Enabling click-to-edit
134
+
135
+ Click-to-edit overlays are **not enabled by default**. Instead, editors can:
136
+
137
+ - **Hold Alt/Option key**: Temporarily enable click-to-edit mode while the key is held down
138
+ - **Release the key**: Disable click-to-edit mode when released
139
+
140
+ If you prefer to enable click-to-edit programmatically on mount, set the `enableClickToEdit` prop:
141
+
142
+ ```svelte
143
+ <ContentLink enableClickToEdit={true} />
144
+ ```
145
+
146
+ Or with scroll-to-nearest option:
147
+
148
+ ```svelte
149
+ <ContentLink enableClickToEdit={{ scrollToNearestTarget: true }} />
150
+ ```
151
+
152
+ ## Flash-all highlighting
153
+
154
+ The flash-all feature provides visual feedback by highlighting all editable elements on the page. This is useful for:
155
+ - Showing editors what content they can edit
156
+ - Debugging to verify Visual Editing is working correctly
157
+ - Onboarding new content editors
158
+
159
+ When you enable click-to-edit with the `scrollToNearestTarget` option, it triggers the flash-all effect:
160
+
161
+ ```svelte
162
+ <ContentLink enableClickToEdit={{ scrollToNearestTarget: true }} />
163
+ ```
164
+
165
+ The `scrollToNearestTarget` parameter scrolls to the nearest editable element, useful on long pages.
166
+
167
+ ## Props
168
+
169
+ | Prop | Type | Default | Description |
170
+ | ------------------- | ----------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
171
+ | `onNavigateTo` | `(path: string) => void` | - | Callback when [Web Previews plugin](https://www.datocms.com/marketplace/plugins/i/datocms-plugin-web-previews) requests navigation to a different page |
172
+ | `currentPath` | `string` | - | Current pathname to sync with [Web Previews plugin](https://www.datocms.com/marketplace/plugins/i/datocms-plugin-web-previews) |
173
+ | `enableClickToEdit` | `true \| { scrollToNearestTarget: true }` | - | Enable click-to-edit overlays on mount. Pass `true` or an object with options. If undefined, click-to-edit is disabled |
174
+ | `stripStega` | `boolean` | - | Whether to strip stega encoding from text nodes after stamping |
175
+ | `root` | `ParentNode` | - | Root element to limit scanning to instead of the entire document |
176
+
177
+ ## StructuredText integration
178
+
179
+ When rendering Structured Text fields, you'll want to make the entire structured text area clickable rather than just specific spans. DatoCMS provides special HTML attributes to control this behavior.
180
+
181
+ ### Edit groups with `data-datocms-content-link-group`
182
+
183
+ Wrap your StructuredText component with a container that has the `data-datocms-content-link-group` attribute. This makes the entire area clickable to edit the structured text field:
184
+
185
+ ```svelte
186
+ <script>
187
+ import { StructuredText } from '@datocms/svelte';
188
+ </script>
189
+
190
+ <div data-datocms-content-link-group>
191
+ <StructuredText data={content.structuredTextField} />
192
+ </div>
193
+ ```
194
+
195
+ This allows editors to click anywhere within the structured text content to edit it, rather than targeting small span elements.
196
+
197
+ ### Edit boundaries with `data-datocms-content-link-boundary`
198
+
199
+ When your Structured Text contains embedded blocks, you'll want those blocks to open their own specific record editor instead of the structured text field editor. Use the `data-datocms-content-link-boundary` attribute to stop the upward traversal:
200
+
201
+ ```svelte
202
+ <script>
203
+ import { StructuredText } from '@datocms/svelte';
204
+ import BlockComponent from './BlockComponent.svelte';
205
+ </script>
206
+
207
+ <div data-datocms-content-link-group>
208
+ <StructuredText
209
+ data={content.structuredTextField}
210
+ blocks={{
211
+ // Render custom blocks
212
+ myBlock: (props) => ({
213
+ component: BlockComponent,
214
+ props: {
215
+ block: props.record,
216
+ // Wrap the block with a boundary
217
+ useBoundary: true,
218
+ }
219
+ })
220
+ }}
221
+ />
222
+ </div>
223
+
224
+ <!-- In BlockComponent.svelte -->
225
+ <div data-datocms-content-link-boundary>
226
+ <h2>{block.title}</h2>
227
+ <p>{block.description}</p>
228
+ </div>
229
+ ```
230
+
231
+ In this example:
232
+ - Clicking on the main structured text content opens the structured text field editor
233
+ - Clicking on an embedded block opens that specific block's record editor
234
+
235
+ ## Manual overlays with `data-datocms-content-link-url`
236
+
237
+ For non-text fields like booleans, numbers, dates, and JSON, the DatoCMS API cannot embed stega-encoded metadata. In these cases, you can manually specify the edit URL using the `data-datocms-content-link-url` attribute.
238
+
239
+ The recommended approach is to use the `_editingUrl` field available on all records:
240
+
241
+ ```graphql
242
+ query {
243
+ product {
244
+ id
245
+ price
246
+ isActive
247
+ _editingUrl
248
+ }
249
+ }
250
+ ```
251
+
252
+ Then add the attribute to your element:
253
+
254
+ ```svelte
255
+ <span data-datocms-content-link-url={product._editingUrl}>
256
+ ${product.price}
257
+ </span>
258
+
259
+ <span data-datocms-content-link-url={product._editingUrl}>
260
+ {product.isActive ? 'Active' : 'Inactive'}
261
+ </span>
262
+ ```
263
+
264
+ This ensures the URL format is always correct and adapts automatically to any future changes.
265
+
266
+ ## Low-level utilities
267
+
268
+ The `@datocms/svelte` package re-exports utility functions from `@datocms/content-link` for working with stega-encoded content:
269
+
270
+ ### `decodeStega`
271
+
272
+ Decodes stega-encoded content to extract editing metadata:
273
+
274
+ ```typescript
275
+ import { decodeStega } from '@datocms/svelte';
276
+
277
+ const text = "Hello, world!"; // Contains invisible stega data
278
+ const decoded = decodeStega(text);
279
+
280
+ if (decoded) {
281
+ console.log('Editing URL:', decoded.url);
282
+ console.log('Clean text:', decoded.cleanText);
283
+ }
284
+ ```
285
+
286
+ ### `stripStega`
287
+
288
+ Removes stega encoding from text, returning clean text:
289
+
290
+ ```typescript
291
+ import { stripStega } from '@datocms/svelte';
292
+
293
+ const text = "Hello, world!"; // Contains invisible stega data
294
+ const clean = stripStega(text);
295
+
296
+ console.log(clean); // "Hello, world!" without encoding
297
+ ```
298
+
299
+ These utilities are useful when you need to:
300
+ - Extract clean text for meta tags or social sharing
301
+ - Check if content has stega encoding
302
+ - Debug Visual Editing issues
303
+ - Process stega-encoded content programmatically
304
+
305
+ ## Troubleshooting
306
+
307
+ ### Click-to-edit overlays not appearing
308
+
309
+ **Problem**: Overlays don't appear when clicking on content.
310
+
311
+ **Solutions**:
312
+ 1. Verify stega encoding is enabled in your API calls:
313
+ ```js
314
+ const result = await executeQuery(query, {
315
+ token: 'YOUR_API_TOKEN',
316
+ contentLink: 'v1',
317
+ baseEditingUrl: 'https://your-project.admin.datocms.com',
318
+ });
319
+ ```
320
+
321
+ 2. Check that `<ContentLink />` is mounted in your component tree
322
+
323
+ 3. Ensure you've enabled click-to-edit mode:
324
+ ```svelte
325
+ <ContentLink enableClickToEdit={true} />
326
+ ```
327
+ Or hold Alt/Option key while browsing
328
+
329
+ 4. Check browser console for errors
330
+
331
+ ### Navigation not syncing with Web Previews plugin
332
+
333
+ **Problem**: When you navigate in your preview, the DatoCMS editor doesn't follow along.
334
+
335
+ **Solutions**:
336
+ 1. Ensure you're providing both `onNavigateTo` and `currentPath` props:
337
+ ```svelte
338
+ <ContentLink
339
+ onNavigateTo={(path) => goto(path)}
340
+ currentPath={$page.url.pathname}
341
+ />
342
+ ```
343
+
344
+ 2. Verify `currentPath` updates when navigation occurs
345
+
346
+ 3. Check that `baseEditingUrl` in your API calls matches your preview URL
347
+
348
+ ### StructuredText blocks not clickable
349
+
350
+ **Problem**: Content within StructuredText blocks doesn't have click-to-edit overlays.
351
+
352
+ **Solutions**:
353
+ 1. Wrap StructuredText with `data-datocms-content-link-group`:
354
+ ```svelte
355
+ <div data-datocms-content-link-group>
356
+ <StructuredText data={content} />
357
+ </div>
358
+ ```
359
+
360
+ 2. Add `data-datocms-content-link-boundary` to custom blocks to prevent them from bubbling to the parent field
@@ -46,7 +46,7 @@ export type FaviconTag = SeoMetaTag | SeoLinkTag;
46
46
  export type SeoOrFaviconTag = SeoTag | FaviconTag;
47
47
  declare const __propDef: {
48
48
  props: {
49
- data?: (GenericTag | SeoOrFaviconTag)[] | undefined;
49
+ data?: Array<GenericTag | SeoOrFaviconTag>;
50
50
  };
51
51
  events: {
52
52
  [evt: string]: CustomEvent<any>;
@@ -4,17 +4,17 @@ import { type ResponsiveImageType } from '../NakedImage/utils';
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  /** The actual response you get from a DatoCMS `responsiveImage` GraphQL query */ data: ResponsiveImageType;
7
- /** Additional CSS className for root node */ class?: string | null | undefined;
8
- /** Additional CSS class for the `<picture />` tag */ pictureClass?: string | null | undefined;
9
- /** Additional CSS class for the image inside the `<picture />` tag */ imgClass?: string | null | undefined;
10
- /** Additional CSS class for the placeholder element */ placeholderClass?: string | null | undefined;
11
- /** Duration (in ms) of the fade-in transition effect upoad image loading */ fadeInDuration?: number | undefined;
12
- /** Indicate at what percentage of the placeholder visibility the loading of the image should be triggered. A value of 0 means that as soon as even one pixel is visible, the callback will be run. A value of 1.0 means that the threshold isn't considered passed until every pixel is visible */ intersectionThreshold?: number | undefined;
13
- /** Margin around the placeholder. Can have values similar to the CSS margin property (top, right, bottom, left). The values can be percentages. This set of values serves to grow or shrink each side of the placeholder element's bounding box before computing intersections */ intersectionMargin?: string | undefined;
14
- /** Additional CSS rules to add to the root node */ style?: string | null | undefined;
15
- /** Additional CSS rules to add to the `<picture />` tag */ pictureStyle?: string | null | undefined;
16
- /** Additional CSS rules to add to the image inside the `<picture />` tag */ imgStyle?: string | null | undefined;
17
- /** Additional CSS rules to add to the placeholder element */ placeholderStyle?: string | null | undefined;
7
+ /** Additional CSS className for root node */ class?: string | null;
8
+ /** Additional CSS class for the `<picture />` tag */ pictureClass?: string | null;
9
+ /** Additional CSS class for the image inside the `<picture />` tag */ imgClass?: string | null;
10
+ /** Additional CSS class for the placeholder element */ placeholderClass?: string | null;
11
+ /** Duration (in ms) of the fade-in transition effect upoad image loading */ fadeInDuration?: number;
12
+ /** Indicate at what percentage of the placeholder visibility the loading of the image should be triggered. A value of 0 means that as soon as even one pixel is visible, the callback will be run. A value of 1.0 means that the threshold isn't considered passed until every pixel is visible */ intersectionThreshold?: number;
13
+ /** Margin around the placeholder. Can have values similar to the CSS margin property (top, right, bottom, left). The values can be percentages. This set of values serves to grow or shrink each side of the placeholder element's bounding box before computing intersections */ intersectionMargin?: string;
14
+ /** Additional CSS rules to add to the root node */ style?: string | null;
15
+ /** Additional CSS rules to add to the `<picture />` tag */ pictureStyle?: string | null;
16
+ /** Additional CSS rules to add to the image inside the `<picture />` tag */ imgStyle?: string | null;
17
+ /** Additional CSS rules to add to the placeholder element */ placeholderStyle?: string | null;
18
18
  /**
19
19
  * The layout behavior of the image as the viewport changes size
20
20
  *
@@ -24,33 +24,33 @@ declare const __propDef: {
24
24
  * * `fixed`: the image dimensions will not change as the viewport changes (no responsiveness) similar to the native img element
25
25
  * * `responsive`: the image will scale the dimensions down for smaller viewports and scale up for larger viewports
26
26
  * * `fill`: image will stretch both width and height to the dimensions of the parent element, provided the parent element is `relative`
27
- **/ layout?: "fill" | "intrinsic" | "fixed" | "responsive" | undefined;
28
- /** Defines how the image will fit into its parent container when using layout="fill" */ objectFit?: CSS.PropertiesHyphen['object-fit'];
29
- /** Defines how the image is positioned within its parent element when using layout="fill". */ objectPosition?: CSS.PropertiesHyphen['object-position'];
30
- /** Whether the component should use a blurred image placeholder */ usePlaceholder?: boolean | undefined;
27
+ **/ layout?: "intrinsic" | "fixed" | "responsive" | "fill";
28
+ /** Defines how the image will fit into its parent container when using layout="fill" */ objectFit?: CSS.PropertiesHyphen["object-fit"];
29
+ /** Defines how the image is positioned within its parent element when using layout="fill". */ objectPosition?: CSS.PropertiesHyphen["object-position"];
30
+ /** Whether the component should use a blurred image placeholder */ usePlaceholder?: boolean;
31
31
  /**
32
32
  * The HTML5 `sizes` attribute for the image
33
33
  *
34
34
  * Learn more about srcset and sizes:
35
35
  * -> https://web.dev/learn/design/responsive-images/#sizes
36
36
  * -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
37
- **/ sizes?: string | null | undefined;
37
+ **/ sizes?: HTMLImageElement["sizes"] | null;
38
38
  /**
39
39
  * When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
40
40
  * You should use the priority property on any image detected as the Largest Contentful Paint (LCP) element. It may be appropriate to have multiple priority images, as different images may be the LCP element for different viewport sizes.
41
41
  * Should only be used when the image is visible above the fold.
42
- **/ priority?: boolean | undefined;
42
+ **/ priority?: boolean;
43
43
  /**
44
44
  * If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
45
45
  *
46
46
  * Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
47
- **/ srcSetCandidates?: number[] | undefined;
47
+ **/ srcSetCandidates?: number[];
48
48
  /**
49
49
  * Defines which referrer is sent when fetching the image
50
50
  * Read more: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#referrerpolicy
51
51
  *
52
52
  * Defaults to `no-referrer-when-downgrade` to give more useful stats in DatoCMS Project Usages
53
- **/ referrerPolicy?: ReferrerPolicy | undefined;
53
+ **/ referrerPolicy?: ReferrerPolicy;
54
54
  };
55
55
  events: {
56
56
  load: CustomEvent<any>;
@@ -3,34 +3,34 @@ import { type ResponsiveImageType } from './utils';
3
3
  declare const __propDef: {
4
4
  props: {
5
5
  /** The actual response you get from a DatoCMS `responsiveImage` GraphQL query */ data: ResponsiveImageType;
6
- /** Additional CSS className for the root <picture> tag */ pictureClass?: string | null | undefined;
7
- /** Additional CSS rules to add to the root <picture> tag */ pictureStyle?: string | null | undefined;
8
- /** Additional CSS className for the <img> tag */ imgClass?: string | null | undefined;
9
- /** Additional CSS rules to add to the <img> tag */ imgStyle?: string | null | undefined;
10
- /** Whether the component should use a blurred image placeholder */ usePlaceholder?: boolean | undefined;
6
+ /** Additional CSS className for the root <picture> tag */ pictureClass?: string | null;
7
+ /** Additional CSS rules to add to the root <picture> tag */ pictureStyle?: string | null;
8
+ /** Additional CSS className for the <img> tag */ imgClass?: string | null;
9
+ /** Additional CSS rules to add to the <img> tag */ imgStyle?: string | null;
10
+ /** Whether the component should use a blurred image placeholder */ usePlaceholder?: boolean;
11
11
  /**
12
12
  * The HTML5 `sizes` attribute for the image
13
13
  *
14
14
  * Learn more about srcset and sizes:
15
15
  * -> https://web.dev/learn/design/responsive-images/#sizes
16
16
  * -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
17
- **/ sizes?: string | null | undefined;
17
+ **/ sizes?: HTMLImageElement["sizes"] | null;
18
18
  /**
19
19
  * When true, the image will be considered high priority. Lazy loading is automatically disabled, and fetchpriority="high" is added to the image.
20
20
  * You should use the priority property on any image detected as the Largest Contentful Paint (LCP) element. It may be appropriate to have multiple priority images, as different images may be the LCP element for different viewport sizes.
21
21
  * Should only be used when the image is visible above the fold.
22
- **/ priority?: boolean | undefined;
22
+ **/ priority?: boolean;
23
23
  /**
24
24
  * If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
25
25
  *
26
26
  * Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
27
- **/ srcSetCandidates?: number[] | undefined;
27
+ **/ srcSetCandidates?: number[];
28
28
  /**
29
29
  * Defines which referrer is sent when fetching the image
30
30
  * Read more: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#referrerpolicy
31
31
  *
32
32
  * Defaults to `no-referrer-when-downgrade` to give more useful stats in DatoCMS Project Usages
33
- **/ referrerPolicy?: ReferrerPolicy | undefined;
33
+ **/ referrerPolicy?: ReferrerPolicy;
34
34
  };
35
35
  events: {
36
36
  load: CustomEvent<any>;
@@ -5,10 +5,10 @@ import type { PredicateComponentTuple } from '../..';
5
5
  declare const __propDef: {
6
6
  props: {
7
7
  node: Node;
8
- blocks: StructuredText['blocks'];
9
- inlineBlocks: StructuredText['inlineBlocks'];
10
- links: StructuredText['links'];
11
- components?: PredicateComponentTuple[] | undefined;
8
+ blocks: StructuredText["blocks"];
9
+ inlineBlocks: StructuredText["inlineBlocks"];
10
+ links: StructuredText["links"];
11
+ components?: PredicateComponentTuple[];
12
12
  };
13
13
  events: {
14
14
  [evt: string]: CustomEvent<any>;
@@ -4,7 +4,7 @@ import type { PredicateComponentTuple } from '../..';
4
4
  declare const __propDef: {
5
5
  props: {
6
6
  /** The actual field value you get from DatoCMS **/ data?: StructuredText | Document | DastNode | null | undefined;
7
- components?: PredicateComponentTuple[] | undefined;
7
+ components?: PredicateComponentTuple[];
8
8
  };
9
9
  events: {
10
10
  [evt: string]: CustomEvent<any>;
@@ -1,7 +1,7 @@
1
1
  import { SvelteComponent } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
- lines?: string[] | undefined;
4
+ lines?: string[];
5
5
  };
6
6
  events: {
7
7
  [evt: string]: CustomEvent<any>;
@@ -94,7 +94,7 @@ export declare const toNativeAttrValue: (propValue: any, propName: string) => an
94
94
  import type MuxPlayerElement from '@mux/mux-player';
95
95
  declare const __propDef: {
96
96
  props: Partial<MuxPlayerProps> & {
97
- data?: Video | undefined;
97
+ data?: Video;
98
98
  };
99
99
  events: {
100
100
  abort: UIEvent;
@@ -120,8 +120,8 @@ declare const __propDef: {
120
120
  suspend: Event;
121
121
  ended: Event;
122
122
  error: ErrorEvent;
123
- cuepointchange: Event | UIEvent | ProgressEvent<EventTarget> | ErrorEvent | ClipboardEvent | DragEvent | MouseEvent | FocusEvent | AnimationEvent | InputEvent | CompositionEvent | FormDataEvent | PointerEvent | KeyboardEvent | SecurityPolicyViolationEvent | SubmitEvent | TouchEvent | TransitionEvent | WheelEvent;
124
- cuepointschange: Event | UIEvent | ProgressEvent<EventTarget> | ErrorEvent | ClipboardEvent | DragEvent | MouseEvent | FocusEvent | AnimationEvent | InputEvent | CompositionEvent | FormDataEvent | PointerEvent | KeyboardEvent | SecurityPolicyViolationEvent | SubmitEvent | TouchEvent | TransitionEvent | WheelEvent;
123
+ cuepointchange: Event | UIEvent | ProgressEvent<EventTarget> | ErrorEvent | ClipboardEvent | DragEvent | MouseEvent | PointerEvent | FocusEvent | AnimationEvent | InputEvent | ToggleEvent | CompositionEvent | FormDataEvent | KeyboardEvent | SecurityPolicyViolationEvent | SubmitEvent | TouchEvent | TransitionEvent | WheelEvent;
124
+ cuepointschange: Event | UIEvent | ProgressEvent<EventTarget> | ErrorEvent | ClipboardEvent | DragEvent | MouseEvent | PointerEvent | FocusEvent | AnimationEvent | InputEvent | ToggleEvent | CompositionEvent | FormDataEvent | KeyboardEvent | SecurityPolicyViolationEvent | SubmitEvent | TouchEvent | TransitionEvent | WheelEvent;
125
125
  } & {
126
126
  [evt: string]: CustomEvent<any>;
127
127
  };
@@ -1,12 +1,15 @@
1
1
  import type { Node, CdaStructuredTextValue, CdaStructuredTextRecord, TypesafeCdaStructuredTextValue, Document as StructuredTextDocument } from 'datocms-structured-text-utils';
2
2
  export { default as NakedImage } from './components/NakedImage/NakedImage.svelte';
3
3
  export type { ResponsiveImageType } from './components/NakedImage/utils';
4
+ export { default as ContentLink } from './components/ContentLink/ContentLink.svelte';
4
5
  export { default as Head } from './components/Head/Head.svelte';
5
6
  export { default as Image } from './components/Image/Image.svelte';
6
7
  export { default as StructuredText } from './components/StructuredText/StructuredText.svelte';
7
8
  export { default as VideoPlayer } from './components/VideoPlayer/VideoPlayer.svelte';
8
9
  export * from './stores/querySubscription';
9
- export type { StructuredTextDocument, CdaStructuredTextValue, TypesafeCdaStructuredTextValue, CdaStructuredTextRecord, };
10
+ export type { Controller } from '@datocms/content-link';
11
+ export { decodeStega, stripStega } from '@datocms/content-link';
12
+ export type { StructuredTextDocument, CdaStructuredTextValue, TypesafeCdaStructuredTextValue, CdaStructuredTextRecord };
10
13
  export type PredicateComponentTuple = [
11
14
  (n: Node) => boolean,
12
15
  any
package/package/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  export { default as NakedImage } from './components/NakedImage/NakedImage.svelte';
2
+ export { default as ContentLink } from './components/ContentLink/ContentLink.svelte';
2
3
  export { default as Head } from './components/Head/Head.svelte';
3
4
  export { default as Image } from './components/Image/Image.svelte';
4
5
  export { default as StructuredText } from './components/StructuredText/StructuredText.svelte';
5
6
  export { default as VideoPlayer } from './components/VideoPlayer/VideoPlayer.svelte';
6
7
  export * from './stores/querySubscription';
8
+ export { decodeStega, stripStega } from '@datocms/content-link';
@@ -1,4 +1,3 @@
1
- /// <reference types="svelte" />
2
1
  import { type ChannelErrorData, type ConnectionStatus, type Options } from 'datocms-listen';
3
2
  export type SubscribeToQueryOptions<QueryResult, QueryVariables> = Omit<Options<QueryResult, QueryVariables>, 'onStatusChange' | 'onUpdate' | 'onChannelError'>;
4
3
  export type EnabledQuerySubscriptionOptions<QueryResult, QueryVariables> = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datocms/svelte",
3
- "version": "4.2.3",
3
+ "version": "4.2.4",
4
4
  "description": "A set of components and utilities to work faster with DatoCMS in Svelte",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -45,6 +45,7 @@
45
45
  "@testing-library/svelte": "^4.1.0",
46
46
  "@typescript-eslint/eslint-plugin": "^5.62.0",
47
47
  "@typescript-eslint/parser": "^5.62.0",
48
+ "@types/node": "^25.0.10",
48
49
  "csstype": "^3.1.3",
49
50
  "datocms-structured-text-generic-html-renderer": "^5.0.0",
50
51
  "doctoc": "^2.0.0",
@@ -59,18 +60,24 @@
59
60
  "svelte": "^4.0.0",
60
61
  "svelte-check": "^3.6.2",
61
62
  "tslib": "^2.6.2",
62
- "typescript": "^5.0.0",
63
+ "typescript": "^5.9.3",
63
64
  "vite": "^5.0.0",
64
65
  "vitest": "^1.0.0"
65
66
  },
66
67
  "type": "module",
67
68
  "dependencies": {
68
- "datocms-listen": "^0.1.15",
69
+ "@datocms/content-link": "^0.3.9",
70
+ "datocms-listen": "^1.0.2",
69
71
  "datocms-structured-text-utils": "^5.1.6",
70
72
  "svelte-intersection-observer": "^1.0.0"
71
73
  },
72
74
  "exports": {
73
75
  "./package.json": "./package.json",
76
+ "./components/ContentLink/ContentLink.svelte": {
77
+ "types": "./package/components/ContentLink/ContentLink.svelte.d.ts",
78
+ "svelte": "./package/components/ContentLink/ContentLink.svelte",
79
+ "default": "./package/components/ContentLink/ContentLink.svelte"
80
+ },
74
81
  "./components/Head/Head.svelte": {
75
82
  "types": "./package/components/Head/Head.svelte.d.ts",
76
83
  "svelte": "./package/components/Head/Head.svelte",
@@ -173,6 +180,9 @@
173
180
  "svelte": "./package/index.js",
174
181
  "typesVersions": {
175
182
  ">4.0": {
183
+ "components/ContentLink/ContentLink.svelte": [
184
+ "./package/components/ContentLink/ContentLink.svelte.d.ts"
185
+ ],
176
186
  "components/Head/Head.svelte": [
177
187
  "./package/components/Head/Head.svelte.d.ts"
178
188
  ],