UNPKG

@randy.tarampi/jsx

Version:

Some common JSX components for www.randytarampi.ca

347 lines (325 loc) 12.8 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } import { Post, POST_ENTITIES, POST_OVERRIDING_TAG_SENTINEL_REGEX } from "@randy.tarampi/js"; import SchemaJsonLdComponent from "@randy.tarampi/schema-dot-org-json-ld-components"; import isHtml from "is-html"; import { DateTime } from "luxon"; import PropTypes from "prop-types"; import React, { Fragment, PureComponent } from "react"; import { Marker } from "react-google-maps"; import { Col, Row } from "react-materialize"; import { connect } from "react-redux"; import { updateMapCreator } from "../actions"; import { CampaignLink, getBrandedLinkForNetwork, InternalLink } from "./link"; import { MapComponent } from "./map"; export class PostComponent extends PureComponent { get postElement() { return document.getElementById(this.props.post.uid); } get width() { var postElement = this.postElement; return postElement ? postElement.clientWidth : this.props.containerHeight; } get height() { var postElement = this.postElement; return postElement ? postElement.clientHeight : this.props.containerWidth; } get metadataWidth() { var postElement = this.postElement; var metadataColumnElement = postElement && postElement.querySelector(".post-metadata"); return metadataColumnElement ? metadataColumnElement.clientWidth : this.width; } get metadataHeight() { var postElement = this.postElement; var metadataColumnElement = postElement && postElement.querySelector(".post-metadata"); return metadataColumnElement ? metadataColumnElement.clientHeight : this.height; } get contentHeight() { var postElement = this.postElement; var contentColumnElement = postElement && postElement.querySelector(".post-content"); return contentColumnElement ? contentColumnElement.clientHeight : this.height; } get containerHeight() { return this.props.containerHeight; } get containerWidth() { return this.props.containerWidth; } get scaledHeight() { return Math.round(this.containerWidth * this.height / this.width); } get title() { return this.props.post.title || "Untitled"; } render() { var { post } = this.props; return /*#__PURE__*/React.createElement(Row, { className: "post post--words", id: post.uid }, /*#__PURE__*/React.createElement(SchemaJsonLdComponent, { markup: post.toSchema() }), /*#__PURE__*/React.createElement(Col, { className: "post-metadata", s: 12, l: 4 }, /*#__PURE__*/React.createElement(PostTitleComponent, { post: post, title: this.title }), /*#__PURE__*/React.createElement(PostDatePublishedComponent, { post: post }), /*#__PURE__*/React.createElement(PostDateCreatedComponent, { post: post }), /*#__PURE__*/React.createElement(PostLocationComponent, { post: post }), /*#__PURE__*/React.createElement(PostTagsComponent, { post: post })), /*#__PURE__*/React.createElement(Col, { className: "post-content", s: 12, l: 8 }, /*#__PURE__*/React.createElement(PostBodyAsStringComponent, { post: post }), /*#__PURE__*/React.createElement(PostBodyAsArrayComponent, { post: post }))); } } PostComponent.propTypes = { post: PropTypes.instanceOf(Post).isRequired, containerWidth: PropTypes.number, containerHeight: PropTypes.number }; export var PostTitleComponent = (_ref) => { var { post, title } = _ref; return /*#__PURE__*/React.createElement("h1", { className: "post-title" }, post.sourceUrl ? /*#__PURE__*/React.createElement(CampaignLink, { className: "post-title__link", href: post.sourceUrl, text: title }) : /*#__PURE__*/React.createElement("span", { className: "post-title__text" }, title)); }; PostTitleComponent.propTypes = { post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired, title: PropTypes.string.isRequired }; export var PostBodyAsStringComponent = (_ref2) => { var { post } = _ref2; return typeof post.body === "string" && post.body !== "" ? /*#__PURE__*/React.createElement("div", { className: "post-body" }, isHtml(post.body) ? /*#__PURE__*/React.createElement("div", { className: "post-body__html" }, /*#__PURE__*/React.createElement("div", { dangerouslySetInnerHTML: { __html: post.body } })) : /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("span", { className: "post-body__text", dangerouslySetInnerHTML: { __html: post.body } }))) : null; }; PostBodyAsStringComponent.propTypes = { post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired }; export var PostBodyAsArrayComponent = (_ref3) => { var { post } = _ref3; return Array.isArray(post.body) ? /*#__PURE__*/React.createElement(Fragment, null, post.body.map((htmlString, index) => { return /*#__PURE__*/React.createElement("div", { className: "post-body", key: "".concat(post.id, ":").concat(post.type, ":body:").concat(index) }, isHtml(htmlString) ? /*#__PURE__*/React.createElement("div", { className: "post-body__html" }, /*#__PURE__*/React.createElement("div", { dangerouslySetInnerHTML: { __html: htmlString } })) : /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("span", { className: "post-body__text", dangerouslySetInnerHTML: { __html: htmlString } }))); })) : null; }; PostBodyAsArrayComponent.propTypes = { post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired }; export var PostDatePublishedComponent = (_ref4) => { var { post, label } = _ref4; var postSourceLink = null; if (post.creator) { var PostSourceLinkComponent = getBrandedLinkForNetwork(post.source); var sourceName = post.creator.username || post.creator.name; var sourceAttribution = "".concat(sourceName, " on ").concat(post.source); if (PostSourceLinkComponent) { postSourceLink = /*#__PURE__*/React.createElement(PostSourceLinkComponent, { className: "post-source__link", href: post.creator.url, username: post.creator.username, text: sourceAttribution }, sourceName, " on ", /*#__PURE__*/React.createElement("span", { className: "post-source__source-name" }, post.source)); } else { postSourceLink = /*#__PURE__*/React.createElement(CampaignLink, { className: "post-source__link", href: post.creator.url, text: sourceAttribution }); } } return post.datePublished ? /*#__PURE__*/React.createElement("p", { className: "post-date" }, /*#__PURE__*/React.createElement("strong", { className: "post-date__label post-date__label--published" }, label), /*#__PURE__*/React.createElement("span", { className: "post-date__date post-date__date--published" }, post.datePublished.toLocaleString(DateTime.DATE_MED)), postSourceLink) : null; }; PostDatePublishedComponent.propTypes = { label: PropTypes.string.isRequired, post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired }; PostDatePublishedComponent.defaultProps = { label: "Posted:" }; export var PostDateCreatedComponent = (_ref5) => { var { post, label } = _ref5; return post.dateCreated && post.dateCreated.valueOf() !== post.datePublished.valueOf() ? /*#__PURE__*/React.createElement("p", { className: "post-date" }, /*#__PURE__*/React.createElement("strong", { className: "post-date__label post-date__label--created" }, label), /*#__PURE__*/React.createElement("span", { className: "post-date__date post-date__date--created" }, post.dateCreated.toLocaleString(DateTime.DATETIME_MED))) : null; }; PostDateCreatedComponent.propTypes = { post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired, label: PropTypes.string.isRequired }; PostDateCreatedComponent.defaultProps = { label: "Drafted:" }; export var PostTagsComponent = (_ref6) => { var { post, tagLinkBase = "/blog".concat("/tags") } = _ref6; return post.tags && post.tags.size ? /*#__PURE__*/React.createElement("p", { className: "post-tags hide-on-med-and-down" }, /*#__PURE__*/React.createElement("strong", { className: "post-tags__label" }, "Tags:"), post.tags.filter(tag => !tag.match(POST_OVERRIDING_TAG_SENTINEL_REGEX)).map(tag => /*#__PURE__*/React.createElement(Fragment, { key: tag }, /*#__PURE__*/React.createElement(InternalLink, { className: "post-tags__tag", href: "".concat(tagLinkBase, "/").concat(tag) }, tag), " ") // NOTE-RT: We need this ` ` between the `</InternalLink>` and the `</Fragment>` because Safari (Webkit?) seems to collapse `&#0032;` and not insert line breaks between each `<Fragment>` but doesn't with ` ` )) : null; }; PostTagsComponent.propTypes = { tagLinkBase: PropTypes.string, post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired }; export var PostMapComponent = (_ref7) => { var { post, mapContainerHeight, children } = _ref7, props = _objectWithoutProperties(_ref7, ["post", "mapContainerHeight", "children"]); return Number.isFinite(post.lat) && Number.isFinite(post.long) ? /*#__PURE__*/React.createElement("div", { className: "post-map" }, /*#__PURE__*/React.createElement(MapComponent, _extends({ mapContainerHeight: mapContainerHeight, defaultZoom: 17, defaultCenter: { lat: post.lat, lng: post.long } }, props), children ? children : /*#__PURE__*/React.createElement(Marker, { position: { lat: post.lat, lng: post.long } }))) : null; }; PostMapComponent.propTypes = { post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired, mapContainerHeight: PropTypes.number, contentHeight: PropTypes.number, metadataHeight: PropTypes.number }; var PostLocationComponentInternal = (_ref8) => { var { post, setMapPostsCenter } = _ref8; if (post.locationCreated) { var postCoordinates = post.locationCreated.coordinates ? [post.locationCreated.coordinates.latitude, post.locationCreated.coordinates.longitude].map(dmsCoordinate => { var dmsArray = dmsCoordinate.dmsArray; return "".concat(dmsArray[0], "\xB0").concat(dmsArray[1], "\u2032").concat(Number(dmsArray[2]).toFixed(3), "\u2033 ").concat(dmsArray[3]); }).join(", ") : null; var postLocationName = post.locationCreated.name; var postAddress = post.locationCreated.address; return /*#__PURE__*/React.createElement("p", { className: "post-location hide-on-med-and-down" }, /*#__PURE__*/React.createElement(InternalLink, { className: "link--branded post-location__link", href: "/map", onClick: setMapPostsCenter, serviceName: postLocationName || postAddress || postCoordinates, serviceType: "map-post" })); } return null; }; PostLocationComponentInternal.propTypes = { post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired, setMapPostsCenter: PropTypes.func.isRequired }; export var PostLocationComponent = connect(null, (dispatch, _ref9) => { var { post, mapId } = _ref9; return { setMapPostsCenter: () => dispatch(updateMapCreator({ id: mapId, center: { lat: post.lat, lng: post.long }, bounds: null, zoom: 18 })) }; })(PostLocationComponentInternal); PostLocationComponent.propTypes = { post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired, mapId: PropTypes.string.isRequired }; PostLocationComponent.defaultProps = { mapId: "map-posts" }; export default PostComponent;