groovinads-ui 1.2.74 → 1.9.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.
Files changed (90) hide show
  1. package/README.md +628 -236
  2. package/dist/index.es.js +2 -15
  3. package/dist/index.js +2 -15
  4. package/index.d.ts +364 -0
  5. package/package.json +87 -79
  6. package/.babelrc +0 -3
  7. package/.eslintignore +0 -2
  8. package/.eslintrc.cjs +0 -32
  9. package/.prettierignore +0 -9
  10. package/.prettierrc +0 -7
  11. package/.storybook/main.js +0 -19
  12. package/.storybook/preview-head.html +0 -6
  13. package/.storybook/preview.js +0 -13
  14. package/.yarn/releases/yarn-4.1.1.cjs +0 -893
  15. package/.yarnrc.yml +0 -3
  16. package/rollup.config.mjs +0 -42
  17. package/src/components/Button/Button.jsx +0 -78
  18. package/src/components/Button/index.js +0 -3
  19. package/src/components/Dropdowns/DropdownComponent.jsx +0 -135
  20. package/src/components/Dropdowns/DropdownFilter.jsx +0 -304
  21. package/src/components/Dropdowns/DropdownMultiSelect.jsx +0 -304
  22. package/src/components/Dropdowns/DropdownSimpleDatePicker.jsx +0 -175
  23. package/src/components/Dropdowns/DropdownsDatePicker/DropdownDatePicker.jsx +0 -313
  24. package/src/components/Dropdowns/DropdownsDatePicker/PeriodAndDetailDropdowns.tsx +0 -351
  25. package/src/components/Dropdowns/DropdownsDatePicker/index.js +0 -3
  26. package/src/components/Dropdowns/index.js +0 -7
  27. package/src/components/Inputs/Checkbox.jsx +0 -55
  28. package/src/components/Inputs/Input.jsx +0 -155
  29. package/src/components/Inputs/InputChip.jsx +0 -168
  30. package/src/components/Inputs/InputEmail.jsx +0 -175
  31. package/src/components/Inputs/Radio.jsx +0 -57
  32. package/src/components/Inputs/Switch.jsx +0 -70
  33. package/src/components/Inputs/Textarea.jsx +0 -68
  34. package/src/components/Inputs/index.js +0 -9
  35. package/src/components/Labels/Alert.jsx +0 -62
  36. package/src/components/Labels/Icon.jsx +0 -76
  37. package/src/components/Labels/LoginSource.jsx +0 -19
  38. package/src/components/Labels/PillComponent.jsx +0 -47
  39. package/src/components/Labels/Spinner.jsx +0 -35
  40. package/src/components/Labels/StatusIcon.jsx +0 -66
  41. package/src/components/Labels/index.js +0 -8
  42. package/src/components/Navigation/Dropdowns/DeckDropdown.jsx +0 -210
  43. package/src/components/Navigation/Dropdowns/DropdownClient.jsx +0 -171
  44. package/src/components/Navigation/Dropdowns/UserDropdown.jsx +0 -69
  45. package/src/components/Navigation/Dropdowns/index.js +0 -5
  46. package/src/components/Navigation/Navbar.jsx +0 -83
  47. package/src/components/Navigation/Sidebar.jsx +0 -201
  48. package/src/components/Navigation/Stepper.jsx +0 -22
  49. package/src/components/Navigation/Tabnav.jsx +0 -73
  50. package/src/components/Navigation/index.js +0 -6
  51. package/src/components/Toasts/Toast/ToastCardComponent.jsx +0 -47
  52. package/src/components/Toasts/ToastComponent.jsx +0 -45
  53. package/src/components/Toasts/ToastProgress.jsx +0 -118
  54. package/src/components/Toasts/index.js +0 -4
  55. package/src/components/index.js +0 -50
  56. package/src/hooks/index.js +0 -4
  57. package/src/hooks/useGetBaseDomain.jsx +0 -9
  58. package/src/hooks/useTextFormatter.jsx +0 -48
  59. package/src/index.js +0 -51
  60. package/src/services/components.services.js +0 -29
  61. package/src/services/helpers.js +0 -32
  62. package/src/services/index.jsx +0 -10
  63. package/src/services/url.path.js +0 -29
  64. package/src/stories/Alert.stories.jsx +0 -11
  65. package/src/stories/Button.stories.jsx +0 -20
  66. package/src/stories/Checkbox.stories.jsx +0 -17
  67. package/src/stories/DropdownComponent.stories.jsx +0 -89
  68. package/src/stories/DropdownDatePicker.stories.jsx +0 -69
  69. package/src/stories/DropdownFilter.stories.jsx +0 -60
  70. package/src/stories/DropdownMultiSelect.stories.jsx +0 -72
  71. package/src/stories/DropdownSimpleDatePicker.stories.jsx +0 -64
  72. package/src/stories/Icon.stories.jsx +0 -11
  73. package/src/stories/Input.stories.jsx +0 -20
  74. package/src/stories/InputChip.stories.jsx +0 -44
  75. package/src/stories/InputEmail.stories.jsx +0 -27
  76. package/src/stories/Layout.stories.jsx +0 -73
  77. package/src/stories/LoginSource.stories.jsx +0 -11
  78. package/src/stories/Navbar.stories.jsx +0 -24
  79. package/src/stories/PillComponent.stories.jsx +0 -22
  80. package/src/stories/Radio.stories.jsx +0 -18
  81. package/src/stories/Sidebar.stories.jsx +0 -169
  82. package/src/stories/Spinner.stories.jsx +0 -11
  83. package/src/stories/StatusIcon.stories.jsx +0 -11
  84. package/src/stories/Stepper.stories.jsx +0 -16
  85. package/src/stories/Switch.stories.jsx +0 -17
  86. package/src/stories/Tabnav.stories.jsx +0 -55
  87. package/src/stories/Textarea.stories.jsx +0 -20
  88. package/src/stories/ToastComponent.stories.jsx +0 -62
  89. package/src/stories/ToastProgress.stories.jsx +0 -11
  90. package/version.js +0 -8
@@ -1,55 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- // HOOKS
5
- import useTextFormatter from '../../hooks/useTextFormatter';
6
-
7
- // Checkbox
8
- const Checkbox = ({
9
- children,
10
- className = '',
11
- id,
12
- name,
13
- status = false,
14
- setStatus
15
- }) => {
16
- const { toCamelCase } = useTextFormatter();
17
-
18
- let checkboxId = id;
19
- if (!id && typeof children === 'string') {
20
- checkboxId = toCamelCase(children);
21
- }
22
-
23
- const handleChange = (event) => {
24
- setStatus(event.target.checked);
25
- };
26
-
27
- return (
28
- <div className={`form-group form-check ${className}`}>
29
- <label className='checkbox'>
30
- <input
31
- type='checkbox'
32
- checked={status}
33
- onChange={handleChange}
34
- minLength='1'
35
- id={checkboxId}
36
- name={name}
37
- />
38
- <span className='outer'>
39
- <span className='inner'></span>
40
- </span>
41
- {children}
42
- </label>
43
- </div>
44
- );
45
- };
46
-
47
- Checkbox.propTypes = {
48
- className: PropTypes.string,
49
- id: PropTypes.string,
50
- name: PropTypes.string,
51
- status: PropTypes.bool,
52
- setStatus: PropTypes.func,
53
- };
54
-
55
- export default Checkbox;
@@ -1,155 +0,0 @@
1
- import React, { useRef, useEffect } from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- // HOOKS
5
- import useTextFormatter from '../../hooks/useTextFormatter';
6
-
7
- // COMPONENTS
8
- import Icon from '../Labels/Icon';
9
-
10
- // Input
11
- const Input = ({
12
- autoFocus = false,
13
- className = '',
14
- focus=false,
15
- disabled,
16
- helpText,
17
- icon,
18
- label = 'Label',
19
- name,
20
- onChange,
21
- prefix,
22
- requiredText,
23
- showError,
24
- setShowError,
25
- size = 'md',
26
- suffix,
27
- type = 'text',
28
- value,
29
- min,
30
- max,
31
- maxLength,
32
- }) => {
33
- const { toCamelCase } = useTextFormatter();
34
- const inputRef = useRef(null);
35
-
36
- const id = toCamelCase(label);
37
-
38
- useEffect(() => {
39
- if (showError) {
40
- setTimeout(() => {
41
- setShowError(false);
42
- }, 3000);
43
- }
44
- }, [showError]);
45
-
46
- useEffect(() => {
47
- if(inputRef.current && focus) {
48
- inputRef.current.focus();
49
- }
50
- }, [focus])
51
-
52
- return (
53
- <div className={`position-relative ${className}`}>
54
- {prefix || suffix || icon ? (
55
- <div
56
- className={`input-group ${showError ? 'not-validated' : ''}`}
57
- data-error={requiredText}
58
- >
59
- {icon && (
60
- <span className='input-group-text'>
61
- <Icon
62
- style={'solid'}
63
- iconName={icon}
64
- scale={1}
65
- />
66
- </span>
67
- )}
68
- {prefix && <span className='input-group-text'>{prefix}</span>}
69
- <div className='form-floating'>
70
- <input
71
- type={type}
72
- className={`form-control ${size !== 'md' ? `form-control-${size}` : ''}`}
73
- value={value}
74
- id={id}
75
- name={name}
76
- placeholder={label}
77
- onChange={onChange}
78
- required={!!requiredText}
79
- autoFocus={autoFocus}
80
- ref={inputRef}
81
- min={min}
82
- max={max}
83
- />
84
- <label htmlFor={id}>{label}</label>
85
- </div>
86
- {suffix && <span className='input-group-text'>{suffix}</span>}
87
- </div>
88
- ) : (
89
- <div
90
- className={`form-floating ${showError ? 'not-validated' : ''}`}
91
- data-error={requiredText}
92
- >
93
- <input
94
- type={type}
95
- className={`form-control ${size !== 'md' ? `form-control-${size}` : ''}`}
96
- value={value}
97
- id={id}
98
- placeholder={label}
99
- onChange={onChange}
100
- required={!!requiredText}
101
- name={name}
102
- disabled={disabled}
103
- autoFocus={autoFocus}
104
- ref={inputRef}
105
- min={min}
106
- max={max}
107
- maxLength={maxLength}
108
- />
109
- <label htmlFor={id}>{label}</label>
110
- </div>
111
- )}
112
- {helpText && <small className='form-text text-muted'>{helpText}</small>}
113
- </div>
114
- );
115
- };
116
-
117
- Input.propTypes = {
118
- className: PropTypes.string,
119
- focus: PropTypes.bool,
120
- disabled: PropTypes.bool,
121
- helpText: PropTypes.string,
122
- icon: PropTypes.string,
123
- label: PropTypes.string,
124
- name: PropTypes.string,
125
- onChange: PropTypes.func,
126
- prefix: PropTypes.string,
127
- requiredText: PropTypes.string,
128
- size: PropTypes.oneOf(['xs', 'md', 'lg']),
129
- showError: PropTypes.bool,
130
- setShowError: PropTypes.func,
131
- suffix: PropTypes.string,
132
- type: PropTypes.oneOf([
133
- 'color',
134
- 'date',
135
- 'datetime-local',
136
- 'email',
137
- 'file',
138
- 'image',
139
- 'month',
140
- 'number',
141
- 'password',
142
- 'tel',
143
- 'text',
144
- 'time',
145
- 'url',
146
- 'week',
147
- ]),
148
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
149
- autoFocus: PropTypes.bool,
150
- min: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
151
- max: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
152
- maxLength: PropTypes.number,
153
- };
154
-
155
- export default Input;
@@ -1,168 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- // COMPONENTS
5
- import { PillComponent } from '../Labels';
6
-
7
- const InputChip = ({
8
- className ='',
9
- placeholder,
10
- keywordsList = [],
11
- setKeywordsList,
12
- pillColor = 'neutral',
13
- counter = false,
14
- maxKeywordLength, // max keyword length (each keyword).
15
- recomendedKeywords, // Num recomendedKeywords.
16
- maxKeywords, // maxKeywords (total array).
17
- requiredText, // requiered--> maxKeywordsList.
18
- duplicateKeywordErrorText
19
-
20
- }) => {
21
- // STATE
22
- const [inputValue, setInputValue] = useState('');
23
- const [error, setError] = useState('');
24
- const [showNotValidated, setShowNotValidated] = useState(false);
25
-
26
- // VARIABLES
27
- const strokeDasharray = 56.55
28
-
29
- // FUNCTIONS
30
- // ADD
31
- const handleKeyDown = (e) => {
32
- if (
33
- e.key === 'Enter' &&
34
- inputValue.trim() !== ''
35
- && keywordsList.length < maxKeywords
36
- ) {
37
- // MAX KEYWORD LENGTH
38
- if (inputValue.length > maxKeywordLength) {
39
- setError(`Each keyword must be ${maxKeywordLength} characters or less.`);
40
- setTimeout(() => setError(''), 2000);
41
- setInputValue('');
42
- return;
43
- }
44
- // CHECK IF DUPLICATE KEYWORD
45
- if (keywordsList.includes(inputValue.trim())) {
46
- setError(duplicateKeywordErrorText);
47
- setTimeout(() => setError(''), 2000);
48
- setInputValue('');
49
- return;
50
- }
51
-
52
- const newChipsList = [...keywordsList, inputValue.trim()];
53
- setKeywordsList(newChipsList);
54
- setInputValue('');
55
- }
56
- };
57
-
58
- // DELETE
59
- const handleDelete = (chipToDelete) => {
60
- const newChipsList = keywordsList.filter((chip) => chip !== chipToDelete);
61
- setKeywordsList(newChipsList);
62
- };
63
-
64
- useEffect(() => {
65
- if (keywordsList.length === maxKeywords) {
66
- setShowNotValidated(true);
67
- setTimeout(() => {
68
- setShowNotValidated(false);
69
- }, 3000);
70
- }
71
- }, [keywordsList]);
72
-
73
- return (
74
- <>
75
- <div className={`position-relative ${className}`}>
76
- <div className={`input-chip ${showNotValidated ? 'not-validated' : ''}`} data-error={requiredText}>
77
-
78
- <div className='wrapper'>
79
- {/* PILLS */}
80
- {keywordsList.map((chip, index) => (
81
- <PillComponent
82
- key={index}
83
- closeButton={true}
84
- color={
85
- pillColor
86
- }
87
- onClick={() => handleDelete(chip)}
88
- >
89
- {chip}
90
- </PillComponent>
91
- ))}
92
- </div>
93
-
94
- {/* INPUT */}
95
- <input
96
- type='text'
97
- value={inputValue}
98
- onKeyDown={handleKeyDown}
99
- onChange={(e) => {
100
- setInputValue(e.target.value);
101
- }}
102
- placeholder={placeholder}
103
- />
104
-
105
- {/* KEYWORDS COUNTER */}
106
- {counter && keywordsList.length >= recomendedKeywords && (
107
- <div className={`progress-counter-wrapper ${
108
- keywordsList.length >= maxKeywords
109
- ? 'progress-value-error'
110
- : keywordsList.length >= recomendedKeywords
111
- ? 'progress-value-warning'
112
- : ''
113
- }`}
114
- >
115
- <svg
116
- width='20'
117
- height='20'
118
- viewBox='0 0 20 20'
119
- xmlns='http://www.w3.org/2000/svg'
120
- className='progress-counter'
121
- >
122
- <circle
123
- className='progress-bg'
124
- cx='10'
125
- cy='10'
126
- r='9'
127
- fill='none'
128
- />
129
-
130
- <circle
131
- className='progress-value'
132
- cx='10'
133
- cy='10'
134
- r='9'
135
- strokeDasharray={strokeDasharray}
136
- strokeDashoffset={strokeDasharray * (1 - keywordsList.length / maxKeywords)}
137
- strokeLinecap='round'
138
- fill='none'
139
- />
140
- </svg>
141
- <span className='progress-counter-text'>
142
- {keywordsList.length}
143
- </span>
144
- </div>
145
- )}
146
- </div>
147
-
148
- {/* ERROR MESSAGGE */}
149
- {error && <small className='form-text text-muted'>{error}</small>}
150
- </div>
151
- </>
152
- );
153
- };
154
-
155
- InputChip.propTypes = {
156
- className: PropTypes.string,
157
- placeholder: PropTypes.string.isRequired,
158
- keywordsList: PropTypes.array.isRequired,
159
- setKeywordsList: PropTypes.func.isRequired,
160
- maxKeywordLength: PropTypes.number.isRequired,
161
- pillColor: PropTypes.oneOf(['blue', 'danger', 'dark', 'green', 'light', 'midtone', 'neutral', 'red', 'yellow']),
162
- maxKeywords: PropTypes.number.isRequired,
163
- requiredText: PropTypes.string.isRequired,
164
- counter: PropTypes.bool,
165
- duplicateKeywordErrorText: PropTypes.string,
166
- };
167
-
168
- export default InputChip;
@@ -1,175 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- // COMPONENTS GROOVINADS
5
- import Input from './Input';
6
- import { Button } from '../Button';
7
-
8
- import { ComponentsService } from '../../services';
9
- import { Icon, Spinner } from '../Labels';
10
-
11
- const InputEmail = ({
12
- showModal = true,
13
- titleList = 'Added emails',
14
- label = 'Email addresses',
15
- textButton = 'Add',
16
- textError = 'You must enter a valid email address',
17
- apiGetEmail,
18
- apiPostEmail,
19
- }) => {
20
- // STATE
21
- const [notifications, setNotifications] = useState([]);
22
- const [newEmail, setNewEmail] = useState('');
23
-
24
- const [selectedButton, setSelectedButton] = useState([]);
25
-
26
- const [emailInvalid, setEmailInvalid] = useState(false);
27
-
28
- // VARIABLES
29
- const validEmailPattern = /^\w+([.-_+]?\w+)*@\w+([.-]?\w+)*(\.\w{2,10})+$/;
30
-
31
- // GET, Returns a list of emails
32
- const fetchNotifications = async () => {
33
- const resp = await ComponentsService.getInfo(apiGetEmail);
34
- setNotifications(resp || []);
35
-
36
- };
37
-
38
- // POST, Receives a list of emails
39
- const handleAddEmail = async () => {
40
- const emails = newEmail
41
- .split(/[;, ]+/)
42
- .map((email) => email.trim())
43
- .filter((email) => email.length > 0);
44
-
45
- // Filter invalid emails
46
- const invalidEmails = emails.filter(
47
- (email) => !validEmailPattern.test(email),
48
- );
49
- const validEmails = emails.filter((email) => validEmailPattern.test(email));
50
-
51
- if (invalidEmails.length) {
52
- setNewEmail(invalidEmails.join(' ')); // if there are multiple invalid emails, they are joined in the array and separated by a space
53
- setEmailInvalid(true);
54
- setTimeout(() => {
55
- setEmailInvalid(false);
56
- }, 3000);
57
- }
58
-
59
- // update total list of emails validated
60
- if (validEmails.length) {
61
- const resp = await ComponentsService.postInfo(apiPostEmail, [
62
- ...notifications,
63
- ...validEmails,
64
- ]);
65
- setNotifications(resp);
66
- }
67
- setNewEmail(invalidEmails.join(' '));
68
- };
69
-
70
- const handleInputChange = (e) => {
71
- const value = e.target.value.replace(/\. +/g, ' '); // removes the dot and space, replacing it with ' '
72
- setNewEmail(value);
73
-
74
- if (!value.trim() || validEmailPattern.test(value)) {
75
- setEmailInvalid(false);
76
- }
77
- };
78
-
79
- // DELETE, Receives a list of emails
80
- const handleDeleteEmail = async (emailToDelete) => {
81
- setSelectedButton([...selectedButton, emailToDelete]);
82
-
83
- const emailDeletedList = notifications.filter(
84
- (email) => email !== emailToDelete,
85
- )
86
-
87
- const resp = await ComponentsService.postInfo(
88
- apiPostEmail,
89
- emailDeletedList,
90
- );
91
-
92
- setTimeout(() => {
93
- setSelectedButton(
94
- selectedButton.filter((email) => email !== emailToDelete),
95
- );
96
- setNotifications(resp);
97
- }, 1000);
98
- };
99
-
100
- useEffect(() => {
101
- if (showModal) {
102
- fetchNotifications();
103
- } else if(notifications.length){
104
- setNotifications([]);
105
- }
106
- }, [showModal]);
107
- return (
108
- <>
109
- {/* SECTIONS ADD EMAILS */}
110
- <div className={'mb-3'}>
111
- <div
112
- className={`mb-3 input-group w-100 mb-4 ${
113
- emailInvalid ? 'not-validated' : ''
114
- }`}
115
- data-error={textError}
116
- >
117
- <Input
118
- label={label}
119
- value={newEmail}
120
- onChange={(e) => {
121
- handleInputChange(e);
122
- }}
123
- />
124
- {/* ADD BUTTON */}
125
- <Button
126
- onClick={handleAddEmail}
127
- className={`${newEmail.trim() ? '' : 'disabled'}`}
128
- >
129
- {textButton}
130
- </Button>
131
- </div>
132
- </div>
133
- {/* SECTIONS LIST ADDED EMAILS */}
134
- {notifications?.length ? (
135
- <div className='shared-users-list'>
136
- <h3>{titleList}</h3>
137
- {notifications?.map((email, index) => (
138
- <div key={`email${index}`} className='shared-user-item'>
139
- <div className='shared-user'>
140
- <Icon iconName='user-circle' scale={2} />
141
- <span>{email}</span>
142
- </div>
143
- {selectedButton.some(
144
- (selectedEmail) => selectedEmail === email,
145
- ) ? (
146
- <div className='spinner-wrapper'>
147
- <Spinner scale={1} />
148
- </div>
149
- ) : (
150
- <Button
151
- variant='terciary'
152
- style='danger'
153
- icon='trash-can'
154
- onClick={() => handleDeleteEmail(email)}
155
- />
156
- )}
157
- </div>
158
- ))}
159
- </div>
160
- ) : null}
161
- </>
162
- );
163
- };
164
-
165
- InputEmail.propTypes = {
166
- showModal: PropTypes.bool,
167
- apiGetEmail: PropTypes.string.isRequired,
168
- apiPostEmail: PropTypes.string.isRequired,
169
- titleList: PropTypes.string,
170
- label: PropTypes.string,
171
- textButton: PropTypes.string,
172
- textError: PropTypes.string,
173
- };
174
-
175
- export default InputEmail;
@@ -1,57 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- // HOOKS
5
- import useTextFormatter from '../../hooks/useTextFormatter';
6
-
7
- // Radio
8
- const Radio = ({
9
- children,
10
- className = '',
11
- id,
12
- fullWidth = false,
13
- name,
14
- setStatus,
15
- status = false,
16
- }) => {
17
- const { toCamelCase } = useTextFormatter();
18
-
19
- let RadioId = id;
20
- if (!id && typeof children === 'string') {
21
- RadioId = toCamelCase(children);
22
- }
23
-
24
- const handleChange = (event) => {
25
- setStatus(event.target.checked);
26
- };
27
-
28
- return (
29
- <div className={`form-group form-check ${className}`}>
30
- <label className={`radio ${fullWidth ? 'w-100' : ''}`}>
31
- <input
32
- type='radio'
33
- checked={status}
34
- onChange={handleChange}
35
- minLength='1'
36
- id={RadioId}
37
- name={name}
38
- />
39
- <span className='outer'>
40
- <span className='inner'></span>
41
- </span>
42
- {children}
43
- </label>
44
- </div>
45
- );
46
- };
47
-
48
- Radio.propTypes = {
49
- className: PropTypes.string,
50
- id: PropTypes.string,
51
- fullWidth: PropTypes.bool,
52
- name: PropTypes.string,
53
- setStatus: PropTypes.func,
54
- status: PropTypes.bool,
55
- };
56
-
57
- export default Radio;
@@ -1,70 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
-
4
- // HOOKS
5
- import useTextFormatter from '../../hooks/useTextFormatter';
6
-
7
- const Switch = ({
8
- children,
9
- className = '',
10
- icon = false,
11
- id,
12
- name,
13
- size,
14
- setStatus,
15
- status = 0,
16
- switchPosition = 'start'
17
- }) => {
18
- const { toCamelCase } = useTextFormatter();
19
-
20
- const sizeClass =
21
- size === 'lg' ? 'form-switch-lg' : size === 'xs' ? 'form-switch-xs' : '';
22
-
23
- const inputId = id ? id : toCamelCase(children);
24
-
25
- const handleChange = () => {
26
- if (typeof status === 'boolean') {
27
- return setStatus(!status);
28
- } else {
29
- setStatus(status ? 0 : 1);
30
- }
31
- };
32
-
33
- return (
34
- <div
35
- className={`form-check form-switch ${sizeClass} ${className} ${
36
- switchPosition === 'end' ? 'switch-end' : ''
37
- } ${icon ? 'switch-icon' : ''}`}
38
- >
39
- <input
40
- className='form-check-input'
41
- type='checkbox'
42
- role='switch'
43
- onChange={handleChange}
44
- id={inputId}
45
- name={name}
46
- checked={!!status}
47
- />
48
- {children && (
49
- <label className='form-check-label' htmlFor={inputId}>
50
- {children}
51
- </label>
52
- )}
53
- </div>
54
- );
55
- };
56
-
57
- Switch.propTypes = {
58
- className: PropTypes.string,
59
- icon: PropTypes.bool,
60
- id: PropTypes.string,
61
- name: PropTypes.string,
62
- setStatus: PropTypes.func,
63
- status: PropTypes.oneOfType([
64
- PropTypes.number,
65
- PropTypes.bool
66
- ]),
67
- switchPosition: PropTypes.oneOf(['start', 'end']),
68
- };
69
-
70
- export default Switch;