@brilo/base-blocks 0.1.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.
Files changed (254) hide show
  1. package/.editorconfig +12 -0
  2. package/.prettierrc +8 -0
  3. package/README.md +59 -0
  4. package/USAGE.md +263 -0
  5. package/biome.json +38 -0
  6. package/bun.lock +1392 -0
  7. package/docs/block-anatomy.md +73 -0
  8. package/docs/conventions.md +204 -0
  9. package/docs/new-block.md +179 -0
  10. package/package.json +41 -0
  11. package/src/blocks/column/column-group/edit.tsx +56 -0
  12. package/src/blocks/column/column-group/editor.scss +7 -0
  13. package/src/blocks/column/column-group/factory.tsx +29 -0
  14. package/src/blocks/column/column-group/index.ts +14 -0
  15. package/src/blocks/column/column-group/types.ts +8 -0
  16. package/src/blocks/column/column-item/constants.ts +1 -0
  17. package/src/blocks/column/column-item/edit.tsx +48 -0
  18. package/src/blocks/column/column-item/editor.scss +34 -0
  19. package/src/blocks/column/column-item/factory.tsx +25 -0
  20. package/src/blocks/column/column-item/index.ts +10 -0
  21. package/src/blocks/column/column-item/types.ts +7 -0
  22. package/src/blocks/compare/compare-group/constants.ts +1 -0
  23. package/src/blocks/compare/compare-group/edit.tsx +52 -0
  24. package/src/blocks/compare/compare-group/factory.tsx +29 -0
  25. package/src/blocks/compare/compare-group/icon.tsx +7 -0
  26. package/src/blocks/compare/compare-group/index.ts +13 -0
  27. package/src/blocks/compare/compare-group/types.ts +12 -0
  28. package/src/blocks/compare/compare-item/edit.tsx +38 -0
  29. package/src/blocks/compare/compare-item/editor.scss +15 -0
  30. package/src/blocks/compare/compare-item/factory.tsx +28 -0
  31. package/src/blocks/compare/compare-item/icon.tsx +9 -0
  32. package/src/blocks/compare/compare-item/index.ts +13 -0
  33. package/src/blocks/compare/compare-item/types.ts +9 -0
  34. package/src/blocks/compare/compare-option/constants.ts +7 -0
  35. package/src/blocks/compare/compare-option/edit.tsx +64 -0
  36. package/src/blocks/compare/compare-option/editor.scss +26 -0
  37. package/src/blocks/compare/compare-option/factory.tsx +35 -0
  38. package/src/blocks/compare/compare-option/icon.tsx +7 -0
  39. package/src/blocks/compare/compare-option/index.ts +8 -0
  40. package/src/blocks/compare/compare-option/types.ts +12 -0
  41. package/src/blocks/contact/contact-group/constants.ts +3 -0
  42. package/src/blocks/contact/contact-group/edit.tsx +57 -0
  43. package/src/blocks/contact/contact-group/editor.scss +20 -0
  44. package/src/blocks/contact/contact-group/factory.tsx +35 -0
  45. package/src/blocks/contact/contact-group/index.ts +12 -0
  46. package/src/blocks/contact/contact-group/types.ts +12 -0
  47. package/src/blocks/contact/contact-item/constants.ts +17 -0
  48. package/src/blocks/contact/contact-item/edit.tsx +93 -0
  49. package/src/blocks/contact/contact-item/editor.scss +38 -0
  50. package/src/blocks/contact/contact-item/factory.tsx +35 -0
  51. package/src/blocks/contact/contact-item/index.ts +23 -0
  52. package/src/blocks/contact/contact-item/types.ts +21 -0
  53. package/src/blocks/core/basic-button/constants.ts +17 -0
  54. package/src/blocks/core/basic-button/edit.tsx +107 -0
  55. package/src/blocks/core/basic-button/editor.scss +80 -0
  56. package/src/blocks/core/basic-button/factory.tsx +54 -0
  57. package/src/blocks/core/basic-button/index.ts +8 -0
  58. package/src/blocks/core/basic-button/types.ts +29 -0
  59. package/src/blocks/core/basic-heading/constants.ts +1 -0
  60. package/src/blocks/core/basic-heading/edit.tsx +76 -0
  61. package/src/blocks/core/basic-heading/editor.scss +8 -0
  62. package/src/blocks/core/basic-heading/factory.tsx +40 -0
  63. package/src/blocks/core/basic-heading/index.ts +8 -0
  64. package/src/blocks/core/basic-heading/types.ts +20 -0
  65. package/src/blocks/core/basic-overline/edit.tsx +28 -0
  66. package/src/blocks/core/basic-overline/editor.scss +14 -0
  67. package/src/blocks/core/basic-overline/factory.tsx +22 -0
  68. package/src/blocks/core/basic-overline/index.ts +8 -0
  69. package/src/blocks/core/basic-overline/types.ts +7 -0
  70. package/src/blocks/faq/faq-group/constants.ts +11 -0
  71. package/src/blocks/faq/faq-group/edit.tsx +55 -0
  72. package/src/blocks/faq/faq-group/editor.scss +11 -0
  73. package/src/blocks/faq/faq-group/factory.tsx +39 -0
  74. package/src/blocks/faq/faq-group/index.ts +11 -0
  75. package/src/blocks/faq/faq-group/types.ts +14 -0
  76. package/src/blocks/faq/faq-item/edit.tsx +50 -0
  77. package/src/blocks/faq/faq-item/editor.scss +57 -0
  78. package/src/blocks/faq/faq-item/factory.tsx +24 -0
  79. package/src/blocks/faq/faq-item/index.ts +9 -0
  80. package/src/blocks/faq/faq-item/types.ts +7 -0
  81. package/src/blocks/form/form-field/constants.ts +14 -0
  82. package/src/blocks/form/form-field/edit.tsx +178 -0
  83. package/src/blocks/form/form-field/editor.scss +71 -0
  84. package/src/blocks/form/form-field/factory.tsx +32 -0
  85. package/src/blocks/form/form-field/index.ts +10 -0
  86. package/src/blocks/form/form-field/types.ts +18 -0
  87. package/src/blocks/form/form-group/constants.ts +16 -0
  88. package/src/blocks/form/form-group/edit.tsx +190 -0
  89. package/src/blocks/form/form-group/editor.scss +41 -0
  90. package/src/blocks/form/form-group/factory.tsx +35 -0
  91. package/src/blocks/form/form-group/index.ts +18 -0
  92. package/src/blocks/form/form-group/types.ts +22 -0
  93. package/src/blocks/groups/banner-group/constants.ts +15 -0
  94. package/src/blocks/groups/banner-group/edit.tsx +122 -0
  95. package/src/blocks/groups/banner-group/editor.scss +18 -0
  96. package/src/blocks/groups/banner-group/factory.tsx +64 -0
  97. package/src/blocks/groups/banner-group/icon.tsx +13 -0
  98. package/src/blocks/groups/banner-group/index.ts +11 -0
  99. package/src/blocks/groups/banner-group/types.ts +30 -0
  100. package/src/blocks/groups/basic-header-group/constants.ts +9 -0
  101. package/src/blocks/groups/basic-header-group/edit.tsx +99 -0
  102. package/src/blocks/groups/basic-header-group/editor.scss +35 -0
  103. package/src/blocks/groups/basic-header-group/factory.tsx +46 -0
  104. package/src/blocks/groups/basic-header-group/icon.tsx +17 -0
  105. package/src/blocks/groups/basic-header-group/index.ts +9 -0
  106. package/src/blocks/groups/basic-header-group/types.ts +27 -0
  107. package/src/blocks/groups/button-group/constants.ts +7 -0
  108. package/src/blocks/groups/button-group/edit.tsx +52 -0
  109. package/src/blocks/groups/button-group/editor.scss +23 -0
  110. package/src/blocks/groups/button-group/factory.tsx +34 -0
  111. package/src/blocks/groups/button-group/index.ts +11 -0
  112. package/src/blocks/groups/button-group/types.ts +12 -0
  113. package/src/blocks/groups/text-and-media-group/constants.ts +43 -0
  114. package/src/blocks/groups/text-and-media-group/edit.tsx +241 -0
  115. package/src/blocks/groups/text-and-media-group/editor.scss +123 -0
  116. package/src/blocks/groups/text-and-media-group/factory.tsx +100 -0
  117. package/src/blocks/groups/text-and-media-group/icon.tsx +37 -0
  118. package/src/blocks/groups/text-and-media-group/index.ts +18 -0
  119. package/src/blocks/groups/text-and-media-group/types.ts +60 -0
  120. package/src/blocks/hero/hero-group/constants.ts +23 -0
  121. package/src/blocks/hero/hero-group/edit.tsx +85 -0
  122. package/src/blocks/hero/hero-group/editor.scss +0 -0
  123. package/src/blocks/hero/hero-group/factory.tsx +45 -0
  124. package/src/blocks/hero/hero-group/icon.tsx +28 -0
  125. package/src/blocks/hero/hero-group/index.ts +11 -0
  126. package/src/blocks/hero/hero-group/types.ts +22 -0
  127. package/src/blocks/hero/hero-item/constants.ts +15 -0
  128. package/src/blocks/hero/hero-item/edit.tsx +107 -0
  129. package/src/blocks/hero/hero-item/editor.scss +87 -0
  130. package/src/blocks/hero/hero-item/factory.tsx +49 -0
  131. package/src/blocks/hero/hero-item/index.ts +10 -0
  132. package/src/blocks/hero/hero-item/types.ts +38 -0
  133. package/src/blocks/map/map-group/constants.ts +20 -0
  134. package/src/blocks/map/map-group/edit.tsx +108 -0
  135. package/src/blocks/map/map-group/editor.scss +24 -0
  136. package/src/blocks/map/map-group/factory.tsx +51 -0
  137. package/src/blocks/map/map-group/index.ts +9 -0
  138. package/src/blocks/map/map-group/types.ts +16 -0
  139. package/src/blocks/newsletter/newsletter-form/constants.ts +5 -0
  140. package/src/blocks/newsletter/newsletter-form/edit.tsx +194 -0
  141. package/src/blocks/newsletter/newsletter-form/editor.scss +68 -0
  142. package/src/blocks/newsletter/newsletter-form/factory.tsx +59 -0
  143. package/src/blocks/newsletter/newsletter-form/index.ts +11 -0
  144. package/src/blocks/newsletter/newsletter-form/types.ts +45 -0
  145. package/src/blocks/post/post-slider-group/constants.ts +3 -0
  146. package/src/blocks/post/post-slider-group/edit.tsx +76 -0
  147. package/src/blocks/post/post-slider-group/factory.tsx +43 -0
  148. package/src/blocks/post/post-slider-group/icon.tsx +13 -0
  149. package/src/blocks/post/post-slider-group/index.ts +9 -0
  150. package/src/blocks/post/post-slider-group/types.ts +20 -0
  151. package/src/blocks/responsive-grid/responsive-grid-group/edit.tsx +95 -0
  152. package/src/blocks/responsive-grid/responsive-grid-group/factory.tsx +33 -0
  153. package/src/blocks/responsive-grid/responsive-grid-group/index.ts +13 -0
  154. package/src/blocks/responsive-grid/responsive-grid-group/types.ts +9 -0
  155. package/src/blocks/responsive-grid/responsive-grid-item/edit.tsx +19 -0
  156. package/src/blocks/responsive-grid/responsive-grid-item/factory.tsx +20 -0
  157. package/src/blocks/responsive-grid/responsive-grid-item/index.ts +9 -0
  158. package/src/blocks/responsive-grid/responsive-grid-item/types.ts +5 -0
  159. package/src/blocks/sections/base-section/attributes.ts +17 -0
  160. package/src/blocks/sections/base-section/constants.ts +18 -0
  161. package/src/blocks/sections/base-section/controls.tsx +70 -0
  162. package/src/blocks/sections/base-section/edit.tsx +34 -0
  163. package/src/blocks/sections/base-section/editor.scss +24 -0
  164. package/src/blocks/sections/base-section/factory.tsx +47 -0
  165. package/src/blocks/sections/base-section/icon.tsx +6 -0
  166. package/src/blocks/sections/base-section/index.ts +14 -0
  167. package/src/blocks/sections/base-section/types.ts +26 -0
  168. package/src/blocks/signpost/signpost-group/constants.ts +3 -0
  169. package/src/blocks/signpost/signpost-group/edit.tsx +75 -0
  170. package/src/blocks/signpost/signpost-group/editor.scss +0 -0
  171. package/src/blocks/signpost/signpost-group/factory.tsx +40 -0
  172. package/src/blocks/signpost/signpost-group/icon.tsx +19 -0
  173. package/src/blocks/signpost/signpost-group/index.ts +15 -0
  174. package/src/blocks/signpost/signpost-group/types.ts +9 -0
  175. package/src/blocks/signpost/signpost-item/constants.ts +4 -0
  176. package/src/blocks/signpost/signpost-item/edit.tsx +90 -0
  177. package/src/blocks/signpost/signpost-item/editor.scss +25 -0
  178. package/src/blocks/signpost/signpost-item/factory.tsx +29 -0
  179. package/src/blocks/signpost/signpost-item/icon.tsx +7 -0
  180. package/src/blocks/signpost/signpost-item/index.ts +10 -0
  181. package/src/blocks/signpost/signpost-item/types.ts +12 -0
  182. package/src/blocks/step/step-group/constants.ts +6 -0
  183. package/src/blocks/step/step-group/edit.tsx +64 -0
  184. package/src/blocks/step/step-group/editor.scss +19 -0
  185. package/src/blocks/step/step-group/factory.tsx +36 -0
  186. package/src/blocks/step/step-group/icon.tsx +27 -0
  187. package/src/blocks/step/step-group/index.ts +15 -0
  188. package/src/blocks/step/step-group/types.ts +13 -0
  189. package/src/blocks/step/step-item/constants.ts +6 -0
  190. package/src/blocks/step/step-item/edit.tsx +60 -0
  191. package/src/blocks/step/step-item/editor.scss +18 -0
  192. package/src/blocks/step/step-item/factory.tsx +27 -0
  193. package/src/blocks/step/step-item/index.ts +11 -0
  194. package/src/blocks/step/step-item/types.ts +12 -0
  195. package/src/blocks/testimonial/testimonial-group/constants.ts +27 -0
  196. package/src/blocks/testimonial/testimonial-group/edit.tsx +74 -0
  197. package/src/blocks/testimonial/testimonial-group/editor.scss +38 -0
  198. package/src/blocks/testimonial/testimonial-group/factory.tsx +44 -0
  199. package/src/blocks/testimonial/testimonial-group/icon.tsx +33 -0
  200. package/src/blocks/testimonial/testimonial-group/index.ts +15 -0
  201. package/src/blocks/testimonial/testimonial-group/types.ts +19 -0
  202. package/src/blocks/testimonial/testimonial-item/edit.tsx +48 -0
  203. package/src/blocks/testimonial/testimonial-item/editor.scss +20 -0
  204. package/src/blocks/testimonial/testimonial-item/factory.tsx +35 -0
  205. package/src/blocks/testimonial/testimonial-item/index.ts +9 -0
  206. package/src/blocks/testimonial/testimonial-item/types.ts +9 -0
  207. package/src/blocks/text-and-form/text-and-form-group/constants.ts +6 -0
  208. package/src/blocks/text-and-form/text-and-form-group/edit.tsx +59 -0
  209. package/src/blocks/text-and-form/text-and-form-group/editor.scss +21 -0
  210. package/src/blocks/text-and-form/text-and-form-group/factory.tsx +38 -0
  211. package/src/blocks/text-and-form/text-and-form-group/icon.tsx +23 -0
  212. package/src/blocks/text-and-form/text-and-form-group/index.ts +9 -0
  213. package/src/blocks/text-and-form/text-and-form-group/types.ts +23 -0
  214. package/src/blocks/text-and-form/text-and-form-text-column/constants.ts +10 -0
  215. package/src/blocks/text-and-form/text-and-form-text-column/edit.tsx +94 -0
  216. package/src/blocks/text-and-form/text-and-form-text-column/editor.scss +29 -0
  217. package/src/blocks/text-and-form/text-and-form-text-column/factory.tsx +41 -0
  218. package/src/blocks/text-and-form/text-and-form-text-column/index.ts +18 -0
  219. package/src/blocks/text-and-form/text-and-form-text-column/types.ts +23 -0
  220. package/src/blocks/usp/usp-group/constants.ts +54 -0
  221. package/src/blocks/usp/usp-group/edit.tsx +197 -0
  222. package/src/blocks/usp/usp-group/editor.scss +24 -0
  223. package/src/blocks/usp/usp-group/factory.tsx +113 -0
  224. package/src/blocks/usp/usp-group/icon.tsx +18 -0
  225. package/src/blocks/usp/usp-group/index.ts +15 -0
  226. package/src/blocks/usp/usp-group/types.ts +70 -0
  227. package/src/blocks/usp/usp-item/constants.ts +7 -0
  228. package/src/blocks/usp/usp-item/edit.tsx +65 -0
  229. package/src/blocks/usp/usp-item/editor.scss +17 -0
  230. package/src/blocks/usp/usp-item/factory.tsx +30 -0
  231. package/src/blocks/usp/usp-item/index.ts +11 -0
  232. package/src/blocks/usp/usp-item/types.ts +17 -0
  233. package/src/components/IconControl/IconControl.tsx +55 -0
  234. package/src/components/IconControl/editor.scss +53 -0
  235. package/src/components/IconControl/index.ts +2 -0
  236. package/src/components/IconControl/index.tsx +1 -0
  237. package/src/components/ImagePicker/ImagePicker.tsx +124 -0
  238. package/src/components/ImagePicker/editor.scss +79 -0
  239. package/src/components/ImagePicker/index.ts +2 -0
  240. package/src/components/ImagePicker/index.tsx +1 -0
  241. package/src/components/ItemIconControl/ItemIconControl.tsx +72 -0
  242. package/src/components/ItemIconControl/ItemIconModal.tsx +12 -0
  243. package/src/components/ItemIconControl/ItemIconPreview.tsx +93 -0
  244. package/src/components/ItemIconControl/editor.scss +52 -0
  245. package/src/components/ItemIconControl/index.ts +2 -0
  246. package/src/components/ItemIconControl/types.d.ts +30 -0
  247. package/src/constants.ts +20 -0
  248. package/src/editor.scss +34 -0
  249. package/src/globals.scss +237 -0
  250. package/src/hooks/useGroupBlock.ts +53 -0
  251. package/src/index.ts +122 -0
  252. package/src/types.ts +33 -0
  253. package/src/utils/createEditAdapter.ts +11 -0
  254. package/tsconfig.json +21 -0
@@ -0,0 +1,48 @@
1
+ import {InspectorControls, RichText, useBlockProps} from '@wordpress/block-editor'
2
+ import {PanelBody, TextControl} from '@wordpress/components'
3
+ import {__} from '@wordpress/i18n'
4
+ import {ImagePickerBody, ImagePickerControl} from '~/components/ImagePicker'
5
+ import type {TestimonialItemAttributes, TestimonialItemOptions} from './types'
6
+
7
+ export function createTestimonialItemEdit(options: TestimonialItemOptions) {
8
+ return function Edit({
9
+ attributes,
10
+ setAttributes,
11
+ }: {
12
+ attributes: TestimonialItemAttributes
13
+ setAttributes: (a: Partial<TestimonialItemAttributes>) => void
14
+ }) {
15
+ const {title, url, img} = attributes
16
+
17
+ const blockProps = useBlockProps({
18
+ className: options.blockClassName ?? 'i-testimonial',
19
+ })
20
+
21
+ return (
22
+ <>
23
+ <InspectorControls>
24
+ <PanelBody title={__('Nastavení položky', 'brilo-blocks')}>
25
+ <ImagePickerControl value={img} onChange={(v) => setAttributes({img: v})} />
26
+ <TextControl label={__('Nadpis', 'brilo-blocks')} value={title} onChange={(v) => setAttributes({title: v})} />
27
+ <TextControl label={__('URL', 'brilo-blocks')} value={url} onChange={(v) => setAttributes({url: v})} />
28
+ </PanelBody>
29
+ </InspectorControls>
30
+
31
+ <div {...blockProps}>
32
+ <div className="i-testimonial__inner wp-block-inner">
33
+ <div className="i-testimonial__image-wrap">
34
+ <ImagePickerBody value={img} onChange={(v) => setAttributes({img: v})} placeholder={__('Vyberte logo', 'brilo-blocks')} />
35
+ </div>
36
+ <RichText
37
+ tagName="p"
38
+ className="i-testimonial__title u-text-editable"
39
+ value={title}
40
+ onChange={(v) => setAttributes({title: v})}
41
+ placeholder={__('Název firmy / reference...', 'brilo-blocks')}
42
+ />
43
+ </div>
44
+ </div>
45
+ </>
46
+ )
47
+ }
48
+ }
@@ -0,0 +1,20 @@
1
+ @layer base {
2
+ .i-testimonial__image-wrap {
3
+ width: 100%;
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ margin-bottom: 12px;
8
+ flex-grow: 1;
9
+
10
+ img {
11
+ max-width: 100%;
12
+ max-height: 100%;
13
+ object-fit: contain;
14
+ }
15
+ }
16
+
17
+ .i-testimonial__inner {
18
+ height: 100%;
19
+ }
20
+ }
@@ -0,0 +1,35 @@
1
+ import type {BlockConfiguration} from '@wordpress/blocks'
2
+ import {__} from '@wordpress/i18n'
3
+ import {createTestimonialItemEdit} from './edit'
4
+ import type {TestimonialItemAttributes, TestimonialItemOptions} from './types'
5
+
6
+ export function createTestimonialItemBlock(
7
+ options: TestimonialItemOptions & {parent?: string[]},
8
+ ): BlockConfiguration<TestimonialItemAttributes> {
9
+ return {
10
+ name: options.name,
11
+ title: options.title ?? __('Reference - položka', 'brilo-blocks'),
12
+ category: options.category ?? 'brilo',
13
+ supports: {html: false, customClassName: false},
14
+ attributes: {
15
+ title: {
16
+ type: 'string',
17
+ default: '',
18
+ },
19
+ url: {
20
+ type: 'string',
21
+ default: '',
22
+ },
23
+ img: {
24
+ type: 'object',
25
+ default: {
26
+ id: 0,
27
+ url: '',
28
+ alt: '',
29
+ },
30
+ },
31
+ },
32
+ edit: createTestimonialItemEdit(options),
33
+ save: () => null,
34
+ } as unknown as BlockConfiguration<TestimonialItemAttributes>
35
+ }
@@ -0,0 +1,9 @@
1
+ export type {TestimonialItemAttributes, TestimonialItemOptions} from './types'
2
+ export {createTestimonialItemBlock} from './factory'
3
+
4
+ import type {TestimonialItemOptions} from './types'
5
+
6
+ export const testimonialItemDefaults: TestimonialItemOptions = {
7
+ name: 'brilo/testimonial-item',
8
+ parent: ['brilo/testimonial-group'],
9
+ }
@@ -0,0 +1,9 @@
1
+ import type {BriloBlockType, Media} from '~/types'
2
+
3
+ export interface TestimonialItemAttributes extends Record<string, unknown> {
4
+ title: string
5
+ url: string
6
+ img: Media
7
+ }
8
+
9
+ export interface TestimonialItemOptions extends BriloBlockType {}
@@ -0,0 +1,6 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ export const FORM_POSITIONS = [
4
+ {value: 'left', label: __('Formulář vlevo', 'brilo-blocks')},
5
+ {value: 'right', label: __('Formulář vpravo', 'brilo-blocks')},
6
+ ] as const
@@ -0,0 +1,59 @@
1
+ import {BlockControls, InspectorControls} from '@wordpress/block-editor'
2
+ import type {BlockEditProps} from '@wordpress/blocks'
3
+ import {ToolbarButton, ToolbarGroup} from '@wordpress/components'
4
+ import clsx from 'clsx'
5
+ import {useGroupBlock} from '~/hooks/useGroupBlock'
6
+ import {FORM_POSITIONS} from './constants'
7
+ import type {TextAndFormGroupAttributes, TextAndFormGroupOptions} from './types'
8
+
9
+ const [POSITION_LEFT, POSITION_RIGHT] = FORM_POSITIONS
10
+
11
+ export function createTextAndFormGroupEdit(options: TextAndFormGroupOptions) {
12
+ const textColumnBlock = options.textColumnBlock ?? 'brilo/text-and-form-text-column'
13
+ const formColumnBlock = options.formColumnBlock ?? 'brilo/form-group'
14
+
15
+ return function Edit(props: BlockEditProps<TextAndFormGroupAttributes>) {
16
+ const {attributes, setAttributes} = props
17
+ const {formPosition} = attributes
18
+ const isFormLeft = formPosition === POSITION_LEFT.value
19
+
20
+ const extraClasses = options.extraBlockClassName?.(attributes as never) ?? []
21
+
22
+ const {blockProps, innerBlocksProps} = useGroupBlock({
23
+ blockClassName: [options.blockClassName ?? 'g-text-and-form wp-block-section', `--form-${formPosition}`, ...extraClasses],
24
+ containerClassName: clsx(options.containerClassName ?? 'g-text-and-form__grid u-grid-responsive --col-2'),
25
+ allowedBlocks: [textColumnBlock, formColumnBlock],
26
+ template: [
27
+ [textColumnBlock, {}],
28
+ [formColumnBlock, {}],
29
+ ],
30
+ templateLock: false,
31
+ layout: {type: 'default'},
32
+ })
33
+
34
+ return (
35
+ <>
36
+ <BlockControls>
37
+ <ToolbarGroup>
38
+ <ToolbarButton
39
+ icon="align-pull-left"
40
+ label={POSITION_LEFT.label}
41
+ isActive={isFormLeft}
42
+ onClick={() => setAttributes({formPosition: POSITION_LEFT.value})}
43
+ />
44
+ <ToolbarButton
45
+ icon="align-pull-right"
46
+ label={POSITION_RIGHT.label}
47
+ isActive={!isFormLeft}
48
+ onClick={() => setAttributes({formPosition: POSITION_RIGHT.value})}
49
+ />
50
+ </ToolbarGroup>
51
+ </BlockControls>
52
+ {options.extraControls && <InspectorControls>{options.extraControls(props as never)}</InspectorControls>}
53
+ <div {...blockProps}>
54
+ <div {...innerBlocksProps} />
55
+ </div>
56
+ </>
57
+ )
58
+ }
59
+ }
@@ -0,0 +1,21 @@
1
+ @layer base {
2
+ .g-text-and-form {
3
+ padding: 8px;
4
+
5
+ &.--form-left {
6
+ .g-text-and-form__grid > :first-child {
7
+ order: 2;
8
+ }
9
+
10
+ .g-text-and-form__grid > :last-child {
11
+ order: 1;
12
+ }
13
+ }
14
+ }
15
+
16
+ .g-text-and-form__grid {
17
+ --grid-gap: 24px;
18
+ --grid-min-col-size: 240px;
19
+ align-items: start;
20
+ }
21
+ }
@@ -0,0 +1,38 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import {FORM_POSITIONS} from './constants'
5
+ import {createTextAndFormGroupEdit} from './edit'
6
+ import {icon as defaultIcon} from './icon'
7
+ import type {TextAndFormGroupAttributes, TextAndFormGroupOptions} from './types'
8
+
9
+ export type {TextAndFormGroupAttributes, TextAndFormGroupOptions}
10
+
11
+ export function createTextAndFormGroupBlock<TExtra extends Record<string, unknown> = Record<string, never>>(
12
+ options: TextAndFormGroupOptions<TExtra>,
13
+ ): BlockConfiguration<TextAndFormGroupAttributes & TExtra> {
14
+ const attributes: Record<string, unknown> = {
15
+ formPosition: {
16
+ type: 'string',
17
+ default: FORM_POSITIONS[1].value,
18
+ enum: FORM_POSITIONS.map((p) => p.value),
19
+ },
20
+ }
21
+
22
+ if (options.extraAttributes) {
23
+ Object.assign(attributes, options.extraAttributes)
24
+ }
25
+
26
+ return {
27
+ name: options.name,
28
+ title: options.title ?? __('Text a formulář', 'brilo-blocks'),
29
+ description: options.description,
30
+ category: options.category ?? 'layout',
31
+ ...(options.parent && {parent: options.parent}),
32
+ icon: options.icon ?? {src: defaultIcon},
33
+ supports: {html: false, customClassName: false},
34
+ attributes,
35
+ edit: createTextAndFormGroupEdit(options as unknown as TextAndFormGroupOptions),
36
+ save: () => <InnerBlocks.Content />,
37
+ } as unknown as BlockConfiguration<TextAndFormGroupAttributes & TExtra>
38
+ }
@@ -0,0 +1,23 @@
1
+ export const icon = (
2
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <title>Text and Form Group</title>
4
+ <path d="M0 2H8V3H0V2Z" fill="black" />
5
+ <path d="M0 4H9V5H0V4Z" fill="black" />
6
+ <path d="M0 6H6V7H0V6Z" fill="black" />
7
+ <path
8
+ fillRule="evenodd"
9
+ clipRule="evenodd"
10
+ d="M1.5 9C0.671573 9 0 9.67157 0 10.5C0 11.3284 0.671573 12 1.5 12H6.5C7.32843 12 8 11.3284 8 10.5C8 9.67157 7.32843 9 6.5 9H1.5ZM6 10H2V11H6V10Z"
11
+ fill="#357AB5"
12
+ />
13
+ <rect x="10.5" y="1.5" width="9" height="3" rx="0.5" stroke="black" fill="none" />
14
+ <rect x="10.5" y="6.5" width="9" height="3" rx="0.5" stroke="black" fill="none" />
15
+ <rect x="10.5" y="11.5" width="4" height="3" rx="0.5" stroke="black" fill="none" />
16
+ <path
17
+ fillRule="evenodd"
18
+ clipRule="evenodd"
19
+ d="M11.5 16C10.6716 16 10 16.6716 10 17.5C10 18.3284 10.6716 19 11.5 19H15.5C16.3284 19 17 18.3284 17 17.5C17 16.6716 16.3284 16 15.5 16H11.5ZM15 17H12V18H15V17Z"
20
+ fill="#357AB5"
21
+ />
22
+ </svg>
23
+ )
@@ -0,0 +1,9 @@
1
+ export type {TextAndFormGroupAttributes, TextAndFormGroupOptions} from './types'
2
+ export {createTextAndFormGroupBlock} from './factory'
3
+
4
+ import type {TextAndFormGroupOptions} from './types'
5
+
6
+ export const textAndFormGroupDefaults: TextAndFormGroupOptions = {
7
+ name: 'brilo/text-and-form-group',
8
+ parent: ['brilo/base-section'],
9
+ }
@@ -0,0 +1,23 @@
1
+ import type {BlockEditProps} from '@wordpress/blocks'
2
+ import type {ReactNode} from 'react'
3
+ import type {BriloBlockType} from '~/types'
4
+ import type {FORM_POSITIONS} from './constants'
5
+
6
+ export type FormPositions = (typeof FORM_POSITIONS)[number]['value']
7
+
8
+ export interface TextAndFormGroupAttributes extends Record<string, unknown> {
9
+ formPosition: FormPositions
10
+ }
11
+
12
+ export interface TextAndFormGroupOptions<TExtra extends Record<string, unknown> = Record<string, never>> extends BriloBlockType {
13
+ textColumnBlock?: string
14
+ formColumnBlock?: string
15
+ extraAttributes?: {
16
+ [K in keyof TExtra]: {
17
+ type: string
18
+ default: TExtra[K]
19
+ }
20
+ }
21
+ extraControls?: (props: BlockEditProps<TextAndFormGroupAttributes & TExtra>) => ReactNode
22
+ extraBlockClassName?: (attrs: TExtra) => (string | false | undefined)[]
23
+ }
@@ -0,0 +1,10 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ export {CONTENT_SIZES as DEFAULT_CONTENT_SIZES, HEADING_LEVELS} from '~/constants'
4
+
5
+ export const DEFAULT_HEADING_STYLES = [
6
+ {value: 'h1', label: __('H1 styl', 'brilo-blocks')},
7
+ {value: 'h2', label: __('H2 styl', 'brilo-blocks')},
8
+ {value: 'h3', label: __('H3 styl', 'brilo-blocks')},
9
+ {value: 'h4', label: __('H4 styl', 'brilo-blocks')},
10
+ ] as const
@@ -0,0 +1,94 @@
1
+ import {InspectorControls, RichText} from '@wordpress/block-editor'
2
+ import {
3
+ PanelBody,
4
+ __experimentalToggleGroupControl as ToggleGroupControl,
5
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
6
+ } from '@wordpress/components'
7
+ import {__} from '@wordpress/i18n'
8
+ import {useGroupBlock} from '~/hooks/useGroupBlock'
9
+ import {DEFAULT_CONTENT_SIZES, DEFAULT_HEADING_STYLES, HEADING_LEVELS} from './constants'
10
+ import type {ContentSizes, HeadingLevels, HeadingStyles, TextAndFormTextColumnAttributes, TextAndFormTextColumnOptions} from './types'
11
+
12
+ export function createTextAndFormTextColumnEdit(options: TextAndFormTextColumnOptions) {
13
+ const HEADING_STYLES = options.headingStyles ?? DEFAULT_HEADING_STYLES
14
+ const CONTENT_SIZES = options.contentSizes ?? DEFAULT_CONTENT_SIZES
15
+
16
+ return function Edit({
17
+ attributes,
18
+ setAttributes,
19
+ }: {
20
+ attributes: TextAndFormTextColumnAttributes
21
+ setAttributes: (a: Partial<TextAndFormTextColumnAttributes>) => void
22
+ }) {
23
+ const {header, content} = attributes
24
+
25
+ const {blockProps, innerBlocksProps} = useGroupBlock({
26
+ blockClassName: ['g-text-and-form__text', `--content-${content.size}`],
27
+ containerClassName: 'g-text-and-form__inner-blocks',
28
+ allowedBlocks: options.allowedBlocks,
29
+ template: options.template,
30
+ layout: {type: 'default'},
31
+ })
32
+
33
+ return (
34
+ <>
35
+ <InspectorControls>
36
+ <PanelBody title={__('Nadpis', 'brilo-blocks')} initialOpen={false}>
37
+ <ToggleGroupControl
38
+ label={__('Úroveň nadpisu', 'brilo-blocks')}
39
+ value={String(header.heading.level)}
40
+ onChange={(value) =>
41
+ setAttributes({header: {...header, heading: {...header.heading, level: Number(value) as HeadingLevels}}})
42
+ }
43
+ isBlock
44
+ >
45
+ {HEADING_LEVELS.map((l) => (
46
+ <ToggleGroupControlOption key={l} value={String(l)} label={`H${l}`} />
47
+ ))}
48
+ </ToggleGroupControl>
49
+ <ToggleGroupControl
50
+ label={__('Styl nadpisu', 'brilo-blocks')}
51
+ value={header.heading.style}
52
+ onChange={(value) => setAttributes({header: {...header, heading: {...header.heading, style: value as HeadingStyles}}})}
53
+ isBlock
54
+ >
55
+ {HEADING_STYLES.map((s) => (
56
+ <ToggleGroupControlOption key={s.value} value={s.value} label={s.label} />
57
+ ))}
58
+ </ToggleGroupControl>
59
+ </PanelBody>
60
+ <PanelBody title={__('Rozložení', 'brilo-blocks')}>
61
+ <ToggleGroupControl
62
+ label={__('Velikost textu', 'brilo-blocks')}
63
+ value={content.size}
64
+ onChange={(value) => setAttributes({content: {size: value as ContentSizes}})}
65
+ isBlock
66
+ >
67
+ {CONTENT_SIZES.map((s) => (
68
+ <ToggleGroupControlOption key={s.value} value={s.value} label={s.label} />
69
+ ))}
70
+ </ToggleGroupControl>
71
+ </PanelBody>
72
+ </InspectorControls>
73
+ <div {...blockProps}>
74
+ <RichText
75
+ tagName="span"
76
+ className="g-text-and-form__overline u-text-editable"
77
+ value={header.overline.title}
78
+ onChange={(value: string) => setAttributes({header: {...header, overline: {title: value}}})}
79
+ placeholder={__('Overline...', 'brilo-blocks')}
80
+ allowedFormats={[]}
81
+ />
82
+ <RichText
83
+ tagName={`h${header.heading.level}` as 'h1' | 'h2' | 'h3' | 'h4'}
84
+ className={`g-text-and-form__heading --heading-style-${header.heading.style} u-text-editable`}
85
+ value={header.heading.title}
86
+ onChange={(value: string) => setAttributes({header: {...header, heading: {...header.heading, title: value}}})}
87
+ placeholder={__('Nadpis...', 'brilo-blocks')}
88
+ />
89
+ <div {...innerBlocksProps} />
90
+ </div>
91
+ </>
92
+ )
93
+ }
94
+ }
@@ -0,0 +1,29 @@
1
+ @layer base {
2
+ .g-text-and-form__text {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 8px;
6
+ padding: 8px;
7
+ width: 100%;
8
+ }
9
+
10
+ .g-text-and-form__overline {
11
+ display: block;
12
+ font-size: 12px;
13
+ font-weight: 600;
14
+ text-transform: uppercase;
15
+ letter-spacing: 1px;
16
+ color: #888;
17
+ }
18
+
19
+ .g-text-and-form__heading {
20
+ margin: 0;
21
+ font-weight: 700;
22
+ font-size: var(--heading-size, 24px);
23
+ }
24
+
25
+ .g-text-and-form__inner-blocks {
26
+ margin-top: 8px;
27
+ min-height: 40px;
28
+ }
29
+ }
@@ -0,0 +1,41 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import type {OptionArray} from '~/types'
5
+ import {DEFAULT_CONTENT_SIZES, DEFAULT_HEADING_STYLES, HEADING_LEVELS} from './constants'
6
+ import {createTextAndFormTextColumnEdit} from './edit'
7
+ import type {TextAndFormTextColumnAttributes, TextAndFormTextColumnOptions} from './types'
8
+
9
+ export type {TextAndFormTextColumnAttributes, TextAndFormTextColumnOptions}
10
+
11
+ export function createTextAndFormTextColumnBlock<
12
+ THeadingStyles extends OptionArray = typeof DEFAULT_HEADING_STYLES,
13
+ TContentSizes extends OptionArray = typeof DEFAULT_CONTENT_SIZES,
14
+ >(
15
+ options: TextAndFormTextColumnOptions<THeadingStyles, TContentSizes>,
16
+ ): BlockConfiguration<TextAndFormTextColumnAttributes<THeadingStyles[number]['value'], TContentSizes[number]['value']>> {
17
+ const headingStyles = options.headingStyles ?? DEFAULT_HEADING_STYLES
18
+ const contentSizes = options.contentSizes ?? DEFAULT_CONTENT_SIZES
19
+
20
+ return {
21
+ name: options.name,
22
+ title: options.title ?? __('Textový sloupec', 'brilo-blocks'),
23
+ description: options.description,
24
+ category: options.category ?? 'layout',
25
+ ...(options.parent && {parent: options.parent}),
26
+ icon: options.icon ?? 'text',
27
+ supports: {html: false, customClassName: false},
28
+ attributes: {
29
+ header: {
30
+ type: 'object',
31
+ default: {
32
+ heading: {title: '', level: HEADING_LEVELS[1], style: headingStyles[1]?.value ?? headingStyles[0].value},
33
+ overline: {title: ''},
34
+ },
35
+ },
36
+ content: {type: 'object', default: {size: contentSizes[1]?.value ?? contentSizes[0].value}},
37
+ },
38
+ edit: createTextAndFormTextColumnEdit(options as unknown as TextAndFormTextColumnOptions),
39
+ save: () => <InnerBlocks.Content />,
40
+ } as unknown as BlockConfiguration<TextAndFormTextColumnAttributes<THeadingStyles[number]['value'], TContentSizes[number]['value']>>
41
+ }
@@ -0,0 +1,18 @@
1
+ export type {TextAndFormTextColumnAttributes, TextAndFormTextColumnOptions} from './types'
2
+ export {createTextAndFormTextColumnBlock} from './factory'
3
+
4
+ import type {TextAndFormTextColumnOptions} from './types'
5
+
6
+ export const textAndFormTextColumnDefaults: TextAndFormTextColumnOptions = {
7
+ name: 'brilo/text-and-form-text-column',
8
+ parent: ['brilo/text-and-form-group'],
9
+ allowedBlocks: [
10
+ 'brilo/basic-button',
11
+ 'brilo/basic-heading',
12
+ 'brilo/basic-overline',
13
+ 'brilo/button-group',
14
+ 'core/heading',
15
+ 'core/list',
16
+ 'core/paragraph',
17
+ ],
18
+ }
@@ -0,0 +1,23 @@
1
+ import type {BriloBlockType, OptionArray} from '~/types'
2
+ import type {DEFAULT_CONTENT_SIZES, DEFAULT_HEADING_STYLES, HEADING_LEVELS} from './constants'
3
+
4
+ export type HeadingStyles = (typeof DEFAULT_HEADING_STYLES)[number]['value']
5
+ export type HeadingLevels = (typeof HEADING_LEVELS)[number]
6
+ export type ContentSizes = (typeof DEFAULT_CONTENT_SIZES)[number]['value']
7
+
8
+ export interface TextAndFormTextColumnAttributes<THeadingStyle extends string = HeadingStyles, TContentSize extends string = ContentSizes>
9
+ extends Record<string, unknown> {
10
+ header: {
11
+ heading: {title: string; level: HeadingLevels; style: THeadingStyle}
12
+ overline: {title: string}
13
+ }
14
+ content: {size: TContentSize}
15
+ }
16
+
17
+ export interface TextAndFormTextColumnOptions<
18
+ THeadingStyles extends OptionArray = typeof DEFAULT_HEADING_STYLES,
19
+ TContentSizes extends OptionArray = typeof DEFAULT_CONTENT_SIZES,
20
+ > extends BriloBlockType {
21
+ headingStyles?: THeadingStyles
22
+ contentSizes?: TContentSizes
23
+ }
@@ -0,0 +1,54 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ export {CONTENT_SIZES as DEFAULT_CONTENT_SIZES} from '~/constants'
4
+
5
+ export const DEFAULT_COLUMNS = [2, 3, 4, 5, 6] as const
6
+
7
+ export const DEFAULT_DIRECTIONS = [
8
+ {value: 'vertical', label: __('Vertikální', 'brilo-blocks')},
9
+ {value: 'horizontal', label: __('Horizontální', 'brilo-blocks')},
10
+ ] as const
11
+
12
+ export const HEADING_LEVELS = [2, 3] as const
13
+
14
+ export const DEFAULT_HEADING_STYLES = [
15
+ {value: 'h1', label: 'L', description: __('48px', 'brilo-blocks')},
16
+ {value: 'h2', label: 'M', description: __('32px', 'brilo-blocks')},
17
+ {value: 'h3', label: 'S', description: __('24px', 'brilo-blocks')},
18
+ {value: 'h4', label: 'XS', description: __('20px', 'brilo-blocks')},
19
+ {value: 'h5', label: 'XXS', description: __('16px', 'brilo-blocks')},
20
+ ] as const
21
+
22
+ export const DEFAULT_SHADOWS = [
23
+ {value: 'none', label: __('Žádný', 'brilo-blocks')},
24
+ {value: 'sm', label: __('Malý', 'brilo-blocks')},
25
+ {value: 'md', label: __('Střední', 'brilo-blocks')},
26
+ ] as const
27
+
28
+ export const DEFAULT_ICON_SIZES = [
29
+ {value: 'xs', label: __('Extra Malá', 'brilo-blocks'), description: __('48px', 'brilo-blocks')},
30
+ {value: 'sm', label: __('Malá', 'brilo-blocks'), description: __('64px', 'brilo-blocks')},
31
+ {value: 'default', label: __('Výchozí', 'brilo-blocks'), description: __('88px', 'brilo-blocks')},
32
+ {value: 'lg', label: __('Velká', 'brilo-blocks'), description: __('104px', 'brilo-blocks')},
33
+ {value: 'xl', label: __('Extra Velká', 'brilo-blocks'), description: __('128px', 'brilo-blocks')},
34
+ ] as const
35
+
36
+ export const DEFAULT_ICON_COLORS = [
37
+ {value: 'none', label: __('Žádná', 'brilo-blocks')},
38
+ {value: 'primary', label: __('Primární', 'brilo-blocks')},
39
+ {value: 'secondary', label: __('Sekundární', 'brilo-blocks')},
40
+ {value: 'neutral', label: __('Neutrální', 'brilo-blocks')},
41
+ {value: 'conversion', label: __('Konverzní', 'brilo-blocks')},
42
+ ] as const
43
+
44
+ export const DEFAULT_ICON_BACKGROUNDS = [
45
+ {value: 'none', label: __('Žádné', 'brilo-blocks')},
46
+ {value: 'primary', label: __('Primární', 'brilo-blocks')},
47
+ {value: 'secondary', label: __('Sekundární', 'brilo-blocks')},
48
+ {value: 'neutral', label: __('Neutrální', 'brilo-blocks')},
49
+ ] as const
50
+
51
+ export const DEFAULT_ALIGNMENTS = [
52
+ {value: 'left', label: __('Vlevo', 'brilo-blocks')},
53
+ {value: 'center', label: __('Na střed', 'brilo-blocks')},
54
+ ] as const