@autobusal/routes-order 1.11.1 → 1.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Checkout/Sidebar/styles.ts +11 -3
- package/Found/Found.tsx +7 -2
- package/RoutesOrder.tsx +38 -14
- package/Step5/Coupons/Coupons.tsx +23 -17
- package/Step5/Coupons/styles.ts +40 -14
- package/Step5/Payments/Payments.tsx +2 -2
- package/Step5/Payments/styles.ts +15 -9
- package/Step5/Summary/About/About.tsx +12 -6
- package/Step5/Summary/About/styles.ts +12 -5
- package/package.json +1 -1
- package/styles.ts +66 -2
|
@@ -11,10 +11,18 @@ import styled from 'styled-components';
|
|
|
11
11
|
export const Container = styled.aside`
|
|
12
12
|
min-width: 0;
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
16
|
+
*
|
|
17
|
+
* 5/12 of the row rather than a fixed 340px, so on a wide screen the
|
|
18
|
+
* summary grows with the page instead of staying a narrow strip beside a
|
|
19
|
+
* very wide form. A proportion also keeps the payment options on one
|
|
20
|
+
* line at every width above the breakpoint.
|
|
21
|
+
*
|
|
22
|
+
* 1280 matches Results in ../../styles.ts, where the row layout starts.
|
|
23
|
+
*/
|
|
16
24
|
@media (min-width: 1280px) {
|
|
17
|
-
flex: 0 0
|
|
25
|
+
flex: 0 0 calc((5 / 12) * 100% - 20px);
|
|
18
26
|
position: sticky;
|
|
19
27
|
top: 15px;
|
|
20
28
|
max-height: calc(100vh - 30px);
|
package/Found/Found.tsx
CHANGED
|
@@ -2,7 +2,6 @@ import { useMemo, useState } from 'react';
|
|
|
2
2
|
import { useSearchParams } from 'react-router-dom';
|
|
3
3
|
import { TFunction } from 'i18next';
|
|
4
4
|
import Dates from './Dates/Dates';
|
|
5
|
-
import Booking from './Booking/Booking';
|
|
6
5
|
import Header from './Header/Header';
|
|
7
6
|
import Orders from './Orders/Orders';
|
|
8
7
|
import Sort from './Sort/Sort';
|
|
@@ -90,7 +89,13 @@ const Found = ({ type, loading, data, step1, preferredStop, t, onSearch, onSave
|
|
|
90
89
|
<>
|
|
91
90
|
<Dates type={ type } step1={ step1 } t={ t } onSearch={ onSearch } />
|
|
92
91
|
|
|
93
|
-
{
|
|
92
|
+
{ /* Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
93
|
+
The Booking.com banner is gone from the results. It sat between
|
|
94
|
+
the date strip and the trips, pushing the actual results below
|
|
95
|
+
it and advertising a hotel to somebody still deciding whether
|
|
96
|
+
they can travel at all. The component is kept, unused, so the
|
|
97
|
+
affiliate placement can be reinstated somewhere it does not
|
|
98
|
+
interrupt the search. */ }
|
|
94
99
|
|
|
95
100
|
{ showControls && (
|
|
96
101
|
<>
|
package/RoutesOrder.tsx
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { useParams } from 'react-router-dom';
|
|
3
3
|
import { TFunction } from 'i18next';
|
|
4
|
+
import { AiOutlineSearch, AiOutlineCaretDown, AiOutlineCaretUp } from 'react-icons/ai';
|
|
4
5
|
import { Meta } from '@autobusal/common';
|
|
6
|
+
import { useSystemTheme } from '@autobusal/hooks';
|
|
7
|
+
import { useGetSettings } from '@autobusal/providers/services';
|
|
5
8
|
import RoutesSearch from '@autobusal/routes-search';
|
|
6
9
|
import { useGetSuggestions } from '@autobusal/routes-search/services';
|
|
7
|
-
import { SearchAgain } from './styles';
|
|
10
|
+
import { SearchAgain, SearchInner, SearchToggle, SearchSummary, SearchPanel } from './styles';
|
|
8
11
|
import Step1 from './Step1/Step1';
|
|
9
12
|
import Step2 from './Step2';
|
|
10
13
|
import Step3 from './Step3';
|
|
@@ -31,6 +34,12 @@ const RoutesOrder = ({ t }: Props): JSX.Element => {
|
|
|
31
34
|
// search form (no :from/:to params yet) or if a slug doesn't resolve.
|
|
32
35
|
const { data: cities } = useGetSuggestions();
|
|
33
36
|
|
|
37
|
+
const { data: settings } = useGetSettings();
|
|
38
|
+
|
|
39
|
+
// same artwork the homepage hero uses, so the results page reads as the
|
|
40
|
+
// same site rather than a bare form on a white band
|
|
41
|
+
const mode = useSystemTheme();
|
|
42
|
+
|
|
34
43
|
const fromCity = cities.find(city => city.slug === params.from);
|
|
35
44
|
const toCity = cities.find(city => city.slug === params.to);
|
|
36
45
|
|
|
@@ -42,6 +51,7 @@ const RoutesOrder = ({ t }: Props): JSX.Element => {
|
|
|
42
51
|
? t('routes_order.meta.description_pair', { from: fromCity.name, to: toCity.name })
|
|
43
52
|
: t('routes_order.meta.description');
|
|
44
53
|
|
|
54
|
+
const [ searchOpen, setSearchOpen ] = useState<boolean>(false);
|
|
45
55
|
const [ redirected, setRedirected ] = useState<boolean>(false);
|
|
46
56
|
const [ current, setCurrent ] = useState<number>(1);
|
|
47
57
|
const [ step1, setStep1 ] = useState<RoutesSearchForm | undefined>(undefined);
|
|
@@ -114,19 +124,33 @@ const RoutesOrder = ({ t }: Props): JSX.Element => {
|
|
|
114
124
|
return (
|
|
115
125
|
<Meta title={ title } description={ description }>
|
|
116
126
|
{ showSearchAgain && step1 !== undefined && (
|
|
117
|
-
<SearchAgain
|
|
118
|
-
<
|
|
119
|
-
type={
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
<SearchAgain $background={ `${ settings.url }/home/background-${ mode }.jpg` }>
|
|
128
|
+
<SearchInner>
|
|
129
|
+
<SearchToggle type="button" aria-expanded={ searchOpen } onClick={ () => setSearchOpen(!searchOpen) }>
|
|
130
|
+
<AiOutlineSearch />
|
|
131
|
+
|
|
132
|
+
<SearchSummary>
|
|
133
|
+
{ fromCity?.name ?? step1.from } → { toCity?.name ?? step1.to } · { step1.departure }
|
|
134
|
+
</SearchSummary>
|
|
135
|
+
|
|
136
|
+
{ searchOpen ? <AiOutlineCaretUp /> : <AiOutlineCaretDown /> }
|
|
137
|
+
</SearchToggle>
|
|
138
|
+
|
|
139
|
+
<SearchPanel $open={ searchOpen }>
|
|
140
|
+
<RoutesSearch
|
|
141
|
+
type={ step1.type ?? 'departure' }
|
|
142
|
+
from={ `${ step1.from }${ step1.stop_from ? `:${ step1.stop_from }` : '' }` }
|
|
143
|
+
to={ `${ step1.to }${ step1.stop_to ? `:${ step1.stop_to }` : '' }` }
|
|
144
|
+
departure={ step1.departure }
|
|
145
|
+
_return={ step1._return ?? '' }
|
|
146
|
+
adultsNo={ step1.adults }
|
|
147
|
+
childrenNo={ step1.children }
|
|
148
|
+
babiesNo={ step1.babies }
|
|
149
|
+
t={ t }
|
|
150
|
+
onSearch={ data => { setSearchOpen(false); onStep1(data); } }
|
|
151
|
+
/>
|
|
152
|
+
</SearchPanel>
|
|
153
|
+
</SearchInner>
|
|
130
154
|
</SearchAgain>
|
|
131
155
|
) }
|
|
132
156
|
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { TFunction } from 'i18next';
|
|
2
2
|
import { useForm } from 'react-hook-form';
|
|
3
3
|
import { RiCoupon3Line } from 'react-icons/ri';
|
|
4
|
-
import { Button } from '@autobusal/common';
|
|
5
4
|
import { Validate, Display } from '@autobusal/utilities';
|
|
6
|
-
import {
|
|
7
|
-
import { Container, ContainerForm, ContainerInput } from './styles';
|
|
5
|
+
import { Container, ContainerForm, ContainerInput, Apply } from './styles';
|
|
8
6
|
import { CouponData } from '@autobusal/providers/types/orders';
|
|
9
7
|
import { FoundData } from '@autobusal/providers/types/routes';
|
|
10
8
|
import { TotalData, CouponForm } from '../../types';
|
|
@@ -46,27 +44,35 @@ const Coupons = ({ current, step2, t, total, onApplied }: Props): (JSX.Element |
|
|
|
46
44
|
return null;
|
|
47
45
|
}
|
|
48
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
49
|
+
*
|
|
50
|
+
* One field with the apply control tucked inside it. In the checkout
|
|
51
|
+
* sidebar this used to be a card of its own, with a heading and a
|
|
52
|
+
* full-width button, taking more room than the totals it exists to
|
|
53
|
+
* change - for something most buyers do not have.
|
|
54
|
+
*
|
|
55
|
+
* The button keeps its accessible name via aria-label and title, so
|
|
56
|
+
* dropping the visible text costs a screen reader nothing.
|
|
57
|
+
*/
|
|
49
58
|
return (
|
|
50
|
-
<Container
|
|
51
|
-
<SubTitle>
|
|
52
|
-
<RiCoupon3Line />
|
|
53
|
-
{ t('routes_order.step5.coupon.title') }
|
|
54
|
-
</SubTitle>
|
|
55
|
-
|
|
59
|
+
<Container>
|
|
56
60
|
<form onSubmit={ handleSubmit(onSubmit) }>
|
|
57
61
|
<ContainerForm>
|
|
58
62
|
<ContainerInput>
|
|
59
63
|
<input type="text" placeholder={ t('routes_order.step5.coupon.code') } { ...register('code', Validate('required|min_length:4', t)) } />
|
|
60
|
-
|
|
64
|
+
|
|
65
|
+
<Apply
|
|
66
|
+
type="submit"
|
|
67
|
+
disabled={ isPending }
|
|
68
|
+
aria-label={ t('routes_order.step5.coupon.apply') }
|
|
69
|
+
title={ t('routes_order.step5.coupon.apply') }
|
|
70
|
+
>
|
|
71
|
+
<RiCoupon3Line />
|
|
72
|
+
</Apply>
|
|
61
73
|
</ContainerInput>
|
|
62
74
|
|
|
63
|
-
|
|
64
|
-
type="submit"
|
|
65
|
-
loading={ isPending }
|
|
66
|
-
text={ t('routes_order.step5.coupon.apply') }
|
|
67
|
-
noMargin
|
|
68
|
-
maxWidth={ 175 }
|
|
69
|
-
/>
|
|
75
|
+
{ Display(errors.code) }
|
|
70
76
|
</ContainerForm>
|
|
71
77
|
</form>
|
|
72
78
|
</Container>
|
package/Step5/Coupons/styles.ts
CHANGED
|
@@ -4,24 +4,50 @@ export const Container = styled.div`
|
|
|
4
4
|
margin-top: 0;
|
|
5
5
|
`;
|
|
6
6
|
|
|
7
|
+
export const ContainerForm = styled.div`
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
gap: 4px;
|
|
11
|
+
`;
|
|
12
|
+
|
|
7
13
|
/**
|
|
8
14
|
* Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
9
15
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* in a column too narrow for either - the input came out 86px wide.
|
|
14
|
-
*
|
|
15
|
-
* flex-basis plus wrap is container-responsive without container queries:
|
|
16
|
-
* they sit side by side where there is room and stack where there is not.
|
|
16
|
+
* The apply control sits INSIDE the field rather than beside it. Beside it
|
|
17
|
+
* in a narrow sidebar, the two either fought for width or stacked into two
|
|
18
|
+
* full-width rows for something most buyers never use.
|
|
17
19
|
*/
|
|
18
|
-
export const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
export const ContainerInput = styled.div`
|
|
21
|
+
position: relative;
|
|
22
|
+
|
|
23
|
+
& > input {
|
|
24
|
+
width: 100%;
|
|
25
|
+
padding-right: 42px;
|
|
26
|
+
}
|
|
23
27
|
`;
|
|
24
28
|
|
|
25
|
-
export const
|
|
26
|
-
|
|
29
|
+
export const Apply = styled.button`
|
|
30
|
+
position: absolute;
|
|
31
|
+
top: 50%;
|
|
32
|
+
right: 6px;
|
|
33
|
+
transform: translateY(-50%);
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
justify-content: center;
|
|
37
|
+
width: 30px;
|
|
38
|
+
height: 30px;
|
|
39
|
+
font-size: ${ props => props.theme.size.l };
|
|
40
|
+
color: ${ props => props.theme.primary.contrast };
|
|
41
|
+
background: ${ props => props.theme.primary.normal };
|
|
42
|
+
border-radius: ${ props => props.theme.borderRadius };
|
|
43
|
+
transition: all 0.2s ease;
|
|
44
|
+
|
|
45
|
+
&:hover {
|
|
46
|
+
opacity: .85;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
&:disabled {
|
|
50
|
+
opacity: .5;
|
|
51
|
+
cursor: default;
|
|
52
|
+
}
|
|
27
53
|
`;
|
|
@@ -31,7 +31,7 @@ const Payments = ({ selected, isPartner, t, onChange }: Props): JSX.Element => {
|
|
|
31
31
|
|
|
32
32
|
if (isLoading) {
|
|
33
33
|
return (
|
|
34
|
-
<Container
|
|
34
|
+
<Container>
|
|
35
35
|
<Inline text={ t('routes_order.step5.actions.loading') } />
|
|
36
36
|
</Container>
|
|
37
37
|
);
|
|
@@ -39,7 +39,7 @@ const Payments = ({ selected, isPartner, t, onChange }: Props): JSX.Element => {
|
|
|
39
39
|
|
|
40
40
|
return (
|
|
41
41
|
<>
|
|
42
|
-
<Container
|
|
42
|
+
<Container>
|
|
43
43
|
<SubTitle>
|
|
44
44
|
<RiSecurePaymentLine />
|
|
45
45
|
{ t('routes_order.step5.actions.title') }
|
package/Step5/Payments/styles.ts
CHANGED
|
@@ -4,11 +4,17 @@ export const Container = styled.div`
|
|
|
4
4
|
margin-top: 0;
|
|
5
5
|
`;
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
9
|
+
*
|
|
10
|
+
* All options on one row inside the checkout sidebar. They are a choice of
|
|
11
|
+
* three short labels, not three products, so stacking them into tall cards
|
|
12
|
+
* gave a minor decision more visual weight than the total above it.
|
|
13
|
+
*/
|
|
7
14
|
export const ContainerPayments = styled.div`
|
|
8
15
|
display: flex;
|
|
9
16
|
flex-direction: row;
|
|
10
|
-
|
|
11
|
-
gap: 10px;
|
|
17
|
+
gap: 6px;
|
|
12
18
|
justify-content: center;
|
|
13
19
|
`;
|
|
14
20
|
|
|
@@ -17,12 +23,12 @@ export const ButtonPayment = styled.button<{ $selected: boolean }>`
|
|
|
17
23
|
flex-direction: column;
|
|
18
24
|
align-items: center;
|
|
19
25
|
justify-content: center;
|
|
20
|
-
gap:
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
padding:
|
|
26
|
+
gap: 4px;
|
|
27
|
+
// equal shares of one row, never wrapping - min-width:0 lets them shrink
|
|
28
|
+
// below their label width instead of pushing each other onto new lines
|
|
29
|
+
flex: 1 1 0;
|
|
30
|
+
min-width: 0;
|
|
31
|
+
padding: 8px 4px;
|
|
26
32
|
text-align: center;
|
|
27
33
|
font-weight: 700;
|
|
28
34
|
border: 1px solid ${ props => props.theme.background.neutral };
|
|
@@ -30,7 +36,7 @@ export const ButtonPayment = styled.button<{ $selected: boolean }>`
|
|
|
30
36
|
transition: all 0.3s ease;
|
|
31
37
|
|
|
32
38
|
& > svg {
|
|
33
|
-
font-size:
|
|
39
|
+
font-size: 22px;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
&:hover {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TFunction } from 'i18next';
|
|
2
2
|
import { FaArrowLeft, FaArrowRight } from 'react-icons/fa';
|
|
3
3
|
import { FaCircleDot, FaLocationDot } from 'react-icons/fa6';
|
|
4
|
-
import { Container, ContainerIcon, Icon, Information, Title, Operator, Logo, Leg, Point, PointIcon, PointCity, Country, PointMeta } from './styles';
|
|
4
|
+
import { Container, ContainerIcon, Icon, Information, Title, Operator, Carrier, Logo, Leg, Point, PointIcon, PointCity, Country, PointMeta } from './styles';
|
|
5
5
|
import { RoutesSearchForm } from '@autobusal/routes-search/types';
|
|
6
6
|
import { FoundData } from '@autobusal/providers/types/routes';
|
|
7
7
|
|
|
@@ -44,9 +44,17 @@ const About = ({ type, step1, data, t }: Props): (JSX.Element | null) => {
|
|
|
44
44
|
<Information>
|
|
45
45
|
<Title>{ data.name } ({ data.code })</Title>
|
|
46
46
|
|
|
47
|
-
{
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
{ /* Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
48
|
+
Mark and name together, ranged right. The name used to sit
|
|
49
|
+
alone at the foot of the block, so the logo read as decoration
|
|
50
|
+
rather than as the operator being identified. */ }
|
|
51
|
+
<Carrier>
|
|
52
|
+
{ data.operator.logo_url && (
|
|
53
|
+
<Logo src={ data.operator.logo_url } alt={ data.operator.company } />
|
|
54
|
+
) }
|
|
55
|
+
|
|
56
|
+
<Operator>{ data.operator.company }</Operator>
|
|
57
|
+
</Carrier>
|
|
50
58
|
|
|
51
59
|
<Leg>
|
|
52
60
|
<Point>
|
|
@@ -88,8 +96,6 @@ const About = ({ type, step1, data, t }: Props): (JSX.Element | null) => {
|
|
|
88
96
|
</PointMeta>
|
|
89
97
|
</Point>
|
|
90
98
|
</Leg>
|
|
91
|
-
|
|
92
|
-
<Operator>{ data.operator.company }</Operator>
|
|
93
99
|
</Information>
|
|
94
100
|
</Container>
|
|
95
101
|
);
|
|
@@ -114,17 +114,24 @@ export const PointMeta = styled.div<{ $strong?: boolean }>`
|
|
|
114
114
|
// Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
115
115
|
// The operator's mark under the route name - who the buyer is actually
|
|
116
116
|
// travelling with, which a company name alone conveys less quickly.
|
|
117
|
+
export const Carrier = styled.div`
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
justify-content: flex-end;
|
|
121
|
+
gap: 8px;
|
|
122
|
+
margin: 6px 0;
|
|
123
|
+
`;
|
|
124
|
+
|
|
117
125
|
export const Logo = styled.img`
|
|
118
126
|
display: block;
|
|
119
|
-
max-width:
|
|
120
|
-
max-height:
|
|
127
|
+
max-width: 90px;
|
|
128
|
+
max-height: 30px;
|
|
121
129
|
object-fit: contain;
|
|
122
|
-
object-position: left;
|
|
123
|
-
margin: 6px 0;
|
|
124
130
|
`;
|
|
125
131
|
|
|
126
132
|
export const Operator = styled.div`
|
|
127
|
-
padding-left: 10px;
|
|
128
133
|
font-size: calc(${ props => props.theme.size.s } - 1px);
|
|
134
|
+
font-weight: 700;
|
|
135
|
+
text-align: right;
|
|
129
136
|
color: ${ props => props.theme.font.faded };
|
|
130
137
|
`;
|
package/package.json
CHANGED
package/styles.ts
CHANGED
|
@@ -32,8 +32,72 @@ export const Actions = styled.div`
|
|
|
32
32
|
* your place. The form stays available above the results so an adjustment
|
|
33
33
|
* is one edit rather than a round trip.
|
|
34
34
|
*/
|
|
35
|
-
export const SearchAgain = styled.div
|
|
36
|
-
|
|
35
|
+
export const SearchAgain = styled.div<{ $background: string }>`
|
|
36
|
+
position: relative;
|
|
37
|
+
margin: -35px calc(50% - 50vw) 20px;
|
|
38
|
+
padding: 18px calc(50vw - 50%);
|
|
39
|
+
background-image: url('${ props => props.$background }');
|
|
40
|
+
background-size: cover;
|
|
41
|
+
background-repeat: no-repeat;
|
|
42
|
+
background-position: center;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Same scrim as the homepage hero, for the same reason: the artwork a
|
|
46
|
+
* brand supplies may be light or dark, and the controls on top of it must
|
|
47
|
+
* read either way.
|
|
48
|
+
*/
|
|
49
|
+
&::before {
|
|
50
|
+
content: '';
|
|
51
|
+
position: absolute;
|
|
52
|
+
inset: 0;
|
|
53
|
+
pointer-events: none;
|
|
54
|
+
background: rgba(0, 0, 0, .45);
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
|
|
58
|
+
export const SearchInner = styled.div`
|
|
59
|
+
position: relative;
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
export const SearchToggle = styled.button`
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 8px;
|
|
66
|
+
padding: 6px 14px;
|
|
67
|
+
font-size: ${ props => props.theme.size.s };
|
|
68
|
+
font-weight: 700;
|
|
69
|
+
color: #FFF;
|
|
70
|
+
border: 1px solid rgba(255, 255, 255, .45);
|
|
71
|
+
border-radius: 100px;
|
|
72
|
+
transition: all 0.2s ease;
|
|
73
|
+
|
|
74
|
+
&:hover {
|
|
75
|
+
border-color: #FFF;
|
|
76
|
+
background: rgba(255, 255, 255, .12);
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
export const SearchSummary = styled.span`
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
text-overflow: ellipsis;
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
`;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Edited: Ferjolt Ozuni - Date: 2026-08-01
|
|
88
|
+
*
|
|
89
|
+
* Collapsed by default: the form is there for the minority who want to
|
|
90
|
+
* change something, and left open it pushed the results themselves below
|
|
91
|
+
* the fold on the page whose whole job is showing results.
|
|
92
|
+
*/
|
|
93
|
+
export const SearchPanel = styled.div<{ $open: boolean }>`
|
|
94
|
+
display: ${ props => props.$open ? 'block' : 'none' };
|
|
95
|
+
margin-top: 14px;
|
|
96
|
+
padding: 20px;
|
|
97
|
+
background: ${ props => props.theme.header.transparent };
|
|
98
|
+
backdrop-filter: blur(25px);
|
|
99
|
+
-webkit-backdrop-filter: blur(25px);
|
|
100
|
+
border-radius: ${ props => props.theme.borderRadius };
|
|
37
101
|
`;
|
|
38
102
|
|
|
39
103
|
/**
|