@ckeditor/ckeditor5-ai
Version:
AI Assistant feature for CKEditor 5.
393 lines (360 loc) • 15.2 kB
CSS
/**
* @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/*
* What you're currently looking at is the source code of a legally protected, proprietary software.
* CKEditor 5 Collaboration is licensed under a commercial license and protected by copyright law. Where not otherwise indicated,
* all CKEditor 5 Collaboration content is authored by CKSource engineers and consists of CKSource-owned intellectual property.
*
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/*
* These definitions bring violet accents (tint) across the AI UI.
*/
:root {
--ck-ai-form-submit-button-text-color: var(--ck-color-text);
--ck-ai-form-submit-button-border-color: transparent;
--ck-ai-form-submit-button-disabled-border-color: transparent;
--ck-ai-toolbar-button-hover-color: var(--ck-color-text);
--ck-color-ai-selection: hsla(201, 100%, 56%, 0.3);
}
/* Note: This class name is mentioned in the guide and acts like a public API. */
.ck-ai-assistant-ui_theme {
--ck-color-button-default-hover-background: hsl(262.1,100%,96.3%);
--ck-color-button-default-active-background: hsl(262.1,100%,96.3%);
--ck-color-button-on-background: hsl(262.1,100%,96.3%);
--ck-color-button-on-hover-background: hsl(262.1,100%,96.3%);
--ck-color-button-on-active-background: hsl(262.1,100%,96.3%);
--ck-color-button-on-disabled-background: hsl(262.1,100%,96.3%);
--ck-color-button-on-color: hsl(263.2,59.2%,52%);
--ck-color-button-action-background: hsl(263.2,59.2%,52%);
--ck-color-button-action-hover-background: hsl(262.6,58.9%,49.6%);
--ck-color-button-action-active-background: hsl(262.6,58.9%,49.6%);
--ck-color-button-action-disabled-background: hsl(263.8,59.3%,75.9%);
--ck-color-list-button-hover-background: hsl(262.1,100%,96.3%);
--ck-ai-form-content-background: hsl(0,0%,97.6%);
--ck-ai-form-submit-button-text-color: var(--ck-color-button-on-color);
--ck-ai-form-submit-button-border-color: var(--ck-color-button-action-background);
--ck-ai-form-submit-button-disabled-border-color: var(--ck-color-button-action-disabled-background);
--ck-ai-toolbar-button-hover-color: var(--ck-color-button-on-color);
--ck-color-ai-selection: hsl(262.5,60%,90%);
}
/*
* Apply the theme colors for specific elements.
*/
.ck-ai-commands-dropdown > .ck-button:hover,
.ck-ai-assistant-button:hover {
color: var(--ck-ai-toolbar-button-hover-color);
}
/*
* Classes used by the "fake visual selection" displayed in the content
* when the AI dialog is open.
*
* Narrow down to <span> to prevent changing background for widgets and nested editables.
*/
.ck span.ck-fake-ai-selection {
background: var(--ck-color-ai-selection);
}
.ck .ck-widget.ck-fake-ai-selection {
outline-color: var(--ck-color-ai-selection);
}
/*
* Classes used by the "fake visual candidate selection" displayed in the content when an input
* in the AI dropdown has focus (the browser does not render the native selection in this state).
*
* Narrow down to <span> to prevent changing background for widgets and nested editables.
*/
.ck span.ck-fake-ai-selection-candidate {
background: var(--ck-color-ai-selection);
}
/* A collapsed fake visual selection. */
.ck .ck-fake-ai-selection_collapsed {
height: 100%;
border-right: 1px solid var(--ck-color-base-text);
margin-right: -1px;
outline: solid 1px hsla(0, 0%, 100%, .5);
}
/*
* Styles of the AI response field. The margins, font sizes and line-heights have been reduced
* to save space.
*
* Note: This class name is mentioned in the guide and acts like a public API.
*/
.ck.ck-content.ck-ai-form__content-field h2 {
font-size: 1.3em;
}
.ck.ck-content.ck-ai-form__content-field h3 {
font-size: 1.2em;
}
.ck.ck-content.ck-ai-form__content-field h4, .ck.ck-content.ck-ai-form__content-field h5, .ck.ck-content.ck-ai-form__content-field h6 {
font-size: 1.1em;
}
.ck.ck-content.ck-ai-form__content-field h2, .ck.ck-content.ck-ai-form__content-field h3, .ck.ck-content.ck-ai-form__content-field h4, .ck.ck-content.ck-ai-form__content-field h5, .ck.ck-content.ck-ai-form__content-field h6, .ck.ck-content.ck-ai-form__content-field p, .ck.ck-content.ck-ai-form__content-field ul, .ck.ck-content.ck-ai-form__content-field ol {
margin-block-start: .5em;
margin-block-end: .5em;
line-height: 1.7em;
}
.ck.ck-content.ck-ai-form__content-field > :first-child {
margin-top: 0;
}
.ck.ck-content.ck-ai-form__content-field > :last-child {
margin-bottom: 0;
}
/*
* What you're currently looking at is the source code of a legally protected, proprietary software.
* CKEditor 5 Collaboration is licensed under a commercial license and protected by copyright law. Where not otherwise indicated,
* all CKEditor 5 Collaboration content is authored by CKSource engineers and consists of CKSource-owned intellectual property.
*
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/*
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/*
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
:root {
--ck-ai-dropdown-view-width: 250px;
--ck-ai-dropdown-view-list-max-height: 250px;
}
.ck.ck-ai-commands-search {
width: var(--ck-ai-dropdown-view-width);
}
.ck.ck-ai-commands-search > .ck-labeled-field-view {
padding: var(--ck-spacing-large);
}
.ck.ck-ai-commands-search > .ck-labeled-field-view .ck-input {
min-width: unset;
}
.ck.ck-ai-commands-search > .ck-search__results {
border-top: 1px solid var(--ck-color-base-border);
}
.ck.ck-ai-commands-search > .ck-search__results > .ck-list {
max-height: var(--ck-ai-dropdown-view-list-max-height);
overflow: auto;
}
/*
* What you're currently looking at is the source code of a legally protected, proprietary software.
* CKEditor 5 Collaboration is licensed under a commercial license and protected by copyright law. Where not otherwise indicated,
* all CKEditor 5 Collaboration content is authored by CKSource engineers and consists of CKSource-owned intellectual property.
*
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/*
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
/*
* Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
*/
:root {
--ck-ai-form-view-width: 600px;
--ck-ai-form-content-height: 175px;
--ck-ai-form-content-background: hsl(0, 0%, 98%);
--ck-ai-form-history-font-size: .9em;
--ck-ai-form-error-background: var(--ck-color-light-red);
}
/* Note: This class name is mentioned in the guide and acts like a public API. */
.ck .ck-ai-form {
width: var(--ck-ai-form-view-width);
/* Don't overflow the parent dialog container */
max-width: 100%;
}
@media screen and (max-width: 600px) {
.ck .ck-ai-form {
/* Allow the for the layout to be fluid in narrow viewports to avoid breaking it due to limited
* horizontal space (https://github.com/ckeditor/ckeditor5-commercial/issues/5913). */
--ck-ai-form-view-width: 100vw;
}
}
.ck .ck-ai-form .ck-ai-form-content {
padding: var(--ck-spacing-large);
width: 100%;
}
.ck .ck-ai-form .ck-ai-form-content .ck-input {
width: 100%;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area-wrapper {
width: 100%;
max-height: var(--ck-ai-form-content-height);
overflow-y: auto;
border: 1px solid var(--ck-color-base-border);
border-radius: 2px;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area-wrapper:focus {
outline: none;
border: var(--ck-focus-ring);
box-shadow: var(--ck-focus-outer-shadow), 0 0;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area {
display: flex;
background-color: var(--ck-ai-form-content-background);
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area.ck-ai-form__content-area--processing {
--ck-color-text: var(--ck-color-input-disabled-text);
background-color: var(--ck-color-input-disabled-background);
}
/* Note: This class name is mentioned in the guide and acts like a public API */
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__content-field {
width: 100%;
white-space: normal;
padding: var(--ck-spacing-tiny) var(--ck-spacing-medium);
min-height: calc( var(--ck-line-height-base) * var(--ck-font-size-base) );
box-sizing: content-box;
}
[dir="ltr"] .ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__content-field {
padding-right: 0;
}
[dir="rtl"] .ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__content-field {
padding-left: 0;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__content-field > * {
white-space: normal;
color: inherit;
}
[dir="ltr"] .ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-spinner-container {
margin-right: var(--ck-spacing-medium);
}
[dir="rtl"] .ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-spinner-container {
margin-left: var(--ck-spacing-medium);
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__copy-button-wrapper {
display: flex;
flex-direction: column-reverse;
padding-left: 2px;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__copy-button {
position: sticky;
right: 1px;
bottom: 1px;
padding: 4px;
min-height: unset;
min-width: unset;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__copy-button svg {
--ck-icon-size: 16px;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__content-area .ck-ai-form__copy-button.ck-ai-form__copy-button--copied {
color: inherit;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__toolbar {
border: none;
padding: 0;
margin-top: var(--ck-spacing-medium);
margin-bottom: calc( 2 * var(--ck-spacing-medium) );
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__loader {
display: flex;
align-items: center;
}
.ck .ck-ai-form .ck-ai-form-content .ck-ai-form__loader .ck-spinner {
box-sizing: border-box;
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete {
display: flex;
justify-content: space-between;
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck-labeled-field-view {
flex-grow: 1;
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck.ck-ai-form__submit {
border-color: var(--ck-ai-form-submit-button-border-color);
color: var(--ck-ai-form-submit-button-text-color);
}
[dir="ltr"] .ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck.ck-ai-form__submit {
margin-left: var(--ck-spacing-medium);
}
[dir="rtl"] .ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck.ck-ai-form__submit {
margin-right: var(--ck-spacing-medium);
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck.ck-ai-form__submit.ck-disabled {
border-color: var(--ck-ai-form-submit-button-disabled-border-color);
}
/* Toggle history button */
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck-labeled-field-view .ck-ai-form__toggle-history {
position: absolute;
font-size: var(--ck-font-size-tiny);
bottom: var(--ck-spacing-small);
top: var(--ck-spacing-small);
padding: 4px;
min-height: unset;
min-width: unset;
}
[dir="ltr"] .ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck-labeled-field-view .ck-ai-form__toggle-history {
right: var(--ck-spacing-medium);
}
[dir="rtl"] .ck .ck-ai-form .ck-ai-form-content .ck-autocomplete > .ck-labeled-field-view .ck-ai-form__toggle-history {
left: var(--ck-spacing-medium);
}
/* Give the toggle history button some space */
[dir="ltr"] .ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-textarea {
padding-right: 30px;
}
[dir="rtl"] .ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-textarea {
padding-left: 30px;
}
/* Squash the textarea horizontally if necessary on narrow layouts
* to avoid breaking the layout even at the cost of the placeholder
* being cut off (https://github.com/ckeditor/ckeditor5-commercial/issues/5913). */
@media screen and (max-width: 600px) {
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-textarea {
--ck-input-width: auto;
}
}
/* Prompt history group */
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-search__results .ck-list .ck-list__group {
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: auto;
grid-column-gap: 0px;
grid-row-gap: 0px;
/* History group label */
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-search__results .ck-list .ck-list__group > span {
grid-area: 1 / 1 / 2 / 2;
}
/* Clear button in the history */
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-search__results .ck-list .ck-list__group > .ck-button {
padding: 0;
min-height: auto;
grid-area: 1 / 2 / 2 / 3;
font-size: var(--ck-ai-form-history-font-size);
justify-self: start;
background: none;
margin: var(--ck-spacing-medium) 0 0;
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-search__results .ck-list .ck-list__group > .ck-button .ck-button__label {
line-height: inherit;
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-search__results .ck-list .ck-list__group > .ck-button .ck-button__label:hover {
text-decoration: underline;
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-search__results .ck-list .ck-list__group > .ck-list {
grid-area: 2 / 1 / 3 / 3;
/* Prompts can be very long. We need to display them whole. */
}
.ck .ck-ai-form .ck-ai-form-content .ck-autocomplete .ck-search__results .ck-list .ck-list__group > .ck-list .ck-list__item .ck-button .ck-button__label {
white-space: nowrap;
overflow: hidden;
max-width: 100%;
text-overflow: ellipsis;
font-size: var(--ck-ai-form-history-font-size);
line-height: var(--ck-line-height-base);
}
.ck .ck-ai-form .ck-ai-form__error {
display: flex;
justify-content: center;
align-items: center;
padding: var(--ck-spacing-medium);
background-color: var(--ck-ai-form-error-background);
color: var(--ck-color-base-text);
border-radius: 2px;
margin-bottom: var(--ck-spacing-medium);
}