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

children #43

Open
globallyunique opened this issue Oct 31, 2024 · 6 comments
Open

children #43

globallyunique opened this issue Oct 31, 2024 · 6 comments

Comments

@globallyunique
Copy link

globallyunique commented Oct 31, 2024

I'm trying to convert the React components of the elastic-search UI framework to use in a svelte app. Several of the components need the children passed as a function to the parent component. I don't want to change the code of the elastic search components. The specific place I'm stuck is the WithSearch component shown below. Can you point me at an example of passing child html components to a React parent or suggest how I pass SearchBox children to WithSearch after I've done: const react = sveltify({ SearchBox, WithSearch, SearchProvider }); instead of using the function the way it's done in this React code? I thought it was with an array of snippets but I can't see how to make that work.

  <**WithSearch** mapContextToProps={({ wasSearched }) => ({ wasSearched })}>
    {({ wasSearched }) => {
      return (
        <div className="App">
          <ErrorBoundary>
            <Layout
              header={
                <**SearchBox**
                  autocompleteMinimumCharacters={3}
                  autocompleteResults={{
                    linkTarget: "_blank",
                    sectionTitle: "Results",
                    titleField: "title",
                    urlField: "url",
                    shouldTrackClickThrough: true
                  }}
                  autocompleteSuggestions={true}
                  debounceLength={0}
                />
              }
              sideContent={
                <div>
                  {wasSearched && <Sorting label={"Sort by"} sortOptions={[]} />}
                  <Facet key={"1"} field={"genre.keyword"} label={"genre"} />
                  <Facet key={"2"} field={"actors.keyword"} label={"actors"} />
                  <Facet key={"3"} field={"directors.keyword"} label={"directors"} />
                  <Facet key={"4"} field={"released"} label={"released"} />
                  <Facet key={"4"} field={"imdbRating"} label={"imdb rating"} />
                </div>
              }
              bodyContent={<Results shouldTrackClickThrough={true} />}
              bodyHeader={
                <React.Fragment>
                  {wasSearched && <PagingInfo />}
                  {wasSearched && <ResultsPerPage />}
                </React.Fragment>
              }
              bodyFooter={<Paging />}
            />
          </ErrorBoundary>
        </div>
      );
    }}
  </WithSearch>
@bfanger
Copy link
Owner

bfanger commented Oct 31, 2024

In version 2.0.2, when using the children attribute, the value is passed directly to the React component:

The following React code:

<WithSearch
  mapContextToProps={({ wasSearched }) => ({ wasSearched })}
>
  {({ wasSearched }) => <div className="App" />
</WithSearch>

Can now be written in Svelte as:

<react.WithSearch
  mapContextToProps={({ wasSearched }) => ({ wasSearched })} 
  children={({ wasSearched }) => createElement("div", { className: "App" })}
/>

Note that aside from the children attribute the JSX is written using createElement notation.

Not ideal, maybe the preprocessor can do something smarter with snippets in the future.

@globallyunique
Copy link
Author

I upgraded to 2.0.2. For this code:

`<react.SearchProvider config={config}>
  <react.WithSearch
    mapContextToProps={({ wasSearched }: any) => ({ wasSearched })} 
    children={({ wasSearched }:any) => createElement("div", { className: "App" })}
  />
</react.SearchProvider>`

I get this error from the 'children='. Am I supposed to be creating a Snippet somewhere?

 `Type '({ wasSearched }: any) => React.DetailedReactHTMLElement<{ className: string; }, HTMLElement>' is not assignable to type 'Snippet<[]>'.
Target signature provides too few arguments. Expected 1 or more, but got 0.ts(2322)`

@bfanger
Copy link
Owner

bfanger commented Nov 1, 2024

No, React doesn't understand Snippets, are you still using const react = sveltify({ WithSearch }); ?
(The typing did work on my machine in src/routes/render-prop/+page.svelte )

But could be I'm missing some Typescript config in the published package.json, wrap the children into an

( ...code... ) as any

for now.

@globallyunique
Copy link
Author

Yes I'm still doing react = sveltify({ WithSearch });

I still get the error. Is it perhaps because your 'Search' in src/routes/render-prop/+page.svelte is a real svelte component and the WithSearch I'm trying to use is some kind of "a Higher Order Component that wraps a component and injects state and actions from Search UI, effectively connecting it to Search UI", see: https://github.com/elastic/search-ui/blob/main/packages/react-search-ui/src/withSearch.tsx.

Do I need to make it into a svelte component that I then reference as children?

bfanger added a commit that referenced this issue Nov 2, 2024
@bfanger
Copy link
Owner

bfanger commented Nov 2, 2024

I've experimented with elastic-search and I suggest creating a React component named SearchPage:

// SearchPage.tsx
export default function SearchPage() {
  return (
    <SearchProvider config={config}>
      <WithSearch
        mapContextToProps={({ wasSearched }) => ({
          wasSearched,
        })}
      >
        {({ wasSearched }) => {
          return (
            <div className="App">
            ...

which you can then use inside your Svelte application:

<script lang="ts">
  import SearchPage from "./SearchPage";

  const react = sveltify({ SearchPage });
</script>

<react.SearchPage />

This allows using the provided React components from elastic-search inside SearchPage without the caveats that are caused by the svelte bridges or limitation of no JSX in a svelte file.

And where you want something custom, you can use svelte components inside the SearchPage.tsx by converting them to react components:

import { reactify } from "svelte-preprocess-react";
import MyComponentSvelte from "./MyComponent.svelte";
const MyComponent = reactify(MyComponentSvelte);

@globallyunique
Copy link
Author

globallyunique commented Nov 3, 2024

It works as you said to code it. THANKS for all the help and the great package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants