@brilo/base-blocks 0.1.46 → 0.1.48
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/.tsbuildinfo +1 -1
- package/build/blocks/contact/contact-group/constants.d.ts +71 -0
- package/build/blocks/contact/contact-group/constants.d.ts.map +1 -1
- package/build/blocks/contact/contact-group/constants.js +35 -0
- package/build/blocks/contact/contact-group/edit.d.ts.map +1 -1
- package/build/blocks/contact/contact-group/edit.js +20 -8
- package/build/blocks/contact/contact-group/factory.d.ts +3 -3
- package/build/blocks/contact/contact-group/factory.d.ts.map +1 -1
- package/build/blocks/contact/contact-group/factory.js +33 -8
- package/build/blocks/contact/contact-group/index.d.ts +2 -2
- package/build/blocks/contact/contact-group/index.d.ts.map +1 -1
- package/build/blocks/contact/contact-group/index.js +1 -1
- package/build/blocks/contact/contact-group/types.d.ts +29 -6
- package/build/blocks/contact/contact-group/types.d.ts.map +1 -1
- package/build/blocks/contact/contact-item/buildPreviewStyle.d.ts +24 -0
- package/build/blocks/contact/contact-item/buildPreviewStyle.d.ts.map +1 -0
- package/build/blocks/contact/contact-item/buildPreviewStyle.js +31 -0
- package/build/blocks/contact/contact-item/edit.d.ts.map +1 -1
- package/build/blocks/contact/contact-item/edit.js +10 -8
- package/build/blocks/contact/contact-item/factory.js +2 -2
- package/build/blocks/sections/base-section/constants.d.ts +1 -0
- package/build/blocks/sections/base-section/constants.d.ts.map +1 -1
- package/build/blocks/sections/base-section/constants.js +1 -0
- package/build/blocks/sections/base-section/controls.d.ts.map +1 -1
- package/build/blocks/sections/base-section/controls.js +4 -3
- package/build/blocks/sections/base-section/edit.d.ts.map +1 -1
- package/build/blocks/sections/base-section/edit.js +23 -24
- package/build/blocks/sections/base-section/types.d.ts +1 -0
- package/build/blocks/sections/base-section/types.d.ts.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/package.json +1 -1
- package/src/blocks/contact/contact-group/constants.ts +42 -0
- package/src/blocks/contact/contact-group/edit.tsx +177 -20
- package/src/blocks/contact/contact-group/editor.scss +19 -0
- package/src/blocks/contact/contact-group/factory.tsx +61 -8
- package/src/blocks/contact/contact-group/index.ts +10 -2
- package/src/blocks/contact/contact-group/types.ts +48 -6
- package/src/blocks/contact/contact-item/buildPreviewStyle.ts +69 -0
- package/src/blocks/contact/contact-item/edit.tsx +17 -30
- package/src/blocks/contact/contact-item/editor.scss +136 -7
- package/src/blocks/contact/contact-item/factory.tsx +2 -2
- package/src/blocks/sections/base-section/constants.ts +2 -0
- package/src/blocks/sections/base-section/controls.tsx +10 -0
- package/src/blocks/sections/base-section/edit.tsx +24 -22
- package/src/blocks/sections/base-section/types.ts +1 -0
- package/src/index.ts +5 -0
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type {
|
|
2
|
+
ContactColumns,
|
|
3
|
+
ContactDirection,
|
|
4
|
+
ContactGroupAttributes,
|
|
5
|
+
ContactGroupOptions,
|
|
6
|
+
ContactIconBackgroundShape,
|
|
7
|
+
ContactShadow,
|
|
8
|
+
ContactTextAlign,
|
|
9
|
+
} from './types'
|
|
2
10
|
export {createContactGroupBlock} from './factory'
|
|
3
|
-
export {CONTACT_COLUMNS, CONTACT_COLUMNS_CONTEXT} from './constants'
|
|
11
|
+
export {CONTACT_COLUMNS, CONTACT_COLUMNS_CONTEXT, CONTACT_STYLE_CONTEXT} from './constants'
|
|
4
12
|
|
|
5
13
|
import type {ContactGroupOptions} from './types'
|
|
6
14
|
|
|
@@ -1,23 +1,65 @@
|
|
|
1
|
-
import type {BriloBlockType, NumberArray} from '~/types'
|
|
2
|
-
import type {
|
|
1
|
+
import type {BriloBlockType, NumberArray, OptionArray} from '~/types'
|
|
2
|
+
import type {
|
|
3
|
+
CONTACT_COLUMNS,
|
|
4
|
+
DEFAULT_DIRECTIONS,
|
|
5
|
+
DEFAULT_ICON_BACKGROUND_SHAPES,
|
|
6
|
+
DEFAULT_SHADOWS,
|
|
7
|
+
TEXT_ALIGNS,
|
|
8
|
+
} from './constants'
|
|
3
9
|
|
|
4
10
|
export type ContactColumns = (typeof CONTACT_COLUMNS)[number]
|
|
5
11
|
|
|
6
12
|
export type ContactShadow = (typeof DEFAULT_SHADOWS)[number]['value']
|
|
7
13
|
|
|
14
|
+
export type ContactDirection = (typeof DEFAULT_DIRECTIONS)[number]['value']
|
|
15
|
+
|
|
8
16
|
export type ContactTextAlign = (typeof TEXT_ALIGNS)[number]['value']
|
|
9
17
|
|
|
10
|
-
export
|
|
18
|
+
export type ContactIconBackgroundShape = (typeof DEFAULT_ICON_BACKGROUND_SHAPES)[number]['value']
|
|
19
|
+
|
|
20
|
+
export interface ContactSizePreset {
|
|
21
|
+
value: number
|
|
22
|
+
label: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface ContactGroupAttributes<
|
|
26
|
+
TColumns extends number = ContactColumns,
|
|
27
|
+
TDirection extends string = ContactDirection,
|
|
28
|
+
TShadow extends string = ContactShadow,
|
|
29
|
+
TIconBackgroundShape extends string = ContactIconBackgroundShape,
|
|
30
|
+
> extends Record<string, unknown> {
|
|
11
31
|
columns: TColumns
|
|
32
|
+
groupBackgroundColor: string
|
|
12
33
|
style: {
|
|
13
|
-
shadow:
|
|
34
|
+
shadow: TShadow
|
|
35
|
+
direction: TDirection
|
|
36
|
+
textAlign: ContactTextAlign
|
|
14
37
|
borderColor: string
|
|
15
38
|
backgroundColor: string
|
|
16
39
|
textColor: string
|
|
17
|
-
|
|
40
|
+
icon: {
|
|
41
|
+
size: number
|
|
42
|
+
color: string
|
|
43
|
+
background: string
|
|
44
|
+
backgroundSize: number
|
|
45
|
+
backgroundShape: TIconBackgroundShape
|
|
46
|
+
borderColor: string
|
|
47
|
+
borderWidth: number
|
|
48
|
+
}
|
|
18
49
|
}
|
|
50
|
+
spacing?: number
|
|
19
51
|
}
|
|
20
52
|
|
|
21
|
-
export interface ContactGroupOptions<
|
|
53
|
+
export interface ContactGroupOptions<
|
|
54
|
+
TColumns extends NumberArray = typeof CONTACT_COLUMNS,
|
|
55
|
+
TDirections extends OptionArray = typeof DEFAULT_DIRECTIONS,
|
|
56
|
+
TShadows extends OptionArray = typeof DEFAULT_SHADOWS,
|
|
57
|
+
TIconBackgroundShapes extends OptionArray = typeof DEFAULT_ICON_BACKGROUND_SHAPES,
|
|
58
|
+
> extends BriloBlockType {
|
|
22
59
|
columns?: TColumns
|
|
60
|
+
directions?: TDirections
|
|
61
|
+
shadows?: TShadows
|
|
62
|
+
iconSizePresets?: readonly ContactSizePreset[]
|
|
63
|
+
iconBackgroundSizePresets?: readonly ContactSizePreset[]
|
|
64
|
+
iconBackgroundShapes?: TIconBackgroundShapes
|
|
23
65
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import clsx from 'clsx'
|
|
2
|
+
|
|
3
|
+
export interface ContactSharedStyle {
|
|
4
|
+
direction?: string
|
|
5
|
+
textAlign?: string
|
|
6
|
+
shadow?: string
|
|
7
|
+
borderColor?: string
|
|
8
|
+
backgroundColor?: string
|
|
9
|
+
textColor?: string
|
|
10
|
+
icon?: {
|
|
11
|
+
size?: number
|
|
12
|
+
color?: string
|
|
13
|
+
background?: string
|
|
14
|
+
backgroundSize?: number
|
|
15
|
+
backgroundShape?: string
|
|
16
|
+
borderColor?: string
|
|
17
|
+
borderWidth?: number
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ContactPreviewStyle {
|
|
22
|
+
rootClassName: string
|
|
23
|
+
iconClassName: string
|
|
24
|
+
cssVars: Record<string, string>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function buildContactPreviewStyle(
|
|
28
|
+
shared?: ContactSharedStyle,
|
|
29
|
+
resolveHex: (value: string) => string = (value) => value,
|
|
30
|
+
): ContactPreviewStyle {
|
|
31
|
+
if (!shared) {
|
|
32
|
+
return {rootClassName: '', iconClassName: '', cssVars: {}}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const icon = shared.icon ?? {}
|
|
36
|
+
|
|
37
|
+
const rootClassName = clsx(
|
|
38
|
+
shared.direction && `--direction-${shared.direction}`,
|
|
39
|
+
shared.textAlign && `--align-${shared.textAlign}`,
|
|
40
|
+
shared.shadow && shared.shadow !== 'none' && `--shadow --shadow-${shared.shadow}`,
|
|
41
|
+
icon.background && icon.background !== 'none' && '--icon-background',
|
|
42
|
+
icon.color && icon.color !== 'none' && '--icon-color',
|
|
43
|
+
icon.borderColor && '--icon-bordered',
|
|
44
|
+
shared.backgroundColor && '--background-color',
|
|
45
|
+
shared.borderColor && '--border',
|
|
46
|
+
shared.textColor && '--text-color',
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
const iconClassName = clsx(
|
|
50
|
+
icon.backgroundShape && icon.backgroundShape !== 'none' && `--background-shape --background-shape-${icon.backgroundShape}`,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
const cssVars: Record<string, string> = {}
|
|
54
|
+
if (shared.borderColor) cssVars['--border-color'] = resolveHex(shared.borderColor)
|
|
55
|
+
if (shared.backgroundColor) cssVars['--background-color'] = resolveHex(shared.backgroundColor)
|
|
56
|
+
if (shared.textColor) cssVars['--text-color'] = resolveHex(shared.textColor)
|
|
57
|
+
if (icon.background && icon.background !== 'none') cssVars['--icon-background-color'] = resolveHex(icon.background)
|
|
58
|
+
if (icon.color && icon.color !== 'none') cssVars['--icon-color'] = resolveHex(icon.color)
|
|
59
|
+
if (icon.size) cssVars['--icon-size'] = `${icon.size}px`
|
|
60
|
+
if (icon.background && icon.background !== 'none' && icon.backgroundSize) {
|
|
61
|
+
cssVars['--icon-background-size'] = `${icon.backgroundSize}px`
|
|
62
|
+
}
|
|
63
|
+
if (icon.borderColor) {
|
|
64
|
+
cssVars['--icon-outline-color'] = resolveHex(icon.borderColor)
|
|
65
|
+
cssVars['--icon-outline-width'] = `${icon.borderWidth || 1}px`
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return {rootClassName, iconClassName, cssVars}
|
|
69
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {InspectorControls} from '@wordpress/block-editor'
|
|
2
2
|
import {
|
|
3
3
|
PanelBody,
|
|
4
|
-
RangeControl,
|
|
5
4
|
__experimentalToggleGroupControl as ToggleGroupControl,
|
|
6
5
|
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
|
|
7
6
|
} from '@wordpress/components'
|
|
@@ -10,9 +9,11 @@ import clsx from 'clsx'
|
|
|
10
9
|
import type {CSSProperties} from 'react'
|
|
11
10
|
import {ItemIconControl, ItemIconPreview} from '~/components/ItemIconControl'
|
|
12
11
|
import {useGroupBlock} from '~/hooks/useGroupBlock'
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
12
|
+
import {useTenantColorPalette} from '~/hooks/useTenantColorPalette'
|
|
13
|
+
import {CONTACT_COLUMNS_CONTEXT, CONTACT_STYLE_CONTEXT} from '../contact-group/constants'
|
|
14
|
+
import {buildContactPreviewStyle, type ContactSharedStyle} from './buildPreviewStyle'
|
|
15
|
+
import {CONTACT_ICON_TYPES} from './constants'
|
|
16
|
+
import type {ContactItemAttributes, ContactItemOptions} from './types'
|
|
16
17
|
|
|
17
18
|
export function createContactItemEdit(options: ContactItemOptions) {
|
|
18
19
|
const iconOptions = {icons: options.icons ?? [], iconsSrc: options.iconsSrc ?? ''}
|
|
@@ -26,16 +27,18 @@ export function createContactItemEdit(options: ContactItemOptions) {
|
|
|
26
27
|
setAttributes: (a: Partial<ContactItemAttributes>) => void
|
|
27
28
|
context: Record<string, unknown>
|
|
28
29
|
}) {
|
|
29
|
-
const {colSpan, icon
|
|
30
|
+
const {colSpan, icon} = attributes
|
|
30
31
|
const columns = Number(context[CONTACT_COLUMNS_CONTEXT] ?? 3)
|
|
31
32
|
const span = Math.min(colSpan, columns)
|
|
32
33
|
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
34
|
+
const {resolveHex} = useTenantColorPalette()
|
|
35
|
+
const {rootClassName, iconClassName, cssVars} = buildContactPreviewStyle(
|
|
36
|
+
context[CONTACT_STYLE_CONTEXT] as ContactSharedStyle | undefined,
|
|
37
|
+
resolveHex,
|
|
38
|
+
)
|
|
36
39
|
|
|
37
40
|
const {blockProps, innerBlocksProps} = useGroupBlock({
|
|
38
|
-
blockClassName: clsx(options.blockClassName ?? 'i-contact'),
|
|
41
|
+
blockClassName: clsx(options.blockClassName ?? 'i-contact', rootClassName),
|
|
39
42
|
containerClassName: [options.containerClassName ?? 'i-contact__inner'],
|
|
40
43
|
allowedBlocks: options.allowedBlocks,
|
|
41
44
|
template: options.template,
|
|
@@ -60,29 +63,13 @@ export function createContactItemEdit(options: ContactItemOptions) {
|
|
|
60
63
|
</PanelBody>
|
|
61
64
|
<PanelBody title={__('Ikona', 'brilo-blocks')}>
|
|
62
65
|
<ItemIconControl icon={icon} setAttributes={setAttributes} iconTypes={CONTACT_ICON_TYPES} options={iconOptions} />
|
|
63
|
-
<ToggleGroupControl
|
|
64
|
-
isBlock
|
|
65
|
-
label={__('Velikost ikony', 'brilo-blocks')}
|
|
66
|
-
value={iconSize.variant}
|
|
67
|
-
onChange={(v) => setAttributes({iconSize: {...iconSize, variant: v as ContactIconSizeVariant}})}
|
|
68
|
-
>
|
|
69
|
-
{CONTACT_ICON_SIZES.map((s) => (
|
|
70
|
-
<ToggleGroupControlOption key={s.value} value={s.value} label={s.label} />
|
|
71
|
-
))}
|
|
72
|
-
</ToggleGroupControl>
|
|
73
|
-
{iconSize.variant === 'custom' && (
|
|
74
|
-
<RangeControl
|
|
75
|
-
label={__('Vlastní velikost (px)', 'brilo-blocks')}
|
|
76
|
-
value={iconSize.custom}
|
|
77
|
-
min={CONTACT_ICON_SIZE_RANGE.min}
|
|
78
|
-
max={CONTACT_ICON_SIZE_RANGE.max}
|
|
79
|
-
onChange={(v) => setAttributes({iconSize: {...iconSize, custom: v ?? CONTACT_ICON_SIZE_RANGE.min}})}
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
82
66
|
</PanelBody>
|
|
83
67
|
</InspectorControls>
|
|
84
|
-
<div
|
|
85
|
-
|
|
68
|
+
<div
|
|
69
|
+
{...blockProps}
|
|
70
|
+
style={{...(blockProps.style as CSSProperties), ...cssVars, '--col-span': span} as CSSProperties}
|
|
71
|
+
>
|
|
72
|
+
<div className={clsx('i-contact__icon-wrap', iconClassName)}>
|
|
86
73
|
<ItemIconPreview icon={icon} className="i-contact__icon" setAttributes={setAttributes} options={iconOptions} />
|
|
87
74
|
</div>
|
|
88
75
|
<div {...innerBlocksProps} />
|
|
@@ -9,18 +9,67 @@
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.i-contact {
|
|
12
|
+
--icon-background-size: 0px;
|
|
13
|
+
|
|
12
14
|
grid-column: span var(--col-span, 1);
|
|
13
15
|
margin-inline: 0;
|
|
14
16
|
width: 100%;
|
|
15
17
|
box-sizing: border-box;
|
|
16
|
-
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: 8px;
|
|
17
21
|
padding: 8px;
|
|
22
|
+
border-radius: 4px;
|
|
23
|
+
align-items: var(--align-items, flex-start);
|
|
24
|
+
text-align: var(--text-align, left);
|
|
25
|
+
|
|
26
|
+
&.--direction-horizontal {
|
|
27
|
+
flex-direction: row;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&.--align-left {
|
|
31
|
+
--align-items: flex-start;
|
|
32
|
+
--text-align: left;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&.--align-center {
|
|
36
|
+
--align-items: center;
|
|
37
|
+
--text-align: center;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Background size only reserves space when a background or outline is actually selected.
|
|
41
|
+
&.--icon-background,
|
|
42
|
+
&.--icon-bordered {
|
|
43
|
+
--icon-background-size: 88px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&.--shadow {
|
|
47
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&.--shadow-md {
|
|
51
|
+
box-shadow: 0 4px 14px rgba(0, 0, 0, 0.14);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.--border {
|
|
55
|
+
border: 1px solid var(--border-color, transparent);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&.--background-color {
|
|
59
|
+
background-color: var(--background-color, transparent);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&.--text-color {
|
|
63
|
+
color: var(--text-color);
|
|
64
|
+
}
|
|
18
65
|
|
|
19
66
|
.i-contact__inner {
|
|
20
67
|
display: flex;
|
|
21
68
|
flex-direction: column;
|
|
22
69
|
gap: 8px;
|
|
23
|
-
|
|
70
|
+
flex: 1;
|
|
71
|
+
min-width: 0;
|
|
72
|
+
text-align: inherit;
|
|
24
73
|
|
|
25
74
|
p,
|
|
26
75
|
h3,
|
|
@@ -29,14 +78,94 @@
|
|
|
29
78
|
margin-block: 4px;
|
|
30
79
|
}
|
|
31
80
|
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.i-contact__icon-wrap {
|
|
84
|
+
--icon-box-size: max(var(--icon-background-size, 0px), var(--icon-size, 88px));
|
|
85
|
+
|
|
86
|
+
width: var(--icon-box-size);
|
|
87
|
+
height: var(--icon-box-size);
|
|
88
|
+
flex: 0 0 var(--icon-box-size);
|
|
89
|
+
display: grid;
|
|
90
|
+
grid-template-areas: "pile";
|
|
91
|
+
place-items: center;
|
|
92
|
+
isolation: isolate;
|
|
93
|
+
|
|
94
|
+
&::before,
|
|
95
|
+
&::after {
|
|
96
|
+
content: "";
|
|
97
|
+
grid-area: pile;
|
|
98
|
+
width: var(--icon-background-size, 0px);
|
|
99
|
+
height: var(--icon-background-size, 0px);
|
|
100
|
+
border-radius: inherit;
|
|
101
|
+
clip-path: var(--icon-background-shape, none);
|
|
102
|
+
}
|
|
32
103
|
|
|
33
|
-
|
|
34
|
-
|
|
104
|
+
&::before {
|
|
105
|
+
z-index: 0;
|
|
106
|
+
background-color: var(--icon-outline-color, transparent);
|
|
35
107
|
}
|
|
36
108
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
109
|
+
&::after {
|
|
110
|
+
z-index: 1;
|
|
111
|
+
width: calc(var(--icon-background-size, 0px) - var(--icon-outline-width, 0px) * 2);
|
|
112
|
+
height: calc(var(--icon-background-size, 0px) - var(--icon-outline-width, 0px) * 2);
|
|
113
|
+
background-color: var(--icon-background-color, transparent);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.i-contact__icon,
|
|
117
|
+
img,
|
|
118
|
+
svg {
|
|
119
|
+
grid-area: pile;
|
|
120
|
+
position: relative;
|
|
121
|
+
z-index: 2;
|
|
122
|
+
width: var(--icon-size, 88px);
|
|
123
|
+
height: var(--icon-size, 88px);
|
|
40
124
|
object-fit: contain;
|
|
41
125
|
}
|
|
126
|
+
|
|
127
|
+
svg path {
|
|
128
|
+
fill: var(--icon-color, currentcolor);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&.--background-shape-circle {
|
|
132
|
+
--icon-background-shape: circle(50% at 50% 50%);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
&.--background-shape-triangle {
|
|
136
|
+
--icon-background-shape: polygon(50% 0%, 0% 100%, 100% 100%);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&.--background-shape-rhombus {
|
|
140
|
+
--icon-background-shape: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
&.--background-shape-octagon {
|
|
144
|
+
--icon-background-shape: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
&.--background-shape-bevel {
|
|
148
|
+
--icon-background-shape: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&.--background-shape-rabbet {
|
|
152
|
+
--icon-background-shape: polygon(
|
|
153
|
+
0% 15%,
|
|
154
|
+
15% 15%,
|
|
155
|
+
15% 0%,
|
|
156
|
+
85% 0%,
|
|
157
|
+
85% 15%,
|
|
158
|
+
100% 15%,
|
|
159
|
+
100% 85%,
|
|
160
|
+
85% 85%,
|
|
161
|
+
85% 100%,
|
|
162
|
+
15% 100%,
|
|
163
|
+
15% 85%,
|
|
164
|
+
0% 85%
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&.--background-shape-parallelogram {
|
|
169
|
+
--icon-background-shape: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%);
|
|
170
|
+
}
|
|
42
171
|
}
|
|
@@ -3,7 +3,7 @@ import type {BlockConfiguration, BlockEditProps} from '@wordpress/blocks'
|
|
|
3
3
|
import {__} from '@wordpress/i18n'
|
|
4
4
|
import type {Icon} from '~/types'
|
|
5
5
|
import type {IconType} from '~/components/IconControl/IconControl'
|
|
6
|
-
import {CONTACT_COLUMNS_CONTEXT} from '../contact-group/constants'
|
|
6
|
+
import {CONTACT_COLUMNS_CONTEXT, CONTACT_STYLE_CONTEXT} from '../contact-group/constants'
|
|
7
7
|
import {CONTACT_ICON_SIZE_DEFAULT, CONTACT_ICON_TYPES} from './constants'
|
|
8
8
|
import type {ContactItemAttributes, ContactItemOptions} from './types'
|
|
9
9
|
|
|
@@ -24,7 +24,7 @@ export function createContactItemBlock<T extends ContactItemAttributes = Contact
|
|
|
24
24
|
...(options.parent && {parent: options.parent}),
|
|
25
25
|
icon: options.icon ?? 'id-alt',
|
|
26
26
|
supports: {html: false, customClassName: false},
|
|
27
|
-
usesContext: [CONTACT_COLUMNS_CONTEXT],
|
|
27
|
+
usesContext: [CONTACT_COLUMNS_CONTEXT, CONTACT_STYLE_CONTEXT],
|
|
28
28
|
attributes: {
|
|
29
29
|
...(options.attributes as any),
|
|
30
30
|
colSpan: {type: 'number', default: 1},
|
|
@@ -33,6 +33,7 @@ import type {
|
|
|
33
33
|
} from './types'
|
|
34
34
|
import {
|
|
35
35
|
BACKGROUND_IMAGE_FITS,
|
|
36
|
+
BACKGROUND_IMAGE_OPACITY_DEFAULT,
|
|
36
37
|
BACKGROUND_IMAGE_OVERLAY_OPACITY_DEFAULT,
|
|
37
38
|
BACKGROUND_IMAGE_POSITIONS,
|
|
38
39
|
BACKGROUND_IMAGE_REPEATS,
|
|
@@ -295,6 +296,7 @@ function BackgroundImageControl({value, onChange}: BackgroundImageControlProps)
|
|
|
295
296
|
const repeat = value?.repeat ?? 'no-repeat'
|
|
296
297
|
const overlayColor = value?.overlay?.color
|
|
297
298
|
const overlayOpacity = value?.overlay?.opacity ?? BACKGROUND_IMAGE_OVERLAY_OPACITY_DEFAULT
|
|
299
|
+
const opacity = value?.opacity ?? BACKGROUND_IMAGE_OPACITY_DEFAULT
|
|
298
300
|
|
|
299
301
|
const update = (patch: Partial<BackgroundImage>) =>
|
|
300
302
|
onChange(mergeUpdate({img, fit, position, repeat, overlay: value?.overlay}, value, patch))
|
|
@@ -365,6 +367,14 @@ function BackgroundImageControl({value, onChange}: BackgroundImageControlProps)
|
|
|
365
367
|
onChange={(next) => update({repeat: next as BackgroundImageRepeat})}
|
|
366
368
|
/>
|
|
367
369
|
|
|
370
|
+
<RangeControl
|
|
371
|
+
label={__('Průhlednost obrázku', 'brilo-blocks')}
|
|
372
|
+
value={opacity}
|
|
373
|
+
min={0}
|
|
374
|
+
max={100}
|
|
375
|
+
onChange={(next) => update({opacity: next ?? BACKGROUND_IMAGE_OPACITY_DEFAULT})}
|
|
376
|
+
/>
|
|
377
|
+
|
|
368
378
|
<BaseControl
|
|
369
379
|
label={__('Překryv barvou', 'brilo-blocks')}
|
|
370
380
|
help={__('Ztmavení/zabarvení obrázku pro lepší čitelnost textu.', 'brilo-blocks')}
|
|
@@ -3,7 +3,7 @@ import type {BlockEditProps} from '@wordpress/blocks'
|
|
|
3
3
|
import type {CSSProperties} from 'react'
|
|
4
4
|
import type {BaseBlockAttributes, BaseSectionOptions} from './types'
|
|
5
5
|
import {BaseControls} from './controls'
|
|
6
|
-
import {BACKGROUND_IMAGE_SIZE_VALUE_DEFAULT} from './constants'
|
|
6
|
+
import {BACKGROUND_IMAGE_OPACITY_DEFAULT, BACKGROUND_IMAGE_SIZE_VALUE_DEFAULT} from './constants'
|
|
7
7
|
|
|
8
8
|
export function createBaseSectionEdit<TExtra extends Record<string, unknown> = Record<string, never>>(options: BaseSectionOptions<TExtra>) {
|
|
9
9
|
const EXCLUDE = options.exclude ?? []
|
|
@@ -12,9 +12,9 @@ export function createBaseSectionEdit<TExtra extends Record<string, unknown> = R
|
|
|
12
12
|
const {attributes, setAttributes} = props
|
|
13
13
|
const {background, textColor, gradient, backgroundImage} = attributes as BaseBlockAttributes & {gradient?: string}
|
|
14
14
|
const bgImageSrc = backgroundImage?.img?.src
|
|
15
|
-
// A plain background-color/gradient always paints behind an image, so it can never tint it.
|
|
16
|
-
//
|
|
17
|
-
//
|
|
15
|
+
// A plain background-color/gradient always paints behind an image, so it can never tint it.
|
|
16
|
+
// To preview it sitting on top of the image (matching frontend), it renders as its own
|
|
17
|
+
// absolutely-positioned layer, separate from the image layer below it and the content above.
|
|
18
18
|
const tintLayer = background ? `linear-gradient(${background}, ${background})` : gradient
|
|
19
19
|
const blockProps = useBlockProps({
|
|
20
20
|
className: options.blockClassName,
|
|
@@ -23,26 +23,26 @@ export function createBaseSectionEdit<TExtra extends Record<string, unknown> = R
|
|
|
23
23
|
...(background && !bgImageSrc ? {backgroundColor: background, padding: '16px'} : {}),
|
|
24
24
|
...(gradient && !bgImageSrc ? {background: gradient, padding: '16px'} : {}),
|
|
25
25
|
...(textColor ? {color: textColor} : {}),
|
|
26
|
-
...(bgImageSrc
|
|
27
|
-
? {
|
|
28
|
-
backgroundImage: [tintLayer, `url(${bgImageSrc})`].filter(Boolean).join(', '),
|
|
29
|
-
backgroundSize: [
|
|
30
|
-
tintLayer ? '100% 100%' : null,
|
|
31
|
-
backgroundImage?.fit === 'custom'
|
|
32
|
-
? (backgroundImage?.sizeValue ?? BACKGROUND_IMAGE_SIZE_VALUE_DEFAULT)
|
|
33
|
-
: (backgroundImage?.fit ?? 'cover'),
|
|
34
|
-
]
|
|
35
|
-
.filter(Boolean)
|
|
36
|
-
.join(', '),
|
|
37
|
-
backgroundPosition: [tintLayer ? 'center center' : null, backgroundImage?.position ?? 'center center']
|
|
38
|
-
.filter(Boolean)
|
|
39
|
-
.join(', '),
|
|
40
|
-
backgroundRepeat: [tintLayer ? 'no-repeat' : null, backgroundImage?.repeat ?? 'no-repeat'].filter(Boolean).join(', '),
|
|
41
|
-
padding: '16px',
|
|
42
|
-
}
|
|
43
|
-
: {}),
|
|
26
|
+
...(bgImageSrc ? {padding: '16px'} : {}),
|
|
44
27
|
},
|
|
45
28
|
})
|
|
29
|
+
// Opacity applies to the image alone — it must live on its own layer, not on blockProps,
|
|
30
|
+
// or it would fade the section's inner content (headings, buttons, ...) along with it.
|
|
31
|
+
const bgImageLayerStyle: CSSProperties = bgImageSrc
|
|
32
|
+
? {
|
|
33
|
+
position: 'absolute',
|
|
34
|
+
inset: 0,
|
|
35
|
+
backgroundImage: `url(${bgImageSrc})`,
|
|
36
|
+
backgroundSize:
|
|
37
|
+
backgroundImage?.fit === 'custom'
|
|
38
|
+
? (backgroundImage?.sizeValue ?? BACKGROUND_IMAGE_SIZE_VALUE_DEFAULT)
|
|
39
|
+
: (backgroundImage?.fit ?? 'cover'),
|
|
40
|
+
backgroundPosition: backgroundImage?.position ?? 'center center',
|
|
41
|
+
backgroundRepeat: backgroundImage?.repeat ?? 'no-repeat',
|
|
42
|
+
opacity: (backgroundImage?.opacity ?? BACKGROUND_IMAGE_OPACITY_DEFAULT) / 100,
|
|
43
|
+
}
|
|
44
|
+
: {}
|
|
45
|
+
const tintLayerStyle: CSSProperties = tintLayer ? {position: 'absolute', inset: 0, background: tintLayer} : {}
|
|
46
46
|
const innerBlocksProps = useInnerBlocksProps({className: options.containerClassName}, {
|
|
47
47
|
allowedBlocks: options.allowedBlocks,
|
|
48
48
|
orientation: 'vertical',
|
|
@@ -60,6 +60,8 @@ export function createBaseSectionEdit<TExtra extends Record<string, unknown> = R
|
|
|
60
60
|
{options.extraControls?.(props)}
|
|
61
61
|
</InspectorControls>
|
|
62
62
|
<div {...blockProps}>
|
|
63
|
+
{!!bgImageSrc && <div style={bgImageLayerStyle} />}
|
|
64
|
+
{!!bgImageSrc && !!tintLayer && <div style={tintLayerStyle} />}
|
|
63
65
|
<div {...innerBlocksProps} />
|
|
64
66
|
</div>
|
|
65
67
|
</>
|
package/src/index.ts
CHANGED
|
@@ -11,12 +11,17 @@ export {
|
|
|
11
11
|
} from './blocks/anchor/anchor-item'
|
|
12
12
|
export type {
|
|
13
13
|
ContactColumns,
|
|
14
|
+
ContactDirection,
|
|
14
15
|
ContactGroupAttributes,
|
|
15
16
|
ContactGroupOptions,
|
|
17
|
+
ContactIconBackgroundShape,
|
|
18
|
+
ContactShadow,
|
|
19
|
+
ContactTextAlign,
|
|
16
20
|
} from './blocks/contact/contact-group'
|
|
17
21
|
export {
|
|
18
22
|
CONTACT_COLUMNS,
|
|
19
23
|
CONTACT_COLUMNS_CONTEXT,
|
|
24
|
+
CONTACT_STYLE_CONTEXT,
|
|
20
25
|
contactGroupDefaults,
|
|
21
26
|
createContactGroupBlock,
|
|
22
27
|
} from './blocks/contact/contact-group'
|