mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
use autocomplete parts in /? slash
This commit is contained in:
@ -219,6 +219,7 @@ import { ScraperManager } from './scripts/scrapers.js';
|
||||
import { SlashCommandParser } from './scripts/slash-commands/SlashCommandParser.js';
|
||||
import { SlashCommand } from './scripts/slash-commands/SlashCommand.js';
|
||||
import { ARGUMENT_TYPE, SlashCommandArgument } from './scripts/slash-commands/SlashCommandArgument.js';
|
||||
import { SlashCommandBrowser } from './scripts/slash-commands/SlashCommandBrowser.js';
|
||||
|
||||
//exporting functions and vars for mods
|
||||
export {
|
||||
@ -2447,6 +2448,14 @@ function sendSystemMessage(type, text, extra = {}) {
|
||||
chat.push(newMessage);
|
||||
addOneMessage(newMessage);
|
||||
is_send_press = false;
|
||||
if (type == system_message_types.SLASH_COMMANDS) {
|
||||
const browser = new SlashCommandBrowser();
|
||||
const spinner = document.querySelector('#chat .last_mes .custom-slashHelp');
|
||||
const parent = spinner.parentElement;
|
||||
spinner.remove();
|
||||
browser.renderInto(parent);
|
||||
browser.search.focus();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,4 +190,171 @@ export class SlashCommand {
|
||||
}
|
||||
return li;
|
||||
}
|
||||
|
||||
renderHelpDetails(key = null) {
|
||||
const frag = document.createDocumentFragment();
|
||||
key = key ?? this.name;
|
||||
const cmd = this;
|
||||
const namedArguments = cmd.namedArgumentList ?? [];
|
||||
const unnamedArguments = cmd.unnamedArgumentList ?? [];
|
||||
const returnType = cmd.returns ?? 'void';
|
||||
const helpString = cmd.helpString ?? 'NO DETAILS';
|
||||
const aliasList = [cmd.name, ...(cmd.aliases ?? [])].filter(it=>it != key);
|
||||
const specs = document.createElement('div'); {
|
||||
specs.classList.add('specs');
|
||||
const name = document.createElement('div'); {
|
||||
name.classList.add('name');
|
||||
name.classList.add('monospace');
|
||||
name.title = 'command name';
|
||||
name.textContent = `/${key}`;
|
||||
specs.append(name);
|
||||
}
|
||||
const body = document.createElement('div'); {
|
||||
body.classList.add('body');
|
||||
const args = document.createElement('ul'); {
|
||||
args.classList.add('arguments');
|
||||
for (const arg of namedArguments) {
|
||||
const listItem = document.createElement('li'); {
|
||||
listItem.classList.add('argumentItem');
|
||||
const argSpec = document.createElement('div'); {
|
||||
argSpec.classList.add('argumentSpec');
|
||||
const argItem = document.createElement('div'); {
|
||||
argItem.classList.add('argument');
|
||||
argItem.classList.add('namedArgument');
|
||||
argItem.title = `${arg.isRequired ? '' : 'optional '}named argument`;
|
||||
if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
|
||||
if (arg.acceptsMultiple) argItem.classList.add('multiple');
|
||||
const name = document.createElement('span'); {
|
||||
name.classList.add('argument-name');
|
||||
name.title = `${argItem.title} - name`;
|
||||
name.textContent = arg.name;
|
||||
argItem.append(name);
|
||||
}
|
||||
if (arg.enumList.length > 0) {
|
||||
const enums = document.createElement('span'); {
|
||||
enums.classList.add('argument-enums');
|
||||
enums.title = `${argItem.title} - accepted values`;
|
||||
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 {
|
||||
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(argSpec);
|
||||
}
|
||||
const desc = document.createElement('div'); {
|
||||
desc.classList.add('argument-description');
|
||||
desc.innerHTML = arg.description;
|
||||
listItem.append(desc);
|
||||
}
|
||||
args.append(listItem);
|
||||
}
|
||||
}
|
||||
for (const arg of unnamedArguments) {
|
||||
const listItem = document.createElement('li'); {
|
||||
listItem.classList.add('argumentItem');
|
||||
const argItem = document.createElement('div'); {
|
||||
argItem.classList.add('argument');
|
||||
argItem.classList.add('unnamedArgument');
|
||||
argItem.title = `${arg.isRequired ? '' : 'optional '}unnamed argument`;
|
||||
if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
|
||||
if (arg.acceptsMultiple) argItem.classList.add('multiple');
|
||||
if (arg.enumList.length > 0) {
|
||||
const enums = document.createElement('span'); {
|
||||
enums.classList.add('argument-enums');
|
||||
enums.title = `${argItem.title} - accepted values`;
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
listItem.append(argItem);
|
||||
}
|
||||
const desc = document.createElement('div'); {
|
||||
desc.classList.add('argument-description');
|
||||
desc.innerHTML = arg.description;
|
||||
listItem.append(desc);
|
||||
}
|
||||
args.append(listItem);
|
||||
}
|
||||
}
|
||||
body.append(args);
|
||||
}
|
||||
const returns = document.createElement('span'); {
|
||||
returns.classList.add('returns');
|
||||
returns.title = [null, undefined, 'void'].includes(returnType) ? 'command does not return anything' : 'return value';
|
||||
returns.textContent = returnType ?? 'void';
|
||||
body.append(returns);
|
||||
}
|
||||
specs.append(body);
|
||||
}
|
||||
frag.append(specs);
|
||||
}
|
||||
const help = document.createElement('span'); {
|
||||
help.classList.add('help');
|
||||
help.innerHTML = helpString;
|
||||
frag.append(help);
|
||||
}
|
||||
if (aliasList.length > 0) {
|
||||
const aliases = document.createElement('span'); {
|
||||
aliases.classList.add('aliases');
|
||||
aliases.append(' (alias: ');
|
||||
for (const aliasName of aliasList) {
|
||||
const alias = document.createElement('span'); {
|
||||
alias.classList.add('monospace');
|
||||
alias.textContent = `/${aliasName}`;
|
||||
aliases.append(alias);
|
||||
}
|
||||
}
|
||||
aliases.append(')');
|
||||
frag.append(aliases);
|
||||
}
|
||||
}
|
||||
return frag;
|
||||
}
|
||||
}
|
||||
|
@ -282,171 +282,10 @@ export class SlashCommandAutoCompleteOption {
|
||||
return frag;
|
||||
}
|
||||
renderCommandDetails() {
|
||||
const frag = document.createDocumentFragment();
|
||||
const key = this.name;
|
||||
/**@type {SlashCommand} */
|
||||
// @ts-ignore
|
||||
const cmd = this.value;
|
||||
const namedArguments = cmd.namedArgumentList ?? [];
|
||||
const unnamedArguments = cmd.unnamedArgumentList ?? [];
|
||||
const returnType = cmd.returns ?? 'void';
|
||||
const helpString = cmd.helpString ?? 'NO DETAILS';
|
||||
const aliasList = [cmd.name, ...(cmd.aliases ?? [])].filter(it=>it != key);
|
||||
const specs = document.createElement('div'); {
|
||||
specs.classList.add('specs');
|
||||
const name = document.createElement('div'); {
|
||||
name.classList.add('name');
|
||||
name.classList.add('monospace');
|
||||
name.title = 'command name';
|
||||
name.textContent = `/${key}`;
|
||||
specs.append(name);
|
||||
}
|
||||
const body = document.createElement('div'); {
|
||||
body.classList.add('body');
|
||||
const args = document.createElement('ul'); {
|
||||
args.classList.add('arguments');
|
||||
for (const arg of namedArguments) {
|
||||
const listItem = document.createElement('li'); {
|
||||
listItem.classList.add('argumentItem');
|
||||
const argSpec = document.createElement('div'); {
|
||||
argSpec.classList.add('argumentSpec');
|
||||
const argItem = document.createElement('div'); {
|
||||
argItem.classList.add('argument');
|
||||
argItem.classList.add('namedArgument');
|
||||
argItem.title = `${arg.isRequired ? '' : 'optional '}named argument`;
|
||||
if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
|
||||
if (arg.acceptsMultiple) argItem.classList.add('multiple');
|
||||
const name = document.createElement('span'); {
|
||||
name.classList.add('argument-name');
|
||||
name.title = `${argItem.title} - name`;
|
||||
name.textContent = arg.name;
|
||||
argItem.append(name);
|
||||
}
|
||||
if (arg.enumList.length > 0) {
|
||||
const enums = document.createElement('span'); {
|
||||
enums.classList.add('argument-enums');
|
||||
enums.title = `${argItem.title} - accepted values`;
|
||||
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 {
|
||||
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(argSpec);
|
||||
}
|
||||
const desc = document.createElement('div'); {
|
||||
desc.classList.add('argument-description');
|
||||
desc.innerHTML = arg.description;
|
||||
listItem.append(desc);
|
||||
}
|
||||
args.append(listItem);
|
||||
}
|
||||
}
|
||||
for (const arg of unnamedArguments) {
|
||||
const listItem = document.createElement('li'); {
|
||||
listItem.classList.add('argumentItem');
|
||||
const argItem = document.createElement('div'); {
|
||||
argItem.classList.add('argument');
|
||||
argItem.classList.add('unnamedArgument');
|
||||
argItem.title = `${arg.isRequired ? '' : 'optional '}unnamed argument`;
|
||||
if (!arg.isRequired || (arg.defaultValue ?? false)) argItem.classList.add('optional');
|
||||
if (arg.acceptsMultiple) argItem.classList.add('multiple');
|
||||
if (arg.enumList.length > 0) {
|
||||
const enums = document.createElement('span'); {
|
||||
enums.classList.add('argument-enums');
|
||||
enums.title = `${argItem.title} - accepted values`;
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
listItem.append(argItem);
|
||||
}
|
||||
const desc = document.createElement('div'); {
|
||||
desc.classList.add('argument-description');
|
||||
desc.innerHTML = arg.description;
|
||||
listItem.append(desc);
|
||||
}
|
||||
args.append(listItem);
|
||||
}
|
||||
}
|
||||
body.append(args);
|
||||
}
|
||||
const returns = document.createElement('span'); {
|
||||
returns.classList.add('returns');
|
||||
returns.title = [null, undefined, 'void'].includes(returnType) ? 'command does not return anything' : 'return value';
|
||||
returns.textContent = returnType ?? 'void';
|
||||
body.append(returns);
|
||||
}
|
||||
specs.append(body);
|
||||
}
|
||||
frag.append(specs);
|
||||
}
|
||||
const help = document.createElement('span'); {
|
||||
help.classList.add('help');
|
||||
help.innerHTML = helpString;
|
||||
frag.append(help);
|
||||
}
|
||||
if (aliasList.length > 0) {
|
||||
const aliases = document.createElement('span'); {
|
||||
aliases.classList.add('aliases');
|
||||
aliases.append(' (alias: ');
|
||||
for (const aliasName of aliasList) {
|
||||
const alias = document.createElement('span'); {
|
||||
alias.classList.add('monospace');
|
||||
alias.textContent = `/${aliasName}`;
|
||||
aliases.append(alias);
|
||||
}
|
||||
}
|
||||
aliases.append(')');
|
||||
frag.append(aliases);
|
||||
}
|
||||
}
|
||||
return frag;
|
||||
return cmd.renderHelpDetails(key);
|
||||
}
|
||||
}
|
||||
|
148
public/scripts/slash-commands/SlashCommandBrowser.js
Normal file
148
public/scripts/slash-commands/SlashCommandBrowser.js
Normal file
@ -0,0 +1,148 @@
|
||||
import { escapeRegex } from '../utils.js';
|
||||
import { SlashCommand } from './SlashCommand.js';
|
||||
import { SlashCommandParser } from './SlashCommandParser.js';
|
||||
|
||||
export class SlashCommandBrowser {
|
||||
/**@type {SlashCommand[]}*/ cmdList;
|
||||
/**@type {HTMLElement}*/ dom;
|
||||
/**@type {HTMLElement}*/ search;
|
||||
/**@type {HTMLElement}*/ details;
|
||||
/**@type {Object.<string,HTMLElement>}*/ itemMap = {};
|
||||
/**@type {MutationObserver}*/ mo;
|
||||
|
||||
renderInto(parent) {
|
||||
if (!this.dom) {
|
||||
const queryRegex = /(?:(?:^|\s+)([^\s"][^\s]*?)(?:\s+|$))|(?:(?:^|\s+)"(.*?)(?:"|$)(?:\s+|$))/;
|
||||
const root = document.createElement('div'); {
|
||||
this.dom = root;
|
||||
const search = document.createElement('div'); {
|
||||
search.classList.add('search');
|
||||
const lbl = document.createElement('label'); {
|
||||
lbl.classList.add('searchLabel');
|
||||
lbl.textContent = 'Search: ';
|
||||
const inp = document.createElement('input'); {
|
||||
this.search = inp;
|
||||
inp.classList.add('searchInput');
|
||||
inp.classList.add('text_pole');
|
||||
inp.type = 'search';
|
||||
inp.placeholder = 'Search slash commands - use quotes to search "literal" instead of fuzzy';
|
||||
inp.addEventListener('input', ()=>{
|
||||
this.details?.remove();
|
||||
this.details = null;
|
||||
let query = inp.value.trim();
|
||||
if (query.slice(-1) == '"' && !/(?:^|\s+)"/.test(query)) {
|
||||
query = `"${query}`;
|
||||
}
|
||||
let fuzzyList = [];
|
||||
let quotedList = [];
|
||||
while (query.length > 0) {
|
||||
const match = queryRegex.exec(query);
|
||||
if (!match) break;
|
||||
if (match[1] !== undefined) {
|
||||
fuzzyList.push(new RegExp(`^(.*?)${match[1].split('').map(char=>`(${escapeRegex(char)})`).join('(.*?)')}(.*?)$`, 'i'));
|
||||
} else if (match[2] !== undefined) {
|
||||
quotedList.push(match[2]);
|
||||
}
|
||||
query = query.slice(match.index + match[0].length);
|
||||
}
|
||||
for (const cmd of this.cmdList) {
|
||||
const targets = [
|
||||
cmd.name,
|
||||
...cmd.namedArgumentList.map(it=>it.name),
|
||||
...cmd.namedArgumentList.map(it=>it.description),
|
||||
...cmd.namedArgumentList.map(it=>it.enumList).flat(),
|
||||
...cmd.namedArgumentList.map(it=>it.typeList).flat(),
|
||||
...cmd.unnamedArgumentList.map(it=>it.description),
|
||||
...cmd.unnamedArgumentList.map(it=>it.enumList).flat(),
|
||||
...cmd.unnamedArgumentList.map(it=>it.typeList).flat(),
|
||||
...cmd.aliases,
|
||||
cmd.helpString,
|
||||
];
|
||||
const find = ()=>targets.find(t=>(fuzzyList.find(f=>f.test(t)) ?? quotedList.find(q=>t.includes(q))) !== undefined) !== undefined;
|
||||
if (fuzzyList.length + quotedList.length == 0 || find()) {
|
||||
this.itemMap[cmd.name].classList.remove('isFiltered');
|
||||
} else {
|
||||
this.itemMap[cmd.name].classList.add('isFiltered');
|
||||
}
|
||||
}
|
||||
});
|
||||
lbl.append(inp);
|
||||
}
|
||||
search.append(lbl);
|
||||
}
|
||||
root.append(search);
|
||||
}
|
||||
const container = document.createElement('div'); {
|
||||
container.classList.add('commandContainer');
|
||||
const list = document.createElement('div'); {
|
||||
list.classList.add('slashCommandAutoComplete');
|
||||
this.cmdList = Object
|
||||
.keys(SlashCommandParser.commands)
|
||||
.filter(key => SlashCommandParser.commands[key].name == key) // exclude aliases
|
||||
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
||||
.map(key => SlashCommandParser.commands[key])
|
||||
;
|
||||
for (const cmd of this.cmdList) {
|
||||
const item = cmd.renderHelpItem();
|
||||
this.itemMap[cmd.name] = item;
|
||||
let details;
|
||||
item.addEventListener('click', ()=>{
|
||||
if (!details) {
|
||||
details = document.createElement('div'); {
|
||||
details.classList.add('slashCommandAutoComplete-detailsWrap');
|
||||
const inner = document.createElement('div'); {
|
||||
inner.classList.add('slashCommandAutoComplete-details');
|
||||
inner.append(cmd.renderHelpDetails());
|
||||
details.append(inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.details != details) {
|
||||
Array.from(list.querySelectorAll('.selected')).forEach(it=>it.classList.remove('selected'));
|
||||
item.classList.add('selected');
|
||||
this.details?.remove();
|
||||
container.append(details);
|
||||
this.details = details;
|
||||
const pRect = list.getBoundingClientRect();
|
||||
const rect = item.children[0].getBoundingClientRect();
|
||||
details.style.setProperty('--targetOffset', rect.top - pRect.top);
|
||||
} else {
|
||||
item.classList.remove('selected');
|
||||
details.remove();
|
||||
this.details = null;
|
||||
}
|
||||
});
|
||||
list.append(item);
|
||||
}
|
||||
container.append(list);
|
||||
}
|
||||
root.append(container);
|
||||
}
|
||||
root.classList.add('slashCommandBrowser');
|
||||
}
|
||||
}
|
||||
parent.append(this.dom);
|
||||
|
||||
this.mo = new MutationObserver(muts=>{
|
||||
if (muts.find(mut=>Array.from(mut.removedNodes).find(it=>it == this.dom || it.contains(this.dom)))) {
|
||||
this.mo.disconnect();
|
||||
window.removeEventListener('keydown', boundHandler);
|
||||
}
|
||||
});
|
||||
this.mo.observe(document.querySelector('#chat'), { childList:true, subtree:true });
|
||||
const boundHandler = this.handleKeyDown.bind(this);
|
||||
window.addEventListener('keydown', boundHandler);
|
||||
return this.dom;
|
||||
}
|
||||
|
||||
handleKeyDown(evt) {
|
||||
if (!evt.shiftKey && !evt.altKey && evt.ctrlKey && evt.key.toLowerCase() == 'f') {
|
||||
if (!this.dom.closest('body')) return;
|
||||
if (this.dom.closest('.mes') && !this.dom.closest('.last_mes')) return;
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
evt.stopImmediatePropagation();
|
||||
this.search.focus();
|
||||
}
|
||||
}
|
||||
}
|
@ -255,6 +255,9 @@ export class SlashCommandParser {
|
||||
}
|
||||
|
||||
getHelpString() {
|
||||
return '<div class="slashHelp">Loading...</div>';
|
||||
}
|
||||
getHelpStringX() {
|
||||
const listItems = Object
|
||||
.keys(this.commands)
|
||||
.filter(key=>this.commands[key].name == key)
|
||||
|
@ -1197,6 +1197,7 @@ select {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slashCommandAutoComplete, .slashCommandAutoComplete-details {
|
||||
--ac-color-border: rgb(69 69 69);
|
||||
--ac-color-background: rgb(32 32 32);
|
||||
@ -1225,6 +1226,9 @@ select {
|
||||
margin: 0px;
|
||||
overflow: auto;
|
||||
padding: 0px;
|
||||
padding-bottom: 1px;
|
||||
line-height: 1.2;
|
||||
text-align: left;
|
||||
z-index: 10000;
|
||||
}
|
||||
.slashCommandAutoComplete {
|
||||
@ -1232,7 +1236,7 @@ select {
|
||||
/* position: absolute; */
|
||||
display: grid;
|
||||
grid-template-columns: 0fr auto minmax(50%, 1fr);
|
||||
align-items: baseline;
|
||||
align-items: center;
|
||||
max-height: calc(95vh - var(--bottom));
|
||||
/* gap: 0.5em; */
|
||||
> .item {
|
||||
@ -1497,6 +1501,60 @@ select {
|
||||
}
|
||||
}
|
||||
|
||||
.slashCommandBrowser {
|
||||
> .search {
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
align-items: baseline;
|
||||
white-space: nowrap;
|
||||
> .searchLabel {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
gap: 0.5em;
|
||||
align-items: baseline;
|
||||
> .searchInput {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
> .searchOptions {
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
align-items: baseline;
|
||||
}
|
||||
}
|
||||
> .commandContainer {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
> .slashCommandAutoComplete {
|
||||
flex: 1 1 auto;
|
||||
max-height: unset;
|
||||
> .isFiltered {
|
||||
display: none;
|
||||
}
|
||||
.specs {
|
||||
grid-column: 2 / 4;
|
||||
}
|
||||
.help {
|
||||
grid-column: 2 / 4;
|
||||
padding-left: 1em;
|
||||
opacity: 0.75;
|
||||
}
|
||||
}
|
||||
> .slashCommandAutoComplete-detailsWrap {
|
||||
flex: 0 0 auto;
|
||||
align-self: stretch;
|
||||
width: 30%;
|
||||
position: static;
|
||||
&:before {
|
||||
flex: 0 1 calc(var(--targetOffset) * 1px);
|
||||
}
|
||||
> .slashCommandAutoComplete-details {
|
||||
max-height: 50vh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#character_popup .editor_maximize {
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
|
Reference in New Issue
Block a user