UNPKG

lincd

Version:

LINCD is a JavaScript library for building user interfaces with linked data (also known as 'structured data', or RDF)

127 lines 5.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useWatchPropertySet = exports.useStyles = void 0; exports.useWatchProperty = useWatchProperty; const react_1 = require("react"); const react_usestateref_1 = __importDefault(require("react-usestateref")); const Shape_1 = require("../shapes/Shape"); const models_1 = require("../models"); const ShapeClass_1 = require("./ShapeClass"); /** * Merges styles and class names from props with the classnames & styles given as arguments * @param props * @param classNamesOrStyles class name(s) or a style object * @param styles option to provide a style object if class names were given as first argument */ const useStyles = (props, classNamesOrStyles, styles) => { let classNames; let combinedStyles; let propsCopy = Object.assign({}, props); if (props.className) { if (typeof props.className === 'string') { classNames = [props.className]; } else if (Array.isArray(props.className)) { classNames = props.className; } delete propsCopy.className; } if (props.style) { combinedStyles = props.style; delete propsCopy.style; } if (classNamesOrStyles) { let paramType = typeof classNamesOrStyles; if (paramType === 'string') { if (classNames) { classNames.push(classNamesOrStyles); } else { classNames = [classNamesOrStyles]; } } else if (paramType === 'object') { if (Array.isArray(classNamesOrStyles)) { if (classNames) { classNames = classNames.concat(classNamesOrStyles); } else { classNames = classNamesOrStyles; } } else { //merge props.style with first param (which is a React.CSSProperties object) combinedStyles = Object.assign(Object.assign({}, props.style), classNamesOrStyles); } } if (styles) { //merge props.style with second param (first param must have been class names) combinedStyles = Object.assign(Object.assign({}, combinedStyles), styles); } } return Object.assign({ className: classNames.filter(Boolean).join(' '), style: combinedStyles }, propsCopy); }; exports.useStyles = useStyles; /** * Updates your component automatically when the values for a given subject+predicate ValuesSet change * @param valuesSet */ const useWatchPropertySet = (...valuesSets) => { let [bool, setBool, boolRef] = (0, react_usestateref_1.default)(false); let forceUpdate = (0, react_1.useCallback)(() => { setBool(!boolRef.current); }, [bool]); (0, react_1.useEffect)(() => { valuesSets.forEach(valuesSet => valuesSet.onChange(forceUpdate)); return () => { valuesSets.forEach(valuesSet => valuesSet.removeOnChange(forceUpdate)); }; }, []); }; exports.useWatchPropertySet = useWatchPropertySet; function useWatchProperty(source, property) { let [bool, setBool, boolRef] = (0, react_usestateref_1.default)(false); let forceUpdate = (0, react_1.useCallback)(() => { setBool(!boolRef.current); }, [bool]); (0, react_1.useEffect)(() => { if (typeof property === 'string') { if (source instanceof Shape_1.Shape) { //we want to check all the property shapes of the given shape //we could access shape.nodeShape, but we actually also need the propertyShapes of all the shapes in the inheritance chain //this we can (currently) do by getting the shapeClass first let shapeClass = (0, ShapeClass_1.getShapeClass)(source.nodeShape.namedNode); //from there we can get the classes it extends let shapeClasses = (0, ShapeClass_1.getSuperShapesClasses)(shapeClass); //we add back the shapeClass itself, as the first shapeClass to check shapeClasses.unshift(shapeClass); //then for each shape class for (let shapeClass of shapeClasses) { //we can check if it has a property shape with the given name let matchingPropertyShape = shapeClass.shape.getPropertyShapes().find(shape => { return shape.label === property; }); if (matchingPropertyShape) { //TODO: if path can be multiple props, we need to watch the whole path property = matchingPropertyShape.path; break; } } if (!(property instanceof models_1.NamedNode)) { throw new Error(`Can't find property ${property} on shape ${source.nodeShape.label}`); } } else { throw new Error("Can't use string property with a NamedNode source. Provide a shape + string or NamedNode + NamedNode instead."); } } source.onChange(property, forceUpdate); return () => { source.removeOnChange(property, forceUpdate); }; }, []); } //# sourceMappingURL=Hooks.js.map