Files
dees-catalog/ts_web/elements/dees-dataview-codebox.ts

262 lines
7.1 KiB
TypeScript
Raw Normal View History

2023-09-20 18:57:54 +02:00
import { demoFunc } from './dees-dataview-codebox.demo.js';
2023-04-05 14:46:20 +02:00
import {
DeesElement,
html,
customElement,
2023-08-07 20:02:18 +02:00
type TemplateResult,
2023-04-05 14:46:20 +02:00
property,
state,
2023-09-20 18:57:54 +02:00
cssManager,
2023-08-07 19:13:29 +02:00
} from '@design.estate/dees-element';
2025-06-27 17:32:01 +00:00
import { cssGeistFontFamily, cssMonoFontFamily } from './00fonts.js';
2023-04-05 14:46:20 +02:00
import hlight from 'highlight.js';
2023-08-07 19:13:29 +02:00
import * as smartstring from '@push.rocks/smartstring';
2023-04-05 14:46:20 +02:00
2023-08-07 19:13:29 +02:00
import * as domtools from '@design.estate/dees-domtools';
2023-09-20 18:57:54 +02:00
import { DeesContextmenu } from './dees-contextmenu.js';
2023-04-05 14:46:20 +02:00
declare global {
interface HTMLElementTagNameMap {
'dees-dataview-codebox': DeesDataviewCodebox;
}
}
@customElement('dees-dataview-codebox')
export class DeesDataviewCodebox extends DeesElement {
2023-09-07 18:34:38 +02:00
public static demo = demoFunc;
2023-04-05 14:46:20 +02:00
@property()
public progLang: string = 'typescript';
@property({
2023-04-06 17:29:07 +02:00
type: String,
reflect: true,
2023-04-05 14:46:20 +02:00
})
2023-04-06 17:29:07 +02:00
public codeToDisplay: string = '';
2023-04-05 14:46:20 +02:00
constructor() {
super();
}
render(): TemplateResult {
return html`
${domtools.elementBasic.styles}
<style>
:host {
position: relative;
display: block;
text-align: left;
font-size: 16px;
2025-06-27 17:32:01 +00:00
font-family: ${cssGeistFontFamily};
2023-04-05 14:46:20 +02:00
}
.mainbox {
position: relative;
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
background: ${cssManager.bdTheme('#ffffff', '#09090b')};
border-radius: 6px;
2023-09-07 18:34:38 +02:00
overflow: hidden;
}
.appbar {
2023-12-20 19:09:55 +01:00
position: relative;
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
background: ${cssManager.bdTheme('#f9fafb', '#18181b')};
border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
height: 32px;
2023-12-20 19:09:55 +01:00
display: flex;
2025-06-27 21:05:28 +00:00
font-size: 13px;
line-height: 32px;
2023-12-20 19:09:55 +01:00
justify-content: center;
align-items: center;
2023-09-07 18:34:38 +02:00
}
.appbar .fileName {
2023-12-20 19:09:55 +01:00
line-height: inherit;
position: relative;
flex: 1;
2023-09-07 18:34:38 +02:00
text-align: center;
}
.bottomBar {
2025-06-27 21:07:47 +00:00
position: relative;
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
background: ${cssManager.bdTheme('#f9fafb', '#18181b')};
border-top: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
height: 28px;
2023-09-07 18:34:38 +02:00
font-size: 12px;
2025-06-27 21:05:28 +00:00
line-height: 28px;
2025-06-27 21:07:47 +00:00
display: flex;
justify-content: flex-end;
align-items: stretch;
overflow: hidden;
}
.spacesLabel {
padding: 0 16px;
display: flex;
align-items: center;
2023-04-05 14:46:20 +02:00
}
.languageLabel {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
2023-04-05 14:46:20 +02:00
font-size: 12px;
2025-06-27 21:05:28 +00:00
line-height: 28px;
background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.1)')};
2025-06-27 21:07:47 +00:00
padding: 0px 16px;
2025-06-27 21:05:28 +00:00
font-weight: 500;
2025-06-27 21:07:47 +00:00
display: flex;
align-items: center;
2023-04-05 14:46:20 +02:00
}
.hljs-keyword {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#dc2626', '#f87171')};
2023-04-05 14:46:20 +02:00
}
.codegrid {
display: grid;
grid-template-columns: 50px auto;
overflow: hidden;
}
.lineNumbers {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#71717a', '#52525b')};
padding: 24px 16px 0px 0px;
2023-04-05 14:46:20 +02:00
text-align: right;
2025-06-27 21:05:28 +00:00
border-right: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
2023-04-05 14:46:20 +02:00
}
.lineCounter:last-child {
opacity: 50%;
}
pre {
overflow-x: auto;
margin: 0px;
2025-06-27 21:05:28 +00:00
padding: 24px 24px;
2023-04-05 14:46:20 +02:00
}
code {
2025-06-27 21:05:28 +00:00
font-weight: 400;
2023-04-05 14:46:20 +02:00
padding: 0px;
margin: 0px;
}
code,
code *,
.lineNumbers {
line-height: 1.4em;
font-weight: 200;
2025-06-27 17:32:01 +00:00
font-family: ${cssMonoFontFamily};
2023-04-05 14:46:20 +02:00
}
.hljs-string {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#059669', '#10b981')};
2023-04-05 14:46:20 +02:00
}
.hljs-built_in {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#8b5cf6', '#a78bfa')};
2023-04-05 14:46:20 +02:00
}
.hljs-function {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
2023-04-05 14:46:20 +02:00
}
.hljs-params {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#0891b2', '#06b6d4')};
2023-04-05 14:46:20 +02:00
}
.hljs-comment {
2025-06-27 21:05:28 +00:00
color: ${cssManager.bdTheme('#71717a', '#71717a')};
}
.hljs-number {
color: ${cssManager.bdTheme('#ea580c', '#fb923c')};
}
.hljs-literal {
color: ${cssManager.bdTheme('#dc2626', '#f87171')};
}
.hljs-attr {
color: ${cssManager.bdTheme('#8b5cf6', '#a78bfa')};
}
.hljs-variable {
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
2023-04-05 14:46:20 +02:00
}
</style>
2023-09-20 18:57:54 +02:00
<div
class="mainbox"
@contextmenu="${(eventArg) => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [
{
name: 'About',
iconName: 'circleInfo',
action: async () => {
return null;
},
},
]);
}}"
>
2023-09-07 18:34:38 +02:00
<div class="appbar">
2023-12-20 19:09:55 +01:00
<dees-windowcontrols type="mac" position="left"></dees-windowcontrols>
2023-09-07 18:34:38 +02:00
<div class="fileName">index.ts</div>
2023-12-20 19:09:55 +01:00
<dees-windowcontrols type="mac" position="right"></dees-windowcontrols>
2023-09-07 18:34:38 +02:00
</div>
2023-04-05 14:46:20 +02:00
<div class="codegrid">
<div class="lineNumbers">
${(() => {
let lineCounter = 0;
2023-09-07 18:34:38 +02:00
return this.codeToDisplay.split('\n').map((lineArg) => {
2023-04-05 14:46:20 +02:00
lineCounter++;
return html`<div class="lineCounter">${lineCounter}</div>`;
2023-09-07 18:34:38 +02:00
});
2023-04-05 14:46:20 +02:00
})()}
</div>
2023-04-06 17:29:07 +02:00
<pre><code></code></pre>
2023-04-05 14:46:20 +02:00
</div>
2023-09-07 18:34:38 +02:00
<div class="bottomBar">
2025-06-27 21:07:47 +00:00
<div class="spacesLabel">Spaces: 2</div>
2023-09-07 18:34:38 +02:00
<div class="languageLabel">${this.progLang}</div>
</div>
2023-04-05 14:46:20 +02:00
</div>
`;
}
2023-04-06 17:29:07 +02:00
@state()
private codeToDisplayStore = '';
2023-04-05 14:46:20 +02:00
public async updated(_changedProperties) {
super.updated(_changedProperties);
console.log('highlighting now');
console.log(this.childNodes);
const slottedCodeNodes: Text[] = [];
this.childNodes.forEach((childNode) => {
if (childNode.nodeName === '#text') {
slottedCodeNodes.push(childNode as Text);
}
});
2023-04-06 17:29:07 +02:00
if (this.codeToDisplay && this.codeToDisplay !== this.codeToDisplayStore) {
2023-04-10 00:17:38 +02:00
this.codeToDisplayStore = smartstring.indent.normalize(this.codeToDisplay).trimStart();
2023-04-06 17:29:07 +02:00
}
if (slottedCodeNodes[0] && slottedCodeNodes[0].wholeText && !this.codeToDisplay) {
2023-09-07 18:34:38 +02:00
this.codeToDisplayStore = smartstring.indent
.normalize(slottedCodeNodes[0].wholeText)
.trimStart();
2023-04-06 17:29:07 +02:00
this.codeToDisplay = this.codeToDisplayStore;
2023-04-05 14:46:20 +02:00
}
await domtools.plugins.smartdelay.delayFor(0);
const localCodeNode = this.shadowRoot.querySelector('code');
2023-09-07 18:34:38 +02:00
const html = hlight.highlight(this.codeToDisplayStore, {
language: this.progLang,
ignoreIllegals: true,
});
2023-04-06 17:29:07 +02:00
localCodeNode.innerHTML = html.value;
2023-04-05 14:46:20 +02:00
}
}