umberto 8.1.0 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,23 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [8.3.0](https://github.com/cksource/umberto/compare/v8.2.0...v8.3.0) (September 2, 2025)
5
+
6
+ ### Features
7
+
8
+ * Added custom styling for the [Kapa.ai](https://www.kapa.ai/) service.
9
+ * The source script of the [Kapa.ai](https://www.kapa.ai/) service must be defined in the `kapa.widgetOptions.src` key in the Umberto configuration.
10
+
11
+
12
+ ## [8.2.0](https://github.com/cksource/umberto/compare/v8.1.0...v8.2.0) (August 29, 2025)
13
+
14
+ ### Features
15
+
16
+ * Added integration with the [Kapa.ai](https://www.kapa.ai/) service.
17
+
18
+ Umberto configuration can now specify the `kapa` key that allows loading the Kapa button and widget.
19
+
20
+
4
21
  ## [8.1.0](https://github.com/cksource/umberto/compare/v8.0.3...v8.1.0) (August 12, 2025)
5
22
 
6
23
  ### Features
@@ -27,44 +44,6 @@ Changelog
27
44
  * Changed from `overscroll-behavior: none` to `overscroll-behavior-y: none` on `<html>` and `<body>` elements to allow Mac trackpad swipe gestures for browser navigation.
28
45
  * Code blocks in API descriptions are no longer duplicated when there are multiple code blocks withing the same description.
29
46
 
30
-
31
- ## [8.0.1](https://github.com/cksource/umberto/compare/v8.0.0...v8.0.1) (July 28, 2025)
32
-
33
- ### Bug fixes
34
-
35
- * The performance of the building and the behavior of components have been improved. The most important changes are listed below:
36
-
37
- * Improved the performance of the `validate-links` task by processing links in parallel across multiple CPU cores, instead of a single core.
38
- * Enhanced the API filters behavior: now, when the `inherited` filter is unchecked while `internal` is selected, items tagged with both `inherited` and `internal` will be properly hidden from the results.
39
- * Added the Lato font for improved typography and visual consistency.
40
- * Restored the default selection color for content on the website to ensure a familiar and accessible user experience.
41
- * Added a footer snippet for consistent branding and navigation across all pages.
42
- * Improved the styling of `code` tags in API documentation for better readability and clarity.
43
- * Added a new `sparkles` icon to the icon set.
44
- * Fixed the project selection dropdown: after rebuilding, it now correctly displays all available projects instead of only one.
45
- * Optimized the performance of the navigation tree building process, resulting in faster page loads and smoother navigation.
46
-
47
-
48
- ## [8.0.0](https://github.com/cksource/umberto/compare/v7.0.2...v8.0.0) (July 18, 2025)
49
-
50
- ### BREAKING CHANGES
51
-
52
- * Updated the required version of Node.js to 22.
53
-
54
- ### Features
55
-
56
- * We have introduced a brand-new theme to elevate your UI experience. Enjoy a fresh look with improved aesthetics and feel.
57
-
58
- ### Bug fixes
59
-
60
- * Removed link to unnecessary stylesheet that results in a 404.
61
- * Fixed output path calculation on Windows environment for generated HTML files. Previously, non-normalized CWD was used which caused the generated output path to contain invalid characters and be incorrect.
62
-
63
- ### Other changes
64
-
65
- * The repository now uses ESLint v9. Therefore, the required Node.js version has been upgraded to 22 to match the ESLint requirements.
66
- * Update `LICENSE.md` file to include licenses of direct dependencies
67
-
68
47
  ---
69
48
 
70
49
  To see all releases, visit the [release page](https://github.com/cksource/umberto/releases).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umberto",
3
- "version": "8.1.0",
3
+ "version": "8.3.0",
4
4
  "description": "CKSource Documentation builder",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -20,6 +20,7 @@ const umbertoVersion = require( '../../../package.json' ).version;
20
20
  * @param {Object} googleoptimize Google Optimize config.
21
21
  * @param {Object} googletagmanager Google Tag Manager config.
22
22
  * @param {Object} googleanalytics Google Analytics config.
23
+ * @param {Object} kapa Kapa.ai config.
23
24
  * @param {Object} vwo Visual Website Optimizer config.
24
25
  * @param {Object} feedbackWidget Feedback widget config
25
26
  * @param {Array} extraStylePaths Paths to extra external css.
@@ -36,6 +37,7 @@ module.exports = ( ctx, {
36
37
  googleoptimize,
37
38
  googletagmanager,
38
39
  googleanalytics,
40
+ kapa,
39
41
  promobar,
40
42
  vwo,
41
43
  feedbackWidget,
@@ -105,6 +107,7 @@ module.exports = ( ctx, {
105
107
  locals.googleoptimize = googleoptimize;
106
108
  locals.googletagmanager = googletagmanager;
107
109
  locals.googleanalytics = googleanalytics;
110
+ locals.kapa = kapa;
108
111
  locals.promobar = promobar;
109
112
  locals.vwo = vwo;
110
113
  locals.feedbackWidget = feedbackWidget;
@@ -141,6 +141,7 @@ module.exports = options => {
141
141
  googleoptimize: mainConfig.googleoptimize,
142
142
  googletagmanager: mainConfig.googletagmanager,
143
143
  googleanalytics: mainConfig.googleanalytics,
144
+ kapa: mainConfig.kapa,
144
145
  promobar: mainConfig.promobar,
145
146
  sitemap: mainConfig.sitemap,
146
147
  vwo: mainConfig.vwo,
@@ -275,6 +276,7 @@ async function buildProjects( rootPath, projectPaths, options = {} ) {
275
276
  googleoptimize: options.googleoptimize,
276
277
  googletagmanager: options.googletagmanager,
277
278
  googleanalytics: options.googleanalytics,
279
+ kapa: options.kapa,
278
280
  promobar: options.promobar,
279
281
  sitemap: options.sitemap,
280
282
  vwo: options.vwo,
@@ -353,6 +355,7 @@ async function buildProjects( rootPath, projectPaths, options = {} ) {
353
355
  googleoptimize: options.googleoptimize,
354
356
  googletagmanager: options.googletagmanager,
355
357
  googleanalytics: options.googleanalytics,
358
+ kapa: options.kapa,
356
359
  promobar: options.promobar,
357
360
  quickNavigationProjects: options.quickNavigationProjects,
358
361
  vwo: options.vwo,
@@ -465,6 +468,7 @@ async function buildApis( projectConfigs, options = {} ) {
465
468
  googleoptimize: options.googleoptimize,
466
469
  googletagmanager: options.googletagmanager,
467
470
  googleanalytics: options.googleanalytics,
471
+ kapa: options.kapa,
468
472
  promobar: options.promobar,
469
473
  vwo: options.vwo,
470
474
  feedbackWidget: options.feedbackWidget,
@@ -16,12 +16,13 @@
16
16
  //- +button({ variant: 'secondary' })
17
17
  //- +button({ variant: 'transparent', fillColor: '--color-orange-600' })
18
18
  //- span Custom content
19
- mixin button({ variant = 'primary', tooltip, blockDisplay, active, disabled, id, className, square, rounded, type = 'button', size = 'base', label, ariaLabel, ariaControls, icon, labelClassName, iconClassName, fillColor, iconPosition = 'left' })
19
+ mixin button({ variant = 'primary', tooltip, blockDisplay, active, disabled, id, className, square, rounded, type = 'button', size = 'base', label, ariaLabel, ariaControls, icon, labelClassName, iconClassName, fillColor, iconPosition = 'left', onClick })
20
20
  - const showTooltip = !!id && !!tooltip && !ariaLabel;
21
21
 
22
22
  button.c-button(
23
23
  id=id,
24
24
  disabled=disabled,
25
+ onClick=onClick || false,
25
26
  class={
26
27
  'is-block': blockDisplay,
27
28
  'is-active': active,
@@ -45,6 +45,8 @@ if page.BASE_PATH && page.BASE_PATH !== '.' && !page.BASE_PATH.includes( 'latest
45
45
  link( rel = 'canonical' href = page.canonicalUrlBeginning + page.path.replace( page.BASE_PATH, projectLocals.latestBasePath ) )
46
46
 
47
47
  +head-preloads()
48
+ if kapa
49
+ +load-kapa-script(kapa)
48
50
 
49
51
  script(src=relative_url(page.path, pathJoin( 'assets', umbertoVersion, 'gloria/scripts/app.js')))
50
52
 
@@ -50,6 +50,8 @@ mixin header({ withChooseProject = true, className = '' } = {})
50
50
 
51
51
  .c-header__brand-row-toolbar.u-flex-horizontal.u-align-items-center
52
52
  +algolia-search
53
+ if kapa
54
+ +kapa-button
53
55
  +button-link({
54
56
  label: 'Sign up',
55
57
  icon: 'export',
@@ -12,3 +12,4 @@ include ./header-promobar/index
12
12
  include ./breadcrumbs/index
13
13
  include ./algolia-search/index
14
14
  include ./not-found/index
15
+ include ./kapa/index
@@ -0,0 +1,29 @@
1
+ /* Style for the floating button. */
2
+ #kapa-button p {
3
+ position: relative;
4
+ top: 6px;
5
+ }
6
+
7
+ /* Style for hyperlinks inside the AI's answer. */
8
+ #kapa-modal-content
9
+ > div:nth-of-type(1)
10
+ > div:nth-of-type(1)
11
+ > div:nth-of-type(1)
12
+ > div:nth-of-type(2)
13
+ > div:nth-of-type(1)
14
+ a
15
+ {
16
+ font-weight: normal !important;
17
+ color: #743CCD !important;
18
+ text-decoration-line: underline !important;
19
+ text-decoration-color: #C4B1E6 !important;
20
+
21
+ &:hover {
22
+ text-decoration-color: #743CCD !important;
23
+ }
24
+
25
+ &:visited {
26
+ color: #582AA2 !important;
27
+ text-decoration-color: #582AA2 !important;
28
+ }
29
+ }
@@ -0,0 +1,159 @@
1
+ mixin load-kapa-script( kapa )
2
+ -
3
+ const mainColor = '#743CCD';
4
+ const textPrimaryColor = '#00091B';
5
+ const textSecondaryColor = '#585B5F';
6
+ const infoPanelBackgroundColor = '#F8F9FA';
7
+ const standardBorder = '1px solid var(--mantine-color-gray-3)';
8
+ const buttonHoverBgColor = 'var(--mantine-color-default-hover)';
9
+ const exampleQuestionsTitleColor = 'var(--mantine-color-gray-text)';
10
+
11
+ var attributes = {
12
+ 'async': true,
13
+ 'fetchpriority': 'low',
14
+ 'src': kapa.widgetOptions.src,
15
+ 'data-website-id': kapa.widgetOptions.websiteId,
16
+ 'data-project-name': kapa.widgetOptions.projectName,
17
+
18
+ // Global settings.
19
+ 'data-project-color': mainColor,
20
+ 'data-project-logo': 'https://ckeditor.com/docs/ckeditor5/latest/assets/img/ckeditor5-logo.svg',
21
+ 'data-font-family': '"Title Mullish", text public sans',
22
+
23
+ // Floating button.
24
+ 'data-button-text': 'Need help?',
25
+ 'data-button-image': 'https://ckeditor.com/docs/ckeditor5/latest/assets/img/ckeditor5-logo-white.svg',
26
+ 'data-button-width': 'fit-content',
27
+ 'data-button-height': '90px',
28
+ 'data-button-padding': '12px',
29
+
30
+ // Modal style.
31
+ 'data-modal-size': '900px',
32
+ 'data-modal-z-index': '2000',
33
+ 'data-modal-border-radius': '6px',
34
+
35
+ // Modal title.
36
+ 'data-modal-title': 'AI Helper',
37
+ 'data-modal-title-color': textPrimaryColor,
38
+
39
+ // Modal disclaimer.
40
+ 'data-modal-disclaimer': 'Disclaimer: Responses are generated by AI and may contain inaccuracies. Please verify the information with the official documentation.',
41
+ 'data-modal-disclaimer-text-color': exampleQuestionsTitleColor,
42
+ 'data-modal-disclaimer-bg-color': infoPanelBackgroundColor,
43
+
44
+ // Modal example questions.
45
+ 'data-example-question-button-border': standardBorder,
46
+ 'data-example-question-button-text-color': textSecondaryColor,
47
+
48
+ // Modal question input.
49
+ 'data-query-input-text-color': textPrimaryColor,
50
+ 'data-query-input-placeholder-text-color': textSecondaryColor,
51
+ 'data-modal-ask-ai-input-placeholder': 'Ask me a question about the project...',
52
+
53
+ // Modal deep thinking button.
54
+ 'data-deep-thinking-button-text-color': textSecondaryColor,
55
+
56
+ // Modal answer.
57
+ 'data-question-text-color': textPrimaryColor,
58
+ 'data-answer-text-color': textPrimaryColor,
59
+
60
+ // Modal copy, clear & feedback buttons.
61
+ 'data-answer-copy-button-bg-color': 'white',
62
+ 'data-answer-copy-button-border': standardBorder,
63
+ 'data-answer-copy-button-hover-bg-color': buttonHoverBgColor,
64
+ 'data-thread-clear-button-bg-color': 'white',
65
+ 'data-thread-clear-button-border': standardBorder,
66
+ 'data-thread-clear-button-hover-bg-color': buttonHoverBgColor,
67
+ 'data-answer-feedback-button-bg-color': 'white',
68
+ 'data-answer-feedback-button-border': standardBorder,
69
+ 'data-answer-feedback-button-active-bg-color': buttonHoverBgColor,
70
+
71
+ // Modal answer source buttons.
72
+ 'data-source-link-primary-heading-text-color': textPrimaryColor,
73
+ 'data-source-link-secondary-heading-text-color': textSecondaryColor,
74
+ 'data-source-link-hover-bg-color': buttonHoverBgColor,
75
+ }
76
+
77
+ const projectConfig = projectLocals && kapa[ projectLocals.projectSlug ];
78
+
79
+ function getModalTitle( projectConfig ) {
80
+ const defaultTitle = kapa.default.modalTitle;
81
+
82
+ if ( !projectConfig ) {
83
+ return defaultTitle;
84
+ }
85
+
86
+ if ( !projectConfig.modalTitle ) {
87
+ return defaultTitle;
88
+ }
89
+
90
+ return projectConfig.modalTitle;
91
+ };
92
+
93
+ function getQuestionPlaceholder() {
94
+ const defaultQuestionPlaceholder = kapa.default.questionPlaceholder;
95
+
96
+ if ( !projectConfig ) {
97
+ return defaultQuestionPlaceholder;
98
+ }
99
+
100
+ if ( !projectConfig.questionPlaceholder ) {
101
+ return defaultQuestionPlaceholder;
102
+ }
103
+
104
+ return projectConfig.questionPlaceholder;
105
+ };
106
+
107
+ function getExampleQuestions() {
108
+ const defaultExampleQuestions = kapa.default.exampleQuestions.join( ',' );
109
+
110
+ if ( !projectConfig ) {
111
+ return defaultExampleQuestions;
112
+ }
113
+
114
+ if ( !projectConfig.exampleQuestions ) {
115
+ return defaultExampleQuestions;
116
+ }
117
+
118
+ if ( !projectConfig.exampleQuestions.length ) {
119
+ return defaultExampleQuestions;
120
+ }
121
+
122
+ return projectConfig.exampleQuestions.join( ',' );
123
+ }
124
+
125
+ attributes[ 'data-modal-title' ] = getModalTitle( projectConfig );
126
+ attributes[ 'data-modal-ask-ai-input-placeholder' ] = getQuestionPlaceholder();
127
+ attributes[ 'data-modal-example-questions' ] = getExampleQuestions();
128
+
129
+ script&attributes(attributes)
130
+
131
+ style#custom_kapa_styles
132
+ include custom_kapa_styles.css
133
+
134
+ script.
135
+ const mutationObserver = new MutationObserver( () => {
136
+ const container = document.querySelector( '#kapa-widget-container' );
137
+
138
+ if ( !container ) {
139
+ return;
140
+ }
141
+
142
+ mutationObserver.disconnect();
143
+
144
+ const customKapaStylesElement = document.querySelector( 'style#custom_kapa_styles' );
145
+ const injectedSheet = new CSSStyleSheet();
146
+ injectedSheet.replaceSync( customKapaStylesElement.innerText );
147
+ container.shadowRoot.adoptedStyleSheets.push( injectedSheet );
148
+ customKapaStylesElement.remove();
149
+ } );
150
+
151
+ mutationObserver.observe( document, { childList: true, subtree: true } );
152
+
153
+ mixin kapa-button
154
+ +button({
155
+ label: 'Ask AI',
156
+ icon: 'chat',
157
+ variant: 'toolbar',
158
+ onClick: 'window.Kapa(\'open\')'
159
+ })
@@ -0,0 +1,3 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M1.76782 15.2671C1.82839 15.2671 1.88757 15.2565 1.94458 15.2388L4.21411 14.4995C6.12656 15.1316 8.2129 14.7834 9.80396 13.6245L9.79517 13.6167C10.4093 13.5828 11.0272 13.4619 11.6252 13.2495L13.886 13.9614C13.9575 13.984 14.033 13.9924 14.1077 13.9858C14.1823 13.9793 14.2551 13.958 14.3215 13.9233C14.388 13.8887 14.4472 13.8411 14.4954 13.7837C14.5434 13.7263 14.5794 13.6598 14.6018 13.5884C14.6197 13.5348 14.6292 13.4776 14.6292 13.4204L14.6428 11.0522C16.3963 8.78261 16.4699 5.58834 14.7502 3.21338C12.6163 0.290177 8.51232 -0.357907 5.58911 1.76709C5.20354 2.0456 4.85922 2.35857 4.55396 2.69775L4.55396 2.6958C3.19644 3.06057 2.00514 3.87984 1.17896 5.01709C-0.417359 7.21518 -0.376417 10.1666 1.19653 12.3022L1.19653 14.6958C1.19668 15.0116 1.45198 15.2669 1.76782 15.2671ZM11.5891 11.8921L11.3752 11.981C9.15207 12.847 6.59175 12.1221 5.16138 10.1597C3.45604 7.81327 3.97848 4.51834 6.33911 2.80225C8.69255 1.09877 11.9926 1.62058 13.7141 3.98096C15.1284 5.92914 15.0285 8.58439 13.5178 10.4272L13.3752 10.5884L13.3577 12.4458L11.5891 11.8921ZM2.50024 11.856L2.35767 11.6772C0.991728 9.98443 0.917806 7.56318 2.21411 5.78467C2.53375 5.34003 2.91082 4.97189 3.32153 4.67725L3.33228 4.67041C2.53946 6.68459 2.76114 9.04694 4.12524 10.9272C4.96108 12.0747 6.14695 12.9202 7.50415 13.3364L7.50024 13.3384C6.51275 13.6152 5.44653 13.5848 4.44653 13.2134L4.23267 13.1245L2.48267 13.7134L2.50024 11.856ZM6.9104 7.8042C7.3229 7.8042 7.64282 7.484 7.64282 7.08936C7.6426 6.69491 7.32276 6.37549 6.9104 6.37549C6.53378 6.37553 6.21434 6.69493 6.21411 7.08936C6.21411 7.48397 6.53365 7.80415 6.9104 7.8042ZM9.4104 7.8042C9.8229 7.8042 10.1428 7.484 10.1428 7.08936C10.1426 6.69491 9.82276 6.37549 9.4104 6.37549C9.03378 6.37553 8.71434 6.69493 8.71411 7.08936C8.71411 7.48397 9.03365 7.80415 9.4104 7.8042ZM11.9104 7.8042C12.3229 7.8042 12.6428 7.484 12.6428 7.08936C12.6426 6.69491 12.3228 6.37549 11.9104 6.37549C11.5338 6.37554 11.2143 6.69493 11.2141 7.08936C11.2141 7.48397 11.5337 7.80415 11.9104 7.8042Z" fill="#585B5F"/>
3
+ </svg>