@exdst-sitecore-content-sdk/astro 0.0.1 → 0.0.6
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/LICENSE.txt +202 -202
- package/README.md +3 -3
- package/package.json +98 -101
- package/src/components/AstroImage.astro +114 -114
- package/src/components/Date.astro +76 -76
- package/src/components/DefaultEmptyFieldEditingComponentImage.astro +24 -24
- package/src/components/DefaultEmptyFieldEditingComponentText.astro +12 -12
- package/src/components/EditingScripts.astro +48 -48
- package/src/components/EmptyRendering.astro +2 -2
- package/src/components/ErrorBoundary.astro +77 -77
- package/src/components/FieldMetadata.astro +30 -30
- package/src/components/File.astro +46 -46
- package/src/components/HiddenRendering.astro +22 -22
- package/src/components/Image.astro +155 -155
- package/src/components/Link.astro +105 -105
- package/src/components/MissingComponent.astro +39 -39
- package/src/components/Placeholder/EmptyPlaceholder.astro +9 -9
- package/src/components/Placeholder/Placeholder.astro +100 -100
- package/src/components/Placeholder/PlaceholderMetadata.astro +102 -102
- package/src/components/Placeholder/PlaceholderUtils.astro +152 -152
- package/src/components/RenderWrapper.astro +31 -31
- package/src/components/RichText.astro +59 -59
- package/src/components/Text.astro +97 -97
- package/src/enhancers/WithEmptyFieldEditingComponent.astro +56 -56
- package/src/enhancers/WithFieldMetadata.astro +31 -31
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { Page } from '@sitecore-content-sdk/core/client';
|
|
3
|
-
import { ComponentRendering } from '@sitecore-content-sdk/core/layout';
|
|
4
|
-
import { AstroContentSdkComponent } from '../sharedTypes/component-props';
|
|
5
|
-
import { useSitecore } from '../context';
|
|
6
|
-
|
|
7
|
-
export type ErrorBoundaryProps = {
|
|
8
|
-
page: Page;
|
|
9
|
-
isDynamic?: boolean;
|
|
10
|
-
errorComponent?: AstroContentSdkComponent;
|
|
11
|
-
rendering?: ComponentRendering;
|
|
12
|
-
componentLoadingMessage?: string;
|
|
13
|
-
disableSuspense?: boolean;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
let props = Astro.props as ErrorBoundaryProps;
|
|
17
|
-
const { page } = useSitecore();
|
|
18
|
-
props = { ...props, page };
|
|
19
|
-
|
|
20
|
-
const defaultErrorMessage = 'There was a problem loading this section.';
|
|
21
|
-
|
|
22
|
-
const isInDevMode = (): boolean => {
|
|
23
|
-
return process.env.NODE_ENV === 'development';
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const showErrorDetails = (): boolean => {
|
|
27
|
-
return (
|
|
28
|
-
isInDevMode() || props.page.mode.isEditing || props.page.mode.isPreview
|
|
29
|
-
);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
let state: { error?: Error } = {};
|
|
33
|
-
|
|
34
|
-
let html;
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
html = await Astro.slots.render('default');
|
|
38
|
-
} catch (e) {
|
|
39
|
-
state = { error: e };
|
|
40
|
-
if (showErrorDetails()) {
|
|
41
|
-
console.error(
|
|
42
|
-
`An error occurred in component ${props.rendering?.componentName} (${props.rendering?.uid}): `
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
console.error(e);
|
|
46
|
-
}
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
<>
|
|
50
|
-
{!state.error && <Fragment set:html={html} />}
|
|
51
|
-
{
|
|
52
|
-
state.error && props.errorComponent && (
|
|
53
|
-
<props.errorComponent error={state.error} />
|
|
54
|
-
)
|
|
55
|
-
}
|
|
56
|
-
{
|
|
57
|
-
state.error && !props.errorComponent && showErrorDetails() && (
|
|
58
|
-
<div>
|
|
59
|
-
<div class="sc-content-sdk-placeholder-error">
|
|
60
|
-
A rendering error occurred in component{' '}
|
|
61
|
-
<em>{props.rendering?.componentName}</em>
|
|
62
|
-
<br />
|
|
63
|
-
Error: <em>{state.error.message || JSON.stringify(state.error)}</em>
|
|
64
|
-
</div>
|
|
65
|
-
</div>
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
{
|
|
69
|
-
state.error && !props.errorComponent && !showErrorDetails() && (
|
|
70
|
-
<div>
|
|
71
|
-
<div class="sc-content-sdk-placeholder-error">
|
|
72
|
-
{defaultErrorMessage}
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
</>
|
|
1
|
+
---
|
|
2
|
+
import { Page } from '@sitecore-content-sdk/core/client';
|
|
3
|
+
import { ComponentRendering } from '@sitecore-content-sdk/core/layout';
|
|
4
|
+
import { AstroContentSdkComponent } from '../sharedTypes/component-props';
|
|
5
|
+
import { useSitecore } from '../context';
|
|
6
|
+
|
|
7
|
+
export type ErrorBoundaryProps = {
|
|
8
|
+
page: Page;
|
|
9
|
+
isDynamic?: boolean;
|
|
10
|
+
errorComponent?: AstroContentSdkComponent;
|
|
11
|
+
rendering?: ComponentRendering;
|
|
12
|
+
componentLoadingMessage?: string;
|
|
13
|
+
disableSuspense?: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
let props = Astro.props as ErrorBoundaryProps;
|
|
17
|
+
const { page } = useSitecore();
|
|
18
|
+
props = { ...props, page };
|
|
19
|
+
|
|
20
|
+
const defaultErrorMessage = 'There was a problem loading this section.';
|
|
21
|
+
|
|
22
|
+
const isInDevMode = (): boolean => {
|
|
23
|
+
return process.env.NODE_ENV === 'development';
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const showErrorDetails = (): boolean => {
|
|
27
|
+
return (
|
|
28
|
+
isInDevMode() || props.page.mode.isEditing || props.page.mode.isPreview
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
let state: { error?: Error } = {};
|
|
33
|
+
|
|
34
|
+
let html;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
html = await Astro.slots.render('default');
|
|
38
|
+
} catch (e) {
|
|
39
|
+
state = { error: e };
|
|
40
|
+
if (showErrorDetails()) {
|
|
41
|
+
console.error(
|
|
42
|
+
`An error occurred in component ${props.rendering?.componentName} (${props.rendering?.uid}): `
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
console.error(e);
|
|
46
|
+
}
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
<>
|
|
50
|
+
{!state.error && <Fragment set:html={html} />}
|
|
51
|
+
{
|
|
52
|
+
state.error && props.errorComponent && (
|
|
53
|
+
<props.errorComponent error={state.error} />
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
{
|
|
57
|
+
state.error && !props.errorComponent && showErrorDetails() && (
|
|
58
|
+
<div>
|
|
59
|
+
<div class="sc-content-sdk-placeholder-error">
|
|
60
|
+
A rendering error occurred in component{' '}
|
|
61
|
+
<em>{props.rendering?.componentName}</em>
|
|
62
|
+
<br />
|
|
63
|
+
Error: <em>{state.error.message || JSON.stringify(state.error)}</em>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
{
|
|
69
|
+
state.error && !props.errorComponent && !showErrorDetails() && (
|
|
70
|
+
<div>
|
|
71
|
+
<div class="sc-content-sdk-placeholder-error">
|
|
72
|
+
{defaultErrorMessage}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
</>
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
---
|
|
2
|
-
/**
|
|
3
|
-
* The component which renders field metadata markup
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { MetadataKind } from '@sitecore-content-sdk/core/editing';
|
|
7
|
-
|
|
8
|
-
interface FieldMetadataProps {
|
|
9
|
-
metadata: { [key: string]: unknown };
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const props = Astro.props as FieldMetadataProps;
|
|
13
|
-
|
|
14
|
-
const data = JSON.stringify(props.metadata);
|
|
15
|
-
|
|
16
|
-
const attributes = {
|
|
17
|
-
type: 'text/sitecore',
|
|
18
|
-
chrometype: 'field',
|
|
19
|
-
className: 'scpm',
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const codeOpenAttributes = { ...attributes, kind: MetadataKind.Open };
|
|
23
|
-
const codeCloseAttributes = { ...attributes, kind: MetadataKind.Close };
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
<>
|
|
27
|
-
<code {...codeOpenAttributes}>{data}</code>
|
|
28
|
-
<slot />
|
|
29
|
-
<code {...codeCloseAttributes}>{}</code>
|
|
30
|
-
</>
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* The component which renders field metadata markup
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { MetadataKind } from '@sitecore-content-sdk/core/editing';
|
|
7
|
+
|
|
8
|
+
interface FieldMetadataProps {
|
|
9
|
+
metadata: { [key: string]: unknown };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const props = Astro.props as FieldMetadataProps;
|
|
13
|
+
|
|
14
|
+
const data = JSON.stringify(props.metadata);
|
|
15
|
+
|
|
16
|
+
const attributes = {
|
|
17
|
+
type: 'text/sitecore',
|
|
18
|
+
chrometype: 'field',
|
|
19
|
+
className: 'scpm',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const codeOpenAttributes = { ...attributes, kind: MetadataKind.Open };
|
|
23
|
+
const codeCloseAttributes = { ...attributes, kind: MetadataKind.Close };
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
<>
|
|
27
|
+
<code {...codeOpenAttributes}>{data}</code>
|
|
28
|
+
<slot />
|
|
29
|
+
<code {...codeCloseAttributes}>{}</code>
|
|
30
|
+
</>
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { isFieldValueEmpty } from '@sitecore-content-sdk/core/layout';
|
|
3
|
-
|
|
4
|
-
export interface FileFieldValue {
|
|
5
|
-
[propName: string]: unknown;
|
|
6
|
-
src?: string;
|
|
7
|
-
title?: string;
|
|
8
|
-
displayName?: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface FileField {
|
|
12
|
-
value: FileFieldValue;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface FileProps {
|
|
16
|
-
[attributeName: string]: unknown;
|
|
17
|
-
/** The file field data. */
|
|
18
|
-
field: FileFieldValue | FileField;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const { field, ...otherProps } = Astro.props as FileProps;
|
|
22
|
-
|
|
23
|
-
const dynamicField: FileField | FileFieldValue = field;
|
|
24
|
-
|
|
25
|
-
const isEmptyField = isFieldValueEmpty(dynamicField);
|
|
26
|
-
|
|
27
|
-
let file, linkText, anchorAttrs, finalChildren;
|
|
28
|
-
|
|
29
|
-
if (!isEmptyField) {
|
|
30
|
-
// handle link directly on field for forgetful devs
|
|
31
|
-
file = (
|
|
32
|
-
(dynamicField as FileFieldValue).src ? field : dynamicField.value
|
|
33
|
-
) as FileFieldValue;
|
|
34
|
-
|
|
35
|
-
if (file) {
|
|
36
|
-
const children = await Astro.slots.render('default');
|
|
37
|
-
linkText = !children ? file.title || file.displayName : null;
|
|
38
|
-
anchorAttrs = { href: file.src };
|
|
39
|
-
finalChildren = children ? children : linkText;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const attrs = { ...anchorAttrs, ...otherProps };
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
{!isEmptyField && file && <a {...attrs} set:html={finalChildren}></a>}
|
|
1
|
+
---
|
|
2
|
+
import { isFieldValueEmpty } from '@sitecore-content-sdk/core/layout';
|
|
3
|
+
|
|
4
|
+
export interface FileFieldValue {
|
|
5
|
+
[propName: string]: unknown;
|
|
6
|
+
src?: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
displayName?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface FileField {
|
|
12
|
+
value: FileFieldValue;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface FileProps {
|
|
16
|
+
[attributeName: string]: unknown;
|
|
17
|
+
/** The file field data. */
|
|
18
|
+
field: FileFieldValue | FileField;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { field, ...otherProps } = Astro.props as FileProps;
|
|
22
|
+
|
|
23
|
+
const dynamicField: FileField | FileFieldValue = field;
|
|
24
|
+
|
|
25
|
+
const isEmptyField = isFieldValueEmpty(dynamicField);
|
|
26
|
+
|
|
27
|
+
let file, linkText, anchorAttrs, finalChildren;
|
|
28
|
+
|
|
29
|
+
if (!isEmptyField) {
|
|
30
|
+
// handle link directly on field for forgetful devs
|
|
31
|
+
file = (
|
|
32
|
+
(dynamicField as FileFieldValue).src ? field : dynamicField.value
|
|
33
|
+
) as FileFieldValue;
|
|
34
|
+
|
|
35
|
+
if (file) {
|
|
36
|
+
const children = await Astro.slots.render('default');
|
|
37
|
+
linkText = !children ? file.title || file.displayName : null;
|
|
38
|
+
anchorAttrs = { href: file.src };
|
|
39
|
+
finalChildren = children ? children : linkText;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const attrs = { ...anchorAttrs, ...otherProps };
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
{!isEmptyField && file && <a {...attrs} set:html={finalChildren}></a>}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
---
|
|
2
|
-
const baseStyles = {
|
|
3
|
-
backgroundSize: '3px 3px',
|
|
4
|
-
display: 'flex',
|
|
5
|
-
justifyContent: 'center',
|
|
6
|
-
alignItems: 'center',
|
|
7
|
-
padding: '30px',
|
|
8
|
-
color: '#aaa',
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const backgroundImageStyle = {
|
|
12
|
-
backgroundImage:
|
|
13
|
-
'linear-gradient(45deg, #ffffff 25%, #dcdcdc 25%, #dcdcdc 50%, #ffffff 50%, #ffffff 75%, #dcdcdc 75%, #dcdcdc 100%)',
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const styles =
|
|
17
|
-
process.env.NODE_ENV === 'test'
|
|
18
|
-
? baseStyles
|
|
19
|
-
: { ...baseStyles, ...backgroundImageStyle };
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
<div style={styles}>The component is hidden</div>
|
|
1
|
+
---
|
|
2
|
+
const baseStyles = {
|
|
3
|
+
backgroundSize: '3px 3px',
|
|
4
|
+
display: 'flex',
|
|
5
|
+
justifyContent: 'center',
|
|
6
|
+
alignItems: 'center',
|
|
7
|
+
padding: '30px',
|
|
8
|
+
color: '#aaa',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const backgroundImageStyle = {
|
|
12
|
+
backgroundImage:
|
|
13
|
+
'linear-gradient(45deg, #ffffff 25%, #dcdcdc 25%, #dcdcdc 50%, #ffffff 50%, #ffffff 75%, #dcdcdc 75%, #dcdcdc 100%)',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const styles =
|
|
17
|
+
process.env.NODE_ENV === 'test'
|
|
18
|
+
? baseStyles
|
|
19
|
+
: { ...baseStyles, ...backgroundImageStyle };
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<div style={styles}>The component is hidden</div>
|
|
@@ -1,155 +1,155 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { mediaApi } from '@sitecore-content-sdk/core/media';
|
|
3
|
-
import { EditableFieldProps } from './sharedTypes';
|
|
4
|
-
import {
|
|
5
|
-
FieldMetadata,
|
|
6
|
-
isFieldValueEmpty,
|
|
7
|
-
} from '@sitecore-content-sdk/core/layout';
|
|
8
|
-
import { addClassName } from '../utils';
|
|
9
|
-
import WithFieldMetadata from '../enhancers/WithFieldMetadata.astro';
|
|
10
|
-
import WithEmptyFieldEditingComponent from '../enhancers/WithEmptyFieldEditingComponent.astro';
|
|
11
|
-
import DefaultEmptyFieldEditingComponentImage from './DefaultEmptyFieldEditingComponentImage.astro';
|
|
12
|
-
|
|
13
|
-
export interface ImageFieldValue {
|
|
14
|
-
[attributeName: string]: unknown;
|
|
15
|
-
src?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface ImageField {
|
|
19
|
-
value?: ImageFieldValue;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface ImageSizeParameters {
|
|
23
|
-
[attr: string]: string | number | undefined;
|
|
24
|
-
/** Fixed width of the image */
|
|
25
|
-
w?: number;
|
|
26
|
-
/** Fixed height of the image */
|
|
27
|
-
h?: number;
|
|
28
|
-
/** Max width of the image */
|
|
29
|
-
mw?: number;
|
|
30
|
-
/** Max height of the image */
|
|
31
|
-
mh?: number;
|
|
32
|
-
/** Ignore aspect ratio */
|
|
33
|
-
iar?: 1 | 0;
|
|
34
|
-
/** Allow stretch */
|
|
35
|
-
as?: 1 | 0;
|
|
36
|
-
/** Image scale. Defaults to 1.0 */
|
|
37
|
-
sc?: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface BaseImageProps {
|
|
41
|
-
[attributeName: string]: unknown;
|
|
42
|
-
/** Image field data (consistent with other field types) */
|
|
43
|
-
field?: (ImageField | ImageFieldValue) & FieldMetadata;
|
|
44
|
-
/**
|
|
45
|
-
* Parameters that will be attached to Sitecore media URLs
|
|
46
|
-
*/
|
|
47
|
-
imageParams?: {
|
|
48
|
-
[paramName: string]: string | number;
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Custom regexp that finds media URL prefix that will be replaced by `/-/jssmedia` or `/~/jssmedia`.
|
|
52
|
-
* @example
|
|
53
|
-
* /\/([-~]{1})assets\//i
|
|
54
|
-
* /-assets/website -> /-/jssmedia/website
|
|
55
|
-
* /~assets/website -> /~/jssmedia/website
|
|
56
|
-
*/
|
|
57
|
-
mediaUrlPrefix?: RegExp;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface ImageProps extends BaseImageProps, EditableFieldProps {
|
|
61
|
-
srcSet?: ImageSizeParameters[];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const getImageAttrs = (
|
|
65
|
-
{
|
|
66
|
-
src,
|
|
67
|
-
srcSet,
|
|
68
|
-
...otherAttrs
|
|
69
|
-
}: {
|
|
70
|
-
[key: string]: unknown;
|
|
71
|
-
src?: string;
|
|
72
|
-
srcSet?: ImageSizeParameters[];
|
|
73
|
-
},
|
|
74
|
-
imageParams?: { [paramName: string]: string | number },
|
|
75
|
-
mediaUrlPrefix?: RegExp
|
|
76
|
-
) => {
|
|
77
|
-
if (!src) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
addClassName(otherAttrs);
|
|
81
|
-
|
|
82
|
-
const newAttrs: { [attr: string]: unknown } = {
|
|
83
|
-
...otherAttrs,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
// update image URL for content sdk handler and image rendering params
|
|
87
|
-
const resolvedSrc = mediaApi.updateImageUrl(src, imageParams, mediaUrlPrefix);
|
|
88
|
-
if (srcSet) {
|
|
89
|
-
// replace with HTML-formatted srcset, including updated image URLs
|
|
90
|
-
newAttrs.srcSet = mediaApi.getSrcSet(
|
|
91
|
-
resolvedSrc,
|
|
92
|
-
srcSet,
|
|
93
|
-
imageParams,
|
|
94
|
-
mediaUrlPrefix
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
// always output original src as fallback for older browsers
|
|
98
|
-
newAttrs.src = resolvedSrc;
|
|
99
|
-
return newAttrs;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
const {
|
|
103
|
-
editable = true,
|
|
104
|
-
imageParams,
|
|
105
|
-
field,
|
|
106
|
-
mediaUrlPrefix,
|
|
107
|
-
emptyFieldEditingComponent,
|
|
108
|
-
...otherProps
|
|
109
|
-
} = Astro.props as ImageProps;
|
|
110
|
-
|
|
111
|
-
const dynamicMedia = field as ImageField | ImageFieldValue;
|
|
112
|
-
|
|
113
|
-
const isEmptyField = isFieldValueEmpty(dynamicMedia);
|
|
114
|
-
|
|
115
|
-
let img;
|
|
116
|
-
if (!isEmptyField) {
|
|
117
|
-
// handle image directly on field for forgetful devs
|
|
118
|
-
img = (dynamicMedia as ImageFieldValue).src
|
|
119
|
-
? { ...field }
|
|
120
|
-
: (dynamicMedia.value as ImageFieldValue);
|
|
121
|
-
|
|
122
|
-
if (img) {
|
|
123
|
-
// prevent metadata from being passed to the img tag
|
|
124
|
-
if (img.metadata) {
|
|
125
|
-
delete img.metadata;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const attrs = getImageAttrs(
|
|
131
|
-
{ ...img, ...otherProps },
|
|
132
|
-
imageParams,
|
|
133
|
-
mediaUrlPrefix
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
console.log("Attrs", attrs);
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
{
|
|
140
|
-
(
|
|
141
|
-
<WithFieldMetadata field={field} editable={editable}>
|
|
142
|
-
<WithEmptyFieldEditingComponent
|
|
143
|
-
field={field}
|
|
144
|
-
editable={editable}
|
|
145
|
-
defaultEmptyFieldEditingComponent={
|
|
146
|
-
DefaultEmptyFieldEditingComponentImage
|
|
147
|
-
}
|
|
148
|
-
emptyFieldEditingComponent={emptyFieldEditingComponent}
|
|
149
|
-
{...otherProps}
|
|
150
|
-
>
|
|
151
|
-
{!isEmptyField && img && attrs && <img {...attrs} />}
|
|
152
|
-
</WithEmptyFieldEditingComponent>
|
|
153
|
-
</WithFieldMetadata>
|
|
154
|
-
)
|
|
155
|
-
}
|
|
1
|
+
---
|
|
2
|
+
import { mediaApi } from '@sitecore-content-sdk/core/media';
|
|
3
|
+
import { EditableFieldProps } from './sharedTypes';
|
|
4
|
+
import {
|
|
5
|
+
FieldMetadata,
|
|
6
|
+
isFieldValueEmpty,
|
|
7
|
+
} from '@sitecore-content-sdk/core/layout';
|
|
8
|
+
import { addClassName } from '../utils';
|
|
9
|
+
import WithFieldMetadata from '../enhancers/WithFieldMetadata.astro';
|
|
10
|
+
import WithEmptyFieldEditingComponent from '../enhancers/WithEmptyFieldEditingComponent.astro';
|
|
11
|
+
import DefaultEmptyFieldEditingComponentImage from './DefaultEmptyFieldEditingComponentImage.astro';
|
|
12
|
+
|
|
13
|
+
export interface ImageFieldValue {
|
|
14
|
+
[attributeName: string]: unknown;
|
|
15
|
+
src?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ImageField {
|
|
19
|
+
value?: ImageFieldValue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ImageSizeParameters {
|
|
23
|
+
[attr: string]: string | number | undefined;
|
|
24
|
+
/** Fixed width of the image */
|
|
25
|
+
w?: number;
|
|
26
|
+
/** Fixed height of the image */
|
|
27
|
+
h?: number;
|
|
28
|
+
/** Max width of the image */
|
|
29
|
+
mw?: number;
|
|
30
|
+
/** Max height of the image */
|
|
31
|
+
mh?: number;
|
|
32
|
+
/** Ignore aspect ratio */
|
|
33
|
+
iar?: 1 | 0;
|
|
34
|
+
/** Allow stretch */
|
|
35
|
+
as?: 1 | 0;
|
|
36
|
+
/** Image scale. Defaults to 1.0 */
|
|
37
|
+
sc?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface BaseImageProps {
|
|
41
|
+
[attributeName: string]: unknown;
|
|
42
|
+
/** Image field data (consistent with other field types) */
|
|
43
|
+
field?: (ImageField | ImageFieldValue) & FieldMetadata;
|
|
44
|
+
/**
|
|
45
|
+
* Parameters that will be attached to Sitecore media URLs
|
|
46
|
+
*/
|
|
47
|
+
imageParams?: {
|
|
48
|
+
[paramName: string]: string | number;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Custom regexp that finds media URL prefix that will be replaced by `/-/jssmedia` or `/~/jssmedia`.
|
|
52
|
+
* @example
|
|
53
|
+
* /\/([-~]{1})assets\//i
|
|
54
|
+
* /-assets/website -> /-/jssmedia/website
|
|
55
|
+
* /~assets/website -> /~/jssmedia/website
|
|
56
|
+
*/
|
|
57
|
+
mediaUrlPrefix?: RegExp;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ImageProps extends BaseImageProps, EditableFieldProps {
|
|
61
|
+
srcSet?: ImageSizeParameters[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const getImageAttrs = (
|
|
65
|
+
{
|
|
66
|
+
src,
|
|
67
|
+
srcSet,
|
|
68
|
+
...otherAttrs
|
|
69
|
+
}: {
|
|
70
|
+
[key: string]: unknown;
|
|
71
|
+
src?: string;
|
|
72
|
+
srcSet?: ImageSizeParameters[];
|
|
73
|
+
},
|
|
74
|
+
imageParams?: { [paramName: string]: string | number },
|
|
75
|
+
mediaUrlPrefix?: RegExp
|
|
76
|
+
) => {
|
|
77
|
+
if (!src) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
addClassName(otherAttrs);
|
|
81
|
+
|
|
82
|
+
const newAttrs: { [attr: string]: unknown } = {
|
|
83
|
+
...otherAttrs,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// update image URL for content sdk handler and image rendering params
|
|
87
|
+
const resolvedSrc = mediaApi.updateImageUrl(src, imageParams, mediaUrlPrefix);
|
|
88
|
+
if (srcSet) {
|
|
89
|
+
// replace with HTML-formatted srcset, including updated image URLs
|
|
90
|
+
newAttrs.srcSet = mediaApi.getSrcSet(
|
|
91
|
+
resolvedSrc,
|
|
92
|
+
srcSet,
|
|
93
|
+
imageParams,
|
|
94
|
+
mediaUrlPrefix
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
// always output original src as fallback for older browsers
|
|
98
|
+
newAttrs.src = resolvedSrc;
|
|
99
|
+
return newAttrs;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const {
|
|
103
|
+
editable = true,
|
|
104
|
+
imageParams,
|
|
105
|
+
field,
|
|
106
|
+
mediaUrlPrefix,
|
|
107
|
+
emptyFieldEditingComponent,
|
|
108
|
+
...otherProps
|
|
109
|
+
} = Astro.props as ImageProps;
|
|
110
|
+
|
|
111
|
+
const dynamicMedia = field as ImageField | ImageFieldValue;
|
|
112
|
+
|
|
113
|
+
const isEmptyField = isFieldValueEmpty(dynamicMedia);
|
|
114
|
+
|
|
115
|
+
let img;
|
|
116
|
+
if (!isEmptyField) {
|
|
117
|
+
// handle image directly on field for forgetful devs
|
|
118
|
+
img = (dynamicMedia as ImageFieldValue).src
|
|
119
|
+
? { ...field }
|
|
120
|
+
: (dynamicMedia.value as ImageFieldValue);
|
|
121
|
+
|
|
122
|
+
if (img) {
|
|
123
|
+
// prevent metadata from being passed to the img tag
|
|
124
|
+
if (img.metadata) {
|
|
125
|
+
delete img.metadata;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const attrs = getImageAttrs(
|
|
131
|
+
{ ...img, ...otherProps },
|
|
132
|
+
imageParams,
|
|
133
|
+
mediaUrlPrefix
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
console.log("Attrs", attrs);
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
{
|
|
140
|
+
(
|
|
141
|
+
<WithFieldMetadata field={field} editable={editable}>
|
|
142
|
+
<WithEmptyFieldEditingComponent
|
|
143
|
+
field={field}
|
|
144
|
+
editable={editable}
|
|
145
|
+
defaultEmptyFieldEditingComponent={
|
|
146
|
+
DefaultEmptyFieldEditingComponentImage
|
|
147
|
+
}
|
|
148
|
+
emptyFieldEditingComponent={emptyFieldEditingComponent}
|
|
149
|
+
{...otherProps}
|
|
150
|
+
>
|
|
151
|
+
{!isEmptyField && img && attrs && <img {...attrs} />}
|
|
152
|
+
</WithEmptyFieldEditingComponent>
|
|
153
|
+
</WithFieldMetadata>
|
|
154
|
+
)
|
|
155
|
+
}
|