@secretstache/wordpress-gutenberg 0.2.5 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. package/README.md +4 -0
  2. package/build/index.js +8 -2
  3. package/build/index.js.map +1 -1
  4. package/build/{index.css → styles.css} +44 -10
  5. package/package.json +5 -3
  6. package/src/components/ColorPaletteControl.js +24 -0
  7. package/src/components/DataQueryControls.js +51 -0
  8. package/src/components/DividersControl.js +74 -0
  9. package/src/components/IconPicker.js +73 -0
  10. package/src/components/ImageActions.js +59 -0
  11. package/src/components/LinkControl.js +30 -0
  12. package/src/components/MediaPicker.js +179 -0
  13. package/src/components/MediaTypeControl.js +54 -0
  14. package/src/components/ResourcesWrapper.js +46 -0
  15. package/src/components/ResponsiveSpacingControl.js +74 -0
  16. package/src/components/SortableSelect.js +60 -0
  17. package/src/components/SpacingControl.js +119 -0
  18. package/src/components/index.js +12 -0
  19. package/src/hooks/index.js +11 -0
  20. package/src/hooks/useAccordionItem.js +51 -0
  21. package/src/hooks/useAllowedBlocks.js +25 -0
  22. package/src/hooks/useBlockTabsData.js +90 -0
  23. package/src/hooks/useChildBlockPosition.js +31 -0
  24. package/src/hooks/useColorChange.js +12 -0
  25. package/src/hooks/useDataQuery.js +45 -0
  26. package/src/hooks/useParentBlock.js +57 -0
  27. package/src/hooks/usePreviewToggle.js +32 -0
  28. package/src/hooks/useSlider.js +24 -0
  29. package/src/hooks/useThemeColors.js +19 -0
  30. package/src/hooks/useUpdateAttribute.js +4 -0
  31. package/src/index.js +6 -0
  32. package/src/styles/_animation-file-renderer.scss +11 -0
  33. package/src/styles/_editor-base.scss +56 -0
  34. package/src/styles/_icon-picker.scss +4 -0
  35. package/src/styles/_image-wrapper.scss +59 -0
  36. package/src/styles/_link-control.scss +6 -0
  37. package/src/styles/_media-picker.scss +20 -0
  38. package/src/styles/_new-child-btn.scss +15 -0
  39. package/src/styles/_responsive-spacing.scss +30 -0
  40. package/src/styles/_root-block-appender.scss +40 -0
  41. package/src/styles/_sortable-select.scss +5 -0
  42. package/src/styles/styles.scss +12 -0
  43. package/src/utils/attributes.js +224 -0
  44. package/src/utils/constants.js +17 -0
  45. package/src/utils/helpers.js +175 -0
  46. package/src/utils/index.js +6 -0
  47. package/src/utils/rootBlock/README.md +71 -0
  48. package/src/utils/rootBlock/hideRootBlockForInlineInserter.js +13 -0
  49. package/src/utils/rootBlock/hideRootBlockForOtherBlocks.js +32 -0
  50. package/src/utils/rootBlock/index.js +4 -0
  51. package/src/utils/rootBlock/initRootBlockAppender.js +45 -0
  52. package/src/utils/rootBlock/setRootBlock.js +32 -0
  53. package/src/utils/waitForContainer/README.md +40 -0
  54. package/src/utils/waitForContainer/index.js +25 -0
@@ -10,16 +10,17 @@
10
10
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
11
11
  text-align: center; }
12
12
 
13
- .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container.has-background {
14
- transition: background 1s, color 1s; }
15
-
16
- .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container > .block-list-appender.wp-block:only-child p {
17
- margin-top: 0;
18
- margin-bottom: 0; }
19
-
20
- .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container > .block-list-appender.wp-block:only-child,
21
- .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container > p.wp-block:only-child {
22
- margin: 2rem 0; }
13
+ .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container {
14
+ margin-bottom: 3rem;
15
+ padding-bottom: 100px; }
16
+ .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container.has-background {
17
+ transition: background 1s, color 1s; }
18
+ .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container > .block-list-appender.wp-block:only-child p {
19
+ margin-top: 0;
20
+ margin-bottom: 0; }
21
+ .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container > .block-list-appender.wp-block:only-child,
22
+ .block-editor__container .editor-styles-wrapper .block-editor-block-list__layout.is-root-container > p.wp-block:only-child {
23
+ margin: 2rem 0; }
23
24
 
24
25
  .block-editor__container .block-editor-block-types-list > [role=presentation] {
25
26
  justify-content: center; }
@@ -142,3 +143,36 @@
142
143
  padding: 12px !important;
143
144
  box-shadow: inset 0 0 0 1px #1e1e1e;
144
145
  color: #1e1e1e; }
146
+
147
+ .block-editor__container .root-block-appender {
148
+ position: absolute;
149
+ bottom: 30px;
150
+ left: 50%;
151
+ transform: translateX(-50%);
152
+ width: calc(100% - var(--content-padding) * 2); }
153
+ .block-editor__container .root-block-appender::after {
154
+ content: attr(data-tooltip);
155
+ position: absolute;
156
+ left: 50%;
157
+ bottom: -30px;
158
+ transform: translateX(-50%);
159
+ z-index: 1;
160
+ visibility: hidden;
161
+ opacity: 0;
162
+ transition: opacity 0.3s;
163
+ width: max-content;
164
+ max-width: 200px;
165
+ white-space: nowrap;
166
+ background: #000;
167
+ border-radius: 2px;
168
+ color: #f0f0f0;
169
+ font-size: 12px;
170
+ line-height: 1.4;
171
+ padding: 4px 8px;
172
+ text-align: center;
173
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, sans-serif; }
174
+ .block-editor__container .root-block-appender:hover::after {
175
+ visibility: visible;
176
+ opacity: 1; }
177
+ .block-editor__container .root-block-appender ~ .block-list-appender.wp-block {
178
+ display: none; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secretstache/wordpress-gutenberg",
3
- "version": "0.2.5",
3
+ "version": "0.3.1",
4
4
  "description": "",
5
5
  "author": "Secret Stache",
6
6
  "license": "GPL-2.0-or-later",
@@ -14,7 +14,8 @@
14
14
  "main": "build/index.js",
15
15
  "module": "build/index.es.js",
16
16
  "files": [
17
- "build"
17
+ "build",
18
+ "src"
18
19
  ],
19
20
  "type": "module",
20
21
  "scripts": {
@@ -50,18 +51,19 @@
50
51
  "rollup-plugin-postcss": "^4.0.2"
51
52
  },
52
53
  "dependencies": {
54
+ "classnames": "^2.5.1",
53
55
  "es-toolkit": "^1.12.0",
54
56
  "react-select": "5.7.5",
55
57
  "react-sortable-hoc": "2.0.0",
56
58
  "slugify": "^1.6.6"
57
59
  },
58
60
  "peerDependencies": {
59
- "@wordpress/dom-ready": "^4.3.0",
60
61
  "@wordpress/api-fetch": "^6.52.0",
61
62
  "@wordpress/block-editor": "^12.22.0",
62
63
  "@wordpress/blocks": "^12.34.0",
63
64
  "@wordpress/components": "^27.2.0",
64
65
  "@wordpress/data": "^9.24.0",
66
+ "@wordpress/dom-ready": "^4.3.0",
65
67
  "@wordpress/element": "^5.32.0",
66
68
  "@wordpress/hooks": "^3.57.0",
67
69
  "@wordpress/icons": "^9.45.0",
@@ -0,0 +1,24 @@
1
+ import { BaseControl, ColorPalette } from '@wordpress/components';
2
+ import { useThemeColors, useColorChange } from '../hooks';
3
+
4
+ export const ColorPaletteControl = ({
5
+ label = 'Color',
6
+ value,
7
+ attributeName,
8
+ setAttributes,
9
+ allowedColors,
10
+ }) => {
11
+ const colors = useThemeColors(allowedColors);
12
+ const onColorChange = useColorChange(colors, setAttributes);
13
+
14
+ return (
15
+ <BaseControl label={label}>
16
+ <ColorPalette
17
+ colors={colors}
18
+ value={value}
19
+ disableCustomColors={true}
20
+ onChange={(colorValue) => onColorChange(colorValue, attributeName)}
21
+ />
22
+ </BaseControl>
23
+ );
24
+ };
@@ -0,0 +1,51 @@
1
+ import { RadioControl } from '@wordpress/components';
2
+
3
+ // TODO: add support of curated posts, categories; consider merging with the useDataQuery hook
4
+ export const DataQueryControls = (props) => {
5
+ const {
6
+ dataSourceLabel = 'Data Source',
7
+ dataSource,
8
+ onDataSourceChange,
9
+
10
+ queryTypeLabel = 'Query',
11
+ queryType,
12
+ onQueryTypeChange,
13
+
14
+ settings,
15
+ } = props;
16
+
17
+ const sourcesList = settings
18
+ .filter((source) => source?.value && source?.label)
19
+ .map((source) => ({ label: source.label, value: source.value }));
20
+
21
+ const queriesList = settings.find((source) => source.value === dataSource)?.queries || [];
22
+
23
+ const hasSources = sourcesList && sourcesList?.length > 0;
24
+ const hasQueries = queriesList && queriesList?.length > 0;
25
+
26
+ return (
27
+ <>
28
+ {
29
+ hasSources && (
30
+ <RadioControl
31
+ label={dataSourceLabel}
32
+ selected={dataSource}
33
+ options={sourcesList}
34
+ onChange={onDataSourceChange}
35
+ />
36
+ )
37
+ }
38
+
39
+ {
40
+ hasQueries && (
41
+ <RadioControl
42
+ label={queryTypeLabel}
43
+ selected={queryType}
44
+ options={queriesList}
45
+ onChange={onQueryTypeChange}
46
+ />
47
+ )
48
+ }
49
+ </>
50
+ )
51
+ }
@@ -0,0 +1,74 @@
1
+ import { SelectControl, ToggleControl } from '@wordpress/components';
2
+ import { useEffect, useState } from '@wordpress/element';
3
+
4
+ export const DividersControl = ({
5
+ topDividers = [],
6
+ bottomDividers = [],
7
+ value = { topDivider: '', bottomDivider: '', isIncludeLine: false },
8
+ hasLine = true,
9
+ onChange,
10
+ }) => {
11
+ const hasTop = topDividers && topDividers?.length > 0;
12
+ const hasBottom = bottomDividers && bottomDividers?.length > 0;
13
+
14
+ const [ topDivider, setTopDivider ] = useState(value?.topDivider || '');
15
+ const [ bottomDivider, setBottomDivider ] = useState(value?.bottomDivider || '');
16
+ const [ isIncludeLine, setIsIncludeLine ] = useState(value?.isIncludeLine || false);
17
+
18
+ useEffect(() => {
19
+ onChange({
20
+ topDivider,
21
+ bottomDivider,
22
+ isIncludeLine,
23
+ });
24
+ }, [ topDivider, bottomDivider, isIncludeLine ]);
25
+
26
+ return (
27
+ <>
28
+ {
29
+ hasTop && (
30
+ <SelectControl
31
+ label="Top Divider"
32
+ value={topDivider}
33
+ onChange={(topDivider) => setTopDivider(topDivider)}
34
+ options={[
35
+ {
36
+ label: 'None',
37
+ value: ''
38
+ },
39
+ ...topDividers,
40
+ ]}
41
+
42
+ />
43
+ )
44
+ }
45
+
46
+ {
47
+ hasBottom && (
48
+ <SelectControl
49
+ label="Bottom Divider"
50
+ value={bottomDivider}
51
+ onChange={(bottomDivider) => setBottomDivider(bottomDivider)}
52
+ options={[
53
+ {
54
+ label: 'None',
55
+ value: ''
56
+ },
57
+ ...bottomDividers,
58
+ ]}
59
+ />
60
+ )
61
+ }
62
+
63
+ {
64
+ hasLine && (
65
+ <ToggleControl
66
+ label="Include Vertical Line leading from this block to the next"
67
+ checked={isIncludeLine}
68
+ onChange={() => setIsIncludeLine((prevState) => !prevState)}
69
+ />
70
+ )
71
+ }
72
+ </>
73
+ );
74
+ }
@@ -0,0 +1,73 @@
1
+ import {
2
+ MediaPlaceholder,
3
+ MediaUpload,
4
+ MediaUploadCheck,
5
+ } from '@wordpress/block-editor';
6
+ import { Button, Icon } from '@wordpress/components';
7
+ import { edit as editIcon, trash as trashIcon } from '@wordpress/icons';
8
+
9
+ export const IconPicker = ({ imageId, imageUrl, imageAlt, svgCode, onSelect, onRemove }) => {
10
+ const hasImage = imageId && imageUrl;
11
+ const isSvg = hasImage && svgCode;
12
+
13
+ return (
14
+ <MediaUploadCheck>
15
+ <MediaUpload
16
+ onSelect={onSelect}
17
+ allowedTypes={['image']}
18
+ value={imageId}
19
+ render={({ open }) => {
20
+ return hasImage ? (
21
+ <div className="bc-image-wrapper">
22
+ {hasImage && (
23
+ isSvg ? (
24
+ <div
25
+ className="svg-container"
26
+ dangerouslySetInnerHTML={{ __html: svgCode }}
27
+ />
28
+ ) : (
29
+ <img src={imageUrl} alt={imageAlt || 'icon'} />
30
+ )
31
+ )}
32
+
33
+ <div className="bc-image-wrapper__actions">
34
+ <Button
35
+ className="bc-image-wrapper__btn bc-image-wrapper__replace-btn"
36
+ type="button"
37
+ onClick={open}
38
+ >
39
+ <Icon
40
+ icon={editIcon}
41
+ size={20}
42
+ className="bc-image-wrapper__btn-icon"
43
+ />
44
+ </Button>
45
+
46
+ <Button
47
+ className="bc-image-wrapper__btn bc-image-wrapper__remove-btn"
48
+ type="button"
49
+ onClick={onRemove}
50
+ >
51
+ <Icon
52
+ icon={trashIcon}
53
+ size={20}
54
+ className="bc-image-wrapper__btn-icon"
55
+ />
56
+ </Button>
57
+ </div>
58
+
59
+ <div className="bc-image-wrapper__overlay" />
60
+ </div>
61
+ ) : (
62
+ <MediaPlaceholder
63
+ icon="format-image"
64
+ onSelect={onSelect}
65
+ allowedTypes={['image', 'image/svg+xml']}
66
+ labels={{ title: 'Icon Image' }}
67
+ />
68
+ );
69
+ }}
70
+ />
71
+ </MediaUploadCheck>
72
+ );
73
+ };
@@ -0,0 +1,59 @@
1
+ import { MediaUpload, MediaUploadCheck, MediaPlaceholder } from '@wordpress/block-editor';
2
+ import { Button } from '@wordpress/components';
3
+
4
+ export const ImageActions = ({
5
+ imageId,
6
+ imageUrl,
7
+ imageAlt,
8
+ placeholder = false,
9
+ onSelectImage,
10
+ onRemoveImage,
11
+ className = '',
12
+ }) => {
13
+ const hasImage = imageId && imageUrl;
14
+
15
+ return (
16
+ <MediaUploadCheck>
17
+ <MediaUpload
18
+ onSelect={onSelectImage}
19
+ allowedTypes={['image']}
20
+ value={imageId}
21
+ render={({ open }) => {
22
+ return hasImage ? (
23
+ <div className={`bc-image-wrapper ${className}`}>
24
+ <img src={imageUrl} alt={imageAlt} onClick={open} />
25
+ <div className="bc-image-wrapper__actions">
26
+ <Button
27
+ className="bc-image-wrapper__btn bc-image-wrapper__replace-btn"
28
+ type="button"
29
+ onClick={open}
30
+ >
31
+ Replace
32
+ </Button>
33
+ <Button
34
+ className="bc-image-wrapper__btn bc-image-wrapper__remove-btn"
35
+ type="button"
36
+ onClick={onRemoveImage}
37
+ >
38
+ Remove
39
+ </Button>
40
+ </div>
41
+ <div className="bc-image-wrapper__overlay" />
42
+ </div>
43
+ ) : placeholder ? (
44
+ <MediaPlaceholder
45
+ className="media-placeholder"
46
+ icon="format-image"
47
+ onSelect={onSelectImage}
48
+ allowedTypes={['image']}
49
+ labels={{
50
+ title: 'Image',
51
+ instructions: 'Upload an image file or pick one from your media library.',
52
+ }}
53
+ />
54
+ ) : null;
55
+ }}
56
+ />
57
+ </MediaUploadCheck>
58
+ );
59
+ };
@@ -0,0 +1,30 @@
1
+ import { BaseControl, CheckboxControl } from '@wordpress/components';
2
+ import { URLInput } from '@wordpress/block-editor';
3
+ import { useUpdateAttribute } from '../hooks';
4
+
5
+ export const LinkControl = ({
6
+ url = { value: '#', attrName: 'linkSource' },
7
+ isOpenInNewTab = { value: false, attrName: 'linkIsOpenInNewTab'},
8
+ setAttributes,
9
+ label = 'Source',
10
+ }) => {
11
+ const updateAttribute = useUpdateAttribute(setAttributes);
12
+
13
+ return (
14
+ <>
15
+ <BaseControl label={label}>
16
+ <URLInput
17
+ className="bc-url-input"
18
+ value={url.value}
19
+ onChange={(newUrl) => setAttributes({ [url.attrName]: newUrl })}
20
+ />
21
+ </BaseControl>
22
+
23
+ <CheckboxControl
24
+ checked={isOpenInNewTab.value}
25
+ label="Open in a new tab"
26
+ onChange={(newIsOpenInNewTab) => setAttributes({ [isOpenInNewTab.attrName]: newIsOpenInNewTab })}
27
+ />
28
+ </>
29
+ );
30
+ };
@@ -0,0 +1,179 @@
1
+ import { Button, Icon as WPIcon } from '@wordpress/components';
2
+ import { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';
3
+ import { page as pageIcon } from '@wordpress/icons';
4
+
5
+ import { MEDIA_TYPES } from '../utils/index.js';
6
+
7
+ export const BCImageRenderer = ({
8
+ imageId,
9
+ imageUrl,
10
+ onImageClick,
11
+ onRemoveClick,
12
+ onSelectClick,
13
+ }) => {
14
+ return imageId && imageUrl ? (
15
+ <>
16
+ <div className="bc-selected-media-wrapper">
17
+ <img
18
+ src={imageUrl}
19
+ className="bc-selected-media bc-selected-media--image"
20
+ alt="Selected Image"
21
+ onClick={onImageClick}
22
+ />
23
+ </div>
24
+
25
+ <Button
26
+ className="bc-remove-btn"
27
+ onClick={onRemoveClick}
28
+ isSecondary
29
+ isDestructive
30
+ >
31
+ Remove Image
32
+ </Button>
33
+ </>
34
+ ) : (
35
+ <Button
36
+ variant="secondary"
37
+ onClick={onSelectClick}
38
+ className="bc-select-btn"
39
+ >
40
+ Select Image
41
+ </Button>
42
+ );
43
+ };
44
+
45
+ export const BCVideoRenderer = ({
46
+ videoId,
47
+ videoUrl,
48
+ onRemoveClick,
49
+ onSelectClick,
50
+ }) => {
51
+ return videoId && videoUrl ? (
52
+ <>
53
+ <div className="bc-selected-media-wrapper">
54
+ <video src={videoUrl} className="bc-selected-media bc-selected-media--video" controls />
55
+ </div>
56
+
57
+ <Button
58
+ className="bc-remove-btn"
59
+ onClick={onRemoveClick}
60
+ isSecondary
61
+ isDestructive
62
+ >
63
+ Remove Video
64
+ </Button>
65
+ </>
66
+ ) : (
67
+ <Button
68
+ variant="secondary"
69
+ onClick={onSelectClick}
70
+ className="bc-select-btn"
71
+ >
72
+ Select Video
73
+ </Button>
74
+ );
75
+ };
76
+
77
+ export const BCAnimationRenderer = ({
78
+ animationFileId,
79
+ animationFileUrl,
80
+ animationFileName,
81
+ onSelectClick,
82
+ onRemoveClick,
83
+ }) => {
84
+ return animationFileId && animationFileUrl ? (
85
+ <>
86
+ <div className="bc-animation-block-json-file" onClick={onSelectClick}>
87
+ <WPIcon icon={pageIcon} size={36}/>
88
+ <span>{animationFileName}</span>
89
+ </div>
90
+ <Button
91
+ variant="secondary"
92
+ isDestructive
93
+ className="bc-remove-btn"
94
+ onClick={onRemoveClick}
95
+ >
96
+ Remove File
97
+ </Button>
98
+ </>
99
+ ) : (
100
+ <Button variant="secondary" onClick={onSelectClick}>
101
+ Select File
102
+ </Button>
103
+ )
104
+ };
105
+
106
+ // TODO: find better name
107
+ export const BCMediaPicker = ({
108
+ mediaId,
109
+ mediaUrl,
110
+ mediaFileName = '',
111
+ onSelect,
112
+ onRemove,
113
+ type = MEDIA_TYPES.IMAGE,
114
+ ...other
115
+ }) => {
116
+ if (type === MEDIA_TYPES.IMAGE) {
117
+ return (
118
+ <MediaUploadCheck>
119
+ <MediaUpload
120
+ onSelect={onSelect}
121
+ allowedTypes={['image', 'image/svg+xml']}
122
+ accept="image/*"
123
+ value={mediaId}
124
+ render={({ open }) => (
125
+ <BCImageRenderer
126
+ imageId={mediaId}
127
+ imageUrl={mediaUrl}
128
+ onImageClick={open}
129
+ onSelectClick={open}
130
+ onRemoveClick={onRemove}
131
+ />
132
+ )}
133
+ { ...other }
134
+ />
135
+ </MediaUploadCheck>
136
+ );
137
+ } else if (type === MEDIA_TYPES.VIDEO) {
138
+ return (
139
+ <MediaUploadCheck>
140
+ <MediaUpload
141
+ onSelect={onSelect}
142
+ allowedTypes={['video']}
143
+ value={mediaId}
144
+ render={({ open }) => (
145
+ <BCVideoRenderer
146
+ videoId={mediaId}
147
+ videoUrl={mediaUrl}
148
+ onSelectClick={open}
149
+ onRemoveClick={onRemove}
150
+ />
151
+ )}
152
+ { ...other }
153
+ />
154
+ </MediaUploadCheck>
155
+ );
156
+ } else if (type === MEDIA_TYPES.ANIMATION) {
157
+ return (
158
+ <MediaUploadCheck>
159
+ <MediaUpload
160
+ onSelect={onSelect}
161
+ allowedTypes={['application/json', 'text/plain', 'application/lottie']}
162
+ value={mediaId}
163
+ render={({ open }) => (
164
+ <BCAnimationRenderer
165
+ animationFileId={mediaId}
166
+ animationFileUrl={mediaUrl}
167
+ animationFileName={mediaFileName}
168
+ onSelectClick={open}
169
+ onRemoveClick={onRemove}
170
+ />
171
+ )}
172
+ {...other}
173
+ />
174
+ </MediaUploadCheck>
175
+ );
176
+ } else {
177
+ throw new Error('Unrecognized media type.');
178
+ }
179
+ };
@@ -0,0 +1,54 @@
1
+ import { useState } from '@wordpress/element';
2
+ import { SelectControl } from '@wordpress/components';
3
+
4
+ import { BCMediaPicker } from './MediaPicker.js';
5
+ import { MEDIA_TYPE_LABELS} from '../utils/index.js';
6
+
7
+ export const MediaTypeControl = (props) => {
8
+ const {
9
+ mediaTypes = [],
10
+ mediaId,
11
+ mediaUrl,
12
+ mediaFileName = '',
13
+ mediaOnSelect,
14
+ mediaOnRemove,
15
+ } = props;
16
+
17
+ const [ selectedMediaType, setSelectedMediaType ] = useState(mediaTypes?.[0]);
18
+
19
+ const mediaTypesOptions = mediaTypes
20
+ ?.filter((type) => MEDIA_TYPE_LABELS[type]) // Ensure it's an allowed type
21
+ ?.map((type) => ({
22
+ label: MEDIA_TYPE_LABELS[type],
23
+ value: type,
24
+ }));
25
+
26
+ return (
27
+ <>
28
+ {
29
+ // TODO: add custom label
30
+ mediaTypes && (
31
+ <SelectControl
32
+ label="Media Type"
33
+ value={selectedMediaType}
34
+ onChange={(mediaType) => setSelectedMediaType(mediaType)}
35
+ options={mediaTypesOptions}
36
+ />
37
+ )
38
+ }
39
+
40
+ {
41
+ selectedMediaType && (
42
+ <BCMediaPicker
43
+ mediaId={mediaId}
44
+ mediaUrl={mediaUrl}
45
+ mediaFileName={mediaFileName}
46
+ type={selectedMediaType}
47
+ onSelect={mediaOnSelect}
48
+ onRemove={mediaOnRemove}
49
+ />
50
+ )
51
+ }
52
+ </>
53
+ );
54
+ }