@onehat/ui 0.3.179 → 0.3.183

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onehat/ui",
3
- "version": "0.3.179",
3
+ "version": "0.3.183",
4
4
  "description": "Base UI for OneHat apps",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -6,7 +6,7 @@ import {
6
6
  Tooltip,
7
7
  } from 'native-base';
8
8
  import withComponent from '../Hoc/withComponent.js';
9
- import styles from '../../Constants/Styles.js';
9
+ import UiGlobals from '../../UiGlobals.js';
10
10
  import _ from 'lodash';
11
11
 
12
12
  const
@@ -19,7 +19,8 @@ const
19
19
  tooltip,
20
20
  tooltipPlacement = 'bottom',
21
21
  self,
22
- } = props;
22
+ } = props,
23
+ styles = UiGlobals.styles;
23
24
  let ref = props.outerRef;
24
25
 
25
26
  if (!ref) {
@@ -49,7 +50,8 @@ const
49
50
  flexDirection="row"
50
51
  justifyContent="center"
51
52
  alignItems="center"
52
- p={2}
53
+ px={styles.ICON_BUTTON_PX}
54
+ py={styles.ICON_BUTTON_PY}
53
55
  // bg={styles.ICON_BUTTON_BG}
54
56
  _hover={{
55
57
  bg: styles.ICON_BUTTON_BG_HOVER,
@@ -686,6 +686,7 @@ export function ComboComponent(props) {
686
686
  h={UiGlobals.mode === UI_MODE_WEB ? styles.FORM_COMBO_MENU_HEIGHT + 'px' : null}
687
687
  newEntityDisplayValue={newEntityDisplayValue}
688
688
  disablePresetButtons={!isEditor}
689
+ alternateRowBackgrounds={false}
689
690
  onChangeSelection={(selection) => {
690
691
 
691
692
  if (Repository && selection[0]?.isPhantom) {
@@ -931,7 +932,7 @@ export function ComboComponent(props) {
931
932
  // be responsive for small screen sizes and bump additionalButtons to the next line
932
933
  assembledComponents =
933
934
  <Column>
934
- <Row {...refProps} justifyContent="center" alignItems="center" flex={1}>
935
+ <Row {...refProps} justifyContent="center" alignItems="center" flex={1} h="100%">
935
936
  {xButton}
936
937
  {eyeButton}
937
938
  {inputAndTrigger}
@@ -943,7 +944,7 @@ export function ComboComponent(props) {
943
944
  </Column>;
944
945
  } else {
945
946
  assembledComponents =
946
- <Row {...refProps} justifyContent="center" alignItems="center" flex={1} onLayout={onLayout}>
947
+ <Row {...refProps} justifyContent="center" alignItems="center" flex={1} h="100%" onLayout={onLayout}>
947
948
  {xButton}
948
949
  {eyeButton}
949
950
  {inputAndTrigger}
@@ -994,7 +995,7 @@ export function ComboComponent(props) {
994
995
  }
995
996
 
996
997
  if (tooltip) {
997
- assembledComponents = <Tooltip label={tooltip} placement={tooltipPlacement}>
998
+ assembledComponents = <Tooltip label={tooltip} placement={tooltipPlacement} h="100%">
998
999
  {assembledComponents}
999
1000
  </Tooltip>;
1000
1001
  }
@@ -35,11 +35,9 @@ function NumberElement(props) {
35
35
  const key = e.nativeEvent.key; // e.key works on web, but not mobile; so use e.nativeEvent.key which works on both
36
36
  switch(key) {
37
37
  case 'ArrowDown':
38
- case 'ArrowLeft':
39
38
  onDecrement();
40
39
  break;
41
40
  case 'ArrowUp':
42
- case 'ArrowRight':
43
41
  onIncrement();
44
42
  break;
45
43
  case 'Tab':
@@ -13,6 +13,7 @@ import withData from '../../../Hoc/withData.js';
13
13
  import withValue from '../../../Hoc/withValue.js';
14
14
  import ValueBox from './ValueBox.js';
15
15
  import Combo, { ComboEditor } from '../Combo/Combo.js';
16
+ import UiGlobals from '../../../../UiGlobals.js';
16
17
  import _ from 'lodash';
17
18
 
18
19
 
@@ -41,6 +42,7 @@ function TagComponent(props) {
41
42
  setValue,
42
43
  ...propsToPass // break connection between Tag and Combo props
43
44
  } = props,
45
+ styles = UiGlobals.styles,
44
46
  valueRef = useRef(value),
45
47
  ignoreNextComboValueChangeRef = useRef(false),
46
48
  [isViewerShown, setIsViewerShown] = useState(false),
@@ -247,9 +249,9 @@ function TagComponent(props) {
247
249
  borderColor="trueGray.300"
248
250
  borderRadius="md"
249
251
  bg="trueGray.100"
250
- p={1}
251
- mb={1}
252
- minHeight={10}
252
+ p={styles.FORM_TAG_PADDING}
253
+ mb={styles.FORM_TAG_MB}
254
+ minHeight={styles.FORM_TAG_MIN_HEIGHT}
253
255
  flexWrap="wrap"
254
256
  >{valueBoxes}</Row>
255
257
  {!isViewOnly && <WhichCombo
@@ -5,6 +5,7 @@ import {
5
5
  import IconButton from '../../../Buttons/IconButton.js';
6
6
  import Eye from '../../../Icons/Eye.js';
7
7
  import Xmark from '../../../Icons/Xmark.js';
8
+ import UiGlobals from '../../../../UiGlobals.js';
8
9
  import _ from 'lodash';
9
10
 
10
11
  export default function ValueBox(props) {
@@ -12,7 +13,8 @@ export default function ValueBox(props) {
12
13
  text,
13
14
  onView,
14
15
  onDelete,
15
- } = props;
16
+ } = props,
17
+ styles = UiGlobals.styles;
16
18
  return <Row
17
19
  borderWidth={1}
18
20
  borderColor="trueGray.400"
@@ -25,18 +27,22 @@ export default function ValueBox(props) {
25
27
  _icon={{
26
28
  as: Eye,
27
29
  color: 'trueGray.600',
28
- size: 'sm',
30
+ size: styles.FORM_TAG_VALUEBOX_ICON_SIZE,
29
31
  }}
30
32
  onPress={onView}
31
33
  h="100%"
32
34
  />
33
- <Text color="trueGray.600" mr={onDelete ? 0 : 2}>{text}</Text>
35
+ <Text
36
+ color="trueGray.600"
37
+ mr={onDelete ? 0 : 2}
38
+ fontSize={styles.FORM_TAG_VALUEBOX_FONTSIZE}
39
+ >{text}</Text>
34
40
  {onDelete &&
35
41
  <IconButton
36
42
  _icon={{
37
43
  as: Xmark,
38
44
  color: 'trueGray.600',
39
- size: 'sm',
45
+ size: styles.FORM_TAG_VALUEBOX_ICON_SIZE,
40
46
  }}
41
47
  onPress={onDelete}
42
48
  h="100%"
@@ -121,6 +121,8 @@ function GridComponent(props) {
121
121
  flex,
122
122
  bg = '#fff',
123
123
  verifyCanEdit,
124
+ alternateRowBackgrounds = true,
125
+ alternatingInterval = 2,
124
126
 
125
127
  // withComponent
126
128
  self,
@@ -409,6 +411,8 @@ function GridComponent(props) {
409
411
  }
410
412
  } else if (showHovers && isHovered) {
411
413
  mixWith = styles.GRID_ROW_HOVER_BG;
414
+ } else if (alternateRowBackgrounds && index % alternatingInterval === 0) { // i.e. every second line, or every third line
415
+ mixWith = styles.GRID_ROW_ALTERNATE_BG;
412
416
  }
413
417
  if (mixWith) {
414
418
  const
@@ -396,7 +396,16 @@ export default function GridHeaderRow(props) {
396
396
  {...textProps}
397
397
  >{header}</Text>
398
398
 
399
- {isSorter && <Icon key="Icon" as={isSortDirectionAsc ? SortUp : SortDown} textAlign="center" size="sm" mt={3} mr={2} color="trueGray.500" />}
399
+ {isSorter &&
400
+ <Icon
401
+ key="Icon"
402
+ as={isSortDirectionAsc ? SortUp : SortDown}
403
+ textAlign="center"
404
+ size={styles.GRID_HEADER_ICON_SIZE}
405
+ mt={styles.GRID_HEADER_ICON_MT}
406
+ mr={styles.GRID_HEADER_ICON_MR}
407
+ color="trueGray.500"
408
+ />}
400
409
 
401
410
  {isResizable && showDragHandles &&
402
411
  <HeaderResizeHandle
@@ -138,7 +138,15 @@ export default function withSecondaryEditor(WrappedComponent, isTree = false) {
138
138
  } else {
139
139
  // Set repository to sort by id DESC and switch to page 1, so this new entity is guaranteed to show up on the current page, even after saving
140
140
  const currentSorter = SecondaryRepository.sorters[0];
141
- if (currentSorter.name !== SecondaryRepository.schema.model.idProperty || currentSorter.direction !== 'DESC') {
141
+ if (currentSorter.name.match(/__sort_order$/)) { // when it's using a sort column, keep using it
142
+ if (currentSorter.direction !== 'DESC') {
143
+ SecondaryRepository.pauseEvents();
144
+ SecondaryRepository.sort(currentSorter.name, 'DESC');
145
+ SecondaryRepository.setPage(1);
146
+ SecondaryRepository.resumeEvents();
147
+ await SecondaryRepository.reload();
148
+ }
149
+ } else if (currentSorter.name !== SecondaryRepository.schema.model.idProperty || currentSorter.direction !== 'DESC') {
142
150
  SecondaryRepository.pauseEvents();
143
151
  SecondaryRepository.sort(SecondaryRepository.schema.model.idProperty, 'DESC');
144
152
  SecondaryRepository.setPage(1);
@@ -135,7 +135,15 @@ export default function withEditor(WrappedComponent, isTree = false) {
135
135
  } else {
136
136
  // Set repository to sort by id DESC and switch to page 1, so this new entity is guaranteed to show up on the current page, even after saving
137
137
  const currentSorter = Repository.sorters[0];
138
- if (currentSorter.name !== Repository.schema.model.idProperty || currentSorter.direction !== 'DESC') {
138
+ if (currentSorter.name.match(/__sort_order$/)) { // when it's using a sort column, keep using it
139
+ if (currentSorter.direction !== 'DESC') {
140
+ Repository.pauseEvents();
141
+ Repository.sort(currentSorter.name, 'DESC');
142
+ Repository.setPage(1);
143
+ Repository.resumeEvents();
144
+ await Repository.reload();
145
+ }
146
+ } else if (currentSorter.name !== Repository.schema.model.idProperty || currentSorter.direction !== 'DESC') {
139
147
  Repository.pauseEvents();
140
148
  Repository.sort(Repository.schema.model.idProperty, 'DESC');
141
149
  Repository.setPage(1);
@@ -313,7 +313,7 @@ export default function withFilters(WrappedComponent) {
313
313
  {...elementProps}
314
314
  />;
315
315
  if (showLabels && field !== 'q') {
316
- filterElement = <Row key={'label-' + ix} alignItems="center">
316
+ filterElement = <Row key={'label-' + ix} alignItems="center" h="100%">
317
317
  <Text ml={2} mr={1} fontSize={UiGlobals.styles.FILTER_LABEL_FONTSIZE}>{title}</Text>
318
318
  {filterElement}
319
319
  </Row>;
@@ -1,15 +1,18 @@
1
1
  import {
2
2
  Row,
3
3
  } from 'native-base';
4
+ import UiGlobals from '../../UiGlobals.js';
4
5
 
5
6
  export default function Toolbar(props) {
7
+ const styles = UiGlobals.styles;
6
8
  return <Row
7
9
  w="100%"
8
10
  justifyContent="flex-start"
9
11
  bg="trueGray.200"
10
12
  borderBottomWidth={1}
11
13
  borderBottomColor="trueGray.400"
12
- p={2}
14
+ px={styles.TOOLBAR_PX}
15
+ py={styles.TOOLBAR_PY}
13
16
  overflow="auto"
14
17
  {...props}
15
18
  >
@@ -42,6 +42,11 @@ const defaults = {
42
42
  FORM_LABEL_WIDTH: '30%',
43
43
  FORM_LABEL_FONTSIZE: DEFAULT_FONTSIZE,
44
44
  FORM_NUMBER_FONTSIZE: DEFAULT_FONTSIZE,
45
+ FORM_TAG_MB: 1,
46
+ FORM_TAG_MIN_HEIGHT: 10,
47
+ FORM_TAG_PADDING: 1,
48
+ FORM_TAG_VALUEBOX_FONTSIZE: DEFAULT_FONTSIZE,
49
+ FORM_TAG_VALUEBOX_ICON_SIZE: 'sm',
45
50
  FORM_TEXT_FONTSIZE: DEFAULT_FONTSIZE,
46
51
  FORM_TEXTAREA_BG: WHITE,
47
52
  FORM_TEXTAREA_FONTSIZE: DEFAULT_FONTSIZE,
@@ -59,11 +64,15 @@ const defaults = {
59
64
  GRID_HEADER_FONTSIZE: DEFAULT_FONTSIZE,
60
65
  GRID_HEADER_CELL_PX: 2,
61
66
  GRID_HEADER_CELL_PY: 3,
67
+ GRID_HEADER_ICON_MT: 3,
68
+ GRID_HEADER_ICON_MR: 2,
69
+ GRID_HEADER_ICON_SIZE: 'sm',
62
70
  GRID_INLINE_EDITOR_BORDER_COLOR: 'primary.100',
63
71
  GRID_NAV_COLUMN_COLOR: '#aaa',
64
72
  GRID_CELL_PX: 2,
65
73
  GRID_CELL_PY: 3,
66
74
  GRID_ROW_BG: WHITE,
75
+ GRID_ROW_ALTERNATE_BG: '#e5e5e5',
67
76
  GRID_ROW_HOVER_BG: 'hover',
68
77
  GRID_ROW_SELECTED_BG: 'selected',
69
78
  GRID_ROW_SELECTED_HOVER_BG: 'selectedHover',
@@ -73,6 +82,8 @@ const defaults = {
73
82
  ICON_BUTTON_BG_DISABLED: 'trueGray.200',
74
83
  ICON_BUTTON_BG_HOVER: '#000:alpha.20',
75
84
  ICON_BUTTON_BG_PRESSED: '#000:alpha.30',
85
+ ICON_BUTTON_PX: 2,
86
+ ICON_BUTTON_PY: 2,
76
87
  INLINE_EDITOR_MIN_WIDTH: 150,
77
88
  PANEL_FOOTER_BG: 'primary.100', // :alpha.50
78
89
  PANEL_HEADER_BG: 'primary.100',
@@ -108,6 +119,8 @@ const defaults = {
108
119
  TOOLBAR_ITEMS_COLOR: 'trueGray.800',
109
120
  TOOLBAR_ITEMS_DISABLED_COLOR: 'trueGray.400',
110
121
  TOOLBAR_ITEMS_ICON_SIZE: 'sm',
122
+ TOOLBAR_PX: 2,
123
+ TOOLBAR_PY: 2,
111
124
  VIEWER_ANCILLARY_FONTSIZE: 22,
112
125
  };
113
126