@skyscanner/backpack-web 34.0.0 → 34.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,6 @@
1
1
  import type { SyntheticEvent, ReactNode } from "react";
2
- export type Props = {
2
+ interface CommonProps {
3
3
  actionText?: string;
4
- ariaLabelledby: string;
5
4
  children: ReactNode;
6
5
  closeLabel?: string;
7
6
  closeOnEscPressed?: boolean;
@@ -14,6 +13,11 @@ export type Props = {
14
13
  title?: string;
15
14
  wide?: boolean;
16
15
  isOpen: boolean;
17
- };
18
- declare const BpkBottomSheet: ({ actionText, ariaLabelledby, children, closeLabel, closeOnEscPressed, closeOnScrimClick, id, isOpen, onAction, onClose, title, wide }: Props) => JSX.Element;
16
+ }
17
+ export type Props = CommonProps & ({
18
+ ariaLabelledby: string;
19
+ } | {
20
+ ariaLabel: string;
21
+ });
22
+ declare const BpkBottomSheet: ({ actionText, children, closeLabel, closeOnEscPressed, closeOnScrimClick, id, isOpen, onAction, onClose, title, wide, ...ariaProps }: Props) => JSX.Element;
19
23
  export default BpkBottomSheet;
@@ -30,7 +30,6 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
30
30
  const getClassName = cssModules(STYLES);
31
31
  const BpkBottomSheet = ({
32
32
  actionText = '',
33
- ariaLabelledby,
34
33
  children,
35
34
  closeLabel = '',
36
35
  closeOnEscPressed = false,
@@ -40,7 +39,8 @@ const BpkBottomSheet = ({
40
39
  onAction = () => null,
41
40
  onClose,
42
41
  title = '',
43
- wide = false
42
+ wide = false,
43
+ ...ariaProps
44
44
  }) => {
45
45
  const [exiting, setExiting] = useState(false);
46
46
  const animationTimeout = 240;
@@ -56,7 +56,7 @@ const BpkBottomSheet = ({
56
56
  return /*#__PURE__*/_jsx(BpkBreakpoint, {
57
57
  query: BREAKPOINTS.ABOVE_MOBILE,
58
58
  children: isAboveMobile => /*#__PURE__*/_jsx(BpkDialogWrapper, {
59
- ariaLabelledby: ariaLabelledby,
59
+ ...ariaProps,
60
60
  dialogClassName: dialogClassName,
61
61
  id: id,
62
62
  isOpen: isOpen,
@@ -56,7 +56,7 @@ BpkCloseButton.propTypes = {
56
56
  onClick: PropTypes.func.isRequired,
57
57
  className: PropTypes.string,
58
58
  customIcon: PropTypes.func,
59
- onDark: PropTypes.Boolean
59
+ onDark: PropTypes.bool
60
60
  };
61
61
  BpkCloseButton.defaultProps = {
62
62
  className: null,
@@ -60,14 +60,22 @@ const getLoadingIcon = props => {
60
60
  const BpkLoadingButton = props => {
61
61
  const {
62
62
  children,
63
+ destructive,
63
64
  disabled,
65
+ featured,
64
66
  icon,
65
67
  iconDisabled,
66
68
  iconLoading,
67
69
  iconOnly,
68
70
  iconPosition,
69
71
  large,
72
+ link,
73
+ linkOnDark,
70
74
  loading,
75
+ primaryOnDark,
76
+ primaryOnLight,
77
+ secondary,
78
+ secondaryOnDark,
71
79
  ...rest
72
80
  } = props;
73
81
  const showBtnDisabled = disabled || loading;
@@ -77,28 +85,28 @@ const BpkLoadingButton = props => {
77
85
  const loadingIcon = getLoadingIcon(props);
78
86
  const iconClassNames = getClassName('bpk-loading-button__icon');
79
87
  let type = BUTTON_TYPES.primary;
80
- if (props.link) {
88
+ if (link) {
81
89
  type = BUTTON_TYPES.link;
82
90
  }
83
- if (props.linkOnDark) {
91
+ if (linkOnDark) {
84
92
  type = BUTTON_TYPES.linkOnDark;
85
93
  }
86
- if (props.featured) {
94
+ if (featured) {
87
95
  type = BUTTON_TYPES.featured;
88
96
  }
89
- if (props.destructive) {
97
+ if (destructive) {
90
98
  type = BUTTON_TYPES.destructive;
91
99
  }
92
- if (props.secondaryOnDark) {
100
+ if (secondaryOnDark) {
93
101
  type = BUTTON_TYPES.secondaryOnDark;
94
102
  }
95
- if (props.secondary) {
103
+ if (secondary) {
96
104
  type = BUTTON_TYPES.secondary;
97
105
  }
98
- if (props.primaryOnLight) {
106
+ if (primaryOnLight) {
99
107
  type = BUTTON_TYPES.primaryOnLight;
100
108
  }
101
- if (props.primaryOnDark) {
109
+ if (primaryOnDark) {
102
110
  type = BUTTON_TYPES.primaryOnDark;
103
111
  }
104
112
  return /*#__PURE__*/_jsx(BpkButtonV2, {
@@ -0,0 +1,4 @@
1
+ import BpkRating from './src/BpkRating';
2
+ import { RATING_SIZES, RATING_SCALES } from './src/common-types';
3
+ export default BpkRating;
4
+ export { RATING_SIZES, RATING_SCALES };
@@ -0,0 +1,36 @@
1
+ import PropTypes from 'prop-types';
2
+ import type { ReactNode } from 'react';
3
+ import { RATING_SIZES, RATING_SCALES } from './common-types';
4
+ type ValueOf<T> = T[keyof T];
5
+ type Props = {
6
+ ariaLabel: string;
7
+ className?: string;
8
+ ratingScale: ValueOf<typeof RATING_SCALES>;
9
+ showScale?: boolean;
10
+ size: ValueOf<typeof RATING_SIZES>;
11
+ subtitle?: string;
12
+ title?: string | ReactNode;
13
+ value: string | number;
14
+ };
15
+ declare const BpkRating: {
16
+ (props: Props): JSX.Element;
17
+ propTypes: {
18
+ ariaLabel: PropTypes.Validator<string>;
19
+ value: PropTypes.Validator<NonNullable<NonNullable<string | number | null | undefined>>>;
20
+ className: PropTypes.Requireable<string>;
21
+ ratingScale: PropTypes.Requireable<string>;
22
+ size: PropTypes.Requireable<string>;
23
+ subtitle: PropTypes.Requireable<string>;
24
+ showScale: PropTypes.Requireable<boolean>;
25
+ title: PropTypes.Requireable<NonNullable<PropTypes.ReactNodeLike>>;
26
+ };
27
+ defaultProps: {
28
+ className: null;
29
+ ratingScale: "zeroToFive";
30
+ size: "base";
31
+ subtitle: null;
32
+ showScale: boolean;
33
+ title: null;
34
+ };
35
+ };
36
+ export default BpkRating;
@@ -14,13 +14,15 @@
14
14
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
- */import PropTypes from 'prop-types';
17
+ */
18
+
19
+ import PropTypes from 'prop-types';
18
20
  import clamp from 'lodash.clamp';
19
21
  import BpkText, { TEXT_STYLES } from "../../bpk-component-text";
20
22
  import { cssModules } from "../../bpk-react-utils";
21
23
  import { RATING_SIZES, RATING_SCALES } from "./common-types";
22
24
  import STYLES from "./BpkRating.module.css";
23
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
25
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
26
  const getClassName = cssModules(STYLES);
25
27
  const getMinValue = () =>
26
28
  // Currently the min value is zero no matter what scale is used.
@@ -51,8 +53,8 @@ const BpkRating = props => {
51
53
  const valueStyles = getClassName('bpk-rating__value');
52
54
  const scaleStyles = getClassName('bpk-rating__scale');
53
55
  const textWrapperStyles = getClassName('bpk-rating__text-wrapper', size === RATING_SIZES.large && 'bpk-rating__text-wrapper--large');
54
- const titleStyles = getClassName(subtitle && 'bpk-rating__title--with-subtitle', size === RATING_SIZES.large && 'bpk-rating__title--large');
55
- const subtitleStyles = getClassName('bpk-rating__subtitle', size === RATING_SIZES.large && 'bpk-rating__subtitle--large');
56
+ const titleStyles = getClassName(subtitle && 'bpk-rating__title--with-subtitle');
57
+ const subtitleStyles = getClassName('bpk-rating__subtitle');
56
58
  let valueTextSize = TEXT_STYLES.label1;
57
59
  let scaleTextSize = TEXT_STYLES.caption;
58
60
  let titleTextSize = TEXT_STYLES.label1;
@@ -66,59 +68,53 @@ const BpkRating = props => {
66
68
  const minValue = getMinValue();
67
69
  const maxValue = getMaxValue(ratingScale);
68
70
  let adjustedValue = value;
69
- if (adjustedValue >= maxValue || adjustedValue <= minValue) {
70
- adjustedValue = clamp(adjustedValue, minValue, maxValue);
71
+ if (typeof adjustedValue === "number") {
72
+ if (adjustedValue >= maxValue || adjustedValue <= minValue) {
73
+ adjustedValue = clamp(adjustedValue, minValue, maxValue);
74
+ }
71
75
  }
72
- return (
73
- /*#__PURE__*/
74
- // $FlowFixMe[cannot-spread-inexact] - inexact rest. See 'decisions/flowfixme.md'.
75
- _jsxs("div", {
76
- className: classNames,
77
- "aria-label": ariaLabel,
78
- role: "figure",
79
- ...rest,
80
- children: [/*#__PURE__*/_jsxs(BpkText, {
76
+ return /*#__PURE__*/_jsxs("div", {
77
+ className: classNames,
78
+ "aria-label": ariaLabel,
79
+ role: "figure",
80
+ ...rest,
81
+ children: [/*#__PURE__*/_jsxs("div", {
82
+ className: valueStyles,
83
+ children: [/*#__PURE__*/_jsx(BpkText, {
81
84
  textStyle: valueTextSize,
82
- tagName: "span"
83
- // TODO: className to be removed
84
- // eslint-disable-next-line @skyscanner/rules/forbid-component-props
85
- ,
86
- className: valueStyles,
85
+ tagName: "span",
87
86
  "aria-hidden": "true",
88
- children: [adjustedValue, showScale && /*#__PURE__*/_jsxs(BpkText, {
89
- textStyle: scaleTextSize
90
- // TODO: className to be removed
91
- // eslint-disable-next-line @skyscanner/rules/forbid-component-props
92
- ,
87
+ children: adjustedValue
88
+ }), showScale && /*#__PURE__*/_jsx(BpkText, {
89
+ textStyle: scaleTextSize,
90
+ tagName: "span",
91
+ "aria-hidden": "true",
92
+ children: /*#__PURE__*/_jsxs("span", {
93
93
  className: scaleStyles,
94
- tagName: "span",
95
- "aria-hidden": "true",
96
94
  children: ["/", maxValue]
97
- })]
98
- }), /*#__PURE__*/_jsxs("div", {
99
- className: textWrapperStyles,
100
- children: [title && /*#__PURE__*/_jsx(BpkText, {
101
- textStyle: titleTextSize
102
- // TODO: className to be removed
103
- // eslint-disable-next-line @skyscanner/rules/forbid-component-props
104
- ,
95
+ })
96
+ })]
97
+ }), /*#__PURE__*/_jsxs("div", {
98
+ className: textWrapperStyles,
99
+ children: [title && /*#__PURE__*/_jsx(BpkText, {
100
+ textStyle: titleTextSize,
101
+ tagName: "span",
102
+ "aria-hidden": "true",
103
+ children: /*#__PURE__*/_jsx("span", {
105
104
  className: titleStyles,
106
- tagName: "span",
107
- "aria-hidden": "true",
108
105
  children: title
109
- }), subtitle && /*#__PURE__*/_jsx(BpkText
110
- // TODO: className to be removed
111
- // eslint-disable-next-line @skyscanner/rules/forbid-component-props
112
- , {
106
+ })
107
+ }), subtitle && /*#__PURE__*/_jsx(BpkText, {
108
+ textStyle: subtitleTextSize,
109
+ tagName: "span",
110
+ "aria-hidden": "true",
111
+ children: /*#__PURE__*/_jsx("span", {
113
112
  className: subtitleStyles,
114
- textStyle: subtitleTextSize,
115
- tagName: "span",
116
- "aria-hidden": "true",
117
113
  children: subtitle
118
- })]
114
+ })
119
115
  })]
120
- })
121
- );
116
+ })]
117
+ });
122
118
  };
123
119
  BpkRating.propTypes = {
124
120
  ariaLabel: PropTypes.string.isRequired,
@@ -15,4 +15,4 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- .bpk-rating{display:flex;flex-flow:row nowrap;align-items:baseline}.bpk-rating--large{align-items:center}.bpk-rating__value{display:flex;padding-right:.5rem;justify-content:center;align-items:baseline;color:#161616}html[dir=rtl] .bpk-rating__value{padding-right:0;padding-left:.5rem;direction:ltr}.bpk-rating__text-wrapper{display:flex;flex-direction:row;align-items:baseline;white-space:nowrap}.bpk-rating__text-wrapper--large{flex-direction:column;align-items:flex-start}.bpk-rating__scale{color:#626971}.bpk-rating__title--with-subtitle{padding-right:.5rem}html[dir=rtl] .bpk-rating__title--with-subtitle{padding-right:0;padding-left:.5rem}.bpk-rating__title--large{padding-top:.0625rem}.bpk-rating__subtitle{color:#626971}
18
+ .bpk-rating{display:flex;flex-flow:row nowrap;align-items:baseline}.bpk-rating--large{align-items:center}.bpk-rating__value{padding-inline-end:.5rem}.bpk-rating__text-wrapper{display:flex;flex-direction:row;align-items:baseline;white-space:nowrap}.bpk-rating__text-wrapper--large{padding-top:.0625rem;flex-direction:column;align-items:flex-start}.bpk-rating__scale{color:#626971}.bpk-rating__title--with-subtitle{padding-right:.5rem}html[dir=rtl] .bpk-rating__title--with-subtitle{padding-right:0;padding-left:.5rem}.bpk-rating__subtitle{color:#626971}
@@ -0,0 +1,8 @@
1
+ export declare const RATING_SIZES: {
2
+ readonly base: "base";
3
+ readonly large: "large";
4
+ };
5
+ export declare const RATING_SCALES: {
6
+ readonly zeroToFive: "zeroToFive";
7
+ readonly zeroToTen: "zeroToTen";
8
+ };
@@ -14,7 +14,9 @@
14
14
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
- */export const RATING_SIZES = {
17
+ */
18
+
19
+ export const RATING_SIZES = {
18
20
  base: 'base',
19
21
  large: 'large'
20
22
  };
@@ -83,10 +83,6 @@ const BpkScrollableCalendarGridList = props => {
83
83
  focusedDate: focusedDate,
84
84
  preventKeyboardFocus: rest.preventKeyboardFocus,
85
85
  "aria-hidden": index !== 1
86
- // TODO: className to be removed
87
- // eslint-disable-next-line @skyscanner/rules/forbid-component-props
88
- ,
89
- className: getClassName('bpk-scrollable-calendar-grid-list__item')
90
86
  })
91
87
  });
92
88
  const calculateOffsetInPixels = numberOfMonths => {
@@ -15,4 +15,4 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- .bpk-scrollable-calendar-grid-list{position:relative;width:100%;height:100%;min-height:26.25rem;overflow-x:hidden;box-sizing:border-box;-ms-overflow-style:-ms-autohiding-scrollbar}.bpk-scrollable-calendar-grid-list__item{display:inline-table}
18
+ .bpk-scrollable-calendar-grid-list{position:relative;width:100%;height:100%;min-height:26.25rem;overflow-x:hidden;box-sizing:border-box;-ms-overflow-style:-ms-autohiding-scrollbar}
@@ -37,6 +37,6 @@ declare const _default: {
37
37
  isDeviceIpad: () => boolean;
38
38
  isDeviceIos: () => boolean;
39
39
  isRTL: () => boolean;
40
- BpkDialogWrapper: (props: import("./src/BpkDialogWrapper/BpkDialogWrapper").Props) => JSX.Element | null;
40
+ BpkDialogWrapper: ({ children, closeOnEscPressed, closeOnScrimClick, dialogClassName, exiting, id, isOpen, onClose, timeout, transitionClassNames, ...ariaProps }: import("./src/BpkDialogWrapper/BpkDialogWrapper").Props) => JSX.Element | null;
41
41
  };
42
42
  export default _default;
@@ -1,6 +1,5 @@
1
1
  import type { SyntheticEvent, ReactNode } from "react";
2
- export interface Props {
3
- ariaLabelledby: string;
2
+ interface CommonProps {
4
3
  children: ReactNode;
5
4
  closeOnEscPressed?: boolean;
6
5
  closeOnScrimClick?: boolean;
@@ -21,4 +20,10 @@ export interface Props {
21
20
  exit?: number;
22
21
  };
23
22
  }
24
- export declare const BpkDialogWrapper: (props: Props) => JSX.Element | null;
23
+ export type Props = CommonProps & ({
24
+ ariaLabelledby: string;
25
+ } | {
26
+ ariaLabel: string;
27
+ });
28
+ export declare const BpkDialogWrapper: ({ children, closeOnEscPressed, closeOnScrimClick, dialogClassName, exiting, id, isOpen, onClose, timeout, transitionClassNames, ...ariaProps }: Props) => JSX.Element | null;
29
+ export {};
@@ -36,23 +36,22 @@ const setPageProperties = ({
36
36
  document.body.style.width = isDialogOpen ? '100%' : 'auto';
37
37
  }
38
38
  };
39
- export const BpkDialogWrapper = props => {
40
- const {
41
- ariaLabelledby,
42
- children,
43
- closeOnEscPressed = false,
44
- closeOnScrimClick = false,
45
- dialogClassName = '',
46
- exiting = false,
47
- id,
48
- isOpen,
49
- onClose,
50
- timeout = {
51
- appear: 0,
52
- exit: 0
53
- },
54
- transitionClassNames = {}
55
- } = props;
39
+ export const BpkDialogWrapper = ({
40
+ children,
41
+ closeOnEscPressed = false,
42
+ closeOnScrimClick = false,
43
+ dialogClassName = '',
44
+ exiting = false,
45
+ id,
46
+ isOpen,
47
+ onClose,
48
+ timeout = {
49
+ appear: 0,
50
+ exit: 0
51
+ },
52
+ transitionClassNames = {},
53
+ ...ariaProps
54
+ }) => {
56
55
  const ref = useRef(null);
57
56
  const [dialogTarget, setDialogTarget] = useState(null);
58
57
  useEffect(() => {
@@ -107,6 +106,14 @@ export const BpkDialogWrapper = props => {
107
106
  window.removeEventListener('keydown', handleKeyDown);
108
107
  };
109
108
  }, [id, isOpen, onClose, closeOnEscPressed, closeOnScrimClick]);
109
+ const aria = {
110
+ ...("ariaLabelledby" in ariaProps ? {
111
+ "aria-labelledby": ariaProps.ariaLabelledby
112
+ } : undefined),
113
+ ...("ariaLabel" in ariaProps ? {
114
+ "aria-label": ariaProps.ariaLabel
115
+ } : undefined)
116
+ };
110
117
  return isOpen ? /*#__PURE__*/_jsxs("div", {
111
118
  className: getClassName('bpk-dialog-wrapper', !dialogSupported && 'bpk-dialog-wrapper--polyfill'),
112
119
  children: [!dialogSupported && /*#__PURE__*/_jsx("div", {
@@ -120,6 +127,7 @@ export const BpkDialogWrapper = props => {
120
127
  exit: exiting,
121
128
  timeout: timeout,
122
129
  children: /*#__PURE__*/_jsx("dialog", {
130
+ ...aria,
123
131
  id: id,
124
132
  className: getClassName('bpk-dialog-wrapper--container', dialogClassName),
125
133
  onCancel: e => {
@@ -130,7 +138,6 @@ export const BpkDialogWrapper = props => {
130
138
  });
131
139
  }
132
140
  },
133
- "aria-labelledby": ariaLabelledby,
134
141
  "data-open": isOpen,
135
142
  ref: ref,
136
143
  children: /*#__PURE__*/_jsx("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyscanner/backpack-web",
3
- "version": "34.0.0",
3
+ "version": "34.1.0",
4
4
  "description": "Backpack Design System web library",
5
5
  "repository": {
6
6
  "type": "git",