@pinuts/bsr-uikit-relaunch 0.3.5 → 0.4.2

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 (133) hide show
  1. package/config-overrides.js +1 -0
  2. package/dist/hooks/useValidationMessage.d.ts.map +1 -1
  3. package/dist/hooks/useValidationMessage.js +8 -1
  4. package/dist/hooks/withFieldGroup.d.ts.map +1 -1
  5. package/dist/hooks/withFieldGroup.js +35 -1
  6. package/dist/index.d.ts +4 -0
  7. package/dist/index.js +1 -1
  8. package/dist/items/AbholdatumMaterialienField/AbholdatumMaterialienField.d.ts +25 -0
  9. package/dist/items/AbholdatumMaterialienField/AbholdatumMaterialienField.d.ts.map +1 -0
  10. package/dist/items/AbholdatumMaterialienField/AbholdatumMaterialienField.js +77 -0
  11. package/dist/items/AbholdatumMaterialienField/getAbholTermine.d.ts +7 -0
  12. package/dist/items/AbholdatumMaterialienField/getAbholTermine.d.ts.map +1 -0
  13. package/dist/items/AbholdatumMaterialienField/getAbholTermine.js +117 -0
  14. package/dist/items/AbholortMaterialienField/AbholortMaterialienField.d.ts +26 -0
  15. package/dist/items/AbholortMaterialienField/AbholortMaterialienField.d.ts.map +1 -0
  16. package/dist/items/AbholortMaterialienField/AbholortMaterialienField.js +73 -0
  17. package/dist/items/BSRAddressSelector/BSRAddressButtons.d.ts.map +1 -1
  18. package/dist/items/BSRAddressSelector/BSRAddressButtons.js +10 -0
  19. package/dist/items/BSRAddressSelector/BSRAddressSelector.d.ts +1 -0
  20. package/dist/items/BSRAddressSelector/BSRAddressSelector.d.ts.map +1 -1
  21. package/dist/items/BSRAddressSelector/BSRAddressSelector.js +21 -2
  22. package/dist/items/BSRAddressSelector/BSRAutocompleteField.d.ts.map +1 -1
  23. package/dist/items/BSRAddressSelector/BSRAutocompleteField.js +14 -3
  24. package/dist/items/BSRAddressSelector/BSRStreetPlzSelector.d.ts.map +1 -1
  25. package/dist/items/BSRAddressSelector/BSRStreetPlzSelector.js +6 -0
  26. package/dist/items/BSRAddressSelector/HouseNumberSelectField.d.ts.map +1 -1
  27. package/dist/items/BSRAddressSelector/HouseNumberSelectField.js +5 -0
  28. package/dist/items/BootstrapInputGroupField/BootstrapInputGroupField.d.ts.map +1 -1
  29. package/dist/items/BootstrapInputGroupField/BootstrapInputGroupField.js +2 -1
  30. package/dist/items/DateInputField/DateInputField.d.ts.map +1 -1
  31. package/dist/items/DateInputField/DateInputField.js +2 -1
  32. package/dist/items/FileUploadField/FileUploadField.d.ts +4 -0
  33. package/dist/items/FileUploadField/FileUploadField.d.ts.map +1 -0
  34. package/dist/items/FileUploadField/FileUploadField.js +271 -0
  35. package/dist/items/FileUploadField/uploadedFileStore.d.ts +4 -0
  36. package/dist/items/FileUploadField/uploadedFileStore.d.ts.map +1 -0
  37. package/dist/items/FileUploadField/uploadedFileStore.js +31 -0
  38. package/dist/items/FormFieldWrapper/FormFieldChildPropTypes.d.ts +1 -0
  39. package/dist/items/FormFieldWrapper/FormFieldChildPropTypes.d.ts.map +1 -1
  40. package/dist/items/FormFieldWrapper/FormFieldChildPropTypes.js +1 -0
  41. package/dist/items/GroupInputField/GroupInputField.d.ts.map +1 -1
  42. package/dist/items/GroupInputField/GroupInputField.js +41 -4
  43. package/dist/items/Modal/Modal.d.ts.map +1 -1
  44. package/dist/items/Modal/Modal.js +6 -1
  45. package/dist/items/MultiSelectField/MultiSelectField.d.ts.map +1 -1
  46. package/dist/items/MultiSelectField/MultiSelectField.js +15 -2
  47. package/dist/items/NumberInputField/NumberInputField.d.ts.map +1 -1
  48. package/dist/items/NumberInputField/NumberInputField.js +2 -1
  49. package/dist/items/ReviewValue/ReviewValueList.d.ts +17 -0
  50. package/dist/items/ReviewValue/ReviewValueList.d.ts.map +1 -0
  51. package/dist/items/ReviewValue/ReviewValueList.js +36 -0
  52. package/dist/items/SectionSpinner/SectionSpinner.d.ts +1 -0
  53. package/dist/items/SectionSpinner/SectionSpinner.d.ts.map +1 -1
  54. package/dist/items/SelectField/SelectField.d.ts.map +1 -1
  55. package/dist/items/SelectField/SelectField.js +3 -2
  56. package/dist/items/StaticAlert/StaticAlert.d.ts +1 -0
  57. package/dist/items/StaticAlert/StaticAlert.d.ts.map +1 -1
  58. package/dist/items/TextAreaField/TextAreaField.d.ts.map +1 -1
  59. package/dist/items/TextAreaField/TextAreaField.js +8 -0
  60. package/dist/items/TextBox/TextBox.d.ts +1 -0
  61. package/dist/items/TextBox/TextBox.d.ts.map +1 -1
  62. package/dist/items/TextBox/TextBox.js +11 -2
  63. package/dist/items/TextInputField/TextInputField.d.ts.map +1 -1
  64. package/dist/items/TextInputField/TextInputField.js +8 -1
  65. package/dist/items/Toast/Toast.d.ts +1 -0
  66. package/dist/items/Toast/Toast.d.ts.map +1 -1
  67. package/dist/items/ToggleSwitchField/ToggleSwitchField.d.ts.map +1 -1
  68. package/dist/items/ToggleSwitchField/ToggleSwitchField.js +2 -1
  69. package/dist/items/index.d.ts +4 -1
  70. package/dist/items/index.d.ts.map +1 -1
  71. package/dist/items/index.js +22 -1
  72. package/dist/items/validations.d.ts.map +1 -0
  73. package/dist/items/validations.js +27 -0
  74. package/dist/locales.d.ts +73 -2
  75. package/dist/locales.js +64 -0
  76. package/dist/shared/ErrorMessagesInfoBox/ErrorMessagesInfoBox.d.ts +16 -0
  77. package/dist/shared/ErrorMessagesInfoBox/ErrorMessagesInfoBox.d.ts.map +1 -0
  78. package/dist/shared/ErrorMessagesInfoBox/ErrorMessagesInfoBox.js +144 -0
  79. package/dist/shared/FormWidget/FormWidget.d.ts +30 -0
  80. package/dist/shared/FormWidget/FormWidget.d.ts.map +1 -0
  81. package/dist/shared/FormWidget/FormWidget.js +165 -0
  82. package/dist/shared/FormWidget/FormWidgetControlPage.d.ts +29 -0
  83. package/dist/shared/FormWidget/FormWidgetControlPage.d.ts.map +1 -0
  84. package/dist/shared/FormWidget/FormWidgetControlPage.js +84 -0
  85. package/dist/shared/FormWidget/FormWidgetFormPage.d.ts +26 -0
  86. package/dist/shared/FormWidget/FormWidgetFormPage.d.ts.map +1 -0
  87. package/dist/shared/FormWidget/FormWidgetFormPage.js +55 -0
  88. package/dist/shared/FormWidget/FormWidgetMessagePage.d.ts +20 -0
  89. package/dist/shared/FormWidget/FormWidgetMessagePage.d.ts.map +1 -0
  90. package/dist/shared/FormWidget/FormWidgetMessagePage.js +37 -0
  91. package/dist/shared/FormWidget/captions.d.ts +33 -0
  92. package/dist/shared/FormWidget/captions.d.ts.map +1 -0
  93. package/dist/shared/FormWidget/captions.js +43 -0
  94. package/dist/shared/KehrenbuergerForm/KehrenbuergerForm.d.ts +23 -0
  95. package/dist/shared/KehrenbuergerForm/KehrenbuergerForm.d.ts.map +1 -0
  96. package/dist/shared/KehrenbuergerForm/KehrenbuergerForm.js +173 -0
  97. package/dist/styles/_errorMessagesInfoBox.scss +42 -0
  98. package/dist/styles/_form.scss +9 -0
  99. package/dist/styles/_review.scss +29 -0
  100. package/dist/styles/main.scss +62 -49
  101. package/dist/styles/variables/_buttons.scss +8 -7
  102. package/dist/styles/variables/_variables.scss +15 -2
  103. package/dist/utils/files/convertFilesToUploadFiles.d.ts +8 -0
  104. package/dist/utils/files/convertFilesToUploadFiles.d.ts.map +1 -0
  105. package/dist/utils/files/convertFilesToUploadFiles.js +33 -0
  106. package/dist/utils/files/formatFileSize.d.ts +3 -0
  107. package/dist/utils/files/formatFileSize.d.ts.map +1 -0
  108. package/dist/utils/files/formatFileSize.js +44 -0
  109. package/dist/utils/files/generateUniqueFilename.d.ts +3 -0
  110. package/dist/utils/files/generateUniqueFilename.d.ts.map +1 -0
  111. package/dist/utils/files/generateUniqueFilename.js +32 -0
  112. package/dist/utils/files/index.d.ts +7 -0
  113. package/dist/utils/files/index.d.ts.map +1 -0
  114. package/dist/utils/files/index.js +71 -0
  115. package/dist/utils/files/validateFiles.d.ts +9 -0
  116. package/dist/utils/files/validateFiles.d.ts.map +1 -0
  117. package/dist/utils/files/validateFiles.js +28 -0
  118. package/dist/utils/files/validateFilesBySize.d.ts +6 -0
  119. package/dist/utils/files/validateFilesBySize.d.ts.map +1 -0
  120. package/dist/utils/files/validateFilesBySize.js +31 -0
  121. package/dist/utils/files/validateFilesByType.d.ts +9 -0
  122. package/dist/utils/files/validateFilesByType.d.ts.map +1 -0
  123. package/dist/utils/files/validateFilesByType.js +79 -0
  124. package/dist/utils/index.d.ts +1 -0
  125. package/dist/utils/index.js +11 -0
  126. package/dist/utils/reviewValue.d.ts +3 -0
  127. package/dist/utils/reviewValue.d.ts.map +1 -0
  128. package/dist/utils/reviewValue.js +16 -0
  129. package/package.json +1 -1
  130. package/webpack.config.js +3 -0
  131. package/dist/items/eventWizardItems/validations.d.ts.map +0 -1
  132. package/dist/items/eventWizardItems/validations.js +0 -7
  133. /package/dist/items/{eventWizardItems/validations.d.ts → validations.d.ts} +0 -0
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+ var _reactI18next = require("react-i18next");
10
+ var _HTMLParserSanitized = require("../../items/HTMLParserSanitized/HTMLParserSanitized.jsx");
11
+ var _SectionSpinner = _interopRequireDefault(require("../../items/SectionSpinner/SectionSpinner.jsx"));
12
+ var _isWindowAvailable = require("../../utils/isWindowAvailable.js");
13
+ var _FormWidget = _interopRequireDefault(require("../FormWidget/FormWidget.jsx"));
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
+ const WIDGET_CONFIG_PATH = '/de.bsr.kehrenbuerger.widget/formConfig';
18
+ const AKTION_PATH = '/de.bsr.kehrenbuerger.aktionen/aktion';
19
+
20
+ // Leere Captions rausfiltern, damit die Defaults des FormWidget greifen
21
+ const withoutEmpty = caption => Object.fromEntries(Object.entries(caption).filter(_ref => {
22
+ let [, text] = _ref;
23
+ return Boolean(text);
24
+ }));
25
+
26
+ // Das Backend liefert die Kehrenbürger-Struktur (formPage/confirmPage/...),
27
+ // das FormWidget erwartet formPage/controlPage/successPage.
28
+ const mapCaptions = function () {
29
+ let captions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
30
+ return {
31
+ formPage: withoutEmpty({
32
+ header: captions.formPage?.header,
33
+ text: captions.formPage?.text,
34
+ submitBtn: captions.formPage?.nextBtn
35
+ }),
36
+ controlPage: withoutEmpty({
37
+ header: captions.confirmPage?.header,
38
+ text: captions.confirmPage?.text,
39
+ backBtn: captions.confirmPage?.backBtn,
40
+ submitBtn: captions.confirmPage?.saveBtn
41
+ }),
42
+ successPage: withoutEmpty({
43
+ header: captions.successPage?.header,
44
+ text: captions.successPage?.text
45
+ })
46
+ };
47
+ };
48
+
49
+ // Das Backend erwartet die Werte unter "data"
50
+ const transformPayload = values => ({
51
+ data: values
52
+ });
53
+
54
+ // Bestätigungs-Link (Double-Opt-In): ?c=<aktionId> in der URL.
55
+ // Prod nutzt normale URLs (?c=... vor dem #), die CMS-Vorschau Hash-URLs
56
+ // (#/pfad?c=...) - deshalb beide Stellen prüfen.
57
+ const getDoiAktionId = () => {
58
+ if (!(0, _isWindowAvailable.isWindowAvailable)()) {
59
+ return null;
60
+ }
61
+ const fromSearch = new URLSearchParams(window.location.search).get('c');
62
+ if (fromSearch) {
63
+ return fromSearch;
64
+ }
65
+ const hash = window.location.hash || '';
66
+ const queryIndex = hash.indexOf('?');
67
+ return queryIndex === -1 ? null : new URLSearchParams(hash.slice(queryIndex + 1)).get('c');
68
+ };
69
+
70
+ /**
71
+ * Kehrenbürger-Anmeldeformular als eigenständige Komponente (ohne HTML-Rahmen).
72
+ * Lädt FormConfig und Captions vom RestProxy und rendert das FormWidget.
73
+ *
74
+ * Enthält die URL einen `c`-Parameter, ist es ein DOI-Bestätigungslink: dann
75
+ * wird die Anmeldung per PUT bestätigt und nur die Bestätigungsmeldung gezeigt.
76
+ */
77
+ const KehrenbuergerForm = _ref2 => {
78
+ let {
79
+ restUrl = '/p',
80
+ showControlPage = true,
81
+ className
82
+ } = _ref2;
83
+ const [t] = (0, _reactI18next.useTranslation)();
84
+ const configUrl = `${restUrl}${WIDGET_CONFIG_PATH}`;
85
+ const submitUrl = `${restUrl}${AKTION_PATH}`;
86
+ const doiAktionId = (0, _react.useMemo)(() => getDoiAktionId(), []);
87
+ const isDoiMode = Boolean(doiAktionId);
88
+ const [formConfig, setFormConfig] = (0, _react.useState)(null);
89
+ const [rawCaptions, setRawCaptions] = (0, _react.useState)(null);
90
+ const [loadError, setLoadError] = (0, _react.useState)(false);
91
+ const [doiMessage, setDoiMessage] = (0, _react.useState)('');
92
+
93
+ // FormConfig + Captions laden (Captions werden auch im DOI-Modus gebraucht)
94
+ (0, _react.useEffect)(() => {
95
+ let aborted = false;
96
+ fetch(configUrl).then(response => {
97
+ if (!response.ok) {
98
+ throw new Error(`${configUrl} antwortete mit Status ${response.status}`);
99
+ }
100
+ return response.json();
101
+ }).then(json => {
102
+ if (aborted) {
103
+ return;
104
+ }
105
+ const formConfigs = json?.data?.formConfigs;
106
+ if (!formConfigs?.anmeldung) {
107
+ throw new Error('In der Antwort fehlt data.formConfigs.anmeldung');
108
+ }
109
+ setFormConfig(formConfigs.anmeldung);
110
+ setRawCaptions(formConfigs.captions || {});
111
+ }).catch(() => {
112
+ if (!aborted) {
113
+ setLoadError(true);
114
+ }
115
+ });
116
+ return () => {
117
+ aborted = true;
118
+ };
119
+ }, [configUrl]);
120
+
121
+ // DOI: Anmeldung per PUT bestätigen, sobald die Captions da sind
122
+ const doiConfirmed = (0, _react.useRef)(false);
123
+ (0, _react.useEffect)(() => {
124
+ if (!isDoiMode || !rawCaptions || doiConfirmed.current) {
125
+ return;
126
+ }
127
+ doiConfirmed.current = true;
128
+ const doiCaption = rawCaptions.doiPage || {};
129
+ fetch(`${submitUrl}/doi/${doiAktionId}`, {
130
+ method: 'PUT',
131
+ credentials: 'include',
132
+ headers: {
133
+ 'X-CSRF-Safe': 'yes'
134
+ }
135
+ }).then(response => response.json().catch(() => ({}))).then(json => {
136
+ setDoiMessage(json?.success ? doiCaption.success : doiCaption.failed);
137
+ }).catch(() => {
138
+ setDoiMessage(doiCaption.failed);
139
+ });
140
+ }, [isDoiMode, rawCaptions, doiAktionId, submitUrl]);
141
+ const captions = (0, _react.useMemo)(() => mapCaptions(rawCaptions || {}), [rawCaptions]);
142
+ if (loadError) {
143
+ return /*#__PURE__*/_react.default.createElement("div", {
144
+ className: "alert alert-danger"
145
+ }, t('bsrItems.kehrenbuerger.loadError'));
146
+ }
147
+ if (!formConfig || !rawCaptions) {
148
+ return /*#__PURE__*/_react.default.createElement(_SectionSpinner.default, null);
149
+ }
150
+ if (isDoiMode) {
151
+ const doiCaption = rawCaptions.doiPage || {};
152
+ return /*#__PURE__*/_react.default.createElement("div", {
153
+ className: className
154
+ }, doiCaption.header && /*#__PURE__*/_react.default.createElement("h1", null, doiCaption.header), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_HTMLParserSanitized.HTMLParserSanitized, null, doiMessage || t('bsrItems.kehrenbuerger.waitDoi'))));
155
+ }
156
+ return /*#__PURE__*/_react.default.createElement(_FormWidget.default, {
157
+ className: className,
158
+ formId: "kehrenbuerger",
159
+ formConfig: formConfig,
160
+ captions: captions,
161
+ submitUrl: submitUrl,
162
+ method: "POST",
163
+ showControlPage: showControlPage,
164
+ transformPayload: transformPayload
165
+ });
166
+ };
167
+ KehrenbuergerForm.propTypes = {
168
+ // Basis-URL des RestProxy, z.B. '/p'
169
+ restUrl: _propTypes.default.string,
170
+ showControlPage: _propTypes.default.bool,
171
+ className: _propTypes.default.string
172
+ };
173
+ var _default = exports.default = KehrenbuergerForm;
@@ -0,0 +1,42 @@
1
+ // Fehlerbox über dem Formular. Klassen und Styles entsprechen den BSR-Formularen
2
+ // (vgl. sepa-basis-lastschriftmandat-cf2), damit die Box in Consumer-Projekten
3
+ // mit BSR-Styles identisch aussieht - und ohne sie ebenfalls korrekt.
4
+ .pi-form-control__has-error {
5
+ display: block;
6
+
7
+ .pi-message-text {
8
+ display: flex;
9
+ flex-direction: column;
10
+ margin: 0 0 ($base-gap * 4);
11
+ padding: ($base-gap * 3) ($base-gap * 5); // 12px 20px
12
+ border: $bsr-border-width-l solid $error;
13
+ border-radius: $border-radius;
14
+ background-color: $white;
15
+ color: $error;
16
+ box-shadow: $bsr-shadow-default;
17
+
18
+ // leere Elemente (z.B. Caption ohne Text) nicht als Lücke rendern
19
+ > *:empty {
20
+ display: none;
21
+ }
22
+
23
+ p {
24
+ margin: 0 0 ($base-gap * 4);
25
+ font-weight: $fontweight-bold;
26
+ }
27
+
28
+ ul {
29
+ margin: 0;
30
+ padding-inline-start: $base-gap * 2;
31
+ }
32
+
33
+ li {
34
+ color: $error;
35
+
36
+ a {
37
+ color: $bsr-black-90;
38
+ text-decoration: underline;
39
+ }
40
+ }
41
+ }
42
+ }
@@ -228,6 +228,15 @@ textarea {
228
228
  line-height: $input-label-line-height;
229
229
  }
230
230
 
231
+ // Adresse des gewählten Abholorts, unterhalb der Selectbox
232
+ .abholort-adresse {
233
+ display: block;
234
+ margin-block-start: $base-gap * 2;
235
+ color: $bsr-black-90;
236
+ font-size: $input-label-font-size;
237
+ line-height: $input-label-line-height;
238
+ }
239
+
231
240
  [aria-disabled="true"] {
232
241
  input,
233
242
  label {
@@ -0,0 +1,29 @@
1
+ // Kontrollseite (reviewMode). Bewusst minimal: die visuelle Feinabstimmung
2
+ // (Kontraste, Abstände) folgt in einem eigenen Schritt.
3
+ .pi-review {
4
+ .pi-review-item {
5
+ margin: 0;
6
+ }
7
+
8
+ .pi-review-pair {
9
+ margin-bottom: $base-gap * 3;
10
+ }
11
+
12
+ dt {
13
+ font-weight: $fontweight-bold;
14
+ }
15
+
16
+ dd {
17
+ margin: 0;
18
+ }
19
+
20
+ // Zeilenumbrüche aus Textarea-Eingaben sichtbar halten
21
+ .pi-review-multiline {
22
+ white-space: pre-line;
23
+ }
24
+
25
+ .pi-review-values {
26
+ margin: 0;
27
+ padding-inline-start: $base-gap * 4;
28
+ }
29
+ }
@@ -1,92 +1,105 @@
1
1
  @use "sass:math";
2
2
  @import "./variables/_variables.scss";
3
- @import "./ariakit_combobox";
4
- @import "./form";
5
3
 
6
- .sr-only {
7
- display: none;
8
- }
4
+ // All CSS-emitting styles are scoped under `.bsr-uikit` so the UI-KIT's
5
+ // global styles (element selectors like h1/body/p and class rules) do not
6
+ // leak into consumer projects. Consumers opt in by adding the class
7
+ // `bsr-uikit` to a wrapping element (e.g. the app root or a container
8
+ // around UI-KIT components).
9
+ //
10
+ // Note: _variables.scss above only defines SCSS variables/functions and
11
+ // emits no CSS, so it stays outside the wrapper.
12
+ .bsr-uikit {
13
+ @import "./ariakit_combobox";
14
+ @import "./form";
15
+ @import "./errorMessagesInfoBox";
16
+ @import "./review";
17
+ @import "./variables/_buttons.scss";
18
+ @import "./variables/_images.scss";
9
19
 
10
- [aria-disabled="true"] {
11
- input,
12
- label {
13
- color: $bsr-black-40;
14
- border-color: $bsr-black-40;
15
- pointer-events: none;
16
- }
17
- input {
18
- background: $bsr-black-10;
20
+ // Base font previously applied to `body`; scoped to the wrapper element
21
+ // itself so it does not leak to the consumer's <body>.
22
+ font-family: $fontfamily-base;
23
+ font-size: $defaultBrowserFontSize;
24
+
25
+ .sr-only {
26
+ display: none;
19
27
  }
20
- }
21
28
 
22
- body {
23
- font-family: $fontfamily-base;
24
- font-size: $defaultBrowserFontSize;
25
- }
29
+ [aria-disabled="true"] {
30
+ input,
31
+ label {
32
+ color: $bsr-black-40;
33
+ border-color: $bsr-black-40;
34
+ pointer-events: none;
35
+ }
36
+ input {
37
+ background: $bsr-black-10;
38
+ }
39
+ }
26
40
 
27
- p, span {
41
+ p, span {
28
42
  font-family: $fontfamily-base;
29
- }
43
+ }
30
44
 
31
- h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
45
+ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
32
46
  font-family: $fontfamily-heading;
33
47
  color: $bsr-black-90;
34
48
  font-weight: $fontweight-bold;
35
49
  scroll-margin-top: $base-gap * 18;
36
- }
50
+ }
37
51
 
38
- h1, .h1 {
52
+ h1, .h1 {
39
53
  font-size: $h1-fontsize;
40
54
  line-height: $h1-lineheight;
41
55
  letter-spacing: $letter-spacing-lg;
42
- margin-bottom: $base-gap * 10;
43
56
 
44
57
  @media screen and (max-width: $screen-sm-max) {
45
- font-size: $h1-fontsize-sm;
46
- line-height: $h1-lineheight-sm;
47
- letter-spacing: $letter-spacing-sm;
48
- margin-bottom: $base-gap * 3;
58
+ font-size: $h1-fontsize-sm;
59
+ line-height: $h1-lineheight-sm;
60
+ letter-spacing: $letter-spacing-sm;
49
61
  }
50
- }
62
+ }
51
63
 
52
- h2, .h2 {
64
+ h2, .h2 {
53
65
  font-size: $h2-fontsize;
54
66
  line-height: $h2-lineheight;
55
67
  letter-spacing: $letter-spacing-md;
56
68
  margin-bottom: $base-gap * 5;
57
69
 
58
70
  @media screen and (max-width: $screen-sm-max) {
59
- font-size: $h2-fontsize-sm;
60
- line-height: $h2-lineheight-sm;
61
- margin-bottom: $base-gap * 3;
71
+ font-size: $h2-fontsize-sm;
72
+ line-height: $h2-lineheight-sm;
73
+ margin-bottom: $base-gap * 3;
62
74
  }
63
- }
75
+ }
64
76
 
65
- h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
77
+ h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
66
78
  margin-bottom: $base-gap * 5;
67
79
  margin-top: $base-gap * 10;
68
80
  color: $bsr-black-90;
69
81
 
70
82
  @media screen and (max-width: $screen-sm-max) {
71
- font-size: $h3-fontsize-sm;
72
- line-height: $h3-lineheight-sm;
73
- margin-bottom: $base-gap * 3;
74
- margin-top: $base-gap * 8;
83
+ font-size: $h3-fontsize-sm;
84
+ line-height: $h3-lineheight-sm;
85
+ margin-bottom: $base-gap * 3;
86
+ margin-top: $base-gap * 8;
75
87
  }
76
- }
88
+ }
77
89
 
78
- q {
90
+ q {
79
91
  font-family: $fontfamily-heading;
80
- }
92
+ }
81
93
 
82
- footer {
94
+ footer {
83
95
  font-family: $fontfamily-heading;
84
- }
96
+ }
85
97
 
86
- .rbc-wrapper .rbc-calendar {
98
+ .rbc-wrapper .rbc-calendar {
87
99
  font-family: $fontfamily-base;
88
- }
100
+ }
89
101
 
90
- .rbc-date-cell.rbc-now span {
102
+ .rbc-date-cell.rbc-now span {
91
103
  color: $bsr-brick-100;
92
- }
104
+ }
105
+ }
@@ -1,6 +1,7 @@
1
- $btn-border-radius: $border-radius-lg;
2
- $btn-padding-x: $base-gap * 6;
3
- $btn-padding-y: calc($base-gap * 2 - 1px);
1
+ // NOTE: $btn-border-radius / $btn-padding-x / $btn-padding-y were moved to
2
+ // variables/_variables.scss because they are also consumed by _form.scss and
3
+ // must be available in the variables layer (this file's CSS rules are imported
4
+ // later, inside the .bsr-uikit wrapper in main.scss).
4
5
 
5
6
  .btn,
6
7
  .pi-form-button button {
@@ -109,7 +110,7 @@ $btn-padding-y: calc($base-gap * 2 - 1px);
109
110
  border-color: $bsr-brick-100 !important;
110
111
  }
111
112
  }
112
- &:focus {
113
+ &:focus-visible {
113
114
  background-color: $bsr-white-100 !important;
114
115
  color: $bsr-black-90 !important;
115
116
  box-shadow: 0 0 0 0.25rem rgba($bsr-white-100, 0.5) !important;
@@ -143,7 +144,7 @@ $btn-padding-y: calc($base-gap * 2 - 1px);
143
144
  text-decoration: none;
144
145
 
145
146
  &:hover,
146
- &:focus,
147
+ &:focus-visible,
147
148
  &:active {
148
149
  background-color: $white !important;
149
150
  color: $text-secondary !important;
@@ -170,7 +171,7 @@ button[type="button"].btn.btn-primary, button[type="button"].btn.btn-secondary {
170
171
  &:focus-visible {
171
172
  text-decoration-color: currentColor;
172
173
  }
173
-
174
+
174
175
  &:focus,
175
176
  &:focus-visible {
176
177
  outline: none;
@@ -193,7 +194,7 @@ button[type="button"].btn.btn-secondary {
193
194
  background-color: $bsr-white-100;
194
195
  color: $bsr-brick-100;
195
196
  border: $bsr-border-width-m solid $bsr-brick-100;
196
-
197
+
197
198
  &:hover,
198
199
  &:focus-visible {
199
200
  background-color: $bsr-brick-100 !important;
@@ -4,11 +4,24 @@
4
4
  @import '_shadows.scss';
5
5
  @import '_borders.scss';
6
6
  @import '_fonts.scss';
7
- @import '_images.scss';
8
7
  @import '_fonts.scss';
9
- @import '_buttons.scss';
10
8
  @import '_focus.scss';
11
9
 
10
+ /* NOTE: _buttons.scss and _images.scss emit CSS (not just variables).
11
+ They are intentionally NOT imported here so that _variables.scss stays
12
+ side-effect free (it is imported by multiple entry files). They are
13
+ imported inside the .bsr-uikit wrapper in main.scss instead.
14
+
15
+ Use CSS block comments here, not SCSS line comments: this file is also
16
+ pulled into .module.scss entries via css-loader (no sass-loader), which
17
+ parses it as plain CSS and rejects SCSS double-slash comments. */
18
+
19
+ /* Button sizing variables. Kept here (not in _buttons.scss) because _form.scss
20
+ also consumes them and needs them available in the variables layer. */
21
+ $btn-border-radius: $border-radius-lg;
22
+ $btn-padding-x: $base-gap * 6;
23
+ $btn-padding-y: calc($base-gap * 2 - 1px);
24
+
12
25
  $font-family-main: 'TradeGothicNext', sans-serif;
13
26
  $base-transition: all 0.2s ease-in;
14
27
  $transition-duration-base: 0.2s;
@@ -0,0 +1,8 @@
1
+ export function convertFilesToUploadFiles(files: File[], existingNames?: Set<string>): {
2
+ id: any;
3
+ name: any;
4
+ size: number;
5
+ file: File;
6
+ }[];
7
+ export default convertFilesToUploadFiles;
8
+ //# sourceMappingURL=convertFilesToUploadFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convertFilesToUploadFiles.d.ts","sourceRoot":"","sources":["../../../src/utils/files/convertFilesToUploadFiles.js"],"names":[],"mappings":"AAWO,iDAHI,IAAI,EAAE,kBACN,GAAG,CAAC,MAAM,CAAC;;;;;IAkBrB"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.convertFilesToUploadFiles = void 0;
7
+ var _uuid = require("uuid");
8
+ var _generateUniqueFilename = require("./generateUniqueFilename.js");
9
+ /**
10
+ * Wandelt native File-Objekte in UploadFile-Objekte um:
11
+ * { id, name, size, file }. Doppelte Dateinamen bekommen einen Index
12
+ * ("datei (1).pdf").
13
+ *
14
+ * @param {File[]} files
15
+ * @param {Set<string>} existingNames bereits vergebene Namen
16
+ */
17
+ const convertFilesToUploadFiles = function (files) {
18
+ let existingNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
19
+ // Kopie, damit das übergebene Set nicht verändert wird
20
+ const usedNames = new Set(existingNames);
21
+ return files.map(file => {
22
+ const uniqueName = (0, _generateUniqueFilename.generateUniqueFilename)(file.name, usedNames);
23
+ usedNames.add(uniqueName);
24
+ return {
25
+ id: (0, _uuid.v4)(),
26
+ name: uniqueName,
27
+ size: file.size,
28
+ file
29
+ };
30
+ });
31
+ };
32
+ exports.convertFilesToUploadFiles = convertFilesToUploadFiles;
33
+ var _default = exports.default = convertFilesToUploadFiles;
@@ -0,0 +1,3 @@
1
+ export function formatFileSize(size: any, unit: any): string;
2
+ export default formatFileSize;
3
+ //# sourceMappingURL=formatFileSize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatFileSize.d.ts","sourceRoot":"","sources":["../../../src/utils/files/formatFileSize.js"],"names":[],"mappings":"AAUO,6DA+BN"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.formatFileSize = exports.default = void 0;
7
+ const KB = 1024;
8
+ const MB = KB * 1024;
9
+ const GB = MB * 1024;
10
+ const toFormattedString = value => value.toFixed(2).replace('.', ',');
11
+
12
+ /**
13
+ * Formatiert eine Dateigröße in Bytes als lesbaren String ("1,50 MB").
14
+ * Ohne `unit` wird die Einheit anhand der Größe gewählt.
15
+ */
16
+ const formatFileSize = (size, unit) => {
17
+ if (!Number.isFinite(size) || size < 0) {
18
+ return '0 B';
19
+ }
20
+ switch (unit) {
21
+ case 'B':
22
+ return `${size} B`;
23
+ case 'KB':
24
+ return `${toFormattedString(size / KB)} KB`;
25
+ case 'MB':
26
+ return `${toFormattedString(size / MB)} MB`;
27
+ case 'GB':
28
+ return `${toFormattedString(size / GB)} GB`;
29
+ default:
30
+ break;
31
+ }
32
+ if (size < KB) {
33
+ return `${size} B`;
34
+ }
35
+ if (size < MB) {
36
+ return `${toFormattedString(size / KB)} KB`;
37
+ }
38
+ if (size < GB) {
39
+ return `${toFormattedString(size / MB)} MB`;
40
+ }
41
+ return `${toFormattedString(size / GB)} GB`;
42
+ };
43
+ exports.formatFileSize = formatFileSize;
44
+ var _default = exports.default = formatFileSize;
@@ -0,0 +1,3 @@
1
+ export function generateUniqueFilename(name: any, existingNames: any): any;
2
+ export default generateUniqueFilename;
3
+ //# sourceMappingURL=generateUniqueFilename.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateUniqueFilename.d.ts","sourceRoot":"","sources":["../../../src/utils/files/generateUniqueFilename.js"],"names":[],"mappings":"AAMO,2EAoBN"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.generateUniqueFilename = exports.default = void 0;
7
+ const MAX_ITERATIONS = 10000;
8
+
9
+ /**
10
+ * Hängt einen Index an, wenn der Dateiname schon vergeben ist:
11
+ * "dokument.pdf" -> "dokument (1).pdf" -> "dokument (2).pdf"
12
+ */
13
+ const generateUniqueFilename = (name, existingNames) => {
14
+ if (!existingNames.has(name)) {
15
+ return name;
16
+ }
17
+
18
+ // Ein Punkt an Position 0 gehört zu einer versteckten Datei (.gitignore), das ist keine Endung
19
+ const lastDotIndex = name.lastIndexOf('.');
20
+ const hasExtension = lastDotIndex > 0;
21
+ const baseName = hasExtension ? name.substring(0, lastDotIndex) : name;
22
+ const extension = hasExtension ? name.substring(lastDotIndex) : '';
23
+ let index = 1;
24
+ let newName = `${baseName} (${index})${extension}`;
25
+ while (existingNames.has(newName) && index < MAX_ITERATIONS) {
26
+ index += 1;
27
+ newName = `${baseName} (${index})${extension}`;
28
+ }
29
+ return newName;
30
+ };
31
+ exports.generateUniqueFilename = generateUniqueFilename;
32
+ var _default = exports.default = generateUniqueFilename;
@@ -0,0 +1,7 @@
1
+ export * from "./convertFilesToUploadFiles.js";
2
+ export * from "./formatFileSize.js";
3
+ export * from "./generateUniqueFilename.js";
4
+ export * from "./validateFiles.js";
5
+ export * from "./validateFilesBySize.js";
6
+ export * from "./validateFilesByType.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/files/index.js"],"names":[],"mappings":""}