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

fix: map prop to children prop for variant #297

Merged
merged 2 commits into from
Dec 11, 2021

Conversation

yeung-wah
Copy link
Contributor

@yeung-wah yeung-wah commented Dec 9, 2021

Issue #, if available:

map prop to children prop for variant

Description of changes:
Revision3
Moved getComponentTypeFromOverrideKey function to under StudioNode class

Revision2
In revision 1, missed to handle a case where the overrideKey in variant can be a nested children component(Flex.Flex[0].Flex[0].Button[0]), added a new function to parse overrideKey and get the corresponding component type

Added complex test using real world payload, the code for the nested children components which have the mapping should flip label prop to children prop, and display different text

Added test to not flip prop to children prop if the component is not defined in the mapping table

Revision1
Currently we are not remapping prop to children prop for variant. This change would remap predefined prop to children prop for variant. It is very similar to what we are doing with property binding. It will go through the variants section, and remap all the predefined prop to children for the specific primitive hierarchy based on this mapping

export const PrimitiveChildrenPropMapping: Partial<Record<Primitive, string>> = {

Example:

{
  "id": "1234-5678-9010",
  "componentType": "Button",
  "name": "ComponentWithVariant",
  "properties": {
    "children": {
      "value": "ComponentWithVariant"
    }
  },
  "variants": [
    {
      "variantValues": {
        "variant": "success"
      },
      "overrides": {
        "Button": {
          "label": "ComponentWithVariantWithMappedChildrenProp",
          "fontSize": "15px"
        }
      }
    }
  ]
}

In memory it will turn into

{
  "id": "1234-5678-9010",
  "componentType": "Button",
  "name": "ComponentWithVariant",
  "properties": {
    "children": {
      "value": "ComponentWithVariant"
    }
  },
  "variants": [
    {
      "variantValues": {
        "variant": "success"
      },
      "overrides": {
        "Button": {
          "children": "ComponentWithVariantWithMappedChildrenProp",
          "fontSize": "15px"
        }
      }
    }
  ]
}

and output

/* eslint-disable */
import React from "react";
import {
  EscapeHatchProps,
  Variant,
  getOverrideProps,
  getOverridesFromVariants,
} from "@aws-amplify/ui-react/internal";
import { Button, ButtonProps } from "@aws-amplify/ui-react";

export type ComponentWithVariantProps = React.PropsWithChildren<
  Partial<ButtonProps> & {
    variant?: "success";
  } & {
    overrides?: EscapeHatchProps | undefined | null;
  }
>;
export default function ComponentWithVariant(
  props: ComponentWithVariantProps
): React.ReactElement {
  const { overrides: overridesProp, ...rest } = props;
  const variants: Variant[] = [
    {
      variantValues: { variant: "success" },
      overrides: {
        Button: {
          fontSize: "15px",
          children: "ComponentWithVariantWithMappedChildrenProp",
        },
      },
    },
  ];
  const mergeVariantsAndOverrides = (
    variants: EscapeHatchProps,
    overrides: EscapeHatchProps
  ): EscapeHatchProps => {
    const overrideKeys = new Set(Object.keys(overrides));
    const sharedKeys = Object.keys(variants).filter((variantKey) =>
      overrideKeys.has(variantKey)
    );
    const merged = Object.fromEntries(
      sharedKeys.map((sharedKey) => [
        sharedKey,
        { ...variants[sharedKey], ...overrides[sharedKey] },
      ])
    );
    return {
      ...variants,
      ...overrides,
      ...merged,
    };
  };
  const overrides = mergeVariantsAndOverrides(
    getOverridesFromVariants(variants, props),
    overridesProp || {}
  );
  return (
    /* @ts-ignore: TS2322 */
    <Button
      children="ComponentWithVariant"
      {...rest}
      {...getOverrideProps(overrides, "Button")}
    ></Button>
  );
}

Since we are already taking care of children props in variant, it will follow the existing process, and display different text.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@yeung-wah yeung-wah requested a review from a team December 9, 2021 00:10
Copy link
Contributor

@alharris-at alharris-at left a comment

Choose a reason for hiding this comment

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

A few minor comments, but overall looks good to me. Could you also add a unit test to verify label doesn't get remapped if it's not in your table?

if (childrenPropMapping !== undefined) {
const propsInOverrides = variant.overrides[overridesKey];
// only remap if children prop is not defined in this particular overrides section
if (propsInOverrides.children === undefined && propsInOverrides[childrenPropMapping] !== undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Even if propsInOverrides[childrenPropMapping] === undefined we probably want to map for consistency sake.

Copy link
Member

@dpilch dpilch Dec 9, 2021

Choose a reason for hiding this comment

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

edit: nvm, that was all wrong

Copy link
Contributor Author

@yeung-wah yeung-wah Dec 9, 2021

Choose a reason for hiding this comment

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

Even if propsInOverrides[childrenPropMapping] === undefined we probably want to map for consistency sake.

hmmm, childrenPropMapping here is referring to the predefined prop that we want to map to children prop(Ex label). For example, we need to remap label prop to children prop for button component

 "overrides": {
        "Button": {
          "label": "ComponentWithVariantWithMappedChildrenProp",
          "fontSize": "15px"
        }
      }

convert to

 "overrides": {
        "Button": {
          "children": "ComponentWithVariantWithMappedChildrenProp",
          "fontSize": "15px"
        }
      }

if children prop is not defined(propsInOverrides.children) and label prop is defined(propsInOverrides[childrenPropMapping], then we will remap label prop to children prop. So if propsInOverrides[childrenPropMapping] is undefined, then we don need to do anything as the label prop is not there.


this.component.variants.forEach((variant) => {
// loop through the keys in the dict. Ex. button, button.text
Object.keys(variant.overrides).forEach((overridesKey) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of Object.key you can use Object.entries since you are accessing the values as well as the keys down below.

@alharris-at alharris-at changed the base branch from main to develop December 9, 2021 19:30
@yeung-wah yeung-wah force-pushed the map_prop_to_children_prop_for_variant branch 2 times, most recently from 0e15464 to a333e2f Compare December 10, 2021 18:31
* Example2: Button
*
*/
private getComponentTypeFromOverrideKey(overrideKey: string): string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you move this method to the StudioNode class as a static method, and ensure we've got unit tests covering it?

@yeung-wah yeung-wah force-pushed the map_prop_to_children_prop_for_variant branch from a333e2f to e432c00 Compare December 10, 2021 21:10
@codecov-commenter
Copy link

codecov-commenter commented Dec 10, 2021

Codecov Report

Merging #297 (1404151) into develop (eba7f1f) will increase coverage by 0.17%.
The diff coverage is 100.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #297      +/-   ##
===========================================
+ Coverage    89.45%   89.63%   +0.17%     
===========================================
  Files           36       36              
  Lines         1223     1244      +21     
  Branches       273      278       +5     
===========================================
+ Hits          1094     1115      +21     
  Misses         126      126              
  Partials         3        3              
Impacted Files Coverage Δ
...gen-ui-react/lib/react-studio-template-renderer.ts 91.21% <100.00%> (+0.38%) ⬆️
packages/codegen-ui/lib/studio-node.ts 96.29% <100.00%> (+1.29%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update eba7f1f...1404151. Read the comment docs.

@alharris-at alharris-at force-pushed the map_prop_to_children_prop_for_variant branch from e432c00 to 1404151 Compare December 10, 2021 23:52
@alharris-at alharris-at merged commit f511f2c into develop Dec 11, 2021
@alharris-at alharris-at deleted the map_prop_to_children_prop_for_variant branch December 11, 2021 00:10
alharris-at added a commit that referenced this pull request Dec 11, 2021
* fix: map prop to children prop for variant

* fix: flip generated tests to jsx

Co-authored-by: Alexander Harris <alharris@amazon.com>
yeung-wah added a commit that referenced this pull request Dec 11, 2021
* fix: map prop to children prop for variant

Co-authored-by: Alexander Harris <alharris@amazon.com>

Co-authored-by: yeung-wah <94481720+yeung-wah@users.noreply.github.com>
dpilch pushed a commit that referenced this pull request Dec 15, 2021
* fix: map prop to children prop for variant

* fix: flip generated tests to jsx

Co-authored-by: Alexander Harris <alharris@amazon.com>
@dpilch dpilch mentioned this pull request Feb 24, 2022
@alharris-at alharris-at mentioned this pull request Feb 24, 2022
alharris-at added a commit that referenced this pull request Feb 25, 2022
* fix: map prop to children prop for variant

* fix: flip generated tests to jsx

Co-authored-by: Alexander Harris <alharris@amazon.com>
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.

4 participants