UNPKG

@matt-dunn/react-wireframes

Version:

React component to annotate your components — useful for prototypes and proof of concepts

403 lines (306 loc) 17.1 kB
"use strict"; function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } require("core-js/modules/es.symbol"); require("core-js/modules/es.symbol.description"); require("core-js/modules/es.symbol.iterator"); require("core-js/modules/es.array.from"); require("core-js/modules/es.array.iterator"); require("core-js/modules/es.array.slice"); require("core-js/modules/es.function.name"); require("core-js/modules/es.object.freeze"); require("core-js/modules/es.object.to-string"); require("core-js/modules/es.regexp.to-string"); require("core-js/modules/es.string.iterator"); require("core-js/modules/es.string.fixed"); require("core-js/modules/web.dom-collections.iterator"); require("core-js/modules/web.timers"); Object.defineProperty(exports, "__esModule", { value: true }); exports.WireframeContainer = exports.ActiveWireframeAnnotationContext = exports.WireframeAnnotationsClose = exports.WireframeAnnotationsToggle = void 0; var _react = _interopRequireWildcard(require("react")); var _css = _interopRequireDefault(require("@emotion/css")); var _styled = _interopRequireDefault(require("@emotion/styled")); var _useScrollElementIntoView = require("../useScrollElementIntoView"); var _api = require("../api"); var _WireframeAnnotationNotes = require("../WireframeAnnotationNotes"); var _utils = require("../utils"); var _WireframeProvider = require("../WireframeProvider"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _templateObject12() { var data = _taggedTemplateLiteral(["\n overflow: hidden;\n z-index: 1;\n position: relative;\n background-color: inherit;\n display: flex;\n flex-grow: 1;\n \n > * {\n overflow-x: hidden;\n overflow-y: auto;\n }\n"]); _templateObject12 = function _templateObject12() { return data; }; return data; } function _templateObject11() { var data = _taggedTemplateLiteral(["\n flex-grow: 0;\n align-self: flex-start;\n cursor: pointer;\n line-height: 1;\n font-size: 1.5em;\n font-family: -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";\n background-color: transparent;\n border: none;\n padding: 0;\n margin: 0 0 0 0.25em;\n color: inherit;\n"]); _templateObject11 = function _templateObject11() { return data; }; return data; } function _templateObject10() { var data = _taggedTemplateLiteral(["transform: rotate(180deg);"]); _templateObject10 = function _templateObject10() { return data; }; return data; } function _templateObject9() { var data = _taggedTemplateLiteral(["translate(-100%, -50%)"]); _templateObject9 = function _templateObject9() { return data; }; return data; } function _templateObject8() { var data = _taggedTemplateLiteral(["translate(0, -50%)"]); _templateObject8 = function _templateObject8() { return data; }; return data; } function _templateObject7() { var data = _taggedTemplateLiteral(["\n margin: 0;\n padding: 0;\n position: absolute;\n left: 0;\n top: 50%;\n background-color: #555;\n color: #fff;\n border: none;\n border-radius: 0.5rem 0 0 0.5rem;\n transform: ", ";\n transition: opacity 100ms, transform 100ms;\n display: flex;\n flex-direction: row;\n align-items: center;\n opacity: ", ";\n font-size: 1rem;\n min-height: 3.5em;\n cursor: pointer;\n \n &:active,\n &:focus,\n &:hover {\n outline: none;\n opacity: 1;\n }\n\n span {\n all: initial;\n cursor: inherit;\n color: inherit;\n padding: 0.25em;\n font-size: 1.25em;\n font-family: -apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";\n font-weight: bold;\n transition: transform ", "ms;\n display: block;\n ", ";\n }\n"]); _templateObject7 = function _templateObject7() { return data; }; return data; } function _templateObject6() { var data = _taggedTemplateLiteral(["\n position: fixed;\n "]); _templateObject6 = function _templateObject6() { return data; }; return data; } function _templateObject5() { var data = _taggedTemplateLiteral(["\n flex-grow: 0;\n flex-shrink: 0;\n border-left: 2px solid #555;\n padding: 0;\n width: 25%;\n max-width: 400px;\n min-width: 250px;\n right: 0;\n top: 0;\n bottom: 0;\n background-color: #fafafa;\n display: flex;\n flex-direction: column;\n transition: transform ", ";\n z-index: 6000;\n position: absolute;\n\n ", "\n \n header.annotations {\n padding: 0.1em 0.75em;\n background-color: #555;\n color: #fff;\n display: flex;\n flex-shrink: 0;\n align-items: center;\n \n h1 {\n flex-grow: 1;\n font-size: 1.5em;\n margin: 0;\n line-height: 1.5;\n font-weight: lighter;\n }\n }\n"]); _templateObject5 = function _templateObject5() { return data; }; return data; } function _templateObject4() { var data = _taggedTemplateLiteral(["\n all: initial;\n font-family: inherit;\n line-height: 1.5;\n flex-grow: 0;\n flex-shrink: 0;\n max-width: 400px;\n padding: 0;\n transition: width ", ", min-width ", ";\n position: relative;\n \n &:hover {\n [data-annotations-toggle] {\n transform: translate(-100%, -50%);\n }\n }\n \n"]); _templateObject4 = function _templateObject4() { return data; }; return data; } function _templateObject3() { var data = _taggedTemplateLiteral(["\n flex-grow: 1;\n"]); _templateObject3 = function _templateObject3() { return data; }; return data; } function _templateObject2() { var data = _taggedTemplateLiteral(["\n overflow: hidden;\n "]); _templateObject2 = function _templateObject2() { return data; }; return data; } function _templateObject() { var data = _taggedTemplateLiteral(["\n display: flex;\n\n ", "\n\n > [data-annotations-container] {\n width: 0;\n min-width: 0;\n\n [data-annotations] {\n transform: translateX(100%);\n }\n }\n\n &.open {\n > [data-annotations-container] {\n width: 25%;\n min-width: 250px;\n\n > [data-annotations] {\n transform: translateX(0);\n }\n }\n }\n"]); _templateObject = function _templateObject() { return data; }; return data; } function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } var transitionDuration = 250; var transition = "".concat(transitionDuration, "ms ease-in-out"); var WireframeMainContainer = _styled.default.div(_templateObject(), function (_ref) { var fixed = _ref.fixed; return fixed === false && (0, _css.default)(_templateObject2()); }); var WireframeBody = _styled.default.main(_templateObject3()); var WireframeAnnotationsContainer = _styled.default.section(_templateObject4(), transition, transition); var WireframeAnnotationsWrapper = _styled.default.div(_templateObject5(), transition, function (_ref2) { var fixed = _ref2.fixed; return fixed !== false && (0, _css.default)(_templateObject6()); }); var WireframeAnnotationsToggle = _styled.default.button(_templateObject7(), function (_ref3) { var open = _ref3.open; return open && (0, _css.default)(_templateObject8()) || (0, _css.default)(_templateObject9()); }, function (_ref4) { var open = _ref4.open; return open && 1 || 0.25; }, transitionDuration, function (_ref5) { var open = _ref5.open; return !open && (0, _css.default)(_templateObject10()); }); exports.WireframeAnnotationsToggle = WireframeAnnotationsToggle; var WireframeAnnotationsClose = _styled.default.button(_templateObject11()); exports.WireframeAnnotationsClose = WireframeAnnotationsClose; var WireframeAnnotationNotesContainer = _styled.default.div(_templateObject12()); var ActiveWireframeAnnotationContext = /*#__PURE__*/(0, _react.createContext)(undefined); /** * Use the WireframeContainer at the top of your component tree * */ exports.ActiveWireframeAnnotationContext = ActiveWireframeAnnotationContext; var WireframeContainer = function WireframeContainer(_ref6) { var children = _ref6.children, open = _ref6.open, onToggleOpen = _ref6.onToggleOpen, className = _ref6.className, _ref6$defaultOpen = _ref6.defaultOpen, defaultOpen = _ref6$defaultOpen === void 0 ? true : _ref6$defaultOpen, onHighlightAnnotation = _ref6.onHighlightAnnotation, _ref6$fixed = _ref6.fixed, fixed = _ref6$fixed === void 0 ? true : _ref6$fixed; if (open !== undefined && !onToggleOpen) { throw new TypeError("Controlled container must implement 'onToggleOpen'"); } var _useState = (0, _react.useState)(false), _useState2 = _slicedToArray(_useState, 2), isClient = _useState2[0], setIsClient = _useState2[1]; (0, _utils.useIsomorphicLayoutEffect)(function () { setIsClient(true); }, []); var activeAPI = (0, _react.useContext)(ActiveWireframeAnnotationContext); var parentAPI = (0, _react.useContext)(_WireframeProvider.WireframeAnnotationContext); var parentAnnotation = (0, _react.useContext)(_WireframeProvider.WireframeAnnotationComponentContext); var _useState3 = (0, _react.useState)(), _useState4 = _slicedToArray(_useState3, 2), annotations = _useState4[0], setAnnotations = _useState4[1]; var _useState5 = (0, _react.useState)(undefined), _useState6 = _slicedToArray(_useState5, 2), highlightedNote = _useState6[0], setHighlightedNote = _useState6[1]; var _useState7 = (0, _react.useState)(false), _useState8 = _slicedToArray(_useState7, 2), isOpened = _useState8[0], setIsOpened = _useState8[1]; var _useState9 = (0, _react.useState)(open !== undefined ? open : defaultOpen), _useState10 = _slicedToArray(_useState9, 2), isOpen = _useState10[0], setIsOpen = _useState10[1]; var opening = (0, _react.useRef)(); var container = (0, _react.useRef)(null); var annotationsContainer = (0, _react.useRef)(null); var api = (0, _react.useMemo)(function () { if (activeAPI) { activeAPI.setOptions({ updater: setAnnotations, highlightNote: function highlightNote(wireFrameAnnotation) { return setHighlightedNote(wireFrameAnnotation); } }); return activeAPI; } return (0, _api.API)({ updater: setAnnotations, highlightNote: function highlightNote(wireFrameAnnotation) { return setHighlightedNote(wireFrameAnnotation); } }); }, [activeAPI]); (0, _react.useMemo)(function () { if (parentAPI && parentAnnotation) { api.setParentReference({ api: parentAPI, id: parentAnnotation.id }); } }, [api, parentAPI, parentAnnotation]); (0, _react.useEffect)(function () { var opener = api.onOpen(setIsOpen); return function () { opener.unregister(); }; }, [api]); (0, _react.useEffect)(function () { api.setOpen(isOpen); if (!isOpen) { api.highlightNote(undefined); } }, [api, isOpen]); (0, _react.useEffect)(function () { if (open !== undefined) { api.setOpen(open); } }, [api, open]); (0, _react.useEffect)(function () { clearTimeout(opening.current); if (isOpen) { setIsOpened(true); } else { opening.current = setTimeout(function () { setIsOpened(false); }, transitionDuration); } }, [isOpen]); (0, _useScrollElementIntoView.useScrollElementIntoView)({ element: highlightedNote && container.current && isOpen && container.current.querySelector("[data-annotation-id='".concat(highlightedNote.id, "']")) || null, boundary: annotationsContainer.current, onScrollIntoView: (0, _react.useCallback)(function (el) { return onHighlightAnnotation && highlightedNote && onHighlightAnnotation(highlightedNote, el); }, [onHighlightAnnotation, highlightedNote]) }); var handleToggle = (0, _react.useCallback)(function () { if (open === undefined) { setIsOpen(function (value) { return !value; }); } if (onToggleOpen) { onToggleOpen(!open); } }, [setIsOpen, open, onToggleOpen]); var handleClose = (0, _react.useCallback)(function () { if (open === undefined) { setIsOpen(false); } if (onToggleOpen) { onToggleOpen(!open); } }, [setIsOpen, open, onToggleOpen]); return /*#__PURE__*/_react.default.createElement(_WireframeProvider.WireframeProvider, { api: api }, /*#__PURE__*/_react.default.createElement(WireframeMainContainer, { "data-test": "container", className: isOpen && "open" || "", fixed: fixed }, /*#__PURE__*/_react.default.createElement(WireframeBody, { className: className }, children), isClient && /*#__PURE__*/_react.default.createElement(WireframeAnnotationsContainer, { "data-annotations-container": true, ref: container }, /*#__PURE__*/_react.default.createElement(WireframeAnnotationsWrapper, { "data-annotations": true, fixed: fixed }, /*#__PURE__*/_react.default.createElement(WireframeAnnotationsToggle, { open: isOpen, "data-test": "toggle", "data-annotations-toggle": true, title: "Toggle annotations", onClick: handleToggle }, /*#__PURE__*/_react.default.createElement("span", null, "\u2192")), isOpened && /*#__PURE__*/_react.default.createElement("header", { className: "annotations" }, /*#__PURE__*/_react.default.createElement("h1", null, "Annotations"), /*#__PURE__*/_react.default.createElement(WireframeAnnotationsClose, { "aria-label": "Close annotations", onClick: handleClose }, "\xD7")), isOpened && /*#__PURE__*/_react.default.createElement(WireframeAnnotationNotesContainer, { ref: annotationsContainer }, /*#__PURE__*/_react.default.createElement(_WireframeAnnotationNotes.WireframeAnnotationNotes, { annotations: annotations, parentReference: api.getParentReference(), highlightedNote: highlightedNote })))))); }; exports.WireframeContainer = WireframeContainer;