@redocly/theme 0.21.3 → 0.22.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 (43) hide show
  1. package/lib/components/Feedback/Emotions.d.ts +4 -0
  2. package/lib/components/Feedback/Emotions.js +74 -0
  3. package/lib/components/Feedback/Feedback.js +6 -0
  4. package/lib/components/Feedback/Mood.d.ts +8 -0
  5. package/lib/components/Feedback/Mood.js +116 -0
  6. package/lib/components/Feedback/index.d.ts +1 -0
  7. package/lib/components/Feedback/index.js +3 -1
  8. package/lib/components/Feedback/types.d.ts +24 -0
  9. package/lib/config.d.ts +10 -1
  10. package/lib/config.js +4 -1
  11. package/lib/icons/DissatisfiedIcon/DissatisfiedIcon.d.ts +4 -0
  12. package/lib/icons/DissatisfiedIcon/DissatisfiedIcon.js +18 -0
  13. package/lib/icons/DissatisfiedIcon/index.d.ts +1 -0
  14. package/lib/icons/DissatisfiedIcon/index.js +18 -0
  15. package/lib/icons/NeutralIcon/NeutralIcon.d.ts +4 -0
  16. package/lib/icons/NeutralIcon/NeutralIcon.js +18 -0
  17. package/lib/icons/NeutralIcon/index.d.ts +1 -0
  18. package/lib/icons/NeutralIcon/index.js +18 -0
  19. package/lib/icons/SatisfiedIcon/SatisfiedIcon.d.ts +4 -0
  20. package/lib/icons/SatisfiedIcon/SatisfiedIcon.js +18 -0
  21. package/lib/icons/SatisfiedIcon/index.d.ts +1 -0
  22. package/lib/icons/SatisfiedIcon/index.js +18 -0
  23. package/lib/icons/index.d.ts +3 -0
  24. package/lib/icons/index.js +3 -0
  25. package/lib/types/portal/src/shared/constants.d.ts +2 -1
  26. package/lib/types/portal/src/shared/constants.js +1 -0
  27. package/lib/types/portal/src/shared/types/feedback.d.ts +2 -2
  28. package/package.json +2 -2
  29. package/src/components/Feedback/Emotions.tsx +59 -0
  30. package/src/components/Feedback/Feedback.tsx +13 -1
  31. package/src/components/Feedback/Mood.tsx +133 -0
  32. package/src/components/Feedback/index.ts +1 -0
  33. package/src/components/Feedback/types.ts +21 -0
  34. package/src/config.ts +4 -1
  35. package/src/icons/DissatisfiedIcon/DissatisfiedIcon.tsx +38 -0
  36. package/src/icons/DissatisfiedIcon/index.ts +1 -0
  37. package/src/icons/NeutralIcon/NeutralIcon.tsx +34 -0
  38. package/src/icons/NeutralIcon/index.ts +1 -0
  39. package/src/icons/SatisfiedIcon/SatisfiedIcon.tsx +45 -0
  40. package/src/icons/SatisfiedIcon/index.ts +1 -0
  41. package/src/icons/index.ts +3 -0
  42. package/src/types/portal/src/shared/constants.ts +1 -0
  43. package/src/types/portal/src/shared/types/feedback.ts +2 -2
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const Satisfied: () => JSX.Element;
3
+ export declare const Dissatisfied: () => JSX.Element;
4
+ export declare const Neutral: () => JSX.Element;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Neutral = exports.Dissatisfied = exports.Satisfied = void 0;
30
+ const React = __importStar(require("react"));
31
+ const styled_components_1 = __importDefault(require("styled-components"));
32
+ const icons_1 = require("../../icons");
33
+ const Satisfied = () => {
34
+ return (React.createElement(Wrapper, null,
35
+ React.createElement(Icon, null,
36
+ React.createElement(icons_1.SatisfiedIcon, null))));
37
+ };
38
+ exports.Satisfied = Satisfied;
39
+ const Dissatisfied = () => {
40
+ return (React.createElement(Wrapper, null,
41
+ React.createElement(Icon, null,
42
+ React.createElement(icons_1.DissatisfiedIcon, null))));
43
+ };
44
+ exports.Dissatisfied = Dissatisfied;
45
+ const Neutral = () => {
46
+ return (React.createElement(Wrapper, null,
47
+ React.createElement(Icon, null,
48
+ React.createElement(icons_1.NeutralIcon, null))));
49
+ };
50
+ exports.Neutral = Neutral;
51
+ const Wrapper = styled_components_1.default.div `
52
+ font-family: var(--font-family-base);
53
+ display: flex;
54
+ color: var(--color-info-text);
55
+ &:hover {
56
+ color: var(--color-info-text-active);
57
+ svg {
58
+ > g {
59
+ fill: var(--color-info-text-active);
60
+ }
61
+ }
62
+ }
63
+ `;
64
+ const Icon = styled_components_1.default.div `
65
+ width: 16px;
66
+ height: 16px;
67
+ margin-right: 5px;
68
+ > svg {
69
+ > g {
70
+ fill: var(--color-info-text);
71
+ }
72
+ }
73
+ `;
74
+ //# sourceMappingURL=Emotions.js.map
@@ -53,6 +53,12 @@ const Feedback = (props) => {
53
53
  submitFeedback({ type: 'sentiment', values, path });
54
54
  telemetry_1.telemetry.send('feedback_sent', { type: 'sentiment' });
55
55
  } })));
56
+ case 'mood':
57
+ return (React.createElement(Wrapper, null,
58
+ React.createElement(Feedback_1.Mood, { settings: settings, onSubmit: (values) => {
59
+ submitFeedback({ type: 'mood', values, path });
60
+ telemetry_1.telemetry.send('feedback_sent', { type: 'mood' });
61
+ } })));
56
62
  case 'comment':
57
63
  return (React.createElement(Wrapper, null,
58
64
  React.createElement(Feedback_1.Comment, { settings: settings, onSubmit: (values) => {
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import type { MoodProps } from '../../components';
3
+ export declare enum MOOD_STATES {
4
+ SATISFIED = "satisfied",
5
+ NEUTRAL = "neutral",
6
+ DISSATISFIED = "dissatisfied"
7
+ }
8
+ export declare const Mood: ({ settings, onSubmit, className }: MoodProps) => JSX.Element;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Mood = exports.MOOD_STATES = void 0;
30
+ const React = __importStar(require("react"));
31
+ const styled_components_1 = __importDefault(require("styled-components"));
32
+ const hooks_1 = require("../../mocks/hooks");
33
+ const Emotions_1 = require("../../components/Feedback/Emotions");
34
+ const Feedback_1 = require("../../components/Feedback");
35
+ var MOOD_STATES;
36
+ (function (MOOD_STATES) {
37
+ MOOD_STATES["SATISFIED"] = "satisfied";
38
+ MOOD_STATES["NEUTRAL"] = "neutral";
39
+ MOOD_STATES["DISSATISFIED"] = "dissatisfied";
40
+ })(MOOD_STATES = exports.MOOD_STATES || (exports.MOOD_STATES = {}));
41
+ const Mood = ({ settings, onSubmit, className }) => {
42
+ const { label, submitText, comment: commentSettings, reasons: reasonsSettings } = settings || {};
43
+ const [score, setScore] = React.useState('');
44
+ const [comment, setComment] = React.useState('');
45
+ const [reasons, setReasons] = React.useState([]);
46
+ const { translate } = (0, hooks_1.useTranslate)();
47
+ const translationKeys = {
48
+ submitText: 'theme.feedback.settings.submitText',
49
+ label: 'theme.feedback.settings.label',
50
+ satisfiedLabel: 'theme.feedback.settings.comment.satisfiedLabel',
51
+ neutralLabel: 'theme.feedback.settings.comment.neutralLabel',
52
+ dissatisfiedLabel: 'theme.feedback.settings.comment.dissatisfiedLabel',
53
+ };
54
+ if (score && (reasonsSettings === null || reasonsSettings === void 0 ? void 0 : reasonsSettings.enable) && !reasons.length) {
55
+ const { label: reasonsLabel, items, multi } = reasonsSettings;
56
+ const buttonText = (commentSettings === null || commentSettings === void 0 ? void 0 : commentSettings.enable) ? 'Next' : 'Send';
57
+ return (React.createElement(Feedback_1.Reasons, { onSubmit: ({ reasons }) => setReasons(reasons), settings: { label: reasonsLabel, items, multi, buttonText } }));
58
+ }
59
+ if (score && (commentSettings === null || commentSettings === void 0 ? void 0 : commentSettings.enable) && !comment) {
60
+ const renderCommentLabel = (score) => {
61
+ switch (score) {
62
+ case MOOD_STATES.SATISFIED:
63
+ return translate(translationKeys.satisfiedLabel, commentSettings.satisfiedLabel || 'What was most helpful?');
64
+ case MOOD_STATES.NEUTRAL:
65
+ return translate(translationKeys.neutralLabel, commentSettings.neutralLabel || 'What can we improve?');
66
+ case MOOD_STATES.DISSATISFIED:
67
+ return translate(translationKeys.dissatisfiedLabel, commentSettings.dissatisfiedLabel || 'What can we improve?');
68
+ default:
69
+ return translate(translationKeys.satisfiedLabel, 'What can we improve?');
70
+ }
71
+ };
72
+ return (React.createElement(Feedback_1.Comment, { onSubmit: ({ comment }) => setComment(comment), settings: { label: renderCommentLabel(score) } }));
73
+ }
74
+ if (score) {
75
+ onSubmit({
76
+ score,
77
+ comment,
78
+ reasons,
79
+ });
80
+ return (React.createElement(Wrapper, null,
81
+ React.createElement(Label, { "data-translation-key": translationKeys.submitText }, translate(translationKeys.submitText, submitText || 'Thank you for your feedback!'))));
82
+ }
83
+ return (React.createElement(Wrapper, { "data-component-name": "Feedback/Mood", className: className },
84
+ React.createElement(Label, { "data-translation-key": translationKeys.label }, translate(translationKeys.label, label || 'Was this page helpful?')),
85
+ React.createElement(Vote, { onClick: () => {
86
+ setScore(MOOD_STATES.DISSATISFIED);
87
+ } },
88
+ React.createElement(Emotions_1.Dissatisfied, null)),
89
+ React.createElement(Vote, { onClick: () => {
90
+ setScore(MOOD_STATES.NEUTRAL);
91
+ } },
92
+ React.createElement(Emotions_1.Neutral, null)),
93
+ React.createElement(Vote, { onClick: () => {
94
+ setScore(MOOD_STATES.SATISFIED);
95
+ } },
96
+ React.createElement(Emotions_1.Satisfied, null))));
97
+ };
98
+ exports.Mood = Mood;
99
+ const Wrapper = styled_components_1.default.div `
100
+ font-family: var(--font-family-base);
101
+ display: flex;
102
+ align-items: center;
103
+ `;
104
+ const Label = styled_components_1.default.h3 `
105
+ font-family: var(--h3-font-family);
106
+ font-weight: var(--h3-font-weight);
107
+ font-size: var(--h3-font-size);
108
+ line-height: var(--h3-line-height);
109
+ color: var(--h3-text-color);
110
+ margin-right: 15px;
111
+ `;
112
+ const Vote = styled_components_1.default.div `
113
+ cursor: pointer;
114
+ margin: 0 10px;
115
+ `;
116
+ //# sourceMappingURL=Mood.js.map
@@ -1,6 +1,7 @@
1
1
  export { Feedback } from '../../components/Feedback/Feedback';
2
2
  export { Rating } from '../../components/Feedback/Rating';
3
3
  export { Sentiment } from '../../components/Feedback/Sentiment';
4
+ export { Mood } from '../../components/Feedback/Mood';
4
5
  export { Comment } from '../../components/Feedback/Comment';
5
6
  export { Reasons } from '../../components/Feedback/Reasons';
6
7
  export { ReportDialog } from '../../components/Feedback/ReportDialog';
@@ -14,13 +14,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.useReportDialog = exports.ReportDialog = exports.Reasons = exports.Comment = exports.Sentiment = exports.Rating = exports.Feedback = void 0;
17
+ exports.useReportDialog = exports.ReportDialog = exports.Reasons = exports.Comment = exports.Mood = exports.Sentiment = exports.Rating = exports.Feedback = void 0;
18
18
  var Feedback_1 = require("../../components/Feedback/Feedback");
19
19
  Object.defineProperty(exports, "Feedback", { enumerable: true, get: function () { return Feedback_1.Feedback; } });
20
20
  var Rating_1 = require("../../components/Feedback/Rating");
21
21
  Object.defineProperty(exports, "Rating", { enumerable: true, get: function () { return Rating_1.Rating; } });
22
22
  var Sentiment_1 = require("../../components/Feedback/Sentiment");
23
23
  Object.defineProperty(exports, "Sentiment", { enumerable: true, get: function () { return Sentiment_1.Sentiment; } });
24
+ var Mood_1 = require("../../components/Feedback/Mood");
25
+ Object.defineProperty(exports, "Mood", { enumerable: true, get: function () { return Mood_1.Mood; } });
24
26
  var Comment_1 = require("../../components/Feedback/Comment");
25
27
  Object.defineProperty(exports, "Comment", { enumerable: true, get: function () { return Comment_1.Comment; } });
26
28
  var Reasons_1 = require("../../components/Feedback/Reasons");
@@ -22,6 +22,30 @@ export type RatingProps = {
22
22
  };
23
23
  className?: string;
24
24
  };
25
+ export type MoodProps = {
26
+ onSubmit: (value: {
27
+ score: string;
28
+ comment?: string;
29
+ reasons?: string[];
30
+ }) => void;
31
+ settings?: {
32
+ label?: string;
33
+ submitText?: string;
34
+ comment?: {
35
+ enable: boolean;
36
+ satisfiedLabel?: string;
37
+ neutralLabel?: string;
38
+ dissatisfiedLabel?: string;
39
+ };
40
+ reasons?: {
41
+ enable: boolean;
42
+ label?: string;
43
+ multi?: boolean;
44
+ items: string[];
45
+ };
46
+ };
47
+ className?: string;
48
+ };
25
49
  export type SentimentProps = {
26
50
  onSubmit: (value: {
27
51
  score: number;
package/lib/config.d.ts CHANGED
@@ -1011,7 +1011,7 @@ export declare const themeConfigSchema: {
1011
1011
  };
1012
1012
  readonly type: {
1013
1013
  readonly type: "string";
1014
- readonly enum: readonly ["rating", "sentiment", "comment", "reasons"];
1014
+ readonly enum: readonly ["rating", "sentiment", "comment", "reasons", "mood"];
1015
1015
  readonly default: "sentiment";
1016
1016
  };
1017
1017
  readonly settings: {
@@ -1080,6 +1080,15 @@ export declare const themeConfigSchema: {
1080
1080
  readonly dislikeLabel: {
1081
1081
  readonly type: "string";
1082
1082
  };
1083
+ readonly satisfiedLabel: {
1084
+ readonly type: "string";
1085
+ };
1086
+ readonly neutralLabel: {
1087
+ readonly type: "string";
1088
+ };
1089
+ readonly dissatisfiedLabel: {
1090
+ readonly type: "string";
1091
+ };
1083
1092
  };
1084
1093
  readonly additionalProperties: false;
1085
1094
  };
package/lib/config.js CHANGED
@@ -394,7 +394,7 @@ exports.themeConfigSchema = {
394
394
  },
395
395
  type: {
396
396
  type: 'string',
397
- enum: ['rating', 'sentiment', 'comment', 'reasons'],
397
+ enum: ['rating', 'sentiment', 'comment', 'reasons', 'mood'],
398
398
  default: 'sentiment',
399
399
  },
400
400
  settings: Object.assign({ type: 'object', properties: {
@@ -421,6 +421,9 @@ exports.themeConfigSchema = {
421
421
  label: { type: 'string' },
422
422
  likeLabel: { type: 'string' },
423
423
  dislikeLabel: { type: 'string' },
424
+ satisfiedLabel: { type: 'string' },
425
+ neutralLabel: { type: 'string' },
426
+ dissatisfiedLabel: { type: 'string' },
424
427
  },
425
428
  additionalProperties: false,
426
429
  },
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const DissatisfiedIcon: import("styled-components").StyledComponent<() => JSX.Element, any, {
3
+ 'data-component-name': string;
4
+ }, "data-component-name">;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DissatisfiedIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const Icon = () => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "17", viewBox: "0 0 16 17", fill: "none" },
10
+ react_1.default.createElement("rect", { width: "16", height: "16", transform: "translate(0 0.511719)", fill: "white", style: { mixBlendMode: 'multiply' } }),
11
+ react_1.default.createElement("path", { d: "M8 1.51172C6.61553 1.51172 5.26216 1.92226 4.11101 2.69143C2.95987 3.4606 2.06266 4.55385 1.53285 5.83293C1.00303 7.11202 0.86441 8.51948 1.13451 9.87735C1.4046 11.2352 2.07129 12.4825 3.05026 13.4615C4.02922 14.4404 5.2765 15.1071 6.63437 15.3772C7.99224 15.6473 9.3997 15.5087 10.6788 14.9789C11.9579 14.4491 13.0511 13.5519 13.8203 12.4007C14.5895 11.2496 15 9.89619 15 8.51172C15 6.6552 14.2625 4.87473 12.9497 3.56197C11.637 2.24922 9.85652 1.51172 8 1.51172ZM8 14.5117C6.81332 14.5117 5.65328 14.1598 4.66658 13.5005C3.67989 12.8412 2.91085 11.9042 2.45673 10.8078C2.0026 9.71146 1.88378 8.50506 2.11529 7.34118C2.3468 6.17729 2.91825 5.10819 3.75736 4.26908C4.59648 3.42996 5.66558 2.85852 6.82946 2.62701C7.99335 2.3955 9.19975 2.51432 10.2961 2.96844C11.3925 3.42257 12.3295 4.1916 12.9888 5.1783C13.6481 6.16499 14 7.32503 14 8.51172C14 10.103 13.3679 11.6291 12.2426 12.7544C11.1174 13.8796 9.5913 14.5117 8 14.5117Z", fill: "black", fillOpacity: "0.45" }),
12
+ react_1.default.createElement("path", { d: "M5.75 6.01172C5.50278 6.01172 5.2611 6.08503 5.05554 6.22238C4.84998 6.35973 4.68976 6.55496 4.59515 6.78336C4.50054 7.01177 4.47579 7.26311 4.52402 7.50558C4.57225 7.74806 4.6913 7.97079 4.86612 8.1456C5.04094 8.32042 5.26366 8.43947 5.50614 8.4877C5.74862 8.53593 5.99995 8.51118 6.22836 8.41657C6.45677 8.32196 6.65199 8.16174 6.78934 7.95618C6.92669 7.75062 7 7.50895 7 7.26172C7 6.9302 6.86831 6.61226 6.63389 6.37784C6.39947 6.14341 6.08152 6.01172 5.75 6.01172Z", fill: "black", fillOpacity: "0.45" }),
13
+ react_1.default.createElement("path", { d: "M10.25 6.01172C10.0028 6.01172 9.7611 6.08503 9.55554 6.22238C9.34998 6.35973 9.18976 6.55496 9.09515 6.78336C9.00054 7.01177 8.97579 7.26311 9.02402 7.50558C9.07225 7.74806 9.1913 7.97079 9.36612 8.1456C9.54093 8.32042 9.76366 8.43947 10.0061 8.4877C10.2486 8.53593 10.4999 8.51118 10.7284 8.41657C10.9568 8.32196 11.152 8.16174 11.2893 7.95618C11.4267 7.75062 11.5 7.50895 11.5 7.26172C11.5 6.9302 11.3683 6.61226 11.1339 6.37784C10.8995 6.14341 10.5815 6.01172 10.25 6.01172Z", fill: "black", fillOpacity: "0.45" }),
14
+ react_1.default.createElement("path", { d: "M8 10.0117C7.30982 10.0129 6.63168 10.1926 6.03151 10.5334C5.43135 10.8743 4.92958 11.3646 4.575 11.9567L5.43 12.4567C5.69683 12.0136 6.07369 11.647 6.524 11.3925C6.97431 11.1381 7.48276 11.0043 8 11.0043C8.51724 11.0043 9.0257 11.1381 9.47601 11.3925C9.92631 11.647 10.3032 12.0136 10.57 12.4567L11.425 11.9567C11.0704 11.3646 10.5687 10.8743 9.96849 10.5334C9.36833 10.1926 8.69019 10.0129 8 10.0117Z", fill: "black", fillOpacity: "0.45" })));
15
+ exports.DissatisfiedIcon = (0, styled_components_1.default)(Icon).attrs(() => ({
16
+ 'data-component-name': 'icons/DissatisfiedIcon/DissatisfiedIcon',
17
+ })) ``;
18
+ //# sourceMappingURL=DissatisfiedIcon.js.map
@@ -0,0 +1 @@
1
+ export * from '../../icons/DissatisfiedIcon/DissatisfiedIcon';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("../../icons/DissatisfiedIcon/DissatisfiedIcon"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const NeutralIcon: import("styled-components").StyledComponent<() => JSX.Element, any, {
3
+ 'data-component-name': string;
4
+ }, "data-component-name">;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NeutralIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const Icon = () => (react_1.default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "17", viewBox: "0 0 16 17", fill: "none" },
10
+ react_1.default.createElement("rect", { width: "16", height: "16", transform: "translate(0 0.511719)", fill: "white", style: { mixBlendMode: 'multiply' } }),
11
+ react_1.default.createElement("path", { d: "M8 1.51172C6.61553 1.51172 5.26216 1.92226 4.11101 2.69143C2.95987 3.4606 2.06266 4.55385 1.53285 5.83293C1.00303 7.11202 0.86441 8.51948 1.13451 9.87735C1.4046 11.2352 2.07129 12.4825 3.05026 13.4615C4.02922 14.4404 5.2765 15.1071 6.63437 15.3772C7.99224 15.6473 9.3997 15.5087 10.6788 14.9789C11.9579 14.4491 13.0511 13.5519 13.8203 12.4007C14.5895 11.2496 15 9.89619 15 8.51172C15 6.6552 14.2625 4.87473 12.9497 3.56197C11.637 2.24922 9.85652 1.51172 8 1.51172ZM8 14.5117C6.81332 14.5117 5.65328 14.1598 4.66658 13.5005C3.67989 12.8412 2.91085 11.9042 2.45673 10.8078C2.0026 9.71146 1.88378 8.50506 2.11529 7.34118C2.3468 6.17729 2.91825 5.10819 3.75736 4.26908C4.59648 3.42996 5.66558 2.85852 6.82946 2.62701C7.99335 2.3955 9.19975 2.51432 10.2961 2.96844C11.3925 3.42257 12.3295 4.1916 12.9888 5.1783C13.6481 6.16499 14 7.32503 14 8.51172C14 10.103 13.3679 11.6291 12.2426 12.7544C11.1174 13.8796 9.5913 14.5117 8 14.5117Z", fill: "black", fillOpacity: "0.45" }),
12
+ react_1.default.createElement("path", { d: "M5.75 6.01172C5.50278 6.01172 5.2611 6.08503 5.05554 6.22238C4.84998 6.35973 4.68976 6.55496 4.59515 6.78336C4.50054 7.01177 4.47579 7.26311 4.52402 7.50558C4.57225 7.74806 4.6913 7.97079 4.86612 8.1456C5.04094 8.32042 5.26366 8.43947 5.50614 8.4877C5.74862 8.53593 5.99995 8.51118 6.22836 8.41657C6.45677 8.32196 6.65199 8.16174 6.78934 7.95618C6.92669 7.75062 7 7.50895 7 7.26172C7 6.9302 6.86831 6.61226 6.63389 6.37784C6.39947 6.14341 6.08152 6.01172 5.75 6.01172Z", fill: "black", fillOpacity: "0.45" }),
13
+ react_1.default.createElement("path", { d: "M10.25 6.01172C10.0028 6.01172 9.7611 6.08503 9.55554 6.22238C9.34998 6.35973 9.18976 6.55496 9.09515 6.78336C9.00054 7.01177 8.97579 7.26311 9.02402 7.50558C9.07225 7.74806 9.1913 7.97079 9.36612 8.1456C9.54093 8.32042 9.76366 8.43947 10.0061 8.4877C10.2486 8.53593 10.4999 8.51118 10.7284 8.41657C10.9568 8.32196 11.152 8.16174 11.2893 7.95618C11.4267 7.75062 11.5 7.50895 11.5 7.26172C11.5 6.9302 11.3683 6.61226 11.1339 6.37784C10.8995 6.14341 10.5815 6.01172 10.25 6.01172Z", fill: "black", fillOpacity: "0.45" }),
14
+ react_1.default.createElement("path", { d: "M11 10.5117H5V11.5117H11V10.5117Z", fill: "black", fillOpacity: "0.45" })));
15
+ exports.NeutralIcon = (0, styled_components_1.default)(Icon).attrs(() => ({
16
+ 'data-component-name': 'icons/NeutralIcon/NeutralIcon',
17
+ })) ``;
18
+ //# sourceMappingURL=NeutralIcon.js.map
@@ -0,0 +1 @@
1
+ export * from '../../icons/NeutralIcon/NeutralIcon';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("../../icons/NeutralIcon/NeutralIcon"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ export declare const SatisfiedIcon: import("styled-components").StyledComponent<() => JSX.Element, any, {
3
+ 'data-component-name': string;
4
+ }, "data-component-name">;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SatisfiedIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const Icon = () => (react_1.default.createElement("svg", { version: "1.1", xmlns: "http://www.w3.org/2000/svg", width: "16", height: "17", viewBox: "0 0 16 17", fill: "none" },
10
+ react_1.default.createElement("rect", { width: "16", height: "16", transform: "translate(0 0.511719)", fill: "white", style: { mixBlendMode: 'multiply' } }),
11
+ react_1.default.createElement("path", { d: "M8 1.51172C6.61553 1.51172 5.26216 1.92226 4.11101 2.69143C2.95987 3.4606 2.06266 4.55385 1.53285 5.83293C1.00303 7.11202 0.86441 8.51948 1.13451 9.87735C1.4046 11.2352 2.07129 12.4825 3.05026 13.4615C4.02922 14.4404 5.2765 15.1071 6.63437 15.3772C7.99224 15.6473 9.3997 15.5087 10.6788 14.9789C11.9579 14.4491 13.0511 13.5519 13.8203 12.4007C14.5895 11.2496 15 9.89619 15 8.51172C15 6.6552 14.2625 4.87473 12.9497 3.56197C11.637 2.24922 9.85652 1.51172 8 1.51172ZM8 14.5117C6.81332 14.5117 5.65328 14.1598 4.66658 13.5005C3.67989 12.8412 2.91085 11.9042 2.45673 10.8078C2.0026 9.71146 1.88378 8.50506 2.11529 7.34118C2.3468 6.17729 2.91825 5.10819 3.75736 4.26908C4.59648 3.42996 5.66558 2.85852 6.82946 2.62701C7.99335 2.3955 9.19975 2.51432 10.2961 2.96844C11.3925 3.42257 12.3295 4.1916 12.9888 5.1783C13.6481 6.16499 14 7.32503 14 8.51172C14 10.103 13.3679 11.6291 12.2426 12.7544C11.1174 13.8796 9.5913 14.5117 8 14.5117Z", fill: "black", fillOpacity: "0.45" }),
12
+ react_1.default.createElement("path", { d: "M5.75 6.01172C5.50278 6.01172 5.2611 6.08503 5.05554 6.22238C4.84998 6.35973 4.68976 6.55496 4.59515 6.78336C4.50054 7.01177 4.47579 7.26311 4.52402 7.50558C4.57225 7.74806 4.6913 7.97079 4.86612 8.1456C5.04094 8.32042 5.26366 8.43947 5.50614 8.4877C5.74862 8.53593 5.99995 8.51118 6.22836 8.41657C6.45677 8.32196 6.65199 8.16174 6.78934 7.95618C6.92669 7.75062 7 7.50895 7 7.26172C7.00134 7.0972 6.96991 6.93405 6.90757 6.78179C6.84522 6.62953 6.7532 6.49121 6.63686 6.37487C6.52052 6.25853 6.38219 6.1665 6.22993 6.10416C6.07767 6.04181 5.91453 6.01039 5.75 6.01172Z", fill: "black", fillOpacity: "0.45" }),
13
+ react_1.default.createElement("path", { d: "M10.25 6.01172C10.0028 6.01172 9.7611 6.08503 9.55554 6.22238C9.34998 6.35973 9.18976 6.55496 9.09515 6.78336C9.00054 7.01177 8.97579 7.26311 9.02402 7.50558C9.07225 7.74806 9.1913 7.97079 9.36612 8.1456C9.54093 8.32042 9.76366 8.43947 10.0061 8.4877C10.2486 8.53593 10.4999 8.51118 10.7284 8.41657C10.9568 8.32196 11.152 8.16174 11.2893 7.95618C11.4267 7.75062 11.5 7.50895 11.5 7.26172C11.5013 7.0972 11.4699 6.93405 11.4076 6.78179C11.3452 6.62953 11.2532 6.49121 11.1369 6.37487C11.0205 6.25853 10.8822 6.1665 10.7299 6.10416C10.5777 6.04181 10.4145 6.01039 10.25 6.01172Z", fill: "black", fillOpacity: "0.45" }),
14
+ react_1.default.createElement("path", { d: "M8 12.5117C8.69019 12.5106 9.36833 12.3308 9.96849 11.99C10.5687 11.6492 11.0704 11.1589 11.425 10.5667L10.57 10.0667C10.3032 10.5098 9.92631 10.8764 9.47601 11.1309C9.0257 11.3854 8.51724 11.5191 8 11.5191C7.48276 11.5191 6.97431 11.3854 6.524 11.1309C6.07369 10.8764 5.69683 10.5098 5.43 10.0667L4.575 10.5667C4.92958 11.1589 5.43135 11.6492 6.03151 11.99C6.63168 12.3308 7.30982 12.5106 8 12.5117Z", fill: "black", fillOpacity: "0.45" })));
15
+ exports.SatisfiedIcon = (0, styled_components_1.default)(Icon).attrs(() => ({
16
+ 'data-component-name': 'icons/SatisfiedIcon/SatisfiedIcon',
17
+ })) ``;
18
+ //# sourceMappingURL=SatisfiedIcon.js.map
@@ -0,0 +1 @@
1
+ export * from '../../icons/SatisfiedIcon/SatisfiedIcon';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("../../icons/SatisfiedIcon/SatisfiedIcon"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -21,3 +21,6 @@ export * from '../icons/CheckboxIcon';
21
21
  export * from '../icons/ErrorIcon';
22
22
  export * from '../icons/EditIcon';
23
23
  export * from '../icons/RocketIcon';
24
+ export * from '../icons/SatisfiedIcon';
25
+ export * from '../icons/DissatisfiedIcon';
26
+ export * from '../icons/NeutralIcon';
@@ -37,4 +37,7 @@ __exportStar(require("../icons/CheckboxIcon"), exports);
37
37
  __exportStar(require("../icons/ErrorIcon"), exports);
38
38
  __exportStar(require("../icons/EditIcon"), exports);
39
39
  __exportStar(require("../icons/RocketIcon"), exports);
40
+ __exportStar(require("../icons/SatisfiedIcon"), exports);
41
+ __exportStar(require("../icons/DissatisfiedIcon"), exports);
42
+ __exportStar(require("../icons/NeutralIcon"), exports);
40
43
  //# sourceMappingURL=index.js.map
@@ -6,7 +6,8 @@ export type DEFAULT_COOKIE_EXPIRATION = number;
6
6
  export declare enum FEEDBACK_TYPES {
7
7
  RATING = "rating",
8
8
  SENTIMENT = "sentiment",
9
- COMMENT = "comment"
9
+ COMMENT = "comment",
10
+ MOOD = "mood"
10
11
  }
11
12
  export declare const DEV_LOGIN_SLUG = "/login/";
12
13
  export declare enum ExternalRoutes {
@@ -9,6 +9,7 @@ var FEEDBACK_TYPES;
9
9
  FEEDBACK_TYPES["RATING"] = "rating";
10
10
  FEEDBACK_TYPES["SENTIMENT"] = "sentiment";
11
11
  FEEDBACK_TYPES["COMMENT"] = "comment";
12
+ FEEDBACK_TYPES["MOOD"] = "mood";
12
13
  })(FEEDBACK_TYPES = exports.FEEDBACK_TYPES || (exports.FEEDBACK_TYPES = {}));
13
14
  exports.DEV_LOGIN_SLUG = '/login/';
14
15
  var ExternalRoutes;
@@ -1,5 +1,5 @@
1
1
  import type { FEEDBACK_TYPES } from '../constants';
2
- import type { RatingProps, SentimentProps, CommentProps } from '../../../../../components/Feedback';
2
+ import type { RatingProps, SentimentProps, CommentProps, MoodProps } from '../../../../../components/Feedback';
3
3
  export type SubmitFeedbackParams = {
4
4
  type: string;
5
5
  values: Record<string, unknown>;
@@ -7,5 +7,5 @@ export type SubmitFeedbackParams = {
7
7
  };
8
8
  export type FeedbackProps = {
9
9
  type: FEEDBACK_TYPES;
10
- settings: (RatingProps | SentimentProps | CommentProps)['settings'];
10
+ settings: (RatingProps | SentimentProps | CommentProps | MoodProps)['settings'];
11
11
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.21.3",
3
+ "version": "0.22.0",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -81,7 +81,7 @@
81
81
  "tsconfig-paths-webpack-plugin": "^3.5.2",
82
82
  "typescript": "^4.8.4",
83
83
  "webpack": "^5.72.0",
84
- "@redocly/portal-types": "1.0.2"
84
+ "@redocly/portal-types": "1.1.0"
85
85
  },
86
86
  "dependencies": {
87
87
  "@redocly/ajv": "^8.11.0",
@@ -0,0 +1,59 @@
1
+ import * as React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import { SatisfiedIcon, DissatisfiedIcon, NeutralIcon } from '@theme/icons';
5
+
6
+ export const Satisfied = () => {
7
+ return (
8
+ <Wrapper>
9
+ <Icon>
10
+ <SatisfiedIcon />
11
+ </Icon>
12
+ </Wrapper>
13
+ );
14
+ };
15
+
16
+ export const Dissatisfied = () => {
17
+ return (
18
+ <Wrapper>
19
+ <Icon>
20
+ <DissatisfiedIcon />
21
+ </Icon>
22
+ </Wrapper>
23
+ );
24
+ };
25
+
26
+ export const Neutral = () => {
27
+ return (
28
+ <Wrapper>
29
+ <Icon>
30
+ <NeutralIcon />
31
+ </Icon>
32
+ </Wrapper>
33
+ );
34
+ };
35
+
36
+ const Wrapper = styled.div`
37
+ font-family: var(--font-family-base);
38
+ display: flex;
39
+ color: var(--color-info-text);
40
+ &:hover {
41
+ color: var(--color-info-text-active);
42
+ svg {
43
+ > g {
44
+ fill: var(--color-info-text-active);
45
+ }
46
+ }
47
+ }
48
+ `;
49
+
50
+ const Icon = styled.div`
51
+ width: 16px;
52
+ height: 16px;
53
+ margin-right: 5px;
54
+ > svg {
55
+ > g {
56
+ fill: var(--color-info-text);
57
+ }
58
+ }
59
+ `;
@@ -3,7 +3,7 @@ import { useLocation } from 'react-router-dom';
3
3
  import styled from 'styled-components';
4
4
 
5
5
  import type { FeedbackProps } from '@theme/types/portal/src/shared/types/feedback';
6
- import { Rating, Sentiment, Comment } from '@theme/components/Feedback';
6
+ import { Rating, Sentiment, Comment, Mood } from '@theme/components/Feedback';
7
7
  import { useThemeConfig } from '@theme/hooks';
8
8
  import { useSubmitFeedback } from '@portal/Feedback/useSubmitFeedback';
9
9
  import { telemetry } from '@portal/telemetry';
@@ -40,6 +40,18 @@ export const Feedback = (props: FeedbackProps & { path?: string }) => {
40
40
  />
41
41
  </Wrapper>
42
42
  );
43
+ case 'mood':
44
+ return (
45
+ <Wrapper>
46
+ <Mood
47
+ settings={settings}
48
+ onSubmit={(values) => {
49
+ submitFeedback({ type: 'mood', values, path });
50
+ telemetry.send('feedback_sent', { type: 'mood' });
51
+ }}
52
+ />
53
+ </Wrapper>
54
+ );
43
55
  case 'comment':
44
56
  return (
45
57
  <Wrapper>
@@ -0,0 +1,133 @@
1
+ import * as React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { MoodProps, ReasonsProps } from '@theme/components/';
5
+ import { useTranslate } from '@portal/hooks';
6
+ import { Dissatisfied, Neutral, Satisfied } from '@theme/components/Feedback/Emotions';
7
+ import { Comment, Reasons } from '@theme/components/Feedback';
8
+
9
+ export enum MOOD_STATES {
10
+ SATISFIED = 'satisfied',
11
+ NEUTRAL = 'neutral',
12
+ DISSATISFIED = 'dissatisfied',
13
+ }
14
+
15
+ export const Mood = ({ settings, onSubmit, className }: MoodProps): JSX.Element => {
16
+ const { label, submitText, comment: commentSettings, reasons: reasonsSettings } = settings || {};
17
+ const [score, setScore] = React.useState('');
18
+ const [comment, setComment] = React.useState('');
19
+ const [reasons, setReasons] = React.useState([] as ReasonsProps['settings']['items']);
20
+ const { translate } = useTranslate();
21
+ const translationKeys = {
22
+ submitText: 'theme.feedback.settings.submitText',
23
+ label: 'theme.feedback.settings.label',
24
+ satisfiedLabel: 'theme.feedback.settings.comment.satisfiedLabel',
25
+ neutralLabel: 'theme.feedback.settings.comment.neutralLabel',
26
+ dissatisfiedLabel: 'theme.feedback.settings.comment.dissatisfiedLabel',
27
+ };
28
+
29
+ if (score && reasonsSettings?.enable && !reasons.length) {
30
+ const { label: reasonsLabel, items, multi } = reasonsSettings;
31
+ const buttonText = commentSettings?.enable ? 'Next' : 'Send';
32
+ return (
33
+ <Reasons
34
+ onSubmit={({ reasons }) => setReasons(reasons)}
35
+ settings={{ label: reasonsLabel, items, multi, buttonText }}
36
+ />
37
+ );
38
+ }
39
+
40
+ if (score && commentSettings?.enable && !comment) {
41
+ const renderCommentLabel = (score: string) => {
42
+ switch (score) {
43
+ case MOOD_STATES.SATISFIED:
44
+ return translate(
45
+ translationKeys.satisfiedLabel,
46
+ commentSettings.satisfiedLabel || 'What was most helpful?',
47
+ );
48
+ case MOOD_STATES.NEUTRAL:
49
+ return translate(
50
+ translationKeys.neutralLabel,
51
+ commentSettings.neutralLabel || 'What can we improve?',
52
+ );
53
+ case MOOD_STATES.DISSATISFIED:
54
+ return translate(
55
+ translationKeys.dissatisfiedLabel,
56
+ commentSettings.dissatisfiedLabel || 'What can we improve?',
57
+ );
58
+ default:
59
+ return translate(translationKeys.satisfiedLabel, 'What can we improve?');
60
+ }
61
+ };
62
+ return (
63
+ <Comment
64
+ onSubmit={({ comment }) => setComment(comment)}
65
+ settings={{ label: renderCommentLabel(score) }}
66
+ />
67
+ );
68
+ }
69
+
70
+ if (score) {
71
+ onSubmit({
72
+ score,
73
+ comment,
74
+ reasons,
75
+ });
76
+ return (
77
+ <Wrapper>
78
+ <Label data-translation-key={translationKeys.submitText}>
79
+ {translate(translationKeys.submitText, submitText || 'Thank you for your feedback!')}
80
+ </Label>
81
+ </Wrapper>
82
+ );
83
+ }
84
+
85
+ return (
86
+ <Wrapper data-component-name="Feedback/Mood" className={className}>
87
+ <Label data-translation-key={translationKeys.label}>
88
+ {translate(translationKeys.label, label || 'Was this page helpful?')}
89
+ </Label>
90
+ <Vote
91
+ onClick={() => {
92
+ setScore(MOOD_STATES.DISSATISFIED);
93
+ }}
94
+ >
95
+ <Dissatisfied />
96
+ </Vote>
97
+ <Vote
98
+ onClick={() => {
99
+ setScore(MOOD_STATES.NEUTRAL);
100
+ }}
101
+ >
102
+ <Neutral />
103
+ </Vote>
104
+ <Vote
105
+ onClick={() => {
106
+ setScore(MOOD_STATES.SATISFIED);
107
+ }}
108
+ >
109
+ <Satisfied />
110
+ </Vote>
111
+ </Wrapper>
112
+ );
113
+ };
114
+
115
+ const Wrapper = styled.div`
116
+ font-family: var(--font-family-base);
117
+ display: flex;
118
+ align-items: center;
119
+ `;
120
+
121
+ const Label = styled.h3`
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);
126
+ color: var(--h3-text-color);
127
+ margin-right: 15px;
128
+ `;
129
+
130
+ const Vote = styled.div`
131
+ cursor: pointer;
132
+ margin: 0 10px;
133
+ `;
@@ -1,6 +1,7 @@
1
1
  export { Feedback } from '@theme/components/Feedback/Feedback';
2
2
  export { Rating } from '@theme/components/Feedback/Rating';
3
3
  export { Sentiment } from '@theme/components/Feedback/Sentiment';
4
+ export { Mood } from '@theme/components/Feedback/Mood';
4
5
  export { Comment } from '@theme/components/Feedback/Comment';
5
6
  export { Reasons } from '@theme/components/Feedback/Reasons';
6
7
  export { ReportDialog } from '@theme/components/Feedback/ReportDialog';
@@ -20,6 +20,27 @@ export type RatingProps = {
20
20
  className?: string;
21
21
  };
22
22
 
23
+ export type MoodProps = {
24
+ onSubmit: (value: { score: string; comment?: string; reasons?: string[] }) => void;
25
+ settings?: {
26
+ label?: string;
27
+ submitText?: string;
28
+ comment?: {
29
+ enable: boolean;
30
+ satisfiedLabel?: string;
31
+ neutralLabel?: string;
32
+ dissatisfiedLabel?: string;
33
+ };
34
+ reasons?: {
35
+ enable: boolean;
36
+ label?: string;
37
+ multi?: boolean;
38
+ items: string[];
39
+ };
40
+ };
41
+ className?: string;
42
+ };
43
+
23
44
  export type SentimentProps = {
24
45
  onSubmit: (value: { score: number; comment?: string; reasons?: string[] }) => void;
25
46
  settings?: {
package/src/config.ts CHANGED
@@ -448,7 +448,7 @@ export const themeConfigSchema = {
448
448
  },
449
449
  type: {
450
450
  type: 'string',
451
- enum: ['rating', 'sentiment', 'comment', 'reasons'],
451
+ enum: ['rating', 'sentiment', 'comment', 'reasons', 'mood'],
452
452
  default: 'sentiment',
453
453
  },
454
454
  settings: {
@@ -477,6 +477,9 @@ export const themeConfigSchema = {
477
477
  label: { type: 'string' },
478
478
  likeLabel: { type: 'string' },
479
479
  dislikeLabel: { type: 'string' },
480
+ satisfiedLabel: { type: 'string' },
481
+ neutralLabel: { type: 'string' },
482
+ dissatisfiedLabel: { type: 'string' },
480
483
  },
481
484
  additionalProperties: false,
482
485
  },
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ const Icon = () => (
5
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
6
+ <rect
7
+ width="16"
8
+ height="16"
9
+ transform="translate(0 0.511719)"
10
+ fill="white"
11
+ style={{ mixBlendMode: 'multiply' }}
12
+ />
13
+ <path
14
+ d="M8 1.51172C6.61553 1.51172 5.26216 1.92226 4.11101 2.69143C2.95987 3.4606 2.06266 4.55385 1.53285 5.83293C1.00303 7.11202 0.86441 8.51948 1.13451 9.87735C1.4046 11.2352 2.07129 12.4825 3.05026 13.4615C4.02922 14.4404 5.2765 15.1071 6.63437 15.3772C7.99224 15.6473 9.3997 15.5087 10.6788 14.9789C11.9579 14.4491 13.0511 13.5519 13.8203 12.4007C14.5895 11.2496 15 9.89619 15 8.51172C15 6.6552 14.2625 4.87473 12.9497 3.56197C11.637 2.24922 9.85652 1.51172 8 1.51172ZM8 14.5117C6.81332 14.5117 5.65328 14.1598 4.66658 13.5005C3.67989 12.8412 2.91085 11.9042 2.45673 10.8078C2.0026 9.71146 1.88378 8.50506 2.11529 7.34118C2.3468 6.17729 2.91825 5.10819 3.75736 4.26908C4.59648 3.42996 5.66558 2.85852 6.82946 2.62701C7.99335 2.3955 9.19975 2.51432 10.2961 2.96844C11.3925 3.42257 12.3295 4.1916 12.9888 5.1783C13.6481 6.16499 14 7.32503 14 8.51172C14 10.103 13.3679 11.6291 12.2426 12.7544C11.1174 13.8796 9.5913 14.5117 8 14.5117Z"
15
+ fill="black"
16
+ fillOpacity="0.45"
17
+ />
18
+ <path
19
+ d="M5.75 6.01172C5.50278 6.01172 5.2611 6.08503 5.05554 6.22238C4.84998 6.35973 4.68976 6.55496 4.59515 6.78336C4.50054 7.01177 4.47579 7.26311 4.52402 7.50558C4.57225 7.74806 4.6913 7.97079 4.86612 8.1456C5.04094 8.32042 5.26366 8.43947 5.50614 8.4877C5.74862 8.53593 5.99995 8.51118 6.22836 8.41657C6.45677 8.32196 6.65199 8.16174 6.78934 7.95618C6.92669 7.75062 7 7.50895 7 7.26172C7 6.9302 6.86831 6.61226 6.63389 6.37784C6.39947 6.14341 6.08152 6.01172 5.75 6.01172Z"
20
+ fill="black"
21
+ fillOpacity="0.45"
22
+ />
23
+ <path
24
+ d="M10.25 6.01172C10.0028 6.01172 9.7611 6.08503 9.55554 6.22238C9.34998 6.35973 9.18976 6.55496 9.09515 6.78336C9.00054 7.01177 8.97579 7.26311 9.02402 7.50558C9.07225 7.74806 9.1913 7.97079 9.36612 8.1456C9.54093 8.32042 9.76366 8.43947 10.0061 8.4877C10.2486 8.53593 10.4999 8.51118 10.7284 8.41657C10.9568 8.32196 11.152 8.16174 11.2893 7.95618C11.4267 7.75062 11.5 7.50895 11.5 7.26172C11.5 6.9302 11.3683 6.61226 11.1339 6.37784C10.8995 6.14341 10.5815 6.01172 10.25 6.01172Z"
25
+ fill="black"
26
+ fillOpacity="0.45"
27
+ />
28
+ <path
29
+ d="M8 10.0117C7.30982 10.0129 6.63168 10.1926 6.03151 10.5334C5.43135 10.8743 4.92958 11.3646 4.575 11.9567L5.43 12.4567C5.69683 12.0136 6.07369 11.647 6.524 11.3925C6.97431 11.1381 7.48276 11.0043 8 11.0043C8.51724 11.0043 9.0257 11.1381 9.47601 11.3925C9.92631 11.647 10.3032 12.0136 10.57 12.4567L11.425 11.9567C11.0704 11.3646 10.5687 10.8743 9.96849 10.5334C9.36833 10.1926 8.69019 10.0129 8 10.0117Z"
30
+ fill="black"
31
+ fillOpacity="0.45"
32
+ />
33
+ </svg>
34
+ );
35
+
36
+ export const DissatisfiedIcon = styled(Icon).attrs(() => ({
37
+ 'data-component-name': 'icons/DissatisfiedIcon/DissatisfiedIcon',
38
+ }))``;
@@ -0,0 +1 @@
1
+ export * from '@theme/icons/DissatisfiedIcon/DissatisfiedIcon';
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ const Icon = () => (
5
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
6
+ <rect
7
+ width="16"
8
+ height="16"
9
+ transform="translate(0 0.511719)"
10
+ fill="white"
11
+ style={{ mixBlendMode: 'multiply' }}
12
+ />
13
+ <path
14
+ d="M8 1.51172C6.61553 1.51172 5.26216 1.92226 4.11101 2.69143C2.95987 3.4606 2.06266 4.55385 1.53285 5.83293C1.00303 7.11202 0.86441 8.51948 1.13451 9.87735C1.4046 11.2352 2.07129 12.4825 3.05026 13.4615C4.02922 14.4404 5.2765 15.1071 6.63437 15.3772C7.99224 15.6473 9.3997 15.5087 10.6788 14.9789C11.9579 14.4491 13.0511 13.5519 13.8203 12.4007C14.5895 11.2496 15 9.89619 15 8.51172C15 6.6552 14.2625 4.87473 12.9497 3.56197C11.637 2.24922 9.85652 1.51172 8 1.51172ZM8 14.5117C6.81332 14.5117 5.65328 14.1598 4.66658 13.5005C3.67989 12.8412 2.91085 11.9042 2.45673 10.8078C2.0026 9.71146 1.88378 8.50506 2.11529 7.34118C2.3468 6.17729 2.91825 5.10819 3.75736 4.26908C4.59648 3.42996 5.66558 2.85852 6.82946 2.62701C7.99335 2.3955 9.19975 2.51432 10.2961 2.96844C11.3925 3.42257 12.3295 4.1916 12.9888 5.1783C13.6481 6.16499 14 7.32503 14 8.51172C14 10.103 13.3679 11.6291 12.2426 12.7544C11.1174 13.8796 9.5913 14.5117 8 14.5117Z"
15
+ fill="black"
16
+ fillOpacity="0.45"
17
+ />
18
+ <path
19
+ d="M5.75 6.01172C5.50278 6.01172 5.2611 6.08503 5.05554 6.22238C4.84998 6.35973 4.68976 6.55496 4.59515 6.78336C4.50054 7.01177 4.47579 7.26311 4.52402 7.50558C4.57225 7.74806 4.6913 7.97079 4.86612 8.1456C5.04094 8.32042 5.26366 8.43947 5.50614 8.4877C5.74862 8.53593 5.99995 8.51118 6.22836 8.41657C6.45677 8.32196 6.65199 8.16174 6.78934 7.95618C6.92669 7.75062 7 7.50895 7 7.26172C7 6.9302 6.86831 6.61226 6.63389 6.37784C6.39947 6.14341 6.08152 6.01172 5.75 6.01172Z"
20
+ fill="black"
21
+ fillOpacity="0.45"
22
+ />
23
+ <path
24
+ d="M10.25 6.01172C10.0028 6.01172 9.7611 6.08503 9.55554 6.22238C9.34998 6.35973 9.18976 6.55496 9.09515 6.78336C9.00054 7.01177 8.97579 7.26311 9.02402 7.50558C9.07225 7.74806 9.1913 7.97079 9.36612 8.1456C9.54093 8.32042 9.76366 8.43947 10.0061 8.4877C10.2486 8.53593 10.4999 8.51118 10.7284 8.41657C10.9568 8.32196 11.152 8.16174 11.2893 7.95618C11.4267 7.75062 11.5 7.50895 11.5 7.26172C11.5 6.9302 11.3683 6.61226 11.1339 6.37784C10.8995 6.14341 10.5815 6.01172 10.25 6.01172Z"
25
+ fill="black"
26
+ fillOpacity="0.45"
27
+ />
28
+ <path d="M11 10.5117H5V11.5117H11V10.5117Z" fill="black" fillOpacity="0.45" />
29
+ </svg>
30
+ );
31
+
32
+ export const NeutralIcon = styled(Icon).attrs(() => ({
33
+ 'data-component-name': 'icons/NeutralIcon/NeutralIcon',
34
+ }))``;
@@ -0,0 +1 @@
1
+ export * from '@theme/icons/NeutralIcon/NeutralIcon';
@@ -0,0 +1,45 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ const Icon = () => (
5
+ <svg
6
+ version="1.1"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ width="16"
9
+ height="17"
10
+ viewBox="0 0 16 17"
11
+ fill="none"
12
+ >
13
+ <rect
14
+ width="16"
15
+ height="16"
16
+ transform="translate(0 0.511719)"
17
+ fill="white"
18
+ style={{ mixBlendMode: 'multiply' }}
19
+ />
20
+ <path
21
+ d="M8 1.51172C6.61553 1.51172 5.26216 1.92226 4.11101 2.69143C2.95987 3.4606 2.06266 4.55385 1.53285 5.83293C1.00303 7.11202 0.86441 8.51948 1.13451 9.87735C1.4046 11.2352 2.07129 12.4825 3.05026 13.4615C4.02922 14.4404 5.2765 15.1071 6.63437 15.3772C7.99224 15.6473 9.3997 15.5087 10.6788 14.9789C11.9579 14.4491 13.0511 13.5519 13.8203 12.4007C14.5895 11.2496 15 9.89619 15 8.51172C15 6.6552 14.2625 4.87473 12.9497 3.56197C11.637 2.24922 9.85652 1.51172 8 1.51172ZM8 14.5117C6.81332 14.5117 5.65328 14.1598 4.66658 13.5005C3.67989 12.8412 2.91085 11.9042 2.45673 10.8078C2.0026 9.71146 1.88378 8.50506 2.11529 7.34118C2.3468 6.17729 2.91825 5.10819 3.75736 4.26908C4.59648 3.42996 5.66558 2.85852 6.82946 2.62701C7.99335 2.3955 9.19975 2.51432 10.2961 2.96844C11.3925 3.42257 12.3295 4.1916 12.9888 5.1783C13.6481 6.16499 14 7.32503 14 8.51172C14 10.103 13.3679 11.6291 12.2426 12.7544C11.1174 13.8796 9.5913 14.5117 8 14.5117Z"
22
+ fill="black"
23
+ fillOpacity="0.45"
24
+ />
25
+ <path
26
+ d="M5.75 6.01172C5.50278 6.01172 5.2611 6.08503 5.05554 6.22238C4.84998 6.35973 4.68976 6.55496 4.59515 6.78336C4.50054 7.01177 4.47579 7.26311 4.52402 7.50558C4.57225 7.74806 4.6913 7.97079 4.86612 8.1456C5.04094 8.32042 5.26366 8.43947 5.50614 8.4877C5.74862 8.53593 5.99995 8.51118 6.22836 8.41657C6.45677 8.32196 6.65199 8.16174 6.78934 7.95618C6.92669 7.75062 7 7.50895 7 7.26172C7.00134 7.0972 6.96991 6.93405 6.90757 6.78179C6.84522 6.62953 6.7532 6.49121 6.63686 6.37487C6.52052 6.25853 6.38219 6.1665 6.22993 6.10416C6.07767 6.04181 5.91453 6.01039 5.75 6.01172Z"
27
+ fill="black"
28
+ fillOpacity="0.45"
29
+ />
30
+ <path
31
+ d="M10.25 6.01172C10.0028 6.01172 9.7611 6.08503 9.55554 6.22238C9.34998 6.35973 9.18976 6.55496 9.09515 6.78336C9.00054 7.01177 8.97579 7.26311 9.02402 7.50558C9.07225 7.74806 9.1913 7.97079 9.36612 8.1456C9.54093 8.32042 9.76366 8.43947 10.0061 8.4877C10.2486 8.53593 10.4999 8.51118 10.7284 8.41657C10.9568 8.32196 11.152 8.16174 11.2893 7.95618C11.4267 7.75062 11.5 7.50895 11.5 7.26172C11.5013 7.0972 11.4699 6.93405 11.4076 6.78179C11.3452 6.62953 11.2532 6.49121 11.1369 6.37487C11.0205 6.25853 10.8822 6.1665 10.7299 6.10416C10.5777 6.04181 10.4145 6.01039 10.25 6.01172Z"
32
+ fill="black"
33
+ fillOpacity="0.45"
34
+ />
35
+ <path
36
+ d="M8 12.5117C8.69019 12.5106 9.36833 12.3308 9.96849 11.99C10.5687 11.6492 11.0704 11.1589 11.425 10.5667L10.57 10.0667C10.3032 10.5098 9.92631 10.8764 9.47601 11.1309C9.0257 11.3854 8.51724 11.5191 8 11.5191C7.48276 11.5191 6.97431 11.3854 6.524 11.1309C6.07369 10.8764 5.69683 10.5098 5.43 10.0667L4.575 10.5667C4.92958 11.1589 5.43135 11.6492 6.03151 11.99C6.63168 12.3308 7.30982 12.5106 8 12.5117Z"
37
+ fill="black"
38
+ fillOpacity="0.45"
39
+ />
40
+ </svg>
41
+ );
42
+
43
+ export const SatisfiedIcon = styled(Icon).attrs(() => ({
44
+ 'data-component-name': 'icons/SatisfiedIcon/SatisfiedIcon',
45
+ }))``;
@@ -0,0 +1 @@
1
+ export * from '@theme/icons/SatisfiedIcon/SatisfiedIcon';
@@ -21,3 +21,6 @@ export * from '@theme/icons/CheckboxIcon';
21
21
  export * from '@theme/icons/ErrorIcon';
22
22
  export * from '@theme/icons/EditIcon';
23
23
  export * from '@theme/icons/RocketIcon';
24
+ export * from '@theme/icons/SatisfiedIcon';
25
+ export * from '@theme/icons/DissatisfiedIcon';
26
+ export * from '@theme/icons/NeutralIcon';
@@ -7,6 +7,7 @@ export enum FEEDBACK_TYPES {
7
7
  RATING = 'rating',
8
8
  SENTIMENT = 'sentiment',
9
9
  COMMENT = 'comment',
10
+ MOOD = 'mood',
10
11
  }
11
12
  export const DEV_LOGIN_SLUG = '/login/';
12
13
  export enum ExternalRoutes {
@@ -1,6 +1,6 @@
1
1
  import type { FEEDBACK_TYPES } from '../constants';
2
2
 
3
- import type { RatingProps, SentimentProps, CommentProps } from '@theme/components/Feedback';
3
+ import type {RatingProps, SentimentProps, CommentProps, MoodProps} from '@theme/components/Feedback';
4
4
 
5
5
  export type SubmitFeedbackParams = {
6
6
  type: string;
@@ -10,5 +10,5 @@ export type SubmitFeedbackParams = {
10
10
 
11
11
  export type FeedbackProps = {
12
12
  type: FEEDBACK_TYPES;
13
- settings: (RatingProps | SentimentProps | CommentProps)['settings'];
13
+ settings: (RatingProps | SentimentProps | CommentProps | MoodProps)['settings'];
14
14
  }