genesys-react-components 0.1.6 → 0.1.8-devengage-1376.128

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 (37) hide show
  1. package/README.md +4 -0
  2. package/build/index.d.ts +1 -2
  3. package/build/index.js +6 -6
  4. package/build/index.js.map +1 -1
  5. package/package.json +49 -47
  6. package/src/alertblock/AlertBlock.scss +108 -0
  7. package/src/alertblock/AlertBlock.tsx +80 -0
  8. package/src/copybutton/CopyButton.scss +8 -0
  9. package/src/copybutton/CopyButton.tsx +42 -0
  10. package/src/dxaccordion/DxAccordion.scss +41 -0
  11. package/src/dxaccordion/DxAccordion.tsx +49 -0
  12. package/src/dxaccordion/DxAccordionGroup.scss +3 -0
  13. package/src/dxaccordion/DxAccordionGroup.tsx +12 -0
  14. package/src/dxbutton/DxButton.scss +79 -0
  15. package/src/dxbutton/DxButton.tsx +31 -0
  16. package/src/dxitemgroup/DxCheckbox.scss +145 -0
  17. package/src/dxitemgroup/DxCheckbox.tsx +46 -0
  18. package/src/dxitemgroup/DxItemGroup.scss +6 -0
  19. package/src/dxitemgroup/DxItemGroup.tsx +133 -0
  20. package/src/dxitemgroup/dropdown.scss +53 -0
  21. package/src/dxitemgroup/multiselect.scss +74 -0
  22. package/src/dxitemgroup/radiobutton.scss +2 -0
  23. package/src/dxlabel/DxLabel.scss +31 -0
  24. package/src/dxlabel/DxLabel.tsx +39 -0
  25. package/src/dxtabbedcontent/DxTabPanel.scss +0 -0
  26. package/src/dxtabbedcontent/DxTabPanel.tsx +8 -0
  27. package/src/dxtabbedcontent/DxTabbedContent.scss +45 -0
  28. package/src/dxtabbedcontent/DxTabbedContent.tsx +28 -0
  29. package/src/dxtextbox/DxTextbox.scss +107 -0
  30. package/src/dxtextbox/DxTextbox.tsx +159 -0
  31. package/src/dxtoggle/DxToggle.scss +76 -0
  32. package/src/dxtoggle/DxToggle.tsx +51 -0
  33. package/src/index.ts +141 -0
  34. package/src/loadingplaceholder/LoadingPlaceholder.scss +58 -0
  35. package/src/loadingplaceholder/LoadingPlaceholder.tsx +17 -0
  36. package/src/tooltip/Tooltip.scss +108 -0
  37. package/src/tooltip/Tooltip.tsx +46 -0
@@ -0,0 +1,42 @@
1
+ import { GenesysDevIcon, GenesysDevIcons } from 'genesys-dev-icons';
2
+ import React, { useState } from 'react';
3
+ import Tooltip from '../tooltip/Tooltip';
4
+
5
+ import './CopyButton.scss';
6
+
7
+ interface IProps {
8
+ copyText: string;
9
+ className?: string;
10
+ tooltipPosition?: 'top' | 'right' | 'bottom' | 'left';
11
+ }
12
+
13
+ export default function CopyButton(props: IProps) {
14
+ let [copyState, setCopyState] = useState(false);
15
+
16
+ // Copy function will set the component state to indicate we have copied the record and then show the tool tip. With the copyState set to true we will see 'Copied'
17
+ const copyCode = (e: React.MouseEvent<HTMLElement>) => {
18
+ e.stopPropagation();
19
+ setCopyState(true);
20
+ navigator.clipboard.writeText(props.copyText);
21
+ return;
22
+ };
23
+
24
+ // Once we lose focus on the copy button, we want to set the copyState to false so that we can hide the tool tip and set the default tool tip to ''
25
+ const loseFocus = () => {
26
+ setCopyState(false);
27
+ return;
28
+ };
29
+
30
+ const buttonClasses = ['copy-button'];
31
+ if (props.className) buttonClasses.push(props.className);
32
+
33
+ return (
34
+ <React.Fragment>
35
+ <Tooltip isShowing={copyState} text="Copied" position={props.tooltipPosition}>
36
+ <button type="button" className={buttonClasses.join(' ')} onClick={copyCode} onMouseOut={loseFocus}>
37
+ <GenesysDevIcon icon={GenesysDevIcons.AppCopy} />
38
+ </button>
39
+ </Tooltip>
40
+ </React.Fragment>
41
+ );
42
+ }
@@ -0,0 +1,41 @@
1
+ .dx-accordion {
2
+ margin: 0;
3
+
4
+ .accordion-heading {
5
+ border-width: 0 0 1px 0;
6
+ border-style: solid;
7
+ border-color: #bfd4e4;
8
+ font-style: normal;
9
+ font-weight: bold;
10
+ font-size: 14px;
11
+ line-height: 14px;
12
+ color: #54565a;
13
+ padding: 13px 20px;
14
+ display: flex;
15
+ flex-flow: row nowrap;
16
+ justify-content: space-between;
17
+ align-items: center;
18
+ cursor: pointer;
19
+
20
+ .icon {
21
+ line-height: 0;
22
+ }
23
+
24
+ &__left {
25
+ align-self: left;
26
+ }
27
+ }
28
+
29
+ .accordion-content {
30
+ padding: 13px 20px 20px 20px;
31
+ border-bottom: 1px solid #bfd4e4;
32
+
33
+ // Clear excess margins from content, we provide the padding
34
+ & > *:first-child {
35
+ margin-top: 0;
36
+ }
37
+ & > *:last-child {
38
+ margin-bottom: 0;
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,49 @@
1
+ import { GenesysDevIcon, GenesysDevIcons } from 'genesys-dev-icons';
2
+ import React, { useState } from 'react';
3
+ import { DxAccordionProps } from '..';
4
+
5
+ import './DxAccordion.scss';
6
+
7
+ export default function DxAccordion(props: DxAccordionProps) {
8
+ const [isOpen, setIsOpen] = useState(props.showOpen || false);
9
+ const [expandTrigger, setExpandTrigger] = useState(props.expandTrigger);
10
+ const [showOpenTrigger, setShowOpenTrigger] = useState(props.showOpenTrigger);
11
+
12
+ // This one forcibly opens the component
13
+ React.useEffect(() => {
14
+ if (props.expandTrigger !== expandTrigger) {
15
+ setIsOpen(true);
16
+ setExpandTrigger(props.expandTrigger);
17
+ }
18
+ }, [props.expandTrigger, expandTrigger]);
19
+
20
+ // This one forcibly recalculates the state based on the value for props.showOpen
21
+ React.useEffect(() => {
22
+ if (props.showOpenTrigger !== showOpenTrigger) {
23
+ setIsOpen(props.showOpen);
24
+ setShowOpenTrigger(props.showOpenTrigger);
25
+ }
26
+ }, [props.showOpenTrigger, showOpenTrigger, props.showOpen]);
27
+
28
+ React.useEffect(() => {
29
+ if (props.showOpen === true || props.showOpen === false) setIsOpen(props.showOpen);
30
+ }, [props.showOpen]);
31
+
32
+ let style = {} as React.CSSProperties;
33
+ if (props.headingColor) style.color = props.headingColor;
34
+
35
+ let icon;
36
+ if (props.headingIcon) icon = <GenesysDevIcon icon={props.headingIcon} className="heading-icon" />;
37
+
38
+ return (
39
+ <div id={props.containerId || undefined} className={`dx-accordion${props.className ? ' ' + props.className : ''}`}>
40
+ <div className="accordion-heading" style={style} onClick={() => setIsOpen(!isOpen)}>
41
+ <span className="accordion-heading__left">
42
+ {icon} {props.title}
43
+ </span>{' '}
44
+ <GenesysDevIcon icon={isOpen ? GenesysDevIcons.AppChevronUp : GenesysDevIcons.AppChevronDown} />
45
+ </div>
46
+ {isOpen ? <div className="accordion-content">{props.children}</div> : undefined}
47
+ </div>
48
+ );
49
+ }
@@ -0,0 +1,3 @@
1
+ .dx-accordion-group {
2
+ margin: 40px 0;
3
+ }
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+
3
+ import './DxAccordionGroup.scss';
4
+
5
+ interface IProps {
6
+ children: React.ReactNode;
7
+ className?: string;
8
+ }
9
+
10
+ export default function DxAccordionGroup(props: IProps) {
11
+ return <div className={`dx-accordion-group${props.className ? ' ' + props.className : ''}`}>{props.children}</div>;
12
+ }
@@ -0,0 +1,79 @@
1
+ .dx-button {
2
+ margin: 15px 10px;
3
+ border-radius: 2px;
4
+ padding: 8px 15px;
5
+ cursor: pointer;
6
+ font-weight: 500;
7
+
8
+ &-primary {
9
+ color: #ffffff;
10
+ border: 1px solid #419bb2;
11
+ background-color: #419bb2;
12
+
13
+ &:hover {
14
+ background-color: #317b8d;
15
+ border-color: #317b8d;
16
+ transition: 0.1s;
17
+ }
18
+
19
+ &:focus {
20
+ background-color: #419bb2;
21
+ border-color: #419bb2;
22
+ box-shadow: 0 0 0 2px #aac9ff;
23
+ transition: 0.1s;
24
+ }
25
+
26
+ &:disabled {
27
+ background-color: #9aafb540;
28
+ border-color: #9aafb540;
29
+ transition: 0.1s;
30
+ cursor: not-allowed;
31
+ }
32
+ }
33
+
34
+ &-secondary {
35
+ color: #419bb2;
36
+ border: 1px solid #419bb2;
37
+ background-color: #ffffff;
38
+
39
+ &:hover {
40
+ color: #317b8d;
41
+ border-color: #317b8d;
42
+ transition: 0.1s;
43
+ }
44
+
45
+ &:focus {
46
+ color: #419bb2;
47
+ border-color: #419bb2;
48
+ box-shadow: 0 0 0 2px #aac9ff;
49
+ transition: 0.1s;
50
+ }
51
+
52
+ &:disabled {
53
+ color: #8a9a9e;
54
+ background-color: #e0e6e8;
55
+ border-color: #e0e6e8;
56
+ transition: 0.1s;
57
+ cursor: not-allowed;
58
+ }
59
+ }
60
+
61
+ &-link {
62
+ color: #2f7bb1;
63
+ background: transparent;
64
+ margin: 0;
65
+ padding: 0 2px;
66
+ border: 0;
67
+
68
+ &:hover {
69
+ color: #1c5176;
70
+ }
71
+
72
+ &:disabled {
73
+ color: #8a9a9e;
74
+ transition: 0.1s;
75
+ cursor: not-allowed;
76
+ text-decoration: line-through;
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { VoidEventCallback } from '..';
3
+
4
+ import './DxButton.scss';
5
+
6
+ interface IProps {
7
+ type?: 'primary' | 'secondary' | 'link';
8
+ disabled?: boolean;
9
+ children?: React.ReactNode;
10
+ className?: string;
11
+ onClick?: VoidEventCallback;
12
+ }
13
+
14
+ export default function DxButton(props: IProps) {
15
+ let classNames = ['dx-button'];
16
+ classNames.push(`dx-button-${props.type || 'primary'}`);
17
+ if (props.className) classNames.push(props.className);
18
+
19
+ const handleClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
20
+ if (!props.onClick) return;
21
+ e.preventDefault();
22
+ e.stopPropagation();
23
+ props.onClick();
24
+ };
25
+
26
+ return (
27
+ <button className={classNames.join(' ')} type="button" onClick={handleClick} disabled={props.disabled === true}>
28
+ {props.children}
29
+ </button>
30
+ );
31
+ }
@@ -0,0 +1,145 @@
1
+ .dx-checkbox {
2
+ display: flex;
3
+ flex-flow: row nowrap;
4
+ align-items: center;
5
+ margin: 15px 0;
6
+
7
+ &:first-of-type {
8
+ margin-top: 0;
9
+ }
10
+
11
+ .label-text {
12
+ font-family: Roboto;
13
+ font-style: normal;
14
+ font-weight: normal;
15
+ font-size: 12px;
16
+ line-height: 18px;
17
+ color: #75757a;
18
+ }
19
+
20
+ input[type='checkbox'] {
21
+ // Hide default appearance
22
+ -webkit-appearance: none;
23
+ appearance: none;
24
+
25
+ // Custom appearance
26
+ margin: 0 8px 0 0;
27
+ width: 16px;
28
+ height: 16px;
29
+ border: 1px solid #8a96a3;
30
+ border-radius: 2px;
31
+ background-color: #ffffff;
32
+ flex-shrink: 0;
33
+ }
34
+
35
+ // Hide checkmark initially
36
+ input[type='checkbox']::before {
37
+ display: none;
38
+ }
39
+
40
+ // Fill in background on check
41
+ input[type='checkbox']:checked {
42
+ background-color: #8a96a3;
43
+ }
44
+
45
+ // Display checkmark on check
46
+ input[type='checkbox']:checked::before {
47
+ display: block;
48
+ position: relative;
49
+ top: 7px;
50
+ left: 3px;
51
+ font-size: 9px;
52
+ line-height: 0;
53
+ color: #ffffff;
54
+
55
+ // genesys-dev-icons app-check
56
+ content: '\f103';
57
+ font-family: genesys-dev-icons !important;
58
+ font-style: normal;
59
+ font-weight: normal !important;
60
+ font-feature-settings: normal;
61
+ font-variant: normal;
62
+ text-transform: none;
63
+ -webkit-font-smoothing: antialiased;
64
+ -moz-osx-font-smoothing: grayscale;
65
+ }
66
+
67
+ // Hover - radio button
68
+ input[type='checkbox']:not(:disabled):hover {
69
+ border-color: #4d5061;
70
+ }
71
+
72
+ // Focus - radio button
73
+ input[type='checkbox']:not(:disabled):focus {
74
+ outline: #aac9ff solid 2px;
75
+ }
76
+ // Disable default focus outline
77
+ input[type='checkbox']:not(:disabled):focus-visible {
78
+ outline: 0;
79
+ }
80
+ input[type='radio'] {
81
+ // Hide default appearance
82
+ -webkit-appearance: none;
83
+ appearance: none;
84
+
85
+ // Custom appearance
86
+ margin: 0 8px 0 0;
87
+ width: 16px;
88
+ height: 16px;
89
+ border: 1px solid #8a96a3;
90
+ border-radius: 8px;
91
+ background-color: #ffffff;
92
+ flex-shrink: 0;
93
+ }
94
+
95
+ // Hide radio button initially
96
+ input[type='radio']::before {
97
+ display: none;
98
+ }
99
+
100
+ // Display filled radio button
101
+ input[type='radio']:checked::before {
102
+ content: '';
103
+ display: block;
104
+ width: 10px;
105
+ height: 10px;
106
+ border-radius: 8px;
107
+ position: relative;
108
+ top: 2px;
109
+ left: 2px;
110
+ background-color: #8a96a3;
111
+ }
112
+
113
+ // Hover - radio button
114
+ input[type='radio']:not(:disabled):hover {
115
+ border-color: #4d5061;
116
+ }
117
+
118
+ // Focus - radio button
119
+ input[type='radio']:not(:disabled):focus {
120
+ outline: #aac9ff solid 2px;
121
+ }
122
+ // Disable default focus outline
123
+ input[type='radio']:not(:disabled):focus-visible {
124
+ outline: 0;
125
+ }
126
+
127
+ &.disabled {
128
+ cursor: not-allowed;
129
+
130
+ input {
131
+ border-color: #e8eaed;
132
+ cursor: not-allowed;
133
+ }
134
+
135
+ // Fill in background on check
136
+ input:checked {
137
+ background-color: #e8eaed;
138
+ cursor: not-allowed;
139
+ }
140
+ }
141
+ }
142
+
143
+ .dx-label .dx-checkbox .label-text {
144
+ margin: 0;
145
+ }
@@ -0,0 +1,46 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { CheckedChangedCallback } from '..';
3
+
4
+ import './DxCheckbox.scss';
5
+
6
+ interface IProps {
7
+ label: string;
8
+ itemValue: string;
9
+ description?: string;
10
+ checked?: boolean;
11
+ initiallyChecked?: boolean;
12
+ name?: string;
13
+ className?: string;
14
+ onCheckChanged?: CheckedChangedCallback;
15
+ useRadioType?: boolean;
16
+ disabled?: boolean;
17
+ }
18
+
19
+ export default function DxCheckbox(props: IProps) {
20
+ let initialValue: boolean = props.checked !== undefined ? props.checked : props.initiallyChecked || false;
21
+
22
+ const [checked, setChecked] = useState<boolean>(initialValue);
23
+
24
+ useEffect(() => {
25
+ if (props.checked === undefined || props.checked === checked) return;
26
+ setChecked(props.checked);
27
+ }, [props.checked]);
28
+
29
+ useEffect(() => {
30
+ if (props.onCheckChanged) props.onCheckChanged(checked);
31
+ }, [checked]);
32
+
33
+ return (
34
+ <label className={`dx-checkbox${props.className ? ' ' + props.className : ''}${props.disabled ? ' disabled' : ''}`}>
35
+ <input
36
+ type={props.useRadioType ? 'radio' : 'checkbox'}
37
+ name={props.name}
38
+ value={props.itemValue}
39
+ checked={checked}
40
+ onChange={(e) => setChecked(e.target.checked)}
41
+ disabled={props.disabled === true}
42
+ />
43
+ <span className='label-text'>{props.label}</span>
44
+ </label>
45
+ );
46
+ }
@@ -0,0 +1,6 @@
1
+ .dx-item-group {
2
+ display: block;
3
+ border: 0;
4
+ margin: 0;
5
+ padding: 0;
6
+ }
@@ -0,0 +1,133 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { v4 as uuid } from 'uuid';
3
+ import { DxItemGroupItem, DxItemGroupItemValue, DxItemGroupProps, ItemChangedCallback, ItemGroupChangedCallback } from '..';
4
+
5
+ import './DxItemGroup.scss';
6
+ import './radiobutton.scss';
7
+ import './dropdown.scss';
8
+ import './multiselect.scss';
9
+ import DxLabel from '../dxlabel/DxLabel';
10
+ import DxCheckbox from './DxCheckbox';
11
+
12
+ export default function DxItemGroup(props: DxItemGroupProps) {
13
+ const [data, setData] = useState<DxItemGroupItemValue[]>(
14
+ props.items.map((item) => {
15
+ return { item, isSelected: item.isSelected !== undefined ? item.isSelected : false };
16
+ })
17
+ );
18
+ const [id] = useState(uuid());
19
+ const [title, setTitle] = useState(props.title);
20
+ const [description, setDescription] = useState(props.description);
21
+ const [format, setFormat] = useState(props.format);
22
+ const [disabled, setDisabled] = useState(props.disabled);
23
+ const [className, setClassName] = useState(props.className);
24
+
25
+ // data changed
26
+ useEffect(() => {
27
+ if (props.onItemsChanged) props.onItemsChanged(data);
28
+ // eslint-disable-next-line react-hooks/exhaustive-deps
29
+ }, [data]);
30
+
31
+ // Recalculate on props changed
32
+ useEffect(() => {
33
+ setTitle(props.title);
34
+ setDescription(props.description);
35
+ setFormat(props.format);
36
+ setDisabled(props.disabled);
37
+ setClassName(props.className);
38
+ }, [props.title, props.description, props.format, props.items, props.disabled, props.className]);
39
+
40
+ useEffect(() => {
41
+ setData(
42
+ props.items.map((item) => {
43
+ return { item, isSelected: item.isSelected !== undefined ? item.isSelected : false };
44
+ })
45
+ );
46
+ }, [props.items]);
47
+ // Handle individual item changed
48
+ const itemChanged = (idx: number, item: DxItemGroupItem, checked: boolean) => {
49
+ if (props.onItemChanged) props.onItemChanged(item, checked);
50
+ let newData = [...data];
51
+ // Unselect everything if it's radio buttons
52
+ if (format === 'radio') newData.forEach((value) => (value.isSelected = false));
53
+ // Set the selected state of the new item
54
+ newData[idx].isSelected = checked;
55
+ setData(newData);
56
+ };
57
+
58
+ const selectChanged = (e: React.ChangeEvent<HTMLSelectElement>) => {
59
+ const options = e.target.options;
60
+ let newData = [...data];
61
+ // Assign selected value for each item in the list
62
+ for (let i = 0; i < options.length; i++) {
63
+ const thisItem = newData.find((value) => value.item.value === options[i].value);
64
+ thisItem.isSelected = options[i].selected;
65
+ }
66
+ // Update entire data list
67
+ setData(newData);
68
+ // Trigger individual update
69
+ const changedItemIdx = newData.findIndex((value) => value.item.value === e.target.value);
70
+ if (changedItemIdx >= 0) itemChanged(changedItemIdx, newData[changedItemIdx].item, newData[changedItemIdx].isSelected);
71
+ };
72
+
73
+ switch (format) {
74
+ case 'multiselect':
75
+ case 'dropdown': {
76
+ const isMulti = format === 'multiselect';
77
+ return (
78
+ <DxLabel label={title} description={description} className={className}>
79
+ <div className={`dx-item-group${isMulti ? ' dx-multiselect-group' : ' dx-select-group'}${disabled ? ' disabled' : ''}`}>
80
+ <select
81
+ multiple={isMulti}
82
+ disabled={disabled === true}
83
+ onChange={(e) => selectChanged(e)}
84
+ value={
85
+ isMulti
86
+ ? data.filter((item) => item.isSelected)?.map((item) => item.item.value)
87
+ : data.find((item) => item.isSelected)?.item.value
88
+ }
89
+ >
90
+ {data.map((d, i) => (
91
+ <option key={i} value={d.item.value} disabled={d.item.disabled}>
92
+ {d.item.label}
93
+ </option>
94
+ ))}
95
+ </select>
96
+ </div>
97
+ </DxLabel>
98
+ );
99
+ }
100
+ case 'checkbox':
101
+ case 'radio':
102
+ default: {
103
+ return (
104
+ <DxLabel
105
+ label={title}
106
+ description={description}
107
+ className={`dx-item-group${disabled ? ' disabled' : ''}${className ? ' ' + className : ''}`}
108
+ useFieldset={true}
109
+ >
110
+ <div
111
+ onChange={(e: React.ChangeEvent<HTMLDivElement>) => {
112
+ const i = data.findIndex((d) => d.item.value === (e.target as any)?.value);
113
+ if (i < 0) return;
114
+ itemChanged(i, data[i].item, (e.target as any)?.checked);
115
+ }}
116
+ >
117
+ {data.map((d, i) => (
118
+ <DxCheckbox
119
+ key={d.item.value}
120
+ name={format === 'checkbox' ? `${id}-${d.item.value}` : id}
121
+ label={d.item.label}
122
+ itemValue={d.item.value}
123
+ checked={d.isSelected}
124
+ useRadioType={format === 'radio'}
125
+ disabled={disabled || d.item.disabled}
126
+ />
127
+ ))}
128
+ </div>
129
+ </DxLabel>
130
+ );
131
+ }
132
+ }
133
+ }
@@ -0,0 +1,53 @@
1
+ .dx-select-group {
2
+ appearance: none;
3
+ position: relative;
4
+
5
+ select {
6
+ border: 1px solid #8a96a3;
7
+ border-radius: 2px;
8
+ background-color: #ffffff;
9
+ font-style: normal;
10
+ font-weight: 300;
11
+ font-size: 12px;
12
+ line-height: 14px;
13
+ color: #75757a;
14
+ padding: 8px 32px 8px 12px;
15
+ width: 100%;
16
+ appearance: none;
17
+
18
+ &:focus-visible {
19
+ outline: 2px solid #aac9ff;
20
+ }
21
+ }
22
+
23
+ &::after {
24
+ position: absolute;
25
+ bottom: 12px;
26
+ right: 12px;
27
+ content: '\f104';
28
+ font-size: 8px;
29
+ font-family: genesys-dev-icons !important;
30
+ font-style: normal;
31
+ font-weight: normal !important;
32
+ font-feature-settings: normal;
33
+ font-variant: normal;
34
+ text-transform: none;
35
+ line-height: 1;
36
+ -webkit-font-smoothing: antialiased;
37
+ -moz-osx-font-smoothing: grayscale;
38
+ pointer-events: none;
39
+ }
40
+
41
+ &.disabled {
42
+ &::after {
43
+ color: #8a9a9e;
44
+ }
45
+
46
+ select:disabled {
47
+ background-color: #e6ebec;
48
+ border-color: #e8eaed;
49
+ color: #8a9a9e;
50
+ cursor: not-allowed;
51
+ }
52
+ }
53
+ }