@pdftron/webviewer-react-toolkit
Version:
A React component library for integrating with PDFTron WebViewer API.
104 lines (103 loc) • 5.57 kB
JavaScript
import { __assign, __rest } from "tslib";
import classnames from 'classnames';
import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react';
import { useAccessibleFocus, useFocus } from '../../hooks';
import { useID } from '../../hooks/useID';
import { Icon } from '../Icon';
export var Choice = forwardRef(function (_a, ref) {
var label = _a.label, leftLabel = _a.leftLabel, className = _a.className, children = _a.children, id = _a.id, radio = _a.radio, isSwitch = _a.isSwitch, center = _a.center, disabledLabelChange = _a.disabledLabelChange, onChange = _a.onChange, onFocus = _a.onFocus, onBlur = _a.onBlur, props = __rest(_a, ["label", "leftLabel", "className", "children", "id", "radio", "isSwitch", "center", "disabledLabelChange", "onChange", "onFocus", "onBlur"]);
var inputRef = useRef(null);
useImperativeHandle(ref, function () { return inputRef.current; });
var isUserTabbing = useAccessibleFocus();
var _b = useFocus(onFocus, onBlur), focused = _b.focused, handleOnFocus = _b.handleOnFocus, handleOnBlur = _b.handleOnBlur;
var choiceID = useID(id);
var _c = useState(function () { var _a, _b, _c; return (_c = (_a = props.checked) !== null && _a !== void 0 ? _a : (_b = inputRef.current) === null || _b === void 0 ? void 0 : _b.checked) !== null && _c !== void 0 ? _c : false; }), checked = _c[0], setChecked = _c[1];
useEffect(function () {
if (props.checked !== undefined)
setChecked(props.checked);
}, [props.checked]);
var handleOnChange = function (event) {
if (props.checked === undefined)
setChecked(event.target.checked);
onChange === null || onChange === void 0 ? void 0 : onChange(event);
};
// HACK: since there is no way to detect that a radio button is being
// unchecked due to form activity, we subscribe all radio buttons to an
// observable. When checked changes and props.checked is undefined, this
// will trigger the observable which will ping all other subscribers to
// check if they have become unchecked, and if so change their internal
// state.
useEffect(function () {
if (props.name && radio) {
return observable.subscribe(props.name, function () {
if (inputRef.current && inputRef.current.checked !== checked) {
setChecked(inputRef.current.checked);
}
});
}
return;
}, [checked, props.name, radio]);
var choiceClass = classnames('ui__base ui__choice', {
'ui__choice--radio': radio,
'ui__choice--leftLabel': leftLabel,
'ui__choice--checked': checked,
'ui__choice--center': center,
'ui__choice--disabled': props.disabled,
}, className);
var inputClass = classnames('ui__choice__input', {
'ui__choice__input--switch': isSwitch,
});
var checkClass = isSwitch
? classnames('ui__choice__input__switch', {
'ui__choice__input__switch--checked': checked,
'ui__choice__input__switch--disabled': props.disabled,
'ui__choice__input__switch--focus': isUserTabbing && focused,
})
: classnames('ui__choice__input__check', {
'ui__choice__input__check--checked': checked,
'ui__choice__input__check--disabled': props.disabled,
'ui__choice__input__check--focus': isUserTabbing && focused,
});
var labelClass = classnames('ui__choice__label', {
'ui__choice__label--disabled': props.disabled && disabledLabelChange,
});
var labelElement = useMemo(function () {
if (!label)
return undefined;
return (React.createElement("label", { className: labelClass, htmlFor: choiceID }, label));
}, [choiceID, label, labelClass]);
return (React.createElement("span", { className: choiceClass },
leftLabel ? labelElement : undefined,
React.createElement("span", { className: inputClass },
isSwitch ? (React.createElement("div", { className: checkClass },
React.createElement("div", { className: "ui__choice__input__toggle" }))) : (React.createElement("div", { className: checkClass }, checked && !radio ? React.createElement(Icon, { icon: "Check", className: "ui__choice__input__icon" }) : undefined)),
React.createElement("input", __assign({}, props, { id: choiceID, type: radio ? 'radio' : 'checkbox', onChange: handleOnChange, ref: inputRef, onFocus: handleOnFocus, onBlur: handleOnBlur }), children)),
!leftLabel ? labelElement : undefined));
});
/**
* Observable helper to notify radio buttons that they have become unchecked.
*/
var RadioObservable = /** @class */ (function () {
function RadioObservable() {
this._subscribers = [];
}
RadioObservable.prototype.subscribe = function (name, subscriber) {
this._trigger(name);
this._subscribers.push({ name: name, subscriber: subscriber });
return this._unsubscribe(subscriber);
};
RadioObservable.prototype._trigger = function (name) {
this._subscribers.forEach(function (s) {
if (name === s.name)
s.subscriber();
});
};
RadioObservable.prototype._unsubscribe = function (subscriber) {
var _this = this;
return function () {
_this._subscribers = _this._subscribers.filter(function (s) { return s.subscriber !== subscriber; });
};
};
return RadioObservable;
}());
var observable = new RadioObservable();