@public-ui/sample-react 1.7.11 → 1.7.13
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.
- package/dist/104.js +1 -1
- package/dist/1296.js +1 -1
- package/dist/1461.js +1 -1
- package/dist/1684.js +1 -1
- package/dist/1720.js +1 -1
- package/dist/1888.js +1 -1
- package/dist/{616.js → 2104.js} +2 -2
- package/dist/2120.js +1 -1
- package/dist/2240.js +1 -1
- package/dist/2444.js +1 -1
- package/dist/2628.js +1 -1
- package/dist/2740.js +1 -1
- package/dist/2764.js +1 -1
- package/dist/2782.js +1 -1
- package/dist/2812.js +1 -1
- package/dist/3200.js +1 -1
- package/dist/3204.js +1 -1
- package/dist/352.js +1 -1
- package/dist/3564.js +1 -1
- package/dist/3920.js +1 -1
- package/dist/4064.js +1 -1
- package/dist/4136.js +1 -1
- package/dist/4184.js +1 -1
- package/dist/4544.js +1 -1
- package/dist/4728.js +1 -1
- package/dist/4915.js +1 -1
- package/dist/4988.js +1 -1
- package/dist/5060.js +2 -0
- package/dist/5376.js +1 -1
- package/dist/5456.js +1 -1
- package/dist/5615.js +1 -1
- package/dist/5628.js +1 -1
- package/dist/5744.js +1 -1
- package/dist/5768.js +1 -1
- package/dist/5839.js +1 -1
- package/dist/5956.js +1 -1
- package/dist/5972.js +1 -1
- package/dist/6040.js +1 -1
- package/dist/6272.js +1 -1
- package/dist/7192.js +1 -1
- package/dist/7312.js +1 -1
- package/dist/7344.js +1 -1
- package/dist/736.js +1 -1
- package/dist/7496.js +1 -1
- package/dist/7508.js +1 -1
- package/dist/7596.js +1 -1
- package/dist/7712.js +1 -1
- package/dist/7808.js +1 -1
- package/dist/8188.js +1 -1
- package/dist/8232.js +1 -1
- package/dist/8248.js +1 -1
- package/dist/828.js +1 -1
- package/dist/8476.js +1 -1
- package/dist/8524.js +1 -1
- package/dist/8696.js +2 -0
- package/dist/9088.js +1 -1
- package/dist/9404.js +1 -1
- package/dist/9424.js +1 -1
- package/dist/9496.js +1 -1
- package/dist/9544.js +1 -1
- package/dist/9680.js +1 -1
- package/dist/9844.js +2 -0
- package/dist/9888.js +1 -1
- package/dist/9984.js +1 -1
- package/dist/index.html +1 -1
- package/dist/main.css +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +2 -4
- package/package.json +13 -15
- package/public/index.html +1 -1
- package/src/App.tsx +26 -23
- package/src/components/SampleDescription.tsx +23 -0
- package/src/components/input-text/hide-errors.tsx +25 -0
- package/src/components/input-text/partials/cases.tsx +1 -4
- package/src/components/input-text/routes.ts +2 -0
- package/src/components/tabs/basic.tsx +24 -7
- package/src/scenarios/appointment-form/AppointmentForm.tsx +13 -7
- package/src/scenarios/appointment-form/AvailableAppointmentsForm.tsx +7 -10
- package/src/scenarios/appointment-form/DistrictForm.tsx +4 -9
- package/src/scenarios/appointment-form/PersonalInformationForm.tsx +29 -6
- package/src/scenarios/appointment-form/formUtils.ts +8 -0
- package/src/scenarios/routes.ts +3 -1
- package/src/scenarios/static-form.tsx +74 -0
- package/src/shares/HideMenusContext.ts +3 -0
- package/dist/4236.js +0 -2
- package/dist/4900.js +0 -2
- package/dist/5384.js +0 -2
- package/src/scenarios/appointment-form/ErrorList.tsx +0 -35
- /package/dist/{4236.js.LICENSE.txt → 2104.js.LICENSE.txt} +0 -0
- /package/dist/{4900.js.LICENSE.txt → 5060.js.LICENSE.txt} +0 -0
- /package/dist/{5384.js.LICENSE.txt → 8696.js.LICENSE.txt} +0 -0
- /package/dist/{616.js.LICENSE.txt → 9844.js.LICENSE.txt} +0 -0
package/dist/main.js.LICENSE.txt
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
* KoliBri - The accessible HTML-Standard
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
/*!__STENCIL_STATIC_IMPORT_SWITCH__*/
|
|
6
|
-
|
|
7
5
|
/**
|
|
8
6
|
* @license React
|
|
9
7
|
* react-dom.production.min.js
|
|
@@ -35,7 +33,7 @@
|
|
|
35
33
|
*/
|
|
36
34
|
|
|
37
35
|
/**
|
|
38
|
-
* @remix-run/router v1.15.
|
|
36
|
+
* @remix-run/router v1.15.1
|
|
39
37
|
*
|
|
40
38
|
* Copyright (c) Remix Software Inc.
|
|
41
39
|
*
|
|
@@ -46,7 +44,7 @@
|
|
|
46
44
|
*/
|
|
47
45
|
|
|
48
46
|
/**
|
|
49
|
-
* React Router v6.22.
|
|
47
|
+
* React Router v6.22.1
|
|
50
48
|
*
|
|
51
49
|
* Copyright (c) Remix Software Inc.
|
|
52
50
|
*
|
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@public-ui/sample-react",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.13",
|
|
4
4
|
"description": "This app contains samples for the KoliBri/Public UI",
|
|
5
5
|
"license": "EUPL-1.2",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@leanup/stack": "1.3.49",
|
|
8
8
|
"@leanup/stack-react": "1.3.49",
|
|
9
9
|
"@leanup/stack-webpack": "1.3.49",
|
|
10
|
-
"@public-ui/components": "1.7.
|
|
11
|
-
"@public-ui/react": "1.7.
|
|
12
|
-
"@public-ui/themes": "1.7.
|
|
13
|
-
"@types/node": "20.11.
|
|
14
|
-
"@types/react": "18.2.
|
|
10
|
+
"@public-ui/components": "1.7.13",
|
|
11
|
+
"@public-ui/react": "1.7.13",
|
|
12
|
+
"@public-ui/themes": "1.7.13",
|
|
13
|
+
"@types/node": "20.11.19",
|
|
14
|
+
"@types/react": "18.2.57",
|
|
15
15
|
"@types/react-dom": "18.2.19",
|
|
16
16
|
"@unocss/preset-uno": "0.58.5",
|
|
17
17
|
"@unocss/webpack": "0.58.5",
|
|
18
18
|
"ajv": "8.12.0",
|
|
19
|
-
"chromedriver": "121.0.
|
|
19
|
+
"chromedriver": "121.0.2",
|
|
20
20
|
"cpy-cli": "5.0.0",
|
|
21
21
|
"eslint-plugin-jsx-a11y": "6.8.0",
|
|
22
22
|
"eslint-plugin-react": "7.33.2",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"npm-run-all": "4.1.5",
|
|
26
26
|
"react": "18.2.0",
|
|
27
27
|
"react-dom": "18.2.0",
|
|
28
|
-
"react-router": "6.22.
|
|
29
|
-
"react-router-dom": "6.22.
|
|
28
|
+
"react-router": "6.22.1",
|
|
29
|
+
"react-router-dom": "6.22.1",
|
|
30
30
|
"rimraf": "3.0.2",
|
|
31
31
|
"ts-prune": "0.10.3",
|
|
32
32
|
"typescript": "5.3.3",
|
|
@@ -48,16 +48,14 @@
|
|
|
48
48
|
"webpack.config.js"
|
|
49
49
|
],
|
|
50
50
|
"scripts": {
|
|
51
|
-
"clean": "git clean -f -d -X",
|
|
52
|
-
"clean:locks": "rimraf package-lock.json pnpm-lock.yaml && npm run clean",
|
|
53
51
|
"build": "rimraf dist && cross-env NODE_ENV=production webpack",
|
|
52
|
+
"build:deps": "pnpm --filter @public-ui/sample-react^... build",
|
|
54
53
|
"format": "prettier --check src",
|
|
55
54
|
"lint": "eslint \"{src,tests}/**/*.{html,js,json,jsx,ts,tsx,gql,graphql}\"",
|
|
55
|
+
"prepare:components-assets": "cpy \"node_modules/@public-ui/components/assets/**/*\" public/assets --dot",
|
|
56
|
+
"prepare:themes-assets": "cpy \"node_modules/@public-ui/themes/assets/**/*\" public/assets --dot",
|
|
56
57
|
"serve": "cross-env NODE_ENV=development webpack serve --devtool=source-map",
|
|
57
58
|
"start": "npm run serve -- --open",
|
|
58
|
-
"unused": "ts-prune -e src"
|
|
59
|
-
"postinstall": "npm-run-all postinstall:*",
|
|
60
|
-
"postinstall:components-assets": "cpy \"node_modules/@public-ui/components/assets/**/*\" public/assets --dot",
|
|
61
|
-
"postinstall:themes-assets": "cpy \"node_modules/@public-ui/themes/assets/**/*\" public/assets --dot"
|
|
59
|
+
"unused": "ts-prune -e src"
|
|
62
60
|
}
|
|
63
61
|
}
|
package/public/index.html
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<link rel="stylesheet" href="assets/tabler-icons/tabler-icons.css" />
|
|
19
19
|
<link rel="stylesheet" href="main.css" />
|
|
20
20
|
<meta name="robots" content="noindex" />
|
|
21
|
-
<meta name="kolibri" content="dev-mode=false" />
|
|
21
|
+
<meta name="kolibri" content="dev-mode=false;experimental-mode=true;" />
|
|
22
22
|
</head>
|
|
23
23
|
<body>
|
|
24
24
|
<div id="app"></div>
|
package/src/App.tsx
CHANGED
|
@@ -3,13 +3,14 @@ import { Navigate, Route, Routes, useSearchParams } from 'react-router-dom';
|
|
|
3
3
|
import { Route as MyRoute, Routes as MyRoutes } from './shares/types';
|
|
4
4
|
|
|
5
5
|
import { Option } from '@public-ui/components';
|
|
6
|
+
import PackageJson from '@public-ui/components/package.json';
|
|
6
7
|
import { KolAlert, KolBadge } from '@public-ui/react';
|
|
8
|
+
import { HideMenusContext } from './shares/HideMenusContext';
|
|
9
|
+
import { useLocation } from 'react-router';
|
|
10
|
+
import { Sidebar } from './components/Sidebar';
|
|
7
11
|
import { ROUTES } from './shares/routes';
|
|
8
|
-
import { isDraftTheme, Theme, THEME_OPTIONS } from './shares/theme';
|
|
9
|
-
import PackageJson from '@public-ui/components/package.json';
|
|
10
12
|
import { getTheme, getThemeName, setStorage, setTheme } from './shares/store';
|
|
11
|
-
import {
|
|
12
|
-
import { useLocation } from 'react-router';
|
|
13
|
+
import { THEME_OPTIONS, Theme, isDraftTheme } from './shares/theme';
|
|
13
14
|
|
|
14
15
|
import { BackPage } from './components/BackPage';
|
|
15
16
|
|
|
@@ -118,26 +119,28 @@ export const App: FC = () => {
|
|
|
118
119
|
};
|
|
119
120
|
|
|
120
121
|
return (
|
|
121
|
-
<
|
|
122
|
-
{!hideMenus
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
122
|
+
<HideMenusContext.Provider value={hideMenus}>
|
|
123
|
+
<div className={!hideMenus ? 'app-container' : ''} data-theme={theme}>
|
|
124
|
+
{!hideMenus && (
|
|
125
|
+
<Sidebar
|
|
126
|
+
version={PackageJson.version}
|
|
127
|
+
theme={theme}
|
|
128
|
+
sample={routerLocation.pathname}
|
|
129
|
+
routes={ROUTES}
|
|
130
|
+
routeList={ROUTE_LIST}
|
|
131
|
+
onThemeChange={handleThemeChange}
|
|
132
|
+
/>
|
|
133
|
+
)}
|
|
132
134
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
<div className="p-4" id="route-container">
|
|
136
|
+
{!hideMenus && isDraftTheme(theme) && <KolBadge className="mb-3" _label="DRAFT" _color="#db5461" />}
|
|
137
|
+
<Routes>
|
|
138
|
+
{ROUTE_TREE}
|
|
139
|
+
<Route path="*" element={<KolAlert _type="info">This code example has not been migrated yet - it's coming soon!</KolAlert>} />
|
|
140
|
+
<Route path="back-page" element={<BackPage />} />
|
|
141
|
+
</Routes>
|
|
142
|
+
</div>
|
|
140
143
|
</div>
|
|
141
|
-
</
|
|
144
|
+
</HideMenusContext.Provider>
|
|
142
145
|
);
|
|
143
146
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FC, PropsWithChildren } from 'react';
|
|
2
|
+
import React, { useContext } from 'react';
|
|
3
|
+
|
|
4
|
+
import { KolIndentedText, KolLink } from '@public-ui/react';
|
|
5
|
+
|
|
6
|
+
import { HideMenusContext } from '../shares/HideMenusContext';
|
|
7
|
+
|
|
8
|
+
export const SampleDescription: FC<PropsWithChildren> = (props) => {
|
|
9
|
+
const hideMenus = useContext(HideMenusContext);
|
|
10
|
+
|
|
11
|
+
return hideMenus ? null : (
|
|
12
|
+
<div className="flex mb-sm">
|
|
13
|
+
<KolIndentedText>{props.children}</KolIndentedText>
|
|
14
|
+
<KolLink
|
|
15
|
+
_hideLabel
|
|
16
|
+
_href={`${location.href}?hideMenus`}
|
|
17
|
+
_label="Beispiel in neuem Tab öffnen"
|
|
18
|
+
_target="_blank"
|
|
19
|
+
className="mla flex-self-center"
|
|
20
|
+
></KolLink>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { KolAlert, KolCard, KolInputText } from '@public-ui/react';
|
|
2
|
+
import type { FC } from 'react';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { SampleDescription } from '../SampleDescription';
|
|
5
|
+
|
|
6
|
+
export const InputTextHideErrors: FC = () => (
|
|
7
|
+
<div className="grid gap-4">
|
|
8
|
+
<SampleDescription>
|
|
9
|
+
This case shows the <code>_hideError</code> feature in the se. You can use the <code>_error</code> prop to show an error message.
|
|
10
|
+
</SampleDescription>
|
|
11
|
+
<KolCard _label="Normal input field with error" _level={0}>
|
|
12
|
+
<KolInputText _error="Error message" _label="Input with error" _touched />
|
|
13
|
+
</KolCard>
|
|
14
|
+
<KolCard _label="Input field with hidden error" _level={0}>
|
|
15
|
+
<fieldset className="grid md:grid-cols-2 gap-4">
|
|
16
|
+
<legend>Combined input field</legend>
|
|
17
|
+
<KolAlert className="col-span-2" _level={0} _type="error">
|
|
18
|
+
This is a combined error message
|
|
19
|
+
</KolAlert>
|
|
20
|
+
<KolInputText _error="This is a combined error message" _hideError _label="First input" _touched />
|
|
21
|
+
<KolInputText _error="This is a combined error message" _hideError _label="Second input with error" _touched />
|
|
22
|
+
</fieldset>
|
|
23
|
+
</KolCard>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
@@ -14,7 +14,6 @@ export const InputTextCases = forwardRef<HTMLKolInputTextElement, Components.Kol
|
|
|
14
14
|
_error={ERROR_MSG}
|
|
15
15
|
_placeholder="Mit Icons"
|
|
16
16
|
_icons={{
|
|
17
|
-
left: 'codicon codicon-arrow-left',
|
|
18
17
|
right: {
|
|
19
18
|
icon: 'codicon codicon-arrow-right',
|
|
20
19
|
style: {
|
|
@@ -28,13 +27,11 @@ export const InputTextCases = forwardRef<HTMLKolInputTextElement, Components.Kol
|
|
|
28
27
|
onClick: console.log,
|
|
29
28
|
onFocus: console.log,
|
|
30
29
|
}}
|
|
31
|
-
_hideLabel
|
|
32
30
|
_required
|
|
33
31
|
_type="search"
|
|
34
32
|
_touched
|
|
35
|
-
_label="
|
|
33
|
+
_label="Vorname (text)"
|
|
36
34
|
/>
|
|
37
|
-
<KolInputText {...props} ref={ref} _placeholder="Placeholder" _label="Vorname (text)" _required />
|
|
38
35
|
<KolInputText {...props} _placeholder="Placeholder" _label="Suche (search)" _type="search" />
|
|
39
36
|
<KolInputText {...props} _placeholder="Placeholder" _error={ERROR_MSG} _touched _type="url" _label="URL (url)" />
|
|
40
37
|
<KolInputText {...props} _placeholder="Placeholder" _type="tel" _label="Telefon (tel)" />
|
|
@@ -2,6 +2,7 @@ import { Routes } from '../../shares/types';
|
|
|
2
2
|
|
|
3
3
|
import { InputTextBasic } from './basic';
|
|
4
4
|
import { InputTextBlur } from './blur';
|
|
5
|
+
import { InputTextHideErrors } from './hide-errors';
|
|
5
6
|
import { InputTextFocus } from './focus';
|
|
6
7
|
|
|
7
8
|
export const INPUT_TEXT_ROUTES: Routes = {
|
|
@@ -9,5 +10,6 @@ export const INPUT_TEXT_ROUTES: Routes = {
|
|
|
9
10
|
basic: InputTextBasic,
|
|
10
11
|
blur: InputTextBlur,
|
|
11
12
|
focus: InputTextFocus,
|
|
13
|
+
'hide-errors': InputTextHideErrors,
|
|
12
14
|
},
|
|
13
15
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
2
4
|
import { KolTabs } from '@public-ui/react';
|
|
3
5
|
|
|
4
6
|
const tabs = [
|
|
@@ -20,11 +22,26 @@ const tabs = [
|
|
|
20
22
|
_label: 'Letzter Tab',
|
|
21
23
|
},
|
|
22
24
|
];
|
|
25
|
+
|
|
26
|
+
const tabsWithoutIcons = tabs.map((tab) => ({
|
|
27
|
+
...tab,
|
|
28
|
+
_icons: undefined,
|
|
29
|
+
}));
|
|
30
|
+
|
|
23
31
|
export const TabsBasic: FC = () => (
|
|
24
|
-
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
<>
|
|
33
|
+
<KolTabs _tabs={tabsWithoutIcons} _label="Regular tabs">
|
|
34
|
+
<div slot="tab-0">Inhalte von Tab 1</div>
|
|
35
|
+
<div slot="tab-1">Inhalte von Tab 2</div>
|
|
36
|
+
<div slot="tab-2">Inhalte von Tab 3</div>
|
|
37
|
+
<div slot="tab-3">Inhalte von Tab 4</div>
|
|
38
|
+
</KolTabs>
|
|
39
|
+
|
|
40
|
+
<KolTabs _tabs={tabs} className="mt-4" _label="Tabs with icons">
|
|
41
|
+
<div slot="tab-0">Inhalte von Tab 1</div>
|
|
42
|
+
<div slot="tab-1">Inhalte von Tab 2</div>
|
|
43
|
+
<div slot="tab-2">Inhalte von Tab 3</div>
|
|
44
|
+
<div slot="tab-3">Inhalte von Tab 4</div>
|
|
45
|
+
</KolTabs>
|
|
46
|
+
</>
|
|
30
47
|
);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
2
|
import { KolTabs } from '@public-ui/react';
|
|
3
3
|
import { DistrictForm } from './DistrictForm';
|
|
4
4
|
import { Summary } from './Summary';
|
|
5
5
|
import { PersonalInformationForm } from './PersonalInformationForm';
|
|
6
|
-
import { Formik, FormikHelpers } from 'formik';
|
|
6
|
+
import { Formik, FormikHelpers, FormikProps } from 'formik';
|
|
7
7
|
import * as Yup from 'yup';
|
|
8
8
|
import { AvailableAppointmentsForm } from './AvailableAppointmentsForm';
|
|
9
9
|
import { Iso8601 } from '@public-ui/components';
|
|
@@ -46,12 +46,12 @@ const districtSchema = {
|
|
|
46
46
|
};
|
|
47
47
|
const personalInformationSchema = {
|
|
48
48
|
salutation: Yup.string().required('Bitte Anrede auswählen.'),
|
|
49
|
-
name: Yup.string().required('Bitte
|
|
49
|
+
name: Yup.string().required('Bitte Vor- und Zuname eingeben.'),
|
|
50
50
|
company: Yup.string().when('salutation', {
|
|
51
51
|
is: (salutation: string) => salutation === 'Firma',
|
|
52
|
-
then: (schema) => schema.required('Bitte
|
|
52
|
+
then: (schema) => schema.required('Bitte Firma angeben.'),
|
|
53
53
|
}),
|
|
54
|
-
email: Yup.string().required('Bitte E-Mail
|
|
54
|
+
email: Yup.string().required('Bitte E-Mail eingeben.'),
|
|
55
55
|
};
|
|
56
56
|
const availableAppointmentsSchema = {
|
|
57
57
|
date: Yup.string().required('Bitte Datum eingeben.'),
|
|
@@ -64,6 +64,7 @@ const availableAppointmentsSchema = {
|
|
|
64
64
|
export function AppointmentForm() {
|
|
65
65
|
const [activeFormSection, setActiveFormSection] = useState(FormSection.DISTRICT);
|
|
66
66
|
const [selectedTab, setSelectedTab] = useState(activeFormSection);
|
|
67
|
+
const formikRef = useRef<FormikProps<FormValues>>(null);
|
|
67
68
|
|
|
68
69
|
const validationSchema = Yup.object().shape({
|
|
69
70
|
...(activeFormSection === FormSection.DISTRICT ? districtSchema : {}),
|
|
@@ -86,7 +87,7 @@ export function AppointmentForm() {
|
|
|
86
87
|
};
|
|
87
88
|
|
|
88
89
|
return (
|
|
89
|
-
<Formik<FormValues> initialValues={initialValues} validationSchema={validationSchema} onSubmit={handleSubmit}>
|
|
90
|
+
<Formik<FormValues> innerRef={formikRef} initialValues={initialValues} validationSchema={validationSchema} onSubmit={handleSubmit}>
|
|
90
91
|
<KolTabs
|
|
91
92
|
_tabs={[
|
|
92
93
|
{
|
|
@@ -107,7 +108,12 @@ export function AppointmentForm() {
|
|
|
107
108
|
]}
|
|
108
109
|
_label="Formular-Navigation"
|
|
109
110
|
_selected={selectedTab}
|
|
110
|
-
_on={{
|
|
111
|
+
_on={{
|
|
112
|
+
onSelect: (_event, selectedTab) => {
|
|
113
|
+
setActiveFormSection(selectedTab);
|
|
114
|
+
formikRef.current?.setErrors({});
|
|
115
|
+
},
|
|
116
|
+
}}
|
|
111
117
|
>
|
|
112
118
|
<div>
|
|
113
119
|
<DistrictForm />
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import { KolButton, KolForm, KolHeading, KolInputDate, KolInputRadio, KolSpin } from '@public-ui/react';
|
|
3
3
|
import { FormValues } from './AppointmentForm';
|
|
4
|
-
import { ErrorList } from './ErrorList';
|
|
5
4
|
import { Field, FieldProps, useFormikContext } from 'formik';
|
|
6
5
|
import { fetchAvailableTimes } from './appointmentService';
|
|
7
6
|
import { Option } from '@public-ui/components/src';
|
|
7
|
+
import { createErrorList } from './formUtils';
|
|
8
8
|
|
|
9
9
|
export function AvailableAppointmentsForm() {
|
|
10
10
|
const form = useFormikContext<FormValues>();
|
|
11
11
|
|
|
12
12
|
const [sectionSubmitted, setSectionSubmitted] = useState(false);
|
|
13
13
|
const [availableTimes, setAvailableTimes] = useState<Option<string>[] | null>(null);
|
|
14
|
+
const errorList = createErrorList(form.errors);
|
|
14
15
|
|
|
15
16
|
useEffect(() => {
|
|
16
17
|
let ignoreResponse = false;
|
|
@@ -36,14 +37,8 @@ export function AvailableAppointmentsForm() {
|
|
|
36
37
|
return (
|
|
37
38
|
<div className="p-2">
|
|
38
39
|
<KolHeading _level={2} _label="Wählen Sie einen Termin aus"></KolHeading>
|
|
39
|
-
|
|
40
|
-
{sectionSubmitted && Object.keys(form.errors).length ? (
|
|
41
|
-
<div className="mt-2">
|
|
42
|
-
<ErrorList errors={form.errors} />
|
|
43
|
-
</div>
|
|
44
|
-
) : null}
|
|
45
|
-
|
|
46
40
|
<KolForm
|
|
41
|
+
_errorList={sectionSubmitted ? errorList : []}
|
|
47
42
|
_on={{
|
|
48
43
|
onSubmit: () => {
|
|
49
44
|
void form.submitForm();
|
|
@@ -81,7 +76,7 @@ export function AvailableAppointmentsForm() {
|
|
|
81
76
|
<Field name="time">
|
|
82
77
|
{({ field }: FieldProps<FormValues['time']>) => (
|
|
83
78
|
<KolInputRadio
|
|
84
|
-
id="field-
|
|
79
|
+
id="field-time"
|
|
85
80
|
_label="Zeit"
|
|
86
81
|
_orientation="horizontal"
|
|
87
82
|
_options={availableTimes}
|
|
@@ -92,10 +87,12 @@ export function AvailableAppointmentsForm() {
|
|
|
92
87
|
_on={{
|
|
93
88
|
onChange: (event: Event, value: unknown): void => {
|
|
94
89
|
if (event.target) {
|
|
95
|
-
void form.setFieldTouched('time', true);
|
|
96
90
|
void form.setFieldValue('time', value, true);
|
|
97
91
|
}
|
|
98
92
|
},
|
|
93
|
+
onBlur: () => {
|
|
94
|
+
void form.setFieldTouched('time', true);
|
|
95
|
+
},
|
|
99
96
|
}}
|
|
100
97
|
/>
|
|
101
98
|
)}
|
|
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { KolButton, KolForm, KolHeading, KolSelect } from '@public-ui/react';
|
|
3
3
|
import { Field, FieldProps, useFormikContext } from 'formik';
|
|
4
4
|
import { FormValues } from './AppointmentForm';
|
|
5
|
-
import {
|
|
5
|
+
import { createErrorList } from './formUtils';
|
|
6
6
|
|
|
7
7
|
const LOCATION_OPTIONS = [
|
|
8
8
|
{
|
|
@@ -32,13 +32,6 @@ export function DistrictForm() {
|
|
|
32
32
|
const [sectionSubmitted, setSectionSubmitted] = useState(false);
|
|
33
33
|
const errorList = createErrorList(form.errors);
|
|
34
34
|
|
|
35
|
-
function createErrorList(formikErrors: Record<string, string>): ErrorListPropType[] {
|
|
36
|
-
return Object.keys(formikErrors).map((fieldName) => ({
|
|
37
|
-
message: formikErrors[fieldName],
|
|
38
|
-
selector: `#field-${fieldName}`,
|
|
39
|
-
}));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
35
|
return (
|
|
43
36
|
<div className="p-2">
|
|
44
37
|
<KolHeading _level={2} _label="Wählen Sie einen Stadtteil aus"></KolHeading>
|
|
@@ -62,11 +55,13 @@ export function DistrictForm() {
|
|
|
62
55
|
_touched={form.touched.district}
|
|
63
56
|
_required
|
|
64
57
|
_on={{
|
|
58
|
+
onBlur: () => {
|
|
59
|
+
void form.setFieldTouched('district', true);
|
|
60
|
+
},
|
|
65
61
|
onChange: (event, values: unknown) => {
|
|
66
62
|
// Select und Radio setzen den Wert immer initial.
|
|
67
63
|
if (event.target) {
|
|
68
64
|
const [value] = values as [FormValues['district']];
|
|
69
|
-
void form.setFieldTouched('district', true);
|
|
70
65
|
void form.setFieldValue('district', value, true);
|
|
71
66
|
}
|
|
72
67
|
},
|
|
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { KolButton, KolForm, KolHeading, KolInputEmail, KolInputText, KolSelect } from '@public-ui/react';
|
|
3
3
|
import { Field, FieldProps, useFormikContext } from 'formik';
|
|
4
4
|
import { FormValues } from './AppointmentForm';
|
|
5
|
+
import { createErrorList } from './formUtils';
|
|
5
6
|
|
|
6
7
|
const SALUTATION_OPTIONS = [
|
|
7
8
|
{
|
|
@@ -25,12 +26,13 @@ const SALUTATION_OPTIONS = [
|
|
|
25
26
|
export function PersonalInformationForm() {
|
|
26
27
|
const form = useFormikContext<FormValues>();
|
|
27
28
|
const [sectionSubmitted, setSectionSubmitted] = useState(false);
|
|
29
|
+
const errorList = createErrorList(form.errors);
|
|
28
30
|
|
|
29
31
|
return (
|
|
30
32
|
<div className="p-2">
|
|
31
33
|
<KolHeading _level={2} _label="Geben Sie Ihre Kontaktdaten ein"></KolHeading>
|
|
32
|
-
<ul>{sectionSubmitted && Object.entries(form.errors).map(([field, error]) => <li key={field}>{error}</li>)}</ul>
|
|
33
34
|
<KolForm
|
|
35
|
+
_errorList={sectionSubmitted ? errorList : []}
|
|
34
36
|
_on={{
|
|
35
37
|
onSubmit: () => {
|
|
36
38
|
void form.submitForm();
|
|
@@ -41,6 +43,10 @@ export function PersonalInformationForm() {
|
|
|
41
43
|
<Field name="salutation">
|
|
42
44
|
{({ field }: FieldProps<FormValues['salutation']>) => (
|
|
43
45
|
<KolSelect
|
|
46
|
+
onBlur={() => {
|
|
47
|
+
void form.setFieldTouched('salutation', true);
|
|
48
|
+
}}
|
|
49
|
+
id="field-salutation"
|
|
44
50
|
_label="Anrede"
|
|
45
51
|
_value={[field.value]}
|
|
46
52
|
_error={form.errors.salutation || ''}
|
|
@@ -48,10 +54,12 @@ export function PersonalInformationForm() {
|
|
|
48
54
|
_options={[{ label: 'Bitte wählen…', value: '' }, ...SALUTATION_OPTIONS]}
|
|
49
55
|
_required
|
|
50
56
|
_on={{
|
|
57
|
+
onBlur: () => {
|
|
58
|
+
void form.setFieldTouched('salutation', true);
|
|
59
|
+
},
|
|
51
60
|
onChange: (event, values: unknown) => {
|
|
52
61
|
if (event.target) {
|
|
53
62
|
const [value] = values as [FormValues['salutation']];
|
|
54
|
-
void form.setFieldTouched('salutation', true);
|
|
55
63
|
void form.setFieldValue('salutation', value, true);
|
|
56
64
|
}
|
|
57
65
|
},
|
|
@@ -65,15 +73,18 @@ export function PersonalInformationForm() {
|
|
|
65
73
|
{({ field }: FieldProps<FormValues['company']>) => (
|
|
66
74
|
<div className="block mt-2">
|
|
67
75
|
<KolInputText
|
|
76
|
+
id="field-company"
|
|
68
77
|
_label="Firma"
|
|
69
78
|
_value={field.value}
|
|
70
79
|
_error={form.errors.company || ''}
|
|
71
80
|
_touched={form.touched.company}
|
|
72
81
|
_required
|
|
73
82
|
_on={{
|
|
83
|
+
onBlur: () => {
|
|
84
|
+
void form.setFieldTouched('company', true);
|
|
85
|
+
},
|
|
74
86
|
onChange: (event, value: unknown) => {
|
|
75
87
|
if (event.target) {
|
|
76
|
-
void form.setFieldTouched('company', true);
|
|
77
88
|
void form.setFieldValue('company', value, true);
|
|
78
89
|
}
|
|
79
90
|
},
|
|
@@ -88,15 +99,18 @@ export function PersonalInformationForm() {
|
|
|
88
99
|
{({ field }: FieldProps<FormValues['name']>) => (
|
|
89
100
|
<div className="block mt-2">
|
|
90
101
|
<KolInputText
|
|
102
|
+
id="field-name"
|
|
91
103
|
_label="Vor- und Zuname"
|
|
92
104
|
_value={field.value}
|
|
93
105
|
_error={form.errors.name || ''}
|
|
94
106
|
_touched={form.touched.name}
|
|
95
107
|
_required
|
|
96
108
|
_on={{
|
|
109
|
+
onBlur: () => {
|
|
110
|
+
void form.setFieldTouched('name', true);
|
|
111
|
+
},
|
|
97
112
|
onChange: (event, value: unknown) => {
|
|
98
113
|
if (event.target) {
|
|
99
|
-
void form.setFieldTouched('name', true);
|
|
100
114
|
void form.setFieldValue('name', value, true);
|
|
101
115
|
}
|
|
102
116
|
},
|
|
@@ -110,15 +124,21 @@ export function PersonalInformationForm() {
|
|
|
110
124
|
{({ field }: FieldProps<FormValues['email']>) => (
|
|
111
125
|
<div className="block mt-2">
|
|
112
126
|
<KolInputEmail
|
|
127
|
+
onBlur={() => {
|
|
128
|
+
void form.setFieldTouched('email', true);
|
|
129
|
+
}}
|
|
130
|
+
id="field-email"
|
|
113
131
|
_label="E-Mail"
|
|
114
132
|
_value={field.value}
|
|
115
133
|
_error={form.errors.email || ''}
|
|
116
134
|
_touched={form.touched.email}
|
|
117
135
|
_required
|
|
118
136
|
_on={{
|
|
137
|
+
onBlur: () => {
|
|
138
|
+
void form.setFieldTouched('email', true);
|
|
139
|
+
},
|
|
119
140
|
onChange: (event, value: unknown) => {
|
|
120
141
|
if (event.target) {
|
|
121
|
-
void form.setFieldTouched('email', true);
|
|
122
142
|
void form.setFieldValue('email', value, true);
|
|
123
143
|
}
|
|
124
144
|
},
|
|
@@ -132,15 +152,18 @@ export function PersonalInformationForm() {
|
|
|
132
152
|
{({ field }: FieldProps<FormValues['phone']>) => (
|
|
133
153
|
<div className="block mt-2">
|
|
134
154
|
<KolInputText
|
|
155
|
+
id="field-phone"
|
|
135
156
|
_type="tel"
|
|
136
157
|
_label="Telefonnumer"
|
|
137
158
|
_value={field.value}
|
|
138
159
|
_error={form.errors.phone || ''}
|
|
139
160
|
_touched={form.touched.phone}
|
|
140
161
|
_on={{
|
|
162
|
+
onBlur: () => {
|
|
163
|
+
void form.setFieldTouched('phone', true);
|
|
164
|
+
},
|
|
141
165
|
onChange: (event, value: unknown) => {
|
|
142
166
|
if (event.target) {
|
|
143
|
-
void form.setFieldTouched('phone', true);
|
|
144
167
|
void form.setFieldValue('phone', value, true);
|
|
145
168
|
}
|
|
146
169
|
},
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ErrorListPropType } from '@public-ui/components';
|
|
2
|
+
|
|
3
|
+
export function createErrorList(formikErrors: Record<string, string>): ErrorListPropType[] {
|
|
4
|
+
return Object.keys(formikErrors).map((fieldName) => ({
|
|
5
|
+
message: formikErrors[fieldName],
|
|
6
|
+
selector: `#field-${fieldName}`,
|
|
7
|
+
}));
|
|
8
|
+
}
|
package/src/scenarios/routes.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Routes } from '../shares/types';
|
|
2
|
-
import { TerminComponent } from './complex-form/component';
|
|
3
2
|
import { AppointmentForm } from './appointment-form/AppointmentForm';
|
|
3
|
+
import { TerminComponent } from './complex-form/component';
|
|
4
4
|
import { CustomTooltipWidth } from './custom-tooltip-width';
|
|
5
|
+
import { StaticForm } from './static-form';
|
|
5
6
|
|
|
6
7
|
export const SCENARIO_ROUTES: Routes = {
|
|
7
8
|
scenarios: {
|
|
8
9
|
'complex-form': TerminComponent,
|
|
9
10
|
'appointment-form': AppointmentForm,
|
|
10
11
|
'custom-tooltip-width': CustomTooltipWidth,
|
|
12
|
+
'static-form': StaticForm,
|
|
11
13
|
},
|
|
12
14
|
};
|