@npm_leadtech/legal-lib-components 7.22.0 → 7.22.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.
@@ -0,0 +1,3 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M15.2462 5.92913C15.5706 5.60466 15.5706 5.07859 15.2462 4.75413C14.9217 4.42966 14.3956 4.42966 14.0712 4.75413L10.0003 8.82496L5.92949 4.75413C5.60503 4.42966 5.07896 4.42966 4.75449 4.75413C4.43002 5.07859 4.43003 5.60466 4.75449 5.92913L8.82533 9.99996L4.75449 14.0708C4.43003 14.3953 4.43002 14.9213 4.75449 15.2458C5.07896 15.5703 5.60502 15.5703 5.92949 15.2458L10.0003 11.175L14.0712 15.2458C14.3956 15.5703 14.9217 15.5703 15.2462 15.2458C15.5706 14.9213 15.5706 14.3953 15.2462 14.0708L11.1753 9.99996L15.2462 5.92913Z" fill="#B5BABD"/>
3
+ </svg>
@@ -1,3 +1,3 @@
1
1
  import React from 'react';
2
2
  import { DropdownInputProps } from './DropdownInputProps.types';
3
- export declare const DropdownInput: React.FC<DropdownInputProps>;
3
+ export declare const DropdownInput: React.ForwardRefExoticComponent<DropdownInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /* eslint-disable jsx-a11y/no-static-element-interactions */
3
- import React, { useState } from 'react';
3
+ import React, { forwardRef, useState } from 'react';
4
4
  import { DropdownInputStyled } from './DropdownInput.styled';
5
- export const DropdownInput = ({ onChange, results, className = '', name, icon, placeholder }) => {
5
+ export const DropdownInput = forwardRef(({ onChange, results, className = '', name, icon, placeholder }, ref) => {
6
6
  const [searchTerm, setSearchTerm] = useState('');
7
7
  const updateInput = (e) => {
8
8
  setSearchTerm(e.target.value);
@@ -11,7 +11,7 @@ export const DropdownInput = ({ onChange, results, className = '', name, icon, p
11
11
  const resetInput = () => {
12
12
  setSearchTerm('');
13
13
  };
14
- return (_jsxs(DropdownInputStyled, { className: `dropdown_input ${className}`, children: [_jsxs("div", { className: 'dropdown_input__container', children: [_jsx("input", { className: `dropdown_input__container__text_input ${icon ? 'with-icon' : ''}`, type: 'text', name: `dropdown_input_${name}`, placeholder: placeholder, value: searchTerm, onChange: (e) => {
14
+ return (_jsxs(DropdownInputStyled, { className: `dropdown_input ${className}`, children: [_jsxs("div", { className: 'dropdown_input__container', children: [_jsx("input", { ref: ref, className: `dropdown_input__container__text_input ${icon ? 'with-icon' : ''}`, type: 'text', name: `dropdown_input_${name}`, placeholder: placeholder, value: searchTerm, onChange: (e) => {
15
15
  updateInput(e);
16
16
  } }), _jsxs("div", { className: `dropdown_input__container__icon ${searchTerm ? 'active' : ''}`, children: [icon &&
17
17
  React.cloneElement(icon, {
@@ -21,4 +21,5 @@ export const DropdownInput = ({ onChange, results, className = '', name, icon, p
21
21
  }, onKeyDown: () => {
22
22
  resetInput();
23
23
  } }))] })] }), searchTerm && !!results?.length && _jsx("ul", { className: 'dropdown_input__results', children: results })] }));
24
- };
24
+ });
25
+ DropdownInput.displayName = 'DropdownInput';
@@ -2,32 +2,13 @@ import { device } from '../../../globalStyles/breakpoints';
2
2
  import styled from 'styled-components';
3
3
  export const DropdownInputStyled = styled.div `
4
4
  position: relative;
5
- padding-left: 1.5rem;
6
- padding-right: 1.5rem;
7
5
 
8
- a {
9
- text-decoration: none;
6
+ @media ${device['landscape-tablets']} {
7
+ padding: 1rem 2rem;
10
8
  }
11
9
 
12
- &:focus-within {
13
- @media ${device['landscape-tablets']} {
14
- .dropdown_input__container {
15
- border-bottom: 2px var(--neutral-neutral-4) solid;
16
- }
17
-
18
- .dropdown_input__results {
19
- opacity: 1;
20
- }
21
- }
22
-
23
- .dropdown_input__container__icon {
24
- color: var(--primary-main);
25
-
26
- svg {
27
- fill: var(--primary-main);
28
- stroke: var(--primary-main);
29
- }
30
- }
10
+ a {
11
+ text-decoration: none;
31
12
  }
32
13
 
33
14
  .dropdown_input__container {
@@ -41,6 +22,23 @@ export const DropdownInputStyled = styled.div `
41
22
  border-bottom: 2px solid transparent;
42
23
  }
43
24
 
25
+ &:focus-within {
26
+ border-bottom: 2px var(--neutral-neutral-4) solid;
27
+
28
+ @media ${device['landscape-tablets']} {
29
+ border-bottom: 2px var(--neutral-neutral-4) solid;
30
+ }
31
+
32
+ .dropdown_input__container__icon {
33
+ color: var(--primary-main);
34
+
35
+ svg {
36
+ fill: var(--primary-main);
37
+ stroke: var(--primary-main);
38
+ }
39
+ }
40
+ }
41
+
44
42
  .dropdown_input__container__text_input {
45
43
  width: 100%;
46
44
  height: 100%;
@@ -55,7 +53,7 @@ export const DropdownInputStyled = styled.div `
55
53
  color: var(--neutral-neutral-3);
56
54
  }
57
55
 
58
- .dropdown_input__container__text_input.with-icon {
56
+ &.with-icon {
59
57
  padding-right: 2rem;
60
58
  }
61
59
  }
@@ -79,6 +77,7 @@ export const DropdownInputStyled = styled.div `
79
77
  height: 1.5rem;
80
78
  opacity: 1;
81
79
  margin-right: 0.25rem;
80
+ cursor: pointer;
82
81
 
83
82
  path {
84
83
  transition: all 0.25s;
@@ -115,21 +114,27 @@ export const DropdownInputStyled = styled.div `
115
114
  .dropdown_input__results {
116
115
  transition: all 0.25s;
117
116
  display: flex;
118
- position: relative;
119
117
  flex-direction: column;
120
118
  width: 100%;
121
- border-radius: $s-border-radius;
122
- margin-top: 1rem;
119
+ border-radius: 8px;
123
120
  background: var(--others-white);
124
121
  min-width: 20rem;
125
-
126
- @media ${device['landscape-tablets']} {
127
- position: absolute;
128
- opacity: 0;
122
+ position: absolute;
123
+ top: 100%;
124
+ left: 0;
125
+ z-index: 10;
126
+ background-color: var(--others-white);
127
+ border-top: none;
128
+ padding: 1rem 2rem;
129
+
130
+ @media ${device['laptop']} {
131
+ opacity: 1;
129
132
  left: 0;
130
133
  top: 100%;
131
- box-shadow: $box-shadow-medium;
132
- padding: 0.75rem 1rem;
134
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
135
+ margin-top: 0;
136
+ border: none;
137
+ border-radius: 0 0 8px 8px;
133
138
  }
134
139
 
135
140
  & > li > * {
@@ -1,35 +1,15 @@
1
1
  import { device } from '../../../globalStyles/breakpoints'
2
-
3
2
  import styled from 'styled-components'
4
3
 
5
4
  export const DropdownInputStyled = styled.div`
6
5
  position: relative;
7
- padding-left: 1.5rem;
8
- padding-right: 1.5rem;
9
6
 
10
- a {
11
- text-decoration: none;
7
+ @media ${device['landscape-tablets']} {
8
+ padding: 1rem 2rem;
12
9
  }
13
10
 
14
- &:focus-within {
15
- @media ${device['landscape-tablets']} {
16
- .dropdown_input__container {
17
- border-bottom: 2px var(--neutral-neutral-4) solid;
18
- }
19
-
20
- .dropdown_input__results {
21
- opacity: 1;
22
- }
23
- }
24
-
25
- .dropdown_input__container__icon {
26
- color: var(--primary-main);
27
-
28
- svg {
29
- fill: var(--primary-main);
30
- stroke: var(--primary-main);
31
- }
32
- }
11
+ a {
12
+ text-decoration: none;
33
13
  }
34
14
 
35
15
  .dropdown_input__container {
@@ -43,6 +23,23 @@ export const DropdownInputStyled = styled.div`
43
23
  border-bottom: 2px solid transparent;
44
24
  }
45
25
 
26
+ &:focus-within {
27
+ border-bottom: 2px var(--neutral-neutral-4) solid;
28
+
29
+ @media ${device['landscape-tablets']} {
30
+ border-bottom: 2px var(--neutral-neutral-4) solid;
31
+ }
32
+
33
+ .dropdown_input__container__icon {
34
+ color: var(--primary-main);
35
+
36
+ svg {
37
+ fill: var(--primary-main);
38
+ stroke: var(--primary-main);
39
+ }
40
+ }
41
+ }
42
+
46
43
  .dropdown_input__container__text_input {
47
44
  width: 100%;
48
45
  height: 100%;
@@ -57,7 +54,7 @@ export const DropdownInputStyled = styled.div`
57
54
  color: var(--neutral-neutral-3);
58
55
  }
59
56
 
60
- .dropdown_input__container__text_input.with-icon {
57
+ &.with-icon {
61
58
  padding-right: 2rem;
62
59
  }
63
60
  }
@@ -81,6 +78,7 @@ export const DropdownInputStyled = styled.div`
81
78
  height: 1.5rem;
82
79
  opacity: 1;
83
80
  margin-right: 0.25rem;
81
+ cursor: pointer;
84
82
 
85
83
  path {
86
84
  transition: all 0.25s;
@@ -117,21 +115,27 @@ export const DropdownInputStyled = styled.div`
117
115
  .dropdown_input__results {
118
116
  transition: all 0.25s;
119
117
  display: flex;
120
- position: relative;
121
118
  flex-direction: column;
122
119
  width: 100%;
123
- border-radius: $s-border-radius;
124
- margin-top: 1rem;
120
+ border-radius: 8px;
125
121
  background: var(--others-white);
126
122
  min-width: 20rem;
127
-
128
- @media ${device['landscape-tablets']} {
129
- position: absolute;
130
- opacity: 0;
123
+ position: absolute;
124
+ top: 100%;
125
+ left: 0;
126
+ z-index: 10;
127
+ background-color: var(--others-white);
128
+ border-top: none;
129
+ padding: 1rem 2rem;
130
+
131
+ @media ${device['laptop']} {
132
+ opacity: 1;
131
133
  left: 0;
132
134
  top: 100%;
133
- box-shadow: $box-shadow-medium;
134
- padding: 0.75rem 1rem;
135
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
136
+ margin-top: 0;
137
+ border: none;
138
+ border-radius: 0 0 8px 8px;
135
139
  }
136
140
 
137
141
  & > li > * {
@@ -1,60 +1,57 @@
1
1
  /* eslint-disable jsx-a11y/no-static-element-interactions */
2
-
3
- import React, { useState } from 'react'
2
+ import React, { forwardRef, useState } from 'react'
4
3
  import { DropdownInputProps } from './DropdownInputProps.types'
5
4
  import { DropdownInputStyled } from './DropdownInput.styled'
6
5
 
7
- export const DropdownInput: React.FC<DropdownInputProps> = ({
8
- onChange,
9
- results,
10
- className = '',
11
- name,
12
- icon,
13
- placeholder
14
- }) => {
15
- const [searchTerm, setSearchTerm] = useState('')
6
+ export const DropdownInput = forwardRef<HTMLInputElement, DropdownInputProps>(
7
+ ({ onChange, results, className = '', name, icon, placeholder }, ref) => {
8
+ const [searchTerm, setSearchTerm] = useState('')
16
9
 
17
- const updateInput = (e): void => {
18
- setSearchTerm(e.target.value)
19
- onChange(e.target.value)
20
- }
10
+ const updateInput = (e): void => {
11
+ setSearchTerm(e.target.value)
12
+ onChange(e.target.value)
13
+ }
21
14
 
22
- const resetInput = (): void => {
23
- setSearchTerm('')
24
- }
15
+ const resetInput = (): void => {
16
+ setSearchTerm('')
17
+ }
25
18
 
26
- return (
27
- <DropdownInputStyled className={`dropdown_input ${className}`}>
28
- <div className='dropdown_input__container'>
29
- <input
30
- className={`dropdown_input__container__text_input ${icon ? 'with-icon' : ''}`}
31
- type='text'
32
- name={`dropdown_input_${name}`}
33
- placeholder={placeholder}
34
- value={searchTerm}
35
- onChange={(e) => {
36
- updateInput(e)
37
- }}
38
- />
39
- <div className={`dropdown_input__container__icon ${searchTerm ? 'active' : ''}`}>
40
- {icon &&
41
- React.cloneElement(icon, {
42
- className: 'dropdown_input__container__icon__main'
43
- })}
44
- {searchTerm && (
45
- <div
46
- className='icon-cross main-color dropdown_input__container__icon__clear'
47
- onClick={() => {
48
- resetInput()
49
- }}
50
- onKeyDown={() => {
51
- resetInput()
52
- }}
53
- ></div>
54
- )}
19
+ return (
20
+ <DropdownInputStyled className={`dropdown_input ${className}`}>
21
+ <div className='dropdown_input__container'>
22
+ <input
23
+ ref={ref}
24
+ className={`dropdown_input__container__text_input ${icon ? 'with-icon' : ''}`}
25
+ type='text'
26
+ name={`dropdown_input_${name}`}
27
+ placeholder={placeholder}
28
+ value={searchTerm}
29
+ onChange={(e) => {
30
+ updateInput(e)
31
+ }}
32
+ />
33
+ <div className={`dropdown_input__container__icon ${searchTerm ? 'active' : ''}`}>
34
+ {icon &&
35
+ React.cloneElement(icon, {
36
+ className: 'dropdown_input__container__icon__main'
37
+ })}
38
+ {searchTerm && (
39
+ <div
40
+ className='icon-cross main-color dropdown_input__container__icon__clear'
41
+ onClick={() => {
42
+ resetInput()
43
+ }}
44
+ onKeyDown={() => {
45
+ resetInput()
46
+ }}
47
+ ></div>
48
+ )}
49
+ </div>
55
50
  </div>
56
- </div>
57
- {searchTerm && !!results?.length && <ul className='dropdown_input__results'>{results}</ul>}
58
- </DropdownInputStyled>
59
- )
60
- }
51
+ {searchTerm && !!results?.length && <ul className='dropdown_input__results'>{results}</ul>}
52
+ </DropdownInputStyled>
53
+ )
54
+ }
55
+ )
56
+
57
+ DropdownInput.displayName = 'DropdownInput'
@@ -1,33 +1,83 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
3
3
  import { DropdownInput } from '../../atoms/DropdownInput/DropdownInput';
4
4
  import { SearchIcon } from '../../../../images/componentsSvg/SearchIcon';
5
5
  import { useWindowSize } from '../../../hooks/useWindowSize';
6
6
  import { SearchBarStyled } from './SearchBar.styled';
7
- export const SearchBar = ({ products, searchBarTexts, routes, handleResultClick }) => {
8
- const [results, setResults] = useState([]);
9
- const windowSize = useWindowSize();
10
- const _placeholder = windowSize.width === null || windowSize.width >= 720 ? '' : searchBarTexts.placeholder;
11
- const searchFunction = (text) => {
12
- const searchTerm = text.toLowerCase();
13
- const productsFiltered = products.filter((item) => item.linkText.toLowerCase().includes(searchTerm));
14
- const results = productsFiltered
15
- .map((item) => {
16
- const product = item.linkText;
17
- const preMatch = product.slice(0, product.toLowerCase().indexOf(searchTerm));
18
- const match = product.slice(product.toLowerCase().indexOf(searchTerm), preMatch.length + searchTerm.length);
19
- const postMatch = product.slice(product.toLowerCase().indexOf(searchTerm) + searchTerm.length, product.length);
20
- const link = item.categoryUrl ? `${item.categoryUrl}/${item.slug}` : item.slug;
21
- return (_jsx("li", { className: 'dropdown_input__item', children: _jsxs("a", { href: routes.CUSTOM_URL_FROM_TARGET_ADDRESS(link), className: 'dropdown_input__link', onClick: (e) => {
22
- e.preventDefault();
23
- handleResultClick(product, routes.CUSTOM_URL_FROM_TARGET_ADDRESS(link));
24
- }, title: product, children: [preMatch, _jsx("strong", { className: 'dropdown_input__link__emphasis', children: match }), postMatch] }, item.linkText) }, searchBarTexts.title));
25
- })
26
- .slice(0, 9);
27
- results.push(_jsx("li", { className: 'dropdown_input__item', children: _jsx("a", { className: 'dropdown_input__link--all', title: searchBarTexts.title, href: routes.LEGAL_DOCUMENTS, children: searchBarTexts.title }) }, searchBarTexts.title));
28
- setResults(results);
29
- };
30
- return (_jsx(SearchBarStyled, { children: _jsx(DropdownInput, { name: 'search', className: 'search', placeholder: _placeholder, icon: _jsx(SearchIcon, {}), onChange: (text) => {
7
+ import { useSearchFunction } from '../../../hooks/useSearchFunction';
8
+ const DesktopSearchBar = ({ products, searchBarTexts, routes, handleResultClick }) => {
9
+ const { results, searchFunction } = useSearchFunction({
10
+ products,
11
+ searchBarTexts,
12
+ routes,
13
+ handleResultClick
14
+ });
15
+ const searchInputRef = useRef(null);
16
+ const searchBarContainerRef = useRef(null);
17
+ const isResultsVisible = Array.isArray(results) && results.length > 0;
18
+ useEffect(() => {
19
+ const handleKeyDown = (event) => {
20
+ if (event.key === 'Escape') {
21
+ searchFunction('');
22
+ }
23
+ };
24
+ const handleClickOutside = (event) => {
25
+ if (searchBarContainerRef.current && !searchBarContainerRef.current.contains(event.target)) {
26
+ searchFunction('');
27
+ }
28
+ };
29
+ if (isResultsVisible) {
30
+ document.addEventListener('keydown', handleKeyDown);
31
+ document.addEventListener('mousedown', handleClickOutside);
32
+ }
33
+ return () => {
34
+ document.removeEventListener('keydown', handleKeyDown);
35
+ document.removeEventListener('mousedown', handleClickOutside);
36
+ };
37
+ }, [isResultsVisible, searchFunction]);
38
+ return (_jsx(SearchBarStyled, { ref: searchBarContainerRef, className: 'modal_searchbar', children: _jsx("div", { className: 'modal_searchbar__content', children: _jsx(DropdownInput, { ref: searchInputRef, name: 'search', className: 'search', placeholder: searchBarTexts.placeholder, icon: _jsx(SearchIcon, {}), onChange: (text) => {
39
+ searchFunction(text);
40
+ }, results: results }) }) }));
41
+ };
42
+ const MobileSearchBar = ({ products, searchBarTexts, routes, handleResultClick }) => {
43
+ const { results, searchFunction } = useSearchFunction({
44
+ products,
45
+ searchBarTexts,
46
+ routes,
47
+ handleResultClick
48
+ });
49
+ const searchInputRef = useRef(null);
50
+ const searchBarContainerRef = useRef(null);
51
+ const isResultsVisible = Array.isArray(results) && results.length > 0;
52
+ useEffect(() => {
53
+ const handleKeyDown = (event) => {
54
+ if (event.key === 'Escape') {
55
+ searchFunction('');
56
+ }
57
+ };
58
+ const handleClickOutside = (event) => {
59
+ if (searchBarContainerRef.current && !searchBarContainerRef.current.contains(event.target)) {
60
+ searchFunction('');
61
+ }
62
+ };
63
+ if (isResultsVisible) {
64
+ document.addEventListener('keydown', handleKeyDown);
65
+ document.addEventListener('mousedown', handleClickOutside);
66
+ }
67
+ return () => {
68
+ document.removeEventListener('keydown', handleKeyDown);
69
+ document.removeEventListener('mousedown', handleClickOutside);
70
+ };
71
+ }, [isResultsVisible, searchFunction]);
72
+ return (_jsx(SearchBarStyled, { ref: searchBarContainerRef, children: _jsx(DropdownInput, { ref: searchInputRef, name: 'search', className: 'search', placeholder: searchBarTexts.placeholder, icon: _jsx(SearchIcon, {}), onChange: (text) => {
31
73
  searchFunction(text);
32
74
  }, results: results }) }));
33
75
  };
76
+ export const SearchBar = (props) => {
77
+ const windowSize = useWindowSize();
78
+ const isDesktop = !!windowSize.width && windowSize.width >= 960;
79
+ if (isDesktop) {
80
+ return _jsx(DesktopSearchBar, { ...props });
81
+ }
82
+ return _jsx(MobileSearchBar, { ...props });
83
+ };
@@ -5,58 +5,56 @@ export const SearchBarStyled = styled.div `
5
5
  .search {
6
6
  width: calc(100% - 3rem);
7
7
  margin: 0 1.5rem;
8
+ }
9
+ }
8
10
 
9
- @media ${device['landscape-tablets']} {
10
- display: none;
11
- }
12
-
13
- @media ${device['landscape-tablets']} {
14
- display: block;
15
- width: 10rem;
16
- margin: 0 1.5rem 0 0;
11
+ @media ${device['landscape-tablets']} {
12
+ &.modal_searchbar {
13
+ position: fixed;
14
+ top: 0;
15
+ left: 0;
16
+ width: 100vw;
17
+ height: 100vh;
18
+ background: rgba(255, 255, 255, 0.95);
19
+ z-index: 9999;
20
+ display: flex;
21
+ justify-content: center;
22
+ align-items: flex-start;
23
+ padding-top: 100px;
24
+
25
+ .modal_searchbar__content {
26
+ background-color: var(--neutral-white);
27
+ padding: 1.5rem;
28
+ border-radius: 8px;
29
+ width: 90%;
30
+ max-width: 768px;
31
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
32
+
33
+ @media ${device['landscape-tablets']} {
34
+ padding: 0;
35
+ border-radius: 8px 8px 0 0;
36
+ }
17
37
  }
18
38
 
19
- @media ${device['desktop']} {
20
- width: 14rem;
39
+ .modal_searchbar__header {
40
+ display: flex;
41
+ justify-content: space-between;
42
+ align-items: center;
43
+ margin-bottom: 1rem;
21
44
  }
22
45
 
23
- .dropdown_input__results {
24
- transition: all 0.25s;
25
- min-width: 100%;
26
- width: max-content;
46
+ .modal_searchbar__title {
47
+ font-size: 1.5rem;
48
+ font-weight: bold;
49
+ color: var(--others-black);
27
50
  }
28
51
 
29
- .dropdown_input__link {
30
- color: var(--neutral-neutral-3);
31
- animation: newLine 0.5s;
32
-
33
- &:hover {
34
- color: var(--others-black);
35
- }
36
-
37
- &__emphasis {
38
- font-style: normal;
39
- font-weight: normal;
40
- color: var(--others-black);
41
- }
42
-
43
- &--all {
44
- font-weight: bold;
45
- animation: none;
52
+ .dropdown_input {
53
+ .search {
54
+ width: 100%;
55
+ margin: 0;
46
56
  }
47
57
  }
48
58
  }
49
59
  }
50
-
51
- @keyframes newLine {
52
- 0% {
53
- opacity: 0;
54
- line-height: 0rem;
55
- }
56
-
57
- 100% {
58
- opacity: 1;
59
- line-height: 1.5rem;
60
- }
61
- }
62
60
  `;