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

Sub-component style support in mergeStyleSets #5513

Merged
merged 14 commits into from
Jul 13, 2018

Conversation

cliffkoh
Copy link
Contributor

@cliffkoh cliffkoh commented Jul 11, 2018

Pull request checklist

Description of changes

Support passing in a stylefunction or object to subcomponent styles (in a new way that doesn't require conditional types).
Substantially improve typings which results in way better intellisense, and more errors being caught.

Very rough example of what you can do now in a .styles.ts

export const getStyles = {
        root: { background: 'red' },
        a: { background: 'green' },
        subComponentStyles: {
          label: (props: ILabelStyleProps) => ({
             root: { background: 'green', fontSize: 12 }
          });
        }
      };

A user calling the component can then pass in:

<SomeComponent styles={{
        a: { background: 'white' },
        b: { background: 'blue' },
        subComponentStyles: {
          label:  {  // you can also pass in objects
            root: {
               background: 'yellow',
               color: 'pink'
            }
          }
        }
      }} />

Focus areas to test

(optional)

Microsoft Reviewers: Open in CodeFlow

@@ -1 +0,0 @@
export type IClassNames<T> = { [key in keyof T]: string };
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would like to major bump @uifabric/utilities because of this change. IClassNames simply doesn't make sense now (semantically wrong, in addition to structurally wrong) because it doesn't just have classnames...

Copy link
Member

@dzearing dzearing left a comment

Choose a reason for hiding this comment

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

pull master
resolve "object" error
resolve typing issue

@cliffkoh cliffkoh requested a review from kkjeer as a code owner July 12, 2018 01:25
@cliffkoh
Copy link
Contributor Author

@dzearing pulled and investigated the new errors. Unfortunately I think there is a deeper issue with newly introduced DetailsRow code and one for which a mechanical fix wouldn't be the right fix. Sent an email to @kenotron and will need him to resolve the issue in DetailsRow first.

getDefaultStyles(styleProps),
getStyles && getStyles(styleProps)
);
const classNames = getStyles
Copy link
Member

Choose a reason for hiding this comment

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

This LOOKS cleaner - but is there something fundamentally wrong with having a null as a 2nd param?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a type error.. I didn't change this because I was too free 😁

example-app-base could use a lot of work to get spruced up to modern standards. In modern standards, we don't call mergeStyleSets from components but we call classNameFunction/getClassNames instead. dzearing asked me to do the bare minimum though and to invest my time in Dropdown conversion instead.


/**
* Combine a set of styles together (but does not register css classes).
* @param styleSet1 The first style set to be concatenated.
Copy link
Member

Choose a reason for hiding this comment

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

@param styleSet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

styleSet6: TStyleSet6 | false | null | undefined
): IConcatenatedStyleSet<TStyleSet1 & TStyleSet2 & TStyleSet3 & TStyleSet4 & TStyleSet5 & TStyleSet6>;

/**
Copy link
Member

Choose a reason for hiding this comment

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

Don't know if my eyes are playing tricks on me but is this the same as the implementation below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is the same.

@@ -14,7 +14,7 @@ export class ButtonSplitExample extends React.Component<IButtonProps> {
const { disabled, checked } = this.props;

const getClassNames = classNamesFunction<IButtonBasicExampleStyleProps, IButtonBasicExampleStyles>();
const classNames = getClassNames(getStyles);
const classNames = getClassNames(getStyles, {});
Copy link
Member

Choose a reason for hiding this comment

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

I don't think that {} is needed - the definition of getClassNames already defaults to {} for you...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, initially I didn't allow it but David decided to keep it optional for backwards compatibility. The original version would have been undefined. My POV is that if you don't need style props, you should just pass in a style object and so all style functions should take in the 2nd arg.

@@ -1,4 +1,6 @@
{
"extends": ["office-ui-fabric-react-tslint"],
"rules": {}
"rules": {
"no-any": false
Copy link
Member

Choose a reason for hiding this comment

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

I think we could just do tslint:disable:no-any like the other places

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My POV is that this library in particular has a high density of real, unavoidable uses of any (the implementation function in the overloads, for instance). Having a ton of tslint:disable scattered around is a big mess.

We still disallow implicit anys, and any use of any will be scrutinized.

// However, because we usually use `props.styles` as the argument to an invocation of this method, and
// `props.styles` itself is defined as optional, this avoids the need to use `!` at all invocation points.
if (styleFunctionOrObject === undefined) {
// throw new TypeError(
Copy link
Member

Choose a reason for hiding this comment

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

Remove commented code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm I already did - must have forgotten to push 😅

/**
* A concatenated style set differs from `IStyleSet` in that subComponentStyles will always be a style function.
*/
export type IConcatenatedStyleSet<TStyleSet extends IStyleSet<TStyleSet>> = {
Copy link
Member

Choose a reason for hiding this comment

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

There is no difference between this and IProcessedStyleSet... I'm thinking about whether we gain much in differentiating them. The difference is that mergestyleset has a side effect of registering them but concat doesn't. The result is the same type structurally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a difference, look closely.

One contains classnames, one contains IStyles.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not just specified in the code, but called out in the comments as well. :)

@cliffkoh
Copy link
Contributor Author

@kenotron Appreciate if you could review the changes to DetailsRow in 97e4fd4 (part of this PR) and sign off on it by approving the PR. There's technically a breaking change in #5514 which you're also doing because we're removing a prop...

@Vitalius1, do you know why there is another copy of Shimmer in experiments? Should we be de-duping?

@JasonGore appreciate if you could sign off on the createComponent changes in experiments too.

Copy link
Member

@kenotron kenotron left a comment

Choose a reason for hiding this comment

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

These changes work in DetailsRow I believe.

@cliffkoh cliffkoh closed this Jul 12, 2018
@cliffkoh cliffkoh reopened this Jul 12, 2018
@Vitalius1
Copy link
Contributor

Vitalius1 commented Jul 12, 2018

@cliffkoh The Shimmer from experiments can not be removed as of now as it's being used in common's packages.

@cliffkoh cliffkoh closed this Jul 12, 2018
@cliffkoh cliffkoh reopened this Jul 12, 2018
@cliffkoh cliffkoh closed this Jul 12, 2018
@cliffkoh cliffkoh reopened this Jul 12, 2018
@srideshpande
Copy link
Contributor

srideshpande commented Jul 12, 2018

Signing off from ChoiceGroup perspective. #Resolved

Copy link
Contributor

@srideshpande srideshpande left a comment

Choose a reason for hiding this comment

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

:shipit:

Copy link
Member

@Jahnp Jahnp left a comment

Choose a reason for hiding this comment

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

This is awesome!

};

/**
* A processed style set is one which the set of styles associated with each area has been converted
Copy link
Member

Choose a reason for hiding this comment

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

👍

// It might not be necessary once Omit becomes part of lib.d.ts (when we remove our own Omit and rely on
// the official version).
// tslint:disable-next-line:no-any
return concatStyleSets(...(result as any)) as IConcatenatedStyleSet<TStyleSet>;
Copy link
Member

Choose a reason for hiding this comment

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

Could it be related to this? I feel like I had a similar issue.

@cliffkoh cliffkoh merged commit 7faceae into microsoft:master Jul 13, 2018
@cliffkoh cliffkoh deleted the cliffkoh/styleFunctionsV2 branch July 13, 2018 06:56
dzearing added a commit that referenced this pull request Jul 13, 2018
* Revert "Sub-component style support in mergeStyleSets (#5513)"

This reverts commit 7faceae.

* Adding change files.

* updating shrinkwrap.
@cliffkoh cliffkoh mentioned this pull request Jul 17, 2018
cliffkoh added a commit to cliffkoh/office-ui-fabric-react that referenced this pull request Jul 17, 2018
dzearing pushed a commit that referenced this pull request Jul 18, 2018
* Initial revert

* Fix forward
@JasonGore JasonGore mentioned this pull request Jul 19, 2018
2 tasks
@microsoft microsoft locked as resolved and limited conversation to collaborators Aug 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MergeStyles: Support StyleFunctions
10 participants