@coinbase/cds-mobile 8.53.1 → 8.55.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +5 -2
  3. package/dts/buttons/IconButton.d.ts +23 -1
  4. package/dts/buttons/IconButton.d.ts.map +1 -1
  5. package/dts/controls/InputIconButton.d.ts +22 -1
  6. package/dts/controls/InputIconButton.d.ts.map +1 -1
  7. package/dts/dates/Calendar.d.ts +170 -0
  8. package/dts/dates/Calendar.d.ts.map +1 -0
  9. package/dts/dates/DateInput.d.ts +2 -2
  10. package/dts/dates/DateInput.d.ts.map +1 -1
  11. package/dts/dates/DatePicker.d.ts +136 -67
  12. package/dts/dates/DatePicker.d.ts.map +1 -1
  13. package/dts/overlays/drawer/Drawer.d.ts +12 -0
  14. package/dts/overlays/drawer/Drawer.d.ts.map +1 -1
  15. package/dts/overlays/drawer/useDrawerSpacing.d.ts +4 -1
  16. package/dts/overlays/drawer/useDrawerSpacing.d.ts.map +1 -1
  17. package/dts/overlays/tooltip/Tooltip.d.ts +9 -1
  18. package/dts/overlays/tooltip/Tooltip.d.ts.map +1 -1
  19. package/dts/overlays/tray/Tray.d.ts +3 -0
  20. package/dts/overlays/tray/Tray.d.ts.map +1 -1
  21. package/dts/sticky-footer/StickyFooter.d.ts.map +1 -1
  22. package/esm/buttons/IconButton.js +4 -3
  23. package/esm/controls/InputIconButton.js +4 -3
  24. package/esm/dates/Calendar.js +346 -0
  25. package/esm/dates/DateInput.js +3 -1
  26. package/esm/dates/DatePicker.js +116 -39
  27. package/esm/dates/__stories__/Calendar.stories.js +360 -0
  28. package/esm/dates/__stories__/DatePicker.stories.js +51 -25
  29. package/esm/overlays/__stories__/TrayAction.stories.js +20 -21
  30. package/esm/overlays/__stories__/TrayInformational.stories.js +40 -43
  31. package/esm/overlays/__stories__/TrayMessaging.stories.js +36 -37
  32. package/esm/overlays/__stories__/TrayPromotional.stories.js +51 -74
  33. package/esm/overlays/__stories__/TrayRedesign.stories.js +5 -12
  34. package/esm/overlays/__stories__/Trays.js +1 -0
  35. package/esm/overlays/drawer/Drawer.js +9 -13
  36. package/esm/overlays/drawer/useDrawerSpacing.js +11 -8
  37. package/esm/overlays/tooltip/Tooltip.js +7 -2
  38. package/esm/overlays/tray/Tray.js +5 -0
  39. package/esm/sticky-footer/StickyFooter.js +4 -2
  40. package/esm/sticky-footer/__stories__/StickyFooterWithTray.stories.js +37 -42
  41. package/package.json +2 -4
@@ -1,5 +1,8 @@
1
1
  import type { PinningDirection } from '@coinbase/cds-common';
2
- export declare const useDrawerSpacing: (pin?: PinningDirection | undefined) =>
2
+ export declare const useDrawerSpacing: (
3
+ pin?: PinningDirection | undefined,
4
+ disableSafeAreaPaddingBottom?: boolean,
5
+ ) =>
3
6
  | {
4
7
  paddingTop: number;
5
8
  paddingLeft?: undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"useDrawerSpacing.d.ts","sourceRoot":"","sources":["../../../src/overlays/drawer/useDrawerSpacing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAK7D,eAAO,MAAM,gBAAgB,GAAI,MAAK,gBAAgB,GAAG,SAAoB;;;;;;;;;;;;;;;;;;;;CAoB5E,CAAC"}
1
+ {"version":3,"file":"useDrawerSpacing.d.ts","sourceRoot":"","sources":["../../../src/overlays/drawer/useDrawerSpacing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAK7D,eAAO,MAAM,gBAAgB,GAC3B,MAAK,gBAAgB,GAAG,SAAoB,EAC5C,+BAA8B,OAAe;;;;;;;;;;;;;;;;;;;;CA6B9C,CAAC"}
@@ -1,5 +1,12 @@
1
1
  import React from 'react';
2
- import type { TooltipProps } from './TooltipProps';
2
+ import { type AccessibilityState } from 'react-native';
3
+ import type { TooltipBaseProps } from './TooltipProps';
4
+ export type TooltipProps = TooltipBaseProps & {
5
+ /**
6
+ * Accessibility state for the trigger.
7
+ */
8
+ accessibilityState?: AccessibilityState;
9
+ };
3
10
  export declare const Tooltip: React.MemoExoticComponent<
4
11
  ({
5
12
  children,
@@ -14,6 +21,7 @@ export declare const Tooltip: React.MemoExoticComponent<
14
21
  accessibilityHint,
15
22
  accessibilityLabelForContent,
16
23
  accessibilityHintForContent,
24
+ accessibilityState,
17
25
  visible,
18
26
  invertColorScheme,
19
27
  elevation,
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/overlays/tooltip/Tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4E,MAAM,OAAO,CAAC;AAMjG,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGlE,eAAO,MAAM,OAAO,qSAmBf,YAAY,6CAsJhB,CAAC"}
1
+ {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/overlays/tooltip/Tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4E,MAAM,OAAO,CAAC;AACjG,OAAO,EAAE,KAAK,kBAAkB,EAA4C,MAAM,cAAc,CAAC;AAKjG,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGtE,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG;IAC5C;;OAEG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,OAAO,yTAoBf,YAAY,6CA0JhB,CAAC"}
@@ -78,6 +78,9 @@ export declare const Tray: React.MemoExoticComponent<
78
78
  } & React.RefAttributes<DrawerRefBaseProps>
79
79
  >
80
80
  >;
81
+ /**
82
+ * @deprecated Redundant component.
83
+ */
81
84
  export declare const TrayStickyFooter: ({
82
85
  children,
83
86
  }: {
@@ -1 +1 @@
1
- {"version":3,"file":"Tray.d.ts","sourceRoot":"","sources":["../../../src/overlays/tray/Tray.tsx"],"names":[],"mappings":"AAAA,OAAO,KASN,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAqB,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAM5D,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,EAAE,CAAC;IAAE,WAAW,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,UAAU,CAAC,GAAG;IACtE,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;IAChD,6CAA6C;IAC7C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;IAC9C;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,6CAA6C;IAC7C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;IAC9C;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAC;IAC7D,gDAAgD;IAChD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,aAAa,GACnC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,UAAU,CAAC,GAAG;IACtC,GAAG,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG;QAC/B,2BAA2B;QAC3B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/B,6BAA6B;QAC7B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC9B,yBAAyB;QACzB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAC9B,CAAC;CACH,CAAC;AAEJ,eAAO,MAAM,WAAW;oCACU,MAAM;iBACzB,MAAM;EAInB,CAAC;AAEH,eAAO,MAAM,IAAI;IA1Cf,8CAA8C;eACnC,KAAK,CAAC,SAAS,GAAG,kBAAkB;IAC/C,6CAA6C;aACpC,KAAK,CAAC,SAAS,GAAG,kBAAkB;IAC7C;;;OAGG;sBACe,eAAe;IACjC,6CAA6C;aACpC,KAAK,CAAC,SAAS,GAAG,kBAAkB;IAC7C;;;;OAIG;yBACkB,CAAC,OAAO,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI;IAC5D,gDAAgD;YACxC,KAAK,CAAC,SAAS;;UAKf,WAAW,CAAC,KAAK,CAAC;aACf,WAAW,CAAC,QAAQ,CAAC,GAAG;QAC/B,2BAA2B;QAC3B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/B,6BAA6B;QAC7B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC9B,yBAAyB;QACzB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAC9B;6CAqIJ,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,4CAQrE,CAAC"}
1
+ {"version":3,"file":"Tray.d.ts","sourceRoot":"","sources":["../../../src/overlays/tray/Tray.tsx"],"names":[],"mappings":"AAAA,OAAO,KASN,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAqB,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACvF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAM5D,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,EAAE,CAAC;IAAE,WAAW,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,CAAC;AAEvE,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,UAAU,CAAC,GAAG;IACtE,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;IAChD,6CAA6C;IAC7C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;IAC9C;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,6CAA6C;IAC7C,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;IAC9C;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAC;IAC7D,gDAAgD;IAChD,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,aAAa,GACnC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,UAAU,CAAC,GAAG;IACtC,GAAG,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG;QAC/B,2BAA2B;QAC3B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/B,6BAA6B;QAC7B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC9B,yBAAyB;QACzB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAC9B,CAAC;CACH,CAAC;AAEJ,eAAO,MAAM,WAAW;oCACU,MAAM;iBACzB,MAAM;EAInB,CAAC;AAEH,eAAO,MAAM,IAAI;IA1Cf,8CAA8C;eACnC,KAAK,CAAC,SAAS,GAAG,kBAAkB;IAC/C,6CAA6C;aACpC,KAAK,CAAC,SAAS,GAAG,kBAAkB;IAC7C;;;OAGG;sBACe,eAAe;IACjC,6CAA6C;aACpC,KAAK,CAAC,SAAS,GAAG,kBAAkB;IAC7C;;;;OAIG;yBACkB,CAAC,OAAO,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI;IAC5D,gDAAgD;YACxC,KAAK,CAAC,SAAS;;UAKf,WAAW,CAAC,KAAK,CAAC;aACf,WAAW,CAAC,QAAQ,CAAC,GAAG;QAC/B,2BAA2B;QAC3B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/B,6BAA6B;QAC7B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QAC9B,yBAAyB;QACzB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;KAC9B;6CAsIJ,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,cAAc;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,4CAQrE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"StickyFooter.d.ts","sourceRoot":"","sources":["../../src/sticky-footer/StickyFooter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG;IACzC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;IAPvB;;;OAGG;eACQ,OAAO;+BAiCnB,CAAC"}
1
+ {"version":3,"file":"StickyFooter.d.ts","sourceRoot":"","sources":["../../src/sticky-footer/StickyFooter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAGpC,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE/C,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG;IACzC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;IAPvB;;;OAGG;eACQ,OAAO;+BAmCnB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  const _excluded = ["name", "active", "variant", "transparent", "compact", "background", "color", "borderColor", "iconSize", "borderWidth", "borderRadius", "feedback", "flush", "loading", "style", "accessibilityHint", "accessibilityLabel"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
- import React, { memo, useCallback, useMemo } from 'react';
4
+ import React, { forwardRef, memo, useCallback, useMemo } from 'react';
5
5
  import { ActivityIndicator } from 'react-native';
6
6
  import { transparentVariants, variants } from '@coinbase/cds-common/tokens/button';
7
7
  import { interactableHeight } from '@coinbase/cds-common/tokens/interactableHeight';
@@ -10,7 +10,7 @@ import { useTheme } from '../hooks/useTheme';
10
10
  import { Icon } from '../icons/Icon';
11
11
  import { Pressable } from '../system/Pressable';
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
- export const IconButton = /*#__PURE__*/memo(function IconButton(_ref) {
13
+ export const IconButton = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(function IconButton(_ref, ref) {
14
14
  let {
15
15
  name,
16
16
  active,
@@ -54,6 +54,7 @@ export const IconButton = /*#__PURE__*/memo(function IconButton(_ref) {
54
54
  }), [minHeight]);
55
55
  const pressableStyle = useCallback(state => [sizingStyle, typeof style === 'function' ? style(state) : style], [sizingStyle, style]);
56
56
  return /*#__PURE__*/_jsx(Pressable, _extends({
57
+ ref: ref,
57
58
  accessibilityHint: accessibilityHint,
58
59
  accessibilityLabel: loading ? (accessibilityLabel != null ? accessibilityLabel : '') + ", loading" : accessibilityLabel,
59
60
  background: backgroundValue,
@@ -83,5 +84,5 @@ export const IconButton = /*#__PURE__*/memo(function IconButton(_ref) {
83
84
  style: sizingStyle
84
85
  })
85
86
  }));
86
- });
87
+ }));
87
88
  IconButton.displayName = 'IconButton';
@@ -1,7 +1,7 @@
1
1
  const _excluded = ["disableInheritFocusStyle", "testID", "variant", "accessibilityLabel", "accessibilityHint"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
- import React, { memo, useContext } from 'react';
4
+ import React, { forwardRef, memo, useContext } from 'react';
5
5
  import { IconButton } from '../buttons/IconButton';
6
6
  import { Box } from '../layout/Box';
7
7
  import { TextInputFocusVariantContext } from './context';
@@ -14,7 +14,7 @@ export const variantTransformMap = {
14
14
  foregroundMuted: 'foregroundMuted',
15
15
  secondary: 'secondary'
16
16
  };
17
- export const InputIconButton = /*#__PURE__*/memo(function InputIconButton(_ref) {
17
+ export const InputIconButton = /*#__PURE__*/memo(/*#__PURE__*/forwardRef(function InputIconButton(_ref, ref) {
18
18
  let {
19
19
  disableInheritFocusStyle = false,
20
20
  testID,
@@ -30,10 +30,11 @@ export const InputIconButton = /*#__PURE__*/memo(function InputIconButton(_ref)
30
30
  paddingStart: 1,
31
31
  testID: testID,
32
32
  children: /*#__PURE__*/_jsx(IconButton, _extends({
33
+ ref: ref,
33
34
  transparent: true,
34
35
  accessibilityHint: accessibilityHint != null ? accessibilityHint : props.name,
35
36
  accessibilityLabel: accessibilityLabel != null ? accessibilityLabel : props.name,
36
37
  variant: disableInheritFocusStyle ? variant : transformedVariant
37
38
  }, props))
38
39
  });
39
- });
40
+ }));
@@ -0,0 +1,346 @@
1
+ const _excluded = ["background", "borderRadius", "children"],
2
+ _excluded2 = ["selectedDate", "seedDate", "onPressDate", "disabled", "hideControls", "disabledDates", "highlightedDates", "minDate", "maxDate", "disabledDateError", "nextArrowAccessibilityLabel", "previousArrowAccessibilityLabel", "todayAccessibilityHint", "highlightedDateAccessibilityHint", "style", "styles"];
3
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
5
+ import { forwardRef, memo, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';
6
+ import { StyleSheet } from 'react-native';
7
+ import { generateCalendarMonth } from '@coinbase/cds-common/dates/generateCalendarMonth';
8
+ import { getMidnightDate } from '@coinbase/cds-common/dates/getMidnightDate';
9
+ import { getTimesFromDatesAndRanges } from '@coinbase/cds-common/dates/getTimesFromDatesAndRanges';
10
+ import { useLocale } from '@coinbase/cds-common/system/LocaleProvider';
11
+ import { accessibleOpacityDisabled } from '@coinbase/cds-common/tokens/interactable';
12
+ import { useA11y } from '../hooks/useA11y';
13
+ import { useScreenReaderStatus } from '../hooks/useScreenReaderStatus';
14
+ import { Icon } from '../icons/Icon';
15
+ import { Box } from '../layout/Box';
16
+ import { HStack } from '../layout/HStack';
17
+ import { VStack } from '../layout/VStack';
18
+ import { Tooltip } from '../overlays/tooltip/Tooltip';
19
+ import { Pressable } from '../system/Pressable';
20
+ import { Text } from '../typography/Text';
21
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
+ const CALENDAR_DAY_DIMENSION = 40;
23
+
24
+ // These could be dynamically generated, but our Calendar and DatePicker aren't localized so there's no point
25
+ const DAYS_OF_WEEK = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
26
+ const styles = StyleSheet.create({
27
+ pressable: {
28
+ alignItems: 'center',
29
+ justifyContent: 'center',
30
+ width: '100%',
31
+ height: '100%'
32
+ }
33
+ });
34
+ const CalendarPressable = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
35
+ let {
36
+ background = 'transparent',
37
+ borderRadius = 1000,
38
+ children
39
+ } = _ref,
40
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
41
+ return /*#__PURE__*/_jsx(Pressable, _extends({
42
+ ref: ref,
43
+ background: background,
44
+ borderRadius: borderRadius,
45
+ contentStyle: styles.pressable,
46
+ height: CALENDAR_DAY_DIMENSION,
47
+ width: CALENDAR_DAY_DIMENSION
48
+ }, props, {
49
+ children: children
50
+ }));
51
+ }));
52
+ CalendarPressable.displayName = 'CalendarPressable';
53
+ const getDayAccessibilityLabel = function (date, locale) {
54
+ if (locale === void 0) {
55
+ locale = 'en-US';
56
+ }
57
+ return date.toLocaleDateString(locale, {
58
+ weekday: 'long',
59
+ day: 'numeric'
60
+ }) + " " + date.toLocaleDateString(locale, {
61
+ month: 'long',
62
+ year: 'numeric'
63
+ });
64
+ };
65
+ const CalendarDay = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref2, ref) => {
66
+ let {
67
+ date,
68
+ active,
69
+ disabled,
70
+ highlighted,
71
+ isToday,
72
+ isCurrentMonth,
73
+ onPress,
74
+ disabledError,
75
+ todayAccessibilityHint,
76
+ highlightedDateAccessibilityHint,
77
+ style
78
+ } = _ref2;
79
+ const {
80
+ locale
81
+ } = useLocale();
82
+ const handlePress = useCallback(() => onPress == null ? void 0 : onPress(date), [date, onPress]);
83
+ const accessibilityLabel = useMemo(() => getDayAccessibilityLabel(date, locale), [date, locale]);
84
+ const accessibilityState = useMemo(() => ({
85
+ disabled: !!disabled,
86
+ selected: !!active
87
+ }), [disabled, active]);
88
+
89
+ // Period between phrases gives screen readers a clear pause (e.g. "Today. Date unavailable").
90
+ const accessibilityHint = useMemo(() => {
91
+ const hints = [isToday ? todayAccessibilityHint : undefined, highlighted ? highlightedDateAccessibilityHint : undefined, disabled ? disabledError : undefined].filter(Boolean).join('. ');
92
+ return hints || undefined;
93
+ }, [disabled, highlighted, isToday, todayAccessibilityHint, highlightedDateAccessibilityHint, disabledError]);
94
+ const isScreenReaderEnabled = useScreenReaderStatus();
95
+
96
+ // Expose disabled to the tooltip's accessibilityState so screen readers on both platforms
97
+ // announce the day button as disabled. We only set disabled when a screen reader is active:
98
+ // on some platforms a11y disabled is equivalent to the top-level disabled prop, so always
99
+ // setting it would block tooltip interactivity for users not using SRs.
100
+ const tooltipAccessibilityState = useMemo(() => ({
101
+ disabled: isScreenReaderEnabled
102
+ }), [isScreenReaderEnabled]);
103
+ if (!isCurrentMonth) {
104
+ return /*#__PURE__*/_jsx(Box, {
105
+ "aria-hidden": true,
106
+ height: CALENDAR_DAY_DIMENSION,
107
+ width: CALENDAR_DAY_DIMENSION
108
+ });
109
+ }
110
+ const dayButton = /*#__PURE__*/_jsx(CalendarPressable, {
111
+ ref: ref,
112
+ accessibilityHint: accessibilityHint,
113
+ accessibilityLabel: accessibilityLabel,
114
+ accessibilityRole: "button",
115
+ accessibilityState: accessibilityState,
116
+ background: active && !disabled ? 'bgPrimary' : undefined,
117
+ borderColor: isToday ? 'bgPrimary' : undefined,
118
+ bordered: isToday,
119
+ disabled: disabled,
120
+ feedback: disabled ? 'none' : 'light',
121
+ onPress: handlePress,
122
+ style: style,
123
+ children: /*#__PURE__*/_jsx(Text, {
124
+ accessible: false,
125
+ align: "center",
126
+ color: active && !disabled ? 'fgInverse' : highlighted ? 'fgPrimary' : undefined,
127
+ font: "body",
128
+ children: date.getDate()
129
+ })
130
+ });
131
+ if (disabled) {
132
+ return /*#__PURE__*/_jsx(Tooltip, {
133
+ accessibilityHint: accessibilityHint,
134
+ accessibilityLabel: accessibilityLabel,
135
+ accessibilityState: tooltipAccessibilityState,
136
+ content: disabledError,
137
+ children: dayButton
138
+ });
139
+ }
140
+ return dayButton;
141
+ }));
142
+ CalendarDay.displayName = 'CalendarDay';
143
+ export const Calendar = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref3, ref) => {
144
+ let {
145
+ selectedDate,
146
+ seedDate,
147
+ onPressDate,
148
+ disabled,
149
+ hideControls,
150
+ disabledDates,
151
+ highlightedDates,
152
+ minDate,
153
+ maxDate,
154
+ disabledDateError = 'Date unavailable',
155
+ nextArrowAccessibilityLabel = 'Go to next month',
156
+ previousArrowAccessibilityLabel = 'Go to previous month',
157
+ todayAccessibilityHint = 'Today',
158
+ highlightedDateAccessibilityHint = 'Highlighted',
159
+ style,
160
+ styles
161
+ } = _ref3,
162
+ props = _objectWithoutPropertiesLoose(_ref3, _excluded2);
163
+ const {
164
+ setA11yFocus,
165
+ announceForA11y
166
+ } = useA11y();
167
+ const today = useMemo(() => getMidnightDate(new Date()), []);
168
+ const todayTime = useMemo(() => today.getTime(), [today]);
169
+
170
+ // Determine default calendar seed date: use whichever comes first between maxDate and today
171
+ const defaultSeedDate = useMemo(() => {
172
+ if (selectedDate) {
173
+ return selectedDate;
174
+ }
175
+ if (seedDate) {
176
+ return seedDate;
177
+ }
178
+ if (maxDate) {
179
+ const maxDateTime = getMidnightDate(maxDate).getTime();
180
+ const todayTime = today.getTime();
181
+ return maxDateTime < todayTime ? maxDate : today;
182
+ }
183
+ return today;
184
+ }, [selectedDate, seedDate, maxDate, today]);
185
+ const [calendarSeedDate, setCalendarSeedDate] = useState(defaultSeedDate);
186
+ const initialFocusRef = useRef(null);
187
+ const calendarMonth = useMemo(() => generateCalendarMonth(calendarSeedDate), [calendarSeedDate]);
188
+ const selectedTime = useMemo(() => selectedDate ? getMidnightDate(selectedDate).getTime() : null, [selectedDate]);
189
+ const disabledTimes = useMemo(() => new Set(getTimesFromDatesAndRanges(disabledDates || [])), [disabledDates]);
190
+ const focusTargetTime = useMemo(() => selectedTime || (seedDate ? getMidnightDate(seedDate).getTime() : null) || todayTime, [selectedTime, seedDate, todayTime]);
191
+ useImperativeHandle(ref, () => ({
192
+ focusInitialDate: () => {
193
+ if (disabled || !initialFocusRef.current) {
194
+ return;
195
+ }
196
+ setA11yFocus(initialFocusRef);
197
+ }
198
+ }), [disabled, setA11yFocus]);
199
+ const minTime = useMemo(() => minDate && getMidnightDate(minDate).getTime(), [minDate]);
200
+ const maxTime = useMemo(() => maxDate && getMidnightDate(maxDate).getTime(), [maxDate]);
201
+ const highlightedTimes = useMemo(() => new Set(getTimesFromDatesAndRanges(highlightedDates || [])), [highlightedDates]);
202
+ const handleGoNextMonth = useCallback(() => {
203
+ setCalendarSeedDate(s => {
204
+ const next = new Date(s.getFullYear(), s.getMonth() + 1, 1);
205
+ announceForA11y(next.toLocaleDateString('en-US', {
206
+ month: 'long',
207
+ year: 'numeric'
208
+ }));
209
+ return next;
210
+ });
211
+ }, [setCalendarSeedDate, announceForA11y]);
212
+ const handleGoPreviousMonth = useCallback(() => {
213
+ setCalendarSeedDate(s => {
214
+ const prev = new Date(s.getFullYear(), s.getMonth() - 1, 1);
215
+ announceForA11y(prev.toLocaleDateString('en-US', {
216
+ month: 'long',
217
+ year: 'numeric'
218
+ }));
219
+ return prev;
220
+ });
221
+ }, [setCalendarSeedDate, announceForA11y]);
222
+ const disableGoNextMonth = useMemo(() => {
223
+ if (disabled) {
224
+ return true;
225
+ }
226
+ const firstDateOfNextMonth = new Date(calendarSeedDate.getFullYear(), calendarSeedDate.getMonth() + 1, 1);
227
+ return maxTime ? maxTime < firstDateOfNextMonth.getTime() : false;
228
+ }, [maxTime, calendarSeedDate, disabled]);
229
+ const disableGoPreviousMonth = useMemo(() => {
230
+ if (disabled) {
231
+ return true;
232
+ }
233
+ const lastDateOfPreviousMonth = new Date(calendarSeedDate.getFullYear(), calendarSeedDate.getMonth(), 0);
234
+ return minTime ? minTime > lastDateOfPreviousMonth.getTime() : false;
235
+ }, [minTime, calendarSeedDate, disabled]);
236
+
237
+ // Split calendar month into weeks
238
+ const calendarWeeks = useMemo(() => {
239
+ const weeks = [];
240
+ for (let i = 0; i < calendarMonth.length; i += DAYS_OF_WEEK.length) {
241
+ const weekDates = calendarMonth.slice(i, i + DAYS_OF_WEEK.length);
242
+ weeks.push(["week-" + calendarMonth[i].getTime(), weekDates]);
243
+ }
244
+ return weeks;
245
+ }, [calendarMonth]);
246
+ const monthYearLabel = useMemo(() => calendarSeedDate.toLocaleDateString('en-US', {
247
+ month: 'long',
248
+ year: 'numeric'
249
+ }), [calendarSeedDate]);
250
+ const previousArrowAccessibilityState = useMemo(() => ({
251
+ disabled: !!disableGoPreviousMonth
252
+ }), [disableGoPreviousMonth]);
253
+ const nextArrowAccessibilityState = useMemo(() => ({
254
+ disabled: !!disableGoNextMonth
255
+ }), [disableGoNextMonth]);
256
+ return /*#__PURE__*/_jsxs(VStack, _extends({
257
+ opacity: disabled ? accessibleOpacityDisabled : undefined,
258
+ style: [style, styles == null ? void 0 : styles.root]
259
+ }, props, {
260
+ children: [/*#__PURE__*/_jsxs(HStack, {
261
+ alignItems: "center",
262
+ justifyContent: "space-between",
263
+ paddingBottom: 2,
264
+ paddingStart: 1.5,
265
+ style: styles == null ? void 0 : styles.header,
266
+ children: [/*#__PURE__*/_jsx(Text, {
267
+ accessibilityRole: "header",
268
+ font: "headline",
269
+ style: styles == null ? void 0 : styles.title,
270
+ children: monthYearLabel
271
+ }), !hideControls && /*#__PURE__*/_jsxs(HStack, {
272
+ gap: 1,
273
+ style: styles == null ? void 0 : styles.navigation,
274
+ children: [/*#__PURE__*/_jsx(CalendarPressable, {
275
+ accessibilityLabel: previousArrowAccessibilityLabel,
276
+ accessibilityRole: "button",
277
+ accessibilityState: previousArrowAccessibilityState,
278
+ disabled: disableGoPreviousMonth,
279
+ feedback: "light",
280
+ onPress: disableGoPreviousMonth ? undefined : handleGoPreviousMonth,
281
+ children: /*#__PURE__*/_jsx(Icon, {
282
+ color: "fg",
283
+ name: "backArrow",
284
+ size: "s"
285
+ })
286
+ }), /*#__PURE__*/_jsx(CalendarPressable, {
287
+ accessibilityLabel: nextArrowAccessibilityLabel,
288
+ accessibilityRole: "button",
289
+ accessibilityState: nextArrowAccessibilityState,
290
+ disabled: disableGoNextMonth,
291
+ feedback: "light",
292
+ onPress: disableGoNextMonth ? undefined : handleGoNextMonth,
293
+ children: /*#__PURE__*/_jsx(Icon, {
294
+ color: "fg",
295
+ name: "forwardArrow",
296
+ size: "s"
297
+ })
298
+ })]
299
+ })]
300
+ }), /*#__PURE__*/_jsxs(VStack, {
301
+ gap: 1,
302
+ style: styles == null ? void 0 : styles.content,
303
+ children: [/*#__PURE__*/_jsx(HStack, {
304
+ "aria-hidden": true,
305
+ gap: 1,
306
+ justifyContent: "space-between",
307
+ paddingBottom: 1,
308
+ children: DAYS_OF_WEEK.map(day => /*#__PURE__*/_jsx(Box, {
309
+ alignItems: "center",
310
+ height: CALENDAR_DAY_DIMENSION,
311
+ justifyContent: "center",
312
+ width: CALENDAR_DAY_DIMENSION,
313
+ children: /*#__PURE__*/_jsx(Text, {
314
+ font: "body",
315
+ userSelect: "none",
316
+ children: day.charAt(0)
317
+ })
318
+ }, day))
319
+ }), calendarWeeks.map(_ref4 => {
320
+ let [weekId, week] = _ref4;
321
+ return /*#__PURE__*/_jsx(HStack, {
322
+ gap: 1,
323
+ justifyContent: "space-between",
324
+ children: week.map(date => {
325
+ const time = date.getTime();
326
+ return /*#__PURE__*/_jsx(CalendarDay, {
327
+ ref: time === focusTargetTime ? initialFocusRef : undefined,
328
+ active: time === selectedTime,
329
+ date: date,
330
+ disabled: disabled || minTime !== undefined && minTime !== null && time < minTime || maxTime !== undefined && maxTime !== null && time > maxTime || disabledTimes.has(time),
331
+ disabledError: disabledDateError,
332
+ highlighted: highlightedTimes.has(time),
333
+ highlightedDateAccessibilityHint: highlightedDateAccessibilityHint,
334
+ isCurrentMonth: date.getMonth() === calendarSeedDate.getMonth(),
335
+ isToday: time === todayTime,
336
+ onPress: onPressDate,
337
+ style: styles == null ? void 0 : styles.day,
338
+ todayAccessibilityHint: todayAccessibilityHint
339
+ }, time);
340
+ })
341
+ }, weekId);
342
+ })]
343
+ })]
344
+ }));
345
+ }));
346
+ Calendar.displayName = 'Calendar';
@@ -1,4 +1,4 @@
1
- const _excluded = ["date", "onChangeDate", "error", "onErrorDate", "required", "separator", "minDate", "maxDate", "requiredError", "invalidDateError", "disabledDateError", "start", "end", "placeholder", "helperText", "variant", "onBlur", "onChange", "onEndEditing", "testIDMap", "style"];
1
+ const _excluded = ["date", "onChangeDate", "error", "onErrorDate", "required", "separator", "disabledDates", "minDate", "maxDate", "requiredError", "invalidDateError", "disabledDateError", "start", "end", "placeholder", "helperText", "variant", "onBlur", "onChange", "onEndEditing", "testIDMap", "style"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
4
4
  import React, { forwardRef, memo, useCallback, useMemo, useRef } from 'react';
@@ -16,6 +16,7 @@ export const DateInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
16
16
  onErrorDate,
17
17
  required,
18
18
  separator = '/',
19
+ disabledDates,
19
20
  minDate,
20
21
  maxDate,
21
22
  requiredError,
@@ -53,6 +54,7 @@ export const DateInput = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) =
53
54
  onErrorDate,
54
55
  intlDateFormat,
55
56
  required,
57
+ disabledDates,
56
58
  minDate,
57
59
  maxDate,
58
60
  requiredError,