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
JavaScript
;
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