Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Add DocumentCardLogo and DoucmentCardStatus for Conversation card",
"type": "patch"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

minor

}
],
"packageName": "office-ui-fabric-react",
"email": "inateeg@microsoft.com"
}
Empty file added common/last-install.flag
Empty file.
Empty file.
9 changes: 9 additions & 0 deletions common/npm-local/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"dependencies": {
"npm": "3.10.9"
},
"description": "Temporary file generated by the Rush tool",
"name": "npm-local-install",
"private": true,
"version": "0.0.0"
}
7 changes: 7 additions & 0 deletions common/npmx-link.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"localLinks": {
"todo-app": [
"office-ui-fabric-react"
]
}
}
14 changes: 14 additions & 0 deletions common/rush-link.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"localLinks": {
"fabric-website": [
"@uifabric/utilities",
"office-ui-fabric-react"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i'm confused why these files are in the PR...

],
"office-ui-fabric-react": [
"@uifabric/utilities"
],
"todo-app": [
"office-ui-fabric-react"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@ $ms-DocumentCardActivity-personaTextGutter: 8px;
font-size: $ms-font-size-s;
}


/** Title **/
$DocumentCard-title-lineHeight: 21px;
.title {
Expand All @@ -286,4 +285,30 @@ $DocumentCard-title-lineHeight: 21px;
line-height: $DocumentCard-title-lineHeight;
overflow: hidden;
word-wrap: break-word;
}
}

.secondaryTitle {
padding: 8px 16px;
display: block;
@include ms-font-m;
color: $ms-color-neutralSecondary;
line-height: 18px;
overflow: hidden;
word-wrap: break-word;
height: 45px;
}

.logo {
font-size: 32px;
color: $ms-color-themePrimary;
display: block;
@include ms-padding(16px, 16px, 0, 16px);
}

.status {
@include ms-margin(8px, 16px, 8px, 16px);
@include ms-font-m;
color: $ms-color-neutralPrimary;
background-color: $ms-color-neutralLighter;
height: 32px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { DocumentCardPreview } from './DocumentCardPreview';
import { DocumentCardLocation } from './DocumentCardLocation';
import { DocumentCardActivity } from './DocumentCardActivity';
import { DocumentCardActions } from './DocumentCardActions';
import { DocumentCardLogo } from './DocumentCardLogo';
import { DocumentCardStatus } from './DocumentCardStatus';
import { PersonaInitialsColor } from '../../Persona';
import { ImageFit } from '../../Image';
import { IButtonProps } from '../../Button';
Expand Down Expand Up @@ -144,6 +146,12 @@ export interface IDocumentCardPreviewImage {
* If provided, icon will be rendered instead of image.
*/
previewIconProps?: IIconProps;

/**
* The props for the preview icon container classname.
* If provided, icon container classname will be used..
*/
previewIconContainerClass?: string;
}

export interface IDocumentCardTitleProps extends React.Props<DocumentCardTitle> {
Expand All @@ -162,6 +170,12 @@ export interface IDocumentCardTitleProps extends React.Props<DocumentCardTitle>
* @defaultvalue true
*/
shouldTruncate?: boolean;

/**
* Whether show as title as secondary title style such as smaller font and lighter color.
* @defaultvalue false
*/
showAsSecondaryTitle?: boolean;
}

export interface IDocumentCardLocationProps extends React.Props<DocumentCardLocation> {
Expand Down Expand Up @@ -247,3 +261,35 @@ export interface IDocumentCardActionsProps extends React.Props<DocumentCardActio
*/
views?: Number;
}

export interface IDocumentCardLogoProps extends React.Props<DocumentCardLogo> {
/**
* Gets the component ref.
*/
componentRef?: () => void;
/**
* Describes DocumentCard Logo badge.
*/
logoIcon: string;

/**
* Describe Logo name, optional.
*/
logoName?: string;
}

export interface IDocumentCardStatusProps extends React.Props<DocumentCardStatus> {
/**
* Gets the component ref.
*/
componentRef?: () => void;
/**
* Describes DocumentCard status icon.
*/
statusIcon?: string;

/**
* Describe status information. Required field.
*/
status: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as React from 'react';
import { BaseComponent, css } from '../../Utilities';
import { IDocumentCardLogoProps } from './DocumentCard.types';
import { Icon } from '../../Icon';
import * as stylesImport from './DocumentCard.scss';
const styles: any = stylesImport;

export class DocumentCardLogo extends BaseComponent<IDocumentCardLogoProps, any> {
public render() {
const { logoIcon } = this.props;

return (
<div className={ css('ms-DocumentCardLogo', styles.logo) }>
<Icon iconName={ logoIcon } />
</div>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export class DocumentCardPage extends React.Component<IComponentDemoPageProps, {
<p>
This example shows a couple of optional abilities, including being able to have a card represent multiple items, being able to expose up to three relevant commands, and showing the number of views in the bottom right corner.
</p>
<p>
Also show a card with Logo, text preview and status that is used for Conversation card.
</p>
<DocumentCardCompleteExample />
</ExampleCard>
<ExampleCard title='DocumentCard with compact layout ' code={ DocumentCardCompactExampleCode }>
Expand Down Expand Up @@ -80,7 +83,7 @@ export class DocumentCardPage extends React.Component<IComponentDemoPageProps, {
isHeaderVisible={ this.props.isHeaderVisible }
componentStatus={
<ComponentStatus
{...DocumentCardStatus}
{ ...DocumentCardStatus }
/>
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ export class DocumentCardPreview extends BaseComponent<IDocumentCardPreviewProps
}

private _renderPreviewImage(previewImage: IDocumentCardPreviewImage): React.ReactElement<React.HTMLAttributes<HTMLDivElement>> {
const { width, height, imageFit, previewIconProps } = previewImage;
const { width, height, imageFit, previewIconProps, previewIconContainerClass } = previewImage;
const iconContainerClass = previewIconContainerClass ? previewIconContainerClass : 'ms-DocumentCardPreview-iconContainer';

if (previewIconProps) {
return (
<div className={ css('ms-DocumentCardPreview-iconContainer', styles.previewIconContainer) } style={ { width: width, height: height } } >
<div className={ css(iconContainerClass, styles.previewIconContainer) } style={ { width: width, height: height } } >
<Icon { ...previewIconProps } />
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* tslint:disable:no-unused-variable */
import * as React from 'react';
/* tslint:enable:no-unused-variable */

import {
BaseComponent,
autobind,
css
} from '../../Utilities';
import { IDocumentCardStatusProps } from './DocumentCard.types';
import * as stylesImport from './DocumentCard.scss';
import { Icon } from '../../Icon';
const styles: any = stylesImport;

export class DocumentCardStatus extends BaseComponent<IDocumentCardStatusProps, any> {
constructor(props: IDocumentCardStatusProps) {
super(props);
}

public render() {
const { statusIcon, status } = this.props;
const iconProps = {
iconName: statusIcon, styles: {
root: { padding: '8px' }
}
};
return (
<div className={ css('ms-DocumentCardStatus', styles.status) }>
{ statusIcon && <Icon { ...iconProps } /> }
{ status }
</div>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '../../Utilities';
import { IDocumentCardTitleProps } from './DocumentCard.types';
import * as stylesImport from './DocumentCard.scss';

const styles: any = stylesImport;

export interface IDocumentCardTitleState {
Expand All @@ -19,6 +20,10 @@ export interface IDocumentCardTitleState {
const TRUNCATION_SEPARATOR = '&hellip;';
const TRUNCATION_MINIMUM_LENGTH = 40; // This is the length we know can fit into the min width of DocumentCard.
const TRUNCATION_MAXIMUM_LENGTH = 90 - TRUNCATION_SEPARATOR.length;

// This is the length we know can fit into the min width 2 lines of DocumentCard.
const TRUNCATION_MINI_LENGTH_SECONDARY = 80;
const TRUNCATION_MAX_LENGTH_SECONDARY = 130 - TRUNCATION_SEPARATOR.length;
const TRUNCATION_FIRST_PIECE_LONGER_BY = 10;
const TRUNCATION_VERTICAL_OVERFLOW_THRESHOLD = 5;

Expand All @@ -38,8 +43,9 @@ export class DocumentCardTitle extends BaseComponent<IDocumentCardTitleProps, ID
}

public componentDidMount() {
const { title, shouldTruncate } = this.props;
if (shouldTruncate && title && title.length > TRUNCATION_MINIMUM_LENGTH) {
const { title, shouldTruncate, showAsSecondaryTitle } = this.props;
const miniLength = showAsSecondaryTitle ? TRUNCATION_MINI_LENGTH_SECONDARY : TRUNCATION_MINIMUM_LENGTH;
if (shouldTruncate && title && title.length > miniLength) {
if (this._doesTitleOverflow()) {
this._startTruncation(this.props);
}
Expand All @@ -51,7 +57,8 @@ export class DocumentCardTitle extends BaseComponent<IDocumentCardTitleProps, ID
this._events.off(window, 'resize');
this._isTruncated = false;

if (newProps.shouldTruncate && newProps.title && newProps.title.length > TRUNCATION_MINIMUM_LENGTH) {
const miniLength = newProps.showAsSecondaryTitle ? TRUNCATION_MINI_LENGTH_SECONDARY : TRUNCATION_MINIMUM_LENGTH;
if (newProps.shouldTruncate && newProps.title && newProps.title.length > miniLength) {
this._startTruncation(newProps);
this._events.on(window, 'resize', this._updateTruncation);
}
Expand All @@ -65,37 +72,42 @@ export class DocumentCardTitle extends BaseComponent<IDocumentCardTitleProps, ID
}

public render() {
const { title, shouldTruncate } = this.props;
const { title, shouldTruncate, showAsSecondaryTitle } = this.props;
const { truncatedTitleFirstPiece, truncatedTitleSecondPiece } = this.state;

let documentCardTitle;
if (shouldTruncate && this._isTruncated) {
documentCardTitle = (
<div className={ css('ms-DocumentCardTitle', styles.title) } ref={ this._titleElement } title={ title }>{ truncatedTitleFirstPiece }&hellip;{ truncatedTitleSecondPiece }</div>
<div className={ css('ms-DocumentCardTitle', showAsSecondaryTitle ? styles.secondaryTitle : styles.title) } ref={ this._resolveRef('_titleElement') } title={ title }>
{ truncatedTitleFirstPiece }&hellip;{ truncatedTitleSecondPiece }
</div>
);
} else {
documentCardTitle = (
<div className={ css('ms-DocumentCardTitle', styles.title) } ref={ this._titleElement } title={ title }>{ title }</div>
<div className={ css('ms-DocumentCardTitle', showAsSecondaryTitle ? styles.secondaryTitle : styles.title) } ref={ this._resolveRef('_titleElement') } title={ title }>
{ title }
</div>
);
}

return documentCardTitle;
}

private _startTruncation = (props: IDocumentCardTitleProps): void => {
const originalTitle = props.title;
this._isTruncated = false;
const miniLength = props.showAsSecondaryTitle ? TRUNCATION_MINI_LENGTH_SECONDARY : TRUNCATION_MINIMUM_LENGTH;
const maxLength = props.showAsSecondaryTitle ? TRUNCATION_MAX_LENGTH_SECONDARY : TRUNCATION_MAXIMUM_LENGTH;

// If the title is really short, there's no need to truncate it
if (originalTitle && originalTitle.length >= TRUNCATION_MINIMUM_LENGTH) {
if (originalTitle && originalTitle.length >= miniLength) {

// Break the text into two pieces for assembly later
if (originalTitle.length > TRUNCATION_MAXIMUM_LENGTH) {
if (originalTitle.length > maxLength) {
// The text is really long, so we can take a chunk out of the middle so the two pieces combine for the maximum length
this._isTruncated = true;
this.setState({
truncatedTitleFirstPiece: originalTitle.slice(0, TRUNCATION_MAXIMUM_LENGTH / 2 + TRUNCATION_FIRST_PIECE_LONGER_BY),
truncatedTitleSecondPiece: originalTitle.slice(originalTitle.length - (TRUNCATION_MAXIMUM_LENGTH / 2 - TRUNCATION_FIRST_PIECE_LONGER_BY))
truncatedTitleFirstPiece: originalTitle.slice(0, maxLength / 2 + TRUNCATION_FIRST_PIECE_LONGER_BY),
truncatedTitleSecondPiece: originalTitle.slice(originalTitle.length - (maxLength / 2 - TRUNCATION_FIRST_PIECE_LONGER_BY))
});
} else {
// The text is not so long, so we'll just break it into two pieces
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ export class DocumentCardCompactExample extends React.Component<any, any> {
]
};

const previewOutlookUsingIcon: IDocumentCardPreviewProps = {
previewImages: [
{
previewIconProps: { iconName: 'OutlookLogo', styles: { root: { fontSize: 42, color: '#0078d7' } } },
previewIconContainerClass: 'ms-DocumentCardPreview-iconContainer2',
width: 144
}
]
};

return (
<div>
<DocumentCard type={ DocumentCardType.compact } onClickHref='http://bing.com'>
Expand Down Expand Up @@ -109,6 +119,24 @@ export class DocumentCardCompactExample extends React.Component<any, any> {
/>
</div>
</DocumentCard>
<p />
<DocumentCard type={ DocumentCardType.compact } onClickHref='http://bing.com'>
<DocumentCardPreview { ...previewOutlookUsingIcon } />
<div className='ms-DocumentCard-details'>
<DocumentCardTitle
title='Conversation about anual report from SharePoint conference'
shouldTruncate={ true }
/>
<DocumentCardActivity
activity='Sent a few minutes ago'
people={
[
{ name: 'Kat Larrson', profileImageSrc: TestImages.personaFemale }
]
}
/>
</div>
</DocumentCard>
</div>
);
}
Expand Down
Loading