@db-ux/react-core-components 3.1.19 → 4.0.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 CHANGED
@@ -1,10 +1,26 @@
1
1
  # @db-ux/react-core-components
2
2
 
3
+ ## 4.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - feat: Switch stable rework - [see commit cb2deb0](https://github.com/db-ux-design-system/core-web/commit/cb2deb0f1c54900d1967483aea05d81279c02f59):
8
+ - **BREAKING CHANGE**: remove `emphasis` property
9
+ - introduce validation (invalid and valid)
10
+ - configurable label position
11
+
12
+ - **BREAKING CHANGE**: refactor(Custom Select): renamed `ariaListLabel` property to `listLabel` - [see commit 966d5ad](https://github.com/db-ux-design-system/core-web/commit/966d5ad01f00d0ca1707cc316a63e2d431fff1e9)
13
+
14
+ ## 3.1.20
15
+
16
+ ### Patch Changes
17
+
18
+ - fix(input): iOS Safari VoiceOver bug for types `date`, `datetime-local`, `week`, `month`, `time` and `color` - [see commit 2ca96c8](https://github.com/db-ux-design-system/core-web/commit/2ca96c8852b7413f9a3281d69e9c4fc6f79c4f13)
19
+
3
20
  ## 3.1.19
4
21
 
5
22
  _version bump_
6
23
 
7
-
8
24
  ## 3.1.18
9
25
 
10
26
  ### Patch Changes
@@ -662,7 +662,7 @@ function DBCustomSelectFn(props, component) {
662
662
  React.createElement("label", null,
663
663
  React.createElement("input", { type: "checkbox", value: "select-all", ref: selectAllRef, form: _id, checked: selectAllChecked, onChange: (event) => handleSelectAll(event) }),
664
664
  getSelectAllLabel())))) : null,
665
- React.createElement(DBCustomSelectList, { multiple: getBoolean(props.multiple, "multiple"), label: (_h = (_g = props.ariaListLabel) !== null && _g !== void 0 ? _g : props.label) !== null && _h !== void 0 ? _h : DEFAULT_LABEL }, _options === null || _options === void 0 ? void 0 : _options.map((option) => (React.createElement(DBCustomSelectListItem, { type: props.multiple ? "checkbox" : "radio", showDivider: option.showDivider, icon: option.icon, isGroupTitle: option.isGroupTitle, groupTitle: getOptionLabel(option), name: _id, checked: getOptionChecked(option.value), disabled: option.disabled, value: option.value, onChange: (event) => handleSelect(option.value), key: getOptionKey(option, "custom-select-list-item-") }, !option.isGroupTitle ? (React.createElement(React.Fragment, null, getOptionLabel(option))) : null))))))),
665
+ React.createElement(DBCustomSelectList, { multiple: getBoolean(props.multiple, "multiple"), label: (_h = (_g = props.listLabel) !== null && _g !== void 0 ? _g : props.label) !== null && _h !== void 0 ? _h : DEFAULT_LABEL }, _options === null || _options === void 0 ? void 0 : _options.map((option) => (React.createElement(DBCustomSelectListItem, { type: props.multiple ? "checkbox" : "radio", showDivider: option.showDivider, icon: option.icon, isGroupTitle: option.isGroupTitle, groupTitle: getOptionLabel(option), name: _id, checked: getOptionChecked(option.value), disabled: option.disabled, value: option.value, onChange: (event) => handleSelect(option.value), key: getOptionKey(option, "custom-select-list-item-") }, !option.isGroupTitle ? (React.createElement(React.Fragment, null, getOptionLabel(option))) : null))))))),
666
666
  React.createElement("div", null,
667
667
  React.createElement(DBButton, { variant: "ghost", width: "full", icon: "cross", size: "small", name: _id, form: _id, onClick: (event) => handleClose(undefined, true) }, (_j = props.mobileCloseButtonText) !== null && _j !== void 0 ? _j : DEFAULT_CLOSE_BUTTON))))) : null),
668
668
  ((_k = props.showClearSelection) !== null && _k !== void 0 ? _k : true) && (_values === null || _values === void 0 ? void 0 : _values.length) ? (React.createElement(DBButton, { icon: "cross", variant: "ghost", size: "small", noText: true, name: _id, form: _id, onClick: (event) => handleClearAll(event) },
@@ -68,7 +68,7 @@ export type DBCustomSelectDefaultProps = {
68
68
  /**
69
69
  * Overwrite the default aria-label (props.label) for the custom-select-list
70
70
  */
71
- ariaListLabel?: string;
71
+ listLabel?: string;
72
72
  /**
73
73
  * Label for the clear selection button
74
74
  */
@@ -3,10 +3,10 @@ import * as React from "react";
3
3
  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
- import { cls, delay, getBoolean, getBooleanAsString, getHideProp, getInputValue, getNumber, hasVoiceOver, isArrayOfStrings, stringPropVisible, uuid, } from "../../utils";
6
+ import { cls, delay, getBoolean, getBooleanAsString, getHideProp, getInputValue, getNumber, hasVoiceOver, isArrayOfStrings, isIOSSafari, stringPropVisible, uuid, } from "../../utils";
7
7
  import DBInfotext from "../infotext/infotext";
8
8
  function DBInputFn(props, component) {
9
- var _a, _b, _c, _d, _e, _f;
9
+ var _a, _b, _c, _d, _e, _f, _g;
10
10
  const _ref = component || useRef(component);
11
11
  const [_id, set_id] = useState(() => undefined);
12
12
  const [_messageId, set_messageId] = useState(() => undefined);
@@ -117,8 +117,10 @@ function DBInputFn(props, component) {
117
117
  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
118
  React.createElement("label", { htmlFor: _id }, (_c = props.label) !== null && _c !== void 0 ? _c : DEFAULT_LABEL),
119
119
  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") ||
120
- getBoolean(props.readonly, "readonly"), form: props.form, pattern: props.pattern, size: props.size, autoComplete: props.autocomplete, autoFocus: getBoolean(props.autofocus, "autofocus"), enterKeyHint: props.enterkeyhint, inputMode: props.inputmode, onInput: (event) => handleInput(event), onChange: (event) => handleChange(event), onBlur: (event) => handleBlur(event), onFocus: (event) => handleFocus(event), list: props.dataList && _dataListId, "aria-describedby": (_e = props.ariaDescribedBy) !== null && _e !== void 0 ? _e : _descByIds })),
121
- props.dataList ? (React.createElement("datalist", { id: _dataListId }, (_f = getDataList()) === null || _f === void 0 ? void 0 : _f.map((option) => (React.createElement("option", { key: _dataListId + "-option-" + option.value, value: option.value }, option.label))))) : null,
120
+ getBoolean(props.readonly, "readonly"), form: props.form, pattern: props.pattern, size: props.size, autoComplete: props.autocomplete, autoFocus: getBoolean(props.autofocus, "autofocus"), enterKeyHint: props.enterkeyhint, inputMode: props.inputmode, onInput: (event) => handleInput(event), onChange: (event) => handleChange(event), onBlur: (event) => handleBlur(event), onFocus: (event) => handleFocus(event), list: props.dataList && _dataListId, "aria-describedby": (_e = props.ariaDescribedBy) !== null && _e !== void 0 ? _e : _descByIds, role: ["datetime-local", "date", "time", "week", "month", "color"].includes((_f = props.type) !== null && _f !== void 0 ? _f : "") && isIOSSafari()
121
+ ? "textbox"
122
+ : undefined })),
123
+ props.dataList ? (React.createElement("datalist", { id: _dataListId }, (_g = getDataList()) === null || _g === void 0 ? void 0 : _g.map((option) => (React.createElement("option", { key: _dataListId + "-option-" + option.value, value: option.value }, option.label))))) : null,
122
124
  props.children,
123
125
  stringPropVisible(props.message, props.showMessage) ? (React.createElement(DBInfotext, { size: props.messageSize || "small", icon: props.messageIcon, id: _messageId }, props.message)) : null,
124
126
  hasValidState() ? (React.createElement(DBInfotext, { semantic: "successful", id: _validMessageId, size: props.validMessageSize || "small" }, props.validMessage || DEFAULT_VALID_MESSAGE)) : null,
@@ -43,8 +43,8 @@ export type DBInputDefaultProps = {
43
43
  */
44
44
  inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
45
45
  /**
46
- * The size of the message infotext. Defaults to "small".
47
- */
46
+ * The size of the message infotext. Defaults to "small".
47
+ */
48
48
  messageSize?: SizeType;
49
49
  /**
50
50
  * The size of the valid message infotext. Defaults to "small".
@@ -1,10 +1,14 @@
1
- import { ChangeEventProps, ChangeEventState, EmphasisProps, FocusEventProps, FocusEventState, FormCheckProps, FormProps, FormState, GlobalProps, GlobalState, IconLeadingProps, IconProps, IconTrailingProps, SizeProps } from '../../shared/model';
1
+ import { ChangeEventProps, ChangeEventState, FocusEventProps, FocusEventState, FormCheckProps, FormMessageProps, FormProps, FormState, FromValidState, GlobalProps, GlobalState, IconLeadingProps, IconProps, IconTrailingProps, LabelVariantHorizontalType, SizeProps } from '../../shared/model';
2
2
  export type DBSwitchDefaultProps = {
3
3
  /**
4
4
  * Add additional icons to indicate active/inactive state.
5
5
  */
6
6
  visualAid?: boolean | string;
7
+ /**
8
+ * Change the variant of the label to `trailing` or `leading`. Defaults to `trailing`
9
+ */
10
+ variant?: LabelVariantHorizontalType;
7
11
  };
8
- export type DBSwitchProps = DBSwitchDefaultProps & GlobalProps & ChangeEventProps<HTMLInputElement> & FocusEventProps<HTMLInputElement> & FormProps & FormCheckProps & EmphasisProps & SizeProps & IconProps & IconTrailingProps & IconLeadingProps;
12
+ export type DBSwitchProps = GlobalProps & ChangeEventProps<HTMLInputElement> & FocusEventProps<HTMLInputElement> & FormProps & FormCheckProps & FormMessageProps & SizeProps & IconProps & IconTrailingProps & IconLeadingProps & DBSwitchDefaultProps;
9
13
  export type DBSwitchDefaultState = {};
10
- export type DBSwitchState = DBSwitchDefaultState & GlobalState & ChangeEventState<HTMLInputElement> & FocusEventState<HTMLInputElement> & FormState;
14
+ export type DBSwitchState = DBSwitchDefaultState & GlobalState & ChangeEventState<HTMLInputElement> & FocusEventState<HTMLInputElement> & FormState & FromValidState;
@@ -1,3 +1,3 @@
1
1
  import * as React from "react";
2
- declare const DBSwitch: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<any>, "value" | "size" | "icon" | "checked" | keyof import("../../shared/model").GlobalProps | "emphasis" | "iconLeading" | "iconTrailing" | 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" | "visualAid"> & import("./model").DBSwitchDefaultProps & import("../../shared/model").GlobalProps & 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").EmphasisProps & import("../../shared/model").SizeProps & import("../../shared/model").IconProps & import("../../shared/model").IconTrailingProps & import("../../shared/model").IconLeadingProps & React.RefAttributes<any>>;
2
+ declare const DBSwitch: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<any>, "variant" | "name" | "required" | "message" | "id" | "change" | "value" | "form" | "label" | "blur" | "focus" | "autocomplete" | "className" | "children" | "autofocus" | "disabled" | "size" | "class" | "icon" | "onFocus" | "onBlur" | "onChange" | "checked" | "placeholder" | "iconLeading" | "iconTrailing" | "ariaDescribedBy" | "validation" | "showRequiredAsterisk" | "showLabel" | "validMessage" | "invalidMessage" | "messageIcon" | "showMessage" | "visualAid"> & import("../../shared/model").GlobalProps & 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").FormMessageProps & import("../../shared/model").SizeProps & import("../../shared/model").IconProps & import("../../shared/model").IconTrailingProps & import("../../shared/model").IconLeadingProps & import("./model").DBSwitchDefaultProps & React.RefAttributes<any>>;
3
3
  export default DBSwitch;
@@ -2,15 +2,59 @@
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, getBooleanAsString, getHideProp, uuid, } from "../../utils";
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
+ import { cls, delay, getBoolean, getBooleanAsString, getHideProp, hasVoiceOver, stringPropVisible, uuid, } from "../../utils";
7
+ import DBInfotext from "../infotext/infotext";
6
8
  function DBSwitchFn(props, component) {
7
- var _a;
9
+ var _a, _b, _c;
8
10
  const _ref = component || useRef(component);
9
11
  const [_id, set_id] = useState(() => undefined);
12
+ const [_messageId, set_messageId] = useState(() => undefined);
13
+ const [_validMessageId, set_validMessageId] = useState(() => undefined);
14
+ const [_invalidMessageId, set_invalidMessageId] = useState(() => undefined);
15
+ const [_invalidMessage, set_invalidMessage] = useState(() => undefined);
16
+ const [_descByIds, set_descByIds] = useState(() => undefined);
17
+ const [_voiceOverFallback, set_voiceOverFallback] = useState(() => "");
18
+ function hasValidState() {
19
+ var _a;
20
+ return !!((_a = props.validMessage) !== null && _a !== void 0 ? _a : props.validation === "valid");
21
+ }
22
+ function handleValidation() {
23
+ var _a, _b, _c, _d, _e, _f;
24
+ if (!((_b = (_a = _ref.current) === null || _a === void 0 ? void 0 : _a.validity) === null || _b === void 0 ? void 0 : _b.valid) || props.validation === "invalid") {
25
+ set_descByIds(_invalidMessageId);
26
+ set_invalidMessage(props.invalidMessage ||
27
+ ((_c = _ref.current) === null || _c === void 0 ? void 0 : _c.validationMessage) ||
28
+ DEFAULT_INVALID_MESSAGE);
29
+ if (hasVoiceOver()) {
30
+ set_voiceOverFallback(_invalidMessage || DEFAULT_INVALID_MESSAGE);
31
+ delay(() => {
32
+ set_voiceOverFallback("");
33
+ }, 1000);
34
+ }
35
+ return;
36
+ }
37
+ if (hasValidState() && ((_e = (_d = _ref.current) === null || _d === void 0 ? void 0 : _d.validity) === null || _e === void 0 ? void 0 : _e.valid) && props.required) {
38
+ set_descByIds(_validMessageId);
39
+ if (hasVoiceOver()) {
40
+ set_voiceOverFallback((_f = props.validMessage) !== null && _f !== void 0 ? _f : DEFAULT_VALID_MESSAGE);
41
+ delay(() => {
42
+ set_voiceOverFallback("");
43
+ }, 1000);
44
+ }
45
+ return;
46
+ }
47
+ if (stringPropVisible(props.message, props.showMessage)) {
48
+ set_descByIds(_messageId);
49
+ return;
50
+ }
51
+ set_descByIds(undefined);
52
+ }
10
53
  function handleChange(event) {
11
54
  if (props.onChange) {
12
55
  props.onChange(event);
13
56
  }
57
+ handleValidation();
14
58
  }
15
59
  function handleBlur(event) {
16
60
  if (props.onBlur) {
@@ -25,10 +69,30 @@ function DBSwitchFn(props, component) {
25
69
  useEffect(() => {
26
70
  var _a;
27
71
  set_id((_a = props.id) !== null && _a !== void 0 ? _a : `switch-${uuid()}`);
72
+ set_messageId(`${_id}${DEFAULT_MESSAGE_ID_SUFFIX}`);
73
+ set_validMessageId(`${_id}${DEFAULT_VALID_MESSAGE_ID_SUFFIX}`);
74
+ set_invalidMessageId(`${_id}${DEFAULT_INVALID_MESSAGE_ID_SUFFIX}`);
75
+ handleValidation();
28
76
  }, []);
29
- return (React.createElement("label", Object.assign({ "data-visual-aid": getBooleanAsString(props.visualAid), "data-size": props.size, "data-hide-label": getHideProp(props.showLabel), "data-emphasis": props.emphasis, htmlFor: _id, "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-switch", props.className) }),
30
- 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", "data-custom-validity": props.validation, 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) })),
31
- props.label ? React.createElement(React.Fragment, null, props.label) : React.createElement(React.Fragment, null, props.children)));
77
+ useEffect(() => {
78
+ handleValidation();
79
+ }, [
80
+ props.validation,
81
+ props.required,
82
+ props.message,
83
+ props.showMessage,
84
+ props.validMessage,
85
+ props.invalidMessage,
86
+ props.checked,
87
+ ]);
88
+ 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
+ React.createElement("label", { htmlFor: _id },
90
+ 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) })),
91
+ props.label ? React.createElement(React.Fragment, null, props.label) : React.createElement(React.Fragment, null, props.children)),
92
+ stringPropVisible(props.message, props.showMessage) ? (React.createElement(DBInfotext, { size: "small", semantic: "adaptive", id: _messageId, icon: props.messageIcon }, props.message)) : null,
93
+ hasValidState() ? (React.createElement(DBInfotext, { size: "small", semantic: "successful", id: _validMessageId }, (_b = props.validMessage) !== null && _b !== void 0 ? _b : DEFAULT_VALID_MESSAGE)) : null,
94
+ React.createElement(DBInfotext, { size: "small", semantic: "critical", id: _invalidMessageId }, (_c = _invalidMessage !== null && _invalidMessage !== void 0 ? _invalidMessage : props.invalidMessage) !== null && _c !== void 0 ? _c : DEFAULT_INVALID_MESSAGE),
95
+ React.createElement("span", { "data-visually-hidden": "true", role: "status" }, _voiceOverFallback)));
32
96
  }
33
97
  const DBSwitch = forwardRef(DBSwitchFn);
34
98
  export default DBSwitch;
@@ -309,6 +309,8 @@ export type FormCheckProps = {
309
309
  };
310
310
  export declare const LabelVariantList: readonly ["above", "floating"];
311
311
  export type LabelVariantType = (typeof LabelVariantList)[number];
312
+ export declare const LabelVariantHorizontalList: readonly ["leading", "trailing"];
313
+ export type LabelVariantHorizontalType = (typeof LabelVariantHorizontalList)[number];
312
314
  export declare const AutoCompleteList: readonly ["off", "on", "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "email", "username", "new-password", "current-password", "one-time-code", "organization-title", "organization", "street-address", "shipping", "billing", "address-line1", "address-line2", "address-line3", "address-level4", "address-level3", "address-level2", "address-level1", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-extension", "impp", "url", "photo", "webauthn"];
313
315
  export type AutoCompleteType = (typeof AutoCompleteList)[number];
314
316
  export type FormMessageProps = {
@@ -15,6 +15,7 @@ export const EmphasisList = ['weak', 'strong'];
15
15
  export const ValidationList = ['invalid', 'valid', 'no-validation'];
16
16
  export const FieldSizingList = ['fixed', 'content'];
17
17
  export const LabelVariantList = ['above', 'floating'];
18
+ export const LabelVariantHorizontalList = ['leading', 'trailing'];
18
19
  export const AutoCompleteList = ['off', 'on', 'name', 'honorific-prefix', 'given-name', 'additional-name', 'family-name', 'honorific-suffix', 'nickname', 'email', 'username', 'new-password', 'current-password', 'one-time-code', 'organization-title', 'organization', 'street-address', 'shipping', 'billing', 'address-line1', 'address-line2', 'address-line3', 'address-level4', 'address-level3', 'address-level2', 'address-level1', 'country', 'country-name', 'postal-code', 'cc-name', 'cc-given-name', 'cc-additional-name', 'cc-family-name', 'cc-number', 'cc-exp', 'cc-exp-month', 'cc-exp-year', 'cc-csc', 'cc-type', 'transaction-currency', 'transaction-amount', 'language', 'bday', 'bday-day', 'bday-month', 'bday-year', 'sex', 'tel', 'tel-country-code', 'tel-national', 'tel-area-code', 'tel-local', 'tel-extension', 'impp', 'url', 'photo', 'webauthn'];
19
20
  export const LinkTargetList = ['_self', '_blank', '_parent', '_top'];
20
21
  export const LinkReferrerPolicyList = ['no-referrer', 'no-referrer-when-downgrade', 'origin', 'origin-when-cross-origin', 'same-origin', 'strict-origin', 'strict-origin-when-cross-origin', 'unsafe-url'];
@@ -10,6 +10,16 @@ export type ClassNameArg = string | {
10
10
  export declare const cls: (...args: ClassNameArg[]) => string;
11
11
  export declare const isArrayOfStrings: (value: unknown) => value is string[];
12
12
  export declare const hasVoiceOver: () => boolean;
13
+ /**
14
+ * Determines if the current browser is Safari running on an iOS device.
15
+ *
16
+ * This function checks the user agent string to verify both iOS platform
17
+ * (iPad, iPhone, or iPod) and Safari browser, excluding other browsers
18
+ * such as Chrome, Firefox, Opera, and Edge on iOS.
19
+ *
20
+ * @returns {boolean} `true` if the browser is Safari on iOS, otherwise `false`.
21
+ */
22
+ export declare const isIOSSafari: () => boolean;
13
23
  export declare const delay: (fn: () => void, ms: number) => Promise<unknown>;
14
24
  /**
15
25
  * Some frameworks like stencil would not add "true" as value for a prop
@@ -40,6 +40,25 @@ export const cls = (...args) => {
40
40
  export const isArrayOfStrings = (value) => Array.isArray(value) && value.every(item => typeof item === 'string');
41
41
  const appleOs = ['Mac', 'iPhone', 'iPad', 'iPod'];
42
42
  export const hasVoiceOver = () => typeof window !== 'undefined' && appleOs.some(os => window.navigator.userAgent.includes(os));
43
+ /**
44
+ * Determines if the current browser is Safari running on an iOS device.
45
+ *
46
+ * This function checks the user agent string to verify both iOS platform
47
+ * (iPad, iPhone, or iPod) and Safari browser, excluding other browsers
48
+ * such as Chrome, Firefox, Opera, and Edge on iOS.
49
+ *
50
+ * @returns {boolean} `true` if the browser is Safari on iOS, otherwise `false`.
51
+ */
52
+ export const isIOSSafari = () => {
53
+ if (typeof window === 'undefined' || typeof navigator === 'undefined')
54
+ return false;
55
+ const ua = navigator.userAgent;
56
+ // iOS detection
57
+ const isIOS = /iP(ad|hone|od)/.test(ua);
58
+ // Safari detection (not Chrome or Firefox on iOS)
59
+ const isSafari = !!ua.match(/Safari/) && !ua.match(/CriOS|FxiOS|OPiOS|EdgiOS/);
60
+ return isIOS && isSafari;
61
+ };
43
62
  export const delay = (fn, ms) => new Promise(() => setTimeout(fn, ms));
44
63
  /**
45
64
  * Some frameworks like stencil would not add "true" as value for a prop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@db-ux/react-core-components",
3
- "version": "3.1.19",
3
+ "version": "4.0.0",
4
4
  "description": "React components for @db-ux/core-components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "sideEffects": false,
44
44
  "dependencies": {
45
- "@db-ux/core-components": "3.1.19",
46
- "@db-ux/core-foundations": "3.1.19"
45
+ "@db-ux/core-components": "4.0.0",
46
+ "@db-ux/core-foundations": "4.0.0"
47
47
  }
48
48
  }