it('memo wrapping forwardRef component', () => { const Memo = React.memo(React.forwardRef(() => <div>this is component 1</div>)); ReactHotLoader.register(Memo, 'memo', 'memo-test'); const wrapper = TestRenderer.create( <AppContainer> <Memo /> </AppContainer>, ); { const Memo = React.memo(React.forwardRef(() => <div>this is component 2</div>)); ReactHotLoader.register(Memo, 'memo', 'memo-test'); wrapper.update( <AppContainer update> <Memo /> </AppContainer>, ); expect(wrapper.toJSON()).toEqual(snapShot); } });
export default function createSvgIcon(path, displayName) { const Component = React.memo( React.forwardRef((props, ref) => ( <SvgIcon {...props} data-mui-test={`${displayName}Icon`} ref={ref}> {path} </SvgIcon> )), ); if (process.env.NODE_ENV !== 'production') { Component.displayName = `${displayName}Icon`; } Component.muiName = SvgIcon.muiName; return Component; }
// Utils, HOC function withNavigation(defaultSubtitle, className, icon) { return memo(function Navigation({ title, children, subtitle = defaultSubtitle, ...link }) { let linkTitle = title if (!linkTitle && typeof children === 'string') { linkTitle = children } return ( <Link {...link} title={linkTitle} className={className}> <div className={styles.TextSection}> <div className={styles.Subtitle}>{subtitle}</div> <div className={styles.Title}>{children}</div> </div> <Button className={styles.Icon}>{icon}</Button> </Link> ) }) }
import React from 'react'; import PropTypes from 'prop-types'; import { Headline, Caption } from './../texts'; const CardValue = React.memo(({ title, text, customClass = '' }) => ( <div className={customClass}> <Caption text={title} /> <Headline text={text} /> </div> )); CardValue.propTypes = { title: PropTypes.string.isRequired, text: PropTypes.string.isRequired, customClass: PropTypes.string, }; export default CardValue;
const RectAnnotationOutline = memo( ({ x, y, width, height, animate, motionStiffness, motionDamping }) => { const theme = useTheme() if (!animate) { return ( <> {theme.annotations.outline.outlineWidth > 0 && ( <rect x={x - width / 2} y={y - height / 2} width={width} height={height} style={{ ...theme.annotations.outline, fill: 'none', strokeWidth: theme.annotations.outline.strokeWidth + theme.annotations.outline.outlineWidth * 2, stroke: theme.annotations.outline.outlineColor, }} /> )} <rect x={x - width / 2} y={y - height / 2} width={width} height={height} style={theme.annotations.outline} /> </> ) } const springConfig = { stiffness: motionStiffness, damping: motionDamping, } return ( <Motion style={{ x: spring(x - width / 2, springConfig), y: spring(y - height / 2, springConfig), width: spring(width, springConfig), height: spring(height, springConfig), }} > {interpolated => ( <> {theme.annotations.outline.outlineWidth > 0 && ( <rect x={interpolated.x} y={interpolated.y} width={interpolated.width} height={interpolated.height} style={{ ...theme.annotations.outline, fill: 'none', strokeWidth: theme.annotations.outline.strokeWidth + theme.annotations.outline.outlineWidth * 2, stroke: theme.annotations.outline.outlineColor, }} /> )} <rect x={interpolated.x} y={interpolated.y} width={interpolated.width} height={interpolated.height} style={theme.annotations.outline} /> </> )} </Motion> ) } )
export default memo(({ years }) => ( <Fragment> <h3>Storyline</h3> <ol className="flipper"> {years.map(({ year, events, image }) => ( <li key={year} className="year flip-container"> <span className="front"> <span className="when">{year}</span> </span> <ul className="what back"> {!!events && events.map(event => <li key={event}>{event}</li>)} {!events && ( <li> <img alt="placeholder" src={image} /> </li> )} </ul> </li> ))} <li className="year year--filler" /> <li className="year year--filler" /> <li className="year year--filler" /> <li className="year year--filler" /> <li className="year year--filler" /> <li className="year year--filler" /> <li className="year year--filler" /> <li className="year year--filler" /> </ol> </Fragment> ));
import React from 'react'; import PropTypes from 'prop-types'; import { Text } from './texts'; const Snackbar = React.memo(({ text, show }) => ( <div className={`snackbar ${show ? 'show-snackbar' : 'hide-snackbar'}`}> <div> <Text text={text} /> </div> </div> )); Snackbar.propTypes = { text: PropTypes.string.isRequired, show: PropTypes.bool.isRequired, }; export default Snackbar;
grade: GradeFormatHelper.formatGrade(originalGrade, { gradingType, pointsPossible, formatType: 'points_out_of_fraction' }) })} {I18n.t( {one: 'Late Penalty: minus 1 Point', other: 'Late Penalty: minus %{count} Points'}, {count: pointsDeducted} )} {I18n.t('Grade: %{grade}', { grade: GradeFormatHelper.formatGrade(grade, { gradingType, pointsPossible, formatType: 'points_out_of_fraction' }) })} </ScreenReaderContent> ) } AccessibleTipContent.propTypes = { grade: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, gradingType: PropTypes.string.isRequired, originalGrade: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, pointsDeducted: PropTypes.number.isRequired, pointsPossible: PropTypes.number.isRequired } export default React.memo(AccessibleTipContent)
const CalendarDay = memo( ({ x, y, size, spacing, color, borderWidth, borderColor, onClick, showTooltip, hideTooltip, }) => { return ( <> <rect x={x} y={y} width={size} height={size} style={{ fill: color, strokeWidth: borderWidth, stroke: borderColor, }} /> <rect fill="rgba(0, 0, 0, 0)" x={x - spacing / 2} y={y - spacing / 2} width={size + spacing} height={size + spacing} onClick={onClick} onMouseEnter={showTooltip} onMouseMove={showTooltip} onMouseLeave={hideTooltip} /> </> ) } )
import React from 'react' import { useBdux } from 'bdux' export const Container = (props) => { useBdux(props) return <div {...props} /> } export default React.memo(Container)
x='8' y='105' width='384' height='190' rx='95' /> <circle id='Oval' className={ theme === 'dark' ? 'color-background-fill' : 'color-contrast-fill' } cx='113.5' cy='200.5' r='58.5' /> <circle id='Oval-Copy' className={ theme === 'light' ? 'color-background-fill' : 'color-contrast-fill' } cx='286.5' cy='200.5' r='58.5' /> </g> </Container> ) } export default React.memo(ToggleIconSVG)
import React, { memo } from 'react' import PropTypes from 'prop-types' import Base from 'components/pagination' Pagination.propTypes = { page: PropTypes.number.isRequired, pageSize: PropTypes.number, count: PropTypes.number.isRequired, onChange: PropTypes.func.isRequired, } function Pagination({ page, count, pageSize = 25, onChange }) { const total = Math.ceil(count / pageSize) return <Base total={total} active={page} onChange={onChange} /> } export default memo(Pagination)
preview = previewComplex((value: any), theme); } return ( <div className={styles.listItem}> <div className={styles.nameValueRow} onClick={toggleOpen}> {isCustomHook && <div className={styles.arrowContainer}> {isOpen && <span className={styles.expandedArrow}></span>} {!isOpen && <span className={styles.collapsedArrow}></span>} </div>} <div className={isCustomHook ? styles.nameCustom : styles.name}> {name}: </div> {<div className={styles.value}>{preview}</div>} </div> {isOpen && hasBeenHydrated && <HooksTreeView hooksTree={subHooks} inspect={inspect} path={path} theme={theme} />} </div> ); } // $FlowFixMe export default React.memo(HooksTreeView);
import React from "react"; const ComponentA = (props) => <div />; export default React.memo(ComponentA);
import React from 'react' import Link from './Link' import styles from './Navbar.css' function Donate(props) { return ( <Link {...props} className={styles.Donate}> Donate </Link> ) } export default React.memo(Donate)
export default memo(() => { const [visible, setVisible] = useState(false); const refContainer = useRef(null); const refAudio = useRef(null); if (typeof document !== "undefined") { useEffect(() => { document.body.style.overflow = visible ? "hidden" : "auto"; }, [visible]); } return ( <footer> <Konami konami={[67, 69, 68, 77, 65, 88]} easterEgg={() => { setVisible(true); if (typeof document !== "undefined") { autoScroll(refContainer.current, () => { fadeAudio(refAudio.current, () => { setVisible(false); }); }); } }} /> {visible && ( // eslint-disable-next-line jsx-a11y/media-has-caption <audio autoPlay ref={refAudio}> <source src={require("../media/Rolemusic_Besos_y_Abrazos.mp3")} /> </audio> )} <div className={`credits${visible ? " credits--visible" : ""}`}> <div ref={refContainer} className="credits-content"> <div className="credits__title full-screen"> <div> <h1>Credits</h1> </div> </div> <section className="credits__block"> <h3>Pictures</h3> <div> George Agnelli <br /> Federico Ros <br /> Irene Ros <br /> Paris Web conference <br /> Front Trends conference <br /> Front the Front meetup <br /> </div> </section> <section className="credits__block"> <h3>Built with</h3> <div> <a target="_blank" rel="noopener noreferrer" href="https://netlify.com" > Netlify </a> <br /> <a target="_blank" rel="noopener noreferrer" href="https://www.sanity.io/" > Sanity.io </a> <br /> <a target="_blank" rel="noopener noreferrer" href="https://react-static.js.org" > React Static </a> <br /> <a target="_blank" rel="noopener noreferrer" href="https://github.com/TylerBarnes/close-pixelate" > Close Pixelate </a> </div> </section> <section className="credits__block"> <h3>Icons and Images</h3> <div> <a target="_blank" rel="noopener noreferrer" href="https://simpleicons.org/" > Simple Icons </a> <br /> <a target="_blank" rel="noopener noreferrer" href="https://giphy.com" > Animated Gifs </a> </div> </section> <section className="credits__block"> <h3>Fonts</h3> <div> <a target="_blank" rel="noopener noreferrer" href="http://www.dafont.com/super-mario-bros-3.font" > Super Mario Bros 3 </a> <br /> <a target="_blank" rel="noopener noreferrer" href="http://www.dafont.com/8-bit-madness.font" > 8 Bit Madness </a> </div> </section> <section className="credits__block"> <h3>Tune</h3> <div> <a target="_blank" rel="noopener noreferrer" href="https://freemusicarchive.org/music/Rolemusic/~/Besos_y_Abrazos" > Besos y Abrazos <br /> <small>by Rolemusic</small> </a> </div> </section> <section className="full-screen"> <div> <img src={require("../media/me.jpg")} alt="me" /> </div> </section> </div> </div> </footer> ); });
const SwarmPlot = memo( ({ width, height, margin: partialMargin, data, groups, groupBy, identity, label, value, valueFormat, valueScale, size, spacing, layout, gap, forceStrength, simulationIterations, layers, renderNode, colors, colorBy, borderWidth, borderColor, enableGridX, gridXValues, enableGridY, gridYValues, axisTop, axisRight, axisBottom, axisLeft, annotations, isInteractive, useMesh, debugMesh, onMouseEnter, onMouseMove, onMouseLeave, onClick, tooltip, animate, motionStiffness, motionDamping, }) => { const { margin, innerWidth, innerHeight, outerWidth, outerHeight } = useDimensions( width, height, partialMargin ) const theme = useTheme() const { nodes, xScale, yScale } = useSwarmPlot({ width: innerWidth, height: innerHeight, data, groups, groupBy, identity, label, value, valueFormat, valueScale, size, spacing, layout, gap, colors, colorBy, forceStrength, simulationIterations, }) const getBorderWidth = useBorderWidth(borderWidth) const getBorderColor = useInheritedColor(borderColor, theme) const layerById = { grid: ( <Grid key="grid" theme={theme} width={innerWidth} height={innerHeight} xScale={enableGridX ? xScale : null} xValues={gridXValues} yScale={enableGridY ? yScale : null} yValues={gridYValues} animate={animate} motionStiffness={motionStiffness} motionDamping={motionDamping} /> ), axes: ( <Axes key="axes" xScale={xScale} yScale={yScale} width={innerWidth} height={innerHeight} theme={theme} top={axisTop} right={axisRight} bottom={axisBottom} left={axisLeft} animate={animate} motionStiffness={motionStiffness} motionDamping={motionDamping} /> ), mesh: null, annotations: ( <SwarmPlotAnnotations key="annotations" nodes={nodes} annotations={annotations} innerWidth={innerWidth} innerHeight={innerHeight} animate={animate} motionStiffness={motionStiffness} motionDamping={motionDamping} /> ), } const enableNodeInteractivity = isInteractive && !useMesh const handlers = useNodeMouseHandlers({ isEnabled: isInteractive, onMouseEnter, onMouseMove, onMouseLeave, onClick, tooltip, }) if (animate) { layerById.nodes = ( <AnimatedSwarmPlotNodes key="nodes" nodes={nodes} renderNode={renderNode} getBorderWidth={getBorderWidth} getBorderColor={getBorderColor} motionStiffness={motionStiffness} motionDamping={motionDamping} isInteractive={enableNodeInteractivity} onMouseEnter={!useMesh ? handlers.onMouseEnter : undefined} onMouseMove={!useMesh ? handlers.onMouseMove : undefined} onMouseLeave={!useMesh ? handlers.onMouseLeave : undefined} onClick={!useMesh ? handlers.onClick : undefined} /> ) } else { layerById.nodes = ( <StaticSwarmPlotNodes key="nodes" nodes={nodes} renderNode={renderNode} getBorderWidth={getBorderWidth} getBorderColor={getBorderColor} isInteractive={enableNodeInteractivity} onMouseEnter={!useMesh ? handlers.onMouseEnter : undefined} onMouseMove={!useMesh ? handlers.onMouseMove : undefined} onMouseLeave={!useMesh ? handlers.onMouseLeave : undefined} onClick={!useMesh ? handlers.onClick : undefined} /> ) } if (isInteractive === true && useMesh === true) { layerById.mesh = ( <Mesh key="mesh" nodes={nodes} width={innerWidth} height={innerHeight} onMouseEnter={handlers.onMouseEnter} onMouseMove={handlers.onMouseMove} onMouseLeave={handlers.onMouseLeave} onClick={handlers.onClick} debug={debugMesh} /> ) } const layerContext = { nodes, xScale, yScale, innerWidth, innerHeight, outerWidth, outerHeight, margin, getBorderColor, getBorderWidth, animate, motionStiffness, motionDamping, } return ( <SvgWrapper width={outerWidth} height={outerHeight} margin={margin} theme={theme}> {layers.map((layer, i) => { if (layerById[layer] !== undefined) { return layerById[layer] } if (typeof layer === 'function') { return <Fragment key={i}>{layer(layerContext)}</Fragment> } return null })} </SvgWrapper> ) } )
const BasesLocales = React.memo(({datasets, stats}) => { const isValidRatio = Math.round((stats.isValid / stats.model['bal-aitf']) * 100) const mapData = { type: 'FeatureCollection', features: datasets.map(dataset => ({ type: 'Feature', properties: { id: dataset.id, nom: dataset.title, license: dataset.license, organization: dataset.organization ? dataset.organization.name : null }, geometry: dataset.contour })) } return ( <div> <Section background='white'> <div className='intro'> <p>La <b>création des voies et des adresses</b> en France est du ressort des <b>communes</b>, via le conseil municipal.<br />{} Cette compétence est <b>régulièrement déléguée à un EPCI</b>.</p> <p>Une <b>base Adresse locale</b> est donc l’expression de cette compétence, et regroupe toute les adresses d’une collectivité.<br />{} Elle est <b>publiée sous sa responsabilité</b>.</p> <p>Ces bases de données ont vocation à <b>alimenter les bases nationales</b>, et en particulier la Base Adresse Nationale.</p> </div> </Section> <Section background='white'> <h4>Qu’est-ce que le format BAL ?</h4> <div> <p>L’<a href='http://www.aitf.fr/'>Association des Ingénieurs Territoriaux de France</a> (AITF) a créé en avril 2015 un groupe de travail portant sur la Base Adresse Nationale.</p> <p>Les <a href='https://cms.geobretagne.fr/content/travaux-gt-ban-aitf'>travaux de ce groupe</a> ont abouti à la <a href='https://cms.geobretagne.fr/sites/default/files/documents/aitf-sig-topo-adresse-fichier-echange-simplifie-v_1.1_0.pdf'>spécification d’un format d’échange</a>, aujourd’hui en version 1.1.</p> <p>Le format <b>BAL 1.1</b> est aujourd’hui le format d’échange à privilégier pour les données Adresse produites localement.</p> </div> <div className='action'> <Link href='/bases-locales/validateur'> <ButtonLink>Valider vos données au format BAL <FaCheckSquareO /></ButtonLink> </Link> </div> </Section> <Section background='grey'> <h4>Créer ou modifier une Base Adresse Locale</h4> <div> <p>Cet outil permet de générer une nouvelle Base Adresse Locale à partir de la BAN, ou d’éditer une Base Adresse Locale existante.</p> <p>Il permet de gérer très simplement les <strong>voies</strong>, les <strong>numéros</strong> et les <strong>positions</strong> des adresses d’une commune ou d’une intercommunalité, mais aussi de gérer des <strong>toponymes</strong>.</p> <p>Les données résultantes peuvent ensuite être publiées sous <a href='https://www.etalab.gouv.fr/licence-version-2-0-de-la-licence-ouverte-suite-a-la-consultation-et-presentation-du-decret'>Licence Ouverte</a>.</p> </div> <div className='action'> <Link href='/bases-locales/editeur'> <ButtonLink>Créer ou modifier une Base Adresse Locale <FaFileTextO /></ButtonLink> </Link> </div> </Section> <Section title='Quelques bases locales déjà publiées' background='white'> {shuffle(datasets.filter(d => d.model === 'bal-aitf')).slice(0, 3).map(dataset => ( <BaseAdresseLocale key={dataset.id} dataset={dataset} /> ))} <div className='centered'> <Link href='/bases-locales/jeux-de-donnees'> <ButtonLink> Voir toutes les Bases Adresse Locales </ButtonLink> </Link> </div> </Section> <Section title='État du déploiement des Bases Adresse Locales'> <Mapbox> {(map, marker, popUp) => ( <BalMap map={map} popUp={popUp} data={mapData} /> )} </Mapbox> </Section> <Section title='Jeux de données publiés' background='white'> <div className='stats'> <div className='stat'> <Counter value={stats.count} title='Jeux de données publiés' /> </div> <div className='stat'> <Counter value={isValidRatio} unit='%' color={isValidRatio < 20 ? 'error' : isValidRatio < 50 ? 'warning' : 'success'} title='Conformité à la spécification BAL 1.1' /> </div> <div className='stat'> <Counter title='Communes représentées' value={stats.communesCount} /> </div> <div className='stat'> <Counter title='Adresses gérées par les collectivités' value={stats.numerosCount} /> </div> <div className='stat'> <Pie title='Licences utilisées' data={{ 'Licence Ouverte': stats.license.lov2, 'ODbL 1.0': stats.license['odc-odbl'] }} colors={[theme.colors.green, theme.colors.orange]} /> </div> </div> </Section> <style jsx>{` .intro { text-align: left; } .action { display: flex; margin-top: 3em; } .centered { margin: 40px auto; display: flex; justify-content: center; } .stats { display: flex; text-align: center; justify-content: space-around; align-items: center; flex-flow: wrap; margin: 2em 0; } .stat { margin: 1em 0.5em; width: 300px; } a { text-align: center; text-decoration: underline; } `}</style> </div> ) })
)} </h1> </Header> <Body> <Submission value={data}> <Shim horizontal> {loading && ( <Loading> Loading Mountain Information Network reports... </Loading> )} <Metadata /> </Shim> <Shim vertical> <TabSet /> </Shim> <Gallery /> </Submission> </Body> </Container> )} </Report> ) } export default memo( MountainInformationNetwork, (prev, next) => prev.id === next.id )
'Header--isActive': isActive, 'Header--Disabled': disabled, }) return ( <div role="tab" className={className} style={style} onClick={onActivate}> {children} </div> ) } export const Header = memo(BaseHeader) ColoredHeader.propTypes = { color: PropTypes.string, isActive: PropTypes.bool, disabled: PropTypes.bool, arrow: PropTypes.bool, onActivate: PropTypes.func, style: PropTypes.object, children: PropTypes.node.isRequired, } export function ColoredHeader({ color, ...props }) { const { disabled, isActive } = props const style = color && { backgroundColor: disabled ? null : isActive ? color : null,
const RadarGridLabels = memo( ({ radius, angles, indices, label: labelComponent, labelOffset, theme, animate, motionStiffness, motionDamping, }) => { const springConfig = { motionDamping, motionStiffness, } const labels = indices.map((index, i) => { const position = positionFromAngle(angles[i], radius + labelOffset) const textAnchor = textAnchorFromAngle(angles[i]) return { id: index, angle: radiansToDegrees(angles[i]), anchor: textAnchor, ...position, } }) if (animate !== true) { return <g>{labels.map(label => renderLabel(label, theme, labelComponent))}</g> } return ( <TransitionMotion styles={labels.map(label => ({ key: label.id, data: label, style: { x: spring(label.x, springConfig), y: spring(label.y, springConfig), }, }))} > {interpolatedStyles => ( <g> {interpolatedStyles.map(({ data }) => renderLabel(data, theme, labelComponent) )} </g> )} </TransitionMotion> ) } )
export const updateInstance = instance => { const { updater, forceUpdate } = instance; if (typeof forceUpdate === 'function') { instance.forceUpdate(); } else if (updater && typeof updater.enqueueForceUpdate === 'function') { updater.enqueueForceUpdate(instance); } }; export const isFragmentNode = ({ type }) => React.Fragment && type === React.Fragment; const ContextType = React.createContext ? React.createContext() : null; const ConsumerType = ContextType && ContextType.Consumer.$$typeof; const ProviderType = ContextType && ContextType.Provider.$$typeof; const MemoType = React.memo && React.memo(() => null).$$typeof; const LazyType = React.lazy && React.lazy(() => null).$$typeof; const ForwardType = React.forwardRef && React.forwardRef(() => null).$$typeof; export const CONTEXT_CURRENT_VALUE = '_currentValue'; export const isContextConsumer = ({ type }) => type && typeof type === 'object' && '$$typeof' in type && type.$$typeof === ConsumerType && ConsumerType; export const isContextProvider = ({ type }) => type && typeof type === 'object' && '$$typeof' in type && type.$$typeof === ProviderType && ProviderType; export const isMemoType = ({ type }) => type && typeof type === 'object' && '$$typeof' in type && type.$$typeof === MemoType && MemoType; export const isLazyType = ({ type }) => type && typeof type === 'object' && '$$typeof' in type && type.$$typeof === LazyType && LazyType; export const isForwardType = ({ type }) => type && typeof type === 'object' && '$$typeof' in type && type.$$typeof === ForwardType && ForwardType;
const RadarGridLevels = memo( ({ shape, radii, angleStep, dataLength, theme, animate, motionStiffness, motionDamping }) => { const springConfig = { damping: motionDamping, stiffness: motionStiffness, } const levelsTransitionProps = { willEnter: levelWillEnter, willLeave: () => ({ r: spring(0, springConfig) }), styles: radii.map((r, i) => ({ key: `level.${i}`, style: { r: spring(r, springConfig), }, })), } if (shape === 'circular') { if (animate !== true) { return ( <g> {radii.map((r, i) => ( <circle key={`level.${i}`} fill="none" r={r} {...theme.grid.line} /> ))} </g> ) } return ( <TransitionMotion {...levelsTransitionProps}> {interpolatedStyles => ( <g> {interpolatedStyles.map(({ key, style }) => ( <circle key={key} fill="none" r={Math.max(style.r, 0)} {...theme.grid.line} /> ))} </g> )} </TransitionMotion> ) } const radarLineGenerator = lineRadial() .angle(i => i * angleStep) .curve(curveLinearClosed) const points = range(dataLength) if (animate !== true) { return ( <g> {radii.map((radius, i) => ( <path key={`level.${i}`} fill="none" d={radarLineGenerator.radius(radius)(points)} {...theme.grid.line} /> ))} </g> ) } return ( <TransitionMotion {...levelsTransitionProps}> {interpolatedStyles => ( <g> {interpolatedStyles.map(({ key, style }) => ( <path key={key} fill="none" d={radarLineGenerator.radius(style.r)(points)} {...theme.grid.line} /> ))} </g> )} </TransitionMotion> ) } )
const SwarmPlotCanvas = memo( ({ pixelRatio, width, height, margin: partialMargin, data, groups, groupBy, identity, label, value, valueFormat, valueScale, size, spacing, layout, gap, forceStrength, simulationIterations, layers, renderNode, colors, colorBy, borderWidth, borderColor, enableGridX, gridXValues, enableGridY, gridYValues, axisTop, axisRight, axisBottom, axisLeft, annotations, isInteractive, onMouseEnter, onMouseMove, onMouseLeave, onClick, tooltip, debugMesh, }) => { const canvasEl = useRef(null) const [currentNode, setCurrentNode] = useState(null) const { margin, innerWidth, innerHeight, outerWidth, outerHeight } = useDimensions( width, height, partialMargin ) const theme = useTheme() const { nodes, xScale, yScale } = useSwarmPlot({ width: innerWidth, height: innerHeight, data, groups, groupBy, identity, label, value, valueFormat, valueScale, size, spacing, layout, gap, colors, colorBy, forceStrength, simulationIterations, }) const boundAnnotations = useSwarmPlotAnnotations(nodes, annotations) const computedAnnotations = useComputedAnnotations({ annotations: boundAnnotations, innerWidth, innerHeight, }) const getBorderWidth = useBorderWidth(borderWidth) const getBorderColor = useInheritedColor(borderColor, theme) const { delaunay, voronoi } = useVoronoiMesh({ points: nodes, width: innerWidth, height: innerHeight, debug: debugMesh, }) useEffect(() => { canvasEl.current.width = outerWidth * pixelRatio canvasEl.current.height = outerHeight * pixelRatio const ctx = canvasEl.current.getContext('2d') ctx.scale(pixelRatio, pixelRatio) ctx.fillStyle = theme.background ctx.fillRect(0, 0, outerWidth, outerHeight) ctx.translate(margin.left, margin.top) layers.forEach(layer => { if (layer === 'grid' && theme.grid.line.strokeWidth > 0) { ctx.lineWidth = theme.grid.line.strokeWidth ctx.strokeStyle = theme.grid.line.stroke enableGridX && renderGridLinesToCanvas(ctx, { width: innerWidth, height: innerHeight, scale: xScale, axis: 'x', values: gridXValues, }) enableGridY && renderGridLinesToCanvas(ctx, { width: innerWidth, height: innerHeight, scale: yScale, axis: 'y', values: gridYValues, }) } if (layer === 'axes') { renderAxesToCanvas(ctx, { xScale, yScale, width: innerWidth, height: innerHeight, top: axisTop, right: axisRight, bottom: axisBottom, left: axisLeft, theme, }) } if (layer === 'nodes') { nodes.forEach(node => { renderNode(ctx, { node, getBorderWidth, getBorderColor, }) }) } if (layer === 'mesh' && debugMesh === true) { renderVoronoiToCanvas(ctx, voronoi) if (currentNode) { renderVoronoiCellToCanvas(ctx, voronoi, currentNode.index) } } if (layer === 'annotations') { renderAnnotationsToCanvas(ctx, { annotations: computedAnnotations, theme, }) } if (typeof layer === 'function') { layer(ctx, { nodes, innerWidth, innerHeight, outerWidth, outerHeight, margin, xScale, yScale, }) } }) }, [ canvasEl, innerWidth, innerHeight, outerWidth, outerHeight, margin, pixelRatio, theme, layers, nodes, xScale, yScale, getBorderWidth, getBorderColor, voronoi, currentNode, computedAnnotations, ]) const [showTooltip, hideTooltip] = useTooltip() const showNodeTooltip = useMemo(() => { if (tooltip) return (node, event) => showTooltip(tooltip({ node }), event) return (node, event) => showTooltip(<SwarmPlotTooltip node={node} />, event) }, [showTooltip, tooltip]) const getNodeFromMouseEvent = useCallback( event => { const [x, y] = getRelativeCursor(canvasEl.current, event) if (!isCursorInRect(margin.left, margin.top, innerWidth, innerHeight, x, y)) return null const nodeIndex = delaunay.find(x - margin.left, y - margin.top) return nodes[nodeIndex] }, [canvasEl, margin, innerWidth, innerHeight, delaunay, setCurrentNode] ) const handleMouseHover = useCallback( event => { const node = getNodeFromMouseEvent(event) setCurrentNode(node) onMouseMove && onMouseMove(node, event) if (node) { showNodeTooltip(node, event) if ((!currentNode || currentNode.id !== node.id) && onMouseEnter) { onMouseEnter(node, event) } if (currentNode && currentNode.id !== node.id && onMouseLeave) { onMouseLeave(currentNode, event) } } else { currentNode && onMouseLeave && onMouseLeave(currentNode, event) hideTooltip() } }, [ getNodeFromMouseEvent, currentNode, onMouseEnter, onMouseLeave, showNodeTooltip, hideTooltip, ] ) const handleMouseLeave = useCallback( event => { hideTooltip() setCurrentNode(null) onMouseLeave && onMouseLeave(currentNode, event) }, [hideTooltip, setCurrentNode, currentNode, onMouseLeave] ) const handleClick = useCallback( event => { const node = getNodeFromMouseEvent(event) node && onClick && onClick(node, event) }, [getNodeFromMouseEvent, onClick] ) return ( <canvas ref={canvasEl} width={outerWidth * pixelRatio} height={outerHeight * pixelRatio} style={{ width: outerWidth, height: outerHeight, cursor: isInteractive ? 'auto' : 'normal', }} onMouseEnter={isInteractive ? handleMouseHover : undefined} onMouseMove={isInteractive ? handleMouseHover : undefined} onMouseLeave={isInteractive ? handleMouseLeave : undefined} onClick={isInteractive ? handleClick : undefined} /> ) } )
import React, { memo } from "react"; import { Head } from "react-static"; export default memo(({ meta }) => ( <Head> <title>{meta.meta_title}</title> <meta name="description" content={meta.meta_decription} /> <meta property="og:image" content={`https://cedmax.com${meta.image}`} /> <meta property="og:url" content="https://cedmax.com/" /> <meta property="og:title" content={meta.meta_title} /> <meta property="og:description" content={meta.meta_decription} /> <meta name="twitter:site" content="@cedmax" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" type="image/x-icon" /> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /> </Head> ));
const cleanups = [ /<title>.*<\/title>/gi, /<desc>.*<\/desc>/gi, /<!--.*-->/gi, / +width="\d+(\.\d+)?(px)?"/gi, / +height="\d+(\.\d+)?(px)?"/gi, / +fill=\\"(none|#[0-9a-f]+)\\"/gi, ]; function cleanupSvg(svg, customClass = '') { return cleanups .reduce((acc, clean) => acc.replace(clean, ''), svg) .replace(/<svg/, `<svg class="${customClass}" `) .trim(); } const Icon = React.memo(({ component, customClass = '' }) => ( <i dangerouslySetInnerHTML={{ __html: cleanupSvg(component, customClass), }} /> )); Icon.propTypes = { component: PropTypes.string.isRequired, customClass: PropTypes.string, }; export default Icon;
import { defineMessages, F, FHTML, injectIntl } from '../../shared/i18n'; import React from 'react'; import styles from './Error.module.css'; const messages = defineMessages({ upsideDownFace: { msg: 'upside down face' }, }); const NotFound = React.memo(function NotFound({ intl }) { const emojiAriaLabel = intl.formatMessage(messages.upsideDownFace); return ( <div className={styles.message}> <span className={styles.emojiSpin} role="img" aria-label={emojiAriaLabel}> 🙃 </span> <h1> 404: <F msg="not found" /> </h1> <div> <F msg="i'm sorry, dave. i'm afraid i can't do that." /> <br /> <FHTML msg="try going back to the <a href='/'>beginning</a>." /> </div> </div> ); }); export default injectIntl(NotFound);
thread: { marginBottom: 15 }, truncatedMessage: { color: '#fff', fontWeight: 'bold', borderTop: '1px solid #656565', borderBottom: '1px dotted #fff', backgroundColor: '#181818', cursor: 'pointer', marginTop: -3, '&:hover': { backgroundColor: '#282828' } }, replyCount: { color: '#00bff3' }, truncatedContainer: { height: 300, overflow: 'hidden', position: 'relative' }, truncatedComments: { position: 'absolute !important', bottom: 0 } }) export default React.memo(Thread)
<Entry term="Terrain trap">{terrainTrap}</Entry> </List> {groupDetails && ( <List title="Group details"> <Entry term="Total in the group?"> {groupDetails.groupSize} </Entry> <Entry term="People fully buried?"> {groupDetails.numberFullyBuried} </Entry> <Entry term="People partly buried with impaired breathing?"> {groupDetails.numberPartlyBuriedImpairedBreathing} </Entry> <Entry term="People partly buried with normal breathing?"> {groupDetails.numberPartlyBuriedAbleBreathing} </Entry> <Entry term="People injured (caught but not buried)?"> {groupDetails.numberCaughtOnly} </Entry> <Entry term="People not injured (caught but not buried)?"> {groupDetails.numberPeopleInjured} </Entry> </List> )} <Comment>{incidentDescription}</Comment> </Fragment> ) } export default memo(Incident)
import React, { memo } from 'react'; import PropTypes from 'prop-types'; const NavItem = memo(props => { const { navText } = props; if(navText === 'fa fa-envelope'){ return ( <li onClick={navItemClickHandler.bind(null, props)}> <span><i className={navText}></i></span> </li> ); } else { return ( <li onClick={navItemClickHandler.bind(null, props)}> <span>{navText}</span> </li> ); } }); function navItemClickHandler(props){ const {scrollToSection, target} = props; scrollToSection(target); } NavItem.propTypes = { navText: PropTypes.string, scrollToSection: PropTypes.func, target: PropTypes.string