Skip to content

Commit

Permalink
Refactor state into the editor
Browse files Browse the repository at this point in the history
  • Loading branch information
bkeepers committed Sep 13, 2022
1 parent b3fe28b commit 44c5bbe
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export declare interface PcEditor extends Components.PcEditor {}

@ProxyCmp({
defineCustomElementFn: undefined,
inputs: ['value'],
methods: ['setCapo']
inputs: ['value']
})
@Component({
selector: 'pc-editor',
Expand Down Expand Up @@ -90,12 +89,14 @@ export class PcEditorModeDropdown {
export declare interface PcEditorSplitView extends Components.PcEditorSplitView {}

@ProxyCmp({
defineCustomElementFn: undefined
defineCustomElementFn: undefined,
inputs: ['value']
})
@Component({
selector: 'pc-editor-split-view',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>'
template: '<ng-content></ng-content>',
inputs: ['value']
})
export class PcEditorSplitView {
protected el: HTMLElement;
Expand Down
3 changes: 2 additions & 1 deletion packages/studio/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
export namespace Components {
interface PcEditor {
"setCapo": (capoPosition: number) => Promise<void>;
"value": string;
}
interface PcEditorCapoDropdown {
Expand All @@ -17,6 +16,7 @@ export namespace Components {
interface PcEditorModeDropdown {
}
interface PcEditorSplitView {
"value": string;
}
interface PcRenderer {
"html": string;
Expand Down Expand Up @@ -80,6 +80,7 @@ declare namespace LocalJSX {
interface PcEditorModeDropdown {
}
interface PcEditorSplitView {
"value"?: string;
}
interface PcRenderer {
"html"?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,26 @@ export default {
// this creates a ‘Components’ folder and a ‘MyComponent’ subfolder
title: 'Components/Studio',
argTypes: {
label: { control: 'text' }, // always shows
advanced: { control: 'boolean' },
// below are only included when advanced is true
margin: { control: 'number', if: { arg: 'advanced' } },
padding: { control: 'number', if: { arg: 'advanced' } },
cornerRadius: { control: 'number', if: { arg: 'advanced' } },
value: { control: 'text' }, // always shows
},
// component: Studio
// component: Studio
};

const Template = (args) => `<pc-split-view></pc-split-view>`;
const Template = (args) => `<pc-editor-split-view value="${args.value}" />`;

export const Example = Template.bind({});
export const ChordPro = Template.bind({});
ChordPro.args = {
value: `{t:Kingdom}
{artist: Maverick City Music}
{capo: 2}
{key: F}
{c:Intro (2x)}
[Gm][F][/][/][|][C#dim7][Dm][/][/][|]
{c:Verse 1 *1}
My [Dm7]heart has always [C/E]longed for something[F] more
I [Dm7]searched the stars to [Bb]knock on Heaven's [F2]door
Cre - [Dm7]ation groans for [C2/E]God to be re [F2]- vealed
[Dm7]Every wound we [Bb]carry will be[F2] healed
My eyes on the [G7/B]Son, Lord Your will be [Bbm6]done`
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, Host, h } from '@stencil/core';
import { Component, Prop, Host, h } from '@stencil/core';
import Split from 'split.js'
import state from "../../stores/editor_store";

Expand All @@ -12,6 +12,8 @@ export class EditorSplitView {
private editor?: HTMLElement
private view?: HTMLElement

@Prop() value: string

componentDidLoad() {
// this.chordpro = this.html
Split([this.editor, this.view], {
Expand All @@ -29,7 +31,7 @@ export class EditorSplitView {
<pc-editor-capo-dropdown></pc-editor-capo-dropdown>
</div>
<div id="flex">
<pc-editor ref={el => this.editor = el as HTMLElement} value={state.input}></pc-editor>
<pc-editor ref={el => this.editor = el as HTMLElement} value={this.value}></pc-editor>
<pc-renderer ref={el => this.view = el as HTMLElement} html={state.html}></pc-renderer>
</div>
</Host>
Expand Down
7 changes: 7 additions & 0 deletions packages/studio/src/components/editor-split-view/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
<!-- Auto Generated Below -->


## Properties

| Property | Attribute | Description | Type | Default |
| -------- | --------- | ----------- | -------- | ----------- |
| `value` | `value` | | `string` | `undefined` |


## Dependencies

### Depends on
Expand Down
70 changes: 51 additions & 19 deletions packages/studio/src/components/editor/editor.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,70 @@
import { Component, h, Element, Host, Prop, State, Method } from '@stencil/core';
import { Component, h, Element, Host, Prop, Watch } from '@stencil/core';
import {EditorState} from "@codemirror/state"
import {EditorView} from "@codemirror/view"
import state from "../../stores/editor_store";
import {EditorView, highlightActiveLine, keymap, lineNumbers} from "@codemirror/view"
import {defaultKeymap, history} from "@codemirror/commands"
import {syntaxHighlighting} from "@codemirror/language"
import {ChordPro, exampleStringLinter} from "codemirror-lang-chordpro"
import {lintGutter} from "@codemirror/lint"
import { language, myHighlightStyle, myTheme, wordHover } from "../../utils/codemirror.utils";

@Component({
tag: 'pc-editor',
styleUrl: 'editor.scss',
shadow: true,
})
export class Editor {
private view: EditorView;

@Prop() value: string;

@State() capo: number;
@Prop({ mutable: true }) value: string = '';

@Element() host: HTMLElement;

@Method()
async setCapo(capoPosition: number) {
state.capo = capoPosition;
extensions() {
const updateListener = EditorView.updateListener.of((v) => {
if (v.docChanged) {
this.value = v.state.doc.toString()
}
});

return [
language.of(ChordPro()),
syntaxHighlighting(myHighlightStyle, {fallback: true}),
keymap.of(defaultKeymap),
lineNumbers(),
exampleStringLinter,
lintGutter(),
highlightActiveLine(),
history(),
updateListener,
myTheme,
wordHover
];
}

connectedCallback() {
if (!state.editorView) {
state.editorView = new EditorView({
state: EditorState.create({
doc: this.value,
extensions: state.editorExtensions
}),
parent: this.host.shadowRoot,
root: this.host.shadowRoot,
})
}
this.view = new EditorView({
state: EditorState.create({
doc: this.value,
extensions: this.extensions()
}),
parent: this.host.shadowRoot,
root: this.host.shadowRoot,
})
}

// Update text editor content when value changes
@Watch('value')
setValue(newValue: string) {
if (this.currentValue !== newValue) {
this.view.dispatch({
changes: { from: 0, to: this.view.state.doc.length, insert: newValue }
});
}
}

get currentValue() {
return this.view.state.doc.toString()
}

render() {
return (
Expand Down
13 changes: 0 additions & 13 deletions packages/studio/src/components/editor/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,6 @@
| `value` | `value` | | `string` | `undefined` |


## Methods

### `setCapo(capoPosition: number) => Promise<void>`



#### Returns

Type: `Promise<void>`




## Dependencies

### Used by
Expand Down
48 changes: 5 additions & 43 deletions packages/studio/src/stores/editor_store.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { createStore } from "@stencil/store";
import { ChordProFormatter, HtmlDivFormatter, HtmlTableFormatter, Song, ChordProParser, ChordSheetParser, TextFormatter } from '@praisecharts/chordsheetjs';
import {EditorView, highlightActiveLine, keymap, lineNumbers} from "@codemirror/view"
import {defaultKeymap, history} from "@codemirror/commands"
import {syntaxHighlighting} from "@codemirror/language"
import {ChordPro, exampleStringLinter} from "codemirror-lang-chordpro"
import {lintGutter} from "@codemirror/lint"
import { formatSong, getAvaliableCaposFromKey, getKeys, parseInput } from "../utils/chordsheetjs.helpers";
import { language, myHighlightStyle, myTheme, wordHover } from "../utils/codemirror.utils";

interface IStore {
capo: number;
capos: any[]
Expand All @@ -17,7 +12,6 @@ interface IStore {
editorExtensions: any[];
editorMode: "chordpro" | "chords_over_words";
editorModes: any;
editorView: EditorView;
formatter: ChordProFormatter | HtmlDivFormatter | HtmlTableFormatter | TextFormatter;
html: string;
input: string;
Expand All @@ -32,12 +26,6 @@ interface IStore {
songMap: boolean;
}

const updateListener = EditorView.updateListener.of((v) => {
if (v.docChanged) {
state.input = v.state.doc.toString();
}
});

const { state, onChange } = createStore<IStore>({
...initialState()
});
Expand All @@ -46,7 +34,7 @@ onChange('input', value => {
state.song = parseInput(value, state.parser, state.metadata);
state.html = formatSong(state.song, state.formatter);

if (state.song.key !== state.currentKey.name) {
if (state.song.key !== state.currentKey?.name) {
state.currentKey = { name: state.song.key };
// take majorKeys from teh keys config and map each key to an array of objects where there is a name and a value
state.keys = getKeys(true);
Expand All @@ -57,22 +45,14 @@ onChange('input', value => {
onChange('capo', value => {
const formatter = new ChordProFormatter();
state.song = state.song.setCapo(value);
let input = formatter.format(state.song);
let docLength = state.editorView.state.doc.length;
let transaction = state.editorView.state.update({changes: {from: 0, to: docLength, insert: input}});
state.editorView.dispatch(transaction);
state.input = input;
state.input = formatter.format(state.song);
});

onChange('currentKey', value => {
const formatter = new ChordProFormatter();
state.song = state.song.changeKey(value);
state.capos = getAvaliableCaposFromKey(value);
let input = formatter.format(state.song);
let docLength = state.editorView.state.doc.length;
let transaction = state.editorView.state.update({changes: {from: 0, to: docLength, insert: input}});
state.editorView.dispatch(transaction);
state.input = input;
state.input = formatter.format(state.song);
});

onChange('editorMode', value => {
Expand All @@ -85,11 +65,7 @@ onChange('editorMode', value => {
formatter = new ChordProFormatter();
state.parser = new ChordProParser();
}
let input = formatter.format(state.song);
let docLength = state.editorView.state.doc.length;
let transaction = state.editorView.state.update({changes: {from: 0, to: docLength, insert: input}});
state.editorView.dispatch(transaction);
state.input = input;
state.input = formatter.format(state.song);
});

function initialState() {
Expand Down Expand Up @@ -117,20 +93,6 @@ function initialState() {
formatter: new HtmlDivFormatter(),
rendererMode: "pdf",
rendererZoom: "100%",
editorView: null,
editorExtensions: [
language.of(ChordPro()),
syntaxHighlighting(myHighlightStyle, {fallback: true}),
keymap.of(defaultKeymap),
lineNumbers(),
exampleStringLinter,
lintGutter(),
highlightActiveLine(),
history(),
updateListener,
myTheme,
wordHover
],
};
}

Expand Down

0 comments on commit 44c5bbe

Please sign in to comment.