@redocly/theme 0.70.0-next.1 → 0.70.0-next.3
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.
- package/lib/components/CodeBlock/CodeBlockControls.js +3 -5
- package/lib/components/Consent/Consent.d.ts +2 -0
- package/lib/components/Consent/Consent.js +17 -0
- package/lib/components/Consent/ConsentBanner.d.ts +2 -0
- package/lib/components/Consent/ConsentBanner.js +120 -0
- package/lib/components/Consent/ConsentDialog.d.ts +2 -0
- package/lib/components/Consent/ConsentDialog.js +128 -0
- package/lib/components/Consent/ConsentSettingsLink.d.ts +2 -0
- package/lib/components/Consent/ConsentSettingsLink.js +35 -0
- package/lib/components/Consent/variables.d.ts +1 -0
- package/lib/components/Consent/variables.js +31 -0
- package/lib/components/Footer/Footer.js +4 -1
- package/lib/components/JsonViewer/Helpers.d.ts +10 -2
- package/lib/components/JsonViewer/Helpers.js +29 -33
- package/lib/components/JsonViewer/JsonViewer.js +15 -18
- package/lib/components/Markdown/styles/base-table.js +14 -1
- package/lib/components/Markdown/variables.js +1 -0
- package/lib/components/Product/utils.js +1 -1
- package/lib/components/Search/SearchAiConversationInput.js +10 -6
- package/lib/components/Search/SearchAiDialog.js +8 -1
- package/lib/components/Search/SearchAiMessage.js +1 -1
- package/lib/components/Search/SearchAiResponse.js +1 -0
- package/lib/components/Search/SearchItem.js +9 -1
- package/lib/core/constants/consent.d.ts +2 -0
- package/lib/core/constants/consent.js +30 -0
- package/lib/core/constants/index.d.ts +1 -0
- package/lib/core/constants/index.js +1 -0
- package/lib/core/constants/search.d.ts +1 -1
- package/lib/core/constants/search.js +1 -1
- package/lib/core/hooks/index.d.ts +2 -0
- package/lib/core/hooks/index.js +2 -0
- package/lib/core/hooks/use-consent-dialog.d.ts +12 -0
- package/lib/core/hooks/use-consent-dialog.js +36 -0
- package/lib/core/hooks/use-consent-telemetry.d.ts +1 -0
- package/lib/core/hooks/use-consent-telemetry.js +42 -0
- package/lib/core/hooks/use-dialog-hotkeys.js +4 -2
- package/lib/core/hooks/use-theme-hooks.js +14 -0
- package/lib/core/styles/global.js +42 -40
- package/lib/core/types/consent.d.ts +54 -0
- package/lib/core/types/consent.js +3 -0
- package/lib/core/types/hooks.d.ts +2 -0
- package/lib/core/types/index.d.ts +1 -0
- package/lib/core/types/l10n.d.ts +1 -1
- package/lib/core/types/search.d.ts +2 -0
- package/lib/core/utils/consent-settings-link-placement.d.ts +3 -0
- package/lib/core/utils/consent-settings-link-placement.js +15 -0
- package/lib/core/utils/index.d.ts +1 -0
- package/lib/core/utils/index.js +1 -0
- package/lib/core/utils/mcp.js +1 -1
- package/lib/core/utils/menu.js +6 -5
- package/lib/core/utils/urls.js +3 -1
- package/lib/icons/ExpandCollapseIcon/ExpandCollapseIcon.d.ts +29 -0
- package/lib/icons/ExpandCollapseIcon/ExpandCollapseIcon.js +81 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +3 -3
- package/src/components/CodeBlock/CodeBlockControls.tsx +4 -7
- package/src/components/Consent/Consent.tsx +18 -0
- package/src/components/Consent/ConsentBanner.tsx +110 -0
- package/src/components/Consent/ConsentDialog.tsx +210 -0
- package/src/components/Consent/ConsentSettingsLink.tsx +44 -0
- package/src/components/Consent/variables.ts +28 -0
- package/src/components/Footer/Footer.tsx +2 -0
- package/src/components/JsonViewer/Helpers.tsx +46 -51
- package/src/components/JsonViewer/JsonViewer.tsx +23 -25
- package/src/components/Markdown/styles/base-table.ts +14 -1
- package/src/components/Markdown/variables.ts +1 -0
- package/src/components/Product/utils.ts +1 -1
- package/src/components/Search/SearchAiConversationInput.tsx +13 -7
- package/src/components/Search/SearchAiDialog.tsx +16 -1
- package/src/components/Search/SearchAiMessage.tsx +1 -1
- package/src/components/Search/SearchAiResponse.tsx +1 -0
- package/src/components/Search/SearchItem.tsx +14 -0
- package/src/core/constants/consent.ts +29 -0
- package/src/core/constants/index.ts +1 -0
- package/src/core/constants/search.ts +1 -1
- package/src/core/hooks/__mocks__/use-theme-hooks.ts +15 -0
- package/src/core/hooks/code-walkthrough/__mocks__/MockIntersectionObserver.ts +1 -2
- package/src/core/hooks/code-walkthrough/__mocks__/mock-intersection-observer.ts +1 -2
- package/src/core/hooks/index.ts +2 -0
- package/src/core/hooks/use-consent-dialog.ts +51 -0
- package/src/core/hooks/use-consent-telemetry.ts +56 -0
- package/src/core/hooks/use-dialog-hotkeys.ts +11 -5
- package/src/core/hooks/use-theme-hooks.ts +14 -0
- package/src/core/styles/global.ts +2 -0
- package/src/core/types/consent.ts +51 -0
- package/src/core/types/hooks.ts +2 -0
- package/src/core/types/index.ts +1 -0
- package/src/core/types/l10n.ts +25 -1
- package/src/core/types/search.ts +2 -0
- package/src/core/utils/consent-settings-link-placement.ts +18 -0
- package/src/core/utils/index.ts +1 -0
- package/src/core/utils/mcp.ts +1 -1
- package/src/core/utils/menu.ts +5 -6
- package/src/core/utils/urls.ts +3 -1
- package/src/icons/ExpandCollapseIcon/ExpandCollapseIcon.tsx +56 -0
- package/src/index.ts +1 -0
|
@@ -48,17 +48,21 @@ function SearchAiConversationInput({ isGeneratingResponse, onMessageSent, classN
|
|
|
48
48
|
const { useTranslate } = (0, hooks_1.useThemeHooks)();
|
|
49
49
|
const { translate } = useTranslate();
|
|
50
50
|
const inputRef = (0, react_1.useRef)(null);
|
|
51
|
+
const wasGeneratingResponseRef = (0, react_1.useRef)(isGeneratingResponse);
|
|
51
52
|
const [query, setQuery] = (0, react_1.useState)('');
|
|
52
53
|
(0, react_1.useEffect)(() => {
|
|
53
|
-
|
|
54
|
+
const wasGeneratingResponse = wasGeneratingResponseRef.current;
|
|
55
|
+
wasGeneratingResponseRef.current = isGeneratingResponse;
|
|
56
|
+
if (wasGeneratingResponse && !isGeneratingResponse) {
|
|
54
57
|
requestAnimationFrame(() => {
|
|
55
58
|
var _a;
|
|
56
59
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
57
60
|
});
|
|
58
61
|
}
|
|
59
62
|
}, [isGeneratingResponse]);
|
|
63
|
+
const isDisabled = disabled || isGeneratingResponse || query.trim().length === 0;
|
|
60
64
|
const handleSendMessage = () => {
|
|
61
|
-
if (
|
|
65
|
+
if (isDisabled)
|
|
62
66
|
return;
|
|
63
67
|
setQuery('');
|
|
64
68
|
onMessageSent(query);
|
|
@@ -72,7 +76,6 @@ function SearchAiConversationInput({ isGeneratingResponse, onMessageSent, classN
|
|
|
72
76
|
handleSendMessage();
|
|
73
77
|
}
|
|
74
78
|
};
|
|
75
|
-
const isDisabled = disabled || isGeneratingResponse || query.trim().length === 0;
|
|
76
79
|
const commonProps = {
|
|
77
80
|
placeholder: placeholder || translate('search.ai.followUpQuestion', 'Ask a follow up question?'),
|
|
78
81
|
onChange: (e) => setQuery(e.target.value),
|
|
@@ -83,7 +86,7 @@ function SearchAiConversationInput({ isGeneratingResponse, onMessageSent, classN
|
|
|
83
86
|
};
|
|
84
87
|
return (react_1.default.createElement(SearchAiConversationInputWrapper, { "data-component-name": "Search/SearchAiConversationInput", className: className },
|
|
85
88
|
multiline ? (react_1.default.createElement(ConversationTextarea, Object.assign({ ref: inputRef }, commonProps))) : (react_1.default.createElement(ConversationInput, Object.assign({ ref: inputRef, type: "text" }, commonProps))),
|
|
86
|
-
react_1.default.createElement(SendButton, { disabled: isDisabled, size: "small", icon: react_1.default.createElement(SendIcon_1.SendIcon, { color: isDisabled
|
|
89
|
+
react_1.default.createElement(SendButton, { "aria-label": translate('search.ai.send', 'Send question'), "aria-disabled": isDisabled, size: "small", icon: react_1.default.createElement(SendIcon_1.SendIcon, { color: isDisabled
|
|
87
90
|
? '--button-content-color-disabled'
|
|
88
91
|
: 'var(--search-ai-conversation-input-send-button-icon-color)' }), onClick: handleSendMessage })));
|
|
89
92
|
}
|
|
@@ -151,11 +154,12 @@ const SendButton = (0, styled_components_1.default)(Button_1.Button) `
|
|
|
151
154
|
border-radius: var(--search-ai-conversation-input-send-button-border-radius);
|
|
152
155
|
padding: var(--search-ai-conversation-input-send-button-padding);
|
|
153
156
|
|
|
154
|
-
&:hover {
|
|
157
|
+
&:hover:not([aria-disabled='true']) {
|
|
155
158
|
background-color: var(--search-ai-conversation-input-send-button-bg-color-hover);
|
|
156
159
|
}
|
|
157
160
|
|
|
158
|
-
|
|
161
|
+
&[aria-disabled='true'] {
|
|
162
|
+
cursor: default;
|
|
159
163
|
background-color: var(--search-ai-conversation-input-send-button-bg-color-disabled);
|
|
160
164
|
border: var(--search-ai-conversation-input-send-button-border-disabled);
|
|
161
165
|
}
|
|
@@ -52,6 +52,13 @@ function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error,
|
|
|
52
52
|
const { aiAssistant } = (0, hooks_1.useThemeConfig)();
|
|
53
53
|
const { translate } = useTranslate();
|
|
54
54
|
const conversationEndRef = react_1.default.useRef(null);
|
|
55
|
+
const wrapperRef = react_1.default.useRef(null);
|
|
56
|
+
(0, react_1.useEffect)(() => {
|
|
57
|
+
requestAnimationFrame(() => {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
(_b = (_a = wrapperRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('[data-component-name="Search/SearchAiConversationInput"] :is(input, textarea):not(:disabled)')) === null || _b === void 0 ? void 0 : _b.focus();
|
|
60
|
+
});
|
|
61
|
+
}, []);
|
|
55
62
|
const suggestions = (_a = aiAssistant === null || aiAssistant === void 0 ? void 0 : aiAssistant.suggestions) !== null && _a !== void 0 ? _a : [];
|
|
56
63
|
const placeholder = isGeneratingResponse
|
|
57
64
|
? translate('search.ai.generatingResponse', 'Generating response...')
|
|
@@ -139,7 +146,7 @@ function SearchAiDialog({ isGeneratingResponse, response, initialMessage, error,
|
|
|
139
146
|
const handleFeedbackChange = (0, react_1.useCallback)((messageId, feedback) => {
|
|
140
147
|
setConversation((prev) => prev.map((item) => (item.messageId === messageId ? Object.assign(Object.assign({}, item), { feedback }) : item)));
|
|
141
148
|
}, [setConversation]);
|
|
142
|
-
return (react_1.default.createElement(SearchAiDialogWrapper, { "data-component-name": "Search/SearchAiDialog", className: className },
|
|
149
|
+
return (react_1.default.createElement(SearchAiDialogWrapper, { ref: wrapperRef, "data-component-name": "Search/SearchAiDialog", className: className },
|
|
143
150
|
!conversation.length && (react_1.default.createElement(WelcomeWrapper, null,
|
|
144
151
|
react_1.default.createElement(AiStarsIcon_1.AiStarsIcon, { color: "var(--search-ai-icon-color)", size: "32px", background: "var(--search-ai-icon-bg-color)", borderRadius: "var(--border-radius-lg)", margin: "0 var(--spacing-xs) 0 0" }),
|
|
145
152
|
translate('search.ai.welcomeText', 'Welcome to AI assistant! Feel free to ask me anything. How can I help you? '))),
|
|
@@ -251,7 +251,7 @@ const ResourceTagsWrapper = styled_components_1.default.div `
|
|
|
251
251
|
flex-wrap: wrap;
|
|
252
252
|
gap: var(--search-ai-resource-tags-gap);
|
|
253
253
|
`;
|
|
254
|
-
const ResourceTag = (0, styled_components_1.default)(Tag_1.Tag) `
|
|
254
|
+
const ResourceTag = (0, styled_components_1.default)(Tag_1.Tag).attrs({ textTransform: 'none' }) `
|
|
255
255
|
.tag-default {
|
|
256
256
|
--tag-color: var(--search-ai-resource-tag-text-color);
|
|
257
257
|
max-width: 100%;
|
|
@@ -141,6 +141,7 @@ const ResourceTags = styled_components_1.default.div `
|
|
|
141
141
|
`;
|
|
142
142
|
const ResourceTag = (0, styled_components_1.default)(Tag_1.Tag).attrs({
|
|
143
143
|
className: 'tag-resource',
|
|
144
|
+
textTransform: 'none',
|
|
144
145
|
}) `
|
|
145
146
|
.tag-default {
|
|
146
147
|
--tag-color: --search-ai-resource-tag-text-color;
|
|
@@ -99,7 +99,15 @@ function SearchItem({ onClick, item, className, product, innerRef, }) {
|
|
|
99
99
|
(0, SearchHighlight_1.searchHighlight)(parameter.path.join(' → ')),
|
|
100
100
|
` → `)) : null,
|
|
101
101
|
(0, SearchHighlight_1.searchHighlight)(parameter.name)),
|
|
102
|
-
react_1.default.createElement("div", null, (0, SearchHighlight_1.searchHighlight)(parameter.description))
|
|
102
|
+
react_1.default.createElement("div", null, (0, SearchHighlight_1.searchHighlight)(parameter.description)),
|
|
103
|
+
parameter.enum ? (react_1.default.createElement("div", null,
|
|
104
|
+
translate('search.searchItem.enum', 'Enum'),
|
|
105
|
+
': ',
|
|
106
|
+
(0, SearchHighlight_1.searchHighlight)(parameter.enum))) : null,
|
|
107
|
+
parameter.example ? (react_1.default.createElement("div", null,
|
|
108
|
+
translate('search.searchItem.example', 'Example'),
|
|
109
|
+
': ',
|
|
110
|
+
(0, SearchHighlight_1.searchHighlight)(parameter.example))) : null)) : (shouldShowPath && (react_1.default.createElement(SearchItemPath, null, highlight.path && highlight.path.length
|
|
103
111
|
? (0, SearchHighlight_1.searchHighlight)(highlight.path.join(' → '))
|
|
104
112
|
: (_c = document.path) === null || _c === void 0 ? void 0 : _c.join(' → '))))),
|
|
105
113
|
react_1.default.createElement(ReturnKeyIcon_1.ReturnKeyIcon, { color: "var(--search-item-text-color)" })));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONSENT_CATEGORIES = void 0;
|
|
4
|
+
exports.CONSENT_CATEGORIES = [
|
|
5
|
+
{
|
|
6
|
+
id: 'necessary',
|
|
7
|
+
locked: true,
|
|
8
|
+
titleTranslationKey: 'consent.category.necessary.title',
|
|
9
|
+
descriptionTranslationKey: 'consent.category.necessary.description',
|
|
10
|
+
titleDefault: 'Necessary',
|
|
11
|
+
descriptionDefault: 'Needed for the site to work: your consent choice, your color mode, and anonymous usage data.',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: 'analytics',
|
|
15
|
+
locked: false,
|
|
16
|
+
titleTranslationKey: 'consent.category.analytics.title',
|
|
17
|
+
descriptionTranslationKey: 'consent.category.analytics.description',
|
|
18
|
+
titleDefault: 'Analytics',
|
|
19
|
+
descriptionDefault: 'Helps us understand which pages are useful.',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'marketing',
|
|
23
|
+
locked: false,
|
|
24
|
+
titleTranslationKey: 'consent.category.marketing.title',
|
|
25
|
+
descriptionTranslationKey: 'consent.category.marketing.description',
|
|
26
|
+
titleDefault: 'Marketing',
|
|
27
|
+
descriptionDefault: 'Lets us measure which campaigns bring visitors to this site.',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
//# sourceMappingURL=consent.js.map
|
|
@@ -26,4 +26,5 @@ __exportStar(require("./mcp"), exports);
|
|
|
26
26
|
__exportStar(require("./feedback"), exports);
|
|
27
27
|
__exportStar(require("./heading"), exports);
|
|
28
28
|
__exportStar(require("./markdown"), exports);
|
|
29
|
+
__exportStar(require("./consent"), exports);
|
|
29
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -13,7 +13,7 @@ export declare const AiSearchConversationRole: {
|
|
|
13
13
|
export type AiSearchConversationRole = (typeof AiSearchConversationRole)[keyof typeof AiSearchConversationRole];
|
|
14
14
|
export declare const AI_SEARCH_ERROR_CONFIG: Record<AiSearchError, AiSearchErrorConfig>;
|
|
15
15
|
export declare const AI_SEARCH_MAX_MESSAGE_LENGTH = 45000;
|
|
16
|
-
export declare const SEARCH_DEBOUNCE_TIME_MS =
|
|
16
|
+
export declare const SEARCH_DEBOUNCE_TIME_MS = 500;
|
|
17
17
|
export declare const DEFAULT_KEYBOARD_SHORTCUTS = "\u2318+K,CTRL+K";
|
|
18
18
|
export declare const TOOL_CALL_DISPLAY_TEXT: Partial<Record<string, {
|
|
19
19
|
inProgressText: string;
|
|
@@ -38,7 +38,7 @@ exports.AI_SEARCH_ERROR_CONFIG = {
|
|
|
38
38
|
[AiSearchError.ErrorProcessingResponse]: defaultErrorConfig,
|
|
39
39
|
};
|
|
40
40
|
exports.AI_SEARCH_MAX_MESSAGE_LENGTH = 45000;
|
|
41
|
-
exports.SEARCH_DEBOUNCE_TIME_MS =
|
|
41
|
+
exports.SEARCH_DEBOUNCE_TIME_MS = 500;
|
|
42
42
|
exports.DEFAULT_KEYBOARD_SHORTCUTS = '⌘+K,CTRL+K';
|
|
43
43
|
exports.TOOL_CALL_DISPLAY_TEXT = {
|
|
44
44
|
[search_1.ToolCallName.SearchDocumentation]: {
|
|
@@ -22,6 +22,8 @@ export * from './menu/use-collapse';
|
|
|
22
22
|
export * from './feedback/use-report-dialog';
|
|
23
23
|
export * from './use-tabs';
|
|
24
24
|
export * from './use-focus-trap';
|
|
25
|
+
export * from './use-consent-dialog';
|
|
26
|
+
export * from './use-consent-telemetry';
|
|
25
27
|
export * from './use-language-picker';
|
|
26
28
|
export * from './use-product-picker';
|
|
27
29
|
export * from './search/use-search-dialog';
|
package/lib/core/hooks/index.js
CHANGED
|
@@ -38,6 +38,8 @@ __exportStar(require("./menu/use-collapse"), exports);
|
|
|
38
38
|
__exportStar(require("./feedback/use-report-dialog"), exports);
|
|
39
39
|
__exportStar(require("./use-tabs"), exports);
|
|
40
40
|
__exportStar(require("./use-focus-trap"), exports);
|
|
41
|
+
__exportStar(require("./use-consent-dialog"), exports);
|
|
42
|
+
__exportStar(require("./use-consent-telemetry"), exports);
|
|
41
43
|
__exportStar(require("./use-language-picker"), exports);
|
|
42
44
|
__exportStar(require("./use-product-picker"), exports);
|
|
43
45
|
__exportStar(require("./search/use-search-dialog"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
import type { ConsentCategory, ConsentCategoryId, UseConsentResult } from '../types/consent';
|
|
3
|
+
export type ConsentDraft = Record<Exclude<ConsentCategoryId, 'necessary'>, boolean>;
|
|
4
|
+
export type UseConsentDialogResult = {
|
|
5
|
+
draft: ConsentDraft;
|
|
6
|
+
setCategory: (id: keyof ConsentDraft, value: boolean) => void;
|
|
7
|
+
dialogRef: RefObject<HTMLDivElement | null>;
|
|
8
|
+
close: () => void;
|
|
9
|
+
save: () => void;
|
|
10
|
+
categories: readonly ConsentCategory[];
|
|
11
|
+
};
|
|
12
|
+
export declare function useConsentDialog(consent: UseConsentResult): UseConsentDialogResult;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useConsentDialog = useConsentDialog;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const consent_1 = require("../constants/consent");
|
|
6
|
+
const use_focus_trap_1 = require("./use-focus-trap");
|
|
7
|
+
function useConsentDialog(consent) {
|
|
8
|
+
const [draft, setDraft] = (0, react_1.useState)(() => { var _a, _b; var _c, _d; return ({
|
|
9
|
+
analytics: (_c = (_a = consent.state) === null || _a === void 0 ? void 0 : _a.analytics) !== null && _c !== void 0 ? _c : consent.mode === 'opt-out',
|
|
10
|
+
marketing: ((_d = (_b = consent.state) === null || _b === void 0 ? void 0 : _b.marketing) !== null && _d !== void 0 ? _d : consent.mode === 'opt-out') && !consent.gpc,
|
|
11
|
+
}); });
|
|
12
|
+
const dialogRef = (0, react_1.useRef)(null);
|
|
13
|
+
const close = consent.closeDialog;
|
|
14
|
+
const closeRef = (0, react_1.useRef)(close);
|
|
15
|
+
closeRef.current = close;
|
|
16
|
+
(0, react_1.useEffect)(() => {
|
|
17
|
+
const previous = document.activeElement;
|
|
18
|
+
const onKeyDown = (event) => {
|
|
19
|
+
if (event.key === 'Escape')
|
|
20
|
+
closeRef.current();
|
|
21
|
+
};
|
|
22
|
+
document.addEventListener('keydown', onKeyDown);
|
|
23
|
+
return () => {
|
|
24
|
+
var _a;
|
|
25
|
+
document.removeEventListener('keydown', onKeyDown);
|
|
26
|
+
(_a = previous === null || previous === void 0 ? void 0 : previous.focus) === null || _a === void 0 ? void 0 : _a.call(previous);
|
|
27
|
+
};
|
|
28
|
+
}, []);
|
|
29
|
+
(0, use_focus_trap_1.useFocusTrap)(dialogRef);
|
|
30
|
+
const setCategory = (id, value) => {
|
|
31
|
+
setDraft((current) => (Object.assign(Object.assign({}, current), { [id]: value })));
|
|
32
|
+
};
|
|
33
|
+
const save = () => consent.save(draft);
|
|
34
|
+
return { draft, setCategory, dialogRef, close, save, categories: consent_1.CONSENT_CATEGORIES };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=use-consent-dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function useConsentTelemetry(): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useConsentTelemetry = useConsentTelemetry;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const use_theme_hooks_1 = require("./use-theme-hooks");
|
|
6
|
+
const get_base_data_attributes_1 = require("../utils/telemetry/get-base-data-attributes");
|
|
7
|
+
function isRealmOwned(runtime) {
|
|
8
|
+
return runtime.region.source !== 'provider';
|
|
9
|
+
}
|
|
10
|
+
function getConsentRuntime() {
|
|
11
|
+
var _a;
|
|
12
|
+
if (typeof window === 'undefined')
|
|
13
|
+
return undefined;
|
|
14
|
+
return (_a = window.redocly) === null || _a === void 0 ? void 0 : _a.consent;
|
|
15
|
+
}
|
|
16
|
+
// Sends one consent.changed event per visitor choice in the modes Realm owns.
|
|
17
|
+
function useConsentTelemetry() {
|
|
18
|
+
const { useTelemetry } = (0, use_theme_hooks_1.useThemeHooks)();
|
|
19
|
+
const telemetry = useTelemetry();
|
|
20
|
+
const telemetryRef = (0, react_1.useRef)(telemetry);
|
|
21
|
+
telemetryRef.current = telemetry;
|
|
22
|
+
(0, react_1.useEffect)(() => {
|
|
23
|
+
const found = getConsentRuntime();
|
|
24
|
+
const runtime = found && isRealmOwned(found) ? found : null;
|
|
25
|
+
if (!runtime)
|
|
26
|
+
return;
|
|
27
|
+
return runtime.on('change', (state) => {
|
|
28
|
+
const choice = state.analytics && state.marketing
|
|
29
|
+
? 'accept'
|
|
30
|
+
: !state.analytics && !state.marketing
|
|
31
|
+
? 'reject'
|
|
32
|
+
: 'partial';
|
|
33
|
+
const { origin, pathname, search, hash } = window.location;
|
|
34
|
+
const uri = `${origin}${pathname}${search}${hash}`;
|
|
35
|
+
telemetryRef.current.sendConsentChangedMessage([
|
|
36
|
+
Object.assign(Object.assign({}, (0, get_base_data_attributes_1.getBaseDataAttributes)('consent', 'consent')), { choice, mode: runtime.mode, configuredMode: runtime.configuredMode, regionSource: runtime.region.source, gpc: runtime.gpc }),
|
|
37
|
+
(0, get_base_data_attributes_1.getBaseDataAttributes)(uri, 'page', uri),
|
|
38
|
+
]);
|
|
39
|
+
});
|
|
40
|
+
}, []);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=use-consent-telemetry.js.map
|
|
@@ -23,8 +23,10 @@ function useDialogHotKeys(ref, onClose) {
|
|
|
23
23
|
};
|
|
24
24
|
const onFocusableElementsHandler = () => {
|
|
25
25
|
var _a;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
var _b;
|
|
27
|
+
const focusableElements = Array.from((_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll('input, textarea, select, button, [href], [tabindex]:not([tabindex="-1"])')) !== null && _b !== void 0 ? _b : []).filter((element) => !element.hasAttribute('disabled') &&
|
|
28
|
+
(typeof element.checkVisibility !== 'function' || element.checkVisibility()));
|
|
29
|
+
if (focusableElements.length > 0) {
|
|
28
30
|
firstFocusableRef.current = focusableElements[0];
|
|
29
31
|
lastFocusableRef.current = focusableElements[focusableElements.length - 1];
|
|
30
32
|
}
|
|
@@ -17,6 +17,20 @@ const fallbacks = {
|
|
|
17
17
|
useOtelTelemetry: () => ({ send: () => { } }),
|
|
18
18
|
useBreadcrumbs: () => ({ breadcrumbs: [], siblings: undefined }),
|
|
19
19
|
useBanner: () => ({ banner: undefined, dismissBanner: () => { } }),
|
|
20
|
+
useConsent: () => ({
|
|
21
|
+
enabled: false,
|
|
22
|
+
config: undefined,
|
|
23
|
+
mode: undefined,
|
|
24
|
+
state: undefined,
|
|
25
|
+
decided: false,
|
|
26
|
+
gpc: false,
|
|
27
|
+
isDialogOpen: false,
|
|
28
|
+
openDialog: () => { },
|
|
29
|
+
closeDialog: () => { },
|
|
30
|
+
accept: () => { },
|
|
31
|
+
reject: () => { },
|
|
32
|
+
save: () => { },
|
|
33
|
+
}),
|
|
20
34
|
useCodeHighlight: () => ({ highlight: (rawContent) => rawContent }),
|
|
21
35
|
useUserMenu: () => ({}),
|
|
22
36
|
usePageData: () => null,
|
|
@@ -30,26 +30,27 @@ const variables_25 = require("../../components/CodeBlock/variables");
|
|
|
30
30
|
const variables_26 = require("../../components/Product/variables");
|
|
31
31
|
const variables_27 = require("../../components/Markdown/variables");
|
|
32
32
|
const variables_28 = require("../../components/Banner/variables");
|
|
33
|
-
const variables_29 = require("../../
|
|
34
|
-
const variables_30 = require("../../markdoc/components/
|
|
35
|
-
const variables_31 = require("../../markdoc/components/
|
|
36
|
-
const variables_32 = require("../../markdoc/components/
|
|
37
|
-
const variables_33 = require("../../components/
|
|
38
|
-
const variables_34 = require("../../components/
|
|
39
|
-
const variables_35 = require("../../components/
|
|
40
|
-
const variables_36 = require("../../components/
|
|
41
|
-
const variables_37 = require("../../components/
|
|
42
|
-
const variables_38 = require("../../components/
|
|
43
|
-
const variables_39 = require("../../components/
|
|
44
|
-
const variables_40 = require("../../components/
|
|
45
|
-
const variables_41 = require("../../components/
|
|
46
|
-
const variables_42 = require("../../
|
|
47
|
-
const variables_43 = require("../../markdoc/components/
|
|
48
|
-
const variables_44 = require("../../components/
|
|
49
|
-
const variables_45 = require("../../components/
|
|
50
|
-
const variables_46 = require("../../components/
|
|
51
|
-
const variables_47 = require("../../components/
|
|
52
|
-
const variables_48 = require("../../components/
|
|
33
|
+
const variables_29 = require("../../components/Consent/variables");
|
|
34
|
+
const variables_30 = require("../../markdoc/components/Accordion/variables");
|
|
35
|
+
const variables_31 = require("../../markdoc/components/Tabs/variables");
|
|
36
|
+
const variables_32 = require("../../markdoc/components/NumberedList/variables");
|
|
37
|
+
const variables_33 = require("../../markdoc/components/Diagram/variables");
|
|
38
|
+
const variables_34 = require("../../components/LastUpdated/variables");
|
|
39
|
+
const variables_35 = require("../../components/Logo/variables");
|
|
40
|
+
const variables_36 = require("../../components/StatusCode/variables");
|
|
41
|
+
const variables_37 = require("../../components/Segmented/variables");
|
|
42
|
+
const variables_38 = require("../../components/UserMenu/variables");
|
|
43
|
+
const variables_39 = require("../../components/Tags/variables");
|
|
44
|
+
const variables_40 = require("../../components/VersionPicker/variables");
|
|
45
|
+
const variables_41 = require("../../components/DatePicker/variables");
|
|
46
|
+
const variables_42 = require("../../components/Switch/variables");
|
|
47
|
+
const variables_43 = require("../../markdoc/components/Cards/variables");
|
|
48
|
+
const variables_44 = require("../../markdoc/components/CodeWalkthrough/variables");
|
|
49
|
+
const variables_45 = require("../../components/SkipContent/variables");
|
|
50
|
+
const variables_46 = require("../../components/PageActions/variables");
|
|
51
|
+
const variables_47 = require("../../components/SvgViewer/variables");
|
|
52
|
+
const variables_48 = require("../../components/Toast/variables");
|
|
53
|
+
const variables_49 = require("../../components/PageNavigation/variables");
|
|
53
54
|
const palette_1 = require("./palette");
|
|
54
55
|
const dark_1 = require("./dark");
|
|
55
56
|
const themeColors = (0, styled_components_1.css) `
|
|
@@ -1313,33 +1314,34 @@ exports.styles = (0, styled_components_1.css) `
|
|
|
1313
1314
|
${badges}
|
|
1314
1315
|
${variables_28.banner}
|
|
1315
1316
|
${borders}
|
|
1317
|
+
${variables_29.consent}
|
|
1316
1318
|
${variables_5.breadcrumbs}
|
|
1317
1319
|
${variables_20.button}
|
|
1318
1320
|
${variables_21.aiAssistantButton}
|
|
1319
|
-
${
|
|
1321
|
+
${variables_43.cards}
|
|
1320
1322
|
${variables_8.catalog}
|
|
1321
1323
|
${variables_11.catalogClassic}
|
|
1322
1324
|
${variables_25.code}
|
|
1323
|
-
${
|
|
1325
|
+
${variables_44.codeWalkthrough}
|
|
1324
1326
|
${docsDropdown}
|
|
1325
1327
|
${variables_15.dropdown}
|
|
1326
1328
|
${error}
|
|
1327
1329
|
${variables_10.filter}
|
|
1328
1330
|
${variables_19.footer}
|
|
1329
1331
|
${headingsTypography}
|
|
1330
|
-
${
|
|
1332
|
+
${variables_39.httpTag}
|
|
1331
1333
|
${variables_9.image}
|
|
1332
1334
|
${inputs}
|
|
1333
1335
|
${variables_1.languagePicker}
|
|
1334
|
-
${
|
|
1336
|
+
${variables_34.lastUpdated}
|
|
1335
1337
|
${links}
|
|
1336
1338
|
${loadProgressBar}
|
|
1337
|
-
${
|
|
1339
|
+
${variables_35.logo}
|
|
1338
1340
|
${variables_27.markdown}
|
|
1339
|
-
${
|
|
1340
|
-
${
|
|
1341
|
-
${
|
|
1342
|
-
${
|
|
1341
|
+
${variables_30.markdownAccordion}
|
|
1342
|
+
${variables_31.markdownTabs}
|
|
1343
|
+
${variables_32.markdownNumberedList}
|
|
1344
|
+
${variables_33.diagram}
|
|
1343
1345
|
${variables_24.menu}
|
|
1344
1346
|
${variables_24.mobileMenu}
|
|
1345
1347
|
${modal}
|
|
@@ -1358,26 +1360,26 @@ exports.styles = (0, styled_components_1.css) `
|
|
|
1358
1360
|
${variables_7.toc}
|
|
1359
1361
|
${variables_16.tooltip}
|
|
1360
1362
|
${typography}
|
|
1361
|
-
${
|
|
1362
|
-
${
|
|
1363
|
+
${variables_38.userMenu}
|
|
1364
|
+
${variables_40.versionPicker}
|
|
1363
1365
|
${zIndexDepth}
|
|
1364
1366
|
${scorecardColors}
|
|
1365
|
-
${
|
|
1367
|
+
${variables_36.statusCode}
|
|
1366
1368
|
${tab}
|
|
1367
1369
|
${icon}
|
|
1368
1370
|
${tree}
|
|
1369
|
-
${
|
|
1370
|
-
${
|
|
1371
|
+
${variables_37.segmented}
|
|
1372
|
+
${variables_42.switcher}
|
|
1371
1373
|
${variables_17.checkbox}
|
|
1372
1374
|
${variables_3.feedback}
|
|
1373
1375
|
${variables_2.scorecard}
|
|
1374
|
-
${
|
|
1376
|
+
${variables_41.datePicker}
|
|
1375
1377
|
${replay}
|
|
1376
|
-
${
|
|
1377
|
-
${
|
|
1378
|
-
${
|
|
1379
|
-
${
|
|
1380
|
-
${
|
|
1378
|
+
${variables_45.skipContent}
|
|
1379
|
+
${variables_46.pageActions}
|
|
1380
|
+
${variables_47.svgViewer}
|
|
1381
|
+
${variables_48.toast}
|
|
1382
|
+
${variables_49.pageNavigation}
|
|
1381
1383
|
|
|
1382
1384
|
background-color: var(--bg-color);
|
|
1383
1385
|
color: var(--text-color-primary);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ConsentConfig } from '@redocly/config';
|
|
2
|
+
import type { TranslationKey } from './l10n';
|
|
3
|
+
export type ConsentCategoryId = 'necessary' | 'analytics' | 'marketing';
|
|
4
|
+
export type ConsentCategory = {
|
|
5
|
+
id: ConsentCategoryId;
|
|
6
|
+
locked: boolean;
|
|
7
|
+
titleTranslationKey: TranslationKey;
|
|
8
|
+
descriptionTranslationKey: TranslationKey;
|
|
9
|
+
titleDefault: string;
|
|
10
|
+
descriptionDefault: string;
|
|
11
|
+
};
|
|
12
|
+
export type ConsentState = {
|
|
13
|
+
necessary: true;
|
|
14
|
+
analytics: boolean;
|
|
15
|
+
marketing: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type ConsentChoice = {
|
|
18
|
+
analytics?: boolean;
|
|
19
|
+
marketing?: boolean;
|
|
20
|
+
};
|
|
21
|
+
export type ConsentProvider = 'onetrust' | 'cookiebot' | 'trustarc' | 'tcf';
|
|
22
|
+
export type ConsentRuntime = {
|
|
23
|
+
configuredMode: 'auto' | 'opt-in' | 'opt-out' | ConsentProvider;
|
|
24
|
+
mode: 'opt-in' | 'opt-out' | ConsentProvider;
|
|
25
|
+
state: ConsentState;
|
|
26
|
+
decided: boolean;
|
|
27
|
+
gpc: boolean;
|
|
28
|
+
dialogOpen: boolean;
|
|
29
|
+
region: {
|
|
30
|
+
source: 'timezone' | 'config' | 'none' | 'provider';
|
|
31
|
+
timeZone: string | null;
|
|
32
|
+
};
|
|
33
|
+
accept: () => void;
|
|
34
|
+
reject: () => void;
|
|
35
|
+
save: (next: ConsentChoice) => void;
|
|
36
|
+
open: () => void;
|
|
37
|
+
close: () => void;
|
|
38
|
+
reload: () => void;
|
|
39
|
+
on: (event: 'change' | 'open' | 'close', fn: (state: ConsentState) => void) => () => void;
|
|
40
|
+
};
|
|
41
|
+
export type UseConsentResult = {
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
config: ConsentConfig | undefined;
|
|
44
|
+
mode: ConsentRuntime['mode'] | undefined;
|
|
45
|
+
state: ConsentState | undefined;
|
|
46
|
+
decided: boolean;
|
|
47
|
+
gpc: boolean;
|
|
48
|
+
isDialogOpen: boolean;
|
|
49
|
+
openDialog: () => void;
|
|
50
|
+
closeDialog: () => void;
|
|
51
|
+
accept: () => void;
|
|
52
|
+
reject: () => void;
|
|
53
|
+
save: (next: ConsentChoice) => void;
|
|
54
|
+
};
|
|
@@ -12,6 +12,7 @@ import type { SearchItemData, SearchFacet, SearchFilterItem, SearchFacetQuery, A
|
|
|
12
12
|
import type { SubmitFeedbackParams } from './feedback';
|
|
13
13
|
import type { TFunction } from './l10n';
|
|
14
14
|
import type { BreadcrumbItem } from './breadcrumb';
|
|
15
|
+
import type { UseConsentResult } from './consent';
|
|
15
16
|
import type { AiSearchError } from '../constants/search';
|
|
16
17
|
export type ThemeHooks = {
|
|
17
18
|
useTranslate: () => {
|
|
@@ -64,6 +65,7 @@ export type ThemeHooks = {
|
|
|
64
65
|
banner: ResolvedBannerConfig | undefined;
|
|
65
66
|
dismissBanner: (content: string) => void;
|
|
66
67
|
};
|
|
68
|
+
useConsent: () => UseConsentResult;
|
|
67
69
|
useSearch: (product?: string, autoSearchDisabled?: boolean) => {
|
|
68
70
|
query: string;
|
|
69
71
|
setQuery: React.Dispatch<React.SetStateAction<string>>;
|