UNPKG

@cgi-learning-hub/ui

Version:

@cgi-learning-hub/ui is an open-source React component library that implements UI for HUB's features

884 lines (874 loc) 24.3 kB
var we = Object.defineProperty; var Be = (o, e, t) => e in o ? we(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t; var ae = (o, e, t) => Be(o, typeof e != "symbol" ? e + "" : e, t); import * as d from "react"; import H, { isValidElement as W, cloneElement as G, Children as Le } from "react"; import { P as n } from "./index-B9vkf41S.js"; import { H as C, F as pe, G as Oe } from "./generateUtilityClasses-B_xKAflz.js"; import { jsx as I, jsxs as ke } from "react/jsx-runtime"; import { u as fe, s as ne, c as je } from "./DefaultPropsProvider-BrmlvPWg.js"; import { a as Fe, u as $e } from "./useTimeout-CrCYVizI.js"; import { _ as Ie, a as Ue, T as ue } from "./TransitionGroupContext-DbLioz_6.js"; import { keyframes as oe } from "@emotion/react"; import { u as le } from "./useForkRef-u29GSuCu.js"; import { a as J } from "./useEventCallback-Y2KwRxBw.js"; import { i as ce } from "./isFocusVisible-CPZqtjv2.js"; import { e as ze } from "./elementTypeAcceptingRef-vRb2iI4O.js"; import { r as _e } from "./refType-8hihVLUh.js"; class Q { constructor() { ae(this, "mountEffect", () => { this.shouldMount && !this.didMount && this.ref.current !== null && (this.didMount = !0, this.mounted.resolve()); }); this.ref = { current: null }, this.mounted = null, this.didMount = !1, this.shouldMount = !1, this.setShouldMount = null; } /** React ref to the ripple instance */ /** If the ripple component should be mounted */ /** Promise that resolves when the ripple component is mounted */ /** If the ripple component has been mounted */ /** React state hook setter */ static create() { return new Q(); } static use() { const e = Fe(Q.create).current, [t, a] = d.useState(!1); return e.shouldMount = t, e.setShouldMount = a, d.useEffect(e.mountEffect, [t]), e; } mount() { return this.mounted || (this.mounted = Ye(), this.shouldMount = !0, this.setShouldMount(this.shouldMount)), this.mounted; } /* Ripple API */ start(...e) { this.mount().then(() => { var t; return (t = this.ref.current) == null ? void 0 : t.start(...e); }); } stop(...e) { this.mount().then(() => { var t; return (t = this.ref.current) == null ? void 0 : t.stop(...e); }); } pulsate(...e) { this.mount().then(() => { var t; return (t = this.ref.current) == null ? void 0 : t.pulsate(...e); }); } } function Xe() { return Q.use(); } function Ye() { let o, e; const t = new Promise((a, i) => { o = a, e = i; }); return t.resolve = o, t.reject = e, t; } function ee() { return ee = Object.assign ? Object.assign.bind() : function(o) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var a in t) ({}).hasOwnProperty.call(t, a) && (o[a] = t[a]); } return o; }, ee.apply(null, arguments); } function Ae(o) { if (o === void 0) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return o; } function ie(o, e) { var t = function(r) { return e && W(r) ? e(r) : r; }, a = /* @__PURE__ */ Object.create(null); return o && Le.map(o, function(i) { return i; }).forEach(function(i) { a[i.key] = t(i); }), a; } function Ke(o, e) { o = o || {}, e = e || {}; function t(h) { return h in e ? e[h] : o[h]; } var a = /* @__PURE__ */ Object.create(null), i = []; for (var r in o) r in e ? i.length && (a[r] = i, i = []) : i.push(r); var s, p = {}; for (var l in e) { if (a[l]) for (s = 0; s < a[l].length; s++) { var f = a[l][s]; p[a[l][s]] = t(f); } p[l] = t(l); } for (s = 0; s < i.length; s++) p[i[s]] = t(i[s]); return p; } function k(o, e, t) { return t[e] != null ? t[e] : o.props[e]; } function qe(o, e) { return ie(o.children, function(t) { return G(t, { onExited: e.bind(null, t), in: !0, appear: k(t, "appear", o), enter: k(t, "enter", o), exit: k(t, "exit", o) }); }); } function He(o, e, t) { var a = ie(o.children), i = Ke(e, a); return Object.keys(i).forEach(function(r) { var s = i[r]; if (W(s)) { var p = r in e, l = r in a, f = e[r], h = W(f) && !f.props.in; l && (!p || h) ? i[r] = G(s, { onExited: t.bind(null, s), in: !0, exit: k(s, "exit", o), enter: k(s, "enter", o) }) : !l && p && !h ? i[r] = G(s, { in: !1 }) : l && p && W(f) && (i[r] = G(s, { onExited: t.bind(null, s), in: f.props.in, exit: k(s, "exit", o), enter: k(s, "enter", o) })); } }), i; } var We = Object.values || function(o) { return Object.keys(o).map(function(e) { return o[e]; }); }, Ge = { component: "div", childFactory: function(e) { return e; } }, re = /* @__PURE__ */ (function(o) { Ie(e, o); function e(a, i) { var r; r = o.call(this, a, i) || this; var s = r.handleExited.bind(Ae(r)); return r.state = { contextValue: { isMounting: !0 }, handleExited: s, firstRender: !0 }, r; } var t = e.prototype; return t.componentDidMount = function() { this.mounted = !0, this.setState({ contextValue: { isMounting: !1 } }); }, t.componentWillUnmount = function() { this.mounted = !1; }, e.getDerivedStateFromProps = function(i, r) { var s = r.children, p = r.handleExited, l = r.firstRender; return { children: l ? qe(i, p) : He(i, s, p), firstRender: !1 }; }, t.handleExited = function(i, r) { var s = ie(this.props.children); i.key in s || (i.props.onExited && i.props.onExited(r), this.mounted && this.setState(function(p) { var l = ee({}, p.children); return delete l[i.key], { children: l }; })); }, t.render = function() { var i = this.props, r = i.component, s = i.childFactory, p = Ue(i, ["component", "childFactory"]), l = this.state.contextValue, f = We(this.state.children).map(s); return delete p.appear, delete p.enter, delete p.exit, r === null ? /* @__PURE__ */ H.createElement(ue.Provider, { value: l }, f) : /* @__PURE__ */ H.createElement(ue.Provider, { value: l }, /* @__PURE__ */ H.createElement(r, p, f)); }, e; })(H.Component); re.propTypes = process.env.NODE_ENV !== "production" ? { /** * `<TransitionGroup>` renders a `<div>` by default. You can change this * behavior by providing a `component` prop. * If you use React v16+ and would like to avoid a wrapping `<div>` element * you can pass in `component={null}`. This is useful if the wrapping div * borks your css styles. */ component: n.any, /** * A set of `<Transition>` components, that are toggled `in` and out as they * leave. the `<TransitionGroup>` will inject specific transition props, so * remember to spread them through if you are wrapping the `<Transition>` as * with our `<Fade>` example. * * While this component is meant for multiple `Transition` or `CSSTransition` * children, sometimes you may want to have a single transition child with * content that you want to be transitioned out and in when you change it * (e.g. routes, images etc.) In that case you can change the `key` prop of * the transition child as you change its content, this will cause * `TransitionGroup` to transition the child out and back in. */ children: n.node, /** * A convenience prop that enables or disables appear animations * for all children. Note that specifying this will override any defaults set * on individual children Transitions. */ appear: n.bool, /** * A convenience prop that enables or disables enter animations * for all children. Note that specifying this will override any defaults set * on individual children Transitions. */ enter: n.bool, /** * A convenience prop that enables or disables exit animations * for all children. Note that specifying this will override any defaults set * on individual children Transitions. */ exit: n.bool, /** * You may need to apply reactive updates to a child as it is exiting. * This is generally done by using `cloneElement` however in the case of an exiting * child the element has already been removed and not accessible to the consumer. * * If you do need to update a child as it leaves you can provide a `childFactory` * to wrap every child, even the ones that are leaving. * * @type Function(child: ReactElement) -> ReactElement */ childFactory: n.func } : {}; re.defaultProps = Ge; function de(o) { const { className: e, classes: t, pulsate: a = !1, rippleX: i, rippleY: r, rippleSize: s, in: p, onExited: l, timeout: f } = o, [h, m] = d.useState(!1), y = C(e, t.ripple, t.rippleVisible, a && t.ripplePulsate), D = { width: s, height: s, top: -(s / 2) + r, left: -(s / 2) + i }, g = C(t.child, h && t.childLeaving, a && t.childPulsate); return !p && !h && m(!0), d.useEffect(() => { if (!p && l != null) { const w = setTimeout(l, f); return () => { clearTimeout(w); }; } }, [l, p, f]), /* @__PURE__ */ I("span", { className: y, style: D, children: /* @__PURE__ */ I("span", { className: g }) }); } process.env.NODE_ENV !== "production" && (de.propTypes = { /** * Override or extend the styles applied to the component. */ classes: n.object.isRequired, className: n.string, /** * @ignore - injected from TransitionGroup */ in: n.bool, /** * @ignore - injected from TransitionGroup */ onExited: n.func, /** * If `true`, the ripple pulsates, typically indicating the keyboard focus state of an element. */ pulsate: n.bool, /** * Diameter of the ripple. */ rippleSize: n.number, /** * Horizontal position of the ripple center. */ rippleX: n.number, /** * Vertical position of the ripple center. */ rippleY: n.number, /** * exit delay */ timeout: n.number.isRequired }); const M = pe("MuiTouchRipple", ["root", "ripple", "rippleVisible", "ripplePulsate", "child", "childLeaving", "childPulsate"]), te = 550, Je = 80, Qe = oe` 0% { transform: scale(0); opacity: 0.1; } 100% { transform: scale(1); opacity: 0.3; } `, Ze = oe` 0% { opacity: 1; } 100% { opacity: 0; } `, et = oe` 0% { transform: scale(1); } 50% { transform: scale(0.92); } 100% { transform: scale(1); } `, tt = ne("span", { name: "MuiTouchRipple", slot: "Root" })({ overflow: "hidden", pointerEvents: "none", position: "absolute", zIndex: 0, top: 0, right: 0, bottom: 0, left: 0, borderRadius: "inherit" }), nt = ne(de, { name: "MuiTouchRipple", slot: "Ripple" })` opacity: 0; position: absolute; &.${M.rippleVisible} { opacity: 0.3; transform: scale(1); animation-name: ${Qe}; animation-duration: ${te}ms; animation-timing-function: ${({ theme: o }) => o.transitions.easing.easeInOut}; } &.${M.ripplePulsate} { animation-duration: ${({ theme: o }) => o.transitions.duration.shorter}ms; } & .${M.child} { opacity: 1; display: block; width: 100%; height: 100%; border-radius: 50%; background-color: currentColor; } & .${M.childLeaving} { opacity: 0; animation-name: ${Ze}; animation-duration: ${te}ms; animation-timing-function: ${({ theme: o }) => o.transitions.easing.easeInOut}; } & .${M.childPulsate} { position: absolute; /* @noflip */ left: 0px; top: 0; animation-name: ${et}; animation-duration: 2500ms; animation-timing-function: ${({ theme: o }) => o.transitions.easing.easeInOut}; animation-iteration-count: infinite; animation-delay: 200ms; } `, he = /* @__PURE__ */ d.forwardRef(function(e, t) { const a = fe({ props: e, name: "MuiTouchRipple" }), { center: i = !1, classes: r = {}, className: s, ...p } = a, [l, f] = d.useState([]), h = d.useRef(0), m = d.useRef(null); d.useEffect(() => { m.current && (m.current(), m.current = null); }, [l]); const y = d.useRef(!1), D = $e(), g = d.useRef(null), w = d.useRef(null), x = d.useCallback((c) => { const { pulsate: T, rippleX: R, rippleY: $, rippleSize: B, cb: U } = c; f((E) => [...E, /* @__PURE__ */ I(nt, { classes: { ripple: C(r.ripple, M.ripple), rippleVisible: C(r.rippleVisible, M.rippleVisible), ripplePulsate: C(r.ripplePulsate, M.ripplePulsate), child: C(r.child, M.child), childLeaving: C(r.childLeaving, M.childLeaving), childPulsate: C(r.childPulsate, M.childPulsate) }, timeout: te, pulsate: T, rippleX: R, rippleY: $, rippleSize: B }, h.current)]), h.current += 1, m.current = U; }, [r]), j = d.useCallback((c = {}, T = {}, R = () => { }) => { const { pulsate: $ = !1, center: B = i || T.pulsate, fakeElement: U = !1 // For test purposes } = T; if ((c == null ? void 0 : c.type) === "mousedown" && y.current) { y.current = !1; return; } (c == null ? void 0 : c.type) === "touchstart" && (y.current = !0); const E = U ? null : w.current, V = E ? E.getBoundingClientRect() : { width: 0, height: 0, left: 0, top: 0 }; let S, P, v; if (B || c === void 0 || c.clientX === 0 && c.clientY === 0 || !c.clientX && !c.touches) S = Math.round(V.width / 2), P = Math.round(V.height / 2); else { const { clientX: z, clientY: L } = c.touches && c.touches.length > 0 ? c.touches[0] : c; S = Math.round(z - V.left), P = Math.round(L - V.top); } if (B) v = Math.sqrt((2 * V.width ** 2 + V.height ** 2) / 3), v % 2 === 0 && (v += 1); else { const z = Math.max(Math.abs((E ? E.clientWidth : 0) - S), S) * 2 + 2, L = Math.max(Math.abs((E ? E.clientHeight : 0) - P), P) * 2 + 2; v = Math.sqrt(z ** 2 + L ** 2); } c != null && c.touches ? g.current === null && (g.current = () => { x({ pulsate: $, rippleX: S, rippleY: P, rippleSize: v, cb: R }); }, D.start(Je, () => { g.current && (g.current(), g.current = null); })) : x({ pulsate: $, rippleX: S, rippleY: P, rippleSize: v, cb: R }); }, [i, x, D]), A = d.useCallback(() => { j({}, { pulsate: !0 }); }, [j]), F = d.useCallback((c, T) => { if (D.clear(), (c == null ? void 0 : c.type) === "touchend" && g.current) { g.current(), g.current = null, D.start(0, () => { F(c, T); }); return; } g.current = null, f((R) => R.length > 0 ? R.slice(1) : R), m.current = T; }, [D]); return d.useImperativeHandle(t, () => ({ pulsate: A, start: j, stop: F }), [A, j, F]), /* @__PURE__ */ I(tt, { className: C(M.root, r.root, s), ref: w, ...p, children: /* @__PURE__ */ I(re, { component: null, exit: !0, children: l }) }); }); process.env.NODE_ENV !== "production" && (he.propTypes = { /** * If `true`, the ripple starts at the center of the component * rather than at the point of interaction. */ center: n.bool, /** * Override or extend the styles applied to the component. */ classes: n.object, /** * @ignore */ className: n.string }); function ot(o) { return Oe("MuiButtonBase", o); } const it = pe("MuiButtonBase", ["root", "disabled", "focusVisible"]), rt = (o) => { const { disabled: e, focusVisible: t, focusVisibleClassName: a, classes: i } = o, s = je({ root: ["root", e && "disabled", t && "focusVisible"] }, ot, i); return t && a && (s.root += ` ${a}`), s; }, st = ne("button", { name: "MuiButtonBase", slot: "Root" })({ display: "inline-flex", alignItems: "center", justifyContent: "center", position: "relative", boxSizing: "border-box", WebkitTapHighlightColor: "transparent", backgroundColor: "transparent", // Reset default value // We disable the focus ring for mouse, touch and keyboard users. outline: 0, border: 0, margin: 0, // Remove the margin in Safari borderRadius: 0, padding: 0, // Remove the padding in Firefox cursor: "pointer", userSelect: "none", verticalAlign: "middle", MozAppearance: "none", // Reset WebkitAppearance: "none", // Reset textDecoration: "none", // So we take precedent over the style of a native <a /> element. color: "inherit", "&::-moz-focus-inner": { borderStyle: "none" // Remove Firefox dotted outline. }, [`&.${it.disabled}`]: { pointerEvents: "none", // Disable link interactions cursor: "default" }, "@media print": { colorAdjust: "exact" } }), at = /* @__PURE__ */ d.forwardRef(function(e, t) { const a = fe({ props: e, name: "MuiButtonBase" }), { action: i, centerRipple: r = !1, children: s, className: p, component: l = "button", disabled: f = !1, disableRipple: h = !1, disableTouchRipple: m = !1, focusRipple: y = !1, focusVisibleClassName: D, LinkComponent: g = "a", onBlur: w, onClick: x, onContextMenu: j, onDragLeave: A, onFocus: F, onFocusVisible: c, onKeyDown: T, onKeyUp: R, onMouseDown: $, onMouseLeave: B, onMouseUp: U, onTouchEnd: E, onTouchMove: V, onTouchStart: S, tabIndex: P = 0, TouchRippleProps: v, touchRippleRef: z, type: L, ..._ } = a, X = d.useRef(null), b = Xe(), me = le(b.ref, z), [O, K] = d.useState(!1); f && O && K(!1), d.useImperativeHandle(i, () => ({ focusVisible: () => { K(!0), X.current.focus(); } }), []); const be = b.shouldMount && !h && !f; d.useEffect(() => { O && y && !h && b.pulsate(); }, [h, y, O, b]); const ge = N(b, "start", $, m), Me = N(b, "stop", j, m), ye = N(b, "stop", A, m), Re = N(b, "stop", U, m), Te = N(b, "stop", (u) => { O && u.preventDefault(), B && B(u); }, m), Ee = N(b, "start", S, m), Ce = N(b, "stop", E, m), xe = N(b, "stop", V, m), Pe = N(b, "stop", (u) => { ce(u.target) || K(!1), w && w(u); }, !1), Ne = J((u) => { X.current || (X.current = u.currentTarget), ce(u.target) && (K(!0), c && c(u)), F && F(u); }), Z = () => { const u = X.current; return l && l !== "button" && !(u.tagName === "A" && u.href); }, De = J((u) => { y && !u.repeat && O && u.key === " " && b.stop(u, () => { b.start(u); }), u.target === u.currentTarget && Z() && u.key === " " && u.preventDefault(), T && T(u), u.target === u.currentTarget && Z() && u.key === "Enter" && !f && (u.preventDefault(), x && x(u)); }), Ve = J((u) => { y && u.key === " " && O && !u.defaultPrevented && b.stop(u, () => { b.pulsate(u); }), R && R(u), x && u.target === u.currentTarget && Z() && u.key === " " && !u.defaultPrevented && x(u); }); let q = l; q === "button" && (_.href || _.to) && (q = g); const Y = {}; q === "button" ? (Y.type = L === void 0 ? "button" : L, Y.disabled = f) : (!_.href && !_.to && (Y.role = "button"), f && (Y["aria-disabled"] = f)); const Se = le(t, X), se = { ...a, centerRipple: r, component: l, disabled: f, disableRipple: h, disableTouchRipple: m, focusRipple: y, tabIndex: P, focusVisible: O }, ve = rt(se); return /* @__PURE__ */ ke(st, { as: q, className: C(ve.root, p), ownerState: se, onBlur: Pe, onClick: x, onContextMenu: Me, onFocus: Ne, onKeyDown: De, onKeyUp: Ve, onMouseDown: ge, onMouseLeave: Te, onMouseUp: Re, onDragLeave: ye, onTouchEnd: Ce, onTouchMove: xe, onTouchStart: Ee, ref: Se, tabIndex: f ? -1 : P, type: L, ...Y, ..._, children: [s, be ? /* @__PURE__ */ I(he, { ref: me, center: r, ...v }) : null] }); }); function N(o, e, t, a = !1) { return J((i) => (t && t(i), a || o[e](i), !0)); } process.env.NODE_ENV !== "production" && (at.propTypes = { // ┌────────────────────────────── Warning ──────────────────────────────┐ // │ These PropTypes are generated from the TypeScript type definitions. │ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │ // └─────────────────────────────────────────────────────────────────────┘ /** * A ref for imperative actions. * It currently only supports `focusVisible()` action. */ action: _e, /** * If `true`, the ripples are centered. * They won't start at the cursor interaction position. * @default false */ centerRipple: n.bool, /** * The content of the component. */ children: n.node, /** * Override or extend the styles applied to the component. */ classes: n.object, /** * @ignore */ className: n.string, /** * The component used for the root node. * Either a string to use a HTML element or a component. */ component: ze, /** * If `true`, the component is disabled. * @default false */ disabled: n.bool, /** * If `true`, the ripple effect is disabled. * * ⚠️ Without a ripple there is no styling for :focus-visible by default. Be sure * to highlight the element by applying separate styles with the `.Mui-focusVisible` class. * @default false */ disableRipple: n.bool, /** * If `true`, the touch ripple effect is disabled. * @default false */ disableTouchRipple: n.bool, /** * If `true`, the base button will have a keyboard focus ripple. * @default false */ focusRipple: n.bool, /** * This prop can help identify which element has keyboard focus. * The class name will be applied when the element gains the focus through keyboard interaction. * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo). * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/HEAD/explainer.md). * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `focus-visible` class to other components * if needed. */ focusVisibleClassName: n.string, /** * @ignore */ href: n.any, /** * The component used to render a link when the `href` prop is provided. * @default 'a' */ LinkComponent: n.elementType, /** * @ignore */ onBlur: n.func, /** * @ignore */ onClick: n.func, /** * @ignore */ onContextMenu: n.func, /** * @ignore */ onDragLeave: n.func, /** * @ignore */ onFocus: n.func, /** * Callback fired when the component is focused with a keyboard. * We trigger a `onFocus` callback too. */ onFocusVisible: n.func, /** * @ignore */ onKeyDown: n.func, /** * @ignore */ onKeyUp: n.func, /** * @ignore */ onMouseDown: n.func, /** * @ignore */ onMouseLeave: n.func, /** * @ignore */ onMouseUp: n.func, /** * @ignore */ onTouchEnd: n.func, /** * @ignore */ onTouchMove: n.func, /** * @ignore */ onTouchStart: n.func, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx: n.oneOfType([n.arrayOf(n.oneOfType([n.func, n.object, n.bool])), n.func, n.object]), /** * @default 0 */ tabIndex: n.number, /** * Props applied to the `TouchRipple` element. */ TouchRippleProps: n.object, /** * A ref that points to the `TouchRipple` element. */ touchRippleRef: n.oneOfType([n.func, n.shape({ current: n.shape({ pulsate: n.func.isRequired, start: n.func.isRequired, stop: n.func.isRequired }) })]), /** * @ignore */ type: n.oneOfType([n.oneOf(["button", "reset", "submit"]), n.string]) }); export { at as B, re as T, ee as _ };