@xqmsg/ui-core 0.24.11 → 0.25.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.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.24.11",
2
+ "version": "0.25.0",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -3,6 +3,7 @@ import {
3
3
  ReadonlyTableColumns,
4
4
  TableBody,
5
5
  TableColumns,
6
+ TableColumnsWidths,
6
7
  TableHeaders,
7
8
  } from './TableTypes';
8
9
  import { generateTableColumnsAsConst } from './utils/generateTableColumns';
@@ -27,6 +28,8 @@ export interface SimpleTableProps<T extends ReadonlyTableColumns> {
27
28
  loading?: boolean;
28
29
  loadMore?: () => void;
29
30
  placeholder?: string;
31
+ layout?: 'fixed' | 'auto';
32
+ columnsWidths?: TableColumnsWidths<T>;
30
33
  }
31
34
 
32
35
  /**
@@ -38,6 +41,8 @@ export function SimpleTable<T extends ReadonlyTableColumns>({
38
41
  body,
39
42
  loading,
40
43
  loadMore,
44
+ layout = 'auto',
45
+ columnsWidths,
41
46
  }: SimpleTableProps<T>) {
42
47
  const columnsAsConst = generateTableColumnsAsConst(columns);
43
48
 
@@ -50,14 +55,16 @@ export function SimpleTable<T extends ReadonlyTableColumns>({
50
55
  style={{
51
56
  borderCollapse: 'separate',
52
57
  borderSpacing: '0px',
58
+ tableLayout: layout,
53
59
  }}
54
60
  >
55
- {headers && (
61
+ {(headers || columnsWidths) && (
56
62
  <Thead>
57
63
  <Tr _odd={{ bg: colors.label.primary.dark }}>
58
64
  {columnsAsConst.map((column, idx) => (
59
- // @ts-ignore
60
- <Th key={idx}>{headers[column]}</Th>
65
+ <Th key={idx} width={columnsWidths?.[column as T[number]]}>
66
+ {headers && headers[column as T[number]]}
67
+ </Th>
61
68
  ))}
62
69
  </Tr>
63
70
  </Thead>
@@ -8,6 +8,10 @@ export type TableHeaders<K extends ReadonlyTableColumns> = {
8
8
  [k in K[number]]: ReactNode;
9
9
  };
10
10
 
11
+ export type TableColumnsWidths<K extends ReadonlyTableColumns> = {
12
+ [k in K[number]]: string | number;
13
+ };
14
+
11
15
  export type TableRow<K extends ReadonlyTableColumns> = {
12
16
  [k in K[number]]: ReactNode;
13
17
  };
@@ -14,6 +14,7 @@ export const Close: React.FC<CloseProps> = ({ boxSize, onClick }) => {
14
14
  <CloseIcon
15
15
  width={boxSize}
16
16
  height={boxSize}
17
+ flexBasis={boxSize}
17
18
  onClick={onClick}
18
19
  cursor="pointer"
19
20
  />
@@ -112,6 +112,21 @@ const Template: Story<InputProps<StoryFormSchema>> = args => {
112
112
 
113
113
  return (
114
114
  <Form formHandler={formHandler}>
115
+ <Input
116
+ label="To"
117
+ name="recipients"
118
+ inputType="pilled-text"
119
+ placeholder="Enter email address..."
120
+ isInvalid={!!form.formState.errors['prop5']?.message}
121
+ errorText={form.formState.errors['prop5']?.message}
122
+ control={form.control}
123
+ setValue={form.setValue}
124
+ setError={form.setError}
125
+ clearErrors={form.clearErrors}
126
+ ariaLabel="email input"
127
+ isRequired
128
+ truncatePillLength={1000}
129
+ />
115
130
  <Input
116
131
  {...args}
117
132
  inputType="multi-select"
@@ -21,6 +21,7 @@ export interface StackedPilledInputProps extends InputFieldProps {
21
21
  variant?: string;
22
22
  label?: string;
23
23
  truncatePillLength?: number;
24
+ mode?: 'scroll' | 'wrap';
24
25
  }
25
26
 
26
27
  /**
@@ -41,6 +42,7 @@ const StackedPilledInput = React.forwardRef<
41
42
  variant,
42
43
  label,
43
44
  truncatePillLength,
45
+ mode = 'scroll',
44
46
  },
45
47
  _ref
46
48
  ) => {
@@ -60,7 +62,7 @@ const StackedPilledInput = React.forwardRef<
60
62
  const latestTokenElement = document.getElementById(
61
63
  `${name}_token_${lastestFormValueToArray.length - 1}`
62
64
  );
63
-
65
+ const scrollMode = mode === 'scroll';
64
66
  // gets latest watched form value (common delimited) from RHF state and creates a list
65
67
  useEffect(() => {
66
68
  if (watchedValue !== undefined && !watchedValue.length) {
@@ -290,12 +292,14 @@ const StackedPilledInput = React.forwardRef<
290
292
  bg={disabled ? colors.fill.light.quaternary : '#ffffff'}
291
293
  cursor={disabled ? 'not-allowed' : 'pointer'}
292
294
  ref={inputWrapperRef}
293
- h={isMobile ? '48px' : '26px'}
295
+ h={isMobile ? '48px' : scrollMode ? '26px' : 'auto'}
296
+ minH={isMobile ? '48px' : '26px'}
294
297
  >
295
298
  <Flex
296
299
  h="100%"
297
300
  alignItems="center"
298
- overflowX="scroll"
301
+ overflowX={scrollMode ? 'scroll' : 'hidden'}
302
+ flexWrap={scrollMode ? 'nowrap' : 'wrap'}
299
303
  overflowY="hidden"
300
304
  maxWidth={isFocussed ? '80%' : '100%'}
301
305
  style={{
@@ -323,11 +327,14 @@ const StackedPilledInput = React.forwardRef<
323
327
  }
324
328
  borderRadius="full"
325
329
  onClick={() => setTokenIndex(index)}
326
- width="100%"
330
+ width={scrollMode ? '100%' : 'auto'}
331
+ maxWidth={'100%'}
327
332
  id={`${name}_token_${index}`}
328
333
  >
329
334
  <Token
335
+ maxWidth={'100%'}
330
336
  label={label}
337
+ showClose={!isFocussed || tokenIndex === index}
331
338
  onDelete={(e: any) => {
332
339
  e.stopPropagation();
333
340
  e.preventDefault();
@@ -9,6 +9,8 @@ export interface TokenProps {
9
9
  onDelete: any;
10
10
  isMobile?: boolean;
11
11
  truncateLength?: number;
12
+ showClose?: boolean;
13
+ maxWidth?: string | number;
12
14
  }
13
15
 
14
16
  // For v1 we are truncating the label at 15 characters to avoid overflow
@@ -17,6 +19,8 @@ const Token: React.FC<TokenProps> = ({
17
19
  onDelete,
18
20
  isMobile = false,
19
21
  truncateLength = 15,
22
+ showClose = true,
23
+ maxWidth = 'auto',
20
24
  }) => {
21
25
  return (
22
26
  <Flex
@@ -26,6 +30,7 @@ const Token: React.FC<TokenProps> = ({
26
30
  alignItems="center"
27
31
  width="fit-content"
28
32
  w="auto"
33
+ maxWidth={maxWidth}
29
34
  h={isMobile ? '18px' : '16px'}
30
35
  pl="6px"
31
36
  pr="2px"
@@ -34,16 +39,22 @@ const Token: React.FC<TokenProps> = ({
34
39
  >
35
40
  <Text
36
41
  whiteSpace="nowrap"
42
+ wordBreak="break-word"
37
43
  color={colors.label.primary.light}
38
44
  fontSize={isMobile ? '17px' : '13px'}
39
45
  pr="4px"
46
+ maxWidth={maxWidth}
47
+ overflow="hidden"
48
+ textOverflow="ellipsis"
40
49
  >
41
50
  {truncate(label.trim(), {
42
51
  length: truncateLength,
43
52
  omission: '...',
44
53
  })}
45
54
  </Text>
46
- <Close boxSize={isMobile ? '17px' : '11px'} onClick={onDelete} />
55
+ {showClose && (
56
+ <Close boxSize={isMobile ? '17px' : '11px'} onClick={onDelete} />
57
+ )}
47
58
  </Flex>
48
59
  );
49
60
  };
@@ -53,6 +53,7 @@ export interface InputProps<T extends FieldValues = FieldValues>
53
53
  loadingOptions?: boolean;
54
54
  truncatePillLength?: number;
55
55
  searchable?: boolean;
56
+ overflowMode?: 'scroll' | 'wrap';
56
57
  }
57
58
 
58
59
  /**
@@ -88,6 +89,7 @@ export function Input<T extends FieldValues>({
88
89
  loadingOptions = false,
89
90
  truncatePillLength,
90
91
  searchable,
92
+ overflowMode = 'scroll',
91
93
  }: InputProps<T>) {
92
94
  function selectedInputField<T extends Element = Element>(
93
95
  onChange: ((e: ChangeEvent<T>) => void) | ((v?: string) => void),
@@ -238,6 +240,7 @@ export function Input<T extends FieldValues>({
238
240
  label={label}
239
241
  separators={separators}
240
242
  truncatePillLength={truncatePillLength}
243
+ mode={overflowMode}
241
244
  />
242
245
  );
243
246
  case 'switch':