aesthetic-suite / framework

🎨 Aesthetic is an end-to-end multi-platform styling framework that offers a strict design system, robust atomic CSS-in-JS engine, a structural style sheet specification (SSS), a low-runtime solution, and much more!
https://aestheticsuite.dev
MIT License
203 stars 5 forks source link

Double extend a component #74

Closed nunoliveira12 closed 4 years ago

nunoliveira12 commented 4 years ago

Is it possible to override styles from grandparent in a child component?

Example:

ComponentC styles can only override styles from componentB and no longer change styles from componentA

milesj commented 4 years ago

@nunoliveira12 A few things here.

nunoliveira12 commented 4 years ago

@milesj It does override for the parent component

For example BaseChip.tsx:

export const styleSheet: StyleSheetFactory<Theme> = theme => ({
  chip: {
    backgroundColor:"blue",
    color:"white"
  }
});

const BaseChip: React.FC<WithStylesProps> = ({
  styles,
  cx
}) => {
  return (
    <div
      className={cx(styles.chip)}
    >
      base chip
    </div>
  );
};

export default withStyles(styleSheet, { extendable: true })(BaseChip);

and DerivedChip.tsx:

const DerivedChip: React.FC = () => {
  const AlteredBaseChip = BaseChip.extendStyles(theme => ({
      chip: {
          backgroundColor:"red"
      }
  }));

  return (
    <AlteredBaseChip/>
  );
};

export default DerivedChip;

It does override the first style: image

Now if they were more complex than these examples and I wanted to extend the styles of the DerivedChip, how would I do it? And If I do similar to what was done, it will only extend the styles on the parent and couldn't, for example, change this backgroundColor because it was from the grandparent.

Anyway, from your bullet points, it does inherit the style from A & B but can only change the styles from B

milesj commented 4 years ago

@nunoliveira12 In your second example, it would just be this.

const DerivedChip = BaseChip.extendStyles(theme => ({
  chip: {
      backgroundColor:"red"
  }
}));

export default DerivedChip;

Extending styles creates a new component, so you can just render <DerivedChip />. And with the example above, you can extend yet again.

const DerivedChipAgain = DerivedChip.extendStyles(theme => ({
  chip: {
      backgroundColor: "green"
  }
}));

export default DerivedChipAgain;
nunoliveira12 commented 4 years ago

@milesj Thanks!

But If we want to change something on the render / add some props. Let's imagine it accepts a prop derived and I wanted to enable it (that's why I used the example before).

Should we do it another way than this?

const DerivedChip: React.FC = () => {
  const AlteredBaseChip = BaseChip.extendStyles(theme => ({
      chip: {
          backgroundColor:"red"
      }
  }));

  return (
    <AlteredBaseChip derived={true}/>
  );
};

export default DerivedChip;

but if I do this, I cannot extend again the same way

milesj commented 4 years ago

@nunoliveira12 Just moved the altered outside.

const AlteredBaseChip = BaseChip.extendStyles(theme => ({
  chip: {
    backgroundColor: 'red',
  },
}));

const DerivedChip: React.FC = () => {
  return <AlteredBaseChip derived={true} />;
};

export default DerivedChip;
nunoliveira12 commented 4 years ago

@milesj Thanks for your help so far,

And sorry for not explaining what I wanted from the beginning.

Your example does allow to extend the styles, but If I wanted to extend the style while also extend the component.

These examples are quite simple, but I wanted to have a ComplexComponent extending a BasicComponent, and then having a ComplexWithStyleComponent that changes the ComplexComponent.

const AlteredBaseChip = BaseChip.extendStyles(theme => ({
  chip: {
    backgroundColor: 'red',
  },
}));

const DerivedChip: React.FC = () => {
  return <AlteredBaseChip derived={true} />;
};

const AlteredBaseChipAgain = AlteredBaseChip.extendStyles(theme => ({
  chip: {
    backgroundColor: 'green',
  },
}));

const DerivedChipAgain: React.FC = () => {
  return <AlteredBaseChipAgain  />;  // This one doesn't enable the derived={true} prop, that's what I wanted , while changing the styles.
};

Sorry, probably I'm just overlooking something, but couldn't get this to work

milesj commented 4 years ago

@nunoliveira12 Yeah, that's not supported. Extending only changes the styles, it doesn't extend component classes or copy props over.

It just reuses the same base component over and over again (extendStyles calls withStyles): https://github.com/milesj/aesthetic/blob/master/packages/react/src/withStyles.tsx#L77

nunoliveira12 commented 4 years ago

@milesj Thanks for your answer! That's what I was afraid of.

Is there any plan on including this in future releases?

milesj commented 4 years ago

@nunoliveira12 Probably not. It would cause far too many layers of nested components.

I'm also moving towards hooks, which may make this API easier to use in the future.

milesj commented 4 years ago

The entire API has been rewritten from the ground up. This pattern is no longer possible, but with the new API, it should be much easier to use. Closing for now, will write docs soon.