@skyscanner/backpack-web 20.0.0 → 21.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/bpk-component-button/src/BpkButtonBase.js +1 -11
- package/bpk-component-calendar/README.md +119 -131
- package/bpk-component-calendar/src/BpkCalendarGrid.js +1 -20
- package/bpk-component-calendar/src/BpkCalendarGridHeader.js +6 -15
- package/bpk-component-card/README.md +50 -17
- package/bpk-component-card/index.js +2 -1
- package/bpk-component-card/src/BpkCardWrapper.js +66 -0
- package/bpk-component-card/src/BpkCardWrapper.module.scss +61 -0
- package/bpk-component-datatable/README.md +5 -5
- package/bpk-component-datatable/src/BpkDataTable.js +4 -4
- package/bpk-react-utils/src/deviceDetection.js +2 -2
- package/package.json +1 -1
|
@@ -85,16 +85,6 @@ const BpkButton = (props: Props) => {
|
|
|
85
85
|
);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
// Due to React bug in Chrome, the onClick event fires even if the button is disabled.
|
|
89
|
-
// Pull request is being worked on (as of 2016-12-22): https://github.com/facebook/react/pull/8329
|
|
90
|
-
const onClickWrapper = onClick
|
|
91
|
-
? (...args) => {
|
|
92
|
-
if (!disabled) {
|
|
93
|
-
onClick(...args);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
: null;
|
|
97
|
-
|
|
98
88
|
const buttonType = submit ? 'submit' : 'button';
|
|
99
89
|
|
|
100
90
|
/* eslint-disable react/button-has-type */
|
|
@@ -104,7 +94,7 @@ const BpkButton = (props: Props) => {
|
|
|
104
94
|
type={buttonType}
|
|
105
95
|
disabled={disabled}
|
|
106
96
|
className={classNameFinal}
|
|
107
|
-
onClick={
|
|
97
|
+
onClick={onClick}
|
|
108
98
|
{...rest}
|
|
109
99
|
>
|
|
110
100
|
{children}
|
|
@@ -11,11 +11,13 @@ Check the main [Readme](https://github.com/skyscanner/backpack#usage) for a comp
|
|
|
11
11
|
```js
|
|
12
12
|
import { Component } from 'react';
|
|
13
13
|
import BpkCalendar from '@skyscanner/backpack-web/bpk-component-calendar';
|
|
14
|
-
import BpkInput, {
|
|
14
|
+
import BpkInput, {
|
|
15
|
+
INPUT_TYPES,
|
|
16
|
+
} from '@skyscanner/backpack-web/bpk-component-input';
|
|
15
17
|
import format from 'date-fns/format';
|
|
16
18
|
|
|
17
|
-
const formatDateFull = date => format(date, 'EEEE, do MMMM yyyy');
|
|
18
|
-
const formatMonth = date => format(date, 'MMMM yyyy');
|
|
19
|
+
const formatDateFull = (date) => format(date, 'EEEE, do MMMM yyyy');
|
|
20
|
+
const formatMonth = (date) => format(date, 'MMMM yyyy');
|
|
19
21
|
const daysOfWeek = [
|
|
20
22
|
{
|
|
21
23
|
name: 'Sunday',
|
|
@@ -27,14 +29,14 @@ const daysOfWeek = [
|
|
|
27
29
|
];
|
|
28
30
|
|
|
29
31
|
export default class App extends Component {
|
|
30
|
-
constructor
|
|
32
|
+
constructor() {
|
|
31
33
|
super();
|
|
32
34
|
|
|
33
35
|
this.state = {
|
|
34
36
|
selectionConfiguration: {
|
|
35
37
|
type: CALENDAR_SELECTION_TYPE.single,
|
|
36
38
|
date: null,
|
|
37
|
-
|
|
39
|
+
},
|
|
38
40
|
};
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -45,20 +47,20 @@ export default class App extends Component {
|
|
|
45
47
|
date: date,
|
|
46
48
|
},
|
|
47
49
|
});
|
|
48
|
-
}
|
|
50
|
+
};
|
|
49
51
|
|
|
50
|
-
render
|
|
52
|
+
render() {
|
|
51
53
|
return (
|
|
52
54
|
<div>
|
|
53
55
|
<BpkInput
|
|
54
|
-
id=
|
|
56
|
+
id="dateInput"
|
|
55
57
|
type={INPUT_TYPES.text}
|
|
56
|
-
name=
|
|
58
|
+
name="date"
|
|
57
59
|
value={(this.state.selectionConfiguration.date || '').toString()}
|
|
58
|
-
placeholder=
|
|
60
|
+
placeholder="Departure date"
|
|
59
61
|
/>
|
|
60
62
|
<BpkCalendar
|
|
61
|
-
id=
|
|
63
|
+
id="calendar"
|
|
62
64
|
onDateSelect={this.handleDateSelect}
|
|
63
65
|
formatMonth={formatMonth}
|
|
64
66
|
formatDateFull={formatDateFull}
|
|
@@ -70,7 +72,7 @@ export default class App extends Component {
|
|
|
70
72
|
selectionConfiguration={this.state.selectionConfiguration}
|
|
71
73
|
/>
|
|
72
74
|
</div>
|
|
73
|
-
)
|
|
75
|
+
);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
```
|
|
@@ -95,12 +97,14 @@ The default export of this package uses the following set of components:
|
|
|
95
97
|
Composition and state are implemented using the aforementioned higher-order components:
|
|
96
98
|
|
|
97
99
|
```js
|
|
98
|
-
withCalendarState(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
withCalendarState(
|
|
101
|
+
composeCalendar(
|
|
102
|
+
BpkCalendarNav,
|
|
103
|
+
BpkCalendarGridHeader,
|
|
104
|
+
TransitioningBpkCalendarGrid,
|
|
105
|
+
BpkCalendarDate,
|
|
106
|
+
),
|
|
107
|
+
);
|
|
104
108
|
```
|
|
105
109
|
|
|
106
110
|
### Building a custom calendar
|
|
@@ -108,45 +112,32 @@ withCalendarState(composeCalendar(
|
|
|
108
112
|
A custom calendar can be created by swapping out any default component for an alternative:
|
|
109
113
|
|
|
110
114
|
```js
|
|
111
|
-
composeCalendar(
|
|
112
|
-
MyNavigation,
|
|
113
|
-
MyHeader,
|
|
114
|
-
MyGrid,
|
|
115
|
-
MyDate,
|
|
116
|
-
)
|
|
115
|
+
composeCalendar(MyNavigation, MyHeader, MyGrid, MyDate);
|
|
117
116
|
```
|
|
118
117
|
|
|
119
118
|
The navigation and header components are optional. If they are not needed, the arguments to `composeCalendar` should be set to `null`:
|
|
120
119
|
|
|
121
120
|
```js
|
|
122
|
-
composeCalendar(
|
|
123
|
-
null,
|
|
124
|
-
null,
|
|
125
|
-
MyGrid,
|
|
126
|
-
MyDate,
|
|
127
|
-
)
|
|
121
|
+
composeCalendar(null, null, MyGrid, MyDate);
|
|
128
122
|
```
|
|
129
123
|
|
|
130
124
|
In many cases, you might want to keep most of the components and replace only one or two:
|
|
131
125
|
|
|
132
126
|
```js
|
|
133
|
-
composeCalendar(
|
|
134
|
-
BpkCalendarNav,
|
|
135
|
-
BpkCalendarGridHeader,
|
|
136
|
-
BpkCalendarGrid,
|
|
137
|
-
MyDate,
|
|
138
|
-
)
|
|
127
|
+
composeCalendar(BpkCalendarNav, BpkCalendarGridHeader, BpkCalendarGrid, MyDate);
|
|
139
128
|
```
|
|
140
129
|
|
|
141
130
|
Finally, focus management and support for keyboard input can be added using `withCalendarState`:
|
|
142
131
|
|
|
143
132
|
```js
|
|
144
|
-
withCalendarState(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
133
|
+
withCalendarState(
|
|
134
|
+
composeCalendar(
|
|
135
|
+
BpkCalendarNav,
|
|
136
|
+
BpkCalendarGridHeader,
|
|
137
|
+
BpkCalendarGrid,
|
|
138
|
+
MyDate,
|
|
139
|
+
),
|
|
140
|
+
);
|
|
150
141
|
```
|
|
151
142
|
|
|
152
143
|
> When implementing a replacement for any of the default calendar components, make sure it
|
|
@@ -155,32 +146,32 @@ withCalendarState(composeCalendar(
|
|
|
155
146
|
|
|
156
147
|
## Props
|
|
157
148
|
|
|
158
|
-
| Property
|
|
159
|
-
|
|
|
160
|
-
| daysOfWeek
|
|
161
|
-
| formatDateFull
|
|
162
|
-
| formatMonth
|
|
163
|
-
| id
|
|
164
|
-
| weekStartsOn
|
|
165
|
-
| changeMonthLabel
|
|
166
|
-
| nextMonthLabel
|
|
167
|
-
| previousMonthLabel
|
|
168
|
-
| className
|
|
169
|
-
| fixedWidth
|
|
170
|
-
| gridClassName
|
|
171
|
-
| initiallyFocusedDate
|
|
172
|
-
| markOutsideDays
|
|
173
|
-
| markToday
|
|
174
|
-
| maxDate
|
|
175
|
-
| minDate
|
|
176
|
-
| onDateSelect
|
|
177
|
-
| onMonthChange
|
|
178
|
-
| selectionConfiguration| object
|
|
179
|
-
| navProps
|
|
180
|
-
| headerProps
|
|
181
|
-
| gridProps
|
|
182
|
-
| dateProps
|
|
183
|
-
| weekDayKey
|
|
149
|
+
| Property | PropType | Required | Default Value |
|
|
150
|
+
| ---------------------- | -------- | --------------- | ---------------------------------------------------- |
|
|
151
|
+
| daysOfWeek | object | true | - |
|
|
152
|
+
| formatDateFull | func | true | - |
|
|
153
|
+
| formatMonth | func | true | - |
|
|
154
|
+
| id | string | true | - |
|
|
155
|
+
| weekStartsOn | number | true | - |
|
|
156
|
+
| changeMonthLabel | string | if Nav !== null | - |
|
|
157
|
+
| nextMonthLabel | string | if Nav !== null | - |
|
|
158
|
+
| previousMonthLabel | string | if Nav !== null | - |
|
|
159
|
+
| className | string | false | null |
|
|
160
|
+
| fixedWidth | bool | false | true |
|
|
161
|
+
| gridClassName | string | false | null |
|
|
162
|
+
| initiallyFocusedDate | Date | false | null |
|
|
163
|
+
| markOutsideDays | bool | false | true |
|
|
164
|
+
| markToday | bool | false | true |
|
|
165
|
+
| maxDate | Date | false | new Date() + 1 year |
|
|
166
|
+
| minDate | Date | false | new Date() |
|
|
167
|
+
| onDateSelect | func | false | null |
|
|
168
|
+
| onMonthChange | func | false | null |
|
|
169
|
+
| selectionConfiguration | object | false | { type: CALENDAR_SELECTION_TYPE.single, date: null } |
|
|
170
|
+
| navProps | object | false | null |
|
|
171
|
+
| headerProps | object | false | null |
|
|
172
|
+
| gridProps | object | false | null |
|
|
173
|
+
| dateProps | object | false | null |
|
|
174
|
+
| weekDayKey | string | false | nameAbbr |
|
|
184
175
|
|
|
185
176
|
Some of the more complex props and props for sub-components are detailed below.
|
|
186
177
|
|
|
@@ -189,18 +180,18 @@ Some of the more complex props and props for sub-components are detailed below.
|
|
|
189
180
|
The BpkCalendarNav component is used to change the month that is being displayed by using
|
|
190
181
|
buttons and a select box.
|
|
191
182
|
|
|
192
|
-
| Property
|
|
193
|
-
|
|
|
194
|
-
| changeMonthLabel
|
|
195
|
-
| nextMonthLabel
|
|
196
|
-
| previousMonthLabel
|
|
197
|
-
| formatMonth
|
|
198
|
-
| id
|
|
199
|
-
| maxDate
|
|
200
|
-
| minDate
|
|
201
|
-
| month
|
|
202
|
-
| onMonthChange
|
|
203
|
-
| disabled
|
|
183
|
+
| Property | PropType | Required | Default Value |
|
|
184
|
+
| ------------------ | -------- | -------- | ------------- |
|
|
185
|
+
| changeMonthLabel | string | true | - |
|
|
186
|
+
| nextMonthLabel | string | true | - |
|
|
187
|
+
| previousMonthLabel | string | true | - |
|
|
188
|
+
| formatMonth | func | true | - |
|
|
189
|
+
| id | string | true | - |
|
|
190
|
+
| maxDate | Date | true | - |
|
|
191
|
+
| minDate | Date | true | - |
|
|
192
|
+
| month | Date | true | - |
|
|
193
|
+
| onMonthChange | func | false | null |
|
|
194
|
+
| disabled | bool | false | false |
|
|
204
195
|
|
|
205
196
|
### BpkCalendarGridHeader
|
|
206
197
|
|
|
@@ -208,55 +199,53 @@ The BpkCalendarGridHeader component displays the header of `BpkCalendarGrid`, li
|
|
|
208
199
|
the days of the week. This is needed as a separate component, as the header should stay
|
|
209
200
|
in place while the rest of the grid transitions when changing months.
|
|
210
201
|
|
|
211
|
-
| Property
|
|
212
|
-
|
|
|
213
|
-
| daysOfWeek
|
|
214
|
-
| weekStartsOn
|
|
215
|
-
| className
|
|
216
|
-
| weekDayKey
|
|
202
|
+
| Property | PropType | Required | Default Value |
|
|
203
|
+
| ------------ | -------- | -------- | ------------- |
|
|
204
|
+
| daysOfWeek | object | true | - |
|
|
205
|
+
| weekStartsOn | number | true | - |
|
|
206
|
+
| className | string | false | null |
|
|
207
|
+
| weekDayKey | string | false | nameAbbr |
|
|
217
208
|
|
|
218
209
|
### BpkCalendarGrid
|
|
219
210
|
|
|
220
211
|
The BpkCalendarGrid component displays a month as a table.
|
|
221
212
|
|
|
222
|
-
| Property
|
|
223
|
-
|
|
|
224
|
-
| DateComponent
|
|
225
|
-
|
|
|
226
|
-
|
|
|
227
|
-
|
|
|
228
|
-
|
|
|
229
|
-
|
|
|
230
|
-
|
|
|
231
|
-
|
|
|
232
|
-
|
|
|
233
|
-
|
|
|
234
|
-
|
|
|
235
|
-
|
|
|
236
|
-
|
|
|
237
|
-
|
|
|
238
|
-
| onDateKeyDown | func | false | null |
|
|
239
|
-
| preventKeyboardFocus | bool | false | false |
|
|
213
|
+
| Property | PropType | Required | Default Value |
|
|
214
|
+
| ---------------------- | ----------- | -------- | ---------------------------------------------------- |
|
|
215
|
+
| DateComponent | elementType | true | - |
|
|
216
|
+
| formatDateFull | func | true | - |
|
|
217
|
+
| month | Date | true | - |
|
|
218
|
+
| weekStartsOn | number | true | - |
|
|
219
|
+
| selectionConfiguration | object | false | { type: CALENDAR_SELECTION_TYPE.single, date: null } |
|
|
220
|
+
| focusedDate | Date | false | null |
|
|
221
|
+
| isKeyboardFocusable | bool | false | true |
|
|
222
|
+
| markOutsideDays | bool | false | true |
|
|
223
|
+
| markToday | bool | false | true |
|
|
224
|
+
| maxDate | Date | false | new Date() + 1 year |
|
|
225
|
+
| minDate | Date | false | new Date() |
|
|
226
|
+
| onDateClick | func | false | null |
|
|
227
|
+
| onDateKeyDown | func | false | null |
|
|
228
|
+
| preventKeyboardFocus | bool | false | false |
|
|
240
229
|
|
|
241
230
|
### BpkCalendarDate
|
|
242
231
|
|
|
243
232
|
The BpkCalendarDate component is used to render the content of a cell
|
|
244
233
|
(a single day) inside the calendar grid.
|
|
245
234
|
|
|
246
|
-
| Property
|
|
247
|
-
|
|
|
248
|
-
| date
|
|
249
|
-
| isBlocked
|
|
250
|
-
| isFocused
|
|
251
|
-
| isKeyboardFocusable
|
|
252
|
-
| isOutside
|
|
253
|
-
| isSelected
|
|
254
|
-
| isToday
|
|
255
|
-
| onClick
|
|
256
|
-
| onDateKeyDown
|
|
257
|
-
| preventKeyboardFocus
|
|
258
|
-
| selectionType
|
|
259
|
-
| style
|
|
235
|
+
| Property | PropType | Required | Default Value |
|
|
236
|
+
| -------------------- | ------------------------------------------------------------------------------------------------- | -------- | ---------------------- |
|
|
237
|
+
| date | Date | true | - |
|
|
238
|
+
| isBlocked | bool | false | false |
|
|
239
|
+
| isFocused | bool | false | false |
|
|
240
|
+
| isKeyboardFocusable | bool | false | true |
|
|
241
|
+
| isOutside | bool | false | false |
|
|
242
|
+
| isSelected | bool | false | false |
|
|
243
|
+
| isToday | bool | false | false |
|
|
244
|
+
| onClick | func | false | null |
|
|
245
|
+
| onDateKeyDown | func | false | null |
|
|
246
|
+
| preventKeyboardFocus | bool | false | true |
|
|
247
|
+
| selectionType | oneOf(SELECTION_TYPES.single, SELECTION_TYPES.start, SELECTION_TYPES.middle, SELECTION_TYPES.end) | false | SELECTION_TYPES.single |
|
|
248
|
+
| style | object | false | null |
|
|
260
249
|
|
|
261
250
|
#### `selectionType` prop
|
|
262
251
|
|
|
@@ -341,7 +330,7 @@ A function to format a full, human-readable date, for example: "Monday, 8th Janu
|
|
|
341
330
|
```js
|
|
342
331
|
import format from 'date-fns/format';
|
|
343
332
|
|
|
344
|
-
const formatDateFull = date => format(date, 'EEEE, do MMMM yyyy');
|
|
333
|
+
const formatDateFull = (date) => format(date, 'EEEE, do MMMM yyyy');
|
|
345
334
|
```
|
|
346
335
|
|
|
347
336
|
#### formatMonth
|
|
@@ -353,7 +342,7 @@ If you just need to quickly prototype, use the following from [`date-fns`](https
|
|
|
353
342
|
```js
|
|
354
343
|
import format from 'date-fns/format';
|
|
355
344
|
|
|
356
|
-
const formatMonth = date => format(date, 'MMMM yyyy');
|
|
345
|
+
const formatMonth = (date) => format(date, 'MMMM yyyy');
|
|
357
346
|
```
|
|
358
347
|
|
|
359
348
|
#### weekStartsOn
|
|
@@ -381,14 +370,13 @@ These are useful if your custom implementation of one of these components requir
|
|
|
381
370
|
|
|
382
371
|
## Theme Props
|
|
383
372
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
373
|
+
- `calendarDateTextColor`
|
|
374
|
+
- `calendarDateTextHoverColor`
|
|
375
|
+
- `calendarDateTextActiveColor`
|
|
376
|
+
- `calendarDateTextFocusColor`
|
|
377
|
+
- `calendarDateTextSelectedColor`
|
|
378
|
+
- `calendarDateSelectedBackgroundColor`
|
|
379
|
+
- `calendarDateFocusedBorderColor`
|
|
380
|
+
- `calendarNudgerIconColor`
|
|
381
|
+
- `calendarNudgerIconHoverColor`
|
|
382
|
+
- `calendarNudgerIconActiveColor`
|
|
@@ -21,14 +21,12 @@ import { Component } from 'react';
|
|
|
21
21
|
|
|
22
22
|
import { cssModules, isDeviceIos } from '../../bpk-react-utils';
|
|
23
23
|
|
|
24
|
-
import BpkCalendarGridHeader from './BpkCalendarGridHeader';
|
|
25
24
|
import Week from './Week';
|
|
26
25
|
import {
|
|
27
26
|
addMonths,
|
|
28
27
|
formatIsoDate,
|
|
29
28
|
getCalendarMonthWeeks,
|
|
30
29
|
isSameMonth,
|
|
31
|
-
orderDaysOfWeek,
|
|
32
30
|
} from './date-utils';
|
|
33
31
|
import CustomPropTypes, { CALENDAR_SELECTION_TYPE } from './custom-proptypes';
|
|
34
32
|
import STYLES from './BpkCalendarGrid.module.scss';
|
|
@@ -58,14 +56,12 @@ class BpkCalendarGrid extends Component {
|
|
|
58
56
|
props.month,
|
|
59
57
|
props.weekStartsOn,
|
|
60
58
|
),
|
|
61
|
-
daysOfWeek: orderDaysOfWeek(props.daysOfWeek, props.weekStartsOn),
|
|
62
59
|
};
|
|
63
60
|
}
|
|
64
61
|
|
|
65
62
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
66
63
|
// We cache expensive calculations (and identities) in state
|
|
67
64
|
if (
|
|
68
|
-
nextProps.daysOfWeek !== this.props.daysOfWeek ||
|
|
69
65
|
!isSameMonth(nextProps.month, this.props.month) ||
|
|
70
66
|
nextProps.weekStartsOn !== this.props.weekStartsOn
|
|
71
67
|
) {
|
|
@@ -74,10 +70,6 @@ class BpkCalendarGrid extends Component {
|
|
|
74
70
|
nextProps.month,
|
|
75
71
|
nextProps.weekStartsOn,
|
|
76
72
|
),
|
|
77
|
-
daysOfWeek: orderDaysOfWeek(
|
|
78
|
-
nextProps.daysOfWeek,
|
|
79
|
-
nextProps.weekStartsOn,
|
|
80
|
-
),
|
|
81
73
|
});
|
|
82
74
|
}
|
|
83
75
|
}
|
|
@@ -91,7 +83,6 @@ class BpkCalendarGrid extends Component {
|
|
|
91
83
|
dateProps,
|
|
92
84
|
focusedDate,
|
|
93
85
|
formatDateFull,
|
|
94
|
-
formatMonth,
|
|
95
86
|
ignoreOutsideDate,
|
|
96
87
|
isKeyboardFocusable,
|
|
97
88
|
markOutsideDays,
|
|
@@ -106,20 +97,12 @@ class BpkCalendarGrid extends Component {
|
|
|
106
97
|
weekStartsOn,
|
|
107
98
|
} = this.props;
|
|
108
99
|
|
|
109
|
-
const { calendarMonthWeeks
|
|
100
|
+
const { calendarMonthWeeks } = this.state;
|
|
110
101
|
|
|
111
102
|
const classNames = getClassName('bpk-calendar-grid', className);
|
|
112
103
|
|
|
113
104
|
return (
|
|
114
105
|
<div className={classNames} aria-hidden={!isKeyboardFocusable}>
|
|
115
|
-
<caption className={getClassName('bpk-calendar-grid__caption')} hidden>
|
|
116
|
-
{formatMonth(month)}
|
|
117
|
-
</caption>
|
|
118
|
-
<BpkCalendarGridHeader
|
|
119
|
-
isTableHead
|
|
120
|
-
daysOfWeek={daysOfWeek}
|
|
121
|
-
weekStartsOn={weekStartsOn}
|
|
122
|
-
/>
|
|
123
106
|
<div>
|
|
124
107
|
{calendarMonthWeeks.map((dates) => (
|
|
125
108
|
<Week
|
|
@@ -154,9 +137,7 @@ class BpkCalendarGrid extends Component {
|
|
|
154
137
|
export const propTypes = {
|
|
155
138
|
// Required
|
|
156
139
|
DateComponent: PropTypes.elementType.isRequired,
|
|
157
|
-
daysOfWeek: CustomPropTypes.DaysOfWeek.isRequired,
|
|
158
140
|
formatDateFull: PropTypes.func.isRequired,
|
|
159
|
-
formatMonth: PropTypes.func.isRequired,
|
|
160
141
|
month: PropTypes.instanceOf(Date).isRequired,
|
|
161
142
|
weekStartsOn: PropTypes.number.isRequired,
|
|
162
143
|
// Optional
|
|
@@ -55,35 +55,28 @@ WeekDay.defaultProps = {
|
|
|
55
55
|
|
|
56
56
|
class BpkCalendarGridHeader extends PureComponent {
|
|
57
57
|
render() {
|
|
58
|
-
const { className,
|
|
59
|
-
|
|
60
|
-
const Header = isTableHead ? 'thead' : 'header';
|
|
61
|
-
const List = isTableHead ? 'tr' : 'ol';
|
|
62
|
-
const Item = isTableHead ? 'th' : 'li';
|
|
58
|
+
const { className, weekDayKey, weekStartsOn } = this.props;
|
|
63
59
|
|
|
64
60
|
const daysOfWeek = orderDaysOfWeek(this.props.daysOfWeek, weekStartsOn);
|
|
65
61
|
|
|
66
62
|
const classNames = [getClassName('bpk-calendar-header')];
|
|
67
|
-
if (isTableHead) {
|
|
68
|
-
classNames.push(getClassName('bpk-calendar-header--table-head'));
|
|
69
|
-
}
|
|
70
63
|
if (className) {
|
|
71
64
|
classNames.push(className);
|
|
72
65
|
}
|
|
73
66
|
|
|
74
67
|
return (
|
|
75
|
-
<
|
|
76
|
-
<
|
|
68
|
+
<header className={classNames.join(' ')} aria-hidden>
|
|
69
|
+
<ol className={getClassName('bpk-calendar-header__week')}>
|
|
77
70
|
{daysOfWeek.map((weekDay) => (
|
|
78
71
|
<WeekDay
|
|
79
|
-
Element=
|
|
72
|
+
Element="li"
|
|
80
73
|
key={weekDay.index}
|
|
81
74
|
weekDay={weekDay}
|
|
82
75
|
weekDayKey={weekDayKey}
|
|
83
76
|
/>
|
|
84
77
|
))}
|
|
85
|
-
</
|
|
86
|
-
</
|
|
78
|
+
</ol>
|
|
79
|
+
</header>
|
|
87
80
|
);
|
|
88
81
|
}
|
|
89
82
|
}
|
|
@@ -91,13 +84,11 @@ class BpkCalendarGridHeader extends PureComponent {
|
|
|
91
84
|
BpkCalendarGridHeader.propTypes = {
|
|
92
85
|
daysOfWeek: CustomPropTypes.DaysOfWeek.isRequired,
|
|
93
86
|
weekStartsOn: PropTypes.number.isRequired,
|
|
94
|
-
isTableHead: PropTypes.bool,
|
|
95
87
|
className: PropTypes.string,
|
|
96
88
|
weekDayKey: CustomPropTypes.WeekDayKey,
|
|
97
89
|
};
|
|
98
90
|
|
|
99
91
|
BpkCalendarGridHeader.defaultProps = {
|
|
100
|
-
isTableHead: false,
|
|
101
92
|
className: null,
|
|
102
93
|
weekDayKey: 'nameAbbr',
|
|
103
94
|
};
|
|
@@ -15,9 +15,9 @@ import BpkCard from '@skyscanner/backpack-web/bpk-component-card';
|
|
|
15
15
|
|
|
16
16
|
export default () => (
|
|
17
17
|
<BpkCard>
|
|
18
|
-
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
|
|
19
|
+
ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis
|
|
20
|
+
parturient montes, nascetur ridiculus mus.
|
|
21
21
|
</BpkCard>
|
|
22
22
|
);
|
|
23
23
|
```
|
|
@@ -25,20 +25,22 @@ export default () => (
|
|
|
25
25
|
### BpkDividedCard
|
|
26
26
|
|
|
27
27
|
```js
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
BpkDividedCard,
|
|
30
|
+
ORIENTATION,
|
|
31
|
+
} from '@skyscanner/backpack-web/bpk-component-card';
|
|
29
32
|
|
|
30
33
|
export default () => (
|
|
31
34
|
<>
|
|
32
35
|
<BpkDividedCard
|
|
33
|
-
primaryContent={
|
|
34
|
-
secondaryContent={
|
|
36
|
+
primaryContent={<span>foo</span>}
|
|
37
|
+
secondaryContent={<span>bar</span>}
|
|
35
38
|
orientation={ORIENTATION.vertical}
|
|
36
39
|
/>
|
|
37
|
-
|
|
38
40
|
// Toggle shadow shadow with isElevated
|
|
39
41
|
<BpkDividedCard
|
|
40
|
-
primaryContent={
|
|
41
|
-
secondaryContent={
|
|
42
|
+
primaryContent={<span>foo</span>}
|
|
43
|
+
secondaryContent={<span>bar</span>}
|
|
42
44
|
orientation={ORIENTATION.horizontal}
|
|
43
45
|
isElevated={false}
|
|
44
46
|
/>
|
|
@@ -46,6 +48,28 @@ export default () => (
|
|
|
46
48
|
);
|
|
47
49
|
```
|
|
48
50
|
|
|
51
|
+
### BpkCardWrapper
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import { BpkCardWrapper } from '@skyscanner/backpack-web/bpk-component-card';
|
|
55
|
+
import { coreAccentDay } from '@skyscanner/bpk-foundations-web/tokens/base.es6';
|
|
56
|
+
import BpkCard from '@skyscanner/backpack-web/bpk-component-card';
|
|
57
|
+
|
|
58
|
+
export default () => (
|
|
59
|
+
<BpkCardWrapper
|
|
60
|
+
header={<span>Hoc header</span>}
|
|
61
|
+
card={
|
|
62
|
+
<BpkCard>
|
|
63
|
+
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo
|
|
64
|
+
ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis
|
|
65
|
+
dis parturient montes, nascetur ridiculus mus.
|
|
66
|
+
</BpkCard>
|
|
67
|
+
}
|
|
68
|
+
backgroundColor={coreAccentDay}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
```
|
|
72
|
+
|
|
49
73
|
## Props
|
|
50
74
|
|
|
51
75
|
### BpkCard
|
|
@@ -60,11 +84,20 @@ export default () => (
|
|
|
60
84
|
|
|
61
85
|
### BpkDividedCard
|
|
62
86
|
|
|
63
|
-
| Property
|
|
64
|
-
|
|
|
65
|
-
| primaryContent
|
|
66
|
-
| secondaryContent | node
|
|
67
|
-
| orientation
|
|
68
|
-
| href
|
|
69
|
-
| className
|
|
70
|
-
| isElevated
|
|
87
|
+
| Property | PropType | Required | Default Value |
|
|
88
|
+
| ---------------- | --------------------------------------------------- | -------- | ---------------------- |
|
|
89
|
+
| primaryContent | node | true | - |
|
|
90
|
+
| secondaryContent | node | true | - |
|
|
91
|
+
| orientation | oneOf(ORIENTATION.horizontal, ORIENTATION.vertical) | false | ORIENTATION.horizontal |
|
|
92
|
+
| href | string | false | null |
|
|
93
|
+
| className | string | false | null |
|
|
94
|
+
| isElevated | bool | false | true |
|
|
95
|
+
|
|
96
|
+
### BpkCardWrapper
|
|
97
|
+
|
|
98
|
+
| Property | PropType | Required | Default Value |
|
|
99
|
+
| --------------- | -------- | -------- | ------------- |
|
|
100
|
+
| backgroundColor | string | true | null |
|
|
101
|
+
| card | node | true | - |
|
|
102
|
+
| header | node | true | - |
|
|
103
|
+
| className | string | false | null |
|
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
/* @flow strict */
|
|
19
19
|
|
|
20
20
|
import BpkCard from './src/BpkCard';
|
|
21
|
+
import BpkCardWrapper from './src/BpkCardWrapper';
|
|
21
22
|
import BpkDividedCard, { ORIENTATION } from './src/BpkDividedCard';
|
|
22
23
|
|
|
23
|
-
export { ORIENTATION, BpkDividedCard };
|
|
24
|
+
export { ORIENTATION, BpkDividedCard, BpkCardWrapper };
|
|
24
25
|
|
|
25
26
|
export default BpkCard;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Backpack - Skyscanner's Design System
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2016 Skyscanner Ltd
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/* @flow strict */
|
|
20
|
+
|
|
21
|
+
import PropTypes from 'prop-types';
|
|
22
|
+
import { type Node } from 'react';
|
|
23
|
+
|
|
24
|
+
import { cssModules } from '../../bpk-react-utils';
|
|
25
|
+
|
|
26
|
+
import STYLES from './BpkCardWrapper.module.scss';
|
|
27
|
+
|
|
28
|
+
const getClassName = cssModules(STYLES);
|
|
29
|
+
|
|
30
|
+
type Props = {
|
|
31
|
+
card: Node,
|
|
32
|
+
className: ?string,
|
|
33
|
+
backgroundColor: string,
|
|
34
|
+
header: Node,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const BpkCardWrapper = (props: Props) => {
|
|
38
|
+
const { backgroundColor, card, className, header } = props;
|
|
39
|
+
|
|
40
|
+
const classNames = getClassName('bpk-card-wrapper', className);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div
|
|
44
|
+
className={classNames}
|
|
45
|
+
style={{
|
|
46
|
+
'--background-color': backgroundColor,
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<div className={getClassName('bpk-card-wrapper--header')}>{header}</div>
|
|
50
|
+
<div className={getClassName('bpk-card-wrapper--content')}>{card}</div>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
BpkCardWrapper.propTypes = {
|
|
56
|
+
backgroundColor: PropTypes.string.isRequired,
|
|
57
|
+
card: PropTypes.node.isRequired,
|
|
58
|
+
className: PropTypes.string,
|
|
59
|
+
header: PropTypes.node.isRequired,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
BpkCardWrapper.defaultProps = {
|
|
63
|
+
className: null,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export default BpkCardWrapper;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Backpack - Skyscanner's Design System
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2016 Skyscanner Ltd
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
@import '~bpk-mixins/index.scss';
|
|
20
|
+
|
|
21
|
+
.bpk-card-wrapper {
|
|
22
|
+
@include bpk-card;
|
|
23
|
+
@include bpk-border-lg(var(--background-color), '');
|
|
24
|
+
|
|
25
|
+
&--header {
|
|
26
|
+
border-radius: $bpk-border-radius-sm $bpk-border-radius-sm 0 0;
|
|
27
|
+
background-color: var(--background-color);
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&--content {
|
|
32
|
+
position: relative;
|
|
33
|
+
border-radius: 0 0 $bpk-border-radius-md $bpk-border-radius-md;
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
|
|
36
|
+
&::before,
|
|
37
|
+
&::after {
|
|
38
|
+
position: absolute;
|
|
39
|
+
top: 0;
|
|
40
|
+
content: ' ';
|
|
41
|
+
z-index: 2;
|
|
42
|
+
width: bpk-spacing-lg();
|
|
43
|
+
height: bpk-spacing-lg();
|
|
44
|
+
background-color: transparent;
|
|
45
|
+
box-shadow: bpk-spacing-base() 0 0 0 var(--background-color);
|
|
46
|
+
overflow: hidden;
|
|
47
|
+
|
|
48
|
+
@include bpk-border-radius-md;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&::before {
|
|
52
|
+
left: 0;
|
|
53
|
+
transform: rotate(225deg);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&::after {
|
|
57
|
+
right: 0;
|
|
58
|
+
transform: rotate(-45deg);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -113,11 +113,11 @@ export default () => (
|
|
|
113
113
|
| ---------------------- | --------------------------- | -------- | -------------------- |
|
|
114
114
|
| rows | arrayOf(Object) | true | - |
|
|
115
115
|
| children | arrayOf(BpkDataTableColumn) | true | - |
|
|
116
|
-
| height | number
|
|
117
|
-
| width | number
|
|
118
|
-
| headerHeight | number
|
|
116
|
+
| height | oneOfType(number, string) | true | - |
|
|
117
|
+
| width | oneOfType(number, string) | false | full width of parent |
|
|
118
|
+
| headerHeight | oneOfType(number, string) | false | 60 |
|
|
119
119
|
| rowClassName | string | false | null |
|
|
120
|
-
| rowHeight | number
|
|
120
|
+
| rowHeight | oneOfType(number, string) | false | 60 |
|
|
121
121
|
| rowStyle | object | false | {} |
|
|
122
122
|
| onRowClick | func | false | null |
|
|
123
123
|
| className | string | false | null |
|
|
@@ -193,4 +193,4 @@ function ({
|
|
|
193
193
|
rowData: any,
|
|
194
194
|
rowIndex: any,
|
|
195
195
|
}): node
|
|
196
|
-
```
|
|
196
|
+
```
|
|
@@ -212,10 +212,10 @@ const BpkDataTable = (props: Props) => {
|
|
|
212
212
|
BpkDataTable.propTypes = {
|
|
213
213
|
rows: PropTypes.arrayOf(Object).isRequired,
|
|
214
214
|
children: PropTypes.node.isRequired,
|
|
215
|
-
height: PropTypes.number.isRequired,
|
|
216
|
-
width: PropTypes.number,
|
|
217
|
-
headerHeight: PropTypes.number,
|
|
218
|
-
rowHeight: PropTypes.number,
|
|
215
|
+
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
|
|
216
|
+
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
217
|
+
headerHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
218
|
+
rowHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
219
219
|
className: PropTypes.string,
|
|
220
220
|
defaultColumnSortIndex: PropTypes.number,
|
|
221
221
|
sort: PropTypes.func,
|
|
@@ -20,11 +20,11 @@
|
|
|
20
20
|
|
|
21
21
|
const isDeviceIphone = () =>
|
|
22
22
|
/iPhone/i.test(
|
|
23
|
-
typeof window !== 'undefined' ? window.navigator.
|
|
23
|
+
typeof window !== 'undefined' ? window.navigator.userAgent : '',
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
const isDeviceIpad = () =>
|
|
27
|
-
/iPad/i.test(typeof window !== 'undefined' ? window.navigator.
|
|
27
|
+
/iPad/i.test(typeof window !== 'undefined' ? window.navigator.userAgent : '');
|
|
28
28
|
|
|
29
29
|
const isDeviceIos = () => isDeviceIphone() || isDeviceIpad();
|
|
30
30
|
|