@redocly/theme 0.63.0-next.0 → 0.63.0-next.2

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 (39) hide show
  1. package/lib/components/Buttons/EditPageButton.js +4 -26
  2. package/lib/components/Dropdown/Dropdown.js +1 -1
  3. package/lib/components/Dropdown/variables.js +1 -0
  4. package/lib/components/Feedback/Comment.js +17 -4
  5. package/lib/components/Feedback/Mood.js +6 -3
  6. package/lib/components/Feedback/Rating.js +6 -3
  7. package/lib/components/Feedback/Scale.js +6 -3
  8. package/lib/components/Feedback/Sentiment.js +6 -3
  9. package/lib/components/Menu/variables.js +3 -3
  10. package/lib/components/PageActions/PageActions.js +1 -1
  11. package/lib/core/constants/feedback.d.ts +2 -0
  12. package/lib/core/constants/feedback.js +6 -0
  13. package/lib/core/constants/index.d.ts +1 -0
  14. package/lib/core/constants/index.js +1 -0
  15. package/lib/core/openapi/index.d.ts +1 -0
  16. package/lib/core/openapi/index.js +3 -1
  17. package/lib/core/styles/dark.js +11 -0
  18. package/lib/core/styles/global.js +7 -0
  19. package/lib/core/types/l10n.d.ts +1 -1
  20. package/lib/icons/DirectionRightIcon/DirectionRightIcon.d.ts +5 -0
  21. package/lib/icons/DirectionRightIcon/DirectionRightIcon.js +24 -0
  22. package/package.json +4 -4
  23. package/src/components/Buttons/EditPageButton.tsx +13 -34
  24. package/src/components/Dropdown/Dropdown.tsx +1 -1
  25. package/src/components/Dropdown/variables.ts +1 -0
  26. package/src/components/Feedback/Comment.tsx +22 -4
  27. package/src/components/Feedback/Mood.tsx +6 -2
  28. package/src/components/Feedback/Rating.tsx +6 -2
  29. package/src/components/Feedback/Scale.tsx +6 -2
  30. package/src/components/Feedback/Sentiment.tsx +6 -2
  31. package/src/components/Menu/variables.ts +3 -3
  32. package/src/components/PageActions/PageActions.tsx +1 -1
  33. package/src/core/constants/feedback.ts +2 -0
  34. package/src/core/constants/index.ts +1 -0
  35. package/src/core/openapi/index.ts +1 -0
  36. package/src/core/styles/dark.ts +12 -0
  37. package/src/core/styles/global.ts +7 -0
  38. package/src/core/types/l10n.ts +1 -0
  39. package/src/icons/DirectionRightIcon/DirectionRightIcon.tsx +35 -0
@@ -8,37 +8,15 @@ const react_1 = __importDefault(require("react"));
8
8
  const styled_components_1 = __importDefault(require("styled-components"));
9
9
  const hooks_1 = require("../../core/hooks");
10
10
  const EditIcon_1 = require("../../icons/EditIcon/EditIcon");
11
- const Link_1 = require("../../components/Link/Link");
11
+ const Button_1 = require("../../components/Button/Button");
12
12
  function EditPageButton({ to }) {
13
13
  const { useTranslate, useTelemetry } = (0, hooks_1.useThemeHooks)();
14
14
  const { translate } = useTranslate();
15
15
  const telemetry = useTelemetry();
16
- return (react_1.default.createElement(EditPageButtonWrapper, { "data-component-name": "Buttons/EditPageButton", target: "_blank", to: to, onClick: () => telemetry.sendEditPageLinkClickedMessage() },
17
- react_1.default.createElement(ButtonIcon, null),
18
- react_1.default.createElement(ButtonText, { "data-translation-key": "markdown.editPage.text" }, translate('markdown.editPage.text', 'Edit'))));
16
+ return (react_1.default.createElement(EditPageButtonWrapper, { "data-component-name": "Buttons/EditPageButton" },
17
+ react_1.default.createElement(Button_1.Button, { to: to, external: true, variant: "ghost", size: "small", icon: react_1.default.createElement(EditIcon_1.EditIcon, null), onClick: () => telemetry.sendEditPageLinkClickedMessage(), "data-translation-key": "markdown.editPage.text" }, translate('markdown.editPage.text', 'Edit'))));
19
18
  }
20
- const EditPageButtonWrapper = (0, styled_components_1.default)(Link_1.Link) `
21
- height: fit-content;
19
+ const EditPageButtonWrapper = styled_components_1.default.div `
22
20
  margin-left: auto;
23
- display: inline-flex;
24
- color: var(--text-color-secondary);
25
- font-weight: var(--font-weight-bold);
26
- font-size: var(--font-size-base);
27
- font-family: var(--font-family-base);
28
- text-decoration: none;
29
-
30
- &:hover {
31
- color: var(--text-color-primary);
32
- }
33
-
34
- @media print {
35
- display: none;
36
- }
37
- `;
38
- const ButtonIcon = (0, styled_components_1.default)(EditIcon_1.EditIcon) `
39
- margin-right: 3px;
40
- `;
41
- const ButtonText = styled_components_1.default.span `
42
- line-height: 14px;
43
21
  `;
44
22
  //# sourceMappingURL=EditPageButton.js.map
@@ -97,6 +97,6 @@ const ChildrenWrapper = styled_components_1.default.div `
97
97
  right: ${({ alignment }) => (alignment === 'end' ? '0' : 'auto')};
98
98
  display: ${({ isOpen }) => (isOpen ? 'block' : 'none')};
99
99
 
100
- z-index: var(--z-index-raised);
100
+ z-index: var(--dropdown-menu-z-index);
101
101
  `;
102
102
  //# sourceMappingURL=Dropdown.js.map
@@ -10,6 +10,7 @@ exports.dropdown = (0, styled_components_1.css) `
10
10
  --dropdown-menu-font-weight: var(--font-weight-regular); // @presenter FontWeight
11
11
  --dropdown-menu-line-height: var(--line-height-base); // @presenter LineHeight
12
12
  --dropdown-menu-text-color: var(--text-color-secondary); // @presenter Color
13
+ --dropdown-menu-z-index: var(--z-index-raised); // @presenter ZIndex
13
14
 
14
15
  --dropdown-menu-padding-top: var(--spacing-xxs);
15
16
  --dropdown-menu-min-width: 100px;
@@ -39,23 +39,27 @@ const styled_components_1 = __importStar(require("styled-components"));
39
39
  const hooks_1 = require("../../core/hooks");
40
40
  const RadioCheckButtonIcon_1 = require("../../icons/RadioCheckButtonIcon/RadioCheckButtonIcon");
41
41
  const Button_1 = require("../../components/Button/Button");
42
+ const constants_1 = require("../../core/constants");
42
43
  function Comment({ settings, onSubmit, onCancel, className, standAlone = true, isDialog = false, }) {
43
44
  const { useTranslate } = (0, hooks_1.useThemeHooks)();
44
45
  const { translate } = useTranslate();
45
46
  const { label, submitText } = settings || {};
46
47
  const [text, setText] = react_1.default.useState('');
47
48
  const [submitValue, setSubmitValue] = react_1.default.useState('');
49
+ const [isMaxLengthReached, setIsMaxLengthReached] = react_1.default.useState(false);
48
50
  const modalRef = (0, react_1.useRef)(null);
49
51
  (0, hooks_1.useOutsideClick)(modalRef, onCancel);
50
52
  const send = () => {
51
- if (!text)
53
+ const trimmedText = text.trim();
54
+ if (!trimmedText)
52
55
  return;
53
- setSubmitValue(text);
54
- onSubmit({ comment: text });
56
+ setSubmitValue(trimmedText);
57
+ onSubmit({ comment: trimmedText });
55
58
  };
56
59
  const handleTextAreaChange = (e) => {
57
60
  const commentValue = e.target.value;
58
61
  setText(commentValue);
62
+ setIsMaxLengthReached(commentValue.length >= constants_1.MAX_CONTEXT_LENGTH);
59
63
  if (!standAlone) {
60
64
  onSubmit({ comment: commentValue });
61
65
  }
@@ -70,7 +74,11 @@ function Comment({ settings, onSubmit, onCancel, className, standAlone = true, i
70
74
  return (react_1.default.createElement(CommentWrapper, { ref: modalRef, "data-component-name": "Feedback/Comment", className: className, style: standAlone ? { width: 'var(--feedback-report-dialog-width)' } : { width: 'auto' } },
71
75
  react_1.default.createElement(Label, { "data-translation-key": "feedback.settings.comment.label", standAlone: standAlone }, label ||
72
76
  translate('feedback.settings.comment.label', 'Please share your feedback with us.')),
73
- react_1.default.createElement(TextArea, { rows: 3, onChange: handleTextAreaChange }),
77
+ react_1.default.createElement(TextArea, { rows: 3, maxLength: constants_1.MAX_CONTEXT_LENGTH, onChange: handleTextAreaChange }),
78
+ isMaxLengthReached && (react_1.default.createElement(MaxLengthMessage, { "data-translation-key": "feedback.settings.comment.maxLength" }, translate('feedback.settings.comment.maxLength', {
79
+ maxLength: constants_1.MAX_CONTEXT_LENGTH,
80
+ defaultValue: `Maximum content length of ${constants_1.MAX_CONTEXT_LENGTH} characters reached`,
81
+ }))),
74
82
  standAlone && (react_1.default.createElement(ButtonsContainer, null,
75
83
  onCancel && (react_1.default.createElement(Button_1.Button, { "data-translation-key": "feedback.settings.comment.cancel", onClick: onCancel, variant: "text", size: "small" }, translate('feedback.settings.comment.cancel', 'Cancel'))),
76
84
  react_1.default.createElement(Button_1.Button, { "data-translation-key": "feedback.settings.comment.send", onClick: send, variant: isDialog ? 'primary' : 'secondary', size: "small" }, translate('feedback.settings.comment.send', 'Send'))))));
@@ -136,4 +144,9 @@ const ButtonsContainer = styled_components_1.default.div `
136
144
  margin-top: var(--spacing-xs);
137
145
  gap: var(--spacing-xs);
138
146
  `;
147
+ const MaxLengthMessage = styled_components_1.default.div `
148
+ font-size: var(--font-size-sm);
149
+ color: var(--text-color-secondary);
150
+ margin-top: var(--spacing-xxs);
151
+ `;
139
152
  //# sourceMappingURL=Comment.js.map
@@ -46,6 +46,7 @@ const Button_1 = require("../../components/Button/Button");
46
46
  const FaceDissatisfiedIcon_1 = require("../../icons/FaceDissatisfiedIcon/FaceDissatisfiedIcon");
47
47
  const FaceSatisfiedIcon_1 = require("../../icons/FaceSatisfiedIcon/FaceSatisfiedIcon");
48
48
  const FaceNeutralIcon_1 = require("../../icons/FaceNeutralIcon/FaceNeutralIcon");
49
+ const constants_1 = require("../../core/constants");
49
50
  var MOOD_STATES;
50
51
  (function (MOOD_STATES) {
51
52
  MOOD_STATES["SATISFIED"] = "satisfied";
@@ -118,11 +119,13 @@ function Mood({ settings, onSubmit, className }) {
118
119
  const displaySubmitBnt = !!(score && (displayReasons || displayComment));
119
120
  const displayFeedbackEmail = !!score && !(optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.hide) && !userData.isAuthenticated;
120
121
  const onSubmitMoodForm = () => {
122
+ const trimmedComment = (comment === null || comment === void 0 ? void 0 : comment.trim()) || undefined;
123
+ const trimmedEmail = (email === null || email === void 0 ? void 0 : email.trim()) || undefined;
121
124
  onSubmit({
122
125
  score: remapScore(score),
123
- comment,
126
+ comment: trimmedComment,
124
127
  reasons,
125
- email,
128
+ email: trimmedEmail,
126
129
  });
127
130
  setIsSubmitted(true);
128
131
  };
@@ -170,7 +173,7 @@ function Mood({ settings, onSubmit, className }) {
170
173
  React.createElement(InputLabel, { "data-translation-key": "feedback.settings.optionalEmail.label" }, (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.label) ||
171
174
  translate('feedback.settings.optionalEmail.label', 'Your email (optional, for follow-up)')),
172
175
  React.createElement(EmailInput, { onChange: onEmailChange, placeholder: (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.placeholder) ||
173
- translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", required: !!email, onKeyDown: (e) => {
176
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", maxLength: constants_1.MAX_EMAIL_LENGTH, required: !!email, onKeyDown: (e) => {
174
177
  if (e.key === 'Enter') {
175
178
  e.preventDefault();
176
179
  onSubmitMoodForm();
@@ -47,6 +47,7 @@ const RadioCheckButtonIcon_1 = require("../../icons/RadioCheckButtonIcon/RadioCh
47
47
  const Comment_1 = require("../../components/Feedback/Comment");
48
48
  const Stars_1 = require("../../components/Feedback/Stars");
49
49
  const Button_1 = require("../../components/Button/Button");
50
+ const constants_1 = require("../../core/constants");
50
51
  exports.FEEDBACK_MAX_RATING = 5;
51
52
  function Rating({ settings, onSubmit, className }) {
52
53
  const { label, submitText, comment: commentSettings, reasons: reasonsSettings, optionalEmail: optionalEmailSettings, } = settings || {};
@@ -63,12 +64,14 @@ function Rating({ settings, onSubmit, className }) {
63
64
  setEmail(value || undefined);
64
65
  };
65
66
  const onSubmitRatingForm = () => {
67
+ const trimmedComment = (comment === null || comment === void 0 ? void 0 : comment.trim()) || undefined;
68
+ const trimmedEmail = (email === null || email === void 0 ? void 0 : email.trim()) || undefined;
66
69
  onSubmit({
67
70
  score,
68
- comment,
71
+ comment: trimmedComment,
69
72
  reasons,
70
73
  max: exports.FEEDBACK_MAX_RATING,
71
- email,
74
+ email: trimmedEmail,
72
75
  });
73
76
  setIsSubmitted(true);
74
77
  };
@@ -115,7 +118,7 @@ function Rating({ settings, onSubmit, className }) {
115
118
  React.createElement(InputLabel, { "data-translation-key": "feedback.settings.optionalEmail.label" }, (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.label) ||
116
119
  translate('feedback.settings.optionalEmail.label', 'Your email (optional, for follow-up)')),
117
120
  React.createElement(EmailInput, { onChange: onEmailChange, placeholder: (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.placeholder) ||
118
- translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", required: !!email, onKeyDown: (e) => {
121
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", maxLength: constants_1.MAX_EMAIL_LENGTH, required: !!email, onKeyDown: (e) => {
119
122
  if (e.key === 'Enter') {
120
123
  e.preventDefault();
121
124
  onSubmitRatingForm();
@@ -47,6 +47,7 @@ const RadioCheckButtonIcon_1 = require("../../icons/RadioCheckButtonIcon/RadioCh
47
47
  const Comment_1 = require("../../components/Feedback/Comment");
48
48
  const Reasons_1 = require("../../components/Feedback/Reasons");
49
49
  const Button_1 = require("../../components/Button/Button");
50
+ const constants_1 = require("../../core/constants");
50
51
  exports.MAX_SCALE = 10;
51
52
  function Scale({ settings, onSubmit, className }) {
52
53
  const { label, submitText, leftScaleLabel, rightScaleLabel, comment: commentSettings, reasons: reasonsSettings, optionalEmail: optionalEmailSettings, } = settings || {};
@@ -77,12 +78,14 @@ function Scale({ settings, onSubmit, className }) {
77
78
  setEmail(undefined);
78
79
  };
79
80
  const onSubmitScaleForm = () => {
81
+ const trimmedComment = (comment === null || comment === void 0 ? void 0 : comment.trim()) || undefined;
82
+ const trimmedEmail = (email === null || email === void 0 ? void 0 : email.trim()) || undefined;
80
83
  onSubmit({
81
84
  score,
82
- comment,
85
+ comment: trimmedComment,
83
86
  reasons,
84
87
  max: exports.MAX_SCALE,
85
- email,
88
+ email: trimmedEmail,
86
89
  });
87
90
  setIsSubmitted(true);
88
91
  };
@@ -122,7 +125,7 @@ function Scale({ settings, onSubmit, className }) {
122
125
  React.createElement(InputLabel, { "data-translation-key": "feedback.settings.optionalEmail.label" }, (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.label) ||
123
126
  translate('feedback.settings.optionalEmail.label', 'Your email (optional, for follow-up)')),
124
127
  React.createElement(EmailInput, { onChange: onEmailChange, placeholder: (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.placeholder) ||
125
- translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", required: !!email, onKeyDown: (e) => {
128
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", maxLength: constants_1.MAX_EMAIL_LENGTH, required: !!email, onKeyDown: (e) => {
126
129
  if (e.key === 'Enter') {
127
130
  e.preventDefault();
128
131
  onSubmitScaleForm();
@@ -47,6 +47,7 @@ const Comment_1 = require("../../components/Feedback/Comment");
47
47
  const Button_1 = require("../../components/Button/Button");
48
48
  const ThumbDownIcon_1 = require("../../icons/ThumbDownIcon/ThumbDownIcon");
49
49
  const ThumbUpIcon_1 = require("../../icons/ThumbUpIcon/ThumbUpIcon");
50
+ const constants_1 = require("../../core/constants");
50
51
  function Sentiment({ settings, onSubmit, className }) {
51
52
  const { label, submitText, comment: commentSettings, reasons: reasonsSettings, optionalEmail: optionalEmailSettings, } = settings || {};
52
53
  const [isSubmitted, setIsSubmitted] = React.useState(false);
@@ -105,11 +106,13 @@ function Sentiment({ settings, onSubmit, className }) {
105
106
  return scoreSpecificReasonSettings === null || scoreSpecificReasonSettings === void 0 ? void 0 : scoreSpecificReasonSettings.component;
106
107
  };
107
108
  const onSubmitSentimentForm = () => {
109
+ const trimmedComment = (comment === null || comment === void 0 ? void 0 : comment.trim()) || undefined;
110
+ const trimmedEmail = (email === null || email === void 0 ? void 0 : email.trim()) || undefined;
108
111
  onSubmit({
109
112
  score,
110
- comment,
113
+ comment: trimmedComment,
111
114
  reasons,
112
- email,
115
+ email: trimmedEmail,
113
116
  });
114
117
  setIsSubmitted(true);
115
118
  };
@@ -154,7 +157,7 @@ function Sentiment({ settings, onSubmit, className }) {
154
157
  React.createElement(InputLabel, { "data-translation-key": "feedback.settings.optionalEmail.label" }, (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.label) ||
155
158
  translate('feedback.settings.optionalEmail.label', 'Your email (optional, for follow-up)')),
156
159
  React.createElement(EmailInput, { onChange: onEmailChange, placeholder: (optionalEmailSettings === null || optionalEmailSettings === void 0 ? void 0 : optionalEmailSettings.placeholder) ||
157
- translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", required: !!email, onKeyDown: (e) => {
160
+ translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com'), type: "email", maxLength: constants_1.MAX_EMAIL_LENGTH, required: !!email, onKeyDown: (e) => {
158
161
  if (e.key === 'Enter') {
159
162
  e.preventDefault();
160
163
  onSubmitSentimentForm();
@@ -131,12 +131,12 @@ exports.mobileMenu = (0, styled_components_1.css) `
131
131
  * @tokens Mobile Menu
132
132
  * */
133
133
  /* Fallback for older browsers. dvh accounts for dynamic UI elements like mobile address bars */
134
- --menu-mobile-height: calc(100vh - var(--navbar-height));
135
- --menu-mobile-height: calc(100dvh - var(--navbar-height));
134
+ --menu-mobile-height: calc(100vh - var(--navbar-height) - var(--banner-height));
135
+ --menu-mobile-height: calc(100dvh - var(--navbar-height) - var(--banner-height));
136
136
  --menu-mobile-width: 100%;
137
137
  --menu-mobile-z-index: var(--z-index-raised);
138
138
  --menu-mobile-left: 0;
139
- --menu-mobile-top: var(--navbar-height);
139
+ --menu-mobile-top: calc(var(--navbar-height) + var(--banner-height));
140
140
  --menu-mobile-transition: 0.5s;
141
141
  --menu-mobile-bg: var(--bg-color); // @presenter Color
142
142
  --menu-mobile-margin: var(--menu-mobile-items-margin-top) var(--menu-mobile-margin-horizontal) 0 var(--menu-mobile-margin-horizontal);
@@ -115,7 +115,7 @@ const LinkMenuItem = (0, styled_components_1.default)(Link_1.Link) `
115
115
  --link-decoration-hover: none;
116
116
  `;
117
117
  const StyledDropdown = (0, styled_components_1.default)(Dropdown_1.Dropdown) `
118
- z-index: calc(var(--z-index-raised) - 1);
118
+ --dropdown-menu-z-index: calc(var(--z-index-raised) - 1);
119
119
  `;
120
120
  const StyledDropdownMenu = (0, styled_components_1.default)(DropdownMenu_1.DropdownMenu) `
121
121
  --dropdown-menu-max-height: var(--page-actions-dropdown-max-height);
@@ -0,0 +1,2 @@
1
+ export declare const MAX_EMAIL_LENGTH = 254;
2
+ export declare const MAX_CONTEXT_LENGTH = 5000;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_CONTEXT_LENGTH = exports.MAX_EMAIL_LENGTH = void 0;
4
+ exports.MAX_EMAIL_LENGTH = 254;
5
+ exports.MAX_CONTEXT_LENGTH = 5000;
6
+ //# sourceMappingURL=feedback.js.map
@@ -6,3 +6,4 @@ export * from './catalog';
6
6
  export * from './breadcrumb';
7
7
  export * from './request-methods';
8
8
  export * from './mcp';
9
+ export * from './feedback';
@@ -22,4 +22,5 @@ __exportStar(require("./catalog"), exports);
22
22
  __exportStar(require("./breadcrumb"), exports);
23
23
  __exportStar(require("./request-methods"), exports);
24
24
  __exportStar(require("./mcp"), exports);
25
+ __exportStar(require("./feedback"), exports);
25
26
  //# sourceMappingURL=index.js.map
@@ -26,3 +26,4 @@ export { isUndefined, isString, isNotNull, isObject } from '../utils/type-guards
26
26
  export { ThemeDataContext, type ThemeDataTransferObject } from '../contexts/ThemeDataContext';
27
27
  export { SearchSessionProvider, SearchSessionContext } from '../contexts/SearchContext';
28
28
  export { useUniqueSvgIds } from '../hooks/use-unique-svg-ids';
29
+ export { trimText } from '../utils/text-trimmer';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useUniqueSvgIds = exports.SearchSessionContext = exports.SearchSessionProvider = exports.ThemeDataContext = exports.isObject = exports.isNotNull = exports.isString = exports.isUndefined = exports.SecurityVariablesEnvSuffix = exports.useDialogHotKeys = exports.useSearchDialog = exports.useModalScrollLock = exports.useActiveSectionId = exports.useOutsideClick = exports.useThemeHooks = exports.useFocusTrap = exports.getUserAgent = exports.ClipboardService = exports.getOperationColor = exports.isPrimitive = exports.breakpoints = exports.GlobalStyle = exports.useMount = exports.typedMemo = exports.capitalize = exports.withPathPrefix = exports.addTrailingSlash = exports.combineUrls = exports.getPathPrefix = exports.removeLeadingSlash = exports.addLeadingSlash = exports.IS_BROWSER = void 0;
3
+ exports.trimText = exports.useUniqueSvgIds = exports.SearchSessionContext = exports.SearchSessionProvider = exports.ThemeDataContext = exports.isObject = exports.isNotNull = exports.isString = exports.isUndefined = exports.SecurityVariablesEnvSuffix = exports.useDialogHotKeys = exports.useSearchDialog = exports.useModalScrollLock = exports.useActiveSectionId = exports.useOutsideClick = exports.useThemeHooks = exports.useFocusTrap = exports.getUserAgent = exports.ClipboardService = exports.getOperationColor = exports.isPrimitive = exports.breakpoints = exports.GlobalStyle = exports.useMount = exports.typedMemo = exports.capitalize = exports.withPathPrefix = exports.addTrailingSlash = exports.combineUrls = exports.getPathPrefix = exports.removeLeadingSlash = exports.addLeadingSlash = exports.IS_BROWSER = void 0;
4
4
  var dom_1 = require("../utils/dom");
5
5
  Object.defineProperty(exports, "IS_BROWSER", { enumerable: true, get: function () { return dom_1.IS_BROWSER; } });
6
6
  var urls_1 = require("../utils/urls");
@@ -56,4 +56,6 @@ Object.defineProperty(exports, "SearchSessionProvider", { enumerable: true, get:
56
56
  Object.defineProperty(exports, "SearchSessionContext", { enumerable: true, get: function () { return SearchContext_1.SearchSessionContext; } });
57
57
  var use_unique_svg_ids_1 = require("../hooks/use-unique-svg-ids");
58
58
  Object.defineProperty(exports, "useUniqueSvgIds", { enumerable: true, get: function () { return use_unique_svg_ids_1.useUniqueSvgIds; } });
59
+ var text_trimmer_1 = require("../utils/text-trimmer");
60
+ Object.defineProperty(exports, "trimText", { enumerable: true, get: function () { return text_trimmer_1.trimText; } });
59
61
  //# sourceMappingURL=index.js.map
@@ -46,6 +46,16 @@ const replayDarkMode = (0, styled_components_1.css) `
46
46
 
47
47
  // @tokens End
48
48
  `;
49
+ const badgesDarkMode = (0, styled_components_1.css) `
50
+ /**
51
+ * @tokens Audience Badge
52
+ */
53
+
54
+ --badge-audience-text-color: var(--text-color-secondary); // @presenter Color
55
+ --badge-audience-bg-color: var(--color-warm-grey-4); // @presenter Color
56
+
57
+ // @tokens End
58
+ `;
49
59
  exports.darkMode = (0, styled_components_1.css) `
50
60
  /* === Dark Theme Colors === */
51
61
 
@@ -333,6 +343,7 @@ exports.darkMode = (0, styled_components_1.css) `
333
343
  ${variables_dark_15.bannerDarkMode}
334
344
  ${variables_dark_16.admonitionDarkMode}
335
345
  ${variables_dark_17.svgViewerDarkMode}
346
+ ${badgesDarkMode}
336
347
 
337
348
  /**
338
349
  * @tokens Dark Theme Scrollbar Config
@@ -815,6 +815,13 @@ const badges = (0, styled_components_1.css) `
815
815
  --badge-deprecated-bg-color: var(--color-warning-base); // @presenter Color
816
816
  --badge-deprecated-border-radius: var(--border-radius); // @presenter BorderRadius
817
817
 
818
+ /**
819
+ * @tokens Audience Badge
820
+ */
821
+
822
+ --badge-audience-text-color: var(--text-color-secondary); // @presenter Color
823
+ --badge-audience-bg-color: var(--color-warm-grey-2); // @presenter Color
824
+
818
825
  // @tokens End
819
826
  `;
820
827
  const loadProgressBar = (0, styled_components_1.css) `
@@ -1,5 +1,5 @@
1
1
  import type { TOptions } from 'i18next';
2
- export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.toolResult.found' | 'search.ai.toolResult.found.documents' | 'search.ai.toolCall.searching' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.tags.more' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to' | 'mermaid.openFullscreen' | 'mermaid.zoomIn' | 'mermaid.zoomOut' | 'mermaid.reset' | 'mermaid.close' | 'mermaid.viewer';
2
+ export type TranslationKey = 'dev.newApp' | 'dev.newApp.text' | 'dev.sidebar.header' | 'dev.sidebar.footer.text' | 'dev.create.app.dialog.appName.placeholder' | 'dev.create.app.dialog.appName.error' | 'dev.create.app.dialog.selectAPIs' | 'dev.create.app.dialog.description' | 'dev.create.app.dialog.description.placeholder' | 'dev.create.app.dialog.create' | 'dev.create.app.dialog.cancel' | 'dev.main.tab.appKeys' | 'dev.main.tab.logs' | 'dev.app.description.title' | 'dev.edit.description.dialog.title' | 'dev.edit.description.dialog.save' | 'dev.edit.description.dialog.cancel' | 'dev.edit.apis.dialog.selectedAPIs' | 'dev.app.key.create' | 'dev.create.key.dialog.title' | 'dev.create.key.dialog.create' | 'dev.create.key.dialog.cancel' | 'dev.app.edit' | 'dev.app.delete' | 'dev.edit.app.dialog.title' | 'dev.edit.app.dialog.save' | 'dev.edit.app.dialog.cancel' | 'dev.delete.app.dialog.title' | 'dev.delete.app.dialog.confirmation' | 'dev.delete.app.dialog.delete' | 'dev.delete.app.dialog.cancel' | 'dev.app.key.roll' | 'dev.roll.key.dialog.title' | 'dev.roll.key.dialog.apiKey' | 'dev.roll.key.dialog.expires' | 'dev.roll.key.dialog.confirmation' | 'dev.roll.key.dialog.cancel' | 'dev.roll.key.dialog.roll' | 'dev.update.key.dialog.title' | 'dev.update.key.dialog.update' | 'dev.update.key.dialog.cancel' | 'dev.app.key.api.name' | 'dev.app.key.api.status' | 'dev.app.key.api.edit' | 'dev.edit.apis.dialog.title' | 'dev.edit.apis.dialog.apiKey' | 'dev.edit.apis.dialog.save' | 'dev.edit.apis.dialog.cancel' | 'dev.select.placeholder' | 'dev.app.overview.status.pending' | 'dev.app.overview.status.approved' | 'dev.app.overview.status.revoked' | 'dev.app.overview.status' | 'dev.app.overview.non-production' | 'dev.app.overview.production' | 'dev.app.overview.clientId' | 'dev.app.overview.apiKey' | 'dev.app.key.revoke' | 'dev.revoke.key.dialog.title' | 'dev.revoke.key.dialog.apiKey' | 'dev.revoke.key.dialog.expires' | 'dev.revoke.key.dialog.confirmation' | 'dev.revoke.key.dialog.revoke' | 'dev.revoke.key.dialog.cancel' | 'dev.app.overview.expires' | 'dev.app.overview.created' | 'dev.app.overview.visibilityToggle.hide' | 'dev.app.overview.visibilityToggle.show' | 'search.loading' | 'search.noResults.title' | 'search.keys.navigate' | 'search.keys.select' | 'search.keys.exit' | 'search.label' | 'search.cancel' | 'search.recent' | 'search.navbar.label' | 'search.suggested' | 'search.showMore' | 'search.filter.title' | 'search.filter.reset' | 'search.filter.field.reset' | 'search.ai.welcomeText' | 'search.ai.newConversation' | 'search.ai.backToSearch' | 'search.ai.back' | 'search.ai.assistant' | 'search.ai.placeholder' | 'search.ai.generatingResponse' | 'search.ai.followUpQuestion' | 'search.ai.suggestionsTitle' | 'search.ai.thinkingText' | 'search.ai.resourcesFound' | 'search.ai.resourcesFound.basedOn' | 'search.ai.resourcesFound.resources' | 'search.ai.feedback.title' | 'search.ai.feedback.detailsPlaceholder' | 'search.ai.feedback.thanks' | 'search.ai.toolResult.found' | 'search.ai.toolResult.found.documents' | 'search.ai.toolCall.searching' | 'search.ai.button' | 'search.ai.label' | 'search.ai.disclaimer' | 'search.ai.error.description' | 'search.ai.error.description.forbidden' | 'search.ai.error.description.unauthorized' | 'search.ai.error.header' | 'search.ai.error.header.forbidden' | 'search.ai.error.header.unauthorized' | 'search.ai.feedback.more' | 'search.searchItem.deprecated' | 'search.groups.all' | 'search.filter.field.footer' | 'aiAssistant.trigger' | 'toc.header' | 'footer.copyrightText' | 'page.homeButton' | 'page.forbidden.title' | 'page.forbidden.description' | 'page.notFound.title' | 'page.notFound.description' | 'page.lastUpdated.timeago' | 'page.lastUpdated.on' | 'catalog.filters.placeholder' | 'catalog.filters.title' | 'catalog.filters.add' | 'catalog.filters.clearAll' | 'catalog.filters.select.addFilter' | 'catalog.filters.select.all' | 'catalog.filters.done' | 'catalog.catalogs.all.title' | 'catalog.catalogs.all.description' | 'catalog.catalogs.all.switcherLabel' | 'catalog.catalogs.service.title' | 'catalog.catalogs.service.description' | 'catalog.catalogs.service.switcherLabel' | 'catalog.catalogs.user.title' | 'catalog.catalogs.user.description' | 'catalog.catalogs.user.switcherLabel' | 'catalog.catalogs.team.title' | 'catalog.catalogs.team.description' | 'catalog.catalogs.team.switcherLabel' | 'catalog.catalogs.domain.title' | 'catalog.catalogs.domain.description' | 'catalog.catalogs.domain.switcherLabel' | 'catalog.catalogs.apiDescription.title' | 'catalog.catalogs.apiDescription.description' | 'catalog.catalogs.apiDescription.switcherLabel' | 'catalog.catalogs.dataSchema.title' | 'catalog.catalogs.dataSchema.description' | 'catalog.catalogs.dataSchema.switcherLabel' | 'catalog.catalogs.apiOperation.title' | 'catalog.catalogs.apiOperation.description' | 'catalog.catalogs.apiOperation.switcherLabel' | 'catalog.entity.metadata.title' | 'catalog.entity.schema.title' | 'catalog.entity.properties.apiDescription.title' | 'catalog.backToAllLabel' | 'catalog.tags.more' | 'catalog.tags.label' | 'catalog.sort' | 'catalog.catalogs.label' | 'catalog.owners.label' | 'catalog.repositories.label' | 'catalog.email.label' | 'catalog.format.label' | 'catalog.entityType.label' | 'catalog.domains.label' | 'catalog.contact.label' | 'catalog.methodAndPath.label' | 'catalog.links.label' | 'catalog.metadata.domains' | 'catalog.metadata.owners' | 'catalog.history.button.label' | 'catalog.history.sidebar.title' | 'catalog.history.sidebar.close' | 'catalog.history.version.label' | 'catalog.history.version.notSpecified' | 'catalog.history.version.default' | 'catalog.history.revisions.limitMessage' | 'catalog.history.revision.current' | 'catalog.history.revisions.showLess' | 'catalog.history.revisions.showMore' | 'sidebar.menu.backLabel' | 'sidebar.menu.backToLabel' | 'sidebar.actions.show' | 'sidebar.actions.hide' | 'sidebar.actions.changeToSingleColumn' | 'sidebar.actions.changeToTwoColumns' | 'sidebar.actions.singleColumn' | 'sidebar.actions.twoColumns' | 'versionPicker.label' | 'versionPicker.unversioned' | 'codeSnippet.copy.buttonText' | 'codeSnippet.copy.tooltipText' | 'codeSnippet.copy.toasterText' | 'markdown.editPage.text' | 'feedback.settings.comment.submitText' | 'feedback.settings.comment.label' | 'feedback.settings.comment.send' | 'feedback.settings.comment.cancel' | 'feedback.settings.comment.maxLength' | 'feedback.settings.comment.satisfiedLabel' | 'feedback.settings.comment.neutralLabel' | 'feedback.settings.comment.dissatisfiedLabel' | 'feedback.settings.submitText' | 'feedback.settings.label' | 'feedback.settings.reasons.label' | 'feedback.submit' | 'feedback.cancel' | 'feedback.settings.comment.likeLabel' | 'feedback.settings.comment.dislikeLabel' | 'feedback.sentiment.thumbUp' | 'feedback.sentiment.thumbDown' | 'feedback.settings.leftScaleLabel' | 'feedback.settings.rightScaleLabel' | 'feedback.settings.optionalEmail.placeholder' | 'feedback.settings.optionalEmail.label' | 'codeSnippet.report.buttonText' | 'codeSnippet.report.tooltipText' | 'codeSnippet.report.label' | 'codeSnippet.expand.tooltipText' | 'codeSnippet.collapse.tooltipText' | 'userMenu.login' | 'userMenu.logout' | 'userMenu.devOnboardingLabel' | 'mobileMenu.mainMenu' | 'mobileMenu.previous' | 'mobileMenu.products' | 'mobileMenu.version' | 'navbar.products' | 'page.nextButton' | 'page.previousButton' | 'page.actions.copyButtonText' | 'page.actions.copyTitle' | 'page.actions.copyDescription' | 'page.actions.viewAsMdTitle' | 'page.actions.viewAsMdButtonText' | 'page.actions.viewAsMdDescription' | 'page.actions.chatGptTitle' | 'page.actions.chatGptButtonText' | 'page.actions.chatGptDescription' | 'page.actions.claudeTitle' | 'page.actions.claudeButtonText' | 'page.actions.claudeDescription' | 'page.actions.cursorMcpButtonText' | 'page.actions.cursorMcpTitle' | 'page.actions.cursorMcpDescription' | 'page.actions.connectMcp' | 'page.actions.connectMcp.cursor' | 'page.actions.connectMcp.cursorDescription' | 'page.actions.connectMcp.vscode' | 'page.actions.connectMcp.vscodeDescription' | 'page.actions.connectMcp.copyConfig' | 'page.actions.connectMcp.copyConfigDescription' | 'openapi.download.description.title' | 'openapi.info.title' | 'openapi.info.contact.url' | 'openapi.info.contact.name' | 'openapi.info.license' | 'openapi.info.termsOfService' | 'openapi.info.metadata.title' | 'openapi.key' | 'openapi.value' | 'openapi.enum' | 'openapi.items' | 'openapi.default' | 'openapi.variable' | 'openapi.variables' | 'openapi.actions.show' | 'openapi.actions.hide' | 'openapi.actions.more' | 'openapi.languages.title' | 'openapi.servers.title' | 'openapi.operations' | 'openapi.webhooks' | 'openapi.description' | 'openapi.badges.deprecated' | 'openapi.badges.required' | 'openapi.badges.webhook' | 'openapi.request' | 'openapi.path' | 'openapi.query' | 'openapi.cookie' | 'openapi.header' | 'openapi.body' | 'openapi.responses' | 'openapi.response' | 'openapi.callbacks' | 'openapi.callbackRequest' | 'openapi.callbackResponse' | 'openapi.payload' | 'openapi.discriminator' | 'openapi.contentType' | 'openapi.tryIt' | 'openapi.loading' | 'openapi.example' | 'openapi.examples' | 'openapi.additionalProperties' | 'openapi.patternProperties' | 'openapi.required' | 'openapi.recursive' | 'openapi.complex' | 'openapi.hideExample' | 'openapi.showExample' | 'openapi.expandAll' | 'openapi.collapseAll' | 'openapi.viewSecurityDetails' | 'openapi.noResponseExample' | 'openapi.discriminator.searchPlaceholder' | 'openapi.discriminator.searchNoResults' | 'openapi.discriminator.defaultMapping' | 'openapi.discriminator.defaultMappingTooltip' | 'openapi.noResponseContent' | 'openapi.noRequestPayload' | 'openapi.hidePattern' | 'openapi.showPattern' | 'openapi.authorizationUrl' | 'openapi.tokenUrl' | 'openapi.refreshUrl' | 'openapi.showOptionalScopes' | 'openapi.hideOptionalScopes' | 'openapi.security' | 'openapi.httpAuthorizationScheme' | 'openapi.bearerFormat' | 'openapi.parameterName' | 'openapi.flowType' | 'openapi.connectUrl' | 'openapi.requiredScopes' | 'openapi.unsupportedLanguage' | 'openapi.failedToGenerateCodeSample' | 'openapi.schemaCatalogLink.title' | 'openapi.schemaCatalogLink.copyButtonTooltip' | 'openapi.schemaCatalogLink.copiedTooltip' | 'openapi.mcp.title' | 'openapi.mcp.endpoint' | 'openapi.mcp.tools' | 'openapi.mcp.protocolVersion' | 'openapi.mcp.capabilities' | 'openapi.mcp.experimentalCapabilities' | 'openapi.mcp.inputSchema' | 'openapi.mcp.inputExample' | 'openapi.mcp.outputSchema' | 'openapi.mcp.outputExample' | 'asyncapi.download.description.title' | 'asyncapi.info.title' | 'graphql.download.description.title' | 'graphql.info.title' | 'graphql.info.contact.url' | 'graphql.info.contact.name' | 'graphql.info.license' | 'graphql.info.termsOfService' | 'graphql.overview' | 'graphql.metadata' | 'graphql.key' | 'graphql.value' | 'graphql.queries' | 'graphql.mutations' | 'graphql.subscriptions' | 'graphql.directives' | 'graphql.objects' | 'graphql.interfaces' | 'graphql.unions' | 'graphql.enums' | 'graphql.inputs' | 'graphql.scalars' | 'graphql.arguments.label' | 'graphql.arguments.show' | 'graphql.arguments.hide' | 'graphql.arguments.here' | 'graphql.returnTypes.label' | 'graphql.returnTypes.show' | 'graphql.returnTypes.hide' | 'graphql.possibleTypes' | 'graphql.defaultValue' | 'graphql.deprecationReason' | 'graphql.requiredScopes' | 'graphql.viewSecurityDetails' | 'graphql.objectScopes' | 'graphql.fieldScopes' | 'graphql.implementedInterfaces' | 'graphql.nonNull' | 'graphql.required' | 'graphql.deprecated' | 'graphql.variables' | 'graphql.querySample' | 'graphql.mutationSample' | 'graphql.subscriptionSample' | 'graphql.responseSample' | 'graphql.locations' | 'graphql.sample' | 'graphql.referenced' | 'graphql.content.fragment' | 'codeWalkthrough.download' | 'codeWalkthrough.preview' | 'time.justNow' | 'time.past.second' | 'time.past.seconds' | 'time.past.minute' | 'time.past.minutes' | 'time.past.hour' | 'time.past.hours' | 'time.past.day' | 'time.past.days' | 'time.past.week' | 'time.past.weeks' | 'time.past.month' | 'time.past.months' | 'time.past.year' | 'time.past.years' | 'page.internalServerError.title' | 'page.internalServerError.description' | 'page.skipToContent.label' | 'select.noResults' | 'loaders.loading' | 'filter.dateRange.from' | 'filter.dateRange.to' | 'mermaid.openFullscreen' | 'mermaid.zoomIn' | 'mermaid.zoomOut' | 'mermaid.reset' | 'mermaid.close' | 'mermaid.viewer';
3
3
  export type Locale = {
4
4
  code: string;
5
5
  name: string;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { IconProps } from '../../icons/types';
3
+ export declare const DirectionRightIcon: import("styled-components").StyledComponent<(props: IconProps) => React.JSX.Element, any, {
4
+ 'data-component-name': string;
5
+ }, "data-component-name">;
@@ -0,0 +1,24 @@
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.DirectionRightIcon = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styled_components_1 = __importDefault(require("styled-components"));
9
+ const utils_1 = require("../../core/utils");
10
+ const Icon = (props) => (react_1.default.createElement("svg", Object.assign({ width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, props),
11
+ react_1.default.createElement("path", { d: "M9.5 4L8.79295 4.70705L11.0859 7H5C4.73478 7 4.48043 7.10536 4.29289 7.29289C4.10536 7.48043 4 7.73478 4 8V14H5V8H11.0859L8.79295 10.2929L9.5 11L13 7.5L9.5 4Z", fill: "#1A1C21" }),
12
+ react_1.default.createElement("path", { d: "M5 2H4V6H5V2Z", fill: "#1A1C21" })));
13
+ exports.DirectionRightIcon = (0, styled_components_1.default)(Icon).attrs(() => ({
14
+ 'data-component-name': 'icons/DirectionRightIcon/DirectionRightIcon',
15
+ })) `
16
+ path {
17
+ fill: ${({ color }) => (0, utils_1.getCssColorVariable)(color)};
18
+ }
19
+
20
+ height: ${({ size }) => size || '16px'};
21
+ width: ${({ size }) => size || '16px'};
22
+ vertical-align: middle;
23
+ `;
24
+ //# sourceMappingURL=DirectionRightIcon.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/theme",
3
- "version": "0.63.0-next.0",
3
+ "version": "0.63.0-next.2",
4
4
  "description": "Shared UI components lib",
5
5
  "keywords": [
6
6
  "theme",
@@ -62,8 +62,8 @@
62
62
  "typescript": "5.9.3",
63
63
  "vitest": "4.0.10",
64
64
  "vitest-when": "0.6.2",
65
- "webpack": "5.94.0",
66
- "@redocly/realm-asyncapi-sdk": "0.9.0-next.0"
65
+ "webpack": "5.105.2",
66
+ "@redocly/realm-asyncapi-sdk": "0.9.0-next.1"
67
67
  },
68
68
  "dependencies": {
69
69
  "@tanstack/react-query": "5.62.3",
@@ -78,7 +78,7 @@
78
78
  "lodash.debounce": "^4.0.8",
79
79
  "lodash.throttle": "4.1.1",
80
80
  "nprogress": "0.2.0",
81
- "openapi-sampler": "1.6.2",
81
+ "openapi-sampler": "1.7.0",
82
82
  "react-calendar": "5.1.0",
83
83
  "react-date-picker": "11.0.0",
84
84
  "@redocly/config": "0.43.0"
@@ -5,7 +5,7 @@ import type { JSX } from 'react';
5
5
 
6
6
  import { useThemeHooks } from '@redocly/theme/core/hooks';
7
7
  import { EditIcon } from '@redocly/theme/icons/EditIcon/EditIcon';
8
- import { Link } from '@redocly/theme/components/Link/Link';
8
+ import { Button } from '@redocly/theme/components/Button/Button';
9
9
 
10
10
  export type EditPageButtonProps = {
11
11
  to: string;
@@ -17,43 +17,22 @@ export function EditPageButton({ to }: EditPageButtonProps): JSX.Element {
17
17
  const telemetry = useTelemetry();
18
18
 
19
19
  return (
20
- <EditPageButtonWrapper
21
- data-component-name="Buttons/EditPageButton"
22
- target="_blank"
23
- to={to}
24
- onClick={() => telemetry.sendEditPageLinkClickedMessage()}
25
- >
26
- <ButtonIcon />
27
- <ButtonText data-translation-key="markdown.editPage.text">
20
+ <EditPageButtonWrapper data-component-name="Buttons/EditPageButton">
21
+ <Button
22
+ to={to}
23
+ external={true}
24
+ variant="ghost"
25
+ size="small"
26
+ icon={<EditIcon />}
27
+ onClick={() => telemetry.sendEditPageLinkClickedMessage()}
28
+ data-translation-key="markdown.editPage.text"
29
+ >
28
30
  {translate('markdown.editPage.text', 'Edit')}
29
- </ButtonText>
31
+ </Button>
30
32
  </EditPageButtonWrapper>
31
33
  );
32
34
  }
33
35
 
34
- const EditPageButtonWrapper = styled(Link)`
35
- height: fit-content;
36
+ const EditPageButtonWrapper = styled.div`
36
37
  margin-left: auto;
37
- display: inline-flex;
38
- color: var(--text-color-secondary);
39
- font-weight: var(--font-weight-bold);
40
- font-size: var(--font-size-base);
41
- font-family: var(--font-family-base);
42
- text-decoration: none;
43
-
44
- &:hover {
45
- color: var(--text-color-primary);
46
- }
47
-
48
- @media print {
49
- display: none;
50
- }
51
- `;
52
-
53
- const ButtonIcon = styled(EditIcon)`
54
- margin-right: 3px;
55
- `;
56
-
57
- const ButtonText = styled.span`
58
- line-height: 14px;
59
38
  `;
@@ -142,5 +142,5 @@ const ChildrenWrapper = styled.div<{ placement?: string; alignment?: string; isO
142
142
  right: ${({ alignment }) => (alignment === 'end' ? '0' : 'auto')};
143
143
  display: ${({ isOpen }) => (isOpen ? 'block' : 'none')};
144
144
 
145
- z-index: var(--z-index-raised);
145
+ z-index: var(--dropdown-menu-z-index);
146
146
  `;
@@ -8,6 +8,7 @@ export const dropdown = css`
8
8
  --dropdown-menu-font-weight: var(--font-weight-regular); // @presenter FontWeight
9
9
  --dropdown-menu-line-height: var(--line-height-base); // @presenter LineHeight
10
10
  --dropdown-menu-text-color: var(--text-color-secondary); // @presenter Color
11
+ --dropdown-menu-z-index: var(--z-index-raised); // @presenter ZIndex
11
12
 
12
13
  --dropdown-menu-padding-top: var(--spacing-xxs);
13
14
  --dropdown-menu-min-width: 100px;
@@ -6,6 +6,7 @@ import type { JSX } from 'react';
6
6
  import { useOutsideClick, useThemeHooks } from '@redocly/theme/core/hooks';
7
7
  import { RadioCheckButtonIcon } from '@redocly/theme/icons/RadioCheckButtonIcon/RadioCheckButtonIcon';
8
8
  import { Button } from '@redocly/theme/components/Button/Button';
9
+ import { MAX_CONTEXT_LENGTH } from '@redocly/theme/core/constants';
9
10
 
10
11
  export type CommentProps = {
11
12
  onSubmit: (value: { comment: string }) => void;
@@ -32,18 +33,21 @@ export function Comment({
32
33
  const { label, submitText } = settings || {};
33
34
  const [text, setText] = React.useState('');
34
35
  const [submitValue, setSubmitValue] = React.useState('');
36
+ const [isMaxLengthReached, setIsMaxLengthReached] = React.useState(false);
35
37
  const modalRef = useRef<HTMLDivElement>(null);
36
38
 
37
39
  useOutsideClick(modalRef, onCancel);
38
40
 
39
41
  const send = () => {
40
- if (!text) return;
41
- setSubmitValue(text);
42
- onSubmit({ comment: text });
42
+ const trimmedText = text.trim();
43
+ if (!trimmedText) return;
44
+ setSubmitValue(trimmedText);
45
+ onSubmit({ comment: trimmedText });
43
46
  };
44
47
  const handleTextAreaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
45
48
  const commentValue = e.target.value;
46
49
  setText(commentValue);
50
+ setIsMaxLengthReached(commentValue.length >= MAX_CONTEXT_LENGTH);
47
51
 
48
52
  if (!standAlone) {
49
53
  onSubmit({ comment: commentValue });
@@ -81,7 +85,15 @@ export function Comment({
81
85
  {label ||
82
86
  translate('feedback.settings.comment.label', 'Please share your feedback with us.')}
83
87
  </Label>
84
- <TextArea rows={3} onChange={handleTextAreaChange} />
88
+ <TextArea rows={3} maxLength={MAX_CONTEXT_LENGTH} onChange={handleTextAreaChange} />
89
+ {isMaxLengthReached && (
90
+ <MaxLengthMessage data-translation-key="feedback.settings.comment.maxLength">
91
+ {translate('feedback.settings.comment.maxLength', {
92
+ maxLength: MAX_CONTEXT_LENGTH,
93
+ defaultValue: `Maximum content length of ${MAX_CONTEXT_LENGTH} characters reached`,
94
+ })}
95
+ </MaxLengthMessage>
96
+ )}
85
97
  {standAlone && (
86
98
  <ButtonsContainer>
87
99
  {onCancel && (
@@ -175,3 +187,9 @@ const ButtonsContainer = styled.div`
175
187
  margin-top: var(--spacing-xs);
176
188
  gap: var(--spacing-xs);
177
189
  `;
190
+
191
+ const MaxLengthMessage = styled.div`
192
+ font-size: var(--font-size-sm);
193
+ color: var(--text-color-secondary);
194
+ margin-top: var(--spacing-xxs);
195
+ `;
@@ -14,6 +14,7 @@ import { Button } from '@redocly/theme/components/Button/Button';
14
14
  import { FaceDissatisfiedIcon } from '@redocly/theme/icons/FaceDissatisfiedIcon/FaceDissatisfiedIcon';
15
15
  import { FaceSatisfiedIcon } from '@redocly/theme/icons/FaceSatisfiedIcon/FaceSatisfiedIcon';
16
16
  import { FaceNeutralIcon } from '@redocly/theme/icons/FaceNeutralIcon/FaceNeutralIcon';
17
+ import { MAX_EMAIL_LENGTH } from '@redocly/theme/core/constants';
17
18
 
18
19
  export enum MOOD_STATES {
19
20
  SATISFIED = 'satisfied',
@@ -135,11 +136,13 @@ export function Mood({ settings, onSubmit, className }: MoodProps): JSX.Element
135
136
  const displayFeedbackEmail = !!score && !optionalEmailSettings?.hide && !userData.isAuthenticated;
136
137
 
137
138
  const onSubmitMoodForm = () => {
139
+ const trimmedComment = comment?.trim() || undefined;
140
+ const trimmedEmail = email?.trim() || undefined;
138
141
  onSubmit({
139
142
  score: remapScore(score),
140
- comment,
143
+ comment: trimmedComment,
141
144
  reasons,
142
- email,
145
+ email: trimmedEmail,
143
146
  });
144
147
  setIsSubmitted(true);
145
148
  };
@@ -255,6 +258,7 @@ export function Mood({ settings, onSubmit, className }: MoodProps): JSX.Element
255
258
  translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
256
259
  }
257
260
  type="email"
261
+ maxLength={MAX_EMAIL_LENGTH}
258
262
  required={!!email}
259
263
  onKeyDown={(e) => {
260
264
  if (e.key === 'Enter') {
@@ -12,6 +12,7 @@ import { RadioCheckButtonIcon } from '@redocly/theme/icons/RadioCheckButtonIcon/
12
12
  import { Comment } from '@redocly/theme/components/Feedback/Comment';
13
13
  import { Stars } from '@redocly/theme/components/Feedback/Stars';
14
14
  import { Button } from '@redocly/theme/components/Button/Button';
15
+ import { MAX_EMAIL_LENGTH } from '@redocly/theme/core/constants';
15
16
 
16
17
  export const FEEDBACK_MAX_RATING = 5;
17
18
 
@@ -64,12 +65,14 @@ export function Rating({ settings, onSubmit, className }: RatingProps): JSX.Elem
64
65
  };
65
66
 
66
67
  const onSubmitRatingForm = () => {
68
+ const trimmedComment = comment?.trim() || undefined;
69
+ const trimmedEmail = email?.trim() || undefined;
67
70
  onSubmit({
68
71
  score,
69
- comment,
72
+ comment: trimmedComment,
70
73
  reasons,
71
74
  max: FEEDBACK_MAX_RATING,
72
- email,
75
+ email: trimmedEmail,
73
76
  });
74
77
  setIsSubmitted(true);
75
78
  };
@@ -168,6 +171,7 @@ export function Rating({ settings, onSubmit, className }: RatingProps): JSX.Elem
168
171
  translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
169
172
  }
170
173
  type="email"
174
+ maxLength={MAX_EMAIL_LENGTH}
171
175
  required={!!email}
172
176
  onKeyDown={(e) => {
173
177
  if (e.key === 'Enter') {
@@ -12,6 +12,7 @@ import { RadioCheckButtonIcon } from '@redocly/theme/icons/RadioCheckButtonIcon/
12
12
  import { Comment } from '@redocly/theme/components/Feedback/Comment';
13
13
  import { Reasons } from '@redocly/theme/components/Feedback/Reasons';
14
14
  import { Button } from '@redocly/theme/components/Button/Button';
15
+ import { MAX_EMAIL_LENGTH } from '@redocly/theme/core/constants';
15
16
 
16
17
  export const MAX_SCALE = 10;
17
18
 
@@ -96,12 +97,14 @@ export function Scale({ settings, onSubmit, className }: ScaleProps): JSX.Elemen
96
97
  };
97
98
 
98
99
  const onSubmitScaleForm = () => {
100
+ const trimmedComment = comment?.trim() || undefined;
101
+ const trimmedEmail = email?.trim() || undefined;
99
102
  onSubmit({
100
103
  score,
101
- comment,
104
+ comment: trimmedComment,
102
105
  reasons,
103
106
  max: MAX_SCALE,
104
- email,
107
+ email: trimmedEmail,
105
108
  });
106
109
  setIsSubmitted(true);
107
110
  };
@@ -193,6 +196,7 @@ export function Scale({ settings, onSubmit, className }: ScaleProps): JSX.Elemen
193
196
  translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
194
197
  }
195
198
  type="email"
199
+ maxLength={MAX_EMAIL_LENGTH}
196
200
  required={!!email}
197
201
  onKeyDown={(e) => {
198
202
  if (e.key === 'Enter') {
@@ -13,6 +13,7 @@ import { Comment } from '@redocly/theme/components/Feedback/Comment';
13
13
  import { Button } from '@redocly/theme/components/Button/Button';
14
14
  import { ThumbDownIcon } from '@redocly/theme/icons/ThumbDownIcon/ThumbDownIcon';
15
15
  import { ThumbUpIcon } from '@redocly/theme/icons/ThumbUpIcon/ThumbUpIcon';
16
+ import { MAX_EMAIL_LENGTH } from '@redocly/theme/core/constants';
16
17
 
17
18
  export type SentimentProps = {
18
19
  onSubmit: (value: {
@@ -117,11 +118,13 @@ export function Sentiment({ settings, onSubmit, className }: SentimentProps): JS
117
118
  };
118
119
 
119
120
  const onSubmitSentimentForm = () => {
121
+ const trimmedComment = comment?.trim() || undefined;
122
+ const trimmedEmail = email?.trim() || undefined;
120
123
  onSubmit({
121
124
  score,
122
- comment,
125
+ comment: trimmedComment,
123
126
  reasons,
124
- email,
127
+ email: trimmedEmail,
125
128
  });
126
129
  setIsSubmitted(true);
127
130
  };
@@ -227,6 +230,7 @@ export function Sentiment({ settings, onSubmit, className }: SentimentProps): JS
227
230
  translate('feedback.settings.optionalEmail.placeholder', 'yourname@example.com')
228
231
  }
229
232
  type="email"
233
+ maxLength={MAX_EMAIL_LENGTH}
230
234
  required={!!email}
231
235
  onKeyDown={(e) => {
232
236
  if (e.key === 'Enter') {
@@ -130,12 +130,12 @@ export const mobileMenu = css`
130
130
  * @tokens Mobile Menu
131
131
  * */
132
132
  /* Fallback for older browsers. dvh accounts for dynamic UI elements like mobile address bars */
133
- --menu-mobile-height: calc(100vh - var(--navbar-height));
134
- --menu-mobile-height: calc(100dvh - var(--navbar-height));
133
+ --menu-mobile-height: calc(100vh - var(--navbar-height) - var(--banner-height));
134
+ --menu-mobile-height: calc(100dvh - var(--navbar-height) - var(--banner-height));
135
135
  --menu-mobile-width: 100%;
136
136
  --menu-mobile-z-index: var(--z-index-raised);
137
137
  --menu-mobile-left: 0;
138
- --menu-mobile-top: var(--navbar-height);
138
+ --menu-mobile-top: calc(var(--navbar-height) + var(--banner-height));
139
139
  --menu-mobile-transition: 0.5s;
140
140
  --menu-mobile-bg: var(--bg-color); // @presenter Color
141
141
  --menu-mobile-margin: var(--menu-mobile-items-margin-top) var(--menu-mobile-margin-horizontal) 0 var(--menu-mobile-margin-horizontal);
@@ -119,7 +119,7 @@ const LinkMenuItem = styled(Link)`
119
119
  `;
120
120
 
121
121
  const StyledDropdown = styled(Dropdown)`
122
- z-index: calc(var(--z-index-raised) - 1);
122
+ --dropdown-menu-z-index: calc(var(--z-index-raised) - 1);
123
123
  `;
124
124
 
125
125
  const StyledDropdownMenu = styled(DropdownMenu)`
@@ -0,0 +1,2 @@
1
+ export const MAX_EMAIL_LENGTH = 254;
2
+ export const MAX_CONTEXT_LENGTH = 5000;
@@ -6,3 +6,4 @@ export * from './catalog';
6
6
  export * from './breadcrumb';
7
7
  export * from './request-methods';
8
8
  export * from './mcp';
9
+ export * from './feedback';
@@ -39,3 +39,4 @@ export { isUndefined, isString, isNotNull, isObject } from '../utils/type-guards
39
39
  export { ThemeDataContext, type ThemeDataTransferObject } from '../contexts/ThemeDataContext';
40
40
  export { SearchSessionProvider, SearchSessionContext } from '../contexts/SearchContext';
41
41
  export { useUniqueSvgIds } from '../hooks/use-unique-svg-ids';
42
+ export { trimText } from '../utils/text-trimmer';
@@ -46,6 +46,17 @@ const replayDarkMode = css`
46
46
  // @tokens End
47
47
  `;
48
48
 
49
+ const badgesDarkMode = css`
50
+ /**
51
+ * @tokens Audience Badge
52
+ */
53
+
54
+ --badge-audience-text-color: var(--text-color-secondary); // @presenter Color
55
+ --badge-audience-bg-color: var(--color-warm-grey-4); // @presenter Color
56
+
57
+ // @tokens End
58
+ `
59
+
49
60
 
50
61
  export const darkMode = css`
51
62
  /* === Dark Theme Colors === */
@@ -334,6 +345,7 @@ export const darkMode = css`
334
345
  ${bannerDarkMode}
335
346
  ${admonitionDarkMode}
336
347
  ${svgViewerDarkMode}
348
+ ${badgesDarkMode}
337
349
 
338
350
  /**
339
351
  * @tokens Dark Theme Scrollbar Config
@@ -823,6 +823,13 @@ const badges = css`
823
823
  --badge-deprecated-bg-color: var(--color-warning-base); // @presenter Color
824
824
  --badge-deprecated-border-radius: var(--border-radius); // @presenter BorderRadius
825
825
 
826
+ /**
827
+ * @tokens Audience Badge
828
+ */
829
+
830
+ --badge-audience-text-color: var(--text-color-secondary); // @presenter Color
831
+ --badge-audience-bg-color: var(--color-warm-grey-2); // @presenter Color
832
+
826
833
  // @tokens End
827
834
  `;
828
835
 
@@ -203,6 +203,7 @@ export type TranslationKey =
203
203
  | 'feedback.settings.comment.label'
204
204
  | 'feedback.settings.comment.send'
205
205
  | 'feedback.settings.comment.cancel'
206
+ | 'feedback.settings.comment.maxLength'
206
207
  | 'feedback.settings.comment.satisfiedLabel'
207
208
  | 'feedback.settings.comment.neutralLabel'
208
209
  | 'feedback.settings.comment.dissatisfiedLabel'
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import type { IconProps } from '@redocly/theme/icons/types';
5
+
6
+ import { getCssColorVariable } from '@redocly/theme/core/utils';
7
+
8
+ const Icon = (props: IconProps) => (
9
+ <svg
10
+ width="16"
11
+ height="16"
12
+ viewBox="0 0 16 16"
13
+ fill="none"
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ {...props}
16
+ >
17
+ <path
18
+ d="M9.5 4L8.79295 4.70705L11.0859 7H5C4.73478 7 4.48043 7.10536 4.29289 7.29289C4.10536 7.48043 4 7.73478 4 8V14H5V8H11.0859L8.79295 10.2929L9.5 11L13 7.5L9.5 4Z"
19
+ fill="#1A1C21"
20
+ />
21
+ <path d="M5 2H4V6H5V2Z" fill="#1A1C21" />
22
+ </svg>
23
+ );
24
+
25
+ export const DirectionRightIcon = styled(Icon).attrs(() => ({
26
+ 'data-component-name': 'icons/DirectionRightIcon/DirectionRightIcon',
27
+ }))`
28
+ path {
29
+ fill: ${({ color }) => getCssColorVariable(color)};
30
+ }
31
+
32
+ height: ${({ size }) => size || '16px'};
33
+ width: ${({ size }) => size || '16px'};
34
+ vertical-align: middle;
35
+ `;