@sprinklrjs/spaceweb 14.12.1 → 14.12.3

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 (50) hide show
  1. package/a11y/StatusMessage.d.ts +1 -1
  2. package/a11y/StatusMessage.js +2 -2
  3. package/a11y/types.d.ts +5 -0
  4. package/baseui/layer/tether.js +5 -5
  5. package/esm/a11y/StatusMessage.d.ts +1 -1
  6. package/esm/a11y/StatusMessage.js +2 -2
  7. package/esm/a11y/types.d.ts +5 -0
  8. package/esm/baseui/layer/tether.js +5 -5
  9. package/esm/input/base-input.js +1 -1
  10. package/esm/list/divider.js +3 -1
  11. package/esm/list/list.js +11 -14
  12. package/esm/list/utils.d.ts +8 -0
  13. package/esm/list/utils.js +28 -1
  14. package/esm/menu/menu-item.js +1 -1
  15. package/esm/phone-input/constants.d.ts +476 -0
  16. package/esm/phone-input/constants.js +397 -105
  17. package/esm/phone-input/country-select.js +7 -4
  18. package/esm/phone-input/types.d.ts +24 -1
  19. package/esm/phone-input/useStatefulPhoneInput.d.ts +1 -1
  20. package/esm/phone-input/utils.d.ts +25 -1
  21. package/esm/phone-input/utils.js +49 -0
  22. package/esm/snackbar/Snackbar.d.ts +1 -1
  23. package/esm/snackbar/Snackbar.js +5 -10
  24. package/esm/snackbar/snackbarContext.d.ts +1 -1
  25. package/esm/snackbar/snackbarContext.js +7 -2
  26. package/esm/snackbar/types.d.ts +6 -0
  27. package/esm/snackbar/useSnackbar.d.ts +2 -1
  28. package/esm/snackbar/useSnackbar.js +12 -5
  29. package/input/base-input.js +1 -1
  30. package/list/divider.js +3 -1
  31. package/list/list.js +10 -13
  32. package/list/utils.d.ts +8 -0
  33. package/list/utils.js +31 -1
  34. package/menu/menu-item.js +1 -1
  35. package/package.json +2 -2
  36. package/phone-input/constants.d.ts +476 -0
  37. package/phone-input/constants.js +397 -105
  38. package/phone-input/country-select.js +5 -2
  39. package/phone-input/types.d.ts +24 -1
  40. package/phone-input/useStatefulPhoneInput.d.ts +1 -1
  41. package/phone-input/utils.d.ts +25 -1
  42. package/phone-input/utils.js +52 -1
  43. package/snackbar/Snackbar.d.ts +1 -1
  44. package/snackbar/Snackbar.js +5 -10
  45. package/snackbar/snackbarContext.d.ts +1 -1
  46. package/snackbar/snackbarContext.js +7 -2
  47. package/snackbar/types.d.ts +6 -0
  48. package/snackbar/useSnackbar.d.ts +2 -1
  49. package/snackbar/useSnackbar.js +12 -5
  50. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,20 +1,23 @@
1
1
  import { __assign, __read, __rest } from "tslib";
2
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useMemo, useRef } from 'react';
4
4
  import * as React from 'react';
5
5
  import _pick from 'lodash/pick';
6
6
  import { Select as DefaultSelect } from '../select';
7
7
  import { ListItem } from '../list';
8
8
  import { Typography } from '../typography';
9
+ import { Box } from '../box';
9
10
  import FlagContainer from './flag-container';
10
11
  import { useLocale } from '../locale';
11
12
  import { mergeOverrides, useOverrides } from '../overrides';
12
- import { iso2FlagEmoji, countrySelectFilterOptions } from './utils';
13
+ import { iso2FlagEmoji, countrySelectFilterOptions, resolveCountryLabelParts } from './utils';
13
14
  import { COUNTRY_SELECT_OPTIONS } from './constants';
14
15
  import { POPOVER_MARGIN } from '../popover/types';
15
16
  var SelectListItem = React.forwardRef(function (_a, ref) {
16
- var mapIsoToLabel = _a.mapIsoToLabel, _b = _a.$item, id = _b.id, label = _b.label, dialCode = _b.dialCode, rest = __rest(_a, ["mapIsoToLabel", "$item"]);
17
- return (_jsxs(ListItem, __assign({}, rest, { startEnhancer: iso2FlagEmoji(id), ref: ref }, { children: [dialCode, _jsxs(Typography, __assign({ "data-testid": id, "data-entity-type": "country-label", className: "spr-text-03 ml-1" }, { children: ["(", mapIsoToLabel ? mapIsoToLabel(id) : label, ")"] }))] })));
17
+ var mapIsoToLabel = _a.mapIsoToLabel, country = _a.$item, rest = __rest(_a, ["mapIsoToLabel", "$item"]);
18
+ var id = country.id, dialCode = country.dialCode;
19
+ var _b = resolveCountryLabelParts(country, mapIsoToLabel), primaryName = _b.primaryName, nativeName = _b.nativeName, nativeLang = _b.nativeLang;
20
+ return (_jsxs(ListItem, __assign({}, rest, { startEnhancer: iso2FlagEmoji(id), ref: ref }, { children: [dialCode, _jsxs(Typography, __assign({ "data-testid": id, "data-entity-type": "country-label", className: "spr-text-03 ml-1" }, { children: ["(", primaryName, nativeName && nativeLang ? (_jsxs(_Fragment, { children: [' (', _jsx(Box, __assign({ "$as": "span", lang: nativeLang }, { children: nativeName })), ")"] })) : null, _jsx(Box, __assign({ "$as": "span" }, { children: ")" }))] }))] })));
18
21
  });
19
22
  var CountrySelect = function (props) {
20
23
  var size = props.size, disabled = props.disabled, inputRef = props.inputRef, onChange = props.onChange, countries = props.countries, value = props.value, mapIsoToLabel = props.mapIsoToLabel, maxDropdownHeight = props.maxDropdownHeight, maxDropdownWidth = props.maxDropdownWidth, overrides = props.overrides;
@@ -7,6 +7,14 @@ export type Country = {
7
7
  id: keyof typeof COUNTRIES;
8
8
  label: string;
9
9
  dialCode: string;
10
+ /**
11
+ * The portion of `label` (without the wrapping parentheses) that is rendered in a language
12
+ * other than the component's default (English), e.g. `'भारत'` for India. Used to apply the
13
+ * correct `lang` attribute to that segment for screen reader pronunciation (WCAG 3.1.2).
14
+ */
15
+ nativeName?: string;
16
+ /** BCP 47 language tag for `nativeName`, e.g. `'hi'` for Hindi. */
17
+ nativeLang?: string;
10
18
  };
11
19
  export type State = {
12
20
  country: Country;
@@ -22,11 +30,26 @@ export type PhoneInputOverrides = {
22
30
  FlagContainer?: Override<SharedProps & Record<string, any>>;
23
31
  DialCode?: Override<SharedProps & Record<string, any>>;
24
32
  };
33
+ /**
34
+ * Custom country label for `mapIsoToLabel`. Provide both `nativeName` and `nativeLang` when a
35
+ * native-language segment should be marked with `lang` (WCAG 3.1.2); otherwise only `label` is used.
36
+ */
37
+ export type CustomCountryLabel = {
38
+ label: string;
39
+ nativeName?: string;
40
+ nativeLang?: string;
41
+ };
25
42
  export type PhoneInputProps = Omit<InputProps, 'value' | 'onChange'> & {
26
43
  onInputChange?: (event: React.SyntheticEvent<HTMLInputElement>) => unknown;
27
44
  onChange?: (value: Value) => void;
28
45
  value?: Value;
29
- mapIsoToLabel?: (iso: string) => string;
46
+ /**
47
+ * Maps an ISO country code to the dropdown label. Return a `string` to replace the whole label
48
+ * (legacy behavior), or a `CustomCountryLabel` with both `nativeName` and `nativeLang` to mark
49
+ * a native-language segment with `lang` (WCAG 3.1.2). Object results missing either native field
50
+ * are flattened into a single label string.
51
+ */
52
+ mapIsoToLabel?: (iso: string) => string | CustomCountryLabel;
30
53
  maxDropdownHeight?: string;
31
54
  countries?: Array<Country>;
32
55
  maxDropdownWidth?: string;
@@ -9,7 +9,7 @@ declare const useStatefulPhoneInput: ({ clearable, disabled, id, initialState, i
9
9
  intent: import("..").Intent | undefined;
10
10
  maxDropdownHeight: string;
11
11
  maxDropdownWidth: string;
12
- mapIsoToLabel: ((iso: string) => string) | undefined;
12
+ mapIsoToLabel: ((iso: string) => string | import("./types").CustomCountryLabel) | undefined;
13
13
  name: string | undefined;
14
14
  overrides: import("../input").BaseInputOverrides & {
15
15
  Root?: import("../overrides").Override<import("../input").SharedProps & Record<string, any>> | undefined;
@@ -1,5 +1,5 @@
1
1
  import type { Value as ValueT } from '../select/types';
2
- import type { Value, Country } from './types';
2
+ import type { Value, Country, CustomCountryLabel } from './types';
3
3
  export declare const iso2FlagEmoji: (iso: string) => string | undefined;
4
4
  export declare const sanitize: (value?: string) => string;
5
5
  export declare const getPhoneNumberWithCountryDialCode: (value: Value) => string | undefined;
@@ -11,3 +11,27 @@ export declare const getDefaultValue: (countries?: Country[]) => {
11
11
  country: Country;
12
12
  phoneNumber: string;
13
13
  };
14
+ export type CountryLabelParts = {
15
+ primaryName: string;
16
+ nativeName?: string;
17
+ nativeLang?: string;
18
+ };
19
+ /**
20
+ * Splits a country's `label` (e.g. `'India (भारत)'`) into the default-language name and the
21
+ * trailing native-language segment (if any), so the native segment can be given its own `lang`
22
+ * attribute for correct screen reader pronunciation (WCAG 3.1.2 - Language of Parts).
23
+ *
24
+ * Requires both `nativeName` and `nativeLang`. Falls back to the whole `label` as `primaryName`
25
+ * if either is missing or `nativeName` is not actually a trailing `label` suffix, so incomplete
26
+ * data never breaks rendering or ships a native segment without a language tag.
27
+ */
28
+ export declare const getCountryLabelParts: ({ label, nativeName, nativeLang }: Country) => CountryLabelParts;
29
+ /**
30
+ * Resolves the label parts to render for a country option, honoring an optional `mapIsoToLabel`
31
+ * override (string or `{ label, nativeName?, nativeLang? }`).
32
+ *
33
+ * String overrides replace the whole label (legacy behavior). Object overrides only split out a
34
+ * `lang`-tagged native segment when both `nativeName` and `nativeLang` are provided; otherwise the
35
+ * visible text is flattened into `primaryName` so display stays correct without invalid markup.
36
+ */
37
+ export declare const resolveCountryLabelParts: (country: Country, mapIsoToLabel?: ((iso: string) => string | CustomCountryLabel) | undefined) => CountryLabelParts;
@@ -30,3 +30,52 @@ export var countrySelectFilterOptions = function (options, filterValue, excludeO
30
30
  export var getDefaultValue = function (countries) {
31
31
  return countries && !_isEmpty(countries) ? { country: COUNTRIES[countries[0].id], phoneNumber: '' } : defaultValue;
32
32
  };
33
+ /**
34
+ * Splits a country's `label` (e.g. `'India (भारत)'`) into the default-language name and the
35
+ * trailing native-language segment (if any), so the native segment can be given its own `lang`
36
+ * attribute for correct screen reader pronunciation (WCAG 3.1.2 - Language of Parts).
37
+ *
38
+ * Requires both `nativeName` and `nativeLang`. Falls back to the whole `label` as `primaryName`
39
+ * if either is missing or `nativeName` is not actually a trailing `label` suffix, so incomplete
40
+ * data never breaks rendering or ships a native segment without a language tag.
41
+ */
42
+ export var getCountryLabelParts = function (_a) {
43
+ var label = _a.label, nativeName = _a.nativeName, nativeLang = _a.nativeLang;
44
+ if (!nativeName || !nativeLang) {
45
+ return { primaryName: label };
46
+ }
47
+ var nativeNameSuffix = "(".concat(nativeName, ")");
48
+ var suffixStartIndex = label.lastIndexOf(nativeNameSuffix);
49
+ var isSuffixAtEnd = suffixStartIndex !== -1 && suffixStartIndex + nativeNameSuffix.length === label.length;
50
+ if (!isSuffixAtEnd) {
51
+ return { primaryName: label };
52
+ }
53
+ return { primaryName: label.slice(0, suffixStartIndex).trimEnd(), nativeName: nativeName, nativeLang: nativeLang };
54
+ };
55
+ /**
56
+ * Resolves the label parts to render for a country option, honoring an optional `mapIsoToLabel`
57
+ * override (string or `{ label, nativeName?, nativeLang? }`).
58
+ *
59
+ * String overrides replace the whole label (legacy behavior). Object overrides only split out a
60
+ * `lang`-tagged native segment when both `nativeName` and `nativeLang` are provided; otherwise the
61
+ * visible text is flattened into `primaryName` so display stays correct without invalid markup.
62
+ */
63
+ export var resolveCountryLabelParts = function (country, mapIsoToLabel) {
64
+ if (!mapIsoToLabel) {
65
+ return getCountryLabelParts(country);
66
+ }
67
+ var mapped = mapIsoToLabel(country.id);
68
+ if (typeof mapped === 'string') {
69
+ return { primaryName: mapped };
70
+ }
71
+ if (!mapped.nativeName || !mapped.nativeLang) {
72
+ return {
73
+ primaryName: mapped.nativeName ? "".concat(mapped.label, " (").concat(mapped.nativeName, ")") : mapped.label,
74
+ };
75
+ }
76
+ return {
77
+ primaryName: mapped.label,
78
+ nativeName: mapped.nativeName,
79
+ nativeLang: mapped.nativeLang,
80
+ };
81
+ };
@@ -1,7 +1,7 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import type { SnackbarProps } from './types';
3
3
  declare const Snackbar: {
4
- ({ intent: _intent, message: _message, disableManualClose, placement, autoHide, autoHideDuration, hideOnClickAway, overrides: _overrides, onClose, }: SnackbarProps): ReactElement | null;
4
+ ({ intent: _intent, message: _message, id, disableManualClose, placement, autoHide, autoHideDuration, hideOnClickAway, overrides: _overrides, onClose, }: SnackbarProps): ReactElement | null;
5
5
  __standard: string;
6
6
  };
7
7
  export default Snackbar;
@@ -19,11 +19,12 @@ import { useLocale } from '../locale';
19
19
  import { useStyle } from '../style';
20
20
  import { ThemeProvider } from '../theme';
21
21
  var Snackbar = function (_a) {
22
- var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message, _c = _a.disableManualClose, disableManualClose = _c === void 0 ? false : _c, _d = _a.placement, placement = _d === void 0 ? 'bottom' : _d, _e = _a.autoHide, autoHide = _e === void 0 ? true : _e, _f = _a.autoHideDuration, autoHideDuration = _f === void 0 ? TYPE_TO_HIDE_DURATION[_intent] : _f, _g = _a.hideOnClickAway, hideOnClickAway = _g === void 0 ? true : _g, _overrides = _a.overrides, _h = _a.onClose, onClose = _h === void 0 ? _noop : _h;
22
+ var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message, id = _a.id, _c = _a.disableManualClose, disableManualClose = _c === void 0 ? false : _c, _d = _a.placement, placement = _d === void 0 ? 'bottom' : _d, _e = _a.autoHide, autoHide = _e === void 0 ? true : _e, _f = _a.autoHideDuration, autoHideDuration = _f === void 0 ? TYPE_TO_HIDE_DURATION[_intent] : _f, _g = _a.hideOnClickAway, hideOnClickAway = _g === void 0 ? true : _g, _overrides = _a.overrides, _h = _a.onClose, onClose = _h === void 0 ? _noop : _h;
23
23
  var outerTheme = useStyle().theme;
24
24
  var inverseTheme = useMemo(function () { return (isDarkTheme(outerTheme) ? hyperspaceLight : hyperspaceDark); }, [outerTheme]);
25
25
  var _j = useSnackbar({
26
26
  intent: _intent,
27
+ id: id,
27
28
  message: _message,
28
29
  overrides: _overrides,
29
30
  autoHide: autoHide,
@@ -52,18 +53,12 @@ var Snackbar = function (_a) {
52
53
  var _s = __read(useOverrides(overrides === null || overrides === void 0 ? void 0 : overrides.CloseIcon, CloseIcon), 2), Close = _s[0], closeProps = _s[1];
53
54
  var _t = __read(useOverrides(overrides === null || overrides === void 0 ? void 0 : overrides.CloseIconButton, IconButton), 2), CloseIconButton = _t[0], closeIconButtonProps = _t[1];
54
55
  var locale = useLocale();
55
- var role = INTENT_TO_ROLE[intent];
56
- // We don't know if the message contains any interactive elements, so we only
57
- // delegate to the shared screen-reader announcer when the message is a string.
58
56
  var isStringMessage = typeof message === 'string';
59
- // Announce string messages through the shared global live region instead of
60
- // hand-rolling sr-only regions here. The announcer keeps a single source of
61
- // truth for status messages (WCAG 4.1.3) and re-announces repeated text.
62
57
  useEffect(function () {
63
- if (isStringMessage && message) {
64
- announce(message, { politeness: role === 'alert' ? 'assertive' : 'polite' });
58
+ if (typeof _message === 'string' && _message) {
59
+ announce(_message, { politeness: INTENT_TO_ROLE[_intent] === 'alert' ? 'assertive' : 'polite' });
65
60
  }
66
- }, [isStringMessage, message, role]);
61
+ }, [_message, _intent, id]);
67
62
  return (_jsx(_Fragment, { children: shouldRender ? (_jsx(LayersManager, __assign({ zIndex: Z_INDEX.SNACKBAR }, { children: _jsx(Layer, __assign({}, sharedProps, layerProps, { children: _jsx(PlacementContainer, __assign({ "data-spaceweb": "snackbar", "data-testid": "snackbar" }, sharedProps, placementContainerProps, { children: _jsx(SnackbarContainer, __assign({}, snackbarContainerProps, { ref: snackbarContainerRef }, sharedProps, snackbarContainerOverrideProps, { style: [getSnackbarContainerAnimationStyle, snackbarContainerOverrideProps.style] }, { children: _jsx(ThemeProvider, __assign({ theme: inverseTheme }, { children: _jsxs(ContentContainer, __assign({}, sharedProps, contentContainerProps, { children: [_jsx(IconsContainer, __assign({}, sharedProps, iconsContainerProps, { children: _jsx(IntentIcon, __assign({ size: 20, className: getIconStyles }, sharedProps, intentIconProps)) })), _jsx(Message
68
63
  // The sr-only region handles screen reader announcements
69
64
  // to prevent the message from being read twice
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { Intent } from '.';
2
+ import type { Intent } from './types';
3
3
  type Notification = {
4
4
  message: string;
5
5
  intent?: Intent;
@@ -10,14 +10,19 @@ export var SnackbarProvider = function (_a) {
10
10
  var children = _a.children;
11
11
  var _b = __read(useState(''), 2), message = _b[0], setMessage = _b[1];
12
12
  var _c = __read(useState('success'), 2), intent = _c[0], setIntent = _c[1];
13
+ var _d = __read(useState(0), 2), id = _d[0], setId = _d[1];
13
14
  var notify = useCallback(function (_a) {
14
15
  var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message;
16
+ setId(function (prev) { return prev + 1; });
15
17
  setMessage(_message);
16
18
  setIntent(_intent);
17
19
  }, []);
18
- var onClose = useCallback(function () {
20
+ var onClose = useCallback(function (reason) {
21
+ // Keep content when swapping instances; only clear on real dismiss.
22
+ if (reason === 'messageChange')
23
+ return;
19
24
  setMessage('');
20
25
  setIntent('success');
21
26
  }, []);
22
- return (_jsxs(_Fragment, { children: [_jsx(SnackbarContext.Provider, __assign({ value: notify }, { children: children })), message && intent ? _jsx(Snackbar, { message: message, intent: intent, onClose: onClose }) : null] }));
27
+ return (_jsxs(_Fragment, { children: [_jsx(SnackbarContext.Provider, __assign({ value: notify }, { children: children })), message && intent ? _jsx(Snackbar, { id: id, message: message, intent: intent, onClose: onClose }) : null] }));
23
28
  };
@@ -26,6 +26,12 @@ export type SnackbarOverrides = {
26
26
  };
27
27
  export type SnackbarProps = {
28
28
  message?: React.ReactNode;
29
+ /**
30
+ * Opaque instance identity. Bump this (e.g. increment a counter) when re-showing
31
+ * the same `message` so the snackbar re-opens and re-announces for screen readers.
32
+ * `SnackbarProvider` / `useNotification` set this automatically on every `notify()`.
33
+ */
34
+ id?: string | number;
29
35
  intent?: Intent;
30
36
  hideOnClickAway?: boolean;
31
37
  disableManualClose?: boolean;
@@ -5,6 +5,7 @@ type UseSnackbarParams = {
5
5
  autoHideDuration: number;
6
6
  hideOnClickAway: boolean;
7
7
  intent: Intent;
8
+ id?: string | number;
8
9
  message?: React.ReactNode;
9
10
  onClose?: (reason: HideReason) => void;
10
11
  overrides?: SnackbarOverrides;
@@ -23,5 +24,5 @@ type UseSnackbarReturnValue = {
23
24
  intent: Intent;
24
25
  overrides?: SnackbarOverrides;
25
26
  };
26
- declare const useSnackbar: ({ autoHide, autoHideDuration, hideOnClickAway, intent: nextIntent, message: nextMessage, onClose, overrides: nextOverrides, }: UseSnackbarParams) => UseSnackbarReturnValue;
27
+ declare const useSnackbar: ({ autoHide, autoHideDuration, hideOnClickAway, intent: nextIntent, id, message: nextMessage, onClose, overrides: nextOverrides, }: UseSnackbarParams) => UseSnackbarReturnValue;
27
28
  export default useSnackbar;
@@ -33,10 +33,10 @@ var useAutoHide = function (_a) {
33
33
  }, [open, autoHide, autoHideDuration, autoHideTimeoutRef]);
34
34
  };
35
35
  var useDomVisibility = function (_a) {
36
- var message = _a.message, open = _a.open, enter = _a.enter, handleClose = _a.handleClose, intent = _a.intent;
36
+ var message = _a.message, open = _a.open, enter = _a.enter, handleClose = _a.handleClose, intent = _a.intent, id = _a.id;
37
37
  var _b = __read(useState(false), 2), domVisibility = _b[0], setDomVisibility = _b[1];
38
38
  var removeFromDomTimeoutRef = useRef();
39
- // handle exit, enter on message change
39
+ // handle exit, enter on message / intent / id change
40
40
  useEffect(function () {
41
41
  if (!message)
42
42
  return undefined;
@@ -51,7 +51,7 @@ var useDomVisibility = function (_a) {
51
51
  open && handleClose('messageChange');
52
52
  return function () { return window.clearTimeout(timeoutId); };
53
53
  // eslint-disable-next-line react-hooks/exhaustive-deps -- handleClose not required
54
- }, [message, intent]);
54
+ }, [message, intent, id]);
55
55
  // remove from DOM, once transition is over
56
56
  useUpdateEffect(function () {
57
57
  if (open)
@@ -64,7 +64,7 @@ var useDomVisibility = function (_a) {
64
64
  return domVisibility;
65
65
  };
66
66
  var useSnackbar = function (_a) {
67
- var autoHide = _a.autoHide, autoHideDuration = _a.autoHideDuration, hideOnClickAway = _a.hideOnClickAway, nextIntent = _a.intent, nextMessage = _a.message, onClose = _a.onClose, nextOverrides = _a.overrides;
67
+ var autoHide = _a.autoHide, autoHideDuration = _a.autoHideDuration, hideOnClickAway = _a.hideOnClickAway, nextIntent = _a.intent, id = _a.id, nextMessage = _a.message, onClose = _a.onClose, nextOverrides = _a.overrides;
68
68
  var _b = __read(useState(false), 2), open = _b[0], setOpen = _b[1];
69
69
  var _c = __read(useState({
70
70
  intent: nextIntent,
@@ -89,7 +89,14 @@ var useSnackbar = function (_a) {
89
89
  };
90
90
  useAutoHide({ open: open, handleClose: handleClose, autoHideTimeoutRef: autoHideTimeoutRef, autoHideDuration: autoHideDuration, autoHide: autoHide });
91
91
  var snackbarContainerRef = useHideOnClickAway({ hideOnClickAway: hideOnClickAway, handleClose: handleClose, open: open });
92
- var shouldRender = useDomVisibility({ handleClose: handleClose, open: open, intent: nextIntent, message: nextMessage, enter: enter });
92
+ var shouldRender = useDomVisibility({
93
+ handleClose: handleClose,
94
+ open: open,
95
+ intent: nextIntent,
96
+ id: id,
97
+ message: nextMessage,
98
+ enter: enter,
99
+ });
93
100
  var handleMouseEnter = function () {
94
101
  window.clearTimeout(autoHideTimeoutRef.current);
95
102
  };
@@ -143,7 +143,7 @@ var BaseInput = function (_a) {
143
143
  var hasScroll = inputRef.current && inputRef.current.scrollHeight > inputRef.current.clientHeight;
144
144
  var charCount = typeof value === 'string' ? value.length : 0;
145
145
  var ariaLabel = 'Clear value';
146
- return ((0, jsx_runtime_1.jsxs)(InputContainer, tslib_1.__assign({ "data-spaceweb": "base-input" }, sharedProps, inputContainerProps, { children: [(0, jsx_runtime_1.jsx)(Before, tslib_1.__assign({}, sharedProps, beforeProps)), (0, jsx_runtime_1.jsx)(Input, tslib_1.__assign({ ref: inputRef, "aria-activedescendant": props['aria-activedescendant'], "aria-autocomplete": props['aria-autocomplete'], "aria-controls": props['aria-controls'], "aria-errormessage": props['aria-errormessage'], "aria-haspopup": props['aria-haspopup'], "aria-label": props['aria-label'], "aria-labelledby": props['aria-labelledby'], "aria-describedby": props['aria-describedby'], "aria-required": props['aria-required'], "aria-invalid": props['aria-invalid'], autoComplete: _autoComplete, disabled: disabled, readOnly: readOnly, id: id, inputMode: inputMode, maxLength: maxLength, name: name, onBlur: handleOnBlur, onChange: handleChange, onFocus: handleOnFocus, onKeyDown: handleKeyDown, onScroll: handleBoxShadow, onKeyPress: onKeyPress, onKeyUp: onKeyUp, pattern: pattern, placeholder: placeholder, type: getInputType(), required: required, role: role, value: value, min: min, max: max, step: step, draggable: draggable, onDragStart: draggable ? handleOnDragStart : undefined, rows: type === constants_1.CUSTOM_INPUT_TYPE.textarea ? rows : null }, sharedProps, inputProps)), showClearIcon ? ((0, jsx_runtime_1.jsx)(ClearIconContainer, tslib_1.__assign({ "$alignTop": type === constants_1.CUSTOM_INPUT_TYPE.textarea }, sharedProps, clearIconContainerProps, { children: (0, jsx_runtime_1.jsx)(ClearIcon, tslib_1.__assign({ title: ariaLabel, "aria-label": ariaLabel, onClick: onClearIconClick, onKeyDown: function (event) {
146
+ return ((0, jsx_runtime_1.jsxs)(InputContainer, tslib_1.__assign({ "data-spaceweb": "base-input" }, sharedProps, inputContainerProps, { children: [(0, jsx_runtime_1.jsx)(Before, tslib_1.__assign({}, sharedProps, beforeProps)), (0, jsx_runtime_1.jsx)(Input, tslib_1.__assign({ ref: inputRef, "aria-activedescendant": props['aria-activedescendant'], "aria-autocomplete": props['aria-autocomplete'], "aria-controls": props['aria-controls'], "aria-errormessage": props['aria-errormessage'], "aria-haspopup": props['aria-haspopup'], "aria-label": props['aria-label'], "aria-labelledby": props['aria-labelledby'], "aria-describedby": props['aria-describedby'], "aria-required": props['aria-required'], "aria-invalid": props['aria-invalid'], "aria-expanded": props['aria-expanded'], autoComplete: _autoComplete, disabled: disabled, readOnly: readOnly, id: id, inputMode: inputMode, maxLength: maxLength, name: name, onBlur: handleOnBlur, onChange: handleChange, onFocus: handleOnFocus, onKeyDown: handleKeyDown, onScroll: handleBoxShadow, onKeyPress: onKeyPress, onKeyUp: onKeyUp, pattern: pattern, placeholder: placeholder, type: getInputType(), required: required, role: role, value: value, min: min, max: max, step: step, draggable: draggable, onDragStart: draggable ? handleOnDragStart : undefined, rows: type === constants_1.CUSTOM_INPUT_TYPE.textarea ? rows : null }, sharedProps, inputProps)), showClearIcon ? ((0, jsx_runtime_1.jsx)(ClearIconContainer, tslib_1.__assign({ "$alignTop": type === constants_1.CUSTOM_INPUT_TYPE.textarea }, sharedProps, clearIconContainerProps, { children: (0, jsx_runtime_1.jsx)(ClearIcon, tslib_1.__assign({ title: ariaLabel, "aria-label": ariaLabel, onClick: onClearIconClick, onKeyDown: function (event) {
147
147
  if (event.key && (event.key === 'Enter' || event.key === ' ')) {
148
148
  event.preventDefault();
149
149
  onClearIconClick();
package/list/divider.js CHANGED
@@ -6,15 +6,17 @@ var react_1 = require("react");
6
6
  var overrides_1 = require("../overrides");
7
7
  var list_item_1 = tslib_1.__importDefault(require("./list-item"));
8
8
  var styled_component_1 = require("./styled-component");
9
+ var utils_1 = require("./utils");
9
10
  var Divider = (0, react_1.forwardRef)(function (_a, ref) {
10
11
  var children = _a.children, _b = _a.first, first = _b === void 0 ? false : _b, _c = _a.overrides, overrides = _c === void 0 ? {} : _c, className = _a.className, restProps = tslib_1.__rest(_a, ["children", "first", "overrides", "className"]);
11
12
  var _d = tslib_1.__read((0, overrides_1.useOverrides)(overrides.Separator, styled_component_1.StyledListItemDivider), 2), Separator = _d[0], separatorProps = _d[1];
12
13
  var _e = tslib_1.__read((0, overrides_1.useOverrides)(overrides.SubHeader, list_item_1.default), 2), SubHeader = _e[0], subHeaderProps = _e[1];
14
+ var propsWithoutContainerAria = (0, utils_1.omitContainerAriaProps)(restProps);
13
15
  return children ? ((0, jsx_runtime_1.jsx)(SubHeader, tslib_1.__assign({ className: [
14
16
  'spr-border-primary border-solid border-b-0 border-l-0 border-r-0 mx-0 rounded-0',
15
17
  first ? 'border-t-0 pt-0' : 'border-t',
16
18
  className,
17
- ], "aria-disabled": true }, restProps, subHeaderProps, { ref: ref }, { children: children }))) : ((0, jsx_runtime_1.jsx)(Separator, tslib_1.__assign({ "data-spaceweb": "divider", "aria-disabled": true, className: className }, restProps, { ref: ref }, separatorProps)));
19
+ ], role: "presentation" }, propsWithoutContainerAria, subHeaderProps, { ref: ref }, { children: children }))) : ((0, jsx_runtime_1.jsx)(Separator, tslib_1.__assign({ "data-spaceweb": "divider", role: "presentation", className: className }, propsWithoutContainerAria, { ref: ref }, separatorProps)));
18
20
  });
19
21
  Divider.displayName = 'Divider';
20
22
  exports.default = Divider;
package/list/list.js CHANGED
@@ -13,14 +13,14 @@ var constants_1 = require("./constants");
13
13
  var style_1 = require("../style");
14
14
  var getCloneElement = function (item, virtualRow, totalCount) {
15
15
  var _a, _b;
16
- return React.cloneElement(item, {
17
- style: [{ '--sw-translate-y': "".concat(virtualRow.start, "px") }, item.props.style],
18
- className: ['w-full absolute top-0 left-0 box-border translate-y-[--sw-translate-y]'],
16
+ return React.cloneElement(item, tslib_1.__assign({ style: [{ '--sw-translate-y': "".concat(virtualRow.start, "px") }, item.props.style], className: ['w-full absolute top-0 left-0 box-border translate-y-[--sw-translate-y]'],
19
17
  // @ts-expect-error TS(2339): Property 'ref' does not exist on type 'ReactElemen... Remove this comment to see the full error message
20
- ref: (0, useCombinedRef_1.combineRefs)(virtualRow.measureElement, item.ref),
21
- 'aria-posinset': (_a = item.props['aria-posinset']) !== null && _a !== void 0 ? _a : virtualRow.index + 1,
22
- 'aria-setsize': (_b = item.props['aria-setsize']) !== null && _b !== void 0 ? _b : totalCount,
23
- });
18
+ ref: (0, useCombinedRef_1.combineRefs)(virtualRow.measureElement, item.ref) }, ((0, utils_1.isPresentationalRole)(item.props.role)
19
+ ? {}
20
+ : {
21
+ 'aria-posinset': (_a = item.props['aria-posinset']) !== null && _a !== void 0 ? _a : virtualRow.index + 1,
22
+ 'aria-setsize': (_b = item.props['aria-setsize']) !== null && _b !== void 0 ? _b : totalCount,
23
+ })));
24
24
  };
25
25
  var List = React.forwardRef(function (_a, forwardedRef) {
26
26
  var _b = _a.overrides, overrides = _b === void 0 ? {} : _b, children = _a.children, virtual = _a.virtual, scrollElement = _a.scrollElement, _c = _a.overscanCount, overscanCount = _c === void 0 ? constants_1.DEFAULT_OVER_SCAN_COUNT : _c, _d = _a.estimateItemSize, estimateItemSize = _d === void 0 ? constants_1.DEFAULT_LIST_ITEM_HEIGHT : _d, _e = _a.role, role = _e === void 0 ? 'list' : _e, autoScrollToSelectedItem = _a.autoScrollToSelectedItem, style = _a.style, className = _a.className, _f = _a.keepFirstItemMounted, keepFirstItemMounted = _f === void 0 ? false : _f, restProps = tslib_1.__rest(_a, ["overrides", "children", "virtual", "scrollElement", "overscanCount", "estimateItemSize", "role", "autoScrollToSelectedItem", "style", "className", "keepFirstItemMounted"]);
@@ -52,13 +52,10 @@ var List = React.forwardRef(function (_a, forwardedRef) {
52
52
  // eslint-disable-next-line react-hooks/exhaustive-deps -- scrollToIndex on mount only
53
53
  }, []);
54
54
  if (virtual) {
55
- return ((0, jsx_runtime_1.jsx)(Root, tslib_1.__assign({ "data-spaceweb": "list", "$as": "div", role: role }, restProps, rootProps, { ref: combinedRef, style: [{ '--sw-min-width': px2rem(styled_component_1.LIST_MIN_WIDTH) }, style, rootProps === null || rootProps === void 0 ? void 0 : rootProps.style], className: [className, rootProps === null || rootProps === void 0 ? void 0 : rootProps.className] }, { children: (0, jsx_runtime_1.jsx)(box_1.Box
56
- // NOTE: resetting margin and padding here. should be removed when normalize css merges
57
- , tslib_1.__assign({
58
- // NOTE: resetting margin and padding here. should be removed when normalize css merges
59
- className: "w-full relative p-0 m-0", style: {
55
+ var _h = (0, utils_1.splitA11yProps)(restProps), a11yProps = _h.a11yProps, otherProps = _h.otherProps;
56
+ return ((0, jsx_runtime_1.jsx)(Root, tslib_1.__assign({ "data-spaceweb": "list", "$as": "div" }, otherProps, rootProps, { ref: combinedRef, style: [{ '--sw-min-width': px2rem(styled_component_1.LIST_MIN_WIDTH) }, style, rootProps === null || rootProps === void 0 ? void 0 : rootProps.style], className: [className, rootProps === null || rootProps === void 0 ? void 0 : rootProps.className] }, { children: (0, jsx_runtime_1.jsx)(box_1.Box, tslib_1.__assign({ className: "w-full relative p-0", style: {
60
57
  height: "".concat(rowVirtualizer.getTotalSize(), "px"),
61
- }, "$as": "ul" }, { children: rowVirtualizer
58
+ }, "$as": "ul", role: role }, a11yProps, { children: rowVirtualizer
62
59
  .getVirtualItems()
63
60
  .map(function (virtualRow) { return getCloneElement(childrenArr[virtualRow.index], virtualRow, childrenArr.length); }) })) })));
64
61
  }
package/list/utils.d.ts CHANGED
@@ -4,3 +4,11 @@ export declare const measureElement: typeof measureElementType;
4
4
  * Keeps the first item mounted even when it falls outside the range.
5
5
  */
6
6
  export declare const customRangeExtractor: (range: Range) => number[];
7
+ export declare const splitA11yProps: (props: Record<string, unknown>) => {
8
+ a11yProps: Record<string, unknown>;
9
+ otherProps: Record<string, unknown>;
10
+ };
11
+ export declare const isPresentationalRole: (role?: string | null) => boolean;
12
+ export declare const omitContainerAriaProps: ({ "aria-posinset": _ariaPosInSet, "aria-setsize": _ariaSetSize, ...rest }: Record<string, unknown>) => {
13
+ [x: string]: unknown;
14
+ };
package/list/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.customRangeExtractor = exports.measureElement = void 0;
3
+ exports.omitContainerAriaProps = exports.isPresentationalRole = exports.splitA11yProps = exports.customRangeExtractor = exports.measureElement = void 0;
4
4
  var tslib_1 = require("tslib");
5
5
  var react_virtual_1 = require("@tanstack/react-virtual");
6
6
  var parseMeasurement = function (str) { return parseFloat(str) || 0; };
@@ -28,3 +28,33 @@ var customRangeExtractor = function (range) {
28
28
  return tslib_1.__spreadArray([0], tslib_1.__read(defaultIndices), false);
29
29
  };
30
30
  exports.customRangeExtractor = customRangeExtractor;
31
+ var isA11yProp = function (key) { return key === 'id' || key === 'tabIndex' || key.startsWith('aria-'); };
32
+ var splitA11yProps = function (props) {
33
+ var e_1, _a;
34
+ var a11yProps = {};
35
+ var otherProps = {};
36
+ try {
37
+ for (var _b = tslib_1.__values(Object.entries(props)), _c = _b.next(); !_c.done; _c = _b.next()) {
38
+ var _d = tslib_1.__read(_c.value, 2), key = _d[0], value = _d[1];
39
+ (isA11yProp(key) ? a11yProps : otherProps)[key] = value;
40
+ }
41
+ }
42
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
43
+ finally {
44
+ try {
45
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
46
+ }
47
+ finally { if (e_1) throw e_1.error; }
48
+ }
49
+ return { a11yProps: a11yProps, otherProps: otherProps };
50
+ };
51
+ exports.splitA11yProps = splitA11yProps;
52
+ var isPresentationalRole = function (role) {
53
+ return role === 'presentation' || role === 'none' || role === 'separator';
54
+ };
55
+ exports.isPresentationalRole = isPresentationalRole;
56
+ var omitContainerAriaProps = function (_a) {
57
+ var _ariaPosInSet = _a["aria-posinset"], _ariaSetSize = _a["aria-setsize"], rest = tslib_1.__rest(_a, ['aria-posinset', 'aria-setsize']);
58
+ return rest;
59
+ };
60
+ exports.omitContainerAriaProps = omitContainerAriaProps;
package/menu/menu-item.js CHANGED
@@ -83,7 +83,7 @@ function MenuActionContainer(_a) {
83
83
  // Only show actions that are always visible or whose parent item is highlighted
84
84
  className: [
85
85
  index === 0 ? 'ml-0' : 'ml-1',
86
- alwaysVisible || sharedProps.$highlighted ? 'visible' : 'invisible w-0 ml-0',
86
+ alwaysVisible || sharedProps.$highlighted ? 'visible' : 'invisible w-0 overflow-hidden ml-0',
87
87
  ] }, { children: React.cloneElement(actionEl, { tabIndex: -1 }) }), (_a = actionEl.key) !== null && _a !== void 0 ? _a : "menu-action-".concat(index)));
88
88
  }) })));
89
89
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprinklrjs/spaceweb",
3
- "version": "14.12.1",
3
+ "version": "14.12.3",
4
4
  "description": "Components for SpaceWeb",
5
5
  "main": "index.js",
6
6
  "module": "./esm/index.js",
@@ -100,7 +100,7 @@
100
100
  "ts-node": "^10.4.0"
101
101
  },
102
102
  "peerDependencies": {
103
- "@sprinklrjs/spaceweb-themes": "14.12.1",
103
+ "@sprinklrjs/spaceweb-themes": "14.12.3",
104
104
  "react": ">=17.0.2 <19.0.0",
105
105
  "react-dom": ">=17.0.2 <19.0.0"
106
106
  }