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

fix(Loader): Adding labeling when loader get focus #2352

Merged
merged 11 commits into from
Feb 14, 2020

Conversation

kolaps33
Copy link
Collaborator

Fixing the ticket:
#2254


componentDidUpdate(prevProps) {
if (this.getIdFromShorthand(this.props.label) !== this.getIdFromShorthand(prevProps.label)) {
this.setState(prevState => ({ labelLoaderId: getOrGenerateIdFromShorthand('loader-label-', this.props.label, prevState.labelLoaderId) }))
}
Copy link
Member

Choose a reason for hiding this comment

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

Why don't use getDerivedStateFromProps()? This will produce an additional render

Copy link
Contributor

@jurokapsiar jurokapsiar Feb 13, 2020

Choose a reason for hiding this comment

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

do you mean getAutoControlledStateFromProps @layershifter? - please see Dialog.tsx

Copy link
Contributor

Choose a reason for hiding this comment

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

getDerivedStateFromProps should be enough. This is not Autocontrolled component.

})

test('do NOT add aria-labelledby, when aria-labelled was set already', () => {
props['aria-labelledby'] = 'id'
Copy link
Member

Choose a reason for hiding this comment

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

Let's avoid mutation of props:

const expectedResult = loaderBehavior({ labelLoaderId: "label-id",'aria-labelledby':'id'  })

@DustyTheBot
Copy link
Collaborator

DustyTheBot commented Feb 13, 2020

Perf comparison

Status Scenario Fluent TPI Fabric TPI Ratio Iterations Ticks
🔧 Avatar.Fluent 0.5 0.4 1.25:1 2000 1002
🦄 Button.Fluent 0.11 0.17 0.65:1 1000 113
🔧 Checkbox.Fluent 0.83 0.27 3.07:1 1000 826
🔧 Dialog.Fluent 0.34 0.17 2:1 5000 1704
🔧 Dropdown.Fluent 3.71 0.37 10.03:1 1000 3707
🔧 Icon.Fluent 0.12 0.03 4:1 5000 624
🦄 Image.Fluent 0.04 0.07 0.57:1 5000 224
🔧 Slider.Fluent 1.68 0.31 5.42:1 1000 1679
🔧 Text.Fluent 0.06 0.02 3:1 5000 295
🦄 Tooltip.Fluent 0.12 18.34 0.01:1 5000 582

🔧 Needs work     🎯 On target     🦄 Amazing

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
ChatDuplicateMessagesPerf.default 807 634 1.27:1
RefMinimalPerf.default 177 139 1.27:1
AccordionMinimalPerf.default 240 202 1.19:1
ButtonMinimalPerf.default 135 113 1.19:1
DropdownManyItemsPerf.default 551 464 1.19:1
GridMinimalPerf.default 941 806 1.17:1
CheckboxMinimalPerf.default 4081 3513 1.16:1
Text.Fluent 295 256 1.15:1
StatusMinimalPerf.default 262 230 1.14:1
ListMinimalPerf.default 299 265 1.13:1
AnimationMinimalPerf.default 529 474 1.12:1
DropdownMinimalPerf.default 3851 3424 1.12:1
ListCommonPerf.default 171 156 1.1:1
AvatarMinimalPerf.default 546 505 1.08:1
BoxMinimalPerf.default 253 235 1.08:1
ChatWithPopoverPerf.default 724 689 1.05:1
ItemLayoutMinimalPerf.default 1770 1691 1.05:1
RadioGroupMinimalPerf.default 421 400 1.05:1
Icon.Fluent 624 596 1.05:1
Button.Fluent 113 109 1.04:1
Dialog.Fluent 1704 1636 1.04:1
DialogMinimalPerf.default 1650 1596 1.03:1
LayoutMinimalPerf.default 514 500 1.03:1
TextAreaMinimalPerf.default 2986 2910 1.03:1
Tree60WithListItems.default 235 229 1.03:1
ChatMinimalPerf.default 1918 1889 1.02:1
FlexMinimalPerf.default 356 350 1.02:1
PopupMinimalPerf.default 316 310 1.02:1
SliderMinimalPerf.default 1410 1380 1.02:1
CarouselMinimalPerf.default 1909 1883 1.01:1
HeaderSlotsPerf.default 1313 1294 1.01:1
LoaderMinimalPerf.default 2346 2319 1.01:1
TextMinimalPerf.default 259 257 1.01:1
Avatar.Fluent 1002 995 1.01:1
Checkbox.Fluent 826 817 1.01:1
HeaderMinimalPerf.default 421 423 1:1
PortalMinimalPerf.default 217 218 1:1
ReactionMinimalPerf.default 2492 2487 1:1
TableMinimalPerf.default 555 556 1:1
TreeMinimalPerf.default 903 907 1:1
VideoMinimalPerf.default 689 691 1:1
MenuMinimalPerf.default 1811 1830 0.99:1
ProviderMinimalPerf.default 569 572 0.99:1
SplitButtonMinimalPerf.default 11814 11900 0.99:1
ToolbarMinimalPerf.default 735 741 0.99:1
AttachmentSlotsPerf.default 3304 3384 0.98:1
ButtonSlotsPerf.default 594 609 0.98:1
InputMinimalPerf.default 906 926 0.98:1
TooltipMinimalPerf.default 833 848 0.98:1
AttachmentMinimalPerf.default 876 907 0.97:1
EmbedMinimalPerf.default 5988 6163 0.97:1
Dropdown.Fluent 3707 3829 0.97:1
IconMinimalPerf.default 302 316 0.96:1
ProviderMergeThemesPerf.default 1027 1075 0.96:1
ImageMinimalPerf.default 209 219 0.95:1
MenuButtonMinimalPerf.default 1404 1479 0.95:1
CustomToolbarPrototype.default 3775 3957 0.95:1
Image.Fluent 224 235 0.95:1
HierarchicalTreeMinimalPerf.default 764 814 0.94:1
LabelMinimalPerf.default 774 835 0.93:1
Slider.Fluent 1679 1821 0.92:1
Tooltip.Fluent 582 631 0.92:1
AlertMinimalPerf.default 536 596 0.9:1
SegmentMinimalPerf.default 1194 1347 0.89:1
DividerMinimalPerf.default 915 1051 0.87:1
FormMinimalPerf.default 759 947 0.8:1

Generated by 🚫 dangerJS

}

static getDerivedStateFromProps(props, state) {
if (Loader.getIdFromShorthand(props.label) !== Loader.getIdFromShorthand(state.labelLoaderId)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we compare here getIdFromShorthand(props.label) with getIdFromShorthand(this.props.label)?

@@ -94,9 +97,40 @@ class Loader extends UIComponent<WithAsProp<LoaderProps>, LoaderState> {

this.state = {
visible: this.props.delay === 0,
labelLoaderId: getOrGenerateIdFromShorthand('loader-label-', props.label, ''),
Copy link
Member

Choose a reason for hiding this comment

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

We don't need this anymore as getDerivedStateFromProps() is executed before each render


type LoaderBehaviorProps = {
/** id of the loader label element. */
labelLoaderId?: string
Copy link
Member

Choose a reason for hiding this comment

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

I expect that it will be just labelId

state.labelLoaderId,
)
return {
labelLoaderId: nextLabelLoaderId,
Copy link
Member

Choose a reason for hiding this comment

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

I believe that it can used in the same way as in Dialog, just:

return {
labelId: getOrGenerateIdFromShorthand('loader-label-', props.label, state.loaderId),
}

return result
}

static getDerivedStateFromProps(props, state) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's type this method as in Dialog

if (props['aria-label'] || props['aria-labelledby']) {
return undefined
}
return props['tabIndex'] !== undefined ? props.labelLoaderId : undefined
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Let's invert this condition to make more readable:

return props['tabIndex'] === undefined ? undefined : props.labelLoaderId

Copy link
Member

@layershifter layershifter left a comment

Choose a reason for hiding this comment

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

Plz fix UTs before merging 👍

@kolaps33 kolaps33 merged commit 35aaf02 into master Feb 14, 2020
@kolaps33 kolaps33 deleted the mituron/focusable-loader branch February 14, 2020 11:56
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.

6 participants