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

Commit 8a334fc

Browse files
committed
wip !
1 parent 23b75bf commit 8a334fc

File tree

8 files changed

+156
-14
lines changed

8 files changed

+156
-14
lines changed

docs/src/components/Playground/renderConfig.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import * as Accessibility from '@fluentui/accessibility'
22
import * as CodeSandbox from '@fluentui/code-sandbox'
33
import * as DocsComponent from '@fluentui/docs-components'
44
import * as FluentUI from '@fluentui/react'
5+
import * as FluentBindings from '@fluentui/react-bindings'
56
import * as ReactFela from 'react-fela'
67
import * as _ from 'lodash'
8+
import * as PropTypes from 'prop-types'
79
import * as React from 'react'
810
import * as ReactDOM from 'react-dom'
911
import * as Classnames from 'classnames'
@@ -39,6 +41,10 @@ export const imports: Record<string, { version: string; module: any }> = {
3941
version: projectPackageJson.version,
4042
module: FluentUI,
4143
},
44+
'@fluentui/react-bindings': {
45+
version: null,
46+
module: FluentBindings,
47+
},
4248
classnames: {
4349
version: projectPackageJson.dependencies['classnames'],
4450
module: Classnames,
@@ -47,6 +53,10 @@ export const imports: Record<string, { version: string; module: any }> = {
4753
version: projectPackageJson.dependencies['lodash'],
4854
module: _,
4955
},
56+
'prop-types': {
57+
version: projectPackageJson.dependencies['prop-types'],
58+
module: PropTypes,
59+
},
5060
react: {
5161
version: projectPackageJson.peerDependencies['react'],
5262
module: React,
Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,56 @@
1-
import * as React from 'react'
21
import { Status } from '@fluentui/react'
2+
import { compose } from '@fluentui/react-bindings'
3+
import * as React from 'react'
4+
import * as PropTypes from 'prop-types'
5+
6+
const MyStatus = compose<{ title: never; disabled?: boolean; name: string }>(Status, {
7+
displayName: 'MyStatus',
8+
mapPropsToBehavior: props => {
9+
return {
10+
name: props.name,
11+
}
12+
},
13+
mapPropsToStyles: props => ({
14+
disabled: props.disabled,
15+
}),
16+
// Existing
17+
// handledProps: ['disabled']
18+
// Emotion approach
19+
shouldForwardProp: prop => prop === 'disabled',
20+
overrideStyles: true,
21+
})
22+
23+
const StatusWithProp = compose<{ square?: boolean }>(Status, {
24+
displayName: 'SquareStatus',
25+
mapPropsToStyles: props => ({
26+
square: props.square,
27+
}),
28+
})
29+
30+
StatusWithProp.propTypes = {
31+
square: PropTypes.bool,
32+
}
333

4-
const StatusExampleShorthand = () => <Status title="default state" />
34+
const StatusExampleShorthand = () => (
35+
<>
36+
<h2>
37+
Default <code>Status</code>
38+
</h2>
39+
<Status title="default state" />
40+
<h2>
41+
<code>Status</code> with additional prop
42+
</h2>
43+
<StatusWithProp />
44+
<StatusWithProp square />
45+
<h2>
46+
Composed <code>MyStatus</code>
47+
</h2>
48+
<MyStatus
49+
accessibility={props => ({ attributes: { root: { 'data-shift': props.name } } })}
50+
name="Hoba!"
51+
/>
52+
<MyStatus disabled />
53+
</>
54+
)
555

656
export default StatusExampleShorthand
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import * as React from 'react'
2+
3+
type ComposeOptions = {
4+
className?: string
5+
displayName: string
6+
mapPropsToBehavior?: Function
7+
mapPropsToStyles?: Function
8+
shouldForwardProp?: Function
9+
overrideStyles?: boolean
10+
}
11+
12+
const compose = <UserProps, CProps = {}>(
13+
Component: React.ComponentType<CProps>,
14+
options: ComposeOptions,
15+
): React.ComponentType<CProps & UserProps> => {
16+
const ComponentComponent = { ...Component }
17+
18+
ComponentComponent.displayName = options.displayName
19+
ComponentComponent.defaultProps = {
20+
...Component.defaultProps,
21+
__unstable_config: {
22+
overrideStyles: false,
23+
...options,
24+
},
25+
}
26+
27+
return ComponentComponent as any
28+
}
29+
30+
export default compose

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
} from '@fluentui/react'
1616
import resolveStylesAndClasses from '@fluentui/react/src/utils/resolveStylesAndClasses'
1717

18-
const useStyles = (displayName: string, options: any) => {
18+
const useStyles = (displayName: string | string[], options: any) => {
1919
const className = options.className || 'no-classname-🙉'
2020
const rtl = options.rtl || false
2121
const props = options.mapPropsToStyles()
@@ -25,21 +25,28 @@ const useStyles = (displayName: string, options: any) => {
2525

2626
const { disableAnimations = false, renderer = null, theme = emptyTheme } = context || {}
2727

28+
const componentVariables = Array.isArray(displayName)
29+
? displayName.map(displayName => theme.componentVariables[displayName])
30+
: [theme.componentVariables[displayName]]
31+
const componentStyles = Array.isArray(displayName)
32+
? displayName.map(displayName => theme.componentStyles[displayName])
33+
: [theme.componentStyles[displayName]]
34+
2835
// Merge inline variables on top of cached variables
2936
const resolvedVariables = mergeComponentVariables(
30-
theme.componentVariables[displayName],
37+
...componentVariables,
3138
variables,
3239
)(theme.siteVariables)
33-
40+
console.log(componentStyles, props)
3441
// Resolve styles using resolved variables, merge results, allow props.styles to override
3542
const mergedStyles: ComponentSlotStylesPrepared = mergeComponentStyles(
36-
theme.componentStyles[displayName],
43+
...componentStyles,
3744
{ root: design },
3845
{ root: styles },
3946
)
4047

4148
const styleParam: ComponentStyleFunctionParam = {
42-
displayName,
49+
displayName: Array.isArray(displayName) ? displayName[0] : displayName,
4350
props,
4451
variables: resolvedVariables,
4552
theme,

packages/react-bindings/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ export { default as useStateManager } from './hooks/useStateManager'
1717
export { default as callable } from './utils/callable'
1818
export { default as getElementType } from './utils/getElementType'
1919
export { default as getUnhandledProps } from './utils/getUnhandledProps'
20+
21+
export { default as compose } from './compose'

packages/react-bindings/src/utils/getUnhandledProps.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,19 @@
99
function getUnhandledProps<P extends Record<string, any>>(
1010
handledProps: (keyof P)[],
1111
props: P,
12+
shouldForwardProp: Function = () => false,
1213
): Partial<P> {
1314
return Object.keys(props).reduce<Partial<P>>((acc, prop) => {
14-
if (handledProps.indexOf(prop) === -1) (acc as any)[prop] = props[prop]
15+
if (shouldForwardProp(prop)) {
16+
;(acc as any)[prop] = props[prop]
17+
return acc
18+
}
1519

20+
if (handledProps.indexOf(prop) !== -1) {
21+
return acc
22+
}
23+
24+
;(acc as any)[prop] = props[prop]
1625
return acc
1726
}, {})
1827
}

packages/react/src/components/Status/Status.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,20 @@ export interface StatusProps extends UIComponentProps {
3434

3535
const Status = React.forwardRef<HTMLDivElement, WithAsProp<StatusProps>>((props, ref) => {
3636
const { className, color, icon, size, state, design, styles, variables } = props
37+
const { displayName, mapPropsToBehavior, mapPropsToStyles, overrideStyles, shouldForwardProp } =
38+
props.__unstable_config || {}
3739

3840
const { rtl }: ProviderContextPrepared = React.useContext(ThemeContext)
39-
const [classes, resolvedStyles] = useStyles(Status.displayName, {
41+
const magicName = overrideStyles
42+
? displayName || Status.displayName
43+
: [Status.displayName, displayName].filter(Boolean)
44+
const [classes, resolvedStyles] = useStyles(magicName, {
4045
className: (Status as any).className,
4146
mapPropsToStyles: () => ({
4247
color,
4348
size,
4449
state,
50+
...(mapPropsToStyles && mapPropsToStyles(props)),
4551
}),
4652
mapInlineToStyles: () => ({
4753
className,
@@ -52,12 +58,17 @@ const Status = React.forwardRef<HTMLDivElement, WithAsProp<StatusProps>>((props,
5258
rtl,
5359
})
5460
const getA11Props = useAccessibility(props.accessibility, {
55-
debugName: Status.displayName,
61+
debugName: displayName || Status.displayName,
62+
mapPropsToBehavior: mapPropsToBehavior ? () => mapPropsToBehavior(props) : undefined,
5663
rtl,
5764
})
5865
const ElementType = getElementType(props)
59-
const unhandledProps = getUnhandledProps((Status as any).handledProps /* TODO */, props)
60-
66+
const unhandledProps = getUnhandledProps(
67+
(Status as any).handledProps /* TODO */,
68+
props,
69+
shouldForwardProp,
70+
)
71+
console.log(getA11Props('root', {}))
6172
return (
6273
<ElementType {...getA11Props('root', { className: classes.root, ref, ...unhandledProps })}>
6374
{Icon.create(icon, {
@@ -83,7 +94,7 @@ const Status = React.forwardRef<HTMLDivElement, WithAsProp<StatusProps>>((props,
8394
size: customPropTypes.size,
8495
state: PropTypes.oneOf(['success', 'info', 'warning', 'error', 'unknown']),
8596
}
86-
;(Status as any).handledProps = Object.keys((Status as any).propTypes)
97+
;(Status as any).handledProps = [...Object.keys((Status as any).propTypes), '__unstable_config']
8798
Status.defaultProps = {
8899
accessibility: statusBehavior,
89100
as: 'span',

packages/react/src/themes/teams/index.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,30 @@ const teamsTheme: ThemePrepared = createTheme(
5353
{
5454
siteVariables,
5555
componentVariables,
56-
componentStyles,
56+
componentStyles: {
57+
...componentStyles,
58+
MyStatus: {
59+
root: ({ props: p }) => ({
60+
display: 'inline-flex',
61+
background: 'pink',
62+
border: '1px',
63+
borderRadius: '9999px',
64+
height: '10px',
65+
width: '10px',
66+
67+
...(p.disabled && {
68+
background: 'gray',
69+
}),
70+
}),
71+
},
72+
SquareStatus: {
73+
root: ({ props: p }) => ({
74+
...(p.square && {
75+
borderRadius: 0,
76+
}),
77+
}),
78+
},
79+
},
5780
fontFaces,
5881
staticStyles,
5982
icons,

0 commit comments

Comments
 (0)