@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,34 @@
1
+ @layer base {
2
+ .i-column {
3
+ border: 1px dashed #0073aa;
4
+ box-sizing: border-box;
5
+ border-radius: 4px;
6
+ padding: 4px;
7
+ min-height: 64px;
8
+ margin: 0 !important;
9
+
10
+ &.--size-1\/4 {
11
+ grid-column: span 3;
12
+ }
13
+
14
+ &.--size-1\/3 {
15
+ grid-column: span 4;
16
+ }
17
+
18
+ &.--size-1\/2 {
19
+ grid-column: span 6;
20
+ }
21
+
22
+ &.--size-2\/3 {
23
+ grid-column: span 8;
24
+ }
25
+
26
+ &.--size-3\/4 {
27
+ grid-column: span 9;
28
+ }
29
+
30
+ &.--size-1\/1 {
31
+ grid-column: span 12;
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,25 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import {createColumnItemEdit} from './edit'
5
+ import type {ColumnItemAttributes, ColumnItemOptions} from './types'
6
+
7
+ export function createColumnItemBlock(options: ColumnItemOptions): BlockConfiguration<ColumnItemAttributes> {
8
+ return {
9
+ name: options.name,
10
+ title: options.title ?? __('Položka sloupce', 'brilo-blocks'),
11
+ description: options.description,
12
+ category: options.category ?? 'layout',
13
+ ...(options.parent && {parent: options.parent}),
14
+ icon: options.icon ?? 'column',
15
+ supports: {html: false, customClassName: false},
16
+ attributes: {
17
+ size: {
18
+ type: 'string',
19
+ default: '1/2',
20
+ },
21
+ },
22
+ edit: createColumnItemEdit(options),
23
+ save: () => <InnerBlocks.Content />,
24
+ } as BlockConfiguration<ColumnItemAttributes>
25
+ }
@@ -0,0 +1,10 @@
1
+ export type {ColumnItemAttributes, ColumnItemOptions} from './types'
2
+ export {createColumnItemBlock} from './factory'
3
+
4
+ import type {ColumnItemOptions} from './types'
5
+
6
+ export const columnItemDefaults: ColumnItemOptions = {
7
+ name: 'brilo/column-item',
8
+ parent: ['brilo/column-group'],
9
+ allowedBlocks: ['core/paragraph', 'core/list', 'core/image', 'core/heading', 'core/embed', 'core/quote', 'core/table', 'core/gallery'],
10
+ }
@@ -0,0 +1,7 @@
1
+ import type {BriloBlockType} from '~/types'
2
+
3
+ export interface ColumnItemAttributes extends Record<string, unknown> {
4
+ size: string
5
+ }
6
+
7
+ export interface ColumnItemOptions extends BriloBlockType {}
@@ -0,0 +1 @@
1
+ export const HEADING_LEVELS = [2, 3, 4] as const
@@ -0,0 +1,52 @@
1
+ import {InspectorControls} 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 {HEADING_LEVELS} from './constants'
10
+ import type {CompareGroupAttributes, CompareGroupOptions} from './types'
11
+
12
+ export function createCompareGroupEdit(options: CompareGroupOptions) {
13
+ return function Edit({
14
+ attributes,
15
+ setAttributes,
16
+ }: {
17
+ attributes: CompareGroupAttributes
18
+ setAttributes: (a: Partial<CompareGroupAttributes>) => void
19
+ }) {
20
+ const {headingLevel} = attributes
21
+ const {blockProps, innerBlocksProps} = useGroupBlock({
22
+ blockClassName: options.blockClassName ?? 'g-compare wp-block-section',
23
+ containerClassName: [options.containerClassName ?? 'u-grid-responsive'],
24
+ allowedBlocks: options.allowedBlocks,
25
+ orientation: 'horizontal',
26
+ template: options.template,
27
+ layout: {type: 'default'},
28
+ })
29
+
30
+ return (
31
+ <>
32
+ <InspectorControls>
33
+ <PanelBody title={__('Nastavení', 'brilo-blocks')}>
34
+ <ToggleGroupControl
35
+ isBlock
36
+ label={__('Úroveň nadpisu', 'brilo-blocks')}
37
+ value={String(headingLevel)}
38
+ onChange={(v) => setAttributes({headingLevel: Number(v) as CompareGroupAttributes['headingLevel']})}
39
+ >
40
+ {HEADING_LEVELS.map((l) => (
41
+ <ToggleGroupControlOption key={l} value={String(l)} label={`H${l}`} />
42
+ ))}
43
+ </ToggleGroupControl>
44
+ </PanelBody>
45
+ </InspectorControls>
46
+ <div {...blockProps}>
47
+ <div {...innerBlocksProps} />
48
+ </div>
49
+ </>
50
+ )
51
+ }
52
+ }
@@ -0,0 +1,29 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import {createCompareGroupEdit} from './edit'
5
+ import {icon as defaultIcon} from './icon'
6
+ import {HEADING_LEVELS} from './constants'
7
+ import type {CompareGroupAttributes, CompareGroupOptions} from './types'
8
+
9
+ export type {CompareGroupAttributes, CompareGroupOptions}
10
+
11
+ export function createCompareGroupBlock(options: CompareGroupOptions): BlockConfiguration<CompareGroupAttributes> {
12
+ return {
13
+ name: options.name,
14
+ title: options.title ?? __('Srovnání', 'brilo-blocks'),
15
+ description: options.description,
16
+ category: options.category ?? 'layout',
17
+ ...(options.parent && {parent: options.parent}),
18
+ icon: options.icon ?? {src: defaultIcon},
19
+ supports: {html: false, customClassName: false},
20
+ attributes: {
21
+ headingLevel: {
22
+ type: 'number',
23
+ default: HEADING_LEVELS[1],
24
+ },
25
+ },
26
+ edit: createCompareGroupEdit(options),
27
+ save: () => <InnerBlocks.Content />,
28
+ } as unknown as BlockConfiguration<CompareGroupAttributes>
29
+ }
@@ -0,0 +1,7 @@
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>Compare Group</title>
4
+ <rect x="2" y="2" width="7" height="16" rx="1" stroke="currentColor" strokeWidth="1.5" fill="none" />
5
+ <rect x="11" y="2" width="7" height="16" rx="1" stroke="currentColor" strokeWidth="1.5" fill="none" />
6
+ </svg>
7
+ )
@@ -0,0 +1,13 @@
1
+ export type {CompareGroupAttributes, CompareGroupOptions} from './types'
2
+ export {createCompareGroupBlock} from './factory'
3
+ import type {CompareGroupOptions} from './types'
4
+
5
+ export const compareGroupDefaults: CompareGroupOptions = {
6
+ name: 'brilo/compare-group',
7
+ parent: ['brilo/base-section'],
8
+ allowedBlocks: ['brilo/compare-item'],
9
+ template: [
10
+ ['brilo/compare-item', {}],
11
+ ['brilo/compare-item', {}],
12
+ ],
13
+ }
@@ -0,0 +1,12 @@
1
+ import {HEADING_LEVELS} from './constants'
2
+ import type {BriloBlockType} from '~/types'
3
+
4
+ export type CompareHeadingLevel = (typeof HEADING_LEVELS)[number]
5
+
6
+ export interface CompareGroupAttributes extends Record<string, unknown> {
7
+ headingLevel: CompareHeadingLevel
8
+ }
9
+
10
+ export interface CompareGroupOptions extends BriloBlockType {
11
+ allowedBlocks: string[]
12
+ }
@@ -0,0 +1,38 @@
1
+ import {RichText, useBlockProps, useInnerBlocksProps} from '@wordpress/block-editor'
2
+ import {__} from '@wordpress/i18n'
3
+ import type {CompareItemAttributes, CompareItemOptions} from './types'
4
+
5
+ export function createCompareItemEdit(options: CompareItemOptions) {
6
+ return function Edit({
7
+ attributes,
8
+ setAttributes,
9
+ }: {
10
+ attributes: CompareItemAttributes
11
+ setAttributes: (a: Partial<CompareItemAttributes>) => void
12
+ }) {
13
+ const {title} = attributes
14
+ const blockProps = useBlockProps({className: 'i-compare'})
15
+ const innerBlocksProps = useInnerBlocksProps(
16
+ {className: 'i-compare__options wp-block-inner-content'},
17
+ {
18
+ allowedBlocks: options.allowedBlocks,
19
+ template: options.template,
20
+ },
21
+ )
22
+
23
+ return (
24
+ <div {...blockProps}>
25
+ <div className={'i-compare__inner'}>
26
+ <RichText
27
+ tagName={'div'}
28
+ className="i-compare__title u-text-editable"
29
+ value={title}
30
+ onChange={(v) => setAttributes({title: v})}
31
+ placeholder={__('Nadpis...', 'brilo-blocks')}
32
+ />
33
+ <div {...innerBlocksProps} />
34
+ </div>
35
+ </div>
36
+ )
37
+ }
38
+ }
@@ -0,0 +1,15 @@
1
+ @layer base {
2
+ .i-compare__inner {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 16px;
6
+ padding: 16px;
7
+ border: 1px solid #ccc;
8
+ width: 100%;
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ .i-compare {
13
+ width: 100%;
14
+ }
15
+ }
@@ -0,0 +1,28 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import {createCompareItemEdit} from './edit'
5
+ import {icon as defaultIcon} from './icon'
6
+ import type {CompareItemAttributes, CompareItemOptions} from './types'
7
+
8
+ export type {CompareItemAttributes, CompareItemOptions}
9
+
10
+ export function createCompareItemBlock(options: CompareItemOptions): BlockConfiguration<CompareItemAttributes> {
11
+ return {
12
+ name: options.name,
13
+ title: options.title ?? __('Položka srovnání', 'brilo-blocks'),
14
+ description: options.description,
15
+ category: options.category ?? 'layout',
16
+ ...(options.parent && {parent: options.parent}),
17
+ icon: options.icon ?? {src: defaultIcon},
18
+ supports: {html: false, customClassName: false},
19
+ attributes: {
20
+ title: {
21
+ type: 'string',
22
+ default: '',
23
+ },
24
+ },
25
+ edit: createCompareItemEdit(options),
26
+ save: () => <InnerBlocks.Content />,
27
+ } as unknown as BlockConfiguration<CompareItemAttributes>
28
+ }
@@ -0,0 +1,9 @@
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>Compare Item</title>
4
+ <rect x="4" y="2" width="12" height="16" rx="1" stroke="currentColor" strokeWidth="1.5" fill="none" />
5
+ <path d="M7 6H13" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
6
+ <path d="M7 9H13" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
7
+ <path d="M7 12H10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
8
+ </svg>
9
+ )
@@ -0,0 +1,13 @@
1
+ export type {CompareItemAttributes, CompareItemOptions} from './types'
2
+ export {createCompareItemBlock} from './factory'
3
+ import type {CompareItemOptions} from './types'
4
+
5
+ export const compareItemDefaults: CompareItemOptions = {
6
+ name: 'brilo/compare-item',
7
+ parent: ['brilo/compare-group'],
8
+ allowedBlocks: ['brilo/compare-option'],
9
+ template: [
10
+ ['brilo/compare-option', {variant: 'plus'}],
11
+ ['brilo/compare-option', {variant: 'minus'}],
12
+ ],
13
+ }
@@ -0,0 +1,9 @@
1
+ import type {BriloBlockType} from '~/types'
2
+
3
+ export interface CompareItemAttributes extends Record<string, unknown> {
4
+ title: string
5
+ }
6
+
7
+ export interface CompareItemOptions extends BriloBlockType {
8
+ allowedBlocks: string[]
9
+ }
@@ -0,0 +1,7 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ export const VARIANTS = [
4
+ {value: 'plus', label: __('+', 'brilo-blocks')},
5
+ {value: 'minus', label: __('-', 'brilo-blocks')},
6
+ {value: 'custom', label: __('Vlastní', 'brilo-blocks')},
7
+ ] as const
@@ -0,0 +1,64 @@
1
+ import {InspectorControls, RichText, useBlockProps} from '@wordpress/block-editor'
2
+ import {
3
+ PanelBody,
4
+ TextControl,
5
+ __experimentalToggleGroupControl as ToggleGroupControl,
6
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
7
+ } from '@wordpress/components'
8
+ import {__} from '@wordpress/i18n'
9
+ import {VARIANTS} from './constants'
10
+ import type {CompareOptionAttributes, CompareOptionOptions} from './types'
11
+
12
+ export function createCompareOptionEdit(options: CompareOptionOptions) {
13
+ return function Edit({
14
+ attributes,
15
+ setAttributes,
16
+ }: {
17
+ attributes: CompareOptionAttributes
18
+ setAttributes: (a: Partial<CompareOptionAttributes>) => void
19
+ }) {
20
+ const {text, variant, customChar} = attributes
21
+ const blockProps = useBlockProps({className: 'i-compare-option'})
22
+
23
+ return (
24
+ <>
25
+ <InspectorControls>
26
+ <PanelBody title={__('Nastavení', 'brilo-blocks')}>
27
+ <ToggleGroupControl
28
+ isBlock
29
+ label={__('Varianta', 'brilo-blocks')}
30
+ value={variant}
31
+ onChange={(v) => setAttributes({variant: v as CompareOptionAttributes['variant']})}
32
+ >
33
+ {VARIANTS.map((v) => (
34
+ <ToggleGroupControlOption key={v.value} value={v.value} label={v.label} />
35
+ ))}
36
+ </ToggleGroupControl>
37
+ {variant === 'custom' && (
38
+ <TextControl
39
+ label={__('Vlastní znak', 'brilo-blocks')}
40
+ value={customChar}
41
+ onChange={(v) => setAttributes({customChar: v.substring(0, 1)})}
42
+ help={__('Zadejte 1 znak', 'brilo-blocks')}
43
+ />
44
+ )}
45
+ </PanelBody>
46
+ </InspectorControls>
47
+ <div {...blockProps}>
48
+ <div className="i-compare-option__bullet">
49
+ {variant === 'plus' && '+'}
50
+ {variant === 'minus' && '−'}
51
+ {variant === 'custom' && (customChar || '?')}
52
+ </div>
53
+ <RichText
54
+ tagName="span"
55
+ className="i-compare-option__text u-text-editable"
56
+ value={text}
57
+ onChange={(v) => setAttributes({text: v})}
58
+ placeholder={__('Text...', 'brilo-blocks')}
59
+ />
60
+ </div>
61
+ </>
62
+ )
63
+ }
64
+ }
@@ -0,0 +1,26 @@
1
+ @layer base {
2
+ .i-compare-option__bullet {
3
+ display: flex;
4
+ align-items: center;
5
+ justify-content: center;
6
+ padding: 4px;
7
+ width: 24px;
8
+ height: 24px;
9
+ background-color: #006ba1;
10
+ color: #fff;
11
+ font-weight: 900;
12
+ font-size: 18px;
13
+ flex-shrink: 0;
14
+ }
15
+
16
+ .i-compare-option__text {
17
+ flex-grow: 1;
18
+ }
19
+
20
+ .i-compare-option {
21
+ display: flex;
22
+ align-items: center;
23
+ gap: 8px;
24
+ width: 100%;
25
+ }
26
+ }
@@ -0,0 +1,35 @@
1
+ import type {BlockConfiguration} from '@wordpress/blocks'
2
+ import {__} from '@wordpress/i18n'
3
+ import {createCompareOptionEdit} from './edit'
4
+ import {icon as defaultIcon} from './icon'
5
+ import type {CompareOptionAttributes, CompareOptionOptions} from './types'
6
+
7
+ export type {CompareOptionAttributes, CompareOptionOptions}
8
+
9
+ export function createCompareOptionBlock(options: CompareOptionOptions): BlockConfiguration<CompareOptionAttributes> {
10
+ return {
11
+ name: options.name,
12
+ title: options.title ?? __('Možnost srovnání', 'brilo-blocks'),
13
+ description: options.description,
14
+ category: options.category ?? 'layout',
15
+ ...(options.parent && {parent: options.parent}),
16
+ icon: options.icon ?? {src: defaultIcon},
17
+ supports: {html: false, customClassName: false},
18
+ attributes: {
19
+ text: {
20
+ type: 'string',
21
+ default: '',
22
+ },
23
+ variant: {
24
+ type: 'string',
25
+ default: 'plus',
26
+ },
27
+ customChar: {
28
+ type: 'string',
29
+ default: '',
30
+ },
31
+ },
32
+ edit: createCompareOptionEdit(options),
33
+ save: () => null,
34
+ } as unknown as BlockConfiguration<CompareOptionAttributes>
35
+ }
@@ -0,0 +1,7 @@
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>Compare Option</title>
4
+ <path d="M4 10H16" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
5
+ <path d="M10 4V16" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
6
+ </svg>
7
+ )
@@ -0,0 +1,8 @@
1
+ export type {CompareOptionAttributes, CompareOptionOptions} from './types'
2
+ export {createCompareOptionBlock} from './factory'
3
+ import type {CompareOptionOptions} from './types'
4
+
5
+ export const compareOptionDefaults: CompareOptionOptions = {
6
+ name: 'brilo/compare-option',
7
+ parent: ['brilo/compare-item'],
8
+ }
@@ -0,0 +1,12 @@
1
+ import type {BriloBlockType} from '~/types'
2
+ import {VARIANTS} from './constants'
3
+
4
+ export type CompareOptionVariant = (typeof VARIANTS)[number]['value']
5
+
6
+ export interface CompareOptionAttributes extends Record<string, unknown> {
7
+ text: string
8
+ variant: CompareOptionVariant
9
+ customChar: string
10
+ }
11
+
12
+ export interface CompareOptionOptions extends BriloBlockType {}
@@ -0,0 +1,3 @@
1
+ export const CONTACT_COLUMNS = [2, 3] as const
2
+
3
+ export const CONTACT_COLUMNS_CONTEXT = 'brilo/contact-columns'
@@ -0,0 +1,57 @@
1
+ import {InspectorControls} 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 clsx from 'clsx'
9
+ import {useGroupBlock} from '~/hooks/useGroupBlock'
10
+ import {CONTACT_COLUMNS} from './constants'
11
+ import type {ContactColumns, ContactGroupAttributes, ContactGroupOptions} from './types'
12
+
13
+ export function createContactGroupEdit(options: ContactGroupOptions) {
14
+ const COLUMNS = options.columns ?? CONTACT_COLUMNS
15
+
16
+ return function Edit({
17
+ attributes,
18
+ setAttributes,
19
+ }: {
20
+ attributes: ContactGroupAttributes
21
+ setAttributes: (a: Partial<ContactGroupAttributes>) => void
22
+ }) {
23
+ const {columns} = attributes
24
+
25
+ const {blockProps, innerBlocksProps} = useGroupBlock({
26
+ blockClassName: clsx(options.blockClassName ?? 'g-contact wp-block-section'),
27
+ containerClassName: [options.containerClassName ?? 'g-contact__items', `--cols-${columns}`],
28
+ containerStyle: {'--grid-max-col-count': columns},
29
+ allowedBlocks: options.allowedBlocks,
30
+ orientation: 'horizontal',
31
+ template: options.template,
32
+ layout: {type: 'default'},
33
+ })
34
+
35
+ return (
36
+ <>
37
+ <InspectorControls>
38
+ <PanelBody title={__('Rozložení', 'brilo-blocks')}>
39
+ <ToggleGroupControl
40
+ isBlock
41
+ label={__('Počet sloupců', 'brilo-blocks')}
42
+ value={String(columns)}
43
+ onChange={(v) => setAttributes({columns: Number(v) as ContactColumns})}
44
+ >
45
+ {COLUMNS.map((c) => (
46
+ <ToggleGroupControlOption key={c} value={String(c)} label={String(c)} />
47
+ ))}
48
+ </ToggleGroupControl>
49
+ </PanelBody>
50
+ </InspectorControls>
51
+ <div {...blockProps}>
52
+ <div {...innerBlocksProps} />
53
+ </div>
54
+ </>
55
+ )
56
+ }
57
+ }
@@ -0,0 +1,20 @@
1
+ @layer base {
2
+ .g-contact {
3
+ .g-contact__items {
4
+ display: grid;
5
+ grid-template-columns: repeat(var(--grid-max-col-count, 3), minmax(0, 1fr));
6
+ gap: 16px;
7
+ align-items: start;
8
+ }
9
+ }
10
+ }
11
+
12
+ // WP core sets `margin-left/right: auto` on `.wp-block` children of containers whose
13
+ // layout type isn't flex/grid (ours is `default`). That rule is UNLAYERED, so a
14
+ // layered override can't beat it regardless of specificity — keep this UNLAYERED and
15
+ // bump above WP's (0,2,0) specificity to win.
16
+ .editor-styles-wrapper .g-contact__items > .wp-block {
17
+ margin-left: 0;
18
+ margin-right: 0;
19
+ max-width: none;
20
+ }
@@ -0,0 +1,35 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import type {NumberArray} from '~/types'
5
+ import {CONTACT_COLUMNS, CONTACT_COLUMNS_CONTEXT} from './constants'
6
+ import {createContactGroupEdit} from './edit'
7
+ import type {ContactGroupAttributes, ContactGroupOptions} from './types'
8
+
9
+ export type {ContactGroupAttributes, ContactGroupOptions}
10
+
11
+ export function createContactGroupBlock<TColumns extends NumberArray = typeof CONTACT_COLUMNS>(
12
+ options: ContactGroupOptions<TColumns>,
13
+ ): BlockConfiguration<ContactGroupAttributes<TColumns[number]>> {
14
+ const columns = options.columns ?? CONTACT_COLUMNS
15
+
16
+ return {
17
+ name: options.name,
18
+ title: options.title ?? __('Kontakty', 'brilo-blocks'),
19
+ description: options.description,
20
+ category: options.category ?? 'layout',
21
+ ...(options.parent && {parent: options.parent}),
22
+ icon: options.icon ?? 'id-alt',
23
+ supports: {html: false, customClassName: false},
24
+ providesContext: {[CONTACT_COLUMNS_CONTEXT]: 'columns'},
25
+ attributes: {
26
+ columns: {
27
+ type: 'number',
28
+ default: columns[1] ?? columns[0],
29
+ enum: [...columns],
30
+ },
31
+ },
32
+ edit: createContactGroupEdit(options as unknown as ContactGroupOptions),
33
+ save: () => <InnerBlocks.Content />,
34
+ } as unknown as BlockConfiguration<ContactGroupAttributes<TColumns[number]>>
35
+ }
@@ -0,0 +1,12 @@
1
+ export type {ContactColumns, ContactGroupAttributes, ContactGroupOptions} from './types'
2
+ export {createContactGroupBlock} from './factory'
3
+ export {CONTACT_COLUMNS, CONTACT_COLUMNS_CONTEXT} from './constants'
4
+
5
+ import type {ContactGroupOptions} from './types'
6
+
7
+ export const contactGroupDefaults: ContactGroupOptions = {
8
+ name: 'brilo/contact-group',
9
+ parent: ['brilo/base-section'],
10
+ allowedBlocks: ['brilo/contact-item'],
11
+ template: [['brilo/contact-item', {}]],
12
+ }
@@ -0,0 +1,12 @@
1
+ import type {BriloBlockType, NumberArray} from '~/types'
2
+ import type {CONTACT_COLUMNS} from './constants'
3
+
4
+ export type ContactColumns = (typeof CONTACT_COLUMNS)[number]
5
+
6
+ export interface ContactGroupAttributes<TColumns extends number = ContactColumns> extends Record<string, unknown> {
7
+ columns: TColumns
8
+ }
9
+
10
+ export interface ContactGroupOptions<TColumns extends NumberArray = typeof CONTACT_COLUMNS> extends BriloBlockType {
11
+ columns?: TColumns
12
+ }
@@ -0,0 +1,17 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ export const CONTACT_ICON_TYPES = [
4
+ {value: 'preselected', label: __('Předvolená', 'brilo-blocks')},
5
+ {value: 'media', label: __('Obrázek', 'brilo-blocks')},
6
+ ] as const
7
+
8
+ export const CONTACT_ICON_SIZES = [
9
+ {value: 'sm', label: __('Malá', 'brilo-blocks'), size: 24},
10
+ {value: 'md', label: __('Střední', 'brilo-blocks'), size: 32},
11
+ {value: 'lg', label: __('Velká', 'brilo-blocks'), size: 48},
12
+ {value: 'custom', label: __('Vlastní', 'brilo-blocks')},
13
+ ] as const
14
+
15
+ export const CONTACT_ICON_SIZE_RANGE = {min: 8, max: 100} as const
16
+
17
+ export const CONTACT_ICON_SIZE_DEFAULT = 32