@brilo/base-blocks 0.1.1 → 0.1.3
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/build/blocks/form/form-group/edit.d.ts.map +1 -1
- package/build/blocks/form/form-group/edit.js +17 -3
- package/build/blocks/form/form-group/factory.d.ts.map +1 -1
- package/build/blocks/form/form-group/factory.js +1 -0
- package/build/blocks/form/form-group/types.d.ts +1 -0
- package/build/blocks/form/form-group/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/blocks/column/column-group/edit.tsx +56 -0
- package/src/blocks/column/column-group/editor.scss +7 -0
- package/src/blocks/column/column-group/factory.tsx +29 -0
- package/src/blocks/column/column-group/index.ts +14 -0
- package/src/blocks/column/column-group/types.ts +8 -0
- package/src/blocks/column/column-item/constants.ts +1 -0
- package/src/blocks/column/column-item/edit.tsx +48 -0
- package/src/blocks/column/column-item/editor.scss +34 -0
- package/src/blocks/column/column-item/factory.tsx +25 -0
- package/src/blocks/column/column-item/index.ts +10 -0
- package/src/blocks/column/column-item/types.ts +7 -0
- package/src/blocks/compare/compare-group/constants.ts +1 -0
- package/src/blocks/compare/compare-group/edit.tsx +52 -0
- package/src/blocks/compare/compare-group/factory.tsx +29 -0
- package/src/blocks/compare/compare-group/icon.tsx +7 -0
- package/src/blocks/compare/compare-group/index.ts +13 -0
- package/src/blocks/compare/compare-group/types.ts +12 -0
- package/src/blocks/compare/compare-item/edit.tsx +38 -0
- package/src/blocks/compare/compare-item/editor.scss +15 -0
- package/src/blocks/compare/compare-item/factory.tsx +28 -0
- package/src/blocks/compare/compare-item/icon.tsx +9 -0
- package/src/blocks/compare/compare-item/index.ts +13 -0
- package/src/blocks/compare/compare-item/types.ts +9 -0
- package/src/blocks/compare/compare-option/constants.ts +7 -0
- package/src/blocks/compare/compare-option/edit.tsx +64 -0
- package/src/blocks/compare/compare-option/editor.scss +26 -0
- package/src/blocks/compare/compare-option/factory.tsx +35 -0
- package/src/blocks/compare/compare-option/icon.tsx +7 -0
- package/src/blocks/compare/compare-option/index.ts +8 -0
- package/src/blocks/compare/compare-option/types.ts +12 -0
- package/src/blocks/contact/contact-group/constants.ts +3 -0
- package/src/blocks/contact/contact-group/edit.tsx +57 -0
- package/src/blocks/contact/contact-group/editor.scss +20 -0
- package/src/blocks/contact/contact-group/factory.tsx +35 -0
- package/src/blocks/contact/contact-group/index.ts +12 -0
- package/src/blocks/contact/contact-group/types.ts +12 -0
- package/src/blocks/contact/contact-item/constants.ts +17 -0
- package/src/blocks/contact/contact-item/edit.tsx +93 -0
- package/src/blocks/contact/contact-item/editor.scss +38 -0
- package/src/blocks/contact/contact-item/factory.tsx +35 -0
- package/src/blocks/contact/contact-item/index.ts +23 -0
- package/src/blocks/contact/contact-item/types.ts +21 -0
- package/src/blocks/core/basic-button/constants.ts +17 -0
- package/src/blocks/core/basic-button/edit.tsx +107 -0
- package/src/blocks/core/basic-button/editor.scss +80 -0
- package/src/blocks/core/basic-button/factory.tsx +54 -0
- package/src/blocks/core/basic-button/index.ts +8 -0
- package/src/blocks/core/basic-button/types.ts +29 -0
- package/src/blocks/core/basic-heading/constants.ts +1 -0
- package/src/blocks/core/basic-heading/edit.tsx +76 -0
- package/src/blocks/core/basic-heading/editor.scss +8 -0
- package/src/blocks/core/basic-heading/factory.tsx +40 -0
- package/src/blocks/core/basic-heading/index.ts +8 -0
- package/src/blocks/core/basic-heading/types.ts +20 -0
- package/src/blocks/core/basic-overline/edit.tsx +28 -0
- package/src/blocks/core/basic-overline/editor.scss +14 -0
- package/src/blocks/core/basic-overline/factory.tsx +22 -0
- package/src/blocks/core/basic-overline/index.ts +8 -0
- package/src/blocks/core/basic-overline/types.ts +7 -0
- package/src/blocks/faq/faq-group/constants.ts +11 -0
- package/src/blocks/faq/faq-group/edit.tsx +55 -0
- package/src/blocks/faq/faq-group/editor.scss +11 -0
- package/src/blocks/faq/faq-group/factory.tsx +39 -0
- package/src/blocks/faq/faq-group/index.ts +11 -0
- package/src/blocks/faq/faq-group/types.ts +14 -0
- package/src/blocks/faq/faq-item/edit.tsx +50 -0
- package/src/blocks/faq/faq-item/editor.scss +57 -0
- package/src/blocks/faq/faq-item/factory.tsx +24 -0
- package/src/blocks/faq/faq-item/index.ts +9 -0
- package/src/blocks/faq/faq-item/types.ts +7 -0
- package/src/blocks/form/form-field/constants.ts +14 -0
- package/src/blocks/form/form-field/edit.tsx +178 -0
- package/src/blocks/form/form-field/editor.scss +71 -0
- package/src/blocks/form/form-field/factory.tsx +32 -0
- package/src/blocks/form/form-field/index.ts +10 -0
- package/src/blocks/form/form-field/types.ts +18 -0
- package/src/blocks/form/form-group/constants.ts +16 -0
- package/src/blocks/form/form-group/edit.tsx +214 -0
- package/src/blocks/form/form-group/editor.scss +41 -0
- package/src/blocks/form/form-group/factory.tsx +36 -0
- package/src/blocks/form/form-group/index.ts +18 -0
- package/src/blocks/form/form-group/types.ts +23 -0
- package/src/blocks/groups/banner-group/constants.ts +15 -0
- package/src/blocks/groups/banner-group/edit.tsx +122 -0
- package/src/blocks/groups/banner-group/editor.scss +18 -0
- package/src/blocks/groups/banner-group/factory.tsx +64 -0
- package/src/blocks/groups/banner-group/icon.tsx +13 -0
- package/src/blocks/groups/banner-group/index.ts +11 -0
- package/src/blocks/groups/banner-group/types.ts +30 -0
- package/src/blocks/groups/basic-header-group/constants.ts +9 -0
- package/src/blocks/groups/basic-header-group/edit.tsx +99 -0
- package/src/blocks/groups/basic-header-group/editor.scss +35 -0
- package/src/blocks/groups/basic-header-group/factory.tsx +46 -0
- package/src/blocks/groups/basic-header-group/icon.tsx +17 -0
- package/src/blocks/groups/basic-header-group/index.ts +9 -0
- package/src/blocks/groups/basic-header-group/types.ts +27 -0
- package/src/blocks/groups/button-group/constants.ts +7 -0
- package/src/blocks/groups/button-group/edit.tsx +52 -0
- package/src/blocks/groups/button-group/editor.scss +23 -0
- package/src/blocks/groups/button-group/factory.tsx +34 -0
- package/src/blocks/groups/button-group/index.ts +11 -0
- package/src/blocks/groups/button-group/types.ts +12 -0
- package/src/blocks/groups/text-and-media-group/constants.ts +43 -0
- package/src/blocks/groups/text-and-media-group/edit.tsx +241 -0
- package/src/blocks/groups/text-and-media-group/editor.scss +123 -0
- package/src/blocks/groups/text-and-media-group/factory.tsx +100 -0
- package/src/blocks/groups/text-and-media-group/icon.tsx +37 -0
- package/src/blocks/groups/text-and-media-group/index.ts +18 -0
- package/src/blocks/groups/text-and-media-group/types.ts +60 -0
- package/src/blocks/hero/hero-group/constants.ts +23 -0
- package/src/blocks/hero/hero-group/edit.tsx +85 -0
- package/src/blocks/hero/hero-group/editor.scss +0 -0
- package/src/blocks/hero/hero-group/factory.tsx +45 -0
- package/src/blocks/hero/hero-group/icon.tsx +28 -0
- package/src/blocks/hero/hero-group/index.ts +11 -0
- package/src/blocks/hero/hero-group/types.ts +22 -0
- package/src/blocks/hero/hero-item/constants.ts +15 -0
- package/src/blocks/hero/hero-item/edit.tsx +107 -0
- package/src/blocks/hero/hero-item/editor.scss +87 -0
- package/src/blocks/hero/hero-item/factory.tsx +49 -0
- package/src/blocks/hero/hero-item/index.ts +10 -0
- package/src/blocks/hero/hero-item/types.ts +38 -0
- package/src/blocks/map/map-group/constants.ts +20 -0
- package/src/blocks/map/map-group/edit.tsx +108 -0
- package/src/blocks/map/map-group/editor.scss +24 -0
- package/src/blocks/map/map-group/factory.tsx +51 -0
- package/src/blocks/map/map-group/index.ts +9 -0
- package/src/blocks/map/map-group/types.ts +16 -0
- package/src/blocks/newsletter/newsletter-form/constants.ts +5 -0
- package/src/blocks/newsletter/newsletter-form/edit.tsx +194 -0
- package/src/blocks/newsletter/newsletter-form/editor.scss +68 -0
- package/src/blocks/newsletter/newsletter-form/factory.tsx +59 -0
- package/src/blocks/newsletter/newsletter-form/index.ts +11 -0
- package/src/blocks/newsletter/newsletter-form/types.ts +45 -0
- package/src/blocks/post/post-slider-group/constants.ts +3 -0
- package/src/blocks/post/post-slider-group/edit.tsx +76 -0
- package/src/blocks/post/post-slider-group/factory.tsx +43 -0
- package/src/blocks/post/post-slider-group/icon.tsx +13 -0
- package/src/blocks/post/post-slider-group/index.ts +9 -0
- package/src/blocks/post/post-slider-group/types.ts +20 -0
- package/src/blocks/responsive-grid/responsive-grid-group/edit.tsx +95 -0
- package/src/blocks/responsive-grid/responsive-grid-group/factory.tsx +33 -0
- package/src/blocks/responsive-grid/responsive-grid-group/index.ts +13 -0
- package/src/blocks/responsive-grid/responsive-grid-group/types.ts +9 -0
- package/src/blocks/responsive-grid/responsive-grid-item/edit.tsx +19 -0
- package/src/blocks/responsive-grid/responsive-grid-item/factory.tsx +20 -0
- package/src/blocks/responsive-grid/responsive-grid-item/index.ts +9 -0
- package/src/blocks/responsive-grid/responsive-grid-item/types.ts +5 -0
- package/src/blocks/sections/base-section/attributes.ts +17 -0
- package/src/blocks/sections/base-section/constants.ts +18 -0
- package/src/blocks/sections/base-section/controls.tsx +70 -0
- package/src/blocks/sections/base-section/edit.tsx +34 -0
- package/src/blocks/sections/base-section/editor.scss +24 -0
- package/src/blocks/sections/base-section/factory.tsx +47 -0
- package/src/blocks/sections/base-section/icon.tsx +6 -0
- package/src/blocks/sections/base-section/index.ts +14 -0
- package/src/blocks/sections/base-section/types.ts +26 -0
- package/src/blocks/signpost/signpost-group/constants.ts +3 -0
- package/src/blocks/signpost/signpost-group/edit.tsx +75 -0
- package/src/blocks/signpost/signpost-group/editor.scss +0 -0
- package/src/blocks/signpost/signpost-group/factory.tsx +40 -0
- package/src/blocks/signpost/signpost-group/icon.tsx +19 -0
- package/src/blocks/signpost/signpost-group/index.ts +15 -0
- package/src/blocks/signpost/signpost-group/types.ts +9 -0
- package/src/blocks/signpost/signpost-item/constants.ts +4 -0
- package/src/blocks/signpost/signpost-item/edit.tsx +90 -0
- package/src/blocks/signpost/signpost-item/editor.scss +25 -0
- package/src/blocks/signpost/signpost-item/factory.tsx +29 -0
- package/src/blocks/signpost/signpost-item/icon.tsx +7 -0
- package/src/blocks/signpost/signpost-item/index.ts +10 -0
- package/src/blocks/signpost/signpost-item/types.ts +12 -0
- package/src/blocks/step/step-group/constants.ts +6 -0
- package/src/blocks/step/step-group/edit.tsx +64 -0
- package/src/blocks/step/step-group/editor.scss +19 -0
- package/src/blocks/step/step-group/factory.tsx +36 -0
- package/src/blocks/step/step-group/icon.tsx +27 -0
- package/src/blocks/step/step-group/index.ts +15 -0
- package/src/blocks/step/step-group/types.ts +13 -0
- package/src/blocks/step/step-item/constants.ts +6 -0
- package/src/blocks/step/step-item/edit.tsx +60 -0
- package/src/blocks/step/step-item/editor.scss +18 -0
- package/src/blocks/step/step-item/factory.tsx +27 -0
- package/src/blocks/step/step-item/index.ts +11 -0
- package/src/blocks/step/step-item/types.ts +12 -0
- package/src/blocks/testimonial/testimonial-group/constants.ts +27 -0
- package/src/blocks/testimonial/testimonial-group/edit.tsx +74 -0
- package/src/blocks/testimonial/testimonial-group/editor.scss +38 -0
- package/src/blocks/testimonial/testimonial-group/factory.tsx +44 -0
- package/src/blocks/testimonial/testimonial-group/icon.tsx +33 -0
- package/src/blocks/testimonial/testimonial-group/index.ts +15 -0
- package/src/blocks/testimonial/testimonial-group/types.ts +19 -0
- package/src/blocks/testimonial/testimonial-item/edit.tsx +48 -0
- package/src/blocks/testimonial/testimonial-item/editor.scss +20 -0
- package/src/blocks/testimonial/testimonial-item/factory.tsx +35 -0
- package/src/blocks/testimonial/testimonial-item/index.ts +9 -0
- package/src/blocks/testimonial/testimonial-item/types.ts +9 -0
- package/src/blocks/text-and-form/text-and-form-group/constants.ts +6 -0
- package/src/blocks/text-and-form/text-and-form-group/edit.tsx +59 -0
- package/src/blocks/text-and-form/text-and-form-group/editor.scss +21 -0
- package/src/blocks/text-and-form/text-and-form-group/factory.tsx +38 -0
- package/src/blocks/text-and-form/text-and-form-group/icon.tsx +23 -0
- package/src/blocks/text-and-form/text-and-form-group/index.ts +9 -0
- package/src/blocks/text-and-form/text-and-form-group/types.ts +23 -0
- package/src/blocks/text-and-form/text-and-form-text-column/constants.ts +10 -0
- package/src/blocks/text-and-form/text-and-form-text-column/edit.tsx +94 -0
- package/src/blocks/text-and-form/text-and-form-text-column/editor.scss +29 -0
- package/src/blocks/text-and-form/text-and-form-text-column/factory.tsx +41 -0
- package/src/blocks/text-and-form/text-and-form-text-column/index.ts +18 -0
- package/src/blocks/text-and-form/text-and-form-text-column/types.ts +23 -0
- package/src/blocks/usp/usp-group/constants.ts +54 -0
- package/src/blocks/usp/usp-group/edit.tsx +197 -0
- package/src/blocks/usp/usp-group/editor.scss +24 -0
- package/src/blocks/usp/usp-group/factory.tsx +113 -0
- package/src/blocks/usp/usp-group/icon.tsx +18 -0
- package/src/blocks/usp/usp-group/index.ts +15 -0
- package/src/blocks/usp/usp-group/types.ts +70 -0
- package/src/blocks/usp/usp-item/constants.ts +7 -0
- package/src/blocks/usp/usp-item/edit.tsx +65 -0
- package/src/blocks/usp/usp-item/editor.scss +17 -0
- package/src/blocks/usp/usp-item/factory.tsx +30 -0
- package/src/blocks/usp/usp-item/index.ts +11 -0
- package/src/blocks/usp/usp-item/types.ts +17 -0
- package/src/components/IconControl/IconControl.tsx +55 -0
- package/src/components/IconControl/editor.scss +53 -0
- package/src/components/IconControl/index.ts +2 -0
- package/src/components/IconControl/index.tsx +1 -0
- package/src/components/ImagePicker/ImagePicker.tsx +124 -0
- package/src/components/ImagePicker/editor.scss +79 -0
- package/src/components/ImagePicker/index.ts +2 -0
- package/src/components/ImagePicker/index.tsx +1 -0
- package/src/components/ItemIconControl/ItemIconControl.tsx +72 -0
- package/src/components/ItemIconControl/ItemIconModal.tsx +12 -0
- package/src/components/ItemIconControl/ItemIconPreview.tsx +93 -0
- package/src/components/ItemIconControl/editor.scss +52 -0
- package/src/components/ItemIconControl/index.ts +2 -0
- package/src/components/ItemIconControl/types.d.ts +30 -0
- package/src/constants.ts +20 -0
- package/src/editor.scss +34 -0
- package/src/globals.scss +237 -0
- package/src/hooks/useGroupBlock.ts +53 -0
- package/src/index.ts +122 -0
- package/src/types.ts +33 -0
- package/src/utils/createEditAdapter.ts +11 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {InspectorControls, RichText, useBlockProps} from '@wordpress/block-editor'
|
|
2
|
+
import {Modal, PanelBody, ToggleControl, TextControl} from '@wordpress/components'
|
|
3
|
+
import {useState} from '@wordpress/element'
|
|
4
|
+
import {__} from '@wordpress/i18n'
|
|
5
|
+
import clsx from 'clsx'
|
|
6
|
+
import {IconControl} from '~/components/IconControl'
|
|
7
|
+
import {ItemIconControl, ItemIconPreview} from '~/components/ItemIconControl'
|
|
8
|
+
import {ICON_TYPES} from './constants'
|
|
9
|
+
import type {UspItemAttributes, UspItemOptions} from './types'
|
|
10
|
+
|
|
11
|
+
export function createUspItemEdit(options: UspItemOptions) {
|
|
12
|
+
return function Edit({
|
|
13
|
+
attributes,
|
|
14
|
+
setAttributes,
|
|
15
|
+
}: {
|
|
16
|
+
attributes: UspItemAttributes
|
|
17
|
+
setAttributes: (a: Partial<UspItemAttributes>) => void
|
|
18
|
+
}) {
|
|
19
|
+
const {title, content, url, icon} = attributes
|
|
20
|
+
|
|
21
|
+
const blockProps = useBlockProps({className: 'i-usp'})
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<InspectorControls>
|
|
26
|
+
<PanelBody title={__('Ikona', 'brilo-blocks')}>
|
|
27
|
+
<ItemIconControl icon={icon} setAttributes={setAttributes} iconTypes={ICON_TYPES} options={options} />
|
|
28
|
+
</PanelBody>
|
|
29
|
+
<PanelBody title={__('Odkaz', 'brilo-blocks')} initialOpen={false}>
|
|
30
|
+
<TextControl label={__('URL', 'brilo-blocks')} value={url.src} onChange={(v) => setAttributes({url: {...url, src: v}})} />
|
|
31
|
+
<ToggleControl
|
|
32
|
+
label={__('Otevřít v nové záložce', 'brilo-blocks')}
|
|
33
|
+
checked={url.blank}
|
|
34
|
+
onChange={(v) => setAttributes({url: {...url, blank: v}})}
|
|
35
|
+
/>
|
|
36
|
+
</PanelBody>
|
|
37
|
+
</InspectorControls>
|
|
38
|
+
|
|
39
|
+
<div {...blockProps}>
|
|
40
|
+
<div className="i-usp__inner wp-block-inner">
|
|
41
|
+
<ItemIconPreview icon={icon} className="i-usp__icon" setAttributes={setAttributes} options={options} />
|
|
42
|
+
|
|
43
|
+
<div className={clsx('i-usp__body', 'grow')}>
|
|
44
|
+
<RichText
|
|
45
|
+
tagName="h3"
|
|
46
|
+
className="i-usp__title u-text-editable"
|
|
47
|
+
value={title}
|
|
48
|
+
onChange={(v) => setAttributes({title: v})}
|
|
49
|
+
placeholder={__('Nadpis...', 'brilo-blocks')}
|
|
50
|
+
allowedFormats={['core/bold', 'core/italic']}
|
|
51
|
+
/>
|
|
52
|
+
<RichText
|
|
53
|
+
tagName="p"
|
|
54
|
+
className="i-usp__content u-text-editable"
|
|
55
|
+
value={content}
|
|
56
|
+
onChange={(v) => setAttributes({content: v})}
|
|
57
|
+
placeholder={__('Popis...', 'brilo-blocks')}
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type {BlockConfiguration} from '@wordpress/blocks'
|
|
2
|
+
import {__} from '@wordpress/i18n'
|
|
3
|
+
import {ICON_TYPES} from './constants'
|
|
4
|
+
import {createUspItemEdit} from './edit'
|
|
5
|
+
import type {UspItemAttributes, UspItemOptions} from './types'
|
|
6
|
+
|
|
7
|
+
export type {UspItemAttributes, UspItemOptions}
|
|
8
|
+
|
|
9
|
+
export function createUspItemBlock(options: UspItemOptions): BlockConfiguration<UspItemAttributes> {
|
|
10
|
+
return {
|
|
11
|
+
name: options.name,
|
|
12
|
+
title: options.title ?? __('USP položka', 'brilo-blocks'),
|
|
13
|
+
description: options.description,
|
|
14
|
+
category: options.category ?? 'layout',
|
|
15
|
+
...(options.parent && {parent: options.parent}),
|
|
16
|
+
icon: options.icon ?? 'star-filled',
|
|
17
|
+
supports: {html: false, customClassName: false},
|
|
18
|
+
attributes: {
|
|
19
|
+
title: {type: 'string', default: ''},
|
|
20
|
+
content: {type: 'string', default: ''},
|
|
21
|
+
url: {type: 'object', default: {src: '', blank: false}},
|
|
22
|
+
icon: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
default: {type: ICON_TYPES[0].value, src: '', media: {id: 0, alt: ''}},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
edit: createUspItemEdit(options),
|
|
28
|
+
save: () => null,
|
|
29
|
+
} as unknown as BlockConfiguration<UspItemAttributes>
|
|
30
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type {UspItemAttributes, UspItemOptions} from './types'
|
|
2
|
+
export {createUspItemBlock} from './factory'
|
|
3
|
+
|
|
4
|
+
import type {UspItemOptions} from './types'
|
|
5
|
+
|
|
6
|
+
export const uspItemDefaults: UspItemOptions = {
|
|
7
|
+
name: 'brilo/usp-item',
|
|
8
|
+
parent: ['brilo/usp-group'],
|
|
9
|
+
icons: [],
|
|
10
|
+
iconsSrc: '',
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {BriloBlockType, Icon} from '~/types'
|
|
2
|
+
import type {IconType} from '~/components/IconControl'
|
|
3
|
+
import type {ICON_TYPES} from './constants'
|
|
4
|
+
|
|
5
|
+
export type UspIconType = (typeof ICON_TYPES)[number]['value']
|
|
6
|
+
|
|
7
|
+
export interface UspItemAttributes extends Record<string, unknown> {
|
|
8
|
+
title: string
|
|
9
|
+
content: string
|
|
10
|
+
url: {src: string; blank: boolean}
|
|
11
|
+
icon: Icon
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface UspItemOptions extends BriloBlockType {
|
|
15
|
+
icons: IconType[]
|
|
16
|
+
iconsSrc: string
|
|
17
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {useState} from '@wordpress/element'
|
|
2
|
+
import {__} from '@wordpress/i18n'
|
|
3
|
+
import clsx from 'clsx'
|
|
4
|
+
|
|
5
|
+
export interface IconType {
|
|
6
|
+
value: string
|
|
7
|
+
label: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface IconControlProps {
|
|
11
|
+
value: string
|
|
12
|
+
label?: string
|
|
13
|
+
icons: IconType[]
|
|
14
|
+
iconsSrc: string
|
|
15
|
+
onChange: (icon: IconType) => void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function IconControl({value, label, icons, iconsSrc, onChange}: IconControlProps) {
|
|
19
|
+
const getIconUrl = (name: string) => (name && name !== 'none' ? `${iconsSrc}${name}.svg` : '')
|
|
20
|
+
const [selectedIcon, setSelectedIcon] = useState<IconType>({
|
|
21
|
+
value,
|
|
22
|
+
label: label ?? '',
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className="icon-control flex column gap-4">
|
|
27
|
+
<div className="icon-control__hero-selected flex gap-4">
|
|
28
|
+
<div className="icon-control__hero-selected-img flex items-center justify-center">
|
|
29
|
+
{selectedIcon.value && <img src={getIconUrl(selectedIcon.value)} alt="" width={24} height={24} loading="lazy" />}
|
|
30
|
+
</div>
|
|
31
|
+
<div className="icon-control__hero-selected-body flex column gap-1">
|
|
32
|
+
<span>{__('Vybraná ikona', 'brilo-blocks')}</span>
|
|
33
|
+
<span className="icon-control__hero-selected-label">{selectedIcon.label}</span>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div className="icon-control__group">
|
|
37
|
+
{icons.map((icon) => (
|
|
38
|
+
<button
|
|
39
|
+
key={icon.value}
|
|
40
|
+
type="button"
|
|
41
|
+
className={clsx('icon-control__item', 'flex', 'column', 'gap-2', 'items-center', 'justify-center', 'cursor-pointer', {
|
|
42
|
+
'--selected': selectedIcon.value === icon.value,
|
|
43
|
+
})}
|
|
44
|
+
onClick={() => {
|
|
45
|
+
onChange(icon)
|
|
46
|
+
setSelectedIcon(icon)
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<img src={getIconUrl(icon.value)} alt="" width={24} height={24} loading="lazy" />
|
|
50
|
+
</button>
|
|
51
|
+
))}
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
@layer base {
|
|
2
|
+
.icon-control__group {
|
|
3
|
+
&.u-grid-responsive {
|
|
4
|
+
--grid-min-col-size: 64px;
|
|
5
|
+
--grid-gap: 2px;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.icon-control__item {
|
|
10
|
+
--border-color: #ddd;
|
|
11
|
+
--background-color: transparent;
|
|
12
|
+
|
|
13
|
+
width: 64px;
|
|
14
|
+
height: 64px;
|
|
15
|
+
border: 1px solid var(--border-color);
|
|
16
|
+
background-color: var(--background-color);
|
|
17
|
+
border-radius: 8px;
|
|
18
|
+
justify-self: center;
|
|
19
|
+
transition: border-color 0.3s ease;
|
|
20
|
+
transition-property: border-color, background-color;
|
|
21
|
+
|
|
22
|
+
img {
|
|
23
|
+
transition: filter 0.3s ease;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&.--selected {
|
|
27
|
+
--border-color: oklch(62.3% 0.214 259.815);
|
|
28
|
+
--background-color: oklch(62.3% 0.214 259.815);
|
|
29
|
+
|
|
30
|
+
img {
|
|
31
|
+
filter: invert(1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.icon-control__hero-selected-img {
|
|
37
|
+
--border-color: #ddd;
|
|
38
|
+
--background-color: transparent;
|
|
39
|
+
|
|
40
|
+
width: 64px;
|
|
41
|
+
height: 64px;
|
|
42
|
+
border: 1px solid var(--border-color);
|
|
43
|
+
background-color: var(--background-color);
|
|
44
|
+
border-radius: 8px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.icon-control__hero-selected {
|
|
48
|
+
padding-block: 8px;
|
|
49
|
+
position: sticky;
|
|
50
|
+
top: 0;
|
|
51
|
+
background-color: #fff;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// re-exported from index.ts — this file intentionally empty
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {MediaUpload, MediaUploadCheck} from '@wordpress/block-editor'
|
|
2
|
+
import {Button, TextControl} from '@wordpress/components'
|
|
3
|
+
import {useSelect} from '@wordpress/data'
|
|
4
|
+
import {__} from '@wordpress/i18n'
|
|
5
|
+
import {CSSProperties} from 'react'
|
|
6
|
+
|
|
7
|
+
export interface ImageValue {
|
|
8
|
+
id: number
|
|
9
|
+
alt: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ImageLabels {
|
|
13
|
+
select?: string
|
|
14
|
+
change?: string
|
|
15
|
+
remove?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ImagePickerProps {
|
|
19
|
+
value: ImageValue
|
|
20
|
+
onChange: (value: ImageValue) => void
|
|
21
|
+
allowedTypes?: string[]
|
|
22
|
+
placeholder?: string
|
|
23
|
+
labels?: ImageLabels
|
|
24
|
+
size?: [number, number]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function useMediaUrl(id: number): string | undefined {
|
|
28
|
+
return useSelect(
|
|
29
|
+
(select) => {
|
|
30
|
+
if (!id) return undefined
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
+
const media = (select('core') as any).getMedia(id)
|
|
33
|
+
return media?.source_url as string | undefined
|
|
34
|
+
},
|
|
35
|
+
[id],
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function useImagePicker(value: ImageValue, onChange: (v: ImageValue) => void, labels?: ImageLabels) {
|
|
40
|
+
const mediaUrl = useMediaUrl(value.id)
|
|
41
|
+
const selectLabel = labels?.select ?? __('Vybrat obrázek', 'brilo-blocks')
|
|
42
|
+
const changeLabel = labels?.change ?? __('Změnit', 'brilo-blocks')
|
|
43
|
+
const removeLabel = labels?.remove ?? __('Odebrat', 'brilo-blocks')
|
|
44
|
+
const handleSelect = (media: {id: number; alt: string}) => onChange({id: media.id, alt: media.alt ?? ''})
|
|
45
|
+
const handleRemove = () => onChange({id: 0, alt: ''})
|
|
46
|
+
return {mediaUrl, selectLabel, changeLabel, removeLabel, handleSelect, handleRemove}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function ImagePickerBody({value, onChange, allowedTypes = ['image'], placeholder, labels}: ImagePickerProps) {
|
|
50
|
+
const {mediaUrl, selectLabel, changeLabel, removeLabel, handleSelect, handleRemove} = useImagePicker(value, onChange, labels)
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<MediaUploadCheck>
|
|
54
|
+
<MediaUpload
|
|
55
|
+
onSelect={handleSelect}
|
|
56
|
+
allowedTypes={allowedTypes}
|
|
57
|
+
value={value.id || 0}
|
|
58
|
+
render={({open}: {open: () => void}) =>
|
|
59
|
+
value.id ? (
|
|
60
|
+
<div className="c-image-picker-body">
|
|
61
|
+
<div className="c-image-picker-body__preview">{mediaUrl && <img src={mediaUrl} alt={value.alt} />}</div>
|
|
62
|
+
<div className="c-image-picker-body__actions">
|
|
63
|
+
<Button onClick={open} variant="secondary">
|
|
64
|
+
{changeLabel}
|
|
65
|
+
</Button>
|
|
66
|
+
<Button onClick={handleRemove} variant="tertiary" isDestructive>
|
|
67
|
+
{removeLabel}
|
|
68
|
+
</Button>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
) : (
|
|
72
|
+
<button type="button" className="c-image-picker-body__placeholder" onClick={open}>
|
|
73
|
+
{placeholder ?? selectLabel}
|
|
74
|
+
</button>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
/>
|
|
78
|
+
</MediaUploadCheck>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function ImagePickerControl({value, onChange, allowedTypes = ['image'], placeholder, labels, size = [48, 48]}: ImagePickerProps) {
|
|
83
|
+
const {mediaUrl, selectLabel, changeLabel, removeLabel, handleSelect, handleRemove} = useImagePicker(value, onChange, labels)
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div
|
|
87
|
+
className="c-image-picker-control"
|
|
88
|
+
style={
|
|
89
|
+
{
|
|
90
|
+
'--image-picker-width': `${size[0]}px`,
|
|
91
|
+
'--image-picker-height': `${size[1]}px`,
|
|
92
|
+
} as CSSProperties
|
|
93
|
+
}
|
|
94
|
+
>
|
|
95
|
+
<MediaUploadCheck>
|
|
96
|
+
<MediaUpload
|
|
97
|
+
onSelect={handleSelect}
|
|
98
|
+
allowedTypes={allowedTypes}
|
|
99
|
+
value={value.id || 0}
|
|
100
|
+
render={({open}: {open: () => void}) => (
|
|
101
|
+
<div className="c-image-picker-control__row">
|
|
102
|
+
{!!value.id && !!mediaUrl && (
|
|
103
|
+
<div className="c-image-picker-control__thumb">
|
|
104
|
+
<img src={mediaUrl} alt={value.alt} />
|
|
105
|
+
</div>
|
|
106
|
+
)}
|
|
107
|
+
<div className="c-image-picker-control__btns">
|
|
108
|
+
<Button onClick={open} variant="secondary" size="small">
|
|
109
|
+
{value.id ? changeLabel : (placeholder ?? selectLabel)}
|
|
110
|
+
</Button>
|
|
111
|
+
{!!value.id && (
|
|
112
|
+
<Button onClick={handleRemove} variant="tertiary" size="small" isDestructive>
|
|
113
|
+
{removeLabel}
|
|
114
|
+
</Button>
|
|
115
|
+
)}
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
)}
|
|
119
|
+
/>
|
|
120
|
+
</MediaUploadCheck>
|
|
121
|
+
{!!value.id && <TextControl label={__('Alt text', 'brilo-blocks')} value={value.alt} onChange={(alt) => onChange({...value, alt})} />}
|
|
122
|
+
</div>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
@layer base {
|
|
2
|
+
.c-image-picker-body {
|
|
3
|
+
width: 100%;
|
|
4
|
+
height: 100%;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.c-image-picker-body__preview {
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 100%;
|
|
12
|
+
|
|
13
|
+
img {
|
|
14
|
+
width: 100%;
|
|
15
|
+
max-height: 100%;
|
|
16
|
+
height: auto;
|
|
17
|
+
display: block;
|
|
18
|
+
border-radius: 2px;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.c-image-picker-body__actions {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-wrap: wrap;
|
|
25
|
+
gap: 8px;
|
|
26
|
+
margin-top: 8px;
|
|
27
|
+
padding: 8px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.c-image-picker-body__placeholder {
|
|
31
|
+
width: 100%;
|
|
32
|
+
min-height: 120px;
|
|
33
|
+
background: #e8ecf1;
|
|
34
|
+
border: 2px dashed #b0bec5;
|
|
35
|
+
border-radius: 4px;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: center;
|
|
40
|
+
font-size: 13px;
|
|
41
|
+
color: #546e7a;
|
|
42
|
+
padding: 16px;
|
|
43
|
+
box-sizing: border-box;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.c-image-picker-control {
|
|
47
|
+
width: 100%;
|
|
48
|
+
margin-bottom: 8px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.c-image-picker-control__row {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: 8px;
|
|
55
|
+
margin-bottom: 8px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.c-image-picker-control__thumb {
|
|
59
|
+
width: var(--image-picker-width, 48px);
|
|
60
|
+
height: var(--image-picker-height, 48px);
|
|
61
|
+
flex-shrink: 0;
|
|
62
|
+
border-radius: 2px;
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
|
|
65
|
+
img {
|
|
66
|
+
width: 100%;
|
|
67
|
+
height: 100%;
|
|
68
|
+
object-fit: cover;
|
|
69
|
+
display: block;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.c-image-picker-control__btns {
|
|
74
|
+
display: flex;
|
|
75
|
+
gap: 4px;
|
|
76
|
+
flex-wrap: wrap;
|
|
77
|
+
align-items: center;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// re-exported from index.ts — this file intentionally empty
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
TextControl,
|
|
4
|
+
__experimentalToggleGroupControl as ToggleGroupControl,
|
|
5
|
+
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
|
|
6
|
+
} from '@wordpress/components'
|
|
7
|
+
import {useState} from '@wordpress/element'
|
|
8
|
+
import {__} from '@wordpress/i18n'
|
|
9
|
+
import {ImagePickerControl} from '~/components/ImagePicker'
|
|
10
|
+
import type {ItemIconControlProps} from './types'
|
|
11
|
+
import {ItemIconModal} from './ItemIconModal'
|
|
12
|
+
|
|
13
|
+
export function ItemIconControl({icon, setAttributes, options, iconTypes}: ItemIconControlProps) {
|
|
14
|
+
const [isModalOpen, setModalOpen] = useState(false)
|
|
15
|
+
const preselectedIconUrl = icon.type === 'preselected' && icon.src ? `${options.iconsSrc}${icon.src}.svg` : ''
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<ToggleGroupControl
|
|
20
|
+
label={__('Typ ikony', 'brilo-blocks')}
|
|
21
|
+
value={icon.type}
|
|
22
|
+
onChange={(v) => setAttributes({icon: {...icon, type: v as string}})}
|
|
23
|
+
isBlock
|
|
24
|
+
>
|
|
25
|
+
{iconTypes.map((t) => (
|
|
26
|
+
<ToggleGroupControlOption key={t.value} value={t.value} label={t.label} />
|
|
27
|
+
))}
|
|
28
|
+
</ToggleGroupControl>
|
|
29
|
+
|
|
30
|
+
{icon.type === 'preselected' && (
|
|
31
|
+
<div className="i-item-icon__control-preselected">
|
|
32
|
+
{preselectedIconUrl && (
|
|
33
|
+
<div className="i-item-icon__preview">
|
|
34
|
+
<img src={preselectedIconUrl} alt="" width={32} height={32} />
|
|
35
|
+
</div>
|
|
36
|
+
)}
|
|
37
|
+
<Button variant="secondary" onClick={() => setModalOpen(true)}>
|
|
38
|
+
{icon.src ? __('Změnit ikonu', 'brilo-blocks') : __('Vybrat ikonu', 'brilo-blocks')}
|
|
39
|
+
</Button>
|
|
40
|
+
</div>
|
|
41
|
+
)}
|
|
42
|
+
|
|
43
|
+
{icon.type === 'media' && (
|
|
44
|
+
<ImagePickerControl
|
|
45
|
+
value={icon.media}
|
|
46
|
+
onChange={(val) => setAttributes({icon: {...icon, media: val}})}
|
|
47
|
+
labels={{
|
|
48
|
+
select: __('Vybrat ikonu', 'brilo-blocks'),
|
|
49
|
+
change: __('Změnit ikonu', 'brilo-blocks'),
|
|
50
|
+
remove: __('Odebrat ikonu', 'brilo-blocks'),
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
)}
|
|
54
|
+
|
|
55
|
+
{icon.type === 'number' && (
|
|
56
|
+
<TextControl label={__('Číslo', 'brilo-blocks')} value={icon.src} onChange={(v) => setAttributes({icon: {...icon, src: v}})} />
|
|
57
|
+
)}
|
|
58
|
+
|
|
59
|
+
{isModalOpen && (
|
|
60
|
+
<ItemIconModal
|
|
61
|
+
icon={icon}
|
|
62
|
+
options={options}
|
|
63
|
+
onClose={() => setModalOpen(false)}
|
|
64
|
+
onChange={(selectedIcon) => {
|
|
65
|
+
setAttributes({icon: {...icon, src: selectedIcon.value}})
|
|
66
|
+
setModalOpen(false)
|
|
67
|
+
}}
|
|
68
|
+
/>
|
|
69
|
+
)}
|
|
70
|
+
</>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {Modal} from '@wordpress/components'
|
|
2
|
+
import {__} from '@wordpress/i18n'
|
|
3
|
+
import {IconControl} from '~/components/IconControl'
|
|
4
|
+
import type {ItemIconModalProps} from './types'
|
|
5
|
+
|
|
6
|
+
export function ItemIconModal({icon, options, onClose, onChange, className = 'i-item-icon__modal'}: ItemIconModalProps) {
|
|
7
|
+
return (
|
|
8
|
+
<Modal title={__('Vybrat ikonu', 'brilo-blocks')} onRequestClose={onClose} size="large" className={className}>
|
|
9
|
+
<IconControl value={icon.src} icons={options.icons} iconsSrc={options.iconsSrc} onChange={onChange} />
|
|
10
|
+
</Modal>
|
|
11
|
+
)
|
|
12
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import clsx from 'clsx'
|
|
2
|
+
import {useState} from '@wordpress/element'
|
|
3
|
+
import {useMediaUrl} from '~/components/ImagePicker'
|
|
4
|
+
import type {ItemIconPreviewProps} from './types'
|
|
5
|
+
import {ItemIconModal} from './ItemIconModal'
|
|
6
|
+
|
|
7
|
+
export function ItemIconPreview({icon, className, options, setAttributes}: ItemIconPreviewProps) {
|
|
8
|
+
const [isModalOpen, setModalOpen] = useState(false)
|
|
9
|
+
const mediaIconUrl = useMediaUrl(icon.media.id)
|
|
10
|
+
const preselectedIconUrl = icon.type === 'preselected' && icon.src ? `${options.iconsSrc}${icon.src}.svg` : ''
|
|
11
|
+
|
|
12
|
+
const renderContent = () => {
|
|
13
|
+
if (icon.type === 'preselected') {
|
|
14
|
+
if (preselectedIconUrl) {
|
|
15
|
+
return (
|
|
16
|
+
<div className={clsx('i-item-icon', className)}>
|
|
17
|
+
<img
|
|
18
|
+
src={preselectedIconUrl}
|
|
19
|
+
alt=""
|
|
20
|
+
className={clsx(className ? `${className}-img` : 'i-item-icon__img')}
|
|
21
|
+
width={40}
|
|
22
|
+
height={40}
|
|
23
|
+
/>
|
|
24
|
+
</div>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
return (
|
|
28
|
+
<button
|
|
29
|
+
type="button"
|
|
30
|
+
className={clsx(
|
|
31
|
+
'i-item-icon',
|
|
32
|
+
className ? `${className}-placeholder` : null,
|
|
33
|
+
'i-item-icon__placeholder',
|
|
34
|
+
!isModalOpen && '--clickable',
|
|
35
|
+
)}
|
|
36
|
+
onClick={() => setModalOpen(true)}
|
|
37
|
+
>
|
|
38
|
+
<span>☆</span>
|
|
39
|
+
</button>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (icon.type === 'media') {
|
|
44
|
+
if (icon.media.id && mediaIconUrl) {
|
|
45
|
+
return (
|
|
46
|
+
<div className={clsx('i-item-icon', className)}>
|
|
47
|
+
<img src={mediaIconUrl} alt={icon.media.alt} className={clsx(className ? `${className}-img` : null, 'i-item-icon__img')} />
|
|
48
|
+
</div>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
return (
|
|
52
|
+
<div className={clsx('i-item-icon', className ? `${className}-placeholder` : 'i-item-icon__placeholder')}>
|
|
53
|
+
<span>☆</span>
|
|
54
|
+
</div>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (icon.type === 'number') {
|
|
59
|
+
if (icon.src) {
|
|
60
|
+
return (
|
|
61
|
+
<div className={clsx('i-item-icon', className)}>
|
|
62
|
+
<span className={clsx(className ? `${className}-number` : 'i-item-icon__number')}>{icon.src}</span>
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
return (
|
|
67
|
+
<div className={clsx('i-item-icon', className ? `${className}-placeholder` : 'i-item-icon__placeholder')}>
|
|
68
|
+
<span>☆</span>
|
|
69
|
+
</div>
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
{renderContent()}
|
|
79
|
+
{isModalOpen && (
|
|
80
|
+
<ItemIconModal
|
|
81
|
+
icon={icon}
|
|
82
|
+
options={options}
|
|
83
|
+
onClose={() => setModalOpen(false)}
|
|
84
|
+
onChange={(selectedIcon) => {
|
|
85
|
+
setAttributes({icon: {...icon, src: selectedIcon.value}})
|
|
86
|
+
setModalOpen(false)
|
|
87
|
+
}}
|
|
88
|
+
className="i-step__icon-modal"
|
|
89
|
+
/>
|
|
90
|
+
)}
|
|
91
|
+
</>
|
|
92
|
+
)
|
|
93
|
+
}
|