@db-ux/react-core-components 4.0.3 → 4.1.0
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/CHANGELOG.md +32 -15
- package/README.md +9 -4
- package/dist/components/checkbox/checkbox.js +24 -1
- package/dist/components/custom-select/custom-select.js +33 -5
- package/dist/components/custom-select/model.d.ts +5 -0
- package/dist/components/input/input.js +26 -2
- package/dist/components/notification/notification.js +1 -1
- package/dist/components/radio/model.d.ts +3 -3
- package/dist/components/radio/radio.d.ts +1 -1
- package/dist/components/radio/radio.js +37 -3
- package/dist/components/select/select.js +26 -2
- package/dist/components/switch/switch.js +24 -1
- package/dist/components/textarea/textarea.js +26 -2
- package/dist/shared/model.d.ts +6 -2
- package/dist/utils/form-components.d.ts +9 -0
- package/dist/utils/form-components.js +31 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
# @db-ux/react-core-components
|
|
2
2
|
|
|
3
|
+
## 4.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- refactor(notification): update and simplify grid layout for block link variant - [see commit cb83f96](https://github.com/db-ux-design-system/core-web/commit/cb83f966eaf29c85b4cf0079750bdd563f216d6e)
|
|
8
|
+
|
|
9
|
+
- fix(DBCustomSelect): properly announce selected options - [see commit 773edeb](https://github.com/db-ux-design-system/core-web/commit/773edeb943a085eb79e1c8d59059137b2830fbf0):
|
|
10
|
+
- feat(DBCustomSelect): introduce new property `selectedPrefix`
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- fix(DBCustomSelect): automatically handle form reset events - [see commit 6af5246](https://github.com/db-ux-design-system/core-web/commit/6af5246b3b2e6febdc6ff6342ba1a8eb10184d14):
|
|
15
|
+
- An event listener is now added for every form component (input, custom-select, etc.) when a `form` property is passed.
|
|
16
|
+
- This listener detects form resets and updates the component's internal value/checked state accordingly.
|
|
17
|
+
- > **Note**: This does not work for `ngModel` in Angular.
|
|
18
|
+
|
|
19
|
+
- fix(button): Replace fixed height with min-height for buttons to allow dynamic height adjustment when text wraps - [see commit d1fd2c4](https://github.com/db-ux-design-system/core-web/commit/d1fd2c4e58a5ed6f75fab44700cd2d93c7232474)
|
|
20
|
+
|
|
21
|
+
## 4.0.4
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- fix: hide-animation for drawer - [see commit d4a73fa](https://github.com/db-ux-design-system/core-web/commit/d4a73fa9faba38b6f20fda6f7c85d5c6617793fe)
|
|
26
|
+
|
|
3
27
|
## 4.0.3
|
|
4
28
|
|
|
5
|
-
|
|
29
|
+
### Patch Changes
|
|
6
30
|
|
|
31
|
+
- chore: generate Amazon Q rule file with [`@db-ux/agent-cli` node package](https://www.npmjs.com/package/@db-ux/agent-cli) - [see commit b61c8b1](https://github.com/db-ux-design-system/core-web/commit/b61c8b14992f5a5b3615c6bff74018d5682aa0cc)
|
|
7
32
|
|
|
8
33
|
## 4.0.2
|
|
9
34
|
|
|
10
35
|
### Patch Changes
|
|
11
36
|
|
|
12
|
-
- fix(card): Remove the obsolete but harmful declaration regarding wrapping button and link styles. - [see commit
|
|
37
|
+
- fix(card): Remove the obsolete but harmful declaration regarding wrapping button and link styles. - [see commit 34c78df](https://github.com/db-ux-design-system/core-web/commit/34c78dffd4f43b0ac740574358b426a562e05cd0)
|
|
13
38
|
|
|
14
|
-
- Set border of select, textarea, custom select and input to corresponding color when in/valid state is set. - [see commit
|
|
39
|
+
- Set border of select, textarea, custom select and input to corresponding color when in/valid state is set. - [see commit 2a02263](https://github.com/db-ux-design-system/core-web/commit/2a022632f8fea7445e77fb632f109d6cd093e2d3)
|
|
15
40
|
|
|
16
41
|
## 4.0.1
|
|
17
42
|
|
|
@@ -54,25 +79,17 @@ _version bump_
|
|
|
54
79
|
|
|
55
80
|
### Patch Changes
|
|
56
81
|
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
- Updated dependencies [0c20c00]
|
|
60
|
-
- Updated dependencies [0c20c00]
|
|
61
|
-
- @db-ux/core-components@3.1.17
|
|
62
|
-
- @db-ux/core-foundations@3.1.17
|
|
82
|
+
- fix: color mode for textarea resizer control set by color-mode-switch documentation UI component - [see commit 354e270](https://github.com/db-ux-design-system/core-web/commit/354e27029a4378288a97ed5e31b75c11758f0c01)
|
|
83
|
+
- refactor: enabling `hidden` HTML attribute in every context in which we need to set overwriting styling declarations (`display`) - [see commit 4826455](https://github.com/db-ux-design-system/core-web/commit/4826455637590b6ae780afb93abb9effe9380342)
|
|
63
84
|
|
|
64
85
|
## 3.1.16
|
|
65
86
|
|
|
66
87
|
### Patch Changes
|
|
67
88
|
|
|
68
|
-
- a28eb71: fix(custom-select): keyboard navigation for option groups in single-select mode:
|
|
89
|
+
- a28eb71: fix(custom-select): keyboard navigation for option groups in single-select mode - [see commit 6d60bab](https://github.com/db-ux-design-system/core-web/commit/6d60bab2eb87f16a9ffa942085bffd658564769c):
|
|
69
90
|
- Fixes a keyboard accessibility issue where users could not navigate to options in subsequent option groups using arrow keys in single-select mode.
|
|
70
91
|
- Now, all options are accessible via keyboard regardless of group boundaries.
|
|
71
|
-
-
|
|
72
|
-
- Updated dependencies [a28eb71]
|
|
73
|
-
- Updated dependencies [a28eb71]
|
|
74
|
-
- @db-ux/core-components@3.1.16
|
|
75
|
-
- @db-ux/core-foundations@3.1.16
|
|
92
|
+
- fix: JS framework core-components packages are missing `@db-ux` dependencies - [see commit 49df866](https://github.com/db-ux-design-system/core-web/commit/49df866e753a9459f5acdca4ad1e19141b477471)
|
|
76
93
|
|
|
77
94
|
## 3.1.15
|
|
78
95
|
|
package/README.md
CHANGED
|
@@ -59,17 +59,22 @@ import { DBButton } from '@db-ux/react-core-components';
|
|
|
59
59
|
...
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
##
|
|
62
|
+
## AI Agent Support
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
To consume those documentation for AI Agents (currently GitHub Copilot) the best way is to copy the `docs` folder into your project.
|
|
64
|
+
For developers using AI coding assistants like GitHub Copilot or Amazon Q, we provide the [`@db-ux/agent-cli`](https://www.npmjs.com/package/@db-ux/agent-cli) tool that automatically adds DB UX Design System documentation to your repository.
|
|
66
65
|
|
|
67
|
-
|
|
66
|
+
### Quick Start
|
|
67
|
+
|
|
68
|
+
Run this command in your repository:
|
|
68
69
|
|
|
69
70
|
```shell
|
|
70
71
|
npx @db-ux/agent-cli
|
|
71
72
|
```
|
|
72
73
|
|
|
74
|
+
This will create or update `.github/copilot-instructions.md` with component documentation based on your installed `@db-ux` packages, helping AI agents provide better suggestions.
|
|
75
|
+
|
|
76
|
+
📖 **[Learn more about `@db-ux/agent-cli` node package](packages/agent-cli/README.md)**
|
|
77
|
+
|
|
73
78
|
## Deutsche Bahn brand
|
|
74
79
|
|
|
75
80
|
As we'd like to perfectly support our users and customers on their digital journey, the usage of Deutsche Bahn brand and trademarks are bound of clear guidelines and restrictions even if being used with the code that we're providing with this product; Deutsche Bahn fully reserves all rights regarding the Deutsche Bahn brand, even though that we're providing the code of DB UX Design System products free to use and release it under the Apache 2.0 license.
|
|
@@ -4,6 +4,7 @@ import { filterPassingProps, getRootProps } from "../../utils/react";
|
|
|
4
4
|
import { useState, useRef, useEffect, forwardRef } from "react";
|
|
5
5
|
import { DEFAULT_INVALID_MESSAGE, DEFAULT_INVALID_MESSAGE_ID_SUFFIX, DEFAULT_MESSAGE_ID_SUFFIX, DEFAULT_VALID_MESSAGE, DEFAULT_VALID_MESSAGE_ID_SUFFIX, } from "../../shared/constants";
|
|
6
6
|
import { cls, delay, getBoolean, getHideProp, hasVoiceOver, stringPropVisible, uuid, } from "../../utils";
|
|
7
|
+
import { addCheckedResetEventListener, } from "../../utils/form-components";
|
|
7
8
|
import DBInfotext from "../infotext/infotext";
|
|
8
9
|
function DBCheckboxFn(props, component) {
|
|
9
10
|
var _a;
|
|
@@ -16,6 +17,7 @@ function DBCheckboxFn(props, component) {
|
|
|
16
17
|
const [_invalidMessage, set_invalidMessage] = useState(() => undefined);
|
|
17
18
|
const [_descByIds, set_descByIds] = useState(() => undefined);
|
|
18
19
|
const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
|
|
20
|
+
const [abortController, setAbortController] = useState(() => undefined);
|
|
19
21
|
function hasValidState() {
|
|
20
22
|
var _a;
|
|
21
23
|
return !!((_a = props.validMessage) !== null && _a !== void 0 ? _a : props.validation === "valid");
|
|
@@ -49,7 +51,7 @@ function DBCheckboxFn(props, component) {
|
|
|
49
51
|
set_descByIds(undefined);
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
|
-
function handleChange(event) {
|
|
54
|
+
function handleChange(event, reset) {
|
|
53
55
|
if (props.onChange) {
|
|
54
56
|
props.onChange(event);
|
|
55
57
|
}
|
|
@@ -111,6 +113,27 @@ function DBCheckboxFn(props, component) {
|
|
|
111
113
|
setInitialized(false);
|
|
112
114
|
}
|
|
113
115
|
}, [initialized, _ref.current, props.checked]);
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (_ref.current) {
|
|
118
|
+
const defaultChecked = props.defaultChecked;
|
|
119
|
+
let controller = abortController;
|
|
120
|
+
if (!controller) {
|
|
121
|
+
controller = new AbortController();
|
|
122
|
+
setAbortController(controller);
|
|
123
|
+
}
|
|
124
|
+
addCheckedResetEventListener(_ref.current, {
|
|
125
|
+
checked: props.checked,
|
|
126
|
+
defaultChecked,
|
|
127
|
+
}, (event) => {
|
|
128
|
+
handleChange(event, true);
|
|
129
|
+
}, controller.signal);
|
|
130
|
+
}
|
|
131
|
+
}, [_ref.current]);
|
|
132
|
+
useEffect(() => {
|
|
133
|
+
return () => {
|
|
134
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
135
|
+
};
|
|
136
|
+
}, []);
|
|
114
137
|
return (React.createElement("div", Object.assign({}, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-checkbox", props.className), "data-size": props.size, "data-hide-asterisk": getHideProp(props.showRequiredAsterisk), "data-hide-label": getHideProp(props.showLabel) }),
|
|
115
138
|
React.createElement("label", { htmlFor: _id },
|
|
116
139
|
React.createElement("input", Object.assign({ type: "checkbox", "aria-invalid": props.validation === "invalid", "data-custom-validity": props.validation, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { id: _id, name: props.name, checked: getBoolean(props.checked, "checked"), disabled: getBoolean(props.disabled, "disabled"), value: props.value, required: getBoolean(props.required, "required"), onChange: (event) => handleChange(event), onBlur: (event) => handleBlur(event), onFocus: (event) => handleFocus(event), "aria-describedby": (_a = props.ariaDescribedBy) !== null && _a !== void 0 ? _a : _descByIds })),
|
|
@@ -7,6 +7,7 @@ import { cls, delay, getBoolean, getBooleanAsString, getHideProp, getOptionKey,
|
|
|
7
7
|
import { DocumentClickListener } from "../../utils/document-click-listener";
|
|
8
8
|
import { DocumentScrollListener } from "../../utils/document-scroll-listener";
|
|
9
9
|
import { handleFixedDropdown } from "../../utils/floating-components";
|
|
10
|
+
import { addResetEventListener, } from "../../utils/form-components";
|
|
10
11
|
import DBButton from "../button/button";
|
|
11
12
|
import DBCustomSelectDropdown from "../custom-select-dropdown/custom-select-dropdown";
|
|
12
13
|
import DBCustomSelectListItem from "../custom-select-list-item/custom-select-list-item";
|
|
@@ -35,6 +36,7 @@ function DBCustomSelectFn(props, component) {
|
|
|
35
36
|
const [_infoTextId, set_infoTextId] = useState(() => undefined);
|
|
36
37
|
const [_validity, set_validity] = useState(() => "no-validation");
|
|
37
38
|
const [_userInteraction, set_userInteraction] = useState(() => false);
|
|
39
|
+
const [abortController, setAbortController] = useState(() => undefined);
|
|
38
40
|
const [_descByIds, set_descByIds] = useState(() => undefined);
|
|
39
41
|
const [_selectedLabels, set_selectedLabels] = useState(() => "");
|
|
40
42
|
const [_selectedLabelsId, set_selectedLabelsId] = useState(() => undefined);
|
|
@@ -69,7 +71,7 @@ function DBCustomSelectFn(props, component) {
|
|
|
69
71
|
}
|
|
70
72
|
/* For a11y reasons we need to map the correct message with the select */
|
|
71
73
|
if (!((_a = selectRef.current) === null || _a === void 0 ? void 0 : _a.validity.valid) || props.validation === "invalid") {
|
|
72
|
-
|
|
74
|
+
setDescById(_invalidMessageId);
|
|
73
75
|
set_invalidMessage(props.invalidMessage ||
|
|
74
76
|
((_b = selectRef.current) === null || _b === void 0 ? void 0 : _b.validationMessage) ||
|
|
75
77
|
DEFAULT_INVALID_MESSAGE);
|
|
@@ -84,7 +86,7 @@ function DBCustomSelectFn(props, component) {
|
|
|
84
86
|
else if (hasValidState() &&
|
|
85
87
|
((_d = selectRef.current) === null || _d === void 0 ? void 0 : _d.validity.valid) &&
|
|
86
88
|
props.required) {
|
|
87
|
-
|
|
89
|
+
setDescById(_validMessageId);
|
|
88
90
|
if (hasVoiceOver()) {
|
|
89
91
|
set_voiceOverFallback((_e = props.validMessage) !== null && _e !== void 0 ? _e : DEFAULT_VALID_MESSAGE);
|
|
90
92
|
delay(() => set_voiceOverFallback(""), 1000);
|
|
@@ -92,11 +94,11 @@ function DBCustomSelectFn(props, component) {
|
|
|
92
94
|
set_validity((_f = props.validation) !== null && _f !== void 0 ? _f : "valid");
|
|
93
95
|
}
|
|
94
96
|
else if (stringPropVisible(props.message, props.showMessage)) {
|
|
95
|
-
|
|
97
|
+
setDescById(_messageId);
|
|
96
98
|
set_validity((_g = props.validation) !== null && _g !== void 0 ? _g : "no-validation");
|
|
97
99
|
}
|
|
98
100
|
else {
|
|
99
|
-
|
|
101
|
+
setDescById(_placeholderId);
|
|
100
102
|
set_validity((_h = props.validation) !== null && _h !== void 0 ? _h : "no-validation");
|
|
101
103
|
}
|
|
102
104
|
}
|
|
@@ -547,6 +549,25 @@ function DBCustomSelectFn(props, component) {
|
|
|
547
549
|
handleValidation();
|
|
548
550
|
}
|
|
549
551
|
}, [_values, selectRef.current]);
|
|
552
|
+
useEffect(() => {
|
|
553
|
+
if (selectRef.current) {
|
|
554
|
+
let controller = abortController;
|
|
555
|
+
if (!controller) {
|
|
556
|
+
controller = new AbortController();
|
|
557
|
+
setAbortController(controller);
|
|
558
|
+
}
|
|
559
|
+
const initialValues = props.values;
|
|
560
|
+
addResetEventListener(selectRef.current, () => {
|
|
561
|
+
const resetValue = initialValues
|
|
562
|
+
? initialValues
|
|
563
|
+
: selectRef.current.value
|
|
564
|
+
? [selectRef.current.value]
|
|
565
|
+
: [];
|
|
566
|
+
handleOptionSelected(resetValue);
|
|
567
|
+
handleValidation();
|
|
568
|
+
}, controller.signal);
|
|
569
|
+
}
|
|
570
|
+
}, [selectRef.current]);
|
|
550
571
|
useEffect(() => {
|
|
551
572
|
set_validity(props.validation);
|
|
552
573
|
}, [props.validation]);
|
|
@@ -635,6 +656,11 @@ function DBCustomSelectFn(props, component) {
|
|
|
635
656
|
((_a = selectRef.current) === null || _a === void 0 ? void 0 : _a.validationMessage) ||
|
|
636
657
|
DEFAULT_INVALID_MESSAGE);
|
|
637
658
|
}, [selectRef.current, props.invalidMessage]);
|
|
659
|
+
useEffect(() => {
|
|
660
|
+
return () => {
|
|
661
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
662
|
+
};
|
|
663
|
+
}, []);
|
|
638
664
|
return (React.createElement("div", Object.assign({ id: _id, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font", "onOptionSelected", "onAmountChange", "onDropdownToggle"]), getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-custom-select", props.className), "aria-invalid": _validity === "invalid", "data-custom-validity": _validity, "data-width": props.formFieldWidth, "data-variant": props.variant === "floating" &&
|
|
639
665
|
props.selectedType === "tag" &&
|
|
640
666
|
props.multiple
|
|
@@ -646,7 +672,9 @@ function DBCustomSelectFn(props, component) {
|
|
|
646
672
|
props.children,
|
|
647
673
|
props.options ? (React.createElement(React.Fragment, null,
|
|
648
674
|
React.createElement("summary", { className: "db-custom-select-form-field", id: _summaryId, "aria-disabled": getBooleanAsString(props.disabled), "aria-labelledby": _labelId },
|
|
649
|
-
(_selectedLabels === null || _selectedLabels === void 0 ? void 0 : _selectedLabels.length) ? (React.createElement("span", { "data-visually-hidden": getBooleanAsString(props.selectedType === "tag"), id: _selectedLabelsId },
|
|
675
|
+
(_selectedLabels === null || _selectedLabels === void 0 ? void 0 : _selectedLabels.length) ? (React.createElement("span", { "data-visually-hidden": getBooleanAsString(props.selectedType === "tag"), id: _selectedLabelsId },
|
|
676
|
+
props.selectedPrefix ? (React.createElement("span", { "data-visually-hidden": "true" }, props.selectedPrefix)) : null,
|
|
677
|
+
_selectedLabels)) : null,
|
|
650
678
|
props.selectedType === "tag" ? (React.createElement("div", null, _selectedOptions === null || _selectedOptions === void 0 ? void 0 : _selectedOptions.map((option, index) => (React.createElement(DBTag, { emphasis: "strong", behavior: "removable", removeButton: getTagRemoveLabel(option), onRemove: (event) => handleTagRemove(option, event), key: getOptionKey(option, "tag-") }, getOptionLabel(option)))))) : null),
|
|
651
679
|
React.createElement(DBCustomSelectDropdown, { width: props.dropdownWidth },
|
|
652
680
|
searchEnabled ? (React.createElement("div", null,
|
|
@@ -140,6 +140,11 @@ export type DBCustomSelectDefaultProps = {
|
|
|
140
140
|
* You need to define the empty state as well based on selected options.
|
|
141
141
|
*/
|
|
142
142
|
selectedLabels?: string;
|
|
143
|
+
/**
|
|
144
|
+
* Optional: Prefix text announced by screen readers before the selection
|
|
145
|
+
* (e.g., "Ausgewählt" or "Selected").
|
|
146
|
+
*/
|
|
147
|
+
selectedPrefix?: string;
|
|
143
148
|
/**
|
|
144
149
|
* Change the selected type for values shown in multi select
|
|
145
150
|
*/
|
|
@@ -4,6 +4,7 @@ import { filterPassingProps, getRootProps } from "../../utils/react";
|
|
|
4
4
|
import { useState, useRef, useEffect, forwardRef } from "react";
|
|
5
5
|
import { DEFAULT_DATALIST_ID_SUFFIX, DEFAULT_INVALID_MESSAGE, DEFAULT_INVALID_MESSAGE_ID_SUFFIX, DEFAULT_LABEL, DEFAULT_MESSAGE_ID_SUFFIX, DEFAULT_PLACEHOLDER, DEFAULT_VALID_MESSAGE, DEFAULT_VALID_MESSAGE_ID_SUFFIX, } from "../../shared/constants";
|
|
6
6
|
import { cls, delay, getBoolean, getBooleanAsString, getHideProp, getInputValue, getNumber, hasVoiceOver, isArrayOfStrings, isIOSSafari, stringPropVisible, uuid, } from "../../utils";
|
|
7
|
+
import { addValueResetEventListener, } from "../../utils/form-components";
|
|
7
8
|
import DBInfotext from "../infotext/infotext";
|
|
8
9
|
function DBInputFn(props, component) {
|
|
9
10
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -17,6 +18,7 @@ function DBInputFn(props, component) {
|
|
|
17
18
|
const [_descByIds, set_descByIds] = useState(() => undefined);
|
|
18
19
|
const [_value, set_value] = useState(() => undefined);
|
|
19
20
|
const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
|
|
21
|
+
const [abortController, setAbortController] = useState(() => undefined);
|
|
20
22
|
function hasValidState() {
|
|
21
23
|
var _a;
|
|
22
24
|
return !!((_a = props.validMessage) !== null && _a !== void 0 ? _a : props.validation === "valid");
|
|
@@ -50,13 +52,13 @@ function DBInputFn(props, component) {
|
|
|
50
52
|
set_descByIds(undefined);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
|
-
function handleInput(event) {
|
|
55
|
+
function handleInput(event, reset) {
|
|
54
56
|
if (props.onInput) {
|
|
55
57
|
props.onInput(event);
|
|
56
58
|
}
|
|
57
59
|
handleValidation();
|
|
58
60
|
}
|
|
59
|
-
function handleChange(event) {
|
|
61
|
+
function handleChange(event, reset) {
|
|
60
62
|
if (props.onChange) {
|
|
61
63
|
props.onChange(event);
|
|
62
64
|
}
|
|
@@ -114,6 +116,28 @@ function DBInputFn(props, component) {
|
|
|
114
116
|
useEffect(() => {
|
|
115
117
|
set_value(props.value);
|
|
116
118
|
}, [props.value]);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (_ref.current) {
|
|
121
|
+
const defaultValue = props.defaultValue;
|
|
122
|
+
let controller = abortController;
|
|
123
|
+
if (!controller) {
|
|
124
|
+
controller = new AbortController();
|
|
125
|
+
setAbortController(controller);
|
|
126
|
+
}
|
|
127
|
+
addValueResetEventListener(_ref.current, {
|
|
128
|
+
value: props.value,
|
|
129
|
+
defaultValue,
|
|
130
|
+
}, (event) => {
|
|
131
|
+
handleChange(event, true);
|
|
132
|
+
handleInput(event, true);
|
|
133
|
+
}, controller.signal);
|
|
134
|
+
}
|
|
135
|
+
}, [_ref.current]);
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
return () => {
|
|
138
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
139
|
+
};
|
|
140
|
+
}, []);
|
|
117
141
|
return (React.createElement("div", Object.assign({}, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-input", props.className), "data-variant": props.variant, "data-hide-label": getHideProp(props.showLabel), "data-show-icon": getBooleanAsString((_a = props.showIconLeading) !== null && _a !== void 0 ? _a : props.showIcon), "data-icon": (_b = props.iconLeading) !== null && _b !== void 0 ? _b : props.icon, "data-icon-trailing": props.iconTrailing, "data-hide-asterisk": getHideProp(props.showRequiredAsterisk), "data-show-icon-trailing": getBooleanAsString(props.showIconTrailing) }),
|
|
118
142
|
React.createElement("label", { htmlFor: _id }, (_c = props.label) !== null && _c !== void 0 ? _c : DEFAULT_LABEL),
|
|
119
143
|
React.createElement("input", Object.assign({ "aria-invalid": props.validation === "invalid", "data-custom-validity": props.validation, "data-field-sizing": props.fieldSizing, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { id: _id, name: props.name, type: props.type || "text", multiple: getBoolean(props.multiple, "multiple"), placeholder: (_d = props.placeholder) !== null && _d !== void 0 ? _d : DEFAULT_PLACEHOLDER, disabled: getBoolean(props.disabled, "disabled"), required: getBoolean(props.required, "required"), step: getNumber(props.step), value: props.value, maxLength: getNumber(props.maxLength, props.maxlength), minLength: getNumber(props.minLength, props.minlength), max: getInputValue(props.max, props.type), min: getInputValue(props.min, props.type), readOnly: getBoolean(props.readOnly, "readOnly") ||
|
|
@@ -16,7 +16,7 @@ function DBNotificationFn(props, component) {
|
|
|
16
16
|
props.onClose(event);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
return (React.createElement("article", Object.assign({ ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font", "onClose"]), { id: props.id }, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-notification", props.className), "aria-live": props.ariaLive, "data-semantic": props.semantic, "data-variant": props.variant, "data-icon": props.icon, "data-show-icon": getBooleanAsString(props.showIcon), "data-link-variant": props.linkVariant }),
|
|
19
|
+
return (React.createElement("article", Object.assign({ ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font", "onClose"]), { id: props.id }, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-notification", props.className), "aria-live": props.ariaLive, "data-semantic": props.semantic, "data-variant": props.variant, "data-icon": getBoolean(props.showIcon) !== false ? props.icon : undefined, "data-show-icon": getBooleanAsString(props.showIcon), "data-link-variant": props.linkVariant }),
|
|
20
20
|
React.createElement(React.Fragment, null, props.image),
|
|
21
21
|
stringPropVisible(props.headline, props.showHeadline) ? (React.createElement("header", null, props.headline)) : null,
|
|
22
22
|
React.createElement("p", null, props.text ? React.createElement(React.Fragment, null, props.text) : React.createElement(React.Fragment, null, props.children)),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ChangeEventProps, ChangeEventState, FocusEventProps, FocusEventState, FormCheckProps, FormProps, FormState, GlobalProps, GlobalState, InitializedState, SizeProps } from '../../shared/model';
|
|
1
|
+
import { ChangeEventProps, ChangeEventState, FocusEventProps, FocusEventState, FormCheckProps, FormProps, FormState, GlobalProps, GlobalState, InitializedState, InputEventProps, InputEventState, SizeProps } from '../../shared/model';
|
|
2
2
|
export type DBRadioDefaultProps = {};
|
|
3
|
-
export type DBRadioProps = DBRadioDefaultProps & GlobalProps & ChangeEventProps<HTMLInputElement> & FocusEventProps<HTMLInputElement> & FormProps & FormCheckProps & SizeProps;
|
|
3
|
+
export type DBRadioProps = DBRadioDefaultProps & GlobalProps & InputEventProps<HTMLInputElement> & ChangeEventProps<HTMLInputElement> & FocusEventProps<HTMLInputElement> & FormProps & FormCheckProps & SizeProps;
|
|
4
4
|
export type DBRadioDefaultState = {};
|
|
5
|
-
export type DBRadioState = DBRadioDefaultState & GlobalState & ChangeEventState<HTMLInputElement> & FocusEventState<HTMLInputElement> & FormState & InitializedState;
|
|
5
|
+
export type DBRadioState = DBRadioDefaultState & GlobalState & InputEventState<HTMLInputElement> & ChangeEventState<HTMLInputElement> & FocusEventState<HTMLInputElement> & FormState & InitializedState;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
declare const DBRadio: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<any>, "value" | "size" | "checked" | keyof import("../../shared/model").GlobalProps | keyof import("../../shared/model").ChangeEventProps<HTMLInputElement> | keyof import("../../shared/model").FocusEventProps<HTMLInputElement> | keyof import("../../shared/model").CustomFormProps | keyof import("../../shared/model").BaseFormProps | keyof import("../../shared/model").RequiredProps | "showLabel"
|
|
2
|
+
declare const DBRadio: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<any>, "value" | "size" | "checked" | keyof import("../../shared/model").GlobalProps | keyof import("../../shared/model").ChangeEventProps<HTMLInputElement> | keyof import("../../shared/model").FocusEventProps<HTMLInputElement> | keyof import("../../shared/model").CustomFormProps | keyof import("../../shared/model").BaseFormProps | keyof import("../../shared/model").RequiredProps | "showLabel" | keyof import("../../shared/model").InputEventProps<HTMLInputElement>> & import("../../shared/model").GlobalProps & import("../../shared/model").InputEventProps<HTMLInputElement> & import("../../shared/model").ChangeEventProps<HTMLInputElement> & import("../../shared/model").FocusEventProps<HTMLInputElement> & import("../../shared/model").CustomFormProps & import("../../shared/model").BaseFormProps & import("../../shared/model").RequiredProps & import("../../shared/model").ShowLabelProps & import("../../shared/model").ValueProps & import("../../shared/model").FormCheckProps & import("../../shared/model").SizeProps & React.RefAttributes<any>>;
|
|
3
3
|
export default DBRadio;
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { filterPassingProps, getRootProps } from "../../utils/react";
|
|
4
4
|
import { useState, useRef, useEffect, forwardRef } from "react";
|
|
5
|
-
import { cls, getBoolean, getHideProp, uuid } from "../../utils";
|
|
5
|
+
import { cls, delay, getBoolean, getHideProp, uuid } from "../../utils";
|
|
6
|
+
import { addResetEventListener, } from "../../utils/form-components";
|
|
6
7
|
function DBRadioFn(props, component) {
|
|
7
8
|
const _ref = component || useRef(component);
|
|
8
9
|
const [initialized, setInitialized] = useState(() => false);
|
|
9
10
|
const [_id, set_id] = useState(() => undefined);
|
|
10
|
-
|
|
11
|
+
const [abortController, setAbortController] = useState(() => undefined);
|
|
12
|
+
function handleInput(event, reset) {
|
|
13
|
+
if (props.onInput) {
|
|
14
|
+
props.onInput(event);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function handleChange(event, reset) {
|
|
11
18
|
if (props.onChange) {
|
|
12
19
|
props.onChange(event);
|
|
13
20
|
}
|
|
@@ -32,8 +39,35 @@ function DBRadioFn(props, component) {
|
|
|
32
39
|
_ref.current.checked = true;
|
|
33
40
|
}
|
|
34
41
|
}, [initialized, _ref.current, props.checked]);
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (_ref.current) {
|
|
44
|
+
const defaultChecked = props.defaultChecked;
|
|
45
|
+
let controller = abortController;
|
|
46
|
+
if (!controller) {
|
|
47
|
+
controller = new AbortController();
|
|
48
|
+
setAbortController(controller);
|
|
49
|
+
}
|
|
50
|
+
addResetEventListener(_ref.current, (event) => {
|
|
51
|
+
void delay(() => {
|
|
52
|
+
const resetChecked = props.checked
|
|
53
|
+
? props.checked
|
|
54
|
+
: defaultChecked
|
|
55
|
+
? defaultChecked
|
|
56
|
+
: _ref.current.checked;
|
|
57
|
+
const valueEvent = Object.assign(Object.assign({}, event), { target: Object.assign(Object.assign({}, event.target), { value: "", checked: resetChecked }) });
|
|
58
|
+
handleChange(valueEvent, true);
|
|
59
|
+
handleInput(valueEvent, true);
|
|
60
|
+
}, 1);
|
|
61
|
+
}, controller.signal);
|
|
62
|
+
}
|
|
63
|
+
}, [_ref.current]);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
return () => {
|
|
66
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
67
|
+
};
|
|
68
|
+
}, []);
|
|
35
69
|
return (React.createElement("label", Object.assign({ "data-size": props.size, "data-hide-label": getHideProp(props.showLabel), "data-hide-asterisk": getHideProp(props.showRequiredAsterisk) }, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-radio", props.className), htmlFor: _id }),
|
|
36
|
-
React.createElement("input", Object.assign({ type: "radio", "aria-invalid": props.validation === "invalid", "data-custom-validity": props.validation, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { id: _id, name: props.name, checked: getBoolean(props.checked, "checked"), disabled: getBoolean(props.disabled, "disabled"), value: props.value, required: getBoolean(props.required, "required"), onChange: (event) => handleChange(event), onBlur: (event) => handleBlur(event), onFocus: (event) => handleFocus(event) })),
|
|
70
|
+
React.createElement("input", Object.assign({ type: "radio", "aria-invalid": props.validation === "invalid", "data-custom-validity": props.validation, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { id: _id, name: props.name, checked: getBoolean(props.checked, "checked"), disabled: getBoolean(props.disabled, "disabled"), value: props.value, required: getBoolean(props.required, "required"), onInput: (event) => handleInput(event), onChange: (event) => handleChange(event), onBlur: (event) => handleBlur(event), onFocus: (event) => handleFocus(event) })),
|
|
37
71
|
props.label ? React.createElement(React.Fragment, null, props.label) : React.createElement(React.Fragment, null, props.children)));
|
|
38
72
|
}
|
|
39
73
|
const DBRadio = forwardRef(DBRadioFn);
|
|
@@ -4,6 +4,7 @@ import { filterPassingProps, getRootProps } from "../../utils/react";
|
|
|
4
4
|
import { useState, useRef, useEffect, forwardRef } from "react";
|
|
5
5
|
import { DEFAULT_INVALID_MESSAGE, DEFAULT_INVALID_MESSAGE_ID_SUFFIX, DEFAULT_LABEL, DEFAULT_MESSAGE_ID_SUFFIX, DEFAULT_PLACEHOLDER_ID_SUFFIX, DEFAULT_VALID_MESSAGE, DEFAULT_VALID_MESSAGE_ID_SUFFIX, } from "../../shared/constants";
|
|
6
6
|
import { cls, delay, getBoolean, getBooleanAsString, getHideProp, getOptionKey, hasVoiceOver, stringPropVisible, uuid, } from "../../utils";
|
|
7
|
+
import { addValueResetEventListener, } from "../../utils/form-components";
|
|
7
8
|
import DBInfotext from "../infotext/infotext";
|
|
8
9
|
function DBSelectFn(props, component) {
|
|
9
10
|
var _a, _b, _c, _d;
|
|
@@ -18,6 +19,7 @@ function DBSelectFn(props, component) {
|
|
|
18
19
|
const [_value, set_value] = useState(() => "");
|
|
19
20
|
const [initialized, setInitialized] = useState(() => false);
|
|
20
21
|
const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
|
|
22
|
+
const [abortController, setAbortController] = useState(() => undefined);
|
|
21
23
|
function hasValidState() {
|
|
22
24
|
var _a;
|
|
23
25
|
return !!((_a = props.validMessage) !== null && _a !== void 0 ? _a : props.validation === "valid");
|
|
@@ -59,13 +61,13 @@ function DBSelectFn(props, component) {
|
|
|
59
61
|
props.onClick(event);
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
|
-
function handleInput(event) {
|
|
64
|
+
function handleInput(event, reset) {
|
|
63
65
|
if (props.onInput) {
|
|
64
66
|
props.onInput(event);
|
|
65
67
|
}
|
|
66
68
|
handleValidation();
|
|
67
69
|
}
|
|
68
|
-
function handleChange(event) {
|
|
70
|
+
function handleChange(event, reset) {
|
|
69
71
|
if (props.onChange) {
|
|
70
72
|
props.onChange(event);
|
|
71
73
|
}
|
|
@@ -126,6 +128,28 @@ function DBSelectFn(props, component) {
|
|
|
126
128
|
useEffect(() => {
|
|
127
129
|
set_value(props.value);
|
|
128
130
|
}, [props.value]);
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (_ref.current) {
|
|
133
|
+
const defaultValue = props.defaultValue;
|
|
134
|
+
let controller = abortController;
|
|
135
|
+
if (!controller) {
|
|
136
|
+
controller = new AbortController();
|
|
137
|
+
setAbortController(controller);
|
|
138
|
+
}
|
|
139
|
+
addValueResetEventListener(_ref.current, {
|
|
140
|
+
value: props.value,
|
|
141
|
+
defaultValue,
|
|
142
|
+
}, (event) => {
|
|
143
|
+
handleChange(event, true);
|
|
144
|
+
handleInput(event, true);
|
|
145
|
+
}, controller.signal);
|
|
146
|
+
}
|
|
147
|
+
}, [_ref.current]);
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
return () => {
|
|
150
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
151
|
+
};
|
|
152
|
+
}, []);
|
|
129
153
|
return (React.createElement("div", Object.assign({}, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-select", props.className), "data-variant": props.variant, "data-hide-label": getHideProp(props.showLabel), "data-hide-asterisk": getHideProp(props.showRequiredAsterisk), "data-icon": props.icon, "data-show-icon": getBooleanAsString(props.showIcon) }),
|
|
130
154
|
React.createElement("label", { htmlFor: _id }, (_a = props.label) !== null && _a !== void 0 ? _a : DEFAULT_LABEL),
|
|
131
155
|
React.createElement("select", Object.assign({ "aria-invalid": props.validation === "invalid", "data-custom-validity": props.validation, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { required: getBoolean(props.required, "required"), disabled: getBoolean(props.disabled, "disabled"), id: _id, name: props.name, size: props.size, value: props.value, autoComplete: props.autocomplete, multiple: props.multiple, onInput: (event) => handleInput(event), onClick: (event) => handleClick(event), onChange: (event) => handleChange(event), onBlur: (event) => handleBlur(event), onFocus: (event) => handleFocus(event), "aria-describedby": (_b = props.ariaDescribedBy) !== null && _b !== void 0 ? _b : _descByIds }),
|
|
@@ -4,6 +4,7 @@ import { filterPassingProps, getRootProps } from "../../utils/react";
|
|
|
4
4
|
import { useState, useRef, useEffect, forwardRef } from "react";
|
|
5
5
|
import { DEFAULT_INVALID_MESSAGE, DEFAULT_INVALID_MESSAGE_ID_SUFFIX, DEFAULT_MESSAGE_ID_SUFFIX, DEFAULT_VALID_MESSAGE, DEFAULT_VALID_MESSAGE_ID_SUFFIX, } from "../../shared/constants";
|
|
6
6
|
import { cls, delay, getBoolean, getBooleanAsString, getHideProp, hasVoiceOver, stringPropVisible, uuid, } from "../../utils";
|
|
7
|
+
import { addCheckedResetEventListener, } from "../../utils/form-components";
|
|
7
8
|
import DBInfotext from "../infotext/infotext";
|
|
8
9
|
function DBSwitchFn(props, component) {
|
|
9
10
|
var _a, _b, _c;
|
|
@@ -15,6 +16,7 @@ function DBSwitchFn(props, component) {
|
|
|
15
16
|
const [_invalidMessage, set_invalidMessage] = useState(() => undefined);
|
|
16
17
|
const [_descByIds, set_descByIds] = useState(() => undefined);
|
|
17
18
|
const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
|
|
19
|
+
const [abortController, setAbortController] = useState(() => undefined);
|
|
18
20
|
function hasValidState() {
|
|
19
21
|
var _a;
|
|
20
22
|
return !!((_a = props.validMessage) !== null && _a !== void 0 ? _a : props.validation === "valid");
|
|
@@ -50,7 +52,7 @@ function DBSwitchFn(props, component) {
|
|
|
50
52
|
}
|
|
51
53
|
set_descByIds(undefined);
|
|
52
54
|
}
|
|
53
|
-
function handleChange(event) {
|
|
55
|
+
function handleChange(event, reset) {
|
|
54
56
|
if (props.onChange) {
|
|
55
57
|
props.onChange(event);
|
|
56
58
|
}
|
|
@@ -85,6 +87,27 @@ function DBSwitchFn(props, component) {
|
|
|
85
87
|
props.invalidMessage,
|
|
86
88
|
props.checked,
|
|
87
89
|
]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (_ref.current) {
|
|
92
|
+
const defaultChecked = props.defaultChecked;
|
|
93
|
+
let controller = abortController;
|
|
94
|
+
if (!controller) {
|
|
95
|
+
controller = new AbortController();
|
|
96
|
+
setAbortController(controller);
|
|
97
|
+
}
|
|
98
|
+
addCheckedResetEventListener(_ref.current, {
|
|
99
|
+
checked: props.checked,
|
|
100
|
+
defaultChecked,
|
|
101
|
+
}, (event) => {
|
|
102
|
+
handleChange(event, true);
|
|
103
|
+
}, controller.signal);
|
|
104
|
+
}
|
|
105
|
+
}, [_ref.current]);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
return () => {
|
|
108
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
109
|
+
};
|
|
110
|
+
}, []);
|
|
88
111
|
return (React.createElement("div", Object.assign({ "data-visual-aid": getBooleanAsString(props.visualAid), "data-size": props.size, "data-hide-label": getHideProp(props.showLabel), "data-variant": props.variant, "data-hide-asterisk": getHideProp(props.showRequiredAsterisk), "data-custom-validity": props.validation }, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-switch", props.className) }),
|
|
89
112
|
React.createElement("label", { htmlFor: _id },
|
|
90
113
|
React.createElement("input", Object.assign({ type: "checkbox", role: "switch", id: _id, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { checked: getBoolean(props.checked, "checked"), value: props.value, disabled: getBoolean(props.disabled, "disabled"), "aria-invalid": props.validation === "invalid" ? "true" : undefined, "aria-describedby": _descByIds, name: props.name, required: getBoolean(props.required, "required"), "data-aid-icon": (_a = props.iconLeading) !== null && _a !== void 0 ? _a : props.icon, "data-aid-icon-trailing": props.iconTrailing, onChange: (event) => handleChange(event), onBlur: (event) => handleBlur(event), onFocus: (event) => handleFocus(event) })),
|
|
@@ -4,6 +4,7 @@ import { filterPassingProps, getRootProps } from "../../utils/react";
|
|
|
4
4
|
import { useState, useRef, useEffect, forwardRef } from "react";
|
|
5
5
|
import { DEFAULT_INVALID_MESSAGE, DEFAULT_INVALID_MESSAGE_ID_SUFFIX, DEFAULT_LABEL, DEFAULT_MESSAGE_ID_SUFFIX, DEFAULT_PLACEHOLDER, DEFAULT_ROWS, DEFAULT_VALID_MESSAGE, DEFAULT_VALID_MESSAGE_ID_SUFFIX, } from "../../shared/constants";
|
|
6
6
|
import { cls, delay, getBoolean, getHideProp, getNumber, hasVoiceOver, stringPropVisible, uuid, } from "../../utils";
|
|
7
|
+
import { addValueResetEventListener, } from "../../utils/form-components";
|
|
7
8
|
import DBInfotext from "../infotext/infotext";
|
|
8
9
|
function DBTextareaFn(props, component) {
|
|
9
10
|
var _a, _b, _c, _d;
|
|
@@ -16,6 +17,7 @@ function DBTextareaFn(props, component) {
|
|
|
16
17
|
const [_descByIds, set_descByIds] = useState(() => undefined);
|
|
17
18
|
const [_value, set_value] = useState(() => "");
|
|
18
19
|
const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
|
|
20
|
+
const [abortController, setAbortController] = useState(() => undefined);
|
|
19
21
|
function hasValidState() {
|
|
20
22
|
var _a;
|
|
21
23
|
return !!((_a = props.validMessage) !== null && _a !== void 0 ? _a : props.validation === "valid");
|
|
@@ -49,13 +51,13 @@ function DBTextareaFn(props, component) {
|
|
|
49
51
|
set_descByIds(undefined);
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
|
-
function handleInput(event) {
|
|
54
|
+
function handleInput(event, reset) {
|
|
53
55
|
if (props.onInput) {
|
|
54
56
|
props.onInput(event);
|
|
55
57
|
}
|
|
56
58
|
handleValidation();
|
|
57
59
|
}
|
|
58
|
-
function handleChange(event) {
|
|
60
|
+
function handleChange(event, reset) {
|
|
59
61
|
if (props.onChange) {
|
|
60
62
|
props.onChange(event);
|
|
61
63
|
}
|
|
@@ -101,6 +103,28 @@ function DBTextareaFn(props, component) {
|
|
|
101
103
|
useEffect(() => {
|
|
102
104
|
set_value(props.value);
|
|
103
105
|
}, [props.value]);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (_ref.current) {
|
|
108
|
+
const defaultValue = props.defaultValue;
|
|
109
|
+
let controller = abortController;
|
|
110
|
+
if (!controller) {
|
|
111
|
+
controller = new AbortController();
|
|
112
|
+
setAbortController(controller);
|
|
113
|
+
}
|
|
114
|
+
addValueResetEventListener(_ref.current, {
|
|
115
|
+
value: props.value,
|
|
116
|
+
defaultValue,
|
|
117
|
+
}, (event) => {
|
|
118
|
+
handleChange(event, true);
|
|
119
|
+
handleInput(event, true);
|
|
120
|
+
}, controller.signal);
|
|
121
|
+
}
|
|
122
|
+
}, [_ref.current]);
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
return () => {
|
|
125
|
+
abortController === null || abortController === void 0 ? void 0 : abortController.abort();
|
|
126
|
+
};
|
|
127
|
+
}, []);
|
|
104
128
|
return (React.createElement("div", Object.assign({}, getRootProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { className: cls("db-textarea", props.className), "data-variant": props.variant, "data-hide-asterisk": getHideProp(props.showRequiredAsterisk), "data-hide-label": getHideProp(props.showLabel) }),
|
|
105
129
|
React.createElement("label", { htmlFor: _id }, (_a = props.label) !== null && _a !== void 0 ? _a : DEFAULT_LABEL),
|
|
106
130
|
React.createElement("textarea", Object.assign({ "aria-invalid": props.validation === "invalid", "data-custom-validity": props.validation, "data-field-sizing": props.fieldSizing, ref: _ref }, filterPassingProps(props, ["data-icon-variant", "data-icon-variant-before", "data-icon-variant-after", "data-icon-weight", "data-icon-weight-before", "data-icon-weight-after", "data-interactive", "data-force-mobile", "data-color", "data-container-color", "data-bg-color", "data-on-bg-color", "data-color-scheme", "data-font-size", "data-headline-size", "data-divider", "data-focus", "data-font"]), { id: _id, "data-resize": props.resize, "data-hide-resizer": getHideProp((_b = props.showResizer) !== null && _b !== void 0 ? _b : true), disabled: getBoolean(props.disabled, "disabled"), required: getBoolean(props.required, "required"), readOnly: getBoolean(props.readOnly, "readOnly") ||
|
package/dist/shared/model.d.ts
CHANGED
|
@@ -365,6 +365,10 @@ export type FormState = {
|
|
|
365
365
|
* This is an internal Fallback
|
|
366
366
|
*/
|
|
367
367
|
_voiceOverFallback?: string;
|
|
368
|
+
/**
|
|
369
|
+
* We use this to remove form event listener
|
|
370
|
+
*/
|
|
371
|
+
abortController?: AbortController;
|
|
368
372
|
};
|
|
369
373
|
export type InitializedState = {
|
|
370
374
|
initialized: boolean;
|
|
@@ -461,7 +465,7 @@ export type InputEventProps<T> = {
|
|
|
461
465
|
onInput?: (event: InputEvent<T>) => void;
|
|
462
466
|
};
|
|
463
467
|
export type InputEventState<T> = {
|
|
464
|
-
handleInput: (event: InputEvent<T> | any) => void;
|
|
468
|
+
handleInput: (event: InputEvent<T> | any, reset?: boolean) => void;
|
|
465
469
|
};
|
|
466
470
|
export type ChangeEvent<T> = React.ChangeEvent<T>;
|
|
467
471
|
export type ChangeEventProps<T> = {
|
|
@@ -469,7 +473,7 @@ export type ChangeEventProps<T> = {
|
|
|
469
473
|
onChange?: (event: ChangeEvent<T>) => void;
|
|
470
474
|
};
|
|
471
475
|
export type ChangeEventState<T> = {
|
|
472
|
-
handleChange: (event: ChangeEvent<T> | any) => void;
|
|
476
|
+
handleChange: (event: ChangeEvent<T> | any, reset?: boolean) => void;
|
|
473
477
|
};
|
|
474
478
|
export type InteractionEvent<T> = React.FocusEvent<T>;
|
|
475
479
|
export type FocusEventProps<T> = {
|
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
export declare const handleFrameworkEventAngular: (component: any, event: any, modelValue?: string) => void;
|
|
2
2
|
export declare const handleFrameworkEventVue: (emit: (event: string, ...args: any[]) => void, event: any, modelValue?: string) => void;
|
|
3
|
+
export declare const addResetEventListener: (element: any, resetFunction: (event: Event) => void, signal: AbortSignal) => void;
|
|
4
|
+
export declare const addCheckedResetEventListener: (element: any, props: {
|
|
5
|
+
checked?: boolean | string;
|
|
6
|
+
defaultChecked?: boolean;
|
|
7
|
+
}, resetFunction: (event: any) => void, signal: AbortSignal) => void;
|
|
8
|
+
export declare const addValueResetEventListener: (element: any, props: {
|
|
9
|
+
value?: string;
|
|
10
|
+
defaultValue?: string;
|
|
11
|
+
}, resetFunction: (event: any) => void, signal: AbortSignal) => void;
|
|
@@ -1,8 +1,39 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { delay } from './index';
|
|
2
3
|
export const handleFrameworkEventAngular = (component, event, modelValue = 'value') => {
|
|
3
4
|
component.propagateChange(event.target[modelValue]);
|
|
5
|
+
component.writeValue(event.target[modelValue]);
|
|
4
6
|
};
|
|
5
7
|
export const handleFrameworkEventVue = (emit, event, modelValue = 'value') => {
|
|
6
8
|
// TODO: Replace this with the solution out of https://github.com/BuilderIO/mitosis/issues/833 after this has been "solved"
|
|
7
9
|
emit(`update:${modelValue}`, event.target[modelValue]);
|
|
8
10
|
};
|
|
11
|
+
export const addResetEventListener = (element, resetFunction, signal) => {
|
|
12
|
+
if (element.form && !element._dbFormResetListenerAdded) {
|
|
13
|
+
element.form.addEventListener('reset', (event) => {
|
|
14
|
+
resetFunction(event);
|
|
15
|
+
}, {
|
|
16
|
+
signal
|
|
17
|
+
});
|
|
18
|
+
// Mark as added to avoid duplicate listeners
|
|
19
|
+
element._dbFormResetListenerAdded = true;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
export const addCheckedResetEventListener = (element, props, resetFunction, signal) => {
|
|
23
|
+
addResetEventListener(element, (event) => {
|
|
24
|
+
void delay(() => {
|
|
25
|
+
const resetValue = props.checked ? props.checked : props.defaultChecked ? props.defaultChecked : element.checked;
|
|
26
|
+
const valueEvent = Object.assign(Object.assign({}, event), { target: Object.assign(Object.assign({}, event.target), { checked: resetValue }) });
|
|
27
|
+
resetFunction(valueEvent);
|
|
28
|
+
}, 1);
|
|
29
|
+
}, signal);
|
|
30
|
+
};
|
|
31
|
+
export const addValueResetEventListener = (element, props, resetFunction, signal) => {
|
|
32
|
+
addResetEventListener(element, (event) => {
|
|
33
|
+
void delay(() => {
|
|
34
|
+
const resetValue = props.value ? props.value : props.defaultValue ? props.defaultValue : element.value;
|
|
35
|
+
const valueEvent = Object.assign(Object.assign({}, event), { target: Object.assign(Object.assign({}, event.target), { value: resetValue }) });
|
|
36
|
+
resetFunction(valueEvent);
|
|
37
|
+
}, 1);
|
|
38
|
+
}, signal);
|
|
39
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@db-ux/react-core-components",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "React components for @db-ux/core-components",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"tsc": "tsc --project . --sourceMap false"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@playwright/experimental-ct-react": "1.56.
|
|
34
|
+
"@playwright/experimental-ct-react": "1.56.1",
|
|
35
35
|
"@types/react": "18.3.13",
|
|
36
36
|
"react": "18.3.1",
|
|
37
37
|
"react-dom": "18.3.1"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"sideEffects": false,
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@db-ux/core-components": "4.0
|
|
46
|
-
"@db-ux/core-foundations": "4.0
|
|
45
|
+
"@db-ux/core-components": "4.1.0",
|
|
46
|
+
"@db-ux/core-foundations": "4.1.0"
|
|
47
47
|
}
|
|
48
48
|
}
|