@ta-interaktiv/react-municipality-search 1.9.3 → 1.11.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/CHANGELOG.md +16 -0
- package/dist/index.js +96 -86
- package/dist/index.js.map +1 -1
- package/dist/municipalitySearch.d.ts +13 -10
- package/dist/municipalitySearch.d.ts.map +1 -1
- package/es/index.js +96 -85
- package/es/index.js.map +1 -1
- package/es/municipalitySearch.d.ts +13 -10
- package/es/municipalitySearch.d.ts.map +1 -1
- package/package.json +3 -6
- package/src/locales/de.yml +1 -3
- package/src/locales/fr.yml +1 -1
- package/src/municipalitySearch.tsx +197 -119
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/camelcase */
|
|
2
2
|
import React, { ChangeEvent, Component } from 'react'
|
|
3
|
-
import '
|
|
4
|
-
import '@ta-interaktiv/semantic-ui/semantic/dist/components/input.css'
|
|
5
|
-
import '@ta-interaktiv/semantic-ui/semantic/dist/components/label.css'
|
|
6
|
-
// import './styles.scss'
|
|
7
|
-
import styled from 'styled-components'
|
|
3
|
+
import styled, { css } from 'styled-components'
|
|
8
4
|
import { animated, config as springConfig, Transition } from '@react-spring/web'
|
|
9
|
-
import IntlMessageFormat from 'intl-messageformat'
|
|
10
5
|
import de from './locales/de.yml'
|
|
11
6
|
import fr from './locales/fr.yml'
|
|
12
7
|
import Cookies from 'js-cookie'
|
|
@@ -24,13 +19,14 @@ interface LocalisedMessagesList {
|
|
|
24
19
|
|
|
25
20
|
export interface Municipality {
|
|
26
21
|
readonly GDENR: number
|
|
27
|
-
readonly ORTNAME
|
|
28
|
-
readonly PLZ4
|
|
22
|
+
readonly ORTNAME?: string
|
|
23
|
+
readonly PLZ4?: number
|
|
29
24
|
readonly PLZ6?: number
|
|
30
|
-
readonly GDENAMK
|
|
25
|
+
readonly GDENAMK?: string
|
|
31
26
|
readonly KTKZ: string
|
|
32
|
-
readonly NORMORTSNAME
|
|
27
|
+
readonly NORMORTSNAME?: string
|
|
33
28
|
readonly NORMGEMEINDE: string
|
|
29
|
+
readonly URL?: string
|
|
34
30
|
timestamp?: number
|
|
35
31
|
}
|
|
36
32
|
|
|
@@ -42,9 +38,6 @@ export interface Props {
|
|
|
42
38
|
/* Deduplicate list of municipality names */
|
|
43
39
|
dedupe?: boolean
|
|
44
40
|
|
|
45
|
-
/* Hide the tooltip */
|
|
46
|
-
hideTooltip?: boolean
|
|
47
|
-
|
|
48
41
|
/* Reset the component when the user selects a municipality */
|
|
49
42
|
resetOnSelect?: boolean
|
|
50
43
|
|
|
@@ -71,6 +64,18 @@ export interface Props {
|
|
|
71
64
|
|
|
72
65
|
/** Custom list of municipalities */
|
|
73
66
|
customMunicipalities?: Municipality[]
|
|
67
|
+
|
|
68
|
+
/** currently selected municipality displayed inside the input field */
|
|
69
|
+
selectedMunicipality?: Municipality
|
|
70
|
+
|
|
71
|
+
/** handler for when close button pressed */
|
|
72
|
+
onCloseHandler?: () => void
|
|
73
|
+
|
|
74
|
+
/** input background color */
|
|
75
|
+
inputBackgroundColor?: string
|
|
76
|
+
|
|
77
|
+
/** result background color */
|
|
78
|
+
resultBackgroundColor?: string
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
interface State {
|
|
@@ -99,7 +104,7 @@ const localStorageItemName = 'selectedMunicipalities'
|
|
|
99
104
|
*/
|
|
100
105
|
const translationServiceFactory = (
|
|
101
106
|
messageList: LocalisedMessagesList,
|
|
102
|
-
locale: string
|
|
107
|
+
locale: string,
|
|
103
108
|
) => {
|
|
104
109
|
return (key: string | null) => {
|
|
105
110
|
if (key == null) {
|
|
@@ -110,7 +115,7 @@ const translationServiceFactory = (
|
|
|
110
115
|
.split('.')
|
|
111
116
|
.reduce(
|
|
112
117
|
(messages: MessageListContent, prop: string) => messages[prop],
|
|
113
|
-
messageList[locale]
|
|
118
|
+
messageList[locale],
|
|
114
119
|
) || 'TRANSLATED STRING NOT FOUND'
|
|
115
120
|
)
|
|
116
121
|
}
|
|
@@ -152,6 +157,8 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
152
157
|
municipalityData: '2021v3',
|
|
153
158
|
locale: 'de',
|
|
154
159
|
numberOfLastSelectedMunicipalities: 1,
|
|
160
|
+
resultBackgroundColor: 'var(--site-background)',
|
|
161
|
+
inputBackgroundColor: 'var(--site-background)',
|
|
155
162
|
}
|
|
156
163
|
|
|
157
164
|
public state = {
|
|
@@ -183,7 +190,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
183
190
|
const digits = digitsResultsArray[0]
|
|
184
191
|
results = municipalities.filter(
|
|
185
192
|
(municipality: Municipality) =>
|
|
186
|
-
municipality.PLZ4.toString() === digits
|
|
193
|
+
(municipality.PLZ4 ?? '').toString() === digits,
|
|
187
194
|
)
|
|
188
195
|
|
|
189
196
|
if (results.length < 1) {
|
|
@@ -193,7 +200,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
193
200
|
// in case it starts with a number, we're assuming the reader is looking
|
|
194
201
|
// for a zip code
|
|
195
202
|
results = municipalities.filter((municipality: Municipality) =>
|
|
196
|
-
RegExp(`^${searchTerm}`).test(municipality.PLZ4.toString())
|
|
203
|
+
RegExp(`^${searchTerm}`).test((municipality.PLZ4 ?? '').toString()),
|
|
197
204
|
)
|
|
198
205
|
|
|
199
206
|
if (results.length < 1) {
|
|
@@ -209,10 +216,10 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
209
216
|
results = municipalities
|
|
210
217
|
.filter(
|
|
211
218
|
(municipality: Municipality) =>
|
|
212
|
-
r.test(municipality.ORTNAME) ||
|
|
213
|
-
r.test(municipality.GDENAMK) ||
|
|
214
|
-
r.test(municipality.NORMORTSNAME) ||
|
|
215
|
-
r.test(municipality.NORMGEMEINDE)
|
|
219
|
+
r.test(municipality.ORTNAME ?? '') ||
|
|
220
|
+
r.test(municipality.GDENAMK ?? '') ||
|
|
221
|
+
r.test(municipality.NORMORTSNAME ?? '') ||
|
|
222
|
+
r.test(municipality.NORMGEMEINDE),
|
|
216
223
|
)
|
|
217
224
|
.slice(0, this.props.maxResults)
|
|
218
225
|
|
|
@@ -234,14 +241,14 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
234
241
|
|
|
235
242
|
private removeDuplicates(
|
|
236
243
|
arr: Municipality[],
|
|
237
|
-
searchTerm: string
|
|
244
|
+
searchTerm: string,
|
|
238
245
|
): Municipality[] {
|
|
239
246
|
const map = new Map()
|
|
240
247
|
arr.forEach((v) => {
|
|
241
248
|
if (this.props.dedupe) {
|
|
242
|
-
map.set(v.ORTNAME + v.GDENR, v)
|
|
249
|
+
map.set((v.ORTNAME ?? '') + v.GDENR, v)
|
|
243
250
|
} else {
|
|
244
|
-
map.set(v.PLZ4 + v.ORTNAME + v.GDENR, v)
|
|
251
|
+
map.set((v.PLZ4 ?? '') + (v.ORTNAME ?? '') + v.GDENR, v)
|
|
245
252
|
}
|
|
246
253
|
})
|
|
247
254
|
|
|
@@ -250,8 +257,8 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
250
257
|
.reduce(
|
|
251
258
|
(acc, cur) => {
|
|
252
259
|
if (
|
|
253
|
-
cur.GDENAMK
|
|
254
|
-
cur.ORTNAME
|
|
260
|
+
cur.GDENAMK?.toLowerCase() === searchTerm.toLowerCase() ||
|
|
261
|
+
cur.ORTNAME?.toLowerCase() === searchTerm.toLowerCase()
|
|
255
262
|
) {
|
|
256
263
|
acc[0].push(cur)
|
|
257
264
|
} else {
|
|
@@ -259,7 +266,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
259
266
|
}
|
|
260
267
|
return acc
|
|
261
268
|
},
|
|
262
|
-
[[], []]
|
|
269
|
+
[[], []],
|
|
263
270
|
)
|
|
264
271
|
.flat()
|
|
265
272
|
|
|
@@ -340,7 +347,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
340
347
|
return -1
|
|
341
348
|
}
|
|
342
349
|
return 0
|
|
343
|
-
}
|
|
350
|
+
},
|
|
344
351
|
)
|
|
345
352
|
return this.deduplicateMunicipalityArray(ordered)
|
|
346
353
|
}
|
|
@@ -355,7 +362,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
355
362
|
// limit the number of stored municipalities
|
|
356
363
|
const slicedArray = prevSelectedMunicipalities.slice(
|
|
357
364
|
0,
|
|
358
|
-
15
|
|
365
|
+
15,
|
|
359
366
|
) as Municipality[]
|
|
360
367
|
newMuni.timestamp = Date.now()
|
|
361
368
|
slicedArray.unshift(newMuni)
|
|
@@ -364,7 +371,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
364
371
|
try {
|
|
365
372
|
// deduplicate the array, sort it by timestamp and stringify it for localStorage and cookies
|
|
366
373
|
const newMuniArray = JSON.stringify(
|
|
367
|
-
this.deduplicateMunicipalityArray(slicedArray)
|
|
374
|
+
this.deduplicateMunicipalityArray(slicedArray),
|
|
368
375
|
)
|
|
369
376
|
localStorage.setItem(localStorageItemName, newMuniArray)
|
|
370
377
|
Cookies.set(localStorageItemName, newMuniArray, {
|
|
@@ -383,7 +390,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
383
390
|
*/
|
|
384
391
|
|
|
385
392
|
private deduplicateMunicipalityArray = (
|
|
386
|
-
munis: Municipality[]
|
|
393
|
+
munis: Municipality[],
|
|
387
394
|
): Municipality[] => {
|
|
388
395
|
return [
|
|
389
396
|
...new Map(
|
|
@@ -391,9 +398,11 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
391
398
|
.slice()
|
|
392
399
|
.reverse()
|
|
393
400
|
.map((muni: Municipality) => [
|
|
394
|
-
muni.ORTNAME
|
|
401
|
+
(muni.ORTNAME ?? '') +
|
|
402
|
+
muni.GDENR +
|
|
403
|
+
(this.props.dedupe ? '' : muni.PLZ4),
|
|
395
404
|
muni,
|
|
396
|
-
])
|
|
405
|
+
]),
|
|
397
406
|
).values(),
|
|
398
407
|
]
|
|
399
408
|
.reverse()
|
|
@@ -430,7 +439,7 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
430
439
|
.then((res) => {
|
|
431
440
|
if (!res.ok) {
|
|
432
441
|
throw new MunicipalityDownloadError(
|
|
433
|
-
`Download error: ${res.status}: ${res.statusText}
|
|
442
|
+
`Download error: ${res.status}: ${res.statusText}.`,
|
|
434
443
|
)
|
|
435
444
|
}
|
|
436
445
|
return res.json()
|
|
@@ -447,10 +456,10 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
447
456
|
if (error instanceof MunicipalityDownloadError) {
|
|
448
457
|
console.log(error)
|
|
449
458
|
console.info(
|
|
450
|
-
'Make sure that you have the municipality and zip code data for the required year uploaded to the Interaktiv server.'
|
|
459
|
+
'Make sure that you have the municipality and zip code data for the required year uploaded to the Interaktiv server.',
|
|
451
460
|
)
|
|
452
461
|
console.info(
|
|
453
|
-
'Read more about the data generation in the "data" directory in the project repository for the MunicipalitySearch React component.'
|
|
462
|
+
'Read more about the data generation in the "data" directory in the project repository for the MunicipalitySearch React component.',
|
|
454
463
|
)
|
|
455
464
|
this.setState({
|
|
456
465
|
isLoading: false,
|
|
@@ -482,29 +491,31 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
482
491
|
prevSelectedMunicipalities.length > 0
|
|
483
492
|
) {
|
|
484
493
|
const allBfsIdsAndNames = prevSelectedMunicipalities.map(
|
|
485
|
-
(muni) => muni.GDENR + muni.ORTNAME + muni.PLZ4
|
|
494
|
+
(muni) => muni.GDENR + muni.ORTNAME + muni.PLZ4,
|
|
486
495
|
)
|
|
487
496
|
const filteredFromFetchedData: Municipality[] = data.filter(
|
|
488
497
|
(muni: Municipality) =>
|
|
489
|
-
allBfsIdsAndNames.includes(
|
|
498
|
+
allBfsIdsAndNames.includes(
|
|
499
|
+
muni.GDENR + (muni.ORTNAME ?? '') + muni.PLZ4,
|
|
500
|
+
),
|
|
490
501
|
)
|
|
491
502
|
// sort before deduplication
|
|
492
503
|
filteredFromFetchedData.sort((a, b) => {
|
|
493
504
|
return (
|
|
494
|
-
allBfsIdsAndNames.indexOf(a.GDENR + a.ORTNAME + a.PLZ4) -
|
|
495
|
-
allBfsIdsAndNames.indexOf(b.GDENR + b.ORTNAME + b.PLZ4)
|
|
505
|
+
allBfsIdsAndNames.indexOf(a.GDENR + (a.ORTNAME ?? '') + a.PLZ4) -
|
|
506
|
+
allBfsIdsAndNames.indexOf(b.GDENR + (b.ORTNAME ?? '') + b.PLZ4)
|
|
496
507
|
)
|
|
497
508
|
})
|
|
498
509
|
// always dedupe bc. sometimes there is duplicate data in the jsons
|
|
499
510
|
const dedupedData = this.deduplicateMunicipalityArray(
|
|
500
|
-
filteredFromFetchedData
|
|
511
|
+
filteredFromFetchedData,
|
|
501
512
|
)
|
|
502
513
|
|
|
503
514
|
// sort the dedupedData in the same order as in the localStorage
|
|
504
515
|
dedupedData.sort((a, b) => {
|
|
505
516
|
return (
|
|
506
|
-
allBfsIdsAndNames.indexOf(a.GDENR + a.ORTNAME + a.PLZ4) -
|
|
507
|
-
allBfsIdsAndNames.indexOf(b.GDENR + b.ORTNAME + b.PLZ4)
|
|
517
|
+
allBfsIdsAndNames.indexOf(a.GDENR + (a.ORTNAME ?? '') + a.PLZ4) -
|
|
518
|
+
allBfsIdsAndNames.indexOf(b.GDENR + (b.ORTNAME ?? '') + b.PLZ4)
|
|
508
519
|
)
|
|
509
520
|
})
|
|
510
521
|
const muniCount = this.props.numberOfLastSelectedMunicipalities
|
|
@@ -524,52 +535,47 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
524
535
|
*/
|
|
525
536
|
const t = translationServiceFactory(MESSAGES, this.props.locale)
|
|
526
537
|
|
|
527
|
-
// result string formatter
|
|
528
|
-
const resultString = new IntlMessageFormat(
|
|
529
|
-
MESSAGES[this.props.locale].results,
|
|
530
|
-
this.props.locale + '-CH'
|
|
531
|
-
)
|
|
532
|
-
|
|
533
|
-
const labelContent = () => {
|
|
534
|
-
if (this.state.error) {
|
|
535
|
-
return t(this.state.error)
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
if (!!value && value.length >= 2) {
|
|
539
|
-
return resultString.format({ numResults: results.length })
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
return t('label')
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
const labelDirection = window.matchMedia('screen and (max-width: 599px)')
|
|
546
|
-
.matches
|
|
547
|
-
? 'top pointing'
|
|
548
|
-
: 'left pointing'
|
|
549
|
-
|
|
550
538
|
return (
|
|
551
539
|
<MunicipalitySearchContainer className='municipality-search'>
|
|
552
540
|
<InputRow className='inputRow'>
|
|
553
|
-
<
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
541
|
+
<FlexInput
|
|
542
|
+
// id='search'
|
|
543
|
+
type='text'
|
|
544
|
+
// className='prompt flexInput'
|
|
545
|
+
lessPaddingLeft={
|
|
546
|
+
!!this.props.selectedMunicipality || this.props.iconOnRightSide
|
|
558
547
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
|
|
548
|
+
placeholder={this.props.placeholder || (t('placeholder') as string)}
|
|
549
|
+
value={this.props.selectedMunicipality?.NORMGEMEINDE ?? value}
|
|
550
|
+
disabled={
|
|
551
|
+
this.state.error === 'error.municipalitiesNotDownloaded' ||
|
|
552
|
+
!!this.props.selectedMunicipality
|
|
553
|
+
}
|
|
554
|
+
onChange={this.handleSearchChange}
|
|
555
|
+
backgroundColor={this.props.inputBackgroundColor}
|
|
556
|
+
/>
|
|
557
|
+
{this.props.selectedMunicipality ? (
|
|
558
|
+
<Icon
|
|
559
|
+
onClick={() => this.props.onCloseHandler?.()}
|
|
560
|
+
isClickable
|
|
561
|
+
id='search-closing-icon'
|
|
562
|
+
isRight
|
|
563
|
+
>
|
|
564
|
+
<svg
|
|
565
|
+
width='20'
|
|
566
|
+
height='21'
|
|
567
|
+
viewBox='0 0 24 25'
|
|
568
|
+
xmlns='http://www.w3.org/2000/svg'
|
|
569
|
+
fill='currentColor'
|
|
570
|
+
strokeWidth="2"
|
|
571
|
+
>
|
|
572
|
+
<path
|
|
573
|
+
d='M3.9 22L2 20.1L9.6 12.5L2 4.9L3.9 3L11.5 10.6L19.1 3L21 4.9L13.4 12.5L21 20.1L19.1 22L11.5 14.4L3.9 22Z'
|
|
574
|
+
fill='currentColor'
|
|
575
|
+
/>
|
|
576
|
+
</svg>
|
|
577
|
+
</Icon>
|
|
578
|
+
) : (
|
|
573
579
|
<Icon isRight={this.props?.iconOnRightSide}>
|
|
574
580
|
<svg
|
|
575
581
|
width='18'
|
|
@@ -577,35 +583,28 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
577
583
|
viewBox='0 0 18 18'
|
|
578
584
|
fill='none'
|
|
579
585
|
xmlns='http://www.w3.org/2000/svg'
|
|
580
|
-
stroke='
|
|
581
|
-
strokeWidth='
|
|
586
|
+
stroke='currentColor'
|
|
587
|
+
strokeWidth='2'
|
|
582
588
|
>
|
|
583
589
|
<circle cx='7.5' cy='7.5' r='6' />
|
|
584
590
|
<line x1='11' y1='11' x2='17' y2='17' />
|
|
585
591
|
</svg>
|
|
586
592
|
</Icon>
|
|
587
|
-
</div>
|
|
588
|
-
{!this.props.hideTooltip && (
|
|
589
|
-
<div>
|
|
590
|
-
<label
|
|
591
|
-
htmlFor='search'
|
|
592
|
-
className={`ui ${
|
|
593
|
-
this.state.error ? 'red' : 'basic grey'
|
|
594
|
-
} ${labelDirection} label`}
|
|
595
|
-
>
|
|
596
|
-
{String(labelContent())}
|
|
597
|
-
</label>
|
|
598
|
-
</div>
|
|
599
593
|
)}
|
|
600
594
|
</InputRow>
|
|
601
595
|
{showResults(results) && (
|
|
602
|
-
<Results
|
|
596
|
+
<Results
|
|
597
|
+
className='results'
|
|
598
|
+
backgroundColor={this.props.resultBackgroundColor}
|
|
599
|
+
>
|
|
603
600
|
{showResults(results) && (
|
|
604
601
|
<Transition
|
|
605
602
|
native
|
|
606
603
|
items={results}
|
|
607
604
|
keys={(result: Municipality) =>
|
|
608
|
-
result.
|
|
605
|
+
result.GDENR +
|
|
606
|
+
String(result.PLZ4 ?? '') +
|
|
607
|
+
(result.ORTNAME ?? '')
|
|
609
608
|
}
|
|
610
609
|
from={{ transform: 'translate(0,-20px)', opacity: 0 }}
|
|
611
610
|
enter={{ transform: 'translate(0,0px)', opacity: 1 }}
|
|
@@ -643,7 +642,18 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
643
642
|
</ResultHeader>
|
|
644
643
|
<ResultMeta className='resultMeta'>
|
|
645
644
|
<>
|
|
646
|
-
{t('list.municipalityPrefix')}
|
|
645
|
+
{result.ORTNAME ? t('list.municipalityPrefix') : ''}{' '}
|
|
646
|
+
<b>
|
|
647
|
+
{result.GDENAMK ??
|
|
648
|
+
result.NORMGEMEINDE +
|
|
649
|
+
(results.find(
|
|
650
|
+
(muni: Municipality) =>
|
|
651
|
+
muni !== result &&
|
|
652
|
+
muni.NORMGEMEINDE === result.NORMGEMEINDE,
|
|
653
|
+
)
|
|
654
|
+
? ' (' + result.KTKZ + ')'
|
|
655
|
+
: '')}
|
|
656
|
+
</b>
|
|
647
657
|
</>
|
|
648
658
|
</ResultMeta>
|
|
649
659
|
</animated.div>
|
|
@@ -658,7 +668,8 @@ export class MunicipalitySearch extends Component<Props, State> {
|
|
|
658
668
|
|
|
659
669
|
// endregion
|
|
660
670
|
}
|
|
661
|
-
const Icon = styled.i<{ isRight?: boolean }>`
|
|
671
|
+
const Icon = styled.i<{ isRight?: boolean; isClickable?: boolean }>`
|
|
672
|
+
cursor: ${(props) => (props.isClickable ? 'pointer' : 'default')};
|
|
662
673
|
position: absolute;
|
|
663
674
|
top: 50%;
|
|
664
675
|
${(props) => (props.isRight ? 'right: 0; padding-right: 0.8em;' : '')}
|
|
@@ -667,9 +678,43 @@ const Icon = styled.i<{ isRight?: boolean }>`
|
|
|
667
678
|
display: flex;
|
|
668
679
|
opacity: 0.5;
|
|
669
680
|
transition: opacity 0.5s ease-in-out;
|
|
681
|
+
animation: fromLeft 0.3s ease-in-out;
|
|
682
|
+
@keyframes fromLeft {
|
|
683
|
+
0% {
|
|
684
|
+
transform: translateY(-50%) translateX(-10px);
|
|
685
|
+
opacity: 0;
|
|
686
|
+
}
|
|
687
|
+
100% {
|
|
688
|
+
transform: translateY(-50%) translateX(0);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
&#search-closing-icon {
|
|
692
|
+
&:hover {
|
|
693
|
+
opacity: 1;
|
|
694
|
+
}
|
|
695
|
+
animation: fromRight 0.3s ease-in-out;
|
|
696
|
+
@keyframes fromRight {
|
|
697
|
+
0% {
|
|
698
|
+
transform: translateY(-50%) translateX(10px);
|
|
699
|
+
opacity: 0;
|
|
700
|
+
}
|
|
701
|
+
100% {
|
|
702
|
+
transform: translateY(-50%) translateX(0);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
`
|
|
707
|
+
const MunicipalitySearchContainer = styled.div`
|
|
708
|
+
--border-radius: 0.3em;
|
|
709
|
+
font-size: 18px;
|
|
710
|
+
@media screen and (max-width: 599px) {
|
|
711
|
+
max-width: 100%;
|
|
712
|
+
}
|
|
713
|
+
max-width: 300px;
|
|
714
|
+
color: inherit;
|
|
670
715
|
`
|
|
671
|
-
const MunicipalitySearchContainer = styled.div``
|
|
672
716
|
const InputRow = styled.div`
|
|
717
|
+
position: relative;
|
|
673
718
|
display: flex;
|
|
674
719
|
flex-direction: row;
|
|
675
720
|
align-items: center;
|
|
@@ -678,36 +723,69 @@ const InputRow = styled.div`
|
|
|
678
723
|
}
|
|
679
724
|
@media screen and (max-width: 599px) {
|
|
680
725
|
flex-direction: column;
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
726
|
+
}
|
|
727
|
+
.ui.input {
|
|
728
|
+
width: 100%;
|
|
729
|
+
max-width: 100%;
|
|
730
|
+
transition: all 0.5s ease-in-out;
|
|
685
731
|
}
|
|
686
732
|
`
|
|
687
|
-
const FlexInput = styled.input
|
|
733
|
+
const FlexInput = styled.input<{
|
|
734
|
+
lessPaddingLeft?: boolean
|
|
735
|
+
backgroundColor?: string
|
|
736
|
+
}>`
|
|
737
|
+
// reset the default input styles
|
|
738
|
+
color: inherit;
|
|
739
|
+
background-color: ${({ backgroundColor }) => backgroundColor};
|
|
740
|
+
border: solid 1px #7e7e7e7e;
|
|
741
|
+
border-radius: var(--border-radius);
|
|
742
|
+
box-shadow: none;
|
|
743
|
+
font-size: 1em;
|
|
744
|
+
outline: none;
|
|
745
|
+
transition: all 0.3s ease-in-out;
|
|
746
|
+
padding: 0.5em;
|
|
747
|
+
padding-left: ${({ lessPaddingLeft }) => (lessPaddingLeft ? '1em' : '2.4em')};
|
|
748
|
+
margin: 0;
|
|
749
|
+
width: 100%;
|
|
688
750
|
display: flex;
|
|
751
|
+
&::placeholder{
|
|
752
|
+
color: inherit;
|
|
753
|
+
opacity: 0.5;
|
|
754
|
+
}
|
|
689
755
|
`
|
|
690
|
-
const Results = styled.div
|
|
691
|
-
margin-top:
|
|
756
|
+
const Results = styled.div<{ backgroundColor?: string }>`
|
|
757
|
+
margin-top: .25em;
|
|
692
758
|
display: grid;
|
|
693
|
-
grid-template-columns:
|
|
759
|
+
grid-template-columns: 1fr;
|
|
694
760
|
grid-gap: 0;
|
|
695
|
-
font-family: var(--
|
|
761
|
+
font-family: var(--font-plex);
|
|
762
|
+
overflow: hidden;
|
|
763
|
+
display: flex;
|
|
764
|
+
flex-direction: column;
|
|
765
|
+
pointer-events: auto;
|
|
766
|
+
position: absolute;
|
|
767
|
+
background-color: ${({ backgroundColor }) => backgroundColor};
|
|
768
|
+
width: 100%;
|
|
769
|
+
border-radius: var(--border-radius);
|
|
770
|
+
@media screen and (min-width: 599px) {
|
|
771
|
+
max-width: 300px;
|
|
772
|
+
}
|
|
696
773
|
.result {
|
|
774
|
+
max-width: 100%;
|
|
775
|
+
color: currentColor;
|
|
697
776
|
padding: calc(11 / 16 * 1em) calc(14 / 16 * 1em);
|
|
698
|
-
border-radius:
|
|
777
|
+
border-radius: var(--border-radius);
|
|
699
778
|
box-shadow: 0 0 0 rgba(0, 0, 0, 0.3);
|
|
700
779
|
//border: 1px solid #007abf;
|
|
701
|
-
color:
|
|
780
|
+
color: inherit;
|
|
702
781
|
line-height: 1.1em;
|
|
703
782
|
cursor: pointer;
|
|
704
783
|
transition: box-shadow 200ms ease-in-out;
|
|
705
|
-
background-color: transparent;
|
|
706
|
-
|
|
707
784
|
&:hover,
|
|
708
785
|
&:focus {
|
|
709
|
-
box-shadow:
|
|
710
|
-
|
|
786
|
+
box-shadow:
|
|
787
|
+
0 0 0.5ex rgba(0, 0, 0, 0.2),
|
|
788
|
+
0 0 0 1px #007abf inset;
|
|
711
789
|
}
|
|
712
790
|
}
|
|
713
791
|
`
|