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

New variant method API #70

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

New variant method API #70

wants to merge 1 commit into from

Conversation

MiiZZo
Copy link

@MiiZZo MiiZZo commented Jul 8, 2023

Related #34 #35

Motivation

variant provides an API that allows us to render different components based on $store value, but $store value type is limited to string, and it's not convenient to use this API with different $store types.
Imagine we have $user store and isAdmin boolean property and we want to render different components based on this property. With the current API, we need to write something like that:

const $user = createStore({ isAdmin: false });

const Profile = variant({
  source: $user.map((user) => {
    if (!user) {
      return 'isNotAuth';
    }
    
    if (user.isAdmin) {
      return 'isAdmin';
    }
    
    return 'isNotAdmin';
  })),
  cases: {
    isAdmin: AdminProfile,
    isNotAdmin: UserProfile,
    isNotAuth: SignIn,
  },
});

const $products = createStore([]);

const ProductsList = variant({
  source: $products.map((products) => products.length > 0 ? 'notEmpty' : 'empty'),
  cases: {
    empty: CreateYourFirstProject,
    notEmpty: ProductsListView,
  },
});

We may notice that this is inconvenient and the code looks strange. To solve this problem, we need to extend variant API so that developers can define the required component based on any type of $store value.

New API usage example

When our $store contains a value with a type different from string, we can pass an array to cases property. Each case has view field and filter method that takes $store value and returns a boolean value. variant returned view component will render that component that first match filter from up to down.

const $user = createStore({ isAdmin: false });

const Profile = variant({
  source: $user,
  cases: [
    // Pass as many cases as you want.
    { view: SignUp, filter: (user) => user === null },
    { view: UserComponent, filter: (user) => !user.isAdmin },
    { view: AdminComponent, filter: (user) => user.isAdmin }, 
  ],
});

const $products = createStore([]);

const ProductsList = variant({
  source: $products,
  cases: [
    { view: CreateYourFirstProject, filter: (products) => products.length === 0 },
    { view: ProductsListView, filter: (products) =>  products.length > 0 }, 
  ],
});

Tasks:

  • Implement new API.
  • Add types test coverage.
  • Add test coverage. ⚠

Changelogs:

  1. Impemented new API.
  2. Added NonEmptyArray type in types.ts
  3. Added types test coverage.

@stackblitz
Copy link

stackblitz bot commented Jul 8, 2023

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@MiiZZo MiiZZo changed the title add new variant method overload New variant method API Jul 8, 2023
@MiiZZo MiiZZo marked this pull request as draft July 10, 2023 03:49
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

Successfully merging this pull request may close these issues.

1 participant