ish-ui 1.3.5 → 1.3.7

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.
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright ish group pty ltd 2023.
2
+ * Copyright ish group pty ltd 2026.
3
3
  *
4
4
  * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
5
  *
@@ -23,13 +23,17 @@ import React, { useCallback, useContext, useEffect, useMemo, useRef, useState }
23
23
  import CloseIcon from '@mui/icons-material/Close';
24
24
  import ExpandMore from '@mui/icons-material/ExpandMore';
25
25
  import { ListboxComponent, useSelectStyles } from './SelectCustomComponents';
26
- import EditInPlaceFieldBase from './EditInPlaceFieldBase';
26
+ import EditInPlaceFieldBase from '../formFields/EditInPlaceFieldBase';
27
27
  import { makeAppStyles } from '../styles';
28
- import { getHighlightedPartLabel, stubComponent } from '../utils';
29
- import { usePrevious } from '../utils/hooks';
28
+ import { getHighlightedPartLabel, stubComponent, usePrevious } from '../utils';
30
29
  const useStyles = makeAppStyles()({
31
30
  popper: {
32
31
  zIndex: 1400
32
+ },
33
+ customSelectAdornment: {
34
+ "&&": {
35
+ right: 0
36
+ }
33
37
  }
34
38
  });
35
39
  const SelectContext = React.createContext({});
@@ -52,6 +56,7 @@ function EditInPlaceSearchSelect({ label, disabled, className, labelAdornment, i
52
56
  const { classes: ownClasses, cx } = useStyles();
53
57
  const { classes: selectClasses } = useSelectStyles();
54
58
  const classes = Object.assign(Object.assign({}, selectClasses), ownClasses);
59
+ const hasCustomListbox = !(categoryKey || inline);
55
60
  const sortedItems = useMemo(() => {
56
61
  const sorted = items && (sort
57
62
  ? [...items].sort(typeof sort === 'function'
@@ -216,13 +221,16 @@ function EditInPlaceSearchSelect({ label, disabled, className, labelAdornment, i
216
221
  return option[selectValueMark] === value;
217
222
  };
218
223
  const renderOption = (optionProps, data) => {
219
- if (typeof itemRenderer === 'function') {
220
- return [itemRenderer(getHighlightedPartLabel(getOptionLabel(data), searchValue), data, searchValue, optionProps), optionProps];
224
+ const optionLabel = getOptionLabel(data);
225
+ const hasItemRenderrer = typeof itemRenderer === 'function';
226
+ const highlightedPart = getHighlightedPartLabel(optionLabel, searchValue, hasCustomListbox || hasItemRenderrer ? undefined : optionProps);
227
+ if (!hasCustomListbox) {
228
+ return hasItemRenderrer ? itemRenderer(highlightedPart, data, searchValue, optionProps) : highlightedPart;
221
229
  }
222
- if (inline || categoryKey) {
223
- return getHighlightedPartLabel(getOptionLabel(data), searchValue, optionProps);
230
+ if (hasItemRenderrer) {
231
+ return [itemRenderer(highlightedPart, data, searchValue, optionProps), optionProps];
224
232
  }
225
- return [getHighlightedPartLabel(getOptionLabel(data), searchValue), optionProps];
233
+ return [highlightedPart, optionProps];
226
234
  };
227
235
  const selectedOption = useMemo(() => sortedItems.find(i => multiple
228
236
  ? (input.value || []).includes(i[selectValueMark])
@@ -266,13 +274,12 @@ function EditInPlaceSearchSelect({ label, disabled, className, labelAdornment, i
266
274
  ? valueRenderer(displayedValue, valueForRender, searchValue, { value: valueForRender && valueForRender[selectValueMark] })
267
275
  : null;
268
276
  }, [selectedOption, searchValue, displayedValue, selectValueMark, returnType, valueRenderer, input.value]);
269
- const renderIcons = useMemo(() => !disabled && (loading
270
- ? React.createElement(CircularProgress, { size: 24, thickness: 4, className: fieldClasses.loading })
271
- : (React.createElement("div", null,
272
- allowEmpty && input.value && (React.createElement(IconButton, { size: "small", onClick: onClear, color: "inherit" },
273
- React.createElement(CloseIcon, { fontSize: "inherit" }))),
274
- editIcon === undefined ? React.createElement(IconButton, { size: "small", color: "inherit", className: cx(classes.expandIcon, 'pl-0 pr-0', inline && 'p-0'), disableRipple: true },
275
- React.createElement(ExpandMore, { className: inline && 'fsInherit' })) : editIcon))), [disabled, loading, inline, allowEmpty, input.value]);
277
+ const renderLoading = useMemo(() => React.createElement(CircularProgress, Object.assign({}, inline ? { sx: { padding: 0.5 } } : {}, { size: 24, thickness: 4, className: fieldClasses.loading })), [fieldClasses.loading, inline]);
278
+ const renderIcons = useMemo(() => !disabled && (React.createElement("div", null,
279
+ allowEmpty && input.value && (React.createElement(IconButton, { size: "small", onClick: onClear, color: "inherit" },
280
+ React.createElement(CloseIcon, { fontSize: "inherit" }))),
281
+ editIcon === undefined ? React.createElement(IconButton, { size: "small", color: "inherit", className: cx(classes.expandIcon, 'pl-0 pr-0', inline && 'p-0'), disableRipple: true },
282
+ React.createElement(ExpandMore, { className: inline && 'fsInherit' })) : editIcon)), [disabled, inline, allowEmpty, input.value]);
276
283
  const inputValue = useMemo(() => {
277
284
  if (multiple) {
278
285
  return (input.value || []).map(v => sortedItems.find(s => s[selectValueMark] === v));
@@ -285,7 +292,7 @@ function EditInPlaceSearchSelect({ label, disabled, className, labelAdornment, i
285
292
  const renderInput = useCallback((_a) => {
286
293
  var { slotProps: { input: InputProps, htmlInput: inputProps } } = _a, params = __rest(_a, ["slotProps"]);
287
294
  const value = (isEditing ? searchValue : (typeof displayedValue === 'string' ? displayedValue : ''));
288
- return (React.createElement(EditInPlaceFieldBase, Object.assign({}, params, { variant: variant, key: input.name, name: input.name, value: value, error: error, invalid: hasError || invalid, inline: inline, label: label, warning: warning, fieldClasses: fieldClasses, rightAligned: rightAligned, shrink: Boolean(label || input.value), labelAdornment: labelAdornment, placeholder: renderedPlaceholder, editIcon: !hideEditIcon && renderIcons, InputProps: Object.assign(Object.assign({}, InputProps), { endAdornment: null, onChange: handleInputChange, onFocus: edit, onClick: onEditButtonFocus, onBlur,
295
+ return (React.createElement(EditInPlaceFieldBase, Object.assign({}, params, { variant: variant, key: input.name, name: input.name, value: value, error: error, invalid: hasError || invalid, inline: inline, label: label, warning: warning, fieldClasses: fieldClasses, rightAligned: rightAligned, shrink: Boolean(label || input.value), labelAdornment: labelAdornment, placeholder: renderedPlaceholder, editIcon: loading ? renderLoading : (!hideEditIcon && renderIcons), InputProps: Object.assign(Object.assign({}, InputProps), { endAdornment: null, onChange: handleInputChange, onFocus: edit, onClick: onEditButtonFocus, onBlur,
289
296
  disableUnderline, classes: {
290
297
  underline: fieldClasses.underline,
291
298
  input: cx(disabled && classes.readonly, fieldClasses.text),
@@ -299,8 +306,10 @@ function EditInPlaceSearchSelect({ label, disabled, className, labelAdornment, i
299
306
  React.createElement(Select, Object.assign({}, InputProps, { inputRef: ref => {
300
307
  inputProps.ref.current = ref === null || ref === void 0 ? void 0 : ref.node;
301
308
  }, classes: {
302
- select: cx('cursor-text', fieldClasses.text)
303
- }, onFocus: edit, value: (returnType === 'object' ? input.value[selectValueMark] : input.value) || '', endAdornment: React.createElement(InputAdornment, { position: "end", className: 'd-none' }, renderIcons), IconComponent: stubComponent }), renderValue)
309
+ select: cx('cursor-text', fieldClasses.text),
310
+ }, onFocus: edit, value: (returnType === 'object' ? input.value[selectValueMark] : input.value) || '', endAdornment: loading ? renderLoading : React.createElement(InputAdornment, { position: "end", className: 'd-none', classes: {
311
+ root: ownClasses.customSelectAdornment
312
+ } }, renderIcons), IconComponent: stubComponent }), renderValue)
304
313
  : null })));
305
314
  }, [
306
315
  variant,
@@ -354,7 +363,7 @@ function EditInPlaceSearchSelect({ label, disabled, className, labelAdornment, i
354
363
  popper: classes.popper,
355
364
  groupUl: 'm-0'
356
365
  }, groupBy: categoryKey && (option => option[categoryKey]), renderOption: renderOption, getOptionLabel: getOptionLabel, filterOptions: filterItems, slots: {
357
- listbox: inline || categoryKey ? undefined : ListBoxAdapter,
366
+ listbox: hasCustomListbox ? ListBoxAdapter : undefined,
358
367
  popper: categoryKey ? undefined : PopperAdapter,
359
368
  }, renderInput: renderInput, disableListWrap: true, openOnFocus: true, fullWidth: true }))));
360
369
  }
@@ -11,12 +11,12 @@ export declare const useSelectStyles: (params: void, muiStyleOverridesParams?: {
11
11
  };
12
12
  interface ListRowProps {
13
13
  data: {
14
- children: [
14
+ children: Array<[
15
15
  [
16
16
  React.ReactNode
17
17
  ],
18
18
  React.HTMLAttributes<HTMLLIElement>
19
- ];
19
+ ]>;
20
20
  selectAdornment: EditInPlaceSearchSelectFieldProps<any, any>['selectAdornment'];
21
21
  };
22
22
  index: number;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright ish group pty ltd 2023.
2
+ * Copyright ish group pty ltd 2026.
3
3
  *
4
4
  * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
5
  *
@@ -34,8 +34,8 @@ import { List } from 'react-window';
34
34
  import { green } from '@mui/material/colors';
35
35
  import { ListItemButton } from '@mui/material';
36
36
  import Tooltip from '@mui/material/Tooltip';
37
- import { makeAppStyles } from '../styles';
38
37
  import { useStyles } from 'tss-react/mui';
38
+ import { makeAppStyles } from '../styles';
39
39
  export const useSelectStyles = makeAppStyles()((theme, p, classes) => ({
40
40
  bottomMargin: {
41
41
  marginBottom: `${theme.spacing(1) + 1}`
@@ -132,10 +132,15 @@ export const useSelectStyles = makeAppStyles()((theme, p, classes) => ({
132
132
  }
133
133
  },
134
134
  }));
135
- export const ListRow = React.memo(({ data: { children, selectAdornment }, index, style }) => React.createElement(ListItemButton, Object.assign({}, children[index][1], { selected: children[index][1]['aria-selected'], style: style, key: index }), (((selectAdornment === null || selectAdornment === void 0 ? void 0 : selectAdornment.position) === 'start' && index === 0)
136
- || ((selectAdornment === null || selectAdornment === void 0 ? void 0 : selectAdornment.position) === 'end' && index === children.length))
137
- ? selectAdornment.content
138
- : children[index][0]));
135
+ export const ListRow = React.memo(({ data: { children, selectAdornment }, index, style }) => {
136
+ if (!children[index])
137
+ return null;
138
+ const [content, props] = children[index];
139
+ return React.createElement(ListItemButton, Object.assign({ component: 'li' }, props, { selected: Boolean(props['aria-selected']), style: style, key: index }), (((selectAdornment === null || selectAdornment === void 0 ? void 0 : selectAdornment.position) === 'start' && index === 0)
140
+ || ((selectAdornment === null || selectAdornment === void 0 ? void 0 : selectAdornment.position) === 'end' && index === children.length))
141
+ ? selectAdornment.content
142
+ : content);
143
+ });
139
144
  export const ListboxComponent = React.forwardRef((props, ref) => {
140
145
  const { children, rowHeight, remoteRowCount, loadMoreRows, classes, loading, selectAdornment, fieldClasses, ownerState } = props, other = __rest(props, ["children", "rowHeight", "remoteRowCount", "loadMoreRows", "classes", "loading", "selectAdornment", "fieldClasses", "ownerState"]);
141
146
  const { cx } = useStyles();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ish-ui",
3
3
  "sideEffects": false,
4
- "version": "1.3.5",
4
+ "version": "1.3.7",
5
5
  "description": "UI elements for onCourse and other ish apps",
6
6
  "main": "main.ts",
7
7
  "devDependencies": {