Skip to content

Commit

Permalink
Image storage in Keystatic Cloud and custom docs image component (#274)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisLaneAU committed May 22, 2023
1 parent 4563e15 commit 9b7deda
Show file tree
Hide file tree
Showing 9 changed files with 7,751 additions and 6,800 deletions.
39 changes: 39 additions & 0 deletions docs/keystatic.config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
singleton,
component,
} from '@keystatic/core';
import { CloudImagePreview } from './src/components/previews/CloudImagePreview';

export const componentBlocks = {
aside: component({
Expand Down Expand Up @@ -45,6 +46,44 @@ export const componentBlocks = {
},
chromeless: true,
}),
'cloud-image': component({
preview: CloudImagePreview,
label: 'Cloud image',
schema: {
href: fields.text({
label: 'Href *',
validation: {
length: {
min: 1,
},
},
}),
alt: fields.text({
label: 'Alt text',
description:
'Include an alt text description or leave blank for decorative images',
}),
height: fields.text({
label: 'Height',
description:
'The intrinsic height of the image, in pixels. Must be an integer without a unit - e.g. 100',
}),
width: fields.text({
label: 'Width',
description:
'The intrinsic width of the image, in pixels. Must be an integer without a unit - e.g. 100',
}),
srcSet: fields.text({
label: 'Srcset',
description: 'Optionally override the defualt srcset',
}),
sizes: fields.text({
label: 'Sizes',
description: 'Optionally override the defualt sizes',
}),
},
chromeless: false,
}),
};

export default config({
Expand Down
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@types/node": "16.11.13",
"@types/react": "^18.0.25",
"@vercel/analytics": "^0.1.8",
"@voussoir/progress": "0.1.2",
"cookie": "^0.5.0",
"next": "^13.4.1",
"react": "^18.2.0",
Expand Down
16 changes: 16 additions & 0 deletions docs/src/components/document-renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import shiki from 'shiki';
import Heading from './heading';
import { InferRenderersForComponentBlocks } from '@keystatic/core';
import { componentBlocks } from '../../keystatic.config';
import { getDefaultSrcSet } from '../utils';
import { CONTENT_MAX_WIDTH_DESKTOP } from '../constants';

export default async function DocumentRenderer({
slug,
Expand Down Expand Up @@ -111,4 +113,18 @@ const componentBlockRenderers: InferRenderersForComponentBlocks<
</div>
);
},
'cloud-image': ({ href: src, alt, sizes, height, width, srcSet }) => {
const imgMaxWidthPx = `${parseInt(CONTENT_MAX_WIDTH_DESKTOP) * 16}`;

return (
<img
alt={alt || ''}
src={src}
height={height ?? undefined}
width={width ?? imgMaxWidthPx}
srcSet={srcSet || getDefaultSrcSet({ src })}
sizes={sizes || `(max-width: 375px) 375px, ${imgMaxWidthPx}px`}
/>
);
},
};
51 changes: 51 additions & 0 deletions docs/src/components/previews/CloudImagePreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use client';

import { useState } from 'react';
import { ProgressCircle } from '@voussoir/progress';
import { getDefaultSrcSet } from '../../utils';
import { CONTENT_MAX_WIDTH_DESKTOP } from '../../constants';

export function CloudImagePreview(props: any) {
const src = props.fields.href.value;
const alt = props.fields.alt.value;
const sizes = props.fields.sizes.value;
const srcSet = props.fields.srcSet.value;
const height = props.fields.height.value;
const width = props.fields.width.value;

const [isLoading, setIsLoading] = useState(!!src);

return (
<>
<p>Href: {src}</p>
<p>Alt text: {alt}</p>
{height &&
(isNaN(Number(height)) ? (
<p style={{ color: 'red' }}>
Invalid height, please enter an integer, e.g. 100
</p>
) : (
<p>Height: {height}</p>
))}
{width &&
(isNaN(Number(width)) ? (
<p style={{ color: 'red' }}>
Invalid width, please enter an integer, e.g. 100
</p>
) : (
<p>Width: {width}</p>
))}

{isLoading && <ProgressCircle aria-label="Loading…" isIndeterminate />}
<img
alt={alt}
src={src}
height={height}
width={width}
srcSet={srcSet || getDefaultSrcSet({ src })}
sizes={sizes || `${parseInt(CONTENT_MAX_WIDTH_DESKTOP) * 16}px`}
onLoad={() => setIsLoading(false)}
/>
</>
);
}
17 changes: 17 additions & 0 deletions docs/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const KS_CLOUD_STORAGE_URL = 'https://keystatic.io/';
export const DEFAULT_IMG_WIDTHS = [375, 960, 1280, 1920];

export const MAIN_EL_MAX_WIDTH = '76.5rem'; // 1200px + 24px gutter (`px-6`) as rems

/**
* This is a 'remainder' value set by 'auto' and is generated by:
* - Content + Side Nav = `MAIN_EL_MAX_WIDTH` (tailwind `max-w-7xl`)
* - padding left + right = 3rem (`px-6`)
* - Side Nav = 15rem (`w-60`)
* - ON THIS PAGE = 12rem
* - gap = 1.5rem (`gap-6`)
* - padding left = 3rem (`pl-12`)
* -----------------------------------
* Total: 42rem
*/
export const CONTENT_MAX_WIDTH_DESKTOP = '42rem';
18 changes: 18 additions & 0 deletions docs/src/content/pages/installation-astro.mdoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ This guide assumes you are trying to add Keystatic to an existing Astro v2 proje

Here, I've created a brand new Astro project, using the `Include sample files` option:

{% cloud-image
href="https://keystatic.io/images/keystatic-docs/astro-create.png"
alt="Create Astro project" /%}

## Installing dependencies

Expand Down Expand Up @@ -126,6 +129,9 @@ export default defineConfig({

Now, visit the `/keystatic` route once again in your browser:

{% cloud-image
href="https://keystatic.io/images/keystatic-docs/astro-keystatic-dashboard.png"
alt="Keystatic dashboard for Astro demo" /%}

Our Keystatic Admin UI is here! 🎉

Expand Down Expand Up @@ -153,11 +159,17 @@ We should be all set to go for our Keystatic Admin UI now.

Try and visit the `/keystatic` page in the browser one more time, and click on the “Homepage” singleton:

{% cloud-image
href="https://keystatic.io/images/keystatic-docs/astro-keystatic-homepage.png"
alt="Keystatic homepage singleton for Astro demo" /%}

It's working: our “Headline” text field is here.

Go ahead and fill that field with something, and hit `Create`:

{% cloud-image
href="https://keystatic.io/images/keystatic-docs/astro-keystatic-homepage-2.png"
alt="Keystatic homepage singleton for Astro demo with headline" /%}

Check your source code again. Notice anything?

Expand All @@ -173,6 +185,9 @@ Inside, you'll find a `_homepage` directory.

That directory contains an `index.yaml` file with… the `headline` text you've just created!

{% cloud-image
href="https://keystatic.io/images/keystatic-docs/astro-code-editor.png"
alt="Code editor with Keystatic files for Astro demo" /%}

Niiiice ✨

Expand Down Expand Up @@ -209,5 +224,8 @@ Try and replace the homepage's `h1` tag with your homepage headline from Keystat
<h1>{homepageData.headline}</h1>
```

{% cloud-image
href="https://keystatic.io/images/keystatic-docs/astro-keystatic-ui.png"
alt="Home page of the website with updated heading for Astro demo" /%}

Beautiful!
8 changes: 8 additions & 0 deletions docs/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { DEFAULT_IMG_WIDTHS } from '../constants';

export function cx(...classes: string[]) {
return classes.filter(Boolean).join(' ');
}

export function getDefaultSrcSet({ src }: { src: string }) {
const imgWidths = DEFAULT_IMG_WIDTHS;

return imgWidths.map(width => `${src}?width=${width} ${width}w`).join(', ');
}
3 changes: 2 additions & 1 deletion docs/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { MAIN_EL_MAX_WIDTH } = require('./src/constants');
const defaultTheme = require('tailwindcss/defaultTheme');

/** @type {import('tailwindcss').Config} */
Expand All @@ -23,7 +24,7 @@ module.exports = {
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
},
maxWidth: {
'7xl': 1224, // 1200px + 24px gutter (px-6)
'7xl': MAIN_EL_MAX_WIDTH,
},
},
},
Expand Down
Loading

1 comment on commit 9b7deda

@vercel
Copy link

@vercel vercel bot commented on 9b7deda May 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.