@redocly/theme 0.25.2 → 0.26.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 (78) hide show
  1. package/lib/components/Feedback/Comment.d.ts +1 -1
  2. package/lib/components/Feedback/Comment.js +28 -9
  3. package/lib/components/Feedback/Emotions.js +8 -25
  4. package/lib/components/Feedback/Feedback.js +6 -0
  5. package/lib/components/Feedback/Mood.js +115 -47
  6. package/lib/components/Feedback/Rating.d.ts +1 -0
  7. package/lib/components/Feedback/Rating.js +81 -42
  8. package/lib/components/Feedback/Reasons.d.ts +1 -1
  9. package/lib/components/Feedback/Reasons.js +4 -16
  10. package/lib/components/Feedback/Scale.d.ts +4 -0
  11. package/lib/components/Feedback/Scale.js +178 -0
  12. package/lib/components/Feedback/Sentiment.js +105 -35
  13. package/lib/components/Feedback/Stars.d.ts +8 -0
  14. package/lib/components/Feedback/Stars.js +54 -0
  15. package/lib/components/Feedback/Thumbs.d.ts +2 -6
  16. package/lib/components/Feedback/Thumbs.js +9 -46
  17. package/lib/components/Feedback/index.d.ts +1 -0
  18. package/lib/components/Feedback/index.js +3 -1
  19. package/lib/components/Feedback/types.d.ts +26 -5
  20. package/lib/components/Feedback/useReportDialog.js +3 -1
  21. package/lib/components/Markdown/MarkdownLayout.js +1 -0
  22. package/lib/components/Markdown/styledVariables.js +54 -0
  23. package/lib/components/Tabs/Tab.js +30 -6
  24. package/lib/components/Tabs/Tabs.js +22 -8
  25. package/lib/config.d.ts +7 -4
  26. package/lib/config.js +3 -2
  27. package/lib/icons/CheckboxIcon/CheckboxIcon.js +3 -3
  28. package/lib/icons/ColorModeIcon/ColorModeIcon.js +4 -4
  29. package/lib/icons/DissatisfiedIcon/DissatisfiedIcon.js +5 -5
  30. package/lib/icons/NeutralIcon/NeutralIcon.js +5 -5
  31. package/lib/icons/RadioCheckButtonIcon/RadioCheckButtonIcon.d.ts +4 -0
  32. package/lib/icons/RadioCheckButtonIcon/RadioCheckButtonIcon.js +16 -0
  33. package/lib/icons/RadioCheckButtonIcon/index.d.ts +1 -0
  34. package/lib/icons/RadioCheckButtonIcon/index.js +18 -0
  35. package/lib/icons/SatisfiedIcon/SatisfiedIcon.js +5 -5
  36. package/lib/icons/ThumbDownIcon/ThumbDownIcon.d.ts +4 -0
  37. package/lib/icons/ThumbDownIcon/ThumbDownIcon.js +14 -0
  38. package/lib/icons/ThumbDownIcon/index.d.ts +1 -0
  39. package/lib/icons/ThumbDownIcon/index.js +18 -0
  40. package/lib/icons/ThumbUpIcon/ThumbUpIcon.d.ts +4 -0
  41. package/lib/icons/ThumbUpIcon/ThumbUpIcon.js +14 -0
  42. package/lib/icons/ThumbUpIcon/index.d.ts +1 -0
  43. package/lib/icons/ThumbUpIcon/index.js +18 -0
  44. package/lib/types/portal/src/shared/constants.d.ts +2 -1
  45. package/lib/types/portal/src/shared/constants.js +1 -0
  46. package/lib/types/portal/src/shared/types/feedback.d.ts +2 -2
  47. package/package.json +2 -2
  48. package/src/components/Feedback/Comment.tsx +53 -20
  49. package/src/components/Feedback/Emotions.tsx +11 -32
  50. package/src/components/Feedback/Feedback.tsx +13 -1
  51. package/src/components/Feedback/Mood.tsx +164 -80
  52. package/src/components/Feedback/Rating.tsx +106 -79
  53. package/src/components/Feedback/Reasons.tsx +3 -19
  54. package/src/components/Feedback/Scale.tsx +229 -0
  55. package/src/components/Feedback/Sentiment.tsx +150 -56
  56. package/src/components/Feedback/Stars.tsx +51 -0
  57. package/src/components/Feedback/Thumbs.tsx +9 -106
  58. package/src/components/Feedback/index.ts +1 -0
  59. package/src/components/Feedback/types.ts +23 -4
  60. package/src/components/Feedback/useReportDialog.ts +3 -1
  61. package/src/components/Markdown/MarkdownLayout.tsx +1 -0
  62. package/src/components/Markdown/styledVariables.ts +54 -0
  63. package/src/components/Tabs/Tab.tsx +30 -6
  64. package/src/components/Tabs/Tabs.tsx +22 -8
  65. package/src/config.ts +3 -2
  66. package/src/icons/CheckboxIcon/CheckboxIcon.tsx +4 -4
  67. package/src/icons/ColorModeIcon/ColorModeIcon.tsx +4 -4
  68. package/src/icons/DissatisfiedIcon/DissatisfiedIcon.tsx +5 -15
  69. package/src/icons/NeutralIcon/NeutralIcon.tsx +5 -14
  70. package/src/icons/RadioCheckButtonIcon/RadioCheckButtonIcon.tsx +19 -0
  71. package/src/icons/RadioCheckButtonIcon/index.ts +1 -0
  72. package/src/icons/SatisfiedIcon/SatisfiedIcon.tsx +5 -9
  73. package/src/icons/ThumbDownIcon/ThumbDownIcon.tsx +15 -0
  74. package/src/icons/ThumbDownIcon/index.ts +1 -0
  75. package/src/icons/ThumbUpIcon/ThumbUpIcon.tsx +15 -0
  76. package/src/icons/ThumbUpIcon/index.ts +1 -0
  77. package/src/types/portal/src/shared/constants.ts +1 -0
  78. package/src/types/portal/src/shared/types/feedback.ts +2 -2
@@ -1,61 +1,48 @@
1
1
  import * as React from 'react';
2
2
  import styled from 'styled-components';
3
+ import { useEffect } from 'react';
3
4
 
4
5
  import type { RatingProps, ReasonsProps } from '@theme/components/Feedback';
5
6
  import { Comment, Reasons } from '@theme/components/Feedback';
7
+ import { Button } from '@theme/components';
6
8
  import { useTranslate } from '@portal/hooks';
9
+ import { RadioCheckButtonIcon } from '@theme/icons/RadioCheckButtonIcon';
10
+ import { breakpoints } from '@portal/media-css';
7
11
 
8
- type StarsProps = {
9
- onSubmit: (value: number) => void;
10
- max: number;
11
- };
12
+ import { Stars } from './Stars';
13
+
14
+ export const FEEDBACK_MAX_RATING = 5;
12
15
 
13
16
  export const Rating = ({ settings, onSubmit, className }: RatingProps): JSX.Element => {
14
- const {
15
- label,
16
- max,
17
- submitText,
18
- comment: commentSettings,
19
- reasons: reasonsSettings,
20
- } = settings || {};
17
+ const { label, submitText, comment: commentSettings, reasons: reasonsSettings } = settings || {};
21
18
  const [isSubmitted, setIsSubmitted] = React.useState(false);
22
19
  const [score, setScore] = React.useState(0);
23
- const [comment, setComment] = React.useState('');
24
20
  const [reasons, setReasons] = React.useState([] as ReasonsProps['settings']['items']);
21
+ const [comment, setComment] = React.useState('');
25
22
  const { translate } = useTranslate();
26
- const maxRating = max || 5;
27
23
 
28
- if (score && reasonsSettings?.enable && !reasons.length) {
29
- const { label: reasonsLabel, items, multi } = reasonsSettings;
30
- const buttonText = commentSettings?.enable ? 'Next' : 'Send';
31
- return (
32
- <Reasons
33
- onSubmit={({ reasons }) => setReasons(reasons)}
34
- settings={{ label: reasonsLabel, items, multi, buttonText }}
35
- />
36
- );
37
- }
24
+ const onSubmitRatingForm = () => {
25
+ onSubmit({
26
+ score,
27
+ comment,
28
+ reasons,
29
+ max: FEEDBACK_MAX_RATING,
30
+ });
31
+ setIsSubmitted(true);
32
+ };
38
33
 
39
- if (score && commentSettings?.enable && !comment) {
40
- return (
41
- <Comment
42
- onSubmit={({ comment }) => setComment(comment)}
43
- settings={{ label: commentSettings.label }}
44
- />
45
- );
46
- }
34
+ const displayReasons = !!score && reasonsSettings?.enable;
35
+ const displayComment = !!score && commentSettings?.enable;
36
+ const displaySubmitBnt = !!score && (displayReasons || displayComment);
47
37
 
48
- if (score) {
49
- if (!isSubmitted) {
50
- onSubmit({
51
- score,
52
- comment,
53
- reasons,
54
- max: maxRating,
55
- });
56
- setIsSubmitted(true);
38
+ useEffect(() => {
39
+ if (score && !displayComment && !displayReasons) {
40
+ onSubmitRatingForm();
57
41
  }
42
+ // eslint-disable-next-line react-hooks/exhaustive-deps
43
+ }, [score, displayComment, displayReasons]);
58
44
 
45
+ if (isSubmitted) {
59
46
  return (
60
47
  <Wrapper>
61
48
  <Label data-translation-key="theme.feedback.settings.submitText">
@@ -64,64 +51,104 @@ export const Rating = ({ settings, onSubmit, className }: RatingProps): JSX.Elem
64
51
  submitText || 'Thank you for helping improve our documentation!',
65
52
  )}
66
53
  </Label>
54
+ <RadioCheckButtonIcon />
67
55
  </Wrapper>
68
56
  );
69
57
  }
70
58
 
71
59
  return (
72
60
  <Wrapper data-component-name="Feedback/Rating" className={className}>
73
- <Label data-translation-key="theme.feedback.settings.label">
74
- {translate('theme.feedback.settings.label', label || 'How helpful was this page?')}
75
- </Label>
76
- <Stars max={maxRating} onSubmit={setScore} />
61
+ <StyledForm>
62
+ <StyledFormMandatoryFields>
63
+ <Label data-translation-key="theme.feedback.settings.label">
64
+ {translate('theme.feedback.settings.label', label || 'How helpful was this page?')}
65
+ </Label>
66
+
67
+ <StyledMandatoryFieldContainer>
68
+ <Stars max={FEEDBACK_MAX_RATING} onChange={setScore} value={score} />
69
+ </StyledMandatoryFieldContainer>
70
+ </StyledFormMandatoryFields>
71
+
72
+ <StyledFormOptionalFields>
73
+ {displayReasons && (
74
+ <Reasons
75
+ settings={{
76
+ label: reasonsSettings?.label,
77
+ items: reasonsSettings?.items || [],
78
+ multi: reasonsSettings?.multi,
79
+ }}
80
+ onChange={setReasons}
81
+ />
82
+ )}
83
+
84
+ {displayComment && (
85
+ <Comment
86
+ standAlone={false}
87
+ onSubmit={({ comment }) => setComment(comment)}
88
+ settings={{ label: commentSettings.label }}
89
+ />
90
+ )}
91
+ </StyledFormOptionalFields>
92
+ {displaySubmitBnt && (
93
+ <ButtonsContainer>
94
+ <SubmitButton onClick={onSubmitRatingForm}>Submit</SubmitButton>
95
+ </ButtonsContainer>
96
+ )}
97
+ </StyledForm>
77
98
  </Wrapper>
78
99
  );
79
100
  };
80
101
 
81
- const Stars = ({ max, onSubmit }: StarsProps): JSX.Element => {
82
- const [hovered, setHovered] = React.useState(0);
83
- const stars: JSX.Element[] = [];
84
-
85
- for (let index = 1; index <= max; index++) {
86
- stars.push(
87
- <Star
88
- key={index}
89
- onClick={() => onSubmit(index)}
90
- onMouseOver={() => setHovered(index)}
91
- onMouseLeave={() => setHovered(0)}
92
- >
93
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
94
- {hovered < index ? (
95
- <g fill="#e8c002">
96
- <path d="M20 7h-7L10 .5 7 7H0l5.46 5.47-1.64 7 6.18-3.7 6.18 3.73-1.63-7zm-10 6.9-3.76 2.27 1-4.28L3.5 8.5h4.61L10 4.6l1.9 3.9h4.6l-3.73 3.4 1 4.28z" />
97
- </g>
98
- ) : (
99
- <g fill="#e8c002">
100
- <path d="M20 7h-7L10 .5 7 7H0l5.46 5.47-1.64 7 6.18-3.7 6.18 3.73-1.63-7z" />
101
- </g>
102
- )}
103
- </svg>
104
- </Star>,
105
- );
106
- }
102
+ const StyledForm = styled.form`
103
+ width: 100%;
104
+ `;
107
105
 
108
- return <>{stars}</>;
109
- };
106
+ const StyledFormOptionalFields = styled.div`
107
+ display: flex;
108
+ flex-flow: column;
109
+ `;
110
+
111
+ const StyledFormMandatoryFields = styled.div`
112
+ display: flex;
113
+ justify-content: space-between;
114
+ `;
115
+
116
+ const StyledMandatoryFieldContainer = styled.div`
117
+ display: flex;
118
+ `;
110
119
 
111
120
  const Wrapper = styled.div`
112
121
  display: flex;
122
+ justify-content: space-between;
113
123
  align-items: center;
114
- `;
124
+ padding: 16px 24px;
125
+ width: 424px;
126
+ border-radius: 8px;
127
+ background: var(--bg-raised);
115
128
 
116
- const Star = styled.span`
117
- cursor: pointer;
129
+ @media screen and (max-width: ${breakpoints.small}) {
130
+ width: 100%;
131
+ }
118
132
  `;
119
133
 
120
134
  const Label = styled.h3`
121
135
  margin-right: 15px;
122
- font-family: var(--h3-font-family);
123
- font-weight: var(--h3-font-weight);
124
- font-size: var(--h3-font-size);
125
- line-height: var(--h3-line-height);
136
+ font-family: var(--h4-font-family);
137
+ font-weight: var(--h4-font-weight);
138
+ font-size: var(--h4-font-size);
139
+ line-height: var(--h4-line-height);
126
140
  color: var(--h3-text-color);
127
141
  `;
142
+
143
+ const SubmitButton = styled(Button).attrs(() => ({
144
+ color: 'primary',
145
+ }))`
146
+ width: 100px;
147
+ margin-left: 0;
148
+ margin-right: 0;
149
+ `;
150
+
151
+ const ButtonsContainer = styled.div`
152
+ display: flex;
153
+ justify-content: end;
154
+ `;
@@ -1,12 +1,11 @@
1
1
  import * as React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
- import { Button } from '@theme/components/Button/Button';
5
4
  import type { ReasonsProps } from '@theme/components/Feedback';
6
5
  import { useTranslate } from '@portal/hooks';
7
6
 
8
- export const Reasons = ({ settings, onSubmit, className }: ReasonsProps): JSX.Element => {
9
- const { label, multi, buttonText, items = [] } = settings;
7
+ export const Reasons = ({ settings, onChange, className }: ReasonsProps): JSX.Element => {
8
+ const { label, multi, items = [] } = settings;
10
9
  const [checkedState, setCheckedState] = React.useState(new Array(items.length).fill(false));
11
10
  const { translate } = useTranslate();
12
11
 
@@ -20,12 +19,9 @@ export const Reasons = ({ settings, onSubmit, className }: ReasonsProps): JSX.El
20
19
  const updatedCheckedState = multi
21
20
  ? checkedState.map((item, index) => (index === position ? !item : item))
22
21
  : items.map((_, idx) => position === idx);
23
-
24
22
  setCheckedState(updatedCheckedState);
25
- };
26
23
 
27
- const submitForm = () => {
28
- onSubmit({ reasons: items.filter((_, index) => !!checkedState[index]) });
24
+ onChange(items.filter((_, index) => !!updatedCheckedState[index]));
29
25
  };
30
26
 
31
27
  return (
@@ -58,9 +54,6 @@ export const Reasons = ({ settings, onSubmit, className }: ReasonsProps): JSX.El
58
54
  </label>
59
55
  </OptionWrapper>
60
56
  ))}
61
- <SendButton data-translation-key="theme.feedback.settings.reasons.send" onClick={submitForm}>
62
- {translate('theme.feedback.settings.reasons.send', buttonText || 'Send')}
63
- </SendButton>
64
57
  </Wrapper>
65
58
  );
66
59
  };
@@ -80,15 +73,6 @@ const Label = styled.h3`
80
73
  margin-right: 15px;
81
74
  `;
82
75
 
83
- const SendButton = styled(Button).attrs(() => ({
84
- color: 'primary',
85
- }))`
86
- width: 100px;
87
- margin-left: 0;
88
- margin-right: 0;
89
- margin-top: 15px;
90
- `;
91
-
92
76
  const OptionWrapper = styled.div`
93
77
  margin: 5px 0;
94
78
  display: flex;
@@ -0,0 +1,229 @@
1
+ import * as React from 'react';
2
+ import { useEffect } from 'react';
3
+ import styled from 'styled-components';
4
+
5
+ import type { ScaleProps, ReasonsProps } from '@theme/components/';
6
+ import { useTranslate } from '@portal/hooks';
7
+ import { breakpoints } from '@portal/media-css';
8
+ import { Comment, Reasons } from '@theme/components/Feedback';
9
+ import { RadioCheckButtonIcon } from '@theme/icons/RadioCheckButtonIcon';
10
+ import { Button } from '@theme/components';
11
+
12
+ export const MAX_SCALE = 10;
13
+
14
+ export const Scale = ({ settings, onSubmit, className }: ScaleProps): JSX.Element => {
15
+ const {
16
+ label,
17
+ submitText,
18
+ leftScaleLabel,
19
+ rightScaleLabel,
20
+ comment: commentSettings,
21
+ reasons: reasonsSettings,
22
+ } = settings || {};
23
+ const [score, setScore] = React.useState(0);
24
+ const [isSubmitted, setIsSubmitted] = React.useState(false);
25
+ const [comment, setComment] = React.useState('');
26
+ const [reasons, setReasons] = React.useState([] as ReasonsProps['settings']['items']);
27
+ const { translate } = useTranslate();
28
+
29
+ const scaleOptions = [];
30
+
31
+ for (let i = 1; i <= MAX_SCALE; i++) {
32
+ scaleOptions.push(
33
+ <ScaleOption
34
+ id={`scale-option-${i}`}
35
+ key={`scale-option-${i}`}
36
+ onClick={() => setScore(i)}
37
+ className={`${score === i ? 'active' : ''}`}
38
+ >
39
+ {i}
40
+ </ScaleOption>,
41
+ );
42
+ }
43
+
44
+ const displayReasons = !!score && reasonsSettings?.enable;
45
+ const displayComment = !!score && commentSettings?.enable;
46
+ const displaySubmitBnt = !!score && (displayReasons || displayComment);
47
+
48
+ const onSubmitScaleForm = () => {
49
+ onSubmit({
50
+ score,
51
+ comment,
52
+ reasons,
53
+ max: MAX_SCALE,
54
+ });
55
+ setIsSubmitted(true);
56
+ };
57
+
58
+ useEffect(() => {
59
+ if (score && !displayComment && !displayReasons) {
60
+ onSubmitScaleForm();
61
+ }
62
+ // eslint-disable-next-line react-hooks/exhaustive-deps
63
+ }, [score, displayComment, displayReasons]);
64
+
65
+ if (isSubmitted) {
66
+ return (
67
+ <Wrapper>
68
+ <Label data-translation-key="theme.feedback.settings.submitText">
69
+ {translate(
70
+ 'theme.feedback.settings.submitText',
71
+ submitText || 'Thank you for helping improve our documentation!',
72
+ )}
73
+ </Label>
74
+ <RadioCheckButtonIcon />
75
+ </Wrapper>
76
+ );
77
+ }
78
+
79
+ return (
80
+ <Wrapper data-component-name="Feedback/Scale" className={className}>
81
+ <StyledForm>
82
+ <StyledFormMandatoryFields>
83
+ <Label data-translation-key="theme.feedback.settings.label">
84
+ {translate('theme.feedback.settings.label', label || 'How helpful was this page?')}
85
+ </Label>
86
+
87
+ <ScaleWrapper>{scaleOptions}</ScaleWrapper>
88
+
89
+ <SubLabelContainer>
90
+ <SubLabel data-translation-key="theme.feedback.settings.leftScaleLabel">
91
+ {translate(
92
+ 'theme.feedback.settings.leftScaleLabel',
93
+ leftScaleLabel || 'Not helpful at all',
94
+ )}
95
+ </SubLabel>
96
+ <SubLabel data-translation-key="theme.feedback.settings.rightScaleLabel">
97
+ {translate(
98
+ 'theme.feedback.settings.rightScaleLabel',
99
+ rightScaleLabel || 'Extremely helpful',
100
+ )}
101
+ </SubLabel>
102
+ </SubLabelContainer>
103
+ </StyledFormMandatoryFields>
104
+ <StyledFormOptionalFields>
105
+ {displayReasons && (
106
+ <Reasons
107
+ settings={{
108
+ label: reasonsSettings?.label,
109
+ items: reasonsSettings?.items || [],
110
+ multi: reasonsSettings?.multi,
111
+ }}
112
+ onChange={setReasons}
113
+ />
114
+ )}
115
+
116
+ {displayComment && (
117
+ <Comment
118
+ standAlone={false}
119
+ onSubmit={({ comment }) => setComment(comment)}
120
+ settings={{ label: commentSettings.label }}
121
+ />
122
+ )}
123
+ </StyledFormOptionalFields>
124
+ {displaySubmitBnt && (
125
+ <ButtonsContainer>
126
+ <SubmitButton onClick={onSubmitScaleForm}>Submit</SubmitButton>
127
+ </ButtonsContainer>
128
+ )}
129
+ </StyledForm>
130
+ </Wrapper>
131
+ );
132
+ };
133
+
134
+ const Wrapper = styled.div`
135
+ font-family: var(--font-family-base);
136
+ display: flex;
137
+ justify-content: space-between;
138
+ align-items: center;
139
+ padding: 16px 24px;
140
+ width: 502px;
141
+ border-radius: 8px;
142
+ background: var(--bg-raised);
143
+
144
+ @media screen and (max-width: ${breakpoints.small}) {
145
+ width: 100%;
146
+ }
147
+ `;
148
+
149
+ const Label = styled.h3`
150
+ margin-right: 15px;
151
+ font-family: var(--h4-font-family);
152
+ font-weight: var(--h4-font-weight);
153
+ font-size: var(--h4-font-size);
154
+ line-height: var(--h4-line-height);
155
+ color: var(--h3-text-color);
156
+ `;
157
+
158
+ const SubLabelContainer = styled.div`
159
+ display: flex;
160
+ justify-content: space-between;
161
+ width: 100%;
162
+ flex-direction: row;
163
+ `;
164
+
165
+ const SubLabel = styled.h3`
166
+ font-family: var(--h4-font-family);
167
+ font-weight: var(--h4-font-weight);
168
+ font-size: var(--h4-font-size);
169
+ line-height: var(--h4-line-height);
170
+ color: var(--text-description);
171
+ `;
172
+
173
+ const StyledForm = styled.form`
174
+ width: 100%;
175
+ `;
176
+
177
+ const SubmitButton = styled(Button).attrs(() => ({
178
+ color: 'primary',
179
+ }))`
180
+ width: 100px;
181
+ margin-left: 0;
182
+ margin-right: 0;
183
+ `;
184
+
185
+ const ButtonsContainer = styled.div`
186
+ display: flex;
187
+ justify-content: end;
188
+ `;
189
+
190
+ const StyledFormOptionalFields = styled.div`
191
+ display: flex;
192
+ flex-flow: column;
193
+ `;
194
+
195
+ const StyledFormMandatoryFields = styled.div`
196
+ display: flex;
197
+ flex-direction: column;
198
+ align-items: center;
199
+ `;
200
+
201
+ const ScaleOption = styled.div`
202
+ cursor: pointer;
203
+ border-radius: 6px;
204
+ background: var(--bg-overlay);
205
+ display: flex;
206
+ padding: 8px 16px;
207
+ flex-direction: column;
208
+ justify-content: center;
209
+ align-items: center;
210
+ &.active {
211
+ border: 1px solid var(--text-primary);
212
+ }
213
+
214
+ @media screen and (max-width: ${breakpoints.small}) {
215
+ padding: 4px 8px;
216
+ }
217
+ `;
218
+
219
+ const ScaleWrapper = styled.div`
220
+ display: flex;
221
+ justify-content: space-between;
222
+ flex-direction: row;
223
+ gap: 4px;
224
+ width: 100%;
225
+
226
+ @media screen and (max-width: ${breakpoints.small}) {
227
+ gap: 1px;
228
+ }
229
+ `;