Skip to content

Commit

Permalink
feat(events): events extension export element. #633
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Feb 22, 2024
1 parent 923c164 commit 92c5c57
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 11 deletions.
42 changes: 36 additions & 6 deletions extensions/events/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,33 @@ npm install @uiw/codemirror-extensions-events --save

```js
import * as events from '@uiw/codemirror-extensions-events';
import { element } from '@uiw/codemirror-extensions-events';

const extension1 = events.scroll({
scroll: (evn) => {
console.log(evn.target.scrollTop);
/* ... */
},
});

const extension1 = events.dom({
click: (evn) => {
/* ... */
},
});

const extension2 = events.content({
focus: (evn) => {
console.log('focus');
/* ... */
},
blur: (evn) => {
console.log('blur');
/* ... */
},
});

const extension3 = element({
type: 'content',
props: {
inputMode: 'none',
},
});
```
Expand All @@ -38,7 +52,8 @@ const extension2 = events.content({

```jsx
import CodeMirror from '@uiw/react-codemirror';
import { events } from '@uiw/codemirror-extensions-events';
import * as events from '@uiw/codemirror-extensions-events';
import { element } from '@uiw/codemirror-extensions-events';

function App() {
const [scrollTop, setScrollTop] = useState(0);
Expand All @@ -58,15 +73,30 @@ function App() {
},
});

return <CodeMirror value="console.log('hello world!');" height="200px" extensions={[eventExt, eventExt2]} />;
return (
<CodeMirror
value="console.log('hello world!');"
height="200px"
extensions={[
element({
type: 'content',
props: {
inputMode: 'none',
},
}),
eventExt,
eventExt2,
]}
/>
);
}
export default App;
```

```js
import { EditorView } from '@codemirror/view';
import { EditorState } from '@codemirror/state';
import { events } from '@uiw/codemirror-extensions-events';
import * as events from '@uiw/codemirror-extensions-events';

const eventExt = events.content({
focus: (evn) => {
Expand Down
21 changes: 16 additions & 5 deletions extensions/events/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export type Events<K extends keyof HTMLElementEventMap> = Record<
(this: HTMLElement, event: HTMLElementEventMap[K]) => void
>;

interface DOMElementProps extends Partial<HTMLElement> {}
type Options<T extends keyof HTMLElementEventMap> = {
/**
* Bind events on different dom nodes.
Expand All @@ -13,10 +14,11 @@ type Options<T extends keyof HTMLElementEventMap> = {
*/
type?: 'scroll' | 'dom' | 'content';
events?: Events<T>;
props?: DOMElementProps;
};

function events<T extends keyof HTMLElementEventMap>(opts: Options<T>) {
const { type = 'scroll', events } = opts;
export function element<T extends keyof HTMLElementEventMap>(opts: Options<T>) {
const { type = 'scroll', events, props } = opts;
return ViewPlugin.fromClass(
class {
dom?: HTMLElement;
Expand All @@ -30,6 +32,15 @@ function events<T extends keyof HTMLElementEventMap>(opts: Options<T>) {
} else {
this.dom = view.scrollDOM;
}

// Apply props to the DOM element
if (this.dom && props) {
const keys = Object.keys(props) as (keyof typeof props)[];
keys.forEach((key) => {
(this.dom as any)[key] = props[key];
});
}

(Object.keys(events || {}) as Array<keyof typeof events>).forEach((keyname) => {
if (events && events[keyname] && this.dom) {
this.dom.addEventListener(keyname, events[keyname]);
Expand All @@ -51,19 +62,19 @@ function events<T extends keyof HTMLElementEventMap>(opts: Options<T>) {
* (Note that it may not have been, so you can't assume this is scrollable.)
*/
export function dom<T extends keyof HTMLElementEventMap>(opts: Events<T>) {
return events({ type: 'dom', events: opts });
return element({ type: 'dom', events: opts });
}
/**
* The DOM element that wraps the entire editor view.
*/
export function scroll<T extends keyof HTMLElementEventMap>(opts: Events<T>) {
return events({ type: 'scroll', events: opts });
return element({ type: 'scroll', events: opts });
}
/**
* The editable DOM element holding the editor content.
* You should not, usually, interact with this content directly though the DOM,
* since the editor will immediately undo most of the changes you make.
*/
export function content<T extends keyof HTMLElementEventMap>(opts: Events<T>) {
return events({ type: 'content', events: opts });
return element({ type: 'content', events: opts });
}

0 comments on commit 92c5c57

Please sign in to comment.