@thecb/components 4.3.1 → 4.3.4

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": "@thecb/components",
3
- "version": "4.3.1",
3
+ "version": "4.3.4",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -63,7 +63,8 @@ const StyledCheckbox = styled.div`
63
63
  checkedStyles,
64
64
  focusedStyles,
65
65
  errorStyles,
66
- disabledStyles
66
+ disabledStyles,
67
+ disabledCheckedStyles
67
68
  }) =>
68
69
  error
69
70
  ? css`
@@ -71,7 +72,7 @@ const StyledCheckbox = styled.div`
71
72
  `
72
73
  : disabled
73
74
  ? css`
74
- ${disabledStyles}
75
+ ${checked ? disabledCheckedStyles : disabledStyles}
75
76
  `
76
77
  : checked
77
78
  ? css`
@@ -90,7 +91,9 @@ const Checkbox = ({
90
91
  disabled = false,
91
92
  themeValues,
92
93
  hidden = false,
93
- error = false
94
+ error = false,
95
+ extraStyles,
96
+ textExtraStyles
94
97
  }) => {
95
98
  const [focused, setFocused] = useState(false);
96
99
 
@@ -109,7 +112,7 @@ const Checkbox = ({
109
112
  onKeyDown={e => handleClick(e, onChange)}
110
113
  hiddenStyles={hidden}
111
114
  background={themeValues.backgroundColor}
112
- extraStyles="outline: none;"
115
+ extraStyles={`outline: none; ${extraStyles}`}
113
116
  >
114
117
  <CheckboxLabelContainer>
115
118
  <CheckboxContainer data-qa="Checkbox">
@@ -131,6 +134,7 @@ const Checkbox = ({
131
134
  checkedStyles={themeValues.checkedStyles}
132
135
  errorStyles={themeValues.errorStyles}
133
136
  disabledStyles={themeValues.disabledStyles}
137
+ disabledCheckedStyles={themeValues.disabledCheckedStyles}
134
138
  focusedStyles={themeValues.focusedStyles}
135
139
  >
136
140
  <CheckboxIcon
@@ -147,7 +151,13 @@ const Checkbox = ({
147
151
  variant="p"
148
152
  weight={themeValues.textFontWeight}
149
153
  color={themeValues.textColor}
150
- extraStyles={`margin-left: 1rem`}
154
+ extraStyles={
155
+ textExtraStyles
156
+ ? `${textExtraStyles} ${disabled &&
157
+ `color: #6e727e; background-color: #f7f7f7;`} `
158
+ : `margin-left: 1rem ${disabled &&
159
+ `color: #6e727e; background-color: #f7f7f7;`}`
160
+ }
151
161
  >
152
162
  {title}
153
163
  </Text>
@@ -13,12 +13,19 @@ const textFontSize = { default: "1.1rem" };
13
13
  const textFontWeight = { default: "400" };
14
14
  const textLineHeight = { default: "2rem" };
15
15
  const textColor = { default: `${CHARADE_GREY}` };
16
- const disabledCheckColor = { default: `${GHOST_GREY};` };
16
+ const disabledCheckColor = { default: `${WHITE};` };
17
17
  const checkColor = { default: `${WHITE};` };
18
18
  const errorStyles = { default: `border: 1px solid ${RED};` };
19
19
  const focusedStyles = {
20
20
  default: `box-shadow: 0 0 5px 0 ${MATISSE_BLUE};`
21
21
  };
22
+ const disabledCheckedStyles = {
23
+ default: `
24
+ background: #6d717e;
25
+ border: 1px solid #6d717e;
26
+ `
27
+ };
28
+
22
29
  const disabledStyles = {
23
30
  default: `
24
31
  background: ${SEASHELL_WHITE};
@@ -50,5 +57,6 @@ export const fallbackValues = {
50
57
  focusedStyles,
51
58
  disabledStyles,
52
59
  checkedStyles,
53
- defaultStyles
60
+ defaultStyles,
61
+ disabledCheckedStyles
54
62
  };
@@ -17,7 +17,6 @@ import { themeComponent } from "../../../util/themeUtils";
17
17
 
18
18
  const IconWrapper = styled.div`
19
19
  display: flex;
20
- padding-left: 8px;
21
20
  flex-direction: column;
22
21
  justify-content: center;
23
22
  transition: transform 0.3s ease;
@@ -92,7 +91,8 @@ const Dropdown = ({
92
91
  onClick = noop,
93
92
  themeValues,
94
93
  maxHeight,
95
- widthFitOptions = false
94
+ widthFitOptions = false,
95
+ disabled
96
96
  }) => {
97
97
  const [inputValue, setInputValue] = useState("");
98
98
  const [optionsState, setOptionsState] = useState([]);
@@ -171,7 +171,6 @@ const Dropdown = ({
171
171
  useEffect(() => {
172
172
  clearTimeout(timer);
173
173
  setTimer(setTimeout(() => setInputValue(""), 2000));
174
-
175
174
  setFilteredOptions(
176
175
  options.filter(
177
176
  option =>
@@ -205,6 +204,12 @@ const Dropdown = ({
205
204
  width="100%"
206
205
  hoverStyles={`background-color: ${themeValues.hoverColor};`}
207
206
  aria-expanded={isOpen}
207
+ extraStyles={
208
+ disabled &&
209
+ `color: #6e727e;
210
+ background-color: #f7f7f7;
211
+ pointer-events: none;`
212
+ }
208
213
  >
209
214
  <Box
210
215
  as="button"
@@ -222,8 +227,13 @@ const Dropdown = ({
222
227
  }
223
228
  borderRadius="2px"
224
229
  tabIndex={0}
225
- extraStyles={`height: 48px;`}
226
230
  dataQa={placeholder}
231
+ extraStyles={`height: 48px;
232
+ ${disabled &&
233
+ `color: #6e727e;
234
+ background-color: #f7f7f7;
235
+ pointer-events: none;`}
236
+ `}
227
237
  >
228
238
  <Stack direction="row" bottomItem={2}>
229
239
  {isOpen ? (
@@ -234,7 +244,15 @@ const Dropdown = ({
234
244
  themeValues={themeValues}
235
245
  />
236
246
  ) : (
237
- <Text variant="p">
247
+ <Text
248
+ variant="p"
249
+ extraStyles={
250
+ disabled &&
251
+ `color: #6e727e;
252
+ background-color: #f7f7f7;
253
+ pointer-events: none;`
254
+ }
255
+ >
238
256
  {value
239
257
  ? options.find(option => option.value === value)?.text
240
258
  : placeholder}
@@ -40,6 +40,13 @@ const InputField = styled.input`
40
40
  outline-offset: 2px;
41
41
  }
42
42
 
43
+ ${({ disabled }) =>
44
+ disabled &&
45
+ css`
46
+ color: #6e727e;
47
+ background-color: #f7f7f7;
48
+ `}
49
+
43
50
  ${({ extraStyles }) =>
44
51
  css`
45
52
  ${extraStyles}
@@ -76,6 +83,13 @@ const FormattedInputField = styled(({ showErrors, themeValues, ...props }) => (
76
83
  outline-offset: 2px;
77
84
  }
78
85
 
86
+ ${({ disabled }) =>
87
+ disabled &&
88
+ css`
89
+ color: #6e727e;
90
+ background-color: #f7f7f7;
91
+ `}
92
+
79
93
  ${({ extraStyles }) =>
80
94
  css`
81
95
  ${extraStyles}
@@ -17,6 +17,7 @@ const FormSelect = ({
17
17
  onChange,
18
18
  dropdownMaxHeight,
19
19
  disabledValues,
20
+ disabled,
20
21
  themeValues
21
22
  }) => {
22
23
  const [open, setOpen] = useState(false);
@@ -36,7 +37,7 @@ const FormSelect = ({
36
37
  });
37
38
 
38
39
  return (
39
- <SelectContainer ref={dropdownRef}>
40
+ <SelectContainer ref={dropdownRef} disabled={disabled}>
40
41
  <Box padding="0" minWidth="100%">
41
42
  <Cluster justify="space-between" align="center">
42
43
  <Text
@@ -70,6 +71,7 @@ const FormSelect = ({
70
71
  onChange ? value => onChange(value) : value => fieldActions.set(value)
71
72
  }
72
73
  onClick={() => setOpen(!open)}
74
+ disabled={disabled}
73
75
  />
74
76
  <Stack direction="row" justify="space-between">
75
77
  {(field.hasErrors && field.dirty) || (field.hasErrors && showErrors) ? (
@@ -32,6 +32,7 @@ export { default as PasswordRequirements } from "./password-requirements";
32
32
  export { default as Placeholder } from "./placeholder";
33
33
  export { default as ProcessingFee } from "./processing-fee";
34
34
  export { default as RadioButton } from "./radio-button";
35
+ export { default as SearchableSelect } from "./searchable-select";
35
36
  export { default as SolidDivider } from "./solid-divider";
36
37
  export { default as Spinner } from "./spinner";
37
38
  export { default as StateProvinceDropdown } from "./state-province-dropdown";
@@ -23,15 +23,15 @@ import {
23
23
  const PasswordRequirements = ({ password, isMobile }) => {
24
24
  const iconMap = {
25
25
  [INPUT_STATE_NEUTRAL]: {
26
- icon: <IconNeutral margin="0.125rem 0.5rem 0 0" />,
26
+ icon: <IconNeutral margin="0 0.5rem 0 0" />,
27
27
  color: MINESHAFT_GREY
28
28
  },
29
29
  [INPUT_STATE_INVALID]: {
30
- icon: <IconInvalid margin="0.125rem 0.5rem 0 0" />,
30
+ icon: <IconInvalid margin="0 0.5rem 0 0" />,
31
31
  color: RAZZMATAZZ_RED
32
32
  },
33
33
  [INPUT_STATE_VALID]: {
34
- icon: <IconValid margin="0.125rem 0.5rem 0 0" />,
34
+ icon: <IconValid margin="0 0.5rem 0 0" />,
35
35
  color: FOREST_GREEN
36
36
  }
37
37
  };
@@ -83,7 +83,7 @@ const PasswordRequirements = ({ password, isMobile }) => {
83
83
  </Box>
84
84
  <Box padding="0">
85
85
  <Sidebar onRight childGap="0rem">
86
- <Box padding="0rem">
86
+ <Box padding="0.15rem 0 0 0">
87
87
  <Cluster justify="flex-start" align="center">
88
88
  <Stack fullHeight childGap="0.25rem">
89
89
  <Paragraph
@@ -0,0 +1,85 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import { fallbackValues } from "./SearchableSelect.theme";
3
+ import { themeComponent } from "../../../util/themeUtils";
4
+ import { Box, Stack } from "../layouts";
5
+ import { FormInput } from "../form-layouts";
6
+ import Checkbox from "../checkbox";
7
+
8
+ const SELECT_ALL = "Select All";
9
+
10
+ const SearchableSelect = ({
11
+ items,
12
+ selectedItems,
13
+ allSelected,
14
+ toggleSelectAllItems,
15
+ selectItem,
16
+ fields,
17
+ actions,
18
+ disabled,
19
+ themeValues
20
+ }) => {
21
+ const [itemList, setItemList] = useState([]);
22
+ useEffect(() => setItemList(items), [items, selectedItems]);
23
+ useEffect(() => {
24
+ const filteredItems = items.filter(item =>
25
+ item?.name
26
+ ?.toLowerCase()
27
+ .includes(fields?.searchTerm?.rawValue?.toLowerCase())
28
+ );
29
+ setItemList(filteredItems);
30
+ }, [fields.searchTerm.rawValue]);
31
+
32
+ const handleSelect = value => {
33
+ if (value.name === SELECT_ALL) {
34
+ allSelected ? toggleSelectAllItems(false) : toggleSelectAllItems(true);
35
+ } else {
36
+ selectItem(value);
37
+ }
38
+ };
39
+ return (
40
+ <Box
41
+ padding="1rem"
42
+ border={themeValues.border}
43
+ extraStyles={
44
+ disabled &&
45
+ `color: #6e727e; background-color: #f7f7f7; pointer-events: none;`
46
+ }
47
+ >
48
+ <Stack>
49
+ <FormInput
50
+ errorMessages={{}}
51
+ field={fields.searchTerm}
52
+ fieldActions={actions.fields.searchTerm}
53
+ placeholder="Search agencies"
54
+ disabled={disabled}
55
+ />
56
+ <Box
57
+ padding="0.5rem 0"
58
+ extraStyles={`overflow-y: scroll; height: 250px;`}
59
+ >
60
+ <Stack>
61
+ {itemList.map(value => (
62
+ <Checkbox
63
+ key={value.name}
64
+ title={value.name}
65
+ name={value.name}
66
+ checked={selectedItems.find(item => item.name === value.name)}
67
+ onChange={() => handleSelect(value)}
68
+ textExtraStyles={`margin: 0;`}
69
+ disabled={disabled}
70
+ extraStyles={`margin: 0 0.5rem;`}
71
+ />
72
+ ))}
73
+ </Stack>
74
+ </Box>
75
+ </Stack>
76
+ </Box>
77
+ );
78
+ };
79
+
80
+ export default themeComponent(
81
+ SearchableSelect,
82
+ "SearchableSelect",
83
+ fallbackValues,
84
+ "default"
85
+ );
@@ -0,0 +1,7 @@
1
+ const border = {
2
+ default: `1px solid #caced8`
3
+ };
4
+
5
+ export const fallbackValues = {
6
+ border
7
+ };
@@ -0,0 +1,3 @@
1
+ import SearchableSelect from "./SearchableSelect";
2
+
3
+ export default SearchableSelect;
@@ -13,9 +13,13 @@ import {
13
13
  FormContainer,
14
14
  FormInputColumn
15
15
  } from "../../atoms/form-layouts";
16
- import { Box, Cluster } from "../../atoms/layouts";
16
+ import { Box, Cluster, Stack } from "../../atoms/layouts";
17
+ import ButtonWithAction from "../../atoms/button-with-action";
18
+ import Heading from "../../atoms/heading";
19
+ import Text from "../../atoms/text";
17
20
  import PasswordRequirements from "../../atoms/password-requirements";
18
21
  import { noop } from "../../../util/general";
22
+ import { GHOST_GREY } from "../../../constants/colors";
19
23
 
20
24
  const ChangePasswordForm = ({
21
25
  clearOnDismount,
@@ -23,7 +27,11 @@ const ChangePasswordForm = ({
23
27
  actions,
24
28
  handleSubmit = noop,
25
29
  showErrors,
26
- isMobile
30
+ isMobile,
31
+ revenueManagement,
32
+ closeForm,
33
+ firstName,
34
+ lastName
27
35
  }) => {
28
36
  if (clearOnDismount) {
29
37
  useEffect(() => () => actions.form.clear(), []);
@@ -48,43 +56,89 @@ const ChangePasswordForm = ({
48
56
  };
49
57
 
50
58
  return (
51
- <FormContainer role="form" aria-label="Change password">
52
- <FormInputColumn>
53
- <FormInput
54
- labelTextWhenNoError="Current password"
55
- errorMessages={currentPasswordErrorMessages}
56
- field={fields.currentPassword}
57
- fieldActions={actions.fields.currentPassword}
58
- showErrors={showErrors}
59
- onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
60
- type="password"
61
- />
62
- <FormInput
63
- labelTextWhenNoError="New password"
64
- errorMessages={newPasswordErrorMessages}
65
- field={fields.newPassword}
66
- fieldActions={actions.fields.newPassword}
67
- showErrors={showErrors}
68
- onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
69
- type="password"
70
- />
71
- <FormInput
72
- labelTextWhenNoError="Confirm password"
73
- errorMessages={confirmNewPasswordErrorMessages}
74
- field={fields.confirmNewPassword}
75
- fieldActions={actions.fields.confirmNewPassword}
76
- showErrors={showErrors}
77
- onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
78
- type="password"
79
- />
80
- </FormInputColumn>
81
- <Box padding={isMobile ? "1rem 0 0" : "1.5rem 0 0"}>
82
- <Cluster justify="center" align="center">
83
- <PasswordRequirements
84
- password={fields.newPassword}
85
- isMobile={isMobile}
59
+ <FormContainer
60
+ role="form"
61
+ aria-label="Change password"
62
+ extraStyles={`padding: 0;`}
63
+ >
64
+ {revenueManagement && (
65
+ <Box
66
+ padding="1.5rem"
67
+ borderColor={GHOST_GREY}
68
+ borderSize="1px"
69
+ borderWidthOverride={"0 0 1px 0"}
70
+ >
71
+ <Cluster justify="flex-start" align="center">
72
+ <Box padding="1.25rem" borderRadius="50%" background="#CACED8">
73
+ <Heading variant="h4" weight="700">
74
+ {firstName.charAt(0).toUpperCase()}
75
+ {lastName.charAt(0).toUpperCase()}
76
+ </Heading>
77
+ </Box>
78
+ <Text variant="p" weight="700" extraStyles={`padding-left: 1rem;`}>
79
+ {firstName} {lastName}
80
+ </Text>
81
+ </Cluster>
82
+ </Box>
83
+ )}
84
+ <Box padding="1.5rem">
85
+ <FormInputColumn>
86
+ <FormInput
87
+ labelTextWhenNoError="Current password"
88
+ errorMessages={currentPasswordErrorMessages}
89
+ field={fields.currentPassword}
90
+ fieldActions={actions.fields.currentPassword}
91
+ showErrors={showErrors}
92
+ onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
93
+ type="password"
86
94
  />
87
- </Cluster>
95
+ <FormInput
96
+ labelTextWhenNoError="New password"
97
+ errorMessages={newPasswordErrorMessages}
98
+ field={fields.newPassword}
99
+ fieldActions={actions.fields.newPassword}
100
+ showErrors={showErrors}
101
+ onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
102
+ type="password"
103
+ />
104
+ <FormInput
105
+ labelTextWhenNoError="Confirm password"
106
+ errorMessages={confirmNewPasswordErrorMessages}
107
+ field={fields.confirmNewPassword}
108
+ fieldActions={actions.fields.confirmNewPassword}
109
+ showErrors={showErrors}
110
+ onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
111
+ type="password"
112
+ />
113
+ </FormInputColumn>
114
+ <Box padding={isMobile ? "1rem 0 0" : "1.5rem 0 0"}>
115
+ <Cluster justify="center" align="center">
116
+ <PasswordRequirements
117
+ password={fields.newPassword}
118
+ isMobile={isMobile}
119
+ />
120
+ </Cluster>
121
+ </Box>
122
+ {revenueManagement && (
123
+ <Box padding="1.5rem 0 0">
124
+ <Stack childGap="1rem" direction="row" justify="flex-end">
125
+ <ButtonWithAction
126
+ text="Cancel"
127
+ action={closeForm}
128
+ variant={"secondary"}
129
+ dataQa="Cancel"
130
+ extraStyles={`margin: 0rem; padding: 0.75rem 1.5rem; border-radius: 4px;`}
131
+ />
132
+ <ButtonWithAction
133
+ text="Save"
134
+ action={handleSubmit}
135
+ variant="primary"
136
+ dataQa="Save"
137
+ extraStyles={`margin: 0rem; padding: 0.75rem 1.5rem; border-radius: 4px;`}
138
+ />
139
+ </Stack>
140
+ </Box>
141
+ )}
88
142
  </Box>
89
143
  </FormContainer>
90
144
  );
@@ -8,6 +8,7 @@ export { default as EmailForm } from "./email-form";
8
8
  export { default as ForgotPasswordForm } from "./forgot-password-form";
9
9
  export { default as HighlightTabRow } from "./highlight-tab-row";
10
10
  export { iconsMap as ObligationIcons } from "./obligation/icons";
11
+ export { default as InternalUserInfoForm } from "./internal-user-info-form";
11
12
  export { default as LoginForm } from "./login-form";
12
13
  export { default as Modal } from "./modal";
13
14
  export { default as Module } from "./module";
@@ -25,6 +26,7 @@ export { default as RegistrationForm } from "./registration-form";
25
26
  export { default as ResetConfirmationForm } from "./reset-confirmation-form";
26
27
  export { default as ResetPasswordForm } from "./reset-password-form";
27
28
  export { default as ResetPasswordSuccess } from "./reset-password-success";
29
+ export { default as Tabs } from "./tabs";
28
30
  export { default as TabSidebar } from "./tab-sidebar";
29
31
  export { default as TermsAndConditions } from "./terms-and-conditions";
30
32
  export { default as TermsAndConditionsModal } from "./terms-and-conditions-modal";