-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(MainSiteArticleBody): added MainSiteArticleBody component (#201)
* initial article * finished body * update legacy mdx file * refactor CSS global
- Loading branch information
Showing
5 changed files
with
245 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 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,69 @@ | ||
--- | ||
name: Main Site Article Body | ||
route: /main-site-article-body | ||
--- | ||
|
||
import { Playground, Props } from 'docz' | ||
import MainSiteArticleBody from '.' | ||
import MainSiteImage from '../MainSiteImage' | ||
import { css } from 'react-emotion' | ||
|
||
# Main Site Article Body | ||
|
||
How an article displays on the main site | ||
|
||
<Props of={MainSiteArticleBody} /> | ||
|
||
## Internal components | ||
Internal images must follow the props given by `MainSiteImage` | ||
<Props of={MainSiteImage} /> | ||
|
||
|
||
## Example usage | ||
<Playground> | ||
<MainSiteArticleBody | ||
isLegacy={false} | ||
content={ | ||
[ | ||
{ | ||
type: 'text', | ||
value: { | ||
isHTML: false, | ||
value: 'Former UCLA doctor James Heaps is facing a growing number of civil suits for alleged sexual abuse.' | ||
} | ||
}, | ||
{ | ||
type: 'text', | ||
value: { | ||
isHTML: false, | ||
value: 'Two more civil lawsuits from nine women alleging sexual abuse by Heaps were filed Tuesday, according to a press release from Manly, Stewart & Finaldi, the law firm representing the women. This brings the total number of civil suits against Heaps up to at least five. Three of the nine women were UCLA students at the time of the alleged incidents, according to court documents.' | ||
} | ||
}, | ||
{ | ||
type: 'text', | ||
value: { | ||
isHTML: false, | ||
value: 'Heaps worked at the Ronald Reagan UCLA Medical Center from 2014 to 2018 as an obstetrician-gynecologist and held medical staff privileges there for about 30 years. Prior to his employment at the medical center, he worked at what is now the UCLA Arthur Ashe Student Health and Wellness Center as a part-time doctor from 1983 to 2010.' | ||
} | ||
}, | ||
{ | ||
type: 'image', | ||
value: { | ||
imageURL: 'https://dailybruin.com/images/2018/06/web.sp_.kellihayes.KH_.1-640x426.jpg', | ||
imageCaption: 'Anna Tsai, a first-year physics student, designed "The Garden of Eden" for the 18th Fashion and Student Trends runway show, which took place Thursday night in Pauley Pavilion.', | ||
imageCredit: 'Joe Bruin', | ||
imageStaffPosition: 'Daily Bruin senior staff', | ||
imageCreditProfileURL: 'https://google.com' | ||
} | ||
}, | ||
{ | ||
type: 'text', | ||
value: { | ||
isHTML: true, | ||
value: '\n<p>Additionally, the city approved an NWWNC-endorsed bid <a href=\"https:\/\/dailybruin.com\/2018\/04\/24\/broxton-avenue-proposed-to-turn-into-pedestrian-only-area-for-events\/\" target=\"_blank\" rel=\"noreferrer noopener\">to transform the south side of Broxton Avenue into a pedestrian plaza<\/a>, which would permanently close the area off to traffic and reserve it for people and events, Skiles said.<\/p>\n' | ||
} | ||
} | ||
] | ||
} | ||
/> | ||
</Playground> |
This file contains 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,161 @@ | ||
import * as React from 'react' | ||
import { css } from 'react-emotion' | ||
import reactStringReplace from 'react-string-replace' | ||
// tslint:disable-next-line:no-submodule-imports | ||
import { renderToStaticMarkup } from 'react-dom/server' | ||
import MainSiteLink from '../MainSiteLink' | ||
import MainSiteImage, { MainSiteImageProps } from '../MainSiteImage' | ||
import { | ||
bodyTextSize, | ||
bodyFont, | ||
bodyTextCSS, | ||
} from '../../globals/mainsiteGlobalStyles' | ||
|
||
enum ContentType { | ||
Text = 'text', | ||
Image = 'image', | ||
Line = 'line', | ||
Video = 'video', | ||
Break = 'break', | ||
} | ||
|
||
interface Content { | ||
type: ContentType | ||
/** This takes in a JSON object with the appropriate props */ | ||
value?: any | ||
} | ||
|
||
/** | ||
* Properties required for a main site article | ||
*/ | ||
export interface MainSiteArticleBodyProps { | ||
/** Determines whether this is pre Gutenberg Block wordpress (< 5.0) */ | ||
isLegacy: boolean | ||
/** Array of content to be rendered */ | ||
content: Content[] | ||
/** Legacy content string */ | ||
legacyContent?: string | ||
} | ||
|
||
interface MainSiteText { | ||
/** Whether this should be rendered as HTML or in a p tag */ | ||
isHTML: boolean | ||
value: string | ||
} | ||
|
||
const bodySizeCSS = css` | ||
margin-left: auto; | ||
margin-right: auto; | ||
max-width: 620px; | ||
padding: 1rem; | ||
` | ||
|
||
class MainSiteArticleBody extends React.Component<MainSiteArticleBodyProps> { | ||
public render() { | ||
/** Check and render legacy content */ | ||
if (this.props.isLegacy) { | ||
return ( | ||
<article | ||
className={css` | ||
${bodySizeCSS}; | ||
${bodyTextCSS}; | ||
`} | ||
dangerouslySetInnerHTML={{ | ||
__html: this.props.legacyContent, | ||
}} | ||
/> | ||
) | ||
} | ||
|
||
const renderedContent = this.props.content.map( | ||
(content: any, i: number) => { | ||
switch (content.type) { | ||
case ContentType.Text: | ||
const text = content.value as MainSiteText | ||
if (!text.isHTML) { | ||
return ( | ||
<p | ||
key={i} | ||
className={css` | ||
${bodyTextCSS}; | ||
`} | ||
> | ||
{text.value} | ||
</p> | ||
) | ||
} else { | ||
/** Replace all links with a MainSiteLink */ | ||
/** | ||
* We render the links as MainSiteLinks in a string | ||
* and use react-string-replace to help with the final output | ||
*/ | ||
const replacedText = reactStringReplace( | ||
text.value, | ||
/<\s*a[^>] *(.*?)<\s*\/\s*a>/g, | ||
(match, num: number) => { | ||
// first we find the link text and URL | ||
const linkURLStart: number = match.indexOf('href="') + 6 | ||
const linkURLEnd: number = match.indexOf( | ||
'"', | ||
linkURLStart + 1 | ||
) | ||
const linkURLString: string = match.substring( | ||
linkURLStart, | ||
linkURLEnd | ||
) | ||
|
||
// next we find the link text | ||
const textStart: number = match.indexOf('>', linkURLEnd) + 1 | ||
const textString: string = match.substring(textStart) | ||
|
||
// render this as a MainSiteLink in static markup | ||
return renderToStaticMarkup( | ||
<MainSiteLink key={num} href={linkURLString}> | ||
{textString} | ||
</MainSiteLink> | ||
) | ||
} | ||
) | ||
|
||
// remove outer <p> tags | ||
const stringText = replacedText.join('') | ||
const firstTag = stringText.indexOf('<p>') | ||
const finalTag = stringText.lastIndexOf('</p>') | ||
const finalRender = stringText.substring(firstTag + 3, finalTag) | ||
|
||
return ( | ||
<p | ||
key={i} | ||
className={css` | ||
${bodyTextCSS}; | ||
`} | ||
dangerouslySetInnerHTML={{ | ||
__html: finalRender, | ||
}} | ||
/> | ||
) | ||
} | ||
case ContentType.Image: | ||
const image = content.value as MainSiteImageProps | ||
return <MainSiteImage key={i} {...image} /> | ||
case ContentType.Line: | ||
return <hr /> | ||
case ContentType.Break: | ||
return <br /> | ||
} | ||
} | ||
) | ||
|
||
return ( | ||
<article | ||
className={css` | ||
${bodySizeCSS}; | ||
`} | ||
> | ||
{renderedContent} | ||
</article> | ||
) | ||
} | ||
} | ||
|
||
export default MainSiteArticleBody |
This file contains 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 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 |
---|---|---|
|
@@ -13587,6 +13587,12 @@ react-simple-code-editor@^0.9.0: | |
version "0.9.10" | ||
resolved "https://registry.yarnpkg.com/react-simple-code-editor/-/react-simple-code-editor-0.9.10.tgz#1ab5ea7215687ed918c6d0dae90736cf01890905" | ||
|
||
[email protected]: | ||
version "0.4.4" | ||
resolved "https://registry.yarnpkg.com/react-string-replace/-/react-string-replace-0.4.4.tgz#24006fbe0db573d5be583133df38b1a735cb4225" | ||
dependencies: | ||
lodash "^4.17.4" | ||
|
||
[email protected]: | ||
version "5.4.4" | ||
resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-5.4.4.tgz#3fa787999492be94b228e4540a7211556bf4fd94" | ||
|