-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce autocompleting (mentions) #998
Comments
What is the status of this feature.? |
We'd love to work on it but we don't have the capacity at the moment and I'm not sure now when we'll be able to start working on it. |
@Reinmar |
Was wondering the same, any chance of just updating the hackathon? I have tried but my JS is lowsy |
We held that hackathon ~2 years ago and since then the API changed drastically, so, unfortunately, it's more about writing it from scratch. Anyway, I'll know more about our plans next week, so 🤞 :) |
Please!! - i guess I could fallback to V4, that has mentions? Right? |
CKE4 will have the autocomplete feature tomorrow (4.10.0 is scheduled for tomorrow and this feature will be a part of it). So, yes, if you need autocomplete today, CKE4 would be the easiest option. |
Hei @Reinmar, here in Brazil we are also waiting for the feature also. Please, think fondly and convince your team :) |
Any word on this feature??? |
Any update on this ? |
It's in the roadmap for Q1 this year. We'll start working on this soon. |
There was a hackathon if your interested for this request if you want to go that route. Autocompletion (suggestions) |
this is wonderful feature to have in ck5 hopefully it will be flexible can we have configurable different endpoint for different usage
|
Bootstrapping MentionsGeneral ideaI think that we leans toward implementing Mentions plugin + extensive guide on how to implement similar features using CKE5 API. CKEditor 4 comparisonThe CKEditor 4 some time ago introduced constellation of plugins of similar feature set;
For the mentions MVP we need:
High level API:Mentions plugin configurationCKEditor 4 has 10 config options - which is too much for CKE5:
I'd go with minimal set of requirements as we're going to expose building blocks + awesome guide :). Examples: // minimal:
ClassicEditor.create( '#editor', {
mentions: {
feed: [ 'Casper', 'Mathew', 'Peter', 'Symon', 'Victor' ],
}
} );
// async:
const mentionsConfig = {
feed: ( text ) => {
const filteredNames = [ 'Casper', 'Mathew', 'Peter', 'Symon', 'Victor' ]
.filter( n => n.toLowerCase().startsWith( text ) );
// Might be with setTimeout() ;)
return Promise.resolve( filteredNames );
},
chars: 2
}
// multiple configurations:
const mentionsConfig = [
{ feed: [ 'Casper', 'Mathew', 'Peter', 'Symon', 'Victor' ] },
{ marker: '#', feed: ( text ) => fetchTicketIdsFromServer( text ), chars: 2 },
{ marker: ':', feed: ( text ) => getEmojis( text ) }
] Model-View and output customizationModel: <paragraph>Foo <mention>@jodator</mention> bar</paragraph> Default view: <p>Foo <span class="ck-mention">@jodator</span> bar</p> The mention is only inserted when user accepts it from list (more on this later in UI/UX). Extensibility vs widget requirementsWe do not have templates as in CKE 4 and I don't see them required for CKE5. We can tell people to override default converter ie: ClassicEditor.create( '#editor', {
mentions: {
feed: [ 'foo', 'bar', 'baz' ]
},
extraPlugins: [ editor => {
// Plugin that overrides conversion
editor.conversion.elementToElement( 'mention', {
view: {
name: 'span',
classes: 'ck-mention'
},
model: 'mention',
converterPriority: 'high'
} );
} ]
} ); But then the returned thingy might loose widget behavior. In order to make proper separation we could go either way:
POC in action (default sample produces UI/UX
Stubs of API / plugin implementation:Bunch of API usage ideas gathered in code - just to showcase ideas of bundling stuff together. It does not show the Mentions plugin (ie missing reading configuration) but rather a stub plugin for a guide. class MyMentions extends Plugin {
init() {
const editor = this.editor;
const watcher = editor.plugins.get( 'TextWatcher' );
const observable = watcher.watch( /foo/ );
observable.on( 'match', ( evt, data ) => {
if ( !this.isWatching ) {
this.startWatching();
}
const visibleMentions = getMentions( data.text );
updateItems( this._items, visibleMentions, this.getItemCreator() );
} );
observable.on( 'unmatch', () => this.stopWatching() );
}
getMentions( text ) {
const models = [ 'peter', 'matthiew', 'marco', 'symon' ]
.filter( name => name.startsWith( text ) )
.map( name => new Model( { label: text } ) );
// Might be stored also...
return new Collection( models );
}
// Also provide API for extending / overriding.
getItemCreator() {
// The default would just return ListItemView
return item => {
const listItemView = new ListItemView( locale );
const buttonView = new ButtonView( locale );
// Bind all model properties to the button view.
buttonView.bind( ...Object.keys( model ) ).to( model );
buttonView.delegate( 'execute' ).to( listItemView );
listItemView.children.add( buttonView );
return listItemView;
};
}
startWatching() {
this._items = new Collection();
const listView = createListView(); // util, might be similar to dropdown utils
// or this._window.show(); if already present.
listView.items.bindTo( items );
// dunno the name...
this._window = showSelectionToolWindow( listView ); // util
}
stopWatching( ) {
this._window.hide(); // or destroy
}
} Bonus:Possible problems (as with CKE 4 from @jacekbogdanski ):
|
It would be good to clarify what is a part of autocomplete feature and what is already mentions (a feature using autocomplete or autocomplete implementation/configuration). Do you want to expose things like I am not sure if I like having a (finished) mention as a widget. It doesn't feel right for some reason, I am not sure about UX around that. I guess I'd have to try, but I think no-one does it like that. Remember that if in a widget, that text will not be editable, there will be some weirdness with the selection, etc. I think that a mention should still be a plain-text but with some styling. I think that it will be important to provide a way for people to hook their own callbacks when a mention gets selected (finished) and also when it was removed (undo, backspace). This way people will be able to implement their own integrations (for example, sending an e-mail when someone is mentioned). I think it is crucial to have it done in a simple way - by passing a callback function in the config. I'd go with that in MVP, we already are being asked about things like this. |
Check how slack mentions are implemented - it might be an editable widget after all. But editing it would break the mention. Anyway the inserted mention is something to discuss on UI/UX part. But I don't like that inserted mention would loose a meaning - ie it would be converted down to a general link is not good IMO.
That's a good point. I thought that one could listen to selection change event and check the selected element so no configuration would be necessary. (also a good thing to add to a guide. |
This part of the feature is probably doable with some weird hacky way outside of the feature, but why make it difficult for 3rd party integrators if we already have all the parts in the feature, we just need a nice way to expose them :).
All I meant is that I think that not having it converted to a widget might be a better UX. To be checked and discussed. |
To sum up some F2F talks. So for the mentions MVP: The default implementation without any customization will support string-like data: ClassicEditor.create( '#editor' , {
mentions: [
{
marker: '@',
feed: [ 'foo', 'bar', 'baz' ],
}
]
} ); The customization will allow to change item template in the UI as well as the rendered node. ClassicEditor.create( 'foo', {
mentions: [
{
marker: '@',
feed: ( match ) => {
return [
{ id: 1410, name: 'John' },
{ id: 966, name: 'Johnatan' }
];
},
itemRenderer: ( item ) => {
// Control how the the UI list items are rendered:
return createDomFromHtml( `<div class="item">${ item.name }</div>` );
}
}
]
} ); The default converter will insert span: editor.model.change( writer => {
const label = item.name || item; // The name being the default.
writer.insertText( label, { mention: item }, editor.model.selection.getFirstPosition() );
} ); The created mention will be stored in the model as text node attribute: <$text mention="John">John</$text>
<span class=mention data-mention="John">John</span> Alternative (extension) to be tested in a manual test: <$text mention="{id:1345,name:John Watch}">John Watch</$text>
<span class=mention data-mention="1234">John Watch</span> Other requirements:
Stub for UI talks. The items in the autocomplete lists will be dipslayed using list view: <ul class=ck-list-panel>
<li class=ck-list-item ck-mention-item ck-item-selected>
// <- itemRender( item )
</li>
</ul> The MVP should allow us to check if the approach is OK and easily extensible and:
|
No callbacks on mention create / remove in MVP? :( |
Sometimes we would prefer to display full name instead of user name or id just like in Facebook. |
Feature: The mentions feature. Closes ckeditor/ckeditor5#998.
The feature supports defining what text should be inserted into the editor and what's saved in the data attribute. The output looks like this: <span class="mention" data-mention="@someId">Someone's name</span> It's also possible (and covered by the documentation) how to completely customize the element that's being rendered. |
I would like to use this plugin as a kind of suggestion tool, while entereing some expression. When I start typing something like $Database.ta Also the trigger is not working when I type =$. I have to type a blank after the = Any chance these limiting characters - I suppose they are a kind of limiting caharacters- can be configured. Or can I use a configurable regex for this, like in some other editors, I evaluated. |
did you found any solution for this? |
Almost every simple editor that we use in real life comes with some kind of autocomplete that helps a lot. For example I cannot imagine not being able to write messages on GitHub without being able to mention someone nickname, same on Slack with mentioning for example channels, nicknames, including emojis etc.
This issue is created to track the interest, use cases and ideas before we start working on it.
The text was updated successfully, but these errors were encountered: