add autocomplete details tooltips

This commit is contained in:
LenAnderson
2024-04-23 18:18:04 -04:00
parent 58a9937c99
commit dadfe7b19d
3 changed files with 100 additions and 42 deletions

View File

@ -90,7 +90,7 @@ export class SlashCommandAutoComplete {
textarea.addEventListener('keydown', (evt)=>this.handleKeyDown(evt)); textarea.addEventListener('keydown', (evt)=>this.handleKeyDown(evt));
textarea.addEventListener('click', ()=>this.isActive ? this.show() : null); textarea.addEventListener('click', ()=>this.isActive ? this.show() : null);
textarea.addEventListener('selectionchange', ()=>this.show()); textarea.addEventListener('selectionchange', ()=>this.show());
textarea.addEventListener('blur', ()=>this.hide()); // textarea.addEventListener('blur', ()=>this.hide());
if (isFloating) { if (isFloating) {
textarea.addEventListener('scroll', ()=>this.updateFloatingPositionDebounced()); textarea.addEventListener('scroll', ()=>this.updateFloatingPositionDebounced());
} }
@ -866,6 +866,7 @@ export class SlashCommandAutoComplete {
return; return;
} }
case 'Enter': { case 'Enter': {
// pick the selected item to autocomplete
if (evt.ctrlKey || evt.altKey || evt.shiftKey || this.selectedItem.type == OPTION_TYPE.BLANK) break; if (evt.ctrlKey || evt.altKey || evt.shiftKey || this.selectedItem.type == OPTION_TYPE.BLANK) break;
if (this.selectedItem.name == this.slashCommand) break; if (this.selectedItem.name == this.slashCommand) break;
evt.preventDefault(); evt.preventDefault();

View File

@ -120,6 +120,7 @@ export class SlashCommandAutoCompleteOption {
const name = document.createElement('div'); { const name = document.createElement('div'); {
name.classList.add('name'); name.classList.add('name');
name.classList.add('monospace'); name.classList.add('monospace');
name.title = 'command name';
name.textContent = `/${key}`; name.textContent = `/${key}`;
specs.append(name); specs.append(name);
} }
@ -130,42 +131,58 @@ export class SlashCommandAutoCompleteOption {
for (const arg of namedArguments) { for (const arg of namedArguments) {
const listItem = document.createElement('li'); { const listItem = document.createElement('li'); {
listItem.classList.add('argumentItem'); listItem.classList.add('argumentItem');
const argItem = document.createElement('div'); { const argSpec = document.createElement('div'); {
argItem.classList.add('argument'); argSpec.classList.add('argumentSpec');
argItem.classList.add('namedArgument'); const argItem = document.createElement('div'); {
if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional'); argItem.classList.add('argument');
if (arg.acceptsMultiple) argItem.classList.add('multiple'); argItem.classList.add('namedArgument');
const name = document.createElement('span'); { argItem.title = `${arg.isRequired ? '' : 'optional '}named argument`;
name.classList.add('argument-name'); if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
name.textContent = arg.name; if (arg.acceptsMultiple) argItem.classList.add('multiple');
argItem.append(name); const name = document.createElement('span'); {
} name.classList.add('argument-name');
if (arg.enumList.length > 0) { name.title = `${argItem.title} - name`;
const enums = document.createElement('span'); { name.textContent = arg.name;
enums.classList.add('argument-enums'); argItem.append(name);
for (const e of arg.enumList) {
const enumItem = document.createElement('span'); {
enumItem.classList.add('argument-enum');
enumItem.textContent = e;
enums.append(enumItem);
}
}
argItem.append(enums);
} }
} else { if (arg.enumList.length > 0) {
const types = document.createElement('span'); { const enums = document.createElement('span'); {
types.classList.add('argument-types'); enums.classList.add('argument-enums');
for (const t of arg.typeList) { enums.title = `${argItem.title} - accepted values`;
const type = document.createElement('span'); { for (const e of arg.enumList) {
type.classList.add('argument-type'); const enumItem = document.createElement('span'); {
type.textContent = t; enumItem.classList.add('argument-enum');
types.append(type); enumItem.textContent = e;
enums.append(enumItem);
}
} }
argItem.append(enums);
} }
argItem.append(types); } else {
const types = document.createElement('span'); {
types.classList.add('argument-types');
types.title = `${argItem.title} - accepted types`;
for (const t of arg.typeList) {
const type = document.createElement('span'); {
type.classList.add('argument-type');
type.textContent = t;
types.append(type);
}
}
argItem.append(types);
}
}
argSpec.append(argItem);
}
if (arg.defaultValue !== null) {
const argDefault = document.createElement('div'); {
argDefault.classList.add('argument-default');
argDefault.title = 'default value';
argDefault.textContent = arg.defaultValue.toString();
argSpec.append(argDefault);
} }
} }
listItem.append(argItem); listItem.append(argSpec);
} }
const desc = document.createElement('div'); { const desc = document.createElement('div'); {
desc.classList.add('argument-description'); desc.classList.add('argument-description');
@ -181,11 +198,13 @@ export class SlashCommandAutoCompleteOption {
const argItem = document.createElement('div'); { const argItem = document.createElement('div'); {
argItem.classList.add('argument'); argItem.classList.add('argument');
argItem.classList.add('unnamedArgument'); argItem.classList.add('unnamedArgument');
argItem.title = `${arg.isRequired ? '' : 'optional '}unnamed argument`;
if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional'); if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
if (arg.acceptsMultiple) argItem.classList.add('multiple'); if (arg.acceptsMultiple) argItem.classList.add('multiple');
if (arg.enumList.length > 0) { if (arg.enumList.length > 0) {
const enums = document.createElement('span'); { const enums = document.createElement('span'); {
enums.classList.add('argument-enums'); enums.classList.add('argument-enums');
enums.title = `${argItem.title} - accepted values`;
for (const e of arg.enumList) { for (const e of arg.enumList) {
const enumItem = document.createElement('span'); { const enumItem = document.createElement('span'); {
enumItem.classList.add('argument-enum'); enumItem.classList.add('argument-enum');
@ -198,6 +217,7 @@ export class SlashCommandAutoCompleteOption {
} else { } else {
const types = document.createElement('span'); { const types = document.createElement('span'); {
types.classList.add('argument-types'); types.classList.add('argument-types');
types.title = `${argItem.title} - accepted types`;
for (const t of arg.typeList) { for (const t of arg.typeList) {
const type = document.createElement('span'); { const type = document.createElement('span'); {
type.classList.add('argument-type'); type.classList.add('argument-type');
@ -222,6 +242,7 @@ export class SlashCommandAutoCompleteOption {
} }
const returns = document.createElement('span'); { const returns = document.createElement('span'); {
returns.classList.add('returns'); returns.classList.add('returns');
returns.title = [null, undefined, 'void'].includes(returnType) ? 'command does not return anything' : 'return value';
returns.textContent = returnType ?? 'void'; returns.textContent = returnType ?? 'void';
body.append(returns); body.append(returns);
} }

View File

@ -1292,9 +1292,6 @@ select {
height: 100%; height: 100%;
> .helpContent { > .helpContent {
&:before { content: " "; } &:before { content: " "; }
/* display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1; */
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
font-size: 0.9em;white-space: nowrap; font-size: 0.9em;white-space: nowrap;
@ -1314,12 +1311,17 @@ select {
flex-direction: column; flex-direction: column;
gap: 0.5em; gap: 0.5em;
> .specs { > .specs {
cursor: default;
flex-direction: column; flex-direction: column;
padding: 0.25em 0.25em 0.5em 0.25em; padding: 0.25em 0.25em 0.5em 0.25em;
border-bottom: 1px solid var(--ac-color-border); border-bottom: 1px solid var(--ac-color-border);
> .name { > .name {
font-weight: bold; font-weight: bold;
color: var(--ac-color-text); color: var(--ac-color-text);
cursor: help;
&:hover {
text-decoration: 1px dotted underline;
}
} }
> .body { > .body {
flex-direction: column; flex-direction: column;
@ -1330,7 +1332,39 @@ select {
> .argumentItem::marker { > .argumentItem::marker {
color: color-mix(in srgb, var(--ac-color-text), var(--ac-color-background)); color: color-mix(in srgb, var(--ac-color-text), var(--ac-color-background));
} }
.argument.optional + .argument-description:before {
.argumentSpec {
display: flex;
gap: 0.5em;
.argument-default {
&:before {
content: " = ";
color: var(--ac-color-text);
}
color: var(--ac-color-string);
}
}
.argument {
cursor: help;
&:hover:not(:has(.argument-name:hover, .argument-types:hover, .argument-enums:hover)) {
text-decoration: 1px dotted underline;
}
}
.argument-name,
.argument-types,
.argument-enums,
.argument-default
{
cursor: help;
&:hover {
text-decoration: 1px dotted underline;
}
}
.argument.optional + .argument-description:before,
.argumentSpec:has(.argument.optional) + argument.description:before
{
content: "(optional) "; content: "(optional) ";
color: var(--ac-color-text); color: var(--ac-color-text);
opacity: 0.5; opacity: 0.5;
@ -1342,6 +1376,12 @@ select {
font-size: 0.9em; font-size: 0.9em;
} }
} }
.returns {
cursor: help;
&:hover {
text-decoration: 1px dotted underline;
}
}
} }
} }
> .help { > .help {
@ -1418,15 +1458,13 @@ select {
color: var(--ac-color-text); color: var(--ac-color-text);
} }
> .argument-types { > .argument-types {
color: var(--ac-color-type);
word-break: break-all; word-break: break-all;
white-space: break-spaces; white-space: break-spaces;
> .argument-type + .argument-type:before { > .argument-type + .argument-type:before {
content: "|"; content: "|";
color: var(--ac-color-text); color: var(--ac-color-text);
}; };
> .argument-type {
color: var(--ac-color-type);
}
} }
> .argument-types + .argument-enums, > .argument-types + .argument-enums,
> .argument-name + .argument-enums > .argument-name + .argument-enums
@ -1437,15 +1475,13 @@ select {
} }
} }
> .argument-enums { > .argument-enums {
color: var(--ac-color-string);
word-break: break-all; word-break: break-all;
white-space: break-spaces; white-space: break-spaces;
> .argument-enum + .argument-enum:before { > .argument-enum + .argument-enum:before {
content: "|"; content: "|";
color: var(--ac-color-text); color: var(--ac-color-text);
}; };
> .argument-enum {
color: var(--ac-color-string);
}
} }
} }
} }