UNPKG

@ckeditor/ckeditor5-ai

Version:

AI Assistant feature for CKEditor 5.

393 lines (360 loc) • 15.2 kB
/** * @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); }