Skip to content

Commit 1c4a6ca

Browse files
committed
Merge branch 'develop'
# Conflicts: # package.json
2 parents 06a04ce + 8a9dc35 commit 1c4a6ca

19 files changed

Lines changed: 1741 additions & 1645 deletions

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v18
1+
v22

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## [3.6.3] - 2025-11-12
4+
5+
### Added
6+
- Versioning now matches the Formcentric Client.
7+
- Includes client and theme updates (see @formcentric/client/CHANGELOG.md).
8+
39
## [1.0.2] - 2025-06-03
410

511
### Changed

docs/de/stories/Elements.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,12 @@ export const DefaultFieldStoryArgs = {
109109
summary: 'Object',
110110
detail: `{
111111
captcha: () => React.ReactNode,
112-
fileUploader: (props: TemplateProps) => React.ReactNode,
113-
comboBox: (props: TemplateProps) => React.ReactNode,
112+
fileUploader: (props: TemplateProps & { dashboardProps: UppyDashboardProps, buttonProps: UppyDashboardButtonProps }) => React.ReactNode,
113+
comboBox: (props: TemplateProps & { inlineSelected: boolean }) => React.ReactNode,
114114
suggestions: (props: TemplateProps) => React.ReactNode,
115115
hint: (props: TemplateProps & { additionalClosureButton: boolean }) => React.ReactNode,
116116
markdown: (props: { markdown: string; data?: Record<string, string> }) => React.ReactNode,
117-
datePicker: (props: TemplateProps) => React.ReactNode,
117+
datePicker: (props: TemplateProps & { datePickerProps: ReactDatePickerProps, datePickerInputProps: ReactDatePickerInputProps }) => React.ReactNode,
118118
siganture: (props: TemplateProps & { colors: { applyFromTheme: boolean } }) => React.ReactNode
119119
}`,
120120
},

docs/de/stories/Elements/Captcha.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const meta: Meta<typeof CaptchaFieldTemplate> = {
1313
docs: {
1414
description: {
1515
component:
16-
'Dieses Template verfügt über erweiterte Funktionalitäten, die auf einer Komponente basieren, die der Client an das Template übergibt. Um sie anzusehen, musst du den Workspace starten. Die `captcha` Komponente ist eine dynamische Komponente und befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion, wodurch eine dynamische Darstellung von Formularelementen in verschiedenen Zuständen ermöglicht wird.',
16+
'Dieses Template nutzt erweiterte Funktionalitäten durch eine dynamische Komponente, die der Client übergibt. Um diese zu testen, starten Sie den Workspace. Die `captcha`-Komponente befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion. Dies ermöglicht die dynamische Darstellung von Formularelementen in verschiedenen Zuständen.',
1717
},
1818
},
1919
},

docs/de/stories/Elements/Combobox.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const meta: Meta<typeof ComboboxTemplate> = {
1313
docs: {
1414
description: {
1515
component:
16-
'Dieses Template verfügt über erweiterte Funktionalitäten, die auf einer Komponente basieren, die der Client an das Template übergibt. Um sie anzusehen, musst du den Workspace starten. Die `comboBox` Komponente ist eine dynamische Komponente und befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion, wodurch eine dynamische Darstellung von Formularelementen in verschiedenen Zuständen ermöglicht wird.',
16+
'Dieses Template nutzt erweiterte Funktionalitäten durch eine dynamische Komponente, die der Client übergibt. Um diese zu testen, starten Sie den Workspace. Die `comboBox`-Komponente befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion. Dies ermöglicht die dynamische Darstellung von Formularelementen in verschiedenen Zuständen.',
1717
},
1818
},
1919
},

docs/de/stories/Elements/Content.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const meta: Meta<typeof ContentTemplate> = {
1313
docs: {
1414
description: {
1515
component:
16-
'Dieses Template verfügt über erweiterte Funktionalitäten, die auf einer Komponente basieren, die der Client an das Template übergibt. Um sie anzusehen, musst du den Workspace starten. Die `content` Komponente ist eine dynamische Komponente und befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion, wodurch eine dynamische Darstellung von Formularelementen in verschiedenen Zuständen ermöglicht wird.',
16+
'Dieses Template nutzt erweiterte Funktionalitäten durch eine dynamische Komponente, die der Client übergibt. Um diese zu testen, starten Sie den Workspace. Die `content`-Komponente befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion. Dies ermöglicht die dynamische Darstellung von Formularelementen in verschiedenen Zuständen.',
1717
},
1818
},
1919
},

docs/de/stories/Elements/DateField.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const meta: Meta<typeof DateFieldTemplate> = {
1313
docs: {
1414
description: {
1515
component:
16-
'Dieses Template verfügt über erweiterte Funktionalitäten, die auf einer Komponente basieren, die der Client an das Template übergibt. Um sie anzusehen, musst du den Workspace starten. Die `dateField` Komponente ist eine dynamische Komponente und befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion, wodurch eine dynamische Darstellung von Formularelementen in verschiedenen Zuständen ermöglicht wird.',
16+
'Intern verwendet die Komponente [React Datepicker](https://reactdatepicker.com/), um einen Datepicker zu rendern und mehrsprachige Datetimeformate zu generieren. Alle properties des Datepickers und dessen Eingabefeld können über das Template überschrieben werden. Eine vollständige Liste aller verfügbaren Props finden Sie in der verlinkten Dokumentation.\n\n## Verwendung\n\nUm den Datepicker zu verwenden oder dessen Verhalten anzupassen, rufen Sie `props.components.datePicker()` im Template auf.\n\n### Beispiel: Setzen des minimal auswählbaren Datums auf das aktuelle Datum und Hinzufügen eines aria-labels am Inputfeld\n\n```js\nprops.components.datePicker({ ...props, datePickerProps: { minDate: new Date() }, datepickerInputProps: { "aria-label": "Datum auswählen" } })\n```',
1717
},
1818
},
1919
},

docs/de/stories/Elements/FileUpload.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const meta: Meta<typeof FileUploadTemplate> = {
1313
docs: {
1414
description: {
1515
component:
16-
'Dieses Template verfügt über erweiterte Funktionalitäten, die auf einer Komponente basieren, die der Client an das Template übergibt. Um sie anzusehen, musst du den Workspace starten. Die `fileUpload` Komponente ist eine dynamische Komponente und befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion, wodurch eine dynamische Darstellung von Formularelementen in verschiedenen Zuständen ermöglicht wird.',
16+
"Diese Komponente nutzt erweiterte Funktionalitäten durch eine dynamische React-Komponente, die der Client übergibt. Um diese zu testen, starten Sie den Workspace. Die `fileUpload` Komponente ist eine dynamische Komponente und befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion, wodurch eine dynamische Darstellung von Formularelementen in verschiedenen Zuständen ermöglicht wird.\n\n## Uppy\n\nIntern verwendet die Komponente [Uppy React](https://uppy.io/docs/react/) um ein Upload-Dashboard zu rendern und die Upload-Logik zu handhaben.\n\n## Verwendung\n\nFormcentric bietet zwei separate Integrationsmodi dieser Bibliothek:\n\n1. Inline Upload-Dashboard\n2. Upload-Modal\n\nDer verwendete Modus hängt von der Template-Konfiguration ab. Lassen Sie die trigger-Eigenschaft beim Aufruf von `props.components.fileUploader()` weg, um das Upload-Dashboard inline im Formular zu rendern. Fügen Sie die `trigger`-Eigenschaft hinzu, um einen Button zu erstellen, der das Dashboard in einem Modal öffnet.\n\n### Beispiel: Inline Upload-Dashboard\n\n```js\nprops.components.fileUploader({\n id: props.id,\n onblur: props.onblur,\n onfocus: props.onfocus,\n // Keine Trigger-Eigenschaft = Inline-Dashboard\n dashboardProps: {\n disabled: props?.disabled,\n },\n buttonProps: {\n type: 'button',\n name: props.name,\n 'aria-disabled': props.disabled,\n 'aria-errormessage': `fc-error-${props.id}`,\n 'aria-invalid': !!props.fieldError?.defaultMessage,\n 'aria-describedby': `fc-hint-${props.id}`,\n },\n})\n```\n\n### Beispiel: Upload-Modal\n```js\nprops.components.fileUploader({\n id: props.id,\n onblur: props.onblur,\n onfocus: props.onfocus,\n // Modal-Konfiguration mit Trigger und Target\n dashboardProps: {\n trigger: `#${props.id}`,\n target: document.querySelector(`[data-fc-form=\"${props.formId}\"]`),\n },\n})\n```",
1717
},
1818
},
1919
},

docs/de/stories/Elements/Signature.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const meta: Meta<typeof SignatureTemplate> = {
1313
docs: {
1414
description: {
1515
component:
16-
'Dieses Template verfügt über erweiterte Funktionalitäten, die auf einer Komponente basieren, die der Client an das Template übergibt. Um sie anzusehen, musst du den Workspace starten. Die `signature` Komponente ist eine dynamische Komponente und befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion, wodurch eine dynamische Darstellung von Formularelementen in verschiedenen Zuständen ermöglicht wird.',
16+
'Diese Komponente nutzt erweiterte Funktionalitäten durch eine dynamische React-Komponente, die der Client übergibt. Um diese zu testen, starten Sie den Workspace. Die `signature`-Komponente befindet sich im Verzeichnis `templates/elements/`. Der Formcentric-Client übergibt die aufgelisteten Eigenschaften als zweites Argument an die Template-Funktion. Dies ermöglicht die dynamische Darstellung von Formularelementen in verschiedenen Zuständen.',
1717
},
1818
},
1919
},

docs/de/stories/Footer.tsx

Lines changed: 139 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react'
22
import { StoryObj } from '@storybook/react'
3+
import { Dispatch, StateUpdater } from 'preact/hooks'
4+
import { TemplateProps } from '../../types/Templates'
35

46
export type FooterButtonProps = {
57
id: string
@@ -37,21 +39,56 @@ export const argTypeButton = {
3739
}
3840

3941
export type FooterProps = {
42+
formId: string
43+
formName: string
44+
customStates: [Record<string, unknown>, Dispatch<StateUpdater<Record<string, unknown>>>]
45+
pageTitle: string
46+
pageTitles: string[]
47+
currentPageIndex: number
48+
currentPageFull: number
4049
currentPage: number
4150
pageCount: number
51+
pageCountFull: number
52+
hiddenPages: number[]
53+
resetForm: () => void
4254
translation: (key: string, _params?: Record<string, string>) => string
55+
pageButtonProps: {
56+
onclick: () => void
57+
label: string | number
58+
disabled: boolean
59+
'aria-current': string
60+
}[]
4361
_back: FooterButtonProps
4462
_cancel: FooterButtonProps
4563
_next: FooterButtonProps
4664
_finish: FooterButtonProps
65+
components: TemplateProps['components']
4766
}
4867

4968
export const FooterProps: FooterProps = {
69+
formId: '1234',
70+
formName: 'test',
71+
customStates: [{}, () => {}],
72+
pageTitle: 'Seite 1',
73+
pageTitles: ['Seite 1', 'Seite 2'],
74+
currentPageIndex: 0,
75+
currentPageFull: 1,
76+
pageCountFull: 3,
5077
currentPage: 1,
5178
pageCount: 2,
79+
hiddenPages: [2],
80+
resetForm: () => {},
5281
translation: (key, params = {}) => {
5382
return key
5483
},
84+
pageButtonProps: [
85+
{
86+
onclick: () => {},
87+
label: '1',
88+
disabled: false,
89+
'aria-current': 'page',
90+
},
91+
],
5592
_back: {
5693
id: '_back',
5794
type: 'button',
@@ -100,6 +137,16 @@ export const FooterProps: FooterProps = {
100137
hidden: true,
101138
},
102139
},
140+
components: {
141+
captcha: () => null,
142+
fileUploader: () => null,
143+
comboBox: () => null,
144+
suggestions: () => null,
145+
hint: () => null,
146+
datePicker: () => null,
147+
markdown: props => props.markdown,
148+
siganture: () => null,
149+
},
103150
}
104151

105152
export type FooterStory = StoryObj<
@@ -113,22 +160,22 @@ export const Footer: FooterStory = {
113160
...FooterProps,
114161
},
115162
argTypes: {
116-
currentPage: {
117-
control: 'number',
118-
description: 'Index der aktuellen Seite',
163+
formId: {
164+
control: 'text',
165+
description: 'ID des Formulars',
119166
},
120-
pageCount: {
121-
control: 'number',
122-
description: 'Gesamtanzahl der Formularseiten',
123-
table: {
124-
type: { summary: 'number' },
125-
},
167+
formName: {
168+
control: 'text',
169+
description: 'Name des Formulars',
126170
},
127171
translation: {
128172
control: false,
129173
description: 'Übersetzungs-Funktion',
130174
table: {
131-
type: { summary: 'function' },
175+
type: {
176+
summary: 'function',
177+
detail: `translation(key: string, params?: Record<string, string>) => string`,
178+
},
132179
},
133180
},
134181
_back: {
@@ -157,5 +204,87 @@ export const Footer: FooterStory = {
157204
type: { summary: 'FooterButtonProps' },
158205
},
159206
},
207+
customStates: {
208+
control: false,
209+
description: 'Benutzerdefinierte Zustände zum Persistieren von Template-Daten zwischen Renderings',
210+
table: {
211+
type: { summary: '[Record<string, unknown>, Dispatch<StateUpdater<Record<string, unknown>>>]' },
212+
},
213+
},
214+
pageTitle: {
215+
control: 'text',
216+
description: 'Titel der aktuellen Seite',
217+
},
218+
pageTitles: {
219+
control: 'object',
220+
description: 'Array aller Seitentitel',
221+
table: {
222+
type: { summary: 'string[]' },
223+
},
224+
},
225+
currentPageIndex: {
226+
control: 'number',
227+
description: 'Index der aktuellen Seite (0-basiert)',
228+
},
229+
currentPageFull: {
230+
control: 'number',
231+
description: 'Aktuelle Seite (1-basiert, inklusive versteckter Seiten)',
232+
},
233+
currentPage: {
234+
control: 'number',
235+
description: 'Tatsächliche aktuelle Seite (1-basiert, ohne versteckte Seiten)',
236+
},
237+
pageCount: {
238+
control: 'number',
239+
description: 'Anzahl der sichtbaren Seiten (1-basiert, bedingt versteckte Seiten werden nicht gezählt)',
240+
},
241+
pageCountFull: {
242+
control: 'number',
243+
description: 'Gesamtanzahl aller Seiten (inklusive versteckter Seiten)',
244+
},
245+
hiddenPages: {
246+
control: 'object',
247+
description: 'Array der Indizes versteckter Seiten',
248+
table: {
249+
type: { summary: 'number[]' },
250+
},
251+
},
252+
resetForm: {
253+
control: false,
254+
description: 'Funktion zum Zurücksetzen des Formulars',
255+
table: {
256+
type: { summary: '() => void' },
257+
},
258+
},
259+
pageButtonProps: {
260+
control: 'object',
261+
description:
262+
'Button-Eigenschaften für die vollständige Formular-Navigationsleiste (siehe Seattle formHeader.js)',
263+
table: {
264+
type: {
265+
summary:
266+
'Array<{ onclick: () => void, label: string | number, disabled: boolean, "aria-current": string }>',
267+
},
268+
},
269+
},
270+
components: {
271+
description: 'Formcentric Helper-Komponenten',
272+
control: false,
273+
table: {
274+
type: {
275+
summary: 'Object',
276+
detail: `{
277+
captcha: () => React.ReactNode,
278+
fileUploader: (props: TemplateProps & { dashboardProps: UppyDashboardProps, buttonProps: UppyDashboardButtonProps }) => React.ReactNode,
279+
comboBox: (props: TemplateProps & { inlineSelected: boolean }) => React.ReactNode,
280+
suggestions: (props: TemplateProps) => React.ReactNode,
281+
hint: (props: TemplateProps & { additionalClosureButton: boolean }) => React.ReactNode,
282+
markdown: (props: { markdown: string; data?: Record<string, string> }) => React.ReactNode,
283+
datePicker: (props: TemplateProps & { datePickerProps: ReactDatePickerProps, datePickerInputProps: ReactDatePickerInputProps }) => React.ReactNode,
284+
siganture: (props: TemplateProps & { colors: { applyFromTheme: boolean } }) => React.ReactNode
285+
}`,
286+
},
287+
},
288+
},
160289
},
161290
}

0 commit comments

Comments
 (0)