Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Geolocation component #336

Merged
merged 13 commits into from
Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const parameters = {
'AlternativeVerticals',
'SpellCheck',
'ResultsCount',
'Geolocation',
'LocationBias',
oshi97 marked this conversation as resolved.
Show resolved Hide resolved
'Dropdown'
]
Expand Down
26 changes: 26 additions & 0 deletions docs/search-ui-react.geolocation_2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [Geolocation\_2](./search-ui-react.geolocation_2.md)

## Geolocation\_2() function

A React Component which collects location information to create a location filter and perform a new search.

<b>Signature:</b>

```typescript
export declare function Geolocation({ geolocationOptions, radius, label, GeolocationIcon, handleClick, customCssClasses, }: GeolocationProps): JSX.Element | null;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| { geolocationOptions, radius, label, GeolocationIcon, handleClick, customCssClasses, } | [GeolocationProps](./search-ui-react.geolocationprops.md) | |

<b>Returns:</b>

JSX.Element \| null

A react component for geolocation

11 changes: 11 additions & 0 deletions docs/search-ui-react.geolocationcssclasses.button.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationCssClasses](./search-ui-react.geolocationcssclasses.md) &gt; [button](./search-ui-react.geolocationcssclasses.button.md)

## GeolocationCssClasses.button property

<b>Signature:</b>

```typescript
button?: string;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationCssClasses](./search-ui-react.geolocationcssclasses.md) &gt; [geolocationContainer](./search-ui-react.geolocationcssclasses.geolocationcontainer.md)

## GeolocationCssClasses.geolocationContainer property

<b>Signature:</b>

```typescript
geolocationContainer?: string;
```
11 changes: 11 additions & 0 deletions docs/search-ui-react.geolocationcssclasses.iconcontainer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationCssClasses](./search-ui-react.geolocationcssclasses.md) &gt; [iconContainer](./search-ui-react.geolocationcssclasses.iconcontainer.md)

## GeolocationCssClasses.iconContainer property

<b>Signature:</b>

```typescript
iconContainer?: string;
```
22 changes: 22 additions & 0 deletions docs/search-ui-react.geolocationcssclasses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationCssClasses](./search-ui-react.geolocationcssclasses.md)

## GeolocationCssClasses interface

The CSS class interface for the Geolocation component.

<b>Signature:</b>

```typescript
export interface GeolocationCssClasses
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [button?](./search-ui-react.geolocationcssclasses.button.md) | string | <i>(Optional)</i> |
| [geolocationContainer?](./search-ui-react.geolocationcssclasses.geolocationcontainer.md) | string | <i>(Optional)</i> |
| [iconContainer?](./search-ui-react.geolocationcssclasses.iconcontainer.md) | string | <i>(Optional)</i> |

13 changes: 13 additions & 0 deletions docs/search-ui-react.geolocationprops.customcssclasses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationProps](./search-ui-react.geolocationprops.md) &gt; [customCssClasses](./search-ui-react.geolocationprops.customcssclasses.md)

## GeolocationProps.customCssClasses property

CSS classes for customizing the component styling.

<b>Signature:</b>

```typescript
customCssClasses?: GeolocationCssClasses;
```
13 changes: 13 additions & 0 deletions docs/search-ui-react.geolocationprops.geolocationicon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationProps](./search-ui-react.geolocationprops.md) &gt; [GeolocationIcon](./search-ui-react.geolocationprops.geolocationicon.md)

## GeolocationProps.GeolocationIcon property

Custom icon component to display along with the button.

<b>Signature:</b>

```typescript
GeolocationIcon?: React.FunctionComponent;
```
13 changes: 13 additions & 0 deletions docs/search-ui-react.geolocationprops.geolocationoptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationProps](./search-ui-react.geolocationprops.md) &gt; [geolocationOptions](./search-ui-react.geolocationprops.geolocationoptions.md)

## GeolocationProps.geolocationOptions property

Configuration used when collecting the user's location. Definition: [https://w3c.github.io/geolocation-api/\#position\_options\_interface](https://w3c.github.io/geolocation-api/#position_options_interface)<!-- -->.

<b>Signature:</b>

```typescript
geolocationOptions?: PositionOptions;
```
13 changes: 13 additions & 0 deletions docs/search-ui-react.geolocationprops.handleclick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationProps](./search-ui-react.geolocationprops.md) &gt; [handleClick](./search-ui-react.geolocationprops.handleclick.md)

## GeolocationProps.handleClick property

A function which is called when the geolocation button is clicked, after user's position is successfully determined.

<b>Signature:</b>

```typescript
handleClick?: (position: GeolocationPosition) => void;
```
13 changes: 13 additions & 0 deletions docs/search-ui-react.geolocationprops.label.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationProps](./search-ui-react.geolocationprops.md) &gt; [label](./search-ui-react.geolocationprops.label.md)

## GeolocationProps.label property

The label for the button. Defaults to 'Use my location'.

<b>Signature:</b>

```typescript
label?: string;
```
25 changes: 25 additions & 0 deletions docs/search-ui-react.geolocationprops.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationProps](./search-ui-react.geolocationprops.md)

## GeolocationProps interface

The props for the Geolocation component.

<b>Signature:</b>

```typescript
export interface GeolocationProps
```

## Properties

| Property | Type | Description |
| --- | --- | --- |
| [customCssClasses?](./search-ui-react.geolocationprops.customcssclasses.md) | [GeolocationCssClasses](./search-ui-react.geolocationcssclasses.md) | <i>(Optional)</i> CSS classes for customizing the component styling. |
| [GeolocationIcon?](./search-ui-react.geolocationprops.geolocationicon.md) | React.FunctionComponent | <i>(Optional)</i> Custom icon component to display along with the button. |
| [geolocationOptions?](./search-ui-react.geolocationprops.geolocationoptions.md) | PositionOptions | <i>(Optional)</i> Configuration used when collecting the user's location. Definition: [https://w3c.github.io/geolocation-api/\#position\_options\_interface](https://w3c.github.io/geolocation-api/#position_options_interface)<!-- -->. |
| [handleClick?](./search-ui-react.geolocationprops.handleclick.md) | (position: GeolocationPosition) =&gt; void | <i>(Optional)</i> A function which is called when the geolocation button is clicked, after user's position is successfully determined. |
| [label?](./search-ui-react.geolocationprops.label.md) | string | <i>(Optional)</i> The label for the button. Defaults to 'Use my location'. |
| [radius?](./search-ui-react.geolocationprops.radius.md) | number | <i>(Optional)</i> The radius, in miles, around the user's location to find results. Defaults to 50. If location accuracy is low, a larger radius may be used automatically. |

13 changes: 13 additions & 0 deletions docs/search-ui-react.geolocationprops.radius.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@yext/search-ui-react](./search-ui-react.md) &gt; [GeolocationProps](./search-ui-react.geolocationprops.md) &gt; [radius](./search-ui-react.geolocationprops.radius.md)

## GeolocationProps.radius property

The radius, in miles, around the user's location to find results. Defaults to 50. If location accuracy is low, a larger radius may be used automatically.

<b>Signature:</b>

```typescript
radius?: number;
```
3 changes: 3 additions & 0 deletions docs/search-ui-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
| [executeSearch(searchActions)](./search-ui-react.executesearch.md) | Executes a universal/vertical search. |
| [FilterDivider({ className })](./search-ui-react.filterdivider.md) | A divider component used to separate NumericalFacets, HierarchicalFacets, StandardFacets, and StaticFilters. |
| [FilterSearch({ searchFields, label, placeholder, searchOnSelect, onSelect, sectioned, customCssClasses })](./search-ui-react.filtersearch.md) | A component which allows a user to search for filters associated with specific entities and fields. |
| [Geolocation\_2({ geolocationOptions, radius, label, GeolocationIcon, handleClick, customCssClasses, })](./search-ui-react.geolocation_2.md) | A React Component which collects location information to create a location filter and perform a new search. |
| [getSearchIntents(searchActions)](./search-ui-react.getsearchintents.md) | Get search intents of the current query stored in headless using autocomplete request. |
| [getUserLocation(geolocationOptions)](./search-ui-react.getuserlocation.md) | Retrieves user's location using navigator.geolocation API. |
| [HierarchicalFacets({ searchOnChange, collapsible, defaultExpanded, includedFieldIds, customCssClasses, delimiter, showMoreLimit })](./search-ui-react.hierarchicalfacets.md) | A component that displays hierarchical facets, in a tree level structure, applicable to the current vertical search. |
Expand Down Expand Up @@ -64,6 +65,8 @@
| [FilterOptionConfig](./search-ui-react.filteroptionconfig.md) | The configuration data for a field value filter option. |
| [FilterSearchCssClasses](./search-ui-react.filtersearchcssclasses.md) | The CSS class interface for [FilterSearch()](./search-ui-react.filtersearch.md)<!-- -->. |
| [FilterSearchProps](./search-ui-react.filtersearchprops.md) | The props for the [FilterSearch()](./search-ui-react.filtersearch.md) component. |
| [GeolocationCssClasses](./search-ui-react.geolocationcssclasses.md) | The CSS class interface for the Geolocation component. |
| [GeolocationProps](./search-ui-react.geolocationprops.md) | The props for the Geolocation component. |
| [HierarchicalFacetDisplayCssClasses](./search-ui-react.hierarchicalfacetdisplaycssclasses.md) | The CSS class interface for HierarchicalFacetDisplay. |
| [HierarchicalFacetsCssClasses](./search-ui-react.hierarchicalfacetscssclasses.md) | The CSS class interface for [HierarchicalFacets()](./search-ui-react.hierarchicalfacets.md)<!-- -->. |
| [HierarchicalFacetsProps](./search-ui-react.hierarchicalfacetsprops.md) | Props for the [HierarchicalFacets()](./search-ui-react.hierarchicalfacets.md) component. |
Expand Down
24 changes: 24 additions & 0 deletions etc/search-ui-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,30 @@ export interface FilterSearchProps {
// @public
export type FocusedItemData = Record<string, unknown>;

// @public
function Geolocation_2({ geolocationOptions, radius, label, GeolocationIcon, handleClick, customCssClasses, }: GeolocationProps): JSX.Element | null;
export { Geolocation_2 as Geolocation }

// @public
export interface GeolocationCssClasses {
// (undocumented)
button?: string;
// (undocumented)
geolocationContainer?: string;
// (undocumented)
iconContainer?: string;
}

// @public
export interface GeolocationProps {
customCssClasses?: GeolocationCssClasses;
GeolocationIcon?: React.FunctionComponent;
geolocationOptions?: PositionOptions;
handleClick?: (position: GeolocationPosition) => void;
label?: string;
radius?: number;
}

// @public
export function getSearchIntents(searchActions: SearchActions): Promise<SearchIntent[] | undefined>;

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@
"restoreMocks": true
},
"dependencies": {
"lodash": "^4.17.21",
"@microsoft/api-documenter": "^7.15.3",
"@microsoft/api-extractor": "^7.19.4",
"@reach/auto-id": "^0.18.0",
"@restart/ui": "^1.0.1",
"@tailwindcss/forms": "^0.5.0",
"@yext/analytics": "^0.2.0-beta.3",
"classnames": "^2.3.1",
"lodash": "^4.17.21",
yen-tt marked this conversation as resolved.
Show resolved Hide resolved
"mapbox-gl": "^2.9.2",
"prop-types": "^15.8.1",
"react-collapsed": "^3.3.0",
Expand Down
4 changes: 2 additions & 2 deletions src/components/AppliedFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface AppliedFiltersProps {
customCssClasses?: AppliedFiltersCssClasses
}

const DEFUALT_HIDDEN_FIELDS = ['builtin.entityType'];
const DEFAULT_HIDDEN_FIELDS = ['builtin.entityType'];

/**
* A component that displays a list of filters applied to the current vertical
Expand All @@ -61,7 +61,7 @@ export function AppliedFilters(props: AppliedFiltersProps): JSX.Element {
const isLoading = useSearchState(state => state.searchStatus.isLoading);

const {
hiddenFields = DEFUALT_HIDDEN_FIELDS,
hiddenFields = DEFAULT_HIDDEN_FIELDS,
customCssClasses = {},
hierarchicalFacetsDelimiter = DEFAULT_HIERARCHICAL_DELIMITER,
hierarchicalFacetsFieldIds
Expand Down
91 changes: 91 additions & 0 deletions src/components/Geolocation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { useComposedCssClasses } from '../hooks/useComposedCssClasses';
import { useState } from 'react';
import LoadingIndicator from '../icons/LoadingIndicator';
import { YextIcon } from '../icons/YextIcon';
import { useGeolocationHandler } from '../hooks/useGeolocationHandler';

/**
* The CSS class interface for the Geolocation component.
Copy link
Contributor Author

@yen-tt yen-tt Nov 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot use {@link Geolocation} here due to an issue with API Extractor adding _2 suffix to duplicate interface/class names. In search-ui-react, Geolocation from Typescript's "lib.dom.d.ts" file conflicts with Geolocation component.
See: microsoft/rushstack#2534 and microsoft/rushstack#2976
Open PR: microsoft/rushstack#2608

Screen Shot 2022-11-16 at 12 15 08 PM

It does make it a little odd in the doc but the signature of the component is correct. What to know if the team have any thoughts on this. A work around, which is a little hacky, is to add a script to manually update the files generated from API extractor.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with it, the api extractor docs aren't made to be extremely beginner friendly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we link to Geolocation_2? or would that not resolve correctly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would link correctly in the doc pages but we would see this in search-ui-react.api.md file:
Screen Shot 2022-11-16 at 3 28 29 PM

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh ok, I'm fine leaving it without a link

*
* @public
*/
export interface GeolocationCssClasses {
geolocationContainer?: string,
button?: string,
iconContainer?: string
}

const builtInCssClasses: Readonly<GeolocationCssClasses> = {
geolocationContainer: 'text-sm text-neutral text-center justify-center items-center flex flex-row',
button: 'text-primary font-semibold hover:underline focus:underline',
iconContainer: 'w-4 ml-2'
};

/**
* The props for the Geolocation component.
*
* @public
*/
export interface GeolocationProps {
/**
* Configuration used when collecting the user's location.
* Definition: {@link https://w3c.github.io/geolocation-api/#position_options_interface}.
*/
geolocationOptions?: PositionOptions,
/**
* The radius, in miles, around the user's location to find results. Defaults to 50.
* If location accuracy is low, a larger radius may be used automatically.
*/
radius?: number,
/** The label for the button. Defaults to 'Use my location'. */
label?: string,
/** Custom icon component to display along with the button. */
GeolocationIcon?: React.FunctionComponent,
/**
* A function which is called when the geolocation button is clicked,
* after user's position is successfully determined.
*/
handleClick?: (position: GeolocationPosition) => void,
/** CSS classes for customizing the component styling. */
customCssClasses?: GeolocationCssClasses
}

/**
* A React Component which collects location information to create a
* location filter and perform a new search.
*
* @public
*
* @param props - {@link GeolocationProps}
* @returns A react component for geolocation
*/
export function Geolocation({
geolocationOptions,
radius = 50,
label = 'Use my location',
//TODO: replace default icon with SVG create from design team
GeolocationIcon = YextIcon,
handleClick,
customCssClasses,
}: GeolocationProps): JSX.Element | null {
const [isFetchingLocation, setIsFetchingLocation] = useState<boolean>(false);
const cssClasses = useComposedCssClasses(builtInCssClasses, customCssClasses);

const handleGeolocationClick = useGeolocationHandler({
setIsFetchingLocation,
geolocationOptions,
radius,
handleUserPosition: handleClick
});

return (
<div className={cssClasses.geolocationContainer}>
<button className={cssClasses.button} onClick={handleGeolocationClick}>
{label}
oshi97 marked this conversation as resolved.
Show resolved Hide resolved
</button>
<div className={cssClasses.iconContainer}>
{isFetchingLocation ? <LoadingIndicator /> : <GeolocationIcon />}
</div>
</div>
);
}
6 changes: 6 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ export {
LocationBiasProps
} from './LocationBias';

export {
Geolocation,
GeolocationCssClasses,
GeolocationProps
} from './Geolocation';

export {
AppliedFilters,
AppliedFiltersCssClasses,
Expand Down
Loading