-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Experimental Chiclet Component #4678
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
Changes from 32 commits
fb26b91
ad94997
542fcf8
c6f0aab
5d7f668
56f52c9
15ccf73
1012e4c
ee82f29
fd42f49
fc90f50
3fa9d9e
3df9860
a2b0fa5
2e5978d
e497323
d0b31a2
d3a9f0d
acbcbc2
26cb7d0
bbacc49
600e4c8
7742c47
2f3ca5b
4e44852
64af2e7
5b4d21d
4e87878
b9581b7
3719108
7d1104d
f873b97
5020b32
eb3b959
a44db3b
4ba3924
65fba98
2b65727
3965f9a
c91dfe3
806aff1
cbe9c0f
eba2185
00c9ca3
6d762d2
7a35619
db18be7
02849e3
ada5ffe
9a1b9c6
4756ed0
a0d6e73
68b9102
1abe186
d353ed7
6bad6f0
49c756b
972d37d
16156a8
275bbc2
db80bf2
70badd3
5b381fb
8f17013
9a7d9e8
be9118f
b33c5b8
51f1ba8
679e0a6
c404200
7a550dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,4 +30,4 @@ | |
| "devDependencies": { | ||
| "@microsoft/rush": "4.3.0" | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export * from './components/Chiclet/index'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| const baseProductionCdnUrl = 'https://az742526.vo.msecnd.net/files/odsp-next-release-odc_2018-04-13_20180418.001/odsp-media/images/apps/'; | ||
|
|
||
| export const ChicletTestImages = { | ||
| iconWordDoc: baseProductionCdnUrl + 'word_16x1.svg', | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import * as React from 'react'; | ||
| import { | ||
| BaseComponent | ||
| } from '../../Utilities'; | ||
| import { Chiclet } from './Chiclet'; | ||
| import { ChicletSize } from './Chiclet.types'; | ||
| import { OpenGraphUtilities } from './OpenGraph'; | ||
| import { IBaseChicletProps } from './BaseChiclet.types'; | ||
|
|
||
| export class BaseChiclet extends BaseComponent<IBaseChicletProps, any> { | ||
| constructor(props: IBaseChicletProps) { | ||
| super(props); | ||
|
|
||
| let chicletCardProps = OpenGraphUtilities.extractMetaTags(this.props.url); | ||
| this.state = { chicletCardProps: chicletCardProps }; | ||
| } | ||
|
|
||
| public render() { | ||
| const { size, actions } = this.props; | ||
| const { chicletCardProps } = this.state; | ||
|
|
||
| return ( | ||
| <Chiclet chicletCardProps={ chicletCardProps } size={ size ? size : ChicletSize.medium } actions={ actions } /> | ||
| ); | ||
| } | ||
|
|
||
| public componentWillReceiveProps(nextProps: any) { | ||
| if (this.props.url != nextProps.url) { | ||
| this.setState({ chicletCardProps: OpenGraphUtilities.extractMetaTags(this.props.url) }); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import * as React from 'react'; | ||
| import { BaseChiclet } from './BaseChiclet'; | ||
| import { ChicletSize } from './Chiclet.types'; | ||
|
|
||
| export interface IBaseChiclet { | ||
|
|
||
| } | ||
|
|
||
| export interface IBaseChicletProps extends React.Props<BaseChiclet> { | ||
| /** | ||
| * Optional callback to access the IBaseChiclet interface. Use this instead of ref for accessing | ||
| * the public methods and properties of the component. | ||
| */ | ||
| componentRef?: (component: IBaseChiclet | null) => void; | ||
|
|
||
| /** | ||
| * Optional class for chiclet. | ||
| */ | ||
| className?: string; | ||
|
|
||
| /** | ||
| * Sharing link | ||
| */ | ||
| url: string; | ||
|
|
||
| /** | ||
| * Chiclet size to render | ||
| */ | ||
| size?: ChicletSize; | ||
|
|
||
| /** | ||
| * Action icon buttons to render. | ||
| */ | ||
| actions?: string[]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| import { memoizeFunction } from '../../Utilities'; | ||
| import { | ||
| ITheme, | ||
| concatStyleSets, | ||
| getTheme | ||
| } from '../../Styling'; | ||
| import { IChicletCardStyles } from './ChicletCard.types'; | ||
|
|
||
| const ChicletCardTitleLineHeight = '21px'; | ||
|
|
||
| /* Actions */ | ||
| const msChicletCardActionsActionSize = '34px'; | ||
| const msChicletCardActionsHorizontalPadding = '12px'; | ||
| const msChicletCardActionsVerticalPadding = '2px'; | ||
|
|
||
| export const getClassNames = memoizeFunction(( | ||
| theme: ITheme = getTheme(), | ||
| customStyles?: IChicletCardStyles | ||
| ): IChicletCardStyles => { | ||
| const styles: IChicletCardStyles = { | ||
| root: { | ||
| WebkitFontSmoothing: 'antialiased', | ||
| backgroundColor: theme.palette.white, | ||
| borderRadius: '2px', | ||
| boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.3)', | ||
| width: '600px', | ||
| height: '126px', | ||
| userSelect: 'none', | ||
| position: 'relative', | ||
| selectors: { | ||
| ':hover': { | ||
| cursor: 'pointer' | ||
| } | ||
| } | ||
| }, | ||
| icon: [ | ||
| 'ms-DocumentCardPreview-icon', | ||
| { | ||
| padding: '10px 166px 8px 8px', | ||
| //bottom: '10px', | ||
| position: 'absolute', | ||
| color: '#166EBE' | ||
| } | ||
| ], | ||
| preview: [ | ||
| 'ms-ChicletCardPreview', | ||
| { | ||
| float: 'left', | ||
| height: '122px', | ||
| width: '198px', | ||
| position: 'relative', | ||
| //opacity: '0.02', | ||
| overflow: 'hidden', // need to fix | ||
| backgroundColor: theme.palette.white, | ||
| display: 'block', | ||
| padding: '2px 0px 2px 2px', | ||
| } | ||
| ], | ||
| info: [ | ||
| 'ms-ChicletCardInfo', | ||
| { | ||
| position: 'relative', | ||
| display: 'block', | ||
| height: '100%', | ||
| //lineHeight: '21px', | ||
| overflow: 'hidden', | ||
| wordWrap: 'break-word', | ||
| weight: '400px' | ||
| } | ||
| ], | ||
| title: [ | ||
| 'ms-ChicletCardTitle', | ||
| { | ||
| padding: '9px 26px 5px 11px', | ||
| //font: theme.fonts.large, | ||
| fontSize: '16px', | ||
| fontWeight: 'normal', | ||
| fontStyle: 'normal', | ||
| fontStretch: 'normal', | ||
| color: theme.palette.neutralPrimary, | ||
| letterSpacing: 'normal', | ||
| textAlign: 'left', | ||
| height: '41px', // Two lines of text, making sure the third line is hidden | ||
| width: '363px', | ||
| lineHeight: '1.25', | ||
| overflow: 'hidden', | ||
| wordWrap: 'break-word' | ||
| } | ||
| ], | ||
| link: [ | ||
| 'ms-ChicletCardLink', | ||
| { | ||
| padding: '0px 16px 25px 11px', | ||
| fontSize: '12px', | ||
| fontWeight: 'normal', | ||
| fontStyle: 'normal', | ||
| fontStretch: 'normal', | ||
| lineHeight: '1.33', | ||
| letterSpacing: 'normal', | ||
| textAlign: 'left', | ||
| color: '#797671', | ||
| width: '248px', | ||
| height: '16px', | ||
| overflow: 'hidden', | ||
| whiteSpace: 'nowrap', | ||
| textOverflow: 'ellipsis' | ||
| } | ||
| ], | ||
| actions: [ | ||
| 'ms-ChicletFooter', | ||
| { | ||
| paddingRight: '6px', | ||
| height: '24px', | ||
| position: 'relative' | ||
| } | ||
| ], | ||
| action: [ | ||
| 'ms-ChicletFooter-action', | ||
| { | ||
| float: 'right', | ||
| cursor: 'pointer', | ||
| width: '32px', | ||
| height: '32px', | ||
| backgroundColor: theme.palette.white, | ||
| color: '#0078D7' | ||
| } | ||
| ] | ||
| }; | ||
|
|
||
| return concatStyleSets(styles, customStyles)!; | ||
|
|
||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import * as React from 'react'; | ||
| import { IChicletProps, ChicletSize } from './Chiclet.types'; | ||
| import { IChicletCardProps, IChicletAction } from './ChicletCard.types'; | ||
| import { ChicletCard } from './ChicletCard'; | ||
|
|
||
| export class Chiclet extends React.Component<IChicletProps, IChicletCardProps> { | ||
| public render() { | ||
| const { chicletCardProps, size, actions } = this.props; | ||
|
|
||
| var actionsToIChicletActionProps: IChicletAction[] = []; | ||
| if (actions != null) { | ||
| actions.forEach(function (string) { | ||
| switch (string) { | ||
| case "Breadcrumb": | ||
| actionsToIChicletActionProps.push({ buttonProps: { iconProps: { iconName: 'Breadcrumb' } } }); | ||
| break; | ||
| case "Save": | ||
| actionsToIChicletActionProps.push({ buttonProps: { iconProps: { iconName: 'Save' } } }); | ||
| break; | ||
| case "Share": | ||
| actionsToIChicletActionProps.push({ buttonProps: { iconProps: { iconName: 'Share' } } }); | ||
| break; | ||
| default: | ||
| break; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| switch (size) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Each case returns the same DOM as far as I can tell. Intentional as an area of extensibility later?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes exactly!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general, we should not add extra prototype code that we know will need to change eventually. Let's just add to this when we get there. Maybe add a @todo comment to mention what you intend to do. |
||
| case ChicletSize.medium: | ||
| return ( | ||
| <ChicletCard {...chicletCardProps} onClick={ this._onClick } actions={ actionsToIChicletActionProps } /> | ||
| ); | ||
| // @todo: handle other types of chiclets | ||
| default: | ||
| return ( | ||
| <ChicletCard {...chicletCardProps} onClick={ this._onClick } actions={ actionsToIChicletActionProps } /> | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| private _onClick(): void { // @todo: default click handler | ||
| console.log("You clicked the Chiclet"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // @todo: default click handler |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import * as React from 'react'; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's split this file into 3 one for each component: ChicletCard.types.ts, Chiclet.types.ts and BaseChiclet.types.ts |
||
| import { Chiclet } from './Chiclet'; | ||
| import { IChicletCardProps } from './ChicletCard.types'; | ||
|
|
||
| export interface IChiclet { | ||
|
|
||
| } | ||
|
|
||
| export interface IChicletProps extends React.Props<Chiclet> { | ||
| /** | ||
| * Props to render in the chosen ChicletCard | ||
| */ | ||
| chicletCardProps?: IChicletCardProps | undefined; | ||
|
|
||
| /** | ||
| * Chiclet size to render | ||
| */ | ||
| size?: ChicletSize; | ||
|
|
||
| /** | ||
| * Action icon buttons to render. | ||
| */ | ||
| actions?: string[]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still think the type of actions should be IChicletAction all the way up. We'd need to send in the onClick too, right? |
||
| } | ||
|
|
||
| export enum ChicletSize { | ||
| /** | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You likely don't need to supply values for this enum in its current usage. You may need it if you use the values later as part of assigning the sizes to the props for the node. I left a comment elsewhere about that potential enhancement. |
||
| * X-Small Chiclet | ||
| */ | ||
| xsmall = 0, | ||
|
|
||
| /** | ||
| * Small Chiclet | ||
| */ | ||
| small = 1, | ||
|
|
||
| /** | ||
| * Medium Chiclet | ||
| */ | ||
| medium = 2, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The naming convention for enum members is InitialCaps
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Most enums in the fabric codebase seem to be lowerCamelCased... let's go with consistency now, and if we want to change the convention, do it all in one go? |
||
|
|
||
| /** | ||
| * Large Chiclet | ||
| */ | ||
| large = 3 | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please avoid using
memoizeFunctionandgetClassNames. Instead, usestyledhelper and thegetStylesprop to make things style-able.Follow the guidance here:
https://github.com/OfficeDev/office-ui-fabric-react/blob/master/ghdocs/BestPractices/Styling.md