Skip to content

Commit

Permalink
Feature/issue 574 table as dialogue (#580)
Browse files Browse the repository at this point in the history
* add new references as const

* Update ArticleFigure.js

* Update ArticleFigure.js

* add various tags

* fix link from figure label

* enable '<br/>'

* rename ArticleFigure

* addd iconoir react lib

* replace table tagged as dialog only if markdown

this requires some adjustment in the table DOM elements

* add class css when cells are tagged as "dialog"

* add method getPrefix() to get the prefix without the "-" (nicer on css)

* Update ArticleCellFigure.scss

* add <br> variant to markdown rendering

* add different icons

* use div instead of p in nested figcaption in ArticleCellFigure

* forward figureRefPrefix in ArticleToc to replace isTable isFigure

* fix missing tr

* move replacement for td from ArticleCell to pynb logic function together with all other rulsez

* refine dialog preview in the oither layer

* improve readability of ArticleCell memo

* use Mediamage instead of Image in ToC

* add cover in constrant prefix

* when cover, just use "cover" translation label in ArticleFigure
  • Loading branch information
danieleguido authored Oct 16, 2023
1 parent 6ef57ee commit 2e7b0ad
Show file tree
Hide file tree
Showing 25 changed files with 668 additions and 349 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"i18next": "^19.8.4",
"i18next-browser-languagedetector": "^7.0.1",
"i18next-http-backend": "^2.1.1",
"iconoir-react": "^6.11.0",
"jsonschema": "^1.3.0",
"lodash.find": "^4.6.0",
"lodash.findindex": "^4.6.0",
Expand Down
11 changes: 5 additions & 6 deletions src/components/Article/ArticleCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,9 +232,8 @@ const ArticleCell = ({
return <div>unknown type: {type}</div>
}

export default React.memo(ArticleCell, (prevProps, nextProps) => {
if (prevProps.memoid === nextProps.memoid || prevProps.active === nextProps.active) {
return true // props are equal
}
return false // props are not equal -> update the component
})
export default React.memo(
ArticleCell,
(prevProps, nextProps) =>
prevProps.memoid === nextProps.memoid || prevProps.active === nextProps.active,
)
17 changes: 11 additions & 6 deletions src/components/Article/ArticleCellFigure.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo } from 'react'
import ArticleCellOutputs from './ArticleCellOutputs'
import ArticleFigure from './ArticleFigure'
import ArticleFigureCaption from './ArticleFigureCaption'
import { markdownParser } from '../../logic/ipynb'
import { BootstrapColumLayout } from '../../constants'
import { Container, Row, Col } from 'react-bootstrap'
Expand Down Expand Up @@ -61,13 +61,18 @@ const ArticleCellFigure = ({
}
const mimetypes = Object.keys(output.data ?? [])
const mimetype = mimetypes.find((d) => d.indexOf('image/') === 0)
const outputProps = output ? Object.keys(output) : []
const isOutputEmpty =
outputProps.length === 0 ||
(outputProps.length === 1 && outputProps.shift() === 'metadata')

if (mimetype) {
acc.pictures.push({
// ...output,
src: output.metadata?.jdh?.object?.src,
base64: `data:${mimetype};base64,${output.data[mimetype]}`,
})
} else {
} else if (!isOutputEmpty) {
acc.otherOutputs.push(output)
}
return acc
Expand Down Expand Up @@ -101,7 +106,7 @@ const ArticleCellFigure = ({
)

return (
<div className={`ArticleCellFigure ${active ? 'active' : ''}`}>
<div className={`ArticleCellFigure ${active ? 'active' : ''} ${figure.getPrefix()}`}>
<Container className={containerClassName} fluid={isFluidContainer}>
<Row>
<Col {...columnLayout}>
Expand Down Expand Up @@ -164,15 +169,15 @@ const ArticleCellFigure = ({
<Row className="small">
<Col {...BootstrapColumLayout}>
{sourceCode}
<ArticleFigure figure={figure}>
<p
<ArticleFigureCaption figure={figure}>
<div
dangerouslySetInnerHTML={{
__html: captions
.join('<br />')
.replace(/(Fig.|figure|table)\s+[\da-z-]+\s*:\s+/i, ''),
}}
/>
</ArticleFigure>
</ArticleFigureCaption>
</Col>
</Row>
</Container>
Expand Down
78 changes: 38 additions & 40 deletions src/components/Article/ArticleCellObject.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React, { useMemo, lazy } from 'react'
import { markdownParser } from '../../logic/ipynb'
import ArticleFigure from './ArticleFigure'
import ArticleFigureCaption from './ArticleFigureCaption'

const VegaWrapper = lazy(() => import('../Module/VegaWrapper'))
const ImageWrapper = lazy(() => import('../Module/ImageWrapper'))


const ArticleCellObject = ({ metadata, figure, children, progress }) => {
const objectMetadata = useMemo(() => metadata.jdh?.object ?? {}, [metadata.jdh])
const objectOutputs = useMemo(() => metadata.jdh?.outputs ?? [], [metadata.jdh])
Expand All @@ -30,16 +29,21 @@ const ArticleCellObject = ({ metadata, figure, children, progress }) => {
alignItems: 'center',
}
// flex alignment
if ([ 'start', 'flex-start', 'end', 'flex-end', 'center', 'space-between', 'space-around'].includes(objectMetadata.justifyContent)) {
if (
['start', 'flex-start', 'end', 'flex-end', 'center', 'space-between', 'space-around'].includes(
objectMetadata.justifyContent,
)
) {
objectWrapperStyle = {
...objectWrapperStyle,
justifyContent: objectMetadata.justifyContent,
}
}
if ([
'start', 'flex-start', 'end', 'flex-end', 'center',
'baseline', 'first baseline'
].includes(objectMetadata.alignItems)) {
if (
['start', 'flex-start', 'end', 'flex-end', 'center', 'baseline', 'first baseline'].includes(
objectMetadata.alignItems,
)
) {
objectWrapperStyle = {
...objectWrapperStyle,
alignItems: objectMetadata.alignItems,
Expand All @@ -49,7 +53,7 @@ const ArticleCellObject = ({ metadata, figure, children, progress }) => {
if (!isNaN(objectMetadata.heightRatio)) {
objectWrapperStyle = {
...objectWrapperStyle,
height: window.innerHeight * objectMetadata.heightRatio
height: window.innerHeight * objectMetadata.heightRatio,
}
}

Expand All @@ -59,44 +63,38 @@ const ArticleCellObject = ({ metadata, figure, children, progress }) => {
position: 'sticky',
top: objectMetadata.top ?? 'var(--spacer-3)',
}
if(isNaN(objectMetadata.heightRatio)) {
if (isNaN(objectMetadata.heightRatio)) {
objectWrapperStyle.height = 'auto'
}
}

return (<>
<div style={objectWrapperStyle} className={objectClassName.join(' ')}>
{objectMetadata.type === 'image' && objectOutputs.map((output, i) => (
<ImageWrapper key={i}
metadata={objectMetadata}
output={output} figure={figure}/>
))}
{['video', 'map'].includes(objectMetadata.type) && (
<>
{progress}
<div dangerouslySetInnerHTML={{__html: objectContents}}></div>
</>
)}
{['vega'].includes(objectMetadata.type)
? (
<VegaWrapper
metadata={objectMetadata}
progress={progress}
>
<ArticleFigure figure={figure}>
<div dangerouslySetInnerHTML={{__html: objectContents}}></div>
</ArticleFigure>
</VegaWrapper>)
: null
}
{['text'].includes(objectMetadata.type) && (
<div dangerouslySetInnerHTML={{__html: objectContents}}></div>
)}
</div>
<div>{children}</div>
return (
<>
<div style={objectWrapperStyle} className={objectClassName.join(' ')}>
{objectMetadata.type === 'image' &&
objectOutputs.map((output, i) => (
<ImageWrapper key={i} metadata={objectMetadata} output={output} figure={figure} />
))}
{['video', 'map'].includes(objectMetadata.type) && (
<>
{progress}
<div dangerouslySetInnerHTML={{ __html: objectContents }}></div>
</>
)}
{['vega'].includes(objectMetadata.type) ? (
<VegaWrapper metadata={objectMetadata} progress={progress}>
<ArticleFigureCaption figure={figure}>
<div dangerouslySetInnerHTML={{ __html: objectContents }}></div>
</ArticleFigureCaption>
</VegaWrapper>
) : null}
{['text'].includes(objectMetadata.type) && (
<div dangerouslySetInnerHTML={{ __html: objectContents }}></div>
)}
</div>
<div>{children}</div>
</>
)
}


export default ArticleCellObject
28 changes: 0 additions & 28 deletions src/components/Article/ArticleFigure.js

This file was deleted.

27 changes: 27 additions & 0 deletions src/components/Article/ArticleFigureCaption.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { DisplayLayerCellIdxQueryParam } from '../../constants'
import { useQueryParam, NumberParam } from 'use-query-params'
import './ArticleFigureCaption.scss'

const ArticleFigureCaption = ({ figure, className = '', children }) => {
const { t } = useTranslation()
const [, set] = useQueryParam(DisplayLayerCellIdxQueryParam, NumberParam)
// figure number, for translation label.
return (
<figcaption className={`ArticleFigure position-relative ${className}`}>
<div className="ArticleFigure__figcaption_num">
{figure.ref ? (
<button onClick={() => set(figure.idx)} className="btn btn-link mr-2">
{t(figure.tNLabel, { n: figure.tNum })}
</button>
) : (
<div className="mr-2">{t(figure.tNLabel, { n: figure.tNum })}</div>
)}
</div>
{children}
</figcaption>
)
}

export default ArticleFigureCaption
29 changes: 29 additions & 0 deletions src/components/Article/ArticleFigureCaption.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.ArticleFigure {
min-height: 50px;
margin-top: var(--spacer-3);
}

.ArticleFigure__figcaption_num {
position: absolute;
left: -140px;
width: 140px;
text-align: right;
padding-right: var(--spacer-3);
font-family: var(--font-family-monospace);
font-weight: bold;
}

.ArticleFigure button.btn-link {
color: #000;
border-radius: 0;
font-size: inherit;
padding: 0;
line-height: 1.05em;
text-decoration: none;
box-shadow: 0 1px 0 var(--secondary);
font-weight: bold;
&:hover {
text-decoration: none;
color: #000;
}
}
65 changes: 41 additions & 24 deletions src/components/Article/ArticleScrollamaSticky.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react'
import { Container, Row, Col } from 'react-bootstrap'
import ArticleFigure from './ArticleFigure'
import ArticleFigureCaption from './ArticleFigureCaption'
import ArticleCellOutput from './ArticleCellOutput'
import {
BootstrapNarrativeStepFigureColumnLayout,
BootstrapNarrativeStepCaptionColumnLayout
BootstrapNarrativeStepCaptionColumnLayout,
} from '../../constants'
import { markdownParser } from '../../logic/ipynb'
import { useCurrentWindowDimensions, useBoundingClientRect } from '../../hooks/graphics'
Expand All @@ -18,8 +18,8 @@ import { useCurrentWindowDimensions, useBoundingClientRect } from '../../hooks/g
const ArticleScrollamaSticky = ({
cell,
currentStep,
marginTop=100,
marginBottom=50,
marginTop = 100,
marginBottom = 50,
// marginRight=100,
// marginLeft=50
}) => {
Expand All @@ -36,34 +36,51 @@ const ArticleScrollamaSticky = ({
}, [])
console.info('ArticleScrollamaSticky currentStep:', currentStep)
return (
<div className="ArticleScrollamaSticky" style={{
position: 'sticky',
top: 100,
height: height - marginTop - marginBottom
}}>
<a className='anchor' id={`C-${cell.idx}`} />
<div
className="ArticleScrollamaSticky"
style={{
position: 'sticky',
top: 100,
height: height - marginTop - marginBottom,
}}
>
<a className="anchor" id={`C-${cell.idx}`} />
<a className="anchor" id={cell.figure.ref} />
<Container className=" d-flex flex-column" style={{
height: height - marginTop - marginBottom
}}>
<Container
className=" d-flex flex-column"
style={{
height: height - marginTop - marginBottom,
}}
>
<Row className="flex-grow-1">
<Col className="h-100 position-relative" ref={ref} {...BootstrapNarrativeStepFigureColumnLayout}>
<div className="position-absolute h-100 w-100" style={{overflow: 'hidden'}}>
{!cell.outputs.length ? (
<div className="ArticleCellFigure_no_output">
</div>
): null}
{cell.outputs.map((output,i) => (
<ArticleCellOutput hideLabel height={bbox.height} width={bbox.width} output={output} key={i} />
<Col
className="h-100 position-relative"
ref={ref}
{...BootstrapNarrativeStepFigureColumnLayout}
>
<div className="position-absolute h-100 w-100" style={{ overflow: 'hidden' }}>
{!cell.outputs.length ? <div className="ArticleCellFigure_no_output"></div> : null}
{cell.outputs.map((output, i) => (
<ArticleCellOutput
hideLabel
height={bbox.height}
width={bbox.width}
output={output}
key={i}
/>
))}
</div>
</Col>
</Row>
<Row className="flex-shrink-1">
<Col {...BootstrapNarrativeStepCaptionColumnLayout}>
<ArticleFigure figure={cell.figure}><p dangerouslySetInnerHTML={{
__html: captions.join('<br />'),
}} /></ArticleFigure>
<ArticleFigureCaption figure={cell.figure}>
<p
dangerouslySetInnerHTML={{
__html: captions.join('<br />'),
}}
/>
</ArticleFigureCaption>
</Col>
</Row>
</Container>
Expand Down
Loading

0 comments on commit 2e7b0ad

Please sign in to comment.