@xqmsg/ui-core 0.22.4 → 0.23.1-rc.1

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 (40) hide show
  1. package/dist/components/form/FormTypes.d.ts +2 -0
  2. package/dist/components/input/StackedCheckbox/StackedCheckbox.d.ts +3 -2
  3. package/dist/components/input/StackedInput/StackedInput.d.ts +2 -0
  4. package/dist/components/input/StackedPilledInput/index.d.ts +3 -0
  5. package/dist/components/input/StackedTextarea/StackedTextarea.d.ts +4 -0
  6. package/dist/components/input/components/token/index.d.ts +1 -0
  7. package/dist/components/input/index.d.ts +3 -2
  8. package/dist/components/select/index.d.ts +27 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/theme/components/button.d.ts +113 -0
  11. package/dist/theme/components/checkbox.d.ts +29 -0
  12. package/dist/theme/components/input.d.ts +23 -0
  13. package/dist/theme/components/select.d.ts +23 -0
  14. package/dist/theme/components/textarea.d.ts +78 -0
  15. package/dist/ui-core.cjs.development.js +336 -54
  16. package/dist/ui-core.cjs.development.js.map +1 -1
  17. package/dist/ui-core.cjs.production.min.js +1 -1
  18. package/dist/ui-core.cjs.production.min.js.map +1 -1
  19. package/dist/ui-core.esm.js +338 -57
  20. package/dist/ui-core.esm.js.map +1 -1
  21. package/package.json +1 -1
  22. package/src/components/button/Button.stories.tsx +92 -27
  23. package/src/components/form/FormTypes.ts +2 -0
  24. package/src/components/form/section/index.tsx +2 -0
  25. package/src/components/input/Input.stories.tsx +67 -0
  26. package/src/components/input/StackedCheckbox/StackedCheckbox.tsx +12 -4
  27. package/src/components/input/StackedInput/StackedInput.tsx +11 -1
  28. package/src/components/input/StackedPilledInput/index.tsx +310 -266
  29. package/src/components/input/StackedTextarea/StackedTextarea.tsx +30 -4
  30. package/src/components/input/components/dropdown/index.tsx +1 -1
  31. package/src/components/input/components/token/index.tsx +6 -5
  32. package/src/components/input/index.tsx +25 -9
  33. package/src/components/select/index.tsx +140 -0
  34. package/src/components/tabs/TabsWrapper.stories.tsx +1 -1
  35. package/src/index.tsx +3 -0
  36. package/src/theme/components/button.ts +67 -0
  37. package/src/theme/components/checkbox.ts +28 -0
  38. package/src/theme/components/input.ts +23 -1
  39. package/src/theme/components/textarea.ts +21 -0
  40. package/src/theme/customXQChakraTheme.ts +2 -0
@@ -1,8 +1,13 @@
1
1
  import React from 'react';
2
- import { Textarea } from '@chakra-ui/react';
2
+ import { Flex, Textarea } from '@chakra-ui/react';
3
3
  import { TextareaFieldProps } from '../InputTypes';
4
4
 
5
- export interface StackedTextareaProps extends TextareaFieldProps {}
5
+ export interface StackedTextareaProps extends TextareaFieldProps {
6
+ isRequired?: boolean;
7
+ allowDefault?: boolean;
8
+ variant: string;
9
+ label?: string;
10
+ }
6
11
 
7
12
  /**
8
13
  * A functional React component utilized to render the `StackedTextarea` component.
@@ -10,14 +15,35 @@ export interface StackedTextareaProps extends TextareaFieldProps {}
10
15
  const StackedTextarea = React.forwardRef<
11
16
  HTMLTextAreaElement,
12
17
  StackedTextareaProps
13
- >(({ ...props }, _ref) => {
18
+ >(({ isRequired, allowDefault, variant, label, ...props }, _ref) => {
19
+ const isMobile = variant === 'mobile';
20
+ if (isMobile) {
21
+ return (
22
+ <Flex>
23
+ <Textarea
24
+ ref={_ref}
25
+ {...props}
26
+ variant={variant}
27
+ fontSize="17px"
28
+ placeholder={label ?? ''}
29
+ onKeyDown={e => {
30
+ if (e.key === 'Enter' && !allowDefault) {
31
+ e.stopPropagation();
32
+ e.preventDefault();
33
+ }
34
+ }}
35
+ />
36
+ </Flex>
37
+ );
38
+ }
14
39
  return (
15
40
  <Textarea
16
41
  ref={_ref}
17
42
  {...props}
43
+ variant={variant}
18
44
  fontSize="13px"
19
45
  onKeyDown={e => {
20
- if (e.key === 'Enter') {
46
+ if (e.key === 'Enter' && !allowDefault) {
21
47
  e.stopPropagation();
22
48
  e.preventDefault();
23
49
  }
@@ -23,7 +23,7 @@ export const Dropdown: React.FC<DropdownProps> = ({
23
23
  }) => {
24
24
  const DropdownContent = useMemo(() => {
25
25
  return options.map((option, idx) => (
26
- <Box key={idx} width="100%">
26
+ <Box key={idx} width="100%" role="combobox">
27
27
  {option.value === 'section_header' &&
28
28
  options[idx + 1] &&
29
29
  options[idx + 1].value !== 'section_header' && (
@@ -7,19 +7,20 @@ import colors from '../../../../../src/theme/foundations/colors';
7
7
  export interface TokenProps {
8
8
  label: any;
9
9
  onDelete: any;
10
+ isMobile?: boolean;
10
11
  }
11
12
 
12
13
  // For v1 we are truncating the label at 15 characters to avoid overflow
13
- const Token: React.FC<TokenProps> = ({ label, onDelete }) => {
14
+ const Token: React.FC<TokenProps> = ({ label, onDelete, isMobile = false }) => {
14
15
  return (
15
16
  <Flex
16
17
  key={label}
17
- borderRadius="full"
18
+ borderRadius={'full'}
18
19
  backgroundColor="#7676801F"
19
20
  alignItems="center"
20
21
  width="fit-content"
21
22
  w="auto"
22
- h="16px"
23
+ h={isMobile ? '18px' : '16px'}
23
24
  pl="6px"
24
25
  pr="2px"
25
26
  py="2px"
@@ -28,7 +29,7 @@ const Token: React.FC<TokenProps> = ({ label, onDelete }) => {
28
29
  <Text
29
30
  whiteSpace="nowrap"
30
31
  color={colors.label.primary.light}
31
- fontSize="13px"
32
+ fontSize={isMobile ? '17px' : '13px'}
32
33
  pr="4px"
33
34
  >
34
35
  {truncate(label.trim(), {
@@ -36,7 +37,7 @@ const Token: React.FC<TokenProps> = ({ label, onDelete }) => {
36
37
  omission: '...',
37
38
  })}
38
39
  </Text>
39
- <Close boxSize="11px" onClick={onDelete} />
40
+ <Close boxSize={isMobile ? '17px' : '11px'} onClick={onDelete} />
40
41
  </Flex>
41
42
  );
42
43
  };
@@ -38,7 +38,7 @@ export interface InputProps<T extends FieldValues> extends ValidationProps {
38
38
  fullOptions?: FieldOptions;
39
39
  maxLength?: number;
40
40
  helperText?: React.ReactNode;
41
- control: Control<T, any>;
41
+ control: Control<T, unknown>;
42
42
  onChange?: (value?: string) => void;
43
43
  disabled?: boolean;
44
44
  tooltipText?: string;
@@ -48,6 +48,7 @@ export interface InputProps<T extends FieldValues> extends ValidationProps {
48
48
  leftElement?: React.ReactNode;
49
49
  allowDefault?: boolean;
50
50
  rightElement?: React.ReactNode;
51
+ variant: string;
51
52
  }
52
53
 
53
54
  /**
@@ -75,6 +76,7 @@ export function Input<T extends FieldValues>({
75
76
  rightElement,
76
77
  leftElement,
77
78
  allowDefault,
79
+ variant = 'default',
78
80
  onChange,
79
81
  setValue,
80
82
  setError,
@@ -107,6 +109,8 @@ export function Input<T extends FieldValues>({
107
109
  defaultValue={defaultValue}
108
110
  value={value}
109
111
  allowDefault={allowDefault}
112
+ variant={variant}
113
+ label={label as string}
110
114
  />
111
115
  );
112
116
  case 'radio':
@@ -161,6 +165,8 @@ export function Input<T extends FieldValues>({
161
165
  ref={ref}
162
166
  disabled={disabled}
163
167
  value={value}
168
+ variant={variant}
169
+ label={label as string}
164
170
  />
165
171
  );
166
172
  case 'checkbox':
@@ -177,6 +183,7 @@ export function Input<T extends FieldValues>({
177
183
  defaultValue={defaultValue}
178
184
  label={label as string}
179
185
  disabled={disabled}
186
+ variant={variant}
180
187
  />
181
188
  );
182
189
  case 'multi-select':
@@ -218,6 +225,8 @@ export function Input<T extends FieldValues>({
218
225
  clearErrors={clearErrors as UseFormClearErrors<FieldValues>}
219
226
  control={control as Control<FieldValues, any>}
220
227
  maxLength={maxLength}
228
+ variant={variant}
229
+ label={label}
221
230
  />
222
231
  );
223
232
  case 'switch':
@@ -238,6 +247,7 @@ export function Input<T extends FieldValues>({
238
247
  return null;
239
248
  }
240
249
  };
250
+ const nonLabeledInputs = ['checkbox'];
241
251
 
242
252
  return (
243
253
  <Controller
@@ -252,18 +262,24 @@ export function Input<T extends FieldValues>({
252
262
  isInvalid={isInvalid}
253
263
  position="relative"
254
264
  py={
255
- (inputType !== 'checkbox' && label) || helperText || isInvalid
265
+ (!nonLabeledInputs.includes(inputType) &&
266
+ variant !== 'mobile' &&
267
+ label) ||
268
+ helperText ||
269
+ isInvalid
256
270
  ? 5
257
271
  : 0
258
272
  }
259
273
  >
260
- {label && inputType !== 'checkbox' && (
261
- <Label
262
- tooltipText={tooltipText}
263
- label={label}
264
- isRequired={isRequired}
265
- />
266
- )}
274
+ {label &&
275
+ !nonLabeledInputs.includes(inputType) &&
276
+ variant !== 'mobile' && (
277
+ <Label
278
+ tooltipText={tooltipText}
279
+ label={label}
280
+ isRequired={isRequired}
281
+ />
282
+ )}
267
283
  {selectedInputField(
268
284
  onChange ? onChange : fieldOnChange,
269
285
  onBlur,
@@ -0,0 +1,140 @@
1
+ import React, { useEffect } from 'react';
2
+ import { Select } from '@chakra-ui/react';
3
+ import {
4
+ FormControl,
5
+ FormErrorMessage,
6
+ FormHelperText,
7
+ } from '@chakra-ui/react';
8
+ import {
9
+ Control,
10
+ Controller,
11
+ FieldValues,
12
+ UseFormClearErrors,
13
+ UseFormSetError,
14
+ UseFormSetValue,
15
+ } from 'react-hook-form';
16
+ import { FieldOptions, ValidationProps } from 'src/components/input/InputTypes';
17
+
18
+ export interface SelectNativeProps<T extends FieldValues>
19
+ extends ValidationProps {
20
+ isRequired: boolean;
21
+
22
+ name: string;
23
+ ariaLabel: string;
24
+ placeholder?: string;
25
+ defaultValue?: string;
26
+ label?: string;
27
+ className?: string;
28
+ options?: FieldOptions;
29
+ fullOptions?: FieldOptions;
30
+ helperText?: React.ReactNode;
31
+ control: Control<T, unknown>;
32
+ onChange?: (value?: string) => void;
33
+ disabled?: boolean;
34
+ tooltipText?: string;
35
+ setValue: UseFormSetValue<T>;
36
+ setError: UseFormSetError<T>;
37
+ clearErrors: UseFormClearErrors<T>;
38
+ allowDefault?: boolean;
39
+ }
40
+
41
+ /**
42
+ * A functional React component utilized to render the `SelectNative` component.
43
+ */
44
+ export const SelectNative: React.FC<SelectNativeProps<HTMLSelectElement>> = ({
45
+ label,
46
+ ariaLabel,
47
+ className,
48
+ placeholder,
49
+ name,
50
+ helperText,
51
+ options,
52
+ tooltipText,
53
+ isInvalid,
54
+ errorText,
55
+ isRequired,
56
+ defaultValue,
57
+ fullOptions,
58
+ control,
59
+ disabled,
60
+ onChange,
61
+ setValue,
62
+ setError,
63
+ clearErrors,
64
+ ...props
65
+ }) => {
66
+ // const [selectedOption, setSelectedOption] = useState(
67
+ // options ? options[0] ?? '' : ''
68
+ // );
69
+
70
+ const style = {
71
+ cursor: 'pointer',
72
+ color: 'var(--chakra-colors-blue-500)',
73
+ height: '48px',
74
+ fontSize: '17px',
75
+ lineHeight: '20px',
76
+ fontWeight: 400,
77
+ padding: '12px 16px 12px 0px',
78
+ borderRadius: 0,
79
+ border: '0.5px solid rgba(153, 153, 153, 0.1)',
80
+ borderLeft: 'none',
81
+ borderRight: 'none',
82
+ };
83
+
84
+ const handleOnSelectItem = (selectedValue: string) => {
85
+ const selectedOption = options?.find(
86
+ ({ value: val }) => selectedValue === val
87
+ );
88
+
89
+ if (selectedOption) {
90
+ if (onChange) {
91
+ onChange(selectedOption.value);
92
+ }
93
+ setValue(name as string, selectedOption.value);
94
+ } else {
95
+ setValue(name as string, selectedValue);
96
+ }
97
+ };
98
+
99
+ useEffect(() => {
100
+ if (defaultValue) {
101
+ handleOnSelectItem(defaultValue);
102
+ }
103
+ // eslint-disable-next-line react-hooks/exhaustive-deps
104
+ }, [defaultValue]);
105
+ return (
106
+ <Controller
107
+ control={control}
108
+ name={name}
109
+ rules={{ required: isRequired }}
110
+ /** @ts-ignore: issues with implicit */
111
+ render={({ field: { onBlur, onChange: fieldOnChange, ref, value } }) => (
112
+ <FormControl id={name} isInvalid={isInvalid} position="relative" py={0}>
113
+ <Select
114
+ {...props}
115
+ required={isRequired}
116
+ ref={ref}
117
+ value={value}
118
+ disabled={disabled ?? false}
119
+ onChange={e => handleOnSelectItem(e.target.value)}
120
+ style={style}
121
+ >
122
+ {options &&
123
+ options.map(i => {
124
+ return (
125
+ <option value={i.value} key={i.sortValue}>
126
+ {i.label}
127
+ </option>
128
+ );
129
+ })}
130
+ </Select>
131
+ {isInvalid ? (
132
+ <FormErrorMessage>{errorText}</FormErrorMessage>
133
+ ) : (
134
+ helperText && <FormHelperText>{helperText}</FormHelperText>
135
+ )}
136
+ </FormControl>
137
+ )}
138
+ />
139
+ );
140
+ };
@@ -3,7 +3,7 @@ import { Meta, Story } from '@storybook/react';
3
3
  import { Text } from '../text';
4
4
  import { Table, TableProps } from '../table';
5
5
  import { TableBody, TableHeaders } from '../table/TableTypes';
6
- import { useArgs, useMemo, useState } from '@storybook/addons';
6
+ import { useMemo, useState } from '@storybook/addons';
7
7
  import { TabsWrapper, TabsWrapperProps } from '.';
8
8
 
9
9
  const tableColumns = ['foo', 'bar'];
package/src/index.tsx CHANGED
@@ -35,6 +35,9 @@ export * from './components/icons';
35
35
  // Input
36
36
  export * from './components/input';
37
37
 
38
+ // Select
39
+ export { SelectNative } from './components/select';
40
+
38
41
  // Layout
39
42
  export * from './components/layout';
40
43
 
@@ -79,10 +79,77 @@ const variantTertiary = () => {
79
79
  };
80
80
  };
81
81
 
82
+ const variantPrimaryFlat = () => {
83
+ return {
84
+ ...baseStyle,
85
+ bg: colors.fill.action,
86
+ bgGradient: null,
87
+ minWidth: '172.5px',
88
+ padding: '10px 16px',
89
+ borderRadius: '8px',
90
+ border: '0.5px',
91
+ gap: '8px',
92
+ height: '44px',
93
+ // margin: '8px',
94
+ fontSize: '17px',
95
+ fontWeight: '500',
96
+ lineHeight: '24px',
97
+ letterSpacing: '0.02em',
98
+ textAlign: 'center',
99
+ boxShadow: '0px 0.5px 1px 0.5px #0000001A',
100
+ };
101
+ };
102
+
103
+ const variantSecondaryFlat = () => {
104
+ return {
105
+ ...variantPrimaryFlat(),
106
+ fontWeight: '400',
107
+ color: colors.black,
108
+ bg: colors.label.primary.dark,
109
+ _hover: {
110
+ bg: colors.label.primary.dark,
111
+ },
112
+ _active: {
113
+ color: colors.black,
114
+ bg: colors.label.primary.dark,
115
+ bgGradient: colors.fill.light.quaternary,
116
+ },
117
+ _focus: {
118
+ bg: colors.label.primary.dark,
119
+ },
120
+ };
121
+ };
122
+ const variantTertiaryFlat = () => {
123
+ return {
124
+ ...variantPrimaryFlat(),
125
+ fontWeight: '400',
126
+ color: colors.label.primary.dark,
127
+ bg: colors.blur.quaternary.dark,
128
+ _hover: {
129
+ bg: colors.blur.quaternary.dark,
130
+ },
131
+ _active: {
132
+ color: colors.label.primary.dark,
133
+ bg: colors.blur.tertiary.dark,
134
+ },
135
+ _focus: {
136
+ color: colors.label.primary.dark,
137
+ bg: colors.blur.quaternary.dark,
138
+ },
139
+ _disabled: {
140
+ backgroundColor: colors.blur.quaternary.dark,
141
+ color: colors.blur.tertiary.dark,
142
+ },
143
+ };
144
+ };
145
+
82
146
  const variants = {
83
147
  primary: variantPrimary(),
84
148
  secondary: variantSecondary(),
85
149
  tertiary: variantTertiary(),
150
+ 'flat-primary': variantPrimaryFlat(),
151
+ 'flat-secondary': variantSecondaryFlat(),
152
+ 'flat-tertiary': variantTertiaryFlat(),
86
153
  };
87
154
 
88
155
  const defaultProps = {
@@ -0,0 +1,28 @@
1
+ import { checkboxAnatomy } from '@chakra-ui/anatomy';
2
+ import { createMultiStyleConfigHelpers } from '@chakra-ui/react';
3
+
4
+ const {
5
+ definePartsStyle,
6
+ defineMultiStyleConfig,
7
+ } = createMultiStyleConfigHelpers(checkboxAnatomy.keys);
8
+
9
+ const roundedCheckbox = definePartsStyle({
10
+ control: {
11
+ //borderRadius: 50,
12
+ },
13
+ label: {
14
+ fontSize: '17px',
15
+ fontWeight: 400,
16
+ lineHeight: '20px',
17
+ padding: '12px 16px 12px 0px',
18
+ },
19
+ height: '44px',
20
+ });
21
+
22
+ const variants = {
23
+ mobile: roundedCheckbox,
24
+ };
25
+
26
+ export default defineMultiStyleConfig({
27
+ variants,
28
+ });
@@ -26,10 +26,32 @@ const baseStyle = {
26
26
  border: '2px solid',
27
27
  borderColor: colors.border.focus,
28
28
  },
29
+ _placeholder: {
30
+ color: colors.label.secondary.light,
31
+ },
32
+ },
33
+ };
34
+
35
+ const mobileInputs = {
36
+ ...baseStyle,
37
+ field: {
38
+ fontSize: '17px',
39
+ py: '14px',
40
+ px: '16px',
41
+ cursor: 'pointer',
42
+ lineHeight: '21px',
43
+ fontWeight: 400,
44
+ borderRadius: 0,
45
+ height: '48px',
46
+ padding: '12px 16px 12px 0px',
47
+ border: '0.5px solid rgba(153, 153, 153, 0.1)',
48
+ borderColor: 'rgba(153, 153, 153, 0.1)',
49
+ borderLeft: 'none',
50
+ borderRight: 'none',
29
51
  },
30
52
  };
31
53
 
32
- const variants = { default: baseStyle };
54
+ const variants = { default: baseStyle, mobile: mobileInputs };
33
55
 
34
56
  const defaultProps = {
35
57
  variant: 'default',
@@ -1,4 +1,5 @@
1
1
  import Input from './input';
2
+ import { defineStyle } from '@chakra-ui/react';
2
3
 
3
4
  const baseStyle = {
4
5
  ...Input.baseStyle.field,
@@ -11,11 +12,31 @@ const baseStyle = {
11
12
  lineHeight: 'short',
12
13
  };
13
14
 
15
+ const mobileInputs = defineStyle({
16
+ ...baseStyle,
17
+ ...Input.variants.mobile.field,
18
+ border: 'none',
19
+ borderRadius: 0,
20
+ paddingY: '16px',
21
+ paddingX: '0',
22
+ // padding: '16px 16px',
23
+ cursor: 'pointer',
24
+ lineHeight: '21px',
25
+ fontWeight: 400,
26
+ resize: 'none',
27
+ overflowY: 'auto',
28
+ fontSize: '17px',
29
+ minHeight: '208px',
30
+ });
31
+
32
+ const variants = { default: baseStyle, mobile: mobileInputs };
33
+
14
34
  const defaultProps = {
15
35
  variant: 'default',
16
36
  };
17
37
 
18
38
  export default {
19
39
  baseStyle,
40
+ variants,
20
41
  defaultProps,
21
42
  };
@@ -6,6 +6,7 @@ import typography from './foundations/typography';
6
6
  import Alert from './components/alert';
7
7
  import Badge from './components/badge';
8
8
  import Button from './components/button';
9
+ import Checkbox from './components/checkbox';
9
10
  import Code from './components/code';
10
11
  import Form from './components/form';
11
12
  import FormError from './components/form-error';
@@ -30,6 +31,7 @@ const customXQChakraTheme = extendTheme({
30
31
  Alert,
31
32
  Badge,
32
33
  Button,
34
+ Checkbox,
33
35
  Code,
34
36
  Form,
35
37
  FormError,