<div class="search-field search-field--big">
    <div class="search-field__field">
        <input type="search" class="search-field__input" />
        <button class="search-field__submit" type="submit"></button>
    </div>
</div>
<div class="search-field {{ getmodifiers modifiers "search-field" }}">
    <div class="search-field__field">
        <input type="search" class="search-field__input" {{{getattributes attributes}}} />
        <button class="search-field__submit" type="submit"></button>
    </div>
</div>
{
  "modifiers": [
    "big"
  ]
}
  • Content:
    import React from 'react';
    
    const Geolocation = (props) => {
    
        const requestIpLocation = async (cb) => {
            try {
                const res = await fetch('https://ipinfo.io/geo');
                const data = await res.json();
                cb(data.loc.split(','));
            } catch (e) {
                console.warn(e);
            }
        };
    
        const requestGeolocation = async (e) => {
            e.preventDefault();
    
            if (!navigator.geolocation) {
                return requestIpLocation();
            }
            const cords = await new Promise((resolve) => {
                navigator.geolocation.getCurrentPosition((position) => {
                    resolve([position.coords.latitude, position.coords.longitude]);
                }, () => requestIpLocation(resolve));
            });
            props.onGeolocation(cords);
        };
    
        return (
            <button
                className="search-field__geolocation"
                onClick={requestGeolocation}
            />
        );
    };
    
    export default Geolocation;
    
  • URL: /components/raw/search-field/Geolocation.jsx
  • Filesystem Path: src/components/search-field/Geolocation.jsx
  • Size: 976 Bytes
  • Content:
    import React from 'react';
    import Downshift from 'downshift';
    import PropTypes from 'prop-types';
    import Icon from '../icon';
    
    const SearchField = (props) => {
        const {
            preSelectedFirstItem,
            onInputChange,
            onSubmit,
            onChange,
            itemStyle,
            items,
            itemComponent,
            className,
            inputPlaceholder,
            seeMoreLink,
            seeMoreText
        } = props;
    
        function stateReducer(state, changes) {
            // this prevents the menu from being closed when the user
            // selects an item with a keyboard or mouse
            switch (changes.type) {
                case Downshift.stateChangeTypes.blurInput:
                    return {
                        ...changes,
                        ...(items[state.highlightedIndex] && { inputValue: items[state.highlightedIndex].value }),
                        ...(typeof onSubmit !== 'undefined' && { inputValue: state.inputValue }),
                        ...(onSubmit === 'undefined' && { highlightedIndex: state.highlightedIndex })
                    };
            default:
                return changes;
            }
        }
    
        return (
            <form onSubmit={(e) => onSubmit && onSubmit(e)}>
                <Downshift
                    itemToString={item => (item ? item.value : ``)}
                    defaultHighlightedIndex={preSelectedFirstItem ? 0 : null}
                    stateReducer={stateReducer}
                    {...props}
                >
                    {({
                        getInputProps,
                        getItemProps,
                        getMenuProps,
                        isOpen,
                        inputValue,
                        highlightedIndex
                    }) => (
                        <div className={`search-field ${className}`}>
                            <div className="search-field__field">
                                <input
                                    name="q"
                                    className="search-field__input"
                                    placeholder={inputPlaceholder}
                                    type="search"
                                    {...getInputProps({
                                        onChange: e => onInputChange(e)
                                    })}
                                />
                                <button
                                    className="search-field__submit"
                                    type="submit"
                                    onClick={(e) => {
                                        if (typeof items[highlightedIndex] !== 'undefined') {
                                            onChange(items[highlightedIndex]);
                                            e.preventDefault();
                                        } else if (typeof onSubmit === 'undefined') {
                                            e.preventDefault();
                                        }
                                    }}
                                />
                                {props.children}
                            </div>
                            {isOpen && inputValue.length > 0 && items.length > 0
                            ? (
                                <React.Fragment>
                                    <ul
                                        className={`search-field__autocomplete ${isOpen &&
                                            `search-field__autocomplete--is-open`}`}
                                        {...getMenuProps()}
                                    >
                                        {items.map((item, index) => (
                                                <li
                                                    className={`search-field__item ${highlightedIndex ===
                                                        index &&
                                                        `search-field__item--selected`} ${itemStyle}`}
                                                    {...getItemProps({
                                                        key: index,
                                                        index,
                                                        item
                                                    })}
                                                >
                                                    {itemComponent(item)}
                                                </li>
                                            ))}
                                        {
                                            seeMoreLink && seeMoreLink.length > 0 &&
                                            <li className='search-field__item search-field__item--link-holder'>
                                                <a className='search-field__item--link' href={`${seeMoreLink}?qp=${inputValue}`}>
                                                    <span>{seeMoreText}</span>
                                                    <Icon icon='chevron-right' additionalClasses="search-field__item--icon" />
                                                </a>
                                            </li>
                                        }
                                    </ul>
                                </React.Fragment>
                            ) : null}
                        </div>
                    )}
                </Downshift>
            </form>
        );
    };
    
    SearchField.propTypes = {
        onInputChange: PropTypes.func,
        onSubmit: PropTypes.func,
        itemStyle: PropTypes.string,
        items: PropTypes.array.isRequired,
        itemComponent: PropTypes.func,
        className: PropTypes.string,
        inputPlaceholder: PropTypes.string,
        preSelectedFirstItem: PropTypes.bool,
        seeMoreLink: PropTypes.string
    };
    
    SearchField.defaultProps = {
        onInputChange: () => {},
        itemStyle: '',
        className: '',
        preSelectedFirstItem: true,
        seeMoreLink: ''
    };
    
    export default SearchField;
    
  • URL: /components/raw/search-field/SearchField.jsx
  • Filesystem Path: src/components/search-field/SearchField.jsx
  • Size: 5.7 KB
  • Content:
    import SearchField from './SearchField';
    export { default as Geolocation } from './Geolocation';
    
    export default SearchField;
    
  • URL: /components/raw/search-field/index.js
  • Filesystem Path: src/components/search-field/index.js
  • Size: 126 Bytes
  • Content:
    $height-big: size(8);
    $height-small: size(6);
    
    .search-field {
        width: 100%;
        position: relative;
        margin-bottom: size(4);
    
        &--big {
            @include breakpoint-classes {
                @include breakpoint($s) {
                    .search-field__input, .search-field__submit, .search-field__geolocation {
                        height: $height-big;
                    }
                    .search-field__submit, .search-field__geolocation {
                        width: $height-big;
                        background-size: calc(100% - #{size(3)});
                    }
                }
            }
        }
    }
    
    
    .search-field__field {
        display: flex;
    }
    
    .search-field__input {
        border: $color-gray-2 1px solid;
        padding: size(2) size(3);
        line-height: size(3);
        height: $height-small;
        display: flex;
        flex: 1;
        font-size: size(2.5);
        border-radius: size(.5) 0 0 size(.5);
        border-right: 0;
        background: $color-white;
        width: 100%;
    
        @include placeholder {
            color: $color-gray-3;
            font-size: size(2.5);
            opacity: 1;
        }
    
        &::-webkit-input-placeholder {
            transform: translateY(0);
            -webkit-transform: translateY(2px);
        }
    
        &::-webkit-search-decoration,
        &::-webkit-search-cancel-button,
        &::-webkit-search-results-button,
        &::-webkit-search-results-decoration {
            display: none;
        }
    }
    
    // buttons
    .search-field__geolocation, .search-field__submit {
        width: $height-small;
        height: $height-small;
        min-width: auto;
    }
    
    .search-field__geolocation {
        background: url(./img/icon-crosshair.svg) $color-gray-1 no-repeat center;
        border-radius: size(.5);
        background-size: calc(100% - #{size(2)});
        margin-left: size(1);
    
        @include breakpoint($m) {
            margin-left: size(2);
        }
    }
    
    .search-field__submit {
        background: url(./img/icon-search.svg) no-repeat center;
        border-radius: 0 size(.5) size(.5) 0;
        background-size: calc(100% - #{size(2)});
        background-color: $color-green-dark;
    
        &:hover {
            cursor: pointer;
        }
    
        @include color-theme {
            background-color: $arg-theme-color;
        }
    }
    
    .search-field__autocomplete {
        position: absolute;
        width: 100%;
        border-radius: size(.5);
        border: $color-gray-2 1px solid;
        visibility: hidden;
        list-style: none;
        padding: 0;
        margin: 0;
        text-align: left;
        top: 100%;
        z-index: 1;
    
        &--is-open {
            visibility: visible;
        }
    }
    
    .search-field__item {
        border-bottom: 1px solid $color-gray-2;
        background-color: $color-white;
        display: flex;
        align-items: center;
    
        &:nth-child(odd) {
            background-color: $color-gray-1;
        }
    
        &--selected {
            background-color: $color-green-pale !important;
        }
    
        &--link-holder {
            justify-content: center;
            padding: size(2) size(3);
        }
    
        &--link {
            color: $color-green;
            display: inline-block;
            vertical-align: top;
            position: relative;
            padding-right: size(2);
    
        }
    
        &--icon {
            position: absolute;
            top: 50%;
            right: 0;
            width: 16px;
            height: 16px;
            vertical-align: middle;
            fill: currentColor;
            transform: translateY(-50%);
        }
    }
    
    .search-widget__spinner {
        position: absolute;
        top:50%;
        transform: translateY(-50%);
        right: 70px;
    }
    
  • URL: /components/raw/search-field/search-field.scss
  • Filesystem Path: src/components/search-field/search-field.scss
  • Size: 3.4 KB

No notes defined.