mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-27 21:48:27 +00:00
reactify autocomplete info
This commit is contained in:
parent
0f18f5eb81
commit
f497d7b212
72
packages/react/src/components/Autocomplete.jsx
Normal file
72
packages/react/src/components/Autocomplete.jsx
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
|
import jsdoc from '../../../../doc.json';
|
||||||
|
|
||||||
|
const getDocLabel = (doc) => doc.name || doc.longname;
|
||||||
|
|
||||||
|
export function Autocomplete({ doc }) {
|
||||||
|
return (
|
||||||
|
<div className="prose prose-invert max-h-[400px] overflow-auto">
|
||||||
|
<h3 className="pt-0 mt-0">{getDocLabel(doc)}</h3>
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: doc.description }} />
|
||||||
|
<ul>
|
||||||
|
{doc.params?.map(({ name, type, description }, i) => (
|
||||||
|
<li key={i}>
|
||||||
|
{name} : {type.names?.join(' | ')} {description ? <> - {description}</> : ''}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<div>
|
||||||
|
{doc.examples?.map((example, i) => (
|
||||||
|
<div key={i}>
|
||||||
|
<pre
|
||||||
|
className="cursor-pointer"
|
||||||
|
onMouseDown={(e) => {
|
||||||
|
console.log('ola!');
|
||||||
|
navigator.clipboard.writeText(example);
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{example}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsdocCompletions = jsdoc.docs
|
||||||
|
.filter(
|
||||||
|
(doc) =>
|
||||||
|
getDocLabel(doc) &&
|
||||||
|
!getDocLabel(doc).startsWith('_') &&
|
||||||
|
!['package'].includes(doc.kind) &&
|
||||||
|
!['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)),
|
||||||
|
)
|
||||||
|
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
||||||
|
.map((doc) /*: Completion */ => ({
|
||||||
|
label: getDocLabel(doc),
|
||||||
|
// detail: 'xxx', // An optional short piece of information to show (with a different style) after the label.
|
||||||
|
info: () => {
|
||||||
|
const node = document.createElement('div');
|
||||||
|
// if Autocomplete is non-interactive, it could also be rendered at build time..
|
||||||
|
// .. using renderToStaticMarkup
|
||||||
|
createRoot(node).render(<Autocomplete doc={doc} />);
|
||||||
|
return node;
|
||||||
|
},
|
||||||
|
type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const strudelAutocomplete = (context /* : CompletionContext */) => {
|
||||||
|
let word = context.matchBefore(/\w*/);
|
||||||
|
if (word.from == word.to && !context.explicit) return null;
|
||||||
|
return {
|
||||||
|
from: word.from,
|
||||||
|
options: jsdocCompletions,
|
||||||
|
/* options: [
|
||||||
|
{ label: 'match', type: 'keyword' },
|
||||||
|
{ label: 'hello', type: 'variable', info: '(World)' },
|
||||||
|
{ label: 'magic', type: 'text', apply: '⠁⭒*.✩.*⭒⠁', detail: 'macro' },
|
||||||
|
], */
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -7,7 +7,7 @@ import strudelTheme from '../themes/strudel-theme';
|
|||||||
import './style.css';
|
import './style.css';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { autocompletion } from '@codemirror/autocomplete';
|
import { autocompletion } from '@codemirror/autocomplete';
|
||||||
import jsdoc from '../../../../doc.json';
|
import { strudelAutocomplete } from './Autocomplete';
|
||||||
|
|
||||||
export const setFlash = StateEffect.define();
|
export const setFlash = StateEffect.define();
|
||||||
const flashField = StateField.define({
|
const flashField = StateField.define({
|
||||||
@ -81,72 +81,6 @@ const highlightField = StateField.define({
|
|||||||
provide: (f) => EditorView.decorations.from(f),
|
provide: (f) => EditorView.decorations.from(f),
|
||||||
});
|
});
|
||||||
|
|
||||||
const getDocLabel = (doc) => doc.name || doc.longname;
|
|
||||||
const jsdocCompletions = jsdoc.docs
|
|
||||||
.filter(
|
|
||||||
(doc) =>
|
|
||||||
getDocLabel(doc) &&
|
|
||||||
!getDocLabel(doc).startsWith('_') &&
|
|
||||||
!['package'].includes(doc.kind) &&
|
|
||||||
!['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag)),
|
|
||||||
)
|
|
||||||
// https://codemirror.net/docs/ref/#autocomplete.Completion
|
|
||||||
.map((doc) /*: Completion */ => ({
|
|
||||||
label: getDocLabel(doc),
|
|
||||||
// detail: 'xxx', // An optional short piece of information to show (with a different style) after the label.
|
|
||||||
info: () => {
|
|
||||||
const heading = document.createElement('h3');
|
|
||||||
heading.innerText = getDocLabel(doc);
|
|
||||||
heading.style = 'padding-top:0;margin-top:0';
|
|
||||||
const description = document.createElement('div');
|
|
||||||
description.innerHTML = doc.description;
|
|
||||||
const params = document.createElement('ul');
|
|
||||||
doc.params?.forEach(({ name, type, description }) => {
|
|
||||||
const li = document.createElement('li');
|
|
||||||
const span = document.createElement('span');
|
|
||||||
span.innerText = name + ': ' + type.names?.join(' | ') + (description ? ' - ' : '');
|
|
||||||
const c = document.createElement('span');
|
|
||||||
c.innerHTML = description || '';
|
|
||||||
const comment = document.createElement('span');
|
|
||||||
comment.innerHTML = c.innerText;
|
|
||||||
li.appendChild(span);
|
|
||||||
li.appendChild(comment);
|
|
||||||
params.appendChild(li);
|
|
||||||
});
|
|
||||||
const examples = document.createElement('div');
|
|
||||||
doc.examples?.forEach((ex) => {
|
|
||||||
const code = document.createElement('pre');
|
|
||||||
code.style = 'font-size:14px';
|
|
||||||
code.innerText = ex;
|
|
||||||
examples.appendChild(code);
|
|
||||||
});
|
|
||||||
const node = document.createElement('div');
|
|
||||||
node.classList.add('prose');
|
|
||||||
node.classList.add('prose-invert');
|
|
||||||
node.style = 'max-width:500px;max-height:400px;overflow:auto';
|
|
||||||
node.appendChild(heading);
|
|
||||||
node.appendChild(description);
|
|
||||||
node.appendChild(params);
|
|
||||||
node.appendChild(examples);
|
|
||||||
return node;
|
|
||||||
}, // Additional info to show when the completion is selected
|
|
||||||
type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const strudelAutocomplete = (context /* : CompletionContext */) => {
|
|
||||||
let word = context.matchBefore(/\w*/);
|
|
||||||
if (word.from == word.to && !context.explicit) return null;
|
|
||||||
return {
|
|
||||||
from: word.from,
|
|
||||||
options: jsdocCompletions,
|
|
||||||
/* options: [
|
|
||||||
{ label: 'match', type: 'keyword' },
|
|
||||||
{ label: 'hello', type: 'variable', info: '(World)' },
|
|
||||||
{ label: 'magic', type: 'text', apply: '⠁⭒*.✩.*⭒⠁', detail: 'macro' },
|
|
||||||
], */
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const extensions = [
|
const extensions = [
|
||||||
javascript(),
|
javascript(),
|
||||||
strudelTheme,
|
strudelTheme,
|
||||||
|
|||||||
@ -18,3 +18,7 @@
|
|||||||
padding-top: 12px !important;
|
padding-top: 12px !important;
|
||||||
padding-left: 8px !important;
|
padding-left: 8px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cm-scroller {
|
||||||
|
padding-bottom: 50vh;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user