-
Notifications
You must be signed in to change notification settings - Fork 2.9k
ComponentPage: Add Edit On GitHub buttons to page sections #4424
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
Merged
Merged
Changes from 30 commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
7382b77
Add edit buttons and some APIs to ComponentPage.
26988d4
Remove duplicate export
e39b916
Remove test url
45ca1af
More documentation, better type safety, and more a11y.
bedff98
Fix editOverviewUrl prop.
3967779
npm run changes output
484d376
Make edit buttons go directly to GitHub editor.
05fb3c4
change to let for string replacement
59834df
Merge branch 'master' into edit-docs-buttons
f4712b8
Fix edit url changer
7628089
Remove className from edit buttons
b109e71
Remove View on Github from Pivot
07d41d6
Merge branch 'master' into edit-docs-buttons
beefb6a
return undefined if no url before computing urls
de00933
Compute URL only if generated
6a3269e
Add github link method
5983aed
Add link below overview
3a9c52d
Remove view button
4c25b8e
Switch from `componentName` to `title`
b0e1755
Merge branch 'master' into edit-docs-buttons
61cf9ef
eod
03c4ca1
Add Edit button to Best Practices
29f905d
Only render edit button if section has PageMarkdown
1564123
No best practices
5f8739c
Remove console log
c4fcb7d
Better switch type safety.
61afbd7
Remove spaces from component name.
a5295c0
nit
9cc735b
Fix type error when props are undefined.
05a6870
removed commented code
0445d25
Alphebetize enum
0de2372
Rename class
5e55da4
Fix screen reader label
525b0ab
Split button off into subcomponent
b43c08d
fix export
jordandrako File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
common/changes/@uifabric/example-app-base/edit-docs-buttons_2018-03-31-00-27.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "changes": [ | ||
| { | ||
| "packageName": "@uifabric/example-app-base", | ||
| "comment": "Add new APIs for editing sections on GitHub.", | ||
| "type": "minor" | ||
| } | ||
| ], | ||
| "packageName": "@uifabric/example-app-base", | ||
| "email": "v-jojanz@microsoft.com" | ||
| } |
11 changes: 11 additions & 0 deletions
11
common/changes/office-ui-fabric-react/edit-docs-buttons_2018-03-31-00-27.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "changes": [ | ||
| { | ||
| "packageName": "office-ui-fabric-react", | ||
| "comment": "Add new component page prop for editing on GitHub.", | ||
| "type": "patch" | ||
| } | ||
| ], | ||
| "packageName": "office-ui-fabric-react", | ||
| "email": "v-jojanz@microsoft.com" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,9 @@ import { | |
| import { | ||
| Link | ||
| } from 'office-ui-fabric-react/lib/Link'; | ||
| import { IconButton } from 'office-ui-fabric-react/lib/Button'; | ||
| import { MessageBar } from 'office-ui-fabric-react/lib/MessageBar'; | ||
| import { TooltipHost } from 'office-ui-fabric-react/lib/Tooltip'; | ||
| import './ComponentPage.scss'; | ||
|
|
||
| export interface IComponentPageSection { | ||
|
|
@@ -32,6 +34,47 @@ export interface IComponentPageProps { | |
| otherSections?: IComponentPageSection[]; | ||
| allowNativeProps?: boolean | string; | ||
| nativePropsElement?: string | string[] | undefined; | ||
|
|
||
| /** | ||
| * Link to the Component root folder on GitHub. | ||
| * Enables 'View On GitHub' and all 'Edit' buttons. | ||
| */ | ||
| componentUrl?: string; | ||
|
|
||
| /** | ||
| * Link to the BestPractices markdown file on GitHub. | ||
| * Enables the 'Edit Best Practices' button. | ||
| * Overrides URL from componentUrl. | ||
| */ | ||
| editBestPracticesUrl?: string; | ||
|
|
||
| /** | ||
| * Link to the Donts markdown file on GitHub. | ||
| * Enables the 'Edit Don'ts' button. | ||
| * Overrides URL from componentUrl. | ||
| */ | ||
| editDontsUrl?: string; | ||
|
|
||
| /** | ||
| * Link to the Dos markdown file on GitHub. | ||
| * Enables the 'Edit Dos' button. | ||
| * Overrides URL from componentUrl. | ||
| */ | ||
| editDosUrl?: string; | ||
|
|
||
| /** | ||
| * Link to the Overview markdown file on GitHub. | ||
| * Enables the 'Edit Overview' button. | ||
| * Overrides URL from componentUrl. | ||
| */ | ||
| editOverviewUrl?: string; | ||
| } | ||
|
|
||
| export enum ComponentPageSection { | ||
| Dos = 0, | ||
|
Collaborator
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. Should we start these out alphabetized? |
||
| BestPractices = 1, | ||
| Donts = 2, | ||
| Overview = 3, | ||
| } | ||
|
|
||
| export class ComponentPage extends React.Component<IComponentPageProps, {}> { | ||
|
|
@@ -63,7 +106,10 @@ export class ComponentPage extends React.Component<IComponentPageProps, {}> { | |
| <div className='ComponentPage-body'> | ||
| { this._getComponentStatusBadges() } | ||
| <div className='ComponentPage-overviewSection'> | ||
| <h2 className='ComponentPage-subHeading' id='Overview'>Overview</h2> | ||
| <div className='ComponentPage-overviewSectionHeader'> | ||
| <h2 className='ComponentPage-subHeading' id='Overview'>Overview</h2> | ||
| { this._editButton(ComponentPageSection.Overview, this.props.editOverviewUrl) } | ||
| </div> | ||
| <div className='ComponentPage-overviewSectionContent'> | ||
| <div className='ComponentPage-overview'> | ||
| { overview } | ||
|
|
@@ -100,7 +146,7 @@ export class ComponentPage extends React.Component<IComponentPageProps, {}> { | |
| let { | ||
| bestPractices, | ||
| dos, | ||
| donts | ||
| donts, | ||
| } = this.props; | ||
|
|
||
| if (bestPractices && dos && donts) { | ||
|
|
@@ -153,8 +199,8 @@ export class ComponentPage extends React.Component<IComponentPageProps, {}> { | |
|
|
||
| private _getNativePropsInfo(): JSX.Element | undefined { | ||
| if (this.props.allowNativeProps) { | ||
| let elementString: string | string[] | JSX.Element = this.props.nativePropsElement || 'div', | ||
| componentString: JSX.Element | undefined; | ||
| let elementString: string | string[] | JSX.Element = this.props.nativePropsElement || 'div'; | ||
| let componentString: JSX.Element | undefined; | ||
| if (typeof elementString === 'object' && elementString.length > 1) { | ||
| const elementArr = elementString.slice(); | ||
| for (let _i = 0; _i < elementArr.length; _i++) { | ||
|
|
@@ -196,11 +242,13 @@ export class ComponentPage extends React.Component<IComponentPageProps, {}> { | |
|
|
||
| private _getDosAndDonts(): JSX.Element | undefined { | ||
| let dosAndDonts: Array<JSX.Element> = []; | ||
|
|
||
| if (this.props.bestPractices) { | ||
| dosAndDonts.push( | ||
| <div className='ComponentPage-usage' id='BestPractices' key='best-practices'> | ||
| <h2 className='ComponentPage-subHeading'>Best Practices</h2> | ||
| <div className='ComponentPage-usageHeader'> | ||
| <h2 className='ComponentPage-subHeading'>Best Practices</h2> | ||
| { this._editButton(ComponentPageSection.BestPractices, this.props.editBestPracticesUrl) } | ||
| </div> | ||
| { this.props.bestPractices } | ||
| </div> | ||
| ); | ||
|
|
@@ -210,11 +258,19 @@ export class ComponentPage extends React.Component<IComponentPageProps, {}> { | |
| dosAndDonts.push( | ||
| <div className='ComponentPage-doSections' key='do-sections'> | ||
| <div className='ComponentPage-doSection'> | ||
| <h3>Do</h3> | ||
| <div className='ComponentPage-doSectionHeader'> | ||
| <h3>Do</h3> | ||
| { this._editButton(ComponentPageSection.Dos, this.props.editDosUrl) } | ||
| </div> | ||
| <hr className='ComponentPage-doSectionHr' /> | ||
| { this.props.dos } | ||
| </div> | ||
| <div className='ComponentPage-doSection ComponentPage-doSection--dont'> | ||
| <h3>Don’t</h3> | ||
| <div className='ComponentPage-doSectionHeader'> | ||
| <h3>Don’t</h3> | ||
| { this._editButton(ComponentPageSection.Donts, this.props.editDontsUrl) } | ||
| </div> | ||
| <hr className='ComponentPage-doSectionHr' /> | ||
| { this.props.donts } | ||
| </div> | ||
| </div> | ||
|
|
@@ -287,4 +343,86 @@ export class ComponentPage extends React.Component<IComponentPageProps, {}> { | |
|
|
||
| return undefined; | ||
| } | ||
|
|
||
| private _editButton(sectionIndex: ComponentPageSection, url?: string): JSX.Element | undefined { | ||
| if (!url && !this.props.componentUrl) { | ||
| return undefined; | ||
| } | ||
|
|
||
| // Get section string for URLs and IDs. | ||
| const section = ComponentPageSection[sectionIndex]; | ||
| let readableSection = section; | ||
| const componentName = (this.props.title || this.props.componentName).replace(/\s/g, ''); | ||
|
|
||
| // Check if the section contains a function (using PageMarkdown) | ||
| const { | ||
| bestPractices, | ||
| dos, | ||
| donts, | ||
| overview, | ||
| } = this.props; | ||
| const isMarkdown = { | ||
| BestPractices: bestPractices ? typeof bestPractices.type === 'function' : false, | ||
| Dos: dos ? typeof dos.type === 'function' : false, | ||
| Donts: donts ? typeof donts.type === 'function' : false, | ||
| Overview: overview ? typeof overview.type === 'function' : false, | ||
| }; | ||
| let sectionIsMarkdown = false; | ||
| switch (sectionIndex) { | ||
| case ComponentPageSection.BestPractices: | ||
| sectionIsMarkdown = isMarkdown.BestPractices; | ||
| readableSection = 'Best Practices'; | ||
| break; | ||
| case ComponentPageSection.Dos: | ||
| sectionIsMarkdown = isMarkdown.Dos; | ||
| break; | ||
| case ComponentPageSection.Donts: | ||
| sectionIsMarkdown = isMarkdown.Donts; | ||
| readableSection = 'Don\'ts'; | ||
| break; | ||
| case ComponentPageSection.Overview: | ||
| sectionIsMarkdown = isMarkdown.Overview; | ||
| break; | ||
| default: | ||
| sectionIsMarkdown = false; | ||
| readableSection = section; | ||
| } | ||
| if (sectionIsMarkdown === false) { | ||
| return undefined; | ||
| } | ||
|
|
||
| // Generate edit URL from componentURL | ||
| let mdUrl: string | undefined = undefined; | ||
| if (this.props.componentUrl) { | ||
| mdUrl = `${this.props.componentUrl}/docs/${componentName}${section}.md`; | ||
| // Replace /tree/ or /blob/ with /edit/ to get straight to GitHub editor. | ||
| if (mdUrl!.includes('/tree/')) { | ||
| mdUrl = mdUrl!.replace('/tree/', '/edit/'); | ||
| } else if (mdUrl!.includes('/blob/')) { | ||
| mdUrl = mdUrl!.replace('/blob/', '/edit/'); | ||
| } | ||
| } | ||
|
|
||
| // Allow generated URL fallback. | ||
| const editUrl = url || mdUrl; | ||
| if (!editUrl) { | ||
| return undefined; | ||
| } | ||
|
|
||
| return ( | ||
| <TooltipHost | ||
| key={ `${componentName}-${section}-editButton` } | ||
| content={ `Edit ${componentName} ${readableSection} on GitHub` } | ||
| id={ `${componentName}-${section}-editButtonHost` } | ||
| > | ||
| <IconButton | ||
| aria-describedby={ `${componentName}-${section}-editButtonHost` } | ||
| iconProps={ { iconName: 'Edit' } } | ||
| href={ editUrl } | ||
| target='_blank' | ||
| rel='noopener noreferrer' | ||
| /> | ||
| </TooltipHost> | ||
| ); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Can you expand 'Hr' into 'Header' or what ever it's for?
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.
It's for the
<hr>tag that used to be the:afteron the header since it now has to be inside a container for the edit button.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.
Ah, makes sense now! Maybe another word then? Like 'line' or something? In case it ends up not being an hr tag someday.
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.
Good suggestion