diff --git a/content/docs/advanced/React.md b/content/docs/advanced/React.md index 3323ffab5..0bc187a5d 100644 --- a/content/docs/advanced/React.md +++ b/content/docs/advanced/React.md @@ -6,7 +6,7 @@ sectionid: docs permalink: advanced/react.html prev: advanced/customquery.html prevTitle: "Defining Custom Queries" -next: advanced/reactivecomponent.html +next: advanced/reactivecomponentindepth.html nextTitle: "Reactive Component" redirect_from: - 'advanced/react' diff --git a/content/docs/advanced/ReactiveComponent.md b/content/docs/advanced/ReactiveComponent.md index 3e61982c0..a7c47afa6 100644 --- a/content/docs/advanced/ReactiveComponent.md +++ b/content/docs/advanced/ReactiveComponent.md @@ -1,16 +1,16 @@ --- -id: reactivecomponent +id: reactivecomponentindepth title: "Reactive Component" layout: docs sectionid: reactivecomponent -permalink: advanced/reactivecomponent.html +permalink: advanced/reactivecomponentindepth.html prev: react.html prevTitle: "React Prop" next: ssr.html nextTitle: "Server Side Rendering" redirect_from: - - "advanced/reactivecomponent" - - "reactivecomponent" + - "advanced/reactivecomponentindepth" + - "reactivecomponentindepth" --- We have built this library keeping you, the developer, in mind. If you're here, it is obvious that you want to create a custom component that is reactive in nature. Perhaps, you already have a component in your design kit and want it to work seamlessly with Reactivesearch. diff --git a/content/docs/advanced/SSR.md b/content/docs/advanced/SSR.md index 90b94226e..b8c5ea16d 100644 --- a/content/docs/advanced/SSR.md +++ b/content/docs/advanced/SSR.md @@ -4,7 +4,7 @@ title: "Server Side Rendering" layout: docs sectionid: docs permalink: advanced/ssr.html -prev: reactivecomponent.html +prev: reactivecomponentindepth.html prevTitle: "Reactive Component" next: componentsusage.html nextTitle: "Components Usage" diff --git a/content/docs/advanced/nav.yml b/content/docs/advanced/nav.yml index b590268d1..f3dee901c 100644 --- a/content/docs/advanced/nav.yml +++ b/content/docs/advanced/nav.yml @@ -59,26 +59,26 @@ title: Props href: /advanced/react.html#props forceInternal: true - - id: reactivecomponent + - id: reactivecomponentindepth title: Reactive Component - href: /advanced/reactivecomponent.html + href: /advanced/reactivecomponentindepth.html forceInternal: true subitems: - id: usage-with-defaultquery title: Usage with defaultQuery - href: /advanced/reactivecomponent.html#usage-with-defaultquery + href: /advanced/reactivecomponentindepth.html#usage-with-defaultquery forceInternal: true - id: usage-with-customquery title: Usage with customQuery - href: /advanced/reactivecomponent.html#usage-with-customquery + href: /advanced/reactivecomponentindepth.html#usage-with-customquery forceInternal: true - id: props title: Props - href: /advanced/reactivecomponent.html#props + href: /advanced/reactivecomponentindepth.html#props forceInternal: true - id: examples title: Examples - href: /advanced/reactivecomponent.html#examples + href: /advanced/reactivecomponentindepth.html#examples forceInternal: true - id: ssr title: Server Side Rendering diff --git a/content/docs/base-components/ReactiveComponent.md b/content/docs/base-components/ReactiveComponent.md new file mode 100644 index 000000000..4b02c6b95 --- /dev/null +++ b/content/docs/base-components/ReactiveComponent.md @@ -0,0 +1,155 @@ +--- +id: reactivecomponent +title: "Reactive Component" +layout: docs +sectionid: reactivecomponent +permalink: base-components/reactivecomponent.html +prev: selectedfilters.html +prevTitle: "SelectedFilters" +next: /list-components/singlelist.html +nextTitle: "List Components: SingleList" +redirect_from: + - 'basic-components/reactivecomponent.html' + - 'base-components/reactivecomponent' + - 'reactivecomponent' +--- + + +ReactiveComponent lets you connect any React UI component with an ElasticSearch query or an aggregation seamlessly. It can be used as a standalone component to integrate ElasticSearch queries into your frontend UI declaratively. It can also be used in conjunction with other ReactiveSearch components. Read more [here](/advanced/reactivecomponentindepth.html). + +> How does this work? +> +> `ReactiveComponent` supports a defaultQuery prop, which can take any ElasticSearch Query DSL object, and provides a callback onData prop which is called on successful query execution by ElasticSearch and can be used to create a side-effect in your app. There is also a render prop which can be used to render any React UI component of your choice which will have access to the hits and aggregations from the defaultQuery. + + +### Usage + +Let's suppose - we are building an e-commerce store for cars which displays a list of cars and 5 popular car brands in tabs UI as the user selects a tab the result gets updated with the cars of selected brand. Now if the user wants to select other brand from tab, the results should be updated to new selected brand. In this case, `ReactiveComponent` can be used with `defaultQuery` to achieve the desired behavior easily. + +After selecting value from `ReactiveComponent` we will need to update result component with items satisfying the value, to achieve this we can take use of `react` prop. You can read more about the prop [here](/advanced/react.html). + +Check demo [here](https://codesandbox.io/s/7zrj740oj6). + + +```js + ({ + aggs: { + 'brand.keyword': { + terms: { + field: 'brand.keyword', + order: { + _count: 'desc', + }, + size: 5, + }, + }, + }, + })} + render={data => { + return ; + }} +/> +``` + +Here `TabComponent` is responsible to render the Tabs UI and handle the switching between tabs and displaying selected filters. We are using `render` prop to display the component which provides an object with different parameters that can be used in rendering the UI and dispatching a new query. Fow switching the tab we will use `onClick` event to fire a new query. We will make use of the following paramateres provided by `render` method: + +- **aggregations** `Object` + `aggregations` prop contains the results from `aggs` Elasticsearch query of the component. +- **setQuery** `function` + `setQuery` function sets the query of the component. It takes an object param of shape: +```javascript + { + query: {}, // query of the component + value: '' // value of the component + } +``` +- **value** `any` +`value` contains the current value of the component (which can be set via `setQuery()` function). This is used for URLParams and SelectedFilters. + +**SelectedFilters with ReactiveComponent** +For showing selected filters we will use [`SelectedFilters`](/base-components/selectedfilters.html). When we use `ReactiveComponent` we will need to maintain `SelectedFilters` value manually. To clear the selected value of `ReactiveComponent` use `onClear` prop on `SelectedFilter` and pass `null` in `setQuery`. + + +**ReactiveComponent and React context** +If the CustomComponent contains multiple react components which need to access ElasticSearch data we can take use of react [`context`](https://reactjs.org/docs/context.html) in order to pass data through the component tree without having to pass props down manually at every level. We can refactor the above example to use multiple child components and pass the data using context. You can check the refactored app demo [here](https://codesandbox.io/s/o9popzr47y). + + +**ReactiveComponent with Ant Design Component** +You can also easily connect component from design system to index data using `ReactiveComponent`. Check the example [here](https://codesandbox.io/s/mmkjv990nj) which connects `Dropdown` component of `Antd` with index data. + +**ReactiveComponent Query using helper method** + +You can also take advantage of various ReactiveSearch components static method for generating query. So we our basically selecting a single tab so we can use `SingleList` static method to generate query as follow: + +```js + ({ + ...SingleList.generateQueryOptions({ + dataField: "brand.keyword", + size: 5, + sortBy: "count" + }) + })} + render={data => { + return ; + }} +/> +``` + + +### Props + +- **className** `String` + CSS class to be injected on the component container. +- **style** `Object` + CSS styles to be applied to the **DataSearch** component. +- **defaultQuery** `Function` + **returns** the default query to be applied to the component, as defined in Elasticsearch Query DSL. +- **customQuery** `Function` + **returns** the custom query to be applied to the component, as defined in Elasticsearch Query DSL. + Custom query can be used to change the component's behavior for its subscribers. +- **onQueryChange** `Function` + is a callback function which accepts component's **prevQuery** and **nextQuery** as parameters. It is called everytime the component's query changes. This prop is handy in cases where you want to generate a side-effect whenever the component's query would change. +- **onData** `Function` + callback function which provides `data`, `rawData` and `aggregations` as function params. +- **showFilter** `Boolean` [optional] + show as filter when a value is selected in a global selected filters view. Defaults to `true`. +- **filterLabel** `String` [optional] + An optional label to display for the component in the global selected filters view. This is only applicable if `showFilter` is enabled. Default value used here is `componentId`. +- **react** `Object` + `react` prop is available in components whose data view should reactively update when on or more dependent components change their states, e.g. [`ReactiveMap`](/map-components/reactivemap.html), [`ReactiveList`](/basic-components/reactivelist.html). + - **key** `String` + one of `and`, `or`, `not` defines the combining clause. + - **and** clause implies that the results will be filtered by matches from **all** of the associated component states. + - **or** clause implies that the results will be filtered by matches from **at least one** of the associated component states. + - **not** clause implies that the results will be filtered by an **inverse** match of the associated component states. + - **value** `String or Array or Object` + - `String` is used for specifying a single component by its `componentId`. + - `Array` is used for specifying multiple components by their `componentId`. + - `Object` is used for nesting other key clauses. + +- **URLParams** `Boolean` [optional] + enable creating a URL query string parameter based on the selected value of the list. This is useful for sharing URLs with the component state. Defaults to `false`. + +### Demo + + + +**ReactiveComponent with defaultQuery** +
+ + +**ReactiveComponent with defaultQuery and React context** +
+ + +**ReactiveComponent with defaultQuery and Antd component** +
+ + +A custom component using ReactiveComponent diff --git a/content/docs/base-components/SelectedFilters.md b/content/docs/base-components/SelectedFilters.md index abd3ea7c5..52a7e6026 100644 --- a/content/docs/base-components/SelectedFilters.md +++ b/content/docs/base-components/SelectedFilters.md @@ -4,8 +4,8 @@ title: "SelectedFilters" layout: docs sectionid: docs permalink: base-components/selectedfilters.html -next: /list-components/singlelist.html -nextTitle: "List Components: SingleList" +next: reactivecomponent.html +nextTitle: "Reactive Component" redirect_from: - 'basic-components/selectedfilters.html' - 'base-components/selectedfilters' diff --git a/content/docs/base-components/nav.yml b/content/docs/base-components/nav.yml index 346c708c7..a2d7b586e 100644 --- a/content/docs/base-components/nav.yml +++ b/content/docs/base-components/nav.yml @@ -29,3 +29,20 @@ title: Examples href: /base-components/selectedfilters.html#examples forceInternal: true + - id: reactivecomponent + title: Reactive Component + href: /base-components/reactivecomponent.html + forceInternal: true + subitems: + - id: usage + title: Usage + href: /base-components/reactivecomponent.html#usage + forceInternal: true + - id: props + title: Props + href: /base-components/reactivecomponent.html#props + forceInternal: true + - id: demo + title: Demo + href: /base-components/reactivecomponent.html#demo + forceInternal: true diff --git a/yarn.lock b/yarn.lock index a5ebd9507..b515b1717 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5188,7 +5188,7 @@ graphql@0.10.5: graphql@^0.11.3, graphql@^0.11.7: version "0.11.7" - resolved "https://registry.npmjs.org/graphql/-/graphql-0.11.7.tgz#e5abaa9cb7b7cccb84e9f0836bf4370d268750c6" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.11.7.tgz#e5abaa9cb7b7cccb84e9f0836bf4370d268750c6" integrity sha512-x7uDjyz8Jx+QPbpCFCMQ8lltnQa4p4vSYHx6ADe8rVYRTdsyhCJbvSty5DAsLVmU6cGakl+r8HQYolKHxk/tiw== dependencies: iterall "1.1.3"