Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

chore(Box|Button|Image|Avatar): converting components with hooks #2238

Merged
merged 30 commits into from
Jan 24, 2020

Conversation

mnajdova
Copy link
Contributor

@mnajdova mnajdova commented Jan 14, 2020

This PR converts Box, Button, Image, Avatar components to use our newly shipped React hooks as part of #2269.

  • no performance improvements or degrades
  • no visual regressions

Adds FluentComponentStaticProps type to use Fluent specific static props (className, handledProps) on function components.

BREAKING CHANGES
We are now restricting the set of props provided to the styles. Here are the props propagated to the updated components;

  • Button: text, primary, disabled, circular, size, loading, inverted, iconOnly, fluid and hasContent
  • Avatar: size
  • Image: avatar, circular, fluid

@DustyTheBot
Copy link
Collaborator

DustyTheBot commented Jan 14, 2020

Perf comparison

Status Scenario Fluent TPI Fabric TPI Ratio Iterations Ticks
🔧 Avatar.Fluent 0.74 0.5 1.48:1 2000 1487
🔧 Button.Fluent 1.64 0.22 7.45:1 1000 1640
🔧 Checkbox.Fluent 1.86 0.35 5.31:1 1000 1855
🔧 Dialog.Fluent 0.42 0.22 1.91:1 5000 2092
🔧 Dropdown.Fluent 4.58 0.45 10.18:1 1000 4578
🔧 Icon.Fluent 0.28 0.03 9.33:1 5000 1420
🔧 Image.Fluent 0.13 0.09 1.44:1 5000 656
🔧 Slider.Fluent 2.6 0.41 6.34:1 1000 2604
🦄 Text.Fluent 0.07 0.21 0.33:1 5000 335
🦄 Tooltip.Fluent 0.36 24.66 0.01:1 5000 1815

🔧 Needs work     🎯 On target     🦄 Amazing

Generated by 🚫 dangerJS

import * as customPropTypes from '@fluentui/react-proptypes'
import * as PropTypes from 'prop-types'
import * as React from 'react'
// @ts-ignore
import { ThemeContext } from 'react-fela'
Copy link
Member

@dzearing dzearing Jan 15, 2020

Choose a reason for hiding this comment

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

Avatar.tsx should not refer to fela specifics directly. @jdhuntington for heads up here.

We should expect the base component to simply take in a classes prop. So, Avatar renders DOM and injects the right classes.

Then createComponent can abstract how classes gets injected.

export const Avatar = createComponent(AvatarBase, { stuff to build `classes` attribute });

Copy link
Member

Choose a reason for hiding this comment

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

What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

It's not Fela specifics. We use this context only by historical reasons. We should use own context instead.

'larger',
'largest',
])
export const accessibility = PropTypes.func
Copy link
Member

Choose a reason for hiding this comment

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

⚠️ This change is correct as all behaviors are functions

// Components
// ========================================================

export type FluentComponentStaticProps<P = {}> = {
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 have better naming ideas

# Conflicts:
#	packages/react-bindings/src/hooks/useStyles.ts
#	packages/react/src/types.ts
@layershifter layershifter changed the title [WIP] converting components with hooks chore(Box|Button|Image|Avatar): converting components with hooks Jan 17, 2020
}

setEnd()
Copy link
Member

Choose a reason for hiding this comment

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

This is extremely fragile and (currently) wrong.
What if I forget to add telemetry to my component? There should be a conformance test for that.

But the main problem I see is that nothing prevents you from calling setStart too late or setEnd too early.

In this case the whole return is down outside of the telemetry scope - all calls to getAttributes(), getA11Props(), renderLoader(), renderIcon()... - which makes the numbers useless :-(

So we should either give up and remove fluent-ui telemetry (no!) or rethink and rework how we measure it (something like a wrapping function for the whole render? And named something like renderComponent?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No renderComponent please, we are trying to move out from it. This is an internal thing and we can track it (like you can block the PR because it's not in the Avatar, and Image components :D - oops will ad it) Even when this was in renderComponent, it was setting end even before invoking render() which may be even worse.. Anyway, I will add the telemetry to the other components before merging. Do you have some other proposal for the setting of the start and end?

Copy link
Member

Choose a reason for hiding this comment

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

Even when this was in renderComponent, it was setting end even before invoking render() which may be even worse..

That's not true. That's what @layershifter broke in #1980

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed renderComponent, fixed components' telemetry to be accurate. It is used internally now, so we can make sure we are adding it properly until we have better idea of how to improve it.

@mnajdova mnajdova merged commit a4d68f5 into master Jan 24, 2020
@mnajdova mnajdova deleted the feat/use-hooks-in-box-component branch January 24, 2020 12:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants