@brilo/base-blocks 0.1.58 → 0.1.61

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 (255) hide show
  1. package/build/.tsbuildinfo +1 -1
  2. package/build/blocks/anchor/anchor-group/icon.js +1 -1
  3. package/build/blocks/career/career-benefits/icon.js +1 -1
  4. package/build/blocks/career/career-header/icon.js +1 -1
  5. package/build/blocks/career/job-position-group/icon.js +1 -1
  6. package/build/blocks/column/column-item/edit.d.ts.map +1 -1
  7. package/build/blocks/column/column-item/index.d.ts.map +1 -1
  8. package/build/blocks/column/column-item/index.js +1 -0
  9. package/build/blocks/compare/compare-option/edit.d.ts +1 -1
  10. package/build/blocks/compare/compare-option/edit.d.ts.map +1 -1
  11. package/build/blocks/compare/compare-option/edit.js +1 -1
  12. package/build/blocks/contact/contact-item/factory.d.ts.map +1 -1
  13. package/build/blocks/document/documents-grid/icon.js +1 -1
  14. package/build/blocks/event/event-detail-content/icon.js +1 -1
  15. package/build/blocks/event/event-detail-header/icon.js +1 -1
  16. package/build/blocks/event/event-list-group/icon.js +1 -1
  17. package/build/blocks/faq/faq-item/edit.d.ts.map +1 -1
  18. package/build/blocks/faq/faq-item/edit.js +2 -2
  19. package/build/blocks/food-menu/food-menu-group/FoodMenuPreview.d.ts.map +1 -1
  20. package/build/blocks/food-menu/food-menu-group/FoodMenuPreview.js +36 -6
  21. package/build/blocks/food-menu/food-menu-group/constants.d.ts +51 -3
  22. package/build/blocks/food-menu/food-menu-group/constants.d.ts.map +1 -1
  23. package/build/blocks/food-menu/food-menu-group/constants.js +32 -6
  24. package/build/blocks/food-menu/food-menu-group/edit.d.ts.map +1 -1
  25. package/build/blocks/food-menu/food-menu-group/edit.js +61 -2
  26. package/build/blocks/food-menu/food-menu-group/factory.d.ts.map +1 -1
  27. package/build/blocks/food-menu/food-menu-group/factory.js +77 -45
  28. package/build/blocks/food-menu/food-menu-group/index.d.ts +1 -1
  29. package/build/blocks/food-menu/food-menu-group/index.d.ts.map +1 -1
  30. package/build/blocks/food-menu/food-menu-group/types.d.ts +12 -5
  31. package/build/blocks/food-menu/food-menu-group/types.d.ts.map +1 -1
  32. package/build/blocks/food-menu/food-reservation/edit.d.ts +7 -0
  33. package/build/blocks/food-menu/food-reservation/edit.d.ts.map +1 -0
  34. package/build/blocks/food-menu/food-reservation/edit.js +69 -0
  35. package/build/blocks/food-menu/food-reservation/factory.d.ts +4 -0
  36. package/build/blocks/food-menu/food-reservation/factory.d.ts.map +1 -0
  37. package/build/blocks/food-menu/food-reservation/factory.js +24 -0
  38. package/build/blocks/food-menu/food-reservation/icon.d.ts +2 -0
  39. package/build/blocks/food-menu/food-reservation/icon.d.ts.map +1 -0
  40. package/build/blocks/food-menu/food-reservation/icon.js +2 -0
  41. package/build/blocks/food-menu/food-reservation/index.d.ts +5 -0
  42. package/build/blocks/food-menu/food-reservation/index.d.ts.map +1 -0
  43. package/build/blocks/food-menu/food-reservation/index.js +6 -0
  44. package/build/blocks/food-menu/food-reservation/types.d.ts +7 -0
  45. package/build/blocks/food-menu/food-reservation/types.d.ts.map +1 -0
  46. package/build/blocks/food-menu/food-reservation/types.js +1 -0
  47. package/build/blocks/form/form-field/types.d.ts +1 -1
  48. package/build/blocks/form/form-field/types.d.ts.map +1 -1
  49. package/build/blocks/form/form-group/index.js +1 -1
  50. package/build/blocks/gallery/gallery-group/constants.d.ts +1 -19
  51. package/build/blocks/gallery/gallery-group/constants.d.ts.map +1 -1
  52. package/build/blocks/gallery/gallery-group/constants.js +1 -8
  53. package/build/blocks/gallery/gallery-group/edit.d.ts.map +1 -1
  54. package/build/blocks/gallery/gallery-group/edit.js +3 -19
  55. package/build/blocks/gallery/gallery-item/index.js +1 -1
  56. package/build/blocks/gallery/gallery-strip-group/constants.d.ts +34 -0
  57. package/build/blocks/gallery/gallery-strip-group/constants.d.ts.map +1 -0
  58. package/build/blocks/gallery/gallery-strip-group/constants.js +17 -0
  59. package/build/blocks/gallery/gallery-strip-group/edit.d.ts +7 -0
  60. package/build/blocks/gallery/gallery-strip-group/edit.d.ts.map +1 -0
  61. package/build/blocks/gallery/gallery-strip-group/edit.js +34 -0
  62. package/build/blocks/gallery/gallery-strip-group/factory.d.ts +5 -0
  63. package/build/blocks/gallery/gallery-strip-group/factory.d.ts.map +1 -0
  64. package/build/blocks/gallery/gallery-strip-group/factory.js +28 -0
  65. package/build/blocks/gallery/gallery-strip-group/index.d.ts +5 -0
  66. package/build/blocks/gallery/gallery-strip-group/index.d.ts.map +1 -0
  67. package/build/blocks/gallery/gallery-strip-group/index.js +7 -0
  68. package/build/blocks/gallery/gallery-strip-group/types.d.ts +18 -0
  69. package/build/blocks/gallery/gallery-strip-group/types.d.ts.map +1 -0
  70. package/build/blocks/gallery/gallery-strip-group/types.js +1 -0
  71. package/build/blocks/groups/banner-group/icon.js +1 -1
  72. package/build/blocks/groups/content-group/icon.js +1 -1
  73. package/build/blocks/groups/text-and-media-group/index.d.ts.map +1 -1
  74. package/build/blocks/groups/text-and-media-group/index.js +2 -0
  75. package/build/blocks/hero/hero-group/edit.js +1 -1
  76. package/build/blocks/hero/hero-group/icon.js +1 -1
  77. package/build/blocks/hero/hero-group/types.d.ts +1 -1
  78. package/build/blocks/hero/hero-group/types.d.ts.map +1 -1
  79. package/build/blocks/hero/hero-item/edit.js +1 -1
  80. package/build/blocks/hero/hero-item/index.js +1 -1
  81. package/build/blocks/layout/box/icon.js +1 -1
  82. package/build/blocks/layout/layout-aside/edit.d.ts +1 -2
  83. package/build/blocks/layout/layout-aside/edit.d.ts.map +1 -1
  84. package/build/blocks/layout/layout-aside/edit.js +1 -1
  85. package/build/blocks/layout/layout-aside/factory.d.ts.map +1 -1
  86. package/build/blocks/layout/layout-aside/icon.d.ts +1 -2
  87. package/build/blocks/layout/layout-aside/icon.d.ts.map +1 -1
  88. package/build/blocks/layout/layout-aside/icon.js +1 -1
  89. package/build/blocks/layout/layout-content/edit.d.ts +1 -2
  90. package/build/blocks/layout/layout-content/edit.d.ts.map +1 -1
  91. package/build/blocks/layout/layout-content/edit.js +1 -1
  92. package/build/blocks/layout/layout-content/factory.d.ts.map +1 -1
  93. package/build/blocks/layout/layout-content/icon.d.ts +1 -2
  94. package/build/blocks/layout/layout-content/icon.d.ts.map +1 -1
  95. package/build/blocks/layout/layout-content/icon.js +1 -1
  96. package/build/blocks/layout/layout-content-w-aside/edit.d.ts +1 -2
  97. package/build/blocks/layout/layout-content-w-aside/edit.d.ts.map +1 -1
  98. package/build/blocks/layout/layout-content-w-aside/factory.d.ts.map +1 -1
  99. package/build/blocks/layout/layout-content-w-aside/icon.d.ts +1 -2
  100. package/build/blocks/layout/layout-content-w-aside/icon.d.ts.map +1 -1
  101. package/build/blocks/layout/layout-content-w-aside/icon.js +1 -1
  102. package/build/blocks/link/link-item/icon.js +1 -1
  103. package/build/blocks/map/map-group/edit.d.ts.map +1 -1
  104. package/build/blocks/map/map-group/edit.js +1 -1
  105. package/build/blocks/map/map-group/factory.d.ts.map +1 -1
  106. package/build/blocks/map/map-group/types.d.ts.map +1 -1
  107. package/build/blocks/newsletter/newsletter-form/edit.d.ts.map +1 -1
  108. package/build/blocks/newsletter/newsletter-form/edit.js +2 -1
  109. package/build/blocks/person/person-group/icon.js +1 -1
  110. package/build/blocks/person/person-item/constants.d.ts.map +1 -1
  111. package/build/blocks/post/post-content/icon.js +1 -1
  112. package/build/blocks/post/post-content/types.d.ts.map +1 -1
  113. package/build/blocks/post/post-slider-group/icon.js +1 -1
  114. package/build/blocks/post/posts-grid/icon.js +1 -1
  115. package/build/blocks/review/review-summary-item/constants.d.ts +3 -0
  116. package/build/blocks/review/review-summary-item/constants.d.ts.map +1 -0
  117. package/build/blocks/review/review-summary-item/constants.js +2 -0
  118. package/build/blocks/review/review-summary-item/edit.d.ts +6 -0
  119. package/build/blocks/review/review-summary-item/edit.d.ts.map +1 -0
  120. package/build/blocks/review/review-summary-item/edit.js +17 -0
  121. package/build/blocks/review/review-summary-item/factory.d.ts +5 -0
  122. package/build/blocks/review/review-summary-item/factory.d.ts.map +1 -0
  123. package/build/blocks/review/review-summary-item/factory.js +23 -0
  124. package/build/blocks/review/review-summary-item/index.d.ts +5 -0
  125. package/build/blocks/review/review-summary-item/index.d.ts.map +1 -0
  126. package/build/blocks/review/review-summary-item/index.js +5 -0
  127. package/build/blocks/review/review-summary-item/types.d.ts +11 -0
  128. package/build/blocks/review/review-summary-item/types.d.ts.map +1 -0
  129. package/build/blocks/review/review-summary-item/types.js +1 -0
  130. package/build/blocks/share/share/icon.js +1 -1
  131. package/build/blocks/signpost/signpost-group/icon.js +1 -1
  132. package/build/blocks/step/step-group/factory.d.ts.map +1 -1
  133. package/build/blocks/step/step-group/icon.js +1 -1
  134. package/build/blocks/testimonial/testimonial-group/icon.js +1 -1
  135. package/build/blocks/urgency/urgency-item/constants.d.ts +56 -0
  136. package/build/blocks/urgency/urgency-item/constants.d.ts.map +1 -0
  137. package/build/blocks/urgency/urgency-item/constants.js +32 -0
  138. package/build/blocks/urgency/urgency-item/edit.d.ts +7 -0
  139. package/build/blocks/urgency/urgency-item/edit.d.ts.map +1 -0
  140. package/build/blocks/urgency/urgency-item/edit.js +83 -0
  141. package/build/blocks/urgency/urgency-item/factory.d.ts +5 -0
  142. package/build/blocks/urgency/urgency-item/factory.d.ts.map +1 -0
  143. package/build/blocks/urgency/urgency-item/factory.js +31 -0
  144. package/build/blocks/urgency/urgency-item/index.d.ts +5 -0
  145. package/build/blocks/urgency/urgency-item/index.d.ts.map +1 -0
  146. package/build/blocks/urgency/urgency-item/index.js +5 -0
  147. package/build/blocks/urgency/urgency-item/types.d.ts +22 -0
  148. package/build/blocks/urgency/urgency-item/types.d.ts.map +1 -0
  149. package/build/blocks/urgency/urgency-item/types.js +1 -0
  150. package/build/components/GalleryImagesAppender/index.d.ts +5 -0
  151. package/build/components/GalleryImagesAppender/index.d.ts.map +1 -0
  152. package/build/components/GalleryImagesAppender/index.js +12 -0
  153. package/build/components/ImagePicker/ImagePicker.d.ts.map +1 -1
  154. package/build/components/ImagePicker/ImagePicker.js +1 -5
  155. package/build/constants.d.ts +19 -0
  156. package/build/constants.d.ts.map +1 -1
  157. package/build/constants.js +8 -0
  158. package/build/hooks/useGroupBlock.d.ts.map +1 -1
  159. package/build/hooks/useGroupBlock.js +10 -3
  160. package/build/index.d.ts +8 -0
  161. package/build/index.d.ts.map +1 -1
  162. package/build/index.js +4 -0
  163. package/package.json +4 -3
  164. package/src/blocks/anchor/anchor-group/icon.tsx +1 -1
  165. package/src/blocks/career/career-benefits/icon.tsx +1 -1
  166. package/src/blocks/career/career-header/icon.tsx +1 -1
  167. package/src/blocks/career/job-position-group/icon.tsx +1 -1
  168. package/src/blocks/column/column-item/edit.tsx +0 -1
  169. package/src/blocks/column/column-item/index.ts +1 -0
  170. package/src/blocks/compare/compare-option/edit.tsx +1 -1
  171. package/src/blocks/contact/contact-item/factory.tsx +1 -2
  172. package/src/blocks/document/documents-grid/icon.tsx +1 -1
  173. package/src/blocks/event/event-detail-content/icon.tsx +1 -1
  174. package/src/blocks/event/event-detail-header/icon.tsx +1 -1
  175. package/src/blocks/event/event-list-group/icon.tsx +1 -1
  176. package/src/blocks/faq/faq-item/edit.tsx +23 -25
  177. package/src/blocks/food-menu/food-menu-group/FoodMenuPreview.tsx +58 -9
  178. package/src/blocks/food-menu/food-menu-group/constants.ts +37 -6
  179. package/src/blocks/food-menu/food-menu-group/edit.tsx +116 -20
  180. package/src/blocks/food-menu/food-menu-group/editor.scss +35 -6
  181. package/src/blocks/food-menu/food-menu-group/factory.tsx +77 -39
  182. package/src/blocks/food-menu/food-menu-group/index.ts +2 -0
  183. package/src/blocks/food-menu/food-menu-group/types.ts +18 -5
  184. package/src/blocks/food-menu/food-reservation/edit.tsx +179 -0
  185. package/src/blocks/food-menu/food-reservation/factory.tsx +28 -0
  186. package/src/blocks/food-menu/food-reservation/icon.tsx +9 -0
  187. package/src/blocks/food-menu/food-reservation/index.ts +10 -0
  188. package/src/blocks/food-menu/food-reservation/types.ts +8 -0
  189. package/src/blocks/form/form-field/types.ts +1 -7
  190. package/src/blocks/form/form-group/index.ts +1 -1
  191. package/src/blocks/gallery/gallery-group/constants.ts +1 -8
  192. package/src/blocks/gallery/gallery-group/edit.tsx +3 -39
  193. package/src/blocks/gallery/gallery-group/editor.scss +0 -12
  194. package/src/blocks/gallery/gallery-item/index.ts +1 -1
  195. package/src/blocks/gallery/gallery-strip-group/constants.ts +22 -0
  196. package/src/blocks/gallery/gallery-strip-group/edit.tsx +112 -0
  197. package/src/blocks/gallery/gallery-strip-group/editor.scss +36 -0
  198. package/src/blocks/gallery/gallery-strip-group/factory.tsx +32 -0
  199. package/src/blocks/gallery/gallery-strip-group/index.ts +11 -0
  200. package/src/blocks/gallery/gallery-strip-group/types.ts +20 -0
  201. package/src/blocks/groups/banner-group/edit.tsx +1 -1
  202. package/src/blocks/groups/banner-group/icon.tsx +1 -1
  203. package/src/blocks/groups/content-group/icon.tsx +1 -1
  204. package/src/blocks/groups/text-and-media-group/index.ts +2 -0
  205. package/src/blocks/hero/hero-group/edit.tsx +3 -3
  206. package/src/blocks/hero/hero-group/icon.tsx +1 -1
  207. package/src/blocks/hero/hero-group/types.ts +1 -1
  208. package/src/blocks/hero/hero-item/edit.tsx +5 -5
  209. package/src/blocks/hero/hero-item/index.ts +1 -1
  210. package/src/blocks/layout/box/icon.tsx +1 -1
  211. package/src/blocks/layout/layout-aside/edit.tsx +2 -3
  212. package/src/blocks/layout/layout-aside/factory.tsx +0 -1
  213. package/src/blocks/layout/layout-aside/icon.tsx +1 -3
  214. package/src/blocks/layout/layout-content/edit.tsx +2 -3
  215. package/src/blocks/layout/layout-content/factory.tsx +0 -1
  216. package/src/blocks/layout/layout-content/icon.tsx +1 -3
  217. package/src/blocks/layout/layout-content-w-aside/edit.tsx +0 -1
  218. package/src/blocks/layout/layout-content-w-aside/factory.tsx +0 -1
  219. package/src/blocks/layout/layout-content-w-aside/icon.tsx +1 -3
  220. package/src/blocks/link/link-item/icon.tsx +1 -1
  221. package/src/blocks/map/map-group/edit.tsx +8 -3
  222. package/src/blocks/map/map-group/factory.tsx +1 -1
  223. package/src/blocks/map/map-group/types.ts +1 -1
  224. package/src/blocks/newsletter/newsletter-form/edit.tsx +5 -2
  225. package/src/blocks/person/person-group/icon.tsx +1 -1
  226. package/src/blocks/person/person-item/constants.ts +1 -1
  227. package/src/blocks/post/post-content/icon.tsx +1 -1
  228. package/src/blocks/post/post-content/types.ts +0 -1
  229. package/src/blocks/post/post-slider-group/icon.tsx +1 -1
  230. package/src/blocks/post/posts-grid/icon.tsx +1 -1
  231. package/src/blocks/review/review-summary-item/constants.ts +2 -0
  232. package/src/blocks/review/review-summary-item/edit.tsx +86 -0
  233. package/src/blocks/review/review-summary-item/editor.scss +44 -0
  234. package/src/blocks/review/review-summary-item/factory.tsx +27 -0
  235. package/src/blocks/review/review-summary-item/index.ts +9 -0
  236. package/src/blocks/review/review-summary-item/types.ts +11 -0
  237. package/src/blocks/share/share/icon.tsx +1 -1
  238. package/src/blocks/signpost/signpost-group/icon.tsx +1 -1
  239. package/src/blocks/step/step-group/factory.tsx +1 -1
  240. package/src/blocks/step/step-group/icon.tsx +1 -1
  241. package/src/blocks/testimonial/testimonial-group/icon.tsx +1 -1
  242. package/src/blocks/urgency/urgency-item/constants.ts +39 -0
  243. package/src/blocks/urgency/urgency-item/edit.tsx +319 -0
  244. package/src/blocks/urgency/urgency-item/editor.scss +99 -0
  245. package/src/blocks/urgency/urgency-item/factory.tsx +36 -0
  246. package/src/blocks/urgency/urgency-item/index.ts +9 -0
  247. package/src/blocks/urgency/urgency-item/types.ts +23 -0
  248. package/src/components/GalleryImagesAppender/editor.scss +15 -0
  249. package/src/components/GalleryImagesAppender/index.tsx +29 -0
  250. package/src/components/ImagePicker/ImagePicker.tsx +6 -6
  251. package/src/components/ItemIconControl/types.d.ts +0 -1
  252. package/src/constants.ts +9 -0
  253. package/src/editor.scss +4 -0
  254. package/src/hooks/useGroupBlock.ts +10 -2
  255. package/src/index.ts +8 -0
@@ -0,0 +1,86 @@
1
+ import {InspectorControls, RichText, useBlockProps} from '@wordpress/block-editor'
2
+ import {PanelBody, RangeControl, TextControl, ToggleControl} from '@wordpress/components'
3
+ import {__} from '@wordpress/i18n'
4
+ import clsx from 'clsx'
5
+ import type {CSSProperties} from 'react'
6
+ import {RATING_MAX, RATING_STEP} from './constants'
7
+ import type {ReviewSummaryItemAttributes, ReviewSummaryItemOptions} from './types'
8
+
9
+ const roundToHalf = (value: number) => Math.round(value * 2) / 2
10
+
11
+ export function createReviewSummaryItemEdit(options: ReviewSummaryItemOptions) {
12
+ return function Edit({
13
+ attributes,
14
+ setAttributes,
15
+ }: {
16
+ attributes: ReviewSummaryItemAttributes
17
+ setAttributes: (a: Partial<ReviewSummaryItemAttributes>) => void
18
+ }) {
19
+ const {rating, count, countLabel, showMax, description} = attributes
20
+ const hasRating = typeof rating === 'number'
21
+ const hasCount = typeof count === 'number' && count > 0
22
+
23
+ const blockProps = useBlockProps({className: clsx(options.blockClassName ?? 'i-review-summary-item wp-block-section')})
24
+
25
+ return (
26
+ <>
27
+ <InspectorControls>
28
+ <PanelBody title={__('Hodnocení', 'brilo-blocks')}>
29
+ <RangeControl
30
+ label={__('Průměrné hodnocení', 'brilo-blocks')}
31
+ help={__('Bez hodnoty se hvězdičky ani číslo nezobrazí.', 'brilo-blocks')}
32
+ value={rating}
33
+ onChange={(v) => setAttributes({rating: v})}
34
+ min={0}
35
+ max={RATING_MAX}
36
+ step={RATING_STEP}
37
+ allowReset
38
+ withInputField
39
+ />
40
+ <ToggleControl label={__('Zobrazit „/ 5"', 'brilo-blocks')} checked={showMax} onChange={(v) => setAttributes({showMax: v})} />
41
+ <TextControl
42
+ type="number"
43
+ min={0}
44
+ label={__('Počet recenzí', 'brilo-blocks')}
45
+ help={__('Při nule nebo prázdné hodnotě se počet nezobrazí.', 'brilo-blocks')}
46
+ value={typeof count === 'number' ? String(count) : ''}
47
+ onChange={(v) => setAttributes({count: v === '' ? undefined : Math.max(0, Number.parseInt(v, 10) || 0)})}
48
+ />
49
+ <TextControl label={__('Popisek počtu', 'brilo-blocks')} value={countLabel} onChange={(v) => setAttributes({countLabel: v})} />
50
+ </PanelBody>
51
+ </InspectorControls>
52
+
53
+ <div {...blockProps}>
54
+ <div className="i-review-summary-item__score">
55
+ {hasRating && (
56
+ <>
57
+ <span
58
+ className="i-review-summary-item__stars"
59
+ style={{'--rating-fill': `${(roundToHalf(rating) / RATING_MAX) * 100}%`} as CSSProperties}
60
+ >
61
+ ★★★★★
62
+ </span>
63
+ <strong className="i-review-summary-item__value">
64
+ {rating.toLocaleString(undefined, {minimumFractionDigits: 1, maximumFractionDigits: 1})}
65
+ {showMax && ` / ${RATING_MAX}`}
66
+ </strong>
67
+ </>
68
+ )}
69
+ {hasCount && <span className="i-review-summary-item__count">{`${count} ${countLabel}`}</span>}
70
+ {!hasRating && !hasCount && (
71
+ <span className="i-review-summary-item__placeholder">{__('Nastavte hodnocení v postranním panelu', 'brilo-blocks')}</span>
72
+ )}
73
+ </div>
74
+ <RichText
75
+ tagName="p"
76
+ className="i-review-summary-item__description u-text-editable"
77
+ value={description}
78
+ onChange={(v) => setAttributes({description: v})}
79
+ placeholder={__('Popis hodnocení...', 'brilo-blocks')}
80
+ allowedFormats={['core/bold', 'core/italic', 'core/link', 'brilo-blocks/text-color']}
81
+ />
82
+ </div>
83
+ </>
84
+ )
85
+ }
86
+ }
@@ -0,0 +1,44 @@
1
+ .i-review-summary-item {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 8px;
5
+ }
6
+
7
+ .i-review-summary-item__score {
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+ align-items: center;
11
+ gap: 8px;
12
+ }
13
+
14
+ .i-review-summary-item__stars {
15
+ position: relative;
16
+ display: inline-block;
17
+ font-size: 20px;
18
+ line-height: 1;
19
+ letter-spacing: 2px;
20
+ color: #d0d5dd;
21
+
22
+ &::before {
23
+ content: "★★★★★";
24
+ position: absolute;
25
+ inset: 0;
26
+ width: var(--rating-fill, 0%);
27
+ overflow: hidden;
28
+ color: #1e2d45;
29
+ }
30
+ }
31
+
32
+ .i-review-summary-item__value {
33
+ font-size: 18px;
34
+ }
35
+
36
+ .i-review-summary-item__count,
37
+ .i-review-summary-item__placeholder {
38
+ font-size: 14px;
39
+ color: #50575e;
40
+ }
41
+
42
+ .i-review-summary-item__description {
43
+ margin: 0;
44
+ }
@@ -0,0 +1,27 @@
1
+ import type {BlockConfiguration} from '@wordpress/blocks'
2
+ import {__} from '@wordpress/i18n'
3
+ import {createReviewSummaryItemEdit} from './edit'
4
+ import type {ReviewSummaryItemAttributes, ReviewSummaryItemOptions} from './types'
5
+
6
+ export type {ReviewSummaryItemAttributes, ReviewSummaryItemOptions}
7
+
8
+ export function createReviewSummaryItemBlock(options: ReviewSummaryItemOptions): BlockConfiguration<ReviewSummaryItemAttributes> {
9
+ return {
10
+ name: options.name,
11
+ title: options.title ?? __('Souhrn hodnocení', 'brilo-blocks'),
12
+ description: options.description ?? __('Průměrné hodnocení hvězdičkami s počtem recenzí a popisem', 'brilo-blocks'),
13
+ category: options.category ?? 'layout',
14
+ ...(options.parent && {parent: options.parent}),
15
+ icon: options.icon ?? 'star-half',
16
+ supports: {html: false, customClassName: false},
17
+ attributes: {
18
+ rating: {type: 'number'},
19
+ count: {type: 'number'},
20
+ countLabel: {type: 'string', default: __('hodnocení', 'brilo-blocks')},
21
+ showMax: {type: 'boolean', default: false},
22
+ description: {type: 'string', default: ''},
23
+ },
24
+ edit: createReviewSummaryItemEdit(options),
25
+ save: () => null,
26
+ } as unknown as BlockConfiguration<ReviewSummaryItemAttributes>
27
+ }
@@ -0,0 +1,9 @@
1
+ export type {ReviewSummaryItemAttributes, ReviewSummaryItemOptions} from './types'
2
+ export {createReviewSummaryItemBlock} from './factory'
3
+
4
+ import type {ReviewSummaryItemOptions} from './types'
5
+
6
+ export const reviewSummaryItemDefaults: ReviewSummaryItemOptions = {
7
+ name: 'brilo/review-summary-item',
8
+ parent: ['brilo/base-section', 'brilo/text-and-media-group', 'brilo/hero-item'],
9
+ }
@@ -0,0 +1,11 @@
1
+ import type {BriloBlockType} from '~/types'
2
+
3
+ export interface ReviewSummaryItemAttributes extends Record<string, unknown> {
4
+ rating?: number
5
+ count?: number
6
+ countLabel: string
7
+ showMax: boolean
8
+ description: string
9
+ }
10
+
11
+ export interface ReviewSummaryItemOptions extends BriloBlockType {}
@@ -1,5 +1,5 @@
1
1
  export const icon = (
2
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
3
3
  <circle cx="5" cy="10" r="2" stroke="black" fill="none" />
4
4
  <circle cx="15" cy="4" r="2" stroke="black" fill="none" />
5
5
  <circle cx="15" cy="16" r="2" stroke="black" fill="none" />
@@ -1,5 +1,5 @@
1
1
  export const icon = (
2
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
3
3
  <rect x="0.5" y="7.5" width="8" height="11" stroke="black" fill="none" />
4
4
  <rect x="2.5" y="9.5" width="4" height="3" stroke="black" fill="none" />
5
5
  <path d="M2 14H6V15H2V14Z" fill="black" />
@@ -1,7 +1,7 @@
1
1
  import {InnerBlocks} from '@wordpress/block-editor'
2
2
  import type {BlockConfiguration} from '@wordpress/blocks'
3
3
  import {__} from '@wordpress/i18n'
4
- import {DEFAULT_ICON_BACKGROUND_SIZE, DEFAULT_ICON_SIZE, DEFAULT_SHADOWS, DEFAULT_VARIANTS, TEXT_ALIGNS} from './constants'
4
+ import {DEFAULT_ICON_BACKGROUND_SIZE, DEFAULT_SHADOWS, DEFAULT_VARIANTS, TEXT_ALIGNS} from './constants'
5
5
  import {createStepGroupEdit} from './edit'
6
6
  import type {StepGroupAttributes, StepGroupOptions} from './types'
7
7
  import {icon} from '~/blocks/step/step-group/icon'
@@ -1,5 +1,5 @@
1
1
  export const icon = (
2
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
3
3
  <path d="M4 6H7V7H4V6Z" fill="black" />
4
4
  <path d="M12 6H15V7H12V6Z" fill="black" />
5
5
  <path
@@ -1,5 +1,5 @@
1
1
  export const icon = (
2
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
3
3
  <path d="M4 4H9V5H4V4Z" fill="black" />
4
4
  <path d="M10 4H16V5H10V4Z" fill="black" />
5
5
  <path
@@ -0,0 +1,39 @@
1
+ import {__} from '@wordpress/i18n'
2
+
3
+ export {CONTENT_SIZES as TEXT_SIZES} from '~/constants'
4
+
5
+ export const TYPES = [
6
+ {value: 'deadline', label: __('Termín', 'brilo-blocks')},
7
+ {value: 'capacity', label: __('Volná místa', 'brilo-blocks')},
8
+ {value: 'season', label: __('Sezóna', 'brilo-blocks')},
9
+ ] as const
10
+
11
+ export const DEADLINE_DISPLAYS = [
12
+ {value: 'countdown', label: __('Odpočet', 'brilo-blocks')},
13
+ {value: 'date', label: __('Datum', 'brilo-blocks')},
14
+ ] as const
15
+
16
+ export const TEXTS = {
17
+ countdown: __('Nabídka končí za', 'brilo-blocks'),
18
+ date: __('Nabídka platí do', 'brilo-blocks'),
19
+ capacity: __('Zbývá volných míst', 'brilo-blocks'),
20
+ season: __('Nabídka platí pouze tuto sezónu', 'brilo-blocks'),
21
+ } as const
22
+
23
+ export const COUNTDOWN_UNITS = [
24
+ {key: 'days', label: __('dní', 'brilo-blocks')},
25
+ {key: 'hours', label: __('hod', 'brilo-blocks')},
26
+ {key: 'minutes', label: __('min', 'brilo-blocks')},
27
+ {key: 'seconds', label: __('sek', 'brilo-blocks')},
28
+ ] as const
29
+
30
+ export const NUMBER_SIZE_MIN = 16
31
+ export const NUMBER_SIZE_MAX = 120
32
+
33
+ export const NUMBER_SIZE_PRESETS = [
34
+ {value: 32, label: __('XS', 'brilo-blocks')},
35
+ {value: 40, label: __('SM', 'brilo-blocks')},
36
+ {value: 48, label: __('MD', 'brilo-blocks')},
37
+ {value: 60, label: __('LG', 'brilo-blocks')},
38
+ {value: 72, label: __('XL', 'brilo-blocks')},
39
+ ] as const
@@ -0,0 +1,319 @@
1
+ import {InspectorControls, useBlockProps} from '@wordpress/block-editor'
2
+ import {
3
+ BaseControl,
4
+ Button,
5
+ ColorPalette,
6
+ DateTimePicker,
7
+ Notice,
8
+ PanelBody,
9
+ RangeControl,
10
+ TextControl,
11
+ __experimentalToggleGroupControl as ToggleGroupControl,
12
+ __experimentalToggleGroupControlOption as ToggleGroupControlOption,
13
+ } from '@wordpress/components'
14
+ import {useDispatch} from '@wordpress/data'
15
+ import {dateI18n, getDate, getSettings} from '@wordpress/date'
16
+ import {__} from '@wordpress/i18n'
17
+ import clsx from 'clsx'
18
+ import {type CSSProperties, useEffect} from 'react'
19
+ import {useTenantColorPalette} from '~/hooks/useTenantColorPalette'
20
+ import {
21
+ COUNTDOWN_UNITS,
22
+ DEADLINE_DISPLAYS,
23
+ TEXTS,
24
+ NUMBER_SIZE_MAX,
25
+ NUMBER_SIZE_MIN,
26
+ NUMBER_SIZE_PRESETS,
27
+ TEXT_SIZES,
28
+ TYPES,
29
+ } from './constants'
30
+ import type {UrgencyDeadlineDisplay, UrgencyItemAttributes, UrgencyItemOptions, UrgencyTextSize, UrgencyType} from './types'
31
+
32
+ const TEXT_VALUES: string[] = Object.values(TEXTS)
33
+
34
+ function defaultTextFor(type: UrgencyType, display: UrgencyDeadlineDisplay): string {
35
+ return type === 'deadline' ? TEXTS[display] : TEXTS[type]
36
+ }
37
+
38
+ function parseCount(value: string): number | undefined {
39
+ return value === '' ? undefined : Math.max(0, Number.parseInt(value, 10) || 0)
40
+ }
41
+
42
+ function countdownParts(milliseconds: number): Record<(typeof COUNTDOWN_UNITS)[number]['key'], string> {
43
+ const totalSeconds = Math.max(0, Math.floor(milliseconds / 1000))
44
+ const pad = (n: number) => String(n).padStart(2, '0')
45
+
46
+ return {
47
+ days: pad(Math.floor(totalSeconds / 86400)),
48
+ hours: pad(Math.floor((totalSeconds % 86400) / 3600)),
49
+ minutes: pad(Math.floor((totalSeconds % 3600) / 60)),
50
+ seconds: pad(totalSeconds % 60),
51
+ }
52
+ }
53
+
54
+ function formatDeadline(deadline: string): string {
55
+ const {formats} = getSettings()
56
+ const time = deadline.slice(11, 16)
57
+ const format = time === '00:00' || time === '23:59' ? formats.date : `${formats.date} ${formats.time}`
58
+
59
+ return dateI18n(format, getDate(deadline))
60
+ }
61
+
62
+ function endOfDay(date: string): number {
63
+ return getDate(`${date}T23:59:59`).getTime()
64
+ }
65
+
66
+ function ColorControl({label, id, value, onChange}: {label: string; id: string; value: string; onChange: (v: string) => void}) {
67
+ const {paletteColors} = useTenantColorPalette()
68
+
69
+ return (
70
+ <BaseControl label={label} id={id}>
71
+ <ColorPalette colors={paletteColors} value={value || undefined} onChange={(v) => onChange(v ?? '')} />
72
+ </BaseControl>
73
+ )
74
+ }
75
+
76
+ function NumberSizeControl({value, onChange}: {value?: number; onChange: (v?: number) => void}) {
77
+ return (
78
+ <BaseControl
79
+ label={__('Velikost čísel (px)', 'brilo-blocks')}
80
+ help={__('Bez nastavení se použije velikost nadpisu ze šablony.', 'brilo-blocks')}
81
+ id="urgency-item-number-size"
82
+ >
83
+ <div className="i-urgency__number-presets">
84
+ {NUMBER_SIZE_PRESETS.map((p) => (
85
+ <Button key={p.label} variant={value === p.value ? 'primary' : 'secondary'} size="small" onClick={() => onChange(p.value)}>
86
+ {p.label}
87
+ </Button>
88
+ ))}
89
+ </div>
90
+ <RangeControl value={value} onChange={onChange} min={NUMBER_SIZE_MIN} max={NUMBER_SIZE_MAX} step={1} withInputField allowReset />
91
+ </BaseControl>
92
+ )
93
+ }
94
+
95
+ export function createUrgencyItemEdit(options: UrgencyItemOptions) {
96
+ return function Edit({
97
+ attributes,
98
+ setAttributes,
99
+ clientId,
100
+ }: {
101
+ attributes: UrgencyItemAttributes
102
+ setAttributes: (a: Partial<UrgencyItemAttributes>) => void
103
+ clientId: string
104
+ }) {
105
+ const {
106
+ type,
107
+ text,
108
+ deadline,
109
+ display,
110
+ remaining,
111
+ total,
112
+ endDate,
113
+ textSize,
114
+ numberSize,
115
+ backgroundColor,
116
+ numberBackgroundColor,
117
+ textColor,
118
+ } = attributes
119
+ // core/editor is missing outside the post editor (widgets, site editor) – dispatch returns undefined there.
120
+ const editorDispatch = useDispatch('core/editor') as unknown as
121
+ | {lockPostSaving: (lockName: string) => void; unlockPostSaving: (lockName: string) => void}
122
+ | undefined
123
+ const lockPostSaving = editorDispatch?.lockPostSaving
124
+ const unlockPostSaving = editorDispatch?.unlockPostSaving
125
+
126
+ const isDeadlineMissing = type === 'deadline' && !deadline
127
+ const isCapacityMissing = type === 'capacity' && (typeof remaining !== 'number' || typeof total !== 'number' || total <= 0)
128
+ const expiresAt =
129
+ type === 'deadline' && deadline ? getDate(deadline).getTime() : type === 'season' && endDate ? endOfDay(endDate) : null
130
+ const isExpired = expiresAt !== null && expiresAt <= Date.now()
131
+
132
+ useEffect(() => {
133
+ if (!lockPostSaving || !unlockPostSaving) {
134
+ return
135
+ }
136
+
137
+ const lockName = `brilo-urgency-item-${clientId}`
138
+
139
+ if (isDeadlineMissing || isCapacityMissing) {
140
+ lockPostSaving(lockName)
141
+ } else {
142
+ unlockPostSaving(lockName)
143
+ }
144
+
145
+ return () => unlockPostSaving(lockName)
146
+ }, [clientId, isDeadlineMissing, isCapacityMissing, lockPostSaving, unlockPostSaving])
147
+
148
+ const switchText = (nextType: UrgencyType, nextDisplay: UrgencyDeadlineDisplay) =>
149
+ !text || TEXT_VALUES.includes(text) ? {text: defaultTextFor(nextType, nextDisplay)} : {}
150
+
151
+ const countdown = countdownParts(deadline ? getDate(deadline).getTime() - Date.now() : 0)
152
+ const takenPercent =
153
+ type === 'capacity' && total ? Math.min(100, Math.max(0, ((total - Math.min(remaining ?? total, total)) / total) * 100)) : 0
154
+
155
+ const blockProps = useBlockProps({className: clsx(options.blockClassName ?? 'i-urgency wp-block-section', `--${type}`)})
156
+ const isCountdown = type === 'deadline' && display === 'countdown'
157
+ const cardStyle = {
158
+ color: textColor || undefined,
159
+ '--urgency-background': backgroundColor || undefined,
160
+ '--urgency-number-background': numberBackgroundColor || undefined,
161
+ '--urgency-text-color': textColor || undefined,
162
+ '--urgency-number-size': numberSize ? `${numberSize}px` : undefined,
163
+ } as CSSProperties
164
+
165
+ return (
166
+ <>
167
+ <InspectorControls>
168
+ <PanelBody title={__('Nastavení', 'brilo-blocks')}>
169
+ <ToggleGroupControl
170
+ isBlock
171
+ label={__('Co zobrazit', 'brilo-blocks')}
172
+ value={type}
173
+ onChange={(v) => setAttributes({type: v as UrgencyType, ...switchText(v as UrgencyType, display)})}
174
+ >
175
+ {TYPES.map((t) => (
176
+ <ToggleGroupControlOption key={t.value} value={t.value} label={t.label} />
177
+ ))}
178
+ </ToggleGroupControl>
179
+ <TextControl
180
+ label={__('Text', 'brilo-blocks')}
181
+ value={text}
182
+ placeholder={defaultTextFor(type, display)}
183
+ onChange={(v) => setAttributes({text: v})}
184
+ />
185
+ </PanelBody>
186
+
187
+ {type === 'deadline' && (
188
+ <PanelBody title={__('Termín', 'brilo-blocks')}>
189
+ <ToggleGroupControl
190
+ isBlock
191
+ label={__('Zobrazit jako', 'brilo-blocks')}
192
+ value={display}
193
+ onChange={(v) => setAttributes({display: v as UrgencyDeadlineDisplay, ...switchText(type, v as UrgencyDeadlineDisplay)})}
194
+ >
195
+ {DEADLINE_DISPLAYS.map((d) => (
196
+ <ToggleGroupControlOption key={d.value} value={d.value} label={d.label} />
197
+ ))}
198
+ </ToggleGroupControl>
199
+ <DateTimePicker currentDate={deadline || null} onChange={(v) => setAttributes({deadline: v ?? ''})} is12Hour={false} />
200
+ </PanelBody>
201
+ )}
202
+
203
+ {type === 'capacity' && (
204
+ <PanelBody title={__('Volná místa', 'brilo-blocks')}>
205
+ <TextControl
206
+ type="number"
207
+ min={0}
208
+ label={__('Zbývá míst', 'brilo-blocks')}
209
+ value={typeof remaining === 'number' ? String(remaining) : ''}
210
+ onChange={(v) => setAttributes({remaining: parseCount(v)})}
211
+ />
212
+ <TextControl
213
+ type="number"
214
+ min={1}
215
+ label={__('Celkem míst', 'brilo-blocks')}
216
+ value={typeof total === 'number' ? String(total) : ''}
217
+ onChange={(v) => setAttributes({total: parseCount(v)})}
218
+ />
219
+ </PanelBody>
220
+ )}
221
+
222
+ {type === 'season' && (
223
+ <PanelBody title={__('Sezóna', 'brilo-blocks')}>
224
+ <TextControl
225
+ type="date"
226
+ label={__('Konec sezóny (volitelné)', 'brilo-blocks')}
227
+ help={__('Po tomto dni se blok na webu skryje.', 'brilo-blocks')}
228
+ value={endDate}
229
+ onChange={(v) => setAttributes({endDate: v})}
230
+ />
231
+ </PanelBody>
232
+ )}
233
+
234
+ <PanelBody title={__('Styl', 'brilo-blocks')}>
235
+ <ToggleGroupControl
236
+ isBlock
237
+ label={__('Velikost textu', 'brilo-blocks')}
238
+ value={textSize}
239
+ onChange={(v) => setAttributes({textSize: v as UrgencyTextSize})}
240
+ >
241
+ {TEXT_SIZES.map((s) => (
242
+ <ToggleGroupControlOption key={s.value} value={s.value} label={s.label} />
243
+ ))}
244
+ </ToggleGroupControl>
245
+ {type !== 'season' && <NumberSizeControl value={numberSize} onChange={(v) => setAttributes({numberSize: v})} />}
246
+ <ColorControl
247
+ label={__('Barva pozadí', 'brilo-blocks')}
248
+ id="urgency-item-background-color"
249
+ value={backgroundColor}
250
+ onChange={(v) => setAttributes({backgroundColor: v})}
251
+ />
252
+ {isCountdown && (
253
+ <ColorControl
254
+ label={__('Pozadí čísel', 'brilo-blocks')}
255
+ id="urgency-item-number-background-color"
256
+ value={numberBackgroundColor}
257
+ onChange={(v) => setAttributes({numberBackgroundColor: v})}
258
+ />
259
+ )}
260
+ <ColorControl
261
+ label={__('Barva textu', 'brilo-blocks')}
262
+ id="urgency-item-text-color"
263
+ value={textColor}
264
+ onChange={(v) => setAttributes({textColor: v})}
265
+ />
266
+ </PanelBody>
267
+ </InspectorControls>
268
+
269
+ <div {...blockProps}>
270
+ {isDeadlineMissing && (
271
+ <Notice status="error" isDismissible={false}>
272
+ {__('Vyberte termín v postranním panelu – bez něj nelze stránku uložit.', 'brilo-blocks')}
273
+ </Notice>
274
+ )}
275
+ {isCapacityMissing && (
276
+ <Notice status="error" isDismissible={false}>
277
+ {__('Vyplňte volná a celková místa v postranním panelu – bez nich nelze stránku uložit.', 'brilo-blocks')}
278
+ </Notice>
279
+ )}
280
+ {isExpired && (
281
+ <Notice status="warning" isDismissible={false}>
282
+ {__('Termín vypršel – na webu se nezobrazuje.', 'brilo-blocks')}
283
+ </Notice>
284
+ )}
285
+
286
+ <div className={clsx('i-urgency__card', `--text-${textSize}`)} style={cardStyle}>
287
+ {text && <span className="i-urgency__label">{text}</span>}
288
+
289
+ {isCountdown && (
290
+ <span className="i-urgency__countdown">
291
+ {COUNTDOWN_UNITS.map((unit) => (
292
+ <span key={unit.key} className="i-urgency__unit">
293
+ <span className="i-urgency__number">{countdown[unit.key]}</span>
294
+ <span className="i-urgency__unit-label">{unit.label}</span>
295
+ </span>
296
+ ))}
297
+ </span>
298
+ )}
299
+
300
+ {type === 'deadline' && display === 'date' && (
301
+ <span className="i-urgency__value">{deadline ? formatDeadline(deadline) : '—'}</span>
302
+ )}
303
+
304
+ {type === 'capacity' && (
305
+ <>
306
+ <span className="i-urgency__value">
307
+ {remaining ?? '—'} / {total ?? '—'}
308
+ </span>
309
+ <span className="i-urgency__progress">
310
+ <span className="i-urgency__progress-fill" style={{width: `${takenPercent}%`}} />
311
+ </span>
312
+ </>
313
+ )}
314
+ </div>
315
+ </div>
316
+ </>
317
+ )
318
+ }
319
+ }
@@ -0,0 +1,99 @@
1
+ .i-urgency {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 8px;
5
+
6
+ .components-notice {
7
+ margin: 0;
8
+ }
9
+ }
10
+
11
+ .i-urgency__card {
12
+ display: flex;
13
+ flex-direction: column;
14
+ align-items: center;
15
+ gap: 12px;
16
+ padding: 20px 16px;
17
+ border-radius: 8px;
18
+ background: var(--urgency-background, #f3f4f6);
19
+ text-align: center;
20
+
21
+ &.--text-sm {
22
+ .i-urgency__label {
23
+ font-size: 14px;
24
+ }
25
+
26
+ .i-urgency__unit-label {
27
+ font-size: 12px;
28
+ }
29
+ }
30
+
31
+ &.--text-lg {
32
+ .i-urgency__label {
33
+ font-size: 18px;
34
+ }
35
+
36
+ .i-urgency__unit-label {
37
+ font-size: 16px;
38
+ }
39
+ }
40
+ }
41
+
42
+ .i-urgency__label {
43
+ font-size: 16px;
44
+ font-weight: 600;
45
+ }
46
+
47
+ .i-urgency__countdown {
48
+ display: flex;
49
+ flex-wrap: wrap;
50
+ justify-content: center;
51
+ gap: 8px;
52
+ }
53
+
54
+ .i-urgency__unit {
55
+ display: flex;
56
+ flex-direction: column;
57
+ align-items: center;
58
+ gap: 4px;
59
+ min-width: 64px;
60
+ padding: 10px 8px;
61
+ border-radius: 6px;
62
+ background: var(--urgency-number-background, #fff);
63
+ }
64
+
65
+ .i-urgency__number,
66
+ .i-urgency__value {
67
+ font-size: var(--urgency-number-size, 28px);
68
+ font-weight: 700;
69
+ line-height: 1;
70
+ font-variant-numeric: tabular-nums;
71
+ }
72
+
73
+ .i-urgency__unit-label {
74
+ font-size: 14px;
75
+ color: var(--urgency-text-color, #50575e);
76
+ }
77
+
78
+ .i-urgency__progress {
79
+ display: block;
80
+ width: 240px;
81
+ max-width: 100%;
82
+ height: 8px;
83
+ border-radius: 4px;
84
+ background: #fff;
85
+ overflow: hidden;
86
+ }
87
+
88
+ .i-urgency__progress-fill {
89
+ display: block;
90
+ height: 100%;
91
+ background: #1e2d45;
92
+ }
93
+
94
+ .i-urgency__number-presets {
95
+ display: flex;
96
+ flex-wrap: wrap;
97
+ gap: 4px;
98
+ margin-bottom: 8px;
99
+ }