ish-ui 1.2.8 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/appBar/AppBarHelpMenu.js +1 -1
  2. package/dist/colorPicker/ColorPicker.js +2 -2
  3. package/dist/dialog/BrowserWarning.js +1 -1
  4. package/dist/dialog/message/Message.js +21 -15
  5. package/dist/dynamicSizeList/DynamicSizeList.d.ts +21 -12
  6. package/dist/dynamicSizeList/DynamicSizeList.js +30 -157
  7. package/dist/fieldMessage/styles.d.ts +2 -2
  8. package/dist/fileUploader/FileUploaderDialog.js +8 -1
  9. package/dist/formFields/AutosizeInput.d.ts +14 -0
  10. package/dist/formFields/AutosizeInput.js +156 -0
  11. package/dist/formFields/CheckboxField.d.ts +4 -2
  12. package/dist/formFields/ColoredCheckBox.js +5 -2
  13. package/dist/formFields/EditInPlaceDateTimeField.js +35 -36
  14. package/dist/formFields/EditInPlaceField.js +8 -9
  15. package/dist/formFields/EditInPlaceFieldBase.d.ts +2 -3
  16. package/dist/formFields/EditInPlaceFieldBase.js +7 -14
  17. package/dist/formFields/EditInPlaceFileField.js +10 -2
  18. package/dist/formFields/EditInPlaceMoneyField.js +2 -2
  19. package/dist/formFields/EditInPlacePhoneField.js +13 -3
  20. package/dist/formFields/EditInPlaceSearchSelect.js +6 -3
  21. package/dist/formFields/SelectCustomComponents.d.ts +18 -4
  22. package/dist/formFields/SelectCustomComponents.js +36 -20
  23. package/dist/formFields/Switch.d.ts +3 -1
  24. package/dist/markdownEditor/WysiwygEditor.js +14 -16
  25. package/dist/markdownEditor/utils/index.d.ts +1 -1
  26. package/dist/model/Fields.d.ts +1 -6
  27. package/dist/styles/makeStyles.d.ts +8 -25
  28. package/dist/styles/makeStyles.js +9 -3
  29. package/dist/tagsInput/AddTagMenu.d.ts +2 -2
  30. package/dist/tagsInput/AddTagMenu.js +8 -5
  31. package/dist/tagsInput/AddTagMenuItem.d.ts +2 -2
  32. package/dist/tagsInput/AddTagMenuItem.js +1 -1
  33. package/dist/tagsInput/TagInputList.js +102 -155
  34. package/dist/themes/ishTheme.js +13 -3
  35. package/dist/utils/DOM/index.d.ts +0 -1
  36. package/dist/utils/DOM/index.js +0 -1
  37. package/dist/utils/dates/formatTimezone.js +3 -3
  38. package/dist/utils/formatting/index.d.ts +1 -1
  39. package/dist/utils/hooks/index.d.ts +16 -0
  40. package/dist/utils/hooks/index.js +31 -1
  41. package/dist/utils/tags/index.d.ts +1 -1
  42. package/dist/utils/tags/index.js +1 -1
  43. package/package.json +81 -71
  44. package/tsconfig.prod.json +3 -0
  45. package/dist/utils/DOM/getCaretCoordinates.d.ts +0 -6
  46. package/dist/utils/DOM/getCaretCoordinates.js +0 -109
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { withStyles } from 'tss-react/mui';
3
- import HelpOutline from '@mui/icons-material/HelpOutline';
3
+ import HelpOutline from '@mui/icons-material/HelpOutlineOutlined';
4
4
  import IconButton from '@mui/material/IconButton';
5
5
  import Typography from '@mui/material/Typography';
6
6
  import Menu from '@mui/material/Menu';
@@ -9,7 +9,7 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
9
9
  import ButtonBase from '@mui/material/ButtonBase';
10
10
  import Popper from '@mui/material/Popper';
11
11
  import { AlphaPicker, HuePicker } from 'react-color';
12
- import { ClickAwayListener } from '@mui/base';
12
+ import { ClickAwayListener } from '@mui/material';
13
13
  import Paper from '@mui/material/Paper';
14
14
  import Grow from '@mui/material/Grow';
15
15
  import { stopEventPropagation } from '../utils/events';
@@ -87,7 +87,7 @@ const ColorPickerBase = React.memo(({ color, input: { value, onChange }, Transit
87
87
  const { classes, cx } = useStyles();
88
88
  const [hueColor, setHueColor] = useState(color);
89
89
  const [alfaColor, setAlfaColor] = useState(color);
90
- const hueRef = useRef();
90
+ const hueRef = useRef(undefined);
91
91
  const onHueChange = useCallback(color => {
92
92
  setHueColor(color.hsv);
93
93
  setAlfaColor(color.hsv);
@@ -1,4 +1,4 @@
1
- import { Alert } from '@mui/lab';
1
+ import { Alert } from '@mui/material';
2
2
  import * as React from 'react';
3
3
  const BROWSER_WARNING_TEXT = 'Your current browser is not supported. Please ensure you are using an up to date version of Chrome, Firefox or Edge.';
4
4
  export const isOldIE = () => {
@@ -50,21 +50,27 @@ const Message = ({ opened, text, clearMessage, success, persist }) => {
50
50
  horizontal: 'left'
51
51
  }, classes: {
52
52
  root: classes.autoWidthRoot
53
- }, ContentProps: {
54
- classes: {
55
- root: cx(classes.autoWidth, {
56
- [classes.success]: success
57
- }),
58
- message: persist ? classes.fullScreenMessage : undefined
53
+ }, slotProps: {
54
+ content: {
55
+ classes: {
56
+ root: cx(classes.autoWidth, {
57
+ [classes.success]: success
58
+ }),
59
+ message: persist ? classes.fullScreenMessage : undefined
60
+ }
61
+ },
62
+ clickAwayListener: {
63
+ onClickAway: handleClose
59
64
  }
60
- }, ClickAwayListenerProps: {
61
- onClickAway: handleClose
62
- }, autoHideDuration: persist ? null : 6000, onClose: handleClose, disableWindowBlurListener: persist },
63
- React.createElement(Alert, { variant: "filled", severity: success ? 'success' : 'error', classes: {
64
- message: 'text-pre-wrap',
65
- standardError: 'errorBackgroundColor',
66
- standardSuccess: 'successBackgroundColor'
67
- }, action: (React.createElement(IconButton, { key: "close", "aria-label": "Close", color: "inherit", className: classes.close, onClick: clearMessage },
68
- React.createElement(CloseIcon, null))) }, text)));
65
+ }, autoHideDuration: persist ? null : 6000, onClose: handleClose, disableWindowBlurListener: persist }, React.createElement(Alert, { variant: "filled", severity: success ? 'success' : 'error', classes: {
66
+ // MUI 9 replaced the variant+severity class keys (`standardError`,
67
+ // `standardSuccess`) with separate `standard` and `colorError` /
68
+ // `colorSuccess` keys. Both were already inert here because this
69
+ // Alert renders with `variant="filled"`, so they are dropped rather
70
+ // than remapped — remapping to `colorError`/`colorSuccess` would
71
+ // newly apply styling that has never been active.
72
+ message: 'text-pre-wrap'
73
+ }, action: (React.createElement(IconButton, { key: "close", "aria-label": "Close", color: "inherit", className: classes.close, onClick: clearMessage },
74
+ React.createElement(CloseIcon, null))) }, text)));
69
75
  };
70
76
  export default Message;
@@ -1,17 +1,26 @@
1
1
  import React from 'react';
2
- import { VariableSizeListProps } from 'react-window';
3
- interface Props extends Omit<VariableSizeListProps, 'itemSize'> {
2
+ export interface DynamicSizeListProps {
3
+ /** Component rendering a single row; receives `data`, `index` and `style`. */
4
+ children: any;
5
+ itemCount: number;
6
+ itemData?: any;
7
+ height?: number | string;
8
+ width?: number | string;
9
+ /** Row height assumed before a row has been measured. */
10
+ estimatedItemSize?: number;
4
11
  listRef?: any;
12
+ className?: string;
13
+ overscanCount?: number;
5
14
  }
6
- declare class DynamicSizeList extends React.Component<Props> {
7
- listRef: React.RefObject<any>;
8
- rowSizes: any[];
9
- componentDidMount(): void;
10
- attachRefs: (node: any) => void;
11
- render(): React.JSX.Element;
12
- scrollToItem(index: any, align: any): void;
13
- renderItem: (props: any) => React.ReactElement<any, string | React.JSXElementConstructor<any>>;
14
- handleNewMeasurements: (index: any, newSize: any) => void;
15
- getItemSize: (index: any) => any;
15
+ export interface DynamicSizeListApi {
16
+ scrollToItem(index: number, align?: 'auto' | 'center' | 'end' | 'smart' | 'start'): void;
16
17
  }
18
+ /**
19
+ * Variable-height virtualised list.
20
+ *
21
+ * react-window v2 measures dynamic rows itself through `useDynamicRowHeight`,
22
+ * which replaces the ResizeObserver-based row measurer this component used to
23
+ * carry against v1's `VariableSizeList`.
24
+ */
25
+ declare const DynamicSizeList: React.ForwardRefExoticComponent<DynamicSizeListProps & React.RefAttributes<DynamicSizeListApi>>;
17
26
  export default DynamicSizeList;
@@ -5,163 +5,36 @@
5
5
  *
6
6
  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
7
  */
8
- var __rest = (this && this.__rest) || function (s, e) {
9
- var t = {};
10
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
11
- t[p] = s[p];
12
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
13
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
14
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
15
- t[p[i]] = s[p[i]];
16
- }
17
- return t;
18
- };
19
- import React from 'react';
20
- import { VariableSizeList } from 'react-window';
21
- class ItemMeasurer extends React.Component {
22
- constructor() {
23
- super(...arguments);
24
- this._node = null;
25
- this._resizeObserver = null;
26
- this._measureItem = () => {
27
- const { handleNewMeasurements, index } = this.props;
28
- const node = this._node;
29
- if (node) {
30
- const { height, width } = node.getBoundingClientRect();
31
- const isVisible = height > 0 || width > 0;
32
- if (isVisible) {
33
- const newSize = Math.ceil(height);
34
- handleNewMeasurements(index, newSize);
35
- }
36
- }
37
- };
38
- this._refSetter = ref => {
39
- if (this._resizeObserver !== null && this._node !== null) {
40
- this._resizeObserver.unobserve(this._node);
41
- }
42
- if (ref) {
43
- this._node = ref;
44
- }
45
- else {
46
- this._node = null;
47
- }
48
- if (this._resizeObserver !== null && this._node !== null) {
49
- this._resizeObserver.observe(this._node);
50
- }
51
- };
52
- this._onResize = entries => {
53
- const _this = this;
54
- window.requestAnimationFrame(() => {
55
- if (!Array.isArray(entries) || !entries.length) {
56
- return;
57
- }
58
- _this._measureItem();
59
- });
60
- };
61
- }
62
- componentDidMount() {
63
- this._measureItem();
64
- // @ts-ignore
65
- if (typeof window.ResizeObserver !== 'undefined') {
66
- // @ts-ignore
67
- this._resizeObserver = new window.ResizeObserver(this._onResize);
68
- if (this._node !== null) {
69
- this._resizeObserver.observe(this._node);
70
- }
71
- }
72
- else {
73
- //
74
- }
75
- }
76
- componentWillUnmount() {
77
- if (this._resizeObserver !== null) {
78
- this._resizeObserver.disconnect();
79
- this._resizeObserver = null;
80
- }
81
- }
82
- render() {
83
- return React.cloneElement(this.props.item, {
84
- ref: this._refSetter
85
- });
86
- }
87
- }
88
- class DynamicSizeList extends React.Component {
89
- constructor() {
90
- super(...arguments);
91
- this.listRef = React.createRef();
92
- this.rowSizes = [];
93
- this.attachRefs = node => {
94
- const { listRef } = this.props;
95
- if (node) {
96
- if (!this.listRef.current) {
97
- // @ts-ignore
98
- this.listRef.current = node;
99
- }
100
- if (typeof listRef === 'function') {
101
- listRef(node);
102
- }
103
- if (typeof listRef === 'object') {
104
- listRef.current = node;
105
- }
106
- }
107
- };
108
- this.renderItem = props => {
109
- // clear height
110
- if (props.style.height !== undefined) {
111
- props.style.height = undefined;
112
- }
113
- return React.createElement(ItemMeasurer, {
114
- index: props.index,
115
- // @ts-ignore
116
- item: React.createElement(this.props.children, props),
117
- handleNewMeasurements: this.handleNewMeasurements
118
- });
119
- };
120
- this.handleNewMeasurements = (index, newSize) => {
121
- const itemSizeDelta = newSize - this.getItemSize(index);
122
- if (itemSizeDelta !== 0) {
123
- this.rowSizes[index] = newSize;
124
- const ref = this.listRef.current;
125
- if (ref) {
126
- const { isScrolling, scrollDirection } = ref.state;
127
- if (isScrolling && scrollDirection === 'backward') {
128
- ref._outerRef.scrollBy({
129
- top: itemSizeDelta,
130
- left: 0,
131
- behavior: 'auto'
132
- });
133
- }
134
- ref.resetAfterIndex(index, true);
135
- }
136
- }
137
- };
138
- this.getItemSize = index => {
139
- // https://react-window.now.sh/#/api/VariableSizeList
140
- const defaultEstimatedItemSize = 50;
141
- return (this.rowSizes[index]
142
- || this.props.estimatedItemSize
143
- || defaultEstimatedItemSize);
144
- };
145
- }
146
- componentDidMount() {
147
- const ref = this.listRef.current;
148
- if (ref) {
149
- ref.resetAfterIndex(0, true);
8
+ import React, { useImperativeHandle, useRef } from 'react';
9
+ import { List, useDynamicRowHeight } from 'react-window';
10
+ /**
11
+ * Variable-height virtualised list.
12
+ *
13
+ * react-window v2 measures dynamic rows itself through `useDynamicRowHeight`,
14
+ * which replaces the ResizeObserver-based row measurer this component used to
15
+ * carry against v1's `VariableSizeList`.
16
+ */
17
+ const DynamicSizeList = React.forwardRef(({ children, itemCount, itemData, height, width, estimatedItemSize, listRef, className, overscanCount, }, ref) => {
18
+ const defaultEstimatedItemSize = 50;
19
+ const rowHeight = useDynamicRowHeight({
20
+ defaultRowHeight: estimatedItemSize || defaultEstimatedItemSize,
21
+ });
22
+ const listApi = useRef(undefined);
23
+ const attachRefs = node => {
24
+ listApi.current = node;
25
+ if (typeof listRef === 'function') {
26
+ listRef(node);
150
27
  }
151
- }
152
- render() {
153
- const _a = this.props, { children } = _a, rest = __rest(_a, ["children"]);
154
- return (React.createElement(VariableSizeList, Object.assign({}, rest, { ref: this.attachRefs, itemSize: this.getItemSize }), this.renderItem));
155
- }
156
- scrollToItem(index, align) {
157
- const ref = this.listRef.current;
158
- if (ref) {
159
- ref.scrollToItem(index, align);
160
- //
161
- window.requestAnimationFrame(() => {
162
- ref.scrollToItem(index, align);
163
- });
28
+ else if (listRef && typeof listRef === 'object') {
29
+ listRef.current = node;
164
30
  }
165
- }
166
- }
31
+ };
32
+ useImperativeHandle(ref, () => ({
33
+ scrollToItem: (index, align) => {
34
+ var _a;
35
+ (_a = listApi.current) === null || _a === void 0 ? void 0 : _a.scrollToRow({ index, align });
36
+ },
37
+ }), []);
38
+ return (React.createElement(List, { className: className, style: { height, width }, listRef: attachRefs, rowComponent: children, rowProps: { data: itemData }, rowCount: itemCount, rowHeight: rowHeight, overscanCount: overscanCount }));
39
+ });
167
40
  export default DynamicSizeList;
@@ -1,5 +1,6 @@
1
1
  import { AppTheme } from '../model';
2
- declare const _default: (theme: AppTheme) => {
2
+ export default _default;
3
+ declare function _default(theme: AppTheme): {
3
4
  root: {
4
5
  marginTop: string;
5
6
  paddingBottom: string;
@@ -11,4 +12,3 @@ declare const _default: (theme: AppTheme) => {
11
12
  marginRight: string;
12
13
  };
13
14
  };
14
- export default _default;
@@ -87,7 +87,14 @@ const FileUploaderDialog = (props => {
87
87
  "Please upload only:",
88
88
  ' ',
89
89
  acceptText())))))));
90
- return dialog ? (React.createElement(Dialog, { ref: fileRef, open: opened, disableEscapeKeyDown: true, onClose: onClose, classes: {
90
+ return dialog ? (React.createElement(Dialog, { ref: fileRef, open: opened,
91
+ // MUI 9 removed `disableEscapeKeyDown`; ignoring the `escapeKeyDown`
92
+ // close reason preserves the previous behaviour.
93
+ onClose: onClose && ((event, reason) => {
94
+ if (reason !== 'escapeKeyDown') {
95
+ onClose();
96
+ }
97
+ }), classes: {
91
98
  paper: 'w-100'
92
99
  } },
93
100
  React.createElement("div", null,
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ interface AutosizeInputProps extends React.ComponentPropsWithRef<"input"> {
3
+ placeholder?: string;
4
+ /**
5
+ * Space kept free after the text, in px. Defaults to the advance width of a
6
+ * single space in the input's resolved font, so the caret always fits without
7
+ * the value scrolling inside the input.
8
+ */
9
+ reserveWidth?: number;
10
+ /** MUI InputBase hands the DOM node over through this prop instead of `ref`. */
11
+ inputRef?: React.Ref<HTMLInputElement>;
12
+ }
13
+ export declare const AutosizeInput: React.FC<AutosizeInputProps>;
14
+ export {};
@@ -0,0 +1,156 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
13
+ /**
14
+ * The space is measured as the difference between these two strings instead of
15
+ * on its own: a span holding nothing but whitespace is not reliably measurable,
16
+ * and differencing also folds letter- and word-spacing into the result. Both
17
+ * samples use `M` so that a copied `text-transform` cannot change them.
18
+ */
19
+ const SPACE_SAMPLE = "M M";
20
+ const NO_SPACE_SAMPLE = "MM";
21
+ /** Every property that can change the advance width of a string. */
22
+ const TYPOGRAPHY_PROPS = [
23
+ "font-family",
24
+ "font-size",
25
+ "font-weight",
26
+ "font-style",
27
+ "font-stretch",
28
+ "font-variant",
29
+ "font-feature-settings",
30
+ "font-variation-settings",
31
+ "font-kerning",
32
+ "font-optical-sizing",
33
+ "letter-spacing",
34
+ "word-spacing",
35
+ "text-transform"
36
+ ];
37
+ const measureStyle = {
38
+ // Typography is copied from the input itself once mounted, `inherit` is just
39
+ // the starting approximation
40
+ font: "inherit",
41
+ letterSpacing: "inherit",
42
+ textTransform: "inherit",
43
+ position: "absolute",
44
+ top: 0,
45
+ left: 0,
46
+ visibility: "hidden",
47
+ pointerEvents: "none",
48
+ whiteSpace: "pre",
49
+ height: 0,
50
+ padding: 0,
51
+ border: "none",
52
+ margin: 0
53
+ };
54
+ /** Bumped when webfonts finish loading, which invalidates cached glyph metrics. */
55
+ let fontEpoch = 0;
56
+ const spaceWidthCache = new Map();
57
+ /**
58
+ * Copies the typography of `source` onto `targets` and returns a signature of
59
+ * the applied values, usable as a cache key for font dependent measurements.
60
+ */
61
+ const copyTypography = (source, targets) => {
62
+ const computed = window.getComputedStyle(source);
63
+ return TYPOGRAPHY_PROPS.map(prop => {
64
+ const propValue = computed.getPropertyValue(prop);
65
+ targets.forEach(target => target.style.setProperty(prop, propValue));
66
+ return propValue;
67
+ }).join("|");
68
+ };
69
+ /**
70
+ * Advance width of a single space under the current font settings, used as the
71
+ * trailing buffer instead of a hardcoded pixel constant so that it scales with
72
+ * the font size while staying as narrow as the typography allows.
73
+ */
74
+ const getSpaceWidth = (probe, typographySignature) => {
75
+ const cacheKey = `${fontEpoch}|${typographySignature}`;
76
+ const cached = spaceWidthCache.get(cacheKey);
77
+ if (cached !== undefined)
78
+ return cached;
79
+ probe.textContent = SPACE_SAMPLE;
80
+ const withSpace = probe.getBoundingClientRect().width;
81
+ probe.textContent = NO_SPACE_SAMPLE;
82
+ const withoutSpace = probe.getBoundingClientRect().width;
83
+ probe.textContent = "";
84
+ const spaceWidth = Math.max(withSpace - withoutSpace, 0);
85
+ spaceWidthCache.set(cacheKey, spaceWidth);
86
+ return spaceWidth;
87
+ };
88
+ export const AutosizeInput = (_a) => {
89
+ var { placeholder, reserveWidth, inputRef, ref } = _a, props = __rest(_a, ["placeholder", "reserveWidth", "inputRef", "ref"]);
90
+ const [value, setValue] = useState(props.value || "");
91
+ const [width, setWidth] = useState(0);
92
+ const spanRef = useRef(null);
93
+ const probeRef = useRef(null);
94
+ const inputNode = useRef(null);
95
+ const setInputNode = useCallback((node) => {
96
+ inputNode.current = node;
97
+ [ref, inputRef].forEach(target => {
98
+ if (typeof target === "function")
99
+ target(node);
100
+ else if (target)
101
+ target.current = node;
102
+ });
103
+ }, [ref, inputRef]);
104
+ const measure = useCallback(() => {
105
+ const span = spanRef.current;
106
+ const probe = probeRef.current;
107
+ const input = inputNode.current;
108
+ if (!span || !probe || !input)
109
+ return;
110
+ // Measuring against the input's own computed typography keeps the two in
111
+ // sync even when the font is applied by a class rather than inherited
112
+ const typographySignature = copyTypography(input, [span, probe]);
113
+ // getBoundingClientRect keeps the sub pixel part that offsetWidth truncates
114
+ const textWidth = span.getBoundingClientRect().width;
115
+ const reserve = reserveWidth !== null && reserveWidth !== void 0 ? reserveWidth : getSpaceWidth(probe, typographySignature);
116
+ // Deliberately not rounded up: `Math.ceil` inflated the trailing gap by up
117
+ // to a full pixel, which is a fifth of a space at body font sizes. Layout is
118
+ // sub pixel accurate, so a fractional width keeps the gap exactly one space
119
+ setWidth(textWidth + reserve);
120
+ }, [reserveWidth]);
121
+ // Layout effect, so the width is correct in the same frame the value changes
122
+ useLayoutEffect(measure, [measure, value, placeholder]);
123
+ // Re-measure when the text changes size for reasons React cannot see: late
124
+ // loading webfonts, theme driven typography swaps, zoom, becoming visible
125
+ useEffect(() => {
126
+ if (typeof ResizeObserver === "undefined" || !spanRef.current)
127
+ return;
128
+ const observer = new ResizeObserver(measure);
129
+ observer.observe(spanRef.current);
130
+ return () => observer.disconnect();
131
+ }, [measure]);
132
+ // A webfont replacing the fallback face keeps the same computed values, so the
133
+ // cached glyph metrics have to be invalidated explicitly
134
+ useEffect(() => {
135
+ const fonts = document.fonts;
136
+ if (!fonts)
137
+ return;
138
+ const onLoadingDone = () => {
139
+ fontEpoch += 1;
140
+ measure();
141
+ };
142
+ fonts.addEventListener("loadingdone", onLoadingDone);
143
+ return () => fonts.removeEventListener("loadingdone", onLoadingDone);
144
+ }, [measure]);
145
+ const handleChange = (e) => {
146
+ setValue(e.target.value);
147
+ if (props.onChange)
148
+ props.onChange(e);
149
+ };
150
+ return (React.createElement("div", { style: { display: "inline-block", position: "relative" } },
151
+ React.createElement("span", { ref: spanRef, style: measureStyle, "aria-hidden": true }, value || placeholder || ""),
152
+ React.createElement("span", { ref: probeRef, style: measureStyle, "aria-hidden": true }),
153
+ React.createElement("input", Object.assign({}, props, { ref: setInputNode, type: "text", value: value, onChange: handleChange, placeholder: placeholder, style: Object.assign(Object.assign({}, props.style), { letterSpacing: "inherit", textTransform: "inherit", width: `${width}px`, boxSizing: "border-box",
154
+ // CRITICAL: Padding and borders must be 0, the measuring span has none either
155
+ paddingLeft: 0, paddingRight: 0, borderLeft: "none", borderRight: "none", margin: 0, textOverflow: "unset" }) }))));
156
+ };
@@ -3,6 +3,8 @@
3
3
  * */
4
4
  import React from 'react';
5
5
  import { CheckboxFieldProps, FieldInputProps } from '../model';
6
- import { CheckboxProps } from '@mui/material/Checkbox/Checkbox';
7
- export declare const StyledCheckbox: (props: any) => React.JSX.Element;
6
+ import { CheckboxProps } from '@mui/material';
7
+ declare const StyledCheckboxBase: (props: any) => React.JSX.Element;
8
+ export declare const StyledCheckbox: typeof StyledCheckboxBase;
8
9
  export declare function CheckboxField<IP extends FieldInputProps>({ input, color, disabled, stringValue, className, uncheckedClass, onChangeHandler, stopPropagation, ...rest }: CheckboxFieldProps<IP> & CheckboxProps): React.JSX.Element;
10
+ export {};
@@ -16,7 +16,7 @@ import { useStyles } from 'tss-react/mui';
16
16
  export function ColoredCheckBox({ input, label, color, className, disabled }) {
17
17
  const { cx } = useStyles();
18
18
  const theme = useAppTheme();
19
- const inputRef = useRef();
19
+ const inputRef = useRef(null);
20
20
  const onClick = useCallback(() => {
21
21
  inputRef.current.click();
22
22
  }, [inputRef.current]);
@@ -34,7 +34,10 @@ export function ColoredCheckBox({ input, label, color, className, disabled }) {
34
34
  backgroundColor: input.value ? `${color}` : alpha(`${color}`, 0.1),
35
35
  color: theme => theme.palette.getContrastText(`${color}`)
36
36
  } }, input.value && React.createElement(FontAwesomeIcon, { fixedWidth: true, icon: "check" })),
37
- label && React.createElement(Typography, { variant: "caption", fontWeight: "400", sx: {
37
+ label && React.createElement(Typography, { variant: "caption", sx: {
38
+ // MUI 9 no longer accepts system props such as `fontWeight`
39
+ // directly on Typography.
40
+ fontWeight: 400,
38
41
  marginLeft: 1,
39
42
  textDecoration: input.value ? 'line-through' : 'unset',
40
43
  color: theme => (input.value ? theme.palette.text.disabled : 'unset'),
@@ -163,44 +163,43 @@ function EditInPlaceDateTimeField({ type, formatDate, formatTime, formatDateTime
163
163
  [classes.inlineContainer]: inline,
164
164
  'pointer-events-none': disabled
165
165
  }) },
166
- React.createElement("div", { id: input.name, className: "w-100" },
167
- React.createElement(DateTimeField, { type: type, toolbarTitle: label, open: pickerOpened, value: dateValue, onChange: onChange, onClose: onClose, slots: {
168
- field: EditInPlaceFieldBase
169
- }, slotProps: {
170
- field: {
171
- name: input.name,
166
+ React.createElement("div", { id: input.name, className: "w-100" }, React.createElement(DateTimeField, { type: type, toolbarTitle: label, open: pickerOpened, value: dateValue, onChange: onChange, onClose: onClose, slots: {
167
+ field: EditInPlaceFieldBase
168
+ }, slotProps: {
169
+ field: {
170
+ name: input.name,
171
+ value: textValue,
172
+ variant,
173
+ error,
174
+ invalid,
175
+ inline,
176
+ label,
177
+ warning,
178
+ fieldClasses,
179
+ rightAligned,
180
+ disabled,
181
+ labelAdornment,
182
+ placeholder,
183
+ shrink: Boolean(label || input.value),
184
+ editIcon: React.createElement(IconButton, { tabIndex: -1, onClick: openPicker, sx: variant === 'outlined' ? {
185
+ marginRight: -1
186
+ } : null, classes: {
187
+ root: cx(fieldClasses.text, inline && classes.inlinePickerButton)
188
+ } }, type === 'time'
189
+ ? React.createElement(QueryBuilder, { fontSize: "inherit", color: "inherit" })
190
+ : React.createElement(DateRange, { color: "inherit", fontSize: "inherit" })),
191
+ InputProps: {
192
+ type: 'text',
193
+ onFocus: input.onFocus,
194
+ inputRef: inputNode,
172
195
  value: textValue,
173
- variant,
174
- error,
175
- invalid,
176
- inline,
177
- label,
178
- warning,
179
- fieldClasses,
180
- rightAligned,
196
+ onKeyPress,
181
197
  disabled,
182
- labelAdornment,
183
- placeholder,
184
- shrink: Boolean(label || input.value),
185
- editIcon: React.createElement(IconButton, { tabIndex: -1, onClick: openPicker, sx: variant === 'outlined' ? {
186
- marginRight: -1
187
- } : null, classes: {
188
- root: cx(fieldClasses.text, inline && classes.inlinePickerButton)
189
- } }, type === 'time'
190
- ? React.createElement(QueryBuilder, { fontSize: "inherit", color: "inherit" })
191
- : React.createElement(DateRange, { color: "inherit", fontSize: "inherit" })),
192
- InputProps: {
193
- type: 'text',
194
- onFocus: input.onFocus,
195
- inputRef: inputNode,
196
- value: textValue,
197
- onKeyPress,
198
- disabled,
199
- onBlur,
200
- onKeyDown: onEnterPress,
201
- onChange: onInputChange
202
- }
198
+ onBlur,
199
+ onKeyDown: onEnterPress,
200
+ onChange: onInputChange
203
201
  }
204
- } }))));
202
+ }
203
+ } }))));
205
204
  }
206
205
  export default EditInPlaceDateTimeField;
@@ -41,14 +41,13 @@ function EditInPlaceField({ inputRef, input, label, maxLength, disabled, min, ma
41
41
  return (React.createElement("div", { id: input.name, className: cx(className, 'outline-none', {
42
42
  [classes.rightAligned]: rightAligned,
43
43
  [classes.inlineContainer]: inline
44
- }) },
45
- React.createElement(EditInPlaceFieldBase, { name: input.name, value: inputValue, variant: variant, error: error, invalid: invalid, inline: inline, label: label, warning: warning, fieldClasses: fieldClasses, endAdornmentClass: classes.endAdornment, rightAligned: rightAligned, shrink: Boolean(label || input.value), disabled: disabled, labelAdornment: labelAdornment, placeholder: placeholder, hideArrows: ['percentage', 'number'].includes(type), editIcon: editIcon === undefined ? React.createElement(Edit, { fontSize: inline ? 'inherit' : undefined }) : editIcon, InputProps: Object.assign({ multiline,
46
- onKeyPress,
47
- onBlur, onFocus: input.onFocus, maxRows: truncateLines, inputProps: Object.assign({ ref: inputRef, maxLength,
48
- step,
49
- min,
50
- max,
51
- onKeyDown,
52
- type }, InputProps.inputProps || {}), value: inputValue, onChange: v => (type === 'number' && max && Number(v) > Number(max) ? null : input.onChange(v)) }, InputProps) })));
44
+ }) }, React.createElement(EditInPlaceFieldBase, { name: input.name, value: inputValue, variant: variant, error: error, invalid: invalid, inline: inline, label: label, warning: warning, fieldClasses: fieldClasses, endAdornmentClass: classes.endAdornment, rightAligned: rightAligned, shrink: Boolean(label || input.value), disabled: disabled, labelAdornment: labelAdornment, placeholder: placeholder, hideArrows: ['percentage', 'number'].includes(type), editIcon: editIcon === undefined ? React.createElement(Edit, { fontSize: inline ? 'inherit' : undefined }) : editIcon, InputProps: Object.assign({ multiline,
45
+ onKeyPress,
46
+ onBlur, onFocus: input.onFocus, maxRows: truncateLines, inputProps: Object.assign({ ref: inputRef, maxLength,
47
+ step,
48
+ min,
49
+ max,
50
+ onKeyDown,
51
+ type }, InputProps.inputProps || {}), value: inputValue, onChange: v => (type === 'number' && max && Number(v) > Number(max) ? null : input.onChange(v)) }, InputProps) })));
53
52
  }
54
53
  export default EditInPlaceField;