@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,13 @@
1
+ export type {ResponsiveGridGroupAttributes, ResponsiveGridGroupOptions} from './types'
2
+ export {createResponsiveGridGroupBlock} from './factory'
3
+
4
+ import type {ResponsiveGridGroupOptions} from './types'
5
+
6
+ export const responsiveGridGroupDefaults: ResponsiveGridGroupOptions = {
7
+ name: 'brilo/responsive-grid-group',
8
+ allowedBlocks: ['brilo/responsive-grid-item'],
9
+ template: [
10
+ ['brilo/responsive-grid-item', {}],
11
+ ['brilo/responsive-grid-item', {}],
12
+ ],
13
+ }
@@ -0,0 +1,9 @@
1
+ import type {BriloBlockType} from '~/types'
2
+
3
+ export interface ResponsiveGridGroupAttributes extends Record<string, unknown> {
4
+ columns: number
5
+ gap: number
6
+ minColSize: number
7
+ }
8
+
9
+ export interface ResponsiveGridGroupOptions extends BriloBlockType {}
@@ -0,0 +1,19 @@
1
+ import {useGroupBlock} from '~/hooks/useGroupBlock'
2
+ import type {ResponsiveGridItemAttributes, ResponsiveGridItemOptions} from './types'
3
+
4
+ export function createResponsiveGridItemEdit(options: ResponsiveGridItemOptions) {
5
+ return function Edit(_: {attributes: ResponsiveGridItemAttributes; setAttributes: (a: Partial<ResponsiveGridItemAttributes>) => void}) {
6
+ const {blockProps, innerBlocksProps} = useGroupBlock({
7
+ blockClassName: options.blockClassName ?? 'u-grid-responsive__item',
8
+ containerClassName: options.containerClassName ?? 'u-grid-responsive__item-inner entry-content',
9
+ allowedBlocks: options.allowedBlocks,
10
+ template: options.template,
11
+ })
12
+
13
+ return (
14
+ <div {...blockProps}>
15
+ <div {...innerBlocksProps} />
16
+ </div>
17
+ )
18
+ }
19
+ }
@@ -0,0 +1,20 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import {createResponsiveGridItemEdit} from './edit'
5
+ import type {ResponsiveGridItemAttributes, ResponsiveGridItemOptions} from './types'
6
+
7
+ export function createResponsiveGridItemBlock(options: ResponsiveGridItemOptions): BlockConfiguration<ResponsiveGridItemAttributes> {
8
+ return {
9
+ name: options.name,
10
+ title: options.title ?? __('Buňka mřížky', 'brilo-blocks'),
11
+ description: options.description,
12
+ category: options.category ?? 'layout',
13
+ ...(options.parent && {parent: options.parent}),
14
+ icon: options.icon ?? 'grid-view',
15
+ supports: {html: false, customClassName: false},
16
+ attributes: {},
17
+ edit: createResponsiveGridItemEdit(options),
18
+ save: () => <InnerBlocks.Content />,
19
+ } as BlockConfiguration<ResponsiveGridItemAttributes>
20
+ }
@@ -0,0 +1,9 @@
1
+ export type {ResponsiveGridItemAttributes, ResponsiveGridItemOptions} from './types'
2
+ export {createResponsiveGridItemBlock} from './factory'
3
+
4
+ import type {ResponsiveGridItemOptions} from './types'
5
+
6
+ export const responsiveGridItemDefaults: ResponsiveGridItemOptions = {
7
+ name: 'brilo/responsive-grid-item',
8
+ parent: ['brilo/responsive-grid-group'],
9
+ }
@@ -0,0 +1,5 @@
1
+ import type {BriloBlockType} from '~/types'
2
+
3
+ export interface ResponsiveGridItemAttributes extends Record<string, unknown> {}
4
+
5
+ export interface ResponsiveGridItemOptions extends BriloBlockType {}
@@ -0,0 +1,17 @@
1
+ export const baseAttributes = {
2
+ id: {
3
+ type: 'string',
4
+ default: '',
5
+ },
6
+ spacing: {
7
+ type: 'object',
8
+ default: {
9
+ position: 'default',
10
+ size: 'default',
11
+ },
12
+ },
13
+ background: {
14
+ type: 'string',
15
+ default: 'none',
16
+ },
17
+ } as const
@@ -0,0 +1,18 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ export const SPACING_POSITIONS = [
4
+ {value: 'default', label: __('Nahoře i dole', 'brilo-blocks')},
5
+ {value: 'none', label: __('Žádná', 'brilo-blocks')},
6
+ {value: 'bottom-0', label: __('Pouze nahoře', 'brilo-blocks')},
7
+ {value: 'top-0', label: __('Pouze dole', 'brilo-blocks')},
8
+ ] as const
9
+
10
+ export const SPACING_SIZES = ['default', 'sm', 'xs'] as const
11
+
12
+ export const BACKGROUNDS = [
13
+ {value: 'none', label: __('Žádné', 'brilo-blocks')},
14
+ {value: 'primary', label: __('Primární', 'brilo-blocks')},
15
+ {value: 'secondary', label: __('Sekundární', 'brilo-blocks')},
16
+ {value: 'conversion', label: __('Konverzní', 'brilo-blocks')},
17
+ {value: 'neutral', label: __('Neutrální', 'brilo-blocks')},
18
+ ] as const
@@ -0,0 +1,70 @@
1
+ import {
2
+ PanelBody,
3
+ SelectControl,
4
+ TextControl,
5
+ __experimentalToggleGroupControl as ToggleGroupControl,
6
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
7
+ } from '@wordpress/components'
8
+ import {__} from '@wordpress/i18n'
9
+ import type {BaseBlockAttributes, ExcludableBaseAttr} from './types'
10
+ import {BACKGROUNDS, SPACING_POSITIONS, SPACING_SIZES} from './constants'
11
+
12
+ type SpacingPosition = BaseBlockAttributes['spacing']['position']
13
+ type SpacingSize = BaseBlockAttributes['spacing']['size']
14
+
15
+ interface BaseControlsProps {
16
+ attributes: BaseBlockAttributes
17
+ setAttributes: (attrs: Partial<BaseBlockAttributes>) => void
18
+ exclude: ExcludableBaseAttr[]
19
+ }
20
+
21
+ export function BaseControls({attributes, setAttributes, exclude}: BaseControlsProps) {
22
+ const {id, spacing, background} = attributes
23
+
24
+ return (
25
+ <>
26
+ {!exclude.includes('spacing') && (
27
+ <PanelBody title={__('Rozestupy', 'brilo-blocks')}>
28
+ <SelectControl<string>
29
+ label={__('Pozice', 'brilo-blocks')}
30
+ value={spacing.position}
31
+ options={[...SPACING_POSITIONS]}
32
+ onChange={(value) => setAttributes({spacing: {...spacing, position: value as SpacingPosition}})}
33
+ />
34
+ <ToggleGroupControl
35
+ label={__('Velikost', 'brilo-blocks')}
36
+ value={spacing.size}
37
+ onChange={(value) => setAttributes({spacing: {...spacing, size: value as SpacingSize}})}
38
+ isBlock
39
+ >
40
+ {SPACING_SIZES.map((s) => (
41
+ <ToggleGroupControlOption key={s} value={s} label={s === 'default' ? __('Výchozí', 'brilo-blocks') : s.toUpperCase()} />
42
+ ))}
43
+ </ToggleGroupControl>
44
+ </PanelBody>
45
+ )}
46
+
47
+ {!exclude.includes('background') && (
48
+ <PanelBody title={__('Pozadí', 'brilo-blocks')}>
49
+ <SelectControl<string>
50
+ label={__('Pozadí', 'brilo-blocks')}
51
+ value={background}
52
+ options={[...BACKGROUNDS]}
53
+ onChange={(value) => setAttributes({background: value})}
54
+ />
55
+ </PanelBody>
56
+ )}
57
+
58
+ {!exclude.includes('id') && (
59
+ <PanelBody title={__('Kotva', 'brilo-blocks')} initialOpen={false}>
60
+ <TextControl
61
+ label={__('ID sekce', 'brilo-blocks')}
62
+ value={id ?? ''}
63
+ onChange={(value) => setAttributes({id: value})}
64
+ help={__('Použije se jako HTML atribut id pro kotevní odkaz.', 'brilo-blocks')}
65
+ />
66
+ </PanelBody>
67
+ )}
68
+ </>
69
+ )
70
+ }
@@ -0,0 +1,34 @@
1
+ import {InspectorControls, useBlockProps, useInnerBlocksProps} from '@wordpress/block-editor'
2
+ import type {BlockEditProps} from '@wordpress/blocks'
3
+ import type {BaseBlockAttributes, BaseSectionOptions} from './types'
4
+ import {BaseControls} from './controls'
5
+
6
+ export function createBaseSectionEdit<TExtra extends Record<string, unknown> = Record<string, never>>(options: BaseSectionOptions<TExtra>) {
7
+ const EXCLUDE = options.exclude ?? []
8
+
9
+ return function Edit(props: BlockEditProps<BaseBlockAttributes & TExtra>) {
10
+ const {attributes, setAttributes} = props
11
+ const blockProps = useBlockProps({className: options.blockClassName})
12
+ const innerBlocksProps = useInnerBlocksProps({className: options.containerClassName}, {
13
+ allowedBlocks: options.allowedBlocks,
14
+ orientation: 'vertical',
15
+ layout: {type: 'default'},
16
+ } as Parameters<typeof useInnerBlocksProps>[1])
17
+
18
+ return (
19
+ <>
20
+ <InspectorControls>
21
+ <BaseControls
22
+ attributes={attributes as BaseBlockAttributes}
23
+ setAttributes={setAttributes as (attrs: Partial<BaseBlockAttributes>) => void}
24
+ exclude={EXCLUDE}
25
+ />
26
+ {options.extraControls?.(props)}
27
+ </InspectorControls>
28
+ <div {...blockProps}>
29
+ <div {...innerBlocksProps} />
30
+ </div>
31
+ </>
32
+ )
33
+ }
34
+ }
@@ -0,0 +1,24 @@
1
+ @layer base {
2
+ .s-base {
3
+ border: 2px dashed #0073aa;
4
+ padding: 16px;
5
+ min-height: 60px;
6
+ position: relative;
7
+ max-width: 1200px;
8
+
9
+ &::before {
10
+ content: "Sekce";
11
+ display: block;
12
+ font-size: 10px;
13
+ font-weight: 600;
14
+ text-transform: uppercase;
15
+ color: #0073aa;
16
+ letter-spacing: 0.5px;
17
+ margin-bottom: 8px;
18
+ }
19
+ }
20
+
21
+ .s-base__inner {
22
+ min-height: 40px;
23
+ }
24
+ }
@@ -0,0 +1,47 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import {baseAttributes} from './attributes'
5
+ import {BACKGROUNDS} from './constants'
6
+ import {createBaseSectionEdit} from './edit'
7
+ import {icon as defaultIcon} from './icon'
8
+ import type {BaseBlockAttributes, BaseSectionOptions, ExcludableBaseAttr} from './types'
9
+
10
+ export type {BaseBlockAttributes, BaseSectionOptions, ExcludableBaseAttr}
11
+
12
+ export function createBaseSectionBlock<TExtra extends Record<string, unknown> = Record<string, never>>(
13
+ options: BaseSectionOptions<TExtra>,
14
+ ): BlockConfiguration<BaseBlockAttributes & TExtra> {
15
+ const exclude = options.exclude ?? []
16
+
17
+ const attributes: Record<string, unknown> = {}
18
+ for (const [key, value] of Object.entries(baseAttributes)) {
19
+ if (!exclude.includes(key as keyof typeof baseAttributes)) {
20
+ if (key === 'background') {
21
+ attributes[key] = {...value, enum: BACKGROUNDS.map((b) => b.value)}
22
+ } else {
23
+ attributes[key] = value
24
+ }
25
+ }
26
+ }
27
+
28
+ if (options.extraAttributes) {
29
+ Object.assign(attributes, options.extraAttributes)
30
+ }
31
+
32
+ return {
33
+ name: options.name,
34
+ title: options.title ?? __('Sekce', 'brilo-blocks'),
35
+ description: options.description,
36
+ category: options.category ?? 'layout',
37
+ icon: options.icon ?? {src: defaultIcon},
38
+ supports: options.supports ?? {
39
+ html: false,
40
+ customClassName: false,
41
+ align: false,
42
+ },
43
+ attributes,
44
+ edit: createBaseSectionEdit(options),
45
+ save: () => <InnerBlocks.Content />,
46
+ } as unknown as BlockConfiguration<BaseBlockAttributes & TExtra>
47
+ }
@@ -0,0 +1,6 @@
1
+ export const icon = (
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 512 512" fill="black">
3
+ <title>Base Section</title>
4
+ <path d="M.3 89.5C.1 91.6 0 93.8 0 96L0 224 0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-192 0-128c0-35.3-28.7-64-64-64L64 32c-2.2 0-4.4 .1-6.5 .3c-9.2 .9-17.8 3.8-25.5 8.2C21.8 46.5 13.4 55.1 7.7 65.5c-3.9 7.3-6.5 15.4-7.4 24zM48 224l416 0 0 192c0 8.8-7.2 16-16 16L64 432c-8.8 0-16-7.2-16-16l0-192z" />
5
+ </svg>
6
+ )
@@ -0,0 +1,14 @@
1
+ export type {BaseBlockAttributes, BaseSectionOptions, ExcludableBaseAttr} from './types'
2
+ export {baseAttributes} from './attributes'
3
+ export {BACKGROUNDS, SPACING_POSITIONS, SPACING_SIZES} from './constants'
4
+ export {createBaseSectionEdit} from './edit'
5
+ export {createBaseSectionBlock} from './factory'
6
+
7
+ import type {BaseSectionOptions} from './types'
8
+
9
+ export const baseSectionDefaults: BaseSectionOptions = {
10
+ name: 'brilo/base-section',
11
+ blockClassName: 'wp-block-section',
12
+ containerClassName: 'wp-block-section__inner',
13
+ allowedBlocks: [],
14
+ }
@@ -0,0 +1,26 @@
1
+ import type {BlockConfiguration, BlockEditProps} from '@wordpress/blocks'
2
+ import type {ReactNode} from 'react'
3
+ import type {BriloBlockType} from '~/types'
4
+
5
+ export interface BaseBlockAttributes extends Record<string, unknown> {
6
+ id: string
7
+ spacing: {
8
+ position: string
9
+ size: string
10
+ }
11
+ background: string
12
+ }
13
+
14
+ export type ExcludableBaseAttr = 'spacing' | 'background' | 'id'
15
+
16
+ export interface BaseSectionOptions<TExtra extends Record<string, unknown> = Record<string, never>> extends BriloBlockType {
17
+ supports?: BlockConfiguration['supports']
18
+ extraAttributes?: {
19
+ [K in keyof TExtra]: {
20
+ type: string
21
+ default: TExtra[K]
22
+ }
23
+ }
24
+ extraControls?: (props: BlockEditProps<BaseBlockAttributes & TExtra>) => ReactNode
25
+ exclude?: ExcludableBaseAttr[]
26
+ }
@@ -0,0 +1,3 @@
1
+ export const COLUMNS = [4, 3, 2] as const
2
+ export const RATIOS = ['4:3', '3:2', '16:9', '1:1', '2:1', '3:4'] as const
3
+ export const HEADING_LEVELS = [2, 3, 4] as const
@@ -0,0 +1,75 @@
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 {COLUMNS, HEADING_LEVELS, RATIOS} from './constants'
11
+ import type {SignpostGroupAttributes, SignpostGroupOptions} from './types'
12
+
13
+ export function createSignpostGroupEdit(options: SignpostGroupOptions) {
14
+ return function Edit({
15
+ attributes,
16
+ setAttributes,
17
+ }: {
18
+ attributes: SignpostGroupAttributes
19
+ setAttributes: (a: Partial<SignpostGroupAttributes>) => void
20
+ }) {
21
+ const {columns, headingLevel, ratio} = attributes
22
+
23
+ const {blockProps, innerBlocksProps} = useGroupBlock({
24
+ blockClassName: clsx(options.blockClassName ?? 'g-signpost wp-block-section'),
25
+ containerClassName: [options.containerClassName ?? 'u-grid-responsive', `--cols-${columns}`, `--ratio-${ratio.replace(':', '-')}`],
26
+ containerStyle: {'--grid-max-col-count': columns},
27
+ allowedBlocks: options.allowedBlocks,
28
+ orientation: 'horizontal',
29
+ template: options.template,
30
+ layout: {type: 'default'},
31
+ })
32
+
33
+ return (
34
+ <>
35
+ <InspectorControls>
36
+ <PanelBody title={__('Rozložení', 'brilo-blocks')}>
37
+ <ToggleGroupControl
38
+ isBlock
39
+ label={__('Počet sloupců', 'brilo-blocks')}
40
+ value={String(columns)}
41
+ onChange={(v) => setAttributes({columns: Number(v) as SignpostGroupAttributes['columns']})}
42
+ >
43
+ {COLUMNS.map((c) => (
44
+ <ToggleGroupControlOption key={c} value={String(c)} label={String(c)} />
45
+ ))}
46
+ </ToggleGroupControl>
47
+ <ToggleGroupControl
48
+ isBlock
49
+ label={__('Poměr stran', 'brilo-blocks')}
50
+ value={ratio}
51
+ onChange={(v) => setAttributes({ratio: v as string})}
52
+ >
53
+ {RATIOS.map((r) => (
54
+ <ToggleGroupControlOption key={r} value={r} label={r} />
55
+ ))}
56
+ </ToggleGroupControl>
57
+ <ToggleGroupControl
58
+ isBlock
59
+ label={__('Úroveň nadpisu položek', 'brilo-blocks')}
60
+ value={String(headingLevel)}
61
+ onChange={(v) => setAttributes({headingLevel: Number(v)})}
62
+ >
63
+ {HEADING_LEVELS.map((l) => (
64
+ <ToggleGroupControlOption key={l} value={String(l)} label={`H${l}`} />
65
+ ))}
66
+ </ToggleGroupControl>
67
+ </PanelBody>
68
+ </InspectorControls>
69
+ <div {...blockProps}>
70
+ <div {...innerBlocksProps} />
71
+ </div>
72
+ </>
73
+ )
74
+ }
75
+ }
File without changes
@@ -0,0 +1,40 @@
1
+ import {InnerBlocks} from '@wordpress/block-editor'
2
+ import type {BlockConfiguration} from '@wordpress/blocks'
3
+ import {__} from '@wordpress/i18n'
4
+ import {COLUMNS, HEADING_LEVELS, RATIOS} from './constants'
5
+ import {createSignpostGroupEdit} from './edit'
6
+ import {icon as defaultIcon} from './icon'
7
+ import type {SignpostGroupAttributes, SignpostGroupOptions} from './types'
8
+
9
+ export type {SignpostGroupAttributes, SignpostGroupOptions}
10
+
11
+ export function createSignpostGroupBlock(options: SignpostGroupOptions): BlockConfiguration<SignpostGroupAttributes> {
12
+ return {
13
+ name: options.name,
14
+ title: options.title ?? __('Rozcestník', '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
+ columns: {
22
+ type: 'number',
23
+ default: COLUMNS[1],
24
+ enum: [...COLUMNS],
25
+ },
26
+ ratio: {
27
+ type: 'string',
28
+ default: RATIOS[0],
29
+ enum: [...RATIOS],
30
+ },
31
+ headingLevel: {
32
+ type: 'number',
33
+ default: HEADING_LEVELS[0],
34
+ enum: [...HEADING_LEVELS],
35
+ },
36
+ },
37
+ edit: createSignpostGroupEdit(options),
38
+ save: () => <InnerBlocks.Content />,
39
+ } as unknown as BlockConfiguration<SignpostGroupAttributes>
40
+ }
@@ -0,0 +1,19 @@
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
+ <rect x="0.5" y="7.5" width="8" height="11" stroke="black" fill="none" />
4
+ <rect x="2.5" y="9.5" width="4" height="3" stroke="black" fill="none" />
5
+ <path d="M2 14H6V15H2V14Z" fill="black" />
6
+ <path d="M2 16H7V17H2V16Z" fill="black" />
7
+ <rect x="11.5" y="7.5" width="8" height="11" stroke="black" fill="none" />
8
+ <rect x="13.5" y="9.5" width="4" height="3" stroke="black" fill="none" />
9
+ <path d="M13 14H17V15H13V14Z" fill="black" />
10
+ <path d="M13 16H18V17H13V16Z" fill="black" />
11
+ <path d="M4 4H9V5H4V4Z" fill="black" />
12
+ <path d="M10 4H16V5H10V4Z" fill="black" />
13
+ <path
14
+ d="M12 2C12 1.44772 12.4477 1 13 1H14C14.5523 1 15 1.44772 15 2C15 2.55228 14.5523 3 14 3H13C12.4477 3 12 2.55228 12 2Z"
15
+ fill="black"
16
+ />
17
+ <path d="M5 2C5 1.44772 5.44772 1 6 1H10C10.5523 1 11 1.44772 11 2C11 2.55228 10.5523 3 10 3H6C5.44772 3 5 2.55228 5 2Z" fill="black" />
18
+ </svg>
19
+ )
@@ -0,0 +1,15 @@
1
+ export type {SignpostGroupAttributes, SignpostGroupOptions} from './types'
2
+ export {createSignpostGroupBlock} from './factory'
3
+
4
+ import type {SignpostGroupOptions} from './types'
5
+
6
+ export const signpostGroupDefaults: SignpostGroupOptions = {
7
+ name: 'brilo/signpost-group',
8
+ parent: ['brilo/base-section'],
9
+ allowedBlocks: ['brilo/signpost-item'],
10
+ template: [
11
+ ['brilo/signpost-item', {}],
12
+ ['brilo/signpost-item', {}],
13
+ ['brilo/signpost-item', {}],
14
+ ],
15
+ }
@@ -0,0 +1,9 @@
1
+ import {BriloBlockType} from '~/types'
2
+
3
+ export interface SignpostGroupAttributes extends Record<string, unknown> {
4
+ columns: number
5
+ headingLevel: number
6
+ ratio: string
7
+ }
8
+
9
+ export interface SignpostGroupOptions extends BriloBlockType {}
@@ -0,0 +1,4 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ // No item-specific constants yet, but file is required by anatomy
4
+ export {}
@@ -0,0 +1,90 @@
1
+ import {InspectorControls, RichText, useBlockProps} from '@wordpress/block-editor'
2
+ import {Button, PanelBody, TextControl, ToggleControl} from '@wordpress/components'
3
+ import {__} from '@wordpress/i18n'
4
+ import {ImagePickerControl} from '~/components/ImagePicker'
5
+ import type {SignpostItemAttributes, SignpostItemOptions} from './types'
6
+ import {useGroupBlock} from '~/hooks/useGroupBlock'
7
+ import clsx from 'clsx'
8
+
9
+ export function createSignpostItemEdit(options: SignpostItemOptions) {
10
+ return function Edit({
11
+ attributes,
12
+ setAttributes,
13
+ }: {
14
+ attributes: SignpostItemAttributes
15
+ setAttributes: (a: Partial<SignpostItemAttributes>) => void
16
+ }) {
17
+ const {title, img, button, url} = attributes
18
+
19
+ const {blockProps, innerBlocksProps} = useGroupBlock({
20
+ blockClassName: clsx(options.blockClassName ?? 'i-signpost'),
21
+ containerClassName: [options.containerClassName ?? 'i-signpost__content wp-block-inner-content'],
22
+ allowedBlocks: options.allowedBlocks,
23
+ orientation: 'vertical',
24
+ template: options.template,
25
+ layout: {type: 'default'},
26
+ })
27
+
28
+ return (
29
+ <>
30
+ <InspectorControls>
31
+ <PanelBody title={__('Obrázek', 'brilo-blocks')}>
32
+ <ImagePickerControl value={img} onChange={(val) => setAttributes({img: val})} />
33
+ </PanelBody>
34
+ <PanelBody title={__('Tlačítko', 'brilo-blocks')}>
35
+ <TextControl
36
+ label={__('Text tlačítka', 'brilo-blocks')}
37
+ value={button.text}
38
+ onChange={(v) => setAttributes({button: {...button, text: v}})}
39
+ />
40
+ </PanelBody>
41
+ <PanelBody title={__('Odkaz', 'brilo-blocks')} initialOpen={false}>
42
+ <TextControl label={__('URL', 'brilo-blocks')} value={url.src} onChange={(v) => setAttributes({url: {...url, src: v}})} />
43
+ <ToggleControl
44
+ label={__('Otevřít v nové záložce', 'brilo-blocks')}
45
+ checked={url.blank}
46
+ onChange={(v) => setAttributes({url: {...url, blank: v}})}
47
+ />
48
+ </PanelBody>
49
+ </InspectorControls>
50
+
51
+ <div {...blockProps}>
52
+ <div className="i-signpost__inner">
53
+ <div className="i-signpost__image-wrapper">
54
+ {img.id ? (
55
+ <ImagePickerControl value={img} onChange={(val) => setAttributes({img: val})} size={[128, 128]} />
56
+ ) : (
57
+ <div className="i-signpost__image-placeholder">
58
+ <ImagePickerControl value={img} onChange={(val) => setAttributes({img: val})} />
59
+ </div>
60
+ )}
61
+ </div>
62
+
63
+ <div className="i-signpost__body">
64
+ <RichText
65
+ tagName="h3"
66
+ className="i-signpost__title u-text-editable"
67
+ value={title}
68
+ onChange={(v) => setAttributes({title: v})}
69
+ placeholder={__('Nadpis...', 'brilo-blocks')}
70
+ allowedFormats={['core/bold', 'core/italic']}
71
+ />
72
+
73
+ <div {...innerBlocksProps} />
74
+
75
+ <Button variant={'primary'} className="i-signpost__button">
76
+ <RichText
77
+ tagName="span"
78
+ className="i-signpost__button-text"
79
+ value={button.text}
80
+ onChange={(v) => setAttributes({button: {...button, text: v}})}
81
+ placeholder={__('Text tlačítka...', 'brilo-blocks')}
82
+ />
83
+ </Button>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </>
88
+ )
89
+ }
90
+ }
@@ -0,0 +1,25 @@
1
+ @layer base {
2
+ .i-signpost {
3
+ width: 100%;
4
+ }
5
+
6
+ .i-signpost__inner {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: 8px;
10
+ padding: 12px;
11
+ border: 1px solid #eee;
12
+ border-radius: 4px;
13
+ }
14
+
15
+ .i-signpost__image-placeholder {
16
+ border: 1px dashed #0073aa;
17
+ padding: 16px 8px 8px;
18
+ }
19
+
20
+ .i-signpost__image-wrapper {
21
+ .c-image-picker-control__row {
22
+ flex-direction: column;
23
+ }
24
+ }
25
+ }