sanity-plugin-shopify-assets 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +106 -0
- package/dist/index.d.ts +73 -0
- package/dist/index.esm.js +2654 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2671 -0
- package/dist/index.js.map +1 -0
- package/package.json +101 -0
- package/sanity.json +8 -0
- package/src/components/AssetDiff.tsx +58 -0
- package/src/components/AssetPreview.tsx +82 -0
- package/src/components/DialogHeader.tsx +45 -0
- package/src/components/File.styled.tsx +66 -0
- package/src/components/File.tsx +56 -0
- package/src/components/ShopifyAssetInput.styled.tsx +13 -0
- package/src/components/ShopifyAssetInput.tsx +84 -0
- package/src/components/ShopifyAssetPicker.tsx +202 -0
- package/src/components/ShopifyIcon.tsx +22 -0
- package/src/components/VideoPlayer.tsx +50 -0
- package/src/datastores/shopify.ts +66 -0
- package/src/index.ts +31 -0
- package/src/schema/shopifyAssetSchema.ts +118 -0
- package/src/types.ts +54 -0
- package/src/utils/helpers.ts +1 -0
- package/v2-incompatible.js +11 -0
package/package.json
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sanity-plugin-shopify-assets",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Choose assets from your Shopify store in your Sanity Studio",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"sanity",
|
|
7
|
+
"sanity-plugin",
|
|
8
|
+
"images",
|
|
9
|
+
"shopify",
|
|
10
|
+
"assets",
|
|
11
|
+
"source"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/sanity-io/sanity-plugin-shopify-assets#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/sanity-io/sanity-plugin-shopify-assets/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git@github.com:sanity-io/sanity-plugin-shopify-assets.git"
|
|
20
|
+
},
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": "Sanity.io <hello@sanity.io>",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"source": "./src/index.ts",
|
|
27
|
+
"require": "./dist/index.js",
|
|
28
|
+
"import": "./dist/index.esm.js",
|
|
29
|
+
"default": "./dist/index.esm.js"
|
|
30
|
+
},
|
|
31
|
+
"./package.json": "./package.json"
|
|
32
|
+
},
|
|
33
|
+
"main": "./dist/index.js",
|
|
34
|
+
"module": "./dist/index.esm.js",
|
|
35
|
+
"source": "./src/index.ts",
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"sanity.json",
|
|
40
|
+
"src",
|
|
41
|
+
"v2-incompatible.js"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "run-s clean && plugin-kit verify-package --silent && pkg-utils build --strict && pkg-utils --strict",
|
|
45
|
+
"clean": "rimraf dist",
|
|
46
|
+
"format": "prettier --write --cache --ignore-unknown .",
|
|
47
|
+
"link-watch": "plugin-kit link-watch",
|
|
48
|
+
"lint": "eslint .",
|
|
49
|
+
"prepublishOnly": "run-s build",
|
|
50
|
+
"watch": "pkg-utils watch --strict"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@sanity/icons": "^2.2.2",
|
|
54
|
+
"@sanity/incompatible-plugin": "^1.0.4",
|
|
55
|
+
"@sanity/ui": "^1.0.14",
|
|
56
|
+
"axios": "^1.2.2",
|
|
57
|
+
"pretty-bytes": "^6.0.0",
|
|
58
|
+
"pretty-ms": "^8.0.0",
|
|
59
|
+
"react-infinite-scroll-component": "^6.1.0",
|
|
60
|
+
"react-photo-album": "^2.0.0",
|
|
61
|
+
"rxjs": "^7.8.0",
|
|
62
|
+
"video.js": "^7.20.3"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@commitlint/cli": "^17.4.2",
|
|
66
|
+
"@commitlint/config-conventional": "^17.4.2",
|
|
67
|
+
"@sanity/pkg-utils": "^2.2.1",
|
|
68
|
+
"@sanity/plugin-kit": "^3.1.3",
|
|
69
|
+
"@sanity/semantic-release-preset": "^3.0.2",
|
|
70
|
+
"@types/react": "^18.0.26",
|
|
71
|
+
"@types/styled-components": "^5.1.26",
|
|
72
|
+
"@types/video.js": "^7.3.50",
|
|
73
|
+
"@typescript-eslint/eslint-plugin": "^5.48.1",
|
|
74
|
+
"@typescript-eslint/parser": "^5.48.1",
|
|
75
|
+
"eslint": "^8.31.0",
|
|
76
|
+
"eslint-config-prettier": "^8.6.0",
|
|
77
|
+
"eslint-config-sanity": "^6.0.0",
|
|
78
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
79
|
+
"eslint-plugin-react": "^7.32.0",
|
|
80
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
81
|
+
"husky": "^8.0.3",
|
|
82
|
+
"lint-staged": "^13.1.0",
|
|
83
|
+
"npm-run-all": "^4.1.5",
|
|
84
|
+
"prettier": "^2.8.2",
|
|
85
|
+
"prettier-plugin-packagejson": "^2.3.0",
|
|
86
|
+
"react": "^18.2.0",
|
|
87
|
+
"react-dom": "^18.2.0",
|
|
88
|
+
"react-is": "^18.2.0",
|
|
89
|
+
"rimraf": "^4.0.4",
|
|
90
|
+
"sanity": "^3.2.3",
|
|
91
|
+
"styled-components": "^5.3.6",
|
|
92
|
+
"typescript": "^4.9.4"
|
|
93
|
+
},
|
|
94
|
+
"peerDependencies": {
|
|
95
|
+
"react": "^18",
|
|
96
|
+
"sanity": "^3"
|
|
97
|
+
},
|
|
98
|
+
"engines": {
|
|
99
|
+
"node": ">=14"
|
|
100
|
+
}
|
|
101
|
+
}
|
package/sanity.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {DiffFromTo} from 'sanity'
|
|
3
|
+
import {Asset} from '../types'
|
|
4
|
+
import {Flex, Text, Stack} from '@sanity/ui'
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
value: Asset | undefined
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const CloudinaryDiffPreview = ({value}: Props) => {
|
|
11
|
+
if (!value) {
|
|
12
|
+
return null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (value?.preview?.url) {
|
|
16
|
+
return (
|
|
17
|
+
<Flex justify="center" align="center" height="fill" width="fill">
|
|
18
|
+
<Stack space={2}>
|
|
19
|
+
<img
|
|
20
|
+
alt="preview"
|
|
21
|
+
src={value?.preview?.url}
|
|
22
|
+
style={{
|
|
23
|
+
objectFit: 'contain',
|
|
24
|
+
margin: 'auto',
|
|
25
|
+
maxWidth: '100%',
|
|
26
|
+
maxHeight: '100%',
|
|
27
|
+
}}
|
|
28
|
+
/>
|
|
29
|
+
<Text size={1}>{value.type.charAt(0).toUpperCase() + value.type.slice(1)}</Text>
|
|
30
|
+
</Stack>
|
|
31
|
+
</Flex>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Flex justify="center" align="center" height="fill" width="fill">
|
|
37
|
+
<div>(no image)</div>
|
|
38
|
+
</Flex>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
type DiffProps = {
|
|
43
|
+
diff: any
|
|
44
|
+
schemaType: any
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const AssetDiff = ({diff, schemaType}: DiffProps) => {
|
|
48
|
+
return (
|
|
49
|
+
<DiffFromTo
|
|
50
|
+
diff={diff}
|
|
51
|
+
schemaType={schemaType}
|
|
52
|
+
previewComponent={CloudinaryDiffPreview}
|
|
53
|
+
layout={'grid'}
|
|
54
|
+
/>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default AssetDiff
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {Box, Flex, Text, Theme, useTheme} from '@sanity/ui'
|
|
2
|
+
import {DurationLine, InfoLine} from './File.styled'
|
|
3
|
+
|
|
4
|
+
import {Asset} from '../types'
|
|
5
|
+
import React from 'react'
|
|
6
|
+
import VideoPlayer from './VideoPlayer'
|
|
7
|
+
import prettyBytes from 'pretty-bytes'
|
|
8
|
+
import prettyMilliseconds from 'pretty-ms'
|
|
9
|
+
import styled from 'styled-components'
|
|
10
|
+
|
|
11
|
+
type SanityTheme = Theme['sanity']
|
|
12
|
+
|
|
13
|
+
interface Style {
|
|
14
|
+
studioTheme: SanityTheme
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface ComponentProps {
|
|
18
|
+
value: Asset
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const StyledBox = styled(Box)`
|
|
22
|
+
background-color: ${({studioTheme}: Style) => studioTheme?.color?.card?.enabled?.bg2};
|
|
23
|
+
border: ${({studioTheme}: Style) => `1px solid ${studioTheme?.color?.card?.enabled?.border}`};
|
|
24
|
+
display: flex;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
margin-bottom: ${({studioTheme}: Style) => studioTheme.space[4]};
|
|
27
|
+
position: relative;
|
|
28
|
+
`
|
|
29
|
+
|
|
30
|
+
const RenderAsset = ({value, url}: {value: Asset; url: string}) => {
|
|
31
|
+
switch (value.type) {
|
|
32
|
+
case 'video':
|
|
33
|
+
return <VideoPlayer src={url} kind="player" />
|
|
34
|
+
default:
|
|
35
|
+
return (
|
|
36
|
+
<Flex justify="center">
|
|
37
|
+
<img
|
|
38
|
+
alt="preview"
|
|
39
|
+
src={value?.preview?.url}
|
|
40
|
+
style={{
|
|
41
|
+
maxWidth: '100%',
|
|
42
|
+
height: 'auto',
|
|
43
|
+
display: 'block',
|
|
44
|
+
maxHeight: '30vh',
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
</Flex>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const AssetPreview = ({value}: ComponentProps) => {
|
|
53
|
+
const url = value && value.url
|
|
54
|
+
const theme = useTheme().sanity
|
|
55
|
+
|
|
56
|
+
if (!value || !url) {
|
|
57
|
+
return null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const {filename, meta} = value
|
|
61
|
+
const {fileSize, duration} = meta
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<StyledBox studioTheme={theme} marginBottom={2}>
|
|
65
|
+
<RenderAsset value={value} url={url} />
|
|
66
|
+
<InfoLine padding={2} radius={2} margin={2} studioTheme={theme}>
|
|
67
|
+
<Text size={1} title={`Select ${filename}`}>
|
|
68
|
+
{filename} {fileSize && `(${prettyBytes(fileSize)})`}
|
|
69
|
+
</Text>
|
|
70
|
+
</InfoLine>
|
|
71
|
+
{duration && (
|
|
72
|
+
<DurationLine padding={2} radius={2} margin={2} studioTheme={theme}>
|
|
73
|
+
<Text size={1} title={`Video duration: ${filename}`}>
|
|
74
|
+
{prettyMilliseconds(duration, {colonNotation: true, secondsDecimalDigits: 0})}
|
|
75
|
+
</Text>
|
|
76
|
+
</DurationLine>
|
|
77
|
+
)}
|
|
78
|
+
</StyledBox>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default AssetPreview
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {useCallback} from 'react'
|
|
2
|
+
import {Box, Flex, Button} from '@sanity/ui'
|
|
3
|
+
import {LaunchIcon} from '@sanity/icons'
|
|
4
|
+
import React from 'react'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
title: string
|
|
8
|
+
shopifyDomain: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const DialogHeader = (props: Props) => {
|
|
12
|
+
const {title, shopifyDomain} = props
|
|
13
|
+
|
|
14
|
+
const handleOpenInNewTab = useCallback(() => {
|
|
15
|
+
window.open(`https://${shopifyDomain}/admin/settings/files`, '_blank')
|
|
16
|
+
}, [shopifyDomain])
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<Flex align="center">
|
|
20
|
+
{title}
|
|
21
|
+
{/*
|
|
22
|
+
HACK: Sanity UI will attempt to focus the first 'focusable' descendant of any dialog.
|
|
23
|
+
Typically this is fine, but since our first focusable element is a button with a tooltip, this
|
|
24
|
+
default behaviour causes the tooltip to appear whenever the dialog is opened, which we don't want!
|
|
25
|
+
|
|
26
|
+
To get around this, we include a pseudo-hidden input to ensure our tooltip-enabled button remains
|
|
27
|
+
unfocused on initial mount.
|
|
28
|
+
*/}
|
|
29
|
+
<input style={{opacity: 0}} tabIndex={-1} type="button" />
|
|
30
|
+
<Box style={{position: 'absolute', right: '-1.5em'}}>
|
|
31
|
+
<Box className="button-large">
|
|
32
|
+
<Button
|
|
33
|
+
fontSize={1}
|
|
34
|
+
icon={LaunchIcon}
|
|
35
|
+
mode="bleed"
|
|
36
|
+
onClick={handleOpenInNewTab}
|
|
37
|
+
text="Add New"
|
|
38
|
+
/>
|
|
39
|
+
</Box>
|
|
40
|
+
</Box>
|
|
41
|
+
</Flex>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default DialogHeader
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {Card, Theme} from '@sanity/ui'
|
|
2
|
+
import styled from 'styled-components'
|
|
3
|
+
|
|
4
|
+
type SanityTheme = Theme['sanity']
|
|
5
|
+
|
|
6
|
+
interface Style {
|
|
7
|
+
studioTheme: SanityTheme
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const Root = styled.div`
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
background-origin: content-box;
|
|
13
|
+
background-repeat: no-repeat;
|
|
14
|
+
background-clip: border-box;
|
|
15
|
+
background-size: cover;
|
|
16
|
+
background-color: ${({studioTheme}: Style) => studioTheme.color.card.enabled.bg2};
|
|
17
|
+
position: relative;
|
|
18
|
+
outline: none !important;
|
|
19
|
+
border: ${({studioTheme}: Style) => `1px solid ${studioTheme.color.card.enabled.border}`};
|
|
20
|
+
box-sizing: content-box;
|
|
21
|
+
user-drag: none;
|
|
22
|
+
|
|
23
|
+
&:hover {
|
|
24
|
+
opacity: 0.85;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:focus,
|
|
28
|
+
&:active {
|
|
29
|
+
border: 1px solid var(--input-border-color-focus);
|
|
30
|
+
box-shadow: inset 0 0 0 3px var(--input-border-color-focus);
|
|
31
|
+
}
|
|
32
|
+
`
|
|
33
|
+
|
|
34
|
+
export const InfoLine = styled(Card)`
|
|
35
|
+
${({studioTheme}: Style) => `
|
|
36
|
+
--infoline-fg: ${studioTheme.color.card.enabled.fg};
|
|
37
|
+
--infoline-bg: ${studioTheme.color.card.enabled.bg};
|
|
38
|
+
`};
|
|
39
|
+
user-drag: none;
|
|
40
|
+
position: absolute;
|
|
41
|
+
background-color: var(--infoline-bg);
|
|
42
|
+
top: 0;
|
|
43
|
+
left: 0;
|
|
44
|
+
max-width: 65%;
|
|
45
|
+
overflow-wrap: break-word;
|
|
46
|
+
|
|
47
|
+
[data-ui='Text'] {
|
|
48
|
+
color: var(--infoline-fg);
|
|
49
|
+
}
|
|
50
|
+
`
|
|
51
|
+
|
|
52
|
+
export const DurationLine = styled(Card)`
|
|
53
|
+
${({studioTheme}: Style) => `
|
|
54
|
+
--durationline-fg: ${studioTheme.color.card.enabled.bg};
|
|
55
|
+
--durationline-bg: ${studioTheme.color.card.enabled.fg};
|
|
56
|
+
`};
|
|
57
|
+
user-drag: none;
|
|
58
|
+
position: absolute;
|
|
59
|
+
background-color: var(--durationline-bg);
|
|
60
|
+
top: 0;
|
|
61
|
+
right: 0;
|
|
62
|
+
|
|
63
|
+
[data-ui='Text'] {
|
|
64
|
+
color: var(--durationline-fg);
|
|
65
|
+
}
|
|
66
|
+
`
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {Asset, ShopifyFile} from '../types'
|
|
2
|
+
import {DurationLine, InfoLine, Root} from './File.styled'
|
|
3
|
+
import React, {useCallback, useRef} from 'react'
|
|
4
|
+
import {Text, useTheme} from '@sanity/ui'
|
|
5
|
+
|
|
6
|
+
import {extractName} from '../utils/helpers'
|
|
7
|
+
import prettyBytes from 'pretty-bytes'
|
|
8
|
+
import prettyMilliseconds from 'pretty-ms'
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
data: ShopifyFile
|
|
12
|
+
width: number
|
|
13
|
+
height: number
|
|
14
|
+
onClick: (file: Asset) => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function File(props: Props) {
|
|
18
|
+
const {onClick, data, width, height} = props
|
|
19
|
+
const rootElm = useRef<HTMLDivElement>(null)
|
|
20
|
+
|
|
21
|
+
const {preview, meta} = data
|
|
22
|
+
const filename = extractName(data.url)
|
|
23
|
+
|
|
24
|
+
const handleClick = useCallback(() => {
|
|
25
|
+
onClick({...data, filename})
|
|
26
|
+
}, [onClick, data, filename])
|
|
27
|
+
|
|
28
|
+
const theme = useTheme().sanity
|
|
29
|
+
return (
|
|
30
|
+
<Root
|
|
31
|
+
ref={rootElm}
|
|
32
|
+
studioTheme={theme}
|
|
33
|
+
title={`${filename}`}
|
|
34
|
+
tabIndex={0}
|
|
35
|
+
style={{
|
|
36
|
+
width: `${width}px`,
|
|
37
|
+
height: `${height}px`,
|
|
38
|
+
backgroundImage: `url("${preview?.url}")`,
|
|
39
|
+
}}
|
|
40
|
+
onClick={handleClick}
|
|
41
|
+
>
|
|
42
|
+
<InfoLine padding={2} radius={2} margin={2} studioTheme={theme}>
|
|
43
|
+
<Text size={1} title={`Select ${filename}`}>
|
|
44
|
+
{filename} {meta.fileSize && `(${prettyBytes(meta.fileSize)})`}
|
|
45
|
+
</Text>
|
|
46
|
+
</InfoLine>
|
|
47
|
+
{meta.duration && (
|
|
48
|
+
<DurationLine padding={2} radius={2} margin={2} studioTheme={theme}>
|
|
49
|
+
<Text size={1} title={`Video duration: ${filename}`}>
|
|
50
|
+
{prettyMilliseconds(meta.duration, {colonNotation: true, secondsDecimalDigits: 0})}
|
|
51
|
+
</Text>
|
|
52
|
+
</DurationLine>
|
|
53
|
+
)}
|
|
54
|
+
</Root>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {Button, Card, Flex, Grid, Inline, Stack, Text} from '@sanity/ui'
|
|
2
|
+
import {ObjectInputProps, PatchEvent, unset} from 'sanity'
|
|
3
|
+
import {useCallback, useState} from 'react'
|
|
4
|
+
|
|
5
|
+
import {Asset} from '../types'
|
|
6
|
+
import AssetPreview from './AssetPreview'
|
|
7
|
+
import {ErrorOutlineIcon} from '@sanity/icons'
|
|
8
|
+
import React from 'react'
|
|
9
|
+
import ShopifyAssetPicker from './ShopifyAssetPicker'
|
|
10
|
+
import ShopifyIcon from './ShopifyIcon'
|
|
11
|
+
|
|
12
|
+
export default function ShopifyAssetInput(props: ObjectInputProps) {
|
|
13
|
+
const {onChange, readOnly, value, schemaType} = props
|
|
14
|
+
const {options} = schemaType
|
|
15
|
+
const {shopifyDomain} = options
|
|
16
|
+
|
|
17
|
+
const [dialogOpen, setDialogOpen] = useState(false)
|
|
18
|
+
|
|
19
|
+
const removeValue = useCallback(() => {
|
|
20
|
+
onChange(PatchEvent.from([unset()]))
|
|
21
|
+
}, [onChange])
|
|
22
|
+
|
|
23
|
+
const onOpen = useCallback(() => {
|
|
24
|
+
setDialogOpen(true)
|
|
25
|
+
}, [setDialogOpen])
|
|
26
|
+
|
|
27
|
+
const onClose = useCallback(() => {
|
|
28
|
+
setDialogOpen(false)
|
|
29
|
+
}, [setDialogOpen])
|
|
30
|
+
|
|
31
|
+
if (!shopifyDomain) {
|
|
32
|
+
return (
|
|
33
|
+
<Card overflow="hidden" padding={4} radius={2} shadow={1} tone="critical">
|
|
34
|
+
<Flex align="center" gap={3}>
|
|
35
|
+
<Text size={2}>
|
|
36
|
+
<ErrorOutlineIcon />
|
|
37
|
+
</Text>
|
|
38
|
+
<Inline space={2}>
|
|
39
|
+
<Text size={1}>
|
|
40
|
+
You need to configure your *.myshopify.com domain in the plugin / field options to
|
|
41
|
+
enable Shopify Assets.
|
|
42
|
+
</Text>
|
|
43
|
+
</Inline>
|
|
44
|
+
</Flex>
|
|
45
|
+
</Card>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<>
|
|
51
|
+
{dialogOpen && (
|
|
52
|
+
<ShopifyAssetPicker
|
|
53
|
+
{...props}
|
|
54
|
+
shopifyDomain={shopifyDomain}
|
|
55
|
+
isOpen={dialogOpen}
|
|
56
|
+
onClose={onClose}
|
|
57
|
+
value={value as Asset}
|
|
58
|
+
/>
|
|
59
|
+
)}
|
|
60
|
+
<Stack>
|
|
61
|
+
<AssetPreview value={value as Asset} />
|
|
62
|
+
|
|
63
|
+
<Grid gap={1} style={{gridTemplateColumns: 'repeat(auto-fit, minmax(100px, 1fr))'}}>
|
|
64
|
+
<Button
|
|
65
|
+
disabled={readOnly}
|
|
66
|
+
mode="ghost"
|
|
67
|
+
icon={ShopifyIcon}
|
|
68
|
+
title="Select an asset"
|
|
69
|
+
onClick={onOpen}
|
|
70
|
+
text="Select…"
|
|
71
|
+
/>
|
|
72
|
+
<Button
|
|
73
|
+
disabled={readOnly || !value}
|
|
74
|
+
tone="critical"
|
|
75
|
+
mode="ghost"
|
|
76
|
+
title="Remove asset"
|
|
77
|
+
text="Remove"
|
|
78
|
+
onClick={removeValue}
|
|
79
|
+
/>
|
|
80
|
+
</Grid>
|
|
81
|
+
</Stack>
|
|
82
|
+
</>
|
|
83
|
+
)
|
|
84
|
+
}
|