@brilo/base-blocks 0.1.2 → 0.1.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../../src/blocks/form/form-group/edit.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAiB,mBAAmB,EAAE,gBAAgB,EAAyC,MAAM,SAAS,CAAA;AAI1H,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,IACtC,0CAIlB;IACD,UAAU,EAAE,mBAAmB,CAAA;IAC/B,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAA;IACxD,QAAQ,EAAE,MAAM,CAAA;CACjB,iCAwKF"}
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../../src/blocks/form/form-group/edit.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAiB,mBAAmB,EAAE,gBAAgB,EAAyC,MAAM,SAAS,CAAA;AAW1H,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,IACtC,0CAIlB;IACD,UAAU,EAAE,mBAAmB,CAAA;IAC/B,aAAa,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAA;IACxD,QAAQ,EAAE,MAAM,CAAA;CACjB,iCAwLF"}
@@ -3,14 +3,20 @@ import { InspectorControls, RichText } from '@wordpress/block-editor';
3
3
  import { FormTokenField, Notice, PanelBody, SelectControl, TextControl, ToggleControl } from '@wordpress/components';
4
4
  import { useDispatch } from '@wordpress/data';
5
5
  import { __ } from '@wordpress/i18n';
6
+ import { cleanForSlug } from '@wordpress/url';
6
7
  import clsx from 'clsx';
7
8
  import { useEffect } from 'react';
8
9
  import { useGroupBlock } from '../../../hooks/useGroupBlock';
9
10
  import { EXTERNAL_METHODS, INTERNAL_SUBMIT_BEHAVIORS, PROCESSING_MODES } from './constants';
10
11
  const ALLOWED_BLOCKS = ['brilo/form-field'];
12
+ function generateFormId(formName) {
13
+ const slug = cleanForSlug(formName) || 'form';
14
+ const hash = Math.random().toString(36).slice(2, 8);
15
+ return `form-${slug}-${hash}`;
16
+ }
11
17
  export function createFormGroupEdit(options) {
12
18
  return function Edit({ attributes, setAttributes, clientId, }) {
13
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
19
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
14
20
  const { lockPostSaving, unlockPostSaving } = useDispatch('core/editor');
15
21
  const processingMode = (_a = attributes.processingMode) !== null && _a !== void 0 ? _a : 'internal';
16
22
  const isInternal = processingMode === 'internal';
@@ -28,6 +34,14 @@ export function createFormGroupEdit(options) {
28
34
  }
29
35
  return () => unlockPostSaving(lockName);
30
36
  }, [clientId, isRecipientsMissing, isExternalUrlMissing, lockPostSaving, unlockPostSaving]);
37
+ // Generated once and persisted into the block's attributes so it stays stable across edits.
38
+ // biome-ignore lint/correctness/useExhaustiveDependencies: must run once on mount only
39
+ useEffect(() => {
40
+ var _a;
41
+ if (!attributes.formId) {
42
+ setAttributes({ formId: generateFormId((_a = attributes.formName) !== null && _a !== void 0 ? _a : '') });
43
+ }
44
+ }, []);
31
45
  const { blockProps, innerBlocksProps } = useGroupBlock({
32
46
  blockClassName: clsx((_c = options.blockClassName) !== null && _c !== void 0 ? _c : 'g-form wp-block-section'),
33
47
  containerClassName: [(_d = options.containerClassName) !== null && _d !== void 0 ? _d : 'g-form__fields'],
@@ -36,10 +50,10 @@ export function createFormGroupEdit(options) {
36
50
  orientation: 'horizontal',
37
51
  layout: { type: 'default' },
38
52
  });
39
- return (_jsxs(_Fragment, { children: [_jsx(InspectorControls, { children: _jsxs(PanelBody, { title: __('Formulář', 'brilo-blocks'), children: [_jsx(TextControl, { label: __('Název formuláře (volitelné)', 'brilo-blocks'), value: (_f = attributes.formName) !== null && _f !== void 0 ? _f : '', placeholder: __('Např. Kontaktní formulář', 'brilo-blocks'), onChange: (formName) => setAttributes({ formName }) }), _jsx(SelectControl, { label: __('Zpracování', 'brilo-blocks'), value: processingMode, options: PROCESSING_MODES.map((m) => ({ label: m.label, value: m.value })), onChange: (mode) => setAttributes({ processingMode: mode }) }), isExternal && (_jsxs(_Fragment, { children: [_jsx(SelectControl, { label: __('Metoda odeslání', 'brilo-blocks'), value: (_g = attributes.externalMethod) !== null && _g !== void 0 ? _g : 'POST', options: EXTERNAL_METHODS.map((m) => ({ label: m.label, value: m.value })), onChange: (externalMethod) => setAttributes({ externalMethod: externalMethod }) }), _jsx(TextControl, { label: __('Externí URL', 'brilo-blocks'), value: (_h = attributes.externalUrl) !== null && _h !== void 0 ? _h : '', onChange: (externalUrl) => setAttributes({ externalUrl }) }), isExternalUrlMissing && (_jsx(Notice, { status: "warning", isDismissible: false, children: __('Pole „Externí URL“ je povinné pro externí zpracování.', 'brilo-blocks') }))] })), isInternal && (_jsxs(_Fragment, { children: [_jsx(FormTokenField, { label: __('Komu (příjemci)', 'brilo-blocks'), value: recipients, __next40pxDefaultSize: true, onChange: (senders) => setAttributes({
53
+ return (_jsxs(_Fragment, { children: [_jsx(InspectorControls, { children: _jsxs(PanelBody, { title: __('Formulář', 'brilo-blocks'), children: [_jsx(TextControl, { label: __('ID formuláře', 'brilo-blocks'), value: (_f = attributes.formId) !== null && _f !== void 0 ? _f : '', readOnly: true, onChange: () => { }, help: __('Generuje se automaticky, slouží k jednoznačné identifikaci formuláře.', 'brilo-blocks') }), _jsx(TextControl, { label: __('Název formuláře (volitelné)', 'brilo-blocks'), value: (_g = attributes.formName) !== null && _g !== void 0 ? _g : '', placeholder: __('Např. Kontaktní formulář', 'brilo-blocks'), onChange: (formName) => setAttributes({ formName }) }), _jsx(SelectControl, { label: __('Zpracování', 'brilo-blocks'), value: processingMode, options: PROCESSING_MODES.map((m) => ({ label: m.label, value: m.value })), onChange: (mode) => setAttributes({ processingMode: mode }) }), isExternal && (_jsxs(_Fragment, { children: [_jsx(SelectControl, { label: __('Metoda odeslání', 'brilo-blocks'), value: (_h = attributes.externalMethod) !== null && _h !== void 0 ? _h : 'POST', options: EXTERNAL_METHODS.map((m) => ({ label: m.label, value: m.value })), onChange: (externalMethod) => setAttributes({ externalMethod: externalMethod }) }), _jsx(TextControl, { label: __('Externí URL', 'brilo-blocks'), value: (_j = attributes.externalUrl) !== null && _j !== void 0 ? _j : '', onChange: (externalUrl) => setAttributes({ externalUrl }) }), isExternalUrlMissing && (_jsx(Notice, { status: "warning", isDismissible: false, children: __('Pole „Externí URL“ je povinné pro externí zpracování.', 'brilo-blocks') }))] })), isInternal && (_jsxs(_Fragment, { children: [_jsx(FormTokenField, { label: __('Komu (příjemci)', 'brilo-blocks'), value: recipients, __next40pxDefaultSize: true, onChange: (senders) => setAttributes({
40
54
  senders: (senders !== null && senders !== void 0 ? senders : [])
41
55
  .map((item) => (typeof item === 'string' ? item.trim() : ''))
42
56
  .filter((item) => item.length > 0),
43
- }) }), isRecipientsMissing && (_jsx(Notice, { status: "warning", isDismissible: false, children: __('Pole „Komu (příjemci)“ je povinné. Vyplňte alespoň jeden e-mail příjemce.', 'brilo-blocks') })), _jsx(TextControl, { label: __('Od koho (From email)', 'brilo-blocks'), value: (_j = attributes.fromEmail) !== null && _j !== void 0 ? _j : '', onChange: (fromEmail) => setAttributes({ fromEmail }) }), _jsx(TextControl, { label: __('Předmět emailu', 'brilo-blocks'), value: (_k = attributes.subject) !== null && _k !== void 0 ? _k : '', placeholder: __('Potvrzení odeslaného formuláře', 'brilo-blocks'), onChange: (subject) => setAttributes({ subject }) }), _jsx(SelectControl, { label: __('Po odeslání', 'brilo-blocks'), value: (_l = attributes.internalSubmitBehavior) !== null && _l !== void 0 ? _l : 'stay', options: INTERNAL_SUBMIT_BEHAVIORS.map((b) => ({ label: b.label, value: b.value })), onChange: (internalSubmitBehavior) => setAttributes({ internalSubmitBehavior: internalSubmitBehavior }) }), ((_m = attributes.internalSubmitBehavior) !== null && _m !== void 0 ? _m : 'stay') === 'redirect' && (_jsx(TextControl, { label: __('URL děkovné stránky', 'brilo-blocks'), value: (_o = attributes.internalRedirectUrl) !== null && _o !== void 0 ? _o : '', onChange: (internalRedirectUrl) => setAttributes({ internalRedirectUrl }) })), _jsx(TextControl, { label: __('Úspěšná zpráva', 'brilo-blocks'), value: (_p = attributes.successMessage) !== null && _p !== void 0 ? _p : '', onChange: (successMessage) => setAttributes({ successMessage }) })] })), _jsx(TextControl, { label: __('Titulek tlačítka odeslání', 'brilo-blocks'), value: (_r = (_q = attributes.submit) === null || _q === void 0 ? void 0 : _q.label) !== null && _r !== void 0 ? _r : 'Odeslat', onChange: (label) => setAttributes({ submit: { label } }) })] }) }), _jsxs("div", { ...blockProps, children: [_jsx("div", { ...innerBlocksProps }), _jsxs("div", { className: "g-form__gdpr", children: [_jsxs("div", { className: "g-form__gdpr-header", children: [_jsx("strong", { children: __('GDPR obsah', 'brilo-blocks') }), _jsx(ToggleControl, { label: __('S checkboxem?', 'brilo-blocks'), checked: (_t = (_s = attributes.gdpr) === null || _s === void 0 ? void 0 : _s.checkbox) !== null && _t !== void 0 ? _t : true, onChange: (checkbox) => { var _a, _b; return setAttributes({ gdpr: { content: (_b = (_a = attributes.gdpr) === null || _a === void 0 ? void 0 : _a.content) !== null && _b !== void 0 ? _b : '', checkbox } }); } })] }), _jsx(RichText, { className: "g-form__gdpr-content", tagName: "div", value: (_v = (_u = attributes.gdpr) === null || _u === void 0 ? void 0 : _u.content) !== null && _v !== void 0 ? _v : '', allowedFormats: ['core/bold', 'core/link'], onChange: (content) => { var _a, _b; return setAttributes({ gdpr: { content, checkbox: (_b = (_a = attributes.gdpr) === null || _a === void 0 ? void 0 : _a.checkbox) !== null && _b !== void 0 ? _b : true } }); }, placeholder: __('Text GDPR souhlasu…', 'brilo-blocks') })] })] })] }));
57
+ }) }), isRecipientsMissing && (_jsx(Notice, { status: "warning", isDismissible: false, children: __('Pole „Komu (příjemci)“ je povinné. Vyplňte alespoň jeden e-mail příjemce.', 'brilo-blocks') })), _jsx(TextControl, { label: __('Od koho (From email)', 'brilo-blocks'), value: (_k = attributes.fromEmail) !== null && _k !== void 0 ? _k : '', onChange: (fromEmail) => setAttributes({ fromEmail }) }), _jsx(TextControl, { label: __('Předmět emailu', 'brilo-blocks'), value: (_l = attributes.subject) !== null && _l !== void 0 ? _l : '', placeholder: __('Potvrzení odeslaného formuláře', 'brilo-blocks'), onChange: (subject) => setAttributes({ subject }) }), _jsx(SelectControl, { label: __('Po odeslání', 'brilo-blocks'), value: (_m = attributes.internalSubmitBehavior) !== null && _m !== void 0 ? _m : 'stay', options: INTERNAL_SUBMIT_BEHAVIORS.map((b) => ({ label: b.label, value: b.value })), onChange: (internalSubmitBehavior) => setAttributes({ internalSubmitBehavior: internalSubmitBehavior }) }), ((_o = attributes.internalSubmitBehavior) !== null && _o !== void 0 ? _o : 'stay') === 'redirect' && (_jsx(TextControl, { label: __('URL děkovné stránky', 'brilo-blocks'), value: (_p = attributes.internalRedirectUrl) !== null && _p !== void 0 ? _p : '', onChange: (internalRedirectUrl) => setAttributes({ internalRedirectUrl }) })), _jsx(TextControl, { label: __('Úspěšná zpráva', 'brilo-blocks'), value: (_q = attributes.successMessage) !== null && _q !== void 0 ? _q : '', onChange: (successMessage) => setAttributes({ successMessage }) })] })), _jsx(TextControl, { label: __('Titulek tlačítka odeslání', 'brilo-blocks'), value: (_s = (_r = attributes.submit) === null || _r === void 0 ? void 0 : _r.label) !== null && _s !== void 0 ? _s : 'Odeslat', onChange: (label) => setAttributes({ submit: { label } }) })] }) }), _jsxs("div", { ...blockProps, children: [_jsx("div", { ...innerBlocksProps }), _jsxs("div", { className: "g-form__gdpr", children: [_jsxs("div", { className: "g-form__gdpr-header", children: [_jsx("strong", { children: __('GDPR obsah', 'brilo-blocks') }), _jsx(ToggleControl, { label: __('S checkboxem?', 'brilo-blocks'), checked: (_u = (_t = attributes.gdpr) === null || _t === void 0 ? void 0 : _t.checkbox) !== null && _u !== void 0 ? _u : true, onChange: (checkbox) => { var _a, _b; return setAttributes({ gdpr: { content: (_b = (_a = attributes.gdpr) === null || _a === void 0 ? void 0 : _a.content) !== null && _b !== void 0 ? _b : '', checkbox } }); } })] }), _jsx(RichText, { className: "g-form__gdpr-content", tagName: "div", value: (_w = (_v = attributes.gdpr) === null || _v === void 0 ? void 0 : _v.content) !== null && _w !== void 0 ? _w : '', allowedFormats: ['core/bold', 'core/link'], onChange: (content) => { var _a, _b; return setAttributes({ gdpr: { content, checkbox: (_b = (_a = attributes.gdpr) === null || _a === void 0 ? void 0 : _a.checkbox) !== null && _b !== void 0 ? _b : true } }); }, placeholder: __('Text GDPR souhlasu…', 'brilo-blocks') })] })] })] }));
44
58
  };
45
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/blocks/form/form-group/factory.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAA;AAGzD,OAAO,KAAK,EAAC,mBAAmB,EAAE,gBAAgB,EAAC,MAAM,SAAS,CAAA;AAElE,YAAY,EAAC,mBAAmB,EAAE,gBAAgB,EAAC,CAAA;AAEnD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CA0BvG"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/blocks/form/form-group/factory.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAA;AAGzD,OAAO,KAAK,EAAC,mBAAmB,EAAE,gBAAgB,EAAC,MAAM,SAAS,CAAA;AAElE,YAAY,EAAC,mBAAmB,EAAE,gBAAgB,EAAC,CAAA;AAEnD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CA2BvG"}
@@ -13,6 +13,7 @@ export function createFormGroupBlock(options) {
13
13
  icon: (_c = options.icon) !== null && _c !== void 0 ? _c : 'feedback',
14
14
  supports: { html: false, customClassName: false },
15
15
  attributes: {
16
+ formId: { type: 'string', default: '' },
16
17
  formName: { type: 'string', default: '' },
17
18
  processingMode: { type: 'string', default: 'internal' },
18
19
  externalMethod: { type: 'string', default: 'POST' },
@@ -3,6 +3,7 @@ export type ProcessingMode = 'internal' | 'external';
3
3
  export type ExternalMethod = 'POST' | 'GET';
4
4
  export type InternalSubmitBehavior = 'stay' | 'redirect';
5
5
  export interface FormGroupAttributes extends Record<string, unknown> {
6
+ formId: string;
6
7
  formName: string;
7
8
  processingMode: ProcessingMode;
8
9
  externalMethod: ExternalMethod;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/blocks/form/form-group/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AAE3C,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,CAAA;AACpD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAA;AAC3C,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,UAAU,CAAA;AAExD,MAAM,WAAW,mBAAoB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,cAAc,CAAA;IAC9B,cAAc,EAAE,cAAc,CAAA;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB,EAAE,sBAAsB,CAAA;IAC9C,mBAAmB,EAAE,MAAM,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAA;IACvB,IAAI,EAAE;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAC,CAAA;IAC1C,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CAAG"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/blocks/form/form-group/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AAE3C,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,CAAA;AACpD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAA;AAC3C,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,UAAU,CAAA;AAExD,MAAM,WAAW,mBAAoB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAClE,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,cAAc,CAAA;IAC9B,cAAc,EAAE,cAAc,CAAA;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,sBAAsB,EAAE,sBAAsB,CAAA;IAC9C,mBAAmB,EAAE,MAAM,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAA;IACvB,IAAI,EAAE;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAC,CAAA;IAC1C,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CAAG"}
@@ -17,6 +17,6 @@ export function createSignpostItemEdit(options) {
17
17
  template: options.template,
18
18
  layout: { type: 'default' },
19
19
  });
20
- return (_jsxs(_Fragment, { children: [_jsxs(InspectorControls, { children: [_jsx(PanelBody, { title: __('Obrázek', 'brilo-blocks'), children: _jsx(ImagePickerControl, { value: img, onChange: (val) => setAttributes({ img: val }) }) }), _jsx(PanelBody, { title: __('Tlačítko', 'brilo-blocks'), children: _jsx(TextControl, { label: __('Text tlačítka', 'brilo-blocks'), value: button.text, onChange: (v) => setAttributes({ button: { ...button, text: v } }) }) }), _jsxs(PanelBody, { title: __('Odkaz', 'brilo-blocks'), initialOpen: false, children: [_jsx(TextControl, { label: __('URL', 'brilo-blocks'), value: url.src, onChange: (v) => setAttributes({ url: { ...url, src: v } }) }), _jsx(ToggleControl, { label: __('Otevřít v nové záložce', 'brilo-blocks'), checked: url.blank, onChange: (v) => setAttributes({ url: { ...url, blank: v } }) })] })] }), _jsx("div", { ...blockProps, children: _jsxs("div", { className: "i-signpost__inner", children: [_jsx("div", { className: "i-signpost__image-wrapper", children: img.id ? (_jsx(ImagePickerControl, { value: img, onChange: (val) => setAttributes({ img: val }), size: [128, 128] })) : (_jsx("div", { className: "i-signpost__image-placeholder", children: _jsx(ImagePickerControl, { value: img, onChange: (val) => setAttributes({ img: val }) }) })) }), _jsxs("div", { className: "i-signpost__body", children: [_jsx(RichText, { tagName: "h3", className: "i-signpost__title u-text-editable", value: title, onChange: (v) => setAttributes({ title: v }), placeholder: __('Nadpis...', 'brilo-blocks'), allowedFormats: ['core/bold', 'core/italic'] }), _jsx("div", { ...innerBlocksProps }), _jsx(Button, { variant: 'primary', className: "i-signpost__button", children: _jsx(RichText, { tagName: "span", className: "i-signpost__button-text", value: button.text, onChange: (v) => setAttributes({ button: { ...button, text: v } }), placeholder: __('Text tlačítka...', 'brilo-blocks') }) })] })] }) })] }));
20
+ return (_jsxs(_Fragment, { children: [_jsxs(InspectorControls, { children: [_jsx(PanelBody, { title: __('Obrázek', 'brilo-blocks'), children: _jsx(ImagePickerControl, { value: img, onChange: (val) => setAttributes({ img: val }) }) }), _jsx(PanelBody, { title: __('Tlačítko', 'brilo-blocks'), children: _jsx(TextControl, { label: __('Text tlačítka', 'brilo-blocks'), value: button.title, onChange: (v) => setAttributes({ button: { ...button, title: v } }) }) }), _jsxs(PanelBody, { title: __('Odkaz', 'brilo-blocks'), initialOpen: false, children: [_jsx(TextControl, { label: __('URL', 'brilo-blocks'), value: url.src, onChange: (v) => setAttributes({ url: { ...url, src: v } }) }), _jsx(ToggleControl, { label: __('Otevřít v nové záložce', 'brilo-blocks'), checked: url.blank, onChange: (v) => setAttributes({ url: { ...url, blank: v } }) })] })] }), _jsx("div", { ...blockProps, children: _jsxs("div", { className: "i-signpost__inner", children: [_jsx("div", { className: "i-signpost__image-wrapper", children: img.id ? (_jsx(ImagePickerControl, { value: img, onChange: (val) => setAttributes({ img: val }), size: [128, 128] })) : (_jsx("div", { className: "i-signpost__image-placeholder", children: _jsx(ImagePickerControl, { value: img, onChange: (val) => setAttributes({ img: val }) }) })) }), _jsxs("div", { className: "i-signpost__body", children: [_jsx(RichText, { tagName: "h3", className: "i-signpost__title u-text-editable", value: title, onChange: (v) => setAttributes({ title: v }), placeholder: __('Nadpis...', 'brilo-blocks'), allowedFormats: ['core/bold', 'core/italic'] }), _jsx("div", { ...innerBlocksProps }), _jsx(Button, { variant: 'primary', className: "i-signpost__button", children: _jsx(RichText, { tagName: "span", className: "i-signpost__button-text", value: button.title, onChange: (v) => setAttributes({ button: { ...button, title: v } }), placeholder: __('Text tlačítka...', 'brilo-blocks') }) })] })] }) })] }));
21
21
  };
22
22
  }
@@ -16,7 +16,7 @@ export function createSignpostItemBlock(options) {
16
16
  attributes: {
17
17
  title: { type: 'string', default: '' },
18
18
  img: { type: 'object', default: { id: 0, alt: '' } },
19
- button: { type: 'object', default: { text: '' } },
19
+ button: { type: 'object', default: { title: '' } },
20
20
  url: { type: 'string', default: '' },
21
21
  blank: { type: 'boolean', default: false },
22
22
  },
@@ -4,7 +4,7 @@ export interface SignpostItemAttributes extends Record<string, unknown> {
4
4
  title: string;
5
5
  img: ImageValue;
6
6
  button: {
7
- text: string;
7
+ title: string;
8
8
  };
9
9
  url: {
10
10
  src: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/blocks/signpost/signpost-item/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AACtC,OAAO,EAAC,UAAU,EAAC,MAAM,sCAAsC,CAAA;AAE/D,MAAM,WAAW,sBAAuB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrE,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,UAAU,CAAA;IACf,MAAM,EAAE;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAA;IACtB,GAAG,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAC,CAAA;IAClC,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;CAAG"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/blocks/signpost/signpost-item/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,SAAS,CAAA;AACtC,OAAO,EAAC,UAAU,EAAC,MAAM,sCAAsC,CAAA;AAE/D,MAAM,WAAW,sBAAuB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrE,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,UAAU,CAAA;IACf,MAAM,EAAE;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAA;IACvB,GAAG,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAC,CAAA;IAClC,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;CAAG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brilo/base-blocks",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "author": "Brilo",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -2,6 +2,7 @@ import {InspectorControls, RichText} from '@wordpress/block-editor'
2
2
  import {FormTokenField, Notice, PanelBody, SelectControl, TextControl, ToggleControl} from '@wordpress/components'
3
3
  import {useDispatch} from '@wordpress/data'
4
4
  import {__} from '@wordpress/i18n'
5
+ import {cleanForSlug} from '@wordpress/url'
5
6
  import clsx from 'clsx'
6
7
  import {useEffect} from 'react'
7
8
  import {useGroupBlock} from '~/hooks/useGroupBlock'
@@ -10,6 +11,13 @@ import type {ExternalMethod, FormGroupAttributes, FormGroupOptions, InternalSubm
10
11
 
11
12
  const ALLOWED_BLOCKS = ['brilo/form-field']
12
13
 
14
+ function generateFormId(formName: string): string {
15
+ const slug = cleanForSlug(formName) || 'form'
16
+ const hash = Math.random().toString(36).slice(2, 8)
17
+
18
+ return `form-${slug}-${hash}`
19
+ }
20
+
13
21
  export function createFormGroupEdit(options: FormGroupOptions) {
14
22
  return function Edit({
15
23
  attributes,
@@ -44,6 +52,14 @@ export function createFormGroupEdit(options: FormGroupOptions) {
44
52
  return () => unlockPostSaving(lockName)
45
53
  }, [clientId, isRecipientsMissing, isExternalUrlMissing, lockPostSaving, unlockPostSaving])
46
54
 
55
+ // Generated once and persisted into the block's attributes so it stays stable across edits.
56
+ // biome-ignore lint/correctness/useExhaustiveDependencies: must run once on mount only
57
+ useEffect(() => {
58
+ if (!attributes.formId) {
59
+ setAttributes({formId: generateFormId(attributes.formName ?? '')})
60
+ }
61
+ }, [])
62
+
47
63
  const {blockProps, innerBlocksProps} = useGroupBlock({
48
64
  blockClassName: clsx(options.blockClassName ?? 'g-form wp-block-section'),
49
65
  containerClassName: [options.containerClassName ?? 'g-form__fields'],
@@ -57,6 +73,14 @@ export function createFormGroupEdit(options: FormGroupOptions) {
57
73
  <>
58
74
  <InspectorControls>
59
75
  <PanelBody title={__('Formulář', 'brilo-blocks')}>
76
+ <TextControl
77
+ label={__('ID formuláře', 'brilo-blocks')}
78
+ value={attributes.formId ?? ''}
79
+ readOnly
80
+ onChange={() => {}}
81
+ help={__('Generuje se automaticky, slouží k jednoznačné identifikaci formuláře.', 'brilo-blocks')}
82
+ />
83
+
60
84
  <TextControl
61
85
  label={__('Název formuláře (volitelné)', 'brilo-blocks')}
62
86
  value={attributes.formName ?? ''}
@@ -16,6 +16,7 @@ export function createFormGroupBlock(options: FormGroupOptions): BlockConfigurat
16
16
  icon: options.icon ?? 'feedback',
17
17
  supports: {html: false, customClassName: false},
18
18
  attributes: {
19
+ formId: {type: 'string', default: ''},
19
20
  formName: {type: 'string', default: ''},
20
21
  processingMode: {type: 'string', default: 'internal'},
21
22
  externalMethod: {type: 'string', default: 'POST'},
@@ -5,6 +5,7 @@ export type ExternalMethod = 'POST' | 'GET'
5
5
  export type InternalSubmitBehavior = 'stay' | 'redirect'
6
6
 
7
7
  export interface FormGroupAttributes extends Record<string, unknown> {
8
+ formId: string
8
9
  formName: string
9
10
  processingMode: ProcessingMode
10
11
  externalMethod: ExternalMethod
@@ -34,8 +34,8 @@ export function createSignpostItemEdit(options: SignpostItemOptions) {
34
34
  <PanelBody title={__('Tlačítko', 'brilo-blocks')}>
35
35
  <TextControl
36
36
  label={__('Text tlačítka', 'brilo-blocks')}
37
- value={button.text}
38
- onChange={(v) => setAttributes({button: {...button, text: v}})}
37
+ value={button.title}
38
+ onChange={(v) => setAttributes({button: {...button, title: v}})}
39
39
  />
40
40
  </PanelBody>
41
41
  <PanelBody title={__('Odkaz', 'brilo-blocks')} initialOpen={false}>
@@ -76,8 +76,8 @@ export function createSignpostItemEdit(options: SignpostItemOptions) {
76
76
  <RichText
77
77
  tagName="span"
78
78
  className="i-signpost__button-text"
79
- value={button.text}
80
- onChange={(v) => setAttributes({button: {...button, text: v}})}
79
+ value={button.title}
80
+ onChange={(v) => setAttributes({button: {...button, title: v}})}
81
81
  placeholder={__('Text tlačítka...', 'brilo-blocks')}
82
82
  />
83
83
  </Button>
@@ -19,7 +19,7 @@ export function createSignpostItemBlock(options: SignpostItemOptions): BlockConf
19
19
  attributes: {
20
20
  title: {type: 'string', default: ''},
21
21
  img: {type: 'object', default: {id: 0, alt: ''}},
22
- button: {type: 'object', default: {text: ''}},
22
+ button: {type: 'object', default: {title: ''}},
23
23
  url: {type: 'string', default: ''},
24
24
  blank: {type: 'boolean', default: false},
25
25
  },
@@ -4,7 +4,7 @@ import {ImageValue} from '~/components/ImagePicker/ImagePicker'
4
4
  export interface SignpostItemAttributes extends Record<string, unknown> {
5
5
  title: string
6
6
  img: ImageValue
7
- button: {text: string}
7
+ button: {title: string}
8
8
  url: {src: string; blank: boolean}
9
9
  blank: boolean
10
10
  }