fix(ts_web): resolve TypeScript nullability and event typing issues across web components

This commit is contained in:
2026-04-01 05:00:21 +00:00
parent b1c8a7446e
commit af1f660486
78 changed files with 429 additions and 399 deletions

View File

@@ -1,5 +1,13 @@
# Changelog # Changelog
## 2026-04-01 - 3.49.1 - fix(ts_web)
resolve TypeScript nullability and event typing issues across web components
- adds explicit non-null assertions and nullable types to component properties, shadowRoot queries, and modal references
- normalizes demo and component event listeners by casting generic Event objects to CustomEvent where needed
- guards optional form, dropdown, menu, and DOM interactions to prevent invalid access under stricter TypeScript checks
- updates tsconfig to include Node types for the web build environment
## 2026-03-18 - 3.49.0 - feat(dataview-statusobject) ## 2026-03-18 - 3.49.0 - feat(dataview-statusobject)
add last updated footer to status object and refresh demo data add last updated footer to status object and refresh demo data

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-catalog', name: '@design.estate/dees-catalog',
version: '3.49.0', version: '3.49.1',
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
} }

View File

@@ -122,7 +122,7 @@ export class DeesAppuiBar extends DeesElement {
> >
${menuItem.iconName ? html`<dees-icon .icon="${`lucide:${menuItem.iconName}`}"></dees-icon>` : ''} ${menuItem.iconName ? html`<dees-icon .icon="${`lucide:${menuItem.iconName}`}"></dees-icon>` : ''}
${menuItem.name} ${menuItem.name}
${hasSubmenu ? this.renderDropdown(menuItem.submenu, itemId, isActive) : ''} ${hasSubmenu ? this.renderDropdown(menuItem.submenu!, itemId, isActive) : ''}
</div> </div>
`; `;
} }

View File

@@ -75,21 +75,21 @@ export const demoFunc = () => {
// Set up status toggle // Set up status toggle
const statusButtons = elementArg.querySelectorAll('.status-toggle dees-button'); const statusButtons = elementArg.querySelectorAll('.status-toggle dees-button');
statusButtons[0].addEventListener('click', () => { statusButtons[0].addEventListener('click', () => {
appbar.user = { ...appbar.user, status: 'online' }; appbar.user = { ...appbar.user!, status: 'online' };
}); });
statusButtons[1].addEventListener('click', () => { statusButtons[1].addEventListener('click', () => {
appbar.user = { ...appbar.user, status: 'busy' }; appbar.user = { ...appbar.user!, status: 'busy' };
}); });
statusButtons[2].addEventListener('click', () => { statusButtons[2].addEventListener('click', () => {
appbar.user = { ...appbar.user, status: 'away' }; appbar.user = { ...appbar.user!, status: 'away' };
}); });
statusButtons[3].addEventListener('click', () => { statusButtons[3].addEventListener('click', () => {
appbar.user = { ...appbar.user, status: 'offline' }; appbar.user = { ...appbar.user!, status: 'offline' };
}); });
// Set up window controls toggle // Set up window controls toggle
const windowControlsButton = elementArg.querySelector('.window-controls-toggle dees-button'); const windowControlsButton = elementArg.querySelector('.window-controls-toggle dees-button');
windowControlsButton.addEventListener('click', () => { windowControlsButton!.addEventListener('click', () => {
appbar.showWindowControls = !appbar.showWindowControls; appbar.showWindowControls = !appbar.showWindowControls;
}); });

View File

@@ -165,7 +165,7 @@ export class DeesAppuiMaincontent extends DeesElement {
} }
// Tab selection is now handled by the dees-appui-tabs component // Tab selection is now handled by the dees-appui-tabs component
// But we need to ensure the tabs component is ready // But we need to ensure the tabs component is ready
const tabsComponent = this.shadowRoot.querySelector('dees-appui-tabs') as DeesAppuiTabs; const tabsComponent = this.shadowRoot!.querySelector('dees-appui-tabs') as DeesAppuiTabs;
if (tabsComponent) { if (tabsComponent) {
await tabsComponent.updateComplete; await tabsComponent.updateComplete;
} }

View File

@@ -46,7 +46,7 @@ export class DeesAppuiMainmenu extends DeesElement {
accessor tabs: interfaces.IMenuItem[] = []; accessor tabs: interfaces.IMenuItem[] = [];
@property() @property()
accessor selectedTab: interfaces.IMenuItem; accessor selectedTab!: interfaces.IMenuItem;
@property({ type: Boolean, reflect: true }) @property({ type: Boolean, reflect: true })
accessor collapsed: boolean = false; accessor collapsed: boolean = false;

View File

@@ -663,21 +663,21 @@ export class DeesAppuiTabs extends DeesElement {
} }
private shouldShowIndicator(): boolean { private shouldShowIndicator(): boolean {
return this.selectedTab && this.showTabIndicator && this.tabs.includes(this.selectedTab); return !!this.selectedTab && this.showTabIndicator && this.tabs.includes(this.selectedTab);
} }
private getSelectedTabElement(): HTMLElement | null { private getSelectedTabElement(): HTMLElement | null {
const selectedIndex = this.tabs.indexOf(this.selectedTab); const selectedIndex = this.tabs.indexOf(this.selectedTab!);
const isHorizontal = this.tabStyle === 'horizontal'; const isHorizontal = this.tabStyle === 'horizontal';
const selector = isHorizontal const selector = isHorizontal
? `.tabs-wrapper .tabsContainer .tab:nth-child(${selectedIndex + 1})` ? `.tabs-wrapper .tabsContainer .tab:nth-child(${selectedIndex + 1})`
: `.vertical-wrapper .tabsContainer .tab:nth-child(${selectedIndex + 1})`; : `.vertical-wrapper .tabsContainer .tab:nth-child(${selectedIndex + 1})`;
return this.shadowRoot.querySelector(selector); return this.shadowRoot!.querySelector(selector);
} }
private getIndicatorElement(): HTMLElement | null { private getIndicatorElement(): HTMLElement | null {
return this.shadowRoot.querySelector('.tabIndicator'); return this.shadowRoot!.querySelector('.tabIndicator');
} }
private handleInitialTransition(indicator: HTMLElement): void { private handleInitialTransition(indicator: HTMLElement): void {
@@ -695,7 +695,7 @@ export class DeesAppuiTabs extends DeesElement {
const tabContent = tabElement.querySelector('.tab-content') as HTMLElement; const tabContent = tabElement.querySelector('.tab-content') as HTMLElement;
if (!tabContent) return; if (!tabContent) return;
const wrapperRect = indicator.parentElement.getBoundingClientRect(); const wrapperRect = indicator.parentElement!.getBoundingClientRect();
const contentRect = tabContent.getBoundingClientRect(); const contentRect = tabContent.getBoundingClientRect();
const contentLeft = contentRect.left - wrapperRect.left; const contentLeft = contentRect.left - wrapperRect.left;
@@ -707,7 +707,7 @@ export class DeesAppuiTabs extends DeesElement {
} }
private updateVerticalIndicator(indicator: HTMLElement, tabElement: HTMLElement): void { private updateVerticalIndicator(indicator: HTMLElement, tabElement: HTMLElement): void {
const tabsContainer = this.shadowRoot.querySelector('.vertical-wrapper .tabsContainer') as HTMLElement; const tabsContainer = this.shadowRoot!.querySelector('.vertical-wrapper .tabsContainer') as HTMLElement;
if (!tabsContainer) return; if (!tabsContainer) return;
indicator.style.top = `${tabElement.offsetTop + tabsContainer.offsetTop}px`; indicator.style.top = `${tabElement.offsetTop + tabsContainer.offsetTop}px`;

View File

@@ -12,7 +12,7 @@ class DemoDashboardView extends DeesElement {
@state() @state()
accessor activated: boolean = false; accessor activated: boolean = false;
private ctx: IViewActivationContext; private ctx!: IViewActivationContext;
private statsTiles: IStatsTile[] = [ private statsTiles: IStatsTile[] = [
{ {
@@ -267,7 +267,7 @@ class DemoSettingsView extends DeesElement {
@state() @state()
accessor hasChanges: boolean = false; accessor hasChanges: boolean = false;
private appui: DeesAppui; private appui!: DeesAppui;
onActivate(context: IViewActivationContext) { onActivate(context: IViewActivationContext) {
this.appui = context.appui as any; this.appui = context.appui as any;

View File

@@ -1037,7 +1037,7 @@ export class DeesAppui extends DeesElement {
if (!config.mainMenu?.sections) return []; if (!config.mainMenu?.sections) return [];
return config.mainMenu.sections.map((section) => ({ return config.mainMenu.sections.map((section) => ({
name: section.name, name: section.name || '',
items: section.views items: section.views
.map((viewId) => { .map((viewId) => {
const view = this.viewRegistry.get(viewId); const view = this.viewRegistry.get(viewId);

View File

@@ -173,7 +173,7 @@ export class ViewRegistry {
} }
// Check for cached instance // Check for cached instance
let element = shouldCache ? this.instances.get(viewId) : undefined; let element: HTMLElement | null | undefined = shouldCache ? this.instances.get(viewId) : undefined;
if (element) { if (element) {
// Reuse cached instance - just show it // Reuse cached instance - just show it

View File

@@ -1,5 +1,5 @@
import { html, css } from '@design.estate/dees-element'; import { html, css } from '@design.estate/dees-element';
import '../00group-button/dees-button/dees-button.js'; import '../../00group-button/dees-button/dees-button.js';
import '../../00group-layout/dees-panel/dees-panel.js'; import '../../00group-layout/dees-panel/dees-panel.js';
import '@design.estate/dees-wcctools/demotools'; import '@design.estate/dees-wcctools/demotools';

View File

@@ -301,14 +301,14 @@ export class DeesMobilenavigation extends DeesElement {
`; `;
} }
private windowLayer: DeesWindowLayer; private windowLayer!: DeesWindowLayer;
/** /**
* inits the show * inits the show
*/ */
public async show() { public async show() {
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
const main = this.shadowRoot.querySelector('.main'); const main = this.shadowRoot!.querySelector('.main');
// Create window layer first (it will get its own z-index) // Create window layer first (it will get its own z-index)
if (!this.windowLayer) { if (!this.windowLayer) {
@@ -328,7 +328,7 @@ export class DeesMobilenavigation extends DeesElement {
zIndexRegistry.register(this, this.mobileNavZIndex); zIndexRegistry.register(this, this.mobileNavZIndex);
await domtools.convenience.smartdelay.delayFor(10); await domtools.convenience.smartdelay.delayFor(10);
main.classList.add('show'); main!.classList.add('show');
} }
/** /**
@@ -336,8 +336,8 @@ export class DeesMobilenavigation extends DeesElement {
*/ */
public async hide() { public async hide() {
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
const main = this.shadowRoot.querySelector('.main'); const main = this.shadowRoot!.querySelector('.main');
main.classList.remove('show'); main!.classList.remove('show');
// Unregister from z-index registry // Unregister from z-index registry
zIndexRegistry.unregister(this); zIndexRegistry.unregister(this);

View File

@@ -288,8 +288,8 @@ export const demoFunc = () => html`
} }
if (dataBtn && output) { if (dataBtn && output) {
dataBtn.addEventListener('clicked', (e: CustomEvent) => { dataBtn.addEventListener('clicked', (e: Event) => {
output.textContent = `Clicked: Secondary button with data: ${e.detail.data}`; output.textContent = `Clicked: Secondary button with data: ${(e as CustomEvent).detail.data}`;
}); });
} }
@@ -322,9 +322,9 @@ export const demoFunc = () => html`
const output = elementArg.querySelector('#form-output'); const output = elementArg.querySelector('#form-output');
if (form && output) { if (form && output) {
form.addEventListener('formData', (e: CustomEvent) => { form.addEventListener('formData', (e: Event) => {
output.innerHTML = '<strong>Form submitted with data:</strong><br>' + output.innerHTML = '<strong>Form submitted with data:</strong><br>' +
JSON.stringify(e.detail.data, null, 2); JSON.stringify((e as CustomEvent).detail.data, null, 2);
}); });
} }

View File

@@ -31,10 +31,10 @@ export class DeesButton extends DeesElement {
return true; return true;
} }
}) })
accessor text: string; accessor text!: string;
@property() @property()
accessor eventDetailData: string; accessor eventDetailData!: string;
@property({ @property({
type: Boolean, type: Boolean,
@@ -69,7 +69,7 @@ export class DeesButton extends DeesElement {
accessor insideForm: boolean = false; accessor insideForm: boolean = false;
@property({ type: String, reflect: true }) @property({ type: String, reflect: true })
accessor icon: string; accessor icon!: string;
@property({ type: String, reflect: true }) @property({ type: String, reflect: true })
accessor iconPosition: 'left' | 'right' = 'left'; accessor iconPosition: 'left' | 'right' = 'left';

View File

@@ -37,7 +37,7 @@ export class DeesChartArea extends DeesElement {
// instance // instance
@state() @state()
accessor chart: ApexCharts; accessor chart!: ApexCharts;
@property() @property()
accessor label: string = 'Untitled Chart'; accessor label: string = 'Untitled Chart';
@@ -68,8 +68,8 @@ export class DeesChartArea extends DeesElement {
@property({ type: Number }) @property({ type: Number })
accessor autoScrollInterval: number = 1000; // Auto-scroll interval in milliseconds (0 to disable) accessor autoScrollInterval: number = 1000; // Auto-scroll interval in milliseconds (0 to disable)
private resizeObserver: ResizeObserver; private resizeObserver!: ResizeObserver;
private resizeTimeout: number; private resizeTimeout!: number;
private internalChartData: ApexAxisChartSeries = []; private internalChartData: ApexAxisChartSeries = [];
private autoScrollTimer: number | null = null; private autoScrollTimer: number | null = null;
private readonly DEBUG_RESIZE = false; // Set to true to enable resize debugging private readonly DEBUG_RESIZE = false; // Set to true to enable resize debugging
@@ -132,7 +132,7 @@ export class DeesChartArea extends DeesElement {
if (this.chart) { if (this.chart) {
try { try {
this.chart.destroy(); this.chart.destroy();
this.chart = null; this.chart = null as any;
} catch (error) { } catch (error) {
console.error('Error destroying chart:', error); console.error('Error destroying chart:', error);
} }
@@ -170,8 +170,8 @@ export class DeesChartArea extends DeesElement {
await new Promise(resolve => requestAnimationFrame(resolve)); await new Promise(resolve => requestAnimationFrame(resolve));
// Get actual dimensions of the container // Get actual dimensions of the container
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox'); const mainbox: HTMLDivElement | null = this.shadowRoot!.querySelector('.mainbox');
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer'); const chartContainer: HTMLDivElement | null = this.shadowRoot!.querySelector('.chartContainer');
if (!mainbox || !chartContainer) { if (!mainbox || !chartContainer) {
console.error('Chart containers not found'); console.error('Chart containers not found');
@@ -368,7 +368,7 @@ export class DeesChartArea extends DeesElement {
}; };
try { try {
this.chart = new ApexChartsLib(this.shadowRoot.querySelector('.chartContainer'), options); this.chart = new ApexChartsLib(this.shadowRoot!.querySelector('.chartContainer')!, options);
await this.chart.render(); await this.chart.render();
// Give the chart a moment to fully initialize before resizing // Give the chart a moment to fully initialize before resizing
@@ -376,7 +376,7 @@ export class DeesChartArea extends DeesElement {
await this.resizeChart(); await this.resizeChart();
// Ensure resize observer is watching the mainbox // Ensure resize observer is watching the mainbox
const mainbox = this.shadowRoot.querySelector('.mainbox'); const mainbox = this.shadowRoot!.querySelector('.mainbox');
if (mainbox && this.resizeObserver) { if (mainbox && this.resizeObserver) {
// Disconnect any previous observations // Disconnect any previous observations
this.resizeObserver.disconnect(); this.resizeObserver.disconnect();
@@ -572,8 +572,8 @@ export class DeesChartArea extends DeesElement {
} }
try { try {
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox'); const mainbox: HTMLDivElement | null = this.shadowRoot!.querySelector('.mainbox');
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer'); const chartContainer: HTMLDivElement | null = this.shadowRoot!.querySelector('.chartContainer');
if (!mainbox || !chartContainer) { if (!mainbox || !chartContainer) {
return; return;

View File

@@ -44,8 +44,8 @@ export const demoFunc = () => {
// Get the chart elements // Get the chart elements
const chartElement = elementArg.querySelector('#main-chart') as DeesChartArea; const chartElement = elementArg.querySelector('#main-chart') as DeesChartArea;
const connectionsChartElement = elementArg.querySelector('#connections-chart') as DeesChartArea; const connectionsChartElement = elementArg.querySelector('#connections-chart') as DeesChartArea;
let intervalId: number; let intervalId: number | null;
let connectionsIntervalId: number; let connectionsIntervalId: number | null;
let currentDataset = 'system'; let currentDataset = 'system';
// Y-axis formatters for different datasets // Y-axis formatters for different datasets
@@ -71,7 +71,7 @@ export const demoFunc = () => {
// Generate initial data points for time window // Generate initial data points for time window
const generateInitialData = (baseValue: number, variance: number, interval: number = DATA_POINT_INTERVAL) => { const generateInitialData = (baseValue: number, variance: number, interval: number = DATA_POINT_INTERVAL) => {
const data = []; const data: Array<{ x: string; y: number }> = [];
const now = Date.now(); const now = Date.now();
const pointCount = Math.floor(TIME_WINDOW / interval); const pointCount = Math.floor(TIME_WINDOW / interval);
@@ -240,10 +240,10 @@ export const demoFunc = () => {
// Switch dataset // Switch dataset
const switchDataset = (name: string) => { const switchDataset = (name: string) => {
currentDataset = name; currentDataset = name;
const dataset = datasets[name]; const dataset = (datasets as Record<string, any>)[name];
chartElement.label = dataset.label; chartElement.label = dataset.label;
chartElement.series = dataset.series; chartElement.series = dataset.series;
chartElement.yAxisFormatter = formatters[name]; chartElement.yAxisFormatter = (formatters as Record<string, any>)[name];
// Set appropriate y-axis scaling // Set appropriate y-axis scaling
if (name === 'system') { if (name === 'system') {

View File

@@ -8,8 +8,8 @@ export const demoFunc = () => {
// Get the log elements // Get the log elements
const structuredLog = elementArg.querySelector('#structured-log') as DeesChartLog; const structuredLog = elementArg.querySelector('#structured-log') as DeesChartLog;
const rawLog = elementArg.querySelector('#raw-log') as DeesChartLog; const rawLog = elementArg.querySelector('#raw-log') as DeesChartLog;
let structuredIntervalId: number; let structuredIntervalId: number | null;
let rawIntervalId: number; let rawIntervalId: number | null;
const serverSources = ['Server', 'Database', 'API', 'Auth', 'Cache', 'Queue', 'WebSocket', 'Scheduler']; const serverSources = ['Server', 'Database', 'API', 'Auth', 'Cache', 'Queue', 'WebSocket', 'Scheduler'];

View File

@@ -203,7 +203,7 @@ export class DeesDataviewCodebox extends DeesElement {
</style> </style>
<div <div
class="mainbox" class="mainbox"
@contextmenu="${(eventArg) => { @contextmenu="${(eventArg: MouseEvent) => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [ DeesContextmenu.openContextMenuWithOptions(eventArg, [
{ {
name: 'About', name: 'About',
@@ -241,7 +241,7 @@ export class DeesDataviewCodebox extends DeesElement {
private codeToDisplayStore = ''; private codeToDisplayStore = '';
private highlightJs: HLJSApi | null = null; private highlightJs: HLJSApi | null = null;
public async updated(_changedProperties) { public async updated(_changedProperties: Map<string, any>) {
super.updated(_changedProperties); super.updated(_changedProperties);
console.log('highlighting now'); console.log('highlighting now');
console.log(this.childNodes); console.log(this.childNodes);
@@ -267,11 +267,11 @@ export class DeesDataviewCodebox extends DeesElement {
this.highlightJs = await DeesServiceLibLoader.getInstance().loadHighlightJs(); this.highlightJs = await DeesServiceLibLoader.getInstance().loadHighlightJs();
} }
const localCodeNode = this.shadowRoot.querySelector('code'); const localCodeNode = this.shadowRoot!.querySelector('code');
const highlightedHtml = this.highlightJs.highlight(this.codeToDisplayStore, { const highlightedHtml = this.highlightJs.highlight(this.codeToDisplayStore, {
language: this.progLang, language: this.progLang,
ignoreIllegals: true, ignoreIllegals: true,
}); });
localCodeNode.innerHTML = highlightedHtml.value; localCodeNode!.innerHTML = highlightedHtml.value;
} }
} }

View File

@@ -29,7 +29,7 @@ export class DeesDataviewStatusobject extends DeesElement {
public static demo = demoFunc; public static demo = demoFunc;
public static demoGroups = ['Data View']; public static demoGroups = ['Data View'];
@property({ type: Object }) accessor statusObject: tsclass.code.IStatusObject; @property({ type: Object }) accessor statusObject!: tsclass.code.IStatusObject;
public static styles = [ public static styles = [
themeDefaultStyles, themeDefaultStyles,
@@ -259,7 +259,7 @@ export class DeesDataviewStatusobject extends DeesElement {
await navigator.clipboard.writeText(JSON.stringify(this.statusObject, null, 2)); await navigator.clipboard.writeText(JSON.stringify(this.statusObject, null, 2));
// Show feedback // Show feedback
const button = this.shadowRoot.querySelector('.copyMain') as HTMLElement; const button = this.shadowRoot!.querySelector('.copyMain') as HTMLElement;
const originalText = button.textContent; const originalText = button.textContent;
button.textContent = 'Copied!'; button.textContent = 'Copied!';

View File

@@ -878,7 +878,7 @@ export class DeesStatsGrid extends DeesElement {
private renderTile(tile: IStatsTile): TemplateResult { private renderTile(tile: IStatsTile): TemplateResult {
const hasActions = tile.actions && tile.actions.length > 0; const hasActions = tile.actions && tile.actions.length > 0;
const clickable = hasActions && tile.actions.length === 1; const clickable = hasActions && tile.actions!.length === 1;
const columnSpan = tile.columnSpan && tile.columnSpan > 1 ? tile.columnSpan : undefined; const columnSpan = tile.columnSpan && tile.columnSpan > 1 ? tile.columnSpan : undefined;
return html` return html`

View File

@@ -52,12 +52,12 @@ export class DeesTable<T> extends DeesElement {
@property({ @property({
type: String, type: String,
}) })
accessor key: string; accessor key!: string;
@property({ @property({
type: String, type: String,
}) })
accessor label: string; accessor label!: string;
@property({ @property({
type: Boolean, type: Boolean,
@@ -83,7 +83,7 @@ export class DeesTable<T> extends DeesElement {
type: String, type: String,
reflect: true, reflect: true,
}) })
accessor dataName: string; accessor dataName!: string;
@property({ @property({
@@ -127,7 +127,7 @@ export class DeesTable<T> extends DeesElement {
@property({ @property({
type: Object, type: Object,
}) })
accessor selectedDataRow: T; accessor selectedDataRow!: T;
@property({ @property({
type: Array, type: Array,
@@ -359,7 +359,7 @@ export class DeesTable<T> extends DeesElement {
if (elementArg.tagName === 'TR') { if (elementArg.tagName === 'TR') {
return elementArg; return elementArg;
} else { } else {
return getTr(elementArg.parentElement); return getTr(elementArg.parentElement!);
} }
}; };
return html` return html`
@@ -393,8 +393,8 @@ export class DeesTable<T> extends DeesElement {
}} }}
@drop=${async (eventArg: DragEvent) => { @drop=${async (eventArg: DragEvent) => {
eventArg.preventDefault(); eventArg.preventDefault();
const newFiles = []; const newFiles: File[] = [];
for (const file of Array.from(eventArg.dataTransfer.files)) { for (const file of Array.from(eventArg.dataTransfer!.files)) {
this.files.push(file); this.files.push(file);
newFiles.push(file); newFiles.push(file);
this.requestUpdate(); this.requestUpdate();
@@ -548,8 +548,8 @@ export class DeesTable<T> extends DeesElement {
type: ['header'], type: ['header'],
actionFunc: async () => { actionFunc: async () => {
console.log('open search'); console.log('open search');
const searchGrid = this.shadowRoot.querySelector('.searchGrid'); const searchGrid = this.shadowRoot!.querySelector('.searchGrid');
searchGrid.classList.toggle('hidden'); searchGrid!.classList.toggle('hidden');
} }
}); });
console.log(this.dataActions); console.log(this.dataActions);
@@ -609,7 +609,7 @@ export class DeesTable<T> extends DeesElement {
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
await domtools.convenience.smartdelay.delayFor(0); await domtools.convenience.smartdelay.delayFor(0);
// Get the table element // Get the table element
const table = this.shadowRoot.querySelector('table'); const table = this.shadowRoot!.querySelector('table');
if (!table) return; if (!table) return;
// Get the first row's cells to measure the widths // Get the first row's cells to measure the widths
@@ -718,7 +718,7 @@ export class DeesTable<T> extends DeesElement {
if (!this._rowIdMap.has(key)) { if (!this._rowIdMap.has(key)) {
this._rowIdMap.set(key, String(++this._rowIdCounter)); this._rowIdMap.set(key, String(++this._rowIdCounter));
} }
return this._rowIdMap.get(key); return this._rowIdMap.get(key)!;
} }
private isRowSelected(row: T): boolean { private isRowSelected(row: T): boolean {
@@ -818,7 +818,7 @@ export class DeesTable<T> extends DeesElement {
input.blur(); input.blur();
} }
if (saveArg) { if (saveArg) {
itemArg[key] = input.value as any; // Convert string to T (you might need better type casting depending on your data structure) (itemArg as any)[key] = input.value as any; // Convert string to T (you might need better type casting depending on your data structure)
this.changeSubject.next(this); this.changeSubject.next(this);
} }
input.remove(); input.remove();

View File

@@ -89,7 +89,7 @@ export class DeesProgressbar extends DeesElement {
} }
public async updatePercentage() { public async updatePercentage() {
const progressBarFill = this.shadowRoot.querySelector('.progressBarFill') as HTMLElement; const progressBarFill = this.shadowRoot!.querySelector('.progressBarFill') as HTMLElement;
progressBarFill.style.width = `${this.percentage}%`; progressBarFill.style.width = `${this.percentage}%`;
} }

View File

@@ -30,7 +30,7 @@ export class DeesFormSubmit extends DeesElement {
accessor disabled = false; accessor disabled = false;
@property({ type: String }) @property({ type: String })
accessor text: string; accessor text!: string;
@property({ type: String }) @property({ type: String })
accessor status: 'normal' | 'pending' | 'success' | 'error' = 'normal'; accessor status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
@@ -42,7 +42,7 @@ export class DeesFormSubmit extends DeesElement {
accessor size: 'sm' | 'default' | 'lg' | 'icon' | 'small' | 'normal' | 'large' = 'default'; accessor size: 'sm' | 'default' | 'lg' | 'icon' | 'small' | 'normal' | 'large' = 'default';
@property({ type: String }) @property({ type: String })
accessor icon: string; accessor icon!: string;
@property({ type: String }) @property({ type: String })
accessor iconPosition: 'left' | 'right' = 'left'; accessor iconPosition: 'left' | 'right' = 'left';

View File

@@ -57,7 +57,7 @@ export const demoFunc = () => html`
const outputDiv = elementArg.querySelector('.form-output'); const outputDiv = elementArg.querySelector('.form-output');
if (form && outputDiv) { if (form && outputDiv) {
form.addEventListener('formData', async (eventArg: CustomEvent) => { form.addEventListener('formData', (async (eventArg: CustomEvent) => {
const data = eventArg.detail.data; const data = eventArg.detail.data;
console.log('Form submitted with data:', data); console.log('Form submitted with data:', data);
@@ -75,7 +75,7 @@ export const demoFunc = () => html`
await domtools.plugins.smartdelay.delayFor(2000); await domtools.plugins.smartdelay.delayFor(2000);
form.reset(); form.reset();
outputDiv.innerHTML = '<em>Form has been reset</em>'; outputDiv.innerHTML = '<em>Form has been reset</em>';
}); }) as unknown as EventListener);
// Track individual field changes // Track individual field changes
const inputs = form.querySelectorAll('dees-input-text, dees-input-dropdown, dees-input-checkbox'); const inputs = form.querySelectorAll('dees-input-text, dees-input-dropdown, dees-input-checkbox');
@@ -158,14 +158,14 @@ export const demoFunc = () => html`
console.log('Horizontal form layout active'); console.log('Horizontal form layout active');
// Monitor filter changes // Monitor filter changes
form.addEventListener('formData', (event: CustomEvent) => { form.addEventListener('formData', ((event: CustomEvent) => {
const filters = event.detail.data; const filters = event.detail.data;
console.log('Filter applied:', filters); console.log('Filter applied:', filters);
// Simulate search // Simulate search
const resultsCount = Math.floor(Math.random() * 100) + 1; const resultsCount = Math.floor(Math.random() * 100) + 1;
console.log(`Found ${resultsCount} results with filters:`, filters); console.log(`Found ${resultsCount} results with filters:`, filters);
}); }) as unknown as EventListener);
// Setup real-time filter updates // Setup real-time filter updates
const inputs = form.querySelectorAll('[key]'); const inputs = form.querySelectorAll('[key]');
@@ -224,7 +224,7 @@ export const demoFunc = () => html`
const statusDiv = elementArg.querySelector('#status-display'); const statusDiv = elementArg.querySelector('#status-display');
if (form) { if (form) {
form.addEventListener('formData', async (eventArg: CustomEvent) => { form.addEventListener('formData', (async (eventArg: CustomEvent) => {
const data = eventArg.detail.data; const data = eventArg.detail.data;
console.log('Advanced form data:', data); console.log('Advanced form data:', data);
@@ -252,7 +252,7 @@ export const demoFunc = () => html`
} }
console.log('Form data logged:', data); console.log('Form data logged:', data);
}); }) as unknown as EventListener);
// Monitor file uploads // Monitor file uploads
const fileUpload = form.querySelector('dees-input-fileupload'); const fileUpload = form.querySelector('dees-input-fileupload');

View File

@@ -156,8 +156,9 @@ export class DeesForm extends DeesElement {
requiredOK = false; requiredOK = false;
} }
} }
if (this.getSubmitButton()) { const submitButton = this.getSubmitButton();
this.getSubmitButton().disabled = !requiredOK; if (submitButton) {
submitButton.disabled = !requiredOK;
} }
} }
@@ -200,6 +201,7 @@ export class DeesForm extends DeesElement {
) { ) {
const inputChildren = this.getFormElements(); const inputChildren = this.getFormElements();
const submitButton = this.getSubmitButton(); const submitButton = this.getSubmitButton();
if (!submitButton) return;
switch (visualStateArg) { switch (visualStateArg) {
case 'normal': case 'normal':
@@ -240,7 +242,6 @@ export class DeesForm extends DeesElement {
*/ */
reset() { reset() {
const inputChildren = this.getFormElements(); const inputChildren = this.getFormElements();
const submitButton = this.getSubmitButton();
for (const inputChild of inputChildren) { for (const inputChild of inputChildren) {
inputChild.value = null; inputChild.value = null;

View File

@@ -31,10 +31,10 @@ export abstract class DeesInputBase<T = any> extends DeesElement {
* Common properties for all inputs * Common properties for all inputs
*/ */
@property({ type: String }) @property({ type: String })
accessor key: string; accessor key!: string;
@property({ type: String }) @property({ type: String })
accessor label: string; accessor label!: string;
@property({ type: Boolean }) @property({ type: Boolean })
accessor required: boolean = false; accessor required: boolean = false;
@@ -43,7 +43,7 @@ export abstract class DeesInputBase<T = any> extends DeesElement {
accessor disabled: boolean = false; accessor disabled: boolean = false;
@property({ type: String }) @property({ type: String })
accessor description: string; accessor description!: string;
/** /**
* Common styles for all input components * Common styles for all input components

View File

@@ -215,7 +215,7 @@ export class DeesInputCheckbox extends DeesInputBase<DeesInputCheckbox> {
} }
public focus(): void { public focus(): void {
const checkboxDiv = this.shadowRoot.querySelector('.checkbox'); const checkboxDiv = this.shadowRoot!.querySelector('.checkbox');
if (checkboxDiv) { if (checkboxDiv) {
(checkboxDiv as any).focus(); (checkboxDiv as any).focus();
} }

View File

@@ -610,20 +610,20 @@ export class DeesInputCode extends DeesInputBase<string> {
{ {
name: 'Cancel', name: 'Cancel',
action: async (modalRef) => { action: async (modalRef) => {
await modalRef.destroy(); await modalRef!.destroy();
}, },
}, },
{ {
name: 'Save & Close', name: 'Save & Close',
action: async (modalRef) => { action: async (modalRef) => {
// Get the editor content from the modal // Get the editor content from the modal
modalEditorElement = modalRef.shadowRoot?.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco; modalEditorElement = modalRef!.shadowRoot?.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;
if (modalEditorElement) { if (modalEditorElement) {
const editor = await modalEditorElement.editorDeferred.promise; const editor = await modalEditorElement.editorDeferred.promise;
const newValue = editor.getValue(); const newValue = editor.getValue();
this.setValue(newValue); this.setValue(newValue);
} }
await modalRef.destroy(); await modalRef!.destroy();
}, },
}, },
], ],

View File

@@ -47,9 +47,9 @@ export const demoFunc = () => html`
const datePicker = elementArg.querySelector('dees-input-datepicker'); const datePicker = elementArg.querySelector('dees-input-datepicker');
if (datePicker) { if (datePicker) {
datePicker.addEventListener('change', (event: CustomEvent) => { datePicker.addEventListener('change', ((event: CustomEvent) => {
console.log('Basic date selected:', (event.target as DeesInputDatepicker).value); console.log('Basic date selected:', (event.target as DeesInputDatepicker).value);
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'Basic Date Picker'} .subtitle=${'Simple date selection without time'}> <dees-panel .title=${'Basic Date Picker'} .subtitle=${'Simple date selection without time'}>
@@ -66,17 +66,17 @@ export const demoFunc = () => html`
const appointmentPicker = elementArg.querySelector('dees-input-datepicker[label="Appointment"]'); const appointmentPicker = elementArg.querySelector('dees-input-datepicker[label="Appointment"]');
if (dateTimePicker) { if (dateTimePicker) {
dateTimePicker.addEventListener('change', (event: CustomEvent) => { dateTimePicker.addEventListener('change', ((event: CustomEvent) => {
const value = (event.target as DeesInputDatepicker).value; const value = (event.target as DeesInputDatepicker).value;
console.log('24h format datetime:', value); console.log('24h format datetime:', value);
}); }) as EventListener);
} }
if (appointmentPicker) { if (appointmentPicker) {
appointmentPicker.addEventListener('change', (event: CustomEvent) => { appointmentPicker.addEventListener('change', ((event: CustomEvent) => {
const value = (event.target as DeesInputDatepicker).value; const value = (event.target as DeesInputDatepicker).value;
console.log('12h format datetime:', value); console.log('12h format datetime:', value);
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'Date and Time Selection'} .subtitle=${'Date pickers with time selection in different formats'}> <dees-panel .title=${'Date and Time Selection'} .subtitle=${'Date pickers with time selection in different formats'}>
@@ -102,14 +102,14 @@ export const demoFunc = () => html`
const timezonePickers = elementArg.querySelectorAll('dees-input-datepicker'); const timezonePickers = elementArg.querySelectorAll('dees-input-datepicker');
timezonePickers.forEach((picker) => { timezonePickers.forEach((picker) => {
picker.addEventListener('change', (event: CustomEvent) => { picker.addEventListener('change', ((event: CustomEvent) => {
const target = event.target as DeesInputDatepicker; const target = event.target as DeesInputDatepicker;
console.log(`${target.label} value:`, target.value); console.log(`${target.label} value:`, target.value);
const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement; const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement;
if (input) { if (input) {
console.log(`${target.label} formatted:`, input.value); console.log(`${target.label} formatted:`, input.value);
} }
}); }) as EventListener);
}); });
}}> }}>
<dees-panel .title=${'Timezone Support'} .subtitle=${'Date and time selection with timezone awareness'}> <dees-panel .title=${'Timezone Support'} .subtitle=${'Date and time selection with timezone awareness'}>
@@ -140,7 +140,7 @@ export const demoFunc = () => html`
if (futureDatePicker) { if (futureDatePicker) {
// Show the min/max constraints in action // Show the min/max constraints in action
futureDatePicker.addEventListener('change', (event: CustomEvent) => { futureDatePicker.addEventListener('change', ((event: CustomEvent) => {
const value = (event.target as DeesInputDatepicker).value; const value = (event.target as DeesInputDatepicker).value;
if (value) { if (value) {
const selectedDate = new Date(value); const selectedDate = new Date(value);
@@ -148,7 +148,7 @@ export const demoFunc = () => html`
const daysDiff = Math.floor((selectedDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24)); const daysDiff = Math.floor((selectedDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
console.log(`Selected date is ${daysDiff} days from today`); console.log(`Selected date is ${daysDiff} days from today`);
} }
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'Date Range Constraints'} .subtitle=${'Limit selectable dates with min and max values'}> <dees-panel .title=${'Date Range Constraints'} .subtitle=${'Limit selectable dates with min and max values'}>
@@ -171,14 +171,14 @@ export const demoFunc = () => html`
const datePickers = elementArg.querySelectorAll('dees-input-datepicker'); const datePickers = elementArg.querySelectorAll('dees-input-datepicker');
datePickers.forEach((picker) => { datePickers.forEach((picker) => {
picker.addEventListener('change', (event: CustomEvent) => { picker.addEventListener('change', ((event: CustomEvent) => {
const target = event.target as DeesInputDatepicker; const target = event.target as DeesInputDatepicker;
// Log the formatted value that's displayed in the input // Log the formatted value that's displayed in the input
const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement; const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement;
if (input) { if (input) {
console.log(`${target.label} format:`, input.value); console.log(`${target.label} format:`, input.value);
} }
}); }) as EventListener);
}); });
}}> }}>
<dees-panel .title=${'Date Formats'} .subtitle=${'Different date display formats for various regions'}> <dees-panel .title=${'Date Formats'} .subtitle=${'Different date display formats for various regions'}>
@@ -268,7 +268,7 @@ export const demoFunc = () => html`
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => { <dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
// Generate weekend dates for the current month // Generate weekend dates for the current month
const generateWeekends = () => { const generateWeekends = () => {
const weekends = []; const weekends: string[] = [];
const now = new Date(); const now = new Date();
const year = now.getFullYear(); const year = now.getFullYear();
const month = now.getMonth(); const month = now.getMonth();
@@ -286,7 +286,7 @@ export const demoFunc = () => html`
const picker = elementArg.querySelector('dees-input-datepicker'); const picker = elementArg.querySelector('dees-input-datepicker');
if (picker) { if (picker) {
picker.disabledDates = generateWeekends(); (picker as DeesInputDatepicker).disabledDates = generateWeekends();
console.log('Disabled weekend dates for current month'); console.log('Disabled weekend dates for current month');
} }
}}> }}>
@@ -344,7 +344,7 @@ export const demoFunc = () => html`
const picker = elementArg.querySelector('dees-input-datepicker'); const picker = elementArg.querySelector('dees-input-datepicker');
if (picker) { if (picker) {
picker.events = sampleEvents; (picker as DeesInputDatepicker).events = sampleEvents;
console.log('Calendar events loaded:', sampleEvents); console.log('Calendar events loaded:', sampleEvents);
} }
}}> }}>
@@ -371,7 +371,7 @@ export const demoFunc = () => html`
const output = elementArg.querySelector('#event-output'); const output = elementArg.querySelector('#event-output');
if (picker && output) { if (picker && output) {
picker.addEventListener('change', (event: CustomEvent) => { picker.addEventListener('change', ((event: CustomEvent) => {
const target = event.target as DeesInputDatepicker; const target = event.target as DeesInputDatepicker;
const value = target.value; const value = target.value;
if (value) { if (value) {
@@ -379,16 +379,16 @@ export const demoFunc = () => html`
// Get the formatted value from the input element // Get the formatted value from the input element
const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement; const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement;
const formattedValue = input?.value || 'N/A'; const formattedValue = input?.value || 'N/A';
output.innerHTML = ` (output as HTMLElement).innerHTML = `
<strong>Event triggered!</strong><br> <strong>Event triggered!</strong><br>
ISO Value: ${value}<br> ISO Value: ${value}<br>
Formatted: ${formattedValue}<br> Formatted: ${formattedValue}<br>
Date object: ${date.toLocaleString()} Date object: ${date.toLocaleString()}
`; `;
} else { } else {
output.innerHTML = '<em>Date cleared</em>'; (output as HTMLElement).innerHTML = '<em>Date cleared</em>';
} }
}); }) as EventListener);
picker.addEventListener('blur', () => { picker.addEventListener('blur', () => {
console.log('Datepicker lost focus'); console.log('Datepicker lost focus');

View File

@@ -56,16 +56,16 @@ export const demoFunc = () => html`
// Log when country changes // Log when country changes
if (countryDropdown) { if (countryDropdown) {
countryDropdown.addEventListener('selectedOption', (event: CustomEvent) => { countryDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
console.log('Country selected:', event.detail); console.log('Country selected:', event.detail);
}); }) as EventListener);
} }
// Log when role changes // Log when role changes
if (roleDropdown) { if (roleDropdown) {
roleDropdown.addEventListener('selectedOption', (event: CustomEvent) => { roleDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
console.log('Role selected:', event.detail); console.log('Role selected:', event.detail);
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'1. Basic Dropdowns'} .subtitle=${'Standard dropdown with search functionality and various options'}> <dees-panel .title=${'1. Basic Dropdowns'} .subtitle=${'Standard dropdown with search functionality and various options'}>
@@ -103,9 +103,9 @@ export const demoFunc = () => html`
const priorityDropdown = elementArg.querySelector('dees-input-dropdown'); const priorityDropdown = elementArg.querySelector('dees-input-dropdown');
if (priorityDropdown) { if (priorityDropdown) {
priorityDropdown.addEventListener('selectedOption', (event: CustomEvent) => { priorityDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
console.log(`Priority changed to: ${event.detail.option}`); console.log(`Priority changed to: ${event.detail.option}`);
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'2. Without Search'} .subtitle=${'Dropdown with search functionality disabled for simpler selection'}> <dees-panel .title=${'2. Without Search'} .subtitle=${'Dropdown with search functionality disabled for simpler selection'}>
@@ -128,10 +128,10 @@ export const demoFunc = () => html`
// Log all changes from horizontal dropdowns // Log all changes from horizontal dropdowns
dropdowns.forEach((dropdown) => { dropdowns.forEach((dropdown) => {
dropdown.addEventListener('selectedOption', (event: CustomEvent) => { dropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
const label = dropdown.getAttribute('label'); const label = dropdown.getAttribute('label');
console.log(`${label}: ${event.detail.option}`); console.log(`${label}: ${event.detail.option}`);
}); }) as EventListener);
}); });
}}> }}>
<dees-panel .title=${'3. Horizontal Layout'} .subtitle=${'Multiple dropdowns in a horizontal layout for compact forms'}> <dees-panel .title=${'3. Horizontal Layout'} .subtitle=${'Multiple dropdowns in a horizontal layout for compact forms'}>
@@ -216,9 +216,9 @@ export const demoFunc = () => html`
const dropdown = elementArg.querySelector('dees-input-dropdown'); const dropdown = elementArg.querySelector('dees-input-dropdown');
if (dropdown) { if (dropdown) {
dropdown.addEventListener('selectedOption', (event: CustomEvent) => { dropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
console.log('Bottom dropdown selected:', event.detail); console.log('Bottom dropdown selected:', event.detail);
}); }) as EventListener);
// Note: The dropdown automatically detects available space // Note: The dropdown automatically detects available space
// and opens upward when near the bottom of the viewport // and opens upward when near the bottom of the viewport
@@ -248,16 +248,16 @@ export const demoFunc = () => html`
output.innerHTML = '<em>Select a product to see details...</em>'; output.innerHTML = '<em>Select a product to see details...</em>';
// Handle dropdown changes // Handle dropdown changes
dropdown.addEventListener('change', (event: CustomEvent) => { dropdown.addEventListener('change', ((event: CustomEvent) => {
if (event.detail.value) { if (event.detail.value) {
output.innerHTML = ` (output as HTMLElement).innerHTML = `
<strong>Selected:</strong> ${event.detail.value.option}<br> <strong>Selected:</strong> ${event.detail.value.option}<br>
<strong>Key:</strong> ${event.detail.value.key}<br> <strong>Key:</strong> ${event.detail.value.key}<br>
<strong>Price:</strong> $${event.detail.value.payload?.price || 'N/A'}<br> <strong>Price:</strong> $${event.detail.value.payload?.price || 'N/A'}<br>
<strong>Features:</strong> ${event.detail.value.payload?.features?.join(', ') || 'N/A'} <strong>Features:</strong> ${event.detail.value.payload?.features?.join(', ') || 'N/A'}
`; `;
} }
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'6. Event Handling & Payload'} .subtitle=${'Dropdown with payload data and change event handling'}> <dees-panel .title=${'6. Event Handling & Payload'} .subtitle=${'Dropdown with payload data and change event handling'}>
@@ -281,20 +281,20 @@ export const demoFunc = () => html`
const frameworkDropdown = elementArg.querySelector('dees-input-dropdown[key="framework"]'); const frameworkDropdown = elementArg.querySelector('dees-input-dropdown[key="framework"]');
if (form) { if (form) {
form.addEventListener('formData', (event: CustomEvent) => { form.addEventListener('formData', ((event: CustomEvent) => {
console.log('Form submitted with data:', event.detail.data); console.log('Form submitted with data:', event.detail.data);
}); }) as EventListener);
} }
if (projectTypeDropdown && frameworkDropdown) { if (projectTypeDropdown && frameworkDropdown) {
// Filter frameworks based on project type // Filter frameworks based on project type
projectTypeDropdown.addEventListener('selectedOption', (event: CustomEvent) => { projectTypeDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
const selectedType = event.detail.key; const selectedType = event.detail.key;
console.log(`Project type changed to: ${selectedType}`); console.log(`Project type changed to: ${selectedType}`);
// In a real app, you could filter the framework options based on project type // In a real app, you could filter the framework options based on project type
// For demo purposes, we just log the change // For demo purposes, we just log the change
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'7. Form Integration'} .subtitle=${'Dropdown working within a form with validation'}> <dees-panel .title=${'7. Form Integration'} .subtitle=${'Dropdown working within a form with validation'}>

View File

@@ -30,14 +30,14 @@ export class DeesInputDropdown extends DeesInputBase<DeesInputDropdown> {
accessor options: { option: string; key: string; payload?: any }[] = []; accessor options: { option: string; key: string; payload?: any }[] = [];
@property() @property()
accessor selectedOption: { option: string; key: string; payload?: any } = null; accessor selectedOption: { option: string; key: string; payload?: any } | null = null;
// Add value property for form compatibility // Add value property for form compatibility
public get value() { public get value() {
return this.selectedOption; return this.selectedOption;
} }
public set value(val: { option: string; key: string; payload?: any }) { public set value(val: { option: string; key: string; payload?: any } | null) {
this.selectedOption = val; this.selectedOption = val;
} }
@@ -372,7 +372,7 @@ export class DeesInputDropdown extends DeesInputBase<DeesInputDropdown> {
if (this.isOpened) { if (this.isOpened) {
// Check available space and set position // Check available space and set position
const selectedBox = this.shadowRoot.querySelector('.selectedBox') as HTMLElement; const selectedBox = this.shadowRoot!.querySelector('.selectedBox') as HTMLElement;
const rect = selectedBox.getBoundingClientRect(); const rect = selectedBox.getBoundingClientRect();
const spaceBelow = window.innerHeight - rect.bottom; const spaceBelow = window.innerHeight - rect.bottom;
const spaceAbove = rect.top; const spaceAbove = rect.top;
@@ -382,7 +382,7 @@ export class DeesInputDropdown extends DeesInputBase<DeesInputDropdown> {
// Focus search input if present // Focus search input if present
await this.updateComplete; await this.updateComplete;
const searchInput = this.shadowRoot.querySelector('.search input') as HTMLInputElement; const searchInput = this.shadowRoot!.querySelector('.search input') as HTMLInputElement;
if (searchInput) { if (searchInput) {
searchInput.focus(); searchInput.focus();
} }
@@ -455,7 +455,7 @@ export class DeesInputDropdown extends DeesInputBase<DeesInputDropdown> {
} }
} }
public getValue(): { option: string; key: string; payload?: any } { public getValue(): { option: string; key: string; payload?: any } | null {
return this.selectedOption; return this.selectedOption;
} }

View File

@@ -48,7 +48,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
accessor maxFiles: number = 0; // 0 means no limit accessor maxFiles: number = 0; // 0 means no limit
@property({ type: String, reflect: true }) @property({ type: String, reflect: true })
accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' = null; accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' | null = null;
accessor validationMessage: string = ''; accessor validationMessage: string = '';
@@ -266,7 +266,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
return; return;
} }
['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => { ['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
this.dropArea!.addEventListener(eventName, this.handleDragEvent); this.dropArea!.addEventListener(eventName, this.handleDragEvent as unknown as EventListener);
}); });
} }
@@ -275,7 +275,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
return; return;
} }
['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => { ['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
this.dropArea!.removeEventListener(eventName, this.handleDragEvent); this.dropArea!.removeEventListener(eventName, this.handleDragEvent as unknown as EventListener);
}); });
} }

View File

@@ -60,7 +60,7 @@ export class DeesInputIban extends DeesInputBase<DeesInputIban> {
public firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) { public firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
super.firstUpdated(_changedProperties); super.firstUpdated(_changedProperties);
const deesInputText = this.shadowRoot.querySelector('dees-input-text') as any; const deesInputText = this.shadowRoot!.querySelector('dees-input-text') as any;
if (deesInputText && deesInputText.changeSubject) { if (deesInputText && deesInputText.changeSubject) {
deesInputText.changeSubject.subscribe(() => { deesInputText.changeSubject.subscribe(() => {
this.changeSubject.next(this); this.changeSubject.next(this);
@@ -81,8 +81,10 @@ export class DeesInputIban extends DeesInputBase<DeesInputIban> {
} }
} }
this.enteredIbanIsValid = ibantools.isValidIBAN(this.enteredString.replace(/ /g, '')); this.enteredIbanIsValid = ibantools.isValidIBAN(this.enteredString.replace(/ /g, ''));
const deesInputText = this.shadowRoot.querySelector('dees-input-text'); const deesInputText = this.shadowRoot!.querySelector('dees-input-text') as any;
deesInputText.validationText = `IBAN is valid: ${this.enteredIbanIsValid}`; if (deesInputText) {
deesInputText.validationText = `IBAN is valid: ${this.enteredIbanIsValid}`;
}
} }
public getValue(): string { public getValue(): string {

View File

@@ -211,7 +211,7 @@ export class DeesInputMultitoggle extends DeesInputBase<DeesInputMultitoggle> {
private indicatorInitialized = false; private indicatorInitialized = false;
public async setIndicator() { public async setIndicator() {
const indicator: HTMLDivElement = this.shadowRoot.querySelector('.indicator'); const indicator: HTMLDivElement | null = this.shadowRoot!.querySelector('.indicator');
const selectedIndex = this.options.indexOf(this.selectedOption); const selectedIndex = this.options.indexOf(this.selectedOption);
// If no valid selection, hide indicator // If no valid selection, hide indicator
@@ -222,7 +222,7 @@ export class DeesInputMultitoggle extends DeesInputBase<DeesInputMultitoggle> {
return; return;
} }
const option: HTMLDivElement = this.shadowRoot.querySelector( const option: HTMLDivElement | null = this.shadowRoot!.querySelector(
`.option:nth-child(${selectedIndex + 2})` `.option:nth-child(${selectedIndex + 2})`
); );

View File

@@ -67,7 +67,7 @@ export class DeesInputPhone extends DeesInputBase<DeesInputPhone> {
} }
// Subscribe to the inner input's changes // Subscribe to the inner input's changes
const innerInput = this.shadowRoot.querySelector('dees-input-text') as any; const innerInput = this.shadowRoot!.querySelector('dees-input-text') as any;
if (innerInput && innerInput.changeSubject) { if (innerInput && innerInput.changeSubject) {
innerInput.changeSubject.subscribe(() => { innerInput.changeSubject.subscribe(() => {
this.changeSubject.next(this); this.changeSubject.next(this);

View File

@@ -35,7 +35,7 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
accessor direction: 'vertical' | 'horizontal' = 'vertical'; accessor direction: 'vertical' | 'horizontal' = 'vertical';
@property({ type: String, reflect: true }) @property({ type: String, reflect: true })
accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' = null; accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' | null = null;
// Form compatibility // Form compatibility
public get value() { public get value() {
@@ -346,15 +346,15 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
} }
private focusNextOption() { private focusNextOption() {
const radioCircles = Array.from(this.shadowRoot.querySelectorAll('.radio-circle')); const radioCircles = Array.from(this.shadowRoot!.querySelectorAll('.radio-circle'));
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot.activeElement); const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot!.activeElement);
const nextIndex = (currentIndex + 1) % radioCircles.length; const nextIndex = (currentIndex + 1) % radioCircles.length;
(radioCircles[nextIndex] as HTMLElement).focus(); (radioCircles[nextIndex] as HTMLElement).focus();
} }
private focusPreviousOption() { private focusPreviousOption() {
const radioCircles = Array.from(this.shadowRoot.querySelectorAll('.radio-circle')); const radioCircles = Array.from(this.shadowRoot!.querySelectorAll('.radio-circle'));
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot.activeElement); const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot!.activeElement);
const prevIndex = currentIndex <= 0 ? radioCircles.length - 1 : currentIndex - 1; const prevIndex = currentIndex <= 0 ? radioCircles.length - 1 : currentIndex - 1;
(radioCircles[prevIndex] as HTMLElement).focus(); (radioCircles[prevIndex] as HTMLElement).focus();
} }

View File

@@ -58,11 +58,11 @@ export class DeesInputRichtext extends DeesInputBase<string> {
@state() @state()
accessor wordCount: number = 0; accessor wordCount: number = 0;
private editorElement: HTMLElement; private editorElement!: HTMLElement;
private linkInputElement: HTMLInputElement; private linkInputElement!: HTMLInputElement;
private tiptapBundle: ITiptapBundle | null = null; private tiptapBundle: ITiptapBundle | null = null;
public editor: Editor; public editor!: Editor;
public static styles = richtextStyles; public static styles = richtextStyles;
@@ -235,8 +235,8 @@ export class DeesInputRichtext extends DeesInputBase<string> {
// Load Tiptap from CDN // Load Tiptap from CDN
this.tiptapBundle = await DeesServiceLibLoader.getInstance().loadTiptap(); this.tiptapBundle = await DeesServiceLibLoader.getInstance().loadTiptap();
this.editorElement = this.shadowRoot.querySelector('.editor-content'); this.editorElement = this.shadowRoot!.querySelector('.editor-content')!;
this.linkInputElement = this.shadowRoot.querySelector('.link-input input'); this.linkInputElement = this.shadowRoot!.querySelector('.link-input input')!;
this.initializeEditor(); this.initializeEditor();
} }

View File

@@ -73,9 +73,9 @@ export const demoFunc = () => html`
const inputs = elementArg.querySelectorAll('dees-input-text'); const inputs = elementArg.querySelectorAll('dees-input-text');
inputs.forEach((input: DeesInputText) => { inputs.forEach((input: DeesInputText) => {
input.addEventListener('changeSubject', (event: CustomEvent) => { input.addEventListener('changeSubject', ((event: CustomEvent) => {
console.log(`Input "${input.label}" changed to:`, input.getValue()); console.log(`Input "${input.label}" changed to:`, input.getValue());
}); }) as EventListener);
input.addEventListener('blur', () => { input.addEventListener('blur', () => {
console.log(`Input "${input.label}" lost focus`); console.log(`Input "${input.label}" lost focus`);
@@ -271,7 +271,8 @@ export const demoFunc = () => html`
// Track password visibility toggles // Track password visibility toggles
const passwordInputs = elementArg.querySelectorAll('dees-input-text[isPasswordBool]'); const passwordInputs = elementArg.querySelectorAll('dees-input-text[isPasswordBool]');
passwordInputs.forEach((input: DeesInputText) => { passwordInputs.forEach((_input) => {
const input = _input as DeesInputText;
// Monitor for toggle button clicks within shadow DOM // Monitor for toggle button clicks within shadow DOM
const checkToggle = () => { const checkToggle = () => {
const inputEl = input.shadowRoot?.querySelector('input'); const inputEl = input.shadowRoot?.querySelector('input');
@@ -316,10 +317,10 @@ export const demoFunc = () => html`
if (dynamicInput && output) { if (dynamicInput && output) {
// Update output on every change // Update output on every change
dynamicInput.addEventListener('changeSubject', (event: CustomEvent) => { dynamicInput.addEventListener('changeSubject', ((event: CustomEvent) => {
const value = (event.detail as DeesInputText).getValue(); const value = (event.detail as DeesInputText).getValue();
output.textContent = `Current value: "${value}"`; output.textContent = `Current value: "${value}"`;
}); }) as EventListener);
// Also track focus/blur events // Also track focus/blur events
dynamicInput.addEventListener('focus', () => { dynamicInput.addEventListener('focus', () => {

View File

@@ -47,7 +47,7 @@ export class DeesInputText extends DeesInputBase {
type: Boolean, type: Boolean,
reflect: true, reflect: true,
}) })
accessor validationState: 'valid' | 'warn' | 'invalid'; accessor validationState!: 'valid' | 'warn' | 'invalid';
@property({ @property({
reflect: true, reflect: true,
@@ -55,7 +55,7 @@ export class DeesInputText extends DeesInputBase {
accessor validationText: string = ''; accessor validationText: string = '';
@property({}) @property({})
accessor validationFunction: (value: string) => boolean; accessor validationFunction!: (value: string) => boolean;
public static styles = [ public static styles = [
themeDefaultStyles, themeDefaultStyles,
@@ -274,12 +274,12 @@ export class DeesInputText extends DeesInputBase {
} }
public async focus() { public async focus() {
const textInput = this.shadowRoot.querySelector('input'); const textInput = this.shadowRoot!.querySelector('input');
textInput.focus(); textInput!.focus();
} }
public async blur() { public async blur() {
const textInput = this.shadowRoot.querySelector('input'); const textInput = this.shadowRoot!.querySelector('input');
textInput.blur(); textInput!.blur();
} }
} }

View File

@@ -12,17 +12,19 @@ export const demoFunc = () => html`
if (toggleAllOnBtn && toggleAllOffBtn) { if (toggleAllOnBtn && toggleAllOffBtn) {
toggleAllOnBtn.addEventListener('click', () => { toggleAllOnBtn.addEventListener('click', () => {
featureToggles.forEach((toggle: DeesInputToggle) => { featureToggles.forEach((toggle) => {
if (!toggle.disabled && !toggle.required) { const t = toggle as unknown as DeesInputToggle;
toggle.value = true; if (!t.disabled && !t.required) {
t.value = true;
} }
}); });
}); });
toggleAllOffBtn.addEventListener('click', () => { toggleAllOffBtn.addEventListener('click', () => {
featureToggles.forEach((toggle: DeesInputToggle) => { featureToggles.forEach((toggle) => {
if (!toggle.disabled && !toggle.required) { const t = toggle as unknown as DeesInputToggle;
toggle.value = false; if (!t.disabled && !t.required) {
t.value = false;
} }
}); });
}); });
@@ -280,10 +282,10 @@ export const demoFunc = () => html`
<dees-input-toggle <dees-input-toggle
.label=${'Airplane mode'} .label=${'Airplane mode'}
.value=${false} .value=${false}
@newValue=${(event: CustomEvent) => { @newValue=${(event: Event) => {
const output = document.querySelector('#airplane-output'); const output = document.querySelector('#airplane-output');
if (output) { if (output) {
output.textContent = `Airplane mode: ${event.detail ? 'ON' : 'OFF'}`; output.textContent = `Airplane mode: ${(event as CustomEvent).detail ? 'ON' : 'OFF'}`;
} }
}} }}
></dees-input-toggle> ></dees-input-toggle>
@@ -291,10 +293,10 @@ export const demoFunc = () => html`
<dees-input-toggle <dees-input-toggle
.label=${'Do not disturb'} .label=${'Do not disturb'}
.value=${false} .value=${false}
@newValue=${(event: CustomEvent) => { @newValue=${(event: Event) => {
const output = document.querySelector('#dnd-output'); const output = document.querySelector('#dnd-output');
if (output) { if (output) {
output.textContent = `Do not disturb: ${event.detail ? 'ENABLED' : 'DISABLED'}`; output.textContent = `Do not disturb: ${(event as CustomEvent).detail ? 'ENABLED' : 'DISABLED'}`;
} }
}} }}
></dees-input-toggle> ></dees-input-toggle>

View File

@@ -156,7 +156,7 @@ export class DeesInputTypelist extends DeesInputBase<DeesInputTypelist> {
<dees-label .label=${this.label} .description=${this.description}></dees-label> <dees-label .label=${this.label} .description=${this.description}></dees-label>
<div class="mainbox"> <div class="mainbox">
<div class="tags" @click=${() => { <div class="tags" @click=${() => {
this.shadowRoot.querySelector('input').focus(); this.shadowRoot!.querySelector('input')!.focus();
}}> }}>
${this.value.length === 0 ${this.value.length === 0
? html`<div class="notags">No tags yet</div>` ? html`<div class="notags">No tags yet</div>`

View File

@@ -200,15 +200,16 @@ export class HeadingBlockHandler extends BaseBlockHandler {
const wysiwygBlock = (headingBlock.getRootNode() as ShadowRoot).host as any; const wysiwygBlock = (headingBlock.getRootNode() as ShadowRoot).host as any;
if (wysiwygBlock) { if (wysiwygBlock) {
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback; const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
const self = this;
(wysiwygBlock as any).disconnectedCallback = async function() { (wysiwygBlock as any).disconnectedCallback = async function() {
if (this.selectionHandler) { if (self.selectionHandler) {
document.removeEventListener('selectionchange', this.selectionHandler); document.removeEventListener('selectionchange', self.selectionHandler);
this.selectionHandler = null; self.selectionHandler = null;
} }
if (originalDisconnectedCallback) { if (originalDisconnectedCallback) {
await originalDisconnectedCallback.call(wysiwygBlock); await originalDisconnectedCallback.call(wysiwygBlock);
} }
}.bind(this); };
} }
} }

View File

@@ -213,15 +213,16 @@ export class ListBlockHandler extends BaseBlockHandler {
const wysiwygBlock = (listBlock.getRootNode() as ShadowRoot).host as any; const wysiwygBlock = (listBlock.getRootNode() as ShadowRoot).host as any;
if (wysiwygBlock) { if (wysiwygBlock) {
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback; const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
const self = this;
(wysiwygBlock as any).disconnectedCallback = async function() { (wysiwygBlock as any).disconnectedCallback = async function() {
if (this.selectionHandler) { if (self.selectionHandler) {
document.removeEventListener('selectionchange', this.selectionHandler); document.removeEventListener('selectionchange', self.selectionHandler);
this.selectionHandler = null; self.selectionHandler = null;
} }
if (originalDisconnectedCallback) { if (originalDisconnectedCallback) {
await originalDisconnectedCallback.call(wysiwygBlock); await originalDisconnectedCallback.call(wysiwygBlock);
} }
}.bind(this); };
} }
} }

View File

@@ -193,15 +193,16 @@ export class ParagraphBlockHandler extends BaseBlockHandler {
const wysiwygBlock = element.closest('dees-wysiwyg-block'); const wysiwygBlock = element.closest('dees-wysiwyg-block');
if (wysiwygBlock) { if (wysiwygBlock) {
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback; const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
const self = this;
(wysiwygBlock as any).disconnectedCallback = async function() { (wysiwygBlock as any).disconnectedCallback = async function() {
if (this.selectionHandler) { if (self.selectionHandler) {
document.removeEventListener('selectionchange', this.selectionHandler); document.removeEventListener('selectionchange', self.selectionHandler);
this.selectionHandler = null; self.selectionHandler = null;
} }
if (originalDisconnectedCallback) { if (originalDisconnectedCallback) {
await originalDisconnectedCallback.call(wysiwygBlock); await originalDisconnectedCallback.call(wysiwygBlock);
} }
}.bind(this); };
} }
} }

View File

@@ -192,15 +192,16 @@ export class QuoteBlockHandler extends BaseBlockHandler {
const wysiwygBlock = (quoteBlock.getRootNode() as ShadowRoot).host as any; const wysiwygBlock = (quoteBlock.getRootNode() as ShadowRoot).host as any;
if (wysiwygBlock) { if (wysiwygBlock) {
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback; const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
const self = this;
(wysiwygBlock as any).disconnectedCallback = async function() { (wysiwygBlock as any).disconnectedCallback = async function() {
if (this.selectionHandler) { if (self.selectionHandler) {
document.removeEventListener('selectionchange', this.selectionHandler); document.removeEventListener('selectionchange', self.selectionHandler);
this.selectionHandler = null; self.selectionHandler = null;
} }
if (originalDisconnectedCallback) { if (originalDisconnectedCallback) {
await originalDisconnectedCallback.call(wysiwygBlock); await originalDisconnectedCallback.call(wysiwygBlock);
} }
}.bind(this); };
} }
} }

View File

@@ -188,22 +188,24 @@ export class DeesFormattingMenu extends DeesElement {
public firstUpdated(): void { public firstUpdated(): void {
// Set up event delegation for the menu // Set up event delegation for the menu
this.shadowRoot?.addEventListener('mousedown', (e: MouseEvent) => { this.shadowRoot!.addEventListener('mousedown', (e: Event) => {
const mouseEvent = e as MouseEvent;
const menu = this.shadowRoot?.querySelector('.formatting-menu'); const menu = this.shadowRoot?.querySelector('.formatting-menu');
if (menu && menu.contains(e.target as Node)) { if (menu && menu.contains(mouseEvent.target as Node)) {
// Prevent focus loss // Prevent focus loss
e.preventDefault(); mouseEvent.preventDefault();
e.stopPropagation(); mouseEvent.stopPropagation();
} }
}); });
this.shadowRoot?.addEventListener('click', (e: MouseEvent) => { this.shadowRoot!.addEventListener('click', (e: Event) => {
const target = e.target as HTMLElement; const mouseEvent = e as MouseEvent;
const target = mouseEvent.target as HTMLElement;
const button = target.closest('.format-button') as HTMLElement; const button = target.closest('.format-button') as HTMLElement;
if (button) { if (button) {
e.preventDefault(); mouseEvent.preventDefault();
e.stopPropagation(); mouseEvent.stopPropagation();
const command = button.getAttribute('data-command'); const command = button.getAttribute('data-command');
if (command) { if (command) {
@@ -212,12 +214,13 @@ export class DeesFormattingMenu extends DeesElement {
} }
}); });
this.shadowRoot?.addEventListener('focus', (e: FocusEvent) => { this.shadowRoot!.addEventListener('focus', (e: Event) => {
const focusEvent = e as FocusEvent;
const menu = this.shadowRoot?.querySelector('.formatting-menu'); const menu = this.shadowRoot?.querySelector('.formatting-menu');
if (menu && menu.contains(e.target as Node)) { if (menu && menu.contains(focusEvent.target as Node)) {
// Prevent menu from taking focus // Prevent menu from taking focus
e.preventDefault(); focusEvent.preventDefault();
e.stopPropagation(); focusEvent.stopPropagation();
} }
}, true); // Use capture phase }, true); // Use capture phase
} }

View File

@@ -77,7 +77,7 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
@state() @state()
accessor selectedText: string = ''; accessor selectedText: string = '';
public editorContentRef: HTMLDivElement; public editorContentRef!: HTMLDivElement;
public isComposing: boolean = false; public isComposing: boolean = false;
// Handler instances // Handler instances
@@ -144,7 +144,7 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
// No global selection listener needed // No global selection listener needed
// Listen for custom selection events from blocks // Listen for custom selection events from blocks
this.addEventListener('block-text-selected', (e: CustomEvent) => { this.addEventListener('block-text-selected', ((e: CustomEvent) => {
if (!this.slashMenu.visible && e.detail.hasSelection && e.detail.text.length > 0) { if (!this.slashMenu.visible && e.detail.hasSelection && e.detail.text.length > 0) {
this.selectedText = e.detail.text; this.selectedText = e.detail.text;
@@ -164,7 +164,7 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
); );
} }
} }
}); }) as EventListener);
// Hide formatting menu when clicking outside // Hide formatting menu when clicking outside
document.addEventListener('mousedown', (e) => { document.addEventListener('mousedown', (e) => {
@@ -896,14 +896,14 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
{ {
name: 'Cancel', name: 'Cancel',
action: async (modal) => { action: async (modal) => {
modal.destroy(); modal!.destroy();
resolve(null); resolve(null);
} }
}, },
{ {
name: 'Add Link', name: 'Add Link',
action: async (modal) => { action: async (modal) => {
modal.destroy(); modal!.destroy();
resolve(linkUrl); resolve(linkUrl);
} }
} }

View File

@@ -216,22 +216,24 @@ export class DeesSlashMenu extends DeesElement {
public firstUpdated(): void { public firstUpdated(): void {
// Set up event delegation // Set up event delegation
this.shadowRoot?.addEventListener('mousedown', (e: MouseEvent) => { this.shadowRoot!.addEventListener('mousedown', (e: Event) => {
const mouseEvent = e as MouseEvent;
const menu = this.shadowRoot?.querySelector('.slash-menu'); const menu = this.shadowRoot?.querySelector('.slash-menu');
if (menu && menu.contains(e.target as Node)) { if (menu && menu.contains(mouseEvent.target as Node)) {
// Prevent focus loss // Prevent focus loss
e.preventDefault(); mouseEvent.preventDefault();
e.stopPropagation(); mouseEvent.stopPropagation();
} }
}); });
this.shadowRoot?.addEventListener('click', (e: MouseEvent) => { this.shadowRoot!.addEventListener('click', (e: Event) => {
const target = e.target as HTMLElement; const mouseEvent = e as MouseEvent;
const target = mouseEvent.target as HTMLElement;
const menuItem = target.closest('.slash-menu-item') as HTMLElement; const menuItem = target.closest('.slash-menu-item') as HTMLElement;
if (menuItem) { if (menuItem) {
e.preventDefault(); mouseEvent.preventDefault();
e.stopPropagation(); mouseEvent.stopPropagation();
const itemType = menuItem.getAttribute('data-item-type'); const itemType = menuItem.getAttribute('data-item-type');
if (itemType) { if (itemType) {
@@ -240,8 +242,9 @@ export class DeesSlashMenu extends DeesElement {
} }
}); });
this.shadowRoot?.addEventListener('mouseenter', (e: MouseEvent) => { this.shadowRoot!.addEventListener('mouseenter', (e: Event) => {
const target = e.target as HTMLElement; const mouseEvent = e as MouseEvent;
const target = mouseEvent.target as HTMLElement;
const menuItem = target.closest('.slash-menu-item') as HTMLElement; const menuItem = target.closest('.slash-menu-item') as HTMLElement;
if (menuItem) { if (menuItem) {
@@ -250,12 +253,13 @@ export class DeesSlashMenu extends DeesElement {
} }
}, true); // Use capture phase }, true); // Use capture phase
this.shadowRoot?.addEventListener('focus', (e: FocusEvent) => { this.shadowRoot!.addEventListener('focus', (e: Event) => {
const focusEvent = e as FocusEvent;
const menu = this.shadowRoot?.querySelector('.slash-menu'); const menu = this.shadowRoot?.querySelector('.slash-menu');
if (menu && menu.contains(e.target as Node)) { if (menu && menu.contains(focusEvent.target as Node)) {
// Prevent menu from taking focus // Prevent menu from taking focus
e.preventDefault(); focusEvent.preventDefault();
e.stopPropagation(); focusEvent.stopPropagation();
} }
}, true); // Use capture phase }, true); // Use capture phase
} }

View File

@@ -33,13 +33,13 @@ export class DeesWysiwygBlock extends DeesElement {
} }
} }
@property({ type: Object }) @property({ type: Object })
accessor block: IBlock; accessor block!: IBlock;
@property({ type: Boolean }) @property({ type: Boolean })
accessor isSelected: boolean = false; accessor isSelected: boolean = false;
@property({ type: Object }) @property({ type: Object })
accessor handlers: IBlockEventHandlers; accessor handlers!: IBlockEventHandlers;
@property({ type: Object }) @property({ type: Object })
accessor wysiwygComponent: any; // Reference to parent dees-input-wysiwyg accessor wysiwygComponent: any; // Reference to parent dees-input-wysiwyg

View File

@@ -105,10 +105,10 @@ export class WysiwygDragDropHandler {
handleDragEnd(): void { handleDragEnd(): void {
// Clean up visual state // Clean up visual state
const allBlocks = this.component.editorContentRef.querySelectorAll('.block-wrapper'); const allBlocks = this.component.editorContentRef.querySelectorAll('.block-wrapper');
allBlocks.forEach((block: HTMLElement) => { allBlocks.forEach((block) => {
block.classList.remove('dragging', 'move-up', 'move-down'); (block as HTMLElement).classList.remove('dragging', 'move-up', 'move-down');
block.style.removeProperty('--drag-offset'); (block as HTMLElement).style.removeProperty('--drag-offset');
block.style.removeProperty('transform'); (block as HTMLElement).style.removeProperty('transform');
}); });
// Remove dragging class from editor // Remove dragging class from editor

View File

@@ -704,9 +704,9 @@ export class WysiwygKeyboardHandler {
const rect = range.getBoundingClientRect(); const rect = range.getBoundingClientRect();
// Get the container element // Get the container element
let container = range.commonAncestorContainer; let container: Node = range.commonAncestorContainer;
if (container.nodeType === Node.TEXT_NODE) { if (container.nodeType === Node.TEXT_NODE) {
container = container.parentElement; container = container.parentElement!;
} }
// Get the top position of the container // Get the top position of the container
@@ -740,9 +740,9 @@ export class WysiwygKeyboardHandler {
const rect = range.getBoundingClientRect(); const rect = range.getBoundingClientRect();
// Get the container element // Get the container element
let container = range.commonAncestorContainer; let container: Node = range.commonAncestorContainer;
if (container.nodeType === Node.TEXT_NODE) { if (container.nodeType === Node.TEXT_NODE) {
container = container.parentElement; container = container.parentElement!;
} }
// Get the bottom position of the container // Get the bottom position of the container

View File

@@ -72,7 +72,7 @@ export class WysiwygModalManager {
{ {
name: 'Cancel', name: 'Cancel',
action: async (modal) => { action: async (modal) => {
modal.destroy(); modal!.destroy();
resolve(null); resolve(null);
} }
} }
@@ -158,7 +158,7 @@ export class WysiwygModalManager {
{ {
name: 'Done', name: 'Done',
action: async (modal) => { action: async (modal) => {
modal.destroy(); modal!.destroy();
} }
} }
] ]

View File

@@ -56,10 +56,10 @@ export const demoFunc = () => html`
const roundProfile = elementArg.querySelector('dees-input-profilepicture[shape="round"]'); const roundProfile = elementArg.querySelector('dees-input-profilepicture[shape="round"]');
if (roundProfile) { if (roundProfile) {
roundProfile.addEventListener('change', (event: CustomEvent) => { roundProfile.addEventListener('change', ((event: CustomEvent) => {
const target = event.target as DeesInputProfilePicture; const target = event.target as DeesInputProfilePicture;
console.log('Round profile picture changed:', target.value?.substring(0, 50) + '...'); console.log('Round profile picture changed:', target.value?.substring(0, 50) + '...');
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'Profile Picture Input'} .subtitle=${'Basic usage with round and square shapes'}> <dees-panel .title=${'Profile Picture Input'} .subtitle=${'Basic usage with round and square shapes'}>
@@ -85,10 +85,10 @@ export const demoFunc = () => html`
// Different sizes demo // Different sizes demo
const profiles = elementArg.querySelectorAll('dees-input-profilepicture'); const profiles = elementArg.querySelectorAll('dees-input-profilepicture');
profiles.forEach((profile) => { profiles.forEach((profile) => {
profile.addEventListener('change', (event: CustomEvent) => { profile.addEventListener('change', ((event: CustomEvent) => {
const target = event.target as DeesInputProfilePicture; const target = event.target as DeesInputProfilePicture;
console.log(`Profile (size ${target.size}) changed`); console.log(`Profile (size ${target.size}) changed`);
}); }) as EventListener);
}); });
}}> }}>
<dees-panel .title=${'Size Variations'} .subtitle=${'Profile pictures in different sizes'}> <dees-panel .title=${'Size Variations'} .subtitle=${'Profile pictures in different sizes'}>
@@ -122,7 +122,7 @@ export const demoFunc = () => html`
if (prefilledProfile) { if (prefilledProfile) {
prefilledProfile.value = sampleImageUrl; prefilledProfile.value = sampleImageUrl;
prefilledProfile.addEventListener('change', (event: CustomEvent) => { prefilledProfile.addEventListener('change', ((event: CustomEvent) => {
const target = event.target as DeesInputProfilePicture; const target = event.target as DeesInputProfilePicture;
const output = elementArg.querySelector('#prefilled-output'); const output = elementArg.querySelector('#prefilled-output');
if (output) { if (output) {
@@ -130,7 +130,7 @@ export const demoFunc = () => html`
`Image data: ${target.value.substring(0, 80)}...` : `Image data: ${target.value.substring(0, 80)}...` :
'No image selected'; 'No image selected';
} }
}); }) as EventListener);
} }
}}> }}>
<dees-panel .title=${'Pre-filled and Value Binding'} .subtitle=${'Profile picture with initial value and change tracking'}> <dees-panel .title=${'Pre-filled and Value Binding'} .subtitle=${'Profile picture with initial value and change tracking'}>

View File

@@ -436,10 +436,10 @@ export class DeesInputProfilePicture extends DeesInputBase<DeesInputProfilePictu
this.modalInstance.outputSize = this.outputSize; this.modalInstance.outputSize = this.outputSize;
this.modalInstance.outputQuality = this.outputQuality; this.modalInstance.outputQuality = this.outputQuality;
this.modalInstance.addEventListener('save', (event: CustomEvent) => { this.modalInstance.addEventListener('save', ((event: CustomEvent) => {
this.value = event.detail.croppedImage; this.value = event.detail.croppedImage;
this.changeSubject.next(this); this.changeSubject.next(this);
}); }) as EventListener);
document.body.appendChild(this.modalInstance); document.body.appendChild(this.modalInstance);
} }

View File

@@ -41,7 +41,7 @@ export class DeesChips extends DeesElement {
accessor selectableChips: Tag[] = []; accessor selectableChips: Tag[] = [];
@property() @property()
accessor selectedChip: Tag = null; accessor selectedChip: Tag | null = null;
@property({ @property({
type: Array, type: Array,

View File

@@ -1,5 +1,6 @@
import { html, css, cssManager } from '@design.estate/dees-element'; import { html, css, cssManager } from '@design.estate/dees-element';
import type { DeesDashboardgrid } from './dees-dashboardgrid.js'; import type { DeesDashboardgrid } from './dees-dashboardgrid.js';
import type { LayoutDirection } from './types.js';
import '@design.estate/dees-wcctools/demotools'; import '@design.estate/dees-wcctools/demotools';
export const demoFunc = () => { export const demoFunc = () => {
@@ -160,7 +161,7 @@ export const demoFunc = () => {
}); });
// Enhanced logging for reflow events // Enhanced logging for reflow events
let lastPlaceholderPosition = null; let lastPlaceholderPosition: Record<string, string> | null = null;
let moveEventCounter = 0; let moveEventCounter = 0;
// Helper function to log grid state // Helper function to log grid state
@@ -231,25 +232,28 @@ export const demoFunc = () => {
// Log initial state // Log initial state
logGridState('Initial Grid State'); logGridState('Initial Grid State');
grid.addEventListener('widget-move', (e: CustomEvent) => { grid.addEventListener('widget-move', (e: Event) => {
const detail = (e as CustomEvent).detail;
logGridState('Widget Move', { logGridState('Widget Move', {
widget: e.detail.widget, widget: detail.widget,
displaced: e.detail.displaced, displaced: detail.displaced,
swappedWith: e.detail.swappedWith swappedWith: detail.swappedWith
}); });
}); });
grid.addEventListener('widget-resize', (e: CustomEvent) => { grid.addEventListener('widget-resize', (e: Event) => {
const detail = (e as CustomEvent).detail;
logGridState('Widget Resize', { logGridState('Widget Resize', {
widget: e.detail.widget, widget: detail.widget,
displaced: e.detail.displaced, displaced: detail.displaced,
swappedWith: e.detail.swappedWith swappedWith: detail.swappedWith
}); });
}); });
grid.addEventListener('widget-remove', (e: CustomEvent) => { grid.addEventListener('widget-remove', (e: Event) => {
const detail = (e as CustomEvent).detail;
logGridState('Widget Remove', { logGridState('Widget Remove', {
removedWidget: e.detail.widget removedWidget: detail.widget
}); });
updateStatus(); updateStatus();
}); });
@@ -312,7 +316,7 @@ export const demoFunc = () => {
// Log compact operations // Log compact operations
const originalCompact = grid.compact.bind(grid); const originalCompact = grid.compact.bind(grid);
grid.compact = (direction?: string) => { grid.compact = (direction?: LayoutDirection) => {
console.group('🗜️ Compacting Grid'); console.group('🗜️ Compacting Grid');
console.log('Direction:', direction || 'vertical'); console.log('Direction:', direction || 'vertical');
logGridState('Before Compact'); logGridState('Before Compact');

View File

@@ -32,7 +32,7 @@ export class DeesLabel extends DeesElement {
type: String, type: String,
reflect: true, reflect: true,
}) })
accessor description: string; accessor description!: string;
@property({ @property({
type: Boolean, type: Boolean,

View File

@@ -45,7 +45,7 @@ export class DeesStepper extends DeesElement {
@property({ @property({
type: Object, type: Object,
}) })
accessor selectedStep: IStep; accessor selectedStep!: IStep;
constructor() { constructor() {
super(); super();
@@ -214,19 +214,19 @@ export class DeesStepper extends DeesElement {
this.setScrollStatus(); this.setScrollStatus();
// Remove entrance class after initial animation completes // Remove entrance class after initial animation completes
await this.domtools.convenience.smartdelay.delayFor(350); await this.domtools.convenience.smartdelay.delayFor(350);
this.shadowRoot.querySelector('.step.entrance')?.classList.remove('entrance'); this.shadowRoot!.querySelector('.step.entrance')?.classList.remove('entrance');
} }
public async updated() { public async updated() {
this.setScrollStatus(); this.setScrollStatus();
} }
public scroller: typeof domtools.plugins.SweetScroll.prototype; public scroller!: typeof domtools.plugins.SweetScroll.prototype;
public async setScrollStatus() { public async setScrollStatus() {
const stepperContainer: HTMLElement = this.shadowRoot.querySelector('.stepperContainer'); const stepperContainer = this.shadowRoot!.querySelector('.stepperContainer') as HTMLElement;
const firstStepElement: HTMLElement = this.shadowRoot.querySelector('.step'); const firstStepElement = this.shadowRoot!.querySelector('.step') as HTMLElement;
const selectedStepElement: HTMLElement = this.shadowRoot.querySelector('.selected'); const selectedStepElement = this.shadowRoot!.querySelector('.selected') as HTMLElement;
if (!selectedStepElement) { if (!selectedStepElement) {
return; return;
} }
@@ -278,7 +278,7 @@ export class DeesStepper extends DeesElement {
this.selectedStep = previousStep; this.selectedStep = previousStep;
await this.domtoolsPromise; await this.domtoolsPromise;
await this.domtools.convenience.smartdelay.delayFor(100); await this.domtools.convenience.smartdelay.delayFor(100);
this.selectedStep.onReturnToStepFunc?.(this, this.shadowRoot.querySelector('.selected')); this.selectedStep.onReturnToStepFunc?.(this, this.shadowRoot!.querySelector('.selected') as HTMLElement);
} }
public goNext() { public goNext() {

View File

@@ -21,9 +21,9 @@ export function throttle<T extends (...args: any[]) => any>(
): (...args: Parameters<T>) => void { ): (...args: Parameters<T>) => void {
let inThrottle: boolean; let inThrottle: boolean;
return function executedFunction(...args: Parameters<T>) { return (...args: Parameters<T>) => {
if (!inThrottle) { if (!inThrottle) {
func.apply(this, args); func(...args);
inThrottle = true; inThrottle = true;
setTimeout(() => inThrottle = false, limit); setTimeout(() => inThrottle = false, limit);
} }

View File

@@ -7,7 +7,7 @@ export const demo = () => {
]; ];
const generateGridItems = (count: number) => { const generateGridItems = (count: number) => {
const items = []; const items: ReturnType<typeof html>[] = [];
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
const pdfUrl = samplePdfs[i % samplePdfs.length]; const pdfUrl = samplePdfs[i % samplePdfs.length];
items.push(html` items.push(html`

View File

@@ -130,7 +130,7 @@ export class DeesContextmenu extends DeesElement {
type: Array, type: Array,
}) })
accessor menuItems: (plugins.tsclass.website.IMenuItem & { shortcut?: string; disabled?: boolean; submenu?: (plugins.tsclass.website.IMenuItem & { shortcut?: string; disabled?: boolean } | { divider: true })[]; divider?: never } | { divider: true })[] = []; accessor menuItems: (plugins.tsclass.website.IMenuItem & { shortcut?: string; disabled?: boolean; submenu?: (plugins.tsclass.website.IMenuItem & { shortcut?: string; disabled?: boolean } | { divider: true })[]; divider?: never } | { divider: true })[] = [];
windowLayer: DeesWindowLayer; windowLayer!: DeesWindowLayer;
private submenu: DeesContextmenu | null = null; private submenu: DeesContextmenu | null = null;
private submenuTimeout: any = null; private submenuTimeout: any = null;
@@ -278,7 +278,7 @@ export class DeesContextmenu extends DeesElement {
} }
private handleKeydown = (event: KeyboardEvent) => { private handleKeydown = (event: KeyboardEvent) => {
const menuItems = Array.from(this.shadowRoot.querySelectorAll('.menuitem:not(.disabled)')); const menuItems = Array.from(this.shadowRoot!.querySelectorAll('.menuitem:not(.disabled)'));
const currentIndex = menuItems.findIndex(item => item.matches(':hover')); const currentIndex = menuItems.findIndex(item => item.matches(':hover'));
switch (event.key) { switch (event.key) {
@@ -352,7 +352,7 @@ export class DeesContextmenu extends DeesElement {
if (!menuItem.submenu || menuItem.submenu.length === 0) return; if (!menuItem.submenu || menuItem.submenu.length === 0) return;
// Find the menu item element // Find the menu item element
const menuItems = Array.from(this.shadowRoot.querySelectorAll('.menuitem')); const menuItems = Array.from(this.shadowRoot!.querySelectorAll('.menuitem'));
const menuItemElement = menuItems.find(el => el.querySelector('.menuitem-text')?.textContent === menuItem.name) as HTMLElement; const menuItemElement = menuItems.find(el => el.querySelector('.menuitem-text')?.textContent === menuItem.name) as HTMLElement;
if (!menuItemElement) return; if (!menuItemElement) return;

View File

@@ -49,7 +49,7 @@ export const demoFunc = () => html`
heading: 'With Help Button', heading: 'With Help Button',
showHelpButton: true, showHelpButton: true,
onHelp: async () => { onHelp: async () => {
const helpModal = await DeesModal.createAndShow({ await DeesModal.createAndShow({
heading: 'Help', heading: 'Help',
width: 'small', width: 'small',
showCloseButton: true, showCloseButton: true,
@@ -60,7 +60,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Got it', name: 'Got it',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}, },
@@ -70,7 +70,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'OK', name: 'OK',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>With Help Button</dees-button> }}>With Help Button</dees-button>
@@ -85,7 +85,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Close', name: 'Close',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>No Close Button</dees-button> }}>No Close Button</dees-button>
@@ -101,7 +101,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Done', name: 'Done',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Both Buttons</dees-button> }}>Both Buttons</dees-button>
@@ -116,7 +116,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Close', name: 'Close',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Clean Header</dees-button> }}>Clean Header</dees-button>
@@ -136,10 +136,10 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Cancel', name: 'Cancel',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}, { }, {
name: 'OK', name: 'OK',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Small Modal</dees-button> }}>Small Modal</dees-button>
@@ -157,10 +157,10 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Cancel', name: 'Cancel',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}, { }, {
name: 'Sign Up', name: 'Sign Up',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Medium Modal</dees-button> }}>Medium Modal</dees-button>
@@ -181,10 +181,10 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Cancel', name: 'Cancel',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}, { }, {
name: 'Save', name: 'Save',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Large Modal</dees-button> }}>Large Modal</dees-button>
@@ -207,10 +207,10 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Save', name: 'Save',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}, { }, {
name: 'Cancel', name: 'Cancel',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Fullscreen Modal</dees-button> }}>Fullscreen Modal</dees-button>
@@ -230,7 +230,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Close', name: 'Close',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Custom 700px</dees-button> }}>Custom 700px</dees-button>
@@ -245,7 +245,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Got it', name: 'Got it',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Max Width 600px</dees-button> }}>Max Width 600px</dees-button>
@@ -260,7 +260,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'OK', name: 'OK',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Min Width 400px</dees-button> }}>Min Width 400px</dees-button>
@@ -279,13 +279,13 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Delete', name: 'Delete',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}, { }, {
name: 'Cancel', name: 'Cancel',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}, { }, {
name: 'Save Changes', name: 'Save Changes',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Three Buttons</dees-button> }}>Three Buttons</dees-button>
@@ -298,7 +298,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Acknowledge', name: 'Acknowledge',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Single Button</dees-button> }}>Single Button</dees-button>
@@ -322,10 +322,10 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Discard All Changes', name: 'Discard All Changes',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}, { }, {
name: 'Save and Continue Editing', name: 'Save and Continue Editing',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Long Labels</dees-button> }}>Long Labels</dees-button>
@@ -347,7 +347,7 @@ export const demoFunc = () => html`
`, `,
menuOptions: [{ menuOptions: [{
name: 'Close', name: 'Close',
action: async (modal) => modal.destroy() action: async (modal) => modal!.destroy()
}], }],
}); });
}}>Test Responsive</dees-button> }}>Test Responsive</dees-button>

View File

@@ -85,7 +85,7 @@ export class DeesModal extends DeesElement {
accessor heading = ''; accessor heading = '';
@state({}) @state({})
accessor content: TemplateResult; accessor content!: TemplateResult;
@state({}) @state({})
accessor menuOptions: plugins.tsclass.website.IMenuItem<DeesModal>[] = []; accessor menuOptions: plugins.tsclass.website.IMenuItem<DeesModal>[] = [];
@@ -94,10 +94,10 @@ export class DeesModal extends DeesElement {
accessor width: 'small' | 'medium' | 'large' | 'fullscreen' | number = 'medium'; accessor width: 'small' | 'medium' | 'large' | 'fullscreen' | number = 'medium';
@property({ type: Number }) @property({ type: Number })
accessor maxWidth: number; accessor maxWidth!: number;
@property({ type: Number }) @property({ type: Number })
accessor minWidth: number; accessor minWidth!: number;
@property({ type: Boolean }) @property({ type: Boolean })
accessor showCloseButton: boolean = true; accessor showCloseButton: boolean = true;
@@ -106,7 +106,7 @@ export class DeesModal extends DeesElement {
accessor showHelpButton: boolean = false; accessor showHelpButton: boolean = false;
@property({ attribute: false }) @property({ attribute: false })
accessor onHelp: () => void | Promise<void>; accessor onHelp!: () => void | Promise<void>;
@property({ type: Boolean }) @property({ type: Boolean })
accessor mobileFullscreen: boolean = false; accessor mobileFullscreen: boolean = false;
@@ -383,18 +383,18 @@ export class DeesModal extends DeesElement {
`; `;
} }
private windowLayer: DeesWindowLayer; private windowLayer!: DeesWindowLayer;
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) { public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
super.firstUpdated(_changedProperties); super.firstUpdated(_changedProperties);
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
await domtools.convenience.smartdelay.delayFor(30); await domtools.convenience.smartdelay.delayFor(30);
const modal = this.shadowRoot.querySelector('.modal'); const modal = this.shadowRoot!.querySelector('.modal');
modal.classList.add('show'); modal!.classList.add('show');
} }
public async handleOutsideClick(eventArg: MouseEvent) { public async handleOutsideClick(eventArg: MouseEvent) {
eventArg.stopPropagation(); eventArg.stopPropagation();
const modalContainer = this.shadowRoot.querySelector('.modalContainer'); const modalContainer = this.shadowRoot!.querySelector('.modalContainer');
if (eventArg.target === modalContainer) { if (eventArg.target === modalContainer) {
await this.destroy(); await this.destroy();
} }
@@ -402,8 +402,8 @@ export class DeesModal extends DeesElement {
public async destroy() { public async destroy() {
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
const modal = this.shadowRoot.querySelector('.modal'); const modal = this.shadowRoot!.querySelector('.modal');
modal.classList.add('predestroy'); modal!.classList.add('predestroy');
await domtools.convenience.smartdelay.delayFor(200); await domtools.convenience.smartdelay.delayFor(200);
document.body.removeChild(this); document.body.removeChild(this);
await this.windowLayer.destroy(); await this.windowLayer.destroy();

View File

@@ -42,7 +42,7 @@ export class DeesSpeechbubble extends DeesElement {
speechbubble.manifested = true; speechbubble.manifested = true;
windowLayer.appendChild(speechbubble); windowLayer.appendChild(speechbubble);
windowLayer.style.pointerEvents = 'none'; windowLayer.style.pointerEvents = 'none';
(windowLayer.shadowRoot.querySelector('.windowOverlay') as HTMLElement).style.pointerEvents = 'none'; (windowLayer.shadowRoot!.querySelector('.windowOverlay') as HTMLElement).style.pointerEvents = 'none';
return speechbubble; return speechbubble;
} }
@@ -50,13 +50,13 @@ export class DeesSpeechbubble extends DeesElement {
@property({ @property({
type: Object, type: Object,
}) })
accessor reffedElement: HTMLElement; accessor reffedElement!: HTMLElement;
@property({ @property({
type: String, type: String,
reflect: true, reflect: true,
}) })
accessor text: string; accessor text!: string;
@property({ @property({
type: Boolean, type: Boolean,
@@ -73,7 +73,7 @@ export class DeesSpeechbubble extends DeesElement {
}) })
accessor status: 'normal' | 'pending' | 'success' | 'error' = 'normal'; accessor status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
public windowLayer: DeesWindowLayer; public windowLayer!: DeesWindowLayer;
constructor() { constructor() {
super(); super();
@@ -189,7 +189,7 @@ export class DeesSpeechbubble extends DeesElement {
} }
if (this.manifested) { if (this.manifested) {
await this.updatePosition(); await this.updatePosition();
(this.shadowRoot.querySelector('.maincontainer') as HTMLElement).style.opacity = '1'; (this.shadowRoot!.querySelector('.maincontainer') as HTMLElement).style.opacity = '1';
} else { } else {
// lets make sure we instrument it // lets make sure we instrument it
let speechbubble: DeesSpeechbubble; let speechbubble: DeesSpeechbubble;
@@ -227,7 +227,7 @@ export class DeesSpeechbubble extends DeesElement {
public async show() {} public async show() {}
public async destroy() { public async destroy() {
(this.shadowRoot.querySelector('.maincontainer') as HTMLElement).style.opacity = '0'; (this.shadowRoot!.querySelector('.maincontainer') as HTMLElement).style.opacity = '0';
this.windowLayer.destroy(); this.windowLayer.destroy();
} }
} }

View File

@@ -132,7 +132,7 @@ export class WebContainerEnvironment implements IExecutionEnvironment {
const watcher = this.container!.fs.watch( const watcher = this.container!.fs.watch(
path, path,
{ recursive: options?.recursive ?? false }, { recursive: options?.recursive ?? false },
callback callback as (event: 'rename' | 'change', filename: string | Uint8Array) => void
); );
return { return {
stop: () => watcher.close(), stop: () => watcher.close(),

View File

@@ -109,14 +109,14 @@ export const demoFunc = () => html`
<dees-panel .title=${'Interactive Shopping Cart'} .subtitle=${'Product cards with dynamic cart calculation'} .runAfterRender=${async (elementArg: HTMLElement) => { <dees-panel .title=${'Interactive Shopping Cart'} .subtitle=${'Product cards with dynamic cart calculation'} .runAfterRender=${async (elementArg: HTMLElement) => {
const products = [ const products = [
{ id: 'laptop', element: null, data: { name: 'MacBook Pro 14"', category: 'Computers', description: 'M3 Pro chip with 18GB RAM', price: 1999, originalPrice: 2199, iconName: 'lucide:laptop' }}, { id: 'laptop', element: null as DeesShoppingProductcard | null, data: { name: 'MacBook Pro 14"', category: 'Computers', description: 'M3 Pro chip with 18GB RAM', price: 1999, originalPrice: 2199, iconName: 'lucide:laptop' }},
{ id: 'ipad', element: null, data: { name: 'iPad Air', category: 'Tablets', description: '10.9" Liquid Retina display', price: 599, iconName: 'lucide:tablet' }}, { id: 'ipad', element: null as DeesShoppingProductcard | null, data: { name: 'iPad Air', category: 'Tablets', description: '10.9" Liquid Retina display', price: 599, iconName: 'lucide:tablet' }},
{ id: 'keyboard', element: null, data: { name: 'Magic Keyboard', category: 'Accessories', description: 'Wireless keyboard with Touch ID', price: 149, iconName: 'lucide:keyboard' }} { id: 'keyboard', element: null as DeesShoppingProductcard | null, data: { name: 'Magic Keyboard', category: 'Accessories', description: 'Wireless keyboard with Touch ID', price: 149, iconName: 'lucide:keyboard' }}
]; ];
const updateCartSummary = () => { const updateCartSummary = () => {
let total = 0; let total = 0;
const items = []; const items: string[] = [];
products.forEach(product => { products.forEach(product => {
const element = elementArg.querySelector(`#${product.id}`) as DeesShoppingProductcard; const element = elementArg.querySelector(`#${product.id}`) as DeesShoppingProductcard;
@@ -216,8 +216,8 @@ export const demoFunc = () => html`
const output = document.querySelector('#selection-output'); const output = document.querySelector('#selection-output');
if (output) { if (output) {
const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]'); const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]');
const selectedProducts = []; const selectedProducts: string[] = [];
selectedCards.forEach((card: DeesShoppingProductcard) => { (selectedCards as NodeListOf<DeesShoppingProductcard>).forEach((card) => {
if (card.selected) { if (card.selected) {
selectedProducts.push(card.productData.name); selectedProducts.push(card.productData.name);
} }
@@ -243,8 +243,8 @@ export const demoFunc = () => html`
const output = document.querySelector('#selection-output'); const output = document.querySelector('#selection-output');
if (output) { if (output) {
const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]'); const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]');
const selectedProducts = []; const selectedProducts: string[] = [];
selectedCards.forEach((card: DeesShoppingProductcard) => { (selectedCards as NodeListOf<DeesShoppingProductcard>).forEach((card) => {
if (card.selected) { if (card.selected) {
selectedProducts.push(card.productData.name); selectedProducts.push(card.productData.name);
} }
@@ -271,8 +271,8 @@ export const demoFunc = () => html`
const output = document.querySelector('#selection-output'); const output = document.querySelector('#selection-output');
if (output) { if (output) {
const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]'); const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]');
const selectedProducts = []; const selectedProducts: string[] = [];
selectedCards.forEach((card: DeesShoppingProductcard) => { (selectedCards as NodeListOf<DeesShoppingProductcard>).forEach((card) => {
if (card.selected) { if (card.selected) {
selectedProducts.push(card.productData.name); selectedProducts.push(card.productData.name);
} }

View File

@@ -46,7 +46,7 @@ export class DeesSimpleAppDash extends DeesElement {
accessor terminalSetupCommand: string = `echo "Terminal ready"`; accessor terminalSetupCommand: string = `echo "Terminal ready"`;
@state() @state()
accessor selectedView: IView; accessor selectedView!: IView;
public static styles = [ public static styles = [
@@ -386,7 +386,7 @@ export class DeesSimpleAppDash extends DeesElement {
`; `;
} }
public async firstUpdated(_changedProperties): Promise<void> { public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>): Promise<void> {
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
super.firstUpdated(_changedProperties); super.firstUpdated(_changedProperties);
if (this.viewTabs && this.viewTabs.length > 0) { if (this.viewTabs && this.viewTabs.length > 0) {
@@ -395,7 +395,7 @@ export class DeesSimpleAppDash extends DeesElement {
} }
} }
public currentTerminal: DeesWorkspaceTerminal; public currentTerminal: DeesWorkspaceTerminal | null = null;
public async launchTerminal() { public async launchTerminal() {
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
if (this.currentTerminal) { if (this.currentTerminal) {
@@ -404,7 +404,7 @@ export class DeesSimpleAppDash extends DeesElement {
return; return;
} }
const maincontainer = this.shadowRoot.querySelector('.maincontainer'); const maincontainer = this.shadowRoot!.querySelector('.maincontainer')! as HTMLElement;
const { DeesWorkspaceTerminal } = await import('../../00group-workspace/dees-workspace-terminal/dees-workspace-terminal.js'); const { DeesWorkspaceTerminal } = await import('../../00group-workspace/dees-workspace-terminal/dees-workspace-terminal.js');
const terminal = new DeesWorkspaceTerminal(); const terminal = new DeesWorkspaceTerminal();
terminal.setupCommand = this.terminalSetupCommand; terminal.setupCommand = this.terminalSetupCommand;
@@ -444,9 +444,9 @@ export class DeesSimpleAppDash extends DeesElement {
} }
private currentView: DeesElement; private currentView!: DeesElement;
public async loadView(viewArg: IView) { public async loadView(viewArg: IView) {
const appcontent = this.shadowRoot.querySelector('.appcontent'); const appcontent = this.shadowRoot!.querySelector('.appcontent')!;
const view = new viewArg.element(); const view = new viewArg.element();
if (this.currentView) { if (this.currentView) {
this.currentView.remove(); this.currentView.remove();

View File

@@ -141,15 +141,15 @@ export class DeesSimpleLogin extends DeesElement {
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>): Promise<void> { public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>): Promise<void> {
super.firstUpdated(_changedProperties); super.firstUpdated(_changedProperties);
const form = this.shadowRoot.querySelector('dees-form') as any; const form = this.shadowRoot!.querySelector('dees-form') as any;
if (form) { if (form) {
form.addEventListener('formData', (event: CustomEvent) => { form.addEventListener('formData', ((event: CustomEvent) => {
this.dispatchEvent(new CustomEvent('login', { this.dispatchEvent(new CustomEvent('login', {
detail: event.detail, detail: event.detail,
bubbles: true, bubbles: true,
composed: true composed: true
})); }));
}); }) as EventListener);
} }
} }
@@ -158,9 +158,9 @@ export class DeesSimpleLogin extends DeesElement {
*/ */
public async switchToSlottedContent() { public async switchToSlottedContent() {
const domtools = await this.domtoolsPromise; const domtools = await this.domtoolsPromise;
const loginDiv: HTMLDivElement = this.shadowRoot.querySelector('.login'); const loginDiv = this.shadowRoot!.querySelector('.login') as HTMLDivElement;
const loginContainerDiv: HTMLDivElement = this.shadowRoot.querySelector('.loginContainer'); const loginContainerDiv = this.shadowRoot!.querySelector('.loginContainer') as HTMLDivElement;
const slotContainerDiv: HTMLDivElement = this.shadowRoot.querySelector('.slotContainer'); const slotContainerDiv = this.shadowRoot!.querySelector('.slotContainer') as HTMLDivElement;
loginDiv.style.opacity = '0'; loginDiv.style.opacity = '0';
loginDiv.style.transform = 'translateY(20px)'; loginDiv.style.transform = 'translateY(20px)';
loginContainerDiv.style.pointerEvents = 'none'; loginContainerDiv.style.pointerEvents = 'none';

View File

@@ -15,7 +15,7 @@ export const demoFunc = () => {
.filter(key => { .filter(key => {
// Skip utility functions and focus on icon components (first letter is uppercase) // Skip utility functions and focus on icon components (first letter is uppercase)
const isUppercaseFirst = key[0] === key[0].toUpperCase() && key[0] !== key[0].toLowerCase(); const isUppercaseFirst = key[0] === key[0].toUpperCase() && key[0] !== key[0].toLowerCase();
const isFunction = typeof lucideIcons[key] === 'function'; const isFunction = typeof (lucideIcons as any)[key] === 'function';
const notUtility = !['createElement', 'createIcons', 'default'].includes(key); const notUtility = !['createElement', 'createIcons', 'default'].includes(key);
return isFunction && isUppercaseFirst && notUtility; return isFunction && isUppercaseFirst && notUtility;
}) })
@@ -63,7 +63,7 @@ export const demoFunc = () => {
const searchIcons = (event: InputEvent) => { const searchIcons = (event: InputEvent) => {
const searchTerm = (event.target as HTMLInputElement).value.toLowerCase().trim(); const searchTerm = (event.target as HTMLInputElement).value.toLowerCase().trim();
// Get the demo container first, then search within it // Get the demo container first, then search within it
const demoContainer = (event.target as HTMLElement).closest('.demoContainer'); const demoContainer = (event.target as HTMLElement).closest('.demoContainer')!;
const containers = demoContainer.querySelectorAll('.iconContainer'); const containers = demoContainer.querySelectorAll('.iconContainer');
containers.forEach(container => { containers.forEach(container => {
@@ -79,7 +79,7 @@ export const demoFunc = () => {
}); });
// Update counts - search within demoContainer // Update counts - search within demoContainer
demoContainer.querySelectorAll('.section-container').forEach(section => { demoContainer!.querySelectorAll('.section-container').forEach(section => {
const visibleIcons = section.querySelectorAll('.iconContainer:not(.hidden)').length; const visibleIcons = section.querySelectorAll('.iconContainer:not(.hidden)').length;
const countElement = section.querySelector('.icon-count'); const countElement = section.querySelector('.icon-count');
if (countElement) { if (countElement) {

View File

@@ -208,7 +208,7 @@ export class DeesIcon extends DeesElement {
accessor icon: IconWithPrefix | undefined = undefined; accessor icon: IconWithPrefix | undefined = undefined;
@property({ type: Number }) @property({ type: Number })
accessor iconSize: number; accessor iconSize!: number;
@property({ type: String }) @property({ type: String })
accessor color: string = 'currentColor'; accessor color: string = 'currentColor';
@@ -292,13 +292,13 @@ export class DeesIcon extends DeesElement {
const pascalCaseName = iconName.charAt(0).toUpperCase() + iconName.slice(1); const pascalCaseName = iconName.charAt(0).toUpperCase() + iconName.slice(1);
// Check if the icon exists in lucideIcons // Check if the icon exists in lucideIcons
if (!lucideIcons[pascalCaseName]) { if (!(lucideIcons as any)[pascalCaseName]) {
console.warn(`Lucide icon '${pascalCaseName}' not found in lucideIcons object`); console.warn(`Lucide icon '${pascalCaseName}' not found in lucideIcons object`);
return ''; return '';
} }
// Use the exact pattern from Lucide documentation // Use the exact pattern from Lucide documentation
const svgElement = createElement(lucideIcons[pascalCaseName], { const svgElement = createElement((lucideIcons as any)[pascalCaseName], {
color: this.color, color: this.color,
size: this.iconSize, size: this.iconSize,
strokeWidth: this.strokeWidth strokeWidth: this.strokeWidth
@@ -404,9 +404,9 @@ export class DeesIcon extends DeesElement {
// Convert to PascalCase // Convert to PascalCase
const pascalCaseName = name.charAt(0).toUpperCase() + name.slice(1); const pascalCaseName = name.charAt(0).toUpperCase() + name.slice(1);
if (lucideIcons[pascalCaseName]) { if ((lucideIcons as any)[pascalCaseName]) {
// Use the documented pattern from Lucide docs // Use the documented pattern from Lucide docs
const svgElement = createElement(lucideIcons[pascalCaseName], { const svgElement = createElement((lucideIcons as any)[pascalCaseName], {
color: this.color, color: this.color,
size: this.iconSize, size: this.iconSize,
strokeWidth: this.strokeWidth strokeWidth: this.strokeWidth

View File

@@ -33,12 +33,12 @@ export class DeesUpdater extends DeesElement {
@property({ @property({
type: String, type: String,
}) })
accessor currentVersion: string; accessor currentVersion!: string;
@property({ @property({
type: String, type: String,
}) })
accessor updatedVersion: string; accessor updatedVersion!: string;
constructor() { constructor() {
super(); super();
@@ -107,7 +107,7 @@ export class DeesUpdater extends DeesElement {
} }
public async destroy() { public async destroy() {
this.parentElement.removeChild(this); this.parentElement!.removeChild(this);
} }
private windowLayerClicked() {} private windowLayerClicked() {}

View File

@@ -447,7 +447,7 @@ export class DeesWorkspaceFiletree extends DeesElement {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const menuItems = []; const menuItems: Array<{ name?: string; iconName?: string; action?: () => Promise<void>; divider?: boolean }> = [];
if (node.type === 'directory') { if (node.type === 'directory') {
// Directory-specific options // Directory-specific options
@@ -503,7 +503,7 @@ export class DeesWorkspaceFiletree extends DeesElement {
} }
); );
await DeesContextmenu.openContextMenuWithOptions(e, menuItems); await DeesContextmenu.openContextMenuWithOptions(e, menuItems as any);
} }
private async handleEmptySpaceContextMenu(e: MouseEvent) { private async handleEmptySpaceContextMenu(e: MouseEvent) {
@@ -561,14 +561,14 @@ export class DeesWorkspaceFiletree extends DeesElement {
menuOptions: [ menuOptions: [
{ {
name: 'Cancel', name: 'Cancel',
action: async (modalRef) => { action: async (modalRef: any) => {
await modalRef.destroy(); await modalRef.destroy();
resolve(null); resolve(null);
}, },
}, },
{ {
name: options.buttonName || 'Create', name: options.buttonName || 'Create',
action: async (modalRef) => { action: async (modalRef: any) => {
// Query the input element directly and read its value // Query the input element directly and read its value
const contentEl = modalRef.shadowRoot?.querySelector('.modal .content'); const contentEl = modalRef.shadowRoot?.querySelector('.modal .content');
const inputElement = contentEl?.querySelector('dees-input-text') as DeesInputText | null; const inputElement = contentEl?.querySelector('dees-input-text') as DeesInputText | null;

View File

@@ -129,8 +129,8 @@ export class DeesWorkspaceMarkdown extends DeesElement {
@state() @state()
accessor isDragging: boolean = false; accessor isDragging: boolean = false;
private resizeHandleElement: HTMLElement; private resizeHandleElement!: HTMLElement;
private containerElement: HTMLElement; private containerElement!: HTMLElement;
public render() { public render() {
return html` return html`
@@ -173,26 +173,26 @@ const hello = 'yes'
`; `;
} }
public async firstUpdated(_changedPropertiesArg) { public async firstUpdated(_changedPropertiesArg: Map<string | number | symbol, unknown>) {
await super.firstUpdated(_changedPropertiesArg); await super.firstUpdated(_changedPropertiesArg);
// Initialize current ratio from property // Initialize current ratio from property
this.currentSplitRatio = this.splitRatio; this.currentSplitRatio = this.splitRatio;
// Cache elements // Cache elements
this.containerElement = this.shadowRoot.querySelector('.splitContainer'); this.containerElement = this.shadowRoot!.querySelector('.splitContainer')!;
this.resizeHandleElement = this.shadowRoot.querySelector('.resizeHandle'); this.resizeHandleElement = this.shadowRoot!.querySelector('.resizeHandle')!;
const editor = this.shadowRoot.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco; const editor = this.shadowRoot!.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;
// Wire up markdown rendering // Wire up markdown rendering
const markdownOutlet = this.shadowRoot.querySelector('dees-workspace-markdownoutlet'); const markdownOutlet = this.shadowRoot!.querySelector('dees-workspace-markdownoutlet');
const smartmarkdownInstance = new domtools.plugins.smartmarkdown.SmartMarkdown(); const smartmarkdownInstance = new domtools.plugins.smartmarkdown.SmartMarkdown();
const mdParsedResult = await smartmarkdownInstance.getMdParsedResultFromMarkdown('loading...') const mdParsedResult = await smartmarkdownInstance.getMdParsedResultFromMarkdown('loading...')
editor.contentSubject.subscribe(async contentArg => { editor.contentSubject.subscribe(async contentArg => {
await mdParsedResult.updateFromMarkdownString(contentArg) await mdParsedResult.updateFromMarkdownString(contentArg)
const html = mdParsedResult.html; const html = mdParsedResult.html;
markdownOutlet.updateHtmlText(html); markdownOutlet!.updateHtmlText(html);
}); });
} }
@@ -226,7 +226,7 @@ const hello = 'yes'
document.removeEventListener('mouseup', this.handleMouseUp); document.removeEventListener('mouseup', this.handleMouseUp);
// Trigger resize on monaco editor // Trigger resize on monaco editor
const editor = this.shadowRoot.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco; const editor = this.shadowRoot!.querySelector('dees-workspace-monaco') as DeesWorkspaceMonaco;
if (editor) { if (editor) {
// Monaco needs to be notified of size changes // Monaco needs to be notified of size changes
window.dispatchEvent(new Event('resize')); window.dispatchEvent(new Event('resize'));

View File

@@ -381,7 +381,7 @@ export class DeesWorkspaceMarkdownoutlet extends DeesElement {
]; ];
// INSTANCE // INSTANCE
private outlet: HTMLElement; private outlet!: HTMLElement;
public render(): TemplateResult { public render(): TemplateResult {
return html` return html`
@@ -394,13 +394,13 @@ export class DeesWorkspaceMarkdownoutlet extends DeesElement {
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) { public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
await super.firstUpdated(_changedProperties); await super.firstUpdated(_changedProperties);
this.outlet = this.shadowRoot.querySelector('.outlet'); this.outlet = this.shadowRoot!.querySelector('.outlet')!;
} }
public async updateHtmlText(htmlTextArg: string) { public async updateHtmlText(htmlTextArg: string) {
await this.updateComplete; await this.updateComplete;
if (!this.outlet) { if (!this.outlet) {
this.outlet = this.shadowRoot.querySelector('.outlet'); this.outlet = this.shadowRoot!.querySelector('.outlet')!;
} }
this.outlet.innerHTML = htmlTextArg; this.outlet.innerHTML = htmlTextArg;
} }

View File

@@ -106,7 +106,7 @@ export class DeesWorkspaceMonaco extends DeesElement {
_changedProperties: Map<string | number | symbol, unknown> _changedProperties: Map<string | number | symbol, unknown>
): Promise<void> { ): Promise<void> {
super.firstUpdated(_changedProperties); super.firstUpdated(_changedProperties);
const container = this.shadowRoot.getElementById('container'); const container = this.shadowRoot!.getElementById('container')!
const monacoCdnBase = `https://cdn.jsdelivr.net/npm/monaco-editor@${MONACO_VERSION}`; const monacoCdnBase = `https://cdn.jsdelivr.net/npm/monaco-editor@${MONACO_VERSION}`;
if (!DeesWorkspaceMonaco.monacoDeferred) { if (!DeesWorkspaceMonaco.monacoDeferred) {
@@ -174,7 +174,7 @@ export class DeesWorkspaceMonaco extends DeesElement {
).text(); ).text();
const styleElement = document.createElement('style'); const styleElement = document.createElement('style');
styleElement.textContent = css; styleElement.textContent = css;
this.shadowRoot.append(styleElement); this.shadowRoot!.append(styleElement);
// editor is setup let do the rest // editor is setup let do the rest

View File

@@ -537,15 +537,15 @@ export const zIndexShowcase = () => html`
</p> </p>
`, `,
menuOptions: [ menuOptions: [
{ name: 'Cancel', action: async (modal) => modal.destroy() }, { name: 'Cancel', action: async (modal) => modal!.destroy() },
{ name: 'Save', action: async (modal) => modal.destroy() } { name: 'Save', action: async (modal) => modal!.destroy() }
] ]
}); });
// Add context menu to modal content // Add context menu to modal content
const modalContent = modal.shadowRoot.querySelector('.modal .content'); const modalContent = modal!.shadowRoot!.querySelector('.modal .content');
if (modalContent) { if (modalContent) {
modalContent.addEventListener('contextmenu', async (e: MouseEvent) => { (modalContent as HTMLElement).addEventListener('contextmenu', async (e: MouseEvent) => {
DeesContextmenu.openContextMenuWithOptions(e, [ DeesContextmenu.openContextMenuWithOptions(e, [
{ name: 'Context menu in modal', iconName: 'check', action: async () => {} }, { name: 'Context menu in modal', iconName: 'check', action: async () => {} },
{ divider: true }, { divider: true },
@@ -607,7 +607,7 @@ export const zIndexShowcase = () => html`
></dees-input-dropdown> ></dees-input-dropdown>
`, `,
menuOptions: [ menuOptions: [
{ name: 'Close', action: async (modal) => modal.destroy() } { name: 'Close', action: async (modal) => modal!.destroy() }
] ]
}); });
}}>Show Second Modal</dees-button> }}>Show Second Modal</dees-button>
@@ -615,7 +615,7 @@ export const zIndexShowcase = () => html`
`, `,
menuOptions: [ menuOptions: [
{ name: 'Close All', action: async (modal) => { { name: 'Close All', action: async (modal) => {
modal.destroy(); modal!.destroy();
// Also show a toast // Also show a toast
DeesToast.createAndShow({ message: 'All modals closed!', type: 'info' }); DeesToast.createAndShow({ message: 'All modals closed!', type: 'info' });
}} }}
@@ -694,10 +694,10 @@ export const zIndexShowcase = () => html`
</div> </div>
`, `,
menuOptions: [ menuOptions: [
{ name: 'Cancel', action: async (modal) => modal.destroy() }, { name: 'Cancel', action: async (modal) => modal!.destroy() },
{ name: 'Save', action: async (modal) => { { name: 'Save', action: async (modal) => {
DeesToast.createAndShow({ message: 'Document saved!', type: 'success' }); DeesToast.createAndShow({ message: 'Document saved!', type: 'success' });
modal.destroy(); modal!.destroy();
}} }}
] ]
}); });
@@ -735,10 +735,10 @@ export const zIndexShowcase = () => html`
</dees-form> </dees-form>
`, `,
menuOptions: [ menuOptions: [
{ name: 'Cancel', action: async (modal) => modal.destroy() }, { name: 'Cancel', action: async (modal) => modal!.destroy() },
{ name: 'Apply', action: async (modal) => { { name: 'Apply', action: async (modal) => {
DeesToast.createAndShow({ message: 'Tags applied!', type: 'success' }); DeesToast.createAndShow({ message: 'Tags applied!', type: 'success' });
modal.destroy(); modal!.destroy();
}} }}
] ]
}); });
@@ -766,7 +766,7 @@ export const zIndexShowcase = () => html`
></dees-input-dropdown> ></dees-input-dropdown>
`, `,
menuOptions: [ menuOptions: [
{ name: 'Exit Fullscreen', action: async (modal) => modal.destroy() } { name: 'Exit Fullscreen', action: async (modal) => modal!.destroy() }
] ]
}); });
}}>Open Fullscreen</dees-button> }}>Open Fullscreen</dees-button>

View File

@@ -228,7 +228,7 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
const module = await import(/* @vite-ignore */ url); const module = await import(/* @vite-ignore */ url);
this.highlightJsLib = module.default; this.highlightJsLib = module.default;
return this.highlightJsLib; return this.highlightJsLib!;
})(); })();
return this.highlightJsLoadingPromise; return this.highlightJsLoadingPromise;
@@ -252,7 +252,7 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
const module = await import(/* @vite-ignore */ url); const module = await import(/* @vite-ignore */ url);
this.apexChartsLib = module.default; this.apexChartsLib = module.default;
return this.apexChartsLib; return this.apexChartsLib!;
})(); })();
return this.apexChartsLoadingPromise; return this.apexChartsLoadingPromise;

View File

@@ -5,7 +5,8 @@
"moduleResolution": "NodeNext", "moduleResolution": "NodeNext",
"esModuleInterop": true, "esModuleInterop": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true,
"skipLibCheck": false "skipLibCheck": false,
"types": ["node"]
}, },
"exclude": [ "exclude": [
"dist_*/**/*.d.ts" "dist_*/**/*.d.ts"