willba-component-library 0.3.5 → 0.3.7

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/README.md +21 -5
  2. package/lib/components/FilterBar/FilterBarTypes.d.ts +13 -7
  3. package/lib/components/FilterBar/components/buttons/select-button/SelectButton.d.ts +1 -0
  4. package/lib/components/FilterBar/components/cards/image-card/ImageCard.d.ts +2 -2
  5. package/lib/components/FilterBar/components/common/FilterSectionHeader.d.ts +8 -0
  6. package/lib/components/FilterBar/components/dates/Dates.d.ts +16 -0
  7. package/lib/components/FilterBar/components/dates/index.d.ts +1 -0
  8. package/lib/components/FilterBar/components/guests/Guests.d.ts +1 -0
  9. package/lib/components/FilterBar/utils/getLocalizedContent.d.ts +8 -0
  10. package/lib/components/FilterBar/utils/index.d.ts +1 -0
  11. package/lib/index.d.ts +13 -7
  12. package/lib/index.esm.js +93 -45
  13. package/lib/index.esm.js.map +1 -1
  14. package/lib/index.js +93 -45
  15. package/lib/index.js.map +1 -1
  16. package/lib/index.umd.js +93 -45
  17. package/lib/index.umd.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/components/FilterBar/FilterBar.css +1 -1
  20. package/src/components/FilterBar/FilterBar.stories.tsx +43 -34
  21. package/src/components/FilterBar/FilterBar.tsx +21 -13
  22. package/src/components/FilterBar/FilterBarTypes.ts +15 -7
  23. package/src/components/FilterBar/components/buttons/select-button/SelectButton.css +13 -13
  24. package/src/components/FilterBar/components/buttons/select-button/SelectButton.tsx +6 -3
  25. package/src/components/FilterBar/components/cards/image-card/ImageCard.tsx +2 -2
  26. package/src/components/FilterBar/components/categories/Categories.tsx +1 -0
  27. package/src/components/FilterBar/components/common/FilterSectionHeader.css +29 -0
  28. package/src/components/FilterBar/components/common/FilterSectionHeader.tsx +16 -0
  29. package/src/components/FilterBar/components/dates/Dates.tsx +59 -0
  30. package/src/components/FilterBar/components/dates/index.ts +1 -0
  31. package/src/components/FilterBar/components/guests/GuestCount/GuestCount.css +4 -7
  32. package/src/components/FilterBar/components/guests/Guests.css +5 -20
  33. package/src/components/FilterBar/components/guests/Guests.tsx +8 -2
  34. package/src/components/FilterBar/components/locations/Locations.css +1 -15
  35. package/src/components/FilterBar/components/locations/Locations.tsx +43 -14
  36. package/src/components/FilterBar/utils/getLocalizedContent.tsx +21 -0
  37. package/src/components/FilterBar/utils/index.tsx +1 -0
  38. package/src/components/FilterBar/utils/parseLocations.tsx +5 -1
  39. package/src/core/components/calendar/Calendar.css +100 -50
  40. package/src/locales/en/filterBar.json +1 -1
  41. package/src/locales/fi/filterBar.json +2 -2
@@ -4,6 +4,9 @@ import { useTranslation } from 'react-i18next'
4
4
  import './Locations.css'
5
5
  import { ImageCard } from '../cards/image-card/ImageCard'
6
6
  import { Location } from '../../FilterBarTypes'
7
+ import { FilterSectionHeader } from '../common/FilterSectionHeader'
8
+ import { CloseButton } from '../../../../core/components'
9
+ import { getLocalizedContent } from '../../utils'
7
10
 
8
11
  type Props = {
9
12
  locations?: Location[]
@@ -40,7 +43,9 @@ export const Locations = forwardRef<HTMLDivElement, Props>(
40
43
  const handleLocationClick = (location: Location) => {
41
44
  if (multiSelect) {
42
45
  // Multi-select: toggle location in array
43
- const isSelected = selectedLocations.some((loc) => loc.id === location.id)
46
+ const isSelected = selectedLocations.some(
47
+ (loc) => loc.id === location.id
48
+ )
44
49
 
45
50
  if (isSelected) {
46
51
  // Remove location if already selected
@@ -60,23 +65,47 @@ export const Locations = forwardRef<HTMLDivElement, Props>(
60
65
 
61
66
  return (
62
67
  <div className="will-filter-bar-locations" ref={ref}>
63
- <h3 className="will-locations-filter-title">{t('locations.title')}</h3>
68
+ <FilterSectionHeader
69
+ title={t('locations.title')}
70
+ action={onClose && <CloseButton handleClose={onClose} />}
71
+ />
64
72
 
65
73
  <div className="will-locations-filter-container">
66
74
  {!!(locations?.length && language) &&
67
75
  locations
68
- .filter((location) => location?.label?.[language])
69
- .map((location, index) => (
70
- <ImageCard
71
- key={location.id}
72
- ref={index === 0 ? firstCardRef : null}
73
- title={location.label[language]}
74
- description={location.description?.[language]}
75
- imageUrl={location.imageUrl}
76
- isSelected={selectedLocations.some((loc) => loc.id === location.id)}
77
- onClick={() => handleLocationClick(location)}
78
- />
79
- ))}
76
+ .filter((location) => {
77
+ const label = getLocalizedContent({
78
+ contents: location.label,
79
+ locale: language,
80
+ })
81
+ return !!label
82
+ })
83
+ .map((location, index) => {
84
+ const label = getLocalizedContent({
85
+ contents: location.label,
86
+ locale: language,
87
+ })
88
+ const description = location.description
89
+ ? getLocalizedContent({
90
+ contents: location.description,
91
+ locale: language,
92
+ })
93
+ : null
94
+
95
+ return (
96
+ <ImageCard
97
+ key={location.id}
98
+ ref={index === 0 ? firstCardRef : null}
99
+ title={label}
100
+ description={description}
101
+ imageUrl={location.imageUrl}
102
+ isSelected={selectedLocations.some(
103
+ (loc) => loc.id === location.id
104
+ )}
105
+ onClick={() => handleLocationClick(location)}
106
+ />
107
+ )
108
+ })}
80
109
  </div>
81
110
  </div>
82
111
  )
@@ -0,0 +1,21 @@
1
+ import { LocaleTranslation } from '../FilterBarTypes'
2
+
3
+ type Props = {
4
+ contents: LocaleTranslation
5
+ locale: string
6
+ fallbackLocale?: string
7
+ }
8
+
9
+ export const getLocalizedContent = ({
10
+ contents,
11
+ locale,
12
+ fallbackLocale = 'en',
13
+ }: Props): string | undefined => {
14
+ const preferred = contents.find((content) => content.locale === locale)
15
+ if (preferred) return preferred.content
16
+
17
+ const fallback = contents.find((content) => content.locale === fallbackLocale)
18
+ if (fallback) return fallback.content
19
+
20
+ return contents[0]?.content
21
+ }
@@ -1,2 +1,3 @@
1
1
  export { parseGuests } from './parseGuests'
2
2
  export { parseLocations } from './parseLocations'
3
+ export { getLocalizedContent } from './getLocalizedContent'
@@ -1,4 +1,5 @@
1
1
  import { Location } from '../FilterBarTypes'
2
+ import { getLocalizedContent } from './getLocalizedContent'
2
3
 
3
4
  type Props = {
4
5
  selectedLocations: Location[]
@@ -18,7 +19,10 @@ export const parseLocations = ({
18
19
  }
19
20
 
20
21
  if (selectedLocations.length === 1) {
21
- const translation = selectedLocations[0]?.label?.[language]
22
+ const translation = getLocalizedContent({
23
+ contents: selectedLocations[0].label,
24
+ locale: language,
25
+ })
22
26
  if (!translation) {
23
27
  return locationsPlaceholder
24
28
  }
@@ -5,6 +5,9 @@
5
5
  }
6
6
 
7
7
  /* Calendar overrides */
8
+ .will-calendar-filter-container .rdp {
9
+ margin: 0;
10
+ }
8
11
 
9
12
  .will-calendar-filter-container .DayPicker {
10
13
  font-size: 25px;
@@ -31,14 +34,13 @@
31
34
  color: var(--will-primary);
32
35
  }
33
36
 
34
-
35
37
  .will-calendar-filter-container .rdp-month .rdp-caption {
36
38
  position: initial;
37
39
  }
38
40
 
39
41
  .will-calendar-filter-container .rdp-month .rdp-caption > .rdp-caption_label,
40
42
  .will-calendar-filter-container .rdp-table .rdp-head {
41
- opacity: .6;
43
+ opacity: 0.6;
42
44
  }
43
45
 
44
46
  .will-calendar-filter-container .rdp-table {
@@ -46,13 +48,14 @@
46
48
  border-spacing: 0px 2px;
47
49
  }
48
50
 
49
- .will-calendar-filter-container .rdp-button_reset.rdp-button.rdp-day.rdp-day_selected {
51
+ .will-calendar-filter-container
52
+ .rdp-button_reset.rdp-button.rdp-day.rdp-day_selected {
50
53
  background-color: var(--will-primary);
51
54
  opacity: 1;
52
- color: var(--will-white)
55
+ color: var(--will-white);
53
56
  }
54
57
 
55
- .will-calendar-filter-container .my-today:not(.rdp-day_selected) {
58
+ .will-calendar-filter-container .my-today:not(.rdp-day_selected) {
56
59
  font-weight: 700;
57
60
  opacity: 1;
58
61
  color: var(--will-primary);
@@ -66,14 +69,14 @@
66
69
  font-weight: 500;
67
70
  }
68
71
 
69
- .will-calendar-filter-container .rdp-cell button.booked {
72
+ .will-calendar-filter-container .rdp-cell button.booked {
70
73
  font-weight: 400;
71
74
  cursor: not-allowed;
72
75
  }
73
76
 
74
77
  .will-calendar-filter-container .rdp-cell .rdp-button[disabled] {
75
78
  color: var(--will-transparent-black);
76
- opacity: 1
79
+ opacity: 1;
77
80
  }
78
81
 
79
82
  @media (max-width: 960px) {
@@ -85,7 +88,7 @@
85
88
  .will-calendar-filter-container .rdp-month.rdp-caption_start {
86
89
  padding-left: 10px;
87
90
  }
88
-
91
+
89
92
  .will-calendar-filter-container .rdp-month.rdp-caption_end {
90
93
  padding-right: 10px;
91
94
  }
@@ -94,22 +97,40 @@
94
97
  /* Tooltips */
95
98
  .will-root .will-calendar-filter-container .will-calendar-tooltip,
96
99
  .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out,
97
- .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date,
98
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out-only,
99
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-in-only {
100
- position: absolute;
101
- top: -42px;
102
- transform: translateX(calc(-50% + 20px));
103
- display: none;
104
- white-space: nowrap;
105
- z-index: 2;
100
+ .will-root
101
+ .will-calendar-filter-container
102
+ .will-calendar-tooltip-overlapping-date,
103
+ .will-root
104
+ .will-calendar-filter-container
105
+ .will-calendar-tooltip-check-out-only,
106
+ .will-root
107
+ .will-calendar-filter-container
108
+ .will-calendar-tooltip-check-in-only {
109
+ position: absolute;
110
+ top: -42px;
111
+ transform: translateX(calc(-50% + 20px));
112
+ display: none;
113
+ white-space: nowrap;
114
+ z-index: 2;
106
115
  }
107
116
 
108
117
  .will-root .will-calendar-filter-container .will-calendar-tooltip > div,
109
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out > div,
110
- .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date > div,
111
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out-only > div,
112
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-in-only > div {
118
+ .will-root
119
+ .will-calendar-filter-container
120
+ .will-calendar-tooltip-check-out
121
+ > div,
122
+ .will-root
123
+ .will-calendar-filter-container
124
+ .will-calendar-tooltip-overlapping-date
125
+ > div,
126
+ .will-root
127
+ .will-calendar-filter-container
128
+ .will-calendar-tooltip-check-out-only
129
+ > div,
130
+ .will-root
131
+ .will-calendar-filter-container
132
+ .will-calendar-tooltip-check-in-only
133
+ > div {
113
134
  background-color: white;
114
135
  position: relative;
115
136
  padding: 5px 10px;
@@ -118,27 +139,50 @@
118
139
  }
119
140
 
120
141
  .will-root .will-calendar-filter-container .will-calendar-tooltip::before,
121
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out::before,
122
- .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date::before,
123
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out-only::before,
124
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-in-only::before {
125
- content: "";
142
+ .will-root
143
+ .will-calendar-filter-container
144
+ .will-calendar-tooltip-check-out::before,
145
+ .will-root
146
+ .will-calendar-filter-container
147
+ .will-calendar-tooltip-overlapping-date::before,
148
+ .will-root
149
+ .will-calendar-filter-container
150
+ .will-calendar-tooltip-check-out-only::before,
151
+ .will-root
152
+ .will-calendar-filter-container
153
+ .will-calendar-tooltip-check-in-only::before {
154
+ content: '';
126
155
  width: 10px;
127
156
  height: 10px;
128
157
  border: 1px solid var(--will-primary);
129
158
  position: absolute;
130
159
  bottom: -4px;
131
- left:calc(50% - 5.555px);
160
+ left: calc(50% - 5.555px);
132
161
  rotate: 45deg;
133
162
  z-index: 0;
134
163
  background-color: var(--will-white);
135
164
  }
136
165
 
137
- .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip,
138
- .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-check-out,
139
- .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-overlapping-date,
140
- .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-check-out-only,
141
- .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-check-in-only {
166
+ .will-root
167
+ .will-calendar-filter-container
168
+ .rdp-cell:hover
169
+ .will-calendar-tooltip,
170
+ .will-root
171
+ .will-calendar-filter-container
172
+ .rdp-cell:hover
173
+ .will-calendar-tooltip-check-out,
174
+ .will-root
175
+ .will-calendar-filter-container
176
+ .rdp-cell:hover
177
+ .will-calendar-tooltip-overlapping-date,
178
+ .will-root
179
+ .will-calendar-filter-container
180
+ .rdp-cell:hover
181
+ .will-calendar-tooltip-check-out-only,
182
+ .will-root
183
+ .will-calendar-filter-container
184
+ .rdp-cell:hover
185
+ .will-calendar-tooltip-check-in-only {
142
186
  display: block;
143
187
  }
144
188
 
@@ -150,8 +194,8 @@
150
194
 
151
195
  .will-root .will-calendar-filter-container .will-calendar-spinner {
152
196
  position: absolute;
153
- top:0;
154
- bottom:0;
197
+ top: 0;
198
+ bottom: 0;
155
199
  left: 0;
156
200
  right: 0;
157
201
  background-color: var(--will-white-transparent);
@@ -166,14 +210,14 @@
166
210
 
167
211
  .will-root .will-calendar-filter-container .no-active-selection-start,
168
212
  .will-root .will-calendar-filter-container .no-active-selection-mid,
169
- .will-root .will-calendar-filter-container .no-active-selection-end {
213
+ .will-root .will-calendar-filter-container .no-active-selection-end {
170
214
  position: initial;
171
215
  }
172
216
 
173
217
  .will-root .will-calendar-filter-container .no-active-selection-start::before,
174
218
  .will-root .will-calendar-filter-container .no-active-selection-mid::before,
175
- .will-root .will-calendar-filter-container .no-active-selection-end::before {
176
- content: "";
219
+ .will-root .will-calendar-filter-container .no-active-selection-end::before {
220
+ content: '';
177
221
  position: absolute;
178
222
  width: 100%;
179
223
  height: 100%;
@@ -198,7 +242,9 @@
198
242
  border-bottom-right-radius: 50%;
199
243
  }
200
244
 
201
- .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_middle.checkout-option {
245
+ .will-root
246
+ .will-calendar-filter-container
247
+ .rdp-day_selected.rdp-day_range_middle.checkout-option {
202
248
  background-color: var(--will-primary-lightest);
203
249
  color: inherit;
204
250
  }
@@ -215,16 +261,20 @@
215
261
  }
216
262
 
217
263
  @media (max-width: 600px) {
218
- /* Tooltips */
219
- .will-root .will-calendar-filter-container .will-calendar-tooltip,
220
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out,
221
- .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date,
222
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out-only,
223
- .will-root .will-calendar-filter-container .will-calendar-tooltip-check-in-only {
224
- top: -70px;
225
- white-space: wrap;
226
- max-width: 120px;
227
- }
264
+ /* Tooltips */
265
+ .will-root .will-calendar-filter-container .will-calendar-tooltip,
266
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out,
267
+ .will-root
268
+ .will-calendar-filter-container
269
+ .will-calendar-tooltip-overlapping-date,
270
+ .will-root
271
+ .will-calendar-filter-container
272
+ .will-calendar-tooltip-check-out-only,
273
+ .will-root
274
+ .will-calendar-filter-container
275
+ .will-calendar-tooltip-check-in-only {
276
+ top: -70px;
277
+ white-space: wrap;
278
+ max-width: 120px;
279
+ }
228
280
  }
229
-
230
-
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "locations": {
3
3
  "label": "Locations",
4
- "title": "Where to?",
4
+ "title": "Select location",
5
5
  "placeholder": "Add location",
6
6
  "selected": "locations"
7
7
  },
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "locations": {
3
3
  "label": "Sijainnit",
4
- "title": "Minne?",
4
+ "title": "Valitse sijainti",
5
5
  "placeholder": "Lisää sijainti",
6
- "selected": "sijaintia"
6
+ "selected": "sijainnit"
7
7
  },
8
8
  "calendar": {
9
9
  "label": "Päivät",