UNPKG

@pdftron/webviewer-react-toolkit

Version:

A React component library for integrating with PDFTron WebViewer API.

104 lines (103 loc) 5.57 kB
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();