@datocms/astro 0.1.13 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +50 -38
  2. package/package.json +63 -50
  3. package/src/Image/Image.astro +14 -22
  4. package/src/Image/README.md +124 -0
  5. package/src/Image/buildSrcSet.ts +9 -16
  6. package/src/Image/index.ts +3 -1
  7. package/src/Image/types.ts +2 -2
  8. package/src/QueryListener/QueryListener.astro +56 -0
  9. package/src/QueryListener/README.md +67 -0
  10. package/src/QueryListener/index.ts +4 -0
  11. package/src/QueryListener/types.ts +12 -0
  12. package/src/Seo/README.md +57 -0
  13. package/src/Seo/Seo.astro +2 -2
  14. package/src/Seo/index.ts +3 -3
  15. package/src/Seo/renderMetaTagsToString.tsx +1 -3
  16. package/src/Seo/types.ts +9 -20
  17. package/src/StructuredText/Node.astro +15 -26
  18. package/src/StructuredText/README.md +42 -96
  19. package/src/StructuredText/StructuredText.astro +4 -6
  20. package/src/StructuredText/index.ts +2 -2
  21. package/src/StructuredText/nodes/Blockquote.astro +1 -1
  22. package/src/StructuredText/nodes/Code.astro +3 -3
  23. package/src/StructuredText/nodes/Heading.astro +1 -1
  24. package/src/StructuredText/nodes/Link.astro +3 -3
  25. package/src/StructuredText/nodes/List.astro +2 -2
  26. package/src/StructuredText/nodes/ListItem.astro +1 -1
  27. package/src/StructuredText/nodes/Paragraph.astro +1 -1
  28. package/src/StructuredText/nodes/Root.astro +1 -1
  29. package/src/StructuredText/nodes/Span.astro +8 -8
  30. package/src/StructuredText/nodes/ThematicBreak.astro +1 -1
  31. package/src/StructuredText/types.ts +1 -1
  32. package/src/StructuredText/utils.ts +71 -73
  33. package/src/index.ts +4 -0
  34. package/src/VideoPlayer/VideoPlayer.astro +0 -30
  35. package/src/VideoPlayer/index.ts +0 -2
  36. package/src/VideoPlayer/types.ts +0 -72
  37. package/src/VideoPlayer/utils.ts +0 -50
  38. package/src/useVideoPlayer/index.ts +0 -55
package/README.md CHANGED
@@ -1,54 +1,66 @@
1
- # Astro Starter Kit: Basics
1
+ <!--datocms-autoinclude-header start-->
2
2
 
3
- ```sh
4
- npm create astro@latest -- --template basics
5
- ```
3
+ <a href="https://www.datocms.com/"><img src="https://www.datocms.com/images/full_logo.svg" height="60"></a>
4
+
5
+ 👉 [Visit the DatoCMS homepage](https://www.datocms.com) or see [What is DatoCMS?](#what-is-datocms)
6
+
7
+ <!--datocms-autoinclude-header end-->
8
+
9
+ # @datocms/astro
10
+
11
+ [![MIT](https://img.shields.io/npm/l/@datocms/astro?style=for-the-badge)](https://github.com/datocms/astro-datocms/blob/master/LICENSE) [![NPM](https://img.shields.io/npm/v/@datocms/astro?style=for-the-badge)](https://www.npmjs.com/package/@datocms/astro)
12
+
13
+ A set of TypeScript-ready components and utilities to work faster with [DatoCMS](https://www.datocms.com/) in Astro project. Integrates seamlessly with [DatoCMS's GraphQL Content Delivery API](https://www.datocms.com/docs/content-delivery-api).
6
14
 
7
- [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)
8
- [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/basics)
9
- [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/basics/devcontainer.json)
15
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
16
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
10
17
 
11
- > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
18
+ - [Features](#features)
19
+ - [Installation](#installation)
20
+ - [What is DatoCMS?](#what-is-datocms)
12
21
 
13
- ![just-the-basics](https://github.com/withastro/astro/assets/2244813/a0a5533c-a856-4198-8470-2d67b1d7c554)
22
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
14
23
 
15
- ## 🚀 Project Structure
24
+ ## Features
16
25
 
17
- Inside of your Astro project, you'll see the following folders and files:
26
+ `@datocms/astro` contains ready-to-use Astro components and helpers:
18
27
 
19
- ```text
20
- /
21
- ├── public/
22
- │ └── favicon.svg
23
- ├── src/
24
- │ ├── components/
25
- │ │ └── Card.astro
26
- │ ├── layouts/
27
- │ │ └── Layout.astro
28
- │ └── pages/
29
- │ └── index.astro
30
- └── package.json
28
+ - [`<Image />`](src/Image)
29
+ - [`<Seo />`](src/Seo)
30
+ - [`<StructuredText />`](src/StructuredText)
31
+ - [`<QueryListener />`](src/QueryListener)
32
+
33
+ ## Installation
34
+
35
+ ```
36
+ npm install @datocms/astro
31
37
  ```
32
38
 
33
- Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
39
+ <!--datocms-autoinclude-footer start-->
40
+
41
+ # What is DatoCMS?
42
+
43
+ <a href="https://www.datocms.com/"><img src="https://www.datocms.com/images/full_logo.svg" height="60"></a>
44
+
45
+ [DatoCMS](https://www.datocms.com/) is the REST & GraphQL Headless CMS for the modern web.
34
46
 
35
- There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
47
+ Trusted by over 25,000 enterprise businesses, agency partners, and individuals across the world, DatoCMS users create online content at scale from a central hub and distribute it via API. We ❤️ our [developers](https://www.datocms.com/team/best-cms-for-developers), [content editors](https://www.datocms.com/team/content-creators) and [marketers](https://www.datocms.com/team/cms-digital-marketing)!
36
48
 
37
- Any static assets, like images, can be placed in the `public/` directory.
49
+ **Quick links:**
38
50
 
39
- ## 🧞 Commands
51
+ - ⚡️ Get started with a [free DatoCMS account](https://dashboard.datocms.com/signup)
52
+ - 🔖 Go through the [docs](https://www.datocms.com/docs)
53
+ - ⚙️ Get [support from us and the community](https://community.datocms.com/)
54
+ - 🆕 Stay up to date on new features and fixes on the [changelog](https://www.datocms.com/product-updates)
40
55
 
41
- All commands are run from the root of the project, from a terminal:
56
+ **Our featured repos:**
42
57
 
43
- | Command | Action |
44
- | :------------------------ | :----------------------------------------------- |
45
- | `npm install` | Installs dependencies |
46
- | `npm run dev` | Starts local dev server at `localhost:4321` |
47
- | `npm run build` | Build your production site to `./dist/` |
48
- | `npm run preview` | Preview your build locally, before deploying |
49
- | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
50
- | `npm run astro -- --help` | Get help using the Astro CLI |
58
+ - [datocms/react-datocms](https://github.com/datocms/react-datocms): React helper components for images, Structured Text rendering, and more
59
+ - [datocms/js-rest-api-clients](https://github.com/datocms/js-rest-api-clients): Node and browser JavaScript clients for updating and administering your content. For frontend fetches, we recommend using our [GraphQL Content Delivery API](https://www.datocms.com/docs/content-delivery-api) instead.
60
+ - [datocms/cli](https://github.com/datocms/cli): Command-line interface that includes our [Contentful importer](https://github.com/datocms/cli/tree/main/packages/cli-plugin-contentful) and [Wordpress importer](https://github.com/datocms/cli/tree/main/packages/cli-plugin-wordpress)
61
+ - [datocms/plugins](https://github.com/datocms/plugins): Example plugins we've made that extend the editor/admin dashboard
62
+ - [DatoCMS Starters](https://www.datocms.com/marketplace/starters) has examples for various Javascript frontend frameworks
51
63
 
52
- ## 👀 Want to learn more?
64
+ Or see [all our public repos](https://github.com/orgs/datocms/repositories?q=&type=public&language=&sort=stargazers)
53
65
 
54
- Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
66
+ <!--datocms-autoinclude-footer end-->
package/package.json CHANGED
@@ -1,52 +1,65 @@
1
1
  {
2
- "name": "@datocms/astro",
3
- "description": "A set of components and utilities to work faster with DatoCMS in Astro projects.",
4
- "type": "module",
5
- "version": "0.1.13",
6
- "sideEffects": false,
7
- "repository": {
8
- "type": "git",
9
- "url": "git://github.com/datocms/astro-datocms.git"
10
- },
11
- "homepage": "https://github.com/datocms/astro-datocms",
12
- "license": "MIT",
13
- "author": "Stefano Verna <s.verna@datocms.com>",
14
- "contributors": ["Silvano Stralla <silvano@datocms.com>"],
15
- "keywords": [
16
- "astro",
17
- "withastro",
18
- "astro-component",
19
- "datocms",
20
- "typescript",
21
- "ui"
22
- ],
23
- "exports": {
24
- "./useVideoPlayer": "./src/useVideoPlayer/index.ts",
25
- "./VideoPlayer": "./src/VideoPlayer/index.ts",
26
- "./Image": "./src/Image/index.ts",
27
- "./StructuredText": "./src/StructuredText/index.ts",
28
- "./Seo": "./src/Seo/index.ts"
29
- },
30
- "engines": {
31
- "node": ">=18.0.0"
32
- },
33
- "files": ["src"],
34
- "dependencies": {
35
- "@mux/playback-core": "^0.25.1",
36
- "datocms-structured-text-utils": "^4.0.1",
37
- "typescript": "^5.5.4"
38
- },
39
- "peerDependencies": {
40
- "@mux/mux-player": "*",
41
- "astro": "*"
42
- },
43
- "peerDependenciesMeta": {
44
- "@mux/mux-player": {
45
- "optional": true
46
- }
47
- },
48
- "devDependencies": {
49
- "@mux/mux-player": "*",
50
- "astro": "^4.13.1"
51
- }
2
+ "name": "@datocms/astro",
3
+ "description": "A set of components and utilities to work faster with DatoCMS in Astro projects.",
4
+ "type": "module",
5
+ "version": "0.2.1",
6
+ "sideEffects": false,
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git://github.com/datocms/astro-datocms.git"
10
+ },
11
+ "homepage": "https://github.com/datocms/astro-datocms",
12
+ "license": "MIT",
13
+ "author": "Stefano Verna <s.verna@datocms.com>",
14
+ "contributors": [
15
+ "Silvano Stralla <silvano@datocms.com>"
16
+ ],
17
+ "keywords": [
18
+ "astro",
19
+ "withastro",
20
+ "astro-component",
21
+ "datocms",
22
+ "typescript",
23
+ "ui"
24
+ ],
25
+ "scripts": {
26
+ "prepare": "npx simple-git-hooks",
27
+ "lint": "prettier --check .",
28
+ "format": "npm run toc && npx prettier . --write",
29
+ "toc": "doctoc --github README.md src",
30
+ "test": "echo 1"
31
+ },
32
+ "exports": {
33
+ ".": "./src/index.ts",
34
+ "./Image": "./src/Image/index.ts",
35
+ "./StructuredText": "./src/StructuredText/index.ts",
36
+ "./Seo": "./src/Seo/index.ts",
37
+ "./QueryListener": "./src/QueryListener/index.ts"
38
+ },
39
+ "engines": {
40
+ "node": ">=18.0.0"
41
+ },
42
+ "files": [
43
+ "src"
44
+ ],
45
+ "dependencies": {
46
+ "@0no-co/graphql.web": "^1.0.7",
47
+ "datocms-listen": "^1.0.0",
48
+ "datocms-structured-text-utils": "^4.0.1"
49
+ },
50
+ "peerDependencies": {
51
+ "astro": "*"
52
+ },
53
+ "devDependencies": {
54
+ "astro": "^4.13.1",
55
+ "doctoc": "^2.2.1",
56
+ "np": "^10.0.7",
57
+ "prettier": "^3.3.3",
58
+ "prettier-plugin-astro": "^0.14.1",
59
+ "simple-git-hooks": "^2.11.1",
60
+ "typescript": "^5.5.4"
61
+ },
62
+ "simple-git-hooks": {
63
+ "pre-commit": "npm run format"
64
+ }
52
65
  }
@@ -1,9 +1,8 @@
1
1
  ---
2
-
3
2
  import { buildSrcSet } from './buildSrcSet';
4
3
  import type { ImageProps } from './types';
5
4
 
6
- interface Props extends ImageProps {};
5
+ interface Props extends ImageProps {}
7
6
 
8
7
  const {
9
8
  data,
@@ -21,52 +20,45 @@ const placeholderStyle =
21
20
  usePlaceholder && data.base64
22
21
  ? {
23
22
  backgroundImage: `url("${data.base64}")`,
24
- backgroundSize: "cover",
25
- backgroundRepeat: "no-repeat",
26
- backgroundPosition: "50% 50%",
27
- color: "transparent",
23
+ backgroundSize: 'cover',
24
+ backgroundRepeat: 'no-repeat',
25
+ backgroundPosition: '50% 50%',
26
+ color: 'transparent',
28
27
  }
29
28
  : usePlaceholder && data.bgColor
30
- ? { backgroundColor: data.bgColor ?? undefined, color: "transparent" }
29
+ ? { backgroundColor: data.bgColor ?? undefined, color: 'transparent' }
31
30
  : undefined;
32
31
 
33
32
  const { width } = data;
34
33
 
35
- const height =
36
- data.height ?? Math.round(data.aspectRatio ? width / data.aspectRatio : 0);
34
+ const height = data.height ?? Math.round(data.aspectRatio ? width / data.aspectRatio : 0);
37
35
 
38
36
  const sizingStyle = {
39
37
  aspectRatio: `${width} / ${height}`,
40
- width: "100%",
38
+ width: '100%',
41
39
  maxWidth: `${width}px`,
42
- height: "auto",
40
+ height: 'auto',
43
41
  };
44
42
  ---
45
43
 
46
44
  <picture class={pictureClass} style={pictureStyle}>
47
45
  {
48
46
  data.webpSrcSet && (
49
- <source
50
- srcset={data.webpSrcSet}
51
- sizes={sizes ?? data.sizes ?? null}
52
- type="image/webp"
53
- />
47
+ <source srcset={data.webpSrcSet} sizes={sizes ?? data.sizes ?? null} type="image/webp" />
54
48
  )
55
49
  }
56
50
  <source
57
- srcset={data.srcSet ??
58
- buildSrcSet(data.src, data.width, srcSetCandidates) ??
59
- null}
51
+ srcset={data.srcSet ?? buildSrcSet(data.src, data.width, srcSetCandidates) ?? null}
60
52
  sizes={sizes ?? data.sizes ?? null}
61
53
  />
62
54
  {
63
55
  data.src && (
64
56
  <img
65
57
  src={data.src}
66
- alt={data.alt ?? ""}
58
+ alt={data.alt ?? ''}
67
59
  title={data.title ?? null}
68
- fetchpriority={priority ? "high" : undefined}
69
- loading={priority ? undefined : "lazy"}
60
+ fetchpriority={priority ? 'high' : undefined}
61
+ loading={priority ? undefined : 'lazy'}
70
62
  class={imgClass}
71
63
  style={{
72
64
  ...placeholderStyle,
@@ -0,0 +1,124 @@
1
+ # Progressive responsive image
2
+
3
+ `<Image>` is a TypeScript-ready Astro component specially designed to work seamlessly with DatoCMS’s [`responsiveImage` GraphQL query](https://www.datocms.com/docs/content-delivery-api/uploads#responsive-images) which optimizes image loading for your websites.
4
+
5
+ ### Out-of-the-box features
6
+
7
+ - Completely native, with no JavaScript footprint
8
+ - Offers optimized version of images for browsers that support WebP/AVIF format
9
+ - Generates multiple smaller images so smartphones and tablets don’t download desktop-sized images
10
+ - Efficiently lazy loads images to speed initial page load and save bandwidth
11
+ - Holds the image position so your page doesn’t jump while images load
12
+ - Uses either blur-up or background color techniques to show a preview of the image while it loads
13
+
14
+ ### Table of contents
15
+
16
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
17
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
18
+
19
+ - [Setup](#setup)
20
+ - [Usage](#usage)
21
+ - [Example](#example)
22
+ - [The `ResponsiveImage` object](#the-responsiveimage-object)
23
+ - [`<Image />`](#image-)
24
+ - [Props](#props)
25
+
26
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
27
+
28
+ ### Setup
29
+
30
+ You can import the component like this:
31
+
32
+ ```js
33
+ import { Image } from '@datocms/astro/Image';
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ 1. Use `<Image>` in place of the regular `<img />` tag
39
+ 2. Write a GraphQL query to your DatoCMS project using the [`responsiveImage` query](https://www.datocms.com/docs/content-delivery-api/images-and-videos#responsive-images)
40
+
41
+ The GraphQL query returns multiple thumbnails with optimized compression. The components automatically set up the "blur-up" effect as well as lazy loading of images further down the screen.
42
+
43
+ ## Example
44
+
45
+ Here is a minimal starting point:
46
+
47
+ ```astro
48
+ ---
49
+ import { Image } from '@datocms/astro/Image';
50
+ import { executeQuery } from '@datocms/cda-client';
51
+
52
+ const query = gql`
53
+ query {
54
+ blogPost {
55
+ title
56
+ cover {
57
+ responsiveImage(imgixParams: { fit: crop, w: 300, h: 300, auto: format }) {
58
+ # always required
59
+ src
60
+ width
61
+ height
62
+ # not required, but strongly suggested!
63
+ alt
64
+ title
65
+ # blur-up placeholder, JPEG format, base64-encoded, or...
66
+ base64
67
+ # background color placeholder
68
+ bgColor
69
+ # you can omit sizes if you explicitly pass the sizes prop to the image component
70
+ sizes
71
+ }
72
+ }
73
+ }
74
+ }
75
+ `;
76
+
77
+ const { blogPost } = await executeQuery(query, { token: '<YOUR-API-TOKEN>' });
78
+ ---
79
+
80
+ <Image data={blogPost.cover.responsiveImage} />
81
+ ```
82
+
83
+ ## The `ResponsiveImage` object
84
+
85
+ The `data` prop of both components expects an object with the same shape as the one returned by `responsiveImage` GraphQL call. It's up to you to make a GraphQL query that will return the properties you need for a specific use of the `<Image>` component.
86
+
87
+ - The minimum required properties for `data` are: `src`, `width` and `height`;
88
+ - `alt` and `title`, while not mandatory, are all highly suggested, so remember to use them!
89
+ - If you don't request `srcSet`, the component will auto-generate an `srcset` based on `src` + the `srcSetCandidates` prop (it can help reducing the GraphQL response size drammatically when many images are returned);
90
+ - We strongly to suggest to always specify [`{ auto: format }`](https://docs.imgix.com/apis/rendering/auto/auto#format) in your `imgixParams`, instead of requesting `webpSrcSet`, so that you can also take advantage of more performant optimizations (AVIF), without increasing GraphQL response size;
91
+ - If you request both the `bgColor` and `base64` property, the latter will take precedence, so just avoid querying both fields at the same time, as it will only make the GraphQL response bigger :wink:;
92
+ - You can avoid requesting `sizes` and directly pass a `sizes` prop to the component to reduce the GraphQL response size;
93
+
94
+ Here's a complete recap of what `responsiveImage` offers:
95
+
96
+ | property | type | required | description |
97
+ | ----------- | ------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
+ | src | string | :white_check_mark: | The `src` attribute for the image |
99
+ | width | integer | :white_check_mark: | The width of the image |
100
+ | height | integer | :white_check_mark: | The height of the image |
101
+ | alt | string | :x: | Alternate text (`alt`) for the image (not required, but strongly suggested!) |
102
+ | title | string | :x: | Title attribute (`title`) for the image (not required, but strongly suggested!) |
103
+ | sizes | string | :x: | The HTML5 `sizes` attribute for the image (omit it if you're already passing a `sizes` prop to the Image component) |
104
+ | base64 | string | :x: | A base64-encoded thumbnail to offer during image loading |
105
+ | bgColor | string | :x: | The background color for the image placeholder (omit it if you're already requesting `base64`) |
106
+ | srcSet | string | :x: | The HTML5 `srcSet` attribute for the image (can be omitted, the Image component knows how to build it based on `src`) |
107
+ | webpSrcSet | string | :x: | The HTML5 `srcSet` attribute for the image in WebP format (deprecated, it's better to use the [`auto=format`](https://docs.imgix.com/apis/rendering/auto/auto#format) Imgix transform instead) |
108
+ | aspectRatio | float | :x: | The aspect ratio (width/height) of the image |
109
+
110
+ ## `<Image />`
111
+
112
+ ### Props
113
+
114
+ | prop | type | default | required | description |
115
+ | ---------------- | ------------------------ | ---------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
116
+ | data | `ResponsiveImage` object | | :white_check_mark: | The actual response you get from a DatoCMS `responsiveImage` GraphQL query \*\*\*\* |
117
+ | pictureClass | string | null | :x: | Additional CSS class for the root `<picture>` tag |
118
+ | pictureStyle | CSS properties | null | :x: | Additional CSS rules to add to the root `<picture>` tag |
119
+ | imgClass | string | null | :x: | Additional CSS class for the `<img>` tag |
120
+ | imgStyle | CSS properties | null | :x: | Additional CSS rules to add to the `<img>` tag |
121
+ | priority | Boolean | false | :x: | Disables lazy loading, and sets the image [fetchPriority](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/fetchPriority) to "high" |
122
+ | sizes | string | undefined | :x: | The HTML5 [`sizes`](https://web.dev/learn/design/responsive-images/#sizes) attribute for the image (will be used `data.sizes` as a fallback) |
123
+ | usePlaceholder | Boolean | true | :x: | Whether the image should use a blurred image placeholder |
124
+ | srcSetCandidates | Array<number> | [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4] | :x: | If `data` does not contain `srcSet`, the candidates for the `srcset` attribute of the image will be auto-generated based on these width multipliers |
@@ -1,10 +1,9 @@
1
-
2
- const bogusBaseUrl = "https://example.com/";
1
+ const bogusBaseUrl = 'https://example.com/';
3
2
 
4
3
  export const buildSrcSet = (
5
4
  src: string | null | undefined,
6
5
  width: number | undefined,
7
- candidateMultipliers: number[]
6
+ candidateMultipliers: number[],
8
7
  ) => {
9
8
  if (!(src && width)) {
10
9
  return undefined;
@@ -15,20 +14,14 @@ export const buildSrcSet = (
15
14
  const url = new URL(src, bogusBaseUrl);
16
15
 
17
16
  if (multiplier !== 1) {
18
- url.searchParams.set("dpr", `${multiplier}`);
19
- const maxH = url.searchParams.get("max-h");
20
- const maxW = url.searchParams.get("max-w");
17
+ url.searchParams.set('dpr', `${multiplier}`);
18
+ const maxH = url.searchParams.get('max-h');
19
+ const maxW = url.searchParams.get('max-w');
21
20
  if (maxH) {
22
- url.searchParams.set(
23
- "max-h",
24
- `${Math.floor(Number.parseInt(maxH) * multiplier)}`
25
- );
21
+ url.searchParams.set('max-h', `${Math.floor(Number.parseInt(maxH) * multiplier)}`);
26
22
  }
27
23
  if (maxW) {
28
- url.searchParams.set(
29
- "max-w",
30
- `${Math.floor(Number.parseInt(maxW) * multiplier)}`
31
- );
24
+ url.searchParams.set('max-w', `${Math.floor(Number.parseInt(maxW) * multiplier)}`);
32
25
  }
33
26
  }
34
27
 
@@ -38,8 +31,8 @@ export const buildSrcSet = (
38
31
  return null;
39
32
  }
40
33
 
41
- return `${url.toString().replace(bogusBaseUrl, "/")} ${finalWidth}w`;
34
+ return `${url.toString().replace(bogusBaseUrl, '/')} ${finalWidth}w`;
42
35
  })
43
36
  .filter(Boolean)
44
- .join(",");
37
+ .join(',');
45
38
  };
@@ -1,2 +1,4 @@
1
- import Image from "./Image.astro";
1
+ import Image from './Image.astro';
2
+
3
+ export * from './types';
2
4
  export { Image };
@@ -56,11 +56,11 @@ export type ImageProps = {
56
56
  * -> https://web.dev/learn/design/responsive-images/#sizes
57
57
  * -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes
58
58
  **/
59
- sizes?: HTMLImageElement["sizes"];
59
+ sizes?: HTMLImageElement['sizes'];
60
60
  /**
61
61
  * If `data` does not contain `srcSet`, the candidates for the `srcset` of the image will be auto-generated based on these width multipliers
62
62
  *
63
63
  * Default candidate multipliers are [0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4]
64
64
  **/
65
65
  srcSetCandidates?: number[];
66
- }
66
+ };
@@ -0,0 +1,56 @@
1
+ ---
2
+ import type { QueryListenerOptions } from './types';
3
+ import { print } from '@0no-co/graphql.web';
4
+
5
+ type Props<QueryResult, QueryVariables> = QueryListenerOptions<QueryResult, QueryVariables>;
6
+
7
+ const { query, ...rest } = Astro.props;
8
+
9
+ const stringifiedQuery = typeof query === 'object' ? print(query) : query;
10
+ ---
11
+
12
+ <datocms-query-listener data-config={JSON.stringify({ ...rest, query: stringifiedQuery })}>
13
+ </datocms-query-listener>
14
+
15
+ <script>
16
+ import { subscribeToQuery as subscribeToQueryFn } from 'datocms-listen';
17
+ import type { QueryListenerOptions } from './types';
18
+
19
+ class QueryListener extends HTMLElement {
20
+ config: QueryListenerOptions<unknown, unknown>;
21
+ updatesReceived: number = 0;
22
+
23
+ constructor() {
24
+ super();
25
+
26
+ if (!this.dataset.config) {
27
+ throw new Error('Missing config');
28
+ }
29
+
30
+ this.config = JSON.parse(this.dataset.config);
31
+
32
+ import('datocms-listen').then(({ subscribeToQuery }) => {
33
+ this.run(subscribeToQuery);
34
+ });
35
+ }
36
+
37
+ run(subscribeToQuery: typeof subscribeToQueryFn) {
38
+ subscribeToQuery<unknown, unknown>({
39
+ ...this.config,
40
+ onUpdate: () => {
41
+ this.updatesReceived += 1;
42
+
43
+ if (this.updatesReceived > 1) {
44
+ document.location.reload();
45
+ }
46
+ },
47
+ onChannelError: (error) => {
48
+ console.error('[QueryListener]', error);
49
+ },
50
+ });
51
+ }
52
+ }
53
+
54
+ // Tell the browser to use our AstroHeart class for <astro-heart> elements.
55
+ customElements.define('datocms-query-listener', QueryListener);
56
+ </script>
@@ -0,0 +1,67 @@
1
+ # Live real-time updates
2
+
3
+ `<QueryListener />` is an Astro component that you can use to implement client-side reload of the page as soon as the content of a query changes. It uses DatoCMS's [Real-time Updates API](https://www.datocms.com/docs/real-time-updates-api/api-reference) to receive the updated query results in real-time, and is able to reconnect in case of network failures.
4
+
5
+ Live reloads are great to get instant previews of your content while editing it inside DatoCMS.
6
+
7
+ `<QueryListener />` is based on the `subscribeToQuery` helper provided by the [datocms-listen](https://www.npmjs.com/package/datocms-listen) package.
8
+
9
+ ## Table of Contents
10
+
11
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
12
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
13
+
14
+ - [Installation](#installation)
15
+ - [Reference](#reference)
16
+ - [Initialization options](#initialization-options)
17
+
18
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
19
+
20
+ ## Installation
21
+
22
+ ```
23
+ npm install --save @datocms/astro
24
+ ```
25
+
26
+ ## Reference
27
+
28
+ Import `<QueryListener>` from `@datocms/astro` and use it inside your components setup function like this:
29
+
30
+ ```astro
31
+ ---
32
+ import { QueryListener } from '@datocms/astro/QueryListener';
33
+ import { executeQuery } from '@datocms/cda-client';
34
+
35
+ const query = gql`
36
+ query {
37
+ homepage {
38
+ title
39
+ }
40
+ }
41
+ `;
42
+
43
+ const data = await executeQuery(query, { token: '<YOUR-API-TOKEN>' });
44
+ ---
45
+
46
+ <h1>{data.homepage.title}</h1>
47
+
48
+ <QueryListener query={query} token="<YOUR-API-TOKEN>" />
49
+ ```
50
+
51
+ ## Initialization options
52
+
53
+ | prop | type | required | description | default |
54
+ | ------------------ | ------------------------------------------------------------------------------------------ | ------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------ |
55
+ | enabled | boolean | :x: | Whether the subscription has to be performed or not | true |
56
+ | query | string \| [`TypedDocumentNode`](https://github.com/dotansimha/graphql-typed-document-node) | :white_check_mark: | The GraphQL query to subscribe | |
57
+ | token | string | :white_check_mark: | DatoCMS API token to use | |
58
+ | variables | Object | :x: | GraphQL variables for the query | |
59
+ | includeDrafts | boolean | :x: | If true, draft records will be returned | |
60
+ | excludeInvalid | boolean | :x: | If true, invalid records will be filtered out | |
61
+ | environment | string | :x: | The name of the DatoCMS environment where to perform the query (defaults to primary environment) | |
62
+ | contentLink | `'vercel-1'` or `undefined` | :x: | If true, embed metadata that enable Content Link | |
63
+ | baseEditingUrl | string | :x: | The base URL of the DatoCMS project | |
64
+ | cacheTags | boolean | :x: | If true, receive the Cache Tags associated with the query | |
65
+ | initialData | Object | :x: | The initial data to use on the first render | |
66
+ | reconnectionPeriod | number | :x: | In case of network errors, the period (in ms) to wait to reconnect | 1000 |
67
+ | baseUrl | string | :x: | The base URL to use to perform the query | `https://graphql-listen.datocms.com` |
@@ -0,0 +1,4 @@
1
+ import QueryListener from './QueryListener.astro';
2
+
3
+ export * from './types';
4
+ export { QueryListener };