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

Provide a helper that conditionally renders if a field is filled #199

Open
angeloashmore opened this issue Nov 30, 2023 · 0 comments
Open
Labels
enhancement New feature or request

Comments

@angeloashmore
Copy link
Member

angeloashmore commented Nov 30, 2023

Is your feature request related to a problem? Please describe.

Webpages commonly need to conditionally render content only if a content field has a value. For example, you may only want to render an <h1> element if a Title field has a value.

This can currently be accomplished with @prismicio/client's isFilled set of helpers:

import { isFilled } from "@prismicio/client";
import { PrismicRichText } from "@prismicio/react";

export function MySlice({ slice }) {
  return (
    <section>
      {isFilled.richText(slice.primary.title) ? (
        <h1>
          <PrismicRichText field={slice.primary.title} />
        </h1>
      ) : (
        <div>Some fallback</div>
      )}
    </section>
  );
}

While the above code works, it is verbose and feels procedural.

Describe the solution you'd like

A dedicated React component that accomplishes the same as above in a declarative way would be an improvement.

import { IsFilled, PrismicRichText } from "@prismicio/react";

export function MySlice({ slice }) {
  return (
    <section>
      <IsFilled.RichText
        field={slice.primary.title}
        fallback={<div>Some fallback</div>}
      >
        <h1>
          <PrismicRichText field={slice.primary.title} />
        </h1>
      </IsFilled.RichText>
    </section>
  );
}

Although the above code is not more concise than the isFilled.richText() version (it is actually more characters), it is easier to read and edit. The React syntax fits in with the surrounding code better than the ternarry and isFilled helper.

This solution can be ported to other integration libraries, like @prismicio/vue and @prismicio/svelte.

Type Narrowing

isFilled narrows the type of the provided field. After narrowing the field, you can be sure that the field is filled, and you will get autocompletion that suggests that.

When using JSX, you will not get that effect because TypeScript doesn't support type predicates in JSX (see Using type predicates).

To get around that limitation, we may need to introduce a dedicated render prop (render={(field) => {...}}) or render prop via children (i.e. (field) => {...}) rather than supporting children directly.

import { IsFilled, PrismicRichText } from "@prismicio/react";

export function MySlice({ slice }) {
  return (
    <section>
      <IsFilled.RichText
        field={slice.primary.title}
        fallback={<div>Some fallback</div>}
      >
        {(field) => (
          <h1>
            <PrismicRichText field={field} />
          </h1>
        )}
      </IsFilled.RichText>
    </section>
  );
}

Or...

import { IsFilled, PrismicRichText } from "@prismicio/react";

export function MySlice({ slice }) {
  return (
    <section>
      <IsFilled.RichText
        field={slice.primary.title}
        render={(field) => (
          <h1>
            <PrismicRichText field={field} />
          </h1>
        )}
        fallback={<div>Some fallback</div>}
      />
    </section>
  );
}

Either case may not work in Server Components since it passes a function.

Describe alternatives you've considered

  1. isFilled helpers, as described above.
  2. Pre-process query results to bake metadata into values. For example, a key text field could have a hidden _hasValue computed property that tells us if it is filled. Pre-processing content requires access to the type JSON definitions, which is not available on the client.
  3. Build-time generated that creates isFilled helpers specific for your content. It's not clear exactly what this is yet.

Additional context

N/A

@angeloashmore angeloashmore added the enhancement New feature or request label Nov 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant