Skip to content

Commit

Permalink
working on editor events
Browse files Browse the repository at this point in the history
  • Loading branch information
KonnorRogers committed Oct 30, 2023
1 parent f6e21e9 commit 1a719f2
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 169 deletions.
4 changes: 2 additions & 2 deletions docs/Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ end
namespace :frontend do
desc "Build the frontend with esbuild for deployment"
task :build do
sh "yarn run esbuild"
sh "pnpm run esbuild"
end

desc "Watch the frontend with esbuild during development"
task :dev do
sh "yarn run esbuild-dev"
sh "pnpm run esbuild-dev"
rescue Interrupt
end
end
Expand Down
2 changes: 1 addition & 1 deletion docs/frontend/styles/components/_syntax_block.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
:is(.language-bash, .language-shell, .language-zsh, .language-sh).highlighter-rouge pre.highlight::before {
content: "$";
user-select: none;
vertical-align: -2px;
/* vertical-align: -2px; */
padding-inline-end: 0.45em;
color: gray;
}
2 changes: 1 addition & 1 deletion docs/frontend/styles/components/_tables.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ th {

th,
td {
text-align: start;
text-align: center;
padding: 1rem;
}

Expand Down
1 change: 1 addition & 0 deletions docs/plugins/builders/component_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def events_table(events)
#{event.name}
</td>
<td>
#{event.description}
</td>
</tr>
HTML
Expand Down
2 changes: 1 addition & 1 deletion docs/src/_layouts/home.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ layout: default
<ul class="call-to-action__items" style="list-style: none;">
<% resource.data.call_to_action_items.each do |item| %>
<li>
<sl-button variant="<%= item[:type] %>" href="<%= item[:href] %>" class="call-to-action" pill>
<sl-button variant="<%= item[:type] %>" href="<%= site.base_path + "/" + item[:href] %>" class="call-to-action" pill>
<%= item[:text].to_s.html_safe %>
</sl-button>
</li>
Expand Down
12 changes: 12 additions & 0 deletions exports/events/light-resize-event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @ts-check
import { BaseEvent } from "../../internal/base-event.js"

export class LightResizeEvent extends BaseEvent {
/**
* @param {Partial<EventInit & { height: number, width: number }>} [options={}]
*/
constructor (options = {}, name = "light-resize") {
super(name, options)
}
}

62 changes: 48 additions & 14 deletions exports/light-editor.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { html } from "lit";
import { BaseElement } from "../internal/base-element.js";
import { baseStyles } from "./base-styles.js";
import { styles } from "./light-editor.styles.js";
import { theme } from "./default-theme.styles.js";
import { live } from "lit/directives/live.js";

import HighlightJS from 'highlight.js/lib/core';
import JavaScript from 'highlight.js/lib/languages/javascript';
import HTML from 'highlight.js/lib/languages/xml';
import CSS from 'highlight.js/lib/languages/css';
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { dedent } from "../internal/dedent.js";
import { createRef, ref } from "lit/directives/ref.js";
import { ref } from "lit/directives/ref.js";

import { BaseElement } from "../internal/base-element.js";
import { baseStyles } from "./base-styles.js";
import { styles } from "./light-editor.styles.js";
import { theme } from "./default-theme.styles.js";
import { LightResizeEvent } from "./events/light-resize-event.js"

HighlightJS.registerLanguage('javascript', JavaScript);
HighlightJS.registerLanguage('xml', HTML);
Expand All @@ -22,6 +21,10 @@ HighlightJS.registerLanguage('css', CSS);
* @customElement
* @tagname light-editor
*
* @event {Event} light-change - Re-emits the textarea's "change" event
* @event {Event} light-selectionchange - Re-emits the textarea's "selectionchange" event
* @event {Event} light-input - Re-emits the textarea's "input" event
*
*/
export default class LightEditor extends BaseElement {
static baseName = "light-editor"
Expand Down Expand Up @@ -60,14 +63,35 @@ export default class LightEditor extends BaseElement {
this.textarea = null
}

/**
* @param {ResizeObserverEntry[]} entries
*/
handleTextAreaResize (entries) {
const { target } = entries[0]
const {
left, right,
top, bottom
} = entries[0].contentRect;
const width = left + right
const height = top + bottom

// @ts-expect-error
target.parentElement.style.setProperty("--textarea-height", `${height}px`)


/** @internal */
this.dispatchEvent(new LightResizeEvent({height, width}))
// One day we'll allow the textarea to resize the width.
// target.parentElement.style.setProperty("--textarea-width", `${width}px`)
}

render () {
const language = this.language

const highlightedCode = this.value ? unsafeHTML(this.highlightCode({ code: this.value, language })) : ""

return html`
<div class="editor" part="editor">
<div class="base" part="base">
<!-- This is where the fancy syntax highlighting comes in -->
<pre
id="pre-${language}"
Expand All @@ -81,13 +105,13 @@ export default class LightEditor extends BaseElement {
<!-- IMPORTANT! There must be no white-space above. -->
<textarea
id="textarea-${language}"
${ref(this.textareaChanged)}
data-code-lang=${language}
part="textarea textarea-${language}"
spellcheck="false"
autocorrect="off"
autocapitalize="off"
translate="no"
${ref(this.textareaChanged)}
@keydown=${this.keydownHandler}
@selectionchange=${/** @param {Event} e */ (e) => {
this.dispatchEvent(new Event("light-selectionchange", { bubbles: true, composed: true }))
Expand All @@ -102,7 +126,7 @@ export default class LightEditor extends BaseElement {
this.dispatchEvent(new Event("light-change", { bubbles: true, composed: true }))
}}
@scroll=${this.syncScroll}
value=${this.value}
.value=${this.value}
>${this.value}</textarea>
</div>
`
Expand All @@ -117,15 +141,19 @@ export default class LightEditor extends BaseElement {
}

const textarea = element
const self = this

this.textareaObserver = new MutationObserver((mutationRecords) => {
this.textareaResizeObserver = new ResizeObserver((entries) => this.handleTextAreaResize(entries))

this.textareaResizeObserver.observe(textarea)

this.textareaMutationObserver = new MutationObserver((mutationRecords) => {
// We actually don't care about what the mutation is, just update and move on.
// for (const mutation of mutationRecords) {
// }
this.value = textarea.value
})

this.textareaObserver.observe(textarea, {
this.textareaMutationObserver.observe(textarea, {
characterData: true,
subtree: true
})
Expand Down Expand Up @@ -162,6 +190,12 @@ export default class LightEditor extends BaseElement {
pre.scrollLeft = textarea.scrollLeft;
}

disconnectedCallback () {
this.textareaResizeObserver?.disconnect()
this.textareaMutationObserver?.disconnect()
super.disconnectedCallback()
}

/**
* @param {KeyboardEvent} evt
*/
Expand Down
14 changes: 13 additions & 1 deletion exports/light-editor.styles.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { css } from "lit"

export const styles = css`
[part~="editor"] {
[part~="base"] {
display:grid;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, 1fr);
Expand Down Expand Up @@ -50,10 +50,22 @@ export const styles = css`
background-color: #f7f7f7;
}
[part~="pre"] {
height: var(--textarea-height, auto);
max-height: var(--textarea-height, auto);
width: var(--textarea-width, auto);
max-width: var(--textarea-width, auto);
}
[part~="pre"],
[part~="code"],
[part~="textarea"] {
font-family: Menlo, Monaco, "Courier New", monospace;
font-size: 0.875rem;
}
[part~="textarea"]::selection {
color: inherit;
background-color: rgba(0,0,0,0.15);
}
`
Loading

0 comments on commit 1a719f2

Please sign in to comment.