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

Commit 37e6c6b

Browse files
authored
feat(react-bindings): added useTelemetry and improved returned value of other hooks (#2257)
* -updates * -updated changelog * -removed animation from useStyles * -updated tests
1 parent f0c5ff7 commit 37e6c6b

File tree

22 files changed

+87
-58
lines changed

22 files changed

+87
-58
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2929
- Allow `useRef` hook used for storing debugging data to be defined in any order with other hooks in functional components @layershifter, @mnajdova ([#2236](https://github.com/microsoft/fluent-ui-react/pull/2236))
3030
- Add `useStyles()` hook to use theming capabilities in custom components @layershifter, @mnajdova ([#2217](https://github.com/microsoft/fluent-ui-react/pull/2217))
3131
- Add optional wrapper function to `List` which can be used to inject custom scrollbars to `Dropdown` @jurokapsiar ([#2092](https://github.com/microsoft/fluent-ui-react/pull/2092))
32+
- Add `useTelemetry()` hook for adding telemetry information for the Fluent components and improve return types for the `useStyles` and `useStateManager` hooks @mnajdova ([#2257](https://github.com/microsoft/fluent-ui-react/pull/2257))
3233

3334
### Documentation
3435
- Add per-component performance charts @miroslavstastny ([#2240](https://github.com/microsoft/fluent-ui-react/pull/2240))

docs/src/prototypes/customToolbar/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import * as _ from 'lodash'
22
import * as React from 'react'
33
import { KnobsSnippet } from '@fluentui/code-sandbox'
4+
import { Telemetry } from '@fluentui/react-bindings'
45
import {
56
KnobProvider,
67
useBooleanKnob,
78
useSelectKnob,
89
KnobInspector,
910
} from '@fluentui/docs-components'
10-
import { Provider, Flex, themes, mergeThemes, Telemetry } from '@fluentui/react'
11+
import { Provider, Flex, themes, mergeThemes } from '@fluentui/react'
1112

1213
import { darkThemeOverrides } from './darkThemeOverrides'
1314
import { highContrastThemeOverrides } from './highContrastThemeOverrides'

packages/react-bindings/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ const createInputManager: ManagerFactory<InputState, InputActions> = config =>
116116
})
117117

118118
const Input: React.FC<InputProps> = props => {
119-
const [state, actions] = useStateManager(createInputManager, {
119+
const { state, actions } = useStateManager(createInputManager, {
120120
mapPropsToInitialState: () => ({ value: props.defaultValue }),
121121
mapPropsToState: () => ({ value: props.value }),
122122
})
@@ -136,8 +136,8 @@ const Input: React.FC<InputProps> = props => {
136136
### Reference
137137

138138
```tsx
139-
const [state, actions] = useStateManager(createInputManager)
140-
const [state, actions] = useStateManager(
139+
const { state, actions } = useStateManager(createInputManager)
140+
const { state, actions } = useStateManager(
141141
managerFactory: ManagerFactory<State, Actions>,
142142
options: UseStateManagerOptions<Props>,
143143
)
@@ -164,7 +164,7 @@ type TextComponentProps = {
164164
const Text: React.FunctionComponent<TextComponentProps> = props => {
165165
const { className, children, color } = props
166166

167-
const [classes] = useStyles('Text', {
167+
const { classes } = useStyles('Text', {
168168
className: 'ui-text',
169169
mapPropsToStyles: () => ({ color }),
170170
})
@@ -176,7 +176,7 @@ const Text: React.FunctionComponent<TextComponentProps> = props => {
176176
### Reference
177177

178178
```tsx
179-
const [classes] = useStyles(
179+
const { classes } = useStyles(
180180
displayName: string,
181181
options: UseStylesOptions<Props>,
182182
)

packages/react-bindings/src/hooks/useStateManager.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ type UseStateManagerOptions<State> = {
77
sideEffects?: SideEffect<State>[]
88
}
99

10+
type UseStateManagerResult<State, Actions> = {
11+
state: Readonly<State>
12+
actions: Readonly<Actions>
13+
}
14+
1015
const getDefinedProps = <Props extends Record<string, any>>(props: Props): Partial<Props> => {
1116
const definedProps: Partial<Props> = {}
1217

@@ -25,7 +30,7 @@ const useStateManager = <
2530
>(
2631
managerFactory: ManagerFactory<State, Actions>,
2732
options: UseStateManagerOptions<State> = {},
28-
): [Readonly<State>, Readonly<Actions>] => {
33+
): UseStateManagerResult<State, Actions> => {
2934
const {
3035
mapPropsToInitialState = () => ({} as Partial<State>),
3136
mapPropsToState = () => ({} as Partial<State>),
@@ -58,11 +63,14 @@ const useStateManager = <
5863
// https://github.com/facebook/react/issues/11527#issuecomment-360199710
5964

6065
if (process.env.NODE_ENV === 'production') {
61-
return [latestManager.current.state, latestManager.current.actions]
66+
return { state: latestManager.current.state, actions: latestManager.current.actions }
6267
}
6368

6469
// Object.freeze() is used only in dev-mode to avoid usage mistakes
65-
return [Object.freeze(latestManager.current.state), Object.freeze(latestManager.current.actions)]
70+
return {
71+
state: Object.freeze(latestManager.current.state),
72+
actions: Object.freeze(latestManager.current.actions),
73+
}
6674
}
6775

6876
export default useStateManager

packages/react-bindings/src/hooks/useStyles.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ type UseStylesOptions<StyleProps extends PrimitiveProps> = {
2525
rtl?: boolean
2626
}
2727

28+
type UseStylesResult = {
29+
classes: ComponentSlotClasses
30+
styles: ComponentSlotStylesPrepared
31+
}
32+
2833
type InlineStyleProps<StyleProps> = {
2934
/** Additional CSS class name(s) to apply. */
3035
className?: string
@@ -48,7 +53,7 @@ const defaultContext: StylesContextValue<{ renderRule: RendererRenderRule }> = {
4853
const useStyles = <StyleProps extends PrimitiveProps>(
4954
displayName: string,
5055
options: UseStylesOptions<StyleProps>,
51-
): [ComponentSlotClasses, ComponentSlotStylesPrepared] => {
56+
): UseStylesResult => {
5257
const context: StylesContextValue<{ renderRule: RendererRenderRule }> =
5358
React.useContext(ThemeContext) || defaultContext
5459

@@ -79,7 +84,7 @@ const useStyles = <StyleProps extends PrimitiveProps>(
7984
_internal_resolvedComponentVariables: context._internal_resolvedComponentVariables,
8085
})
8186

82-
return [classes, resolvedStyles]
87+
return { classes, styles: resolvedStyles }
8388
}
8489

8590
export default useStyles

packages/react-bindings/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,8 @@ export { default as unstable_createAnimationStyles } from './styles/createAnimat
1818
export { default as unstable_getStyles } from './styles/getStyles'
1919
export * from './styles/types'
2020

21+
export { default as useTelemetry } from './telemetry/useTelemetry'
22+
export * from './telemetry/types'
23+
2124
export { default as getElementType } from './utils/getElementType'
2225
export { default as getUnhandledProps } from './utils/getUnhandledProps'

packages/react/src/utils/Telemetry.ts renamed to packages/react-bindings/src/telemetry/types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ type ComponentPerfStats = {
55
msMax: number
66
}
77

8-
export default class Telemetry {
8+
export type UseTelemetryResult = {
9+
setStart: () => void
10+
setEnd: () => void
11+
}
12+
13+
export class Telemetry {
914
performance: Record<string, ComponentPerfStats>
1015
enabled: boolean
1116

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Telemetry, UseTelemetryResult } from './types'
2+
3+
const useTelemetry = (
4+
displayName: string,
5+
telemetry: Telemetry | undefined,
6+
): UseTelemetryResult => {
7+
let start: number = -1
8+
let end: number = -1
9+
10+
const setStart = () => {
11+
start = telemetry && telemetry.enabled ? performance.now() : -1
12+
}
13+
14+
const setEnd = () => {
15+
if (telemetry && telemetry.enabled && start !== -1) {
16+
end = performance.now()
17+
const duration = end - start
18+
if (telemetry.performance[displayName]) {
19+
telemetry.performance[displayName].count++
20+
telemetry.performance[displayName].msTotal += duration
21+
telemetry.performance[displayName].msMin = Math.min(
22+
duration,
23+
telemetry.performance[displayName].msMin,
24+
)
25+
telemetry.performance[displayName].msMax = Math.max(
26+
duration,
27+
telemetry.performance[displayName].msMax,
28+
)
29+
} else {
30+
telemetry.performance[displayName] = {
31+
count: 1,
32+
msTotal: duration,
33+
msMin: duration,
34+
msMax: duration,
35+
}
36+
}
37+
}
38+
}
39+
40+
return { setStart, setEnd }
41+
}
42+
43+
export default useTelemetry

packages/react-bindings/test/hooks/useDispatchEffect-test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const TestComponent: React.FunctionComponent<TestComponentProps> = props => {
3737
}
3838
},
3939
)
40-
const [state, actions] = useStateManager(createTestManager, {
40+
const { state, actions } = useStateManager(createTestManager, {
4141
mapPropsToInitialState: () => ({ value: props.defaultValue }),
4242
mapPropsToState: () => ({ value: props.value }),
4343
sideEffects: [dispatchEffect],

packages/react-bindings/test/hooks/useStateManager-test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type TestComponentProps = Partial<TestState> & {
3333
}
3434

3535
const TestComponent: React.FunctionComponent<TestComponentProps> = props => {
36-
const [state, actions] = useStateManager(createTestManager, {
36+
const { state, actions } = useStateManager(createTestManager, {
3737
mapPropsToInitialState: () => ({
3838
open: props.defaultOpen,
3939
value: props.defaultValue,

0 commit comments

Comments
 (0)